aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore15
-rw-r--r--.travis.yml57
-rw-r--r--BUILD205
-rw-r--r--CHANGES.txt345
-rw-r--r--INSTALL.txt237
-rw-r--r--Makefile.am532
-rw-r--r--Protobuf.podspec21
-rw-r--r--README.md206
-rw-r--r--WORKSPACE53
-rw-r--r--appveyor.bat9
-rw-r--r--appveyor.yml70
-rw-r--r--benchmarks/Makefile.am69
-rw-r--r--benchmarks/README.md28
-rw-r--r--benchmarks/benchmark_messages_proto2.proto (renamed from benchmarks/google_speed.proto)19
-rw-r--r--benchmarks/benchmark_messages_proto3.proto76
-rw-r--r--benchmarks/benchmarks.proto63
-rw-r--r--benchmarks/generate_datasets.cc117
-rw-r--r--cmake/CMakeLists.txt40
-rw-r--r--cmake/README.md9
-rw-r--r--cmake/examples.cmake57
-rw-r--r--cmake/extract_includes.bat.in6
-rw-r--r--cmake/install.cmake102
-rw-r--r--cmake/libprotobuf.cmake6
-rw-r--r--cmake/libprotoc.cmake2
-rw-r--r--cmake/protobuf-config-version.cmake.in59
-rw-r--r--cmake/protobuf-config.cmake.in28
-rw-r--r--cmake/protobuf-module.cmake.in184
-rw-r--r--cmake/protobuf-options.cmake7
-rw-r--r--cmake/tests.cmake12
-rw-r--r--configure.ac15
-rw-r--r--conformance/ConformanceJava.java30
-rw-r--r--conformance/ConformanceJavaLite.java125
-rw-r--r--conformance/Makefile.am184
-rw-r--r--conformance/conformance.proto61
-rw-r--r--conformance/conformance_cpp.cc17
-rw-r--r--conformance/conformance_objc.m2
-rwxr-xr-xconformance/conformance_ruby.rb18
-rw-r--r--conformance/conformance_test.cc1551
-rw-r--r--conformance/conformance_test.h32
-rw-r--r--conformance/conformance_test_runner.cc84
-rw-r--r--conformance/failure_list_cpp.txt27
-rw-r--r--conformance/failure_list_csharp.txt7
-rw-r--r--conformance/failure_list_java.txt43
-rw-r--r--conformance/failure_list_objc.txt3
-rw-r--r--conformance/failure_list_python-post26.txt2
-rw-r--r--conformance/failure_list_python.txt47
-rw-r--r--conformance/failure_list_python_cpp.txt47
-rw-r--r--conformance/failure_list_ruby.txt201
-rw-r--r--conformance/third_party/jsoncpp/json.h2075
-rw-r--r--conformance/third_party/jsoncpp/jsoncpp.cpp5192
-rwxr-xr-xconformance/update_failure_list.py73
-rw-r--r--csharp/.gitignore22
-rw-r--r--csharp/CHANGES.txt2
-rw-r--r--csharp/Google.Protobuf.Tools.nuspec37
-rw-r--r--csharp/README.md52
-rw-r--r--csharp/build_packages.bat7
-rwxr-xr-xcsharp/buildall.sh15
-rwxr-xr-xcsharp/generate_protos.sh14
-rw-r--r--csharp/keys/Google.Protobuf.snkbin0 -> 596 bytes
-rw-r--r--csharp/keys/README.md6
-rw-r--r--csharp/protos/unittest_issues.proto9
-rw-r--r--csharp/src/AddressBook/AddPerson.cs6
-rw-r--r--csharp/src/AddressBook/AddressBook.csproj75
-rw-r--r--csharp/src/AddressBook/AddressBook.xproj19
-rw-r--r--csharp/src/AddressBook/Addressbook.cs92
-rw-r--r--csharp/src/AddressBook/ListPeople.cs6
-rw-r--r--csharp/src/AddressBook/Properties/AssemblyInfo.cs18
-rw-r--r--csharp/src/AddressBook/SampleUsage.cs2
-rw-r--r--csharp/src/AddressBook/app.config3
-rw-r--r--csharp/src/AddressBook/project.json20
-rw-r--r--csharp/src/Google.Protobuf.Conformance/App.config6
-rw-r--r--csharp/src/Google.Protobuf.Conformance/Conformance.cs1712
-rw-r--r--csharp/src/Google.Protobuf.Conformance/Google.Protobuf.Conformance.csproj61
-rw-r--r--csharp/src/Google.Protobuf.Conformance/Google.Protobuf.Conformance.xproj19
-rw-r--r--csharp/src/Google.Protobuf.Conformance/Program.cs66
-rw-r--r--csharp/src/Google.Protobuf.Conformance/project.json19
-rw-r--r--csharp/src/Google.Protobuf.JsonDump/Google.Protobuf.JsonDump.csproj68
-rw-r--r--csharp/src/Google.Protobuf.JsonDump/Google.Protobuf.JsonDump.xproj19
-rw-r--r--csharp/src/Google.Protobuf.JsonDump/Program.cs3
-rw-r--r--csharp/src/Google.Protobuf.JsonDump/Properties/AssemblyInfo.cs19
-rw-r--r--csharp/src/Google.Protobuf.JsonDump/app.config3
-rw-r--r--csharp/src/Google.Protobuf.JsonDump/project.json19
-rw-r--r--csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs72
-rw-r--r--csharp/src/Google.Protobuf.Test/CodedOutputStreamTest.cs28
-rw-r--r--csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.cs56
-rw-r--r--csharp/src/Google.Protobuf.Test/Collections/RepeatedFieldTest.cs90
-rw-r--r--csharp/src/Google.Protobuf.Test/Compatibility/TypeExtensionsTest.cs20
-rw-r--r--csharp/src/Google.Protobuf.Test/FieldCodecTest.cs5
-rw-r--r--csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs100
-rw-r--r--csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj141
-rw-r--r--csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.xproj19
-rw-r--r--csharp/src/Google.Protobuf.Test/IssuesTest.cs19
-rw-r--r--csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs205
-rw-r--r--csharp/src/Google.Protobuf.Test/JsonParserTest.cs198
-rw-r--r--csharp/src/Google.Protobuf.Test/JsonTokenizerTest.cs1
-rw-r--r--csharp/src/Google.Protobuf.Test/Properties/AppManifest.xml6
-rw-r--r--csharp/src/Google.Protobuf.Test/Properties/AssemblyInfo.cs20
-rw-r--r--csharp/src/Google.Protobuf.Test/Reflection/DescriptorsTest.cs2
-rw-r--r--csharp/src/Google.Protobuf.Test/Reflection/FieldAccessTest.cs4
-rw-r--r--csharp/src/Google.Protobuf.Test/SampleMessages.cs16
-rw-r--r--csharp/src/Google.Protobuf.Test/TestCornerCases.cs4
-rw-r--r--csharp/src/Google.Protobuf.Test/TestProtos/ForeignMessagePartial.cs (renamed from csharp/src/Google.Protobuf.Conformance/Properties/AssemblyInfo.cs)31
-rw-r--r--csharp/src/Google.Protobuf.Test/TestProtos/MapUnittestProto3.cs184
-rw-r--r--csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportProto3.cs31
-rw-r--r--csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportPublicProto3.cs23
-rw-r--r--csharp/src/Google.Protobuf.Test/TestProtos/UnittestIssues.cs450
-rw-r--r--csharp/src/Google.Protobuf.Test/TestProtos/UnittestProto3.cs914
-rw-r--r--csharp/src/Google.Protobuf.Test/TestProtos/UnittestWellKnownTypes.cs213
-rw-r--r--csharp/src/Google.Protobuf.Test/WellKnownTypes/AnyTest.cs50
-rw-r--r--csharp/src/Google.Protobuf.Test/WellKnownTypes/DurationTest.cs38
-rw-r--r--csharp/src/Google.Protobuf.Test/WellKnownTypes/FieldMaskTest.cs62
-rw-r--r--csharp/src/Google.Protobuf.Test/WellKnownTypes/TimestampTest.cs31
-rw-r--r--csharp/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs78
-rw-r--r--csharp/src/Google.Protobuf.Test/packages.config5
-rw-r--r--csharp/src/Google.Protobuf.Test/project.json44
-rw-r--r--csharp/src/Google.Protobuf.sln67
-rw-r--r--csharp/src/Google.Protobuf/CodedInputStream.cs86
-rw-r--r--csharp/src/Google.Protobuf/CodedOutputStream.cs67
-rw-r--r--csharp/src/Google.Protobuf/Collections/MapField.cs98
-rw-r--r--csharp/src/Google.Protobuf/Collections/RepeatedField.cs129
-rw-r--r--csharp/src/Google.Protobuf/Compatibility/PropertyInfoExtensions.cs8
-rw-r--r--csharp/src/Google.Protobuf/Compatibility/TypeExtensions.cs11
-rw-r--r--csharp/src/Google.Protobuf/FieldCodec.cs144
-rw-r--r--csharp/src/Google.Protobuf/Google.Protobuf.csproj155
-rw-r--r--csharp/src/Google.Protobuf/Google.Protobuf.nuspec37
-rw-r--r--csharp/src/Google.Protobuf/Google.Protobuf.xproj19
-rw-r--r--csharp/src/Google.Protobuf/ICustomDiagnosticMessage.cs69
-rw-r--r--csharp/src/Google.Protobuf/InvalidProtocolBufferException.cs11
-rw-r--r--csharp/src/Google.Protobuf/JsonFormatter.cs515
-rw-r--r--csharp/src/Google.Protobuf/JsonParser.cs204
-rw-r--r--csharp/src/Google.Protobuf/MessageExtensions.cs28
-rw-r--r--csharp/src/Google.Protobuf/MessageParser.cs8
-rw-r--r--csharp/src/Google.Protobuf/Properties/AssemblyInfo.cs18
-rw-r--r--csharp/src/Google.Protobuf/ProtoPreconditions.cs (renamed from csharp/src/Google.Protobuf/Preconditions.cs)9
-rw-r--r--csharp/src/Google.Protobuf/Reflection/Descriptor.cs1367
-rw-r--r--csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs130
-rw-r--r--csharp/src/Google.Protobuf/Reflection/FileDescriptor.cs6
-rw-r--r--csharp/src/Google.Protobuf/Reflection/GeneratedClrTypeInfo.cs (renamed from csharp/src/Google.Protobuf/Reflection/GeneratedCodeInfo.cs)14
-rw-r--r--csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs24
-rw-r--r--csharp/src/Google.Protobuf/Reflection/OriginalNameAttribute.cs58
-rw-r--r--csharp/src/Google.Protobuf/Reflection/TypeRegistry.cs4
-rw-r--r--csharp/src/Google.Protobuf/WellKnownTypes/Any.cs95
-rw-r--r--csharp/src/Google.Protobuf/WellKnownTypes/AnyPartial.cs48
-rw-r--r--csharp/src/Google.Protobuf/WellKnownTypes/Api.cs111
-rw-r--r--csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs31
-rw-r--r--csharp/src/Google.Protobuf/WellKnownTypes/DurationPartial.cs121
-rw-r--r--csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs29
-rw-r--r--csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs106
-rw-r--r--csharp/src/Google.Protobuf/WellKnownTypes/FieldMaskPartial.cs128
-rw-r--r--csharp/src/Google.Protobuf/WellKnownTypes/SourceContext.cs27
-rw-r--r--csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs85
-rw-r--r--csharp/src/Google.Protobuf/WellKnownTypes/TimeExtensions.cs4
-rw-r--r--csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs31
-rw-r--r--csharp/src/Google.Protobuf/WellKnownTypes/TimestampPartial.cs92
-rw-r--r--csharp/src/Google.Protobuf/WellKnownTypes/Type.cs360
-rw-r--r--csharp/src/Google.Protobuf/WellKnownTypes/ValuePartial.cs6
-rw-r--r--csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs194
-rw-r--r--csharp/src/Google.Protobuf/project.json65
-rw-r--r--docs/swift/DesignDoc.md674
-rw-r--r--docs/third_party.md149
-rw-r--r--examples/CMakeLists.txt63
-rw-r--r--examples/README.txt2
-rw-r--r--examples/add_person.go5
-rwxr-xr-xexamples/add_person.py10
-rw-r--r--examples/list_people.go46
-rwxr-xr-xexamples/list_people.py5
-rw-r--r--examples/list_people_test.go24
-rwxr-xr-xgenerate_descriptor_proto.sh53
-rw-r--r--java/README.md85
-rw-r--r--java/compatibility_tests/README.md50
-rw-r--r--java/compatibility_tests/v2.5.0/deps/pom.xml43
-rw-r--r--java/compatibility_tests/v2.5.0/more_protos/pom.xml69
-rw-r--r--java/compatibility_tests/v2.5.0/more_protos/src/proto/com/google/protobuf/multiple_files_test.proto71
-rw-r--r--java/compatibility_tests/v2.5.0/more_protos/src/proto/com/google/protobuf/nested_builders_test.proto53
-rw-r--r--java/compatibility_tests/v2.5.0/more_protos/src/proto/com/google/protobuf/nested_extension.proto45
-rw-r--r--java/compatibility_tests/v2.5.0/more_protos/src/proto/com/google/protobuf/nested_extension_lite.proto48
-rw-r--r--java/compatibility_tests/v2.5.0/more_protos/src/proto/com/google/protobuf/non_nested_extension.proto48
-rw-r--r--java/compatibility_tests/v2.5.0/more_protos/src/proto/com/google/protobuf/non_nested_extension_lite.proto50
-rw-r--r--java/compatibility_tests/v2.5.0/more_protos/src/proto/com/google/protobuf/test_bad_identifiers.proto108
-rw-r--r--java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/descriptor.proto620
-rw-r--r--java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest.proto719
-rw-r--r--java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_custom_options.proto387
-rw-r--r--java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_embed_optimize_for.proto50
-rw-r--r--java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_empty.proto37
-rw-r--r--java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_enormous_descriptor.proto1046
-rw-r--r--java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_import.proto64
-rw-r--r--java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_import_lite.proto51
-rw-r--r--java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_import_public.proto40
-rw-r--r--java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_import_public_lite.proto42
-rw-r--r--java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_lite.proto360
-rw-r--r--java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_lite_imports_nonlite.proto43
-rw-r--r--java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_mset.proto72
-rw-r--r--java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_no_generic_services.proto52
-rw-r--r--java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_optimize_for.proto61
-rw-r--r--java/compatibility_tests/v2.5.0/pom.xml30
-rw-r--r--java/compatibility_tests/v2.5.0/protos/pom.xml71
-rw-r--r--java/compatibility_tests/v2.5.0/protos/src/proto/com/google/protobuf/multiple_files_test.proto71
-rw-r--r--java/compatibility_tests/v2.5.0/protos/src/proto/com/google/protobuf/nested_builders_test.proto53
-rw-r--r--java/compatibility_tests/v2.5.0/protos/src/proto/com/google/protobuf/nested_extension.proto45
-rw-r--r--java/compatibility_tests/v2.5.0/protos/src/proto/com/google/protobuf/nested_extension_lite.proto48
-rw-r--r--java/compatibility_tests/v2.5.0/protos/src/proto/com/google/protobuf/non_nested_extension.proto48
-rw-r--r--java/compatibility_tests/v2.5.0/protos/src/proto/com/google/protobuf/non_nested_extension_lite.proto50
-rw-r--r--java/compatibility_tests/v2.5.0/protos/src/proto/com/google/protobuf/test_bad_identifiers.proto108
-rw-r--r--java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/descriptor.proto620
-rw-r--r--java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest.proto719
-rw-r--r--java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_custom_options.proto387
-rw-r--r--java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_embed_optimize_for.proto50
-rw-r--r--java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_empty.proto37
-rw-r--r--java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_enormous_descriptor.proto1046
-rw-r--r--java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_import.proto64
-rw-r--r--java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_import_lite.proto51
-rw-r--r--java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_import_public.proto40
-rw-r--r--java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_import_public_lite.proto42
-rw-r--r--java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_lite.proto360
-rw-r--r--java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_lite_imports_nonlite.proto43
-rw-r--r--java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_mset.proto72
-rw-r--r--java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_no_generic_services.proto52
-rw-r--r--java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_optimize_for.proto61
-rwxr-xr-xjava/compatibility_tests/v2.5.0/test.sh140
-rw-r--r--java/compatibility_tests/v2.5.0/tests/pom.xml73
-rw-r--r--java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/AbstractMessageTest.java510
-rw-r--r--java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/BoundedByteStringTest.java56
-rw-r--r--java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/ByteStringTest.java590
-rw-r--r--java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/CodedInputStreamTest.java469
-rw-r--r--java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/CodedOutputStreamTest.java (renamed from java/src/test/java/com/google/protobuf/CodedOutputStreamTest.java)197
-rw-r--r--java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/DeprecatedFieldTest.java81
-rw-r--r--java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/DescriptorsTest.java649
-rw-r--r--java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/DynamicMessageTest.java265
-rw-r--r--java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/ForceFieldBuildersPreRun.java49
-rw-r--r--java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/GeneratedMessageTest.java961
-rw-r--r--java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/LazyStringArrayListTest.java163
-rw-r--r--java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/LazyStringEndToEndTest.java108
-rw-r--r--java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/LiteralByteStringTest.java344
-rw-r--r--java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/MessageTest.java354
-rw-r--r--java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/NestedBuildersTest.java186
-rw-r--r--java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/ParserTest.java278
-rw-r--r--java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/RopeByteStringSubstringTest.java62
-rw-r--r--java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/RopeByteStringTest.java84
-rw-r--r--java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/ServiceTest.java (renamed from java/src/test/java/com/google/protobuf/ServiceTest.java)5
-rw-r--r--java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/TestBadIdentifiers.java64
-rw-r--r--java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/TestUtil.java3068
-rw-r--r--java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/TextFormatTest.java536
-rw-r--r--java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/UnknownFieldSetTest.java438
-rw-r--r--java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/UnmodifiableLazyStringListTest.java153
-rw-r--r--java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/WireFormatTest.java465
-rw-r--r--java/core/generate-sources-build.xml20
-rw-r--r--java/core/generate-test-sources-build.xml43
-rw-r--r--java/core/pom.xml118
-rw-r--r--java/core/src/main/java/com/google/protobuf/AbstractMessage.java (renamed from java/src/main/java/com/google/protobuf/AbstractMessage.java)154
-rw-r--r--java/core/src/main/java/com/google/protobuf/AbstractMessageLite.java (renamed from java/src/main/java/com/google/protobuf/AbstractMessageLite.java)113
-rw-r--r--java/core/src/main/java/com/google/protobuf/AbstractParser.java (renamed from java/src/main/java/com/google/protobuf/AbstractParser.java)85
-rw-r--r--java/core/src/main/java/com/google/protobuf/AbstractProtobufList.java (renamed from java/src/main/java/com/google/protobuf/AbstractProtobufList.java)48
-rw-r--r--java/core/src/main/java/com/google/protobuf/BlockingRpcChannel.java (renamed from java/src/main/java/com/google/protobuf/BlockingRpcChannel.java)0
-rw-r--r--java/core/src/main/java/com/google/protobuf/BlockingService.java (renamed from java/src/main/java/com/google/protobuf/BlockingService.java)0
-rw-r--r--java/core/src/main/java/com/google/protobuf/BooleanArrayList.java (renamed from java/src/main/java/com/google/protobuf/BooleanArrayList.java)100
-rw-r--r--java/core/src/main/java/com/google/protobuf/ByteBufferWriter.java145
-rw-r--r--java/core/src/main/java/com/google/protobuf/ByteOutput.java116
-rw-r--r--java/core/src/main/java/com/google/protobuf/ByteString.java (renamed from java/src/main/java/com/google/protobuf/ByteString.java)649
-rw-r--r--java/core/src/main/java/com/google/protobuf/CodedInputStream.java (renamed from java/src/main/java/com/google/protobuf/CodedInputStream.java)237
-rw-r--r--java/core/src/main/java/com/google/protobuf/CodedOutputStream.java2635
-rw-r--r--java/core/src/main/java/com/google/protobuf/Descriptors.java (renamed from java/src/main/java/com/google/protobuf/Descriptors.java)240
-rw-r--r--java/core/src/main/java/com/google/protobuf/DoubleArrayList.java (renamed from java/src/main/java/com/google/protobuf/DoubleArrayList.java)100
-rw-r--r--java/core/src/main/java/com/google/protobuf/DynamicMessage.java (renamed from java/src/main/java/com/google/protobuf/DynamicMessage.java)48
-rw-r--r--java/core/src/main/java/com/google/protobuf/ExperimentalApi.java66
-rw-r--r--java/core/src/main/java/com/google/protobuf/Extension.java (renamed from java/src/main/java/com/google/protobuf/Extension.java)1
-rw-r--r--java/core/src/main/java/com/google/protobuf/ExtensionLite.java (renamed from java/src/main/java/com/google/protobuf/ExtensionLite.java)0
-rw-r--r--java/core/src/main/java/com/google/protobuf/ExtensionRegistry.java (renamed from java/src/main/java/com/google/protobuf/ExtensionRegistry.java)11
-rw-r--r--java/core/src/main/java/com/google/protobuf/ExtensionRegistryFactory.java95
-rw-r--r--java/core/src/main/java/com/google/protobuf/ExtensionRegistryLite.java (renamed from java/src/main/java/com/google/protobuf/ExtensionRegistryLite.java)57
-rw-r--r--java/core/src/main/java/com/google/protobuf/FieldSet.java (renamed from java/src/main/java/com/google/protobuf/FieldSet.java)35
-rw-r--r--java/core/src/main/java/com/google/protobuf/FloatArrayList.java (renamed from java/src/main/java/com/google/protobuf/FloatArrayList.java)100
-rw-r--r--java/core/src/main/java/com/google/protobuf/GeneratedMessage.java (renamed from java/src/main/java/com/google/protobuf/GeneratedMessage.java)523
-rw-r--r--java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java (renamed from java/src/main/java/com/google/protobuf/GeneratedMessageLite.java)1413
-rw-r--r--java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java2716
-rw-r--r--java/core/src/main/java/com/google/protobuf/IntArrayList.java (renamed from java/src/main/java/com/google/protobuf/IntArrayList.java)100
-rw-r--r--java/core/src/main/java/com/google/protobuf/Internal.java (renamed from java/src/main/java/com/google/protobuf/Internal.java)80
-rw-r--r--java/core/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java (renamed from java/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java)12
-rw-r--r--java/core/src/main/java/com/google/protobuf/LazyField.java (renamed from java/src/main/java/com/google/protobuf/LazyField.java)16
-rw-r--r--java/core/src/main/java/com/google/protobuf/LazyFieldLite.java (renamed from java/src/main/java/com/google/protobuf/LazyFieldLite.java)153
-rw-r--r--java/core/src/main/java/com/google/protobuf/LazyStringArrayList.java (renamed from java/src/main/java/com/google/protobuf/LazyStringArrayList.java)52
-rw-r--r--java/core/src/main/java/com/google/protobuf/LazyStringList.java (renamed from java/src/main/java/com/google/protobuf/LazyStringList.java)0
-rw-r--r--java/core/src/main/java/com/google/protobuf/LongArrayList.java (renamed from java/src/main/java/com/google/protobuf/LongArrayList.java)100
-rw-r--r--java/core/src/main/java/com/google/protobuf/MapEntry.java (renamed from java/src/main/java/com/google/protobuf/MapEntry.java)219
-rw-r--r--java/core/src/main/java/com/google/protobuf/MapEntryLite.java226
-rw-r--r--java/core/src/main/java/com/google/protobuf/MapField.java (renamed from java/src/main/java/com/google/protobuf/MapField.java)416
-rw-r--r--java/core/src/main/java/com/google/protobuf/MapFieldLite.java224
-rw-r--r--java/core/src/main/java/com/google/protobuf/Message.java (renamed from java/src/main/java/com/google/protobuf/Message.java)70
-rw-r--r--java/core/src/main/java/com/google/protobuf/MessageLite.java (renamed from java/src/main/java/com/google/protobuf/MessageLite.java)21
-rw-r--r--java/core/src/main/java/com/google/protobuf/MessageLiteOrBuilder.java (renamed from java/src/main/java/com/google/protobuf/MessageLiteOrBuilder.java)0
-rw-r--r--java/core/src/main/java/com/google/protobuf/MessageLiteToString.java239
-rw-r--r--java/core/src/main/java/com/google/protobuf/MessageOrBuilder.java (renamed from java/src/main/java/com/google/protobuf/MessageOrBuilder.java)2
-rw-r--r--java/core/src/main/java/com/google/protobuf/MessageReflection.java (renamed from java/src/main/java/com/google/protobuf/MessageReflection.java)104
-rw-r--r--java/core/src/main/java/com/google/protobuf/MutabilityOracle.java (renamed from java/src/main/java/com/google/protobuf/MutabilityOracle.java)0
-rw-r--r--java/core/src/main/java/com/google/protobuf/NioByteString.java290
-rw-r--r--java/core/src/main/java/com/google/protobuf/Parser.java (renamed from java/src/main/java/com/google/protobuf/Parser.java)11
-rw-r--r--java/core/src/main/java/com/google/protobuf/ProtobufArrayList.java (renamed from java/src/main/java/com/google/protobuf/ProtobufArrayList.java)20
-rw-r--r--java/core/src/main/java/com/google/protobuf/ProtocolMessageEnum.java (renamed from java/src/main/java/com/google/protobuf/ProtocolMessageEnum.java)1
-rw-r--r--java/core/src/main/java/com/google/protobuf/ProtocolStringList.java (renamed from java/src/main/java/com/google/protobuf/ProtocolStringList.java)0
-rw-r--r--java/core/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java (renamed from java/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java)8
-rw-r--r--java/core/src/main/java/com/google/protobuf/RepeatedFieldBuilderV3.java708
-rw-r--r--java/core/src/main/java/com/google/protobuf/RopeByteString.java (renamed from java/src/main/java/com/google/protobuf/RopeByteString.java)286
-rw-r--r--java/core/src/main/java/com/google/protobuf/RpcCallback.java (renamed from java/src/main/java/com/google/protobuf/RpcCallback.java)0
-rw-r--r--java/core/src/main/java/com/google/protobuf/RpcChannel.java (renamed from java/src/main/java/com/google/protobuf/RpcChannel.java)0
-rw-r--r--java/core/src/main/java/com/google/protobuf/RpcController.java (renamed from java/src/main/java/com/google/protobuf/RpcController.java)0
-rw-r--r--java/core/src/main/java/com/google/protobuf/RpcUtil.java (renamed from java/src/main/java/com/google/protobuf/RpcUtil.java)4
-rw-r--r--java/core/src/main/java/com/google/protobuf/Service.java (renamed from java/src/main/java/com/google/protobuf/Service.java)0
-rw-r--r--java/core/src/main/java/com/google/protobuf/ServiceException.java (renamed from java/src/main/java/com/google/protobuf/ServiceException.java)0
-rw-r--r--java/core/src/main/java/com/google/protobuf/SingleFieldBuilder.java (renamed from java/src/main/java/com/google/protobuf/SingleFieldBuilder.java)2
-rw-r--r--java/core/src/main/java/com/google/protobuf/SingleFieldBuilderV3.java241
-rw-r--r--java/core/src/main/java/com/google/protobuf/SmallSortedMap.java (renamed from java/src/main/java/com/google/protobuf/SmallSortedMap.java)108
-rw-r--r--java/core/src/main/java/com/google/protobuf/TextFormat.java (renamed from java/src/main/java/com/google/protobuf/TextFormat.java)291
-rw-r--r--java/core/src/main/java/com/google/protobuf/TextFormatEscaper.java137
-rw-r--r--java/core/src/main/java/com/google/protobuf/TextFormatParseInfoTree.java225
-rw-r--r--java/core/src/main/java/com/google/protobuf/TextFormatParseLocation.java104
-rw-r--r--java/core/src/main/java/com/google/protobuf/UninitializedMessageException.java (renamed from java/src/main/java/com/google/protobuf/UninitializedMessageException.java)0
-rw-r--r--java/core/src/main/java/com/google/protobuf/UnknownFieldSet.java (renamed from java/src/main/java/com/google/protobuf/UnknownFieldSet.java)81
-rw-r--r--java/core/src/main/java/com/google/protobuf/UnknownFieldSetLite.java (renamed from java/src/main/java/com/google/protobuf/UnknownFieldSetLite.java)110
-rw-r--r--java/core/src/main/java/com/google/protobuf/UnmodifiableLazyStringList.java (renamed from java/src/main/java/com/google/protobuf/UnmodifiableLazyStringList.java)50
-rw-r--r--java/core/src/main/java/com/google/protobuf/UnsafeByteOperations.java101
-rw-r--r--java/core/src/main/java/com/google/protobuf/UnsafeUtil.java210
-rw-r--r--java/core/src/main/java/com/google/protobuf/Utf8.java1573
-rw-r--r--java/core/src/main/java/com/google/protobuf/WireFormat.java (renamed from java/src/main/java/com/google/protobuf/WireFormat.java)19
-rw-r--r--java/core/src/test/java/com/google/protobuf/AbstractMessageTest.java (renamed from java/src/test/java/com/google/protobuf/AbstractMessageTest.java)42
-rw-r--r--java/core/src/test/java/com/google/protobuf/AnyTest.java (renamed from java/src/test/java/com/google/protobuf/AnyTest.java)45
-rw-r--r--java/core/src/test/java/com/google/protobuf/BooleanArrayListTest.java (renamed from java/src/test/java/com/google/protobuf/BooleanArrayListTest.java)210
-rw-r--r--java/core/src/test/java/com/google/protobuf/BoundedByteStringTest.java (renamed from java/src/test/java/com/google/protobuf/BoundedByteStringTest.java)7
-rw-r--r--java/core/src/test/java/com/google/protobuf/ByteBufferWriterTest.java81
-rw-r--r--java/core/src/test/java/com/google/protobuf/ByteStringTest.java (renamed from java/src/test/java/com/google/protobuf/ByteStringTest.java)38
-rw-r--r--java/core/src/test/java/com/google/protobuf/CheckUtf8Test.java (renamed from java/src/test/java/com/google/protobuf/CheckUtf8Test.java)1
-rw-r--r--java/core/src/test/java/com/google/protobuf/CodedInputStreamTest.java (renamed from java/src/test/java/com/google/protobuf/CodedInputStreamTest.java)52
-rw-r--r--java/core/src/test/java/com/google/protobuf/CodedOutputStreamTest.java776
-rw-r--r--java/core/src/test/java/com/google/protobuf/DeprecatedFieldTest.java (renamed from java/src/test/java/com/google/protobuf/DeprecatedFieldTest.java)1
-rw-r--r--java/core/src/test/java/com/google/protobuf/DescriptorsTest.java (renamed from java/src/test/java/com/google/protobuf/DescriptorsTest.java)54
-rw-r--r--java/core/src/test/java/com/google/protobuf/DoubleArrayListTest.java (renamed from java/src/test/java/com/google/protobuf/DoubleArrayListTest.java)169
-rw-r--r--java/core/src/test/java/com/google/protobuf/DynamicMessageTest.java (renamed from java/src/test/java/com/google/protobuf/DynamicMessageTest.java)2
-rw-r--r--java/core/src/test/java/com/google/protobuf/EnumTest.java76
-rw-r--r--java/core/src/test/java/com/google/protobuf/ExtensionRegistryFactoryTest.java245
-rw-r--r--java/core/src/test/java/com/google/protobuf/FieldPresenceTest.java (renamed from java/src/test/java/com/google/protobuf/FieldPresenceTest.java)168
-rw-r--r--java/core/src/test/java/com/google/protobuf/FloatArrayListTest.java (renamed from java/src/test/java/com/google/protobuf/FloatArrayListTest.java)169
-rw-r--r--java/core/src/test/java/com/google/protobuf/ForceFieldBuildersPreRun.java (renamed from java/src/test/java/com/google/protobuf/ForceFieldBuildersPreRun.java)2
-rw-r--r--java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java (renamed from java/src/test/java/com/google/protobuf/GeneratedMessageTest.java)27
-rw-r--r--java/core/src/test/java/com/google/protobuf/IntArrayListTest.java (renamed from java/src/test/java/com/google/protobuf/IntArrayListTest.java)157
-rw-r--r--java/core/src/test/java/com/google/protobuf/IsValidUtf8Test.java (renamed from java/src/test/java/com/google/protobuf/IsValidUtf8Test.java)73
-rw-r--r--java/core/src/test/java/com/google/protobuf/IsValidUtf8TestUtil.java (renamed from java/src/test/java/com/google/protobuf/IsValidUtf8TestUtil.java)202
-rw-r--r--java/core/src/test/java/com/google/protobuf/LazyFieldLiteTest.java (renamed from java/src/test/java/com/google/protobuf/LazyFieldLiteTest.java)3
-rw-r--r--java/core/src/test/java/com/google/protobuf/LazyFieldTest.java (renamed from java/src/test/java/com/google/protobuf/LazyFieldTest.java)3
-rw-r--r--java/core/src/test/java/com/google/protobuf/LazyMessageLiteTest.java (renamed from java/src/test/java/com/google/protobuf/LazyMessageLiteTest.java)17
-rw-r--r--java/core/src/test/java/com/google/protobuf/LazyStringArrayListTest.java (renamed from java/src/test/java/com/google/protobuf/LazyStringArrayListTest.java)3
-rw-r--r--java/core/src/test/java/com/google/protobuf/LazyStringEndToEndTest.java (renamed from java/src/test/java/com/google/protobuf/LazyStringEndToEndTest.java)0
-rw-r--r--java/core/src/test/java/com/google/protobuf/LiteEqualsAndHashTest.java (renamed from java/src/test/java/com/google/protobuf/LiteEqualsAndHashTest.java)19
-rw-r--r--java/core/src/test/java/com/google/protobuf/LiteTest.java (renamed from java/src/test/java/com/google/protobuf/LiteTest.java)908
-rw-r--r--java/core/src/test/java/com/google/protobuf/LiteralByteStringTest.java (renamed from java/src/test/java/com/google/protobuf/LiteralByteStringTest.java)90
-rw-r--r--java/core/src/test/java/com/google/protobuf/LongArrayListTest.java (renamed from java/src/test/java/com/google/protobuf/LongArrayListTest.java)203
-rw-r--r--java/core/src/test/java/com/google/protobuf/MapForProto2LiteTest.java799
-rw-r--r--java/core/src/test/java/com/google/protobuf/MapForProto2Test.java (renamed from java/src/test/java/com/google/protobuf/MapForProto2Test.java)655
-rw-r--r--java/core/src/test/java/com/google/protobuf/MapTest.java (renamed from java/src/test/java/com/google/protobuf/MapTest.java)589
-rw-r--r--java/core/src/test/java/com/google/protobuf/MessageTest.java (renamed from java/src/test/java/com/google/protobuf/MessageTest.java)4
-rw-r--r--java/core/src/test/java/com/google/protobuf/NestedBuildersTest.java (renamed from java/src/test/java/com/google/protobuf/NestedBuildersTest.java)2
-rw-r--r--java/core/src/test/java/com/google/protobuf/NioByteStringTest.java620
-rw-r--r--java/core/src/test/java/com/google/protobuf/ParseExceptionsTest.java273
-rw-r--r--java/core/src/test/java/com/google/protobuf/ParserTest.java (renamed from java/src/test/java/com/google/protobuf/ParserTest.java)20
-rw-r--r--java/core/src/test/java/com/google/protobuf/ProtobufArrayListTest.java (renamed from java/src/test/java/com/google/protobuf/ProtobufArrayListTest.java)18
-rw-r--r--java/core/src/test/java/com/google/protobuf/RepeatedFieldBuilderV3Test.java (renamed from java/src/test/java/com/google/protobuf/RepeatedFieldBuilderTest.java)26
-rw-r--r--java/core/src/test/java/com/google/protobuf/RopeByteStringSubstringTest.java (renamed from java/src/test/java/com/google/protobuf/RopeByteStringSubstringTest.java)2
-rw-r--r--java/core/src/test/java/com/google/protobuf/RopeByteStringTest.java (renamed from java/src/test/java/com/google/protobuf/RopeByteStringTest.java)0
-rw-r--r--java/core/src/test/java/com/google/protobuf/ServiceTest.java326
-rw-r--r--java/core/src/test/java/com/google/protobuf/SingleFieldBuilderV3Test.java (renamed from java/src/test/java/com/google/protobuf/SingleFieldBuilderTest.java)20
-rw-r--r--java/core/src/test/java/com/google/protobuf/SmallSortedMapTest.java (renamed from java/src/test/java/com/google/protobuf/SmallSortedMapTest.java)3
-rw-r--r--java/core/src/test/java/com/google/protobuf/TestBadIdentifiers.java (renamed from java/src/test/java/com/google/protobuf/TestBadIdentifiers.java)0
-rw-r--r--java/core/src/test/java/com/google/protobuf/TestUtil.java (renamed from java/src/test/java/com/google/protobuf/TestUtil.java)601
-rw-r--r--java/core/src/test/java/com/google/protobuf/TestUtilLite.java559
-rw-r--r--java/core/src/test/java/com/google/protobuf/TextFormatParseInfoTreeTest.java182
-rw-r--r--java/core/src/test/java/com/google/protobuf/TextFormatParseLocationTest.java86
-rw-r--r--java/core/src/test/java/com/google/protobuf/TextFormatTest.java (renamed from java/src/test/java/com/google/protobuf/TextFormatTest.java)119
-rw-r--r--java/core/src/test/java/com/google/protobuf/UnknownEnumValueTest.java (renamed from java/src/test/java/com/google/protobuf/UnknownEnumValueTest.java)0
-rw-r--r--java/core/src/test/java/com/google/protobuf/UnknownFieldSetLiteTest.java (renamed from java/src/test/java/com/google/protobuf/UnknownFieldSetLiteTest.java)40
-rw-r--r--java/core/src/test/java/com/google/protobuf/UnknownFieldSetTest.java (renamed from java/src/test/java/com/google/protobuf/UnknownFieldSetTest.java)1
-rw-r--r--java/core/src/test/java/com/google/protobuf/UnmodifiableLazyStringListTest.java (renamed from java/src/test/java/com/google/protobuf/UnmodifiableLazyStringListTest.java)0
-rw-r--r--java/core/src/test/java/com/google/protobuf/WellKnownTypesTest.java (renamed from java/src/test/java/com/google/protobuf/WellKnownTypesTest.java)0
-rw-r--r--java/core/src/test/java/com/google/protobuf/WireFormatTest.java (renamed from java/src/test/java/com/google/protobuf/WireFormatTest.java)32
-rw-r--r--java/core/src/test/proto/com/google/protobuf/any_test.proto (renamed from java/src/test/java/com/google/protobuf/any_test.proto)0
-rw-r--r--java/core/src/test/proto/com/google/protobuf/field_presence_test.proto (renamed from java/src/test/java/com/google/protobuf/field_presence_test.proto)2
-rw-r--r--java/core/src/test/proto/com/google/protobuf/lazy_fields_lite.proto (renamed from java/src/test/java/com/google/protobuf/lazy_fields_lite.proto)0
-rw-r--r--java/core/src/test/proto/com/google/protobuf/lite_equals_and_hash.proto (renamed from java/src/test/java/com/google/protobuf/lite_equals_and_hash.proto)15
-rw-r--r--java/core/src/test/proto/com/google/protobuf/map_for_proto2_lite_test.proto (renamed from java/src/test/java/com/google/protobuf/map_for_proto2_lite_test.proto)11
-rw-r--r--java/core/src/test/proto/com/google/protobuf/map_for_proto2_test.proto (renamed from java/src/test/java/com/google/protobuf/map_for_proto2_test.proto)11
-rw-r--r--java/core/src/test/proto/com/google/protobuf/map_initialization_order_test.proto (renamed from java/src/test/java/com/google/protobuf/map_initialization_order_test.proto)0
-rw-r--r--java/core/src/test/proto/com/google/protobuf/map_test.proto (renamed from java/src/test/java/com/google/protobuf/map_test.proto)13
-rw-r--r--java/core/src/test/proto/com/google/protobuf/multiple_files_test.proto (renamed from java/src/test/java/com/google/protobuf/multiple_files_test.proto)0
-rw-r--r--java/core/src/test/proto/com/google/protobuf/nested_builders_test.proto (renamed from java/src/test/java/com/google/protobuf/nested_builders_test.proto)0
-rw-r--r--java/core/src/test/proto/com/google/protobuf/nested_extension.proto (renamed from java/src/test/java/com/google/protobuf/nested_extension.proto)0
-rw-r--r--java/core/src/test/proto/com/google/protobuf/nested_extension_lite.proto (renamed from java/src/test/java/com/google/protobuf/nested_extension_lite.proto)0
-rw-r--r--java/core/src/test/proto/com/google/protobuf/non_nested_extension.proto (renamed from java/src/test/java/com/google/protobuf/non_nested_extension.proto)0
-rw-r--r--java/core/src/test/proto/com/google/protobuf/non_nested_extension_lite.proto (renamed from java/src/test/java/com/google/protobuf/non_nested_extension_lite.proto)0
-rw-r--r--java/core/src/test/proto/com/google/protobuf/outer_class_name_test.proto (renamed from java/src/test/java/com/google/protobuf/outer_class_name_test.proto)0
-rw-r--r--java/core/src/test/proto/com/google/protobuf/outer_class_name_test2.proto (renamed from java/src/test/java/com/google/protobuf/outer_class_name_test2.proto)0
-rw-r--r--java/core/src/test/proto/com/google/protobuf/outer_class_name_test3.proto (renamed from java/src/test/java/com/google/protobuf/outer_class_name_test3.proto)0
-rw-r--r--java/core/src/test/proto/com/google/protobuf/test_bad_identifiers.proto (renamed from java/src/test/java/com/google/protobuf/test_bad_identifiers.proto)1
-rw-r--r--java/core/src/test/proto/com/google/protobuf/test_check_utf8.proto (renamed from java/src/test/java/com/google/protobuf/test_check_utf8.proto)0
-rw-r--r--java/core/src/test/proto/com/google/protobuf/test_check_utf8_size.proto (renamed from java/src/test/java/com/google/protobuf/test_check_utf8_size.proto)0
-rw-r--r--java/core/src/test/proto/com/google/protobuf/test_custom_options.proto (renamed from java/src/test/java/com/google/protobuf/test_custom_options.proto)0
-rw-r--r--java/core/src/test/proto/com/google/protobuf/test_extra_interfaces.proto (renamed from java/src/test/java/com/google/protobuf/test_extra_interfaces.proto)0
-rw-r--r--java/lite/generate-sources-build.xml20
-rw-r--r--java/lite/generate-test-sources-build.xml43
-rw-r--r--java/lite/pom.xml156
-rw-r--r--java/pom.xml393
-rw-r--r--java/src/main/java/com/google/protobuf/BoundedByteString.java180
-rw-r--r--java/src/main/java/com/google/protobuf/CodedOutputStream.java1385
-rw-r--r--java/src/main/java/com/google/protobuf/LiteralByteString.java372
-rw-r--r--java/src/main/java/com/google/protobuf/MapEntryLite.java331
-rw-r--r--java/src/main/java/com/google/protobuf/MapFieldLite.java546
-rw-r--r--java/src/main/java/com/google/protobuf/Utf8.java481
-rw-r--r--java/src/test/java/com/google/protobuf/MapForProto2LiteTest.java458
-rw-r--r--java/util/pom.xml185
-rw-r--r--java/util/src/main/java/com/google/protobuf/util/Durations.java256
-rw-r--r--java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java125
-rw-r--r--java/util/src/main/java/com/google/protobuf/util/FieldMaskUtil.java184
-rw-r--r--java/util/src/main/java/com/google/protobuf/util/JsonFormat.java1049
-rw-r--r--java/util/src/main/java/com/google/protobuf/util/TimeUtil.java377
-rw-r--r--java/util/src/main/java/com/google/protobuf/util/Timestamps.java349
-rw-r--r--java/util/src/test/java/com/google/protobuf/util/FieldMaskTreeTest.java144
-rw-r--r--java/util/src/test/java/com/google/protobuf/util/FieldMaskUtilTest.java144
-rw-r--r--java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java1339
-rw-r--r--java/util/src/test/java/com/google/protobuf/util/TimeUtilTest.java122
-rw-r--r--java/util/src/test/proto/com/google/protobuf/util/json_test.proto (renamed from java/util/src/test/java/com/google/protobuf/util/json_test.proto)44
-rw-r--r--javanano/pom.xml4
-rw-r--r--javanano/src/main/java/com/google/protobuf/nano/FieldArray.java4
-rw-r--r--javanano/src/main/java/com/google/protobuf/nano/MessageNanoPrinter.java2
-rw-r--r--jenkins/README.md6
-rwxr-xr-xjenkins/build_and_run_docker.sh56
-rw-r--r--jenkins/buildcmds/README.md6
-rwxr-xr-xjenkins/buildcmds/pull_request.sh15
-rw-r--r--jenkins/docker/Dockerfile153
-rw-r--r--jenkins/make_test_output.py91
-rwxr-xr-xjenkins/pull_request_in_docker.sh74
-rw-r--r--js/README.md158
-rw-r--r--js/binary/arith.js413
-rw-r--r--js/binary/arith_test.js355
-rw-r--r--js/binary/constants.js360
-rw-r--r--js/binary/decoder.js1007
-rw-r--r--js/binary/decoder_test.js334
-rw-r--r--js/binary/encoder.js430
-rw-r--r--js/binary/proto_test.js628
-rw-r--r--js/binary/reader.js1127
-rw-r--r--js/binary/reader_test.js922
-rw-r--r--js/binary/utils.js975
-rw-r--r--js/binary/utils_test.js668
-rw-r--r--js/binary/writer.js1577
-rw-r--r--js/binary/writer_test.js123
-rw-r--r--js/commonjs/export.js24
-rw-r--r--js/commonjs/export_asserts.js37
-rw-r--r--js/commonjs/export_testdeps.js18
-rw-r--r--js/commonjs/import_test.js52
-rw-r--r--js/commonjs/jasmine.json9
-rw-r--r--js/commonjs/rewrite_tests_for_commonjs.js97
-rw-r--r--js/commonjs/test6/test6.proto40
-rw-r--r--js/commonjs/test7/test7.proto42
-rw-r--r--js/data.proto51
-rw-r--r--js/debug.js142
-rw-r--r--js/debug_test.js105
-rw-r--r--js/gulpfile.js143
-rw-r--r--js/jasmine.json12
-rw-r--r--js/map.js463
-rw-r--r--js/message.js1431
-rw-r--r--js/message_test.js1080
-rw-r--r--js/node_loader.js (renamed from src/google/protobuf/util/internal/snake2camel_objectwriter_test.cc)38
-rw-r--r--js/package.json26
-rw-r--r--js/proto3_test.js329
-rw-r--r--js/proto3_test.proto89
-rw-r--r--js/test.proto236
-rw-r--r--js/test2.proto54
-rw-r--r--js/test3.proto53
-rw-r--r--js/test4.proto (renamed from src/google/protobuf/compiler/cpp/test_large_enum_value.proto)17
-rw-r--r--js/test5.proto44
-rw-r--r--js/test_bootstrap.js41
-rw-r--r--js/testbinary.proto212
-rw-r--r--js/testempty.proto34
-rw-r--r--m4/acx_check_suncc.m417
-rw-r--r--m4/stl_hash.m43
-rw-r--r--objectivec/.gitignore23
-rwxr-xr-xobjectivec/DevTools/compile_testing_protos.sh65
-rwxr-xr-xobjectivec/DevTools/full_mac_build.sh115
-rwxr-xr-xobjectivec/DevTools/pddm.py3
-rw-r--r--objectivec/GPBArray.h34
-rw-r--r--objectivec/GPBArray.m192
-rw-r--r--objectivec/GPBBootstrap.h11
-rw-r--r--objectivec/GPBCodedInputStream.h108
-rw-r--r--objectivec/GPBCodedInputStream.m412
-rw-r--r--objectivec/GPBCodedInputStream_PackagePrivate.h17
-rw-r--r--objectivec/GPBCodedOutputStream.h238
-rw-r--r--objectivec/GPBCodedOutputStream.m27
-rw-r--r--objectivec/GPBCodedOutputStream_PackagePrivate.h126
-rw-r--r--objectivec/GPBDescriptor.h20
-rw-r--r--objectivec/GPBDescriptor.m387
-rw-r--r--objectivec/GPBDescriptor_PackagePrivate.h191
-rw-r--r--objectivec/GPBDictionary.h1135
-rw-r--r--objectivec/GPBDictionary.m2224
-rw-r--r--objectivec/GPBExtensionInternals.m13
-rw-r--r--objectivec/GPBExtensionRegistry.h53
-rw-r--r--objectivec/GPBExtensionRegistry.m8
-rw-r--r--objectivec/GPBMessage.h293
-rw-r--r--objectivec/GPBMessage.m178
-rw-r--r--objectivec/GPBMessage_PackagePrivate.h26
-rw-r--r--objectivec/GPBProtocolBuffers.h39
-rw-r--r--objectivec/GPBProtocolBuffers.m16
-rw-r--r--objectivec/GPBRootObject.h7
-rw-r--r--objectivec/GPBRootObject.m28
-rw-r--r--objectivec/GPBRuntimeTypes.h4
-rw-r--r--objectivec/GPBUnknownField.h37
-rw-r--r--objectivec/GPBUnknownField.m14
-rw-r--r--objectivec/GPBUnknownFieldSet.h19
-rw-r--r--objectivec/GPBUnknownFieldSet.m11
-rw-r--r--objectivec/GPBUtilities.h150
-rw-r--r--objectivec/GPBUtilities.m122
-rw-r--r--objectivec/GPBUtilities_PackagePrivate.h10
-rw-r--r--objectivec/GPBWellKnownTypes.h15
-rw-r--r--objectivec/GPBWellKnownTypes.m2
-rw-r--r--objectivec/GPBWireFormat.h1
-rw-r--r--objectivec/GPBWireFormat.m7
-rw-r--r--objectivec/ProtocolBuffers_OSX.xcodeproj/project.pbxproj82
-rw-r--r--objectivec/ProtocolBuffers_OSX.xcodeproj/xcshareddata/xcschemes/PerformanceTests.xcscheme6
-rw-r--r--objectivec/ProtocolBuffers_OSX.xcodeproj/xcshareddata/xcschemes/ProtocolBuffers.xcscheme3
-rw-r--r--objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj82
-rw-r--r--objectivec/ProtocolBuffers_iOS.xcodeproj/xcshareddata/xcbaselines/8BBEA4A5147C727100C4ADB7.xcbaseline/FFE465CA-0E74-40E8-9F09-500B66B7DCB2.plist62
-rw-r--r--objectivec/ProtocolBuffers_iOS.xcodeproj/xcshareddata/xcbaselines/8BBEA4A5147C727100C4ADB7.xcbaseline/Info.plist21
-rw-r--r--objectivec/ProtocolBuffers_iOS.xcodeproj/xcshareddata/xcschemes/PerformanceTests.xcscheme6
-rw-r--r--objectivec/ProtocolBuffers_iOS.xcodeproj/xcshareddata/xcschemes/ProtocolBuffers.xcscheme3
-rw-r--r--objectivec/README.md42
-rw-r--r--objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester.xcodeproj/project.pbxproj290
-rw-r--r--objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester.xcodeproj/project.xcworkspace/contents.xcworkspacedata7
-rw-r--r--objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester.xcodeproj/xcshareddata/xcschemes/OSXCocoaPodsTester.xcscheme91
-rw-r--r--objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/AppDelegate.h37
-rw-r--r--objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/AppDelegate.m48
-rw-r--r--objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/Assets.xcassets/AppIcon.appiconset/Contents.json58
-rw-r--r--objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/Base.lproj/MainMenu.xib680
-rw-r--r--objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/Info.plist34
-rw-r--r--objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/main.m35
-rw-r--r--objectivec/Tests/CocoaPods/OSXCocoaPodsTester/Podfile-framework10
-rw-r--r--objectivec/Tests/CocoaPods/OSXCocoaPodsTester/Podfile-static8
-rw-r--r--objectivec/Tests/CocoaPods/README.md9
-rw-r--r--objectivec/Tests/CocoaPods/iOSCocoaPodsTester/Podfile-framework10
-rw-r--r--objectivec/Tests/CocoaPods/iOSCocoaPodsTester/Podfile-static8
-rw-r--r--objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester.xcodeproj/project.pbxproj309
-rw-r--r--objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester.xcodeproj/project.xcworkspace/contents.xcworkspacedata7
-rw-r--r--objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester.xcodeproj/xcshareddata/xcschemes/iOSCocoaPodsTester.xcscheme91
-rw-r--r--objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/AppDelegate.h39
-rw-r--r--objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/AppDelegate.m67
-rw-r--r--objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/Assets.xcassets/AppIcon.appiconset/Contents.json68
-rw-r--r--objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/Base.lproj/LaunchScreen.storyboard27
-rw-r--r--objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/Base.lproj/Main.storyboard26
-rw-r--r--objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/Info.plist47
-rw-r--r--objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/ViewController.h37
-rw-r--r--objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/ViewController.m49
-rw-r--r--objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/main.m39
-rwxr-xr-xobjectivec/Tests/CocoaPods/run_tests.sh150
-rw-r--r--objectivec/Tests/GPBARCUnittestProtos.m5
-rw-r--r--objectivec/Tests/GPBCodedInputStreamTests.m53
-rw-r--r--objectivec/Tests/GPBCodedOuputStreamTests.m21
-rw-r--r--objectivec/Tests/GPBDescriptorTests.m21
-rw-r--r--objectivec/Tests/GPBDictionaryTests+Bool.m1086
-rw-r--r--objectivec/Tests/GPBDictionaryTests+Int32.m2108
-rw-r--r--objectivec/Tests/GPBDictionaryTests+Int64.m2108
-rw-r--r--objectivec/Tests/GPBDictionaryTests+String.m2036
-rw-r--r--objectivec/Tests/GPBDictionaryTests+UInt32.m2108
-rw-r--r--objectivec/Tests/GPBDictionaryTests+UInt64.m2108
-rw-r--r--objectivec/Tests/GPBDictionaryTests.pddm535
-rw-r--r--objectivec/Tests/GPBMessageTests+Merge.m4
-rw-r--r--objectivec/Tests/GPBMessageTests+Runtime.m41
-rw-r--r--objectivec/Tests/GPBMessageTests+Serialization.m189
-rw-r--r--objectivec/Tests/GPBMessageTests.m106
-rw-r--r--objectivec/Tests/GPBStringTests.m513
-rw-r--r--objectivec/Tests/GPBSwiftTests.swift42
-rw-r--r--objectivec/Tests/GPBTestUtilities.m30
-rw-r--r--objectivec/Tests/GPBUnittestProtos.m5
-rw-r--r--objectivec/Tests/GPBUnknownFieldSetTest.m4
-rw-r--r--objectivec/Tests/GPBUtilitiesTests.m27
-rw-r--r--objectivec/Tests/GPBWireFormatTests.m9
-rw-r--r--objectivec/Tests/unittest_objc.proto67
-rwxr-xr-xobjectivec/generate_well_known_types.sh (renamed from objectivec/generate_descriptors_proto.sh)36
-rw-r--r--objectivec/google/protobuf/Any.pbobjc.h174
-rw-r--r--objectivec/google/protobuf/Any.pbobjc.m57
-rw-r--r--objectivec/google/protobuf/Api.pbobjc.h300
-rw-r--r--objectivec/google/protobuf/Api.pbobjc.m181
-rw-r--r--objectivec/google/protobuf/Descriptor.pbobjc.h1160
-rw-r--r--objectivec/google/protobuf/Descriptor.pbobjc.m2445
-rw-r--r--objectivec/google/protobuf/Duration.pbobjc.h129
-rw-r--r--objectivec/google/protobuf/Duration.pbobjc.m46
-rw-r--r--objectivec/google/protobuf/Empty.pbobjc.h51
-rw-r--r--objectivec/google/protobuf/Empty.pbobjc.m34
-rw-r--r--objectivec/google/protobuf/FieldMask.pbobjc.h362
-rw-r--r--objectivec/google/protobuf/FieldMask.pbobjc.m40
-rw-r--r--objectivec/google/protobuf/SourceContext.pbobjc.h41
-rw-r--r--objectivec/google/protobuf/SourceContext.pbobjc.m40
-rw-r--r--objectivec/google/protobuf/Struct.pbobjc.h115
-rw-r--r--objectivec/google/protobuf/Struct.pbobjc.m139
-rw-r--r--objectivec/google/protobuf/Timestamp.pbobjc.h153
-rw-r--r--objectivec/google/protobuf/Timestamp.pbobjc.m46
-rw-r--r--objectivec/google/protobuf/Type.pbobjc.h233
-rw-r--r--objectivec/google/protobuf/Type.pbobjc.m370
-rw-r--r--objectivec/google/protobuf/Wrappers.pbobjc.h105
-rw-r--r--objectivec/google/protobuf/Wrappers.pbobjc.m169
-rw-r--r--php/ext/google/protobuf/config.m410
-rw-r--r--php/ext/google/protobuf/def.c381
-rw-r--r--php/ext/google/protobuf/message.c273
-rw-r--r--php/ext/google/protobuf/protobuf.c89
-rw-r--r--php/ext/google/protobuf/protobuf.h281
-rw-r--r--php/ext/google/protobuf/storage.c539
-rw-r--r--php/ext/google/protobuf/test.php15
-rw-r--r--php/ext/google/protobuf/upb.c11990
-rw-r--r--php/ext/google/protobuf/upb.h8217
-rw-r--r--php/tests/autoload.php4
-rwxr-xr-xpost_process_dist.sh2
-rw-r--r--protobuf.bzl150
-rw-r--r--protoc-artifacts/Dockerfile4
-rw-r--r--protoc-artifacts/README.md46
-rwxr-xr-xprotoc-artifacts/build-protoc.sh29
-rwxr-xr-xprotoc-artifacts/build-zip.sh108
-rw-r--r--protoc-artifacts/pom.xml3
-rw-r--r--python/README.md12
-rwxr-xr-xpython/google/__init__.py5
-rwxr-xr-xpython/google/protobuf/__init__.py8
-rwxr-xr-xpython/google/protobuf/descriptor.py65
-rw-r--r--python/google/protobuf/descriptor_database.py4
-rw-r--r--python/google/protobuf/descriptor_pool.py138
-rwxr-xr-xpython/google/protobuf/internal/_parameterized.py2
-rw-r--r--python/google/protobuf/internal/any_test.proto42
-rwxr-xr-xpython/google/protobuf/internal/api_implementation.py6
-rwxr-xr-xpython/google/protobuf/internal/containers.py29
-rw-r--r--python/google/protobuf/internal/descriptor_database_test.py3
-rw-r--r--python/google/protobuf/internal/descriptor_pool_test.py187
-rw-r--r--python/google/protobuf/internal/descriptor_pool_test2.proto1
-rwxr-xr-xpython/google/protobuf/internal/descriptor_test.py64
-rw-r--r--python/google/protobuf/internal/file_options_test.proto43
-rwxr-xr-xpython/google/protobuf/internal/generator_test.py3
-rw-r--r--python/google/protobuf/internal/json_format_test.py351
-rw-r--r--python/google/protobuf/internal/message_factory_test.py64
-rw-r--r--python/google/protobuf/internal/message_set_extensions.proto8
-rwxr-xr-xpython/google/protobuf/internal/message_test.py161
-rw-r--r--python/google/protobuf/internal/proto_builder_test.py1
-rwxr-xr-xpython/google/protobuf/internal/python_message.py147
-rwxr-xr-xpython/google/protobuf/internal/reflection_test.py34
-rwxr-xr-xpython/google/protobuf/internal/service_reflection_test.py4
-rw-r--r--python/google/protobuf/internal/symbol_database_test.py29
-rwxr-xr-xpython/google/protobuf/internal/test_util.py2
-rwxr-xr-xpython/google/protobuf/internal/text_encoding_test.py3
-rwxr-xr-xpython/google/protobuf/internal/text_format_test.py838
-rwxr-xr-xpython/google/protobuf/internal/type_checkers.py23
-rwxr-xr-xpython/google/protobuf/internal/unknown_fields_test.py22
-rw-r--r--python/google/protobuf/internal/well_known_types.py724
-rw-r--r--python/google/protobuf/internal/well_known_types_test.py644
-rwxr-xr-xpython/google/protobuf/internal/wire_format_test.py3
-rw-r--r--python/google/protobuf/json_format.py840
-rwxr-xr-xpython/google/protobuf/message.py3
-rw-r--r--python/google/protobuf/message_factory.py4
-rw-r--r--python/google/protobuf/pyext/__init__.py4
-rw-r--r--python/google/protobuf/pyext/cpp_message.py6
-rw-r--r--python/google/protobuf/pyext/descriptor.cc319
-rw-r--r--python/google/protobuf/pyext/descriptor.h6
-rw-r--r--python/google/protobuf/pyext/descriptor_containers.cc158
-rw-r--r--python/google/protobuf/pyext/descriptor_containers.h8
-rw-r--r--python/google/protobuf/pyext/descriptor_database.cc148
-rw-r--r--python/google/protobuf/pyext/descriptor_database.h75
-rw-r--r--python/google/protobuf/pyext/descriptor_pool.cc157
-rw-r--r--python/google/protobuf/pyext/descriptor_pool.h21
-rw-r--r--python/google/protobuf/pyext/extension_dict.cc66
-rw-r--r--python/google/protobuf/pyext/extension_dict.h11
-rw-r--r--python/google/protobuf/pyext/map_container.cc970
-rw-r--r--python/google/protobuf/pyext/map_container.h (renamed from python/google/protobuf/pyext/message_map_container.h)72
-rw-r--r--python/google/protobuf/pyext/message.cc542
-rw-r--r--python/google/protobuf/pyext/message.h42
-rw-r--r--python/google/protobuf/pyext/message_map_container.cc569
-rw-r--r--python/google/protobuf/pyext/message_module.cc88
-rw-r--r--python/google/protobuf/pyext/repeated_composite_container.cc16
-rw-r--r--python/google/protobuf/pyext/repeated_composite_container.h7
-rw-r--r--python/google/protobuf/pyext/scalar_map_container.cc542
-rw-r--r--python/google/protobuf/pyext/scalar_map_container.h119
-rwxr-xr-xpython/google/protobuf/reflection.py8
-rw-r--r--python/google/protobuf/symbol_database.py110
-rwxr-xr-xpython/google/protobuf/text_format.py1284
-rw-r--r--python/google/protobuf/util/__init__.py0
-rw-r--r--python/setup.cfg2
-rwxr-xr-xpython/setup.py56
-rw-r--r--python/tox.ini2
-rw-r--r--ruby/Gemfile.lock6
-rw-r--r--ruby/README.md28
-rw-r--r--ruby/Rakefile74
-rw-r--r--ruby/ext/google/protobuf_c/defs.c10
-rw-r--r--ruby/ext/google/protobuf_c/encode_decode.c124
-rw-r--r--ruby/ext/google/protobuf_c/map.c20
-rw-r--r--ruby/ext/google/protobuf_c/message.c46
-rw-r--r--ruby/ext/google/protobuf_c/protobuf.h7
-rw-r--r--ruby/ext/google/protobuf_c/repeated_field.c5
-rw-r--r--ruby/ext/google/protobuf_c/storage.c72
-rw-r--r--ruby/ext/google/protobuf_c/upb.c3208
-rw-r--r--ruby/ext/google/protobuf_c/upb.h2972
-rw-r--r--ruby/google-protobuf.gemspec13
-rw-r--r--ruby/lib/google/protobuf.rb6
-rw-r--r--ruby/lib/google/protobuf/repeated_field.rb6
-rw-r--r--ruby/lib/google/protobuf/well_known_types.rb212
-rw-r--r--ruby/pom.xml2
-rw-r--r--ruby/src/main/java/com/google/protobuf/jruby/RubyMap.java4
-rw-r--r--ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java32
-rw-r--r--ruby/src/main/java/com/google/protobuf/jruby/RubyRepeatedField.java4
-rw-r--r--ruby/src/main/java/com/google/protobuf/jruby/Utils.java37
-rw-r--r--ruby/src/main/sentinel.proto18
-rw-r--r--ruby/tests/basic.rb122
-rw-r--r--ruby/tests/generated_code.proto2
-rw-r--r--ruby/tests/generated_code.rb74
-rw-r--r--ruby/tests/generated_code_test.rb4
-rw-r--r--ruby/tests/test_import.proto5
-rw-r--r--ruby/tests/well_known_types_test.rb122
-rwxr-xr-xruby/travis-test.sh7
-rw-r--r--src/Makefile.am74
-rw-r--r--src/README.md212
-rw-r--r--src/google/protobuf/any.cc45
-rw-r--r--src/google/protobuf/any.h20
-rw-r--r--src/google/protobuf/any.pb.cc50
-rw-r--r--src/google/protobuf/any.pb.h12
-rw-r--r--src/google/protobuf/any.proto72
-rw-r--r--src/google/protobuf/api.pb.cc116
-rw-r--r--src/google/protobuf/api.pb.h32
-rw-r--r--src/google/protobuf/api.proto5
-rwxr-xr-xsrc/google/protobuf/arena.cc26
-rw-r--r--src/google/protobuf/arena.h38
-rw-r--r--src/google/protobuf/arena_nc_test.py2
-rw-r--r--src/google/protobuf/arena_unittest.cc59
-rwxr-xr-xsrc/google/protobuf/arenastring.h14
-rw-r--r--src/google/protobuf/arenastring_unittest.cc3
-rw-r--r--src/google/protobuf/compiler/command_line_interface.cc115
-rw-r--r--src/google/protobuf/compiler/command_line_interface.h4
-rw-r--r--src/google/protobuf/compiler/command_line_interface_unittest.cc52
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc3
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_enum.cc46
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_enum.h17
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_enum_field.cc46
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_enum_field.h11
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_field.cc3
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_field.h8
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_file.cc216
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_file.h19
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_generator.cc40
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_helpers.cc69
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_helpers.h85
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_map_field.cc291
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_map_field.h7
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_message.cc426
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_message.h12
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_message_field.cc108
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_message_field.h12
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_options.h14
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc3
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_primitive_field.cc35
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_primitive_field.h12
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_service.cc8
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_string_field.cc93
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_string_field.h12
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_unittest.cc3
-rw-r--r--src/google/protobuf/compiler/cpp/metadata_test.cc242
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_enum.cc23
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_enum.h2
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_enum_field.cc11
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_enum_field.h8
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_field_base.cc21
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_field_base.h4
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_generator.cc28
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_generator_unittest.cc20
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_helpers.cc129
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_helpers.h24
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_map_field.cc16
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_map_field.h4
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_message.cc95
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_message.h2
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_message_field.cc18
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_message_field.h8
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_options.h79
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_primitive_field.cc17
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_primitive_field.h10
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_reflection_class.cc23
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_reflection_class.h6
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc6
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.h4
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc12
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_repeated_message_field.h6
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc6
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h2
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_source_generator_base.cc15
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_source_generator_base.h8
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc15
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_wrapper_field.h10
-rw-r--r--src/google/protobuf/compiler/importer.cc13
-rw-r--r--src/google/protobuf/compiler/importer.h9
-rw-r--r--src/google/protobuf/compiler/importer_unittest.cc21
-rw-r--r--src/google/protobuf/compiler/java/java_context.cc11
-rw-r--r--src/google/protobuf/compiler/java/java_context.h16
-rw-r--r--src/google/protobuf/compiler/java/java_doc_comment.cc56
-rw-r--r--src/google/protobuf/compiler/java/java_enum.cc96
-rw-r--r--src/google/protobuf/compiler/java/java_enum.h5
-rw-r--r--src/google/protobuf/compiler/java/java_enum_field.cc42
-rw-r--r--src/google/protobuf/compiler/java/java_enum_field_lite.cc152
-rw-r--r--src/google/protobuf/compiler/java/java_enum_field_lite.h6
-rw-r--r--src/google/protobuf/compiler/java/java_enum_lite.cc47
-rw-r--r--src/google/protobuf/compiler/java/java_enum_lite.h5
-rw-r--r--src/google/protobuf/compiler/java/java_extension.cc87
-rw-r--r--src/google/protobuf/compiler/java/java_extension_lite.cc118
-rw-r--r--src/google/protobuf/compiler/java/java_extension_lite.h76
-rw-r--r--src/google/protobuf/compiler/java/java_field.cc12
-rw-r--r--src/google/protobuf/compiler/java/java_field.h2
-rw-r--r--src/google/protobuf/compiler/java/java_file.cc140
-rw-r--r--src/google/protobuf/compiler/java/java_file.h10
-rw-r--r--src/google/protobuf/compiler/java/java_generator.cc83
-rw-r--r--src/google/protobuf/compiler/java/java_generator_factory.cc14
-rw-r--r--src/google/protobuf/compiler/java/java_helpers.cc23
-rw-r--r--src/google/protobuf/compiler/java/java_helpers.h95
-rw-r--r--src/google/protobuf/compiler/java/java_lazy_message_field.cc12
-rw-r--r--src/google/protobuf/compiler/java/java_lazy_message_field_lite.cc83
-rw-r--r--src/google/protobuf/compiler/java/java_lazy_message_field_lite.h4
-rw-r--r--src/google/protobuf/compiler/java/java_map_field.cc426
-rw-r--r--src/google/protobuf/compiler/java/java_map_field.h1
-rw-r--r--src/google/protobuf/compiler/java/java_map_field_lite.cc513
-rw-r--r--src/google/protobuf/compiler/java/java_map_field_lite.h2
-rw-r--r--src/google/protobuf/compiler/java/java_message.cc274
-rw-r--r--src/google/protobuf/compiler/java/java_message.h13
-rw-r--r--src/google/protobuf/compiler/java/java_message_builder.cc106
-rw-r--r--src/google/protobuf/compiler/java/java_message_builder_lite.cc19
-rw-r--r--src/google/protobuf/compiler/java/java_message_field.cc40
-rw-r--r--src/google/protobuf/compiler/java/java_message_field_lite.cc57
-rw-r--r--src/google/protobuf/compiler/java/java_message_field_lite.h6
-rw-r--r--src/google/protobuf/compiler/java/java_message_lite.cc387
-rw-r--r--src/google/protobuf/compiler/java/java_message_lite.h11
-rw-r--r--src/google/protobuf/compiler/java/java_name_resolver.cc7
-rw-r--r--src/google/protobuf/compiler/java/java_name_resolver.h1
-rw-r--r--src/google/protobuf/compiler/java/java_options.h73
-rw-r--r--src/google/protobuf/compiler/java/java_plugin_unittest.cc3
-rw-r--r--src/google/protobuf/compiler/java/java_primitive_field.cc16
-rw-r--r--src/google/protobuf/compiler/java/java_primitive_field_lite.cc129
-rw-r--r--src/google/protobuf/compiler/java/java_primitive_field_lite.h6
-rw-r--r--src/google/protobuf/compiler/java/java_service.cc5
-rw-r--r--src/google/protobuf/compiler/java/java_service.h4
-rw-r--r--src/google/protobuf/compiler/java/java_shared_code_generator.cc49
-rw-r--r--src/google/protobuf/compiler/java/java_shared_code_generator.h8
-rw-r--r--src/google/protobuf/compiler/java/java_string_field.cc118
-rw-r--r--src/google/protobuf/compiler/java/java_string_field.h1
-rw-r--r--src/google/protobuf/compiler/java/java_string_field_lite.cc130
-rw-r--r--src/google/protobuf/compiler/java/java_string_field_lite.h7
-rw-r--r--src/google/protobuf/compiler/javanano/javanano_generator.cc8
-rw-r--r--src/google/protobuf/compiler/javanano/javanano_helpers.cc8
-rwxr-xr-xsrc/google/protobuf/compiler/js/js_generator.cc3307
-rwxr-xr-xsrc/google/protobuf/compiler/js/js_generator.h281
-rw-r--r--src/google/protobuf/compiler/main.cc16
-rw-r--r--src/google/protobuf/compiler/mock_code_generator.cc18
-rw-r--r--src/google/protobuf/compiler/mock_code_generator.h5
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_enum.cc77
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc35
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_enum_field.h14
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_extension.cc8
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_field.cc225
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_field.h46
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_file.cc365
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_file.h9
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_generator.cc70
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_helpers.cc439
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_helpers.h71
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_map_field.cc61
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_map_field.h9
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_message.cc287
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_message.h7
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_message_field.cc20
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_message_field.h15
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_oneof.cc18
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_oneof.h4
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc53
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_primitive_field.h24
-rw-r--r--src/google/protobuf/compiler/parser.cc74
-rw-r--r--src/google/protobuf/compiler/parser.h4
-rw-r--r--src/google/protobuf/compiler/parser_unittest.cc56
-rw-r--r--src/google/protobuf/compiler/plugin.cc81
-rw-r--r--src/google/protobuf/compiler/plugin.h18
-rw-r--r--src/google/protobuf/compiler/plugin.pb.cc94
-rw-r--r--src/google/protobuf/compiler/plugin.pb.h30
-rw-r--r--src/google/protobuf/compiler/python/python_generator.cc89
-rw-r--r--src/google/protobuf/compiler/python/python_generator.h2
-rw-r--r--src/google/protobuf/compiler/python/python_plugin_unittest.cc51
-rw-r--r--src/google/protobuf/compiler/ruby/ruby_generated_code_pb.rb (renamed from src/google/protobuf/compiler/ruby/ruby_generated_code.rb)0
-rw-r--r--src/google/protobuf/compiler/ruby/ruby_generator.cc140
-rw-r--r--src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc24
-rw-r--r--src/google/protobuf/compiler/subprocess.cc3
-rw-r--r--src/google/protobuf/descriptor.cc120
-rw-r--r--src/google/protobuf/descriptor.h45
-rw-r--r--src/google/protobuf/descriptor.pb.cc2322
-rw-r--r--src/google/protobuf/descriptor.pb.h942
-rw-r--r--src/google/protobuf/descriptor.proto42
-rw-r--r--src/google/protobuf/descriptor_database_unittest.cc1
-rw-r--r--src/google/protobuf/descriptor_unittest.cc216
-rw-r--r--src/google/protobuf/duration.pb.cc51
-rw-r--r--src/google/protobuf/duration.pb.h8
-rw-r--r--src/google/protobuf/duration.proto11
-rw-r--r--src/google/protobuf/dynamic_message.cc23
-rw-r--r--src/google/protobuf/dynamic_message_unittest.cc3
-rw-r--r--src/google/protobuf/empty.pb.cc79
-rw-r--r--src/google/protobuf/empty.pb.h21
-rw-r--r--src/google/protobuf/empty.proto9
-rw-r--r--src/google/protobuf/extension_set.cc71
-rw-r--r--src/google/protobuf/extension_set.h64
-rw-r--r--src/google/protobuf/extension_set_heavy.cc99
-rw-r--r--src/google/protobuf/extension_set_unittest.cc68
-rw-r--r--src/google/protobuf/field_mask.pb.cc37
-rw-r--r--src/google/protobuf/field_mask.pb.h9
-rw-r--r--src/google/protobuf/field_mask.proto91
-rw-r--r--src/google/protobuf/generated_message_reflection.cc59
-rw-r--r--src/google/protobuf/generated_message_reflection.h12
-rw-r--r--src/google/protobuf/generated_message_reflection_unittest.cc67
-rw-r--r--src/google/protobuf/generated_message_util.cc6
-rw-r--r--src/google/protobuf/generated_message_util.h13
-rw-r--r--src/google/protobuf/io/coded_stream.cc151
-rw-r--r--src/google/protobuf/io/coded_stream.h83
-rw-r--r--src/google/protobuf/io/coded_stream_unittest.cc2
-rw-r--r--src/google/protobuf/io/gzip_stream.cc4
-rw-r--r--src/google/protobuf/io/gzip_stream.h3
-rw-r--r--src/google/protobuf/io/printer.cc76
-rw-r--r--src/google/protobuf/io/printer.h184
-rw-r--r--src/google/protobuf/io/printer_unittest.cc237
-rw-r--r--src/google/protobuf/io/strtod.cc11
-rw-r--r--src/google/protobuf/io/strtod.h5
-rw-r--r--src/google/protobuf/io/tokenizer.cc10
-rw-r--r--src/google/protobuf/io/tokenizer.h22
-rw-r--r--src/google/protobuf/io/tokenizer_unittest.cc20
-rw-r--r--src/google/protobuf/io/zero_copy_stream_impl_lite.cc45
-rw-r--r--src/google/protobuf/io/zero_copy_stream_impl_lite.h26
-rw-r--r--src/google/protobuf/io/zero_copy_stream_unittest.cc4
-rw-r--r--src/google/protobuf/lite_unittest.cc27
-rw-r--r--src/google/protobuf/map.h1134
-rw-r--r--src/google/protobuf/map_entry.h8
-rw-r--r--src/google/protobuf/map_entry_lite.h173
-rw-r--r--src/google/protobuf/map_field.cc25
-rw-r--r--src/google/protobuf/map_field.h11
-rw-r--r--src/google/protobuf/map_field_inl.h20
-rw-r--r--src/google/protobuf/map_field_lite.h2
-rw-r--r--src/google/protobuf/map_field_test.cc4
-rw-r--r--src/google/protobuf/map_lite_unittest.proto2
-rw-r--r--src/google/protobuf/map_proto2_unittest.proto20
-rw-r--r--src/google/protobuf/map_test.cc670
-rw-r--r--src/google/protobuf/map_type_handler.h46
-rw-r--r--src/google/protobuf/map_unittest.proto2
-rw-r--r--src/google/protobuf/message.cc6
-rw-r--r--src/google/protobuf/message.h38
-rw-r--r--src/google/protobuf/message_lite.cc26
-rw-r--r--src/google/protobuf/message_lite.h29
-rw-r--r--src/google/protobuf/message_unittest.cc1
-rw-r--r--src/google/protobuf/metadata.h2
-rw-r--r--src/google/protobuf/proto3_arena_lite_unittest.cc164
-rw-r--r--src/google/protobuf/proto3_lite_unittest.cc145
-rwxr-xr-xsrc/google/protobuf/reflection.h2
-rw-r--r--src/google/protobuf/repeated_field.cc4
-rw-r--r--src/google/protobuf/repeated_field.h183
-rw-r--r--src/google/protobuf/repeated_field_reflection.h337
-rw-r--r--src/google/protobuf/repeated_field_unittest.cc38
-rw-r--r--src/google/protobuf/source_context.pb.cc37
-rw-r--r--src/google/protobuf/source_context.pb.h9
-rw-r--r--src/google/protobuf/source_context.proto9
-rw-r--r--src/google/protobuf/struct.pb.cc236
-rw-r--r--src/google/protobuf/struct.pb.h27
-rw-r--r--src/google/protobuf/struct.proto12
-rw-r--r--src/google/protobuf/stubs/atomicops.h4
-rw-r--r--src/google/protobuf/stubs/atomicops_internals_ppc_gcc.h155
-rw-r--r--src/google/protobuf/stubs/bytestream.h2
-rw-r--r--src/google/protobuf/stubs/callback.h83
-rw-r--r--[-rwxr-xr-x]src/google/protobuf/stubs/hash.h70
-rw-r--r--src/google/protobuf/stubs/int128.cc8
-rw-r--r--src/google/protobuf/stubs/logging.h2
-rw-r--r--src/google/protobuf/stubs/map_util.h7
-rw-r--r--src/google/protobuf/stubs/mathlimits.h6
-rw-r--r--src/google/protobuf/stubs/mathutil.h2
-rw-r--r--src/google/protobuf/stubs/platform_macros.h5
-rw-r--r--src/google/protobuf/stubs/port.h35
-rw-r--r--src/google/protobuf/stubs/statusor.h4
-rw-r--r--src/google/protobuf/stubs/stringpiece.h46
-rw-r--r--src/google/protobuf/stubs/stringpiece_unittest.cc17
-rw-r--r--src/google/protobuf/stubs/stringprintf.cc1
-rw-r--r--src/google/protobuf/stubs/strutil.cc86
-rw-r--r--src/google/protobuf/stubs/strutil.h32
-rw-r--r--src/google/protobuf/stubs/time.h2
-rw-r--r--src/google/protobuf/test_util.cc6
-rw-r--r--src/google/protobuf/testdata/golden_message_mapsbin0 -> 13619 bytes
-rw-r--r--src/google/protobuf/testing/googletest.cc4
-rw-r--r--src/google/protobuf/text_format.cc120
-rw-r--r--src/google/protobuf/text_format.h14
-rw-r--r--src/google/protobuf/text_format_unittest.cc79
-rw-r--r--src/google/protobuf/timestamp.pb.cc87
-rw-r--r--src/google/protobuf/timestamp.pb.h21
-rw-r--r--src/google/protobuf/timestamp.proto12
-rw-r--r--src/google/protobuf/type.pb.cc332
-rw-r--r--src/google/protobuf/type.pb.h176
-rw-r--r--src/google/protobuf/type.proto60
-rw-r--r--src/google/protobuf/unittest.proto2
-rw-r--r--src/google/protobuf/unittest_custom_options.proto36
-rw-r--r--src/google/protobuf/unittest_lite.proto22
-rw-r--r--src/google/protobuf/unittest_proto3_arena_lite.proto207
-rw-r--r--src/google/protobuf/unittest_proto3_lite.proto206
-rw-r--r--src/google/protobuf/unittest_well_known_types.proto2
-rw-r--r--src/google/protobuf/unknown_field_set.cc28
-rw-r--r--src/google/protobuf/unknown_field_set.h8
-rw-r--r--src/google/protobuf/util/field_comparator.cc24
-rw-r--r--src/google/protobuf/util/field_comparator.h4
-rw-r--r--src/google/protobuf/util/field_comparator_test.cc8
-rw-r--r--src/google/protobuf/util/field_mask_util.cc132
-rw-r--r--src/google/protobuf/util/field_mask_util.h52
-rw-r--r--src/google/protobuf/util/field_mask_util_test.cc229
-rw-r--r--src/google/protobuf/util/internal/constants.h20
-rw-r--r--src/google/protobuf/util/internal/datapiece.cc138
-rw-r--r--src/google/protobuf/util/internal/datapiece.h54
-rw-r--r--src/google/protobuf/util/internal/default_value_objectwriter.cc149
-rw-r--r--src/google/protobuf/util/internal/default_value_objectwriter.h81
-rw-r--r--src/google/protobuf/util/internal/default_value_objectwriter_test.cc68
-rw-r--r--src/google/protobuf/util/internal/error_listener.h2
-rw-r--r--src/google/protobuf/util/internal/json_escaping.cc6
-rw-r--r--src/google/protobuf/util/internal/json_objectwriter.cc20
-rw-r--r--src/google/protobuf/util/internal/json_objectwriter.h15
-rw-r--r--src/google/protobuf/util/internal/json_objectwriter_test.cc231
-rw-r--r--src/google/protobuf/util/internal/json_stream_parser.cc64
-rw-r--r--src/google/protobuf/util/internal/json_stream_parser_test.cc120
-rw-r--r--src/google/protobuf/util/internal/object_writer.h23
-rw-r--r--src/google/protobuf/util/internal/proto_writer.cc796
-rw-r--r--src/google/protobuf/util/internal/proto_writer.h345
-rw-r--r--src/google/protobuf/util/internal/protostream_objectsource.cc268
-rw-r--r--src/google/protobuf/util/internal/protostream_objectsource.h69
-rw-r--r--src/google/protobuf/util/internal/protostream_objectsource_test.cc189
-rw-r--r--src/google/protobuf/util/internal/protostream_objectwriter.cc1704
-rw-r--r--src/google/protobuf/util/internal/protostream_objectwriter.h365
-rw-r--r--src/google/protobuf/util/internal/protostream_objectwriter_test.cc665
-rw-r--r--src/google/protobuf/util/internal/snake2camel_objectwriter.h165
-rw-r--r--src/google/protobuf/util/internal/testdata/books.proto18
-rw-r--r--src/google/protobuf/util/internal/testdata/default_value.proto7
-rw-r--r--src/google/protobuf/util/internal/testdata/default_value_test.proto7
-rw-r--r--src/google/protobuf/util/internal/testdata/maps.proto29
-rw-r--r--src/google/protobuf/util/internal/type_info.cc3
-rw-r--r--src/google/protobuf/util/internal/type_info_test_helper.cc6
-rw-r--r--src/google/protobuf/util/internal/type_info_test_helper.h8
-rw-r--r--src/google/protobuf/util/internal/utility.cc46
-rw-r--r--src/google/protobuf/util/internal/utility.h9
-rw-r--r--src/google/protobuf/util/json_format_proto3.proto14
-rw-r--r--src/google/protobuf/util/json_util.cc118
-rw-r--r--src/google/protobuf/util/json_util.h78
-rw-r--r--src/google/protobuf/util/json_util_test.cc139
-rw-r--r--src/google/protobuf/util/message_differencer.cc38
-rw-r--r--src/google/protobuf/util/message_differencer.h18
-rwxr-xr-xsrc/google/protobuf/util/message_differencer_unittest.cc60
-rw-r--r--src/google/protobuf/util/time_util.cc9
-rw-r--r--src/google/protobuf/util/type_resolver_util.cc45
-rw-r--r--src/google/protobuf/util/type_resolver_util_test.cc14
-rw-r--r--src/google/protobuf/wire_format.h2
-rw-r--r--src/google/protobuf/wire_format_lite.cc14
-rw-r--r--src/google/protobuf/wire_format_lite.h40
-rw-r--r--src/google/protobuf/wire_format_lite_inl.h74
-rw-r--r--src/google/protobuf/wire_format_unittest.cc1
-rw-r--r--src/google/protobuf/wrappers.pb.cc645
-rw-r--r--src/google/protobuf/wrappers.pb.h281
-rw-r--r--src/google/protobuf/wrappers.proto10
-rwxr-xr-xtests.sh371
-rwxr-xr-xtravis.sh282
-rw-r--r--util/python/BUILD12
1060 files changed, 151195 insertions, 40382 deletions
diff --git a/.gitignore b/.gitignore
index 19e52129..5cb8cba9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -58,6 +58,7 @@ python/.eggs/
python/.tox
python/build/
python/google/protobuf/compiler/
+python/google/protobuf/util/
src/protoc
src/unittest_proto_middleman
@@ -87,16 +88,14 @@ build_msvc
# packages themselves.
/csharp/src/packages/*/
-# Directories created by opening the Objective C Xcode projects.
-objectivec/ProtocolBuffers_OSX.xcodeproj/project.xcworkspace/xcuserdata/
-objectivec/ProtocolBuffers_OSX.xcodeproj/project.xcworkspace/xcshareddata/ProtocolBuffers_OSX.xccheckout
-objectivec/ProtocolBuffers_OSX.xcodeproj/xcuserdata/
-objectivec/ProtocolBuffers_iOS.xcodeproj/project.xcworkspace/xcuserdata/
-objectivec/ProtocolBuffers_iOS.xcodeproj/project.xcworkspace/xcshareddata/ProtocolBuffers_iOS.xccheckout
-objectivec/ProtocolBuffers_iOS.xcodeproj/xcuserdata/
# OS X's Finder creates these for state about opened windows/etc.
**/.DS_Store
+# Cocoapods artifacts
+# Podfile.lock and the workspace file are tracked, to ease deleting them. That's
+# needed to trigger "pod install" to rerun the preinstall commands.
+Pods/
+
# Comformance test output
conformance/.libs/
conformance/com/
@@ -110,5 +109,7 @@ conformance/conformance.pb.h
conformance/Conformance.pbobjc.h
conformance/Conformance.pbobjc.m
conformance/conformance.rb
+conformance/google/
conformance/javac_middleman
+conformance/lite/
conformance/protoc_middleman
diff --git a/.travis.yml b/.travis.yml
index 7daee86b..094235e0 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -5,27 +5,28 @@ sudo: required
# rvm/gemfile/jdk/etc. entries rather than manually doing the work.
language: cpp
os:
- - linux
- osx
-# The Objective C build needs Xcode 6.4 or later.
-osx_image: xcode7.1
+# The Objective C build needs Xcode 7.0 or later.
+osx_image: xcode7.3
script:
- - ./travis.sh $CONFIG
+ - ./tests.sh $CONFIG
env:
- CONFIG=cpp
- CONFIG=cpp_distcheck
- - CONFIG=csharp
- CONFIG=golang
- - CONFIG=java_jdk6
- CONFIG=java_jdk7
- CONFIG=java_oracle7
- - CONFIG=javanano_jdk6
- CONFIG=javanano_jdk7
- CONFIG=javanano_oracle7
+ - CONFIG=javascript
+ # iOS build log was starting to choke travis UI, so split to cover the
+ # Xcode Debug and Release Configurations independently.
+ - CONFIG=objectivec_ios_debug
+ - CONFIG=objectivec_ios_release
+ - CONFIG=objectivec_osx
+ - CONFIG=objectivec_cocoapods_integration
- CONFIG=python
- CONFIG=python_cpp
- - CONFIG=ruby19
- - CONFIG=ruby20
- CONFIG=ruby21
- CONFIG=ruby22
- CONFIG=jruby
@@ -34,37 +35,47 @@ matrix:
# It's nontrivial to programmatically install a new JDK from the command
# line on OS X, so we rely on testing on Linux for Java code.
- os: osx
- env: CONFIG=java_jdk6
- - os: osx
env: CONFIG=java_jdk7
- os: osx
env: CONFIG=java_oracle7
- os: osx
- env: CONFIG=javanano_jdk6
- - os: osx
env: CONFIG=javanano_jdk7
- os: osx
env: CONFIG=javanano_oracle7
- # Requires installing mono, currently travis.sh is doing that with apt-get
- # which doesn't work on OS X.
- - os: osx
- env: CONFIG=csharp
# Requires installing golang, currently travis.sh is doing that with apt-get
# which doesn't work on OS X.
- os: osx
env: CONFIG=golang
- # Add into the matrix OS X tests of Objective C (needs Xcode, so it won't
- # work on other platforms). These are split so it doesn't take as long to run.
include:
- - os: osx
- env: CONFIG=objectivec_ios
- - os: osx
- env: CONFIG=objectivec_osx
+ # The dotnet environment requires Ubuntu 14.04 or 16.04. This
+ # configuration is effectively an "extra" one, outside the
+ # autogenerated matrix.
+ - os: linux
+ env: CONFIG=csharp
+ dist: trusty
+ # This test is kept on travis because it doesn't play nicely with other
+ # tests on jenkins running in parallel.
+ - os: linux
+ env: CONFIG=cpp_distcheck
+ # The Java compatibility test currently only runs on Linux because it will
+ # fetch pre-built Linux protoc binaries in the test.
+ - os: linux
+ env: CONFIG=java_compatibility
allow_failures:
# These currently do not work on OS X but are being worked on by @haberman.
- os: osx
env: CONFIG=ruby22
- os: osx
env: CONFIG=jruby
+ # https://github.com/google/protobuf/issues/1253 - Started failing when
+ # we moved to an OS X image that is 10.11.
+ - os: osx
+ env: CONFIG=python_cpp
+ # Mark the iOS test as flakey as xcodebuild some times fails to start the
+ # iOS Simulator.
+ - os: osx
+ env: CONFIG=objectivec_ios_debug
+ - os: osx
+ env: CONFIG=objectivec_ios_release
notifications:
email: false
diff --git a/BUILD b/BUILD
index 89b8162a..0941d8c4 100644
--- a/BUILD
+++ b/BUILD
@@ -15,17 +15,59 @@ COPTS = [
"-Wno-error=unused-function",
]
-# Bazel should provide portable link_opts for pthread.
-LINK_OPTS = ["-lpthread"]
+config_setting(
+ name = "android",
+ values = {
+ "crosstool_top": "//external:android/crosstool",
+ },
+)
+
+# Android builds do not need to link in a separate pthread library.
+LINK_OPTS = select({
+ ":android": [],
+ "//conditions:default": ["-lpthread"],
+})
load(
"protobuf",
"cc_proto_library",
"py_proto_library",
"internal_copied_filegroup",
+ "internal_gen_well_known_protos_java",
"internal_protobuf_py_tests",
)
+config_setting(
+ name = "ios_armv7",
+ values = {
+ "ios_cpu": "armv7",
+ },
+)
+
+config_setting(
+ name = "ios_armv7s",
+ values = {
+ "ios_cpu": "armv7s",
+ },
+)
+
+config_setting(
+ name = "ios_arm64",
+ values = {
+ "ios_cpu": "arm64",
+ },
+)
+
+IOS_ARM_COPTS = COPTS + [
+ "-DOS_IOS",
+ "-miphoneos-version-min=7.0",
+ "-arch armv7",
+ "-arch armv7s",
+ "-arch arm64",
+ "-D__thread=",
+ "-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.2.sdk/",
+]
+
cc_library(
name = "protobuf_lite",
srcs = [
@@ -55,7 +97,12 @@ cc_library(
"src/google/protobuf/wire_format_lite.cc",
],
hdrs = glob(["src/google/protobuf/**/*.h"]),
- copts = COPTS,
+ copts = select({
+ ":ios_armv7": IOS_ARM_COPTS,
+ ":ios_armv7s": IOS_ARM_COPTS,
+ ":ios_arm64": IOS_ARM_COPTS,
+ "//conditions:default": COPTS,
+ }),
includes = ["src/"],
linkopts = LINK_OPTS,
visibility = ["//visibility:public"],
@@ -106,6 +153,7 @@ cc_library(
"src/google/protobuf/util/internal/json_objectwriter.cc",
"src/google/protobuf/util/internal/json_stream_parser.cc",
"src/google/protobuf/util/internal/object_writer.cc",
+ "src/google/protobuf/util/internal/proto_writer.cc",
"src/google/protobuf/util/internal/protostream_objectsource.cc",
"src/google/protobuf/util/internal/protostream_objectwriter.cc",
"src/google/protobuf/util/internal/type_info.cc",
@@ -119,7 +167,12 @@ cc_library(
"src/google/protobuf/wrappers.pb.cc",
],
hdrs = glob(["src/**/*.h"]),
- copts = COPTS,
+ copts = select({
+ ":ios_armv7": IOS_ARM_COPTS,
+ ":ios_armv7s": IOS_ARM_COPTS,
+ ":ios_arm64": IOS_ARM_COPTS,
+ "//conditions:default": COPTS,
+ }),
includes = ["src/"],
linkopts = LINK_OPTS,
visibility = ["//visibility:public"],
@@ -152,6 +205,12 @@ RELATIVE_WELL_KNOWN_PROTOS = [
WELL_KNOWN_PROTOS = ["src/" + s for s in RELATIVE_WELL_KNOWN_PROTOS]
+filegroup(
+ name = "well_known_protos",
+ srcs = WELL_KNOWN_PROTOS,
+ visibility = ["//visibility:public"],
+)
+
cc_proto_library(
name = "cc_wkt_protos",
srcs = WELL_KNOWN_PROTOS,
@@ -208,6 +267,7 @@ cc_library(
"src/google/protobuf/compiler/java/java_enum_field_lite.cc",
"src/google/protobuf/compiler/java/java_enum_lite.cc",
"src/google/protobuf/compiler/java/java_extension.cc",
+ "src/google/protobuf/compiler/java/java_extension_lite.cc",
"src/google/protobuf/compiler/java/java_field.cc",
"src/google/protobuf/compiler/java/java_file.cc",
"src/google/protobuf/compiler/java/java_generator.cc",
@@ -241,6 +301,7 @@ cc_library(
"src/google/protobuf/compiler/javanano/javanano_message.cc",
"src/google/protobuf/compiler/javanano/javanano_message_field.cc",
"src/google/protobuf/compiler/javanano/javanano_primitive_field.cc",
+ "src/google/protobuf/compiler/js/js_generator.cc",
"src/google/protobuf/compiler/objectivec/objectivec_enum.cc",
"src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc",
"src/google/protobuf/compiler/objectivec/objectivec_extension.cc",
@@ -317,6 +378,8 @@ RELATIVE_TEST_PROTOS = [
"google/protobuf/unittest_preserve_unknown_enum.proto",
"google/protobuf/unittest_preserve_unknown_enum2.proto",
"google/protobuf/unittest_proto3_arena.proto",
+ "google/protobuf/unittest_proto3_arena_lite.proto",
+ "google/protobuf/unittest_proto3_lite.proto",
"google/protobuf/unittest_well_known_types.proto",
"google/protobuf/util/internal/testdata/anys.proto",
"google/protobuf/util/internal/testdata/books.proto",
@@ -328,6 +391,7 @@ RELATIVE_TEST_PROTOS = [
"google/protobuf/util/internal/testdata/struct.proto",
"google/protobuf/util/internal/testdata/timestamp_duration.proto",
"google/protobuf/util/json_format_proto3.proto",
+ "google/protobuf/util/message_differencer_unittest.proto",
]
TEST_PROTOS = ["src/" + s for s in RELATIVE_TEST_PROTOS]
@@ -376,6 +440,7 @@ cc_test(
"src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc",
"src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc",
"src/google/protobuf/compiler/cpp/cpp_unittest.cc",
+ "src/google/protobuf/compiler/cpp/metadata_test.cc",
"src/google/protobuf/compiler/csharp/csharp_generator_unittest.cc",
"src/google/protobuf/compiler/importer_unittest.cc",
"src/google/protobuf/compiler/java/java_doc_comment_unittest.cc",
@@ -400,7 +465,9 @@ cc_test(
"src/google/protobuf/message_unittest.cc",
"src/google/protobuf/no_field_presence_test.cc",
"src/google/protobuf/preserve_unknown_enum_test.cc",
+ "src/google/protobuf/proto3_arena_lite_unittest.cc",
"src/google/protobuf/proto3_arena_unittest.cc",
+ "src/google/protobuf/proto3_lite_unittest.cc",
"src/google/protobuf/reflection_ops_unittest.cc",
"src/google/protobuf/repeated_field_reflection_unittest.cc",
"src/google/protobuf/repeated_field_unittest.cc",
@@ -428,6 +495,7 @@ cc_test(
"src/google/protobuf/util/internal/protostream_objectwriter_test.cc",
"src/google/protobuf/util/internal/type_info_test_helper.cc",
"src/google/protobuf/util/json_util_test.cc",
+ "src/google/protobuf/util/message_differencer_unittest.cc",
"src/google/protobuf/util/time_util_test.cc",
"src/google/protobuf/util/type_resolver_util_test.cc",
"src/google/protobuf/well_known_types_unittest.cc",
@@ -454,20 +522,29 @@ cc_test(
################################################################################
# Java support
################################################################################
-genrule(
- name = "generate_java_descriptor_proto",
- srcs = ["src/google/protobuf/descriptor.proto"],
- outs = ["com/google/protobuf/DescriptorProtos.java"],
- cmd = "$(location :protoc) --java_out=$(@D)/../../.. $<",
- tools = [":protoc"],
+internal_gen_well_known_protos_java(
+ srcs = WELL_KNOWN_PROTOS,
)
java_library(
name = "protobuf_java",
srcs = glob([
- "java/src/main/java/com/google/protobuf/*.java",
+ "java/core/src/main/java/com/google/protobuf/*.java",
]) + [
- ":generate_java_descriptor_proto",
+ ":gen_well_known_protos_java",
+ ],
+ visibility = ["//visibility:public"],
+)
+
+java_library(
+ name = "protobuf_java_util",
+ srcs = glob([
+ "java/util/src/main/java/com/google/protobuf/util/*.java",
+ ]),
+ deps = [
+ "protobuf_java",
+ "//external:gson",
+ "//external:guava",
],
visibility = ["//visibility:public"],
)
@@ -476,25 +553,7 @@ java_library(
# Python support
################################################################################
-# Hack:
-# protoc generated files contain imports like:
-# "from google.protobuf.xxx import yyy"
-# However, the sources files of the python runtime are not directly under
-# "google/protobuf" (they are under python/google/protobuf). We workaround
-# this by copying runtime source files into the desired location to workaround
-# the import issue. Ideally py_library should support something similiar to the
-# "include" attribute in cc_library to inject the PYTHON_PATH for all libraries
-# that depend on the target.
-#
-# If you use python protobuf as a third_party library in your bazel managed
-# project:
-# 1) Please import the whole package to //google/protobuf in your
-# project. Otherwise, bazel disallows generated files out of the current
-# package, thus we won't be able to copy protobuf runtime files into
-# //google/protobuf/.
-# 2) The runtime also requires "six" for Python2/3 compatibility, please see the
-# WORKSPACE file and bind "six" to your workspace as well.
-internal_copied_filegroup(
+py_library(
name = "python_srcs",
srcs = glob(
[
@@ -502,11 +561,14 @@ internal_copied_filegroup(
"python/google/protobuf/**/*.py",
],
exclude = [
+ "python/google/protobuf/__init__.py",
+ "python/google/protobuf/**/__init__.py",
"python/google/protobuf/internal/*_test.py",
"python/google/protobuf/internal/test_util.py",
],
),
- include = "python",
+ srcs_version = "PY2AND3",
+ imports = ["python"],
)
cc_binary(
@@ -519,7 +581,7 @@ cc_binary(
linkstatic = 1,
deps = select({
"//conditions:default": [],
- ":use_fast_cpp_protos": ["//util/python:python_headers"],
+ ":use_fast_cpp_protos": ["//external:python_headers"],
}),
)
@@ -531,7 +593,10 @@ cc_binary(
]),
copts = COPTS + [
"-DGOOGLE_PROTOBUF_HAS_ONEOF=1",
- ],
+ ] + select({
+ "//conditions:default": [],
+ ":allow_oversize_protos": ["-DPROTOBUF_PYTHON_ALLOW_OVERSIZE_PROTOS=1"],
+ }),
includes = [
"python/",
"src/",
@@ -542,7 +607,7 @@ cc_binary(
":protobuf",
] + select({
"//conditions:default": [],
- ":use_fast_cpp_protos": ["//util/python:python_headers"],
+ ":use_fast_cpp_protos": ["//external:python_headers"],
}),
)
@@ -553,10 +618,33 @@ config_setting(
},
)
+config_setting(
+ name = "allow_oversize_protos",
+ values = {
+ "define": "allow_oversize_protos=true",
+ },
+)
+
+# Copy the builtin proto files from src/google/protobuf to
+# python/google/protobuf. This way, the generated Python sources will be in the
+# same directory as the Python runtime sources. This is necessary for the
+# modules to be imported correctly since they are all part of the same Python
+# package.
+internal_copied_filegroup(
+ name = "protos_python",
+ srcs = WELL_KNOWN_PROTOS,
+ strip_prefix = "src",
+ dest = "python",
+)
+
+# TODO(dzc): Remove this once py_proto_library can have labels in srcs, in
+# which case we can simply add :protos_python in srcs.
+COPIED_WELL_KNOWN_PROTOS = ["python/" + s for s in RELATIVE_WELL_KNOWN_PROTOS]
+
py_proto_library(
name = "protobuf_python",
- srcs = WELL_KNOWN_PROTOS,
- include = "src",
+ srcs = COPIED_WELL_KNOWN_PROTOS,
+ include = "python",
data = select({
"//conditions:default": [],
":use_fast_cpp_protos": [
@@ -566,29 +654,38 @@ py_proto_library(
}),
default_runtime = "",
protoc = ":protoc",
- py_extra_srcs = [":python_srcs"],
- py_libs = ["//external:six"],
+ py_libs = [
+ ":python_srcs",
+ "//external:six"
+ ],
srcs_version = "PY2AND3",
visibility = ["//visibility:public"],
)
+# Copy the test proto files from src/google/protobuf to
+# python/google/protobuf. This way, the generated Python sources will be in the
+# same directory as the Python runtime sources. This is necessary for the
+# modules to be imported correctly by the tests since they are all part of the
+# same Python package.
internal_copied_filegroup(
- name = "python_test_srcs",
- srcs = glob(
- [
- "python/google/protobuf/internal/*_test.py",
- "python/google/protobuf/internal/test_util.py",
- ],
- ),
- include = "python",
+ name = "protos_python_test",
+ srcs = LITE_TEST_PROTOS + TEST_PROTOS,
+ strip_prefix = "src",
+ dest = "python",
)
+# TODO(dzc): Remove this once py_proto_library can have labels in srcs, in
+# which case we can simply add :protos_python_test in srcs.
+COPIED_LITE_TEST_PROTOS = ["python/" + s for s in RELATIVE_LITE_TEST_PROTOS]
+COPIED_TEST_PROTOS = ["python/" + s for s in RELATIVE_TEST_PROTOS]
+
py_proto_library(
name = "python_common_test_protos",
- srcs = LITE_TEST_PROTOS + TEST_PROTOS,
- include = "src",
+ srcs = COPIED_LITE_TEST_PROTOS + COPIED_TEST_PROTOS,
+ include = "python",
default_runtime = "",
protoc = ":protoc",
+ srcs_version = "PY2AND3",
deps = [":protobuf_python"],
)
@@ -601,12 +698,20 @@ py_proto_library(
include = "python",
default_runtime = ":protobuf_python",
protoc = ":protoc",
+ srcs_version = "PY2AND3",
deps = [":python_common_test_protos"],
)
py_library(
name = "python_tests",
- srcs = [":python_test_srcs"],
+ srcs = glob(
+ [
+ "python/google/protobuf/internal/*_test.py",
+ "python/google/protobuf/internal/test_util.py",
+ "python/google/protobuf/internal/import_test_package/__init__.py",
+ ],
+ ),
+ imports = ["python"],
srcs_version = "PY2AND3",
deps = [
":protobuf_python",
diff --git a/CHANGES.txt b/CHANGES.txt
index ca3078c3..822136c0 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,3 +1,332 @@
+2016-07-27 version 3.0.0 (C++/Java/Python/Ruby/Objective-C/C#/JavaScript/Lite)
+ General
+ * This log only contains changes since the beta-4 release. Summarized change
+ log since the last stable release (v2.6.1) can be found in the github
+ release page.
+
+ Compatibility Notice
+ * v3.0.0 is the first API stable release of the v3.x series. We do not expect
+ any future API breaking changes.
+ * For C++, Java Lite and Objective-C, source level compatibility is
+ guaranteed. Upgrading from v3.0.0 to newer minor version releases will be
+ source compatible. For example, if your code compiles against protobuf
+ v3.0.0, it will continue to compile after you upgrade protobuf library to
+ v3.1.0.
+ * For other languages, both source level compatibility and binary level
+ compatibility are guaranteed. For example, if you have a Java binary built
+ against protobuf v3.0.0. After switching the protobuf runtime binary to
+ v3.1.0, your built binary should continue to work.
+ * Compatibility is only guaranteed for documented API and documented
+ behaviors. If you are using undocumented API (e.g., use anything in the C++
+ internal namespace), it can be broken by minor version releases in an
+ undetermined manner.
+
+ Ruby
+ * When you assign a string field `a.string_field = "X"`, we now call
+ #encode(UTF-8) on the string and freeze the copy. This saves you from
+ needing to ensure the string is already encoded as UTF-8. It also prevents
+ you from mutating the string after it has been assigned (this is how we
+ ensure it stays valid UTF-8).
+ * The generated file for `foo.proto` is now `foo_pb.rb` instead of just
+ `foo.rb`. This makes it easier to see which imports/requires are from
+ protobuf generated code, and also prevents conflicts with any `foo.rb` file
+ you might have written directly in Ruby. It is a backward-incompatible
+ change: you will need to update all of your `require` statements.
+ * For package names like `foo_bar`, we now translate this to the Ruby module
+ `FooBar`. This is more idiomatic Ruby than what we used to do (`Foo_bar`).
+
+ JavaScript
+ * Scalar fields like numbers and boolean now return defaults instead of
+ `undefined` or `null` when they are unset. You can test for presence
+ explicitly by calling `hasFoo()`, which we now generate for scalar fields.
+
+ Java Lite
+ * Java Lite is now implemented as a separate plugin, maintained in the
+ `javalite` branch. Both lite runtime and protoc artifacts will be available
+ in Maven.
+
+ C#
+ * Target platforms now .NET 4.5, selected portable subsets and .NET Core.
+ * legacy_enum_values option is no longer supported.
+
+2016-07-15 version 3.0.0-beta-4 (C++/Java/Python/Ruby/Objective-C/C#/JavaScript)
+ General
+ * Added a deterministic serialization API for C++. The deterministic
+ serialization guarantees that given a binary, equal messages will be
+ serialized to the same bytes. This allows applications like MapReduce to
+ group equal messages based on the serialized bytes. The deterministic
+ serialization is, however, NOT canonical across languages; it is also
+ unstable across different builds with schema changes due to unknown fields.
+ Users who need canonical serialization, e.g. persistent storage in a
+ canonical form, fingerprinting, etc, should define their own
+ canonicalization specification and implement the serializer using reflection
+ APIs rather than relying on this API.
+ * Added OneofOptions. You can now define custom options for oneof groups.
+ import "google/protobuf/descriptor.proto";
+ extend google.protobuf.OneofOptions {
+ optional int32 my_oneof_extension = 12345;
+ }
+ message Foo {
+ oneof oneof_group {
+ (my_oneof_extension) = 54321;
+ ...
+ }
+ }
+
+ C++ (beta)
+ * Introduced a deterministic serialization API in
+ CodedOutputStream::SetSerializationDeterministic(bool). See the notes about
+ deterministic serialization in the General section.
+ * Added google::protobuf::Map::swap() to swap two map fields.
+ * Fixed a memory leak when calling Reflection::ReleaseMessage() on a message
+ allocated on arena.
+ * Improved error reporting when parsing text format protos.
+ * JSON
+ - Added a new parser option to ignore unknown fields when parsing JSON.
+ - Added convenient methods for message to/from JSON conversion.
+ * Various performance optimizations.
+
+ Java (beta)
+ * File option "java_generate_equals_and_hash" is now deprecated. equals() and
+ hashCode() methods are generated by default.
+ * Added a new JSON printer option "omittingInsignificantWhitespace" to produce
+ a more compact JSON output. The printer will pretty-print by default.
+ * Updated Java runtime to be compatible with 2.5.0/2.6.1 generated protos.
+
+ Python (beta)
+ * Added support to pretty print Any messages in text format.
+ * Added a flag to ignore unknown fields when parsing JSON.
+ * Bugfix: "@type" field of a JSON Any message is now correctly put before
+ other fields.
+
+ Objective-C (beta)
+ * Updated the code to support compiling with more compiler warnings
+ enabled. (Issue 1616)
+ * Exposing more detailed errors for parsing failures. (PR 1623)
+ * Small (breaking) change to the naming of some methods on the support classes
+ for map<>. There were collisions with the system provided KVO support, so
+ the names were changed to avoid those issues. (PR 1699)
+ * Fixed for proper Swift bridging of error handling during parsing. (PR 1712)
+ * Complete support for generating sources that will go into a Framework and
+ depend on generated sources from other Frameworks. (Issue 1457)
+
+ C# (beta)
+ * RepeatedField optimizations.
+ * Support for .NET Core.
+ * Minor bug fixes.
+ * Ability to format a single value in JsonFormatter (advanced usage only).
+ * Modifications to attributes applied to generated code.
+
+ Javascript (alpha)
+ * Maps now have a real map API instead of being treated as repeated fields.
+ * Well-known types are now provided in the google-protobuf package, and the
+ code generator knows to require() them from that package.
+ * Bugfix: non-canonical varints are correctly decoded.
+
+ Ruby (alpha)
+ * Accessors for oneof fields now return default values instead of nil.
+
+ Java Lite
+ * Java lite support is removed from protocol compiler. It will be supported
+ as a protocol compiler plugin in a separate code branch.
+
+2016-05-16 version 3.0.0-beta-3 (C++/Java/Python/Ruby/Nano/Objective-C/C#/JavaScript)
+ General
+ * Supported Proto3 lite-runtime in C++/Java for mobile platforms.
+ * Any type now supports APIs to specify prefixes other than
+ type.googleapis.com
+ * Removed javanano_use_deprecated_package option; Nano will always has its own
+ ".nano" package.
+
+ C++ (Beta)
+ * Improved hash maps.
+ - Improved hash maps comments. In particular, please note that equal hash
+ maps will not necessarily have the same iteration order and
+ serialization.
+ - Added a new hash maps implementation that will become the default in a
+ later release.
+ * Arenas
+ - Several inlined methods in Arena were moved to out-of-line to improve
+ build performance and code size.
+ - Added SpaceAllocatedAndUsed() to report both space used and allocated
+ - Added convenient class UnsafeArenaAllocatedRepeatedPtrFieldBackInserter
+ * Any
+ - Allow custom type URL prefixes in Any packing.
+ - TextFormat now expand the Any type rather than printing bytes.
+ * Performance optimizations and various bug fixes.
+
+ Java (Beta)
+ * Introduced an ExperimentalApi annotation. Annotated APIs are experimental
+ and are subject to change in a backward incompatible way in future releases.
+ * Introduced zero-copy serialization as an ExperimentalApi
+ - Introduction of the `ByteOutput` interface. This is similar to
+ `OutputStream` but provides semantics for lazy writing (i.e. no
+ immediate copy required) of fields that are considered to be immutable.
+ - `ByteString` now supports writing to a `ByteOutput`, which will directly
+ expose the internals of the `ByteString` (i.e. `byte[]` or `ByteBuffer`)
+ to the `ByteOutput` without copying.
+ - `CodedOutputStream` now supports writing to a `ByteOutput`. `ByteString`
+ instances that are too large to fit in the internal buffer will be
+ (lazily) written to the `ByteOutput` directly.
+ - This allows applications using large `ByteString` fields to avoid
+ duplication of these fields entirely. Such an application can supply a
+ `ByteOutput` that chains together the chunks received from
+ `CodedOutputStream` before forwarding them onto the IO system.
+ * Other related changes to `CodedOutputStream`
+ - Additional use of `sun.misc.Unsafe` where possible to perform fast
+ access to `byte[]` and `ByteBuffer` values and avoiding unnecessary
+ range checking.
+ - `ByteBuffer`-backed `CodedOutputStream` now writes directly to the
+ `ByteBuffer` rather than to an intermediate array.
+ * Improved lite-runtime.
+ - Lite protos now implement deep equals/hashCode/toString
+ - Significantly improved the performance of Builder#mergeFrom() and
+ Builder#mergeDelimitedFrom()
+ * Various bug fixes and small feature enhancement.
+ - Fixed stack overflow when in hashCode() for infinite recursive oneofs.
+ - Fixed the lazy field parsing in lite to merge rather than overwrite.
+ - TextFormat now supports reporting line/column numbers on errors.
+ - Updated to add appropriate @Override for better compiler errors.
+
+ Python (Beta)
+ * Added JSON format for Any, Struct, Value and ListValue
+ * [ ] is now accepted for both repeated scalar fields and repeated message
+ fields in text format parser.
+ * Numerical field name is now supported in text format.
+ * Added DiscardUnknownFields API for python protobuf message.
+
+ Objective-C (Beta)
+ * Proto comments now come over as HeaderDoc comments in the generated sources
+ so Xcode can pick them up and display them.
+ * The library headers have been updated to use HeaderDoc comments so Xcode can
+ pick them up and display them.
+ * The per message and per field overhead in both generated code and runtime
+ object sizes was reduced.
+ * Generated code now include deprecated annotations when the proto file
+ included them.
+
+ C# (Beta)
+ In general: some changes are breaking, which require regenerating messages.
+ Most user-written code will not be impacted *except* for the renaming of enum
+ values.
+
+ * Allow custom type URL prefixes in `Any` packing, and ignore them when
+ unpacking
+ * `protoc` is now in a separate NuGet package (Google.Protobuf.Tools)
+ * New option: `internal_access` to generate internal classes
+ * Enum values are now PascalCased, and if there's a prefix which matches the
+ name of the enum, that is removed (so an enum `COLOR` with a value
+ `COLOR_BLUE` would generate a value of just `Blue`). An option
+ (`legacy_enum_values`) is temporarily available to disable this, but the
+ option will be removed for GA.
+ * `json_name` option is now honored
+ * If group tags are encountered when parsing, they are validated more
+ thoroughly (although we don't support actual groups)
+ * NuGet dependencies are better specified
+ * Breaking: `Preconditions` is renamed to `ProtoPreconditions`
+ * Breaking: `GeneratedCodeInfo` is renamed to `GeneratedClrTypeInfo`
+ * `JsonFormatter` now allows writing to a `TextWriter`
+ * New interface, `ICustomDiagnosticMessage` to allow more compact
+ representations from `ToString`
+ * `CodedInputStream` and `CodedOutputStream` now implement `IDisposable`,
+ which simply disposes of the streams they were constructed with
+ * Map fields no longer support null values (in line with other languages)
+ * Improvements in JSON formatting and parsing
+
+ Javascript (Alpha)
+ * Better support for "bytes" fields: bytes fields can be read as either a
+ base64 string or UInt8Array (in environments where TypedArray is supported).
+ * New support for CommonJS imports. This should make it easier to use the
+ JavaScript support in Node.js and tools like WebPack. See js/README.md for
+ more information.
+ * Some significant internal refactoring to simplify and modularize the code.
+
+ Ruby (Alpha)
+ * JSON serialization now properly uses camelCased names, with a runtime option
+ that will preserve original names from .proto files instead.
+ * Well-known types are now included in the distribution.
+ * Release now includes binary gems for Windows, Mac, and Linux instead of just
+ source gems.
+ * Bugfix for serializing oneofs.
+
+ C++/Java Lite (Alpha)
+ A new "lite" generator parameter was introduced in the protoc for C++ and
+ Java for Proto3 syntax messages. Example usage:
+
+ ./protoc --cpp_out=lite:$OUTPUT_PATH foo.proto
+
+ The protoc will treat the current input and all the transitive dependencies
+ as LITE. The same generator parameter must be used to generate the
+ dependencies.
+
+ In Proto3 syntax files, "optimized_for=LITE_RUNTIME" is no longer supported.
+
+
+2015-12-30 version 3.0.0-beta-2 (C++/Java/Python/Ruby/Nano/Objective-C/C#/JavaScript)
+ General
+ * Introduced a new language implementation: JavaScript.
+ * Added a new field option "json_name". By default proto field names are
+ converted to "lowerCamelCase" in proto3 JSON format. This option can be
+ used to override this behavior and specify a different JSON name for the
+ field.
+ * Added conformance tests to ensure implementations are following proto3 JSON
+ specification.
+
+ C++ (Beta)
+ * Various bug fixes and improvements to the JSON support utility:
+ - Duplicate map keys in JSON are now rejected (i.e., translation will
+ fail).
+ - Fixed wire-format for google.protobuf.Value/ListValue.
+ - Fixed precision loss when converting google.protobuf.Timestamp.
+ - Fixed a bug when parsing invalid UTF-8 code points.
+ - Fixed a memory leak.
+ - Reduced call stack usage.
+
+ Java (Beta)
+ * Cleaned up some unused methods on CodedOutputStream.
+ * Presized lists for packed fields during parsing in the lite runtime to
+ reduce allocations and improve performance.
+ * Improved the performance of unknown fields in the lite runtime.
+ * Introduced UnsafeByteStrings to support zero-copy ByteString creation.
+ * Various bug fixes and improvements to the JSON support utility:
+ - Fixed a thread-safety bug.
+ - Added a new option “preservingProtoFieldNames” to JsonFormat.
+ - Added a new option “includingDefaultValueFields” to JsonFormat.
+ - Updated the JSON utility to comply with proto3 JSON specification.
+
+ Python (Beta)
+ * Added proto3 JSON format utility. It includes support for all field types
+ and a few well-known types except for Any and Struct.
+ * Added runtime support for Any, Timestamp, Duration and FieldMask.
+ * [ ] is now accepted for repeated scalar fields in text format parser.
+ * Map fields now have proper O(1) performance for lookup/insert/delete
+ when using the Python/C++ implementation. They were previously using O(n)
+ search-based algorithms because the C++ reflection interface didn't
+ support true map operations.
+
+ Objective-C (Beta)
+ * Various bug-fixes and code tweaks to pass more strict compiler warnings.
+ * Now has conformance test coverage and is passing all tests.
+
+ C# (Beta)
+ * Various bug-fixes.
+ * Code generation: Files generated in directories based on namespace.
+ * Code generation: Include comments from .proto files in XML doc
+ comments (naively)
+ * Code generation: Change organization/naming of "reflection class" (access
+ to file descriptor)
+ * Code generation and library: Add Parser property to MessageDescriptor,
+ and introduce a non-generic parser type.
+ * Library: Added TypeRegistry to support JSON parsing/formatting of Any.
+ * Library: Added Any.Pack/Unpack support.
+ * Library: Implemented JSON parsing.
+
+ Javascript (Alpha)
+ * Added proto3 support for JavaScript. The runtime is written in pure
+ JavaScript and works in browsers and in Node.js. To generate JavaScript
+ code for your proto, invoke protoc with "--js_out". See js/README.md
+ for more build instructions.
+
2015-08-26 version 3.0.0-beta-1 (C++/Java/Python/Ruby/Nano/Objective-C/C#)
About Beta
* This is the first beta release of protobuf v3.0.0. Not all languages
@@ -115,7 +444,7 @@
still disable packed serialization by setting packed to false for now.
* Added well-known type protos (any.proto, empty.proto, timestamp.proto,
duration.proto, etc.). Users can import and use these protos just like
- regular proto files. Addtional runtime support will be added for them in
+ regular proto files. Additional runtime support will be added for them in
future releases (in the form of utility helper functions, or having them
replaced by language specific types in generated code).
* Added a "reserved" keyword in both proto2 and proto3 syntax. User can use
@@ -157,7 +486,7 @@
https://github.com/jskeet/protobuf-csharp-port. The original project was
frozen and all the new development will happen here.
* Codegen plugin for C# was completely rewritten to C++ and is now an
- intergral part of protoc.
+ integral part of protoc.
* Some refactorings and cleanup has been applied to the C# runtime library.
* Only proto2 is supported in C# at the moment, proto3 support is in
progress and will likely bring significant breaking changes to the API.
@@ -321,7 +650,7 @@
This release (v3.0.0-alpha-1) includes partial proto3 support for C++ and
Java. Items 6 (well-known types) and 7 (JSON format) in the above feature
- list are not impelmented.
+ list are not implemented.
A new notion "syntax" is introduced to specify whether a .proto file
uses proto2 or proto3:
@@ -422,7 +751,7 @@
}
* Files, services, enums, messages, methods and enum values can be marked
as deprecated now.
- * Added Support for list values, including lists of mesaages, when
+ * Added Support for list values, including lists of messages, when
parsing text-formatted protos in C++ and Java.
For example: foo: [1, 2, 3]
@@ -502,7 +831,7 @@
Python
* Added support for dynamic message creation. DescriptorDatabase,
- DescriptorPool, and MessageFactory work like their C++ couterparts to
+ DescriptorPool, and MessageFactory work like their C++ counterparts to
simplify Descriptor construction from *DescriptorProtos, and MessageFactory
provides a message instance from a Descriptor.
* Added pickle support for protobuf messages.
@@ -516,7 +845,7 @@
2011-05-01 version 2.4.1:
C++
- * Fixed the frendship problem for old compilers to make the library now gcc 3
+ * Fixed the friendship problem for old compilers to make the library now gcc 3
compatible again.
* Fixed vcprojects/extract_includes.bat to extract compiler/plugin.h.
@@ -783,7 +1112,7 @@
* Fixed tendency for TextFormat's parsing to overflow the stack when
parsing large string values. The underlying problem is with Java's
regex implementation (which unfortunately uses recursive backtracking
- rather than building an NFA). Worked around by making use of possesive
+ rather than building an NFA). Worked around by making use of possessive
quantifiers.
* Generated service classes now also generate pure interfaces. For a service
Foo, Foo.Interface is a pure interface containing all of the service's
@@ -797,7 +1126,7 @@
RPC implementations will have to implement the new interfaces in order to
support blocking mode.
* New I/O methods parseDelimitedFrom(), mergeDelimitedFrom(), and
- writeDelimitedTo() read and write "delemited" messages from/to a stream,
+ writeDelimitedTo() read and write "delimited" messages from/to a stream,
meaning that the message size precedes the data. This way, you can write
multiple messages to a stream without having to worry about delimiting
them yourself.
diff --git a/INSTALL.txt b/INSTALL.txt
deleted file mode 100644
index ce3b0949..00000000
--- a/INSTALL.txt
+++ /dev/null
@@ -1,237 +0,0 @@
-This file contains detailed but generic information on building and
-installing the C++ part of this project. For shorter instructions,
-as well as instructions for compiling and installing the Java or
-Python parts, see README.
-
-======================================================================
-
-Copyright 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
-Foundation, Inc.
-
- This file is free documentation; the Free Software Foundation gives
-unlimited permission to copy, distribute and modify it.
-
-
-Basic Installation
-==================
-
- These are generic installation instructions.
-
- The `configure' shell script attempts to guess correct values for
-various system-dependent variables used during compilation. It uses
-those values to create a `Makefile' in each directory of the package.
-It may also create one or more `.h' files containing system-dependent
-definitions. Finally, it creates a shell script `config.status' that
-you can run in the future to recreate the current configuration, and a
-file `config.log' containing compiler output (useful mainly for
-debugging `configure').
-
- It can also use an optional file (typically called `config.cache'
-and enabled with `--cache-file=config.cache' or simply `-C') that saves
-the results of its tests to speed up reconfiguring. (Caching is
-disabled by default to prevent problems with accidental use of stale
-cache files.)
-
- If you need to do unusual things to compile the package, please try
-to figure out how `configure' could check whether to do them, and mail
-diffs or instructions to the address given in the `README' so they can
-be considered for the next release. If you are using the cache, and at
-some point `config.cache' contains results you don't want to keep, you
-may remove or edit it.
-
- The file `configure.ac' (or `configure.in') is used to create
-`configure' by a program called `autoconf'. You only need
-`configure.ac' if you want to change it or regenerate `configure' using
-a newer version of `autoconf'.
-
-The simplest way to compile this package is:
-
- 1. `cd' to the directory containing the package's source code and type
- `./configure' to configure the package for your system. If you're
- using `csh' on an old version of System V, you might need to type
- `sh ./configure' instead to prevent `csh' from trying to execute
- `configure' itself.
-
- Running `configure' takes awhile. While running, it prints some
- messages telling which features it is checking for.
-
- 2. Type `make' to compile the package.
-
- 3. Optionally, type `make check' to run any self-tests that come with
- the package.
-
- 4. Type `make install' to install the programs and any data files and
- documentation.
-
- 5. You can remove the program binaries and object files from the
- source code directory by typing `make clean'. To also remove the
- files that `configure' created (so you can compile the package for
- a different kind of computer), type `make distclean'. There is
- also a `make maintainer-clean' target, but that is intended mainly
- for the package's developers. If you use it, you may have to get
- all sorts of other programs in order to regenerate files that came
- with the distribution.
-
-Compilers and Options
-=====================
-
- Some systems require unusual options for compilation or linking that
-the `configure' script does not know about. Run `./configure --help'
-for details on some of the pertinent environment variables.
-
- You can give `configure' initial values for configuration parameters
-by setting variables in the command line or in the environment. Here
-is an example:
-
- ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
-
- *Note Defining Variables::, for more details.
-
-Compiling For Multiple Architectures
-====================================
-
- You can compile the package for more than one kind of computer at the
-same time, by placing the object files for each architecture in their
-own directory. To do this, you must use a version of `make' that
-supports the `VPATH' variable, such as GNU `make'. `cd' to the
-directory where you want the object files and executables to go and run
-the `configure' script. `configure' automatically checks for the
-source code in the directory that `configure' is in and in `..'.
-
- If you have to use a `make' that does not support the `VPATH'
-variable, you have to compile the package for one architecture at a
-time in the source code directory. After you have installed the
-package for one architecture, use `make distclean' before reconfiguring
-for another architecture.
-
-Installation Names
-==================
-
- By default, `make install' will install the package's files in
-`/usr/local/bin', `/usr/local/man', etc. You can specify an
-installation prefix other than `/usr/local' by giving `configure' the
-option `--prefix=PATH'.
-
- You can specify separate installation prefixes for
-architecture-specific files and architecture-independent files. If you
-give `configure' the option `--exec-prefix=PATH', the package will use
-PATH as the prefix for installing programs and libraries.
-Documentation and other data files will still use the regular prefix.
-
- In addition, if you use an unusual directory layout you can give
-options like `--bindir=PATH' to specify different values for particular
-kinds of files. Run `configure --help' for a list of the directories
-you can set and what kinds of files go in them.
-
- If the package supports it, you can cause programs to be installed
-with an extra prefix or suffix on their names by giving `configure' the
-option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
-
-Optional Features
-=================
-
- Some packages pay attention to `--enable-FEATURE' options to
-`configure', where FEATURE indicates an optional part of the package.
-They may also pay attention to `--with-PACKAGE' options, where PACKAGE
-is something like `gnu-as' or `x' (for the X Window System). The
-`README' should mention any `--enable-' and `--with-' options that the
-package recognizes.
-
- For packages that use the X Window System, `configure' can usually
-find the X include and library files automatically, but if it doesn't,
-you can use the `configure' options `--x-includes=DIR' and
-`--x-libraries=DIR' to specify their locations.
-
-Specifying the System Type
-==========================
-
- There may be some features `configure' cannot figure out
-automatically, but needs to determine by the type of machine the package
-will run on. Usually, assuming the package is built to be run on the
-_same_ architectures, `configure' can figure that out, but if it prints
-a message saying it cannot guess the machine type, give it the
-`--build=TYPE' option. TYPE can either be a short name for the system
-type, such as `sun4', or a canonical name which has the form:
-
- CPU-COMPANY-SYSTEM
-
-where SYSTEM can have one of these forms:
-
- OS KERNEL-OS
-
- See the file `config.sub' for the possible values of each field. If
-`config.sub' isn't included in this package, then this package doesn't
-need to know the machine type.
-
- If you are _building_ compiler tools for cross-compiling, you should
-use the `--target=TYPE' option to select the type of system they will
-produce code for.
-
- If you want to _use_ a cross compiler, that generates code for a
-platform different from the build platform, you should specify the
-"host" platform (i.e., that on which the generated programs will
-eventually be run) with `--host=TYPE'.
-
-Sharing Defaults
-================
-
- If you want to set default values for `configure' scripts to share,
-you can create a site shell script called `config.site' that gives
-default values for variables like `CC', `cache_file', and `prefix'.
-`configure' looks for `PREFIX/share/config.site' if it exists, then
-`PREFIX/etc/config.site' if it exists. Or, you can set the
-`CONFIG_SITE' environment variable to the location of the site script.
-A warning: not all `configure' scripts look for a site script.
-
-Defining Variables
-==================
-
- Variables not defined in a site shell script can be set in the
-environment passed to `configure'. However, some packages may run
-configure again during the build, and the customized values of these
-variables may be lost. In order to avoid this problem, you should set
-them in the `configure' command line, using `VAR=value'. For example:
-
- ./configure CC=/usr/local2/bin/gcc
-
-will cause the specified gcc to be used as the C compiler (unless it is
-overridden in the site shell script).
-
-`configure' Invocation
-======================
-
- `configure' recognizes the following options to control how it
-operates.
-
-`--help'
-`-h'
- Print a summary of the options to `configure', and exit.
-
-`--version'
-`-V'
- Print the version of Autoconf used to generate the `configure'
- script, and exit.
-
-`--cache-file=FILE'
- Enable the cache: use and save the results of the tests in FILE,
- traditionally `config.cache'. FILE defaults to `/dev/null' to
- disable caching.
-
-`--config-cache'
-`-C'
- Alias for `--cache-file=config.cache'.
-
-`--quiet'
-`--silent'
-`-q'
- Do not print messages saying which checks are being made. To
- suppress all normal output, redirect it to `/dev/null' (any error
- messages will still be shown).
-
-`--srcdir=DIR'
- Look for the package's source code in directory DIR. Usually
- `configure' can determine that directory automatically.
-
-`configure' also accepts some other, not widely useful, options. Run
-`configure --help' for more details.
-
diff --git a/Makefile.am b/Makefile.am
index bb735177..41d25823 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -9,7 +9,7 @@ AUTOMAKE_OPTIONS = foreign
SUBDIRS = . src
# Always include gmock in distributions.
-DIST_SUBDIRS = $(subdirs) src conformance
+DIST_SUBDIRS = $(subdirs) src conformance benchmarks
# Build gmock before we build protobuf tests. We don't add gmock to SUBDIRS
# because then "make check" would also build and run all of gmock's own tests,
@@ -36,6 +36,10 @@ clean-local:
echo "Making clean in conformance"; \
cd conformance && $(MAKE) $(AM_MAKEFLAGS) clean; \
fi; \
+ if test -e benchmarks/Makefile; then \
+ echo "Making clean in benchmarks"; \
+ cd benchmarks && $(MAKE) $(AM_MAKEFLAGS) clean; \
+ fi; \
if test -e objectivec/DevTools; then \
echo "Cleaning any ObjC pyc files"; \
rm -f objectivec/DevTools/*.pyc; \
@@ -47,30 +51,29 @@ pkgconfig_DATA = protobuf.pc protobuf-lite.pc
csharp_EXTRA_DIST= \
csharp/.gitignore \
csharp/CHANGES.txt \
+ csharp/Google.Protobuf.Tools.nuspec \
csharp/README.md \
csharp/build_packages.bat \
csharp/buildall.sh \
csharp/generate_protos.sh \
csharp/keys/Google.Protobuf.public.snk \
+ csharp/keys/Google.Protobuf.snk \
csharp/keys/README.md \
csharp/protos/unittest_issues.proto \
csharp/src/AddressBook/AddPerson.cs \
- csharp/src/AddressBook/AddressBook.csproj \
csharp/src/AddressBook/Addressbook.cs \
+ csharp/src/AddressBook/AddressBook.xproj \
csharp/src/AddressBook/ListPeople.cs \
csharp/src/AddressBook/Program.cs \
- csharp/src/AddressBook/Properties/AssemblyInfo.cs \
csharp/src/AddressBook/SampleUsage.cs \
- csharp/src/AddressBook/app.config \
- csharp/src/Google.Protobuf.Conformance/App.config \
+ csharp/src/AddressBook/project.json \
csharp/src/Google.Protobuf.Conformance/Conformance.cs \
- csharp/src/Google.Protobuf.Conformance/Google.Protobuf.Conformance.csproj \
+ csharp/src/Google.Protobuf.Conformance/Google.Protobuf.Conformance.xproj \
csharp/src/Google.Protobuf.Conformance/Program.cs \
- csharp/src/Google.Protobuf.Conformance/Properties/AssemblyInfo.cs \
- csharp/src/Google.Protobuf.JsonDump/Google.Protobuf.JsonDump.csproj \
+ csharp/src/Google.Protobuf.Conformance/project.json \
+ csharp/src/Google.Protobuf.JsonDump/Google.Protobuf.JsonDump.xproj \
csharp/src/Google.Protobuf.JsonDump/Program.cs \
- csharp/src/Google.Protobuf.JsonDump/Properties/AssemblyInfo.cs \
- csharp/src/Google.Protobuf.JsonDump/app.config \
+ csharp/src/Google.Protobuf.JsonDump/project.json \
csharp/src/Google.Protobuf.Test/ByteStringTest.cs \
csharp/src/Google.Protobuf.Test/CodedInputStreamExtensions.cs \
csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs \
@@ -83,18 +86,18 @@ csharp_EXTRA_DIST= \
csharp/src/Google.Protobuf.Test/EqualityTester.cs \
csharp/src/Google.Protobuf.Test/FieldCodecTest.cs \
csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs \
- csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj \
+ csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.xproj \
csharp/src/Google.Protobuf.Test/IssuesTest.cs \
csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs \
csharp/src/Google.Protobuf.Test/JsonParserTest.cs \
csharp/src/Google.Protobuf.Test/JsonTokenizerTest.cs \
- csharp/src/Google.Protobuf.Test/Properties/AppManifest.xml \
- csharp/src/Google.Protobuf.Test/Properties/AssemblyInfo.cs \
csharp/src/Google.Protobuf.Test/Reflection/DescriptorsTest.cs \
csharp/src/Google.Protobuf.Test/Reflection/FieldAccessTest.cs \
+ csharp/src/Google.Protobuf.Test/Reflection/TypeRegistryTest.cs \
csharp/src/Google.Protobuf.Test/SampleEnum.cs \
csharp/src/Google.Protobuf.Test/SampleMessages.cs \
csharp/src/Google.Protobuf.Test/TestCornerCases.cs \
+ csharp/src/Google.Protobuf.Test/TestProtos/ForeignMessagePartial.cs \
csharp/src/Google.Protobuf.Test/TestProtos/MapUnittestProto3.cs \
csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportProto3.cs \
csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportPublicProto3.cs \
@@ -103,9 +106,10 @@ csharp_EXTRA_DIST= \
csharp/src/Google.Protobuf.Test/TestProtos/UnittestWellKnownTypes.cs \
csharp/src/Google.Protobuf.Test/WellKnownTypes/AnyTest.cs \
csharp/src/Google.Protobuf.Test/WellKnownTypes/DurationTest.cs \
+ csharp/src/Google.Protobuf.Test/WellKnownTypes/FieldMaskTest.cs \
csharp/src/Google.Protobuf.Test/WellKnownTypes/TimestampTest.cs \
csharp/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs \
- csharp/src/Google.Protobuf.Test/packages.config \
+ csharp/src/Google.Protobuf.Test/project.json \
csharp/src/Google.Protobuf.sln \
csharp/src/Google.Protobuf/ByteArray.cs \
csharp/src/Google.Protobuf/ByteString.cs \
@@ -119,8 +123,8 @@ csharp_EXTRA_DIST= \
csharp/src/Google.Protobuf/Compatibility/TypeExtensions.cs \
csharp/src/Google.Protobuf/FieldCodec.cs \
csharp/src/Google.Protobuf/FrameworkPortability.cs \
- csharp/src/Google.Protobuf/Google.Protobuf.csproj \
- csharp/src/Google.Protobuf/Google.Protobuf.nuspec \
+ csharp/src/Google.Protobuf/Google.Protobuf.xproj \
+ csharp/src/Google.Protobuf/ICustomDiagnosticMessage.cs \
csharp/src/Google.Protobuf/IDeepCloneable.cs \
csharp/src/Google.Protobuf/IMessage.cs \
csharp/src/Google.Protobuf/InvalidJsonException.cs \
@@ -132,7 +136,7 @@ csharp_EXTRA_DIST= \
csharp/src/Google.Protobuf/LimitedInputStream.cs \
csharp/src/Google.Protobuf/MessageExtensions.cs \
csharp/src/Google.Protobuf/MessageParser.cs \
- csharp/src/Google.Protobuf/Preconditions.cs \
+ csharp/src/Google.Protobuf/ProtoPreconditions.cs \
csharp/src/Google.Protobuf/Properties/AssemblyInfo.cs \
csharp/src/Google.Protobuf/Reflection/Descriptor.cs \
csharp/src/Google.Protobuf/Reflection/DescriptorBase.cs \
@@ -145,7 +149,7 @@ csharp_EXTRA_DIST= \
csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs \
csharp/src/Google.Protobuf/Reflection/FieldType.cs \
csharp/src/Google.Protobuf/Reflection/FileDescriptor.cs \
- csharp/src/Google.Protobuf/Reflection/GeneratedCodeInfo.cs \
+ csharp/src/Google.Protobuf/Reflection/GeneratedClrTypeInfo.cs \
csharp/src/Google.Protobuf/Reflection/IDescriptor.cs \
csharp/src/Google.Protobuf/Reflection/IFieldAccessor.cs \
csharp/src/Google.Protobuf/Reflection/MapFieldAccessor.cs \
@@ -153,12 +157,14 @@ csharp_EXTRA_DIST= \
csharp/src/Google.Protobuf/Reflection/MethodDescriptor.cs \
csharp/src/Google.Protobuf/Reflection/OneofAccessor.cs \
csharp/src/Google.Protobuf/Reflection/OneofDescriptor.cs \
+ csharp/src/Google.Protobuf/Reflection/OriginalNameAttribute.cs \
csharp/src/Google.Protobuf/Reflection/PackageDescriptor.cs \
csharp/src/Google.Protobuf/Reflection/PartialClasses.cs \
csharp/src/Google.Protobuf/Reflection/ReflectionUtil.cs \
csharp/src/Google.Protobuf/Reflection/RepeatedFieldAccessor.cs \
csharp/src/Google.Protobuf/Reflection/ServiceDescriptor.cs \
csharp/src/Google.Protobuf/Reflection/SingleFieldAccessor.cs \
+ csharp/src/Google.Protobuf/Reflection/TypeRegistry.cs \
csharp/src/Google.Protobuf/WellKnownTypes/Any.cs \
csharp/src/Google.Protobuf/WellKnownTypes/AnyPartial.cs \
csharp/src/Google.Protobuf/WellKnownTypes/Api.cs \
@@ -166,163 +172,195 @@ csharp_EXTRA_DIST= \
csharp/src/Google.Protobuf/WellKnownTypes/DurationPartial.cs \
csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs \
csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs \
+ csharp/src/Google.Protobuf/WellKnownTypes/FieldMaskPartial.cs \
csharp/src/Google.Protobuf/WellKnownTypes/SourceContext.cs \
csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs \
csharp/src/Google.Protobuf/WellKnownTypes/TimeExtensions.cs \
csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs \
csharp/src/Google.Protobuf/WellKnownTypes/TimestampPartial.cs \
csharp/src/Google.Protobuf/WellKnownTypes/Type.cs \
+ csharp/src/Google.Protobuf/WellKnownTypes/ValuePartial.cs \
csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs \
+ csharp/src/Google.Protobuf/WellKnownTypes/WrappersPartial.cs \
csharp/src/Google.Protobuf/WireFormat.cs \
+ csharp/src/Google.Protobuf/project.json \
csharp/src/packages/repositories.config
-java_EXTRA_DIST= \
- java/src/main/java/com/google/protobuf/AbstractMessage.java \
- java/src/main/java/com/google/protobuf/AbstractMessageLite.java \
- java/src/main/java/com/google/protobuf/AbstractParser.java \
- java/src/main/java/com/google/protobuf/AbstractProtobufList.java \
- java/src/main/java/com/google/protobuf/BlockingRpcChannel.java \
- java/src/main/java/com/google/protobuf/BlockingService.java \
- java/src/main/java/com/google/protobuf/BooleanArrayList.java \
- java/src/main/java/com/google/protobuf/BoundedByteString.java \
- java/src/main/java/com/google/protobuf/ByteString.java \
- java/src/main/java/com/google/protobuf/CodedInputStream.java \
- java/src/main/java/com/google/protobuf/CodedOutputStream.java \
- java/src/main/java/com/google/protobuf/Descriptors.java \
- java/src/main/java/com/google/protobuf/DoubleArrayList.java \
- java/src/main/java/com/google/protobuf/DynamicMessage.java \
- java/src/main/java/com/google/protobuf/Extension.java \
- java/src/main/java/com/google/protobuf/ExtensionLite.java \
- java/src/main/java/com/google/protobuf/ExtensionRegistry.java \
- java/src/main/java/com/google/protobuf/ExtensionRegistryLite.java \
- java/src/main/java/com/google/protobuf/FieldSet.java \
- java/src/main/java/com/google/protobuf/FloatArrayList.java \
- java/src/main/java/com/google/protobuf/GeneratedMessage.java \
- java/src/main/java/com/google/protobuf/GeneratedMessageLite.java \
- java/src/main/java/com/google/protobuf/IntArrayList.java \
- java/src/main/java/com/google/protobuf/Internal.java \
- java/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java \
- java/src/main/java/com/google/protobuf/LazyField.java \
- java/src/main/java/com/google/protobuf/LazyFieldLite.java \
- java/src/main/java/com/google/protobuf/LazyStringArrayList.java \
- java/src/main/java/com/google/protobuf/LazyStringList.java \
- java/src/main/java/com/google/protobuf/LiteralByteString.java \
- java/src/main/java/com/google/protobuf/LongArrayList.java \
- java/src/main/java/com/google/protobuf/MapEntry.java \
- java/src/main/java/com/google/protobuf/MapEntryLite.java \
- java/src/main/java/com/google/protobuf/MapField.java \
- java/src/main/java/com/google/protobuf/MapFieldLite.java \
- java/src/main/java/com/google/protobuf/Message.java \
- java/src/main/java/com/google/protobuf/MessageLite.java \
- java/src/main/java/com/google/protobuf/MessageLiteOrBuilder.java \
- java/src/main/java/com/google/protobuf/MessageOrBuilder.java \
- java/src/main/java/com/google/protobuf/MessageReflection.java \
- java/src/main/java/com/google/protobuf/MutabilityOracle.java \
- java/src/main/java/com/google/protobuf/Parser.java \
- java/src/main/java/com/google/protobuf/ProtobufArrayList.java \
- java/src/main/java/com/google/protobuf/ProtocolMessageEnum.java \
- java/src/main/java/com/google/protobuf/ProtocolStringList.java \
- java/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java \
- java/src/main/java/com/google/protobuf/RopeByteString.java \
- java/src/main/java/com/google/protobuf/RpcCallback.java \
- java/src/main/java/com/google/protobuf/RpcChannel.java \
- java/src/main/java/com/google/protobuf/RpcController.java \
- java/src/main/java/com/google/protobuf/RpcUtil.java \
- java/src/main/java/com/google/protobuf/Service.java \
- java/src/main/java/com/google/protobuf/ServiceException.java \
- java/src/main/java/com/google/protobuf/SingleFieldBuilder.java \
- java/src/main/java/com/google/protobuf/SmallSortedMap.java \
- java/src/main/java/com/google/protobuf/TextFormat.java \
- java/src/main/java/com/google/protobuf/UninitializedMessageException.java \
- java/src/main/java/com/google/protobuf/UnknownFieldSet.java \
- java/src/main/java/com/google/protobuf/UnknownFieldSetLite.java \
- java/src/main/java/com/google/protobuf/UnmodifiableLazyStringList.java \
- java/src/main/java/com/google/protobuf/Utf8.java \
- java/src/main/java/com/google/protobuf/WireFormat.java \
- java/src/test/java/com/google/protobuf/AbstractMessageTest.java \
- java/src/test/java/com/google/protobuf/AnyTest.java \
- java/src/test/java/com/google/protobuf/BooleanArrayListTest.java \
- java/src/test/java/com/google/protobuf/BoundedByteStringTest.java \
- java/src/test/java/com/google/protobuf/ByteStringTest.java \
- java/src/test/java/com/google/protobuf/CheckUtf8Test.java \
- java/src/test/java/com/google/protobuf/CodedInputStreamTest.java \
- java/src/test/java/com/google/protobuf/CodedOutputStreamTest.java \
- java/src/test/java/com/google/protobuf/DeprecatedFieldTest.java \
- java/src/test/java/com/google/protobuf/DescriptorsTest.java \
- java/src/test/java/com/google/protobuf/DoubleArrayListTest.java \
- java/src/test/java/com/google/protobuf/DynamicMessageTest.java \
- java/src/test/java/com/google/protobuf/FieldPresenceTest.java \
- java/src/test/java/com/google/protobuf/FloatArrayListTest.java \
- java/src/test/java/com/google/protobuf/ForceFieldBuildersPreRun.java \
- java/src/test/java/com/google/protobuf/GeneratedMessageTest.java \
- java/src/test/java/com/google/protobuf/IntArrayListTest.java \
- java/src/test/java/com/google/protobuf/IsValidUtf8Test.java \
- java/src/test/java/com/google/protobuf/IsValidUtf8TestUtil.java \
- java/src/test/java/com/google/protobuf/LazyFieldLiteTest.java \
- java/src/test/java/com/google/protobuf/LazyFieldTest.java \
- java/src/test/java/com/google/protobuf/LazyMessageLiteTest.java \
- java/src/test/java/com/google/protobuf/LazyStringArrayListTest.java \
- java/src/test/java/com/google/protobuf/LazyStringEndToEndTest.java \
- java/src/test/java/com/google/protobuf/LiteEqualsAndHashTest.java \
- java/src/test/java/com/google/protobuf/LiteTest.java \
- java/src/test/java/com/google/protobuf/LiteralByteStringTest.java \
- java/src/test/java/com/google/protobuf/LongArrayListTest.java \
- java/src/test/java/com/google/protobuf/MapForProto2LiteTest.java \
- java/src/test/java/com/google/protobuf/MapForProto2Test.java \
- java/src/test/java/com/google/protobuf/MapTest.java \
- java/src/test/java/com/google/protobuf/MessageTest.java \
- java/src/test/java/com/google/protobuf/NestedBuildersTest.java \
- java/src/test/java/com/google/protobuf/ParserTest.java \
- java/src/test/java/com/google/protobuf/ProtobufArrayListTest.java \
- java/src/test/java/com/google/protobuf/RepeatedFieldBuilderTest.java \
- java/src/test/java/com/google/protobuf/RopeByteStringSubstringTest.java \
- java/src/test/java/com/google/protobuf/RopeByteStringTest.java \
- java/src/test/java/com/google/protobuf/ServiceTest.java \
- java/src/test/java/com/google/protobuf/SingleFieldBuilderTest.java \
- java/src/test/java/com/google/protobuf/SmallSortedMapTest.java \
- java/src/test/java/com/google/protobuf/TestBadIdentifiers.java \
- java/src/test/java/com/google/protobuf/TestUtil.java \
- java/src/test/java/com/google/protobuf/TextFormatTest.java \
- java/src/test/java/com/google/protobuf/UnknownEnumValueTest.java \
- java/src/test/java/com/google/protobuf/UnknownFieldSetLiteTest.java \
- java/src/test/java/com/google/protobuf/UnknownFieldSetTest.java \
- java/src/test/java/com/google/protobuf/UnmodifiableLazyStringListTest.java \
- java/src/test/java/com/google/protobuf/WellKnownTypesTest.java \
- java/src/test/java/com/google/protobuf/WireFormatTest.java \
- java/src/test/java/com/google/protobuf/any_test.proto \
- java/src/test/java/com/google/protobuf/field_presence_test.proto \
- java/src/test/java/com/google/protobuf/lazy_fields_lite.proto \
- java/src/test/java/com/google/protobuf/lite_equals_and_hash.proto \
- java/src/test/java/com/google/protobuf/map_for_proto2_lite_test.proto \
- java/src/test/java/com/google/protobuf/map_for_proto2_test.proto \
- java/src/test/java/com/google/protobuf/map_initialization_order_test.proto \
- java/src/test/java/com/google/protobuf/map_test.proto \
- java/src/test/java/com/google/protobuf/multiple_files_test.proto \
- java/src/test/java/com/google/protobuf/nested_builders_test.proto \
- java/src/test/java/com/google/protobuf/nested_extension.proto \
- java/src/test/java/com/google/protobuf/nested_extension_lite.proto \
- java/src/test/java/com/google/protobuf/non_nested_extension.proto \
- java/src/test/java/com/google/protobuf/non_nested_extension_lite.proto \
- java/src/test/java/com/google/protobuf/outer_class_name_test.proto \
- java/src/test/java/com/google/protobuf/outer_class_name_test2.proto \
- java/src/test/java/com/google/protobuf/outer_class_name_test3.proto \
- java/src/test/java/com/google/protobuf/test_bad_identifiers.proto \
- java/src/test/java/com/google/protobuf/test_check_utf8.proto \
- java/src/test/java/com/google/protobuf/test_check_utf8_size.proto \
- java/src/test/java/com/google/protobuf/test_custom_options.proto \
- java/src/test/java/com/google/protobuf/test_extra_interfaces.proto \
- java/util/pom.xml \
- java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java \
- java/util/src/main/java/com/google/protobuf/util/FieldMaskUtil.java \
- java/util/src/main/java/com/google/protobuf/util/JsonFormat.java \
- java/util/src/main/java/com/google/protobuf/util/TimeUtil.java \
- java/util/src/test/java/com/google/protobuf/util/FieldMaskTreeTest.java \
- java/util/src/test/java/com/google/protobuf/util/FieldMaskUtilTest.java \
- java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java \
- java/util/src/test/java/com/google/protobuf/util/TimeUtilTest.java \
- java/util/src/test/java/com/google/protobuf/util/json_test.proto \
- java/pom.xml \
- java/README.md
+java_EXTRA_DIST= \
+ java/README.md \
+ java/core/generate-sources-build.xml \
+ java/core/generate-test-sources-build.xml \
+ java/core/pom.xml \
+ java/core/src/main/java/com/google/protobuf/AbstractMessage.java \
+ java/core/src/main/java/com/google/protobuf/AbstractMessageLite.java \
+ java/core/src/main/java/com/google/protobuf/AbstractParser.java \
+ java/core/src/main/java/com/google/protobuf/AbstractProtobufList.java \
+ java/core/src/main/java/com/google/protobuf/BlockingRpcChannel.java \
+ java/core/src/main/java/com/google/protobuf/BlockingService.java \
+ java/core/src/main/java/com/google/protobuf/BooleanArrayList.java \
+ java/core/src/main/java/com/google/protobuf/ByteBufferWriter.java \
+ java/core/src/main/java/com/google/protobuf/ByteOutput.java \
+ java/core/src/main/java/com/google/protobuf/ByteString.java \
+ java/core/src/main/java/com/google/protobuf/CodedInputStream.java \
+ java/core/src/main/java/com/google/protobuf/CodedOutputStream.java \
+ java/core/src/main/java/com/google/protobuf/Descriptors.java \
+ java/core/src/main/java/com/google/protobuf/DoubleArrayList.java \
+ java/core/src/main/java/com/google/protobuf/DynamicMessage.java \
+ java/core/src/main/java/com/google/protobuf/ExperimentalApi.java \
+ java/core/src/main/java/com/google/protobuf/Extension.java \
+ java/core/src/main/java/com/google/protobuf/ExtensionLite.java \
+ java/core/src/main/java/com/google/protobuf/ExtensionRegistry.java \
+ java/core/src/main/java/com/google/protobuf/ExtensionRegistryFactory.java \
+ java/core/src/main/java/com/google/protobuf/ExtensionRegistryLite.java \
+ java/core/src/main/java/com/google/protobuf/FieldSet.java \
+ java/core/src/main/java/com/google/protobuf/FloatArrayList.java \
+ java/core/src/main/java/com/google/protobuf/GeneratedMessage.java \
+ java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java \
+ java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java \
+ java/core/src/main/java/com/google/protobuf/IntArrayList.java \
+ java/core/src/main/java/com/google/protobuf/Internal.java \
+ java/core/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java \
+ java/core/src/main/java/com/google/protobuf/LazyField.java \
+ java/core/src/main/java/com/google/protobuf/LazyFieldLite.java \
+ java/core/src/main/java/com/google/protobuf/LazyStringArrayList.java \
+ java/core/src/main/java/com/google/protobuf/LazyStringList.java \
+ java/core/src/main/java/com/google/protobuf/LongArrayList.java \
+ java/core/src/main/java/com/google/protobuf/MapEntry.java \
+ java/core/src/main/java/com/google/protobuf/MapEntryLite.java \
+ java/core/src/main/java/com/google/protobuf/MapField.java \
+ java/core/src/main/java/com/google/protobuf/MapFieldLite.java \
+ java/core/src/main/java/com/google/protobuf/Message.java \
+ java/core/src/main/java/com/google/protobuf/MessageLite.java \
+ java/core/src/main/java/com/google/protobuf/MessageLiteOrBuilder.java \
+ java/core/src/main/java/com/google/protobuf/MessageLiteToString.java \
+ java/core/src/main/java/com/google/protobuf/MessageOrBuilder.java \
+ java/core/src/main/java/com/google/protobuf/MessageReflection.java \
+ java/core/src/main/java/com/google/protobuf/MutabilityOracle.java \
+ java/core/src/main/java/com/google/protobuf/NioByteString.java \
+ java/core/src/main/java/com/google/protobuf/Parser.java \
+ java/core/src/main/java/com/google/protobuf/ProtobufArrayList.java \
+ java/core/src/main/java/com/google/protobuf/ProtocolMessageEnum.java \
+ java/core/src/main/java/com/google/protobuf/ProtocolStringList.java \
+ java/core/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java \
+ java/core/src/main/java/com/google/protobuf/RepeatedFieldBuilderV3.java \
+ java/core/src/main/java/com/google/protobuf/RopeByteString.java \
+ java/core/src/main/java/com/google/protobuf/RpcCallback.java \
+ java/core/src/main/java/com/google/protobuf/RpcChannel.java \
+ java/core/src/main/java/com/google/protobuf/RpcController.java \
+ java/core/src/main/java/com/google/protobuf/RpcUtil.java \
+ java/core/src/main/java/com/google/protobuf/Service.java \
+ java/core/src/main/java/com/google/protobuf/ServiceException.java \
+ java/core/src/main/java/com/google/protobuf/SingleFieldBuilder.java \
+ java/core/src/main/java/com/google/protobuf/SingleFieldBuilderV3.java \
+ java/core/src/main/java/com/google/protobuf/SmallSortedMap.java \
+ java/core/src/main/java/com/google/protobuf/TextFormat.java \
+ java/core/src/main/java/com/google/protobuf/TextFormatEscaper.java \
+ java/core/src/main/java/com/google/protobuf/TextFormatParseInfoTree.java \
+ java/core/src/main/java/com/google/protobuf/TextFormatParseLocation.java \
+ java/core/src/main/java/com/google/protobuf/UninitializedMessageException.java \
+ java/core/src/main/java/com/google/protobuf/UnknownFieldSet.java \
+ java/core/src/main/java/com/google/protobuf/UnknownFieldSetLite.java \
+ java/core/src/main/java/com/google/protobuf/UnmodifiableLazyStringList.java \
+ java/core/src/main/java/com/google/protobuf/UnsafeByteOperations.java \
+ java/core/src/main/java/com/google/protobuf/UnsafeUtil.java \
+ java/core/src/main/java/com/google/protobuf/Utf8.java \
+ java/core/src/main/java/com/google/protobuf/WireFormat.java \
+ java/core/src/test/java/com/google/protobuf/AbstractMessageTest.java \
+ java/core/src/test/java/com/google/protobuf/AnyTest.java \
+ java/core/src/test/java/com/google/protobuf/BooleanArrayListTest.java \
+ java/core/src/test/java/com/google/protobuf/BoundedByteStringTest.java \
+ java/core/src/test/java/com/google/protobuf/ByteBufferWriterTest.java \
+ java/core/src/test/java/com/google/protobuf/ByteStringTest.java \
+ java/core/src/test/java/com/google/protobuf/CheckUtf8Test.java \
+ java/core/src/test/java/com/google/protobuf/CodedInputStreamTest.java \
+ java/core/src/test/java/com/google/protobuf/CodedOutputStreamTest.java \
+ java/core/src/test/java/com/google/protobuf/DeprecatedFieldTest.java \
+ java/core/src/test/java/com/google/protobuf/DescriptorsTest.java \
+ java/core/src/test/java/com/google/protobuf/DoubleArrayListTest.java \
+ java/core/src/test/java/com/google/protobuf/DynamicMessageTest.java \
+ java/core/src/test/java/com/google/protobuf/EnumTest.java \
+ java/core/src/test/java/com/google/protobuf/ExtensionRegistryFactoryTest.java \
+ java/core/src/test/java/com/google/protobuf/FieldPresenceTest.java \
+ java/core/src/test/java/com/google/protobuf/FloatArrayListTest.java \
+ java/core/src/test/java/com/google/protobuf/ForceFieldBuildersPreRun.java \
+ java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java \
+ java/core/src/test/java/com/google/protobuf/IntArrayListTest.java \
+ java/core/src/test/java/com/google/protobuf/IsValidUtf8Test.java \
+ java/core/src/test/java/com/google/protobuf/IsValidUtf8TestUtil.java \
+ java/core/src/test/java/com/google/protobuf/LazyFieldLiteTest.java \
+ java/core/src/test/java/com/google/protobuf/LazyFieldTest.java \
+ java/core/src/test/java/com/google/protobuf/LazyMessageLiteTest.java \
+ java/core/src/test/java/com/google/protobuf/LazyStringArrayListTest.java \
+ java/core/src/test/java/com/google/protobuf/LazyStringEndToEndTest.java \
+ java/core/src/test/java/com/google/protobuf/LiteEqualsAndHashTest.java \
+ java/core/src/test/java/com/google/protobuf/LiteTest.java \
+ java/core/src/test/java/com/google/protobuf/LiteralByteStringTest.java \
+ java/core/src/test/java/com/google/protobuf/LongArrayListTest.java \
+ java/core/src/test/java/com/google/protobuf/MapForProto2LiteTest.java \
+ java/core/src/test/java/com/google/protobuf/MapForProto2Test.java \
+ java/core/src/test/java/com/google/protobuf/MapTest.java \
+ java/core/src/test/java/com/google/protobuf/MessageTest.java \
+ java/core/src/test/java/com/google/protobuf/NestedBuildersTest.java \
+ java/core/src/test/java/com/google/protobuf/NioByteStringTest.java \
+ java/core/src/test/java/com/google/protobuf/ParseExceptionsTest.java \
+ java/core/src/test/java/com/google/protobuf/ParserTest.java \
+ java/core/src/test/java/com/google/protobuf/ProtobufArrayListTest.java \
+ java/core/src/test/java/com/google/protobuf/RepeatedFieldBuilderV3Test.java \
+ java/core/src/test/java/com/google/protobuf/RopeByteStringSubstringTest.java \
+ java/core/src/test/java/com/google/protobuf/RopeByteStringTest.java \
+ java/core/src/test/java/com/google/protobuf/ServiceTest.java \
+ java/core/src/test/java/com/google/protobuf/SingleFieldBuilderV3Test.java \
+ java/core/src/test/java/com/google/protobuf/SmallSortedMapTest.java \
+ java/core/src/test/java/com/google/protobuf/TestBadIdentifiers.java \
+ java/core/src/test/java/com/google/protobuf/TestUtil.java \
+ java/core/src/test/java/com/google/protobuf/TestUtilLite.java \
+ java/core/src/test/java/com/google/protobuf/TextFormatParseInfoTreeTest.java \
+ java/core/src/test/java/com/google/protobuf/TextFormatParseLocationTest.java \
+ java/core/src/test/java/com/google/protobuf/TextFormatTest.java \
+ java/core/src/test/java/com/google/protobuf/UnknownEnumValueTest.java \
+ java/core/src/test/java/com/google/protobuf/UnknownFieldSetLiteTest.java \
+ java/core/src/test/java/com/google/protobuf/UnknownFieldSetTest.java \
+ java/core/src/test/java/com/google/protobuf/UnmodifiableLazyStringListTest.java \
+ java/core/src/test/java/com/google/protobuf/WellKnownTypesTest.java \
+ java/core/src/test/java/com/google/protobuf/WireFormatTest.java \
+ java/core/src/test/proto/com/google/protobuf/any_test.proto \
+ java/core/src/test/proto/com/google/protobuf/field_presence_test.proto \
+ java/core/src/test/proto/com/google/protobuf/lazy_fields_lite.proto \
+ java/core/src/test/proto/com/google/protobuf/lite_equals_and_hash.proto \
+ java/core/src/test/proto/com/google/protobuf/map_for_proto2_lite_test.proto \
+ java/core/src/test/proto/com/google/protobuf/map_for_proto2_test.proto \
+ java/core/src/test/proto/com/google/protobuf/map_initialization_order_test.proto \
+ java/core/src/test/proto/com/google/protobuf/map_test.proto \
+ java/core/src/test/proto/com/google/protobuf/multiple_files_test.proto \
+ java/core/src/test/proto/com/google/protobuf/nested_builders_test.proto \
+ java/core/src/test/proto/com/google/protobuf/nested_extension.proto \
+ java/core/src/test/proto/com/google/protobuf/nested_extension_lite.proto \
+ java/core/src/test/proto/com/google/protobuf/non_nested_extension.proto \
+ java/core/src/test/proto/com/google/protobuf/non_nested_extension_lite.proto \
+ java/core/src/test/proto/com/google/protobuf/outer_class_name_test.proto \
+ java/core/src/test/proto/com/google/protobuf/outer_class_name_test2.proto \
+ java/core/src/test/proto/com/google/protobuf/outer_class_name_test3.proto \
+ java/core/src/test/proto/com/google/protobuf/test_bad_identifiers.proto \
+ java/core/src/test/proto/com/google/protobuf/test_check_utf8.proto \
+ java/core/src/test/proto/com/google/protobuf/test_check_utf8_size.proto \
+ java/core/src/test/proto/com/google/protobuf/test_custom_options.proto \
+ java/core/src/test/proto/com/google/protobuf/test_extra_interfaces.proto \
+ java/lite/generate-sources-build.xml \
+ java/lite/generate-test-sources-build.xml \
+ java/lite/pom.xml \
+ java/pom.xml \
+ java/util/pom.xml \
+ java/util/src/main/java/com/google/protobuf/util/Durations.java \
+ java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java \
+ java/util/src/main/java/com/google/protobuf/util/FieldMaskUtil.java \
+ java/util/src/main/java/com/google/protobuf/util/JsonFormat.java \
+ java/util/src/main/java/com/google/protobuf/util/TimeUtil.java \
+ java/util/src/main/java/com/google/protobuf/util/Timestamps.java \
+ java/util/src/test/java/com/google/protobuf/util/FieldMaskTreeTest.java \
+ java/util/src/test/java/com/google/protobuf/util/FieldMaskUtilTest.java \
+ java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java \
+ java/util/src/test/java/com/google/protobuf/util/TimeUtilTest.java \
+ java/util/src/test/proto/com/google/protobuf/util/json_test.proto
javanano_EXTRA_DIST= \
javanano/src/main/java/com/google/protobuf/nano/CodedOutputByteBufferNano.java \
@@ -369,13 +407,11 @@ objectivec_EXTRA_DIST= \
objectivec/DevTools/full_mac_build.sh \
objectivec/DevTools/pddm.py \
objectivec/DevTools/pddm_tests.py \
- objectivec/generate_descriptors_proto.sh \
+ objectivec/generate_well_known_types.sh \
objectivec/google/protobuf/Any.pbobjc.h \
objectivec/google/protobuf/Any.pbobjc.m \
objectivec/google/protobuf/Api.pbobjc.h \
objectivec/google/protobuf/Api.pbobjc.m \
- objectivec/google/protobuf/Descriptor.pbobjc.h \
- objectivec/google/protobuf/Descriptor.pbobjc.m \
objectivec/google/protobuf/Duration.pbobjc.h \
objectivec/google/protobuf/Duration.pbobjc.m \
objectivec/google/protobuf/Empty.pbobjc.h \
@@ -401,6 +437,7 @@ objectivec_EXTRA_DIST= \
objectivec/GPBCodedInputStream_PackagePrivate.h \
objectivec/GPBCodedOutputStream.h \
objectivec/GPBCodedOutputStream.m \
+ objectivec/GPBCodedOutputStream_PackagePrivate.h \
objectivec/GPBDescriptor.h \
objectivec/GPBDescriptor.m \
objectivec/GPBDescriptor_PackagePrivate.h \
@@ -437,8 +474,6 @@ objectivec_EXTRA_DIST= \
objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj \
objectivec/ProtocolBuffers_iOS.xcodeproj/project.xcworkspace/contents.xcworkspacedata \
objectivec/ProtocolBuffers_iOS.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings \
- objectivec/ProtocolBuffers_iOS.xcodeproj/xcshareddata/xcbaselines/8BBEA4A5147C727100C4ADB7.xcbaseline/FFE465CA-0E74-40E8-9F09-500B66B7DCB2.plist \
- objectivec/ProtocolBuffers_iOS.xcodeproj/xcshareddata/xcbaselines/8BBEA4A5147C727100C4ADB7.xcbaseline/Info.plist \
objectivec/ProtocolBuffers_iOS.xcodeproj/xcshareddata/xcschemes/PerformanceTests.xcscheme \
objectivec/ProtocolBuffers_iOS.xcodeproj/xcshareddata/xcschemes/ProtocolBuffers.xcscheme \
objectivec/ProtocolBuffers_OSX.xcodeproj/project.pbxproj \
@@ -447,6 +482,33 @@ objectivec_EXTRA_DIST= \
objectivec/ProtocolBuffers_OSX.xcodeproj/xcshareddata/xcschemes/PerformanceTests.xcscheme \
objectivec/ProtocolBuffers_OSX.xcodeproj/xcshareddata/xcschemes/ProtocolBuffers.xcscheme \
objectivec/README.md \
+ objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester.xcodeproj/project.pbxproj \
+ objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester.xcodeproj/project.xcworkspace/contents.xcworkspacedata \
+ objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester.xcodeproj/xcshareddata/xcschemes/OSXCocoaPodsTester.xcscheme \
+ objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/AppDelegate.h \
+ objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/AppDelegate.m \
+ objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/Assets.xcassets/AppIcon.appiconset/Contents.json \
+ objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/Base.lproj/MainMenu.xib \
+ objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/Info.plist \
+ objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/main.m \
+ objectivec/Tests/CocoaPods/OSXCocoaPodsTester/Podfile-framework \
+ objectivec/Tests/CocoaPods/OSXCocoaPodsTester/Podfile-static \
+ objectivec/Tests/CocoaPods/README.md \
+ objectivec/Tests/CocoaPods/iOSCocoaPodsTester/Podfile-framework \
+ objectivec/Tests/CocoaPods/iOSCocoaPodsTester/Podfile-static \
+ objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester.xcodeproj/project.pbxproj \
+ objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester.xcodeproj/project.xcworkspace/contents.xcworkspacedata \
+ objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester.xcodeproj/xcshareddata/xcschemes/iOSCocoaPodsTester.xcscheme \
+ objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/AppDelegate.h \
+ objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/AppDelegate.m \
+ objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/Assets.xcassets/AppIcon.appiconset/Contents.json \
+ objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/Base.lproj/LaunchScreen.storyboard \
+ objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/Base.lproj/Main.storyboard \
+ objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/Info.plist \
+ objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/ViewController.h \
+ objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/ViewController.m \
+ objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/main.m \
+ objectivec/Tests/CocoaPods/run_tests.sh \
objectivec/Tests/golden_message \
objectivec/Tests/golden_packed_fields_message \
objectivec/Tests/GPBARCUnittestProtos.m \
@@ -468,7 +530,6 @@ objectivec_EXTRA_DIST= \
objectivec/Tests/GPBMessageTests.m \
objectivec/Tests/GPBObjectiveCPlusPlusTest.mm \
objectivec/Tests/GPBPerfTests.m \
- objectivec/Tests/GPBStringTests.m \
objectivec/Tests/GPBSwiftTests.swift \
objectivec/Tests/GPBTestUtilities.h \
objectivec/Tests/GPBTestUtilities.m \
@@ -504,6 +565,15 @@ objectivec_EXTRA_DIST= \
python_EXTRA_DIST= \
python/MANIFEST.in \
+ python/google/__init__.py \
+ python/google/protobuf/__init__.py \
+ python/google/protobuf/descriptor.py \
+ python/google/protobuf/descriptor_database.py \
+ python/google/protobuf/descriptor_pool.py \
+ python/google/protobuf/internal/__init__.py \
+ python/google/protobuf/internal/_parameterized.py \
+ python/google/protobuf/internal/any_test.proto \
+ python/google/protobuf/internal/any_test.proto \
python/google/protobuf/internal/api_implementation.cc \
python/google/protobuf/internal/api_implementation.py \
python/google/protobuf/internal/containers.py \
@@ -517,18 +587,21 @@ python_EXTRA_DIST= \
python/google/protobuf/internal/enum_type_wrapper.py \
python/google/protobuf/internal/factory_test1.proto \
python/google/protobuf/internal/factory_test2.proto \
+ python/google/protobuf/internal/file_options_test.proto \
python/google/protobuf/internal/generator_test.py \
+ python/google/protobuf/internal/import_test_package/__init__.py \
+ python/google/protobuf/internal/import_test_package/inner.proto \
+ python/google/protobuf/internal/import_test_package/outer.proto \
python/google/protobuf/internal/json_format_test.py \
python/google/protobuf/internal/message_factory_test.py \
python/google/protobuf/internal/message_listener.py \
python/google/protobuf/internal/message_set_extensions.proto \
python/google/protobuf/internal/message_test.py \
python/google/protobuf/internal/missing_enum_values.proto \
- python/google/protobuf/internal/more_extensions_dynamic.proto \
python/google/protobuf/internal/more_extensions.proto \
+ python/google/protobuf/internal/more_extensions_dynamic.proto \
python/google/protobuf/internal/more_messages.proto \
python/google/protobuf/internal/packed_field_test.proto \
- python/google/protobuf/internal/_parameterized.py \
python/google/protobuf/internal/proto_builder_test.py \
python/google/protobuf/internal/python_message.py \
python/google/protobuf/internal/reflection_test.py \
@@ -540,53 +613,50 @@ python_EXTRA_DIST= \
python/google/protobuf/internal/text_format_test.py \
python/google/protobuf/internal/type_checkers.py \
python/google/protobuf/internal/unknown_fields_test.py \
+ python/google/protobuf/internal/well_known_types.py \
+ python/google/protobuf/internal/well_known_types.py \
+ python/google/protobuf/internal/well_known_types_test.py \
+ python/google/protobuf/internal/well_known_types_test.py \
python/google/protobuf/internal/wire_format.py \
python/google/protobuf/internal/wire_format_test.py \
- python/google/protobuf/internal/__init__.py \
- python/google/protobuf/internal/import_test_package/__init__.py \
- python/google/protobuf/internal/import_test_package/inner.proto \
- python/google/protobuf/internal/import_test_package/outer.proto \
+ python/google/protobuf/json_format.py \
+ python/google/protobuf/message.py \
+ python/google/protobuf/message_factory.py \
+ python/google/protobuf/proto_builder.py \
python/google/protobuf/pyext/README \
+ python/google/protobuf/pyext/__init__.py \
python/google/protobuf/pyext/cpp_message.py \
- python/google/protobuf/pyext/descriptor.h \
python/google/protobuf/pyext/descriptor.cc \
- python/google/protobuf/pyext/descriptor_pool.h \
- python/google/protobuf/pyext/descriptor_pool.cc \
- python/google/protobuf/pyext/descriptor_containers.h \
+ python/google/protobuf/pyext/descriptor.h \
python/google/protobuf/pyext/descriptor_containers.cc \
- python/google/protobuf/pyext/extension_dict.h \
+ python/google/protobuf/pyext/descriptor_containers.h \
+ python/google/protobuf/pyext/descriptor_database.cc \
+ python/google/protobuf/pyext/descriptor_database.h \
+ python/google/protobuf/pyext/descriptor_pool.cc \
+ python/google/protobuf/pyext/descriptor_pool.h \
python/google/protobuf/pyext/extension_dict.cc \
- python/google/protobuf/pyext/message.h \
+ python/google/protobuf/pyext/extension_dict.h \
+ python/google/protobuf/pyext/map_container.cc \
+ python/google/protobuf/pyext/map_container.h \
python/google/protobuf/pyext/message.cc \
- python/google/protobuf/pyext/message_map_container.cc \
- python/google/protobuf/pyext/message_map_container.h \
+ python/google/protobuf/pyext/message.h \
+ python/google/protobuf/pyext/message_module.cc \
python/google/protobuf/pyext/proto2_api_test.proto \
python/google/protobuf/pyext/python.proto \
python/google/protobuf/pyext/python_protobuf.h \
- python/google/protobuf/pyext/repeated_composite_container.h \
python/google/protobuf/pyext/repeated_composite_container.cc \
- python/google/protobuf/pyext/repeated_scalar_container.h \
+ python/google/protobuf/pyext/repeated_composite_container.h \
python/google/protobuf/pyext/repeated_scalar_container.cc \
- python/google/protobuf/pyext/scalar_map_container.cc \
- python/google/protobuf/pyext/scalar_map_container.h \
+ python/google/protobuf/pyext/repeated_scalar_container.h \
python/google/protobuf/pyext/scoped_pyobject_ptr.h \
- python/google/protobuf/pyext/__init__.py \
- python/google/protobuf/descriptor.py \
- python/google/protobuf/descriptor_database.py \
- python/google/protobuf/descriptor_pool.py \
- python/google/protobuf/json_format.py \
- python/google/protobuf/message.py \
- python/google/protobuf/message_factory.py \
- python/google/protobuf/proto_builder.py \
python/google/protobuf/reflection.py \
python/google/protobuf/service.py \
python/google/protobuf/service_reflection.py \
python/google/protobuf/symbol_database.py \
python/google/protobuf/text_encoding.py \
python/google/protobuf/text_format.py \
- python/google/protobuf/__init__.py \
- python/google/__init__.py \
python/mox.py \
+ python/setup.cfg \
python/setup.py \
python/stubout.py \
python/tox.ini \
@@ -612,6 +682,7 @@ ruby_EXTRA_DIST= \
ruby/google-protobuf.gemspec \
ruby/lib/google/protobuf/message_exts.rb \
ruby/lib/google/protobuf/repeated_field.rb \
+ ruby/lib/google/protobuf/well_known_types.rb \
ruby/lib/google/protobuf.rb \
ruby/pom.xml \
ruby/src/main/java/com/google/protobuf/jruby/RubyBuilder.java \
@@ -636,17 +707,61 @@ ruby_EXTRA_DIST= \
ruby/tests/repeated_field_test.rb \
ruby/tests/stress.rb \
ruby/tests/generated_code.proto \
- ruby/tests/generated_code.rb \
+ ruby/tests/test_import.proto \
ruby/tests/generated_code_test.rb \
+ ruby/tests/well_known_types_test.rb \
ruby/travis-test.sh
-all_EXTRA_DIST=$(csharp_EXTRA_DIST) $(java_EXTRA_DIST) $(javanano_EXTRA_DIST) $(objectivec_EXTRA_DIST) $(python_EXTRA_DIST) $(ruby_EXTRA_DIST)
+js_EXTRA_DIST= \
+ js/README.md \
+ js/binary/arith.js \
+ js/binary/arith_test.js \
+ js/binary/constants.js \
+ js/binary/decoder.js \
+ js/binary/decoder_test.js \
+ js/binary/encoder.js \
+ js/binary/proto_test.js \
+ js/binary/reader.js \
+ js/binary/reader_test.js \
+ js/binary/utils.js \
+ js/binary/utils_test.js \
+ js/binary/writer.js \
+ js/binary/writer_test.js \
+ js/commonjs/export.js \
+ js/commonjs/export_asserts.js \
+ js/commonjs/export_testdeps.js \
+ js/commonjs/import_test.js \
+ js/commonjs/jasmine.json \
+ js/commonjs/rewrite_tests_for_commonjs.js \
+ js/commonjs/test6/test6.proto \
+ js/commonjs/test7/test7.proto \
+ js/data.proto \
+ js/debug.js \
+ js/debug_test.js \
+ js/gulpfile.js \
+ js/jasmine.json \
+ js/map.js \
+ js/message.js \
+ js/message_test.js \
+ js/node_loader.js \
+ js/package.json \
+ js/proto3_test.js \
+ js/proto3_test.proto \
+ js/test.proto \
+ js/test2.proto \
+ js/test3.proto \
+ js/test4.proto \
+ js/test5.proto \
+ js/test_bootstrap.js \
+ js/testbinary.proto \
+ js/testempty.proto
+
+all_EXTRA_DIST=$(csharp_EXTRA_DIST) $(java_EXTRA_DIST) $(javanano_EXTRA_DIST) $(objectivec_EXTRA_DIST) $(python_EXTRA_DIST) $(ruby_EXTRA_DIST) $(js_EXTRA_DIST)
EXTRA_DIST = $(@DIST_LANG@_EXTRA_DIST) \
autogen.sh \
generate_descriptor_proto.sh \
README.md \
- INSTALL.txt \
LICENSE \
CONTRIBUTORS.txt \
CHANGES.txt \
@@ -656,6 +771,7 @@ EXTRA_DIST = $(@DIST_LANG@_EXTRA_DIST) \
WORKSPACE \
cmake/CMakeLists.txt \
cmake/README.md \
+ cmake/examples.cmake \
cmake/extract_includes.bat.in \
cmake/install.cmake \
cmake/libprotobuf.cmake \
@@ -664,20 +780,30 @@ EXTRA_DIST = $(@DIST_LANG@_EXTRA_DIST) \
cmake/protobuf-config-version.cmake.in \
cmake/protobuf-config.cmake.in \
cmake/protobuf-module.cmake.in \
+ cmake/protobuf-options.cmake \
cmake/protoc.cmake \
cmake/tests.cmake \
editors/README.txt \
editors/proto.vim \
editors/protobuf-mode.el \
+ examples/CMakeLists.txt \
examples/README.txt \
examples/Makefile \
examples/addressbook.proto \
examples/add_person.cc \
+ examples/add_person.go \
+ examples/add_person_test.go \
examples/list_people.cc \
+ examples/list_people.go \
examples/AddPerson.java \
+ examples/CMakeLists.txt \
examples/ListPeople.java \
examples/add_person.py \
- examples/list_people.py
+ examples/list_people.py \
+ examples/list_people_test.go \
+ protobuf.bzl \
+ six.BUILD \
+ util/python/BUILD
# Deletes all the files generated by autogen.sh.
MAINTAINERCLEANFILES = \
diff --git a/Protobuf.podspec b/Protobuf.podspec
index 92ff2904..72e6dd0a 100644
--- a/Protobuf.podspec
+++ b/Protobuf.podspec
@@ -5,34 +5,37 @@
# dependent projects use the :git notation to refer to the library.
Pod::Spec.new do |s|
s.name = 'Protobuf'
- s.version = '3.0.0-alpha-4.1'
+ s.version = '3.0.0'
s.summary = 'Protocol Buffers v.3 runtime library for Objective-C.'
s.homepage = 'https://github.com/google/protobuf'
s.license = 'New BSD'
s.authors = { 'The Protocol Buffers contributors' => 'protobuf@googlegroups.com' }
+ s.cocoapods_version = '>= 1.0'
+
+ s.source = { :git => 'https://github.com/google/protobuf.git',
+ :tag => "v#{s.version}" }
s.source_files = 'objectivec/*.{h,m}',
'objectivec/google/protobuf/Any.pbobjc.{h,m}',
'objectivec/google/protobuf/Api.pbobjc.{h,m}',
- 'objectivec/google/protobuf/Descriptor.pbobjc.{h,m}',
- 'objectivec/google/protobuf/Duration.pbobjc.h',
+ 'objectivec/google/protobuf/Duration.pbobjc.{h,m}',
'objectivec/google/protobuf/Empty.pbobjc.{h,m}',
'objectivec/google/protobuf/FieldMask.pbobjc.{h,m}',
'objectivec/google/protobuf/SourceContext.pbobjc.{h,m}',
'objectivec/google/protobuf/Struct.pbobjc.{h,m}',
- 'objectivec/google/protobuf/Timestamp.pbobjc.h',
+ 'objectivec/google/protobuf/Timestamp.pbobjc.{h,m}',
'objectivec/google/protobuf/Type.pbobjc.{h,m}',
'objectivec/google/protobuf/Wrappers.pbobjc.{h,m}'
- # Timestamp.pbobjc.m and Duration.pbobjc.m are #imported by GPBWellKnownTypes.m. So we can't
- # compile them (duplicate symbols), but we need them available for the importing:
- s.preserve_paths = 'objectivec/google/protobuf/Duration.pbobjc.m',
- 'objectivec/google/protobuf/Timestamp.pbobjc.m'
# The following would cause duplicate symbol definitions. GPBProtocolBuffers is expected to be
# left out, as it's an umbrella implementation file.
s.exclude_files = 'objectivec/GPBProtocolBuffers.m'
- s.header_mappings_dir = 'objectivec'
+
+ # Set a CPP symbol so the code knows to use framework imports.
+ s.user_target_xcconfig = { 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1' }
+ s.pod_target_xcconfig = { 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1' }
s.ios.deployment_target = '7.1'
s.osx.deployment_target = '10.9'
+ s.watchos.deployment_target = '2.0'
s.requires_arc = false
end
diff --git a/README.md b/README.md
index a974d301..ba9c589d 100644
--- a/README.md
+++ b/README.md
@@ -7,182 +7,66 @@ Copyright 2008 Google Inc.
https://developers.google.com/protocol-buffers/
-C++ Installation - Unix
------------------------
+Overview
+--------
-If you get the source from github, you need to generate the configure script
-first:
+Protocol Buffers (a.k.a., protobuf) are Google's language-neutral,
+platform-neutral, extensible mechanism for serializing structured data. You
+can find [protobuf's documentation on the Google Developers site](https://developers.google.com/protocol-buffers/).
- $ ./autogen.sh
+This README file contains protobuf installation instructions. To install
+protobuf, you need to install the protocol compiler (used to compile .proto
+files) and the protobuf runtime for your chosen programming language.
-This will download gmock source (which is used for C++ Protocol Buffer
-unit-tests) to the current directory and run automake, autoconf, etc.
-to generate the configure script and various template makefiles.
+Protocol Compiler Installation
+------------------------------
-You can skip this step if you are using a release package (which already
-contains gmock and the configure script).
+The protocol compiler is written in C++. If you are using C++, please follow
+the [C++ Installation Instructions](src/README.md) to install protoc along
+with the C++ runtime.
-To build and install the C++ Protocol Buffer runtime and the Protocol
-Buffer compiler (protoc) execute the following:
+For non-C++ users, the simplest way to install the protocol compiler is to
+download a pre-built binary from our release page:
- $ ./configure
- $ make
- $ make check
- $ make install
+ [https://github.com/google/protobuf/releases](https://github.com/google/protobuf/releases)
-If "make check" fails, you can still install, but it is likely that
-some features of this library will not work correctly on your system.
-Proceed at your own risk.
+In the downloads section of each release, you can find pre-built binaries in
+zip packages: protoc-$VERSION-$PLATFORM.zip. It contains the protoc binary
+as well as a set of standard .proto files distributed along with protobuf.
-"make install" may require superuser privileges.
+If you are looking for an old version that is not available in the release
+page, check out the maven repo here:
-For advanced usage information on configure and make, see INSTALL.txt.
+ [http://repo1.maven.org/maven2/com/google/protobuf/protoc/](http://repo1.maven.org/maven2/com/google/protobuf/protoc/)
-**Hint on install location**
+These pre-built binaries are only provided for released versions. If you want
+to use the github master version at HEAD, or you need to modify protobuf code,
+or you are using C++, it's recommended to build your own protoc binary from
+source.
- By default, the package will be installed to /usr/local. However,
- on many platforms, /usr/local/lib is not part of LD_LIBRARY_PATH.
- You can add it, but it may be easier to just install to /usr
- instead. To do this, invoke configure as follows:
+If you would like to build protoc binary from source, see the [C++ Installation
+Instructions](src/README.md).
- ./configure --prefix=/usr
+Protobuf Runtime Installation
+-----------------------------
- If you already built the package with a different prefix, make sure
- to run "make clean" before building again.
+Protobuf supports several different programming languages. For each programming
+language, you can find instructions in the corresponding source directory about
+how to install protobuf runtime for that specific language:
-**Compiling dependent packages**
+| Language | Source |
+|--------------------------------------|-------------------------------------------------------|
+| C++ (include C++ runtime and protoc) | [src](src) |
+| Java | [java](java) |
+| Python | [python](python) |
+| Objective-C | [objectivec](objectivec) |
+| C# | [csharp](csharp) |
+| JavaNano | [javanano](javanano) |
+| JavaScript | [js](js) |
+| Ruby | [ruby](ruby) |
+| Go | [golang/protobuf](https://github.com/golang/protobuf) |
+| PHP | TBD |
- To compile a package that uses Protocol Buffers, you need to pass
- various flags to your compiler and linker. As of version 2.2.0,
- Protocol Buffers integrates with pkg-config to manage this. If you
- have pkg-config installed, then you can invoke it to get a list of
- flags like so:
-
- pkg-config --cflags protobuf # print compiler flags
- pkg-config --libs protobuf # print linker flags
- pkg-config --cflags --libs protobuf # print both
-
- For example:
-
- c++ my_program.cc my_proto.pb.cc `pkg-config --cflags --libs protobuf`
-
- Note that packages written prior to the 2.2.0 release of Protocol
- Buffers may not yet integrate with pkg-config to get flags, and may
- not pass the correct set of flags to correctly link against
- libprotobuf. If the package in question uses autoconf, you can
- often fix the problem by invoking its configure script like:
-
- configure CXXFLAGS="$(pkg-config --cflags protobuf)" \
- LIBS="$(pkg-config --libs protobuf)"
-
- This will force it to use the correct flags.
-
- If you are writing an autoconf-based package that uses Protocol
- Buffers, you should probably use the PKG_CHECK_MODULES macro in your
- configure script like:
-
- PKG_CHECK_MODULES([protobuf], [protobuf])
-
- See the pkg-config man page for more info.
-
- If you only want protobuf-lite, substitute "protobuf-lite" in place
- of "protobuf" in these examples.
-
-**Note for Mac users**
-
- For a Mac system, Unix tools are not available by default. You will first need
- to install Xcode from the Mac AppStore and then run the following command from
- a terminal:
-
- $ sudo xcode-select --install
-
- To install Unix tools, you can install "port" following the instructions at
- https://www.macports.org . This will reside in /opt/local/bin/port for most
- Mac installations.
-
- $ sudo /opt/local/bin/port install autoconf automake libtool
-
- Then follow the Unix instructions above.
-
-**Note for cross-compiling**
-
- The makefiles normally invoke the protoc executable that they just
- built in order to build tests. When cross-compiling, the protoc
- executable may not be executable on the host machine. In this case,
- you must build a copy of protoc for the host machine first, then use
- the --with-protoc option to tell configure to use it instead. For
- example:
-
- ./configure --with-protoc=protoc
-
- This will use the installed protoc (found in your $PATH) instead of
- trying to execute the one built during the build process. You can
- also use an executable that hasn't been installed. For example, if
- you built the protobuf package for your host machine in ../host,
- you might do:
-
- ./configure --with-protoc=../host/src/protoc
-
- Either way, you must make sure that the protoc executable you use
- has the same version as the protobuf source code you are trying to
- use it with.
-
-**Note for Solaris users**
-
- Solaris 10 x86 has a bug that will make linking fail, complaining
- about libstdc++.la being invalid. We have included a work-around
- in this package. To use the work-around, run configure as follows:
-
- ./configure LDFLAGS=-L$PWD/src/solaris
-
- See src/solaris/libstdc++.la for more info on this bug.
-
-**Note for HP C++ Tru64 users**
-
- To compile invoke configure as follows:
-
- ./configure CXXFLAGS="-O -std ansi -ieee -D__USE_STD_IOSTREAM"
-
- Also, you will need to use gmake instead of make.
-
-**Note for AIX users**
-
- Compile using the IBM xlC C++ compiler as follows:
-
- ./configure CXX=xlC
-
- Also, you will need to use GNU `make` (`gmake`) instead of AIX `make`.
-
-C++ Installation - Windows
---------------------------
-
-If you are using Microsoft Visual C++, see cmake/README.md.
-
-If you are using Cygwin or MinGW, follow the Unix installation
-instructions, above.
-
-Binary Compatibility Warning
-----------------------------
-
-Due to the nature of C++, it is unlikely that any two versions of the
-Protocol Buffers C++ runtime libraries will have compatible ABIs.
-That is, if you linked an executable against an older version of
-libprotobuf, it is unlikely to work with a newer version without
-re-compiling. This problem, when it occurs, will normally be detected
-immediately on startup of your app. Still, you may want to consider
-using static linkage. You can configure this package to install
-static libraries only using:
-
- ./configure --disable-shared
-
-Java and Python Installation
-----------------------------
-
-The Java and Python runtime libraries for Protocol Buffers are located
-in the java and python directories. See the README file in each
-directory for more information on how to compile and install them.
-Note that both of them require you to first install the Protocol
-Buffer compiler (protoc), which is part of the C++ package.
Usage
-----
diff --git a/WORKSPACE b/WORKSPACE
index c3f18cc7..065dc819 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -1,28 +1,53 @@
new_http_archive(
- name = "gmock_archive",
- url = "https://googlemock.googlecode.com/files/gmock-1.7.0.zip",
- sha256 = "26fcbb5925b74ad5fc8c26b0495dfc96353f4d553492eb97e85a8a6d2f43095b",
- build_file = "gmock.BUILD",
+ name = "gmock_archive",
+ url = "https://googlemock.googlecode.com/files/gmock-1.7.0.zip",
+ sha256 = "26fcbb5925b74ad5fc8c26b0495dfc96353f4d553492eb97e85a8a6d2f43095b",
+ build_file = "gmock.BUILD",
)
new_http_archive(
- name = "six_archive",
- url = "https://pypi.python.org/packages/source/s/six/six-1.10.0.tar.gz#md5=34eed507548117b2ab523ab14b2f8b55",
- sha256 = "105f8d68616f8248e24bf0e9372ef04d3cc10104f1980f54d57b2ce73a5ad56a",
- build_file = "six.BUILD",
+ name = "six_archive",
+ url = "https://pypi.python.org/packages/source/s/six/six-1.10.0.tar.gz#md5=34eed507548117b2ab523ab14b2f8b55",
+ sha256 = "105f8d68616f8248e24bf0e9372ef04d3cc10104f1980f54d57b2ce73a5ad56a",
+ build_file = "six.BUILD",
)
bind(
- name = "gtest",
- actual = "@gmock_archive//:gtest",
+ name = "python_headers",
+ actual = "//util/python:python_headers",
)
bind(
- name = "gtest_main",
- actual = "@gmock_archive//:gtest_main",
+ name = "gtest",
+ actual = "@gmock_archive//:gtest",
)
bind(
- name = "six",
- actual = "@six_archive//:six",
+ name = "gtest_main",
+ actual = "@gmock_archive//:gtest_main",
+)
+
+bind(
+ name = "six",
+ actual = "@six_archive//:six",
+)
+
+maven_jar(
+ name = "guava_maven",
+ artifact = "com.google.guava:guava:18.0",
+)
+
+bind(
+ name = "guava",
+ actual = "@guava_maven//jar",
+)
+
+maven_jar(
+ name = "gson_maven",
+ artifact = "com.google.code.gson:gson:2.3",
+)
+
+bind(
+ name = "gson",
+ actual = "@gson_maven//jar",
)
diff --git a/appveyor.bat b/appveyor.bat
index 9a46b928..0e6dd520 100644
--- a/appveyor.bat
+++ b/appveyor.bat
@@ -19,9 +19,12 @@ goto :EOF
:build_csharp
echo Building C#
cd csharp\src
-nuget restore
-msbuild Google.Protobuf.sln /p:Platform="Any CPU" /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" || goto error
-nunit-console Google.Protobuf.Test\bin\%configuration%\Google.Protobuf.Test.dll || goto error
+dotnet restore
+dotnet build -c %configuration% Google.Protobuf Google.Protobuf.Test Google.Protobuf.Conformance || goto error
+
+echo Testing C#
+dotnet test -c %configuration% Google.Protobuf.Test || goto error
+
goto :EOF
:error
diff --git a/appveyor.yml b/appveyor.yml
index 3447602e..ce797c69 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,32 +1,38 @@
-# Only test one combination: "Visual Studio 12 + Win64 + Debug + DLL". We can
-# test more combinations but AppVeyor just takes too long to finish (each
-# combination takes ~15mins).
-platform:
- - Win64
-
-configuration:
- - Debug
-
-environment:
- matrix:
- - language: cpp
- BUILD_DLL: ON
-
- - language: csharp
-
-install:
- - ps: Start-FileDownload https://googlemock.googlecode.com/files/gmock-1.7.0.zip
- - 7z x gmock-1.7.0.zip
- - rename gmock-1.7.0 gmock
-
-before_build:
- - if %platform%==Win32 set generator=Visual Studio 12
- - if %platform%==Win64 set generator=Visual Studio 12 Win64
- - if %platform%==Win32 set vcplatform=Win32
- - if %platform%==Win64 set vcplatform=x64
-
-build_script:
- - CALL appveyor.bat
-
-skip_commits:
- message: /.*\[skip appveyor\].*/
+# Only test one combination: "Visual Studio 12 + Win64 + Debug + DLL". We can
+# test more combinations but AppVeyor just takes too long to finish (each
+# combination takes ~15mins).
+platform:
+ - Win64
+
+configuration:
+ - Debug
+
+environment:
+ matrix:
+ - language: cpp
+ BUILD_DLL: ON
+
+ - language: csharp
+
+# Our build scripts run tests automatically; we don't want AppVeyor
+# to try to detect them itself.
+test: off
+
+install:
+ - ps: Start-FileDownload https://googlemock.googlecode.com/files/gmock-1.7.0.zip
+ - 7z x gmock-1.7.0.zip
+ - rename gmock-1.7.0 gmock
+ - ps: Start-FileDownload https://go.microsoft.com/fwlink/?LinkID=809122 -FileName dotnetsdk.exe
+ - dotnetsdk.exe /install /quiet /norestart
+
+before_build:
+ - if %platform%==Win32 set generator=Visual Studio 12
+ - if %platform%==Win64 set generator=Visual Studio 12 Win64
+ - if %platform%==Win32 set vcplatform=Win32
+ - if %platform%==Win64 set vcplatform=x64
+
+build_script:
+ - CALL appveyor.bat
+
+skip_commits:
+ message: /.*\[skip appveyor\].*/
diff --git a/benchmarks/Makefile.am b/benchmarks/Makefile.am
new file mode 100644
index 00000000..f730afe5
--- /dev/null
+++ b/benchmarks/Makefile.am
@@ -0,0 +1,69 @@
+
+benchmarks_protoc_inputs = \
+ benchmarks.proto \
+ benchmark_messages_proto3.proto
+
+benchmarks_protoc_inputs_proto2 = \
+ benchmark_messages_proto2.proto
+
+benchmarks_protoc_outputs = \
+ benchmarks.pb.cc \
+ benchmarks.pb.h \
+ benchmark_messages_proto3.pb.cc \
+ benchmark_messages_proto3.pb.h
+
+benchmarks_protoc_outputs_proto2 = \
+ benchmark_messages_proto2.pb.cc \
+ benchmark_messages_proto2.pb.h
+
+bin_PROGRAMS = generate-datasets
+
+generate_datasets_LDADD = $(top_srcdir)/src/libprotobuf.la
+generate_datasets_SOURCES = generate_datasets.cc
+generate_datasets_CPPFLAGS = -I$(top_srcdir)/src -I$(srcdir)
+nodist_generate_datasets_SOURCES = \
+ $(benchmarks_protoc_outputs) \
+ $(benchmarks_protoc_outputs_proto2)
+
+# Explicit deps because BUILT_SOURCES are only done before a "make all/check"
+# so a direct "make test_cpp" could fail if parallel enough.
+# See: https://www.gnu.org/software/automake/manual/html_node/Built-Sources-Example.html#Recording-Dependencies-manually
+generate_datasets-generate_datasets.$(OBJEXT): benchmarks.pb.h
+
+$(benchmarks_protoc_outputs): protoc_middleman
+$(benchmarks_protoc_outputs_proto2): protoc_middleman2
+
+CLEANFILES = \
+ $(benchmarks_protoc_outputs) \
+ $(benchmarks_protoc_outputs_proto2) \
+ protoc_middleman \
+ protoc_middleman2 \
+ dataset.*
+
+MAINTAINERCLEANFILES = \
+ Makefile.in
+
+if USE_EXTERNAL_PROTOC
+
+protoc_middleman: $(benchmarks_protoc_inputs)
+ $(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. $(benchmarks_protoc_inputs)
+ touch protoc_middleman
+
+protoc_middleman2: $(benchmarks_protoc_inputs_proto2)
+ $(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. $(benchmarks_protoc_inputs_proto2)
+ touch protoc_middleman2
+
+else
+
+# We have to cd to $(srcdir) before executing protoc because $(protoc_inputs) is
+# relative to srcdir, which may not be the same as the current directory when
+# building out-of-tree.
+protoc_middleman: $(top_srcdir)/src/protoc$(EXEEXT) $(benchmarks_protoc_inputs) $(well_known_type_protoc_inputs)
+ oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd $(benchmarks_protoc_inputs) )
+ touch protoc_middleman
+
+protoc_middleman2: $(top_srcdir)/src/protoc$(EXEEXT) $(benchmarks_protoc_inputs_proto2) $(well_known_type_protoc_inputs)
+ oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd $(benchmarks_protoc_inputs_proto2) )
+ touch protoc_middleman
+
+endif
diff --git a/benchmarks/README.md b/benchmarks/README.md
new file mode 100644
index 00000000..c9027805
--- /dev/null
+++ b/benchmarks/README.md
@@ -0,0 +1,28 @@
+
+# Protocol Buffers Benchmarks
+
+This directory contains benchmarking schemas and data sets that you
+can use to test a variety of performance scenarios against your
+protobuf language runtime.
+
+The schema for the datasets is described in `benchmarks.proto`.
+
+Generate the data sets like so:
+
+```
+$ make
+$ ./generate-datasets
+Wrote dataset: dataset.google_message1_proto3.pb
+Wrote dataset: dataset.google_message1_proto2.pb
+Wrote dataset: dataset.google_message2.pb
+$
+```
+
+Each data set will be written to its own file. Benchmarks will
+likely want to run several benchmarks against each data set (parse,
+serialize, possibly JSON, possibly using different APIs, etc).
+
+We would like to add more data sets. In general we will favor data sets
+that make the overall suite diverse without being too large or having
+too many similar tests. Ideally everyone can run through the entire
+suite without the test run getting too long.
diff --git a/benchmarks/google_speed.proto b/benchmarks/benchmark_messages_proto2.proto
index 16f6d678..01f67a1a 100644
--- a/benchmarks/google_speed.proto
+++ b/benchmarks/benchmark_messages_proto2.proto
@@ -1,11 +1,14 @@
+// Benchmark messages for proto2.
+
syntax = "proto2";
-package benchmarks;
+package benchmarks.proto2;
+option java_package = "com.google.protobuf.benchmarks";
-option java_outer_classname = "GoogleSpeed";
+// This is the default, but we specify it here explicitly.
option optimize_for = SPEED;
-message SpeedMessage1 {
+message GoogleMessage1 {
required string field1 = 1;
optional string field9 = 9;
optional string field18 = 18;
@@ -40,7 +43,7 @@ message SpeedMessage1 {
optional int32 field23 = 23 [default=0];
optional bool field24 = 24 [default=false];
optional int32 field25 = 25 [default=0];
- optional SpeedMessage1SubMessage field15 = 15;
+ optional GoogleMessage1SubMessage field15 = 15;
optional bool field78 = 78;
optional int32 field67 = 67 [default=0];
optional int32 field68 = 68;
@@ -49,7 +52,7 @@ message SpeedMessage1 {
optional int32 field131 = 131 [default=0];
}
-message SpeedMessage1SubMessage {
+message GoogleMessage1SubMessage {
optional int32 field1 = 1 [default=0];
optional int32 field2 = 2 [default=0];
optional int32 field3 = 3 [default=0];
@@ -72,7 +75,7 @@ message SpeedMessage1SubMessage {
optional uint64 field300 = 300;
}
-message SpeedMessage2 {
+message GoogleMessage2 {
optional string field1 = 1;
optional int64 field3 = 3;
optional int64 field4 = 4;
@@ -112,7 +115,7 @@ message SpeedMessage2 {
repeated int32 field73 = 73;
optional int32 field20 = 20 [default=0];
optional string field24 = 24;
- optional SpeedMessage2GroupedMessage field31 = 31;
+ optional GoogleMessage2GroupedMessage field31 = 31;
}
repeated string field128 = 128;
optional int64 field131 = 131;
@@ -123,7 +126,7 @@ message SpeedMessage2 {
optional bool field206 = 206 [default=false];
}
-message SpeedMessage2GroupedMessage {
+message GoogleMessage2GroupedMessage {
optional float field1 = 1;
optional float field2 = 2;
optional float field3 = 3 [default=0.0];
diff --git a/benchmarks/benchmark_messages_proto3.proto b/benchmarks/benchmark_messages_proto3.proto
new file mode 100644
index 00000000..32f58698
--- /dev/null
+++ b/benchmarks/benchmark_messages_proto3.proto
@@ -0,0 +1,76 @@
+// Benchmark messages for proto3.
+
+syntax = "proto3";
+
+package benchmarks.proto3;
+option java_package = "com.google.protobuf.benchmarks";
+
+// This is the default, but we specify it here explicitly.
+option optimize_for = SPEED;
+
+message GoogleMessage1 {
+ string field1 = 1;
+ string field9 = 9;
+ string field18 = 18;
+ bool field80 = 80;
+ bool field81 = 81;
+ int32 field2 = 2;
+ int32 field3 = 3;
+ int32 field280 = 280;
+ int32 field6 = 6;
+ int64 field22 = 22;
+ string field4 = 4;
+ repeated fixed64 field5 = 5;
+ bool field59 = 59;
+ string field7 = 7;
+ int32 field16 = 16;
+ int32 field130 = 130;
+ bool field12 = 12;
+ bool field17 = 17;
+ bool field13 = 13;
+ bool field14 = 14;
+ int32 field104 = 104;
+ int32 field100 = 100;
+ int32 field101 = 101;
+ string field102 = 102;
+ string field103 = 103;
+ int32 field29 = 29;
+ bool field30 = 30;
+ int32 field60 = 60;
+ int32 field271 = 271;
+ int32 field272 = 272;
+ int32 field150 = 150;
+ int32 field23 = 23;
+ bool field24 = 24;
+ int32 field25 = 25;
+ GoogleMessage1SubMessage field15 = 15;
+ bool field78 = 78;
+ int32 field67 = 67;
+ int32 field68 = 68;
+ int32 field128 = 128;
+ string field129 = 129;
+ int32 field131 = 131;
+}
+
+message GoogleMessage1SubMessage {
+ int32 field1 = 1;
+ int32 field2 = 2;
+ int32 field3 = 3;
+ string field15 = 15;
+ bool field12 = 12;
+ int64 field13 = 13;
+ int64 field14 = 14;
+ int32 field16 = 16;
+ int32 field19 = 19;
+ bool field20 = 20;
+ bool field28 = 28;
+ fixed64 field21 = 21;
+ int32 field22 = 22;
+ bool field23 = 23;
+ bool field206 = 206;
+ fixed32 field203 = 203;
+ int32 field204 = 204;
+ string field205 = 205;
+ uint64 field207 = 207;
+ uint64 field300 = 300;
+}
diff --git a/benchmarks/benchmarks.proto b/benchmarks/benchmarks.proto
new file mode 100644
index 00000000..51c0b548
--- /dev/null
+++ b/benchmarks/benchmarks.proto
@@ -0,0 +1,63 @@
+// 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.
+
+syntax = "proto3";
+package benchmarks;
+option java_package = "com.google.protobuf.benchmarks";
+
+message BenchmarkDataset {
+ // Name of the benchmark dataset. This should be unique across all datasets.
+ // Should only contain word characters: [a-zA-Z0-9_]
+ string name = 1;
+
+ // Fully-qualified name of the protobuf message for this dataset.
+ // It will be one of the messages defined benchmark_messages_proto2.proto
+ // or benchmark_messages_proto3.proto.
+ //
+ // Implementations that do not support reflection can implement this with
+ // an explicit "if/else" chain that lists every known message defined
+ // in those files.
+ string message_name = 2;
+
+ // The payload(s) for this dataset. They should be parsed or serialized
+ // in sequence, in a loop, ie.
+ //
+ // while (!benchmarkDone) { // Benchmark runner decides when to exit.
+ // for (i = 0; i < benchmark.payload.length; i++) {
+ // parse(benchmark.payload[i])
+ // }
+ // }
+ //
+ // This is intended to let datasets include a variety of data to provide
+ // potentially more realistic results than just parsing the same message
+ // over and over. A single message parsed repeatedly could yield unusually
+ // good branch prediction performance.
+ repeated bytes payload = 3;
+}
diff --git a/benchmarks/generate_datasets.cc b/benchmarks/generate_datasets.cc
new file mode 100644
index 00000000..61e7adf1
--- /dev/null
+++ b/benchmarks/generate_datasets.cc
@@ -0,0 +1,117 @@
+// 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 <fstream>
+#include <iostream>
+#include "benchmarks.pb.h"
+
+using benchmarks::BenchmarkDataset;
+using google::protobuf::Descriptor;
+using google::protobuf::DescriptorPool;
+using google::protobuf::Message;
+using google::protobuf::MessageFactory;
+
+std::set<std::string> names;
+
+const char *file_prefix = "dataset.";
+const char *file_suffix = ".pb";
+
+void WriteFileWithPayloads(const std::string& name,
+ const std::string& message_name,
+ const std::vector<std::string>& payload) {
+ if (!names.insert(name).second) {
+ std::cerr << "Duplicate test name: " << name << "\n";
+ abort();
+ }
+
+ // First verify that this message name exists in our set of benchmark messages
+ // and that these payloads are valid for the given message.
+ const Descriptor* d =
+ DescriptorPool::generated_pool()->FindMessageTypeByName(message_name);
+
+ if (!d) {
+ std::cerr << "For dataset " << name << ", no such message: "
+ << message_name << "\n";
+ abort();
+ }
+
+ Message* m = MessageFactory::generated_factory()->GetPrototype(d)->New();
+
+ for (size_t i = 0; i < payload.size(); i++) {
+ if (!m->ParseFromString(payload[i])) {
+ std::cerr << "For dataset " << name << ", payload[" << i << "] fails "
+ << "to parse\n";
+ abort();
+ }
+ }
+
+ BenchmarkDataset dataset;
+ dataset.set_name(name);
+ dataset.set_message_name(message_name);
+ for (size_t i = 0; i < payload.size(); i++) {
+ dataset.add_payload()->assign(payload[i]);
+ }
+
+ std::ofstream writer;
+ std::string fname = file_prefix + name + file_suffix;
+ writer.open(fname.c_str());
+ dataset.SerializeToOstream(&writer);
+ writer.close();
+
+ std::cerr << "Wrote dataset: " << fname << "\n";
+}
+
+void WriteFile(const std::string& name, const std::string& message_name,
+ const std::string& payload) {
+ std::vector<std::string> payloads;
+ payloads.push_back(payload);
+ WriteFileWithPayloads(name, message_name, payloads);
+}
+
+std::string ReadFile(const std::string& name) {
+ std::ifstream file(name.c_str());
+ GOOGLE_CHECK(file.is_open()) << "Couldn't find file '" << name <<
+ "', please make sure you are running "
+ "this command from the benchmarks/ "
+ "directory.\n";
+ return std::string((std::istreambuf_iterator<char>(file)),
+ std::istreambuf_iterator<char>());
+}
+
+int main() {
+ WriteFile("google_message1_proto3", "benchmarks.proto3.GoogleMessage1",
+ ReadFile("google_message1.dat"));
+ WriteFile("google_message1_proto2", "benchmarks.proto2.GoogleMessage1",
+ ReadFile("google_message1.dat"));
+
+ // Not in proto3 because it has a group, which is not supported.
+ WriteFile("google_message2", "benchmarks.proto2.GoogleMessage2",
+ ReadFile("google_message2.dat"));
+}
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
index 15ae457a..f947b741 100644
--- a/cmake/CMakeLists.txt
+++ b/cmake/CMakeLists.txt
@@ -1,22 +1,28 @@
# Minimum CMake required
-cmake_minimum_required(VERSION 2.8)
+cmake_minimum_required(VERSION 2.8.12)
-# Project
-project(protobuf C CXX)
+if(protobuf_VERBOSE)
+ message(STATUS "Protocol Buffers Configuring...")
+endif()
# CMake policies
cmake_policy(SET CMP0022 NEW)
+# Project
+project(protobuf C CXX)
+
# Options
-option(protobuf_VERBOSE "Enable for verbose output" OFF)
option(protobuf_BUILD_TESTS "Build tests" ON)
+option(protobuf_BUILD_EXAMPLES "Build examples" OFF)
if (BUILD_SHARED_LIBS)
set(protobuf_BUILD_SHARED_LIBS_DEFAULT ON)
else (BUILD_SHARED_LIBS)
set(protobuf_BUILD_SHARED_LIBS_DEFAULT OFF)
endif (BUILD_SHARED_LIBS)
option(protobuf_BUILD_SHARED_LIBS "Build Shared Libraries" ${protobuf_BUILD_SHARED_LIBS_DEFAULT})
-option(protobuf_MSVC_STATIC_RUNTIME "Link static runtime libraries" ON)
+include(CMakeDependentOption)
+cmake_dependent_option(protobuf_MSVC_STATIC_RUNTIME "Link static runtime libraries" ON
+ "NOT protobuf_BUILD_SHARED_LIBS" OFF)
if (MSVC)
set(protobuf_WITH_ZLIB_DEFAULT OFF)
else (MSVC)
@@ -25,6 +31,9 @@ endif (MSVC)
option(protobuf_WITH_ZLIB "Build with zlib support" ${protobuf_WITH_ZLIB_DEFAULT})
set(protobuf_DEBUG_POSTFIX "d"
CACHE STRING "Default debug postfix")
+mark_as_advanced(protobuf_DEBUG_POSTFIX)
+# User options
+include(protobuf-options.cmake)
# Path to main configure script
set(protobuf_CONFIGURE_SCRIPT "../configure.ac")
@@ -44,17 +53,24 @@ string(REGEX REPLACE "${protobuf_AC_INIT_REGEX}" "\\2"
string(REGEX REPLACE "${protobuf_AC_INIT_REGEX}" "\\3"
protobuf_CONTACT "${protobuf_AC_INIT_LINE}")
# Parse version tweaks
-set(protobuf_VERSION_REGEX "^([0-9]+)\\.([0-9]+)\\.([0-9]+).*$")
+set(protobuf_VERSION_REGEX "^([0-9]+)\\.([0-9]+)\\.([0-9]+)-?(.*)$")
string(REGEX REPLACE "${protobuf_VERSION_REGEX}" "\\1"
protobuf_VERSION_MAJOR "${protobuf_VERSION_STRING}")
string(REGEX REPLACE "${protobuf_VERSION_REGEX}" "\\2"
protobuf_VERSION_MINOR "${protobuf_VERSION_STRING}")
string(REGEX REPLACE "${protobuf_VERSION_REGEX}" "\\3"
protobuf_VERSION_PATCH "${protobuf_VERSION_STRING}")
+string(REGEX REPLACE "${protobuf_VERSION_REGEX}" "\\4"
+ protobuf_VERSION_PRERELEASE "${protobuf_VERSION_STRING}")
+
# Package version
set(protobuf_VERSION
"${protobuf_VERSION_MAJOR}.${protobuf_VERSION_MINOR}.${protobuf_VERSION_PATCH}")
+if(protobuf_VERSION_PRERELEASE)
+ set(protobuf_VERSION "${protobuf_VERSION}-${protobuf_VERSION_PRERELEASE}")
+endif()
+
if(protobuf_VERBOSE)
message(STATUS "Configuration script parsing status [")
message(STATUS " Description : ${protobuf_DESCRIPTION}")
@@ -70,6 +86,7 @@ if (CMAKE_USE_PTHREADS_INIT)
add_definitions(-DHAVE_PTHREAD)
endif (CMAKE_USE_PTHREADS_INIT)
+set(_protobuf_FIND_ZLIB)
if (protobuf_WITH_ZLIB)
find_package(ZLIB)
if (ZLIB_FOUND)
@@ -80,6 +97,7 @@ if (protobuf_WITH_ZLIB)
# Using imported target if exists
if (TARGET ZLIB::ZLIB)
set(ZLIB_LIBRARIES ZLIB::ZLIB)
+ set(_protobuf_FIND_ZLIB "if(NOT ZLIB_FOUND)\n find_package(ZLIB)\nendif()")
endif (TARGET ZLIB::ZLIB)
else (ZLIB_FOUND)
set(HAVE_ZLIB 0)
@@ -118,6 +136,8 @@ if (MSVC)
# Build with multiple processes
add_definitions(/MP)
add_definitions(/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305)
+ # Allow big object
+ add_definitions(/bigobj)
string(REPLACE "/" "\\" PROTOBUF_SOURCE_WIN32_PATH ${protobuf_SOURCE_DIR})
string(REPLACE "/" "\\" PROTOBUF_BINARY_WIN32_PATH ${protobuf_BINARY_DIR})
configure_file(extract_includes.bat.in extract_includes.bat)
@@ -149,3 +169,11 @@ if (protobuf_BUILD_TESTS)
endif (protobuf_BUILD_TESTS)
include(install.cmake)
+
+if (protobuf_BUILD_EXAMPLES)
+ include(examples.cmake)
+endif (protobuf_BUILD_EXAMPLES)
+
+if(protobuf_VERBOSE)
+ message(STATUS "Protocol Buffers Configuring done")
+endif()
diff --git a/cmake/README.md b/cmake/README.md
index b3042e6c..1e7410d8 100644
--- a/cmake/README.md
+++ b/cmake/README.md
@@ -28,11 +28,11 @@ Create a folder where protobuf headers/libraries/binaries will be installed afte
C:\Path\to>mkdir install
-If *cmake* command is not avaliable from *Command Prompt*, add it to system *PATH* variable:
+If *cmake* command is not available from *Command Prompt*, add it to system *PATH* variable:
C:\Path\to>set PATH=%PATH%;C:\Program Files (x86)\CMake\bin
-If *git* command is not avaliable from *Command Prompt*, add it to system *PATH* variable:
+If *git* command is not available from *Command Prompt*, add it to system *PATH* variable:
C:\Path\to>set PATH=%PATH%;C:\Program Files\Git\cmd
@@ -157,7 +157,8 @@ And wait for the compilation to finish.
Testing
=======
-To run unit-tests:
+To run unit-tests, first you must compile protobuf as described above.
+Then run:
C:\Path\to\protobuf\cmake\build\release>nmake check
@@ -218,7 +219,7 @@ It sounds not so strange and it works.
This will create the following folders under the *install* location:
* bin - that contains protobuf *protoc.exe* compiler;
- * inclue - that contains C++ headers and protobuf *.proto files;
+ * include - that contains C++ headers and protobuf *.proto files;
* lib - that contains linking libraries and *CMake* configuration files for *protobuf* package.
Now you can if needed:
diff --git a/cmake/examples.cmake b/cmake/examples.cmake
new file mode 100644
index 00000000..e5cad63f
--- /dev/null
+++ b/cmake/examples.cmake
@@ -0,0 +1,57 @@
+if(protobuf_VERBOSE)
+ message(STATUS "Protocol Buffers Examples Configuring...")
+endif()
+
+get_filename_component(examples_dir "../examples" ABSOLUTE)
+
+if(protobuf_VERBOSE)
+ message(STATUS "Protocol Buffers Examples Configuring done")
+endif()
+include(ExternalProject)
+
+# Internal utility function: Create a custom target representing a build of examples with custom options.
+function(add_examples_build NAME)
+
+ ExternalProject_Add(${NAME}
+ PREFIX ${NAME}
+ SOURCE_DIR "${examples_dir}"
+ BINARY_DIR ${NAME}
+ STAMP_DIR ${NAME}/logs
+ INSTALL_COMMAND "" #Skip
+ LOG_CONFIGURE 1
+ CMAKE_CACHE_ARGS "-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}"
+ "-Dprotobuf_VERBOSE:BOOL=${protobuf_VERBOSE}"
+ ${ARGN}
+ )
+ set_property(TARGET ${NAME} PROPERTY FOLDER "Examples")
+ set_property(TARGET ${NAME} PROPERTY EXCLUDE_FROM_ALL TRUE)
+endfunction()
+
+# Add examples as an external project.
+# sub_directory cannot be used because the find_package(protobuf) call would cause failures with redefined targets.
+add_examples_build(examples "-Dprotobuf_DIR:PATH=${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_CMAKEDIR}")
+add_dependencies(examples libprotobuf protoc)
+
+option(protobuf_BUILD_EXAMPLES_MULTITEST "Build Examples in multiple configurations. Useful for testing." OFF)
+mark_as_advanced(protobuf_BUILD_EXAMPLES_MULTITEST)
+if(protobuf_BUILD_EXAMPLES_MULTITEST)
+ set_property(GLOBAL PROPERTY USE_FOLDERS ON)
+
+ #Build using the legacy compatibility module.
+ add_examples_build(examples-legacy
+ "-Dprotobuf_DIR:PATH=${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_CMAKEDIR}"
+ "-Dprotobuf_MODULE_COMPATIBLE:BOOL=TRUE"
+ )
+ add_dependencies(examples-legacy libprotobuf protoc)
+
+ #Build using the installed library.
+ add_examples_build(examples-installed
+ "-Dprotobuf_DIR:PATH=${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_CMAKEDIR}"
+ )
+
+ #Build using the installed library in legacy compatibility mode.
+ add_examples_build(examples-installed-legacy
+ "-Dprotobuf_DIR:PATH=${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_CMAKEDIR}"
+ "-Dprotobuf_MODULE_COMPATIBLE:BOOL=TRUE"
+ )
+endif()
diff --git a/cmake/extract_includes.bat.in b/cmake/extract_includes.bat.in
index f6d8b893..9edafca8 100644
--- a/cmake/extract_includes.bat.in
+++ b/cmake/extract_includes.bat.in
@@ -6,6 +6,7 @@ mkdir include\google\protobuf\compiler\cpp
mkdir include\google\protobuf\compiler\csharp
mkdir include\google\protobuf\compiler\java
mkdir include\google\protobuf\compiler\javanano
+mkdir include\google\protobuf\compiler\js
mkdir include\google\protobuf\compiler\objectivec
mkdir include\google\protobuf\compiler\python
mkdir include\google\protobuf\compiler\ruby
@@ -22,10 +23,12 @@ copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\command_line_
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\cpp\cpp_generator.h include\google\protobuf\compiler\cpp\cpp_generator.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\csharp\csharp_generator.h include\google\protobuf\compiler\csharp\csharp_generator.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\csharp\csharp_names.h include\google\protobuf\compiler\csharp\csharp_names.h
+copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\csharp\csharp_options.h include\google\protobuf\compiler\csharp\csharp_options.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\importer.h include\google\protobuf\compiler\importer.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\java\java_generator.h include\google\protobuf\compiler\java\java_generator.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\java\java_names.h include\google\protobuf\compiler\java\java_names.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\javanano\javanano_generator.h include\google\protobuf\compiler\javanano\javanano_generator.h
+copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\js\js_generator.h include\google\protobuf\compiler\js\js_generator.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\objectivec\objectivec_generator.h include\google\protobuf\compiler\objectivec\objectivec_generator.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\objectivec\objectivec_helpers.h include\google\protobuf\compiler\objectivec\objectivec_helpers.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\parser.h include\google\protobuf\compiler\parser.h
@@ -66,13 +69,11 @@ copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\metadata.h include\goo
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\reflection.h include\google\protobuf\reflection.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\reflection_ops.h include\google\protobuf\reflection_ops.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\repeated_field.h include\google\protobuf\repeated_field.h
-copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\repeated_field_reflection.h include\google\protobuf\repeated_field_reflection.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\service.h include\google\protobuf\service.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\source_context.pb.h include\google\protobuf\source_context.pb.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\struct.pb.h include\google\protobuf\struct.pb.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomic_sequence_num.h include\google\protobuf\stubs\atomic_sequence_num.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops.h include\google\protobuf\stubs\atomicops.h
-copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_power.h include\google\protobuf\stubs\atomicops_internals_power.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_arm64_gcc.h include\google\protobuf\stubs\atomicops_internals_arm64_gcc.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_arm_gcc.h include\google\protobuf\stubs\atomicops_internals_arm_gcc.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_arm_qnx.h include\google\protobuf\stubs\atomicops_internals_arm_qnx.h
@@ -81,6 +82,7 @@ copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_intern
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_macosx.h include\google\protobuf\stubs\atomicops_internals_macosx.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_mips_gcc.h include\google\protobuf\stubs\atomicops_internals_mips_gcc.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_pnacl.h include\google\protobuf\stubs\atomicops_internals_pnacl.h
+copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_power.h include\google\protobuf\stubs\atomicops_internals_power.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_solaris.h include\google\protobuf\stubs\atomicops_internals_solaris.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_tsan.h include\google\protobuf\stubs\atomicops_internals_tsan.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\atomicops_internals_x86_gcc.h include\google\protobuf\stubs\atomicops_internals_x86_gcc.h
diff --git a/cmake/install.cmake b/cmake/install.cmake
index dbb4265d..94ef2198 100644
--- a/cmake/install.cmake
+++ b/cmake/install.cmake
@@ -6,6 +6,7 @@ foreach(_library
libprotoc)
set_property(TARGET ${_library}
PROPERTY INTERFACE_INCLUDE_DIRECTORIES
+ $<BUILD_INTERFACE:${protobuf_source_dir}/src>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
install(TARGETS ${_library} EXPORT protobuf-targets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${_library}
@@ -16,34 +17,32 @@ endforeach()
install(TARGETS protoc EXPORT protobuf-targets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT protoc)
-if(TRUE)
- file(STRINGS extract_includes.bat.in _extract_strings
- REGEX "^copy")
- foreach(_extract_string ${_extract_strings})
- string(REPLACE "copy \${PROTOBUF_SOURCE_WIN32_PATH}\\" ""
- _extract_string ${_extract_string})
- string(REPLACE "\\" "/" _extract_string ${_extract_string})
- string(REGEX MATCH "^[^ ]+"
- _extract_from ${_extract_string})
- string(REGEX REPLACE "^${_extract_from} ([^$]+)" "\\1"
- _extract_to ${_extract_string})
- get_filename_component(_extract_from "${protobuf_SOURCE_DIR}/${_extract_from}" ABSOLUTE)
- get_filename_component(_extract_name ${_extract_to} NAME)
- get_filename_component(_extract_to ${_extract_to} PATH)
- string(REPLACE "include/" "${CMAKE_INSTALL_INCLUDEDIR}/"
- _extract_to "${_extract_to}")
- if(EXISTS "${_extract_from}")
- install(FILES "${_extract_from}"
- DESTINATION "${_extract_to}"
- COMPONENT protobuf-headers
- RENAME "${_extract_name}")
- else()
- message(AUTHOR_WARNING "The file \"${_extract_from}\" is listed in "
- "\"${protobuf_SOURCE_DIR}/cmake/extract_includes.bat.in\" "
- "but there not exists. The file will not be installed.")
- endif()
- endforeach()
-endif()
+file(STRINGS extract_includes.bat.in _extract_strings
+ REGEX "^copy")
+foreach(_extract_string ${_extract_strings})
+ string(REPLACE "copy \${PROTOBUF_SOURCE_WIN32_PATH}\\" ""
+ _extract_string ${_extract_string})
+ string(REPLACE "\\" "/" _extract_string ${_extract_string})
+ string(REGEX MATCH "^[^ ]+"
+ _extract_from ${_extract_string})
+ string(REGEX REPLACE "^${_extract_from} ([^$]+)" "\\1"
+ _extract_to ${_extract_string})
+ get_filename_component(_extract_from "${protobuf_SOURCE_DIR}/${_extract_from}" ABSOLUTE)
+ get_filename_component(_extract_name ${_extract_to} NAME)
+ get_filename_component(_extract_to ${_extract_to} PATH)
+ string(REPLACE "include/" "${CMAKE_INSTALL_INCLUDEDIR}/"
+ _extract_to "${_extract_to}")
+ if(EXISTS "${_extract_from}")
+ install(FILES "${_extract_from}"
+ DESTINATION "${_extract_to}"
+ COMPONENT protobuf-headers
+ RENAME "${_extract_name}")
+ else()
+ message(AUTHOR_WARNING "The file \"${_extract_from}\" is listed in "
+ "\"${protobuf_SOURCE_DIR}/cmake/extract_includes.bat.in\" "
+ "but there not exists. The file will not be installed.")
+ endif()
+endforeach()
# Internal function for parsing auto tools scripts
function(_protobuf_auto_list FILE_NAME VARIABLE)
@@ -82,22 +81,43 @@ foreach(_file ${nobase_dist_proto_DATA})
endif()
endforeach()
-# Export configuration
-
-install(EXPORT protobuf-targets
- DESTINATION "lib/cmake/protobuf"
- COMPONENT protobuf-export)
+# Install configuration
+set(_cmakedir_desc "Directory relative to CMAKE_INSTALL to install the cmake configuration files")
+if(NOT MSVC)
+ set(CMAKE_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/protobuf" CACHE STRING "${_cmakedir_desc}")
+else()
+ set(CMAKE_INSTALL_CMAKEDIR "cmake" CACHE STRING "${_cmakedir_desc}")
+endif()
+mark_as_advanced(CMAKE_INSTALL_CMAKEDIR)
configure_file(protobuf-config.cmake.in
- protobuf-config.cmake @ONLY)
+ ${CMAKE_INSTALL_CMAKEDIR}/protobuf-config.cmake @ONLY)
configure_file(protobuf-config-version.cmake.in
- protobuf-config-version.cmake @ONLY)
+ ${CMAKE_INSTALL_CMAKEDIR}/protobuf-config-version.cmake @ONLY)
configure_file(protobuf-module.cmake.in
- protobuf-module.cmake @ONLY)
+ ${CMAKE_INSTALL_CMAKEDIR}/protobuf-module.cmake @ONLY)
+configure_file(protobuf-options.cmake
+ ${CMAKE_INSTALL_CMAKEDIR}/protobuf-options.cmake @ONLY)
+
+# Allows the build directory to be used as a find directory.
+export(TARGETS libprotobuf-lite libprotobuf libprotoc protoc
+ NAMESPACE protobuf::
+ FILE ${CMAKE_INSTALL_CMAKEDIR}/protobuf-targets.cmake
+)
-install(FILES
- "${protobuf_BINARY_DIR}/protobuf-config.cmake"
- "${protobuf_BINARY_DIR}/protobuf-config-version.cmake"
- "${protobuf_BINARY_DIR}/protobuf-module.cmake"
- DESTINATION "lib/cmake/protobuf"
+install(EXPORT protobuf-targets
+ DESTINATION "${CMAKE_INSTALL_CMAKEDIR}"
+ NAMESPACE protobuf::
COMPONENT protobuf-export)
+
+install(DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_CMAKEDIR}/
+ DESTINATION "${CMAKE_INSTALL_CMAKEDIR}"
+ COMPONENT protobuf-export
+ PATTERN protobuf-targets.cmake EXCLUDE
+)
+
+option(protobuf_INSTALL_EXAMPLES "Install the examples folder" OFF)
+if(protobuf_INSTALL_EXAMPLES)
+ install(DIRECTORY ../examples/ DESTINATION examples
+ COMPONENT protobuf-examples)
+endif()
diff --git a/cmake/libprotobuf.cmake b/cmake/libprotobuf.cmake
index a6ee8f2e..26e1f356 100644
--- a/cmake/libprotobuf.cmake
+++ b/cmake/libprotobuf.cmake
@@ -40,6 +40,7 @@ set(libprotobuf_files
${protobuf_source_dir}/src/google/protobuf/util/internal/json_objectwriter.cc
${protobuf_source_dir}/src/google/protobuf/util/internal/json_stream_parser.cc
${protobuf_source_dir}/src/google/protobuf/util/internal/object_writer.cc
+ ${protobuf_source_dir}/src/google/protobuf/util/internal/proto_writer.cc
${protobuf_source_dir}/src/google/protobuf/util/internal/protostream_objectsource.cc
${protobuf_source_dir}/src/google/protobuf/util/internal/protostream_objectwriter.cc
${protobuf_source_dir}/src/google/protobuf/util/internal/type_info.cc
@@ -55,7 +56,10 @@ set(libprotobuf_files
add_library(libprotobuf ${protobuf_SHARED_OR_STATIC}
${libprotobuf_lite_files} ${libprotobuf_files})
-target_link_libraries(libprotobuf ${CMAKE_THREAD_LIBS_INIT} ${ZLIB_LIBRARIES})
+target_link_libraries(libprotobuf ${CMAKE_THREAD_LIBS_INIT})
+if(protobuf_WITH_ZLIB)
+ target_link_libraries(libprotobuf ${ZLIB_LIBRARIES})
+endif()
target_include_directories(libprotobuf PUBLIC ${protobuf_source_dir}/src)
if(MSVC AND protobuf_BUILD_SHARED_LIBS)
target_compile_definitions(libprotobuf
diff --git a/cmake/libprotoc.cmake b/cmake/libprotoc.cmake
index 4e628905..8df8986a 100644
--- a/cmake/libprotoc.cmake
+++ b/cmake/libprotoc.cmake
@@ -37,6 +37,7 @@ set(libprotoc_files
${protobuf_source_dir}/src/google/protobuf/compiler/java/java_enum_field_lite.cc
${protobuf_source_dir}/src/google/protobuf/compiler/java/java_enum_lite.cc
${protobuf_source_dir}/src/google/protobuf/compiler/java/java_extension.cc
+ ${protobuf_source_dir}/src/google/protobuf/compiler/java/java_extension_lite.cc
${protobuf_source_dir}/src/google/protobuf/compiler/java/java_field.cc
${protobuf_source_dir}/src/google/protobuf/compiler/java/java_file.cc
${protobuf_source_dir}/src/google/protobuf/compiler/java/java_generator.cc
@@ -70,6 +71,7 @@ set(libprotoc_files
${protobuf_source_dir}/src/google/protobuf/compiler/javanano/javanano_message.cc
${protobuf_source_dir}/src/google/protobuf/compiler/javanano/javanano_message_field.cc
${protobuf_source_dir}/src/google/protobuf/compiler/javanano/javanano_primitive_field.cc
+ ${protobuf_source_dir}/src/google/protobuf/compiler/js/js_generator.cc
${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_enum.cc
${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc
${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_extension.cc
diff --git a/cmake/protobuf-config-version.cmake.in b/cmake/protobuf-config-version.cmake.in
index 1f171c66..0036c9ef 100644
--- a/cmake/protobuf-config-version.cmake.in
+++ b/cmake/protobuf-config-version.cmake.in
@@ -1 +1,58 @@
-set(PACKAGE_VERSION @protobuf_VERSION@)
+set(PACKAGE_VERSION "@protobuf_VERSION@")
+set(${PACKAGE_FIND_NAME}_VERSION_PRERELEASE "@protobuf_VERSION_PRERELEASE@" PARENT_SCOPE)
+
+# Prerelease versions cannot be passed in directly via the find_package command,
+# so we allow users to specify it in a variable
+if(NOT DEFINED "${PACKAGE_FIND_NAME}_FIND_VERSION_PRERELEASE")
+ set("${${PACKAGE_FIND_NAME}_FIND_VERSION_PRERELEASE}" "")
+else()
+ set(PACKAGE_FIND_VERSION ${PACKAGE_FIND_VERSION}-${${PACKAGE_FIND_NAME}_FIND_VERSION_PRERELEASE})
+endif()
+set(PACKAGE_FIND_VERSION_PRERELEASE "${${PACKAGE_FIND_NAME}_FIND_VERSION_PRERELEASE}")
+
+# VERSION_EQUAL ignores the prerelease strings, so we use STREQUAL.
+if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION)
+ set(PACKAGE_VERSION_EXACT TRUE)
+endif()
+
+set(PACKAGE_VERSION_COMPATIBLE TRUE) #Assume true until shown otherwise
+
+if(NOT PACKAGE_FIND_VERSION_MAJOR EQUAL "@protobuf_VERSION_MAJOR@")
+ set(PACKAGE_VERSION_COMPATIBLE FALSE)
+elseif(PACKAGE_FIND_VERSION VERSION_GREATER PACKAGE_VERSION)
+ set(PACKAGE_VERSION_COMPATIBLE FALSE)
+elseif(PACKAGE_FIND_VERSION VERSION_EQUAL PACKAGE_VERSION)
+ # Do not match prerelease versions to non-prerelease version requests.
+ if(NOT "@protobuf_VERSION_PRERELEASE@" STREQUAL "" AND PACKAGE_FIND_VERSION_PRERELEASE STREQUAL "")
+ message(AUTHOR_WARNING "To use this prerelease version of ${PACKAGE_FIND_NAME}, set ${PACKAGE_FIND_NAME}_FIND_VERSION_PRERELEASE to '@protobuf_VERSION_PRERELEASE@' or greater.")
+ set(PACKAGE_VERSION_COMPATIBLE FALSE)
+ endif()
+
+ # Not robustly SemVer compliant, but protobuf never uses '.' separated prerelease identifiers.
+ if(PACKAGE_FIND_VERSION_PRERELEASE STRGREATER "@protobuf_VERSION_PRERELEASE@")
+ set(PACKAGE_VERSION_COMPATIBLE FALSE)
+ endif()
+endif()
+
+# Check and save build options used to create this package
+macro(_check_and_save_build_option OPTION VALUE)
+ if(DEFINED ${PACKAGE_FIND_NAME}_${OPTION} AND
+ NOT ${PACKAGE_FIND_NAME}_${OPTION} EQUAL VALUE)
+ set(PACKAGE_VERSION_UNSUITABLE TRUE)
+ endif()
+ set(${PACKAGE_FIND_NAME}_${OPTION} ${VALUE})
+endmacro()
+_check_and_save_build_option(WITH_ZLIB @protobuf_WITH_ZLIB@)
+_check_and_save_build_option(MSVC_STATIC_RUNTIME @protobuf_MSVC_STATIC_RUNTIME@)
+_check_and_save_build_option(BUILD_SHARED_LIBS @protobuf_BUILD_SHARED_LIBS@)
+
+# if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it:
+if(NOT "${CMAKE_SIZEOF_VOID_P}" STREQUAL "" AND NOT "@CMAKE_SIZEOF_VOID_P@" STREQUAL "")
+ # check that the installed version has the same 32/64bit-ness as the one which is currently searching:
+ if(NOT CMAKE_SIZEOF_VOID_P STREQUAL "@CMAKE_SIZEOF_VOID_P@")
+ math(EXPR installedBits "@CMAKE_SIZEOF_VOID_P@ * 8")
+ set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)")
+ set(PACKAGE_VERSION_UNSUITABLE TRUE)
+ endif()
+endif()
+
diff --git a/cmake/protobuf-config.cmake.in b/cmake/protobuf-config.cmake.in
index bb0997b8..a044fe5c 100644
--- a/cmake/protobuf-config.cmake.in
+++ b/cmake/protobuf-config.cmake.in
@@ -1,27 +1,13 @@
-# Version info variables
-set(PROTOBUF_VERSION "@protobuf_VERSION@")
-set(PROTOBUF_VERSION_STRING "@protobuf_VERSION_STRING@")
+# User options
+include("${CMAKE_CURRENT_LIST_DIR}/protobuf-options.cmake")
-# Current dir
-get_filename_component(_PROTOBUF_PACKAGE_PREFIX
- "${CMAKE_CURRENT_LIST_FILE}" PATH)
+# Depend packages
+@_protobuf_FIND_ZLIB@
# Imported targets
-include("${_PROTOBUF_PACKAGE_PREFIX}/protobuf-targets.cmake")
-
-# Compute the installation prefix relative to this file.
-get_filename_component(_PROTOBUF_IMPORT_PREFIX
- "${_PROTOBUF_PACKAGE_PREFIX}" PATH)
-get_filename_component(_PROTOBUF_IMPORT_PREFIX
- "${_PROTOBUF_IMPORT_PREFIX}" PATH)
-get_filename_component(_PROTOBUF_IMPORT_PREFIX
- "${_PROTOBUF_IMPORT_PREFIX}" PATH)
+include("${CMAKE_CURRENT_LIST_DIR}/protobuf-targets.cmake")
# CMake FindProtobuf module compatible file
-if(NOT DEFINED PROTOBUF_MODULE_COMPATIBLE OR "${PROTOBUF_MODULE_COMPATIBLE}")
- include("${_PROTOBUF_PACKAGE_PREFIX}/protobuf-module.cmake")
+if(protobuf_MODULE_COMPATIBLE)
+ include("${CMAKE_CURRENT_LIST_DIR}/protobuf-module.cmake")
endif()
-
-# Cleanup temporary variables.
-set(_PROTOBUF_PACKAGE_PREFIX)
-set(_PROTOBUF_IMPORT_PREFIX)
diff --git a/cmake/protobuf-module.cmake.in b/cmake/protobuf-module.cmake.in
index d81dc459..614e4c04 100644
--- a/cmake/protobuf-module.cmake.in
+++ b/cmake/protobuf-module.cmake.in
@@ -1,7 +1,4 @@
-if(PROTOBUF_SRC_ROOT_FOLDER)
- message(AUTHOR_WARNING "Variable PROTOBUF_SRC_ROOT_FOLDER defined, but not"
- " used in CONFIG mode")
-endif()
+# Functions
function(PROTOBUF_GENERATE_CPP SRCS HDRS)
if(NOT ARGN)
@@ -23,12 +20,8 @@ function(PROTOBUF_GENERATE_CPP SRCS HDRS)
set(_protobuf_include_path -I ${CMAKE_CURRENT_SOURCE_DIR})
endif()
- # Add well-known type protos include path
- list(APPEND _protobuf_include_path
- -I "${_PROTOBUF_IMPORT_PREFIX}/@CMAKE_INSTALL_INCLUDEDIR@")
-
- if(DEFINED PROTOBUF_IMPORT_DIRS)
- foreach(DIR ${PROTOBUF_IMPORT_DIRS})
+ if(DEFINED Protobuf_IMPORT_DIRS)
+ foreach(DIR ${Protobuf_IMPORT_DIRS})
get_filename_component(ABS_PATH ${DIR} ABSOLUTE)
list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
if(${_contains_already} EQUAL -1)
@@ -49,11 +42,11 @@ function(PROTOBUF_GENERATE_CPP SRCS HDRS)
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.cc"
"${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h"
- COMMAND ${PROTOBUF_PROTOC_EXECUTABLE}
+ COMMAND ${Protobuf_PROTOC_EXECUTABLE}
ARGS --cpp_out ${CMAKE_CURRENT_BINARY_DIR} ${_protobuf_include_path} ${ABS_FIL}
- DEPENDS ${ABS_FIL} ${PROTOBUF_PROTOC_EXECUTABLE}
+ DEPENDS ${ABS_FIL} ${Protobuf_PROTOC_EXECUTABLE}
COMMENT "Running C++ protocol buffer compiler on ${FIL}"
- VERBATIM)
+ VERBATIM )
endforeach()
set_source_files_properties(${${SRCS}} ${${HDRS}} PROPERTIES GENERATED TRUE)
@@ -61,29 +54,104 @@ function(PROTOBUF_GENERATE_CPP SRCS HDRS)
set(${HDRS} ${${HDRS}} PARENT_SCOPE)
endfunction()
+function(PROTOBUF_GENERATE_PYTHON SRCS)
+ if(NOT ARGN)
+ message(SEND_ERROR "Error: PROTOBUF_GENERATE_PYTHON() called without any proto files")
+ return()
+ endif()
+
+ if(PROTOBUF_GENERATE_CPP_APPEND_PATH)
+ # Create an include path for each file specified
+ foreach(FIL ${ARGN})
+ get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
+ get_filename_component(ABS_PATH ${ABS_FIL} PATH)
+ list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
+ if(${_contains_already} EQUAL -1)
+ list(APPEND _protobuf_include_path -I ${ABS_PATH})
+ endif()
+ endforeach()
+ else()
+ set(_protobuf_include_path -I ${CMAKE_CURRENT_SOURCE_DIR})
+ endif()
+
+ if(DEFINED Protobuf_IMPORT_DIRS)
+ foreach(DIR ${Protobuf_IMPORT_DIRS})
+ get_filename_component(ABS_PATH ${DIR} ABSOLUTE)
+ list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
+ if(${_contains_already} EQUAL -1)
+ list(APPEND _protobuf_include_path -I ${ABS_PATH})
+ endif()
+ endforeach()
+ endif()
+
+ set(${SRCS})
+ foreach(FIL ${ARGN})
+ get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
+ get_filename_component(FIL_WE ${FIL} NAME_WE)
+
+ list(APPEND ${SRCS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}_pb2.py")
+ add_custom_command(
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}_pb2.py"
+ COMMAND ${Protobuf_PROTOC_EXECUTABLE} --python_out ${CMAKE_CURRENT_BINARY_DIR} ${_protobuf_include_path} ${ABS_FIL}
+ DEPENDS ${ABS_FIL} ${Protobuf_PROTOC_EXECUTABLE}
+ COMMENT "Running Python protocol buffer compiler on ${FIL}"
+ VERBATIM )
+ endforeach()
+
+ set(${SRCS} ${${SRCS}} PARENT_SCOPE)
+endfunction()
+
+# Environment
+
+# Backwards compatibility
+# Define camel case versions of input variables
+foreach(UPPER
+ PROTOBUF_SRC_ROOT_FOLDER
+ PROTOBUF_IMPORT_DIRS
+ PROTOBUF_DEBUG
+ PROTOBUF_LIBRARY
+ PROTOBUF_PROTOC_LIBRARY
+ PROTOBUF_INCLUDE_DIR
+ PROTOBUF_PROTOC_EXECUTABLE
+ PROTOBUF_LIBRARY_DEBUG
+ PROTOBUF_PROTOC_LIBRARY_DEBUG
+ PROTOBUF_LITE_LIBRARY
+ PROTOBUF_LITE_LIBRARY_DEBUG
+ )
+ if (DEFINED ${UPPER})
+ string(REPLACE "PROTOBUF_" "Protobuf_" Camel ${UPPER})
+ if (NOT DEFINED ${Camel})
+ set(${Camel} ${${UPPER}})
+ endif()
+ endif()
+endforeach()
+
+if(DEFINED Protobuf_SRC_ROOT_FOLDER)
+ message(AUTHOR_WARNING "Variable Protobuf_SRC_ROOT_FOLDER defined, but not"
+ " used in CONFIG mode")
+endif()
+
+include(SelectLibraryConfigurations)
+
# Internal function: search for normal library as well as a debug one
# if the debug one is specified also include debug/optimized keywords
# in *_LIBRARIES variable
function(_protobuf_find_libraries name filename)
- get_target_property(${name}_LIBRARY lib${filename}
- IMPORTED_LOCATION_RELEASE)
- set(${name}_LIBRARY "${${name}_LIBRARY}" PARENT_SCOPE)
- get_target_property(${name}_LIBRARY_DEBUG lib${filename}
- IMPORTED_LOCATION_DEBUG)
- set(${name}_LIBRARY_DEBUG "${${name}_LIBRARY_DEBUG}" PARENT_SCOPE)
-
- if(NOT ${name}_LIBRARY_DEBUG)
- # There is no debug library
- set(${name}_LIBRARY_DEBUG ${${name}_LIBRARY} PARENT_SCOPE)
- set(${name}_LIBRARIES ${${name}_LIBRARY} PARENT_SCOPE)
- else()
- # There IS a debug library
- set(${name}_LIBRARIES
- optimized ${${name}_LIBRARY}
- debug ${${name}_LIBRARY_DEBUG}
- PARENT_SCOPE
- )
- endif()
+ if(${name}_LIBRARIES)
+ # Use result recorded by a previous call.
+ elseif(${name}_LIBRARY)
+ # Honor cache entry used by CMake 3.5 and lower.
+ set(${name}_LIBRARIES "${${name}_LIBRARY}" PARENT_SCOPE)
+ else()
+ get_target_property(${name}_LIBRARY_RELEASE protobuf::lib${filename}
+ LOCATION_RELEASE)
+ get_target_property(${name}_LIBRARY_DEBUG protobuf::lib${filename}
+ LOCATION_DEBUG)
+
+ select_library_configurations(${name})
+ set(${name}_LIBRARY ${${name}_LIBRARY} PARENT_SCOPE)
+ set(${name}_LIBRARIES ${${name}_LIBRARIES} PARENT_SCOPE)
+ endif()
endfunction()
# Internal function: find threads library
@@ -107,33 +175,59 @@ if(NOT DEFINED PROTOBUF_GENERATE_CPP_APPEND_PATH)
endif()
# The Protobuf library
-_protobuf_find_libraries(PROTOBUF protobuf)
+_protobuf_find_libraries(Protobuf protobuf)
# The Protobuf Lite library
-_protobuf_find_libraries(PROTOBUF_LITE protobuf-lite)
+_protobuf_find_libraries(Protobuf_LITE protobuf-lite)
# The Protobuf Protoc Library
-_protobuf_find_libraries(PROTOBUF_PROTOC protoc)
+_protobuf_find_libraries(Protobuf_PROTOC protoc)
if(UNIX)
_protobuf_find_threads()
endif()
# Set the include directory
-set(PROTOBUF_INCLUDE_DIR "${_PROTOBUF_IMPORT_PREFIX}/@CMAKE_INSTALL_INCLUDEDIR@")
+get_target_property(Protobuf_INCLUDE_DIRS protobuf::libprotobuf
+ INTERFACE_INCLUDE_DIRECTORIES)
# Set the protoc Executable
-get_target_property(PROTOBUF_PROTOC_EXECUTABLE protoc
+get_target_property(Protobuf_PROTOC_EXECUTABLE protobuf::protoc
IMPORTED_LOCATION_RELEASE)
-if(NOT PROTOBUF_PROTOC_EXECUTABLE)
- get_target_property(PROTOBUF_PROTOC_EXECUTABLE protoc
+if(NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}")
+ get_target_property(Protobuf_PROTOC_EXECUTABLE protobuf::protoc
IMPORTED_LOCATION_DEBUG)
endif()
-include(FindPackageHandleStandardArgs)
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(PROTOBUF DEFAULT_MSG
- PROTOBUF_LIBRARY PROTOBUF_INCLUDE_DIR)
+# Version info variable
+set(Protobuf_VERSION "@protobuf_VERSION@")
-if(PROTOBUF_FOUND)
- set(PROTOBUF_INCLUDE_DIRS ${PROTOBUF_INCLUDE_DIR})
-endif()
+include(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(Protobuf
+ REQUIRED_VARS Protobuf_PROTOC_EXECUTABLE Protobuf_LIBRARIES Protobuf_INCLUDE_DIRS
+ VERSION_VAR Protobuf_VERSION
+)
+
+# Backwards compatibility
+# Define upper case versions of output variables
+foreach(Camel
+ Protobuf_VERSION
+ Protobuf_SRC_ROOT_FOLDER
+ Protobuf_IMPORT_DIRS
+ Protobuf_DEBUG
+ Protobuf_INCLUDE_DIRS
+ Protobuf_LIBRARIES
+ Protobuf_PROTOC_LIBRARIES
+ Protobuf_LITE_LIBRARIES
+ Protobuf_LIBRARY
+ Protobuf_PROTOC_LIBRARY
+ Protobuf_INCLUDE_DIR
+ Protobuf_PROTOC_EXECUTABLE
+ Protobuf_LIBRARY_DEBUG
+ Protobuf_PROTOC_LIBRARY_DEBUG
+ Protobuf_LITE_LIBRARY
+ Protobuf_LITE_LIBRARY_DEBUG
+ )
+ string(TOUPPER ${Camel} UPPER)
+ set(${UPPER} ${${Camel}})
+endforeach()
diff --git a/cmake/protobuf-options.cmake b/cmake/protobuf-options.cmake
new file mode 100644
index 00000000..47fb1582
--- /dev/null
+++ b/cmake/protobuf-options.cmake
@@ -0,0 +1,7 @@
+# Verbose output
+option(protobuf_VERBOSE "Enable for verbose output" OFF)
+mark_as_advanced(protobuf_VERBOSE)
+
+# FindProtobuf module compatibel
+option(protobuf_MODULE_COMPATIBLE "CMake build-in FindProtobuf.cmake module compatible" OFF)
+mark_as_advanced(protobuf_MODULE_COMPATIBLE)
diff --git a/cmake/tests.cmake b/cmake/tests.cmake
index 06d98860..ec0d6030 100644
--- a/cmake/tests.cmake
+++ b/cmake/tests.cmake
@@ -4,6 +4,7 @@ endif()
option(protobuf_ABSOLUTE_TEST_PLUGIN_PATH
"Using absolute test_plugin path in tests" ON)
+mark_as_advanced(protobuf_ABSOLUTE_TEST_PLUGIN_PATH)
include_directories(
${protobuf_source_dir}/gmock
@@ -52,6 +53,8 @@ set(tests_protos
google/protobuf/unittest_preserve_unknown_enum.proto
google/protobuf/unittest_preserve_unknown_enum2.proto
google/protobuf/unittest_proto3_arena.proto
+ google/protobuf/unittest_proto3_arena_lite.proto
+ google/protobuf/unittest_proto3_lite.proto
google/protobuf/unittest_well_known_types.proto
google/protobuf/util/internal/testdata/anys.proto
google/protobuf/util/internal/testdata/books.proto
@@ -63,6 +66,7 @@ set(tests_protos
google/protobuf/util/internal/testdata/struct.proto
google/protobuf/util/internal/testdata/timestamp_duration.proto
google/protobuf/util/json_format_proto3.proto
+ google/protobuf/util/message_differencer_unittest.proto
)
macro(compile_proto_file filename)
@@ -99,8 +103,6 @@ set(common_test_files
${protobuf_source_dir}/src/google/protobuf/test_util.cc
${protobuf_source_dir}/src/google/protobuf/testing/file.cc
${protobuf_source_dir}/src/google/protobuf/testing/googletest.cc
- ${protobuf_source_dir}/src/google/protobuf/compiler/mock_code_generator.cc
- ${protobuf_source_dir}/src/google/protobuf/util/internal/type_info_test_helper.cc
)
set(common_lite_test_files
@@ -117,10 +119,12 @@ set(tests_files
${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc
${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_unittest.cc
+ ${protobuf_source_dir}/src/google/protobuf/compiler/cpp/metadata_test.cc
${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_generator_unittest.cc
${protobuf_source_dir}/src/google/protobuf/compiler/importer_unittest.cc
${protobuf_source_dir}/src/google/protobuf/compiler/java/java_doc_comment_unittest.cc
${protobuf_source_dir}/src/google/protobuf/compiler/java/java_plugin_unittest.cc
+ ${protobuf_source_dir}/src/google/protobuf/compiler/mock_code_generator.cc
${protobuf_source_dir}/src/google/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc
${protobuf_source_dir}/src/google/protobuf/compiler/parser_unittest.cc
${protobuf_source_dir}/src/google/protobuf/compiler/python/python_plugin_unittest.cc
@@ -140,7 +144,9 @@ set(tests_files
${protobuf_source_dir}/src/google/protobuf/message_unittest.cc
${protobuf_source_dir}/src/google/protobuf/no_field_presence_test.cc
${protobuf_source_dir}/src/google/protobuf/preserve_unknown_enum_test.cc
+ ${protobuf_source_dir}/src/google/protobuf/proto3_arena_lite_unittest.cc
${protobuf_source_dir}/src/google/protobuf/proto3_arena_unittest.cc
+ ${protobuf_source_dir}/src/google/protobuf/proto3_lite_unittest.cc
${protobuf_source_dir}/src/google/protobuf/reflection_ops_unittest.cc
${protobuf_source_dir}/src/google/protobuf/repeated_field_reflection_unittest.cc
${protobuf_source_dir}/src/google/protobuf/repeated_field_unittest.cc
@@ -166,7 +172,9 @@ set(tests_files
${protobuf_source_dir}/src/google/protobuf/util/internal/json_stream_parser_test.cc
${protobuf_source_dir}/src/google/protobuf/util/internal/protostream_objectsource_test.cc
${protobuf_source_dir}/src/google/protobuf/util/internal/protostream_objectwriter_test.cc
+ ${protobuf_source_dir}/src/google/protobuf/util/internal/type_info_test_helper.cc
${protobuf_source_dir}/src/google/protobuf/util/json_util_test.cc
+ ${protobuf_source_dir}/src/google/protobuf/util/message_differencer_unittest.cc
${protobuf_source_dir}/src/google/protobuf/util/time_util_test.cc
${protobuf_source_dir}/src/google/protobuf/util/type_resolver_util_test.cc
${protobuf_source_dir}/src/google/protobuf/well_known_types_unittest.cc
diff --git a/configure.ac b/configure.ac
index 42605ae3..41887997 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4,15 +4,20 @@
AC_PREREQ(2.59)
# Note: If you change the version, you must also update it in:
-# * java/pom.xml
-# * python/setup.py
+# * Protobuf.podspec
+# * csharp/Google.Protobuf.Tools.nuspec
+# * csharp/src/*/AssemblyInfo.cs
+# * csharp/src/Google.Protobuf/Google.Protobuf.nuspec
+# * java/*/pom.xml
+# * python/google/protobuf/__init__.py
+# * protoc-artifacts/pom.xml
# * src/google/protobuf/stubs/common.h
# * src/Makefile.am (Update -version-info for LDFLAGS if needed)
#
# In the SVN trunk, the version should always be the next anticipated release
# version with the "-pre" suffix. (We used to use "-SNAPSHOT" but this pushed
# the size of one file name in the dist tarfile over the 99-char limit.)
-AC_INIT([Protocol Buffers],[3.0.0-beta-1],[protobuf@googlegroups.com],[protobuf])
+AC_INIT([Protocol Buffers],[3.0.0],[protobuf@googlegroups.com],[protobuf])
AM_MAINTAINER_MODE([enable])
@@ -26,7 +31,7 @@ AC_CONFIG_MACRO_DIR([m4])
AC_ARG_VAR(DIST_LANG, [language to include in the distribution package (i.e., make dist)])
case "$DIST_LANG" in
"") DIST_LANG=all ;;
- all | cpp | csharp | java | python | javanano | objectivec | ruby) ;;
+ all | cpp | csharp | java | python | javanano | objectivec | ruby | js) ;;
*) AC_MSG_FAILURE([unknown language: $DIST_LANG]) ;;
esac
AC_SUBST(DIST_LANG)
@@ -180,5 +185,5 @@ export CFLAGS
export CXXFLAGS
AC_CONFIG_SUBDIRS([gmock])
-AC_CONFIG_FILES([Makefile src/Makefile conformance/Makefile protobuf.pc protobuf-lite.pc])
+AC_CONFIG_FILES([Makefile src/Makefile benchmarks/Makefile conformance/Makefile protobuf.pc protobuf-lite.pc])
AC_OUTPUT
diff --git a/conformance/ConformanceJava.java b/conformance/ConformanceJava.java
index 25646b85..43787ffc 100644
--- a/conformance/ConformanceJava.java
+++ b/conformance/ConformanceJava.java
@@ -1,9 +1,12 @@
import com.google.protobuf.conformance.Conformance;
+import com.google.protobuf.util.JsonFormat;
+import com.google.protobuf.util.JsonFormat.TypeRegistry;
import com.google.protobuf.InvalidProtocolBufferException;
class ConformanceJava {
private int testCount = 0;
+ private TypeRegistry typeRegistry;
private boolean readFromStdin(byte[] buf, int len) throws Exception {
int ofs = 0;
@@ -29,7 +32,10 @@ class ConformanceJava {
if (!readFromStdin(buf, 4)) {
return -1;
}
- return buf[0] | (buf[1] << 1) | (buf[2] << 2) | (buf[3] << 3);
+ return (buf[0] & 0xff)
+ | ((buf[1] & 0xff) << 8)
+ | ((buf[2] & 0xff) << 16)
+ | ((buf[3] & 0xff) << 24);
}
private void writeLittleEndianIntToStdout(int val) throws Exception {
@@ -54,7 +60,15 @@ class ConformanceJava {
break;
}
case JSON_PAYLOAD: {
- return Conformance.ConformanceResponse.newBuilder().setSkipped("JSON not yet supported.").build();
+ try {
+ Conformance.TestAllTypes.Builder builder = Conformance.TestAllTypes.newBuilder();
+ JsonFormat.parser().usingTypeRegistry(typeRegistry)
+ .merge(request.getJsonPayload(), builder);
+ testMessage = builder.build();
+ } catch (InvalidProtocolBufferException e) {
+ return Conformance.ConformanceResponse.newBuilder().setParseError(e.getMessage()).build();
+ }
+ break;
}
case PAYLOAD_NOT_SET: {
throw new RuntimeException("Request didn't have payload.");
@@ -73,7 +87,13 @@ class ConformanceJava {
return Conformance.ConformanceResponse.newBuilder().setProtobufPayload(testMessage.toByteString()).build();
case JSON:
- return Conformance.ConformanceResponse.newBuilder().setSkipped("JSON not yet supported.").build();
+ try {
+ return Conformance.ConformanceResponse.newBuilder().setJsonPayload(
+ JsonFormat.printer().usingTypeRegistry(typeRegistry).print(testMessage)).build();
+ } catch (InvalidProtocolBufferException | IllegalArgumentException e) {
+ return Conformance.ConformanceResponse.newBuilder().setSerializeError(
+ e.getMessage()).build();
+ }
default: {
throw new RuntimeException("Unexpected request output.");
@@ -106,8 +126,10 @@ class ConformanceJava {
}
public void run() throws Exception {
+ typeRegistry = TypeRegistry.newBuilder().add(
+ Conformance.TestAllTypes.getDescriptor()).build();
while (doTestIo()) {
- // Empty.
+ this.testCount++;
}
System.err.println("ConformanceJava: received EOF from test runner after " +
diff --git a/conformance/ConformanceJavaLite.java b/conformance/ConformanceJavaLite.java
new file mode 100644
index 00000000..016f7932
--- /dev/null
+++ b/conformance/ConformanceJavaLite.java
@@ -0,0 +1,125 @@
+
+import com.google.protobuf.conformance.Conformance;
+import com.google.protobuf.InvalidProtocolBufferException;
+
+class ConformanceJavaLite {
+ private int testCount = 0;
+
+ private boolean readFromStdin(byte[] buf, int len) throws Exception {
+ int ofs = 0;
+ while (len > 0) {
+ int read = System.in.read(buf, ofs, len);
+ if (read == -1) {
+ return false; // EOF
+ }
+ ofs += read;
+ len -= read;
+ }
+
+ return true;
+ }
+
+ private void writeToStdout(byte[] buf) throws Exception {
+ System.out.write(buf);
+ }
+
+ // Returns -1 on EOF (the actual values will always be positive).
+ private int readLittleEndianIntFromStdin() throws Exception {
+ byte[] buf = new byte[4];
+ if (!readFromStdin(buf, 4)) {
+ return -1;
+ }
+ return (buf[0] & 0xff)
+ | ((buf[1] & 0xff) << 8)
+ | ((buf[2] & 0xff) << 16)
+ | ((buf[3] & 0xff) << 24);
+ }
+
+ private void writeLittleEndianIntToStdout(int val) throws Exception {
+ byte[] buf = new byte[4];
+ buf[0] = (byte)val;
+ buf[1] = (byte)(val >> 8);
+ buf[2] = (byte)(val >> 16);
+ buf[3] = (byte)(val >> 24);
+ writeToStdout(buf);
+ }
+
+ private Conformance.ConformanceResponse doTest(Conformance.ConformanceRequest request) {
+ Conformance.TestAllTypes testMessage;
+
+ switch (request.getPayloadCase()) {
+ case PROTOBUF_PAYLOAD: {
+ try {
+ testMessage = Conformance.TestAllTypes.parseFrom(request.getProtobufPayload());
+ } catch (InvalidProtocolBufferException e) {
+ return Conformance.ConformanceResponse.newBuilder().setParseError(e.getMessage()).build();
+ }
+ break;
+ }
+ case JSON_PAYLOAD: {
+ return Conformance.ConformanceResponse.newBuilder().setSkipped(
+ "Lite runtime does not support JSON format.").build();
+ }
+ case PAYLOAD_NOT_SET: {
+ throw new RuntimeException("Request didn't have payload.");
+ }
+
+ default: {
+ throw new RuntimeException("Unexpected payload case.");
+ }
+ }
+
+ switch (request.getRequestedOutputFormat()) {
+ case UNSPECIFIED:
+ throw new RuntimeException("Unspecified output format.");
+
+ case PROTOBUF:
+ return Conformance.ConformanceResponse.newBuilder().setProtobufPayload(testMessage.toByteString()).build();
+
+ case JSON:
+ return Conformance.ConformanceResponse.newBuilder().setSkipped(
+ "Lite runtime does not support JSON format.").build();
+
+ default: {
+ throw new RuntimeException("Unexpected request output.");
+ }
+ }
+ }
+
+ private boolean doTestIo() throws Exception {
+ int bytes = readLittleEndianIntFromStdin();
+
+ if (bytes == -1) {
+ return false; // EOF
+ }
+
+ byte[] serializedInput = new byte[bytes];
+
+ if (!readFromStdin(serializedInput, bytes)) {
+ throw new RuntimeException("Unexpected EOF from test program.");
+ }
+
+ Conformance.ConformanceRequest request =
+ Conformance.ConformanceRequest.parseFrom(serializedInput);
+ Conformance.ConformanceResponse response = doTest(request);
+ byte[] serializedOutput = response.toByteArray();
+
+ writeLittleEndianIntToStdout(serializedOutput.length);
+ writeToStdout(serializedOutput);
+
+ return true;
+ }
+
+ public void run() throws Exception {
+ while (doTestIo()) {
+ this.testCount++;
+ }
+
+ System.err.println("ConformanceJavaLite: received EOF from test runner after " +
+ this.testCount + " tests");
+ }
+
+ public static void main(String[] args) throws Exception {
+ new ConformanceJavaLite().run();
+ }
+}
diff --git a/conformance/Makefile.am b/conformance/Makefile.am
index 1c022270..b76407ee 100644
--- a/conformance/Makefile.am
+++ b/conformance/Makefile.am
@@ -1,25 +1,160 @@
## Process this file with automake to produce Makefile.in
-protoc_inputs = \
+conformance_protoc_inputs = \
conformance.proto
+well_known_type_protoc_inputs = \
+ $(top_srcdir)/src/google/protobuf/any.proto \
+ $(top_srcdir)/src/google/protobuf/duration.proto \
+ $(top_srcdir)/src/google/protobuf/field_mask.proto \
+ $(top_srcdir)/src/google/protobuf/struct.proto \
+ $(top_srcdir)/src/google/protobuf/timestamp.proto \
+ $(top_srcdir)/src/google/protobuf/wrappers.proto
+
+
protoc_outputs = \
conformance.pb.cc \
conformance.pb.h
other_language_protoc_outputs = \
- conformance.rb \
- com/google/protobuf/conformance/Conformance.java \
conformance_pb2.py \
Conformance.pbobjc.h \
- Conformance.pbobjc.m
+ Conformance.pbobjc.m \
+ conformance.rb \
+ com/google/protobuf/Any.java \
+ com/google/protobuf/AnyOrBuilder.java \
+ com/google/protobuf/AnyProto.java \
+ com/google/protobuf/BoolValue.java \
+ com/google/protobuf/BoolValueOrBuilder.java \
+ com/google/protobuf/BytesValue.java \
+ com/google/protobuf/BytesValueOrBuilder.java \
+ com/google/protobuf/conformance/Conformance.java \
+ com/google/protobuf/DoubleValue.java \
+ com/google/protobuf/DoubleValueOrBuilder.java \
+ com/google/protobuf/Duration.java \
+ com/google/protobuf/DurationOrBuilder.java \
+ com/google/protobuf/DurationProto.java \
+ com/google/protobuf/FieldMask.java \
+ com/google/protobuf/FieldMaskOrBuilder.java \
+ com/google/protobuf/FieldMaskProto.java \
+ com/google/protobuf/FloatValue.java \
+ com/google/protobuf/FloatValueOrBuilder.java \
+ com/google/protobuf/Int32Value.java \
+ com/google/protobuf/Int32ValueOrBuilder.java \
+ com/google/protobuf/Int64Value.java \
+ com/google/protobuf/Int64ValueOrBuilder.java \
+ com/google/protobuf/ListValue.java \
+ com/google/protobuf/ListValueOrBuilder.java \
+ com/google/protobuf/NullValue.java \
+ com/google/protobuf/StringValue.java \
+ com/google/protobuf/StringValueOrBuilder.java \
+ com/google/protobuf/Struct.java \
+ com/google/protobuf/StructOrBuilder.java \
+ com/google/protobuf/StructProto.java \
+ com/google/protobuf/Timestamp.java \
+ com/google/protobuf/TimestampOrBuilder.java \
+ com/google/protobuf/TimestampProto.java \
+ com/google/protobuf/UInt32Value.java \
+ com/google/protobuf/UInt32ValueOrBuilder.java \
+ com/google/protobuf/UInt64Value.java \
+ com/google/protobuf/UInt64ValueOrBuilder.java \
+ com/google/protobuf/Value.java \
+ com/google/protobuf/ValueOrBuilder.java \
+ com/google/protobuf/WrappersProto.java \
+ google/protobuf/any.pb.cc \
+ google/protobuf/any.pb.h \
+ google/protobuf/any.rb \
+ google/protobuf/any_pb2.py \
+ google/protobuf/duration.pb.cc \
+ google/protobuf/duration.pb.h \
+ google/protobuf/duration.rb \
+ google/protobuf/duration_pb2.py \
+ google/protobuf/field_mask.pb.cc \
+ google/protobuf/field_mask.pb.h \
+ google/protobuf/field_mask.rb \
+ google/protobuf/field_mask_pb2.py \
+ google/protobuf/struct.pb.cc \
+ google/protobuf/struct.pb.h \
+ google/protobuf/struct.rb \
+ google/protobuf/struct_pb2.py \
+ google/protobuf/timestamp.pb.cc \
+ google/protobuf/timestamp.pb.h \
+ google/protobuf/timestamp.rb \
+ google/protobuf/timestamp_pb2.py \
+ google/protobuf/wrappers.pb.cc \
+ google/protobuf/wrappers.pb.h \
+ google/protobuf/wrappers.rb \
+ google/protobuf/wrappers_pb2.py
+ # lite/com/google/protobuf/Any.java \
+ # lite/com/google/protobuf/AnyOrBuilder.java \
+ # lite/com/google/protobuf/AnyProto.java \
+ # lite/com/google/protobuf/BoolValue.java \
+ # lite/com/google/protobuf/BoolValueOrBuilder.java \
+ # lite/com/google/protobuf/BytesValue.java \
+ # lite/com/google/protobuf/BytesValueOrBuilder.java \
+ # lite/com/google/protobuf/conformance/Conformance.java \
+ # lite/com/google/protobuf/DoubleValue.java \
+ # lite/com/google/protobuf/DoubleValueOrBuilder.java \
+ # lite/com/google/protobuf/Duration.java \
+ # lite/com/google/protobuf/DurationOrBuilder.java \
+ # lite/com/google/protobuf/DurationProto.java \
+ # lite/com/google/protobuf/FieldMask.java \
+ # lite/com/google/protobuf/FieldMaskOrBuilder.java \
+ # lite/com/google/protobuf/FieldMaskProto.java \
+ # lite/com/google/protobuf/FloatValue.java \
+ # lite/com/google/protobuf/FloatValueOrBuilder.java \
+ # lite/com/google/protobuf/Int32Value.java \
+ # lite/com/google/protobuf/Int32ValueOrBuilder.java \
+ # lite/com/google/protobuf/Int64Value.java \
+ # lite/com/google/protobuf/Int64ValueOrBuilder.java \
+ # lite/com/google/protobuf/ListValue.java \
+ # lite/com/google/protobuf/ListValueOrBuilder.java \
+ # lite/com/google/protobuf/NullValue.java \
+ # lite/com/google/protobuf/StringValue.java \
+ # lite/com/google/protobuf/StringValueOrBuilder.java \
+ # lite/com/google/protobuf/Struct.java \
+ # lite/com/google/protobuf/StructOrBuilder.java \
+ # lite/com/google/protobuf/StructProto.java \
+ # lite/com/google/protobuf/Timestamp.java \
+ # lite/com/google/protobuf/TimestampOrBuilder.java \
+ # lite/com/google/protobuf/TimestampProto.java \
+ # lite/com/google/protobuf/UInt32Value.java \
+ # lite/com/google/protobuf/UInt32ValueOrBuilder.java \
+ # lite/com/google/protobuf/UInt64Value.java \
+ # lite/com/google/protobuf/UInt64ValueOrBuilder.java \
+ # lite/com/google/protobuf/Value.java \
+ # lite/com/google/protobuf/ValueOrBuilder.java \
+ # lite/com/google/protobuf/WrappersProto.java
bin_PROGRAMS = conformance-test-runner conformance-cpp
+# All source files excepet C++/Objective-C ones should be explicitly listed
+# here because the autoconf tools don't include files of other languages
+# automatically.
+EXTRA_DIST = \
+ ConformanceJava.java \
+ ConformanceJavaLite.java \
+ README.md \
+ conformance.proto \
+ conformance_python.py \
+ conformance_ruby.rb \
+ failure_list_cpp.txt \
+ failure_list_csharp.txt \
+ failure_list_java.txt \
+ failure_list_objc.txt \
+ failure_list_python.txt \
+ failure_list_python_cpp.txt \
+ failure_list_python-post26.txt \
+ failure_list_ruby.txt
+
conformance_test_runner_LDADD = $(top_srcdir)/src/libprotobuf.la
-conformance_test_runner_SOURCES = conformance_test.cc conformance_test_runner.cc
+conformance_test_runner_SOURCES = conformance_test.h conformance_test.cc \
+ conformance_test_runner.cc \
+ third_party/jsoncpp/json.h \
+ third_party/jsoncpp/jsoncpp.cpp
nodist_conformance_test_runner_SOURCES = conformance.pb.cc
-conformance_test_runner_CPPFLAGS = -I$(top_srcdir)/src
+conformance_test_runner_CPPFLAGS = -I$(top_srcdir)/src -I$(srcdir)
+conformance_test_runner_CXXFLAGS = -std=c++11
# Explicit deps beacuse BUILT_SOURCES are only done before a "make all/check"
# so a direct "make test_cpp" could fail if parallel enough.
conformance_test_runner-conformance_test.$(OBJEXT): conformance.pb.h
@@ -53,8 +188,11 @@ endif
if USE_EXTERNAL_PROTOC
-protoc_middleman: $(protoc_inputs)
- $(PROTOC) -I$(srcdir) --cpp_out=. --java_out=. --ruby_out=. --objc_out=. --python_out=.$^
+# Some implementations include pre-generated versions of well-known types.
+protoc_middleman: $(conformance_protoc_inputs) $(well_known_type_protoc_inputs)
+ $(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. --java_out=. --ruby_out=. --objc_out=. --python_out=. $(conformance_protoc_inputs)
+ $(PROTOC) -I$(srcdir) -I$(top_srcdir) --cpp_out=. --java_out=. --ruby_out=. --python_out=. $(well_known_type_protoc_inputs)
+ ## $(PROTOC) -I$(srcdir) -I$(top_srcdir) --java_out=lite:lite $(conformance_protoc_inputs) $(well_known_type_protoc_inputs)
touch protoc_middleman
else
@@ -62,8 +200,11 @@ else
# We have to cd to $(srcdir) before executing protoc because $(protoc_inputs) is
# relative to srcdir, which may not be the same as the current directory when
# building out-of-tree.
-protoc_middleman: $(top_srcdir)/src/protoc$(EXEEXT) $(protoc_inputs)
- oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. --cpp_out=$$oldpwd --java_out=$$oldpwd --ruby_out=$$oldpwd --objc_out=$$oldpwd --python_out=$$oldpwd $(protoc_inputs) )
+protoc_middleman: $(top_srcdir)/src/protoc$(EXEEXT) $(conformance_protoc_inputs) $(well_known_type_protoc_inputs)
+ oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd --java_out=$$oldpwd --ruby_out=$$oldpwd --objc_out=$$oldpwd --python_out=$$oldpwd $(conformance_protoc_inputs) )
+ oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --cpp_out=$$oldpwd --java_out=$$oldpwd --ruby_out=$$oldpwd --python_out=$$oldpwd $(well_known_type_protoc_inputs) )
+ ## @mkdir -p lite
+ ## oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. -I$(top_srcdir)/src --java_out=lite:$$oldpwd/lite $(conformance_protoc_inputs) $(well_known_type_protoc_inputs) )
touch protoc_middleman
endif
@@ -74,28 +215,38 @@ $(other_language_protoc_outputs): protoc_middleman
BUILT_SOURCES = $(protoc_outputs) $(other_language_protoc_outputs)
-CLEANFILES = $(protoc_outputs) protoc_middleman javac_middleman conformance-java conformance-csharp $(other_language_protoc_outputs)
+CLEANFILES = $(protoc_outputs) protoc_middleman javac_middleman conformance-java javac_middleman_lite conformance-java-lite conformance-csharp $(other_language_protoc_outputs)
MAINTAINERCLEANFILES = \
Makefile.in
javac_middleman: ConformanceJava.java protoc_middleman $(other_language_protoc_outputs)
- javac -classpath ../java/target/classes ConformanceJava.java com/google/protobuf/conformance/Conformance.java
+ jar=`ls ../java/util/target/*jar-with-dependencies.jar` && javac -classpath ../java/target/classes:$$jar ConformanceJava.java com/google/protobuf/conformance/Conformance.java
@touch javac_middleman
conformance-java: javac_middleman
@echo "Writing shortcut script conformance-java..."
@echo '#! /bin/sh' > conformance-java
- @echo 'java -classpath .:../java/target/classes ConformanceJava "$$@"' >> conformance-java
+ @jar=`ls ../java/util/target/*jar-with-dependencies.jar` && echo java -classpath .:../java/target/classes:$$jar ConformanceJava '$$@' >> conformance-java
@chmod +x conformance-java
+javac_middleman_lite: ConformanceJavaLite.java protoc_middleman $(other_language_protoc_outputs)
+ javac -classpath ../java/lite/target/classes:lite ConformanceJavaLite.java lite/com/google/protobuf/conformance/Conformance.java
+ @touch javac_middleman_lite
+
+conformance-java-lite: javac_middleman_lite
+ @echo "Writing shortcut script conformance-java-lite..."
+ @echo '#! /bin/sh' > conformance-java-lite
+ @echo java -classpath .:../java/lite/target/classes:lite ConformanceJavaLite '$$@' >> conformance-java-lite
+ @chmod +x conformance-java-lite
+
# Currently the conformance code is alongside the rest of the C#
# source, as it's easier to maintain there. We assume we've already
# built that, so we just need a script to run it.
conformance-csharp: $(other_language_protoc_outputs)
@echo "Writing shortcut script conformance-csharp..."
@echo '#! /bin/sh' > conformance-csharp
- @echo 'mono ../csharp/src/Google.Protobuf.Conformance/bin/Release/Google.Protobuf.Conformance.exe "$$@"' >> conformance-csharp
+ @echo 'dotnet ../csharp/src/Google.Protobuf.Conformance/bin/Release/netcoreapp1.0/Google.Protobuf.Conformance.dll "$$@"' >> conformance-csharp
@chmod +x conformance-csharp
# Targets for actually running tests.
@@ -103,7 +254,10 @@ test_cpp: protoc_middleman conformance-test-runner conformance-cpp
./conformance-test-runner --failure_list failure_list_cpp.txt ./conformance-cpp
test_java: protoc_middleman conformance-test-runner conformance-java
- ./conformance-test-runner ./conformance-java
+ ./conformance-test-runner --failure_list failure_list_java.txt ./conformance-java
+
+test_java_lite: protoc_middleman conformance-test-runner conformance-java-lite
+ ./conformance-test-runner ./conformance-java-lite
test_csharp: protoc_middleman conformance-test-runner conformance-csharp
./conformance-test-runner --failure_list failure_list_csharp.txt ./conformance-csharp
diff --git a/conformance/conformance.proto b/conformance/conformance.proto
index 714cbe78..fc96074a 100644
--- a/conformance/conformance.proto
+++ b/conformance/conformance.proto
@@ -32,6 +32,13 @@ syntax = "proto3";
package conformance;
option java_package = "com.google.protobuf.conformance";
+import "google/protobuf/any.proto";
+import "google/protobuf/duration.proto";
+import "google/protobuf/field_mask.proto";
+import "google/protobuf/struct.proto";
+import "google/protobuf/timestamp.proto";
+import "google/protobuf/wrappers.proto";
+
// This defines the conformance testing protocol. This protocol exists between
// the conformance test suite itself and the code being tested. For each test,
// the suite will send a ConformanceRequest message and expect a
@@ -84,6 +91,11 @@ message ConformanceResponse {
// test. Some of the test cases are intentionally invalid input.
string parse_error = 1;
+ // If the input was successfully parsed but errors occurred when
+ // serializing it to the requested output format, set the error message in
+ // this field.
+ string serialize_error = 6;
+
// This should be set if some other error occurred. This will always
// indicate that the test failed. The string can provide more information
// about the failure.
@@ -199,6 +211,55 @@ message TestAllTypes {
string oneof_string = 113;
bytes oneof_bytes = 114;
}
+
+ // Well-known types
+ google.protobuf.BoolValue optional_bool_wrapper = 201;
+ google.protobuf.Int32Value optional_int32_wrapper = 202;
+ google.protobuf.Int64Value optional_int64_wrapper = 203;
+ google.protobuf.UInt32Value optional_uint32_wrapper = 204;
+ google.protobuf.UInt64Value optional_uint64_wrapper = 205;
+ google.protobuf.FloatValue optional_float_wrapper = 206;
+ google.protobuf.DoubleValue optional_double_wrapper = 207;
+ google.protobuf.StringValue optional_string_wrapper = 208;
+ google.protobuf.BytesValue optional_bytes_wrapper = 209;
+
+ repeated google.protobuf.BoolValue repeated_bool_wrapper = 211;
+ repeated google.protobuf.Int32Value repeated_int32_wrapper = 212;
+ repeated google.protobuf.Int64Value repeated_int64_wrapper = 213;
+ repeated google.protobuf.UInt32Value repeated_uint32_wrapper = 214;
+ repeated google.protobuf.UInt64Value repeated_uint64_wrapper = 215;
+ repeated google.protobuf.FloatValue repeated_float_wrapper = 216;
+ repeated google.protobuf.DoubleValue repeated_double_wrapper = 217;
+ repeated google.protobuf.StringValue repeated_string_wrapper = 218;
+ repeated google.protobuf.BytesValue repeated_bytes_wrapper = 219;
+
+ google.protobuf.Duration optional_duration = 301;
+ google.protobuf.Timestamp optional_timestamp = 302;
+ google.protobuf.FieldMask optional_field_mask = 303;
+ google.protobuf.Struct optional_struct = 304;
+ google.protobuf.Any optional_any = 305;
+ google.protobuf.Value optional_value = 306;
+
+ repeated google.protobuf.Duration repeated_duration = 311;
+ repeated google.protobuf.Timestamp repeated_timestamp = 312;
+ repeated google.protobuf.FieldMask repeated_fieldmask = 313;
+ repeated google.protobuf.Struct repeated_struct = 324;
+ repeated google.protobuf.Any repeated_any = 315;
+ repeated google.protobuf.Value repeated_value = 316;
+
+ // Test field-name-to-JSON-name convention.
+ int32 fieldname1 = 401;
+ int32 field_name2 = 402;
+ int32 _field_name3 = 403;
+ int32 field__name4_ = 404;
+ int32 field0name5 = 405;
+ int32 field_0_name6 = 406;
+ int32 fieldName7 = 407;
+ int32 FieldName8 = 408;
+ int32 field_Name9 = 409;
+ int32 Field_Name10 = 410;
+ int32 FIELD_NAME11 = 411;
+ int32 FIELD_name12 = 412;
}
message ForeignMessage {
diff --git a/conformance/conformance_cpp.cc b/conformance/conformance_cpp.cc
index 863b6a5b..1a265493 100644
--- a/conformance/conformance_cpp.cc
+++ b/conformance/conformance_cpp.cc
@@ -108,7 +108,11 @@ void DoTest(const ConformanceRequest& request, ConformanceResponse* response) {
return;
}
- GOOGLE_CHECK(test_message.ParseFromString(proto_binary));
+ if (!test_message.ParseFromString(proto_binary)) {
+ response->set_runtime_error(
+ "Parsing JSON generates invalid proto output.");
+ return;
+ }
break;
}
@@ -132,9 +136,18 @@ void DoTest(const ConformanceRequest& request, ConformanceResponse* response) {
GOOGLE_CHECK(test_message.SerializeToString(&proto_binary));
Status status = BinaryToJsonString(type_resolver, *type_url, proto_binary,
response->mutable_json_payload());
- GOOGLE_CHECK(status.ok());
+ if (!status.ok()) {
+ response->set_serialize_error(
+ string("Failed to serialize JSON output: ") +
+ status.error_message().as_string());
+ return;
+ }
break;
}
+
+ default:
+ GOOGLE_LOG(FATAL) << "Unknown output format: "
+ << request.requested_output_format();
}
}
diff --git a/conformance/conformance_objc.m b/conformance/conformance_objc.m
index 06c97a82..1124bfeb 100644
--- a/conformance/conformance_objc.m
+++ b/conformance/conformance_objc.m
@@ -95,7 +95,7 @@ static ConformanceResponse *DoTest(ConformanceRequest *request) {
case WireFormat_Protobuf:
response.protobufPayload = testMessage.data;
if (!response.protobufPayload) {
- response.runtimeError =
+ response.serializeError =
[NSString stringWithFormat:@"Failed to make data from: %@", testMessage];
}
break;
diff --git a/conformance/conformance_ruby.rb b/conformance/conformance_ruby.rb
index cd065673..aa572144 100755
--- a/conformance/conformance_ruby.rb
+++ b/conformance/conformance_ruby.rb
@@ -30,7 +30,7 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-require 'conformance'
+require 'conformance_pb'
$test_count = 0
$verbose = false
@@ -51,7 +51,12 @@ def do_test(request)
end
when :json_payload
- test_message = Conformance::TestAllTypes.decode_json(request.json_payload)
+ begin
+ test_message = Conformance::TestAllTypes.decode_json(request.json_payload)
+ rescue Google::Protobuf::ParseError => err
+ response.parse_error = err.message.encode('utf-8')
+ return response
+ end
when nil
fail "Request didn't have payload"
@@ -66,6 +71,9 @@ def do_test(request)
when :JSON
response.json_payload = test_message.to_json
+
+ when nil
+ fail "Request didn't have requested output format"
end
rescue StandardError => err
response.runtime_error = err.message.encode('utf-8')
@@ -96,8 +104,8 @@ def do_test_io
STDOUT.flush
if $verbose
- STDERR.puts("conformance-cpp: request={request.to_json}, " \
- "response={response.to_json}\n")
+ STDERR.puts("conformance_ruby: request=#{request.to_json}, " \
+ "response=#{response.to_json}\n")
end
$test_count += 1
@@ -107,7 +115,7 @@ end
loop do
unless do_test_io
- STDERR.puts('conformance-cpp: received EOF from test runner ' \
+ STDERR.puts('conformance_ruby: received EOF from test runner ' \
"after #{$test_count} tests, exiting")
break
end
diff --git a/conformance/conformance_test.cc b/conformance/conformance_test.cc
index c250cb1e..598ef732 100644
--- a/conformance/conformance_test.cc
+++ b/conformance/conformance_test.cc
@@ -30,6 +30,7 @@
#include <stdarg.h>
#include <string>
+#include <fstream>
#include "conformance.pb.h"
#include "conformance_test.h"
@@ -37,10 +38,13 @@
#include <google/protobuf/stubs/stringprintf.h>
#include <google/protobuf/text_format.h>
#include <google/protobuf/util/json_util.h>
+#include <google/protobuf/util/field_comparator.h>
#include <google/protobuf/util/message_differencer.h>
#include <google/protobuf/util/type_resolver_util.h>
#include <google/protobuf/wire_format_lite.h>
+#include "third_party/jsoncpp/json.h"
+
using conformance::ConformanceRequest;
using conformance::ConformanceResponse;
using conformance::TestAllTypes;
@@ -49,6 +53,7 @@ using google::protobuf::Descriptor;
using google::protobuf::FieldDescriptor;
using google::protobuf::internal::WireFormatLite;
using google::protobuf::TextFormat;
+using google::protobuf::util::DefaultFieldComparator;
using google::protobuf::util::JsonToBinaryString;
using google::protobuf::util::MessageDifferencer;
using google::protobuf::util::NewTypeResolverForDescriptorPool;
@@ -220,7 +225,7 @@ void ConformanceTestSuite::RunTest(const string& test_name,
string serialized_response;
request.SerializeToString(&serialized_request);
- runner_->RunTest(serialized_request, &serialized_response);
+ runner_->RunTest(test_name, serialized_request, &serialized_response);
if (!response->ParseFromString(serialized_response)) {
response->Clear();
@@ -240,7 +245,9 @@ void ConformanceTestSuite::RunValidInputTest(
const string& equivalent_text_format, WireFormat requested_output) {
TestAllTypes reference_message;
GOOGLE_CHECK(
- TextFormat::ParseFromString(equivalent_text_format, &reference_message));
+ TextFormat::ParseFromString(equivalent_text_format, &reference_message))
+ << "Failed to parse data for test case: " << test_name
+ << ", data: " << equivalent_text_format;
ConformanceRequest request;
ConformanceResponse response;
@@ -254,9 +261,8 @@ void ConformanceTestSuite::RunValidInputTest(
request.set_json_payload(input);
break;
- case conformance::UNSPECIFIED:
+ default:
GOOGLE_LOG(FATAL) << "Unspecified input format";
-
}
request.set_requested_output_format(requested_output);
@@ -268,8 +274,9 @@ void ConformanceTestSuite::RunValidInputTest(
switch (response.result_case()) {
case ConformanceResponse::kParseError:
case ConformanceResponse::kRuntimeError:
+ case ConformanceResponse::kSerializeError:
ReportFailure(test_name, request, response,
- "Failed to parse valid JSON input.");
+ "Failed to parse JSON input or produce JSON output.");
return;
case ConformanceResponse::kSkipped:
@@ -293,7 +300,13 @@ void ConformanceTestSuite::RunValidInputTest(
return;
}
- GOOGLE_CHECK(test_message.ParseFromString(binary_protobuf));
+ if (!test_message.ParseFromString(binary_protobuf)) {
+ ReportFailure(test_name, request, response,
+ "INTERNAL ERROR: internal JSON->protobuf transcode "
+ "yielded unparseable proto.");
+ return;
+ }
+
break;
}
@@ -313,13 +326,20 @@ void ConformanceTestSuite::RunValidInputTest(
break;
}
+
+ default:
+ GOOGLE_LOG(FATAL) << test_name << ": unknown payload type: "
+ << response.result_case();
}
MessageDifferencer differencer;
+ DefaultFieldComparator field_comparator;
+ field_comparator.set_treat_nan_as_equal(true);
+ differencer.set_field_comparator(&field_comparator);
string differences;
differencer.ReportDifferencesToString(&differences);
- if (differencer.Equals(reference_message, test_message)) {
+ if (differencer.Compare(reference_message, test_message)) {
ReportSuccess(test_name);
} else {
ReportFailure(test_name, request, response,
@@ -343,6 +363,8 @@ void ConformanceTestSuite::ExpectParseFailureForProto(
RunTest(effective_test_name, request, &response);
if (response.result_case() == ConformanceResponse::kParseError) {
ReportSuccess(effective_test_name);
+ } else if (response.result_case() == ConformanceResponse::kSkipped) {
+ ReportSkip(effective_test_name, request, response);
} else {
ReportFailure(effective_test_name, request, response,
"Should have failed to parse, but didn't.");
@@ -362,13 +384,112 @@ void ConformanceTestSuite::ExpectHardParseFailureForProto(
void ConformanceTestSuite::RunValidJsonTest(
const string& test_name, const string& input_json,
const string& equivalent_text_format) {
- RunValidInputTest("JsonInput." + test_name + ".JsonOutput", input_json,
+ RunValidInputTest("JsonInput." + test_name + ".ProtobufOutput", input_json,
conformance::JSON, equivalent_text_format,
conformance::PROTOBUF);
- RunValidInputTest("JsonInput." + test_name + ".ProtobufOutput", input_json, conformance::JSON,
+ RunValidInputTest("JsonInput." + test_name + ".JsonOutput", input_json,
+ conformance::JSON, equivalent_text_format,
+ conformance::JSON);
+}
+
+void ConformanceTestSuite::RunValidJsonTestWithProtobufInput(
+ const string& test_name, const TestAllTypes& input,
+ const string& equivalent_text_format) {
+ RunValidInputTest("ProtobufInput." + test_name + ".JsonOutput",
+ input.SerializeAsString(), conformance::PROTOBUF,
equivalent_text_format, conformance::JSON);
}
+// According to proto3 JSON specification, JSON serializers follow more strict
+// rules than parsers (e.g., a serializer must serialize int32 values as JSON
+// numbers while the parser is allowed to accept them as JSON strings). This
+// method allows strict checking on a proto3 JSON serializer by inspecting
+// the JSON output directly.
+void ConformanceTestSuite::RunValidJsonTestWithValidator(
+ const string& test_name, const string& input_json,
+ const Validator& validator) {
+ ConformanceRequest request;
+ ConformanceResponse response;
+ request.set_json_payload(input_json);
+ request.set_requested_output_format(conformance::JSON);
+
+ string effective_test_name = "JsonInput." + test_name + ".Validator";
+
+ RunTest(effective_test_name, request, &response);
+
+ if (response.result_case() == ConformanceResponse::kSkipped) {
+ ReportSkip(effective_test_name, request, response);
+ return;
+ }
+
+ if (response.result_case() != ConformanceResponse::kJsonPayload) {
+ ReportFailure(effective_test_name, request, response,
+ "Expected JSON payload but got type %d.",
+ response.result_case());
+ return;
+ }
+ Json::Reader reader;
+ Json::Value value;
+ if (!reader.parse(response.json_payload(), value)) {
+ ReportFailure(effective_test_name, request, response,
+ "JSON payload cannot be parsed as valid JSON: %s",
+ reader.getFormattedErrorMessages().c_str());
+ return;
+ }
+ if (!validator(value)) {
+ ReportFailure(effective_test_name, request, response,
+ "JSON payload validation failed.");
+ return;
+ }
+ ReportSuccess(effective_test_name);
+}
+
+void ConformanceTestSuite::ExpectParseFailureForJson(
+ const string& test_name, const string& input_json) {
+ ConformanceRequest request;
+ ConformanceResponse response;
+ request.set_json_payload(input_json);
+ string effective_test_name = "JsonInput." + test_name;
+
+ // We don't expect output, but if the program erroneously accepts the protobuf
+ // we let it send its response as this. We must not leave it unspecified.
+ request.set_requested_output_format(conformance::JSON);
+
+ RunTest(effective_test_name, request, &response);
+ if (response.result_case() == ConformanceResponse::kParseError) {
+ ReportSuccess(effective_test_name);
+ } else if (response.result_case() == ConformanceResponse::kSkipped) {
+ ReportSkip(effective_test_name, request, response);
+ } else {
+ ReportFailure(effective_test_name, request, response,
+ "Should have failed to parse, but didn't.");
+ }
+}
+
+void ConformanceTestSuite::ExpectSerializeFailureForJson(
+ const string& test_name, const string& text_format) {
+ TestAllTypes payload_message;
+ GOOGLE_CHECK(
+ TextFormat::ParseFromString(text_format, &payload_message))
+ << "Failed to parse: " << text_format;
+
+ ConformanceRequest request;
+ ConformanceResponse response;
+ request.set_protobuf_payload(payload_message.SerializeAsString());
+ string effective_test_name = test_name + ".JsonOutput";
+ request.set_requested_output_format(conformance::JSON);
+
+ RunTest(effective_test_name, request, &response);
+ if (response.result_case() == ConformanceResponse::kSerializeError) {
+ ReportSuccess(effective_test_name);
+ } else if (response.result_case() == ConformanceResponse::kSkipped) {
+ ReportSkip(effective_test_name, request, response);
+ } else {
+ ReportFailure(effective_test_name, request, response,
+ "Should have failed to serialize, but didn't.");
+ }
+}
+
void ConformanceTestSuite::TestPrematureEOFForType(FieldDescriptor::Type type) {
// Incomplete values for each wire type.
static const string incompletes[6] = {
@@ -455,24 +576,41 @@ void ConformanceTestSuite::TestPrematureEOFForType(FieldDescriptor::Type type) {
}
}
-void ConformanceTestSuite::SetFailureList(const vector<string>& failure_list) {
+void ConformanceTestSuite::SetFailureList(const string& filename,
+ const vector<string>& failure_list) {
+ failure_list_filename_ = filename;
expected_to_fail_.clear();
std::copy(failure_list.begin(), failure_list.end(),
std::inserter(expected_to_fail_, expected_to_fail_.end()));
}
bool ConformanceTestSuite::CheckSetEmpty(const set<string>& set_to_check,
- const char* msg) {
+ const std::string& write_to_file,
+ const std::string& msg) {
if (set_to_check.empty()) {
return true;
} else {
StringAppendF(&output_, "\n");
- StringAppendF(&output_, "%s:\n", msg);
+ StringAppendF(&output_, "%s\n\n", msg.c_str());
for (set<string>::const_iterator iter = set_to_check.begin();
iter != set_to_check.end(); ++iter) {
StringAppendF(&output_, " %s\n", iter->c_str());
}
StringAppendF(&output_, "\n");
+
+ if (!write_to_file.empty()) {
+ std::ofstream os(write_to_file);
+ if (os) {
+ for (set<string>::const_iterator iter = set_to_check.begin();
+ iter != set_to_check.end(); ++iter) {
+ os << *iter << "\n";
+ }
+ } else {
+ StringAppendF(&output_, "Failed to open file: %s\n",
+ write_to_file.c_str());
+ }
+ }
+
return false;
}
}
@@ -500,22 +638,1387 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner,
RunValidJsonTest("HelloWorld", "{\"optionalString\":\"Hello, World!\"}",
"optional_string: 'Hello, World!'");
- bool ok =
- CheckSetEmpty(expected_to_fail_,
- "These tests were listed in the failure list, but they "
- "don't exist. Remove them from the failure list") &&
+ // Test field name conventions.
+ RunValidJsonTest(
+ "FieldNameInSnakeCase",
+ R"({
+ "fieldname1": 1,
+ "fieldName2": 2,
+ "FieldName3": 3
+ })",
+ R"(
+ fieldname1: 1
+ field_name2: 2
+ _field_name3: 3
+ )");
+ RunValidJsonTest(
+ "FieldNameWithNumbers",
+ R"({
+ "field0name5": 5,
+ "field0Name6": 6
+ })",
+ R"(
+ field0name5: 5
+ field_0_name6: 6
+ )");
+ RunValidJsonTest(
+ "FieldNameWithMixedCases",
+ R"({
+ "fieldName7": 7,
+ "fieldName8": 8,
+ "fieldName9": 9,
+ "fieldName10": 10,
+ "fIELDNAME11": 11,
+ "fIELDName12": 12
+ })",
+ R"(
+ fieldName7: 7
+ FieldName8: 8
+ field_Name9: 9
+ Field_Name10: 10
+ FIELD_NAME11: 11
+ FIELD_name12: 12
+ )");
+ // Using the original proto field name in JSON is also allowed.
+ RunValidJsonTest(
+ "OriginalProtoFieldName",
+ R"({
+ "fieldname1": 1,
+ "field_name2": 2,
+ "_field_name3": 3,
+ "field0name5": 5,
+ "field_0_name6": 6,
+ "fieldName7": 7,
+ "FieldName8": 8,
+ "field_Name9": 9,
+ "Field_Name10": 10,
+ "FIELD_NAME11": 11,
+ "FIELD_name12": 12
+ })",
+ R"(
+ fieldname1: 1
+ field_name2: 2
+ _field_name3: 3
+ field0name5: 5
+ field_0_name6: 6
+ fieldName7: 7
+ FieldName8: 8
+ field_Name9: 9
+ Field_Name10: 10
+ FIELD_NAME11: 11
+ FIELD_name12: 12
+ )");
+ // Field names can be escaped.
+ RunValidJsonTest(
+ "FieldNameEscaped",
+ R"({"fieldn\u0061me1": 1})",
+ "fieldname1: 1");
+ // Field names must be quoted (or it's not valid JSON).
+ ExpectParseFailureForJson(
+ "FieldNameNotQuoted",
+ "{fieldname1: 1}");
+ // Trailing comma is not allowed (not valid JSON).
+ ExpectParseFailureForJson(
+ "TrailingCommaInAnObject",
+ R"({"fieldname1":1,})");
+ // JSON doesn't support comments.
+ ExpectParseFailureForJson(
+ "JsonWithComments",
+ R"({
+ // This is a comment.
+ "fieldname1": 1
+ })");
+ // Duplicated field names are not allowed.
+ ExpectParseFailureForJson(
+ "FieldNameDuplicate",
+ R"({
+ "optionalNestedMessage": {a: 1},
+ "optionalNestedMessage": {}
+ })");
+ ExpectParseFailureForJson(
+ "FieldNameDuplicateDifferentCasing1",
+ R"({
+ "optional_nested_message": {a: 1},
+ "optionalNestedMessage": {}
+ })");
+ ExpectParseFailureForJson(
+ "FieldNameDuplicateDifferentCasing2",
+ R"({
+ "optionalNestedMessage": {a: 1},
+ "optional_nested_message": {}
+ })");
+ // Serializers should use lowerCamelCase by default.
+ RunValidJsonTestWithValidator(
+ "FieldNameInLowerCamelCase",
+ R"({
+ "fieldname1": 1,
+ "fieldName2": 2,
+ "FieldName3": 3
+ })",
+ [](const Json::Value& value) {
+ return value.isMember("fieldname1") &&
+ value.isMember("fieldName2") &&
+ value.isMember("FieldName3");
+ });
+ RunValidJsonTestWithValidator(
+ "FieldNameWithNumbers",
+ R"({
+ "field0name5": 5,
+ "field0Name6": 6
+ })",
+ [](const Json::Value& value) {
+ return value.isMember("field0name5") &&
+ value.isMember("field0Name6");
+ });
+ RunValidJsonTestWithValidator(
+ "FieldNameWithMixedCases",
+ R"({
+ "fieldName7": 7,
+ "fieldName8": 8,
+ "fieldName9": 9,
+ "fieldName10": 10,
+ "fIELDNAME11": 11,
+ "fIELDName12": 12
+ })",
+ [](const Json::Value& value) {
+ return value.isMember("fieldName7") &&
+ value.isMember("fieldName8") &&
+ value.isMember("fieldName9") &&
+ value.isMember("fieldName10") &&
+ value.isMember("fIELDNAME11") &&
+ value.isMember("fIELDName12");
+ });
+
+ // Integer fields.
+ RunValidJsonTest(
+ "Int32FieldMaxValue",
+ R"({"optionalInt32": 2147483647})",
+ "optional_int32: 2147483647");
+ RunValidJsonTest(
+ "Int32FieldMinValue",
+ R"({"optionalInt32": -2147483648})",
+ "optional_int32: -2147483648");
+ RunValidJsonTest(
+ "Uint32FieldMaxValue",
+ R"({"optionalUint32": 4294967295})",
+ "optional_uint32: 4294967295");
+ RunValidJsonTest(
+ "Int64FieldMaxValue",
+ R"({"optionalInt64": "9223372036854775807"})",
+ "optional_int64: 9223372036854775807");
+ RunValidJsonTest(
+ "Int64FieldMinValue",
+ R"({"optionalInt64": "-9223372036854775808"})",
+ "optional_int64: -9223372036854775808");
+ RunValidJsonTest(
+ "Uint64FieldMaxValue",
+ R"({"optionalUint64": "18446744073709551615"})",
+ "optional_uint64: 18446744073709551615");
+ // While not the largest Int64, this is the largest
+ // Int64 which can be exactly represented within an
+ // IEEE-754 64-bit float, which is the expected level
+ // of interoperability guarantee. Larger values may
+ // work in some implementations, but should not be
+ // relied upon.
+ RunValidJsonTest(
+ "Int64FieldMaxValueNotQuoted",
+ R"({"optionalInt64": 9223372036854774784})",
+ "optional_int64: 9223372036854774784");
+ RunValidJsonTest(
+ "Int64FieldMinValueNotQuoted",
+ R"({"optionalInt64": -9223372036854775808})",
+ "optional_int64: -9223372036854775808");
+ // Largest interoperable Uint64; see comment above
+ // for Int64FieldMaxValueNotQuoted.
+ RunValidJsonTest(
+ "Uint64FieldMaxValueNotQuoted",
+ R"({"optionalUint64": 18446744073709549568})",
+ "optional_uint64: 18446744073709549568");
+ // Values can be represented as JSON strings.
+ RunValidJsonTest(
+ "Int32FieldStringValue",
+ R"({"optionalInt32": "2147483647"})",
+ "optional_int32: 2147483647");
+ RunValidJsonTest(
+ "Int32FieldStringValueEscaped",
+ R"({"optionalInt32": "2\u003147483647"})",
+ "optional_int32: 2147483647");
+
+ // Parsers reject out-of-bound integer values.
+ ExpectParseFailureForJson(
+ "Int32FieldTooLarge",
+ R"({"optionalInt32": 2147483648})");
+ ExpectParseFailureForJson(
+ "Int32FieldTooSmall",
+ R"({"optionalInt32": -2147483649})");
+ ExpectParseFailureForJson(
+ "Uint32FieldTooLarge",
+ R"({"optionalUint32": 4294967296})");
+ ExpectParseFailureForJson(
+ "Int64FieldTooLarge",
+ R"({"optionalInt64": "9223372036854775808"})");
+ ExpectParseFailureForJson(
+ "Int64FieldTooSmall",
+ R"({"optionalInt64": "-9223372036854775809"})");
+ ExpectParseFailureForJson(
+ "Uint64FieldTooLarge",
+ R"({"optionalUint64": "18446744073709551616"})");
+ // Parser reject non-integer numeric values as well.
+ ExpectParseFailureForJson(
+ "Int32FieldNotInteger",
+ R"({"optionalInt32": 0.5})");
+ ExpectParseFailureForJson(
+ "Uint32FieldNotInteger",
+ R"({"optionalUint32": 0.5})");
+ ExpectParseFailureForJson(
+ "Int64FieldNotInteger",
+ R"({"optionalInt64": "0.5"})");
+ ExpectParseFailureForJson(
+ "Uint64FieldNotInteger",
+ R"({"optionalUint64": "0.5"})");
+
+ // Integers but represented as float values are accepted.
+ RunValidJsonTest(
+ "Int32FieldFloatTrailingZero",
+ R"({"optionalInt32": 100000.000})",
+ "optional_int32: 100000");
+ RunValidJsonTest(
+ "Int32FieldExponentialFormat",
+ R"({"optionalInt32": 1e5})",
+ "optional_int32: 100000");
+ RunValidJsonTest(
+ "Int32FieldMaxFloatValue",
+ R"({"optionalInt32": 2.147483647e9})",
+ "optional_int32: 2147483647");
+ RunValidJsonTest(
+ "Int32FieldMinFloatValue",
+ R"({"optionalInt32": -2.147483648e9})",
+ "optional_int32: -2147483648");
+ RunValidJsonTest(
+ "Uint32FieldMaxFloatValue",
+ R"({"optionalUint32": 4.294967295e9})",
+ "optional_uint32: 4294967295");
+
+ // Parser reject non-numeric values.
+ ExpectParseFailureForJson(
+ "Int32FieldNotNumber",
+ R"({"optionalInt32": "3x3"})");
+ ExpectParseFailureForJson(
+ "Uint32FieldNotNumber",
+ R"({"optionalUint32": "3x3"})");
+ ExpectParseFailureForJson(
+ "Int64FieldNotNumber",
+ R"({"optionalInt64": "3x3"})");
+ ExpectParseFailureForJson(
+ "Uint64FieldNotNumber",
+ R"({"optionalUint64": "3x3"})");
+ // JSON does not allow "+" on numric values.
+ ExpectParseFailureForJson(
+ "Int32FieldPlusSign",
+ R"({"optionalInt32": +1})");
+ // JSON doesn't allow leading 0s.
+ ExpectParseFailureForJson(
+ "Int32FieldLeadingZero",
+ R"({"optionalInt32": 01})");
+ ExpectParseFailureForJson(
+ "Int32FieldNegativeWithLeadingZero",
+ R"({"optionalInt32": -01})");
+ // String values must follow the same syntax rule. Specifically leading
+ // or traling spaces are not allowed.
+ ExpectParseFailureForJson(
+ "Int32FieldLeadingSpace",
+ R"({"optionalInt32": " 1"})");
+ ExpectParseFailureForJson(
+ "Int32FieldTrailingSpace",
+ R"({"optionalInt32": "1 "})");
+
+ // 64-bit values are serialized as strings.
+ RunValidJsonTestWithValidator(
+ "Int64FieldBeString",
+ R"({"optionalInt64": 1})",
+ [](const Json::Value& value) {
+ return value["optionalInt64"].type() == Json::stringValue &&
+ value["optionalInt64"].asString() == "1";
+ });
+ RunValidJsonTestWithValidator(
+ "Uint64FieldBeString",
+ R"({"optionalUint64": 1})",
+ [](const Json::Value& value) {
+ return value["optionalUint64"].type() == Json::stringValue &&
+ value["optionalUint64"].asString() == "1";
+ });
+
+ // Bool fields.
+ RunValidJsonTest(
+ "BoolFieldTrue",
+ R"({"optionalBool":true})",
+ "optional_bool: true");
+ RunValidJsonTest(
+ "BoolFieldFalse",
+ R"({"optionalBool":false})",
+ "optional_bool: false");
+
+ // Other forms are not allowed.
+ ExpectParseFailureForJson(
+ "BoolFieldIntegerZero",
+ R"({"optionalBool":0})");
+ ExpectParseFailureForJson(
+ "BoolFieldIntegerOne",
+ R"({"optionalBool":1})");
+ ExpectParseFailureForJson(
+ "BoolFieldCamelCaseTrue",
+ R"({"optionalBool":True})");
+ ExpectParseFailureForJson(
+ "BoolFieldCamelCaseFalse",
+ R"({"optionalBool":False})");
+ ExpectParseFailureForJson(
+ "BoolFieldAllCapitalTrue",
+ R"({"optionalBool":TRUE})");
+ ExpectParseFailureForJson(
+ "BoolFieldAllCapitalFalse",
+ R"({"optionalBool":FALSE})");
+ ExpectParseFailureForJson(
+ "BoolFieldDoubleQuotedTrue",
+ R"({"optionalBool":"true"})");
+ ExpectParseFailureForJson(
+ "BoolFieldDoubleQuotedFalse",
+ R"({"optionalBool":"false"})");
+
+ // Float fields.
+ RunValidJsonTest(
+ "FloatFieldMinPositiveValue",
+ R"({"optionalFloat": 1.175494e-38})",
+ "optional_float: 1.175494e-38");
+ RunValidJsonTest(
+ "FloatFieldMaxNegativeValue",
+ R"({"optionalFloat": -1.175494e-38})",
+ "optional_float: -1.175494e-38");
+ RunValidJsonTest(
+ "FloatFieldMaxPositiveValue",
+ R"({"optionalFloat": 3.402823e+38})",
+ "optional_float: 3.402823e+38");
+ RunValidJsonTest(
+ "FloatFieldMinNegativeValue",
+ R"({"optionalFloat": 3.402823e+38})",
+ "optional_float: 3.402823e+38");
+ // Values can be quoted.
+ RunValidJsonTest(
+ "FloatFieldQuotedValue",
+ R"({"optionalFloat": "1"})",
+ "optional_float: 1");
+ // Special values.
+ RunValidJsonTest(
+ "FloatFieldNan",
+ R"({"optionalFloat": "NaN"})",
+ "optional_float: nan");
+ RunValidJsonTest(
+ "FloatFieldInfinity",
+ R"({"optionalFloat": "Infinity"})",
+ "optional_float: inf");
+ RunValidJsonTest(
+ "FloatFieldNegativeInfinity",
+ R"({"optionalFloat": "-Infinity"})",
+ "optional_float: -inf");
+ // Non-cannonical Nan will be correctly normalized.
+ {
+ TestAllTypes message;
+ // IEEE floating-point standard 32-bit quiet NaN:
+ // 0111 1111 1xxx xxxx xxxx xxxx xxxx xxxx
+ message.set_optional_float(
+ WireFormatLite::DecodeFloat(0x7FA12345));
+ RunValidJsonTestWithProtobufInput(
+ "FloatFieldNormalizeQuietNan", message,
+ "optional_float: nan");
+ // IEEE floating-point standard 64-bit signaling NaN:
+ // 1111 1111 1xxx xxxx xxxx xxxx xxxx xxxx
+ message.set_optional_float(
+ WireFormatLite::DecodeFloat(0xFFB54321));
+ RunValidJsonTestWithProtobufInput(
+ "FloatFieldNormalizeSignalingNan", message,
+ "optional_float: nan");
+ }
- CheckSetEmpty(unexpected_failing_tests_,
- "These tests failed. If they can't be fixed right now, "
- "you can add them to the failure list so the overall "
- "suite can succeed") &&
+ // Special values must be quoted.
+ ExpectParseFailureForJson(
+ "FloatFieldNanNotQuoted",
+ R"({"optionalFloat": NaN})");
+ ExpectParseFailureForJson(
+ "FloatFieldInfinityNotQuoted",
+ R"({"optionalFloat": Infinity})");
+ ExpectParseFailureForJson(
+ "FloatFieldNegativeInfinityNotQuoted",
+ R"({"optionalFloat": -Infinity})");
+ // Parsers should reject out-of-bound values.
+ ExpectParseFailureForJson(
+ "FloatFieldTooSmall",
+ R"({"optionalFloat": -3.502823e+38})");
+ ExpectParseFailureForJson(
+ "FloatFieldTooLarge",
+ R"({"optionalFloat": 3.502823e+38})");
+
+ // Double fields.
+ RunValidJsonTest(
+ "DoubleFieldMinPositiveValue",
+ R"({"optionalDouble": 2.22507e-308})",
+ "optional_double: 2.22507e-308");
+ RunValidJsonTest(
+ "DoubleFieldMaxNegativeValue",
+ R"({"optionalDouble": -2.22507e-308})",
+ "optional_double: -2.22507e-308");
+ RunValidJsonTest(
+ "DoubleFieldMaxPositiveValue",
+ R"({"optionalDouble": 1.79769e+308})",
+ "optional_double: 1.79769e+308");
+ RunValidJsonTest(
+ "DoubleFieldMinNegativeValue",
+ R"({"optionalDouble": -1.79769e+308})",
+ "optional_double: -1.79769e+308");
+ // Values can be quoted.
+ RunValidJsonTest(
+ "DoubleFieldQuotedValue",
+ R"({"optionalDouble": "1"})",
+ "optional_double: 1");
+ // Speical values.
+ RunValidJsonTest(
+ "DoubleFieldNan",
+ R"({"optionalDouble": "NaN"})",
+ "optional_double: nan");
+ RunValidJsonTest(
+ "DoubleFieldInfinity",
+ R"({"optionalDouble": "Infinity"})",
+ "optional_double: inf");
+ RunValidJsonTest(
+ "DoubleFieldNegativeInfinity",
+ R"({"optionalDouble": "-Infinity"})",
+ "optional_double: -inf");
+ // Non-cannonical Nan will be correctly normalized.
+ {
+ TestAllTypes message;
+ message.set_optional_double(
+ WireFormatLite::DecodeDouble(0x7FFA123456789ABCLL));
+ RunValidJsonTestWithProtobufInput(
+ "DoubleFieldNormalizeQuietNan", message,
+ "optional_double: nan");
+ message.set_optional_double(
+ WireFormatLite::DecodeDouble(0xFFFBCBA987654321LL));
+ RunValidJsonTestWithProtobufInput(
+ "DoubleFieldNormalizeSignalingNan", message,
+ "optional_double: nan");
+ }
- CheckSetEmpty(unexpected_succeeding_tests_,
- "These tests succeeded, even though they were listed in "
- "the failure list. Remove them from the failure list");
+ // Special values must be quoted.
+ ExpectParseFailureForJson(
+ "DoubleFieldNanNotQuoted",
+ R"({"optionalDouble": NaN})");
+ ExpectParseFailureForJson(
+ "DoubleFieldInfinityNotQuoted",
+ R"({"optionalDouble": Infinity})");
+ ExpectParseFailureForJson(
+ "DoubleFieldNegativeInfinityNotQuoted",
+ R"({"optionalDouble": -Infinity})");
+
+ // Parsers should reject out-of-bound values.
+ ExpectParseFailureForJson(
+ "DoubleFieldTooSmall",
+ R"({"optionalDouble": -1.89769e+308})");
+ ExpectParseFailureForJson(
+ "DoubleFieldTooLarge",
+ R"({"optionalDouble": +1.89769e+308})");
+
+ // Enum fields.
+ RunValidJsonTest(
+ "EnumField",
+ R"({"optionalNestedEnum": "FOO"})",
+ "optional_nested_enum: FOO");
+ // Enum values must be represented as strings.
+ ExpectParseFailureForJson(
+ "EnumFieldNotQuoted",
+ R"({"optionalNestedEnum": FOO})");
+ // Numeric values are allowed.
+ RunValidJsonTest(
+ "EnumFieldNumericValueZero",
+ R"({"optionalNestedEnum": 0})",
+ "optional_nested_enum: FOO");
+ RunValidJsonTest(
+ "EnumFieldNumericValueNonZero",
+ R"({"optionalNestedEnum": 1})",
+ "optional_nested_enum: BAR");
+ // Unknown enum values are represented as numeric values.
+ RunValidJsonTestWithValidator(
+ "EnumFieldUnknownValue",
+ R"({"optionalNestedEnum": 123})",
+ [](const Json::Value& value) {
+ return value["optionalNestedEnum"].type() == Json::intValue &&
+ value["optionalNestedEnum"].asInt() == 123;
+ });
+
+ // String fields.
+ RunValidJsonTest(
+ "StringField",
+ R"({"optionalString": "Hello world!"})",
+ "optional_string: \"Hello world!\"");
+ RunValidJsonTest(
+ "StringFieldUnicode",
+ // Google in Chinese.
+ R"({"optionalString": "谷歌"})",
+ R"(optional_string: "谷歌")");
+ RunValidJsonTest(
+ "StringFieldEscape",
+ R"({"optionalString": "\"\\\/\b\f\n\r\t"})",
+ R"(optional_string: "\"\\/\b\f\n\r\t")");
+ RunValidJsonTest(
+ "StringFieldUnicodeEscape",
+ R"({"optionalString": "\u8C37\u6B4C"})",
+ R"(optional_string: "谷歌")");
+ RunValidJsonTest(
+ "StringFieldUnicodeEscapeWithLowercaseHexLetters",
+ R"({"optionalString": "\u8c37\u6b4c"})",
+ R"(optional_string: "谷歌")");
+ RunValidJsonTest(
+ "StringFieldSurrogatePair",
+ // The character is an emoji: grinning face with smiling eyes. 😁
+ R"({"optionalString": "\uD83D\uDE01"})",
+ R"(optional_string: "\xF0\x9F\x98\x81")");
+
+ // Unicode escapes must start with "\u" (lowercase u).
+ ExpectParseFailureForJson(
+ "StringFieldUppercaseEscapeLetter",
+ R"({"optionalString": "\U8C37\U6b4C"})");
+ ExpectParseFailureForJson(
+ "StringFieldInvalidEscape",
+ R"({"optionalString": "\uXXXX\u6B4C"})");
+ ExpectParseFailureForJson(
+ "StringFieldUnterminatedEscape",
+ R"({"optionalString": "\u8C3"})");
+ ExpectParseFailureForJson(
+ "StringFieldUnpairedHighSurrogate",
+ R"({"optionalString": "\uD800"})");
+ ExpectParseFailureForJson(
+ "StringFieldUnpairedLowSurrogate",
+ R"({"optionalString": "\uDC00"})");
+ ExpectParseFailureForJson(
+ "StringFieldSurrogateInWrongOrder",
+ R"({"optionalString": "\uDE01\uD83D"})");
+ ExpectParseFailureForJson(
+ "StringFieldNotAString",
+ R"({"optionalString": 12345})");
+
+ // Bytes fields.
+ RunValidJsonTest(
+ "BytesField",
+ R"({"optionalBytes": "AQI="})",
+ R"(optional_bytes: "\x01\x02")");
+ ExpectParseFailureForJson(
+ "BytesFieldNoPadding",
+ R"({"optionalBytes": "AQI"})");
+ ExpectParseFailureForJson(
+ "BytesFieldInvalidBase64Characters",
+ R"({"optionalBytes": "-_=="})");
+
+ // Message fields.
+ RunValidJsonTest(
+ "MessageField",
+ R"({"optionalNestedMessage": {"a": 1234}})",
+ "optional_nested_message: {a: 1234}");
+
+ // Oneof fields.
+ ExpectParseFailureForJson(
+ "OneofFieldDuplicate",
+ R"({"oneofUint32": 1, "oneofString": "test"})");
+
+ // Repeated fields.
+ RunValidJsonTest(
+ "PrimitiveRepeatedField",
+ R"({"repeatedInt32": [1, 2, 3, 4]})",
+ "repeated_int32: [1, 2, 3, 4]");
+ RunValidJsonTest(
+ "EnumRepeatedField",
+ R"({"repeatedNestedEnum": ["FOO", "BAR", "BAZ"]})",
+ "repeated_nested_enum: [FOO, BAR, BAZ]");
+ RunValidJsonTest(
+ "StringRepeatedField",
+ R"({"repeatedString": ["Hello", "world"]})",
+ R"(repeated_string: ["Hello", "world"])");
+ RunValidJsonTest(
+ "BytesRepeatedField",
+ R"({"repeatedBytes": ["AAEC", "AQI="]})",
+ R"(repeated_bytes: ["\x00\x01\x02", "\x01\x02"])");
+ RunValidJsonTest(
+ "MessageRepeatedField",
+ R"({"repeatedNestedMessage": [{"a": 1234}, {"a": 5678}]})",
+ "repeated_nested_message: {a: 1234}"
+ "repeated_nested_message: {a: 5678}");
+
+ // Repeated field elements are of incorrect type.
+ ExpectParseFailureForJson(
+ "RepeatedFieldWrongElementTypeExpectingIntegersGotBool",
+ R"({"repeatedInt32": [1, false, 3, 4]})");
+ ExpectParseFailureForJson(
+ "RepeatedFieldWrongElementTypeExpectingIntegersGotString",
+ R"({"repeatedInt32": [1, 2, "name", 4]})");
+ ExpectParseFailureForJson(
+ "RepeatedFieldWrongElementTypeExpectingIntegersGotMessage",
+ R"({"repeatedInt32": [1, 2, 3, {"a": 4}]})");
+ ExpectParseFailureForJson(
+ "RepeatedFieldWrongElementTypeExpectingStringsGotInt",
+ R"({"repeatedString": ["1", 2, "3", "4"]})");
+ ExpectParseFailureForJson(
+ "RepeatedFieldWrongElementTypeExpectingStringsGotBool",
+ R"({"repeatedString": ["1", "2", false, "4"]})");
+ ExpectParseFailureForJson(
+ "RepeatedFieldWrongElementTypeExpectingStringsGotMessage",
+ R"({"repeatedString": ["1", 2, "3", {"a": 4}]})");
+ ExpectParseFailureForJson(
+ "RepeatedFieldWrongElementTypeExpectingMessagesGotInt",
+ R"({"repeatedNestedMessage": [{"a": 1}, 2]})");
+ ExpectParseFailureForJson(
+ "RepeatedFieldWrongElementTypeExpectingMessagesGotBool",
+ R"({"repeatedNestedMessage": [{"a": 1}, false]})");
+ ExpectParseFailureForJson(
+ "RepeatedFieldWrongElementTypeExpectingMessagesGotString",
+ R"({"repeatedNestedMessage": [{"a": 1}, "2"]})");
+ // Trailing comma in the repeated field is not allowed.
+ ExpectParseFailureForJson(
+ "RepeatedFieldTrailingComma",
+ R"({"repeatedInt32": [1, 2, 3, 4,]})");
+
+ // Map fields.
+ RunValidJsonTest(
+ "Int32MapField",
+ R"({"mapInt32Int32": {"1": 2, "3": 4}})",
+ "map_int32_int32: {key: 1 value: 2}"
+ "map_int32_int32: {key: 3 value: 4}");
+ ExpectParseFailureForJson(
+ "Int32MapFieldKeyNotQuoted",
+ R"({"mapInt32Int32": {1: 2, 3: 4}})");
+ RunValidJsonTest(
+ "Uint32MapField",
+ R"({"mapUint32Uint32": {"1": 2, "3": 4}})",
+ "map_uint32_uint32: {key: 1 value: 2}"
+ "map_uint32_uint32: {key: 3 value: 4}");
+ ExpectParseFailureForJson(
+ "Uint32MapFieldKeyNotQuoted",
+ R"({"mapUint32Uint32": {1: 2, 3: 4}})");
+ RunValidJsonTest(
+ "Int64MapField",
+ R"({"mapInt64Int64": {"1": 2, "3": 4}})",
+ "map_int64_int64: {key: 1 value: 2}"
+ "map_int64_int64: {key: 3 value: 4}");
+ ExpectParseFailureForJson(
+ "Int64MapFieldKeyNotQuoted",
+ R"({"mapInt64Int64": {1: 2, 3: 4}})");
+ RunValidJsonTest(
+ "Uint64MapField",
+ R"({"mapUint64Uint64": {"1": 2, "3": 4}})",
+ "map_uint64_uint64: {key: 1 value: 2}"
+ "map_uint64_uint64: {key: 3 value: 4}");
+ ExpectParseFailureForJson(
+ "Uint64MapFieldKeyNotQuoted",
+ R"({"mapUint64Uint64": {1: 2, 3: 4}})");
+ RunValidJsonTest(
+ "BoolMapField",
+ R"({"mapBoolBool": {"true": true, "false": false}})",
+ "map_bool_bool: {key: true value: true}"
+ "map_bool_bool: {key: false value: false}");
+ ExpectParseFailureForJson(
+ "BoolMapFieldKeyNotQuoted",
+ R"({"mapBoolBool": {true: true, false: false}})");
+ RunValidJsonTest(
+ "MessageMapField",
+ R"({
+ "mapStringNestedMessage": {
+ "hello": {"a": 1234},
+ "world": {"a": 5678}
+ }
+ })",
+ R"(
+ map_string_nested_message: {
+ key: "hello"
+ value: {a: 1234}
+ }
+ map_string_nested_message: {
+ key: "world"
+ value: {a: 5678}
+ }
+ )");
+ // Since Map keys are represented as JSON strings, escaping should be allowed.
+ RunValidJsonTest(
+ "Int32MapEscapedKey",
+ R"({"mapInt32Int32": {"\u0031": 2}})",
+ "map_int32_int32: {key: 1 value: 2}");
+ RunValidJsonTest(
+ "Int64MapEscapedKey",
+ R"({"mapInt64Int64": {"\u0031": 2}})",
+ "map_int64_int64: {key: 1 value: 2}");
+ RunValidJsonTest(
+ "BoolMapEscapedKey",
+ R"({"mapBoolBool": {"tr\u0075e": true}})",
+ "map_bool_bool: {key: true value: true}");
+
+ // "null" is accepted for all fields types.
+ RunValidJsonTest(
+ "AllFieldAcceptNull",
+ R"({
+ "optionalInt32": null,
+ "optionalInt64": null,
+ "optionalUint32": null,
+ "optionalUint64": null,
+ "optionalBool": null,
+ "optionalString": null,
+ "optionalBytes": null,
+ "optionalNestedEnum": null,
+ "optionalNestedMessage": null,
+ "repeatedInt32": null,
+ "repeatedInt64": null,
+ "repeatedUint32": null,
+ "repeatedUint64": null,
+ "repeatedBool": null,
+ "repeatedString": null,
+ "repeatedBytes": null,
+ "repeatedNestedEnum": null,
+ "repeatedNestedMessage": null,
+ "mapInt32Int32": null,
+ "mapBoolBool": null,
+ "mapStringNestedMessage": null
+ })",
+ "");
+
+ // Repeated field elements cannot be null.
+ ExpectParseFailureForJson(
+ "RepeatedFieldPrimitiveElementIsNull",
+ R"({"repeatedInt32": [1, null, 2]})");
+ ExpectParseFailureForJson(
+ "RepeatedFieldMessageElementIsNull",
+ R"({"repeatedNestedMessage": [{"a":1}, null, {"a":2}]})");
+ // Map field keys cannot be null.
+ ExpectParseFailureForJson(
+ "MapFieldKeyIsNull",
+ R"({"mapInt32Int32": {null: 1}})");
+ // Map field values cannot be null.
+ ExpectParseFailureForJson(
+ "MapFieldValueIsNull",
+ R"({"mapInt32Int32": {"0": null}})");
+
+ // Wrapper types.
+ RunValidJsonTest(
+ "OptionalBoolWrapper",
+ R"({"optionalBoolWrapper": false})",
+ "optional_bool_wrapper: {value: false}");
+ RunValidJsonTest(
+ "OptionalInt32Wrapper",
+ R"({"optionalInt32Wrapper": 0})",
+ "optional_int32_wrapper: {value: 0}");
+ RunValidJsonTest(
+ "OptionalUint32Wrapper",
+ R"({"optionalUint32Wrapper": 0})",
+ "optional_uint32_wrapper: {value: 0}");
+ RunValidJsonTest(
+ "OptionalInt64Wrapper",
+ R"({"optionalInt64Wrapper": 0})",
+ "optional_int64_wrapper: {value: 0}");
+ RunValidJsonTest(
+ "OptionalUint64Wrapper",
+ R"({"optionalUint64Wrapper": 0})",
+ "optional_uint64_wrapper: {value: 0}");
+ RunValidJsonTest(
+ "OptionalFloatWrapper",
+ R"({"optionalFloatWrapper": 0})",
+ "optional_float_wrapper: {value: 0}");
+ RunValidJsonTest(
+ "OptionalDoubleWrapper",
+ R"({"optionalDoubleWrapper": 0})",
+ "optional_double_wrapper: {value: 0}");
+ RunValidJsonTest(
+ "OptionalStringWrapper",
+ R"({"optionalStringWrapper": ""})",
+ R"(optional_string_wrapper: {value: ""})");
+ RunValidJsonTest(
+ "OptionalBytesWrapper",
+ R"({"optionalBytesWrapper": ""})",
+ R"(optional_bytes_wrapper: {value: ""})");
+ RunValidJsonTest(
+ "OptionalWrapperTypesWithNonDefaultValue",
+ R"({
+ "optionalBoolWrapper": true,
+ "optionalInt32Wrapper": 1,
+ "optionalUint32Wrapper": 1,
+ "optionalInt64Wrapper": "1",
+ "optionalUint64Wrapper": "1",
+ "optionalFloatWrapper": 1,
+ "optionalDoubleWrapper": 1,
+ "optionalStringWrapper": "1",
+ "optionalBytesWrapper": "AQI="
+ })",
+ R"(
+ optional_bool_wrapper: {value: true}
+ optional_int32_wrapper: {value: 1}
+ optional_uint32_wrapper: {value: 1}
+ optional_int64_wrapper: {value: 1}
+ optional_uint64_wrapper: {value: 1}
+ optional_float_wrapper: {value: 1}
+ optional_double_wrapper: {value: 1}
+ optional_string_wrapper: {value: "1"}
+ optional_bytes_wrapper: {value: "\x01\x02"}
+ )");
+ RunValidJsonTest(
+ "RepeatedBoolWrapper",
+ R"({"repeatedBoolWrapper": [true, false]})",
+ "repeated_bool_wrapper: {value: true}"
+ "repeated_bool_wrapper: {value: false}");
+ RunValidJsonTest(
+ "RepeatedInt32Wrapper",
+ R"({"repeatedInt32Wrapper": [0, 1]})",
+ "repeated_int32_wrapper: {value: 0}"
+ "repeated_int32_wrapper: {value: 1}");
+ RunValidJsonTest(
+ "RepeatedUint32Wrapper",
+ R"({"repeatedUint32Wrapper": [0, 1]})",
+ "repeated_uint32_wrapper: {value: 0}"
+ "repeated_uint32_wrapper: {value: 1}");
+ RunValidJsonTest(
+ "RepeatedInt64Wrapper",
+ R"({"repeatedInt64Wrapper": [0, 1]})",
+ "repeated_int64_wrapper: {value: 0}"
+ "repeated_int64_wrapper: {value: 1}");
+ RunValidJsonTest(
+ "RepeatedUint64Wrapper",
+ R"({"repeatedUint64Wrapper": [0, 1]})",
+ "repeated_uint64_wrapper: {value: 0}"
+ "repeated_uint64_wrapper: {value: 1}");
+ RunValidJsonTest(
+ "RepeatedFloatWrapper",
+ R"({"repeatedFloatWrapper": [0, 1]})",
+ "repeated_float_wrapper: {value: 0}"
+ "repeated_float_wrapper: {value: 1}");
+ RunValidJsonTest(
+ "RepeatedDoubleWrapper",
+ R"({"repeatedDoubleWrapper": [0, 1]})",
+ "repeated_double_wrapper: {value: 0}"
+ "repeated_double_wrapper: {value: 1}");
+ RunValidJsonTest(
+ "RepeatedStringWrapper",
+ R"({"repeatedStringWrapper": ["", "AQI="]})",
+ R"(
+ repeated_string_wrapper: {value: ""}
+ repeated_string_wrapper: {value: "AQI="}
+ )");
+ RunValidJsonTest(
+ "RepeatedBytesWrapper",
+ R"({"repeatedBytesWrapper": ["", "AQI="]})",
+ R"(
+ repeated_bytes_wrapper: {value: ""}
+ repeated_bytes_wrapper: {value: "\x01\x02"}
+ )");
+ RunValidJsonTest(
+ "WrapperTypesWithNullValue",
+ R"({
+ "optionalBoolWrapper": null,
+ "optionalInt32Wrapper": null,
+ "optionalUint32Wrapper": null,
+ "optionalInt64Wrapper": null,
+ "optionalUint64Wrapper": null,
+ "optionalFloatWrapper": null,
+ "optionalDoubleWrapper": null,
+ "optionalStringWrapper": null,
+ "optionalBytesWrapper": null,
+ "repeatedBoolWrapper": null,
+ "repeatedInt32Wrapper": null,
+ "repeatedUint32Wrapper": null,
+ "repeatedInt64Wrapper": null,
+ "repeatedUint64Wrapper": null,
+ "repeatedFloatWrapper": null,
+ "repeatedDoubleWrapper": null,
+ "repeatedStringWrapper": null,
+ "repeatedBytesWrapper": null
+ })",
+ "");
+
+ // Duration
+ RunValidJsonTest(
+ "DurationMinValue",
+ R"({"optionalDuration": "-315576000000.999999999s"})",
+ "optional_duration: {seconds: -315576000000 nanos: -999999999}");
+ RunValidJsonTest(
+ "DurationMaxValue",
+ R"({"optionalDuration": "315576000000.999999999s"})",
+ "optional_duration: {seconds: 315576000000 nanos: 999999999}");
+ RunValidJsonTest(
+ "DurationRepeatedValue",
+ R"({"repeatedDuration": ["1.5s", "-1.5s"]})",
+ "repeated_duration: {seconds: 1 nanos: 500000000}"
+ "repeated_duration: {seconds: -1 nanos: -500000000}");
+
+ ExpectParseFailureForJson(
+ "DurationMissingS",
+ R"({"optionalDuration": "1"})");
+ ExpectParseFailureForJson(
+ "DurationJsonInputTooSmall",
+ R"({"optionalDuration": "-315576000001.000000000s"})");
+ ExpectParseFailureForJson(
+ "DurationJsonInputTooLarge",
+ R"({"optionalDuration": "315576000001.000000000s"})");
+ ExpectSerializeFailureForJson(
+ "DurationProtoInputTooSmall",
+ "optional_duration: {seconds: -315576000001 nanos: 0}");
+ ExpectSerializeFailureForJson(
+ "DurationProtoInputTooLarge",
+ "optional_duration: {seconds: 315576000001 nanos: 0}");
+
+ RunValidJsonTestWithValidator(
+ "DurationHasZeroFractionalDigit",
+ R"({"optionalDuration": "1.000000000s"})",
+ [](const Json::Value& value) {
+ return value["optionalDuration"].asString() == "1s";
+ });
+ RunValidJsonTestWithValidator(
+ "DurationHas3FractionalDigits",
+ R"({"optionalDuration": "1.010000000s"})",
+ [](const Json::Value& value) {
+ return value["optionalDuration"].asString() == "1.010s";
+ });
+ RunValidJsonTestWithValidator(
+ "DurationHas6FractionalDigits",
+ R"({"optionalDuration": "1.000010000s"})",
+ [](const Json::Value& value) {
+ return value["optionalDuration"].asString() == "1.000010s";
+ });
+ RunValidJsonTestWithValidator(
+ "DurationHas9FractionalDigits",
+ R"({"optionalDuration": "1.000000010s"})",
+ [](const Json::Value& value) {
+ return value["optionalDuration"].asString() == "1.000000010s";
+ });
+
+ // Timestamp
+ RunValidJsonTest(
+ "TimestampMinValue",
+ R"({"optionalTimestamp": "0001-01-01T00:00:00Z"})",
+ "optional_timestamp: {seconds: -62135596800}");
+ RunValidJsonTest(
+ "TimestampMaxValue",
+ R"({"optionalTimestamp": "9999-12-31T23:59:59.999999999Z"})",
+ "optional_timestamp: {seconds: 253402300799 nanos: 999999999}");
+ RunValidJsonTest(
+ "TimestampRepeatedValue",
+ R"({
+ "repeatedTimestamp": [
+ "0001-01-01T00:00:00Z",
+ "9999-12-31T23:59:59.999999999Z"
+ ]
+ })",
+ "repeated_timestamp: {seconds: -62135596800}"
+ "repeated_timestamp: {seconds: 253402300799 nanos: 999999999}");
+ RunValidJsonTest(
+ "TimestampWithPositiveOffset",
+ R"({"optionalTimestamp": "1970-01-01T08:00:00+08:00"})",
+ "optional_timestamp: {seconds: 0}");
+ RunValidJsonTest(
+ "TimestampWithNegativeOffset",
+ R"({"optionalTimestamp": "1969-12-31T16:00:00-08:00"})",
+ "optional_timestamp: {seconds: 0}");
+
+ ExpectParseFailureForJson(
+ "TimestampJsonInputTooSmall",
+ R"({"optionalTimestamp": "0000-01-01T00:00:00Z"})");
+ ExpectParseFailureForJson(
+ "TimestampJsonInputTooLarge",
+ R"({"optionalTimestamp": "10000-01-01T00:00:00Z"})");
+ ExpectParseFailureForJson(
+ "TimestampJsonInputMissingZ",
+ R"({"optionalTimestamp": "0001-01-01T00:00:00"})");
+ ExpectParseFailureForJson(
+ "TimestampJsonInputMissingT",
+ R"({"optionalTimestamp": "0001-01-01 00:00:00Z"})");
+ ExpectParseFailureForJson(
+ "TimestampJsonInputLowercaseZ",
+ R"({"optionalTimestamp": "0001-01-01T00:00:00z"})");
+ ExpectParseFailureForJson(
+ "TimestampJsonInputLowercaseT",
+ R"({"optionalTimestamp": "0001-01-01t00:00:00Z"})");
+ ExpectSerializeFailureForJson(
+ "TimestampProtoInputTooSmall",
+ "optional_timestamp: {seconds: -62135596801}");
+ ExpectSerializeFailureForJson(
+ "TimestampProtoInputTooLarge",
+ "optional_timestamp: {seconds: 253402300800}");
+ RunValidJsonTestWithValidator(
+ "TimestampZeroNormalized",
+ R"({"optionalTimestamp": "1969-12-31T16:00:00-08:00"})",
+ [](const Json::Value& value) {
+ return value["optionalTimestamp"].asString() ==
+ "1970-01-01T00:00:00Z";
+ });
+ RunValidJsonTestWithValidator(
+ "TimestampHasZeroFractionalDigit",
+ R"({"optionalTimestamp": "1970-01-01T00:00:00.000000000Z"})",
+ [](const Json::Value& value) {
+ return value["optionalTimestamp"].asString() ==
+ "1970-01-01T00:00:00Z";
+ });
+ RunValidJsonTestWithValidator(
+ "TimestampHas3FractionalDigits",
+ R"({"optionalTimestamp": "1970-01-01T00:00:00.010000000Z"})",
+ [](const Json::Value& value) {
+ return value["optionalTimestamp"].asString() ==
+ "1970-01-01T00:00:00.010Z";
+ });
+ RunValidJsonTestWithValidator(
+ "TimestampHas6FractionalDigits",
+ R"({"optionalTimestamp": "1970-01-01T00:00:00.000010000Z"})",
+ [](const Json::Value& value) {
+ return value["optionalTimestamp"].asString() ==
+ "1970-01-01T00:00:00.000010Z";
+ });
+ RunValidJsonTestWithValidator(
+ "TimestampHas9FractionalDigits",
+ R"({"optionalTimestamp": "1970-01-01T00:00:00.000000010Z"})",
+ [](const Json::Value& value) {
+ return value["optionalTimestamp"].asString() ==
+ "1970-01-01T00:00:00.000000010Z";
+ });
+
+ // FieldMask
+ RunValidJsonTest(
+ "FieldMask",
+ R"({"optionalFieldMask": "foo,barBaz"})",
+ R"(optional_field_mask: {paths: "foo" paths: "bar_baz"})");
+ ExpectParseFailureForJson(
+ "FieldMaskInvalidCharacter",
+ R"({"optionalFieldMask": "foo,bar_bar"})");
+ ExpectSerializeFailureForJson(
+ "FieldMaskPathsDontRoundTrip",
+ R"(optional_field_mask: {paths: "fooBar"})");
+ ExpectSerializeFailureForJson(
+ "FieldMaskNumbersDontRoundTrip",
+ R"(optional_field_mask: {paths: "foo_3_bar"})");
+ ExpectSerializeFailureForJson(
+ "FieldMaskTooManyUnderscore",
+ R"(optional_field_mask: {paths: "foo__bar"})");
+
+ // Struct
+ RunValidJsonTest(
+ "Struct",
+ R"({
+ "optionalStruct": {
+ "nullValue": null,
+ "intValue": 1234,
+ "boolValue": true,
+ "doubleValue": 1234.5678,
+ "stringValue": "Hello world!",
+ "listValue": [1234, "5678"],
+ "objectValue": {
+ "value": 0
+ }
+ }
+ })",
+ R"(
+ optional_struct: {
+ fields: {
+ key: "nullValue"
+ value: {null_value: NULL_VALUE}
+ }
+ fields: {
+ key: "intValue"
+ value: {number_value: 1234}
+ }
+ fields: {
+ key: "boolValue"
+ value: {bool_value: true}
+ }
+ fields: {
+ key: "doubleValue"
+ value: {number_value: 1234.5678}
+ }
+ fields: {
+ key: "stringValue"
+ value: {string_value: "Hello world!"}
+ }
+ fields: {
+ key: "listValue"
+ value: {
+ list_value: {
+ values: {
+ number_value: 1234
+ }
+ values: {
+ string_value: "5678"
+ }
+ }
+ }
+ }
+ fields: {
+ key: "objectValue"
+ value: {
+ struct_value: {
+ fields: {
+ key: "value"
+ value: {
+ number_value: 0
+ }
+ }
+ }
+ }
+ }
+ }
+ )");
+ // Value
+ RunValidJsonTest(
+ "ValueAcceptInteger",
+ R"({"optionalValue": 1})",
+ "optional_value: { number_value: 1}");
+ RunValidJsonTest(
+ "ValueAcceptFloat",
+ R"({"optionalValue": 1.5})",
+ "optional_value: { number_value: 1.5}");
+ RunValidJsonTest(
+ "ValueAcceptBool",
+ R"({"optionalValue": false})",
+ "optional_value: { bool_value: false}");
+ RunValidJsonTest(
+ "ValueAcceptNull",
+ R"({"optionalValue": null})",
+ "optional_value: { null_value: NULL_VALUE}");
+ RunValidJsonTest(
+ "ValueAcceptString",
+ R"({"optionalValue": "hello"})",
+ R"(optional_value: { string_value: "hello"})");
+ RunValidJsonTest(
+ "ValueAcceptList",
+ R"({"optionalValue": [0, "hello"]})",
+ R"(
+ optional_value: {
+ list_value: {
+ values: {
+ number_value: 0
+ }
+ values: {
+ string_value: "hello"
+ }
+ }
+ }
+ )");
+ RunValidJsonTest(
+ "ValueAcceptObject",
+ R"({"optionalValue": {"value": 1}})",
+ R"(
+ optional_value: {
+ struct_value: {
+ fields: {
+ key: "value"
+ value: {
+ number_value: 1
+ }
+ }
+ }
+ }
+ )");
+
+ // Any
+ RunValidJsonTest(
+ "Any",
+ R"({
+ "optionalAny": {
+ "@type": "type.googleapis.com/conformance.TestAllTypes",
+ "optionalInt32": 12345
+ }
+ })",
+ R"(
+ optional_any: {
+ [type.googleapis.com/conformance.TestAllTypes] {
+ optional_int32: 12345
+ }
+ }
+ )");
+ RunValidJsonTest(
+ "AnyNested",
+ R"({
+ "optionalAny": {
+ "@type": "type.googleapis.com/google.protobuf.Any",
+ "value": {
+ "@type": "type.googleapis.com/conformance.TestAllTypes",
+ "optionalInt32": 12345
+ }
+ }
+ })",
+ R"(
+ optional_any: {
+ [type.googleapis.com/google.protobuf.Any] {
+ [type.googleapis.com/conformance.TestAllTypes] {
+ optional_int32: 12345
+ }
+ }
+ }
+ )");
+ // The special "@type" tag is not required to appear first.
+ RunValidJsonTest(
+ "AnyUnorderedTypeTag",
+ R"({
+ "optionalAny": {
+ "optionalInt32": 12345,
+ "@type": "type.googleapis.com/conformance.TestAllTypes"
+ }
+ })",
+ R"(
+ optional_any: {
+ [type.googleapis.com/conformance.TestAllTypes] {
+ optional_int32: 12345
+ }
+ }
+ )");
+ // Well-known types in Any.
+ RunValidJsonTest(
+ "AnyWithInt32ValueWrapper",
+ R"({
+ "optionalAny": {
+ "@type": "type.googleapis.com/google.protobuf.Int32Value",
+ "value": 12345
+ }
+ })",
+ R"(
+ optional_any: {
+ [type.googleapis.com/google.protobuf.Int32Value] {
+ value: 12345
+ }
+ }
+ )");
+ RunValidJsonTest(
+ "AnyWithDuration",
+ R"({
+ "optionalAny": {
+ "@type": "type.googleapis.com/google.protobuf.Duration",
+ "value": "1.5s"
+ }
+ })",
+ R"(
+ optional_any: {
+ [type.googleapis.com/google.protobuf.Duration] {
+ seconds: 1
+ nanos: 500000000
+ }
+ }
+ )");
+ RunValidJsonTest(
+ "AnyWithTimestamp",
+ R"({
+ "optionalAny": {
+ "@type": "type.googleapis.com/google.protobuf.Timestamp",
+ "value": "1970-01-01T00:00:00Z"
+ }
+ })",
+ R"(
+ optional_any: {
+ [type.googleapis.com/google.protobuf.Timestamp] {
+ seconds: 0
+ nanos: 0
+ }
+ }
+ )");
+ RunValidJsonTest(
+ "AnyWithFieldMask",
+ R"({
+ "optionalAny": {
+ "@type": "type.googleapis.com/google.protobuf.FieldMask",
+ "value": "foo,barBaz"
+ }
+ })",
+ R"(
+ optional_any: {
+ [type.googleapis.com/google.protobuf.FieldMask] {
+ paths: ["foo", "bar_baz"]
+ }
+ }
+ )");
+ RunValidJsonTest(
+ "AnyWithStruct",
+ R"({
+ "optionalAny": {
+ "@type": "type.googleapis.com/google.protobuf.Struct",
+ "value": {
+ "foo": 1
+ }
+ }
+ })",
+ R"(
+ optional_any: {
+ [type.googleapis.com/google.protobuf.Struct] {
+ fields: {
+ key: "foo"
+ value: {
+ number_value: 1
+ }
+ }
+ }
+ }
+ )");
+ RunValidJsonTest(
+ "AnyWithValueForJsonObject",
+ R"({
+ "optionalAny": {
+ "@type": "type.googleapis.com/google.protobuf.Value",
+ "value": {
+ "foo": 1
+ }
+ }
+ })",
+ R"(
+ optional_any: {
+ [type.googleapis.com/google.protobuf.Value] {
+ struct_value: {
+ fields: {
+ key: "foo"
+ value: {
+ number_value: 1
+ }
+ }
+ }
+ }
+ }
+ )");
+ RunValidJsonTest(
+ "AnyWithValueForInteger",
+ R"({
+ "optionalAny": {
+ "@type": "type.googleapis.com/google.protobuf.Value",
+ "value": 1
+ }
+ })",
+ R"(
+ optional_any: {
+ [type.googleapis.com/google.protobuf.Value] {
+ number_value: 1
+ }
+ }
+ )");
+
+ bool ok = true;
+ if (!CheckSetEmpty(expected_to_fail_, "nonexistent_tests.txt",
+ "These tests were listed in the failure list, but they "
+ "don't exist. Remove them from the failure list by "
+ "running:\n"
+ " ./update_failure_list.py " + failure_list_filename_ +
+ " --remove nonexistent_tests.txt")) {
+ ok = false;
+ }
+ if (!CheckSetEmpty(unexpected_failing_tests_, "failing_tests.txt",
+ "These tests failed. If they can't be fixed right now, "
+ "you can add them to the failure list so the overall "
+ "suite can succeed. Add them to the failure list by "
+ "running:\n"
+ " ./update_failure_list.py " + failure_list_filename_ +
+ " --add failing_tests.txt")) {
+ ok = false;
+ }
+ if (!CheckSetEmpty(unexpected_succeeding_tests_, "succeeding_tests.txt",
+ "These tests succeeded, even though they were listed in "
+ "the failure list. Remove them from the failure list "
+ "by running:\n"
+ " ./update_failure_list.py " + failure_list_filename_ +
+ " --remove succeeding_tests.txt")) {
+ ok = false;
+ }
if (verbose_) {
- CheckSetEmpty(skipped_,
+ CheckSetEmpty(skipped_, "",
"These tests were skipped (probably because support for some "
"features is not implemented)");
}
diff --git a/conformance/conformance_test.h b/conformance/conformance_test.h
index 9e6cdaee..c9c5213c 100644
--- a/conformance/conformance_test.h
+++ b/conformance/conformance_test.h
@@ -38,14 +38,18 @@
#ifndef CONFORMANCE_CONFORMANCE_TEST_H
#define CONFORMANCE_CONFORMANCE_TEST_H
+#include <functional>
#include <string>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/util/type_resolver.h>
#include <google/protobuf/wire_format_lite.h>
+#include "third_party/jsoncpp/json.h"
+
namespace conformance {
class ConformanceRequest;
class ConformanceResponse;
+class TestAllTypes;
} // namespace conformance
namespace google {
@@ -53,6 +57,8 @@ namespace protobuf {
class ConformanceTestRunner {
public:
+ virtual ~ConformanceTestRunner() {}
+
// Call to run a single conformance test.
//
// "input" is a serialized conformance.ConformanceRequest.
@@ -60,7 +66,9 @@ class ConformanceTestRunner {
//
// If there is any error in running the test itself, set "runtime_error" in
// the response.
- virtual void RunTest(const std::string& input, std::string* output) = 0;
+ virtual void RunTest(const std::string& test_name,
+ const std::string& input,
+ std::string* output) = 0;
};
// Class representing the test suite itself. To run it, implement your own
@@ -90,7 +98,11 @@ class ConformanceTestSuite {
// Sets the list of tests that are expected to fail when RunSuite() is called.
// RunSuite() will fail unless the set of failing tests is exactly the same
// as this list.
- void SetFailureList(const std::vector<std::string>& failure_list);
+ //
+ // The filename here is *only* used to create/format useful error messages for
+ // how to update the failure list. We do NOT read this file at all.
+ void SetFailureList(const std::string& filename,
+ const std::vector<std::string>& failure_list);
// Run all the conformance tests against the given test runner.
// Test output will be stored in "output".
@@ -118,17 +130,31 @@ class ConformanceTestSuite {
conformance::WireFormat requested_output);
void RunValidJsonTest(const string& test_name, const string& input_json,
const string& equivalent_text_format);
+ void RunValidJsonTestWithProtobufInput(const string& test_name,
+ const conformance::TestAllTypes& input,
+ const string& equivalent_text_format);
+
+ typedef std::function<bool(const Json::Value&)> Validator;
+ void RunValidJsonTestWithValidator(const string& test_name,
+ const string& input_json,
+ const Validator& validator);
+ void ExpectParseFailureForJson(const string& test_name,
+ const string& input_json);
+ void ExpectSerializeFailureForJson(const string& test_name,
+ const string& text_format);
void ExpectParseFailureForProto(const std::string& proto,
const std::string& test_name);
void ExpectHardParseFailureForProto(const std::string& proto,
const std::string& test_name);
void TestPrematureEOFForType(google::protobuf::FieldDescriptor::Type type);
- bool CheckSetEmpty(const set<string>& set_to_check, const char* msg);
+ bool CheckSetEmpty(const set<string>& set_to_check,
+ const std::string& write_to_file, const std::string& msg);
ConformanceTestRunner* runner_;
int successes_;
int expected_failures_;
bool verbose_;
std::string output_;
+ std::string failure_list_filename_;
// The set of test names that are expected to fail in this run, but haven't
// failed yet.
diff --git a/conformance/conformance_test_runner.cc b/conformance/conformance_test_runner.cc
index c3b3db22..d6b1175c 100644
--- a/conformance/conformance_test_runner.cc
+++ b/conformance/conformance_test_runner.cc
@@ -53,17 +53,23 @@
// 3. testee sends 4-byte length M (little endian)
// 4. testee sends M bytes representing a ConformanceResponse proto
+#include <algorithm>
#include <errno.h>
-#include <unistd.h>
#include <fstream>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
#include <vector>
+#include <google/protobuf/stubs/stringprintf.h>
+
#include "conformance.pb.h"
#include "conformance_test.h"
using conformance::ConformanceRequest;
using conformance::ConformanceResponse;
using google::protobuf::internal::scoped_array;
+using google::protobuf::StringAppendF;
using std::string;
using std::vector;
@@ -80,17 +86,47 @@ using std::vector;
class ForkPipeRunner : public google::protobuf::ConformanceTestRunner {
public:
ForkPipeRunner(const std::string &executable)
- : executable_(executable), running_(false) {}
+ : child_pid_(-1), executable_(executable) {}
- void RunTest(const std::string& request, std::string* response) {
- if (!running_) {
+ virtual ~ForkPipeRunner() {}
+
+ void RunTest(const std::string& test_name,
+ const std::string& request,
+ std::string* response) {
+ if (child_pid_ < 0) {
SpawnTestProgram();
}
+ current_test_name_ = test_name;
+
uint32_t len = request.size();
CheckedWrite(write_fd_, &len, sizeof(uint32_t));
CheckedWrite(write_fd_, request.c_str(), request.size());
- CheckedRead(read_fd_, &len, sizeof(uint32_t));
+
+ if (!TryRead(read_fd_, &len, sizeof(uint32_t))) {
+ // We failed to read from the child, assume a crash and try to reap.
+ GOOGLE_LOG(INFO) << "Trying to reap child, pid=" << child_pid_;
+
+ int status;
+ waitpid(child_pid_, &status, WEXITED);
+
+ string error_msg;
+ if (WIFEXITED(status)) {
+ StringAppendF(&error_msg,
+ "child exited, status=%d", WEXITSTATUS(status));
+ } else if (WIFSIGNALED(status)) {
+ StringAppendF(&error_msg,
+ "child killed by signal %d", WTERMSIG(status));
+ }
+ GOOGLE_LOG(INFO) << error_msg;
+ child_pid_ = -1;
+
+ conformance::ConformanceResponse response_obj;
+ response_obj.set_runtime_error(error_msg);
+ response_obj.SerializeToString(response);
+ return;
+ }
+
response->resize(len);
CheckedRead(read_fd_, (void*)response->c_str(), len);
}
@@ -134,7 +170,7 @@ class ForkPipeRunner : public google::protobuf::ConformanceTestRunner {
CHECK_SYSCALL(close(fromproc_pipe_fd[1]));
write_fd_ = toproc_pipe_fd[1];
read_fd_ = fromproc_pipe_fd[0];
- running_ = true;
+ child_pid_ = pid;
} else {
// Child.
CHECK_SYSCALL(close(STDIN_FILENO));
@@ -158,30 +194,48 @@ class ForkPipeRunner : public google::protobuf::ConformanceTestRunner {
void CheckedWrite(int fd, const void *buf, size_t len) {
if (write(fd, buf, len) != len) {
- GOOGLE_LOG(FATAL) << "Error writing to test program: " << strerror(errno);
+ GOOGLE_LOG(FATAL) << current_test_name_
+ << ": error writing to test program: "
+ << strerror(errno);
}
}
- void CheckedRead(int fd, void *buf, size_t len) {
+ bool TryRead(int fd, void *buf, size_t len) {
size_t ofs = 0;
while (len > 0) {
ssize_t bytes_read = read(fd, (char*)buf + ofs, len);
if (bytes_read == 0) {
- GOOGLE_LOG(FATAL) << "Unexpected EOF from test program";
+ GOOGLE_LOG(ERROR) << current_test_name_
+ << ": unexpected EOF from test program";
+ return false;
} else if (bytes_read < 0) {
- GOOGLE_LOG(FATAL) << "Error reading from test program: " << strerror(errno);
+ GOOGLE_LOG(ERROR) << current_test_name_
+ << ": error reading from test program: "
+ << strerror(errno);
+ return false;
}
len -= bytes_read;
ofs += bytes_read;
}
+
+ return true;
+ }
+
+ void CheckedRead(int fd, void *buf, size_t len) {
+ if (!TryRead(fd, buf, len)) {
+ GOOGLE_LOG(FATAL) << current_test_name_
+ << ": error reading from test program: "
+ << strerror(errno);
+ }
}
int write_fd_;
int read_fd_;
- bool running_;
+ pid_t child_pid_;
std::string executable_;
+ std::string current_test_name_;
};
void UsageError() {
@@ -223,16 +277,17 @@ void ParseFailureList(const char *filename, vector<string>* failure_list) {
}
int main(int argc, char *argv[]) {
- int arg = 1;
char *program;
google::protobuf::ConformanceTestSuite suite;
+ string failure_list_filename;
+ vector<string> failure_list;
+
for (int arg = 1; arg < argc; ++arg) {
if (strcmp(argv[arg], "--failure_list") == 0) {
if (++arg == argc) UsageError();
- vector<string> failure_list;
+ failure_list_filename = argv[arg];
ParseFailureList(argv[arg], &failure_list);
- suite.SetFailureList(failure_list);
} else if (strcmp(argv[arg], "--verbose") == 0) {
suite.SetVerbose(true);
} else if (argv[arg][0] == '-') {
@@ -247,6 +302,7 @@ int main(int argc, char *argv[]) {
}
}
+ suite.SetFailureList(failure_list_filename, failure_list);
ForkPipeRunner runner(program);
std::string output;
diff --git a/conformance/failure_list_cpp.txt b/conformance/failure_list_cpp.txt
index 53d90c99..839e5210 100644
--- a/conformance/failure_list_cpp.txt
+++ b/conformance/failure_list_cpp.txt
@@ -7,6 +7,33 @@
# TODO(haberman): insert links to corresponding bugs tracking the issue.
# Should we use GitHub issues or the Google-internal bug tracker?
+FieldMaskNumbersDontRoundTrip.JsonOutput
+FieldMaskPathsDontRoundTrip.JsonOutput
+FieldMaskTooManyUnderscore.JsonOutput
+JsonInput.AnyUnorderedTypeTag.JsonOutput
+JsonInput.AnyUnorderedTypeTag.ProtobufOutput
+JsonInput.BoolFieldDoubleQuotedFalse
+JsonInput.BoolFieldDoubleQuotedTrue
+JsonInput.BytesFieldNoPadding
+JsonInput.DoubleFieldTooSmall
+JsonInput.DurationHasZeroFractionalDigit.Validator
+JsonInput.EnumFieldUnknownValue.Validator
+JsonInput.FieldMaskInvalidCharacter
+JsonInput.FieldNameDuplicate
+JsonInput.FieldNameDuplicateDifferentCasing1
+JsonInput.FieldNameDuplicateDifferentCasing2
+JsonInput.FieldNameInLowerCamelCase.Validator
+JsonInput.FieldNameInSnakeCase.JsonOutput
+JsonInput.FieldNameInSnakeCase.ProtobufOutput
+JsonInput.FieldNameNotQuoted
+JsonInput.MapFieldValueIsNull
+JsonInput.RepeatedFieldMessageElementIsNull
+JsonInput.RepeatedFieldPrimitiveElementIsNull
+JsonInput.RepeatedFieldTrailingComma
+JsonInput.StringFieldUppercaseEscapeLetter
+JsonInput.TrailingCommaInAnObject
+JsonInput.WrapperTypesWithNullValue.JsonOutput
+JsonInput.WrapperTypesWithNullValue.ProtobufOutput
ProtobufInput.PrematureEofBeforeKnownRepeatedValue.MESSAGE
ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE
ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE
diff --git a/conformance/failure_list_csharp.txt b/conformance/failure_list_csharp.txt
index e69de29b..1716bcbd 100644
--- a/conformance/failure_list_csharp.txt
+++ b/conformance/failure_list_csharp.txt
@@ -0,0 +1,7 @@
+JsonInput.FieldNameInLowerCamelCase.Validator
+JsonInput.FieldNameInSnakeCase.JsonOutput
+JsonInput.FieldNameInSnakeCase.ProtobufOutput
+JsonInput.FieldNameWithMixedCases.JsonOutput
+JsonInput.FieldNameWithMixedCases.ProtobufOutput
+JsonInput.FieldNameWithMixedCases.Validator
+JsonInput.OriginalProtoFieldName.JsonOutput
diff --git a/conformance/failure_list_java.txt b/conformance/failure_list_java.txt
new file mode 100644
index 00000000..850712bd
--- /dev/null
+++ b/conformance/failure_list_java.txt
@@ -0,0 +1,43 @@
+# This is the list of conformance tests that are known to fail for the Java
+# implementation right now. These should be fixed.
+#
+# By listing them here we can keep tabs on which ones are failing and be sure
+# that we don't introduce regressions in other tests.
+
+FieldMaskNumbersDontRoundTrip.JsonOutput
+FieldMaskPathsDontRoundTrip.JsonOutput
+FieldMaskTooManyUnderscore.JsonOutput
+JsonInput.BoolFieldAllCapitalFalse
+JsonInput.BoolFieldAllCapitalTrue
+JsonInput.BoolFieldCamelCaseFalse
+JsonInput.BoolFieldCamelCaseTrue
+JsonInput.BoolFieldDoubleQuotedFalse
+JsonInput.BoolFieldDoubleQuotedTrue
+JsonInput.BoolMapFieldKeyNotQuoted
+JsonInput.DoubleFieldInfinityNotQuoted
+JsonInput.DoubleFieldNanNotQuoted
+JsonInput.DoubleFieldNegativeInfinityNotQuoted
+JsonInput.EnumFieldNotQuoted
+JsonInput.FieldMaskInvalidCharacter
+JsonInput.FieldNameDuplicate
+JsonInput.FieldNameInSnakeCase.JsonOutput
+JsonInput.FieldNameNotQuoted
+JsonInput.FloatFieldInfinityNotQuoted
+JsonInput.FloatFieldNanNotQuoted
+JsonInput.FloatFieldNegativeInfinityNotQuoted
+JsonInput.Int32FieldLeadingZero
+JsonInput.Int32FieldNegativeWithLeadingZero
+JsonInput.Int32FieldPlusSign
+JsonInput.Int32MapFieldKeyNotQuoted
+JsonInput.Int64MapFieldKeyNotQuoted
+JsonInput.JsonWithComments
+JsonInput.OriginalProtoFieldName.JsonOutput
+JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotBool
+JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotInt
+JsonInput.StringFieldNotAString
+JsonInput.StringFieldSurrogateInWrongOrder
+JsonInput.StringFieldUnpairedHighSurrogate
+JsonInput.StringFieldUnpairedLowSurrogate
+JsonInput.StringFieldUppercaseEscapeLetter
+JsonInput.Uint32MapFieldKeyNotQuoted
+JsonInput.Uint64MapFieldKeyNotQuoted
diff --git a/conformance/failure_list_objc.txt b/conformance/failure_list_objc.txt
index f53230ca..5dac3501 100644
--- a/conformance/failure_list_objc.txt
+++ b/conformance/failure_list_objc.txt
@@ -1 +1,4 @@
# No tests currently failing.
+#
+# json input or output tests are skipped (in conformance_objc.m) as mobile
+# platforms don't support json wire format to avoid code bloat.
diff --git a/conformance/failure_list_python-post26.txt b/conformance/failure_list_python-post26.txt
new file mode 100644
index 00000000..19d99b04
--- /dev/null
+++ b/conformance/failure_list_python-post26.txt
@@ -0,0 +1,2 @@
+JsonInput.StringFieldSurrogateInWrongOrder
+JsonInput.StringFieldUnpairedHighSurrogate
diff --git a/conformance/failure_list_python.txt b/conformance/failure_list_python.txt
index e69de29b..550a043f 100644
--- a/conformance/failure_list_python.txt
+++ b/conformance/failure_list_python.txt
@@ -0,0 +1,47 @@
+DurationProtoInputTooLarge.JsonOutput
+DurationProtoInputTooSmall.JsonOutput
+FieldMaskNumbersDontRoundTrip.JsonOutput
+FieldMaskPathsDontRoundTrip.JsonOutput
+FieldMaskTooManyUnderscore.JsonOutput
+JsonInput.AnyWithFieldMask.ProtobufOutput
+JsonInput.BytesFieldInvalidBase64Characters
+JsonInput.DoubleFieldInfinityNotQuoted
+JsonInput.DoubleFieldNanNotQuoted
+JsonInput.DoubleFieldNegativeInfinityNotQuoted
+JsonInput.DoubleFieldTooSmall
+JsonInput.DurationJsonInputTooLarge
+JsonInput.DurationJsonInputTooSmall
+JsonInput.DurationMissingS
+JsonInput.EnumFieldNumericValueNonZero.JsonOutput
+JsonInput.EnumFieldNumericValueNonZero.ProtobufOutput
+JsonInput.EnumFieldNumericValueZero.JsonOutput
+JsonInput.EnumFieldNumericValueZero.ProtobufOutput
+JsonInput.EnumFieldUnknownValue.Validator
+JsonInput.FieldMask.ProtobufOutput
+JsonInput.FieldMaskInvalidCharacter
+JsonInput.FieldNameInLowerCamelCase.Validator
+JsonInput.FieldNameInSnakeCase.JsonOutput
+JsonInput.FieldNameInSnakeCase.ProtobufOutput
+JsonInput.FloatFieldInfinityNotQuoted
+JsonInput.FloatFieldNanNotQuoted
+JsonInput.FloatFieldNegativeInfinityNotQuoted
+JsonInput.FloatFieldTooLarge
+JsonInput.FloatFieldTooSmall
+JsonInput.Int32FieldExponentialFormat.JsonOutput
+JsonInput.Int32FieldExponentialFormat.ProtobufOutput
+JsonInput.Int32FieldFloatTrailingZero.JsonOutput
+JsonInput.Int32FieldFloatTrailingZero.ProtobufOutput
+JsonInput.Int32FieldMaxFloatValue.JsonOutput
+JsonInput.Int32FieldMaxFloatValue.ProtobufOutput
+JsonInput.Int32FieldMinFloatValue.JsonOutput
+JsonInput.Int32FieldMinFloatValue.ProtobufOutput
+JsonInput.OriginalProtoFieldName.JsonOutput
+JsonInput.OriginalProtoFieldName.ProtobufOutput
+JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotBool
+JsonInput.TimestampJsonInputLowercaseT
+JsonInput.Uint32FieldMaxFloatValue.JsonOutput
+JsonInput.Uint32FieldMaxFloatValue.ProtobufOutput
+JsonInput.ValueAcceptNull.JsonOutput
+JsonInput.ValueAcceptNull.ProtobufOutput
+TimestampProtoInputTooLarge.JsonOutput
+TimestampProtoInputTooSmall.JsonOutput
diff --git a/conformance/failure_list_python_cpp.txt b/conformance/failure_list_python_cpp.txt
index 4b16a88b..1eb916ab 100644
--- a/conformance/failure_list_python_cpp.txt
+++ b/conformance/failure_list_python_cpp.txt
@@ -7,6 +7,51 @@
# TODO(haberman): insert links to corresponding bugs tracking the issue.
# Should we use GitHub issues or the Google-internal bug tracker?
+DurationProtoInputTooLarge.JsonOutput
+DurationProtoInputTooSmall.JsonOutput
+FieldMaskNumbersDontRoundTrip.JsonOutput
+FieldMaskPathsDontRoundTrip.JsonOutput
+FieldMaskTooManyUnderscore.JsonOutput
+JsonInput.AnyWithFieldMask.ProtobufOutput
+JsonInput.BytesFieldInvalidBase64Characters
+JsonInput.DoubleFieldInfinityNotQuoted
+JsonInput.DoubleFieldNanNotQuoted
+JsonInput.DoubleFieldNegativeInfinityNotQuoted
+JsonInput.DoubleFieldTooSmall
+JsonInput.DurationJsonInputTooLarge
+JsonInput.DurationJsonInputTooSmall
+JsonInput.DurationMissingS
+JsonInput.EnumFieldNumericValueNonZero.JsonOutput
+JsonInput.EnumFieldNumericValueNonZero.ProtobufOutput
+JsonInput.EnumFieldNumericValueZero.JsonOutput
+JsonInput.EnumFieldNumericValueZero.ProtobufOutput
+JsonInput.EnumFieldUnknownValue.Validator
+JsonInput.FieldMask.ProtobufOutput
+JsonInput.FieldMaskInvalidCharacter
+JsonInput.FieldNameInLowerCamelCase.Validator
+JsonInput.FieldNameInSnakeCase.JsonOutput
+JsonInput.FieldNameInSnakeCase.ProtobufOutput
+JsonInput.FloatFieldInfinityNotQuoted
+JsonInput.FloatFieldNanNotQuoted
+JsonInput.FloatFieldNegativeInfinityNotQuoted
+JsonInput.FloatFieldTooLarge
+JsonInput.FloatFieldTooSmall
+JsonInput.Int32FieldExponentialFormat.JsonOutput
+JsonInput.Int32FieldExponentialFormat.ProtobufOutput
+JsonInput.Int32FieldFloatTrailingZero.JsonOutput
+JsonInput.Int32FieldFloatTrailingZero.ProtobufOutput
+JsonInput.Int32FieldMaxFloatValue.JsonOutput
+JsonInput.Int32FieldMaxFloatValue.ProtobufOutput
+JsonInput.Int32FieldMinFloatValue.JsonOutput
+JsonInput.Int32FieldMinFloatValue.ProtobufOutput
+JsonInput.OriginalProtoFieldName.JsonOutput
+JsonInput.OriginalProtoFieldName.ProtobufOutput
+JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotBool
+JsonInput.TimestampJsonInputLowercaseT
+JsonInput.Uint32FieldMaxFloatValue.JsonOutput
+JsonInput.Uint32FieldMaxFloatValue.ProtobufOutput
+JsonInput.ValueAcceptNull.JsonOutput
+JsonInput.ValueAcceptNull.ProtobufOutput
ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE
ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE
ProtobufInput.PrematureEofInPackedField.BOOL
@@ -23,3 +68,5 @@ ProtobufInput.PrematureEofInPackedField.SINT32
ProtobufInput.PrematureEofInPackedField.SINT64
ProtobufInput.PrematureEofInPackedField.UINT32
ProtobufInput.PrematureEofInPackedField.UINT64
+TimestampProtoInputTooLarge.JsonOutput
+TimestampProtoInputTooSmall.JsonOutput
diff --git a/conformance/failure_list_ruby.txt b/conformance/failure_list_ruby.txt
index ff220cb9..7c12da06 100644
--- a/conformance/failure_list_ruby.txt
+++ b/conformance/failure_list_ruby.txt
@@ -1,2 +1,199 @@
-JsonInput.HelloWorld.JsonOutput
-JsonInput.HelloWorld.ProtobufOutput
+DurationProtoInputTooLarge.JsonOutput
+DurationProtoInputTooSmall.JsonOutput
+FieldMaskNumbersDontRoundTrip.JsonOutput
+FieldMaskPathsDontRoundTrip.JsonOutput
+FieldMaskTooManyUnderscore.JsonOutput
+JsonInput.Any.JsonOutput
+JsonInput.Any.ProtobufOutput
+JsonInput.AnyNested.JsonOutput
+JsonInput.AnyNested.ProtobufOutput
+JsonInput.AnyUnorderedTypeTag.JsonOutput
+JsonInput.AnyUnorderedTypeTag.ProtobufOutput
+JsonInput.AnyWithDuration.JsonOutput
+JsonInput.AnyWithDuration.ProtobufOutput
+JsonInput.AnyWithFieldMask.JsonOutput
+JsonInput.AnyWithFieldMask.ProtobufOutput
+JsonInput.AnyWithInt32ValueWrapper.JsonOutput
+JsonInput.AnyWithInt32ValueWrapper.ProtobufOutput
+JsonInput.AnyWithStruct.JsonOutput
+JsonInput.AnyWithStruct.ProtobufOutput
+JsonInput.AnyWithTimestamp.JsonOutput
+JsonInput.AnyWithTimestamp.ProtobufOutput
+JsonInput.AnyWithValueForInteger.JsonOutput
+JsonInput.AnyWithValueForInteger.ProtobufOutput
+JsonInput.AnyWithValueForJsonObject.JsonOutput
+JsonInput.AnyWithValueForJsonObject.ProtobufOutput
+JsonInput.BoolFieldIntegerOne
+JsonInput.BoolFieldIntegerZero
+JsonInput.DoubleFieldInfinity.JsonOutput
+JsonInput.DoubleFieldInfinity.ProtobufOutput
+JsonInput.DoubleFieldMaxNegativeValue.JsonOutput
+JsonInput.DoubleFieldMaxNegativeValue.ProtobufOutput
+JsonInput.DoubleFieldMaxPositiveValue.JsonOutput
+JsonInput.DoubleFieldMaxPositiveValue.ProtobufOutput
+JsonInput.DoubleFieldMinNegativeValue.JsonOutput
+JsonInput.DoubleFieldMinNegativeValue.ProtobufOutput
+JsonInput.DoubleFieldMinPositiveValue.JsonOutput
+JsonInput.DoubleFieldMinPositiveValue.ProtobufOutput
+JsonInput.DoubleFieldNan.JsonOutput
+JsonInput.DoubleFieldNan.ProtobufOutput
+JsonInput.DoubleFieldNegativeInfinity.JsonOutput
+JsonInput.DoubleFieldNegativeInfinity.ProtobufOutput
+JsonInput.DoubleFieldQuotedValue.JsonOutput
+JsonInput.DoubleFieldQuotedValue.ProtobufOutput
+JsonInput.DurationHas3FractionalDigits.Validator
+JsonInput.DurationHas6FractionalDigits.Validator
+JsonInput.DurationHas9FractionalDigits.Validator
+JsonInput.DurationHasZeroFractionalDigit.Validator
+JsonInput.DurationMaxValue.JsonOutput
+JsonInput.DurationMaxValue.ProtobufOutput
+JsonInput.DurationMinValue.JsonOutput
+JsonInput.DurationMinValue.ProtobufOutput
+JsonInput.DurationRepeatedValue.JsonOutput
+JsonInput.DurationRepeatedValue.ProtobufOutput
+JsonInput.EnumFieldNumericValueNonZero.JsonOutput
+JsonInput.EnumFieldNumericValueNonZero.ProtobufOutput
+JsonInput.EnumFieldNumericValueZero.JsonOutput
+JsonInput.EnumFieldNumericValueZero.ProtobufOutput
+JsonInput.EnumFieldUnknownValue.Validator
+JsonInput.FieldMask.JsonOutput
+JsonInput.FieldMask.ProtobufOutput
+JsonInput.FieldNameInSnakeCase.JsonOutput
+JsonInput.FieldNameWithMixedCases.JsonOutput
+JsonInput.FieldNameWithMixedCases.ProtobufOutput
+JsonInput.FieldNameWithMixedCases.Validator
+JsonInput.FloatFieldInfinity.JsonOutput
+JsonInput.FloatFieldInfinity.ProtobufOutput
+JsonInput.FloatFieldNan.JsonOutput
+JsonInput.FloatFieldNan.ProtobufOutput
+JsonInput.FloatFieldNegativeInfinity.JsonOutput
+JsonInput.FloatFieldNegativeInfinity.ProtobufOutput
+JsonInput.FloatFieldQuotedValue.JsonOutput
+JsonInput.FloatFieldQuotedValue.ProtobufOutput
+JsonInput.FloatFieldTooLarge
+JsonInput.FloatFieldTooSmall
+JsonInput.Int32FieldExponentialFormat.JsonOutput
+JsonInput.Int32FieldExponentialFormat.ProtobufOutput
+JsonInput.Int32FieldFloatTrailingZero.JsonOutput
+JsonInput.Int32FieldFloatTrailingZero.ProtobufOutput
+JsonInput.Int32FieldMaxFloatValue.JsonOutput
+JsonInput.Int32FieldMaxFloatValue.ProtobufOutput
+JsonInput.Int32FieldMinFloatValue.JsonOutput
+JsonInput.Int32FieldMinFloatValue.ProtobufOutput
+JsonInput.Int32FieldStringValue.JsonOutput
+JsonInput.Int32FieldStringValue.ProtobufOutput
+JsonInput.Int32FieldStringValueEscaped.JsonOutput
+JsonInput.Int32FieldStringValueEscaped.ProtobufOutput
+JsonInput.Int32MapEscapedKey.JsonOutput
+JsonInput.Int32MapEscapedKey.ProtobufOutput
+JsonInput.Int32MapField.JsonOutput
+JsonInput.Int32MapField.ProtobufOutput
+JsonInput.Int64FieldBeString.Validator
+JsonInput.Int64FieldMaxValue.JsonOutput
+JsonInput.Int64FieldMaxValue.ProtobufOutput
+JsonInput.Int64FieldMinValue.JsonOutput
+JsonInput.Int64FieldMinValue.ProtobufOutput
+JsonInput.Int64MapEscapedKey.JsonOutput
+JsonInput.Int64MapEscapedKey.ProtobufOutput
+JsonInput.Int64MapField.JsonOutput
+JsonInput.Int64MapField.ProtobufOutput
+JsonInput.MessageField.JsonOutput
+JsonInput.MessageField.ProtobufOutput
+JsonInput.MessageMapField.JsonOutput
+JsonInput.MessageMapField.ProtobufOutput
+JsonInput.MessageRepeatedField.JsonOutput
+JsonInput.MessageRepeatedField.ProtobufOutput
+JsonInput.OptionalBoolWrapper.JsonOutput
+JsonInput.OptionalBoolWrapper.ProtobufOutput
+JsonInput.OptionalBytesWrapper.JsonOutput
+JsonInput.OptionalBytesWrapper.ProtobufOutput
+JsonInput.OptionalDoubleWrapper.JsonOutput
+JsonInput.OptionalDoubleWrapper.ProtobufOutput
+JsonInput.OptionalFloatWrapper.JsonOutput
+JsonInput.OptionalFloatWrapper.ProtobufOutput
+JsonInput.OptionalInt32Wrapper.JsonOutput
+JsonInput.OptionalInt32Wrapper.ProtobufOutput
+JsonInput.OptionalInt64Wrapper.JsonOutput
+JsonInput.OptionalInt64Wrapper.ProtobufOutput
+JsonInput.OptionalStringWrapper.JsonOutput
+JsonInput.OptionalStringWrapper.ProtobufOutput
+JsonInput.OptionalUint32Wrapper.JsonOutput
+JsonInput.OptionalUint32Wrapper.ProtobufOutput
+JsonInput.OptionalUint64Wrapper.JsonOutput
+JsonInput.OptionalUint64Wrapper.ProtobufOutput
+JsonInput.OptionalWrapperTypesWithNonDefaultValue.JsonOutput
+JsonInput.OptionalWrapperTypesWithNonDefaultValue.ProtobufOutput
+JsonInput.OriginalProtoFieldName.JsonOutput
+JsonInput.PrimitiveRepeatedField.JsonOutput
+JsonInput.PrimitiveRepeatedField.ProtobufOutput
+JsonInput.RepeatedBoolWrapper.JsonOutput
+JsonInput.RepeatedBoolWrapper.ProtobufOutput
+JsonInput.RepeatedBytesWrapper.JsonOutput
+JsonInput.RepeatedBytesWrapper.ProtobufOutput
+JsonInput.RepeatedDoubleWrapper.JsonOutput
+JsonInput.RepeatedDoubleWrapper.ProtobufOutput
+JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotInt
+JsonInput.RepeatedFloatWrapper.JsonOutput
+JsonInput.RepeatedFloatWrapper.ProtobufOutput
+JsonInput.RepeatedInt32Wrapper.JsonOutput
+JsonInput.RepeatedInt32Wrapper.ProtobufOutput
+JsonInput.RepeatedInt64Wrapper.JsonOutput
+JsonInput.RepeatedInt64Wrapper.ProtobufOutput
+JsonInput.RepeatedStringWrapper.JsonOutput
+JsonInput.RepeatedStringWrapper.ProtobufOutput
+JsonInput.RepeatedUint32Wrapper.JsonOutput
+JsonInput.RepeatedUint32Wrapper.ProtobufOutput
+JsonInput.RepeatedUint64Wrapper.JsonOutput
+JsonInput.RepeatedUint64Wrapper.ProtobufOutput
+JsonInput.StringFieldNotAString
+JsonInput.StringFieldSurrogateInWrongOrder
+JsonInput.StringFieldSurrogatePair.JsonOutput
+JsonInput.StringFieldSurrogatePair.ProtobufOutput
+JsonInput.StringFieldUnpairedHighSurrogate
+JsonInput.StringFieldUnpairedLowSurrogate
+JsonInput.Struct.JsonOutput
+JsonInput.Struct.ProtobufOutput
+JsonInput.TimestampHas3FractionalDigits.Validator
+JsonInput.TimestampHas6FractionalDigits.Validator
+JsonInput.TimestampHas9FractionalDigits.Validator
+JsonInput.TimestampHasZeroFractionalDigit.Validator
+JsonInput.TimestampMaxValue.JsonOutput
+JsonInput.TimestampMaxValue.ProtobufOutput
+JsonInput.TimestampMinValue.JsonOutput
+JsonInput.TimestampMinValue.ProtobufOutput
+JsonInput.TimestampRepeatedValue.JsonOutput
+JsonInput.TimestampRepeatedValue.ProtobufOutput
+JsonInput.TimestampWithNegativeOffset.JsonOutput
+JsonInput.TimestampWithNegativeOffset.ProtobufOutput
+JsonInput.TimestampWithPositiveOffset.JsonOutput
+JsonInput.TimestampWithPositiveOffset.ProtobufOutput
+JsonInput.TimestampZeroNormalized.Validator
+JsonInput.Uint32FieldMaxFloatValue.JsonOutput
+JsonInput.Uint32FieldMaxFloatValue.ProtobufOutput
+JsonInput.Uint32MapField.JsonOutput
+JsonInput.Uint32MapField.ProtobufOutput
+JsonInput.Uint64FieldBeString.Validator
+JsonInput.Uint64FieldMaxValue.JsonOutput
+JsonInput.Uint64FieldMaxValue.ProtobufOutput
+JsonInput.Uint64MapField.JsonOutput
+JsonInput.Uint64MapField.ProtobufOutput
+JsonInput.ValueAcceptBool.JsonOutput
+JsonInput.ValueAcceptBool.ProtobufOutput
+JsonInput.ValueAcceptFloat.JsonOutput
+JsonInput.ValueAcceptFloat.ProtobufOutput
+JsonInput.ValueAcceptInteger.JsonOutput
+JsonInput.ValueAcceptInteger.ProtobufOutput
+JsonInput.ValueAcceptList.JsonOutput
+JsonInput.ValueAcceptList.ProtobufOutput
+JsonInput.ValueAcceptNull.JsonOutput
+JsonInput.ValueAcceptNull.ProtobufOutput
+JsonInput.ValueAcceptObject.JsonOutput
+JsonInput.ValueAcceptObject.ProtobufOutput
+JsonInput.ValueAcceptString.JsonOutput
+JsonInput.ValueAcceptString.ProtobufOutput
+ProtobufInput.DoubleFieldNormalizeQuietNan.JsonOutput
+ProtobufInput.DoubleFieldNormalizeSignalingNan.JsonOutput
+ProtobufInput.FloatFieldNormalizeQuietNan.JsonOutput
+ProtobufInput.FloatFieldNormalizeSignalingNan.JsonOutput
+TimestampProtoInputTooLarge.JsonOutput
+TimestampProtoInputTooSmall.JsonOutput
diff --git a/conformance/third_party/jsoncpp/json.h b/conformance/third_party/jsoncpp/json.h
new file mode 100644
index 00000000..42e7e7f4
--- /dev/null
+++ b/conformance/third_party/jsoncpp/json.h
@@ -0,0 +1,2075 @@
+/// Json-cpp amalgated header (http://jsoncpp.sourceforge.net/).
+/// It is intended to be used with #include "json/json.h"
+
+// //////////////////////////////////////////////////////////////////////
+// Beginning of content of file: LICENSE
+// //////////////////////////////////////////////////////////////////////
+
+/*
+The JsonCpp library's source code, including accompanying documentation,
+tests and demonstration applications, are licensed under the following
+conditions...
+
+The author (Baptiste Lepilleur) explicitly disclaims copyright in all
+jurisdictions which recognize such a disclaimer. In such jurisdictions,
+this software is released into the Public Domain.
+
+In jurisdictions which do not recognize Public Domain property (e.g. Germany as of
+2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur, and is
+released under the terms of the MIT License (see below).
+
+In jurisdictions which recognize Public Domain property, the user of this
+software may choose to accept it either as 1) Public Domain, 2) under the
+conditions of the MIT License (see below), or 3) under the terms of dual
+Public Domain/MIT License conditions described here, as they choose.
+
+The MIT License is about as close to Public Domain as a license can get, and is
+described in clear, concise terms at:
+
+ http://en.wikipedia.org/wiki/MIT_License
+
+The full text of the MIT License follows:
+
+========================================================================
+Copyright (c) 2007-2010 Baptiste Lepilleur
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use, copy,
+modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+========================================================================
+(END LICENSE TEXT)
+
+The MIT license is compatible with both the GPL and commercial
+software, affording one all of the rights of Public Domain with the
+minor nuisance of being required to keep the above copyright notice
+and license text in the source code. Note also that by accepting the
+Public Domain "license" you can re-license your copy using whatever
+license you like.
+
+*/
+
+// //////////////////////////////////////////////////////////////////////
+// End of content of file: LICENSE
+// //////////////////////////////////////////////////////////////////////
+
+
+
+
+
+#ifndef JSON_AMALGATED_H_INCLUDED
+# define JSON_AMALGATED_H_INCLUDED
+/// If defined, indicates that the source file is amalgated
+/// to prevent private header inclusion.
+#define JSON_IS_AMALGAMATION
+
+// //////////////////////////////////////////////////////////////////////
+// Beginning of content of file: include/json/version.h
+// //////////////////////////////////////////////////////////////////////
+
+// DO NOT EDIT. This file (and "version") is generated by CMake.
+// Run CMake configure step to update it.
+#ifndef JSON_VERSION_H_INCLUDED
+# define JSON_VERSION_H_INCLUDED
+
+# define JSONCPP_VERSION_STRING "1.6.5"
+# define JSONCPP_VERSION_MAJOR 1
+# define JSONCPP_VERSION_MINOR 6
+# define JSONCPP_VERSION_PATCH 5
+# define JSONCPP_VERSION_QUALIFIER
+# define JSONCPP_VERSION_HEXA ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | (JSONCPP_VERSION_PATCH << 8))
+
+#endif // JSON_VERSION_H_INCLUDED
+
+// //////////////////////////////////////////////////////////////////////
+// End of content of file: include/json/version.h
+// //////////////////////////////////////////////////////////////////////
+
+
+
+
+
+
+// //////////////////////////////////////////////////////////////////////
+// Beginning of content of file: include/json/config.h
+// //////////////////////////////////////////////////////////////////////
+
+// Copyright 2007-2010 Baptiste Lepilleur
+// Distributed under MIT license, or public domain if desired and
+// recognized in your jurisdiction.
+// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
+
+#ifndef JSON_CONFIG_H_INCLUDED
+#define JSON_CONFIG_H_INCLUDED
+
+/// If defined, indicates that json library is embedded in CppTL library.
+//# define JSON_IN_CPPTL 1
+
+/// If defined, indicates that json may leverage CppTL library
+//# define JSON_USE_CPPTL 1
+/// If defined, indicates that cpptl vector based map should be used instead of
+/// std::map
+/// as Value container.
+//# define JSON_USE_CPPTL_SMALLMAP 1
+
+// If non-zero, the library uses exceptions to report bad input instead of C
+// assertion macros. The default is to use exceptions.
+#ifndef JSON_USE_EXCEPTION
+#define JSON_USE_EXCEPTION 1
+#endif
+
+/// If defined, indicates that the source file is amalgated
+/// to prevent private header inclusion.
+/// Remarks: it is automatically defined in the generated amalgated header.
+// #define JSON_IS_AMALGAMATION
+
+#ifdef JSON_IN_CPPTL
+#include <cpptl/config.h>
+#ifndef JSON_USE_CPPTL
+#define JSON_USE_CPPTL 1
+#endif
+#endif
+
+#ifdef JSON_IN_CPPTL
+#define JSON_API CPPTL_API
+#elif defined(JSON_DLL_BUILD)
+#if defined(_MSC_VER)
+#define JSON_API __declspec(dllexport)
+#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING
+#endif // if defined(_MSC_VER)
+#elif defined(JSON_DLL)
+#if defined(_MSC_VER)
+#define JSON_API __declspec(dllimport)
+#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING
+#endif // if defined(_MSC_VER)
+#endif // ifdef JSON_IN_CPPTL
+#if !defined(JSON_API)
+#define JSON_API
+#endif
+
+// If JSON_NO_INT64 is defined, then Json only support C++ "int" type for
+// integer
+// Storages, and 64 bits integer support is disabled.
+// #define JSON_NO_INT64 1
+
+#if defined(_MSC_VER) // MSVC
+# if _MSC_VER <= 1200 // MSVC 6
+ // Microsoft Visual Studio 6 only support conversion from __int64 to double
+ // (no conversion from unsigned __int64).
+# define JSON_USE_INT64_DOUBLE_CONVERSION 1
+ // Disable warning 4786 for VS6 caused by STL (identifier was truncated to '255'
+ // characters in the debug information)
+ // All projects I've ever seen with VS6 were using this globally (not bothering
+ // with pragma push/pop).
+# pragma warning(disable : 4786)
+# endif // MSVC 6
+
+# if _MSC_VER >= 1500 // MSVC 2008
+ /// Indicates that the following function is deprecated.
+# define JSONCPP_DEPRECATED(message) __declspec(deprecated(message))
+# endif
+
+#endif // defined(_MSC_VER)
+
+
+#ifndef JSON_HAS_RVALUE_REFERENCES
+
+#if defined(_MSC_VER) && _MSC_VER >= 1600 // MSVC >= 2010
+#define JSON_HAS_RVALUE_REFERENCES 1
+#endif // MSVC >= 2010
+
+#ifdef __clang__
+#if __has_feature(cxx_rvalue_references)
+#define JSON_HAS_RVALUE_REFERENCES 1
+#endif // has_feature
+
+#elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc)
+#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L)
+#define JSON_HAS_RVALUE_REFERENCES 1
+#endif // GXX_EXPERIMENTAL
+
+#endif // __clang__ || __GNUC__
+
+#endif // not defined JSON_HAS_RVALUE_REFERENCES
+
+#ifndef JSON_HAS_RVALUE_REFERENCES
+#define JSON_HAS_RVALUE_REFERENCES 0
+#endif
+
+#ifdef __clang__
+#elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc)
+# if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
+# define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message)))
+# elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
+# define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__))
+# endif // GNUC version
+#endif // __clang__ || __GNUC__
+
+#if !defined(JSONCPP_DEPRECATED)
+#define JSONCPP_DEPRECATED(message)
+#endif // if !defined(JSONCPP_DEPRECATED)
+
+namespace Json {
+typedef int Int;
+typedef unsigned int UInt;
+#if defined(JSON_NO_INT64)
+typedef int LargestInt;
+typedef unsigned int LargestUInt;
+#undef JSON_HAS_INT64
+#else // if defined(JSON_NO_INT64)
+// For Microsoft Visual use specific types as long long is not supported
+#if defined(_MSC_VER) // Microsoft Visual Studio
+typedef __int64 Int64;
+typedef unsigned __int64 UInt64;
+#else // if defined(_MSC_VER) // Other platforms, use long long
+typedef long long int Int64;
+typedef unsigned long long int UInt64;
+#endif // if defined(_MSC_VER)
+typedef Int64 LargestInt;
+typedef UInt64 LargestUInt;
+#define JSON_HAS_INT64
+#endif // if defined(JSON_NO_INT64)
+} // end namespace Json
+
+#endif // JSON_CONFIG_H_INCLUDED
+
+// //////////////////////////////////////////////////////////////////////
+// End of content of file: include/json/config.h
+// //////////////////////////////////////////////////////////////////////
+
+
+
+
+
+
+// //////////////////////////////////////////////////////////////////////
+// Beginning of content of file: include/json/forwards.h
+// //////////////////////////////////////////////////////////////////////
+
+// Copyright 2007-2010 Baptiste Lepilleur
+// Distributed under MIT license, or public domain if desired and
+// recognized in your jurisdiction.
+// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
+
+#ifndef JSON_FORWARDS_H_INCLUDED
+#define JSON_FORWARDS_H_INCLUDED
+
+#if !defined(JSON_IS_AMALGAMATION)
+#include "config.h"
+#endif // if !defined(JSON_IS_AMALGAMATION)
+
+namespace Json {
+
+// writer.h
+class FastWriter;
+class StyledWriter;
+
+// reader.h
+class Reader;
+
+// features.h
+class Features;
+
+// value.h
+typedef unsigned int ArrayIndex;
+class StaticString;
+class Path;
+class PathArgument;
+class Value;
+class ValueIteratorBase;
+class ValueIterator;
+class ValueConstIterator;
+
+} // namespace Json
+
+#endif // JSON_FORWARDS_H_INCLUDED
+
+// //////////////////////////////////////////////////////////////////////
+// End of content of file: include/json/forwards.h
+// //////////////////////////////////////////////////////////////////////
+
+
+
+
+
+
+// //////////////////////////////////////////////////////////////////////
+// Beginning of content of file: include/json/features.h
+// //////////////////////////////////////////////////////////////////////
+
+// Copyright 2007-2010 Baptiste Lepilleur
+// Distributed under MIT license, or public domain if desired and
+// recognized in your jurisdiction.
+// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
+
+#ifndef CPPTL_JSON_FEATURES_H_INCLUDED
+#define CPPTL_JSON_FEATURES_H_INCLUDED
+
+#if !defined(JSON_IS_AMALGAMATION)
+#include "forwards.h"
+#endif // if !defined(JSON_IS_AMALGAMATION)
+
+namespace Json {
+
+/** \brief Configuration passed to reader and writer.
+ * This configuration object can be used to force the Reader or Writer
+ * to behave in a standard conforming way.
+ */
+class JSON_API Features {
+public:
+ /** \brief A configuration that allows all features and assumes all strings
+ * are UTF-8.
+ * - C & C++ comments are allowed
+ * - Root object can be any JSON value
+ * - Assumes Value strings are encoded in UTF-8
+ */
+ static Features all();
+
+ /** \brief A configuration that is strictly compatible with the JSON
+ * specification.
+ * - Comments are forbidden.
+ * - Root object must be either an array or an object value.
+ * - Assumes Value strings are encoded in UTF-8
+ */
+ static Features strictMode();
+
+ /** \brief Initialize the configuration like JsonConfig::allFeatures;
+ */
+ Features();
+
+ /// \c true if comments are allowed. Default: \c true.
+ bool allowComments_;
+
+ /// \c true if root must be either an array or an object value. Default: \c
+ /// false.
+ bool strictRoot_;
+
+ /// \c true if dropped null placeholders are allowed. Default: \c false.
+ bool allowDroppedNullPlaceholders_;
+
+ /// \c true if numeric object key are allowed. Default: \c false.
+ bool allowNumericKeys_;
+};
+
+} // namespace Json
+
+#endif // CPPTL_JSON_FEATURES_H_INCLUDED
+
+// //////////////////////////////////////////////////////////////////////
+// End of content of file: include/json/features.h
+// //////////////////////////////////////////////////////////////////////
+
+
+
+
+
+
+// //////////////////////////////////////////////////////////////////////
+// Beginning of content of file: include/json/value.h
+// //////////////////////////////////////////////////////////////////////
+
+// Copyright 2007-2010 Baptiste Lepilleur
+// Distributed under MIT license, or public domain if desired and
+// recognized in your jurisdiction.
+// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
+
+#ifndef CPPTL_JSON_H_INCLUDED
+#define CPPTL_JSON_H_INCLUDED
+
+#if !defined(JSON_IS_AMALGAMATION)
+#include "forwards.h"
+#endif // if !defined(JSON_IS_AMALGAMATION)
+#include <string>
+#include <vector>
+#include <exception>
+
+#ifndef JSON_USE_CPPTL_SMALLMAP
+#include <map>
+#else
+#include <cpptl/smallmap.h>
+#endif
+#ifdef JSON_USE_CPPTL
+#include <cpptl/forwards.h>
+#endif
+
+// Disable warning C4251: <data member>: <type> needs to have dll-interface to
+// be used by...
+#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
+#pragma warning(push)
+#pragma warning(disable : 4251)
+#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
+
+/** \brief JSON (JavaScript Object Notation).
+ */
+namespace Json {
+
+/** Base class for all exceptions we throw.
+ *
+ * We use nothing but these internally. Of course, STL can throw others.
+ */
+class JSON_API Exception : public std::exception {
+public:
+ Exception(std::string const& msg);
+ ~Exception() throw() override;
+ char const* what() const throw() override;
+protected:
+ std::string msg_;
+};
+
+/** Exceptions which the user cannot easily avoid.
+ *
+ * E.g. out-of-memory (when we use malloc), stack-overflow, malicious input
+ *
+ * \remark derived from Json::Exception
+ */
+class JSON_API RuntimeError : public Exception {
+public:
+ RuntimeError(std::string const& msg);
+};
+
+/** Exceptions thrown by JSON_ASSERT/JSON_FAIL macros.
+ *
+ * These are precondition-violations (user bugs) and internal errors (our bugs).
+ *
+ * \remark derived from Json::Exception
+ */
+class JSON_API LogicError : public Exception {
+public:
+ LogicError(std::string const& msg);
+};
+
+/// used internally
+void throwRuntimeError(std::string const& msg);
+/// used internally
+void throwLogicError(std::string const& msg);
+
+/** \brief Type of the value held by a Value object.
+ */
+enum ValueType {
+ nullValue = 0, ///< 'null' value
+ intValue, ///< signed integer value
+ uintValue, ///< unsigned integer value
+ realValue, ///< double value
+ stringValue, ///< UTF-8 string value
+ booleanValue, ///< bool value
+ arrayValue, ///< array value (ordered list)
+ objectValue ///< object value (collection of name/value pairs).
+};
+
+enum CommentPlacement {
+ commentBefore = 0, ///< a comment placed on the line before a value
+ commentAfterOnSameLine, ///< a comment just after a value on the same line
+ commentAfter, ///< a comment on the line after a value (only make sense for
+ /// root value)
+ numberOfCommentPlacement
+};
+
+//# ifdef JSON_USE_CPPTL
+// typedef CppTL::AnyEnumerator<const char *> EnumMemberNames;
+// typedef CppTL::AnyEnumerator<const Value &> EnumValues;
+//# endif
+
+/** \brief Lightweight wrapper to tag static string.
+ *
+ * Value constructor and objectValue member assignement takes advantage of the
+ * StaticString and avoid the cost of string duplication when storing the
+ * string or the member name.
+ *
+ * Example of usage:
+ * \code
+ * Json::Value aValue( StaticString("some text") );
+ * Json::Value object;
+ * static const StaticString code("code");
+ * object[code] = 1234;
+ * \endcode
+ */
+class JSON_API StaticString {
+public:
+ explicit StaticString(const char* czstring) : c_str_(czstring) {}
+
+ operator const char*() const { return c_str_; }
+
+ const char* c_str() const { return c_str_; }
+
+private:
+ const char* c_str_;
+};
+
+/** \brief Represents a <a HREF="http://www.json.org">JSON</a> value.
+ *
+ * This class is a discriminated union wrapper that can represents a:
+ * - signed integer [range: Value::minInt - Value::maxInt]
+ * - unsigned integer (range: 0 - Value::maxUInt)
+ * - double
+ * - UTF-8 string
+ * - boolean
+ * - 'null'
+ * - an ordered list of Value
+ * - collection of name/value pairs (javascript object)
+ *
+ * The type of the held value is represented by a #ValueType and
+ * can be obtained using type().
+ *
+ * Values of an #objectValue or #arrayValue can be accessed using operator[]()
+ * methods.
+ * Non-const methods will automatically create the a #nullValue element
+ * if it does not exist.
+ * The sequence of an #arrayValue will be automatically resized and initialized
+ * with #nullValue. resize() can be used to enlarge or truncate an #arrayValue.
+ *
+ * The get() methods can be used to obtain default value in the case the
+ * required element does not exist.
+ *
+ * It is possible to iterate over the list of a #objectValue values using
+ * the getMemberNames() method.
+ *
+ * \note #Value string-length fit in size_t, but keys must be < 2^30.
+ * (The reason is an implementation detail.) A #CharReader will raise an
+ * exception if a bound is exceeded to avoid security holes in your app,
+ * but the Value API does *not* check bounds. That is the responsibility
+ * of the caller.
+ */
+class JSON_API Value {
+ friend class ValueIteratorBase;
+public:
+ typedef std::vector<std::string> Members;
+ typedef ValueIterator iterator;
+ typedef ValueConstIterator const_iterator;
+ typedef Json::UInt UInt;
+ typedef Json::Int Int;
+#if defined(JSON_HAS_INT64)
+ typedef Json::UInt64 UInt64;
+ typedef Json::Int64 Int64;
+#endif // defined(JSON_HAS_INT64)
+ typedef Json::LargestInt LargestInt;
+ typedef Json::LargestUInt LargestUInt;
+ typedef Json::ArrayIndex ArrayIndex;
+
+ static const Value& null; ///< We regret this reference to a global instance; prefer the simpler Value().
+ static const Value& nullRef; ///< just a kludge for binary-compatibility; same as null
+ /// Minimum signed integer value that can be stored in a Json::Value.
+ static const LargestInt minLargestInt;
+ /// Maximum signed integer value that can be stored in a Json::Value.
+ static const LargestInt maxLargestInt;
+ /// Maximum unsigned integer value that can be stored in a Json::Value.
+ static const LargestUInt maxLargestUInt;
+
+ /// Minimum signed int value that can be stored in a Json::Value.
+ static const Int minInt;
+ /// Maximum signed int value that can be stored in a Json::Value.
+ static const Int maxInt;
+ /// Maximum unsigned int value that can be stored in a Json::Value.
+ static const UInt maxUInt;
+
+#if defined(JSON_HAS_INT64)
+ /// Minimum signed 64 bits int value that can be stored in a Json::Value.
+ static const Int64 minInt64;
+ /// Maximum signed 64 bits int value that can be stored in a Json::Value.
+ static const Int64 maxInt64;
+ /// Maximum unsigned 64 bits int value that can be stored in a Json::Value.
+ static const UInt64 maxUInt64;
+#endif // defined(JSON_HAS_INT64)
+
+private:
+#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
+ class CZString {
+ public:
+ enum DuplicationPolicy {
+ noDuplication = 0,
+ duplicate,
+ duplicateOnCopy
+ };
+ CZString(ArrayIndex index);
+ CZString(char const* str, unsigned length, DuplicationPolicy allocate);
+ CZString(CZString const& other);
+#if JSON_HAS_RVALUE_REFERENCES
+ CZString(CZString&& other);
+#endif
+ ~CZString();
+ CZString& operator=(CZString other);
+ bool operator<(CZString const& other) const;
+ bool operator==(CZString const& other) const;
+ ArrayIndex index() const;
+ //const char* c_str() const; ///< \deprecated
+ char const* data() const;
+ unsigned length() const;
+ bool isStaticString() const;
+
+ private:
+ void swap(CZString& other);
+
+ struct StringStorage {
+ unsigned policy_: 2;
+ unsigned length_: 30; // 1GB max
+ };
+
+ char const* cstr_; // actually, a prefixed string, unless policy is noDup
+ union {
+ ArrayIndex index_;
+ StringStorage storage_;
+ };
+ };
+
+public:
+#ifndef JSON_USE_CPPTL_SMALLMAP
+ typedef std::map<CZString, Value> ObjectValues;
+#else
+ typedef CppTL::SmallMap<CZString, Value> ObjectValues;
+#endif // ifndef JSON_USE_CPPTL_SMALLMAP
+#endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
+
+public:
+ /** \brief Create a default Value of the given type.
+
+ This is a very useful constructor.
+ To create an empty array, pass arrayValue.
+ To create an empty object, pass objectValue.
+ Another Value can then be set to this one by assignment.
+This is useful since clear() and resize() will not alter types.
+
+ Examples:
+\code
+Json::Value null_value; // null
+Json::Value arr_value(Json::arrayValue); // []
+Json::Value obj_value(Json::objectValue); // {}
+\endcode
+ */
+ Value(ValueType type = nullValue);
+ Value(Int value);
+ Value(UInt value);
+#if defined(JSON_HAS_INT64)
+ Value(Int64 value);
+ Value(UInt64 value);
+#endif // if defined(JSON_HAS_INT64)
+ Value(double value);
+ Value(const char* value); ///< Copy til first 0. (NULL causes to seg-fault.)
+ Value(const char* begin, const char* end); ///< Copy all, incl zeroes.
+ /** \brief Constructs a value from a static string.
+
+ * Like other value string constructor but do not duplicate the string for
+ * internal storage. The given string must remain alive after the call to this
+ * constructor.
+ * \note This works only for null-terminated strings. (We cannot change the
+ * size of this class, so we have nowhere to store the length,
+ * which might be computed later for various operations.)
+ *
+ * Example of usage:
+ * \code
+ * static StaticString foo("some text");
+ * Json::Value aValue(foo);
+ * \endcode
+ */
+ Value(const StaticString& value);
+ Value(const std::string& value); ///< Copy data() til size(). Embedded zeroes too.
+#ifdef JSON_USE_CPPTL
+ Value(const CppTL::ConstString& value);
+#endif
+ Value(bool value);
+ /// Deep copy.
+ Value(const Value& other);
+#if JSON_HAS_RVALUE_REFERENCES
+ /// Move constructor
+ Value(Value&& other);
+#endif
+ ~Value();
+
+ /// Deep copy, then swap(other).
+ /// \note Over-write existing comments. To preserve comments, use #swapPayload().
+ Value& operator=(Value other);
+ /// Swap everything.
+ void swap(Value& other);
+ /// Swap values but leave comments and source offsets in place.
+ void swapPayload(Value& other);
+
+ ValueType type() const;
+
+ /// Compare payload only, not comments etc.
+ bool operator<(const Value& other) const;
+ bool operator<=(const Value& other) const;
+ bool operator>=(const Value& other) const;
+ bool operator>(const Value& other) const;
+ bool operator==(const Value& other) const;
+ bool operator!=(const Value& other) const;
+ int compare(const Value& other) const;
+
+ const char* asCString() const; ///< Embedded zeroes could cause you trouble!
+ std::string asString() const; ///< Embedded zeroes are possible.
+ /** Get raw char* of string-value.
+ * \return false if !string. (Seg-fault if str or end are NULL.)
+ */
+ bool getString(
+ char const** begin, char const** end) const;
+#ifdef JSON_USE_CPPTL
+ CppTL::ConstString asConstString() const;
+#endif
+ Int asInt() const;
+ UInt asUInt() const;
+#if defined(JSON_HAS_INT64)
+ Int64 asInt64() const;
+ UInt64 asUInt64() const;
+#endif // if defined(JSON_HAS_INT64)
+ LargestInt asLargestInt() const;
+ LargestUInt asLargestUInt() const;
+ float asFloat() const;
+ double asDouble() const;
+ bool asBool() const;
+
+ bool isNull() const;
+ bool isBool() const;
+ bool isInt() const;
+ bool isInt64() const;
+ bool isUInt() const;
+ bool isUInt64() const;
+ bool isIntegral() const;
+ bool isDouble() const;
+ bool isNumeric() const;
+ bool isString() const;
+ bool isArray() const;
+ bool isObject() const;
+
+ bool isConvertibleTo(ValueType other) const;
+
+ /// Number of values in array or object
+ ArrayIndex size() const;
+
+ /// \brief Return true if empty array, empty object, or null;
+ /// otherwise, false.
+ bool empty() const;
+
+ /// Return isNull()
+ bool operator!() const;
+
+ /// Remove all object members and array elements.
+ /// \pre type() is arrayValue, objectValue, or nullValue
+ /// \post type() is unchanged
+ void clear();
+
+ /// Resize the array to size elements.
+ /// New elements are initialized to null.
+ /// May only be called on nullValue or arrayValue.
+ /// \pre type() is arrayValue or nullValue
+ /// \post type() is arrayValue
+ void resize(ArrayIndex size);
+
+ /// Access an array element (zero based index ).
+ /// If the array contains less than index element, then null value are
+ /// inserted
+ /// in the array so that its size is index+1.
+ /// (You may need to say 'value[0u]' to get your compiler to distinguish
+ /// this from the operator[] which takes a string.)
+ Value& operator[](ArrayIndex index);
+
+ /// Access an array element (zero based index ).
+ /// If the array contains less than index element, then null value are
+ /// inserted
+ /// in the array so that its size is index+1.
+ /// (You may need to say 'value[0u]' to get your compiler to distinguish
+ /// this from the operator[] which takes a string.)
+ Value& operator[](int index);
+
+ /// Access an array element (zero based index )
+ /// (You may need to say 'value[0u]' to get your compiler to distinguish
+ /// this from the operator[] which takes a string.)
+ const Value& operator[](ArrayIndex index) const;
+
+ /// Access an array element (zero based index )
+ /// (You may need to say 'value[0u]' to get your compiler to distinguish
+ /// this from the operator[] which takes a string.)
+ const Value& operator[](int index) const;
+
+ /// If the array contains at least index+1 elements, returns the element
+ /// value,
+ /// otherwise returns defaultValue.
+ Value get(ArrayIndex index, const Value& defaultValue) const;
+ /// Return true if index < size().
+ bool isValidIndex(ArrayIndex index) const;
+ /// \brief Append value to array at the end.
+ ///
+ /// Equivalent to jsonvalue[jsonvalue.size()] = value;
+ Value& append(const Value& value);
+
+ /// Access an object value by name, create a null member if it does not exist.
+ /// \note Because of our implementation, keys are limited to 2^30 -1 chars.
+ /// Exceeding that will cause an exception.
+ Value& operator[](const char* key);
+ /// Access an object value by name, returns null if there is no member with
+ /// that name.
+ const Value& operator[](const char* key) const;
+ /// Access an object value by name, create a null member if it does not exist.
+ /// \param key may contain embedded nulls.
+ Value& operator[](const std::string& key);
+ /// Access an object value by name, returns null if there is no member with
+ /// that name.
+ /// \param key may contain embedded nulls.
+ const Value& operator[](const std::string& key) const;
+ /** \brief Access an object value by name, create a null member if it does not
+ exist.
+
+ * If the object has no entry for that name, then the member name used to store
+ * the new entry is not duplicated.
+ * Example of use:
+ * \code
+ * Json::Value object;
+ * static const StaticString code("code");
+ * object[code] = 1234;
+ * \endcode
+ */
+ Value& operator[](const StaticString& key);
+#ifdef JSON_USE_CPPTL
+ /// Access an object value by name, create a null member if it does not exist.
+ Value& operator[](const CppTL::ConstString& key);
+ /// Access an object value by name, returns null if there is no member with
+ /// that name.
+ const Value& operator[](const CppTL::ConstString& key) const;
+#endif
+ /// Return the member named key if it exist, defaultValue otherwise.
+ /// \note deep copy
+ Value get(const char* key, const Value& defaultValue) const;
+ /// Return the member named key if it exist, defaultValue otherwise.
+ /// \note deep copy
+ /// \note key may contain embedded nulls.
+ Value get(const char* begin, const char* end, const Value& defaultValue) const;
+ /// Return the member named key if it exist, defaultValue otherwise.
+ /// \note deep copy
+ /// \param key may contain embedded nulls.
+ Value get(const std::string& key, const Value& defaultValue) const;
+#ifdef JSON_USE_CPPTL
+ /// Return the member named key if it exist, defaultValue otherwise.
+ /// \note deep copy
+ Value get(const CppTL::ConstString& key, const Value& defaultValue) const;
+#endif
+ /// Most general and efficient version of isMember()const, get()const,
+ /// and operator[]const
+ /// \note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30
+ Value const* find(char const* begin, char const* end) const;
+ /// Most general and efficient version of object-mutators.
+ /// \note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30
+ /// \return non-zero, but JSON_ASSERT if this is neither object nor nullValue.
+ Value const* demand(char const* begin, char const* end);
+ /// \brief Remove and return the named member.
+ ///
+ /// Do nothing if it did not exist.
+ /// \return the removed Value, or null.
+ /// \pre type() is objectValue or nullValue
+ /// \post type() is unchanged
+ /// \deprecated
+ Value removeMember(const char* key);
+ /// Same as removeMember(const char*)
+ /// \param key may contain embedded nulls.
+ /// \deprecated
+ Value removeMember(const std::string& key);
+ /// Same as removeMember(const char* begin, const char* end, Value* removed),
+ /// but 'key' is null-terminated.
+ bool removeMember(const char* key, Value* removed);
+ /** \brief Remove the named map member.
+
+ Update 'removed' iff removed.
+ \param key may contain embedded nulls.
+ \return true iff removed (no exceptions)
+ */
+ bool removeMember(std::string const& key, Value* removed);
+ /// Same as removeMember(std::string const& key, Value* removed)
+ bool removeMember(const char* begin, const char* end, Value* removed);
+ /** \brief Remove the indexed array element.
+
+ O(n) expensive operations.
+ Update 'removed' iff removed.
+ \return true iff removed (no exceptions)
+ */
+ bool removeIndex(ArrayIndex i, Value* removed);
+
+ /// Return true if the object has a member named key.
+ /// \note 'key' must be null-terminated.
+ bool isMember(const char* key) const;
+ /// Return true if the object has a member named key.
+ /// \param key may contain embedded nulls.
+ bool isMember(const std::string& key) const;
+ /// Same as isMember(std::string const& key)const
+ bool isMember(const char* begin, const char* end) const;
+#ifdef JSON_USE_CPPTL
+ /// Return true if the object has a member named key.
+ bool isMember(const CppTL::ConstString& key) const;
+#endif
+
+ /// \brief Return a list of the member names.
+ ///
+ /// If null, return an empty list.
+ /// \pre type() is objectValue or nullValue
+ /// \post if type() was nullValue, it remains nullValue
+ Members getMemberNames() const;
+
+ //# ifdef JSON_USE_CPPTL
+ // EnumMemberNames enumMemberNames() const;
+ // EnumValues enumValues() const;
+ //# endif
+
+ /// \deprecated Always pass len.
+ JSONCPP_DEPRECATED("Use setComment(std::string const&) instead.")
+ void setComment(const char* comment, CommentPlacement placement);
+ /// Comments must be //... or /* ... */
+ void setComment(const char* comment, size_t len, CommentPlacement placement);
+ /// Comments must be //... or /* ... */
+ void setComment(const std::string& comment, CommentPlacement placement);
+ bool hasComment(CommentPlacement placement) const;
+ /// Include delimiters and embedded newlines.
+ std::string getComment(CommentPlacement placement) const;
+
+ std::string toStyledString() const;
+
+ const_iterator begin() const;
+ const_iterator end() const;
+
+ iterator begin();
+ iterator end();
+
+ // Accessors for the [start, limit) range of bytes within the JSON text from
+ // which this value was parsed, if any.
+ void setOffsetStart(size_t start);
+ void setOffsetLimit(size_t limit);
+ size_t getOffsetStart() const;
+ size_t getOffsetLimit() const;
+
+private:
+ void initBasic(ValueType type, bool allocated = false);
+
+ Value& resolveReference(const char* key);
+ Value& resolveReference(const char* key, const char* end);
+
+ struct CommentInfo {
+ CommentInfo();
+ ~CommentInfo();
+
+ void setComment(const char* text, size_t len);
+
+ char* comment_;
+ };
+
+ // struct MemberNamesTransform
+ //{
+ // typedef const char *result_type;
+ // const char *operator()( const CZString &name ) const
+ // {
+ // return name.c_str();
+ // }
+ //};
+
+ union ValueHolder {
+ LargestInt int_;
+ LargestUInt uint_;
+ double real_;
+ bool bool_;
+ char* string_; // actually ptr to unsigned, followed by str, unless !allocated_
+ ObjectValues* map_;
+ } value_;
+ ValueType type_ : 8;
+ unsigned int allocated_ : 1; // Notes: if declared as bool, bitfield is useless.
+ // If not allocated_, string_ must be null-terminated.
+ CommentInfo* comments_;
+
+ // [start, limit) byte offsets in the source JSON text from which this Value
+ // was extracted.
+ size_t start_;
+ size_t limit_;
+};
+
+/** \brief Experimental and untested: represents an element of the "path" to
+ * access a node.
+ */
+class JSON_API PathArgument {
+public:
+ friend class Path;
+
+ PathArgument();
+ PathArgument(ArrayIndex index);
+ PathArgument(const char* key);
+ PathArgument(const std::string& key);
+
+private:
+ enum Kind {
+ kindNone = 0,
+ kindIndex,
+ kindKey
+ };
+ std::string key_;
+ ArrayIndex index_;
+ Kind kind_;
+};
+
+/** \brief Experimental and untested: represents a "path" to access a node.
+ *
+ * Syntax:
+ * - "." => root node
+ * - ".[n]" => elements at index 'n' of root node (an array value)
+ * - ".name" => member named 'name' of root node (an object value)
+ * - ".name1.name2.name3"
+ * - ".[0][1][2].name1[3]"
+ * - ".%" => member name is provided as parameter
+ * - ".[%]" => index is provied as parameter
+ */
+class JSON_API Path {
+public:
+ Path(const std::string& path,
+ const PathArgument& a1 = PathArgument(),
+ const PathArgument& a2 = PathArgument(),
+ const PathArgument& a3 = PathArgument(),
+ const PathArgument& a4 = PathArgument(),
+ const PathArgument& a5 = PathArgument());
+
+ const Value& resolve(const Value& root) const;
+ Value resolve(const Value& root, const Value& defaultValue) const;
+ /// Creates the "path" to access the specified node and returns a reference on
+ /// the node.
+ Value& make(Value& root) const;
+
+private:
+ typedef std::vector<const PathArgument*> InArgs;
+ typedef std::vector<PathArgument> Args;
+
+ void makePath(const std::string& path, const InArgs& in);
+ void addPathInArg(const std::string& path,
+ const InArgs& in,
+ InArgs::const_iterator& itInArg,
+ PathArgument::Kind kind);
+ void invalidPath(const std::string& path, int location);
+
+ Args args_;
+};
+
+/** \brief base class for Value iterators.
+ *
+ */
+class JSON_API ValueIteratorBase {
+public:
+ typedef std::bidirectional_iterator_tag iterator_category;
+ typedef unsigned int size_t;
+ typedef int difference_type;
+ typedef ValueIteratorBase SelfType;
+
+ bool operator==(const SelfType& other) const { return isEqual(other); }
+
+ bool operator!=(const SelfType& other) const { return !isEqual(other); }
+
+ difference_type operator-(const SelfType& other) const {
+ return other.computeDistance(*this);
+ }
+
+ /// Return either the index or the member name of the referenced value as a
+ /// Value.
+ Value key() const;
+
+ /// Return the index of the referenced Value, or -1 if it is not an arrayValue.
+ UInt index() const;
+
+ /// Return the member name of the referenced Value, or "" if it is not an
+ /// objectValue.
+ /// \note Avoid `c_str()` on result, as embedded zeroes are possible.
+ std::string name() const;
+
+ /// Return the member name of the referenced Value. "" if it is not an
+ /// objectValue.
+ /// \deprecated This cannot be used for UTF-8 strings, since there can be embedded nulls.
+ JSONCPP_DEPRECATED("Use `key = name();` instead.")
+ char const* memberName() const;
+ /// Return the member name of the referenced Value, or NULL if it is not an
+ /// objectValue.
+ /// \note Better version than memberName(). Allows embedded nulls.
+ char const* memberName(char const** end) const;
+
+protected:
+ Value& deref() const;
+
+ void increment();
+
+ void decrement();
+
+ difference_type computeDistance(const SelfType& other) const;
+
+ bool isEqual(const SelfType& other) const;
+
+ void copy(const SelfType& other);
+
+private:
+ Value::ObjectValues::iterator current_;
+ // Indicates that iterator is for a null value.
+ bool isNull_;
+
+public:
+ // For some reason, BORLAND needs these at the end, rather
+ // than earlier. No idea why.
+ ValueIteratorBase();
+ explicit ValueIteratorBase(const Value::ObjectValues::iterator& current);
+};
+
+/** \brief const iterator for object and array value.
+ *
+ */
+class JSON_API ValueConstIterator : public ValueIteratorBase {
+ friend class Value;
+
+public:
+ typedef const Value value_type;
+ //typedef unsigned int size_t;
+ //typedef int difference_type;
+ typedef const Value& reference;
+ typedef const Value* pointer;
+ typedef ValueConstIterator SelfType;
+
+ ValueConstIterator();
+ ValueConstIterator(ValueIterator const& other);
+
+private:
+/*! \internal Use by Value to create an iterator.
+ */
+ explicit ValueConstIterator(const Value::ObjectValues::iterator& current);
+public:
+ SelfType& operator=(const ValueIteratorBase& other);
+
+ SelfType operator++(int) {
+ SelfType temp(*this);
+ ++*this;
+ return temp;
+ }
+
+ SelfType operator--(int) {
+ SelfType temp(*this);
+ --*this;
+ return temp;
+ }
+
+ SelfType& operator--() {
+ decrement();
+ return *this;
+ }
+
+ SelfType& operator++() {
+ increment();
+ return *this;
+ }
+
+ reference operator*() const { return deref(); }
+
+ pointer operator->() const { return &deref(); }
+};
+
+/** \brief Iterator for object and array value.
+ */
+class JSON_API ValueIterator : public ValueIteratorBase {
+ friend class Value;
+
+public:
+ typedef Value value_type;
+ typedef unsigned int size_t;
+ typedef int difference_type;
+ typedef Value& reference;
+ typedef Value* pointer;
+ typedef ValueIterator SelfType;
+
+ ValueIterator();
+ explicit ValueIterator(const ValueConstIterator& other);
+ ValueIterator(const ValueIterator& other);
+
+private:
+/*! \internal Use by Value to create an iterator.
+ */
+ explicit ValueIterator(const Value::ObjectValues::iterator& current);
+public:
+ SelfType& operator=(const SelfType& other);
+
+ SelfType operator++(int) {
+ SelfType temp(*this);
+ ++*this;
+ return temp;
+ }
+
+ SelfType operator--(int) {
+ SelfType temp(*this);
+ --*this;
+ return temp;
+ }
+
+ SelfType& operator--() {
+ decrement();
+ return *this;
+ }
+
+ SelfType& operator++() {
+ increment();
+ return *this;
+ }
+
+ reference operator*() const { return deref(); }
+
+ pointer operator->() const { return &deref(); }
+};
+
+} // namespace Json
+
+
+namespace std {
+/// Specialize std::swap() for Json::Value.
+template<>
+inline void swap(Json::Value& a, Json::Value& b) { a.swap(b); }
+}
+
+
+#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
+#pragma warning(pop)
+#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
+
+#endif // CPPTL_JSON_H_INCLUDED
+
+// //////////////////////////////////////////////////////////////////////
+// End of content of file: include/json/value.h
+// //////////////////////////////////////////////////////////////////////
+
+
+
+
+
+
+// //////////////////////////////////////////////////////////////////////
+// Beginning of content of file: include/json/reader.h
+// //////////////////////////////////////////////////////////////////////
+
+// Copyright 2007-2010 Baptiste Lepilleur
+// Distributed under MIT license, or public domain if desired and
+// recognized in your jurisdiction.
+// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
+
+#ifndef CPPTL_JSON_READER_H_INCLUDED
+#define CPPTL_JSON_READER_H_INCLUDED
+
+#if !defined(JSON_IS_AMALGAMATION)
+#include "features.h"
+#include "value.h"
+#endif // if !defined(JSON_IS_AMALGAMATION)
+#include <deque>
+#include <iosfwd>
+#include <stack>
+#include <string>
+#include <istream>
+
+// Disable warning C4251: <data member>: <type> needs to have dll-interface to
+// be used by...
+#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
+#pragma warning(push)
+#pragma warning(disable : 4251)
+#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
+
+namespace Json {
+
+/** \brief Unserialize a <a HREF="http://www.json.org">JSON</a> document into a
+ *Value.
+ *
+ * \deprecated Use CharReader and CharReaderBuilder.
+ */
+class JSON_API Reader {
+public:
+ typedef char Char;
+ typedef const Char* Location;
+
+ /** \brief An error tagged with where in the JSON text it was encountered.
+ *
+ * The offsets give the [start, limit) range of bytes within the text. Note
+ * that this is bytes, not codepoints.
+ *
+ */
+ struct StructuredError {
+ size_t offset_start;
+ size_t offset_limit;
+ std::string message;
+ };
+
+ /** \brief Constructs a Reader allowing all features
+ * for parsing.
+ */
+ Reader();
+
+ /** \brief Constructs a Reader allowing the specified feature set
+ * for parsing.
+ */
+ Reader(const Features& features);
+
+ /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
+ * document.
+ * \param document UTF-8 encoded string containing the document to read.
+ * \param root [out] Contains the root value of the document if it was
+ * successfully parsed.
+ * \param collectComments \c true to collect comment and allow writing them
+ * back during
+ * serialization, \c false to discard comments.
+ * This parameter is ignored if
+ * Features::allowComments_
+ * is \c false.
+ * \return \c true if the document was successfully parsed, \c false if an
+ * error occurred.
+ */
+ bool
+ parse(const std::string& document, Value& root, bool collectComments = true);
+
+ /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
+ document.
+ * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the
+ document to read.
+ * \param endDoc Pointer on the end of the UTF-8 encoded string of the
+ document to read.
+ * Must be >= beginDoc.
+ * \param root [out] Contains the root value of the document if it was
+ * successfully parsed.
+ * \param collectComments \c true to collect comment and allow writing them
+ back during
+ * serialization, \c false to discard comments.
+ * This parameter is ignored if
+ Features::allowComments_
+ * is \c false.
+ * \return \c true if the document was successfully parsed, \c false if an
+ error occurred.
+ */
+ bool parse(const char* beginDoc,
+ const char* endDoc,
+ Value& root,
+ bool collectComments = true);
+
+ /// \brief Parse from input stream.
+ /// \see Json::operator>>(std::istream&, Json::Value&).
+ bool parse(std::istream& is, Value& root, bool collectComments = true);
+
+ /** \brief Returns a user friendly string that list errors in the parsed
+ * document.
+ * \return Formatted error message with the list of errors with their location
+ * in
+ * the parsed document. An empty string is returned if no error
+ * occurred
+ * during parsing.
+ * \deprecated Use getFormattedErrorMessages() instead (typo fix).
+ */
+ JSONCPP_DEPRECATED("Use getFormattedErrorMessages() instead.")
+ std::string getFormatedErrorMessages() const;
+
+ /** \brief Returns a user friendly string that list errors in the parsed
+ * document.
+ * \return Formatted error message with the list of errors with their location
+ * in
+ * the parsed document. An empty string is returned if no error
+ * occurred
+ * during parsing.
+ */
+ std::string getFormattedErrorMessages() const;
+
+ /** \brief Returns a vector of structured erros encounted while parsing.
+ * \return A (possibly empty) vector of StructuredError objects. Currently
+ * only one error can be returned, but the caller should tolerate
+ * multiple
+ * errors. This can occur if the parser recovers from a non-fatal
+ * parse error and then encounters additional errors.
+ */
+ std::vector<StructuredError> getStructuredErrors() const;
+
+ /** \brief Add a semantic error message.
+ * \param value JSON Value location associated with the error
+ * \param message The error message.
+ * \return \c true if the error was successfully added, \c false if the
+ * Value offset exceeds the document size.
+ */
+ bool pushError(const Value& value, const std::string& message);
+
+ /** \brief Add a semantic error message with extra context.
+ * \param value JSON Value location associated with the error
+ * \param message The error message.
+ * \param extra Additional JSON Value location to contextualize the error
+ * \return \c true if the error was successfully added, \c false if either
+ * Value offset exceeds the document size.
+ */
+ bool pushError(const Value& value, const std::string& message, const Value& extra);
+
+ /** \brief Return whether there are any errors.
+ * \return \c true if there are no errors to report \c false if
+ * errors have occurred.
+ */
+ bool good() const;
+
+private:
+ enum TokenType {
+ tokenEndOfStream = 0,
+ tokenObjectBegin,
+ tokenObjectEnd,
+ tokenArrayBegin,
+ tokenArrayEnd,
+ tokenString,
+ tokenNumber,
+ tokenTrue,
+ tokenFalse,
+ tokenNull,
+ tokenArraySeparator,
+ tokenMemberSeparator,
+ tokenComment,
+ tokenError
+ };
+
+ class Token {
+ public:
+ TokenType type_;
+ Location start_;
+ Location end_;
+ };
+
+ class ErrorInfo {
+ public:
+ Token token_;
+ std::string message_;
+ Location extra_;
+ };
+
+ typedef std::deque<ErrorInfo> Errors;
+
+ bool readToken(Token& token);
+ void skipSpaces();
+ bool match(Location pattern, int patternLength);
+ bool readComment();
+ bool readCStyleComment();
+ bool readCppStyleComment();
+ bool readString();
+ void readNumber();
+ bool readValue();
+ bool readObject(Token& token);
+ bool readArray(Token& token);
+ bool decodeNumber(Token& token);
+ bool decodeNumber(Token& token, Value& decoded);
+ bool decodeString(Token& token);
+ bool decodeString(Token& token, std::string& decoded);
+ bool decodeDouble(Token& token);
+ bool decodeDouble(Token& token, Value& decoded);
+ bool decodeUnicodeCodePoint(Token& token,
+ Location& current,
+ Location end,
+ unsigned int& unicode);
+ bool decodeUnicodeEscapeSequence(Token& token,
+ Location& current,
+ Location end,
+ unsigned int& unicode);
+ bool addError(const std::string& message, Token& token, Location extra = 0);
+ bool recoverFromError(TokenType skipUntilToken);
+ bool addErrorAndRecover(const std::string& message,
+ Token& token,
+ TokenType skipUntilToken);
+ void skipUntilSpace();
+ Value& currentValue();
+ Char getNextChar();
+ void
+ getLocationLineAndColumn(Location location, int& line, int& column) const;
+ std::string getLocationLineAndColumn(Location location) const;
+ void addComment(Location begin, Location end, CommentPlacement placement);
+ void skipCommentTokens(Token& token);
+
+ typedef std::stack<Value*> Nodes;
+ Nodes nodes_;
+ Errors errors_;
+ std::string document_;
+ Location begin_;
+ Location end_;
+ Location current_;
+ Location lastValueEnd_;
+ Value* lastValue_;
+ std::string commentsBefore_;
+ Features features_;
+ bool collectComments_;
+}; // Reader
+
+/** Interface for reading JSON from a char array.
+ */
+class JSON_API CharReader {
+public:
+ virtual ~CharReader() {}
+ /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
+ document.
+ * The document must be a UTF-8 encoded string containing the document to read.
+ *
+ * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the
+ document to read.
+ * \param endDoc Pointer on the end of the UTF-8 encoded string of the
+ document to read.
+ * Must be >= beginDoc.
+ * \param root [out] Contains the root value of the document if it was
+ * successfully parsed.
+ * \param errs [out] Formatted error messages (if not NULL)
+ * a user friendly string that lists errors in the parsed
+ * document.
+ * \return \c true if the document was successfully parsed, \c false if an
+ error occurred.
+ */
+ virtual bool parse(
+ char const* beginDoc, char const* endDoc,
+ Value* root, std::string* errs) = 0;
+
+ class JSON_API Factory {
+ public:
+ virtual ~Factory() {}
+ /** \brief Allocate a CharReader via operator new().
+ * \throw std::exception if something goes wrong (e.g. invalid settings)
+ */
+ virtual CharReader* newCharReader() const = 0;
+ }; // Factory
+}; // CharReader
+
+/** \brief Build a CharReader implementation.
+
+Usage:
+\code
+ using namespace Json;
+ CharReaderBuilder builder;
+ builder["collectComments"] = false;
+ Value value;
+ std::string errs;
+ bool ok = parseFromStream(builder, std::cin, &value, &errs);
+\endcode
+*/
+class JSON_API CharReaderBuilder : public CharReader::Factory {
+public:
+ // Note: We use a Json::Value so that we can add data-members to this class
+ // without a major version bump.
+ /** Configuration of this builder.
+ These are case-sensitive.
+ Available settings (case-sensitive):
+ - `"collectComments": false or true`
+ - true to collect comment and allow writing them
+ back during serialization, false to discard comments.
+ This parameter is ignored if allowComments is false.
+ - `"allowComments": false or true`
+ - true if comments are allowed.
+ - `"strictRoot": false or true`
+ - true if root must be either an array or an object value
+ - `"allowDroppedNullPlaceholders": false or true`
+ - true if dropped null placeholders are allowed. (See StreamWriterBuilder.)
+ - `"allowNumericKeys": false or true`
+ - true if numeric object keys are allowed.
+ - `"allowSingleQuotes": false or true`
+ - true if '' are allowed for strings (both keys and values)
+ - `"stackLimit": integer`
+ - Exceeding stackLimit (recursive depth of `readValue()`) will
+ cause an exception.
+ - This is a security issue (seg-faults caused by deeply nested JSON),
+ so the default is low.
+ - `"failIfExtra": false or true`
+ - If true, `parse()` returns false when extra non-whitespace trails
+ the JSON value in the input string.
+ - `"rejectDupKeys": false or true`
+ - If true, `parse()` returns false when a key is duplicated within an object.
+ - `"allowSpecialFloats": false or true`
+ - If true, special float values (NaNs and infinities) are allowed
+ and their values are lossfree restorable.
+
+ You can examine 'settings_` yourself
+ to see the defaults. You can also write and read them just like any
+ JSON Value.
+ \sa setDefaults()
+ */
+ Json::Value settings_;
+
+ CharReaderBuilder();
+ ~CharReaderBuilder() override;
+
+ CharReader* newCharReader() const override;
+
+ /** \return true if 'settings' are legal and consistent;
+ * otherwise, indicate bad settings via 'invalid'.
+ */
+ bool validate(Json::Value* invalid) const;
+
+ /** A simple way to update a specific setting.
+ */
+ Value& operator[](std::string key);
+
+ /** Called by ctor, but you can use this to reset settings_.
+ * \pre 'settings' != NULL (but Json::null is fine)
+ * \remark Defaults:
+ * \snippet src/lib_json/json_reader.cpp CharReaderBuilderDefaults
+ */
+ static void setDefaults(Json::Value* settings);
+ /** Same as old Features::strictMode().
+ * \pre 'settings' != NULL (but Json::null is fine)
+ * \remark Defaults:
+ * \snippet src/lib_json/json_reader.cpp CharReaderBuilderStrictMode
+ */
+ static void strictMode(Json::Value* settings);
+};
+
+/** Consume entire stream and use its begin/end.
+ * Someday we might have a real StreamReader, but for now this
+ * is convenient.
+ */
+bool JSON_API parseFromStream(
+ CharReader::Factory const&,
+ std::istream&,
+ Value* root, std::string* errs);
+
+/** \brief Read from 'sin' into 'root'.
+
+ Always keep comments from the input JSON.
+
+ This can be used to read a file into a particular sub-object.
+ For example:
+ \code
+ Json::Value root;
+ cin >> root["dir"]["file"];
+ cout << root;
+ \endcode
+ Result:
+ \verbatim
+ {
+ "dir": {
+ "file": {
+ // The input stream JSON would be nested here.
+ }
+ }
+ }
+ \endverbatim
+ \throw std::exception on parse error.
+ \see Json::operator<<()
+*/
+JSON_API std::istream& operator>>(std::istream&, Value&);
+
+} // namespace Json
+
+#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
+#pragma warning(pop)
+#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
+
+#endif // CPPTL_JSON_READER_H_INCLUDED
+
+// //////////////////////////////////////////////////////////////////////
+// End of content of file: include/json/reader.h
+// //////////////////////////////////////////////////////////////////////
+
+
+
+
+
+
+// //////////////////////////////////////////////////////////////////////
+// Beginning of content of file: include/json/writer.h
+// //////////////////////////////////////////////////////////////////////
+
+// Copyright 2007-2010 Baptiste Lepilleur
+// Distributed under MIT license, or public domain if desired and
+// recognized in your jurisdiction.
+// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
+
+#ifndef JSON_WRITER_H_INCLUDED
+#define JSON_WRITER_H_INCLUDED
+
+#if !defined(JSON_IS_AMALGAMATION)
+#include "value.h"
+#endif // if !defined(JSON_IS_AMALGAMATION)
+#include <vector>
+#include <string>
+#include <ostream>
+
+// Disable warning C4251: <data member>: <type> needs to have dll-interface to
+// be used by...
+#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
+#pragma warning(push)
+#pragma warning(disable : 4251)
+#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
+
+namespace Json {
+
+class Value;
+
+/**
+
+Usage:
+\code
+ using namespace Json;
+ void writeToStdout(StreamWriter::Factory const& factory, Value const& value) {
+ std::unique_ptr<StreamWriter> const writer(
+ factory.newStreamWriter());
+ writer->write(value, &std::cout);
+ std::cout << std::endl; // add lf and flush
+ }
+\endcode
+*/
+class JSON_API StreamWriter {
+protected:
+ std::ostream* sout_; // not owned; will not delete
+public:
+ StreamWriter();
+ virtual ~StreamWriter();
+ /** Write Value into document as configured in sub-class.
+ Do not take ownership of sout, but maintain a reference during function.
+ \pre sout != NULL
+ \return zero on success (For now, we always return zero, so check the stream instead.)
+ \throw std::exception possibly, depending on configuration
+ */
+ virtual int write(Value const& root, std::ostream* sout) = 0;
+
+ /** \brief A simple abstract factory.
+ */
+ class JSON_API Factory {
+ public:
+ virtual ~Factory();
+ /** \brief Allocate a CharReader via operator new().
+ * \throw std::exception if something goes wrong (e.g. invalid settings)
+ */
+ virtual StreamWriter* newStreamWriter() const = 0;
+ }; // Factory
+}; // StreamWriter
+
+/** \brief Write into stringstream, then return string, for convenience.
+ * A StreamWriter will be created from the factory, used, and then deleted.
+ */
+std::string JSON_API writeString(StreamWriter::Factory const& factory, Value const& root);
+
+
+/** \brief Build a StreamWriter implementation.
+
+Usage:
+\code
+ using namespace Json;
+ Value value = ...;
+ StreamWriterBuilder builder;
+ builder["commentStyle"] = "None";
+ builder["indentation"] = " "; // or whatever you like
+ std::unique_ptr<Json::StreamWriter> writer(
+ builder.newStreamWriter());
+ writer->write(value, &std::cout);
+ std::cout << std::endl; // add lf and flush
+\endcode
+*/
+class JSON_API StreamWriterBuilder : public StreamWriter::Factory {
+public:
+ // Note: We use a Json::Value so that we can add data-members to this class
+ // without a major version bump.
+ /** Configuration of this builder.
+ Available settings (case-sensitive):
+ - "commentStyle": "None" or "All"
+ - "indentation": "<anything>"
+ - "enableYAMLCompatibility": false or true
+ - slightly change the whitespace around colons
+ - "dropNullPlaceholders": false or true
+ - Drop the "null" string from the writer's output for nullValues.
+ Strictly speaking, this is not valid JSON. But when the output is being
+ fed to a browser's Javascript, it makes for smaller output and the
+ browser can handle the output just fine.
+ - "useSpecialFloats": false or true
+ - If true, outputs non-finite floating point values in the following way:
+ NaN values as "NaN", positive infinity as "Infinity", and negative infinity
+ as "-Infinity".
+
+ You can examine 'settings_` yourself
+ to see the defaults. You can also write and read them just like any
+ JSON Value.
+ \sa setDefaults()
+ */
+ Json::Value settings_;
+
+ StreamWriterBuilder();
+ ~StreamWriterBuilder() override;
+
+ /**
+ * \throw std::exception if something goes wrong (e.g. invalid settings)
+ */
+ StreamWriter* newStreamWriter() const override;
+
+ /** \return true if 'settings' are legal and consistent;
+ * otherwise, indicate bad settings via 'invalid'.
+ */
+ bool validate(Json::Value* invalid) const;
+ /** A simple way to update a specific setting.
+ */
+ Value& operator[](std::string key);
+
+ /** Called by ctor, but you can use this to reset settings_.
+ * \pre 'settings' != NULL (but Json::null is fine)
+ * \remark Defaults:
+ * \snippet src/lib_json/json_writer.cpp StreamWriterBuilderDefaults
+ */
+ static void setDefaults(Json::Value* settings);
+};
+
+/** \brief Abstract class for writers.
+ * \deprecated Use StreamWriter. (And really, this is an implementation detail.)
+ */
+class JSON_API Writer {
+public:
+ virtual ~Writer();
+
+ virtual std::string write(const Value& root) = 0;
+};
+
+/** \brief Outputs a Value in <a HREF="http://www.json.org">JSON</a> format
+ *without formatting (not human friendly).
+ *
+ * The JSON document is written in a single line. It is not intended for 'human'
+ *consumption,
+ * but may be usefull to support feature such as RPC where bandwith is limited.
+ * \sa Reader, Value
+ * \deprecated Use StreamWriterBuilder.
+ */
+class JSON_API FastWriter : public Writer {
+
+public:
+ FastWriter();
+ ~FastWriter() override {}
+
+ void enableYAMLCompatibility();
+
+ /** \brief Drop the "null" string from the writer's output for nullValues.
+ * Strictly speaking, this is not valid JSON. But when the output is being
+ * fed to a browser's Javascript, it makes for smaller output and the
+ * browser can handle the output just fine.
+ */
+ void dropNullPlaceholders();
+
+ void omitEndingLineFeed();
+
+public: // overridden from Writer
+ std::string write(const Value& root) override;
+
+private:
+ void writeValue(const Value& value);
+
+ std::string document_;
+ bool yamlCompatiblityEnabled_;
+ bool dropNullPlaceholders_;
+ bool omitEndingLineFeed_;
+};
+
+/** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a
+ *human friendly way.
+ *
+ * The rules for line break and indent are as follow:
+ * - Object value:
+ * - if empty then print {} without indent and line break
+ * - if not empty the print '{', line break & indent, print one value per
+ *line
+ * and then unindent and line break and print '}'.
+ * - Array value:
+ * - if empty then print [] without indent and line break
+ * - if the array contains no object value, empty array or some other value
+ *types,
+ * and all the values fit on one lines, then print the array on a single
+ *line.
+ * - 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
+ *#CommentPlacement.
+ *
+ * \sa Reader, Value, Value::setComment()
+ * \deprecated Use StreamWriterBuilder.
+ */
+class JSON_API StyledWriter : public Writer {
+public:
+ StyledWriter();
+ ~StyledWriter() override {}
+
+public: // overridden from Writer
+ /** \brief Serialize a Value in <a HREF="http://www.json.org">JSON</a> format.
+ * \param root Value to serialize.
+ * \return String containing the JSON document that represents the root value.
+ */
+ std::string write(const Value& root) override;
+
+private:
+ void writeValue(const Value& value);
+ void writeArrayValue(const Value& value);
+ bool isMultineArray(const Value& value);
+ void pushValue(const std::string& value);
+ void writeIndent();
+ void writeWithIndent(const std::string& value);
+ void indent();
+ void unindent();
+ void writeCommentBeforeValue(const Value& root);
+ void writeCommentAfterValueOnSameLine(const Value& root);
+ bool hasCommentForValue(const Value& value);
+ static std::string normalizeEOL(const std::string& text);
+
+ typedef std::vector<std::string> ChildValues;
+
+ ChildValues childValues_;
+ std::string document_;
+ std::string indentString_;
+ int rightMargin_;
+ int indentSize_;
+ bool addChildValues_;
+};
+
+/** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a
+ human friendly way,
+ to a stream rather than to a string.
+ *
+ * The rules for line break and indent are as follow:
+ * - Object value:
+ * - if empty then print {} without indent and line break
+ * - if not empty the print '{', line break & indent, print one value per
+ line
+ * and then unindent and line break and print '}'.
+ * - Array value:
+ * - if empty then print [] without indent and line break
+ * - if the array contains no object value, empty array or some other value
+ types,
+ * and all the values fit on one lines, then print the array on a single
+ line.
+ * - 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
+ #CommentPlacement.
+ *
+ * \param indentation Each level will be indented by this amount extra.
+ * \sa Reader, Value, Value::setComment()
+ * \deprecated Use StreamWriterBuilder.
+ */
+class JSON_API StyledStreamWriter {
+public:
+ StyledStreamWriter(std::string indentation = "\t");
+ ~StyledStreamWriter() {}
+
+public:
+ /** \brief Serialize a Value in <a HREF="http://www.json.org">JSON</a> format.
+ * \param out Stream to write to. (Can be ostringstream, e.g.)
+ * \param root Value to serialize.
+ * \note There is no point in deriving from Writer, since write() should not
+ * return a value.
+ */
+ void write(std::ostream& out, const Value& root);
+
+private:
+ void writeValue(const Value& value);
+ void writeArrayValue(const Value& value);
+ bool isMultineArray(const Value& value);
+ void pushValue(const std::string& value);
+ void writeIndent();
+ void writeWithIndent(const std::string& value);
+ void indent();
+ void unindent();
+ void writeCommentBeforeValue(const Value& root);
+ void writeCommentAfterValueOnSameLine(const Value& root);
+ bool hasCommentForValue(const Value& value);
+ static std::string normalizeEOL(const std::string& text);
+
+ typedef std::vector<std::string> ChildValues;
+
+ ChildValues childValues_;
+ std::ostream* document_;
+ std::string indentString_;
+ int rightMargin_;
+ std::string indentation_;
+ bool addChildValues_ : 1;
+ bool indented_ : 1;
+};
+
+#if defined(JSON_HAS_INT64)
+std::string JSON_API valueToString(Int value);
+std::string JSON_API valueToString(UInt value);
+#endif // if defined(JSON_HAS_INT64)
+std::string JSON_API valueToString(LargestInt value);
+std::string JSON_API valueToString(LargestUInt value);
+std::string JSON_API valueToString(double value);
+std::string JSON_API valueToString(bool value);
+std::string JSON_API valueToQuotedString(const char* value);
+
+/// \brief Output using the StyledStreamWriter.
+/// \see Json::operator>>()
+JSON_API std::ostream& operator<<(std::ostream&, const Value& root);
+
+} // namespace Json
+
+#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
+#pragma warning(pop)
+#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
+
+#endif // JSON_WRITER_H_INCLUDED
+
+// //////////////////////////////////////////////////////////////////////
+// End of content of file: include/json/writer.h
+// //////////////////////////////////////////////////////////////////////
+
+
+
+
+
+
+// //////////////////////////////////////////////////////////////////////
+// Beginning of content of file: include/json/assertions.h
+// //////////////////////////////////////////////////////////////////////
+
+// Copyright 2007-2010 Baptiste Lepilleur
+// Distributed under MIT license, or public domain if desired and
+// recognized in your jurisdiction.
+// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
+
+#ifndef CPPTL_JSON_ASSERTIONS_H_INCLUDED
+#define CPPTL_JSON_ASSERTIONS_H_INCLUDED
+
+#include <stdlib.h>
+#include <sstream>
+
+#if !defined(JSON_IS_AMALGAMATION)
+#include "config.h"
+#endif // if !defined(JSON_IS_AMALGAMATION)
+
+/** It should not be possible for a maliciously designed file to
+ * cause an abort() or seg-fault, so these macros are used only
+ * for pre-condition violations and internal logic errors.
+ */
+#if JSON_USE_EXCEPTION
+
+// @todo <= add detail about condition in exception
+# define JSON_ASSERT(condition) \
+ {if (!(condition)) {Json::throwLogicError( "assert json failed" );}}
+
+# define JSON_FAIL_MESSAGE(message) \
+ { \
+ std::ostringstream oss; oss << message; \
+ Json::throwLogicError(oss.str()); \
+ abort(); \
+ }
+
+#else // JSON_USE_EXCEPTION
+
+# define JSON_ASSERT(condition) assert(condition)
+
+// The call to assert() will show the failure message in debug builds. In
+// release builds we abort, for a core-dump or debugger.
+# define JSON_FAIL_MESSAGE(message) \
+ { \
+ std::ostringstream oss; oss << message; \
+ assert(false && oss.str().c_str()); \
+ abort(); \
+ }
+
+
+#endif
+
+#define JSON_ASSERT_MESSAGE(condition, message) \
+ if (!(condition)) { \
+ JSON_FAIL_MESSAGE(message); \
+ }
+
+#endif // CPPTL_JSON_ASSERTIONS_H_INCLUDED
+
+// //////////////////////////////////////////////////////////////////////
+// End of content of file: include/json/assertions.h
+// //////////////////////////////////////////////////////////////////////
+
+
+
+
+
+#endif //ifndef JSON_AMALGATED_H_INCLUDED
diff --git a/conformance/third_party/jsoncpp/jsoncpp.cpp b/conformance/third_party/jsoncpp/jsoncpp.cpp
new file mode 100644
index 00000000..f803962a
--- /dev/null
+++ b/conformance/third_party/jsoncpp/jsoncpp.cpp
@@ -0,0 +1,5192 @@
+/// Json-cpp amalgated source (http://jsoncpp.sourceforge.net/).
+/// It is intended to be used with #include "json/json.h"
+
+// //////////////////////////////////////////////////////////////////////
+// Beginning of content of file: LICENSE
+// //////////////////////////////////////////////////////////////////////
+
+/*
+The JsonCpp library's source code, including accompanying documentation,
+tests and demonstration applications, are licensed under the following
+conditions...
+
+The author (Baptiste Lepilleur) explicitly disclaims copyright in all
+jurisdictions which recognize such a disclaimer. In such jurisdictions,
+this software is released into the Public Domain.
+
+In jurisdictions which do not recognize Public Domain property (e.g. Germany as of
+2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur, and is
+released under the terms of the MIT License (see below).
+
+In jurisdictions which recognize Public Domain property, the user of this
+software may choose to accept it either as 1) Public Domain, 2) under the
+conditions of the MIT License (see below), or 3) under the terms of dual
+Public Domain/MIT License conditions described here, as they choose.
+
+The MIT License is about as close to Public Domain as a license can get, and is
+described in clear, concise terms at:
+
+ http://en.wikipedia.org/wiki/MIT_License
+
+The full text of the MIT License follows:
+
+========================================================================
+Copyright (c) 2007-2010 Baptiste Lepilleur
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use, copy,
+modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+========================================================================
+(END LICENSE TEXT)
+
+The MIT license is compatible with both the GPL and commercial
+software, affording one all of the rights of Public Domain with the
+minor nuisance of being required to keep the above copyright notice
+and license text in the source code. Note also that by accepting the
+Public Domain "license" you can re-license your copy using whatever
+license you like.
+
+*/
+
+// //////////////////////////////////////////////////////////////////////
+// End of content of file: LICENSE
+// //////////////////////////////////////////////////////////////////////
+
+
+
+
+
+
+#include "third_party/jsoncpp/json.h"
+
+#ifndef JSON_IS_AMALGAMATION
+#error "Compile with -I PATH_TO_JSON_DIRECTORY"
+#endif
+
+
+// //////////////////////////////////////////////////////////////////////
+// Beginning of content of file: src/lib_json/json_tool.h
+// //////////////////////////////////////////////////////////////////////
+
+// Copyright 2007-2010 Baptiste Lepilleur
+// Distributed under MIT license, or public domain if desired and
+// recognized in your jurisdiction.
+// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
+
+#ifndef LIB_JSONCPP_JSON_TOOL_H_INCLUDED
+#define LIB_JSONCPP_JSON_TOOL_H_INCLUDED
+
+/* This header provides common string manipulation support, such as UTF-8,
+ * portable conversion from/to string...
+ *
+ * It is an internal header that must not be exposed.
+ */
+
+namespace Json {
+
+/// Converts a unicode code-point to UTF-8.
+static inline std::string codePointToUTF8(unsigned int cp) {
+ std::string result;
+
+ // based on description from http://en.wikipedia.org/wiki/UTF-8
+
+ if (cp <= 0x7f) {
+ result.resize(1);
+ result[0] = static_cast<char>(cp);
+ } else if (cp <= 0x7FF) {
+ result.resize(2);
+ result[1] = static_cast<char>(0x80 | (0x3f & cp));
+ result[0] = static_cast<char>(0xC0 | (0x1f & (cp >> 6)));
+ } else if (cp <= 0xFFFF) {
+ result.resize(3);
+ result[2] = static_cast<char>(0x80 | (0x3f & cp));
+ result[1] = static_cast<char>(0x80 | (0x3f & (cp >> 6)));
+ result[0] = static_cast<char>(0xE0 | (0xf & (cp >> 12)));
+ } else if (cp <= 0x10FFFF) {
+ result.resize(4);
+ result[3] = static_cast<char>(0x80 | (0x3f & cp));
+ result[2] = static_cast<char>(0x80 | (0x3f & (cp >> 6)));
+ result[1] = static_cast<char>(0x80 | (0x3f & (cp >> 12)));
+ result[0] = static_cast<char>(0xF0 | (0x7 & (cp >> 18)));
+ }
+
+ return result;
+}
+
+/// Returns true if ch is a control character (in range [1,31]).
+static inline bool isControlCharacter(char ch) { return ch > 0 && ch <= 0x1F; }
+
+enum {
+ /// Constant that specify the size of the buffer that must be passed to
+ /// uintToString.
+ uintToStringBufferSize = 3 * sizeof(LargestUInt) + 1
+};
+
+// Defines a char buffer for use with uintToString().
+typedef char UIntToStringBuffer[uintToStringBufferSize];
+
+/** Converts an unsigned integer to string.
+ * @param value Unsigned interger to convert to string
+ * @param current Input/Output string buffer.
+ * Must have at least uintToStringBufferSize chars free.
+ */
+static inline void uintToString(LargestUInt value, char*& current) {
+ *--current = 0;
+ do {
+ *--current = static_cast<signed char>(value % 10U + static_cast<unsigned>('0'));
+ value /= 10;
+ } while (value != 0);
+}
+
+/** Change ',' to '.' everywhere in buffer.
+ *
+ * We had a sophisticated way, but it did not work in WinCE.
+ * @see https://github.com/open-source-parsers/jsoncpp/pull/9
+ */
+static inline void fixNumericLocale(char* begin, char* end) {
+ while (begin < end) {
+ if (*begin == ',') {
+ *begin = '.';
+ }
+ ++begin;
+ }
+}
+
+} // namespace Json {
+
+#endif // LIB_JSONCPP_JSON_TOOL_H_INCLUDED
+
+// //////////////////////////////////////////////////////////////////////
+// End of content of file: src/lib_json/json_tool.h
+// //////////////////////////////////////////////////////////////////////
+
+
+
+
+
+
+// //////////////////////////////////////////////////////////////////////
+// Beginning of content of file: src/lib_json/json_reader.cpp
+// //////////////////////////////////////////////////////////////////////
+
+// Copyright 2007-2011 Baptiste Lepilleur
+// Distributed under MIT license, or public domain if desired and
+// recognized in your jurisdiction.
+// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
+
+#if !defined(JSON_IS_AMALGAMATION)
+#include <json/assertions.h>
+#include <json/reader.h>
+#include <json/value.h>
+#include "json_tool.h"
+#endif // if !defined(JSON_IS_AMALGAMATION)
+#include <utility>
+#include <cstdio>
+#include <cassert>
+#include <cstring>
+#include <istream>
+#include <sstream>
+#include <memory>
+#include <set>
+#include <limits>
+
+#if defined(_MSC_VER)
+#if !defined(WINCE) && defined(__STDC_SECURE_LIB__) && _MSC_VER >= 1500 // VC++ 9.0 and above
+#define snprintf sprintf_s
+#elif _MSC_VER >= 1900 // VC++ 14.0 and above
+#define snprintf std::snprintf
+#else
+#define snprintf _snprintf
+#endif
+#elif defined(__ANDROID__) || defined(__QNXNTO__)
+#define snprintf snprintf
+#elif __cplusplus >= 201103L
+#define snprintf std::snprintf
+#endif
+
+#if defined(__QNXNTO__)
+#define sscanf std::sscanf
+#endif
+
+#if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0
+// Disable warning about strdup being deprecated.
+#pragma warning(disable : 4996)
+#endif
+
+static int const stackLimit_g = 1000;
+static int stackDepth_g = 0; // see readValue()
+
+namespace Json {
+
+#if __cplusplus >= 201103L || (defined(_CPPLIB_VER) && _CPPLIB_VER >= 520)
+typedef std::unique_ptr<CharReader> CharReaderPtr;
+#else
+typedef std::auto_ptr<CharReader> CharReaderPtr;
+#endif
+
+// Implementation of class Features
+// ////////////////////////////////
+
+Features::Features()
+ : allowComments_(true), strictRoot_(false),
+ allowDroppedNullPlaceholders_(false), allowNumericKeys_(false) {}
+
+Features Features::all() { return Features(); }
+
+Features Features::strictMode() {
+ Features features;
+ features.allowComments_ = false;
+ features.strictRoot_ = true;
+ features.allowDroppedNullPlaceholders_ = false;
+ features.allowNumericKeys_ = false;
+ return features;
+}
+
+// Implementation of class Reader
+// ////////////////////////////////
+
+static bool containsNewLine(Reader::Location begin, Reader::Location end) {
+ for (; begin < end; ++begin)
+ if (*begin == '\n' || *begin == '\r')
+ return true;
+ return false;
+}
+
+// Class Reader
+// //////////////////////////////////////////////////////////////////
+
+Reader::Reader()
+ : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(),
+ lastValue_(), commentsBefore_(), features_(Features::all()),
+ collectComments_() {}
+
+Reader::Reader(const Features& features)
+ : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(),
+ lastValue_(), commentsBefore_(), features_(features), collectComments_() {
+}
+
+bool
+Reader::parse(const std::string& document, Value& root, bool collectComments) {
+ document_ = document;
+ const char* begin = document_.c_str();
+ const char* end = begin + document_.length();
+ return parse(begin, end, root, collectComments);
+}
+
+bool Reader::parse(std::istream& sin, Value& root, bool collectComments) {
+ // std::istream_iterator<char> begin(sin);
+ // std::istream_iterator<char> end;
+ // Those would allow streamed input from a file, if parse() were a
+ // template function.
+
+ // Since std::string is reference-counted, this at least does not
+ // create an extra copy.
+ std::string doc;
+ std::getline(sin, doc, (char)EOF);
+ return parse(doc, root, collectComments);
+}
+
+bool Reader::parse(const char* beginDoc,
+ const char* endDoc,
+ Value& root,
+ bool collectComments) {
+ if (!features_.allowComments_) {
+ collectComments = false;
+ }
+
+ begin_ = beginDoc;
+ end_ = endDoc;
+ collectComments_ = collectComments;
+ current_ = begin_;
+ lastValueEnd_ = 0;
+ lastValue_ = 0;
+ commentsBefore_ = "";
+ errors_.clear();
+ while (!nodes_.empty())
+ nodes_.pop();
+ nodes_.push(&root);
+
+ stackDepth_g = 0; // Yes, this is bad coding, but options are limited.
+ bool successful = readValue();
+ Token token;
+ skipCommentTokens(token);
+ if (collectComments_ && !commentsBefore_.empty())
+ root.setComment(commentsBefore_, commentAfter);
+ if (features_.strictRoot_) {
+ if (!root.isArray() && !root.isObject()) {
+ // Set error location to start of doc, ideally should be first token found
+ // in doc
+ token.type_ = tokenError;
+ token.start_ = beginDoc;
+ token.end_ = endDoc;
+ addError(
+ "A valid JSON document must be either an array or an object value.",
+ token);
+ return false;
+ }
+ }
+ return successful;
+}
+
+bool Reader::readValue() {
+ // This is a non-reentrant way to support a stackLimit. Terrible!
+ // But this deprecated class has a security problem: Bad input can
+ // cause a seg-fault. This seems like a fair, binary-compatible way
+ // to prevent the problem.
+ if (stackDepth_g >= stackLimit_g) throwRuntimeError("Exceeded stackLimit in readValue().");
+ ++stackDepth_g;
+
+ Token token;
+ skipCommentTokens(token);
+ bool successful = true;
+
+ if (collectComments_ && !commentsBefore_.empty()) {
+ currentValue().setComment(commentsBefore_, commentBefore);
+ commentsBefore_ = "";
+ }
+
+ switch (token.type_) {
+ case tokenObjectBegin:
+ successful = readObject(token);
+ currentValue().setOffsetLimit(current_ - begin_);
+ break;
+ case tokenArrayBegin:
+ successful = readArray(token);
+ currentValue().setOffsetLimit(current_ - begin_);
+ break;
+ case tokenNumber:
+ successful = decodeNumber(token);
+ break;
+ case tokenString:
+ successful = decodeString(token);
+ break;
+ case tokenTrue:
+ {
+ Value v(true);
+ currentValue().swapPayload(v);
+ currentValue().setOffsetStart(token.start_ - begin_);
+ currentValue().setOffsetLimit(token.end_ - begin_);
+ }
+ break;
+ case tokenFalse:
+ {
+ Value v(false);
+ currentValue().swapPayload(v);
+ currentValue().setOffsetStart(token.start_ - begin_);
+ currentValue().setOffsetLimit(token.end_ - begin_);
+ }
+ break;
+ case tokenNull:
+ {
+ Value v;
+ currentValue().swapPayload(v);
+ currentValue().setOffsetStart(token.start_ - begin_);
+ currentValue().setOffsetLimit(token.end_ - begin_);
+ }
+ break;
+ case tokenArraySeparator:
+ case tokenObjectEnd:
+ case tokenArrayEnd:
+ if (features_.allowDroppedNullPlaceholders_) {
+ // "Un-read" the current token and mark the current value as a null
+ // token.
+ current_--;
+ Value v;
+ currentValue().swapPayload(v);
+ currentValue().setOffsetStart(current_ - begin_ - 1);
+ currentValue().setOffsetLimit(current_ - begin_);
+ break;
+ } // Else, fall through...
+ default:
+ currentValue().setOffsetStart(token.start_ - begin_);
+ currentValue().setOffsetLimit(token.end_ - begin_);
+ return addError("Syntax error: value, object or array expected.", token);
+ }
+
+ if (collectComments_) {
+ lastValueEnd_ = current_;
+ lastValue_ = &currentValue();
+ }
+
+ --stackDepth_g;
+ return successful;
+}
+
+void Reader::skipCommentTokens(Token& token) {
+ if (features_.allowComments_) {
+ do {
+ readToken(token);
+ } while (token.type_ == tokenComment);
+ } else {
+ readToken(token);
+ }
+}
+
+bool Reader::readToken(Token& token) {
+ skipSpaces();
+ token.start_ = current_;
+ Char c = getNextChar();
+ bool ok = true;
+ switch (c) {
+ case '{':
+ token.type_ = tokenObjectBegin;
+ break;
+ case '}':
+ token.type_ = tokenObjectEnd;
+ break;
+ case '[':
+ token.type_ = tokenArrayBegin;
+ break;
+ case ']':
+ token.type_ = tokenArrayEnd;
+ break;
+ case '"':
+ token.type_ = tokenString;
+ ok = readString();
+ break;
+ case '/':
+ token.type_ = tokenComment;
+ ok = readComment();
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case '-':
+ token.type_ = tokenNumber;
+ readNumber();
+ break;
+ case 't':
+ token.type_ = tokenTrue;
+ ok = match("rue", 3);
+ break;
+ case 'f':
+ token.type_ = tokenFalse;
+ ok = match("alse", 4);
+ break;
+ case 'n':
+ token.type_ = tokenNull;
+ ok = match("ull", 3);
+ break;
+ case ',':
+ token.type_ = tokenArraySeparator;
+ break;
+ case ':':
+ token.type_ = tokenMemberSeparator;
+ break;
+ case 0:
+ token.type_ = tokenEndOfStream;
+ break;
+ default:
+ ok = false;
+ break;
+ }
+ if (!ok)
+ token.type_ = tokenError;
+ token.end_ = current_;
+ return true;
+}
+
+void Reader::skipSpaces() {
+ while (current_ != end_) {
+ Char c = *current_;
+ if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
+ ++current_;
+ else
+ break;
+ }
+}
+
+bool Reader::match(Location pattern, int patternLength) {
+ if (end_ - current_ < patternLength)
+ return false;
+ int index = patternLength;
+ while (index--)
+ if (current_[index] != pattern[index])
+ return false;
+ current_ += patternLength;
+ return true;
+}
+
+bool Reader::readComment() {
+ Location commentBegin = current_ - 1;
+ Char c = getNextChar();
+ bool successful = false;
+ if (c == '*')
+ successful = readCStyleComment();
+ else if (c == '/')
+ successful = readCppStyleComment();
+ if (!successful)
+ return false;
+
+ if (collectComments_) {
+ CommentPlacement placement = commentBefore;
+ if (lastValueEnd_ && !containsNewLine(lastValueEnd_, commentBegin)) {
+ if (c != '*' || !containsNewLine(commentBegin, current_))
+ placement = commentAfterOnSameLine;
+ }
+
+ addComment(commentBegin, current_, placement);
+ }
+ return true;
+}
+
+static std::string normalizeEOL(Reader::Location begin, Reader::Location end) {
+ std::string normalized;
+ normalized.reserve(end - begin);
+ Reader::Location current = begin;
+ while (current != end) {
+ char c = *current++;
+ if (c == '\r') {
+ if (current != end && *current == '\n')
+ // convert dos EOL
+ ++current;
+ // convert Mac EOL
+ normalized += '\n';
+ } else {
+ normalized += c;
+ }
+ }
+ return normalized;
+}
+
+void
+Reader::addComment(Location begin, Location end, CommentPlacement placement) {
+ assert(collectComments_);
+ const std::string& normalized = normalizeEOL(begin, end);
+ if (placement == commentAfterOnSameLine) {
+ assert(lastValue_ != 0);
+ lastValue_->setComment(normalized, placement);
+ } else {
+ commentsBefore_ += normalized;
+ }
+}
+
+bool Reader::readCStyleComment() {
+ while (current_ != end_) {
+ Char c = getNextChar();
+ if (c == '*' && *current_ == '/')
+ break;
+ }
+ return getNextChar() == '/';
+}
+
+bool Reader::readCppStyleComment() {
+ while (current_ != end_) {
+ Char c = getNextChar();
+ if (c == '\n')
+ break;
+ if (c == '\r') {
+ // Consume DOS EOL. It will be normalized in addComment.
+ if (current_ != end_ && *current_ == '\n')
+ getNextChar();
+ // Break on Moc OS 9 EOL.
+ break;
+ }
+ }
+ return true;
+}
+
+void Reader::readNumber() {
+ const char *p = current_;
+ char c = '0'; // stopgap for already consumed character
+ // integral part
+ while (c >= '0' && c <= '9')
+ c = (current_ = p) < end_ ? *p++ : 0;
+ // fractional part
+ if (c == '.') {
+ c = (current_ = p) < end_ ? *p++ : 0;
+ while (c >= '0' && c <= '9')
+ c = (current_ = p) < end_ ? *p++ : 0;
+ }
+ // exponential part
+ if (c == 'e' || c == 'E') {
+ c = (current_ = p) < end_ ? *p++ : 0;
+ if (c == '+' || c == '-')
+ c = (current_ = p) < end_ ? *p++ : 0;
+ while (c >= '0' && c <= '9')
+ c = (current_ = p) < end_ ? *p++ : 0;
+ }
+}
+
+bool Reader::readString() {
+ Char c = 0;
+ while (current_ != end_) {
+ c = getNextChar();
+ if (c == '\\')
+ getNextChar();
+ else if (c == '"')
+ break;
+ }
+ return c == '"';
+}
+
+bool Reader::readObject(Token& tokenStart) {
+ Token tokenName;
+ std::string name;
+ Value init(objectValue);
+ currentValue().swapPayload(init);
+ currentValue().setOffsetStart(tokenStart.start_ - begin_);
+ while (readToken(tokenName)) {
+ bool initialTokenOk = true;
+ while (tokenName.type_ == tokenComment && initialTokenOk)
+ initialTokenOk = readToken(tokenName);
+ if (!initialTokenOk)
+ break;
+ if (tokenName.type_ == tokenObjectEnd && name.empty()) // empty object
+ return true;
+ name = "";
+ if (tokenName.type_ == tokenString) {
+ if (!decodeString(tokenName, name))
+ return recoverFromError(tokenObjectEnd);
+ } else if (tokenName.type_ == tokenNumber && features_.allowNumericKeys_) {
+ Value numberName;
+ if (!decodeNumber(tokenName, numberName))
+ return recoverFromError(tokenObjectEnd);
+ name = numberName.asString();
+ } else {
+ break;
+ }
+
+ Token colon;
+ if (!readToken(colon) || colon.type_ != tokenMemberSeparator) {
+ return addErrorAndRecover(
+ "Missing ':' after object member name", colon, tokenObjectEnd);
+ }
+ Value& value = currentValue()[name];
+ nodes_.push(&value);
+ bool ok = readValue();
+ nodes_.pop();
+ if (!ok) // error already set
+ return recoverFromError(tokenObjectEnd);
+
+ Token comma;
+ if (!readToken(comma) ||
+ (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator &&
+ comma.type_ != tokenComment)) {
+ return addErrorAndRecover(
+ "Missing ',' or '}' in object declaration", comma, tokenObjectEnd);
+ }
+ bool finalizeTokenOk = true;
+ while (comma.type_ == tokenComment && finalizeTokenOk)
+ finalizeTokenOk = readToken(comma);
+ if (comma.type_ == tokenObjectEnd)
+ return true;
+ }
+ return addErrorAndRecover(
+ "Missing '}' or object member name", tokenName, tokenObjectEnd);
+}
+
+bool Reader::readArray(Token& tokenStart) {
+ Value init(arrayValue);
+ currentValue().swapPayload(init);
+ currentValue().setOffsetStart(tokenStart.start_ - begin_);
+ skipSpaces();
+ if (*current_ == ']') // empty array
+ {
+ Token endArray;
+ readToken(endArray);
+ return true;
+ }
+ int index = 0;
+ for (;;) {
+ Value& value = currentValue()[index++];
+ nodes_.push(&value);
+ bool ok = readValue();
+ nodes_.pop();
+ if (!ok) // error already set
+ return recoverFromError(tokenArrayEnd);
+
+ Token token;
+ // Accept Comment after last item in the array.
+ ok = readToken(token);
+ while (token.type_ == tokenComment && ok) {
+ ok = readToken(token);
+ }
+ bool badTokenType =
+ (token.type_ != tokenArraySeparator && token.type_ != tokenArrayEnd);
+ if (!ok || badTokenType) {
+ return addErrorAndRecover(
+ "Missing ',' or ']' in array declaration", token, tokenArrayEnd);
+ }
+ if (token.type_ == tokenArrayEnd)
+ break;
+ }
+ return true;
+}
+
+bool Reader::decodeNumber(Token& token) {
+ Value decoded;
+ if (!decodeNumber(token, decoded))
+ return false;
+ currentValue().swapPayload(decoded);
+ currentValue().setOffsetStart(token.start_ - begin_);
+ currentValue().setOffsetLimit(token.end_ - begin_);
+ return true;
+}
+
+bool Reader::decodeNumber(Token& token, Value& decoded) {
+ // Attempts to parse the number as an integer. If the number is
+ // larger than the maximum supported value of an integer then
+ // we decode the number as a double.
+ Location current = token.start_;
+ bool isNegative = *current == '-';
+ if (isNegative)
+ ++current;
+ // TODO: Help the compiler do the div and mod at compile time or get rid of them.
+ Value::LargestUInt maxIntegerValue =
+ isNegative ? Value::LargestUInt(Value::maxLargestInt) + 1
+ : Value::maxLargestUInt;
+ Value::LargestUInt threshold = maxIntegerValue / 10;
+ Value::LargestUInt value = 0;
+ while (current < token.end_) {
+ Char c = *current++;
+ if (c < '0' || c > '9')
+ return decodeDouble(token, decoded);
+ Value::UInt digit(c - '0');
+ if (value >= threshold) {
+ // We've hit or exceeded the max value divided by 10 (rounded down). If
+ // a) we've only just touched the limit, b) this is the last digit, and
+ // c) it's small enough to fit in that rounding delta, we're okay.
+ // Otherwise treat this number as a double to avoid overflow.
+ if (value > threshold || current != token.end_ ||
+ digit > maxIntegerValue % 10) {
+ return decodeDouble(token, decoded);
+ }
+ }
+ value = value * 10 + digit;
+ }
+ if (isNegative && value == maxIntegerValue)
+ decoded = Value::minLargestInt;
+ else if (isNegative)
+ decoded = -Value::LargestInt(value);
+ else if (value <= Value::LargestUInt(Value::maxInt))
+ decoded = Value::LargestInt(value);
+ else
+ decoded = value;
+ return true;
+}
+
+bool Reader::decodeDouble(Token& token) {
+ Value decoded;
+ if (!decodeDouble(token, decoded))
+ return false;
+ currentValue().swapPayload(decoded);
+ currentValue().setOffsetStart(token.start_ - begin_);
+ currentValue().setOffsetLimit(token.end_ - begin_);
+ return true;
+}
+
+bool Reader::decodeDouble(Token& token, Value& decoded) {
+ double value = 0;
+ std::string buffer(token.start_, token.end_);
+ std::istringstream is(buffer);
+ if (!(is >> value))
+ return addError("'" + std::string(token.start_, token.end_) +
+ "' is not a number.",
+ token);
+ decoded = value;
+ return true;
+}
+
+bool Reader::decodeString(Token& token) {
+ std::string decoded_string;
+ if (!decodeString(token, decoded_string))
+ return false;
+ Value decoded(decoded_string);
+ currentValue().swapPayload(decoded);
+ currentValue().setOffsetStart(token.start_ - begin_);
+ currentValue().setOffsetLimit(token.end_ - begin_);
+ return true;
+}
+
+bool Reader::decodeString(Token& token, std::string& decoded) {
+ decoded.reserve(token.end_ - token.start_ - 2);
+ Location current = token.start_ + 1; // skip '"'
+ Location end = token.end_ - 1; // do not include '"'
+ while (current != end) {
+ Char c = *current++;
+ if (c == '"')
+ break;
+ else if (c == '\\') {
+ if (current == end)
+ return addError("Empty escape sequence in string", token, current);
+ Char escape = *current++;
+ switch (escape) {
+ case '"':
+ decoded += '"';
+ break;
+ case '/':
+ decoded += '/';
+ break;
+ case '\\':
+ decoded += '\\';
+ break;
+ case 'b':
+ decoded += '\b';
+ break;
+ case 'f':
+ decoded += '\f';
+ break;
+ case 'n':
+ decoded += '\n';
+ break;
+ case 'r':
+ decoded += '\r';
+ break;
+ case 't':
+ decoded += '\t';
+ break;
+ case 'u': {
+ unsigned int unicode;
+ if (!decodeUnicodeCodePoint(token, current, end, unicode))
+ return false;
+ decoded += codePointToUTF8(unicode);
+ } break;
+ default:
+ return addError("Bad escape sequence in string", token, current);
+ }
+ } else {
+ decoded += c;
+ }
+ }
+ return true;
+}
+
+bool Reader::decodeUnicodeCodePoint(Token& token,
+ Location& current,
+ Location end,
+ unsigned int& unicode) {
+
+ if (!decodeUnicodeEscapeSequence(token, current, end, unicode))
+ return false;
+ if (unicode >= 0xD800 && unicode <= 0xDBFF) {
+ // surrogate pairs
+ if (end - current < 6)
+ return addError(
+ "additional six characters expected to parse unicode surrogate pair.",
+ token,
+ current);
+ unsigned int surrogatePair;
+ if (*(current++) == '\\' && *(current++) == 'u') {
+ if (decodeUnicodeEscapeSequence(token, current, end, surrogatePair)) {
+ unicode = 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF);
+ } else
+ return false;
+ } else
+ return addError("expecting another \\u token to begin the second half of "
+ "a unicode surrogate pair",
+ token,
+ current);
+ }
+ return true;
+}
+
+bool Reader::decodeUnicodeEscapeSequence(Token& token,
+ Location& current,
+ Location end,
+ unsigned int& unicode) {
+ if (end - current < 4)
+ return addError(
+ "Bad unicode escape sequence in string: four digits expected.",
+ token,
+ current);
+ unicode = 0;
+ for (int index = 0; index < 4; ++index) {
+ Char c = *current++;
+ unicode *= 16;
+ if (c >= '0' && c <= '9')
+ unicode += c - '0';
+ else if (c >= 'a' && c <= 'f')
+ unicode += c - 'a' + 10;
+ else if (c >= 'A' && c <= 'F')
+ unicode += c - 'A' + 10;
+ else
+ return addError(
+ "Bad unicode escape sequence in string: hexadecimal digit expected.",
+ token,
+ current);
+ }
+ return true;
+}
+
+bool
+Reader::addError(const std::string& message, Token& token, Location extra) {
+ ErrorInfo info;
+ info.token_ = token;
+ info.message_ = message;
+ info.extra_ = extra;
+ errors_.push_back(info);
+ return false;
+}
+
+bool Reader::recoverFromError(TokenType skipUntilToken) {
+ int errorCount = int(errors_.size());
+ Token skip;
+ for (;;) {
+ if (!readToken(skip))
+ errors_.resize(errorCount); // discard errors caused by recovery
+ if (skip.type_ == skipUntilToken || skip.type_ == tokenEndOfStream)
+ break;
+ }
+ errors_.resize(errorCount);
+ return false;
+}
+
+bool Reader::addErrorAndRecover(const std::string& message,
+ Token& token,
+ TokenType skipUntilToken) {
+ addError(message, token);
+ return recoverFromError(skipUntilToken);
+}
+
+Value& Reader::currentValue() { return *(nodes_.top()); }
+
+Reader::Char Reader::getNextChar() {
+ if (current_ == end_)
+ return 0;
+ return *current_++;
+}
+
+void Reader::getLocationLineAndColumn(Location location,
+ int& line,
+ int& column) const {
+ Location current = begin_;
+ Location lastLineStart = current;
+ line = 0;
+ while (current < location && current != end_) {
+ Char c = *current++;
+ if (c == '\r') {
+ if (*current == '\n')
+ ++current;
+ lastLineStart = current;
+ ++line;
+ } else if (c == '\n') {
+ lastLineStart = current;
+ ++line;
+ }
+ }
+ // column & line start at 1
+ column = int(location - lastLineStart) + 1;
+ ++line;
+}
+
+std::string Reader::getLocationLineAndColumn(Location location) const {
+ int line, column;
+ getLocationLineAndColumn(location, line, column);
+ char buffer[18 + 16 + 16 + 1];
+ snprintf(buffer, sizeof(buffer), "Line %d, Column %d", line, column);
+ return buffer;
+}
+
+// Deprecated. Preserved for backward compatibility
+std::string Reader::getFormatedErrorMessages() const {
+ return getFormattedErrorMessages();
+}
+
+std::string Reader::getFormattedErrorMessages() const {
+ std::string formattedMessage;
+ for (Errors::const_iterator itError = errors_.begin();
+ itError != errors_.end();
+ ++itError) {
+ const ErrorInfo& error = *itError;
+ formattedMessage +=
+ "* " + getLocationLineAndColumn(error.token_.start_) + "\n";
+ formattedMessage += " " + error.message_ + "\n";
+ if (error.extra_)
+ formattedMessage +=
+ "See " + getLocationLineAndColumn(error.extra_) + " for detail.\n";
+ }
+ return formattedMessage;
+}
+
+std::vector<Reader::StructuredError> Reader::getStructuredErrors() const {
+ std::vector<Reader::StructuredError> allErrors;
+ for (Errors::const_iterator itError = errors_.begin();
+ itError != errors_.end();
+ ++itError) {
+ const ErrorInfo& error = *itError;
+ Reader::StructuredError structured;
+ structured.offset_start = error.token_.start_ - begin_;
+ structured.offset_limit = error.token_.end_ - begin_;
+ structured.message = error.message_;
+ allErrors.push_back(structured);
+ }
+ return allErrors;
+}
+
+bool Reader::pushError(const Value& value, const std::string& message) {
+ size_t length = end_ - begin_;
+ if(value.getOffsetStart() > length
+ || value.getOffsetLimit() > length)
+ return false;
+ Token token;
+ token.type_ = tokenError;
+ token.start_ = begin_ + value.getOffsetStart();
+ token.end_ = end_ + value.getOffsetLimit();
+ ErrorInfo info;
+ info.token_ = token;
+ info.message_ = message;
+ info.extra_ = 0;
+ errors_.push_back(info);
+ return true;
+}
+
+bool Reader::pushError(const Value& value, const std::string& message, const Value& extra) {
+ size_t length = end_ - begin_;
+ if(value.getOffsetStart() > length
+ || value.getOffsetLimit() > length
+ || extra.getOffsetLimit() > length)
+ return false;
+ Token token;
+ token.type_ = tokenError;
+ token.start_ = begin_ + value.getOffsetStart();
+ token.end_ = begin_ + value.getOffsetLimit();
+ ErrorInfo info;
+ info.token_ = token;
+ info.message_ = message;
+ info.extra_ = begin_ + extra.getOffsetStart();
+ errors_.push_back(info);
+ return true;
+}
+
+bool Reader::good() const {
+ return !errors_.size();
+}
+
+// exact copy of Features
+class OurFeatures {
+public:
+ static OurFeatures all();
+ bool allowComments_;
+ bool strictRoot_;
+ bool allowDroppedNullPlaceholders_;
+ bool allowNumericKeys_;
+ bool allowSingleQuotes_;
+ bool failIfExtra_;
+ bool rejectDupKeys_;
+ bool allowSpecialFloats_;
+ int stackLimit_;
+}; // OurFeatures
+
+// exact copy of Implementation of class Features
+// ////////////////////////////////
+
+OurFeatures OurFeatures::all() { return OurFeatures(); }
+
+// Implementation of class Reader
+// ////////////////////////////////
+
+// exact copy of Reader, renamed to OurReader
+class OurReader {
+public:
+ typedef char Char;
+ typedef const Char* Location;
+ struct StructuredError {
+ size_t offset_start;
+ size_t offset_limit;
+ std::string message;
+ };
+
+ OurReader(OurFeatures const& features);
+ bool parse(const char* beginDoc,
+ const char* endDoc,
+ Value& root,
+ bool collectComments = true);
+ std::string getFormattedErrorMessages() const;
+ std::vector<StructuredError> getStructuredErrors() const;
+ bool pushError(const Value& value, const std::string& message);
+ bool pushError(const Value& value, const std::string& message, const Value& extra);
+ bool good() const;
+
+private:
+ OurReader(OurReader const&); // no impl
+ void operator=(OurReader const&); // no impl
+
+ enum TokenType {
+ tokenEndOfStream = 0,
+ tokenObjectBegin,
+ tokenObjectEnd,
+ tokenArrayBegin,
+ tokenArrayEnd,
+ tokenString,
+ tokenNumber,
+ tokenTrue,
+ tokenFalse,
+ tokenNull,
+ tokenNaN,
+ tokenPosInf,
+ tokenNegInf,
+ tokenArraySeparator,
+ tokenMemberSeparator,
+ tokenComment,
+ tokenError
+ };
+
+ class Token {
+ public:
+ TokenType type_;
+ Location start_;
+ Location end_;
+ };
+
+ class ErrorInfo {
+ public:
+ Token token_;
+ std::string message_;
+ Location extra_;
+ };
+
+ typedef std::deque<ErrorInfo> Errors;
+
+ bool readToken(Token& token);
+ void skipSpaces();
+ bool match(Location pattern, int patternLength);
+ bool readComment();
+ bool readCStyleComment();
+ bool readCppStyleComment();
+ bool readString();
+ bool readStringSingleQuote();
+ bool readNumber(bool checkInf);
+ bool readValue();
+ bool readObject(Token& token);
+ bool readArray(Token& token);
+ bool decodeNumber(Token& token);
+ bool decodeNumber(Token& token, Value& decoded);
+ bool decodeString(Token& token);
+ bool decodeString(Token& token, std::string& decoded);
+ bool decodeDouble(Token& token);
+ bool decodeDouble(Token& token, Value& decoded);
+ bool decodeUnicodeCodePoint(Token& token,
+ Location& current,
+ Location end,
+ unsigned int& unicode);
+ bool decodeUnicodeEscapeSequence(Token& token,
+ Location& current,
+ Location end,
+ unsigned int& unicode);
+ bool addError(const std::string& message, Token& token, Location extra = 0);
+ bool recoverFromError(TokenType skipUntilToken);
+ bool addErrorAndRecover(const std::string& message,
+ Token& token,
+ TokenType skipUntilToken);
+ void skipUntilSpace();
+ Value& currentValue();
+ Char getNextChar();
+ void
+ getLocationLineAndColumn(Location location, int& line, int& column) const;
+ std::string getLocationLineAndColumn(Location location) const;
+ void addComment(Location begin, Location end, CommentPlacement placement);
+ void skipCommentTokens(Token& token);
+
+ typedef std::stack<Value*> Nodes;
+ Nodes nodes_;
+ Errors errors_;
+ std::string document_;
+ Location begin_;
+ Location end_;
+ Location current_;
+ Location lastValueEnd_;
+ Value* lastValue_;
+ std::string commentsBefore_;
+ int stackDepth_;
+
+ OurFeatures const features_;
+ bool collectComments_;
+}; // OurReader
+
+// complete copy of Read impl, for OurReader
+
+OurReader::OurReader(OurFeatures const& features)
+ : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(),
+ lastValue_(), commentsBefore_(),
+ stackDepth_(0),
+ features_(features), collectComments_() {
+}
+
+bool OurReader::parse(const char* beginDoc,
+ const char* endDoc,
+ Value& root,
+ bool collectComments) {
+ if (!features_.allowComments_) {
+ collectComments = false;
+ }
+
+ begin_ = beginDoc;
+ end_ = endDoc;
+ collectComments_ = collectComments;
+ current_ = begin_;
+ lastValueEnd_ = 0;
+ lastValue_ = 0;
+ commentsBefore_ = "";
+ errors_.clear();
+ while (!nodes_.empty())
+ nodes_.pop();
+ nodes_.push(&root);
+
+ stackDepth_ = 0;
+ bool successful = readValue();
+ Token token;
+ skipCommentTokens(token);
+ if (features_.failIfExtra_) {
+ if (token.type_ != tokenError && token.type_ != tokenEndOfStream) {
+ addError("Extra non-whitespace after JSON value.", token);
+ return false;
+ }
+ }
+ if (collectComments_ && !commentsBefore_.empty())
+ root.setComment(commentsBefore_, commentAfter);
+ if (features_.strictRoot_) {
+ if (!root.isArray() && !root.isObject()) {
+ // Set error location to start of doc, ideally should be first token found
+ // in doc
+ token.type_ = tokenError;
+ token.start_ = beginDoc;
+ token.end_ = endDoc;
+ addError(
+ "A valid JSON document must be either an array or an object value.",
+ token);
+ return false;
+ }
+ }
+ return successful;
+}
+
+bool OurReader::readValue() {
+ if (stackDepth_ >= features_.stackLimit_) throwRuntimeError("Exceeded stackLimit in readValue().");
+ ++stackDepth_;
+ Token token;
+ skipCommentTokens(token);
+ bool successful = true;
+
+ if (collectComments_ && !commentsBefore_.empty()) {
+ currentValue().setComment(commentsBefore_, commentBefore);
+ commentsBefore_ = "";
+ }
+
+ switch (token.type_) {
+ case tokenObjectBegin:
+ successful = readObject(token);
+ currentValue().setOffsetLimit(current_ - begin_);
+ break;
+ case tokenArrayBegin:
+ successful = readArray(token);
+ currentValue().setOffsetLimit(current_ - begin_);
+ break;
+ case tokenNumber:
+ successful = decodeNumber(token);
+ break;
+ case tokenString:
+ successful = decodeString(token);
+ break;
+ case tokenTrue:
+ {
+ Value v(true);
+ currentValue().swapPayload(v);
+ currentValue().setOffsetStart(token.start_ - begin_);
+ currentValue().setOffsetLimit(token.end_ - begin_);
+ }
+ break;
+ case tokenFalse:
+ {
+ Value v(false);
+ currentValue().swapPayload(v);
+ currentValue().setOffsetStart(token.start_ - begin_);
+ currentValue().setOffsetLimit(token.end_ - begin_);
+ }
+ break;
+ case tokenNull:
+ {
+ Value v;
+ currentValue().swapPayload(v);
+ currentValue().setOffsetStart(token.start_ - begin_);
+ currentValue().setOffsetLimit(token.end_ - begin_);
+ }
+ break;
+ case tokenNaN:
+ {
+ Value v(std::numeric_limits<double>::quiet_NaN());
+ currentValue().swapPayload(v);
+ currentValue().setOffsetStart(token.start_ - begin_);
+ currentValue().setOffsetLimit(token.end_ - begin_);
+ }
+ break;
+ case tokenPosInf:
+ {
+ Value v(std::numeric_limits<double>::infinity());
+ currentValue().swapPayload(v);
+ currentValue().setOffsetStart(token.start_ - begin_);
+ currentValue().setOffsetLimit(token.end_ - begin_);
+ }
+ break;
+ case tokenNegInf:
+ {
+ Value v(-std::numeric_limits<double>::infinity());
+ currentValue().swapPayload(v);
+ currentValue().setOffsetStart(token.start_ - begin_);
+ currentValue().setOffsetLimit(token.end_ - begin_);
+ }
+ break;
+ case tokenArraySeparator:
+ case tokenObjectEnd:
+ case tokenArrayEnd:
+ if (features_.allowDroppedNullPlaceholders_) {
+ // "Un-read" the current token and mark the current value as a null
+ // token.
+ current_--;
+ Value v;
+ currentValue().swapPayload(v);
+ currentValue().setOffsetStart(current_ - begin_ - 1);
+ currentValue().setOffsetLimit(current_ - begin_);
+ break;
+ } // else, fall through ...
+ default:
+ currentValue().setOffsetStart(token.start_ - begin_);
+ currentValue().setOffsetLimit(token.end_ - begin_);
+ return addError("Syntax error: value, object or array expected.", token);
+ }
+
+ if (collectComments_) {
+ lastValueEnd_ = current_;
+ lastValue_ = &currentValue();
+ }
+
+ --stackDepth_;
+ return successful;
+}
+
+void OurReader::skipCommentTokens(Token& token) {
+ if (features_.allowComments_) {
+ do {
+ readToken(token);
+ } while (token.type_ == tokenComment);
+ } else {
+ readToken(token);
+ }
+}
+
+bool OurReader::readToken(Token& token) {
+ skipSpaces();
+ token.start_ = current_;
+ Char c = getNextChar();
+ bool ok = true;
+ switch (c) {
+ case '{':
+ token.type_ = tokenObjectBegin;
+ break;
+ case '}':
+ token.type_ = tokenObjectEnd;
+ break;
+ case '[':
+ token.type_ = tokenArrayBegin;
+ break;
+ case ']':
+ token.type_ = tokenArrayEnd;
+ break;
+ case '"':
+ token.type_ = tokenString;
+ ok = readString();
+ break;
+ case '\'':
+ if (features_.allowSingleQuotes_) {
+ token.type_ = tokenString;
+ ok = readStringSingleQuote();
+ break;
+ } // else continue
+ case '/':
+ token.type_ = tokenComment;
+ ok = readComment();
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ token.type_ = tokenNumber;
+ readNumber(false);
+ break;
+ case '-':
+ if (readNumber(true)) {
+ token.type_ = tokenNumber;
+ } else {
+ token.type_ = tokenNegInf;
+ ok = features_.allowSpecialFloats_ && match("nfinity", 7);
+ }
+ break;
+ case 't':
+ token.type_ = tokenTrue;
+ ok = match("rue", 3);
+ break;
+ case 'f':
+ token.type_ = tokenFalse;
+ ok = match("alse", 4);
+ break;
+ case 'n':
+ token.type_ = tokenNull;
+ ok = match("ull", 3);
+ break;
+ case 'N':
+ if (features_.allowSpecialFloats_) {
+ token.type_ = tokenNaN;
+ ok = match("aN", 2);
+ } else {
+ ok = false;
+ }
+ break;
+ case 'I':
+ if (features_.allowSpecialFloats_) {
+ token.type_ = tokenPosInf;
+ ok = match("nfinity", 7);
+ } else {
+ ok = false;
+ }
+ break;
+ case ',':
+ token.type_ = tokenArraySeparator;
+ break;
+ case ':':
+ token.type_ = tokenMemberSeparator;
+ break;
+ case 0:
+ token.type_ = tokenEndOfStream;
+ break;
+ default:
+ ok = false;
+ break;
+ }
+ if (!ok)
+ token.type_ = tokenError;
+ token.end_ = current_;
+ return true;
+}
+
+void OurReader::skipSpaces() {
+ while (current_ != end_) {
+ Char c = *current_;
+ if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
+ ++current_;
+ else
+ break;
+ }
+}
+
+bool OurReader::match(Location pattern, int patternLength) {
+ if (end_ - current_ < patternLength)
+ return false;
+ int index = patternLength;
+ while (index--)
+ if (current_[index] != pattern[index])
+ return false;
+ current_ += patternLength;
+ return true;
+}
+
+bool OurReader::readComment() {
+ Location commentBegin = current_ - 1;
+ Char c = getNextChar();
+ bool successful = false;
+ if (c == '*')
+ successful = readCStyleComment();
+ else if (c == '/')
+ successful = readCppStyleComment();
+ if (!successful)
+ return false;
+
+ if (collectComments_) {
+ CommentPlacement placement = commentBefore;
+ if (lastValueEnd_ && !containsNewLine(lastValueEnd_, commentBegin)) {
+ if (c != '*' || !containsNewLine(commentBegin, current_))
+ placement = commentAfterOnSameLine;
+ }
+
+ addComment(commentBegin, current_, placement);
+ }
+ return true;
+}
+
+void
+OurReader::addComment(Location begin, Location end, CommentPlacement placement) {
+ assert(collectComments_);
+ const std::string& normalized = normalizeEOL(begin, end);
+ if (placement == commentAfterOnSameLine) {
+ assert(lastValue_ != 0);
+ lastValue_->setComment(normalized, placement);
+ } else {
+ commentsBefore_ += normalized;
+ }
+}
+
+bool OurReader::readCStyleComment() {
+ while (current_ != end_) {
+ Char c = getNextChar();
+ if (c == '*' && *current_ == '/')
+ break;
+ }
+ return getNextChar() == '/';
+}
+
+bool OurReader::readCppStyleComment() {
+ while (current_ != end_) {
+ Char c = getNextChar();
+ if (c == '\n')
+ break;
+ if (c == '\r') {
+ // Consume DOS EOL. It will be normalized in addComment.
+ if (current_ != end_ && *current_ == '\n')
+ getNextChar();
+ // Break on Moc OS 9 EOL.
+ break;
+ }
+ }
+ return true;
+}
+
+bool OurReader::readNumber(bool checkInf) {
+ const char *p = current_;
+ if (checkInf && p != end_ && *p == 'I') {
+ current_ = ++p;
+ return false;
+ }
+ char c = '0'; // stopgap for already consumed character
+ // integral part
+ while (c >= '0' && c <= '9')
+ c = (current_ = p) < end_ ? *p++ : 0;
+ // fractional part
+ if (c == '.') {
+ c = (current_ = p) < end_ ? *p++ : 0;
+ while (c >= '0' && c <= '9')
+ c = (current_ = p) < end_ ? *p++ : 0;
+ }
+ // exponential part
+ if (c == 'e' || c == 'E') {
+ c = (current_ = p) < end_ ? *p++ : 0;
+ if (c == '+' || c == '-')
+ c = (current_ = p) < end_ ? *p++ : 0;
+ while (c >= '0' && c <= '9')
+ c = (current_ = p) < end_ ? *p++ : 0;
+ }
+ return true;
+}
+bool OurReader::readString() {
+ Char c = 0;
+ while (current_ != end_) {
+ c = getNextChar();
+ if (c == '\\')
+ getNextChar();
+ else if (c == '"')
+ break;
+ }
+ return c == '"';
+}
+
+
+bool OurReader::readStringSingleQuote() {
+ Char c = 0;
+ while (current_ != end_) {
+ c = getNextChar();
+ if (c == '\\')
+ getNextChar();
+ else if (c == '\'')
+ break;
+ }
+ return c == '\'';
+}
+
+bool OurReader::readObject(Token& tokenStart) {
+ Token tokenName;
+ std::string name;
+ Value init(objectValue);
+ currentValue().swapPayload(init);
+ currentValue().setOffsetStart(tokenStart.start_ - begin_);
+ while (readToken(tokenName)) {
+ bool initialTokenOk = true;
+ while (tokenName.type_ == tokenComment && initialTokenOk)
+ initialTokenOk = readToken(tokenName);
+ if (!initialTokenOk)
+ break;
+ if (tokenName.type_ == tokenObjectEnd && name.empty()) // empty object
+ return true;
+ name = "";
+ if (tokenName.type_ == tokenString) {
+ if (!decodeString(tokenName, name))
+ return recoverFromError(tokenObjectEnd);
+ } else if (tokenName.type_ == tokenNumber && features_.allowNumericKeys_) {
+ Value numberName;
+ if (!decodeNumber(tokenName, numberName))
+ return recoverFromError(tokenObjectEnd);
+ name = numberName.asString();
+ } else {
+ break;
+ }
+
+ Token colon;
+ if (!readToken(colon) || colon.type_ != tokenMemberSeparator) {
+ return addErrorAndRecover(
+ "Missing ':' after object member name", colon, tokenObjectEnd);
+ }
+ if (name.length() >= (1U<<30)) throwRuntimeError("keylength >= 2^30");
+ if (features_.rejectDupKeys_ && currentValue().isMember(name)) {
+ std::string msg = "Duplicate key: '" + name + "'";
+ return addErrorAndRecover(
+ msg, tokenName, tokenObjectEnd);
+ }
+ Value& value = currentValue()[name];
+ nodes_.push(&value);
+ bool ok = readValue();
+ nodes_.pop();
+ if (!ok) // error already set
+ return recoverFromError(tokenObjectEnd);
+
+ Token comma;
+ if (!readToken(comma) ||
+ (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator &&
+ comma.type_ != tokenComment)) {
+ return addErrorAndRecover(
+ "Missing ',' or '}' in object declaration", comma, tokenObjectEnd);
+ }
+ bool finalizeTokenOk = true;
+ while (comma.type_ == tokenComment && finalizeTokenOk)
+ finalizeTokenOk = readToken(comma);
+ if (comma.type_ == tokenObjectEnd)
+ return true;
+ }
+ return addErrorAndRecover(
+ "Missing '}' or object member name", tokenName, tokenObjectEnd);
+}
+
+bool OurReader::readArray(Token& tokenStart) {
+ Value init(arrayValue);
+ currentValue().swapPayload(init);
+ currentValue().setOffsetStart(tokenStart.start_ - begin_);
+ skipSpaces();
+ if (*current_ == ']') // empty array
+ {
+ Token endArray;
+ readToken(endArray);
+ return true;
+ }
+ int index = 0;
+ for (;;) {
+ Value& value = currentValue()[index++];
+ nodes_.push(&value);
+ bool ok = readValue();
+ nodes_.pop();
+ if (!ok) // error already set
+ return recoverFromError(tokenArrayEnd);
+
+ Token token;
+ // Accept Comment after last item in the array.
+ ok = readToken(token);
+ while (token.type_ == tokenComment && ok) {
+ ok = readToken(token);
+ }
+ bool badTokenType =
+ (token.type_ != tokenArraySeparator && token.type_ != tokenArrayEnd);
+ if (!ok || badTokenType) {
+ return addErrorAndRecover(
+ "Missing ',' or ']' in array declaration", token, tokenArrayEnd);
+ }
+ if (token.type_ == tokenArrayEnd)
+ break;
+ }
+ return true;
+}
+
+bool OurReader::decodeNumber(Token& token) {
+ Value decoded;
+ if (!decodeNumber(token, decoded))
+ return false;
+ currentValue().swapPayload(decoded);
+ currentValue().setOffsetStart(token.start_ - begin_);
+ currentValue().setOffsetLimit(token.end_ - begin_);
+ return true;
+}
+
+bool OurReader::decodeNumber(Token& token, Value& decoded) {
+ // Attempts to parse the number as an integer. If the number is
+ // larger than the maximum supported value of an integer then
+ // we decode the number as a double.
+ Location current = token.start_;
+ bool isNegative = *current == '-';
+ if (isNegative)
+ ++current;
+ // TODO: Help the compiler do the div and mod at compile time or get rid of them.
+ Value::LargestUInt maxIntegerValue =
+ isNegative ? Value::LargestUInt(-Value::minLargestInt)
+ : Value::maxLargestUInt;
+ Value::LargestUInt threshold = maxIntegerValue / 10;
+ Value::LargestUInt value = 0;
+ while (current < token.end_) {
+ Char c = *current++;
+ if (c < '0' || c > '9')
+ return decodeDouble(token, decoded);
+ Value::UInt digit(c - '0');
+ if (value >= threshold) {
+ // We've hit or exceeded the max value divided by 10 (rounded down). If
+ // a) we've only just touched the limit, b) this is the last digit, and
+ // c) it's small enough to fit in that rounding delta, we're okay.
+ // Otherwise treat this number as a double to avoid overflow.
+ if (value > threshold || current != token.end_ ||
+ digit > maxIntegerValue % 10) {
+ return decodeDouble(token, decoded);
+ }
+ }
+ value = value * 10 + digit;
+ }
+ if (isNegative)
+ decoded = -Value::LargestInt(value);
+ else if (value <= Value::LargestUInt(Value::maxInt))
+ decoded = Value::LargestInt(value);
+ else
+ decoded = value;
+ return true;
+}
+
+bool OurReader::decodeDouble(Token& token) {
+ Value decoded;
+ if (!decodeDouble(token, decoded))
+ return false;
+ currentValue().swapPayload(decoded);
+ currentValue().setOffsetStart(token.start_ - begin_);
+ currentValue().setOffsetLimit(token.end_ - begin_);
+ return true;
+}
+
+bool OurReader::decodeDouble(Token& token, Value& decoded) {
+ double value = 0;
+ const int bufferSize = 32;
+ int count;
+ int length = int(token.end_ - token.start_);
+
+ // Sanity check to avoid buffer overflow exploits.
+ if (length < 0) {
+ return addError("Unable to parse token length", token);
+ }
+
+ // Avoid using a string constant for the format control string given to
+ // sscanf, as this can cause hard to debug crashes on OS X. See here for more
+ // info:
+ //
+ // http://developer.apple.com/library/mac/#DOCUMENTATION/DeveloperTools/gcc-4.0.1/gcc/Incompatibilities.html
+ char format[] = "%lf";
+
+ if (length <= bufferSize) {
+ Char buffer[bufferSize + 1];
+ memcpy(buffer, token.start_, length);
+ buffer[length] = 0;
+ count = sscanf(buffer, format, &value);
+ } else {
+ std::string buffer(token.start_, token.end_);
+ count = sscanf(buffer.c_str(), format, &value);
+ }
+
+ if (count != 1)
+ return addError("'" + std::string(token.start_, token.end_) +
+ "' is not a number.",
+ token);
+ decoded = value;
+ return true;
+}
+
+bool OurReader::decodeString(Token& token) {
+ std::string decoded_string;
+ if (!decodeString(token, decoded_string))
+ return false;
+ Value decoded(decoded_string);
+ currentValue().swapPayload(decoded);
+ currentValue().setOffsetStart(token.start_ - begin_);
+ currentValue().setOffsetLimit(token.end_ - begin_);
+ return true;
+}
+
+bool OurReader::decodeString(Token& token, std::string& decoded) {
+ decoded.reserve(token.end_ - token.start_ - 2);
+ Location current = token.start_ + 1; // skip '"'
+ Location end = token.end_ - 1; // do not include '"'
+ while (current != end) {
+ Char c = *current++;
+ if (c == '"')
+ break;
+ else if (c == '\\') {
+ if (current == end)
+ return addError("Empty escape sequence in string", token, current);
+ Char escape = *current++;
+ switch (escape) {
+ case '"':
+ decoded += '"';
+ break;
+ case '/':
+ decoded += '/';
+ break;
+ case '\\':
+ decoded += '\\';
+ break;
+ case 'b':
+ decoded += '\b';
+ break;
+ case 'f':
+ decoded += '\f';
+ break;
+ case 'n':
+ decoded += '\n';
+ break;
+ case 'r':
+ decoded += '\r';
+ break;
+ case 't':
+ decoded += '\t';
+ break;
+ case 'u': {
+ unsigned int unicode;
+ if (!decodeUnicodeCodePoint(token, current, end, unicode))
+ return false;
+ decoded += codePointToUTF8(unicode);
+ } break;
+ default:
+ return addError("Bad escape sequence in string", token, current);
+ }
+ } else {
+ decoded += c;
+ }
+ }
+ return true;
+}
+
+bool OurReader::decodeUnicodeCodePoint(Token& token,
+ Location& current,
+ Location end,
+ unsigned int& unicode) {
+
+ if (!decodeUnicodeEscapeSequence(token, current, end, unicode))
+ return false;
+ if (unicode >= 0xD800 && unicode <= 0xDBFF) {
+ // surrogate pairs
+ if (end - current < 6)
+ return addError(
+ "additional six characters expected to parse unicode surrogate pair.",
+ token,
+ current);
+ unsigned int surrogatePair;
+ if (*(current++) == '\\' && *(current++) == 'u') {
+ if (decodeUnicodeEscapeSequence(token, current, end, surrogatePair)) {
+ unicode = 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF);
+ } else
+ return false;
+ } else
+ return addError("expecting another \\u token to begin the second half of "
+ "a unicode surrogate pair",
+ token,
+ current);
+ }
+ return true;
+}
+
+bool OurReader::decodeUnicodeEscapeSequence(Token& token,
+ Location& current,
+ Location end,
+ unsigned int& unicode) {
+ if (end - current < 4)
+ return addError(
+ "Bad unicode escape sequence in string: four digits expected.",
+ token,
+ current);
+ unicode = 0;
+ for (int index = 0; index < 4; ++index) {
+ Char c = *current++;
+ unicode *= 16;
+ if (c >= '0' && c <= '9')
+ unicode += c - '0';
+ else if (c >= 'a' && c <= 'f')
+ unicode += c - 'a' + 10;
+ else if (c >= 'A' && c <= 'F')
+ unicode += c - 'A' + 10;
+ else
+ return addError(
+ "Bad unicode escape sequence in string: hexadecimal digit expected.",
+ token,
+ current);
+ }
+ return true;
+}
+
+bool
+OurReader::addError(const std::string& message, Token& token, Location extra) {
+ ErrorInfo info;
+ info.token_ = token;
+ info.message_ = message;
+ info.extra_ = extra;
+ errors_.push_back(info);
+ return false;
+}
+
+bool OurReader::recoverFromError(TokenType skipUntilToken) {
+ int errorCount = int(errors_.size());
+ Token skip;
+ for (;;) {
+ if (!readToken(skip))
+ errors_.resize(errorCount); // discard errors caused by recovery
+ if (skip.type_ == skipUntilToken || skip.type_ == tokenEndOfStream)
+ break;
+ }
+ errors_.resize(errorCount);
+ return false;
+}
+
+bool OurReader::addErrorAndRecover(const std::string& message,
+ Token& token,
+ TokenType skipUntilToken) {
+ addError(message, token);
+ return recoverFromError(skipUntilToken);
+}
+
+Value& OurReader::currentValue() { return *(nodes_.top()); }
+
+OurReader::Char OurReader::getNextChar() {
+ if (current_ == end_)
+ return 0;
+ return *current_++;
+}
+
+void OurReader::getLocationLineAndColumn(Location location,
+ int& line,
+ int& column) const {
+ Location current = begin_;
+ Location lastLineStart = current;
+ line = 0;
+ while (current < location && current != end_) {
+ Char c = *current++;
+ if (c == '\r') {
+ if (*current == '\n')
+ ++current;
+ lastLineStart = current;
+ ++line;
+ } else if (c == '\n') {
+ lastLineStart = current;
+ ++line;
+ }
+ }
+ // column & line start at 1
+ column = int(location - lastLineStart) + 1;
+ ++line;
+}
+
+std::string OurReader::getLocationLineAndColumn(Location location) const {
+ int line, column;
+ getLocationLineAndColumn(location, line, column);
+ char buffer[18 + 16 + 16 + 1];
+ snprintf(buffer, sizeof(buffer), "Line %d, Column %d", line, column);
+ return buffer;
+}
+
+std::string OurReader::getFormattedErrorMessages() const {
+ std::string formattedMessage;
+ for (Errors::const_iterator itError = errors_.begin();
+ itError != errors_.end();
+ ++itError) {
+ const ErrorInfo& error = *itError;
+ formattedMessage +=
+ "* " + getLocationLineAndColumn(error.token_.start_) + "\n";
+ formattedMessage += " " + error.message_ + "\n";
+ if (error.extra_)
+ formattedMessage +=
+ "See " + getLocationLineAndColumn(error.extra_) + " for detail.\n";
+ }
+ return formattedMessage;
+}
+
+std::vector<OurReader::StructuredError> OurReader::getStructuredErrors() const {
+ std::vector<OurReader::StructuredError> allErrors;
+ for (Errors::const_iterator itError = errors_.begin();
+ itError != errors_.end();
+ ++itError) {
+ const ErrorInfo& error = *itError;
+ OurReader::StructuredError structured;
+ structured.offset_start = error.token_.start_ - begin_;
+ structured.offset_limit = error.token_.end_ - begin_;
+ structured.message = error.message_;
+ allErrors.push_back(structured);
+ }
+ return allErrors;
+}
+
+bool OurReader::pushError(const Value& value, const std::string& message) {
+ size_t length = end_ - begin_;
+ if(value.getOffsetStart() > length
+ || value.getOffsetLimit() > length)
+ return false;
+ Token token;
+ token.type_ = tokenError;
+ token.start_ = begin_ + value.getOffsetStart();
+ token.end_ = end_ + value.getOffsetLimit();
+ ErrorInfo info;
+ info.token_ = token;
+ info.message_ = message;
+ info.extra_ = 0;
+ errors_.push_back(info);
+ return true;
+}
+
+bool OurReader::pushError(const Value& value, const std::string& message, const Value& extra) {
+ size_t length = end_ - begin_;
+ if(value.getOffsetStart() > length
+ || value.getOffsetLimit() > length
+ || extra.getOffsetLimit() > length)
+ return false;
+ Token token;
+ token.type_ = tokenError;
+ token.start_ = begin_ + value.getOffsetStart();
+ token.end_ = begin_ + value.getOffsetLimit();
+ ErrorInfo info;
+ info.token_ = token;
+ info.message_ = message;
+ info.extra_ = begin_ + extra.getOffsetStart();
+ errors_.push_back(info);
+ return true;
+}
+
+bool OurReader::good() const {
+ return !errors_.size();
+}
+
+
+class OurCharReader : public CharReader {
+ bool const collectComments_;
+ OurReader reader_;
+public:
+ OurCharReader(
+ bool collectComments,
+ OurFeatures const& features)
+ : collectComments_(collectComments)
+ , reader_(features)
+ {}
+ bool parse(
+ char const* beginDoc, char const* endDoc,
+ Value* root, std::string* errs) override {
+ bool ok = reader_.parse(beginDoc, endDoc, *root, collectComments_);
+ if (errs) {
+ *errs = reader_.getFormattedErrorMessages();
+ }
+ return ok;
+ }
+};
+
+CharReaderBuilder::CharReaderBuilder()
+{
+ setDefaults(&settings_);
+}
+CharReaderBuilder::~CharReaderBuilder()
+{}
+CharReader* CharReaderBuilder::newCharReader() const
+{
+ bool collectComments = settings_["collectComments"].asBool();
+ OurFeatures features = OurFeatures::all();
+ features.allowComments_ = settings_["allowComments"].asBool();
+ features.strictRoot_ = settings_["strictRoot"].asBool();
+ features.allowDroppedNullPlaceholders_ = settings_["allowDroppedNullPlaceholders"].asBool();
+ features.allowNumericKeys_ = settings_["allowNumericKeys"].asBool();
+ features.allowSingleQuotes_ = settings_["allowSingleQuotes"].asBool();
+ features.stackLimit_ = settings_["stackLimit"].asInt();
+ features.failIfExtra_ = settings_["failIfExtra"].asBool();
+ features.rejectDupKeys_ = settings_["rejectDupKeys"].asBool();
+ features.allowSpecialFloats_ = settings_["allowSpecialFloats"].asBool();
+ return new OurCharReader(collectComments, features);
+}
+static void getValidReaderKeys(std::set<std::string>* valid_keys)
+{
+ valid_keys->clear();
+ valid_keys->insert("collectComments");
+ valid_keys->insert("allowComments");
+ valid_keys->insert("strictRoot");
+ valid_keys->insert("allowDroppedNullPlaceholders");
+ valid_keys->insert("allowNumericKeys");
+ valid_keys->insert("allowSingleQuotes");
+ valid_keys->insert("stackLimit");
+ valid_keys->insert("failIfExtra");
+ valid_keys->insert("rejectDupKeys");
+ valid_keys->insert("allowSpecialFloats");
+}
+bool CharReaderBuilder::validate(Json::Value* invalid) const
+{
+ Json::Value my_invalid;
+ if (!invalid) invalid = &my_invalid; // so we do not need to test for NULL
+ Json::Value& inv = *invalid;
+ std::set<std::string> valid_keys;
+ getValidReaderKeys(&valid_keys);
+ Value::Members keys = settings_.getMemberNames();
+ size_t n = keys.size();
+ for (size_t i = 0; i < n; ++i) {
+ std::string const& key = keys[i];
+ if (valid_keys.find(key) == valid_keys.end()) {
+ inv[key] = settings_[key];
+ }
+ }
+ return 0u == inv.size();
+}
+Value& CharReaderBuilder::operator[](std::string key)
+{
+ return settings_[key];
+}
+// static
+void CharReaderBuilder::strictMode(Json::Value* settings)
+{
+//! [CharReaderBuilderStrictMode]
+ (*settings)["allowComments"] = false;
+ (*settings)["strictRoot"] = true;
+ (*settings)["allowDroppedNullPlaceholders"] = false;
+ (*settings)["allowNumericKeys"] = false;
+ (*settings)["allowSingleQuotes"] = false;
+ (*settings)["stackLimit"] = 1000;
+ (*settings)["failIfExtra"] = true;
+ (*settings)["rejectDupKeys"] = true;
+ (*settings)["allowSpecialFloats"] = false;
+//! [CharReaderBuilderStrictMode]
+}
+// static
+void CharReaderBuilder::setDefaults(Json::Value* settings)
+{
+//! [CharReaderBuilderDefaults]
+ (*settings)["collectComments"] = true;
+ (*settings)["allowComments"] = true;
+ (*settings)["strictRoot"] = false;
+ (*settings)["allowDroppedNullPlaceholders"] = false;
+ (*settings)["allowNumericKeys"] = false;
+ (*settings)["allowSingleQuotes"] = false;
+ (*settings)["stackLimit"] = 1000;
+ (*settings)["failIfExtra"] = false;
+ (*settings)["rejectDupKeys"] = false;
+ (*settings)["allowSpecialFloats"] = false;
+//! [CharReaderBuilderDefaults]
+}
+
+//////////////////////////////////
+// global functions
+
+bool parseFromStream(
+ CharReader::Factory const& fact, std::istream& sin,
+ Value* root, std::string* errs)
+{
+ std::ostringstream ssin;
+ ssin << sin.rdbuf();
+ std::string doc = ssin.str();
+ char const* begin = doc.data();
+ char const* end = begin + doc.size();
+ // Note that we do not actually need a null-terminator.
+ CharReaderPtr const reader(fact.newCharReader());
+ return reader->parse(begin, end, root, errs);
+}
+
+std::istream& operator>>(std::istream& sin, Value& root) {
+ CharReaderBuilder b;
+ std::string errs;
+ bool ok = parseFromStream(b, sin, &root, &errs);
+ if (!ok) {
+ fprintf(stderr,
+ "Error from reader: %s",
+ errs.c_str());
+
+ throwRuntimeError(errs);
+ }
+ return sin;
+}
+
+} // namespace Json
+
+// //////////////////////////////////////////////////////////////////////
+// End of content of file: src/lib_json/json_reader.cpp
+// //////////////////////////////////////////////////////////////////////
+
+
+
+
+
+
+// //////////////////////////////////////////////////////////////////////
+// Beginning of content of file: src/lib_json/json_valueiterator.inl
+// //////////////////////////////////////////////////////////////////////
+
+// Copyright 2007-2010 Baptiste Lepilleur
+// Distributed under MIT license, or public domain if desired and
+// recognized in your jurisdiction.
+// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
+
+// included by json_value.cpp
+
+namespace Json {
+
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// class ValueIteratorBase
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+
+ValueIteratorBase::ValueIteratorBase()
+ : current_(), isNull_(true) {
+}
+
+ValueIteratorBase::ValueIteratorBase(
+ const Value::ObjectValues::iterator& current)
+ : current_(current), isNull_(false) {}
+
+Value& ValueIteratorBase::deref() const {
+ return current_->second;
+}
+
+void ValueIteratorBase::increment() {
+ ++current_;
+}
+
+void ValueIteratorBase::decrement() {
+ --current_;
+}
+
+ValueIteratorBase::difference_type
+ValueIteratorBase::computeDistance(const SelfType& other) const {
+#ifdef JSON_USE_CPPTL_SMALLMAP
+ return other.current_ - current_;
+#else
+ // Iterator for null value are initialized using the default
+ // constructor, which initialize current_ to the default
+ // std::map::iterator. As begin() and end() are two instance
+ // of the default std::map::iterator, they can not be compared.
+ // To allow this, we handle this comparison specifically.
+ if (isNull_ && other.isNull_) {
+ return 0;
+ }
+
+ // Usage of std::distance is not portable (does not compile with Sun Studio 12
+ // RogueWave STL,
+ // which is the one used by default).
+ // Using a portable hand-made version for non random iterator instead:
+ // return difference_type( std::distance( current_, other.current_ ) );
+ difference_type myDistance = 0;
+ for (Value::ObjectValues::iterator it = current_; it != other.current_;
+ ++it) {
+ ++myDistance;
+ }
+ return myDistance;
+#endif
+}
+
+bool ValueIteratorBase::isEqual(const SelfType& other) const {
+ if (isNull_) {
+ return other.isNull_;
+ }
+ return current_ == other.current_;
+}
+
+void ValueIteratorBase::copy(const SelfType& other) {
+ current_ = other.current_;
+ isNull_ = other.isNull_;
+}
+
+Value ValueIteratorBase::key() const {
+ const Value::CZString czstring = (*current_).first;
+ if (czstring.data()) {
+ if (czstring.isStaticString())
+ return Value(StaticString(czstring.data()));
+ return Value(czstring.data(), czstring.data() + czstring.length());
+ }
+ return Value(czstring.index());
+}
+
+UInt ValueIteratorBase::index() const {
+ const Value::CZString czstring = (*current_).first;
+ if (!czstring.data())
+ return czstring.index();
+ return Value::UInt(-1);
+}
+
+std::string ValueIteratorBase::name() const {
+ char const* keey;
+ char const* end;
+ keey = memberName(&end);
+ if (!keey) return std::string();
+ return std::string(keey, end);
+}
+
+char const* ValueIteratorBase::memberName() const {
+ const char* cname = (*current_).first.data();
+ return cname ? cname : "";
+}
+
+char const* ValueIteratorBase::memberName(char const** end) const {
+ const char* cname = (*current_).first.data();
+ if (!cname) {
+ *end = NULL;
+ return NULL;
+ }
+ *end = cname + (*current_).first.length();
+ return cname;
+}
+
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// class ValueConstIterator
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+
+ValueConstIterator::ValueConstIterator() {}
+
+ValueConstIterator::ValueConstIterator(
+ const Value::ObjectValues::iterator& current)
+ : ValueIteratorBase(current) {}
+
+ValueConstIterator::ValueConstIterator(ValueIterator const& other)
+ : ValueIteratorBase(other) {}
+
+ValueConstIterator& ValueConstIterator::
+operator=(const ValueIteratorBase& other) {
+ copy(other);
+ return *this;
+}
+
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// class ValueIterator
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+
+ValueIterator::ValueIterator() {}
+
+ValueIterator::ValueIterator(const Value::ObjectValues::iterator& current)
+ : ValueIteratorBase(current) {}
+
+ValueIterator::ValueIterator(const ValueConstIterator& other)
+ : ValueIteratorBase(other) {
+ throwRuntimeError("ConstIterator to Iterator should never be allowed.");
+}
+
+ValueIterator::ValueIterator(const ValueIterator& other)
+ : ValueIteratorBase(other) {}
+
+ValueIterator& ValueIterator::operator=(const SelfType& other) {
+ copy(other);
+ return *this;
+}
+
+} // namespace Json
+
+// //////////////////////////////////////////////////////////////////////
+// End of content of file: src/lib_json/json_valueiterator.inl
+// //////////////////////////////////////////////////////////////////////
+
+
+
+
+
+
+// //////////////////////////////////////////////////////////////////////
+// Beginning of content of file: src/lib_json/json_value.cpp
+// //////////////////////////////////////////////////////////////////////
+
+// Copyright 2011 Baptiste Lepilleur
+// Distributed under MIT license, or public domain if desired and
+// recognized in your jurisdiction.
+// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
+
+#if !defined(JSON_IS_AMALGAMATION)
+#include <json/assertions.h>
+#include <json/value.h>
+#include <json/writer.h>
+#endif // if !defined(JSON_IS_AMALGAMATION)
+#include <math.h>
+#include <sstream>
+#include <utility>
+#include <cstring>
+#include <cassert>
+#ifdef JSON_USE_CPPTL
+#include <cpptl/conststring.h>
+#endif
+#include <cstddef> // size_t
+#include <algorithm> // min()
+
+#define JSON_ASSERT_UNREACHABLE assert(false)
+
+namespace Json {
+
+// This is a walkaround to avoid the static initialization of Value::null.
+// kNull must be word-aligned to avoid crashing on ARM. We use an alignment of
+// 8 (instead of 4) as a bit of future-proofing.
+#if defined(__ARMEL__)
+#define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment)))
+#else
+#define ALIGNAS(byte_alignment)
+#endif
+static const unsigned char ALIGNAS(8) kNull[sizeof(Value)] = { 0 };
+const unsigned char& kNullRef = kNull[0];
+const Value& Value::null = reinterpret_cast<const Value&>(kNullRef);
+const Value& Value::nullRef = null;
+
+const Int Value::minInt = Int(~(UInt(-1) / 2));
+const Int Value::maxInt = Int(UInt(-1) / 2);
+const UInt Value::maxUInt = UInt(-1);
+#if defined(JSON_HAS_INT64)
+const Int64 Value::minInt64 = Int64(~(UInt64(-1) / 2));
+const Int64 Value::maxInt64 = Int64(UInt64(-1) / 2);
+const UInt64 Value::maxUInt64 = UInt64(-1);
+// The constant is hard-coded because some compiler have trouble
+// converting Value::maxUInt64 to a double correctly (AIX/xlC).
+// Assumes that UInt64 is a 64 bits integer.
+static const double maxUInt64AsDouble = 18446744073709551615.0;
+#endif // defined(JSON_HAS_INT64)
+const LargestInt Value::minLargestInt = LargestInt(~(LargestUInt(-1) / 2));
+const LargestInt Value::maxLargestInt = LargestInt(LargestUInt(-1) / 2);
+const LargestUInt Value::maxLargestUInt = LargestUInt(-1);
+
+#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
+template <typename T, typename U>
+static inline bool InRange(double d, T min, U max) {
+ return d >= min && d <= max;
+}
+#else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
+static inline double integerToDouble(Json::UInt64 value) {
+ return static_cast<double>(Int64(value / 2)) * 2.0 + Int64(value & 1);
+}
+
+template <typename T> static inline double integerToDouble(T value) {
+ return static_cast<double>(value);
+}
+
+template <typename T, typename U>
+static inline bool InRange(double d, T min, U max) {
+ return d >= integerToDouble(min) && d <= integerToDouble(max);
+}
+#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
+
+/** Duplicates the specified string value.
+ * @param value Pointer to the string to duplicate. Must be zero-terminated if
+ * length is "unknown".
+ * @param length Length of the value. if equals to unknown, then it will be
+ * computed using strlen(value).
+ * @return Pointer on the duplicate instance of string.
+ */
+static inline char* duplicateStringValue(const char* value,
+ size_t length) {
+ // Avoid an integer overflow in the call to malloc below by limiting length
+ // to a sane value.
+ if (length >= (size_t)Value::maxInt)
+ length = Value::maxInt - 1;
+
+ char* newString = static_cast<char*>(malloc(length + 1));
+ if (newString == NULL) {
+ throwRuntimeError(
+ "in Json::Value::duplicateStringValue(): "
+ "Failed to allocate string value buffer");
+ }
+ memcpy(newString, value, length);
+ newString[length] = 0;
+ return newString;
+}
+
+/* Record the length as a prefix.
+ */
+static inline char* duplicateAndPrefixStringValue(
+ const char* value,
+ unsigned int length)
+{
+ // Avoid an integer overflow in the call to malloc below by limiting length
+ // to a sane value.
+ JSON_ASSERT_MESSAGE(length <= (unsigned)Value::maxInt - sizeof(unsigned) - 1U,
+ "in Json::Value::duplicateAndPrefixStringValue(): "
+ "length too big for prefixing");
+ unsigned actualLength = length + static_cast<unsigned>(sizeof(unsigned)) + 1U;
+ char* newString = static_cast<char*>(malloc(actualLength));
+ if (newString == 0) {
+ throwRuntimeError(
+ "in Json::Value::duplicateAndPrefixStringValue(): "
+ "Failed to allocate string value buffer");
+ }
+ *reinterpret_cast<unsigned*>(newString) = length;
+ memcpy(newString + sizeof(unsigned), value, length);
+ newString[actualLength - 1U] = 0; // to avoid buffer over-run accidents by users later
+ return newString;
+}
+inline static void decodePrefixedString(
+ bool isPrefixed, char const* prefixed,
+ unsigned* length, char const** value)
+{
+ if (!isPrefixed) {
+ *length = static_cast<unsigned>(strlen(prefixed));
+ *value = prefixed;
+ } else {
+ *length = *reinterpret_cast<unsigned const*>(prefixed);
+ *value = prefixed + sizeof(unsigned);
+ }
+}
+/** Free the string duplicated by duplicateStringValue()/duplicateAndPrefixStringValue().
+ */
+static inline void releaseStringValue(char* value) { free(value); }
+
+} // namespace Json
+
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// ValueInternals...
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+#if !defined(JSON_IS_AMALGAMATION)
+
+#include "json_valueiterator.inl"
+#endif // if !defined(JSON_IS_AMALGAMATION)
+
+namespace Json {
+
+Exception::Exception(std::string const& msg)
+ : msg_(msg)
+{}
+Exception::~Exception() throw()
+{}
+char const* Exception::what() const throw()
+{
+ return msg_.c_str();
+}
+RuntimeError::RuntimeError(std::string const& msg)
+ : Exception(msg)
+{}
+LogicError::LogicError(std::string const& msg)
+ : Exception(msg)
+{}
+void throwRuntimeError(std::string const& msg)
+{
+ throw RuntimeError(msg);
+}
+void throwLogicError(std::string const& msg)
+{
+ throw LogicError(msg);
+}
+
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// class Value::CommentInfo
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+
+Value::CommentInfo::CommentInfo() : comment_(0) {}
+
+Value::CommentInfo::~CommentInfo() {
+ if (comment_)
+ releaseStringValue(comment_);
+}
+
+void Value::CommentInfo::setComment(const char* text, size_t len) {
+ if (comment_) {
+ releaseStringValue(comment_);
+ comment_ = 0;
+ }
+ JSON_ASSERT(text != 0);
+ JSON_ASSERT_MESSAGE(
+ text[0] == '\0' || text[0] == '/',
+ "in Json::Value::setComment(): Comments must start with /");
+ // It seems that /**/ style comments are acceptable as well.
+ comment_ = duplicateStringValue(text, len);
+}
+
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// class Value::CZString
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+
+// Notes: policy_ indicates if the string was allocated when
+// a string is stored.
+
+Value::CZString::CZString(ArrayIndex aindex) : cstr_(0), index_(aindex) {}
+
+Value::CZString::CZString(char const* str, unsigned ulength, DuplicationPolicy allocate)
+ : cstr_(str) {
+ // allocate != duplicate
+ storage_.policy_ = allocate & 0x3;
+ storage_.length_ = ulength & 0x3FFFFFFF;
+}
+
+Value::CZString::CZString(const CZString& other)
+ : cstr_(other.storage_.policy_ != noDuplication && other.cstr_ != 0
+ ? duplicateStringValue(other.cstr_, other.storage_.length_)
+ : other.cstr_) {
+ storage_.policy_ = (other.cstr_
+ ? (static_cast<DuplicationPolicy>(other.storage_.policy_) == noDuplication
+ ? noDuplication : duplicate)
+ : static_cast<DuplicationPolicy>(other.storage_.policy_));
+ storage_.length_ = other.storage_.length_;
+}
+
+#if JSON_HAS_RVALUE_REFERENCES
+Value::CZString::CZString(CZString&& other)
+ : cstr_(other.cstr_), index_(other.index_) {
+ other.cstr_ = nullptr;
+}
+#endif
+
+Value::CZString::~CZString() {
+ if (cstr_ && storage_.policy_ == duplicate)
+ releaseStringValue(const_cast<char*>(cstr_));
+}
+
+void Value::CZString::swap(CZString& other) {
+ std::swap(cstr_, other.cstr_);
+ std::swap(index_, other.index_);
+}
+
+Value::CZString& Value::CZString::operator=(CZString other) {
+ swap(other);
+ return *this;
+}
+
+bool Value::CZString::operator<(const CZString& other) const {
+ if (!cstr_) return index_ < other.index_;
+ //return strcmp(cstr_, other.cstr_) < 0;
+ // Assume both are strings.
+ unsigned this_len = this->storage_.length_;
+ unsigned other_len = other.storage_.length_;
+ unsigned min_len = std::min(this_len, other_len);
+ int comp = memcmp(this->cstr_, other.cstr_, min_len);
+ if (comp < 0) return true;
+ if (comp > 0) return false;
+ return (this_len < other_len);
+}
+
+bool Value::CZString::operator==(const CZString& other) const {
+ if (!cstr_) return index_ == other.index_;
+ //return strcmp(cstr_, other.cstr_) == 0;
+ // Assume both are strings.
+ unsigned this_len = this->storage_.length_;
+ unsigned other_len = other.storage_.length_;
+ if (this_len != other_len) return false;
+ int comp = memcmp(this->cstr_, other.cstr_, this_len);
+ return comp == 0;
+}
+
+ArrayIndex Value::CZString::index() const { return index_; }
+
+//const char* Value::CZString::c_str() const { return cstr_; }
+const char* Value::CZString::data() const { return cstr_; }
+unsigned Value::CZString::length() const { return storage_.length_; }
+bool Value::CZString::isStaticString() const { return storage_.policy_ == noDuplication; }
+
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// class Value::Value
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+
+/*! \internal Default constructor initialization must be equivalent to:
+ * memset( this, 0, sizeof(Value) )
+ * This optimization is used in ValueInternalMap fast allocator.
+ */
+Value::Value(ValueType vtype) {
+ initBasic(vtype);
+ switch (vtype) {
+ case nullValue:
+ break;
+ case intValue:
+ case uintValue:
+ value_.int_ = 0;
+ break;
+ case realValue:
+ value_.real_ = 0.0;
+ break;
+ case stringValue:
+ value_.string_ = 0;
+ break;
+ case arrayValue:
+ case objectValue:
+ value_.map_ = new ObjectValues();
+ break;
+ case booleanValue:
+ value_.bool_ = false;
+ break;
+ default:
+ JSON_ASSERT_UNREACHABLE;
+ }
+}
+
+Value::Value(Int value) {
+ initBasic(intValue);
+ value_.int_ = value;
+}
+
+Value::Value(UInt value) {
+ initBasic(uintValue);
+ value_.uint_ = value;
+}
+#if defined(JSON_HAS_INT64)
+Value::Value(Int64 value) {
+ initBasic(intValue);
+ value_.int_ = value;
+}
+Value::Value(UInt64 value) {
+ initBasic(uintValue);
+ value_.uint_ = value;
+}
+#endif // defined(JSON_HAS_INT64)
+
+Value::Value(double value) {
+ initBasic(realValue);
+ value_.real_ = value;
+}
+
+Value::Value(const char* value) {
+ initBasic(stringValue, true);
+ value_.string_ = duplicateAndPrefixStringValue(value, static_cast<unsigned>(strlen(value)));
+}
+
+Value::Value(const char* beginValue, const char* endValue) {
+ initBasic(stringValue, true);
+ value_.string_ =
+ duplicateAndPrefixStringValue(beginValue, static_cast<unsigned>(endValue - beginValue));
+}
+
+Value::Value(const std::string& value) {
+ initBasic(stringValue, true);
+ value_.string_ =
+ duplicateAndPrefixStringValue(value.data(), static_cast<unsigned>(value.length()));
+}
+
+Value::Value(const StaticString& value) {
+ initBasic(stringValue);
+ value_.string_ = const_cast<char*>(value.c_str());
+}
+
+#ifdef JSON_USE_CPPTL
+Value::Value(const CppTL::ConstString& value) {
+ initBasic(stringValue, true);
+ value_.string_ = duplicateAndPrefixStringValue(value, static_cast<unsigned>(value.length()));
+}
+#endif
+
+Value::Value(bool value) {
+ initBasic(booleanValue);
+ value_.bool_ = value;
+}
+
+Value::Value(Value const& other)
+ : type_(other.type_), allocated_(false)
+ ,
+ comments_(0), start_(other.start_), limit_(other.limit_)
+{
+ switch (type_) {
+ case nullValue:
+ case intValue:
+ case uintValue:
+ case realValue:
+ case booleanValue:
+ value_ = other.value_;
+ break;
+ case stringValue:
+ if (other.value_.string_ && other.allocated_) {
+ unsigned len;
+ char const* str;
+ decodePrefixedString(other.allocated_, other.value_.string_,
+ &len, &str);
+ value_.string_ = duplicateAndPrefixStringValue(str, len);
+ allocated_ = true;
+ } else {
+ value_.string_ = other.value_.string_;
+ allocated_ = false;
+ }
+ break;
+ case arrayValue:
+ case objectValue:
+ value_.map_ = new ObjectValues(*other.value_.map_);
+ break;
+ default:
+ JSON_ASSERT_UNREACHABLE;
+ }
+ if (other.comments_) {
+ comments_ = new CommentInfo[numberOfCommentPlacement];
+ for (int comment = 0; comment < numberOfCommentPlacement; ++comment) {
+ const CommentInfo& otherComment = other.comments_[comment];
+ if (otherComment.comment_)
+ comments_[comment].setComment(
+ otherComment.comment_, strlen(otherComment.comment_));
+ }
+ }
+}
+
+#if JSON_HAS_RVALUE_REFERENCES
+// Move constructor
+Value::Value(Value&& other) {
+ initBasic(nullValue);
+ swap(other);
+}
+#endif
+
+Value::~Value() {
+ switch (type_) {
+ case nullValue:
+ case intValue:
+ case uintValue:
+ case realValue:
+ case booleanValue:
+ break;
+ case stringValue:
+ if (allocated_)
+ releaseStringValue(value_.string_);
+ break;
+ case arrayValue:
+ case objectValue:
+ delete value_.map_;
+ break;
+ default:
+ JSON_ASSERT_UNREACHABLE;
+ }
+
+ if (comments_)
+ delete[] comments_;
+}
+
+Value& Value::operator=(Value other) {
+ swap(other);
+ return *this;
+}
+
+void Value::swapPayload(Value& other) {
+ ValueType temp = type_;
+ type_ = other.type_;
+ other.type_ = temp;
+ std::swap(value_, other.value_);
+ int temp2 = allocated_;
+ allocated_ = other.allocated_;
+ other.allocated_ = temp2 & 0x1;
+}
+
+void Value::swap(Value& other) {
+ swapPayload(other);
+ std::swap(comments_, other.comments_);
+ std::swap(start_, other.start_);
+ std::swap(limit_, other.limit_);
+}
+
+ValueType Value::type() const { return type_; }
+
+int Value::compare(const Value& other) const {
+ if (*this < other)
+ return -1;
+ if (*this > other)
+ return 1;
+ return 0;
+}
+
+bool Value::operator<(const Value& other) const {
+ int typeDelta = type_ - other.type_;
+ if (typeDelta)
+ return typeDelta < 0 ? true : false;
+ switch (type_) {
+ case nullValue:
+ return false;
+ case intValue:
+ return value_.int_ < other.value_.int_;
+ case uintValue:
+ return value_.uint_ < other.value_.uint_;
+ case realValue:
+ return value_.real_ < other.value_.real_;
+ case booleanValue:
+ return value_.bool_ < other.value_.bool_;
+ case stringValue:
+ {
+ if ((value_.string_ == 0) || (other.value_.string_ == 0)) {
+ if (other.value_.string_) return true;
+ else return false;
+ }
+ unsigned this_len;
+ unsigned other_len;
+ char const* this_str;
+ char const* other_str;
+ decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str);
+ decodePrefixedString(other.allocated_, other.value_.string_, &other_len, &other_str);
+ unsigned min_len = std::min(this_len, other_len);
+ int comp = memcmp(this_str, other_str, min_len);
+ if (comp < 0) return true;
+ if (comp > 0) return false;
+ return (this_len < other_len);
+ }
+ case arrayValue:
+ case objectValue: {
+ int delta = int(value_.map_->size() - other.value_.map_->size());
+ if (delta)
+ return delta < 0;
+ return (*value_.map_) < (*other.value_.map_);
+ }
+ default:
+ JSON_ASSERT_UNREACHABLE;
+ }
+ return false; // unreachable
+}
+
+bool Value::operator<=(const Value& other) const { return !(other < *this); }
+
+bool Value::operator>=(const Value& other) const { return !(*this < other); }
+
+bool Value::operator>(const Value& other) const { return other < *this; }
+
+bool Value::operator==(const Value& other) const {
+ // if ( type_ != other.type_ )
+ // GCC 2.95.3 says:
+ // attempt to take address of bit-field structure member `Json::Value::type_'
+ // Beats me, but a temp solves the problem.
+ int temp = other.type_;
+ if (type_ != temp)
+ return false;
+ switch (type_) {
+ case nullValue:
+ return true;
+ case intValue:
+ return value_.int_ == other.value_.int_;
+ case uintValue:
+ return value_.uint_ == other.value_.uint_;
+ case realValue:
+ return value_.real_ == other.value_.real_;
+ case booleanValue:
+ return value_.bool_ == other.value_.bool_;
+ case stringValue:
+ {
+ if ((value_.string_ == 0) || (other.value_.string_ == 0)) {
+ return (value_.string_ == other.value_.string_);
+ }
+ unsigned this_len;
+ unsigned other_len;
+ char const* this_str;
+ char const* other_str;
+ decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str);
+ decodePrefixedString(other.allocated_, other.value_.string_, &other_len, &other_str);
+ if (this_len != other_len) return false;
+ int comp = memcmp(this_str, other_str, this_len);
+ return comp == 0;
+ }
+ case arrayValue:
+ case objectValue:
+ return value_.map_->size() == other.value_.map_->size() &&
+ (*value_.map_) == (*other.value_.map_);
+ default:
+ JSON_ASSERT_UNREACHABLE;
+ }
+ return false; // unreachable
+}
+
+bool Value::operator!=(const Value& other) const { return !(*this == other); }
+
+const char* Value::asCString() const {
+ JSON_ASSERT_MESSAGE(type_ == stringValue,
+ "in Json::Value::asCString(): requires stringValue");
+ if (value_.string_ == 0) return 0;
+ unsigned this_len;
+ char const* this_str;
+ decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str);
+ return this_str;
+}
+
+bool Value::getString(char const** str, char const** cend) const {
+ if (type_ != stringValue) return false;
+ if (value_.string_ == 0) return false;
+ unsigned length;
+ decodePrefixedString(this->allocated_, this->value_.string_, &length, str);
+ *cend = *str + length;
+ return true;
+}
+
+std::string Value::asString() const {
+ switch (type_) {
+ case nullValue:
+ return "";
+ case stringValue:
+ {
+ if (value_.string_ == 0) return "";
+ unsigned this_len;
+ char const* this_str;
+ decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str);
+ return std::string(this_str, this_len);
+ }
+ case booleanValue:
+ return value_.bool_ ? "true" : "false";
+ case intValue:
+ return valueToString(value_.int_);
+ case uintValue:
+ return valueToString(value_.uint_);
+ case realValue:
+ return valueToString(value_.real_);
+ default:
+ JSON_FAIL_MESSAGE("Type is not convertible to string");
+ }
+}
+
+#ifdef JSON_USE_CPPTL
+CppTL::ConstString Value::asConstString() const {
+ unsigned len;
+ char const* str;
+ decodePrefixedString(allocated_, value_.string_,
+ &len, &str);
+ return CppTL::ConstString(str, len);
+}
+#endif
+
+Value::Int Value::asInt() const {
+ switch (type_) {
+ case intValue:
+ JSON_ASSERT_MESSAGE(isInt(), "LargestInt out of Int range");
+ return Int(value_.int_);
+ case uintValue:
+ JSON_ASSERT_MESSAGE(isInt(), "LargestUInt out of Int range");
+ return Int(value_.uint_);
+ case realValue:
+ JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt, maxInt),
+ "double out of Int range");
+ return Int(value_.real_);
+ case nullValue:
+ return 0;
+ case booleanValue:
+ return value_.bool_ ? 1 : 0;
+ default:
+ break;
+ }
+ JSON_FAIL_MESSAGE("Value is not convertible to Int.");
+}
+
+Value::UInt Value::asUInt() const {
+ switch (type_) {
+ case intValue:
+ JSON_ASSERT_MESSAGE(isUInt(), "LargestInt out of UInt range");
+ return UInt(value_.int_);
+ case uintValue:
+ JSON_ASSERT_MESSAGE(isUInt(), "LargestUInt out of UInt range");
+ return UInt(value_.uint_);
+ case realValue:
+ JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt),
+ "double out of UInt range");
+ return UInt(value_.real_);
+ case nullValue:
+ return 0;
+ case booleanValue:
+ return value_.bool_ ? 1 : 0;
+ default:
+ break;
+ }
+ JSON_FAIL_MESSAGE("Value is not convertible to UInt.");
+}
+
+#if defined(JSON_HAS_INT64)
+
+Value::Int64 Value::asInt64() const {
+ switch (type_) {
+ case intValue:
+ return Int64(value_.int_);
+ case uintValue:
+ JSON_ASSERT_MESSAGE(isInt64(), "LargestUInt out of Int64 range");
+ return Int64(value_.uint_);
+ case realValue:
+ JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt64, maxInt64),
+ "double out of Int64 range");
+ return Int64(value_.real_);
+ case nullValue:
+ return 0;
+ case booleanValue:
+ return value_.bool_ ? 1 : 0;
+ default:
+ break;
+ }
+ JSON_FAIL_MESSAGE("Value is not convertible to Int64.");
+}
+
+Value::UInt64 Value::asUInt64() const {
+ switch (type_) {
+ case intValue:
+ JSON_ASSERT_MESSAGE(isUInt64(), "LargestInt out of UInt64 range");
+ return UInt64(value_.int_);
+ case uintValue:
+ return UInt64(value_.uint_);
+ case realValue:
+ JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt64),
+ "double out of UInt64 range");
+ return UInt64(value_.real_);
+ case nullValue:
+ return 0;
+ case booleanValue:
+ return value_.bool_ ? 1 : 0;
+ default:
+ break;
+ }
+ JSON_FAIL_MESSAGE("Value is not convertible to UInt64.");
+}
+#endif // if defined(JSON_HAS_INT64)
+
+LargestInt Value::asLargestInt() const {
+#if defined(JSON_NO_INT64)
+ return asInt();
+#else
+ return asInt64();
+#endif
+}
+
+LargestUInt Value::asLargestUInt() const {
+#if defined(JSON_NO_INT64)
+ return asUInt();
+#else
+ return asUInt64();
+#endif
+}
+
+double Value::asDouble() const {
+ switch (type_) {
+ case intValue:
+ return static_cast<double>(value_.int_);
+ case uintValue:
+#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
+ return static_cast<double>(value_.uint_);
+#else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
+ return integerToDouble(value_.uint_);
+#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
+ case realValue:
+ return value_.real_;
+ case nullValue:
+ return 0.0;
+ case booleanValue:
+ return value_.bool_ ? 1.0 : 0.0;
+ default:
+ break;
+ }
+ JSON_FAIL_MESSAGE("Value is not convertible to double.");
+}
+
+float Value::asFloat() const {
+ switch (type_) {
+ case intValue:
+ return static_cast<float>(value_.int_);
+ case uintValue:
+#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
+ return static_cast<float>(value_.uint_);
+#else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
+ return integerToDouble(value_.uint_);
+#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
+ case realValue:
+ return static_cast<float>(value_.real_);
+ case nullValue:
+ return 0.0;
+ case booleanValue:
+ return value_.bool_ ? 1.0f : 0.0f;
+ default:
+ break;
+ }
+ JSON_FAIL_MESSAGE("Value is not convertible to float.");
+}
+
+bool Value::asBool() const {
+ switch (type_) {
+ case booleanValue:
+ return value_.bool_;
+ case nullValue:
+ return false;
+ case intValue:
+ return value_.int_ ? true : false;
+ case uintValue:
+ return value_.uint_ ? true : false;
+ case realValue:
+ // This is kind of strange. Not recommended.
+ return (value_.real_ != 0.0) ? true : false;
+ default:
+ break;
+ }
+ JSON_FAIL_MESSAGE("Value is not convertible to bool.");
+}
+
+bool Value::isConvertibleTo(ValueType other) const {
+ switch (other) {
+ case nullValue:
+ return (isNumeric() && asDouble() == 0.0) ||
+ (type_ == booleanValue && value_.bool_ == false) ||
+ (type_ == stringValue && asString() == "") ||
+ (type_ == arrayValue && value_.map_->size() == 0) ||
+ (type_ == objectValue && value_.map_->size() == 0) ||
+ type_ == nullValue;
+ case intValue:
+ return isInt() ||
+ (type_ == realValue && InRange(value_.real_, minInt, maxInt)) ||
+ type_ == booleanValue || type_ == nullValue;
+ case uintValue:
+ return isUInt() ||
+ (type_ == realValue && InRange(value_.real_, 0, maxUInt)) ||
+ type_ == booleanValue || type_ == nullValue;
+ case realValue:
+ return isNumeric() || type_ == booleanValue || type_ == nullValue;
+ case booleanValue:
+ return isNumeric() || type_ == booleanValue || type_ == nullValue;
+ case stringValue:
+ return isNumeric() || type_ == booleanValue || type_ == stringValue ||
+ type_ == nullValue;
+ case arrayValue:
+ return type_ == arrayValue || type_ == nullValue;
+ case objectValue:
+ return type_ == objectValue || type_ == nullValue;
+ }
+ JSON_ASSERT_UNREACHABLE;
+ return false;
+}
+
+/// Number of values in array or object
+ArrayIndex Value::size() const {
+ switch (type_) {
+ case nullValue:
+ case intValue:
+ case uintValue:
+ case realValue:
+ case booleanValue:
+ case stringValue:
+ return 0;
+ case arrayValue: // size of the array is highest index + 1
+ if (!value_.map_->empty()) {
+ ObjectValues::const_iterator itLast = value_.map_->end();
+ --itLast;
+ return (*itLast).first.index() + 1;
+ }
+ return 0;
+ case objectValue:
+ return ArrayIndex(value_.map_->size());
+ }
+ JSON_ASSERT_UNREACHABLE;
+ return 0; // unreachable;
+}
+
+bool Value::empty() const {
+ if (isNull() || isArray() || isObject())
+ return size() == 0u;
+ else
+ return false;
+}
+
+bool Value::operator!() const { return isNull(); }
+
+void Value::clear() {
+ JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == arrayValue ||
+ type_ == objectValue,
+ "in Json::Value::clear(): requires complex value");
+ start_ = 0;
+ limit_ = 0;
+ switch (type_) {
+ case arrayValue:
+ case objectValue:
+ value_.map_->clear();
+ break;
+ default:
+ break;
+ }
+}
+
+void Value::resize(ArrayIndex newSize) {
+ JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == arrayValue,
+ "in Json::Value::resize(): requires arrayValue");
+ if (type_ == nullValue)
+ *this = Value(arrayValue);
+ ArrayIndex oldSize = size();
+ if (newSize == 0)
+ clear();
+ else if (newSize > oldSize)
+ (*this)[newSize - 1];
+ else {
+ for (ArrayIndex index = newSize; index < oldSize; ++index) {
+ value_.map_->erase(index);
+ }
+ assert(size() == newSize);
+ }
+}
+
+Value& Value::operator[](ArrayIndex index) {
+ JSON_ASSERT_MESSAGE(
+ type_ == nullValue || type_ == arrayValue,
+ "in Json::Value::operator[](ArrayIndex): requires arrayValue");
+ if (type_ == nullValue)
+ *this = Value(arrayValue);
+ CZString key(index);
+ ObjectValues::iterator it = value_.map_->lower_bound(key);
+ if (it != value_.map_->end() && (*it).first == key)
+ return (*it).second;
+
+ ObjectValues::value_type defaultValue(key, nullRef);
+ it = value_.map_->insert(it, defaultValue);
+ return (*it).second;
+}
+
+Value& Value::operator[](int index) {
+ JSON_ASSERT_MESSAGE(
+ index >= 0,
+ "in Json::Value::operator[](int index): index cannot be negative");
+ return (*this)[ArrayIndex(index)];
+}
+
+const Value& Value::operator[](ArrayIndex index) const {
+ JSON_ASSERT_MESSAGE(
+ type_ == nullValue || type_ == arrayValue,
+ "in Json::Value::operator[](ArrayIndex)const: requires arrayValue");
+ if (type_ == nullValue)
+ return nullRef;
+ CZString key(index);
+ ObjectValues::const_iterator it = value_.map_->find(key);
+ if (it == value_.map_->end())
+ return nullRef;
+ return (*it).second;
+}
+
+const Value& Value::operator[](int index) const {
+ JSON_ASSERT_MESSAGE(
+ index >= 0,
+ "in Json::Value::operator[](int index) const: index cannot be negative");
+ return (*this)[ArrayIndex(index)];
+}
+
+void Value::initBasic(ValueType vtype, bool allocated) {
+ type_ = vtype;
+ allocated_ = allocated;
+ comments_ = 0;
+ start_ = 0;
+ limit_ = 0;
+}
+
+// Access an object value by name, create a null member if it does not exist.
+// @pre Type of '*this' is object or null.
+// @param key is null-terminated.
+Value& Value::resolveReference(const char* key) {
+ JSON_ASSERT_MESSAGE(
+ type_ == nullValue || type_ == objectValue,
+ "in Json::Value::resolveReference(): requires objectValue");
+ if (type_ == nullValue)
+ *this = Value(objectValue);
+ CZString actualKey(
+ key, static_cast<unsigned>(strlen(key)), CZString::noDuplication); // NOTE!
+ ObjectValues::iterator it = value_.map_->lower_bound(actualKey);
+ if (it != value_.map_->end() && (*it).first == actualKey)
+ return (*it).second;
+
+ ObjectValues::value_type defaultValue(actualKey, nullRef);
+ it = value_.map_->insert(it, defaultValue);
+ Value& value = (*it).second;
+ return value;
+}
+
+// @param key is not null-terminated.
+Value& Value::resolveReference(char const* key, char const* cend)
+{
+ JSON_ASSERT_MESSAGE(
+ type_ == nullValue || type_ == objectValue,
+ "in Json::Value::resolveReference(key, end): requires objectValue");
+ if (type_ == nullValue)
+ *this = Value(objectValue);
+ CZString actualKey(
+ key, static_cast<unsigned>(cend-key), CZString::duplicateOnCopy);
+ ObjectValues::iterator it = value_.map_->lower_bound(actualKey);
+ if (it != value_.map_->end() && (*it).first == actualKey)
+ return (*it).second;
+
+ ObjectValues::value_type defaultValue(actualKey, nullRef);
+ it = value_.map_->insert(it, defaultValue);
+ Value& value = (*it).second;
+ return value;
+}
+
+Value Value::get(ArrayIndex index, const Value& defaultValue) const {
+ const Value* value = &((*this)[index]);
+ return value == &nullRef ? defaultValue : *value;
+}
+
+bool Value::isValidIndex(ArrayIndex index) const { return index < size(); }
+
+Value const* Value::find(char const* key, char const* cend) const
+{
+ JSON_ASSERT_MESSAGE(
+ type_ == nullValue || type_ == objectValue,
+ "in Json::Value::find(key, end, found): requires objectValue or nullValue");
+ if (type_ == nullValue) return NULL;
+ CZString actualKey(key, static_cast<unsigned>(cend-key), CZString::noDuplication);
+ ObjectValues::const_iterator it = value_.map_->find(actualKey);
+ if (it == value_.map_->end()) return NULL;
+ return &(*it).second;
+}
+const Value& Value::operator[](const char* key) const
+{
+ Value const* found = find(key, key + strlen(key));
+ if (!found) return nullRef;
+ return *found;
+}
+Value const& Value::operator[](std::string const& key) const
+{
+ Value const* found = find(key.data(), key.data() + key.length());
+ if (!found) return nullRef;
+ return *found;
+}
+
+Value& Value::operator[](const char* key) {
+ return resolveReference(key, key + strlen(key));
+}
+
+Value& Value::operator[](const std::string& key) {
+ return resolveReference(key.data(), key.data() + key.length());
+}
+
+Value& Value::operator[](const StaticString& key) {
+ return resolveReference(key.c_str());
+}
+
+#ifdef JSON_USE_CPPTL
+Value& Value::operator[](const CppTL::ConstString& key) {
+ return resolveReference(key.c_str(), key.end_c_str());
+}
+Value const& Value::operator[](CppTL::ConstString const& key) const
+{
+ Value const* found = find(key.c_str(), key.end_c_str());
+ if (!found) return nullRef;
+ return *found;
+}
+#endif
+
+Value& Value::append(const Value& value) { return (*this)[size()] = value; }
+
+Value Value::get(char const* key, char const* cend, Value const& defaultValue) const
+{
+ Value const* found = find(key, cend);
+ return !found ? defaultValue : *found;
+}
+Value Value::get(char const* key, Value const& defaultValue) const
+{
+ return get(key, key + strlen(key), defaultValue);
+}
+Value Value::get(std::string const& key, Value const& defaultValue) const
+{
+ return get(key.data(), key.data() + key.length(), defaultValue);
+}
+
+
+bool Value::removeMember(const char* key, const char* cend, Value* removed)
+{
+ if (type_ != objectValue) {
+ return false;
+ }
+ CZString actualKey(key, static_cast<unsigned>(cend-key), CZString::noDuplication);
+ ObjectValues::iterator it = value_.map_->find(actualKey);
+ if (it == value_.map_->end())
+ return false;
+ *removed = it->second;
+ value_.map_->erase(it);
+ return true;
+}
+bool Value::removeMember(const char* key, Value* removed)
+{
+ return removeMember(key, key + strlen(key), removed);
+}
+bool Value::removeMember(std::string const& key, Value* removed)
+{
+ return removeMember(key.data(), key.data() + key.length(), removed);
+}
+Value Value::removeMember(const char* key)
+{
+ JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == objectValue,
+ "in Json::Value::removeMember(): requires objectValue");
+ if (type_ == nullValue)
+ return nullRef;
+
+ Value removed; // null
+ removeMember(key, key + strlen(key), &removed);
+ return removed; // still null if removeMember() did nothing
+}
+Value Value::removeMember(const std::string& key)
+{
+ return removeMember(key.c_str());
+}
+
+bool Value::removeIndex(ArrayIndex index, Value* removed) {
+ if (type_ != arrayValue) {
+ return false;
+ }
+ CZString key(index);
+ ObjectValues::iterator it = value_.map_->find(key);
+ if (it == value_.map_->end()) {
+ return false;
+ }
+ *removed = it->second;
+ ArrayIndex oldSize = size();
+ // shift left all items left, into the place of the "removed"
+ for (ArrayIndex i = index; i < (oldSize - 1); ++i){
+ CZString keey(i);
+ (*value_.map_)[keey] = (*this)[i + 1];
+ }
+ // erase the last one ("leftover")
+ CZString keyLast(oldSize - 1);
+ ObjectValues::iterator itLast = value_.map_->find(keyLast);
+ value_.map_->erase(itLast);
+ return true;
+}
+
+#ifdef JSON_USE_CPPTL
+Value Value::get(const CppTL::ConstString& key,
+ const Value& defaultValue) const {
+ return get(key.c_str(), key.end_c_str(), defaultValue);
+}
+#endif
+
+bool Value::isMember(char const* key, char const* cend) const
+{
+ Value const* value = find(key, cend);
+ return NULL != value;
+}
+bool Value::isMember(char const* key) const
+{
+ return isMember(key, key + strlen(key));
+}
+bool Value::isMember(std::string const& key) const
+{
+ return isMember(key.data(), key.data() + key.length());
+}
+
+#ifdef JSON_USE_CPPTL
+bool Value::isMember(const CppTL::ConstString& key) const {
+ return isMember(key.c_str(), key.end_c_str());
+}
+#endif
+
+Value::Members Value::getMemberNames() const {
+ JSON_ASSERT_MESSAGE(
+ type_ == nullValue || type_ == objectValue,
+ "in Json::Value::getMemberNames(), value must be objectValue");
+ if (type_ == nullValue)
+ return Value::Members();
+ Members members;
+ members.reserve(value_.map_->size());
+ ObjectValues::const_iterator it = value_.map_->begin();
+ ObjectValues::const_iterator itEnd = value_.map_->end();
+ for (; it != itEnd; ++it) {
+ members.push_back(std::string((*it).first.data(),
+ (*it).first.length()));
+ }
+ return members;
+}
+//
+//# ifdef JSON_USE_CPPTL
+// EnumMemberNames
+// Value::enumMemberNames() const
+//{
+// if ( type_ == objectValue )
+// {
+// return CppTL::Enum::any( CppTL::Enum::transform(
+// CppTL::Enum::keys( *(value_.map_), CppTL::Type<const CZString &>() ),
+// MemberNamesTransform() ) );
+// }
+// return EnumMemberNames();
+//}
+//
+//
+// EnumValues
+// Value::enumValues() const
+//{
+// if ( type_ == objectValue || type_ == arrayValue )
+// return CppTL::Enum::anyValues( *(value_.map_),
+// CppTL::Type<const Value &>() );
+// return EnumValues();
+//}
+//
+//# endif
+
+static bool IsIntegral(double d) {
+ double integral_part;
+ return modf(d, &integral_part) == 0.0;
+}
+
+bool Value::isNull() const { return type_ == nullValue; }
+
+bool Value::isBool() const { return type_ == booleanValue; }
+
+bool Value::isInt() const {
+ switch (type_) {
+ case intValue:
+ return value_.int_ >= minInt && value_.int_ <= maxInt;
+ case uintValue:
+ return value_.uint_ <= UInt(maxInt);
+ case realValue:
+ return value_.real_ >= minInt && value_.real_ <= maxInt &&
+ IsIntegral(value_.real_);
+ default:
+ break;
+ }
+ return false;
+}
+
+bool Value::isUInt() const {
+ switch (type_) {
+ case intValue:
+ return value_.int_ >= 0 && LargestUInt(value_.int_) <= LargestUInt(maxUInt);
+ case uintValue:
+ return value_.uint_ <= maxUInt;
+ case realValue:
+ return value_.real_ >= 0 && value_.real_ <= maxUInt &&
+ IsIntegral(value_.real_);
+ default:
+ break;
+ }
+ return false;
+}
+
+bool Value::isInt64() const {
+#if defined(JSON_HAS_INT64)
+ switch (type_) {
+ case intValue:
+ return true;
+ case uintValue:
+ return value_.uint_ <= UInt64(maxInt64);
+ case realValue:
+ // Note that maxInt64 (= 2^63 - 1) is not exactly representable as a
+ // double, so double(maxInt64) will be rounded up to 2^63. Therefore we
+ // require the value to be strictly less than the limit.
+ return value_.real_ >= double(minInt64) &&
+ value_.real_ < double(maxInt64) && IsIntegral(value_.real_);
+ default:
+ break;
+ }
+#endif // JSON_HAS_INT64
+ return false;
+}
+
+bool Value::isUInt64() const {
+#if defined(JSON_HAS_INT64)
+ switch (type_) {
+ case intValue:
+ return value_.int_ >= 0;
+ case uintValue:
+ return true;
+ case realValue:
+ // Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a
+ // double, so double(maxUInt64) will be rounded up to 2^64. Therefore we
+ // require the value to be strictly less than the limit.
+ return value_.real_ >= 0 && value_.real_ < maxUInt64AsDouble &&
+ IsIntegral(value_.real_);
+ default:
+ break;
+ }
+#endif // JSON_HAS_INT64
+ return false;
+}
+
+bool Value::isIntegral() const {
+#if defined(JSON_HAS_INT64)
+ return isInt64() || isUInt64();
+#else
+ return isInt() || isUInt();
+#endif
+}
+
+bool Value::isDouble() const { return type_ == realValue || isIntegral(); }
+
+bool Value::isNumeric() const { return isIntegral() || isDouble(); }
+
+bool Value::isString() const { return type_ == stringValue; }
+
+bool Value::isArray() const { return type_ == arrayValue; }
+
+bool Value::isObject() const { return type_ == objectValue; }
+
+void Value::setComment(const char* comment, size_t len, CommentPlacement placement) {
+ if (!comments_)
+ comments_ = new CommentInfo[numberOfCommentPlacement];
+ if ((len > 0) && (comment[len-1] == '\n')) {
+ // Always discard trailing newline, to aid indentation.
+ len -= 1;
+ }
+ comments_[placement].setComment(comment, len);
+}
+
+void Value::setComment(const char* comment, CommentPlacement placement) {
+ setComment(comment, strlen(comment), placement);
+}
+
+void Value::setComment(const std::string& comment, CommentPlacement placement) {
+ setComment(comment.c_str(), comment.length(), placement);
+}
+
+bool Value::hasComment(CommentPlacement placement) const {
+ return comments_ != 0 && comments_[placement].comment_ != 0;
+}
+
+std::string Value::getComment(CommentPlacement placement) const {
+ if (hasComment(placement))
+ return comments_[placement].comment_;
+ return "";
+}
+
+void Value::setOffsetStart(size_t start) { start_ = start; }
+
+void Value::setOffsetLimit(size_t limit) { limit_ = limit; }
+
+size_t Value::getOffsetStart() const { return start_; }
+
+size_t Value::getOffsetLimit() const { return limit_; }
+
+std::string Value::toStyledString() const {
+ StyledWriter writer;
+ return writer.write(*this);
+}
+
+Value::const_iterator Value::begin() const {
+ switch (type_) {
+ case arrayValue:
+ case objectValue:
+ if (value_.map_)
+ return const_iterator(value_.map_->begin());
+ break;
+ default:
+ break;
+ }
+ return const_iterator();
+}
+
+Value::const_iterator Value::end() const {
+ switch (type_) {
+ case arrayValue:
+ case objectValue:
+ if (value_.map_)
+ return const_iterator(value_.map_->end());
+ break;
+ default:
+ break;
+ }
+ return const_iterator();
+}
+
+Value::iterator Value::begin() {
+ switch (type_) {
+ case arrayValue:
+ case objectValue:
+ if (value_.map_)
+ return iterator(value_.map_->begin());
+ break;
+ default:
+ break;
+ }
+ return iterator();
+}
+
+Value::iterator Value::end() {
+ switch (type_) {
+ case arrayValue:
+ case objectValue:
+ if (value_.map_)
+ return iterator(value_.map_->end());
+ break;
+ default:
+ break;
+ }
+ return iterator();
+}
+
+// class PathArgument
+// //////////////////////////////////////////////////////////////////
+
+PathArgument::PathArgument() : key_(), index_(), kind_(kindNone) {}
+
+PathArgument::PathArgument(ArrayIndex index)
+ : key_(), index_(index), kind_(kindIndex) {}
+
+PathArgument::PathArgument(const char* key)
+ : key_(key), index_(), kind_(kindKey) {}
+
+PathArgument::PathArgument(const std::string& key)
+ : key_(key.c_str()), index_(), kind_(kindKey) {}
+
+// class Path
+// //////////////////////////////////////////////////////////////////
+
+Path::Path(const std::string& path,
+ const PathArgument& a1,
+ const PathArgument& a2,
+ const PathArgument& a3,
+ const PathArgument& a4,
+ const PathArgument& a5) {
+ InArgs in;
+ in.push_back(&a1);
+ in.push_back(&a2);
+ in.push_back(&a3);
+ in.push_back(&a4);
+ in.push_back(&a5);
+ makePath(path, in);
+}
+
+void Path::makePath(const std::string& path, const InArgs& in) {
+ const char* current = path.c_str();
+ const char* end = current + path.length();
+ InArgs::const_iterator itInArg = in.begin();
+ while (current != end) {
+ if (*current == '[') {
+ ++current;
+ if (*current == '%')
+ addPathInArg(path, in, itInArg, PathArgument::kindIndex);
+ else {
+ ArrayIndex index = 0;
+ for (; current != end && *current >= '0' && *current <= '9'; ++current)
+ index = index * 10 + ArrayIndex(*current - '0');
+ args_.push_back(index);
+ }
+ if (current == end || *current++ != ']')
+ invalidPath(path, int(current - path.c_str()));
+ } else if (*current == '%') {
+ addPathInArg(path, in, itInArg, PathArgument::kindKey);
+ ++current;
+ } else if (*current == '.') {
+ ++current;
+ } else {
+ const char* beginName = current;
+ while (current != end && !strchr("[.", *current))
+ ++current;
+ args_.push_back(std::string(beginName, current));
+ }
+ }
+}
+
+void Path::addPathInArg(const std::string& /*path*/,
+ const InArgs& in,
+ InArgs::const_iterator& itInArg,
+ PathArgument::Kind kind) {
+ if (itInArg == in.end()) {
+ // Error: missing argument %d
+ } else if ((*itInArg)->kind_ != kind) {
+ // Error: bad argument type
+ } else {
+ args_.push_back(**itInArg);
+ }
+}
+
+void Path::invalidPath(const std::string& /*path*/, int /*location*/) {
+ // Error: invalid path.
+}
+
+const Value& Path::resolve(const Value& root) const {
+ const Value* node = &root;
+ for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
+ const PathArgument& arg = *it;
+ if (arg.kind_ == PathArgument::kindIndex) {
+ if (!node->isArray() || !node->isValidIndex(arg.index_)) {
+ // Error: unable to resolve path (array value expected at position...
+ }
+ node = &((*node)[arg.index_]);
+ } else if (arg.kind_ == PathArgument::kindKey) {
+ if (!node->isObject()) {
+ // Error: unable to resolve path (object value expected at position...)
+ }
+ node = &((*node)[arg.key_]);
+ if (node == &Value::nullRef) {
+ // Error: unable to resolve path (object has no member named '' at
+ // position...)
+ }
+ }
+ }
+ return *node;
+}
+
+Value Path::resolve(const Value& root, const Value& defaultValue) const {
+ const Value* node = &root;
+ for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
+ const PathArgument& arg = *it;
+ if (arg.kind_ == PathArgument::kindIndex) {
+ if (!node->isArray() || !node->isValidIndex(arg.index_))
+ return defaultValue;
+ node = &((*node)[arg.index_]);
+ } else if (arg.kind_ == PathArgument::kindKey) {
+ if (!node->isObject())
+ return defaultValue;
+ node = &((*node)[arg.key_]);
+ if (node == &Value::nullRef)
+ return defaultValue;
+ }
+ }
+ return *node;
+}
+
+Value& Path::make(Value& root) const {
+ Value* node = &root;
+ for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) {
+ const PathArgument& arg = *it;
+ if (arg.kind_ == PathArgument::kindIndex) {
+ if (!node->isArray()) {
+ // Error: node is not an array at position ...
+ }
+ node = &((*node)[arg.index_]);
+ } else if (arg.kind_ == PathArgument::kindKey) {
+ if (!node->isObject()) {
+ // Error: node is not an object at position...
+ }
+ node = &((*node)[arg.key_]);
+ }
+ }
+ return *node;
+}
+
+} // namespace Json
+
+// //////////////////////////////////////////////////////////////////////
+// End of content of file: src/lib_json/json_value.cpp
+// //////////////////////////////////////////////////////////////////////
+
+
+
+
+
+
+// //////////////////////////////////////////////////////////////////////
+// Beginning of content of file: src/lib_json/json_writer.cpp
+// //////////////////////////////////////////////////////////////////////
+
+// Copyright 2011 Baptiste Lepilleur
+// Distributed under MIT license, or public domain if desired and
+// recognized in your jurisdiction.
+// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
+
+#if !defined(JSON_IS_AMALGAMATION)
+#include <json/writer.h>
+#include "json_tool.h"
+#endif // if !defined(JSON_IS_AMALGAMATION)
+#include <iomanip>
+#include <memory>
+#include <sstream>
+#include <utility>
+#include <set>
+#include <cassert>
+#include <cstring>
+#include <cstdio>
+
+#if defined(_MSC_VER) && _MSC_VER >= 1200 && _MSC_VER < 1800 // Between VC++ 6.0 and VC++ 11.0
+#include <float.h>
+#define isfinite _finite
+#elif defined(__sun) && defined(__SVR4) //Solaris
+#if !defined(isfinite)
+#include <ieeefp.h>
+#define isfinite finite
+#endif
+#elif defined(_AIX)
+#if !defined(isfinite)
+#include <math.h>
+#define isfinite finite
+#endif
+#elif defined(__hpux)
+#if !defined(isfinite)
+#if defined(__ia64) && !defined(finite)
+#define isfinite(x) ((sizeof(x) == sizeof(float) ? \
+ _Isfinitef(x) : _IsFinite(x)))
+#else
+#include <math.h>
+#define isfinite finite
+#endif
+#endif
+#else
+#include <cmath>
+#if !(defined(__QNXNTO__)) // QNX already defines isfinite
+#define isfinite std::isfinite
+#endif
+#endif
+
+#if defined(_MSC_VER)
+#if !defined(WINCE) && defined(__STDC_SECURE_LIB__) && _MSC_VER >= 1500 // VC++ 9.0 and above
+#define snprintf sprintf_s
+#elif _MSC_VER >= 1900 // VC++ 14.0 and above
+#define snprintf std::snprintf
+#else
+#define snprintf _snprintf
+#endif
+#elif defined(__ANDROID__) || defined(__QNXNTO__)
+#define snprintf snprintf
+#elif __cplusplus >= 201103L
+#define snprintf std::snprintf
+#endif
+
+#if defined(__BORLANDC__)
+#include <float.h>
+#define isfinite _finite
+#define snprintf _snprintf
+#endif
+
+#if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0
+// Disable warning about strdup being deprecated.
+#pragma warning(disable : 4996)
+#endif
+
+namespace Json {
+
+#if __cplusplus >= 201103L || (defined(_CPPLIB_VER) && _CPPLIB_VER >= 520)
+typedef std::unique_ptr<StreamWriter> StreamWriterPtr;
+#else
+typedef std::auto_ptr<StreamWriter> StreamWriterPtr;
+#endif
+
+static bool containsControlCharacter(const char* str) {
+ while (*str) {
+ if (isControlCharacter(*(str++)))
+ return true;
+ }
+ return false;
+}
+
+static bool containsControlCharacter0(const char* str, unsigned len) {
+ char const* end = str + len;
+ while (end != str) {
+ if (isControlCharacter(*str) || 0==*str)
+ return true;
+ ++str;
+ }
+ return false;
+}
+
+std::string valueToString(LargestInt value) {
+ UIntToStringBuffer buffer;
+ char* current = buffer + sizeof(buffer);
+ if (value == Value::minLargestInt) {
+ uintToString(LargestUInt(Value::maxLargestInt) + 1, current);
+ *--current = '-';
+ } else if (value < 0) {
+ uintToString(LargestUInt(-value), current);
+ *--current = '-';
+ } else {
+ uintToString(LargestUInt(value), current);
+ }
+ assert(current >= buffer);
+ return current;
+}
+
+std::string valueToString(LargestUInt value) {
+ UIntToStringBuffer buffer;
+ char* current = buffer + sizeof(buffer);
+ uintToString(value, current);
+ assert(current >= buffer);
+ return current;
+}
+
+#if defined(JSON_HAS_INT64)
+
+std::string valueToString(Int value) {
+ return valueToString(LargestInt(value));
+}
+
+std::string valueToString(UInt value) {
+ return valueToString(LargestUInt(value));
+}
+
+#endif // # if defined(JSON_HAS_INT64)
+
+std::string valueToString(double value, bool useSpecialFloats, unsigned int precision) {
+ // Allocate a buffer that is more than large enough to store the 16 digits of
+ // precision requested below.
+ char buffer[32];
+ int len = -1;
+
+ char formatString[6];
+ sprintf(formatString, "%%.%dg", precision);
+
+ // Print into the buffer. We need not request the alternative representation
+ // that always has a decimal point because JSON doesn't distingish the
+ // concepts of reals and integers.
+ if (isfinite(value)) {
+ len = snprintf(buffer, sizeof(buffer), formatString, value);
+ } else {
+ // IEEE standard states that NaN values will not compare to themselves
+ if (value != value) {
+ len = snprintf(buffer, sizeof(buffer), useSpecialFloats ? "NaN" : "null");
+ } else if (value < 0) {
+ len = snprintf(buffer, sizeof(buffer), useSpecialFloats ? "-Infinity" : "-1e+9999");
+ } else {
+ len = snprintf(buffer, sizeof(buffer), useSpecialFloats ? "Infinity" : "1e+9999");
+ }
+ // For those, we do not need to call fixNumLoc, but it is fast.
+ }
+ assert(len >= 0);
+ fixNumericLocale(buffer, buffer + len);
+ return buffer;
+}
+
+std::string valueToString(double value) { return valueToString(value, false, 17); }
+
+std::string valueToString(bool value) { return value ? "true" : "false"; }
+
+std::string valueToQuotedString(const char* value) {
+ if (value == NULL)
+ return "";
+ // Not sure how to handle unicode...
+ if (strpbrk(value, "\"\\\b\f\n\r\t") == NULL &&
+ !containsControlCharacter(value))
+ return std::string("\"") + value + "\"";
+ // We have to walk value and escape any special characters.
+ // Appending to std::string is not efficient, but this should be rare.
+ // (Note: forward slashes are *not* rare, but I am not escaping them.)
+ std::string::size_type maxsize =
+ strlen(value) * 2 + 3; // allescaped+quotes+NULL
+ std::string result;
+ result.reserve(maxsize); // to avoid lots of mallocs
+ result += "\"";
+ for (const char* c = value; *c != 0; ++c) {
+ switch (*c) {
+ case '\"':
+ result += "\\\"";
+ break;
+ case '\\':
+ result += "\\\\";
+ break;
+ case '\b':
+ result += "\\b";
+ break;
+ case '\f':
+ result += "\\f";
+ break;
+ case '\n':
+ result += "\\n";
+ break;
+ case '\r':
+ result += "\\r";
+ break;
+ case '\t':
+ result += "\\t";
+ break;
+ // case '/':
+ // Even though \/ is considered a legal escape in JSON, a bare
+ // slash is also legal, so I see no reason to escape it.
+ // (I hope I am not misunderstanding something.
+ // blep notes: actually escaping \/ may be useful in javascript to avoid </
+ // sequence.
+ // Should add a flag to allow this compatibility mode and prevent this
+ // sequence from occurring.
+ default:
+ if (isControlCharacter(*c)) {
+ std::ostringstream oss;
+ oss << "\\u" << std::hex << std::uppercase << std::setfill('0')
+ << std::setw(4) << static_cast<int>(*c);
+ result += oss.str();
+ } else {
+ result += *c;
+ }
+ break;
+ }
+ }
+ result += "\"";
+ return result;
+}
+
+// https://github.com/upcaste/upcaste/blob/master/src/upcore/src/cstring/strnpbrk.cpp
+static char const* strnpbrk(char const* s, char const* accept, size_t n) {
+ assert((s || !n) && accept);
+
+ char const* const end = s + n;
+ for (char const* cur = s; cur < end; ++cur) {
+ int const c = *cur;
+ for (char const* a = accept; *a; ++a) {
+ if (*a == c) {
+ return cur;
+ }
+ }
+ }
+ return NULL;
+}
+static std::string valueToQuotedStringN(const char* value, unsigned length) {
+ if (value == NULL)
+ return "";
+ // Not sure how to handle unicode...
+ if (strnpbrk(value, "\"\\\b\f\n\r\t", length) == NULL &&
+ !containsControlCharacter0(value, length))
+ return std::string("\"") + value + "\"";
+ // We have to walk value and escape any special characters.
+ // Appending to std::string is not efficient, but this should be rare.
+ // (Note: forward slashes are *not* rare, but I am not escaping them.)
+ std::string::size_type maxsize =
+ length * 2 + 3; // allescaped+quotes+NULL
+ std::string result;
+ result.reserve(maxsize); // to avoid lots of mallocs
+ result += "\"";
+ char const* end = value + length;
+ for (const char* c = value; c != end; ++c) {
+ switch (*c) {
+ case '\"':
+ result += "\\\"";
+ break;
+ case '\\':
+ result += "\\\\";
+ break;
+ case '\b':
+ result += "\\b";
+ break;
+ case '\f':
+ result += "\\f";
+ break;
+ case '\n':
+ result += "\\n";
+ break;
+ case '\r':
+ result += "\\r";
+ break;
+ case '\t':
+ result += "\\t";
+ break;
+ // case '/':
+ // Even though \/ is considered a legal escape in JSON, a bare
+ // slash is also legal, so I see no reason to escape it.
+ // (I hope I am not misunderstanding something.)
+ // blep notes: actually escaping \/ may be useful in javascript to avoid </
+ // sequence.
+ // Should add a flag to allow this compatibility mode and prevent this
+ // sequence from occurring.
+ default:
+ if ((isControlCharacter(*c)) || (*c == 0)) {
+ std::ostringstream oss;
+ oss << "\\u" << std::hex << std::uppercase << std::setfill('0')
+ << std::setw(4) << static_cast<int>(*c);
+ result += oss.str();
+ } else {
+ result += *c;
+ }
+ break;
+ }
+ }
+ result += "\"";
+ return result;
+}
+
+// Class Writer
+// //////////////////////////////////////////////////////////////////
+Writer::~Writer() {}
+
+// Class FastWriter
+// //////////////////////////////////////////////////////////////////
+
+FastWriter::FastWriter()
+ : yamlCompatiblityEnabled_(false), dropNullPlaceholders_(false),
+ omitEndingLineFeed_(false) {}
+
+void FastWriter::enableYAMLCompatibility() { yamlCompatiblityEnabled_ = true; }
+
+void FastWriter::dropNullPlaceholders() { dropNullPlaceholders_ = true; }
+
+void FastWriter::omitEndingLineFeed() { omitEndingLineFeed_ = true; }
+
+std::string FastWriter::write(const Value& root) {
+ document_ = "";
+ writeValue(root);
+ if (!omitEndingLineFeed_)
+ document_ += "\n";
+ return document_;
+}
+
+void FastWriter::writeValue(const Value& value) {
+ switch (value.type()) {
+ case nullValue:
+ if (!dropNullPlaceholders_)
+ document_ += "null";
+ break;
+ case intValue:
+ document_ += valueToString(value.asLargestInt());
+ break;
+ case uintValue:
+ document_ += valueToString(value.asLargestUInt());
+ break;
+ case realValue:
+ document_ += valueToString(value.asDouble());
+ break;
+ case stringValue:
+ {
+ // Is NULL possible for value.string_?
+ char const* str;
+ char const* end;
+ bool ok = value.getString(&str, &end);
+ if (ok) document_ += valueToQuotedStringN(str, static_cast<unsigned>(end-str));
+ break;
+ }
+ case booleanValue:
+ document_ += valueToString(value.asBool());
+ break;
+ case arrayValue: {
+ document_ += '[';
+ int size = value.size();
+ for (int index = 0; index < size; ++index) {
+ if (index > 0)
+ document_ += ',';
+ writeValue(value[index]);
+ }
+ document_ += ']';
+ } break;
+ case objectValue: {
+ Value::Members members(value.getMemberNames());
+ document_ += '{';
+ for (Value::Members::iterator it = members.begin(); it != members.end();
+ ++it) {
+ const std::string& name = *it;
+ if (it != members.begin())
+ document_ += ',';
+ document_ += valueToQuotedStringN(name.data(), static_cast<unsigned>(name.length()));
+ document_ += yamlCompatiblityEnabled_ ? ": " : ":";
+ writeValue(value[name]);
+ }
+ document_ += '}';
+ } break;
+ }
+}
+
+// Class StyledWriter
+// //////////////////////////////////////////////////////////////////
+
+StyledWriter::StyledWriter()
+ : rightMargin_(74), indentSize_(3), addChildValues_() {}
+
+std::string StyledWriter::write(const Value& root) {
+ document_ = "";
+ addChildValues_ = false;
+ indentString_ = "";
+ writeCommentBeforeValue(root);
+ writeValue(root);
+ writeCommentAfterValueOnSameLine(root);
+ document_ += "\n";
+ return document_;
+}
+
+void StyledWriter::writeValue(const Value& value) {
+ switch (value.type()) {
+ case nullValue:
+ pushValue("null");
+ break;
+ case intValue:
+ pushValue(valueToString(value.asLargestInt()));
+ break;
+ case uintValue:
+ pushValue(valueToString(value.asLargestUInt()));
+ break;
+ case realValue:
+ pushValue(valueToString(value.asDouble()));
+ break;
+ case stringValue:
+ {
+ // Is NULL possible for value.string_?
+ char const* str;
+ char const* end;
+ bool ok = value.getString(&str, &end);
+ if (ok) pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end-str)));
+ else pushValue("");
+ break;
+ }
+ case booleanValue:
+ pushValue(valueToString(value.asBool()));
+ break;
+ case arrayValue:
+ writeArrayValue(value);
+ break;
+ case objectValue: {
+ Value::Members members(value.getMemberNames());
+ if (members.empty())
+ pushValue("{}");
+ else {
+ writeWithIndent("{");
+ indent();
+ Value::Members::iterator it = members.begin();
+ for (;;) {
+ const std::string& name = *it;
+ const Value& childValue = value[name];
+ writeCommentBeforeValue(childValue);
+ writeWithIndent(valueToQuotedString(name.c_str()));
+ document_ += " : ";
+ writeValue(childValue);
+ if (++it == members.end()) {
+ writeCommentAfterValueOnSameLine(childValue);
+ break;
+ }
+ document_ += ',';
+ writeCommentAfterValueOnSameLine(childValue);
+ }
+ unindent();
+ writeWithIndent("}");
+ }
+ } break;
+ }
+}
+
+void StyledWriter::writeArrayValue(const Value& value) {
+ unsigned size = value.size();
+ if (size == 0)
+ pushValue("[]");
+ else {
+ bool isArrayMultiLine = isMultineArray(value);
+ if (isArrayMultiLine) {
+ writeWithIndent("[");
+ indent();
+ bool hasChildValue = !childValues_.empty();
+ unsigned index = 0;
+ for (;;) {
+ const Value& childValue = value[index];
+ writeCommentBeforeValue(childValue);
+ if (hasChildValue)
+ writeWithIndent(childValues_[index]);
+ else {
+ writeIndent();
+ writeValue(childValue);
+ }
+ if (++index == size) {
+ writeCommentAfterValueOnSameLine(childValue);
+ break;
+ }
+ document_ += ',';
+ writeCommentAfterValueOnSameLine(childValue);
+ }
+ unindent();
+ writeWithIndent("]");
+ } else // output on a single line
+ {
+ assert(childValues_.size() == size);
+ document_ += "[ ";
+ for (unsigned index = 0; index < size; ++index) {
+ if (index > 0)
+ document_ += ", ";
+ document_ += childValues_[index];
+ }
+ document_ += " ]";
+ }
+ }
+}
+
+bool StyledWriter::isMultineArray(const Value& value) {
+ int size = value.size();
+ bool isMultiLine = size * 3 >= rightMargin_;
+ childValues_.clear();
+ for (int index = 0; index < size && !isMultiLine; ++index) {
+ const Value& childValue = value[index];
+ isMultiLine = ((childValue.isArray() || childValue.isObject()) &&
+ childValue.size() > 0);
+ }
+ if (!isMultiLine) // check if line length > max line length
+ {
+ childValues_.reserve(size);
+ addChildValues_ = true;
+ int lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]'
+ for (int index = 0; index < size; ++index) {
+ if (hasCommentForValue(value[index])) {
+ isMultiLine = true;
+ }
+ writeValue(value[index]);
+ lineLength += int(childValues_[index].length());
+ }
+ addChildValues_ = false;
+ isMultiLine = isMultiLine || lineLength >= rightMargin_;
+ }
+ return isMultiLine;
+}
+
+void StyledWriter::pushValue(const std::string& value) {
+ if (addChildValues_)
+ childValues_.push_back(value);
+ else
+ document_ += value;
+}
+
+void StyledWriter::writeIndent() {
+ if (!document_.empty()) {
+ char last = document_[document_.length() - 1];
+ if (last == ' ') // already indented
+ return;
+ if (last != '\n') // Comments may add new-line
+ document_ += '\n';
+ }
+ document_ += indentString_;
+}
+
+void StyledWriter::writeWithIndent(const std::string& value) {
+ writeIndent();
+ document_ += value;
+}
+
+void StyledWriter::indent() { indentString_ += std::string(indentSize_, ' '); }
+
+void StyledWriter::unindent() {
+ assert(int(indentString_.size()) >= indentSize_);
+ indentString_.resize(indentString_.size() - indentSize_);
+}
+
+void StyledWriter::writeCommentBeforeValue(const Value& root) {
+ if (!root.hasComment(commentBefore))
+ return;
+
+ document_ += "\n";
+ writeIndent();
+ const std::string& comment = root.getComment(commentBefore);
+ std::string::const_iterator iter = comment.begin();
+ while (iter != comment.end()) {
+ document_ += *iter;
+ if (*iter == '\n' &&
+ (iter != comment.end() && *(iter + 1) == '/'))
+ writeIndent();
+ ++iter;
+ }
+
+ // Comments are stripped of trailing newlines, so add one here
+ document_ += "\n";
+}
+
+void StyledWriter::writeCommentAfterValueOnSameLine(const Value& root) {
+ if (root.hasComment(commentAfterOnSameLine))
+ document_ += " " + root.getComment(commentAfterOnSameLine);
+
+ if (root.hasComment(commentAfter)) {
+ document_ += "\n";
+ document_ += root.getComment(commentAfter);
+ document_ += "\n";
+ }
+}
+
+bool StyledWriter::hasCommentForValue(const Value& value) {
+ return value.hasComment(commentBefore) ||
+ value.hasComment(commentAfterOnSameLine) ||
+ value.hasComment(commentAfter);
+}
+
+// Class StyledStreamWriter
+// //////////////////////////////////////////////////////////////////
+
+StyledStreamWriter::StyledStreamWriter(std::string indentation)
+ : document_(NULL), rightMargin_(74), indentation_(indentation),
+ addChildValues_() {}
+
+void StyledStreamWriter::write(std::ostream& out, const Value& root) {
+ document_ = &out;
+ addChildValues_ = false;
+ indentString_ = "";
+ indented_ = true;
+ writeCommentBeforeValue(root);
+ if (!indented_) writeIndent();
+ indented_ = true;
+ writeValue(root);
+ writeCommentAfterValueOnSameLine(root);
+ *document_ << "\n";
+ document_ = NULL; // Forget the stream, for safety.
+}
+
+void StyledStreamWriter::writeValue(const Value& value) {
+ switch (value.type()) {
+ case nullValue:
+ pushValue("null");
+ break;
+ case intValue:
+ pushValue(valueToString(value.asLargestInt()));
+ break;
+ case uintValue:
+ pushValue(valueToString(value.asLargestUInt()));
+ break;
+ case realValue:
+ pushValue(valueToString(value.asDouble()));
+ break;
+ case stringValue:
+ {
+ // Is NULL possible for value.string_?
+ char const* str;
+ char const* end;
+ bool ok = value.getString(&str, &end);
+ if (ok) pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end-str)));
+ else pushValue("");
+ break;
+ }
+ case booleanValue:
+ pushValue(valueToString(value.asBool()));
+ break;
+ case arrayValue:
+ writeArrayValue(value);
+ break;
+ case objectValue: {
+ Value::Members members(value.getMemberNames());
+ if (members.empty())
+ pushValue("{}");
+ else {
+ writeWithIndent("{");
+ indent();
+ Value::Members::iterator it = members.begin();
+ for (;;) {
+ const std::string& name = *it;
+ const Value& childValue = value[name];
+ writeCommentBeforeValue(childValue);
+ writeWithIndent(valueToQuotedString(name.c_str()));
+ *document_ << " : ";
+ writeValue(childValue);
+ if (++it == members.end()) {
+ writeCommentAfterValueOnSameLine(childValue);
+ break;
+ }
+ *document_ << ",";
+ writeCommentAfterValueOnSameLine(childValue);
+ }
+ unindent();
+ writeWithIndent("}");
+ }
+ } break;
+ }
+}
+
+void StyledStreamWriter::writeArrayValue(const Value& value) {
+ unsigned size = value.size();
+ if (size == 0)
+ pushValue("[]");
+ else {
+ bool isArrayMultiLine = isMultineArray(value);
+ if (isArrayMultiLine) {
+ writeWithIndent("[");
+ indent();
+ bool hasChildValue = !childValues_.empty();
+ unsigned index = 0;
+ for (;;) {
+ const Value& childValue = value[index];
+ writeCommentBeforeValue(childValue);
+ if (hasChildValue)
+ writeWithIndent(childValues_[index]);
+ else {
+ if (!indented_) writeIndent();
+ indented_ = true;
+ writeValue(childValue);
+ indented_ = false;
+ }
+ if (++index == size) {
+ writeCommentAfterValueOnSameLine(childValue);
+ break;
+ }
+ *document_ << ",";
+ writeCommentAfterValueOnSameLine(childValue);
+ }
+ unindent();
+ writeWithIndent("]");
+ } else // output on a single line
+ {
+ assert(childValues_.size() == size);
+ *document_ << "[ ";
+ for (unsigned index = 0; index < size; ++index) {
+ if (index > 0)
+ *document_ << ", ";
+ *document_ << childValues_[index];
+ }
+ *document_ << " ]";
+ }
+ }
+}
+
+bool StyledStreamWriter::isMultineArray(const Value& value) {
+ int size = value.size();
+ bool isMultiLine = size * 3 >= rightMargin_;
+ childValues_.clear();
+ for (int index = 0; index < size && !isMultiLine; ++index) {
+ const Value& childValue = value[index];
+ isMultiLine = ((childValue.isArray() || childValue.isObject()) &&
+ childValue.size() > 0);
+ }
+ if (!isMultiLine) // check if line length > max line length
+ {
+ childValues_.reserve(size);
+ addChildValues_ = true;
+ int lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]'
+ for (int index = 0; index < size; ++index) {
+ if (hasCommentForValue(value[index])) {
+ isMultiLine = true;
+ }
+ writeValue(value[index]);
+ lineLength += int(childValues_[index].length());
+ }
+ addChildValues_ = false;
+ isMultiLine = isMultiLine || lineLength >= rightMargin_;
+ }
+ return isMultiLine;
+}
+
+void StyledStreamWriter::pushValue(const std::string& value) {
+ if (addChildValues_)
+ childValues_.push_back(value);
+ else
+ *document_ << value;
+}
+
+void StyledStreamWriter::writeIndent() {
+ // blep intended this to look at the so-far-written string
+ // to determine whether we are already indented, but
+ // with a stream we cannot do that. So we rely on some saved state.
+ // The caller checks indented_.
+ *document_ << '\n' << indentString_;
+}
+
+void StyledStreamWriter::writeWithIndent(const std::string& value) {
+ if (!indented_) writeIndent();
+ *document_ << value;
+ indented_ = false;
+}
+
+void StyledStreamWriter::indent() { indentString_ += indentation_; }
+
+void StyledStreamWriter::unindent() {
+ assert(indentString_.size() >= indentation_.size());
+ indentString_.resize(indentString_.size() - indentation_.size());
+}
+
+void StyledStreamWriter::writeCommentBeforeValue(const Value& root) {
+ if (!root.hasComment(commentBefore))
+ return;
+
+ if (!indented_) writeIndent();
+ const std::string& comment = root.getComment(commentBefore);
+ std::string::const_iterator iter = comment.begin();
+ while (iter != comment.end()) {
+ *document_ << *iter;
+ if (*iter == '\n' &&
+ (iter != comment.end() && *(iter + 1) == '/'))
+ // writeIndent(); // would include newline
+ *document_ << indentString_;
+ ++iter;
+ }
+ indented_ = false;
+}
+
+void StyledStreamWriter::writeCommentAfterValueOnSameLine(const Value& root) {
+ if (root.hasComment(commentAfterOnSameLine))
+ *document_ << ' ' << root.getComment(commentAfterOnSameLine);
+
+ if (root.hasComment(commentAfter)) {
+ writeIndent();
+ *document_ << root.getComment(commentAfter);
+ }
+ indented_ = false;
+}
+
+bool StyledStreamWriter::hasCommentForValue(const Value& value) {
+ return value.hasComment(commentBefore) ||
+ value.hasComment(commentAfterOnSameLine) ||
+ value.hasComment(commentAfter);
+}
+
+//////////////////////////
+// BuiltStyledStreamWriter
+
+/// Scoped enums are not available until C++11.
+struct CommentStyle {
+ /// Decide whether to write comments.
+ enum Enum {
+ None, ///< Drop all comments.
+ Most, ///< Recover odd behavior of previous versions (not implemented yet).
+ All ///< Keep all comments.
+ };
+};
+
+struct BuiltStyledStreamWriter : public StreamWriter
+{
+ BuiltStyledStreamWriter(
+ std::string const& indentation,
+ CommentStyle::Enum cs,
+ std::string const& colonSymbol,
+ std::string const& nullSymbol,
+ std::string const& endingLineFeedSymbol,
+ bool useSpecialFloats,
+ unsigned int precision);
+ int write(Value const& root, std::ostream* sout) override;
+private:
+ void writeValue(Value const& value);
+ void writeArrayValue(Value const& value);
+ bool isMultineArray(Value const& value);
+ void pushValue(std::string const& value);
+ void writeIndent();
+ void writeWithIndent(std::string const& value);
+ void indent();
+ void unindent();
+ void writeCommentBeforeValue(Value const& root);
+ void writeCommentAfterValueOnSameLine(Value const& root);
+ static bool hasCommentForValue(const Value& value);
+
+ typedef std::vector<std::string> ChildValues;
+
+ ChildValues childValues_;
+ std::string indentString_;
+ int rightMargin_;
+ std::string indentation_;
+ CommentStyle::Enum cs_;
+ std::string colonSymbol_;
+ std::string nullSymbol_;
+ std::string endingLineFeedSymbol_;
+ bool addChildValues_ : 1;
+ bool indented_ : 1;
+ bool useSpecialFloats_ : 1;
+ unsigned int precision_;
+};
+BuiltStyledStreamWriter::BuiltStyledStreamWriter(
+ std::string const& indentation,
+ CommentStyle::Enum cs,
+ std::string const& colonSymbol,
+ std::string const& nullSymbol,
+ std::string const& endingLineFeedSymbol,
+ bool useSpecialFloats,
+ unsigned int precision)
+ : rightMargin_(74)
+ , indentation_(indentation)
+ , cs_(cs)
+ , colonSymbol_(colonSymbol)
+ , nullSymbol_(nullSymbol)
+ , endingLineFeedSymbol_(endingLineFeedSymbol)
+ , addChildValues_(false)
+ , indented_(false)
+ , useSpecialFloats_(useSpecialFloats)
+ , precision_(precision)
+{
+}
+int BuiltStyledStreamWriter::write(Value const& root, std::ostream* sout)
+{
+ sout_ = sout;
+ addChildValues_ = false;
+ indented_ = true;
+ indentString_ = "";
+ writeCommentBeforeValue(root);
+ if (!indented_) writeIndent();
+ indented_ = true;
+ writeValue(root);
+ writeCommentAfterValueOnSameLine(root);
+ *sout_ << endingLineFeedSymbol_;
+ sout_ = NULL;
+ return 0;
+}
+void BuiltStyledStreamWriter::writeValue(Value const& value) {
+ switch (value.type()) {
+ case nullValue:
+ pushValue(nullSymbol_);
+ break;
+ case intValue:
+ pushValue(valueToString(value.asLargestInt()));
+ break;
+ case uintValue:
+ pushValue(valueToString(value.asLargestUInt()));
+ break;
+ case realValue:
+ pushValue(valueToString(value.asDouble(), useSpecialFloats_, precision_));
+ break;
+ case stringValue:
+ {
+ // Is NULL is possible for value.string_?
+ char const* str;
+ char const* end;
+ bool ok = value.getString(&str, &end);
+ if (ok) pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end-str)));
+ else pushValue("");
+ break;
+ }
+ case booleanValue:
+ pushValue(valueToString(value.asBool()));
+ break;
+ case arrayValue:
+ writeArrayValue(value);
+ break;
+ case objectValue: {
+ Value::Members members(value.getMemberNames());
+ if (members.empty())
+ pushValue("{}");
+ else {
+ writeWithIndent("{");
+ indent();
+ Value::Members::iterator it = members.begin();
+ for (;;) {
+ std::string const& name = *it;
+ Value const& childValue = value[name];
+ writeCommentBeforeValue(childValue);
+ writeWithIndent(valueToQuotedStringN(name.data(), static_cast<unsigned>(name.length())));
+ *sout_ << colonSymbol_;
+ writeValue(childValue);
+ if (++it == members.end()) {
+ writeCommentAfterValueOnSameLine(childValue);
+ break;
+ }
+ *sout_ << ",";
+ writeCommentAfterValueOnSameLine(childValue);
+ }
+ unindent();
+ writeWithIndent("}");
+ }
+ } break;
+ }
+}
+
+void BuiltStyledStreamWriter::writeArrayValue(Value const& value) {
+ unsigned size = value.size();
+ if (size == 0)
+ pushValue("[]");
+ else {
+ bool isMultiLine = (cs_ == CommentStyle::All) || isMultineArray(value);
+ if (isMultiLine) {
+ writeWithIndent("[");
+ indent();
+ bool hasChildValue = !childValues_.empty();
+ unsigned index = 0;
+ for (;;) {
+ Value const& childValue = value[index];
+ writeCommentBeforeValue(childValue);
+ if (hasChildValue)
+ writeWithIndent(childValues_[index]);
+ else {
+ if (!indented_) writeIndent();
+ indented_ = true;
+ writeValue(childValue);
+ indented_ = false;
+ }
+ if (++index == size) {
+ writeCommentAfterValueOnSameLine(childValue);
+ break;
+ }
+ *sout_ << ",";
+ writeCommentAfterValueOnSameLine(childValue);
+ }
+ unindent();
+ writeWithIndent("]");
+ } else // output on a single line
+ {
+ assert(childValues_.size() == size);
+ *sout_ << "[";
+ if (!indentation_.empty()) *sout_ << " ";
+ for (unsigned index = 0; index < size; ++index) {
+ if (index > 0)
+ *sout_ << ", ";
+ *sout_ << childValues_[index];
+ }
+ if (!indentation_.empty()) *sout_ << " ";
+ *sout_ << "]";
+ }
+ }
+}
+
+bool BuiltStyledStreamWriter::isMultineArray(Value const& value) {
+ int size = value.size();
+ bool isMultiLine = size * 3 >= rightMargin_;
+ childValues_.clear();
+ for (int index = 0; index < size && !isMultiLine; ++index) {
+ Value const& childValue = value[index];
+ isMultiLine = ((childValue.isArray() || childValue.isObject()) &&
+ childValue.size() > 0);
+ }
+ if (!isMultiLine) // check if line length > max line length
+ {
+ childValues_.reserve(size);
+ addChildValues_ = true;
+ int lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]'
+ for (int index = 0; index < size; ++index) {
+ if (hasCommentForValue(value[index])) {
+ isMultiLine = true;
+ }
+ writeValue(value[index]);
+ lineLength += int(childValues_[index].length());
+ }
+ addChildValues_ = false;
+ isMultiLine = isMultiLine || lineLength >= rightMargin_;
+ }
+ return isMultiLine;
+}
+
+void BuiltStyledStreamWriter::pushValue(std::string const& value) {
+ if (addChildValues_)
+ childValues_.push_back(value);
+ else
+ *sout_ << value;
+}
+
+void BuiltStyledStreamWriter::writeIndent() {
+ // blep intended this to look at the so-far-written string
+ // to determine whether we are already indented, but
+ // with a stream we cannot do that. So we rely on some saved state.
+ // The caller checks indented_.
+
+ if (!indentation_.empty()) {
+ // In this case, drop newlines too.
+ *sout_ << '\n' << indentString_;
+ }
+}
+
+void BuiltStyledStreamWriter::writeWithIndent(std::string const& value) {
+ if (!indented_) writeIndent();
+ *sout_ << value;
+ indented_ = false;
+}
+
+void BuiltStyledStreamWriter::indent() { indentString_ += indentation_; }
+
+void BuiltStyledStreamWriter::unindent() {
+ assert(indentString_.size() >= indentation_.size());
+ indentString_.resize(indentString_.size() - indentation_.size());
+}
+
+void BuiltStyledStreamWriter::writeCommentBeforeValue(Value const& root) {
+ if (cs_ == CommentStyle::None) return;
+ if (!root.hasComment(commentBefore))
+ return;
+
+ if (!indented_) writeIndent();
+ const std::string& comment = root.getComment(commentBefore);
+ std::string::const_iterator iter = comment.begin();
+ while (iter != comment.end()) {
+ *sout_ << *iter;
+ if (*iter == '\n' &&
+ (iter != comment.end() && *(iter + 1) == '/'))
+ // writeIndent(); // would write extra newline
+ *sout_ << indentString_;
+ ++iter;
+ }
+ indented_ = false;
+}
+
+void BuiltStyledStreamWriter::writeCommentAfterValueOnSameLine(Value const& root) {
+ if (cs_ == CommentStyle::None) return;
+ if (root.hasComment(commentAfterOnSameLine))
+ *sout_ << " " + root.getComment(commentAfterOnSameLine);
+
+ if (root.hasComment(commentAfter)) {
+ writeIndent();
+ *sout_ << root.getComment(commentAfter);
+ }
+}
+
+// static
+bool BuiltStyledStreamWriter::hasCommentForValue(const Value& value) {
+ return value.hasComment(commentBefore) ||
+ value.hasComment(commentAfterOnSameLine) ||
+ value.hasComment(commentAfter);
+}
+
+///////////////
+// StreamWriter
+
+StreamWriter::StreamWriter()
+ : sout_(NULL)
+{
+}
+StreamWriter::~StreamWriter()
+{
+}
+StreamWriter::Factory::~Factory()
+{}
+StreamWriterBuilder::StreamWriterBuilder()
+{
+ setDefaults(&settings_);
+}
+StreamWriterBuilder::~StreamWriterBuilder()
+{}
+StreamWriter* StreamWriterBuilder::newStreamWriter() const
+{
+ std::string indentation = settings_["indentation"].asString();
+ std::string cs_str = settings_["commentStyle"].asString();
+ bool eyc = settings_["enableYAMLCompatibility"].asBool();
+ bool dnp = settings_["dropNullPlaceholders"].asBool();
+ bool usf = settings_["useSpecialFloats"].asBool();
+ unsigned int pre = settings_["precision"].asUInt();
+ CommentStyle::Enum cs = CommentStyle::All;
+ if (cs_str == "All") {
+ cs = CommentStyle::All;
+ } else if (cs_str == "None") {
+ cs = CommentStyle::None;
+ } else {
+ throwRuntimeError("commentStyle must be 'All' or 'None'");
+ }
+ std::string colonSymbol = " : ";
+ if (eyc) {
+ colonSymbol = ": ";
+ } else if (indentation.empty()) {
+ colonSymbol = ":";
+ }
+ std::string nullSymbol = "null";
+ if (dnp) {
+ nullSymbol = "";
+ }
+ if (pre > 17) pre = 17;
+ std::string endingLineFeedSymbol = "";
+ return new BuiltStyledStreamWriter(
+ indentation, cs,
+ colonSymbol, nullSymbol, endingLineFeedSymbol, usf, pre);
+}
+static void getValidWriterKeys(std::set<std::string>* valid_keys)
+{
+ valid_keys->clear();
+ valid_keys->insert("indentation");
+ valid_keys->insert("commentStyle");
+ valid_keys->insert("enableYAMLCompatibility");
+ valid_keys->insert("dropNullPlaceholders");
+ valid_keys->insert("useSpecialFloats");
+ valid_keys->insert("precision");
+}
+bool StreamWriterBuilder::validate(Json::Value* invalid) const
+{
+ Json::Value my_invalid;
+ if (!invalid) invalid = &my_invalid; // so we do not need to test for NULL
+ Json::Value& inv = *invalid;
+ std::set<std::string> valid_keys;
+ getValidWriterKeys(&valid_keys);
+ Value::Members keys = settings_.getMemberNames();
+ size_t n = keys.size();
+ for (size_t i = 0; i < n; ++i) {
+ std::string const& key = keys[i];
+ if (valid_keys.find(key) == valid_keys.end()) {
+ inv[key] = settings_[key];
+ }
+ }
+ return 0u == inv.size();
+}
+Value& StreamWriterBuilder::operator[](std::string key)
+{
+ return settings_[key];
+}
+// static
+void StreamWriterBuilder::setDefaults(Json::Value* settings)
+{
+ //! [StreamWriterBuilderDefaults]
+ (*settings)["commentStyle"] = "All";
+ (*settings)["indentation"] = "\t";
+ (*settings)["enableYAMLCompatibility"] = false;
+ (*settings)["dropNullPlaceholders"] = false;
+ (*settings)["useSpecialFloats"] = false;
+ (*settings)["precision"] = 17;
+ //! [StreamWriterBuilderDefaults]
+}
+
+std::string writeString(StreamWriter::Factory const& builder, Value const& root) {
+ std::ostringstream sout;
+ StreamWriterPtr const writer(builder.newStreamWriter());
+ writer->write(root, &sout);
+ return sout.str();
+}
+
+std::ostream& operator<<(std::ostream& sout, Value const& root) {
+ StreamWriterBuilder builder;
+ StreamWriterPtr const writer(builder.newStreamWriter());
+ writer->write(root, &sout);
+ return sout;
+}
+
+} // namespace Json
+
+// //////////////////////////////////////////////////////////////////////
+// End of content of file: src/lib_json/json_writer.cpp
+// //////////////////////////////////////////////////////////////////////
+
+
+
+
+
diff --git a/conformance/update_failure_list.py b/conformance/update_failure_list.py
new file mode 100755
index 00000000..69f210e3
--- /dev/null
+++ b/conformance/update_failure_list.py
@@ -0,0 +1,73 @@
+#!/usr/bin/env python
+# 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.
+
+"""Script to update a failure list file to add/remove failures.
+
+This is sort of like comm(1), except it recognizes comments and ignores them.
+"""
+
+import argparse
+import fileinput
+
+parser = argparse.ArgumentParser(
+ description='Adds/removes failures from the failure list.')
+parser.add_argument('filename', type=str, help='failure list file to update')
+parser.add_argument('--add', dest='add_list', action='append')
+parser.add_argument('--remove', dest='remove_list', action='append')
+
+args = parser.parse_args()
+
+add_set = set()
+remove_set = set()
+
+for add_file in (args.add_list or []):
+ with open(add_file) as f:
+ for line in f:
+ add_set.add(line)
+
+for remove_file in (args.remove_list or []):
+ with open(remove_file) as f:
+ for line in f:
+ if line in add_set:
+ raise "Asked to both add and remove test: " + line
+ remove_set.add(line.strip())
+
+add_list = sorted(add_set, reverse=True)
+
+existing_list = file(args.filename).read()
+
+with open(args.filename, "w") as f:
+ for line in existing_list.splitlines(True):
+ test = line.split("#")[0].strip()
+ while len(add_list) > 0 and test > add_list[-1]:
+ f.write(add_list.pop())
+ if test not in remove_set:
+ f.write(line)
diff --git a/csharp/.gitignore b/csharp/.gitignore
index 07ea90ac..8ba88499 100644
--- a/csharp/.gitignore
+++ b/csharp/.gitignore
@@ -1,16 +1,10 @@
-#
-# Untracked directories
-#
-src/AddressBook/bin
-src/AddressBook/obj
-src/Google.Protobuf/bin/
-src/Google.Protobuf/obj/
-src/Google.Protobuf.Conformance/bin/
-src/Google.Protobuf.Conformance/obj/
-src/Google.Protobuf.Test/bin/
-src/Google.Protobuf.Test/obj/
-src/Google.Protobuf.JsonDump/bin/
-src/Google.Protobuf.JsonDump/obj/
+# Output
+bin
+obj
+project.lock.json
+TestResult.xml
+
+# Possibly legacy now?
mono/bin
mono/tmp
mono/protoc
@@ -23,6 +17,7 @@ lib/NUnit
#
# Untracked files
#
+.vs
*.user
*.suo
*.nupkg
@@ -33,3 +28,4 @@ mono/.libs
mono/*.exe
mono/*.dll
lib/protoc.exe
+*.ncrunch*
diff --git a/csharp/CHANGES.txt b/csharp/CHANGES.txt
index b29debb8..a87cd4d5 100644
--- a/csharp/CHANGES.txt
+++ b/csharp/CHANGES.txt
@@ -128,7 +128,7 @@ Fixes:
- Issue 12: default value for enumerate fields must be filled out
Other:
-- Rewrite of build using MSBbuild instead of NAnt
+- Rewrite of build using MSbuild instead of NAnt
- Moved to NUnit Version 2.2.8.0
- Changed to using secure .snk for releases
diff --git a/csharp/Google.Protobuf.Tools.nuspec b/csharp/Google.Protobuf.Tools.nuspec
new file mode 100644
index 00000000..24b4a776
--- /dev/null
+++ b/csharp/Google.Protobuf.Tools.nuspec
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<package>
+ <metadata>
+ <id>Google.Protobuf.Tools</id>
+ <title>Google Protocol Buffers tools</title>
+ <summary>Tools for Protocol Buffers - Google's data interchange format.</summary>
+ <description>See project site for more info.</description>
+ <version>3.0.0</version>
+ <authors>Google Inc.</authors>
+ <owners>protobuf-packages</owners>
+ <licenseUrl>https://github.com/google/protobuf/blob/master/LICENSE</licenseUrl>
+ <projectUrl>https://github.com/google/protobuf</projectUrl>
+ <requireLicenseAcceptance>false</requireLicenseAcceptance>
+ <releaseNotes>Tools for Protocol Buffers</releaseNotes>
+ <copyright>Copyright 2015, Google Inc.</copyright>
+ <tags>Protocol Buffers Binary Serialization Format Google proto proto3</tags>
+ </metadata>
+ <files>
+ <file src="protoc\windows_x86\protoc.exe" target="tools\windows_x86\protoc.exe" />
+ <file src="protoc\windows_x64\protoc.exe" target="tools\windows_x64\protoc.exe" />
+ <file src="protoc\linux_x86\protoc" target="tools\linux_x86\protoc" />
+ <file src="protoc\linux_x64\protoc" target="tools\linux_x64\protoc" />
+ <file src="protoc\macosx_x86\protoc" target="tools\macosx_x86\protoc" />
+ <file src="protoc\macosx_x64\protoc" target="tools\macosx_x64\protoc" />
+ <file src="..\src\google\protobuf\any.proto" target="tools\google\protobuf" />
+ <file src="..\src\google\protobuf\api.proto" target="tools\google\protobuf" />
+ <file src="..\src\google\protobuf\descriptor.proto" target="tools\google\protobuf" />
+ <file src="..\src\google\protobuf\duration.proto" target="tools\google\protobuf" />
+ <file src="..\src\google\protobuf\empty.proto" target="tools\google\protobuf" />
+ <file src="..\src\google\protobuf\field_mask.proto" target="tools\google\protobuf" />
+ <file src="..\src\google\protobuf\source_context.proto" target="tools\google\protobuf" />
+ <file src="..\src\google\protobuf\struct.proto" target="tools\google\protobuf" />
+ <file src="..\src\google\protobuf\timestamp.proto" target="tools\google\protobuf" />
+ <file src="..\src\google\protobuf\type.proto" target="tools\google\protobuf" />
+ <file src="..\src\google\protobuf\wrappers.proto" target="tools\google\protobuf" />
+ </files>
+</package>
diff --git a/csharp/README.md b/csharp/README.md
index 305c44b6..ddf1d2be 100644
--- a/csharp/README.md
+++ b/csharp/README.md
@@ -1,18 +1,7 @@
This directory contains the C# Protocol Buffers runtime library.
-Status: Alpha - ready for early adopters
-========================================
-
-This code is still under significant churn. Unlike the original port,
-it only supports proto3 (but not *all* of proto3 yet) - there are no
-unknown fields or extensions, for example. protoc will (eventually)
-deliberately fail if it is asked to generate C# code for proto2
-messages other than descriptor.proto, which is still required for
-reflection. (It's currently exposed publicly, but won't be
-eventually.)
-
-Also unlike the original port, the new version embraces mutability -
-there are no builder types.
+Status: Beta - ready for external testing
+=========================================
Usage
=====
@@ -20,8 +9,8 @@ Usage
The easiest way how to use C# protobufs is via the `Google.Protobuf`
NuGet package. Just add the NuGet package to your VS project.
-Besides C# runtime library, the NuGet package also contains
-precompiled version of `protoc.exe` and a copy of well known `.proto`
+You will also want to install the `Google.Protobuf.Tools` NuGet package, which
+contains precompiled version of `protoc.exe` and a copy of well known `.proto`
files under the package's `tools` directory.
To generate C# files from your `.proto` files, invoke `protoc` with the
@@ -36,14 +25,25 @@ The runtime library is built as a portable class library, supporting:
- Windows 8
- Windows Phone Silverlight 8
- Windows Phone 8.1
-- .NET Core (dnxcore)
+- .NET Core
+
+You should be able to use Protocol Buffers in Visual Studio 2012 and
+all later versions. This includes all code generated by `protoc`,
+which only uses features from C# 3 and earlier.
Building
========
-Open the `src/Google.Protobuf.sln` solution in Visual Studio. Click "Build solution" to build the solution. You should be able to run the NUnit test from Test Explorer (you might need to install NUnit Visual Studio add-in).
+Open the `src/Google.Protobuf.sln` solution in Visual Studio 2015 or
+later. You should be able to run the NUnit test from Test Explorer
+(you might need to install NUnit Visual Studio add-in).
-Supported Visual Studio versions are VS2013 (update 4) and VS2015. On Linux, you can also use Monodevelop 5.9 (older versions might work fine).
+Although *users* of this project are only expected to have Visual
+Studio 2012 or later, *developers* of the library are required to
+have Visual Studio 2015 or later, as the library uses C# 6 features
+in its implementation. These features have no impact when using the
+compiled code - they're only relevant when building the
+`Google.Protobuf` assembly.
History of C# protobufs
=======================
@@ -52,3 +52,19 @@ This subtree was originally imported from https://github.com/jskeet/protobuf-csh
and represents the latest development version of C# protobufs, that will now be developed
and maintained by Google. All the development will be done in open, under this repository
(https://github.com/google/protobuf).
+
+The previous project differs from this project in a number of ways:
+
+- The old code only supported proto2; the new code only supports
+proto3 (so no unknown fields, no required/optional distinction, no
+extensions)
+- The old code was based on immutable message types and builders for
+them
+- The old code did not support maps or `oneof`
+- The old code had its own JSON representation, whereas the new code
+uses the standard protobuf JSON representation
+- The old code had no notion of the "well-known types" which have
+special support in the new code
+- The old project supported some older platforms (such as older
+versions of Silverlight) which are not currently supported in the
+new project
diff --git a/csharp/build_packages.bat b/csharp/build_packages.bat
index 1502f063..37732e7c 100644
--- a/csharp/build_packages.bat
+++ b/csharp/build_packages.bat
@@ -1,10 +1,7 @@
@rem Builds Google.Protobuf NuGet packages
-@rem Adjust the location of nuget.exe
-set NUGET=C:\nuget\nuget.exe
-
-@rem Build src/Google.Protobuf.sln solution in Release configuration first.
-%NUGET% pack src\Google.Protobuf\Google.Protobuf.nuspec -Symbols || goto :error
+dotnet restore src
+dotnet pack -c Release src\Google.Protobuf || goto :error
goto :EOF
diff --git a/csharp/buildall.sh b/csharp/buildall.sh
index 45af705f..cab32229 100755
--- a/csharp/buildall.sh
+++ b/csharp/buildall.sh
@@ -1,17 +1,16 @@
#!/bin/bash
-# Use mono to build solution and run all tests.
-# Adjust these to reflect the location of nunit-console in your system.
-NUNIT_CONSOLE=nunit-console
-
-# The rest you can leave intact
CONFIG=Release
SRC=$(dirname $0)/src
set -ex
-echo Building the solution.
-xbuild /p:Configuration=$CONFIG $SRC/Google.Protobuf.sln
+echo Building relevant projects.
+dotnet build -c $CONFIG $SRC/Google.Protobuf $SRC/Google.Protobuf.Test $SRC/Google.Protobuf.Conformance
echo Running tests.
-$NUNIT_CONSOLE $SRC/Google.Protobuf.Test/bin/$CONFIG/Google.Protobuf.Test.dll
+# Only test netcoreapp1.0, which uses the .NET Core runtime.
+# If we want to test the .NET 4.5 version separately, we could
+# run Mono explicitly. However, we don't have any differences between
+# the .NET 4.5 and netstandard1.0 assemblies.
+dotnet test -c $CONFIG -f netcoreapp1.0 $SRC/Google.Protobuf.Test
diff --git a/csharp/generate_protos.sh b/csharp/generate_protos.sh
index 3a556b0e..d979aa52 100755
--- a/csharp/generate_protos.sh
+++ b/csharp/generate_protos.sh
@@ -3,20 +3,10 @@
# You first need to make sure protoc has been built (see instructions on
# building protoc in root of this repository)
-# This script performs a few fix-ups as part of generation. These are:
-# - descriptor.proto is renamed to descriptor_proto_file.proto before
-# generation, to avoid the naming collision between the class for the file
-# descriptor and its Descriptor property
-# - This change also impacts UnittestCustomOptions, which expects to
-# use a class of Descriptor when it's actually been renamed to
-# DescriptorProtoFile.
-# - Issue 307 (codegen for double-nested types) breaks Unittest.proto and
-# its lite equivalents.
-
set -ex
# cd to repository root
-cd $(dirname $0)/..
+pushd $(dirname $0)/..
# Protocol buffer compiler to use. If the PROTOC variable is set,
# use that. Otherwise, probe for expected locations under both
@@ -68,5 +58,5 @@ $PROTOC -Icsharp/protos --csharp_out=csharp/src/Google.Protobuf.Test \
$PROTOC -Iexamples --csharp_out=csharp/src/AddressBook \
examples/addressbook.proto
-$PROTOC -Iconformance --csharp_out=csharp/src/Google.Protobuf.Conformance \
+$PROTOC -Iconformance -Isrc --csharp_out=csharp/src/Google.Protobuf.Conformance \
conformance/conformance.proto
diff --git a/csharp/keys/Google.Protobuf.snk b/csharp/keys/Google.Protobuf.snk
new file mode 100644
index 00000000..7515443c
--- /dev/null
+++ b/csharp/keys/Google.Protobuf.snk
Binary files differ
diff --git a/csharp/keys/README.md b/csharp/keys/README.md
index 1a014198..ede67357 100644
--- a/csharp/keys/README.md
+++ b/csharp/keys/README.md
@@ -2,4 +2,8 @@ Contents
--------
- Google.Protobuf.public.snk:
- Public key to verify strong name of Google.Protobuf assemblies. \ No newline at end of file
+ Public key to verify strong name of Google.Protobuf assemblies.
+- Google.Protobuf.snk:
+ Signing key to provide strong name of Google.Protobuf assemblies.
+ As per [Microsoft guidance](https://msdn.microsoft.com/en-us/library/wd40t7ad(v=vs.110).aspx)
+ signing key should be checked into the repository.
diff --git a/csharp/protos/unittest_issues.proto b/csharp/protos/unittest_issues.proto
index 989b3dc4..6c9f7634 100644
--- a/csharp/protos/unittest_issues.proto
+++ b/csharp/protos/unittest_issues.proto
@@ -116,4 +116,11 @@ message TestJsonFieldOrdering {
string o2_string = 3;
}
-} \ No newline at end of file
+}
+
+message TestJsonName {
+ // Message for testing the effects for of the json_name option
+ string name = 1;
+ string description = 2 [json_name = "desc"];
+ string guid = 3 [json_name = "exid"];
+}
diff --git a/csharp/src/AddressBook/AddPerson.cs b/csharp/src/AddressBook/AddPerson.cs
index 6eeb9f6e..62d1788d 100644
--- a/csharp/src/AddressBook/AddPerson.cs
+++ b/csharp/src/AddressBook/AddPerson.cs
@@ -73,13 +73,13 @@ namespace Google.Protobuf.Examples.AddressBook
switch (type)
{
case "mobile":
- phoneNumber.Type = Person.Types.PhoneType.MOBILE;
+ phoneNumber.Type = Person.Types.PhoneType.Mobile;
break;
case "home":
- phoneNumber.Type = Person.Types.PhoneType.HOME;
+ phoneNumber.Type = Person.Types.PhoneType.Home;
break;
case "work":
- phoneNumber.Type = Person.Types.PhoneType.WORK;
+ phoneNumber.Type = Person.Types.PhoneType.Work;
break;
default:
output.Write("Unknown phone type. Using default.");
diff --git a/csharp/src/AddressBook/AddressBook.csproj b/csharp/src/AddressBook/AddressBook.csproj
deleted file mode 100644
index 8f8ca7e2..00000000
--- a/csharp/src/AddressBook/AddressBook.csproj
+++ /dev/null
@@ -1,75 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ProductVersion>9.0.30729</ProductVersion>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{A31F5FB2-4FF3-432A-B35B-5CD203606311}</ProjectGuid>
- <OutputType>Exe</OutputType>
- <AppDesignerFolder>Properties</AppDesignerFolder>
- <RootNamespace>Google.Protobuf.Examples.AddressBook</RootNamespace>
- <AssemblyName>AddressBook</AssemblyName>
- <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
- <FileAlignment>512</FileAlignment>
- <StartupObject>Google.Protobuf.Examples.AddressBook.Program</StartupObject>
- <TargetFrameworkProfile>
- </TargetFrameworkProfile>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <DebugSymbols>true</DebugSymbols>
- <DebugType>full</DebugType>
- <Optimize>false</Optimize>
- <OutputPath>bin\Debug</OutputPath>
- <IntermediateOutputPath>obj\Debug\</IntermediateOutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- <NoStdLib>true</NoStdLib>
- <GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
- <Prefer32Bit>false</Prefer32Bit>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <DebugType>pdbonly</DebugType>
- <Optimize>true</Optimize>
- <OutputPath>bin\Release</OutputPath>
- <IntermediateOutputPath>obj\Release\</IntermediateOutputPath>
- <DefineConstants>TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- <NoStdLib>true</NoStdLib>
- <GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
- <Prefer32Bit>false</Prefer32Bit>
- </PropertyGroup>
- <ItemGroup>
- <Reference Include="mscorlib" />
- <Reference Include="System" />
- <Reference Include="System.Data" />
- <Reference Include="System.Xml" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="AddPerson.cs" />
- <Compile Include="Addressbook.cs" />
- <Compile Include="SampleUsage.cs" />
- <Compile Include="ListPeople.cs" />
- <Compile Include="Program.cs" />
- <Compile Include="Properties\AssemblyInfo.cs" />
- </ItemGroup>
- <ItemGroup>
- <ProjectReference Include="..\Google.Protobuf\Google.Protobuf.csproj">
- <Project>{6908BDCE-D925-43F3-94AC-A531E6DF2591}</Project>
- <Name>Google.Protobuf</Name>
- </ProjectReference>
- </ItemGroup>
- <ItemGroup>
- <None Include="app.config" />
- </ItemGroup>
- <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
- Other similar extension points exist, see Microsoft.Common.targets.
- <Target Name="BeforeBuild">
- </Target>
- <Target Name="AfterBuild">
- </Target>
- -->
-</Project> \ No newline at end of file
diff --git a/csharp/src/AddressBook/AddressBook.xproj b/csharp/src/AddressBook/AddressBook.xproj
new file mode 100644
index 00000000..4c9925e8
--- /dev/null
+++ b/csharp/src/AddressBook/AddressBook.xproj
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
+ <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
+ </PropertyGroup>
+ <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>afb63919-1e05-43b4-802a-8fb8c9b2f463</ProjectGuid>
+ <RootNamespace>AddressBook</RootNamespace>
+ <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
+ <OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
+ </PropertyGroup>
+
+ <PropertyGroup>
+ <SchemaVersion>2.0</SchemaVersion>
+ </PropertyGroup>
+ <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
+</Project> \ No newline at end of file
diff --git a/csharp/src/AddressBook/Addressbook.cs b/csharp/src/AddressBook/Addressbook.cs
index d5455d80..8e691ad4 100644
--- a/csharp/src/AddressBook/Addressbook.cs
+++ b/csharp/src/AddressBook/Addressbook.cs
@@ -10,7 +10,6 @@ using scg = global::System.Collections.Generic;
namespace Google.Protobuf.Examples.AddressBook {
/// <summary>Holder for reflection information generated from addressbook.proto</summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public static partial class AddressbookReflection {
#region Descriptor
@@ -34,34 +33,41 @@ namespace Google.Protobuf.Examples.AddressBook {
"cGxlcy5BZGRyZXNzQm9va2IGcHJvdG8z"));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
- new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Examples.AddressBook.Person), global::Google.Protobuf.Examples.AddressBook.Person.Parser, new[]{ "Name", "Id", "Email", "Phones" }, null, new[]{ typeof(global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneType) }, new pbr::GeneratedCodeInfo[] { new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneNumber), global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneNumber.Parser, new[]{ "Number", "Type" }, null, null, null)}),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Examples.AddressBook.AddressBook), global::Google.Protobuf.Examples.AddressBook.AddressBook.Parser, new[]{ "People" }, null, null, null)
+ new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Examples.AddressBook.Person), global::Google.Protobuf.Examples.AddressBook.Person.Parser, new[]{ "Name", "Id", "Email", "Phones" }, null, new[]{ typeof(global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneType) }, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneNumber), global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneNumber.Parser, new[]{ "Number", "Type" }, null, null, null)}),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Examples.AddressBook.AddressBook), global::Google.Protobuf.Examples.AddressBook.AddressBook.Parser, new[]{ "People" }, null, null, null)
}));
}
#endregion
}
#region Messages
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ /// <summary>
+ /// [START messages]
+ /// </summary>
public sealed partial class Person : pb::IMessage<Person> {
private static readonly pb::MessageParser<Person> _parser = new pb::MessageParser<Person>(() => new Person());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<Person> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.Examples.AddressBook.AddressbookReflection.Descriptor.MessageTypes[0]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Person() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Person(Person other) : this() {
name_ = other.name_;
id_ = other.id_;
@@ -69,6 +75,7 @@ namespace Google.Protobuf.Examples.AddressBook {
phones_ = other.phones_.Clone();
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Person Clone() {
return new Person(this);
}
@@ -76,10 +83,11 @@ namespace Google.Protobuf.Examples.AddressBook {
/// <summary>Field number for the "name" field.</summary>
public const int NameFieldNumber = 1;
private string name_ = "";
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string Name {
get { return name_; }
set {
- name_ = pb::Preconditions.CheckNotNull(value, "value");
+ name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -89,6 +97,7 @@ namespace Google.Protobuf.Examples.AddressBook {
/// <summary>
/// Unique ID number for this person.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int Id {
get { return id_; }
set {
@@ -99,10 +108,11 @@ namespace Google.Protobuf.Examples.AddressBook {
/// <summary>Field number for the "email" field.</summary>
public const int EmailFieldNumber = 3;
private string email_ = "";
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string Email {
get { return email_; }
set {
- email_ = pb::Preconditions.CheckNotNull(value, "value");
+ email_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -111,14 +121,17 @@ namespace Google.Protobuf.Examples.AddressBook {
private static readonly pb::FieldCodec<global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneNumber> _repeated_phones_codec
= pb::FieldCodec.ForMessage(34, global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneNumber.Parser);
private readonly pbc::RepeatedField<global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneNumber> phones_ = new pbc::RepeatedField<global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneNumber>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneNumber> Phones {
get { return phones_; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as Person);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(Person other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -133,6 +146,7 @@ namespace Google.Protobuf.Examples.AddressBook {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Name.Length != 0) hash ^= Name.GetHashCode();
@@ -142,10 +156,12 @@ namespace Google.Protobuf.Examples.AddressBook {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Name.Length != 0) {
output.WriteRawTag(10);
@@ -162,6 +178,7 @@ namespace Google.Protobuf.Examples.AddressBook {
phones_.WriteTo(output, _repeated_phones_codec);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Name.Length != 0) {
@@ -177,6 +194,7 @@ namespace Google.Protobuf.Examples.AddressBook {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(Person other) {
if (other == null) {
return;
@@ -193,6 +211,7 @@ namespace Google.Protobuf.Examples.AddressBook {
phones_.Add(other.phones_);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -222,38 +241,43 @@ namespace Google.Protobuf.Examples.AddressBook {
#region Nested types
/// <summary>Container for nested types declared in the Person message type.</summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static partial class Types {
public enum PhoneType {
- MOBILE = 0,
- HOME = 1,
- WORK = 2,
+ [pbr::OriginalName("MOBILE")] Mobile = 0,
+ [pbr::OriginalName("HOME")] Home = 1,
+ [pbr::OriginalName("WORK")] Work = 2,
}
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class PhoneNumber : pb::IMessage<PhoneNumber> {
private static readonly pb::MessageParser<PhoneNumber> _parser = new pb::MessageParser<PhoneNumber>(() => new PhoneNumber());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<PhoneNumber> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.Examples.AddressBook.Person.Descriptor.NestedTypes[0]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public PhoneNumber() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public PhoneNumber(PhoneNumber other) : this() {
number_ = other.number_;
type_ = other.type_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public PhoneNumber Clone() {
return new PhoneNumber(this);
}
@@ -261,16 +285,18 @@ namespace Google.Protobuf.Examples.AddressBook {
/// <summary>Field number for the "number" field.</summary>
public const int NumberFieldNumber = 1;
private string number_ = "";
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string Number {
get { return number_; }
set {
- number_ = pb::Preconditions.CheckNotNull(value, "value");
+ number_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
/// <summary>Field number for the "type" field.</summary>
public const int TypeFieldNumber = 2;
- private global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneType type_ = global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneType.MOBILE;
+ private global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneType type_ = 0;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneType Type {
get { return type_; }
set {
@@ -278,10 +304,12 @@ namespace Google.Protobuf.Examples.AddressBook {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as PhoneNumber);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(PhoneNumber other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -294,39 +322,44 @@ namespace Google.Protobuf.Examples.AddressBook {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Number.Length != 0) hash ^= Number.GetHashCode();
- if (Type != global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneType.MOBILE) hash ^= Type.GetHashCode();
+ if (Type != 0) hash ^= Type.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Number.Length != 0) {
output.WriteRawTag(10);
output.WriteString(Number);
}
- if (Type != global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneType.MOBILE) {
+ if (Type != 0) {
output.WriteRawTag(16);
output.WriteEnum((int) Type);
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Number.Length != 0) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(Number);
}
- if (Type != global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneType.MOBILE) {
+ if (Type != 0) {
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Type);
}
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(PhoneNumber other) {
if (other == null) {
return;
@@ -334,11 +367,12 @@ namespace Google.Protobuf.Examples.AddressBook {
if (other.Number.Length != 0) {
Number = other.Number;
}
- if (other.Type != global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneType.MOBILE) {
+ if (other.Type != 0) {
Type = other.Type;
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -368,29 +402,34 @@ namespace Google.Protobuf.Examples.AddressBook {
/// <summary>
/// Our address book file is just one of these.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class AddressBook : pb::IMessage<AddressBook> {
private static readonly pb::MessageParser<AddressBook> _parser = new pb::MessageParser<AddressBook>(() => new AddressBook());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<AddressBook> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.Examples.AddressBook.AddressbookReflection.Descriptor.MessageTypes[1]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public AddressBook() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public AddressBook(AddressBook other) : this() {
people_ = other.people_.Clone();
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public AddressBook Clone() {
return new AddressBook(this);
}
@@ -400,14 +439,17 @@ namespace Google.Protobuf.Examples.AddressBook {
private static readonly pb::FieldCodec<global::Google.Protobuf.Examples.AddressBook.Person> _repeated_people_codec
= pb::FieldCodec.ForMessage(10, global::Google.Protobuf.Examples.AddressBook.Person.Parser);
private readonly pbc::RepeatedField<global::Google.Protobuf.Examples.AddressBook.Person> people_ = new pbc::RepeatedField<global::Google.Protobuf.Examples.AddressBook.Person>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.Examples.AddressBook.Person> People {
get { return people_; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as AddressBook);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(AddressBook other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -419,26 +461,31 @@ namespace Google.Protobuf.Examples.AddressBook {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
hash ^= people_.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
people_.WriteTo(output, _repeated_people_codec);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
size += people_.CalculateSize(_repeated_people_codec);
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(AddressBook other) {
if (other == null) {
return;
@@ -446,6 +493,7 @@ namespace Google.Protobuf.Examples.AddressBook {
people_.Add(other.people_);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
diff --git a/csharp/src/AddressBook/ListPeople.cs b/csharp/src/AddressBook/ListPeople.cs
index 3979430f..3758c1bc 100644
--- a/csharp/src/AddressBook/ListPeople.cs
+++ b/csharp/src/AddressBook/ListPeople.cs
@@ -55,13 +55,13 @@ namespace Google.Protobuf.Examples.AddressBook
{
switch (phoneNumber.Type)
{
- case Person.Types.PhoneType.MOBILE:
+ case Person.Types.PhoneType.Mobile:
Console.Write(" Mobile phone #: ");
break;
- case Person.Types.PhoneType.HOME:
+ case Person.Types.PhoneType.Home:
Console.Write(" Home phone #: ");
break;
- case Person.Types.PhoneType.WORK:
+ case Person.Types.PhoneType.Work:
Console.Write(" Work phone #: ");
break;
}
diff --git a/csharp/src/AddressBook/Properties/AssemblyInfo.cs b/csharp/src/AddressBook/Properties/AssemblyInfo.cs
deleted file mode 100644
index 9cb014c0..00000000
--- a/csharp/src/AddressBook/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System.Reflection;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-
-[assembly: AssemblyTitle("AddressBook")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("AddressBook")]
-[assembly: AssemblyCopyright("Copyright © 2015")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-[assembly: AssemblyVersion("3.0.0.0")]
-[assembly: AssemblyFileVersion("3.0.0.0")]
diff --git a/csharp/src/AddressBook/SampleUsage.cs b/csharp/src/AddressBook/SampleUsage.cs
index aaaedda4..941d865a 100644
--- a/csharp/src/AddressBook/SampleUsage.cs
+++ b/csharp/src/AddressBook/SampleUsage.cs
@@ -66,7 +66,7 @@ namespace Google.Protobuf.Examples.AddressBook
// The message performs a deep-comparison on equality:
if (restored.People.Count != 1 || !person.Equals(restored.People[0]))
{
- throw new ApplicationException("There is a bad person in here!");
+ throw new Exception("There is a bad person in here!");
}
}
}
diff --git a/csharp/src/AddressBook/app.config b/csharp/src/AddressBook/app.config
deleted file mode 100644
index a80813af..00000000
--- a/csharp/src/AddressBook/app.config
+++ /dev/null
@@ -1,3 +0,0 @@
-<?xml version="1.0"?>
-<configuration>
- <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/></startup></configuration>
diff --git a/csharp/src/AddressBook/project.json b/csharp/src/AddressBook/project.json
new file mode 100644
index 00000000..c500bdc2
--- /dev/null
+++ b/csharp/src/AddressBook/project.json
@@ -0,0 +1,20 @@
+{
+ "buildOptions": {
+ "debugType": "portable",
+ "emitEntryPoint": true,
+ "additionalArguments": [ "/main:Google.Protobuf.Examples.AddressBook.Program" ]
+ },
+ "dependencies": {
+ "Google.Protobuf": { "target": "project" }
+ },
+ "frameworks": {
+ "netcoreapp1.0": {
+ "dependencies": {
+ "Microsoft.NETCore.App": {
+ "type": "platform",
+ "version": "1.0.0"
+ }
+ }
+ }
+ }
+}
diff --git a/csharp/src/Google.Protobuf.Conformance/App.config b/csharp/src/Google.Protobuf.Conformance/App.config
deleted file mode 100644
index 8e156463..00000000
--- a/csharp/src/Google.Protobuf.Conformance/App.config
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<configuration>
- <startup>
- <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
- </startup>
-</configuration> \ No newline at end of file
diff --git a/csharp/src/Google.Protobuf.Conformance/Conformance.cs b/csharp/src/Google.Protobuf.Conformance/Conformance.cs
index 50ce1de4..5fcbff7c 100644
--- a/csharp/src/Google.Protobuf.Conformance/Conformance.cs
+++ b/csharp/src/Google.Protobuf.Conformance/Conformance.cs
@@ -10,7 +10,6 @@ using scg = global::System.Collections.Generic;
namespace Conformance {
/// <summary>Holder for reflection information generated from conformance.proto</summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public static partial class ConformanceReflection {
#region Descriptor
@@ -23,125 +22,175 @@ namespace Conformance {
static ConformanceReflection() {
byte[] descriptorData = global::System.Convert.FromBase64String(
string.Concat(
- "ChFjb25mb3JtYW5jZS5wcm90bxILY29uZm9ybWFuY2UijQEKEkNvbmZvcm1h",
- "bmNlUmVxdWVzdBIaChBwcm90b2J1Zl9wYXlsb2FkGAEgASgMSAASFgoManNv",
- "bl9wYXlsb2FkGAIgASgJSAASOAoXcmVxdWVzdGVkX291dHB1dF9mb3JtYXQY",
- "AyABKA4yFy5jb25mb3JtYW5jZS5XaXJlRm9ybWF0QgkKB3BheWxvYWQilgEK",
- "E0NvbmZvcm1hbmNlUmVzcG9uc2USFQoLcGFyc2VfZXJyb3IYASABKAlIABIX",
- "Cg1ydW50aW1lX2Vycm9yGAIgASgJSAASGgoQcHJvdG9idWZfcGF5bG9hZBgD",
- "IAEoDEgAEhYKDGpzb25fcGF5bG9hZBgEIAEoCUgAEhEKB3NraXBwZWQYBSAB",
- "KAlIAEIICgZyZXN1bHQi6yIKDFRlc3RBbGxUeXBlcxIWCg5vcHRpb25hbF9p",
- "bnQzMhgBIAEoBRIWCg5vcHRpb25hbF9pbnQ2NBgCIAEoAxIXCg9vcHRpb25h",
- "bF91aW50MzIYAyABKA0SFwoPb3B0aW9uYWxfdWludDY0GAQgASgEEhcKD29w",
- "dGlvbmFsX3NpbnQzMhgFIAEoERIXCg9vcHRpb25hbF9zaW50NjQYBiABKBIS",
- "GAoQb3B0aW9uYWxfZml4ZWQzMhgHIAEoBxIYChBvcHRpb25hbF9maXhlZDY0",
- "GAggASgGEhkKEW9wdGlvbmFsX3NmaXhlZDMyGAkgASgPEhkKEW9wdGlvbmFs",
- "X3NmaXhlZDY0GAogASgQEhYKDm9wdGlvbmFsX2Zsb2F0GAsgASgCEhcKD29w",
- "dGlvbmFsX2RvdWJsZRgMIAEoARIVCg1vcHRpb25hbF9ib29sGA0gASgIEhcK",
- "D29wdGlvbmFsX3N0cmluZxgOIAEoCRIWCg5vcHRpb25hbF9ieXRlcxgPIAEo",
- "DBJIChdvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZRgSIAEoCzInLmNvbmZvcm1h",
- "bmNlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlEj0KGG9wdGlvbmFsX2Zv",
- "cmVpZ25fbWVzc2FnZRgTIAEoCzIbLmNvbmZvcm1hbmNlLkZvcmVpZ25NZXNz",
- "YWdlEkIKFG9wdGlvbmFsX25lc3RlZF9lbnVtGBUgASgOMiQuY29uZm9ybWFu",
- "Y2UuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0SNwoVb3B0aW9uYWxfZm9yZWln",
- "bl9lbnVtGBYgASgOMhguY29uZm9ybWFuY2UuRm9yZWlnbkVudW0SIQoVb3B0",
- "aW9uYWxfc3RyaW5nX3BpZWNlGBggASgJQgIIAhIZCg1vcHRpb25hbF9jb3Jk",
- "GBkgASgJQgIIARI0ChFyZWN1cnNpdmVfbWVzc2FnZRgbIAEoCzIZLmNvbmZv",
- "cm1hbmNlLlRlc3RBbGxUeXBlcxIWCg5yZXBlYXRlZF9pbnQzMhgfIAMoBRIW",
- "Cg5yZXBlYXRlZF9pbnQ2NBggIAMoAxIXCg9yZXBlYXRlZF91aW50MzIYISAD",
- "KA0SFwoPcmVwZWF0ZWRfdWludDY0GCIgAygEEhcKD3JlcGVhdGVkX3NpbnQz",
- "MhgjIAMoERIXCg9yZXBlYXRlZF9zaW50NjQYJCADKBISGAoQcmVwZWF0ZWRf",
- "Zml4ZWQzMhglIAMoBxIYChByZXBlYXRlZF9maXhlZDY0GCYgAygGEhkKEXJl",
- "cGVhdGVkX3NmaXhlZDMyGCcgAygPEhkKEXJlcGVhdGVkX3NmaXhlZDY0GCgg",
- "AygQEhYKDnJlcGVhdGVkX2Zsb2F0GCkgAygCEhcKD3JlcGVhdGVkX2RvdWJs",
- "ZRgqIAMoARIVCg1yZXBlYXRlZF9ib29sGCsgAygIEhcKD3JlcGVhdGVkX3N0",
- "cmluZxgsIAMoCRIWCg5yZXBlYXRlZF9ieXRlcxgtIAMoDBJIChdyZXBlYXRl",
- "ZF9uZXN0ZWRfbWVzc2FnZRgwIAMoCzInLmNvbmZvcm1hbmNlLlRlc3RBbGxU",
- "eXBlcy5OZXN0ZWRNZXNzYWdlEj0KGHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2Fn",
- "ZRgxIAMoCzIbLmNvbmZvcm1hbmNlLkZvcmVpZ25NZXNzYWdlEkIKFHJlcGVh",
- "dGVkX25lc3RlZF9lbnVtGDMgAygOMiQuY29uZm9ybWFuY2UuVGVzdEFsbFR5",
- "cGVzLk5lc3RlZEVudW0SNwoVcmVwZWF0ZWRfZm9yZWlnbl9lbnVtGDQgAygO",
- "MhguY29uZm9ybWFuY2UuRm9yZWlnbkVudW0SIQoVcmVwZWF0ZWRfc3RyaW5n",
- "X3BpZWNlGDYgAygJQgIIAhIZCg1yZXBlYXRlZF9jb3JkGDcgAygJQgIIARJF",
- "Cg9tYXBfaW50MzJfaW50MzIYOCADKAsyLC5jb25mb3JtYW5jZS5UZXN0QWxs",
- "VHlwZXMuTWFwSW50MzJJbnQzMkVudHJ5EkUKD21hcF9pbnQ2NF9pbnQ2NBg5",
- "IAMoCzIsLmNvbmZvcm1hbmNlLlRlc3RBbGxUeXBlcy5NYXBJbnQ2NEludDY0",
- "RW50cnkSSQoRbWFwX3VpbnQzMl91aW50MzIYOiADKAsyLi5jb25mb3JtYW5j",
- "ZS5UZXN0QWxsVHlwZXMuTWFwVWludDMyVWludDMyRW50cnkSSQoRbWFwX3Vp",
- "bnQ2NF91aW50NjQYOyADKAsyLi5jb25mb3JtYW5jZS5UZXN0QWxsVHlwZXMu",
- "TWFwVWludDY0VWludDY0RW50cnkSSQoRbWFwX3NpbnQzMl9zaW50MzIYPCAD",
- "KAsyLi5jb25mb3JtYW5jZS5UZXN0QWxsVHlwZXMuTWFwU2ludDMyU2ludDMy",
- "RW50cnkSSQoRbWFwX3NpbnQ2NF9zaW50NjQYPSADKAsyLi5jb25mb3JtYW5j",
- "ZS5UZXN0QWxsVHlwZXMuTWFwU2ludDY0U2ludDY0RW50cnkSTQoTbWFwX2Zp",
- "eGVkMzJfZml4ZWQzMhg+IAMoCzIwLmNvbmZvcm1hbmNlLlRlc3RBbGxUeXBl",
- "cy5NYXBGaXhlZDMyRml4ZWQzMkVudHJ5Ek0KE21hcF9maXhlZDY0X2ZpeGVk",
- "NjQYPyADKAsyMC5jb25mb3JtYW5jZS5UZXN0QWxsVHlwZXMuTWFwRml4ZWQ2",
- "NEZpeGVkNjRFbnRyeRJRChVtYXBfc2ZpeGVkMzJfc2ZpeGVkMzIYQCADKAsy",
- "Mi5jb25mb3JtYW5jZS5UZXN0QWxsVHlwZXMuTWFwU2ZpeGVkMzJTZml4ZWQz",
- "MkVudHJ5ElEKFW1hcF9zZml4ZWQ2NF9zZml4ZWQ2NBhBIAMoCzIyLmNvbmZv",
- "cm1hbmNlLlRlc3RBbGxUeXBlcy5NYXBTZml4ZWQ2NFNmaXhlZDY0RW50cnkS",
- "RQoPbWFwX2ludDMyX2Zsb2F0GEIgAygLMiwuY29uZm9ybWFuY2UuVGVzdEFs",
- "bFR5cGVzLk1hcEludDMyRmxvYXRFbnRyeRJHChBtYXBfaW50MzJfZG91Ymxl",
- "GEMgAygLMi0uY29uZm9ybWFuY2UuVGVzdEFsbFR5cGVzLk1hcEludDMyRG91",
- "YmxlRW50cnkSQQoNbWFwX2Jvb2xfYm9vbBhEIAMoCzIqLmNvbmZvcm1hbmNl",
- "LlRlc3RBbGxUeXBlcy5NYXBCb29sQm9vbEVudHJ5EkkKEW1hcF9zdHJpbmdf",
- "c3RyaW5nGEUgAygLMi4uY29uZm9ybWFuY2UuVGVzdEFsbFR5cGVzLk1hcFN0",
- "cmluZ1N0cmluZ0VudHJ5EkcKEG1hcF9zdHJpbmdfYnl0ZXMYRiADKAsyLS5j",
- "b25mb3JtYW5jZS5UZXN0QWxsVHlwZXMuTWFwU3RyaW5nQnl0ZXNFbnRyeRJY",
- "ChltYXBfc3RyaW5nX25lc3RlZF9tZXNzYWdlGEcgAygLMjUuY29uZm9ybWFu",
- "Y2UuVGVzdEFsbFR5cGVzLk1hcFN0cmluZ05lc3RlZE1lc3NhZ2VFbnRyeRJa",
- "ChptYXBfc3RyaW5nX2ZvcmVpZ25fbWVzc2FnZRhIIAMoCzI2LmNvbmZvcm1h",
- "bmNlLlRlc3RBbGxUeXBlcy5NYXBTdHJpbmdGb3JlaWduTWVzc2FnZUVudHJ5",
- "ElIKFm1hcF9zdHJpbmdfbmVzdGVkX2VudW0YSSADKAsyMi5jb25mb3JtYW5j",
- "ZS5UZXN0QWxsVHlwZXMuTWFwU3RyaW5nTmVzdGVkRW51bUVudHJ5ElQKF21h",
- "cF9zdHJpbmdfZm9yZWlnbl9lbnVtGEogAygLMjMuY29uZm9ybWFuY2UuVGVz",
- "dEFsbFR5cGVzLk1hcFN0cmluZ0ZvcmVpZ25FbnVtRW50cnkSFgoMb25lb2Zf",
- "dWludDMyGG8gASgNSAASRwoUb25lb2ZfbmVzdGVkX21lc3NhZ2UYcCABKAsy",
- "Jy5jb25mb3JtYW5jZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZUgAEhYK",
- "DG9uZW9mX3N0cmluZxhxIAEoCUgAEhUKC29uZW9mX2J5dGVzGHIgASgMSAAa",
- "SgoNTmVzdGVkTWVzc2FnZRIJCgFhGAEgASgFEi4KC2NvcmVjdXJzaXZlGAIg",
- "ASgLMhkuY29uZm9ybWFuY2UuVGVzdEFsbFR5cGVzGjQKEk1hcEludDMySW50",
- "MzJFbnRyeRILCgNrZXkYASABKAUSDQoFdmFsdWUYAiABKAU6AjgBGjQKEk1h",
- "cEludDY0SW50NjRFbnRyeRILCgNrZXkYASABKAMSDQoFdmFsdWUYAiABKAM6",
- "AjgBGjYKFE1hcFVpbnQzMlVpbnQzMkVudHJ5EgsKA2tleRgBIAEoDRINCgV2",
- "YWx1ZRgCIAEoDToCOAEaNgoUTWFwVWludDY0VWludDY0RW50cnkSCwoDa2V5",
- "GAEgASgEEg0KBXZhbHVlGAIgASgEOgI4ARo2ChRNYXBTaW50MzJTaW50MzJF",
- "bnRyeRILCgNrZXkYASABKBESDQoFdmFsdWUYAiABKBE6AjgBGjYKFE1hcFNp",
- "bnQ2NFNpbnQ2NEVudHJ5EgsKA2tleRgBIAEoEhINCgV2YWx1ZRgCIAEoEjoC",
- "OAEaOAoWTWFwRml4ZWQzMkZpeGVkMzJFbnRyeRILCgNrZXkYASABKAcSDQoF",
- "dmFsdWUYAiABKAc6AjgBGjgKFk1hcEZpeGVkNjRGaXhlZDY0RW50cnkSCwoD",
- "a2V5GAEgASgGEg0KBXZhbHVlGAIgASgGOgI4ARo6ChhNYXBTZml4ZWQzMlNm",
- "aXhlZDMyRW50cnkSCwoDa2V5GAEgASgPEg0KBXZhbHVlGAIgASgPOgI4ARo6",
- "ChhNYXBTZml4ZWQ2NFNmaXhlZDY0RW50cnkSCwoDa2V5GAEgASgQEg0KBXZh",
- "bHVlGAIgASgQOgI4ARo0ChJNYXBJbnQzMkZsb2F0RW50cnkSCwoDa2V5GAEg",
- "ASgFEg0KBXZhbHVlGAIgASgCOgI4ARo1ChNNYXBJbnQzMkRvdWJsZUVudHJ5",
- "EgsKA2tleRgBIAEoBRINCgV2YWx1ZRgCIAEoAToCOAEaMgoQTWFwQm9vbEJv",
- "b2xFbnRyeRILCgNrZXkYASABKAgSDQoFdmFsdWUYAiABKAg6AjgBGjYKFE1h",
- "cFN0cmluZ1N0cmluZ0VudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEo",
- "CToCOAEaNQoTTWFwU3RyaW5nQnl0ZXNFbnRyeRILCgNrZXkYASABKAkSDQoF",
- "dmFsdWUYAiABKAw6AjgBGmYKG01hcFN0cmluZ05lc3RlZE1lc3NhZ2VFbnRy",
- "eRILCgNrZXkYASABKAkSNgoFdmFsdWUYAiABKAsyJy5jb25mb3JtYW5jZS5U",
- "ZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZToCOAEaWwocTWFwU3RyaW5nRm9y",
- "ZWlnbk1lc3NhZ2VFbnRyeRILCgNrZXkYASABKAkSKgoFdmFsdWUYAiABKAsy",
- "Gy5jb25mb3JtYW5jZS5Gb3JlaWduTWVzc2FnZToCOAEaYAoYTWFwU3RyaW5n",
- "TmVzdGVkRW51bUVudHJ5EgsKA2tleRgBIAEoCRIzCgV2YWx1ZRgCIAEoDjIk",
- "LmNvbmZvcm1hbmNlLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtOgI4ARpVChlN",
- "YXBTdHJpbmdGb3JlaWduRW51bUVudHJ5EgsKA2tleRgBIAEoCRInCgV2YWx1",
- "ZRgCIAEoDjIYLmNvbmZvcm1hbmNlLkZvcmVpZ25FbnVtOgI4ASI5CgpOZXN0",
- "ZWRFbnVtEgcKA0ZPTxAAEgcKA0JBUhABEgcKA0JBWhACEhAKA05FRxD/////",
- "//////8BQg0KC29uZW9mX2ZpZWxkIhsKDkZvcmVpZ25NZXNzYWdlEgkKAWMY",
- "ASABKAUqNQoKV2lyZUZvcm1hdBIPCgtVTlNQRUNJRklFRBAAEgwKCFBST1RP",
- "QlVGEAESCAoESlNPThACKkAKC0ZvcmVpZ25FbnVtEg8KC0ZPUkVJR05fRk9P",
- "EAASDwoLRk9SRUlHTl9CQVIQARIPCgtGT1JFSUdOX0JBWhACQiEKH2NvbS5n",
- "b29nbGUucHJvdG9idWYuY29uZm9ybWFuY2ViBnByb3RvMw=="));
+ "ChFjb25mb3JtYW5jZS5wcm90bxILY29uZm9ybWFuY2UaGWdvb2dsZS9wcm90",
+ "b2J1Zi9hbnkucHJvdG8aHmdvb2dsZS9wcm90b2J1Zi9kdXJhdGlvbi5wcm90",
+ "bxogZ29vZ2xlL3Byb3RvYnVmL2ZpZWxkX21hc2sucHJvdG8aHGdvb2dsZS9w",
+ "cm90b2J1Zi9zdHJ1Y3QucHJvdG8aH2dvb2dsZS9wcm90b2J1Zi90aW1lc3Rh",
+ "bXAucHJvdG8aHmdvb2dsZS9wcm90b2J1Zi93cmFwcGVycy5wcm90byKNAQoS",
+ "Q29uZm9ybWFuY2VSZXF1ZXN0EhoKEHByb3RvYnVmX3BheWxvYWQYASABKAxI",
+ "ABIWCgxqc29uX3BheWxvYWQYAiABKAlIABI4ChdyZXF1ZXN0ZWRfb3V0cHV0",
+ "X2Zvcm1hdBgDIAEoDjIXLmNvbmZvcm1hbmNlLldpcmVGb3JtYXRCCQoHcGF5",
+ "bG9hZCKxAQoTQ29uZm9ybWFuY2VSZXNwb25zZRIVCgtwYXJzZV9lcnJvchgB",
+ "IAEoCUgAEhkKD3NlcmlhbGl6ZV9lcnJvchgGIAEoCUgAEhcKDXJ1bnRpbWVf",
+ "ZXJyb3IYAiABKAlIABIaChBwcm90b2J1Zl9wYXlsb2FkGAMgASgMSAASFgoM",
+ "anNvbl9wYXlsb2FkGAQgASgJSAASEQoHc2tpcHBlZBgFIAEoCUgAQggKBnJl",
+ "c3VsdCLVMgoMVGVzdEFsbFR5cGVzEhYKDm9wdGlvbmFsX2ludDMyGAEgASgF",
+ "EhYKDm9wdGlvbmFsX2ludDY0GAIgASgDEhcKD29wdGlvbmFsX3VpbnQzMhgD",
+ "IAEoDRIXCg9vcHRpb25hbF91aW50NjQYBCABKAQSFwoPb3B0aW9uYWxfc2lu",
+ "dDMyGAUgASgREhcKD29wdGlvbmFsX3NpbnQ2NBgGIAEoEhIYChBvcHRpb25h",
+ "bF9maXhlZDMyGAcgASgHEhgKEG9wdGlvbmFsX2ZpeGVkNjQYCCABKAYSGQoR",
+ "b3B0aW9uYWxfc2ZpeGVkMzIYCSABKA8SGQoRb3B0aW9uYWxfc2ZpeGVkNjQY",
+ "CiABKBASFgoOb3B0aW9uYWxfZmxvYXQYCyABKAISFwoPb3B0aW9uYWxfZG91",
+ "YmxlGAwgASgBEhUKDW9wdGlvbmFsX2Jvb2wYDSABKAgSFwoPb3B0aW9uYWxf",
+ "c3RyaW5nGA4gASgJEhYKDm9wdGlvbmFsX2J5dGVzGA8gASgMEkgKF29wdGlv",
+ "bmFsX25lc3RlZF9tZXNzYWdlGBIgASgLMicuY29uZm9ybWFuY2UuVGVzdEFs",
+ "bFR5cGVzLk5lc3RlZE1lc3NhZ2USPQoYb3B0aW9uYWxfZm9yZWlnbl9tZXNz",
+ "YWdlGBMgASgLMhsuY29uZm9ybWFuY2UuRm9yZWlnbk1lc3NhZ2USQgoUb3B0",
+ "aW9uYWxfbmVzdGVkX2VudW0YFSABKA4yJC5jb25mb3JtYW5jZS5UZXN0QWxs",
+ "VHlwZXMuTmVzdGVkRW51bRI3ChVvcHRpb25hbF9mb3JlaWduX2VudW0YFiAB",
+ "KA4yGC5jb25mb3JtYW5jZS5Gb3JlaWduRW51bRIhChVvcHRpb25hbF9zdHJp",
+ "bmdfcGllY2UYGCABKAlCAggCEhkKDW9wdGlvbmFsX2NvcmQYGSABKAlCAggB",
+ "EjQKEXJlY3Vyc2l2ZV9tZXNzYWdlGBsgASgLMhkuY29uZm9ybWFuY2UuVGVz",
+ "dEFsbFR5cGVzEhYKDnJlcGVhdGVkX2ludDMyGB8gAygFEhYKDnJlcGVhdGVk",
+ "X2ludDY0GCAgAygDEhcKD3JlcGVhdGVkX3VpbnQzMhghIAMoDRIXCg9yZXBl",
+ "YXRlZF91aW50NjQYIiADKAQSFwoPcmVwZWF0ZWRfc2ludDMyGCMgAygREhcK",
+ "D3JlcGVhdGVkX3NpbnQ2NBgkIAMoEhIYChByZXBlYXRlZF9maXhlZDMyGCUg",
+ "AygHEhgKEHJlcGVhdGVkX2ZpeGVkNjQYJiADKAYSGQoRcmVwZWF0ZWRfc2Zp",
+ "eGVkMzIYJyADKA8SGQoRcmVwZWF0ZWRfc2ZpeGVkNjQYKCADKBASFgoOcmVw",
+ "ZWF0ZWRfZmxvYXQYKSADKAISFwoPcmVwZWF0ZWRfZG91YmxlGCogAygBEhUK",
+ "DXJlcGVhdGVkX2Jvb2wYKyADKAgSFwoPcmVwZWF0ZWRfc3RyaW5nGCwgAygJ",
+ "EhYKDnJlcGVhdGVkX2J5dGVzGC0gAygMEkgKF3JlcGVhdGVkX25lc3RlZF9t",
+ "ZXNzYWdlGDAgAygLMicuY29uZm9ybWFuY2UuVGVzdEFsbFR5cGVzLk5lc3Rl",
+ "ZE1lc3NhZ2USPQoYcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlGDEgAygLMhsu",
+ "Y29uZm9ybWFuY2UuRm9yZWlnbk1lc3NhZ2USQgoUcmVwZWF0ZWRfbmVzdGVk",
+ "X2VudW0YMyADKA4yJC5jb25mb3JtYW5jZS5UZXN0QWxsVHlwZXMuTmVzdGVk",
+ "RW51bRI3ChVyZXBlYXRlZF9mb3JlaWduX2VudW0YNCADKA4yGC5jb25mb3Jt",
+ "YW5jZS5Gb3JlaWduRW51bRIhChVyZXBlYXRlZF9zdHJpbmdfcGllY2UYNiAD",
+ "KAlCAggCEhkKDXJlcGVhdGVkX2NvcmQYNyADKAlCAggBEkUKD21hcF9pbnQz",
+ "Ml9pbnQzMhg4IAMoCzIsLmNvbmZvcm1hbmNlLlRlc3RBbGxUeXBlcy5NYXBJ",
+ "bnQzMkludDMyRW50cnkSRQoPbWFwX2ludDY0X2ludDY0GDkgAygLMiwuY29u",
+ "Zm9ybWFuY2UuVGVzdEFsbFR5cGVzLk1hcEludDY0SW50NjRFbnRyeRJJChFt",
+ "YXBfdWludDMyX3VpbnQzMhg6IAMoCzIuLmNvbmZvcm1hbmNlLlRlc3RBbGxU",
+ "eXBlcy5NYXBVaW50MzJVaW50MzJFbnRyeRJJChFtYXBfdWludDY0X3VpbnQ2",
+ "NBg7IAMoCzIuLmNvbmZvcm1hbmNlLlRlc3RBbGxUeXBlcy5NYXBVaW50NjRV",
+ "aW50NjRFbnRyeRJJChFtYXBfc2ludDMyX3NpbnQzMhg8IAMoCzIuLmNvbmZv",
+ "cm1hbmNlLlRlc3RBbGxUeXBlcy5NYXBTaW50MzJTaW50MzJFbnRyeRJJChFt",
+ "YXBfc2ludDY0X3NpbnQ2NBg9IAMoCzIuLmNvbmZvcm1hbmNlLlRlc3RBbGxU",
+ "eXBlcy5NYXBTaW50NjRTaW50NjRFbnRyeRJNChNtYXBfZml4ZWQzMl9maXhl",
+ "ZDMyGD4gAygLMjAuY29uZm9ybWFuY2UuVGVzdEFsbFR5cGVzLk1hcEZpeGVk",
+ "MzJGaXhlZDMyRW50cnkSTQoTbWFwX2ZpeGVkNjRfZml4ZWQ2NBg/IAMoCzIw",
+ "LmNvbmZvcm1hbmNlLlRlc3RBbGxUeXBlcy5NYXBGaXhlZDY0Rml4ZWQ2NEVu",
+ "dHJ5ElEKFW1hcF9zZml4ZWQzMl9zZml4ZWQzMhhAIAMoCzIyLmNvbmZvcm1h",
+ "bmNlLlRlc3RBbGxUeXBlcy5NYXBTZml4ZWQzMlNmaXhlZDMyRW50cnkSUQoV",
+ "bWFwX3NmaXhlZDY0X3NmaXhlZDY0GEEgAygLMjIuY29uZm9ybWFuY2UuVGVz",
+ "dEFsbFR5cGVzLk1hcFNmaXhlZDY0U2ZpeGVkNjRFbnRyeRJFCg9tYXBfaW50",
+ "MzJfZmxvYXQYQiADKAsyLC5jb25mb3JtYW5jZS5UZXN0QWxsVHlwZXMuTWFw",
+ "SW50MzJGbG9hdEVudHJ5EkcKEG1hcF9pbnQzMl9kb3VibGUYQyADKAsyLS5j",
+ "b25mb3JtYW5jZS5UZXN0QWxsVHlwZXMuTWFwSW50MzJEb3VibGVFbnRyeRJB",
+ "Cg1tYXBfYm9vbF9ib29sGEQgAygLMiouY29uZm9ybWFuY2UuVGVzdEFsbFR5",
+ "cGVzLk1hcEJvb2xCb29sRW50cnkSSQoRbWFwX3N0cmluZ19zdHJpbmcYRSAD",
+ "KAsyLi5jb25mb3JtYW5jZS5UZXN0QWxsVHlwZXMuTWFwU3RyaW5nU3RyaW5n",
+ "RW50cnkSRwoQbWFwX3N0cmluZ19ieXRlcxhGIAMoCzItLmNvbmZvcm1hbmNl",
+ "LlRlc3RBbGxUeXBlcy5NYXBTdHJpbmdCeXRlc0VudHJ5ElgKGW1hcF9zdHJp",
+ "bmdfbmVzdGVkX21lc3NhZ2UYRyADKAsyNS5jb25mb3JtYW5jZS5UZXN0QWxs",
+ "VHlwZXMuTWFwU3RyaW5nTmVzdGVkTWVzc2FnZUVudHJ5EloKGm1hcF9zdHJp",
+ "bmdfZm9yZWlnbl9tZXNzYWdlGEggAygLMjYuY29uZm9ybWFuY2UuVGVzdEFs",
+ "bFR5cGVzLk1hcFN0cmluZ0ZvcmVpZ25NZXNzYWdlRW50cnkSUgoWbWFwX3N0",
+ "cmluZ19uZXN0ZWRfZW51bRhJIAMoCzIyLmNvbmZvcm1hbmNlLlRlc3RBbGxU",
+ "eXBlcy5NYXBTdHJpbmdOZXN0ZWRFbnVtRW50cnkSVAoXbWFwX3N0cmluZ19m",
+ "b3JlaWduX2VudW0YSiADKAsyMy5jb25mb3JtYW5jZS5UZXN0QWxsVHlwZXMu",
+ "TWFwU3RyaW5nRm9yZWlnbkVudW1FbnRyeRIWCgxvbmVvZl91aW50MzIYbyAB",
+ "KA1IABJHChRvbmVvZl9uZXN0ZWRfbWVzc2FnZRhwIAEoCzInLmNvbmZvcm1h",
+ "bmNlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlSAASFgoMb25lb2Zfc3Ry",
+ "aW5nGHEgASgJSAASFQoLb25lb2ZfYnl0ZXMYciABKAxIABI6ChVvcHRpb25h",
+ "bF9ib29sX3dyYXBwZXIYyQEgASgLMhouZ29vZ2xlLnByb3RvYnVmLkJvb2xW",
+ "YWx1ZRI8ChZvcHRpb25hbF9pbnQzMl93cmFwcGVyGMoBIAEoCzIbLmdvb2ds",
+ "ZS5wcm90b2J1Zi5JbnQzMlZhbHVlEjwKFm9wdGlvbmFsX2ludDY0X3dyYXBw",
+ "ZXIYywEgASgLMhsuZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUSPgoXb3B0",
+ "aW9uYWxfdWludDMyX3dyYXBwZXIYzAEgASgLMhwuZ29vZ2xlLnByb3RvYnVm",
+ "LlVJbnQzMlZhbHVlEj4KF29wdGlvbmFsX3VpbnQ2NF93cmFwcGVyGM0BIAEo",
+ "CzIcLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZRI8ChZvcHRpb25hbF9m",
+ "bG9hdF93cmFwcGVyGM4BIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZh",
+ "bHVlEj4KF29wdGlvbmFsX2RvdWJsZV93cmFwcGVyGM8BIAEoCzIcLmdvb2ds",
+ "ZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZRI+ChdvcHRpb25hbF9zdHJpbmdfd3Jh",
+ "cHBlchjQASABKAsyHC5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUSPAoW",
+ "b3B0aW9uYWxfYnl0ZXNfd3JhcHBlchjRASABKAsyGy5nb29nbGUucHJvdG9i",
+ "dWYuQnl0ZXNWYWx1ZRI6ChVyZXBlYXRlZF9ib29sX3dyYXBwZXIY0wEgAygL",
+ "MhouZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZRI8ChZyZXBlYXRlZF9pbnQz",
+ "Ml93cmFwcGVyGNQBIAMoCzIbLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVl",
+ "EjwKFnJlcGVhdGVkX2ludDY0X3dyYXBwZXIY1QEgAygLMhsuZ29vZ2xlLnBy",
+ "b3RvYnVmLkludDY0VmFsdWUSPgoXcmVwZWF0ZWRfdWludDMyX3dyYXBwZXIY",
+ "1gEgAygLMhwuZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlEj4KF3JlcGVh",
+ "dGVkX3VpbnQ2NF93cmFwcGVyGNcBIAMoCzIcLmdvb2dsZS5wcm90b2J1Zi5V",
+ "SW50NjRWYWx1ZRI8ChZyZXBlYXRlZF9mbG9hdF93cmFwcGVyGNgBIAMoCzIb",
+ "Lmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlEj4KF3JlcGVhdGVkX2RvdWJs",
+ "ZV93cmFwcGVyGNkBIAMoCzIcLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1",
+ "ZRI+ChdyZXBlYXRlZF9zdHJpbmdfd3JhcHBlchjaASADKAsyHC5nb29nbGUu",
+ "cHJvdG9idWYuU3RyaW5nVmFsdWUSPAoWcmVwZWF0ZWRfYnl0ZXNfd3JhcHBl",
+ "chjbASADKAsyGy5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZRI1ChFvcHRp",
+ "b25hbF9kdXJhdGlvbhitAiABKAsyGS5nb29nbGUucHJvdG9idWYuRHVyYXRp",
+ "b24SNwoSb3B0aW9uYWxfdGltZXN0YW1wGK4CIAEoCzIaLmdvb2dsZS5wcm90",
+ "b2J1Zi5UaW1lc3RhbXASOAoTb3B0aW9uYWxfZmllbGRfbWFzaxivAiABKAsy",
+ "Gi5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrEjEKD29wdGlvbmFsX3N0cnVj",
+ "dBiwAiABKAsyFy5nb29nbGUucHJvdG9idWYuU3RydWN0EisKDG9wdGlvbmFs",
+ "X2FueRixAiABKAsyFC5nb29nbGUucHJvdG9idWYuQW55Ei8KDm9wdGlvbmFs",
+ "X3ZhbHVlGLICIAEoCzIWLmdvb2dsZS5wcm90b2J1Zi5WYWx1ZRI1ChFyZXBl",
+ "YXRlZF9kdXJhdGlvbhi3AiADKAsyGS5nb29nbGUucHJvdG9idWYuRHVyYXRp",
+ "b24SNwoScmVwZWF0ZWRfdGltZXN0YW1wGLgCIAMoCzIaLmdvb2dsZS5wcm90",
+ "b2J1Zi5UaW1lc3RhbXASNwoScmVwZWF0ZWRfZmllbGRtYXNrGLkCIAMoCzIa",
+ "Lmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2sSMQoPcmVwZWF0ZWRfc3RydWN0",
+ "GMQCIAMoCzIXLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QSKwoMcmVwZWF0ZWRf",
+ "YW55GLsCIAMoCzIULmdvb2dsZS5wcm90b2J1Zi5BbnkSLwoOcmVwZWF0ZWRf",
+ "dmFsdWUYvAIgAygLMhYuZ29vZ2xlLnByb3RvYnVmLlZhbHVlEhMKCmZpZWxk",
+ "bmFtZTEYkQMgASgFEhQKC2ZpZWxkX25hbWUyGJIDIAEoBRIVCgxfZmllbGRf",
+ "bmFtZTMYkwMgASgFEhYKDWZpZWxkX19uYW1lNF8YlAMgASgFEhQKC2ZpZWxk",
+ "MG5hbWU1GJUDIAEoBRIWCg1maWVsZF8wX25hbWU2GJYDIAEoBRITCgpmaWVs",
+ "ZE5hbWU3GJcDIAEoBRITCgpGaWVsZE5hbWU4GJgDIAEoBRIUCgtmaWVsZF9O",
+ "YW1lORiZAyABKAUSFQoMRmllbGRfTmFtZTEwGJoDIAEoBRIVCgxGSUVMRF9O",
+ "QU1FMTEYmwMgASgFEhUKDEZJRUxEX25hbWUxMhicAyABKAUaSgoNTmVzdGVk",
+ "TWVzc2FnZRIJCgFhGAEgASgFEi4KC2NvcmVjdXJzaXZlGAIgASgLMhkuY29u",
+ "Zm9ybWFuY2UuVGVzdEFsbFR5cGVzGjQKEk1hcEludDMySW50MzJFbnRyeRIL",
+ "CgNrZXkYASABKAUSDQoFdmFsdWUYAiABKAU6AjgBGjQKEk1hcEludDY0SW50",
+ "NjRFbnRyeRILCgNrZXkYASABKAMSDQoFdmFsdWUYAiABKAM6AjgBGjYKFE1h",
+ "cFVpbnQzMlVpbnQzMkVudHJ5EgsKA2tleRgBIAEoDRINCgV2YWx1ZRgCIAEo",
+ "DToCOAEaNgoUTWFwVWludDY0VWludDY0RW50cnkSCwoDa2V5GAEgASgEEg0K",
+ "BXZhbHVlGAIgASgEOgI4ARo2ChRNYXBTaW50MzJTaW50MzJFbnRyeRILCgNr",
+ "ZXkYASABKBESDQoFdmFsdWUYAiABKBE6AjgBGjYKFE1hcFNpbnQ2NFNpbnQ2",
+ "NEVudHJ5EgsKA2tleRgBIAEoEhINCgV2YWx1ZRgCIAEoEjoCOAEaOAoWTWFw",
+ "Rml4ZWQzMkZpeGVkMzJFbnRyeRILCgNrZXkYASABKAcSDQoFdmFsdWUYAiAB",
+ "KAc6AjgBGjgKFk1hcEZpeGVkNjRGaXhlZDY0RW50cnkSCwoDa2V5GAEgASgG",
+ "Eg0KBXZhbHVlGAIgASgGOgI4ARo6ChhNYXBTZml4ZWQzMlNmaXhlZDMyRW50",
+ "cnkSCwoDa2V5GAEgASgPEg0KBXZhbHVlGAIgASgPOgI4ARo6ChhNYXBTZml4",
+ "ZWQ2NFNmaXhlZDY0RW50cnkSCwoDa2V5GAEgASgQEg0KBXZhbHVlGAIgASgQ",
+ "OgI4ARo0ChJNYXBJbnQzMkZsb2F0RW50cnkSCwoDa2V5GAEgASgFEg0KBXZh",
+ "bHVlGAIgASgCOgI4ARo1ChNNYXBJbnQzMkRvdWJsZUVudHJ5EgsKA2tleRgB",
+ "IAEoBRINCgV2YWx1ZRgCIAEoAToCOAEaMgoQTWFwQm9vbEJvb2xFbnRyeRIL",
+ "CgNrZXkYASABKAgSDQoFdmFsdWUYAiABKAg6AjgBGjYKFE1hcFN0cmluZ1N0",
+ "cmluZ0VudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoCToCOAEaNQoT",
+ "TWFwU3RyaW5nQnl0ZXNFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiAB",
+ "KAw6AjgBGmYKG01hcFN0cmluZ05lc3RlZE1lc3NhZ2VFbnRyeRILCgNrZXkY",
+ "ASABKAkSNgoFdmFsdWUYAiABKAsyJy5jb25mb3JtYW5jZS5UZXN0QWxsVHlw",
+ "ZXMuTmVzdGVkTWVzc2FnZToCOAEaWwocTWFwU3RyaW5nRm9yZWlnbk1lc3Nh",
+ "Z2VFbnRyeRILCgNrZXkYASABKAkSKgoFdmFsdWUYAiABKAsyGy5jb25mb3Jt",
+ "YW5jZS5Gb3JlaWduTWVzc2FnZToCOAEaYAoYTWFwU3RyaW5nTmVzdGVkRW51",
+ "bUVudHJ5EgsKA2tleRgBIAEoCRIzCgV2YWx1ZRgCIAEoDjIkLmNvbmZvcm1h",
+ "bmNlLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtOgI4ARpVChlNYXBTdHJpbmdG",
+ "b3JlaWduRW51bUVudHJ5EgsKA2tleRgBIAEoCRInCgV2YWx1ZRgCIAEoDjIY",
+ "LmNvbmZvcm1hbmNlLkZvcmVpZ25FbnVtOgI4ASI5CgpOZXN0ZWRFbnVtEgcK",
+ "A0ZPTxAAEgcKA0JBUhABEgcKA0JBWhACEhAKA05FRxD///////////8BQg0K",
+ "C29uZW9mX2ZpZWxkIhsKDkZvcmVpZ25NZXNzYWdlEgkKAWMYASABKAUqNQoK",
+ "V2lyZUZvcm1hdBIPCgtVTlNQRUNJRklFRBAAEgwKCFBST1RPQlVGEAESCAoE",
+ "SlNPThACKkAKC0ZvcmVpZ25FbnVtEg8KC0ZPUkVJR05fRk9PEAASDwoLRk9S",
+ "RUlHTl9CQVIQARIPCgtGT1JFSUdOX0JBWhACQiEKH2NvbS5nb29nbGUucHJv",
+ "dG9idWYuY29uZm9ybWFuY2ViBnByb3RvMw=="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
- new pbr::FileDescriptor[] { },
- new pbr::GeneratedCodeInfo(new[] {typeof(global::Conformance.WireFormat), typeof(global::Conformance.ForeignEnum), }, new pbr::GeneratedCodeInfo[] {
- new pbr::GeneratedCodeInfo(typeof(global::Conformance.ConformanceRequest), global::Conformance.ConformanceRequest.Parser, new[]{ "ProtobufPayload", "JsonPayload", "RequestedOutputFormat" }, new[]{ "Payload" }, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Conformance.ConformanceResponse), global::Conformance.ConformanceResponse.Parser, new[]{ "ParseError", "RuntimeError", "ProtobufPayload", "JsonPayload", "Skipped" }, new[]{ "Result" }, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Conformance.TestAllTypes), global::Conformance.TestAllTypes.Parser, new[]{ "OptionalInt32", "OptionalInt64", "OptionalUint32", "OptionalUint64", "OptionalSint32", "OptionalSint64", "OptionalFixed32", "OptionalFixed64", "OptionalSfixed32", "OptionalSfixed64", "OptionalFloat", "OptionalDouble", "OptionalBool", "OptionalString", "OptionalBytes", "OptionalNestedMessage", "OptionalForeignMessage", "OptionalNestedEnum", "OptionalForeignEnum", "OptionalStringPiece", "OptionalCord", "RecursiveMessage", "RepeatedInt32", "RepeatedInt64", "RepeatedUint32", "RepeatedUint64", "RepeatedSint32", "RepeatedSint64", "RepeatedFixed32", "RepeatedFixed64", "RepeatedSfixed32", "RepeatedSfixed64", "RepeatedFloat", "RepeatedDouble", "RepeatedBool", "RepeatedString", "RepeatedBytes", "RepeatedNestedMessage", "RepeatedForeignMessage", "RepeatedNestedEnum", "RepeatedForeignEnum", "RepeatedStringPiece", "RepeatedCord", "MapInt32Int32", "MapInt64Int64", "MapUint32Uint32", "MapUint64Uint64", "MapSint32Sint32", "MapSint64Sint64", "MapFixed32Fixed32", "MapFixed64Fixed64", "MapSfixed32Sfixed32", "MapSfixed64Sfixed64", "MapInt32Float", "MapInt32Double", "MapBoolBool", "MapStringString", "MapStringBytes", "MapStringNestedMessage", "MapStringForeignMessage", "MapStringNestedEnum", "MapStringForeignEnum", "OneofUint32", "OneofNestedMessage", "OneofString", "OneofBytes" }, new[]{ "OneofField" }, new[]{ typeof(global::Conformance.TestAllTypes.Types.NestedEnum) }, new pbr::GeneratedCodeInfo[] { new pbr::GeneratedCodeInfo(typeof(global::Conformance.TestAllTypes.Types.NestedMessage), global::Conformance.TestAllTypes.Types.NestedMessage.Parser, new[]{ "A", "Corecursive" }, null, null, null),
+ new pbr::FileDescriptor[] { global::Google.Protobuf.WellKnownTypes.AnyReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.DurationReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.FieldMaskReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.StructReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.TimestampReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.WrappersReflection.Descriptor, },
+ new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Conformance.WireFormat), typeof(global::Conformance.ForeignEnum), }, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Conformance.ConformanceRequest), global::Conformance.ConformanceRequest.Parser, new[]{ "ProtobufPayload", "JsonPayload", "RequestedOutputFormat" }, new[]{ "Payload" }, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Conformance.ConformanceResponse), global::Conformance.ConformanceResponse.Parser, new[]{ "ParseError", "SerializeError", "RuntimeError", "ProtobufPayload", "JsonPayload", "Skipped" }, new[]{ "Result" }, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Conformance.TestAllTypes), global::Conformance.TestAllTypes.Parser, new[]{ "OptionalInt32", "OptionalInt64", "OptionalUint32", "OptionalUint64", "OptionalSint32", "OptionalSint64", "OptionalFixed32", "OptionalFixed64", "OptionalSfixed32", "OptionalSfixed64", "OptionalFloat", "OptionalDouble", "OptionalBool", "OptionalString", "OptionalBytes", "OptionalNestedMessage", "OptionalForeignMessage", "OptionalNestedEnum", "OptionalForeignEnum", "OptionalStringPiece", "OptionalCord", "RecursiveMessage", "RepeatedInt32", "RepeatedInt64", "RepeatedUint32", "RepeatedUint64", "RepeatedSint32", "RepeatedSint64", "RepeatedFixed32", "RepeatedFixed64", "RepeatedSfixed32", "RepeatedSfixed64", "RepeatedFloat", "RepeatedDouble", "RepeatedBool", "RepeatedString", "RepeatedBytes", "RepeatedNestedMessage", "RepeatedForeignMessage", "RepeatedNestedEnum", "RepeatedForeignEnum", "RepeatedStringPiece", "RepeatedCord", "MapInt32Int32", "MapInt64Int64", "MapUint32Uint32", "MapUint64Uint64", "MapSint32Sint32", "MapSint64Sint64", "MapFixed32Fixed32", "MapFixed64Fixed64", "MapSfixed32Sfixed32", "MapSfixed64Sfixed64", "MapInt32Float", "MapInt32Double", "MapBoolBool", "MapStringString", "MapStringBytes", "MapStringNestedMessage", "MapStringForeignMessage", "MapStringNestedEnum", "MapStringForeignEnum", "OneofUint32", "OneofNestedMessage", "OneofString", "OneofBytes", "OptionalBoolWrapper", "OptionalInt32Wrapper", "OptionalInt64Wrapper", "OptionalUint32Wrapper", "OptionalUint64Wrapper", "OptionalFloatWrapper", "OptionalDoubleWrapper", "OptionalStringWrapper", "OptionalBytesWrapper", "RepeatedBoolWrapper", "RepeatedInt32Wrapper", "RepeatedInt64Wrapper", "RepeatedUint32Wrapper", "RepeatedUint64Wrapper", "RepeatedFloatWrapper", "RepeatedDoubleWrapper", "RepeatedStringWrapper", "RepeatedBytesWrapper", "OptionalDuration", "OptionalTimestamp", "OptionalFieldMask", "OptionalStruct", "OptionalAny", "OptionalValue", "RepeatedDuration", "RepeatedTimestamp", "RepeatedFieldmask", "RepeatedStruct", "RepeatedAny", "RepeatedValue", "Fieldname1", "FieldName2", "FieldName3", "FieldName4", "Field0Name5", "Field0Name6", "FieldName7", "FieldName8", "FieldName9", "FieldName10", "FIELDNAME11", "FIELDName12" }, new[]{ "OneofField" }, new[]{ typeof(global::Conformance.TestAllTypes.Types.NestedEnum) }, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Conformance.TestAllTypes.Types.NestedMessage), global::Conformance.TestAllTypes.Types.NestedMessage.Parser, new[]{ "A", "Corecursive" }, null, null, null),
null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, }),
- new pbr::GeneratedCodeInfo(typeof(global::Conformance.ForeignMessage), global::Conformance.ForeignMessage.Parser, new[]{ "C" }, null, null, null)
+ new pbr::GeneratedClrTypeInfo(typeof(global::Conformance.ForeignMessage), global::Conformance.ForeignMessage.Parser, new[]{ "C" }, null, null, null)
}));
}
#endregion
@@ -149,15 +198,15 @@ namespace Conformance {
}
#region Enums
public enum WireFormat {
- UNSPECIFIED = 0,
- PROTOBUF = 1,
- JSON = 2,
+ [pbr::OriginalName("UNSPECIFIED")] Unspecified = 0,
+ [pbr::OriginalName("PROTOBUF")] Protobuf = 1,
+ [pbr::OriginalName("JSON")] Json = 2,
}
public enum ForeignEnum {
- FOREIGN_FOO = 0,
- FOREIGN_BAR = 1,
- FOREIGN_BAZ = 2,
+ [pbr::OriginalName("FOREIGN_FOO")] ForeignFoo = 0,
+ [pbr::OriginalName("FOREIGN_BAR")] ForeignBar = 1,
+ [pbr::OriginalName("FOREIGN_BAZ")] ForeignBaz = 2,
}
#endregion
@@ -170,25 +219,29 @@ namespace Conformance {
/// 2. parse the protobuf or JSON payload in "payload" (which may fail)
/// 3. if the parse succeeded, serialize the message in the requested format.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class ConformanceRequest : pb::IMessage<ConformanceRequest> {
private static readonly pb::MessageParser<ConformanceRequest> _parser = new pb::MessageParser<ConformanceRequest>(() => new ConformanceRequest());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<ConformanceRequest> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Conformance.ConformanceReflection.Descriptor.MessageTypes[0]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ConformanceRequest() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ConformanceRequest(ConformanceRequest other) : this() {
requestedOutputFormat_ = other.requestedOutputFormat_;
switch (other.PayloadCase) {
@@ -202,36 +255,40 @@ namespace Conformance {
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ConformanceRequest Clone() {
return new ConformanceRequest(this);
}
/// <summary>Field number for the "protobuf_payload" field.</summary>
public const int ProtobufPayloadFieldNumber = 1;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pb::ByteString ProtobufPayload {
get { return payloadCase_ == PayloadOneofCase.ProtobufPayload ? (pb::ByteString) payload_ : pb::ByteString.Empty; }
set {
- payload_ = pb::Preconditions.CheckNotNull(value, "value");
+ payload_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
payloadCase_ = PayloadOneofCase.ProtobufPayload;
}
}
/// <summary>Field number for the "json_payload" field.</summary>
public const int JsonPayloadFieldNumber = 2;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string JsonPayload {
get { return payloadCase_ == PayloadOneofCase.JsonPayload ? (string) payload_ : ""; }
set {
- payload_ = pb::Preconditions.CheckNotNull(value, "value");
+ payload_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
payloadCase_ = PayloadOneofCase.JsonPayload;
}
}
/// <summary>Field number for the "requested_output_format" field.</summary>
public const int RequestedOutputFormatFieldNumber = 3;
- private global::Conformance.WireFormat requestedOutputFormat_ = global::Conformance.WireFormat.UNSPECIFIED;
+ private global::Conformance.WireFormat requestedOutputFormat_ = 0;
/// <summary>
/// Which format should the testee serialize its message to?
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Conformance.WireFormat RequestedOutputFormat {
get { return requestedOutputFormat_; }
set {
@@ -247,19 +304,23 @@ namespace Conformance {
JsonPayload = 2,
}
private PayloadOneofCase payloadCase_ = PayloadOneofCase.None;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public PayloadOneofCase PayloadCase {
get { return payloadCase_; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void ClearPayload() {
payloadCase_ = PayloadOneofCase.None;
payload_ = null;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as ConformanceRequest);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(ConformanceRequest other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -274,19 +335,22 @@ namespace Conformance {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (payloadCase_ == PayloadOneofCase.ProtobufPayload) hash ^= ProtobufPayload.GetHashCode();
if (payloadCase_ == PayloadOneofCase.JsonPayload) hash ^= JsonPayload.GetHashCode();
- if (RequestedOutputFormat != global::Conformance.WireFormat.UNSPECIFIED) hash ^= RequestedOutputFormat.GetHashCode();
+ if (RequestedOutputFormat != 0) hash ^= RequestedOutputFormat.GetHashCode();
hash ^= (int) payloadCase_;
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (payloadCase_ == PayloadOneofCase.ProtobufPayload) {
output.WriteRawTag(10);
@@ -296,12 +360,13 @@ namespace Conformance {
output.WriteRawTag(18);
output.WriteString(JsonPayload);
}
- if (RequestedOutputFormat != global::Conformance.WireFormat.UNSPECIFIED) {
+ if (RequestedOutputFormat != 0) {
output.WriteRawTag(24);
output.WriteEnum((int) RequestedOutputFormat);
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (payloadCase_ == PayloadOneofCase.ProtobufPayload) {
@@ -310,17 +375,18 @@ namespace Conformance {
if (payloadCase_ == PayloadOneofCase.JsonPayload) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(JsonPayload);
}
- if (RequestedOutputFormat != global::Conformance.WireFormat.UNSPECIFIED) {
+ if (RequestedOutputFormat != 0) {
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) RequestedOutputFormat);
}
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(ConformanceRequest other) {
if (other == null) {
return;
}
- if (other.RequestedOutputFormat != global::Conformance.WireFormat.UNSPECIFIED) {
+ if (other.RequestedOutputFormat != 0) {
RequestedOutputFormat = other.RequestedOutputFormat;
}
switch (other.PayloadCase) {
@@ -334,6 +400,7 @@ namespace Conformance {
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -362,30 +429,37 @@ namespace Conformance {
/// <summary>
/// Represents a single test case's output.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class ConformanceResponse : pb::IMessage<ConformanceResponse> {
private static readonly pb::MessageParser<ConformanceResponse> _parser = new pb::MessageParser<ConformanceResponse>(() => new ConformanceResponse());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<ConformanceResponse> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Conformance.ConformanceReflection.Descriptor.MessageTypes[1]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ConformanceResponse() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ConformanceResponse(ConformanceResponse other) : this() {
switch (other.ResultCase) {
case ResultOneofCase.ParseError:
ParseError = other.ParseError;
break;
+ case ResultOneofCase.SerializeError:
+ SerializeError = other.SerializeError;
+ break;
case ResultOneofCase.RuntimeError:
RuntimeError = other.RuntimeError;
break;
@@ -402,6 +476,7 @@ namespace Conformance {
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ConformanceResponse Clone() {
return new ConformanceResponse(this);
}
@@ -415,14 +490,31 @@ namespace Conformance {
/// Setting this string does not necessarily mean the testee failed the
/// test. Some of the test cases are intentionally invalid input.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string ParseError {
get { return resultCase_ == ResultOneofCase.ParseError ? (string) result_ : ""; }
set {
- result_ = pb::Preconditions.CheckNotNull(value, "value");
+ result_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
resultCase_ = ResultOneofCase.ParseError;
}
}
+ /// <summary>Field number for the "serialize_error" field.</summary>
+ public const int SerializeErrorFieldNumber = 6;
+ /// <summary>
+ /// If the input was successfully parsed but errors occurred when
+ /// serializing it to the requested output format, set the error message in
+ /// this field.
+ /// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public string SerializeError {
+ get { return resultCase_ == ResultOneofCase.SerializeError ? (string) result_ : ""; }
+ set {
+ result_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ resultCase_ = ResultOneofCase.SerializeError;
+ }
+ }
+
/// <summary>Field number for the "runtime_error" field.</summary>
public const int RuntimeErrorFieldNumber = 2;
/// <summary>
@@ -430,10 +522,11 @@ namespace Conformance {
/// indicate that the test failed. The string can provide more information
/// about the failure.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string RuntimeError {
get { return resultCase_ == ResultOneofCase.RuntimeError ? (string) result_ : ""; }
set {
- result_ = pb::Preconditions.CheckNotNull(value, "value");
+ result_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
resultCase_ = ResultOneofCase.RuntimeError;
}
}
@@ -444,10 +537,11 @@ namespace Conformance {
/// If the input was successfully parsed and the requested output was
/// protobuf, serialize it to protobuf and set it in this field.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pb::ByteString ProtobufPayload {
get { return resultCase_ == ResultOneofCase.ProtobufPayload ? (pb::ByteString) result_ : pb::ByteString.Empty; }
set {
- result_ = pb::Preconditions.CheckNotNull(value, "value");
+ result_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
resultCase_ = ResultOneofCase.ProtobufPayload;
}
}
@@ -458,10 +552,11 @@ namespace Conformance {
/// If the input was successfully parsed and the requested output was JSON,
/// serialize to JSON and set it in this field.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string JsonPayload {
get { return resultCase_ == ResultOneofCase.JsonPayload ? (string) result_ : ""; }
set {
- result_ = pb::Preconditions.CheckNotNull(value, "value");
+ result_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
resultCase_ = ResultOneofCase.JsonPayload;
}
}
@@ -472,10 +567,11 @@ namespace Conformance {
/// For when the testee skipped the test, likely because a certain feature
/// wasn't supported, like JSON input/output.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string Skipped {
get { return resultCase_ == ResultOneofCase.Skipped ? (string) result_ : ""; }
set {
- result_ = pb::Preconditions.CheckNotNull(value, "value");
+ result_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
resultCase_ = ResultOneofCase.Skipped;
}
}
@@ -485,25 +581,30 @@ namespace Conformance {
public enum ResultOneofCase {
None = 0,
ParseError = 1,
+ SerializeError = 6,
RuntimeError = 2,
ProtobufPayload = 3,
JsonPayload = 4,
Skipped = 5,
}
private ResultOneofCase resultCase_ = ResultOneofCase.None;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ResultOneofCase ResultCase {
get { return resultCase_; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void ClearResult() {
resultCase_ = ResultOneofCase.None;
result_ = null;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as ConformanceResponse);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(ConformanceResponse other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -512,6 +613,7 @@ namespace Conformance {
return true;
}
if (ParseError != other.ParseError) return false;
+ if (SerializeError != other.SerializeError) return false;
if (RuntimeError != other.RuntimeError) return false;
if (ProtobufPayload != other.ProtobufPayload) return false;
if (JsonPayload != other.JsonPayload) return false;
@@ -520,9 +622,11 @@ namespace Conformance {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (resultCase_ == ResultOneofCase.ParseError) hash ^= ParseError.GetHashCode();
+ if (resultCase_ == ResultOneofCase.SerializeError) hash ^= SerializeError.GetHashCode();
if (resultCase_ == ResultOneofCase.RuntimeError) hash ^= RuntimeError.GetHashCode();
if (resultCase_ == ResultOneofCase.ProtobufPayload) hash ^= ProtobufPayload.GetHashCode();
if (resultCase_ == ResultOneofCase.JsonPayload) hash ^= JsonPayload.GetHashCode();
@@ -531,10 +635,12 @@ namespace Conformance {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (resultCase_ == ResultOneofCase.ParseError) {
output.WriteRawTag(10);
@@ -556,13 +662,21 @@ namespace Conformance {
output.WriteRawTag(42);
output.WriteString(Skipped);
}
+ if (resultCase_ == ResultOneofCase.SerializeError) {
+ output.WriteRawTag(50);
+ output.WriteString(SerializeError);
+ }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (resultCase_ == ResultOneofCase.ParseError) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(ParseError);
}
+ if (resultCase_ == ResultOneofCase.SerializeError) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(SerializeError);
+ }
if (resultCase_ == ResultOneofCase.RuntimeError) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(RuntimeError);
}
@@ -578,6 +692,7 @@ namespace Conformance {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(ConformanceResponse other) {
if (other == null) {
return;
@@ -586,6 +701,9 @@ namespace Conformance {
case ResultOneofCase.ParseError:
ParseError = other.ParseError;
break;
+ case ResultOneofCase.SerializeError:
+ SerializeError = other.SerializeError;
+ break;
case ResultOneofCase.RuntimeError:
RuntimeError = other.RuntimeError;
break;
@@ -602,6 +720,7 @@ namespace Conformance {
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -629,6 +748,10 @@ namespace Conformance {
Skipped = input.ReadString();
break;
}
+ case 50: {
+ SerializeError = input.ReadString();
+ break;
+ }
}
}
}
@@ -639,25 +762,29 @@ namespace Conformance {
/// This proto includes every type of field in both singular and repeated
/// forms.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class TestAllTypes : pb::IMessage<TestAllTypes> {
private static readonly pb::MessageParser<TestAllTypes> _parser = new pb::MessageParser<TestAllTypes>(() => new TestAllTypes());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<TestAllTypes> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Conformance.ConformanceReflection.Descriptor.MessageTypes[2]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestAllTypes() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestAllTypes(TestAllTypes other) : this() {
optionalInt32_ = other.optionalInt32_;
optionalInt64_ = other.optionalInt64_;
@@ -721,6 +848,48 @@ namespace Conformance {
mapStringForeignMessage_ = other.mapStringForeignMessage_.Clone();
mapStringNestedEnum_ = other.mapStringNestedEnum_.Clone();
mapStringForeignEnum_ = other.mapStringForeignEnum_.Clone();
+ OptionalBoolWrapper = other.OptionalBoolWrapper;
+ OptionalInt32Wrapper = other.OptionalInt32Wrapper;
+ OptionalInt64Wrapper = other.OptionalInt64Wrapper;
+ OptionalUint32Wrapper = other.OptionalUint32Wrapper;
+ OptionalUint64Wrapper = other.OptionalUint64Wrapper;
+ OptionalFloatWrapper = other.OptionalFloatWrapper;
+ OptionalDoubleWrapper = other.OptionalDoubleWrapper;
+ OptionalStringWrapper = other.OptionalStringWrapper;
+ OptionalBytesWrapper = other.OptionalBytesWrapper;
+ repeatedBoolWrapper_ = other.repeatedBoolWrapper_.Clone();
+ repeatedInt32Wrapper_ = other.repeatedInt32Wrapper_.Clone();
+ repeatedInt64Wrapper_ = other.repeatedInt64Wrapper_.Clone();
+ repeatedUint32Wrapper_ = other.repeatedUint32Wrapper_.Clone();
+ repeatedUint64Wrapper_ = other.repeatedUint64Wrapper_.Clone();
+ repeatedFloatWrapper_ = other.repeatedFloatWrapper_.Clone();
+ repeatedDoubleWrapper_ = other.repeatedDoubleWrapper_.Clone();
+ repeatedStringWrapper_ = other.repeatedStringWrapper_.Clone();
+ repeatedBytesWrapper_ = other.repeatedBytesWrapper_.Clone();
+ OptionalDuration = other.optionalDuration_ != null ? other.OptionalDuration.Clone() : null;
+ OptionalTimestamp = other.optionalTimestamp_ != null ? other.OptionalTimestamp.Clone() : null;
+ OptionalFieldMask = other.optionalFieldMask_ != null ? other.OptionalFieldMask.Clone() : null;
+ OptionalStruct = other.optionalStruct_ != null ? other.OptionalStruct.Clone() : null;
+ OptionalAny = other.optionalAny_ != null ? other.OptionalAny.Clone() : null;
+ OptionalValue = other.optionalValue_ != null ? other.OptionalValue.Clone() : null;
+ repeatedDuration_ = other.repeatedDuration_.Clone();
+ repeatedTimestamp_ = other.repeatedTimestamp_.Clone();
+ repeatedFieldmask_ = other.repeatedFieldmask_.Clone();
+ repeatedStruct_ = other.repeatedStruct_.Clone();
+ repeatedAny_ = other.repeatedAny_.Clone();
+ repeatedValue_ = other.repeatedValue_.Clone();
+ fieldname1_ = other.fieldname1_;
+ fieldName2_ = other.fieldName2_;
+ FieldName3_ = other.FieldName3_;
+ fieldName4_ = other.fieldName4_;
+ field0Name5_ = other.field0Name5_;
+ field0Name6_ = other.field0Name6_;
+ fieldName7_ = other.fieldName7_;
+ fieldName8_ = other.fieldName8_;
+ fieldName9_ = other.fieldName9_;
+ fieldName10_ = other.fieldName10_;
+ fIELDNAME11_ = other.fIELDNAME11_;
+ fIELDName12_ = other.fIELDName12_;
switch (other.OneofFieldCase) {
case OneofFieldOneofCase.OneofUint32:
OneofUint32 = other.OneofUint32;
@@ -738,6 +907,7 @@ namespace Conformance {
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestAllTypes Clone() {
return new TestAllTypes(this);
}
@@ -748,6 +918,7 @@ namespace Conformance {
/// <summary>
/// Singular
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int OptionalInt32 {
get { return optionalInt32_; }
set {
@@ -758,6 +929,7 @@ namespace Conformance {
/// <summary>Field number for the "optional_int64" field.</summary>
public const int OptionalInt64FieldNumber = 2;
private long optionalInt64_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public long OptionalInt64 {
get { return optionalInt64_; }
set {
@@ -768,6 +940,7 @@ namespace Conformance {
/// <summary>Field number for the "optional_uint32" field.</summary>
public const int OptionalUint32FieldNumber = 3;
private uint optionalUint32_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public uint OptionalUint32 {
get { return optionalUint32_; }
set {
@@ -778,6 +951,7 @@ namespace Conformance {
/// <summary>Field number for the "optional_uint64" field.</summary>
public const int OptionalUint64FieldNumber = 4;
private ulong optionalUint64_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ulong OptionalUint64 {
get { return optionalUint64_; }
set {
@@ -788,6 +962,7 @@ namespace Conformance {
/// <summary>Field number for the "optional_sint32" field.</summary>
public const int OptionalSint32FieldNumber = 5;
private int optionalSint32_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int OptionalSint32 {
get { return optionalSint32_; }
set {
@@ -798,6 +973,7 @@ namespace Conformance {
/// <summary>Field number for the "optional_sint64" field.</summary>
public const int OptionalSint64FieldNumber = 6;
private long optionalSint64_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public long OptionalSint64 {
get { return optionalSint64_; }
set {
@@ -808,6 +984,7 @@ namespace Conformance {
/// <summary>Field number for the "optional_fixed32" field.</summary>
public const int OptionalFixed32FieldNumber = 7;
private uint optionalFixed32_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public uint OptionalFixed32 {
get { return optionalFixed32_; }
set {
@@ -818,6 +995,7 @@ namespace Conformance {
/// <summary>Field number for the "optional_fixed64" field.</summary>
public const int OptionalFixed64FieldNumber = 8;
private ulong optionalFixed64_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ulong OptionalFixed64 {
get { return optionalFixed64_; }
set {
@@ -828,6 +1006,7 @@ namespace Conformance {
/// <summary>Field number for the "optional_sfixed32" field.</summary>
public const int OptionalSfixed32FieldNumber = 9;
private int optionalSfixed32_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int OptionalSfixed32 {
get { return optionalSfixed32_; }
set {
@@ -838,6 +1017,7 @@ namespace Conformance {
/// <summary>Field number for the "optional_sfixed64" field.</summary>
public const int OptionalSfixed64FieldNumber = 10;
private long optionalSfixed64_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public long OptionalSfixed64 {
get { return optionalSfixed64_; }
set {
@@ -848,6 +1028,7 @@ namespace Conformance {
/// <summary>Field number for the "optional_float" field.</summary>
public const int OptionalFloatFieldNumber = 11;
private float optionalFloat_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public float OptionalFloat {
get { return optionalFloat_; }
set {
@@ -858,6 +1039,7 @@ namespace Conformance {
/// <summary>Field number for the "optional_double" field.</summary>
public const int OptionalDoubleFieldNumber = 12;
private double optionalDouble_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public double OptionalDouble {
get { return optionalDouble_; }
set {
@@ -868,6 +1050,7 @@ namespace Conformance {
/// <summary>Field number for the "optional_bool" field.</summary>
public const int OptionalBoolFieldNumber = 13;
private bool optionalBool_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool OptionalBool {
get { return optionalBool_; }
set {
@@ -878,26 +1061,29 @@ namespace Conformance {
/// <summary>Field number for the "optional_string" field.</summary>
public const int OptionalStringFieldNumber = 14;
private string optionalString_ = "";
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string OptionalString {
get { return optionalString_; }
set {
- optionalString_ = pb::Preconditions.CheckNotNull(value, "value");
+ optionalString_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
/// <summary>Field number for the "optional_bytes" field.</summary>
public const int OptionalBytesFieldNumber = 15;
private pb::ByteString optionalBytes_ = pb::ByteString.Empty;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pb::ByteString OptionalBytes {
get { return optionalBytes_; }
set {
- optionalBytes_ = pb::Preconditions.CheckNotNull(value, "value");
+ optionalBytes_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
/// <summary>Field number for the "optional_nested_message" field.</summary>
public const int OptionalNestedMessageFieldNumber = 18;
private global::Conformance.TestAllTypes.Types.NestedMessage optionalNestedMessage_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Conformance.TestAllTypes.Types.NestedMessage OptionalNestedMessage {
get { return optionalNestedMessage_; }
set {
@@ -908,6 +1094,7 @@ namespace Conformance {
/// <summary>Field number for the "optional_foreign_message" field.</summary>
public const int OptionalForeignMessageFieldNumber = 19;
private global::Conformance.ForeignMessage optionalForeignMessage_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Conformance.ForeignMessage OptionalForeignMessage {
get { return optionalForeignMessage_; }
set {
@@ -917,7 +1104,8 @@ namespace Conformance {
/// <summary>Field number for the "optional_nested_enum" field.</summary>
public const int OptionalNestedEnumFieldNumber = 21;
- private global::Conformance.TestAllTypes.Types.NestedEnum optionalNestedEnum_ = global::Conformance.TestAllTypes.Types.NestedEnum.FOO;
+ private global::Conformance.TestAllTypes.Types.NestedEnum optionalNestedEnum_ = 0;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Conformance.TestAllTypes.Types.NestedEnum OptionalNestedEnum {
get { return optionalNestedEnum_; }
set {
@@ -927,7 +1115,8 @@ namespace Conformance {
/// <summary>Field number for the "optional_foreign_enum" field.</summary>
public const int OptionalForeignEnumFieldNumber = 22;
- private global::Conformance.ForeignEnum optionalForeignEnum_ = global::Conformance.ForeignEnum.FOREIGN_FOO;
+ private global::Conformance.ForeignEnum optionalForeignEnum_ = 0;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Conformance.ForeignEnum OptionalForeignEnum {
get { return optionalForeignEnum_; }
set {
@@ -938,26 +1127,29 @@ namespace Conformance {
/// <summary>Field number for the "optional_string_piece" field.</summary>
public const int OptionalStringPieceFieldNumber = 24;
private string optionalStringPiece_ = "";
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string OptionalStringPiece {
get { return optionalStringPiece_; }
set {
- optionalStringPiece_ = pb::Preconditions.CheckNotNull(value, "value");
+ optionalStringPiece_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
/// <summary>Field number for the "optional_cord" field.</summary>
public const int OptionalCordFieldNumber = 25;
private string optionalCord_ = "";
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string OptionalCord {
get { return optionalCord_; }
set {
- optionalCord_ = pb::Preconditions.CheckNotNull(value, "value");
+ optionalCord_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
/// <summary>Field number for the "recursive_message" field.</summary>
public const int RecursiveMessageFieldNumber = 27;
private global::Conformance.TestAllTypes recursiveMessage_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Conformance.TestAllTypes RecursiveMessage {
get { return recursiveMessage_; }
set {
@@ -973,6 +1165,7 @@ namespace Conformance {
/// <summary>
/// Repeated
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<int> RepeatedInt32 {
get { return repeatedInt32_; }
}
@@ -982,6 +1175,7 @@ namespace Conformance {
private static readonly pb::FieldCodec<long> _repeated_repeatedInt64_codec
= pb::FieldCodec.ForInt64(258);
private readonly pbc::RepeatedField<long> repeatedInt64_ = new pbc::RepeatedField<long>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<long> RepeatedInt64 {
get { return repeatedInt64_; }
}
@@ -991,6 +1185,7 @@ namespace Conformance {
private static readonly pb::FieldCodec<uint> _repeated_repeatedUint32_codec
= pb::FieldCodec.ForUInt32(266);
private readonly pbc::RepeatedField<uint> repeatedUint32_ = new pbc::RepeatedField<uint>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<uint> RepeatedUint32 {
get { return repeatedUint32_; }
}
@@ -1000,6 +1195,7 @@ namespace Conformance {
private static readonly pb::FieldCodec<ulong> _repeated_repeatedUint64_codec
= pb::FieldCodec.ForUInt64(274);
private readonly pbc::RepeatedField<ulong> repeatedUint64_ = new pbc::RepeatedField<ulong>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<ulong> RepeatedUint64 {
get { return repeatedUint64_; }
}
@@ -1009,6 +1205,7 @@ namespace Conformance {
private static readonly pb::FieldCodec<int> _repeated_repeatedSint32_codec
= pb::FieldCodec.ForSInt32(282);
private readonly pbc::RepeatedField<int> repeatedSint32_ = new pbc::RepeatedField<int>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<int> RepeatedSint32 {
get { return repeatedSint32_; }
}
@@ -1018,6 +1215,7 @@ namespace Conformance {
private static readonly pb::FieldCodec<long> _repeated_repeatedSint64_codec
= pb::FieldCodec.ForSInt64(290);
private readonly pbc::RepeatedField<long> repeatedSint64_ = new pbc::RepeatedField<long>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<long> RepeatedSint64 {
get { return repeatedSint64_; }
}
@@ -1027,6 +1225,7 @@ namespace Conformance {
private static readonly pb::FieldCodec<uint> _repeated_repeatedFixed32_codec
= pb::FieldCodec.ForFixed32(298);
private readonly pbc::RepeatedField<uint> repeatedFixed32_ = new pbc::RepeatedField<uint>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<uint> RepeatedFixed32 {
get { return repeatedFixed32_; }
}
@@ -1036,6 +1235,7 @@ namespace Conformance {
private static readonly pb::FieldCodec<ulong> _repeated_repeatedFixed64_codec
= pb::FieldCodec.ForFixed64(306);
private readonly pbc::RepeatedField<ulong> repeatedFixed64_ = new pbc::RepeatedField<ulong>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<ulong> RepeatedFixed64 {
get { return repeatedFixed64_; }
}
@@ -1045,6 +1245,7 @@ namespace Conformance {
private static readonly pb::FieldCodec<int> _repeated_repeatedSfixed32_codec
= pb::FieldCodec.ForSFixed32(314);
private readonly pbc::RepeatedField<int> repeatedSfixed32_ = new pbc::RepeatedField<int>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<int> RepeatedSfixed32 {
get { return repeatedSfixed32_; }
}
@@ -1054,6 +1255,7 @@ namespace Conformance {
private static readonly pb::FieldCodec<long> _repeated_repeatedSfixed64_codec
= pb::FieldCodec.ForSFixed64(322);
private readonly pbc::RepeatedField<long> repeatedSfixed64_ = new pbc::RepeatedField<long>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<long> RepeatedSfixed64 {
get { return repeatedSfixed64_; }
}
@@ -1063,6 +1265,7 @@ namespace Conformance {
private static readonly pb::FieldCodec<float> _repeated_repeatedFloat_codec
= pb::FieldCodec.ForFloat(330);
private readonly pbc::RepeatedField<float> repeatedFloat_ = new pbc::RepeatedField<float>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<float> RepeatedFloat {
get { return repeatedFloat_; }
}
@@ -1072,6 +1275,7 @@ namespace Conformance {
private static readonly pb::FieldCodec<double> _repeated_repeatedDouble_codec
= pb::FieldCodec.ForDouble(338);
private readonly pbc::RepeatedField<double> repeatedDouble_ = new pbc::RepeatedField<double>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<double> RepeatedDouble {
get { return repeatedDouble_; }
}
@@ -1081,6 +1285,7 @@ namespace Conformance {
private static readonly pb::FieldCodec<bool> _repeated_repeatedBool_codec
= pb::FieldCodec.ForBool(346);
private readonly pbc::RepeatedField<bool> repeatedBool_ = new pbc::RepeatedField<bool>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<bool> RepeatedBool {
get { return repeatedBool_; }
}
@@ -1090,6 +1295,7 @@ namespace Conformance {
private static readonly pb::FieldCodec<string> _repeated_repeatedString_codec
= pb::FieldCodec.ForString(354);
private readonly pbc::RepeatedField<string> repeatedString_ = new pbc::RepeatedField<string>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<string> RepeatedString {
get { return repeatedString_; }
}
@@ -1099,6 +1305,7 @@ namespace Conformance {
private static readonly pb::FieldCodec<pb::ByteString> _repeated_repeatedBytes_codec
= pb::FieldCodec.ForBytes(362);
private readonly pbc::RepeatedField<pb::ByteString> repeatedBytes_ = new pbc::RepeatedField<pb::ByteString>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<pb::ByteString> RepeatedBytes {
get { return repeatedBytes_; }
}
@@ -1108,6 +1315,7 @@ namespace Conformance {
private static readonly pb::FieldCodec<global::Conformance.TestAllTypes.Types.NestedMessage> _repeated_repeatedNestedMessage_codec
= pb::FieldCodec.ForMessage(386, global::Conformance.TestAllTypes.Types.NestedMessage.Parser);
private readonly pbc::RepeatedField<global::Conformance.TestAllTypes.Types.NestedMessage> repeatedNestedMessage_ = new pbc::RepeatedField<global::Conformance.TestAllTypes.Types.NestedMessage>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Conformance.TestAllTypes.Types.NestedMessage> RepeatedNestedMessage {
get { return repeatedNestedMessage_; }
}
@@ -1117,6 +1325,7 @@ namespace Conformance {
private static readonly pb::FieldCodec<global::Conformance.ForeignMessage> _repeated_repeatedForeignMessage_codec
= pb::FieldCodec.ForMessage(394, global::Conformance.ForeignMessage.Parser);
private readonly pbc::RepeatedField<global::Conformance.ForeignMessage> repeatedForeignMessage_ = new pbc::RepeatedField<global::Conformance.ForeignMessage>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Conformance.ForeignMessage> RepeatedForeignMessage {
get { return repeatedForeignMessage_; }
}
@@ -1126,6 +1335,7 @@ namespace Conformance {
private static readonly pb::FieldCodec<global::Conformance.TestAllTypes.Types.NestedEnum> _repeated_repeatedNestedEnum_codec
= pb::FieldCodec.ForEnum(410, x => (int) x, x => (global::Conformance.TestAllTypes.Types.NestedEnum) x);
private readonly pbc::RepeatedField<global::Conformance.TestAllTypes.Types.NestedEnum> repeatedNestedEnum_ = new pbc::RepeatedField<global::Conformance.TestAllTypes.Types.NestedEnum>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Conformance.TestAllTypes.Types.NestedEnum> RepeatedNestedEnum {
get { return repeatedNestedEnum_; }
}
@@ -1135,6 +1345,7 @@ namespace Conformance {
private static readonly pb::FieldCodec<global::Conformance.ForeignEnum> _repeated_repeatedForeignEnum_codec
= pb::FieldCodec.ForEnum(418, x => (int) x, x => (global::Conformance.ForeignEnum) x);
private readonly pbc::RepeatedField<global::Conformance.ForeignEnum> repeatedForeignEnum_ = new pbc::RepeatedField<global::Conformance.ForeignEnum>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Conformance.ForeignEnum> RepeatedForeignEnum {
get { return repeatedForeignEnum_; }
}
@@ -1144,6 +1355,7 @@ namespace Conformance {
private static readonly pb::FieldCodec<string> _repeated_repeatedStringPiece_codec
= pb::FieldCodec.ForString(434);
private readonly pbc::RepeatedField<string> repeatedStringPiece_ = new pbc::RepeatedField<string>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<string> RepeatedStringPiece {
get { return repeatedStringPiece_; }
}
@@ -1153,6 +1365,7 @@ namespace Conformance {
private static readonly pb::FieldCodec<string> _repeated_repeatedCord_codec
= pb::FieldCodec.ForString(442);
private readonly pbc::RepeatedField<string> repeatedCord_ = new pbc::RepeatedField<string>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<string> RepeatedCord {
get { return repeatedCord_; }
}
@@ -1165,6 +1378,7 @@ namespace Conformance {
/// <summary>
/// Map
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<int, int> MapInt32Int32 {
get { return mapInt32Int32_; }
}
@@ -1174,6 +1388,7 @@ namespace Conformance {
private static readonly pbc::MapField<long, long>.Codec _map_mapInt64Int64_codec
= new pbc::MapField<long, long>.Codec(pb::FieldCodec.ForInt64(8), pb::FieldCodec.ForInt64(16), 458);
private readonly pbc::MapField<long, long> mapInt64Int64_ = new pbc::MapField<long, long>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<long, long> MapInt64Int64 {
get { return mapInt64Int64_; }
}
@@ -1183,6 +1398,7 @@ namespace Conformance {
private static readonly pbc::MapField<uint, uint>.Codec _map_mapUint32Uint32_codec
= new pbc::MapField<uint, uint>.Codec(pb::FieldCodec.ForUInt32(8), pb::FieldCodec.ForUInt32(16), 466);
private readonly pbc::MapField<uint, uint> mapUint32Uint32_ = new pbc::MapField<uint, uint>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<uint, uint> MapUint32Uint32 {
get { return mapUint32Uint32_; }
}
@@ -1192,6 +1408,7 @@ namespace Conformance {
private static readonly pbc::MapField<ulong, ulong>.Codec _map_mapUint64Uint64_codec
= new pbc::MapField<ulong, ulong>.Codec(pb::FieldCodec.ForUInt64(8), pb::FieldCodec.ForUInt64(16), 474);
private readonly pbc::MapField<ulong, ulong> mapUint64Uint64_ = new pbc::MapField<ulong, ulong>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<ulong, ulong> MapUint64Uint64 {
get { return mapUint64Uint64_; }
}
@@ -1201,6 +1418,7 @@ namespace Conformance {
private static readonly pbc::MapField<int, int>.Codec _map_mapSint32Sint32_codec
= new pbc::MapField<int, int>.Codec(pb::FieldCodec.ForSInt32(8), pb::FieldCodec.ForSInt32(16), 482);
private readonly pbc::MapField<int, int> mapSint32Sint32_ = new pbc::MapField<int, int>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<int, int> MapSint32Sint32 {
get { return mapSint32Sint32_; }
}
@@ -1210,6 +1428,7 @@ namespace Conformance {
private static readonly pbc::MapField<long, long>.Codec _map_mapSint64Sint64_codec
= new pbc::MapField<long, long>.Codec(pb::FieldCodec.ForSInt64(8), pb::FieldCodec.ForSInt64(16), 490);
private readonly pbc::MapField<long, long> mapSint64Sint64_ = new pbc::MapField<long, long>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<long, long> MapSint64Sint64 {
get { return mapSint64Sint64_; }
}
@@ -1219,6 +1438,7 @@ namespace Conformance {
private static readonly pbc::MapField<uint, uint>.Codec _map_mapFixed32Fixed32_codec
= new pbc::MapField<uint, uint>.Codec(pb::FieldCodec.ForFixed32(13), pb::FieldCodec.ForFixed32(21), 498);
private readonly pbc::MapField<uint, uint> mapFixed32Fixed32_ = new pbc::MapField<uint, uint>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<uint, uint> MapFixed32Fixed32 {
get { return mapFixed32Fixed32_; }
}
@@ -1228,6 +1448,7 @@ namespace Conformance {
private static readonly pbc::MapField<ulong, ulong>.Codec _map_mapFixed64Fixed64_codec
= new pbc::MapField<ulong, ulong>.Codec(pb::FieldCodec.ForFixed64(9), pb::FieldCodec.ForFixed64(17), 506);
private readonly pbc::MapField<ulong, ulong> mapFixed64Fixed64_ = new pbc::MapField<ulong, ulong>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<ulong, ulong> MapFixed64Fixed64 {
get { return mapFixed64Fixed64_; }
}
@@ -1237,6 +1458,7 @@ namespace Conformance {
private static readonly pbc::MapField<int, int>.Codec _map_mapSfixed32Sfixed32_codec
= new pbc::MapField<int, int>.Codec(pb::FieldCodec.ForSFixed32(13), pb::FieldCodec.ForSFixed32(21), 514);
private readonly pbc::MapField<int, int> mapSfixed32Sfixed32_ = new pbc::MapField<int, int>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<int, int> MapSfixed32Sfixed32 {
get { return mapSfixed32Sfixed32_; }
}
@@ -1246,6 +1468,7 @@ namespace Conformance {
private static readonly pbc::MapField<long, long>.Codec _map_mapSfixed64Sfixed64_codec
= new pbc::MapField<long, long>.Codec(pb::FieldCodec.ForSFixed64(9), pb::FieldCodec.ForSFixed64(17), 522);
private readonly pbc::MapField<long, long> mapSfixed64Sfixed64_ = new pbc::MapField<long, long>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<long, long> MapSfixed64Sfixed64 {
get { return mapSfixed64Sfixed64_; }
}
@@ -1255,6 +1478,7 @@ namespace Conformance {
private static readonly pbc::MapField<int, float>.Codec _map_mapInt32Float_codec
= new pbc::MapField<int, float>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForFloat(21), 530);
private readonly pbc::MapField<int, float> mapInt32Float_ = new pbc::MapField<int, float>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<int, float> MapInt32Float {
get { return mapInt32Float_; }
}
@@ -1264,6 +1488,7 @@ namespace Conformance {
private static readonly pbc::MapField<int, double>.Codec _map_mapInt32Double_codec
= new pbc::MapField<int, double>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForDouble(17), 538);
private readonly pbc::MapField<int, double> mapInt32Double_ = new pbc::MapField<int, double>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<int, double> MapInt32Double {
get { return mapInt32Double_; }
}
@@ -1273,6 +1498,7 @@ namespace Conformance {
private static readonly pbc::MapField<bool, bool>.Codec _map_mapBoolBool_codec
= new pbc::MapField<bool, bool>.Codec(pb::FieldCodec.ForBool(8), pb::FieldCodec.ForBool(16), 546);
private readonly pbc::MapField<bool, bool> mapBoolBool_ = new pbc::MapField<bool, bool>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<bool, bool> MapBoolBool {
get { return mapBoolBool_; }
}
@@ -1282,6 +1508,7 @@ namespace Conformance {
private static readonly pbc::MapField<string, string>.Codec _map_mapStringString_codec
= new pbc::MapField<string, string>.Codec(pb::FieldCodec.ForString(10), pb::FieldCodec.ForString(18), 554);
private readonly pbc::MapField<string, string> mapStringString_ = new pbc::MapField<string, string>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<string, string> MapStringString {
get { return mapStringString_; }
}
@@ -1291,6 +1518,7 @@ namespace Conformance {
private static readonly pbc::MapField<string, pb::ByteString>.Codec _map_mapStringBytes_codec
= new pbc::MapField<string, pb::ByteString>.Codec(pb::FieldCodec.ForString(10), pb::FieldCodec.ForBytes(18), 562);
private readonly pbc::MapField<string, pb::ByteString> mapStringBytes_ = new pbc::MapField<string, pb::ByteString>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<string, pb::ByteString> MapStringBytes {
get { return mapStringBytes_; }
}
@@ -1300,6 +1528,7 @@ namespace Conformance {
private static readonly pbc::MapField<string, global::Conformance.TestAllTypes.Types.NestedMessage>.Codec _map_mapStringNestedMessage_codec
= new pbc::MapField<string, global::Conformance.TestAllTypes.Types.NestedMessage>.Codec(pb::FieldCodec.ForString(10), pb::FieldCodec.ForMessage(18, global::Conformance.TestAllTypes.Types.NestedMessage.Parser), 570);
private readonly pbc::MapField<string, global::Conformance.TestAllTypes.Types.NestedMessage> mapStringNestedMessage_ = new pbc::MapField<string, global::Conformance.TestAllTypes.Types.NestedMessage>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<string, global::Conformance.TestAllTypes.Types.NestedMessage> MapStringNestedMessage {
get { return mapStringNestedMessage_; }
}
@@ -1309,6 +1538,7 @@ namespace Conformance {
private static readonly pbc::MapField<string, global::Conformance.ForeignMessage>.Codec _map_mapStringForeignMessage_codec
= new pbc::MapField<string, global::Conformance.ForeignMessage>.Codec(pb::FieldCodec.ForString(10), pb::FieldCodec.ForMessage(18, global::Conformance.ForeignMessage.Parser), 578);
private readonly pbc::MapField<string, global::Conformance.ForeignMessage> mapStringForeignMessage_ = new pbc::MapField<string, global::Conformance.ForeignMessage>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<string, global::Conformance.ForeignMessage> MapStringForeignMessage {
get { return mapStringForeignMessage_; }
}
@@ -1318,6 +1548,7 @@ namespace Conformance {
private static readonly pbc::MapField<string, global::Conformance.TestAllTypes.Types.NestedEnum>.Codec _map_mapStringNestedEnum_codec
= new pbc::MapField<string, global::Conformance.TestAllTypes.Types.NestedEnum>.Codec(pb::FieldCodec.ForString(10), pb::FieldCodec.ForEnum(16, x => (int) x, x => (global::Conformance.TestAllTypes.Types.NestedEnum) x), 586);
private readonly pbc::MapField<string, global::Conformance.TestAllTypes.Types.NestedEnum> mapStringNestedEnum_ = new pbc::MapField<string, global::Conformance.TestAllTypes.Types.NestedEnum>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<string, global::Conformance.TestAllTypes.Types.NestedEnum> MapStringNestedEnum {
get { return mapStringNestedEnum_; }
}
@@ -1327,12 +1558,14 @@ namespace Conformance {
private static readonly pbc::MapField<string, global::Conformance.ForeignEnum>.Codec _map_mapStringForeignEnum_codec
= new pbc::MapField<string, global::Conformance.ForeignEnum>.Codec(pb::FieldCodec.ForString(10), pb::FieldCodec.ForEnum(16, x => (int) x, x => (global::Conformance.ForeignEnum) x), 594);
private readonly pbc::MapField<string, global::Conformance.ForeignEnum> mapStringForeignEnum_ = new pbc::MapField<string, global::Conformance.ForeignEnum>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<string, global::Conformance.ForeignEnum> MapStringForeignEnum {
get { return mapStringForeignEnum_; }
}
/// <summary>Field number for the "oneof_uint32" field.</summary>
public const int OneofUint32FieldNumber = 111;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public uint OneofUint32 {
get { return oneofFieldCase_ == OneofFieldOneofCase.OneofUint32 ? (uint) oneofField_ : 0; }
set {
@@ -1343,6 +1576,7 @@ namespace Conformance {
/// <summary>Field number for the "oneof_nested_message" field.</summary>
public const int OneofNestedMessageFieldNumber = 112;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Conformance.TestAllTypes.Types.NestedMessage OneofNestedMessage {
get { return oneofFieldCase_ == OneofFieldOneofCase.OneofNestedMessage ? (global::Conformance.TestAllTypes.Types.NestedMessage) oneofField_ : null; }
set {
@@ -1353,24 +1587,488 @@ namespace Conformance {
/// <summary>Field number for the "oneof_string" field.</summary>
public const int OneofStringFieldNumber = 113;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string OneofString {
get { return oneofFieldCase_ == OneofFieldOneofCase.OneofString ? (string) oneofField_ : ""; }
set {
- oneofField_ = pb::Preconditions.CheckNotNull(value, "value");
+ oneofField_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
oneofFieldCase_ = OneofFieldOneofCase.OneofString;
}
}
/// <summary>Field number for the "oneof_bytes" field.</summary>
public const int OneofBytesFieldNumber = 114;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pb::ByteString OneofBytes {
get { return oneofFieldCase_ == OneofFieldOneofCase.OneofBytes ? (pb::ByteString) oneofField_ : pb::ByteString.Empty; }
set {
- oneofField_ = pb::Preconditions.CheckNotNull(value, "value");
+ oneofField_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
oneofFieldCase_ = OneofFieldOneofCase.OneofBytes;
}
}
+ /// <summary>Field number for the "optional_bool_wrapper" field.</summary>
+ public const int OptionalBoolWrapperFieldNumber = 201;
+ private static readonly pb::FieldCodec<bool?> _single_optionalBoolWrapper_codec = pb::FieldCodec.ForStructWrapper<bool>(1610);
+ private bool? optionalBoolWrapper_;
+ /// <summary>
+ /// Well-known types
+ /// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool? OptionalBoolWrapper {
+ get { return optionalBoolWrapper_; }
+ set {
+ optionalBoolWrapper_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "optional_int32_wrapper" field.</summary>
+ public const int OptionalInt32WrapperFieldNumber = 202;
+ private static readonly pb::FieldCodec<int?> _single_optionalInt32Wrapper_codec = pb::FieldCodec.ForStructWrapper<int>(1618);
+ private int? optionalInt32Wrapper_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int? OptionalInt32Wrapper {
+ get { return optionalInt32Wrapper_; }
+ set {
+ optionalInt32Wrapper_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "optional_int64_wrapper" field.</summary>
+ public const int OptionalInt64WrapperFieldNumber = 203;
+ private static readonly pb::FieldCodec<long?> _single_optionalInt64Wrapper_codec = pb::FieldCodec.ForStructWrapper<long>(1626);
+ private long? optionalInt64Wrapper_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public long? OptionalInt64Wrapper {
+ get { return optionalInt64Wrapper_; }
+ set {
+ optionalInt64Wrapper_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "optional_uint32_wrapper" field.</summary>
+ public const int OptionalUint32WrapperFieldNumber = 204;
+ private static readonly pb::FieldCodec<uint?> _single_optionalUint32Wrapper_codec = pb::FieldCodec.ForStructWrapper<uint>(1634);
+ private uint? optionalUint32Wrapper_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public uint? OptionalUint32Wrapper {
+ get { return optionalUint32Wrapper_; }
+ set {
+ optionalUint32Wrapper_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "optional_uint64_wrapper" field.</summary>
+ public const int OptionalUint64WrapperFieldNumber = 205;
+ private static readonly pb::FieldCodec<ulong?> _single_optionalUint64Wrapper_codec = pb::FieldCodec.ForStructWrapper<ulong>(1642);
+ private ulong? optionalUint64Wrapper_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public ulong? OptionalUint64Wrapper {
+ get { return optionalUint64Wrapper_; }
+ set {
+ optionalUint64Wrapper_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "optional_float_wrapper" field.</summary>
+ public const int OptionalFloatWrapperFieldNumber = 206;
+ private static readonly pb::FieldCodec<float?> _single_optionalFloatWrapper_codec = pb::FieldCodec.ForStructWrapper<float>(1650);
+ private float? optionalFloatWrapper_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public float? OptionalFloatWrapper {
+ get { return optionalFloatWrapper_; }
+ set {
+ optionalFloatWrapper_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "optional_double_wrapper" field.</summary>
+ public const int OptionalDoubleWrapperFieldNumber = 207;
+ private static readonly pb::FieldCodec<double?> _single_optionalDoubleWrapper_codec = pb::FieldCodec.ForStructWrapper<double>(1658);
+ private double? optionalDoubleWrapper_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public double? OptionalDoubleWrapper {
+ get { return optionalDoubleWrapper_; }
+ set {
+ optionalDoubleWrapper_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "optional_string_wrapper" field.</summary>
+ public const int OptionalStringWrapperFieldNumber = 208;
+ private static readonly pb::FieldCodec<string> _single_optionalStringWrapper_codec = pb::FieldCodec.ForClassWrapper<string>(1666);
+ private string optionalStringWrapper_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public string OptionalStringWrapper {
+ get { return optionalStringWrapper_; }
+ set {
+ optionalStringWrapper_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "optional_bytes_wrapper" field.</summary>
+ public const int OptionalBytesWrapperFieldNumber = 209;
+ private static readonly pb::FieldCodec<pb::ByteString> _single_optionalBytesWrapper_codec = pb::FieldCodec.ForClassWrapper<pb::ByteString>(1674);
+ private pb::ByteString optionalBytesWrapper_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public pb::ByteString OptionalBytesWrapper {
+ get { return optionalBytesWrapper_; }
+ set {
+ optionalBytesWrapper_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "repeated_bool_wrapper" field.</summary>
+ public const int RepeatedBoolWrapperFieldNumber = 211;
+ private static readonly pb::FieldCodec<bool?> _repeated_repeatedBoolWrapper_codec
+ = pb::FieldCodec.ForStructWrapper<bool>(1690);
+ private readonly pbc::RepeatedField<bool?> repeatedBoolWrapper_ = new pbc::RepeatedField<bool?>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public pbc::RepeatedField<bool?> RepeatedBoolWrapper {
+ get { return repeatedBoolWrapper_; }
+ }
+
+ /// <summary>Field number for the "repeated_int32_wrapper" field.</summary>
+ public const int RepeatedInt32WrapperFieldNumber = 212;
+ private static readonly pb::FieldCodec<int?> _repeated_repeatedInt32Wrapper_codec
+ = pb::FieldCodec.ForStructWrapper<int>(1698);
+ private readonly pbc::RepeatedField<int?> repeatedInt32Wrapper_ = new pbc::RepeatedField<int?>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public pbc::RepeatedField<int?> RepeatedInt32Wrapper {
+ get { return repeatedInt32Wrapper_; }
+ }
+
+ /// <summary>Field number for the "repeated_int64_wrapper" field.</summary>
+ public const int RepeatedInt64WrapperFieldNumber = 213;
+ private static readonly pb::FieldCodec<long?> _repeated_repeatedInt64Wrapper_codec
+ = pb::FieldCodec.ForStructWrapper<long>(1706);
+ private readonly pbc::RepeatedField<long?> repeatedInt64Wrapper_ = new pbc::RepeatedField<long?>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public pbc::RepeatedField<long?> RepeatedInt64Wrapper {
+ get { return repeatedInt64Wrapper_; }
+ }
+
+ /// <summary>Field number for the "repeated_uint32_wrapper" field.</summary>
+ public const int RepeatedUint32WrapperFieldNumber = 214;
+ private static readonly pb::FieldCodec<uint?> _repeated_repeatedUint32Wrapper_codec
+ = pb::FieldCodec.ForStructWrapper<uint>(1714);
+ private readonly pbc::RepeatedField<uint?> repeatedUint32Wrapper_ = new pbc::RepeatedField<uint?>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public pbc::RepeatedField<uint?> RepeatedUint32Wrapper {
+ get { return repeatedUint32Wrapper_; }
+ }
+
+ /// <summary>Field number for the "repeated_uint64_wrapper" field.</summary>
+ public const int RepeatedUint64WrapperFieldNumber = 215;
+ private static readonly pb::FieldCodec<ulong?> _repeated_repeatedUint64Wrapper_codec
+ = pb::FieldCodec.ForStructWrapper<ulong>(1722);
+ private readonly pbc::RepeatedField<ulong?> repeatedUint64Wrapper_ = new pbc::RepeatedField<ulong?>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public pbc::RepeatedField<ulong?> RepeatedUint64Wrapper {
+ get { return repeatedUint64Wrapper_; }
+ }
+
+ /// <summary>Field number for the "repeated_float_wrapper" field.</summary>
+ public const int RepeatedFloatWrapperFieldNumber = 216;
+ private static readonly pb::FieldCodec<float?> _repeated_repeatedFloatWrapper_codec
+ = pb::FieldCodec.ForStructWrapper<float>(1730);
+ private readonly pbc::RepeatedField<float?> repeatedFloatWrapper_ = new pbc::RepeatedField<float?>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public pbc::RepeatedField<float?> RepeatedFloatWrapper {
+ get { return repeatedFloatWrapper_; }
+ }
+
+ /// <summary>Field number for the "repeated_double_wrapper" field.</summary>
+ public const int RepeatedDoubleWrapperFieldNumber = 217;
+ private static readonly pb::FieldCodec<double?> _repeated_repeatedDoubleWrapper_codec
+ = pb::FieldCodec.ForStructWrapper<double>(1738);
+ private readonly pbc::RepeatedField<double?> repeatedDoubleWrapper_ = new pbc::RepeatedField<double?>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public pbc::RepeatedField<double?> RepeatedDoubleWrapper {
+ get { return repeatedDoubleWrapper_; }
+ }
+
+ /// <summary>Field number for the "repeated_string_wrapper" field.</summary>
+ public const int RepeatedStringWrapperFieldNumber = 218;
+ private static readonly pb::FieldCodec<string> _repeated_repeatedStringWrapper_codec
+ = pb::FieldCodec.ForClassWrapper<string>(1746);
+ private readonly pbc::RepeatedField<string> repeatedStringWrapper_ = new pbc::RepeatedField<string>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public pbc::RepeatedField<string> RepeatedStringWrapper {
+ get { return repeatedStringWrapper_; }
+ }
+
+ /// <summary>Field number for the "repeated_bytes_wrapper" field.</summary>
+ public const int RepeatedBytesWrapperFieldNumber = 219;
+ private static readonly pb::FieldCodec<pb::ByteString> _repeated_repeatedBytesWrapper_codec
+ = pb::FieldCodec.ForClassWrapper<pb::ByteString>(1754);
+ private readonly pbc::RepeatedField<pb::ByteString> repeatedBytesWrapper_ = new pbc::RepeatedField<pb::ByteString>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public pbc::RepeatedField<pb::ByteString> RepeatedBytesWrapper {
+ get { return repeatedBytesWrapper_; }
+ }
+
+ /// <summary>Field number for the "optional_duration" field.</summary>
+ public const int OptionalDurationFieldNumber = 301;
+ private global::Google.Protobuf.WellKnownTypes.Duration optionalDuration_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public global::Google.Protobuf.WellKnownTypes.Duration OptionalDuration {
+ get { return optionalDuration_; }
+ set {
+ optionalDuration_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "optional_timestamp" field.</summary>
+ public const int OptionalTimestampFieldNumber = 302;
+ private global::Google.Protobuf.WellKnownTypes.Timestamp optionalTimestamp_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public global::Google.Protobuf.WellKnownTypes.Timestamp OptionalTimestamp {
+ get { return optionalTimestamp_; }
+ set {
+ optionalTimestamp_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "optional_field_mask" field.</summary>
+ public const int OptionalFieldMaskFieldNumber = 303;
+ private global::Google.Protobuf.WellKnownTypes.FieldMask optionalFieldMask_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public global::Google.Protobuf.WellKnownTypes.FieldMask OptionalFieldMask {
+ get { return optionalFieldMask_; }
+ set {
+ optionalFieldMask_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "optional_struct" field.</summary>
+ public const int OptionalStructFieldNumber = 304;
+ private global::Google.Protobuf.WellKnownTypes.Struct optionalStruct_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public global::Google.Protobuf.WellKnownTypes.Struct OptionalStruct {
+ get { return optionalStruct_; }
+ set {
+ optionalStruct_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "optional_any" field.</summary>
+ public const int OptionalAnyFieldNumber = 305;
+ private global::Google.Protobuf.WellKnownTypes.Any optionalAny_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public global::Google.Protobuf.WellKnownTypes.Any OptionalAny {
+ get { return optionalAny_; }
+ set {
+ optionalAny_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "optional_value" field.</summary>
+ public const int OptionalValueFieldNumber = 306;
+ private global::Google.Protobuf.WellKnownTypes.Value optionalValue_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public global::Google.Protobuf.WellKnownTypes.Value OptionalValue {
+ get { return optionalValue_; }
+ set {
+ optionalValue_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "repeated_duration" field.</summary>
+ public const int RepeatedDurationFieldNumber = 311;
+ private static readonly pb::FieldCodec<global::Google.Protobuf.WellKnownTypes.Duration> _repeated_repeatedDuration_codec
+ = pb::FieldCodec.ForMessage(2490, global::Google.Protobuf.WellKnownTypes.Duration.Parser);
+ private readonly pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Duration> repeatedDuration_ = new pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Duration>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Duration> RepeatedDuration {
+ get { return repeatedDuration_; }
+ }
+
+ /// <summary>Field number for the "repeated_timestamp" field.</summary>
+ public const int RepeatedTimestampFieldNumber = 312;
+ private static readonly pb::FieldCodec<global::Google.Protobuf.WellKnownTypes.Timestamp> _repeated_repeatedTimestamp_codec
+ = pb::FieldCodec.ForMessage(2498, global::Google.Protobuf.WellKnownTypes.Timestamp.Parser);
+ private readonly pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Timestamp> repeatedTimestamp_ = new pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Timestamp>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Timestamp> RepeatedTimestamp {
+ get { return repeatedTimestamp_; }
+ }
+
+ /// <summary>Field number for the "repeated_fieldmask" field.</summary>
+ public const int RepeatedFieldmaskFieldNumber = 313;
+ private static readonly pb::FieldCodec<global::Google.Protobuf.WellKnownTypes.FieldMask> _repeated_repeatedFieldmask_codec
+ = pb::FieldCodec.ForMessage(2506, global::Google.Protobuf.WellKnownTypes.FieldMask.Parser);
+ private readonly pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.FieldMask> repeatedFieldmask_ = new pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.FieldMask>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.FieldMask> RepeatedFieldmask {
+ get { return repeatedFieldmask_; }
+ }
+
+ /// <summary>Field number for the "repeated_struct" field.</summary>
+ public const int RepeatedStructFieldNumber = 324;
+ private static readonly pb::FieldCodec<global::Google.Protobuf.WellKnownTypes.Struct> _repeated_repeatedStruct_codec
+ = pb::FieldCodec.ForMessage(2594, global::Google.Protobuf.WellKnownTypes.Struct.Parser);
+ private readonly pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Struct> repeatedStruct_ = new pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Struct>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Struct> RepeatedStruct {
+ get { return repeatedStruct_; }
+ }
+
+ /// <summary>Field number for the "repeated_any" field.</summary>
+ public const int RepeatedAnyFieldNumber = 315;
+ private static readonly pb::FieldCodec<global::Google.Protobuf.WellKnownTypes.Any> _repeated_repeatedAny_codec
+ = pb::FieldCodec.ForMessage(2522, global::Google.Protobuf.WellKnownTypes.Any.Parser);
+ private readonly pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Any> repeatedAny_ = new pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Any>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Any> RepeatedAny {
+ get { return repeatedAny_; }
+ }
+
+ /// <summary>Field number for the "repeated_value" field.</summary>
+ public const int RepeatedValueFieldNumber = 316;
+ private static readonly pb::FieldCodec<global::Google.Protobuf.WellKnownTypes.Value> _repeated_repeatedValue_codec
+ = pb::FieldCodec.ForMessage(2530, global::Google.Protobuf.WellKnownTypes.Value.Parser);
+ private readonly pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Value> repeatedValue_ = new pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Value>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Value> RepeatedValue {
+ get { return repeatedValue_; }
+ }
+
+ /// <summary>Field number for the "fieldname1" field.</summary>
+ public const int Fieldname1FieldNumber = 401;
+ private int fieldname1_;
+ /// <summary>
+ /// Test field-name-to-JSON-name convention.
+ /// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int Fieldname1 {
+ get { return fieldname1_; }
+ set {
+ fieldname1_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "field_name2" field.</summary>
+ public const int FieldName2FieldNumber = 402;
+ private int fieldName2_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int FieldName2 {
+ get { return fieldName2_; }
+ set {
+ fieldName2_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "_field_name3" field.</summary>
+ public const int FieldName3FieldNumber = 403;
+ private int FieldName3_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int FieldName3 {
+ get { return FieldName3_; }
+ set {
+ FieldName3_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "field__name4_" field.</summary>
+ public const int FieldName4FieldNumber = 404;
+ private int fieldName4_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int FieldName4 {
+ get { return fieldName4_; }
+ set {
+ fieldName4_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "field0name5" field.</summary>
+ public const int Field0Name5FieldNumber = 405;
+ private int field0Name5_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int Field0Name5 {
+ get { return field0Name5_; }
+ set {
+ field0Name5_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "field_0_name6" field.</summary>
+ public const int Field0Name6FieldNumber = 406;
+ private int field0Name6_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int Field0Name6 {
+ get { return field0Name6_; }
+ set {
+ field0Name6_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "fieldName7" field.</summary>
+ public const int FieldName7FieldNumber = 407;
+ private int fieldName7_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int FieldName7 {
+ get { return fieldName7_; }
+ set {
+ fieldName7_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "FieldName8" field.</summary>
+ public const int FieldName8FieldNumber = 408;
+ private int fieldName8_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int FieldName8 {
+ get { return fieldName8_; }
+ set {
+ fieldName8_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "field_Name9" field.</summary>
+ public const int FieldName9FieldNumber = 409;
+ private int fieldName9_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int FieldName9 {
+ get { return fieldName9_; }
+ set {
+ fieldName9_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "Field_Name10" field.</summary>
+ public const int FieldName10FieldNumber = 410;
+ private int fieldName10_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int FieldName10 {
+ get { return fieldName10_; }
+ set {
+ fieldName10_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "FIELD_NAME11" field.</summary>
+ public const int FIELDNAME11FieldNumber = 411;
+ private int fIELDNAME11_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int FIELDNAME11 {
+ get { return fIELDNAME11_; }
+ set {
+ fIELDNAME11_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "FIELD_name12" field.</summary>
+ public const int FIELDName12FieldNumber = 412;
+ private int fIELDName12_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int FIELDName12 {
+ get { return fIELDName12_; }
+ set {
+ fIELDName12_ = value;
+ }
+ }
+
private object oneofField_;
/// <summary>Enum of possible cases for the "oneof_field" oneof.</summary>
public enum OneofFieldOneofCase {
@@ -1381,19 +2079,23 @@ namespace Conformance {
OneofBytes = 114,
}
private OneofFieldOneofCase oneofFieldCase_ = OneofFieldOneofCase.None;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public OneofFieldOneofCase OneofFieldCase {
get { return oneofFieldCase_; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void ClearOneofField() {
oneofFieldCase_ = OneofFieldOneofCase.None;
oneofField_ = null;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as TestAllTypes);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(TestAllTypes other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -1467,10 +2169,53 @@ namespace Conformance {
if (!object.Equals(OneofNestedMessage, other.OneofNestedMessage)) return false;
if (OneofString != other.OneofString) return false;
if (OneofBytes != other.OneofBytes) return false;
+ if (OptionalBoolWrapper != other.OptionalBoolWrapper) return false;
+ if (OptionalInt32Wrapper != other.OptionalInt32Wrapper) return false;
+ if (OptionalInt64Wrapper != other.OptionalInt64Wrapper) return false;
+ if (OptionalUint32Wrapper != other.OptionalUint32Wrapper) return false;
+ if (OptionalUint64Wrapper != other.OptionalUint64Wrapper) return false;
+ if (OptionalFloatWrapper != other.OptionalFloatWrapper) return false;
+ if (OptionalDoubleWrapper != other.OptionalDoubleWrapper) return false;
+ if (OptionalStringWrapper != other.OptionalStringWrapper) return false;
+ if (OptionalBytesWrapper != other.OptionalBytesWrapper) return false;
+ if(!repeatedBoolWrapper_.Equals(other.repeatedBoolWrapper_)) return false;
+ if(!repeatedInt32Wrapper_.Equals(other.repeatedInt32Wrapper_)) return false;
+ if(!repeatedInt64Wrapper_.Equals(other.repeatedInt64Wrapper_)) return false;
+ if(!repeatedUint32Wrapper_.Equals(other.repeatedUint32Wrapper_)) return false;
+ if(!repeatedUint64Wrapper_.Equals(other.repeatedUint64Wrapper_)) return false;
+ if(!repeatedFloatWrapper_.Equals(other.repeatedFloatWrapper_)) return false;
+ if(!repeatedDoubleWrapper_.Equals(other.repeatedDoubleWrapper_)) return false;
+ if(!repeatedStringWrapper_.Equals(other.repeatedStringWrapper_)) return false;
+ if(!repeatedBytesWrapper_.Equals(other.repeatedBytesWrapper_)) return false;
+ if (!object.Equals(OptionalDuration, other.OptionalDuration)) return false;
+ if (!object.Equals(OptionalTimestamp, other.OptionalTimestamp)) return false;
+ if (!object.Equals(OptionalFieldMask, other.OptionalFieldMask)) return false;
+ if (!object.Equals(OptionalStruct, other.OptionalStruct)) return false;
+ if (!object.Equals(OptionalAny, other.OptionalAny)) return false;
+ if (!object.Equals(OptionalValue, other.OptionalValue)) return false;
+ if(!repeatedDuration_.Equals(other.repeatedDuration_)) return false;
+ if(!repeatedTimestamp_.Equals(other.repeatedTimestamp_)) return false;
+ if(!repeatedFieldmask_.Equals(other.repeatedFieldmask_)) return false;
+ if(!repeatedStruct_.Equals(other.repeatedStruct_)) return false;
+ if(!repeatedAny_.Equals(other.repeatedAny_)) return false;
+ if(!repeatedValue_.Equals(other.repeatedValue_)) return false;
+ if (Fieldname1 != other.Fieldname1) return false;
+ if (FieldName2 != other.FieldName2) return false;
+ if (FieldName3 != other.FieldName3) return false;
+ if (FieldName4 != other.FieldName4) return false;
+ if (Field0Name5 != other.Field0Name5) return false;
+ if (Field0Name6 != other.Field0Name6) return false;
+ if (FieldName7 != other.FieldName7) return false;
+ if (FieldName8 != other.FieldName8) return false;
+ if (FieldName9 != other.FieldName9) return false;
+ if (FieldName10 != other.FieldName10) return false;
+ if (FIELDNAME11 != other.FIELDNAME11) return false;
+ if (FIELDName12 != other.FIELDName12) return false;
if (OneofFieldCase != other.OneofFieldCase) return false;
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (OptionalInt32 != 0) hash ^= OptionalInt32.GetHashCode();
@@ -1490,8 +2235,8 @@ namespace Conformance {
if (OptionalBytes.Length != 0) hash ^= OptionalBytes.GetHashCode();
if (optionalNestedMessage_ != null) hash ^= OptionalNestedMessage.GetHashCode();
if (optionalForeignMessage_ != null) hash ^= OptionalForeignMessage.GetHashCode();
- if (OptionalNestedEnum != global::Conformance.TestAllTypes.Types.NestedEnum.FOO) hash ^= OptionalNestedEnum.GetHashCode();
- if (OptionalForeignEnum != global::Conformance.ForeignEnum.FOREIGN_FOO) hash ^= OptionalForeignEnum.GetHashCode();
+ if (OptionalNestedEnum != 0) hash ^= OptionalNestedEnum.GetHashCode();
+ if (OptionalForeignEnum != 0) hash ^= OptionalForeignEnum.GetHashCode();
if (OptionalStringPiece.Length != 0) hash ^= OptionalStringPiece.GetHashCode();
if (OptionalCord.Length != 0) hash ^= OptionalCord.GetHashCode();
if (recursiveMessage_ != null) hash ^= RecursiveMessage.GetHashCode();
@@ -1539,14 +2284,58 @@ namespace Conformance {
if (oneofFieldCase_ == OneofFieldOneofCase.OneofNestedMessage) hash ^= OneofNestedMessage.GetHashCode();
if (oneofFieldCase_ == OneofFieldOneofCase.OneofString) hash ^= OneofString.GetHashCode();
if (oneofFieldCase_ == OneofFieldOneofCase.OneofBytes) hash ^= OneofBytes.GetHashCode();
+ if (optionalBoolWrapper_ != null) hash ^= OptionalBoolWrapper.GetHashCode();
+ if (optionalInt32Wrapper_ != null) hash ^= OptionalInt32Wrapper.GetHashCode();
+ if (optionalInt64Wrapper_ != null) hash ^= OptionalInt64Wrapper.GetHashCode();
+ if (optionalUint32Wrapper_ != null) hash ^= OptionalUint32Wrapper.GetHashCode();
+ if (optionalUint64Wrapper_ != null) hash ^= OptionalUint64Wrapper.GetHashCode();
+ if (optionalFloatWrapper_ != null) hash ^= OptionalFloatWrapper.GetHashCode();
+ if (optionalDoubleWrapper_ != null) hash ^= OptionalDoubleWrapper.GetHashCode();
+ if (optionalStringWrapper_ != null) hash ^= OptionalStringWrapper.GetHashCode();
+ if (optionalBytesWrapper_ != null) hash ^= OptionalBytesWrapper.GetHashCode();
+ hash ^= repeatedBoolWrapper_.GetHashCode();
+ hash ^= repeatedInt32Wrapper_.GetHashCode();
+ hash ^= repeatedInt64Wrapper_.GetHashCode();
+ hash ^= repeatedUint32Wrapper_.GetHashCode();
+ hash ^= repeatedUint64Wrapper_.GetHashCode();
+ hash ^= repeatedFloatWrapper_.GetHashCode();
+ hash ^= repeatedDoubleWrapper_.GetHashCode();
+ hash ^= repeatedStringWrapper_.GetHashCode();
+ hash ^= repeatedBytesWrapper_.GetHashCode();
+ if (optionalDuration_ != null) hash ^= OptionalDuration.GetHashCode();
+ if (optionalTimestamp_ != null) hash ^= OptionalTimestamp.GetHashCode();
+ if (optionalFieldMask_ != null) hash ^= OptionalFieldMask.GetHashCode();
+ if (optionalStruct_ != null) hash ^= OptionalStruct.GetHashCode();
+ if (optionalAny_ != null) hash ^= OptionalAny.GetHashCode();
+ if (optionalValue_ != null) hash ^= OptionalValue.GetHashCode();
+ hash ^= repeatedDuration_.GetHashCode();
+ hash ^= repeatedTimestamp_.GetHashCode();
+ hash ^= repeatedFieldmask_.GetHashCode();
+ hash ^= repeatedStruct_.GetHashCode();
+ hash ^= repeatedAny_.GetHashCode();
+ hash ^= repeatedValue_.GetHashCode();
+ if (Fieldname1 != 0) hash ^= Fieldname1.GetHashCode();
+ if (FieldName2 != 0) hash ^= FieldName2.GetHashCode();
+ if (FieldName3 != 0) hash ^= FieldName3.GetHashCode();
+ if (FieldName4 != 0) hash ^= FieldName4.GetHashCode();
+ if (Field0Name5 != 0) hash ^= Field0Name5.GetHashCode();
+ if (Field0Name6 != 0) hash ^= Field0Name6.GetHashCode();
+ if (FieldName7 != 0) hash ^= FieldName7.GetHashCode();
+ if (FieldName8 != 0) hash ^= FieldName8.GetHashCode();
+ if (FieldName9 != 0) hash ^= FieldName9.GetHashCode();
+ if (FieldName10 != 0) hash ^= FieldName10.GetHashCode();
+ if (FIELDNAME11 != 0) hash ^= FIELDNAME11.GetHashCode();
+ if (FIELDName12 != 0) hash ^= FIELDName12.GetHashCode();
hash ^= (int) oneofFieldCase_;
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (OptionalInt32 != 0) {
output.WriteRawTag(8);
@@ -1616,11 +2405,11 @@ namespace Conformance {
output.WriteRawTag(154, 1);
output.WriteMessage(OptionalForeignMessage);
}
- if (OptionalNestedEnum != global::Conformance.TestAllTypes.Types.NestedEnum.FOO) {
+ if (OptionalNestedEnum != 0) {
output.WriteRawTag(168, 1);
output.WriteEnum((int) OptionalNestedEnum);
}
- if (OptionalForeignEnum != global::Conformance.ForeignEnum.FOREIGN_FOO) {
+ if (OptionalForeignEnum != 0) {
output.WriteRawTag(176, 1);
output.WriteEnum((int) OptionalForeignEnum);
}
@@ -1692,8 +2481,123 @@ namespace Conformance {
output.WriteRawTag(146, 7);
output.WriteBytes(OneofBytes);
}
+ if (optionalBoolWrapper_ != null) {
+ _single_optionalBoolWrapper_codec.WriteTagAndValue(output, OptionalBoolWrapper);
+ }
+ if (optionalInt32Wrapper_ != null) {
+ _single_optionalInt32Wrapper_codec.WriteTagAndValue(output, OptionalInt32Wrapper);
+ }
+ if (optionalInt64Wrapper_ != null) {
+ _single_optionalInt64Wrapper_codec.WriteTagAndValue(output, OptionalInt64Wrapper);
+ }
+ if (optionalUint32Wrapper_ != null) {
+ _single_optionalUint32Wrapper_codec.WriteTagAndValue(output, OptionalUint32Wrapper);
+ }
+ if (optionalUint64Wrapper_ != null) {
+ _single_optionalUint64Wrapper_codec.WriteTagAndValue(output, OptionalUint64Wrapper);
+ }
+ if (optionalFloatWrapper_ != null) {
+ _single_optionalFloatWrapper_codec.WriteTagAndValue(output, OptionalFloatWrapper);
+ }
+ if (optionalDoubleWrapper_ != null) {
+ _single_optionalDoubleWrapper_codec.WriteTagAndValue(output, OptionalDoubleWrapper);
+ }
+ if (optionalStringWrapper_ != null) {
+ _single_optionalStringWrapper_codec.WriteTagAndValue(output, OptionalStringWrapper);
+ }
+ if (optionalBytesWrapper_ != null) {
+ _single_optionalBytesWrapper_codec.WriteTagAndValue(output, OptionalBytesWrapper);
+ }
+ repeatedBoolWrapper_.WriteTo(output, _repeated_repeatedBoolWrapper_codec);
+ repeatedInt32Wrapper_.WriteTo(output, _repeated_repeatedInt32Wrapper_codec);
+ repeatedInt64Wrapper_.WriteTo(output, _repeated_repeatedInt64Wrapper_codec);
+ repeatedUint32Wrapper_.WriteTo(output, _repeated_repeatedUint32Wrapper_codec);
+ repeatedUint64Wrapper_.WriteTo(output, _repeated_repeatedUint64Wrapper_codec);
+ repeatedFloatWrapper_.WriteTo(output, _repeated_repeatedFloatWrapper_codec);
+ repeatedDoubleWrapper_.WriteTo(output, _repeated_repeatedDoubleWrapper_codec);
+ repeatedStringWrapper_.WriteTo(output, _repeated_repeatedStringWrapper_codec);
+ repeatedBytesWrapper_.WriteTo(output, _repeated_repeatedBytesWrapper_codec);
+ if (optionalDuration_ != null) {
+ output.WriteRawTag(234, 18);
+ output.WriteMessage(OptionalDuration);
+ }
+ if (optionalTimestamp_ != null) {
+ output.WriteRawTag(242, 18);
+ output.WriteMessage(OptionalTimestamp);
+ }
+ if (optionalFieldMask_ != null) {
+ output.WriteRawTag(250, 18);
+ output.WriteMessage(OptionalFieldMask);
+ }
+ if (optionalStruct_ != null) {
+ output.WriteRawTag(130, 19);
+ output.WriteMessage(OptionalStruct);
+ }
+ if (optionalAny_ != null) {
+ output.WriteRawTag(138, 19);
+ output.WriteMessage(OptionalAny);
+ }
+ if (optionalValue_ != null) {
+ output.WriteRawTag(146, 19);
+ output.WriteMessage(OptionalValue);
+ }
+ repeatedDuration_.WriteTo(output, _repeated_repeatedDuration_codec);
+ repeatedTimestamp_.WriteTo(output, _repeated_repeatedTimestamp_codec);
+ repeatedFieldmask_.WriteTo(output, _repeated_repeatedFieldmask_codec);
+ repeatedAny_.WriteTo(output, _repeated_repeatedAny_codec);
+ repeatedValue_.WriteTo(output, _repeated_repeatedValue_codec);
+ repeatedStruct_.WriteTo(output, _repeated_repeatedStruct_codec);
+ if (Fieldname1 != 0) {
+ output.WriteRawTag(136, 25);
+ output.WriteInt32(Fieldname1);
+ }
+ if (FieldName2 != 0) {
+ output.WriteRawTag(144, 25);
+ output.WriteInt32(FieldName2);
+ }
+ if (FieldName3 != 0) {
+ output.WriteRawTag(152, 25);
+ output.WriteInt32(FieldName3);
+ }
+ if (FieldName4 != 0) {
+ output.WriteRawTag(160, 25);
+ output.WriteInt32(FieldName4);
+ }
+ if (Field0Name5 != 0) {
+ output.WriteRawTag(168, 25);
+ output.WriteInt32(Field0Name5);
+ }
+ if (Field0Name6 != 0) {
+ output.WriteRawTag(176, 25);
+ output.WriteInt32(Field0Name6);
+ }
+ if (FieldName7 != 0) {
+ output.WriteRawTag(184, 25);
+ output.WriteInt32(FieldName7);
+ }
+ if (FieldName8 != 0) {
+ output.WriteRawTag(192, 25);
+ output.WriteInt32(FieldName8);
+ }
+ if (FieldName9 != 0) {
+ output.WriteRawTag(200, 25);
+ output.WriteInt32(FieldName9);
+ }
+ if (FieldName10 != 0) {
+ output.WriteRawTag(208, 25);
+ output.WriteInt32(FieldName10);
+ }
+ if (FIELDNAME11 != 0) {
+ output.WriteRawTag(216, 25);
+ output.WriteInt32(FIELDNAME11);
+ }
+ if (FIELDName12 != 0) {
+ output.WriteRawTag(224, 25);
+ output.WriteInt32(FIELDName12);
+ }
}
-
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (OptionalInt32 != 0) {
@@ -1747,10 +2651,10 @@ namespace Conformance {
if (optionalForeignMessage_ != null) {
size += 2 + pb::CodedOutputStream.ComputeMessageSize(OptionalForeignMessage);
}
- if (OptionalNestedEnum != global::Conformance.TestAllTypes.Types.NestedEnum.FOO) {
+ if (OptionalNestedEnum != 0) {
size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) OptionalNestedEnum);
}
- if (OptionalForeignEnum != global::Conformance.ForeignEnum.FOREIGN_FOO) {
+ if (OptionalForeignEnum != 0) {
size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) OptionalForeignEnum);
}
if (OptionalStringPiece.Length != 0) {
@@ -1814,9 +2718,106 @@ namespace Conformance {
if (oneofFieldCase_ == OneofFieldOneofCase.OneofBytes) {
size += 2 + pb::CodedOutputStream.ComputeBytesSize(OneofBytes);
}
+ if (optionalBoolWrapper_ != null) {
+ size += _single_optionalBoolWrapper_codec.CalculateSizeWithTag(OptionalBoolWrapper);
+ }
+ if (optionalInt32Wrapper_ != null) {
+ size += _single_optionalInt32Wrapper_codec.CalculateSizeWithTag(OptionalInt32Wrapper);
+ }
+ if (optionalInt64Wrapper_ != null) {
+ size += _single_optionalInt64Wrapper_codec.CalculateSizeWithTag(OptionalInt64Wrapper);
+ }
+ if (optionalUint32Wrapper_ != null) {
+ size += _single_optionalUint32Wrapper_codec.CalculateSizeWithTag(OptionalUint32Wrapper);
+ }
+ if (optionalUint64Wrapper_ != null) {
+ size += _single_optionalUint64Wrapper_codec.CalculateSizeWithTag(OptionalUint64Wrapper);
+ }
+ if (optionalFloatWrapper_ != null) {
+ size += _single_optionalFloatWrapper_codec.CalculateSizeWithTag(OptionalFloatWrapper);
+ }
+ if (optionalDoubleWrapper_ != null) {
+ size += _single_optionalDoubleWrapper_codec.CalculateSizeWithTag(OptionalDoubleWrapper);
+ }
+ if (optionalStringWrapper_ != null) {
+ size += _single_optionalStringWrapper_codec.CalculateSizeWithTag(OptionalStringWrapper);
+ }
+ if (optionalBytesWrapper_ != null) {
+ size += _single_optionalBytesWrapper_codec.CalculateSizeWithTag(OptionalBytesWrapper);
+ }
+ size += repeatedBoolWrapper_.CalculateSize(_repeated_repeatedBoolWrapper_codec);
+ size += repeatedInt32Wrapper_.CalculateSize(_repeated_repeatedInt32Wrapper_codec);
+ size += repeatedInt64Wrapper_.CalculateSize(_repeated_repeatedInt64Wrapper_codec);
+ size += repeatedUint32Wrapper_.CalculateSize(_repeated_repeatedUint32Wrapper_codec);
+ size += repeatedUint64Wrapper_.CalculateSize(_repeated_repeatedUint64Wrapper_codec);
+ size += repeatedFloatWrapper_.CalculateSize(_repeated_repeatedFloatWrapper_codec);
+ size += repeatedDoubleWrapper_.CalculateSize(_repeated_repeatedDoubleWrapper_codec);
+ size += repeatedStringWrapper_.CalculateSize(_repeated_repeatedStringWrapper_codec);
+ size += repeatedBytesWrapper_.CalculateSize(_repeated_repeatedBytesWrapper_codec);
+ if (optionalDuration_ != null) {
+ size += 2 + pb::CodedOutputStream.ComputeMessageSize(OptionalDuration);
+ }
+ if (optionalTimestamp_ != null) {
+ size += 2 + pb::CodedOutputStream.ComputeMessageSize(OptionalTimestamp);
+ }
+ if (optionalFieldMask_ != null) {
+ size += 2 + pb::CodedOutputStream.ComputeMessageSize(OptionalFieldMask);
+ }
+ if (optionalStruct_ != null) {
+ size += 2 + pb::CodedOutputStream.ComputeMessageSize(OptionalStruct);
+ }
+ if (optionalAny_ != null) {
+ size += 2 + pb::CodedOutputStream.ComputeMessageSize(OptionalAny);
+ }
+ if (optionalValue_ != null) {
+ size += 2 + pb::CodedOutputStream.ComputeMessageSize(OptionalValue);
+ }
+ size += repeatedDuration_.CalculateSize(_repeated_repeatedDuration_codec);
+ size += repeatedTimestamp_.CalculateSize(_repeated_repeatedTimestamp_codec);
+ size += repeatedFieldmask_.CalculateSize(_repeated_repeatedFieldmask_codec);
+ size += repeatedStruct_.CalculateSize(_repeated_repeatedStruct_codec);
+ size += repeatedAny_.CalculateSize(_repeated_repeatedAny_codec);
+ size += repeatedValue_.CalculateSize(_repeated_repeatedValue_codec);
+ if (Fieldname1 != 0) {
+ size += 2 + pb::CodedOutputStream.ComputeInt32Size(Fieldname1);
+ }
+ if (FieldName2 != 0) {
+ size += 2 + pb::CodedOutputStream.ComputeInt32Size(FieldName2);
+ }
+ if (FieldName3 != 0) {
+ size += 2 + pb::CodedOutputStream.ComputeInt32Size(FieldName3);
+ }
+ if (FieldName4 != 0) {
+ size += 2 + pb::CodedOutputStream.ComputeInt32Size(FieldName4);
+ }
+ if (Field0Name5 != 0) {
+ size += 2 + pb::CodedOutputStream.ComputeInt32Size(Field0Name5);
+ }
+ if (Field0Name6 != 0) {
+ size += 2 + pb::CodedOutputStream.ComputeInt32Size(Field0Name6);
+ }
+ if (FieldName7 != 0) {
+ size += 2 + pb::CodedOutputStream.ComputeInt32Size(FieldName7);
+ }
+ if (FieldName8 != 0) {
+ size += 2 + pb::CodedOutputStream.ComputeInt32Size(FieldName8);
+ }
+ if (FieldName9 != 0) {
+ size += 2 + pb::CodedOutputStream.ComputeInt32Size(FieldName9);
+ }
+ if (FieldName10 != 0) {
+ size += 2 + pb::CodedOutputStream.ComputeInt32Size(FieldName10);
+ }
+ if (FIELDNAME11 != 0) {
+ size += 2 + pb::CodedOutputStream.ComputeInt32Size(FIELDNAME11);
+ }
+ if (FIELDName12 != 0) {
+ size += 2 + pb::CodedOutputStream.ComputeInt32Size(FIELDName12);
+ }
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(TestAllTypes other) {
if (other == null) {
return;
@@ -1878,10 +2879,10 @@ namespace Conformance {
}
OptionalForeignMessage.MergeFrom(other.OptionalForeignMessage);
}
- if (other.OptionalNestedEnum != global::Conformance.TestAllTypes.Types.NestedEnum.FOO) {
+ if (other.OptionalNestedEnum != 0) {
OptionalNestedEnum = other.OptionalNestedEnum;
}
- if (other.OptionalForeignEnum != global::Conformance.ForeignEnum.FOREIGN_FOO) {
+ if (other.OptionalForeignEnum != 0) {
OptionalForeignEnum = other.OptionalForeignEnum;
}
if (other.OptionalStringPiece.Length != 0) {
@@ -1936,6 +2937,138 @@ namespace Conformance {
mapStringForeignMessage_.Add(other.mapStringForeignMessage_);
mapStringNestedEnum_.Add(other.mapStringNestedEnum_);
mapStringForeignEnum_.Add(other.mapStringForeignEnum_);
+ if (other.optionalBoolWrapper_ != null) {
+ if (optionalBoolWrapper_ == null || other.OptionalBoolWrapper != false) {
+ OptionalBoolWrapper = other.OptionalBoolWrapper;
+ }
+ }
+ if (other.optionalInt32Wrapper_ != null) {
+ if (optionalInt32Wrapper_ == null || other.OptionalInt32Wrapper != 0) {
+ OptionalInt32Wrapper = other.OptionalInt32Wrapper;
+ }
+ }
+ if (other.optionalInt64Wrapper_ != null) {
+ if (optionalInt64Wrapper_ == null || other.OptionalInt64Wrapper != 0L) {
+ OptionalInt64Wrapper = other.OptionalInt64Wrapper;
+ }
+ }
+ if (other.optionalUint32Wrapper_ != null) {
+ if (optionalUint32Wrapper_ == null || other.OptionalUint32Wrapper != 0) {
+ OptionalUint32Wrapper = other.OptionalUint32Wrapper;
+ }
+ }
+ if (other.optionalUint64Wrapper_ != null) {
+ if (optionalUint64Wrapper_ == null || other.OptionalUint64Wrapper != 0UL) {
+ OptionalUint64Wrapper = other.OptionalUint64Wrapper;
+ }
+ }
+ if (other.optionalFloatWrapper_ != null) {
+ if (optionalFloatWrapper_ == null || other.OptionalFloatWrapper != 0F) {
+ OptionalFloatWrapper = other.OptionalFloatWrapper;
+ }
+ }
+ if (other.optionalDoubleWrapper_ != null) {
+ if (optionalDoubleWrapper_ == null || other.OptionalDoubleWrapper != 0D) {
+ OptionalDoubleWrapper = other.OptionalDoubleWrapper;
+ }
+ }
+ if (other.optionalStringWrapper_ != null) {
+ if (optionalStringWrapper_ == null || other.OptionalStringWrapper != "") {
+ OptionalStringWrapper = other.OptionalStringWrapper;
+ }
+ }
+ if (other.optionalBytesWrapper_ != null) {
+ if (optionalBytesWrapper_ == null || other.OptionalBytesWrapper != pb::ByteString.Empty) {
+ OptionalBytesWrapper = other.OptionalBytesWrapper;
+ }
+ }
+ repeatedBoolWrapper_.Add(other.repeatedBoolWrapper_);
+ repeatedInt32Wrapper_.Add(other.repeatedInt32Wrapper_);
+ repeatedInt64Wrapper_.Add(other.repeatedInt64Wrapper_);
+ repeatedUint32Wrapper_.Add(other.repeatedUint32Wrapper_);
+ repeatedUint64Wrapper_.Add(other.repeatedUint64Wrapper_);
+ repeatedFloatWrapper_.Add(other.repeatedFloatWrapper_);
+ repeatedDoubleWrapper_.Add(other.repeatedDoubleWrapper_);
+ repeatedStringWrapper_.Add(other.repeatedStringWrapper_);
+ repeatedBytesWrapper_.Add(other.repeatedBytesWrapper_);
+ if (other.optionalDuration_ != null) {
+ if (optionalDuration_ == null) {
+ optionalDuration_ = new global::Google.Protobuf.WellKnownTypes.Duration();
+ }
+ OptionalDuration.MergeFrom(other.OptionalDuration);
+ }
+ if (other.optionalTimestamp_ != null) {
+ if (optionalTimestamp_ == null) {
+ optionalTimestamp_ = new global::Google.Protobuf.WellKnownTypes.Timestamp();
+ }
+ OptionalTimestamp.MergeFrom(other.OptionalTimestamp);
+ }
+ if (other.optionalFieldMask_ != null) {
+ if (optionalFieldMask_ == null) {
+ optionalFieldMask_ = new global::Google.Protobuf.WellKnownTypes.FieldMask();
+ }
+ OptionalFieldMask.MergeFrom(other.OptionalFieldMask);
+ }
+ if (other.optionalStruct_ != null) {
+ if (optionalStruct_ == null) {
+ optionalStruct_ = new global::Google.Protobuf.WellKnownTypes.Struct();
+ }
+ OptionalStruct.MergeFrom(other.OptionalStruct);
+ }
+ if (other.optionalAny_ != null) {
+ if (optionalAny_ == null) {
+ optionalAny_ = new global::Google.Protobuf.WellKnownTypes.Any();
+ }
+ OptionalAny.MergeFrom(other.OptionalAny);
+ }
+ if (other.optionalValue_ != null) {
+ if (optionalValue_ == null) {
+ optionalValue_ = new global::Google.Protobuf.WellKnownTypes.Value();
+ }
+ OptionalValue.MergeFrom(other.OptionalValue);
+ }
+ repeatedDuration_.Add(other.repeatedDuration_);
+ repeatedTimestamp_.Add(other.repeatedTimestamp_);
+ repeatedFieldmask_.Add(other.repeatedFieldmask_);
+ repeatedStruct_.Add(other.repeatedStruct_);
+ repeatedAny_.Add(other.repeatedAny_);
+ repeatedValue_.Add(other.repeatedValue_);
+ if (other.Fieldname1 != 0) {
+ Fieldname1 = other.Fieldname1;
+ }
+ if (other.FieldName2 != 0) {
+ FieldName2 = other.FieldName2;
+ }
+ if (other.FieldName3 != 0) {
+ FieldName3 = other.FieldName3;
+ }
+ if (other.FieldName4 != 0) {
+ FieldName4 = other.FieldName4;
+ }
+ if (other.Field0Name5 != 0) {
+ Field0Name5 = other.Field0Name5;
+ }
+ if (other.Field0Name6 != 0) {
+ Field0Name6 = other.Field0Name6;
+ }
+ if (other.FieldName7 != 0) {
+ FieldName7 = other.FieldName7;
+ }
+ if (other.FieldName8 != 0) {
+ FieldName8 = other.FieldName8;
+ }
+ if (other.FieldName9 != 0) {
+ FieldName9 = other.FieldName9;
+ }
+ if (other.FieldName10 != 0) {
+ FieldName10 = other.FieldName10;
+ }
+ if (other.FIELDNAME11 != 0) {
+ FIELDNAME11 = other.FIELDNAME11;
+ }
+ if (other.FIELDName12 != 0) {
+ FIELDName12 = other.FIELDName12;
+ }
switch (other.OneofFieldCase) {
case OneofFieldOneofCase.OneofUint32:
OneofUint32 = other.OneofUint32;
@@ -1953,6 +3086,7 @@ namespace Conformance {
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -2253,48 +3387,266 @@ namespace Conformance {
OneofBytes = input.ReadBytes();
break;
}
+ case 1610: {
+ bool? value = _single_optionalBoolWrapper_codec.Read(input);
+ if (optionalBoolWrapper_ == null || value != false) {
+ OptionalBoolWrapper = value;
+ }
+ break;
+ }
+ case 1618: {
+ int? value = _single_optionalInt32Wrapper_codec.Read(input);
+ if (optionalInt32Wrapper_ == null || value != 0) {
+ OptionalInt32Wrapper = value;
+ }
+ break;
+ }
+ case 1626: {
+ long? value = _single_optionalInt64Wrapper_codec.Read(input);
+ if (optionalInt64Wrapper_ == null || value != 0L) {
+ OptionalInt64Wrapper = value;
+ }
+ break;
+ }
+ case 1634: {
+ uint? value = _single_optionalUint32Wrapper_codec.Read(input);
+ if (optionalUint32Wrapper_ == null || value != 0) {
+ OptionalUint32Wrapper = value;
+ }
+ break;
+ }
+ case 1642: {
+ ulong? value = _single_optionalUint64Wrapper_codec.Read(input);
+ if (optionalUint64Wrapper_ == null || value != 0UL) {
+ OptionalUint64Wrapper = value;
+ }
+ break;
+ }
+ case 1650: {
+ float? value = _single_optionalFloatWrapper_codec.Read(input);
+ if (optionalFloatWrapper_ == null || value != 0F) {
+ OptionalFloatWrapper = value;
+ }
+ break;
+ }
+ case 1658: {
+ double? value = _single_optionalDoubleWrapper_codec.Read(input);
+ if (optionalDoubleWrapper_ == null || value != 0D) {
+ OptionalDoubleWrapper = value;
+ }
+ break;
+ }
+ case 1666: {
+ string value = _single_optionalStringWrapper_codec.Read(input);
+ if (optionalStringWrapper_ == null || value != "") {
+ OptionalStringWrapper = value;
+ }
+ break;
+ }
+ case 1674: {
+ pb::ByteString value = _single_optionalBytesWrapper_codec.Read(input);
+ if (optionalBytesWrapper_ == null || value != pb::ByteString.Empty) {
+ OptionalBytesWrapper = value;
+ }
+ break;
+ }
+ case 1690: {
+ repeatedBoolWrapper_.AddEntriesFrom(input, _repeated_repeatedBoolWrapper_codec);
+ break;
+ }
+ case 1698: {
+ repeatedInt32Wrapper_.AddEntriesFrom(input, _repeated_repeatedInt32Wrapper_codec);
+ break;
+ }
+ case 1706: {
+ repeatedInt64Wrapper_.AddEntriesFrom(input, _repeated_repeatedInt64Wrapper_codec);
+ break;
+ }
+ case 1714: {
+ repeatedUint32Wrapper_.AddEntriesFrom(input, _repeated_repeatedUint32Wrapper_codec);
+ break;
+ }
+ case 1722: {
+ repeatedUint64Wrapper_.AddEntriesFrom(input, _repeated_repeatedUint64Wrapper_codec);
+ break;
+ }
+ case 1730: {
+ repeatedFloatWrapper_.AddEntriesFrom(input, _repeated_repeatedFloatWrapper_codec);
+ break;
+ }
+ case 1738: {
+ repeatedDoubleWrapper_.AddEntriesFrom(input, _repeated_repeatedDoubleWrapper_codec);
+ break;
+ }
+ case 1746: {
+ repeatedStringWrapper_.AddEntriesFrom(input, _repeated_repeatedStringWrapper_codec);
+ break;
+ }
+ case 1754: {
+ repeatedBytesWrapper_.AddEntriesFrom(input, _repeated_repeatedBytesWrapper_codec);
+ break;
+ }
+ case 2410: {
+ if (optionalDuration_ == null) {
+ optionalDuration_ = new global::Google.Protobuf.WellKnownTypes.Duration();
+ }
+ input.ReadMessage(optionalDuration_);
+ break;
+ }
+ case 2418: {
+ if (optionalTimestamp_ == null) {
+ optionalTimestamp_ = new global::Google.Protobuf.WellKnownTypes.Timestamp();
+ }
+ input.ReadMessage(optionalTimestamp_);
+ break;
+ }
+ case 2426: {
+ if (optionalFieldMask_ == null) {
+ optionalFieldMask_ = new global::Google.Protobuf.WellKnownTypes.FieldMask();
+ }
+ input.ReadMessage(optionalFieldMask_);
+ break;
+ }
+ case 2434: {
+ if (optionalStruct_ == null) {
+ optionalStruct_ = new global::Google.Protobuf.WellKnownTypes.Struct();
+ }
+ input.ReadMessage(optionalStruct_);
+ break;
+ }
+ case 2442: {
+ if (optionalAny_ == null) {
+ optionalAny_ = new global::Google.Protobuf.WellKnownTypes.Any();
+ }
+ input.ReadMessage(optionalAny_);
+ break;
+ }
+ case 2450: {
+ if (optionalValue_ == null) {
+ optionalValue_ = new global::Google.Protobuf.WellKnownTypes.Value();
+ }
+ input.ReadMessage(optionalValue_);
+ break;
+ }
+ case 2490: {
+ repeatedDuration_.AddEntriesFrom(input, _repeated_repeatedDuration_codec);
+ break;
+ }
+ case 2498: {
+ repeatedTimestamp_.AddEntriesFrom(input, _repeated_repeatedTimestamp_codec);
+ break;
+ }
+ case 2506: {
+ repeatedFieldmask_.AddEntriesFrom(input, _repeated_repeatedFieldmask_codec);
+ break;
+ }
+ case 2522: {
+ repeatedAny_.AddEntriesFrom(input, _repeated_repeatedAny_codec);
+ break;
+ }
+ case 2530: {
+ repeatedValue_.AddEntriesFrom(input, _repeated_repeatedValue_codec);
+ break;
+ }
+ case 2594: {
+ repeatedStruct_.AddEntriesFrom(input, _repeated_repeatedStruct_codec);
+ break;
+ }
+ case 3208: {
+ Fieldname1 = input.ReadInt32();
+ break;
+ }
+ case 3216: {
+ FieldName2 = input.ReadInt32();
+ break;
+ }
+ case 3224: {
+ FieldName3 = input.ReadInt32();
+ break;
+ }
+ case 3232: {
+ FieldName4 = input.ReadInt32();
+ break;
+ }
+ case 3240: {
+ Field0Name5 = input.ReadInt32();
+ break;
+ }
+ case 3248: {
+ Field0Name6 = input.ReadInt32();
+ break;
+ }
+ case 3256: {
+ FieldName7 = input.ReadInt32();
+ break;
+ }
+ case 3264: {
+ FieldName8 = input.ReadInt32();
+ break;
+ }
+ case 3272: {
+ FieldName9 = input.ReadInt32();
+ break;
+ }
+ case 3280: {
+ FieldName10 = input.ReadInt32();
+ break;
+ }
+ case 3288: {
+ FIELDNAME11 = input.ReadInt32();
+ break;
+ }
+ case 3296: {
+ FIELDName12 = input.ReadInt32();
+ break;
+ }
}
}
}
#region Nested types
/// <summary>Container for nested types declared in the TestAllTypes message type.</summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static partial class Types {
public enum NestedEnum {
- FOO = 0,
- BAR = 1,
- BAZ = 2,
+ [pbr::OriginalName("FOO")] Foo = 0,
+ [pbr::OriginalName("BAR")] Bar = 1,
+ [pbr::OriginalName("BAZ")] Baz = 2,
/// <summary>
/// Intentionally negative.
/// </summary>
- NEG = -1,
+ [pbr::OriginalName("NEG")] Neg = -1,
}
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class NestedMessage : pb::IMessage<NestedMessage> {
private static readonly pb::MessageParser<NestedMessage> _parser = new pb::MessageParser<NestedMessage>(() => new NestedMessage());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<NestedMessage> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Conformance.TestAllTypes.Descriptor.NestedTypes[0]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public NestedMessage() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public NestedMessage(NestedMessage other) : this() {
a_ = other.a_;
Corecursive = other.corecursive_ != null ? other.Corecursive.Clone() : null;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public NestedMessage Clone() {
return new NestedMessage(this);
}
@@ -2302,6 +3654,7 @@ namespace Conformance {
/// <summary>Field number for the "a" field.</summary>
public const int AFieldNumber = 1;
private int a_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int A {
get { return a_; }
set {
@@ -2312,6 +3665,7 @@ namespace Conformance {
/// <summary>Field number for the "corecursive" field.</summary>
public const int CorecursiveFieldNumber = 2;
private global::Conformance.TestAllTypes corecursive_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Conformance.TestAllTypes Corecursive {
get { return corecursive_; }
set {
@@ -2319,10 +3673,12 @@ namespace Conformance {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as NestedMessage);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(NestedMessage other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -2335,6 +3691,7 @@ namespace Conformance {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (A != 0) hash ^= A.GetHashCode();
@@ -2342,10 +3699,12 @@ namespace Conformance {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (A != 0) {
output.WriteRawTag(8);
@@ -2357,6 +3716,7 @@ namespace Conformance {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (A != 0) {
@@ -2368,6 +3728,7 @@ namespace Conformance {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(NestedMessage other) {
if (other == null) {
return;
@@ -2383,6 +3744,7 @@ namespace Conformance {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -2412,29 +3774,34 @@ namespace Conformance {
}
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class ForeignMessage : pb::IMessage<ForeignMessage> {
private static readonly pb::MessageParser<ForeignMessage> _parser = new pb::MessageParser<ForeignMessage>(() => new ForeignMessage());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<ForeignMessage> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Conformance.ConformanceReflection.Descriptor.MessageTypes[3]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ForeignMessage() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ForeignMessage(ForeignMessage other) : this() {
c_ = other.c_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ForeignMessage Clone() {
return new ForeignMessage(this);
}
@@ -2442,6 +3809,7 @@ namespace Conformance {
/// <summary>Field number for the "c" field.</summary>
public const int CFieldNumber = 1;
private int c_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int C {
get { return c_; }
set {
@@ -2449,10 +3817,12 @@ namespace Conformance {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as ForeignMessage);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(ForeignMessage other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -2464,16 +3834,19 @@ namespace Conformance {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (C != 0) hash ^= C.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (C != 0) {
output.WriteRawTag(8);
@@ -2481,6 +3854,7 @@ namespace Conformance {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (C != 0) {
@@ -2489,6 +3863,7 @@ namespace Conformance {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(ForeignMessage other) {
if (other == null) {
return;
@@ -2498,6 +3873,7 @@ namespace Conformance {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
diff --git a/csharp/src/Google.Protobuf.Conformance/Google.Protobuf.Conformance.csproj b/csharp/src/Google.Protobuf.Conformance/Google.Protobuf.Conformance.csproj
deleted file mode 100644
index 82f728d1..00000000
--- a/csharp/src/Google.Protobuf.Conformance/Google.Protobuf.Conformance.csproj
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ProjectGuid>{0607D1B8-80D6-4B35-9857-1263C1B32B94}</ProjectGuid>
- <OutputType>Exe</OutputType>
- <AppDesignerFolder>Properties</AppDesignerFolder>
- <RootNamespace>Google.Protobuf.Conformance</RootNamespace>
- <AssemblyName>Google.Protobuf.Conformance</AssemblyName>
- <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
- <FileAlignment>512</FileAlignment>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <PlatformTarget>AnyCPU</PlatformTarget>
- <DebugSymbols>true</DebugSymbols>
- <DebugType>full</DebugType>
- <Optimize>false</Optimize>
- <OutputPath>bin\Debug\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <PlatformTarget>AnyCPU</PlatformTarget>
- <DebugType>pdbonly</DebugType>
- <Optimize>true</Optimize>
- <OutputPath>bin\Release\</OutputPath>
- <DefineConstants>TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <ItemGroup>
- <Reference Include="System" />
- <Reference Include="System.Core" />
- <Reference Include="Microsoft.CSharp" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="Conformance.cs" />
- <Compile Include="Program.cs" />
- <Compile Include="Properties\AssemblyInfo.cs" />
- </ItemGroup>
- <ItemGroup>
- <None Include="App.config" />
- </ItemGroup>
- <ItemGroup>
- <ProjectReference Include="..\Google.Protobuf\Google.Protobuf.csproj">
- <Project>{6908bdce-d925-43f3-94ac-a531e6df2591}</Project>
- <Name>Google.Protobuf</Name>
- </ProjectReference>
- </ItemGroup>
- <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
- Other similar extension points exist, see Microsoft.Common.targets.
- <Target Name="BeforeBuild">
- </Target>
- <Target Name="AfterBuild">
- </Target>
- -->
-</Project> \ No newline at end of file
diff --git a/csharp/src/Google.Protobuf.Conformance/Google.Protobuf.Conformance.xproj b/csharp/src/Google.Protobuf.Conformance/Google.Protobuf.Conformance.xproj
new file mode 100644
index 00000000..99ff1465
--- /dev/null
+++ b/csharp/src/Google.Protobuf.Conformance/Google.Protobuf.Conformance.xproj
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
+ <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
+ </PropertyGroup>
+ <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>dddc055b-e185-4181-bab0-072f0f984569</ProjectGuid>
+ <RootNamespace>Google.Protobuf.Conformance</RootNamespace>
+ <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
+ <OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
+ </PropertyGroup>
+
+ <PropertyGroup>
+ <SchemaVersion>2.0</SchemaVersion>
+ </PropertyGroup>
+ <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
+</Project> \ No newline at end of file
diff --git a/csharp/src/Google.Protobuf.Conformance/Program.cs b/csharp/src/Google.Protobuf.Conformance/Program.cs
index af92da9f..19827c48 100644
--- a/csharp/src/Google.Protobuf.Conformance/Program.cs
+++ b/csharp/src/Google.Protobuf.Conformance/Program.cs
@@ -31,6 +31,7 @@
#endregion
using Conformance;
+using Google.Protobuf.Reflection;
using System;
using System.IO;
@@ -47,16 +48,17 @@ namespace Google.Protobuf.Conformance
// This way we get the binary streams instead of readers/writers.
var input = new BinaryReader(Console.OpenStandardInput());
var output = new BinaryWriter(Console.OpenStandardOutput());
+ var typeRegistry = TypeRegistry.FromMessages(TestAllTypes.Descriptor);
int count = 0;
- while (RunTest(input, output))
+ while (RunTest(input, output, typeRegistry))
{
count++;
}
Console.Error.WriteLine("Received EOF after {0} tests", count);
}
- private static bool RunTest(BinaryReader input, BinaryWriter output)
+ private static bool RunTest(BinaryReader input, BinaryWriter output, TypeRegistry typeRegistry)
{
int? size = ReadInt32(input);
if (size == null)
@@ -69,7 +71,7 @@ namespace Google.Protobuf.Conformance
throw new EndOfStreamException("Read " + inputData.Length + " bytes of data when expecting " + size);
}
ConformanceRequest request = ConformanceRequest.Parser.ParseFrom(inputData);
- ConformanceResponse response = PerformRequest(request);
+ ConformanceResponse response = PerformRequest(request, typeRegistry);
byte[] outputData = response.ToByteArray();
output.Write(outputData.Length);
output.Write(outputData);
@@ -77,34 +79,48 @@ namespace Google.Protobuf.Conformance
return true;
}
- private static ConformanceResponse PerformRequest(ConformanceRequest request)
+ private static ConformanceResponse PerformRequest(ConformanceRequest request, TypeRegistry typeRegistry)
{
TestAllTypes message;
- switch (request.PayloadCase)
+ try
{
- case ConformanceRequest.PayloadOneofCase.JsonPayload:
- return new ConformanceResponse { Skipped = "JSON parsing not implemented in C# yet" };
- case ConformanceRequest.PayloadOneofCase.ProtobufPayload:
- try
- {
+ switch (request.PayloadCase)
+ {
+ case ConformanceRequest.PayloadOneofCase.JsonPayload:
+ var parser = new JsonParser(new JsonParser.Settings(20, typeRegistry));
+ message = parser.Parse<TestAllTypes>(request.JsonPayload);
+ break;
+ case ConformanceRequest.PayloadOneofCase.ProtobufPayload:
message = TestAllTypes.Parser.ParseFrom(request.ProtobufPayload);
- }
- catch (InvalidProtocolBufferException e)
- {
- return new ConformanceResponse { ParseError = e.Message };
- }
- break;
- default:
- throw new Exception("Unsupported request payload: " + request.PayloadCase);
+ break;
+ default:
+ throw new Exception("Unsupported request payload: " + request.PayloadCase);
+ }
}
- switch (request.RequestedOutputFormat)
+ catch (InvalidProtocolBufferException e)
{
- case global::Conformance.WireFormat.JSON:
- return new ConformanceResponse { JsonPayload = JsonFormatter.Default.Format(message) };
- case global::Conformance.WireFormat.PROTOBUF:
- return new ConformanceResponse { ProtobufPayload = message.ToByteString() };
- default:
- throw new Exception("Unsupported request output format: " + request.PayloadCase);
+ return new ConformanceResponse { ParseError = e.Message };
+ }
+ catch (InvalidJsonException e)
+ {
+ return new ConformanceResponse { ParseError = e.Message };
+ }
+ try
+ {
+ switch (request.RequestedOutputFormat)
+ {
+ case global::Conformance.WireFormat.Json:
+ var formatter = new JsonFormatter(new JsonFormatter.Settings(false, typeRegistry));
+ return new ConformanceResponse { JsonPayload = formatter.Format(message) };
+ case global::Conformance.WireFormat.Protobuf:
+ return new ConformanceResponse { ProtobufPayload = message.ToByteString() };
+ default:
+ throw new Exception("Unsupported request output format: " + request.PayloadCase);
+ }
+ }
+ catch (InvalidOperationException e)
+ {
+ return new ConformanceResponse { SerializeError = e.Message };
}
}
diff --git a/csharp/src/Google.Protobuf.Conformance/project.json b/csharp/src/Google.Protobuf.Conformance/project.json
new file mode 100644
index 00000000..84b23c45
--- /dev/null
+++ b/csharp/src/Google.Protobuf.Conformance/project.json
@@ -0,0 +1,19 @@
+{
+ "buildOptions": {
+ "debugType": "portable",
+ "emitEntryPoint": true
+ },
+ "dependencies": {
+ "Google.Protobuf": { "target": "project" }
+ },
+ "frameworks": {
+ "netcoreapp1.0": {
+ "dependencies": {
+ "Microsoft.NETCore.App": {
+ "type": "platform",
+ "version": "1.0.0"
+ }
+ }
+ }
+ }
+}
diff --git a/csharp/src/Google.Protobuf.JsonDump/Google.Protobuf.JsonDump.csproj b/csharp/src/Google.Protobuf.JsonDump/Google.Protobuf.JsonDump.csproj
deleted file mode 100644
index ede1f778..00000000
--- a/csharp/src/Google.Protobuf.JsonDump/Google.Protobuf.JsonDump.csproj
+++ /dev/null
@@ -1,68 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ProductVersion>9.0.30729</ProductVersion>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{D7282E99-2DC3-405B-946F-177DB2FD2AE2}</ProjectGuid>
- <OutputType>Exe</OutputType>
- <AppDesignerFolder>Properties</AppDesignerFolder>
- <RootNamespace>Google.Protobuf.JsonDump</RootNamespace>
- <AssemblyName>Google.Protobuf.JsonDump</AssemblyName>
- <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
- <FileAlignment>512</FileAlignment>
- <TargetFrameworkProfile>
- </TargetFrameworkProfile>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <DebugSymbols>true</DebugSymbols>
- <DebugType>full</DebugType>
- <Optimize>false</Optimize>
- <OutputPath>bin\Debug</OutputPath>
- <IntermediateOutputPath>obj\Debug\</IntermediateOutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- <NoStdLib>true</NoStdLib>
- <GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
- <Prefer32Bit>false</Prefer32Bit>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <DebugType>pdbonly</DebugType>
- <Optimize>true</Optimize>
- <OutputPath>bin\Release</OutputPath>
- <IntermediateOutputPath>obj\Release\</IntermediateOutputPath>
- <DefineConstants>TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- <NoStdLib>true</NoStdLib>
- <GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
- <Prefer32Bit>false</Prefer32Bit>
- </PropertyGroup>
- <ItemGroup>
- <Reference Include="mscorlib" />
- <Reference Include="System" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="Program.cs" />
- <Compile Include="Properties\AssemblyInfo.cs" />
- </ItemGroup>
- <ItemGroup>
- <ProjectReference Include="..\Google.Protobuf\Google.Protobuf.csproj">
- <Project>{6908BDCE-D925-43F3-94AC-A531E6DF2591}</Project>
- <Name>Google.Protobuf</Name>
- </ProjectReference>
- </ItemGroup>
- <ItemGroup>
- <None Include="app.config" />
- </ItemGroup>
- <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
- Other similar extension points exist, see Microsoft.Common.targets.
- <Target Name="BeforeBuild">
- </Target>
- <Target Name="AfterBuild">
- </Target>
- -->
-</Project> \ No newline at end of file
diff --git a/csharp/src/Google.Protobuf.JsonDump/Google.Protobuf.JsonDump.xproj b/csharp/src/Google.Protobuf.JsonDump/Google.Protobuf.JsonDump.xproj
new file mode 100644
index 00000000..27095be5
--- /dev/null
+++ b/csharp/src/Google.Protobuf.JsonDump/Google.Protobuf.JsonDump.xproj
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
+ <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
+ </PropertyGroup>
+ <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>9695e08f-9829-497d-b95c-b38f28d48690</ProjectGuid>
+ <RootNamespace>Google.Protobuf.JsonDump</RootNamespace>
+ <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
+ <OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
+ </PropertyGroup>
+
+ <PropertyGroup>
+ <SchemaVersion>2.0</SchemaVersion>
+ </PropertyGroup>
+ <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
+</Project> \ No newline at end of file
diff --git a/csharp/src/Google.Protobuf.JsonDump/Program.cs b/csharp/src/Google.Protobuf.JsonDump/Program.cs
index 99e60e90..296b2f3f 100644
--- a/csharp/src/Google.Protobuf.JsonDump/Program.cs
+++ b/csharp/src/Google.Protobuf.JsonDump/Program.cs
@@ -32,6 +32,7 @@
using System;
using System.IO;
+using System.Reflection;
namespace Google.Protobuf.ProtoDump
{
@@ -55,7 +56,7 @@ namespace Google.Protobuf.ProtoDump
Console.Error.WriteLine("Unable to load type {0}.", args[0]);
return 1;
}
- if (!typeof(IMessage).IsAssignableFrom(type))
+ if (!typeof(IMessage).GetTypeInfo().IsAssignableFrom(type))
{
Console.Error.WriteLine("Type {0} doesn't implement IMessage.", args[0]);
return 1;
diff --git a/csharp/src/Google.Protobuf.JsonDump/Properties/AssemblyInfo.cs b/csharp/src/Google.Protobuf.JsonDump/Properties/AssemblyInfo.cs
deleted file mode 100644
index d980b013..00000000
--- a/csharp/src/Google.Protobuf.JsonDump/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-
-[assembly: AssemblyTitle("ProtoDump")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("ProtoDump")]
-[assembly: AssemblyCopyright("Copyright © 2015")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-[assembly: AssemblyVersion("3.0.0.0")]
-[assembly: AssemblyFileVersion("3.0.0.0")]
diff --git a/csharp/src/Google.Protobuf.JsonDump/app.config b/csharp/src/Google.Protobuf.JsonDump/app.config
deleted file mode 100644
index 51278a45..00000000
--- a/csharp/src/Google.Protobuf.JsonDump/app.config
+++ /dev/null
@@ -1,3 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<configuration>
-<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/></startup></configuration>
diff --git a/csharp/src/Google.Protobuf.JsonDump/project.json b/csharp/src/Google.Protobuf.JsonDump/project.json
new file mode 100644
index 00000000..84b23c45
--- /dev/null
+++ b/csharp/src/Google.Protobuf.JsonDump/project.json
@@ -0,0 +1,19 @@
+{
+ "buildOptions": {
+ "debugType": "portable",
+ "emitEntryPoint": true
+ },
+ "dependencies": {
+ "Google.Protobuf": { "target": "project" }
+ },
+ "frameworks": {
+ "netcoreapp1.0": {
+ "dependencies": {
+ "Microsoft.NETCore.App": {
+ "type": "platform",
+ "version": "1.0.0"
+ }
+ }
+ }
+ }
+}
diff --git a/csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs b/csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs
index 6ae02112..c0a9ffd1 100644
--- a/csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs
+++ b/csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs
@@ -470,6 +470,52 @@ namespace Google.Protobuf
}
[Test]
+ public void SkipGroup_WrongEndGroupTag()
+ {
+ // Create an output stream with:
+ // Field 1: string "field 1"
+ // Start group 2
+ // Field 3: fixed int32
+ // End group 4 (should give an error)
+ var stream = new MemoryStream();
+ var output = new CodedOutputStream(stream);
+ output.WriteTag(1, WireFormat.WireType.LengthDelimited);
+ output.WriteString("field 1");
+
+ // The outer group...
+ output.WriteTag(2, WireFormat.WireType.StartGroup);
+ output.WriteTag(3, WireFormat.WireType.Fixed32);
+ output.WriteFixed32(100);
+ output.WriteTag(4, WireFormat.WireType.EndGroup);
+ output.Flush();
+ stream.Position = 0;
+
+ // Now act like a generated client
+ var input = new CodedInputStream(stream);
+ Assert.AreEqual(WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited), input.ReadTag());
+ Assert.AreEqual("field 1", input.ReadString());
+ Assert.AreEqual(WireFormat.MakeTag(2, WireFormat.WireType.StartGroup), input.ReadTag());
+ Assert.Throws<InvalidProtocolBufferException>(input.SkipLastField);
+ }
+
+ [Test]
+ public void RogueEndGroupTag()
+ {
+ // If we have an end-group tag without a leading start-group tag, generated
+ // code will just call SkipLastField... so that should fail.
+
+ var stream = new MemoryStream();
+ var output = new CodedOutputStream(stream);
+ output.WriteTag(1, WireFormat.WireType.EndGroup);
+ output.Flush();
+ stream.Position = 0;
+
+ var input = new CodedInputStream(stream);
+ Assert.AreEqual(WireFormat.MakeTag(1, WireFormat.WireType.EndGroup), input.ReadTag());
+ Assert.Throws<InvalidProtocolBufferException>(input.SkipLastField);
+ }
+
+ [Test]
public void EndOfStreamReachedWhileSkippingGroup()
{
var stream = new MemoryStream();
@@ -484,7 +530,7 @@ namespace Google.Protobuf
// Now act like a generated client
var input = new CodedInputStream(stream);
input.ReadTag();
- Assert.Throws<InvalidProtocolBufferException>(() => input.SkipLastField());
+ Assert.Throws<InvalidProtocolBufferException>(input.SkipLastField);
}
[Test]
@@ -506,7 +552,7 @@ namespace Google.Protobuf
// Now act like a generated client
var input = new CodedInputStream(stream);
Assert.AreEqual(WireFormat.MakeTag(1, WireFormat.WireType.StartGroup), input.ReadTag());
- Assert.Throws<InvalidProtocolBufferException>(() => input.SkipLastField());
+ Assert.Throws<InvalidProtocolBufferException>(input.SkipLastField);
}
[Test]
@@ -526,5 +572,27 @@ namespace Google.Protobuf
Assert.Throws<ArgumentOutOfRangeException>(() => CodedInputStream.CreateWithLimits(stream, 0, 1));
Assert.Throws<ArgumentOutOfRangeException>(() => CodedInputStream.CreateWithLimits(stream, 1, 0));
}
+
+ [Test]
+ public void Dispose_DisposesUnderlyingStream()
+ {
+ var memoryStream = new MemoryStream();
+ Assert.IsTrue(memoryStream.CanRead);
+ using (var cis = new CodedInputStream(memoryStream))
+ {
+ }
+ Assert.IsFalse(memoryStream.CanRead); // Disposed
+ }
+
+ [Test]
+ public void Dispose_WithLeaveOpen()
+ {
+ var memoryStream = new MemoryStream();
+ Assert.IsTrue(memoryStream.CanRead);
+ using (var cis = new CodedInputStream(memoryStream, true))
+ {
+ }
+ Assert.IsTrue(memoryStream.CanRead); // We left the stream open
+ }
}
} \ No newline at end of file
diff --git a/csharp/src/Google.Protobuf.Test/CodedOutputStreamTest.cs b/csharp/src/Google.Protobuf.Test/CodedOutputStreamTest.cs
index 3297fe87..48bf6d60 100644
--- a/csharp/src/Google.Protobuf.Test/CodedOutputStreamTest.cs
+++ b/csharp/src/Google.Protobuf.Test/CodedOutputStreamTest.cs
@@ -387,5 +387,33 @@ namespace Google.Protobuf
Assert.IsTrue(cin.IsAtEnd);
}
}
+
+ [Test]
+ public void Dispose_DisposesUnderlyingStream()
+ {
+ var memoryStream = new MemoryStream();
+ Assert.IsTrue(memoryStream.CanWrite);
+ using (var cos = new CodedOutputStream(memoryStream))
+ {
+ cos.WriteRawByte(0);
+ Assert.AreEqual(0, memoryStream.Position); // Not flushed yet
+ }
+ Assert.AreEqual(1, memoryStream.ToArray().Length); // Flushed data from CodedOutputStream to MemoryStream
+ Assert.IsFalse(memoryStream.CanWrite); // Disposed
+ }
+
+ [Test]
+ public void Dispose_WithLeaveOpen()
+ {
+ var memoryStream = new MemoryStream();
+ Assert.IsTrue(memoryStream.CanWrite);
+ using (var cos = new CodedOutputStream(memoryStream, true))
+ {
+ cos.WriteRawByte(0);
+ Assert.AreEqual(0, memoryStream.Position); // Not flushed yet
+ }
+ Assert.AreEqual(1, memoryStream.Position); // Flushed data from CodedOutputStream to MemoryStream
+ Assert.IsTrue(memoryStream.CanWrite); // We left the stream open
+ }
}
} \ No newline at end of file
diff --git a/csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.cs b/csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.cs
index ba82c0e8..9c845907 100644
--- a/csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.cs
+++ b/csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.cs
@@ -56,7 +56,7 @@ namespace Google.Protobuf.Collections
}
[Test]
- public void NullValues()
+ public void NullValuesProhibited()
{
TestNullValues<int?>(0);
TestNullValues("");
@@ -65,19 +65,12 @@ namespace Google.Protobuf.Collections
private void TestNullValues<T>(T nonNullValue)
{
- var map = new MapField<int, T>(false);
+ var map = new MapField<int, T>();
var nullValue = (T) (object) null;
Assert.Throws<ArgumentNullException>(() => map.Add(0, nullValue));
Assert.Throws<ArgumentNullException>(() => map[0] = nullValue);
map.Add(1, nonNullValue);
map[1] = nonNullValue;
-
- // Doesn't throw...
- map = new MapField<int, T>(true);
- map.Add(0, nullValue);
- map[0] = nullValue;
- map.Add(1, nonNullValue);
- map[1] = nonNullValue;
}
[Test]
@@ -161,27 +154,6 @@ namespace Google.Protobuf.Collections
}
[Test]
- public void EqualityHandlesNullValues()
- {
- var map1 = new MapField<string, ForeignMessage>();
- map1.Add("a", new ForeignMessage { C = 10 });
- map1.Add("b", null);
-
- var map2 = new MapField<string, ForeignMessage>();
- map2.Add("a", new ForeignMessage { C = 10 });
- map2.Add("b", null);
-
- EqualityTester.AssertEquality(map1, map2);
- // Check the null value isn't ignored entirely...
- Assert.IsTrue(map1.Remove("b"));
- EqualityTester.AssertInequality(map1, map2);
- map1.Add("b", new ForeignMessage());
- EqualityTester.AssertInequality(map1, map2);
- map1["b"] = null;
- EqualityTester.AssertEquality(map1, map2);
- }
-
- [Test]
public void Add_Dictionary()
{
var map1 = new MapField<string, string>
@@ -454,30 +426,6 @@ namespace Google.Protobuf.Collections
}
[Test]
- public void AllowNullValues_Property()
- {
- // Non-message reference type values are non-nullable by default, but can be overridden
- Assert.IsFalse(new MapField<int, string>().AllowsNullValues);
- Assert.IsFalse(new MapField<int, string>(false).AllowsNullValues);
- Assert.IsTrue(new MapField<int, string>(true).AllowsNullValues);
-
- // Non-nullable value type values are never nullable
- Assert.IsFalse(new MapField<int, int>().AllowsNullValues);
- Assert.IsFalse(new MapField<int, int>(false).AllowsNullValues);
- Assert.Throws<ArgumentException>(() => new MapField<int, int>(true));
-
- // Message type values are nullable by default, but can be overridden
- Assert.IsTrue(new MapField<int, TestAllTypes>().AllowsNullValues);
- Assert.IsFalse(new MapField<int, TestAllTypes>(false).AllowsNullValues);
- Assert.IsTrue(new MapField<int, TestAllTypes>(true).AllowsNullValues);
-
- // Nullable value type values are nullable by default, but can be overridden
- Assert.IsTrue(new MapField<int, int?>().AllowsNullValues);
- Assert.IsFalse(new MapField<int, int?>(false).AllowsNullValues);
- Assert.IsTrue(new MapField<int, int?>(true).AllowsNullValues);
- }
-
- [Test]
public void KeysReturnsLiveView()
{
var map = new MapField<string, string>();
diff --git a/csharp/src/Google.Protobuf.Test/Collections/RepeatedFieldTest.cs b/csharp/src/Google.Protobuf.Test/Collections/RepeatedFieldTest.cs
index 8ed54cfb..6852f75f 100644
--- a/csharp/src/Google.Protobuf.Test/Collections/RepeatedFieldTest.cs
+++ b/csharp/src/Google.Protobuf.Test/Collections/RepeatedFieldTest.cs
@@ -75,10 +75,96 @@ namespace Google.Protobuf.Collections
}
[Test]
- public void Add_RepeatedField()
+ public void AddRange_SlowPath()
+ {
+ var list = new RepeatedField<string>();
+ list.AddRange(new[] { "foo", "bar" }.Select(x => x));
+ Assert.AreEqual(2, list.Count);
+ Assert.AreEqual("foo", list[0]);
+ Assert.AreEqual("bar", list[1]);
+ }
+
+ [Test]
+ public void AddRange_SlowPath_NullsProhibited_ReferenceType()
+ {
+ var list = new RepeatedField<string>();
+ // It's okay for this to throw ArgumentNullException if necessary.
+ // It's not ideal, but not awful.
+ Assert.Catch<ArgumentException>(() => list.AddRange(new[] { "foo", null }.Select(x => x)));
+ }
+
+ [Test]
+ public void AddRange_SlowPath_NullsProhibited_NullableValueType()
+ {
+ var list = new RepeatedField<int?>();
+ // It's okay for this to throw ArgumentNullException if necessary.
+ // It's not ideal, but not awful.
+ Assert.Catch<ArgumentException>(() => list.AddRange(new[] { 20, (int?)null }.Select(x => x)));
+ }
+
+ [Test]
+ public void AddRange_Optimized_NonNullableValueType()
+ {
+ var list = new RepeatedField<int>();
+ list.AddRange(new List<int> { 20, 30 });
+ Assert.AreEqual(2, list.Count);
+ Assert.AreEqual(20, list[0]);
+ Assert.AreEqual(30, list[1]);
+ }
+
+ [Test]
+ public void AddRange_Optimized_ReferenceType()
+ {
+ var list = new RepeatedField<string>();
+ list.AddRange(new List<string> { "foo", "bar" });
+ Assert.AreEqual(2, list.Count);
+ Assert.AreEqual("foo", list[0]);
+ Assert.AreEqual("bar", list[1]);
+ }
+
+ [Test]
+ public void AddRange_Optimized_NullableValueType()
+ {
+ var list = new RepeatedField<int?>();
+ list.AddRange(new List<int?> { 20, 30 });
+ Assert.AreEqual(2, list.Count);
+ Assert.AreEqual((int?) 20, list[0]);
+ Assert.AreEqual((int?) 30, list[1]);
+ }
+
+ [Test]
+ public void AddRange_Optimized_NullsProhibited_ReferenceType()
+ {
+ // We don't just trust that a collection with a nullable element type doesn't contain nulls
+ var list = new RepeatedField<string>();
+ // It's okay for this to throw ArgumentNullException if necessary.
+ // It's not ideal, but not awful.
+ Assert.Catch<ArgumentException>(() => list.AddRange(new List<string> { "foo", null }));
+ }
+
+ [Test]
+ public void AddRange_Optimized_NullsProhibited_NullableValueType()
+ {
+ // We don't just trust that a collection with a nullable element type doesn't contain nulls
+ var list = new RepeatedField<int?>();
+ // It's okay for this to throw ArgumentNullException if necessary.
+ // It's not ideal, but not awful.
+ Assert.Catch<ArgumentException>(() => list.AddRange(new List<int?> { 20, null }));
+ }
+
+ [Test]
+ public void AddRange_AlreadyNotEmpty()
+ {
+ var list = new RepeatedField<int> { 1, 2, 3 };
+ list.AddRange(new List<int> { 4, 5, 6 });
+ CollectionAssert.AreEqual(new[] { 1, 2, 3, 4, 5, 6 }, list);
+ }
+
+ [Test]
+ public void AddRange_RepeatedField()
{
var list = new RepeatedField<string> { "original" };
- list.Add(new RepeatedField<string> { "foo", "bar" });
+ list.AddRange(new RepeatedField<string> { "foo", "bar" });
Assert.AreEqual(3, list.Count);
Assert.AreEqual("original", list[0]);
Assert.AreEqual("foo", list[1]);
diff --git a/csharp/src/Google.Protobuf.Test/Compatibility/TypeExtensionsTest.cs b/csharp/src/Google.Protobuf.Test/Compatibility/TypeExtensionsTest.cs
index f0c8d3bc..f430b06b 100644
--- a/csharp/src/Google.Protobuf.Test/Compatibility/TypeExtensionsTest.cs
+++ b/csharp/src/Google.Protobuf.Test/Compatibility/TypeExtensionsTest.cs
@@ -34,6 +34,7 @@ using System;
using System.Collections.Generic;
using System.Reflection;
+#if !DOTNET35
namespace Google.Protobuf.Compatibility
{
public class TypeExtensionsTest
@@ -51,24 +52,6 @@ namespace Google.Protobuf.Compatibility
}
[Test]
- [TestCase(typeof(int), true)]
- [TestCase(typeof(int?), true)]
- [TestCase(typeof(Nullable<>), true)]
- [TestCase(typeof(WireFormat.WireType), true)]
- [TestCase(typeof(string), false)]
- [TestCase(typeof(object), false)]
- [TestCase(typeof(Enum), false)]
- [TestCase(typeof(ValueType), false)]
- [TestCase(typeof(TypeExtensionsTest), false)]
- [TestCase(typeof(Action), false)]
- [TestCase(typeof(Action<>), false)]
- [TestCase(typeof(IDisposable), false)]
- public void IsValueType(Type type, bool expected)
- {
- Assert.AreEqual(expected, TypeExtensions.IsValueType(type));
- }
-
- [Test]
[TestCase(typeof(object), typeof(string), true)]
[TestCase(typeof(object), typeof(int), true)]
[TestCase(typeof(string), typeof(string), true)]
@@ -131,3 +114,4 @@ namespace Google.Protobuf.Compatibility
}
}
}
+#endif
diff --git a/csharp/src/Google.Protobuf.Test/FieldCodecTest.cs b/csharp/src/Google.Protobuf.Test/FieldCodecTest.cs
index 38ba227f..0e2bad59 100644
--- a/csharp/src/Google.Protobuf.Test/FieldCodecTest.cs
+++ b/csharp/src/Google.Protobuf.Test/FieldCodecTest.cs
@@ -32,6 +32,7 @@
using System.Collections.Generic;
using System.IO;
+using System.Reflection;
using Google.Protobuf.TestProtos;
using NUnit.Framework;
@@ -58,7 +59,7 @@ namespace Google.Protobuf
new FieldCodecTestData<float>(FieldCodec.ForFloat(100), 1234.5f, "Float"),
new FieldCodecTestData<double>(FieldCodec.ForDouble(100), 1234567890.5d, "Double"),
new FieldCodecTestData<ForeignEnum>(
- FieldCodec.ForEnum(100, t => (int) t, t => (ForeignEnum) t), ForeignEnum.FOREIGN_BAZ, "Enum"),
+ FieldCodec.ForEnum(100, t => (int) t, t => (ForeignEnum) t), ForeignEnum.ForeignBaz, "Enum"),
new FieldCodecTestData<ForeignMessage>(
FieldCodec.ForMessage(100, ForeignMessage.Parser), new ForeignMessage { C = 10 }, "Message"),
};
@@ -162,7 +163,7 @@ namespace Google.Protobuf
codedOutput.Flush();
Assert.AreEqual(0, stream.Position);
Assert.AreEqual(0, codec.CalculateSizeWithTag(codec.DefaultValue));
- if (typeof(T).IsValueType)
+ if (typeof(T).GetTypeInfo().IsValueType)
{
Assert.AreEqual(default(T), codec.DefaultValue);
}
diff --git a/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs b/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs
index 1163f524..8b153d69 100644
--- a/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs
+++ b/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs
@@ -66,13 +66,13 @@ namespace Google.Protobuf
Assert.AreEqual(0, message.SingleFixed32);
Assert.AreEqual(0L, message.SingleFixed64);
Assert.AreEqual(0.0f, message.SingleFloat);
- Assert.AreEqual(ForeignEnum.FOREIGN_UNSPECIFIED, message.SingleForeignEnum);
+ Assert.AreEqual(ForeignEnum.ForeignUnspecified, message.SingleForeignEnum);
Assert.IsNull(message.SingleForeignMessage);
- Assert.AreEqual(ImportEnum.IMPORT_ENUM_UNSPECIFIED, message.SingleImportEnum);
+ Assert.AreEqual(ImportEnum.Unspecified, message.SingleImportEnum);
Assert.IsNull(message.SingleImportMessage);
Assert.AreEqual(0, message.SingleInt32);
Assert.AreEqual(0L, message.SingleInt64);
- Assert.AreEqual(TestAllTypes.Types.NestedEnum.NESTED_ENUM_UNSPECIFIED, message.SingleNestedEnum);
+ Assert.AreEqual(TestAllTypes.Types.NestedEnum.Unspecified, message.SingleNestedEnum);
Assert.IsNull(message.SingleNestedMessage);
Assert.IsNull(message.SinglePublicImportMessage);
Assert.AreEqual(0, message.SingleSfixed32);
@@ -145,13 +145,13 @@ namespace Google.Protobuf
SingleFixed32 = 23,
SingleFixed64 = 1234567890123,
SingleFloat = 12.25f,
- SingleForeignEnum = ForeignEnum.FOREIGN_BAR,
+ SingleForeignEnum = ForeignEnum.ForeignBar,
SingleForeignMessage = new ForeignMessage { C = 10 },
- SingleImportEnum = ImportEnum.IMPORT_BAZ,
+ SingleImportEnum = ImportEnum.ImportBaz,
SingleImportMessage = new ImportMessage { D = 20 },
SingleInt32 = 100,
SingleInt64 = 3210987654321,
- SingleNestedEnum = TestAllTypes.Types.NestedEnum.FOO,
+ SingleNestedEnum = TestAllTypes.Types.NestedEnum.Foo,
SingleNestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 35 },
SinglePublicImportMessage = new PublicImportMessage { E = 54 },
SingleSfixed32 = -123,
@@ -179,13 +179,13 @@ namespace Google.Protobuf
RepeatedFixed32 = { uint.MaxValue, 23 },
RepeatedFixed64 = { ulong.MaxValue, 1234567890123 },
RepeatedFloat = { 100f, 12.25f },
- RepeatedForeignEnum = { ForeignEnum.FOREIGN_FOO, ForeignEnum.FOREIGN_BAR },
+ RepeatedForeignEnum = { ForeignEnum.ForeignFoo, ForeignEnum.ForeignBar },
RepeatedForeignMessage = { new ForeignMessage(), new ForeignMessage { C = 10 } },
- RepeatedImportEnum = { ImportEnum.IMPORT_BAZ, ImportEnum.IMPORT_ENUM_UNSPECIFIED },
+ RepeatedImportEnum = { ImportEnum.ImportBaz, ImportEnum.Unspecified },
RepeatedImportMessage = { new ImportMessage { D = 20 }, new ImportMessage { D = 25 } },
RepeatedInt32 = { 100, 200 },
RepeatedInt64 = { 3210987654321, long.MaxValue },
- RepeatedNestedEnum = { TestAllTypes.Types.NestedEnum.FOO, TestAllTypes.Types.NestedEnum.NEG },
+ RepeatedNestedEnum = { TestAllTypes.Types.NestedEnum.Foo, TestAllTypes.Types.NestedEnum.Neg },
RepeatedNestedMessage = { new TestAllTypes.Types.NestedMessage { Bb = 35 }, new TestAllTypes.Types.NestedMessage { Bb = 10 } },
RepeatedPublicImportMessage = { new PublicImportMessage { E = 54 }, new PublicImportMessage { E = -1 } },
RepeatedSfixed32 = { -123, 123 },
@@ -221,11 +221,11 @@ namespace Google.Protobuf
},
MapInt32ForeignMessage = {
{ 0, new ForeignMessage { C = 10 } },
- { 5, null },
+ { 5, new ForeignMessage() },
},
MapInt32Enum = {
- { 1, MapEnum.MAP_ENUM_BAR },
- { 2000, MapEnum.MAP_ENUM_FOO }
+ { 1, MapEnum.Bar },
+ { 2000, MapEnum.Foo }
}
};
@@ -249,7 +249,7 @@ namespace Google.Protobuf
Assert.AreEqual(1, parsed.MapInt32Bytes.Count);
Assert.AreEqual(ByteString.Empty, parsed.MapInt32Bytes[0]);
}
-
+
[Test]
public void MapWithOnlyValue()
{
@@ -269,6 +269,40 @@ namespace Google.Protobuf
}
[Test]
+ public void MapWithOnlyKey_PrimitiveValue()
+ {
+ // Hand-craft the stream to contain a single entry with just a key.
+ var memoryStream = new MemoryStream();
+ var output = new CodedOutputStream(memoryStream);
+ output.WriteTag(TestMap.MapInt32DoubleFieldNumber, WireFormat.WireType.LengthDelimited);
+ int key = 10;
+ output.WriteLength(1 + CodedOutputStream.ComputeInt32Size(key));
+ output.WriteTag(1, WireFormat.WireType.Varint);
+ output.WriteInt32(key);
+ output.Flush();
+
+ var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray());
+ Assert.AreEqual(0.0, parsed.MapInt32Double[key]);
+ }
+
+ [Test]
+ public void MapWithOnlyKey_MessageValue()
+ {
+ // Hand-craft the stream to contain a single entry with just a key.
+ var memoryStream = new MemoryStream();
+ var output = new CodedOutputStream(memoryStream);
+ output.WriteTag(TestMap.MapInt32ForeignMessageFieldNumber, WireFormat.WireType.LengthDelimited);
+ int key = 10;
+ output.WriteLength(1 + CodedOutputStream.ComputeInt32Size(key));
+ output.WriteTag(1, WireFormat.WireType.Varint);
+ output.WriteInt32(key);
+ output.Flush();
+
+ var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray());
+ Assert.AreEqual(new ForeignMessage(), parsed.MapInt32ForeignMessage[key]);
+ }
+
+ [Test]
public void MapIgnoresExtraFieldsWithinEntryMessages()
{
// Hand-craft the stream to contain a single entry with three fields
@@ -415,7 +449,7 @@ namespace Google.Protobuf
SingleFloat = 12.25f,
SingleInt32 = 100,
SingleInt64 = 3210987654321,
- SingleNestedEnum = TestAllTypes.Types.NestedEnum.FOO,
+ SingleNestedEnum = TestAllTypes.Types.NestedEnum.Foo,
SingleSfixed32 = -123,
SingleSfixed64 = -12345678901234,
SingleSint32 = -456,
@@ -445,7 +479,7 @@ namespace Google.Protobuf
RepeatedFloat = { 100f, 12.25f },
RepeatedInt32 = { 100, 200 },
RepeatedInt64 = { 3210987654321, long.MaxValue },
- RepeatedNestedEnum = { TestAllTypes.Types.NestedEnum.FOO, TestAllTypes.Types.NestedEnum.NEG },
+ RepeatedNestedEnum = { TestAllTypes.Types.NestedEnum.Foo, TestAllTypes.Types.NestedEnum.Neg },
RepeatedSfixed32 = { -123, 123 },
RepeatedSfixed64 = { -12345678901234, 12345678901234 },
RepeatedSint32 = { -456, 100 },
@@ -636,7 +670,7 @@ namespace Google.Protobuf
{
// 130, 3 is the message tag
// 1 is the data length - but there's no data.
- var data = new byte[] { 130, 3, 1 };
+ var data = new byte[] { 130, 3, 1 };
Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseFrom(data));
}
@@ -645,21 +679,45 @@ namespace Google.Protobuf
/// for details; we may want to change this.
/// </summary>
[Test]
- public void ExtraEndGroupSkipped()
+ public void ExtraEndGroupThrows()
{
var message = SampleMessages.CreateFullTestAllTypes();
var stream = new MemoryStream();
var output = new CodedOutputStream(stream);
- output.WriteTag(100, WireFormat.WireType.EndGroup);
output.WriteTag(TestAllTypes.SingleFixed32FieldNumber, WireFormat.WireType.Fixed32);
output.WriteFixed32(123);
+ output.WriteTag(100, WireFormat.WireType.EndGroup);
output.Flush();
stream.Position = 0;
- var parsed = TestAllTypes.Parser.ParseFrom(stream);
- Assert.AreEqual(new TestAllTypes { SingleFixed32 = 123 }, parsed);
+ Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseFrom(stream));
+ }
+
+ [Test]
+ public void CustomDiagnosticMessage_DirectToStringCall()
+ {
+ var message = new ForeignMessage { C = 31 };
+ Assert.AreEqual("{ \"c\": 31, \"@cInHex\": \"1f\" }", message.ToString());
+ Assert.AreEqual("{ \"c\": 31 }", JsonFormatter.Default.Format(message));
+ }
+
+ [Test]
+ public void CustomDiagnosticMessage_Nested()
+ {
+ var message = new TestAllTypes { SingleForeignMessage = new ForeignMessage { C = 16 } };
+ Assert.AreEqual("{ \"singleForeignMessage\": { \"c\": 16, \"@cInHex\": \"10\" } }", message.ToString());
+ Assert.AreEqual("{ \"singleForeignMessage\": { \"c\": 16 } }", JsonFormatter.Default.Format(message));
+ }
+
+ [Test]
+ public void CustomDiagnosticMessage_DirectToTextWriterCall()
+ {
+ var message = new ForeignMessage { C = 31 };
+ var writer = new StringWriter();
+ JsonFormatter.Default.Format(message, writer);
+ Assert.AreEqual("{ \"c\": 31 }", writer.ToString());
}
}
-}
+} \ No newline at end of file
diff --git a/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj b/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj
deleted file mode 100644
index 903454eb..00000000
--- a/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj
+++ /dev/null
@@ -1,141 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ProductVersion>9.0.30729</ProductVersion>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{DD01ED24-3750-4567-9A23-1DB676A15610}</ProjectGuid>
- <OutputType>Library</OutputType>
- <AppDesignerFolder>Properties</AppDesignerFolder>
- <RootNamespace>Google.Protobuf</RootNamespace>
- <AssemblyName>Google.Protobuf.Test</AssemblyName>
- <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
- <FileAlignment>512</FileAlignment>
- <OldToolsVersion>3.5</OldToolsVersion>
- <TargetFrameworkProfile>
- </TargetFrameworkProfile>
- <NuGetPackageImportStamp>
- </NuGetPackageImportStamp>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <DebugSymbols>true</DebugSymbols>
- <DebugType>full</DebugType>
- <Optimize>false</Optimize>
- <OutputPath>bin\Debug</OutputPath>
- <IntermediateOutputPath>obj\Debug\</IntermediateOutputPath>
- <DefineConstants>DEBUG;TRACE;$(EnvironmentFlavor);$(EnvironmentTemplate)</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- <NoStdLib>true</NoStdLib>
- <GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
- <Prefer32Bit>false</Prefer32Bit>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <DebugType>pdbonly</DebugType>
- <Optimize>true</Optimize>
- <OutputPath>bin\Release</OutputPath>
- <IntermediateOutputPath>obj\Release\</IntermediateOutputPath>
- <DefineConstants>TRACE;$(EnvironmentFlavor);$(EnvironmentTemplate)</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- <NoStdLib>true</NoStdLib>
- <GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
- <Prefer32Bit>false</Prefer32Bit>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseSigned|AnyCPU' ">
- <DebugType>pdbonly</DebugType>
- <Optimize>true</Optimize>
- <OutputPath>bin\ReleaseSigned</OutputPath>
- <IntermediateOutputPath>obj\ReleaseSigned\</IntermediateOutputPath>
- <DefineConstants>TRACE;$(EnvironmentFlavor);$(EnvironmentTemplate)</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- <NoStdLib>true</NoStdLib>
- <GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
- <Prefer32Bit>false</Prefer32Bit>
- <SignAssembly>True</SignAssembly>
- <AssemblyOriginatorKeyFile>C:\keys\Google.Protobuf.snk</AssemblyOriginatorKeyFile>
- </PropertyGroup>
- <ItemGroup>
- <Reference Include="mscorlib" />
- <Reference Include="nunit.core, Version=2.6.4.14350, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
- <HintPath>..\packages\NUnitTestAdapter.2.0.0\lib\nunit.core.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="nunit.core.interfaces, Version=2.6.4.14350, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
- <HintPath>..\packages\NUnitTestAdapter.2.0.0\lib\nunit.core.interfaces.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="nunit.framework, Version=2.6.4.14350, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
- <HintPath>..\packages\NUnit.2.6.4\lib\nunit.framework.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="nunit.util, Version=2.6.4.14350, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
- <HintPath>..\packages\NUnitTestAdapter.2.0.0\lib\nunit.util.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="NUnit.VisualStudio.TestAdapter, Version=2.0.0.0, Culture=neutral, PublicKeyToken=4cb40d35494691ac, processorArchitecture=MSIL">
- <HintPath>..\packages\NUnitTestAdapter.2.0.0\lib\NUnit.VisualStudio.TestAdapter.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="System" />
- <Reference Include="System.Xml" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="ByteStringTest.cs" />
- <Compile Include="CodedInputStreamExtensions.cs" />
- <Compile Include="CodedInputStreamTest.cs" />
- <Compile Include="CodedOutputStreamTest.cs" />
- <Compile Include="Compatibility\PropertyInfoExtensionsTest.cs" />
- <Compile Include="Compatibility\TypeExtensionsTest.cs" />
- <Compile Include="EqualityTester.cs" />
- <Compile Include="FieldCodecTest.cs" />
- <Compile Include="GeneratedMessageTest.cs" />
- <Compile Include="Collections\MapFieldTest.cs" />
- <Compile Include="Collections\RepeatedFieldTest.cs" />
- <Compile Include="JsonFormatterTest.cs" />
- <Compile Include="JsonParserTest.cs" />
- <Compile Include="JsonTokenizerTest.cs" />
- <Compile Include="Reflection\DescriptorsTest.cs" />
- <Compile Include="Reflection\FieldAccessTest.cs" />
- <Compile Include="Reflection\TypeRegistryTest.cs" />
- <Compile Include="SampleEnum.cs" />
- <Compile Include="SampleMessages.cs" />
- <Compile Include="TestProtos\MapUnittestProto3.cs" />
- <Compile Include="TestProtos\UnittestImportProto3.cs" />
- <Compile Include="TestProtos\UnittestImportPublicProto3.cs" />
- <Compile Include="TestProtos\UnittestIssues.cs" />
- <Compile Include="TestProtos\UnittestProto3.cs" />
- <Compile Include="DeprecatedMemberTest.cs" />
- <Compile Include="IssuesTest.cs" />
- <Compile Include="Properties\AssemblyInfo.cs" />
- <Compile Include="TestCornerCases.cs" />
- <Compile Include="TestProtos\UnittestWellKnownTypes.cs" />
- <Compile Include="WellKnownTypes\AnyTest.cs" />
- <Compile Include="WellKnownTypes\DurationTest.cs" />
- <Compile Include="WellKnownTypes\TimestampTest.cs" />
- <Compile Include="WellKnownTypes\WrappersTest.cs" />
- </ItemGroup>
- <ItemGroup>
- <ProjectReference Include="..\Google.Protobuf\Google.Protobuf.csproj">
- <Project>{6908BDCE-D925-43F3-94AC-A531E6DF2591}</Project>
- <Name>Google.Protobuf</Name>
- </ProjectReference>
- </ItemGroup>
- <ItemGroup>
- <None Include="packages.config" />
- </ItemGroup>
- <ItemGroup>
- <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
- </ItemGroup>
- <ItemGroup />
- <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
- Other similar extension points exist, see Microsoft.Common.targets.
- <Target Name="BeforeBuild">
- </Target>
- <Target Name="AfterBuild">
- </Target>
- -->
-</Project> \ No newline at end of file
diff --git a/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.xproj b/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.xproj
new file mode 100644
index 00000000..a9a1cc04
--- /dev/null
+++ b/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.xproj
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
+ <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
+ </PropertyGroup>
+ <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>580eb013-d3c7-4578-b845-015f4a3b0591</ProjectGuid>
+ <RootNamespace>Google.Protobuf.Test</RootNamespace>
+ <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
+ <OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
+ </PropertyGroup>
+
+ <PropertyGroup>
+ <SchemaVersion>2.0</SchemaVersion>
+ </PropertyGroup>
+ <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
+</Project> \ No newline at end of file
diff --git a/csharp/src/Google.Protobuf.Test/IssuesTest.cs b/csharp/src/Google.Protobuf.Test/IssuesTest.cs
index a0350035..a38d6b08 100644
--- a/csharp/src/Google.Protobuf.Test/IssuesTest.cs
+++ b/csharp/src/Google.Protobuf.Test/IssuesTest.cs
@@ -59,5 +59,24 @@ namespace Google.Protobuf
// Underscores aren't reflected in the JSON.
Assert.AreEqual("{ \"types\": 10, \"descriptor\": 20 }", message.ToString());
}
+
+ [Test]
+ public void JsonNameParseTest()
+ {
+ var settings = new JsonParser.Settings(10, TypeRegistry.FromFiles(UnittestIssuesReflection.Descriptor));
+ var parser = new JsonParser(settings);
+
+ // It is safe to use either original field name or explicitly specified json_name
+ Assert.AreEqual(new TestJsonName { Name = "test", Description = "test2", Guid = "test3" },
+ parser.Parse<TestJsonName>("{ \"name\": \"test\", \"desc\": \"test2\", \"guid\": \"test3\" }"));
+ }
+
+ [Test]
+ public void JsonNameFormatTest()
+ {
+ var message = new TestJsonName { Name = "test", Description = "test2", Guid = "test3" };
+ Assert.AreEqual("{ \"name\": \"test\", \"desc\": \"test2\", \"exid\": \"test3\" }",
+ JsonFormatter.Default.Format(message));
+ }
}
}
diff --git a/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs b/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs
index 8473b4be..261ac6a7 100644
--- a/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs
+++ b/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs
@@ -37,6 +37,10 @@ using UnitTest.Issues.TestProtos;
using Google.Protobuf.WellKnownTypes;
using Google.Protobuf.Reflection;
+using static Google.Protobuf.JsonParserTest; // For WrapInQuotes
+using System.IO;
+using Google.Protobuf.Collections;
+
namespace Google.Protobuf
{
/// <summary>
@@ -73,13 +77,13 @@ namespace Google.Protobuf
SingleFixed32 = 23,
SingleFixed64 = 1234567890123,
SingleFloat = 12.25f,
- SingleForeignEnum = ForeignEnum.FOREIGN_BAR,
+ SingleForeignEnum = ForeignEnum.ForeignBar,
SingleForeignMessage = new ForeignMessage { C = 10 },
- SingleImportEnum = ImportEnum.IMPORT_BAZ,
+ SingleImportEnum = ImportEnum.ImportBaz,
SingleImportMessage = new ImportMessage { D = 20 },
SingleInt32 = 100,
SingleInt64 = 3210987654321,
- SingleNestedEnum = TestAllTypes.Types.NestedEnum.FOO,
+ SingleNestedEnum = TestAllTypes.Types.NestedEnum.Foo,
SingleNestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 35 },
SinglePublicImportMessage = new PublicImportMessage { E = 54 },
SingleSfixed32 = -123,
@@ -163,41 +167,31 @@ namespace Google.Protobuf
}
[Test]
- public void UnknownEnumValueOmitted_SingleField()
+ public void UnknownEnumValueNumeric_SingleField()
{
var message = new TestAllTypes { SingleForeignEnum = (ForeignEnum) 100 };
- AssertJson("{ }", JsonFormatter.Default.Format(message));
+ AssertJson("{ 'singleForeignEnum': 100 }", JsonFormatter.Default.Format(message));
}
[Test]
- public void UnknownEnumValueOmitted_RepeatedField()
+ public void UnknownEnumValueNumeric_RepeatedField()
{
- var message = new TestAllTypes { RepeatedForeignEnum = { ForeignEnum.FOREIGN_BAZ, (ForeignEnum) 100, ForeignEnum.FOREIGN_FOO } };
- AssertJson("{ 'repeatedForeignEnum': [ 'FOREIGN_BAZ', 'FOREIGN_FOO' ] }", JsonFormatter.Default.Format(message));
+ var message = new TestAllTypes { RepeatedForeignEnum = { ForeignEnum.ForeignBaz, (ForeignEnum) 100, ForeignEnum.ForeignFoo } };
+ AssertJson("{ 'repeatedForeignEnum': [ 'FOREIGN_BAZ', 100, 'FOREIGN_FOO' ] }", JsonFormatter.Default.Format(message));
}
[Test]
- public void UnknownEnumValueOmitted_MapField()
+ public void UnknownEnumValueNumeric_MapField()
{
- // This matches the C++ behaviour.
- var message = new TestMap { MapInt32Enum = { { 1, MapEnum.MAP_ENUM_FOO }, { 2, (MapEnum) 100 }, { 3, MapEnum.MAP_ENUM_BAR } } };
- AssertJson("{ 'mapInt32Enum': { '1': 'MAP_ENUM_FOO', '3': 'MAP_ENUM_BAR' } }", JsonFormatter.Default.Format(message));
+ var message = new TestMap { MapInt32Enum = { { 1, MapEnum.Foo }, { 2, (MapEnum) 100 }, { 3, MapEnum.Bar } } };
+ AssertJson("{ 'mapInt32Enum': { '1': 'MAP_ENUM_FOO', '2': 100, '3': 'MAP_ENUM_BAR' } }", JsonFormatter.Default.Format(message));
}
[Test]
- public void UnknownEnumValueOmitted_RepeatedField_AllEntriesUnknown()
+ public void UnknownEnumValue_RepeatedField_AllEntriesUnknown()
{
- // *Maybe* we should hold off on writing the "[" until we find that we've got at least one value to write...
- // but this is what happens at the moment, and it doesn't seem too awful.
var message = new TestAllTypes { RepeatedForeignEnum = { (ForeignEnum) 200, (ForeignEnum) 100 } };
- AssertJson("{ 'repeatedForeignEnum': [ ] }", JsonFormatter.Default.Format(message));
- }
-
- [Test]
- public void NullValueForMessage()
- {
- var message = new TestMap { MapInt32ForeignMessage = { { 10, null } } };
- AssertJson("{ 'mapInt32ForeignMessage': { '10': null } }", JsonFormatter.Default.Format(message));
+ AssertJson("{ 'repeatedForeignEnum': [ 200, 100 ] }", JsonFormatter.Default.Format(message));
}
[Test]
@@ -236,6 +230,12 @@ namespace Google.Protobuf
[TestCase("foo_bar", "fooBar")]
[TestCase("bananaBanana", "bananaBanana")]
[TestCase("BANANABanana", "bananaBanana")]
+ [TestCase("simple", "simple")]
+ [TestCase("ACTION_AND_ADVENTURE", "actionAndAdventure")]
+ [TestCase("action_and_adventure", "actionAndAdventure")]
+ [TestCase("kFoo", "kFoo")]
+ [TestCase("HTTPServer", "httpServer")]
+ [TestCase("CLIENT", "client")]
public void ToCamelCase(string original, string expected)
{
Assert.AreEqual(expected, JsonFormatter.ToCamelCase(original));
@@ -319,27 +319,51 @@ namespace Google.Protobuf
}
[Test]
- public void TimestampStandalone()
+ [TestCase("1970-01-01T00:00:00Z", 0)]
+ [TestCase("1970-01-01T00:00:00.000000001Z", 1)]
+ [TestCase("1970-01-01T00:00:00.000000010Z", 10)]
+ [TestCase("1970-01-01T00:00:00.000000100Z", 100)]
+ [TestCase("1970-01-01T00:00:00.000001Z", 1000)]
+ [TestCase("1970-01-01T00:00:00.000010Z", 10000)]
+ [TestCase("1970-01-01T00:00:00.000100Z", 100000)]
+ [TestCase("1970-01-01T00:00:00.001Z", 1000000)]
+ [TestCase("1970-01-01T00:00:00.010Z", 10000000)]
+ [TestCase("1970-01-01T00:00:00.100Z", 100000000)]
+ [TestCase("1970-01-01T00:00:00.120Z", 120000000)]
+ [TestCase("1970-01-01T00:00:00.123Z", 123000000)]
+ [TestCase("1970-01-01T00:00:00.123400Z", 123400000)]
+ [TestCase("1970-01-01T00:00:00.123450Z", 123450000)]
+ [TestCase("1970-01-01T00:00:00.123456Z", 123456000)]
+ [TestCase("1970-01-01T00:00:00.123456700Z", 123456700)]
+ [TestCase("1970-01-01T00:00:00.123456780Z", 123456780)]
+ [TestCase("1970-01-01T00:00:00.123456789Z", 123456789)]
+ public void TimestampStandalone(string expected, int nanos)
{
- Assert.AreEqual("1970-01-01T00:00:00Z", new Timestamp().ToString());
- Assert.AreEqual("1970-01-01T00:00:00.100Z", new Timestamp { Nanos = 100000000 }.ToString());
- Assert.AreEqual("1970-01-01T00:00:00.120Z", new Timestamp { Nanos = 120000000 }.ToString());
- Assert.AreEqual("1970-01-01T00:00:00.123Z", new Timestamp { Nanos = 123000000 }.ToString());
- Assert.AreEqual("1970-01-01T00:00:00.123400Z", new Timestamp { Nanos = 123400000 }.ToString());
- Assert.AreEqual("1970-01-01T00:00:00.123450Z", new Timestamp { Nanos = 123450000 }.ToString());
- Assert.AreEqual("1970-01-01T00:00:00.123456Z", new Timestamp { Nanos = 123456000 }.ToString());
- Assert.AreEqual("1970-01-01T00:00:00.123456700Z", new Timestamp { Nanos = 123456700 }.ToString());
- Assert.AreEqual("1970-01-01T00:00:00.123456780Z", new Timestamp { Nanos = 123456780 }.ToString());
- Assert.AreEqual("1970-01-01T00:00:00.123456789Z", new Timestamp { Nanos = 123456789 }.ToString());
+ Assert.AreEqual(WrapInQuotes(expected), new Timestamp { Nanos = nanos }.ToString());
+ }
- // One before and one after the Unix epoch
- Assert.AreEqual("1673-06-19T12:34:56Z",
+ [Test]
+ public void TimestampStandalone_FromDateTime()
+ {
+ // One before and one after the Unix epoch, more easily represented via DateTime.
+ Assert.AreEqual("\"1673-06-19T12:34:56Z\"",
new DateTime(1673, 6, 19, 12, 34, 56, DateTimeKind.Utc).ToTimestamp().ToString());
- Assert.AreEqual("2015-07-31T10:29:34Z",
+ Assert.AreEqual("\"2015-07-31T10:29:34Z\"",
new DateTime(2015, 7, 31, 10, 29, 34, DateTimeKind.Utc).ToTimestamp().ToString());
}
[Test]
+ [TestCase(-1, -1)] // Would be valid as duration
+ [TestCase(1, Timestamp.MaxNanos + 1)]
+ [TestCase(Timestamp.UnixSecondsAtBclMaxValue + 1, 0)]
+ [TestCase(Timestamp.UnixSecondsAtBclMinValue - 1, 0)]
+ public void TimestampStandalone_NonNormalized(long seconds, int nanoseconds)
+ {
+ var timestamp = new Timestamp { Seconds = seconds, Nanos = nanoseconds };
+ Assert.Throws<InvalidOperationException>(() => JsonFormatter.Default.Format(timestamp));
+ }
+
+ [Test]
public void TimestampField()
{
var message = new TestWellKnownTypes { TimestampField = new Timestamp() };
@@ -350,6 +374,14 @@ namespace Google.Protobuf
[TestCase(0, 0, "0s")]
[TestCase(1, 0, "1s")]
[TestCase(-1, 0, "-1s")]
+ [TestCase(0, 1, "0.000000001s")]
+ [TestCase(0, 10, "0.000000010s")]
+ [TestCase(0, 100, "0.000000100s")]
+ [TestCase(0, 1000, "0.000001s")]
+ [TestCase(0, 10000, "0.000010s")]
+ [TestCase(0, 100000, "0.000100s")]
+ [TestCase(0, 1000000, "0.001s")]
+ [TestCase(0, 10000000, "0.010s")]
[TestCase(0, 100000000, "0.100s")]
[TestCase(0, 120000000, "0.120s")]
[TestCase(0, 123000000, "0.123s")]
@@ -362,12 +394,19 @@ namespace Google.Protobuf
[TestCase(0, -100000000, "-0.100s")]
[TestCase(1, 100000000, "1.100s")]
[TestCase(-1, -100000000, "-1.100s")]
- // Non-normalized examples
- [TestCase(1, 2123456789, "3.123456789s")]
- [TestCase(1, -100000000, "0.900s")]
public void DurationStandalone(long seconds, int nanoseconds, string expected)
{
- Assert.AreEqual(expected, new Duration { Seconds = seconds, Nanos = nanoseconds }.ToString());
+ var json = JsonFormatter.Default.Format(new Duration { Seconds = seconds, Nanos = nanoseconds });
+ Assert.AreEqual(WrapInQuotes(expected), json);
+ }
+
+ [Test]
+ [TestCase(1, 2123456789)]
+ [TestCase(1, -100000000)]
+ public void DurationStandalone_NonNormalized(long seconds, int nanoseconds)
+ {
+ var duration = new Duration { Seconds = seconds, Nanos = nanoseconds };
+ Assert.Throws<InvalidOperationException>(() => JsonFormatter.Default.Format(duration));
}
[Test]
@@ -396,14 +435,24 @@ namespace Google.Protobuf
}
[Test]
+ [TestCase("foo__bar")]
+ [TestCase("foo_3_ar")]
+ [TestCase("fooBar")]
+ public void FieldMaskInvalid(string input)
+ {
+ var mask = new FieldMask { Paths = { input } };
+ Assert.Throws<InvalidOperationException>(() => JsonFormatter.Default.Format(mask));
+ }
+
+ [Test]
public void FieldMaskStandalone()
{
var fieldMask = new FieldMask { Paths = { "", "single", "with_underscore", "nested.field.name", "nested..double_dot" } };
- Assert.AreEqual(",single,withUnderscore,nested.field.name,nested..doubleDot", fieldMask.ToString());
+ Assert.AreEqual("\",single,withUnderscore,nested.field.name,nested..doubleDot\"", fieldMask.ToString());
// Invalid, but we shouldn't create broken JSON...
fieldMask = new FieldMask { Paths = { "x\\y" } };
- Assert.AreEqual(@"x\\y", fieldMask.ToString());
+ Assert.AreEqual(@"""x\\y""", fieldMask.ToString());
}
[Test]
@@ -440,6 +489,15 @@ namespace Google.Protobuf
}
[Test]
+ public void AnyMessageType_CustomPrefix()
+ {
+ var formatter = new JsonFormatter(new JsonFormatter.Settings(false, TypeRegistry.FromMessages(TestAllTypes.Descriptor)));
+ var message = new TestAllTypes { SingleInt32 = 10 };
+ var any = Any.Pack(message, "foo.bar/baz");
+ AssertJson("{ '@type': 'foo.bar/baz/protobuf_unittest.TestAllTypes', 'singleInt32': 10 }", formatter.Format(any));
+ }
+
+ [Test]
public void AnyNested()
{
var registry = TypeRegistry.FromMessages(TestWellKnownTypes.Descriptor, TestAllTypes.Descriptor);
@@ -462,6 +520,67 @@ namespace Google.Protobuf
Assert.Throws<InvalidOperationException>(() => JsonFormatter.Default.Format(any));
}
+ [Test]
+ [TestCase(typeof(BoolValue), true, "true")]
+ [TestCase(typeof(Int32Value), 32, "32")]
+ [TestCase(typeof(Int64Value), 32L, "\"32\"")]
+ [TestCase(typeof(UInt32Value), 32U, "32")]
+ [TestCase(typeof(UInt64Value), 32UL, "\"32\"")]
+ [TestCase(typeof(StringValue), "foo", "\"foo\"")]
+ [TestCase(typeof(FloatValue), 1.5f, "1.5")]
+ [TestCase(typeof(DoubleValue), 1.5d, "1.5")]
+ public void Wrappers_Standalone(System.Type wrapperType, object value, string expectedJson)
+ {
+ IMessage populated = (IMessage)Activator.CreateInstance(wrapperType);
+ populated.Descriptor.Fields[WrappersReflection.WrapperValueFieldNumber].Accessor.SetValue(populated, value);
+ Assert.AreEqual(expectedJson, JsonFormatter.Default.Format(populated));
+ }
+
+ // Sanity tests for WriteValue. Not particularly comprehensive, as it's all covered above already,
+ // as FormatMessage uses WriteValue.
+
+ [TestCase(null, "null")]
+ [TestCase(1, "1")]
+ [TestCase(1L, "'1'")]
+ [TestCase(0.5f, "0.5")]
+ [TestCase(0.5d, "0.5")]
+ [TestCase("text", "'text'")]
+ [TestCase("x\ny", @"'x\ny'")]
+ [TestCase(ForeignEnum.ForeignBar, "'FOREIGN_BAR'")]
+ public void WriteValue_Constant(object value, string expectedJson)
+ {
+ AssertWriteValue(value, expectedJson);
+ }
+
+ [Test]
+ public void WriteValue_Timestamp()
+ {
+ var value = new DateTime(1673, 6, 19, 12, 34, 56, DateTimeKind.Utc).ToTimestamp();
+ AssertWriteValue(value, "'1673-06-19T12:34:56Z'");
+ }
+
+ [Test]
+ public void WriteValue_Message()
+ {
+ var value = new TestAllTypes { SingleInt32 = 100, SingleInt64 = 3210987654321L };
+ AssertWriteValue(value, "{ 'singleInt32': 100, 'singleInt64': '3210987654321' }");
+ }
+
+ [Test]
+ public void WriteValue_List()
+ {
+ var value = new RepeatedField<int> { 1, 2, 3 };
+ AssertWriteValue(value, "[ 1, 2, 3 ]");
+ }
+
+ private static void AssertWriteValue(object value, string expectedJson)
+ {
+ var writer = new StringWriter();
+ JsonFormatter.Default.WriteValue(writer, value);
+ string actual = writer.ToString();
+ AssertJson(expectedJson, actual);
+ }
+
/// <summary>
/// Checks that the actual JSON is the same as the expected JSON - but after replacing
/// all apostrophes in the expected JSON with double quotes. This basically makes the tests easier
diff --git a/csharp/src/Google.Protobuf.Test/JsonParserTest.cs b/csharp/src/Google.Protobuf.Test/JsonParserTest.cs
index 874489e4..f595455a 100644
--- a/csharp/src/Google.Protobuf.Test/JsonParserTest.cs
+++ b/csharp/src/Google.Protobuf.Test/JsonParserTest.cs
@@ -39,9 +39,7 @@ using System;
namespace Google.Protobuf
{
/// <summary>
- /// Unit tests for JSON parsing. Some tests are ignored at the moment as the desired behaviour
- /// isn't fully known, either in terms of which exceptions should be thrown or whether they should
- /// count as valid values.
+ /// Unit tests for JSON parsing.
/// </summary>
public class JsonParserTest
{
@@ -74,6 +72,14 @@ namespace Google.Protobuf
}
[Test]
+ public void OriginalFieldNameAccepted()
+ {
+ var json = "{ \"single_int32\": 10 }";
+ var expected = new TestAllTypes { SingleInt32 = 10 };
+ Assert.AreEqual(expected, TestAllTypes.Parser.ParseJson(json));
+ }
+
+ [Test]
public void SourceContextRoundtrip()
{
AssertRoundtrip(new SourceContext { FileName = "foo.proto" });
@@ -118,24 +124,29 @@ namespace Google.Protobuf
[Test]
public void SingularWrappers_ExplicitNulls()
{
- var message = new TestWellKnownTypes();
+ // When we parse the "valueField": null part, we remember it... basically, it's one case
+ // where explicit default values don't fully roundtrip.
+ var message = new TestWellKnownTypes { ValueField = Value.ForNull() };
var json = new JsonFormatter(new JsonFormatter.Settings(true)).Format(message);
var parsed = JsonParser.Default.Parse<TestWellKnownTypes>(json);
Assert.AreEqual(message, parsed);
}
[Test]
+ [TestCase(typeof(BoolValue), "true", true)]
[TestCase(typeof(Int32Value), "32", 32)]
[TestCase(typeof(Int64Value), "32", 32L)]
+ [TestCase(typeof(Int64Value), "\"32\"", 32L)]
[TestCase(typeof(UInt32Value), "32", 32U)]
+ [TestCase(typeof(UInt64Value), "\"32\"", 32UL)]
[TestCase(typeof(UInt64Value), "32", 32UL)]
[TestCase(typeof(StringValue), "\"foo\"", "foo")]
[TestCase(typeof(FloatValue), "1.5", 1.5f)]
[TestCase(typeof(DoubleValue), "1.5", 1.5d)]
public void Wrappers_Standalone(System.Type wrapperType, string json, object expectedValue)
{
- IMessage parsed = (IMessage) Activator.CreateInstance(wrapperType);
- IMessage expected = (IMessage) Activator.CreateInstance(wrapperType);
+ IMessage parsed = (IMessage)Activator.CreateInstance(wrapperType);
+ IMessage expected = (IMessage)Activator.CreateInstance(wrapperType);
JsonParser.Default.Merge(parsed, "null");
Assert.AreEqual(expected, parsed);
@@ -145,11 +156,19 @@ namespace Google.Protobuf
}
[Test]
+ public void ExplicitNullValue()
+ {
+ string json = "{\"valueField\": null}";
+ var message = JsonParser.Default.Parse<TestWellKnownTypes>(json);
+ Assert.AreEqual(new TestWellKnownTypes { ValueField = Value.ForNull() }, message);
+ }
+
+ [Test]
public void BytesWrapper_Standalone()
{
ByteString data = ByteString.CopyFrom(1, 2, 3);
// Can't do this with attributes...
- var parsed = JsonParser.Default.Parse<BytesValue>("\"" + data.ToBase64() + "\"");
+ var parsed = JsonParser.Default.Parse<BytesValue>(WrapInQuotes(data.ToBase64()));
var expected = new BytesValue { Value = data };
Assert.AreEqual(expected, parsed);
}
@@ -173,6 +192,36 @@ namespace Google.Protobuf
}
[Test]
+ public void RepeatedField_NullElementProhibited()
+ {
+ string json = "{ \"repeated_foreign_message\": [null] }";
+ Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseJson(json));
+ }
+
+ [Test]
+ public void RepeatedField_NullOverallValueAllowed()
+ {
+ string json = "{ \"repeated_foreign_message\": null }";
+ Assert.AreEqual(new TestAllTypes(), TestAllTypes.Parser.ParseJson(json));
+ }
+
+ [Test]
+ [TestCase("{ \"mapInt32Int32\": { \"10\": null }")]
+ [TestCase("{ \"mapStringString\": { \"abc\": null }")]
+ [TestCase("{ \"mapInt32ForeignMessage\": { \"10\": null }")]
+ public void MapField_NullValueProhibited(string json)
+ {
+ Assert.Throws<InvalidProtocolBufferException>(() => TestMap.Parser.ParseJson(json));
+ }
+
+ [Test]
+ public void MapField_NullOverallValueAllowed()
+ {
+ string json = "{ \"mapInt32Int32\": null }";
+ Assert.AreEqual(new TestMap(), TestMap.Parser.ParseJson(json));
+ }
+
+ [Test]
public void IndividualWrapperTypes()
{
Assert.AreEqual(new StringValue { Value = "foo" }, StringValue.Parser.ParseJson("\"foo\""));
@@ -184,7 +233,7 @@ namespace Google.Protobuf
private static void AssertRoundtrip<T>(T message) where T : IMessage<T>, new()
{
var clone = message.Clone();
- var json = message.ToString();
+ var json = JsonFormatter.Default.Format(message);
var parsed = JsonParser.Default.Parse<T>(json);
Assert.AreEqual(clone, parsed);
}
@@ -205,6 +254,8 @@ namespace Google.Protobuf
[Test]
[TestCase("+0")]
+ [TestCase(" 1")]
+ [TestCase("1 ")]
[TestCase("00")]
[TestCase("-00")]
[TestCase("--1")]
@@ -318,7 +369,18 @@ namespace Google.Protobuf
[TestCase("1.0.0")]
[TestCase("+1")]
[TestCase("00")]
+ [TestCase("01")]
+ [TestCase("-00")]
+ [TestCase("-01")]
[TestCase("--1")]
+ [TestCase(" Infinity")]
+ [TestCase(" -Infinity")]
+ [TestCase("NaN ")]
+ [TestCase("Infinity ")]
+ [TestCase("-Infinity ")]
+ [TestCase(" NaN")]
+ [TestCase("INFINITY")]
+ [TestCase("nan")]
[TestCase("\u00BD")] // 1/2 as a single Unicode character. Just sanity checking...
public void StringToDouble_Invalid(string jsonValue)
{
@@ -363,6 +425,10 @@ namespace Google.Protobuf
[TestCase("-1", -1)]
[TestCase("2147483647", 2147483647)]
[TestCase("-2147483648", -2147483648)]
+ [TestCase("1e1", 10)]
+ [TestCase("-1e1", -10)]
+ [TestCase("10.00", 10)]
+ [TestCase("-10.00", -10)]
public void NumberToInt32_Valid(string jsonValue, int expectedParsedValue)
{
string json = "{ \"singleInt32\": " + jsonValue + "}";
@@ -376,7 +442,8 @@ namespace Google.Protobuf
[TestCase("-00", typeof(InvalidJsonException))]
[TestCase("--1", typeof(InvalidJsonException))]
[TestCase("+1", typeof(InvalidJsonException))]
- [TestCase("1.5", typeof(InvalidProtocolBufferException), Ignore = true, Reason = "Desired behaviour unclear")]
+ [TestCase("1.5", typeof(InvalidProtocolBufferException))]
+ // Value is out of range
[TestCase("1e10", typeof(InvalidProtocolBufferException))]
[TestCase("2147483648", typeof(InvalidProtocolBufferException))]
[TestCase("-2147483649", typeof(InvalidProtocolBufferException))]
@@ -411,8 +478,10 @@ namespace Google.Protobuf
[TestCase("0", 0L)]
[TestCase("1", 1L)]
[TestCase("-1", -1L)]
- [TestCase("9223372036854775807", 9223372036854775807, Ignore = true, Reason = "Desired behaviour unclear")]
- [TestCase("-9223372036854775808", -9223372036854775808, Ignore = true, Reason = "Desired behaviour unclear")]
+ // long.MaxValue isn't actually representable as a double. This string value is the highest
+ // representable value which isn't greater than long.MaxValue.
+ [TestCase("9223372036854774784", 9223372036854774784)]
+ [TestCase("-9223372036854775808", -9223372036854775808)]
public void NumberToInt64_Valid(string jsonValue, long expectedParsedValue)
{
string json = "{ \"singleInt64\": " + jsonValue + "}";
@@ -422,8 +491,11 @@ namespace Google.Protobuf
// Assume that anything non-bounds-related is covered in the Int32 case
[Test]
- [TestCase("-9223372036854775809", Ignore = true, Reason = "Desired behaviour unclear")]
- [TestCase("9223372036854775808", Ignore = true, Reason = "Desired behaviour unclear")]
+ [TestCase("9223372036854775808")]
+ // Theoretical bound would be -9223372036854775809, but when that is parsed to a double
+ // we end up with the exact value of long.MinValue due to lack of precision. The value here
+ // is the "next double down".
+ [TestCase("-9223372036854780000")]
public void NumberToInt64_Invalid(string jsonValue)
{
string json = "{ \"singleInt64\": " + jsonValue + "}";
@@ -433,7 +505,9 @@ namespace Google.Protobuf
[Test]
[TestCase("0", 0UL)]
[TestCase("1", 1UL)]
- [TestCase("18446744073709551615", 18446744073709551615, Ignore = true, Reason = "Desired behaviour unclear")]
+ // ulong.MaxValue isn't representable as a double. This value is the largest double within
+ // the range of ulong.
+ [TestCase("18446744073709549568", 18446744073709549568UL)]
public void NumberToUInt64_Valid(string jsonValue, ulong expectedParsedValue)
{
string json = "{ \"singleUint64\": " + jsonValue + "}";
@@ -475,9 +549,9 @@ namespace Google.Protobuf
}
[Test]
- [TestCase("1.7977e308", Ignore = true, Reason = "Desired behaviour unclear")]
- [TestCase("-1.7977e308", Ignore = true, Reason = "Desired behaviour unclear")]
- [TestCase("1e309", Ignore = true, Reason = "Desired behaviour unclear")]
+ [TestCase("1.7977e308")]
+ [TestCase("-1.7977e308")]
+ [TestCase("1e309")]
[TestCase("1,0")]
[TestCase("1.0.0")]
[TestCase("+1")]
@@ -565,11 +639,11 @@ namespace Google.Protobuf
public void Timestamp_Valid(string jsonValue, string expectedFormatted)
{
expectedFormatted = expectedFormatted ?? jsonValue;
- string json = "\"" + jsonValue + "\"";
+ string json = WrapInQuotes(jsonValue);
var parsed = Timestamp.Parser.ParseJson(json);
- Assert.AreEqual(expectedFormatted, parsed.ToString());
+ Assert.AreEqual(WrapInQuotes(expectedFormatted), parsed.ToString());
}
-
+
[Test]
[TestCase("2015-10-09 14:46:23.123456789Z", Description = "No T between date and time")]
[TestCase("2015/10/09T14:46:23.123456789Z", Description = "Wrong date separators")]
@@ -592,7 +666,7 @@ namespace Google.Protobuf
[TestCase("2100-02-29T14:46:23.123456789Z", Description = "Feb 29th on a non-leap-year")]
public void Timestamp_Invalid(string jsonValue)
{
- string json = "\"" + jsonValue + "\"";
+ string json = WrapInQuotes(jsonValue);
Assert.Throws<InvalidProtocolBufferException>(() => Timestamp.Parser.ParseJson(json));
}
@@ -666,9 +740,9 @@ namespace Google.Protobuf
public void Duration_Valid(string jsonValue, string expectedFormatted)
{
expectedFormatted = expectedFormatted ?? jsonValue;
- string json = "\"" + jsonValue + "\"";
+ string json = WrapInQuotes(jsonValue);
var parsed = Duration.Parser.ParseJson(json);
- Assert.AreEqual(expectedFormatted, parsed.ToString());
+ Assert.AreEqual(WrapInQuotes(expectedFormatted), parsed.ToString());
}
// The simplest way of testing that the value has parsed correctly is to reformat it,
@@ -692,12 +766,11 @@ namespace Google.Protobuf
[TestCase("--0.123456789s", Description = "Double minus sign")]
// Violate upper/lower bounds in various ways
[TestCase("315576000001s", Description = "Integer part too large")]
- [TestCase("315576000000.000000001s", Description = "Integer part is upper bound; non-zero fraction")]
[TestCase("3155760000000s", Description = "Integer part too long (positive)")]
[TestCase("-3155760000000s", Description = "Integer part too long (negative)")]
public void Duration_Invalid(string jsonValue)
{
- string json = "\"" + jsonValue + "\"";
+ string json = WrapInQuotes(jsonValue);
Assert.Throws<InvalidProtocolBufferException>(() => Duration.Parser.ParseJson(json));
}
@@ -713,12 +786,20 @@ namespace Google.Protobuf
[TestCase("fooBar.bazQux", "foo_bar.baz_qux")]
public void FieldMask_Valid(string jsonValue, params string[] expectedPaths)
{
- string json = "\"" + jsonValue + "\"";
+ string json = WrapInQuotes(jsonValue);
var parsed = FieldMask.Parser.ParseJson(json);
CollectionAssert.AreEqual(expectedPaths, parsed.Paths);
}
[Test]
+ [TestCase("foo_bar")]
+ public void FieldMask_Invalid(string jsonValue)
+ {
+ string json = WrapInQuotes(jsonValue);
+ Assert.Throws<InvalidProtocolBufferException>(() => FieldMask.Parser.ParseJson(json));
+ }
+
+ [Test]
public void Any_RegularMessage()
{
var registry = TypeRegistry.FromMessages(TestAllTypes.Descriptor);
@@ -733,6 +814,17 @@ namespace Google.Protobuf
}
[Test]
+ public void Any_CustomPrefix()
+ {
+ var registry = TypeRegistry.FromMessages(TestAllTypes.Descriptor);
+ var message = new TestAllTypes { SingleInt32 = 10 };
+ var original = Any.Pack(message, "custom.prefix/middle-part");
+ var parser = new JsonParser(new JsonParser.Settings(10, registry));
+ string json = "{ \"@type\": \"custom.prefix/middle-part/protobuf_unittest.TestAllTypes\", \"singleInt32\": 10 }";
+ Assert.AreEqual(original, parser.Parse<Any>(json));
+ }
+
+ [Test]
public void Any_UnknownType()
{
string json = "{ \"@type\": \"type.googleapis.com/bogus\" }";
@@ -740,6 +832,13 @@ namespace Google.Protobuf
}
[Test]
+ public void Any_NoTypeUrl()
+ {
+ string json = "{ \"foo\": \"bar\" }";
+ Assert.Throws<InvalidProtocolBufferException>(() => Any.Parser.ParseJson(json));
+ }
+
+ [Test]
public void Any_WellKnownType()
{
var registry = TypeRegistry.FromMessages(Timestamp.Descriptor);
@@ -789,7 +888,52 @@ namespace Google.Protobuf
var parser63 = new JsonParser(new JsonParser.Settings(63));
Assert.Throws<InvalidProtocolBufferException>(() => parser63.Parse<TestRecursiveMessage>(data64));
+ }
+ [Test]
+ [TestCase("AQI")]
+ [TestCase("_-==")]
+ public void Bytes_InvalidBase64(string badBase64)
+ {
+ string json = "{ \"singleBytes\": \"" + badBase64 + "\" }";
+ Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseJson(json));
+ }
+
+ [Test]
+ [TestCase("\"FOREIGN_BAR\"", ForeignEnum.ForeignBar)]
+ [TestCase("5", ForeignEnum.ForeignBar)]
+ [TestCase("100", (ForeignEnum)100)]
+ public void EnumValid(string value, ForeignEnum expectedValue)
+ {
+ string json = "{ \"singleForeignEnum\": " + value + " }";
+ var parsed = TestAllTypes.Parser.ParseJson(json);
+ Assert.AreEqual(new TestAllTypes { SingleForeignEnum = expectedValue }, parsed);
+ }
+
+ [Test]
+ [TestCase("\"NOT_A_VALID_VALUE\"")]
+ [TestCase("5.5")]
+ public void Enum_Invalid(string value)
+ {
+ string json = "{ \"singleForeignEnum\": " + value + " }";
+ Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseJson(json));
+ }
+
+ [Test]
+ public void OneofDuplicate_Invalid()
+ {
+ string json = "{ \"oneofString\": \"x\", \"oneofUint32\": 10 }";
+ Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseJson(json));
+ }
+
+ /// <summary>
+ /// Various tests use strings which have quotes round them for parsing or as the result
+ /// of formatting, but without those quotes being specified in the tests (for the sake of readability).
+ /// This method simply returns the input, wrapped in double quotes.
+ /// </summary>
+ internal static string WrapInQuotes(string text)
+ {
+ return '"' + text + '"';
}
}
-}
+} \ No newline at end of file
diff --git a/csharp/src/Google.Protobuf.Test/JsonTokenizerTest.cs b/csharp/src/Google.Protobuf.Test/JsonTokenizerTest.cs
index a0a62227..527ab336 100644
--- a/csharp/src/Google.Protobuf.Test/JsonTokenizerTest.cs
+++ b/csharp/src/Google.Protobuf.Test/JsonTokenizerTest.cs
@@ -249,7 +249,6 @@ namespace Google.Protobuf
[TestCase("[,", 1)]
[TestCase("{", 1)]
[TestCase("{,", 1)]
- [TestCase("{", 1)]
[TestCase("{[", 1)]
[TestCase("{{", 1)]
[TestCase("{0", 1)]
diff --git a/csharp/src/Google.Protobuf.Test/Properties/AppManifest.xml b/csharp/src/Google.Protobuf.Test/Properties/AppManifest.xml
deleted file mode 100644
index a9552327..00000000
--- a/csharp/src/Google.Protobuf.Test/Properties/AppManifest.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<Deployment xmlns="http://schemas.microsoft.com/client/2007/deployment"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
->
- <Deployment.Parts>
- </Deployment.Parts>
-</Deployment>
diff --git a/csharp/src/Google.Protobuf.Test/Properties/AssemblyInfo.cs b/csharp/src/Google.Protobuf.Test/Properties/AssemblyInfo.cs
deleted file mode 100644
index d00acf85..00000000
--- a/csharp/src/Google.Protobuf.Test/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using System;
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-
-[assembly: AssemblyTitle("Google.Protobuf.Test")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("Google.Protobuf.Test")]
-[assembly: AssemblyCopyright("Copyright © 2015")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-[assembly: AssemblyVersion("3.0.0.0")]
-[assembly: AssemblyFileVersion("3.0.0.0")]
diff --git a/csharp/src/Google.Protobuf.Test/Reflection/DescriptorsTest.cs b/csharp/src/Google.Protobuf.Test/Reflection/DescriptorsTest.cs
index 086a4e98..52d5a676 100644
--- a/csharp/src/Google.Protobuf.Test/Reflection/DescriptorsTest.cs
+++ b/csharp/src/Google.Protobuf.Test/Reflection/DescriptorsTest.cs
@@ -195,7 +195,7 @@ namespace Google.Protobuf.Reflection
Assert.AreEqual(value, enumType.Values[1]);
Assert.AreEqual("FOREIGN_FOO", value.Name);
Assert.AreEqual(4, value.Number);
- Assert.AreEqual((int) ForeignEnum.FOREIGN_FOO, value.Number);
+ Assert.AreEqual((int) ForeignEnum.ForeignFoo, value.Number);
Assert.AreEqual(value, enumType.FindValueByNumber(4));
Assert.Null(enumType.FindValueByName("NO_SUCH_VALUE"));
for (int i = 0; i < enumType.Values.Count; i++)
diff --git a/csharp/src/Google.Protobuf.Test/Reflection/FieldAccessTest.cs b/csharp/src/Google.Protobuf.Test/Reflection/FieldAccessTest.cs
index 936e41c6..a488af30 100644
--- a/csharp/src/Google.Protobuf.Test/Reflection/FieldAccessTest.cs
+++ b/csharp/src/Google.Protobuf.Test/Reflection/FieldAccessTest.cs
@@ -128,7 +128,7 @@ namespace Google.Protobuf.Reflection
fields[TestAllTypes.SingleInt32FieldNumber].Accessor.SetValue(message, 500);
fields[TestAllTypes.SingleStringFieldNumber].Accessor.SetValue(message, "It's a string");
fields[TestAllTypes.SingleBytesFieldNumber].Accessor.SetValue(message, ByteString.CopyFrom(99, 98, 97));
- fields[TestAllTypes.SingleForeignEnumFieldNumber].Accessor.SetValue(message, ForeignEnum.FOREIGN_FOO);
+ fields[TestAllTypes.SingleForeignEnumFieldNumber].Accessor.SetValue(message, ForeignEnum.ForeignFoo);
fields[TestAllTypes.SingleForeignMessageFieldNumber].Accessor.SetValue(message, new ForeignMessage { C = 12345 });
fields[TestAllTypes.SingleDoubleFieldNumber].Accessor.SetValue(message, 20150701.5);
@@ -138,7 +138,7 @@ namespace Google.Protobuf.Reflection
SingleInt32 = 500,
SingleString = "It's a string",
SingleBytes = ByteString.CopyFrom(99, 98, 97),
- SingleForeignEnum = ForeignEnum.FOREIGN_FOO,
+ SingleForeignEnum = ForeignEnum.ForeignFoo,
SingleForeignMessage = new ForeignMessage { C = 12345 },
SingleDouble = 20150701.5
};
diff --git a/csharp/src/Google.Protobuf.Test/SampleMessages.cs b/csharp/src/Google.Protobuf.Test/SampleMessages.cs
index 8a9c7f86..ffa4e2a7 100644
--- a/csharp/src/Google.Protobuf.Test/SampleMessages.cs
+++ b/csharp/src/Google.Protobuf.Test/SampleMessages.cs
@@ -54,13 +54,13 @@ namespace Google.Protobuf
SingleFixed32 = 23,
SingleFixed64 = 1234567890123,
SingleFloat = 12.25f,
- SingleForeignEnum = ForeignEnum.FOREIGN_BAR,
+ SingleForeignEnum = ForeignEnum.ForeignBar,
SingleForeignMessage = new ForeignMessage { C = 10 },
- SingleImportEnum = ImportEnum.IMPORT_BAZ,
+ SingleImportEnum = ImportEnum.ImportBaz,
SingleImportMessage = new ImportMessage { D = 20 },
SingleInt32 = 100,
SingleInt64 = 3210987654321,
- SingleNestedEnum = TestAllTypes.Types.NestedEnum.FOO,
+ SingleNestedEnum = TestAllTypes.Types.NestedEnum.Foo,
SingleNestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 35 },
SinglePublicImportMessage = new PublicImportMessage { E = 54 },
SingleSfixed32 = -123,
@@ -76,13 +76,13 @@ namespace Google.Protobuf
RepeatedFixed32 = { UInt32.MaxValue, 23 },
RepeatedFixed64 = { UInt64.MaxValue, 1234567890123 },
RepeatedFloat = { 100f, 12.25f },
- RepeatedForeignEnum = { ForeignEnum.FOREIGN_FOO, ForeignEnum.FOREIGN_BAR },
+ RepeatedForeignEnum = { ForeignEnum.ForeignFoo, ForeignEnum.ForeignBar },
RepeatedForeignMessage = { new ForeignMessage(), new ForeignMessage { C = 10 } },
- RepeatedImportEnum = { ImportEnum.IMPORT_BAZ, ImportEnum.IMPORT_ENUM_UNSPECIFIED },
+ RepeatedImportEnum = { ImportEnum.ImportBaz, ImportEnum.Unspecified },
RepeatedImportMessage = { new ImportMessage { D = 20 }, new ImportMessage { D = 25 } },
RepeatedInt32 = { 100, 200 },
RepeatedInt64 = { 3210987654321, Int64.MaxValue },
- RepeatedNestedEnum = { TestAllTypes.Types.NestedEnum.FOO, TestAllTypes.Types.NestedEnum.NEG },
+ RepeatedNestedEnum = { TestAllTypes.Types.NestedEnum.Foo, TestAllTypes.Types.NestedEnum.Neg },
RepeatedNestedMessage = { new TestAllTypes.Types.NestedMessage { Bb = 35 }, new TestAllTypes.Types.NestedMessage { Bb = 10 } },
RepeatedPublicImportMessage = { new PublicImportMessage { E = 54 }, new PublicImportMessage { E = -1 } },
RepeatedSfixed32 = { -123, 123 },
@@ -92,8 +92,8 @@ namespace Google.Protobuf
RepeatedString = { "foo", "bar" },
RepeatedUint32 = { UInt32.MaxValue, UInt32.MinValue },
RepeatedUint64 = { UInt64.MaxValue, UInt32.MinValue },
- OneofString = "Oneof string"
+ OneofString = "Oneof string"
};
}
}
-}
+} \ No newline at end of file
diff --git a/csharp/src/Google.Protobuf.Test/TestCornerCases.cs b/csharp/src/Google.Protobuf.Test/TestCornerCases.cs
index 03fa1855..248f5fa9 100644
--- a/csharp/src/Google.Protobuf.Test/TestCornerCases.cs
+++ b/csharp/src/Google.Protobuf.Test/TestCornerCases.cs
@@ -43,8 +43,8 @@ namespace Google.Protobuf
NegativeEnumMessage msg = new NegativeEnumMessage
{
Value = NegativeEnum.MinusOne,
- Values = { NegativeEnum.NEGATIVE_ENUM_ZERO, NegativeEnum.MinusOne, NegativeEnum.FiveBelow },
- PackedValues = { NegativeEnum.NEGATIVE_ENUM_ZERO, NegativeEnum.MinusOne, NegativeEnum.FiveBelow }
+ Values = { NegativeEnum.Zero, NegativeEnum.MinusOne, NegativeEnum.FiveBelow },
+ PackedValues = { NegativeEnum.Zero, NegativeEnum.MinusOne, NegativeEnum.FiveBelow }
};
Assert.AreEqual(58, msg.CalculateSize());
diff --git a/csharp/src/Google.Protobuf.Conformance/Properties/AssemblyInfo.cs b/csharp/src/Google.Protobuf.Test/TestProtos/ForeignMessagePartial.cs
index d22e90fd..5663a699 100644
--- a/csharp/src/Google.Protobuf.Conformance/Properties/AssemblyInfo.cs
+++ b/csharp/src/Google.Protobuf.Test/TestProtos/ForeignMessagePartial.cs
@@ -1,6 +1,6 @@
#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
-// Copyright 2015 Google Inc. All rights reserved.
+// Copyright 2016 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
@@ -30,19 +30,16 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
-using System.Reflection;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("Google.Protobuf.Conformance")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("Google.Protobuf.Conformance")]
-[assembly: AssemblyCopyright("Copyright © 2015")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-[assembly: AssemblyVersion("3.0.0.0")]
-[assembly: AssemblyFileVersion("3.0.0.0")]
+namespace Google.Protobuf.TestProtos
+{
+ /// <summary>
+ /// A message with custom diagnostics (to test that they work).
+ /// </summary>
+ public partial class ForeignMessage : ICustomDiagnosticMessage
+ {
+ public string ToDiagnosticString()
+ {
+ return $"{{ \"c\": {C}, \"@cInHex\": \"{C:x}\" }}";
+ }
+ }
+}
diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/MapUnittestProto3.cs b/csharp/src/Google.Protobuf.Test/TestProtos/MapUnittestProto3.cs
index 5ff47ed2..0a299fd7 100644
--- a/csharp/src/Google.Protobuf.Test/TestProtos/MapUnittestProto3.cs
+++ b/csharp/src/Google.Protobuf.Test/TestProtos/MapUnittestProto3.cs
@@ -10,7 +10,6 @@ using scg = global::System.Collections.Generic;
namespace Google.Protobuf.TestProtos {
/// <summary>Holder for reflection information generated from google/protobuf/map_unittest_proto3.proto</summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public static partial class MapUnittestProto3Reflection {
#region Descriptor
@@ -149,14 +148,14 @@ namespace Google.Protobuf.TestProtos {
"b2dsZS5Qcm90b2J1Zi5UZXN0UHJvdG9zYgZwcm90bzM="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor, },
- new pbr::GeneratedCodeInfo(new[] {typeof(global::Google.Protobuf.TestProtos.MapEnum), }, new pbr::GeneratedCodeInfo[] {
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestMap), global::Google.Protobuf.TestProtos.TestMap.Parser, new[]{ "MapInt32Int32", "MapInt64Int64", "MapUint32Uint32", "MapUint64Uint64", "MapSint32Sint32", "MapSint64Sint64", "MapFixed32Fixed32", "MapFixed64Fixed64", "MapSfixed32Sfixed32", "MapSfixed64Sfixed64", "MapInt32Float", "MapInt32Double", "MapBoolBool", "MapStringString", "MapInt32Bytes", "MapInt32Enum", "MapInt32ForeignMessage" }, null, null, new pbr::GeneratedCodeInfo[] { null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, }),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestMapSubmessage), global::Google.Protobuf.TestProtos.TestMapSubmessage.Parser, new[]{ "TestMap" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestMessageMap), global::Google.Protobuf.TestProtos.TestMessageMap.Parser, new[]{ "MapInt32Message" }, null, null, new pbr::GeneratedCodeInfo[] { null, }),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestSameTypeMap), global::Google.Protobuf.TestProtos.TestSameTypeMap.Parser, new[]{ "Map1", "Map2" }, null, null, new pbr::GeneratedCodeInfo[] { null, null, }),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestArenaMap), global::Google.Protobuf.TestProtos.TestArenaMap.Parser, new[]{ "MapInt32Int32", "MapInt64Int64", "MapUint32Uint32", "MapUint64Uint64", "MapSint32Sint32", "MapSint64Sint64", "MapFixed32Fixed32", "MapFixed64Fixed64", "MapSfixed32Sfixed32", "MapSfixed64Sfixed64", "MapInt32Float", "MapInt32Double", "MapBoolBool", "MapInt32Enum", "MapInt32ForeignMessage" }, null, null, new pbr::GeneratedCodeInfo[] { null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, }),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.MessageContainingEnumCalledType), global::Google.Protobuf.TestProtos.MessageContainingEnumCalledType.Parser, new[]{ "Type" }, null, new[]{ typeof(global::Google.Protobuf.TestProtos.MessageContainingEnumCalledType.Types.Type) }, new pbr::GeneratedCodeInfo[] { null, }),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.MessageContainingMapCalledEntry), global::Google.Protobuf.TestProtos.MessageContainingMapCalledEntry.Parser, new[]{ "Entry" }, null, null, new pbr::GeneratedCodeInfo[] { null, })
+ new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Google.Protobuf.TestProtos.MapEnum), }, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestMap), global::Google.Protobuf.TestProtos.TestMap.Parser, new[]{ "MapInt32Int32", "MapInt64Int64", "MapUint32Uint32", "MapUint64Uint64", "MapSint32Sint32", "MapSint64Sint64", "MapFixed32Fixed32", "MapFixed64Fixed64", "MapSfixed32Sfixed32", "MapSfixed64Sfixed64", "MapInt32Float", "MapInt32Double", "MapBoolBool", "MapStringString", "MapInt32Bytes", "MapInt32Enum", "MapInt32ForeignMessage" }, null, null, new pbr::GeneratedClrTypeInfo[] { null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, }),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestMapSubmessage), global::Google.Protobuf.TestProtos.TestMapSubmessage.Parser, new[]{ "TestMap" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestMessageMap), global::Google.Protobuf.TestProtos.TestMessageMap.Parser, new[]{ "MapInt32Message" }, null, null, new pbr::GeneratedClrTypeInfo[] { null, }),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestSameTypeMap), global::Google.Protobuf.TestProtos.TestSameTypeMap.Parser, new[]{ "Map1", "Map2" }, null, null, new pbr::GeneratedClrTypeInfo[] { null, null, }),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestArenaMap), global::Google.Protobuf.TestProtos.TestArenaMap.Parser, new[]{ "MapInt32Int32", "MapInt64Int64", "MapUint32Uint32", "MapUint64Uint64", "MapSint32Sint32", "MapSint64Sint64", "MapFixed32Fixed32", "MapFixed64Fixed64", "MapSfixed32Sfixed32", "MapSfixed64Sfixed64", "MapInt32Float", "MapInt32Double", "MapBoolBool", "MapInt32Enum", "MapInt32ForeignMessage" }, null, null, new pbr::GeneratedClrTypeInfo[] { null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, }),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.MessageContainingEnumCalledType), global::Google.Protobuf.TestProtos.MessageContainingEnumCalledType.Parser, new[]{ "Type" }, null, new[]{ typeof(global::Google.Protobuf.TestProtos.MessageContainingEnumCalledType.Types.Type) }, new pbr::GeneratedClrTypeInfo[] { null, }),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.MessageContainingMapCalledEntry), global::Google.Protobuf.TestProtos.MessageContainingMapCalledEntry.Parser, new[]{ "Entry" }, null, null, new pbr::GeneratedClrTypeInfo[] { null, })
}));
}
#endregion
@@ -164,9 +163,9 @@ namespace Google.Protobuf.TestProtos {
}
#region Enums
public enum MapEnum {
- MAP_ENUM_FOO = 0,
- MAP_ENUM_BAR = 1,
- MAP_ENUM_BAZ = 2,
+ [pbr::OriginalName("MAP_ENUM_FOO")] Foo = 0,
+ [pbr::OriginalName("MAP_ENUM_BAR")] Bar = 1,
+ [pbr::OriginalName("MAP_ENUM_BAZ")] Baz = 2,
}
#endregion
@@ -175,25 +174,29 @@ namespace Google.Protobuf.TestProtos {
/// <summary>
/// Tests maps.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class TestMap : pb::IMessage<TestMap> {
private static readonly pb::MessageParser<TestMap> _parser = new pb::MessageParser<TestMap>(() => new TestMap());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<TestMap> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.MapUnittestProto3Reflection.Descriptor.MessageTypes[0]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestMap() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestMap(TestMap other) : this() {
mapInt32Int32_ = other.mapInt32Int32_.Clone();
mapInt64Int64_ = other.mapInt64Int64_.Clone();
@@ -214,6 +217,7 @@ namespace Google.Protobuf.TestProtos {
mapInt32ForeignMessage_ = other.mapInt32ForeignMessage_.Clone();
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestMap Clone() {
return new TestMap(this);
}
@@ -223,6 +227,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pbc::MapField<int, int>.Codec _map_mapInt32Int32_codec
= new pbc::MapField<int, int>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForInt32(16), 10);
private readonly pbc::MapField<int, int> mapInt32Int32_ = new pbc::MapField<int, int>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<int, int> MapInt32Int32 {
get { return mapInt32Int32_; }
}
@@ -232,6 +237,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pbc::MapField<long, long>.Codec _map_mapInt64Int64_codec
= new pbc::MapField<long, long>.Codec(pb::FieldCodec.ForInt64(8), pb::FieldCodec.ForInt64(16), 18);
private readonly pbc::MapField<long, long> mapInt64Int64_ = new pbc::MapField<long, long>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<long, long> MapInt64Int64 {
get { return mapInt64Int64_; }
}
@@ -241,6 +247,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pbc::MapField<uint, uint>.Codec _map_mapUint32Uint32_codec
= new pbc::MapField<uint, uint>.Codec(pb::FieldCodec.ForUInt32(8), pb::FieldCodec.ForUInt32(16), 26);
private readonly pbc::MapField<uint, uint> mapUint32Uint32_ = new pbc::MapField<uint, uint>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<uint, uint> MapUint32Uint32 {
get { return mapUint32Uint32_; }
}
@@ -250,6 +257,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pbc::MapField<ulong, ulong>.Codec _map_mapUint64Uint64_codec
= new pbc::MapField<ulong, ulong>.Codec(pb::FieldCodec.ForUInt64(8), pb::FieldCodec.ForUInt64(16), 34);
private readonly pbc::MapField<ulong, ulong> mapUint64Uint64_ = new pbc::MapField<ulong, ulong>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<ulong, ulong> MapUint64Uint64 {
get { return mapUint64Uint64_; }
}
@@ -259,6 +267,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pbc::MapField<int, int>.Codec _map_mapSint32Sint32_codec
= new pbc::MapField<int, int>.Codec(pb::FieldCodec.ForSInt32(8), pb::FieldCodec.ForSInt32(16), 42);
private readonly pbc::MapField<int, int> mapSint32Sint32_ = new pbc::MapField<int, int>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<int, int> MapSint32Sint32 {
get { return mapSint32Sint32_; }
}
@@ -268,6 +277,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pbc::MapField<long, long>.Codec _map_mapSint64Sint64_codec
= new pbc::MapField<long, long>.Codec(pb::FieldCodec.ForSInt64(8), pb::FieldCodec.ForSInt64(16), 50);
private readonly pbc::MapField<long, long> mapSint64Sint64_ = new pbc::MapField<long, long>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<long, long> MapSint64Sint64 {
get { return mapSint64Sint64_; }
}
@@ -277,6 +287,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pbc::MapField<uint, uint>.Codec _map_mapFixed32Fixed32_codec
= new pbc::MapField<uint, uint>.Codec(pb::FieldCodec.ForFixed32(13), pb::FieldCodec.ForFixed32(21), 58);
private readonly pbc::MapField<uint, uint> mapFixed32Fixed32_ = new pbc::MapField<uint, uint>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<uint, uint> MapFixed32Fixed32 {
get { return mapFixed32Fixed32_; }
}
@@ -286,6 +297,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pbc::MapField<ulong, ulong>.Codec _map_mapFixed64Fixed64_codec
= new pbc::MapField<ulong, ulong>.Codec(pb::FieldCodec.ForFixed64(9), pb::FieldCodec.ForFixed64(17), 66);
private readonly pbc::MapField<ulong, ulong> mapFixed64Fixed64_ = new pbc::MapField<ulong, ulong>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<ulong, ulong> MapFixed64Fixed64 {
get { return mapFixed64Fixed64_; }
}
@@ -295,6 +307,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pbc::MapField<int, int>.Codec _map_mapSfixed32Sfixed32_codec
= new pbc::MapField<int, int>.Codec(pb::FieldCodec.ForSFixed32(13), pb::FieldCodec.ForSFixed32(21), 74);
private readonly pbc::MapField<int, int> mapSfixed32Sfixed32_ = new pbc::MapField<int, int>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<int, int> MapSfixed32Sfixed32 {
get { return mapSfixed32Sfixed32_; }
}
@@ -304,6 +317,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pbc::MapField<long, long>.Codec _map_mapSfixed64Sfixed64_codec
= new pbc::MapField<long, long>.Codec(pb::FieldCodec.ForSFixed64(9), pb::FieldCodec.ForSFixed64(17), 82);
private readonly pbc::MapField<long, long> mapSfixed64Sfixed64_ = new pbc::MapField<long, long>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<long, long> MapSfixed64Sfixed64 {
get { return mapSfixed64Sfixed64_; }
}
@@ -313,6 +327,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pbc::MapField<int, float>.Codec _map_mapInt32Float_codec
= new pbc::MapField<int, float>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForFloat(21), 90);
private readonly pbc::MapField<int, float> mapInt32Float_ = new pbc::MapField<int, float>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<int, float> MapInt32Float {
get { return mapInt32Float_; }
}
@@ -322,6 +337,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pbc::MapField<int, double>.Codec _map_mapInt32Double_codec
= new pbc::MapField<int, double>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForDouble(17), 98);
private readonly pbc::MapField<int, double> mapInt32Double_ = new pbc::MapField<int, double>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<int, double> MapInt32Double {
get { return mapInt32Double_; }
}
@@ -331,6 +347,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pbc::MapField<bool, bool>.Codec _map_mapBoolBool_codec
= new pbc::MapField<bool, bool>.Codec(pb::FieldCodec.ForBool(8), pb::FieldCodec.ForBool(16), 106);
private readonly pbc::MapField<bool, bool> mapBoolBool_ = new pbc::MapField<bool, bool>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<bool, bool> MapBoolBool {
get { return mapBoolBool_; }
}
@@ -340,6 +357,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pbc::MapField<string, string>.Codec _map_mapStringString_codec
= new pbc::MapField<string, string>.Codec(pb::FieldCodec.ForString(10), pb::FieldCodec.ForString(18), 114);
private readonly pbc::MapField<string, string> mapStringString_ = new pbc::MapField<string, string>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<string, string> MapStringString {
get { return mapStringString_; }
}
@@ -349,6 +367,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pbc::MapField<int, pb::ByteString>.Codec _map_mapInt32Bytes_codec
= new pbc::MapField<int, pb::ByteString>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForBytes(18), 122);
private readonly pbc::MapField<int, pb::ByteString> mapInt32Bytes_ = new pbc::MapField<int, pb::ByteString>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<int, pb::ByteString> MapInt32Bytes {
get { return mapInt32Bytes_; }
}
@@ -358,6 +377,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pbc::MapField<int, global::Google.Protobuf.TestProtos.MapEnum>.Codec _map_mapInt32Enum_codec
= new pbc::MapField<int, global::Google.Protobuf.TestProtos.MapEnum>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForEnum(16, x => (int) x, x => (global::Google.Protobuf.TestProtos.MapEnum) x), 130);
private readonly pbc::MapField<int, global::Google.Protobuf.TestProtos.MapEnum> mapInt32Enum_ = new pbc::MapField<int, global::Google.Protobuf.TestProtos.MapEnum>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<int, global::Google.Protobuf.TestProtos.MapEnum> MapInt32Enum {
get { return mapInt32Enum_; }
}
@@ -367,14 +387,17 @@ namespace Google.Protobuf.TestProtos {
private static readonly pbc::MapField<int, global::Google.Protobuf.TestProtos.ForeignMessage>.Codec _map_mapInt32ForeignMessage_codec
= new pbc::MapField<int, global::Google.Protobuf.TestProtos.ForeignMessage>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForMessage(18, global::Google.Protobuf.TestProtos.ForeignMessage.Parser), 138);
private readonly pbc::MapField<int, global::Google.Protobuf.TestProtos.ForeignMessage> mapInt32ForeignMessage_ = new pbc::MapField<int, global::Google.Protobuf.TestProtos.ForeignMessage>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<int, global::Google.Protobuf.TestProtos.ForeignMessage> MapInt32ForeignMessage {
get { return mapInt32ForeignMessage_; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as TestMap);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(TestMap other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -402,6 +425,7 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
hash ^= MapInt32Int32.GetHashCode();
@@ -424,10 +448,12 @@ namespace Google.Protobuf.TestProtos {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
mapInt32Int32_.WriteTo(output, _map_mapInt32Int32_codec);
mapInt64Int64_.WriteTo(output, _map_mapInt64Int64_codec);
@@ -448,6 +474,7 @@ namespace Google.Protobuf.TestProtos {
mapInt32ForeignMessage_.WriteTo(output, _map_mapInt32ForeignMessage_codec);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
size += mapInt32Int32_.CalculateSize(_map_mapInt32Int32_codec);
@@ -470,6 +497,7 @@ namespace Google.Protobuf.TestProtos {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(TestMap other) {
if (other == null) {
return;
@@ -493,6 +521,7 @@ namespace Google.Protobuf.TestProtos {
mapInt32ForeignMessage_.Add(other.mapInt32ForeignMessage_);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -574,29 +603,34 @@ namespace Google.Protobuf.TestProtos {
}
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class TestMapSubmessage : pb::IMessage<TestMapSubmessage> {
private static readonly pb::MessageParser<TestMapSubmessage> _parser = new pb::MessageParser<TestMapSubmessage>(() => new TestMapSubmessage());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<TestMapSubmessage> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.MapUnittestProto3Reflection.Descriptor.MessageTypes[1]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestMapSubmessage() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestMapSubmessage(TestMapSubmessage other) : this() {
TestMap = other.testMap_ != null ? other.TestMap.Clone() : null;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestMapSubmessage Clone() {
return new TestMapSubmessage(this);
}
@@ -604,6 +638,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "test_map" field.</summary>
public const int TestMapFieldNumber = 1;
private global::Google.Protobuf.TestProtos.TestMap testMap_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.TestProtos.TestMap TestMap {
get { return testMap_; }
set {
@@ -611,10 +646,12 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as TestMapSubmessage);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(TestMapSubmessage other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -626,16 +663,19 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (testMap_ != null) hash ^= TestMap.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (testMap_ != null) {
output.WriteRawTag(10);
@@ -643,6 +683,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (testMap_ != null) {
@@ -651,6 +692,7 @@ namespace Google.Protobuf.TestProtos {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(TestMapSubmessage other) {
if (other == null) {
return;
@@ -663,6 +705,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -683,29 +726,34 @@ namespace Google.Protobuf.TestProtos {
}
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class TestMessageMap : pb::IMessage<TestMessageMap> {
private static readonly pb::MessageParser<TestMessageMap> _parser = new pb::MessageParser<TestMessageMap>(() => new TestMessageMap());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<TestMessageMap> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.MapUnittestProto3Reflection.Descriptor.MessageTypes[2]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestMessageMap() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestMessageMap(TestMessageMap other) : this() {
mapInt32Message_ = other.mapInt32Message_.Clone();
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestMessageMap Clone() {
return new TestMessageMap(this);
}
@@ -715,14 +763,17 @@ namespace Google.Protobuf.TestProtos {
private static readonly pbc::MapField<int, global::Google.Protobuf.TestProtos.TestAllTypes>.Codec _map_mapInt32Message_codec
= new pbc::MapField<int, global::Google.Protobuf.TestProtos.TestAllTypes>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForMessage(18, global::Google.Protobuf.TestProtos.TestAllTypes.Parser), 10);
private readonly pbc::MapField<int, global::Google.Protobuf.TestProtos.TestAllTypes> mapInt32Message_ = new pbc::MapField<int, global::Google.Protobuf.TestProtos.TestAllTypes>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<int, global::Google.Protobuf.TestProtos.TestAllTypes> MapInt32Message {
get { return mapInt32Message_; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as TestMessageMap);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(TestMessageMap other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -734,26 +785,31 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
hash ^= MapInt32Message.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
mapInt32Message_.WriteTo(output, _map_mapInt32Message_codec);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
size += mapInt32Message_.CalculateSize(_map_mapInt32Message_codec);
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(TestMessageMap other) {
if (other == null) {
return;
@@ -761,6 +817,7 @@ namespace Google.Protobuf.TestProtos {
mapInt32Message_.Add(other.mapInt32Message_);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -781,30 +838,35 @@ namespace Google.Protobuf.TestProtos {
/// <summary>
/// Two map fields share the same entry default instance.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class TestSameTypeMap : pb::IMessage<TestSameTypeMap> {
private static readonly pb::MessageParser<TestSameTypeMap> _parser = new pb::MessageParser<TestSameTypeMap>(() => new TestSameTypeMap());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<TestSameTypeMap> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.MapUnittestProto3Reflection.Descriptor.MessageTypes[3]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestSameTypeMap() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestSameTypeMap(TestSameTypeMap other) : this() {
map1_ = other.map1_.Clone();
map2_ = other.map2_.Clone();
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestSameTypeMap Clone() {
return new TestSameTypeMap(this);
}
@@ -814,6 +876,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pbc::MapField<int, int>.Codec _map_map1_codec
= new pbc::MapField<int, int>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForInt32(16), 10);
private readonly pbc::MapField<int, int> map1_ = new pbc::MapField<int, int>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<int, int> Map1 {
get { return map1_; }
}
@@ -823,14 +886,17 @@ namespace Google.Protobuf.TestProtos {
private static readonly pbc::MapField<int, int>.Codec _map_map2_codec
= new pbc::MapField<int, int>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForInt32(16), 18);
private readonly pbc::MapField<int, int> map2_ = new pbc::MapField<int, int>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<int, int> Map2 {
get { return map2_; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as TestSameTypeMap);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(TestSameTypeMap other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -843,6 +909,7 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
hash ^= Map1.GetHashCode();
@@ -850,15 +917,18 @@ namespace Google.Protobuf.TestProtos {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
map1_.WriteTo(output, _map_map1_codec);
map2_.WriteTo(output, _map_map2_codec);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
size += map1_.CalculateSize(_map_map1_codec);
@@ -866,6 +936,7 @@ namespace Google.Protobuf.TestProtos {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(TestSameTypeMap other) {
if (other == null) {
return;
@@ -874,6 +945,7 @@ namespace Google.Protobuf.TestProtos {
map2_.Add(other.map2_);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -895,25 +967,29 @@ namespace Google.Protobuf.TestProtos {
}
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class TestArenaMap : pb::IMessage<TestArenaMap> {
private static readonly pb::MessageParser<TestArenaMap> _parser = new pb::MessageParser<TestArenaMap>(() => new TestArenaMap());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<TestArenaMap> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.MapUnittestProto3Reflection.Descriptor.MessageTypes[4]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestArenaMap() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestArenaMap(TestArenaMap other) : this() {
mapInt32Int32_ = other.mapInt32Int32_.Clone();
mapInt64Int64_ = other.mapInt64Int64_.Clone();
@@ -932,6 +1008,7 @@ namespace Google.Protobuf.TestProtos {
mapInt32ForeignMessage_ = other.mapInt32ForeignMessage_.Clone();
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestArenaMap Clone() {
return new TestArenaMap(this);
}
@@ -941,6 +1018,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pbc::MapField<int, int>.Codec _map_mapInt32Int32_codec
= new pbc::MapField<int, int>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForInt32(16), 10);
private readonly pbc::MapField<int, int> mapInt32Int32_ = new pbc::MapField<int, int>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<int, int> MapInt32Int32 {
get { return mapInt32Int32_; }
}
@@ -950,6 +1028,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pbc::MapField<long, long>.Codec _map_mapInt64Int64_codec
= new pbc::MapField<long, long>.Codec(pb::FieldCodec.ForInt64(8), pb::FieldCodec.ForInt64(16), 18);
private readonly pbc::MapField<long, long> mapInt64Int64_ = new pbc::MapField<long, long>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<long, long> MapInt64Int64 {
get { return mapInt64Int64_; }
}
@@ -959,6 +1038,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pbc::MapField<uint, uint>.Codec _map_mapUint32Uint32_codec
= new pbc::MapField<uint, uint>.Codec(pb::FieldCodec.ForUInt32(8), pb::FieldCodec.ForUInt32(16), 26);
private readonly pbc::MapField<uint, uint> mapUint32Uint32_ = new pbc::MapField<uint, uint>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<uint, uint> MapUint32Uint32 {
get { return mapUint32Uint32_; }
}
@@ -968,6 +1048,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pbc::MapField<ulong, ulong>.Codec _map_mapUint64Uint64_codec
= new pbc::MapField<ulong, ulong>.Codec(pb::FieldCodec.ForUInt64(8), pb::FieldCodec.ForUInt64(16), 34);
private readonly pbc::MapField<ulong, ulong> mapUint64Uint64_ = new pbc::MapField<ulong, ulong>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<ulong, ulong> MapUint64Uint64 {
get { return mapUint64Uint64_; }
}
@@ -977,6 +1058,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pbc::MapField<int, int>.Codec _map_mapSint32Sint32_codec
= new pbc::MapField<int, int>.Codec(pb::FieldCodec.ForSInt32(8), pb::FieldCodec.ForSInt32(16), 42);
private readonly pbc::MapField<int, int> mapSint32Sint32_ = new pbc::MapField<int, int>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<int, int> MapSint32Sint32 {
get { return mapSint32Sint32_; }
}
@@ -986,6 +1068,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pbc::MapField<long, long>.Codec _map_mapSint64Sint64_codec
= new pbc::MapField<long, long>.Codec(pb::FieldCodec.ForSInt64(8), pb::FieldCodec.ForSInt64(16), 50);
private readonly pbc::MapField<long, long> mapSint64Sint64_ = new pbc::MapField<long, long>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<long, long> MapSint64Sint64 {
get { return mapSint64Sint64_; }
}
@@ -995,6 +1078,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pbc::MapField<uint, uint>.Codec _map_mapFixed32Fixed32_codec
= new pbc::MapField<uint, uint>.Codec(pb::FieldCodec.ForFixed32(13), pb::FieldCodec.ForFixed32(21), 58);
private readonly pbc::MapField<uint, uint> mapFixed32Fixed32_ = new pbc::MapField<uint, uint>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<uint, uint> MapFixed32Fixed32 {
get { return mapFixed32Fixed32_; }
}
@@ -1004,6 +1088,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pbc::MapField<ulong, ulong>.Codec _map_mapFixed64Fixed64_codec
= new pbc::MapField<ulong, ulong>.Codec(pb::FieldCodec.ForFixed64(9), pb::FieldCodec.ForFixed64(17), 66);
private readonly pbc::MapField<ulong, ulong> mapFixed64Fixed64_ = new pbc::MapField<ulong, ulong>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<ulong, ulong> MapFixed64Fixed64 {
get { return mapFixed64Fixed64_; }
}
@@ -1013,6 +1098,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pbc::MapField<int, int>.Codec _map_mapSfixed32Sfixed32_codec
= new pbc::MapField<int, int>.Codec(pb::FieldCodec.ForSFixed32(13), pb::FieldCodec.ForSFixed32(21), 74);
private readonly pbc::MapField<int, int> mapSfixed32Sfixed32_ = new pbc::MapField<int, int>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<int, int> MapSfixed32Sfixed32 {
get { return mapSfixed32Sfixed32_; }
}
@@ -1022,6 +1108,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pbc::MapField<long, long>.Codec _map_mapSfixed64Sfixed64_codec
= new pbc::MapField<long, long>.Codec(pb::FieldCodec.ForSFixed64(9), pb::FieldCodec.ForSFixed64(17), 82);
private readonly pbc::MapField<long, long> mapSfixed64Sfixed64_ = new pbc::MapField<long, long>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<long, long> MapSfixed64Sfixed64 {
get { return mapSfixed64Sfixed64_; }
}
@@ -1031,6 +1118,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pbc::MapField<int, float>.Codec _map_mapInt32Float_codec
= new pbc::MapField<int, float>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForFloat(21), 90);
private readonly pbc::MapField<int, float> mapInt32Float_ = new pbc::MapField<int, float>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<int, float> MapInt32Float {
get { return mapInt32Float_; }
}
@@ -1040,6 +1128,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pbc::MapField<int, double>.Codec _map_mapInt32Double_codec
= new pbc::MapField<int, double>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForDouble(17), 98);
private readonly pbc::MapField<int, double> mapInt32Double_ = new pbc::MapField<int, double>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<int, double> MapInt32Double {
get { return mapInt32Double_; }
}
@@ -1049,6 +1138,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pbc::MapField<bool, bool>.Codec _map_mapBoolBool_codec
= new pbc::MapField<bool, bool>.Codec(pb::FieldCodec.ForBool(8), pb::FieldCodec.ForBool(16), 106);
private readonly pbc::MapField<bool, bool> mapBoolBool_ = new pbc::MapField<bool, bool>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<bool, bool> MapBoolBool {
get { return mapBoolBool_; }
}
@@ -1058,6 +1148,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pbc::MapField<int, global::Google.Protobuf.TestProtos.MapEnum>.Codec _map_mapInt32Enum_codec
= new pbc::MapField<int, global::Google.Protobuf.TestProtos.MapEnum>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForEnum(16, x => (int) x, x => (global::Google.Protobuf.TestProtos.MapEnum) x), 114);
private readonly pbc::MapField<int, global::Google.Protobuf.TestProtos.MapEnum> mapInt32Enum_ = new pbc::MapField<int, global::Google.Protobuf.TestProtos.MapEnum>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<int, global::Google.Protobuf.TestProtos.MapEnum> MapInt32Enum {
get { return mapInt32Enum_; }
}
@@ -1067,14 +1158,17 @@ namespace Google.Protobuf.TestProtos {
private static readonly pbc::MapField<int, global::Google.Protobuf.TestProtos.ForeignMessage>.Codec _map_mapInt32ForeignMessage_codec
= new pbc::MapField<int, global::Google.Protobuf.TestProtos.ForeignMessage>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForMessage(18, global::Google.Protobuf.TestProtos.ForeignMessage.Parser), 122);
private readonly pbc::MapField<int, global::Google.Protobuf.TestProtos.ForeignMessage> mapInt32ForeignMessage_ = new pbc::MapField<int, global::Google.Protobuf.TestProtos.ForeignMessage>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<int, global::Google.Protobuf.TestProtos.ForeignMessage> MapInt32ForeignMessage {
get { return mapInt32ForeignMessage_; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as TestArenaMap);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(TestArenaMap other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -1100,6 +1194,7 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
hash ^= MapInt32Int32.GetHashCode();
@@ -1120,10 +1215,12 @@ namespace Google.Protobuf.TestProtos {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
mapInt32Int32_.WriteTo(output, _map_mapInt32Int32_codec);
mapInt64Int64_.WriteTo(output, _map_mapInt64Int64_codec);
@@ -1142,6 +1239,7 @@ namespace Google.Protobuf.TestProtos {
mapInt32ForeignMessage_.WriteTo(output, _map_mapInt32ForeignMessage_codec);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
size += mapInt32Int32_.CalculateSize(_map_mapInt32Int32_codec);
@@ -1162,6 +1260,7 @@ namespace Google.Protobuf.TestProtos {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(TestArenaMap other) {
if (other == null) {
return;
@@ -1183,6 +1282,7 @@ namespace Google.Protobuf.TestProtos {
mapInt32ForeignMessage_.Add(other.mapInt32ForeignMessage_);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -1260,29 +1360,34 @@ namespace Google.Protobuf.TestProtos {
/// Previously, message containing enum called Type cannot be used as value of
/// map field.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class MessageContainingEnumCalledType : pb::IMessage<MessageContainingEnumCalledType> {
private static readonly pb::MessageParser<MessageContainingEnumCalledType> _parser = new pb::MessageParser<MessageContainingEnumCalledType>(() => new MessageContainingEnumCalledType());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<MessageContainingEnumCalledType> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.MapUnittestProto3Reflection.Descriptor.MessageTypes[5]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public MessageContainingEnumCalledType() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public MessageContainingEnumCalledType(MessageContainingEnumCalledType other) : this() {
type_ = other.type_.Clone();
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public MessageContainingEnumCalledType Clone() {
return new MessageContainingEnumCalledType(this);
}
@@ -1292,14 +1397,17 @@ namespace Google.Protobuf.TestProtos {
private static readonly pbc::MapField<int, global::Google.Protobuf.TestProtos.MessageContainingEnumCalledType>.Codec _map_type_codec
= new pbc::MapField<int, global::Google.Protobuf.TestProtos.MessageContainingEnumCalledType>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForMessage(18, global::Google.Protobuf.TestProtos.MessageContainingEnumCalledType.Parser), 10);
private readonly pbc::MapField<int, global::Google.Protobuf.TestProtos.MessageContainingEnumCalledType> type_ = new pbc::MapField<int, global::Google.Protobuf.TestProtos.MessageContainingEnumCalledType>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<int, global::Google.Protobuf.TestProtos.MessageContainingEnumCalledType> Type {
get { return type_; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as MessageContainingEnumCalledType);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(MessageContainingEnumCalledType other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -1311,26 +1419,31 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
hash ^= Type.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
type_.WriteTo(output, _map_type_codec);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
size += type_.CalculateSize(_map_type_codec);
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(MessageContainingEnumCalledType other) {
if (other == null) {
return;
@@ -1338,6 +1451,7 @@ namespace Google.Protobuf.TestProtos {
type_.Add(other.type_);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -1355,10 +1469,10 @@ namespace Google.Protobuf.TestProtos {
#region Nested types
/// <summary>Container for nested types declared in the MessageContainingEnumCalledType message type.</summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static partial class Types {
public enum Type {
- TYPE_FOO = 0,
+ [pbr::OriginalName("TYPE_FOO")] Foo = 0,
}
}
@@ -1369,29 +1483,34 @@ namespace Google.Protobuf.TestProtos {
/// <summary>
/// Previously, message cannot contain map field called "entry".
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class MessageContainingMapCalledEntry : pb::IMessage<MessageContainingMapCalledEntry> {
private static readonly pb::MessageParser<MessageContainingMapCalledEntry> _parser = new pb::MessageParser<MessageContainingMapCalledEntry>(() => new MessageContainingMapCalledEntry());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<MessageContainingMapCalledEntry> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.MapUnittestProto3Reflection.Descriptor.MessageTypes[6]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public MessageContainingMapCalledEntry() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public MessageContainingMapCalledEntry(MessageContainingMapCalledEntry other) : this() {
entry_ = other.entry_.Clone();
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public MessageContainingMapCalledEntry Clone() {
return new MessageContainingMapCalledEntry(this);
}
@@ -1401,14 +1520,17 @@ namespace Google.Protobuf.TestProtos {
private static readonly pbc::MapField<int, int>.Codec _map_entry_codec
= new pbc::MapField<int, int>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForInt32(16), 10);
private readonly pbc::MapField<int, int> entry_ = new pbc::MapField<int, int>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<int, int> Entry {
get { return entry_; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as MessageContainingMapCalledEntry);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(MessageContainingMapCalledEntry other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -1420,26 +1542,31 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
hash ^= Entry.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
entry_.WriteTo(output, _map_entry_codec);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
size += entry_.CalculateSize(_map_entry_codec);
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(MessageContainingMapCalledEntry other) {
if (other == null) {
return;
@@ -1447,6 +1574,7 @@ namespace Google.Protobuf.TestProtos {
entry_.Add(other.entry_);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportProto3.cs b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportProto3.cs
index f257b46c..f6df4e87 100644
--- a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportProto3.cs
+++ b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportProto3.cs
@@ -10,7 +10,6 @@ using scg = global::System.Collections.Generic;
namespace Google.Protobuf.TestProtos {
/// <summary>Holder for reflection information generated from google/protobuf/unittest_import_proto3.proto</summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public static partial class UnittestImportProto3Reflection {
#region Descriptor
@@ -33,8 +32,8 @@ namespace Google.Protobuf.TestProtos {
"Mw=="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { global::Google.Protobuf.TestProtos.UnittestImportPublicProto3Reflection.Descriptor, },
- new pbr::GeneratedCodeInfo(new[] {typeof(global::Google.Protobuf.TestProtos.ImportEnum), }, new pbr::GeneratedCodeInfo[] {
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.ImportMessage), global::Google.Protobuf.TestProtos.ImportMessage.Parser, new[]{ "D" }, null, null, null)
+ new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Google.Protobuf.TestProtos.ImportEnum), }, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.ImportMessage), global::Google.Protobuf.TestProtos.ImportMessage.Parser, new[]{ "D" }, null, null, null)
}));
}
#endregion
@@ -42,38 +41,43 @@ namespace Google.Protobuf.TestProtos {
}
#region Enums
public enum ImportEnum {
- IMPORT_ENUM_UNSPECIFIED = 0,
- IMPORT_FOO = 7,
- IMPORT_BAR = 8,
- IMPORT_BAZ = 9,
+ [pbr::OriginalName("IMPORT_ENUM_UNSPECIFIED")] Unspecified = 0,
+ [pbr::OriginalName("IMPORT_FOO")] ImportFoo = 7,
+ [pbr::OriginalName("IMPORT_BAR")] ImportBar = 8,
+ [pbr::OriginalName("IMPORT_BAZ")] ImportBaz = 9,
}
#endregion
#region Messages
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class ImportMessage : pb::IMessage<ImportMessage> {
private static readonly pb::MessageParser<ImportMessage> _parser = new pb::MessageParser<ImportMessage>(() => new ImportMessage());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<ImportMessage> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestImportProto3Reflection.Descriptor.MessageTypes[0]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ImportMessage() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ImportMessage(ImportMessage other) : this() {
d_ = other.d_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ImportMessage Clone() {
return new ImportMessage(this);
}
@@ -81,6 +85,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "d" field.</summary>
public const int DFieldNumber = 1;
private int d_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int D {
get { return d_; }
set {
@@ -88,10 +93,12 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as ImportMessage);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(ImportMessage other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -103,16 +110,19 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (D != 0) hash ^= D.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (D != 0) {
output.WriteRawTag(8);
@@ -120,6 +130,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (D != 0) {
@@ -128,6 +139,7 @@ namespace Google.Protobuf.TestProtos {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(ImportMessage other) {
if (other == null) {
return;
@@ -137,6 +149,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportPublicProto3.cs b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportPublicProto3.cs
index 2881ca0f..67b8edf4 100644
--- a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportPublicProto3.cs
+++ b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportPublicProto3.cs
@@ -10,7 +10,6 @@ using scg = global::System.Collections.Generic;
namespace Google.Protobuf.TestProtos {
/// <summary>Holder for reflection information generated from google/protobuf/unittest_import_public_proto3.proto</summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public static partial class UnittestImportPublicProto3Reflection {
#region Descriptor
@@ -29,37 +28,42 @@ namespace Google.Protobuf.TestProtos {
"Zi50ZXN0qgIaR29vZ2xlLlByb3RvYnVmLlRlc3RQcm90b3NiBnByb3RvMw=="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
- new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.PublicImportMessage), global::Google.Protobuf.TestProtos.PublicImportMessage.Parser, new[]{ "E" }, null, null, null)
+ new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.PublicImportMessage), global::Google.Protobuf.TestProtos.PublicImportMessage.Parser, new[]{ "E" }, null, null, null)
}));
}
#endregion
}
#region Messages
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class PublicImportMessage : pb::IMessage<PublicImportMessage> {
private static readonly pb::MessageParser<PublicImportMessage> _parser = new pb::MessageParser<PublicImportMessage>(() => new PublicImportMessage());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<PublicImportMessage> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestImportPublicProto3Reflection.Descriptor.MessageTypes[0]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public PublicImportMessage() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public PublicImportMessage(PublicImportMessage other) : this() {
e_ = other.e_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public PublicImportMessage Clone() {
return new PublicImportMessage(this);
}
@@ -67,6 +71,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "e" field.</summary>
public const int EFieldNumber = 1;
private int e_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int E {
get { return e_; }
set {
@@ -74,10 +79,12 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as PublicImportMessage);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(PublicImportMessage other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -89,16 +96,19 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (E != 0) hash ^= E.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (E != 0) {
output.WriteRawTag(8);
@@ -106,6 +116,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (E != 0) {
@@ -114,6 +125,7 @@ namespace Google.Protobuf.TestProtos {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(PublicImportMessage other) {
if (other == null) {
return;
@@ -123,6 +135,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestIssues.cs b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestIssues.cs
index cf34e8bc..f2db6b4e 100644
--- a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestIssues.cs
+++ b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestIssues.cs
@@ -10,7 +10,6 @@ using scg = global::System.Collections.Generic;
namespace UnitTest.Issues.TestProtos {
/// <summary>Holder for reflection information generated from unittest_issues.proto</summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public static partial class UnittestIssuesReflection {
#region Descriptor
@@ -42,20 +41,23 @@ namespace UnitTest.Issues.TestProtos {
"CgtwbGFpbl9pbnQzMhgEIAEoBRITCglvMV9zdHJpbmcYAiABKAlIABISCghv",
"MV9pbnQzMhgFIAEoBUgAEhQKDHBsYWluX3N0cmluZxgBIAEoCRISCghvMl9p",
"bnQzMhgGIAEoBUgBEhMKCW8yX3N0cmluZxgDIAEoCUgBQgQKAm8xQgQKAm8y",
- "KlUKDE5lZ2F0aXZlRW51bRIWChJORUdBVElWRV9FTlVNX1pFUk8QABIWCglG",
- "aXZlQmVsb3cQ+///////////ARIVCghNaW51c09uZRD///////////8BKi4K",
- "DkRlcHJlY2F0ZWRFbnVtEhMKD0RFUFJFQ0FURURfWkVSTxAAEgcKA29uZRAB",
- "Qh9IAaoCGlVuaXRUZXN0Lklzc3Vlcy5UZXN0UHJvdG9zYgZwcm90bzM="));
+ "IksKDFRlc3RKc29uTmFtZRIMCgRuYW1lGAEgASgJEhkKC2Rlc2NyaXB0aW9u",
+ "GAIgASgJUgRkZXNjEhIKBGd1aWQYAyABKAlSBGV4aWQqVQoMTmVnYXRpdmVF",
+ "bnVtEhYKEk5FR0FUSVZFX0VOVU1fWkVSTxAAEhYKCUZpdmVCZWxvdxD7////",
+ "//////8BEhUKCE1pbnVzT25lEP///////////wEqLgoORGVwcmVjYXRlZEVu",
+ "dW0SEwoPREVQUkVDQVRFRF9aRVJPEAASBwoDb25lEAFCH0gBqgIaVW5pdFRl",
+ "c3QuSXNzdWVzLlRlc3RQcm90b3NiBnByb3RvMw=="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
- new pbr::GeneratedCodeInfo(new[] {typeof(global::UnitTest.Issues.TestProtos.NegativeEnum), typeof(global::UnitTest.Issues.TestProtos.DeprecatedEnum), }, new pbr::GeneratedCodeInfo[] {
- new pbr::GeneratedCodeInfo(typeof(global::UnitTest.Issues.TestProtos.Issue307), global::UnitTest.Issues.TestProtos.Issue307.Parser, null, null, null, new pbr::GeneratedCodeInfo[] { new pbr::GeneratedCodeInfo(typeof(global::UnitTest.Issues.TestProtos.Issue307.Types.NestedOnce), global::UnitTest.Issues.TestProtos.Issue307.Types.NestedOnce.Parser, null, null, null, new pbr::GeneratedCodeInfo[] { new pbr::GeneratedCodeInfo(typeof(global::UnitTest.Issues.TestProtos.Issue307.Types.NestedOnce.Types.NestedTwice), global::UnitTest.Issues.TestProtos.Issue307.Types.NestedOnce.Types.NestedTwice.Parser, null, null, null, null)})}),
- new pbr::GeneratedCodeInfo(typeof(global::UnitTest.Issues.TestProtos.NegativeEnumMessage), global::UnitTest.Issues.TestProtos.NegativeEnumMessage.Parser, new[]{ "Value", "Values", "PackedValues" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::UnitTest.Issues.TestProtos.DeprecatedChild), global::UnitTest.Issues.TestProtos.DeprecatedChild.Parser, null, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::UnitTest.Issues.TestProtos.DeprecatedFieldsMessage), global::UnitTest.Issues.TestProtos.DeprecatedFieldsMessage.Parser, new[]{ "PrimitiveValue", "PrimitiveArray", "MessageValue", "MessageArray", "EnumValue", "EnumArray" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::UnitTest.Issues.TestProtos.ItemField), global::UnitTest.Issues.TestProtos.ItemField.Parser, new[]{ "Item" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::UnitTest.Issues.TestProtos.ReservedNames), global::UnitTest.Issues.TestProtos.ReservedNames.Parser, new[]{ "Types_", "Descriptor_" }, null, null, new pbr::GeneratedCodeInfo[] { new pbr::GeneratedCodeInfo(typeof(global::UnitTest.Issues.TestProtos.ReservedNames.Types.SomeNestedType), global::UnitTest.Issues.TestProtos.ReservedNames.Types.SomeNestedType.Parser, null, null, null, null)}),
- new pbr::GeneratedCodeInfo(typeof(global::UnitTest.Issues.TestProtos.TestJsonFieldOrdering), global::UnitTest.Issues.TestProtos.TestJsonFieldOrdering.Parser, new[]{ "PlainInt32", "O1String", "O1Int32", "PlainString", "O2Int32", "O2String" }, new[]{ "O1", "O2" }, null, null)
+ new pbr::GeneratedClrTypeInfo(new[] {typeof(global::UnitTest.Issues.TestProtos.NegativeEnum), typeof(global::UnitTest.Issues.TestProtos.DeprecatedEnum), }, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.Issue307), global::UnitTest.Issues.TestProtos.Issue307.Parser, null, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.Issue307.Types.NestedOnce), global::UnitTest.Issues.TestProtos.Issue307.Types.NestedOnce.Parser, null, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.Issue307.Types.NestedOnce.Types.NestedTwice), global::UnitTest.Issues.TestProtos.Issue307.Types.NestedOnce.Types.NestedTwice.Parser, null, null, null, null)})}),
+ new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.NegativeEnumMessage), global::UnitTest.Issues.TestProtos.NegativeEnumMessage.Parser, new[]{ "Value", "Values", "PackedValues" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.DeprecatedChild), global::UnitTest.Issues.TestProtos.DeprecatedChild.Parser, null, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.DeprecatedFieldsMessage), global::UnitTest.Issues.TestProtos.DeprecatedFieldsMessage.Parser, new[]{ "PrimitiveValue", "PrimitiveArray", "MessageValue", "MessageArray", "EnumValue", "EnumArray" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.ItemField), global::UnitTest.Issues.TestProtos.ItemField.Parser, new[]{ "Item" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.ReservedNames), global::UnitTest.Issues.TestProtos.ReservedNames.Parser, new[]{ "Types_", "Descriptor_" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.ReservedNames.Types.SomeNestedType), global::UnitTest.Issues.TestProtos.ReservedNames.Types.SomeNestedType.Parser, null, null, null, null)}),
+ new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.TestJsonFieldOrdering), global::UnitTest.Issues.TestProtos.TestJsonFieldOrdering.Parser, new[]{ "PlainInt32", "O1String", "O1Int32", "PlainString", "O2Int32", "O2String" }, new[]{ "O1", "O2" }, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.TestJsonName), global::UnitTest.Issues.TestProtos.TestJsonName.Parser, new[]{ "Name", "Description", "Guid" }, null, null, null)
}));
}
#endregion
@@ -63,14 +65,14 @@ namespace UnitTest.Issues.TestProtos {
}
#region Enums
public enum NegativeEnum {
- NEGATIVE_ENUM_ZERO = 0,
- FiveBelow = -5,
- MinusOne = -1,
+ [pbr::OriginalName("NEGATIVE_ENUM_ZERO")] Zero = 0,
+ [pbr::OriginalName("FiveBelow")] FiveBelow = -5,
+ [pbr::OriginalName("MinusOne")] MinusOne = -1,
}
public enum DeprecatedEnum {
- DEPRECATED_ZERO = 0,
- one = 1,
+ [pbr::OriginalName("DEPRECATED_ZERO")] DeprecatedZero = 0,
+ [pbr::OriginalName("one")] One = 1,
}
#endregion
@@ -80,36 +82,43 @@ namespace UnitTest.Issues.TestProtos {
/// Issue 307: when generating doubly-nested types, any references
/// should be of the form A.Types.B.Types.C.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class Issue307 : pb::IMessage<Issue307> {
private static readonly pb::MessageParser<Issue307> _parser = new pb::MessageParser<Issue307>(() => new Issue307());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<Issue307> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::UnitTest.Issues.TestProtos.UnittestIssuesReflection.Descriptor.MessageTypes[0]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Issue307() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Issue307(Issue307 other) : this() {
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Issue307 Clone() {
return new Issue307(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as Issue307);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(Issue307 other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -120,29 +129,35 @@ namespace UnitTest.Issues.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(Issue307 other) {
if (other == null) {
return;
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -156,38 +171,45 @@ namespace UnitTest.Issues.TestProtos {
#region Nested types
/// <summary>Container for nested types declared in the Issue307 message type.</summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static partial class Types {
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class NestedOnce : pb::IMessage<NestedOnce> {
private static readonly pb::MessageParser<NestedOnce> _parser = new pb::MessageParser<NestedOnce>(() => new NestedOnce());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<NestedOnce> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::UnitTest.Issues.TestProtos.Issue307.Descriptor.NestedTypes[0]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public NestedOnce() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public NestedOnce(NestedOnce other) : this() {
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public NestedOnce Clone() {
return new NestedOnce(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as NestedOnce);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(NestedOnce other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -198,29 +220,35 @@ namespace UnitTest.Issues.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(NestedOnce other) {
if (other == null) {
return;
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -234,38 +262,45 @@ namespace UnitTest.Issues.TestProtos {
#region Nested types
/// <summary>Container for nested types declared in the NestedOnce message type.</summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static partial class Types {
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class NestedTwice : pb::IMessage<NestedTwice> {
private static readonly pb::MessageParser<NestedTwice> _parser = new pb::MessageParser<NestedTwice>(() => new NestedTwice());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<NestedTwice> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::UnitTest.Issues.TestProtos.Issue307.Types.NestedOnce.Descriptor.NestedTypes[0]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public NestedTwice() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public NestedTwice(NestedTwice other) : this() {
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public NestedTwice Clone() {
return new NestedTwice(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as NestedTwice);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(NestedTwice other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -276,29 +311,35 @@ namespace UnitTest.Issues.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(NestedTwice other) {
if (other == null) {
return;
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -322,38 +363,44 @@ namespace UnitTest.Issues.TestProtos {
}
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class NegativeEnumMessage : pb::IMessage<NegativeEnumMessage> {
private static readonly pb::MessageParser<NegativeEnumMessage> _parser = new pb::MessageParser<NegativeEnumMessage>(() => new NegativeEnumMessage());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<NegativeEnumMessage> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::UnitTest.Issues.TestProtos.UnittestIssuesReflection.Descriptor.MessageTypes[1]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public NegativeEnumMessage() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public NegativeEnumMessage(NegativeEnumMessage other) : this() {
value_ = other.value_;
values_ = other.values_.Clone();
packedValues_ = other.packedValues_.Clone();
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public NegativeEnumMessage Clone() {
return new NegativeEnumMessage(this);
}
/// <summary>Field number for the "value" field.</summary>
public const int ValueFieldNumber = 1;
- private global::UnitTest.Issues.TestProtos.NegativeEnum value_ = global::UnitTest.Issues.TestProtos.NegativeEnum.NEGATIVE_ENUM_ZERO;
+ private global::UnitTest.Issues.TestProtos.NegativeEnum value_ = 0;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::UnitTest.Issues.TestProtos.NegativeEnum Value {
get { return value_; }
set {
@@ -366,6 +413,7 @@ namespace UnitTest.Issues.TestProtos {
private static readonly pb::FieldCodec<global::UnitTest.Issues.TestProtos.NegativeEnum> _repeated_values_codec
= pb::FieldCodec.ForEnum(16, x => (int) x, x => (global::UnitTest.Issues.TestProtos.NegativeEnum) x);
private readonly pbc::RepeatedField<global::UnitTest.Issues.TestProtos.NegativeEnum> values_ = new pbc::RepeatedField<global::UnitTest.Issues.TestProtos.NegativeEnum>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::UnitTest.Issues.TestProtos.NegativeEnum> Values {
get { return values_; }
}
@@ -375,14 +423,17 @@ namespace UnitTest.Issues.TestProtos {
private static readonly pb::FieldCodec<global::UnitTest.Issues.TestProtos.NegativeEnum> _repeated_packedValues_codec
= pb::FieldCodec.ForEnum(26, x => (int) x, x => (global::UnitTest.Issues.TestProtos.NegativeEnum) x);
private readonly pbc::RepeatedField<global::UnitTest.Issues.TestProtos.NegativeEnum> packedValues_ = new pbc::RepeatedField<global::UnitTest.Issues.TestProtos.NegativeEnum>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::UnitTest.Issues.TestProtos.NegativeEnum> PackedValues {
get { return packedValues_; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as NegativeEnumMessage);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(NegativeEnumMessage other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -396,20 +447,23 @@ namespace UnitTest.Issues.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
- if (Value != global::UnitTest.Issues.TestProtos.NegativeEnum.NEGATIVE_ENUM_ZERO) hash ^= Value.GetHashCode();
+ if (Value != 0) hash ^= Value.GetHashCode();
hash ^= values_.GetHashCode();
hash ^= packedValues_.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
- if (Value != global::UnitTest.Issues.TestProtos.NegativeEnum.NEGATIVE_ENUM_ZERO) {
+ if (Value != 0) {
output.WriteRawTag(8);
output.WriteEnum((int) Value);
}
@@ -417,9 +471,10 @@ namespace UnitTest.Issues.TestProtos {
packedValues_.WriteTo(output, _repeated_packedValues_codec);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
- if (Value != global::UnitTest.Issues.TestProtos.NegativeEnum.NEGATIVE_ENUM_ZERO) {
+ if (Value != 0) {
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Value);
}
size += values_.CalculateSize(_repeated_values_codec);
@@ -427,17 +482,19 @@ namespace UnitTest.Issues.TestProtos {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(NegativeEnumMessage other) {
if (other == null) {
return;
}
- if (other.Value != global::UnitTest.Issues.TestProtos.NegativeEnum.NEGATIVE_ENUM_ZERO) {
+ if (other.Value != 0) {
Value = other.Value;
}
values_.Add(other.values_);
packedValues_.Add(other.packedValues_);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -465,36 +522,43 @@ namespace UnitTest.Issues.TestProtos {
}
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class DeprecatedChild : pb::IMessage<DeprecatedChild> {
private static readonly pb::MessageParser<DeprecatedChild> _parser = new pb::MessageParser<DeprecatedChild>(() => new DeprecatedChild());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<DeprecatedChild> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::UnitTest.Issues.TestProtos.UnittestIssuesReflection.Descriptor.MessageTypes[2]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public DeprecatedChild() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public DeprecatedChild(DeprecatedChild other) : this() {
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public DeprecatedChild Clone() {
return new DeprecatedChild(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as DeprecatedChild);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(DeprecatedChild other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -505,29 +569,35 @@ namespace UnitTest.Issues.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(DeprecatedChild other) {
if (other == null) {
return;
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -541,25 +611,29 @@ namespace UnitTest.Issues.TestProtos {
}
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class DeprecatedFieldsMessage : pb::IMessage<DeprecatedFieldsMessage> {
private static readonly pb::MessageParser<DeprecatedFieldsMessage> _parser = new pb::MessageParser<DeprecatedFieldsMessage>(() => new DeprecatedFieldsMessage());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<DeprecatedFieldsMessage> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::UnitTest.Issues.TestProtos.UnittestIssuesReflection.Descriptor.MessageTypes[3]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public DeprecatedFieldsMessage() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public DeprecatedFieldsMessage(DeprecatedFieldsMessage other) : this() {
primitiveValue_ = other.primitiveValue_;
primitiveArray_ = other.primitiveArray_.Clone();
@@ -569,6 +643,7 @@ namespace UnitTest.Issues.TestProtos {
enumArray_ = other.enumArray_.Clone();
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public DeprecatedFieldsMessage Clone() {
return new DeprecatedFieldsMessage(this);
}
@@ -576,7 +651,8 @@ namespace UnitTest.Issues.TestProtos {
/// <summary>Field number for the "PrimitiveValue" field.</summary>
public const int PrimitiveValueFieldNumber = 1;
private int primitiveValue_;
- [global::System.ObsoleteAttribute()]
+ [global::System.ObsoleteAttribute]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int PrimitiveValue {
get { return primitiveValue_; }
set {
@@ -589,7 +665,8 @@ namespace UnitTest.Issues.TestProtos {
private static readonly pb::FieldCodec<int> _repeated_primitiveArray_codec
= pb::FieldCodec.ForInt32(18);
private readonly pbc::RepeatedField<int> primitiveArray_ = new pbc::RepeatedField<int>();
- [global::System.ObsoleteAttribute()]
+ [global::System.ObsoleteAttribute]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<int> PrimitiveArray {
get { return primitiveArray_; }
}
@@ -597,7 +674,8 @@ namespace UnitTest.Issues.TestProtos {
/// <summary>Field number for the "MessageValue" field.</summary>
public const int MessageValueFieldNumber = 3;
private global::UnitTest.Issues.TestProtos.DeprecatedChild messageValue_;
- [global::System.ObsoleteAttribute()]
+ [global::System.ObsoleteAttribute]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::UnitTest.Issues.TestProtos.DeprecatedChild MessageValue {
get { return messageValue_; }
set {
@@ -610,15 +688,17 @@ namespace UnitTest.Issues.TestProtos {
private static readonly pb::FieldCodec<global::UnitTest.Issues.TestProtos.DeprecatedChild> _repeated_messageArray_codec
= pb::FieldCodec.ForMessage(34, global::UnitTest.Issues.TestProtos.DeprecatedChild.Parser);
private readonly pbc::RepeatedField<global::UnitTest.Issues.TestProtos.DeprecatedChild> messageArray_ = new pbc::RepeatedField<global::UnitTest.Issues.TestProtos.DeprecatedChild>();
- [global::System.ObsoleteAttribute()]
+ [global::System.ObsoleteAttribute]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::UnitTest.Issues.TestProtos.DeprecatedChild> MessageArray {
get { return messageArray_; }
}
/// <summary>Field number for the "EnumValue" field.</summary>
public const int EnumValueFieldNumber = 5;
- private global::UnitTest.Issues.TestProtos.DeprecatedEnum enumValue_ = global::UnitTest.Issues.TestProtos.DeprecatedEnum.DEPRECATED_ZERO;
- [global::System.ObsoleteAttribute()]
+ private global::UnitTest.Issues.TestProtos.DeprecatedEnum enumValue_ = 0;
+ [global::System.ObsoleteAttribute]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::UnitTest.Issues.TestProtos.DeprecatedEnum EnumValue {
get { return enumValue_; }
set {
@@ -631,15 +711,18 @@ namespace UnitTest.Issues.TestProtos {
private static readonly pb::FieldCodec<global::UnitTest.Issues.TestProtos.DeprecatedEnum> _repeated_enumArray_codec
= pb::FieldCodec.ForEnum(50, x => (int) x, x => (global::UnitTest.Issues.TestProtos.DeprecatedEnum) x);
private readonly pbc::RepeatedField<global::UnitTest.Issues.TestProtos.DeprecatedEnum> enumArray_ = new pbc::RepeatedField<global::UnitTest.Issues.TestProtos.DeprecatedEnum>();
- [global::System.ObsoleteAttribute()]
+ [global::System.ObsoleteAttribute]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::UnitTest.Issues.TestProtos.DeprecatedEnum> EnumArray {
get { return enumArray_; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as DeprecatedFieldsMessage);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(DeprecatedFieldsMessage other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -656,21 +739,24 @@ namespace UnitTest.Issues.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (PrimitiveValue != 0) hash ^= PrimitiveValue.GetHashCode();
hash ^= primitiveArray_.GetHashCode();
if (messageValue_ != null) hash ^= MessageValue.GetHashCode();
hash ^= messageArray_.GetHashCode();
- if (EnumValue != global::UnitTest.Issues.TestProtos.DeprecatedEnum.DEPRECATED_ZERO) hash ^= EnumValue.GetHashCode();
+ if (EnumValue != 0) hash ^= EnumValue.GetHashCode();
hash ^= enumArray_.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (PrimitiveValue != 0) {
output.WriteRawTag(8);
@@ -682,13 +768,14 @@ namespace UnitTest.Issues.TestProtos {
output.WriteMessage(MessageValue);
}
messageArray_.WriteTo(output, _repeated_messageArray_codec);
- if (EnumValue != global::UnitTest.Issues.TestProtos.DeprecatedEnum.DEPRECATED_ZERO) {
+ if (EnumValue != 0) {
output.WriteRawTag(40);
output.WriteEnum((int) EnumValue);
}
enumArray_.WriteTo(output, _repeated_enumArray_codec);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (PrimitiveValue != 0) {
@@ -699,13 +786,14 @@ namespace UnitTest.Issues.TestProtos {
size += 1 + pb::CodedOutputStream.ComputeMessageSize(MessageValue);
}
size += messageArray_.CalculateSize(_repeated_messageArray_codec);
- if (EnumValue != global::UnitTest.Issues.TestProtos.DeprecatedEnum.DEPRECATED_ZERO) {
+ if (EnumValue != 0) {
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) EnumValue);
}
size += enumArray_.CalculateSize(_repeated_enumArray_codec);
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(DeprecatedFieldsMessage other) {
if (other == null) {
return;
@@ -721,12 +809,13 @@ namespace UnitTest.Issues.TestProtos {
MessageValue.MergeFrom(other.MessageValue);
}
messageArray_.Add(other.messageArray_);
- if (other.EnumValue != global::UnitTest.Issues.TestProtos.DeprecatedEnum.DEPRECATED_ZERO) {
+ if (other.EnumValue != 0) {
EnumValue = other.EnumValue;
}
enumArray_.Add(other.enumArray_);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -772,29 +861,34 @@ namespace UnitTest.Issues.TestProtos {
/// <summary>
/// Issue 45: http://code.google.com/p/protobuf-csharp-port/issues/detail?id=45
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class ItemField : pb::IMessage<ItemField> {
private static readonly pb::MessageParser<ItemField> _parser = new pb::MessageParser<ItemField>(() => new ItemField());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<ItemField> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::UnitTest.Issues.TestProtos.UnittestIssuesReflection.Descriptor.MessageTypes[4]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ItemField() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ItemField(ItemField other) : this() {
item_ = other.item_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ItemField Clone() {
return new ItemField(this);
}
@@ -802,6 +896,7 @@ namespace UnitTest.Issues.TestProtos {
/// <summary>Field number for the "item" field.</summary>
public const int ItemFieldNumber = 1;
private int item_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int Item {
get { return item_; }
set {
@@ -809,10 +904,12 @@ namespace UnitTest.Issues.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as ItemField);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(ItemField other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -824,16 +921,19 @@ namespace UnitTest.Issues.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Item != 0) hash ^= Item.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Item != 0) {
output.WriteRawTag(8);
@@ -841,6 +941,7 @@ namespace UnitTest.Issues.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Item != 0) {
@@ -849,6 +950,7 @@ namespace UnitTest.Issues.TestProtos {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(ItemField other) {
if (other == null) {
return;
@@ -858,6 +960,7 @@ namespace UnitTest.Issues.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -875,30 +978,35 @@ namespace UnitTest.Issues.TestProtos {
}
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class ReservedNames : pb::IMessage<ReservedNames> {
private static readonly pb::MessageParser<ReservedNames> _parser = new pb::MessageParser<ReservedNames>(() => new ReservedNames());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<ReservedNames> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::UnitTest.Issues.TestProtos.UnittestIssuesReflection.Descriptor.MessageTypes[5]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ReservedNames() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ReservedNames(ReservedNames other) : this() {
types_ = other.types_;
descriptor_ = other.descriptor_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ReservedNames Clone() {
return new ReservedNames(this);
}
@@ -906,6 +1014,7 @@ namespace UnitTest.Issues.TestProtos {
/// <summary>Field number for the "types" field.</summary>
public const int Types_FieldNumber = 1;
private int types_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int Types_ {
get { return types_; }
set {
@@ -916,6 +1025,7 @@ namespace UnitTest.Issues.TestProtos {
/// <summary>Field number for the "descriptor" field.</summary>
public const int Descriptor_FieldNumber = 2;
private int descriptor_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int Descriptor_ {
get { return descriptor_; }
set {
@@ -923,10 +1033,12 @@ namespace UnitTest.Issues.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as ReservedNames);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(ReservedNames other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -939,6 +1051,7 @@ namespace UnitTest.Issues.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Types_ != 0) hash ^= Types_.GetHashCode();
@@ -946,10 +1059,12 @@ namespace UnitTest.Issues.TestProtos {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Types_ != 0) {
output.WriteRawTag(8);
@@ -961,6 +1076,7 @@ namespace UnitTest.Issues.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Types_ != 0) {
@@ -972,6 +1088,7 @@ namespace UnitTest.Issues.TestProtos {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(ReservedNames other) {
if (other == null) {
return;
@@ -984,6 +1101,7 @@ namespace UnitTest.Issues.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -1005,41 +1123,48 @@ namespace UnitTest.Issues.TestProtos {
#region Nested types
/// <summary>Container for nested types declared in the ReservedNames message type.</summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static partial class Types {
/// <summary>
/// Force a nested type called Types
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class SomeNestedType : pb::IMessage<SomeNestedType> {
private static readonly pb::MessageParser<SomeNestedType> _parser = new pb::MessageParser<SomeNestedType>(() => new SomeNestedType());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<SomeNestedType> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::UnitTest.Issues.TestProtos.ReservedNames.Descriptor.NestedTypes[0]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public SomeNestedType() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public SomeNestedType(SomeNestedType other) : this() {
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public SomeNestedType Clone() {
return new SomeNestedType(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as SomeNestedType);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(SomeNestedType other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -1050,29 +1175,35 @@ namespace UnitTest.Issues.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(SomeNestedType other) {
if (other == null) {
return;
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -1103,25 +1234,29 @@ namespace UnitTest.Issues.TestProtos {
/// Alternatively, consider just adding this to
/// unittest_proto3.proto if multiple platforms want it.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class TestJsonFieldOrdering : pb::IMessage<TestJsonFieldOrdering> {
private static readonly pb::MessageParser<TestJsonFieldOrdering> _parser = new pb::MessageParser<TestJsonFieldOrdering>(() => new TestJsonFieldOrdering());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<TestJsonFieldOrdering> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::UnitTest.Issues.TestProtos.UnittestIssuesReflection.Descriptor.MessageTypes[6]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestJsonFieldOrdering() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestJsonFieldOrdering(TestJsonFieldOrdering other) : this() {
plainInt32_ = other.plainInt32_;
plainString_ = other.plainString_;
@@ -1145,6 +1280,7 @@ namespace UnitTest.Issues.TestProtos {
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestJsonFieldOrdering Clone() {
return new TestJsonFieldOrdering(this);
}
@@ -1152,6 +1288,7 @@ namespace UnitTest.Issues.TestProtos {
/// <summary>Field number for the "plain_int32" field.</summary>
public const int PlainInt32FieldNumber = 4;
private int plainInt32_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int PlainInt32 {
get { return plainInt32_; }
set {
@@ -1161,16 +1298,18 @@ namespace UnitTest.Issues.TestProtos {
/// <summary>Field number for the "o1_string" field.</summary>
public const int O1StringFieldNumber = 2;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string O1String {
get { return o1Case_ == O1OneofCase.O1String ? (string) o1_ : ""; }
set {
- o1_ = pb::Preconditions.CheckNotNull(value, "value");
+ o1_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
o1Case_ = O1OneofCase.O1String;
}
}
/// <summary>Field number for the "o1_int32" field.</summary>
public const int O1Int32FieldNumber = 5;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int O1Int32 {
get { return o1Case_ == O1OneofCase.O1Int32 ? (int) o1_ : 0; }
set {
@@ -1182,15 +1321,17 @@ namespace UnitTest.Issues.TestProtos {
/// <summary>Field number for the "plain_string" field.</summary>
public const int PlainStringFieldNumber = 1;
private string plainString_ = "";
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string PlainString {
get { return plainString_; }
set {
- plainString_ = pb::Preconditions.CheckNotNull(value, "value");
+ plainString_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
/// <summary>Field number for the "o2_int32" field.</summary>
public const int O2Int32FieldNumber = 6;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int O2Int32 {
get { return o2Case_ == O2OneofCase.O2Int32 ? (int) o2_ : 0; }
set {
@@ -1201,10 +1342,11 @@ namespace UnitTest.Issues.TestProtos {
/// <summary>Field number for the "o2_string" field.</summary>
public const int O2StringFieldNumber = 3;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string O2String {
get { return o2Case_ == O2OneofCase.O2String ? (string) o2_ : ""; }
set {
- o2_ = pb::Preconditions.CheckNotNull(value, "value");
+ o2_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
o2Case_ = O2OneofCase.O2String;
}
}
@@ -1217,10 +1359,12 @@ namespace UnitTest.Issues.TestProtos {
O1Int32 = 5,
}
private O1OneofCase o1Case_ = O1OneofCase.None;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public O1OneofCase O1Case {
get { return o1Case_; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void ClearO1() {
o1Case_ = O1OneofCase.None;
o1_ = null;
@@ -1234,19 +1378,23 @@ namespace UnitTest.Issues.TestProtos {
O2String = 3,
}
private O2OneofCase o2Case_ = O2OneofCase.None;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public O2OneofCase O2Case {
get { return o2Case_; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void ClearO2() {
o2Case_ = O2OneofCase.None;
o2_ = null;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as TestJsonFieldOrdering);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(TestJsonFieldOrdering other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -1265,6 +1413,7 @@ namespace UnitTest.Issues.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (PlainInt32 != 0) hash ^= PlainInt32.GetHashCode();
@@ -1278,10 +1427,12 @@ namespace UnitTest.Issues.TestProtos {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (PlainString.Length != 0) {
output.WriteRawTag(10);
@@ -1309,6 +1460,7 @@ namespace UnitTest.Issues.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (PlainInt32 != 0) {
@@ -1332,6 +1484,7 @@ namespace UnitTest.Issues.TestProtos {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(TestJsonFieldOrdering other) {
if (other == null) {
return;
@@ -1362,6 +1515,7 @@ namespace UnitTest.Issues.TestProtos {
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -1399,6 +1553,182 @@ namespace UnitTest.Issues.TestProtos {
}
+ public sealed partial class TestJsonName : pb::IMessage<TestJsonName> {
+ private static readonly pb::MessageParser<TestJsonName> _parser = new pb::MessageParser<TestJsonName>(() => new TestJsonName());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pb::MessageParser<TestJsonName> Parser { get { return _parser; } }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pbr::MessageDescriptor Descriptor {
+ get { return global::UnitTest.Issues.TestProtos.UnittestIssuesReflection.Descriptor.MessageTypes[7]; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ pbr::MessageDescriptor pb::IMessage.Descriptor {
+ get { return Descriptor; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public TestJsonName() {
+ OnConstruction();
+ }
+
+ partial void OnConstruction();
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public TestJsonName(TestJsonName other) : this() {
+ name_ = other.name_;
+ description_ = other.description_;
+ guid_ = other.guid_;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public TestJsonName Clone() {
+ return new TestJsonName(this);
+ }
+
+ /// <summary>Field number for the "name" field.</summary>
+ public const int NameFieldNumber = 1;
+ private string name_ = "";
+ /// <summary>
+ /// Message for testing the effects for of the json_name option
+ /// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public string Name {
+ get { return name_; }
+ set {
+ name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ }
+ }
+
+ /// <summary>Field number for the "description" field.</summary>
+ public const int DescriptionFieldNumber = 2;
+ private string description_ = "";
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public string Description {
+ get { return description_; }
+ set {
+ description_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ }
+ }
+
+ /// <summary>Field number for the "guid" field.</summary>
+ public const int GuidFieldNumber = 3;
+ private string guid_ = "";
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public string Guid {
+ get { return guid_; }
+ set {
+ guid_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override bool Equals(object other) {
+ return Equals(other as TestJsonName);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool Equals(TestJsonName other) {
+ if (ReferenceEquals(other, null)) {
+ return false;
+ }
+ if (ReferenceEquals(other, this)) {
+ return true;
+ }
+ if (Name != other.Name) return false;
+ if (Description != other.Description) return false;
+ if (Guid != other.Guid) return false;
+ return true;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override int GetHashCode() {
+ int hash = 1;
+ if (Name.Length != 0) hash ^= Name.GetHashCode();
+ if (Description.Length != 0) hash ^= Description.GetHashCode();
+ if (Guid.Length != 0) hash ^= Guid.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 (Name.Length != 0) {
+ output.WriteRawTag(10);
+ output.WriteString(Name);
+ }
+ if (Description.Length != 0) {
+ output.WriteRawTag(18);
+ output.WriteString(Description);
+ }
+ if (Guid.Length != 0) {
+ output.WriteRawTag(26);
+ output.WriteString(Guid);
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int CalculateSize() {
+ int size = 0;
+ if (Name.Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
+ }
+ if (Description.Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(Description);
+ }
+ if (Guid.Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(Guid);
+ }
+ return size;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(TestJsonName other) {
+ if (other == null) {
+ return;
+ }
+ if (other.Name.Length != 0) {
+ Name = other.Name;
+ }
+ if (other.Description.Length != 0) {
+ Description = other.Description;
+ }
+ if (other.Guid.Length != 0) {
+ Guid = other.Guid;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(pb::CodedInputStream input) {
+ uint tag;
+ while ((tag = input.ReadTag()) != 0) {
+ switch(tag) {
+ default:
+ input.SkipLastField();
+ break;
+ case 10: {
+ Name = input.ReadString();
+ break;
+ }
+ case 18: {
+ Description = input.ReadString();
+ break;
+ }
+ case 26: {
+ Guid = input.ReadString();
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
#endregion
}
diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestProto3.cs b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestProto3.cs
index 04de603b..7e71f94d 100644
--- a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestProto3.cs
+++ b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestProto3.cs
@@ -10,7 +10,6 @@ using scg = global::System.Collections.Generic;
namespace Google.Protobuf.TestProtos {
/// <summary>Holder for reflection information generated from google/protobuf/unittest_proto3.proto</summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public static partial class UnittestProto3Reflection {
#region Descriptor
@@ -152,40 +151,40 @@ namespace Google.Protobuf.TestProtos {
"+AEBqgIaR29vZ2xlLlByb3RvYnVmLlRlc3RQcm90b3NiBnByb3RvMw=="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { global::Google.Protobuf.TestProtos.UnittestImportProto3Reflection.Descriptor, },
- new pbr::GeneratedCodeInfo(new[] {typeof(global::Google.Protobuf.TestProtos.ForeignEnum), typeof(global::Google.Protobuf.TestProtos.TestEnumWithDupValue), typeof(global::Google.Protobuf.TestProtos.TestSparseEnum), }, new pbr::GeneratedCodeInfo[] {
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestAllTypes), global::Google.Protobuf.TestProtos.TestAllTypes.Parser, new[]{ "SingleInt32", "SingleInt64", "SingleUint32", "SingleUint64", "SingleSint32", "SingleSint64", "SingleFixed32", "SingleFixed64", "SingleSfixed32", "SingleSfixed64", "SingleFloat", "SingleDouble", "SingleBool", "SingleString", "SingleBytes", "SingleNestedMessage", "SingleForeignMessage", "SingleImportMessage", "SingleNestedEnum", "SingleForeignEnum", "SingleImportEnum", "SinglePublicImportMessage", "RepeatedInt32", "RepeatedInt64", "RepeatedUint32", "RepeatedUint64", "RepeatedSint32", "RepeatedSint64", "RepeatedFixed32", "RepeatedFixed64", "RepeatedSfixed32", "RepeatedSfixed64", "RepeatedFloat", "RepeatedDouble", "RepeatedBool", "RepeatedString", "RepeatedBytes", "RepeatedNestedMessage", "RepeatedForeignMessage", "RepeatedImportMessage", "RepeatedNestedEnum", "RepeatedForeignEnum", "RepeatedImportEnum", "RepeatedPublicImportMessage", "OneofUint32", "OneofNestedMessage", "OneofString", "OneofBytes" }, new[]{ "OneofField" }, new[]{ typeof(global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum) }, new pbr::GeneratedCodeInfo[] { new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage), global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage.Parser, new[]{ "Bb" }, null, null, null)}),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.NestedTestAllTypes), global::Google.Protobuf.TestProtos.NestedTestAllTypes.Parser, new[]{ "Child", "Payload", "RepeatedChild" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestDeprecatedFields), global::Google.Protobuf.TestProtos.TestDeprecatedFields.Parser, new[]{ "DeprecatedInt32" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.ForeignMessage), global::Google.Protobuf.TestProtos.ForeignMessage.Parser, new[]{ "C" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestReservedFields), global::Google.Protobuf.TestProtos.TestReservedFields.Parser, null, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestForeignNested), global::Google.Protobuf.TestProtos.TestForeignNested.Parser, new[]{ "ForeignNested" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestReallyLargeTagNumber), global::Google.Protobuf.TestProtos.TestReallyLargeTagNumber.Parser, new[]{ "A", "Bb" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestRecursiveMessage), global::Google.Protobuf.TestProtos.TestRecursiveMessage.Parser, new[]{ "A", "I" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestMutualRecursionA), global::Google.Protobuf.TestProtos.TestMutualRecursionA.Parser, new[]{ "Bb" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestMutualRecursionB), global::Google.Protobuf.TestProtos.TestMutualRecursionB.Parser, new[]{ "A", "OptionalInt32" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestCamelCaseFieldNames), global::Google.Protobuf.TestProtos.TestCamelCaseFieldNames.Parser, new[]{ "PrimitiveField", "StringField", "EnumField", "MessageField", "RepeatedPrimitiveField", "RepeatedStringField", "RepeatedEnumField", "RepeatedMessageField" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestFieldOrderings), global::Google.Protobuf.TestProtos.TestFieldOrderings.Parser, new[]{ "MyString", "MyInt", "MyFloat", "SingleNestedMessage" }, null, null, new pbr::GeneratedCodeInfo[] { new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestFieldOrderings.Types.NestedMessage), global::Google.Protobuf.TestProtos.TestFieldOrderings.Types.NestedMessage.Parser, new[]{ "Oo", "Bb" }, null, null, null)}),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.SparseEnumMessage), global::Google.Protobuf.TestProtos.SparseEnumMessage.Parser, new[]{ "SparseEnum" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.OneString), global::Google.Protobuf.TestProtos.OneString.Parser, new[]{ "Data" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.MoreString), global::Google.Protobuf.TestProtos.MoreString.Parser, new[]{ "Data" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.OneBytes), global::Google.Protobuf.TestProtos.OneBytes.Parser, new[]{ "Data" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.MoreBytes), global::Google.Protobuf.TestProtos.MoreBytes.Parser, new[]{ "Data" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.Int32Message), global::Google.Protobuf.TestProtos.Int32Message.Parser, new[]{ "Data" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.Uint32Message), global::Google.Protobuf.TestProtos.Uint32Message.Parser, new[]{ "Data" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.Int64Message), global::Google.Protobuf.TestProtos.Int64Message.Parser, new[]{ "Data" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.Uint64Message), global::Google.Protobuf.TestProtos.Uint64Message.Parser, new[]{ "Data" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.BoolMessage), global::Google.Protobuf.TestProtos.BoolMessage.Parser, new[]{ "Data" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestOneof), global::Google.Protobuf.TestProtos.TestOneof.Parser, new[]{ "FooInt", "FooString", "FooMessage" }, new[]{ "Foo" }, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestPackedTypes), global::Google.Protobuf.TestProtos.TestPackedTypes.Parser, new[]{ "PackedInt32", "PackedInt64", "PackedUint32", "PackedUint64", "PackedSint32", "PackedSint64", "PackedFixed32", "PackedFixed64", "PackedSfixed32", "PackedSfixed64", "PackedFloat", "PackedDouble", "PackedBool", "PackedEnum" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestUnpackedTypes), global::Google.Protobuf.TestProtos.TestUnpackedTypes.Parser, new[]{ "UnpackedInt32", "UnpackedInt64", "UnpackedUint32", "UnpackedUint64", "UnpackedSint32", "UnpackedSint64", "UnpackedFixed32", "UnpackedFixed64", "UnpackedSfixed32", "UnpackedSfixed64", "UnpackedFloat", "UnpackedDouble", "UnpackedBool", "UnpackedEnum" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestRepeatedScalarDifferentTagSizes), global::Google.Protobuf.TestProtos.TestRepeatedScalarDifferentTagSizes.Parser, new[]{ "RepeatedFixed32", "RepeatedInt32", "RepeatedFixed64", "RepeatedInt64", "RepeatedFloat", "RepeatedUint64" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestCommentInjectionMessage), global::Google.Protobuf.TestProtos.TestCommentInjectionMessage.Parser, new[]{ "A" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.FooRequest), global::Google.Protobuf.TestProtos.FooRequest.Parser, null, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.FooResponse), global::Google.Protobuf.TestProtos.FooResponse.Parser, null, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.FooClientMessage), global::Google.Protobuf.TestProtos.FooClientMessage.Parser, null, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.FooServerMessage), global::Google.Protobuf.TestProtos.FooServerMessage.Parser, null, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.BarRequest), global::Google.Protobuf.TestProtos.BarRequest.Parser, null, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.BarResponse), global::Google.Protobuf.TestProtos.BarResponse.Parser, null, null, null, null)
+ new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Google.Protobuf.TestProtos.ForeignEnum), typeof(global::Google.Protobuf.TestProtos.TestEnumWithDupValue), typeof(global::Google.Protobuf.TestProtos.TestSparseEnum), }, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestAllTypes), global::Google.Protobuf.TestProtos.TestAllTypes.Parser, new[]{ "SingleInt32", "SingleInt64", "SingleUint32", "SingleUint64", "SingleSint32", "SingleSint64", "SingleFixed32", "SingleFixed64", "SingleSfixed32", "SingleSfixed64", "SingleFloat", "SingleDouble", "SingleBool", "SingleString", "SingleBytes", "SingleNestedMessage", "SingleForeignMessage", "SingleImportMessage", "SingleNestedEnum", "SingleForeignEnum", "SingleImportEnum", "SinglePublicImportMessage", "RepeatedInt32", "RepeatedInt64", "RepeatedUint32", "RepeatedUint64", "RepeatedSint32", "RepeatedSint64", "RepeatedFixed32", "RepeatedFixed64", "RepeatedSfixed32", "RepeatedSfixed64", "RepeatedFloat", "RepeatedDouble", "RepeatedBool", "RepeatedString", "RepeatedBytes", "RepeatedNestedMessage", "RepeatedForeignMessage", "RepeatedImportMessage", "RepeatedNestedEnum", "RepeatedForeignEnum", "RepeatedImportEnum", "RepeatedPublicImportMessage", "OneofUint32", "OneofNestedMessage", "OneofString", "OneofBytes" }, new[]{ "OneofField" }, new[]{ typeof(global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum) }, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage), global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage.Parser, new[]{ "Bb" }, null, null, null)}),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.NestedTestAllTypes), global::Google.Protobuf.TestProtos.NestedTestAllTypes.Parser, new[]{ "Child", "Payload", "RepeatedChild" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestDeprecatedFields), global::Google.Protobuf.TestProtos.TestDeprecatedFields.Parser, new[]{ "DeprecatedInt32" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.ForeignMessage), global::Google.Protobuf.TestProtos.ForeignMessage.Parser, new[]{ "C" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestReservedFields), global::Google.Protobuf.TestProtos.TestReservedFields.Parser, null, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestForeignNested), global::Google.Protobuf.TestProtos.TestForeignNested.Parser, new[]{ "ForeignNested" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestReallyLargeTagNumber), global::Google.Protobuf.TestProtos.TestReallyLargeTagNumber.Parser, new[]{ "A", "Bb" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestRecursiveMessage), global::Google.Protobuf.TestProtos.TestRecursiveMessage.Parser, new[]{ "A", "I" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestMutualRecursionA), global::Google.Protobuf.TestProtos.TestMutualRecursionA.Parser, new[]{ "Bb" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestMutualRecursionB), global::Google.Protobuf.TestProtos.TestMutualRecursionB.Parser, new[]{ "A", "OptionalInt32" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestCamelCaseFieldNames), global::Google.Protobuf.TestProtos.TestCamelCaseFieldNames.Parser, new[]{ "PrimitiveField", "StringField", "EnumField", "MessageField", "RepeatedPrimitiveField", "RepeatedStringField", "RepeatedEnumField", "RepeatedMessageField" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestFieldOrderings), global::Google.Protobuf.TestProtos.TestFieldOrderings.Parser, new[]{ "MyString", "MyInt", "MyFloat", "SingleNestedMessage" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestFieldOrderings.Types.NestedMessage), global::Google.Protobuf.TestProtos.TestFieldOrderings.Types.NestedMessage.Parser, new[]{ "Oo", "Bb" }, null, null, null)}),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.SparseEnumMessage), global::Google.Protobuf.TestProtos.SparseEnumMessage.Parser, new[]{ "SparseEnum" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.OneString), global::Google.Protobuf.TestProtos.OneString.Parser, new[]{ "Data" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.MoreString), global::Google.Protobuf.TestProtos.MoreString.Parser, new[]{ "Data" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.OneBytes), global::Google.Protobuf.TestProtos.OneBytes.Parser, new[]{ "Data" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.MoreBytes), global::Google.Protobuf.TestProtos.MoreBytes.Parser, new[]{ "Data" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.Int32Message), global::Google.Protobuf.TestProtos.Int32Message.Parser, new[]{ "Data" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.Uint32Message), global::Google.Protobuf.TestProtos.Uint32Message.Parser, new[]{ "Data" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.Int64Message), global::Google.Protobuf.TestProtos.Int64Message.Parser, new[]{ "Data" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.Uint64Message), global::Google.Protobuf.TestProtos.Uint64Message.Parser, new[]{ "Data" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.BoolMessage), global::Google.Protobuf.TestProtos.BoolMessage.Parser, new[]{ "Data" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestOneof), global::Google.Protobuf.TestProtos.TestOneof.Parser, new[]{ "FooInt", "FooString", "FooMessage" }, new[]{ "Foo" }, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestPackedTypes), global::Google.Protobuf.TestProtos.TestPackedTypes.Parser, new[]{ "PackedInt32", "PackedInt64", "PackedUint32", "PackedUint64", "PackedSint32", "PackedSint64", "PackedFixed32", "PackedFixed64", "PackedSfixed32", "PackedSfixed64", "PackedFloat", "PackedDouble", "PackedBool", "PackedEnum" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestUnpackedTypes), global::Google.Protobuf.TestProtos.TestUnpackedTypes.Parser, new[]{ "UnpackedInt32", "UnpackedInt64", "UnpackedUint32", "UnpackedUint64", "UnpackedSint32", "UnpackedSint64", "UnpackedFixed32", "UnpackedFixed64", "UnpackedSfixed32", "UnpackedSfixed64", "UnpackedFloat", "UnpackedDouble", "UnpackedBool", "UnpackedEnum" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestRepeatedScalarDifferentTagSizes), global::Google.Protobuf.TestProtos.TestRepeatedScalarDifferentTagSizes.Parser, new[]{ "RepeatedFixed32", "RepeatedInt32", "RepeatedFixed64", "RepeatedInt64", "RepeatedFloat", "RepeatedUint64" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestCommentInjectionMessage), global::Google.Protobuf.TestProtos.TestCommentInjectionMessage.Parser, new[]{ "A" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.FooRequest), global::Google.Protobuf.TestProtos.FooRequest.Parser, null, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.FooResponse), global::Google.Protobuf.TestProtos.FooResponse.Parser, null, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.FooClientMessage), global::Google.Protobuf.TestProtos.FooClientMessage.Parser, null, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.FooServerMessage), global::Google.Protobuf.TestProtos.FooServerMessage.Parser, null, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.BarRequest), global::Google.Protobuf.TestProtos.BarRequest.Parser, null, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.BarResponse), global::Google.Protobuf.TestProtos.BarResponse.Parser, null, null, null, null)
}));
}
#endregion
@@ -193,39 +192,39 @@ namespace Google.Protobuf.TestProtos {
}
#region Enums
public enum ForeignEnum {
- FOREIGN_UNSPECIFIED = 0,
- FOREIGN_FOO = 4,
- FOREIGN_BAR = 5,
- FOREIGN_BAZ = 6,
+ [pbr::OriginalName("FOREIGN_UNSPECIFIED")] ForeignUnspecified = 0,
+ [pbr::OriginalName("FOREIGN_FOO")] ForeignFoo = 4,
+ [pbr::OriginalName("FOREIGN_BAR")] ForeignBar = 5,
+ [pbr::OriginalName("FOREIGN_BAZ")] ForeignBaz = 6,
}
/// <summary>
/// Test an enum that has multiple values with the same number.
/// </summary>
public enum TestEnumWithDupValue {
- TEST_ENUM_WITH_DUP_VALUE_UNSPECIFIED = 0,
- FOO1 = 1,
- BAR1 = 2,
- BAZ = 3,
- FOO2 = 1,
- BAR2 = 2,
+ [pbr::OriginalName("TEST_ENUM_WITH_DUP_VALUE_UNSPECIFIED")] Unspecified = 0,
+ [pbr::OriginalName("FOO1")] Foo1 = 1,
+ [pbr::OriginalName("BAR1")] Bar1 = 2,
+ [pbr::OriginalName("BAZ")] Baz = 3,
+ [pbr::OriginalName("FOO2")] Foo2 = 1,
+ [pbr::OriginalName("BAR2")] Bar2 = 2,
}
/// <summary>
/// Test an enum with large, unordered values.
/// </summary>
public enum TestSparseEnum {
- TEST_SPARSE_ENUM_UNSPECIFIED = 0,
- SPARSE_A = 123,
- SPARSE_B = 62374,
- SPARSE_C = 12589234,
- SPARSE_D = -15,
- SPARSE_E = -53452,
+ [pbr::OriginalName("TEST_SPARSE_ENUM_UNSPECIFIED")] Unspecified = 0,
+ [pbr::OriginalName("SPARSE_A")] SparseA = 123,
+ [pbr::OriginalName("SPARSE_B")] SparseB = 62374,
+ [pbr::OriginalName("SPARSE_C")] SparseC = 12589234,
+ [pbr::OriginalName("SPARSE_D")] SparseD = -15,
+ [pbr::OriginalName("SPARSE_E")] SparseE = -53452,
/// <summary>
/// In proto3, value 0 must be the first one specified
/// SPARSE_F = 0;
/// </summary>
- SPARSE_G = 2,
+ [pbr::OriginalName("SPARSE_G")] SparseG = 2,
}
#endregion
@@ -235,25 +234,29 @@ namespace Google.Protobuf.TestProtos {
/// This proto includes every type of field in both singular and repeated
/// forms.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class TestAllTypes : pb::IMessage<TestAllTypes> {
private static readonly pb::MessageParser<TestAllTypes> _parser = new pb::MessageParser<TestAllTypes>(() => new TestAllTypes());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<TestAllTypes> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[0]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestAllTypes() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestAllTypes(TestAllTypes other) : this() {
singleInt32_ = other.singleInt32_;
singleInt64_ = other.singleInt64_;
@@ -316,6 +319,7 @@ namespace Google.Protobuf.TestProtos {
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestAllTypes Clone() {
return new TestAllTypes(this);
}
@@ -326,6 +330,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>
/// Singular
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int SingleInt32 {
get { return singleInt32_; }
set {
@@ -336,6 +341,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "single_int64" field.</summary>
public const int SingleInt64FieldNumber = 2;
private long singleInt64_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public long SingleInt64 {
get { return singleInt64_; }
set {
@@ -346,6 +352,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "single_uint32" field.</summary>
public const int SingleUint32FieldNumber = 3;
private uint singleUint32_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public uint SingleUint32 {
get { return singleUint32_; }
set {
@@ -356,6 +363,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "single_uint64" field.</summary>
public const int SingleUint64FieldNumber = 4;
private ulong singleUint64_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ulong SingleUint64 {
get { return singleUint64_; }
set {
@@ -366,6 +374,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "single_sint32" field.</summary>
public const int SingleSint32FieldNumber = 5;
private int singleSint32_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int SingleSint32 {
get { return singleSint32_; }
set {
@@ -376,6 +385,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "single_sint64" field.</summary>
public const int SingleSint64FieldNumber = 6;
private long singleSint64_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public long SingleSint64 {
get { return singleSint64_; }
set {
@@ -386,6 +396,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "single_fixed32" field.</summary>
public const int SingleFixed32FieldNumber = 7;
private uint singleFixed32_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public uint SingleFixed32 {
get { return singleFixed32_; }
set {
@@ -396,6 +407,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "single_fixed64" field.</summary>
public const int SingleFixed64FieldNumber = 8;
private ulong singleFixed64_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ulong SingleFixed64 {
get { return singleFixed64_; }
set {
@@ -406,6 +418,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "single_sfixed32" field.</summary>
public const int SingleSfixed32FieldNumber = 9;
private int singleSfixed32_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int SingleSfixed32 {
get { return singleSfixed32_; }
set {
@@ -416,6 +429,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "single_sfixed64" field.</summary>
public const int SingleSfixed64FieldNumber = 10;
private long singleSfixed64_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public long SingleSfixed64 {
get { return singleSfixed64_; }
set {
@@ -426,6 +440,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "single_float" field.</summary>
public const int SingleFloatFieldNumber = 11;
private float singleFloat_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public float SingleFloat {
get { return singleFloat_; }
set {
@@ -436,6 +451,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "single_double" field.</summary>
public const int SingleDoubleFieldNumber = 12;
private double singleDouble_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public double SingleDouble {
get { return singleDouble_; }
set {
@@ -446,6 +462,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "single_bool" field.</summary>
public const int SingleBoolFieldNumber = 13;
private bool singleBool_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool SingleBool {
get { return singleBool_; }
set {
@@ -456,26 +473,29 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "single_string" field.</summary>
public const int SingleStringFieldNumber = 14;
private string singleString_ = "";
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string SingleString {
get { return singleString_; }
set {
- singleString_ = pb::Preconditions.CheckNotNull(value, "value");
+ singleString_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
/// <summary>Field number for the "single_bytes" field.</summary>
public const int SingleBytesFieldNumber = 15;
private pb::ByteString singleBytes_ = pb::ByteString.Empty;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pb::ByteString SingleBytes {
get { return singleBytes_; }
set {
- singleBytes_ = pb::Preconditions.CheckNotNull(value, "value");
+ singleBytes_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
/// <summary>Field number for the "single_nested_message" field.</summary>
public const int SingleNestedMessageFieldNumber = 18;
private global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage singleNestedMessage_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage SingleNestedMessage {
get { return singleNestedMessage_; }
set {
@@ -486,6 +506,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "single_foreign_message" field.</summary>
public const int SingleForeignMessageFieldNumber = 19;
private global::Google.Protobuf.TestProtos.ForeignMessage singleForeignMessage_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.TestProtos.ForeignMessage SingleForeignMessage {
get { return singleForeignMessage_; }
set {
@@ -496,6 +517,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "single_import_message" field.</summary>
public const int SingleImportMessageFieldNumber = 20;
private global::Google.Protobuf.TestProtos.ImportMessage singleImportMessage_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.TestProtos.ImportMessage SingleImportMessage {
get { return singleImportMessage_; }
set {
@@ -505,7 +527,8 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "single_nested_enum" field.</summary>
public const int SingleNestedEnumFieldNumber = 21;
- private global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum singleNestedEnum_ = global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum.NESTED_ENUM_UNSPECIFIED;
+ private global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum singleNestedEnum_ = 0;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum SingleNestedEnum {
get { return singleNestedEnum_; }
set {
@@ -515,7 +538,8 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "single_foreign_enum" field.</summary>
public const int SingleForeignEnumFieldNumber = 22;
- private global::Google.Protobuf.TestProtos.ForeignEnum singleForeignEnum_ = global::Google.Protobuf.TestProtos.ForeignEnum.FOREIGN_UNSPECIFIED;
+ private global::Google.Protobuf.TestProtos.ForeignEnum singleForeignEnum_ = 0;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.TestProtos.ForeignEnum SingleForeignEnum {
get { return singleForeignEnum_; }
set {
@@ -525,7 +549,8 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "single_import_enum" field.</summary>
public const int SingleImportEnumFieldNumber = 23;
- private global::Google.Protobuf.TestProtos.ImportEnum singleImportEnum_ = global::Google.Protobuf.TestProtos.ImportEnum.IMPORT_ENUM_UNSPECIFIED;
+ private global::Google.Protobuf.TestProtos.ImportEnum singleImportEnum_ = 0;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.TestProtos.ImportEnum SingleImportEnum {
get { return singleImportEnum_; }
set {
@@ -539,6 +564,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>
/// Defined in unittest_import_public.proto
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.TestProtos.PublicImportMessage SinglePublicImportMessage {
get { return singlePublicImportMessage_; }
set {
@@ -554,6 +580,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>
/// Repeated
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<int> RepeatedInt32 {
get { return repeatedInt32_; }
}
@@ -563,6 +590,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<long> _repeated_repeatedInt64_codec
= pb::FieldCodec.ForInt64(258);
private readonly pbc::RepeatedField<long> repeatedInt64_ = new pbc::RepeatedField<long>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<long> RepeatedInt64 {
get { return repeatedInt64_; }
}
@@ -572,6 +600,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<uint> _repeated_repeatedUint32_codec
= pb::FieldCodec.ForUInt32(266);
private readonly pbc::RepeatedField<uint> repeatedUint32_ = new pbc::RepeatedField<uint>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<uint> RepeatedUint32 {
get { return repeatedUint32_; }
}
@@ -581,6 +610,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<ulong> _repeated_repeatedUint64_codec
= pb::FieldCodec.ForUInt64(274);
private readonly pbc::RepeatedField<ulong> repeatedUint64_ = new pbc::RepeatedField<ulong>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<ulong> RepeatedUint64 {
get { return repeatedUint64_; }
}
@@ -590,6 +620,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<int> _repeated_repeatedSint32_codec
= pb::FieldCodec.ForSInt32(282);
private readonly pbc::RepeatedField<int> repeatedSint32_ = new pbc::RepeatedField<int>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<int> RepeatedSint32 {
get { return repeatedSint32_; }
}
@@ -599,6 +630,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<long> _repeated_repeatedSint64_codec
= pb::FieldCodec.ForSInt64(290);
private readonly pbc::RepeatedField<long> repeatedSint64_ = new pbc::RepeatedField<long>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<long> RepeatedSint64 {
get { return repeatedSint64_; }
}
@@ -608,6 +640,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<uint> _repeated_repeatedFixed32_codec
= pb::FieldCodec.ForFixed32(298);
private readonly pbc::RepeatedField<uint> repeatedFixed32_ = new pbc::RepeatedField<uint>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<uint> RepeatedFixed32 {
get { return repeatedFixed32_; }
}
@@ -617,6 +650,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<ulong> _repeated_repeatedFixed64_codec
= pb::FieldCodec.ForFixed64(306);
private readonly pbc::RepeatedField<ulong> repeatedFixed64_ = new pbc::RepeatedField<ulong>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<ulong> RepeatedFixed64 {
get { return repeatedFixed64_; }
}
@@ -626,6 +660,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<int> _repeated_repeatedSfixed32_codec
= pb::FieldCodec.ForSFixed32(314);
private readonly pbc::RepeatedField<int> repeatedSfixed32_ = new pbc::RepeatedField<int>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<int> RepeatedSfixed32 {
get { return repeatedSfixed32_; }
}
@@ -635,6 +670,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<long> _repeated_repeatedSfixed64_codec
= pb::FieldCodec.ForSFixed64(322);
private readonly pbc::RepeatedField<long> repeatedSfixed64_ = new pbc::RepeatedField<long>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<long> RepeatedSfixed64 {
get { return repeatedSfixed64_; }
}
@@ -644,6 +680,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<float> _repeated_repeatedFloat_codec
= pb::FieldCodec.ForFloat(330);
private readonly pbc::RepeatedField<float> repeatedFloat_ = new pbc::RepeatedField<float>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<float> RepeatedFloat {
get { return repeatedFloat_; }
}
@@ -653,6 +690,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<double> _repeated_repeatedDouble_codec
= pb::FieldCodec.ForDouble(338);
private readonly pbc::RepeatedField<double> repeatedDouble_ = new pbc::RepeatedField<double>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<double> RepeatedDouble {
get { return repeatedDouble_; }
}
@@ -662,6 +700,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<bool> _repeated_repeatedBool_codec
= pb::FieldCodec.ForBool(346);
private readonly pbc::RepeatedField<bool> repeatedBool_ = new pbc::RepeatedField<bool>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<bool> RepeatedBool {
get { return repeatedBool_; }
}
@@ -671,6 +710,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<string> _repeated_repeatedString_codec
= pb::FieldCodec.ForString(354);
private readonly pbc::RepeatedField<string> repeatedString_ = new pbc::RepeatedField<string>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<string> RepeatedString {
get { return repeatedString_; }
}
@@ -680,6 +720,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<pb::ByteString> _repeated_repeatedBytes_codec
= pb::FieldCodec.ForBytes(362);
private readonly pbc::RepeatedField<pb::ByteString> repeatedBytes_ = new pbc::RepeatedField<pb::ByteString>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<pb::ByteString> RepeatedBytes {
get { return repeatedBytes_; }
}
@@ -689,6 +730,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage> _repeated_repeatedNestedMessage_codec
= pb::FieldCodec.ForMessage(386, global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage.Parser);
private readonly pbc::RepeatedField<global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage> repeatedNestedMessage_ = new pbc::RepeatedField<global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage> RepeatedNestedMessage {
get { return repeatedNestedMessage_; }
}
@@ -698,6 +740,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<global::Google.Protobuf.TestProtos.ForeignMessage> _repeated_repeatedForeignMessage_codec
= pb::FieldCodec.ForMessage(394, global::Google.Protobuf.TestProtos.ForeignMessage.Parser);
private readonly pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignMessage> repeatedForeignMessage_ = new pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignMessage>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignMessage> RepeatedForeignMessage {
get { return repeatedForeignMessage_; }
}
@@ -707,6 +750,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<global::Google.Protobuf.TestProtos.ImportMessage> _repeated_repeatedImportMessage_codec
= pb::FieldCodec.ForMessage(402, global::Google.Protobuf.TestProtos.ImportMessage.Parser);
private readonly pbc::RepeatedField<global::Google.Protobuf.TestProtos.ImportMessage> repeatedImportMessage_ = new pbc::RepeatedField<global::Google.Protobuf.TestProtos.ImportMessage>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.TestProtos.ImportMessage> RepeatedImportMessage {
get { return repeatedImportMessage_; }
}
@@ -716,6 +760,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum> _repeated_repeatedNestedEnum_codec
= pb::FieldCodec.ForEnum(410, x => (int) x, x => (global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum) x);
private readonly pbc::RepeatedField<global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum> repeatedNestedEnum_ = new pbc::RepeatedField<global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum> RepeatedNestedEnum {
get { return repeatedNestedEnum_; }
}
@@ -725,6 +770,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<global::Google.Protobuf.TestProtos.ForeignEnum> _repeated_repeatedForeignEnum_codec
= pb::FieldCodec.ForEnum(418, x => (int) x, x => (global::Google.Protobuf.TestProtos.ForeignEnum) x);
private readonly pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignEnum> repeatedForeignEnum_ = new pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignEnum>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignEnum> RepeatedForeignEnum {
get { return repeatedForeignEnum_; }
}
@@ -734,6 +780,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<global::Google.Protobuf.TestProtos.ImportEnum> _repeated_repeatedImportEnum_codec
= pb::FieldCodec.ForEnum(426, x => (int) x, x => (global::Google.Protobuf.TestProtos.ImportEnum) x);
private readonly pbc::RepeatedField<global::Google.Protobuf.TestProtos.ImportEnum> repeatedImportEnum_ = new pbc::RepeatedField<global::Google.Protobuf.TestProtos.ImportEnum>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.TestProtos.ImportEnum> RepeatedImportEnum {
get { return repeatedImportEnum_; }
}
@@ -746,12 +793,14 @@ namespace Google.Protobuf.TestProtos {
/// <summary>
/// Defined in unittest_import_public.proto
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.TestProtos.PublicImportMessage> RepeatedPublicImportMessage {
get { return repeatedPublicImportMessage_; }
}
/// <summary>Field number for the "oneof_uint32" field.</summary>
public const int OneofUint32FieldNumber = 111;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public uint OneofUint32 {
get { return oneofFieldCase_ == OneofFieldOneofCase.OneofUint32 ? (uint) oneofField_ : 0; }
set {
@@ -762,6 +811,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "oneof_nested_message" field.</summary>
public const int OneofNestedMessageFieldNumber = 112;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage OneofNestedMessage {
get { return oneofFieldCase_ == OneofFieldOneofCase.OneofNestedMessage ? (global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage) oneofField_ : null; }
set {
@@ -772,20 +822,22 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "oneof_string" field.</summary>
public const int OneofStringFieldNumber = 113;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string OneofString {
get { return oneofFieldCase_ == OneofFieldOneofCase.OneofString ? (string) oneofField_ : ""; }
set {
- oneofField_ = pb::Preconditions.CheckNotNull(value, "value");
+ oneofField_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
oneofFieldCase_ = OneofFieldOneofCase.OneofString;
}
}
/// <summary>Field number for the "oneof_bytes" field.</summary>
public const int OneofBytesFieldNumber = 114;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pb::ByteString OneofBytes {
get { return oneofFieldCase_ == OneofFieldOneofCase.OneofBytes ? (pb::ByteString) oneofField_ : pb::ByteString.Empty; }
set {
- oneofField_ = pb::Preconditions.CheckNotNull(value, "value");
+ oneofField_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
oneofFieldCase_ = OneofFieldOneofCase.OneofBytes;
}
}
@@ -800,19 +852,23 @@ namespace Google.Protobuf.TestProtos {
OneofBytes = 114,
}
private OneofFieldOneofCase oneofFieldCase_ = OneofFieldOneofCase.None;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public OneofFieldOneofCase OneofFieldCase {
get { return oneofFieldCase_; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void ClearOneofField() {
oneofFieldCase_ = OneofFieldOneofCase.None;
oneofField_ = null;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as TestAllTypes);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(TestAllTypes other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -872,6 +928,7 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (SingleInt32 != 0) hash ^= SingleInt32.GetHashCode();
@@ -892,9 +949,9 @@ namespace Google.Protobuf.TestProtos {
if (singleNestedMessage_ != null) hash ^= SingleNestedMessage.GetHashCode();
if (singleForeignMessage_ != null) hash ^= SingleForeignMessage.GetHashCode();
if (singleImportMessage_ != null) hash ^= SingleImportMessage.GetHashCode();
- if (SingleNestedEnum != global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum.NESTED_ENUM_UNSPECIFIED) hash ^= SingleNestedEnum.GetHashCode();
- if (SingleForeignEnum != global::Google.Protobuf.TestProtos.ForeignEnum.FOREIGN_UNSPECIFIED) hash ^= SingleForeignEnum.GetHashCode();
- if (SingleImportEnum != global::Google.Protobuf.TestProtos.ImportEnum.IMPORT_ENUM_UNSPECIFIED) hash ^= SingleImportEnum.GetHashCode();
+ if (SingleNestedEnum != 0) hash ^= SingleNestedEnum.GetHashCode();
+ if (SingleForeignEnum != 0) hash ^= SingleForeignEnum.GetHashCode();
+ if (SingleImportEnum != 0) hash ^= SingleImportEnum.GetHashCode();
if (singlePublicImportMessage_ != null) hash ^= SinglePublicImportMessage.GetHashCode();
hash ^= repeatedInt32_.GetHashCode();
hash ^= repeatedInt64_.GetHashCode();
@@ -926,10 +983,12 @@ namespace Google.Protobuf.TestProtos {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (SingleInt32 != 0) {
output.WriteRawTag(8);
@@ -1003,15 +1062,15 @@ namespace Google.Protobuf.TestProtos {
output.WriteRawTag(162, 1);
output.WriteMessage(SingleImportMessage);
}
- if (SingleNestedEnum != global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum.NESTED_ENUM_UNSPECIFIED) {
+ if (SingleNestedEnum != 0) {
output.WriteRawTag(168, 1);
output.WriteEnum((int) SingleNestedEnum);
}
- if (SingleForeignEnum != global::Google.Protobuf.TestProtos.ForeignEnum.FOREIGN_UNSPECIFIED) {
+ if (SingleForeignEnum != 0) {
output.WriteRawTag(176, 1);
output.WriteEnum((int) SingleForeignEnum);
}
- if (SingleImportEnum != global::Google.Protobuf.TestProtos.ImportEnum.IMPORT_ENUM_UNSPECIFIED) {
+ if (SingleImportEnum != 0) {
output.WriteRawTag(184, 1);
output.WriteEnum((int) SingleImportEnum);
}
@@ -1059,6 +1118,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (SingleInt32 != 0) {
@@ -1115,13 +1175,13 @@ namespace Google.Protobuf.TestProtos {
if (singleImportMessage_ != null) {
size += 2 + pb::CodedOutputStream.ComputeMessageSize(SingleImportMessage);
}
- if (SingleNestedEnum != global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum.NESTED_ENUM_UNSPECIFIED) {
+ if (SingleNestedEnum != 0) {
size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) SingleNestedEnum);
}
- if (SingleForeignEnum != global::Google.Protobuf.TestProtos.ForeignEnum.FOREIGN_UNSPECIFIED) {
+ if (SingleForeignEnum != 0) {
size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) SingleForeignEnum);
}
- if (SingleImportEnum != global::Google.Protobuf.TestProtos.ImportEnum.IMPORT_ENUM_UNSPECIFIED) {
+ if (SingleImportEnum != 0) {
size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) SingleImportEnum);
}
if (singlePublicImportMessage_ != null) {
@@ -1164,6 +1224,7 @@ namespace Google.Protobuf.TestProtos {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(TestAllTypes other) {
if (other == null) {
return;
@@ -1231,13 +1292,13 @@ namespace Google.Protobuf.TestProtos {
}
SingleImportMessage.MergeFrom(other.SingleImportMessage);
}
- if (other.SingleNestedEnum != global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum.NESTED_ENUM_UNSPECIFIED) {
+ if (other.SingleNestedEnum != 0) {
SingleNestedEnum = other.SingleNestedEnum;
}
- if (other.SingleForeignEnum != global::Google.Protobuf.TestProtos.ForeignEnum.FOREIGN_UNSPECIFIED) {
+ if (other.SingleForeignEnum != 0) {
SingleForeignEnum = other.SingleForeignEnum;
}
- if (other.SingleImportEnum != global::Google.Protobuf.TestProtos.ImportEnum.IMPORT_ENUM_UNSPECIFIED) {
+ if (other.SingleImportEnum != 0) {
SingleImportEnum = other.SingleImportEnum;
}
if (other.singlePublicImportMessage_ != null) {
@@ -1285,6 +1346,7 @@ namespace Google.Protobuf.TestProtos {
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -1523,42 +1585,47 @@ namespace Google.Protobuf.TestProtos {
#region Nested types
/// <summary>Container for nested types declared in the TestAllTypes message type.</summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static partial class Types {
public enum NestedEnum {
- NESTED_ENUM_UNSPECIFIED = 0,
- FOO = 1,
- BAR = 2,
- BAZ = 3,
+ [pbr::OriginalName("NESTED_ENUM_UNSPECIFIED")] Unspecified = 0,
+ [pbr::OriginalName("FOO")] Foo = 1,
+ [pbr::OriginalName("BAR")] Bar = 2,
+ [pbr::OriginalName("BAZ")] Baz = 3,
/// <summary>
/// Intentionally negative.
/// </summary>
- NEG = -1,
+ [pbr::OriginalName("NEG")] Neg = -1,
}
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class NestedMessage : pb::IMessage<NestedMessage> {
private static readonly pb::MessageParser<NestedMessage> _parser = new pb::MessageParser<NestedMessage>(() => new NestedMessage());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<NestedMessage> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.TestAllTypes.Descriptor.NestedTypes[0]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public NestedMessage() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public NestedMessage(NestedMessage other) : this() {
bb_ = other.bb_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public NestedMessage Clone() {
return new NestedMessage(this);
}
@@ -1571,6 +1638,7 @@ namespace Google.Protobuf.TestProtos {
/// a local variable named "b" in one of the generated methods. Doh.
/// This file needs to compile in proto1 to test backwards-compatibility.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int Bb {
get { return bb_; }
set {
@@ -1578,10 +1646,12 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as NestedMessage);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(NestedMessage other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -1593,16 +1663,19 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Bb != 0) hash ^= Bb.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Bb != 0) {
output.WriteRawTag(8);
@@ -1610,6 +1683,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Bb != 0) {
@@ -1618,6 +1692,7 @@ namespace Google.Protobuf.TestProtos {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(NestedMessage other) {
if (other == null) {
return;
@@ -1627,6 +1702,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -1652,31 +1728,36 @@ namespace Google.Protobuf.TestProtos {
/// <summary>
/// This proto includes a recusively nested message.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class NestedTestAllTypes : pb::IMessage<NestedTestAllTypes> {
private static readonly pb::MessageParser<NestedTestAllTypes> _parser = new pb::MessageParser<NestedTestAllTypes>(() => new NestedTestAllTypes());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<NestedTestAllTypes> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[1]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public NestedTestAllTypes() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public NestedTestAllTypes(NestedTestAllTypes other) : this() {
Child = other.child_ != null ? other.Child.Clone() : null;
Payload = other.payload_ != null ? other.Payload.Clone() : null;
repeatedChild_ = other.repeatedChild_.Clone();
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public NestedTestAllTypes Clone() {
return new NestedTestAllTypes(this);
}
@@ -1684,6 +1765,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "child" field.</summary>
public const int ChildFieldNumber = 1;
private global::Google.Protobuf.TestProtos.NestedTestAllTypes child_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.TestProtos.NestedTestAllTypes Child {
get { return child_; }
set {
@@ -1694,6 +1776,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "payload" field.</summary>
public const int PayloadFieldNumber = 2;
private global::Google.Protobuf.TestProtos.TestAllTypes payload_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.TestProtos.TestAllTypes Payload {
get { return payload_; }
set {
@@ -1706,14 +1789,17 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<global::Google.Protobuf.TestProtos.NestedTestAllTypes> _repeated_repeatedChild_codec
= pb::FieldCodec.ForMessage(26, global::Google.Protobuf.TestProtos.NestedTestAllTypes.Parser);
private readonly pbc::RepeatedField<global::Google.Protobuf.TestProtos.NestedTestAllTypes> repeatedChild_ = new pbc::RepeatedField<global::Google.Protobuf.TestProtos.NestedTestAllTypes>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.TestProtos.NestedTestAllTypes> RepeatedChild {
get { return repeatedChild_; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as NestedTestAllTypes);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(NestedTestAllTypes other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -1727,6 +1813,7 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (child_ != null) hash ^= Child.GetHashCode();
@@ -1735,10 +1822,12 @@ namespace Google.Protobuf.TestProtos {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (child_ != null) {
output.WriteRawTag(10);
@@ -1751,6 +1840,7 @@ namespace Google.Protobuf.TestProtos {
repeatedChild_.WriteTo(output, _repeated_repeatedChild_codec);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (child_ != null) {
@@ -1763,6 +1853,7 @@ namespace Google.Protobuf.TestProtos {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(NestedTestAllTypes other) {
if (other == null) {
return;
@@ -1782,6 +1873,7 @@ namespace Google.Protobuf.TestProtos {
repeatedChild_.Add(other.repeatedChild_);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -1813,29 +1905,34 @@ namespace Google.Protobuf.TestProtos {
}
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class TestDeprecatedFields : pb::IMessage<TestDeprecatedFields> {
private static readonly pb::MessageParser<TestDeprecatedFields> _parser = new pb::MessageParser<TestDeprecatedFields>(() => new TestDeprecatedFields());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<TestDeprecatedFields> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[2]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestDeprecatedFields() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestDeprecatedFields(TestDeprecatedFields other) : this() {
deprecatedInt32_ = other.deprecatedInt32_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestDeprecatedFields Clone() {
return new TestDeprecatedFields(this);
}
@@ -1843,7 +1940,8 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "deprecated_int32" field.</summary>
public const int DeprecatedInt32FieldNumber = 1;
private int deprecatedInt32_;
- [global::System.ObsoleteAttribute()]
+ [global::System.ObsoleteAttribute]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int DeprecatedInt32 {
get { return deprecatedInt32_; }
set {
@@ -1851,10 +1949,12 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as TestDeprecatedFields);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(TestDeprecatedFields other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -1866,16 +1966,19 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (DeprecatedInt32 != 0) hash ^= DeprecatedInt32.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (DeprecatedInt32 != 0) {
output.WriteRawTag(8);
@@ -1883,6 +1986,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (DeprecatedInt32 != 0) {
@@ -1891,6 +1995,7 @@ namespace Google.Protobuf.TestProtos {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(TestDeprecatedFields other) {
if (other == null) {
return;
@@ -1900,6 +2005,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -1921,29 +2027,34 @@ namespace Google.Protobuf.TestProtos {
/// Define these after TestAllTypes to make sure the compiler can handle
/// that.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class ForeignMessage : pb::IMessage<ForeignMessage> {
private static readonly pb::MessageParser<ForeignMessage> _parser = new pb::MessageParser<ForeignMessage>(() => new ForeignMessage());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<ForeignMessage> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[3]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ForeignMessage() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ForeignMessage(ForeignMessage other) : this() {
c_ = other.c_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ForeignMessage Clone() {
return new ForeignMessage(this);
}
@@ -1951,6 +2062,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "c" field.</summary>
public const int CFieldNumber = 1;
private int c_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int C {
get { return c_; }
set {
@@ -1958,10 +2070,12 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as ForeignMessage);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(ForeignMessage other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -1973,16 +2087,19 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (C != 0) hash ^= C.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (C != 0) {
output.WriteRawTag(8);
@@ -1990,6 +2107,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (C != 0) {
@@ -1998,6 +2116,7 @@ namespace Google.Protobuf.TestProtos {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(ForeignMessage other) {
if (other == null) {
return;
@@ -2007,6 +2126,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -2024,36 +2144,43 @@ namespace Google.Protobuf.TestProtos {
}
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class TestReservedFields : pb::IMessage<TestReservedFields> {
private static readonly pb::MessageParser<TestReservedFields> _parser = new pb::MessageParser<TestReservedFields>(() => new TestReservedFields());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<TestReservedFields> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[4]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestReservedFields() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestReservedFields(TestReservedFields other) : this() {
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestReservedFields Clone() {
return new TestReservedFields(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as TestReservedFields);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(TestReservedFields other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -2064,29 +2191,35 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(TestReservedFields other) {
if (other == null) {
return;
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -2103,29 +2236,34 @@ namespace Google.Protobuf.TestProtos {
/// <summary>
/// Test that we can use NestedMessage from outside TestAllTypes.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class TestForeignNested : pb::IMessage<TestForeignNested> {
private static readonly pb::MessageParser<TestForeignNested> _parser = new pb::MessageParser<TestForeignNested>(() => new TestForeignNested());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<TestForeignNested> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[5]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestForeignNested() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestForeignNested(TestForeignNested other) : this() {
ForeignNested = other.foreignNested_ != null ? other.ForeignNested.Clone() : null;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestForeignNested Clone() {
return new TestForeignNested(this);
}
@@ -2133,6 +2271,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "foreign_nested" field.</summary>
public const int ForeignNestedFieldNumber = 1;
private global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage foreignNested_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage ForeignNested {
get { return foreignNested_; }
set {
@@ -2140,10 +2279,12 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as TestForeignNested);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(TestForeignNested other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -2155,16 +2296,19 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (foreignNested_ != null) hash ^= ForeignNested.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (foreignNested_ != null) {
output.WriteRawTag(10);
@@ -2172,6 +2316,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (foreignNested_ != null) {
@@ -2180,6 +2325,7 @@ namespace Google.Protobuf.TestProtos {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(TestForeignNested other) {
if (other == null) {
return;
@@ -2192,6 +2338,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -2215,30 +2362,35 @@ namespace Google.Protobuf.TestProtos {
/// <summary>
/// Test that really large tag numbers don't break anything.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class TestReallyLargeTagNumber : pb::IMessage<TestReallyLargeTagNumber> {
private static readonly pb::MessageParser<TestReallyLargeTagNumber> _parser = new pb::MessageParser<TestReallyLargeTagNumber>(() => new TestReallyLargeTagNumber());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<TestReallyLargeTagNumber> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[6]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestReallyLargeTagNumber() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestReallyLargeTagNumber(TestReallyLargeTagNumber other) : this() {
a_ = other.a_;
bb_ = other.bb_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestReallyLargeTagNumber Clone() {
return new TestReallyLargeTagNumber(this);
}
@@ -2250,6 +2402,7 @@ namespace Google.Protobuf.TestProtos {
/// The largest possible tag number is 2^28 - 1, since the wire format uses
/// three bits to communicate wire type.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int A {
get { return a_; }
set {
@@ -2260,6 +2413,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "bb" field.</summary>
public const int BbFieldNumber = 268435455;
private int bb_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int Bb {
get { return bb_; }
set {
@@ -2267,10 +2421,12 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as TestReallyLargeTagNumber);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(TestReallyLargeTagNumber other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -2283,6 +2439,7 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (A != 0) hash ^= A.GetHashCode();
@@ -2290,10 +2447,12 @@ namespace Google.Protobuf.TestProtos {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (A != 0) {
output.WriteRawTag(8);
@@ -2305,6 +2464,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (A != 0) {
@@ -2316,6 +2476,7 @@ namespace Google.Protobuf.TestProtos {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(TestReallyLargeTagNumber other) {
if (other == null) {
return;
@@ -2328,6 +2489,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -2349,30 +2511,35 @@ namespace Google.Protobuf.TestProtos {
}
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class TestRecursiveMessage : pb::IMessage<TestRecursiveMessage> {
private static readonly pb::MessageParser<TestRecursiveMessage> _parser = new pb::MessageParser<TestRecursiveMessage>(() => new TestRecursiveMessage());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<TestRecursiveMessage> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[7]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestRecursiveMessage() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestRecursiveMessage(TestRecursiveMessage other) : this() {
A = other.a_ != null ? other.A.Clone() : null;
i_ = other.i_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestRecursiveMessage Clone() {
return new TestRecursiveMessage(this);
}
@@ -2380,6 +2547,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "a" field.</summary>
public const int AFieldNumber = 1;
private global::Google.Protobuf.TestProtos.TestRecursiveMessage a_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.TestProtos.TestRecursiveMessage A {
get { return a_; }
set {
@@ -2390,6 +2558,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "i" field.</summary>
public const int IFieldNumber = 2;
private int i_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int I {
get { return i_; }
set {
@@ -2397,10 +2566,12 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as TestRecursiveMessage);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(TestRecursiveMessage other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -2413,6 +2584,7 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (a_ != null) hash ^= A.GetHashCode();
@@ -2420,10 +2592,12 @@ namespace Google.Protobuf.TestProtos {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (a_ != null) {
output.WriteRawTag(10);
@@ -2435,6 +2609,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (a_ != null) {
@@ -2446,6 +2621,7 @@ namespace Google.Protobuf.TestProtos {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(TestRecursiveMessage other) {
if (other == null) {
return;
@@ -2461,6 +2637,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -2488,29 +2665,34 @@ namespace Google.Protobuf.TestProtos {
/// <summary>
/// Test that mutual recursion works.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class TestMutualRecursionA : pb::IMessage<TestMutualRecursionA> {
private static readonly pb::MessageParser<TestMutualRecursionA> _parser = new pb::MessageParser<TestMutualRecursionA>(() => new TestMutualRecursionA());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<TestMutualRecursionA> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[8]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestMutualRecursionA() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestMutualRecursionA(TestMutualRecursionA other) : this() {
Bb = other.bb_ != null ? other.Bb.Clone() : null;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestMutualRecursionA Clone() {
return new TestMutualRecursionA(this);
}
@@ -2518,6 +2700,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "bb" field.</summary>
public const int BbFieldNumber = 1;
private global::Google.Protobuf.TestProtos.TestMutualRecursionB bb_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.TestProtos.TestMutualRecursionB Bb {
get { return bb_; }
set {
@@ -2525,10 +2708,12 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as TestMutualRecursionA);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(TestMutualRecursionA other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -2540,16 +2725,19 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (bb_ != null) hash ^= Bb.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (bb_ != null) {
output.WriteRawTag(10);
@@ -2557,6 +2745,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (bb_ != null) {
@@ -2565,6 +2754,7 @@ namespace Google.Protobuf.TestProtos {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(TestMutualRecursionA other) {
if (other == null) {
return;
@@ -2577,6 +2767,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -2597,30 +2788,35 @@ namespace Google.Protobuf.TestProtos {
}
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class TestMutualRecursionB : pb::IMessage<TestMutualRecursionB> {
private static readonly pb::MessageParser<TestMutualRecursionB> _parser = new pb::MessageParser<TestMutualRecursionB>(() => new TestMutualRecursionB());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<TestMutualRecursionB> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[9]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestMutualRecursionB() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestMutualRecursionB(TestMutualRecursionB other) : this() {
A = other.a_ != null ? other.A.Clone() : null;
optionalInt32_ = other.optionalInt32_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestMutualRecursionB Clone() {
return new TestMutualRecursionB(this);
}
@@ -2628,6 +2824,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "a" field.</summary>
public const int AFieldNumber = 1;
private global::Google.Protobuf.TestProtos.TestMutualRecursionA a_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.TestProtos.TestMutualRecursionA A {
get { return a_; }
set {
@@ -2638,6 +2835,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "optional_int32" field.</summary>
public const int OptionalInt32FieldNumber = 2;
private int optionalInt32_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int OptionalInt32 {
get { return optionalInt32_; }
set {
@@ -2645,10 +2843,12 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as TestMutualRecursionB);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(TestMutualRecursionB other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -2661,6 +2861,7 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (a_ != null) hash ^= A.GetHashCode();
@@ -2668,10 +2869,12 @@ namespace Google.Protobuf.TestProtos {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (a_ != null) {
output.WriteRawTag(10);
@@ -2683,6 +2886,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (a_ != null) {
@@ -2694,6 +2898,7 @@ namespace Google.Protobuf.TestProtos {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(TestMutualRecursionB other) {
if (other == null) {
return;
@@ -2709,6 +2914,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -2737,25 +2943,29 @@ namespace Google.Protobuf.TestProtos {
/// Test message with CamelCase field names. This violates Protocol Buffer
/// standard style.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class TestCamelCaseFieldNames : pb::IMessage<TestCamelCaseFieldNames> {
private static readonly pb::MessageParser<TestCamelCaseFieldNames> _parser = new pb::MessageParser<TestCamelCaseFieldNames>(() => new TestCamelCaseFieldNames());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<TestCamelCaseFieldNames> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[10]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestCamelCaseFieldNames() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestCamelCaseFieldNames(TestCamelCaseFieldNames other) : this() {
primitiveField_ = other.primitiveField_;
stringField_ = other.stringField_;
@@ -2767,6 +2977,7 @@ namespace Google.Protobuf.TestProtos {
repeatedMessageField_ = other.repeatedMessageField_.Clone();
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestCamelCaseFieldNames Clone() {
return new TestCamelCaseFieldNames(this);
}
@@ -2774,6 +2985,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "PrimitiveField" field.</summary>
public const int PrimitiveFieldFieldNumber = 1;
private int primitiveField_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int PrimitiveField {
get { return primitiveField_; }
set {
@@ -2784,16 +2996,18 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "StringField" field.</summary>
public const int StringFieldFieldNumber = 2;
private string stringField_ = "";
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string StringField {
get { return stringField_; }
set {
- stringField_ = pb::Preconditions.CheckNotNull(value, "value");
+ stringField_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
/// <summary>Field number for the "EnumField" field.</summary>
public const int EnumFieldFieldNumber = 3;
- private global::Google.Protobuf.TestProtos.ForeignEnum enumField_ = global::Google.Protobuf.TestProtos.ForeignEnum.FOREIGN_UNSPECIFIED;
+ private global::Google.Protobuf.TestProtos.ForeignEnum enumField_ = 0;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.TestProtos.ForeignEnum EnumField {
get { return enumField_; }
set {
@@ -2804,6 +3018,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "MessageField" field.</summary>
public const int MessageFieldFieldNumber = 4;
private global::Google.Protobuf.TestProtos.ForeignMessage messageField_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.TestProtos.ForeignMessage MessageField {
get { return messageField_; }
set {
@@ -2816,6 +3031,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<int> _repeated_repeatedPrimitiveField_codec
= pb::FieldCodec.ForInt32(58);
private readonly pbc::RepeatedField<int> repeatedPrimitiveField_ = new pbc::RepeatedField<int>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<int> RepeatedPrimitiveField {
get { return repeatedPrimitiveField_; }
}
@@ -2825,6 +3041,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<string> _repeated_repeatedStringField_codec
= pb::FieldCodec.ForString(66);
private readonly pbc::RepeatedField<string> repeatedStringField_ = new pbc::RepeatedField<string>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<string> RepeatedStringField {
get { return repeatedStringField_; }
}
@@ -2834,6 +3051,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<global::Google.Protobuf.TestProtos.ForeignEnum> _repeated_repeatedEnumField_codec
= pb::FieldCodec.ForEnum(74, x => (int) x, x => (global::Google.Protobuf.TestProtos.ForeignEnum) x);
private readonly pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignEnum> repeatedEnumField_ = new pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignEnum>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignEnum> RepeatedEnumField {
get { return repeatedEnumField_; }
}
@@ -2843,14 +3061,17 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<global::Google.Protobuf.TestProtos.ForeignMessage> _repeated_repeatedMessageField_codec
= pb::FieldCodec.ForMessage(82, global::Google.Protobuf.TestProtos.ForeignMessage.Parser);
private readonly pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignMessage> repeatedMessageField_ = new pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignMessage>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignMessage> RepeatedMessageField {
get { return repeatedMessageField_; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as TestCamelCaseFieldNames);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(TestCamelCaseFieldNames other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -2869,11 +3090,12 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (PrimitiveField != 0) hash ^= PrimitiveField.GetHashCode();
if (StringField.Length != 0) hash ^= StringField.GetHashCode();
- if (EnumField != global::Google.Protobuf.TestProtos.ForeignEnum.FOREIGN_UNSPECIFIED) hash ^= EnumField.GetHashCode();
+ if (EnumField != 0) hash ^= EnumField.GetHashCode();
if (messageField_ != null) hash ^= MessageField.GetHashCode();
hash ^= repeatedPrimitiveField_.GetHashCode();
hash ^= repeatedStringField_.GetHashCode();
@@ -2882,10 +3104,12 @@ namespace Google.Protobuf.TestProtos {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (PrimitiveField != 0) {
output.WriteRawTag(8);
@@ -2895,7 +3119,7 @@ namespace Google.Protobuf.TestProtos {
output.WriteRawTag(18);
output.WriteString(StringField);
}
- if (EnumField != global::Google.Protobuf.TestProtos.ForeignEnum.FOREIGN_UNSPECIFIED) {
+ if (EnumField != 0) {
output.WriteRawTag(24);
output.WriteEnum((int) EnumField);
}
@@ -2909,6 +3133,7 @@ namespace Google.Protobuf.TestProtos {
repeatedMessageField_.WriteTo(output, _repeated_repeatedMessageField_codec);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (PrimitiveField != 0) {
@@ -2917,7 +3142,7 @@ namespace Google.Protobuf.TestProtos {
if (StringField.Length != 0) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(StringField);
}
- if (EnumField != global::Google.Protobuf.TestProtos.ForeignEnum.FOREIGN_UNSPECIFIED) {
+ if (EnumField != 0) {
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) EnumField);
}
if (messageField_ != null) {
@@ -2930,6 +3155,7 @@ namespace Google.Protobuf.TestProtos {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(TestCamelCaseFieldNames other) {
if (other == null) {
return;
@@ -2940,7 +3166,7 @@ namespace Google.Protobuf.TestProtos {
if (other.StringField.Length != 0) {
StringField = other.StringField;
}
- if (other.EnumField != global::Google.Protobuf.TestProtos.ForeignEnum.FOREIGN_UNSPECIFIED) {
+ if (other.EnumField != 0) {
EnumField = other.EnumField;
}
if (other.messageField_ != null) {
@@ -2955,6 +3181,7 @@ namespace Google.Protobuf.TestProtos {
repeatedMessageField_.Add(other.repeatedMessageField_);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -3009,25 +3236,29 @@ namespace Google.Protobuf.TestProtos {
/// We list fields out of order, to ensure that we're using field number and not
/// field index to determine serialization order.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class TestFieldOrderings : pb::IMessage<TestFieldOrderings> {
private static readonly pb::MessageParser<TestFieldOrderings> _parser = new pb::MessageParser<TestFieldOrderings>(() => new TestFieldOrderings());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<TestFieldOrderings> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[11]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestFieldOrderings() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestFieldOrderings(TestFieldOrderings other) : this() {
myString_ = other.myString_;
myInt_ = other.myInt_;
@@ -3035,6 +3266,7 @@ namespace Google.Protobuf.TestProtos {
SingleNestedMessage = other.singleNestedMessage_ != null ? other.SingleNestedMessage.Clone() : null;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestFieldOrderings Clone() {
return new TestFieldOrderings(this);
}
@@ -3042,16 +3274,18 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "my_string" field.</summary>
public const int MyStringFieldNumber = 11;
private string myString_ = "";
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string MyString {
get { return myString_; }
set {
- myString_ = pb::Preconditions.CheckNotNull(value, "value");
+ myString_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
/// <summary>Field number for the "my_int" field.</summary>
public const int MyIntFieldNumber = 1;
private long myInt_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public long MyInt {
get { return myInt_; }
set {
@@ -3062,6 +3296,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "my_float" field.</summary>
public const int MyFloatFieldNumber = 101;
private float myFloat_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public float MyFloat {
get { return myFloat_; }
set {
@@ -3072,6 +3307,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "single_nested_message" field.</summary>
public const int SingleNestedMessageFieldNumber = 200;
private global::Google.Protobuf.TestProtos.TestFieldOrderings.Types.NestedMessage singleNestedMessage_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.TestProtos.TestFieldOrderings.Types.NestedMessage SingleNestedMessage {
get { return singleNestedMessage_; }
set {
@@ -3079,10 +3315,12 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as TestFieldOrderings);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(TestFieldOrderings other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -3097,6 +3335,7 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (MyString.Length != 0) hash ^= MyString.GetHashCode();
@@ -3106,10 +3345,12 @@ namespace Google.Protobuf.TestProtos {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (MyInt != 0L) {
output.WriteRawTag(8);
@@ -3129,6 +3370,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (MyString.Length != 0) {
@@ -3146,6 +3388,7 @@ namespace Google.Protobuf.TestProtos {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(TestFieldOrderings other) {
if (other == null) {
return;
@@ -3167,6 +3410,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -3199,32 +3443,37 @@ namespace Google.Protobuf.TestProtos {
#region Nested types
/// <summary>Container for nested types declared in the TestFieldOrderings message type.</summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static partial class Types {
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class NestedMessage : pb::IMessage<NestedMessage> {
private static readonly pb::MessageParser<NestedMessage> _parser = new pb::MessageParser<NestedMessage>(() => new NestedMessage());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<NestedMessage> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.TestFieldOrderings.Descriptor.NestedTypes[0]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public NestedMessage() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public NestedMessage(NestedMessage other) : this() {
oo_ = other.oo_;
bb_ = other.bb_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public NestedMessage Clone() {
return new NestedMessage(this);
}
@@ -3232,6 +3481,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "oo" field.</summary>
public const int OoFieldNumber = 2;
private long oo_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public long Oo {
get { return oo_; }
set {
@@ -3247,6 +3497,7 @@ namespace Google.Protobuf.TestProtos {
/// a local variable named "b" in one of the generated methods. Doh.
/// This file needs to compile in proto1 to test backwards-compatibility.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int Bb {
get { return bb_; }
set {
@@ -3254,10 +3505,12 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as NestedMessage);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(NestedMessage other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -3270,6 +3523,7 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Oo != 0L) hash ^= Oo.GetHashCode();
@@ -3277,10 +3531,12 @@ namespace Google.Protobuf.TestProtos {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Bb != 0) {
output.WriteRawTag(8);
@@ -3292,6 +3548,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Oo != 0L) {
@@ -3303,6 +3560,7 @@ namespace Google.Protobuf.TestProtos {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(NestedMessage other) {
if (other == null) {
return;
@@ -3315,6 +3573,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -3341,36 +3600,42 @@ namespace Google.Protobuf.TestProtos {
}
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class SparseEnumMessage : pb::IMessage<SparseEnumMessage> {
private static readonly pb::MessageParser<SparseEnumMessage> _parser = new pb::MessageParser<SparseEnumMessage>(() => new SparseEnumMessage());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<SparseEnumMessage> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[12]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public SparseEnumMessage() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public SparseEnumMessage(SparseEnumMessage other) : this() {
sparseEnum_ = other.sparseEnum_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public SparseEnumMessage Clone() {
return new SparseEnumMessage(this);
}
/// <summary>Field number for the "sparse_enum" field.</summary>
public const int SparseEnumFieldNumber = 1;
- private global::Google.Protobuf.TestProtos.TestSparseEnum sparseEnum_ = global::Google.Protobuf.TestProtos.TestSparseEnum.TEST_SPARSE_ENUM_UNSPECIFIED;
+ private global::Google.Protobuf.TestProtos.TestSparseEnum sparseEnum_ = 0;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.TestProtos.TestSparseEnum SparseEnum {
get { return sparseEnum_; }
set {
@@ -3378,10 +3643,12 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as SparseEnumMessage);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(SparseEnumMessage other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -3393,40 +3660,46 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
- if (SparseEnum != global::Google.Protobuf.TestProtos.TestSparseEnum.TEST_SPARSE_ENUM_UNSPECIFIED) hash ^= SparseEnum.GetHashCode();
+ if (SparseEnum != 0) hash ^= SparseEnum.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
- if (SparseEnum != global::Google.Protobuf.TestProtos.TestSparseEnum.TEST_SPARSE_ENUM_UNSPECIFIED) {
+ if (SparseEnum != 0) {
output.WriteRawTag(8);
output.WriteEnum((int) SparseEnum);
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
- if (SparseEnum != global::Google.Protobuf.TestProtos.TestSparseEnum.TEST_SPARSE_ENUM_UNSPECIFIED) {
+ if (SparseEnum != 0) {
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) SparseEnum);
}
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(SparseEnumMessage other) {
if (other == null) {
return;
}
- if (other.SparseEnum != global::Google.Protobuf.TestProtos.TestSparseEnum.TEST_SPARSE_ENUM_UNSPECIFIED) {
+ if (other.SparseEnum != 0) {
SparseEnum = other.SparseEnum;
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -3447,29 +3720,34 @@ namespace Google.Protobuf.TestProtos {
/// <summary>
/// Test String and Bytes: string is for valid UTF-8 strings
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class OneString : pb::IMessage<OneString> {
private static readonly pb::MessageParser<OneString> _parser = new pb::MessageParser<OneString>(() => new OneString());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<OneString> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[13]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public OneString() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public OneString(OneString other) : this() {
data_ = other.data_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public OneString Clone() {
return new OneString(this);
}
@@ -3477,17 +3755,20 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "data" field.</summary>
public const int DataFieldNumber = 1;
private string data_ = "";
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string Data {
get { return data_; }
set {
- data_ = pb::Preconditions.CheckNotNull(value, "value");
+ data_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as OneString);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(OneString other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -3499,16 +3780,19 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Data.Length != 0) hash ^= Data.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Data.Length != 0) {
output.WriteRawTag(10);
@@ -3516,6 +3800,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Data.Length != 0) {
@@ -3524,6 +3809,7 @@ namespace Google.Protobuf.TestProtos {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(OneString other) {
if (other == null) {
return;
@@ -3533,6 +3819,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -3550,29 +3837,34 @@ namespace Google.Protobuf.TestProtos {
}
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class MoreString : pb::IMessage<MoreString> {
private static readonly pb::MessageParser<MoreString> _parser = new pb::MessageParser<MoreString>(() => new MoreString());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<MoreString> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[14]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public MoreString() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public MoreString(MoreString other) : this() {
data_ = other.data_.Clone();
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public MoreString Clone() {
return new MoreString(this);
}
@@ -3582,14 +3874,17 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<string> _repeated_data_codec
= pb::FieldCodec.ForString(10);
private readonly pbc::RepeatedField<string> data_ = new pbc::RepeatedField<string>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<string> Data {
get { return data_; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as MoreString);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(MoreString other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -3601,26 +3896,31 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
hash ^= data_.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
data_.WriteTo(output, _repeated_data_codec);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
size += data_.CalculateSize(_repeated_data_codec);
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(MoreString other) {
if (other == null) {
return;
@@ -3628,6 +3928,7 @@ namespace Google.Protobuf.TestProtos {
data_.Add(other.data_);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -3645,29 +3946,34 @@ namespace Google.Protobuf.TestProtos {
}
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class OneBytes : pb::IMessage<OneBytes> {
private static readonly pb::MessageParser<OneBytes> _parser = new pb::MessageParser<OneBytes>(() => new OneBytes());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<OneBytes> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[15]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public OneBytes() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public OneBytes(OneBytes other) : this() {
data_ = other.data_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public OneBytes Clone() {
return new OneBytes(this);
}
@@ -3675,17 +3981,20 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "data" field.</summary>
public const int DataFieldNumber = 1;
private pb::ByteString data_ = pb::ByteString.Empty;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pb::ByteString Data {
get { return data_; }
set {
- data_ = pb::Preconditions.CheckNotNull(value, "value");
+ data_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as OneBytes);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(OneBytes other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -3697,16 +4006,19 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Data.Length != 0) hash ^= Data.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Data.Length != 0) {
output.WriteRawTag(10);
@@ -3714,6 +4026,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Data.Length != 0) {
@@ -3722,6 +4035,7 @@ namespace Google.Protobuf.TestProtos {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(OneBytes other) {
if (other == null) {
return;
@@ -3731,6 +4045,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -3748,29 +4063,34 @@ namespace Google.Protobuf.TestProtos {
}
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class MoreBytes : pb::IMessage<MoreBytes> {
private static readonly pb::MessageParser<MoreBytes> _parser = new pb::MessageParser<MoreBytes>(() => new MoreBytes());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<MoreBytes> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[16]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public MoreBytes() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public MoreBytes(MoreBytes other) : this() {
data_ = other.data_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public MoreBytes Clone() {
return new MoreBytes(this);
}
@@ -3778,17 +4098,20 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "data" field.</summary>
public const int DataFieldNumber = 1;
private pb::ByteString data_ = pb::ByteString.Empty;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pb::ByteString Data {
get { return data_; }
set {
- data_ = pb::Preconditions.CheckNotNull(value, "value");
+ data_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as MoreBytes);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(MoreBytes other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -3800,16 +4123,19 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Data.Length != 0) hash ^= Data.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Data.Length != 0) {
output.WriteRawTag(10);
@@ -3817,6 +4143,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Data.Length != 0) {
@@ -3825,6 +4152,7 @@ namespace Google.Protobuf.TestProtos {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(MoreBytes other) {
if (other == null) {
return;
@@ -3834,6 +4162,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -3854,29 +4183,34 @@ namespace Google.Protobuf.TestProtos {
/// <summary>
/// Test int32, uint32, int64, uint64, and bool are all compatible
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class Int32Message : pb::IMessage<Int32Message> {
private static readonly pb::MessageParser<Int32Message> _parser = new pb::MessageParser<Int32Message>(() => new Int32Message());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<Int32Message> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[17]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Int32Message() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Int32Message(Int32Message other) : this() {
data_ = other.data_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Int32Message Clone() {
return new Int32Message(this);
}
@@ -3884,6 +4218,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "data" field.</summary>
public const int DataFieldNumber = 1;
private int data_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int Data {
get { return data_; }
set {
@@ -3891,10 +4226,12 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as Int32Message);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(Int32Message other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -3906,16 +4243,19 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Data != 0) hash ^= Data.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Data != 0) {
output.WriteRawTag(8);
@@ -3923,6 +4263,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Data != 0) {
@@ -3931,6 +4272,7 @@ namespace Google.Protobuf.TestProtos {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(Int32Message other) {
if (other == null) {
return;
@@ -3940,6 +4282,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -3957,29 +4300,34 @@ namespace Google.Protobuf.TestProtos {
}
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class Uint32Message : pb::IMessage<Uint32Message> {
private static readonly pb::MessageParser<Uint32Message> _parser = new pb::MessageParser<Uint32Message>(() => new Uint32Message());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<Uint32Message> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[18]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Uint32Message() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Uint32Message(Uint32Message other) : this() {
data_ = other.data_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Uint32Message Clone() {
return new Uint32Message(this);
}
@@ -3987,6 +4335,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "data" field.</summary>
public const int DataFieldNumber = 1;
private uint data_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public uint Data {
get { return data_; }
set {
@@ -3994,10 +4343,12 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as Uint32Message);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(Uint32Message other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -4009,16 +4360,19 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Data != 0) hash ^= Data.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Data != 0) {
output.WriteRawTag(8);
@@ -4026,6 +4380,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Data != 0) {
@@ -4034,6 +4389,7 @@ namespace Google.Protobuf.TestProtos {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(Uint32Message other) {
if (other == null) {
return;
@@ -4043,6 +4399,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -4060,29 +4417,34 @@ namespace Google.Protobuf.TestProtos {
}
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class Int64Message : pb::IMessage<Int64Message> {
private static readonly pb::MessageParser<Int64Message> _parser = new pb::MessageParser<Int64Message>(() => new Int64Message());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<Int64Message> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[19]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Int64Message() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Int64Message(Int64Message other) : this() {
data_ = other.data_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Int64Message Clone() {
return new Int64Message(this);
}
@@ -4090,6 +4452,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "data" field.</summary>
public const int DataFieldNumber = 1;
private long data_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public long Data {
get { return data_; }
set {
@@ -4097,10 +4460,12 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as Int64Message);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(Int64Message other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -4112,16 +4477,19 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Data != 0L) hash ^= Data.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Data != 0L) {
output.WriteRawTag(8);
@@ -4129,6 +4497,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Data != 0L) {
@@ -4137,6 +4506,7 @@ namespace Google.Protobuf.TestProtos {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(Int64Message other) {
if (other == null) {
return;
@@ -4146,6 +4516,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -4163,29 +4534,34 @@ namespace Google.Protobuf.TestProtos {
}
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class Uint64Message : pb::IMessage<Uint64Message> {
private static readonly pb::MessageParser<Uint64Message> _parser = new pb::MessageParser<Uint64Message>(() => new Uint64Message());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<Uint64Message> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[20]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Uint64Message() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Uint64Message(Uint64Message other) : this() {
data_ = other.data_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Uint64Message Clone() {
return new Uint64Message(this);
}
@@ -4193,6 +4569,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "data" field.</summary>
public const int DataFieldNumber = 1;
private ulong data_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ulong Data {
get { return data_; }
set {
@@ -4200,10 +4577,12 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as Uint64Message);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(Uint64Message other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -4215,16 +4594,19 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Data != 0UL) hash ^= Data.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Data != 0UL) {
output.WriteRawTag(8);
@@ -4232,6 +4614,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Data != 0UL) {
@@ -4240,6 +4623,7 @@ namespace Google.Protobuf.TestProtos {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(Uint64Message other) {
if (other == null) {
return;
@@ -4249,6 +4633,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -4266,29 +4651,34 @@ namespace Google.Protobuf.TestProtos {
}
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class BoolMessage : pb::IMessage<BoolMessage> {
private static readonly pb::MessageParser<BoolMessage> _parser = new pb::MessageParser<BoolMessage>(() => new BoolMessage());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<BoolMessage> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[21]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public BoolMessage() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public BoolMessage(BoolMessage other) : this() {
data_ = other.data_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public BoolMessage Clone() {
return new BoolMessage(this);
}
@@ -4296,6 +4686,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "data" field.</summary>
public const int DataFieldNumber = 1;
private bool data_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Data {
get { return data_; }
set {
@@ -4303,10 +4694,12 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as BoolMessage);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(BoolMessage other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -4318,16 +4711,19 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Data != false) hash ^= Data.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Data != false) {
output.WriteRawTag(8);
@@ -4335,6 +4731,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Data != false) {
@@ -4343,6 +4740,7 @@ namespace Google.Protobuf.TestProtos {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(BoolMessage other) {
if (other == null) {
return;
@@ -4352,6 +4750,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -4372,25 +4771,29 @@ namespace Google.Protobuf.TestProtos {
/// <summary>
/// Test oneofs.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class TestOneof : pb::IMessage<TestOneof> {
private static readonly pb::MessageParser<TestOneof> _parser = new pb::MessageParser<TestOneof>(() => new TestOneof());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<TestOneof> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[22]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestOneof() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestOneof(TestOneof other) : this() {
switch (other.FooCase) {
case FooOneofCase.FooInt:
@@ -4406,12 +4809,14 @@ namespace Google.Protobuf.TestProtos {
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestOneof Clone() {
return new TestOneof(this);
}
/// <summary>Field number for the "foo_int" field.</summary>
public const int FooIntFieldNumber = 1;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int FooInt {
get { return fooCase_ == FooOneofCase.FooInt ? (int) foo_ : 0; }
set {
@@ -4422,16 +4827,18 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "foo_string" field.</summary>
public const int FooStringFieldNumber = 2;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string FooString {
get { return fooCase_ == FooOneofCase.FooString ? (string) foo_ : ""; }
set {
- foo_ = pb::Preconditions.CheckNotNull(value, "value");
+ foo_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
fooCase_ = FooOneofCase.FooString;
}
}
/// <summary>Field number for the "foo_message" field.</summary>
public const int FooMessageFieldNumber = 3;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.TestProtos.TestAllTypes FooMessage {
get { return fooCase_ == FooOneofCase.FooMessage ? (global::Google.Protobuf.TestProtos.TestAllTypes) foo_ : null; }
set {
@@ -4449,19 +4856,23 @@ namespace Google.Protobuf.TestProtos {
FooMessage = 3,
}
private FooOneofCase fooCase_ = FooOneofCase.None;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public FooOneofCase FooCase {
get { return fooCase_; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void ClearFoo() {
fooCase_ = FooOneofCase.None;
foo_ = null;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as TestOneof);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(TestOneof other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -4476,6 +4887,7 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (fooCase_ == FooOneofCase.FooInt) hash ^= FooInt.GetHashCode();
@@ -4485,10 +4897,12 @@ namespace Google.Protobuf.TestProtos {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (fooCase_ == FooOneofCase.FooInt) {
output.WriteRawTag(8);
@@ -4504,6 +4918,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (fooCase_ == FooOneofCase.FooInt) {
@@ -4518,6 +4933,7 @@ namespace Google.Protobuf.TestProtos {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(TestOneof other) {
if (other == null) {
return;
@@ -4536,6 +4952,7 @@ namespace Google.Protobuf.TestProtos {
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -4566,25 +4983,29 @@ namespace Google.Protobuf.TestProtos {
}
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class TestPackedTypes : pb::IMessage<TestPackedTypes> {
private static readonly pb::MessageParser<TestPackedTypes> _parser = new pb::MessageParser<TestPackedTypes>(() => new TestPackedTypes());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<TestPackedTypes> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[23]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestPackedTypes() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestPackedTypes(TestPackedTypes other) : this() {
packedInt32_ = other.packedInt32_.Clone();
packedInt64_ = other.packedInt64_.Clone();
@@ -4602,6 +5023,7 @@ namespace Google.Protobuf.TestProtos {
packedEnum_ = other.packedEnum_.Clone();
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestPackedTypes Clone() {
return new TestPackedTypes(this);
}
@@ -4611,6 +5033,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<int> _repeated_packedInt32_codec
= pb::FieldCodec.ForInt32(722);
private readonly pbc::RepeatedField<int> packedInt32_ = new pbc::RepeatedField<int>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<int> PackedInt32 {
get { return packedInt32_; }
}
@@ -4620,6 +5043,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<long> _repeated_packedInt64_codec
= pb::FieldCodec.ForInt64(730);
private readonly pbc::RepeatedField<long> packedInt64_ = new pbc::RepeatedField<long>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<long> PackedInt64 {
get { return packedInt64_; }
}
@@ -4629,6 +5053,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<uint> _repeated_packedUint32_codec
= pb::FieldCodec.ForUInt32(738);
private readonly pbc::RepeatedField<uint> packedUint32_ = new pbc::RepeatedField<uint>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<uint> PackedUint32 {
get { return packedUint32_; }
}
@@ -4638,6 +5063,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<ulong> _repeated_packedUint64_codec
= pb::FieldCodec.ForUInt64(746);
private readonly pbc::RepeatedField<ulong> packedUint64_ = new pbc::RepeatedField<ulong>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<ulong> PackedUint64 {
get { return packedUint64_; }
}
@@ -4647,6 +5073,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<int> _repeated_packedSint32_codec
= pb::FieldCodec.ForSInt32(754);
private readonly pbc::RepeatedField<int> packedSint32_ = new pbc::RepeatedField<int>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<int> PackedSint32 {
get { return packedSint32_; }
}
@@ -4656,6 +5083,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<long> _repeated_packedSint64_codec
= pb::FieldCodec.ForSInt64(762);
private readonly pbc::RepeatedField<long> packedSint64_ = new pbc::RepeatedField<long>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<long> PackedSint64 {
get { return packedSint64_; }
}
@@ -4665,6 +5093,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<uint> _repeated_packedFixed32_codec
= pb::FieldCodec.ForFixed32(770);
private readonly pbc::RepeatedField<uint> packedFixed32_ = new pbc::RepeatedField<uint>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<uint> PackedFixed32 {
get { return packedFixed32_; }
}
@@ -4674,6 +5103,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<ulong> _repeated_packedFixed64_codec
= pb::FieldCodec.ForFixed64(778);
private readonly pbc::RepeatedField<ulong> packedFixed64_ = new pbc::RepeatedField<ulong>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<ulong> PackedFixed64 {
get { return packedFixed64_; }
}
@@ -4683,6 +5113,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<int> _repeated_packedSfixed32_codec
= pb::FieldCodec.ForSFixed32(786);
private readonly pbc::RepeatedField<int> packedSfixed32_ = new pbc::RepeatedField<int>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<int> PackedSfixed32 {
get { return packedSfixed32_; }
}
@@ -4692,6 +5123,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<long> _repeated_packedSfixed64_codec
= pb::FieldCodec.ForSFixed64(794);
private readonly pbc::RepeatedField<long> packedSfixed64_ = new pbc::RepeatedField<long>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<long> PackedSfixed64 {
get { return packedSfixed64_; }
}
@@ -4701,6 +5133,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<float> _repeated_packedFloat_codec
= pb::FieldCodec.ForFloat(802);
private readonly pbc::RepeatedField<float> packedFloat_ = new pbc::RepeatedField<float>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<float> PackedFloat {
get { return packedFloat_; }
}
@@ -4710,6 +5143,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<double> _repeated_packedDouble_codec
= pb::FieldCodec.ForDouble(810);
private readonly pbc::RepeatedField<double> packedDouble_ = new pbc::RepeatedField<double>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<double> PackedDouble {
get { return packedDouble_; }
}
@@ -4719,6 +5153,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<bool> _repeated_packedBool_codec
= pb::FieldCodec.ForBool(818);
private readonly pbc::RepeatedField<bool> packedBool_ = new pbc::RepeatedField<bool>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<bool> PackedBool {
get { return packedBool_; }
}
@@ -4728,14 +5163,17 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<global::Google.Protobuf.TestProtos.ForeignEnum> _repeated_packedEnum_codec
= pb::FieldCodec.ForEnum(826, x => (int) x, x => (global::Google.Protobuf.TestProtos.ForeignEnum) x);
private readonly pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignEnum> packedEnum_ = new pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignEnum>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignEnum> PackedEnum {
get { return packedEnum_; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as TestPackedTypes);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(TestPackedTypes other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -4760,6 +5198,7 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
hash ^= packedInt32_.GetHashCode();
@@ -4779,10 +5218,12 @@ namespace Google.Protobuf.TestProtos {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
packedInt32_.WriteTo(output, _repeated_packedInt32_codec);
packedInt64_.WriteTo(output, _repeated_packedInt64_codec);
@@ -4800,6 +5241,7 @@ namespace Google.Protobuf.TestProtos {
packedEnum_.WriteTo(output, _repeated_packedEnum_codec);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
size += packedInt32_.CalculateSize(_repeated_packedInt32_codec);
@@ -4819,6 +5261,7 @@ namespace Google.Protobuf.TestProtos {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(TestPackedTypes other) {
if (other == null) {
return;
@@ -4839,6 +5282,7 @@ namespace Google.Protobuf.TestProtos {
packedEnum_.Add(other.packedEnum_);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -4926,25 +5370,29 @@ namespace Google.Protobuf.TestProtos {
/// A message with the same fields as TestPackedTypes, but without packing. Used
/// to test packed &lt;-> unpacked wire compatibility.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class TestUnpackedTypes : pb::IMessage<TestUnpackedTypes> {
private static readonly pb::MessageParser<TestUnpackedTypes> _parser = new pb::MessageParser<TestUnpackedTypes>(() => new TestUnpackedTypes());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<TestUnpackedTypes> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[24]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestUnpackedTypes() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestUnpackedTypes(TestUnpackedTypes other) : this() {
unpackedInt32_ = other.unpackedInt32_.Clone();
unpackedInt64_ = other.unpackedInt64_.Clone();
@@ -4962,6 +5410,7 @@ namespace Google.Protobuf.TestProtos {
unpackedEnum_ = other.unpackedEnum_.Clone();
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestUnpackedTypes Clone() {
return new TestUnpackedTypes(this);
}
@@ -4971,6 +5420,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<int> _repeated_unpackedInt32_codec
= pb::FieldCodec.ForInt32(720);
private readonly pbc::RepeatedField<int> unpackedInt32_ = new pbc::RepeatedField<int>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<int> UnpackedInt32 {
get { return unpackedInt32_; }
}
@@ -4980,6 +5430,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<long> _repeated_unpackedInt64_codec
= pb::FieldCodec.ForInt64(728);
private readonly pbc::RepeatedField<long> unpackedInt64_ = new pbc::RepeatedField<long>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<long> UnpackedInt64 {
get { return unpackedInt64_; }
}
@@ -4989,6 +5440,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<uint> _repeated_unpackedUint32_codec
= pb::FieldCodec.ForUInt32(736);
private readonly pbc::RepeatedField<uint> unpackedUint32_ = new pbc::RepeatedField<uint>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<uint> UnpackedUint32 {
get { return unpackedUint32_; }
}
@@ -4998,6 +5450,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<ulong> _repeated_unpackedUint64_codec
= pb::FieldCodec.ForUInt64(744);
private readonly pbc::RepeatedField<ulong> unpackedUint64_ = new pbc::RepeatedField<ulong>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<ulong> UnpackedUint64 {
get { return unpackedUint64_; }
}
@@ -5007,6 +5460,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<int> _repeated_unpackedSint32_codec
= pb::FieldCodec.ForSInt32(752);
private readonly pbc::RepeatedField<int> unpackedSint32_ = new pbc::RepeatedField<int>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<int> UnpackedSint32 {
get { return unpackedSint32_; }
}
@@ -5016,6 +5470,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<long> _repeated_unpackedSint64_codec
= pb::FieldCodec.ForSInt64(760);
private readonly pbc::RepeatedField<long> unpackedSint64_ = new pbc::RepeatedField<long>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<long> UnpackedSint64 {
get { return unpackedSint64_; }
}
@@ -5025,6 +5480,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<uint> _repeated_unpackedFixed32_codec
= pb::FieldCodec.ForFixed32(773);
private readonly pbc::RepeatedField<uint> unpackedFixed32_ = new pbc::RepeatedField<uint>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<uint> UnpackedFixed32 {
get { return unpackedFixed32_; }
}
@@ -5034,6 +5490,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<ulong> _repeated_unpackedFixed64_codec
= pb::FieldCodec.ForFixed64(777);
private readonly pbc::RepeatedField<ulong> unpackedFixed64_ = new pbc::RepeatedField<ulong>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<ulong> UnpackedFixed64 {
get { return unpackedFixed64_; }
}
@@ -5043,6 +5500,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<int> _repeated_unpackedSfixed32_codec
= pb::FieldCodec.ForSFixed32(789);
private readonly pbc::RepeatedField<int> unpackedSfixed32_ = new pbc::RepeatedField<int>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<int> UnpackedSfixed32 {
get { return unpackedSfixed32_; }
}
@@ -5052,6 +5510,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<long> _repeated_unpackedSfixed64_codec
= pb::FieldCodec.ForSFixed64(793);
private readonly pbc::RepeatedField<long> unpackedSfixed64_ = new pbc::RepeatedField<long>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<long> UnpackedSfixed64 {
get { return unpackedSfixed64_; }
}
@@ -5061,6 +5520,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<float> _repeated_unpackedFloat_codec
= pb::FieldCodec.ForFloat(805);
private readonly pbc::RepeatedField<float> unpackedFloat_ = new pbc::RepeatedField<float>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<float> UnpackedFloat {
get { return unpackedFloat_; }
}
@@ -5070,6 +5530,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<double> _repeated_unpackedDouble_codec
= pb::FieldCodec.ForDouble(809);
private readonly pbc::RepeatedField<double> unpackedDouble_ = new pbc::RepeatedField<double>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<double> UnpackedDouble {
get { return unpackedDouble_; }
}
@@ -5079,6 +5540,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<bool> _repeated_unpackedBool_codec
= pb::FieldCodec.ForBool(816);
private readonly pbc::RepeatedField<bool> unpackedBool_ = new pbc::RepeatedField<bool>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<bool> UnpackedBool {
get { return unpackedBool_; }
}
@@ -5088,14 +5550,17 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<global::Google.Protobuf.TestProtos.ForeignEnum> _repeated_unpackedEnum_codec
= pb::FieldCodec.ForEnum(824, x => (int) x, x => (global::Google.Protobuf.TestProtos.ForeignEnum) x);
private readonly pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignEnum> unpackedEnum_ = new pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignEnum>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignEnum> UnpackedEnum {
get { return unpackedEnum_; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as TestUnpackedTypes);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(TestUnpackedTypes other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -5120,6 +5585,7 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
hash ^= unpackedInt32_.GetHashCode();
@@ -5139,10 +5605,12 @@ namespace Google.Protobuf.TestProtos {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
unpackedInt32_.WriteTo(output, _repeated_unpackedInt32_codec);
unpackedInt64_.WriteTo(output, _repeated_unpackedInt64_codec);
@@ -5160,6 +5628,7 @@ namespace Google.Protobuf.TestProtos {
unpackedEnum_.WriteTo(output, _repeated_unpackedEnum_codec);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
size += unpackedInt32_.CalculateSize(_repeated_unpackedInt32_codec);
@@ -5179,6 +5648,7 @@ namespace Google.Protobuf.TestProtos {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(TestUnpackedTypes other) {
if (other == null) {
return;
@@ -5199,6 +5669,7 @@ namespace Google.Protobuf.TestProtos {
unpackedEnum_.Add(other.unpackedEnum_);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -5282,25 +5753,29 @@ namespace Google.Protobuf.TestProtos {
}
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class TestRepeatedScalarDifferentTagSizes : pb::IMessage<TestRepeatedScalarDifferentTagSizes> {
private static readonly pb::MessageParser<TestRepeatedScalarDifferentTagSizes> _parser = new pb::MessageParser<TestRepeatedScalarDifferentTagSizes>(() => new TestRepeatedScalarDifferentTagSizes());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<TestRepeatedScalarDifferentTagSizes> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[25]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestRepeatedScalarDifferentTagSizes() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestRepeatedScalarDifferentTagSizes(TestRepeatedScalarDifferentTagSizes other) : this() {
repeatedFixed32_ = other.repeatedFixed32_.Clone();
repeatedInt32_ = other.repeatedInt32_.Clone();
@@ -5310,6 +5785,7 @@ namespace Google.Protobuf.TestProtos {
repeatedUint64_ = other.repeatedUint64_.Clone();
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestRepeatedScalarDifferentTagSizes Clone() {
return new TestRepeatedScalarDifferentTagSizes(this);
}
@@ -5324,6 +5800,7 @@ namespace Google.Protobuf.TestProtos {
/// used in order to get a tag of the right size; all of the repeated fields
/// in TestAllTypes didn't trigger the check.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<uint> RepeatedFixed32 {
get { return repeatedFixed32_; }
}
@@ -5336,6 +5813,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>
/// Check for a varint type, just for good measure.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<int> RepeatedInt32 {
get { return repeatedInt32_; }
}
@@ -5348,6 +5826,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>
/// These have two-byte tags.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<ulong> RepeatedFixed64 {
get { return repeatedFixed64_; }
}
@@ -5357,6 +5836,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<long> _repeated_repeatedInt64_codec
= pb::FieldCodec.ForInt64(16378);
private readonly pbc::RepeatedField<long> repeatedInt64_ = new pbc::RepeatedField<long>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<long> RepeatedInt64 {
get { return repeatedInt64_; }
}
@@ -5369,6 +5849,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>
/// Three byte tags.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<float> RepeatedFloat {
get { return repeatedFloat_; }
}
@@ -5378,14 +5859,17 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<ulong> _repeated_repeatedUint64_codec
= pb::FieldCodec.ForUInt64(2097146);
private readonly pbc::RepeatedField<ulong> repeatedUint64_ = new pbc::RepeatedField<ulong>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<ulong> RepeatedUint64 {
get { return repeatedUint64_; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as TestRepeatedScalarDifferentTagSizes);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(TestRepeatedScalarDifferentTagSizes other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -5402,6 +5886,7 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
hash ^= repeatedFixed32_.GetHashCode();
@@ -5413,10 +5898,12 @@ namespace Google.Protobuf.TestProtos {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
repeatedFixed32_.WriteTo(output, _repeated_repeatedFixed32_codec);
repeatedInt32_.WriteTo(output, _repeated_repeatedInt32_codec);
@@ -5426,6 +5913,7 @@ namespace Google.Protobuf.TestProtos {
repeatedUint64_.WriteTo(output, _repeated_repeatedUint64_codec);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
size += repeatedFixed32_.CalculateSize(_repeated_repeatedFixed32_codec);
@@ -5437,6 +5925,7 @@ namespace Google.Protobuf.TestProtos {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(TestRepeatedScalarDifferentTagSizes other) {
if (other == null) {
return;
@@ -5449,6 +5938,7 @@ namespace Google.Protobuf.TestProtos {
repeatedUint64_.Add(other.repeatedUint64_);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -5492,29 +5982,34 @@ namespace Google.Protobuf.TestProtos {
}
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class TestCommentInjectionMessage : pb::IMessage<TestCommentInjectionMessage> {
private static readonly pb::MessageParser<TestCommentInjectionMessage> _parser = new pb::MessageParser<TestCommentInjectionMessage>(() => new TestCommentInjectionMessage());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<TestCommentInjectionMessage> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[26]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestCommentInjectionMessage() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestCommentInjectionMessage(TestCommentInjectionMessage other) : this() {
a_ = other.a_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestCommentInjectionMessage Clone() {
return new TestCommentInjectionMessage(this);
}
@@ -5525,17 +6020,20 @@ namespace Google.Protobuf.TestProtos {
/// <summary>
/// */ &lt;- This should not close the generated doc comment
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string A {
get { return a_; }
set {
- a_ = pb::Preconditions.CheckNotNull(value, "value");
+ a_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as TestCommentInjectionMessage);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(TestCommentInjectionMessage other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -5547,16 +6045,19 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (A.Length != 0) hash ^= A.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (A.Length != 0) {
output.WriteRawTag(10);
@@ -5564,6 +6065,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (A.Length != 0) {
@@ -5572,6 +6074,7 @@ namespace Google.Protobuf.TestProtos {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(TestCommentInjectionMessage other) {
if (other == null) {
return;
@@ -5581,6 +6084,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -5601,36 +6105,43 @@ namespace Google.Protobuf.TestProtos {
/// <summary>
/// Test that RPC services work.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class FooRequest : pb::IMessage<FooRequest> {
private static readonly pb::MessageParser<FooRequest> _parser = new pb::MessageParser<FooRequest>(() => new FooRequest());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<FooRequest> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[27]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public FooRequest() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public FooRequest(FooRequest other) : this() {
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public FooRequest Clone() {
return new FooRequest(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as FooRequest);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(FooRequest other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -5641,29 +6152,35 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(FooRequest other) {
if (other == null) {
return;
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -5677,36 +6194,43 @@ namespace Google.Protobuf.TestProtos {
}
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class FooResponse : pb::IMessage<FooResponse> {
private static readonly pb::MessageParser<FooResponse> _parser = new pb::MessageParser<FooResponse>(() => new FooResponse());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<FooResponse> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[28]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public FooResponse() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public FooResponse(FooResponse other) : this() {
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public FooResponse Clone() {
return new FooResponse(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as FooResponse);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(FooResponse other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -5717,29 +6241,35 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(FooResponse other) {
if (other == null) {
return;
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -5753,36 +6283,43 @@ namespace Google.Protobuf.TestProtos {
}
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class FooClientMessage : pb::IMessage<FooClientMessage> {
private static readonly pb::MessageParser<FooClientMessage> _parser = new pb::MessageParser<FooClientMessage>(() => new FooClientMessage());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<FooClientMessage> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[29]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public FooClientMessage() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public FooClientMessage(FooClientMessage other) : this() {
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public FooClientMessage Clone() {
return new FooClientMessage(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as FooClientMessage);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(FooClientMessage other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -5793,29 +6330,35 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(FooClientMessage other) {
if (other == null) {
return;
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -5829,36 +6372,43 @@ namespace Google.Protobuf.TestProtos {
}
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class FooServerMessage : pb::IMessage<FooServerMessage> {
private static readonly pb::MessageParser<FooServerMessage> _parser = new pb::MessageParser<FooServerMessage>(() => new FooServerMessage());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<FooServerMessage> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[30]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public FooServerMessage() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public FooServerMessage(FooServerMessage other) : this() {
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public FooServerMessage Clone() {
return new FooServerMessage(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as FooServerMessage);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(FooServerMessage other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -5869,29 +6419,35 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(FooServerMessage other) {
if (other == null) {
return;
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -5905,36 +6461,43 @@ namespace Google.Protobuf.TestProtos {
}
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class BarRequest : pb::IMessage<BarRequest> {
private static readonly pb::MessageParser<BarRequest> _parser = new pb::MessageParser<BarRequest>(() => new BarRequest());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<BarRequest> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[31]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public BarRequest() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public BarRequest(BarRequest other) : this() {
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public BarRequest Clone() {
return new BarRequest(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as BarRequest);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(BarRequest other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -5945,29 +6508,35 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(BarRequest other) {
if (other == null) {
return;
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -5981,36 +6550,43 @@ namespace Google.Protobuf.TestProtos {
}
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class BarResponse : pb::IMessage<BarResponse> {
private static readonly pb::MessageParser<BarResponse> _parser = new pb::MessageParser<BarResponse>(() => new BarResponse());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<BarResponse> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[32]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public BarResponse() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public BarResponse(BarResponse other) : this() {
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public BarResponse Clone() {
return new BarResponse(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as BarResponse);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(BarResponse other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -6021,29 +6597,35 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(BarResponse other) {
if (other == null) {
return;
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestWellKnownTypes.cs b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestWellKnownTypes.cs
index 642e5f91..6e87fb5d 100644
--- a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestWellKnownTypes.cs
+++ b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestWellKnownTypes.cs
@@ -10,7 +10,6 @@ using scg = global::System.Collections.Generic;
namespace Google.Protobuf.TestProtos {
/// <summary>Holder for reflection information generated from google/protobuf/unittest_well_known_types.proto</summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public static partial class UnittestWellKnownTypesReflection {
#region Descriptor
@@ -31,7 +30,7 @@ namespace Google.Protobuf.TestProtos {
"L3Byb3RvYnVmL3NvdXJjZV9jb250ZXh0LnByb3RvGhxnb29nbGUvcHJvdG9i",
"dWYvc3RydWN0LnByb3RvGh9nb29nbGUvcHJvdG9idWYvdGltZXN0YW1wLnBy",
"b3RvGhpnb29nbGUvcHJvdG9idWYvdHlwZS5wcm90bxoeZ29vZ2xlL3Byb3Rv",
- "YnVmL3dyYXBwZXJzLnByb3RvIpEHChJUZXN0V2VsbEtub3duVHlwZXMSJwoJ",
+ "YnVmL3dyYXBwZXJzLnByb3RvIr4HChJUZXN0V2VsbEtub3duVHlwZXMSJwoJ",
"YW55X2ZpZWxkGAEgASgLMhQuZ29vZ2xlLnByb3RvYnVmLkFueRInCglhcGlf",
"ZmllbGQYAiABKAsyFC5nb29nbGUucHJvdG9idWYuQXBpEjEKDmR1cmF0aW9u",
"X2ZpZWxkGAMgASgLMhkuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uEisKC2Vt",
@@ -51,7 +50,8 @@ namespace Google.Protobuf.TestProtos {
"cm90b2J1Zi5VSW50MzJWYWx1ZRIuCgpib29sX2ZpZWxkGBAgASgLMhouZ29v",
"Z2xlLnByb3RvYnVmLkJvb2xWYWx1ZRIyCgxzdHJpbmdfZmllbGQYESABKAsy",
"HC5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUSMAoLYnl0ZXNfZmllbGQY",
- "EiABKAsyGy5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSKVBwoWUmVwZWF0",
+ "EiABKAsyGy5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZRIrCgt2YWx1ZV9m",
+ "aWVsZBgTIAEoCzIWLmdvb2dsZS5wcm90b2J1Zi5WYWx1ZSKVBwoWUmVwZWF0",
"ZWRXZWxsS25vd25UeXBlcxInCglhbnlfZmllbGQYASADKAsyFC5nb29nbGUu",
"cHJvdG9idWYuQW55EicKCWFwaV9maWVsZBgCIAMoCzIULmdvb2dsZS5wcm90",
"b2J1Zi5BcGkSMQoOZHVyYXRpb25fZmllbGQYAyADKAsyGS5nb29nbGUucHJv",
@@ -161,11 +161,11 @@ namespace Google.Protobuf.TestProtos {
"dFByb3Rvc2IGcHJvdG8z"));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { global::Google.Protobuf.WellKnownTypes.AnyReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.ApiReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.DurationReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.EmptyReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.FieldMaskReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.SourceContextReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.StructReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.TimestampReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.TypeReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.WrappersReflection.Descriptor, },
- new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestWellKnownTypes), global::Google.Protobuf.TestProtos.TestWellKnownTypes.Parser, new[]{ "AnyField", "ApiField", "DurationField", "EmptyField", "FieldMaskField", "SourceContextField", "StructField", "TimestampField", "TypeField", "DoubleField", "FloatField", "Int64Field", "Uint64Field", "Int32Field", "Uint32Field", "BoolField", "StringField", "BytesField" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.RepeatedWellKnownTypes), global::Google.Protobuf.TestProtos.RepeatedWellKnownTypes.Parser, new[]{ "AnyField", "ApiField", "DurationField", "EmptyField", "FieldMaskField", "SourceContextField", "StructField", "TimestampField", "TypeField", "DoubleField", "FloatField", "Int64Field", "Uint64Field", "Int32Field", "Uint32Field", "BoolField", "StringField", "BytesField" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.OneofWellKnownTypes), global::Google.Protobuf.TestProtos.OneofWellKnownTypes.Parser, new[]{ "AnyField", "ApiField", "DurationField", "EmptyField", "FieldMaskField", "SourceContextField", "StructField", "TimestampField", "TypeField", "DoubleField", "FloatField", "Int64Field", "Uint64Field", "Int32Field", "Uint32Field", "BoolField", "StringField", "BytesField" }, new[]{ "OneofField" }, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.MapWellKnownTypes), global::Google.Protobuf.TestProtos.MapWellKnownTypes.Parser, new[]{ "AnyField", "ApiField", "DurationField", "EmptyField", "FieldMaskField", "SourceContextField", "StructField", "TimestampField", "TypeField", "DoubleField", "FloatField", "Int64Field", "Uint64Field", "Int32Field", "Uint32Field", "BoolField", "StringField", "BytesField" }, null, null, new pbr::GeneratedCodeInfo[] { null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, })
+ new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestWellKnownTypes), global::Google.Protobuf.TestProtos.TestWellKnownTypes.Parser, new[]{ "AnyField", "ApiField", "DurationField", "EmptyField", "FieldMaskField", "SourceContextField", "StructField", "TimestampField", "TypeField", "DoubleField", "FloatField", "Int64Field", "Uint64Field", "Int32Field", "Uint32Field", "BoolField", "StringField", "BytesField", "ValueField" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.RepeatedWellKnownTypes), global::Google.Protobuf.TestProtos.RepeatedWellKnownTypes.Parser, new[]{ "AnyField", "ApiField", "DurationField", "EmptyField", "FieldMaskField", "SourceContextField", "StructField", "TimestampField", "TypeField", "DoubleField", "FloatField", "Int64Field", "Uint64Field", "Int32Field", "Uint32Field", "BoolField", "StringField", "BytesField" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.OneofWellKnownTypes), global::Google.Protobuf.TestProtos.OneofWellKnownTypes.Parser, new[]{ "AnyField", "ApiField", "DurationField", "EmptyField", "FieldMaskField", "SourceContextField", "StructField", "TimestampField", "TypeField", "DoubleField", "FloatField", "Int64Field", "Uint64Field", "Int32Field", "Uint32Field", "BoolField", "StringField", "BytesField" }, new[]{ "OneofField" }, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.MapWellKnownTypes), global::Google.Protobuf.TestProtos.MapWellKnownTypes.Parser, new[]{ "AnyField", "ApiField", "DurationField", "EmptyField", "FieldMaskField", "SourceContextField", "StructField", "TimestampField", "TypeField", "DoubleField", "FloatField", "Int64Field", "Uint64Field", "Int32Field", "Uint32Field", "BoolField", "StringField", "BytesField" }, null, null, new pbr::GeneratedClrTypeInfo[] { null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, })
}));
}
#endregion
@@ -177,25 +177,29 @@ namespace Google.Protobuf.TestProtos {
/// Each wrapper type is included separately, as languages
/// map handle different wrappers in different ways.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class TestWellKnownTypes : pb::IMessage<TestWellKnownTypes> {
private static readonly pb::MessageParser<TestWellKnownTypes> _parser = new pb::MessageParser<TestWellKnownTypes>(() => new TestWellKnownTypes());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<TestWellKnownTypes> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestWellKnownTypesReflection.Descriptor.MessageTypes[0]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestWellKnownTypes() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestWellKnownTypes(TestWellKnownTypes other) : this() {
AnyField = other.anyField_ != null ? other.AnyField.Clone() : null;
ApiField = other.apiField_ != null ? other.ApiField.Clone() : null;
@@ -215,8 +219,10 @@ namespace Google.Protobuf.TestProtos {
BoolField = other.BoolField;
StringField = other.StringField;
BytesField = other.BytesField;
+ ValueField = other.valueField_ != null ? other.ValueField.Clone() : null;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TestWellKnownTypes Clone() {
return new TestWellKnownTypes(this);
}
@@ -224,6 +230,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "any_field" field.</summary>
public const int AnyFieldFieldNumber = 1;
private global::Google.Protobuf.WellKnownTypes.Any anyField_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.WellKnownTypes.Any AnyField {
get { return anyField_; }
set {
@@ -234,6 +241,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "api_field" field.</summary>
public const int ApiFieldFieldNumber = 2;
private global::Google.Protobuf.WellKnownTypes.Api apiField_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.WellKnownTypes.Api ApiField {
get { return apiField_; }
set {
@@ -244,6 +252,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "duration_field" field.</summary>
public const int DurationFieldFieldNumber = 3;
private global::Google.Protobuf.WellKnownTypes.Duration durationField_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.WellKnownTypes.Duration DurationField {
get { return durationField_; }
set {
@@ -254,6 +263,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "empty_field" field.</summary>
public const int EmptyFieldFieldNumber = 4;
private global::Google.Protobuf.WellKnownTypes.Empty emptyField_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.WellKnownTypes.Empty EmptyField {
get { return emptyField_; }
set {
@@ -264,6 +274,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "field_mask_field" field.</summary>
public const int FieldMaskFieldFieldNumber = 5;
private global::Google.Protobuf.WellKnownTypes.FieldMask fieldMaskField_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.WellKnownTypes.FieldMask FieldMaskField {
get { return fieldMaskField_; }
set {
@@ -274,6 +285,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "source_context_field" field.</summary>
public const int SourceContextFieldFieldNumber = 6;
private global::Google.Protobuf.WellKnownTypes.SourceContext sourceContextField_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.WellKnownTypes.SourceContext SourceContextField {
get { return sourceContextField_; }
set {
@@ -284,6 +296,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "struct_field" field.</summary>
public const int StructFieldFieldNumber = 7;
private global::Google.Protobuf.WellKnownTypes.Struct structField_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.WellKnownTypes.Struct StructField {
get { return structField_; }
set {
@@ -294,6 +307,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "timestamp_field" field.</summary>
public const int TimestampFieldFieldNumber = 8;
private global::Google.Protobuf.WellKnownTypes.Timestamp timestampField_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.WellKnownTypes.Timestamp TimestampField {
get { return timestampField_; }
set {
@@ -304,6 +318,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "type_field" field.</summary>
public const int TypeFieldFieldNumber = 9;
private global::Google.Protobuf.WellKnownTypes.Type typeField_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.WellKnownTypes.Type TypeField {
get { return typeField_; }
set {
@@ -315,6 +330,7 @@ namespace Google.Protobuf.TestProtos {
public const int DoubleFieldFieldNumber = 10;
private static readonly pb::FieldCodec<double?> _single_doubleField_codec = pb::FieldCodec.ForStructWrapper<double>(82);
private double? doubleField_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public double? DoubleField {
get { return doubleField_; }
set {
@@ -326,6 +342,7 @@ namespace Google.Protobuf.TestProtos {
public const int FloatFieldFieldNumber = 11;
private static readonly pb::FieldCodec<float?> _single_floatField_codec = pb::FieldCodec.ForStructWrapper<float>(90);
private float? floatField_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public float? FloatField {
get { return floatField_; }
set {
@@ -337,6 +354,7 @@ namespace Google.Protobuf.TestProtos {
public const int Int64FieldFieldNumber = 12;
private static readonly pb::FieldCodec<long?> _single_int64Field_codec = pb::FieldCodec.ForStructWrapper<long>(98);
private long? int64Field_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public long? Int64Field {
get { return int64Field_; }
set {
@@ -348,6 +366,7 @@ namespace Google.Protobuf.TestProtos {
public const int Uint64FieldFieldNumber = 13;
private static readonly pb::FieldCodec<ulong?> _single_uint64Field_codec = pb::FieldCodec.ForStructWrapper<ulong>(106);
private ulong? uint64Field_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ulong? Uint64Field {
get { return uint64Field_; }
set {
@@ -359,6 +378,7 @@ namespace Google.Protobuf.TestProtos {
public const int Int32FieldFieldNumber = 14;
private static readonly pb::FieldCodec<int?> _single_int32Field_codec = pb::FieldCodec.ForStructWrapper<int>(114);
private int? int32Field_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int? Int32Field {
get { return int32Field_; }
set {
@@ -370,6 +390,7 @@ namespace Google.Protobuf.TestProtos {
public const int Uint32FieldFieldNumber = 15;
private static readonly pb::FieldCodec<uint?> _single_uint32Field_codec = pb::FieldCodec.ForStructWrapper<uint>(122);
private uint? uint32Field_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public uint? Uint32Field {
get { return uint32Field_; }
set {
@@ -381,6 +402,7 @@ namespace Google.Protobuf.TestProtos {
public const int BoolFieldFieldNumber = 16;
private static readonly pb::FieldCodec<bool?> _single_boolField_codec = pb::FieldCodec.ForStructWrapper<bool>(130);
private bool? boolField_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool? BoolField {
get { return boolField_; }
set {
@@ -392,6 +414,7 @@ namespace Google.Protobuf.TestProtos {
public const int StringFieldFieldNumber = 17;
private static readonly pb::FieldCodec<string> _single_stringField_codec = pb::FieldCodec.ForClassWrapper<string>(138);
private string stringField_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string StringField {
get { return stringField_; }
set {
@@ -403,6 +426,7 @@ namespace Google.Protobuf.TestProtos {
public const int BytesFieldFieldNumber = 18;
private static readonly pb::FieldCodec<pb::ByteString> _single_bytesField_codec = pb::FieldCodec.ForClassWrapper<pb::ByteString>(146);
private pb::ByteString bytesField_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pb::ByteString BytesField {
get { return bytesField_; }
set {
@@ -410,10 +434,26 @@ namespace Google.Protobuf.TestProtos {
}
}
+ /// <summary>Field number for the "value_field" field.</summary>
+ public const int ValueFieldFieldNumber = 19;
+ private global::Google.Protobuf.WellKnownTypes.Value valueField_;
+ /// <summary>
+ /// Part of struct, but useful to be able to test separately
+ /// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public global::Google.Protobuf.WellKnownTypes.Value ValueField {
+ get { return valueField_; }
+ set {
+ valueField_ = value;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as TestWellKnownTypes);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(TestWellKnownTypes other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -439,9 +479,11 @@ namespace Google.Protobuf.TestProtos {
if (BoolField != other.BoolField) return false;
if (StringField != other.StringField) return false;
if (BytesField != other.BytesField) return false;
+ if (!object.Equals(ValueField, other.ValueField)) return false;
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (anyField_ != null) hash ^= AnyField.GetHashCode();
@@ -462,13 +504,16 @@ namespace Google.Protobuf.TestProtos {
if (boolField_ != null) hash ^= BoolField.GetHashCode();
if (stringField_ != null) hash ^= StringField.GetHashCode();
if (bytesField_ != null) hash ^= BytesField.GetHashCode();
+ if (valueField_ != null) hash ^= ValueField.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (anyField_ != null) {
output.WriteRawTag(10);
@@ -533,8 +578,13 @@ namespace Google.Protobuf.TestProtos {
if (bytesField_ != null) {
_single_bytesField_codec.WriteTagAndValue(output, BytesField);
}
+ if (valueField_ != null) {
+ output.WriteRawTag(154, 1);
+ output.WriteMessage(ValueField);
+ }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (anyField_ != null) {
@@ -591,9 +641,13 @@ namespace Google.Protobuf.TestProtos {
if (bytesField_ != null) {
size += _single_bytesField_codec.CalculateSizeWithTag(BytesField);
}
+ if (valueField_ != null) {
+ size += 2 + pb::CodedOutputStream.ComputeMessageSize(ValueField);
+ }
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(TestWellKnownTypes other) {
if (other == null) {
return;
@@ -697,8 +751,15 @@ namespace Google.Protobuf.TestProtos {
BytesField = other.BytesField;
}
}
+ if (other.valueField_ != null) {
+ if (valueField_ == null) {
+ valueField_ = new global::Google.Protobuf.WellKnownTypes.Value();
+ }
+ ValueField.MergeFrom(other.ValueField);
+ }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -832,6 +893,13 @@ namespace Google.Protobuf.TestProtos {
}
break;
}
+ case 154: {
+ if (valueField_ == null) {
+ valueField_ = new global::Google.Protobuf.WellKnownTypes.Value();
+ }
+ input.ReadMessage(valueField_);
+ break;
+ }
}
}
}
@@ -841,25 +909,29 @@ namespace Google.Protobuf.TestProtos {
/// <summary>
/// A repeated field for each well-known type.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class RepeatedWellKnownTypes : pb::IMessage<RepeatedWellKnownTypes> {
private static readonly pb::MessageParser<RepeatedWellKnownTypes> _parser = new pb::MessageParser<RepeatedWellKnownTypes>(() => new RepeatedWellKnownTypes());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<RepeatedWellKnownTypes> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestWellKnownTypesReflection.Descriptor.MessageTypes[1]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public RepeatedWellKnownTypes() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public RepeatedWellKnownTypes(RepeatedWellKnownTypes other) : this() {
anyField_ = other.anyField_.Clone();
apiField_ = other.apiField_.Clone();
@@ -881,6 +953,7 @@ namespace Google.Protobuf.TestProtos {
bytesField_ = other.bytesField_.Clone();
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public RepeatedWellKnownTypes Clone() {
return new RepeatedWellKnownTypes(this);
}
@@ -890,6 +963,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<global::Google.Protobuf.WellKnownTypes.Any> _repeated_anyField_codec
= pb::FieldCodec.ForMessage(10, global::Google.Protobuf.WellKnownTypes.Any.Parser);
private readonly pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Any> anyField_ = new pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Any>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Any> AnyField {
get { return anyField_; }
}
@@ -899,6 +973,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<global::Google.Protobuf.WellKnownTypes.Api> _repeated_apiField_codec
= pb::FieldCodec.ForMessage(18, global::Google.Protobuf.WellKnownTypes.Api.Parser);
private readonly pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Api> apiField_ = new pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Api>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Api> ApiField {
get { return apiField_; }
}
@@ -908,6 +983,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<global::Google.Protobuf.WellKnownTypes.Duration> _repeated_durationField_codec
= pb::FieldCodec.ForMessage(26, global::Google.Protobuf.WellKnownTypes.Duration.Parser);
private readonly pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Duration> durationField_ = new pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Duration>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Duration> DurationField {
get { return durationField_; }
}
@@ -917,6 +993,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<global::Google.Protobuf.WellKnownTypes.Empty> _repeated_emptyField_codec
= pb::FieldCodec.ForMessage(34, global::Google.Protobuf.WellKnownTypes.Empty.Parser);
private readonly pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Empty> emptyField_ = new pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Empty>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Empty> EmptyField {
get { return emptyField_; }
}
@@ -926,6 +1003,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<global::Google.Protobuf.WellKnownTypes.FieldMask> _repeated_fieldMaskField_codec
= pb::FieldCodec.ForMessage(42, global::Google.Protobuf.WellKnownTypes.FieldMask.Parser);
private readonly pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.FieldMask> fieldMaskField_ = new pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.FieldMask>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.FieldMask> FieldMaskField {
get { return fieldMaskField_; }
}
@@ -935,6 +1013,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<global::Google.Protobuf.WellKnownTypes.SourceContext> _repeated_sourceContextField_codec
= pb::FieldCodec.ForMessage(50, global::Google.Protobuf.WellKnownTypes.SourceContext.Parser);
private readonly pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.SourceContext> sourceContextField_ = new pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.SourceContext>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.SourceContext> SourceContextField {
get { return sourceContextField_; }
}
@@ -944,6 +1023,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<global::Google.Protobuf.WellKnownTypes.Struct> _repeated_structField_codec
= pb::FieldCodec.ForMessage(58, global::Google.Protobuf.WellKnownTypes.Struct.Parser);
private readonly pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Struct> structField_ = new pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Struct>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Struct> StructField {
get { return structField_; }
}
@@ -953,6 +1033,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<global::Google.Protobuf.WellKnownTypes.Timestamp> _repeated_timestampField_codec
= pb::FieldCodec.ForMessage(66, global::Google.Protobuf.WellKnownTypes.Timestamp.Parser);
private readonly pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Timestamp> timestampField_ = new pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Timestamp>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Timestamp> TimestampField {
get { return timestampField_; }
}
@@ -962,6 +1043,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<global::Google.Protobuf.WellKnownTypes.Type> _repeated_typeField_codec
= pb::FieldCodec.ForMessage(74, global::Google.Protobuf.WellKnownTypes.Type.Parser);
private readonly pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Type> typeField_ = new pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Type>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Type> TypeField {
get { return typeField_; }
}
@@ -974,6 +1056,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>
/// These don't actually make a lot of sense, but they're not prohibited...
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<double?> DoubleField {
get { return doubleField_; }
}
@@ -983,6 +1066,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<float?> _repeated_floatField_codec
= pb::FieldCodec.ForStructWrapper<float>(90);
private readonly pbc::RepeatedField<float?> floatField_ = new pbc::RepeatedField<float?>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<float?> FloatField {
get { return floatField_; }
}
@@ -992,6 +1076,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<long?> _repeated_int64Field_codec
= pb::FieldCodec.ForStructWrapper<long>(98);
private readonly pbc::RepeatedField<long?> int64Field_ = new pbc::RepeatedField<long?>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<long?> Int64Field {
get { return int64Field_; }
}
@@ -1001,6 +1086,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<ulong?> _repeated_uint64Field_codec
= pb::FieldCodec.ForStructWrapper<ulong>(106);
private readonly pbc::RepeatedField<ulong?> uint64Field_ = new pbc::RepeatedField<ulong?>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<ulong?> Uint64Field {
get { return uint64Field_; }
}
@@ -1010,6 +1096,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<int?> _repeated_int32Field_codec
= pb::FieldCodec.ForStructWrapper<int>(114);
private readonly pbc::RepeatedField<int?> int32Field_ = new pbc::RepeatedField<int?>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<int?> Int32Field {
get { return int32Field_; }
}
@@ -1019,6 +1106,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<uint?> _repeated_uint32Field_codec
= pb::FieldCodec.ForStructWrapper<uint>(122);
private readonly pbc::RepeatedField<uint?> uint32Field_ = new pbc::RepeatedField<uint?>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<uint?> Uint32Field {
get { return uint32Field_; }
}
@@ -1028,6 +1116,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<bool?> _repeated_boolField_codec
= pb::FieldCodec.ForStructWrapper<bool>(130);
private readonly pbc::RepeatedField<bool?> boolField_ = new pbc::RepeatedField<bool?>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<bool?> BoolField {
get { return boolField_; }
}
@@ -1037,6 +1126,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<string> _repeated_stringField_codec
= pb::FieldCodec.ForClassWrapper<string>(138);
private readonly pbc::RepeatedField<string> stringField_ = new pbc::RepeatedField<string>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<string> StringField {
get { return stringField_; }
}
@@ -1046,14 +1136,17 @@ namespace Google.Protobuf.TestProtos {
private static readonly pb::FieldCodec<pb::ByteString> _repeated_bytesField_codec
= pb::FieldCodec.ForClassWrapper<pb::ByteString>(146);
private readonly pbc::RepeatedField<pb::ByteString> bytesField_ = new pbc::RepeatedField<pb::ByteString>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<pb::ByteString> BytesField {
get { return bytesField_; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as RepeatedWellKnownTypes);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(RepeatedWellKnownTypes other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -1082,6 +1175,7 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
hash ^= anyField_.GetHashCode();
@@ -1105,10 +1199,12 @@ namespace Google.Protobuf.TestProtos {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
anyField_.WriteTo(output, _repeated_anyField_codec);
apiField_.WriteTo(output, _repeated_apiField_codec);
@@ -1130,6 +1226,7 @@ namespace Google.Protobuf.TestProtos {
bytesField_.WriteTo(output, _repeated_bytesField_codec);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
size += anyField_.CalculateSize(_repeated_anyField_codec);
@@ -1153,6 +1250,7 @@ namespace Google.Protobuf.TestProtos {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(RepeatedWellKnownTypes other) {
if (other == null) {
return;
@@ -1177,6 +1275,7 @@ namespace Google.Protobuf.TestProtos {
bytesField_.Add(other.bytesField_);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -1262,25 +1361,29 @@ namespace Google.Protobuf.TestProtos {
}
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class OneofWellKnownTypes : pb::IMessage<OneofWellKnownTypes> {
private static readonly pb::MessageParser<OneofWellKnownTypes> _parser = new pb::MessageParser<OneofWellKnownTypes>(() => new OneofWellKnownTypes());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<OneofWellKnownTypes> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestWellKnownTypesReflection.Descriptor.MessageTypes[2]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public OneofWellKnownTypes() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public OneofWellKnownTypes(OneofWellKnownTypes other) : this() {
switch (other.OneofFieldCase) {
case OneofFieldOneofCase.AnyField:
@@ -1341,12 +1444,14 @@ namespace Google.Protobuf.TestProtos {
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public OneofWellKnownTypes Clone() {
return new OneofWellKnownTypes(this);
}
/// <summary>Field number for the "any_field" field.</summary>
public const int AnyFieldFieldNumber = 1;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.WellKnownTypes.Any AnyField {
get { return oneofFieldCase_ == OneofFieldOneofCase.AnyField ? (global::Google.Protobuf.WellKnownTypes.Any) oneofField_ : null; }
set {
@@ -1357,6 +1462,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "api_field" field.</summary>
public const int ApiFieldFieldNumber = 2;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.WellKnownTypes.Api ApiField {
get { return oneofFieldCase_ == OneofFieldOneofCase.ApiField ? (global::Google.Protobuf.WellKnownTypes.Api) oneofField_ : null; }
set {
@@ -1367,6 +1473,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "duration_field" field.</summary>
public const int DurationFieldFieldNumber = 3;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.WellKnownTypes.Duration DurationField {
get { return oneofFieldCase_ == OneofFieldOneofCase.DurationField ? (global::Google.Protobuf.WellKnownTypes.Duration) oneofField_ : null; }
set {
@@ -1377,6 +1484,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "empty_field" field.</summary>
public const int EmptyFieldFieldNumber = 4;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.WellKnownTypes.Empty EmptyField {
get { return oneofFieldCase_ == OneofFieldOneofCase.EmptyField ? (global::Google.Protobuf.WellKnownTypes.Empty) oneofField_ : null; }
set {
@@ -1387,6 +1495,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "field_mask_field" field.</summary>
public const int FieldMaskFieldFieldNumber = 5;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.WellKnownTypes.FieldMask FieldMaskField {
get { return oneofFieldCase_ == OneofFieldOneofCase.FieldMaskField ? (global::Google.Protobuf.WellKnownTypes.FieldMask) oneofField_ : null; }
set {
@@ -1397,6 +1506,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "source_context_field" field.</summary>
public const int SourceContextFieldFieldNumber = 6;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.WellKnownTypes.SourceContext SourceContextField {
get { return oneofFieldCase_ == OneofFieldOneofCase.SourceContextField ? (global::Google.Protobuf.WellKnownTypes.SourceContext) oneofField_ : null; }
set {
@@ -1407,6 +1517,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "struct_field" field.</summary>
public const int StructFieldFieldNumber = 7;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.WellKnownTypes.Struct StructField {
get { return oneofFieldCase_ == OneofFieldOneofCase.StructField ? (global::Google.Protobuf.WellKnownTypes.Struct) oneofField_ : null; }
set {
@@ -1417,6 +1528,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "timestamp_field" field.</summary>
public const int TimestampFieldFieldNumber = 8;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.WellKnownTypes.Timestamp TimestampField {
get { return oneofFieldCase_ == OneofFieldOneofCase.TimestampField ? (global::Google.Protobuf.WellKnownTypes.Timestamp) oneofField_ : null; }
set {
@@ -1427,6 +1539,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "type_field" field.</summary>
public const int TypeFieldFieldNumber = 9;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.WellKnownTypes.Type TypeField {
get { return oneofFieldCase_ == OneofFieldOneofCase.TypeField ? (global::Google.Protobuf.WellKnownTypes.Type) oneofField_ : null; }
set {
@@ -1438,6 +1551,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "double_field" field.</summary>
public const int DoubleFieldFieldNumber = 10;
private static readonly pb::FieldCodec<double?> _oneof_doubleField_codec = pb::FieldCodec.ForStructWrapper<double>(82);
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public double? DoubleField {
get { return oneofFieldCase_ == OneofFieldOneofCase.DoubleField ? (double?) oneofField_ : (double?) null; }
set {
@@ -1449,6 +1563,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "float_field" field.</summary>
public const int FloatFieldFieldNumber = 11;
private static readonly pb::FieldCodec<float?> _oneof_floatField_codec = pb::FieldCodec.ForStructWrapper<float>(90);
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public float? FloatField {
get { return oneofFieldCase_ == OneofFieldOneofCase.FloatField ? (float?) oneofField_ : (float?) null; }
set {
@@ -1460,6 +1575,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "int64_field" field.</summary>
public const int Int64FieldFieldNumber = 12;
private static readonly pb::FieldCodec<long?> _oneof_int64Field_codec = pb::FieldCodec.ForStructWrapper<long>(98);
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public long? Int64Field {
get { return oneofFieldCase_ == OneofFieldOneofCase.Int64Field ? (long?) oneofField_ : (long?) null; }
set {
@@ -1471,6 +1587,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "uint64_field" field.</summary>
public const int Uint64FieldFieldNumber = 13;
private static readonly pb::FieldCodec<ulong?> _oneof_uint64Field_codec = pb::FieldCodec.ForStructWrapper<ulong>(106);
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ulong? Uint64Field {
get { return oneofFieldCase_ == OneofFieldOneofCase.Uint64Field ? (ulong?) oneofField_ : (ulong?) null; }
set {
@@ -1482,6 +1599,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "int32_field" field.</summary>
public const int Int32FieldFieldNumber = 14;
private static readonly pb::FieldCodec<int?> _oneof_int32Field_codec = pb::FieldCodec.ForStructWrapper<int>(114);
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int? Int32Field {
get { return oneofFieldCase_ == OneofFieldOneofCase.Int32Field ? (int?) oneofField_ : (int?) null; }
set {
@@ -1493,6 +1611,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "uint32_field" field.</summary>
public const int Uint32FieldFieldNumber = 15;
private static readonly pb::FieldCodec<uint?> _oneof_uint32Field_codec = pb::FieldCodec.ForStructWrapper<uint>(122);
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public uint? Uint32Field {
get { return oneofFieldCase_ == OneofFieldOneofCase.Uint32Field ? (uint?) oneofField_ : (uint?) null; }
set {
@@ -1504,6 +1623,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "bool_field" field.</summary>
public const int BoolFieldFieldNumber = 16;
private static readonly pb::FieldCodec<bool?> _oneof_boolField_codec = pb::FieldCodec.ForStructWrapper<bool>(130);
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool? BoolField {
get { return oneofFieldCase_ == OneofFieldOneofCase.BoolField ? (bool?) oneofField_ : (bool?) null; }
set {
@@ -1515,6 +1635,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "string_field" field.</summary>
public const int StringFieldFieldNumber = 17;
private static readonly pb::FieldCodec<string> _oneof_stringField_codec = pb::FieldCodec.ForClassWrapper<string>(138);
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string StringField {
get { return oneofFieldCase_ == OneofFieldOneofCase.StringField ? (string) oneofField_ : (string) null; }
set {
@@ -1526,6 +1647,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "bytes_field" field.</summary>
public const int BytesFieldFieldNumber = 18;
private static readonly pb::FieldCodec<pb::ByteString> _oneof_bytesField_codec = pb::FieldCodec.ForClassWrapper<pb::ByteString>(146);
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pb::ByteString BytesField {
get { return oneofFieldCase_ == OneofFieldOneofCase.BytesField ? (pb::ByteString) oneofField_ : (pb::ByteString) null; }
set {
@@ -1558,19 +1680,23 @@ namespace Google.Protobuf.TestProtos {
BytesField = 18,
}
private OneofFieldOneofCase oneofFieldCase_ = OneofFieldOneofCase.None;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public OneofFieldOneofCase OneofFieldCase {
get { return oneofFieldCase_; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void ClearOneofField() {
oneofFieldCase_ = OneofFieldOneofCase.None;
oneofField_ = null;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as OneofWellKnownTypes);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(OneofWellKnownTypes other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -1600,6 +1726,7 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (oneofFieldCase_ == OneofFieldOneofCase.AnyField) hash ^= AnyField.GetHashCode();
@@ -1624,10 +1751,12 @@ namespace Google.Protobuf.TestProtos {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (oneofFieldCase_ == OneofFieldOneofCase.AnyField) {
output.WriteRawTag(10);
@@ -1694,6 +1823,7 @@ namespace Google.Protobuf.TestProtos {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (oneofFieldCase_ == OneofFieldOneofCase.AnyField) {
@@ -1753,6 +1883,7 @@ namespace Google.Protobuf.TestProtos {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(OneofWellKnownTypes other) {
if (other == null) {
return;
@@ -1816,6 +1947,7 @@ namespace Google.Protobuf.TestProtos {
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -1951,25 +2083,29 @@ namespace Google.Protobuf.TestProtos {
/// need to worry about the value part of the map being the
/// well-known types, as messages can't be map keys.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class MapWellKnownTypes : pb::IMessage<MapWellKnownTypes> {
private static readonly pb::MessageParser<MapWellKnownTypes> _parser = new pb::MessageParser<MapWellKnownTypes>(() => new MapWellKnownTypes());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<MapWellKnownTypes> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.TestProtos.UnittestWellKnownTypesReflection.Descriptor.MessageTypes[3]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public MapWellKnownTypes() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public MapWellKnownTypes(MapWellKnownTypes other) : this() {
anyField_ = other.anyField_.Clone();
apiField_ = other.apiField_.Clone();
@@ -1991,6 +2127,7 @@ namespace Google.Protobuf.TestProtos {
bytesField_ = other.bytesField_.Clone();
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public MapWellKnownTypes Clone() {
return new MapWellKnownTypes(this);
}
@@ -2000,6 +2137,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pbc::MapField<int, global::Google.Protobuf.WellKnownTypes.Any>.Codec _map_anyField_codec
= new pbc::MapField<int, global::Google.Protobuf.WellKnownTypes.Any>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForMessage(18, global::Google.Protobuf.WellKnownTypes.Any.Parser), 10);
private readonly pbc::MapField<int, global::Google.Protobuf.WellKnownTypes.Any> anyField_ = new pbc::MapField<int, global::Google.Protobuf.WellKnownTypes.Any>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<int, global::Google.Protobuf.WellKnownTypes.Any> AnyField {
get { return anyField_; }
}
@@ -2009,6 +2147,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pbc::MapField<int, global::Google.Protobuf.WellKnownTypes.Api>.Codec _map_apiField_codec
= new pbc::MapField<int, global::Google.Protobuf.WellKnownTypes.Api>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForMessage(18, global::Google.Protobuf.WellKnownTypes.Api.Parser), 18);
private readonly pbc::MapField<int, global::Google.Protobuf.WellKnownTypes.Api> apiField_ = new pbc::MapField<int, global::Google.Protobuf.WellKnownTypes.Api>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<int, global::Google.Protobuf.WellKnownTypes.Api> ApiField {
get { return apiField_; }
}
@@ -2018,6 +2157,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pbc::MapField<int, global::Google.Protobuf.WellKnownTypes.Duration>.Codec _map_durationField_codec
= new pbc::MapField<int, global::Google.Protobuf.WellKnownTypes.Duration>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForMessage(18, global::Google.Protobuf.WellKnownTypes.Duration.Parser), 26);
private readonly pbc::MapField<int, global::Google.Protobuf.WellKnownTypes.Duration> durationField_ = new pbc::MapField<int, global::Google.Protobuf.WellKnownTypes.Duration>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<int, global::Google.Protobuf.WellKnownTypes.Duration> DurationField {
get { return durationField_; }
}
@@ -2027,6 +2167,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pbc::MapField<int, global::Google.Protobuf.WellKnownTypes.Empty>.Codec _map_emptyField_codec
= new pbc::MapField<int, global::Google.Protobuf.WellKnownTypes.Empty>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForMessage(18, global::Google.Protobuf.WellKnownTypes.Empty.Parser), 34);
private readonly pbc::MapField<int, global::Google.Protobuf.WellKnownTypes.Empty> emptyField_ = new pbc::MapField<int, global::Google.Protobuf.WellKnownTypes.Empty>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<int, global::Google.Protobuf.WellKnownTypes.Empty> EmptyField {
get { return emptyField_; }
}
@@ -2036,6 +2177,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pbc::MapField<int, global::Google.Protobuf.WellKnownTypes.FieldMask>.Codec _map_fieldMaskField_codec
= new pbc::MapField<int, global::Google.Protobuf.WellKnownTypes.FieldMask>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForMessage(18, global::Google.Protobuf.WellKnownTypes.FieldMask.Parser), 42);
private readonly pbc::MapField<int, global::Google.Protobuf.WellKnownTypes.FieldMask> fieldMaskField_ = new pbc::MapField<int, global::Google.Protobuf.WellKnownTypes.FieldMask>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<int, global::Google.Protobuf.WellKnownTypes.FieldMask> FieldMaskField {
get { return fieldMaskField_; }
}
@@ -2045,6 +2187,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pbc::MapField<int, global::Google.Protobuf.WellKnownTypes.SourceContext>.Codec _map_sourceContextField_codec
= new pbc::MapField<int, global::Google.Protobuf.WellKnownTypes.SourceContext>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForMessage(18, global::Google.Protobuf.WellKnownTypes.SourceContext.Parser), 50);
private readonly pbc::MapField<int, global::Google.Protobuf.WellKnownTypes.SourceContext> sourceContextField_ = new pbc::MapField<int, global::Google.Protobuf.WellKnownTypes.SourceContext>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<int, global::Google.Protobuf.WellKnownTypes.SourceContext> SourceContextField {
get { return sourceContextField_; }
}
@@ -2054,6 +2197,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pbc::MapField<int, global::Google.Protobuf.WellKnownTypes.Struct>.Codec _map_structField_codec
= new pbc::MapField<int, global::Google.Protobuf.WellKnownTypes.Struct>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForMessage(18, global::Google.Protobuf.WellKnownTypes.Struct.Parser), 58);
private readonly pbc::MapField<int, global::Google.Protobuf.WellKnownTypes.Struct> structField_ = new pbc::MapField<int, global::Google.Protobuf.WellKnownTypes.Struct>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<int, global::Google.Protobuf.WellKnownTypes.Struct> StructField {
get { return structField_; }
}
@@ -2063,6 +2207,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pbc::MapField<int, global::Google.Protobuf.WellKnownTypes.Timestamp>.Codec _map_timestampField_codec
= new pbc::MapField<int, global::Google.Protobuf.WellKnownTypes.Timestamp>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForMessage(18, global::Google.Protobuf.WellKnownTypes.Timestamp.Parser), 66);
private readonly pbc::MapField<int, global::Google.Protobuf.WellKnownTypes.Timestamp> timestampField_ = new pbc::MapField<int, global::Google.Protobuf.WellKnownTypes.Timestamp>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<int, global::Google.Protobuf.WellKnownTypes.Timestamp> TimestampField {
get { return timestampField_; }
}
@@ -2072,6 +2217,7 @@ namespace Google.Protobuf.TestProtos {
private static readonly pbc::MapField<int, global::Google.Protobuf.WellKnownTypes.Type>.Codec _map_typeField_codec
= new pbc::MapField<int, global::Google.Protobuf.WellKnownTypes.Type>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForMessage(18, global::Google.Protobuf.WellKnownTypes.Type.Parser), 74);
private readonly pbc::MapField<int, global::Google.Protobuf.WellKnownTypes.Type> typeField_ = new pbc::MapField<int, global::Google.Protobuf.WellKnownTypes.Type>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<int, global::Google.Protobuf.WellKnownTypes.Type> TypeField {
get { return typeField_; }
}
@@ -2080,7 +2226,8 @@ namespace Google.Protobuf.TestProtos {
public const int DoubleFieldFieldNumber = 10;
private static readonly pbc::MapField<int, double?>.Codec _map_doubleField_codec
= new pbc::MapField<int, double?>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForStructWrapper<double>(18), 82);
- private readonly pbc::MapField<int, double?> doubleField_ = new pbc::MapField<int, double?>(true);
+ private readonly pbc::MapField<int, double?> doubleField_ = new pbc::MapField<int, double?>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<int, double?> DoubleField {
get { return doubleField_; }
}
@@ -2089,7 +2236,8 @@ namespace Google.Protobuf.TestProtos {
public const int FloatFieldFieldNumber = 11;
private static readonly pbc::MapField<int, float?>.Codec _map_floatField_codec
= new pbc::MapField<int, float?>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForStructWrapper<float>(18), 90);
- private readonly pbc::MapField<int, float?> floatField_ = new pbc::MapField<int, float?>(true);
+ private readonly pbc::MapField<int, float?> floatField_ = new pbc::MapField<int, float?>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<int, float?> FloatField {
get { return floatField_; }
}
@@ -2098,7 +2246,8 @@ namespace Google.Protobuf.TestProtos {
public const int Int64FieldFieldNumber = 12;
private static readonly pbc::MapField<int, long?>.Codec _map_int64Field_codec
= new pbc::MapField<int, long?>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForStructWrapper<long>(18), 98);
- private readonly pbc::MapField<int, long?> int64Field_ = new pbc::MapField<int, long?>(true);
+ private readonly pbc::MapField<int, long?> int64Field_ = new pbc::MapField<int, long?>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<int, long?> Int64Field {
get { return int64Field_; }
}
@@ -2107,7 +2256,8 @@ namespace Google.Protobuf.TestProtos {
public const int Uint64FieldFieldNumber = 13;
private static readonly pbc::MapField<int, ulong?>.Codec _map_uint64Field_codec
= new pbc::MapField<int, ulong?>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForStructWrapper<ulong>(18), 106);
- private readonly pbc::MapField<int, ulong?> uint64Field_ = new pbc::MapField<int, ulong?>(true);
+ private readonly pbc::MapField<int, ulong?> uint64Field_ = new pbc::MapField<int, ulong?>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<int, ulong?> Uint64Field {
get { return uint64Field_; }
}
@@ -2116,7 +2266,8 @@ namespace Google.Protobuf.TestProtos {
public const int Int32FieldFieldNumber = 14;
private static readonly pbc::MapField<int, int?>.Codec _map_int32Field_codec
= new pbc::MapField<int, int?>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForStructWrapper<int>(18), 114);
- private readonly pbc::MapField<int, int?> int32Field_ = new pbc::MapField<int, int?>(true);
+ private readonly pbc::MapField<int, int?> int32Field_ = new pbc::MapField<int, int?>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<int, int?> Int32Field {
get { return int32Field_; }
}
@@ -2125,7 +2276,8 @@ namespace Google.Protobuf.TestProtos {
public const int Uint32FieldFieldNumber = 15;
private static readonly pbc::MapField<int, uint?>.Codec _map_uint32Field_codec
= new pbc::MapField<int, uint?>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForStructWrapper<uint>(18), 122);
- private readonly pbc::MapField<int, uint?> uint32Field_ = new pbc::MapField<int, uint?>(true);
+ private readonly pbc::MapField<int, uint?> uint32Field_ = new pbc::MapField<int, uint?>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<int, uint?> Uint32Field {
get { return uint32Field_; }
}
@@ -2134,7 +2286,8 @@ namespace Google.Protobuf.TestProtos {
public const int BoolFieldFieldNumber = 16;
private static readonly pbc::MapField<int, bool?>.Codec _map_boolField_codec
= new pbc::MapField<int, bool?>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForStructWrapper<bool>(18), 130);
- private readonly pbc::MapField<int, bool?> boolField_ = new pbc::MapField<int, bool?>(true);
+ private readonly pbc::MapField<int, bool?> boolField_ = new pbc::MapField<int, bool?>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<int, bool?> BoolField {
get { return boolField_; }
}
@@ -2143,7 +2296,8 @@ namespace Google.Protobuf.TestProtos {
public const int StringFieldFieldNumber = 17;
private static readonly pbc::MapField<int, string>.Codec _map_stringField_codec
= new pbc::MapField<int, string>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForClassWrapper<string>(18), 138);
- private readonly pbc::MapField<int, string> stringField_ = new pbc::MapField<int, string>(true);
+ private readonly pbc::MapField<int, string> stringField_ = new pbc::MapField<int, string>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<int, string> StringField {
get { return stringField_; }
}
@@ -2152,15 +2306,18 @@ namespace Google.Protobuf.TestProtos {
public const int BytesFieldFieldNumber = 18;
private static readonly pbc::MapField<int, pb::ByteString>.Codec _map_bytesField_codec
= new pbc::MapField<int, pb::ByteString>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForClassWrapper<pb::ByteString>(18), 146);
- private readonly pbc::MapField<int, pb::ByteString> bytesField_ = new pbc::MapField<int, pb::ByteString>(true);
+ private readonly pbc::MapField<int, pb::ByteString> bytesField_ = new pbc::MapField<int, pb::ByteString>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<int, pb::ByteString> BytesField {
get { return bytesField_; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as MapWellKnownTypes);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(MapWellKnownTypes other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -2189,6 +2346,7 @@ namespace Google.Protobuf.TestProtos {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
hash ^= AnyField.GetHashCode();
@@ -2212,10 +2370,12 @@ namespace Google.Protobuf.TestProtos {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
anyField_.WriteTo(output, _map_anyField_codec);
apiField_.WriteTo(output, _map_apiField_codec);
@@ -2237,6 +2397,7 @@ namespace Google.Protobuf.TestProtos {
bytesField_.WriteTo(output, _map_bytesField_codec);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
size += anyField_.CalculateSize(_map_anyField_codec);
@@ -2260,6 +2421,7 @@ namespace Google.Protobuf.TestProtos {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(MapWellKnownTypes other) {
if (other == null) {
return;
@@ -2284,6 +2446,7 @@ namespace Google.Protobuf.TestProtos {
bytesField_.Add(other.bytesField_);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
diff --git a/csharp/src/Google.Protobuf.Test/WellKnownTypes/AnyTest.cs b/csharp/src/Google.Protobuf.Test/WellKnownTypes/AnyTest.cs
index 0a2b8b32..4aecc998 100644
--- a/csharp/src/Google.Protobuf.Test/WellKnownTypes/AnyTest.cs
+++ b/csharp/src/Google.Protobuf.Test/WellKnownTypes/AnyTest.cs
@@ -47,6 +47,24 @@ namespace Google.Protobuf.WellKnownTypes
}
[Test]
+ public void Pack_WithCustomPrefix()
+ {
+ var message = SampleMessages.CreateFullTestAllTypes();
+ var any = Any.Pack(message, "foo.bar/baz");
+ Assert.AreEqual("foo.bar/baz/protobuf_unittest.TestAllTypes", any.TypeUrl);
+ Assert.AreEqual(message.CalculateSize(), any.Value.Length);
+ }
+
+ [Test]
+ public void Pack_WithCustomPrefixTrailingSlash()
+ {
+ var message = SampleMessages.CreateFullTestAllTypes();
+ var any = Any.Pack(message, "foo.bar/baz/");
+ Assert.AreEqual("foo.bar/baz/protobuf_unittest.TestAllTypes", any.TypeUrl);
+ Assert.AreEqual(message.CalculateSize(), any.Value.Length);
+ }
+
+ [Test]
public void Unpack_WrongType()
{
var message = SampleMessages.CreateFullTestAllTypes();
@@ -62,5 +80,37 @@ namespace Google.Protobuf.WellKnownTypes
var unpacked = any.Unpack<TestAllTypes>();
Assert.AreEqual(message, unpacked);
}
+
+ [Test]
+ public void Unpack_CustomPrefix_Success()
+ {
+ var message = SampleMessages.CreateFullTestAllTypes();
+ var any = Any.Pack(message, "foo.bar/baz");
+ var unpacked = any.Unpack<TestAllTypes>();
+ Assert.AreEqual(message, unpacked);
+ }
+
+ [Test]
+ public void ToString_WithValues()
+ {
+ var message = SampleMessages.CreateFullTestAllTypes();
+ var any = Any.Pack(message);
+ var text = any.ToString();
+ Assert.That(text, Does.Contain("\"@value\": \"" + message.ToByteString().ToBase64() + "\""));
+ }
+
+ [Test]
+ public void ToString_Empty()
+ {
+ var any = new Any();
+ Assert.AreEqual("{ \"@type\": \"\", \"@value\": \"\" }", any.ToString());
+ }
+
+ [Test]
+ public void ToString_MessageContainingAny()
+ {
+ var message = new TestWellKnownTypes { AnyField = new Any() };
+ Assert.AreEqual("{ \"anyField\": { \"@type\": \"\", \"@value\": \"\" } }", message.ToString());
+ }
}
}
diff --git a/csharp/src/Google.Protobuf.Test/WellKnownTypes/DurationTest.cs b/csharp/src/Google.Protobuf.Test/WellKnownTypes/DurationTest.cs
index 36012e63..141faf80 100644
--- a/csharp/src/Google.Protobuf.Test/WellKnownTypes/DurationTest.cs
+++ b/csharp/src/Google.Protobuf.Test/WellKnownTypes/DurationTest.cs
@@ -50,11 +50,6 @@ namespace Google.Protobuf.WellKnownTypes
// Rounding is towards 0
Assert.AreEqual(TimeSpan.FromTicks(2), new Duration { Nanos = 250 }.ToTimeSpan());
Assert.AreEqual(TimeSpan.FromTicks(-2), new Duration { Nanos = -250 }.ToTimeSpan());
-
- // Non-normalized durations
- Assert.AreEqual(TimeSpan.FromSeconds(3), new Duration { Seconds = 1, Nanos = 2 * Duration.NanosecondsPerSecond }.ToTimeSpan());
- Assert.AreEqual(TimeSpan.FromSeconds(1), new Duration { Seconds = 3, Nanos = -2 * Duration.NanosecondsPerSecond }.ToTimeSpan());
- Assert.AreEqual(TimeSpan.FromSeconds(-1), new Duration { Seconds = 1, Nanos = -2 * Duration.NanosecondsPerSecond }.ToTimeSpan());
}
[Test]
@@ -100,5 +95,38 @@ namespace Google.Protobuf.WellKnownTypes
Assert.AreEqual(new Duration { Seconds = 1 }, Duration.FromTimeSpan(TimeSpan.FromSeconds(1)));
Assert.AreEqual(new Duration { Nanos = Duration.NanosecondsPerTick }, Duration.FromTimeSpan(TimeSpan.FromTicks(1)));
}
+
+ [Test]
+ [TestCase(0, Duration.MaxNanoseconds + 1)]
+ [TestCase(0, Duration.MinNanoseconds - 1)]
+ [TestCase(Duration.MinSeconds - 1, 0)]
+ [TestCase(Duration.MaxSeconds + 1, 0)]
+ [TestCase(1, -1)]
+ [TestCase(-1, 1)]
+ public void ToTimeSpan_Invalid(long seconds, int nanoseconds)
+ {
+ var duration = new Duration { Seconds = seconds, Nanos = nanoseconds };
+ Assert.Throws<InvalidOperationException>(() => duration.ToTimeSpan());
+ }
+
+ [Test]
+ [TestCase(0, Duration.MaxNanoseconds)]
+ [TestCase(0, Duration.MinNanoseconds)]
+ [TestCase(Duration.MinSeconds, Duration.MinNanoseconds)]
+ [TestCase(Duration.MaxSeconds, Duration.MaxNanoseconds)]
+ public void ToTimeSpan_Valid(long seconds, int nanoseconds)
+ {
+ // Only testing that these values don't throw, unlike their similar tests in ToTimeSpan_Invalid
+ var duration = new Duration { Seconds = seconds, Nanos = nanoseconds };
+ duration.ToTimeSpan();
+ }
+
+ [Test]
+ public void ToString_NonNormalized()
+ {
+ // Just a single example should be sufficient...
+ var duration = new Duration { Seconds = 1, Nanos = -1 };
+ Assert.AreEqual("{ \"@warning\": \"Invalid Duration\", \"seconds\": \"1\", \"nanos\": -1 }", duration.ToString());
+ }
}
}
diff --git a/csharp/src/Google.Protobuf.Test/WellKnownTypes/FieldMaskTest.cs b/csharp/src/Google.Protobuf.Test/WellKnownTypes/FieldMaskTest.cs
new file mode 100644
index 00000000..1d9908b4
--- /dev/null
+++ b/csharp/src/Google.Protobuf.Test/WellKnownTypes/FieldMaskTest.cs
@@ -0,0 +1,62 @@
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2016 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.
+#endregion
+
+
+using NUnit.Framework;
+
+namespace Google.Protobuf.WellKnownTypes
+{
+ public class FieldMaskTest
+ {
+ [Test]
+ [TestCase("foo__bar")]
+ [TestCase("foo_3_ar")]
+ [TestCase("fooBar")]
+ public void ToString_Invalid(string input)
+ {
+ var mask = new FieldMask { Paths = { input } };
+ var text = mask.ToString();
+ // More specific test below
+ Assert.That(text, Does.Contain("@warning"));
+ Assert.That(text, Does.Contain(input));
+ }
+
+ [Test]
+ public void ToString_Invalid_Precise()
+ {
+ var mask = new FieldMask { Paths = { "x", "foo__bar", @"x\y" } };
+ Assert.AreEqual(
+ "{ \"@warning\": \"Invalid FieldMask\", \"paths\": [ \"x\", \"foo__bar\", \"x\\\\y\" ] }",
+ mask.ToString());
+ }
+ }
+}
diff --git a/csharp/src/Google.Protobuf.Test/WellKnownTypes/TimestampTest.cs b/csharp/src/Google.Protobuf.Test/WellKnownTypes/TimestampTest.cs
index 597539eb..9ecd24c6 100644
--- a/csharp/src/Google.Protobuf.Test/WellKnownTypes/TimestampTest.cs
+++ b/csharp/src/Google.Protobuf.Test/WellKnownTypes/TimestampTest.cs
@@ -61,6 +61,29 @@ namespace Google.Protobuf.WellKnownTypes
Assert.AreEqual(new DateTime(1969, 12, 31, 23, 59, 59).AddMilliseconds(1), t2.ToDateTime());
}
+ [Test]
+ [TestCase(Timestamp.UnixSecondsAtBclMinValue - 1, Timestamp.MaxNanos)]
+ [TestCase(Timestamp.UnixSecondsAtBclMaxValue + 1, 0)]
+ [TestCase(0, -1)]
+ [TestCase(0, Timestamp.MaxNanos + 1)]
+ public void ToDateTime_OutOfRange(long seconds, int nanoseconds)
+ {
+ var value = new Timestamp { Seconds = seconds, Nanos = nanoseconds };
+ Assert.Throws<InvalidOperationException>(() => value.ToDateTime());
+ }
+
+ // 1ns larger or smaller than the above values
+ [Test]
+ [TestCase(Timestamp.UnixSecondsAtBclMinValue, 0)]
+ [TestCase(Timestamp.UnixSecondsAtBclMaxValue, Timestamp.MaxNanos)]
+ [TestCase(0, 0)]
+ [TestCase(0, Timestamp.MaxNanos)]
+ public void ToDateTime_ValidBoundaries(long seconds, int nanoseconds)
+ {
+ var value = new Timestamp { Seconds = seconds, Nanos = nanoseconds };
+ value.ToDateTime();
+ }
+
private static void AssertRoundtrip(Timestamp timestamp, DateTime dateTime)
{
Assert.AreEqual(timestamp, Timestamp.FromDateTime(dateTime));
@@ -80,5 +103,13 @@ namespace Google.Protobuf.WellKnownTypes
Assert.AreEqual(t1, t2 + difference);
Assert.AreEqual(t2, t1 - difference);
}
+
+ [Test]
+ public void ToString_NonNormalized()
+ {
+ // Just a single example should be sufficient...
+ var duration = new Timestamp { Seconds = 1, Nanos = -1 };
+ Assert.AreEqual("{ \"@warning\": \"Invalid Timestamp\", \"seconds\": \"1\", \"nanos\": -1 }", duration.ToString());
+ }
}
}
diff --git a/csharp/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs b/csharp/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs
index c87ceb2f..5b7185dc 100644
--- a/csharp/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs
+++ b/csharp/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs
@@ -149,8 +149,34 @@ namespace Google.Protobuf.WellKnownTypes
}
[Test]
+ public void RepeatedWrappersBinaryFormat()
+ {
+ // At one point we accidentally used a packed format for repeated wrappers, which is wrong (and weird).
+ // This test is just to prove that we use the right format.
+
+ var rawOutput = new MemoryStream();
+ var output = new CodedOutputStream(rawOutput);
+ // Write a value of 5
+ output.WriteTag(RepeatedWellKnownTypes.Int32FieldFieldNumber, WireFormat.WireType.LengthDelimited);
+ output.WriteLength(2);
+ output.WriteTag(WrappersReflection.WrapperValueFieldNumber, WireFormat.WireType.Varint);
+ output.WriteInt32(5);
+ // Write a value of 0 (empty message)
+ output.WriteTag(RepeatedWellKnownTypes.Int32FieldFieldNumber, WireFormat.WireType.LengthDelimited);
+ output.WriteLength(0);
+ output.Flush();
+ var expectedBytes = rawOutput.ToArray();
+
+ var message = new RepeatedWellKnownTypes { Int32Field = { 5, 0 } };
+ var actualBytes = message.ToByteArray();
+ Assert.AreEqual(expectedBytes, actualBytes);
+ }
+
+ [Test]
public void MapWrappersSerializeDeserialize()
{
+ // Note: no null values here, as they are prohibited in map fields
+ // (despite being representable).
var message = new MapWellKnownTypes
{
BoolField = { { 10, false }, { 20, true } },
@@ -158,13 +184,12 @@ namespace Google.Protobuf.WellKnownTypes
{ -1, ByteString.CopyFrom(1, 2, 3) },
{ 10, ByteString.CopyFrom(4, 5, 6) },
{ 1000, ByteString.Empty },
- { 10000, null }
},
DoubleField = { { 1, 12.5 }, { 10, -1.5 }, { 20, 0d } },
FloatField = { { 2, 123.25f }, { 3, -20f }, { 4, 0f } },
Int32Field = { { 5, int.MaxValue }, { 6, int.MinValue }, { 7, 0 } },
Int64Field = { { 8, long.MaxValue }, { 9, long.MinValue }, { 10, 0L } },
- StringField = { { 11, "First" }, { 12, "Second" }, { 13, "" }, { 14, null } },
+ StringField = { { 11, "First" }, { 12, "Second" }, { 13, "" } },
Uint32Field = { { 15, uint.MaxValue }, { 16, uint.MinValue }, { 17, 0U } },
Uint64Field = { { 18, ulong.MaxValue }, { 19, ulong.MinValue }, { 20, 0UL } },
};
@@ -224,13 +249,11 @@ namespace Google.Protobuf.WellKnownTypes
[Test]
public void Reflection_MapFields()
{
- // Just a single example... note that we can't have a null value here
- var message = new MapWellKnownTypes { Int32Field = { { 1, 2 }, { 3, null } } };
+ // Just a single example... note that we can't have a null value here despite the value type being int?
+ var message = new MapWellKnownTypes { Int32Field = { { 1, 2 } } };
var fields = MapWellKnownTypes.Descriptor.Fields;
var dictionary = (IDictionary) fields[MapWellKnownTypes.Int32FieldFieldNumber].Accessor.GetValue(message);
Assert.AreEqual(2, dictionary[1]);
- Assert.IsNull(dictionary[3]);
- Assert.IsTrue(dictionary.Contains(3));
}
[Test]
@@ -296,9 +319,10 @@ namespace Google.Protobuf.WellKnownTypes
// Merging is odd with wrapper types, due to the way that default values aren't emitted in
// the binary stream. In fact we cheat a little bit - a message with an explicitly present default
- // value will have that default value ignored.
+ // value will have that default value ignored. See issue 615. Fixing this would require significant upheaval to
+ // the FieldCodec side of things.
[Test]
- public void MergingCornerCase()
+ public void MergingStreamExplicitValue()
{
var message = new TestWellKnownTypes { Int32Field = 5 };
@@ -320,10 +344,48 @@ namespace Google.Protobuf.WellKnownTypes
message.MergeFrom(bytes);
// A normal implementation would have 0 now, as the explicit default would have been overwritten the 5.
+ // With the FieldCodec for Nullable<int>, we can't tell the difference between an implicit 0 and an explicit 0.
Assert.AreEqual(5, message.Int32Field);
}
[Test]
+ public void MergingStreamNoValue()
+ {
+ var message = new TestWellKnownTypes { Int32Field = 5 };
+
+ // Create a byte array which an Int32 field, but with no value.
+ var bytes = new TestWellKnownTypes { Int32Field = 0 }.ToByteArray();
+ Assert.AreEqual(2, bytes.Length); // The tag for Int32Field is a single byte, then a byte indicating a 0-length message.
+ message.MergeFrom(bytes);
+
+ // The "implicit" 0 did *not* overwrite the value.
+ // (This is the correct behaviour.)
+ Assert.AreEqual(5, message.Int32Field);
+ }
+
+ // All permutations of origin/merging value being null, zero (default) or non-default.
+ // As this is the in-memory version, we don't need to worry about the difference between implicit and explicit 0.
+ [Test]
+ [TestCase(null, null, null)]
+ [TestCase(null, 0, 0)]
+ [TestCase(null, 5, 5)]
+ [TestCase(0, null, 0)]
+ [TestCase(0, 0, 0)]
+ [TestCase(0, 5, 5)]
+ [TestCase(5, null, 5)]
+ [TestCase(5, 0, 5)]
+ [TestCase(5, 10, 10)]
+ public void MergingMessageWithZero(int? originValue, int? mergingValue, int? expectedResult)
+ {
+ // This differs from the MergingStreamCornerCase because when we merge message *objects*,
+ // we ignore default values from the "source".
+ var message1 = new TestWellKnownTypes { Int32Field = originValue };
+ var message2 = new TestWellKnownTypes { Int32Field = mergingValue };
+ message1.MergeFrom(message2);
+ Assert.AreEqual(expectedResult, message1.Int32Field);
+ }
+
+ [Test]
public void UnknownFieldInWrapper()
{
var stream = new MemoryStream();
diff --git a/csharp/src/Google.Protobuf.Test/packages.config b/csharp/src/Google.Protobuf.Test/packages.config
deleted file mode 100644
index c7653992..00000000
--- a/csharp/src/Google.Protobuf.Test/packages.config
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
- <package id="NUnit" version="2.6.4" targetFramework="net45" userInstalled="true" />
- <package id="NUnitTestAdapter" version="2.0.0" targetFramework="net45" userInstalled="true" />
-</packages> \ No newline at end of file
diff --git a/csharp/src/Google.Protobuf.Test/project.json b/csharp/src/Google.Protobuf.Test/project.json
new file mode 100644
index 00000000..87b732c9
--- /dev/null
+++ b/csharp/src/Google.Protobuf.Test/project.json
@@ -0,0 +1,44 @@
+{
+ "buildOptions": {
+ "debugType": "portable",
+ "keyFile": "../../keys/Google.Protobuf.snk"
+ },
+
+ "configurations": {
+ "Debug": {
+ "buildOptions": {
+ "define": [ "DEBUG", "TRACE" ]
+ }
+ },
+ "Release": {
+ "buildOptions": {
+ "define": [ "RELEASE", "TRACE" ],
+ "optimize": true
+ }
+ }
+ },
+
+ "dependencies": {
+ "Google.Protobuf": { "target": "project" },
+ "NUnit": "3.4.0",
+ "dotnet-test-nunit": "3.4.0-alpha-2",
+ },
+
+ "testRunner": "nunit",
+
+ "frameworks": {
+ "netcoreapp1.0": {
+ "imports" : [ "dnxcore50", "netcoreapp1.0", "portable-net45+win8" ],
+ "buildOptions": {
+ "define": [ "PCL" ]
+ },
+ "dependencies": {
+ "Microsoft.NETCore.App": {
+ "version": "1.0.0",
+ "type": "platform"
+ },
+ "System.Console": "4.0.0"
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/csharp/src/Google.Protobuf.sln b/csharp/src/Google.Protobuf.sln
index 69ce9a47..3c62bba3 100644
--- a/csharp/src/Google.Protobuf.sln
+++ b/csharp/src/Google.Protobuf.sln
@@ -1,54 +1,43 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 2013
-VisualStudioVersion = 12.0.31101.0
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Google.Protobuf", "Google.Protobuf\Google.Protobuf.csproj", "{6908BDCE-D925-43F3-94AC-A531E6DF2591}"
+# Visual Studio 14
+VisualStudioVersion = 14.0.25420.1
+MinimumVisualStudioVersion = 14.0.24720.0
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "AddressBook", "AddressBook\AddressBook.xproj", "{AFB63919-1E05-43B4-802A-8FB8C9B2F463}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Google.Protobuf.Test", "Google.Protobuf.Test\Google.Protobuf.Test.csproj", "{DD01ED24-3750-4567-9A23-1DB676A15610}"
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Google.Protobuf", "Google.Protobuf\Google.Protobuf.xproj", "{9B576380-726D-4142-8238-60A43AB0E35A}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AddressBook", "AddressBook\AddressBook.csproj", "{A31F5FB2-4FF3-432A-B35B-5CD203606311}"
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Google.Protobuf.Test", "Google.Protobuf.Test\Google.Protobuf.Test.xproj", "{580EB013-D3C7-4578-B845-015F4A3B0591}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Google.Protobuf.JsonDump", "Google.Protobuf.JsonDump\Google.Protobuf.JsonDump.csproj", "{D7282E99-2DC3-405B-946F-177DB2FD2AE2}"
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Google.Protobuf.Conformance", "Google.Protobuf.Conformance\Google.Protobuf.Conformance.xproj", "{DDDC055B-E185-4181-BAB0-072F0F984569}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Google.Protobuf.Conformance", "Google.Protobuf.Conformance\Google.Protobuf.Conformance.csproj", "{0607D1B8-80D6-4B35-9857-1263C1B32B94}"
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Google.Protobuf.JsonDump", "Google.Protobuf.JsonDump\Google.Protobuf.JsonDump.xproj", "{9695E08F-9829-497D-B95C-B38F28D48690}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
- ReleaseSigned|Any CPU = ReleaseSigned|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {6908BDCE-D925-43F3-94AC-A531E6DF2591}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {6908BDCE-D925-43F3-94AC-A531E6DF2591}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {6908BDCE-D925-43F3-94AC-A531E6DF2591}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {6908BDCE-D925-43F3-94AC-A531E6DF2591}.Release|Any CPU.Build.0 = Release|Any CPU
- {6908BDCE-D925-43F3-94AC-A531E6DF2591}.ReleaseSigned|Any CPU.ActiveCfg = ReleaseSigned|Any CPU
- {6908BDCE-D925-43F3-94AC-A531E6DF2591}.ReleaseSigned|Any CPU.Build.0 = ReleaseSigned|Any CPU
- {DD01ED24-3750-4567-9A23-1DB676A15610}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {DD01ED24-3750-4567-9A23-1DB676A15610}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {DD01ED24-3750-4567-9A23-1DB676A15610}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {DD01ED24-3750-4567-9A23-1DB676A15610}.Release|Any CPU.Build.0 = Release|Any CPU
- {DD01ED24-3750-4567-9A23-1DB676A15610}.ReleaseSigned|Any CPU.ActiveCfg = ReleaseSigned|Any CPU
- {DD01ED24-3750-4567-9A23-1DB676A15610}.ReleaseSigned|Any CPU.Build.0 = ReleaseSigned|Any CPU
- {A31F5FB2-4FF3-432A-B35B-5CD203606311}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {A31F5FB2-4FF3-432A-B35B-5CD203606311}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {A31F5FB2-4FF3-432A-B35B-5CD203606311}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {A31F5FB2-4FF3-432A-B35B-5CD203606311}.Release|Any CPU.Build.0 = Release|Any CPU
- {A31F5FB2-4FF3-432A-B35B-5CD203606311}.ReleaseSigned|Any CPU.ActiveCfg = Release|Any CPU
- {A31F5FB2-4FF3-432A-B35B-5CD203606311}.ReleaseSigned|Any CPU.Build.0 = Release|Any CPU
- {D7282E99-2DC3-405B-946F-177DB2FD2AE2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {D7282E99-2DC3-405B-946F-177DB2FD2AE2}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {D7282E99-2DC3-405B-946F-177DB2FD2AE2}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {D7282E99-2DC3-405B-946F-177DB2FD2AE2}.Release|Any CPU.Build.0 = Release|Any CPU
- {D7282E99-2DC3-405B-946F-177DB2FD2AE2}.ReleaseSigned|Any CPU.ActiveCfg = Release|Any CPU
- {D7282E99-2DC3-405B-946F-177DB2FD2AE2}.ReleaseSigned|Any CPU.Build.0 = Release|Any CPU
- {0607D1B8-80D6-4B35-9857-1263C1B32B94}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {0607D1B8-80D6-4B35-9857-1263C1B32B94}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {0607D1B8-80D6-4B35-9857-1263C1B32B94}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {0607D1B8-80D6-4B35-9857-1263C1B32B94}.Release|Any CPU.Build.0 = Release|Any CPU
- {0607D1B8-80D6-4B35-9857-1263C1B32B94}.ReleaseSigned|Any CPU.ActiveCfg = Release|Any CPU
- {0607D1B8-80D6-4B35-9857-1263C1B32B94}.ReleaseSigned|Any CPU.Build.0 = Release|Any CPU
+ {AFB63919-1E05-43B4-802A-8FB8C9B2F463}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AFB63919-1E05-43B4-802A-8FB8C9B2F463}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AFB63919-1E05-43B4-802A-8FB8C9B2F463}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AFB63919-1E05-43B4-802A-8FB8C9B2F463}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9B576380-726D-4142-8238-60A43AB0E35A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9B576380-726D-4142-8238-60A43AB0E35A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9B576380-726D-4142-8238-60A43AB0E35A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9B576380-726D-4142-8238-60A43AB0E35A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {580EB013-D3C7-4578-B845-015F4A3B0591}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {580EB013-D3C7-4578-B845-015F4A3B0591}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {580EB013-D3C7-4578-B845-015F4A3B0591}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {580EB013-D3C7-4578-B845-015F4A3B0591}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DDDC055B-E185-4181-BAB0-072F0F984569}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DDDC055B-E185-4181-BAB0-072F0F984569}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DDDC055B-E185-4181-BAB0-072F0F984569}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DDDC055B-E185-4181-BAB0-072F0F984569}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9695E08F-9829-497D-B95C-B38F28D48690}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9695E08F-9829-497D-B95C-B38F28D48690}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9695E08F-9829-497D-B95C-B38F28D48690}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9695E08F-9829-497D-B95C-B38F28D48690}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/csharp/src/Google.Protobuf/CodedInputStream.cs b/csharp/src/Google.Protobuf/CodedInputStream.cs
index 65d0e710..072e2e17 100644
--- a/csharp/src/Google.Protobuf/CodedInputStream.cs
+++ b/csharp/src/Google.Protobuf/CodedInputStream.cs
@@ -51,9 +51,15 @@ namespace Google.Protobuf
/// and <see cref="MapField{TKey, TValue}"/> to serialize such fields.
/// </para>
/// </remarks>
- public sealed class CodedInputStream
+ public sealed class CodedInputStream : IDisposable
{
/// <summary>
+ /// Whether to leave the underlying stream open when disposing of this stream.
+ /// This is always true when there's no stream.
+ /// </summary>
+ private readonly bool leaveOpen;
+
+ /// <summary>
/// Buffer of data read from the stream or provided at construction time.
/// </summary>
private readonly byte[] buffer;
@@ -115,15 +121,15 @@ namespace Google.Protobuf
/// <summary>
/// Creates a new CodedInputStream reading data from the given byte array.
/// </summary>
- public CodedInputStream(byte[] buffer) : this(null, Preconditions.CheckNotNull(buffer, "buffer"), 0, buffer.Length)
+ public CodedInputStream(byte[] buffer) : this(null, ProtoPreconditions.CheckNotNull(buffer, "buffer"), 0, buffer.Length)
{
}
/// <summary>
- /// Creates a new CodedInputStream that reads from the given byte array slice.
+ /// Creates a new <see cref="CodedInputStream"/> that reads from the given byte array slice.
/// </summary>
public CodedInputStream(byte[] buffer, int offset, int length)
- : this(null, Preconditions.CheckNotNull(buffer, "buffer"), offset, offset + length)
+ : this(null, ProtoPreconditions.CheckNotNull(buffer, "buffer"), offset, offset + length)
{
if (offset < 0 || offset > buffer.Length)
{
@@ -136,14 +142,28 @@ namespace Google.Protobuf
}
/// <summary>
- /// Creates a new CodedInputStream reading data from the given stream.
+ /// Creates a new <see cref="CodedInputStream"/> reading data from the given stream, which will be disposed
+ /// when the returned object is disposed.
/// </summary>
- public CodedInputStream(Stream input) : this(input, new byte[BufferSize], 0, 0)
+ /// <param name="input">The stream to read from.</param>
+ public CodedInputStream(Stream input) : this(input, false)
{
- Preconditions.CheckNotNull(input, "input");
}
/// <summary>
+ /// Creates a new <see cref="CodedInputStream"/> reading data from the given stream.
+ /// </summary>
+ /// <param name="input">The stream to read from.</param>
+ /// <param name="leaveOpen"><c>true</c> to leave <paramref name="input"/> open when the returned
+ /// <c cref="CodedInputStream"/> is disposed; <c>false</c> to dispose of the given stream when the
+ /// returned object is disposed.</param>
+ public CodedInputStream(Stream input, bool leaveOpen)
+ : this(ProtoPreconditions.CheckNotNull(input, "input"), new byte[BufferSize], 0, 0)
+ {
+ this.leaveOpen = leaveOpen;
+ }
+
+ /// <summary>
/// Creates a new CodedInputStream reading data from the given
/// stream and buffer, using the default limits.
/// </summary>
@@ -246,6 +266,22 @@ namespace Google.Protobuf
/// </value>
public int RecursionLimit { get { return recursionLimit; } }
+ /// <summary>
+ /// Disposes of this instance, potentially closing any underlying stream.
+ /// </summary>
+ /// <remarks>
+ /// As there is no flushing to perform here, disposing of a <see cref="CodedInputStream"/> which
+ /// was constructed with the <c>leaveOpen</c> option parameter set to <c>true</c> (or one which
+ /// was constructed to read from a byte array) has no effect.
+ /// </remarks>
+ public void Dispose()
+ {
+ if (!leaveOpen)
+ {
+ input.Dispose();
+ }
+ }
+
#region Validation
/// <summary>
/// Verifies that the last call to ReadTag() returned tag 0 - in other words,
@@ -349,6 +385,14 @@ namespace Google.Protobuf
/// This should be called directly after <see cref="ReadTag"/>, when
/// the caller wishes to skip an unknown field.
/// </summary>
+ /// <remarks>
+ /// This method throws <see cref="InvalidProtocolBufferException"/> if the last-read tag was an end-group tag.
+ /// If a caller wishes to skip a group, they should skip the whole group, by calling this method after reading the
+ /// start-group tag. This behavior allows callers to call this method on any field they don't understand, correctly
+ /// resulting in an error if an end-group tag has not been paired with an earlier start-group tag.
+ /// </remarks>
+ /// <exception cref="InvalidProtocolBufferException">The last tag was an end-group tag</exception>
+ /// <exception cref="InvalidOperationException">The last read operation read to the end of the logical stream</exception>
public void SkipLastField()
{
if (lastTag == 0)
@@ -358,11 +402,11 @@ namespace Google.Protobuf
switch (WireFormat.GetTagWireType(lastTag))
{
case WireFormat.WireType.StartGroup:
- SkipGroup();
+ SkipGroup(lastTag);
break;
case WireFormat.WireType.EndGroup:
- // Just ignore; there's no data following the tag.
- break;
+ throw new InvalidProtocolBufferException(
+ "SkipLastField called on an end-group tag, indicating that the corresponding start-group was missing");
case WireFormat.WireType.Fixed32:
ReadFixed32();
break;
@@ -379,7 +423,7 @@ namespace Google.Protobuf
}
}
- private void SkipGroup()
+ private void SkipGroup(uint startGroupTag)
{
// Note: Currently we expect this to be the way that groups are read. We could put the recursion
// depth changes into the ReadTag method instead, potentially...
@@ -389,16 +433,28 @@ namespace Google.Protobuf
throw InvalidProtocolBufferException.RecursionLimitExceeded();
}
uint tag;
- do
+ while (true)
{
tag = ReadTag();
if (tag == 0)
{
throw InvalidProtocolBufferException.TruncatedMessage();
}
+ // Can't call SkipLastField for this case- that would throw.
+ if (WireFormat.GetTagWireType(tag) == WireFormat.WireType.EndGroup)
+ {
+ break;
+ }
// This recursion will allow us to handle nested groups.
SkipLastField();
- } while (WireFormat.GetTagWireType(tag) != WireFormat.WireType.EndGroup);
+ }
+ int startField = WireFormat.GetTagFieldNumber(startGroupTag);
+ int endField = WireFormat.GetTagFieldNumber(tag);
+ if (startField != endField)
+ {
+ throw new InvalidProtocolBufferException(
+ $"Mismatched end-group tag. Started with field {startField}; ended with field {endField}");
+ }
recursionDepth--;
}
@@ -556,9 +612,7 @@ namespace Google.Protobuf
}
/// <summary>
- /// Reads an enum field value from the stream. If the enum is valid for type T,
- /// then the ref value is set and it returns true. Otherwise the unknown output
- /// value is set and this method returns false.
+ /// Reads an enum field value from the stream.
/// </summary>
public int ReadEnum()
{
diff --git a/csharp/src/Google.Protobuf/CodedOutputStream.cs b/csharp/src/Google.Protobuf/CodedOutputStream.cs
index d6355f03..6211aac3 100644
--- a/csharp/src/Google.Protobuf/CodedOutputStream.cs
+++ b/csharp/src/Google.Protobuf/CodedOutputStream.cs
@@ -55,7 +55,7 @@ namespace Google.Protobuf
/// and <c>MapField&lt;TKey, TValue&gt;</c> to serialize such fields.
/// </para>
/// </remarks>
- public sealed partial class CodedOutputStream
+ public sealed partial class CodedOutputStream : IDisposable
{
// "Local" copy of Encoding.UTF8, for efficiency. (Yes, it makes a difference.)
internal static readonly Encoding Utf8Encoding = Encoding.UTF8;
@@ -65,6 +65,7 @@ namespace Google.Protobuf
/// </summary>
public static readonly int DefaultBufferSize = 4096;
+ private readonly bool leaveOpen;
private readonly byte[] buffer;
private readonly int limit;
private int position;
@@ -91,20 +92,44 @@ namespace Google.Protobuf
this.buffer = buffer;
this.position = offset;
this.limit = offset + length;
+ leaveOpen = true; // Simple way of avoiding trying to dispose of a null reference
}
- private CodedOutputStream(Stream output, byte[] buffer)
+ private CodedOutputStream(Stream output, byte[] buffer, bool leaveOpen)
{
- this.output = output;
+ this.output = ProtoPreconditions.CheckNotNull(output, nameof(output));
this.buffer = buffer;
this.position = 0;
this.limit = buffer.Length;
+ this.leaveOpen = leaveOpen;
+ }
+
+ /// <summary>
+ /// Creates a new <see cref="CodedOutputStream" /> which write to the given stream, and disposes of that
+ /// stream when the returned <c>CodedOutputStream</c> is disposed.
+ /// </summary>
+ /// <param name="output">The stream to write to. It will be disposed when the returned <c>CodedOutputStream is disposed.</c></param>
+ public CodedOutputStream(Stream output) : this(output, DefaultBufferSize, false)
+ {
+ }
+
+ /// <summary>
+ /// Creates a new CodedOutputStream which write to the given stream and uses
+ /// the specified buffer size.
+ /// </summary>
+ /// <param name="output">The stream to write to. It will be disposed when the returned <c>CodedOutputStream is disposed.</c></param>
+ /// <param name="bufferSize">The size of buffer to use internally.</param>
+ public CodedOutputStream(Stream output, int bufferSize) : this(output, new byte[bufferSize], false)
+ {
}
/// <summary>
/// Creates a new CodedOutputStream which write to the given stream.
/// </summary>
- public CodedOutputStream(Stream output) : this(output, DefaultBufferSize)
+ /// <param name="output">The stream to write to.</param>
+ /// <param name="leaveOpen">If <c>true</c>, <paramref name="output"/> is left open when the returned <c>CodedOutputStream</c> is disposed;
+ /// if <c>false</c>, the provided stream is disposed as well.</param>
+ public CodedOutputStream(Stream output, bool leaveOpen) : this(output, DefaultBufferSize, leaveOpen)
{
}
@@ -112,9 +137,13 @@ namespace Google.Protobuf
/// Creates a new CodedOutputStream which write to the given stream and uses
/// the specified buffer size.
/// </summary>
- public CodedOutputStream(Stream output, int bufferSize) : this(output, new byte[bufferSize])
+ /// <param name="output">The stream to write to.</param>
+ /// <param name="bufferSize">The size of buffer to use internally.</param>
+ /// <param name="leaveOpen">If <c>true</c>, <paramref name="output"/> is left open when the returned <c>CodedOutputStream</c> is disposed;
+ /// if <c>false</c>, the provided stream is disposed as well.</param>
+ public CodedOutputStream(Stream output, int bufferSize, bool leaveOpen) : this(output, new byte[bufferSize], leaveOpen)
{
- }
+ }
#endregion
/// <summary>
@@ -660,6 +689,30 @@ namespace Google.Protobuf
}
/// <summary>
+ /// Flushes any buffered data and optionally closes the underlying stream, if any.
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// By default, any underlying stream is closed by this method. To configure this behaviour,
+ /// use a constructor overload with a <c>leaveOpen</c> parameter. If this instance does not
+ /// have an underlying stream, this method does nothing.
+ /// </para>
+ /// <para>
+ /// For the sake of efficiency, calling this method does not prevent future write calls - but
+ /// if a later write ends up writing to a stream which has been disposed, that is likely to
+ /// fail. It is recommend that you not call any other methods after this.
+ /// </para>
+ /// </remarks>
+ public void Dispose()
+ {
+ Flush();
+ if (!leaveOpen)
+ {
+ output.Dispose();
+ }
+ }
+
+ /// <summary>
/// Flushes any buffered data to the underlying stream (if there is one).
/// </summary>
public void Flush()
@@ -705,4 +758,4 @@ namespace Google.Protobuf
}
}
}
-} \ No newline at end of file
+}
diff --git a/csharp/src/Google.Protobuf/Collections/MapField.cs b/csharp/src/Google.Protobuf/Collections/MapField.cs
index c0ed28ae..537ce261 100644
--- a/csharp/src/Google.Protobuf/Collections/MapField.cs
+++ b/csharp/src/Google.Protobuf/Collections/MapField.cs
@@ -30,13 +30,13 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
+using Google.Protobuf.Compatibility;
using Google.Protobuf.Reflection;
using System;
using System.Collections;
using System.Collections.Generic;
+using System.IO;
using System.Linq;
-using System.Text;
-using Google.Protobuf.Compatibility;
namespace Google.Protobuf.Collections
{
@@ -47,49 +47,33 @@ namespace Google.Protobuf.Collections
/// <typeparam name="TValue">Value type in the map. Must be a type supported by Protocol Buffers.</typeparam>
/// <remarks>
/// <para>
- /// This implementation preserves insertion order for simplicity of testing
- /// code using maps fields. Overwriting an existing entry does not change the
- /// position of that entry within the map. Equality is not order-sensitive.
/// For string keys, the equality comparison is provided by <see cref="StringComparer.Ordinal" />.
/// </para>
/// <para>
+ /// Null values are not permitted in the map, either for wrapper types or regular messages.
+ /// If a map is deserialized from a data stream and the value is missing from an entry, a default value
+ /// is created instead. For primitive types, that is the regular default value (0, the empty string and so
+ /// on); for message types, an empty instance of the message is created, as if the map entry contained a 0-length
+ /// encoded value for the field.
+ /// </para>
+ /// <para>
/// This implementation does not generally prohibit the use of key/value types which are not
/// supported by Protocol Buffers (e.g. using a key type of <code>byte</code>) but nor does it guarantee
/// that all operations will work in such cases.
/// </para>
+ /// <para>
+ /// The order in which entries are returned when iterating over this object is undefined, and may change
+ /// in future versions.
+ /// </para>
/// </remarks>
public sealed class MapField<TKey, TValue> : IDeepCloneable<MapField<TKey, TValue>>, IDictionary<TKey, TValue>, IEquatable<MapField<TKey, TValue>>, IDictionary
{
// TODO: Don't create the map/list until we have an entry. (Assume many maps will be empty.)
- private readonly bool allowNullValues;
private readonly Dictionary<TKey, LinkedListNode<KeyValuePair<TKey, TValue>>> map =
new Dictionary<TKey, LinkedListNode<KeyValuePair<TKey, TValue>>>();
private readonly LinkedList<KeyValuePair<TKey, TValue>> list = new LinkedList<KeyValuePair<TKey, TValue>>();
/// <summary>
- /// Constructs a new map field, defaulting the value nullability to only allow null values for message types
- /// and non-nullable value types.
- /// </summary>
- public MapField() : this(typeof(IMessage).IsAssignableFrom(typeof(TValue)) || Nullable.GetUnderlyingType(typeof(TValue)) != null)
- {
- }
-
- /// <summary>
- /// Constructs a new map field, overriding the choice of whether null values are permitted in the map.
- /// This is used by wrapper types, where maps with string and bytes wrappers as the value types
- /// support null values.
- /// </summary>
- /// <param name="allowNullValues">Whether null values are permitted in the map or not.</param>
- public MapField(bool allowNullValues)
- {
- if (allowNullValues && typeof(TValue).IsValueType() && Nullable.GetUnderlyingType(typeof(TValue)) == null)
- {
- throw new ArgumentException("allowNullValues", "Non-nullable value types do not support null values");
- }
- this.allowNullValues = allowNullValues;
- }
-
- /// <summary>
/// Creates a deep clone of this object.
/// </summary>
/// <returns>
@@ -97,13 +81,13 @@ namespace Google.Protobuf.Collections
/// </returns>
public MapField<TKey, TValue> Clone()
{
- var clone = new MapField<TKey, TValue>(allowNullValues);
+ var clone = new MapField<TKey, TValue>();
// Keys are never cloneable. Values might be.
if (typeof(IDeepCloneable<TValue>).IsAssignableFrom(typeof(TValue)))
{
foreach (var pair in list)
{
- clone.Add(pair.Key, pair.Value == null ? pair.Value : ((IDeepCloneable<TValue>)pair.Value).Clone());
+ clone.Add(pair.Key, ((IDeepCloneable<TValue>)pair.Value).Clone());
}
}
else
@@ -128,7 +112,7 @@ namespace Google.Protobuf.Collections
// Validation of arguments happens in ContainsKey and the indexer
if (ContainsKey(key))
{
- throw new ArgumentException("Key already exists in map", "key");
+ throw new ArgumentException("Key already exists in map", nameof(key));
}
this[key] = value;
}
@@ -140,7 +124,7 @@ namespace Google.Protobuf.Collections
/// <returns><c>true</c> if the map contains the given key; <c>false</c> otherwise.</returns>
public bool ContainsKey(TKey key)
{
- Preconditions.CheckNotNullUnconstrained(key, "key");
+ ProtoPreconditions.CheckNotNullUnconstrained(key, nameof(key));
return map.ContainsKey(key);
}
@@ -157,7 +141,7 @@ namespace Google.Protobuf.Collections
/// <returns><c>true</c> if the map contained the given key before the entry was removed; <c>false</c> otherwise.</returns>
public bool Remove(TKey key)
{
- Preconditions.CheckNotNullUnconstrained(key, "key");
+ ProtoPreconditions.CheckNotNullUnconstrained(key, nameof(key));
LinkedListNode<KeyValuePair<TKey, TValue>> node;
if (map.TryGetValue(key, out node))
{
@@ -205,7 +189,7 @@ namespace Google.Protobuf.Collections
{
get
{
- Preconditions.CheckNotNullUnconstrained(key, "key");
+ ProtoPreconditions.CheckNotNullUnconstrained(key, nameof(key));
TValue value;
if (TryGetValue(key, out value))
{
@@ -215,11 +199,11 @@ namespace Google.Protobuf.Collections
}
set
{
- Preconditions.CheckNotNullUnconstrained(key, "key");
+ ProtoPreconditions.CheckNotNullUnconstrained(key, nameof(key));
// value == null check here is redundant, but avoids boxing.
- if (value == null && !allowNullValues)
+ if (value == null)
{
- Preconditions.CheckNotNullUnconstrained(value, "value");
+ ProtoPreconditions.CheckNotNullUnconstrained(value, nameof(value));
}
LinkedListNode<KeyValuePair<TKey, TValue>> node;
var pair = new KeyValuePair<TKey, TValue>(key, value);
@@ -246,12 +230,12 @@ namespace Google.Protobuf.Collections
public ICollection<TValue> Values { get { return new MapView<TValue>(this, pair => pair.Value, ContainsValue); } }
/// <summary>
- /// Adds the specified entries to the map.
+ /// Adds the specified entries to the map. The keys and values are not automatically cloned.
/// </summary>
/// <param name="entries">The entries to add to the map.</param>
public void Add(IDictionary<TKey, TValue> entries)
{
- Preconditions.CheckNotNull(entries, "entries");
+ ProtoPreconditions.CheckNotNull(entries, nameof(entries));
foreach (var pair in entries)
{
Add(pair.Key, pair.Value);
@@ -330,7 +314,7 @@ namespace Google.Protobuf.Collections
{
if (item.Key == null)
{
- throw new ArgumentException("Key is null", "item");
+ throw new ArgumentException("Key is null", nameof(item));
}
LinkedListNode<KeyValuePair<TKey, TValue>> node;
if (map.TryGetValue(item.Key, out node) &&
@@ -347,11 +331,6 @@ namespace Google.Protobuf.Collections
}
/// <summary>
- /// Returns whether or not this map allows values to be null.
- /// </summary>
- public bool AllowsNullValues { get { return allowNullValues; } }
-
- /// <summary>
/// Gets the number of elements contained in the map.
/// </summary>
public int Count { get { return list.Count; } }
@@ -496,9 +475,9 @@ namespace Google.Protobuf.Collections
/// </summary>
public override string ToString()
{
- var builder = new StringBuilder();
- JsonFormatter.Default.WriteDictionary(builder, this);
- return builder.ToString();
+ var writer = new StringWriter();
+ JsonFormatter.Default.WriteDictionary(writer, this);
+ return writer.ToString();
}
#region IDictionary explicit interface implementation
@@ -523,7 +502,7 @@ namespace Google.Protobuf.Collections
void IDictionary.Remove(object key)
{
- Preconditions.CheckNotNull(key, "key");
+ ProtoPreconditions.CheckNotNull(key, nameof(key));
if (!(key is TKey))
{
return;
@@ -552,7 +531,7 @@ namespace Google.Protobuf.Collections
{
get
{
- Preconditions.CheckNotNull(key, "key");
+ ProtoPreconditions.CheckNotNull(key, nameof(key));
if (!(key is TKey))
{
return null;
@@ -632,6 +611,8 @@ namespace Google.Protobuf.Collections
/// </summary>
internal class MessageAdapter : IMessage
{
+ private static readonly byte[] ZeroLengthMessageStreamData = new byte[] { 0 };
+
private readonly Codec codec;
internal TKey Key { get; set; }
internal TValue Value { get; set; }
@@ -665,6 +646,13 @@ namespace Google.Protobuf.Collections
input.SkipLastField();
}
}
+
+ // Corner case: a map entry with a key but no value, where the value type is a message.
+ // Read it as if we'd seen an input stream with no data (i.e. create a "default" message).
+ if (Value == null)
+ {
+ Value = codec.valueCodec.Read(new CodedInputStream(ZeroLengthMessageStreamData));
+ }
}
public void WriteTo(CodedOutputStream output)
@@ -725,11 +713,11 @@ namespace Google.Protobuf.Collections
{
if (arrayIndex < 0)
{
- throw new ArgumentOutOfRangeException("arrayIndex");
+ throw new ArgumentOutOfRangeException(nameof(arrayIndex));
}
if (arrayIndex + Count >= array.Length)
{
- throw new ArgumentException("Not enough space in the array", "array");
+ throw new ArgumentException("Not enough space in the array", nameof(array));
}
foreach (var item in this)
{
@@ -756,11 +744,11 @@ namespace Google.Protobuf.Collections
{
if (index < 0)
{
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
}
if (index + Count >= array.Length)
{
- throw new ArgumentException("Not enough space in the array", "array");
+ throw new ArgumentException("Not enough space in the array", nameof(array));
}
foreach (var item in this)
{
diff --git a/csharp/src/Google.Protobuf/Collections/RepeatedField.cs b/csharp/src/Google.Protobuf/Collections/RepeatedField.cs
index e3f65afe..7bb56448 100644
--- a/csharp/src/Google.Protobuf/Collections/RepeatedField.cs
+++ b/csharp/src/Google.Protobuf/Collections/RepeatedField.cs
@@ -33,8 +33,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
-using System.Text;
-using Google.Protobuf.Compatibility;
+using System.IO;
namespace Google.Protobuf.Collections
{
@@ -96,8 +95,8 @@ namespace Google.Protobuf.Collections
// iteration.
uint tag = input.LastTag;
var reader = codec.ValueReader;
- // Value types can be packed or not.
- if (typeof(T).IsValueType() && WireFormat.GetTagWireType(tag) == WireFormat.WireType.LengthDelimited)
+ // Non-nullable value types can be packed or not.
+ if (FieldCodec<T>.IsPackedRepeatedField(tag))
{
int length = input.ReadLength();
if (length > 0)
@@ -134,7 +133,7 @@ namespace Google.Protobuf.Collections
return 0;
}
uint tag = codec.Tag;
- if (typeof(T).IsValueType() && WireFormat.GetTagWireType(tag) == WireFormat.WireType.LengthDelimited)
+ if (codec.PackedRepeatedField)
{
int dataSize = CalculatePackedDataSize(codec);
return CodedOutputStream.ComputeRawVarint32Size(tag) +
@@ -186,7 +185,7 @@ namespace Google.Protobuf.Collections
}
var writer = codec.ValueWriter;
var tag = codec.Tag;
- if (typeof(T).IsValueType() && WireFormat.GetTagWireType(tag) == WireFormat.WireType.LengthDelimited)
+ if (codec.PackedRepeatedField)
{
// Packed primitive type
uint size = (uint)CalculatePackedDataSize(codec);
@@ -227,10 +226,7 @@ namespace Google.Protobuf.Collections
/// <param name="item">The item to add.</param>
public void Add(T item)
{
- if (item == null)
- {
- throw new ArgumentNullException("item");
- }
+ ProtoPreconditions.CheckNotNullUnconstrained(item, nameof(item));
EnsureSize(count + 1);
array[count++] = item;
}
@@ -285,46 +281,82 @@ namespace Google.Protobuf.Collections
/// <summary>
/// Gets the number of elements contained in the collection.
/// </summary>
- public int Count { get { return count; } }
+ public int Count => count;
/// <summary>
/// Gets a value indicating whether the collection is read-only.
/// </summary>
- public bool IsReadOnly { get { return false; } }
-
- // TODO: Remove this overload and just handle it in the one below, at execution time?
+ public bool IsReadOnly => false;
/// <summary>
/// Adds all of the specified values into this collection.
/// </summary>
/// <param name="values">The values to add to this collection.</param>
- public void Add(RepeatedField<T> values)
+ public void AddRange(IEnumerable<T> values)
{
- if (values == null)
+ ProtoPreconditions.CheckNotNull(values, nameof(values));
+
+ // Optimization 1: If the collection we're adding is already a RepeatedField<T>,
+ // we know the values are valid.
+ var otherRepeatedField = values as RepeatedField<T>;
+ if (otherRepeatedField != null)
{
- throw new ArgumentNullException("values");
+ EnsureSize(count + otherRepeatedField.count);
+ Array.Copy(otherRepeatedField.array, 0, array, count, otherRepeatedField.count);
+ count += otherRepeatedField.count;
+ return;
+ }
+
+ // Optimization 2: The collection is an ICollection, so we can expand
+ // just once and ask the collection to copy itself into the array.
+ var collection = values as ICollection;
+ if (collection != null)
+ {
+ var extraCount = collection.Count;
+ // For reference types and nullable value types, we need to check that there are no nulls
+ // present. (This isn't a thread-safe approach, but we don't advertise this is thread-safe.)
+ // We expect the JITter to optimize this test to true/false, so it's effectively conditional
+ // specialization.
+ if (default(T) == null)
+ {
+ // TODO: Measure whether iterating once to check and then letting the collection copy
+ // itself is faster or slower than iterating and adding as we go. For large
+ // collections this will not be great in terms of cache usage... but the optimized
+ // copy may be significantly faster than doing it one at a time.
+ foreach (var item in collection)
+ {
+ if (item == null)
+ {
+ throw new ArgumentException("Sequence contained null element", nameof(values));
+ }
+ }
+ }
+ EnsureSize(count + extraCount);
+ collection.CopyTo(array, count);
+ count += extraCount;
+ return;
+ }
+
+ // We *could* check for ICollection<T> as well, but very very few collections implement
+ // ICollection<T> but not ICollection. (HashSet<T> does, for one...)
+
+ // Fall back to a slower path of adding items one at a time.
+ foreach (T item in values)
+ {
+ Add(item);
}
- EnsureSize(count + values.count);
- // We know that all the values will be valid, because it's a RepeatedField.
- Array.Copy(values.array, 0, array, count, values.count);
- count += values.count;
}
/// <summary>
- /// Adds all of the specified values into this collection.
+ /// Adds all of the specified values into this collection. This method is present to
+ /// allow repeated fields to be constructed from queries within collection initializers.
+ /// Within non-collection-initializer code, consider using the equivalent <see cref="AddRange"/>
+ /// method instead for clarity.
/// </summary>
/// <param name="values">The values to add to this collection.</param>
public void Add(IEnumerable<T> values)
{
- if (values == null)
- {
- throw new ArgumentNullException("values");
- }
- // TODO: Check for ICollection and get the Count, to optimize?
- foreach (T item in values)
- {
- Add(item);
- }
+ AddRange(values);
}
/// <summary>
@@ -418,10 +450,7 @@ namespace Google.Protobuf.Collections
/// <returns>The zero-based index of the item, or -1 if it is not found.</returns>
public int IndexOf(T item)
{
- if (item == null)
- {
- throw new ArgumentNullException("item");
- }
+ ProtoPreconditions.CheckNotNullUnconstrained(item, nameof(item));
EqualityComparer<T> comparer = EqualityComparer<T>.Default;
for (int i = 0; i < count; i++)
{
@@ -440,13 +469,10 @@ namespace Google.Protobuf.Collections
/// <param name="item">The item to insert.</param>
public void Insert(int index, T item)
{
- if (item == null)
- {
- throw new ArgumentNullException("item");
- }
+ ProtoPreconditions.CheckNotNullUnconstrained(item, nameof(item));
if (index < 0 || index > count)
{
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
}
EnsureSize(count + 1);
Array.Copy(array, index, array, index + 1, count - index);
@@ -462,7 +488,7 @@ namespace Google.Protobuf.Collections
{
if (index < 0 || index >= count)
{
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
}
Array.Copy(array, index + 1, array, index, count - index - 1);
count--;
@@ -475,9 +501,9 @@ namespace Google.Protobuf.Collections
/// </summary>
public override string ToString()
{
- var builder = new StringBuilder();
- JsonFormatter.Default.WriteList(builder, this);
- return builder.ToString();
+ var writer = new StringWriter();
+ JsonFormatter.Default.WriteList(writer, this);
+ return writer.ToString();
}
/// <summary>
@@ -494,7 +520,7 @@ namespace Google.Protobuf.Collections
{
if (index < 0 || index >= count)
{
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
}
return array[index];
}
@@ -502,27 +528,24 @@ namespace Google.Protobuf.Collections
{
if (index < 0 || index >= count)
{
- throw new ArgumentOutOfRangeException("index");
- }
- if (value == null)
- {
- throw new ArgumentNullException("value");
+ throw new ArgumentOutOfRangeException(nameof(index));
}
+ ProtoPreconditions.CheckNotNullUnconstrained(value, nameof(value));
array[index] = value;
}
}
#region Explicit interface implementation for IList and ICollection.
- bool IList.IsFixedSize { get { return false; } }
+ bool IList.IsFixedSize => false;
void ICollection.CopyTo(Array array, int index)
{
Array.Copy(this.array, 0, array, index, count);
}
- bool ICollection.IsSynchronized { get { return false; } }
+ bool ICollection.IsSynchronized => false;
- object ICollection.SyncRoot { get { return this; } }
+ object ICollection.SyncRoot => this;
object IList.this[int index]
{
diff --git a/csharp/src/Google.Protobuf/Compatibility/PropertyInfoExtensions.cs b/csharp/src/Google.Protobuf/Compatibility/PropertyInfoExtensions.cs
index 8a6fefa7..e3914dd3 100644
--- a/csharp/src/Google.Protobuf/Compatibility/PropertyInfoExtensions.cs
+++ b/csharp/src/Google.Protobuf/Compatibility/PropertyInfoExtensions.cs
@@ -47,7 +47,11 @@ namespace Google.Protobuf.Compatibility
/// </summary>
internal static MethodInfo GetGetMethod(this PropertyInfo target)
{
+#if DOTNET35
+ var method = target.GetGetMethod();
+#else
var method = target.GetMethod;
+#endif
return method != null && method.IsPublic ? method : null;
}
@@ -57,7 +61,11 @@ namespace Google.Protobuf.Compatibility
/// </summary>
internal static MethodInfo GetSetMethod(this PropertyInfo target)
{
+#if DOTNET35
+ var method = target.GetSetMethod();
+#else
var method = target.SetMethod;
+#endif
return method != null && method.IsPublic ? method : null;
}
}
diff --git a/csharp/src/Google.Protobuf/Compatibility/TypeExtensions.cs b/csharp/src/Google.Protobuf/Compatibility/TypeExtensions.cs
index 762a29eb..2d93183b 100644
--- a/csharp/src/Google.Protobuf/Compatibility/TypeExtensions.cs
+++ b/csharp/src/Google.Protobuf/Compatibility/TypeExtensions.cs
@@ -33,6 +33,7 @@
using System;
using System.Reflection;
+#if !DOTNET35
namespace Google.Protobuf.Compatibility
{
/// <summary>
@@ -46,15 +47,6 @@ namespace Google.Protobuf.Compatibility
internal static class TypeExtensions
{
/// <summary>
- /// Returns true if the target type is a value type, including a nullable value type or an enum, or false
- /// if it's a reference type (class, delegate, interface - including System.ValueType and System.Enum).
- /// </summary>
- internal static bool IsValueType(this Type target)
- {
- return target.GetTypeInfo().IsValueType;
- }
-
- /// <summary>
/// See https://msdn.microsoft.com/en-us/library/system.type.isassignablefrom
/// </summary>
internal static bool IsAssignableFrom(this Type target, Type c)
@@ -111,3 +103,4 @@ namespace Google.Protobuf.Compatibility
}
}
}
+#endif
diff --git a/csharp/src/Google.Protobuf/FieldCodec.cs b/csharp/src/Google.Protobuf/FieldCodec.cs
index 6ee8e2f9..c28b47e1 100644
--- a/csharp/src/Google.Protobuf/FieldCodec.cs
+++ b/csharp/src/Google.Protobuf/FieldCodec.cs
@@ -30,6 +30,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
+using Google.Protobuf.Compatibility;
using Google.Protobuf.WellKnownTypes;
using System;
using System.Collections.Generic;
@@ -329,17 +330,25 @@ namespace Google.Protobuf
}
/// <summary>
+ /// <para>
/// An encode/decode pair for a single field. This effectively encapsulates
/// all the information needed to read or write the field value from/to a coded
/// stream.
+ /// </para>
+ /// <para>
+ /// This class is public and has to be as it is used by generated code, but its public
+ /// API is very limited - just what the generated code needs to call directly.
+ /// </para>
/// </summary>
/// <remarks>
- /// This never writes default values to the stream, and is not currently designed
- /// to play well with packed arrays.
+ /// This never writes default values to the stream, and does not address "packedness"
+ /// in repeated fields itself, other than to know whether or not the field *should* be packed.
/// </remarks>
public sealed class FieldCodec<T>
{
private static readonly T DefaultDefault;
+ // Only non-nullable value types support packing. This is the simplest way of detecting that.
+ private static readonly bool TypeSupportsPacking = default(T) != null;
static FieldCodec()
{
@@ -354,80 +363,31 @@ namespace Google.Protobuf
// Otherwise it's the default value of the CLR type
}
- private static Func<T, bool> CreateDefaultValueCheck<TTmp>(Func<TTmp, bool> check)
- {
- return (Func<T, bool>)(object)check;
- }
-
- private readonly Func<CodedInputStream, T> reader;
- private readonly Action<CodedOutputStream, T> writer;
- private readonly Func<T, int> sizeCalculator;
- private readonly uint tag;
- private readonly int tagSize;
- private readonly int fixedSize;
- // Default value for this codec. Usually the same for every instance of the same type, but
- // for string/ByteString wrapper fields the codec's default value is null, whereas for
- // other string/ByteString fields it's "" or ByteString.Empty.
- private readonly T defaultValue;
+ internal static bool IsPackedRepeatedField(uint tag) =>
+ TypeSupportsPacking && WireFormat.GetTagWireType(tag) == WireFormat.WireType.LengthDelimited;
- internal FieldCodec(
- Func<CodedInputStream, T> reader,
- Action<CodedOutputStream, T> writer,
- Func<T, int> sizeCalculator,
- uint tag) : this(reader, writer, sizeCalculator, tag, DefaultDefault)
- {
- }
-
- internal FieldCodec(
- Func<CodedInputStream, T> reader,
- Action<CodedOutputStream, T> writer,
- Func<T, int> sizeCalculator,
- uint tag,
- T defaultValue)
- {
- this.reader = reader;
- this.writer = writer;
- this.sizeCalculator = sizeCalculator;
- this.fixedSize = 0;
- this.tag = tag;
- this.defaultValue = defaultValue;
- tagSize = CodedOutputStream.ComputeRawVarint32Size(tag);
- }
-
- internal FieldCodec(
- Func<CodedInputStream, T> reader,
- Action<CodedOutputStream, T> writer,
- int fixedSize,
- uint tag)
- {
- this.reader = reader;
- this.writer = writer;
- this.sizeCalculator = _ => fixedSize;
- this.fixedSize = fixedSize;
- this.tag = tag;
- tagSize = CodedOutputStream.ComputeRawVarint32Size(tag);
- }
+ internal bool PackedRepeatedField { get; }
/// <summary>
- /// Returns the size calculator for just a value.
+ /// Returns a delegate to write a value (unconditionally) to a coded output stream.
/// </summary>
- internal Func<T, int> ValueSizeCalculator { get { return sizeCalculator; } }
+ internal Action<CodedOutputStream, T> ValueWriter { get; }
/// <summary>
- /// Returns a delegate to write a value (unconditionally) to a coded output stream.
+ /// Returns the size calculator for just a value.
/// </summary>
- internal Action<CodedOutputStream, T> ValueWriter { get { return writer; } }
+ internal Func<T, int> ValueSizeCalculator { get; }
/// <summary>
/// Returns a delegate to read a value from a coded input stream. It is assumed that
/// the stream is already positioned on the appropriate tag.
/// </summary>
- internal Func<CodedInputStream, T> ValueReader { get { return reader; } }
+ internal Func<CodedInputStream, T> ValueReader { get; }
/// <summary>
/// Returns the fixed size for an entry, or 0 if sizes vary.
/// </summary>
- internal int FixedSize { get { return fixedSize; } }
+ internal int FixedSize { get; }
/// <summary>
/// Gets the tag of the codec.
@@ -435,15 +395,54 @@ namespace Google.Protobuf
/// <value>
/// The tag of the codec.
/// </value>
- public uint Tag { get { return tag; } }
+ internal uint Tag { get; }
/// <summary>
- /// Gets the default value of the codec's type.
+ /// Default value for this codec. Usually the same for every instance of the same type, but
+ /// for string/ByteString wrapper fields the codec's default value is null, whereas for
+ /// other string/ByteString fields it's "" or ByteString.Empty.
/// </summary>
/// <value>
/// The default value of the codec's type.
/// </value>
- public T DefaultValue { get { return defaultValue; } }
+ internal T DefaultValue { get; }
+
+ private readonly int tagSize;
+
+ internal FieldCodec(
+ Func<CodedInputStream, T> reader,
+ Action<CodedOutputStream, T> writer,
+ int fixedSize,
+ uint tag) : this(reader, writer, _ => fixedSize, tag)
+ {
+ FixedSize = fixedSize;
+ }
+
+ internal FieldCodec(
+ Func<CodedInputStream, T> reader,
+ Action<CodedOutputStream, T> writer,
+ Func<T, int> sizeCalculator,
+ uint tag) : this(reader, writer, sizeCalculator, tag, DefaultDefault)
+ {
+ }
+
+ internal FieldCodec(
+ Func<CodedInputStream, T> reader,
+ Action<CodedOutputStream, T> writer,
+ Func<T, int> sizeCalculator,
+ uint tag,
+ T defaultValue)
+ {
+ ValueReader = reader;
+ ValueWriter = writer;
+ ValueSizeCalculator = sizeCalculator;
+ FixedSize = 0;
+ Tag = tag;
+ DefaultValue = defaultValue;
+ tagSize = CodedOutputStream.ComputeRawVarint32Size(tag);
+ // Detect packed-ness once, so we can check for it within RepeatedField<T>.
+ PackedRepeatedField = IsPackedRepeatedField(tag);
+ }
/// <summary>
/// Write a tag and the given value, *if* the value is not the default.
@@ -452,8 +451,8 @@ namespace Google.Protobuf
{
if (!IsDefault(value))
{
- output.WriteTag(tag);
- writer(output, value);
+ output.WriteTag(Tag);
+ ValueWriter(output, value);
}
}
@@ -462,23 +461,14 @@ namespace Google.Protobuf
/// </summary>
/// <param name="input">The input stream to read from.</param>
/// <returns>The value read from the stream.</returns>
- public T Read(CodedInputStream input)
- {
- return reader(input);
- }
+ public T Read(CodedInputStream input) => ValueReader(input);
/// <summary>
/// Calculates the size required to write the given value, with a tag,
/// if the value is not the default.
/// </summary>
- public int CalculateSizeWithTag(T value)
- {
- return IsDefault(value) ? 0 : sizeCalculator(value) + tagSize;
- }
+ public int CalculateSizeWithTag(T value) => IsDefault(value) ? 0 : ValueSizeCalculator(value) + tagSize;
- private bool IsDefault(T value)
- {
- return EqualityComparer<T>.Default.Equals(value, defaultValue);
- }
+ private bool IsDefault(T value) => EqualityComparer<T>.Default.Equals(value, DefaultValue);
}
}
diff --git a/csharp/src/Google.Protobuf/Google.Protobuf.csproj b/csharp/src/Google.Protobuf/Google.Protobuf.csproj
deleted file mode 100644
index 36807b82..00000000
--- a/csharp/src/Google.Protobuf/Google.Protobuf.csproj
+++ /dev/null
@@ -1,155 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ProductVersion>9.0.30729</ProductVersion>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{6908BDCE-D925-43F3-94AC-A531E6DF2591}</ProjectGuid>
- <OutputType>Library</OutputType>
- <AppDesignerFolder>Properties</AppDesignerFolder>
- <RootNamespace>Google.Protobuf</RootNamespace>
- <AssemblyName>Google.Protobuf</AssemblyName>
- <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
- <TargetFrameworkProfile>Profile259</TargetFrameworkProfile>
- <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
- <FileAlignment>512</FileAlignment>
- <OldToolsVersion>3.5</OldToolsVersion>
- <MinimumVisualStudioVersion>10.0</MinimumVisualStudioVersion>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <DebugSymbols>true</DebugSymbols>
- <DebugType>full</DebugType>
- <Optimize>false</Optimize>
- <OutputPath>bin\Debug</OutputPath>
- <IntermediateOutputPath>obj\Debug\</IntermediateOutputPath>
- <DocumentationFile>bin\Debug\Google.Protobuf.xml</DocumentationFile>
- <NoWarn>
- </NoWarn>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- <NoStdLib>true</NoStdLib>
- <GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
- <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <DebugType>pdbonly</DebugType>
- <Optimize>true</Optimize>
- <OutputPath>bin\Release</OutputPath>
- <IntermediateOutputPath>obj\Release\</IntermediateOutputPath>
- <DocumentationFile>$(OutputPath)\$(AssemblyName).xml</DocumentationFile>
- <NoWarn>
- </NoWarn>
- <DefineConstants>TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- <NoStdLib>true</NoStdLib>
- <GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
- <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseSigned|AnyCPU' ">
- <DebugType>pdbonly</DebugType>
- <Optimize>true</Optimize>
- <OutputPath>bin\ReleaseSigned</OutputPath>
- <IntermediateOutputPath>obj\ReleaseSigned\</IntermediateOutputPath>
- <DocumentationFile>$(OutputPath)\$(AssemblyName).xml</DocumentationFile>
- <NoWarn>
- </NoWarn>
- <DefineConstants>TRACE;SIGNED</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- <NoStdLib>true</NoStdLib>
- <GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
- <SignAssembly>True</SignAssembly>
- <AssemblyOriginatorKeyFile>C:\keys\Google.Protobuf.snk</AssemblyOriginatorKeyFile>
- <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
- </PropertyGroup>
- <ItemGroup>
- <Reference Include="mscorlib" />
- <Reference Include="System" />
- <Reference Include="System.Xml" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="ByteArray.cs" />
- <Compile Include="ByteString.cs" />
- <Compile Include="CodedOutputStream.ComputeSize.cs" />
- <Compile Include="CodedInputStream.cs" />
- <Compile Include="CodedOutputStream.cs" />
- <Compile Include="Collections\MapField.cs" />
- <Compile Include="Collections\ReadOnlyDictionary.cs" />
- <Compile Include="Collections\RepeatedField.cs" />
- <Compile Include="Compatibility\PropertyInfoExtensions.cs" />
- <Compile Include="Compatibility\TypeExtensions.cs" />
- <Compile Include="FieldCodec.cs" />
- <Compile Include="FrameworkPortability.cs" />
- <Compile Include="IDeepCloneable.cs" />
- <Compile Include="InvalidJsonException.cs" />
- <Compile Include="JsonFormatter.cs" />
- <Compile Include="JsonParser.cs" />
- <Compile Include="JsonToken.cs" />
- <Compile Include="JsonTokenizer.cs" />
- <Compile Include="MessageExtensions.cs" />
- <Compile Include="IMessage.cs" />
- <Compile Include="InvalidProtocolBufferException.cs" />
- <Compile Include="LimitedInputStream.cs" />
- <Compile Include="MessageParser.cs" />
- <Compile Include="Properties\AssemblyInfo.cs" />
- <Compile Include="Reflection\Descriptor.cs" />
- <Compile Include="Reflection\DescriptorBase.cs" />
- <Compile Include="Reflection\DescriptorPool.cs" />
- <Compile Include="Reflection\DescriptorUtil.cs" />
- <Compile Include="Reflection\DescriptorValidationException.cs" />
- <Compile Include="Reflection\EnumDescriptor.cs" />
- <Compile Include="Reflection\EnumValueDescriptor.cs" />
- <Compile Include="Reflection\FieldAccessorBase.cs" />
- <Compile Include="Reflection\FieldDescriptor.cs" />
- <Compile Include="Reflection\FieldType.cs" />
- <Compile Include="Reflection\FileDescriptor.cs" />
- <Compile Include="Reflection\GeneratedCodeInfo.cs" />
- <Compile Include="Reflection\IDescriptor.cs" />
- <Compile Include="Reflection\IFieldAccessor.cs" />
- <Compile Include="Reflection\MapFieldAccessor.cs" />
- <Compile Include="Reflection\MessageDescriptor.cs" />
- <Compile Include="Reflection\MethodDescriptor.cs" />
- <Compile Include="Reflection\OneofAccessor.cs" />
- <Compile Include="Reflection\OneofDescriptor.cs" />
- <Compile Include="Reflection\PackageDescriptor.cs" />
- <Compile Include="Reflection\PartialClasses.cs" />
- <Compile Include="Reflection\ReflectionUtil.cs" />
- <Compile Include="Reflection\RepeatedFieldAccessor.cs" />
- <Compile Include="Reflection\ServiceDescriptor.cs" />
- <Compile Include="Reflection\SingleFieldAccessor.cs" />
- <Compile Include="Preconditions.cs" />
- <Compile Include="Reflection\TypeRegistry.cs" />
- <Compile Include="WellKnownTypes\Any.cs" />
- <Compile Include="WellKnownTypes\AnyPartial.cs" />
- <Compile Include="WellKnownTypes\Api.cs" />
- <Compile Include="WellKnownTypes\Duration.cs" />
- <Compile Include="WellKnownTypes\DurationPartial.cs" />
- <Compile Include="WellKnownTypes\Empty.cs" />
- <Compile Include="WellKnownTypes\FieldMask.cs" />
- <Compile Include="WellKnownTypes\SourceContext.cs" />
- <Compile Include="WellKnownTypes\Struct.cs" />
- <Compile Include="WellKnownTypes\TimeExtensions.cs" />
- <Compile Include="WellKnownTypes\Timestamp.cs" />
- <Compile Include="WellKnownTypes\TimestampPartial.cs" />
- <Compile Include="WellKnownTypes\Type.cs" />
- <Compile Include="WellKnownTypes\ValuePartial.cs" />
- <Compile Include="WellKnownTypes\Wrappers.cs" />
- <Compile Include="WellKnownTypes\WrappersPartial.cs" />
- <Compile Include="WireFormat.cs" />
- </ItemGroup>
- <ItemGroup>
- <None Include="Google.Protobuf.nuspec" />
- </ItemGroup>
- <ItemGroup />
- <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
- Other similar extension points exist, see Microsoft.Common.targets.
- <Target Name="BeforeBuild">
- </Target>
- <Target Name="AfterBuild">
- </Target>
- -->
-</Project> \ No newline at end of file
diff --git a/csharp/src/Google.Protobuf/Google.Protobuf.nuspec b/csharp/src/Google.Protobuf/Google.Protobuf.nuspec
deleted file mode 100644
index 9542138a..00000000
--- a/csharp/src/Google.Protobuf/Google.Protobuf.nuspec
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<package>
- <metadata>
- <id>Google.Protobuf</id>
- <title>Google Protocol Buffers C#</title>
- <summary>C# runtime library for Protocol Buffers - Google's data interchange format.</summary>
- <description>See project site for more info.</description>
- <version>3.0.0-alpha4</version>
- <authors>Google Inc.</authors>
- <owners>protobuf-packages</owners>
- <licenseUrl>https://github.com/google/protobuf/blob/master/LICENSE</licenseUrl>
- <projectUrl>https://github.com/google/protobuf</projectUrl>
- <requireLicenseAcceptance>false</requireLicenseAcceptance>
- <releaseNotes>C# proto3 support</releaseNotes>
- <copyright>Copyright 2015, Google Inc.</copyright>
- <tags>Protocol Buffers Binary Serialization Format Google proto proto3</tags>
- </metadata>
- <files>
- <file src="bin/ReleaseSigned/Google.Protobuf.dll" target="lib/portable-net45+netcore45+wpa81+wp8" />
- <file src="bin/ReleaseSigned/Google.Protobuf.pdb" target="lib/portable-net45+netcore45+wpa81+wp8" />
- <file src="bin/ReleaseSigned/Google.Protobuf.xml" target="lib/portable-net45+netcore45+wpa81+wp8" />
- <file src="**\*.cs" target="src" />
- <file src="..\..\..\cmake\Release\protoc.exe" target="tools" />
- <file src="..\..\..\src\google\protobuf\any.proto" target="tools\google\protobuf" />
- <file src="..\..\..\src\google\protobuf\api.proto" target="tools\google\protobuf" />
- <file src="..\..\..\src\google\protobuf\descriptor.proto" target="tools\google\protobuf" />
- <file src="..\..\..\src\google\protobuf\duration.proto" target="tools\google\protobuf" />
- <file src="..\..\..\src\google\protobuf\empty.proto" target="tools\google\protobuf" />
- <file src="..\..\..\src\google\protobuf\field_mask.proto" target="tools\google\protobuf" />
- <file src="..\..\..\src\google\protobuf\source_context.proto" target="tools\google\protobuf" />
- <file src="..\..\..\src\google\protobuf\struct.proto" target="tools\google\protobuf" />
- <file src="..\..\..\src\google\protobuf\timestamp.proto" target="tools\google\protobuf" />
- <file src="..\..\..\src\google\protobuf\any.proto" target="tools\google\protobuf" />
- <file src="..\..\..\src\google\protobuf\type.proto" target="tools\google\protobuf" />
- <file src="..\..\..\src\google\protobuf\wrappers.proto" target="tools\google\protobuf" />
- </files>
-</package>
diff --git a/csharp/src/Google.Protobuf/Google.Protobuf.xproj b/csharp/src/Google.Protobuf/Google.Protobuf.xproj
new file mode 100644
index 00000000..c68e0db3
--- /dev/null
+++ b/csharp/src/Google.Protobuf/Google.Protobuf.xproj
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
+ <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
+ </PropertyGroup>
+ <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>9b576380-726d-4142-8238-60a43ab0e35a</ProjectGuid>
+ <RootNamespace>Google.Protobuf</RootNamespace>
+ <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
+ <OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
+ </PropertyGroup>
+
+ <PropertyGroup>
+ <SchemaVersion>2.0</SchemaVersion>
+ </PropertyGroup>
+ <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
+</Project> \ No newline at end of file
diff --git a/csharp/src/Google.Protobuf/ICustomDiagnosticMessage.cs b/csharp/src/Google.Protobuf/ICustomDiagnosticMessage.cs
new file mode 100644
index 00000000..a0090569
--- /dev/null
+++ b/csharp/src/Google.Protobuf/ICustomDiagnosticMessage.cs
@@ -0,0 +1,69 @@
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2016 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.
+#endregion
+
+namespace Google.Protobuf
+{
+ /// <summary>
+ /// A message type that has a custom string format for diagnostic purposes.
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// Calling <see cref="object.ToString"/> on a generated message type normally
+ /// returns the JSON representation. If a message type implements this interface,
+ /// then the <see cref="ToDiagnosticString"/> method will be called instead of the regular
+ /// JSON formatting code, but only when <c>ToString()</c> is called either on the message itself
+ /// or on another message which contains it. This does not affect the normal JSON formatting of
+ /// the message.
+ /// </para>
+ /// <para>
+ /// For example, if you create a proto message representing a GUID, the internal
+ /// representation may be a <c>bytes</c> field or four <c>fixed32</c> fields. However, when debugging
+ /// it may be more convenient to see a result in the same format as <see cref="System.Guid"/> provides.
+ /// </para>
+ /// <para>This interface extends <see cref="IMessage"/> to avoid it accidentally being implemented
+ /// on types other than messages, where it would not be used by anything in the framework.</para>
+ /// </remarks>
+ public interface ICustomDiagnosticMessage : IMessage
+ {
+ /// <summary>
+ /// Returns a string representation of this object, for diagnostic purposes.
+ /// </summary>
+ /// <remarks>
+ /// This method is called when a message is formatted as part of a <see cref="object.ToString"/>
+ /// call. It does not affect the JSON representation used by <see cref="JsonFormatter"/> other than
+ /// in calls to <see cref="JsonFormatter.ToDiagnosticString(IMessage)"/>. While it is recommended
+ /// that the result is valid JSON, this is never assumed by the Protobuf library.
+ /// </remarks>
+ /// <returns>A string representation of this object, for diagnostic purposes.</returns>
+ string ToDiagnosticString();
+ }
+}
diff --git a/csharp/src/Google.Protobuf/InvalidProtocolBufferException.cs b/csharp/src/Google.Protobuf/InvalidProtocolBufferException.cs
index cacda648..eeb0f13a 100644
--- a/csharp/src/Google.Protobuf/InvalidProtocolBufferException.cs
+++ b/csharp/src/Google.Protobuf/InvalidProtocolBufferException.cs
@@ -30,6 +30,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
+using System;
using System.IO;
namespace Google.Protobuf
@@ -45,6 +46,11 @@ namespace Google.Protobuf
{
}
+ internal InvalidProtocolBufferException(string message, Exception innerException)
+ : base(message, innerException)
+ {
+ }
+
internal static InvalidProtocolBufferException MoreDataAvailable()
{
return new InvalidProtocolBufferException(
@@ -82,6 +88,11 @@ namespace Google.Protobuf
"Protocol message contained an invalid tag (zero).");
}
+ internal static InvalidProtocolBufferException InvalidBase64(Exception innerException)
+ {
+ return new InvalidProtocolBufferException("Invalid base64 data", innerException);
+ }
+
internal static InvalidProtocolBufferException InvalidEndTag()
{
return new InvalidProtocolBufferException(
diff --git a/csharp/src/Google.Protobuf/JsonFormatter.cs b/csharp/src/Google.Protobuf/JsonFormatter.cs
index 45941b39..d8a814d9 100644
--- a/csharp/src/Google.Protobuf/JsonFormatter.cs
+++ b/csharp/src/Google.Protobuf/JsonFormatter.cs
@@ -36,7 +36,10 @@ using System.Globalization;
using System.Text;
using Google.Protobuf.Reflection;
using Google.Protobuf.WellKnownTypes;
+using System.IO;
using System.Linq;
+using System.Collections.Generic;
+using System.Reflection;
namespace Google.Protobuf
{
@@ -56,17 +59,19 @@ namespace Google.Protobuf
public sealed class JsonFormatter
{
internal const string AnyTypeUrlField = "@type";
+ internal const string AnyDiagnosticValueField = "@value";
internal const string AnyWellKnownTypeValueField = "value";
private const string TypeUrlPrefix = "type.googleapis.com";
private const string NameValueSeparator = ": ";
private const string PropertySeparator = ", ";
- private static JsonFormatter defaultInstance = new JsonFormatter(Settings.Default);
-
/// <summary>
/// Returns a formatter using the default settings.
/// </summary>
- public static JsonFormatter Default { get { return defaultInstance; } }
+ public static JsonFormatter Default { get; } = new JsonFormatter(Settings.Default);
+
+ // A JSON formatter which *only* exists
+ private static readonly JsonFormatter diagnosticFormatter = new JsonFormatter(Settings.Default);
/// <summary>
/// The JSON representation of the first 160 characters of Unicode.
@@ -120,6 +125,8 @@ namespace Google.Protobuf
private readonly Settings settings;
+ private bool DiagnosticOnly => ReferenceEquals(this, diagnosticFormatter);
+
/// <summary>
/// Creates a new formatted with the given settings.
/// </summary>
@@ -136,32 +143,77 @@ namespace Google.Protobuf
/// <returns>The formatted message.</returns>
public string Format(IMessage message)
{
- Preconditions.CheckNotNull(message, nameof(message));
- StringBuilder builder = new StringBuilder();
+ var writer = new StringWriter();
+ Format(message, writer);
+ return writer.ToString();
+ }
+
+ /// <summary>
+ /// Formats the specified message as JSON.
+ /// </summary>
+ /// <param name="message">The message to format.</param>
+ /// <param name="writer">The TextWriter to write the formatted message to.</param>
+ /// <returns>The formatted message.</returns>
+ public void Format(IMessage message, TextWriter writer)
+ {
+ ProtoPreconditions.CheckNotNull(message, nameof(message));
+ ProtoPreconditions.CheckNotNull(writer, nameof(writer));
+
if (message.Descriptor.IsWellKnownType)
{
- WriteWellKnownTypeValue(builder, message.Descriptor, message, false);
+ WriteWellKnownTypeValue(writer, message.Descriptor, message);
}
else
{
- WriteMessage(builder, message);
+ WriteMessage(writer, message);
}
- return builder.ToString();
}
- private void WriteMessage(StringBuilder builder, IMessage message)
+ /// <summary>
+ /// Converts a message to JSON for diagnostic purposes with no extra context.
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// This differs from calling <see cref="Format(IMessage)"/> on the default JSON
+ /// formatter in its handling of <see cref="Any"/>. As no type registry is available
+ /// in <see cref="object.ToString"/> calls, the normal way of resolving the type of
+ /// an <c>Any</c> message cannot be applied. Instead, a JSON property named <c>@value</c>
+ /// is included with the base64 data from the <see cref="Any.Value"/> property of the message.
+ /// </para>
+ /// <para>The value returned by this method is only designed to be used for diagnostic
+ /// purposes. It may not be parsable by <see cref="JsonParser"/>, and may not be parsable
+ /// by other Protocol Buffer implementations.</para>
+ /// </remarks>
+ /// <param name="message">The message to format for diagnostic purposes.</param>
+ /// <returns>The diagnostic-only JSON representation of the message</returns>
+ public static string ToDiagnosticString(IMessage message)
+ {
+ ProtoPreconditions.CheckNotNull(message, nameof(message));
+ return diagnosticFormatter.Format(message);
+ }
+
+ private void WriteMessage(TextWriter writer, IMessage message)
{
if (message == null)
{
- WriteNull(builder);
+ WriteNull(writer);
return;
}
- builder.Append("{ ");
- bool writtenFields = WriteMessageFields(builder, message, false);
- builder.Append(writtenFields ? " }" : "}");
+ if (DiagnosticOnly)
+ {
+ ICustomDiagnosticMessage customDiagnosticMessage = message as ICustomDiagnosticMessage;
+ if (customDiagnosticMessage != null)
+ {
+ writer.Write(customDiagnosticMessage.ToDiagnosticString());
+ return;
+ }
+ }
+ writer.Write("{ ");
+ bool writtenFields = WriteMessageFields(writer, message, false);
+ writer.Write(writtenFields ? " }" : "}");
}
- private bool WriteMessageFields(StringBuilder builder, IMessage message, bool assumeFirstFieldWritten)
+ private bool WriteMessageFields(TextWriter writer, IMessage message, bool assumeFirstFieldWritten)
{
var fields = message.Descriptor.Fields;
bool first = !assumeFirstFieldWritten;
@@ -180,27 +232,48 @@ namespace Google.Protobuf
{
continue;
}
- // Omit awkward (single) values such as unknown enum values
- if (!field.IsRepeated && !field.IsMap && !CanWriteSingleValue(value))
- {
- continue;
- }
// Okay, all tests complete: let's write the field value...
if (!first)
{
- builder.Append(PropertySeparator);
+ writer.Write(PropertySeparator);
}
- WriteString(builder, ToCamelCase(accessor.Descriptor.Name));
- builder.Append(NameValueSeparator);
- WriteValue(builder, value);
+
+ WriteString(writer, accessor.Descriptor.JsonName);
+ writer.Write(NameValueSeparator);
+ WriteValue(writer, value);
+
first = false;
- }
+ }
return !first;
}
+ /// <summary>
+ /// Camel-case converter with added strictness for field mask formatting.
+ /// </summary>
+ /// <exception cref="InvalidOperationException">The field mask is invalid for JSON representation</exception>
+ private static string ToCamelCaseForFieldMask(string input)
+ {
+ for (int i = 0; i < input.Length; i++)
+ {
+ char c = input[i];
+ if (c >= 'A' && c <= 'Z')
+ {
+ throw new InvalidOperationException($"Invalid field mask to be converted to JSON: {input}");
+ }
+ if (c == '_' && i < input.Length - 1)
+ {
+ char next = input[i + 1];
+ if (next < 'a' || next > 'z')
+ {
+ throw new InvalidOperationException($"Invalid field mask to be converted to JSON: {input}");
+ }
+ }
+ }
+ return ToCamelCase(input);
+ }
+
// Converted from src/google/protobuf/util/internal/utility.cc ToCamelCase
- // TODO: Use the new field in FieldDescriptor.
internal static string ToCamelCase(string input)
{
bool capitalizeNext = false;
@@ -231,6 +304,7 @@ namespace Google.Protobuf
(!wasCap || (i + 1 < input.Length && char.IsLower(input[i + 1]))))
{
firstWord = false;
+ result.Append(input[i]);
}
else
{
@@ -246,15 +320,23 @@ namespace Google.Protobuf
result.Append(char.ToUpperInvariant(input[i]));
continue;
}
+ else
+ {
+ result.Append(input[i]);
+ continue;
+ }
+ }
+ else
+ {
+ result.Append(char.ToLowerInvariant(input[i]));
}
- result.Append(input[i]);
}
return result.ToString();
}
- private static void WriteNull(StringBuilder builder)
+ private static void WriteNull(TextWriter writer)
{
- builder.Append("null");
+ writer.Write("null");
}
private static bool IsDefaultValue(IFieldAccessor accessor, object value)
@@ -303,77 +385,85 @@ namespace Google.Protobuf
throw new ArgumentException("Invalid field type");
}
}
-
- private void WriteValue(StringBuilder builder, object value)
+
+ /// <summary>
+ /// Writes a single value to the given writer as JSON. Only types understood by
+ /// Protocol Buffers can be written in this way. This method is only exposed for
+ /// advanced use cases; most users should be using <see cref="Format(IMessage)"/>
+ /// or <see cref="Format(IMessage, TextWriter)"/>.
+ /// </summary>
+ /// <param name="writer">The writer to write the value to. Must not be null.</param>
+ /// <param name="value">The value to write. May be null.</param>
+ public void WriteValue(TextWriter writer, object value)
{
if (value == null)
{
- WriteNull(builder);
+ WriteNull(writer);
}
else if (value is bool)
{
- builder.Append((bool) value ? "true" : "false");
+ writer.Write((bool)value ? "true" : "false");
}
else if (value is ByteString)
{
// Nothing in Base64 needs escaping
- builder.Append('"');
- builder.Append(((ByteString) value).ToBase64());
- builder.Append('"');
+ writer.Write('"');
+ writer.Write(((ByteString)value).ToBase64());
+ writer.Write('"');
}
else if (value is string)
{
- WriteString(builder, (string) value);
+ WriteString(writer, (string)value);
}
else if (value is IDictionary)
{
- WriteDictionary(builder, (IDictionary) value);
+ WriteDictionary(writer, (IDictionary)value);
}
else if (value is IList)
{
- WriteList(builder, (IList) value);
+ WriteList(writer, (IList)value);
}
else if (value is int || value is uint)
{
IFormattable formattable = (IFormattable) value;
- builder.Append(formattable.ToString("d", CultureInfo.InvariantCulture));
+ writer.Write(formattable.ToString("d", CultureInfo.InvariantCulture));
}
else if (value is long || value is ulong)
{
- builder.Append('"');
+ writer.Write('"');
IFormattable formattable = (IFormattable) value;
- builder.Append(formattable.ToString("d", CultureInfo.InvariantCulture));
- builder.Append('"');
+ writer.Write(formattable.ToString("d", CultureInfo.InvariantCulture));
+ writer.Write('"');
}
else if (value is System.Enum)
{
- WriteString(builder, value.ToString());
+ string name = OriginalEnumValueHelper.GetOriginalName(value);
+ if (name != null)
+ {
+ WriteString(writer, name);
+ }
+ else
+ {
+ WriteValue(writer, (int)value);
+ }
}
else if (value is float || value is double)
{
string text = ((IFormattable) value).ToString("r", CultureInfo.InvariantCulture);
if (text == "NaN" || text == "Infinity" || text == "-Infinity")
{
- builder.Append('"');
- builder.Append(text);
- builder.Append('"');
+ writer.Write('"');
+ writer.Write(text);
+ writer.Write('"');
}
else
{
- builder.Append(text);
+ writer.Write(text);
}
}
else if (value is IMessage)
{
- IMessage message = (IMessage) value;
- if (message.Descriptor.IsWellKnownType)
- {
- WriteWellKnownTypeValue(builder, message.Descriptor, value, true);
- }
- else
- {
- WriteMessage(builder, (IMessage) value);
- }
+ Format((IMessage)value, writer);
}
else
{
@@ -387,13 +477,13 @@ namespace Google.Protobuf
/// values are using the embedded well-known types, in order to allow for dynamic messages
/// in the future.
/// </summary>
- private void WriteWellKnownTypeValue(StringBuilder builder, MessageDescriptor descriptor, object value, bool inField)
+ private void WriteWellKnownTypeValue(TextWriter writer, MessageDescriptor descriptor, object value)
{
// Currently, we can never actually get here, because null values are always handled by the caller. But if we *could*,
// this would do the right thing.
if (value == null)
{
- WriteNull(builder);
+ WriteNull(writer);
return;
}
// For wrapper types, the value will either be the (possibly boxed) "native" value,
@@ -408,67 +498,49 @@ namespace Google.Protobuf
var message = (IMessage) value;
value = message.Descriptor.Fields[WrappersReflection.WrapperValueFieldNumber].Accessor.GetValue(message);
}
- WriteValue(builder, value);
+ WriteValue(writer, value);
return;
}
if (descriptor.FullName == Timestamp.Descriptor.FullName)
{
- MaybeWrapInString(builder, value, WriteTimestamp, inField);
+ WriteTimestamp(writer, (IMessage)value);
return;
}
if (descriptor.FullName == Duration.Descriptor.FullName)
{
- MaybeWrapInString(builder, value, WriteDuration, inField);
+ WriteDuration(writer, (IMessage)value);
return;
}
if (descriptor.FullName == FieldMask.Descriptor.FullName)
{
- MaybeWrapInString(builder, value, WriteFieldMask, inField);
+ WriteFieldMask(writer, (IMessage)value);
return;
}
if (descriptor.FullName == Struct.Descriptor.FullName)
{
- WriteStruct(builder, (IMessage) value);
+ WriteStruct(writer, (IMessage)value);
return;
}
if (descriptor.FullName == ListValue.Descriptor.FullName)
{
var fieldAccessor = descriptor.Fields[ListValue.ValuesFieldNumber].Accessor;
- WriteList(builder, (IList) fieldAccessor.GetValue((IMessage) value));
+ WriteList(writer, (IList)fieldAccessor.GetValue((IMessage)value));
return;
}
if (descriptor.FullName == Value.Descriptor.FullName)
{
- WriteStructFieldValue(builder, (IMessage) value);
+ WriteStructFieldValue(writer, (IMessage)value);
return;
}
if (descriptor.FullName == Any.Descriptor.FullName)
{
- WriteAny(builder, (IMessage) value);
+ WriteAny(writer, (IMessage)value);
return;
}
- WriteMessage(builder, (IMessage) value);
- }
-
- /// <summary>
- /// Some well-known types end up as string values... so they need wrapping in quotes, but only
- /// when they're being used as fields within another message.
- /// </summary>
- private void MaybeWrapInString(StringBuilder builder, object value, Action<StringBuilder, IMessage> action, bool inField)
- {
- if (inField)
- {
- builder.Append('"');
- action(builder, (IMessage) value);
- builder.Append('"');
- }
- else
- {
- action(builder, (IMessage) value);
- }
+ WriteMessage(writer, (IMessage)value);
}
- private void WriteTimestamp(StringBuilder builder, IMessage value)
+ private void WriteTimestamp(TextWriter writer, IMessage value)
{
// TODO: In the common case where this *is* using the built-in Timestamp type, we could
// avoid all the reflection at this point, by casting to Timestamp. In the interests of
@@ -476,112 +548,79 @@ namespace Google.Protobuf
// it still works in that case.
int nanos = (int) value.Descriptor.Fields[Timestamp.NanosFieldNumber].Accessor.GetValue(value);
long seconds = (long) value.Descriptor.Fields[Timestamp.SecondsFieldNumber].Accessor.GetValue(value);
-
- // Even if the original message isn't using the built-in classes, we can still build one... and then
- // rely on it being normalized.
- Timestamp normalized = Timestamp.Normalize(seconds, nanos);
- // Use .NET's formatting for the value down to the second, including an opening double quote (as it's a string value)
- DateTime dateTime = normalized.ToDateTime();
- builder.Append(dateTime.ToString("yyyy'-'MM'-'dd'T'HH:mm:ss", CultureInfo.InvariantCulture));
- AppendNanoseconds(builder, Math.Abs(normalized.Nanos));
- builder.Append('Z');
+ writer.Write(Timestamp.ToJson(seconds, nanos, DiagnosticOnly));
}
- private void WriteDuration(StringBuilder builder, IMessage value)
+ private void WriteDuration(TextWriter writer, IMessage value)
{
// TODO: Same as for WriteTimestamp
int nanos = (int) value.Descriptor.Fields[Duration.NanosFieldNumber].Accessor.GetValue(value);
long seconds = (long) value.Descriptor.Fields[Duration.SecondsFieldNumber].Accessor.GetValue(value);
-
- // Even if the original message isn't using the built-in classes, we can still build one... and then
- // rely on it being normalized.
- Duration normalized = Duration.Normalize(seconds, nanos);
-
- // The seconds part will normally provide the minus sign if we need it, but not if it's 0...
- if (normalized.Seconds == 0 && normalized.Nanos < 0)
- {
- builder.Append('-');
- }
-
- builder.Append(normalized.Seconds.ToString("d", CultureInfo.InvariantCulture));
- AppendNanoseconds(builder, Math.Abs(normalized.Nanos));
- builder.Append('s');
+ writer.Write(Duration.ToJson(seconds, nanos, DiagnosticOnly));
}
- private void WriteFieldMask(StringBuilder builder, IMessage value)
+ private void WriteFieldMask(TextWriter writer, IMessage value)
{
- IList paths = (IList) value.Descriptor.Fields[FieldMask.PathsFieldNumber].Accessor.GetValue(value);
- AppendEscapedString(builder, string.Join(",", paths.Cast<string>().Select(ToCamelCase)));
+ var paths = (IList<string>) value.Descriptor.Fields[FieldMask.PathsFieldNumber].Accessor.GetValue(value);
+ writer.Write(FieldMask.ToJson(paths, DiagnosticOnly));
}
- private void WriteAny(StringBuilder builder, IMessage value)
+ private void WriteAny(TextWriter writer, IMessage value)
{
+ if (DiagnosticOnly)
+ {
+ WriteDiagnosticOnlyAny(writer, value);
+ return;
+ }
+
string typeUrl = (string) value.Descriptor.Fields[Any.TypeUrlFieldNumber].Accessor.GetValue(value);
ByteString data = (ByteString) value.Descriptor.Fields[Any.ValueFieldNumber].Accessor.GetValue(value);
- string typeName = GetTypeName(typeUrl);
+ string typeName = Any.GetTypeName(typeUrl);
MessageDescriptor descriptor = settings.TypeRegistry.Find(typeName);
if (descriptor == null)
{
throw new InvalidOperationException($"Type registry has no descriptor for type name '{typeName}'");
}
IMessage message = descriptor.Parser.ParseFrom(data);
- builder.Append("{ ");
- WriteString(builder, AnyTypeUrlField);
- builder.Append(NameValueSeparator);
- WriteString(builder, typeUrl);
+ writer.Write("{ ");
+ WriteString(writer, AnyTypeUrlField);
+ writer.Write(NameValueSeparator);
+ WriteString(writer, typeUrl);
if (descriptor.IsWellKnownType)
{
- builder.Append(PropertySeparator);
- WriteString(builder, AnyWellKnownTypeValueField);
- builder.Append(NameValueSeparator);
- WriteWellKnownTypeValue(builder, descriptor, message, true);
+ writer.Write(PropertySeparator);
+ WriteString(writer, AnyWellKnownTypeValueField);
+ writer.Write(NameValueSeparator);
+ WriteWellKnownTypeValue(writer, descriptor, message);
}
else
{
- WriteMessageFields(builder, message, true);
- }
- builder.Append(" }");
- }
-
- internal static string GetTypeName(String typeUrl)
- {
- string[] parts = typeUrl.Split('/');
- if (parts.Length != 2 || parts[0] != TypeUrlPrefix)
- {
- throw new InvalidProtocolBufferException($"Invalid type url: {typeUrl}");
+ WriteMessageFields(writer, message, true);
}
- return parts[1];
+ writer.Write(" }");
}
- /// <summary>
- /// Appends a number of nanoseconds to a StringBuilder. Either 0 digits are added (in which
- /// case no "." is appended), or 3 6 or 9 digits.
- /// </summary>
- private static void AppendNanoseconds(StringBuilder builder, int nanos)
+ private void WriteDiagnosticOnlyAny(TextWriter writer, IMessage value)
{
- if (nanos != 0)
- {
- builder.Append('.');
- // Output to 3, 6 or 9 digits.
- if (nanos % 1000000 == 0)
- {
- builder.Append((nanos / 1000000).ToString("d", CultureInfo.InvariantCulture));
- }
- else if (nanos % 1000 == 0)
- {
- builder.Append((nanos / 1000).ToString("d", CultureInfo.InvariantCulture));
- }
- else
- {
- builder.Append(nanos.ToString("d", CultureInfo.InvariantCulture));
- }
- }
- }
-
- private void WriteStruct(StringBuilder builder, IMessage message)
+ string typeUrl = (string) value.Descriptor.Fields[Any.TypeUrlFieldNumber].Accessor.GetValue(value);
+ ByteString data = (ByteString) value.Descriptor.Fields[Any.ValueFieldNumber].Accessor.GetValue(value);
+ writer.Write("{ ");
+ WriteString(writer, AnyTypeUrlField);
+ writer.Write(NameValueSeparator);
+ WriteString(writer, typeUrl);
+ writer.Write(PropertySeparator);
+ WriteString(writer, AnyDiagnosticValueField);
+ writer.Write(NameValueSeparator);
+ writer.Write('"');
+ writer.Write(data.ToBase64());
+ writer.Write('"');
+ writer.Write(" }");
+ }
+
+ private void WriteStruct(TextWriter writer, IMessage message)
{
- builder.Append("{ ");
+ writer.Write("{ ");
IDictionary fields = (IDictionary) message.Descriptor.Fields[Struct.FieldsFieldNumber].Accessor.GetValue(message);
bool first = true;
foreach (DictionaryEntry entry in fields)
@@ -595,17 +634,17 @@ namespace Google.Protobuf
if (!first)
{
- builder.Append(PropertySeparator);
+ writer.Write(PropertySeparator);
}
- WriteString(builder, key);
- builder.Append(NameValueSeparator);
- WriteStructFieldValue(builder, value);
+ WriteString(writer, key);
+ writer.Write(NameValueSeparator);
+ WriteStructFieldValue(writer, value);
first = false;
}
- builder.Append(first ? "}" : " }");
+ writer.Write(first ? "}" : " }");
}
- private void WriteStructFieldValue(StringBuilder builder, IMessage message)
+ private void WriteStructFieldValue(TextWriter writer, IMessage message)
{
var specifiedField = message.Descriptor.Oneofs[0].Accessor.GetCaseFieldDescriptor(message);
if (specifiedField == null)
@@ -620,56 +659,48 @@ namespace Google.Protobuf
case Value.BoolValueFieldNumber:
case Value.StringValueFieldNumber:
case Value.NumberValueFieldNumber:
- WriteValue(builder, value);
+ WriteValue(writer, value);
return;
case Value.StructValueFieldNumber:
case Value.ListValueFieldNumber:
// Structs and ListValues are nested messages, and already well-known types.
var nestedMessage = (IMessage) specifiedField.Accessor.GetValue(message);
- WriteWellKnownTypeValue(builder, nestedMessage.Descriptor, nestedMessage, true);
+ WriteWellKnownTypeValue(writer, nestedMessage.Descriptor, nestedMessage);
return;
case Value.NullValueFieldNumber:
- WriteNull(builder);
+ WriteNull(writer);
return;
default:
throw new InvalidOperationException("Unexpected case in struct field: " + specifiedField.FieldNumber);
}
}
- internal void WriteList(StringBuilder builder, IList list)
+ internal void WriteList(TextWriter writer, IList list)
{
- builder.Append("[ ");
+ writer.Write("[ ");
bool first = true;
foreach (var value in list)
{
- if (!CanWriteSingleValue(value))
- {
- continue;
- }
if (!first)
{
- builder.Append(PropertySeparator);
+ writer.Write(PropertySeparator);
}
- WriteValue(builder, value);
+ WriteValue(writer, value);
first = false;
}
- builder.Append(first ? "]" : " ]");
+ writer.Write(first ? "]" : " ]");
}
- internal void WriteDictionary(StringBuilder builder, IDictionary dictionary)
+ internal void WriteDictionary(TextWriter writer, IDictionary dictionary)
{
- builder.Append("{ ");
+ writer.Write("{ ");
bool first = true;
// This will box each pair. Could use IDictionaryEnumerator, but that's ugly in terms of disposal.
foreach (DictionaryEntry pair in dictionary)
{
- if (!CanWriteSingleValue(pair.Value))
- {
- continue;
- }
if (!first)
{
- builder.Append(PropertySeparator);
+ writer.Write(PropertySeparator);
}
string keyText;
if (pair.Key is string)
@@ -692,26 +723,12 @@ namespace Google.Protobuf
}
throw new ArgumentException("Unhandled dictionary key type: " + pair.Key.GetType());
}
- WriteString(builder, keyText);
- builder.Append(NameValueSeparator);
- WriteValue(builder, pair.Value);
+ WriteString(writer, keyText);
+ writer.Write(NameValueSeparator);
+ WriteValue(writer, pair.Value);
first = false;
}
- builder.Append(first ? "}" : " }");
- }
-
- /// <summary>
- /// Returns whether or not a singular value can be represented in JSON.
- /// Currently only relevant for enums, where unknown values can't be represented.
- /// For repeated/map fields, this always returns true.
- /// </summary>
- private bool CanWriteSingleValue(object value)
- {
- if (value is System.Enum)
- {
- return System.Enum.IsDefined(value.GetType(), value);
- }
- return true;
+ writer.Write(first ? "}" : " }");
}
/// <summary>
@@ -720,24 +737,15 @@ namespace Google.Protobuf
/// <remarks>
/// Other than surrogate pair handling, this code is mostly taken from src/google/protobuf/util/internal/json_escaping.cc.
/// </remarks>
- private void WriteString(StringBuilder builder, string text)
- {
- builder.Append('"');
- AppendEscapedString(builder, text);
- builder.Append('"');
- }
-
- /// <summary>
- /// Appends the given text to the string builder, escaping as required.
- /// </summary>
- private void AppendEscapedString(StringBuilder builder, string text)
+ internal static void WriteString(TextWriter writer, string text)
{
+ writer.Write('"');
for (int i = 0; i < text.Length; i++)
{
char c = text[i];
if (c < 0xa0)
{
- builder.Append(CommonRepresentations[c]);
+ writer.Write(CommonRepresentations[c]);
continue;
}
if (char.IsHighSurrogate(c))
@@ -749,8 +757,8 @@ namespace Google.Protobuf
{
throw new ArgumentException("String contains low surrogate not followed by high surrogate");
}
- HexEncodeUtf16CodeUnit(builder, c);
- HexEncodeUtf16CodeUnit(builder, text[i]);
+ HexEncodeUtf16CodeUnit(writer, c);
+ HexEncodeUtf16CodeUnit(writer, text[i]);
continue;
}
else if (char.IsLowSurrogate(c))
@@ -771,7 +779,7 @@ namespace Google.Protobuf
case 0x070f: // Syriac abbreviation mark
case 0x17b4: // Khmer vowel inherent Aq
case 0x17b5: // Khmer vowel inherent Aa
- HexEncodeUtf16CodeUnit(builder, c);
+ HexEncodeUtf16CodeUnit(writer, c);
break;
default:
@@ -781,26 +789,27 @@ namespace Google.Protobuf
(c >= 0x2060 && c <= 0x2064) || // Invisible etc.
(c >= 0x206a && c <= 0x206f))
{
- HexEncodeUtf16CodeUnit(builder, c);
+ HexEncodeUtf16CodeUnit(writer, c);
}
else
{
// No handling of surrogates here - that's done earlier
- builder.Append(c);
+ writer.Write(c);
}
break;
}
}
+ writer.Write('"');
}
private const string Hex = "0123456789abcdef";
- private static void HexEncodeUtf16CodeUnit(StringBuilder builder, char c)
+ private static void HexEncodeUtf16CodeUnit(TextWriter writer, char c)
{
- builder.Append("\\u");
- builder.Append(Hex[(c >> 12) & 0xf]);
- builder.Append(Hex[(c >> 8) & 0xf]);
- builder.Append(Hex[(c >> 4) & 0xf]);
- builder.Append(Hex[(c >> 0) & 0xf]);
+ writer.Write("\\u");
+ writer.Write(Hex[(c >> 12) & 0xf]);
+ writer.Write(Hex[(c >> 8) & 0xf]);
+ writer.Write(Hex[(c >> 4) & 0xf]);
+ writer.Write(Hex[(c >> 0) & 0xf]);
}
/// <summary>
@@ -851,8 +860,58 @@ namespace Google.Protobuf
public Settings(bool formatDefaultValues, TypeRegistry typeRegistry)
{
FormatDefaultValues = formatDefaultValues;
- TypeRegistry = Preconditions.CheckNotNull(typeRegistry, nameof(typeRegistry));
+ TypeRegistry = ProtoPreconditions.CheckNotNull(typeRegistry, nameof(typeRegistry));
}
}
+
+ // Effectively a cache of mapping from enum values to the original name as specified in the proto file,
+ // fetched by reflection.
+ // The need for this is unfortunate, as is its unbounded size, but realistically it shouldn't cause issues.
+ private static class OriginalEnumValueHelper
+ {
+ // TODO: In the future we might want to use ConcurrentDictionary, at the point where all
+ // the platforms we target have it.
+ private static readonly Dictionary<System.Type, Dictionary<object, string>> dictionaries
+ = new Dictionary<System.Type, Dictionary<object, string>>();
+
+ internal static string GetOriginalName(object value)
+ {
+ var enumType = value.GetType();
+ Dictionary<object, string> nameMapping;
+ lock (dictionaries)
+ {
+ if (!dictionaries.TryGetValue(enumType, out nameMapping))
+ {
+ nameMapping = GetNameMapping(enumType);
+ dictionaries[enumType] = nameMapping;
+ }
+ }
+
+ string originalName;
+ // If this returns false, originalName will be null, which is what we want.
+ nameMapping.TryGetValue(value, out originalName);
+ return originalName;
+ }
+
+#if DOTNET35
+ // TODO: Consider adding functionality to TypeExtensions to avoid this difference.
+ private static Dictionary<object, string> GetNameMapping(System.Type enumType) =>
+ enumType.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static)
+ .ToDictionary(f => f.GetValue(null),
+ f => (f.GetCustomAttributes(typeof(OriginalNameAttribute), false)
+ .FirstOrDefault() as OriginalNameAttribute)
+ // If the attribute hasn't been applied, fall back to the name of the field.
+ ?.Name ?? f.Name);
+#else
+ private static Dictionary<object, string> GetNameMapping(System.Type enumType) =>
+ enumType.GetTypeInfo().DeclaredFields
+ .Where(f => f.IsStatic)
+ .ToDictionary(f => f.GetValue(null),
+ f => f.GetCustomAttributes<OriginalNameAttribute>()
+ .FirstOrDefault()
+ // If the attribute hasn't been applied, fall back to the name of the field.
+ ?.Name ?? f.Name);
+#endif
+ }
}
}
diff --git a/csharp/src/Google.Protobuf/JsonParser.cs b/csharp/src/Google.Protobuf/JsonParser.cs
index 95f9ad35..6b6f2d9a 100644
--- a/csharp/src/Google.Protobuf/JsonParser.cs
+++ b/csharp/src/Google.Protobuf/JsonParser.cs
@@ -86,7 +86,8 @@ namespace Google.Protobuf
{ FloatValue.Descriptor.FullName, MergeWrapperField },
{ DoubleValue.Descriptor.FullName, MergeWrapperField },
{ BytesValue.Descriptor.FullName, MergeWrapperField },
- { StringValue.Descriptor.FullName, MergeWrapperField }
+ { StringValue.Descriptor.FullName, MergeWrapperField },
+ { BoolValue.Descriptor.FullName, MergeWrapperField }
};
// Convenience method to avoid having to repeat the same code multiple times in the above
@@ -168,6 +169,10 @@ namespace Google.Protobuf
}
var descriptor = message.Descriptor;
var jsonFieldMap = descriptor.Fields.ByJsonName();
+ // All the oneof fields we've already accounted for - we can only see each of them once.
+ // The set is created lazily to avoid the overhead of creating a set for every message
+ // we parsed, when oneofs are relatively rare.
+ HashSet<OneofDescriptor> seenOneofs = null;
while (true)
{
token = tokenizer.Next();
@@ -183,6 +188,17 @@ namespace Google.Protobuf
FieldDescriptor field;
if (jsonFieldMap.TryGetValue(name, out field))
{
+ if (field.ContainingOneof != null)
+ {
+ if (seenOneofs == null)
+ {
+ seenOneofs = new HashSet<OneofDescriptor>();
+ }
+ if (!seenOneofs.Add(field.ContainingOneof))
+ {
+ throw new InvalidProtocolBufferException($"Multiple values specified for oneof {field.ContainingOneof.Name}");
+ }
+ }
MergeField(message, field, tokenizer);
}
else
@@ -200,10 +216,15 @@ namespace Google.Protobuf
var token = tokenizer.Next();
if (token.Type == JsonToken.TokenType.Null)
{
+ // Clear the field if we see a null token, unless it's for a singular field of type
+ // google.protobuf.Value.
// Note: different from Java API, which just ignores it.
// TODO: Bring it more in line? Discuss...
- field.Accessor.Clear(message);
- return;
+ if (field.IsMap || field.IsRepeated || !IsGoogleProtobufValueField(field))
+ {
+ field.Accessor.Clear(message);
+ return;
+ }
}
tokenizer.PushBack(token);
@@ -239,6 +260,10 @@ namespace Google.Protobuf
return;
}
tokenizer.PushBack(token);
+ if (token.Type == JsonToken.TokenType.Null)
+ {
+ throw new InvalidProtocolBufferException("Repeated field elements cannot be null");
+ }
list.Add(ParseSingleValue(field, tokenizer));
}
}
@@ -270,19 +295,30 @@ namespace Google.Protobuf
}
object key = ParseMapKey(keyField, token.StringValue);
object value = ParseSingleValue(valueField, tokenizer);
- // TODO: Null handling
+ if (value == null)
+ {
+ throw new InvalidProtocolBufferException("Map values must not be null");
+ }
dictionary[key] = value;
}
}
+ private static bool IsGoogleProtobufValueField(FieldDescriptor field)
+ {
+ return field.FieldType == FieldType.Message &&
+ field.MessageType.FullName == Value.Descriptor.FullName;
+ }
+
private object ParseSingleValue(FieldDescriptor field, JsonTokenizer tokenizer)
{
var token = tokenizer.Next();
if (token.Type == JsonToken.TokenType.Null)
{
- if (field.FieldType == FieldType.Message && field.MessageType.FullName == Value.Descriptor.FullName)
+ // TODO: In order to support dynamic messages, we should really build this up
+ // dynamically.
+ if (IsGoogleProtobufValueField(field))
{
- return new Value { NullValue = NullValue.NULL_VALUE };
+ return Value.ForNull();
}
return null;
}
@@ -339,7 +375,7 @@ namespace Google.Protobuf
/// <exception cref="InvalidProtocolBufferException">The JSON does not represent a Protocol Buffers message correctly</exception>
public T Parse<T>(string json) where T : IMessage, new()
{
- Preconditions.CheckNotNull(json, nameof(json));
+ ProtoPreconditions.CheckNotNull(json, nameof(json));
return Parse<T>(new StringReader(json));
}
@@ -352,7 +388,7 @@ namespace Google.Protobuf
/// <exception cref="InvalidProtocolBufferException">The JSON does not represent a Protocol Buffers message correctly</exception>
public T Parse<T>(TextReader jsonReader) where T : IMessage, new()
{
- Preconditions.CheckNotNull(jsonReader, nameof(jsonReader));
+ ProtoPreconditions.CheckNotNull(jsonReader, nameof(jsonReader));
T message = new T();
Merge(message, jsonReader);
return message;
@@ -367,8 +403,8 @@ namespace Google.Protobuf
/// <exception cref="InvalidProtocolBufferException">The JSON does not represent a Protocol Buffers message correctly</exception>
public IMessage Parse(string json, MessageDescriptor descriptor)
{
- Preconditions.CheckNotNull(json, nameof(json));
- Preconditions.CheckNotNull(descriptor, nameof(descriptor));
+ ProtoPreconditions.CheckNotNull(json, nameof(json));
+ ProtoPreconditions.CheckNotNull(descriptor, nameof(descriptor));
return Parse(new StringReader(json), descriptor);
}
@@ -381,8 +417,8 @@ namespace Google.Protobuf
/// <exception cref="InvalidProtocolBufferException">The JSON does not represent a Protocol Buffers message correctly</exception>
public IMessage Parse(TextReader jsonReader, MessageDescriptor descriptor)
{
- Preconditions.CheckNotNull(jsonReader, nameof(jsonReader));
- Preconditions.CheckNotNull(descriptor, nameof(descriptor));
+ ProtoPreconditions.CheckNotNull(jsonReader, nameof(jsonReader));
+ ProtoPreconditions.CheckNotNull(descriptor, nameof(descriptor));
IMessage message = descriptor.Parser.CreateTemplate();
Merge(message, jsonReader);
return message;
@@ -464,6 +500,11 @@ namespace Google.Protobuf
{
tokens.Add(token);
token = tokenizer.Next();
+
+ if (tokenizer.ObjectDepth < typeUrlObjectDepth)
+ {
+ throw new InvalidProtocolBufferException("Any message with no @type");
+ }
}
// Don't add the @type property or its value to the recorded token list
@@ -473,7 +514,7 @@ namespace Google.Protobuf
throw new InvalidProtocolBufferException("Expected string value for Any.@type");
}
string typeUrl = token.StringValue;
- string typeName = JsonFormatter.GetTypeName(typeUrl);
+ string typeName = Any.GetTypeName(typeUrl);
MessageDescriptor descriptor = settings.TypeRegistry.Find(typeName);
if (descriptor == null)
@@ -540,17 +581,17 @@ namespace Google.Protobuf
case FieldType.Int32:
case FieldType.SInt32:
case FieldType.SFixed32:
- return ParseNumericString(keyText, int.Parse, false);
+ return ParseNumericString(keyText, int.Parse);
case FieldType.UInt32:
case FieldType.Fixed32:
- return ParseNumericString(keyText, uint.Parse, false);
+ return ParseNumericString(keyText, uint.Parse);
case FieldType.Int64:
case FieldType.SInt64:
case FieldType.SFixed64:
- return ParseNumericString(keyText, long.Parse, false);
+ return ParseNumericString(keyText, long.Parse);
case FieldType.UInt64:
case FieldType.Fixed64:
- return ParseNumericString(keyText, ulong.Parse, false);
+ return ParseNumericString(keyText, ulong.Parse);
default:
throw new InvalidProtocolBufferException("Invalid field type for map: " + field.FieldType);
}
@@ -561,7 +602,6 @@ namespace Google.Protobuf
double value = token.NumberValue;
checked
{
- // TODO: Validate that it's actually an integer, possibly in terms of the textual representation?
try
{
switch (field.FieldType)
@@ -569,16 +609,20 @@ namespace Google.Protobuf
case FieldType.Int32:
case FieldType.SInt32:
case FieldType.SFixed32:
+ CheckInteger(value);
return (int) value;
case FieldType.UInt32:
case FieldType.Fixed32:
+ CheckInteger(value);
return (uint) value;
case FieldType.Int64:
case FieldType.SInt64:
case FieldType.SFixed64:
+ CheckInteger(value);
return (long) value;
case FieldType.UInt64:
case FieldType.Fixed64:
+ CheckInteger(value);
return (ulong) value;
case FieldType.Double:
return value;
@@ -597,20 +641,37 @@ namespace Google.Protobuf
{
return float.NegativeInfinity;
}
- throw new InvalidProtocolBufferException("Value out of range: " + value);
+ throw new InvalidProtocolBufferException($"Value out of range: {value}");
}
return (float) value;
+ case FieldType.Enum:
+ CheckInteger(value);
+ // Just return it as an int, and let the CLR convert it.
+ // Note that we deliberately don't check that it's a known value.
+ return (int) value;
default:
- throw new InvalidProtocolBufferException("Unsupported conversion from JSON number for field type " + field.FieldType);
+ throw new InvalidProtocolBufferException($"Unsupported conversion from JSON number for field type {field.FieldType}");
}
}
catch (OverflowException)
{
- throw new InvalidProtocolBufferException("Value out of range: " + value);
+ throw new InvalidProtocolBufferException($"Value out of range: {value}");
}
}
}
+ private static void CheckInteger(double value)
+ {
+ if (double.IsInfinity(value) || double.IsNaN(value))
+ {
+ throw new InvalidProtocolBufferException($"Value not an integer: {value}");
+ }
+ if (value != Math.Floor(value))
+ {
+ throw new InvalidProtocolBufferException($"Value not an integer: {value}");
+ }
+ }
+
private static object ParseSingleStringValue(FieldDescriptor field, string text)
{
switch (field.FieldType)
@@ -618,47 +679,46 @@ namespace Google.Protobuf
case FieldType.String:
return text;
case FieldType.Bytes:
- return ByteString.FromBase64(text);
+ try
+ {
+ return ByteString.FromBase64(text);
+ }
+ catch (FormatException e)
+ {
+ throw InvalidProtocolBufferException.InvalidBase64(e);
+ }
case FieldType.Int32:
case FieldType.SInt32:
case FieldType.SFixed32:
- return ParseNumericString(text, int.Parse, false);
+ return ParseNumericString(text, int.Parse);
case FieldType.UInt32:
case FieldType.Fixed32:
- return ParseNumericString(text, uint.Parse, false);
+ return ParseNumericString(text, uint.Parse);
case FieldType.Int64:
case FieldType.SInt64:
case FieldType.SFixed64:
- return ParseNumericString(text, long.Parse, false);
+ return ParseNumericString(text, long.Parse);
case FieldType.UInt64:
case FieldType.Fixed64:
- return ParseNumericString(text, ulong.Parse, false);
+ return ParseNumericString(text, ulong.Parse);
case FieldType.Double:
- double d = ParseNumericString(text, double.Parse, true);
- // double.Parse can return +/- infinity on Mono for non-infinite values which are out of range for double.
- if (double.IsInfinity(d) && !text.Contains("Infinity"))
- {
- throw new InvalidProtocolBufferException("Invalid numeric value: " + text);
- }
+ double d = ParseNumericString(text, double.Parse);
+ ValidateInfinityAndNan(text, double.IsPositiveInfinity(d), double.IsNegativeInfinity(d), double.IsNaN(d));
return d;
case FieldType.Float:
- float f = ParseNumericString(text, float.Parse, true);
- // float.Parse can return +/- infinity on Mono for non-infinite values which are out of range for float.
- if (float.IsInfinity(f) && !text.Contains("Infinity"))
- {
- throw new InvalidProtocolBufferException("Invalid numeric value: " + text);
- }
+ float f = ParseNumericString(text, float.Parse);
+ ValidateInfinityAndNan(text, float.IsPositiveInfinity(f), float.IsNegativeInfinity(f), float.IsNaN(f));
return f;
case FieldType.Enum:
var enumValue = field.EnumType.FindValueByName(text);
if (enumValue == null)
{
- throw new InvalidProtocolBufferException("Invalid enum value: " + text + " for enum type: " + field.EnumType.FullName);
+ throw new InvalidProtocolBufferException($"Invalid enum value: {text} for enum type: {field.EnumType.FullName}");
}
// Just return it as an int, and let the CLR convert it.
return enumValue.Number;
default:
- throw new InvalidProtocolBufferException("Unsupported conversion from JSON string for field type " + field.FieldType);
+ throw new InvalidProtocolBufferException($"Unsupported conversion from JSON string for field type {field.FieldType}");
}
}
@@ -670,43 +730,53 @@ namespace Google.Protobuf
return field.MessageType.Parser.CreateTemplate();
}
- private static T ParseNumericString<T>(string text, Func<string, NumberStyles, IFormatProvider, T> parser, bool floatingPoint)
+ private static T ParseNumericString<T>(string text, Func<string, NumberStyles, IFormatProvider, T> parser)
{
- // TODO: Prohibit leading zeroes (but allow 0!)
- // TODO: Validate handling of "Infinity" etc. (Should be case sensitive, no leading whitespace etc)
// Can't prohibit this with NumberStyles.
if (text.StartsWith("+"))
{
- throw new InvalidProtocolBufferException("Invalid numeric value: " + text);
+ throw new InvalidProtocolBufferException($"Invalid numeric value: {text}");
}
if (text.StartsWith("0") && text.Length > 1)
{
if (text[1] >= '0' && text[1] <= '9')
{
- throw new InvalidProtocolBufferException("Invalid numeric value: " + text);
+ throw new InvalidProtocolBufferException($"Invalid numeric value: {text}");
}
}
else if (text.StartsWith("-0") && text.Length > 2)
{
if (text[2] >= '0' && text[2] <= '9')
{
- throw new InvalidProtocolBufferException("Invalid numeric value: " + text);
+ throw new InvalidProtocolBufferException($"Invalid numeric value: {text}");
}
}
try
{
- var styles = floatingPoint
- ? NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent
- : NumberStyles.AllowLeadingSign;
- return parser(text, styles, CultureInfo.InvariantCulture);
+ return parser(text, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent, CultureInfo.InvariantCulture);
}
catch (FormatException)
{
- throw new InvalidProtocolBufferException("Invalid numeric value for type: " + text);
+ throw new InvalidProtocolBufferException($"Invalid numeric value for type: {text}");
}
catch (OverflowException)
{
- throw new InvalidProtocolBufferException("Value out of range: " + text);
+ throw new InvalidProtocolBufferException($"Value out of range: {text}");
+ }
+ }
+
+ /// <summary>
+ /// Checks that any infinite/NaN values originated from the correct text.
+ /// This corrects the lenient whitespace handling of double.Parse/float.Parse, as well as the
+ /// way that Mono parses out-of-range values as infinity.
+ /// </summary>
+ private static void ValidateInfinityAndNan(string text, bool isPositiveInfinity, bool isNegativeInfinity, bool isNaN)
+ {
+ if ((isPositiveInfinity && text != "Infinity") ||
+ (isNegativeInfinity && text != "-Infinity") ||
+ (isNaN && text != "NaN"))
+ {
+ throw new InvalidProtocolBufferException($"Invalid numeric value: {text}");
}
}
@@ -719,7 +789,7 @@ namespace Google.Protobuf
var match = TimestampRegex.Match(token.StringValue);
if (!match.Success)
{
- throw new InvalidProtocolBufferException("Invalid Timestamp value: " + token.StringValue);
+ throw new InvalidProtocolBufferException($"Invalid Timestamp value: {token.StringValue}");
}
var dateTime = match.Groups["datetime"].Value;
var subseconds = match.Groups["subseconds"].Value;
@@ -809,28 +879,24 @@ namespace Google.Protobuf
try
{
- long seconds = long.Parse(secondsText, CultureInfo.InvariantCulture);
+ long seconds = long.Parse(secondsText, CultureInfo.InvariantCulture) * multiplier;
int nanos = 0;
if (subseconds != "")
{
// This should always work, as we've got 1-9 digits.
int parsedFraction = int.Parse(subseconds.Substring(1));
- nanos = parsedFraction * SubsecondScalingFactors[subseconds.Length];
+ nanos = parsedFraction * SubsecondScalingFactors[subseconds.Length] * multiplier;
}
- if (seconds >= Duration.MaxSeconds)
+ if (!Duration.IsNormalized(seconds, nanos))
{
- // Allow precisely 315576000000 seconds, but prohibit even 1ns more.
- if (seconds > Duration.MaxSeconds || nanos > 0)
- {
- throw new InvalidProtocolBufferException("Invalid Duration value: " + token.StringValue);
- }
+ throw new InvalidProtocolBufferException($"Invalid Duration value: {token.StringValue}");
}
- message.Descriptor.Fields[Duration.SecondsFieldNumber].Accessor.SetValue(message, seconds * multiplier);
- message.Descriptor.Fields[Duration.NanosFieldNumber].Accessor.SetValue(message, nanos * multiplier);
+ message.Descriptor.Fields[Duration.SecondsFieldNumber].Accessor.SetValue(message, seconds);
+ message.Descriptor.Fields[Duration.NanosFieldNumber].Accessor.SetValue(message, nanos);
}
catch (FormatException)
{
- throw new InvalidProtocolBufferException("Invalid Duration value: " + token.StringValue);
+ throw new InvalidProtocolBufferException($"Invalid Duration value: {token.StringValue}");
}
}
@@ -853,6 +919,8 @@ namespace Google.Protobuf
private static string ToSnakeCase(string text)
{
var builder = new StringBuilder(text.Length * 2);
+ // Note: this is probably unnecessary now, but currently retained to be as close as possible to the
+ // C++, whilst still throwing an exception on underscores.
bool wasNotUnderscore = false; // Initialize to false for case 1 (below)
bool wasNotCap = false;
@@ -886,7 +954,11 @@ namespace Google.Protobuf
else
{
builder.Append(c);
- wasNotUnderscore = c != '_';
+ if (c == '_')
+ {
+ throw new InvalidProtocolBufferException($"Invalid field mask: {text}");
+ }
+ wasNotUnderscore = true;
wasNotCap = true;
}
}
@@ -940,7 +1012,7 @@ namespace Google.Protobuf
public Settings(int recursionLimit, TypeRegistry typeRegistry)
{
RecursionLimit = recursionLimit;
- TypeRegistry = Preconditions.CheckNotNull(typeRegistry, nameof(typeRegistry));
+ TypeRegistry = ProtoPreconditions.CheckNotNull(typeRegistry, nameof(typeRegistry));
}
}
}
diff --git a/csharp/src/Google.Protobuf/MessageExtensions.cs b/csharp/src/Google.Protobuf/MessageExtensions.cs
index d2d057c0..047156c3 100644
--- a/csharp/src/Google.Protobuf/MessageExtensions.cs
+++ b/csharp/src/Google.Protobuf/MessageExtensions.cs
@@ -46,8 +46,8 @@ namespace Google.Protobuf
/// <param name="data">The data to merge, which must be protobuf-encoded binary data.</param>
public static void MergeFrom(this IMessage message, byte[] data)
{
- Preconditions.CheckNotNull(message, "message");
- Preconditions.CheckNotNull(data, "data");
+ ProtoPreconditions.CheckNotNull(message, "message");
+ ProtoPreconditions.CheckNotNull(data, "data");
CodedInputStream input = new CodedInputStream(data);
message.MergeFrom(input);
input.CheckReadEndOfStreamTag();
@@ -60,8 +60,8 @@ namespace Google.Protobuf
/// <param name="data">The data to merge, which must be protobuf-encoded binary data.</param>
public static void MergeFrom(this IMessage message, ByteString data)
{
- Preconditions.CheckNotNull(message, "message");
- Preconditions.CheckNotNull(data, "data");
+ ProtoPreconditions.CheckNotNull(message, "message");
+ ProtoPreconditions.CheckNotNull(data, "data");
CodedInputStream input = data.CreateCodedInput();
message.MergeFrom(input);
input.CheckReadEndOfStreamTag();
@@ -74,8 +74,8 @@ namespace Google.Protobuf
/// <param name="input">Stream containing the data to merge, which must be protobuf-encoded binary data.</param>
public static void MergeFrom(this IMessage message, Stream input)
{
- Preconditions.CheckNotNull(message, "message");
- Preconditions.CheckNotNull(input, "input");
+ ProtoPreconditions.CheckNotNull(message, "message");
+ ProtoPreconditions.CheckNotNull(input, "input");
CodedInputStream codedInput = new CodedInputStream(input);
message.MergeFrom(codedInput);
codedInput.CheckReadEndOfStreamTag();
@@ -92,8 +92,8 @@ namespace Google.Protobuf
/// <param name="input">Stream containing the data to merge, which must be protobuf-encoded binary data.</param>
public static void MergeDelimitedFrom(this IMessage message, Stream input)
{
- Preconditions.CheckNotNull(message, "message");
- Preconditions.CheckNotNull(input, "input");
+ ProtoPreconditions.CheckNotNull(message, "message");
+ ProtoPreconditions.CheckNotNull(input, "input");
int size = (int) CodedInputStream.ReadRawVarint32(input);
Stream limitedStream = new LimitedInputStream(input, size);
message.MergeFrom(limitedStream);
@@ -106,7 +106,7 @@ namespace Google.Protobuf
/// <returns>The message data as a byte array.</returns>
public static byte[] ToByteArray(this IMessage message)
{
- Preconditions.CheckNotNull(message, "message");
+ ProtoPreconditions.CheckNotNull(message, "message");
byte[] result = new byte[message.CalculateSize()];
CodedOutputStream output = new CodedOutputStream(result);
message.WriteTo(output);
@@ -121,8 +121,8 @@ namespace Google.Protobuf
/// <param name="output">The stream to write to.</param>
public static void WriteTo(this IMessage message, Stream output)
{
- Preconditions.CheckNotNull(message, "message");
- Preconditions.CheckNotNull(output, "output");
+ ProtoPreconditions.CheckNotNull(message, "message");
+ ProtoPreconditions.CheckNotNull(output, "output");
CodedOutputStream codedOutput = new CodedOutputStream(output);
message.WriteTo(codedOutput);
codedOutput.Flush();
@@ -135,8 +135,8 @@ namespace Google.Protobuf
/// <param name="output">The output stream to write to.</param>
public static void WriteDelimitedTo(this IMessage message, Stream output)
{
- Preconditions.CheckNotNull(message, "message");
- Preconditions.CheckNotNull(output, "output");
+ ProtoPreconditions.CheckNotNull(message, "message");
+ ProtoPreconditions.CheckNotNull(output, "output");
CodedOutputStream codedOutput = new CodedOutputStream(output);
codedOutput.WriteRawVarint32((uint)message.CalculateSize());
message.WriteTo(codedOutput);
@@ -150,7 +150,7 @@ namespace Google.Protobuf
/// <returns>The message data as a byte string.</returns>
public static ByteString ToByteString(this IMessage message)
{
- Preconditions.CheckNotNull(message, "message");
+ ProtoPreconditions.CheckNotNull(message, "message");
return ByteString.AttachBytes(message.ToByteArray());
}
}
diff --git a/csharp/src/Google.Protobuf/MessageParser.cs b/csharp/src/Google.Protobuf/MessageParser.cs
index 81be3c2a..8889638b 100644
--- a/csharp/src/Google.Protobuf/MessageParser.cs
+++ b/csharp/src/Google.Protobuf/MessageParser.cs
@@ -64,7 +64,7 @@ namespace Google.Protobuf
/// <returns>The newly parsed message.</returns>
public IMessage ParseFrom(byte[] data)
{
- Preconditions.CheckNotNull(data, "data");
+ ProtoPreconditions.CheckNotNull(data, "data");
IMessage message = factory();
message.MergeFrom(data);
return message;
@@ -77,7 +77,7 @@ namespace Google.Protobuf
/// <returns>The parsed message.</returns>
public IMessage ParseFrom(ByteString data)
{
- Preconditions.CheckNotNull(data, "data");
+ ProtoPreconditions.CheckNotNull(data, "data");
IMessage message = factory();
message.MergeFrom(data);
return message;
@@ -191,7 +191,7 @@ namespace Google.Protobuf
/// <returns>The newly parsed message.</returns>
public new T ParseFrom(byte[] data)
{
- Preconditions.CheckNotNull(data, "data");
+ ProtoPreconditions.CheckNotNull(data, "data");
T message = factory();
message.MergeFrom(data);
return message;
@@ -204,7 +204,7 @@ namespace Google.Protobuf
/// <returns>The parsed message.</returns>
public new T ParseFrom(ByteString data)
{
- Preconditions.CheckNotNull(data, "data");
+ ProtoPreconditions.CheckNotNull(data, "data");
T message = factory();
message.MergeFrom(data);
return message;
diff --git a/csharp/src/Google.Protobuf/Properties/AssemblyInfo.cs b/csharp/src/Google.Protobuf/Properties/AssemblyInfo.cs
index 225ac0dd..9b179bd7 100644
--- a/csharp/src/Google.Protobuf/Properties/AssemblyInfo.cs
+++ b/csharp/src/Google.Protobuf/Properties/AssemblyInfo.cs
@@ -30,7 +30,6 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
-using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
@@ -38,30 +37,13 @@ using System.Security;
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
-[assembly: AssemblyTitle("Google.Protobuf")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("Google.Protobuf")]
-[assembly: AssemblyCopyright("Copyright © 2015")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
#if !NCRUNCH
[assembly: AllowPartiallyTrustedCallers]
#endif
-#if SIGNED
[assembly: InternalsVisibleTo("Google.Protobuf.Test, PublicKey=" +
"002400000480000094000000060200000024000052534131000400000100010025800fbcfc63a1" +
"7c66b303aae80b03a6beaa176bb6bef883be436f2a1579edd80ce23edf151a1f4ced97af83abcd" +
"981207041fd5b2da3b498346fcfcd94910d52f25537c4a43ce3fbe17dc7d43e6cbdb4d8f1242dc" +
"b6bd9b5906be74da8daa7d7280f97130f318a16c07baf118839b156299a48522f9fae2371c9665" +
"c5ae9cb6")]
-#else
-[assembly: InternalsVisibleTo("Google.Protobuf.Test")]
-#endif
-
-[assembly: AssemblyVersion("3.0.0.0")]
-[assembly: AssemblyFileVersion("3.0.0.0")]
-[assembly: AssemblyInformationalVersion("3.0.0-alpha4")]
diff --git a/csharp/src/Google.Protobuf/Preconditions.cs b/csharp/src/Google.Protobuf/ProtoPreconditions.cs
index 2db35ff6..abaeb9b4 100644
--- a/csharp/src/Google.Protobuf/Preconditions.cs
+++ b/csharp/src/Google.Protobuf/ProtoPreconditions.cs
@@ -35,9 +35,14 @@ using System;
namespace Google.Protobuf
{
/// <summary>
- /// Helper methods for throwing exceptions
+ /// Helper methods for throwing exceptions when preconditions are not met.
/// </summary>
- public static class Preconditions
+ /// <remarks>
+ /// This class is used internally and by generated code; it is not particularly
+ /// expected to be used from application code, although nothing prevents it
+ /// from being used that way.
+ /// </remarks>
+ public static class ProtoPreconditions
{
/// <summary>
/// Throws an ArgumentNullException if the given value is null, otherwise
diff --git a/csharp/src/Google.Protobuf/Reflection/Descriptor.cs b/csharp/src/Google.Protobuf/Reflection/Descriptor.cs
index 03685322..83e7928a 100644
--- a/csharp/src/Google.Protobuf/Reflection/Descriptor.cs
+++ b/csharp/src/Google.Protobuf/Reflection/Descriptor.cs
@@ -10,7 +10,6 @@ using scg = global::System.Collections.Generic;
namespace Google.Protobuf.Reflection {
/// <summary>Holder for reflection information generated from google/protobuf/descriptor.proto</summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
internal static partial class DescriptorReflection {
#region Descriptor
@@ -65,98 +64,106 @@ namespace Google.Protobuf.Reflection {
"RVMQDBIPCgtUWVBFX1VJTlQzMhANEg0KCVRZUEVfRU5VTRAOEhEKDVRZUEVf",
"U0ZJWEVEMzIQDxIRCg1UWVBFX1NGSVhFRDY0EBASDwoLVFlQRV9TSU5UMzIQ",
"ERIPCgtUWVBFX1NJTlQ2NBASIkMKBUxhYmVsEhIKDkxBQkVMX09QVElPTkFM",
- "EAESEgoOTEFCRUxfUkVRVUlSRUQQAhISCg5MQUJFTF9SRVBFQVRFRBADIiQK",
- "FE9uZW9mRGVzY3JpcHRvclByb3RvEgwKBG5hbWUYASABKAkijAEKE0VudW1E",
- "ZXNjcmlwdG9yUHJvdG8SDAoEbmFtZRgBIAEoCRI4CgV2YWx1ZRgCIAMoCzIp",
- "Lmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8SLQoH",
- "b3B0aW9ucxgDIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9ucyJs",
- "ChhFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8SDAoEbmFtZRgBIAEoCRIOCgZu",
- "dW1iZXIYAiABKAUSMgoHb3B0aW9ucxgDIAEoCzIhLmdvb2dsZS5wcm90b2J1",
- "Zi5FbnVtVmFsdWVPcHRpb25zIpABChZTZXJ2aWNlRGVzY3JpcHRvclByb3Rv",
- "EgwKBG5hbWUYASABKAkSNgoGbWV0aG9kGAIgAygLMiYuZ29vZ2xlLnByb3Rv",
- "YnVmLk1ldGhvZERlc2NyaXB0b3JQcm90bxIwCgdvcHRpb25zGAMgASgLMh8u",
- "Z29vZ2xlLnByb3RvYnVmLlNlcnZpY2VPcHRpb25zIsEBChVNZXRob2REZXNj",
- "cmlwdG9yUHJvdG8SDAoEbmFtZRgBIAEoCRISCgppbnB1dF90eXBlGAIgASgJ",
- "EhMKC291dHB1dF90eXBlGAMgASgJEi8KB29wdGlvbnMYBCABKAsyHi5nb29n",
- "bGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucxIfChBjbGllbnRfc3RyZWFtaW5n",
- "GAUgASgIOgVmYWxzZRIfChBzZXJ2ZXJfc3RyZWFtaW5nGAYgASgIOgVmYWxz",
- "ZSKqBQoLRmlsZU9wdGlvbnMSFAoMamF2YV9wYWNrYWdlGAEgASgJEhwKFGph",
- "dmFfb3V0ZXJfY2xhc3NuYW1lGAggASgJEiIKE2phdmFfbXVsdGlwbGVfZmls",
- "ZXMYCiABKAg6BWZhbHNlEiwKHWphdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9o",
- "YXNoGBQgASgIOgVmYWxzZRIlChZqYXZhX3N0cmluZ19jaGVja191dGY4GBsg",
- "ASgIOgVmYWxzZRJGCgxvcHRpbWl6ZV9mb3IYCSABKA4yKS5nb29nbGUucHJv",
- "dG9idWYuRmlsZU9wdGlvbnMuT3B0aW1pemVNb2RlOgVTUEVFRBISCgpnb19w",
- "YWNrYWdlGAsgASgJEiIKE2NjX2dlbmVyaWNfc2VydmljZXMYECABKAg6BWZh",
- "bHNlEiQKFWphdmFfZ2VuZXJpY19zZXJ2aWNlcxgRIAEoCDoFZmFsc2USIgoT",
- "cHlfZ2VuZXJpY19zZXJ2aWNlcxgSIAEoCDoFZmFsc2USGQoKZGVwcmVjYXRl",
- "ZBgXIAEoCDoFZmFsc2USHwoQY2NfZW5hYmxlX2FyZW5hcxgfIAEoCDoFZmFs",
- "c2USGQoRb2JqY19jbGFzc19wcmVmaXgYJCABKAkSGAoQY3NoYXJwX25hbWVz",
- "cGFjZRglIAEoCRInCh9qYXZhbmFub191c2VfZGVwcmVjYXRlZF9wYWNrYWdl",
- "GCYgASgIEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2ds",
- "ZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uIjoKDE9wdGltaXplTW9k",
- "ZRIJCgVTUEVFRBABEg0KCUNPREVfU0laRRACEhAKDExJVEVfUlVOVElNRRAD",
- "KgkI6AcQgICAgAIi5gEKDk1lc3NhZ2VPcHRpb25zEiYKF21lc3NhZ2Vfc2V0",
- "X3dpcmVfZm9ybWF0GAEgASgIOgVmYWxzZRIuCh9ub19zdGFuZGFyZF9kZXNj",
- "cmlwdG9yX2FjY2Vzc29yGAIgASgIOgVmYWxzZRIZCgpkZXByZWNhdGVkGAMg",
- "ASgIOgVmYWxzZRIRCgltYXBfZW50cnkYByABKAgSQwoUdW5pbnRlcnByZXRl",
- "ZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0",
- "ZWRPcHRpb24qCQjoBxCAgICAAiKYAwoMRmllbGRPcHRpb25zEjoKBWN0eXBl",
- "GAEgASgOMiMuZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5DVHlwZToG",
- "U1RSSU5HEg4KBnBhY2tlZBgCIAEoCBI/CgZqc3R5cGUYBiABKA4yJC5nb29n",
- "bGUucHJvdG9idWYuRmllbGRPcHRpb25zLkpTVHlwZToJSlNfTk9STUFMEhMK",
- "BGxhenkYBSABKAg6BWZhbHNlEhkKCmRlcHJlY2F0ZWQYAyABKAg6BWZhbHNl",
- "EhMKBHdlYWsYCiABKAg6BWZhbHNlEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9u",
- "GOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9u",
- "Ii8KBUNUeXBlEgoKBlNUUklORxAAEggKBENPUkQQARIQCgxTVFJJTkdfUElF",
- "Q0UQAiI1CgZKU1R5cGUSDQoJSlNfTk9STUFMEAASDQoJSlNfU1RSSU5HEAES",
- "DQoJSlNfTlVNQkVSEAIqCQjoBxCAgICAAiKNAQoLRW51bU9wdGlvbnMSEwoL",
- "YWxsb3dfYWxpYXMYAiABKAgSGQoKZGVwcmVjYXRlZBgDIAEoCDoFZmFsc2US",
- "QwoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3Rv",
- "YnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICAAiJ9ChBFbnVtVmFs",
- "dWVPcHRpb25zEhkKCmRlcHJlY2F0ZWQYASABKAg6BWZhbHNlEkMKFHVuaW50",
- "ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5Vbmlu",
- "dGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIiewoOU2VydmljZU9wdGlvbnMS",
- "GQoKZGVwcmVjYXRlZBghIAEoCDoFZmFsc2USQwoUdW5pbnRlcnByZXRlZF9v",
- "cHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRP",
- "cHRpb24qCQjoBxCAgICAAiJ6Cg1NZXRob2RPcHRpb25zEhkKCmRlcHJlY2F0",
- "ZWQYISABKAg6BWZhbHNlEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMo",
- "CzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uKgkI6AcQ",
- "gICAgAIingIKE1VuaW50ZXJwcmV0ZWRPcHRpb24SOwoEbmFtZRgCIAMoCzIt",
- "Lmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLk5hbWVQYXJ0",
- "EhgKEGlkZW50aWZpZXJfdmFsdWUYAyABKAkSGgoScG9zaXRpdmVfaW50X3Zh",
- "bHVlGAQgASgEEhoKEm5lZ2F0aXZlX2ludF92YWx1ZRgFIAEoAxIUCgxkb3Vi",
- "bGVfdmFsdWUYBiABKAESFAoMc3RyaW5nX3ZhbHVlGAcgASgMEhcKD2FnZ3Jl",
- "Z2F0ZV92YWx1ZRgIIAEoCRozCghOYW1lUGFydBIRCgluYW1lX3BhcnQYASAC",
- "KAkSFAoMaXNfZXh0ZW5zaW9uGAIgAigIItUBCg5Tb3VyY2VDb2RlSW5mbxI6",
- "Cghsb2NhdGlvbhgBIAMoCzIoLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2Rl",
- "SW5mby5Mb2NhdGlvbhqGAQoITG9jYXRpb24SEAoEcGF0aBgBIAMoBUICEAES",
- "EAoEc3BhbhgCIAMoBUICEAESGAoQbGVhZGluZ19jb21tZW50cxgDIAEoCRIZ",
- "ChF0cmFpbGluZ19jb21tZW50cxgEIAEoCRIhChlsZWFkaW5nX2RldGFjaGVk",
- "X2NvbW1lbnRzGAYgAygJQlgKE2NvbS5nb29nbGUucHJvdG9idWZCEERlc2Ny",
- "aXB0b3JQcm90b3NIAVoKZGVzY3JpcHRvcqICA0dQQqoCGkdvb2dsZS5Qcm90",
- "b2J1Zi5SZWZsZWN0aW9u"));
+ "EAESEgoOTEFCRUxfUkVRVUlSRUQQAhISCg5MQUJFTF9SRVBFQVRFRBADIlQK",
+ "FE9uZW9mRGVzY3JpcHRvclByb3RvEgwKBG5hbWUYASABKAkSLgoHb3B0aW9u",
+ "cxgCIAEoCzIdLmdvb2dsZS5wcm90b2J1Zi5PbmVvZk9wdGlvbnMijAEKE0Vu",
+ "dW1EZXNjcmlwdG9yUHJvdG8SDAoEbmFtZRgBIAEoCRI4CgV2YWx1ZRgCIAMo",
+ "CzIpLmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8S",
+ "LQoHb3B0aW9ucxgDIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9u",
+ "cyJsChhFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8SDAoEbmFtZRgBIAEoCRIO",
+ "CgZudW1iZXIYAiABKAUSMgoHb3B0aW9ucxgDIAEoCzIhLmdvb2dsZS5wcm90",
+ "b2J1Zi5FbnVtVmFsdWVPcHRpb25zIpABChZTZXJ2aWNlRGVzY3JpcHRvclBy",
+ "b3RvEgwKBG5hbWUYASABKAkSNgoGbWV0aG9kGAIgAygLMiYuZ29vZ2xlLnBy",
+ "b3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90bxIwCgdvcHRpb25zGAMgASgL",
+ "Mh8uZ29vZ2xlLnByb3RvYnVmLlNlcnZpY2VPcHRpb25zIsEBChVNZXRob2RE",
+ "ZXNjcmlwdG9yUHJvdG8SDAoEbmFtZRgBIAEoCRISCgppbnB1dF90eXBlGAIg",
+ "ASgJEhMKC291dHB1dF90eXBlGAMgASgJEi8KB29wdGlvbnMYBCABKAsyHi5n",
+ "b29nbGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucxIfChBjbGllbnRfc3RyZWFt",
+ "aW5nGAUgASgIOgVmYWxzZRIfChBzZXJ2ZXJfc3RyZWFtaW5nGAYgASgIOgVm",
+ "YWxzZSKHBQoLRmlsZU9wdGlvbnMSFAoMamF2YV9wYWNrYWdlGAEgASgJEhwK",
+ "FGphdmFfb3V0ZXJfY2xhc3NuYW1lGAggASgJEiIKE2phdmFfbXVsdGlwbGVf",
+ "ZmlsZXMYCiABKAg6BWZhbHNlEiwKHWphdmFfZ2VuZXJhdGVfZXF1YWxzX2Fu",
+ "ZF9oYXNoGBQgASgIOgVmYWxzZRIlChZqYXZhX3N0cmluZ19jaGVja191dGY4",
+ "GBsgASgIOgVmYWxzZRJGCgxvcHRpbWl6ZV9mb3IYCSABKA4yKS5nb29nbGUu",
+ "cHJvdG9idWYuRmlsZU9wdGlvbnMuT3B0aW1pemVNb2RlOgVTUEVFRBISCgpn",
+ "b19wYWNrYWdlGAsgASgJEiIKE2NjX2dlbmVyaWNfc2VydmljZXMYECABKAg6",
+ "BWZhbHNlEiQKFWphdmFfZ2VuZXJpY19zZXJ2aWNlcxgRIAEoCDoFZmFsc2US",
+ "IgoTcHlfZ2VuZXJpY19zZXJ2aWNlcxgSIAEoCDoFZmFsc2USGQoKZGVwcmVj",
+ "YXRlZBgXIAEoCDoFZmFsc2USHwoQY2NfZW5hYmxlX2FyZW5hcxgfIAEoCDoF",
+ "ZmFsc2USGQoRb2JqY19jbGFzc19wcmVmaXgYJCABKAkSGAoQY3NoYXJwX25h",
+ "bWVzcGFjZRglIAEoCRJDChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsy",
+ "JC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiI6CgxPcHRp",
+ "bWl6ZU1vZGUSCQoFU1BFRUQQARINCglDT0RFX1NJWkUQAhIQCgxMSVRFX1JV",
+ "TlRJTUUQAyoJCOgHEICAgIACSgQIJhAnIuYBCg5NZXNzYWdlT3B0aW9ucxIm",
+ "ChdtZXNzYWdlX3NldF93aXJlX2Zvcm1hdBgBIAEoCDoFZmFsc2USLgofbm9f",
+ "c3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvchgCIAEoCDoFZmFsc2USGQoK",
+ "ZGVwcmVjYXRlZBgDIAEoCDoFZmFsc2USEQoJbWFwX2VudHJ5GAcgASgIEkMK",
+ "FHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1",
+ "Zi5VbmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIimAMKDEZpZWxkT3B0",
+ "aW9ucxI6CgVjdHlwZRgBIAEoDjIjLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9w",
+ "dGlvbnMuQ1R5cGU6BlNUUklORxIOCgZwYWNrZWQYAiABKAgSPwoGanN0eXBl",
+ "GAYgASgOMiQuZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5KU1R5cGU6",
+ "CUpTX05PUk1BTBITCgRsYXp5GAUgASgIOgVmYWxzZRIZCgpkZXByZWNhdGVk",
+ "GAMgASgIOgVmYWxzZRITCgR3ZWFrGAogASgIOgVmYWxzZRJDChR1bmludGVy",
+ "cHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRl",
+ "cnByZXRlZE9wdGlvbiIvCgVDVHlwZRIKCgZTVFJJTkcQABIICgRDT1JEEAES",
+ "EAoMU1RSSU5HX1BJRUNFEAIiNQoGSlNUeXBlEg0KCUpTX05PUk1BTBAAEg0K",
+ "CUpTX1NUUklORxABEg0KCUpTX05VTUJFUhACKgkI6AcQgICAgAIiXgoMT25l",
+ "b2ZPcHRpb25zEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdv",
+ "b2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIi",
+ "jQEKC0VudW1PcHRpb25zEhMKC2FsbG93X2FsaWFzGAIgASgIEhkKCmRlcHJl",
+ "Y2F0ZWQYAyABKAg6BWZhbHNlEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcH",
+ "IAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uKgkI",
+ "6AcQgICAgAIifQoQRW51bVZhbHVlT3B0aW9ucxIZCgpkZXByZWNhdGVkGAEg",
+ "ASgIOgVmYWxzZRJDChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5n",
+ "b29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbioJCOgHEICAgIAC",
+ "InsKDlNlcnZpY2VPcHRpb25zEhkKCmRlcHJlY2F0ZWQYISABKAg6BWZhbHNl",
+ "EkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90",
+ "b2J1Zi5VbmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIiegoNTWV0aG9k",
+ "T3B0aW9ucxIZCgpkZXByZWNhdGVkGCEgASgIOgVmYWxzZRJDChR1bmludGVy",
+ "cHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRl",
+ "cnByZXRlZE9wdGlvbioJCOgHEICAgIACIp4CChNVbmludGVycHJldGVkT3B0",
+ "aW9uEjsKBG5hbWUYAiADKAsyLS5nb29nbGUucHJvdG9idWYuVW5pbnRlcnBy",
+ "ZXRlZE9wdGlvbi5OYW1lUGFydBIYChBpZGVudGlmaWVyX3ZhbHVlGAMgASgJ",
+ "EhoKEnBvc2l0aXZlX2ludF92YWx1ZRgEIAEoBBIaChJuZWdhdGl2ZV9pbnRf",
+ "dmFsdWUYBSABKAMSFAoMZG91YmxlX3ZhbHVlGAYgASgBEhQKDHN0cmluZ192",
+ "YWx1ZRgHIAEoDBIXCg9hZ2dyZWdhdGVfdmFsdWUYCCABKAkaMwoITmFtZVBh",
+ "cnQSEQoJbmFtZV9wYXJ0GAEgAigJEhQKDGlzX2V4dGVuc2lvbhgCIAIoCCLV",
+ "AQoOU291cmNlQ29kZUluZm8SOgoIbG9jYXRpb24YASADKAsyKC5nb29nbGUu",
+ "cHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24ahgEKCExvY2F0aW9u",
+ "EhAKBHBhdGgYASADKAVCAhABEhAKBHNwYW4YAiADKAVCAhABEhgKEGxlYWRp",
+ "bmdfY29tbWVudHMYAyABKAkSGQoRdHJhaWxpbmdfY29tbWVudHMYBCABKAkS",
+ "IQoZbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cxgGIAMoCSKnAQoRR2VuZXJh",
+ "dGVkQ29kZUluZm8SQQoKYW5ub3RhdGlvbhgBIAMoCzItLmdvb2dsZS5wcm90",
+ "b2J1Zi5HZW5lcmF0ZWRDb2RlSW5mby5Bbm5vdGF0aW9uGk8KCkFubm90YXRp",
+ "b24SEAoEcGF0aBgBIAMoBUICEAESEwoLc291cmNlX2ZpbGUYAiABKAkSDQoF",
+ "YmVnaW4YAyABKAUSCwoDZW5kGAQgASgFQlsKE2NvbS5nb29nbGUucHJvdG9i",
+ "dWZCEERlc2NyaXB0b3JQcm90b3NIAVoKZGVzY3JpcHRvcqABAaICA0dQQqoC",
+ "Gkdvb2dsZS5Qcm90b2J1Zi5SZWZsZWN0aW9u"));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
- new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Reflection.FileDescriptorSet), global::Google.Protobuf.Reflection.FileDescriptorSet.Parser, new[]{ "File" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Reflection.FileDescriptorProto), global::Google.Protobuf.Reflection.FileDescriptorProto.Parser, new[]{ "Name", "Package", "Dependency", "PublicDependency", "WeakDependency", "MessageType", "EnumType", "Service", "Extension", "Options", "SourceCodeInfo", "Syntax" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Reflection.DescriptorProto), global::Google.Protobuf.Reflection.DescriptorProto.Parser, new[]{ "Name", "Field", "Extension", "NestedType", "EnumType", "ExtensionRange", "OneofDecl", "Options", "ReservedRange", "ReservedName" }, null, null, new pbr::GeneratedCodeInfo[] { new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Reflection.DescriptorProto.Types.ExtensionRange), global::Google.Protobuf.Reflection.DescriptorProto.Types.ExtensionRange.Parser, new[]{ "Start", "End" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Reflection.DescriptorProto.Types.ReservedRange), global::Google.Protobuf.Reflection.DescriptorProto.Types.ReservedRange.Parser, new[]{ "Start", "End" }, null, null, null)}),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Reflection.FieldDescriptorProto), global::Google.Protobuf.Reflection.FieldDescriptorProto.Parser, new[]{ "Name", "Number", "Label", "Type", "TypeName", "Extendee", "DefaultValue", "OneofIndex", "JsonName", "Options" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Type), typeof(global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Label) }, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Reflection.OneofDescriptorProto), global::Google.Protobuf.Reflection.OneofDescriptorProto.Parser, new[]{ "Name" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Reflection.EnumDescriptorProto), global::Google.Protobuf.Reflection.EnumDescriptorProto.Parser, new[]{ "Name", "Value", "Options" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Reflection.EnumValueDescriptorProto), global::Google.Protobuf.Reflection.EnumValueDescriptorProto.Parser, new[]{ "Name", "Number", "Options" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Reflection.ServiceDescriptorProto), global::Google.Protobuf.Reflection.ServiceDescriptorProto.Parser, new[]{ "Name", "Method", "Options" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Reflection.MethodDescriptorProto), global::Google.Protobuf.Reflection.MethodDescriptorProto.Parser, new[]{ "Name", "InputType", "OutputType", "Options", "ClientStreaming", "ServerStreaming" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Reflection.FileOptions), global::Google.Protobuf.Reflection.FileOptions.Parser, new[]{ "JavaPackage", "JavaOuterClassname", "JavaMultipleFiles", "JavaGenerateEqualsAndHash", "JavaStringCheckUtf8", "OptimizeFor", "GoPackage", "CcGenericServices", "JavaGenericServices", "PyGenericServices", "Deprecated", "CcEnableArenas", "ObjcClassPrefix", "CsharpNamespace", "JavananoUseDeprecatedPackage", "UninterpretedOption" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode) }, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Reflection.MessageOptions), global::Google.Protobuf.Reflection.MessageOptions.Parser, new[]{ "MessageSetWireFormat", "NoStandardDescriptorAccessor", "Deprecated", "MapEntry", "UninterpretedOption" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Reflection.FieldOptions), global::Google.Protobuf.Reflection.FieldOptions.Parser, new[]{ "Ctype", "Packed", "Jstype", "Lazy", "Deprecated", "Weak", "UninterpretedOption" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.FieldOptions.Types.CType), typeof(global::Google.Protobuf.Reflection.FieldOptions.Types.JSType) }, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Reflection.EnumOptions), global::Google.Protobuf.Reflection.EnumOptions.Parser, new[]{ "AllowAlias", "Deprecated", "UninterpretedOption" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Reflection.EnumValueOptions), global::Google.Protobuf.Reflection.EnumValueOptions.Parser, new[]{ "Deprecated", "UninterpretedOption" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Reflection.ServiceOptions), global::Google.Protobuf.Reflection.ServiceOptions.Parser, new[]{ "Deprecated", "UninterpretedOption" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Reflection.MethodOptions), global::Google.Protobuf.Reflection.MethodOptions.Parser, new[]{ "Deprecated", "UninterpretedOption" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Reflection.UninterpretedOption), global::Google.Protobuf.Reflection.UninterpretedOption.Parser, new[]{ "Name", "IdentifierValue", "PositiveIntValue", "NegativeIntValue", "DoubleValue", "StringValue", "AggregateValue" }, null, null, new pbr::GeneratedCodeInfo[] { new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Reflection.UninterpretedOption.Types.NamePart), global::Google.Protobuf.Reflection.UninterpretedOption.Types.NamePart.Parser, new[]{ "NamePart_", "IsExtension" }, null, null, null)}),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Reflection.SourceCodeInfo), global::Google.Protobuf.Reflection.SourceCodeInfo.Parser, new[]{ "Location" }, null, null, new pbr::GeneratedCodeInfo[] { new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Reflection.SourceCodeInfo.Types.Location), global::Google.Protobuf.Reflection.SourceCodeInfo.Types.Location.Parser, new[]{ "Path", "Span", "LeadingComments", "TrailingComments", "LeadingDetachedComments" }, null, null, null)})
+ new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FileDescriptorSet), global::Google.Protobuf.Reflection.FileDescriptorSet.Parser, new[]{ "File" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FileDescriptorProto), global::Google.Protobuf.Reflection.FileDescriptorProto.Parser, new[]{ "Name", "Package", "Dependency", "PublicDependency", "WeakDependency", "MessageType", "EnumType", "Service", "Extension", "Options", "SourceCodeInfo", "Syntax" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.DescriptorProto), global::Google.Protobuf.Reflection.DescriptorProto.Parser, new[]{ "Name", "Field", "Extension", "NestedType", "EnumType", "ExtensionRange", "OneofDecl", "Options", "ReservedRange", "ReservedName" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.DescriptorProto.Types.ExtensionRange), global::Google.Protobuf.Reflection.DescriptorProto.Types.ExtensionRange.Parser, new[]{ "Start", "End" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.DescriptorProto.Types.ReservedRange), global::Google.Protobuf.Reflection.DescriptorProto.Types.ReservedRange.Parser, new[]{ "Start", "End" }, null, null, null)}),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FieldDescriptorProto), global::Google.Protobuf.Reflection.FieldDescriptorProto.Parser, new[]{ "Name", "Number", "Label", "Type", "TypeName", "Extendee", "DefaultValue", "OneofIndex", "JsonName", "Options" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Type), typeof(global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Label) }, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.OneofDescriptorProto), global::Google.Protobuf.Reflection.OneofDescriptorProto.Parser, new[]{ "Name", "Options" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.EnumDescriptorProto), global::Google.Protobuf.Reflection.EnumDescriptorProto.Parser, new[]{ "Name", "Value", "Options" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.EnumValueDescriptorProto), global::Google.Protobuf.Reflection.EnumValueDescriptorProto.Parser, new[]{ "Name", "Number", "Options" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.ServiceDescriptorProto), global::Google.Protobuf.Reflection.ServiceDescriptorProto.Parser, new[]{ "Name", "Method", "Options" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.MethodDescriptorProto), global::Google.Protobuf.Reflection.MethodDescriptorProto.Parser, new[]{ "Name", "InputType", "OutputType", "Options", "ClientStreaming", "ServerStreaming" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FileOptions), global::Google.Protobuf.Reflection.FileOptions.Parser, new[]{ "JavaPackage", "JavaOuterClassname", "JavaMultipleFiles", "JavaGenerateEqualsAndHash", "JavaStringCheckUtf8", "OptimizeFor", "GoPackage", "CcGenericServices", "JavaGenericServices", "PyGenericServices", "Deprecated", "CcEnableArenas", "ObjcClassPrefix", "CsharpNamespace", "UninterpretedOption" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode) }, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.MessageOptions), global::Google.Protobuf.Reflection.MessageOptions.Parser, new[]{ "MessageSetWireFormat", "NoStandardDescriptorAccessor", "Deprecated", "MapEntry", "UninterpretedOption" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FieldOptions), global::Google.Protobuf.Reflection.FieldOptions.Parser, new[]{ "Ctype", "Packed", "Jstype", "Lazy", "Deprecated", "Weak", "UninterpretedOption" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.FieldOptions.Types.CType), typeof(global::Google.Protobuf.Reflection.FieldOptions.Types.JSType) }, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.OneofOptions), global::Google.Protobuf.Reflection.OneofOptions.Parser, new[]{ "UninterpretedOption" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.EnumOptions), global::Google.Protobuf.Reflection.EnumOptions.Parser, new[]{ "AllowAlias", "Deprecated", "UninterpretedOption" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.EnumValueOptions), global::Google.Protobuf.Reflection.EnumValueOptions.Parser, new[]{ "Deprecated", "UninterpretedOption" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.ServiceOptions), global::Google.Protobuf.Reflection.ServiceOptions.Parser, new[]{ "Deprecated", "UninterpretedOption" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.MethodOptions), global::Google.Protobuf.Reflection.MethodOptions.Parser, new[]{ "Deprecated", "UninterpretedOption" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.UninterpretedOption), global::Google.Protobuf.Reflection.UninterpretedOption.Parser, new[]{ "Name", "IdentifierValue", "PositiveIntValue", "NegativeIntValue", "DoubleValue", "StringValue", "AggregateValue" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.UninterpretedOption.Types.NamePart), global::Google.Protobuf.Reflection.UninterpretedOption.Types.NamePart.Parser, new[]{ "NamePart_", "IsExtension" }, null, null, null)}),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.SourceCodeInfo), global::Google.Protobuf.Reflection.SourceCodeInfo.Parser, new[]{ "Location" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.SourceCodeInfo.Types.Location), global::Google.Protobuf.Reflection.SourceCodeInfo.Types.Location.Parser, new[]{ "Path", "Span", "LeadingComments", "TrailingComments", "LeadingDetachedComments" }, null, null, null)}),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.GeneratedCodeInfo), global::Google.Protobuf.Reflection.GeneratedCodeInfo.Parser, new[]{ "Annotation" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.GeneratedCodeInfo.Types.Annotation), global::Google.Protobuf.Reflection.GeneratedCodeInfo.Types.Annotation.Parser, new[]{ "Path", "SourceFile", "Begin", "End" }, null, null, null)})
}));
}
#endregion
@@ -167,29 +174,34 @@ namespace Google.Protobuf.Reflection {
/// The protocol compiler can output a FileDescriptorSet containing the .proto
/// files it parses.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
internal sealed partial class FileDescriptorSet : pb::IMessage<FileDescriptorSet> {
private static readonly pb::MessageParser<FileDescriptorSet> _parser = new pb::MessageParser<FileDescriptorSet>(() => new FileDescriptorSet());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<FileDescriptorSet> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[0]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public FileDescriptorSet() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public FileDescriptorSet(FileDescriptorSet other) : this() {
file_ = other.file_.Clone();
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public FileDescriptorSet Clone() {
return new FileDescriptorSet(this);
}
@@ -199,14 +211,17 @@ namespace Google.Protobuf.Reflection {
private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.FileDescriptorProto> _repeated_file_codec
= pb::FieldCodec.ForMessage(10, global::Google.Protobuf.Reflection.FileDescriptorProto.Parser);
private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.FileDescriptorProto> file_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.FileDescriptorProto>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.Reflection.FileDescriptorProto> File {
get { return file_; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as FileDescriptorSet);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(FileDescriptorSet other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -218,26 +233,31 @@ namespace Google.Protobuf.Reflection {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
hash ^= file_.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
file_.WriteTo(output, _repeated_file_codec);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
size += file_.CalculateSize(_repeated_file_codec);
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(FileDescriptorSet other) {
if (other == null) {
return;
@@ -245,6 +265,7 @@ namespace Google.Protobuf.Reflection {
file_.Add(other.file_);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -265,25 +286,29 @@ namespace Google.Protobuf.Reflection {
/// <summary>
/// Describes a complete .proto file.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
internal sealed partial class FileDescriptorProto : pb::IMessage<FileDescriptorProto> {
private static readonly pb::MessageParser<FileDescriptorProto> _parser = new pb::MessageParser<FileDescriptorProto>(() => new FileDescriptorProto());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<FileDescriptorProto> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[1]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public FileDescriptorProto() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public FileDescriptorProto(FileDescriptorProto other) : this() {
name_ = other.name_;
package_ = other.package_;
@@ -299,6 +324,7 @@ namespace Google.Protobuf.Reflection {
syntax_ = other.syntax_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public FileDescriptorProto Clone() {
return new FileDescriptorProto(this);
}
@@ -309,10 +335,11 @@ namespace Google.Protobuf.Reflection {
/// <summary>
/// file name, relative to root of source tree
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string Name {
get { return name_; }
set {
- name_ = pb::Preconditions.CheckNotNull(value, "value");
+ name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -322,10 +349,11 @@ namespace Google.Protobuf.Reflection {
/// <summary>
/// e.g. "foo", "foo.bar", etc.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string Package {
get { return package_; }
set {
- package_ = pb::Preconditions.CheckNotNull(value, "value");
+ package_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -337,6 +365,7 @@ namespace Google.Protobuf.Reflection {
/// <summary>
/// Names of files imported by this file.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<string> Dependency {
get { return dependency_; }
}
@@ -349,6 +378,7 @@ namespace Google.Protobuf.Reflection {
/// <summary>
/// Indexes of the public imported files in the dependency list above.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<int> PublicDependency {
get { return publicDependency_; }
}
@@ -362,6 +392,7 @@ namespace Google.Protobuf.Reflection {
/// Indexes of the weak imported files in the dependency list.
/// For Google-internal migration only. Do not use.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<int> WeakDependency {
get { return weakDependency_; }
}
@@ -374,6 +405,7 @@ namespace Google.Protobuf.Reflection {
/// <summary>
/// All top-level definitions in this file.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.Reflection.DescriptorProto> MessageType {
get { return messageType_; }
}
@@ -383,6 +415,7 @@ namespace Google.Protobuf.Reflection {
private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.EnumDescriptorProto> _repeated_enumType_codec
= pb::FieldCodec.ForMessage(42, global::Google.Protobuf.Reflection.EnumDescriptorProto.Parser);
private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.EnumDescriptorProto> enumType_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.EnumDescriptorProto>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.Reflection.EnumDescriptorProto> EnumType {
get { return enumType_; }
}
@@ -392,6 +425,7 @@ namespace Google.Protobuf.Reflection {
private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.ServiceDescriptorProto> _repeated_service_codec
= pb::FieldCodec.ForMessage(50, global::Google.Protobuf.Reflection.ServiceDescriptorProto.Parser);
private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.ServiceDescriptorProto> service_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.ServiceDescriptorProto>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.Reflection.ServiceDescriptorProto> Service {
get { return service_; }
}
@@ -401,6 +435,7 @@ namespace Google.Protobuf.Reflection {
private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.FieldDescriptorProto> _repeated_extension_codec
= pb::FieldCodec.ForMessage(58, global::Google.Protobuf.Reflection.FieldDescriptorProto.Parser);
private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.FieldDescriptorProto> extension_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.FieldDescriptorProto>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.Reflection.FieldDescriptorProto> Extension {
get { return extension_; }
}
@@ -408,6 +443,7 @@ namespace Google.Protobuf.Reflection {
/// <summary>Field number for the "options" field.</summary>
public const int OptionsFieldNumber = 8;
private global::Google.Protobuf.Reflection.FileOptions options_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.Reflection.FileOptions Options {
get { return options_; }
set {
@@ -424,6 +460,7 @@ namespace Google.Protobuf.Reflection {
/// functionality of the descriptors -- the information is needed only by
/// development tools.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.Reflection.SourceCodeInfo SourceCodeInfo {
get { return sourceCodeInfo_; }
set {
@@ -438,17 +475,20 @@ namespace Google.Protobuf.Reflection {
/// The syntax of the proto file.
/// The supported values are "proto2" and "proto3".
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string Syntax {
get { return syntax_; }
set {
- syntax_ = pb::Preconditions.CheckNotNull(value, "value");
+ syntax_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as FileDescriptorProto);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(FileDescriptorProto other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -471,6 +511,7 @@ namespace Google.Protobuf.Reflection {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Name.Length != 0) hash ^= Name.GetHashCode();
@@ -488,10 +529,12 @@ namespace Google.Protobuf.Reflection {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Name.Length != 0) {
output.WriteRawTag(10);
@@ -522,6 +565,7 @@ namespace Google.Protobuf.Reflection {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Name.Length != 0) {
@@ -549,6 +593,7 @@ namespace Google.Protobuf.Reflection {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(FileDescriptorProto other) {
if (other == null) {
return;
@@ -583,6 +628,7 @@ namespace Google.Protobuf.Reflection {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -655,25 +701,29 @@ namespace Google.Protobuf.Reflection {
/// <summary>
/// Describes a message type.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
internal sealed partial class DescriptorProto : pb::IMessage<DescriptorProto> {
private static readonly pb::MessageParser<DescriptorProto> _parser = new pb::MessageParser<DescriptorProto>(() => new DescriptorProto());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<DescriptorProto> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[2]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public DescriptorProto() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public DescriptorProto(DescriptorProto other) : this() {
name_ = other.name_;
field_ = other.field_.Clone();
@@ -687,6 +737,7 @@ namespace Google.Protobuf.Reflection {
reservedName_ = other.reservedName_.Clone();
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public DescriptorProto Clone() {
return new DescriptorProto(this);
}
@@ -694,10 +745,11 @@ namespace Google.Protobuf.Reflection {
/// <summary>Field number for the "name" field.</summary>
public const int NameFieldNumber = 1;
private string name_ = "";
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string Name {
get { return name_; }
set {
- name_ = pb::Preconditions.CheckNotNull(value, "value");
+ name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -706,6 +758,7 @@ namespace Google.Protobuf.Reflection {
private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.FieldDescriptorProto> _repeated_field_codec
= pb::FieldCodec.ForMessage(18, global::Google.Protobuf.Reflection.FieldDescriptorProto.Parser);
private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.FieldDescriptorProto> field_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.FieldDescriptorProto>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.Reflection.FieldDescriptorProto> Field {
get { return field_; }
}
@@ -715,6 +768,7 @@ namespace Google.Protobuf.Reflection {
private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.FieldDescriptorProto> _repeated_extension_codec
= pb::FieldCodec.ForMessage(50, global::Google.Protobuf.Reflection.FieldDescriptorProto.Parser);
private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.FieldDescriptorProto> extension_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.FieldDescriptorProto>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.Reflection.FieldDescriptorProto> Extension {
get { return extension_; }
}
@@ -724,6 +778,7 @@ namespace Google.Protobuf.Reflection {
private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.DescriptorProto> _repeated_nestedType_codec
= pb::FieldCodec.ForMessage(26, global::Google.Protobuf.Reflection.DescriptorProto.Parser);
private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.DescriptorProto> nestedType_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.DescriptorProto>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.Reflection.DescriptorProto> NestedType {
get { return nestedType_; }
}
@@ -733,6 +788,7 @@ namespace Google.Protobuf.Reflection {
private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.EnumDescriptorProto> _repeated_enumType_codec
= pb::FieldCodec.ForMessage(34, global::Google.Protobuf.Reflection.EnumDescriptorProto.Parser);
private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.EnumDescriptorProto> enumType_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.EnumDescriptorProto>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.Reflection.EnumDescriptorProto> EnumType {
get { return enumType_; }
}
@@ -742,6 +798,7 @@ namespace Google.Protobuf.Reflection {
private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.DescriptorProto.Types.ExtensionRange> _repeated_extensionRange_codec
= pb::FieldCodec.ForMessage(42, global::Google.Protobuf.Reflection.DescriptorProto.Types.ExtensionRange.Parser);
private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.DescriptorProto.Types.ExtensionRange> extensionRange_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.DescriptorProto.Types.ExtensionRange>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.Reflection.DescriptorProto.Types.ExtensionRange> ExtensionRange {
get { return extensionRange_; }
}
@@ -751,6 +808,7 @@ namespace Google.Protobuf.Reflection {
private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.OneofDescriptorProto> _repeated_oneofDecl_codec
= pb::FieldCodec.ForMessage(66, global::Google.Protobuf.Reflection.OneofDescriptorProto.Parser);
private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.OneofDescriptorProto> oneofDecl_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.OneofDescriptorProto>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.Reflection.OneofDescriptorProto> OneofDecl {
get { return oneofDecl_; }
}
@@ -758,6 +816,7 @@ namespace Google.Protobuf.Reflection {
/// <summary>Field number for the "options" field.</summary>
public const int OptionsFieldNumber = 7;
private global::Google.Protobuf.Reflection.MessageOptions options_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.Reflection.MessageOptions Options {
get { return options_; }
set {
@@ -770,6 +829,7 @@ namespace Google.Protobuf.Reflection {
private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.DescriptorProto.Types.ReservedRange> _repeated_reservedRange_codec
= pb::FieldCodec.ForMessage(74, global::Google.Protobuf.Reflection.DescriptorProto.Types.ReservedRange.Parser);
private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.DescriptorProto.Types.ReservedRange> reservedRange_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.DescriptorProto.Types.ReservedRange>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.Reflection.DescriptorProto.Types.ReservedRange> ReservedRange {
get { return reservedRange_; }
}
@@ -783,14 +843,17 @@ namespace Google.Protobuf.Reflection {
/// Reserved field names, which may not be used by fields in the same message.
/// A given name may only be reserved once.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<string> ReservedName {
get { return reservedName_; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as DescriptorProto);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(DescriptorProto other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -811,6 +874,7 @@ namespace Google.Protobuf.Reflection {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Name.Length != 0) hash ^= Name.GetHashCode();
@@ -826,10 +890,12 @@ namespace Google.Protobuf.Reflection {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Name.Length != 0) {
output.WriteRawTag(10);
@@ -849,6 +915,7 @@ namespace Google.Protobuf.Reflection {
reservedName_.WriteTo(output, _repeated_reservedName_codec);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Name.Length != 0) {
@@ -868,6 +935,7 @@ namespace Google.Protobuf.Reflection {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(DescriptorProto other) {
if (other == null) {
return;
@@ -891,6 +959,7 @@ namespace Google.Protobuf.Reflection {
reservedName_.Add(other.reservedName_);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -947,32 +1016,37 @@ namespace Google.Protobuf.Reflection {
#region Nested types
/// <summary>Container for nested types declared in the DescriptorProto message type.</summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static partial class Types {
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
internal sealed partial class ExtensionRange : pb::IMessage<ExtensionRange> {
private static readonly pb::MessageParser<ExtensionRange> _parser = new pb::MessageParser<ExtensionRange>(() => new ExtensionRange());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<ExtensionRange> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.Reflection.DescriptorProto.Descriptor.NestedTypes[0]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ExtensionRange() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ExtensionRange(ExtensionRange other) : this() {
start_ = other.start_;
end_ = other.end_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ExtensionRange Clone() {
return new ExtensionRange(this);
}
@@ -980,6 +1054,7 @@ namespace Google.Protobuf.Reflection {
/// <summary>Field number for the "start" field.</summary>
public const int StartFieldNumber = 1;
private int start_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int Start {
get { return start_; }
set {
@@ -990,6 +1065,7 @@ namespace Google.Protobuf.Reflection {
/// <summary>Field number for the "end" field.</summary>
public const int EndFieldNumber = 2;
private int end_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int End {
get { return end_; }
set {
@@ -997,10 +1073,12 @@ namespace Google.Protobuf.Reflection {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as ExtensionRange);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(ExtensionRange other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -1013,6 +1091,7 @@ namespace Google.Protobuf.Reflection {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Start != 0) hash ^= Start.GetHashCode();
@@ -1020,10 +1099,12 @@ namespace Google.Protobuf.Reflection {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Start != 0) {
output.WriteRawTag(8);
@@ -1035,6 +1116,7 @@ namespace Google.Protobuf.Reflection {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Start != 0) {
@@ -1046,6 +1128,7 @@ namespace Google.Protobuf.Reflection {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(ExtensionRange other) {
if (other == null) {
return;
@@ -1058,6 +1141,7 @@ namespace Google.Protobuf.Reflection {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -1084,30 +1168,35 @@ namespace Google.Protobuf.Reflection {
/// fields or extension ranges in the same message. Reserved ranges may
/// not overlap.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
internal sealed partial class ReservedRange : pb::IMessage<ReservedRange> {
private static readonly pb::MessageParser<ReservedRange> _parser = new pb::MessageParser<ReservedRange>(() => new ReservedRange());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<ReservedRange> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.Reflection.DescriptorProto.Descriptor.NestedTypes[1]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ReservedRange() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ReservedRange(ReservedRange other) : this() {
start_ = other.start_;
end_ = other.end_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ReservedRange Clone() {
return new ReservedRange(this);
}
@@ -1118,6 +1207,7 @@ namespace Google.Protobuf.Reflection {
/// <summary>
/// Inclusive.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int Start {
get { return start_; }
set {
@@ -1131,6 +1221,7 @@ namespace Google.Protobuf.Reflection {
/// <summary>
/// Exclusive.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int End {
get { return end_; }
set {
@@ -1138,10 +1229,12 @@ namespace Google.Protobuf.Reflection {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as ReservedRange);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(ReservedRange other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -1154,6 +1247,7 @@ namespace Google.Protobuf.Reflection {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Start != 0) hash ^= Start.GetHashCode();
@@ -1161,10 +1255,12 @@ namespace Google.Protobuf.Reflection {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Start != 0) {
output.WriteRawTag(8);
@@ -1176,6 +1272,7 @@ namespace Google.Protobuf.Reflection {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Start != 0) {
@@ -1187,6 +1284,7 @@ namespace Google.Protobuf.Reflection {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(ReservedRange other) {
if (other == null) {
return;
@@ -1199,6 +1297,7 @@ namespace Google.Protobuf.Reflection {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -1228,25 +1327,29 @@ namespace Google.Protobuf.Reflection {
/// <summary>
/// Describes a field within a message.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
internal sealed partial class FieldDescriptorProto : pb::IMessage<FieldDescriptorProto> {
private static readonly pb::MessageParser<FieldDescriptorProto> _parser = new pb::MessageParser<FieldDescriptorProto>(() => new FieldDescriptorProto());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<FieldDescriptorProto> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[3]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public FieldDescriptorProto() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public FieldDescriptorProto(FieldDescriptorProto other) : this() {
name_ = other.name_;
number_ = other.number_;
@@ -1260,6 +1363,7 @@ namespace Google.Protobuf.Reflection {
Options = other.options_ != null ? other.Options.Clone() : null;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public FieldDescriptorProto Clone() {
return new FieldDescriptorProto(this);
}
@@ -1267,16 +1371,18 @@ namespace Google.Protobuf.Reflection {
/// <summary>Field number for the "name" field.</summary>
public const int NameFieldNumber = 1;
private string name_ = "";
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string Name {
get { return name_; }
set {
- name_ = pb::Preconditions.CheckNotNull(value, "value");
+ name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
/// <summary>Field number for the "number" field.</summary>
public const int NumberFieldNumber = 3;
private int number_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int Number {
get { return number_; }
set {
@@ -1286,7 +1392,8 @@ namespace Google.Protobuf.Reflection {
/// <summary>Field number for the "label" field.</summary>
public const int LabelFieldNumber = 4;
- private global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Label label_ = global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Label.LABEL_OPTIONAL;
+ private global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Label label_ = 0;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Label Label {
get { return label_; }
set {
@@ -1296,11 +1403,12 @@ namespace Google.Protobuf.Reflection {
/// <summary>Field number for the "type" field.</summary>
public const int TypeFieldNumber = 5;
- private global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Type type_ = global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Type.TYPE_DOUBLE;
+ private global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Type type_ = 0;
/// <summary>
/// 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.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Type Type {
get { return type_; }
set {
@@ -1318,10 +1426,11 @@ namespace Google.Protobuf.Reflection {
/// message are searched, then within the parent, on up to the root
/// namespace).
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string TypeName {
get { return typeName_; }
set {
- typeName_ = pb::Preconditions.CheckNotNull(value, "value");
+ typeName_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -1332,10 +1441,11 @@ namespace Google.Protobuf.Reflection {
/// For extensions, this is the name of the type being extended. It is
/// resolved in the same manner as type_name.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string Extendee {
get { return extendee_; }
set {
- extendee_ = pb::Preconditions.CheckNotNull(value, "value");
+ extendee_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -1349,10 +1459,11 @@ namespace Google.Protobuf.Reflection {
/// For bytes, contains the C escaped value. All bytes >= 128 are escaped.
/// TODO(kenton): Base-64 encode?
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string DefaultValue {
get { return defaultValue_; }
set {
- defaultValue_ = pb::Preconditions.CheckNotNull(value, "value");
+ defaultValue_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -1363,6 +1474,7 @@ namespace Google.Protobuf.Reflection {
/// If set, gives the index of a oneof in the containing type's oneof_decl
/// list. This field is a member of that oneof.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int OneofIndex {
get { return oneofIndex_; }
set {
@@ -1379,16 +1491,18 @@ namespace Google.Protobuf.Reflection {
/// will be used. Otherwise, it's deduced from the field's name by converting
/// it to camelCase.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string JsonName {
get { return jsonName_; }
set {
- jsonName_ = pb::Preconditions.CheckNotNull(value, "value");
+ jsonName_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
/// <summary>Field number for the "options" field.</summary>
public const int OptionsFieldNumber = 8;
private global::Google.Protobuf.Reflection.FieldOptions options_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.Reflection.FieldOptions Options {
get { return options_; }
set {
@@ -1396,10 +1510,12 @@ namespace Google.Protobuf.Reflection {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as FieldDescriptorProto);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(FieldDescriptorProto other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -1420,12 +1536,13 @@ namespace Google.Protobuf.Reflection {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Name.Length != 0) hash ^= Name.GetHashCode();
if (Number != 0) hash ^= Number.GetHashCode();
- if (Label != global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Label.LABEL_OPTIONAL) hash ^= Label.GetHashCode();
- if (Type != global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Type.TYPE_DOUBLE) hash ^= Type.GetHashCode();
+ if (Label != 0) hash ^= Label.GetHashCode();
+ if (Type != 0) hash ^= Type.GetHashCode();
if (TypeName.Length != 0) hash ^= TypeName.GetHashCode();
if (Extendee.Length != 0) hash ^= Extendee.GetHashCode();
if (DefaultValue.Length != 0) hash ^= DefaultValue.GetHashCode();
@@ -1435,10 +1552,12 @@ namespace Google.Protobuf.Reflection {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Name.Length != 0) {
output.WriteRawTag(10);
@@ -1452,11 +1571,11 @@ namespace Google.Protobuf.Reflection {
output.WriteRawTag(24);
output.WriteInt32(Number);
}
- if (Label != global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Label.LABEL_OPTIONAL) {
+ if (Label != 0) {
output.WriteRawTag(32);
output.WriteEnum((int) Label);
}
- if (Type != global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Type.TYPE_DOUBLE) {
+ if (Type != 0) {
output.WriteRawTag(40);
output.WriteEnum((int) Type);
}
@@ -1482,6 +1601,7 @@ namespace Google.Protobuf.Reflection {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Name.Length != 0) {
@@ -1490,10 +1610,10 @@ namespace Google.Protobuf.Reflection {
if (Number != 0) {
size += 1 + pb::CodedOutputStream.ComputeInt32Size(Number);
}
- if (Label != global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Label.LABEL_OPTIONAL) {
+ if (Label != 0) {
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Label);
}
- if (Type != global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Type.TYPE_DOUBLE) {
+ if (Type != 0) {
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Type);
}
if (TypeName.Length != 0) {
@@ -1517,6 +1637,7 @@ namespace Google.Protobuf.Reflection {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(FieldDescriptorProto other) {
if (other == null) {
return;
@@ -1527,10 +1648,10 @@ namespace Google.Protobuf.Reflection {
if (other.Number != 0) {
Number = other.Number;
}
- if (other.Label != global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Label.LABEL_OPTIONAL) {
+ if (other.Label != 0) {
Label = other.Label;
}
- if (other.Type != global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Type.TYPE_DOUBLE) {
+ if (other.Type != 0) {
Type = other.Type;
}
if (other.TypeName.Length != 0) {
@@ -1556,6 +1677,7 @@ namespace Google.Protobuf.Reflection {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -1612,66 +1734,66 @@ namespace Google.Protobuf.Reflection {
#region Nested types
/// <summary>Container for nested types declared in the FieldDescriptorProto message type.</summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static partial class Types {
internal enum Type {
/// <summary>
/// 0 is reserved for errors.
/// Order is weird for historical reasons.
/// </summary>
- TYPE_DOUBLE = 1,
- TYPE_FLOAT = 2,
+ [pbr::OriginalName("TYPE_DOUBLE")] Double = 1,
+ [pbr::OriginalName("TYPE_FLOAT")] Float = 2,
/// <summary>
/// Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT64 if
/// negative values are likely.
/// </summary>
- TYPE_INT64 = 3,
- TYPE_UINT64 = 4,
+ [pbr::OriginalName("TYPE_INT64")] Int64 = 3,
+ [pbr::OriginalName("TYPE_UINT64")] Uint64 = 4,
/// <summary>
/// Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT32 if
/// negative values are likely.
/// </summary>
- TYPE_INT32 = 5,
- TYPE_FIXED64 = 6,
- TYPE_FIXED32 = 7,
- TYPE_BOOL = 8,
- TYPE_STRING = 9,
+ [pbr::OriginalName("TYPE_INT32")] Int32 = 5,
+ [pbr::OriginalName("TYPE_FIXED64")] Fixed64 = 6,
+ [pbr::OriginalName("TYPE_FIXED32")] Fixed32 = 7,
+ [pbr::OriginalName("TYPE_BOOL")] Bool = 8,
+ [pbr::OriginalName("TYPE_STRING")] String = 9,
/// <summary>
/// Tag-delimited aggregate.
/// </summary>
- TYPE_GROUP = 10,
+ [pbr::OriginalName("TYPE_GROUP")] Group = 10,
/// <summary>
/// Length-delimited aggregate.
/// </summary>
- TYPE_MESSAGE = 11,
+ [pbr::OriginalName("TYPE_MESSAGE")] Message = 11,
/// <summary>
/// New in version 2.
/// </summary>
- TYPE_BYTES = 12,
- TYPE_UINT32 = 13,
- TYPE_ENUM = 14,
- TYPE_SFIXED32 = 15,
- TYPE_SFIXED64 = 16,
+ [pbr::OriginalName("TYPE_BYTES")] Bytes = 12,
+ [pbr::OriginalName("TYPE_UINT32")] Uint32 = 13,
+ [pbr::OriginalName("TYPE_ENUM")] Enum = 14,
+ [pbr::OriginalName("TYPE_SFIXED32")] Sfixed32 = 15,
+ [pbr::OriginalName("TYPE_SFIXED64")] Sfixed64 = 16,
/// <summary>
/// Uses ZigZag encoding.
/// </summary>
- TYPE_SINT32 = 17,
+ [pbr::OriginalName("TYPE_SINT32")] Sint32 = 17,
/// <summary>
/// Uses ZigZag encoding.
/// </summary>
- TYPE_SINT64 = 18,
+ [pbr::OriginalName("TYPE_SINT64")] Sint64 = 18,
}
internal enum Label {
/// <summary>
/// 0 is reserved for errors
/// </summary>
- LABEL_OPTIONAL = 1,
- LABEL_REQUIRED = 2,
+ [pbr::OriginalName("LABEL_OPTIONAL")] Optional = 1,
+ [pbr::OriginalName("LABEL_REQUIRED")] Required = 2,
/// <summary>
/// TODO(sanjay): Should we add LABEL_MAP?
/// </summary>
- LABEL_REPEATED = 3,
+ [pbr::OriginalName("LABEL_REPEATED")] Repeated = 3,
}
}
@@ -1682,29 +1804,35 @@ namespace Google.Protobuf.Reflection {
/// <summary>
/// Describes a oneof.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
internal sealed partial class OneofDescriptorProto : pb::IMessage<OneofDescriptorProto> {
private static readonly pb::MessageParser<OneofDescriptorProto> _parser = new pb::MessageParser<OneofDescriptorProto>(() => new OneofDescriptorProto());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<OneofDescriptorProto> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[4]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public OneofDescriptorProto() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public OneofDescriptorProto(OneofDescriptorProto other) : this() {
name_ = other.name_;
+ Options = other.options_ != null ? other.Options.Clone() : null;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public OneofDescriptorProto Clone() {
return new OneofDescriptorProto(this);
}
@@ -1712,17 +1840,31 @@ namespace Google.Protobuf.Reflection {
/// <summary>Field number for the "name" field.</summary>
public const int NameFieldNumber = 1;
private string name_ = "";
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string Name {
get { return name_; }
set {
- name_ = pb::Preconditions.CheckNotNull(value, "value");
+ name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
+ /// <summary>Field number for the "options" field.</summary>
+ public const int OptionsFieldNumber = 2;
+ private global::Google.Protobuf.Reflection.OneofOptions options_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public global::Google.Protobuf.Reflection.OneofOptions Options {
+ get { return options_; }
+ set {
+ options_ = value;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as OneofDescriptorProto);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(OneofDescriptorProto other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -1731,34 +1873,48 @@ namespace Google.Protobuf.Reflection {
return true;
}
if (Name != other.Name) return false;
+ if (!object.Equals(Options, other.Options)) return false;
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Name.Length != 0) hash ^= Name.GetHashCode();
+ if (options_ != null) hash ^= Options.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Name.Length != 0) {
output.WriteRawTag(10);
output.WriteString(Name);
}
+ if (options_ != null) {
+ output.WriteRawTag(18);
+ output.WriteMessage(Options);
+ }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Name.Length != 0) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
}
+ if (options_ != null) {
+ size += 1 + pb::CodedOutputStream.ComputeMessageSize(Options);
+ }
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(OneofDescriptorProto other) {
if (other == null) {
return;
@@ -1766,8 +1922,15 @@ namespace Google.Protobuf.Reflection {
if (other.Name.Length != 0) {
Name = other.Name;
}
+ if (other.options_ != null) {
+ if (options_ == null) {
+ options_ = new global::Google.Protobuf.Reflection.OneofOptions();
+ }
+ Options.MergeFrom(other.Options);
+ }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -1779,6 +1942,13 @@ namespace Google.Protobuf.Reflection {
Name = input.ReadString();
break;
}
+ case 18: {
+ if (options_ == null) {
+ options_ = new global::Google.Protobuf.Reflection.OneofOptions();
+ }
+ input.ReadMessage(options_);
+ break;
+ }
}
}
}
@@ -1788,31 +1958,36 @@ namespace Google.Protobuf.Reflection {
/// <summary>
/// Describes an enum type.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
internal sealed partial class EnumDescriptorProto : pb::IMessage<EnumDescriptorProto> {
private static readonly pb::MessageParser<EnumDescriptorProto> _parser = new pb::MessageParser<EnumDescriptorProto>(() => new EnumDescriptorProto());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<EnumDescriptorProto> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[5]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public EnumDescriptorProto() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public EnumDescriptorProto(EnumDescriptorProto other) : this() {
name_ = other.name_;
value_ = other.value_.Clone();
Options = other.options_ != null ? other.Options.Clone() : null;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public EnumDescriptorProto Clone() {
return new EnumDescriptorProto(this);
}
@@ -1820,10 +1995,11 @@ namespace Google.Protobuf.Reflection {
/// <summary>Field number for the "name" field.</summary>
public const int NameFieldNumber = 1;
private string name_ = "";
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string Name {
get { return name_; }
set {
- name_ = pb::Preconditions.CheckNotNull(value, "value");
+ name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -1832,6 +2008,7 @@ namespace Google.Protobuf.Reflection {
private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.EnumValueDescriptorProto> _repeated_value_codec
= pb::FieldCodec.ForMessage(18, global::Google.Protobuf.Reflection.EnumValueDescriptorProto.Parser);
private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.EnumValueDescriptorProto> value_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.EnumValueDescriptorProto>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.Reflection.EnumValueDescriptorProto> Value {
get { return value_; }
}
@@ -1839,6 +2016,7 @@ namespace Google.Protobuf.Reflection {
/// <summary>Field number for the "options" field.</summary>
public const int OptionsFieldNumber = 3;
private global::Google.Protobuf.Reflection.EnumOptions options_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.Reflection.EnumOptions Options {
get { return options_; }
set {
@@ -1846,10 +2024,12 @@ namespace Google.Protobuf.Reflection {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as EnumDescriptorProto);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(EnumDescriptorProto other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -1863,6 +2043,7 @@ namespace Google.Protobuf.Reflection {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Name.Length != 0) hash ^= Name.GetHashCode();
@@ -1871,10 +2052,12 @@ namespace Google.Protobuf.Reflection {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Name.Length != 0) {
output.WriteRawTag(10);
@@ -1887,6 +2070,7 @@ namespace Google.Protobuf.Reflection {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Name.Length != 0) {
@@ -1899,6 +2083,7 @@ namespace Google.Protobuf.Reflection {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(EnumDescriptorProto other) {
if (other == null) {
return;
@@ -1915,6 +2100,7 @@ namespace Google.Protobuf.Reflection {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -1946,31 +2132,36 @@ namespace Google.Protobuf.Reflection {
/// <summary>
/// Describes a value within an enum.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
internal sealed partial class EnumValueDescriptorProto : pb::IMessage<EnumValueDescriptorProto> {
private static readonly pb::MessageParser<EnumValueDescriptorProto> _parser = new pb::MessageParser<EnumValueDescriptorProto>(() => new EnumValueDescriptorProto());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<EnumValueDescriptorProto> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[6]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public EnumValueDescriptorProto() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public EnumValueDescriptorProto(EnumValueDescriptorProto other) : this() {
name_ = other.name_;
number_ = other.number_;
Options = other.options_ != null ? other.Options.Clone() : null;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public EnumValueDescriptorProto Clone() {
return new EnumValueDescriptorProto(this);
}
@@ -1978,16 +2169,18 @@ namespace Google.Protobuf.Reflection {
/// <summary>Field number for the "name" field.</summary>
public const int NameFieldNumber = 1;
private string name_ = "";
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string Name {
get { return name_; }
set {
- name_ = pb::Preconditions.CheckNotNull(value, "value");
+ name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
/// <summary>Field number for the "number" field.</summary>
public const int NumberFieldNumber = 2;
private int number_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int Number {
get { return number_; }
set {
@@ -1998,6 +2191,7 @@ namespace Google.Protobuf.Reflection {
/// <summary>Field number for the "options" field.</summary>
public const int OptionsFieldNumber = 3;
private global::Google.Protobuf.Reflection.EnumValueOptions options_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.Reflection.EnumValueOptions Options {
get { return options_; }
set {
@@ -2005,10 +2199,12 @@ namespace Google.Protobuf.Reflection {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as EnumValueDescriptorProto);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(EnumValueDescriptorProto other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -2022,6 +2218,7 @@ namespace Google.Protobuf.Reflection {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Name.Length != 0) hash ^= Name.GetHashCode();
@@ -2030,10 +2227,12 @@ namespace Google.Protobuf.Reflection {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Name.Length != 0) {
output.WriteRawTag(10);
@@ -2049,6 +2248,7 @@ namespace Google.Protobuf.Reflection {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Name.Length != 0) {
@@ -2063,6 +2263,7 @@ namespace Google.Protobuf.Reflection {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(EnumValueDescriptorProto other) {
if (other == null) {
return;
@@ -2081,6 +2282,7 @@ namespace Google.Protobuf.Reflection {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -2112,31 +2314,36 @@ namespace Google.Protobuf.Reflection {
/// <summary>
/// Describes a service.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
internal sealed partial class ServiceDescriptorProto : pb::IMessage<ServiceDescriptorProto> {
private static readonly pb::MessageParser<ServiceDescriptorProto> _parser = new pb::MessageParser<ServiceDescriptorProto>(() => new ServiceDescriptorProto());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<ServiceDescriptorProto> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[7]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ServiceDescriptorProto() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ServiceDescriptorProto(ServiceDescriptorProto other) : this() {
name_ = other.name_;
method_ = other.method_.Clone();
Options = other.options_ != null ? other.Options.Clone() : null;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ServiceDescriptorProto Clone() {
return new ServiceDescriptorProto(this);
}
@@ -2144,10 +2351,11 @@ namespace Google.Protobuf.Reflection {
/// <summary>Field number for the "name" field.</summary>
public const int NameFieldNumber = 1;
private string name_ = "";
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string Name {
get { return name_; }
set {
- name_ = pb::Preconditions.CheckNotNull(value, "value");
+ name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -2156,6 +2364,7 @@ namespace Google.Protobuf.Reflection {
private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.MethodDescriptorProto> _repeated_method_codec
= pb::FieldCodec.ForMessage(18, global::Google.Protobuf.Reflection.MethodDescriptorProto.Parser);
private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.MethodDescriptorProto> method_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.MethodDescriptorProto>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.Reflection.MethodDescriptorProto> Method {
get { return method_; }
}
@@ -2163,6 +2372,7 @@ namespace Google.Protobuf.Reflection {
/// <summary>Field number for the "options" field.</summary>
public const int OptionsFieldNumber = 3;
private global::Google.Protobuf.Reflection.ServiceOptions options_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.Reflection.ServiceOptions Options {
get { return options_; }
set {
@@ -2170,10 +2380,12 @@ namespace Google.Protobuf.Reflection {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as ServiceDescriptorProto);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(ServiceDescriptorProto other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -2187,6 +2399,7 @@ namespace Google.Protobuf.Reflection {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Name.Length != 0) hash ^= Name.GetHashCode();
@@ -2195,10 +2408,12 @@ namespace Google.Protobuf.Reflection {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Name.Length != 0) {
output.WriteRawTag(10);
@@ -2211,6 +2426,7 @@ namespace Google.Protobuf.Reflection {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Name.Length != 0) {
@@ -2223,6 +2439,7 @@ namespace Google.Protobuf.Reflection {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(ServiceDescriptorProto other) {
if (other == null) {
return;
@@ -2239,6 +2456,7 @@ namespace Google.Protobuf.Reflection {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -2270,25 +2488,29 @@ namespace Google.Protobuf.Reflection {
/// <summary>
/// Describes a method of a service.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
internal sealed partial class MethodDescriptorProto : pb::IMessage<MethodDescriptorProto> {
private static readonly pb::MessageParser<MethodDescriptorProto> _parser = new pb::MessageParser<MethodDescriptorProto>(() => new MethodDescriptorProto());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<MethodDescriptorProto> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[8]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public MethodDescriptorProto() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public MethodDescriptorProto(MethodDescriptorProto other) : this() {
name_ = other.name_;
inputType_ = other.inputType_;
@@ -2298,6 +2520,7 @@ namespace Google.Protobuf.Reflection {
serverStreaming_ = other.serverStreaming_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public MethodDescriptorProto Clone() {
return new MethodDescriptorProto(this);
}
@@ -2305,10 +2528,11 @@ namespace Google.Protobuf.Reflection {
/// <summary>Field number for the "name" field.</summary>
public const int NameFieldNumber = 1;
private string name_ = "";
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string Name {
get { return name_; }
set {
- name_ = pb::Preconditions.CheckNotNull(value, "value");
+ name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -2319,26 +2543,29 @@ namespace Google.Protobuf.Reflection {
/// Input and output type names. These are resolved in the same way as
/// FieldDescriptorProto.type_name, but must refer to a message type.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string InputType {
get { return inputType_; }
set {
- inputType_ = pb::Preconditions.CheckNotNull(value, "value");
+ inputType_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
/// <summary>Field number for the "output_type" field.</summary>
public const int OutputTypeFieldNumber = 3;
private string outputType_ = "";
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string OutputType {
get { return outputType_; }
set {
- outputType_ = pb::Preconditions.CheckNotNull(value, "value");
+ outputType_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
/// <summary>Field number for the "options" field.</summary>
public const int OptionsFieldNumber = 4;
private global::Google.Protobuf.Reflection.MethodOptions options_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.Reflection.MethodOptions Options {
get { return options_; }
set {
@@ -2352,6 +2579,7 @@ namespace Google.Protobuf.Reflection {
/// <summary>
/// Identifies if client streams multiple client messages
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool ClientStreaming {
get { return clientStreaming_; }
set {
@@ -2365,6 +2593,7 @@ namespace Google.Protobuf.Reflection {
/// <summary>
/// Identifies if server streams multiple server messages
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool ServerStreaming {
get { return serverStreaming_; }
set {
@@ -2372,10 +2601,12 @@ namespace Google.Protobuf.Reflection {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as MethodDescriptorProto);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(MethodDescriptorProto other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -2392,6 +2623,7 @@ namespace Google.Protobuf.Reflection {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Name.Length != 0) hash ^= Name.GetHashCode();
@@ -2403,10 +2635,12 @@ namespace Google.Protobuf.Reflection {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Name.Length != 0) {
output.WriteRawTag(10);
@@ -2434,6 +2668,7 @@ namespace Google.Protobuf.Reflection {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Name.Length != 0) {
@@ -2457,6 +2692,7 @@ namespace Google.Protobuf.Reflection {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(MethodDescriptorProto other) {
if (other == null) {
return;
@@ -2484,6 +2720,7 @@ namespace Google.Protobuf.Reflection {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -2524,25 +2761,29 @@ namespace Google.Protobuf.Reflection {
}
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
internal sealed partial class FileOptions : pb::IMessage<FileOptions> {
private static readonly pb::MessageParser<FileOptions> _parser = new pb::MessageParser<FileOptions>(() => new FileOptions());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<FileOptions> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[9]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public FileOptions() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public FileOptions(FileOptions other) : this() {
javaPackage_ = other.javaPackage_;
javaOuterClassname_ = other.javaOuterClassname_;
@@ -2558,10 +2799,10 @@ namespace Google.Protobuf.Reflection {
ccEnableArenas_ = other.ccEnableArenas_;
objcClassPrefix_ = other.objcClassPrefix_;
csharpNamespace_ = other.csharpNamespace_;
- javananoUseDeprecatedPackage_ = other.javananoUseDeprecatedPackage_;
uninterpretedOption_ = other.uninterpretedOption_.Clone();
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public FileOptions Clone() {
return new FileOptions(this);
}
@@ -2575,10 +2816,11 @@ namespace Google.Protobuf.Reflection {
/// inappropriate because proto packages do not normally start with backwards
/// domain names.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string JavaPackage {
get { return javaPackage_; }
set {
- javaPackage_ = pb::Preconditions.CheckNotNull(value, "value");
+ javaPackage_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -2592,10 +2834,11 @@ namespace Google.Protobuf.Reflection {
/// a .proto always translates to a single class, but you may want to
/// explicitly choose the class name).
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string JavaOuterClassname {
get { return javaOuterClassname_; }
set {
- javaOuterClassname_ = pb::Preconditions.CheckNotNull(value, "value");
+ javaOuterClassname_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -2610,6 +2853,7 @@ namespace Google.Protobuf.Reflection {
/// generated to contain the file's getDescriptor() method as well as any
/// top-level extensions defined in the file.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool JavaMultipleFiles {
get { return javaMultipleFiles_; }
set {
@@ -2634,6 +2878,7 @@ namespace Google.Protobuf.Reflection {
/// than object identity. (Implementations should not assume that hashcodes
/// will be consistent across runtimes or versions of the protocol compiler.)
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool JavaGenerateEqualsAndHash {
get { return javaGenerateEqualsAndHash_; }
set {
@@ -2652,6 +2897,7 @@ namespace Google.Protobuf.Reflection {
/// However, an extension field still accepts non-UTF-8 byte sequences.
/// This option has no effect on when used with the lite runtime.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool JavaStringCheckUtf8 {
get { return javaStringCheckUtf8_; }
set {
@@ -2661,7 +2907,8 @@ namespace Google.Protobuf.Reflection {
/// <summary>Field number for the "optimize_for" field.</summary>
public const int OptimizeForFieldNumber = 9;
- private global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode optimizeFor_ = global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode.SPEED;
+ private global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode optimizeFor_ = 0;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode OptimizeFor {
get { return optimizeFor_; }
set {
@@ -2679,10 +2926,11 @@ namespace Google.Protobuf.Reflection {
/// - Otherwise, the package statement in the .proto file, if present.
/// - Otherwise, the basename of the .proto file, without extension.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string GoPackage {
get { return goPackage_; }
set {
- goPackage_ = pb::Preconditions.CheckNotNull(value, "value");
+ goPackage_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -2701,6 +2949,7 @@ namespace Google.Protobuf.Reflection {
/// these default to false. Old code which depends on generic services should
/// explicitly set them to true.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool CcGenericServices {
get { return ccGenericServices_; }
set {
@@ -2711,6 +2960,7 @@ namespace Google.Protobuf.Reflection {
/// <summary>Field number for the "java_generic_services" field.</summary>
public const int JavaGenericServicesFieldNumber = 17;
private bool javaGenericServices_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool JavaGenericServices {
get { return javaGenericServices_; }
set {
@@ -2721,6 +2971,7 @@ namespace Google.Protobuf.Reflection {
/// <summary>Field number for the "py_generic_services" field.</summary>
public const int PyGenericServicesFieldNumber = 18;
private bool pyGenericServices_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool PyGenericServices {
get { return pyGenericServices_; }
set {
@@ -2737,6 +2988,7 @@ namespace Google.Protobuf.Reflection {
/// for everything in the file, or it will be completely ignored; in the very
/// least, this is a formalization for deprecating files.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Deprecated {
get { return deprecated_; }
set {
@@ -2751,6 +3003,7 @@ namespace Google.Protobuf.Reflection {
/// Enables the use of arenas for the proto messages in this file. This applies
/// only to generated classes for C++.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool CcEnableArenas {
get { return ccEnableArenas_; }
set {
@@ -2765,10 +3018,11 @@ namespace Google.Protobuf.Reflection {
/// Sets the objective c class prefix which is prepended to all objective c
/// generated classes from this .proto. There is no default.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string ObjcClassPrefix {
get { return objcClassPrefix_; }
set {
- objcClassPrefix_ = pb::Preconditions.CheckNotNull(value, "value");
+ objcClassPrefix_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -2778,24 +3032,11 @@ namespace Google.Protobuf.Reflection {
/// <summary>
/// Namespace for generated classes; defaults to the package.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string CsharpNamespace {
get { return csharpNamespace_; }
set {
- csharpNamespace_ = pb::Preconditions.CheckNotNull(value, "value");
- }
- }
-
- /// <summary>Field number for the "javanano_use_deprecated_package" field.</summary>
- public const int JavananoUseDeprecatedPackageFieldNumber = 38;
- private bool javananoUseDeprecatedPackage_;
- /// <summary>
- /// Whether the nano proto compiler should generate in the deprecated non-nano
- /// suffixed package.
- /// </summary>
- public bool JavananoUseDeprecatedPackage {
- get { return javananoUseDeprecatedPackage_; }
- set {
- javananoUseDeprecatedPackage_ = value;
+ csharpNamespace_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -2807,14 +3048,17 @@ namespace Google.Protobuf.Reflection {
/// <summary>
/// The parser stores options it doesn't recognize here. See above.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption> UninterpretedOption {
get { return uninterpretedOption_; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as FileOptions);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(FileOptions other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -2836,11 +3080,11 @@ namespace Google.Protobuf.Reflection {
if (CcEnableArenas != other.CcEnableArenas) return false;
if (ObjcClassPrefix != other.ObjcClassPrefix) return false;
if (CsharpNamespace != other.CsharpNamespace) return false;
- if (JavananoUseDeprecatedPackage != other.JavananoUseDeprecatedPackage) return false;
if(!uninterpretedOption_.Equals(other.uninterpretedOption_)) return false;
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (JavaPackage.Length != 0) hash ^= JavaPackage.GetHashCode();
@@ -2848,7 +3092,7 @@ namespace Google.Protobuf.Reflection {
if (JavaMultipleFiles != false) hash ^= JavaMultipleFiles.GetHashCode();
if (JavaGenerateEqualsAndHash != false) hash ^= JavaGenerateEqualsAndHash.GetHashCode();
if (JavaStringCheckUtf8 != false) hash ^= JavaStringCheckUtf8.GetHashCode();
- if (OptimizeFor != global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode.SPEED) hash ^= OptimizeFor.GetHashCode();
+ if (OptimizeFor != 0) hash ^= OptimizeFor.GetHashCode();
if (GoPackage.Length != 0) hash ^= GoPackage.GetHashCode();
if (CcGenericServices != false) hash ^= CcGenericServices.GetHashCode();
if (JavaGenericServices != false) hash ^= JavaGenericServices.GetHashCode();
@@ -2857,15 +3101,16 @@ namespace Google.Protobuf.Reflection {
if (CcEnableArenas != false) hash ^= CcEnableArenas.GetHashCode();
if (ObjcClassPrefix.Length != 0) hash ^= ObjcClassPrefix.GetHashCode();
if (CsharpNamespace.Length != 0) hash ^= CsharpNamespace.GetHashCode();
- if (JavananoUseDeprecatedPackage != false) hash ^= JavananoUseDeprecatedPackage.GetHashCode();
hash ^= uninterpretedOption_.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (JavaPackage.Length != 0) {
output.WriteRawTag(10);
@@ -2875,7 +3120,7 @@ namespace Google.Protobuf.Reflection {
output.WriteRawTag(66);
output.WriteString(JavaOuterClassname);
}
- if (OptimizeFor != global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode.SPEED) {
+ if (OptimizeFor != 0) {
output.WriteRawTag(72);
output.WriteEnum((int) OptimizeFor);
}
@@ -2923,13 +3168,10 @@ namespace Google.Protobuf.Reflection {
output.WriteRawTag(170, 2);
output.WriteString(CsharpNamespace);
}
- if (JavananoUseDeprecatedPackage != false) {
- output.WriteRawTag(176, 2);
- output.WriteBool(JavananoUseDeprecatedPackage);
- }
uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (JavaPackage.Length != 0) {
@@ -2947,7 +3189,7 @@ namespace Google.Protobuf.Reflection {
if (JavaStringCheckUtf8 != false) {
size += 2 + 1;
}
- if (OptimizeFor != global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode.SPEED) {
+ if (OptimizeFor != 0) {
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) OptimizeFor);
}
if (GoPackage.Length != 0) {
@@ -2974,13 +3216,11 @@ namespace Google.Protobuf.Reflection {
if (CsharpNamespace.Length != 0) {
size += 2 + pb::CodedOutputStream.ComputeStringSize(CsharpNamespace);
}
- if (JavananoUseDeprecatedPackage != false) {
- size += 2 + 1;
- }
size += uninterpretedOption_.CalculateSize(_repeated_uninterpretedOption_codec);
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(FileOptions other) {
if (other == null) {
return;
@@ -3000,7 +3240,7 @@ namespace Google.Protobuf.Reflection {
if (other.JavaStringCheckUtf8 != false) {
JavaStringCheckUtf8 = other.JavaStringCheckUtf8;
}
- if (other.OptimizeFor != global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode.SPEED) {
+ if (other.OptimizeFor != 0) {
OptimizeFor = other.OptimizeFor;
}
if (other.GoPackage.Length != 0) {
@@ -3027,12 +3267,10 @@ namespace Google.Protobuf.Reflection {
if (other.CsharpNamespace.Length != 0) {
CsharpNamespace = other.CsharpNamespace;
}
- if (other.JavananoUseDeprecatedPackage != false) {
- JavananoUseDeprecatedPackage = other.JavananoUseDeprecatedPackage;
- }
uninterpretedOption_.Add(other.uninterpretedOption_);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -3096,10 +3334,6 @@ namespace Google.Protobuf.Reflection {
CsharpNamespace = input.ReadString();
break;
}
- case 304: {
- JavananoUseDeprecatedPackage = input.ReadBool();
- break;
- }
case 7994: {
uninterpretedOption_.AddEntriesFrom(input, _repeated_uninterpretedOption_codec);
break;
@@ -3110,7 +3344,7 @@ namespace Google.Protobuf.Reflection {
#region Nested types
/// <summary>Container for nested types declared in the FileOptions message type.</summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static partial class Types {
/// <summary>
/// Generated classes can be optimized for speed or code size.
@@ -3119,15 +3353,15 @@ namespace Google.Protobuf.Reflection {
/// <summary>
/// Generate complete code for parsing, serialization,
/// </summary>
- SPEED = 1,
+ [pbr::OriginalName("SPEED")] Speed = 1,
/// <summary>
/// etc.
/// </summary>
- CODE_SIZE = 2,
+ [pbr::OriginalName("CODE_SIZE")] CodeSize = 2,
/// <summary>
/// Generate code using MessageLite and the lite runtime.
/// </summary>
- LITE_RUNTIME = 3,
+ [pbr::OriginalName("LITE_RUNTIME")] LiteRuntime = 3,
}
}
@@ -3135,25 +3369,29 @@ namespace Google.Protobuf.Reflection {
}
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
internal sealed partial class MessageOptions : pb::IMessage<MessageOptions> {
private static readonly pb::MessageParser<MessageOptions> _parser = new pb::MessageParser<MessageOptions>(() => new MessageOptions());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<MessageOptions> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[10]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public MessageOptions() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public MessageOptions(MessageOptions other) : this() {
messageSetWireFormat_ = other.messageSetWireFormat_;
noStandardDescriptorAccessor_ = other.noStandardDescriptorAccessor_;
@@ -3162,6 +3400,7 @@ namespace Google.Protobuf.Reflection {
uninterpretedOption_ = other.uninterpretedOption_.Clone();
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public MessageOptions Clone() {
return new MessageOptions(this);
}
@@ -3189,6 +3428,7 @@ namespace Google.Protobuf.Reflection {
/// Because this is an option, the above two restrictions are not enforced by
/// the protocol compiler.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool MessageSetWireFormat {
get { return messageSetWireFormat_; }
set {
@@ -3204,6 +3444,7 @@ namespace Google.Protobuf.Reflection {
/// conflict with a field of the same name. This is meant to make migration
/// from proto1 easier; new code should avoid fields named "descriptor".
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool NoStandardDescriptorAccessor {
get { return noStandardDescriptorAccessor_; }
set {
@@ -3220,6 +3461,7 @@ namespace Google.Protobuf.Reflection {
/// for the message, or it will be completely ignored; in the very least,
/// this is a formalization for deprecating messages.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Deprecated {
get { return deprecated_; }
set {
@@ -3253,6 +3495,7 @@ namespace Google.Protobuf.Reflection {
/// instead. The option should only be implicitly set by the proto compiler
/// parser.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool MapEntry {
get { return mapEntry_; }
set {
@@ -3268,14 +3511,17 @@ namespace Google.Protobuf.Reflection {
/// <summary>
/// The parser stores options it doesn't recognize here. See above.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption> UninterpretedOption {
get { return uninterpretedOption_; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as MessageOptions);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(MessageOptions other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -3291,6 +3537,7 @@ namespace Google.Protobuf.Reflection {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (MessageSetWireFormat != false) hash ^= MessageSetWireFormat.GetHashCode();
@@ -3301,10 +3548,12 @@ namespace Google.Protobuf.Reflection {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (MessageSetWireFormat != false) {
output.WriteRawTag(8);
@@ -3325,6 +3574,7 @@ namespace Google.Protobuf.Reflection {
uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (MessageSetWireFormat != false) {
@@ -3343,6 +3593,7 @@ namespace Google.Protobuf.Reflection {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(MessageOptions other) {
if (other == null) {
return;
@@ -3362,6 +3613,7 @@ namespace Google.Protobuf.Reflection {
uninterpretedOption_.Add(other.uninterpretedOption_);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -3395,25 +3647,29 @@ namespace Google.Protobuf.Reflection {
}
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
internal sealed partial class FieldOptions : pb::IMessage<FieldOptions> {
private static readonly pb::MessageParser<FieldOptions> _parser = new pb::MessageParser<FieldOptions>(() => new FieldOptions());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<FieldOptions> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[11]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public FieldOptions() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public FieldOptions(FieldOptions other) : this() {
ctype_ = other.ctype_;
packed_ = other.packed_;
@@ -3424,19 +3680,21 @@ namespace Google.Protobuf.Reflection {
uninterpretedOption_ = other.uninterpretedOption_.Clone();
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public FieldOptions Clone() {
return new FieldOptions(this);
}
/// <summary>Field number for the "ctype" field.</summary>
public const int CtypeFieldNumber = 1;
- private global::Google.Protobuf.Reflection.FieldOptions.Types.CType ctype_ = global::Google.Protobuf.Reflection.FieldOptions.Types.CType.STRING;
+ private global::Google.Protobuf.Reflection.FieldOptions.Types.CType ctype_ = 0;
/// <summary>
/// The ctype option instructs the C++ code generator to use a different
/// representation of the field than it normally would. See the specific
/// options below. This option is not yet implemented in the open source
/// release -- sorry, we'll try to include it in a future version!
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.Reflection.FieldOptions.Types.CType Ctype {
get { return ctype_; }
set {
@@ -3454,6 +3712,7 @@ namespace Google.Protobuf.Reflection {
/// a single length-delimited blob. In proto3, only explicit setting it to
/// false will avoid using packed encoding.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Packed {
get { return packed_; }
set {
@@ -3463,7 +3722,7 @@ namespace Google.Protobuf.Reflection {
/// <summary>Field number for the "jstype" field.</summary>
public const int JstypeFieldNumber = 6;
- private global::Google.Protobuf.Reflection.FieldOptions.Types.JSType jstype_ = global::Google.Protobuf.Reflection.FieldOptions.Types.JSType.JS_NORMAL;
+ private global::Google.Protobuf.Reflection.FieldOptions.Types.JSType jstype_ = 0;
/// <summary>
/// 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
@@ -3475,6 +3734,7 @@ namespace Google.Protobuf.Reflection {
/// This option is an enum to permit additional types to be added,
/// e.g. goog.math.Integer.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.Reflection.FieldOptions.Types.JSType Jstype {
get { return jstype_; }
set {
@@ -3514,6 +3774,7 @@ namespace Google.Protobuf.Reflection {
/// check its required fields, regardless of whether or not the message has
/// been parsed.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Lazy {
get { return lazy_; }
set {
@@ -3530,6 +3791,7 @@ namespace Google.Protobuf.Reflection {
/// for accessors, or it will be completely ignored; in the very least, this
/// is a formalization for deprecating fields.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Deprecated {
get { return deprecated_; }
set {
@@ -3543,6 +3805,7 @@ namespace Google.Protobuf.Reflection {
/// <summary>
/// For Google-internal migration only. Do not use.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Weak {
get { return weak_; }
set {
@@ -3558,14 +3821,17 @@ namespace Google.Protobuf.Reflection {
/// <summary>
/// The parser stores options it doesn't recognize here. See above.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption> UninterpretedOption {
get { return uninterpretedOption_; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as FieldOptions);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(FieldOptions other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -3583,11 +3849,12 @@ namespace Google.Protobuf.Reflection {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
- if (Ctype != global::Google.Protobuf.Reflection.FieldOptions.Types.CType.STRING) hash ^= Ctype.GetHashCode();
+ if (Ctype != 0) hash ^= Ctype.GetHashCode();
if (Packed != false) hash ^= Packed.GetHashCode();
- if (Jstype != global::Google.Protobuf.Reflection.FieldOptions.Types.JSType.JS_NORMAL) hash ^= Jstype.GetHashCode();
+ if (Jstype != 0) hash ^= Jstype.GetHashCode();
if (Lazy != false) hash ^= Lazy.GetHashCode();
if (Deprecated != false) hash ^= Deprecated.GetHashCode();
if (Weak != false) hash ^= Weak.GetHashCode();
@@ -3595,12 +3862,14 @@ namespace Google.Protobuf.Reflection {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
- if (Ctype != global::Google.Protobuf.Reflection.FieldOptions.Types.CType.STRING) {
+ if (Ctype != 0) {
output.WriteRawTag(8);
output.WriteEnum((int) Ctype);
}
@@ -3616,7 +3885,7 @@ namespace Google.Protobuf.Reflection {
output.WriteRawTag(40);
output.WriteBool(Lazy);
}
- if (Jstype != global::Google.Protobuf.Reflection.FieldOptions.Types.JSType.JS_NORMAL) {
+ if (Jstype != 0) {
output.WriteRawTag(48);
output.WriteEnum((int) Jstype);
}
@@ -3627,15 +3896,16 @@ namespace Google.Protobuf.Reflection {
uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
- if (Ctype != global::Google.Protobuf.Reflection.FieldOptions.Types.CType.STRING) {
+ if (Ctype != 0) {
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Ctype);
}
if (Packed != false) {
size += 1 + 1;
}
- if (Jstype != global::Google.Protobuf.Reflection.FieldOptions.Types.JSType.JS_NORMAL) {
+ if (Jstype != 0) {
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Jstype);
}
if (Lazy != false) {
@@ -3651,17 +3921,18 @@ namespace Google.Protobuf.Reflection {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(FieldOptions other) {
if (other == null) {
return;
}
- if (other.Ctype != global::Google.Protobuf.Reflection.FieldOptions.Types.CType.STRING) {
+ if (other.Ctype != 0) {
Ctype = other.Ctype;
}
if (other.Packed != false) {
Packed = other.Packed;
}
- if (other.Jstype != global::Google.Protobuf.Reflection.FieldOptions.Types.JSType.JS_NORMAL) {
+ if (other.Jstype != 0) {
Jstype = other.Jstype;
}
if (other.Lazy != false) {
@@ -3676,6 +3947,7 @@ namespace Google.Protobuf.Reflection {
uninterpretedOption_.Add(other.uninterpretedOption_);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -3717,30 +3989,30 @@ namespace Google.Protobuf.Reflection {
#region Nested types
/// <summary>Container for nested types declared in the FieldOptions message type.</summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static partial class Types {
internal enum CType {
/// <summary>
/// Default mode.
/// </summary>
- STRING = 0,
- CORD = 1,
- STRING_PIECE = 2,
+ [pbr::OriginalName("STRING")] String = 0,
+ [pbr::OriginalName("CORD")] Cord = 1,
+ [pbr::OriginalName("STRING_PIECE")] StringPiece = 2,
}
internal enum JSType {
/// <summary>
/// Use the default type.
/// </summary>
- JS_NORMAL = 0,
+ [pbr::OriginalName("JS_NORMAL")] JsNormal = 0,
/// <summary>
/// Use JavaScript strings.
/// </summary>
- JS_STRING = 1,
+ [pbr::OriginalName("JS_STRING")] JsString = 1,
/// <summary>
/// Use JavaScript numbers.
/// </summary>
- JS_NUMBER = 2,
+ [pbr::OriginalName("JS_NUMBER")] JsNumber = 2,
}
}
@@ -3748,31 +4020,148 @@ namespace Google.Protobuf.Reflection {
}
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ internal sealed partial class OneofOptions : pb::IMessage<OneofOptions> {
+ private static readonly pb::MessageParser<OneofOptions> _parser = new pb::MessageParser<OneofOptions>(() => new OneofOptions());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pb::MessageParser<OneofOptions> Parser { get { return _parser; } }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pbr::MessageDescriptor Descriptor {
+ get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[12]; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ pbr::MessageDescriptor pb::IMessage.Descriptor {
+ get { return Descriptor; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public OneofOptions() {
+ OnConstruction();
+ }
+
+ partial void OnConstruction();
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public OneofOptions(OneofOptions other) : this() {
+ uninterpretedOption_ = other.uninterpretedOption_.Clone();
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public OneofOptions Clone() {
+ return new OneofOptions(this);
+ }
+
+ /// <summary>Field number for the "uninterpreted_option" field.</summary>
+ public const int UninterpretedOptionFieldNumber = 999;
+ private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.UninterpretedOption> _repeated_uninterpretedOption_codec
+ = pb::FieldCodec.ForMessage(7994, global::Google.Protobuf.Reflection.UninterpretedOption.Parser);
+ private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption> uninterpretedOption_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption>();
+ /// <summary>
+ /// The parser stores options it doesn't recognize here. See above.
+ /// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption> UninterpretedOption {
+ get { return uninterpretedOption_; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override bool Equals(object other) {
+ return Equals(other as OneofOptions);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool Equals(OneofOptions other) {
+ if (ReferenceEquals(other, null)) {
+ return false;
+ }
+ if (ReferenceEquals(other, this)) {
+ return true;
+ }
+ if(!uninterpretedOption_.Equals(other.uninterpretedOption_)) return false;
+ return true;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override int GetHashCode() {
+ int hash = 1;
+ hash ^= uninterpretedOption_.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) {
+ uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int CalculateSize() {
+ int size = 0;
+ size += uninterpretedOption_.CalculateSize(_repeated_uninterpretedOption_codec);
+ return size;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(OneofOptions other) {
+ if (other == null) {
+ return;
+ }
+ uninterpretedOption_.Add(other.uninterpretedOption_);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(pb::CodedInputStream input) {
+ uint tag;
+ while ((tag = input.ReadTag()) != 0) {
+ switch(tag) {
+ default:
+ input.SkipLastField();
+ break;
+ case 7994: {
+ uninterpretedOption_.AddEntriesFrom(input, _repeated_uninterpretedOption_codec);
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
internal sealed partial class EnumOptions : pb::IMessage<EnumOptions> {
private static readonly pb::MessageParser<EnumOptions> _parser = new pb::MessageParser<EnumOptions>(() => new EnumOptions());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<EnumOptions> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[12]; }
+ get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[13]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public EnumOptions() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public EnumOptions(EnumOptions other) : this() {
allowAlias_ = other.allowAlias_;
deprecated_ = other.deprecated_;
uninterpretedOption_ = other.uninterpretedOption_.Clone();
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public EnumOptions Clone() {
return new EnumOptions(this);
}
@@ -3784,6 +4173,7 @@ namespace Google.Protobuf.Reflection {
/// Set this option to true to allow mapping different tag names to the same
/// value.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool AllowAlias {
get { return allowAlias_; }
set {
@@ -3800,6 +4190,7 @@ namespace Google.Protobuf.Reflection {
/// for the enum, or it will be completely ignored; in the very least, this
/// is a formalization for deprecating enums.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Deprecated {
get { return deprecated_; }
set {
@@ -3815,14 +4206,17 @@ namespace Google.Protobuf.Reflection {
/// <summary>
/// The parser stores options it doesn't recognize here. See above.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption> UninterpretedOption {
get { return uninterpretedOption_; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as EnumOptions);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(EnumOptions other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -3836,6 +4230,7 @@ namespace Google.Protobuf.Reflection {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (AllowAlias != false) hash ^= AllowAlias.GetHashCode();
@@ -3844,10 +4239,12 @@ namespace Google.Protobuf.Reflection {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (AllowAlias != false) {
output.WriteRawTag(16);
@@ -3860,6 +4257,7 @@ namespace Google.Protobuf.Reflection {
uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (AllowAlias != false) {
@@ -3872,6 +4270,7 @@ namespace Google.Protobuf.Reflection {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(EnumOptions other) {
if (other == null) {
return;
@@ -3885,6 +4284,7 @@ namespace Google.Protobuf.Reflection {
uninterpretedOption_.Add(other.uninterpretedOption_);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -3910,30 +4310,35 @@ namespace Google.Protobuf.Reflection {
}
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
internal sealed partial class EnumValueOptions : pb::IMessage<EnumValueOptions> {
private static readonly pb::MessageParser<EnumValueOptions> _parser = new pb::MessageParser<EnumValueOptions>(() => new EnumValueOptions());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<EnumValueOptions> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[13]; }
+ get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[14]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public EnumValueOptions() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public EnumValueOptions(EnumValueOptions other) : this() {
deprecated_ = other.deprecated_;
uninterpretedOption_ = other.uninterpretedOption_.Clone();
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public EnumValueOptions Clone() {
return new EnumValueOptions(this);
}
@@ -3947,6 +4352,7 @@ namespace Google.Protobuf.Reflection {
/// for the enum value, or it will be completely ignored; in the very least,
/// this is a formalization for deprecating enum values.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Deprecated {
get { return deprecated_; }
set {
@@ -3962,14 +4368,17 @@ namespace Google.Protobuf.Reflection {
/// <summary>
/// The parser stores options it doesn't recognize here. See above.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption> UninterpretedOption {
get { return uninterpretedOption_; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as EnumValueOptions);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(EnumValueOptions other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -3982,6 +4391,7 @@ namespace Google.Protobuf.Reflection {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Deprecated != false) hash ^= Deprecated.GetHashCode();
@@ -3989,10 +4399,12 @@ namespace Google.Protobuf.Reflection {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Deprecated != false) {
output.WriteRawTag(8);
@@ -4001,6 +4413,7 @@ namespace Google.Protobuf.Reflection {
uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Deprecated != false) {
@@ -4010,6 +4423,7 @@ namespace Google.Protobuf.Reflection {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(EnumValueOptions other) {
if (other == null) {
return;
@@ -4020,6 +4434,7 @@ namespace Google.Protobuf.Reflection {
uninterpretedOption_.Add(other.uninterpretedOption_);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -4041,30 +4456,35 @@ namespace Google.Protobuf.Reflection {
}
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
internal sealed partial class ServiceOptions : pb::IMessage<ServiceOptions> {
private static readonly pb::MessageParser<ServiceOptions> _parser = new pb::MessageParser<ServiceOptions>(() => new ServiceOptions());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<ServiceOptions> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[14]; }
+ get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[15]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ServiceOptions() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ServiceOptions(ServiceOptions other) : this() {
deprecated_ = other.deprecated_;
uninterpretedOption_ = other.uninterpretedOption_.Clone();
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ServiceOptions Clone() {
return new ServiceOptions(this);
}
@@ -4078,6 +4498,7 @@ namespace Google.Protobuf.Reflection {
/// for the service, or it will be completely ignored; in the very least,
/// this is a formalization for deprecating services.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Deprecated {
get { return deprecated_; }
set {
@@ -4093,14 +4514,17 @@ namespace Google.Protobuf.Reflection {
/// <summary>
/// The parser stores options it doesn't recognize here. See above.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption> UninterpretedOption {
get { return uninterpretedOption_; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as ServiceOptions);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(ServiceOptions other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -4113,6 +4537,7 @@ namespace Google.Protobuf.Reflection {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Deprecated != false) hash ^= Deprecated.GetHashCode();
@@ -4120,10 +4545,12 @@ namespace Google.Protobuf.Reflection {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Deprecated != false) {
output.WriteRawTag(136, 2);
@@ -4132,6 +4559,7 @@ namespace Google.Protobuf.Reflection {
uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Deprecated != false) {
@@ -4141,6 +4569,7 @@ namespace Google.Protobuf.Reflection {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(ServiceOptions other) {
if (other == null) {
return;
@@ -4151,6 +4580,7 @@ namespace Google.Protobuf.Reflection {
uninterpretedOption_.Add(other.uninterpretedOption_);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -4172,30 +4602,35 @@ namespace Google.Protobuf.Reflection {
}
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
internal sealed partial class MethodOptions : pb::IMessage<MethodOptions> {
private static readonly pb::MessageParser<MethodOptions> _parser = new pb::MessageParser<MethodOptions>(() => new MethodOptions());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<MethodOptions> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[15]; }
+ get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[16]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public MethodOptions() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public MethodOptions(MethodOptions other) : this() {
deprecated_ = other.deprecated_;
uninterpretedOption_ = other.uninterpretedOption_.Clone();
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public MethodOptions Clone() {
return new MethodOptions(this);
}
@@ -4209,6 +4644,7 @@ namespace Google.Protobuf.Reflection {
/// for the method, or it will be completely ignored; in the very least,
/// this is a formalization for deprecating methods.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Deprecated {
get { return deprecated_; }
set {
@@ -4224,14 +4660,17 @@ namespace Google.Protobuf.Reflection {
/// <summary>
/// The parser stores options it doesn't recognize here. See above.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption> UninterpretedOption {
get { return uninterpretedOption_; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as MethodOptions);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(MethodOptions other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -4244,6 +4683,7 @@ namespace Google.Protobuf.Reflection {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Deprecated != false) hash ^= Deprecated.GetHashCode();
@@ -4251,10 +4691,12 @@ namespace Google.Protobuf.Reflection {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Deprecated != false) {
output.WriteRawTag(136, 2);
@@ -4263,6 +4705,7 @@ namespace Google.Protobuf.Reflection {
uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Deprecated != false) {
@@ -4272,6 +4715,7 @@ namespace Google.Protobuf.Reflection {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(MethodOptions other) {
if (other == null) {
return;
@@ -4282,6 +4726,7 @@ namespace Google.Protobuf.Reflection {
uninterpretedOption_.Add(other.uninterpretedOption_);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -4311,25 +4756,29 @@ namespace Google.Protobuf.Reflection {
/// or produced by Descriptor::CopyTo()) will never have UninterpretedOptions
/// in them.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
internal sealed partial class UninterpretedOption : pb::IMessage<UninterpretedOption> {
private static readonly pb::MessageParser<UninterpretedOption> _parser = new pb::MessageParser<UninterpretedOption>(() => new UninterpretedOption());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<UninterpretedOption> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[16]; }
+ get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[17]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public UninterpretedOption() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public UninterpretedOption(UninterpretedOption other) : this() {
name_ = other.name_.Clone();
identifierValue_ = other.identifierValue_;
@@ -4340,6 +4789,7 @@ namespace Google.Protobuf.Reflection {
aggregateValue_ = other.aggregateValue_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public UninterpretedOption Clone() {
return new UninterpretedOption(this);
}
@@ -4349,6 +4799,7 @@ namespace Google.Protobuf.Reflection {
private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.UninterpretedOption.Types.NamePart> _repeated_name_codec
= pb::FieldCodec.ForMessage(18, global::Google.Protobuf.Reflection.UninterpretedOption.Types.NamePart.Parser);
private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption.Types.NamePart> name_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption.Types.NamePart>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption.Types.NamePart> Name {
get { return name_; }
}
@@ -4360,16 +4811,18 @@ namespace Google.Protobuf.Reflection {
/// The value of the uninterpreted option, in whatever type the tokenizer
/// identified it as during parsing. Exactly one of these should be set.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string IdentifierValue {
get { return identifierValue_; }
set {
- identifierValue_ = pb::Preconditions.CheckNotNull(value, "value");
+ identifierValue_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
/// <summary>Field number for the "positive_int_value" field.</summary>
public const int PositiveIntValueFieldNumber = 4;
private ulong positiveIntValue_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ulong PositiveIntValue {
get { return positiveIntValue_; }
set {
@@ -4380,6 +4833,7 @@ namespace Google.Protobuf.Reflection {
/// <summary>Field number for the "negative_int_value" field.</summary>
public const int NegativeIntValueFieldNumber = 5;
private long negativeIntValue_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public long NegativeIntValue {
get { return negativeIntValue_; }
set {
@@ -4390,6 +4844,7 @@ namespace Google.Protobuf.Reflection {
/// <summary>Field number for the "double_value" field.</summary>
public const int DoubleValueFieldNumber = 6;
private double doubleValue_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public double DoubleValue {
get { return doubleValue_; }
set {
@@ -4400,27 +4855,31 @@ namespace Google.Protobuf.Reflection {
/// <summary>Field number for the "string_value" field.</summary>
public const int StringValueFieldNumber = 7;
private pb::ByteString stringValue_ = pb::ByteString.Empty;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pb::ByteString StringValue {
get { return stringValue_; }
set {
- stringValue_ = pb::Preconditions.CheckNotNull(value, "value");
+ stringValue_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
/// <summary>Field number for the "aggregate_value" field.</summary>
public const int AggregateValueFieldNumber = 8;
private string aggregateValue_ = "";
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string AggregateValue {
get { return aggregateValue_; }
set {
- aggregateValue_ = pb::Preconditions.CheckNotNull(value, "value");
+ aggregateValue_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as UninterpretedOption);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(UninterpretedOption other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -4438,6 +4897,7 @@ namespace Google.Protobuf.Reflection {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
hash ^= name_.GetHashCode();
@@ -4450,10 +4910,12 @@ namespace Google.Protobuf.Reflection {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
name_.WriteTo(output, _repeated_name_codec);
if (IdentifierValue.Length != 0) {
@@ -4482,6 +4944,7 @@ namespace Google.Protobuf.Reflection {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
size += name_.CalculateSize(_repeated_name_codec);
@@ -4506,6 +4969,7 @@ namespace Google.Protobuf.Reflection {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(UninterpretedOption other) {
if (other == null) {
return;
@@ -4531,6 +4995,7 @@ namespace Google.Protobuf.Reflection {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -4572,7 +5037,7 @@ namespace Google.Protobuf.Reflection {
#region Nested types
/// <summary>Container for nested types declared in the UninterpretedOption message type.</summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static partial class Types {
/// <summary>
/// The name of the uninterpreted option. Each string represents a segment in
@@ -4581,30 +5046,35 @@ namespace Google.Protobuf.Reflection {
/// E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents
/// "foo.(bar.baz).qux".
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
internal sealed partial class NamePart : pb::IMessage<NamePart> {
private static readonly pb::MessageParser<NamePart> _parser = new pb::MessageParser<NamePart>(() => new NamePart());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<NamePart> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.Reflection.UninterpretedOption.Descriptor.NestedTypes[0]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public NamePart() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public NamePart(NamePart other) : this() {
namePart_ = other.namePart_;
isExtension_ = other.isExtension_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public NamePart Clone() {
return new NamePart(this);
}
@@ -4612,16 +5082,18 @@ namespace Google.Protobuf.Reflection {
/// <summary>Field number for the "name_part" field.</summary>
public const int NamePart_FieldNumber = 1;
private string namePart_ = "";
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string NamePart_ {
get { return namePart_; }
set {
- namePart_ = pb::Preconditions.CheckNotNull(value, "value");
+ namePart_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
/// <summary>Field number for the "is_extension" field.</summary>
public const int IsExtensionFieldNumber = 2;
private bool isExtension_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool IsExtension {
get { return isExtension_; }
set {
@@ -4629,10 +5101,12 @@ namespace Google.Protobuf.Reflection {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as NamePart);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(NamePart other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -4645,6 +5119,7 @@ namespace Google.Protobuf.Reflection {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (NamePart_.Length != 0) hash ^= NamePart_.GetHashCode();
@@ -4652,10 +5127,12 @@ namespace Google.Protobuf.Reflection {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (NamePart_.Length != 0) {
output.WriteRawTag(10);
@@ -4667,6 +5144,7 @@ namespace Google.Protobuf.Reflection {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (NamePart_.Length != 0) {
@@ -4678,6 +5156,7 @@ namespace Google.Protobuf.Reflection {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(NamePart other) {
if (other == null) {
return;
@@ -4690,6 +5169,7 @@ namespace Google.Protobuf.Reflection {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -4720,29 +5200,34 @@ namespace Google.Protobuf.Reflection {
/// Encapsulates information about the original source file from which a
/// FileDescriptorProto was generated.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
internal sealed partial class SourceCodeInfo : pb::IMessage<SourceCodeInfo> {
private static readonly pb::MessageParser<SourceCodeInfo> _parser = new pb::MessageParser<SourceCodeInfo>(() => new SourceCodeInfo());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<SourceCodeInfo> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[17]; }
+ get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[18]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public SourceCodeInfo() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public SourceCodeInfo(SourceCodeInfo other) : this() {
location_ = other.location_.Clone();
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public SourceCodeInfo Clone() {
return new SourceCodeInfo(this);
}
@@ -4797,14 +5282,17 @@ namespace Google.Protobuf.Reflection {
/// ignore those that it doesn't understand, as more types of locations could
/// be recorded in the future.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.Reflection.SourceCodeInfo.Types.Location> Location {
get { return location_; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as SourceCodeInfo);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(SourceCodeInfo other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -4816,26 +5304,31 @@ namespace Google.Protobuf.Reflection {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
hash ^= location_.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
location_.WriteTo(output, _repeated_location_codec);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
size += location_.CalculateSize(_repeated_location_codec);
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(SourceCodeInfo other) {
if (other == null) {
return;
@@ -4843,6 +5336,7 @@ namespace Google.Protobuf.Reflection {
location_.Add(other.location_);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -4860,27 +5354,31 @@ namespace Google.Protobuf.Reflection {
#region Nested types
/// <summary>Container for nested types declared in the SourceCodeInfo message type.</summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static partial class Types {
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
internal sealed partial class Location : pb::IMessage<Location> {
private static readonly pb::MessageParser<Location> _parser = new pb::MessageParser<Location>(() => new Location());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<Location> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.Reflection.SourceCodeInfo.Descriptor.NestedTypes[0]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Location() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Location(Location other) : this() {
path_ = other.path_.Clone();
span_ = other.span_.Clone();
@@ -4889,6 +5387,7 @@ namespace Google.Protobuf.Reflection {
leadingDetachedComments_ = other.leadingDetachedComments_.Clone();
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Location Clone() {
return new Location(this);
}
@@ -4923,6 +5422,7 @@ namespace Google.Protobuf.Reflection {
/// this path refers to the whole field declaration (from the beginning
/// of the label to the terminating semicolon).
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<int> Path {
get { return path_; }
}
@@ -4939,6 +5439,7 @@ namespace Google.Protobuf.Reflection {
/// and column numbers are zero-based -- typically you will want to add
/// 1 to each before displaying to a user.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<int> Span {
get { return span_; }
}
@@ -4995,20 +5496,22 @@ namespace Google.Protobuf.Reflection {
///
/// // ignored detached comments.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string LeadingComments {
get { return leadingComments_; }
set {
- leadingComments_ = pb::Preconditions.CheckNotNull(value, "value");
+ leadingComments_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
/// <summary>Field number for the "trailing_comments" field.</summary>
public const int TrailingCommentsFieldNumber = 4;
private string trailingComments_ = "";
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string TrailingComments {
get { return trailingComments_; }
set {
- trailingComments_ = pb::Preconditions.CheckNotNull(value, "value");
+ trailingComments_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -5017,14 +5520,17 @@ namespace Google.Protobuf.Reflection {
private static readonly pb::FieldCodec<string> _repeated_leadingDetachedComments_codec
= pb::FieldCodec.ForString(50);
private readonly pbc::RepeatedField<string> leadingDetachedComments_ = new pbc::RepeatedField<string>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<string> LeadingDetachedComments {
get { return leadingDetachedComments_; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as Location);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(Location other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -5040,6 +5546,7 @@ namespace Google.Protobuf.Reflection {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
hash ^= path_.GetHashCode();
@@ -5050,10 +5557,12 @@ namespace Google.Protobuf.Reflection {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
path_.WriteTo(output, _repeated_path_codec);
span_.WriteTo(output, _repeated_span_codec);
@@ -5068,6 +5577,7 @@ namespace Google.Protobuf.Reflection {
leadingDetachedComments_.WriteTo(output, _repeated_leadingDetachedComments_codec);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
size += path_.CalculateSize(_repeated_path_codec);
@@ -5082,6 +5592,7 @@ namespace Google.Protobuf.Reflection {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(Location other) {
if (other == null) {
return;
@@ -5097,6 +5608,7 @@ namespace Google.Protobuf.Reflection {
leadingDetachedComments_.Add(other.leadingDetachedComments_);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -5137,6 +5649,341 @@ namespace Google.Protobuf.Reflection {
}
+ /// <summary>
+ /// Describes the relationship between generated code and its original source
+ /// file. A GeneratedCodeInfo message is associated with only one generated
+ /// source file, but may contain references to different source .proto files.
+ /// </summary>
+ internal sealed partial class GeneratedCodeInfo : pb::IMessage<GeneratedCodeInfo> {
+ private static readonly pb::MessageParser<GeneratedCodeInfo> _parser = new pb::MessageParser<GeneratedCodeInfo>(() => new GeneratedCodeInfo());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pb::MessageParser<GeneratedCodeInfo> Parser { get { return _parser; } }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pbr::MessageDescriptor Descriptor {
+ get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[19]; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ pbr::MessageDescriptor pb::IMessage.Descriptor {
+ get { return Descriptor; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public GeneratedCodeInfo() {
+ OnConstruction();
+ }
+
+ partial void OnConstruction();
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public GeneratedCodeInfo(GeneratedCodeInfo other) : this() {
+ annotation_ = other.annotation_.Clone();
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public GeneratedCodeInfo Clone() {
+ return new GeneratedCodeInfo(this);
+ }
+
+ /// <summary>Field number for the "annotation" field.</summary>
+ public const int AnnotationFieldNumber = 1;
+ private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.GeneratedCodeInfo.Types.Annotation> _repeated_annotation_codec
+ = pb::FieldCodec.ForMessage(10, global::Google.Protobuf.Reflection.GeneratedCodeInfo.Types.Annotation.Parser);
+ private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.GeneratedCodeInfo.Types.Annotation> annotation_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.GeneratedCodeInfo.Types.Annotation>();
+ /// <summary>
+ /// An Annotation connects some span of text in generated code to an element
+ /// of its generating .proto file.
+ /// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public pbc::RepeatedField<global::Google.Protobuf.Reflection.GeneratedCodeInfo.Types.Annotation> Annotation {
+ get { return annotation_; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override bool Equals(object other) {
+ return Equals(other as GeneratedCodeInfo);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool Equals(GeneratedCodeInfo other) {
+ if (ReferenceEquals(other, null)) {
+ return false;
+ }
+ if (ReferenceEquals(other, this)) {
+ return true;
+ }
+ if(!annotation_.Equals(other.annotation_)) return false;
+ return true;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override int GetHashCode() {
+ int hash = 1;
+ hash ^= annotation_.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) {
+ annotation_.WriteTo(output, _repeated_annotation_codec);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int CalculateSize() {
+ int size = 0;
+ size += annotation_.CalculateSize(_repeated_annotation_codec);
+ return size;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(GeneratedCodeInfo other) {
+ if (other == null) {
+ return;
+ }
+ annotation_.Add(other.annotation_);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(pb::CodedInputStream input) {
+ uint tag;
+ while ((tag = input.ReadTag()) != 0) {
+ switch(tag) {
+ default:
+ input.SkipLastField();
+ break;
+ case 10: {
+ annotation_.AddEntriesFrom(input, _repeated_annotation_codec);
+ break;
+ }
+ }
+ }
+ }
+
+ #region Nested types
+ /// <summary>Container for nested types declared in the GeneratedCodeInfo message type.</summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static partial class Types {
+ internal sealed partial class Annotation : pb::IMessage<Annotation> {
+ private static readonly pb::MessageParser<Annotation> _parser = new pb::MessageParser<Annotation>(() => new Annotation());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pb::MessageParser<Annotation> Parser { get { return _parser; } }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pbr::MessageDescriptor Descriptor {
+ get { return global::Google.Protobuf.Reflection.GeneratedCodeInfo.Descriptor.NestedTypes[0]; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ pbr::MessageDescriptor pb::IMessage.Descriptor {
+ get { return Descriptor; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public Annotation() {
+ OnConstruction();
+ }
+
+ partial void OnConstruction();
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public Annotation(Annotation other) : this() {
+ path_ = other.path_.Clone();
+ sourceFile_ = other.sourceFile_;
+ begin_ = other.begin_;
+ end_ = other.end_;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public Annotation Clone() {
+ return new Annotation(this);
+ }
+
+ /// <summary>Field number for the "path" field.</summary>
+ public const int PathFieldNumber = 1;
+ private static readonly pb::FieldCodec<int> _repeated_path_codec
+ = pb::FieldCodec.ForInt32(10);
+ private readonly pbc::RepeatedField<int> path_ = new pbc::RepeatedField<int>();
+ /// <summary>
+ /// Identifies the element in the original source .proto file. This field
+ /// is formatted the same as SourceCodeInfo.Location.path.
+ /// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public pbc::RepeatedField<int> Path {
+ get { return path_; }
+ }
+
+ /// <summary>Field number for the "source_file" field.</summary>
+ public const int SourceFileFieldNumber = 2;
+ private string sourceFile_ = "";
+ /// <summary>
+ /// Identifies the filesystem path to the original source .proto.
+ /// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public string SourceFile {
+ get { return sourceFile_; }
+ set {
+ sourceFile_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ }
+ }
+
+ /// <summary>Field number for the "begin" field.</summary>
+ public const int BeginFieldNumber = 3;
+ private int begin_;
+ /// <summary>
+ /// Identifies the starting offset in bytes in the generated code
+ /// that relates to the identified object.
+ /// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int Begin {
+ get { return begin_; }
+ set {
+ begin_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "end" field.</summary>
+ public const int EndFieldNumber = 4;
+ private int end_;
+ /// <summary>
+ /// Identifies the ending offset in bytes in the generated code that
+ /// relates to the identified offset. The end offset should be one past
+ /// the last relevant byte (so the length of the text = end - begin).
+ /// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int End {
+ get { return end_; }
+ set {
+ end_ = value;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override bool Equals(object other) {
+ return Equals(other as Annotation);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool Equals(Annotation other) {
+ if (ReferenceEquals(other, null)) {
+ return false;
+ }
+ if (ReferenceEquals(other, this)) {
+ return true;
+ }
+ if(!path_.Equals(other.path_)) return false;
+ if (SourceFile != other.SourceFile) return false;
+ if (Begin != other.Begin) return false;
+ if (End != other.End) return false;
+ return true;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override int GetHashCode() {
+ int hash = 1;
+ hash ^= path_.GetHashCode();
+ if (SourceFile.Length != 0) hash ^= SourceFile.GetHashCode();
+ if (Begin != 0) hash ^= Begin.GetHashCode();
+ if (End != 0) hash ^= End.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) {
+ path_.WriteTo(output, _repeated_path_codec);
+ if (SourceFile.Length != 0) {
+ output.WriteRawTag(18);
+ output.WriteString(SourceFile);
+ }
+ if (Begin != 0) {
+ output.WriteRawTag(24);
+ output.WriteInt32(Begin);
+ }
+ if (End != 0) {
+ output.WriteRawTag(32);
+ output.WriteInt32(End);
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int CalculateSize() {
+ int size = 0;
+ size += path_.CalculateSize(_repeated_path_codec);
+ if (SourceFile.Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(SourceFile);
+ }
+ if (Begin != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeInt32Size(Begin);
+ }
+ if (End != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeInt32Size(End);
+ }
+ return size;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(Annotation other) {
+ if (other == null) {
+ return;
+ }
+ path_.Add(other.path_);
+ if (other.SourceFile.Length != 0) {
+ SourceFile = other.SourceFile;
+ }
+ if (other.Begin != 0) {
+ Begin = other.Begin;
+ }
+ if (other.End != 0) {
+ End = other.End;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(pb::CodedInputStream input) {
+ uint tag;
+ while ((tag = input.ReadTag()) != 0) {
+ switch(tag) {
+ default:
+ input.SkipLastField();
+ break;
+ case 10:
+ case 8: {
+ path_.AddEntriesFrom(input, _repeated_path_codec);
+ break;
+ }
+ case 18: {
+ SourceFile = input.ReadString();
+ break;
+ }
+ case 24: {
+ Begin = input.ReadInt32();
+ break;
+ }
+ case 32: {
+ End = input.ReadInt32();
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
+ }
+ #endregion
+
+ }
+
#endregion
}
diff --git a/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs
index c6caaec6..6c6f6ee0 100644
--- a/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs
+++ b/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs
@@ -30,9 +30,8 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
-using System;
-using System.Linq;
using Google.Protobuf.Compatibility;
+using System;
namespace Google.Protobuf.Reflection
{
@@ -41,20 +40,35 @@ namespace Google.Protobuf.Reflection
/// </summary>
public sealed class FieldDescriptor : DescriptorBase, IComparable<FieldDescriptor>
{
- private readonly FieldDescriptorProto proto;
private EnumDescriptor enumType;
private MessageDescriptor messageType;
- private readonly MessageDescriptor containingType;
- private readonly OneofDescriptor containingOneof;
private FieldType fieldType;
private readonly string propertyName; // Annoyingly, needed in Crosslink.
private IFieldAccessor accessor;
+ /// <summary>
+ /// Get the field's containing message type.
+ /// </summary>
+ public MessageDescriptor ContainingType { get; }
+
+ /// <summary>
+ /// Returns the oneof containing this field, or <c>null</c> if it is not part of a oneof.
+ /// </summary>
+ public OneofDescriptor ContainingOneof { get; }
+
+ /// <summary>
+ /// The effective JSON name for this field. This is usually the lower-camel-cased form of the field name,
+ /// but can be overridden using the <c>json_name</c> option in the .proto file.
+ /// </summary>
+ public string JsonName { get; }
+
+ internal FieldDescriptorProto Proto { get; }
+
internal FieldDescriptor(FieldDescriptorProto proto, FileDescriptor file,
MessageDescriptor parent, int index, string propertyName)
: base(file, file.ComputeFullName(parent, proto.Name), index)
{
- this.proto = proto;
+ Proto = proto;
if (proto.Type != 0)
{
fieldType = GetFieldTypeFromProtoType(proto.Type);
@@ -64,7 +78,7 @@ namespace Google.Protobuf.Reflection
{
throw new DescriptorValidationException(this, "Field numbers must be positive integers.");
}
- containingType = parent;
+ ContainingType = parent;
// OneofIndex "defaults" to -1 due to a hack in FieldDescriptor.OnConstruction.
if (proto.OneofIndex != -1)
{
@@ -73,7 +87,7 @@ namespace Google.Protobuf.Reflection
throw new DescriptorValidationException(this,
$"FieldDescriptorProto.oneof_index is out of range for type {parent.Name}");
}
- containingOneof = parent.Oneofs[proto.OneofIndex];
+ ContainingOneof = parent.Oneofs[proto.OneofIndex];
}
file.DescriptorPool.AddSymbol(this);
@@ -83,14 +97,14 @@ namespace Google.Protobuf.Reflection
// We could trust the generated code and check whether the type of the property is
// a MapField, but that feels a tad nasty.
this.propertyName = propertyName;
+ JsonName = Proto.JsonName == "" ? JsonFormatter.ToCamelCase(Proto.Name) : Proto.JsonName;
}
+
/// <summary>
/// The brief name of the descriptor's target.
/// </summary>
- public override string Name { get { return proto.Name; } }
-
- internal FieldDescriptorProto Proto { get { return proto; } }
+ public override string Name => Proto.Name;
/// <summary>
/// Returns the accessor for this field.
@@ -110,7 +124,7 @@ namespace Google.Protobuf.Reflection
/// and this property will return null.
/// </para>
/// </remarks>
- public IFieldAccessor Accessor { get { return accessor; } }
+ public IFieldAccessor Accessor => accessor;
/// <summary>
/// Maps a field type as included in the .proto file to a FieldType.
@@ -119,41 +133,41 @@ namespace Google.Protobuf.Reflection
{
switch (type)
{
- case FieldDescriptorProto.Types.Type.TYPE_DOUBLE:
+ case FieldDescriptorProto.Types.Type.Double:
return FieldType.Double;
- case FieldDescriptorProto.Types.Type.TYPE_FLOAT:
+ case FieldDescriptorProto.Types.Type.Float:
return FieldType.Float;
- case FieldDescriptorProto.Types.Type.TYPE_INT64:
+ case FieldDescriptorProto.Types.Type.Int64:
return FieldType.Int64;
- case FieldDescriptorProto.Types.Type.TYPE_UINT64:
+ case FieldDescriptorProto.Types.Type.Uint64:
return FieldType.UInt64;
- case FieldDescriptorProto.Types.Type.TYPE_INT32:
+ case FieldDescriptorProto.Types.Type.Int32:
return FieldType.Int32;
- case FieldDescriptorProto.Types.Type.TYPE_FIXED64:
+ case FieldDescriptorProto.Types.Type.Fixed64:
return FieldType.Fixed64;
- case FieldDescriptorProto.Types.Type.TYPE_FIXED32:
+ case FieldDescriptorProto.Types.Type.Fixed32:
return FieldType.Fixed32;
- case FieldDescriptorProto.Types.Type.TYPE_BOOL:
+ case FieldDescriptorProto.Types.Type.Bool:
return FieldType.Bool;
- case FieldDescriptorProto.Types.Type.TYPE_STRING:
+ case FieldDescriptorProto.Types.Type.String:
return FieldType.String;
- case FieldDescriptorProto.Types.Type.TYPE_GROUP:
+ case FieldDescriptorProto.Types.Type.Group:
return FieldType.Group;
- case FieldDescriptorProto.Types.Type.TYPE_MESSAGE:
+ case FieldDescriptorProto.Types.Type.Message:
return FieldType.Message;
- case FieldDescriptorProto.Types.Type.TYPE_BYTES:
+ case FieldDescriptorProto.Types.Type.Bytes:
return FieldType.Bytes;
- case FieldDescriptorProto.Types.Type.TYPE_UINT32:
+ case FieldDescriptorProto.Types.Type.Uint32:
return FieldType.UInt32;
- case FieldDescriptorProto.Types.Type.TYPE_ENUM:
+ case FieldDescriptorProto.Types.Type.Enum:
return FieldType.Enum;
- case FieldDescriptorProto.Types.Type.TYPE_SFIXED32:
+ case FieldDescriptorProto.Types.Type.Sfixed32:
return FieldType.SFixed32;
- case FieldDescriptorProto.Types.Type.TYPE_SFIXED64:
+ case FieldDescriptorProto.Types.Type.Sfixed64:
return FieldType.SFixed64;
- case FieldDescriptorProto.Types.Type.TYPE_SINT32:
+ case FieldDescriptorProto.Types.Type.Sint32:
return FieldType.SInt32;
- case FieldDescriptorProto.Types.Type.TYPE_SINT64:
+ case FieldDescriptorProto.Types.Type.Sint64:
return FieldType.SInt64;
default:
throw new ArgumentException("Invalid type specified");
@@ -163,62 +177,32 @@ namespace Google.Protobuf.Reflection
/// <summary>
/// Returns <c>true</c> if this field is a repeated field; <c>false</c> otherwise.
/// </summary>
- public bool IsRepeated
- {
- get { return Proto.Label == FieldDescriptorProto.Types.Label.LABEL_REPEATED; }
- }
+ public bool IsRepeated => Proto.Label == FieldDescriptorProto.Types.Label.Repeated;
/// <summary>
/// Returns <c>true</c> if this field is a map field; <c>false</c> otherwise.
/// </summary>
- public bool IsMap
- {
- get { return fieldType == FieldType.Message && messageType.Proto.Options != null && messageType.Proto.Options.MapEntry; }
- }
+ public bool IsMap => fieldType == FieldType.Message && messageType.Proto.Options != null && messageType.Proto.Options.MapEntry;
/// <summary>
/// Returns <c>true</c> if this field is a packed, repeated field; <c>false</c> otherwise.
/// </summary>
- public bool IsPacked
- {
+ public bool IsPacked =>
// Note the || rather than && here - we're effectively defaulting to packed, because that *is*
// the default in proto3, which is all we support. We may give the wrong result for the protos
// within descriptor.proto, but that's okay, as they're never exposed and we don't use IsPacked
// within the runtime.
- get { return Proto.Options == null || Proto.Options.Packed; }
- }
-
- /// <summary>
- /// Get the field's containing message type.
- /// </summary>
- public MessageDescriptor ContainingType
- {
- get { return containingType; }
- }
-
- /// <summary>
- /// Returns the oneof containing this field, or <c>null</c> if it is not part of a oneof.
- /// </summary>
- public OneofDescriptor ContainingOneof
- {
- get { return containingOneof; }
- }
-
+ Proto.Options == null || Proto.Options.Packed;
+
/// <summary>
/// Returns the type of the field.
/// </summary>
- public FieldType FieldType
- {
- get { return fieldType; }
- }
+ public FieldType FieldType => fieldType;
/// <summary>
/// Returns the field number declared in the proto file.
/// </summary>
- public int FieldNumber
- {
- get { return Proto.Number; }
- }
+ public int FieldNumber => Proto.Number;
/// <summary>
/// Compares this descriptor with another one, ordering in "canonical" order
@@ -228,7 +212,7 @@ namespace Google.Protobuf.Reflection
/// </summary>
public int CompareTo(FieldDescriptor other)
{
- if (other.containingType != containingType)
+ if (other.ContainingType != ContainingType)
{
throw new ArgumentException("FieldDescriptors can only be compared to other FieldDescriptors " +
"for fields of the same message type.");
@@ -331,14 +315,14 @@ namespace Google.Protobuf.Reflection
File.DescriptorPool.AddFieldByNumber(this);
- if (containingType != null && containingType.Proto.Options != null && containingType.Proto.Options.MessageSetWireFormat)
+ if (ContainingType != null && ContainingType.Proto.Options != null && ContainingType.Proto.Options.MessageSetWireFormat)
{
throw new DescriptorValidationException(this, "MessageSet format is not supported.");
}
- accessor = CreateAccessor(propertyName);
+ accessor = CreateAccessor();
}
- private IFieldAccessor CreateAccessor(string propertyName)
+ private IFieldAccessor CreateAccessor()
{
// If we're given no property name, that's because we really don't want an accessor.
// (At the moment, that means it's a map entry message...)
@@ -346,10 +330,10 @@ namespace Google.Protobuf.Reflection
{
return null;
}
- var property = containingType.ClrType.GetProperty(propertyName);
+ var property = ContainingType.ClrType.GetProperty(propertyName);
if (property == null)
{
- throw new DescriptorValidationException(this, $"Property {propertyName} not found in {containingType.ClrType}");
+ throw new DescriptorValidationException(this, $"Property {propertyName} not found in {ContainingType.ClrType}");
}
return IsMap ? new MapFieldAccessor(property, this)
: IsRepeated ? new RepeatedFieldAccessor(property, this)
diff --git a/csharp/src/Google.Protobuf/Reflection/FileDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/FileDescriptor.cs
index 48ee5596..ab7cd922 100644
--- a/csharp/src/Google.Protobuf/Reflection/FileDescriptor.cs
+++ b/csharp/src/Google.Protobuf/Reflection/FileDescriptor.cs
@@ -43,7 +43,7 @@ namespace Google.Protobuf.Reflection
/// </summary>
public sealed class FileDescriptor : IDescriptor
{
- private FileDescriptor(ByteString descriptorData, FileDescriptorProto proto, FileDescriptor[] dependencies, DescriptorPool pool, bool allowUnknownDependencies, GeneratedCodeInfo generatedCodeInfo)
+ private FileDescriptor(ByteString descriptorData, FileDescriptorProto proto, FileDescriptor[] dependencies, DescriptorPool pool, bool allowUnknownDependencies, GeneratedClrTypeInfo generatedCodeInfo)
{
SerializedData = descriptorData;
DescriptorPool = pool;
@@ -223,7 +223,7 @@ namespace Google.Protobuf.Reflection
/// <exception cref="DescriptorValidationException">If <paramref name="proto"/> is not
/// a valid descriptor. This can occur for a number of reasons, such as a field
/// having an undefined type or because two messages were defined with the same name.</exception>
- private static FileDescriptor BuildFrom(ByteString descriptorData, FileDescriptorProto proto, FileDescriptor[] dependencies, bool allowUnknownDependencies, GeneratedCodeInfo generatedCodeInfo)
+ private static FileDescriptor BuildFrom(ByteString descriptorData, FileDescriptorProto proto, FileDescriptor[] dependencies, bool allowUnknownDependencies, GeneratedClrTypeInfo generatedCodeInfo)
{
// Building descriptors involves two steps: translating and linking.
// In the translation step (implemented by FileDescriptor's
@@ -291,7 +291,7 @@ namespace Google.Protobuf.Reflection
public static FileDescriptor FromGeneratedCode(
byte[] descriptorData,
FileDescriptor[] dependencies,
- GeneratedCodeInfo generatedCodeInfo)
+ GeneratedClrTypeInfo generatedCodeInfo)
{
FileDescriptorProto proto;
try
diff --git a/csharp/src/Google.Protobuf/Reflection/GeneratedCodeInfo.cs b/csharp/src/Google.Protobuf/Reflection/GeneratedClrTypeInfo.cs
index e5fe9fb7..fe5db656 100644
--- a/csharp/src/Google.Protobuf/Reflection/GeneratedCodeInfo.cs
+++ b/csharp/src/Google.Protobuf/Reflection/GeneratedClrTypeInfo.cs
@@ -38,10 +38,10 @@ namespace Google.Protobuf.Reflection
/// These are constructed as required, and are not long-lived. Hand-written code should
/// never need to use this type.
/// </summary>
- public sealed class GeneratedCodeInfo
+ public sealed class GeneratedClrTypeInfo
{
private static readonly string[] EmptyNames = new string[0];
- private static readonly GeneratedCodeInfo[] EmptyCodeInfo = new GeneratedCodeInfo[0];
+ private static readonly GeneratedClrTypeInfo[] EmptyCodeInfo = new GeneratedClrTypeInfo[0];
/// <summary>
/// Irrelevant for file descriptors; the CLR type for the message for message descriptors.
@@ -70,7 +70,7 @@ namespace Google.Protobuf.Reflection
/// The reflection information for types within this file/message descriptor. Elements may be null
/// if there is no corresponding generated type, e.g. for map entry types.
/// </summary>
- public GeneratedCodeInfo[] NestedTypes { get; }
+ public GeneratedClrTypeInfo[] NestedTypes { get; }
/// <summary>
/// The CLR types for enums within this file/message descriptor.
@@ -78,11 +78,11 @@ namespace Google.Protobuf.Reflection
public Type[] NestedEnums { get; }
/// <summary>
- /// Creates a GeneratedCodeInfo for a message descriptor, with nested types, nested enums, the CLR type, property names and oneof names.
+ /// Creates a GeneratedClrTypeInfo for a message descriptor, with nested types, nested enums, the CLR type, property names and oneof names.
/// Each array parameter may be null, to indicate a lack of values.
/// The parameter order is designed to make it feasible to format the generated code readably.
/// </summary>
- public GeneratedCodeInfo(Type clrType, MessageParser parser, string[] propertyNames, string[] oneofNames, Type[] nestedEnums, GeneratedCodeInfo[] nestedTypes)
+ public GeneratedClrTypeInfo(Type clrType, MessageParser parser, string[] propertyNames, string[] oneofNames, Type[] nestedEnums, GeneratedClrTypeInfo[] nestedTypes)
{
NestedTypes = nestedTypes ?? EmptyCodeInfo;
NestedEnums = nestedEnums ?? ReflectionUtil.EmptyTypes;
@@ -93,9 +93,9 @@ namespace Google.Protobuf.Reflection
}
/// <summary>
- /// Creates a GeneratedCodeInfo for a file descriptor, with only types and enums.
+ /// Creates a GeneratedClrTypeInfo for a file descriptor, with only types and enums.
/// </summary>
- public GeneratedCodeInfo(Type[] nestedEnums, GeneratedCodeInfo[] nestedTypes)
+ public GeneratedClrTypeInfo(Type[] nestedEnums, GeneratedClrTypeInfo[] nestedTypes)
: this(null, null, null, null, nestedEnums, nestedTypes)
{
}
diff --git a/csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs
index d1732b2e..7a1cb9d5 100644
--- a/csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs
+++ b/csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs
@@ -34,6 +34,10 @@ using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
+#if DOTNET35
+// Needed for ReadOnlyDictionary, which does not exist in .NET 3.5
+using Google.Protobuf.Collections;
+#endif
namespace Google.Protobuf.Reflection
{
@@ -60,7 +64,7 @@ namespace Google.Protobuf.Reflection
private readonly IList<FieldDescriptor> fieldsInNumberOrder;
private readonly IDictionary<string, FieldDescriptor> jsonFieldMap;
- internal MessageDescriptor(DescriptorProto proto, FileDescriptor file, MessageDescriptor parent, int typeIndex, GeneratedCodeInfo generatedCodeInfo)
+ internal MessageDescriptor(DescriptorProto proto, FileDescriptor file, MessageDescriptor parent, int typeIndex, GeneratedClrTypeInfo generatedCodeInfo)
: base(file, file.ComputeFullName(parent, proto.Name), typeIndex)
{
Proto = proto;
@@ -92,11 +96,22 @@ namespace Google.Protobuf.Reflection
new FieldDescriptor(field, file, this, index, generatedCodeInfo?.PropertyNames[index]));
fieldsInNumberOrder = new ReadOnlyCollection<FieldDescriptor>(fieldsInDeclarationOrder.OrderBy(field => field.FieldNumber).ToArray());
// TODO: Use field => field.Proto.JsonName when we're confident it's appropriate. (And then use it in the formatter, too.)
- jsonFieldMap = new ReadOnlyDictionary<string, FieldDescriptor>(fieldsInNumberOrder.ToDictionary(field => JsonFormatter.ToCamelCase(field.Name)));
+ jsonFieldMap = CreateJsonFieldMap(fieldsInNumberOrder);
file.DescriptorPool.AddSymbol(this);
Fields = new FieldCollection(this);
}
+ private static ReadOnlyDictionary<string, FieldDescriptor> CreateJsonFieldMap(IList<FieldDescriptor> fields)
+ {
+ var map = new Dictionary<string, FieldDescriptor>();
+ foreach (var field in fields)
+ {
+ map[field.Name] = field;
+ map[field.JsonName] = field;
+ }
+ return new ReadOnlyDictionary<string, FieldDescriptor>(map);
+ }
+
/// <summary>
/// The brief name of the descriptor's target.
/// </summary>
@@ -255,9 +270,10 @@ namespace Google.Protobuf.Reflection
// TODO: consider making this public in the future. (Being conservative for now...)
/// <value>
- /// Returns a read-only dictionary mapping the field names in this message as they're used
+ /// Returns a read-only dictionary mapping the field names in this message as they're available
/// in the JSON representation to the field descriptors. For example, a field <c>foo_bar</c>
- /// in the message would result in an entry with a key <c>fooBar</c>.
+ /// in the message would result two entries, one with a key <c>fooBar</c> and one with a key
+ /// <c>foo_bar</c>, both referring to the same field.
/// </value>
internal IDictionary<string, FieldDescriptor> ByJsonName() => messageDescriptor.jsonFieldMap;
diff --git a/csharp/src/Google.Protobuf/Reflection/OriginalNameAttribute.cs b/csharp/src/Google.Protobuf/Reflection/OriginalNameAttribute.cs
new file mode 100644
index 00000000..27f9ab98
--- /dev/null
+++ b/csharp/src/Google.Protobuf/Reflection/OriginalNameAttribute.cs
@@ -0,0 +1,58 @@
+#region Copyright notice and license
+// 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.
+#endregion
+
+using System;
+
+namespace Google.Protobuf.Reflection
+{
+ /// <summary>
+ /// Specifies the original name (in the .proto file) of a named element,
+ /// such as an enum value.
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Field)]
+ public class OriginalNameAttribute : Attribute
+ {
+ /// <summary>
+ /// The name of the element in the .proto file.
+ /// </summary>
+ public string Name { get; set; }
+
+ /// <summary>
+ /// Constructs a new attribute instance for the given name.
+ /// </summary>
+ /// <param name="name">The name of the element in the .proto file.</param>
+ public OriginalNameAttribute(string name)
+ {
+ Name = ProtoPreconditions.CheckNotNull(name, nameof(name));
+ }
+ }
+} \ No newline at end of file
diff --git a/csharp/src/Google.Protobuf/Reflection/TypeRegistry.cs b/csharp/src/Google.Protobuf/Reflection/TypeRegistry.cs
index 31d5a30f..e94e3e6c 100644
--- a/csharp/src/Google.Protobuf/Reflection/TypeRegistry.cs
+++ b/csharp/src/Google.Protobuf/Reflection/TypeRegistry.cs
@@ -91,7 +91,7 @@ namespace Google.Protobuf.Reflection
/// <returns>A type registry for the given files.</returns>
public static TypeRegistry FromFiles(IEnumerable<FileDescriptor> fileDescriptors)
{
- Preconditions.CheckNotNull(fileDescriptors, nameof(fileDescriptors));
+ ProtoPreconditions.CheckNotNull(fileDescriptors, nameof(fileDescriptors));
var builder = new Builder();
foreach (var file in fileDescriptors)
{
@@ -128,7 +128,7 @@ namespace Google.Protobuf.Reflection
/// <returns>A type registry for the given files.</returns>
public static TypeRegistry FromMessages(IEnumerable<MessageDescriptor> messageDescriptors)
{
- Preconditions.CheckNotNull(messageDescriptors, nameof(messageDescriptors));
+ ProtoPreconditions.CheckNotNull(messageDescriptors, nameof(messageDescriptors));
return FromFiles(messageDescriptors.Select(md => md.File));
}
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs
index 0b830b66..6f91507b 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs
@@ -10,7 +10,6 @@ using scg = global::System.Collections.Generic;
namespace Google.Protobuf.WellKnownTypes {
/// <summary>Holder for reflection information generated from google/protobuf/any.proto</summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public static partial class AnyReflection {
#region Descriptor
@@ -24,13 +23,14 @@ namespace Google.Protobuf.WellKnownTypes {
byte[] descriptorData = global::System.Convert.FromBase64String(
string.Concat(
"Chlnb29nbGUvcHJvdG9idWYvYW55LnByb3RvEg9nb29nbGUucHJvdG9idWYi",
- "JgoDQW55EhAKCHR5cGVfdXJsGAEgASgJEg0KBXZhbHVlGAIgASgMQksKE2Nv",
- "bS5nb29nbGUucHJvdG9idWZCCEFueVByb3RvUAGgAQGiAgNHUEKqAh5Hb29n",
- "bGUuUHJvdG9idWYuV2VsbEtub3duVHlwZXNiBnByb3RvMw=="));
+ "JgoDQW55EhAKCHR5cGVfdXJsGAEgASgJEg0KBXZhbHVlGAIgASgMQnIKE2Nv",
+ "bS5nb29nbGUucHJvdG9idWZCCEFueVByb3RvUAFaJWdpdGh1Yi5jb20vZ29s",
+ "YW5nL3Byb3RvYnVmL3B0eXBlcy9hbnmgAQGiAgNHUEKqAh5Hb29nbGUuUHJv",
+ "dG9idWYuV2VsbEtub3duVHlwZXNiBnByb3RvMw=="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
- new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Any), global::Google.Protobuf.WellKnownTypes.Any.Parser, new[]{ "TypeUrl", "Value" }, null, null, null)
+ new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Any), global::Google.Protobuf.WellKnownTypes.Any.Parser, new[]{ "TypeUrl", "Value" }, null, null, null)
}));
}
#endregion
@@ -38,8 +38,46 @@ namespace Google.Protobuf.WellKnownTypes {
}
#region Messages
/// <summary>
- /// `Any` contains an arbitrary serialized message along with a URL
- /// that describes the type of the serialized message.
+ /// `Any` contains an arbitrary serialized protocol buffer message along with a
+ /// URL that describes the type of the serialized message.
+ ///
+ /// Protobuf library provides support to pack/unpack Any values in the form
+ /// of utility functions or additional generated methods of the Any type.
+ ///
+ /// Example 1: Pack and unpack a message in C++.
+ ///
+ /// Foo foo = ...;
+ /// Any any;
+ /// any.PackFrom(foo);
+ /// ...
+ /// if (any.UnpackTo(&amp;foo)) {
+ /// ...
+ /// }
+ ///
+ /// Example 2: Pack and unpack a message in Java.
+ ///
+ /// Foo foo = ...;
+ /// Any any = Any.pack(foo);
+ /// ...
+ /// if (any.is(Foo.class)) {
+ /// foo = any.unpack(Foo.class);
+ /// }
+ ///
+ /// Example 3: Pack and unpack a message in Python.
+ ///
+ /// foo = Foo(...)
+ /// any = Any()
+ /// any.Pack(foo)
+ /// ...
+ /// if any.Is(Foo.DESCRIPTOR):
+ /// any.Unpack(foo)
+ /// ...
+ ///
+ /// The pack methods provided by protobuf library will by default use
+ /// 'type.googleapis.com/full.type.name' as the type URL and the unpack
+ /// methods only use the fully qualified type name after the last '/'
+ /// in the type URL, for example "foo.bar.com/x/y.z" will yield type
+ /// name "y.z".
///
/// JSON
/// ====
@@ -61,38 +99,43 @@ namespace Google.Protobuf.WellKnownTypes {
///
/// If the embedded message type is well-known and has a custom JSON
/// representation, that representation will be embedded adding a field
- /// `value` which holds the custom JSON in addition to the the `@type`
- /// field. Example (for message [google.protobuf.Duration][google.protobuf.Duration]):
+ /// `value` which holds the custom JSON in addition to the `@type`
+ /// field. Example (for message [google.protobuf.Duration][]):
///
/// {
/// "@type": "type.googleapis.com/google.protobuf.Duration",
/// "value": "1.212s"
/// }
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class Any : pb::IMessage<Any> {
private static readonly pb::MessageParser<Any> _parser = new pb::MessageParser<Any>(() => new Any());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<Any> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.WellKnownTypes.AnyReflection.Descriptor.MessageTypes[0]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Any() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Any(Any other) : this() {
typeUrl_ = other.typeUrl_;
value_ = other.value_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Any Clone() {
return new Any(this);
}
@@ -102,15 +145,17 @@ namespace Google.Protobuf.WellKnownTypes {
private string typeUrl_ = "";
/// <summary>
/// A URL/resource name whose content describes the type of the
- /// serialized message.
+ /// serialized protocol buffer message.
///
- /// For URLs which use the schema `http`, `https`, or no schema, the
+ /// For URLs which use the scheme `http`, `https`, or no scheme, the
/// following restrictions and interpretations apply:
///
- /// * If no schema is provided, `https` is assumed.
+ /// * If no scheme is provided, `https` is assumed.
/// * The last segment of the URL's path must represent the fully
/// qualified name of the type (as in `path/google.protobuf.Duration`).
- /// * An HTTP GET on the URL must yield a [google.protobuf.Type][google.protobuf.Type]
+ /// The name should be in a canonical form (e.g., leading "." is
+ /// not accepted).
+ /// * An HTTP GET on the URL must yield a [google.protobuf.Type][]
/// value in binary format, or produce an error.
/// * Applications are allowed to cache lookup results based on the
/// URL, or have them precompiled into a binary to avoid any
@@ -118,13 +163,14 @@ namespace Google.Protobuf.WellKnownTypes {
/// on changes to types. (Use versioned type names to manage
/// breaking changes.)
///
- /// Schemas other than `http`, `https` (or the empty schema) might be
+ /// Schemes other than `http`, `https` (or the empty scheme) might be
/// used with implementation specific semantics.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string TypeUrl {
get { return typeUrl_; }
set {
- typeUrl_ = pb::Preconditions.CheckNotNull(value, "value");
+ typeUrl_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -132,19 +178,22 @@ namespace Google.Protobuf.WellKnownTypes {
public const int ValueFieldNumber = 2;
private pb::ByteString value_ = pb::ByteString.Empty;
/// <summary>
- /// Must be valid serialized data of the above specified type.
+ /// Must be a valid serialized protocol buffer of the above specified type.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pb::ByteString Value {
get { return value_; }
set {
- value_ = pb::Preconditions.CheckNotNull(value, "value");
+ value_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as Any);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(Any other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -157,6 +206,7 @@ namespace Google.Protobuf.WellKnownTypes {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (TypeUrl.Length != 0) hash ^= TypeUrl.GetHashCode();
@@ -164,10 +214,12 @@ namespace Google.Protobuf.WellKnownTypes {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (TypeUrl.Length != 0) {
output.WriteRawTag(10);
@@ -179,6 +231,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (TypeUrl.Length != 0) {
@@ -190,6 +243,7 @@ namespace Google.Protobuf.WellKnownTypes {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(Any other) {
if (other == null) {
return;
@@ -202,6 +256,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/AnyPartial.cs b/csharp/src/Google.Protobuf/WellKnownTypes/AnyPartial.cs
index 082f7432..f4fac738 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/AnyPartial.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/AnyPartial.cs
@@ -36,11 +36,27 @@ namespace Google.Protobuf.WellKnownTypes
{
public partial class Any
{
+ private const string DefaultPrefix = "type.googleapis.com";
+
// This could be moved to MessageDescriptor if we wanted to, but keeping it here means
// all the Any-specific code is in the same place.
- private static string GetTypeUrl(MessageDescriptor descriptor)
+ private static string GetTypeUrl(MessageDescriptor descriptor, string prefix) =>
+ prefix.EndsWith("/") ? prefix + descriptor.FullName : prefix + "/" + descriptor.FullName;
+
+ /// <summary>
+ /// Retrieves the type name for a type URL. This is always just the last part of the URL,
+ /// after the trailing slash. No validation of anything before the trailing slash is performed.
+ /// If the type URL does not include a slash, an empty string is returned rather than an exception
+ /// being thrown; this won't match any types, and the calling code is probably in a better position
+ /// to give a meaningful error.
+ /// There is no handling of fragments or queries at the moment.
+ /// </summary>
+ /// <param name="typeUrl">The URL to extract the type name from</param>
+ /// <returns>The type name</returns>
+ internal static string GetTypeName(string typeUrl)
{
- return "type.googleapis.com/" + descriptor.FullName;
+ int lastSlash = typeUrl.LastIndexOf('/');
+ return lastSlash == -1 ? "" : typeUrl.Substring(lastSlash + 1);
}
/// <summary>
@@ -55,25 +71,37 @@ namespace Google.Protobuf.WellKnownTypes
// Note: this doesn't perform as well is it might. We could take a MessageParser<T> in an alternative overload,
// which would be expected to perform slightly better... although the difference is likely to be negligible.
T target = new T();
- string targetTypeUrl = GetTypeUrl(target.Descriptor);
- if (TypeUrl != targetTypeUrl)
+ if (GetTypeName(TypeUrl) != target.Descriptor.FullName)
{
- throw new InvalidProtocolBufferException(string.Format("Type url for {0} is {1}; Any message's type url is {2}",
- target.Descriptor.Name, targetTypeUrl, TypeUrl));
+ throw new InvalidProtocolBufferException(
+ $"Full type name for {target.Descriptor.Name} is {target.Descriptor.FullName}; Any message's type url is {TypeUrl}");
}
target.MergeFrom(Value);
return target;
}
/// <summary>
- /// Packs the specified message into an Any message.
+ /// Packs the specified message into an Any message using a type URL prefix of "type.googleapis.com".
+ /// </summary>
+ /// <param name="message">The message to pack.</param>
+ /// <returns>An Any message with the content and type URL of <paramref name="message"/>.</returns>
+ public static Any Pack(IMessage message) => Pack(message, DefaultPrefix);
+
+ /// <summary>
+ /// Packs the specified message into an Any message using the specified type URL prefix.
/// </summary>
/// <param name="message">The message to pack.</param>
+ /// <param name="typeUrlPrefix">The prefix for the type URL.</param>
/// <returns>An Any message with the content and type URL of <paramref name="message"/>.</returns>
- public static Any Pack(IMessage message)
+ public static Any Pack(IMessage message, string typeUrlPrefix)
{
- Preconditions.CheckNotNull(message, "message");
- return new Any { TypeUrl = GetTypeUrl(message.Descriptor), Value = message.ToByteString() };
+ ProtoPreconditions.CheckNotNull(message, nameof(message));
+ ProtoPreconditions.CheckNotNull(typeUrlPrefix, nameof(typeUrlPrefix));
+ return new Any
+ {
+ TypeUrl = GetTypeUrl(message.Descriptor, typeUrlPrefix),
+ Value = message.ToByteString()
+ };
}
}
}
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Api.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Api.cs
index e9330e69..a9fc51d2 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Api.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Api.cs
@@ -10,7 +10,6 @@ using scg = global::System.Collections.Generic;
namespace Google.Protobuf.WellKnownTypes {
/// <summary>Holder for reflection information generated from google/protobuf/api.proto</summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public static partial class ApiReflection {
#region Descriptor
@@ -41,10 +40,10 @@ namespace Google.Protobuf.WellKnownTypes {
"ZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBlc2IGcHJvdG8z"));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { global::Google.Protobuf.WellKnownTypes.SourceContextReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.TypeReflection.Descriptor, },
- new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Api), global::Google.Protobuf.WellKnownTypes.Api.Parser, new[]{ "Name", "Methods", "Options", "Version", "SourceContext", "Mixins", "Syntax" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Method), global::Google.Protobuf.WellKnownTypes.Method.Parser, new[]{ "Name", "RequestTypeUrl", "RequestStreaming", "ResponseTypeUrl", "ResponseStreaming", "Options", "Syntax" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Mixin), global::Google.Protobuf.WellKnownTypes.Mixin.Parser, new[]{ "Name", "Root" }, null, null, null)
+ new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Api), global::Google.Protobuf.WellKnownTypes.Api.Parser, new[]{ "Name", "Methods", "Options", "Version", "SourceContext", "Mixins", "Syntax" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Method), global::Google.Protobuf.WellKnownTypes.Method.Parser, new[]{ "Name", "RequestTypeUrl", "RequestStreaming", "ResponseTypeUrl", "ResponseStreaming", "Options", "Syntax" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Mixin), global::Google.Protobuf.WellKnownTypes.Mixin.Parser, new[]{ "Name", "Root" }, null, null, null)
}));
}
#endregion
@@ -54,25 +53,29 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// Api is a light-weight descriptor for a protocol buffer service.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class Api : pb::IMessage<Api> {
private static readonly pb::MessageParser<Api> _parser = new pb::MessageParser<Api>(() => new Api());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<Api> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.WellKnownTypes.ApiReflection.Descriptor.MessageTypes[0]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Api() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Api(Api other) : this() {
name_ = other.name_;
methods_ = other.methods_.Clone();
@@ -83,6 +86,7 @@ namespace Google.Protobuf.WellKnownTypes {
syntax_ = other.syntax_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Api Clone() {
return new Api(this);
}
@@ -94,10 +98,11 @@ namespace Google.Protobuf.WellKnownTypes {
/// The fully qualified name of this api, including package name
/// followed by the api's simple name.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string Name {
get { return name_; }
set {
- name_ = pb::Preconditions.CheckNotNull(value, "value");
+ name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -109,6 +114,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// The methods of this api, in unspecified order.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Method> Methods {
get { return methods_; }
}
@@ -121,6 +127,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// Any metadata attached to the API.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Option> Options {
get { return options_; }
}
@@ -150,10 +157,11 @@ namespace Google.Protobuf.WellKnownTypes {
/// be omitted. Zero major versions must only be used for
/// experimental, none-GA apis.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string Version {
get { return version_; }
set {
- version_ = pb::Preconditions.CheckNotNull(value, "value");
+ version_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -164,6 +172,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// Source context for the protocol buffer service represented by this
/// message.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.WellKnownTypes.SourceContext SourceContext {
get { return sourceContext_; }
set {
@@ -179,16 +188,18 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// Included APIs. See [Mixin][].
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Mixin> Mixins {
get { return mixins_; }
}
/// <summary>Field number for the "syntax" field.</summary>
public const int SyntaxFieldNumber = 7;
- private global::Google.Protobuf.WellKnownTypes.Syntax syntax_ = global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2;
+ private global::Google.Protobuf.WellKnownTypes.Syntax syntax_ = 0;
/// <summary>
/// The source syntax of the service.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.WellKnownTypes.Syntax Syntax {
get { return syntax_; }
set {
@@ -196,10 +207,12 @@ namespace Google.Protobuf.WellKnownTypes {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as Api);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(Api other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -217,6 +230,7 @@ namespace Google.Protobuf.WellKnownTypes {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Name.Length != 0) hash ^= Name.GetHashCode();
@@ -225,14 +239,16 @@ namespace Google.Protobuf.WellKnownTypes {
if (Version.Length != 0) hash ^= Version.GetHashCode();
if (sourceContext_ != null) hash ^= SourceContext.GetHashCode();
hash ^= mixins_.GetHashCode();
- if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) hash ^= Syntax.GetHashCode();
+ if (Syntax != 0) hash ^= Syntax.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Name.Length != 0) {
output.WriteRawTag(10);
@@ -249,12 +265,13 @@ namespace Google.Protobuf.WellKnownTypes {
output.WriteMessage(SourceContext);
}
mixins_.WriteTo(output, _repeated_mixins_codec);
- if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) {
+ if (Syntax != 0) {
output.WriteRawTag(56);
output.WriteEnum((int) Syntax);
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Name.Length != 0) {
@@ -269,12 +286,13 @@ namespace Google.Protobuf.WellKnownTypes {
size += 1 + pb::CodedOutputStream.ComputeMessageSize(SourceContext);
}
size += mixins_.CalculateSize(_repeated_mixins_codec);
- if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) {
+ if (Syntax != 0) {
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Syntax);
}
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(Api other) {
if (other == null) {
return;
@@ -294,11 +312,12 @@ namespace Google.Protobuf.WellKnownTypes {
SourceContext.MergeFrom(other.SourceContext);
}
mixins_.Add(other.mixins_);
- if (other.Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) {
+ if (other.Syntax != 0) {
Syntax = other.Syntax;
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -346,25 +365,29 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// Method represents a method of an api.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class Method : pb::IMessage<Method> {
private static readonly pb::MessageParser<Method> _parser = new pb::MessageParser<Method>(() => new Method());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<Method> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.WellKnownTypes.ApiReflection.Descriptor.MessageTypes[1]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Method() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Method(Method other) : this() {
name_ = other.name_;
requestTypeUrl_ = other.requestTypeUrl_;
@@ -375,6 +398,7 @@ namespace Google.Protobuf.WellKnownTypes {
syntax_ = other.syntax_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Method Clone() {
return new Method(this);
}
@@ -385,10 +409,11 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// The simple name of this method.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string Name {
get { return name_; }
set {
- name_ = pb::Preconditions.CheckNotNull(value, "value");
+ name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -398,10 +423,11 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// A URL of the input message type.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string RequestTypeUrl {
get { return requestTypeUrl_; }
set {
- requestTypeUrl_ = pb::Preconditions.CheckNotNull(value, "value");
+ requestTypeUrl_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -411,6 +437,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// If true, the request is streamed.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool RequestStreaming {
get { return requestStreaming_; }
set {
@@ -424,10 +451,11 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// The URL of the output message type.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string ResponseTypeUrl {
get { return responseTypeUrl_; }
set {
- responseTypeUrl_ = pb::Preconditions.CheckNotNull(value, "value");
+ responseTypeUrl_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -437,6 +465,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// If true, the response is streamed.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool ResponseStreaming {
get { return responseStreaming_; }
set {
@@ -452,16 +481,18 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// Any metadata attached to the method.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Option> Options {
get { return options_; }
}
/// <summary>Field number for the "syntax" field.</summary>
public const int SyntaxFieldNumber = 7;
- private global::Google.Protobuf.WellKnownTypes.Syntax syntax_ = global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2;
+ private global::Google.Protobuf.WellKnownTypes.Syntax syntax_ = 0;
/// <summary>
/// The source syntax of this method.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.WellKnownTypes.Syntax Syntax {
get { return syntax_; }
set {
@@ -469,10 +500,12 @@ namespace Google.Protobuf.WellKnownTypes {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as Method);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(Method other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -490,6 +523,7 @@ namespace Google.Protobuf.WellKnownTypes {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Name.Length != 0) hash ^= Name.GetHashCode();
@@ -498,14 +532,16 @@ namespace Google.Protobuf.WellKnownTypes {
if (ResponseTypeUrl.Length != 0) hash ^= ResponseTypeUrl.GetHashCode();
if (ResponseStreaming != false) hash ^= ResponseStreaming.GetHashCode();
hash ^= options_.GetHashCode();
- if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) hash ^= Syntax.GetHashCode();
+ if (Syntax != 0) hash ^= Syntax.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Name.Length != 0) {
output.WriteRawTag(10);
@@ -528,12 +564,13 @@ namespace Google.Protobuf.WellKnownTypes {
output.WriteBool(ResponseStreaming);
}
options_.WriteTo(output, _repeated_options_codec);
- if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) {
+ if (Syntax != 0) {
output.WriteRawTag(56);
output.WriteEnum((int) Syntax);
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Name.Length != 0) {
@@ -552,12 +589,13 @@ namespace Google.Protobuf.WellKnownTypes {
size += 1 + 1;
}
size += options_.CalculateSize(_repeated_options_codec);
- if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) {
+ if (Syntax != 0) {
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Syntax);
}
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(Method other) {
if (other == null) {
return;
@@ -578,11 +616,12 @@ namespace Google.Protobuf.WellKnownTypes {
ResponseStreaming = other.ResponseStreaming;
}
options_.Add(other.options_);
- if (other.Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) {
+ if (other.Syntax != 0) {
Syntax = other.Syntax;
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -653,7 +692,6 @@ namespace Google.Protobuf.WellKnownTypes {
///
/// package google.storage.v2;
/// service Storage {
- /// // (-- see AccessControl.GetAcl --)
/// rpc GetAcl(GetAclRequest) returns (Acl);
///
/// // Get a data record.
@@ -704,30 +742,35 @@ namespace Google.Protobuf.WellKnownTypes {
/// ...
/// }
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class Mixin : pb::IMessage<Mixin> {
private static readonly pb::MessageParser<Mixin> _parser = new pb::MessageParser<Mixin>(() => new Mixin());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<Mixin> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.WellKnownTypes.ApiReflection.Descriptor.MessageTypes[2]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Mixin() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Mixin(Mixin other) : this() {
name_ = other.name_;
root_ = other.root_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Mixin Clone() {
return new Mixin(this);
}
@@ -738,10 +781,11 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// The fully qualified name of the API which is included.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string Name {
get { return name_; }
set {
- name_ = pb::Preconditions.CheckNotNull(value, "value");
+ name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -752,17 +796,20 @@ namespace Google.Protobuf.WellKnownTypes {
/// If non-empty specifies a path under which inherited HTTP paths
/// are rooted.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string Root {
get { return root_; }
set {
- root_ = pb::Preconditions.CheckNotNull(value, "value");
+ root_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as Mixin);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(Mixin other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -775,6 +822,7 @@ namespace Google.Protobuf.WellKnownTypes {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Name.Length != 0) hash ^= Name.GetHashCode();
@@ -782,10 +830,12 @@ namespace Google.Protobuf.WellKnownTypes {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Name.Length != 0) {
output.WriteRawTag(10);
@@ -797,6 +847,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Name.Length != 0) {
@@ -808,6 +859,7 @@ namespace Google.Protobuf.WellKnownTypes {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(Mixin other) {
if (other == null) {
return;
@@ -820,6 +872,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs
index 42fda452..5d52330c 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs
@@ -10,7 +10,6 @@ using scg = global::System.Collections.Generic;
namespace Google.Protobuf.WellKnownTypes {
/// <summary>Holder for reflection information generated from google/protobuf/duration.proto</summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public static partial class DurationReflection {
#region Descriptor
@@ -25,13 +24,14 @@ namespace Google.Protobuf.WellKnownTypes {
string.Concat(
"Ch5nb29nbGUvcHJvdG9idWYvZHVyYXRpb24ucHJvdG8SD2dvb2dsZS5wcm90",
"b2J1ZiIqCghEdXJhdGlvbhIPCgdzZWNvbmRzGAEgASgDEg0KBW5hbm9zGAIg",
- "ASgFQlAKE2NvbS5nb29nbGUucHJvdG9idWZCDUR1cmF0aW9uUHJvdG9QAaAB",
- "AaICA0dQQqoCHkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBlc2IGcHJv",
- "dG8z"));
+ "ASgFQnwKE2NvbS5nb29nbGUucHJvdG9idWZCDUR1cmF0aW9uUHJvdG9QAVoq",
+ "Z2l0aHViLmNvbS9nb2xhbmcvcHJvdG9idWYvcHR5cGVzL2R1cmF0aW9uoAEB",
+ "ogIDR1BCqgIeR29vZ2xlLlByb3RvYnVmLldlbGxLbm93blR5cGVzYgZwcm90",
+ "bzM="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
- new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Duration), global::Google.Protobuf.WellKnownTypes.Duration.Parser, new[]{ "Seconds", "Nanos" }, null, null, null)
+ new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Duration), global::Google.Protobuf.WellKnownTypes.Duration.Parser, new[]{ "Seconds", "Nanos" }, null, null, null)
}));
}
#endregion
@@ -80,30 +80,35 @@ namespace Google.Protobuf.WellKnownTypes {
/// end.nanos -= 1000000000;
/// }
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class Duration : pb::IMessage<Duration> {
private static readonly pb::MessageParser<Duration> _parser = new pb::MessageParser<Duration>(() => new Duration());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<Duration> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.WellKnownTypes.DurationReflection.Descriptor.MessageTypes[0]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Duration() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Duration(Duration other) : this() {
seconds_ = other.seconds_;
nanos_ = other.nanos_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Duration Clone() {
return new Duration(this);
}
@@ -115,6 +120,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// Signed seconds of the span of time. Must be from -315,576,000,000
/// to +315,576,000,000 inclusive.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public long Seconds {
get { return seconds_; }
set {
@@ -133,6 +139,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// of the same sign as the `seconds` field. Must be from -999,999,999
/// to +999,999,999 inclusive.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int Nanos {
get { return nanos_; }
set {
@@ -140,10 +147,12 @@ namespace Google.Protobuf.WellKnownTypes {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as Duration);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(Duration other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -156,6 +165,7 @@ namespace Google.Protobuf.WellKnownTypes {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Seconds != 0L) hash ^= Seconds.GetHashCode();
@@ -163,10 +173,12 @@ namespace Google.Protobuf.WellKnownTypes {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Seconds != 0L) {
output.WriteRawTag(8);
@@ -178,6 +190,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Seconds != 0L) {
@@ -189,6 +202,7 @@ namespace Google.Protobuf.WellKnownTypes {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(Duration other) {
if (other == null) {
return;
@@ -201,6 +215,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/DurationPartial.cs b/csharp/src/Google.Protobuf/WellKnownTypes/DurationPartial.cs
index 324f48fc..f164bfd1 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/DurationPartial.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/DurationPartial.cs
@@ -31,12 +31,14 @@
#endregion
using System;
+using System.Globalization;
+using System.Text;
namespace Google.Protobuf.WellKnownTypes
{
// Manually-written partial class for the Duration well-known type,
// providing a conversion to TimeSpan and convenience operators.
- public partial class Duration
+ public partial class Duration : ICustomDiagnosticMessage
{
/// <summary>
/// The number of nanoseconds in a second.
@@ -57,15 +59,37 @@ namespace Google.Protobuf.WellKnownTypes
/// </summary>
public const long MinSeconds = -315576000000L;
+ internal const int MaxNanoseconds = NanosecondsPerSecond - 1;
+ internal const int MinNanoseconds = -NanosecondsPerSecond + 1;
+
+ internal static bool IsNormalized(long seconds, int nanoseconds)
+ {
+ // Simple boundaries
+ if (seconds < MinSeconds || seconds > MaxSeconds ||
+ nanoseconds < MinNanoseconds || nanoseconds > MaxNanoseconds)
+ {
+ return false;
+ }
+ // We only have a problem is one is strictly negative and the other is
+ // strictly positive.
+ return Math.Sign(seconds) * Math.Sign(nanoseconds) != -1;
+ }
+
/// <summary>
/// Converts this <see cref="Duration"/> to a <see cref="TimeSpan"/>.
/// </summary>
/// <remarks>If the duration is not a precise number of ticks, it is truncated towards 0.</remarks>
/// <returns>The value of this duration, as a <c>TimeSpan</c>.</returns>
+ /// <exception cref="InvalidOperationException">This value isn't a valid normalized duration, as
+ /// described in the documentation.</exception>
public TimeSpan ToTimeSpan()
{
checked
{
+ if (!IsNormalized(Seconds, Nanos))
+ {
+ throw new InvalidOperationException("Duration was not a valid normalized duration");
+ }
long ticks = Seconds * TimeSpan.TicksPerSecond + Nanos / NanosecondsPerTick;
return TimeSpan.FromTicks(ticks);
}
@@ -94,7 +118,7 @@ namespace Google.Protobuf.WellKnownTypes
/// <returns>The negated value of this duration.</returns>
public static Duration operator -(Duration value)
{
- Preconditions.CheckNotNull(value, "value");
+ ProtoPreconditions.CheckNotNull(value, "value");
checked
{
return Normalize(-value.Seconds, -value.Nanos);
@@ -109,8 +133,8 @@ namespace Google.Protobuf.WellKnownTypes
/// <returns></returns>
public static Duration operator +(Duration lhs, Duration rhs)
{
- Preconditions.CheckNotNull(lhs, "lhs");
- Preconditions.CheckNotNull(rhs, "rhs");
+ ProtoPreconditions.CheckNotNull(lhs, "lhs");
+ ProtoPreconditions.CheckNotNull(rhs, "rhs");
checked
{
return Normalize(lhs.Seconds + rhs.Seconds, lhs.Nanos + rhs.Nanos);
@@ -125,8 +149,8 @@ namespace Google.Protobuf.WellKnownTypes
/// <returns>The difference between the two specified durations.</returns>
public static Duration operator -(Duration lhs, Duration rhs)
{
- Preconditions.CheckNotNull(lhs, "lhs");
- Preconditions.CheckNotNull(rhs, "rhs");
+ ProtoPreconditions.CheckNotNull(lhs, "lhs");
+ ProtoPreconditions.CheckNotNull(rhs, "rhs");
checked
{
return Normalize(lhs.Seconds - rhs.Seconds, lhs.Nanos - rhs.Nanos);
@@ -157,5 +181,90 @@ namespace Google.Protobuf.WellKnownTypes
}
return new Duration { Seconds = seconds, Nanos = nanoseconds };
}
+
+ /// <summary>
+ /// Converts a duration specified in seconds/nanoseconds to a string.
+ /// </summary>
+ /// <remarks>
+ /// If the value is a normalized duration in the range described in <c>duration.proto</c>,
+ /// <paramref name="diagnosticOnly"/> is ignored. Otherwise, if the parameter is <c>true</c>,
+ /// a JSON object with a warning is returned; if it is <c>false</c>, an <see cref="InvalidOperationException"/> is thrown.
+ /// </remarks>
+ /// <param name="seconds">Seconds portion of the duration.</param>
+ /// <param name="nanoseconds">Nanoseconds portion of the duration.</param>
+ /// <param name="diagnosticOnly">Determines the handling of non-normalized values</param>
+ /// <exception cref="InvalidOperationException">The represented duration is invalid, and <paramref name="diagnosticOnly"/> is <c>false</c>.</exception>
+ internal static string ToJson(long seconds, int nanoseconds, bool diagnosticOnly)
+ {
+ if (IsNormalized(seconds, nanoseconds))
+ {
+ var builder = new StringBuilder();
+ builder.Append('"');
+ // The seconds part will normally provide the minus sign if we need it, but not if it's 0...
+ if (seconds == 0 && nanoseconds < 0)
+ {
+ builder.Append('-');
+ }
+
+ builder.Append(seconds.ToString("d", CultureInfo.InvariantCulture));
+ AppendNanoseconds(builder, Math.Abs(nanoseconds));
+ builder.Append("s\"");
+ return builder.ToString();
+ }
+ if (diagnosticOnly)
+ {
+ // Note: the double braces here are escaping for braces in format strings.
+ return string.Format(CultureInfo.InvariantCulture,
+ "{{ \"@warning\": \"Invalid Duration\", \"seconds\": \"{0}\", \"nanos\": {1} }}",
+ seconds,
+ nanoseconds);
+ }
+ else
+ {
+ throw new InvalidOperationException("Non-normalized duration value");
+ }
+ }
+
+ /// <summary>
+ /// Returns a string representation of this <see cref="Duration"/> for diagnostic purposes.
+ /// </summary>
+ /// <remarks>
+ /// Normally the returned value will be a JSON string value (including leading and trailing quotes) but
+ /// when the value is non-normalized or out of range, a JSON object representation will be returned
+ /// instead, including a warning. This is to avoid exceptions being thrown when trying to
+ /// diagnose problems - the regular JSON formatter will still throw an exception for non-normalized
+ /// values.
+ /// </remarks>
+ /// <returns>A string representation of this value.</returns>
+ public string ToDiagnosticString()
+ {
+ return ToJson(Seconds, Nanos, true);
+ }
+
+ /// <summary>
+ /// Appends a number of nanoseconds to a StringBuilder. Either 0 digits are added (in which
+ /// case no "." is appended), or 3 6 or 9 digits. This is internal for use in Timestamp as well
+ /// as Duration.
+ /// </summary>
+ internal static void AppendNanoseconds(StringBuilder builder, int nanos)
+ {
+ if (nanos != 0)
+ {
+ builder.Append('.');
+ // Output to 3, 6 or 9 digits.
+ if (nanos % 1000000 == 0)
+ {
+ builder.Append((nanos / 1000000).ToString("d3", CultureInfo.InvariantCulture));
+ }
+ else if (nanos % 1000 == 0)
+ {
+ builder.Append((nanos / 1000).ToString("d6", CultureInfo.InvariantCulture));
+ }
+ else
+ {
+ builder.Append(nanos.ToString("d9", CultureInfo.InvariantCulture));
+ }
+ }
+ }
}
}
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs
index 92bc0397..1d3376ee 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs
@@ -10,7 +10,6 @@ using scg = global::System.Collections.Generic;
namespace Google.Protobuf.WellKnownTypes {
/// <summary>Holder for reflection information generated from google/protobuf/empty.proto</summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public static partial class EmptyReflection {
#region Descriptor
@@ -24,13 +23,14 @@ namespace Google.Protobuf.WellKnownTypes {
byte[] descriptorData = global::System.Convert.FromBase64String(
string.Concat(
"Chtnb29nbGUvcHJvdG9idWYvZW1wdHkucHJvdG8SD2dvb2dsZS5wcm90b2J1",
- "ZiIHCgVFbXB0eUJNChNjb20uZ29vZ2xlLnByb3RvYnVmQgpFbXB0eVByb3Rv",
- "UAGgAQGiAgNHUEKqAh5Hb29nbGUuUHJvdG9idWYuV2VsbEtub3duVHlwZXNi",
- "BnByb3RvMw=="));
+ "ZiIHCgVFbXB0eUJ5ChNjb20uZ29vZ2xlLnByb3RvYnVmQgpFbXB0eVByb3Rv",
+ "UAFaJ2dpdGh1Yi5jb20vZ29sYW5nL3Byb3RvYnVmL3B0eXBlcy9lbXB0eaAB",
+ "AfgBAaICA0dQQqoCHkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBlc2IG",
+ "cHJvdG8z"));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
- new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Empty), global::Google.Protobuf.WellKnownTypes.Empty.Parser, null, null, null, null)
+ new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Empty), global::Google.Protobuf.WellKnownTypes.Empty.Parser, null, null, null, null)
}));
}
#endregion
@@ -48,36 +48,43 @@ namespace Google.Protobuf.WellKnownTypes {
///
/// The JSON representation for `Empty` is empty JSON object `{}`.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class Empty : pb::IMessage<Empty> {
private static readonly pb::MessageParser<Empty> _parser = new pb::MessageParser<Empty>(() => new Empty());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<Empty> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.WellKnownTypes.EmptyReflection.Descriptor.MessageTypes[0]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Empty() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Empty(Empty other) : this() {
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Empty Clone() {
return new Empty(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as Empty);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(Empty other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -88,29 +95,35 @@ namespace Google.Protobuf.WellKnownTypes {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(Empty other) {
if (other == null) {
return;
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs b/csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs
index 963b72be..3b146822 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs
@@ -10,7 +10,6 @@ using scg = global::System.Collections.Generic;
namespace Google.Protobuf.WellKnownTypes {
/// <summary>Holder for reflection information generated from google/protobuf/field_mask.proto</summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public static partial class FieldMaskReflection {
#region Descriptor
@@ -29,8 +28,8 @@ namespace Google.Protobuf.WellKnownTypes {
"Z2xlLlByb3RvYnVmLldlbGxLbm93blR5cGVzYgZwcm90bzM="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
- new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.FieldMask), global::Google.Protobuf.WellKnownTypes.FieldMask.Parser, new[]{ "Paths" }, null, null, null)
+ new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.FieldMask), global::Google.Protobuf.WellKnownTypes.FieldMask.Parser, new[]{ "Paths" }, null, null, null)
}));
}
#endregion
@@ -69,7 +68,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// z: 8
///
/// The result will not contain specific values for fields x,y and z
- /// (there value will be set to the default, and omitted in proto text
+ /// (their value will be set to the default, and omitted in proto text
/// output):
///
/// f {
@@ -86,7 +85,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// operation applies to all fields (as if a FieldMask of all fields
/// had been specified).
///
- /// Note that a field mask does not necessarily applies to the
+ /// Note that a field mask does not necessarily apply to the
/// top-level response message. In case of a REST get operation, the
/// field mask applies directly to the response, but in case of a REST
/// list operation, the mask instead applies to each individual message
@@ -105,6 +104,58 @@ namespace Google.Protobuf.WellKnownTypes {
/// describe the updated values, the API ignores the values of all
/// fields not covered by the mask.
///
+ /// If a repeated field is specified for an update operation, the existing
+ /// repeated values in the target resource will be overwritten by the new values.
+ /// Note that a repeated field is only allowed in the last position of a field
+ /// mask.
+ ///
+ /// If a sub-message is specified in the last position of the field mask for an
+ /// update operation, then the existing sub-message in the target resource is
+ /// overwritten. Given the target message:
+ ///
+ /// f {
+ /// b {
+ /// d : 1
+ /// x : 2
+ /// }
+ /// c : 1
+ /// }
+ ///
+ /// And an update message:
+ ///
+ /// f {
+ /// b {
+ /// d : 10
+ /// }
+ /// }
+ ///
+ /// then if the field mask is:
+ ///
+ /// paths: "f.b"
+ ///
+ /// then the result will be:
+ ///
+ /// f {
+ /// b {
+ /// d : 10
+ /// }
+ /// c : 1
+ /// }
+ ///
+ /// However, if the update mask was:
+ ///
+ /// paths: "f.b.d"
+ ///
+ /// then the result would be:
+ ///
+ /// f {
+ /// b {
+ /// d : 10
+ /// x : 2
+ /// }
+ /// c : 1
+ /// }
+ ///
/// In order to reset a field's value to the default, the field must
/// be in the mask and set to the default value in the provided resource.
/// Hence, in order to reset all fields of a resource, provide a default
@@ -159,30 +210,62 @@ namespace Google.Protobuf.WellKnownTypes {
/// {
/// mask: "user.displayName,photo"
/// }
+ ///
+ /// # Field Masks and Oneof Fields
+ ///
+ /// Field masks treat fields in oneofs just as regular fields. Consider the
+ /// following message:
+ ///
+ /// message SampleMessage {
+ /// oneof test_oneof {
+ /// string name = 4;
+ /// SubMessage sub_message = 9;
+ /// }
+ /// }
+ ///
+ /// The field mask can be:
+ ///
+ /// mask {
+ /// paths: "name"
+ /// }
+ ///
+ /// Or:
+ ///
+ /// mask {
+ /// paths: "sub_message"
+ /// }
+ ///
+ /// Note that oneof type names ("test_oneof" in this case) cannot be used in
+ /// paths.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class FieldMask : pb::IMessage<FieldMask> {
private static readonly pb::MessageParser<FieldMask> _parser = new pb::MessageParser<FieldMask>(() => new FieldMask());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<FieldMask> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.WellKnownTypes.FieldMaskReflection.Descriptor.MessageTypes[0]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public FieldMask() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public FieldMask(FieldMask other) : this() {
paths_ = other.paths_.Clone();
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public FieldMask Clone() {
return new FieldMask(this);
}
@@ -195,14 +278,17 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// The set of field mask paths.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<string> Paths {
get { return paths_; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as FieldMask);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(FieldMask other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -214,26 +300,31 @@ namespace Google.Protobuf.WellKnownTypes {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
hash ^= paths_.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
paths_.WriteTo(output, _repeated_paths_codec);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
size += paths_.CalculateSize(_repeated_paths_codec);
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(FieldMask other) {
if (other == null) {
return;
@@ -241,6 +332,7 @@ namespace Google.Protobuf.WellKnownTypes {
paths_.Add(other.paths_);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/FieldMaskPartial.cs b/csharp/src/Google.Protobuf/WellKnownTypes/FieldMaskPartial.cs
new file mode 100644
index 00000000..f9cdb8af
--- /dev/null
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/FieldMaskPartial.cs
@@ -0,0 +1,128 @@
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2016 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.
+#endregion
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace Google.Protobuf.WellKnownTypes
+{
+ // Manually-written partial class for the FieldMask well-known type.
+ public partial class FieldMask : ICustomDiagnosticMessage
+ {
+ /// <summary>
+ /// Converts a timestamp specified in seconds/nanoseconds to a string.
+ /// </summary>
+ /// <remarks>
+ /// If the value is a normalized duration in the range described in <c>field_mask.proto</c>,
+ /// <paramref name="diagnosticOnly"/> is ignored. Otherwise, if the parameter is <c>true</c>,
+ /// a JSON object with a warning is returned; if it is <c>false</c>, an <see cref="InvalidOperationException"/> is thrown.
+ /// </remarks>
+ /// <param name="paths">Paths in the field mask</param>
+ /// <param name="diagnosticOnly">Determines the handling of non-normalized values</param>
+ /// <exception cref="InvalidOperationException">The represented duration is invalid, and <paramref name="diagnosticOnly"/> is <c>false</c>.</exception>
+ internal static string ToJson(IList<string> paths, bool diagnosticOnly)
+ {
+ var firstInvalid = paths.FirstOrDefault(p => !ValidatePath(p));
+ if (firstInvalid == null)
+ {
+ var writer = new StringWriter();
+#if DOTNET35
+ var query = paths.Select(JsonFormatter.ToCamelCase);
+ JsonFormatter.WriteString(writer, string.Join(",", query.ToArray()));
+#else
+ JsonFormatter.WriteString(writer, string.Join(",", paths.Select(JsonFormatter.ToCamelCase)));
+#endif
+ return writer.ToString();
+ }
+ else
+ {
+ if (diagnosticOnly)
+ {
+ var writer = new StringWriter();
+ writer.Write("{ \"@warning\": \"Invalid FieldMask\", \"paths\": ");
+ JsonFormatter.Default.WriteList(writer, (IList)paths);
+ writer.Write(" }");
+ return writer.ToString();
+ }
+ else
+ {
+ throw new InvalidOperationException($"Invalid field mask to be converted to JSON: {firstInvalid}");
+ }
+ }
+ }
+
+ /// <summary>
+ /// Camel-case converter with added strictness for field mask formatting.
+ /// </summary>
+ /// <exception cref="InvalidOperationException">The field mask is invalid for JSON representation</exception>
+ private static bool ValidatePath(string input)
+ {
+ for (int i = 0; i < input.Length; i++)
+ {
+ char c = input[i];
+ if (c >= 'A' && c <= 'Z')
+ {
+ return false;
+ }
+ if (c == '_' && i < input.Length - 1)
+ {
+ char next = input[i + 1];
+ if (next < 'a' || next > 'z')
+ {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ /// <summary>
+ /// Returns a string representation of this <see cref="FieldMask"/> for diagnostic purposes.
+ /// </summary>
+ /// <remarks>
+ /// Normally the returned value will be a JSON string value (including leading and trailing quotes) but
+ /// when the value is non-normalized or out of range, a JSON object representation will be returned
+ /// instead, including a warning. This is to avoid exceptions being thrown when trying to
+ /// diagnose problems - the regular JSON formatter will still throw an exception for non-normalized
+ /// values.
+ /// </remarks>
+ /// <returns>A string representation of this value.</returns>
+ public string ToDiagnosticString()
+ {
+ return ToJson(Paths, true);
+ }
+ }
+}
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/SourceContext.cs b/csharp/src/Google.Protobuf/WellKnownTypes/SourceContext.cs
index d5385642..c9992d2d 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/SourceContext.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/SourceContext.cs
@@ -10,7 +10,6 @@ using scg = global::System.Collections.Generic;
namespace Google.Protobuf.WellKnownTypes {
/// <summary>Holder for reflection information generated from google/protobuf/source_context.proto</summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public static partial class SourceContextReflection {
#region Descriptor
@@ -30,8 +29,8 @@ namespace Google.Protobuf.WellKnownTypes {
"cHJvdG8z"));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
- new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.SourceContext), global::Google.Protobuf.WellKnownTypes.SourceContext.Parser, new[]{ "FileName" }, null, null, null)
+ new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.SourceContext), global::Google.Protobuf.WellKnownTypes.SourceContext.Parser, new[]{ "FileName" }, null, null, null)
}));
}
#endregion
@@ -42,29 +41,34 @@ namespace Google.Protobuf.WellKnownTypes {
/// `SourceContext` represents information about the source of a
/// protobuf element, like the file in which it is defined.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class SourceContext : pb::IMessage<SourceContext> {
private static readonly pb::MessageParser<SourceContext> _parser = new pb::MessageParser<SourceContext>(() => new SourceContext());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<SourceContext> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.WellKnownTypes.SourceContextReflection.Descriptor.MessageTypes[0]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public SourceContext() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public SourceContext(SourceContext other) : this() {
fileName_ = other.fileName_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public SourceContext Clone() {
return new SourceContext(this);
}
@@ -74,19 +78,22 @@ namespace Google.Protobuf.WellKnownTypes {
private string fileName_ = "";
/// <summary>
/// The path-qualified name of the .proto file that contained the associated
- /// protobuf element. For example: `"google/protobuf/source.proto"`.
+ /// protobuf element. For example: `"google/protobuf/source_context.proto"`.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string FileName {
get { return fileName_; }
set {
- fileName_ = pb::Preconditions.CheckNotNull(value, "value");
+ fileName_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as SourceContext);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(SourceContext other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -98,16 +105,19 @@ namespace Google.Protobuf.WellKnownTypes {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (FileName.Length != 0) hash ^= FileName.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (FileName.Length != 0) {
output.WriteRawTag(10);
@@ -115,6 +125,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (FileName.Length != 0) {
@@ -123,6 +134,7 @@ namespace Google.Protobuf.WellKnownTypes {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(SourceContext other) {
if (other == null) {
return;
@@ -132,6 +144,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs
index 73e3cae2..b3d62fbf 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs
@@ -10,7 +10,6 @@ using scg = global::System.Collections.Generic;
namespace Google.Protobuf.WellKnownTypes {
/// <summary>Holder for reflection information generated from google/protobuf/struct.proto</summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public static partial class StructReflection {
#region Descriptor
@@ -34,15 +33,16 @@ namespace Google.Protobuf.WellKnownTypes {
"ABIwCgpsaXN0X3ZhbHVlGAYgASgLMhouZ29vZ2xlLnByb3RvYnVmLkxpc3RW",
"YWx1ZUgAQgYKBGtpbmQiMwoJTGlzdFZhbHVlEiYKBnZhbHVlcxgBIAMoCzIW",
"Lmdvb2dsZS5wcm90b2J1Zi5WYWx1ZSobCglOdWxsVmFsdWUSDgoKTlVMTF9W",
- "QUxVRRAAQk4KE2NvbS5nb29nbGUucHJvdG9idWZCC1N0cnVjdFByb3RvUAGg",
- "AQGiAgNHUEKqAh5Hb29nbGUuUHJvdG9idWYuV2VsbEtub3duVHlwZXNiBnBy",
- "b3RvMw=="));
+ "QUxVRRAAQoEBChNjb20uZ29vZ2xlLnByb3RvYnVmQgtTdHJ1Y3RQcm90b1AB",
+ "WjFnaXRodWIuY29tL2dvbGFuZy9wcm90b2J1Zi9wdHlwZXMvc3RydWN0O3N0",
+ "cnVjdHBioAEBogIDR1BCqgIeR29vZ2xlLlByb3RvYnVmLldlbGxLbm93blR5",
+ "cGVzYgZwcm90bzM="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
- new pbr::GeneratedCodeInfo(new[] {typeof(global::Google.Protobuf.WellKnownTypes.NullValue), }, new pbr::GeneratedCodeInfo[] {
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Struct), global::Google.Protobuf.WellKnownTypes.Struct.Parser, new[]{ "Fields" }, null, null, new pbr::GeneratedCodeInfo[] { null, }),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Value), global::Google.Protobuf.WellKnownTypes.Value.Parser, new[]{ "NullValue", "NumberValue", "StringValue", "BoolValue", "StructValue", "ListValue" }, new[]{ "Kind" }, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.ListValue), global::Google.Protobuf.WellKnownTypes.ListValue.Parser, new[]{ "Values" }, null, null, null)
+ new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Google.Protobuf.WellKnownTypes.NullValue), }, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Struct), global::Google.Protobuf.WellKnownTypes.Struct.Parser, new[]{ "Fields" }, null, null, new pbr::GeneratedClrTypeInfo[] { null, }),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Value), global::Google.Protobuf.WellKnownTypes.Value.Parser, new[]{ "NullValue", "NumberValue", "StringValue", "BoolValue", "StructValue", "ListValue" }, new[]{ "Kind" }, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.ListValue), global::Google.Protobuf.WellKnownTypes.ListValue.Parser, new[]{ "Values" }, null, null, null)
}));
}
#endregion
@@ -59,7 +59,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// Null value.
/// </summary>
- NULL_VALUE = 0,
+ [pbr::OriginalName("NULL_VALUE")] NullValue = 0,
}
#endregion
@@ -75,29 +75,34 @@ namespace Google.Protobuf.WellKnownTypes {
///
/// The JSON representation for `Struct` is JSON object.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class Struct : pb::IMessage<Struct> {
private static readonly pb::MessageParser<Struct> _parser = new pb::MessageParser<Struct>(() => new Struct());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<Struct> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.WellKnownTypes.StructReflection.Descriptor.MessageTypes[0]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Struct() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Struct(Struct other) : this() {
fields_ = other.fields_.Clone();
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Struct Clone() {
return new Struct(this);
}
@@ -108,16 +113,19 @@ namespace Google.Protobuf.WellKnownTypes {
= new pbc::MapField<string, global::Google.Protobuf.WellKnownTypes.Value>.Codec(pb::FieldCodec.ForString(10), pb::FieldCodec.ForMessage(18, global::Google.Protobuf.WellKnownTypes.Value.Parser), 10);
private readonly pbc::MapField<string, global::Google.Protobuf.WellKnownTypes.Value> fields_ = new pbc::MapField<string, global::Google.Protobuf.WellKnownTypes.Value>();
/// <summary>
- /// Map of dynamically typed values.
+ /// Unordered map of dynamically typed values.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<string, global::Google.Protobuf.WellKnownTypes.Value> Fields {
get { return fields_; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as Struct);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(Struct other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -129,26 +137,31 @@ namespace Google.Protobuf.WellKnownTypes {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
hash ^= Fields.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
fields_.WriteTo(output, _map_fields_codec);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
size += fields_.CalculateSize(_map_fields_codec);
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(Struct other) {
if (other == null) {
return;
@@ -156,6 +169,7 @@ namespace Google.Protobuf.WellKnownTypes {
fields_.Add(other.fields_);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -181,25 +195,29 @@ namespace Google.Protobuf.WellKnownTypes {
///
/// The JSON representation for `Value` is JSON value.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class Value : pb::IMessage<Value> {
private static readonly pb::MessageParser<Value> _parser = new pb::MessageParser<Value>(() => new Value());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<Value> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.WellKnownTypes.StructReflection.Descriptor.MessageTypes[1]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Value() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Value(Value other) : this() {
switch (other.KindCase) {
case KindOneofCase.NullValue:
@@ -224,6 +242,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Value Clone() {
return new Value(this);
}
@@ -233,8 +252,9 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// Represents a null value.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.WellKnownTypes.NullValue NullValue {
- get { return kindCase_ == KindOneofCase.NullValue ? (global::Google.Protobuf.WellKnownTypes.NullValue) kind_ : global::Google.Protobuf.WellKnownTypes.NullValue.NULL_VALUE; }
+ get { return kindCase_ == KindOneofCase.NullValue ? (global::Google.Protobuf.WellKnownTypes.NullValue) kind_ : 0; }
set {
kind_ = value;
kindCase_ = KindOneofCase.NullValue;
@@ -246,6 +266,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// Represents a double value.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public double NumberValue {
get { return kindCase_ == KindOneofCase.NumberValue ? (double) kind_ : 0D; }
set {
@@ -259,10 +280,11 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// Represents a string value.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string StringValue {
get { return kindCase_ == KindOneofCase.StringValue ? (string) kind_ : ""; }
set {
- kind_ = pb::Preconditions.CheckNotNull(value, "value");
+ kind_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
kindCase_ = KindOneofCase.StringValue;
}
}
@@ -272,6 +294,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// Represents a boolean value.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool BoolValue {
get { return kindCase_ == KindOneofCase.BoolValue ? (bool) kind_ : false; }
set {
@@ -285,6 +308,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// Represents a structured value.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.WellKnownTypes.Struct StructValue {
get { return kindCase_ == KindOneofCase.StructValue ? (global::Google.Protobuf.WellKnownTypes.Struct) kind_ : null; }
set {
@@ -298,6 +322,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// Represents a repeated `Value`.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.WellKnownTypes.ListValue ListValue {
get { return kindCase_ == KindOneofCase.ListValue ? (global::Google.Protobuf.WellKnownTypes.ListValue) kind_ : null; }
set {
@@ -318,19 +343,23 @@ namespace Google.Protobuf.WellKnownTypes {
ListValue = 6,
}
private KindOneofCase kindCase_ = KindOneofCase.None;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public KindOneofCase KindCase {
get { return kindCase_; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void ClearKind() {
kindCase_ = KindOneofCase.None;
kind_ = null;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as Value);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(Value other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -348,6 +377,7 @@ namespace Google.Protobuf.WellKnownTypes {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (kindCase_ == KindOneofCase.NullValue) hash ^= NullValue.GetHashCode();
@@ -360,10 +390,12 @@ namespace Google.Protobuf.WellKnownTypes {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (kindCase_ == KindOneofCase.NullValue) {
output.WriteRawTag(8);
@@ -391,6 +423,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (kindCase_ == KindOneofCase.NullValue) {
@@ -414,6 +447,7 @@ namespace Google.Protobuf.WellKnownTypes {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(Value other) {
if (other == null) {
return;
@@ -441,6 +475,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -494,29 +529,34 @@ namespace Google.Protobuf.WellKnownTypes {
///
/// The JSON representation for `ListValue` is JSON array.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class ListValue : pb::IMessage<ListValue> {
private static readonly pb::MessageParser<ListValue> _parser = new pb::MessageParser<ListValue>(() => new ListValue());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<ListValue> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.WellKnownTypes.StructReflection.Descriptor.MessageTypes[2]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ListValue() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ListValue(ListValue other) : this() {
values_ = other.values_.Clone();
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ListValue Clone() {
return new ListValue(this);
}
@@ -529,14 +569,17 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// Repeated field of dynamically typed values.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Value> Values {
get { return values_; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as ListValue);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(ListValue other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -548,26 +591,31 @@ namespace Google.Protobuf.WellKnownTypes {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
hash ^= values_.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
values_.WriteTo(output, _repeated_values_codec);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
size += values_.CalculateSize(_repeated_values_codec);
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(ListValue other) {
if (other == null) {
return;
@@ -575,6 +623,7 @@ namespace Google.Protobuf.WellKnownTypes {
values_.Add(other.values_);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/TimeExtensions.cs b/csharp/src/Google.Protobuf/WellKnownTypes/TimeExtensions.cs
index dd485d32..8b63d630 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/TimeExtensions.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/TimeExtensions.cs
@@ -31,10 +31,6 @@
#endregion
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
namespace Google.Protobuf.WellKnownTypes
{
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs
index 499b0950..5157e6d5 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs
@@ -10,7 +10,6 @@ using scg = global::System.Collections.Generic;
namespace Google.Protobuf.WellKnownTypes {
/// <summary>Holder for reflection information generated from google/protobuf/timestamp.proto</summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public static partial class TimestampReflection {
#region Descriptor
@@ -25,13 +24,14 @@ namespace Google.Protobuf.WellKnownTypes {
string.Concat(
"Ch9nb29nbGUvcHJvdG9idWYvdGltZXN0YW1wLnByb3RvEg9nb29nbGUucHJv",
"dG9idWYiKwoJVGltZXN0YW1wEg8KB3NlY29uZHMYASABKAMSDQoFbmFub3MY",
- "AiABKAVCUQoTY29tLmdvb2dsZS5wcm90b2J1ZkIOVGltZXN0YW1wUHJvdG9Q",
- "AaABAaICA0dQQqoCHkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBlc2IG",
- "cHJvdG8z"));
+ "AiABKAVCgQEKE2NvbS5nb29nbGUucHJvdG9idWZCDlRpbWVzdGFtcFByb3Rv",
+ "UAFaK2dpdGh1Yi5jb20vZ29sYW5nL3Byb3RvYnVmL3B0eXBlcy90aW1lc3Rh",
+ "bXCgAQH4AQGiAgNHUEKqAh5Hb29nbGUuUHJvdG9idWYuV2VsbEtub3duVHlw",
+ "ZXNiBnByb3RvMw=="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
- new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Timestamp), global::Google.Protobuf.WellKnownTypes.Timestamp.Parser, new[]{ "Seconds", "Nanos" }, null, null, null)
+ new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Timestamp), global::Google.Protobuf.WellKnownTypes.Timestamp.Parser, new[]{ "Seconds", "Nanos" }, null, null, null)
}));
}
#endregion
@@ -92,30 +92,35 @@ namespace Google.Protobuf.WellKnownTypes {
/// nanos = int((now - seconds) * 10**9)
/// timestamp = Timestamp(seconds=seconds, nanos=nanos)
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class Timestamp : pb::IMessage<Timestamp> {
private static readonly pb::MessageParser<Timestamp> _parser = new pb::MessageParser<Timestamp>(() => new Timestamp());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<Timestamp> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.WellKnownTypes.TimestampReflection.Descriptor.MessageTypes[0]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Timestamp() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Timestamp(Timestamp other) : this() {
seconds_ = other.seconds_;
nanos_ = other.nanos_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Timestamp Clone() {
return new Timestamp(this);
}
@@ -128,6 +133,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// 1970-01-01T00:00:00Z. Must be from from 0001-01-01T00:00:00Z to
/// 9999-12-31T23:59:59Z inclusive.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public long Seconds {
get { return seconds_; }
set {
@@ -144,6 +150,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// that count forward in time. Must be from 0 to 999,999,999
/// inclusive.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int Nanos {
get { return nanos_; }
set {
@@ -151,10 +158,12 @@ namespace Google.Protobuf.WellKnownTypes {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as Timestamp);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(Timestamp other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -167,6 +176,7 @@ namespace Google.Protobuf.WellKnownTypes {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Seconds != 0L) hash ^= Seconds.GetHashCode();
@@ -174,10 +184,12 @@ namespace Google.Protobuf.WellKnownTypes {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Seconds != 0L) {
output.WriteRawTag(8);
@@ -189,6 +201,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Seconds != 0L) {
@@ -200,6 +213,7 @@ namespace Google.Protobuf.WellKnownTypes {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(Timestamp other) {
if (other == null) {
return;
@@ -212,6 +226,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/TimestampPartial.cs b/csharp/src/Google.Protobuf/WellKnownTypes/TimestampPartial.cs
index d284acd6..aa403473 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/TimestampPartial.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/TimestampPartial.cs
@@ -31,15 +31,25 @@
#endregion
using System;
+using System.Globalization;
+using System.Text;
namespace Google.Protobuf.WellKnownTypes
{
- public partial class Timestamp
+ public partial class Timestamp : ICustomDiagnosticMessage
{
private static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
- private static readonly long BclSecondsAtUnixEpoch = UnixEpoch.Ticks / TimeSpan.TicksPerSecond;
- internal static readonly long UnixSecondsAtBclMinValue = -BclSecondsAtUnixEpoch;
- internal static readonly long UnixSecondsAtBclMaxValue = (DateTime.MaxValue.Ticks / TimeSpan.TicksPerSecond) - BclSecondsAtUnixEpoch;
+ // Constants determined programmatically, but then hard-coded so they can be constant expressions.
+ private const long BclSecondsAtUnixEpoch = 62135596800;
+ internal const long UnixSecondsAtBclMaxValue = 253402300799;
+ internal const long UnixSecondsAtBclMinValue = -BclSecondsAtUnixEpoch;
+ internal const int MaxNanos = Duration.NanosecondsPerSecond - 1;
+
+ private static bool IsNormalized(long seconds, int nanoseconds) =>
+ nanoseconds >= 0 &&
+ nanoseconds <= MaxNanos &&
+ seconds >= UnixSecondsAtBclMinValue &&
+ seconds <= UnixSecondsAtBclMaxValue;
/// <summary>
/// Returns the difference between one <see cref="Timestamp"/> and another, as a <see cref="Duration"/>.
@@ -49,8 +59,8 @@ namespace Google.Protobuf.WellKnownTypes
/// <returns>The difference between the two specified timestamps.</returns>
public static Duration operator -(Timestamp lhs, Timestamp rhs)
{
- Preconditions.CheckNotNull(lhs, "lhs");
- Preconditions.CheckNotNull(rhs, "rhs");
+ ProtoPreconditions.CheckNotNull(lhs, "lhs");
+ ProtoPreconditions.CheckNotNull(rhs, "rhs");
checked
{
return Duration.Normalize(lhs.Seconds - rhs.Seconds, lhs.Nanos - rhs.Nanos);
@@ -65,8 +75,8 @@ namespace Google.Protobuf.WellKnownTypes
/// <returns>The result of adding the duration to the timestamp.</returns>
public static Timestamp operator +(Timestamp lhs, Duration rhs)
{
- Preconditions.CheckNotNull(lhs, "lhs");
- Preconditions.CheckNotNull(rhs, "rhs");
+ ProtoPreconditions.CheckNotNull(lhs, "lhs");
+ ProtoPreconditions.CheckNotNull(rhs, "rhs");
checked
{
return Normalize(lhs.Seconds + rhs.Seconds, lhs.Nanos + rhs.Nanos);
@@ -81,8 +91,8 @@ namespace Google.Protobuf.WellKnownTypes
/// <returns>The result of subtracting the duration from the timestamp.</returns>
public static Timestamp operator -(Timestamp lhs, Duration rhs)
{
- Preconditions.CheckNotNull(lhs, "lhs");
- Preconditions.CheckNotNull(rhs, "rhs");
+ ProtoPreconditions.CheckNotNull(lhs, "lhs");
+ ProtoPreconditions.CheckNotNull(rhs, "rhs");
checked
{
return Normalize(lhs.Seconds - rhs.Seconds, lhs.Nanos - rhs.Nanos);
@@ -99,8 +109,14 @@ namespace Google.Protobuf.WellKnownTypes
/// <see cref="DateTime"/> value precisely on a second.
/// </remarks>
/// <returns>This timestamp as a <c>DateTime</c>.</returns>
+ /// <exception cref="InvalidOperationException">The timestamp contains invalid values; either it is
+ /// incorrectly normalized or is outside the valid range.</exception>
public DateTime ToDateTime()
{
+ if (!IsNormalized(Seconds, Nanos))
+ {
+ throw new InvalidOperationException(@"Timestamp contains invalid values: Seconds={Seconds}; Nanos={Nanos}");
+ }
return UnixEpoch.AddSeconds(Seconds).AddTicks(Nanos / Duration.NanosecondsPerTick);
}
@@ -114,6 +130,8 @@ namespace Google.Protobuf.WellKnownTypes
/// <see cref="DateTimeOffset"/> value precisely on a second.
/// </remarks>
/// <returns>This timestamp as a <c>DateTimeOffset</c>.</returns>
+ /// <exception cref="InvalidOperationException">The timestamp contains invalid values; either it is
+ /// incorrectly normalized or is outside the valid range.</exception>
public DateTimeOffset ToDateTimeOffset()
{
return new DateTimeOffset(ToDateTime(), TimeSpan.Zero);
@@ -165,5 +183,59 @@ namespace Google.Protobuf.WellKnownTypes
}
return new Timestamp { Seconds = seconds, Nanos = nanoseconds };
}
+
+ /// <summary>
+ /// Converts a timestamp specified in seconds/nanoseconds to a string.
+ /// </summary>
+ /// <remarks>
+ /// If the value is a normalized duration in the range described in <c>timestamp.proto</c>,
+ /// <paramref name="diagnosticOnly"/> is ignored. Otherwise, if the parameter is <c>true</c>,
+ /// a JSON object with a warning is returned; if it is <c>false</c>, an <see cref="InvalidOperationException"/> is thrown.
+ /// </remarks>
+ /// <param name="seconds">Seconds portion of the duration.</param>
+ /// <param name="nanoseconds">Nanoseconds portion of the duration.</param>
+ /// <param name="diagnosticOnly">Determines the handling of non-normalized values</param>
+ /// <exception cref="InvalidOperationException">The represented duration is invalid, and <paramref name="diagnosticOnly"/> is <c>false</c>.</exception>
+ internal static string ToJson(long seconds, int nanoseconds, bool diagnosticOnly)
+ {
+ if (IsNormalized(seconds, nanoseconds))
+ {
+ // Use .NET's formatting for the value down to the second, including an opening double quote (as it's a string value)
+ DateTime dateTime = UnixEpoch.AddSeconds(seconds);
+ var builder = new StringBuilder();
+ builder.Append('"');
+ builder.Append(dateTime.ToString("yyyy'-'MM'-'dd'T'HH:mm:ss", CultureInfo.InvariantCulture));
+ Duration.AppendNanoseconds(builder, nanoseconds);
+ builder.Append("Z\"");
+ return builder.ToString();
+ }
+ if (diagnosticOnly)
+ {
+ return string.Format(CultureInfo.InvariantCulture,
+ "{{ \"@warning\": \"Invalid Timestamp\", \"seconds\": \"{0}\", \"nanos\": {1} }}",
+ seconds,
+ nanoseconds);
+ }
+ else
+ {
+ throw new InvalidOperationException("Non-normalized timestamp value");
+ }
+ }
+
+ /// <summary>
+ /// Returns a string representation of this <see cref="Timestamp"/> for diagnostic purposes.
+ /// </summary>
+ /// <remarks>
+ /// Normally the returned value will be a JSON string value (including leading and trailing quotes) but
+ /// when the value is non-normalized or out of range, a JSON object representation will be returned
+ /// instead, including a warning. This is to avoid exceptions being thrown when trying to
+ /// diagnose problems - the regular JSON formatter will still throw an exception for non-normalized
+ /// values.
+ /// </remarks>
+ /// <returns>A string representation of this value.</returns>
+ public string ToDiagnosticString()
+ {
+ return ToJson(Seconds, Nanos, true);
+ }
}
}
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Type.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Type.cs
index ef368bd3..2bad3432 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Type.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Type.cs
@@ -10,7 +10,6 @@ using scg = global::System.Collections.Generic;
namespace Google.Protobuf.WellKnownTypes {
/// <summary>Holder for reflection information generated from google/protobuf/type.proto</summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public static partial class TypeReflection {
#region Descriptor
@@ -30,41 +29,42 @@ namespace Google.Protobuf.WellKnownTypes {
"b2ZzGAMgAygJEigKB29wdGlvbnMYBCADKAsyFy5nb29nbGUucHJvdG9idWYu",
"T3B0aW9uEjYKDnNvdXJjZV9jb250ZXh0GAUgASgLMh4uZ29vZ2xlLnByb3Rv",
"YnVmLlNvdXJjZUNvbnRleHQSJwoGc3ludGF4GAYgASgOMhcuZ29vZ2xlLnBy",
- "b3RvYnVmLlN5bnRheCK+BQoFRmllbGQSKQoEa2luZBgBIAEoDjIbLmdvb2ds",
+ "b3RvYnVmLlN5bnRheCLVBQoFRmllbGQSKQoEa2luZBgBIAEoDjIbLmdvb2ds",
"ZS5wcm90b2J1Zi5GaWVsZC5LaW5kEjcKC2NhcmRpbmFsaXR5GAIgASgOMiIu",
"Z29vZ2xlLnByb3RvYnVmLkZpZWxkLkNhcmRpbmFsaXR5Eg4KBm51bWJlchgD",
"IAEoBRIMCgRuYW1lGAQgASgJEhAKCHR5cGVfdXJsGAYgASgJEhMKC29uZW9m",
"X2luZGV4GAcgASgFEg4KBnBhY2tlZBgIIAEoCBIoCgdvcHRpb25zGAkgAygL",
- "MhcuZ29vZ2xlLnByb3RvYnVmLk9wdGlvbhIRCglqc29uX25hbWUYCiABKAki",
- "yAIKBEtpbmQSEAoMVFlQRV9VTktOT1dOEAASDwoLVFlQRV9ET1VCTEUQARIO",
- "CgpUWVBFX0ZMT0FUEAISDgoKVFlQRV9JTlQ2NBADEg8KC1RZUEVfVUlOVDY0",
- "EAQSDgoKVFlQRV9JTlQzMhAFEhAKDFRZUEVfRklYRUQ2NBAGEhAKDFRZUEVf",
- "RklYRUQzMhAHEg0KCVRZUEVfQk9PTBAIEg8KC1RZUEVfU1RSSU5HEAkSDgoK",
- "VFlQRV9HUk9VUBAKEhAKDFRZUEVfTUVTU0FHRRALEg4KClRZUEVfQllURVMQ",
- "DBIPCgtUWVBFX1VJTlQzMhANEg0KCVRZUEVfRU5VTRAOEhEKDVRZUEVfU0ZJ",
- "WEVEMzIQDxIRCg1UWVBFX1NGSVhFRDY0EBASDwoLVFlQRV9TSU5UMzIQERIP",
- "CgtUWVBFX1NJTlQ2NBASInQKC0NhcmRpbmFsaXR5EhcKE0NBUkRJTkFMSVRZ",
- "X1VOS05PV04QABIYChRDQVJESU5BTElUWV9PUFRJT05BTBABEhgKFENBUkRJ",
- "TkFMSVRZX1JFUVVJUkVEEAISGAoUQ0FSRElOQUxJVFlfUkVQRUFURUQQAyLO",
- "AQoERW51bRIMCgRuYW1lGAEgASgJEi0KCWVudW12YWx1ZRgCIAMoCzIaLmdv",
- "b2dsZS5wcm90b2J1Zi5FbnVtVmFsdWUSKAoHb3B0aW9ucxgDIAMoCzIXLmdv",
- "b2dsZS5wcm90b2J1Zi5PcHRpb24SNgoOc291cmNlX2NvbnRleHQYBCABKAsy",
- "Hi5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dBInCgZzeW50YXgYBSAB",
- "KA4yFy5nb29nbGUucHJvdG9idWYuU3ludGF4IlMKCUVudW1WYWx1ZRIMCgRu",
- "YW1lGAEgASgJEg4KBm51bWJlchgCIAEoBRIoCgdvcHRpb25zGAMgAygLMhcu",
- "Z29vZ2xlLnByb3RvYnVmLk9wdGlvbiI7CgZPcHRpb24SDAoEbmFtZRgBIAEo",
- "CRIjCgV2YWx1ZRgCIAEoCzIULmdvb2dsZS5wcm90b2J1Zi5BbnkqLgoGU3lu",
- "dGF4EhEKDVNZTlRBWF9QUk9UTzIQABIRCg1TWU5UQVhfUFJPVE8zEAFCTAoT",
- "Y29tLmdvb2dsZS5wcm90b2J1ZkIJVHlwZVByb3RvUAGgAQGiAgNHUEKqAh5H",
- "b29nbGUuUHJvdG9idWYuV2VsbEtub3duVHlwZXNiBnByb3RvMw=="));
+ "MhcuZ29vZ2xlLnByb3RvYnVmLk9wdGlvbhIRCglqc29uX25hbWUYCiABKAkS",
+ "FQoNZGVmYXVsdF92YWx1ZRgLIAEoCSLIAgoES2luZBIQCgxUWVBFX1VOS05P",
+ "V04QABIPCgtUWVBFX0RPVUJMRRABEg4KClRZUEVfRkxPQVQQAhIOCgpUWVBF",
+ "X0lOVDY0EAMSDwoLVFlQRV9VSU5UNjQQBBIOCgpUWVBFX0lOVDMyEAUSEAoM",
+ "VFlQRV9GSVhFRDY0EAYSEAoMVFlQRV9GSVhFRDMyEAcSDQoJVFlQRV9CT09M",
+ "EAgSDwoLVFlQRV9TVFJJTkcQCRIOCgpUWVBFX0dST1VQEAoSEAoMVFlQRV9N",
+ "RVNTQUdFEAsSDgoKVFlQRV9CWVRFUxAMEg8KC1RZUEVfVUlOVDMyEA0SDQoJ",
+ "VFlQRV9FTlVNEA4SEQoNVFlQRV9TRklYRUQzMhAPEhEKDVRZUEVfU0ZJWEVE",
+ "NjQQEBIPCgtUWVBFX1NJTlQzMhAREg8KC1RZUEVfU0lOVDY0EBIidAoLQ2Fy",
+ "ZGluYWxpdHkSFwoTQ0FSRElOQUxJVFlfVU5LTk9XThAAEhgKFENBUkRJTkFM",
+ "SVRZX09QVElPTkFMEAESGAoUQ0FSRElOQUxJVFlfUkVRVUlSRUQQAhIYChRD",
+ "QVJESU5BTElUWV9SRVBFQVRFRBADIs4BCgRFbnVtEgwKBG5hbWUYASABKAkS",
+ "LQoJZW51bXZhbHVlGAIgAygLMhouZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1",
+ "ZRIoCgdvcHRpb25zGAMgAygLMhcuZ29vZ2xlLnByb3RvYnVmLk9wdGlvbhI2",
+ "Cg5zb3VyY2VfY29udGV4dBgEIAEoCzIeLmdvb2dsZS5wcm90b2J1Zi5Tb3Vy",
+ "Y2VDb250ZXh0EicKBnN5bnRheBgFIAEoDjIXLmdvb2dsZS5wcm90b2J1Zi5T",
+ "eW50YXgiUwoJRW51bVZhbHVlEgwKBG5hbWUYASABKAkSDgoGbnVtYmVyGAIg",
+ "ASgFEigKB29wdGlvbnMYAyADKAsyFy5nb29nbGUucHJvdG9idWYuT3B0aW9u",
+ "IjsKBk9wdGlvbhIMCgRuYW1lGAEgASgJEiMKBXZhbHVlGAIgASgLMhQuZ29v",
+ "Z2xlLnByb3RvYnVmLkFueSouCgZTeW50YXgSEQoNU1lOVEFYX1BST1RPMhAA",
+ "EhEKDVNZTlRBWF9QUk9UTzMQAUJMChNjb20uZ29vZ2xlLnByb3RvYnVmQglU",
+ "eXBlUHJvdG9QAaABAaICA0dQQqoCHkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25v",
+ "d25UeXBlc2IGcHJvdG8z"));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { global::Google.Protobuf.WellKnownTypes.AnyReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.SourceContextReflection.Descriptor, },
- new pbr::GeneratedCodeInfo(new[] {typeof(global::Google.Protobuf.WellKnownTypes.Syntax), }, new pbr::GeneratedCodeInfo[] {
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Type), global::Google.Protobuf.WellKnownTypes.Type.Parser, new[]{ "Name", "Fields", "Oneofs", "Options", "SourceContext", "Syntax" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Field), global::Google.Protobuf.WellKnownTypes.Field.Parser, new[]{ "Kind", "Cardinality", "Number", "Name", "TypeUrl", "OneofIndex", "Packed", "Options", "JsonName" }, null, new[]{ typeof(global::Google.Protobuf.WellKnownTypes.Field.Types.Kind), typeof(global::Google.Protobuf.WellKnownTypes.Field.Types.Cardinality) }, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Enum), global::Google.Protobuf.WellKnownTypes.Enum.Parser, new[]{ "Name", "Enumvalue", "Options", "SourceContext", "Syntax" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.EnumValue), global::Google.Protobuf.WellKnownTypes.EnumValue.Parser, new[]{ "Name", "Number", "Options" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Option), global::Google.Protobuf.WellKnownTypes.Option.Parser, new[]{ "Name", "Value" }, null, null, null)
+ new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Google.Protobuf.WellKnownTypes.Syntax), }, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Type), global::Google.Protobuf.WellKnownTypes.Type.Parser, new[]{ "Name", "Fields", "Oneofs", "Options", "SourceContext", "Syntax" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Field), global::Google.Protobuf.WellKnownTypes.Field.Parser, new[]{ "Kind", "Cardinality", "Number", "Name", "TypeUrl", "OneofIndex", "Packed", "Options", "JsonName", "DefaultValue" }, null, new[]{ typeof(global::Google.Protobuf.WellKnownTypes.Field.Types.Kind), typeof(global::Google.Protobuf.WellKnownTypes.Field.Types.Cardinality) }, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Enum), global::Google.Protobuf.WellKnownTypes.Enum.Parser, new[]{ "Name", "Enumvalue", "Options", "SourceContext", "Syntax" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.EnumValue), global::Google.Protobuf.WellKnownTypes.EnumValue.Parser, new[]{ "Name", "Number", "Options" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Option), global::Google.Protobuf.WellKnownTypes.Option.Parser, new[]{ "Name", "Value" }, null, null, null)
}));
}
#endregion
@@ -72,44 +72,48 @@ namespace Google.Protobuf.WellKnownTypes {
}
#region Enums
/// <summary>
- /// Syntax specifies the syntax in which a service element was defined.
+ /// The syntax in which a protocol buffer element is defined.
/// </summary>
public enum Syntax {
/// <summary>
- /// Syntax "proto2"
+ /// Syntax `proto2`.
/// </summary>
- SYNTAX_PROTO2 = 0,
+ [pbr::OriginalName("SYNTAX_PROTO2")] Proto2 = 0,
/// <summary>
- /// Syntax "proto3"
+ /// Syntax `proto3`.
/// </summary>
- SYNTAX_PROTO3 = 1,
+ [pbr::OriginalName("SYNTAX_PROTO3")] Proto3 = 1,
}
#endregion
#region Messages
/// <summary>
- /// A light-weight descriptor for a proto message type.
+ /// A protocol buffer message type.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class Type : pb::IMessage<Type> {
private static readonly pb::MessageParser<Type> _parser = new pb::MessageParser<Type>(() => new Type());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<Type> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.WellKnownTypes.TypeReflection.Descriptor.MessageTypes[0]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Type() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Type(Type other) : this() {
name_ = other.name_;
fields_ = other.fields_.Clone();
@@ -119,6 +123,7 @@ namespace Google.Protobuf.WellKnownTypes {
syntax_ = other.syntax_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Type Clone() {
return new Type(this);
}
@@ -129,10 +134,11 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// The fully qualified message name.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string Name {
get { return name_; }
set {
- name_ = pb::Preconditions.CheckNotNull(value, "value");
+ name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -144,6 +150,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// The list of fields.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Field> Fields {
get { return fields_; }
}
@@ -154,8 +161,9 @@ namespace Google.Protobuf.WellKnownTypes {
= pb::FieldCodec.ForString(26);
private readonly pbc::RepeatedField<string> oneofs_ = new pbc::RepeatedField<string>();
/// <summary>
- /// The list of oneof definitions.
+ /// The list of types appearing in `oneof` definitions in this type.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<string> Oneofs {
get { return oneofs_; }
}
@@ -166,8 +174,9 @@ namespace Google.Protobuf.WellKnownTypes {
= pb::FieldCodec.ForMessage(34, global::Google.Protobuf.WellKnownTypes.Option.Parser);
private readonly pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Option> options_ = new pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Option>();
/// <summary>
- /// The proto options.
+ /// The protocol buffer options.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Option> Options {
get { return options_; }
}
@@ -178,6 +187,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// The source context.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.WellKnownTypes.SourceContext SourceContext {
get { return sourceContext_; }
set {
@@ -187,10 +197,11 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>Field number for the "syntax" field.</summary>
public const int SyntaxFieldNumber = 6;
- private global::Google.Protobuf.WellKnownTypes.Syntax syntax_ = global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2;
+ private global::Google.Protobuf.WellKnownTypes.Syntax syntax_ = 0;
/// <summary>
/// The source syntax.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.WellKnownTypes.Syntax Syntax {
get { return syntax_; }
set {
@@ -198,10 +209,12 @@ namespace Google.Protobuf.WellKnownTypes {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as Type);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(Type other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -218,6 +231,7 @@ namespace Google.Protobuf.WellKnownTypes {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Name.Length != 0) hash ^= Name.GetHashCode();
@@ -225,14 +239,16 @@ namespace Google.Protobuf.WellKnownTypes {
hash ^= oneofs_.GetHashCode();
hash ^= options_.GetHashCode();
if (sourceContext_ != null) hash ^= SourceContext.GetHashCode();
- if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) hash ^= Syntax.GetHashCode();
+ if (Syntax != 0) hash ^= Syntax.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Name.Length != 0) {
output.WriteRawTag(10);
@@ -245,12 +261,13 @@ namespace Google.Protobuf.WellKnownTypes {
output.WriteRawTag(42);
output.WriteMessage(SourceContext);
}
- if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) {
+ if (Syntax != 0) {
output.WriteRawTag(48);
output.WriteEnum((int) Syntax);
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Name.Length != 0) {
@@ -262,12 +279,13 @@ namespace Google.Protobuf.WellKnownTypes {
if (sourceContext_ != null) {
size += 1 + pb::CodedOutputStream.ComputeMessageSize(SourceContext);
}
- if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) {
+ if (Syntax != 0) {
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Syntax);
}
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(Type other) {
if (other == null) {
return;
@@ -284,11 +302,12 @@ namespace Google.Protobuf.WellKnownTypes {
}
SourceContext.MergeFrom(other.SourceContext);
}
- if (other.Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) {
+ if (other.Syntax != 0) {
Syntax = other.Syntax;
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -330,27 +349,31 @@ namespace Google.Protobuf.WellKnownTypes {
}
/// <summary>
- /// Field represents a single field of a message type.
+ /// A single field of a message type.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class Field : pb::IMessage<Field> {
private static readonly pb::MessageParser<Field> _parser = new pb::MessageParser<Field>(() => new Field());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<Field> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.WellKnownTypes.TypeReflection.Descriptor.MessageTypes[1]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Field() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Field(Field other) : this() {
kind_ = other.kind_;
cardinality_ = other.cardinality_;
@@ -361,18 +384,21 @@ namespace Google.Protobuf.WellKnownTypes {
packed_ = other.packed_;
options_ = other.options_.Clone();
jsonName_ = other.jsonName_;
+ defaultValue_ = other.defaultValue_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Field Clone() {
return new Field(this);
}
/// <summary>Field number for the "kind" field.</summary>
public const int KindFieldNumber = 1;
- private global::Google.Protobuf.WellKnownTypes.Field.Types.Kind kind_ = global::Google.Protobuf.WellKnownTypes.Field.Types.Kind.TYPE_UNKNOWN;
+ private global::Google.Protobuf.WellKnownTypes.Field.Types.Kind kind_ = 0;
/// <summary>
- /// The field kind.
+ /// The field type.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.WellKnownTypes.Field.Types.Kind Kind {
get { return kind_; }
set {
@@ -382,10 +408,11 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>Field number for the "cardinality" field.</summary>
public const int CardinalityFieldNumber = 2;
- private global::Google.Protobuf.WellKnownTypes.Field.Types.Cardinality cardinality_ = global::Google.Protobuf.WellKnownTypes.Field.Types.Cardinality.CARDINALITY_UNKNOWN;
+ private global::Google.Protobuf.WellKnownTypes.Field.Types.Cardinality cardinality_ = 0;
/// <summary>
- /// The field cardinality, i.e. optional/required/repeated.
+ /// The field cardinality.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.WellKnownTypes.Field.Types.Cardinality Cardinality {
get { return cardinality_; }
set {
@@ -397,8 +424,9 @@ namespace Google.Protobuf.WellKnownTypes {
public const int NumberFieldNumber = 3;
private int number_;
/// <summary>
- /// The proto field number.
+ /// The field number.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int Number {
get { return number_; }
set {
@@ -412,10 +440,11 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// The field name.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string Name {
get { return name_; }
set {
- name_ = pb::Preconditions.CheckNotNull(value, "value");
+ name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -423,13 +452,14 @@ namespace Google.Protobuf.WellKnownTypes {
public const int TypeUrlFieldNumber = 6;
private string typeUrl_ = "";
/// <summary>
- /// The type URL (without the scheme) when the type is MESSAGE or ENUM,
- /// such as `type.googleapis.com/google.protobuf.Empty`.
+ /// The field type URL, without the scheme, for message or enumeration
+ /// types. Example: `"type.googleapis.com/google.protobuf.Timestamp"`.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string TypeUrl {
get { return typeUrl_; }
set {
- typeUrl_ = pb::Preconditions.CheckNotNull(value, "value");
+ typeUrl_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -437,8 +467,10 @@ namespace Google.Protobuf.WellKnownTypes {
public const int OneofIndexFieldNumber = 7;
private int oneofIndex_;
/// <summary>
- /// Index in Type.oneofs. Starts at 1. Zero means no oneof mapping.
+ /// The index of the field type in `Type.oneofs`, for message or enumeration
+ /// types. The first type has index 1; zero means the type is not in the list.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int OneofIndex {
get { return oneofIndex_; }
set {
@@ -452,6 +484,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// Whether to use alternative packed wire representation.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Packed {
get { return packed_; }
set {
@@ -465,8 +498,9 @@ namespace Google.Protobuf.WellKnownTypes {
= pb::FieldCodec.ForMessage(74, global::Google.Protobuf.WellKnownTypes.Option.Parser);
private readonly pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Option> options_ = new pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Option>();
/// <summary>
- /// The proto options.
+ /// The protocol buffer options.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Option> Options {
get { return options_; }
}
@@ -475,19 +509,36 @@ namespace Google.Protobuf.WellKnownTypes {
public const int JsonNameFieldNumber = 10;
private string jsonName_ = "";
/// <summary>
- /// The JSON name for this field.
+ /// The field JSON name.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string JsonName {
get { return jsonName_; }
set {
- jsonName_ = pb::Preconditions.CheckNotNull(value, "value");
+ jsonName_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
+ /// <summary>Field number for the "default_value" field.</summary>
+ public const int DefaultValueFieldNumber = 11;
+ private string defaultValue_ = "";
+ /// <summary>
+ /// The string value of the default value of this field. Proto2 syntax only.
+ /// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public string DefaultValue {
+ get { return defaultValue_; }
+ set {
+ defaultValue_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as Field);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(Field other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -504,13 +555,15 @@ namespace Google.Protobuf.WellKnownTypes {
if (Packed != other.Packed) return false;
if(!options_.Equals(other.options_)) return false;
if (JsonName != other.JsonName) return false;
+ if (DefaultValue != other.DefaultValue) return false;
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
- if (Kind != global::Google.Protobuf.WellKnownTypes.Field.Types.Kind.TYPE_UNKNOWN) hash ^= Kind.GetHashCode();
- if (Cardinality != global::Google.Protobuf.WellKnownTypes.Field.Types.Cardinality.CARDINALITY_UNKNOWN) hash ^= Cardinality.GetHashCode();
+ if (Kind != 0) hash ^= Kind.GetHashCode();
+ if (Cardinality != 0) hash ^= Cardinality.GetHashCode();
if (Number != 0) hash ^= Number.GetHashCode();
if (Name.Length != 0) hash ^= Name.GetHashCode();
if (TypeUrl.Length != 0) hash ^= TypeUrl.GetHashCode();
@@ -518,19 +571,22 @@ namespace Google.Protobuf.WellKnownTypes {
if (Packed != false) hash ^= Packed.GetHashCode();
hash ^= options_.GetHashCode();
if (JsonName.Length != 0) hash ^= JsonName.GetHashCode();
+ if (DefaultValue.Length != 0) hash ^= DefaultValue.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
- if (Kind != global::Google.Protobuf.WellKnownTypes.Field.Types.Kind.TYPE_UNKNOWN) {
+ if (Kind != 0) {
output.WriteRawTag(8);
output.WriteEnum((int) Kind);
}
- if (Cardinality != global::Google.Protobuf.WellKnownTypes.Field.Types.Cardinality.CARDINALITY_UNKNOWN) {
+ if (Cardinality != 0) {
output.WriteRawTag(16);
output.WriteEnum((int) Cardinality);
}
@@ -559,14 +615,19 @@ namespace Google.Protobuf.WellKnownTypes {
output.WriteRawTag(82);
output.WriteString(JsonName);
}
+ if (DefaultValue.Length != 0) {
+ output.WriteRawTag(90);
+ output.WriteString(DefaultValue);
+ }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
- if (Kind != global::Google.Protobuf.WellKnownTypes.Field.Types.Kind.TYPE_UNKNOWN) {
+ if (Kind != 0) {
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Kind);
}
- if (Cardinality != global::Google.Protobuf.WellKnownTypes.Field.Types.Cardinality.CARDINALITY_UNKNOWN) {
+ if (Cardinality != 0) {
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Cardinality);
}
if (Number != 0) {
@@ -588,17 +649,21 @@ namespace Google.Protobuf.WellKnownTypes {
if (JsonName.Length != 0) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(JsonName);
}
+ if (DefaultValue.Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(DefaultValue);
+ }
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(Field other) {
if (other == null) {
return;
}
- if (other.Kind != global::Google.Protobuf.WellKnownTypes.Field.Types.Kind.TYPE_UNKNOWN) {
+ if (other.Kind != 0) {
Kind = other.Kind;
}
- if (other.Cardinality != global::Google.Protobuf.WellKnownTypes.Field.Types.Cardinality.CARDINALITY_UNKNOWN) {
+ if (other.Cardinality != 0) {
Cardinality = other.Cardinality;
}
if (other.Number != 0) {
@@ -620,8 +685,12 @@ namespace Google.Protobuf.WellKnownTypes {
if (other.JsonName.Length != 0) {
JsonName = other.JsonName;
}
+ if (other.DefaultValue.Length != 0) {
+ DefaultValue = other.DefaultValue;
+ }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -665,117 +734,120 @@ namespace Google.Protobuf.WellKnownTypes {
JsonName = input.ReadString();
break;
}
+ case 90: {
+ DefaultValue = input.ReadString();
+ break;
+ }
}
}
}
#region Nested types
/// <summary>Container for nested types declared in the Field message type.</summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static partial class Types {
/// <summary>
- /// Kind represents a basic field type.
+ /// Basic field types.
/// </summary>
public enum Kind {
/// <summary>
/// Field type unknown.
/// </summary>
- TYPE_UNKNOWN = 0,
+ [pbr::OriginalName("TYPE_UNKNOWN")] TypeUnknown = 0,
/// <summary>
/// Field type double.
/// </summary>
- TYPE_DOUBLE = 1,
+ [pbr::OriginalName("TYPE_DOUBLE")] TypeDouble = 1,
/// <summary>
/// Field type float.
/// </summary>
- TYPE_FLOAT = 2,
+ [pbr::OriginalName("TYPE_FLOAT")] TypeFloat = 2,
/// <summary>
/// Field type int64.
/// </summary>
- TYPE_INT64 = 3,
+ [pbr::OriginalName("TYPE_INT64")] TypeInt64 = 3,
/// <summary>
/// Field type uint64.
/// </summary>
- TYPE_UINT64 = 4,
+ [pbr::OriginalName("TYPE_UINT64")] TypeUint64 = 4,
/// <summary>
/// Field type int32.
/// </summary>
- TYPE_INT32 = 5,
+ [pbr::OriginalName("TYPE_INT32")] TypeInt32 = 5,
/// <summary>
/// Field type fixed64.
/// </summary>
- TYPE_FIXED64 = 6,
+ [pbr::OriginalName("TYPE_FIXED64")] TypeFixed64 = 6,
/// <summary>
/// Field type fixed32.
/// </summary>
- TYPE_FIXED32 = 7,
+ [pbr::OriginalName("TYPE_FIXED32")] TypeFixed32 = 7,
/// <summary>
/// Field type bool.
/// </summary>
- TYPE_BOOL = 8,
+ [pbr::OriginalName("TYPE_BOOL")] TypeBool = 8,
/// <summary>
/// Field type string.
/// </summary>
- TYPE_STRING = 9,
+ [pbr::OriginalName("TYPE_STRING")] TypeString = 9,
/// <summary>
- /// Field type group (deprecated proto2 type)
+ /// Field type group. Proto2 syntax only, and deprecated.
/// </summary>
- TYPE_GROUP = 10,
+ [pbr::OriginalName("TYPE_GROUP")] TypeGroup = 10,
/// <summary>
/// Field type message.
/// </summary>
- TYPE_MESSAGE = 11,
+ [pbr::OriginalName("TYPE_MESSAGE")] TypeMessage = 11,
/// <summary>
/// Field type bytes.
/// </summary>
- TYPE_BYTES = 12,
+ [pbr::OriginalName("TYPE_BYTES")] TypeBytes = 12,
/// <summary>
/// Field type uint32.
/// </summary>
- TYPE_UINT32 = 13,
+ [pbr::OriginalName("TYPE_UINT32")] TypeUint32 = 13,
/// <summary>
/// Field type enum.
/// </summary>
- TYPE_ENUM = 14,
+ [pbr::OriginalName("TYPE_ENUM")] TypeEnum = 14,
/// <summary>
/// Field type sfixed32.
/// </summary>
- TYPE_SFIXED32 = 15,
+ [pbr::OriginalName("TYPE_SFIXED32")] TypeSfixed32 = 15,
/// <summary>
/// Field type sfixed64.
/// </summary>
- TYPE_SFIXED64 = 16,
+ [pbr::OriginalName("TYPE_SFIXED64")] TypeSfixed64 = 16,
/// <summary>
/// Field type sint32.
/// </summary>
- TYPE_SINT32 = 17,
+ [pbr::OriginalName("TYPE_SINT32")] TypeSint32 = 17,
/// <summary>
/// Field type sint64.
/// </summary>
- TYPE_SINT64 = 18,
+ [pbr::OriginalName("TYPE_SINT64")] TypeSint64 = 18,
}
/// <summary>
- /// Cardinality represents whether a field is optional, required, or
- /// repeated.
+ /// Whether a field is optional, required, or repeated.
/// </summary>
public enum Cardinality {
/// <summary>
- /// The field cardinality is unknown. Typically an error condition.
+ /// For fields with unknown cardinality.
/// </summary>
- CARDINALITY_UNKNOWN = 0,
+ [pbr::OriginalName("CARDINALITY_UNKNOWN")] Unknown = 0,
/// <summary>
/// For optional fields.
/// </summary>
- CARDINALITY_OPTIONAL = 1,
+ [pbr::OriginalName("CARDINALITY_OPTIONAL")] Optional = 1,
/// <summary>
- /// For required fields. Not used for proto3.
+ /// For required fields. Proto2 syntax only.
/// </summary>
- CARDINALITY_REQUIRED = 2,
+ [pbr::OriginalName("CARDINALITY_REQUIRED")] Required = 2,
/// <summary>
/// For repeated fields.
/// </summary>
- CARDINALITY_REPEATED = 3,
+ [pbr::OriginalName("CARDINALITY_REPEATED")] Repeated = 3,
}
}
@@ -786,25 +858,29 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// Enum type definition.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class Enum : pb::IMessage<Enum> {
private static readonly pb::MessageParser<Enum> _parser = new pb::MessageParser<Enum>(() => new Enum());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<Enum> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.WellKnownTypes.TypeReflection.Descriptor.MessageTypes[2]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Enum() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Enum(Enum other) : this() {
name_ = other.name_;
enumvalue_ = other.enumvalue_.Clone();
@@ -813,6 +889,7 @@ namespace Google.Protobuf.WellKnownTypes {
syntax_ = other.syntax_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Enum Clone() {
return new Enum(this);
}
@@ -823,10 +900,11 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// Enum type name.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string Name {
get { return name_; }
set {
- name_ = pb::Preconditions.CheckNotNull(value, "value");
+ name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -838,6 +916,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// Enum value definitions.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.EnumValue> Enumvalue {
get { return enumvalue_; }
}
@@ -848,8 +927,9 @@ namespace Google.Protobuf.WellKnownTypes {
= pb::FieldCodec.ForMessage(26, global::Google.Protobuf.WellKnownTypes.Option.Parser);
private readonly pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Option> options_ = new pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Option>();
/// <summary>
- /// Proto options for the enum type.
+ /// Protocol buffer options.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Option> Options {
get { return options_; }
}
@@ -860,6 +940,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// The source context.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.WellKnownTypes.SourceContext SourceContext {
get { return sourceContext_; }
set {
@@ -869,10 +950,11 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>Field number for the "syntax" field.</summary>
public const int SyntaxFieldNumber = 5;
- private global::Google.Protobuf.WellKnownTypes.Syntax syntax_ = global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2;
+ private global::Google.Protobuf.WellKnownTypes.Syntax syntax_ = 0;
/// <summary>
/// The source syntax.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.WellKnownTypes.Syntax Syntax {
get { return syntax_; }
set {
@@ -880,10 +962,12 @@ namespace Google.Protobuf.WellKnownTypes {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as Enum);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(Enum other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -899,20 +983,23 @@ namespace Google.Protobuf.WellKnownTypes {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Name.Length != 0) hash ^= Name.GetHashCode();
hash ^= enumvalue_.GetHashCode();
hash ^= options_.GetHashCode();
if (sourceContext_ != null) hash ^= SourceContext.GetHashCode();
- if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) hash ^= Syntax.GetHashCode();
+ if (Syntax != 0) hash ^= Syntax.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Name.Length != 0) {
output.WriteRawTag(10);
@@ -924,12 +1011,13 @@ namespace Google.Protobuf.WellKnownTypes {
output.WriteRawTag(34);
output.WriteMessage(SourceContext);
}
- if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) {
+ if (Syntax != 0) {
output.WriteRawTag(40);
output.WriteEnum((int) Syntax);
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Name.Length != 0) {
@@ -940,12 +1028,13 @@ namespace Google.Protobuf.WellKnownTypes {
if (sourceContext_ != null) {
size += 1 + pb::CodedOutputStream.ComputeMessageSize(SourceContext);
}
- if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) {
+ if (Syntax != 0) {
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Syntax);
}
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(Enum other) {
if (other == null) {
return;
@@ -961,11 +1050,12 @@ namespace Google.Protobuf.WellKnownTypes {
}
SourceContext.MergeFrom(other.SourceContext);
}
- if (other.Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) {
+ if (other.Syntax != 0) {
Syntax = other.Syntax;
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -1005,31 +1095,36 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// Enum value definition.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class EnumValue : pb::IMessage<EnumValue> {
private static readonly pb::MessageParser<EnumValue> _parser = new pb::MessageParser<EnumValue>(() => new EnumValue());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<EnumValue> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.WellKnownTypes.TypeReflection.Descriptor.MessageTypes[3]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public EnumValue() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public EnumValue(EnumValue other) : this() {
name_ = other.name_;
number_ = other.number_;
options_ = other.options_.Clone();
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public EnumValue Clone() {
return new EnumValue(this);
}
@@ -1040,10 +1135,11 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// Enum value name.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string Name {
get { return name_; }
set {
- name_ = pb::Preconditions.CheckNotNull(value, "value");
+ name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -1053,6 +1149,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// Enum value number.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int Number {
get { return number_; }
set {
@@ -1066,16 +1163,19 @@ namespace Google.Protobuf.WellKnownTypes {
= pb::FieldCodec.ForMessage(26, global::Google.Protobuf.WellKnownTypes.Option.Parser);
private readonly pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Option> options_ = new pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Option>();
/// <summary>
- /// Proto options for the enum value.
+ /// Protocol buffer options.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Option> Options {
get { return options_; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as EnumValue);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(EnumValue other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -1089,6 +1189,7 @@ namespace Google.Protobuf.WellKnownTypes {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Name.Length != 0) hash ^= Name.GetHashCode();
@@ -1097,10 +1198,12 @@ namespace Google.Protobuf.WellKnownTypes {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Name.Length != 0) {
output.WriteRawTag(10);
@@ -1113,6 +1216,7 @@ namespace Google.Protobuf.WellKnownTypes {
options_.WriteTo(output, _repeated_options_codec);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Name.Length != 0) {
@@ -1125,6 +1229,7 @@ namespace Google.Protobuf.WellKnownTypes {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(EnumValue other) {
if (other == null) {
return;
@@ -1138,6 +1243,7 @@ namespace Google.Protobuf.WellKnownTypes {
options_.Add(other.options_);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -1164,32 +1270,38 @@ namespace Google.Protobuf.WellKnownTypes {
}
/// <summary>
- /// Proto option attached to messages/fields/enums etc.
+ /// A protocol buffer option, which can be attached to a message, field,
+ /// enumeration, etc.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class Option : pb::IMessage<Option> {
private static readonly pb::MessageParser<Option> _parser = new pb::MessageParser<Option>(() => new Option());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<Option> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.WellKnownTypes.TypeReflection.Descriptor.MessageTypes[4]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Option() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Option(Option other) : this() {
name_ = other.name_;
Value = other.value_ != null ? other.Value.Clone() : null;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Option Clone() {
return new Option(this);
}
@@ -1198,12 +1310,13 @@ namespace Google.Protobuf.WellKnownTypes {
public const int NameFieldNumber = 1;
private string name_ = "";
/// <summary>
- /// Proto option name.
+ /// The option's name. For example, `"java_package"`.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string Name {
get { return name_; }
set {
- name_ = pb::Preconditions.CheckNotNull(value, "value");
+ name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -1211,8 +1324,9 @@ namespace Google.Protobuf.WellKnownTypes {
public const int ValueFieldNumber = 2;
private global::Google.Protobuf.WellKnownTypes.Any value_;
/// <summary>
- /// Proto option value.
+ /// The option's value. For example, `"com.google.protobuf"`.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public global::Google.Protobuf.WellKnownTypes.Any Value {
get { return value_; }
set {
@@ -1220,10 +1334,12 @@ namespace Google.Protobuf.WellKnownTypes {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as Option);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(Option other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -1236,6 +1352,7 @@ namespace Google.Protobuf.WellKnownTypes {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Name.Length != 0) hash ^= Name.GetHashCode();
@@ -1243,10 +1360,12 @@ namespace Google.Protobuf.WellKnownTypes {
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Name.Length != 0) {
output.WriteRawTag(10);
@@ -1258,6 +1377,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Name.Length != 0) {
@@ -1269,6 +1389,7 @@ namespace Google.Protobuf.WellKnownTypes {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(Option other) {
if (other == null) {
return;
@@ -1284,6 +1405,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/ValuePartial.cs b/csharp/src/Google.Protobuf/WellKnownTypes/ValuePartial.cs
index b4b6c05e..d34b560d 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/ValuePartial.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/ValuePartial.cs
@@ -41,7 +41,7 @@ namespace Google.Protobuf.WellKnownTypes
/// <returns>A newly-created Value message with the given value.</returns>
public static Value ForString(string value)
{
- Preconditions.CheckNotNull(value, "value");
+ ProtoPreconditions.CheckNotNull(value, "value");
return new Value { StringValue = value };
}
@@ -81,7 +81,7 @@ namespace Google.Protobuf.WellKnownTypes
/// <returns>A newly-created Value message an initial list value.</returns>
public static Value ForList(params Value[] values)
{
- Preconditions.CheckNotNull(values, "values");
+ ProtoPreconditions.CheckNotNull(values, "values");
return new Value { ListValue = new ListValue { Values = { values } } };
}
@@ -92,7 +92,7 @@ namespace Google.Protobuf.WellKnownTypes
/// <returns>A newly-created Value message an initial struct value.</returns>
public static Value ForStruct(Struct value)
{
- Preconditions.CheckNotNull(value, "value");
+ ProtoPreconditions.CheckNotNull(value, "value");
return new Value { StructValue = value };
}
}
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs
index a70b2fb0..80f9f98d 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs
@@ -10,7 +10,6 @@ using scg = global::System.Collections.Generic;
namespace Google.Protobuf.WellKnownTypes {
/// <summary>Holder for reflection information generated from google/protobuf/wrappers.proto</summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public static partial class WrappersReflection {
#region Descriptor
@@ -29,21 +28,22 @@ namespace Google.Protobuf.WellKnownTypes {
"KAMiHAoLVUludDY0VmFsdWUSDQoFdmFsdWUYASABKAQiGwoKSW50MzJWYWx1",
"ZRINCgV2YWx1ZRgBIAEoBSIcCgtVSW50MzJWYWx1ZRINCgV2YWx1ZRgBIAEo",
"DSIaCglCb29sVmFsdWUSDQoFdmFsdWUYASABKAgiHAoLU3RyaW5nVmFsdWUS",
- "DQoFdmFsdWUYASABKAkiGwoKQnl0ZXNWYWx1ZRINCgV2YWx1ZRgBIAEoDEJQ",
- "ChNjb20uZ29vZ2xlLnByb3RvYnVmQg1XcmFwcGVyc1Byb3RvUAGgAQGiAgNH",
- "UEKqAh5Hb29nbGUuUHJvdG9idWYuV2VsbEtub3duVHlwZXNiBnByb3RvMw=="));
+ "DQoFdmFsdWUYASABKAkiGwoKQnl0ZXNWYWx1ZRINCgV2YWx1ZRgBIAEoDEJ/",
+ "ChNjb20uZ29vZ2xlLnByb3RvYnVmQg1XcmFwcGVyc1Byb3RvUAFaKmdpdGh1",
+ "Yi5jb20vZ29sYW5nL3Byb3RvYnVmL3B0eXBlcy93cmFwcGVyc6ABAfgBAaIC",
+ "A0dQQqoCHkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBlc2IGcHJvdG8z"));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
- new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.DoubleValue), global::Google.Protobuf.WellKnownTypes.DoubleValue.Parser, new[]{ "Value" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.FloatValue), global::Google.Protobuf.WellKnownTypes.FloatValue.Parser, new[]{ "Value" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Int64Value), global::Google.Protobuf.WellKnownTypes.Int64Value.Parser, new[]{ "Value" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.UInt64Value), global::Google.Protobuf.WellKnownTypes.UInt64Value.Parser, new[]{ "Value" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Int32Value), global::Google.Protobuf.WellKnownTypes.Int32Value.Parser, new[]{ "Value" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.UInt32Value), global::Google.Protobuf.WellKnownTypes.UInt32Value.Parser, new[]{ "Value" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.BoolValue), global::Google.Protobuf.WellKnownTypes.BoolValue.Parser, new[]{ "Value" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.StringValue), global::Google.Protobuf.WellKnownTypes.StringValue.Parser, new[]{ "Value" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.BytesValue), global::Google.Protobuf.WellKnownTypes.BytesValue.Parser, new[]{ "Value" }, null, null, null)
+ new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.DoubleValue), global::Google.Protobuf.WellKnownTypes.DoubleValue.Parser, new[]{ "Value" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.FloatValue), global::Google.Protobuf.WellKnownTypes.FloatValue.Parser, new[]{ "Value" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Int64Value), global::Google.Protobuf.WellKnownTypes.Int64Value.Parser, new[]{ "Value" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.UInt64Value), global::Google.Protobuf.WellKnownTypes.UInt64Value.Parser, new[]{ "Value" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Int32Value), global::Google.Protobuf.WellKnownTypes.Int32Value.Parser, new[]{ "Value" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.UInt32Value), global::Google.Protobuf.WellKnownTypes.UInt32Value.Parser, new[]{ "Value" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.BoolValue), global::Google.Protobuf.WellKnownTypes.BoolValue.Parser, new[]{ "Value" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.StringValue), global::Google.Protobuf.WellKnownTypes.StringValue.Parser, new[]{ "Value" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.BytesValue), global::Google.Protobuf.WellKnownTypes.BytesValue.Parser, new[]{ "Value" }, null, null, null)
}));
}
#endregion
@@ -55,29 +55,34 @@ namespace Google.Protobuf.WellKnownTypes {
///
/// The JSON representation for `DoubleValue` is JSON number.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class DoubleValue : pb::IMessage<DoubleValue> {
private static readonly pb::MessageParser<DoubleValue> _parser = new pb::MessageParser<DoubleValue>(() => new DoubleValue());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<DoubleValue> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.WellKnownTypes.WrappersReflection.Descriptor.MessageTypes[0]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public DoubleValue() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public DoubleValue(DoubleValue other) : this() {
value_ = other.value_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public DoubleValue Clone() {
return new DoubleValue(this);
}
@@ -88,6 +93,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// The double value.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public double Value {
get { return value_; }
set {
@@ -95,10 +101,12 @@ namespace Google.Protobuf.WellKnownTypes {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as DoubleValue);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(DoubleValue other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -110,16 +118,19 @@ namespace Google.Protobuf.WellKnownTypes {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Value != 0D) hash ^= Value.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Value != 0D) {
output.WriteRawTag(9);
@@ -127,6 +138,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Value != 0D) {
@@ -135,6 +147,7 @@ namespace Google.Protobuf.WellKnownTypes {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(DoubleValue other) {
if (other == null) {
return;
@@ -144,6 +157,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -166,29 +180,34 @@ namespace Google.Protobuf.WellKnownTypes {
///
/// The JSON representation for `FloatValue` is JSON number.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class FloatValue : pb::IMessage<FloatValue> {
private static readonly pb::MessageParser<FloatValue> _parser = new pb::MessageParser<FloatValue>(() => new FloatValue());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<FloatValue> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.WellKnownTypes.WrappersReflection.Descriptor.MessageTypes[1]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public FloatValue() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public FloatValue(FloatValue other) : this() {
value_ = other.value_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public FloatValue Clone() {
return new FloatValue(this);
}
@@ -199,6 +218,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// The float value.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public float Value {
get { return value_; }
set {
@@ -206,10 +226,12 @@ namespace Google.Protobuf.WellKnownTypes {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as FloatValue);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(FloatValue other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -221,16 +243,19 @@ namespace Google.Protobuf.WellKnownTypes {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Value != 0F) hash ^= Value.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Value != 0F) {
output.WriteRawTag(13);
@@ -238,6 +263,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Value != 0F) {
@@ -246,6 +272,7 @@ namespace Google.Protobuf.WellKnownTypes {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(FloatValue other) {
if (other == null) {
return;
@@ -255,6 +282,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -277,29 +305,34 @@ namespace Google.Protobuf.WellKnownTypes {
///
/// The JSON representation for `Int64Value` is JSON string.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class Int64Value : pb::IMessage<Int64Value> {
private static readonly pb::MessageParser<Int64Value> _parser = new pb::MessageParser<Int64Value>(() => new Int64Value());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<Int64Value> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.WellKnownTypes.WrappersReflection.Descriptor.MessageTypes[2]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Int64Value() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Int64Value(Int64Value other) : this() {
value_ = other.value_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Int64Value Clone() {
return new Int64Value(this);
}
@@ -310,6 +343,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// The int64 value.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public long Value {
get { return value_; }
set {
@@ -317,10 +351,12 @@ namespace Google.Protobuf.WellKnownTypes {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as Int64Value);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(Int64Value other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -332,16 +368,19 @@ namespace Google.Protobuf.WellKnownTypes {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Value != 0L) hash ^= Value.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Value != 0L) {
output.WriteRawTag(8);
@@ -349,6 +388,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Value != 0L) {
@@ -357,6 +397,7 @@ namespace Google.Protobuf.WellKnownTypes {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(Int64Value other) {
if (other == null) {
return;
@@ -366,6 +407,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -388,29 +430,34 @@ namespace Google.Protobuf.WellKnownTypes {
///
/// The JSON representation for `UInt64Value` is JSON string.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class UInt64Value : pb::IMessage<UInt64Value> {
private static readonly pb::MessageParser<UInt64Value> _parser = new pb::MessageParser<UInt64Value>(() => new UInt64Value());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<UInt64Value> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.WellKnownTypes.WrappersReflection.Descriptor.MessageTypes[3]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public UInt64Value() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public UInt64Value(UInt64Value other) : this() {
value_ = other.value_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public UInt64Value Clone() {
return new UInt64Value(this);
}
@@ -421,6 +468,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// The uint64 value.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public ulong Value {
get { return value_; }
set {
@@ -428,10 +476,12 @@ namespace Google.Protobuf.WellKnownTypes {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as UInt64Value);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(UInt64Value other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -443,16 +493,19 @@ namespace Google.Protobuf.WellKnownTypes {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Value != 0UL) hash ^= Value.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Value != 0UL) {
output.WriteRawTag(8);
@@ -460,6 +513,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Value != 0UL) {
@@ -468,6 +522,7 @@ namespace Google.Protobuf.WellKnownTypes {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(UInt64Value other) {
if (other == null) {
return;
@@ -477,6 +532,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -499,29 +555,34 @@ namespace Google.Protobuf.WellKnownTypes {
///
/// The JSON representation for `Int32Value` is JSON number.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class Int32Value : pb::IMessage<Int32Value> {
private static readonly pb::MessageParser<Int32Value> _parser = new pb::MessageParser<Int32Value>(() => new Int32Value());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<Int32Value> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.WellKnownTypes.WrappersReflection.Descriptor.MessageTypes[4]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Int32Value() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Int32Value(Int32Value other) : this() {
value_ = other.value_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Int32Value Clone() {
return new Int32Value(this);
}
@@ -532,6 +593,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// The int32 value.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int Value {
get { return value_; }
set {
@@ -539,10 +601,12 @@ namespace Google.Protobuf.WellKnownTypes {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as Int32Value);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(Int32Value other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -554,16 +618,19 @@ namespace Google.Protobuf.WellKnownTypes {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Value != 0) hash ^= Value.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Value != 0) {
output.WriteRawTag(8);
@@ -571,6 +638,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Value != 0) {
@@ -579,6 +647,7 @@ namespace Google.Protobuf.WellKnownTypes {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(Int32Value other) {
if (other == null) {
return;
@@ -588,6 +657,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -610,29 +680,34 @@ namespace Google.Protobuf.WellKnownTypes {
///
/// The JSON representation for `UInt32Value` is JSON number.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class UInt32Value : pb::IMessage<UInt32Value> {
private static readonly pb::MessageParser<UInt32Value> _parser = new pb::MessageParser<UInt32Value>(() => new UInt32Value());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<UInt32Value> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.WellKnownTypes.WrappersReflection.Descriptor.MessageTypes[5]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public UInt32Value() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public UInt32Value(UInt32Value other) : this() {
value_ = other.value_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public UInt32Value Clone() {
return new UInt32Value(this);
}
@@ -643,6 +718,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// The uint32 value.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public uint Value {
get { return value_; }
set {
@@ -650,10 +726,12 @@ namespace Google.Protobuf.WellKnownTypes {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as UInt32Value);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(UInt32Value other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -665,16 +743,19 @@ namespace Google.Protobuf.WellKnownTypes {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Value != 0) hash ^= Value.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Value != 0) {
output.WriteRawTag(8);
@@ -682,6 +763,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Value != 0) {
@@ -690,6 +772,7 @@ namespace Google.Protobuf.WellKnownTypes {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(UInt32Value other) {
if (other == null) {
return;
@@ -699,6 +782,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -721,29 +805,34 @@ namespace Google.Protobuf.WellKnownTypes {
///
/// The JSON representation for `BoolValue` is JSON `true` and `false`.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class BoolValue : pb::IMessage<BoolValue> {
private static readonly pb::MessageParser<BoolValue> _parser = new pb::MessageParser<BoolValue>(() => new BoolValue());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<BoolValue> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.WellKnownTypes.WrappersReflection.Descriptor.MessageTypes[6]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public BoolValue() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public BoolValue(BoolValue other) : this() {
value_ = other.value_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public BoolValue Clone() {
return new BoolValue(this);
}
@@ -754,6 +843,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// The bool value.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Value {
get { return value_; }
set {
@@ -761,10 +851,12 @@ namespace Google.Protobuf.WellKnownTypes {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as BoolValue);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(BoolValue other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -776,16 +868,19 @@ namespace Google.Protobuf.WellKnownTypes {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Value != false) hash ^= Value.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Value != false) {
output.WriteRawTag(8);
@@ -793,6 +888,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Value != false) {
@@ -801,6 +897,7 @@ namespace Google.Protobuf.WellKnownTypes {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(BoolValue other) {
if (other == null) {
return;
@@ -810,6 +907,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -832,29 +930,34 @@ namespace Google.Protobuf.WellKnownTypes {
///
/// The JSON representation for `StringValue` is JSON string.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class StringValue : pb::IMessage<StringValue> {
private static readonly pb::MessageParser<StringValue> _parser = new pb::MessageParser<StringValue>(() => new StringValue());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<StringValue> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.WellKnownTypes.WrappersReflection.Descriptor.MessageTypes[7]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public StringValue() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public StringValue(StringValue other) : this() {
value_ = other.value_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public StringValue Clone() {
return new StringValue(this);
}
@@ -865,17 +968,20 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// The string value.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string Value {
get { return value_; }
set {
- value_ = pb::Preconditions.CheckNotNull(value, "value");
+ value_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as StringValue);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(StringValue other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -887,16 +993,19 @@ namespace Google.Protobuf.WellKnownTypes {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Value.Length != 0) hash ^= Value.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Value.Length != 0) {
output.WriteRawTag(10);
@@ -904,6 +1013,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Value.Length != 0) {
@@ -912,6 +1022,7 @@ namespace Google.Protobuf.WellKnownTypes {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(StringValue other) {
if (other == null) {
return;
@@ -921,6 +1032,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
@@ -943,29 +1055,34 @@ namespace Google.Protobuf.WellKnownTypes {
///
/// The JSON representation for `BytesValue` is JSON string.
/// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class BytesValue : pb::IMessage<BytesValue> {
private static readonly pb::MessageParser<BytesValue> _parser = new pb::MessageParser<BytesValue>(() => new BytesValue());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<BytesValue> Parser { get { return _parser; } }
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Google.Protobuf.WellKnownTypes.WrappersReflection.Descriptor.MessageTypes[8]; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public BytesValue() {
OnConstruction();
}
partial void OnConstruction();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public BytesValue(BytesValue other) : this() {
value_ = other.value_;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public BytesValue Clone() {
return new BytesValue(this);
}
@@ -976,17 +1093,20 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// The bytes value.
/// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pb::ByteString Value {
get { return value_; }
set {
- value_ = pb::Preconditions.CheckNotNull(value, "value");
+ value_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as BytesValue);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(BytesValue other) {
if (ReferenceEquals(other, null)) {
return false;
@@ -998,16 +1118,19 @@ namespace Google.Protobuf.WellKnownTypes {
return true;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Value.Length != 0) hash ^= Value.GetHashCode();
return hash;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
if (Value.Length != 0) {
output.WriteRawTag(10);
@@ -1015,6 +1138,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
if (Value.Length != 0) {
@@ -1023,6 +1147,7 @@ namespace Google.Protobuf.WellKnownTypes {
return size;
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(BytesValue other) {
if (other == null) {
return;
@@ -1032,6 +1157,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
diff --git a/csharp/src/Google.Protobuf/project.json b/csharp/src/Google.Protobuf/project.json
new file mode 100644
index 00000000..9b831f12
--- /dev/null
+++ b/csharp/src/Google.Protobuf/project.json
@@ -0,0 +1,65 @@
+{
+ "version": "3.0.0",
+ "title": "Google Protocol Buffers",
+ "description": "See project site for more info.",
+ "authors": [ "Google Inc." ],
+ "copyright": "Copyright 2015, Google Inc.",
+
+ "packOptions": {
+ "summary": "C# runtime library for Protocol Buffers - Google's data interchange format.",
+ "tags": [ "Protocol", "Buffers", "Binary", "Serialization", "Format", "Google", "proto", "proto3" ],
+ "owners": [ "protobuf-packages" ],
+ "licenseUrl": "https://github.com/google/protobuf/blob/master/LICENSE",
+ "projectUrl": "https://github.com/google/protobuf",
+ "releaseNotes": "C# proto3 support",
+ "requireLicenseAcceptance": false,
+ "repository": {
+ "url": "https://github.com/nodatime/nodatime.git"
+ }
+ },
+
+ "buildOptions": {
+ "debugType": "portable",
+ "keyFile": "../../keys/Google.Protobuf.snk",
+ "xmlDoc": true
+ },
+
+ "configurations": {
+ "Debug": {
+ "buildOptions": {
+ "define": [ "DEBUG", "TRACE" ]
+ }
+ },
+ "Release": {
+ "buildOptions": {
+ "define": [ "RELEASE", "TRACE" ],
+ "optimize": true
+ }
+ }
+ },
+
+ "frameworks": {
+ // This target allows the package to be installed in a .NET 4.5+
+ // project without asking for myriad other dependencies.
+ "net45": {
+ },
+ "netstandard1.0": {
+ "dependencies": {
+ "System.Collections": "4.0.11",
+ "System.Diagnostics.Debug": "4.0.11",
+ "System.Globalization": "4.0.11",
+ "System.IO": "4.1.0",
+ "System.Linq": "4.1.0",
+ "System.Linq.Expressions": "4.1.0",
+ "System.ObjectModel": "4.0.12",
+ "System.Reflection": "4.1.0",
+ "System.Reflection.Extensions": "4.0.1",
+ "System.Runtime": "4.1.0",
+ "System.Runtime.Extensions": "4.1.0",
+ "System.Text.Encoding": "4.0.11",
+ "System.Text.RegularExpressions": "4.1.0",
+ "System.Threading": "4.0.11"
+ }
+ }
+ }
+}
diff --git a/docs/swift/DesignDoc.md b/docs/swift/DesignDoc.md
new file mode 100644
index 00000000..364a4d3f
--- /dev/null
+++ b/docs/swift/DesignDoc.md
@@ -0,0 +1,674 @@
+# Protocol Buffers in Swift
+
+## Objective
+
+This document describes the user-facing API and internal implementation of
+proto2 and proto3 messages in Apple’s Swift programming language.
+
+One of the key goals of protobufs is to provide idiomatic APIs for each
+language. In that vein, **interoperability with Objective-C is a non-goal of
+this proposal.** Protobuf users who need to pass messages between Objective-C
+and Swift code in the same application should use the existing Objective-C proto
+library. The goal of the effort described here is to provide an API for protobuf
+messages that uses features specific to Swift—optional types, algebraic
+enumerated types, value types, and so forth—in a natural way that will delight,
+rather than surprise, users of the language.
+
+## Naming
+
+* By convention, both typical protobuf message names and Swift structs/classes
+ are `UpperCamelCase`, so for most messages, the name of a message can be the
+ same as the name of its generated type. (However, see the discussion below
+ about prefixes under [Packages](#packages).)
+
+* Enum cases in protobufs typically are `UPPERCASE_WITH_UNDERSCORES`, whereas
+ in Swift they are `lowerCamelCase` (as of the Swift 3 API design
+ guidelines). We will transform the names to match Swift convention, using
+ a whitelist similar to the Objective-C compiler plugin to handle commonly
+ used acronyms.
+
+* Typical fields in proto messages are `lowercase_with_underscores`, while in
+ Swift they are `lowerCamelCase`. We will transform the names to match
+ Swift convention by removing the underscores and uppercasing the subsequent
+ letter.
+
+## Swift reserved words
+
+Swift has a large set of reserved words—some always reserved and some
+contextually reserved (that is, they can be used as identifiers in contexts
+where they would not be confused). As of Swift 2.2, the set of always-reserved
+words is:
+
+```
+_, #available, #column, #else, #elseif, #endif, #file, #function, #if, #line,
+#selector, as, associatedtype, break, case, catch, class, continue, default,
+defer, deinit, do, dynamicType, else, enum, extension, fallthrough, false, for,
+func, guard, if, import, in, init, inout, internal, is, let, nil, operator,
+private, protocol, public, repeat, rethrows, return, self, Self, static,
+struct, subscript, super, switch, throw, throws, true, try, typealias, var,
+where, while
+```
+
+The set of contextually reserved words is:
+
+```
+associativity, convenience, dynamic, didSet, final, get, infix, indirect,
+lazy, left, mutating, none, nonmutating, optional, override, postfix,
+precedence, prefix, Protocol, required, right, set, Type, unowned, weak,
+willSet
+```
+
+It is possible to use any reserved word as an identifier by escaping it with
+backticks (for example, ``let `class` = 5``). Other name-mangling schemes would
+require us to transform the names themselves (for example, by appending an
+underscore), which requires us to then ensure that the new name does not collide
+with something else in the same namespace.
+
+While the backtick feature may not be widely known by all Swift developers, a
+small amount of user education can address this and it seems like the best
+approach. We can unconditionally surround all property names with backticks to
+simplify generation.
+
+Some remapping will still be required, though, to avoid collisions between
+generated properties and the names of methods and properties defined in the base
+protocol/implementation of messages.
+
+# Features of Protocol Buffers
+
+This section describes how the features of the protocol buffer syntaxes (proto2
+and proto3) map to features in Swift—what the code generated from a proto will
+look like, and how it will be implemented in the underlying library.
+
+## Packages
+
+Modules are the main form of namespacing in Swift, but they are not declared
+using syntactic constructs like namespaces in C++ or packages in Java. Instead,
+they are tied to build targets in Xcode (or, in the future with open-source
+Swift, declarations in a Swift Package Manager manifest). They also do not
+easily support nesting submodules (Clang module maps support this, but pure
+Swift does not yet provide a way to define submodules).
+
+We will generate types with fully-qualified underscore-delimited names. For
+example, a message `Baz` in package `foo.bar` would generate a struct named
+`Foo_Bar_Baz`. For each fully-qualified proto message, there will be exactly one
+unique type symbol emitted in the generated binary.
+
+Users are likely to balk at the ugliness of underscore-delimited names for every
+generated type. To improve upon this situation, we will add a new string file
+level option, `swift_package_typealias`, that can be added to `.proto` files.
+When present, this will cause `typealias`es to be added to the generated Swift
+messages that replace the package name prefix with the provided string. For
+example, the following `.proto` file:
+
+```protobuf
+option swift_package_typealias = "FBP";
+package foo.bar;
+
+message Baz {
+ // Message fields
+}
+```
+
+would generate the following Swift source:
+
+```swift
+public struct Foo_Bar_Baz {
+ // Message fields and other methods
+}
+
+typealias FBPBaz = Foo_Bar_Baz
+```
+
+It should be noted that this type alias is recorded in the generated
+`.swiftmodule` so that code importing the module can refer to it, but it does
+not cause a new symbol to be generated in the compiled binary (i.e., we do not
+risk compiled size bloat by adding `typealias`es for every type).
+
+Other strategies to handle packages that were considered and rejected can be
+found in [Appendix A](#appendix-a-rejected-strategies-to-handle-packages).
+
+## Messages
+
+Proto messages are natural value types and we will generate messages as structs
+instead of classes. Users will benefit from Swift’s built-in behavior with
+regard to mutability. We will define a `ProtoMessage` protocol that defines the
+common methods and properties for all messages (such as serialization) and also
+lets users treat messages polymorphically. Any shared method implementations
+that do not differ between individual messages can be implemented in a protocol
+extension.
+
+The backing storage itself for fields of a message will be managed by a
+`ProtoFieldStorage` type that uses an internal dictionary keyed by field number,
+and whose values are the value of the field with that number (up-cast to Swift’s
+`Any` type). This class will provide type-safe getters and setters so that
+generated messages can manipulate this storage, and core serialization logic
+will live here as well. Furthermore, factoring the storage out into a separate
+type, rather than inlining the fields as stored properties in the message
+itself, lets us implement copy-on-write efficiently to support passing around
+large messages. (Furthermore, because the messages themselves are value types,
+inlining fields is not possible if the fields are submessages of the same type,
+or a type that eventually includes a submessage of the same type.)
+
+### Required fields (proto2 only)
+
+Required fields in proto2 messages seem like they could be naturally represented
+by non-optional properties in Swift, but this presents some problems/concerns.
+
+Serialization APIs permit partial serialization, which allows required fields to
+remain unset. Furthermore, other language APIs still provide `has*` and `clear*`
+methods for required fields, and knowing whether a property has a value when the
+message is in memory is still useful.
+
+For example, an e-mail draft message may have the “to” address required on the
+wire, but when the user constructs it in memory, it doesn’t make sense to force
+a value until they provide one. We only want to force a value to be present when
+the message is serialized to the wire. Using non-optional properties prevents
+this use case, and makes client usage awkward because the user would be forced
+to select a sentinel or placeholder value for any required fields at the time
+the message was created.
+
+### Default values
+
+In proto2, fields can have a default value specified that may be a value other
+than the default value for its corresponding language type (for example, a
+default value of 5 instead of 0 for an integer). When reading a field that is
+not explicitly set, the user expects to get that value. This makes Swift
+optionals (i.e., `Foo?`) unsuitable for fields in general. Unfortunately, we
+cannot implement our own “enhanced optional” type without severely complicating
+usage (Swift’s use of type inference and its lack of implicit conversions would
+require manual unwrapping of every property value).
+
+Instead, we can use **implicitly unwrapped optionals.** For example, a property
+generated for a field of type `int32` would have Swift type `Int32!`. These
+properties would behave with the following characteristics, which mirror the
+nil-resettable properties used elsewhere in Apple’s SDKs (for example,
+`UIView.tintColor`):
+
+* Assigning a non-nil value to a property sets the field to that value.
+* Assigning nil to a property clears the field (its internal representation is
+ nilled out).
+* Reading the value of a property returns its value if it is set, or returns
+ its default value if it is not set. Reading a property never returns nil.
+
+The final point in the list above implies that the optional cannot be checked to
+determine if the field is set to a value other than its default: it will never
+be nil. Instead, we must provide `has*` methods for each field to allow the user
+to check this. These methods will be public in proto2. In proto3, these methods
+will be private (if generated at all), since the user can test the returned
+value against the zero value for that type.
+
+### Autocreation of nested messages
+
+For convenience, dotting into an unset field representing a nested message will
+return an instance of that message with default values. As in the Objective-C
+implementation, this does not actually cause the field to be set until the
+returned message is mutated. Fortunately, thanks to the way mutability of value
+types is implemented in Swift, the language automatically handles the
+reassignment-on-mutation for us. A static singleton instance containing default
+values can be associated with each message that can be returned when reading, so
+copies are only made by the Swift runtime when mutation occurs. For example,
+given the following proto:
+
+```protobuf
+message Node {
+ Node child = 1;
+ string value = 2 [default = "foo"];
+}
+```
+
+The following Swift code would act as commented, where setting deeply nested
+properties causes the copies and mutations to occur as the assignment statement
+is unwound:
+
+```swift
+var node = Node()
+
+let s = node.child.child.value
+// 1. node.child returns the "default Node".
+// 2. Reading .child on the result of (1) returns the same default Node.
+// 3. Reading .value on the result of (2) returns the default value "foo".
+
+node.child.child.value = "bar"
+// 4. Setting .value on the default Node causes a copy to be made and sets
+// the property on that copy. Subsequently, the language updates the
+// value of "node.child.child" to point to that copy.
+// 5. Updating "node.child.child" in (4) requires another copy, because
+// "node.child" was also the instance of the default node. The copy is
+// assigned back to "node.child".
+// 6. Setting "node.child" in (5) is a simple value reassignment, since
+// "node" is a mutable var.
+```
+
+In other words, the generated messages do not internally have to manage parental
+relationships to backfill the appropriate properties on mutation. Swift provides
+this for free.
+
+## Scalar value fields
+
+Proto scalar value fields will map to Swift types in the following way:
+
+.proto Type | Swift Type
+----------- | -------------------
+`double` | `Double`
+`float` | `Float`
+`int32` | `Int32`
+`int64` | `Int64`
+`uint32` | `UInt32`
+`uint64` | `UInt64`
+`sint32` | `Int32`
+`sint64` | `Int64`
+`fixed32` | `UInt32`
+`fixed64` | `UInt64`
+`sfixed32` | `Int32`
+`sfixed64` | `Int64`
+`bool` | `Bool`
+`string` | `String`
+`bytes` | `Foundation.NSData`
+
+The proto spec defines a number of integral types that map to the same Swift
+type; for example, `intXX`, `sintXX`, and `sfixedXX` are all signed integers,
+and `uintXX` and `fixedXX` are both unsigned integers. No other language
+implementation distinguishes these further, so we do not do so either. The
+rationale is that the various types only serve to distinguish how the value is
+**encoded on the wire**; once loaded in memory, the user is not concerned about
+these variations.
+
+Swift’s lack of implicit conversions among types will make it slightly annoying
+to use these types in a context expecting an `Int`, or vice-versa, but since
+this is a data-interchange format with explicitly-sized fields, we should not
+hide that information from the user. Users will have to explicitly write
+`Int(message.myField)`, for example.
+
+## Embedded message fields
+
+Embedded message fields can be represented using an optional variable of the
+generated message type. Thus, the message
+
+```protobuf
+message Foo {
+ Bar bar = 1;
+}
+```
+
+would be represented in Swift as
+
+```swift
+public struct Foo: ProtoMessage {
+ public var bar: Bar! {
+ get { ... }
+ set { ... }
+ }
+}
+```
+
+If the user explicitly sets `bar` to nil, or if it was never set when read from
+the wire, retrieving the value of `bar` would return a default, statically
+allocated instance of `Bar` containing default values for its fields. This
+achieves the desired behavior for default values in the same way that scalar
+fields are designed, and also allows users to deep-drill into complex object
+graphs to get or set fields without checking for nil at each step.
+
+## Enum fields
+
+The design and implementation of enum fields will differ somewhat drastically
+depending on whether the message being generated is a proto2 or proto3 message.
+
+### proto2 enums
+
+For proto2, we do not need to be concerned about unknown enum values, so we can
+use the simple raw-value enum syntax provided by Swift. So the following enum in
+proto2:
+
+```protobuf
+enum ContentType {
+ TEXT = 0;
+ IMAGE = 1;
+}
+```
+
+would become this Swift enum:
+
+```swift
+public enum ContentType: Int32, NilLiteralConvertible {
+ case text = 0
+ case image = 1
+
+ public init(nilLiteral: ()) {
+ self = .text
+ }
+}
+```
+
+See below for the discussion about `NilLiteralConvertible`.
+
+### proto3 enums
+
+For proto3, we need to be able to preserve unknown enum values that may come
+across the wire so that they can be written back if unmodified. We can
+accomplish this in Swift by using a case with an associated value for unknowns.
+So the following enum in proto3:
+
+```protobuf
+enum ContentType {
+ TEXT = 0;
+ IMAGE = 1;
+}
+```
+
+would become this Swift enum:
+
+```swift
+public enum ContentType: RawRepresentable, NilLiteralConvertible {
+ case text
+ case image
+ case UNKNOWN_VALUE(Int32)
+
+ public typealias RawValue = Int32
+
+ public init(nilLiteral: ()) {
+ self = .text
+ }
+
+ public init(rawValue: RawValue) {
+ switch rawValue {
+ case 0: self = .text
+ case 1: self = .image
+ default: self = .UNKNOWN_VALUE(rawValue)
+ }
+
+ public var rawValue: RawValue {
+ switch self {
+ case .text: return 0
+ case .image: return 1
+ case .UNKNOWN_VALUE(let value): return value
+ }
+ }
+}
+```
+
+Note that the use of a parameterized case prevents us from inheriting from the
+raw `Int32` type; Swift does not allow an enum with a raw type to have cases
+with arguments. Instead, we must implement the raw value initializer and
+computed property manually. The `UNKNOWN_VALUE` case is explicitly chosen to be
+"ugly" so that it stands out and does not conflict with other possible case
+names.
+
+Using this approach, proto3 consumers must always have a default case or handle
+the `.UNKNOWN_VALUE` case to satisfy case exhaustion in a switch statement; the
+Swift compiler considers it an error if switch statements are not exhaustive.
+
+### NilLiteralConvertible conformance
+
+This is required to clean up the usage of enum-typed properties in switch
+statements. Unlike other field types, enum properties cannot be
+implicitly-unwrapped optionals without requiring that uses in switch statements
+be explicitly unwrapped. For example, if we consider a message with the enum
+above, this usage will fail to compile:
+
+```swift
+// Without NilLiteralConvertible conformance on ContentType
+public struct SomeMessage: ProtoMessage {
+ public var contentType: ContentType! { ... }
+}
+
+// ERROR: no case named text or image
+switch someMessage.contentType {
+ case .text: { ... }
+ case .image: { ... }
+}
+```
+
+Even though our implementation guarantees that `contentType` will never be nil,
+if it is an optional type, its cases would be `some` and `none`, not the cases
+of the underlying enum type. In order to use it in this context, the user must
+write `someMessage.contentType!` in their switch statement.
+
+Making the enum itself `NilLiteralConvertible` permits us to make the property
+non-optional, so the user can still set it to nil to clear it (i.e., reset it to
+its default value), while eliminating the need to explicitly unwrap it in a
+switch statement.
+
+```swift
+// With NilLiteralConvertible conformance on ContentType
+public struct SomeMessage: ProtoMessage {
+ // Note that the property type is no longer optional
+ public var contentType: ContentType { ... }
+}
+
+// OK: Compiles and runs as expected
+switch someMessage.contentType {
+ case .text: { ... }
+ case .image: { ... }
+}
+
+// The enum can be reset to its default value this way
+someMessage.contentType = nil
+```
+
+One minor oddity with this approach is that nil will be auto-converted to the
+default value of the enum in any context, not just field assignment. In other
+words, this is valid:
+
+```swift
+func foo(contentType: ContentType) { ... }
+foo(nil) // Inside foo, contentType == .text
+```
+
+That being said, the advantage of being able to simultaneously support
+nil-resettability and switch-without-unwrapping outweighs this side effect,
+especially if appropriately documented. It is our hope that a new form of
+resettable properties will be added to Swift that eliminates this inconsistency.
+Some community members have already drafted or sent proposals for review that
+would benefit our designs:
+
+* [SE-0030: Property Behaviors]
+ (https://github.com/apple/swift-evolution/blob/master/proposals/0030-property-behavior-decls.md)
+* [Drafted: Resettable Properties]
+ (https://github.com/patters/swift-evolution/blob/master/proposals/0000-resettable-properties.md)
+
+### Enum aliases
+
+The `allow_alias` option in protobuf slightly complicates the use of Swift enums
+to represent that type, because raw values of cases in an enum must be unique.
+Swift lets us define static variables in an enum that alias actual cases. For
+example, the following protobuf enum:
+
+```protobuf
+enum Foo {
+ option allow_alias = true;
+ BAR = 0;
+ BAZ = 0;
+}
+```
+
+will be represented in Swift as:
+
+```swift
+public enum Foo: Int32, NilLiteralConvertible {
+ case bar = 0
+ static public let baz = bar
+
+ // ... etc.
+}
+
+// Can still use .baz shorthand to reference the alias in contexts
+// where the type is inferred
+```
+
+That is, we use the first name as the actual case and use static variables for
+the other aliases. One drawback to this approach is that the static aliases
+cannot be used as cases in a switch statement (the compiler emits the error
+*“Enum case ‘baz’ not found in type ‘Foo’”*). However, in our own code bases,
+there are only a few places where enum aliases are not mere renamings of an
+older value, but they also don’t appear to be the type of value that one would
+expect to switch on (for example, a group of named constants representing
+metrics rather than a set of options), so this restriction is not significant.
+
+This strategy also implies that changing the name of an enum and adding the old
+name as an alias below the new name will be a breaking change in the generated
+Swift code.
+
+## Oneof types
+
+The `oneof` feature represents a “variant/union” data type that maps nicely to
+Swift enums with associated values (algebraic types). These fields can also be
+accessed independently though, and, specifically in the case of proto2, it’s
+reasonable to expect access to default values when accessing a field that is not
+explicitly set.
+
+Taking all this into account, we can represent a `oneof` in Swift with two sets
+of constructs:
+
+* Properties in the message that correspond to the `oneof` fields.
+* A nested enum named after the `oneof` and which provides the corresponding
+ field values as case arguments.
+
+This approach fulfills the needs of proto consumers by providing a
+Swift-idiomatic way of simultaneously checking which field is set and accessing
+its value, providing individual properties to access the default values
+(important for proto2), and safely allows a field to be moved into a `oneof`
+without breaking clients.
+
+Consider the following proto:
+
+```protobuf
+message MyMessage {
+ oneof record {
+ string name = 1 [default = "unnamed"];
+ int32 id_number = 2 [default = 0];
+ }
+}
+```
+
+In Swift, we would generate an enum, a property for that enum, and properties
+for the fields themselves:
+
+```swift
+public struct MyMessage: ProtoMessage {
+ public enum Record: NilLiteralConvertible {
+ case name(String)
+ case idNumber(Int32)
+ case NOT_SET
+
+ public init(nilLiteral: ()) { self = .NOT_SET }
+ }
+
+ // This is the "Swifty" way of accessing the value
+ public var record: Record { ... }
+
+ // Direct access to the underlying fields
+ public var name: String! { ... }
+ public var idNumber: Int32! { ... }
+}
+```
+
+This makes both usage patterns possible:
+
+```swift
+// Usage 1: Case-based dispatch
+switch message.record {
+ case .name(let name):
+ // Do something with name if it was explicitly set
+ case .idNumber(let id):
+ // Do something with id_number if it was explicitly set
+ case .NOT_SET:
+ // Do something if it’s not set
+}
+
+// Usage 2: Direct access for default value fallback
+// Sets the label text to the name if it was explicitly set, or to
+// "unnamed" (the default value for the field) if id_number was set
+// instead
+let myLabel = UILabel()
+myLabel.text = message.name
+```
+
+As with proto enums, the generated `oneof` enum conforms to
+`NilLiteralConvertible` to avoid switch statement issues. Setting the property
+to nil will clear it (i.e., reset it to `NOT_SET`).
+
+## Unknown Fields (proto2 only)
+
+To be written.
+
+## Extensions (proto2 only)
+
+To be written.
+
+## Reflection and Descriptors
+
+We will not include reflection or descriptors in the first version of the Swift
+library. The use cases for reflection on mobile are not as strong and the static
+data to represent the descriptors would add bloat when we wish to keep the code
+size small.
+
+In the future, we will investigate whether they can be included as extensions
+which might be able to be excluded from a build and/or automatically dead
+stripped by the compiler if they are not used.
+
+## Appendix A: Rejected strategies to handle packages
+
+### Each package is its own Swift module
+
+Each proto package could be declared as its own Swift module, replacing dots
+with underscores (e.g., package `foo.bar` becomes module `Foo_Bar`). Then, users
+would simply import modules containing whatever proto modules they want to use
+and refer to the generated types by their short names.
+
+**This solution is simply not possible, however.** Swift modules cannot
+circularly reference each other, but there is no restriction against proto
+packages doing so. Circular imports are forbidden (e.g., `foo.proto` importing
+`bar.proto` importing `foo.proto`), but nothing prevents package `foo` from
+using a type in package `bar` which uses a different type in package `foo`, as
+long as there is no import cycle. If these packages were generated as Swift
+modules, then `Foo` would contain an `import Bar` statement and `Bar` would
+contain an `import Foo` statement, and there is no way to compile this.
+
+### Ad hoc namespacing with structs
+
+We can “fake” namespaces in Swift by declaring empty structs with private
+initializers. Since modules are constructed based on compiler arguments, not by
+syntactic constructs, and because there is no pure Swift way to define
+submodules (even though Clang module maps support this), there is no
+source-drive way to group generated code into namespaces aside from this
+approach.
+
+Types can be added to those intermediate package structs using Swift extensions.
+For example, a message `Baz` in package `foo.bar` could be represented in Swift
+as follows:
+
+```swift
+public struct Foo {
+ private init() {}
+}
+
+public extension Foo {
+ public struct Bar {
+ private init() {}
+ }
+}
+
+public extension Foo.Bar {
+ public struct Baz {
+ // Message fields and other methods
+ }
+}
+
+let baz = Foo.Bar.Baz()
+```
+
+Each of these constructs would actually be defined in a separate file; Swift
+lets us keep them separate and add multiple structs to a single “namespace”
+through extensions.
+
+Unfortunately, these intermediate structs generate symbols of their own
+(metatype information in the data segment). This becomes problematic if multiple
+build targets contain Swift sources generated from different messages in the
+same package. At link time, these symbols would collide, resulting in multiple
+definition errors.
+
+This approach also has the disadvantage that there is no automatic “short” way
+to refer to the generated messages at the deepest nesting levels; since this use
+of structs is a hack around the lack of namespaces, there is no equivalent to
+import (Java) or using (C++) to simplify this. Users would have to declare type
+aliases to make this cleaner, or we would have to generate them for users.
diff --git a/docs/third_party.md b/docs/third_party.md
new file mode 100644
index 00000000..021cc564
--- /dev/null
+++ b/docs/third_party.md
@@ -0,0 +1,149 @@
+# Third-Party Add-ons for Protocol Buffers
+
+This page lists code related to Protocol Buffers which is developed and maintained by third parties. You may find this code useful, but note that **these projects are not affiliated with or endorsed by Google (unless explicitly marked)**; try them at your own risk. Also note that many projects here are in the early stages of development and not production-ready.
+
+If you have a project that should be listed here, please [send us a pull request](https://github.com/google/protobuf/pulls) to update this page.
+
+## Programming Languages
+
+These are projects we know about implementing Protocol Buffers for other programming languages:
+* Action Script: http://code.google.com/p/protobuf-actionscript3/
+* Action Script: https://code.google.com/p/protoc-gen-as3/
+* Action Script: https://github.com/matrix3d/JProtoc
+* Action Script: https://github.com/zhongfq/protobuf-as3/
+* C: https://github.com/protobuf-c/protobuf-c
+* C: http://koti.kapsi.fi/jpa/nanopb/
+* C: https://github.com/cloudwu/pbc/
+* C: https://github.com/haberman/upb/wiki
+* C: https://github.com/squidfunk/protobluff
+* C++: https://github.com/google/protobuf (Google-official implementation)
+* C/C++: http://spbc.sf.net/
+* C#: http://code.google.com/p/protobuf-csharp-port
+* C#: http://code.google.com/p/protosharp/
+* C#: https://silentorbit.com/protobuf/
+* C#/.NET/WCF/VB: http://code.google.com/p/protobuf-net/
+* Clojure: http://github.com/ninjudd/clojure-protobuf
+* Common Lisp: http://www.prism.gatech.edu/~ndantam3/docs/s-protobuf/
+* Common Lisp: http://github.com/brown/protobuf
+* D: https://github.com/msoucy/dproto
+* D: http://256.makerslocal.org/wiki/index.php/ProtocolBuffer
+* D: https://github.com/opticron/ProtocolBuffer
+* Dart: https://github.com/dart-lang/dart-protobuf (runtime) https://github.com/dart-lang/dart-protoc-plugin (code generator)
+* Delphi: http://sourceforge.net/projects/protobuf-delphi/
+* Delphi: http://fundementals.sourceforge.net/dl.html
+* Elixir: https://github.com/jeremyong/exprotoc
+* Erlang: http://github.com/ngerakines/erlang_protobuffs/tree/master
+* Erlang: http://piqi.org/
+* Erlang: https://code.google.com/p/protoc-gen-erl/
+* Erlang: https://github.com/basho/erlang_protobuffs
+* Go: https://github.com/golang/protobuf (Google-official implementation)
+* Go: http://code.google.com/p/goprotobuf/
+* Go: https://github.com/akunspy/gopbuf
+* Haskell: http://hackage.haskell.org/package/hprotoc
+* Haxe: https://github.com/Atry/protoc-gen-haxe
+* Java: https://github.com/google/protobuf (Google-official implementation)
+* Java/Android: https://github.com/square/wire
+* Java ME: http://code.google.com/p/protobuf-javame/
+* Java ME: http://swingme.sourceforge.net/encode.shtml
+* Java ME: http://github.com/ponderingpanda/protobuf-j2me
+* Java ME: http://code.google.com/p/protobuf-j2me/
+* Javascript: http://code.google.com/p/protobuf-js/
+* Javascript: http://github.com/sirikata/protojs
+* Javascript: https://github.com/dcodeIO/ProtoBuf.js
+* Javascript: http://code.google.com/p/protobuf-for-node/
+* Javascript: http://code.google.com/p/protostuff/
+* Julia: https://github.com/tanmaykm/ProtoBuf.jl
+* Lua: http://code.google.com/p/protoc-gen-lua/
+* Lua: http://github.com/indygreg/lua-protobuf
+* Lua: https://github.com/Neopallium/lua-pb
+* Matlab: http://code.google.com/p/protobuf-matlab/
+* Mercury: http://code.google.com/p/protobuf-mercury/
+* Objective C: http://code.google.com/p/protobuf-objc/
+* Objective C: https://github.com/alexeyxo/protobuf-objc
+* OCaml: http://piqi.org/
+* Perl: http://groups.google.com/group/protobuf-perl
+* Perl: http://search.cpan.org/perldoc?Google::ProtocolBuffers
+* Perl/XS: http://code.google.com/p/protobuf-perlxs/
+* PHP: http://code.google.com/p/pb4php/
+* PHP: https://github.com/allegro/php-protobuf/
+* PHP: https://github.com/chobie/php-protocolbuffers
+* PHP: http://drslump.github.com/Protobuf-PHP
+* Prolog: http://www.swi-prolog.org/pldoc/package/protobufs.html
+* Python: https://github.com/google/protobuf (Google-official implementation)
+* Python: http://eigenein.github.com/protobuf/
+* R: http://cran.r-project.org/package=RProtoBuf
+* Ruby: http://code.google.com/p/ruby-protobuf/
+* Ruby: http://github.com/mozy/ruby-protocol-buffers
+* Ruby: https://github.com/bmizerany/beefcake/tree/master/lib/beefcake
+* Ruby: https://github.com/localshred/protobuf
+* Rust: https://github.com/stepancheg/rust-protobuf/
+* Scala: http://github.com/jeffplaisance/scala-protobuf
+* Scala: http://code.google.com/p/protobuf-scala
+* Scala: https://github.com/SandroGrzicic/ScalaBuff
+* Scala: http://trueaccord.github.io/ScalaPB/
+* Swift: https://github.com/alexeyxo/protobuf-swift
+* Vala: https://launchpad.net/protobuf-vala
+* Visual Basic: http://code.google.com/p/protobuf-net/
+
+## RPC Implementations
+
+GRPC (http://www.grpc.io/) is Google's RPC implementation for Protocol Buffers. There are other third-party RPC implementations as well. Some of these actually work with Protocol Buffers service definitions (defined using the `service` keyword in `.proto` files) while others just use Protocol Buffers message objects.
+
+* https://github.com/grpc/grpc (C++, Node.js, Python, Ruby, Objective-C, PHP, C#, Google-official implementation)
+* http://zeroc.com/ice.html (Multiple languages)
+* http://code.google.com/p/protobuf-net/ (C#/.NET/WCF/VB)
+* https://launchpad.net/txprotobuf/ (Python)
+* https://github.com/modeswitch/protobuf-rpc (Python)
+* http://code.google.com/p/protobuf-socket-rpc/ (Java, Python)
+* http://code.google.com/p/proto-streamer/ (Java)
+* http://code.google.com/p/server1/ (C++)
+* http://deltavsoft.com/RcfUserGuide/Protobufs (C++)
+* http://code.google.com/p/protobuf-mina-rpc/ (Python client, Java server)
+* http://code.google.com/p/casocklib/ (C++)
+* http://code.google.com/p/cxf-protobuf/ (Java)
+* http://code.google.com/p/protobuf-remote/ (C++/C#)
+* http://code.google.com/p/protobuf-rpc-pro/ (Java)
+* https://code.google.com/p/protorpc/ (Go/C++)
+* https://code.google.com/p/eneter-protobuf-serializer/ (Java/.NET)
+* http://www.deltavsoft.com/RCFProto.html (C++/Java/Python/C#)
+* https://github.com/robbinfan/claire-protorpc (C++)
+* https://github.com/BaiduPS/sofa-pbrpc (C++)
+* https://github.com/ebencheung/arab (C++)
+* http://code.google.com/p/protobuf-csharp-rpc/ (C#)
+* https://github.com/thesamet/rpcz (C++/Python, based on ZeroMQ)
+* https://github.com/w359405949/libmaid (C++, Python)
+* https://github.com/madwyn/libpbrpc (C++)
+
+## Other Utilities
+
+There are miscellaneous other things you may find useful as a Protocol Buffers developer.
+
+* [NetBeans IDE plugin](http://code.google.com/p/protobuf-netbeans-plugin/)
+* [Wireshark/Ethereal packet sniffer plugin](http://code.google.com/p/protobuf-wireshark/)
+* [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)
+* [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/)
+* [C++ Builder compatible protobuf](https://github.com/saadware/protobuf-cppbuilder)
+* Maven Protocol Compiler Plugin
+ * https://github.com/sergei-ivanov/maven-protoc-plugin/
+ * http://igor-petruk.github.com/protobuf-maven-plugin/
+ * http://code.google.com/p/maven-protoc-plugin/
+ * https://github.com/os72/protoc-jar-maven-plugin
+* [Documentation generator plugin (Markdown/HTML/DocBook/...)](https://github.com/estan/protoc-gen-doc)
+* [DocBook generator for .proto files](http://code.google.com/p/protoc-gen-docbook/)
+* [Protobuf for nginx module](https://github.com/dbcode/protobuf-nginx/)
+* [RSpec matchers and Cucumber step defs for testing Protocol Buffers](https://github.com/connamara/protobuf_spec)
+* [Sbt plugin for Protocol Buffers](https://github.com/Atry/sbt-cppp)
+* [Gradle Protobuf Plugin](https://github.com/aantono/gradle-plugin-protobuf)
+* [Multi-platform executable JAR and Java API for protoc](https://github.com/os72/protoc-jar)
+* [Python scripts to convert between Protocol Buffers and JSON](https://github.com/NextTuesday/py-pb-converters)
+* [Visual Studio Language Service support for Protocol Buffers](http://visualstudiogallery.msdn.microsoft.com/4bc0f38c-b058-4e05-ae38-155e053c19c5)
+* [C++ library for serialization/de-serialization between Protocol Buffers and JSON.](https://github.com/yinqiwen/pbjson)
+* [ProtoBuf with Java EE7 Expression Language 3.0; pure Java ProtoBuf Parser and Builder.](https://github.com/protobufel/protobuf-el)
+* [Notepad++ Syntax Highlighting for .proto files](https://github.com/chai2010/notepadplus-protobuf)
+* [Linter for .proto files](https://github.com/ckaznocha/protoc-gen-lint)
+* [Protocol Buffers Dynamic Schema - create protobuf schemas programmatically (Java)] (https://github.com/os72/protobuf-dynamic)
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
new file mode 100644
index 00000000..2cd2acc0
--- /dev/null
+++ b/examples/CMakeLists.txt
@@ -0,0 +1,63 @@
+# Minimum CMake required
+cmake_minimum_required(VERSION 2.8.12)
+
+# Project
+project(protobuf-examples)
+
+# Find required protobuf package
+find_package(protobuf CONFIG REQUIRED)
+
+if(protobuf_VERBOSE)
+ message(STATUS "Using Protocol Buffers ${Protobuf_VERSION}")
+endif()
+
+set(CMAKE_INCLUDE_CURRENT_DIR TRUE)
+
+# http://www.cmake.org/Wiki/CMake_FAQ#How_can_I_build_my_MSVC_application_with_a_static_runtime.3F
+if(MSVC AND protobuf_MSVC_STATIC_RUNTIME)
+ foreach(flag_var
+ CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
+ CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
+ if(${flag_var} MATCHES "/MD")
+ string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
+ endif(${flag_var} MATCHES "/MD")
+ endforeach()
+endif()
+
+foreach(example add_person list_people)
+ set(${example}_SRCS ${example}.cc)
+ set(${example}_PROTOS addressbook.proto)
+
+ #Code Generation
+ if(protobuf_MODULE_COMPATIBLE) #Legacy Support
+ protobuf_generate_cpp(${example}_PROTO_SRCS ${example}_PROTO_HDRS ${${example}_PROTOS})
+ list(APPEND ${example}_SRCS ${${example}_PROTO_SRCS} ${${example}_PROTO_HDRS})
+ else()
+
+ foreach(proto_file ${${example}_PROTOS})
+ get_filename_component(proto_file_abs ${proto_file} ABSOLUTE)
+ get_filename_component(basename ${proto_file} NAME_WE)
+ set(generated_files ${basename}.pb.cc ${basename}.pb.h)
+ list(APPEND ${example}_SRCS ${generated_files})
+
+ add_custom_command(
+ OUTPUT ${generated_files}
+ COMMAND protobuf::protoc
+ ARGS --cpp_out ${CMAKE_CURRENT_BINARY_DIR} -I ${CMAKE_CURRENT_SOURCE_DIR} ${proto_file_abs}
+ COMMENT "Generating ${generated_files} from ${proto_file}"
+ VERBATIM
+ )
+ endforeach()
+ endif()
+
+ #Executable setup
+ set(executable_name ${example}_cpp)
+ add_executable(${executable_name} ${${example}_SRCS} ${${example}_PROTOS})
+ if(protobuf_MODULE_COMPATIBLE) #Legacy mode
+ target_include_directories(${executable_name} PUBLIC ${PROTOBUF_INCLUDE_DIRS})
+ target_link_libraries(${executable_name} ${PROTOBUF_LIBRARIES})
+ else()
+ target_link_libraries(${executable_name} protobuf::libprotobuf)
+ endif()
+
+endforeach()
diff --git a/examples/README.txt b/examples/README.txt
index e6f30370..b33f8414 100644
--- a/examples/README.txt
+++ b/examples/README.txt
@@ -35,7 +35,7 @@ build with all the other examples. See:
https://github.com/golang/protobuf
for more information about Go protocol buffer support.
-First, install the the Protocol Buffers compiler (protoc).
+First, install the Protocol Buffers compiler (protoc).
Then, install the Go Protocol Buffers plugin
($GOPATH/bin must be in your $PATH for protoc to find it):
go get github.com/golang/protobuf/protoc-gen-go
diff --git a/examples/add_person.go b/examples/add_person.go
index 6b2d3d69..4f2e7f74 100644
--- a/examples/add_person.go
+++ b/examples/add_person.go
@@ -105,7 +105,10 @@ func main() {
log.Fatalln("Error reading file:", err)
}
}
+
+ // [START marshal_proto]
book := &pb.AddressBook{}
+ // [START_EXCLUDE]
if err := proto.Unmarshal(in, book); err != nil {
log.Fatalln("Failed to parse address book:", err)
}
@@ -116,6 +119,7 @@ func main() {
log.Fatalln("Error with address:", err)
}
book.People = append(book.People, addr)
+ // [END_EXCLUDE]
// Write the new address book back to disk.
out, err := proto.Marshal(book)
@@ -125,4 +129,5 @@ func main() {
if err := ioutil.WriteFile(fname, out, 0644); err != nil {
log.Fatalln("Failed to write address book:", err)
}
+ // [END marshal_proto]
}
diff --git a/examples/add_person.py b/examples/add_person.py
index fd81c982..0b698579 100755
--- a/examples/add_person.py
+++ b/examples/add_person.py
@@ -43,9 +43,8 @@ address_book = addressbook_pb2.AddressBook()
# Read the existing address book.
try:
- f = open(sys.argv[1], "rb")
- address_book.ParseFromString(f.read())
- f.close()
+ with open(sys.argv[1], "rb") as f:
+ address_book.ParseFromString(f.read())
except IOError:
print sys.argv[1] + ": File not found. Creating a new file."
@@ -53,6 +52,5 @@ except IOError:
PromptForAddress(address_book.people.add())
# Write the new address book back to disk.
-f = open(sys.argv[1], "wb")
-f.write(address_book.SerializeToString())
-f.close()
+with open(sys.argv[1], "wb") as f:
+ f.write(address_book.SerializeToString())
diff --git a/examples/list_people.go b/examples/list_people.go
index 48b1fbfa..70bc589e 100644
--- a/examples/list_people.go
+++ b/examples/list_people.go
@@ -11,25 +11,29 @@ import (
pb "github.com/google/protobuf/examples/tutorial"
)
-func listPeople(w io.Writer, book *pb.AddressBook) {
- for _, p := range book.People {
- fmt.Fprintln(w, "Person ID:", p.Id)
- fmt.Fprintln(w, " Name:", p.Name)
- if p.Email != "" {
- fmt.Fprintln(w, " E-mail address:", p.Email)
- }
+func writePerson(w io.Writer, p *pb.Person) {
+ fmt.Fprintln(w, "Person ID:", p.Id)
+ fmt.Fprintln(w, " Name:", p.Name)
+ if p.Email != "" {
+ fmt.Fprintln(w, " E-mail address:", p.Email)
+ }
- for _, pn := range p.Phones {
- switch pn.Type {
- case pb.Person_MOBILE:
- fmt.Fprint(w, " Mobile phone #: ")
- case pb.Person_HOME:
- fmt.Fprint(w, " Home phone #: ")
- case pb.Person_WORK:
- fmt.Fprint(w, " Work phone #: ")
- }
- fmt.Fprintln(w, pn.Number)
+ for _, pn := range p.Phones {
+ switch pn.Type {
+ case pb.Person_MOBILE:
+ fmt.Fprint(w, " Mobile phone #: ")
+ case pb.Person_HOME:
+ fmt.Fprint(w, " Home phone #: ")
+ case pb.Person_WORK:
+ fmt.Fprint(w, " Work phone #: ")
}
+ fmt.Fprintln(w, pn.Number)
+ }
+}
+
+func listPeople(w io.Writer, book *pb.AddressBook) {
+ for _, p := range book.People {
+ writePerson(w, p)
}
}
@@ -41,19 +45,17 @@ func main() {
}
fname := os.Args[1]
+ // [START unmarshal_proto]
// Read the existing address book.
in, err := ioutil.ReadFile(fname)
if err != nil {
- if os.IsNotExist(err) {
- fmt.Printf("%s: File not found. Creating new file.\n", fname)
- } else {
- log.Fatalln("Error reading file:", err)
- }
+ log.Fatalln("Error reading file:", err)
}
book := &pb.AddressBook{}
if err := proto.Unmarshal(in, book); err != nil {
log.Fatalln("Failed to parse address book:", err)
}
+ // [END unmarshal_proto]
listPeople(os.Stdout, book)
}
diff --git a/examples/list_people.py b/examples/list_people.py
index 755de901..f131872d 100755
--- a/examples/list_people.py
+++ b/examples/list_people.py
@@ -31,8 +31,7 @@ if len(sys.argv) != 2:
address_book = addressbook_pb2.AddressBook()
# Read the existing address book.
-f = open(sys.argv[1], "rb")
-address_book.ParseFromString(f.read())
-f.close()
+with open(sys.argv[1], "rb") as f:
+ address_book.ParseFromString(f.read())
ListPeople(address_book)
diff --git a/examples/list_people_test.go b/examples/list_people_test.go
index 721d3555..87d6ad6e 100644
--- a/examples/list_people_test.go
+++ b/examples/list_people_test.go
@@ -8,6 +8,30 @@ import (
pb "github.com/google/protobuf/examples/tutorial"
)
+func TestWritePersonWritesPerson(t *testing.T) {
+ buf := new(bytes.Buffer)
+ // [START populate_proto]
+ p := pb.Person{
+ Id: 1234,
+ Name: "John Doe",
+ Email: "jdoe@example.com",
+ Phones: []*pb.Person_PhoneNumber{
+ {Number: "555-4321", Type: pb.Person_HOME},
+ },
+ }
+ // [END populate_proto]
+ writePerson(buf, &p)
+ got := buf.String()
+ want := `Person ID: 1234
+ Name: John Doe
+ E-mail address: jdoe@example.com
+ Home phone #: 555-4321
+`
+ if got != want {
+ t.Errorf("writePerson(%s) =>\n\t%q, want %q", p.String(), got, want)
+ }
+}
+
func TestListPeopleWritesList(t *testing.T) {
buf := new(bytes.Buffer)
in := pb.AddressBook{[]*pb.Person{
diff --git a/generate_descriptor_proto.sh b/generate_descriptor_proto.sh
index cd906896..c170c837 100755
--- a/generate_descriptor_proto.sh
+++ b/generate_descriptor_proto.sh
@@ -43,57 +43,64 @@ declare -a RUNTIME_PROTO_FILES=(\
CORE_PROTO_IS_CORRECT=0
PROCESS_ROUND=1
+TMP=$(mktemp -d)
echo "Updating descriptor protos..."
while [ $CORE_PROTO_IS_CORRECT -ne 1 ]
do
echo "Round $PROCESS_ROUND"
CORE_PROTO_IS_CORRECT=1
- for PROTO_FILE in ${RUNTIME_PROTO_FILES[@]}; do
- BASE_NAME=${PROTO_FILE%.*}
- cp ${BASE_NAME}.pb.h ${BASE_NAME}.pb.h.tmp
- cp ${BASE_NAME}.pb.cc ${BASE_NAME}.pb.cc.tmp
- done
- cp google/protobuf/compiler/plugin.pb.h google/protobuf/compiler/plugin.pb.h.tmp
- cp google/protobuf/compiler/plugin.pb.cc google/protobuf/compiler/plugin.pb.cc.tmp
- make $@ protoc &&
- ./protoc --cpp_out=dllexport_decl=LIBPROTOBUF_EXPORT:. ${RUNTIME_PROTO_FILES[@]} && \
- ./protoc --cpp_out=dllexport_decl=LIBPROTOC_EXPORT:. google/protobuf/compiler/plugin.proto
+ make $@ protoc
+ if test $? -ne 0; then
+ echo "Failed to build protoc."
+ exit 1
+ fi
+
+ ./protoc --cpp_out=dllexport_decl=LIBPROTOBUF_EXPORT:$TMP ${RUNTIME_PROTO_FILES[@]} && \
+ ./protoc --cpp_out=dllexport_decl=LIBPROTOC_EXPORT:$TMP google/protobuf/compiler/plugin.proto
for PROTO_FILE in ${RUNTIME_PROTO_FILES[@]}; do
BASE_NAME=${PROTO_FILE%.*}
- diff ${BASE_NAME}.pb.h ${BASE_NAME}.pb.h.tmp > /dev/null
+ diff ${BASE_NAME}.pb.h $TMP/${BASE_NAME}.pb.h > /dev/null
if test $? -ne 0; then
CORE_PROTO_IS_CORRECT=0
fi
- diff ${BASE_NAME}.pb.cc ${BASE_NAME}.pb.cc.tmp > /dev/null
+ diff ${BASE_NAME}.pb.cc $TMP/${BASE_NAME}.pb.cc > /dev/null
if test $? -ne 0; then
CORE_PROTO_IS_CORRECT=0
fi
done
- diff google/protobuf/compiler/plugin.pb.h google/protobuf/compiler/plugin.pb.h.tmp > /dev/null
+ diff google/protobuf/compiler/plugin.pb.h $TMP/google/protobuf/compiler/plugin.pb.h > /dev/null
if test $? -ne 0; then
CORE_PROTO_IS_CORRECT=0
fi
- diff google/protobuf/compiler/plugin.pb.cc google/protobuf/compiler/plugin.pb.cc.tmp > /dev/null
+ diff google/protobuf/compiler/plugin.pb.cc $TMP/google/protobuf/compiler/plugin.pb.cc > /dev/null
if test $? -ne 0; then
CORE_PROTO_IS_CORRECT=0
fi
- for PROTO_FILE in ${RUNTIME_PROTO_FILES[@]}; do
- BASE_NAME=${PROTO_FILE%.*}
- rm ${BASE_NAME}.pb.h.tmp
- rm ${BASE_NAME}.pb.cc.tmp
- done
- rm google/protobuf/compiler/plugin.pb.h.tmp
- rm google/protobuf/compiler/plugin.pb.cc.tmp
+ # Only override the output if the files are different to avoid re-compilation
+ # of the protoc.
+ if [ $CORE_PROTO_IS_CORRECT -ne 1 ]; then
+ for PROTO_FILE in ${RUNTIME_PROTO_FILES[@]}; do
+ BASE_NAME=${PROTO_FILE%.*}
+ mv $TMP/${BASE_NAME}.pb.h ${BASE_NAME}.pb.h
+ mv $TMP/${BASE_NAME}.pb.cc ${BASE_NAME}.pb.cc
+ done
+ mv $TMP/google/protobuf/compiler/plugin.pb.* google/protobuf/compiler/
+ fi
PROCESS_ROUND=$((PROCESS_ROUND + 1))
done
cd ..
-if test -x objectivec/generate_descriptors_proto.sh; then
+if test -x objectivec/generate_well_known_types.sh; then
echo "Generating messages for objc."
- objectivec/generate_descriptors_proto.sh $@
+ objectivec/generate_well_known_types.sh $@
+fi
+
+if test -x csharp/generate_protos.sh; then
+ echo "Generating messages for C#."
+ csharp/generate_protos.sh $@
fi
diff --git a/java/README.md b/java/README.md
index 060d9ac6..0e0fba64 100644
--- a/java/README.md
+++ b/java/README.md
@@ -17,9 +17,10 @@ rather build without Maven, see below.
http://maven.apache.org/
-2) Build the C++ code, or obtain a binary distribution of protoc. If
- you install a binary distribution, make sure that it is the same
- version as this package. If in doubt, run:
+2) Build the C++ code, or obtain a binary distribution of protoc (see
+ the toplevel [README.md](../README.md)). If you install a binary
+ distribution, make sure that it is the same version as this package.
+ If in doubt, run:
$ protoc --version
@@ -44,36 +45,25 @@ rather build without Maven, see below.
The .jar will be placed in the "target" directory.
-Installation - 'Lite' Version - With Maven
-==========================================
-
-Building the 'lite' version of the Java Protocol Buffers library is
-the same as building the full version, except that all commands are
-run using the 'lite' profile. (see
-http://maven.apache.org/guides/introduction/introduction-to-profiles.html)
-
-E.g. to install the lite version of the jar, you would run:
+The above instructions will install 3 maven artifacts:
- $ mvn install -P lite
-
-The resulting artifact has the 'lite' classifier. To reference it
-for dependency resolution, you would specify it as:
-
-```
- <dependency>
- <groupId>com.google.protobuf</groupId>
- <artifactId>protobuf-java</artifactId>
- <version>${version}</version>
- <classifier>lite</classifier>
- </dependency>
-```
+ * protobuf-java: The core Java Protocol Buffers library. Most users only
+ need this artifact.
+ * protobuf-lite: The lite version of core Java Protobuf Buffers library. It
+ is a subset of the core library and is used together with
+ the 'lite' code generator flag to reduce generated code size
+ for mobile.
+ * protobuf-java-util: Utilities to work with protos. It contains JSON support
+ as well as utilities to work with proto3 well-known
+ types.
Installation - Without Maven
============================
If you would rather not install Maven to build the library, you may
follow these instructions instead. Note that these instructions skip
-running unit tests.
+running unit tests and only describes how to install the core protobuf
+library (without the util package).
1) Build the C++ code, or obtain a binary distribution of protoc. If
you install a binary distribution, make sure that it is the same
@@ -86,15 +76,50 @@ running unit tests.
2) Invoke protoc to build DescriptorProtos.java:
- $ protoc --java_out=src/main/java -I../src \
+ $ protoc --java_out=core/src/main/java -I../src \
../src/google/protobuf/descriptor.proto
-3) Compile the code in src/main/java using whatever means you prefer.
+3) Compile the code in core/src/main/java using whatever means you prefer.
4) Install the classes wherever you prefer.
-Usage
-=====
+Compatibility Notice
+====================
+
+* Protobuf minor version releases are backwards-compatible. If your code
+ can build/run against the old version, it's expected to build/run against
+ the new version as well. Both binary compatibility and source compatibility
+ are guaranteed for minor version releases if the user follows the guideline
+ described in this section.
+
+* Protobuf major version releases may also be backwards-compatbile with the
+ last release of the previous major version. See the release notice for more
+ details.
+
+* APIs marked with the @ExperimentalApi annotation are subject to change. They
+ can be modified in any way, or even removed, at any time. Don't use them if
+ compatibility is needed. If your code is a library itself (i.e. it is used on
+ the CLASSPATH of users outside your own control), you should not use
+ experimental APIs, unless you repackage them (e.g. using ProGuard).
+
+* Deprecated non-experimental APIs will be removed two years after the release
+ in which they are first deprecated. You must fix your references before this
+ time. If you don't, any manner of breakage could result (you are not
+ guaranteed a compilation error).
+
+* Protobuf message interfaces/classes are designed to be subclassed by protobuf
+ generated code only. Do not subclass these message interfaces/classes
+ yourself. We may add new methods to the message interfaces/classes which will
+ break your own subclasses.
+
+* Don't use any method/class that is marked as "used by generated code only".
+ Such methods/classes are subject to change.
+
+* Protobuf LITE runtime APIs are not stable yet. They are subject to change even
+ in minor version releases.
+
+Documentation
+=============
The complete documentation for Protocol Buffers is available via the
web at:
diff --git a/java/compatibility_tests/README.md b/java/compatibility_tests/README.md
new file mode 100644
index 00000000..72c6034c
--- /dev/null
+++ b/java/compatibility_tests/README.md
@@ -0,0 +1,50 @@
+# Protobuf Java Compatibility Tests
+
+This directory contains tests to ensure protobuf library is compatible with
+previously released versions.
+
+## Directory Layout
+
+For each released protobuf version we are testing compatibility with, there
+is a sub-directory with the following layout (take v2.5.0 as an example):
+
+ * v2.5.0
+ * test.sh
+ * pom.xml
+ * protos/ - unittest protos.
+ * more_protos/ - unittest protos that import the ones in "protos".
+ * tests/ - actual Java test classes.
+
+The testing code is extracted from regular protobuf unittests by removing:
+
+ * tests that access package private methods/classes.
+ * tests that are known to be broken by an intended behavior change (e.g., we
+ changed the parsing recursion limit from 64 to 100).
+ * all lite runtime tests.
+
+It's also divided into 3 submodule with tests depending on more_protos and
+more_protos depending on protos. This way we can test scenarios where only part
+of the dependency is upgraded to the new version.
+
+## How to Run The Tests
+
+We use a shell script to drive the test of different scenarios so the test
+will only run on unix-like environments. The script expects a few command
+line tools to be available on PATH: git, mvn, wget, grep, sed, java.
+
+Before running the tests, make sure you have already built the protoc binary
+following [the C++ installation instructions](../../src/README.md). The test
+scripts will use the built binary located at ${protobuf}/src/protoc.
+
+To start a test, simply run the test.sh script in each version directory. For
+example:
+
+ $ v2.5.0/test.sh
+
+For each version, the test script will test:
+
+ * only upgrading protos to the new version
+ * only upgrading more_protos to the new version
+
+and see whether everything builds/runs fine. Both source compatibility and
+binary compatibility will be tested.
diff --git a/java/compatibility_tests/v2.5.0/deps/pom.xml b/java/compatibility_tests/v2.5.0/deps/pom.xml
new file mode 100644
index 00000000..7ceb9604
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/deps/pom.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>com.google.protobuf.compatibility</groupId>
+ <artifactId>compatibility-test-deps</artifactId>
+ <version>2.5.0</version>
+
+ <name>Compatibility Test Dependencies</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.4</version>
+ </dependency>
+ <dependency>
+ <groupId>org.easymock</groupId>
+ <artifactId>easymock</artifactId>
+ <version>2.2</version>
+ </dependency>
+ <dependency>
+ <groupId>org.easymock</groupId>
+ <artifactId>easymockclassextension</artifactId>
+ <version>2.2.1</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <version>2.6</version>
+ <configuration>
+ <descriptorRefs>
+ <descriptorRef>jar-with-dependencies</descriptorRef>
+ </descriptorRefs>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/java/compatibility_tests/v2.5.0/more_protos/pom.xml b/java/compatibility_tests/v2.5.0/more_protos/pom.xml
new file mode 100644
index 00000000..ff0c4133
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/more_protos/pom.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>com.google.protobuf.compatibility</groupId>
+ <artifactId>compatibility-test-suite</artifactId>
+ <version>2.5.0</version>
+ <relativePath>..</relativePath>
+ </parent>
+
+ <groupId>com.google.protobuf.compatibility</groupId>
+ <artifactId>compatibility-more-protos</artifactId>
+ <version>2.5.0</version>
+
+ <name>More protos for Compatibility test</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>com.google.protobuf</groupId>
+ <artifactId>protobuf-java</artifactId>
+ <version>${more_protos.protobuf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.google.protobuf.compatibility</groupId>
+ <artifactId>compatibility-protos</artifactId>
+ <version>2.5.0</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.3</version>
+ <configuration>
+ <source>1.6</source>
+ <target>1.6</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>generate-sources</id>
+ <phase>generate-sources</phase>
+ <configuration>
+ <tasks>
+ <mkdir dir="target/generated-sources" />
+ <exec executable="${more_protos.protoc.path}">
+ <arg value="--java_out=target/generated-sources" />
+ <arg value="--proto_path=src/proto" />
+ <arg value="src/proto/google/protobuf/unittest.proto" />
+ <arg value="src/proto/google/protobuf/unittest_optimize_for.proto" />
+ <arg value="src/proto/com/google/protobuf/multiple_files_test.proto" />
+ </exec>
+ </tasks>
+ <sourceRoot>target/generated-sources</sourceRoot>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/java/compatibility_tests/v2.5.0/more_protos/src/proto/com/google/protobuf/multiple_files_test.proto b/java/compatibility_tests/v2.5.0/more_protos/src/proto/com/google/protobuf/multiple_files_test.proto
new file mode 100644
index 00000000..9a040145
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/more_protos/src/proto/com/google/protobuf/multiple_files_test.proto
@@ -0,0 +1,71 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+// Author: kenton@google.com (Kenton Varda)
+//
+// A proto file which tests the java_multiple_files option.
+
+
+// Some generic_services option(s) added automatically.
+// See: http://go/proto2-generic-services-default
+option java_generic_services = true; // auto-added
+
+import "google/protobuf/unittest.proto";
+
+package protobuf_unittest;
+
+option java_multiple_files = true;
+option java_outer_classname = "MultipleFilesTestProto";
+
+message MessageWithNoOuter {
+ message NestedMessage {
+ optional int32 i = 1;
+ }
+ enum NestedEnum {
+ BAZ = 3;
+ }
+ optional NestedMessage nested = 1;
+ repeated TestAllTypes foreign = 2;
+ optional NestedEnum nested_enum = 3;
+ optional EnumWithNoOuter foreign_enum = 4;
+}
+
+enum EnumWithNoOuter {
+ FOO = 1;
+ BAR = 2;
+}
+
+service ServiceWithNoOuter {
+ rpc Foo(MessageWithNoOuter) returns(TestAllTypes);
+}
+
+extend TestAllExtensions {
+ optional int32 extension_with_outer = 1234567;
+}
diff --git a/java/compatibility_tests/v2.5.0/more_protos/src/proto/com/google/protobuf/nested_builders_test.proto b/java/compatibility_tests/v2.5.0/more_protos/src/proto/com/google/protobuf/nested_builders_test.proto
new file mode 100644
index 00000000..abffb9d2
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/more_protos/src/proto/com/google/protobuf/nested_builders_test.proto
@@ -0,0 +1,53 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+// Author: jonp@google.com (Jon Perlow)
+//
+
+package protobuf_unittest;
+
+option java_multiple_files = true;
+option java_outer_classname = "NestedBuilders";
+
+
+message Vehicle {
+ optional Engine engine = 1;
+ repeated Wheel wheel = 2;
+}
+
+message Engine {
+ optional int32 cylinder = 1;
+ optional int32 liters = 2;
+}
+
+message Wheel {
+ optional int32 radius = 1;
+ optional int32 width = 2;
+}
diff --git a/java/compatibility_tests/v2.5.0/more_protos/src/proto/com/google/protobuf/nested_extension.proto b/java/compatibility_tests/v2.5.0/more_protos/src/proto/com/google/protobuf/nested_extension.proto
new file mode 100644
index 00000000..9fe5d560
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/more_protos/src/proto/com/google/protobuf/nested_extension.proto
@@ -0,0 +1,45 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+// Author: Darick Tong (darick@google.com)
+//
+// A proto file with nested extensions. Note that this must be defined in
+// a separate file to properly test the initialization of the outer class.
+
+
+import "com/google/protobuf/non_nested_extension.proto";
+
+package protobuf_unittest;
+
+message MyNestedExtension {
+ extend MessageToBeExtended {
+ optional MessageToBeExtended recursiveExtension = 2;
+ }
+}
diff --git a/java/compatibility_tests/v2.5.0/more_protos/src/proto/com/google/protobuf/nested_extension_lite.proto b/java/compatibility_tests/v2.5.0/more_protos/src/proto/com/google/protobuf/nested_extension_lite.proto
new file mode 100644
index 00000000..16ee46e5
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/more_protos/src/proto/com/google/protobuf/nested_extension_lite.proto
@@ -0,0 +1,48 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+// Author: Darick Tong (darick@google.com)
+//
+// A proto file with nested extensions for a MessageLite messages. Note that
+// this must be defined in a separate file to properly test the initialization
+// of the outer class.
+
+
+package protobuf_unittest;
+
+option optimize_for = LITE_RUNTIME;
+
+import "com/google/protobuf/non_nested_extension_lite.proto";
+
+message MyNestedExtensionLite {
+ extend MessageLiteToBeExtended {
+ optional MessageLiteToBeExtended recursiveExtensionLite = 3;
+ }
+}
diff --git a/java/compatibility_tests/v2.5.0/more_protos/src/proto/com/google/protobuf/non_nested_extension.proto b/java/compatibility_tests/v2.5.0/more_protos/src/proto/com/google/protobuf/non_nested_extension.proto
new file mode 100644
index 00000000..f61b419b
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/more_protos/src/proto/com/google/protobuf/non_nested_extension.proto
@@ -0,0 +1,48 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+// Author: Darick Tong (darick@google.com)
+//
+// A proto file with extensions.
+
+
+package protobuf_unittest;
+
+message MessageToBeExtended {
+ extensions 1 to max;
+}
+
+message MyNonNestedExtension {
+}
+
+extend MessageToBeExtended {
+ optional MyNonNestedExtension nonNestedExtension = 1;
+}
+
diff --git a/java/compatibility_tests/v2.5.0/more_protos/src/proto/com/google/protobuf/non_nested_extension_lite.proto b/java/compatibility_tests/v2.5.0/more_protos/src/proto/com/google/protobuf/non_nested_extension_lite.proto
new file mode 100644
index 00000000..3c82659b
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/more_protos/src/proto/com/google/protobuf/non_nested_extension_lite.proto
@@ -0,0 +1,50 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+// Author: Darick Tong (darick@google.com)
+//
+// A proto file with extensions for a MessageLite messages.
+
+
+package protobuf_unittest;
+
+option optimize_for = LITE_RUNTIME;
+
+message MessageLiteToBeExtended {
+ extensions 1 to max;
+}
+
+message MyNonNestedExtensionLite {
+}
+
+extend MessageLiteToBeExtended {
+ optional MyNonNestedExtensionLite nonNestedExtensionLite = 1;
+}
+
diff --git a/java/compatibility_tests/v2.5.0/more_protos/src/proto/com/google/protobuf/test_bad_identifiers.proto b/java/compatibility_tests/v2.5.0/more_protos/src/proto/com/google/protobuf/test_bad_identifiers.proto
new file mode 100644
index 00000000..6e67d97a
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/more_protos/src/proto/com/google/protobuf/test_bad_identifiers.proto
@@ -0,0 +1,108 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+// Author: jonp@google.com (Jon Perlow)
+
+// This file tests that various identifiers work as field and type names even
+// though the same identifiers are used internally by the java code generator.
+
+
+// Some generic_services option(s) added automatically.
+// See: http://go/proto2-generic-services-default
+option java_generic_services = true; // auto-added
+
+package io_protocol_tests;
+
+option java_package = "com.google.protobuf";
+option java_outer_classname = "TestBadIdentifiersProto";
+
+message TestMessage {
+}
+
+message Descriptor {
+ option no_standard_descriptor_accessor = true;
+ optional string descriptor = 1;
+ message NestedDescriptor {
+ option no_standard_descriptor_accessor = true;
+ optional string descriptor = 1;
+ }
+ optional NestedDescriptor nested_descriptor = 2;
+}
+
+message Parser {
+ enum ParserEnum {
+ PARSER = 1;
+ }
+ optional ParserEnum parser = 1;
+}
+
+message Deprecated {
+ enum TestEnum {
+ FOO = 1;
+ }
+
+ optional int32 field1 = 1 [deprecated=true];
+ optional TestEnum field2 = 2 [deprecated=true];
+ optional TestMessage field3 = 3 [deprecated=true];
+}
+
+message Override {
+ optional int32 override = 1;
+}
+
+message Object {
+ optional int32 object = 1;
+ optional string string_object = 2;
+}
+
+message String {
+ optional string string = 1;
+}
+
+message Integer {
+ optional int32 integer = 1;
+}
+
+message Long {
+ optional int32 long = 1;
+}
+
+message Float {
+ optional float float = 1;
+}
+
+message Double {
+ optional double double = 1;
+}
+
+service TestConflictingMethodNames {
+ rpc Override(TestMessage) returns (TestMessage);
+}
+
diff --git a/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/descriptor.proto b/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/descriptor.proto
new file mode 100644
index 00000000..a785f79f
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/descriptor.proto
@@ -0,0 +1,620 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// The messages in this file describe the definitions found in .proto files.
+// A valid .proto file can be translated directly to a FileDescriptorProto
+// without any other information (e.g. without reading its imports).
+
+
+
+package google.protobuf;
+option java_package = "com.google.protobuf";
+option java_outer_classname = "DescriptorProtos";
+
+// descriptor.proto must be optimized for speed because reflection-based
+// algorithms don't work during bootstrapping.
+option optimize_for = SPEED;
+
+// The protocol compiler can output a FileDescriptorSet containing the .proto
+// files it parses.
+message FileDescriptorSet {
+ repeated FileDescriptorProto file = 1;
+}
+
+// Describes a complete .proto file.
+message FileDescriptorProto {
+ optional string name = 1; // file name, relative to root of source tree
+ optional string package = 2; // e.g. "foo", "foo.bar", etc.
+
+ // Names of files imported by this file.
+ repeated string dependency = 3;
+ // Indexes of the public imported files in the dependency list above.
+ repeated int32 public_dependency = 10;
+ // Indexes of the weak imported files in the dependency list.
+ // For Google-internal migration only. Do not use.
+ repeated int32 weak_dependency = 11;
+
+ // All top-level definitions in this file.
+ repeated DescriptorProto message_type = 4;
+ repeated EnumDescriptorProto enum_type = 5;
+ repeated ServiceDescriptorProto service = 6;
+ repeated FieldDescriptorProto extension = 7;
+
+ optional FileOptions options = 8;
+
+ // This field contains optional information about the original source code.
+ // You may safely remove this entire field whithout harming runtime
+ // functionality of the descriptors -- the information is needed only by
+ // development tools.
+ optional SourceCodeInfo source_code_info = 9;
+}
+
+// Describes a message type.
+message DescriptorProto {
+ optional string name = 1;
+
+ repeated FieldDescriptorProto field = 2;
+ repeated FieldDescriptorProto extension = 6;
+
+ repeated DescriptorProto nested_type = 3;
+ repeated EnumDescriptorProto enum_type = 4;
+
+ message ExtensionRange {
+ optional int32 start = 1;
+ optional int32 end = 2;
+ }
+ repeated ExtensionRange extension_range = 5;
+
+ optional MessageOptions options = 7;
+}
+
+// Describes a field within a message.
+message FieldDescriptorProto {
+ enum Type {
+ // 0 is reserved for errors.
+ // Order is weird for historical reasons.
+ TYPE_DOUBLE = 1;
+ TYPE_FLOAT = 2;
+ // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT64 if
+ // negative values are likely.
+ TYPE_INT64 = 3;
+ TYPE_UINT64 = 4;
+ // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT32 if
+ // negative values are likely.
+ TYPE_INT32 = 5;
+ TYPE_FIXED64 = 6;
+ TYPE_FIXED32 = 7;
+ TYPE_BOOL = 8;
+ TYPE_STRING = 9;
+ TYPE_GROUP = 10; // Tag-delimited aggregate.
+ TYPE_MESSAGE = 11; // Length-delimited aggregate.
+
+ // New in version 2.
+ TYPE_BYTES = 12;
+ TYPE_UINT32 = 13;
+ TYPE_ENUM = 14;
+ TYPE_SFIXED32 = 15;
+ TYPE_SFIXED64 = 16;
+ TYPE_SINT32 = 17; // Uses ZigZag encoding.
+ TYPE_SINT64 = 18; // Uses ZigZag encoding.
+ };
+
+ enum Label {
+ // 0 is reserved for errors
+ LABEL_OPTIONAL = 1;
+ LABEL_REQUIRED = 2;
+ LABEL_REPEATED = 3;
+ // TODO(sanjay): Should we add LABEL_MAP?
+ };
+
+ optional string name = 1;
+ optional int32 number = 3;
+ optional Label label = 4;
+
+ // If type_name is set, this need not be set. If both this and type_name
+ // are set, this must be either TYPE_ENUM or TYPE_MESSAGE.
+ optional Type type = 5;
+
+ // 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
+ // rules are used to find the type (i.e. first the nested types within this
+ // message are searched, then within the parent, on up to the root
+ // namespace).
+ optional string type_name = 6;
+
+ // For extensions, this is the name of the type being extended. It is
+ // resolved in the same manner as type_name.
+ optional string extendee = 2;
+
+ // For numeric types, contains the original text representation of the value.
+ // For booleans, "true" or "false".
+ // For strings, contains the default text contents (not escaped in any way).
+ // For bytes, contains the C escaped value. All bytes >= 128 are escaped.
+ // TODO(kenton): Base-64 encode?
+ optional string default_value = 7;
+
+ optional FieldOptions options = 8;
+}
+
+// Describes an enum type.
+message EnumDescriptorProto {
+ optional string name = 1;
+
+ repeated EnumValueDescriptorProto value = 2;
+
+ optional EnumOptions options = 3;
+}
+
+// Describes a value within an enum.
+message EnumValueDescriptorProto {
+ optional string name = 1;
+ optional int32 number = 2;
+
+ optional EnumValueOptions options = 3;
+}
+
+// Describes a service.
+message ServiceDescriptorProto {
+ optional string name = 1;
+ repeated MethodDescriptorProto method = 2;
+
+ optional ServiceOptions options = 3;
+}
+
+// Describes a method of a service.
+message MethodDescriptorProto {
+ optional string name = 1;
+
+ // Input and output type names. These are resolved in the same way as
+ // FieldDescriptorProto.type_name, but must refer to a message type.
+ optional string input_type = 2;
+ optional string output_type = 3;
+
+ optional MethodOptions options = 4;
+}
+
+
+// ===================================================================
+// Options
+
+// Each of the definitions above may have "options" attached. These are
+// just annotations which may cause code to be generated slightly differently
+// or may contain hints for code that manipulates protocol messages.
+//
+// Clients may define custom options as extensions of the *Options messages.
+// These extensions may not yet be known at parsing time, so the parser cannot
+// store the values in them. Instead it stores them in a field in the *Options
+// message called uninterpreted_option. This field must have the same name
+// across all *Options messages. We then use this field to populate the
+// extensions when we build a descriptor, at which point all protos have been
+// parsed and so all extensions are known.
+//
+// Extension numbers for custom options may be chosen as follows:
+// * For options which will only be used within a single application or
+// organization, or for experimental options, use field numbers 50000
+// through 99999. It is up to you to ensure that you do not use the
+// same number for multiple options.
+// * For options which will be published and used publicly by multiple
+// independent entities, e-mail protobuf-global-extension-registry@google.com
+// to reserve extension numbers. Simply provide your project name (e.g.
+// Object-C plugin) and your porject website (if available) -- there's no need
+// to explain how you intend to use them. Usually you only need one extension
+// number. You can declare multiple options with only one extension number by
+// putting them in a sub-message. See the Custom Options section of the docs
+// for examples:
+// http://code.google.com/apis/protocolbuffers/docs/proto.html#options
+// If this turns out to be popular, a web service will be set up
+// to automatically assign option numbers.
+
+
+message FileOptions {
+
+ // Sets the Java package where classes generated from this .proto will be
+ // placed. By default, the proto package is used, but this is often
+ // inappropriate because proto packages do not normally start with backwards
+ // domain names.
+ optional string java_package = 1;
+
+
+ // 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
+ // (equivalent to the old "--one_java_file" option) and Proto2 (where
+ // a .proto always translates to a single class, but you may want to
+ // explicitly choose the class name).
+ optional string java_outer_classname = 8;
+
+ // 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
+ // file. Thus, these types will *not* be nested inside the outer class
+ // named by java_outer_classname. However, the outer class will still be
+ // generated to contain the file's getDescriptor() method as well as any
+ // top-level extensions defined in the file.
+ optional bool java_multiple_files = 10 [default=false];
+
+ // If set true, then the Java code generator will generate equals() and
+ // hashCode() methods for all messages defined in the .proto file. This is
+ // purely a speed optimization, as the AbstractMessage base class includes
+ // reflection-based implementations of these methods.
+ optional bool java_generate_equals_and_hash = 20 [default=false];
+
+ // Generated classes can be optimized for speed or code size.
+ enum OptimizeMode {
+ SPEED = 1; // Generate complete code for parsing, serialization,
+ // etc.
+ CODE_SIZE = 2; // Use ReflectionOps to implement these methods.
+ LITE_RUNTIME = 3; // Generate code using MessageLite and the lite runtime.
+ }
+ optional OptimizeMode optimize_for = 9 [default=SPEED];
+
+ // Sets the Go package where structs generated from this .proto will be
+ // placed. There is no default.
+ optional string go_package = 11;
+
+
+
+ // Should generic services be generated in each language? "Generic" services
+ // are not specific to any particular RPC system. They are generated by the
+ // main code generators in each language (without additional plugins).
+ // Generic services were the only kind of service generation supported by
+ // early versions of proto2.
+ //
+ // Generic services are now considered deprecated in favor of using plugins
+ // that generate code specific to your particular RPC system. Therefore,
+ // these default to false. Old code which depends on generic services should
+ // explicitly set them to true.
+ optional bool cc_generic_services = 16 [default=false];
+ optional bool java_generic_services = 17 [default=false];
+ optional bool py_generic_services = 18 [default=false];
+
+ // The parser stores options it doesn't recognize here. See above.
+ repeated UninterpretedOption uninterpreted_option = 999;
+
+ // Clients can define custom options in extensions of this message. See above.
+ extensions 1000 to max;
+}
+
+message MessageOptions {
+ // Set true to use the old proto1 MessageSet wire format for extensions.
+ // This is provided for backwards-compatibility with the MessageSet wire
+ // format. You should not use this for any other reason: It's less
+ // efficient, has fewer features, and is more complicated.
+ //
+ // The message must be defined exactly as follows:
+ // message Foo {
+ // option message_set_wire_format = true;
+ // extensions 4 to max;
+ // }
+ // Note that the message cannot have any defined fields; MessageSets only
+ // have extensions.
+ //
+ // All extensions of your type must be singular messages; e.g. they cannot
+ // be int32s, enums, or repeated messages.
+ //
+ // Because this is an option, the above two restrictions are not enforced by
+ // the protocol compiler.
+ optional bool message_set_wire_format = 1 [default=false];
+
+ // Disables the generation of the standard "descriptor()" accessor, which can
+ // conflict with a field of the same name. This is meant to make migration
+ // from proto1 easier; new code should avoid fields named "descriptor".
+ optional bool no_standard_descriptor_accessor = 2 [default=false];
+
+ // The parser stores options it doesn't recognize here. See above.
+ repeated UninterpretedOption uninterpreted_option = 999;
+
+ // Clients can define custom options in extensions of this message. See above.
+ extensions 1000 to max;
+}
+
+message FieldOptions {
+ // The ctype option instructs the C++ code generator to use a different
+ // representation of the field than it normally would. See the specific
+ // options below. This option is not yet implemented in the open source
+ // release -- sorry, we'll try to include it in a future version!
+ optional CType ctype = 1 [default = STRING];
+ enum CType {
+ // Default mode.
+ STRING = 0;
+
+ CORD = 1;
+
+ STRING_PIECE = 2;
+ }
+ // The packed option can be enabled for repeated primitive fields to enable
+ // a more efficient representation on the wire. Rather than repeatedly
+ // writing the tag and type for each element, the entire array is encoded as
+ // a single length-delimited blob.
+ optional bool packed = 2;
+
+
+
+ // Should this field be parsed lazily? Lazy applies only to message-type
+ // fields. It means that when the outer message is initially parsed, the
+ // inner message's contents will not be parsed but instead stored in encoded
+ // form. The inner message will actually be parsed when it is first accessed.
+ //
+ // This is only a hint. Implementations are free to choose whether to use
+ // eager or lazy parsing regardless of the value of this option. However,
+ // setting this option true suggests that the protocol author believes that
+ // using lazy parsing on this field is worth the additional bookkeeping
+ // overhead typically needed to implement it.
+ //
+ // This option does not affect the public interface of any generated code;
+ // all method signatures remain the same. Furthermore, thread-safety of the
+ // interface is not affected by this option; const methods remain safe to
+ // call from multiple threads concurrently, while non-const methods continue
+ // to require exclusive access.
+ //
+ //
+ // Note that implementations may choose not to check required fields within
+ // a lazy sub-message. That is, calling IsInitialized() on the outher message
+ // may return true even if the inner message has missing required fields.
+ // This is necessary because otherwise the inner message would have to be
+ // parsed in order to perform the check, defeating the purpose of lazy
+ // parsing. An implementation which chooses not to check required fields
+ // must be consistent about it. That is, for any particular sub-message, the
+ // implementation must either *always* check its required fields, or *never*
+ // check its required fields, regardless of whether or not the message has
+ // been parsed.
+ optional bool lazy = 5 [default=false];
+
+ // Is this field deprecated?
+ // Depending on the target platform, this can emit Deprecated annotations
+ // for accessors, or it will be completely ignored; in the very least, this
+ // is a formalization for deprecating fields.
+ optional bool deprecated = 3 [default=false];
+
+ // EXPERIMENTAL. DO NOT USE.
+ // For "map" fields, the name of the field in the enclosed type that
+ // is the key for this map. For example, suppose we have:
+ // message Item {
+ // required string name = 1;
+ // required string value = 2;
+ // }
+ // message Config {
+ // repeated Item items = 1 [experimental_map_key="name"];
+ // }
+ // In this situation, the map key for Item will be set to "name".
+ // TODO: Fully-implement this, then remove the "experimental_" prefix.
+ optional string experimental_map_key = 9;
+
+ // For Google-internal migration only. Do not use.
+ optional bool weak = 10 [default=false];
+
+ // The parser stores options it doesn't recognize here. See above.
+ repeated UninterpretedOption uninterpreted_option = 999;
+
+ // Clients can define custom options in extensions of this message. See above.
+ extensions 1000 to max;
+}
+
+message EnumOptions {
+
+ // Set this option to false to disallow mapping different tag names to a same
+ // value.
+ optional bool allow_alias = 2 [default=true];
+
+ // The parser stores options it doesn't recognize here. See above.
+ repeated UninterpretedOption uninterpreted_option = 999;
+
+ // Clients can define custom options in extensions of this message. See above.
+ extensions 1000 to max;
+}
+
+message EnumValueOptions {
+ // The parser stores options it doesn't recognize here. See above.
+ repeated UninterpretedOption uninterpreted_option = 999;
+
+ // Clients can define custom options in extensions of this message. See above.
+ extensions 1000 to max;
+}
+
+message ServiceOptions {
+
+ // Note: Field numbers 1 through 32 are reserved for Google's internal RPC
+ // framework. We apologize for hoarding these numbers to ourselves, but
+ // we were already using them long before we decided to release Protocol
+ // Buffers.
+
+ // The parser stores options it doesn't recognize here. See above.
+ repeated UninterpretedOption uninterpreted_option = 999;
+
+ // Clients can define custom options in extensions of this message. See above.
+ extensions 1000 to max;
+}
+
+message MethodOptions {
+
+ // Note: Field numbers 1 through 32 are reserved for Google's internal RPC
+ // framework. We apologize for hoarding these numbers to ourselves, but
+ // we were already using them long before we decided to release Protocol
+ // Buffers.
+
+ // The parser stores options it doesn't recognize here. See above.
+ repeated UninterpretedOption uninterpreted_option = 999;
+
+ // Clients can define custom options in extensions of this message. See above.
+ extensions 1000 to max;
+}
+
+
+// A message representing a option the parser does not recognize. This only
+// appears in options protos created by the compiler::Parser class.
+// DescriptorPool resolves these when building Descriptor objects. Therefore,
+// options protos in descriptor objects (e.g. returned by Descriptor::options(),
+// or produced by Descriptor::CopyTo()) will never have UninterpretedOptions
+// in them.
+message UninterpretedOption {
+ // The name of the uninterpreted option. Each string represents a segment in
+ // a dot-separated name. is_extension is true iff a segment represents an
+ // extension (denoted with parentheses in options specs in .proto files).
+ // E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents
+ // "foo.(bar.baz).qux".
+ message NamePart {
+ required string name_part = 1;
+ required bool is_extension = 2;
+ }
+ repeated NamePart name = 2;
+
+ // The value of the uninterpreted option, in whatever type the tokenizer
+ // identified it as during parsing. Exactly one of these should be set.
+ optional string identifier_value = 3;
+ optional uint64 positive_int_value = 4;
+ optional int64 negative_int_value = 5;
+ optional double double_value = 6;
+ optional bytes string_value = 7;
+ optional string aggregate_value = 8;
+}
+
+// ===================================================================
+// Optional source code info
+
+// Encapsulates information about the original source file from which a
+// FileDescriptorProto was generated.
+message SourceCodeInfo {
+ // A Location identifies a piece of source code in a .proto file which
+ // corresponds to a particular definition. This information is intended
+ // to be useful to IDEs, code indexers, documentation generators, and similar
+ // tools.
+ //
+ // For example, say we have a file like:
+ // message Foo {
+ // optional string foo = 1;
+ // }
+ // Let's look at just the field definition:
+ // optional string foo = 1;
+ // ^ ^^ ^^ ^ ^^^
+ // a bc de f ghi
+ // We have the following locations:
+ // span path represents
+ // [a,i) [ 4, 0, 2, 0 ] The whole field definition.
+ // [a,b) [ 4, 0, 2, 0, 4 ] The label (optional).
+ // [c,d) [ 4, 0, 2, 0, 5 ] The type (string).
+ // [e,f) [ 4, 0, 2, 0, 1 ] The name (foo).
+ // [g,h) [ 4, 0, 2, 0, 3 ] The number (1).
+ //
+ // Notes:
+ // - A location may refer to a repeated field itself (i.e. not to any
+ // particular index within it). This is used whenever a set of elements are
+ // logically enclosed in a single code segment. For example, an entire
+ // extend block (possibly containing multiple extension definitions) will
+ // have an outer location whose path refers to the "extensions" repeated
+ // field without an index.
+ // - Multiple locations may have the same path. This happens when a single
+ // logical declaration is spread out across multiple places. The most
+ // obvious example is the "extend" block again -- there may be multiple
+ // extend blocks in the same scope, each of which will have the same path.
+ // - A location's span is not always a subset of its parent's span. For
+ // example, the "extendee" of an extension declaration appears at the
+ // beginning of the "extend" block and is shared by all extensions within
+ // the block.
+ // - Just because a location's span is a subset of some other location's span
+ // does not mean that it is a descendent. For example, a "group" defines
+ // both a type and a field in a single declaration. Thus, the locations
+ // corresponding to the type and field and their components will overlap.
+ // - Code which tries to interpret locations should probably be designed to
+ // ignore those that it doesn't understand, as more types of locations could
+ // be recorded in the future.
+ repeated Location location = 1;
+ message Location {
+ // Identifies which part of the FileDescriptorProto was defined at this
+ // location.
+ //
+ // Each element is a field number or an index. They form a path from
+ // the root FileDescriptorProto to the place where the definition. For
+ // example, this path:
+ // [ 4, 3, 2, 7, 1 ]
+ // refers to:
+ // file.message_type(3) // 4, 3
+ // .field(7) // 2, 7
+ // .name() // 1
+ // This is because FileDescriptorProto.message_type has field number 4:
+ // repeated DescriptorProto message_type = 4;
+ // and DescriptorProto.field has field number 2:
+ // repeated FieldDescriptorProto field = 2;
+ // and FieldDescriptorProto.name has field number 1:
+ // optional string name = 1;
+ //
+ // Thus, the above path gives the location of a field name. If we removed
+ // the last element:
+ // [ 4, 3, 2, 7 ]
+ // this path refers to the whole field declaration (from the beginning
+ // of the label to the terminating semicolon).
+ repeated int32 path = 1 [packed=true];
+
+ // Always has exactly three or four elements: start line, start column,
+ // end line (optional, otherwise assumed same as start line), end column.
+ // These are packed into a single field for efficiency. Note that line
+ // and column numbers are zero-based -- typically you will want to add
+ // 1 to each before displaying to a user.
+ repeated int32 span = 2 [packed=true];
+
+ // If this SourceCodeInfo represents a complete declaration, these are any
+ // comments appearing before and after the declaration which appear to be
+ // attached to the declaration.
+ //
+ // A series of line comments appearing on consecutive lines, with no other
+ // tokens appearing on those lines, will be treated as a single comment.
+ //
+ // Only the comment content is provided; comment markers (e.g. //) are
+ // stripped out. For block comments, leading whitespace and an asterisk
+ // will be stripped from the beginning of each line other than the first.
+ // Newlines are included in the output.
+ //
+ // Examples:
+ //
+ // optional int32 foo = 1; // Comment attached to foo.
+ // // Comment attached to bar.
+ // optional int32 bar = 2;
+ //
+ // optional string baz = 3;
+ // // Comment attached to baz.
+ // // Another line attached to baz.
+ //
+ // // Comment attached to qux.
+ // //
+ // // Another line attached to qux.
+ // optional double qux = 4;
+ //
+ // optional string corge = 5;
+ // /* Block comment attached
+ // * to corge. Leading asterisks
+ // * will be removed. */
+ // /* Block comment attached to
+ // * grault. */
+ // optional int32 grault = 6;
+ optional string leading_comments = 3;
+ optional string trailing_comments = 4;
+ }
+}
diff --git a/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest.proto b/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest.proto
new file mode 100644
index 00000000..6eb2d86f
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest.proto
@@ -0,0 +1,719 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// A proto file we will use for unit testing.
+
+
+// Some generic_services option(s) added automatically.
+// See: http://go/proto2-generic-services-default
+option cc_generic_services = true; // auto-added
+option java_generic_services = true; // auto-added
+option py_generic_services = true; // auto-added
+
+import "google/protobuf/unittest_import.proto";
+
+// We don't put this in a package within proto2 because we need to make sure
+// that the generated code doesn't depend on being in the proto2 namespace.
+// In test_util.h we do "using namespace unittest = protobuf_unittest".
+package protobuf_unittest;
+
+// Protos optimized for SPEED use a strict superset of the generated code
+// of equivalent ones optimized for CODE_SIZE, so we should optimize all our
+// tests for speed unless explicitly testing code size optimization.
+option optimize_for = SPEED;
+
+option java_outer_classname = "UnittestProto";
+
+// This proto includes every type of field in both singular and repeated
+// forms.
+message TestAllTypes {
+ message NestedMessage {
+ // The field name "b" fails to compile in proto1 because it conflicts with
+ // a local variable named "b" in one of the generated methods. Doh.
+ // This file needs to compile in proto1 to test backwards-compatibility.
+ optional int32 bb = 1;
+ }
+
+ enum NestedEnum {
+ FOO = 1;
+ BAR = 2;
+ BAZ = 3;
+ }
+
+ // Singular
+ optional int32 optional_int32 = 1;
+ optional int64 optional_int64 = 2;
+ optional uint32 optional_uint32 = 3;
+ optional uint64 optional_uint64 = 4;
+ optional sint32 optional_sint32 = 5;
+ optional sint64 optional_sint64 = 6;
+ optional fixed32 optional_fixed32 = 7;
+ optional fixed64 optional_fixed64 = 8;
+ optional sfixed32 optional_sfixed32 = 9;
+ optional sfixed64 optional_sfixed64 = 10;
+ optional float optional_float = 11;
+ optional double optional_double = 12;
+ optional bool optional_bool = 13;
+ optional string optional_string = 14;
+ optional bytes optional_bytes = 15;
+
+ optional group OptionalGroup = 16 {
+ optional int32 a = 17;
+ }
+
+ optional NestedMessage optional_nested_message = 18;
+ optional ForeignMessage optional_foreign_message = 19;
+ optional protobuf_unittest_import.ImportMessage optional_import_message = 20;
+
+ optional NestedEnum optional_nested_enum = 21;
+ optional ForeignEnum optional_foreign_enum = 22;
+ optional protobuf_unittest_import.ImportEnum optional_import_enum = 23;
+
+ optional string optional_string_piece = 24 [ctype=STRING_PIECE];
+ optional string optional_cord = 25 [ctype=CORD];
+
+ // Defined in unittest_import_public.proto
+ optional protobuf_unittest_import.PublicImportMessage
+ optional_public_import_message = 26;
+
+ optional NestedMessage optional_lazy_message = 27 [lazy=true];
+
+ // Repeated
+ repeated int32 repeated_int32 = 31;
+ repeated int64 repeated_int64 = 32;
+ repeated uint32 repeated_uint32 = 33;
+ repeated uint64 repeated_uint64 = 34;
+ repeated sint32 repeated_sint32 = 35;
+ repeated sint64 repeated_sint64 = 36;
+ repeated fixed32 repeated_fixed32 = 37;
+ repeated fixed64 repeated_fixed64 = 38;
+ repeated sfixed32 repeated_sfixed32 = 39;
+ repeated sfixed64 repeated_sfixed64 = 40;
+ repeated float repeated_float = 41;
+ repeated double repeated_double = 42;
+ repeated bool repeated_bool = 43;
+ repeated string repeated_string = 44;
+ repeated bytes repeated_bytes = 45;
+
+ repeated group RepeatedGroup = 46 {
+ optional int32 a = 47;
+ }
+
+ repeated NestedMessage repeated_nested_message = 48;
+ repeated ForeignMessage repeated_foreign_message = 49;
+ repeated protobuf_unittest_import.ImportMessage repeated_import_message = 50;
+
+ repeated NestedEnum repeated_nested_enum = 51;
+ repeated ForeignEnum repeated_foreign_enum = 52;
+ repeated protobuf_unittest_import.ImportEnum repeated_import_enum = 53;
+
+ repeated string repeated_string_piece = 54 [ctype=STRING_PIECE];
+ repeated string repeated_cord = 55 [ctype=CORD];
+
+ repeated NestedMessage repeated_lazy_message = 57 [lazy=true];
+
+ // Singular with defaults
+ optional int32 default_int32 = 61 [default = 41 ];
+ optional int64 default_int64 = 62 [default = 42 ];
+ optional uint32 default_uint32 = 63 [default = 43 ];
+ optional uint64 default_uint64 = 64 [default = 44 ];
+ optional sint32 default_sint32 = 65 [default = -45 ];
+ optional sint64 default_sint64 = 66 [default = 46 ];
+ optional fixed32 default_fixed32 = 67 [default = 47 ];
+ optional fixed64 default_fixed64 = 68 [default = 48 ];
+ optional sfixed32 default_sfixed32 = 69 [default = 49 ];
+ optional sfixed64 default_sfixed64 = 70 [default = -50 ];
+ optional float default_float = 71 [default = 51.5 ];
+ optional double default_double = 72 [default = 52e3 ];
+ optional bool default_bool = 73 [default = true ];
+ optional string default_string = 74 [default = "hello"];
+ optional bytes default_bytes = 75 [default = "world"];
+
+ optional NestedEnum default_nested_enum = 81 [default = BAR ];
+ optional ForeignEnum default_foreign_enum = 82 [default = FOREIGN_BAR];
+ optional protobuf_unittest_import.ImportEnum
+ default_import_enum = 83 [default = IMPORT_BAR];
+
+ optional string default_string_piece = 84 [ctype=STRING_PIECE,default="abc"];
+ optional string default_cord = 85 [ctype=CORD,default="123"];
+}
+
+message TestDeprecatedFields {
+ optional int32 deprecated_int32 = 1 [deprecated=true];
+}
+
+// Define these after TestAllTypes to make sure the compiler can handle
+// that.
+message ForeignMessage {
+ optional int32 c = 1;
+}
+
+enum ForeignEnum {
+ FOREIGN_FOO = 4;
+ FOREIGN_BAR = 5;
+ FOREIGN_BAZ = 6;
+}
+
+message TestAllExtensions {
+ extensions 1 to max;
+}
+
+extend TestAllExtensions {
+ // Singular
+ optional int32 optional_int32_extension = 1;
+ optional int64 optional_int64_extension = 2;
+ optional uint32 optional_uint32_extension = 3;
+ optional uint64 optional_uint64_extension = 4;
+ optional sint32 optional_sint32_extension = 5;
+ optional sint64 optional_sint64_extension = 6;
+ optional fixed32 optional_fixed32_extension = 7;
+ optional fixed64 optional_fixed64_extension = 8;
+ optional sfixed32 optional_sfixed32_extension = 9;
+ optional sfixed64 optional_sfixed64_extension = 10;
+ optional float optional_float_extension = 11;
+ optional double optional_double_extension = 12;
+ optional bool optional_bool_extension = 13;
+ optional string optional_string_extension = 14;
+ optional bytes optional_bytes_extension = 15;
+
+ optional group OptionalGroup_extension = 16 {
+ optional int32 a = 17;
+ }
+
+ optional TestAllTypes.NestedMessage optional_nested_message_extension = 18;
+ optional ForeignMessage optional_foreign_message_extension = 19;
+ optional protobuf_unittest_import.ImportMessage
+ optional_import_message_extension = 20;
+
+ optional TestAllTypes.NestedEnum optional_nested_enum_extension = 21;
+ optional ForeignEnum optional_foreign_enum_extension = 22;
+ optional protobuf_unittest_import.ImportEnum
+ optional_import_enum_extension = 23;
+
+ optional string optional_string_piece_extension = 24 [ctype=STRING_PIECE];
+ optional string optional_cord_extension = 25 [ctype=CORD];
+
+ optional protobuf_unittest_import.PublicImportMessage
+ optional_public_import_message_extension = 26;
+
+ optional TestAllTypes.NestedMessage
+ optional_lazy_message_extension = 27 [lazy=true];
+
+ // Repeated
+ repeated int32 repeated_int32_extension = 31;
+ repeated int64 repeated_int64_extension = 32;
+ repeated uint32 repeated_uint32_extension = 33;
+ repeated uint64 repeated_uint64_extension = 34;
+ repeated sint32 repeated_sint32_extension = 35;
+ repeated sint64 repeated_sint64_extension = 36;
+ repeated fixed32 repeated_fixed32_extension = 37;
+ repeated fixed64 repeated_fixed64_extension = 38;
+ repeated sfixed32 repeated_sfixed32_extension = 39;
+ repeated sfixed64 repeated_sfixed64_extension = 40;
+ repeated float repeated_float_extension = 41;
+ repeated double repeated_double_extension = 42;
+ repeated bool repeated_bool_extension = 43;
+ repeated string repeated_string_extension = 44;
+ repeated bytes repeated_bytes_extension = 45;
+
+ repeated group RepeatedGroup_extension = 46 {
+ optional int32 a = 47;
+ }
+
+ repeated TestAllTypes.NestedMessage repeated_nested_message_extension = 48;
+ repeated ForeignMessage repeated_foreign_message_extension = 49;
+ repeated protobuf_unittest_import.ImportMessage
+ repeated_import_message_extension = 50;
+
+ repeated TestAllTypes.NestedEnum repeated_nested_enum_extension = 51;
+ repeated ForeignEnum repeated_foreign_enum_extension = 52;
+ repeated protobuf_unittest_import.ImportEnum
+ repeated_import_enum_extension = 53;
+
+ repeated string repeated_string_piece_extension = 54 [ctype=STRING_PIECE];
+ repeated string repeated_cord_extension = 55 [ctype=CORD];
+
+ repeated TestAllTypes.NestedMessage
+ repeated_lazy_message_extension = 57 [lazy=true];
+
+ // Singular with defaults
+ optional int32 default_int32_extension = 61 [default = 41 ];
+ optional int64 default_int64_extension = 62 [default = 42 ];
+ optional uint32 default_uint32_extension = 63 [default = 43 ];
+ optional uint64 default_uint64_extension = 64 [default = 44 ];
+ optional sint32 default_sint32_extension = 65 [default = -45 ];
+ optional sint64 default_sint64_extension = 66 [default = 46 ];
+ optional fixed32 default_fixed32_extension = 67 [default = 47 ];
+ optional fixed64 default_fixed64_extension = 68 [default = 48 ];
+ optional sfixed32 default_sfixed32_extension = 69 [default = 49 ];
+ optional sfixed64 default_sfixed64_extension = 70 [default = -50 ];
+ optional float default_float_extension = 71 [default = 51.5 ];
+ optional double default_double_extension = 72 [default = 52e3 ];
+ optional bool default_bool_extension = 73 [default = true ];
+ optional string default_string_extension = 74 [default = "hello"];
+ optional bytes default_bytes_extension = 75 [default = "world"];
+
+ optional TestAllTypes.NestedEnum
+ default_nested_enum_extension = 81 [default = BAR];
+ optional ForeignEnum
+ default_foreign_enum_extension = 82 [default = FOREIGN_BAR];
+ optional protobuf_unittest_import.ImportEnum
+ default_import_enum_extension = 83 [default = IMPORT_BAR];
+
+ optional string default_string_piece_extension = 84 [ctype=STRING_PIECE,
+ default="abc"];
+ optional string default_cord_extension = 85 [ctype=CORD, default="123"];
+}
+
+message TestNestedExtension {
+ extend TestAllExtensions {
+ // Check for bug where string extensions declared in tested scope did not
+ // compile.
+ optional string test = 1002 [default="test"];
+ }
+}
+
+// We have separate messages for testing required fields because it's
+// annoying to have to fill in required fields in TestProto in order to
+// do anything with it. Note that we don't need to test every type of
+// required filed because the code output is basically identical to
+// optional fields for all types.
+message TestRequired {
+ required int32 a = 1;
+ optional int32 dummy2 = 2;
+ required int32 b = 3;
+
+ extend TestAllExtensions {
+ optional TestRequired single = 1000;
+ repeated TestRequired multi = 1001;
+ }
+
+ // Pad the field count to 32 so that we can test that IsInitialized()
+ // properly checks multiple elements of has_bits_.
+ optional int32 dummy4 = 4;
+ optional int32 dummy5 = 5;
+ optional int32 dummy6 = 6;
+ optional int32 dummy7 = 7;
+ optional int32 dummy8 = 8;
+ optional int32 dummy9 = 9;
+ optional int32 dummy10 = 10;
+ optional int32 dummy11 = 11;
+ optional int32 dummy12 = 12;
+ optional int32 dummy13 = 13;
+ optional int32 dummy14 = 14;
+ optional int32 dummy15 = 15;
+ optional int32 dummy16 = 16;
+ optional int32 dummy17 = 17;
+ optional int32 dummy18 = 18;
+ optional int32 dummy19 = 19;
+ optional int32 dummy20 = 20;
+ optional int32 dummy21 = 21;
+ optional int32 dummy22 = 22;
+ optional int32 dummy23 = 23;
+ optional int32 dummy24 = 24;
+ optional int32 dummy25 = 25;
+ optional int32 dummy26 = 26;
+ optional int32 dummy27 = 27;
+ optional int32 dummy28 = 28;
+ optional int32 dummy29 = 29;
+ optional int32 dummy30 = 30;
+ optional int32 dummy31 = 31;
+ optional int32 dummy32 = 32;
+
+ required int32 c = 33;
+}
+
+message TestRequiredForeign {
+ optional TestRequired optional_message = 1;
+ repeated TestRequired repeated_message = 2;
+ optional int32 dummy = 3;
+}
+
+// Test that we can use NestedMessage from outside TestAllTypes.
+message TestForeignNested {
+ optional TestAllTypes.NestedMessage foreign_nested = 1;
+}
+
+// TestEmptyMessage is used to test unknown field support.
+message TestEmptyMessage {
+}
+
+// Like above, but declare all field numbers as potential extensions. No
+// actual extensions should ever be defined for this type.
+message TestEmptyMessageWithExtensions {
+ extensions 1 to max;
+}
+
+message TestMultipleExtensionRanges {
+ extensions 42;
+ extensions 4143 to 4243;
+ extensions 65536 to max;
+}
+
+// Test that really large tag numbers don't break anything.
+message TestReallyLargeTagNumber {
+ // The largest possible tag number is 2^28 - 1, since the wire format uses
+ // three bits to communicate wire type.
+ optional int32 a = 1;
+ optional int32 bb = 268435455;
+}
+
+message TestRecursiveMessage {
+ optional TestRecursiveMessage a = 1;
+ optional int32 i = 2;
+}
+
+// Test that mutual recursion works.
+message TestMutualRecursionA {
+ optional TestMutualRecursionB bb = 1;
+}
+
+message TestMutualRecursionB {
+ optional TestMutualRecursionA a = 1;
+ optional int32 optional_int32 = 2;
+}
+
+// Test that groups have disjoint field numbers from their siblings and
+// parents. This is NOT possible in proto1; only proto2. When attempting
+// to compile with proto1, this will emit an error; so we only include it
+// in protobuf_unittest_proto.
+message TestDupFieldNumber { // NO_PROTO1
+ optional int32 a = 1; // NO_PROTO1
+ optional group Foo = 2 { optional int32 a = 1; } // NO_PROTO1
+ optional group Bar = 3 { optional int32 a = 1; } // NO_PROTO1
+} // NO_PROTO1
+
+// Additional messages for testing lazy fields.
+message TestEagerMessage {
+ optional TestAllTypes sub_message = 1 [lazy=false];
+}
+message TestLazyMessage {
+ optional TestAllTypes sub_message = 1 [lazy=true];
+}
+
+// Needed for a Python test.
+message TestNestedMessageHasBits {
+ message NestedMessage {
+ repeated int32 nestedmessage_repeated_int32 = 1;
+ repeated ForeignMessage nestedmessage_repeated_foreignmessage = 2;
+ }
+ optional NestedMessage optional_nested_message = 1;
+}
+
+
+// Test an enum that has multiple values with the same number.
+enum TestEnumWithDupValue {
+ option allow_alias = true;
+ FOO1 = 1;
+ BAR1 = 2;
+ BAZ = 3;
+ FOO2 = 1;
+ BAR2 = 2;
+}
+
+// Test an enum with large, unordered values.
+enum TestSparseEnum {
+ SPARSE_A = 123;
+ SPARSE_B = 62374;
+ SPARSE_C = 12589234;
+ SPARSE_D = -15;
+ SPARSE_E = -53452;
+ SPARSE_F = 0;
+ SPARSE_G = 2;
+}
+
+// Test message with CamelCase field names. This violates Protocol Buffer
+// standard style.
+message TestCamelCaseFieldNames {
+ optional int32 PrimitiveField = 1;
+ optional string StringField = 2;
+ optional ForeignEnum EnumField = 3;
+ optional ForeignMessage MessageField = 4;
+ optional string StringPieceField = 5 [ctype=STRING_PIECE];
+ optional string CordField = 6 [ctype=CORD];
+
+ repeated int32 RepeatedPrimitiveField = 7;
+ repeated string RepeatedStringField = 8;
+ repeated ForeignEnum RepeatedEnumField = 9;
+ repeated ForeignMessage RepeatedMessageField = 10;
+ repeated string RepeatedStringPieceField = 11 [ctype=STRING_PIECE];
+ repeated string RepeatedCordField = 12 [ctype=CORD];
+}
+
+
+// We list fields out of order, to ensure that we're using field number and not
+// field index to determine serialization order.
+message TestFieldOrderings {
+ optional string my_string = 11;
+ extensions 2 to 10;
+ optional int64 my_int = 1;
+ extensions 12 to 100;
+ optional float my_float = 101;
+}
+
+
+extend TestFieldOrderings {
+ optional string my_extension_string = 50;
+ optional int32 my_extension_int = 5;
+}
+
+
+message TestExtremeDefaultValues {
+ optional bytes escaped_bytes = 1 [default = "\0\001\a\b\f\n\r\t\v\\\'\"\xfe"];
+ optional uint32 large_uint32 = 2 [default = 0xFFFFFFFF];
+ optional uint64 large_uint64 = 3 [default = 0xFFFFFFFFFFFFFFFF];
+ optional int32 small_int32 = 4 [default = -0x7FFFFFFF];
+ optional int64 small_int64 = 5 [default = -0x7FFFFFFFFFFFFFFF];
+ optional int32 really_small_int32 = 21 [default = -0x80000000];
+ optional int64 really_small_int64 = 22 [default = -0x8000000000000000];
+
+ // The default value here is UTF-8 for "\u1234". (We could also just type
+ // the UTF-8 text directly into this text file rather than escape it, but
+ // lots of people use editors that would be confused by this.)
+ optional string utf8_string = 6 [default = "\341\210\264"];
+
+ // Tests for single-precision floating-point values.
+ optional float zero_float = 7 [default = 0];
+ optional float one_float = 8 [default = 1];
+ optional float small_float = 9 [default = 1.5];
+ optional float negative_one_float = 10 [default = -1];
+ optional float negative_float = 11 [default = -1.5];
+ // Using exponents
+ optional float large_float = 12 [default = 2E8];
+ optional float small_negative_float = 13 [default = -8e-28];
+
+ // Text for nonfinite floating-point values.
+ optional double inf_double = 14 [default = inf];
+ optional double neg_inf_double = 15 [default = -inf];
+ optional double nan_double = 16 [default = nan];
+ optional float inf_float = 17 [default = inf];
+ optional float neg_inf_float = 18 [default = -inf];
+ optional float nan_float = 19 [default = nan];
+
+ // Tests for C++ trigraphs.
+ // Trigraphs should be escaped in C++ generated files, but they should not be
+ // escaped for other languages.
+ // Note that in .proto file, "\?" is a valid way to escape ? in string
+ // literals.
+ optional string cpp_trigraph = 20 [default = "? \? ?? \?? \??? ??/ ?\?-"];
+
+ // String defaults containing the character '\000'
+ optional string string_with_zero = 23 [default = "hel\000lo"];
+ optional bytes bytes_with_zero = 24 [default = "wor\000ld"];
+ optional string string_piece_with_zero = 25 [ctype=STRING_PIECE,
+ default="ab\000c"];
+ optional string cord_with_zero = 26 [ctype=CORD,
+ default="12\0003"];
+}
+
+message SparseEnumMessage {
+ optional TestSparseEnum sparse_enum = 1;
+}
+
+// Test String and Bytes: string is for valid UTF-8 strings
+message OneString {
+ optional string data = 1;
+}
+
+message MoreString {
+ repeated string data = 1;
+}
+
+message OneBytes {
+ optional bytes data = 1;
+}
+
+message MoreBytes {
+ repeated bytes data = 1;
+}
+
+
+// Test messages for packed fields
+
+message TestPackedTypes {
+ repeated int32 packed_int32 = 90 [packed = true];
+ repeated int64 packed_int64 = 91 [packed = true];
+ repeated uint32 packed_uint32 = 92 [packed = true];
+ repeated uint64 packed_uint64 = 93 [packed = true];
+ repeated sint32 packed_sint32 = 94 [packed = true];
+ repeated sint64 packed_sint64 = 95 [packed = true];
+ repeated fixed32 packed_fixed32 = 96 [packed = true];
+ repeated fixed64 packed_fixed64 = 97 [packed = true];
+ repeated sfixed32 packed_sfixed32 = 98 [packed = true];
+ repeated sfixed64 packed_sfixed64 = 99 [packed = true];
+ repeated float packed_float = 100 [packed = true];
+ repeated double packed_double = 101 [packed = true];
+ repeated bool packed_bool = 102 [packed = true];
+ repeated ForeignEnum packed_enum = 103 [packed = true];
+}
+
+// A message with the same fields as TestPackedTypes, but without packing. Used
+// to test packed <-> unpacked wire compatibility.
+message TestUnpackedTypes {
+ repeated int32 unpacked_int32 = 90 [packed = false];
+ repeated int64 unpacked_int64 = 91 [packed = false];
+ repeated uint32 unpacked_uint32 = 92 [packed = false];
+ repeated uint64 unpacked_uint64 = 93 [packed = false];
+ repeated sint32 unpacked_sint32 = 94 [packed = false];
+ repeated sint64 unpacked_sint64 = 95 [packed = false];
+ repeated fixed32 unpacked_fixed32 = 96 [packed = false];
+ repeated fixed64 unpacked_fixed64 = 97 [packed = false];
+ repeated sfixed32 unpacked_sfixed32 = 98 [packed = false];
+ repeated sfixed64 unpacked_sfixed64 = 99 [packed = false];
+ repeated float unpacked_float = 100 [packed = false];
+ repeated double unpacked_double = 101 [packed = false];
+ repeated bool unpacked_bool = 102 [packed = false];
+ repeated ForeignEnum unpacked_enum = 103 [packed = false];
+}
+
+message TestPackedExtensions {
+ extensions 1 to max;
+}
+
+extend TestPackedExtensions {
+ repeated int32 packed_int32_extension = 90 [packed = true];
+ repeated int64 packed_int64_extension = 91 [packed = true];
+ repeated uint32 packed_uint32_extension = 92 [packed = true];
+ repeated uint64 packed_uint64_extension = 93 [packed = true];
+ repeated sint32 packed_sint32_extension = 94 [packed = true];
+ repeated sint64 packed_sint64_extension = 95 [packed = true];
+ repeated fixed32 packed_fixed32_extension = 96 [packed = true];
+ repeated fixed64 packed_fixed64_extension = 97 [packed = true];
+ repeated sfixed32 packed_sfixed32_extension = 98 [packed = true];
+ repeated sfixed64 packed_sfixed64_extension = 99 [packed = true];
+ repeated float packed_float_extension = 100 [packed = true];
+ repeated double packed_double_extension = 101 [packed = true];
+ repeated bool packed_bool_extension = 102 [packed = true];
+ repeated ForeignEnum packed_enum_extension = 103 [packed = true];
+}
+
+// Used by ExtensionSetTest/DynamicExtensions. The test actually builds
+// a set of extensions to TestAllExtensions dynamically, based on the fields
+// of this message type.
+message TestDynamicExtensions {
+ enum DynamicEnumType {
+ DYNAMIC_FOO = 2200;
+ DYNAMIC_BAR = 2201;
+ DYNAMIC_BAZ = 2202;
+ }
+ message DynamicMessageType {
+ optional int32 dynamic_field = 2100;
+ }
+
+ optional fixed32 scalar_extension = 2000;
+ optional ForeignEnum enum_extension = 2001;
+ optional DynamicEnumType dynamic_enum_extension = 2002;
+
+ optional ForeignMessage message_extension = 2003;
+ optional DynamicMessageType dynamic_message_extension = 2004;
+
+ repeated string repeated_extension = 2005;
+ repeated sint32 packed_extension = 2006 [packed = true];
+}
+
+message TestRepeatedScalarDifferentTagSizes {
+ // Parsing repeated fixed size values used to fail. This message needs to be
+ // used in order to get a tag of the right size; all of the repeated fields
+ // in TestAllTypes didn't trigger the check.
+ repeated fixed32 repeated_fixed32 = 12;
+ // Check for a varint type, just for good measure.
+ repeated int32 repeated_int32 = 13;
+
+ // These have two-byte tags.
+ repeated fixed64 repeated_fixed64 = 2046;
+ repeated int64 repeated_int64 = 2047;
+
+ // Three byte tags.
+ repeated float repeated_float = 262142;
+ repeated uint64 repeated_uint64 = 262143;
+}
+
+// Test that if an optional or required message/group field appears multiple
+// times in the input, they need to be merged.
+message TestParsingMerge {
+ // RepeatedFieldsGenerator defines matching field types as TestParsingMerge,
+ // except that all fields are repeated. In the tests, we will serialize the
+ // RepeatedFieldsGenerator to bytes, and parse the bytes to TestParsingMerge.
+ // Repeated fields in RepeatedFieldsGenerator are expected to be merged into
+ // the corresponding required/optional fields in TestParsingMerge.
+ message RepeatedFieldsGenerator {
+ repeated TestAllTypes field1 = 1;
+ repeated TestAllTypes field2 = 2;
+ repeated TestAllTypes field3 = 3;
+ repeated group Group1 = 10 {
+ optional TestAllTypes field1 = 11;
+ }
+ repeated group Group2 = 20 {
+ optional TestAllTypes field1 = 21;
+ }
+ repeated TestAllTypes ext1 = 1000;
+ repeated TestAllTypes ext2 = 1001;
+ }
+ required TestAllTypes required_all_types = 1;
+ optional TestAllTypes optional_all_types = 2;
+ repeated TestAllTypes repeated_all_types = 3;
+ optional group OptionalGroup = 10 {
+ optional TestAllTypes optional_group_all_types = 11;
+ }
+ repeated group RepeatedGroup = 20 {
+ optional TestAllTypes repeated_group_all_types = 21;
+ }
+ extensions 1000 to max;
+ extend TestParsingMerge {
+ optional TestAllTypes optional_ext = 1000;
+ repeated TestAllTypes repeated_ext = 1001;
+ }
+}
+
+message TestCommentInjectionMessage {
+ // */ <- This should not close the generated doc comment
+ optional string a = 1 [default="*/ <- Neither should this."];
+}
+
+
+// Test that RPC services work.
+message FooRequest {}
+message FooResponse {}
+
+message FooClientMessage {}
+message FooServerMessage{}
+
+service TestService {
+ rpc Foo(FooRequest) returns (FooResponse);
+ rpc Bar(BarRequest) returns (BarResponse);
+}
+
+
+message BarRequest {}
+message BarResponse {}
diff --git a/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_custom_options.proto b/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_custom_options.proto
new file mode 100644
index 00000000..e591d294
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_custom_options.proto
@@ -0,0 +1,387 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+// Author: benjy@google.com (Benjy Weinberger)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// A proto file used to test the "custom options" feature of proto2.
+
+
+// Some generic_services option(s) added automatically.
+// See: http://go/proto2-generic-services-default
+option cc_generic_services = true; // auto-added
+option java_generic_services = true; // auto-added
+option py_generic_services = true;
+
+// A custom file option (defined below).
+option (file_opt1) = 9876543210;
+
+import "google/protobuf/descriptor.proto";
+
+// We don't put this in a package within proto2 because we need to make sure
+// that the generated code doesn't depend on being in the proto2 namespace.
+package protobuf_unittest;
+
+
+// Some simple test custom options of various types.
+
+extend google.protobuf.FileOptions {
+ optional uint64 file_opt1 = 7736974;
+}
+
+extend google.protobuf.MessageOptions {
+ optional int32 message_opt1 = 7739036;
+}
+
+extend google.protobuf.FieldOptions {
+ optional fixed64 field_opt1 = 7740936;
+ // This is useful for testing that we correctly register default values for
+ // extension options.
+ optional int32 field_opt2 = 7753913 [default=42];
+}
+
+extend google.protobuf.EnumOptions {
+ optional sfixed32 enum_opt1 = 7753576;
+}
+
+extend google.protobuf.EnumValueOptions {
+ optional int32 enum_value_opt1 = 1560678;
+}
+
+extend google.protobuf.ServiceOptions {
+ optional sint64 service_opt1 = 7887650;
+}
+
+enum MethodOpt1 {
+ METHODOPT1_VAL1 = 1;
+ METHODOPT1_VAL2 = 2;
+}
+
+extend google.protobuf.MethodOptions {
+ optional MethodOpt1 method_opt1 = 7890860;
+}
+
+// A test message with custom options at all possible locations (and also some
+// regular options, to make sure they interact nicely).
+message TestMessageWithCustomOptions {
+ option message_set_wire_format = false;
+
+ option (message_opt1) = -56;
+
+ optional string field1 = 1 [ctype=CORD,
+ (field_opt1)=8765432109];
+
+ enum AnEnum {
+ option (enum_opt1) = -789;
+
+ ANENUM_VAL1 = 1;
+ ANENUM_VAL2 = 2 [(enum_value_opt1) = 123];
+ }
+}
+
+
+// A test RPC service with custom options at all possible locations (and also
+// some regular options, to make sure they interact nicely).
+message CustomOptionFooRequest {
+}
+
+message CustomOptionFooResponse {
+}
+
+message CustomOptionFooClientMessage {
+}
+
+message CustomOptionFooServerMessage {
+}
+
+service TestServiceWithCustomOptions {
+ option (service_opt1) = -9876543210;
+
+ rpc Foo(CustomOptionFooRequest) returns (CustomOptionFooResponse) {
+ option (method_opt1) = METHODOPT1_VAL2;
+ }
+}
+
+
+
+// Options of every possible field type, so we can test them all exhaustively.
+
+message DummyMessageContainingEnum {
+ enum TestEnumType {
+ TEST_OPTION_ENUM_TYPE1 = 22;
+ TEST_OPTION_ENUM_TYPE2 = -23;
+ }
+}
+
+message DummyMessageInvalidAsOptionType {
+}
+
+extend google.protobuf.MessageOptions {
+ optional bool bool_opt = 7706090;
+ optional int32 int32_opt = 7705709;
+ optional int64 int64_opt = 7705542;
+ optional uint32 uint32_opt = 7704880;
+ optional uint64 uint64_opt = 7702367;
+ optional sint32 sint32_opt = 7701568;
+ optional sint64 sint64_opt = 7700863;
+ optional fixed32 fixed32_opt = 7700307;
+ optional fixed64 fixed64_opt = 7700194;
+ optional sfixed32 sfixed32_opt = 7698645;
+ optional sfixed64 sfixed64_opt = 7685475;
+ optional float float_opt = 7675390;
+ optional double double_opt = 7673293;
+ optional string string_opt = 7673285;
+ optional bytes bytes_opt = 7673238;
+ optional DummyMessageContainingEnum.TestEnumType enum_opt = 7673233;
+ optional DummyMessageInvalidAsOptionType message_type_opt = 7665967;
+}
+
+message CustomOptionMinIntegerValues {
+ option (bool_opt) = false;
+ option (int32_opt) = -0x80000000;
+ option (int64_opt) = -0x8000000000000000;
+ option (uint32_opt) = 0;
+ option (uint64_opt) = 0;
+ option (sint32_opt) = -0x80000000;
+ option (sint64_opt) = -0x8000000000000000;
+ option (fixed32_opt) = 0;
+ option (fixed64_opt) = 0;
+ option (sfixed32_opt) = -0x80000000;
+ option (sfixed64_opt) = -0x8000000000000000;
+}
+
+message CustomOptionMaxIntegerValues {
+ option (bool_opt) = true;
+ option (int32_opt) = 0x7FFFFFFF;
+ option (int64_opt) = 0x7FFFFFFFFFFFFFFF;
+ option (uint32_opt) = 0xFFFFFFFF;
+ option (uint64_opt) = 0xFFFFFFFFFFFFFFFF;
+ option (sint32_opt) = 0x7FFFFFFF;
+ option (sint64_opt) = 0x7FFFFFFFFFFFFFFF;
+ option (fixed32_opt) = 0xFFFFFFFF;
+ option (fixed64_opt) = 0xFFFFFFFFFFFFFFFF;
+ option (sfixed32_opt) = 0x7FFFFFFF;
+ option (sfixed64_opt) = 0x7FFFFFFFFFFFFFFF;
+}
+
+message CustomOptionOtherValues {
+ option (int32_opt) = -100; // To test sign-extension.
+ option (float_opt) = 12.3456789;
+ option (double_opt) = 1.234567890123456789;
+ option (string_opt) = "Hello, \"World\"";
+ option (bytes_opt) = "Hello\0World";
+ option (enum_opt) = TEST_OPTION_ENUM_TYPE2;
+}
+
+message SettingRealsFromPositiveInts {
+ option (float_opt) = 12;
+ option (double_opt) = 154;
+}
+
+message SettingRealsFromNegativeInts {
+ option (float_opt) = -12;
+ option (double_opt) = -154;
+}
+
+// Options of complex message types, themselves combined and extended in
+// various ways.
+
+message ComplexOptionType1 {
+ optional int32 foo = 1;
+ optional int32 foo2 = 2;
+ optional int32 foo3 = 3;
+
+ extensions 100 to max;
+}
+
+message ComplexOptionType2 {
+ optional ComplexOptionType1 bar = 1;
+ optional int32 baz = 2;
+
+ message ComplexOptionType4 {
+ optional int32 waldo = 1;
+
+ extend google.protobuf.MessageOptions {
+ optional ComplexOptionType4 complex_opt4 = 7633546;
+ }
+ }
+
+ optional ComplexOptionType4 fred = 3;
+
+ extensions 100 to max;
+}
+
+message ComplexOptionType3 {
+ optional int32 qux = 1;
+
+ optional group ComplexOptionType5 = 2 {
+ optional int32 plugh = 3;
+ }
+}
+
+extend ComplexOptionType1 {
+ optional int32 quux = 7663707;
+ optional ComplexOptionType3 corge = 7663442;
+}
+
+extend ComplexOptionType2 {
+ optional int32 grault = 7650927;
+ optional ComplexOptionType1 garply = 7649992;
+}
+
+extend google.protobuf.MessageOptions {
+ optional protobuf_unittest.ComplexOptionType1 complex_opt1 = 7646756;
+ optional ComplexOptionType2 complex_opt2 = 7636949;
+ optional ComplexOptionType3 complex_opt3 = 7636463;
+ optional group ComplexOpt6 = 7595468 {
+ optional int32 xyzzy = 7593951;
+ }
+}
+
+// Note that we try various different ways of naming the same extension.
+message VariousComplexOptions {
+ option (.protobuf_unittest.complex_opt1).foo = 42;
+ option (protobuf_unittest.complex_opt1).(.protobuf_unittest.quux) = 324;
+ option (.protobuf_unittest.complex_opt1).(protobuf_unittest.corge).qux = 876;
+ option (complex_opt2).baz = 987;
+ option (complex_opt2).(grault) = 654;
+ option (complex_opt2).bar.foo = 743;
+ option (complex_opt2).bar.(quux) = 1999;
+ option (complex_opt2).bar.(protobuf_unittest.corge).qux = 2008;
+ option (complex_opt2).(garply).foo = 741;
+ option (complex_opt2).(garply).(.protobuf_unittest.quux) = 1998;
+ option (complex_opt2).(protobuf_unittest.garply).(corge).qux = 2121;
+ option (ComplexOptionType2.ComplexOptionType4.complex_opt4).waldo = 1971;
+ option (complex_opt2).fred.waldo = 321;
+ option (protobuf_unittest.complex_opt3).qux = 9;
+ option (complex_opt3).complexoptiontype5.plugh = 22;
+ option (complexopt6).xyzzy = 24;
+}
+
+// ------------------------------------------------------
+// Definitions for testing aggregate option parsing.
+// See descriptor_unittest.cc.
+
+message AggregateMessageSet {
+ option message_set_wire_format = true;
+ extensions 4 to max;
+}
+
+message AggregateMessageSetElement {
+ extend AggregateMessageSet {
+ optional AggregateMessageSetElement message_set_extension = 15447542;
+ }
+ optional string s = 1;
+}
+
+// A helper type used to test aggregate option parsing
+message Aggregate {
+ optional int32 i = 1;
+ optional string s = 2;
+
+ // A nested object
+ optional Aggregate sub = 3;
+
+ // To test the parsing of extensions inside aggregate values
+ optional google.protobuf.FileOptions file = 4;
+ extend google.protobuf.FileOptions {
+ optional Aggregate nested = 15476903;
+ }
+
+ // An embedded message set
+ optional AggregateMessageSet mset = 5;
+}
+
+// Allow Aggregate to be used as an option at all possible locations
+// in the .proto grammer.
+extend google.protobuf.FileOptions { optional Aggregate fileopt = 15478479; }
+extend google.protobuf.MessageOptions { optional Aggregate msgopt = 15480088; }
+extend google.protobuf.FieldOptions { optional Aggregate fieldopt = 15481374; }
+extend google.protobuf.EnumOptions { optional Aggregate enumopt = 15483218; }
+extend google.protobuf.EnumValueOptions { optional Aggregate enumvalopt = 15486921; }
+extend google.protobuf.ServiceOptions { optional Aggregate serviceopt = 15497145; }
+extend google.protobuf.MethodOptions { optional Aggregate methodopt = 15512713; }
+
+// Try using AggregateOption at different points in the proto grammar
+option (fileopt) = {
+ s: 'FileAnnotation'
+ // Also test the handling of comments
+ /* of both types */ i: 100
+
+ sub { s: 'NestedFileAnnotation' }
+
+ // Include a google.protobuf.FileOptions and recursively extend it with
+ // another fileopt.
+ file {
+ [protobuf_unittest.fileopt] {
+ s:'FileExtensionAnnotation'
+ }
+ }
+
+ // A message set inside an option value
+ mset {
+ [protobuf_unittest.AggregateMessageSetElement.message_set_extension] {
+ s: 'EmbeddedMessageSetElement'
+ }
+ }
+};
+
+message AggregateMessage {
+ option (msgopt) = { i:101 s:'MessageAnnotation' };
+ optional int32 fieldname = 1 [(fieldopt) = { s:'FieldAnnotation' }];
+}
+
+service AggregateService {
+ option (serviceopt) = { s:'ServiceAnnotation' };
+ rpc Method (AggregateMessage) returns (AggregateMessage) {
+ option (methodopt) = { s:'MethodAnnotation' };
+ }
+}
+
+enum AggregateEnum {
+ option (enumopt) = { s:'EnumAnnotation' };
+ VALUE = 1 [(enumvalopt) = { s:'EnumValueAnnotation' }];
+}
+
+// Test custom options for nested type.
+message NestedOptionType {
+ message NestedMessage {
+ option (message_opt1) = 1001;
+ optional int32 nested_field = 1 [(field_opt1) = 1002];
+ }
+ enum NestedEnum {
+ option (enum_opt1) = 1003;
+ NESTED_ENUM_VALUE = 1 [(enum_value_opt1) = 1004];
+ }
+ extend google.protobuf.FileOptions {
+ optional int32 nested_extension = 7912573 [(field_opt2) = 1005];
+ }
+}
diff --git a/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_embed_optimize_for.proto b/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_embed_optimize_for.proto
new file mode 100644
index 00000000..fa176259
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_embed_optimize_for.proto
@@ -0,0 +1,50 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// A proto file which imports a proto file that uses optimize_for = CODE_SIZE.
+
+import "google/protobuf/unittest_optimize_for.proto";
+
+package protobuf_unittest;
+
+// We optimize for speed here, but we are importing a proto that is optimized
+// for code size.
+option optimize_for = SPEED;
+
+message TestEmbedOptimizedForSize {
+ // Test that embedding a message which has optimize_for = CODE_SIZE into
+ // one optimized for speed works.
+ optional TestOptimizedForSize optional_message = 1;
+ repeated TestOptimizedForSize repeated_message = 2;
+}
diff --git a/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_empty.proto b/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_empty.proto
new file mode 100644
index 00000000..ab12d1fb
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_empty.proto
@@ -0,0 +1,37 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file intentionally left blank. (At one point this wouldn't compile
+// correctly.)
+
diff --git a/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_enormous_descriptor.proto b/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_enormous_descriptor.proto
new file mode 100644
index 00000000..bc0b7c16
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_enormous_descriptor.proto
@@ -0,0 +1,1046 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// A proto file that has an extremely large descriptor. Used to test that
+// descriptors over 64k don't break the string literal length limit in Java.
+
+
+package google.protobuf;
+option java_package = "com.google.protobuf";
+
+// Avoid generating insanely long methods.
+option optimize_for = CODE_SIZE;
+
+message TestEnormousDescriptor {
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_1 = 1 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_2 = 2 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_3 = 3 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_4 = 4 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_5 = 5 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_6 = 6 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_7 = 7 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_8 = 8 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_9 = 9 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_10 = 10 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_11 = 11 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_12 = 12 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_13 = 13 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_14 = 14 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_15 = 15 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_16 = 16 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_17 = 17 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_18 = 18 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_19 = 19 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_20 = 20 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_21 = 21 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_22 = 22 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_23 = 23 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_24 = 24 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_25 = 25 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_26 = 26 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_27 = 27 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_28 = 28 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_29 = 29 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_30 = 30 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_31 = 31 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_32 = 32 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_33 = 33 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_34 = 34 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_35 = 35 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_36 = 36 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_37 = 37 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_38 = 38 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_39 = 39 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_40 = 40 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_41 = 41 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_42 = 42 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_43 = 43 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_44 = 44 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_45 = 45 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_46 = 46 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_47 = 47 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_48 = 48 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_49 = 49 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_50 = 50 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_51 = 51 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_52 = 52 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_53 = 53 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_54 = 54 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_55 = 55 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_56 = 56 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_57 = 57 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_58 = 58 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_59 = 59 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_60 = 60 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_61 = 61 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_62 = 62 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_63 = 63 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_64 = 64 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_65 = 65 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_66 = 66 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_67 = 67 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_68 = 68 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_69 = 69 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_70 = 70 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_71 = 71 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_72 = 72 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_73 = 73 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_74 = 74 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_75 = 75 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_76 = 76 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_77 = 77 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_78 = 78 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_79 = 79 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_80 = 80 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_81 = 81 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_82 = 82 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_83 = 83 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_84 = 84 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_85 = 85 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_86 = 86 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_87 = 87 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_88 = 88 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_89 = 89 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_90 = 90 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_91 = 91 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_92 = 92 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_93 = 93 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_94 = 94 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_95 = 95 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_96 = 96 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_97 = 97 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_98 = 98 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_99 = 99 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_100 = 100 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_101 = 101 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_102 = 102 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_103 = 103 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_104 = 104 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_105 = 105 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_106 = 106 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_107 = 107 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_108 = 108 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_109 = 109 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_110 = 110 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_111 = 111 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_112 = 112 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_113 = 113 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_114 = 114 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_115 = 115 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_116 = 116 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_117 = 117 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_118 = 118 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_119 = 119 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_120 = 120 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_121 = 121 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_122 = 122 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_123 = 123 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_124 = 124 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_125 = 125 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_126 = 126 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_127 = 127 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_128 = 128 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_129 = 129 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_130 = 130 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_131 = 131 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_132 = 132 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_133 = 133 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_134 = 134 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_135 = 135 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_136 = 136 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_137 = 137 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_138 = 138 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_139 = 139 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_140 = 140 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_141 = 141 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_142 = 142 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_143 = 143 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_144 = 144 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_145 = 145 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_146 = 146 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_147 = 147 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_148 = 148 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_149 = 149 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_150 = 150 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_151 = 151 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_152 = 152 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_153 = 153 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_154 = 154 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_155 = 155 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_156 = 156 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_157 = 157 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_158 = 158 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_159 = 159 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_160 = 160 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_161 = 161 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_162 = 162 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_163 = 163 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_164 = 164 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_165 = 165 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_166 = 166 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_167 = 167 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_168 = 168 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_169 = 169 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_170 = 170 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_171 = 171 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_172 = 172 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_173 = 173 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_174 = 174 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_175 = 175 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_176 = 176 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_177 = 177 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_178 = 178 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_179 = 179 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_180 = 180 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_181 = 181 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_182 = 182 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_183 = 183 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_184 = 184 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_185 = 185 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_186 = 186 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_187 = 187 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_188 = 188 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_189 = 189 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_190 = 190 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_191 = 191 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_192 = 192 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_193 = 193 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_194 = 194 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_195 = 195 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_196 = 196 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_197 = 197 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_198 = 198 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_199 = 199 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_200 = 200 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_201 = 201 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_202 = 202 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_203 = 203 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_204 = 204 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_205 = 205 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_206 = 206 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_207 = 207 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_208 = 208 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_209 = 209 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_210 = 210 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_211 = 211 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_212 = 212 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_213 = 213 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_214 = 214 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_215 = 215 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_216 = 216 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_217 = 217 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_218 = 218 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_219 = 219 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_220 = 220 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_221 = 221 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_222 = 222 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_223 = 223 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_224 = 224 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_225 = 225 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_226 = 226 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_227 = 227 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_228 = 228 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_229 = 229 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_230 = 230 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_231 = 231 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_232 = 232 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_233 = 233 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_234 = 234 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_235 = 235 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_236 = 236 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_237 = 237 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_238 = 238 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_239 = 239 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_240 = 240 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_241 = 241 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_242 = 242 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_243 = 243 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_244 = 244 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_245 = 245 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_246 = 246 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_247 = 247 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_248 = 248 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_249 = 249 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_250 = 250 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_251 = 251 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_252 = 252 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_253 = 253 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_254 = 254 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_255 = 255 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_256 = 256 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_257 = 257 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_258 = 258 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_259 = 259 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_260 = 260 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_261 = 261 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_262 = 262 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_263 = 263 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_264 = 264 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_265 = 265 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_266 = 266 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_267 = 267 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_268 = 268 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_269 = 269 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_270 = 270 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_271 = 271 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_272 = 272 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_273 = 273 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_274 = 274 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_275 = 275 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_276 = 276 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_277 = 277 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_278 = 278 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_279 = 279 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_280 = 280 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_281 = 281 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_282 = 282 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_283 = 283 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_284 = 284 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_285 = 285 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_286 = 286 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_287 = 287 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_288 = 288 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_289 = 289 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_290 = 290 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_291 = 291 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_292 = 292 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_293 = 293 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_294 = 294 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_295 = 295 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_296 = 296 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_297 = 297 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_298 = 298 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_299 = 299 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_300 = 300 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_301 = 301 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_302 = 302 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_303 = 303 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_304 = 304 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_305 = 305 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_306 = 306 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_307 = 307 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_308 = 308 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_309 = 309 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_310 = 310 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_311 = 311 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_312 = 312 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_313 = 313 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_314 = 314 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_315 = 315 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_316 = 316 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_317 = 317 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_318 = 318 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_319 = 319 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_320 = 320 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_321 = 321 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_322 = 322 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_323 = 323 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_324 = 324 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_325 = 325 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_326 = 326 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_327 = 327 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_328 = 328 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_329 = 329 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_330 = 330 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_331 = 331 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_332 = 332 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_333 = 333 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_334 = 334 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_335 = 335 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_336 = 336 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_337 = 337 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_338 = 338 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_339 = 339 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_340 = 340 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_341 = 341 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_342 = 342 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_343 = 343 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_344 = 344 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_345 = 345 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_346 = 346 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_347 = 347 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_348 = 348 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_349 = 349 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_350 = 350 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_351 = 351 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_352 = 352 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_353 = 353 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_354 = 354 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_355 = 355 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_356 = 356 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_357 = 357 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_358 = 358 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_359 = 359 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_360 = 360 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_361 = 361 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_362 = 362 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_363 = 363 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_364 = 364 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_365 = 365 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_366 = 366 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_367 = 367 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_368 = 368 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_369 = 369 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_370 = 370 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_371 = 371 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_372 = 372 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_373 = 373 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_374 = 374 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_375 = 375 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_376 = 376 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_377 = 377 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_378 = 378 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_379 = 379 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_380 = 380 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_381 = 381 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_382 = 382 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_383 = 383 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_384 = 384 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_385 = 385 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_386 = 386 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_387 = 387 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_388 = 388 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_389 = 389 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_390 = 390 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_391 = 391 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_392 = 392 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_393 = 393 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_394 = 394 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_395 = 395 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_396 = 396 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_397 = 397 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_398 = 398 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_399 = 399 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_400 = 400 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_401 = 401 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_402 = 402 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_403 = 403 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_404 = 404 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_405 = 405 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_406 = 406 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_407 = 407 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_408 = 408 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_409 = 409 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_410 = 410 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_411 = 411 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_412 = 412 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_413 = 413 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_414 = 414 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_415 = 415 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_416 = 416 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_417 = 417 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_418 = 418 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_419 = 419 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_420 = 420 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_421 = 421 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_422 = 422 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_423 = 423 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_424 = 424 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_425 = 425 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_426 = 426 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_427 = 427 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_428 = 428 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_429 = 429 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_430 = 430 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_431 = 431 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_432 = 432 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_433 = 433 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_434 = 434 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_435 = 435 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_436 = 436 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_437 = 437 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_438 = 438 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_439 = 439 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_440 = 440 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_441 = 441 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_442 = 442 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_443 = 443 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_444 = 444 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_445 = 445 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_446 = 446 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_447 = 447 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_448 = 448 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_449 = 449 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_450 = 450 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_451 = 451 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_452 = 452 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_453 = 453 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_454 = 454 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_455 = 455 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_456 = 456 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_457 = 457 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_458 = 458 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_459 = 459 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_460 = 460 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_461 = 461 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_462 = 462 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_463 = 463 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_464 = 464 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_465 = 465 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_466 = 466 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_467 = 467 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_468 = 468 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_469 = 469 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_470 = 470 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_471 = 471 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_472 = 472 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_473 = 473 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_474 = 474 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_475 = 475 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_476 = 476 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_477 = 477 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_478 = 478 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_479 = 479 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_480 = 480 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_481 = 481 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_482 = 482 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_483 = 483 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_484 = 484 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_485 = 485 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_486 = 486 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_487 = 487 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_488 = 488 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_489 = 489 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_490 = 490 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_491 = 491 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_492 = 492 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_493 = 493 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_494 = 494 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_495 = 495 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_496 = 496 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_497 = 497 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_498 = 498 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_499 = 499 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_500 = 500 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_501 = 501 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_502 = 502 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_503 = 503 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_504 = 504 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_505 = 505 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_506 = 506 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_507 = 507 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_508 = 508 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_509 = 509 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_510 = 510 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_511 = 511 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_512 = 512 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_513 = 513 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_514 = 514 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_515 = 515 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_516 = 516 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_517 = 517 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_518 = 518 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_519 = 519 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_520 = 520 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_521 = 521 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_522 = 522 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_523 = 523 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_524 = 524 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_525 = 525 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_526 = 526 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_527 = 527 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_528 = 528 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_529 = 529 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_530 = 530 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_531 = 531 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_532 = 532 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_533 = 533 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_534 = 534 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_535 = 535 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_536 = 536 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_537 = 537 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_538 = 538 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_539 = 539 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_540 = 540 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_541 = 541 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_542 = 542 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_543 = 543 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_544 = 544 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_545 = 545 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_546 = 546 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_547 = 547 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_548 = 548 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_549 = 549 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_550 = 550 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_551 = 551 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_552 = 552 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_553 = 553 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_554 = 554 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_555 = 555 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_556 = 556 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_557 = 557 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_558 = 558 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_559 = 559 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_560 = 560 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_561 = 561 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_562 = 562 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_563 = 563 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_564 = 564 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_565 = 565 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_566 = 566 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_567 = 567 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_568 = 568 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_569 = 569 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_570 = 570 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_571 = 571 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_572 = 572 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_573 = 573 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_574 = 574 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_575 = 575 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_576 = 576 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_577 = 577 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_578 = 578 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_579 = 579 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_580 = 580 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_581 = 581 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_582 = 582 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_583 = 583 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_584 = 584 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_585 = 585 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_586 = 586 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_587 = 587 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_588 = 588 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_589 = 589 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_590 = 590 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_591 = 591 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_592 = 592 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_593 = 593 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_594 = 594 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_595 = 595 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_596 = 596 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_597 = 597 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_598 = 598 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_599 = 599 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_600 = 600 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_601 = 601 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_602 = 602 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_603 = 603 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_604 = 604 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_605 = 605 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_606 = 606 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_607 = 607 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_608 = 608 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_609 = 609 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_610 = 610 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_611 = 611 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_612 = 612 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_613 = 613 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_614 = 614 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_615 = 615 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_616 = 616 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_617 = 617 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_618 = 618 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_619 = 619 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_620 = 620 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_621 = 621 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_622 = 622 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_623 = 623 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_624 = 624 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_625 = 625 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_626 = 626 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_627 = 627 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_628 = 628 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_629 = 629 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_630 = 630 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_631 = 631 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_632 = 632 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_633 = 633 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_634 = 634 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_635 = 635 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_636 = 636 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_637 = 637 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_638 = 638 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_639 = 639 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_640 = 640 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_641 = 641 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_642 = 642 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_643 = 643 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_644 = 644 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_645 = 645 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_646 = 646 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_647 = 647 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_648 = 648 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_649 = 649 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_650 = 650 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_651 = 651 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_652 = 652 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_653 = 653 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_654 = 654 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_655 = 655 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_656 = 656 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_657 = 657 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_658 = 658 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_659 = 659 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_660 = 660 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_661 = 661 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_662 = 662 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_663 = 663 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_664 = 664 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_665 = 665 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_666 = 666 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_667 = 667 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_668 = 668 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_669 = 669 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_670 = 670 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_671 = 671 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_672 = 672 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_673 = 673 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_674 = 674 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_675 = 675 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_676 = 676 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_677 = 677 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_678 = 678 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_679 = 679 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_680 = 680 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_681 = 681 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_682 = 682 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_683 = 683 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_684 = 684 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_685 = 685 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_686 = 686 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_687 = 687 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_688 = 688 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_689 = 689 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_690 = 690 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_691 = 691 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_692 = 692 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_693 = 693 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_694 = 694 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_695 = 695 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_696 = 696 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_697 = 697 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_698 = 698 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_699 = 699 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_700 = 700 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_701 = 701 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_702 = 702 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_703 = 703 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_704 = 704 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_705 = 705 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_706 = 706 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_707 = 707 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_708 = 708 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_709 = 709 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_710 = 710 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_711 = 711 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_712 = 712 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_713 = 713 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_714 = 714 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_715 = 715 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_716 = 716 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_717 = 717 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_718 = 718 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_719 = 719 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_720 = 720 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_721 = 721 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_722 = 722 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_723 = 723 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_724 = 724 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_725 = 725 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_726 = 726 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_727 = 727 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_728 = 728 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_729 = 729 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_730 = 730 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_731 = 731 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_732 = 732 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_733 = 733 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_734 = 734 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_735 = 735 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_736 = 736 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_737 = 737 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_738 = 738 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_739 = 739 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_740 = 740 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_741 = 741 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_742 = 742 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_743 = 743 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_744 = 744 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_745 = 745 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_746 = 746 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_747 = 747 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_748 = 748 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_749 = 749 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_750 = 750 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_751 = 751 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_752 = 752 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_753 = 753 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_754 = 754 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_755 = 755 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_756 = 756 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_757 = 757 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_758 = 758 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_759 = 759 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_760 = 760 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_761 = 761 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_762 = 762 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_763 = 763 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_764 = 764 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_765 = 765 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_766 = 766 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_767 = 767 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_768 = 768 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_769 = 769 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_770 = 770 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_771 = 771 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_772 = 772 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_773 = 773 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_774 = 774 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_775 = 775 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_776 = 776 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_777 = 777 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_778 = 778 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_779 = 779 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_780 = 780 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_781 = 781 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_782 = 782 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_783 = 783 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_784 = 784 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_785 = 785 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_786 = 786 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_787 = 787 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_788 = 788 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_789 = 789 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_790 = 790 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_791 = 791 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_792 = 792 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_793 = 793 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_794 = 794 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_795 = 795 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_796 = 796 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_797 = 797 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_798 = 798 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_799 = 799 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_800 = 800 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_801 = 801 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_802 = 802 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_803 = 803 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_804 = 804 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_805 = 805 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_806 = 806 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_807 = 807 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_808 = 808 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_809 = 809 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_810 = 810 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_811 = 811 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_812 = 812 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_813 = 813 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_814 = 814 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_815 = 815 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_816 = 816 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_817 = 817 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_818 = 818 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_819 = 819 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_820 = 820 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_821 = 821 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_822 = 822 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_823 = 823 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_824 = 824 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_825 = 825 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_826 = 826 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_827 = 827 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_828 = 828 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_829 = 829 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_830 = 830 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_831 = 831 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_832 = 832 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_833 = 833 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_834 = 834 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_835 = 835 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_836 = 836 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_837 = 837 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_838 = 838 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_839 = 839 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_840 = 840 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_841 = 841 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_842 = 842 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_843 = 843 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_844 = 844 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_845 = 845 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_846 = 846 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_847 = 847 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_848 = 848 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_849 = 849 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_850 = 850 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_851 = 851 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_852 = 852 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_853 = 853 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_854 = 854 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_855 = 855 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_856 = 856 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_857 = 857 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_858 = 858 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_859 = 859 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_860 = 860 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_861 = 861 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_862 = 862 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_863 = 863 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_864 = 864 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_865 = 865 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_866 = 866 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_867 = 867 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_868 = 868 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_869 = 869 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_870 = 870 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_871 = 871 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_872 = 872 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_873 = 873 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_874 = 874 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_875 = 875 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_876 = 876 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_877 = 877 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_878 = 878 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_879 = 879 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_880 = 880 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_881 = 881 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_882 = 882 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_883 = 883 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_884 = 884 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_885 = 885 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_886 = 886 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_887 = 887 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_888 = 888 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_889 = 889 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_890 = 890 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_891 = 891 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_892 = 892 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_893 = 893 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_894 = 894 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_895 = 895 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_896 = 896 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_897 = 897 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_898 = 898 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_899 = 899 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_900 = 900 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_901 = 901 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_902 = 902 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_903 = 903 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_904 = 904 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_905 = 905 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_906 = 906 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_907 = 907 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_908 = 908 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_909 = 909 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_910 = 910 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_911 = 911 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_912 = 912 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_913 = 913 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_914 = 914 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_915 = 915 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_916 = 916 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_917 = 917 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_918 = 918 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_919 = 919 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_920 = 920 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_921 = 921 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_922 = 922 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_923 = 923 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_924 = 924 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_925 = 925 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_926 = 926 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_927 = 927 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_928 = 928 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_929 = 929 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_930 = 930 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_931 = 931 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_932 = 932 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_933 = 933 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_934 = 934 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_935 = 935 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_936 = 936 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_937 = 937 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_938 = 938 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_939 = 939 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_940 = 940 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_941 = 941 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_942 = 942 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_943 = 943 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_944 = 944 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_945 = 945 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_946 = 946 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_947 = 947 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_948 = 948 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_949 = 949 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_950 = 950 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_951 = 951 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_952 = 952 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_953 = 953 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_954 = 954 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_955 = 955 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_956 = 956 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_957 = 957 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_958 = 958 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_959 = 959 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_960 = 960 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_961 = 961 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_962 = 962 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_963 = 963 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_964 = 964 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_965 = 965 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_966 = 966 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_967 = 967 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_968 = 968 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_969 = 969 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_970 = 970 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_971 = 971 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_972 = 972 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_973 = 973 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_974 = 974 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_975 = 975 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_976 = 976 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_977 = 977 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_978 = 978 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_979 = 979 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_980 = 980 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_981 = 981 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_982 = 982 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_983 = 983 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_984 = 984 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_985 = 985 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_986 = 986 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_987 = 987 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_988 = 988 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_989 = 989 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_990 = 990 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_991 = 991 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_992 = 992 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_993 = 993 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_994 = 994 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_995 = 995 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_996 = 996 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_997 = 997 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_998 = 998 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_999 = 999 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_1000 = 1000 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+}
diff --git a/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_import.proto b/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_import.proto
new file mode 100644
index 00000000..c115b111
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_import.proto
@@ -0,0 +1,64 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// A proto file which is imported by unittest.proto to test importing.
+
+
+// We don't put this in a package within proto2 because we need to make sure
+// that the generated code doesn't depend on being in the proto2 namespace.
+// In test_util.h we do
+// "using namespace unittest_import = protobuf_unittest_import".
+package protobuf_unittest_import;
+
+option optimize_for = SPEED;
+
+// Excercise the java_package option.
+option java_package = "com.google.protobuf.test";
+
+// Do not set a java_outer_classname here to verify that Proto2 works without
+// one.
+
+// Test public import
+import public "google/protobuf/unittest_import_public.proto";
+
+message ImportMessage {
+ optional int32 d = 1;
+}
+
+enum ImportEnum {
+ IMPORT_FOO = 7;
+ IMPORT_BAR = 8;
+ IMPORT_BAZ = 9;
+}
+
diff --git a/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_import_lite.proto b/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_import_lite.proto
new file mode 100644
index 00000000..81b117fe
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_import_lite.proto
@@ -0,0 +1,51 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+// Author: kenton@google.com (Kenton Varda)
+//
+// This is like unittest_import.proto but with optimize_for = LITE_RUNTIME.
+
+package protobuf_unittest_import;
+
+option optimize_for = LITE_RUNTIME;
+
+option java_package = "com.google.protobuf";
+
+import public "google/protobuf/unittest_import_public_lite.proto";
+
+message ImportMessageLite {
+ optional int32 d = 1;
+}
+
+enum ImportEnumLite {
+ IMPORT_LITE_FOO = 7;
+ IMPORT_LITE_BAR = 8;
+ IMPORT_LITE_BAZ = 9;
+}
diff --git a/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_import_public.proto b/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_import_public.proto
new file mode 100644
index 00000000..ea5d1b13
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_import_public.proto
@@ -0,0 +1,40 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+// Author: liujisi@google.com (Pherl Liu)
+
+
+package protobuf_unittest_import;
+
+option java_package = "com.google.protobuf.test";
+
+message PublicImportMessage {
+ optional int32 e = 1;
+}
diff --git a/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_import_public_lite.proto b/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_import_public_lite.proto
new file mode 100644
index 00000000..d077563c
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_import_public_lite.proto
@@ -0,0 +1,42 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+// Author: liujisi@google.com (Pherl Liu)
+
+
+package protobuf_unittest_import;
+
+option optimize_for = LITE_RUNTIME;
+
+option java_package = "com.google.protobuf";
+
+message PublicImportMessageLite {
+ optional int32 e = 1;
+}
diff --git a/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_lite.proto b/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_lite.proto
new file mode 100644
index 00000000..a1764aac
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_lite.proto
@@ -0,0 +1,360 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+// Author: kenton@google.com (Kenton Varda)
+//
+// This is like unittest.proto but with optimize_for = LITE_RUNTIME.
+
+package protobuf_unittest;
+
+import "google/protobuf/unittest_import_lite.proto";
+
+option optimize_for = LITE_RUNTIME;
+
+option java_package = "com.google.protobuf";
+
+// Same as TestAllTypes but with the lite runtime.
+message TestAllTypesLite {
+ message NestedMessage {
+ optional int32 bb = 1;
+ }
+
+ enum NestedEnum {
+ FOO = 1;
+ BAR = 2;
+ BAZ = 3;
+ }
+
+ // Singular
+ optional int32 optional_int32 = 1;
+ optional int64 optional_int64 = 2;
+ optional uint32 optional_uint32 = 3;
+ optional uint64 optional_uint64 = 4;
+ optional sint32 optional_sint32 = 5;
+ optional sint64 optional_sint64 = 6;
+ optional fixed32 optional_fixed32 = 7;
+ optional fixed64 optional_fixed64 = 8;
+ optional sfixed32 optional_sfixed32 = 9;
+ optional sfixed64 optional_sfixed64 = 10;
+ optional float optional_float = 11;
+ optional double optional_double = 12;
+ optional bool optional_bool = 13;
+ optional string optional_string = 14;
+ optional bytes optional_bytes = 15;
+
+ optional group OptionalGroup = 16 {
+ optional int32 a = 17;
+ }
+
+ optional NestedMessage optional_nested_message = 18;
+ optional ForeignMessageLite optional_foreign_message = 19;
+ optional protobuf_unittest_import.ImportMessageLite
+ optional_import_message = 20;
+
+ optional NestedEnum optional_nested_enum = 21;
+ optional ForeignEnumLite optional_foreign_enum = 22;
+ optional protobuf_unittest_import.ImportEnumLite optional_import_enum = 23;
+
+ optional string optional_string_piece = 24 [ctype=STRING_PIECE];
+ optional string optional_cord = 25 [ctype=CORD];
+
+ // Defined in unittest_import_public.proto
+ optional protobuf_unittest_import.PublicImportMessageLite
+ optional_public_import_message = 26;
+
+ optional NestedMessage optional_lazy_message = 27 [lazy=true];
+
+ // Repeated
+ repeated int32 repeated_int32 = 31;
+ repeated int64 repeated_int64 = 32;
+ repeated uint32 repeated_uint32 = 33;
+ repeated uint64 repeated_uint64 = 34;
+ repeated sint32 repeated_sint32 = 35;
+ repeated sint64 repeated_sint64 = 36;
+ repeated fixed32 repeated_fixed32 = 37;
+ repeated fixed64 repeated_fixed64 = 38;
+ repeated sfixed32 repeated_sfixed32 = 39;
+ repeated sfixed64 repeated_sfixed64 = 40;
+ repeated float repeated_float = 41;
+ repeated double repeated_double = 42;
+ repeated bool repeated_bool = 43;
+ repeated string repeated_string = 44;
+ repeated bytes repeated_bytes = 45;
+
+ repeated group RepeatedGroup = 46 {
+ optional int32 a = 47;
+ }
+
+ repeated NestedMessage repeated_nested_message = 48;
+ repeated ForeignMessageLite repeated_foreign_message = 49;
+ repeated protobuf_unittest_import.ImportMessageLite
+ repeated_import_message = 50;
+
+ repeated NestedEnum repeated_nested_enum = 51;
+ repeated ForeignEnumLite repeated_foreign_enum = 52;
+ repeated protobuf_unittest_import.ImportEnumLite repeated_import_enum = 53;
+
+ repeated string repeated_string_piece = 54 [ctype=STRING_PIECE];
+ repeated string repeated_cord = 55 [ctype=CORD];
+
+ repeated NestedMessage repeated_lazy_message = 57 [lazy=true];
+
+ // Singular with defaults
+ optional int32 default_int32 = 61 [default = 41 ];
+ optional int64 default_int64 = 62 [default = 42 ];
+ optional uint32 default_uint32 = 63 [default = 43 ];
+ optional uint64 default_uint64 = 64 [default = 44 ];
+ optional sint32 default_sint32 = 65 [default = -45 ];
+ optional sint64 default_sint64 = 66 [default = 46 ];
+ optional fixed32 default_fixed32 = 67 [default = 47 ];
+ optional fixed64 default_fixed64 = 68 [default = 48 ];
+ optional sfixed32 default_sfixed32 = 69 [default = 49 ];
+ optional sfixed64 default_sfixed64 = 70 [default = -50 ];
+ optional float default_float = 71 [default = 51.5 ];
+ optional double default_double = 72 [default = 52e3 ];
+ optional bool default_bool = 73 [default = true ];
+ optional string default_string = 74 [default = "hello"];
+ optional bytes default_bytes = 75 [default = "world"];
+
+ optional NestedEnum default_nested_enum = 81 [default = BAR];
+ optional ForeignEnumLite default_foreign_enum = 82
+ [default = FOREIGN_LITE_BAR];
+ optional protobuf_unittest_import.ImportEnumLite
+ default_import_enum = 83 [default = IMPORT_LITE_BAR];
+
+ optional string default_string_piece = 84 [ctype=STRING_PIECE,default="abc"];
+ optional string default_cord = 85 [ctype=CORD,default="123"];
+}
+
+message ForeignMessageLite {
+ optional int32 c = 1;
+}
+
+enum ForeignEnumLite {
+ FOREIGN_LITE_FOO = 4;
+ FOREIGN_LITE_BAR = 5;
+ FOREIGN_LITE_BAZ = 6;
+}
+
+message TestPackedTypesLite {
+ repeated int32 packed_int32 = 90 [packed = true];
+ repeated int64 packed_int64 = 91 [packed = true];
+ repeated uint32 packed_uint32 = 92 [packed = true];
+ repeated uint64 packed_uint64 = 93 [packed = true];
+ repeated sint32 packed_sint32 = 94 [packed = true];
+ repeated sint64 packed_sint64 = 95 [packed = true];
+ repeated fixed32 packed_fixed32 = 96 [packed = true];
+ repeated fixed64 packed_fixed64 = 97 [packed = true];
+ repeated sfixed32 packed_sfixed32 = 98 [packed = true];
+ repeated sfixed64 packed_sfixed64 = 99 [packed = true];
+ repeated float packed_float = 100 [packed = true];
+ repeated double packed_double = 101 [packed = true];
+ repeated bool packed_bool = 102 [packed = true];
+ repeated ForeignEnumLite packed_enum = 103 [packed = true];
+}
+
+message TestAllExtensionsLite {
+ extensions 1 to max;
+}
+
+extend TestAllExtensionsLite {
+ // Singular
+ optional int32 optional_int32_extension_lite = 1;
+ optional int64 optional_int64_extension_lite = 2;
+ optional uint32 optional_uint32_extension_lite = 3;
+ optional uint64 optional_uint64_extension_lite = 4;
+ optional sint32 optional_sint32_extension_lite = 5;
+ optional sint64 optional_sint64_extension_lite = 6;
+ optional fixed32 optional_fixed32_extension_lite = 7;
+ optional fixed64 optional_fixed64_extension_lite = 8;
+ optional sfixed32 optional_sfixed32_extension_lite = 9;
+ optional sfixed64 optional_sfixed64_extension_lite = 10;
+ optional float optional_float_extension_lite = 11;
+ optional double optional_double_extension_lite = 12;
+ optional bool optional_bool_extension_lite = 13;
+ optional string optional_string_extension_lite = 14;
+ optional bytes optional_bytes_extension_lite = 15;
+
+ optional group OptionalGroup_extension_lite = 16 {
+ optional int32 a = 17;
+ }
+
+ optional TestAllTypesLite.NestedMessage optional_nested_message_extension_lite
+ = 18;
+ optional ForeignMessageLite optional_foreign_message_extension_lite = 19;
+ optional protobuf_unittest_import.ImportMessageLite
+ optional_import_message_extension_lite = 20;
+
+ optional TestAllTypesLite.NestedEnum optional_nested_enum_extension_lite = 21;
+ optional ForeignEnumLite optional_foreign_enum_extension_lite = 22;
+ optional protobuf_unittest_import.ImportEnumLite
+ optional_import_enum_extension_lite = 23;
+
+ optional string optional_string_piece_extension_lite = 24
+ [ctype=STRING_PIECE];
+ optional string optional_cord_extension_lite = 25 [ctype=CORD];
+
+ optional protobuf_unittest_import.PublicImportMessageLite
+ optional_public_import_message_extension_lite = 26;
+
+ optional TestAllTypesLite.NestedMessage
+ optional_lazy_message_extension_lite = 27 [lazy=true];
+
+ // Repeated
+ repeated int32 repeated_int32_extension_lite = 31;
+ repeated int64 repeated_int64_extension_lite = 32;
+ repeated uint32 repeated_uint32_extension_lite = 33;
+ repeated uint64 repeated_uint64_extension_lite = 34;
+ repeated sint32 repeated_sint32_extension_lite = 35;
+ repeated sint64 repeated_sint64_extension_lite = 36;
+ repeated fixed32 repeated_fixed32_extension_lite = 37;
+ repeated fixed64 repeated_fixed64_extension_lite = 38;
+ repeated sfixed32 repeated_sfixed32_extension_lite = 39;
+ repeated sfixed64 repeated_sfixed64_extension_lite = 40;
+ repeated float repeated_float_extension_lite = 41;
+ repeated double repeated_double_extension_lite = 42;
+ repeated bool repeated_bool_extension_lite = 43;
+ repeated string repeated_string_extension_lite = 44;
+ repeated bytes repeated_bytes_extension_lite = 45;
+
+ repeated group RepeatedGroup_extension_lite = 46 {
+ optional int32 a = 47;
+ }
+
+ repeated TestAllTypesLite.NestedMessage repeated_nested_message_extension_lite
+ = 48;
+ repeated ForeignMessageLite repeated_foreign_message_extension_lite = 49;
+ repeated protobuf_unittest_import.ImportMessageLite
+ repeated_import_message_extension_lite = 50;
+
+ repeated TestAllTypesLite.NestedEnum repeated_nested_enum_extension_lite = 51;
+ repeated ForeignEnumLite repeated_foreign_enum_extension_lite = 52;
+ repeated protobuf_unittest_import.ImportEnumLite
+ repeated_import_enum_extension_lite = 53;
+
+ repeated string repeated_string_piece_extension_lite = 54
+ [ctype=STRING_PIECE];
+ repeated string repeated_cord_extension_lite = 55 [ctype=CORD];
+
+ repeated TestAllTypesLite.NestedMessage
+ repeated_lazy_message_extension_lite = 57 [lazy=true];
+
+ // Singular with defaults
+ optional int32 default_int32_extension_lite = 61 [default = 41 ];
+ optional int64 default_int64_extension_lite = 62 [default = 42 ];
+ optional uint32 default_uint32_extension_lite = 63 [default = 43 ];
+ optional uint64 default_uint64_extension_lite = 64 [default = 44 ];
+ optional sint32 default_sint32_extension_lite = 65 [default = -45 ];
+ optional sint64 default_sint64_extension_lite = 66 [default = 46 ];
+ optional fixed32 default_fixed32_extension_lite = 67 [default = 47 ];
+ optional fixed64 default_fixed64_extension_lite = 68 [default = 48 ];
+ optional sfixed32 default_sfixed32_extension_lite = 69 [default = 49 ];
+ optional sfixed64 default_sfixed64_extension_lite = 70 [default = -50 ];
+ optional float default_float_extension_lite = 71 [default = 51.5 ];
+ optional double default_double_extension_lite = 72 [default = 52e3 ];
+ optional bool default_bool_extension_lite = 73 [default = true ];
+ optional string default_string_extension_lite = 74 [default = "hello"];
+ optional bytes default_bytes_extension_lite = 75 [default = "world"];
+
+ optional TestAllTypesLite.NestedEnum
+ default_nested_enum_extension_lite = 81 [default = BAR];
+ optional ForeignEnumLite
+ default_foreign_enum_extension_lite = 82 [default = FOREIGN_LITE_BAR];
+ optional protobuf_unittest_import.ImportEnumLite
+ default_import_enum_extension_lite = 83 [default = IMPORT_LITE_BAR];
+
+ optional string default_string_piece_extension_lite = 84 [ctype=STRING_PIECE,
+ default="abc"];
+ optional string default_cord_extension_lite = 85 [ctype=CORD, default="123"];
+}
+
+message TestPackedExtensionsLite {
+ extensions 1 to max;
+}
+
+extend TestPackedExtensionsLite {
+ repeated int32 packed_int32_extension_lite = 90 [packed = true];
+ repeated int64 packed_int64_extension_lite = 91 [packed = true];
+ repeated uint32 packed_uint32_extension_lite = 92 [packed = true];
+ repeated uint64 packed_uint64_extension_lite = 93 [packed = true];
+ repeated sint32 packed_sint32_extension_lite = 94 [packed = true];
+ repeated sint64 packed_sint64_extension_lite = 95 [packed = true];
+ repeated fixed32 packed_fixed32_extension_lite = 96 [packed = true];
+ repeated fixed64 packed_fixed64_extension_lite = 97 [packed = true];
+ repeated sfixed32 packed_sfixed32_extension_lite = 98 [packed = true];
+ repeated sfixed64 packed_sfixed64_extension_lite = 99 [packed = true];
+ repeated float packed_float_extension_lite = 100 [packed = true];
+ repeated double packed_double_extension_lite = 101 [packed = true];
+ repeated bool packed_bool_extension_lite = 102 [packed = true];
+ repeated ForeignEnumLite packed_enum_extension_lite = 103 [packed = true];
+}
+
+message TestNestedExtensionLite {
+ extend TestAllExtensionsLite {
+ optional int32 nested_extension = 12345;
+ }
+}
+
+// Test that deprecated fields work. We only verify that they compile (at one
+// point this failed).
+message TestDeprecatedLite {
+ optional int32 deprecated_field = 1 [deprecated = true];
+}
+
+// See the comments of the same type in unittest.proto.
+message TestParsingMergeLite {
+ message RepeatedFieldsGenerator {
+ repeated TestAllTypesLite field1 = 1;
+ repeated TestAllTypesLite field2 = 2;
+ repeated TestAllTypesLite field3 = 3;
+ repeated group Group1 = 10 {
+ optional TestAllTypesLite field1 = 11;
+ }
+ repeated group Group2 = 20 {
+ optional TestAllTypesLite field1 = 21;
+ }
+ repeated TestAllTypesLite ext1 = 1000;
+ repeated TestAllTypesLite ext2 = 1001;
+ }
+ required TestAllTypesLite required_all_types = 1;
+ optional TestAllTypesLite optional_all_types = 2;
+ repeated TestAllTypesLite repeated_all_types = 3;
+ optional group OptionalGroup = 10 {
+ optional TestAllTypesLite optional_group_all_types = 11;
+ }
+ repeated group RepeatedGroup = 20 {
+ optional TestAllTypesLite repeated_group_all_types = 21;
+ }
+ extensions 1000 to max;
+ extend TestParsingMergeLite {
+ optional TestAllTypesLite optional_ext = 1000;
+ repeated TestAllTypesLite repeated_ext = 1001;
+ }
+}
diff --git a/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_lite_imports_nonlite.proto b/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_lite_imports_nonlite.proto
new file mode 100644
index 00000000..d52cb8cc
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_lite_imports_nonlite.proto
@@ -0,0 +1,43 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+// Author: kenton@google.com (Kenton Varda)
+//
+// Tests that a "lite" message can import a regular message.
+
+package protobuf_unittest;
+
+import "google/protobuf/unittest.proto";
+
+option optimize_for = LITE_RUNTIME;
+
+message TestLiteImportsNonlite {
+ optional TestAllTypes message = 1;
+}
diff --git a/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_mset.proto b/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_mset.proto
new file mode 100644
index 00000000..3497f09f
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_mset.proto
@@ -0,0 +1,72 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file contains messages for testing message_set_wire_format.
+
+package protobuf_unittest;
+
+option optimize_for = SPEED;
+
+// A message with message_set_wire_format.
+message TestMessageSet {
+ option message_set_wire_format = true;
+ extensions 4 to max;
+}
+
+message TestMessageSetContainer {
+ optional TestMessageSet message_set = 1;
+}
+
+message TestMessageSetExtension1 {
+ extend TestMessageSet {
+ optional TestMessageSetExtension1 message_set_extension = 1545008;
+ }
+ optional int32 i = 15;
+}
+
+message TestMessageSetExtension2 {
+ extend TestMessageSet {
+ optional TestMessageSetExtension2 message_set_extension = 1547769;
+ }
+ optional string str = 25;
+}
+
+// MessageSet wire format is equivalent to this.
+message RawMessageSet {
+ repeated group Item = 1 {
+ required int32 type_id = 2;
+ required bytes message = 3;
+ }
+}
+
diff --git a/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_no_generic_services.proto b/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_no_generic_services.proto
new file mode 100644
index 00000000..cffb4122
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_no_generic_services.proto
@@ -0,0 +1,52 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+// Author: kenton@google.com (Kenton Varda)
+
+package google.protobuf.no_generic_services_test;
+
+// *_generic_services are false by default.
+
+message TestMessage {
+ optional int32 a = 1;
+ extensions 1000 to max;
+}
+
+enum TestEnum {
+ FOO = 1;
+}
+
+extend TestMessage {
+ optional int32 test_extension = 1000;
+}
+
+service TestService {
+ rpc Foo(TestMessage) returns(TestMessage);
+}
diff --git a/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_optimize_for.proto b/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_optimize_for.proto
new file mode 100644
index 00000000..feecbef8
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/unittest_optimize_for.proto
@@ -0,0 +1,61 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// A proto file which uses optimize_for = CODE_SIZE.
+
+import "google/protobuf/unittest.proto";
+
+package protobuf_unittest;
+
+option optimize_for = CODE_SIZE;
+
+message TestOptimizedForSize {
+ optional int32 i = 1;
+ optional ForeignMessage msg = 19;
+
+ extensions 1000 to max;
+
+ extend TestOptimizedForSize {
+ optional int32 test_extension = 1234;
+ optional TestRequiredOptimizedForSize test_extension2 = 1235;
+ }
+}
+
+message TestRequiredOptimizedForSize {
+ required int32 x = 1;
+}
+
+message TestOptionalOptimizedForSize {
+ optional TestRequiredOptimizedForSize o = 1;
+}
diff --git a/java/compatibility_tests/v2.5.0/pom.xml b/java/compatibility_tests/v2.5.0/pom.xml
new file mode 100644
index 00000000..83a7563a
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/pom.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>com.google.protobuf.compatibility</groupId>
+ <artifactId>compatibility-test-suite</artifactId>
+ <version>2.5.0</version>
+ <name>Protocol Buffer Java API compatibility tests</name>
+ <packaging>pom</packaging>
+ <modules>
+ <module>protos</module>
+ <module>more_protos</module>
+ <module>tests</module>
+ </modules>
+ <properties>
+ <protoc.path>protoc</protoc.path>
+ <protobuf.version>2.5.0</protobuf.version>
+
+ <protos.protoc.path>${protoc.path}</protos.protoc.path>
+ <protos.protobuf.version>${protobuf.version}</protos.protobuf.version>
+
+ <more_protos.protoc.path>${protoc.path}</more_protos.protoc.path>
+ <more_protos.protobuf.version>${protobuf.version}</more_protos.protobuf.version>
+
+ <tests.protobuf.version>${protobuf.version}</tests.protobuf.version>
+
+ <protobuf.test.source.path>.</protobuf.test.source.path>
+ </properties>
+</project>
diff --git a/java/compatibility_tests/v2.5.0/protos/pom.xml b/java/compatibility_tests/v2.5.0/protos/pom.xml
new file mode 100644
index 00000000..24447bdc
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/protos/pom.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>com.google.protobuf.compatibility</groupId>
+ <artifactId>compatibility-test-suite</artifactId>
+ <version>2.5.0</version>
+ <relativePath>..</relativePath>
+ </parent>
+
+ <groupId>com.google.protobuf.compatibility</groupId>
+ <artifactId>compatibility-protos</artifactId>
+ <version>2.5.0</version>
+
+ <name>Protos for Compatibility test</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>com.google.protobuf</groupId>
+ <artifactId>protobuf-java</artifactId>
+ <version>${protos.protobuf.version}</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.3</version>
+ <configuration>
+ <source>1.6</source>
+ <target>1.6</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>generate-sources</id>
+ <phase>generate-sources</phase>
+ <configuration>
+ <tasks>
+ <mkdir dir="target/generated-sources" />
+ <exec executable="${protos.protoc.path}">
+ <arg value="--java_out=target/generated-sources" />
+ <arg value="--proto_path=src/proto" />
+ <arg value="src/proto/google/protobuf/unittest_custom_options.proto" />
+ <arg value="src/proto/google/protobuf/unittest_enormous_descriptor.proto" />
+ <arg value="src/proto/google/protobuf/unittest_import.proto" />
+ <arg value="src/proto/google/protobuf/unittest_import_public.proto" />
+ <arg value="src/proto/google/protobuf/unittest_mset.proto" />
+ <arg value="src/proto/google/protobuf/unittest_no_generic_services.proto" />
+ <arg value="src/proto/com/google/protobuf/nested_builders_test.proto" />
+ <arg value="src/proto/com/google/protobuf/nested_extension.proto" />
+ <arg value="src/proto/com/google/protobuf/non_nested_extension.proto" />
+ <arg value="src/proto/com/google/protobuf/test_bad_identifiers.proto" />
+ </exec>
+ </tasks>
+ <sourceRoot>target/generated-sources</sourceRoot>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/java/compatibility_tests/v2.5.0/protos/src/proto/com/google/protobuf/multiple_files_test.proto b/java/compatibility_tests/v2.5.0/protos/src/proto/com/google/protobuf/multiple_files_test.proto
new file mode 100644
index 00000000..9a040145
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/protos/src/proto/com/google/protobuf/multiple_files_test.proto
@@ -0,0 +1,71 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+// Author: kenton@google.com (Kenton Varda)
+//
+// A proto file which tests the java_multiple_files option.
+
+
+// Some generic_services option(s) added automatically.
+// See: http://go/proto2-generic-services-default
+option java_generic_services = true; // auto-added
+
+import "google/protobuf/unittest.proto";
+
+package protobuf_unittest;
+
+option java_multiple_files = true;
+option java_outer_classname = "MultipleFilesTestProto";
+
+message MessageWithNoOuter {
+ message NestedMessage {
+ optional int32 i = 1;
+ }
+ enum NestedEnum {
+ BAZ = 3;
+ }
+ optional NestedMessage nested = 1;
+ repeated TestAllTypes foreign = 2;
+ optional NestedEnum nested_enum = 3;
+ optional EnumWithNoOuter foreign_enum = 4;
+}
+
+enum EnumWithNoOuter {
+ FOO = 1;
+ BAR = 2;
+}
+
+service ServiceWithNoOuter {
+ rpc Foo(MessageWithNoOuter) returns(TestAllTypes);
+}
+
+extend TestAllExtensions {
+ optional int32 extension_with_outer = 1234567;
+}
diff --git a/java/compatibility_tests/v2.5.0/protos/src/proto/com/google/protobuf/nested_builders_test.proto b/java/compatibility_tests/v2.5.0/protos/src/proto/com/google/protobuf/nested_builders_test.proto
new file mode 100644
index 00000000..abffb9d2
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/protos/src/proto/com/google/protobuf/nested_builders_test.proto
@@ -0,0 +1,53 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+// Author: jonp@google.com (Jon Perlow)
+//
+
+package protobuf_unittest;
+
+option java_multiple_files = true;
+option java_outer_classname = "NestedBuilders";
+
+
+message Vehicle {
+ optional Engine engine = 1;
+ repeated Wheel wheel = 2;
+}
+
+message Engine {
+ optional int32 cylinder = 1;
+ optional int32 liters = 2;
+}
+
+message Wheel {
+ optional int32 radius = 1;
+ optional int32 width = 2;
+}
diff --git a/java/compatibility_tests/v2.5.0/protos/src/proto/com/google/protobuf/nested_extension.proto b/java/compatibility_tests/v2.5.0/protos/src/proto/com/google/protobuf/nested_extension.proto
new file mode 100644
index 00000000..9fe5d560
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/protos/src/proto/com/google/protobuf/nested_extension.proto
@@ -0,0 +1,45 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+// Author: Darick Tong (darick@google.com)
+//
+// A proto file with nested extensions. Note that this must be defined in
+// a separate file to properly test the initialization of the outer class.
+
+
+import "com/google/protobuf/non_nested_extension.proto";
+
+package protobuf_unittest;
+
+message MyNestedExtension {
+ extend MessageToBeExtended {
+ optional MessageToBeExtended recursiveExtension = 2;
+ }
+}
diff --git a/java/compatibility_tests/v2.5.0/protos/src/proto/com/google/protobuf/nested_extension_lite.proto b/java/compatibility_tests/v2.5.0/protos/src/proto/com/google/protobuf/nested_extension_lite.proto
new file mode 100644
index 00000000..16ee46e5
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/protos/src/proto/com/google/protobuf/nested_extension_lite.proto
@@ -0,0 +1,48 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+// Author: Darick Tong (darick@google.com)
+//
+// A proto file with nested extensions for a MessageLite messages. Note that
+// this must be defined in a separate file to properly test the initialization
+// of the outer class.
+
+
+package protobuf_unittest;
+
+option optimize_for = LITE_RUNTIME;
+
+import "com/google/protobuf/non_nested_extension_lite.proto";
+
+message MyNestedExtensionLite {
+ extend MessageLiteToBeExtended {
+ optional MessageLiteToBeExtended recursiveExtensionLite = 3;
+ }
+}
diff --git a/java/compatibility_tests/v2.5.0/protos/src/proto/com/google/protobuf/non_nested_extension.proto b/java/compatibility_tests/v2.5.0/protos/src/proto/com/google/protobuf/non_nested_extension.proto
new file mode 100644
index 00000000..f61b419b
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/protos/src/proto/com/google/protobuf/non_nested_extension.proto
@@ -0,0 +1,48 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+// Author: Darick Tong (darick@google.com)
+//
+// A proto file with extensions.
+
+
+package protobuf_unittest;
+
+message MessageToBeExtended {
+ extensions 1 to max;
+}
+
+message MyNonNestedExtension {
+}
+
+extend MessageToBeExtended {
+ optional MyNonNestedExtension nonNestedExtension = 1;
+}
+
diff --git a/java/compatibility_tests/v2.5.0/protos/src/proto/com/google/protobuf/non_nested_extension_lite.proto b/java/compatibility_tests/v2.5.0/protos/src/proto/com/google/protobuf/non_nested_extension_lite.proto
new file mode 100644
index 00000000..3c82659b
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/protos/src/proto/com/google/protobuf/non_nested_extension_lite.proto
@@ -0,0 +1,50 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+// Author: Darick Tong (darick@google.com)
+//
+// A proto file with extensions for a MessageLite messages.
+
+
+package protobuf_unittest;
+
+option optimize_for = LITE_RUNTIME;
+
+message MessageLiteToBeExtended {
+ extensions 1 to max;
+}
+
+message MyNonNestedExtensionLite {
+}
+
+extend MessageLiteToBeExtended {
+ optional MyNonNestedExtensionLite nonNestedExtensionLite = 1;
+}
+
diff --git a/java/compatibility_tests/v2.5.0/protos/src/proto/com/google/protobuf/test_bad_identifiers.proto b/java/compatibility_tests/v2.5.0/protos/src/proto/com/google/protobuf/test_bad_identifiers.proto
new file mode 100644
index 00000000..6e67d97a
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/protos/src/proto/com/google/protobuf/test_bad_identifiers.proto
@@ -0,0 +1,108 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+// Author: jonp@google.com (Jon Perlow)
+
+// This file tests that various identifiers work as field and type names even
+// though the same identifiers are used internally by the java code generator.
+
+
+// Some generic_services option(s) added automatically.
+// See: http://go/proto2-generic-services-default
+option java_generic_services = true; // auto-added
+
+package io_protocol_tests;
+
+option java_package = "com.google.protobuf";
+option java_outer_classname = "TestBadIdentifiersProto";
+
+message TestMessage {
+}
+
+message Descriptor {
+ option no_standard_descriptor_accessor = true;
+ optional string descriptor = 1;
+ message NestedDescriptor {
+ option no_standard_descriptor_accessor = true;
+ optional string descriptor = 1;
+ }
+ optional NestedDescriptor nested_descriptor = 2;
+}
+
+message Parser {
+ enum ParserEnum {
+ PARSER = 1;
+ }
+ optional ParserEnum parser = 1;
+}
+
+message Deprecated {
+ enum TestEnum {
+ FOO = 1;
+ }
+
+ optional int32 field1 = 1 [deprecated=true];
+ optional TestEnum field2 = 2 [deprecated=true];
+ optional TestMessage field3 = 3 [deprecated=true];
+}
+
+message Override {
+ optional int32 override = 1;
+}
+
+message Object {
+ optional int32 object = 1;
+ optional string string_object = 2;
+}
+
+message String {
+ optional string string = 1;
+}
+
+message Integer {
+ optional int32 integer = 1;
+}
+
+message Long {
+ optional int32 long = 1;
+}
+
+message Float {
+ optional float float = 1;
+}
+
+message Double {
+ optional double double = 1;
+}
+
+service TestConflictingMethodNames {
+ rpc Override(TestMessage) returns (TestMessage);
+}
+
diff --git a/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/descriptor.proto b/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/descriptor.proto
new file mode 100644
index 00000000..a785f79f
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/descriptor.proto
@@ -0,0 +1,620 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// The messages in this file describe the definitions found in .proto files.
+// A valid .proto file can be translated directly to a FileDescriptorProto
+// without any other information (e.g. without reading its imports).
+
+
+
+package google.protobuf;
+option java_package = "com.google.protobuf";
+option java_outer_classname = "DescriptorProtos";
+
+// descriptor.proto must be optimized for speed because reflection-based
+// algorithms don't work during bootstrapping.
+option optimize_for = SPEED;
+
+// The protocol compiler can output a FileDescriptorSet containing the .proto
+// files it parses.
+message FileDescriptorSet {
+ repeated FileDescriptorProto file = 1;
+}
+
+// Describes a complete .proto file.
+message FileDescriptorProto {
+ optional string name = 1; // file name, relative to root of source tree
+ optional string package = 2; // e.g. "foo", "foo.bar", etc.
+
+ // Names of files imported by this file.
+ repeated string dependency = 3;
+ // Indexes of the public imported files in the dependency list above.
+ repeated int32 public_dependency = 10;
+ // Indexes of the weak imported files in the dependency list.
+ // For Google-internal migration only. Do not use.
+ repeated int32 weak_dependency = 11;
+
+ // All top-level definitions in this file.
+ repeated DescriptorProto message_type = 4;
+ repeated EnumDescriptorProto enum_type = 5;
+ repeated ServiceDescriptorProto service = 6;
+ repeated FieldDescriptorProto extension = 7;
+
+ optional FileOptions options = 8;
+
+ // This field contains optional information about the original source code.
+ // You may safely remove this entire field whithout harming runtime
+ // functionality of the descriptors -- the information is needed only by
+ // development tools.
+ optional SourceCodeInfo source_code_info = 9;
+}
+
+// Describes a message type.
+message DescriptorProto {
+ optional string name = 1;
+
+ repeated FieldDescriptorProto field = 2;
+ repeated FieldDescriptorProto extension = 6;
+
+ repeated DescriptorProto nested_type = 3;
+ repeated EnumDescriptorProto enum_type = 4;
+
+ message ExtensionRange {
+ optional int32 start = 1;
+ optional int32 end = 2;
+ }
+ repeated ExtensionRange extension_range = 5;
+
+ optional MessageOptions options = 7;
+}
+
+// Describes a field within a message.
+message FieldDescriptorProto {
+ enum Type {
+ // 0 is reserved for errors.
+ // Order is weird for historical reasons.
+ TYPE_DOUBLE = 1;
+ TYPE_FLOAT = 2;
+ // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT64 if
+ // negative values are likely.
+ TYPE_INT64 = 3;
+ TYPE_UINT64 = 4;
+ // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT32 if
+ // negative values are likely.
+ TYPE_INT32 = 5;
+ TYPE_FIXED64 = 6;
+ TYPE_FIXED32 = 7;
+ TYPE_BOOL = 8;
+ TYPE_STRING = 9;
+ TYPE_GROUP = 10; // Tag-delimited aggregate.
+ TYPE_MESSAGE = 11; // Length-delimited aggregate.
+
+ // New in version 2.
+ TYPE_BYTES = 12;
+ TYPE_UINT32 = 13;
+ TYPE_ENUM = 14;
+ TYPE_SFIXED32 = 15;
+ TYPE_SFIXED64 = 16;
+ TYPE_SINT32 = 17; // Uses ZigZag encoding.
+ TYPE_SINT64 = 18; // Uses ZigZag encoding.
+ };
+
+ enum Label {
+ // 0 is reserved for errors
+ LABEL_OPTIONAL = 1;
+ LABEL_REQUIRED = 2;
+ LABEL_REPEATED = 3;
+ // TODO(sanjay): Should we add LABEL_MAP?
+ };
+
+ optional string name = 1;
+ optional int32 number = 3;
+ optional Label label = 4;
+
+ // If type_name is set, this need not be set. If both this and type_name
+ // are set, this must be either TYPE_ENUM or TYPE_MESSAGE.
+ optional Type type = 5;
+
+ // 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
+ // rules are used to find the type (i.e. first the nested types within this
+ // message are searched, then within the parent, on up to the root
+ // namespace).
+ optional string type_name = 6;
+
+ // For extensions, this is the name of the type being extended. It is
+ // resolved in the same manner as type_name.
+ optional string extendee = 2;
+
+ // For numeric types, contains the original text representation of the value.
+ // For booleans, "true" or "false".
+ // For strings, contains the default text contents (not escaped in any way).
+ // For bytes, contains the C escaped value. All bytes >= 128 are escaped.
+ // TODO(kenton): Base-64 encode?
+ optional string default_value = 7;
+
+ optional FieldOptions options = 8;
+}
+
+// Describes an enum type.
+message EnumDescriptorProto {
+ optional string name = 1;
+
+ repeated EnumValueDescriptorProto value = 2;
+
+ optional EnumOptions options = 3;
+}
+
+// Describes a value within an enum.
+message EnumValueDescriptorProto {
+ optional string name = 1;
+ optional int32 number = 2;
+
+ optional EnumValueOptions options = 3;
+}
+
+// Describes a service.
+message ServiceDescriptorProto {
+ optional string name = 1;
+ repeated MethodDescriptorProto method = 2;
+
+ optional ServiceOptions options = 3;
+}
+
+// Describes a method of a service.
+message MethodDescriptorProto {
+ optional string name = 1;
+
+ // Input and output type names. These are resolved in the same way as
+ // FieldDescriptorProto.type_name, but must refer to a message type.
+ optional string input_type = 2;
+ optional string output_type = 3;
+
+ optional MethodOptions options = 4;
+}
+
+
+// ===================================================================
+// Options
+
+// Each of the definitions above may have "options" attached. These are
+// just annotations which may cause code to be generated slightly differently
+// or may contain hints for code that manipulates protocol messages.
+//
+// Clients may define custom options as extensions of the *Options messages.
+// These extensions may not yet be known at parsing time, so the parser cannot
+// store the values in them. Instead it stores them in a field in the *Options
+// message called uninterpreted_option. This field must have the same name
+// across all *Options messages. We then use this field to populate the
+// extensions when we build a descriptor, at which point all protos have been
+// parsed and so all extensions are known.
+//
+// Extension numbers for custom options may be chosen as follows:
+// * For options which will only be used within a single application or
+// organization, or for experimental options, use field numbers 50000
+// through 99999. It is up to you to ensure that you do not use the
+// same number for multiple options.
+// * For options which will be published and used publicly by multiple
+// independent entities, e-mail protobuf-global-extension-registry@google.com
+// to reserve extension numbers. Simply provide your project name (e.g.
+// Object-C plugin) and your porject website (if available) -- there's no need
+// to explain how you intend to use them. Usually you only need one extension
+// number. You can declare multiple options with only one extension number by
+// putting them in a sub-message. See the Custom Options section of the docs
+// for examples:
+// http://code.google.com/apis/protocolbuffers/docs/proto.html#options
+// If this turns out to be popular, a web service will be set up
+// to automatically assign option numbers.
+
+
+message FileOptions {
+
+ // Sets the Java package where classes generated from this .proto will be
+ // placed. By default, the proto package is used, but this is often
+ // inappropriate because proto packages do not normally start with backwards
+ // domain names.
+ optional string java_package = 1;
+
+
+ // 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
+ // (equivalent to the old "--one_java_file" option) and Proto2 (where
+ // a .proto always translates to a single class, but you may want to
+ // explicitly choose the class name).
+ optional string java_outer_classname = 8;
+
+ // 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
+ // file. Thus, these types will *not* be nested inside the outer class
+ // named by java_outer_classname. However, the outer class will still be
+ // generated to contain the file's getDescriptor() method as well as any
+ // top-level extensions defined in the file.
+ optional bool java_multiple_files = 10 [default=false];
+
+ // If set true, then the Java code generator will generate equals() and
+ // hashCode() methods for all messages defined in the .proto file. This is
+ // purely a speed optimization, as the AbstractMessage base class includes
+ // reflection-based implementations of these methods.
+ optional bool java_generate_equals_and_hash = 20 [default=false];
+
+ // Generated classes can be optimized for speed or code size.
+ enum OptimizeMode {
+ SPEED = 1; // Generate complete code for parsing, serialization,
+ // etc.
+ CODE_SIZE = 2; // Use ReflectionOps to implement these methods.
+ LITE_RUNTIME = 3; // Generate code using MessageLite and the lite runtime.
+ }
+ optional OptimizeMode optimize_for = 9 [default=SPEED];
+
+ // Sets the Go package where structs generated from this .proto will be
+ // placed. There is no default.
+ optional string go_package = 11;
+
+
+
+ // Should generic services be generated in each language? "Generic" services
+ // are not specific to any particular RPC system. They are generated by the
+ // main code generators in each language (without additional plugins).
+ // Generic services were the only kind of service generation supported by
+ // early versions of proto2.
+ //
+ // Generic services are now considered deprecated in favor of using plugins
+ // that generate code specific to your particular RPC system. Therefore,
+ // these default to false. Old code which depends on generic services should
+ // explicitly set them to true.
+ optional bool cc_generic_services = 16 [default=false];
+ optional bool java_generic_services = 17 [default=false];
+ optional bool py_generic_services = 18 [default=false];
+
+ // The parser stores options it doesn't recognize here. See above.
+ repeated UninterpretedOption uninterpreted_option = 999;
+
+ // Clients can define custom options in extensions of this message. See above.
+ extensions 1000 to max;
+}
+
+message MessageOptions {
+ // Set true to use the old proto1 MessageSet wire format for extensions.
+ // This is provided for backwards-compatibility with the MessageSet wire
+ // format. You should not use this for any other reason: It's less
+ // efficient, has fewer features, and is more complicated.
+ //
+ // The message must be defined exactly as follows:
+ // message Foo {
+ // option message_set_wire_format = true;
+ // extensions 4 to max;
+ // }
+ // Note that the message cannot have any defined fields; MessageSets only
+ // have extensions.
+ //
+ // All extensions of your type must be singular messages; e.g. they cannot
+ // be int32s, enums, or repeated messages.
+ //
+ // Because this is an option, the above two restrictions are not enforced by
+ // the protocol compiler.
+ optional bool message_set_wire_format = 1 [default=false];
+
+ // Disables the generation of the standard "descriptor()" accessor, which can
+ // conflict with a field of the same name. This is meant to make migration
+ // from proto1 easier; new code should avoid fields named "descriptor".
+ optional bool no_standard_descriptor_accessor = 2 [default=false];
+
+ // The parser stores options it doesn't recognize here. See above.
+ repeated UninterpretedOption uninterpreted_option = 999;
+
+ // Clients can define custom options in extensions of this message. See above.
+ extensions 1000 to max;
+}
+
+message FieldOptions {
+ // The ctype option instructs the C++ code generator to use a different
+ // representation of the field than it normally would. See the specific
+ // options below. This option is not yet implemented in the open source
+ // release -- sorry, we'll try to include it in a future version!
+ optional CType ctype = 1 [default = STRING];
+ enum CType {
+ // Default mode.
+ STRING = 0;
+
+ CORD = 1;
+
+ STRING_PIECE = 2;
+ }
+ // The packed option can be enabled for repeated primitive fields to enable
+ // a more efficient representation on the wire. Rather than repeatedly
+ // writing the tag and type for each element, the entire array is encoded as
+ // a single length-delimited blob.
+ optional bool packed = 2;
+
+
+
+ // Should this field be parsed lazily? Lazy applies only to message-type
+ // fields. It means that when the outer message is initially parsed, the
+ // inner message's contents will not be parsed but instead stored in encoded
+ // form. The inner message will actually be parsed when it is first accessed.
+ //
+ // This is only a hint. Implementations are free to choose whether to use
+ // eager or lazy parsing regardless of the value of this option. However,
+ // setting this option true suggests that the protocol author believes that
+ // using lazy parsing on this field is worth the additional bookkeeping
+ // overhead typically needed to implement it.
+ //
+ // This option does not affect the public interface of any generated code;
+ // all method signatures remain the same. Furthermore, thread-safety of the
+ // interface is not affected by this option; const methods remain safe to
+ // call from multiple threads concurrently, while non-const methods continue
+ // to require exclusive access.
+ //
+ //
+ // Note that implementations may choose not to check required fields within
+ // a lazy sub-message. That is, calling IsInitialized() on the outher message
+ // may return true even if the inner message has missing required fields.
+ // This is necessary because otherwise the inner message would have to be
+ // parsed in order to perform the check, defeating the purpose of lazy
+ // parsing. An implementation which chooses not to check required fields
+ // must be consistent about it. That is, for any particular sub-message, the
+ // implementation must either *always* check its required fields, or *never*
+ // check its required fields, regardless of whether or not the message has
+ // been parsed.
+ optional bool lazy = 5 [default=false];
+
+ // Is this field deprecated?
+ // Depending on the target platform, this can emit Deprecated annotations
+ // for accessors, or it will be completely ignored; in the very least, this
+ // is a formalization for deprecating fields.
+ optional bool deprecated = 3 [default=false];
+
+ // EXPERIMENTAL. DO NOT USE.
+ // For "map" fields, the name of the field in the enclosed type that
+ // is the key for this map. For example, suppose we have:
+ // message Item {
+ // required string name = 1;
+ // required string value = 2;
+ // }
+ // message Config {
+ // repeated Item items = 1 [experimental_map_key="name"];
+ // }
+ // In this situation, the map key for Item will be set to "name".
+ // TODO: Fully-implement this, then remove the "experimental_" prefix.
+ optional string experimental_map_key = 9;
+
+ // For Google-internal migration only. Do not use.
+ optional bool weak = 10 [default=false];
+
+ // The parser stores options it doesn't recognize here. See above.
+ repeated UninterpretedOption uninterpreted_option = 999;
+
+ // Clients can define custom options in extensions of this message. See above.
+ extensions 1000 to max;
+}
+
+message EnumOptions {
+
+ // Set this option to false to disallow mapping different tag names to a same
+ // value.
+ optional bool allow_alias = 2 [default=true];
+
+ // The parser stores options it doesn't recognize here. See above.
+ repeated UninterpretedOption uninterpreted_option = 999;
+
+ // Clients can define custom options in extensions of this message. See above.
+ extensions 1000 to max;
+}
+
+message EnumValueOptions {
+ // The parser stores options it doesn't recognize here. See above.
+ repeated UninterpretedOption uninterpreted_option = 999;
+
+ // Clients can define custom options in extensions of this message. See above.
+ extensions 1000 to max;
+}
+
+message ServiceOptions {
+
+ // Note: Field numbers 1 through 32 are reserved for Google's internal RPC
+ // framework. We apologize for hoarding these numbers to ourselves, but
+ // we were already using them long before we decided to release Protocol
+ // Buffers.
+
+ // The parser stores options it doesn't recognize here. See above.
+ repeated UninterpretedOption uninterpreted_option = 999;
+
+ // Clients can define custom options in extensions of this message. See above.
+ extensions 1000 to max;
+}
+
+message MethodOptions {
+
+ // Note: Field numbers 1 through 32 are reserved for Google's internal RPC
+ // framework. We apologize for hoarding these numbers to ourselves, but
+ // we were already using them long before we decided to release Protocol
+ // Buffers.
+
+ // The parser stores options it doesn't recognize here. See above.
+ repeated UninterpretedOption uninterpreted_option = 999;
+
+ // Clients can define custom options in extensions of this message. See above.
+ extensions 1000 to max;
+}
+
+
+// A message representing a option the parser does not recognize. This only
+// appears in options protos created by the compiler::Parser class.
+// DescriptorPool resolves these when building Descriptor objects. Therefore,
+// options protos in descriptor objects (e.g. returned by Descriptor::options(),
+// or produced by Descriptor::CopyTo()) will never have UninterpretedOptions
+// in them.
+message UninterpretedOption {
+ // The name of the uninterpreted option. Each string represents a segment in
+ // a dot-separated name. is_extension is true iff a segment represents an
+ // extension (denoted with parentheses in options specs in .proto files).
+ // E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents
+ // "foo.(bar.baz).qux".
+ message NamePart {
+ required string name_part = 1;
+ required bool is_extension = 2;
+ }
+ repeated NamePart name = 2;
+
+ // The value of the uninterpreted option, in whatever type the tokenizer
+ // identified it as during parsing. Exactly one of these should be set.
+ optional string identifier_value = 3;
+ optional uint64 positive_int_value = 4;
+ optional int64 negative_int_value = 5;
+ optional double double_value = 6;
+ optional bytes string_value = 7;
+ optional string aggregate_value = 8;
+}
+
+// ===================================================================
+// Optional source code info
+
+// Encapsulates information about the original source file from which a
+// FileDescriptorProto was generated.
+message SourceCodeInfo {
+ // A Location identifies a piece of source code in a .proto file which
+ // corresponds to a particular definition. This information is intended
+ // to be useful to IDEs, code indexers, documentation generators, and similar
+ // tools.
+ //
+ // For example, say we have a file like:
+ // message Foo {
+ // optional string foo = 1;
+ // }
+ // Let's look at just the field definition:
+ // optional string foo = 1;
+ // ^ ^^ ^^ ^ ^^^
+ // a bc de f ghi
+ // We have the following locations:
+ // span path represents
+ // [a,i) [ 4, 0, 2, 0 ] The whole field definition.
+ // [a,b) [ 4, 0, 2, 0, 4 ] The label (optional).
+ // [c,d) [ 4, 0, 2, 0, 5 ] The type (string).
+ // [e,f) [ 4, 0, 2, 0, 1 ] The name (foo).
+ // [g,h) [ 4, 0, 2, 0, 3 ] The number (1).
+ //
+ // Notes:
+ // - A location may refer to a repeated field itself (i.e. not to any
+ // particular index within it). This is used whenever a set of elements are
+ // logically enclosed in a single code segment. For example, an entire
+ // extend block (possibly containing multiple extension definitions) will
+ // have an outer location whose path refers to the "extensions" repeated
+ // field without an index.
+ // - Multiple locations may have the same path. This happens when a single
+ // logical declaration is spread out across multiple places. The most
+ // obvious example is the "extend" block again -- there may be multiple
+ // extend blocks in the same scope, each of which will have the same path.
+ // - A location's span is not always a subset of its parent's span. For
+ // example, the "extendee" of an extension declaration appears at the
+ // beginning of the "extend" block and is shared by all extensions within
+ // the block.
+ // - Just because a location's span is a subset of some other location's span
+ // does not mean that it is a descendent. For example, a "group" defines
+ // both a type and a field in a single declaration. Thus, the locations
+ // corresponding to the type and field and their components will overlap.
+ // - Code which tries to interpret locations should probably be designed to
+ // ignore those that it doesn't understand, as more types of locations could
+ // be recorded in the future.
+ repeated Location location = 1;
+ message Location {
+ // Identifies which part of the FileDescriptorProto was defined at this
+ // location.
+ //
+ // Each element is a field number or an index. They form a path from
+ // the root FileDescriptorProto to the place where the definition. For
+ // example, this path:
+ // [ 4, 3, 2, 7, 1 ]
+ // refers to:
+ // file.message_type(3) // 4, 3
+ // .field(7) // 2, 7
+ // .name() // 1
+ // This is because FileDescriptorProto.message_type has field number 4:
+ // repeated DescriptorProto message_type = 4;
+ // and DescriptorProto.field has field number 2:
+ // repeated FieldDescriptorProto field = 2;
+ // and FieldDescriptorProto.name has field number 1:
+ // optional string name = 1;
+ //
+ // Thus, the above path gives the location of a field name. If we removed
+ // the last element:
+ // [ 4, 3, 2, 7 ]
+ // this path refers to the whole field declaration (from the beginning
+ // of the label to the terminating semicolon).
+ repeated int32 path = 1 [packed=true];
+
+ // Always has exactly three or four elements: start line, start column,
+ // end line (optional, otherwise assumed same as start line), end column.
+ // These are packed into a single field for efficiency. Note that line
+ // and column numbers are zero-based -- typically you will want to add
+ // 1 to each before displaying to a user.
+ repeated int32 span = 2 [packed=true];
+
+ // If this SourceCodeInfo represents a complete declaration, these are any
+ // comments appearing before and after the declaration which appear to be
+ // attached to the declaration.
+ //
+ // A series of line comments appearing on consecutive lines, with no other
+ // tokens appearing on those lines, will be treated as a single comment.
+ //
+ // Only the comment content is provided; comment markers (e.g. //) are
+ // stripped out. For block comments, leading whitespace and an asterisk
+ // will be stripped from the beginning of each line other than the first.
+ // Newlines are included in the output.
+ //
+ // Examples:
+ //
+ // optional int32 foo = 1; // Comment attached to foo.
+ // // Comment attached to bar.
+ // optional int32 bar = 2;
+ //
+ // optional string baz = 3;
+ // // Comment attached to baz.
+ // // Another line attached to baz.
+ //
+ // // Comment attached to qux.
+ // //
+ // // Another line attached to qux.
+ // optional double qux = 4;
+ //
+ // optional string corge = 5;
+ // /* Block comment attached
+ // * to corge. Leading asterisks
+ // * will be removed. */
+ // /* Block comment attached to
+ // * grault. */
+ // optional int32 grault = 6;
+ optional string leading_comments = 3;
+ optional string trailing_comments = 4;
+ }
+}
diff --git a/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest.proto b/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest.proto
new file mode 100644
index 00000000..6eb2d86f
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest.proto
@@ -0,0 +1,719 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// A proto file we will use for unit testing.
+
+
+// Some generic_services option(s) added automatically.
+// See: http://go/proto2-generic-services-default
+option cc_generic_services = true; // auto-added
+option java_generic_services = true; // auto-added
+option py_generic_services = true; // auto-added
+
+import "google/protobuf/unittest_import.proto";
+
+// We don't put this in a package within proto2 because we need to make sure
+// that the generated code doesn't depend on being in the proto2 namespace.
+// In test_util.h we do "using namespace unittest = protobuf_unittest".
+package protobuf_unittest;
+
+// Protos optimized for SPEED use a strict superset of the generated code
+// of equivalent ones optimized for CODE_SIZE, so we should optimize all our
+// tests for speed unless explicitly testing code size optimization.
+option optimize_for = SPEED;
+
+option java_outer_classname = "UnittestProto";
+
+// This proto includes every type of field in both singular and repeated
+// forms.
+message TestAllTypes {
+ message NestedMessage {
+ // The field name "b" fails to compile in proto1 because it conflicts with
+ // a local variable named "b" in one of the generated methods. Doh.
+ // This file needs to compile in proto1 to test backwards-compatibility.
+ optional int32 bb = 1;
+ }
+
+ enum NestedEnum {
+ FOO = 1;
+ BAR = 2;
+ BAZ = 3;
+ }
+
+ // Singular
+ optional int32 optional_int32 = 1;
+ optional int64 optional_int64 = 2;
+ optional uint32 optional_uint32 = 3;
+ optional uint64 optional_uint64 = 4;
+ optional sint32 optional_sint32 = 5;
+ optional sint64 optional_sint64 = 6;
+ optional fixed32 optional_fixed32 = 7;
+ optional fixed64 optional_fixed64 = 8;
+ optional sfixed32 optional_sfixed32 = 9;
+ optional sfixed64 optional_sfixed64 = 10;
+ optional float optional_float = 11;
+ optional double optional_double = 12;
+ optional bool optional_bool = 13;
+ optional string optional_string = 14;
+ optional bytes optional_bytes = 15;
+
+ optional group OptionalGroup = 16 {
+ optional int32 a = 17;
+ }
+
+ optional NestedMessage optional_nested_message = 18;
+ optional ForeignMessage optional_foreign_message = 19;
+ optional protobuf_unittest_import.ImportMessage optional_import_message = 20;
+
+ optional NestedEnum optional_nested_enum = 21;
+ optional ForeignEnum optional_foreign_enum = 22;
+ optional protobuf_unittest_import.ImportEnum optional_import_enum = 23;
+
+ optional string optional_string_piece = 24 [ctype=STRING_PIECE];
+ optional string optional_cord = 25 [ctype=CORD];
+
+ // Defined in unittest_import_public.proto
+ optional protobuf_unittest_import.PublicImportMessage
+ optional_public_import_message = 26;
+
+ optional NestedMessage optional_lazy_message = 27 [lazy=true];
+
+ // Repeated
+ repeated int32 repeated_int32 = 31;
+ repeated int64 repeated_int64 = 32;
+ repeated uint32 repeated_uint32 = 33;
+ repeated uint64 repeated_uint64 = 34;
+ repeated sint32 repeated_sint32 = 35;
+ repeated sint64 repeated_sint64 = 36;
+ repeated fixed32 repeated_fixed32 = 37;
+ repeated fixed64 repeated_fixed64 = 38;
+ repeated sfixed32 repeated_sfixed32 = 39;
+ repeated sfixed64 repeated_sfixed64 = 40;
+ repeated float repeated_float = 41;
+ repeated double repeated_double = 42;
+ repeated bool repeated_bool = 43;
+ repeated string repeated_string = 44;
+ repeated bytes repeated_bytes = 45;
+
+ repeated group RepeatedGroup = 46 {
+ optional int32 a = 47;
+ }
+
+ repeated NestedMessage repeated_nested_message = 48;
+ repeated ForeignMessage repeated_foreign_message = 49;
+ repeated protobuf_unittest_import.ImportMessage repeated_import_message = 50;
+
+ repeated NestedEnum repeated_nested_enum = 51;
+ repeated ForeignEnum repeated_foreign_enum = 52;
+ repeated protobuf_unittest_import.ImportEnum repeated_import_enum = 53;
+
+ repeated string repeated_string_piece = 54 [ctype=STRING_PIECE];
+ repeated string repeated_cord = 55 [ctype=CORD];
+
+ repeated NestedMessage repeated_lazy_message = 57 [lazy=true];
+
+ // Singular with defaults
+ optional int32 default_int32 = 61 [default = 41 ];
+ optional int64 default_int64 = 62 [default = 42 ];
+ optional uint32 default_uint32 = 63 [default = 43 ];
+ optional uint64 default_uint64 = 64 [default = 44 ];
+ optional sint32 default_sint32 = 65 [default = -45 ];
+ optional sint64 default_sint64 = 66 [default = 46 ];
+ optional fixed32 default_fixed32 = 67 [default = 47 ];
+ optional fixed64 default_fixed64 = 68 [default = 48 ];
+ optional sfixed32 default_sfixed32 = 69 [default = 49 ];
+ optional sfixed64 default_sfixed64 = 70 [default = -50 ];
+ optional float default_float = 71 [default = 51.5 ];
+ optional double default_double = 72 [default = 52e3 ];
+ optional bool default_bool = 73 [default = true ];
+ optional string default_string = 74 [default = "hello"];
+ optional bytes default_bytes = 75 [default = "world"];
+
+ optional NestedEnum default_nested_enum = 81 [default = BAR ];
+ optional ForeignEnum default_foreign_enum = 82 [default = FOREIGN_BAR];
+ optional protobuf_unittest_import.ImportEnum
+ default_import_enum = 83 [default = IMPORT_BAR];
+
+ optional string default_string_piece = 84 [ctype=STRING_PIECE,default="abc"];
+ optional string default_cord = 85 [ctype=CORD,default="123"];
+}
+
+message TestDeprecatedFields {
+ optional int32 deprecated_int32 = 1 [deprecated=true];
+}
+
+// Define these after TestAllTypes to make sure the compiler can handle
+// that.
+message ForeignMessage {
+ optional int32 c = 1;
+}
+
+enum ForeignEnum {
+ FOREIGN_FOO = 4;
+ FOREIGN_BAR = 5;
+ FOREIGN_BAZ = 6;
+}
+
+message TestAllExtensions {
+ extensions 1 to max;
+}
+
+extend TestAllExtensions {
+ // Singular
+ optional int32 optional_int32_extension = 1;
+ optional int64 optional_int64_extension = 2;
+ optional uint32 optional_uint32_extension = 3;
+ optional uint64 optional_uint64_extension = 4;
+ optional sint32 optional_sint32_extension = 5;
+ optional sint64 optional_sint64_extension = 6;
+ optional fixed32 optional_fixed32_extension = 7;
+ optional fixed64 optional_fixed64_extension = 8;
+ optional sfixed32 optional_sfixed32_extension = 9;
+ optional sfixed64 optional_sfixed64_extension = 10;
+ optional float optional_float_extension = 11;
+ optional double optional_double_extension = 12;
+ optional bool optional_bool_extension = 13;
+ optional string optional_string_extension = 14;
+ optional bytes optional_bytes_extension = 15;
+
+ optional group OptionalGroup_extension = 16 {
+ optional int32 a = 17;
+ }
+
+ optional TestAllTypes.NestedMessage optional_nested_message_extension = 18;
+ optional ForeignMessage optional_foreign_message_extension = 19;
+ optional protobuf_unittest_import.ImportMessage
+ optional_import_message_extension = 20;
+
+ optional TestAllTypes.NestedEnum optional_nested_enum_extension = 21;
+ optional ForeignEnum optional_foreign_enum_extension = 22;
+ optional protobuf_unittest_import.ImportEnum
+ optional_import_enum_extension = 23;
+
+ optional string optional_string_piece_extension = 24 [ctype=STRING_PIECE];
+ optional string optional_cord_extension = 25 [ctype=CORD];
+
+ optional protobuf_unittest_import.PublicImportMessage
+ optional_public_import_message_extension = 26;
+
+ optional TestAllTypes.NestedMessage
+ optional_lazy_message_extension = 27 [lazy=true];
+
+ // Repeated
+ repeated int32 repeated_int32_extension = 31;
+ repeated int64 repeated_int64_extension = 32;
+ repeated uint32 repeated_uint32_extension = 33;
+ repeated uint64 repeated_uint64_extension = 34;
+ repeated sint32 repeated_sint32_extension = 35;
+ repeated sint64 repeated_sint64_extension = 36;
+ repeated fixed32 repeated_fixed32_extension = 37;
+ repeated fixed64 repeated_fixed64_extension = 38;
+ repeated sfixed32 repeated_sfixed32_extension = 39;
+ repeated sfixed64 repeated_sfixed64_extension = 40;
+ repeated float repeated_float_extension = 41;
+ repeated double repeated_double_extension = 42;
+ repeated bool repeated_bool_extension = 43;
+ repeated string repeated_string_extension = 44;
+ repeated bytes repeated_bytes_extension = 45;
+
+ repeated group RepeatedGroup_extension = 46 {
+ optional int32 a = 47;
+ }
+
+ repeated TestAllTypes.NestedMessage repeated_nested_message_extension = 48;
+ repeated ForeignMessage repeated_foreign_message_extension = 49;
+ repeated protobuf_unittest_import.ImportMessage
+ repeated_import_message_extension = 50;
+
+ repeated TestAllTypes.NestedEnum repeated_nested_enum_extension = 51;
+ repeated ForeignEnum repeated_foreign_enum_extension = 52;
+ repeated protobuf_unittest_import.ImportEnum
+ repeated_import_enum_extension = 53;
+
+ repeated string repeated_string_piece_extension = 54 [ctype=STRING_PIECE];
+ repeated string repeated_cord_extension = 55 [ctype=CORD];
+
+ repeated TestAllTypes.NestedMessage
+ repeated_lazy_message_extension = 57 [lazy=true];
+
+ // Singular with defaults
+ optional int32 default_int32_extension = 61 [default = 41 ];
+ optional int64 default_int64_extension = 62 [default = 42 ];
+ optional uint32 default_uint32_extension = 63 [default = 43 ];
+ optional uint64 default_uint64_extension = 64 [default = 44 ];
+ optional sint32 default_sint32_extension = 65 [default = -45 ];
+ optional sint64 default_sint64_extension = 66 [default = 46 ];
+ optional fixed32 default_fixed32_extension = 67 [default = 47 ];
+ optional fixed64 default_fixed64_extension = 68 [default = 48 ];
+ optional sfixed32 default_sfixed32_extension = 69 [default = 49 ];
+ optional sfixed64 default_sfixed64_extension = 70 [default = -50 ];
+ optional float default_float_extension = 71 [default = 51.5 ];
+ optional double default_double_extension = 72 [default = 52e3 ];
+ optional bool default_bool_extension = 73 [default = true ];
+ optional string default_string_extension = 74 [default = "hello"];
+ optional bytes default_bytes_extension = 75 [default = "world"];
+
+ optional TestAllTypes.NestedEnum
+ default_nested_enum_extension = 81 [default = BAR];
+ optional ForeignEnum
+ default_foreign_enum_extension = 82 [default = FOREIGN_BAR];
+ optional protobuf_unittest_import.ImportEnum
+ default_import_enum_extension = 83 [default = IMPORT_BAR];
+
+ optional string default_string_piece_extension = 84 [ctype=STRING_PIECE,
+ default="abc"];
+ optional string default_cord_extension = 85 [ctype=CORD, default="123"];
+}
+
+message TestNestedExtension {
+ extend TestAllExtensions {
+ // Check for bug where string extensions declared in tested scope did not
+ // compile.
+ optional string test = 1002 [default="test"];
+ }
+}
+
+// We have separate messages for testing required fields because it's
+// annoying to have to fill in required fields in TestProto in order to
+// do anything with it. Note that we don't need to test every type of
+// required filed because the code output is basically identical to
+// optional fields for all types.
+message TestRequired {
+ required int32 a = 1;
+ optional int32 dummy2 = 2;
+ required int32 b = 3;
+
+ extend TestAllExtensions {
+ optional TestRequired single = 1000;
+ repeated TestRequired multi = 1001;
+ }
+
+ // Pad the field count to 32 so that we can test that IsInitialized()
+ // properly checks multiple elements of has_bits_.
+ optional int32 dummy4 = 4;
+ optional int32 dummy5 = 5;
+ optional int32 dummy6 = 6;
+ optional int32 dummy7 = 7;
+ optional int32 dummy8 = 8;
+ optional int32 dummy9 = 9;
+ optional int32 dummy10 = 10;
+ optional int32 dummy11 = 11;
+ optional int32 dummy12 = 12;
+ optional int32 dummy13 = 13;
+ optional int32 dummy14 = 14;
+ optional int32 dummy15 = 15;
+ optional int32 dummy16 = 16;
+ optional int32 dummy17 = 17;
+ optional int32 dummy18 = 18;
+ optional int32 dummy19 = 19;
+ optional int32 dummy20 = 20;
+ optional int32 dummy21 = 21;
+ optional int32 dummy22 = 22;
+ optional int32 dummy23 = 23;
+ optional int32 dummy24 = 24;
+ optional int32 dummy25 = 25;
+ optional int32 dummy26 = 26;
+ optional int32 dummy27 = 27;
+ optional int32 dummy28 = 28;
+ optional int32 dummy29 = 29;
+ optional int32 dummy30 = 30;
+ optional int32 dummy31 = 31;
+ optional int32 dummy32 = 32;
+
+ required int32 c = 33;
+}
+
+message TestRequiredForeign {
+ optional TestRequired optional_message = 1;
+ repeated TestRequired repeated_message = 2;
+ optional int32 dummy = 3;
+}
+
+// Test that we can use NestedMessage from outside TestAllTypes.
+message TestForeignNested {
+ optional TestAllTypes.NestedMessage foreign_nested = 1;
+}
+
+// TestEmptyMessage is used to test unknown field support.
+message TestEmptyMessage {
+}
+
+// Like above, but declare all field numbers as potential extensions. No
+// actual extensions should ever be defined for this type.
+message TestEmptyMessageWithExtensions {
+ extensions 1 to max;
+}
+
+message TestMultipleExtensionRanges {
+ extensions 42;
+ extensions 4143 to 4243;
+ extensions 65536 to max;
+}
+
+// Test that really large tag numbers don't break anything.
+message TestReallyLargeTagNumber {
+ // The largest possible tag number is 2^28 - 1, since the wire format uses
+ // three bits to communicate wire type.
+ optional int32 a = 1;
+ optional int32 bb = 268435455;
+}
+
+message TestRecursiveMessage {
+ optional TestRecursiveMessage a = 1;
+ optional int32 i = 2;
+}
+
+// Test that mutual recursion works.
+message TestMutualRecursionA {
+ optional TestMutualRecursionB bb = 1;
+}
+
+message TestMutualRecursionB {
+ optional TestMutualRecursionA a = 1;
+ optional int32 optional_int32 = 2;
+}
+
+// Test that groups have disjoint field numbers from their siblings and
+// parents. This is NOT possible in proto1; only proto2. When attempting
+// to compile with proto1, this will emit an error; so we only include it
+// in protobuf_unittest_proto.
+message TestDupFieldNumber { // NO_PROTO1
+ optional int32 a = 1; // NO_PROTO1
+ optional group Foo = 2 { optional int32 a = 1; } // NO_PROTO1
+ optional group Bar = 3 { optional int32 a = 1; } // NO_PROTO1
+} // NO_PROTO1
+
+// Additional messages for testing lazy fields.
+message TestEagerMessage {
+ optional TestAllTypes sub_message = 1 [lazy=false];
+}
+message TestLazyMessage {
+ optional TestAllTypes sub_message = 1 [lazy=true];
+}
+
+// Needed for a Python test.
+message TestNestedMessageHasBits {
+ message NestedMessage {
+ repeated int32 nestedmessage_repeated_int32 = 1;
+ repeated ForeignMessage nestedmessage_repeated_foreignmessage = 2;
+ }
+ optional NestedMessage optional_nested_message = 1;
+}
+
+
+// Test an enum that has multiple values with the same number.
+enum TestEnumWithDupValue {
+ option allow_alias = true;
+ FOO1 = 1;
+ BAR1 = 2;
+ BAZ = 3;
+ FOO2 = 1;
+ BAR2 = 2;
+}
+
+// Test an enum with large, unordered values.
+enum TestSparseEnum {
+ SPARSE_A = 123;
+ SPARSE_B = 62374;
+ SPARSE_C = 12589234;
+ SPARSE_D = -15;
+ SPARSE_E = -53452;
+ SPARSE_F = 0;
+ SPARSE_G = 2;
+}
+
+// Test message with CamelCase field names. This violates Protocol Buffer
+// standard style.
+message TestCamelCaseFieldNames {
+ optional int32 PrimitiveField = 1;
+ optional string StringField = 2;
+ optional ForeignEnum EnumField = 3;
+ optional ForeignMessage MessageField = 4;
+ optional string StringPieceField = 5 [ctype=STRING_PIECE];
+ optional string CordField = 6 [ctype=CORD];
+
+ repeated int32 RepeatedPrimitiveField = 7;
+ repeated string RepeatedStringField = 8;
+ repeated ForeignEnum RepeatedEnumField = 9;
+ repeated ForeignMessage RepeatedMessageField = 10;
+ repeated string RepeatedStringPieceField = 11 [ctype=STRING_PIECE];
+ repeated string RepeatedCordField = 12 [ctype=CORD];
+}
+
+
+// We list fields out of order, to ensure that we're using field number and not
+// field index to determine serialization order.
+message TestFieldOrderings {
+ optional string my_string = 11;
+ extensions 2 to 10;
+ optional int64 my_int = 1;
+ extensions 12 to 100;
+ optional float my_float = 101;
+}
+
+
+extend TestFieldOrderings {
+ optional string my_extension_string = 50;
+ optional int32 my_extension_int = 5;
+}
+
+
+message TestExtremeDefaultValues {
+ optional bytes escaped_bytes = 1 [default = "\0\001\a\b\f\n\r\t\v\\\'\"\xfe"];
+ optional uint32 large_uint32 = 2 [default = 0xFFFFFFFF];
+ optional uint64 large_uint64 = 3 [default = 0xFFFFFFFFFFFFFFFF];
+ optional int32 small_int32 = 4 [default = -0x7FFFFFFF];
+ optional int64 small_int64 = 5 [default = -0x7FFFFFFFFFFFFFFF];
+ optional int32 really_small_int32 = 21 [default = -0x80000000];
+ optional int64 really_small_int64 = 22 [default = -0x8000000000000000];
+
+ // The default value here is UTF-8 for "\u1234". (We could also just type
+ // the UTF-8 text directly into this text file rather than escape it, but
+ // lots of people use editors that would be confused by this.)
+ optional string utf8_string = 6 [default = "\341\210\264"];
+
+ // Tests for single-precision floating-point values.
+ optional float zero_float = 7 [default = 0];
+ optional float one_float = 8 [default = 1];
+ optional float small_float = 9 [default = 1.5];
+ optional float negative_one_float = 10 [default = -1];
+ optional float negative_float = 11 [default = -1.5];
+ // Using exponents
+ optional float large_float = 12 [default = 2E8];
+ optional float small_negative_float = 13 [default = -8e-28];
+
+ // Text for nonfinite floating-point values.
+ optional double inf_double = 14 [default = inf];
+ optional double neg_inf_double = 15 [default = -inf];
+ optional double nan_double = 16 [default = nan];
+ optional float inf_float = 17 [default = inf];
+ optional float neg_inf_float = 18 [default = -inf];
+ optional float nan_float = 19 [default = nan];
+
+ // Tests for C++ trigraphs.
+ // Trigraphs should be escaped in C++ generated files, but they should not be
+ // escaped for other languages.
+ // Note that in .proto file, "\?" is a valid way to escape ? in string
+ // literals.
+ optional string cpp_trigraph = 20 [default = "? \? ?? \?? \??? ??/ ?\?-"];
+
+ // String defaults containing the character '\000'
+ optional string string_with_zero = 23 [default = "hel\000lo"];
+ optional bytes bytes_with_zero = 24 [default = "wor\000ld"];
+ optional string string_piece_with_zero = 25 [ctype=STRING_PIECE,
+ default="ab\000c"];
+ optional string cord_with_zero = 26 [ctype=CORD,
+ default="12\0003"];
+}
+
+message SparseEnumMessage {
+ optional TestSparseEnum sparse_enum = 1;
+}
+
+// Test String and Bytes: string is for valid UTF-8 strings
+message OneString {
+ optional string data = 1;
+}
+
+message MoreString {
+ repeated string data = 1;
+}
+
+message OneBytes {
+ optional bytes data = 1;
+}
+
+message MoreBytes {
+ repeated bytes data = 1;
+}
+
+
+// Test messages for packed fields
+
+message TestPackedTypes {
+ repeated int32 packed_int32 = 90 [packed = true];
+ repeated int64 packed_int64 = 91 [packed = true];
+ repeated uint32 packed_uint32 = 92 [packed = true];
+ repeated uint64 packed_uint64 = 93 [packed = true];
+ repeated sint32 packed_sint32 = 94 [packed = true];
+ repeated sint64 packed_sint64 = 95 [packed = true];
+ repeated fixed32 packed_fixed32 = 96 [packed = true];
+ repeated fixed64 packed_fixed64 = 97 [packed = true];
+ repeated sfixed32 packed_sfixed32 = 98 [packed = true];
+ repeated sfixed64 packed_sfixed64 = 99 [packed = true];
+ repeated float packed_float = 100 [packed = true];
+ repeated double packed_double = 101 [packed = true];
+ repeated bool packed_bool = 102 [packed = true];
+ repeated ForeignEnum packed_enum = 103 [packed = true];
+}
+
+// A message with the same fields as TestPackedTypes, but without packing. Used
+// to test packed <-> unpacked wire compatibility.
+message TestUnpackedTypes {
+ repeated int32 unpacked_int32 = 90 [packed = false];
+ repeated int64 unpacked_int64 = 91 [packed = false];
+ repeated uint32 unpacked_uint32 = 92 [packed = false];
+ repeated uint64 unpacked_uint64 = 93 [packed = false];
+ repeated sint32 unpacked_sint32 = 94 [packed = false];
+ repeated sint64 unpacked_sint64 = 95 [packed = false];
+ repeated fixed32 unpacked_fixed32 = 96 [packed = false];
+ repeated fixed64 unpacked_fixed64 = 97 [packed = false];
+ repeated sfixed32 unpacked_sfixed32 = 98 [packed = false];
+ repeated sfixed64 unpacked_sfixed64 = 99 [packed = false];
+ repeated float unpacked_float = 100 [packed = false];
+ repeated double unpacked_double = 101 [packed = false];
+ repeated bool unpacked_bool = 102 [packed = false];
+ repeated ForeignEnum unpacked_enum = 103 [packed = false];
+}
+
+message TestPackedExtensions {
+ extensions 1 to max;
+}
+
+extend TestPackedExtensions {
+ repeated int32 packed_int32_extension = 90 [packed = true];
+ repeated int64 packed_int64_extension = 91 [packed = true];
+ repeated uint32 packed_uint32_extension = 92 [packed = true];
+ repeated uint64 packed_uint64_extension = 93 [packed = true];
+ repeated sint32 packed_sint32_extension = 94 [packed = true];
+ repeated sint64 packed_sint64_extension = 95 [packed = true];
+ repeated fixed32 packed_fixed32_extension = 96 [packed = true];
+ repeated fixed64 packed_fixed64_extension = 97 [packed = true];
+ repeated sfixed32 packed_sfixed32_extension = 98 [packed = true];
+ repeated sfixed64 packed_sfixed64_extension = 99 [packed = true];
+ repeated float packed_float_extension = 100 [packed = true];
+ repeated double packed_double_extension = 101 [packed = true];
+ repeated bool packed_bool_extension = 102 [packed = true];
+ repeated ForeignEnum packed_enum_extension = 103 [packed = true];
+}
+
+// Used by ExtensionSetTest/DynamicExtensions. The test actually builds
+// a set of extensions to TestAllExtensions dynamically, based on the fields
+// of this message type.
+message TestDynamicExtensions {
+ enum DynamicEnumType {
+ DYNAMIC_FOO = 2200;
+ DYNAMIC_BAR = 2201;
+ DYNAMIC_BAZ = 2202;
+ }
+ message DynamicMessageType {
+ optional int32 dynamic_field = 2100;
+ }
+
+ optional fixed32 scalar_extension = 2000;
+ optional ForeignEnum enum_extension = 2001;
+ optional DynamicEnumType dynamic_enum_extension = 2002;
+
+ optional ForeignMessage message_extension = 2003;
+ optional DynamicMessageType dynamic_message_extension = 2004;
+
+ repeated string repeated_extension = 2005;
+ repeated sint32 packed_extension = 2006 [packed = true];
+}
+
+message TestRepeatedScalarDifferentTagSizes {
+ // Parsing repeated fixed size values used to fail. This message needs to be
+ // used in order to get a tag of the right size; all of the repeated fields
+ // in TestAllTypes didn't trigger the check.
+ repeated fixed32 repeated_fixed32 = 12;
+ // Check for a varint type, just for good measure.
+ repeated int32 repeated_int32 = 13;
+
+ // These have two-byte tags.
+ repeated fixed64 repeated_fixed64 = 2046;
+ repeated int64 repeated_int64 = 2047;
+
+ // Three byte tags.
+ repeated float repeated_float = 262142;
+ repeated uint64 repeated_uint64 = 262143;
+}
+
+// Test that if an optional or required message/group field appears multiple
+// times in the input, they need to be merged.
+message TestParsingMerge {
+ // RepeatedFieldsGenerator defines matching field types as TestParsingMerge,
+ // except that all fields are repeated. In the tests, we will serialize the
+ // RepeatedFieldsGenerator to bytes, and parse the bytes to TestParsingMerge.
+ // Repeated fields in RepeatedFieldsGenerator are expected to be merged into
+ // the corresponding required/optional fields in TestParsingMerge.
+ message RepeatedFieldsGenerator {
+ repeated TestAllTypes field1 = 1;
+ repeated TestAllTypes field2 = 2;
+ repeated TestAllTypes field3 = 3;
+ repeated group Group1 = 10 {
+ optional TestAllTypes field1 = 11;
+ }
+ repeated group Group2 = 20 {
+ optional TestAllTypes field1 = 21;
+ }
+ repeated TestAllTypes ext1 = 1000;
+ repeated TestAllTypes ext2 = 1001;
+ }
+ required TestAllTypes required_all_types = 1;
+ optional TestAllTypes optional_all_types = 2;
+ repeated TestAllTypes repeated_all_types = 3;
+ optional group OptionalGroup = 10 {
+ optional TestAllTypes optional_group_all_types = 11;
+ }
+ repeated group RepeatedGroup = 20 {
+ optional TestAllTypes repeated_group_all_types = 21;
+ }
+ extensions 1000 to max;
+ extend TestParsingMerge {
+ optional TestAllTypes optional_ext = 1000;
+ repeated TestAllTypes repeated_ext = 1001;
+ }
+}
+
+message TestCommentInjectionMessage {
+ // */ <- This should not close the generated doc comment
+ optional string a = 1 [default="*/ <- Neither should this."];
+}
+
+
+// Test that RPC services work.
+message FooRequest {}
+message FooResponse {}
+
+message FooClientMessage {}
+message FooServerMessage{}
+
+service TestService {
+ rpc Foo(FooRequest) returns (FooResponse);
+ rpc Bar(BarRequest) returns (BarResponse);
+}
+
+
+message BarRequest {}
+message BarResponse {}
diff --git a/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_custom_options.proto b/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_custom_options.proto
new file mode 100644
index 00000000..e591d294
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_custom_options.proto
@@ -0,0 +1,387 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+// Author: benjy@google.com (Benjy Weinberger)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// A proto file used to test the "custom options" feature of proto2.
+
+
+// Some generic_services option(s) added automatically.
+// See: http://go/proto2-generic-services-default
+option cc_generic_services = true; // auto-added
+option java_generic_services = true; // auto-added
+option py_generic_services = true;
+
+// A custom file option (defined below).
+option (file_opt1) = 9876543210;
+
+import "google/protobuf/descriptor.proto";
+
+// We don't put this in a package within proto2 because we need to make sure
+// that the generated code doesn't depend on being in the proto2 namespace.
+package protobuf_unittest;
+
+
+// Some simple test custom options of various types.
+
+extend google.protobuf.FileOptions {
+ optional uint64 file_opt1 = 7736974;
+}
+
+extend google.protobuf.MessageOptions {
+ optional int32 message_opt1 = 7739036;
+}
+
+extend google.protobuf.FieldOptions {
+ optional fixed64 field_opt1 = 7740936;
+ // This is useful for testing that we correctly register default values for
+ // extension options.
+ optional int32 field_opt2 = 7753913 [default=42];
+}
+
+extend google.protobuf.EnumOptions {
+ optional sfixed32 enum_opt1 = 7753576;
+}
+
+extend google.protobuf.EnumValueOptions {
+ optional int32 enum_value_opt1 = 1560678;
+}
+
+extend google.protobuf.ServiceOptions {
+ optional sint64 service_opt1 = 7887650;
+}
+
+enum MethodOpt1 {
+ METHODOPT1_VAL1 = 1;
+ METHODOPT1_VAL2 = 2;
+}
+
+extend google.protobuf.MethodOptions {
+ optional MethodOpt1 method_opt1 = 7890860;
+}
+
+// A test message with custom options at all possible locations (and also some
+// regular options, to make sure they interact nicely).
+message TestMessageWithCustomOptions {
+ option message_set_wire_format = false;
+
+ option (message_opt1) = -56;
+
+ optional string field1 = 1 [ctype=CORD,
+ (field_opt1)=8765432109];
+
+ enum AnEnum {
+ option (enum_opt1) = -789;
+
+ ANENUM_VAL1 = 1;
+ ANENUM_VAL2 = 2 [(enum_value_opt1) = 123];
+ }
+}
+
+
+// A test RPC service with custom options at all possible locations (and also
+// some regular options, to make sure they interact nicely).
+message CustomOptionFooRequest {
+}
+
+message CustomOptionFooResponse {
+}
+
+message CustomOptionFooClientMessage {
+}
+
+message CustomOptionFooServerMessage {
+}
+
+service TestServiceWithCustomOptions {
+ option (service_opt1) = -9876543210;
+
+ rpc Foo(CustomOptionFooRequest) returns (CustomOptionFooResponse) {
+ option (method_opt1) = METHODOPT1_VAL2;
+ }
+}
+
+
+
+// Options of every possible field type, so we can test them all exhaustively.
+
+message DummyMessageContainingEnum {
+ enum TestEnumType {
+ TEST_OPTION_ENUM_TYPE1 = 22;
+ TEST_OPTION_ENUM_TYPE2 = -23;
+ }
+}
+
+message DummyMessageInvalidAsOptionType {
+}
+
+extend google.protobuf.MessageOptions {
+ optional bool bool_opt = 7706090;
+ optional int32 int32_opt = 7705709;
+ optional int64 int64_opt = 7705542;
+ optional uint32 uint32_opt = 7704880;
+ optional uint64 uint64_opt = 7702367;
+ optional sint32 sint32_opt = 7701568;
+ optional sint64 sint64_opt = 7700863;
+ optional fixed32 fixed32_opt = 7700307;
+ optional fixed64 fixed64_opt = 7700194;
+ optional sfixed32 sfixed32_opt = 7698645;
+ optional sfixed64 sfixed64_opt = 7685475;
+ optional float float_opt = 7675390;
+ optional double double_opt = 7673293;
+ optional string string_opt = 7673285;
+ optional bytes bytes_opt = 7673238;
+ optional DummyMessageContainingEnum.TestEnumType enum_opt = 7673233;
+ optional DummyMessageInvalidAsOptionType message_type_opt = 7665967;
+}
+
+message CustomOptionMinIntegerValues {
+ option (bool_opt) = false;
+ option (int32_opt) = -0x80000000;
+ option (int64_opt) = -0x8000000000000000;
+ option (uint32_opt) = 0;
+ option (uint64_opt) = 0;
+ option (sint32_opt) = -0x80000000;
+ option (sint64_opt) = -0x8000000000000000;
+ option (fixed32_opt) = 0;
+ option (fixed64_opt) = 0;
+ option (sfixed32_opt) = -0x80000000;
+ option (sfixed64_opt) = -0x8000000000000000;
+}
+
+message CustomOptionMaxIntegerValues {
+ option (bool_opt) = true;
+ option (int32_opt) = 0x7FFFFFFF;
+ option (int64_opt) = 0x7FFFFFFFFFFFFFFF;
+ option (uint32_opt) = 0xFFFFFFFF;
+ option (uint64_opt) = 0xFFFFFFFFFFFFFFFF;
+ option (sint32_opt) = 0x7FFFFFFF;
+ option (sint64_opt) = 0x7FFFFFFFFFFFFFFF;
+ option (fixed32_opt) = 0xFFFFFFFF;
+ option (fixed64_opt) = 0xFFFFFFFFFFFFFFFF;
+ option (sfixed32_opt) = 0x7FFFFFFF;
+ option (sfixed64_opt) = 0x7FFFFFFFFFFFFFFF;
+}
+
+message CustomOptionOtherValues {
+ option (int32_opt) = -100; // To test sign-extension.
+ option (float_opt) = 12.3456789;
+ option (double_opt) = 1.234567890123456789;
+ option (string_opt) = "Hello, \"World\"";
+ option (bytes_opt) = "Hello\0World";
+ option (enum_opt) = TEST_OPTION_ENUM_TYPE2;
+}
+
+message SettingRealsFromPositiveInts {
+ option (float_opt) = 12;
+ option (double_opt) = 154;
+}
+
+message SettingRealsFromNegativeInts {
+ option (float_opt) = -12;
+ option (double_opt) = -154;
+}
+
+// Options of complex message types, themselves combined and extended in
+// various ways.
+
+message ComplexOptionType1 {
+ optional int32 foo = 1;
+ optional int32 foo2 = 2;
+ optional int32 foo3 = 3;
+
+ extensions 100 to max;
+}
+
+message ComplexOptionType2 {
+ optional ComplexOptionType1 bar = 1;
+ optional int32 baz = 2;
+
+ message ComplexOptionType4 {
+ optional int32 waldo = 1;
+
+ extend google.protobuf.MessageOptions {
+ optional ComplexOptionType4 complex_opt4 = 7633546;
+ }
+ }
+
+ optional ComplexOptionType4 fred = 3;
+
+ extensions 100 to max;
+}
+
+message ComplexOptionType3 {
+ optional int32 qux = 1;
+
+ optional group ComplexOptionType5 = 2 {
+ optional int32 plugh = 3;
+ }
+}
+
+extend ComplexOptionType1 {
+ optional int32 quux = 7663707;
+ optional ComplexOptionType3 corge = 7663442;
+}
+
+extend ComplexOptionType2 {
+ optional int32 grault = 7650927;
+ optional ComplexOptionType1 garply = 7649992;
+}
+
+extend google.protobuf.MessageOptions {
+ optional protobuf_unittest.ComplexOptionType1 complex_opt1 = 7646756;
+ optional ComplexOptionType2 complex_opt2 = 7636949;
+ optional ComplexOptionType3 complex_opt3 = 7636463;
+ optional group ComplexOpt6 = 7595468 {
+ optional int32 xyzzy = 7593951;
+ }
+}
+
+// Note that we try various different ways of naming the same extension.
+message VariousComplexOptions {
+ option (.protobuf_unittest.complex_opt1).foo = 42;
+ option (protobuf_unittest.complex_opt1).(.protobuf_unittest.quux) = 324;
+ option (.protobuf_unittest.complex_opt1).(protobuf_unittest.corge).qux = 876;
+ option (complex_opt2).baz = 987;
+ option (complex_opt2).(grault) = 654;
+ option (complex_opt2).bar.foo = 743;
+ option (complex_opt2).bar.(quux) = 1999;
+ option (complex_opt2).bar.(protobuf_unittest.corge).qux = 2008;
+ option (complex_opt2).(garply).foo = 741;
+ option (complex_opt2).(garply).(.protobuf_unittest.quux) = 1998;
+ option (complex_opt2).(protobuf_unittest.garply).(corge).qux = 2121;
+ option (ComplexOptionType2.ComplexOptionType4.complex_opt4).waldo = 1971;
+ option (complex_opt2).fred.waldo = 321;
+ option (protobuf_unittest.complex_opt3).qux = 9;
+ option (complex_opt3).complexoptiontype5.plugh = 22;
+ option (complexopt6).xyzzy = 24;
+}
+
+// ------------------------------------------------------
+// Definitions for testing aggregate option parsing.
+// See descriptor_unittest.cc.
+
+message AggregateMessageSet {
+ option message_set_wire_format = true;
+ extensions 4 to max;
+}
+
+message AggregateMessageSetElement {
+ extend AggregateMessageSet {
+ optional AggregateMessageSetElement message_set_extension = 15447542;
+ }
+ optional string s = 1;
+}
+
+// A helper type used to test aggregate option parsing
+message Aggregate {
+ optional int32 i = 1;
+ optional string s = 2;
+
+ // A nested object
+ optional Aggregate sub = 3;
+
+ // To test the parsing of extensions inside aggregate values
+ optional google.protobuf.FileOptions file = 4;
+ extend google.protobuf.FileOptions {
+ optional Aggregate nested = 15476903;
+ }
+
+ // An embedded message set
+ optional AggregateMessageSet mset = 5;
+}
+
+// Allow Aggregate to be used as an option at all possible locations
+// in the .proto grammer.
+extend google.protobuf.FileOptions { optional Aggregate fileopt = 15478479; }
+extend google.protobuf.MessageOptions { optional Aggregate msgopt = 15480088; }
+extend google.protobuf.FieldOptions { optional Aggregate fieldopt = 15481374; }
+extend google.protobuf.EnumOptions { optional Aggregate enumopt = 15483218; }
+extend google.protobuf.EnumValueOptions { optional Aggregate enumvalopt = 15486921; }
+extend google.protobuf.ServiceOptions { optional Aggregate serviceopt = 15497145; }
+extend google.protobuf.MethodOptions { optional Aggregate methodopt = 15512713; }
+
+// Try using AggregateOption at different points in the proto grammar
+option (fileopt) = {
+ s: 'FileAnnotation'
+ // Also test the handling of comments
+ /* of both types */ i: 100
+
+ sub { s: 'NestedFileAnnotation' }
+
+ // Include a google.protobuf.FileOptions and recursively extend it with
+ // another fileopt.
+ file {
+ [protobuf_unittest.fileopt] {
+ s:'FileExtensionAnnotation'
+ }
+ }
+
+ // A message set inside an option value
+ mset {
+ [protobuf_unittest.AggregateMessageSetElement.message_set_extension] {
+ s: 'EmbeddedMessageSetElement'
+ }
+ }
+};
+
+message AggregateMessage {
+ option (msgopt) = { i:101 s:'MessageAnnotation' };
+ optional int32 fieldname = 1 [(fieldopt) = { s:'FieldAnnotation' }];
+}
+
+service AggregateService {
+ option (serviceopt) = { s:'ServiceAnnotation' };
+ rpc Method (AggregateMessage) returns (AggregateMessage) {
+ option (methodopt) = { s:'MethodAnnotation' };
+ }
+}
+
+enum AggregateEnum {
+ option (enumopt) = { s:'EnumAnnotation' };
+ VALUE = 1 [(enumvalopt) = { s:'EnumValueAnnotation' }];
+}
+
+// Test custom options for nested type.
+message NestedOptionType {
+ message NestedMessage {
+ option (message_opt1) = 1001;
+ optional int32 nested_field = 1 [(field_opt1) = 1002];
+ }
+ enum NestedEnum {
+ option (enum_opt1) = 1003;
+ NESTED_ENUM_VALUE = 1 [(enum_value_opt1) = 1004];
+ }
+ extend google.protobuf.FileOptions {
+ optional int32 nested_extension = 7912573 [(field_opt2) = 1005];
+ }
+}
diff --git a/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_embed_optimize_for.proto b/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_embed_optimize_for.proto
new file mode 100644
index 00000000..fa176259
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_embed_optimize_for.proto
@@ -0,0 +1,50 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// A proto file which imports a proto file that uses optimize_for = CODE_SIZE.
+
+import "google/protobuf/unittest_optimize_for.proto";
+
+package protobuf_unittest;
+
+// We optimize for speed here, but we are importing a proto that is optimized
+// for code size.
+option optimize_for = SPEED;
+
+message TestEmbedOptimizedForSize {
+ // Test that embedding a message which has optimize_for = CODE_SIZE into
+ // one optimized for speed works.
+ optional TestOptimizedForSize optional_message = 1;
+ repeated TestOptimizedForSize repeated_message = 2;
+}
diff --git a/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_empty.proto b/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_empty.proto
new file mode 100644
index 00000000..ab12d1fb
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_empty.proto
@@ -0,0 +1,37 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file intentionally left blank. (At one point this wouldn't compile
+// correctly.)
+
diff --git a/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_enormous_descriptor.proto b/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_enormous_descriptor.proto
new file mode 100644
index 00000000..bc0b7c16
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_enormous_descriptor.proto
@@ -0,0 +1,1046 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// A proto file that has an extremely large descriptor. Used to test that
+// descriptors over 64k don't break the string literal length limit in Java.
+
+
+package google.protobuf;
+option java_package = "com.google.protobuf";
+
+// Avoid generating insanely long methods.
+option optimize_for = CODE_SIZE;
+
+message TestEnormousDescriptor {
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_1 = 1 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_2 = 2 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_3 = 3 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_4 = 4 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_5 = 5 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_6 = 6 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_7 = 7 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_8 = 8 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_9 = 9 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_10 = 10 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_11 = 11 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_12 = 12 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_13 = 13 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_14 = 14 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_15 = 15 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_16 = 16 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_17 = 17 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_18 = 18 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_19 = 19 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_20 = 20 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_21 = 21 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_22 = 22 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_23 = 23 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_24 = 24 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_25 = 25 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_26 = 26 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_27 = 27 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_28 = 28 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_29 = 29 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_30 = 30 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_31 = 31 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_32 = 32 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_33 = 33 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_34 = 34 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_35 = 35 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_36 = 36 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_37 = 37 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_38 = 38 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_39 = 39 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_40 = 40 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_41 = 41 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_42 = 42 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_43 = 43 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_44 = 44 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_45 = 45 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_46 = 46 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_47 = 47 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_48 = 48 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_49 = 49 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_50 = 50 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_51 = 51 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_52 = 52 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_53 = 53 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_54 = 54 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_55 = 55 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_56 = 56 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_57 = 57 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_58 = 58 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_59 = 59 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_60 = 60 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_61 = 61 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_62 = 62 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_63 = 63 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_64 = 64 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_65 = 65 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_66 = 66 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_67 = 67 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_68 = 68 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_69 = 69 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_70 = 70 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_71 = 71 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_72 = 72 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_73 = 73 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_74 = 74 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_75 = 75 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_76 = 76 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_77 = 77 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_78 = 78 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_79 = 79 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_80 = 80 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_81 = 81 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_82 = 82 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_83 = 83 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_84 = 84 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_85 = 85 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_86 = 86 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_87 = 87 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_88 = 88 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_89 = 89 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_90 = 90 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_91 = 91 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_92 = 92 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_93 = 93 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_94 = 94 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_95 = 95 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_96 = 96 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_97 = 97 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_98 = 98 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_99 = 99 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_100 = 100 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_101 = 101 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_102 = 102 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_103 = 103 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_104 = 104 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_105 = 105 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_106 = 106 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_107 = 107 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_108 = 108 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_109 = 109 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_110 = 110 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_111 = 111 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_112 = 112 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_113 = 113 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_114 = 114 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_115 = 115 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_116 = 116 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_117 = 117 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_118 = 118 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_119 = 119 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_120 = 120 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_121 = 121 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_122 = 122 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_123 = 123 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_124 = 124 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_125 = 125 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_126 = 126 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_127 = 127 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_128 = 128 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_129 = 129 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_130 = 130 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_131 = 131 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_132 = 132 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_133 = 133 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_134 = 134 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_135 = 135 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_136 = 136 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_137 = 137 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_138 = 138 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_139 = 139 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_140 = 140 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_141 = 141 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_142 = 142 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_143 = 143 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_144 = 144 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_145 = 145 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_146 = 146 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_147 = 147 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_148 = 148 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_149 = 149 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_150 = 150 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_151 = 151 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_152 = 152 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_153 = 153 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_154 = 154 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_155 = 155 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_156 = 156 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_157 = 157 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_158 = 158 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_159 = 159 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_160 = 160 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_161 = 161 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_162 = 162 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_163 = 163 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_164 = 164 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_165 = 165 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_166 = 166 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_167 = 167 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_168 = 168 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_169 = 169 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_170 = 170 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_171 = 171 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_172 = 172 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_173 = 173 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_174 = 174 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_175 = 175 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_176 = 176 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_177 = 177 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_178 = 178 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_179 = 179 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_180 = 180 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_181 = 181 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_182 = 182 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_183 = 183 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_184 = 184 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_185 = 185 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_186 = 186 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_187 = 187 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_188 = 188 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_189 = 189 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_190 = 190 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_191 = 191 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_192 = 192 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_193 = 193 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_194 = 194 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_195 = 195 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_196 = 196 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_197 = 197 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_198 = 198 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_199 = 199 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_200 = 200 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_201 = 201 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_202 = 202 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_203 = 203 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_204 = 204 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_205 = 205 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_206 = 206 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_207 = 207 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_208 = 208 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_209 = 209 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_210 = 210 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_211 = 211 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_212 = 212 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_213 = 213 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_214 = 214 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_215 = 215 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_216 = 216 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_217 = 217 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_218 = 218 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_219 = 219 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_220 = 220 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_221 = 221 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_222 = 222 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_223 = 223 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_224 = 224 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_225 = 225 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_226 = 226 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_227 = 227 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_228 = 228 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_229 = 229 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_230 = 230 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_231 = 231 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_232 = 232 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_233 = 233 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_234 = 234 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_235 = 235 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_236 = 236 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_237 = 237 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_238 = 238 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_239 = 239 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_240 = 240 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_241 = 241 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_242 = 242 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_243 = 243 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_244 = 244 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_245 = 245 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_246 = 246 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_247 = 247 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_248 = 248 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_249 = 249 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_250 = 250 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_251 = 251 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_252 = 252 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_253 = 253 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_254 = 254 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_255 = 255 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_256 = 256 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_257 = 257 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_258 = 258 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_259 = 259 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_260 = 260 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_261 = 261 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_262 = 262 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_263 = 263 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_264 = 264 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_265 = 265 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_266 = 266 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_267 = 267 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_268 = 268 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_269 = 269 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_270 = 270 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_271 = 271 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_272 = 272 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_273 = 273 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_274 = 274 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_275 = 275 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_276 = 276 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_277 = 277 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_278 = 278 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_279 = 279 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_280 = 280 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_281 = 281 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_282 = 282 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_283 = 283 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_284 = 284 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_285 = 285 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_286 = 286 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_287 = 287 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_288 = 288 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_289 = 289 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_290 = 290 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_291 = 291 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_292 = 292 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_293 = 293 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_294 = 294 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_295 = 295 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_296 = 296 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_297 = 297 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_298 = 298 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_299 = 299 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_300 = 300 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_301 = 301 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_302 = 302 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_303 = 303 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_304 = 304 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_305 = 305 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_306 = 306 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_307 = 307 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_308 = 308 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_309 = 309 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_310 = 310 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_311 = 311 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_312 = 312 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_313 = 313 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_314 = 314 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_315 = 315 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_316 = 316 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_317 = 317 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_318 = 318 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_319 = 319 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_320 = 320 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_321 = 321 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_322 = 322 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_323 = 323 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_324 = 324 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_325 = 325 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_326 = 326 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_327 = 327 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_328 = 328 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_329 = 329 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_330 = 330 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_331 = 331 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_332 = 332 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_333 = 333 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_334 = 334 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_335 = 335 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_336 = 336 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_337 = 337 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_338 = 338 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_339 = 339 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_340 = 340 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_341 = 341 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_342 = 342 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_343 = 343 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_344 = 344 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_345 = 345 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_346 = 346 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_347 = 347 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_348 = 348 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_349 = 349 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_350 = 350 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_351 = 351 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_352 = 352 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_353 = 353 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_354 = 354 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_355 = 355 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_356 = 356 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_357 = 357 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_358 = 358 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_359 = 359 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_360 = 360 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_361 = 361 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_362 = 362 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_363 = 363 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_364 = 364 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_365 = 365 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_366 = 366 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_367 = 367 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_368 = 368 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_369 = 369 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_370 = 370 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_371 = 371 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_372 = 372 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_373 = 373 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_374 = 374 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_375 = 375 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_376 = 376 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_377 = 377 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_378 = 378 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_379 = 379 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_380 = 380 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_381 = 381 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_382 = 382 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_383 = 383 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_384 = 384 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_385 = 385 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_386 = 386 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_387 = 387 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_388 = 388 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_389 = 389 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_390 = 390 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_391 = 391 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_392 = 392 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_393 = 393 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_394 = 394 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_395 = 395 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_396 = 396 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_397 = 397 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_398 = 398 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_399 = 399 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_400 = 400 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_401 = 401 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_402 = 402 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_403 = 403 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_404 = 404 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_405 = 405 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_406 = 406 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_407 = 407 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_408 = 408 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_409 = 409 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_410 = 410 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_411 = 411 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_412 = 412 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_413 = 413 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_414 = 414 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_415 = 415 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_416 = 416 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_417 = 417 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_418 = 418 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_419 = 419 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_420 = 420 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_421 = 421 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_422 = 422 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_423 = 423 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_424 = 424 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_425 = 425 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_426 = 426 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_427 = 427 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_428 = 428 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_429 = 429 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_430 = 430 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_431 = 431 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_432 = 432 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_433 = 433 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_434 = 434 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_435 = 435 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_436 = 436 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_437 = 437 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_438 = 438 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_439 = 439 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_440 = 440 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_441 = 441 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_442 = 442 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_443 = 443 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_444 = 444 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_445 = 445 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_446 = 446 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_447 = 447 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_448 = 448 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_449 = 449 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_450 = 450 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_451 = 451 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_452 = 452 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_453 = 453 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_454 = 454 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_455 = 455 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_456 = 456 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_457 = 457 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_458 = 458 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_459 = 459 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_460 = 460 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_461 = 461 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_462 = 462 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_463 = 463 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_464 = 464 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_465 = 465 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_466 = 466 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_467 = 467 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_468 = 468 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_469 = 469 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_470 = 470 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_471 = 471 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_472 = 472 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_473 = 473 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_474 = 474 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_475 = 475 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_476 = 476 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_477 = 477 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_478 = 478 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_479 = 479 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_480 = 480 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_481 = 481 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_482 = 482 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_483 = 483 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_484 = 484 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_485 = 485 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_486 = 486 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_487 = 487 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_488 = 488 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_489 = 489 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_490 = 490 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_491 = 491 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_492 = 492 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_493 = 493 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_494 = 494 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_495 = 495 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_496 = 496 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_497 = 497 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_498 = 498 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_499 = 499 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_500 = 500 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_501 = 501 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_502 = 502 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_503 = 503 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_504 = 504 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_505 = 505 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_506 = 506 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_507 = 507 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_508 = 508 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_509 = 509 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_510 = 510 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_511 = 511 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_512 = 512 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_513 = 513 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_514 = 514 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_515 = 515 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_516 = 516 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_517 = 517 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_518 = 518 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_519 = 519 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_520 = 520 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_521 = 521 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_522 = 522 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_523 = 523 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_524 = 524 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_525 = 525 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_526 = 526 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_527 = 527 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_528 = 528 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_529 = 529 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_530 = 530 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_531 = 531 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_532 = 532 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_533 = 533 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_534 = 534 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_535 = 535 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_536 = 536 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_537 = 537 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_538 = 538 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_539 = 539 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_540 = 540 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_541 = 541 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_542 = 542 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_543 = 543 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_544 = 544 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_545 = 545 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_546 = 546 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_547 = 547 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_548 = 548 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_549 = 549 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_550 = 550 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_551 = 551 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_552 = 552 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_553 = 553 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_554 = 554 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_555 = 555 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_556 = 556 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_557 = 557 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_558 = 558 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_559 = 559 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_560 = 560 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_561 = 561 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_562 = 562 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_563 = 563 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_564 = 564 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_565 = 565 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_566 = 566 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_567 = 567 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_568 = 568 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_569 = 569 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_570 = 570 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_571 = 571 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_572 = 572 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_573 = 573 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_574 = 574 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_575 = 575 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_576 = 576 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_577 = 577 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_578 = 578 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_579 = 579 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_580 = 580 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_581 = 581 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_582 = 582 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_583 = 583 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_584 = 584 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_585 = 585 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_586 = 586 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_587 = 587 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_588 = 588 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_589 = 589 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_590 = 590 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_591 = 591 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_592 = 592 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_593 = 593 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_594 = 594 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_595 = 595 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_596 = 596 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_597 = 597 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_598 = 598 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_599 = 599 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_600 = 600 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_601 = 601 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_602 = 602 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_603 = 603 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_604 = 604 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_605 = 605 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_606 = 606 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_607 = 607 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_608 = 608 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_609 = 609 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_610 = 610 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_611 = 611 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_612 = 612 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_613 = 613 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_614 = 614 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_615 = 615 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_616 = 616 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_617 = 617 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_618 = 618 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_619 = 619 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_620 = 620 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_621 = 621 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_622 = 622 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_623 = 623 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_624 = 624 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_625 = 625 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_626 = 626 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_627 = 627 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_628 = 628 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_629 = 629 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_630 = 630 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_631 = 631 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_632 = 632 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_633 = 633 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_634 = 634 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_635 = 635 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_636 = 636 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_637 = 637 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_638 = 638 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_639 = 639 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_640 = 640 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_641 = 641 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_642 = 642 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_643 = 643 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_644 = 644 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_645 = 645 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_646 = 646 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_647 = 647 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_648 = 648 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_649 = 649 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_650 = 650 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_651 = 651 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_652 = 652 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_653 = 653 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_654 = 654 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_655 = 655 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_656 = 656 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_657 = 657 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_658 = 658 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_659 = 659 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_660 = 660 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_661 = 661 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_662 = 662 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_663 = 663 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_664 = 664 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_665 = 665 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_666 = 666 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_667 = 667 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_668 = 668 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_669 = 669 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_670 = 670 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_671 = 671 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_672 = 672 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_673 = 673 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_674 = 674 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_675 = 675 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_676 = 676 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_677 = 677 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_678 = 678 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_679 = 679 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_680 = 680 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_681 = 681 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_682 = 682 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_683 = 683 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_684 = 684 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_685 = 685 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_686 = 686 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_687 = 687 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_688 = 688 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_689 = 689 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_690 = 690 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_691 = 691 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_692 = 692 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_693 = 693 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_694 = 694 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_695 = 695 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_696 = 696 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_697 = 697 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_698 = 698 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_699 = 699 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_700 = 700 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_701 = 701 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_702 = 702 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_703 = 703 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_704 = 704 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_705 = 705 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_706 = 706 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_707 = 707 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_708 = 708 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_709 = 709 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_710 = 710 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_711 = 711 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_712 = 712 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_713 = 713 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_714 = 714 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_715 = 715 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_716 = 716 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_717 = 717 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_718 = 718 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_719 = 719 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_720 = 720 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_721 = 721 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_722 = 722 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_723 = 723 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_724 = 724 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_725 = 725 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_726 = 726 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_727 = 727 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_728 = 728 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_729 = 729 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_730 = 730 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_731 = 731 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_732 = 732 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_733 = 733 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_734 = 734 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_735 = 735 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_736 = 736 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_737 = 737 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_738 = 738 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_739 = 739 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_740 = 740 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_741 = 741 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_742 = 742 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_743 = 743 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_744 = 744 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_745 = 745 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_746 = 746 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_747 = 747 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_748 = 748 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_749 = 749 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_750 = 750 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_751 = 751 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_752 = 752 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_753 = 753 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_754 = 754 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_755 = 755 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_756 = 756 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_757 = 757 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_758 = 758 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_759 = 759 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_760 = 760 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_761 = 761 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_762 = 762 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_763 = 763 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_764 = 764 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_765 = 765 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_766 = 766 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_767 = 767 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_768 = 768 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_769 = 769 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_770 = 770 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_771 = 771 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_772 = 772 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_773 = 773 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_774 = 774 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_775 = 775 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_776 = 776 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_777 = 777 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_778 = 778 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_779 = 779 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_780 = 780 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_781 = 781 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_782 = 782 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_783 = 783 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_784 = 784 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_785 = 785 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_786 = 786 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_787 = 787 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_788 = 788 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_789 = 789 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_790 = 790 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_791 = 791 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_792 = 792 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_793 = 793 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_794 = 794 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_795 = 795 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_796 = 796 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_797 = 797 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_798 = 798 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_799 = 799 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_800 = 800 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_801 = 801 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_802 = 802 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_803 = 803 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_804 = 804 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_805 = 805 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_806 = 806 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_807 = 807 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_808 = 808 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_809 = 809 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_810 = 810 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_811 = 811 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_812 = 812 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_813 = 813 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_814 = 814 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_815 = 815 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_816 = 816 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_817 = 817 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_818 = 818 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_819 = 819 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_820 = 820 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_821 = 821 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_822 = 822 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_823 = 823 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_824 = 824 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_825 = 825 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_826 = 826 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_827 = 827 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_828 = 828 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_829 = 829 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_830 = 830 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_831 = 831 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_832 = 832 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_833 = 833 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_834 = 834 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_835 = 835 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_836 = 836 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_837 = 837 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_838 = 838 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_839 = 839 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_840 = 840 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_841 = 841 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_842 = 842 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_843 = 843 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_844 = 844 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_845 = 845 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_846 = 846 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_847 = 847 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_848 = 848 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_849 = 849 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_850 = 850 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_851 = 851 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_852 = 852 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_853 = 853 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_854 = 854 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_855 = 855 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_856 = 856 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_857 = 857 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_858 = 858 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_859 = 859 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_860 = 860 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_861 = 861 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_862 = 862 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_863 = 863 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_864 = 864 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_865 = 865 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_866 = 866 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_867 = 867 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_868 = 868 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_869 = 869 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_870 = 870 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_871 = 871 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_872 = 872 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_873 = 873 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_874 = 874 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_875 = 875 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_876 = 876 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_877 = 877 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_878 = 878 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_879 = 879 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_880 = 880 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_881 = 881 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_882 = 882 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_883 = 883 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_884 = 884 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_885 = 885 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_886 = 886 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_887 = 887 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_888 = 888 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_889 = 889 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_890 = 890 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_891 = 891 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_892 = 892 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_893 = 893 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_894 = 894 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_895 = 895 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_896 = 896 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_897 = 897 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_898 = 898 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_899 = 899 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_900 = 900 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_901 = 901 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_902 = 902 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_903 = 903 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_904 = 904 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_905 = 905 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_906 = 906 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_907 = 907 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_908 = 908 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_909 = 909 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_910 = 910 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_911 = 911 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_912 = 912 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_913 = 913 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_914 = 914 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_915 = 915 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_916 = 916 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_917 = 917 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_918 = 918 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_919 = 919 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_920 = 920 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_921 = 921 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_922 = 922 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_923 = 923 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_924 = 924 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_925 = 925 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_926 = 926 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_927 = 927 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_928 = 928 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_929 = 929 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_930 = 930 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_931 = 931 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_932 = 932 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_933 = 933 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_934 = 934 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_935 = 935 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_936 = 936 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_937 = 937 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_938 = 938 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_939 = 939 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_940 = 940 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_941 = 941 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_942 = 942 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_943 = 943 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_944 = 944 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_945 = 945 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_946 = 946 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_947 = 947 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_948 = 948 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_949 = 949 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_950 = 950 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_951 = 951 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_952 = 952 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_953 = 953 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_954 = 954 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_955 = 955 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_956 = 956 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_957 = 957 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_958 = 958 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_959 = 959 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_960 = 960 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_961 = 961 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_962 = 962 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_963 = 963 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_964 = 964 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_965 = 965 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_966 = 966 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_967 = 967 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_968 = 968 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_969 = 969 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_970 = 970 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_971 = 971 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_972 = 972 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_973 = 973 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_974 = 974 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_975 = 975 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_976 = 976 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_977 = 977 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_978 = 978 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_979 = 979 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_980 = 980 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_981 = 981 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_982 = 982 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_983 = 983 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_984 = 984 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_985 = 985 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_986 = 986 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_987 = 987 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_988 = 988 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_989 = 989 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_990 = 990 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_991 = 991 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_992 = 992 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_993 = 993 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_994 = 994 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_995 = 995 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_996 = 996 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_997 = 997 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_998 = 998 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_999 = 999 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_1000 = 1000 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+}
diff --git a/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_import.proto b/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_import.proto
new file mode 100644
index 00000000..c115b111
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_import.proto
@@ -0,0 +1,64 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// A proto file which is imported by unittest.proto to test importing.
+
+
+// We don't put this in a package within proto2 because we need to make sure
+// that the generated code doesn't depend on being in the proto2 namespace.
+// In test_util.h we do
+// "using namespace unittest_import = protobuf_unittest_import".
+package protobuf_unittest_import;
+
+option optimize_for = SPEED;
+
+// Excercise the java_package option.
+option java_package = "com.google.protobuf.test";
+
+// Do not set a java_outer_classname here to verify that Proto2 works without
+// one.
+
+// Test public import
+import public "google/protobuf/unittest_import_public.proto";
+
+message ImportMessage {
+ optional int32 d = 1;
+}
+
+enum ImportEnum {
+ IMPORT_FOO = 7;
+ IMPORT_BAR = 8;
+ IMPORT_BAZ = 9;
+}
+
diff --git a/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_import_lite.proto b/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_import_lite.proto
new file mode 100644
index 00000000..81b117fe
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_import_lite.proto
@@ -0,0 +1,51 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+// Author: kenton@google.com (Kenton Varda)
+//
+// This is like unittest_import.proto but with optimize_for = LITE_RUNTIME.
+
+package protobuf_unittest_import;
+
+option optimize_for = LITE_RUNTIME;
+
+option java_package = "com.google.protobuf";
+
+import public "google/protobuf/unittest_import_public_lite.proto";
+
+message ImportMessageLite {
+ optional int32 d = 1;
+}
+
+enum ImportEnumLite {
+ IMPORT_LITE_FOO = 7;
+ IMPORT_LITE_BAR = 8;
+ IMPORT_LITE_BAZ = 9;
+}
diff --git a/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_import_public.proto b/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_import_public.proto
new file mode 100644
index 00000000..ea5d1b13
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_import_public.proto
@@ -0,0 +1,40 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+// Author: liujisi@google.com (Pherl Liu)
+
+
+package protobuf_unittest_import;
+
+option java_package = "com.google.protobuf.test";
+
+message PublicImportMessage {
+ optional int32 e = 1;
+}
diff --git a/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_import_public_lite.proto b/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_import_public_lite.proto
new file mode 100644
index 00000000..d077563c
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_import_public_lite.proto
@@ -0,0 +1,42 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+// Author: liujisi@google.com (Pherl Liu)
+
+
+package protobuf_unittest_import;
+
+option optimize_for = LITE_RUNTIME;
+
+option java_package = "com.google.protobuf";
+
+message PublicImportMessageLite {
+ optional int32 e = 1;
+}
diff --git a/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_lite.proto b/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_lite.proto
new file mode 100644
index 00000000..a1764aac
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_lite.proto
@@ -0,0 +1,360 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+// Author: kenton@google.com (Kenton Varda)
+//
+// This is like unittest.proto but with optimize_for = LITE_RUNTIME.
+
+package protobuf_unittest;
+
+import "google/protobuf/unittest_import_lite.proto";
+
+option optimize_for = LITE_RUNTIME;
+
+option java_package = "com.google.protobuf";
+
+// Same as TestAllTypes but with the lite runtime.
+message TestAllTypesLite {
+ message NestedMessage {
+ optional int32 bb = 1;
+ }
+
+ enum NestedEnum {
+ FOO = 1;
+ BAR = 2;
+ BAZ = 3;
+ }
+
+ // Singular
+ optional int32 optional_int32 = 1;
+ optional int64 optional_int64 = 2;
+ optional uint32 optional_uint32 = 3;
+ optional uint64 optional_uint64 = 4;
+ optional sint32 optional_sint32 = 5;
+ optional sint64 optional_sint64 = 6;
+ optional fixed32 optional_fixed32 = 7;
+ optional fixed64 optional_fixed64 = 8;
+ optional sfixed32 optional_sfixed32 = 9;
+ optional sfixed64 optional_sfixed64 = 10;
+ optional float optional_float = 11;
+ optional double optional_double = 12;
+ optional bool optional_bool = 13;
+ optional string optional_string = 14;
+ optional bytes optional_bytes = 15;
+
+ optional group OptionalGroup = 16 {
+ optional int32 a = 17;
+ }
+
+ optional NestedMessage optional_nested_message = 18;
+ optional ForeignMessageLite optional_foreign_message = 19;
+ optional protobuf_unittest_import.ImportMessageLite
+ optional_import_message = 20;
+
+ optional NestedEnum optional_nested_enum = 21;
+ optional ForeignEnumLite optional_foreign_enum = 22;
+ optional protobuf_unittest_import.ImportEnumLite optional_import_enum = 23;
+
+ optional string optional_string_piece = 24 [ctype=STRING_PIECE];
+ optional string optional_cord = 25 [ctype=CORD];
+
+ // Defined in unittest_import_public.proto
+ optional protobuf_unittest_import.PublicImportMessageLite
+ optional_public_import_message = 26;
+
+ optional NestedMessage optional_lazy_message = 27 [lazy=true];
+
+ // Repeated
+ repeated int32 repeated_int32 = 31;
+ repeated int64 repeated_int64 = 32;
+ repeated uint32 repeated_uint32 = 33;
+ repeated uint64 repeated_uint64 = 34;
+ repeated sint32 repeated_sint32 = 35;
+ repeated sint64 repeated_sint64 = 36;
+ repeated fixed32 repeated_fixed32 = 37;
+ repeated fixed64 repeated_fixed64 = 38;
+ repeated sfixed32 repeated_sfixed32 = 39;
+ repeated sfixed64 repeated_sfixed64 = 40;
+ repeated float repeated_float = 41;
+ repeated double repeated_double = 42;
+ repeated bool repeated_bool = 43;
+ repeated string repeated_string = 44;
+ repeated bytes repeated_bytes = 45;
+
+ repeated group RepeatedGroup = 46 {
+ optional int32 a = 47;
+ }
+
+ repeated NestedMessage repeated_nested_message = 48;
+ repeated ForeignMessageLite repeated_foreign_message = 49;
+ repeated protobuf_unittest_import.ImportMessageLite
+ repeated_import_message = 50;
+
+ repeated NestedEnum repeated_nested_enum = 51;
+ repeated ForeignEnumLite repeated_foreign_enum = 52;
+ repeated protobuf_unittest_import.ImportEnumLite repeated_import_enum = 53;
+
+ repeated string repeated_string_piece = 54 [ctype=STRING_PIECE];
+ repeated string repeated_cord = 55 [ctype=CORD];
+
+ repeated NestedMessage repeated_lazy_message = 57 [lazy=true];
+
+ // Singular with defaults
+ optional int32 default_int32 = 61 [default = 41 ];
+ optional int64 default_int64 = 62 [default = 42 ];
+ optional uint32 default_uint32 = 63 [default = 43 ];
+ optional uint64 default_uint64 = 64 [default = 44 ];
+ optional sint32 default_sint32 = 65 [default = -45 ];
+ optional sint64 default_sint64 = 66 [default = 46 ];
+ optional fixed32 default_fixed32 = 67 [default = 47 ];
+ optional fixed64 default_fixed64 = 68 [default = 48 ];
+ optional sfixed32 default_sfixed32 = 69 [default = 49 ];
+ optional sfixed64 default_sfixed64 = 70 [default = -50 ];
+ optional float default_float = 71 [default = 51.5 ];
+ optional double default_double = 72 [default = 52e3 ];
+ optional bool default_bool = 73 [default = true ];
+ optional string default_string = 74 [default = "hello"];
+ optional bytes default_bytes = 75 [default = "world"];
+
+ optional NestedEnum default_nested_enum = 81 [default = BAR];
+ optional ForeignEnumLite default_foreign_enum = 82
+ [default = FOREIGN_LITE_BAR];
+ optional protobuf_unittest_import.ImportEnumLite
+ default_import_enum = 83 [default = IMPORT_LITE_BAR];
+
+ optional string default_string_piece = 84 [ctype=STRING_PIECE,default="abc"];
+ optional string default_cord = 85 [ctype=CORD,default="123"];
+}
+
+message ForeignMessageLite {
+ optional int32 c = 1;
+}
+
+enum ForeignEnumLite {
+ FOREIGN_LITE_FOO = 4;
+ FOREIGN_LITE_BAR = 5;
+ FOREIGN_LITE_BAZ = 6;
+}
+
+message TestPackedTypesLite {
+ repeated int32 packed_int32 = 90 [packed = true];
+ repeated int64 packed_int64 = 91 [packed = true];
+ repeated uint32 packed_uint32 = 92 [packed = true];
+ repeated uint64 packed_uint64 = 93 [packed = true];
+ repeated sint32 packed_sint32 = 94 [packed = true];
+ repeated sint64 packed_sint64 = 95 [packed = true];
+ repeated fixed32 packed_fixed32 = 96 [packed = true];
+ repeated fixed64 packed_fixed64 = 97 [packed = true];
+ repeated sfixed32 packed_sfixed32 = 98 [packed = true];
+ repeated sfixed64 packed_sfixed64 = 99 [packed = true];
+ repeated float packed_float = 100 [packed = true];
+ repeated double packed_double = 101 [packed = true];
+ repeated bool packed_bool = 102 [packed = true];
+ repeated ForeignEnumLite packed_enum = 103 [packed = true];
+}
+
+message TestAllExtensionsLite {
+ extensions 1 to max;
+}
+
+extend TestAllExtensionsLite {
+ // Singular
+ optional int32 optional_int32_extension_lite = 1;
+ optional int64 optional_int64_extension_lite = 2;
+ optional uint32 optional_uint32_extension_lite = 3;
+ optional uint64 optional_uint64_extension_lite = 4;
+ optional sint32 optional_sint32_extension_lite = 5;
+ optional sint64 optional_sint64_extension_lite = 6;
+ optional fixed32 optional_fixed32_extension_lite = 7;
+ optional fixed64 optional_fixed64_extension_lite = 8;
+ optional sfixed32 optional_sfixed32_extension_lite = 9;
+ optional sfixed64 optional_sfixed64_extension_lite = 10;
+ optional float optional_float_extension_lite = 11;
+ optional double optional_double_extension_lite = 12;
+ optional bool optional_bool_extension_lite = 13;
+ optional string optional_string_extension_lite = 14;
+ optional bytes optional_bytes_extension_lite = 15;
+
+ optional group OptionalGroup_extension_lite = 16 {
+ optional int32 a = 17;
+ }
+
+ optional TestAllTypesLite.NestedMessage optional_nested_message_extension_lite
+ = 18;
+ optional ForeignMessageLite optional_foreign_message_extension_lite = 19;
+ optional protobuf_unittest_import.ImportMessageLite
+ optional_import_message_extension_lite = 20;
+
+ optional TestAllTypesLite.NestedEnum optional_nested_enum_extension_lite = 21;
+ optional ForeignEnumLite optional_foreign_enum_extension_lite = 22;
+ optional protobuf_unittest_import.ImportEnumLite
+ optional_import_enum_extension_lite = 23;
+
+ optional string optional_string_piece_extension_lite = 24
+ [ctype=STRING_PIECE];
+ optional string optional_cord_extension_lite = 25 [ctype=CORD];
+
+ optional protobuf_unittest_import.PublicImportMessageLite
+ optional_public_import_message_extension_lite = 26;
+
+ optional TestAllTypesLite.NestedMessage
+ optional_lazy_message_extension_lite = 27 [lazy=true];
+
+ // Repeated
+ repeated int32 repeated_int32_extension_lite = 31;
+ repeated int64 repeated_int64_extension_lite = 32;
+ repeated uint32 repeated_uint32_extension_lite = 33;
+ repeated uint64 repeated_uint64_extension_lite = 34;
+ repeated sint32 repeated_sint32_extension_lite = 35;
+ repeated sint64 repeated_sint64_extension_lite = 36;
+ repeated fixed32 repeated_fixed32_extension_lite = 37;
+ repeated fixed64 repeated_fixed64_extension_lite = 38;
+ repeated sfixed32 repeated_sfixed32_extension_lite = 39;
+ repeated sfixed64 repeated_sfixed64_extension_lite = 40;
+ repeated float repeated_float_extension_lite = 41;
+ repeated double repeated_double_extension_lite = 42;
+ repeated bool repeated_bool_extension_lite = 43;
+ repeated string repeated_string_extension_lite = 44;
+ repeated bytes repeated_bytes_extension_lite = 45;
+
+ repeated group RepeatedGroup_extension_lite = 46 {
+ optional int32 a = 47;
+ }
+
+ repeated TestAllTypesLite.NestedMessage repeated_nested_message_extension_lite
+ = 48;
+ repeated ForeignMessageLite repeated_foreign_message_extension_lite = 49;
+ repeated protobuf_unittest_import.ImportMessageLite
+ repeated_import_message_extension_lite = 50;
+
+ repeated TestAllTypesLite.NestedEnum repeated_nested_enum_extension_lite = 51;
+ repeated ForeignEnumLite repeated_foreign_enum_extension_lite = 52;
+ repeated protobuf_unittest_import.ImportEnumLite
+ repeated_import_enum_extension_lite = 53;
+
+ repeated string repeated_string_piece_extension_lite = 54
+ [ctype=STRING_PIECE];
+ repeated string repeated_cord_extension_lite = 55 [ctype=CORD];
+
+ repeated TestAllTypesLite.NestedMessage
+ repeated_lazy_message_extension_lite = 57 [lazy=true];
+
+ // Singular with defaults
+ optional int32 default_int32_extension_lite = 61 [default = 41 ];
+ optional int64 default_int64_extension_lite = 62 [default = 42 ];
+ optional uint32 default_uint32_extension_lite = 63 [default = 43 ];
+ optional uint64 default_uint64_extension_lite = 64 [default = 44 ];
+ optional sint32 default_sint32_extension_lite = 65 [default = -45 ];
+ optional sint64 default_sint64_extension_lite = 66 [default = 46 ];
+ optional fixed32 default_fixed32_extension_lite = 67 [default = 47 ];
+ optional fixed64 default_fixed64_extension_lite = 68 [default = 48 ];
+ optional sfixed32 default_sfixed32_extension_lite = 69 [default = 49 ];
+ optional sfixed64 default_sfixed64_extension_lite = 70 [default = -50 ];
+ optional float default_float_extension_lite = 71 [default = 51.5 ];
+ optional double default_double_extension_lite = 72 [default = 52e3 ];
+ optional bool default_bool_extension_lite = 73 [default = true ];
+ optional string default_string_extension_lite = 74 [default = "hello"];
+ optional bytes default_bytes_extension_lite = 75 [default = "world"];
+
+ optional TestAllTypesLite.NestedEnum
+ default_nested_enum_extension_lite = 81 [default = BAR];
+ optional ForeignEnumLite
+ default_foreign_enum_extension_lite = 82 [default = FOREIGN_LITE_BAR];
+ optional protobuf_unittest_import.ImportEnumLite
+ default_import_enum_extension_lite = 83 [default = IMPORT_LITE_BAR];
+
+ optional string default_string_piece_extension_lite = 84 [ctype=STRING_PIECE,
+ default="abc"];
+ optional string default_cord_extension_lite = 85 [ctype=CORD, default="123"];
+}
+
+message TestPackedExtensionsLite {
+ extensions 1 to max;
+}
+
+extend TestPackedExtensionsLite {
+ repeated int32 packed_int32_extension_lite = 90 [packed = true];
+ repeated int64 packed_int64_extension_lite = 91 [packed = true];
+ repeated uint32 packed_uint32_extension_lite = 92 [packed = true];
+ repeated uint64 packed_uint64_extension_lite = 93 [packed = true];
+ repeated sint32 packed_sint32_extension_lite = 94 [packed = true];
+ repeated sint64 packed_sint64_extension_lite = 95 [packed = true];
+ repeated fixed32 packed_fixed32_extension_lite = 96 [packed = true];
+ repeated fixed64 packed_fixed64_extension_lite = 97 [packed = true];
+ repeated sfixed32 packed_sfixed32_extension_lite = 98 [packed = true];
+ repeated sfixed64 packed_sfixed64_extension_lite = 99 [packed = true];
+ repeated float packed_float_extension_lite = 100 [packed = true];
+ repeated double packed_double_extension_lite = 101 [packed = true];
+ repeated bool packed_bool_extension_lite = 102 [packed = true];
+ repeated ForeignEnumLite packed_enum_extension_lite = 103 [packed = true];
+}
+
+message TestNestedExtensionLite {
+ extend TestAllExtensionsLite {
+ optional int32 nested_extension = 12345;
+ }
+}
+
+// Test that deprecated fields work. We only verify that they compile (at one
+// point this failed).
+message TestDeprecatedLite {
+ optional int32 deprecated_field = 1 [deprecated = true];
+}
+
+// See the comments of the same type in unittest.proto.
+message TestParsingMergeLite {
+ message RepeatedFieldsGenerator {
+ repeated TestAllTypesLite field1 = 1;
+ repeated TestAllTypesLite field2 = 2;
+ repeated TestAllTypesLite field3 = 3;
+ repeated group Group1 = 10 {
+ optional TestAllTypesLite field1 = 11;
+ }
+ repeated group Group2 = 20 {
+ optional TestAllTypesLite field1 = 21;
+ }
+ repeated TestAllTypesLite ext1 = 1000;
+ repeated TestAllTypesLite ext2 = 1001;
+ }
+ required TestAllTypesLite required_all_types = 1;
+ optional TestAllTypesLite optional_all_types = 2;
+ repeated TestAllTypesLite repeated_all_types = 3;
+ optional group OptionalGroup = 10 {
+ optional TestAllTypesLite optional_group_all_types = 11;
+ }
+ repeated group RepeatedGroup = 20 {
+ optional TestAllTypesLite repeated_group_all_types = 21;
+ }
+ extensions 1000 to max;
+ extend TestParsingMergeLite {
+ optional TestAllTypesLite optional_ext = 1000;
+ repeated TestAllTypesLite repeated_ext = 1001;
+ }
+}
diff --git a/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_lite_imports_nonlite.proto b/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_lite_imports_nonlite.proto
new file mode 100644
index 00000000..d52cb8cc
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_lite_imports_nonlite.proto
@@ -0,0 +1,43 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+// Author: kenton@google.com (Kenton Varda)
+//
+// Tests that a "lite" message can import a regular message.
+
+package protobuf_unittest;
+
+import "google/protobuf/unittest.proto";
+
+option optimize_for = LITE_RUNTIME;
+
+message TestLiteImportsNonlite {
+ optional TestAllTypes message = 1;
+}
diff --git a/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_mset.proto b/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_mset.proto
new file mode 100644
index 00000000..3497f09f
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_mset.proto
@@ -0,0 +1,72 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file contains messages for testing message_set_wire_format.
+
+package protobuf_unittest;
+
+option optimize_for = SPEED;
+
+// A message with message_set_wire_format.
+message TestMessageSet {
+ option message_set_wire_format = true;
+ extensions 4 to max;
+}
+
+message TestMessageSetContainer {
+ optional TestMessageSet message_set = 1;
+}
+
+message TestMessageSetExtension1 {
+ extend TestMessageSet {
+ optional TestMessageSetExtension1 message_set_extension = 1545008;
+ }
+ optional int32 i = 15;
+}
+
+message TestMessageSetExtension2 {
+ extend TestMessageSet {
+ optional TestMessageSetExtension2 message_set_extension = 1547769;
+ }
+ optional string str = 25;
+}
+
+// MessageSet wire format is equivalent to this.
+message RawMessageSet {
+ repeated group Item = 1 {
+ required int32 type_id = 2;
+ required bytes message = 3;
+ }
+}
+
diff --git a/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_no_generic_services.proto b/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_no_generic_services.proto
new file mode 100644
index 00000000..cffb4122
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_no_generic_services.proto
@@ -0,0 +1,52 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+// Author: kenton@google.com (Kenton Varda)
+
+package google.protobuf.no_generic_services_test;
+
+// *_generic_services are false by default.
+
+message TestMessage {
+ optional int32 a = 1;
+ extensions 1000 to max;
+}
+
+enum TestEnum {
+ FOO = 1;
+}
+
+extend TestMessage {
+ optional int32 test_extension = 1000;
+}
+
+service TestService {
+ rpc Foo(TestMessage) returns(TestMessage);
+}
diff --git a/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_optimize_for.proto b/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_optimize_for.proto
new file mode 100644
index 00000000..feecbef8
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/unittest_optimize_for.proto
@@ -0,0 +1,61 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// A proto file which uses optimize_for = CODE_SIZE.
+
+import "google/protobuf/unittest.proto";
+
+package protobuf_unittest;
+
+option optimize_for = CODE_SIZE;
+
+message TestOptimizedForSize {
+ optional int32 i = 1;
+ optional ForeignMessage msg = 19;
+
+ extensions 1000 to max;
+
+ extend TestOptimizedForSize {
+ optional int32 test_extension = 1234;
+ optional TestRequiredOptimizedForSize test_extension2 = 1235;
+ }
+}
+
+message TestRequiredOptimizedForSize {
+ required int32 x = 1;
+}
+
+message TestOptionalOptimizedForSize {
+ optional TestRequiredOptimizedForSize o = 1;
+}
diff --git a/java/compatibility_tests/v2.5.0/test.sh b/java/compatibility_tests/v2.5.0/test.sh
new file mode 100755
index 00000000..5d5e9ed4
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/test.sh
@@ -0,0 +1,140 @@
+#!/bin/bash
+
+set -ex
+
+# Change to the script's directory.
+cd $(dirname $0)
+
+# Version of the tests (i.e., the version of protobuf from where we extracted
+# these tests).
+TEST_VERSION=`grep "^ <version>.*</version>" pom.xml | sed "s| <version>\(.*\)</version>|\1|"`
+
+# The old version of protobuf that we are testing compatibility against. This
+# is usually the same as TEST_VERSION (i.e., we use the tests extracted from
+# that version to test compatibility of the newest runtime against it), but it
+# is also possible to use this same test set to test the compatibiilty of the
+# latest version against other versions.
+case "$1" in
+ ""|2.5.0)
+ OLD_VERSION=2.5.0
+ OLD_VERSION_PROTOC=https://github.com/xfxyjwf/protobuf-compiler-release/raw/master/v2.5.0/linux/protoc
+ ;;
+ 2.6.1)
+ OLD_VERSION=2.6.1
+ OLD_VERSION_PROTOC=http://repo1.maven.org/maven2/com/google/protobuf/protoc/2.6.1-build2/protoc-2.6.1-build2-linux-x86_64.exe
+ ;;
+ 3.0.0-beta-1)
+ OLD_VERSION=3.0.0-beta-1
+ OLD_VERSION_PROTOC=http://repo1.maven.org/maven2/com/google/protobuf/protoc/3.0.0-beta-1/protoc-3.0.0-beta-1-linux-x86_64.exe
+ ;;
+ 3.0.0-beta-2)
+ OLD_VERSION=3.0.0-beta-2
+ OLD_VERSION_PROTOC=http://repo1.maven.org/maven2/com/google/protobuf/protoc/3.0.0-beta-2/protoc-3.0.0-beta-2-linux-x86_64.exe
+ ;;
+ 3.0.0-beta-3)
+ OLD_VERSION=3.0.0-beta-3
+ OLD_VERSION_PROTOC=http://repo1.maven.org/maven2/com/google/protobuf/protoc/3.0.0-beta-3/protoc-3.0.0-beta-3-linux-x86_64.exe
+ ;;
+ 3.0.0-beta-4)
+ OLD_VERSION=3.0.0-beta-4
+ OLD_VERSION_PROTOC=http://repo1.maven.org/maven2/com/google/protobuf/protoc/3.0.0-beta-4/protoc-3.0.0-beta-4-linux-x86_64.exe
+ ;;
+ *)
+ echo "[ERROR]: Unknown version number: $1"
+ exit 1
+ ;;
+esac
+
+# Extract the latest protobuf version number.
+VERSION_NUMBER=`grep "^ <version>.*</version>" ../../pom.xml | sed "s| <version>\(.*\)</version>|\1|"`
+
+echo "Running compatibility tests between $VERSION_NUMBER and $OLD_VERSION"
+
+# Check protoc
+[ -f ../../../src/protoc ] || {
+ echo "[ERROR]: Please build protoc first."
+ exit 1
+}
+
+# Build and install protobuf-java-$VERSION_NUMBER.jar
+[ -f ../../core/target/protobuf-java-$VERSION_NUMBER.jar ] || {
+ pushd ../..
+ mvn install -Dmaven.test.skip=true
+ popd
+}
+
+# Download old version source for the compatibility test
+[ -d protobuf ] || {
+ git clone https://github.com/google/protobuf.git
+ cd protobuf
+ git reset --hard v$TEST_VERSION
+ cd ..
+}
+
+# Download old version protoc compiler (for linux)
+wget $OLD_VERSION_PROTOC -O protoc
+chmod +x protoc
+
+# Test source compatibility. In these tests we recompile everything against
+# the new runtime (including old version generated code).
+
+# Test A.1:
+# protos: use new version
+# more_protos: use old version
+mvn clean test \
+ -Dprotobuf.test.source.path=$(pwd)/protobuf \
+ -Dprotoc.path=$(pwd)/protoc \
+ -Dprotos.protoc.path=$(pwd)/../../../src/protoc \
+ -Dprotobuf.version=$VERSION_NUMBER
+
+# Test A.2:
+# protos: use old version
+# more_protos: use new version
+mvn clean test \
+ -Dprotobuf.test.source.path=$(pwd)/protobuf \
+ -Dprotoc.path=$(pwd)/protoc \
+ -Dmore_protos.protoc.path=$(pwd)/../../../src/protoc \
+ -Dprotobuf.version=$VERSION_NUMBER
+
+# Test binary compatibility. In these tests we run the old version compiled
+# jar against the new runtime directly without recompile.
+
+# Collect all test dependencies in a single jar file (except for protobuf) to
+# make it easier to run binary compatibility test (where we will need to run
+# the jar files directly).
+cd deps
+mvn assembly:single
+cd ..
+cp -f deps/target/compatibility-test-deps-${TEST_VERSION}-jar-with-dependencies.jar deps.jar
+
+# Build the old version of all 3 artifacts.
+mvn clean install -Dmaven.test.skip=true -Dprotoc.path=$(pwd)/protoc -Dprotobuf.version=$OLD_VERSION
+cp -f protos/target/compatibility-protos-${TEST_VERSION}.jar protos.jar
+cp -f more_protos/target/compatibility-more-protos-${TEST_VERSION}.jar more_protos.jar
+cp -f tests/target/compatibility-tests-${TEST_VERSION}.jar tests.jar
+
+# Collect the list of tests we need to run.
+TESTS=`find tests -name "*Test.java" | sed "s|/|.|g;s/.java$//g;s/tests.src.main.java.//g"`
+
+# Test B.1: run all the old artifacts against the new runtime. Note that we
+# must run the test in the protobuf source tree because some of the tests need
+# to read golden test data files.
+cd protobuf
+java -cp ../../../core/target/protobuf-java-$VERSION_NUMBER.jar:../protos.jar:../more_protos.jar:../tests.jar:../deps.jar org.junit.runner.JUnitCore $TESTS
+cd ..
+
+# Test B.2: update protos.jar only.
+cd protos
+mvn clean package -Dmaven.test.skip=true -Dprotoc.path=$(pwd)/../../../../src/protoc -Dprotobuf.version=$VERSION_NUMBER
+cd ..
+cd protobuf
+java -cp ../../../core/target/protobuf-java-$VERSION_NUMBER.jar:../protos/target/compatibility-protos-${TEST_VERSION}.jar:../more_protos.jar:../tests.jar:../deps.jar org.junit.runner.JUnitCore $TESTS
+cd ..
+
+# Test B.3: update more_protos.jar only.
+cd more_protos
+mvn clean package -Dmaven.test.skip=true -Dprotoc.path=$(pwd)/../../../../src/protoc -Dprotobuf.version=$VERSION_NUMBER
+cd ..
+cd protobuf
+java -cp ../../../core/target/protobuf-java-$VERSION_NUMBER.jar:../protos.jar:../more_protos/target/compatibility-more-protos-${TEST_VERSION}.jar:../tests.jar:../deps.jar org.junit.runner.JUnitCore $TESTS
+cd ..
diff --git a/java/compatibility_tests/v2.5.0/tests/pom.xml b/java/compatibility_tests/v2.5.0/tests/pom.xml
new file mode 100644
index 00000000..f1ce46e7
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/tests/pom.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>com.google.protobuf.compatibility</groupId>
+ <artifactId>compatibility-test-suite</artifactId>
+ <version>2.5.0</version>
+ <relativePath>..</relativePath>
+ </parent>
+
+ <groupId>com.google.protobuf.compatibility</groupId>
+ <artifactId>compatibility-tests</artifactId>
+ <version>2.5.0</version>
+
+ <name>Compatibility Tests</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.4</version>
+ </dependency>
+ <dependency>
+ <groupId>org.easymock</groupId>
+ <artifactId>easymock</artifactId>
+ <version>2.2</version>
+ </dependency>
+ <dependency>
+ <groupId>org.easymock</groupId>
+ <artifactId>easymockclassextension</artifactId>
+ <version>2.2.1</version>
+ </dependency>
+ <dependency>
+ <groupId>com.google.protobuf</groupId>
+ <artifactId>protobuf-java</artifactId>
+ <version>${tests.protobuf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.google.protobuf.compatibility</groupId>
+ <artifactId>compatibility-protos</artifactId>
+ <version>2.5.0</version>
+ </dependency>
+ <dependency>
+ <groupId>com.google.protobuf.compatibility</groupId>
+ <artifactId>compatibility-more-protos</artifactId>
+ <version>2.5.0</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.6</source>
+ <target>1.6</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <testSourceDirectory>${basedir}/src/main/java/</testSourceDirectory>
+ <testClassesDirectory>${project.build.directory}/classes/</testClassesDirectory>
+ <includes>
+ <include>**/*Test.java</include>
+ </includes>
+ <workingDirectory>${protobuf.test.source.path}</workingDirectory>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/AbstractMessageTest.java b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/AbstractMessageTest.java
new file mode 100644
index 00000000..6789550c
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/AbstractMessageTest.java
@@ -0,0 +1,510 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf.test;
+import com.google.protobuf.*;
+
+import com.google.protobuf.Descriptors.FieldDescriptor;
+import protobuf_unittest.UnittestOptimizeFor.TestOptimizedForSize;
+import protobuf_unittest.UnittestProto;
+import protobuf_unittest.UnittestProto.ForeignMessage;
+import protobuf_unittest.UnittestProto.TestAllExtensions;
+import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestPackedTypes;
+import protobuf_unittest.UnittestProto.TestRequired;
+import protobuf_unittest.UnittestProto.TestRequiredForeign;
+import protobuf_unittest.UnittestProto.TestUnpackedTypes;
+
+import junit.framework.TestCase;
+
+import java.util.Map;
+
+/**
+ * Unit test for {@link AbstractMessage}.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public class AbstractMessageTest extends TestCase {
+ /**
+ * Extends AbstractMessage and wraps some other message object. The methods
+ * of the Message interface which aren't explicitly implemented by
+ * AbstractMessage are forwarded to the wrapped object. This allows us to
+ * test that AbstractMessage's implementations work even if the wrapped
+ * object does not use them.
+ */
+ private static class AbstractMessageWrapper extends AbstractMessage {
+ private final Message wrappedMessage;
+
+ public AbstractMessageWrapper(Message wrappedMessage) {
+ this.wrappedMessage = wrappedMessage;
+ }
+
+ public Descriptors.Descriptor getDescriptorForType() {
+ return wrappedMessage.getDescriptorForType();
+ }
+ public AbstractMessageWrapper getDefaultInstanceForType() {
+ return new AbstractMessageWrapper(
+ wrappedMessage.getDefaultInstanceForType());
+ }
+ public Map<Descriptors.FieldDescriptor, Object> getAllFields() {
+ return wrappedMessage.getAllFields();
+ }
+ public boolean hasField(Descriptors.FieldDescriptor field) {
+ return wrappedMessage.hasField(field);
+ }
+ public Object getField(Descriptors.FieldDescriptor field) {
+ return wrappedMessage.getField(field);
+ }
+ public int getRepeatedFieldCount(Descriptors.FieldDescriptor field) {
+ return wrappedMessage.getRepeatedFieldCount(field);
+ }
+ public Object getRepeatedField(
+ Descriptors.FieldDescriptor field, int index) {
+ return wrappedMessage.getRepeatedField(field, index);
+ }
+ public UnknownFieldSet getUnknownFields() {
+ return wrappedMessage.getUnknownFields();
+ }
+ public Builder newBuilderForType() {
+ return new Builder(wrappedMessage.newBuilderForType());
+ }
+ public Builder toBuilder() {
+ return new Builder(wrappedMessage.toBuilder());
+ }
+
+ static class Builder extends AbstractMessage.Builder<Builder> {
+ private final Message.Builder wrappedBuilder;
+
+ public Builder(Message.Builder wrappedBuilder) {
+ this.wrappedBuilder = wrappedBuilder;
+ }
+
+ public AbstractMessageWrapper build() {
+ return new AbstractMessageWrapper(wrappedBuilder.build());
+ }
+ public AbstractMessageWrapper buildPartial() {
+ return new AbstractMessageWrapper(wrappedBuilder.buildPartial());
+ }
+ public Builder clone() {
+ return new Builder(wrappedBuilder.clone());
+ }
+ public boolean isInitialized() {
+ return clone().buildPartial().isInitialized();
+ }
+ public Descriptors.Descriptor getDescriptorForType() {
+ return wrappedBuilder.getDescriptorForType();
+ }
+ public AbstractMessageWrapper getDefaultInstanceForType() {
+ return new AbstractMessageWrapper(
+ wrappedBuilder.getDefaultInstanceForType());
+ }
+ public Map<Descriptors.FieldDescriptor, Object> getAllFields() {
+ return wrappedBuilder.getAllFields();
+ }
+ public Builder newBuilderForField(Descriptors.FieldDescriptor field) {
+ return new Builder(wrappedBuilder.newBuilderForField(field));
+ }
+ public boolean hasField(Descriptors.FieldDescriptor field) {
+ return wrappedBuilder.hasField(field);
+ }
+ public Object getField(Descriptors.FieldDescriptor field) {
+ return wrappedBuilder.getField(field);
+ }
+ public Builder setField(Descriptors.FieldDescriptor field, Object value) {
+ wrappedBuilder.setField(field, value);
+ return this;
+ }
+ public Builder clearField(Descriptors.FieldDescriptor field) {
+ wrappedBuilder.clearField(field);
+ return this;
+ }
+ public int getRepeatedFieldCount(Descriptors.FieldDescriptor field) {
+ return wrappedBuilder.getRepeatedFieldCount(field);
+ }
+ public Object getRepeatedField(
+ Descriptors.FieldDescriptor field, int index) {
+ return wrappedBuilder.getRepeatedField(field, index);
+ }
+ public Builder setRepeatedField(Descriptors.FieldDescriptor field,
+ int index, Object value) {
+ wrappedBuilder.setRepeatedField(field, index, value);
+ return this;
+ }
+ public Builder addRepeatedField(
+ Descriptors.FieldDescriptor field, Object value) {
+ wrappedBuilder.addRepeatedField(field, value);
+ return this;
+ }
+ public UnknownFieldSet getUnknownFields() {
+ return wrappedBuilder.getUnknownFields();
+ }
+ public Builder setUnknownFields(UnknownFieldSet unknownFields) {
+ wrappedBuilder.setUnknownFields(unknownFields);
+ return this;
+ }
+ @Override
+ public Message.Builder getFieldBuilder(FieldDescriptor field) {
+ return wrappedBuilder.getFieldBuilder(field);
+ }
+ }
+ public Parser<? extends Message> getParserForType() {
+ return wrappedMessage.getParserForType();
+ }
+ }
+
+ // =================================================================
+
+ TestUtil.ReflectionTester reflectionTester =
+ new TestUtil.ReflectionTester(TestAllTypes.getDescriptor(), null);
+
+ TestUtil.ReflectionTester extensionsReflectionTester =
+ new TestUtil.ReflectionTester(TestAllExtensions.getDescriptor(),
+ TestUtil.getExtensionRegistry());
+
+ public void testClear() throws Exception {
+ AbstractMessageWrapper message =
+ new AbstractMessageWrapper.Builder(
+ TestAllTypes.newBuilder(TestUtil.getAllSet()))
+ .clear().build();
+ TestUtil.assertClear((TestAllTypes) message.wrappedMessage);
+ }
+
+ public void testCopy() throws Exception {
+ AbstractMessageWrapper message =
+ new AbstractMessageWrapper.Builder(TestAllTypes.newBuilder())
+ .mergeFrom(TestUtil.getAllSet()).build();
+ TestUtil.assertAllFieldsSet((TestAllTypes) message.wrappedMessage);
+ }
+
+ public void testSerializedSize() throws Exception {
+ TestAllTypes message = TestUtil.getAllSet();
+ Message abstractMessage = new AbstractMessageWrapper(TestUtil.getAllSet());
+
+ assertEquals(message.getSerializedSize(),
+ abstractMessage.getSerializedSize());
+ }
+
+ public void testSerialization() throws Exception {
+ Message abstractMessage = new AbstractMessageWrapper(TestUtil.getAllSet());
+
+ TestUtil.assertAllFieldsSet(
+ TestAllTypes.parseFrom(abstractMessage.toByteString()));
+
+ assertEquals(TestUtil.getAllSet().toByteString(),
+ abstractMessage.toByteString());
+ }
+
+ public void testParsing() throws Exception {
+ AbstractMessageWrapper.Builder builder =
+ new AbstractMessageWrapper.Builder(TestAllTypes.newBuilder());
+ AbstractMessageWrapper message =
+ builder.mergeFrom(TestUtil.getAllSet().toByteString()).build();
+ TestUtil.assertAllFieldsSet((TestAllTypes) message.wrappedMessage);
+ }
+
+ public void testParsingUninitialized() throws Exception {
+ TestRequiredForeign.Builder builder = TestRequiredForeign.newBuilder();
+ builder.getOptionalMessageBuilder().setDummy2(10);
+ ByteString bytes = builder.buildPartial().toByteString();
+ Message.Builder abstractMessageBuilder =
+ new AbstractMessageWrapper.Builder(TestRequiredForeign.newBuilder());
+ // mergeFrom() should not throw initialization error.
+ abstractMessageBuilder.mergeFrom(bytes).buildPartial();
+ try {
+ abstractMessageBuilder.mergeFrom(bytes).build();
+ fail();
+ } catch (UninitializedMessageException ex) {
+ // pass
+ }
+
+ // test DynamicMessage directly.
+ Message.Builder dynamicMessageBuilder = DynamicMessage.newBuilder(
+ TestRequiredForeign.getDescriptor());
+ // mergeFrom() should not throw initialization error.
+ dynamicMessageBuilder.mergeFrom(bytes).buildPartial();
+ try {
+ dynamicMessageBuilder.mergeFrom(bytes).build();
+ fail();
+ } catch (UninitializedMessageException ex) {
+ // pass
+ }
+ }
+
+ public void testPackedSerialization() throws Exception {
+ Message abstractMessage =
+ new AbstractMessageWrapper(TestUtil.getPackedSet());
+
+ TestUtil.assertPackedFieldsSet(
+ TestPackedTypes.parseFrom(abstractMessage.toByteString()));
+
+ assertEquals(TestUtil.getPackedSet().toByteString(),
+ abstractMessage.toByteString());
+ }
+
+ public void testPackedParsing() throws Exception {
+ AbstractMessageWrapper.Builder builder =
+ new AbstractMessageWrapper.Builder(TestPackedTypes.newBuilder());
+ AbstractMessageWrapper message =
+ builder.mergeFrom(TestUtil.getPackedSet().toByteString()).build();
+ TestUtil.assertPackedFieldsSet((TestPackedTypes) message.wrappedMessage);
+ }
+
+ public void testUnpackedSerialization() throws Exception {
+ Message abstractMessage =
+ new AbstractMessageWrapper(TestUtil.getUnpackedSet());
+
+ TestUtil.assertUnpackedFieldsSet(
+ TestUnpackedTypes.parseFrom(abstractMessage.toByteString()));
+
+ assertEquals(TestUtil.getUnpackedSet().toByteString(),
+ abstractMessage.toByteString());
+ }
+
+ public void testParsePackedToUnpacked() throws Exception {
+ AbstractMessageWrapper.Builder builder =
+ new AbstractMessageWrapper.Builder(TestUnpackedTypes.newBuilder());
+ AbstractMessageWrapper message =
+ builder.mergeFrom(TestUtil.getPackedSet().toByteString()).build();
+ TestUtil.assertUnpackedFieldsSet(
+ (TestUnpackedTypes) message.wrappedMessage);
+ }
+
+ public void testParseUnpackedToPacked() throws Exception {
+ AbstractMessageWrapper.Builder builder =
+ new AbstractMessageWrapper.Builder(TestPackedTypes.newBuilder());
+ AbstractMessageWrapper message =
+ builder.mergeFrom(TestUtil.getUnpackedSet().toByteString()).build();
+ TestUtil.assertPackedFieldsSet((TestPackedTypes) message.wrappedMessage);
+ }
+
+ public void testUnpackedParsing() throws Exception {
+ AbstractMessageWrapper.Builder builder =
+ new AbstractMessageWrapper.Builder(TestUnpackedTypes.newBuilder());
+ AbstractMessageWrapper message =
+ builder.mergeFrom(TestUtil.getUnpackedSet().toByteString()).build();
+ TestUtil.assertUnpackedFieldsSet(
+ (TestUnpackedTypes) message.wrappedMessage);
+ }
+
+ public void testOptimizedForSize() throws Exception {
+ // We're mostly only checking that this class was compiled successfully.
+ TestOptimizedForSize message =
+ TestOptimizedForSize.newBuilder().setI(1).build();
+ message = TestOptimizedForSize.parseFrom(message.toByteString());
+ assertEquals(2, message.getSerializedSize());
+ }
+
+ // -----------------------------------------------------------------
+ // Tests for isInitialized().
+
+ private static final TestRequired TEST_REQUIRED_UNINITIALIZED =
+ TestRequired.getDefaultInstance();
+ private static final TestRequired TEST_REQUIRED_INITIALIZED =
+ TestRequired.newBuilder().setA(1).setB(2).setC(3).build();
+
+ public void testIsInitialized() throws Exception {
+ TestRequired.Builder builder = TestRequired.newBuilder();
+ AbstractMessageWrapper.Builder abstractBuilder =
+ new AbstractMessageWrapper.Builder(builder);
+
+ assertFalse(abstractBuilder.isInitialized());
+ assertEquals("a, b, c", abstractBuilder.getInitializationErrorString());
+ builder.setA(1);
+ assertFalse(abstractBuilder.isInitialized());
+ assertEquals("b, c", abstractBuilder.getInitializationErrorString());
+ builder.setB(1);
+ assertFalse(abstractBuilder.isInitialized());
+ assertEquals("c", abstractBuilder.getInitializationErrorString());
+ builder.setC(1);
+ assertTrue(abstractBuilder.isInitialized());
+ assertEquals("", abstractBuilder.getInitializationErrorString());
+ }
+
+ public void testForeignIsInitialized() throws Exception {
+ TestRequiredForeign.Builder builder = TestRequiredForeign.newBuilder();
+ AbstractMessageWrapper.Builder abstractBuilder =
+ new AbstractMessageWrapper.Builder(builder);
+
+ assertTrue(abstractBuilder.isInitialized());
+ assertEquals("", abstractBuilder.getInitializationErrorString());
+
+ builder.setOptionalMessage(TEST_REQUIRED_UNINITIALIZED);
+ assertFalse(abstractBuilder.isInitialized());
+ assertEquals(
+ "optional_message.a, optional_message.b, optional_message.c",
+ abstractBuilder.getInitializationErrorString());
+
+ builder.setOptionalMessage(TEST_REQUIRED_INITIALIZED);
+ assertTrue(abstractBuilder.isInitialized());
+ assertEquals("", abstractBuilder.getInitializationErrorString());
+
+ builder.addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED);
+ assertFalse(abstractBuilder.isInitialized());
+ assertEquals(
+ "repeated_message[0].a, repeated_message[0].b, repeated_message[0].c",
+ abstractBuilder.getInitializationErrorString());
+
+ builder.setRepeatedMessage(0, TEST_REQUIRED_INITIALIZED);
+ assertTrue(abstractBuilder.isInitialized());
+ assertEquals("", abstractBuilder.getInitializationErrorString());
+ }
+
+ // -----------------------------------------------------------------
+ // Tests for mergeFrom
+
+ static final TestAllTypes MERGE_SOURCE =
+ TestAllTypes.newBuilder()
+ .setOptionalInt32(1)
+ .setOptionalString("foo")
+ .setOptionalForeignMessage(ForeignMessage.getDefaultInstance())
+ .addRepeatedString("bar")
+ .build();
+
+ static final TestAllTypes MERGE_DEST =
+ TestAllTypes.newBuilder()
+ .setOptionalInt64(2)
+ .setOptionalString("baz")
+ .setOptionalForeignMessage(ForeignMessage.newBuilder().setC(3).build())
+ .addRepeatedString("qux")
+ .build();
+
+ static final String MERGE_RESULT_TEXT =
+ "optional_int32: 1\n" +
+ "optional_int64: 2\n" +
+ "optional_string: \"foo\"\n" +
+ "optional_foreign_message {\n" +
+ " c: 3\n" +
+ "}\n" +
+ "repeated_string: \"qux\"\n" +
+ "repeated_string: \"bar\"\n";
+
+ public void testMergeFrom() throws Exception {
+ AbstractMessageWrapper result =
+ new AbstractMessageWrapper.Builder(
+ TestAllTypes.newBuilder(MERGE_DEST))
+ .mergeFrom(MERGE_SOURCE).build();
+
+ assertEquals(MERGE_RESULT_TEXT, result.toString());
+ }
+
+ // -----------------------------------------------------------------
+ // Tests for equals and hashCode
+
+ public void testEqualsAndHashCode() throws Exception {
+ TestAllTypes a = TestUtil.getAllSet();
+ TestAllTypes b = TestAllTypes.newBuilder().build();
+ TestAllTypes c = TestAllTypes.newBuilder(b).addRepeatedString("x").build();
+ TestAllTypes d = TestAllTypes.newBuilder(c).addRepeatedString("y").build();
+ TestAllExtensions e = TestUtil.getAllExtensionsSet();
+ TestAllExtensions f = TestAllExtensions.newBuilder(e)
+ .addExtension(UnittestProto.repeatedInt32Extension, 999).build();
+
+ checkEqualsIsConsistent(a);
+ checkEqualsIsConsistent(b);
+ checkEqualsIsConsistent(c);
+ checkEqualsIsConsistent(d);
+ checkEqualsIsConsistent(e);
+ checkEqualsIsConsistent(f);
+
+ checkNotEqual(a, b);
+ checkNotEqual(a, c);
+ checkNotEqual(a, d);
+ checkNotEqual(a, e);
+ checkNotEqual(a, f);
+
+ checkNotEqual(b, c);
+ checkNotEqual(b, d);
+ checkNotEqual(b, e);
+ checkNotEqual(b, f);
+
+ checkNotEqual(c, d);
+ checkNotEqual(c, e);
+ checkNotEqual(c, f);
+
+ checkNotEqual(d, e);
+ checkNotEqual(d, f);
+
+ checkNotEqual(e, f);
+
+ // Deserializing into the TestEmptyMessage such that every field
+ // is an {@link UnknownFieldSet.Field}.
+ UnittestProto.TestEmptyMessage eUnknownFields =
+ UnittestProto.TestEmptyMessage.parseFrom(e.toByteArray());
+ UnittestProto.TestEmptyMessage fUnknownFields =
+ UnittestProto.TestEmptyMessage.parseFrom(f.toByteArray());
+ checkNotEqual(eUnknownFields, fUnknownFields);
+ checkEqualsIsConsistent(eUnknownFields);
+ checkEqualsIsConsistent(fUnknownFields);
+
+ // Subsequent reconstitutions should be identical
+ UnittestProto.TestEmptyMessage eUnknownFields2 =
+ UnittestProto.TestEmptyMessage.parseFrom(e.toByteArray());
+ checkEqualsIsConsistent(eUnknownFields, eUnknownFields2);
+ }
+
+
+ /**
+ * Asserts that the given proto has symmetric equals and hashCode methods.
+ */
+ private void checkEqualsIsConsistent(Message message) {
+ // Object should be equal to itself.
+ assertEquals(message, message);
+
+ // Object should be equal to a dynamic copy of itself.
+ DynamicMessage dynamic = DynamicMessage.newBuilder(message).build();
+ checkEqualsIsConsistent(message, dynamic);
+ }
+
+ /**
+ * Asserts that the given protos are equal and have the same hash code.
+ */
+ private void checkEqualsIsConsistent(Message message1, Message message2) {
+ assertEquals(message1, message2);
+ assertEquals(message2, message1);
+ assertEquals(message2.hashCode(), message1.hashCode());
+ }
+
+ /**
+ * Asserts that the given protos are not equal and have different hash codes.
+ *
+ * @warning It's valid for non-equal objects to have the same hash code, so
+ * this test is stricter than it needs to be. However, this should happen
+ * relatively rarely.
+ */
+ private void checkNotEqual(Message m1, Message m2) {
+ String equalsError = String.format("%s should not be equal to %s", m1, m2);
+ assertFalse(equalsError, m1.equals(m2));
+ assertFalse(equalsError, m2.equals(m1));
+
+ assertFalse(
+ String.format("%s should have a different hash code from %s", m1, m2),
+ m1.hashCode() == m2.hashCode());
+ }
+}
diff --git a/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/BoundedByteStringTest.java b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/BoundedByteStringTest.java
new file mode 100644
index 00000000..c8382743
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/BoundedByteStringTest.java
@@ -0,0 +1,56 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf.test;
+import com.google.protobuf.*;
+
+import java.io.UnsupportedEncodingException;
+
+/**
+ * This class tests {@link BoundedByteString}, which extends {@link LiteralByteString},
+ * by inheriting the tests from {@link LiteralByteStringTest}. The only method which
+ * is strange enough that it needs to be overridden here is {@link #testToString()}.
+ *
+ * @author carlanton@google.com (Carl Haverl)
+ */
+public class BoundedByteStringTest extends LiteralByteStringTest {
+
+ @Override
+ protected void setUp() throws Exception {
+ classUnderTest = "BoundedByteString";
+ byte[] sourceBytes = ByteStringTest.getTestBytes(2341, 11337766L);
+ int from = 100;
+ int to = sourceBytes.length - 100;
+ stringUnderTest = ByteString.copyFrom(sourceBytes).substring(from, to);
+ referenceBytes = new byte[to - from];
+ System.arraycopy(sourceBytes, from, referenceBytes, 0, to - from);
+ expectedHashCode = 727575887;
+ }
+}
diff --git a/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/ByteStringTest.java b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/ByteStringTest.java
new file mode 100644
index 00000000..8bb9f731
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/ByteStringTest.java
@@ -0,0 +1,590 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf.test;
+import com.google.protobuf.*;
+
+import com.google.protobuf.ByteString.Output;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Random;
+
+/**
+ * Test methods with implementations in {@link ByteString}, plus do some top-level "integration"
+ * tests.
+ *
+ * @author carlanton@google.com (Carl Haverl)
+ */
+public class ByteStringTest extends TestCase {
+
+ private static final String UTF_16 = "UTF-16";
+
+ static byte[] getTestBytes(int size, long seed) {
+ Random random = new Random(seed);
+ byte[] result = new byte[size];
+ random.nextBytes(result);
+ return result;
+ }
+
+ private byte[] getTestBytes(int size) {
+ return getTestBytes(size, 445566L);
+ }
+
+ private byte[] getTestBytes() {
+ return getTestBytes(1000);
+ }
+
+ // Compare the entire left array with a subset of the right array.
+ private boolean isArrayRange(byte[] left, byte[] right, int rightOffset, int length) {
+ boolean stillEqual = (left.length == length);
+ for (int i = 0; (stillEqual && i < length); ++i) {
+ stillEqual = (left[i] == right[rightOffset + i]);
+ }
+ return stillEqual;
+ }
+
+ // Returns true only if the given two arrays have identical contents.
+ private boolean isArray(byte[] left, byte[] right) {
+ return left.length == right.length && isArrayRange(left, right, 0, left.length);
+ }
+
+ public void testSubstring_BeginIndex() {
+ byte[] bytes = getTestBytes();
+ ByteString substring = ByteString.copyFrom(bytes).substring(500);
+ assertTrue("substring must contain the tail of the string",
+ isArrayRange(substring.toByteArray(), bytes, 500, bytes.length - 500));
+ }
+
+ public void testCopyFrom_BytesOffsetSize() {
+ byte[] bytes = getTestBytes();
+ ByteString byteString = ByteString.copyFrom(bytes, 500, 200);
+ assertTrue("copyFrom sub-range must contain the expected bytes",
+ isArrayRange(byteString.toByteArray(), bytes, 500, 200));
+ }
+
+ public void testCopyFrom_Bytes() {
+ byte[] bytes = getTestBytes();
+ ByteString byteString = ByteString.copyFrom(bytes);
+ assertTrue("copyFrom must contain the expected bytes",
+ isArray(byteString.toByteArray(), bytes));
+ }
+
+ public void testCopyFrom_ByteBufferSize() {
+ byte[] bytes = getTestBytes();
+ ByteBuffer byteBuffer = ByteBuffer.allocate(bytes.length);
+ byteBuffer.put(bytes);
+ byteBuffer.position(500);
+ ByteString byteString = ByteString.copyFrom(byteBuffer, 200);
+ assertTrue("copyFrom byteBuffer sub-range must contain the expected bytes",
+ isArrayRange(byteString.toByteArray(), bytes, 500, 200));
+ }
+
+ public void testCopyFrom_ByteBuffer() {
+ byte[] bytes = getTestBytes();
+ ByteBuffer byteBuffer = ByteBuffer.allocate(bytes.length);
+ byteBuffer.put(bytes);
+ byteBuffer.position(500);
+ ByteString byteString = ByteString.copyFrom(byteBuffer);
+ assertTrue("copyFrom byteBuffer sub-range must contain the expected bytes",
+ isArrayRange(byteString.toByteArray(), bytes, 500, bytes.length - 500));
+ }
+
+ public void testCopyFrom_StringEncoding() throws UnsupportedEncodingException {
+ String testString = "I love unicode \u1234\u5678 characters";
+ ByteString byteString = ByteString.copyFrom(testString, UTF_16);
+ byte[] testBytes = testString.getBytes(UTF_16);
+ assertTrue("copyFrom string must respect the charset",
+ isArrayRange(byteString.toByteArray(), testBytes, 0, testBytes.length));
+ }
+
+ public void testCopyFrom_Utf8() throws UnsupportedEncodingException {
+ String testString = "I love unicode \u1234\u5678 characters";
+ ByteString byteString = ByteString.copyFromUtf8(testString);
+ byte[] testBytes = testString.getBytes("UTF-8");
+ assertTrue("copyFromUtf8 string must respect the charset",
+ isArrayRange(byteString.toByteArray(), testBytes, 0, testBytes.length));
+ }
+
+ public void testCopyFrom_Iterable() {
+ byte[] testBytes = getTestBytes(77777, 113344L);
+ final List<ByteString> pieces = makeConcretePieces(testBytes);
+ // Call copyFrom() on a Collection
+ ByteString byteString = ByteString.copyFrom(pieces);
+ assertTrue("copyFrom a List must contain the expected bytes",
+ isArrayRange(byteString.toByteArray(), testBytes, 0, testBytes.length));
+ // Call copyFrom on an iteration that's not a collection
+ ByteString byteStringAlt = ByteString.copyFrom(new Iterable<ByteString>() {
+ public Iterator<ByteString> iterator() {
+ return pieces.iterator();
+ }
+ });
+ assertEquals("copyFrom from an Iteration must contain the expected bytes",
+ byteString, byteStringAlt);
+ }
+
+ public void testCopyTo_TargetOffset() {
+ byte[] bytes = getTestBytes();
+ ByteString byteString = ByteString.copyFrom(bytes);
+ byte[] target = new byte[bytes.length + 1000];
+ byteString.copyTo(target, 400);
+ assertTrue("copyFrom byteBuffer sub-range must contain the expected bytes",
+ isArrayRange(bytes, target, 400, bytes.length));
+ }
+
+ public void testReadFrom_emptyStream() throws IOException {
+ ByteString byteString =
+ ByteString.readFrom(new ByteArrayInputStream(new byte[0]));
+ assertSame("reading an empty stream must result in the EMPTY constant "
+ + "byte string", ByteString.EMPTY, byteString);
+ }
+
+ public void testReadFrom_smallStream() throws IOException {
+ assertReadFrom(getTestBytes(10));
+ }
+
+ public void testReadFrom_mutating() throws IOException {
+ byte[] capturedArray = null;
+ EvilInputStream eis = new EvilInputStream();
+ ByteString byteString = ByteString.readFrom(eis);
+
+ capturedArray = eis.capturedArray;
+ byte[] originalValue = byteString.toByteArray();
+ for (int x = 0; x < capturedArray.length; ++x) {
+ capturedArray[x] = (byte) 0;
+ }
+
+ byte[] newValue = byteString.toByteArray();
+ assertTrue("copyFrom byteBuffer must not grant access to underlying array",
+ Arrays.equals(originalValue, newValue));
+ }
+
+ // Tests sizes that are over multi-segment rope threshold.
+ public void testReadFrom_largeStream() throws IOException {
+ assertReadFrom(getTestBytes(0x100));
+ assertReadFrom(getTestBytes(0x101));
+ assertReadFrom(getTestBytes(0x110));
+ assertReadFrom(getTestBytes(0x1000));
+ assertReadFrom(getTestBytes(0x1001));
+ assertReadFrom(getTestBytes(0x1010));
+ assertReadFrom(getTestBytes(0x10000));
+ assertReadFrom(getTestBytes(0x10001));
+ assertReadFrom(getTestBytes(0x10010));
+ }
+
+ // Tests that IOExceptions propagate through ByteString.readFrom().
+ public void testReadFrom_IOExceptions() {
+ try {
+ ByteString.readFrom(new FailStream());
+ fail("readFrom must throw the underlying IOException");
+
+ } catch (IOException e) {
+ assertEquals("readFrom must throw the expected exception",
+ "synthetic failure", e.getMessage());
+ }
+ }
+
+ // Tests that ByteString.readFrom works with streams that don't
+ // always fill their buffers.
+ public void testReadFrom_reluctantStream() throws IOException {
+ final byte[] data = getTestBytes(0x1000);
+
+ ByteString byteString = ByteString.readFrom(new ReluctantStream(data));
+ assertTrue("readFrom byte stream must contain the expected bytes",
+ isArray(byteString.toByteArray(), data));
+
+ // Same test as above, but with some specific chunk sizes.
+ assertReadFromReluctantStream(data, 100);
+ assertReadFromReluctantStream(data, 248);
+ assertReadFromReluctantStream(data, 249);
+ assertReadFromReluctantStream(data, 250);
+ assertReadFromReluctantStream(data, 251);
+ assertReadFromReluctantStream(data, 0x1000);
+ assertReadFromReluctantStream(data, 0x1001);
+ }
+
+ // Fails unless ByteString.readFrom reads the bytes correctly from a
+ // reluctant stream with the given chunkSize parameter.
+ private void assertReadFromReluctantStream(byte[] bytes, int chunkSize)
+ throws IOException {
+ ByteString b = ByteString.readFrom(new ReluctantStream(bytes), chunkSize);
+ assertTrue("readFrom byte stream must contain the expected bytes",
+ isArray(b.toByteArray(), bytes));
+ }
+
+ // Tests that ByteString.readFrom works with streams that implement
+ // available().
+ public void testReadFrom_available() throws IOException {
+ final byte[] data = getTestBytes(0x1001);
+
+ ByteString byteString = ByteString.readFrom(new AvailableStream(data));
+ assertTrue("readFrom byte stream must contain the expected bytes",
+ isArray(byteString.toByteArray(), data));
+ }
+
+ // Fails unless ByteString.readFrom reads the bytes correctly.
+ private void assertReadFrom(byte[] bytes) throws IOException {
+ ByteString byteString =
+ ByteString.readFrom(new ByteArrayInputStream(bytes));
+ assertTrue("readFrom byte stream must contain the expected bytes",
+ isArray(byteString.toByteArray(), bytes));
+ }
+
+ // A stream that fails when read.
+ private static final class FailStream extends InputStream {
+ @Override public int read() throws IOException {
+ throw new IOException("synthetic failure");
+ }
+ }
+
+ // A stream that simulates blocking by only producing 250 characters
+ // per call to read(byte[]).
+ private static class ReluctantStream extends InputStream {
+ protected final byte[] data;
+ protected int pos = 0;
+
+ public ReluctantStream(byte[] data) {
+ this.data = data;
+ }
+
+ @Override public int read() {
+ if (pos == data.length) {
+ return -1;
+ } else {
+ return data[pos++];
+ }
+ }
+
+ @Override public int read(byte[] buf) {
+ return read(buf, 0, buf.length);
+ }
+
+ @Override public int read(byte[] buf, int offset, int size) {
+ if (pos == data.length) {
+ return -1;
+ }
+ int count = Math.min(Math.min(size, data.length - pos), 250);
+ System.arraycopy(data, pos, buf, offset, count);
+ pos += count;
+ return count;
+ }
+ }
+
+ // Same as above, but also implements available().
+ private static final class AvailableStream extends ReluctantStream {
+ public AvailableStream(byte[] data) {
+ super(data);
+ }
+
+ @Override public int available() {
+ return Math.min(250, data.length - pos);
+ }
+ }
+
+ // A stream which exposes the byte array passed into read(byte[], int, int).
+ private static class EvilInputStream extends InputStream {
+ public byte[] capturedArray = null;
+
+ @Override
+ public int read(byte[] buf, int off, int len) {
+ if (capturedArray != null) {
+ return -1;
+ } else {
+ capturedArray = buf;
+ for (int x = 0; x < len; ++x) {
+ buf[x] = (byte) x;
+ }
+ return len;
+ }
+ }
+
+ @Override
+ public int read() {
+ // Purposefully do nothing.
+ return -1;
+ }
+ }
+
+ // A stream which exposes the byte array passed into write(byte[], int, int).
+ private static class EvilOutputStream extends OutputStream {
+ public byte[] capturedArray = null;
+
+ @Override
+ public void write(byte[] buf, int off, int len) {
+ if (capturedArray == null) {
+ capturedArray = buf;
+ }
+ }
+
+ @Override
+ public void write(int ignored) {
+ // Purposefully do nothing.
+ }
+ }
+
+ public void testToStringUtf8() throws UnsupportedEncodingException {
+ String testString = "I love unicode \u1234\u5678 characters";
+ byte[] testBytes = testString.getBytes("UTF-8");
+ ByteString byteString = ByteString.copyFrom(testBytes);
+ assertEquals("copyToStringUtf8 must respect the charset",
+ testString, byteString.toStringUtf8());
+ }
+
+ public void testNewOutput_InitialCapacity() throws IOException {
+ byte[] bytes = getTestBytes();
+ ByteString.Output output = ByteString.newOutput(bytes.length + 100);
+ output.write(bytes);
+ ByteString byteString = output.toByteString();
+ assertTrue(
+ "String built from newOutput(int) must contain the expected bytes",
+ isArrayRange(bytes, byteString.toByteArray(), 0, bytes.length));
+ }
+
+ // Test newOutput() using a variety of buffer sizes and a variety of (fixed)
+ // write sizes
+ public void testNewOutput_ArrayWrite() throws IOException {
+ byte[] bytes = getTestBytes();
+ int length = bytes.length;
+ int[] bufferSizes = {128, 256, length / 2, length - 1, length, length + 1,
+ 2 * length, 3 * length};
+ int[] writeSizes = {1, 4, 5, 7, 23, bytes.length};
+
+ for (int bufferSize : bufferSizes) {
+ for (int writeSize : writeSizes) {
+ // Test writing the entire output writeSize bytes at a time.
+ ByteString.Output output = ByteString.newOutput(bufferSize);
+ for (int i = 0; i < length; i += writeSize) {
+ output.write(bytes, i, Math.min(writeSize, length - i));
+ }
+ ByteString byteString = output.toByteString();
+ assertTrue("String built from newOutput() must contain the expected bytes",
+ isArrayRange(bytes, byteString.toByteArray(), 0, bytes.length));
+ }
+ }
+ }
+
+ // Test newOutput() using a variety of buffer sizes, but writing all the
+ // characters using write(byte);
+ public void testNewOutput_WriteChar() throws IOException {
+ byte[] bytes = getTestBytes();
+ int length = bytes.length;
+ int[] bufferSizes = {0, 1, 128, 256, length / 2,
+ length - 1, length, length + 1,
+ 2 * length, 3 * length};
+ for (int bufferSize : bufferSizes) {
+ ByteString.Output output = ByteString.newOutput(bufferSize);
+ for (byte byteValue : bytes) {
+ output.write(byteValue);
+ }
+ ByteString byteString = output.toByteString();
+ assertTrue("String built from newOutput() must contain the expected bytes",
+ isArrayRange(bytes, byteString.toByteArray(), 0, bytes.length));
+ }
+ }
+
+ // Test newOutput() in which we write the bytes using a variety of methods
+ // and sizes, and in which we repeatedly call toByteString() in the middle.
+ public void testNewOutput_Mixed() throws IOException {
+ Random rng = new Random(1);
+ byte[] bytes = getTestBytes();
+ int length = bytes.length;
+ int[] bufferSizes = {0, 1, 128, 256, length / 2,
+ length - 1, length, length + 1,
+ 2 * length, 3 * length};
+
+ for (int bufferSize : bufferSizes) {
+ // Test writing the entire output using a mixture of write sizes and
+ // methods;
+ ByteString.Output output = ByteString.newOutput(bufferSize);
+ int position = 0;
+ while (position < bytes.length) {
+ if (rng.nextBoolean()) {
+ int count = 1 + rng.nextInt(bytes.length - position);
+ output.write(bytes, position, count);
+ position += count;
+ } else {
+ output.write(bytes[position]);
+ position++;
+ }
+ assertEquals("size() returns the right value", position, output.size());
+ assertTrue("newOutput() substring must have correct bytes",
+ isArrayRange(output.toByteString().toByteArray(),
+ bytes, 0, position));
+ }
+ ByteString byteString = output.toByteString();
+ assertTrue("String built from newOutput() must contain the expected bytes",
+ isArrayRange(bytes, byteString.toByteArray(), 0, bytes.length));
+ }
+ }
+
+ public void testNewOutputEmpty() throws IOException {
+ // Make sure newOutput() correctly builds empty byte strings
+ ByteString byteString = ByteString.newOutput().toByteString();
+ assertEquals(ByteString.EMPTY, byteString);
+ }
+
+ public void testNewOutput_Mutating() throws IOException {
+ Output os = ByteString.newOutput(5);
+ os.write(new byte[] {1, 2, 3, 4, 5});
+ EvilOutputStream eos = new EvilOutputStream();
+ os.writeTo(eos);
+ byte[] capturedArray = eos.capturedArray;
+ ByteString byteString = os.toByteString();
+ byte[] oldValue = byteString.toByteArray();
+ Arrays.fill(capturedArray, (byte) 0);
+ byte[] newValue = byteString.toByteArray();
+ assertTrue("Output must not provide access to the underlying byte array",
+ Arrays.equals(oldValue, newValue));
+ }
+
+ public void testSubstringParity() {
+ byte[] bigBytes = getTestBytes(2048 * 1024, 113344L);
+ int start = 512 * 1024 - 3333;
+ int end = 512 * 1024 + 7777;
+ ByteString concreteSubstring = ByteString.copyFrom(bigBytes).substring(start, end);
+ boolean ok = true;
+ for (int i = start; ok && i < end; ++i) {
+ ok = (bigBytes[i] == concreteSubstring.byteAt(i - start));
+ }
+ assertTrue("Concrete substring didn't capture the right bytes", ok);
+
+ ByteString literalString = ByteString.copyFrom(bigBytes, start, end - start);
+ assertTrue("Substring must be equal to literal string",
+ concreteSubstring.equals(literalString));
+ assertEquals("Substring must have same hashcode as literal string",
+ literalString.hashCode(), concreteSubstring.hashCode());
+ }
+
+ public void testCompositeSubstring() {
+ byte[] referenceBytes = getTestBytes(77748, 113344L);
+
+ List<ByteString> pieces = makeConcretePieces(referenceBytes);
+ ByteString listString = ByteString.copyFrom(pieces);
+
+ int from = 1000;
+ int to = 40000;
+ ByteString compositeSubstring = listString.substring(from, to);
+ byte[] substringBytes = compositeSubstring.toByteArray();
+ boolean stillEqual = true;
+ for (int i = 0; stillEqual && i < to - from; ++i) {
+ stillEqual = referenceBytes[from + i] == substringBytes[i];
+ }
+ assertTrue("Substring must return correct bytes", stillEqual);
+
+ stillEqual = true;
+ for (int i = 0; stillEqual && i < to - from; ++i) {
+ stillEqual = referenceBytes[from + i] == compositeSubstring.byteAt(i);
+ }
+ assertTrue("Substring must support byteAt() correctly", stillEqual);
+
+ ByteString literalSubstring = ByteString.copyFrom(referenceBytes, from, to - from);
+ assertTrue("Composite substring must equal a literal substring over the same bytes",
+ compositeSubstring.equals(literalSubstring));
+ assertTrue("Literal substring must equal a composite substring over the same bytes",
+ literalSubstring.equals(compositeSubstring));
+
+ assertEquals("We must get the same hashcodes for composite and literal substrings",
+ literalSubstring.hashCode(), compositeSubstring.hashCode());
+
+ assertFalse("We can't be equal to a proper substring",
+ compositeSubstring.equals(literalSubstring.substring(0, literalSubstring.size() - 1)));
+ }
+
+ public void testCopyFromList() {
+ byte[] referenceBytes = getTestBytes(77748, 113344L);
+ ByteString literalString = ByteString.copyFrom(referenceBytes);
+
+ List<ByteString> pieces = makeConcretePieces(referenceBytes);
+ ByteString listString = ByteString.copyFrom(pieces);
+
+ assertTrue("Composite string must be equal to literal string",
+ listString.equals(literalString));
+ assertEquals("Composite string must have same hashcode as literal string",
+ literalString.hashCode(), listString.hashCode());
+ }
+
+ public void testConcat() {
+ byte[] referenceBytes = getTestBytes(77748, 113344L);
+ ByteString literalString = ByteString.copyFrom(referenceBytes);
+
+ List<ByteString> pieces = makeConcretePieces(referenceBytes);
+
+ Iterator<ByteString> iter = pieces.iterator();
+ ByteString concatenatedString = iter.next();
+ while (iter.hasNext()) {
+ concatenatedString = concatenatedString.concat(iter.next());
+ }
+
+ assertTrue("Concatenated string must be equal to literal string",
+ concatenatedString.equals(literalString));
+ assertEquals("Concatenated string must have same hashcode as literal string",
+ literalString.hashCode(), concatenatedString.hashCode());
+ }
+
+ public void testStartsWith() {
+ byte[] bytes = getTestBytes(1000, 1234L);
+ ByteString string = ByteString.copyFrom(bytes);
+ ByteString prefix = ByteString.copyFrom(bytes, 0, 500);
+ ByteString suffix = ByteString.copyFrom(bytes, 400, 600);
+ assertTrue(string.startsWith(ByteString.EMPTY));
+ assertTrue(string.startsWith(string));
+ assertTrue(string.startsWith(prefix));
+ assertFalse(string.startsWith(suffix));
+ assertFalse(prefix.startsWith(suffix));
+ assertFalse(suffix.startsWith(prefix));
+ assertFalse(ByteString.EMPTY.startsWith(prefix));
+ assertTrue(ByteString.EMPTY.startsWith(ByteString.EMPTY));
+ }
+
+ static List<ByteString> makeConcretePieces(byte[] referenceBytes) {
+ List<ByteString> pieces = new ArrayList<ByteString>();
+ // Starting length should be small enough that we'll do some concatenating by
+ // copying if we just concatenate all these pieces together.
+ for (int start = 0, length = 16; start < referenceBytes.length; start += length) {
+ length = (length << 1) - 1;
+ if (start + length > referenceBytes.length) {
+ length = referenceBytes.length - start;
+ }
+ pieces.add(ByteString.copyFrom(referenceBytes, start, length));
+ }
+ return pieces;
+ }
+}
diff --git a/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/CodedInputStreamTest.java b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/CodedInputStreamTest.java
new file mode 100644
index 00000000..7e67898e
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/CodedInputStreamTest.java
@@ -0,0 +1,469 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf.test;
+import com.google.protobuf.*;
+
+import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestRecursiveMessage;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayInputStream;
+import java.io.FilterInputStream;
+import java.io.InputStream;
+import java.io.IOException;
+
+/**
+ * Unit test for {@link CodedInputStream}.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public class CodedInputStreamTest extends TestCase {
+ /**
+ * Helper to construct a byte array from a bunch of bytes. The inputs are
+ * actually ints so that I can use hex notation and not get stupid errors
+ * about precision.
+ */
+ private byte[] bytes(int... bytesAsInts) {
+ byte[] bytes = new byte[bytesAsInts.length];
+ for (int i = 0; i < bytesAsInts.length; i++) {
+ bytes[i] = (byte) bytesAsInts[i];
+ }
+ return bytes;
+ }
+
+ /**
+ * An InputStream which limits the number of bytes it reads at a time.
+ * We use this to make sure that CodedInputStream doesn't screw up when
+ * reading in small blocks.
+ */
+ private static final class SmallBlockInputStream extends FilterInputStream {
+ private final int blockSize;
+
+ public SmallBlockInputStream(byte[] data, int blockSize) {
+ this(new ByteArrayInputStream(data), blockSize);
+ }
+
+ public SmallBlockInputStream(InputStream in, int blockSize) {
+ super(in);
+ this.blockSize = blockSize;
+ }
+
+ public int read(byte[] b) throws IOException {
+ return super.read(b, 0, Math.min(b.length, blockSize));
+ }
+
+ public int read(byte[] b, int off, int len) throws IOException {
+ return super.read(b, off, Math.min(len, blockSize));
+ }
+ }
+
+ /**
+ * Parses the given bytes using readRawVarint32() and readRawVarint64() and
+ * checks that the result matches the given value.
+ */
+ private void assertReadVarint(byte[] data, long value) throws Exception {
+ CodedInputStream input = CodedInputStream.newInstance(data);
+ assertEquals((int)value, input.readRawVarint32());
+
+ input = CodedInputStream.newInstance(data);
+ assertEquals(value, input.readRawVarint64());
+ assertTrue(input.isAtEnd());
+
+ // Try different block sizes.
+ for (int blockSize = 1; blockSize <= 16; blockSize *= 2) {
+ input = CodedInputStream.newInstance(
+ new SmallBlockInputStream(data, blockSize));
+ assertEquals((int)value, input.readRawVarint32());
+
+ input = CodedInputStream.newInstance(
+ new SmallBlockInputStream(data, blockSize));
+ assertEquals(value, input.readRawVarint64());
+ assertTrue(input.isAtEnd());
+ }
+
+ // Try reading direct from an InputStream. We want to verify that it
+ // doesn't read past the end of the input, so we copy to a new, bigger
+ // array first.
+ byte[] longerData = new byte[data.length + 1];
+ System.arraycopy(data, 0, longerData, 0, data.length);
+ InputStream rawInput = new ByteArrayInputStream(longerData);
+ }
+
+ /**
+ * Parses the given bytes using readRawVarint32() and readRawVarint64() and
+ * expects them to fail with an InvalidProtocolBufferException whose
+ * description matches the given one.
+ */
+ private void assertReadVarintFailure(
+ InvalidProtocolBufferException expected, byte[] data)
+ throws Exception {
+ CodedInputStream input = CodedInputStream.newInstance(data);
+ try {
+ input.readRawVarint32();
+ fail("Should have thrown an exception.");
+ } catch (InvalidProtocolBufferException e) {
+ assertEquals(expected.getMessage(), e.getMessage());
+ }
+
+ input = CodedInputStream.newInstance(data);
+ try {
+ input.readRawVarint64();
+ fail("Should have thrown an exception.");
+ } catch (InvalidProtocolBufferException e) {
+ assertEquals(expected.getMessage(), e.getMessage());
+ }
+ }
+
+ /** Tests readRawVarint32() and readRawVarint64(). */
+ public void testReadVarint() throws Exception {
+ assertReadVarint(bytes(0x00), 0);
+ assertReadVarint(bytes(0x01), 1);
+ assertReadVarint(bytes(0x7f), 127);
+ // 14882
+ assertReadVarint(bytes(0xa2, 0x74), (0x22 << 0) | (0x74 << 7));
+ // 2961488830
+ assertReadVarint(bytes(0xbe, 0xf7, 0x92, 0x84, 0x0b),
+ (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
+ (0x0bL << 28));
+
+ // 64-bit
+ // 7256456126
+ assertReadVarint(bytes(0xbe, 0xf7, 0x92, 0x84, 0x1b),
+ (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
+ (0x1bL << 28));
+ // 41256202580718336
+ assertReadVarint(
+ bytes(0x80, 0xe6, 0xeb, 0x9c, 0xc3, 0xc9, 0xa4, 0x49),
+ (0x00 << 0) | (0x66 << 7) | (0x6b << 14) | (0x1c << 21) |
+ (0x43L << 28) | (0x49L << 35) | (0x24L << 42) | (0x49L << 49));
+ // 11964378330978735131
+ assertReadVarint(
+ bytes(0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85, 0xa6, 0x01),
+ (0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) |
+ (0x3bL << 28) | (0x56L << 35) | (0x00L << 42) |
+ (0x05L << 49) | (0x26L << 56) | (0x01L << 63));
+ }
+
+ /**
+ * Parses the given bytes using readRawLittleEndian32() and checks
+ * that the result matches the given value.
+ */
+ private void assertReadLittleEndian32(byte[] data, int value)
+ throws Exception {
+ CodedInputStream input = CodedInputStream.newInstance(data);
+ assertEquals(value, input.readRawLittleEndian32());
+ assertTrue(input.isAtEnd());
+
+ // Try different block sizes.
+ for (int blockSize = 1; blockSize <= 16; blockSize *= 2) {
+ input = CodedInputStream.newInstance(
+ new SmallBlockInputStream(data, blockSize));
+ assertEquals(value, input.readRawLittleEndian32());
+ assertTrue(input.isAtEnd());
+ }
+ }
+
+ /**
+ * Parses the given bytes using readRawLittleEndian64() and checks
+ * that the result matches the given value.
+ */
+ private void assertReadLittleEndian64(byte[] data, long value)
+ throws Exception {
+ CodedInputStream input = CodedInputStream.newInstance(data);
+ assertEquals(value, input.readRawLittleEndian64());
+ assertTrue(input.isAtEnd());
+
+ // Try different block sizes.
+ for (int blockSize = 1; blockSize <= 16; blockSize *= 2) {
+ input = CodedInputStream.newInstance(
+ new SmallBlockInputStream(data, blockSize));
+ assertEquals(value, input.readRawLittleEndian64());
+ assertTrue(input.isAtEnd());
+ }
+ }
+
+ /** Tests readRawLittleEndian32() and readRawLittleEndian64(). */
+ public void testReadLittleEndian() throws Exception {
+ assertReadLittleEndian32(bytes(0x78, 0x56, 0x34, 0x12), 0x12345678);
+ assertReadLittleEndian32(bytes(0xf0, 0xde, 0xbc, 0x9a), 0x9abcdef0);
+
+ assertReadLittleEndian64(
+ bytes(0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12),
+ 0x123456789abcdef0L);
+ assertReadLittleEndian64(
+ bytes(0x78, 0x56, 0x34, 0x12, 0xf0, 0xde, 0xbc, 0x9a),
+ 0x9abcdef012345678L);
+ }
+
+ /** Test decodeZigZag32() and decodeZigZag64(). */
+ public void testDecodeZigZag() throws Exception {
+ assertEquals( 0, CodedInputStream.decodeZigZag32(0));
+ assertEquals(-1, CodedInputStream.decodeZigZag32(1));
+ assertEquals( 1, CodedInputStream.decodeZigZag32(2));
+ assertEquals(-2, CodedInputStream.decodeZigZag32(3));
+ assertEquals(0x3FFFFFFF, CodedInputStream.decodeZigZag32(0x7FFFFFFE));
+ assertEquals(0xC0000000, CodedInputStream.decodeZigZag32(0x7FFFFFFF));
+ assertEquals(0x7FFFFFFF, CodedInputStream.decodeZigZag32(0xFFFFFFFE));
+ assertEquals(0x80000000, CodedInputStream.decodeZigZag32(0xFFFFFFFF));
+
+ assertEquals( 0, CodedInputStream.decodeZigZag64(0));
+ assertEquals(-1, CodedInputStream.decodeZigZag64(1));
+ assertEquals( 1, CodedInputStream.decodeZigZag64(2));
+ assertEquals(-2, CodedInputStream.decodeZigZag64(3));
+ assertEquals(0x000000003FFFFFFFL,
+ CodedInputStream.decodeZigZag64(0x000000007FFFFFFEL));
+ assertEquals(0xFFFFFFFFC0000000L,
+ CodedInputStream.decodeZigZag64(0x000000007FFFFFFFL));
+ assertEquals(0x000000007FFFFFFFL,
+ CodedInputStream.decodeZigZag64(0x00000000FFFFFFFEL));
+ assertEquals(0xFFFFFFFF80000000L,
+ CodedInputStream.decodeZigZag64(0x00000000FFFFFFFFL));
+ assertEquals(0x7FFFFFFFFFFFFFFFL,
+ CodedInputStream.decodeZigZag64(0xFFFFFFFFFFFFFFFEL));
+ assertEquals(0x8000000000000000L,
+ CodedInputStream.decodeZigZag64(0xFFFFFFFFFFFFFFFFL));
+ }
+
+ /** Tests reading and parsing a whole message with every field type. */
+ public void testReadWholeMessage() throws Exception {
+ TestAllTypes message = TestUtil.getAllSet();
+
+ byte[] rawBytes = message.toByteArray();
+ assertEquals(rawBytes.length, message.getSerializedSize());
+
+ TestAllTypes message2 = TestAllTypes.parseFrom(rawBytes);
+ TestUtil.assertAllFieldsSet(message2);
+
+ // Try different block sizes.
+ for (int blockSize = 1; blockSize < 256; blockSize *= 2) {
+ message2 = TestAllTypes.parseFrom(
+ new SmallBlockInputStream(rawBytes, blockSize));
+ TestUtil.assertAllFieldsSet(message2);
+ }
+ }
+
+ /** Tests skipField(). */
+ public void testSkipWholeMessage() throws Exception {
+ TestAllTypes message = TestUtil.getAllSet();
+ byte[] rawBytes = message.toByteArray();
+
+ // Create two parallel inputs. Parse one as unknown fields while using
+ // skipField() to skip each field on the other. Expect the same tags.
+ CodedInputStream input1 = CodedInputStream.newInstance(rawBytes);
+ CodedInputStream input2 = CodedInputStream.newInstance(rawBytes);
+ UnknownFieldSet.Builder unknownFields = UnknownFieldSet.newBuilder();
+
+ while (true) {
+ int tag = input1.readTag();
+ assertEquals(tag, input2.readTag());
+ if (tag == 0) {
+ break;
+ }
+ unknownFields.mergeFieldFrom(tag, input1);
+ input2.skipField(tag);
+ }
+ }
+
+ /**
+ * Test that a bug in skipRawBytes() has been fixed: if the skip skips
+ * exactly up to a limit, this should not break things.
+ */
+ public void testSkipRawBytesBug() throws Exception {
+ byte[] rawBytes = new byte[] { 1, 2 };
+ CodedInputStream input = CodedInputStream.newInstance(rawBytes);
+
+ int limit = input.pushLimit(1);
+ input.skipRawBytes(1);
+ input.popLimit(limit);
+ assertEquals(2, input.readRawByte());
+ }
+
+ /**
+ * Test that a bug in skipRawBytes() has been fixed: if the skip skips
+ * past the end of a buffer with a limit that has been set past the end of
+ * that buffer, this should not break things.
+ */
+ public void testSkipRawBytesPastEndOfBufferWithLimit() throws Exception {
+ byte[] rawBytes = new byte[] { 1, 2, 3, 4, 5 };
+ CodedInputStream input = CodedInputStream.newInstance(
+ new SmallBlockInputStream(rawBytes, 3));
+
+ int limit = input.pushLimit(4);
+ // In order to expose the bug we need to read at least one byte to prime the
+ // buffer inside the CodedInputStream.
+ assertEquals(1, input.readRawByte());
+ // Skip to the end of the limit.
+ input.skipRawBytes(3);
+ assertTrue(input.isAtEnd());
+ input.popLimit(limit);
+ assertEquals(5, input.readRawByte());
+ }
+
+ public void testReadHugeBlob() throws Exception {
+ // Allocate and initialize a 1MB blob.
+ byte[] blob = new byte[1 << 20];
+ for (int i = 0; i < blob.length; i++) {
+ blob[i] = (byte)i;
+ }
+
+ // Make a message containing it.
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TestUtil.setAllFields(builder);
+ builder.setOptionalBytes(ByteString.copyFrom(blob));
+ TestAllTypes message = builder.build();
+
+ // Serialize and parse it. Make sure to parse from an InputStream, not
+ // directly from a ByteString, so that CodedInputStream uses buffered
+ // reading.
+ TestAllTypes message2 =
+ TestAllTypes.parseFrom(message.toByteString().newInput());
+
+ assertEquals(message.getOptionalBytes(), message2.getOptionalBytes());
+
+ // Make sure all the other fields were parsed correctly.
+ TestAllTypes message3 = TestAllTypes.newBuilder(message2)
+ .setOptionalBytes(TestUtil.getAllSet().getOptionalBytes())
+ .build();
+ TestUtil.assertAllFieldsSet(message3);
+ }
+
+ public int makeTag(int number, int tag) {
+ return (number << 3) + tag;
+ }
+
+ public void testReadMaliciouslyLargeBlob() throws Exception {
+ ByteString.Output rawOutput = ByteString.newOutput();
+ CodedOutputStream output = CodedOutputStream.newInstance(rawOutput);
+
+ int tag = makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ output.writeRawVarint32(tag);
+ output.writeRawVarint32(0x7FFFFFFF);
+ output.writeRawBytes(new byte[32]); // Pad with a few random bytes.
+ output.flush();
+
+ CodedInputStream input = rawOutput.toByteString().newCodedInput();
+ assertEquals(tag, input.readTag());
+
+ try {
+ input.readBytes();
+ fail("Should have thrown an exception!");
+ } catch (InvalidProtocolBufferException e) {
+ // success.
+ }
+ }
+
+ private TestRecursiveMessage makeRecursiveMessage(int depth) {
+ if (depth == 0) {
+ return TestRecursiveMessage.newBuilder().setI(5).build();
+ } else {
+ return TestRecursiveMessage.newBuilder()
+ .setA(makeRecursiveMessage(depth - 1)).build();
+ }
+ }
+
+ private void assertMessageDepth(TestRecursiveMessage message, int depth) {
+ if (depth == 0) {
+ assertFalse(message.hasA());
+ assertEquals(5, message.getI());
+ } else {
+ assertTrue(message.hasA());
+ assertMessageDepth(message.getA(), depth - 1);
+ }
+ }
+
+ public void testResetSizeCounter() throws Exception {
+ CodedInputStream input = CodedInputStream.newInstance(
+ new SmallBlockInputStream(new byte[256], 8));
+ input.setSizeLimit(16);
+ input.readRawBytes(16);
+ assertEquals(16, input.getTotalBytesRead());
+
+ try {
+ input.readRawByte();
+ fail("Should have thrown an exception!");
+ } catch (InvalidProtocolBufferException e) {
+ // success.
+ }
+
+ input.resetSizeCounter();
+ assertEquals(0, input.getTotalBytesRead());
+ input.readRawByte(); // No exception thrown.
+ input.resetSizeCounter();
+ assertEquals(0, input.getTotalBytesRead());
+ }
+
+ /**
+ * Tests that if we read an string that contains invalid UTF-8, no exception
+ * is thrown. Instead, the invalid bytes are replaced with the Unicode
+ * "replacement character" U+FFFD.
+ */
+ public void testReadInvalidUtf8() throws Exception {
+ ByteString.Output rawOutput = ByteString.newOutput();
+ CodedOutputStream output = CodedOutputStream.newInstance(rawOutput);
+
+ int tag = makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ output.writeRawVarint32(tag);
+ output.writeRawVarint32(1);
+ output.writeRawBytes(new byte[] { (byte)0x80 });
+ output.flush();
+
+ CodedInputStream input = rawOutput.toByteString().newCodedInput();
+ assertEquals(tag, input.readTag());
+ String text = input.readString();
+ assertEquals(0xfffd, text.charAt(0));
+ }
+
+ public void testReadFromSlice() throws Exception {
+ byte[] bytes = bytes(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+ CodedInputStream in = CodedInputStream.newInstance(bytes, 3, 5);
+ assertEquals(0, in.getTotalBytesRead());
+ for (int i = 3; i < 8; i++) {
+ assertEquals(i, in.readRawByte());
+ assertEquals(i-2, in.getTotalBytesRead());
+ }
+ // eof
+ assertEquals(0, in.readTag());
+ assertEquals(5, in.getTotalBytesRead());
+ }
+
+ public void testInvalidTag() throws Exception {
+ // Any tag number which corresponds to field number zero is invalid and
+ // should throw InvalidProtocolBufferException.
+ for (int i = 0; i < 8; i++) {
+ try {
+ CodedInputStream.newInstance(bytes(i)).readTag();
+ fail("Should have thrown an exception.");
+ } catch (InvalidProtocolBufferException e) {
+ }
+ }
+ }
+}
diff --git a/java/src/test/java/com/google/protobuf/CodedOutputStreamTest.java b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/CodedOutputStreamTest.java
index 360e759e..354d89d6 100644
--- a/java/src/test/java/com/google/protobuf/CodedOutputStreamTest.java
+++ b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/CodedOutputStreamTest.java
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
+// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -28,7 +28,8 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-package com.google.protobuf;
+package com.google.protobuf.test;
+import com.google.protobuf.*;
import protobuf_unittest.UnittestProto.SparseEnumMessage;
import protobuf_unittest.UnittestProto.TestAllTypes;
@@ -38,9 +39,7 @@ import protobuf_unittest.UnittestProto.TestSparseEnum;
import junit.framework.TestCase;
import java.io.ByteArrayOutputStream;
-import java.nio.ByteBuffer;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
/**
@@ -316,194 +315,4 @@ public class CodedOutputStreamTest extends TestCase {
SparseEnumMessage message2 = SparseEnumMessage.parseFrom(rawBytes);
assertEquals(TestSparseEnum.SPARSE_E, message2.getSparseEnum());
}
-
- /** Test getTotalBytesWritten() */
- public void testGetTotalBytesWritten() throws Exception {
- final int BUFFER_SIZE = 4 * 1024;
- ByteArrayOutputStream outputStream = new ByteArrayOutputStream(BUFFER_SIZE);
- CodedOutputStream codedStream = CodedOutputStream.newInstance(outputStream);
- byte[] value = "abcde".getBytes(Internal.UTF_8);
- for (int i = 0; i < 1024; ++i) {
- codedStream.writeRawBytes(value, 0, value.length);
- }
- String string =
- "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz";
- // Ensure we take the slower fast path.
- assertTrue(CodedOutputStream.computeRawVarint32Size(string.length())
- != CodedOutputStream.computeRawVarint32Size(string.length() * Utf8.MAX_BYTES_PER_CHAR));
-
- codedStream.writeStringNoTag(string);
- int stringSize = CodedOutputStream.computeStringSizeNoTag(string);
-
- // Make sure we have written more bytes than the buffer could hold. This is
- // to make the test complete.
- assertTrue(codedStream.getTotalBytesWritten() > BUFFER_SIZE);
-
- // Verify that the total bytes written is correct
- assertEquals((value.length * 1024) + stringSize, codedStream.getTotalBytesWritten());
- }
-
- // TODO(dweis): Write a comprehensive test suite for CodedOutputStream that covers more than just
- // this case.
- public void testWriteStringNoTag_fastpath() throws Exception {
- int bufferSize = 153;
- String threeBytesPer = "\u0981";
- String string = threeBytesPer;
- for (int i = 0; i < 50; i++) {
- string += threeBytesPer;
- }
- // These checks ensure we will tickle the slower fast path.
- assertEquals(1, CodedOutputStream.computeRawVarint32Size(string.length()));
- assertEquals(
- 2, CodedOutputStream.computeRawVarint32Size(string.length() * Utf8.MAX_BYTES_PER_CHAR));
- assertEquals(bufferSize, string.length() * Utf8.MAX_BYTES_PER_CHAR);
-
- CodedOutputStream output =
- CodedOutputStream.newInstance(ByteBuffer.allocate(bufferSize), bufferSize);
- output.writeStringNoTag(string);
- }
-
- public void testWriteToByteBuffer() throws Exception {
- final int bufferSize = 16 * 1024;
- ByteBuffer buffer = ByteBuffer.allocate(bufferSize);
- CodedOutputStream codedStream = CodedOutputStream.newInstance(buffer);
- // Write raw bytes into the ByteBuffer.
- final int length1 = 5000;
- for (int i = 0; i < length1; i++) {
- codedStream.writeRawByte((byte) 1);
- }
- final int length2 = 8 * 1024;
- byte[] data = new byte[length2];
- for (int i = 0; i < length2; i++) {
- data[i] = (byte) 2;
- }
- codedStream.writeRawBytes(data);
- final int length3 = bufferSize - length1 - length2;
- for (int i = 0; i < length3; i++) {
- codedStream.writeRawByte((byte) 3);
- }
- codedStream.flush();
-
- // Check that data is correctly written to the ByteBuffer.
- assertEquals(0, buffer.remaining());
- buffer.flip();
- for (int i = 0; i < length1; i++) {
- assertEquals((byte) 1, buffer.get());
- }
- for (int i = 0; i < length2; i++) {
- assertEquals((byte) 2, buffer.get());
- }
- for (int i = 0; i < length3; i++) {
- assertEquals((byte) 3, buffer.get());
- }
- }
-
- public void testWriteByteBuffer() throws Exception {
- byte[] value = "abcde".getBytes(Internal.UTF_8);
- ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
- CodedOutputStream codedStream = CodedOutputStream.newInstance(outputStream);
- ByteBuffer byteBuffer = ByteBuffer.wrap(value, 0, 1);
- // This will actually write 5 bytes into the CodedOutputStream as the
- // ByteBuffer's capacity() is 5.
- codedStream.writeRawBytes(byteBuffer);
- // The above call shouldn't affect the ByteBuffer's state.
- assertEquals(0, byteBuffer.position());
- assertEquals(1, byteBuffer.limit());
-
- // The correct way to write part of an array using ByteBuffer.
- codedStream.writeRawBytes(ByteBuffer.wrap(value, 2, 1).slice());
-
- codedStream.flush();
- byte[] result = outputStream.toByteArray();
- assertEquals(6, result.length);
- for (int i = 0; i < 5; i++) {
- assertEquals(value[i], result[i]);
- }
- assertEquals(value[2], result[5]);
- }
-
- public void testWriteByteArrayWithOffsets() throws Exception {
- byte[] fullArray = bytes(0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88);
- byte[] destination = new byte[4];
- CodedOutputStream codedStream = CodedOutputStream.newInstance(destination);
- codedStream.writeByteArrayNoTag(fullArray, 2, 2);
- assertEqualBytes(bytes(0x02, 0x33, 0x44, 0x00), destination);
- assertEquals(3, codedStream.getTotalBytesWritten());
- }
-
- public void testSerializeInvalidUtf8() throws Exception {
- String[] invalidStrings = new String[] {
- newString(Character.MIN_HIGH_SURROGATE),
- "foobar" + newString(Character.MIN_HIGH_SURROGATE),
- newString(Character.MIN_LOW_SURROGATE),
- "foobar" + newString(Character.MIN_LOW_SURROGATE),
- newString(Character.MIN_HIGH_SURROGATE, Character.MIN_HIGH_SURROGATE)
- };
-
- CodedOutputStream outputWithStream = CodedOutputStream.newInstance(new ByteArrayOutputStream());
- CodedOutputStream outputWithArray = CodedOutputStream.newInstance(new byte[10000]);
- for (String s : invalidStrings) {
- // TODO(dweis): These should all fail; instead they are corrupting data.
- CodedOutputStream.computeStringSizeNoTag(s);
- outputWithStream.writeStringNoTag(s);
- outputWithArray.writeStringNoTag(s);
- }
- }
-
- private static String newString(char... chars) {
- return new String(chars);
- }
-
- /** Regression test for https://github.com/google/protobuf/issues/292 */
- public void testCorrectExceptionThrowWhenEncodingStringsWithoutEnoughSpace() throws Exception {
- String testCase = "Foooooooo";
- assertEquals(CodedOutputStream.computeRawVarint32Size(testCase.length()),
- CodedOutputStream.computeRawVarint32Size(testCase.length() * 3));
- assertEquals(11, CodedOutputStream.computeStringSize(1, testCase));
- // Tag is one byte, varint describing string length is 1 byte, string length is 9 bytes.
- // An array of size 1 will cause a failure when trying to write the varint.
- for (int i = 0; i < 11; i++) {
- CodedOutputStream output = CodedOutputStream.newInstance(new byte[i]);
- try {
- output.writeString(1, testCase);
- fail("Should have thrown an out of space exception");
- } catch (CodedOutputStream.OutOfSpaceException expected) {}
- }
- }
-
- public void testDifferentStringLengths() throws Exception {
- // Test string serialization roundtrip using strings of the following lengths,
- // with ASCII and Unicode characters requiring different UTF-8 byte counts per
- // char, hence causing the length delimiter varint to sometimes require more
- // bytes for the Unicode strings than the ASCII string of the same length.
- int[] lengths = new int[] {
- 0,
- 1,
- (1 << 4) - 1, // 1 byte for ASCII and Unicode
- (1 << 7) - 1, // 1 byte for ASCII, 2 bytes for Unicode
- (1 << 11) - 1, // 2 bytes for ASCII and Unicode
- (1 << 14) - 1, // 2 bytes for ASCII, 3 bytes for Unicode
- (1 << 17) - 1, // 3 bytes for ASCII and Unicode
- };
- for (int i : lengths) {
- testEncodingOfString('q', i); // 1 byte per char
- testEncodingOfString('\u07FF', i); // 2 bytes per char
- testEncodingOfString('\u0981', i); // 3 bytes per char
- }
- }
-
- private void testEncodingOfString(char c, int length) throws Exception {
- String fullString = fullString(c, length);
- TestAllTypes testAllTypes = TestAllTypes.newBuilder()
- .setOptionalString(fullString)
- .build();
- assertEquals(
- fullString, TestAllTypes.parseFrom(testAllTypes.toByteArray()).getOptionalString());
- }
-
- private String fullString(char c, int length) {
- char[] result = new char[length];
- Arrays.fill(result, c);
- return new String(result);
- }
}
diff --git a/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/DeprecatedFieldTest.java b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/DeprecatedFieldTest.java
new file mode 100644
index 00000000..ee4e7675
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/DeprecatedFieldTest.java
@@ -0,0 +1,81 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf.test;
+import com.google.protobuf.*;
+
+import protobuf_unittest.UnittestProto.TestDeprecatedFields;
+
+import junit.framework.TestCase;
+
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Method;
+/**
+ * Test field deprecation
+ *
+ * @author birdo@google.com (Roberto Scaramuzzi)
+ */
+public class DeprecatedFieldTest extends TestCase {
+ private String[] deprecatedGetterNames = {
+ "hasDeprecatedInt32",
+ "getDeprecatedInt32"};
+
+ private String[] deprecatedBuilderGetterNames = {
+ "hasDeprecatedInt32",
+ "getDeprecatedInt32",
+ "clearDeprecatedInt32"};
+
+ private String[] deprecatedBuilderSetterNames = {
+ "setDeprecatedInt32"};
+
+ public void testDeprecatedField() throws Exception {
+ Class<?> deprecatedFields = TestDeprecatedFields.class;
+ Class<?> deprecatedFieldsBuilder = TestDeprecatedFields.Builder.class;
+ for (String name : deprecatedGetterNames) {
+ Method method = deprecatedFields.getMethod(name);
+ assertTrue("Method " + name + " should be deprecated",
+ isDeprecated(method));
+ }
+ for (String name : deprecatedBuilderGetterNames) {
+ Method method = deprecatedFieldsBuilder.getMethod(name);
+ assertTrue("Method " + name + " should be deprecated",
+ isDeprecated(method));
+ }
+ for (String name : deprecatedBuilderSetterNames) {
+ Method method = deprecatedFieldsBuilder.getMethod(name, int.class);
+ assertTrue("Method " + name + " should be deprecated",
+ isDeprecated(method));
+ }
+ }
+
+ private boolean isDeprecated(AnnotatedElement annotated) {
+ return annotated.isAnnotationPresent(Deprecated.class);
+ }
+}
diff --git a/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/DescriptorsTest.java b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/DescriptorsTest.java
new file mode 100644
index 00000000..aabd7b4d
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/DescriptorsTest.java
@@ -0,0 +1,649 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf.test;
+import com.google.protobuf.*;
+
+import com.google.protobuf.DescriptorProtos.DescriptorProto;
+import com.google.protobuf.DescriptorProtos.EnumDescriptorProto;
+import com.google.protobuf.DescriptorProtos.EnumValueDescriptorProto;
+import com.google.protobuf.DescriptorProtos.FieldDescriptorProto;
+import com.google.protobuf.DescriptorProtos.FileDescriptorProto;
+import com.google.protobuf.Descriptors.DescriptorValidationException;
+import com.google.protobuf.Descriptors.FileDescriptor;
+import com.google.protobuf.Descriptors.Descriptor;
+import com.google.protobuf.Descriptors.FieldDescriptor;
+import com.google.protobuf.Descriptors.EnumDescriptor;
+import com.google.protobuf.Descriptors.EnumValueDescriptor;
+import com.google.protobuf.Descriptors.ServiceDescriptor;
+import com.google.protobuf.Descriptors.MethodDescriptor;
+
+import com.google.protobuf.test.UnittestImport;
+import com.google.protobuf.test.UnittestImport.ImportEnum;
+import com.google.protobuf.test.UnittestImport.ImportMessage;
+import protobuf_unittest.UnittestProto;
+import protobuf_unittest.UnittestProto.ForeignEnum;
+import protobuf_unittest.UnittestProto.ForeignMessage;
+import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestAllExtensions;
+import protobuf_unittest.UnittestProto.TestExtremeDefaultValues;
+import protobuf_unittest.UnittestProto.TestRequired;
+import protobuf_unittest.UnittestProto.TestService;
+import protobuf_unittest.UnittestCustomOptions;
+
+
+import junit.framework.TestCase;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Unit test for {@link Descriptors}.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public class DescriptorsTest extends TestCase {
+
+ // Regression test for bug where referencing a FieldDescriptor.Type value
+ // before a FieldDescriptorProto.Type value would yield a
+ // ExceptionInInitializerError.
+ @SuppressWarnings("unused")
+ private static final Object STATIC_INIT_TEST = FieldDescriptor.Type.BOOL;
+
+ public void testFieldTypeEnumMapping() throws Exception {
+ assertEquals(FieldDescriptor.Type.values().length,
+ FieldDescriptorProto.Type.values().length);
+ for (FieldDescriptor.Type type : FieldDescriptor.Type.values()) {
+ FieldDescriptorProto.Type protoType = type.toProto();
+ assertEquals("TYPE_" + type.name(), protoType.name());
+ assertEquals(type, FieldDescriptor.Type.valueOf(protoType));
+ }
+ }
+
+ public void testFileDescriptor() throws Exception {
+ FileDescriptor file = UnittestProto.getDescriptor();
+
+ assertEquals("google/protobuf/unittest.proto", file.getName());
+ assertEquals("protobuf_unittest", file.getPackage());
+
+ assertEquals("UnittestProto", file.getOptions().getJavaOuterClassname());
+ assertEquals("google/protobuf/unittest.proto",
+ file.toProto().getName());
+
+ assertEquals(Arrays.asList(UnittestImport.getDescriptor()),
+ file.getDependencies());
+
+ Descriptor messageType = TestAllTypes.getDescriptor();
+ assertEquals(messageType, file.getMessageTypes().get(0));
+ assertEquals(messageType, file.findMessageTypeByName("TestAllTypes"));
+ assertNull(file.findMessageTypeByName("NoSuchType"));
+ assertNull(file.findMessageTypeByName("protobuf_unittest.TestAllTypes"));
+ for (int i = 0; i < file.getMessageTypes().size(); i++) {
+ assertEquals(i, file.getMessageTypes().get(i).getIndex());
+ }
+
+ EnumDescriptor enumType = ForeignEnum.getDescriptor();
+ assertEquals(enumType, file.getEnumTypes().get(0));
+ assertEquals(enumType, file.findEnumTypeByName("ForeignEnum"));
+ assertNull(file.findEnumTypeByName("NoSuchType"));
+ assertNull(file.findEnumTypeByName("protobuf_unittest.ForeignEnum"));
+ assertEquals(Arrays.asList(ImportEnum.getDescriptor()),
+ UnittestImport.getDescriptor().getEnumTypes());
+ for (int i = 0; i < file.getEnumTypes().size(); i++) {
+ assertEquals(i, file.getEnumTypes().get(i).getIndex());
+ }
+
+ ServiceDescriptor service = TestService.getDescriptor();
+ assertEquals(service, file.getServices().get(0));
+ assertEquals(service, file.findServiceByName("TestService"));
+ assertNull(file.findServiceByName("NoSuchType"));
+ assertNull(file.findServiceByName("protobuf_unittest.TestService"));
+ assertEquals(Collections.emptyList(),
+ UnittestImport.getDescriptor().getServices());
+ for (int i = 0; i < file.getServices().size(); i++) {
+ assertEquals(i, file.getServices().get(i).getIndex());
+ }
+
+ FieldDescriptor extension =
+ UnittestProto.optionalInt32Extension.getDescriptor();
+ assertEquals(extension, file.getExtensions().get(0));
+ assertEquals(extension,
+ file.findExtensionByName("optional_int32_extension"));
+ assertNull(file.findExtensionByName("no_such_ext"));
+ assertNull(file.findExtensionByName(
+ "protobuf_unittest.optional_int32_extension"));
+ assertEquals(Collections.emptyList(),
+ UnittestImport.getDescriptor().getExtensions());
+ for (int i = 0; i < file.getExtensions().size(); i++) {
+ assertEquals(i, file.getExtensions().get(i).getIndex());
+ }
+ }
+
+ public void testDescriptor() throws Exception {
+ Descriptor messageType = TestAllTypes.getDescriptor();
+ Descriptor nestedType = TestAllTypes.NestedMessage.getDescriptor();
+
+ assertEquals("TestAllTypes", messageType.getName());
+ assertEquals("protobuf_unittest.TestAllTypes", messageType.getFullName());
+ assertEquals(UnittestProto.getDescriptor(), messageType.getFile());
+ assertNull(messageType.getContainingType());
+ assertEquals(DescriptorProtos.MessageOptions.getDefaultInstance(),
+ messageType.getOptions());
+ assertEquals("TestAllTypes", messageType.toProto().getName());
+
+ assertEquals("NestedMessage", nestedType.getName());
+ assertEquals("protobuf_unittest.TestAllTypes.NestedMessage",
+ nestedType.getFullName());
+ assertEquals(UnittestProto.getDescriptor(), nestedType.getFile());
+ assertEquals(messageType, nestedType.getContainingType());
+
+ FieldDescriptor field = messageType.getFields().get(0);
+ assertEquals("optional_int32", field.getName());
+ assertEquals(field, messageType.findFieldByName("optional_int32"));
+ assertNull(messageType.findFieldByName("no_such_field"));
+ assertEquals(field, messageType.findFieldByNumber(1));
+ assertNull(messageType.findFieldByNumber(571283));
+ for (int i = 0; i < messageType.getFields().size(); i++) {
+ assertEquals(i, messageType.getFields().get(i).getIndex());
+ }
+
+ assertEquals(nestedType, messageType.getNestedTypes().get(0));
+ assertEquals(nestedType, messageType.findNestedTypeByName("NestedMessage"));
+ assertNull(messageType.findNestedTypeByName("NoSuchType"));
+ for (int i = 0; i < messageType.getNestedTypes().size(); i++) {
+ assertEquals(i, messageType.getNestedTypes().get(i).getIndex());
+ }
+
+ EnumDescriptor enumType = TestAllTypes.NestedEnum.getDescriptor();
+ assertEquals(enumType, messageType.getEnumTypes().get(0));
+ assertEquals(enumType, messageType.findEnumTypeByName("NestedEnum"));
+ assertNull(messageType.findEnumTypeByName("NoSuchType"));
+ for (int i = 0; i < messageType.getEnumTypes().size(); i++) {
+ assertEquals(i, messageType.getEnumTypes().get(i).getIndex());
+ }
+ }
+
+ public void testFieldDescriptor() throws Exception {
+ Descriptor messageType = TestAllTypes.getDescriptor();
+ FieldDescriptor primitiveField =
+ messageType.findFieldByName("optional_int32");
+ FieldDescriptor enumField =
+ messageType.findFieldByName("optional_nested_enum");
+ FieldDescriptor messageField =
+ messageType.findFieldByName("optional_foreign_message");
+ FieldDescriptor cordField =
+ messageType.findFieldByName("optional_cord");
+ FieldDescriptor extension =
+ UnittestProto.optionalInt32Extension.getDescriptor();
+ FieldDescriptor nestedExtension = TestRequired.single.getDescriptor();
+
+ assertEquals("optional_int32", primitiveField.getName());
+ assertEquals("protobuf_unittest.TestAllTypes.optional_int32",
+ primitiveField.getFullName());
+ assertEquals(1, primitiveField.getNumber());
+ assertEquals(messageType, primitiveField.getContainingType());
+ assertEquals(UnittestProto.getDescriptor(), primitiveField.getFile());
+ assertEquals(FieldDescriptor.Type.INT32, primitiveField.getType());
+ assertEquals(FieldDescriptor.JavaType.INT, primitiveField.getJavaType());
+ assertEquals(DescriptorProtos.FieldOptions.getDefaultInstance(),
+ primitiveField.getOptions());
+ assertFalse(primitiveField.isExtension());
+ assertEquals("optional_int32", primitiveField.toProto().getName());
+
+ assertEquals("optional_nested_enum", enumField.getName());
+ assertEquals(FieldDescriptor.Type.ENUM, enumField.getType());
+ assertEquals(FieldDescriptor.JavaType.ENUM, enumField.getJavaType());
+ assertEquals(TestAllTypes.NestedEnum.getDescriptor(),
+ enumField.getEnumType());
+
+ assertEquals("optional_foreign_message", messageField.getName());
+ assertEquals(FieldDescriptor.Type.MESSAGE, messageField.getType());
+ assertEquals(FieldDescriptor.JavaType.MESSAGE, messageField.getJavaType());
+ assertEquals(ForeignMessage.getDescriptor(), messageField.getMessageType());
+
+ assertEquals("optional_cord", cordField.getName());
+ assertEquals(FieldDescriptor.Type.STRING, cordField.getType());
+ assertEquals(FieldDescriptor.JavaType.STRING, cordField.getJavaType());
+ assertEquals(DescriptorProtos.FieldOptions.CType.CORD,
+ cordField.getOptions().getCtype());
+
+ assertEquals("optional_int32_extension", extension.getName());
+ assertEquals("protobuf_unittest.optional_int32_extension",
+ extension.getFullName());
+ assertEquals(1, extension.getNumber());
+ assertEquals(TestAllExtensions.getDescriptor(),
+ extension.getContainingType());
+ assertEquals(UnittestProto.getDescriptor(), extension.getFile());
+ assertEquals(FieldDescriptor.Type.INT32, extension.getType());
+ assertEquals(FieldDescriptor.JavaType.INT, extension.getJavaType());
+ assertEquals(DescriptorProtos.FieldOptions.getDefaultInstance(),
+ extension.getOptions());
+ assertTrue(extension.isExtension());
+ assertEquals(null, extension.getExtensionScope());
+ assertEquals("optional_int32_extension", extension.toProto().getName());
+
+ assertEquals("single", nestedExtension.getName());
+ assertEquals("protobuf_unittest.TestRequired.single",
+ nestedExtension.getFullName());
+ assertEquals(TestRequired.getDescriptor(),
+ nestedExtension.getExtensionScope());
+ }
+
+ public void testFieldDescriptorLabel() throws Exception {
+ FieldDescriptor requiredField =
+ TestRequired.getDescriptor().findFieldByName("a");
+ FieldDescriptor optionalField =
+ TestAllTypes.getDescriptor().findFieldByName("optional_int32");
+ FieldDescriptor repeatedField =
+ TestAllTypes.getDescriptor().findFieldByName("repeated_int32");
+
+ assertTrue(requiredField.isRequired());
+ assertFalse(requiredField.isRepeated());
+ assertFalse(optionalField.isRequired());
+ assertFalse(optionalField.isRepeated());
+ assertFalse(repeatedField.isRequired());
+ assertTrue(repeatedField.isRepeated());
+ }
+
+ public void testFieldDescriptorDefault() throws Exception {
+ Descriptor d = TestAllTypes.getDescriptor();
+ assertFalse(d.findFieldByName("optional_int32").hasDefaultValue());
+ assertEquals(0, d.findFieldByName("optional_int32").getDefaultValue());
+ assertTrue(d.findFieldByName("default_int32").hasDefaultValue());
+ assertEquals(41, d.findFieldByName("default_int32").getDefaultValue());
+
+ d = TestExtremeDefaultValues.getDescriptor();
+ assertEquals(
+ ByteString.copyFrom(
+ "\0\001\007\b\f\n\r\t\013\\\'\"\u00fe".getBytes("ISO-8859-1")),
+ d.findFieldByName("escaped_bytes").getDefaultValue());
+ assertEquals(-1, d.findFieldByName("large_uint32").getDefaultValue());
+ assertEquals(-1L, d.findFieldByName("large_uint64").getDefaultValue());
+ }
+
+ public void testEnumDescriptor() throws Exception {
+ EnumDescriptor enumType = ForeignEnum.getDescriptor();
+ EnumDescriptor nestedType = TestAllTypes.NestedEnum.getDescriptor();
+
+ assertEquals("ForeignEnum", enumType.getName());
+ assertEquals("protobuf_unittest.ForeignEnum", enumType.getFullName());
+ assertEquals(UnittestProto.getDescriptor(), enumType.getFile());
+ assertNull(enumType.getContainingType());
+ assertEquals(DescriptorProtos.EnumOptions.getDefaultInstance(),
+ enumType.getOptions());
+
+ assertEquals("NestedEnum", nestedType.getName());
+ assertEquals("protobuf_unittest.TestAllTypes.NestedEnum",
+ nestedType.getFullName());
+ assertEquals(UnittestProto.getDescriptor(), nestedType.getFile());
+ assertEquals(TestAllTypes.getDescriptor(), nestedType.getContainingType());
+
+ EnumValueDescriptor value = ForeignEnum.FOREIGN_FOO.getValueDescriptor();
+ assertEquals(value, enumType.getValues().get(0));
+ assertEquals("FOREIGN_FOO", value.getName());
+ assertEquals(4, value.getNumber());
+ assertEquals(value, enumType.findValueByName("FOREIGN_FOO"));
+ assertEquals(value, enumType.findValueByNumber(4));
+ assertNull(enumType.findValueByName("NO_SUCH_VALUE"));
+ for (int i = 0; i < enumType.getValues().size(); i++) {
+ assertEquals(i, enumType.getValues().get(i).getIndex());
+ }
+ }
+
+ public void testServiceDescriptor() throws Exception {
+ ServiceDescriptor service = TestService.getDescriptor();
+
+ assertEquals("TestService", service.getName());
+ assertEquals("protobuf_unittest.TestService", service.getFullName());
+ assertEquals(UnittestProto.getDescriptor(), service.getFile());
+
+ assertEquals(2, service.getMethods().size());
+
+ MethodDescriptor fooMethod = service.getMethods().get(0);
+ assertEquals("Foo", fooMethod.getName());
+ assertEquals(UnittestProto.FooRequest.getDescriptor(),
+ fooMethod.getInputType());
+ assertEquals(UnittestProto.FooResponse.getDescriptor(),
+ fooMethod.getOutputType());
+ assertEquals(fooMethod, service.findMethodByName("Foo"));
+
+ MethodDescriptor barMethod = service.getMethods().get(1);
+ assertEquals("Bar", barMethod.getName());
+ assertEquals(UnittestProto.BarRequest.getDescriptor(),
+ barMethod.getInputType());
+ assertEquals(UnittestProto.BarResponse.getDescriptor(),
+ barMethod.getOutputType());
+ assertEquals(barMethod, service.findMethodByName("Bar"));
+
+ assertNull(service.findMethodByName("NoSuchMethod"));
+
+ for (int i = 0; i < service.getMethods().size(); i++) {
+ assertEquals(i, service.getMethods().get(i).getIndex());
+ }
+ }
+
+
+ public void testCustomOptions() throws Exception {
+ Descriptor descriptor =
+ UnittestCustomOptions.TestMessageWithCustomOptions.getDescriptor();
+
+ assertTrue(
+ descriptor.getOptions().hasExtension(UnittestCustomOptions.messageOpt1));
+ assertEquals(Integer.valueOf(-56),
+ descriptor.getOptions().getExtension(UnittestCustomOptions.messageOpt1));
+
+ FieldDescriptor field = descriptor.findFieldByName("field1");
+ assertNotNull(field);
+
+ assertTrue(
+ field.getOptions().hasExtension(UnittestCustomOptions.fieldOpt1));
+ assertEquals(Long.valueOf(8765432109L),
+ field.getOptions().getExtension(UnittestCustomOptions.fieldOpt1));
+
+ EnumDescriptor enumType =
+ UnittestCustomOptions.TestMessageWithCustomOptions.AnEnum.getDescriptor();
+
+ assertTrue(
+ enumType.getOptions().hasExtension(UnittestCustomOptions.enumOpt1));
+ assertEquals(Integer.valueOf(-789),
+ enumType.getOptions().getExtension(UnittestCustomOptions.enumOpt1));
+
+ ServiceDescriptor service =
+ UnittestCustomOptions.TestServiceWithCustomOptions.getDescriptor();
+
+ assertTrue(
+ service.getOptions().hasExtension(UnittestCustomOptions.serviceOpt1));
+ assertEquals(Long.valueOf(-9876543210L),
+ service.getOptions().getExtension(UnittestCustomOptions.serviceOpt1));
+
+ MethodDescriptor method = service.findMethodByName("Foo");
+ assertNotNull(method);
+
+ assertTrue(
+ method.getOptions().hasExtension(UnittestCustomOptions.methodOpt1));
+ assertEquals(UnittestCustomOptions.MethodOpt1.METHODOPT1_VAL2,
+ method.getOptions().getExtension(UnittestCustomOptions.methodOpt1));
+ }
+
+ /**
+ * Test that the FieldDescriptor.Type enum is the same as the
+ * WireFormat.FieldType enum.
+ */
+ public void testFieldTypeTablesMatch() throws Exception {
+ FieldDescriptor.Type[] values1 = FieldDescriptor.Type.values();
+ WireFormat.FieldType[] values2 = WireFormat.FieldType.values();
+
+ assertEquals(values1.length, values2.length);
+
+ for (int i = 0; i < values1.length; i++) {
+ assertEquals(values1[i].toString(), values2[i].toString());
+ }
+ }
+
+ /**
+ * Test that the FieldDescriptor.JavaType enum is the same as the
+ * WireFormat.JavaType enum.
+ */
+ public void testJavaTypeTablesMatch() throws Exception {
+ FieldDescriptor.JavaType[] values1 = FieldDescriptor.JavaType.values();
+ WireFormat.JavaType[] values2 = WireFormat.JavaType.values();
+
+ assertEquals(values1.length, values2.length);
+
+ for (int i = 0; i < values1.length; i++) {
+ assertEquals(values1[i].toString(), values2[i].toString());
+ }
+ }
+
+ public void testEnormousDescriptor() throws Exception {
+ // The descriptor for this file is larger than 64k, yet it did not cause
+ // a compiler error due to an over-long string literal.
+ assertTrue(
+ UnittestEnormousDescriptor.getDescriptor()
+ .toProto().getSerializedSize() > 65536);
+ }
+
+ /**
+ * Tests that the DescriptorValidationException works as intended.
+ */
+ public void testDescriptorValidatorException() throws Exception {
+ FileDescriptorProto fileDescriptorProto = FileDescriptorProto.newBuilder()
+ .setName("foo.proto")
+ .addMessageType(DescriptorProto.newBuilder()
+ .setName("Foo")
+ .addField(FieldDescriptorProto.newBuilder()
+ .setLabel(FieldDescriptorProto.Label.LABEL_OPTIONAL)
+ .setType(FieldDescriptorProto.Type.TYPE_INT32)
+ .setName("foo")
+ .setNumber(1)
+ .setDefaultValue("invalid")
+ .build())
+ .build())
+ .build();
+ try {
+ Descriptors.FileDescriptor.buildFrom(fileDescriptorProto,
+ new FileDescriptor[0]);
+ fail("DescriptorValidationException expected");
+ } catch (DescriptorValidationException e) {
+ // Expected; check that the error message contains some useful hints
+ assertTrue(e.getMessage().indexOf("foo") != -1);
+ assertTrue(e.getMessage().indexOf("Foo") != -1);
+ assertTrue(e.getMessage().indexOf("invalid") != -1);
+ assertTrue(e.getCause() instanceof NumberFormatException);
+ assertTrue(e.getCause().getMessage().indexOf("invalid") != -1);
+ }
+ }
+
+ /**
+ * Tests the translate/crosslink for an example where a message field's name
+ * and type name are the same.
+ */
+ public void testDescriptorComplexCrosslink() throws Exception {
+ FileDescriptorProto fileDescriptorProto = FileDescriptorProto.newBuilder()
+ .setName("foo.proto")
+ .addMessageType(DescriptorProto.newBuilder()
+ .setName("Foo")
+ .addField(FieldDescriptorProto.newBuilder()
+ .setLabel(FieldDescriptorProto.Label.LABEL_OPTIONAL)
+ .setType(FieldDescriptorProto.Type.TYPE_INT32)
+ .setName("foo")
+ .setNumber(1)
+ .build())
+ .build())
+ .addMessageType(DescriptorProto.newBuilder()
+ .setName("Bar")
+ .addField(FieldDescriptorProto.newBuilder()
+ .setLabel(FieldDescriptorProto.Label.LABEL_OPTIONAL)
+ .setTypeName("Foo")
+ .setName("Foo")
+ .setNumber(1)
+ .build())
+ .build())
+ .build();
+ // translate and crosslink
+ FileDescriptor file =
+ Descriptors.FileDescriptor.buildFrom(fileDescriptorProto,
+ new FileDescriptor[0]);
+ // verify resulting descriptors
+ assertNotNull(file);
+ List<Descriptor> msglist = file.getMessageTypes();
+ assertNotNull(msglist);
+ assertTrue(msglist.size() == 2);
+ boolean barFound = false;
+ for (Descriptor desc : msglist) {
+ if (desc.getName().equals("Bar")) {
+ barFound = true;
+ assertNotNull(desc.getFields());
+ List<FieldDescriptor> fieldlist = desc.getFields();
+ assertNotNull(fieldlist);
+ assertTrue(fieldlist.size() == 1);
+ assertTrue(fieldlist.get(0).getType() == FieldDescriptor.Type.MESSAGE);
+ assertTrue(fieldlist.get(0).getMessageType().getName().equals("Foo"));
+ }
+ }
+ assertTrue(barFound);
+ }
+
+ public void testInvalidPublicDependency() throws Exception {
+ FileDescriptorProto fooProto = FileDescriptorProto.newBuilder()
+ .setName("foo.proto") .build();
+ FileDescriptorProto barProto = FileDescriptorProto.newBuilder()
+ .setName("boo.proto")
+ .addDependency("foo.proto")
+ .addPublicDependency(1) // Error, should be 0.
+ .build();
+ FileDescriptor fooFile = Descriptors.FileDescriptor.buildFrom(fooProto,
+ new FileDescriptor[0]);
+ try {
+ Descriptors.FileDescriptor.buildFrom(barProto,
+ new FileDescriptor[] {fooFile});
+ fail("DescriptorValidationException expected");
+ } catch (DescriptorValidationException e) {
+ assertTrue(
+ e.getMessage().indexOf("Invalid public dependency index.") != -1);
+ }
+ }
+
+ public void testHiddenDependency() throws Exception {
+ FileDescriptorProto barProto = FileDescriptorProto.newBuilder()
+ .setName("bar.proto")
+ .addMessageType(DescriptorProto.newBuilder().setName("Bar"))
+ .build();
+ FileDescriptorProto forwardProto = FileDescriptorProto.newBuilder()
+ .setName("forward.proto")
+ .addDependency("bar.proto")
+ .build();
+ FileDescriptorProto fooProto = FileDescriptorProto.newBuilder()
+ .setName("foo.proto")
+ .addDependency("forward.proto")
+ .addMessageType(DescriptorProto.newBuilder()
+ .setName("Foo")
+ .addField(FieldDescriptorProto.newBuilder()
+ .setLabel(FieldDescriptorProto.Label.LABEL_OPTIONAL)
+ .setTypeName("Bar")
+ .setName("bar")
+ .setNumber(1)))
+ .build();
+ FileDescriptor barFile = Descriptors.FileDescriptor.buildFrom(
+ barProto, new FileDescriptor[0]);
+ FileDescriptor forwardFile = Descriptors.FileDescriptor.buildFrom(
+ forwardProto, new FileDescriptor[] {barFile});
+
+ try {
+ Descriptors.FileDescriptor.buildFrom(
+ fooProto, new FileDescriptor[] {forwardFile});
+ fail("DescriptorValidationException expected");
+ } catch (DescriptorValidationException e) {
+ assertTrue(e.getMessage().indexOf("Bar") != -1);
+ assertTrue(e.getMessage().indexOf("is not defined") != -1);
+ }
+ }
+
+ public void testPublicDependency() throws Exception {
+ FileDescriptorProto barProto = FileDescriptorProto.newBuilder()
+ .setName("bar.proto")
+ .addMessageType(DescriptorProto.newBuilder().setName("Bar"))
+ .build();
+ FileDescriptorProto forwardProto = FileDescriptorProto.newBuilder()
+ .setName("forward.proto")
+ .addDependency("bar.proto")
+ .addPublicDependency(0)
+ .build();
+ FileDescriptorProto fooProto = FileDescriptorProto.newBuilder()
+ .setName("foo.proto")
+ .addDependency("forward.proto")
+ .addMessageType(DescriptorProto.newBuilder()
+ .setName("Foo")
+ .addField(FieldDescriptorProto.newBuilder()
+ .setLabel(FieldDescriptorProto.Label.LABEL_OPTIONAL)
+ .setTypeName("Bar")
+ .setName("bar")
+ .setNumber(1)))
+ .build();
+ FileDescriptor barFile = Descriptors.FileDescriptor.buildFrom(
+ barProto, new FileDescriptor[0]);
+ FileDescriptor forwardFile = Descriptors.FileDescriptor.buildFrom(
+ forwardProto, new FileDescriptor[]{barFile});
+ Descriptors.FileDescriptor.buildFrom(
+ fooProto, new FileDescriptor[] {forwardFile});
+ }
+
+ /**
+ * Tests the translate/crosslink for an example with a more complex namespace
+ * referencing.
+ */
+ public void testComplexNamespacePublicDependency() throws Exception {
+ FileDescriptorProto fooProto = FileDescriptorProto.newBuilder()
+ .setName("bar.proto")
+ .setPackage("a.b.c.d.bar.shared")
+ .addEnumType(EnumDescriptorProto.newBuilder()
+ .setName("MyEnum")
+ .addValue(EnumValueDescriptorProto.newBuilder()
+ .setName("BLAH")
+ .setNumber(1)))
+ .build();
+ FileDescriptorProto barProto = FileDescriptorProto.newBuilder()
+ .setName("foo.proto")
+ .addDependency("bar.proto")
+ .setPackage("a.b.c.d.foo.shared")
+ .addMessageType(DescriptorProto.newBuilder()
+ .setName("MyMessage")
+ .addField(FieldDescriptorProto.newBuilder()
+ .setLabel(FieldDescriptorProto.Label.LABEL_REPEATED)
+ .setTypeName("bar.shared.MyEnum")
+ .setName("MyField")
+ .setNumber(1)))
+ .build();
+ // translate and crosslink
+ FileDescriptor fooFile = Descriptors.FileDescriptor.buildFrom(
+ fooProto, new FileDescriptor[0]);
+ FileDescriptor barFile = Descriptors.FileDescriptor.buildFrom(
+ barProto, new FileDescriptor[]{fooFile});
+ // verify resulting descriptors
+ assertNotNull(barFile);
+ List<Descriptor> msglist = barFile.getMessageTypes();
+ assertNotNull(msglist);
+ assertTrue(msglist.size() == 1);
+ Descriptor desc = msglist.get(0);
+ if (desc.getName().equals("MyMessage")) {
+ assertNotNull(desc.getFields());
+ List<FieldDescriptor> fieldlist = desc.getFields();
+ assertNotNull(fieldlist);
+ assertTrue(fieldlist.size() == 1);
+ FieldDescriptor field = fieldlist.get(0);
+ assertTrue(field.getType() == FieldDescriptor.Type.ENUM);
+ assertTrue(field.getEnumType().getName().equals("MyEnum"));
+ assertTrue(field.getEnumType().getFile().getName().equals("bar.proto"));
+ assertTrue(field.getEnumType().getFile().getPackage().equals(
+ "a.b.c.d.bar.shared"));
+ }
+ }
+}
diff --git a/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/DynamicMessageTest.java b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/DynamicMessageTest.java
new file mode 100644
index 00000000..00230678
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/DynamicMessageTest.java
@@ -0,0 +1,265 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf.test;
+import com.google.protobuf.*;
+
+import protobuf_unittest.UnittestProto.TestAllExtensions;
+import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestEmptyMessage;
+import protobuf_unittest.UnittestProto.TestPackedTypes;
+
+import junit.framework.TestCase;
+import java.util.Arrays;
+
+/**
+ * Unit test for {@link DynamicMessage}. See also {@link MessageTest}, which
+ * tests some {@link DynamicMessage} functionality.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public class DynamicMessageTest extends TestCase {
+ TestUtil.ReflectionTester reflectionTester =
+ new TestUtil.ReflectionTester(TestAllTypes.getDescriptor(), null);
+
+ TestUtil.ReflectionTester extensionsReflectionTester =
+ new TestUtil.ReflectionTester(TestAllExtensions.getDescriptor(),
+ TestUtil.getExtensionRegistry());
+ TestUtil.ReflectionTester packedReflectionTester =
+ new TestUtil.ReflectionTester(TestPackedTypes.getDescriptor(), null);
+
+ public void testDynamicMessageAccessors() throws Exception {
+ Message.Builder builder =
+ DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
+ reflectionTester.setAllFieldsViaReflection(builder);
+ Message message = builder.build();
+ reflectionTester.assertAllFieldsSetViaReflection(message);
+ }
+
+ public void testSettersAfterBuild() throws Exception {
+ Message.Builder builder =
+ DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
+ Message firstMessage = builder.build();
+ // double build()
+ builder.build();
+ // clear() after build()
+ builder.clear();
+ // setters after build()
+ reflectionTester.setAllFieldsViaReflection(builder);
+ Message message = builder.build();
+ reflectionTester.assertAllFieldsSetViaReflection(message);
+ // repeated setters after build()
+ reflectionTester.modifyRepeatedFieldsViaReflection(builder);
+ message = builder.build();
+ reflectionTester.assertRepeatedFieldsModifiedViaReflection(message);
+ // firstMessage shouldn't have been modified.
+ reflectionTester.assertClearViaReflection(firstMessage);
+ }
+
+ public void testUnknownFields() throws Exception {
+ Message.Builder builder =
+ DynamicMessage.newBuilder(TestEmptyMessage.getDescriptor());
+ builder.setUnknownFields(UnknownFieldSet.newBuilder()
+ .addField(1, UnknownFieldSet.Field.newBuilder().addVarint(1).build())
+ .addField(2, UnknownFieldSet.Field.newBuilder().addFixed32(1).build())
+ .build());
+ Message message = builder.build();
+ assertEquals(2, message.getUnknownFields().asMap().size());
+ // clone() with unknown fields
+ Message.Builder newBuilder = builder.clone();
+ assertEquals(2, newBuilder.getUnknownFields().asMap().size());
+ // clear() with unknown fields
+ newBuilder.clear();
+ assertTrue(newBuilder.getUnknownFields().asMap().isEmpty());
+ // serialize/parse with unknown fields
+ newBuilder.mergeFrom(message.toByteString());
+ assertEquals(2, newBuilder.getUnknownFields().asMap().size());
+ }
+
+ public void testDynamicMessageSettersRejectNull() throws Exception {
+ Message.Builder builder =
+ DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
+ reflectionTester.assertReflectionSettersRejectNull(builder);
+ }
+
+ public void testDynamicMessageExtensionAccessors() throws Exception {
+ // We don't need to extensively test DynamicMessage's handling of
+ // extensions because, frankly, it doesn't do anything special with them.
+ // It treats them just like any other fields.
+ Message.Builder builder =
+ DynamicMessage.newBuilder(TestAllExtensions.getDescriptor());
+ extensionsReflectionTester.setAllFieldsViaReflection(builder);
+ Message message = builder.build();
+ extensionsReflectionTester.assertAllFieldsSetViaReflection(message);
+ }
+
+ public void testDynamicMessageExtensionSettersRejectNull() throws Exception {
+ Message.Builder builder =
+ DynamicMessage.newBuilder(TestAllExtensions.getDescriptor());
+ extensionsReflectionTester.assertReflectionSettersRejectNull(builder);
+ }
+
+ public void testDynamicMessageRepeatedSetters() throws Exception {
+ Message.Builder builder =
+ DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
+ reflectionTester.setAllFieldsViaReflection(builder);
+ reflectionTester.modifyRepeatedFieldsViaReflection(builder);
+ Message message = builder.build();
+ reflectionTester.assertRepeatedFieldsModifiedViaReflection(message);
+ }
+
+ public void testDynamicMessageRepeatedSettersRejectNull() throws Exception {
+ Message.Builder builder =
+ DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
+ reflectionTester.assertReflectionRepeatedSettersRejectNull(builder);
+ }
+
+ public void testDynamicMessageDefaults() throws Exception {
+ reflectionTester.assertClearViaReflection(
+ DynamicMessage.getDefaultInstance(TestAllTypes.getDescriptor()));
+ reflectionTester.assertClearViaReflection(
+ DynamicMessage.newBuilder(TestAllTypes.getDescriptor()).build());
+ }
+
+ public void testDynamicMessageSerializedSize() throws Exception {
+ TestAllTypes message = TestUtil.getAllSet();
+
+ Message.Builder dynamicBuilder =
+ DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
+ reflectionTester.setAllFieldsViaReflection(dynamicBuilder);
+ Message dynamicMessage = dynamicBuilder.build();
+
+ assertEquals(message.getSerializedSize(),
+ dynamicMessage.getSerializedSize());
+ }
+
+ public void testDynamicMessageSerialization() throws Exception {
+ Message.Builder builder =
+ DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
+ reflectionTester.setAllFieldsViaReflection(builder);
+ Message message = builder.build();
+
+ ByteString rawBytes = message.toByteString();
+ TestAllTypes message2 = TestAllTypes.parseFrom(rawBytes);
+
+ TestUtil.assertAllFieldsSet(message2);
+
+ // In fact, the serialized forms should be exactly the same, byte-for-byte.
+ assertEquals(TestUtil.getAllSet().toByteString(), rawBytes);
+ }
+
+ public void testDynamicMessageParsing() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TestUtil.setAllFields(builder);
+ TestAllTypes message = builder.build();
+
+ ByteString rawBytes = message.toByteString();
+
+ Message message2 =
+ DynamicMessage.parseFrom(TestAllTypes.getDescriptor(), rawBytes);
+ reflectionTester.assertAllFieldsSetViaReflection(message2);
+
+ // Test Parser interface.
+ Message message3 = message2.getParserForType().parseFrom(rawBytes);
+ reflectionTester.assertAllFieldsSetViaReflection(message3);
+ }
+
+ public void testDynamicMessageExtensionParsing() throws Exception {
+ ByteString rawBytes = TestUtil.getAllExtensionsSet().toByteString();
+ Message message = DynamicMessage.parseFrom(
+ TestAllExtensions.getDescriptor(), rawBytes,
+ TestUtil.getExtensionRegistry());
+ extensionsReflectionTester.assertAllFieldsSetViaReflection(message);
+
+ // Test Parser interface.
+ Message message2 = message.getParserForType().parseFrom(
+ rawBytes, TestUtil.getExtensionRegistry());
+ extensionsReflectionTester.assertAllFieldsSetViaReflection(message2);
+ }
+
+ public void testDynamicMessagePackedSerialization() throws Exception {
+ Message.Builder builder =
+ DynamicMessage.newBuilder(TestPackedTypes.getDescriptor());
+ packedReflectionTester.setPackedFieldsViaReflection(builder);
+ Message message = builder.build();
+
+ ByteString rawBytes = message.toByteString();
+ TestPackedTypes message2 = TestPackedTypes.parseFrom(rawBytes);
+
+ TestUtil.assertPackedFieldsSet(message2);
+
+ // In fact, the serialized forms should be exactly the same, byte-for-byte.
+ assertEquals(TestUtil.getPackedSet().toByteString(), rawBytes);
+ }
+
+ public void testDynamicMessagePackedParsing() throws Exception {
+ TestPackedTypes.Builder builder = TestPackedTypes.newBuilder();
+ TestUtil.setPackedFields(builder);
+ TestPackedTypes message = builder.build();
+
+ ByteString rawBytes = message.toByteString();
+
+ Message message2 =
+ DynamicMessage.parseFrom(TestPackedTypes.getDescriptor(), rawBytes);
+ packedReflectionTester.assertPackedFieldsSetViaReflection(message2);
+
+ // Test Parser interface.
+ Message message3 = message2.getParserForType().parseFrom(rawBytes);
+ packedReflectionTester.assertPackedFieldsSetViaReflection(message3);
+ }
+
+ public void testDynamicMessageCopy() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TestUtil.setAllFields(builder);
+ TestAllTypes message = builder.build();
+
+ DynamicMessage copy = DynamicMessage.newBuilder(message).build();
+ reflectionTester.assertAllFieldsSetViaReflection(copy);
+ }
+
+ public void testToBuilder() throws Exception {
+ DynamicMessage.Builder builder =
+ DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
+ reflectionTester.setAllFieldsViaReflection(builder);
+ int unknownFieldNum = 9;
+ long unknownFieldVal = 90;
+ builder.setUnknownFields(UnknownFieldSet.newBuilder()
+ .addField(unknownFieldNum,
+ UnknownFieldSet.Field.newBuilder()
+ .addVarint(unknownFieldVal).build())
+ .build());
+ DynamicMessage message = builder.build();
+
+ DynamicMessage derived = message.toBuilder().build();
+ reflectionTester.assertAllFieldsSetViaReflection(derived);
+ assertEquals(Arrays.asList(unknownFieldVal),
+ derived.getUnknownFields().getField(unknownFieldNum).getVarintList());
+ }
+}
diff --git a/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/ForceFieldBuildersPreRun.java b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/ForceFieldBuildersPreRun.java
new file mode 100644
index 00000000..6a39500e
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/ForceFieldBuildersPreRun.java
@@ -0,0 +1,49 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf.test;
+import com.google.protobuf.*;
+
+/**
+ * A prerun for a test suite that allows running the full protocol buffer
+ * tests in a mode that disables the optimization for not using
+ * {@link RepeatedFieldBuilder} and {@link SingleFieldBuilder} until they are
+ * requested. This allows us to run all the tests through both code paths
+ * and ensures that both code paths produce identical results.
+ *
+ * @author jonp@google.com (Jon Perlow)
+ */
+public class ForceFieldBuildersPreRun implements Runnable {
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public void run() {
+ // GeneratedMessage.enableAlwaysUseFieldBuildersForTesting();
+ }
+}
diff --git a/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/GeneratedMessageTest.java b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/GeneratedMessageTest.java
new file mode 100644
index 00000000..49f11464
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/GeneratedMessageTest.java
@@ -0,0 +1,961 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf.test;
+import com.google.protobuf.*;
+
+import com.google.protobuf.Descriptors.Descriptor;
+import com.google.protobuf.Descriptors.FieldDescriptor;
+import com.google.protobuf.test.UnittestImport;
+import protobuf_unittest.EnumWithNoOuter;
+import protobuf_unittest.MessageWithNoOuter;
+import protobuf_unittest.MultipleFilesTestProto;
+import protobuf_unittest.NestedExtension.MyNestedExtension;
+import protobuf_unittest.NonNestedExtension;
+import protobuf_unittest.NonNestedExtension.MessageToBeExtended;
+import protobuf_unittest.NonNestedExtension.MyNonNestedExtension;
+import protobuf_unittest.ServiceWithNoOuter;
+import protobuf_unittest.UnittestOptimizeFor.TestOptimizedForSize;
+import protobuf_unittest.UnittestOptimizeFor.TestOptionalOptimizedForSize;
+import protobuf_unittest.UnittestOptimizeFor.TestRequiredOptimizedForSize;
+import protobuf_unittest.UnittestProto;
+import protobuf_unittest.UnittestProto.ForeignEnum;
+import protobuf_unittest.UnittestProto.ForeignMessage;
+import protobuf_unittest.UnittestProto.ForeignMessageOrBuilder;
+import protobuf_unittest.UnittestProto.TestAllExtensions;
+import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage;
+import protobuf_unittest.UnittestProto.TestAllTypesOrBuilder;
+import protobuf_unittest.UnittestProto.TestExtremeDefaultValues;
+import protobuf_unittest.UnittestProto.TestPackedTypes;
+import protobuf_unittest.UnittestProto.TestUnpackedTypes;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Unit test for generated messages and generated code. See also
+ * {@link MessageTest}, which tests some generated message functionality.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public class GeneratedMessageTest extends TestCase {
+ TestUtil.ReflectionTester reflectionTester =
+ new TestUtil.ReflectionTester(TestAllTypes.getDescriptor(), null);
+
+ public void testDefaultInstance() throws Exception {
+ assertSame(TestAllTypes.getDefaultInstance(),
+ TestAllTypes.getDefaultInstance().getDefaultInstanceForType());
+ assertSame(TestAllTypes.getDefaultInstance(),
+ TestAllTypes.newBuilder().getDefaultInstanceForType());
+ }
+
+ public void testMessageOrBuilder() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TestUtil.setAllFields(builder);
+ TestAllTypes message = builder.build();
+ TestUtil.assertAllFieldsSet(message);
+ }
+
+ public void testUsingBuilderMultipleTimes() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ // primitive field scalar and repeated
+ builder.setOptionalSfixed64(100);
+ builder.addRepeatedInt32(100);
+ // enum field scalar and repeated
+ builder.setOptionalImportEnum(UnittestImport.ImportEnum.IMPORT_BAR);
+ builder.addRepeatedImportEnum(UnittestImport.ImportEnum.IMPORT_BAR);
+ // proto field scalar and repeated
+ builder.setOptionalForeignMessage(ForeignMessage.newBuilder().setC(1));
+ builder.addRepeatedForeignMessage(ForeignMessage.newBuilder().setC(1));
+
+ TestAllTypes value1 = builder.build();
+
+ assertEquals(100, value1.getOptionalSfixed64());
+ assertEquals(100, value1.getRepeatedInt32(0));
+ assertEquals(UnittestImport.ImportEnum.IMPORT_BAR,
+ value1.getOptionalImportEnum());
+ assertEquals(UnittestImport.ImportEnum.IMPORT_BAR,
+ value1.getRepeatedImportEnum(0));
+ assertEquals(1, value1.getOptionalForeignMessage().getC());
+ assertEquals(1, value1.getRepeatedForeignMessage(0).getC());
+
+ // Make sure that builder didn't update previously created values
+ builder.setOptionalSfixed64(200);
+ builder.setRepeatedInt32(0, 200);
+ builder.setOptionalImportEnum(UnittestImport.ImportEnum.IMPORT_FOO);
+ builder.setRepeatedImportEnum(0, UnittestImport.ImportEnum.IMPORT_FOO);
+ builder.setOptionalForeignMessage(ForeignMessage.newBuilder().setC(2));
+ builder.setRepeatedForeignMessage(0, ForeignMessage.newBuilder().setC(2));
+
+ TestAllTypes value2 = builder.build();
+
+ // Make sure value1 didn't change.
+ assertEquals(100, value1.getOptionalSfixed64());
+ assertEquals(100, value1.getRepeatedInt32(0));
+ assertEquals(UnittestImport.ImportEnum.IMPORT_BAR,
+ value1.getOptionalImportEnum());
+ assertEquals(UnittestImport.ImportEnum.IMPORT_BAR,
+ value1.getRepeatedImportEnum(0));
+ assertEquals(1, value1.getOptionalForeignMessage().getC());
+ assertEquals(1, value1.getRepeatedForeignMessage(0).getC());
+
+ // Make sure value2 is correct
+ assertEquals(200, value2.getOptionalSfixed64());
+ assertEquals(200, value2.getRepeatedInt32(0));
+ assertEquals(UnittestImport.ImportEnum.IMPORT_FOO,
+ value2.getOptionalImportEnum());
+ assertEquals(UnittestImport.ImportEnum.IMPORT_FOO,
+ value2.getRepeatedImportEnum(0));
+ assertEquals(2, value2.getOptionalForeignMessage().getC());
+ assertEquals(2, value2.getRepeatedForeignMessage(0).getC());
+ }
+
+ public void testRepeatedArraysAreImmutable() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ builder.addRepeatedInt32(100);
+ builder.addRepeatedImportEnum(UnittestImport.ImportEnum.IMPORT_BAR);
+ builder.addRepeatedForeignMessage(ForeignMessage.getDefaultInstance());
+ assertIsUnmodifiable(builder.getRepeatedInt32List());
+ assertIsUnmodifiable(builder.getRepeatedImportEnumList());
+ assertIsUnmodifiable(builder.getRepeatedForeignMessageList());
+ assertIsUnmodifiable(builder.getRepeatedFloatList());
+
+
+ TestAllTypes value = builder.build();
+ assertIsUnmodifiable(value.getRepeatedInt32List());
+ assertIsUnmodifiable(value.getRepeatedImportEnumList());
+ assertIsUnmodifiable(value.getRepeatedForeignMessageList());
+ assertIsUnmodifiable(value.getRepeatedFloatList());
+ }
+
+ public void testParsedMessagesAreImmutable() throws Exception {
+ TestAllTypes value = TestAllTypes.PARSER.parseFrom(
+ TestUtil.getAllSet().toByteString());
+ assertIsUnmodifiable(value.getRepeatedInt32List());
+ assertIsUnmodifiable(value.getRepeatedInt64List());
+ assertIsUnmodifiable(value.getRepeatedUint32List());
+ assertIsUnmodifiable(value.getRepeatedUint64List());
+ assertIsUnmodifiable(value.getRepeatedSint32List());
+ assertIsUnmodifiable(value.getRepeatedSint64List());
+ assertIsUnmodifiable(value.getRepeatedFixed32List());
+ assertIsUnmodifiable(value.getRepeatedFixed64List());
+ assertIsUnmodifiable(value.getRepeatedSfixed32List());
+ assertIsUnmodifiable(value.getRepeatedSfixed64List());
+ assertIsUnmodifiable(value.getRepeatedFloatList());
+ assertIsUnmodifiable(value.getRepeatedDoubleList());
+ assertIsUnmodifiable(value.getRepeatedBoolList());
+ assertIsUnmodifiable(value.getRepeatedStringList());
+ assertIsUnmodifiable(value.getRepeatedBytesList());
+ assertIsUnmodifiable(value.getRepeatedGroupList());
+ assertIsUnmodifiable(value.getRepeatedNestedMessageList());
+ assertIsUnmodifiable(value.getRepeatedForeignMessageList());
+ assertIsUnmodifiable(value.getRepeatedImportMessageList());
+ assertIsUnmodifiable(value.getRepeatedNestedEnumList());
+ assertIsUnmodifiable(value.getRepeatedForeignEnumList());
+ assertIsUnmodifiable(value.getRepeatedImportEnumList());
+ }
+
+ private void assertIsUnmodifiable(List<?> list) {
+ if (list == Collections.emptyList()) {
+ // OKAY -- Need to check this b/c EmptyList allows you to call clear.
+ } else {
+ try {
+ list.clear();
+ fail("List wasn't immutable");
+ } catch (UnsupportedOperationException e) {
+ // good
+ }
+ }
+ }
+
+ public void testSettersRejectNull() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ try {
+ builder.setOptionalString(null);
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.setOptionalBytes(null);
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.setOptionalNestedMessage((TestAllTypes.NestedMessage) null);
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.setOptionalNestedMessage(
+ (TestAllTypes.NestedMessage.Builder) null);
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.setOptionalNestedEnum(null);
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.addRepeatedString(null);
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.addRepeatedBytes(null);
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.addRepeatedNestedMessage((TestAllTypes.NestedMessage) null);
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.addRepeatedNestedMessage(
+ (TestAllTypes.NestedMessage.Builder) null);
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.addRepeatedNestedEnum(null);
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ }
+
+ public void testRepeatedSetters() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TestUtil.setAllFields(builder);
+ TestUtil.modifyRepeatedFields(builder);
+ TestAllTypes message = builder.build();
+ TestUtil.assertRepeatedFieldsModified(message);
+ }
+
+ public void testRepeatedSettersRejectNull() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+
+ builder.addRepeatedString("one");
+ builder.addRepeatedString("two");
+ try {
+ builder.setRepeatedString(1, null);
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+
+ builder.addRepeatedBytes(TestUtil.toBytes("one"));
+ builder.addRepeatedBytes(TestUtil.toBytes("two"));
+ try {
+ builder.setRepeatedBytes(1, null);
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+
+ builder.addRepeatedNestedMessage(
+ TestAllTypes.NestedMessage.newBuilder().setBb(218).build());
+ builder.addRepeatedNestedMessage(
+ TestAllTypes.NestedMessage.newBuilder().setBb(456).build());
+ try {
+ builder.setRepeatedNestedMessage(1, (TestAllTypes.NestedMessage) null);
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.setRepeatedNestedMessage(
+ 1, (TestAllTypes.NestedMessage.Builder) null);
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+
+ builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.FOO);
+ builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.BAR);
+ try {
+ builder.setRepeatedNestedEnum(1, null);
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ }
+
+ public void testRepeatedAppend() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+
+ builder.addAllRepeatedInt32(Arrays.asList(1, 2, 3, 4));
+ builder.addAllRepeatedForeignEnum(Arrays.asList(ForeignEnum.FOREIGN_BAZ));
+
+ ForeignMessage foreignMessage =
+ ForeignMessage.newBuilder().setC(12).build();
+ builder.addAllRepeatedForeignMessage(Arrays.asList(foreignMessage));
+
+ TestAllTypes message = builder.build();
+ assertEquals(message.getRepeatedInt32List(), Arrays.asList(1, 2, 3, 4));
+ assertEquals(message.getRepeatedForeignEnumList(),
+ Arrays.asList(ForeignEnum.FOREIGN_BAZ));
+ assertEquals(1, message.getRepeatedForeignMessageCount());
+ assertEquals(12, message.getRepeatedForeignMessage(0).getC());
+ }
+
+ public void testRepeatedAppendRejectsNull() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+
+ ForeignMessage foreignMessage =
+ ForeignMessage.newBuilder().setC(12).build();
+ try {
+ builder.addAllRepeatedForeignMessage(
+ Arrays.asList(foreignMessage, (ForeignMessage) null));
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+
+ try {
+ builder.addAllRepeatedForeignEnum(
+ Arrays.asList(ForeignEnum.FOREIGN_BAZ, null));
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+
+ try {
+ builder.addAllRepeatedString(Arrays.asList("one", null));
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+
+ try {
+ builder.addAllRepeatedBytes(Arrays.asList(TestUtil.toBytes("one"), null));
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ }
+
+ public void testSettingForeignMessageUsingBuilder() throws Exception {
+ TestAllTypes message = TestAllTypes.newBuilder()
+ // Pass builder for foreign message instance.
+ .setOptionalForeignMessage(ForeignMessage.newBuilder().setC(123))
+ .build();
+ TestAllTypes expectedMessage = TestAllTypes.newBuilder()
+ // Create expected version passing foreign message instance explicitly.
+ .setOptionalForeignMessage(
+ ForeignMessage.newBuilder().setC(123).build())
+ .build();
+ // TODO(ngd): Upgrade to using real #equals method once implemented
+ assertEquals(expectedMessage.toString(), message.toString());
+ }
+
+ public void testSettingRepeatedForeignMessageUsingBuilder() throws Exception {
+ TestAllTypes message = TestAllTypes.newBuilder()
+ // Pass builder for foreign message instance.
+ .addRepeatedForeignMessage(ForeignMessage.newBuilder().setC(456))
+ .build();
+ TestAllTypes expectedMessage = TestAllTypes.newBuilder()
+ // Create expected version passing foreign message instance explicitly.
+ .addRepeatedForeignMessage(
+ ForeignMessage.newBuilder().setC(456).build())
+ .build();
+ assertEquals(expectedMessage.toString(), message.toString());
+ }
+
+ public void testDefaults() throws Exception {
+ TestUtil.assertClear(TestAllTypes.getDefaultInstance());
+ TestUtil.assertClear(TestAllTypes.newBuilder().build());
+
+ TestExtremeDefaultValues message =
+ TestExtremeDefaultValues.getDefaultInstance();
+ assertEquals("\u1234", message.getUtf8String());
+ assertEquals(Double.POSITIVE_INFINITY, message.getInfDouble());
+ assertEquals(Double.NEGATIVE_INFINITY, message.getNegInfDouble());
+ assertTrue(Double.isNaN(message.getNanDouble()));
+ assertEquals(Float.POSITIVE_INFINITY, message.getInfFloat());
+ assertEquals(Float.NEGATIVE_INFINITY, message.getNegInfFloat());
+ assertTrue(Float.isNaN(message.getNanFloat()));
+ assertEquals("? ? ?? ?? ??? ??/ ??-", message.getCppTrigraph());
+ }
+
+ public void testClear() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TestUtil.assertClear(builder);
+ TestUtil.setAllFields(builder);
+ builder.clear();
+ TestUtil.assertClear(builder);
+ }
+
+ public void testReflectionGetters() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TestUtil.setAllFields(builder);
+ reflectionTester.assertAllFieldsSetViaReflection(builder);
+
+ TestAllTypes message = builder.build();
+ reflectionTester.assertAllFieldsSetViaReflection(message);
+ }
+
+ public void testReflectionSetters() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ reflectionTester.setAllFieldsViaReflection(builder);
+ TestUtil.assertAllFieldsSet(builder);
+
+ TestAllTypes message = builder.build();
+ TestUtil.assertAllFieldsSet(message);
+ }
+
+ public void testReflectionSettersRejectNull() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ reflectionTester.assertReflectionSettersRejectNull(builder);
+ }
+
+ public void testReflectionRepeatedSetters() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ reflectionTester.setAllFieldsViaReflection(builder);
+ reflectionTester.modifyRepeatedFieldsViaReflection(builder);
+ TestUtil.assertRepeatedFieldsModified(builder);
+
+ TestAllTypes message = builder.build();
+ TestUtil.assertRepeatedFieldsModified(message);
+ }
+
+ public void testReflectionRepeatedSettersRejectNull() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ reflectionTester.assertReflectionRepeatedSettersRejectNull(builder);
+ }
+
+ public void testReflectionDefaults() throws Exception {
+ reflectionTester.assertClearViaReflection(
+ TestAllTypes.getDefaultInstance());
+ reflectionTester.assertClearViaReflection(
+ TestAllTypes.newBuilder().build());
+ }
+
+ public void testEnumInterface() throws Exception {
+ assertTrue(TestAllTypes.getDefaultInstance().getDefaultNestedEnum()
+ instanceof ProtocolMessageEnum);
+ }
+
+ public void testEnumMap() throws Exception {
+ Internal.EnumLiteMap<ForeignEnum> map = ForeignEnum.internalGetValueMap();
+
+ for (ForeignEnum value : ForeignEnum.values()) {
+ assertEquals(value, map.findValueByNumber(value.getNumber()));
+ }
+
+ assertTrue(map.findValueByNumber(12345) == null);
+ }
+
+ public void testParsePackedToUnpacked() throws Exception {
+ TestUnpackedTypes.Builder builder = TestUnpackedTypes.newBuilder();
+ TestUnpackedTypes message =
+ builder.mergeFrom(TestUtil.getPackedSet().toByteString()).build();
+ TestUtil.assertUnpackedFieldsSet(message);
+ }
+
+ public void testParseUnpackedToPacked() throws Exception {
+ TestPackedTypes.Builder builder = TestPackedTypes.newBuilder();
+ TestPackedTypes message =
+ builder.mergeFrom(TestUtil.getUnpackedSet().toByteString()).build();
+ TestUtil.assertPackedFieldsSet(message);
+ }
+
+ // =================================================================
+ // Extensions.
+
+ TestUtil.ReflectionTester extensionsReflectionTester =
+ new TestUtil.ReflectionTester(TestAllExtensions.getDescriptor(),
+ TestUtil.getExtensionRegistry());
+
+ public void testExtensionMessageOrBuilder() throws Exception {
+ TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
+ TestUtil.setAllExtensions(builder);
+ TestAllExtensions message = builder.build();
+ TestUtil.assertAllExtensionsSet(message);
+ }
+
+ public void testExtensionRepeatedSetters() throws Exception {
+ TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
+ TestUtil.setAllExtensions(builder);
+ TestUtil.modifyRepeatedExtensions(builder);
+ TestAllExtensions message = builder.build();
+ TestUtil.assertRepeatedExtensionsModified(message);
+ }
+
+ public void testExtensionDefaults() throws Exception {
+ TestUtil.assertExtensionsClear(TestAllExtensions.getDefaultInstance());
+ TestUtil.assertExtensionsClear(TestAllExtensions.newBuilder().build());
+ }
+
+ public void testExtensionReflectionGetters() throws Exception {
+ TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
+ TestUtil.setAllExtensions(builder);
+ extensionsReflectionTester.assertAllFieldsSetViaReflection(builder);
+
+ TestAllExtensions message = builder.build();
+ extensionsReflectionTester.assertAllFieldsSetViaReflection(message);
+ }
+
+ public void testExtensionReflectionSetters() throws Exception {
+ TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
+ extensionsReflectionTester.setAllFieldsViaReflection(builder);
+ TestUtil.assertAllExtensionsSet(builder);
+
+ TestAllExtensions message = builder.build();
+ TestUtil.assertAllExtensionsSet(message);
+ }
+
+ public void testExtensionReflectionSettersRejectNull() throws Exception {
+ TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
+ extensionsReflectionTester.assertReflectionSettersRejectNull(builder);
+ }
+
+ public void testExtensionReflectionRepeatedSetters() throws Exception {
+ TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
+ extensionsReflectionTester.setAllFieldsViaReflection(builder);
+ extensionsReflectionTester.modifyRepeatedFieldsViaReflection(builder);
+ TestUtil.assertRepeatedExtensionsModified(builder);
+
+ TestAllExtensions message = builder.build();
+ TestUtil.assertRepeatedExtensionsModified(message);
+ }
+
+ public void testExtensionReflectionRepeatedSettersRejectNull()
+ throws Exception {
+ TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
+ extensionsReflectionTester.assertReflectionRepeatedSettersRejectNull(
+ builder);
+ }
+
+ public void testExtensionReflectionDefaults() throws Exception {
+ extensionsReflectionTester.assertClearViaReflection(
+ TestAllExtensions.getDefaultInstance());
+ extensionsReflectionTester.assertClearViaReflection(
+ TestAllExtensions.newBuilder().build());
+ }
+
+ public void testClearExtension() throws Exception {
+ // clearExtension() is not actually used in TestUtil, so try it manually.
+ assertFalse(
+ TestAllExtensions.newBuilder()
+ .setExtension(UnittestProto.optionalInt32Extension, 1)
+ .clearExtension(UnittestProto.optionalInt32Extension)
+ .hasExtension(UnittestProto.optionalInt32Extension));
+ assertEquals(0,
+ TestAllExtensions.newBuilder()
+ .addExtension(UnittestProto.repeatedInt32Extension, 1)
+ .clearExtension(UnittestProto.repeatedInt32Extension)
+ .getExtensionCount(UnittestProto.repeatedInt32Extension));
+ }
+
+ public void testExtensionCopy() throws Exception {
+ TestAllExtensions original = TestUtil.getAllExtensionsSet();
+ TestAllExtensions copy = TestAllExtensions.newBuilder(original).build();
+ TestUtil.assertAllExtensionsSet(copy);
+ }
+
+ public void testExtensionMergeFrom() throws Exception {
+ TestAllExtensions original =
+ TestAllExtensions.newBuilder()
+ .setExtension(UnittestProto.optionalInt32Extension, 1).build();
+ TestAllExtensions merged =
+ TestAllExtensions.newBuilder().mergeFrom(original).build();
+ assertTrue(merged.hasExtension(UnittestProto.optionalInt32Extension));
+ assertEquals(
+ 1, (int) merged.getExtension(UnittestProto.optionalInt32Extension));
+ }
+
+ // =================================================================
+ // multiple_files_test
+
+ public void testMultipleFilesOption() throws Exception {
+ // We mostly just want to check that things compile.
+ MessageWithNoOuter message =
+ MessageWithNoOuter.newBuilder()
+ .setNested(MessageWithNoOuter.NestedMessage.newBuilder().setI(1))
+ .addForeign(TestAllTypes.newBuilder().setOptionalInt32(1))
+ .setNestedEnum(MessageWithNoOuter.NestedEnum.BAZ)
+ .setForeignEnum(EnumWithNoOuter.BAR)
+ .build();
+ assertEquals(message, MessageWithNoOuter.parseFrom(message.toByteString()));
+
+ assertEquals(MultipleFilesTestProto.getDescriptor(),
+ MessageWithNoOuter.getDescriptor().getFile());
+
+ Descriptors.FieldDescriptor field =
+ MessageWithNoOuter.getDescriptor().findFieldByName("foreign_enum");
+ assertEquals(EnumWithNoOuter.BAR.getValueDescriptor(),
+ message.getField(field));
+
+ assertEquals(MultipleFilesTestProto.getDescriptor(),
+ ServiceWithNoOuter.getDescriptor().getFile());
+
+ assertFalse(
+ TestAllExtensions.getDefaultInstance().hasExtension(
+ MultipleFilesTestProto.extensionWithOuter));
+ }
+
+ public void testOptionalFieldWithRequiredSubfieldsOptimizedForSize()
+ throws Exception {
+ TestOptionalOptimizedForSize message =
+ TestOptionalOptimizedForSize.getDefaultInstance();
+ assertTrue(message.isInitialized());
+
+ message = TestOptionalOptimizedForSize.newBuilder().setO(
+ TestRequiredOptimizedForSize.newBuilder().buildPartial()
+ ).buildPartial();
+ assertFalse(message.isInitialized());
+
+ message = TestOptionalOptimizedForSize.newBuilder().setO(
+ TestRequiredOptimizedForSize.newBuilder().setX(5).buildPartial()
+ ).buildPartial();
+ assertTrue(message.isInitialized());
+ }
+
+ public void testUninitializedExtensionInOptimizedForSize()
+ throws Exception {
+ TestOptimizedForSize.Builder builder = TestOptimizedForSize.newBuilder();
+ builder.setExtension(TestOptimizedForSize.testExtension2,
+ TestRequiredOptimizedForSize.newBuilder().buildPartial());
+ assertFalse(builder.isInitialized());
+ assertFalse(builder.buildPartial().isInitialized());
+
+ builder = TestOptimizedForSize.newBuilder();
+ builder.setExtension(TestOptimizedForSize.testExtension2,
+ TestRequiredOptimizedForSize.newBuilder().setX(10).buildPartial());
+ assertTrue(builder.isInitialized());
+ assertTrue(builder.buildPartial().isInitialized());
+ }
+
+ public void testToBuilder() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TestUtil.setAllFields(builder);
+ TestAllTypes message = builder.build();
+ TestUtil.assertAllFieldsSet(message);
+ TestUtil.assertAllFieldsSet(message.toBuilder().build());
+ }
+
+ public void testFieldConstantValues() throws Exception {
+ assertEquals(TestAllTypes.NestedMessage.BB_FIELD_NUMBER, 1);
+ assertEquals(TestAllTypes.OPTIONAL_INT32_FIELD_NUMBER, 1);
+ assertEquals(TestAllTypes.OPTIONALGROUP_FIELD_NUMBER, 16);
+ assertEquals(TestAllTypes.OPTIONAL_NESTED_MESSAGE_FIELD_NUMBER, 18);
+ assertEquals(TestAllTypes.OPTIONAL_NESTED_ENUM_FIELD_NUMBER, 21);
+ assertEquals(TestAllTypes.REPEATED_INT32_FIELD_NUMBER, 31);
+ assertEquals(TestAllTypes.REPEATEDGROUP_FIELD_NUMBER, 46);
+ assertEquals(TestAllTypes.REPEATED_NESTED_MESSAGE_FIELD_NUMBER, 48);
+ assertEquals(TestAllTypes.REPEATED_NESTED_ENUM_FIELD_NUMBER, 51);
+ }
+
+ public void testExtensionConstantValues() throws Exception {
+ assertEquals(UnittestProto.TestRequired.SINGLE_FIELD_NUMBER, 1000);
+ assertEquals(UnittestProto.TestRequired.MULTI_FIELD_NUMBER, 1001);
+ assertEquals(UnittestProto.OPTIONAL_INT32_EXTENSION_FIELD_NUMBER, 1);
+ assertEquals(UnittestProto.OPTIONALGROUP_EXTENSION_FIELD_NUMBER, 16);
+ assertEquals(
+ UnittestProto.OPTIONAL_NESTED_MESSAGE_EXTENSION_FIELD_NUMBER, 18);
+ assertEquals(UnittestProto.OPTIONAL_NESTED_ENUM_EXTENSION_FIELD_NUMBER, 21);
+ assertEquals(UnittestProto.REPEATED_INT32_EXTENSION_FIELD_NUMBER, 31);
+ assertEquals(UnittestProto.REPEATEDGROUP_EXTENSION_FIELD_NUMBER, 46);
+ assertEquals(
+ UnittestProto.REPEATED_NESTED_MESSAGE_EXTENSION_FIELD_NUMBER, 48);
+ assertEquals(UnittestProto.REPEATED_NESTED_ENUM_EXTENSION_FIELD_NUMBER, 51);
+ }
+
+ public void testRecursiveMessageDefaultInstance() throws Exception {
+ UnittestProto.TestRecursiveMessage message =
+ UnittestProto.TestRecursiveMessage.getDefaultInstance();
+ assertTrue(message != null);
+ assertTrue(message.getA() != null);
+ assertTrue(message.getA() == message);
+ }
+
+ public void testSerialize() throws Exception {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TestUtil.setAllFields(builder);
+ TestAllTypes expected = builder.build();
+ ObjectOutputStream out = new ObjectOutputStream(baos);
+ try {
+ out.writeObject(expected);
+ } finally {
+ out.close();
+ }
+ ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+ ObjectInputStream in = new ObjectInputStream(bais);
+ TestAllTypes actual = (TestAllTypes) in.readObject();
+ assertEquals(expected, actual);
+ }
+
+ public void testSerializePartial() throws Exception {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TestAllTypes expected = builder.buildPartial();
+ ObjectOutputStream out = new ObjectOutputStream(baos);
+ try {
+ out.writeObject(expected);
+ } finally {
+ out.close();
+ }
+ ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+ ObjectInputStream in = new ObjectInputStream(bais);
+ TestAllTypes actual = (TestAllTypes) in.readObject();
+ assertEquals(expected, actual);
+ }
+
+ public void testEnumValues() {
+ assertEquals(
+ TestAllTypes.NestedEnum.BAR.getNumber(),
+ TestAllTypes.NestedEnum.BAR_VALUE);
+ assertEquals(
+ TestAllTypes.NestedEnum.BAZ.getNumber(),
+ TestAllTypes.NestedEnum.BAZ_VALUE);
+ assertEquals(
+ TestAllTypes.NestedEnum.FOO.getNumber(),
+ TestAllTypes.NestedEnum.FOO_VALUE);
+ }
+
+ public void testNonNestedExtensionInitialization() {
+ assertTrue(NonNestedExtension.nonNestedExtension
+ .getMessageDefaultInstance() instanceof MyNonNestedExtension);
+ assertEquals("nonNestedExtension",
+ NonNestedExtension.nonNestedExtension.getDescriptor().getName());
+ }
+
+ public void testNestedExtensionInitialization() {
+ assertTrue(MyNestedExtension.recursiveExtension.getMessageDefaultInstance()
+ instanceof MessageToBeExtended);
+ assertEquals("recursiveExtension",
+ MyNestedExtension.recursiveExtension.getDescriptor().getName());
+ }
+
+
+ public void testBaseMessageOrBuilder() {
+ // Mostly just makes sure the base interface exists and has some methods.
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TestAllTypes message = builder.buildPartial();
+ TestAllTypesOrBuilder builderAsInterface = (TestAllTypesOrBuilder) builder;
+ TestAllTypesOrBuilder messageAsInterface = (TestAllTypesOrBuilder) message;
+
+ assertEquals(
+ messageAsInterface.getDefaultBool(),
+ messageAsInterface.getDefaultBool());
+ assertEquals(
+ messageAsInterface.getOptionalDouble(),
+ messageAsInterface.getOptionalDouble());
+ }
+
+ public void testMessageOrBuilderGetters() {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+
+ // single fields
+ assertSame(ForeignMessage.getDefaultInstance(),
+ builder.getOptionalForeignMessageOrBuilder());
+ ForeignMessage.Builder subBuilder =
+ builder.getOptionalForeignMessageBuilder();
+ assertSame(subBuilder, builder.getOptionalForeignMessageOrBuilder());
+
+ // repeated fields
+ ForeignMessage m0 = ForeignMessage.newBuilder().buildPartial();
+ ForeignMessage m1 = ForeignMessage.newBuilder().buildPartial();
+ ForeignMessage m2 = ForeignMessage.newBuilder().buildPartial();
+ builder.addRepeatedForeignMessage(m0);
+ builder.addRepeatedForeignMessage(m1);
+ builder.addRepeatedForeignMessage(m2);
+ assertSame(m0, builder.getRepeatedForeignMessageOrBuilder(0));
+ assertSame(m1, builder.getRepeatedForeignMessageOrBuilder(1));
+ assertSame(m2, builder.getRepeatedForeignMessageOrBuilder(2));
+ ForeignMessage.Builder b0 = builder.getRepeatedForeignMessageBuilder(0);
+ ForeignMessage.Builder b1 = builder.getRepeatedForeignMessageBuilder(1);
+ assertSame(b0, builder.getRepeatedForeignMessageOrBuilder(0));
+ assertSame(b1, builder.getRepeatedForeignMessageOrBuilder(1));
+ assertSame(m2, builder.getRepeatedForeignMessageOrBuilder(2));
+
+ List<? extends ForeignMessageOrBuilder> messageOrBuilderList =
+ builder.getRepeatedForeignMessageOrBuilderList();
+ assertSame(b0, messageOrBuilderList.get(0));
+ assertSame(b1, messageOrBuilderList.get(1));
+ assertSame(m2, messageOrBuilderList.get(2));
+ }
+
+ public void testGetFieldBuilder() {
+ Descriptor descriptor = TestAllTypes.getDescriptor();
+
+ FieldDescriptor fieldDescriptor =
+ descriptor.findFieldByName("optional_nested_message");
+ FieldDescriptor foreignFieldDescriptor =
+ descriptor.findFieldByName("optional_foreign_message");
+ FieldDescriptor importFieldDescriptor =
+ descriptor.findFieldByName("optional_import_message");
+
+ // Mutate the message with new field builder
+ // Mutate nested message
+ TestAllTypes.Builder builder1 = TestAllTypes.newBuilder();
+ Message.Builder fieldBuilder1 = builder1.newBuilderForField(fieldDescriptor)
+ .mergeFrom((Message) builder1.getField(fieldDescriptor));
+ FieldDescriptor subFieldDescriptor1 =
+ fieldBuilder1.getDescriptorForType().findFieldByName("bb");
+ fieldBuilder1.setField(subFieldDescriptor1, 1);
+ builder1.setField(fieldDescriptor, fieldBuilder1.build());
+
+ // Mutate foreign message
+ Message.Builder foreignFieldBuilder1 = builder1.newBuilderForField(
+ foreignFieldDescriptor)
+ .mergeFrom((Message) builder1.getField(foreignFieldDescriptor));
+ FieldDescriptor subForeignFieldDescriptor1 =
+ foreignFieldBuilder1.getDescriptorForType().findFieldByName("c");
+ foreignFieldBuilder1.setField(subForeignFieldDescriptor1, 2);
+ builder1.setField(foreignFieldDescriptor, foreignFieldBuilder1.build());
+
+ // Mutate import message
+ Message.Builder importFieldBuilder1 = builder1.newBuilderForField(
+ importFieldDescriptor)
+ .mergeFrom((Message) builder1.getField(importFieldDescriptor));
+ FieldDescriptor subImportFieldDescriptor1 =
+ importFieldBuilder1.getDescriptorForType().findFieldByName("d");
+ importFieldBuilder1.setField(subImportFieldDescriptor1, 3);
+ builder1.setField(importFieldDescriptor, importFieldBuilder1.build());
+
+ Message newMessage1 = builder1.build();
+
+ // Mutate the message with existing field builder
+ // Mutate nested message
+ TestAllTypes.Builder builder2 = TestAllTypes.newBuilder();
+ Message.Builder fieldBuilder2 = builder2.getFieldBuilder(fieldDescriptor);
+ FieldDescriptor subFieldDescriptor2 =
+ fieldBuilder2.getDescriptorForType().findFieldByName("bb");
+ fieldBuilder2.setField(subFieldDescriptor2, 1);
+ builder2.setField(fieldDescriptor, fieldBuilder2.build());
+
+ // Mutate foreign message
+ Message.Builder foreignFieldBuilder2 = builder2.newBuilderForField(
+ foreignFieldDescriptor)
+ .mergeFrom((Message) builder2.getField(foreignFieldDescriptor));
+ FieldDescriptor subForeignFieldDescriptor2 =
+ foreignFieldBuilder2.getDescriptorForType().findFieldByName("c");
+ foreignFieldBuilder2.setField(subForeignFieldDescriptor2, 2);
+ builder2.setField(foreignFieldDescriptor, foreignFieldBuilder2.build());
+
+ // Mutate import message
+ Message.Builder importFieldBuilder2 = builder2.newBuilderForField(
+ importFieldDescriptor)
+ .mergeFrom((Message) builder2.getField(importFieldDescriptor));
+ FieldDescriptor subImportFieldDescriptor2 =
+ importFieldBuilder2.getDescriptorForType().findFieldByName("d");
+ importFieldBuilder2.setField(subImportFieldDescriptor2, 3);
+ builder2.setField(importFieldDescriptor, importFieldBuilder2.build());
+
+ Message newMessage2 = builder2.build();
+
+ // These two messages should be equal.
+ assertEquals(newMessage1, newMessage2);
+ }
+
+ public void testGetFieldBuilderWithInitializedValue() {
+ Descriptor descriptor = TestAllTypes.getDescriptor();
+ FieldDescriptor fieldDescriptor =
+ descriptor.findFieldByName("optional_nested_message");
+
+ // Before setting field, builder is initialized by default value.
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ NestedMessage.Builder fieldBuilder =
+ (NestedMessage.Builder) builder.getFieldBuilder(fieldDescriptor);
+ assertEquals(0, fieldBuilder.getBb());
+
+ // Setting field value with new field builder instance.
+ builder = TestAllTypes.newBuilder();
+ NestedMessage.Builder newFieldBuilder =
+ builder.getOptionalNestedMessageBuilder();
+ newFieldBuilder.setBb(2);
+ // Then get the field builder instance by getFieldBuilder().
+ fieldBuilder =
+ (NestedMessage.Builder) builder.getFieldBuilder(fieldDescriptor);
+ // It should contain new value.
+ assertEquals(2, fieldBuilder.getBb());
+ // These two builder should be equal.
+ assertSame(fieldBuilder, newFieldBuilder);
+ }
+
+ public void testGetFieldBuilderNotSupportedException() {
+ Descriptor descriptor = TestAllTypes.getDescriptor();
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ try {
+ builder.getFieldBuilder(descriptor.findFieldByName("optional_int32"));
+ fail("Exception was not thrown");
+ } catch (UnsupportedOperationException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.getFieldBuilder(
+ descriptor.findFieldByName("optional_nested_enum"));
+ fail("Exception was not thrown");
+ } catch (UnsupportedOperationException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.getFieldBuilder(descriptor.findFieldByName("repeated_int32"));
+ fail("Exception was not thrown");
+ } catch (UnsupportedOperationException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.getFieldBuilder(
+ descriptor.findFieldByName("repeated_nested_enum"));
+ fail("Exception was not thrown");
+ } catch (UnsupportedOperationException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.getFieldBuilder(
+ descriptor.findFieldByName("repeated_nested_message"));
+ fail("Exception was not thrown");
+ } catch (UnsupportedOperationException e) {
+ // We expect this exception.
+ }
+ }
+}
diff --git a/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/LazyStringArrayListTest.java b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/LazyStringArrayListTest.java
new file mode 100644
index 00000000..9bc94eef
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/LazyStringArrayListTest.java
@@ -0,0 +1,163 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf.test;
+import com.google.protobuf.*;
+
+import junit.framework.TestCase;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tests for {@link LazyStringArrayList}.
+ *
+ * @author jonp@google.com (Jon Perlow)
+ */
+public class LazyStringArrayListTest extends TestCase {
+
+ private static String STRING_A = "A";
+ private static String STRING_B = "B";
+ private static String STRING_C = "C";
+
+ private static ByteString BYTE_STRING_A = ByteString.copyFromUtf8("A");
+ private static ByteString BYTE_STRING_B = ByteString.copyFromUtf8("B");
+ private static ByteString BYTE_STRING_C = ByteString.copyFromUtf8("C");
+
+ public void testJustStrings() {
+ LazyStringArrayList list = new LazyStringArrayList();
+ list.add(STRING_A);
+ list.add(STRING_B);
+ list.add(STRING_C);
+
+ assertEquals(3, list.size());
+ assertSame(STRING_A, list.get(0));
+ assertSame(STRING_B, list.get(1));
+ assertSame(STRING_C, list.get(2));
+
+ list.set(1, STRING_C);
+ assertSame(STRING_C, list.get(1));
+
+ list.remove(1);
+ assertSame(STRING_A, list.get(0));
+ assertSame(STRING_C, list.get(1));
+ }
+
+ public void testJustByteString() {
+ LazyStringArrayList list = new LazyStringArrayList();
+ list.add(BYTE_STRING_A);
+ list.add(BYTE_STRING_B);
+ list.add(BYTE_STRING_C);
+
+ assertEquals(3, list.size());
+ assertSame(BYTE_STRING_A, list.getByteString(0));
+ assertSame(BYTE_STRING_B, list.getByteString(1));
+ assertSame(BYTE_STRING_C, list.getByteString(2));
+
+ list.remove(1);
+ assertSame(BYTE_STRING_A, list.getByteString(0));
+ assertSame(BYTE_STRING_C, list.getByteString(1));
+ }
+
+ public void testConversionBackAndForth() {
+ LazyStringArrayList list = new LazyStringArrayList();
+ list.add(STRING_A);
+ list.add(BYTE_STRING_B);
+ list.add(BYTE_STRING_C);
+
+ // String a should be the same because it was originally a string
+ assertSame(STRING_A, list.get(0));
+
+ // String b and c should be different because the string has to be computed
+ // from the ByteString
+ String bPrime = list.get(1);
+ assertNotSame(STRING_B, bPrime);
+ assertEquals(STRING_B, bPrime);
+ String cPrime = list.get(2);
+ assertNotSame(STRING_C, cPrime);
+ assertEquals(STRING_C, cPrime);
+
+ // String c and c should stay the same once cached.
+ assertSame(bPrime, list.get(1));
+ assertSame(cPrime, list.get(2));
+
+ // ByteString needs to be computed from string for both a and b
+ ByteString aPrimeByteString = list.getByteString(0);
+ assertEquals(BYTE_STRING_A, aPrimeByteString);
+ ByteString bPrimeByteString = list.getByteString(1);
+ assertNotSame(BYTE_STRING_B, bPrimeByteString);
+ assertEquals(BYTE_STRING_B, list.getByteString(1));
+
+ // Once cached, ByteString should stay cached.
+ assertSame(aPrimeByteString, list.getByteString(0));
+ assertSame(bPrimeByteString, list.getByteString(1));
+ }
+
+ public void testCopyConstructorCopiesByReference() {
+ LazyStringArrayList list1 = new LazyStringArrayList();
+ list1.add(STRING_A);
+ list1.add(BYTE_STRING_B);
+ list1.add(BYTE_STRING_C);
+
+ LazyStringArrayList list2 = new LazyStringArrayList(list1);
+ assertEquals(3, list2.size());
+ assertSame(STRING_A, list2.get(0));
+ assertSame(BYTE_STRING_B, list2.getByteString(1));
+ assertSame(BYTE_STRING_C, list2.getByteString(2));
+ }
+
+ public void testListCopyConstructor() {
+ List<String> list1 = new ArrayList<String>();
+ list1.add(STRING_A);
+ list1.add(STRING_B);
+ list1.add(STRING_C);
+
+ LazyStringArrayList list2 = new LazyStringArrayList(list1);
+ assertEquals(3, list2.size());
+ assertSame(STRING_A, list2.get(0));
+ assertSame(STRING_B, list2.get(1));
+ assertSame(STRING_C, list2.get(2));
+ }
+
+ public void testAddAllCopiesByReferenceIfPossible() {
+ LazyStringArrayList list1 = new LazyStringArrayList();
+ list1.add(STRING_A);
+ list1.add(BYTE_STRING_B);
+ list1.add(BYTE_STRING_C);
+
+ LazyStringArrayList list2 = new LazyStringArrayList();
+ list2.addAll(list1);
+
+ assertEquals(3, list2.size());
+ assertSame(STRING_A, list2.get(0));
+ assertSame(BYTE_STRING_B, list2.getByteString(1));
+ assertSame(BYTE_STRING_C, list2.getByteString(2));
+ }
+}
diff --git a/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/LazyStringEndToEndTest.java b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/LazyStringEndToEndTest.java
new file mode 100644
index 00000000..e21e0389
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/LazyStringEndToEndTest.java
@@ -0,0 +1,108 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf.test;
+import com.google.protobuf.*;
+
+
+import protobuf_unittest.UnittestProto;
+
+import junit.framework.TestCase;
+
+import java.io.IOException;
+
+/**
+ * Tests to make sure the lazy conversion of UTF8-encoded byte arrays to
+ * strings works correctly.
+ *
+ * @author jonp@google.com (Jon Perlow)
+ */
+public class LazyStringEndToEndTest extends TestCase {
+
+ private static ByteString TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8 =
+ ByteString.copyFrom(new byte[] {
+ 114, 4, -1, 0, -1, 0, -30, 2, 4, -1,
+ 0, -1, 0, -30, 2, 4, -1, 0, -1, 0, });
+
+ private ByteString encodedTestAllTypes;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ this.encodedTestAllTypes = UnittestProto.TestAllTypes.newBuilder()
+ .setOptionalString("foo")
+ .addRepeatedString("bar")
+ .addRepeatedString("baz")
+ .build()
+ .toByteString();
+ }
+
+ /**
+ * Tests that an invalid UTF8 string will roundtrip through a parse
+ * and serialization.
+ */
+ public void testParseAndSerialize() throws InvalidProtocolBufferException {
+ UnittestProto.TestAllTypes tV2 = UnittestProto.TestAllTypes.parseFrom(
+ TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8);
+ ByteString bytes = tV2.toByteString();
+ assertEquals(TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8, bytes);
+
+ tV2.getOptionalString();
+ bytes = tV2.toByteString();
+ assertEquals(TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8, bytes);
+ }
+
+ public void testParseAndWrite() throws IOException {
+ UnittestProto.TestAllTypes tV2 = UnittestProto.TestAllTypes.parseFrom(
+ TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8);
+ byte[] sink = new byte[TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8.size()];
+ CodedOutputStream outputStream = CodedOutputStream.newInstance(sink);
+ tV2.writeTo(outputStream);
+ outputStream.flush();
+ assertEquals(
+ TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8,
+ ByteString.copyFrom(sink));
+ }
+
+ public void testNoStringCachingIfOnlyBytesAccessed() throws Exception {
+ UnittestProto.TestAllTypes proto =
+ UnittestProto.TestAllTypes.parseFrom(encodedTestAllTypes);
+ ByteString optional = proto.getOptionalStringBytes();
+ assertSame(optional, proto.getOptionalStringBytes());
+ assertSame(optional, proto.toBuilder().getOptionalStringBytes());
+
+ ByteString repeated0 = proto.getRepeatedStringBytes(0);
+ ByteString repeated1 = proto.getRepeatedStringBytes(1);
+ assertSame(repeated0, proto.getRepeatedStringBytes(0));
+ assertSame(repeated1, proto.getRepeatedStringBytes(1));
+ assertSame(repeated0, proto.toBuilder().getRepeatedStringBytes(0));
+ assertSame(repeated1, proto.toBuilder().getRepeatedStringBytes(1));
+ }
+}
diff --git a/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/LiteralByteStringTest.java b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/LiteralByteStringTest.java
new file mode 100644
index 00000000..b2dcc7e8
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/LiteralByteStringTest.java
@@ -0,0 +1,344 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf.test;
+import com.google.protobuf.*;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+/**
+ * Test {@link LiteralByteString} by setting up a reference string in {@link #setUp()}.
+ * This class is designed to be extended for testing extensions of {@link LiteralByteString}
+ * such as {@link BoundedByteString}, see {@link BoundedByteStringTest}.
+ *
+ * @author carlanton@google.com (Carl Haverl)
+ */
+public class LiteralByteStringTest extends TestCase {
+ protected static final String UTF_8 = "UTF-8";
+
+ protected String classUnderTest;
+ protected byte[] referenceBytes;
+ protected ByteString stringUnderTest;
+ protected int expectedHashCode;
+
+ @Override
+ protected void setUp() throws Exception {
+ classUnderTest = "LiteralByteString";
+ referenceBytes = ByteStringTest.getTestBytes(1234, 11337766L);
+ stringUnderTest = ByteString.copyFrom(referenceBytes);
+ expectedHashCode = 331161852;
+ }
+
+ protected String getActualClassName(Object object) {
+ String actualClassName = object.getClass().getName();
+ actualClassName = actualClassName.substring(actualClassName.lastIndexOf('.') + 1);
+ return actualClassName;
+ }
+
+ public void testByteAt() {
+ boolean stillEqual = true;
+ for (int i = 0; stillEqual && i < referenceBytes.length; ++i) {
+ stillEqual = (referenceBytes[i] == stringUnderTest.byteAt(i));
+ }
+ assertTrue(classUnderTest + " must capture the right bytes", stillEqual);
+ }
+
+ public void testByteIterator() {
+ boolean stillEqual = true;
+ ByteString.ByteIterator iter = stringUnderTest.iterator();
+ for (int i = 0; stillEqual && i < referenceBytes.length; ++i) {
+ stillEqual = (iter.hasNext() && referenceBytes[i] == iter.nextByte());
+ }
+ assertTrue(classUnderTest + " must capture the right bytes", stillEqual);
+ assertFalse(classUnderTest + " must have exhausted the itertor", iter.hasNext());
+
+ try {
+ iter.nextByte();
+ fail("Should have thrown an exception.");
+ } catch (NoSuchElementException e) {
+ // This is success
+ }
+ }
+
+ public void testByteIterable() {
+ boolean stillEqual = true;
+ int j = 0;
+ for (byte quantum : stringUnderTest) {
+ stillEqual = (referenceBytes[j] == quantum);
+ ++j;
+ }
+ assertTrue(classUnderTest + " must capture the right bytes as Bytes", stillEqual);
+ assertEquals(classUnderTest + " iterable character count", referenceBytes.length, j);
+ }
+
+ public void testSize() {
+ assertEquals(classUnderTest + " must have the expected size", referenceBytes.length,
+ stringUnderTest.size());
+ }
+
+ public void testCopyTo_ByteArrayOffsetLength() {
+ int destinationOffset = 50;
+ int length = 100;
+ byte[] destination = new byte[destinationOffset + length];
+ int sourceOffset = 213;
+ stringUnderTest.copyTo(destination, sourceOffset, destinationOffset, length);
+ boolean stillEqual = true;
+ for (int i = 0; stillEqual && i < length; ++i) {
+ stillEqual = referenceBytes[i + sourceOffset] == destination[i + destinationOffset];
+ }
+ assertTrue(classUnderTest + ".copyTo(4 arg) must give the expected bytes", stillEqual);
+ }
+
+ public void testCopyTo_ByteArrayOffsetLengthErrors() {
+ int destinationOffset = 50;
+ int length = 100;
+ byte[] destination = new byte[destinationOffset + length];
+
+ try {
+ // Copy one too many bytes
+ stringUnderTest.copyTo(destination, stringUnderTest.size() + 1 - length,
+ destinationOffset, length);
+ fail("Should have thrown an exception when copying too many bytes of a "
+ + classUnderTest);
+ } catch (IndexOutOfBoundsException expected) {
+ // This is success
+ }
+
+ try {
+ // Copy with illegal negative sourceOffset
+ stringUnderTest.copyTo(destination, -1, destinationOffset, length);
+ fail("Should have thrown an exception when given a negative sourceOffset in "
+ + classUnderTest);
+ } catch (IndexOutOfBoundsException expected) {
+ // This is success
+ }
+
+ try {
+ // Copy with illegal negative destinationOffset
+ stringUnderTest.copyTo(destination, 0, -1, length);
+ fail("Should have thrown an exception when given a negative destinationOffset in "
+ + classUnderTest);
+ } catch (IndexOutOfBoundsException expected) {
+ // This is success
+ }
+
+ try {
+ // Copy with illegal negative size
+ stringUnderTest.copyTo(destination, 0, 0, -1);
+ fail("Should have thrown an exception when given a negative size in "
+ + classUnderTest);
+ } catch (IndexOutOfBoundsException expected) {
+ // This is success
+ }
+
+ try {
+ // Copy with illegal too-large sourceOffset
+ stringUnderTest.copyTo(destination, 2 * stringUnderTest.size(), 0, length);
+ fail("Should have thrown an exception when the destinationOffset is too large in "
+ + classUnderTest);
+ } catch (IndexOutOfBoundsException expected) {
+ // This is success
+ }
+
+ try {
+ // Copy with illegal too-large destinationOffset
+ stringUnderTest.copyTo(destination, 0, 2 * destination.length, length);
+ fail("Should have thrown an exception when the destinationOffset is too large in "
+ + classUnderTest);
+ } catch (IndexOutOfBoundsException expected) {
+ // This is success
+ }
+ }
+
+ public void testCopyTo_ByteBuffer() {
+ ByteBuffer myBuffer = ByteBuffer.allocate(referenceBytes.length);
+ stringUnderTest.copyTo(myBuffer);
+ assertTrue(classUnderTest + ".copyTo(ByteBuffer) must give back the same bytes",
+ Arrays.equals(referenceBytes, myBuffer.array()));
+ }
+
+ public void testAsReadOnlyByteBuffer() {
+ ByteBuffer byteBuffer = stringUnderTest.asReadOnlyByteBuffer();
+ byte[] roundTripBytes = new byte[referenceBytes.length];
+ assertTrue(byteBuffer.remaining() == referenceBytes.length);
+ assertTrue(byteBuffer.isReadOnly());
+ byteBuffer.get(roundTripBytes);
+ assertTrue(classUnderTest + ".asReadOnlyByteBuffer() must give back the same bytes",
+ Arrays.equals(referenceBytes, roundTripBytes));
+ }
+
+ public void testAsReadOnlyByteBufferList() {
+ List<ByteBuffer> byteBuffers = stringUnderTest.asReadOnlyByteBufferList();
+ int bytesSeen = 0;
+ byte[] roundTripBytes = new byte[referenceBytes.length];
+ for (ByteBuffer byteBuffer : byteBuffers) {
+ int thisLength = byteBuffer.remaining();
+ assertTrue(byteBuffer.isReadOnly());
+ assertTrue(bytesSeen + thisLength <= referenceBytes.length);
+ byteBuffer.get(roundTripBytes, bytesSeen, thisLength);
+ bytesSeen += thisLength;
+ }
+ assertTrue(bytesSeen == referenceBytes.length);
+ assertTrue(classUnderTest + ".asReadOnlyByteBufferTest() must give back the same bytes",
+ Arrays.equals(referenceBytes, roundTripBytes));
+ }
+
+ public void testToByteArray() {
+ byte[] roundTripBytes = stringUnderTest.toByteArray();
+ assertTrue(classUnderTest + ".toByteArray() must give back the same bytes",
+ Arrays.equals(referenceBytes, roundTripBytes));
+ }
+
+ public void testWriteTo() throws IOException {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ stringUnderTest.writeTo(bos);
+ byte[] roundTripBytes = bos.toByteArray();
+ assertTrue(classUnderTest + ".writeTo() must give back the same bytes",
+ Arrays.equals(referenceBytes, roundTripBytes));
+ }
+
+ public void testWriteTo_mutating() throws IOException {
+ OutputStream os = new OutputStream() {
+ @Override
+ public void write(byte[] b, int off, int len) {
+ for (int x = 0; x < len; ++x) {
+ b[off + x] = (byte) 0;
+ }
+ }
+
+ @Override
+ public void write(int b) {
+ // Purposefully left blank.
+ }
+ };
+
+ stringUnderTest.writeTo(os);
+ byte[] newBytes = stringUnderTest.toByteArray();
+ assertTrue(classUnderTest + ".writeTo() must not grant access to underlying array",
+ Arrays.equals(referenceBytes, newBytes));
+ }
+
+ public void testNewOutput() throws IOException {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ByteString.Output output = ByteString.newOutput();
+ stringUnderTest.writeTo(output);
+ assertEquals("Output Size returns correct result",
+ output.size(), stringUnderTest.size());
+ output.writeTo(bos);
+ assertTrue("Output.writeTo() must give back the same bytes",
+ Arrays.equals(referenceBytes, bos.toByteArray()));
+
+ // write the output stream to itself! This should cause it to double
+ output.writeTo(output);
+ assertEquals("Writing an output stream to itself is successful",
+ stringUnderTest.concat(stringUnderTest), output.toByteString());
+
+ output.reset();
+ assertEquals("Output.reset() resets the output", 0, output.size());
+ assertEquals("Output.reset() resets the output",
+ ByteString.EMPTY, output.toByteString());
+
+ }
+
+ public void testHashCode() {
+ int hash = stringUnderTest.hashCode();
+ assertEquals(classUnderTest + " must have expected hashCode", expectedHashCode, hash);
+ }
+
+ public void testNewInput() throws IOException {
+ InputStream input = stringUnderTest.newInput();
+ assertEquals("InputStream.available() returns correct value",
+ stringUnderTest.size(), input.available());
+ boolean stillEqual = true;
+ for (byte referenceByte : referenceBytes) {
+ int expectedInt = (referenceByte & 0xFF);
+ stillEqual = (expectedInt == input.read());
+ }
+ assertEquals("InputStream.available() returns correct value",
+ 0, input.available());
+ assertTrue(classUnderTest + " must give the same bytes from the InputStream", stillEqual);
+ assertEquals(classUnderTest + " InputStream must now be exhausted", -1, input.read());
+ }
+
+ public void testNewInput_skip() throws IOException {
+ InputStream input = stringUnderTest.newInput();
+ int stringSize = stringUnderTest.size();
+ int nearEndIndex = stringSize * 2 / 3;
+ long skipped1 = input.skip(nearEndIndex);
+ assertEquals("InputStream.skip()", skipped1, nearEndIndex);
+ assertEquals("InputStream.available()",
+ stringSize - skipped1, input.available());
+ assertTrue("InputStream.mark() is available", input.markSupported());
+ input.mark(0);
+ assertEquals("InputStream.skip(), read()",
+ stringUnderTest.byteAt(nearEndIndex) & 0xFF, input.read());
+ assertEquals("InputStream.available()",
+ stringSize - skipped1 - 1, input.available());
+ long skipped2 = input.skip(stringSize);
+ assertEquals("InputStream.skip() incomplete",
+ skipped2, stringSize - skipped1 - 1);
+ assertEquals("InputStream.skip(), no more input", 0, input.available());
+ assertEquals("InputStream.skip(), no more input", -1, input.read());
+ input.reset();
+ assertEquals("InputStream.reset() succeded",
+ stringSize - skipped1, input.available());
+ assertEquals("InputStream.reset(), read()",
+ stringUnderTest.byteAt(nearEndIndex) & 0xFF, input.read());
+ }
+
+ public void testNewCodedInput() throws IOException {
+ CodedInputStream cis = stringUnderTest.newCodedInput();
+ byte[] roundTripBytes = cis.readRawBytes(referenceBytes.length);
+ assertTrue(classUnderTest + " must give the same bytes back from the CodedInputStream",
+ Arrays.equals(referenceBytes, roundTripBytes));
+ assertTrue(classUnderTest + " CodedInputStream must now be exhausted", cis.isAtEnd());
+ }
+
+ /**
+ * Make sure we keep things simple when concatenating with empty. See also
+ * {@link ByteStringTest#testConcat_empty()}.
+ */
+ public void testConcat_empty() {
+ assertSame(classUnderTest + " concatenated with empty must give " + classUnderTest,
+ stringUnderTest.concat(ByteString.EMPTY), stringUnderTest);
+ assertSame("empty concatenated with " + classUnderTest + " must give " + classUnderTest,
+ ByteString.EMPTY.concat(stringUnderTest), stringUnderTest);
+ }
+}
diff --git a/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/MessageTest.java b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/MessageTest.java
new file mode 100644
index 00000000..c8c95a87
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/MessageTest.java
@@ -0,0 +1,354 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf.test;
+import com.google.protobuf.*;
+
+import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestAllExtensions;
+import protobuf_unittest.UnittestProto.TestRequired;
+import protobuf_unittest.UnittestProto.TestRequiredForeign;
+import protobuf_unittest.UnittestProto.ForeignMessage;
+
+import junit.framework.TestCase;
+
+import java.util.List;
+
+/**
+ * Misc. unit tests for message operations that apply to both generated
+ * and dynamic messages.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public class MessageTest extends TestCase {
+ // =================================================================
+ // Message-merging tests.
+
+ static final TestAllTypes MERGE_SOURCE =
+ TestAllTypes.newBuilder()
+ .setOptionalInt32(1)
+ .setOptionalString("foo")
+ .setOptionalForeignMessage(ForeignMessage.getDefaultInstance())
+ .addRepeatedString("bar")
+ .build();
+
+ static final TestAllTypes MERGE_DEST =
+ TestAllTypes.newBuilder()
+ .setOptionalInt64(2)
+ .setOptionalString("baz")
+ .setOptionalForeignMessage(ForeignMessage.newBuilder().setC(3).build())
+ .addRepeatedString("qux")
+ .build();
+
+ static final String MERGE_RESULT_TEXT =
+ "optional_int32: 1\n" +
+ "optional_int64: 2\n" +
+ "optional_string: \"foo\"\n" +
+ "optional_foreign_message {\n" +
+ " c: 3\n" +
+ "}\n" +
+ "repeated_string: \"qux\"\n" +
+ "repeated_string: \"bar\"\n";
+
+ public void testMergeFrom() throws Exception {
+ TestAllTypes result =
+ TestAllTypes.newBuilder(MERGE_DEST)
+ .mergeFrom(MERGE_SOURCE).build();
+
+ assertEquals(MERGE_RESULT_TEXT, result.toString());
+ }
+
+ /**
+ * Test merging a DynamicMessage into a GeneratedMessage. As long as they
+ * have the same descriptor, this should work, but it is an entirely different
+ * code path.
+ */
+ public void testMergeFromDynamic() throws Exception {
+ TestAllTypes result =
+ TestAllTypes.newBuilder(MERGE_DEST)
+ .mergeFrom(DynamicMessage.newBuilder(MERGE_SOURCE).build())
+ .build();
+
+ assertEquals(MERGE_RESULT_TEXT, result.toString());
+ }
+
+ /** Test merging two DynamicMessages. */
+ public void testDynamicMergeFrom() throws Exception {
+ DynamicMessage result =
+ DynamicMessage.newBuilder(MERGE_DEST)
+ .mergeFrom(DynamicMessage.newBuilder(MERGE_SOURCE).build())
+ .build();
+
+ assertEquals(MERGE_RESULT_TEXT, result.toString());
+ }
+
+ // =================================================================
+ // Required-field-related tests.
+
+ private static final TestRequired TEST_REQUIRED_UNINITIALIZED =
+ TestRequired.getDefaultInstance();
+ private static final TestRequired TEST_REQUIRED_INITIALIZED =
+ TestRequired.newBuilder().setA(1).setB(2).setC(3).build();
+
+ public void testRequired() throws Exception {
+ TestRequired.Builder builder = TestRequired.newBuilder();
+
+ assertFalse(builder.isInitialized());
+ builder.setA(1);
+ assertFalse(builder.isInitialized());
+ builder.setB(1);
+ assertFalse(builder.isInitialized());
+ builder.setC(1);
+ assertTrue(builder.isInitialized());
+ }
+
+ public void testRequiredForeign() throws Exception {
+ TestRequiredForeign.Builder builder = TestRequiredForeign.newBuilder();
+
+ assertTrue(builder.isInitialized());
+
+ builder.setOptionalMessage(TEST_REQUIRED_UNINITIALIZED);
+ assertFalse(builder.isInitialized());
+
+ builder.setOptionalMessage(TEST_REQUIRED_INITIALIZED);
+ assertTrue(builder.isInitialized());
+
+ builder.addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED);
+ assertFalse(builder.isInitialized());
+
+ builder.setRepeatedMessage(0, TEST_REQUIRED_INITIALIZED);
+ assertTrue(builder.isInitialized());
+ }
+
+ public void testRequiredExtension() throws Exception {
+ TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
+
+ assertTrue(builder.isInitialized());
+
+ builder.setExtension(TestRequired.single, TEST_REQUIRED_UNINITIALIZED);
+ assertFalse(builder.isInitialized());
+
+ builder.setExtension(TestRequired.single, TEST_REQUIRED_INITIALIZED);
+ assertTrue(builder.isInitialized());
+
+ builder.addExtension(TestRequired.multi, TEST_REQUIRED_UNINITIALIZED);
+ assertFalse(builder.isInitialized());
+
+ builder.setExtension(TestRequired.multi, 0, TEST_REQUIRED_INITIALIZED);
+ assertTrue(builder.isInitialized());
+ }
+
+ public void testRequiredDynamic() throws Exception {
+ Descriptors.Descriptor descriptor = TestRequired.getDescriptor();
+ DynamicMessage.Builder builder = DynamicMessage.newBuilder(descriptor);
+
+ assertFalse(builder.isInitialized());
+ builder.setField(descriptor.findFieldByName("a"), 1);
+ assertFalse(builder.isInitialized());
+ builder.setField(descriptor.findFieldByName("b"), 1);
+ assertFalse(builder.isInitialized());
+ builder.setField(descriptor.findFieldByName("c"), 1);
+ assertTrue(builder.isInitialized());
+ }
+
+ public void testRequiredDynamicForeign() throws Exception {
+ Descriptors.Descriptor descriptor = TestRequiredForeign.getDescriptor();
+ DynamicMessage.Builder builder = DynamicMessage.newBuilder(descriptor);
+
+ assertTrue(builder.isInitialized());
+
+ builder.setField(descriptor.findFieldByName("optional_message"),
+ TEST_REQUIRED_UNINITIALIZED);
+ assertFalse(builder.isInitialized());
+
+ builder.setField(descriptor.findFieldByName("optional_message"),
+ TEST_REQUIRED_INITIALIZED);
+ assertTrue(builder.isInitialized());
+
+ builder.addRepeatedField(descriptor.findFieldByName("repeated_message"),
+ TEST_REQUIRED_UNINITIALIZED);
+ assertFalse(builder.isInitialized());
+
+ builder.setRepeatedField(descriptor.findFieldByName("repeated_message"), 0,
+ TEST_REQUIRED_INITIALIZED);
+ assertTrue(builder.isInitialized());
+ }
+
+ public void testUninitializedException() throws Exception {
+ try {
+ TestRequired.newBuilder().build();
+ fail("Should have thrown an exception.");
+ } catch (UninitializedMessageException e) {
+ assertEquals("Message missing required fields: a, b, c", e.getMessage());
+ }
+ }
+
+ public void testBuildPartial() throws Exception {
+ // We're mostly testing that no exception is thrown.
+ TestRequired message = TestRequired.newBuilder().buildPartial();
+ assertFalse(message.isInitialized());
+ }
+
+ public void testNestedUninitializedException() throws Exception {
+ try {
+ TestRequiredForeign.newBuilder()
+ .setOptionalMessage(TEST_REQUIRED_UNINITIALIZED)
+ .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED)
+ .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED)
+ .build();
+ fail("Should have thrown an exception.");
+ } catch (UninitializedMessageException e) {
+ assertEquals(
+ "Message missing required fields: " +
+ "optional_message.a, " +
+ "optional_message.b, " +
+ "optional_message.c, " +
+ "repeated_message[0].a, " +
+ "repeated_message[0].b, " +
+ "repeated_message[0].c, " +
+ "repeated_message[1].a, " +
+ "repeated_message[1].b, " +
+ "repeated_message[1].c",
+ e.getMessage());
+ }
+ }
+
+ public void testBuildNestedPartial() throws Exception {
+ // We're mostly testing that no exception is thrown.
+ TestRequiredForeign message =
+ TestRequiredForeign.newBuilder()
+ .setOptionalMessage(TEST_REQUIRED_UNINITIALIZED)
+ .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED)
+ .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED)
+ .buildPartial();
+ assertFalse(message.isInitialized());
+ }
+
+ public void testParseUnititialized() throws Exception {
+ try {
+ TestRequired.parseFrom(ByteString.EMPTY);
+ fail("Should have thrown an exception.");
+ } catch (InvalidProtocolBufferException e) {
+ assertEquals("Message missing required fields: a, b, c", e.getMessage());
+ }
+ }
+
+ public void testParseNestedUnititialized() throws Exception {
+ ByteString data =
+ TestRequiredForeign.newBuilder()
+ .setOptionalMessage(TEST_REQUIRED_UNINITIALIZED)
+ .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED)
+ .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED)
+ .buildPartial().toByteString();
+
+ try {
+ TestRequiredForeign.parseFrom(data);
+ fail("Should have thrown an exception.");
+ } catch (InvalidProtocolBufferException e) {
+ assertEquals(
+ "Message missing required fields: " +
+ "optional_message.a, " +
+ "optional_message.b, " +
+ "optional_message.c, " +
+ "repeated_message[0].a, " +
+ "repeated_message[0].b, " +
+ "repeated_message[0].c, " +
+ "repeated_message[1].a, " +
+ "repeated_message[1].b, " +
+ "repeated_message[1].c",
+ e.getMessage());
+ }
+ }
+
+ public void testDynamicUninitializedException() throws Exception {
+ try {
+ DynamicMessage.newBuilder(TestRequired.getDescriptor()).build();
+ fail("Should have thrown an exception.");
+ } catch (UninitializedMessageException e) {
+ assertEquals("Message missing required fields: a, b, c", e.getMessage());
+ }
+ }
+
+ public void testDynamicBuildPartial() throws Exception {
+ // We're mostly testing that no exception is thrown.
+ DynamicMessage message =
+ DynamicMessage.newBuilder(TestRequired.getDescriptor())
+ .buildPartial();
+ assertFalse(message.isInitialized());
+ }
+
+ public void testDynamicParseUnititialized() throws Exception {
+ try {
+ Descriptors.Descriptor descriptor = TestRequired.getDescriptor();
+ DynamicMessage.parseFrom(descriptor, ByteString.EMPTY);
+ fail("Should have thrown an exception.");
+ } catch (InvalidProtocolBufferException e) {
+ assertEquals("Message missing required fields: a, b, c", e.getMessage());
+ }
+ }
+
+ /** Test reading unset repeated message from DynamicMessage. */
+ public void testDynamicRepeatedMessageNull() throws Exception {
+ Descriptors.Descriptor descriptor = TestRequired.getDescriptor();
+ DynamicMessage result =
+ DynamicMessage.newBuilder(TestAllTypes.getDescriptor())
+ .mergeFrom(DynamicMessage.newBuilder(MERGE_SOURCE).build())
+ .build();
+
+ assertTrue(result.getField(result.getDescriptorForType()
+ .findFieldByName("repeated_foreign_message")) instanceof List<?>);
+ assertEquals(result.getRepeatedFieldCount(result.getDescriptorForType()
+ .findFieldByName("repeated_foreign_message")), 0);
+ }
+
+ /** Test reading repeated message from DynamicMessage. */
+ public void testDynamicRepeatedMessageNotNull() throws Exception {
+
+ TestAllTypes REPEATED_NESTED =
+ TestAllTypes.newBuilder()
+ .setOptionalInt32(1)
+ .setOptionalString("foo")
+ .setOptionalForeignMessage(ForeignMessage.getDefaultInstance())
+ .addRepeatedString("bar")
+ .addRepeatedForeignMessage(ForeignMessage.getDefaultInstance())
+ .addRepeatedForeignMessage(ForeignMessage.getDefaultInstance())
+ .build();
+ Descriptors.Descriptor descriptor = TestRequired.getDescriptor();
+ DynamicMessage result =
+ DynamicMessage.newBuilder(TestAllTypes.getDescriptor())
+ .mergeFrom(DynamicMessage.newBuilder(REPEATED_NESTED).build())
+ .build();
+
+ assertTrue(result.getField(result.getDescriptorForType()
+ .findFieldByName("repeated_foreign_message")) instanceof List<?>);
+ assertEquals(result.getRepeatedFieldCount(result.getDescriptorForType()
+ .findFieldByName("repeated_foreign_message")), 2);
+ }
+}
diff --git a/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/NestedBuildersTest.java b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/NestedBuildersTest.java
new file mode 100644
index 00000000..68d70bec
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/NestedBuildersTest.java
@@ -0,0 +1,186 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf.test;
+import com.google.protobuf.*;
+
+import protobuf_unittest.Vehicle;
+import protobuf_unittest.Wheel;
+
+import junit.framework.TestCase;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * Test cases that exercise end-to-end use cases involving
+ * {@link SingleFieldBuilder} and {@link RepeatedFieldBuilder}.
+ *
+ * @author jonp@google.com (Jon Perlow)
+ */
+public class NestedBuildersTest extends TestCase {
+
+ public void testMessagesAndBuilders() {
+ Vehicle.Builder vehicleBuilder = Vehicle.newBuilder();
+ vehicleBuilder.addWheelBuilder()
+ .setRadius(4)
+ .setWidth(1);
+ vehicleBuilder.addWheelBuilder()
+ .setRadius(4)
+ .setWidth(2);
+ vehicleBuilder.addWheelBuilder()
+ .setRadius(4)
+ .setWidth(3);
+ vehicleBuilder.addWheelBuilder()
+ .setRadius(4)
+ .setWidth(4);
+ vehicleBuilder.getEngineBuilder()
+ .setLiters(10);
+
+ Vehicle vehicle = vehicleBuilder.build();
+ assertEquals(4, vehicle.getWheelCount());
+ for (int i = 0; i < 4; i++) {
+ Wheel wheel = vehicle.getWheel(i);
+ assertEquals(4, wheel.getRadius());
+ assertEquals(i + 1, wheel.getWidth());
+ }
+ assertEquals(10, vehicle.getEngine().getLiters());
+
+ for (int i = 0; i < 4; i++) {
+ vehicleBuilder.getWheelBuilder(i)
+ .setRadius(5)
+ .setWidth(i + 10);
+ }
+ vehicleBuilder.getEngineBuilder().setLiters(20);
+
+ vehicle = vehicleBuilder.build();
+ for (int i = 0; i < 4; i++) {
+ Wheel wheel = vehicle.getWheel(i);
+ assertEquals(5, wheel.getRadius());
+ assertEquals(i + 10, wheel.getWidth());
+ }
+ assertEquals(20, vehicle.getEngine().getLiters());
+ assertTrue(vehicle.hasEngine());
+ }
+
+ public void testMessagesAreCached() {
+ Vehicle.Builder vehicleBuilder = Vehicle.newBuilder();
+ vehicleBuilder.addWheelBuilder()
+ .setRadius(1)
+ .setWidth(2);
+ vehicleBuilder.addWheelBuilder()
+ .setRadius(3)
+ .setWidth(4);
+ vehicleBuilder.addWheelBuilder()
+ .setRadius(5)
+ .setWidth(6);
+ vehicleBuilder.addWheelBuilder()
+ .setRadius(7)
+ .setWidth(8);
+
+ // Make sure messages are cached.
+ List<Wheel> wheels = new ArrayList<Wheel>(vehicleBuilder.getWheelList());
+ for (int i = 0; i < wheels.size(); i++) {
+ assertSame(wheels.get(i), vehicleBuilder.getWheel(i));
+ }
+
+ // Now get builders and check they didn't change.
+ for (int i = 0; i < wheels.size(); i++) {
+ vehicleBuilder.getWheel(i);
+ }
+ for (int i = 0; i < wheels.size(); i++) {
+ assertSame(wheels.get(i), vehicleBuilder.getWheel(i));
+ }
+
+ // Change just one
+ vehicleBuilder.getWheelBuilder(3)
+ .setRadius(20).setWidth(20);
+
+ // Now get wheels and check that only that one changed
+ for (int i = 0; i < wheels.size(); i++) {
+ if (i < 3) {
+ assertSame(wheels.get(i), vehicleBuilder.getWheel(i));
+ } else {
+ assertNotSame(wheels.get(i), vehicleBuilder.getWheel(i));
+ }
+ }
+ }
+
+ public void testRemove_WithNestedBuilders() {
+ Vehicle.Builder vehicleBuilder = Vehicle.newBuilder();
+ vehicleBuilder.addWheelBuilder()
+ .setRadius(1)
+ .setWidth(1);
+ vehicleBuilder.addWheelBuilder()
+ .setRadius(2)
+ .setWidth(2);
+ vehicleBuilder.removeWheel(0);
+
+ assertEquals(1, vehicleBuilder.getWheelCount());
+ assertEquals(2, vehicleBuilder.getWheel(0).getRadius());
+ }
+
+ public void testRemove_WithNestedMessages() {
+ Vehicle.Builder vehicleBuilder = Vehicle.newBuilder();
+ vehicleBuilder.addWheel(Wheel.newBuilder()
+ .setRadius(1)
+ .setWidth(1));
+ vehicleBuilder.addWheel(Wheel.newBuilder()
+ .setRadius(2)
+ .setWidth(2));
+ vehicleBuilder.removeWheel(0);
+
+ assertEquals(1, vehicleBuilder.getWheelCount());
+ assertEquals(2, vehicleBuilder.getWheel(0).getRadius());
+ }
+
+ public void testMerge() {
+ Vehicle vehicle1 = Vehicle.newBuilder()
+ .addWheel(Wheel.newBuilder().setRadius(1).build())
+ .addWheel(Wheel.newBuilder().setRadius(2).build())
+ .build();
+
+ Vehicle vehicle2 = Vehicle.newBuilder()
+ .mergeFrom(vehicle1)
+ .build();
+ // List should be the same -- no allocation
+ assertSame(vehicle1.getWheelList(), vehicle2.getWheelList());
+
+ Vehicle vehicle3 = vehicle1.toBuilder().build();
+ assertSame(vehicle1.getWheelList(), vehicle3.getWheelList());
+ }
+
+ public void testGettingBuilderMarksFieldAsHaving() {
+ Vehicle.Builder vehicleBuilder = Vehicle.newBuilder();
+ vehicleBuilder.getEngineBuilder();
+ Vehicle vehicle = vehicleBuilder.buildPartial();
+ assertTrue(vehicle.hasEngine());
+ }
+}
diff --git a/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/ParserTest.java b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/ParserTest.java
new file mode 100644
index 00000000..b35af689
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/ParserTest.java
@@ -0,0 +1,278 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf.test;
+import com.google.protobuf.*;
+
+import protobuf_unittest.UnittestOptimizeFor.TestOptimizedForSize;
+import protobuf_unittest.UnittestOptimizeFor.TestRequiredOptimizedForSize;
+import protobuf_unittest.UnittestOptimizeFor;
+import protobuf_unittest.UnittestProto.ForeignMessage;
+import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestEmptyMessage;
+import protobuf_unittest.UnittestProto.TestRequired;
+import protobuf_unittest.UnittestProto.TestParsingMerge;
+import protobuf_unittest.UnittestProto;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Unit test for {@link Parser}.
+ *
+ * @author liujisi@google.com (Pherl Liu)
+ */
+public class ParserTest extends TestCase {
+ public void testGeneratedMessageParserSingleton() throws Exception {
+ for (int i = 0; i < 10; i++) {
+ assertEquals(TestAllTypes.PARSER,
+ TestUtil.getAllSet().getParserForType());
+ }
+ }
+
+ private void assertRoundTripEquals(MessageLite message,
+ ExtensionRegistryLite registry)
+ throws Exception {
+ final byte[] data = message.toByteArray();
+ final int offset = 20;
+ final int length = data.length;
+ final int padding = 30;
+ Parser<? extends MessageLite> parser = message.getParserForType();
+ assertMessageEquals(message, parser.parseFrom(data, registry));
+ assertMessageEquals(message, parser.parseFrom(
+ generatePaddingArray(data, offset, padding),
+ offset, length, registry));
+ assertMessageEquals(message, parser.parseFrom(
+ message.toByteString(), registry));
+ assertMessageEquals(message, parser.parseFrom(
+ new ByteArrayInputStream(data), registry));
+ assertMessageEquals(message, parser.parseFrom(
+ CodedInputStream.newInstance(data), registry));
+ }
+
+ private void assertRoundTripEquals(MessageLite message) throws Exception {
+ final byte[] data = message.toByteArray();
+ final int offset = 20;
+ final int length = data.length;
+ final int padding = 30;
+ Parser<? extends MessageLite> parser = message.getParserForType();
+ assertMessageEquals(message, parser.parseFrom(data));
+ assertMessageEquals(message, parser.parseFrom(
+ generatePaddingArray(data, offset, padding),
+ offset, length));
+ assertMessageEquals(message, parser.parseFrom(message.toByteString()));
+ assertMessageEquals(message, parser.parseFrom(
+ new ByteArrayInputStream(data)));
+ assertMessageEquals(message, parser.parseFrom(
+ CodedInputStream.newInstance(data)));
+ }
+
+ private void assertMessageEquals(MessageLite expected, MessageLite actual)
+ throws Exception {
+ if (expected instanceof Message) {
+ assertEquals(expected, actual);
+ } else {
+ assertEquals(expected.toByteString(), actual.toByteString());
+ }
+ }
+
+ private byte[] generatePaddingArray(byte[] data, int offset, int padding) {
+ byte[] result = new byte[offset + data.length + padding];
+ System.arraycopy(data, 0, result, offset, data.length);
+ return result;
+ }
+
+ public void testNormalMessage() throws Exception {
+ assertRoundTripEquals(TestUtil.getAllSet());
+ }
+
+ public void testParsePartial() throws Exception {
+ Parser<TestRequired> parser = TestRequired.PARSER;
+ final String errorString =
+ "Should throw exceptions when the parsed message isn't initialized.";
+
+ // TestRequired.b and TestRequired.c are not set.
+ TestRequired partialMessage = TestRequired.newBuilder()
+ .setA(1).buildPartial();
+
+ // parsePartialFrom should pass.
+ byte[] data = partialMessage.toByteArray();
+ assertEquals(partialMessage, parser.parsePartialFrom(data));
+ assertEquals(partialMessage, parser.parsePartialFrom(
+ partialMessage.toByteString()));
+ assertEquals(partialMessage, parser.parsePartialFrom(
+ new ByteArrayInputStream(data)));
+ assertEquals(partialMessage, parser.parsePartialFrom(
+ CodedInputStream.newInstance(data)));
+
+ // parseFrom(ByteArray)
+ try {
+ parser.parseFrom(partialMessage.toByteArray());
+ fail(errorString);
+ } catch (InvalidProtocolBufferException e) {
+ // pass.
+ }
+
+ // parseFrom(ByteString)
+ try {
+ parser.parseFrom(partialMessage.toByteString());
+ fail(errorString);
+ } catch (InvalidProtocolBufferException e) {
+ // pass.
+ }
+
+ // parseFrom(InputStream)
+ try {
+ parser.parseFrom(new ByteArrayInputStream(partialMessage.toByteArray()));
+ fail(errorString);
+ } catch (IOException e) {
+ // pass.
+ }
+
+ // parseFrom(CodedInputStream)
+ try {
+ parser.parseFrom(CodedInputStream.newInstance(
+ partialMessage.toByteArray()));
+ fail(errorString);
+ } catch (IOException e) {
+ // pass.
+ }
+ }
+
+ public void testParseDelimitedTo() throws Exception {
+ // Write normal Message.
+ TestAllTypes normalMessage = TestUtil.getAllSet();
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ normalMessage.writeDelimitedTo(output);
+
+ InputStream input = new ByteArrayInputStream(output.toByteArray());
+ assertMessageEquals(
+ normalMessage,
+ normalMessage.getParserForType().parseDelimitedFrom(input));
+ }
+
+ public void testParseUnknownFields() throws Exception {
+ // All fields will be treated as unknown fields in emptyMessage.
+ TestEmptyMessage emptyMessage = TestEmptyMessage.PARSER.parseFrom(
+ TestUtil.getAllSet().toByteString());
+ assertEquals(
+ TestUtil.getAllSet().toByteString(),
+ emptyMessage.toByteString());
+ }
+
+ public void testOptimizeForSize() throws Exception {
+ TestOptimizedForSize.Builder builder = TestOptimizedForSize.newBuilder();
+ builder.setI(12).setMsg(ForeignMessage.newBuilder().setC(34).build());
+ builder.setExtension(TestOptimizedForSize.testExtension, 56);
+ builder.setExtension(TestOptimizedForSize.testExtension2,
+ TestRequiredOptimizedForSize.newBuilder().setX(78).build());
+
+ TestOptimizedForSize message = builder.build();
+ ExtensionRegistry registry = ExtensionRegistry.newInstance();
+ UnittestOptimizeFor.registerAllExtensions(registry);
+
+ assertRoundTripEquals(message, registry);
+ }
+
+ /** Helper method for {@link #testParsingMerge()}.*/
+ private void assertMessageMerged(TestAllTypes allTypes)
+ throws Exception {
+ assertEquals(3, allTypes.getOptionalInt32());
+ assertEquals(2, allTypes.getOptionalInt64());
+ assertEquals("hello", allTypes.getOptionalString());
+ }
+
+ public void testParsingMerge() throws Exception {
+ // Build messages.
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TestAllTypes msg1 = builder.setOptionalInt32(1).build();
+ builder.clear();
+ TestAllTypes msg2 = builder.setOptionalInt64(2).build();
+ builder.clear();
+ TestAllTypes msg3 = builder.setOptionalInt32(3)
+ .setOptionalString("hello").build();
+
+ // Build groups.
+ TestParsingMerge.RepeatedFieldsGenerator.Group1 optionalG1 =
+ TestParsingMerge.RepeatedFieldsGenerator.Group1.newBuilder()
+ .setField1(msg1).build();
+ TestParsingMerge.RepeatedFieldsGenerator.Group1 optionalG2 =
+ TestParsingMerge.RepeatedFieldsGenerator.Group1.newBuilder()
+ .setField1(msg2).build();
+ TestParsingMerge.RepeatedFieldsGenerator.Group1 optionalG3 =
+ TestParsingMerge.RepeatedFieldsGenerator.Group1.newBuilder()
+ .setField1(msg3).build();
+ TestParsingMerge.RepeatedFieldsGenerator.Group2 repeatedG1 =
+ TestParsingMerge.RepeatedFieldsGenerator.Group2.newBuilder()
+ .setField1(msg1).build();
+ TestParsingMerge.RepeatedFieldsGenerator.Group2 repeatedG2 =
+ TestParsingMerge.RepeatedFieldsGenerator.Group2.newBuilder()
+ .setField1(msg2).build();
+ TestParsingMerge.RepeatedFieldsGenerator.Group2 repeatedG3 =
+ TestParsingMerge.RepeatedFieldsGenerator.Group2.newBuilder()
+ .setField1(msg3).build();
+
+ // Assign and serialize RepeatedFieldsGenerator.
+ ByteString data = TestParsingMerge.RepeatedFieldsGenerator.newBuilder()
+ .addField1(msg1).addField1(msg2).addField1(msg3)
+ .addField2(msg1).addField2(msg2).addField2(msg3)
+ .addField3(msg1).addField3(msg2).addField3(msg3)
+ .addGroup1(optionalG1).addGroup1(optionalG2).addGroup1(optionalG3)
+ .addGroup2(repeatedG1).addGroup2(repeatedG2).addGroup2(repeatedG3)
+ .addExt1(msg1).addExt1(msg2).addExt1(msg3)
+ .addExt2(msg1).addExt2(msg2).addExt2(msg3)
+ .build().toByteString();
+
+ // Parse TestParsingMerge.
+ ExtensionRegistry registry = ExtensionRegistry.newInstance();
+ UnittestProto.registerAllExtensions(registry);
+ TestParsingMerge parsingMerge =
+ TestParsingMerge.PARSER.parseFrom(data, registry);
+
+ // Required and optional fields should be merged.
+ assertMessageMerged(parsingMerge.getRequiredAllTypes());
+ assertMessageMerged(parsingMerge.getOptionalAllTypes());
+ assertMessageMerged(
+ parsingMerge.getOptionalGroup().getOptionalGroupAllTypes());
+ assertMessageMerged(parsingMerge.getExtension(
+ TestParsingMerge.optionalExt));
+
+ // Repeated fields should not be merged.
+ assertEquals(3, parsingMerge.getRepeatedAllTypesCount());
+ assertEquals(3, parsingMerge.getRepeatedGroupCount());
+ assertEquals(3, parsingMerge.getExtensionCount(
+ TestParsingMerge.repeatedExt));
+ }
+
+}
diff --git a/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/RopeByteStringSubstringTest.java b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/RopeByteStringSubstringTest.java
new file mode 100644
index 00000000..3c1f5035
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/RopeByteStringSubstringTest.java
@@ -0,0 +1,62 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf.test;
+import com.google.protobuf.*;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Iterator;
+
+/**
+ * This class tests {@link RopeByteString#substring(int, int)} by inheriting the tests from
+ * {@link LiteralByteStringTest}. Only a couple of methods are overridden.
+ *
+ * @author carlanton@google.com (Carl Haverl)
+ */
+public class RopeByteStringSubstringTest extends LiteralByteStringTest {
+
+ @Override
+ protected void setUp() throws Exception {
+ classUnderTest = "RopeByteString";
+ byte[] sourceBytes = ByteStringTest.getTestBytes(22341, 22337766L);
+ Iterator<ByteString> iter = ByteStringTest.makeConcretePieces(sourceBytes).iterator();
+ ByteString sourceString = iter.next();
+ while (iter.hasNext()) {
+ sourceString = sourceString.concat(iter.next());
+ }
+
+ int from = 1130;
+ int to = sourceBytes.length - 5555;
+ stringUnderTest = sourceString.substring(from, to);
+ referenceBytes = new byte[to - from];
+ System.arraycopy(sourceBytes, from, referenceBytes, 0, to - from);
+ expectedHashCode = -1259260680;
+ }
+}
diff --git a/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/RopeByteStringTest.java b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/RopeByteStringTest.java
new file mode 100644
index 00000000..8caeadd9
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/RopeByteStringTest.java
@@ -0,0 +1,84 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf.test;
+import com.google.protobuf.*;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Arrays;
+import java.util.Iterator;
+
+/**
+ * This class tests {@link RopeByteString} by inheriting the tests from
+ * {@link LiteralByteStringTest}. Only a couple of methods are overridden.
+ *
+ * <p>A full test of the result of {@link RopeByteString#substring(int, int)} is found in the
+ * separate class {@link RopeByteStringSubstringTest}.
+ *
+ * @author carlanton@google.com (Carl Haverl)
+ */
+public class RopeByteStringTest extends LiteralByteStringTest {
+
+ @Override
+ protected void setUp() throws Exception {
+ classUnderTest = "RopeByteString";
+ referenceBytes = ByteStringTest.getTestBytes(22341, 22337766L);
+ Iterator<ByteString> iter = ByteStringTest.makeConcretePieces(referenceBytes).iterator();
+ stringUnderTest = iter.next();
+ while (iter.hasNext()) {
+ stringUnderTest = stringUnderTest.concat(iter.next());
+ }
+ expectedHashCode = -1214197238;
+ }
+
+ public void testBalance() {
+ int numberOfPieces = 10000;
+ int pieceSize = 64;
+ byte[] testBytes = ByteStringTest.getTestBytes(numberOfPieces * pieceSize, 113377L);
+
+ // Build up a big ByteString from smaller pieces to force a rebalance
+ ByteString concatenated = ByteString.EMPTY;
+ for (int i = 0; i < numberOfPieces; ++i) {
+ concatenated = concatenated.concat(ByteString.copyFrom(testBytes, i * pieceSize, pieceSize));
+ }
+
+ assertEquals(classUnderTest + " from string must have the expected type",
+ classUnderTest, getActualClassName(concatenated));
+ assertTrue(classUnderTest + " underlying bytes must match after balancing",
+ Arrays.equals(testBytes, concatenated.toByteArray()));
+ ByteString testString = ByteString.copyFrom(testBytes);
+ assertTrue(classUnderTest + " balanced string must equal flat string",
+ concatenated.equals(testString));
+ assertTrue(classUnderTest + " flat string must equal balanced string",
+ testString.equals(concatenated));
+ assertEquals(classUnderTest + " balanced string must have same hash code as flat string",
+ testString.hashCode(), concatenated.hashCode());
+ }
+}
diff --git a/java/src/test/java/com/google/protobuf/ServiceTest.java b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/ServiceTest.java
index ff980d66..4c7f751c 100644
--- a/java/src/test/java/com/google/protobuf/ServiceTest.java
+++ b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/ServiceTest.java
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
+// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -28,7 +28,8 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-package com.google.protobuf;
+package com.google.protobuf.test;
+import com.google.protobuf.*;
import com.google.protobuf.Descriptors.FileDescriptor;
import com.google.protobuf.Descriptors.MethodDescriptor;
diff --git a/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/TestBadIdentifiers.java b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/TestBadIdentifiers.java
new file mode 100644
index 00000000..50867322
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/TestBadIdentifiers.java
@@ -0,0 +1,64 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf.test;
+import com.google.protobuf.*;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests that proto2 api generation doesn't cause compile errors when
+ * compiling protocol buffers that have names that would otherwise conflict
+ * if not fully qualified (like @Deprecated and @Override).
+ *
+ * @author jonp@google.com (Jon Perlow)
+ */
+public class TestBadIdentifiers extends TestCase {
+
+ public void testCompilation() {
+ // If this compiles, it means the generation was correct.
+ TestBadIdentifiersProto.Deprecated.newBuilder();
+ TestBadIdentifiersProto.Override.newBuilder();
+ }
+
+ public void testGetDescriptor() {
+ Descriptors.FileDescriptor fileDescriptor =
+ TestBadIdentifiersProto.getDescriptor();
+ String descriptorField = TestBadIdentifiersProto.Descriptor
+ .getDefaultInstance().getDescriptor();
+ Descriptors.Descriptor protoDescriptor = TestBadIdentifiersProto.Descriptor
+ .getDefaultInstance().getDescriptorForType();
+ String nestedDescriptorField = TestBadIdentifiersProto.Descriptor
+ .NestedDescriptor.getDefaultInstance().getDescriptor();
+ Descriptors.Descriptor nestedProtoDescriptor = TestBadIdentifiersProto
+ .Descriptor.NestedDescriptor.getDefaultInstance()
+ .getDescriptorForType();
+ }
+}
diff --git a/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/TestUtil.java b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/TestUtil.java
new file mode 100644
index 00000000..a9234830
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/TestUtil.java
@@ -0,0 +1,3068 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf.test;
+import com.google.protobuf.*;
+
+import protobuf_unittest.UnittestProto;
+
+// The static imports are to avoid 100+ char lines. The following is roughly equivalent to
+// import static protobuf_unittest.UnittestProto.*;
+import static protobuf_unittest.UnittestProto.defaultInt32Extension;
+import static protobuf_unittest.UnittestProto.defaultInt64Extension;
+import static protobuf_unittest.UnittestProto.defaultUint32Extension;
+import static protobuf_unittest.UnittestProto.defaultUint64Extension;
+import static protobuf_unittest.UnittestProto.defaultSint32Extension;
+import static protobuf_unittest.UnittestProto.defaultSint64Extension;
+import static protobuf_unittest.UnittestProto.defaultFixed32Extension;
+import static protobuf_unittest.UnittestProto.defaultFixed64Extension;
+import static protobuf_unittest.UnittestProto.defaultSfixed32Extension;
+import static protobuf_unittest.UnittestProto.defaultSfixed64Extension;
+import static protobuf_unittest.UnittestProto.defaultFloatExtension;
+import static protobuf_unittest.UnittestProto.defaultDoubleExtension;
+import static protobuf_unittest.UnittestProto.defaultBoolExtension;
+import static protobuf_unittest.UnittestProto.defaultStringExtension;
+import static protobuf_unittest.UnittestProto.defaultBytesExtension;
+import static protobuf_unittest.UnittestProto.defaultNestedEnumExtension;
+import static protobuf_unittest.UnittestProto.defaultForeignEnumExtension;
+import static protobuf_unittest.UnittestProto.defaultImportEnumExtension;
+import static protobuf_unittest.UnittestProto.defaultStringPieceExtension;
+import static protobuf_unittest.UnittestProto.defaultCordExtension;
+
+import static protobuf_unittest.UnittestProto.optionalInt32Extension;
+import static protobuf_unittest.UnittestProto.optionalInt64Extension;
+import static protobuf_unittest.UnittestProto.optionalUint32Extension;
+import static protobuf_unittest.UnittestProto.optionalUint64Extension;
+import static protobuf_unittest.UnittestProto.optionalSint32Extension;
+import static protobuf_unittest.UnittestProto.optionalSint64Extension;
+import static protobuf_unittest.UnittestProto.optionalFixed32Extension;
+import static protobuf_unittest.UnittestProto.optionalFixed64Extension;
+import static protobuf_unittest.UnittestProto.optionalSfixed32Extension;
+import static protobuf_unittest.UnittestProto.optionalSfixed64Extension;
+import static protobuf_unittest.UnittestProto.optionalFloatExtension;
+import static protobuf_unittest.UnittestProto.optionalDoubleExtension;
+import static protobuf_unittest.UnittestProto.optionalBoolExtension;
+import static protobuf_unittest.UnittestProto.optionalStringExtension;
+import static protobuf_unittest.UnittestProto.optionalBytesExtension;
+import static protobuf_unittest.UnittestProto.optionalGroupExtension;
+import static protobuf_unittest.UnittestProto.optionalCordExtension;
+import static protobuf_unittest.UnittestProto.optionalForeignEnumExtension;
+import static protobuf_unittest.UnittestProto.optionalForeignMessageExtension;
+import static protobuf_unittest.UnittestProto.optionalImportEnumExtension;
+import static protobuf_unittest.UnittestProto.optionalImportMessageExtension;
+import static protobuf_unittest.UnittestProto.optionalNestedEnumExtension;
+import static protobuf_unittest.UnittestProto.optionalNestedMessageExtension;
+import static protobuf_unittest.UnittestProto.optionalPublicImportMessageExtension;
+import static protobuf_unittest.UnittestProto.optionalLazyMessageExtension;
+import static protobuf_unittest.UnittestProto.optionalStringPieceExtension;
+
+import static protobuf_unittest.UnittestProto.repeatedInt32Extension;
+import static protobuf_unittest.UnittestProto.repeatedInt64Extension;
+import static protobuf_unittest.UnittestProto.repeatedUint32Extension;
+import static protobuf_unittest.UnittestProto.repeatedUint64Extension;
+import static protobuf_unittest.UnittestProto.repeatedSint32Extension;
+import static protobuf_unittest.UnittestProto.repeatedSint64Extension;
+import static protobuf_unittest.UnittestProto.repeatedFixed32Extension;
+import static protobuf_unittest.UnittestProto.repeatedFixed64Extension;
+import static protobuf_unittest.UnittestProto.repeatedSfixed32Extension;
+import static protobuf_unittest.UnittestProto.repeatedSfixed64Extension;
+import static protobuf_unittest.UnittestProto.repeatedFloatExtension;
+import static protobuf_unittest.UnittestProto.repeatedDoubleExtension;
+import static protobuf_unittest.UnittestProto.repeatedBoolExtension;
+import static protobuf_unittest.UnittestProto.repeatedStringExtension;
+import static protobuf_unittest.UnittestProto.repeatedBytesExtension;
+import static protobuf_unittest.UnittestProto.repeatedGroupExtension;
+import static protobuf_unittest.UnittestProto.repeatedNestedMessageExtension;
+import static protobuf_unittest.UnittestProto.repeatedForeignMessageExtension;
+import static protobuf_unittest.UnittestProto.repeatedImportMessageExtension;
+import static protobuf_unittest.UnittestProto.repeatedLazyMessageExtension;
+import static protobuf_unittest.UnittestProto.repeatedNestedEnumExtension;
+import static protobuf_unittest.UnittestProto.repeatedForeignEnumExtension;
+import static protobuf_unittest.UnittestProto.repeatedImportEnumExtension;
+import static protobuf_unittest.UnittestProto.repeatedStringPieceExtension;
+import static protobuf_unittest.UnittestProto.repeatedCordExtension;
+
+import static protobuf_unittest.UnittestProto.OptionalGroup_extension;
+import static protobuf_unittest.UnittestProto.RepeatedGroup_extension;
+
+import static protobuf_unittest.UnittestProto.packedInt32Extension;
+import static protobuf_unittest.UnittestProto.packedInt64Extension;
+import static protobuf_unittest.UnittestProto.packedUint32Extension;
+import static protobuf_unittest.UnittestProto.packedUint64Extension;
+import static protobuf_unittest.UnittestProto.packedSint32Extension;
+import static protobuf_unittest.UnittestProto.packedSint64Extension;
+import static protobuf_unittest.UnittestProto.packedFixed32Extension;
+import static protobuf_unittest.UnittestProto.packedFixed64Extension;
+import static protobuf_unittest.UnittestProto.packedSfixed32Extension;
+import static protobuf_unittest.UnittestProto.packedSfixed64Extension;
+import static protobuf_unittest.UnittestProto.packedFloatExtension;
+import static protobuf_unittest.UnittestProto.packedDoubleExtension;
+import static protobuf_unittest.UnittestProto.packedBoolExtension;
+import static protobuf_unittest.UnittestProto.packedEnumExtension;
+
+
+import protobuf_unittest.UnittestProto.TestAllExtensions;
+import protobuf_unittest.UnittestProto.TestAllExtensionsOrBuilder;
+import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestAllTypesOrBuilder;
+import protobuf_unittest.UnittestProto.TestPackedExtensions;
+import protobuf_unittest.UnittestProto.TestPackedTypes;
+import protobuf_unittest.UnittestProto.TestUnpackedTypes;
+import protobuf_unittest.UnittestProto.ForeignMessage;
+import protobuf_unittest.UnittestProto.ForeignEnum;
+import com.google.protobuf.test.UnittestImport.ImportEnum;
+import com.google.protobuf.test.UnittestImport.ImportMessage;
+import com.google.protobuf.test.UnittestImportPublic.PublicImportMessage;
+
+import junit.framework.Assert;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+
+/**
+ * Contains methods for setting all fields of {@code TestAllTypes} to
+ * some values as well as checking that all the fields are set to those values.
+ * These are useful for testing various protocol message features, e.g.
+ * set all fields of a message, serialize it, parse it, and check that all
+ * fields are set.
+ *
+ * <p>This code is not to be used outside of {@code com.google.protobuf} and
+ * subpackages.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public final class TestUtil {
+ private TestUtil() {}
+
+ /** Helper to convert a String to ByteString. */
+ static ByteString toBytes(String str) {
+ try {
+ return ByteString.copyFrom(str.getBytes("UTF-8"));
+ } catch(java.io.UnsupportedEncodingException e) {
+ throw new RuntimeException("UTF-8 not supported.", e);
+ }
+ }
+
+ /**
+ * Get a {@code TestAllTypes} with all fields set as they would be by
+ * {@link #setAllFields(TestAllTypes.Builder)}.
+ */
+ public static TestAllTypes getAllSet() {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ setAllFields(builder);
+ return builder.build();
+ }
+
+ /**
+ * Get a {@code TestAllTypes.Builder} with all fields set as they would be by
+ * {@link #setAllFields(TestAllTypes.Builder)}.
+ */
+ public static TestAllTypes.Builder getAllSetBuilder() {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ setAllFields(builder);
+ return builder;
+ }
+
+ /**
+ * Get a {@code TestAllExtensions} with all fields set as they would be by
+ * {@link #setAllExtensions(TestAllExtensions.Builder)}.
+ */
+ public static TestAllExtensions getAllExtensionsSet() {
+ TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
+ setAllExtensions(builder);
+ return builder.build();
+ }
+
+ public static TestPackedTypes getPackedSet() {
+ TestPackedTypes.Builder builder = TestPackedTypes.newBuilder();
+ setPackedFields(builder);
+ return builder.build();
+ }
+
+ public static TestUnpackedTypes getUnpackedSet() {
+ TestUnpackedTypes.Builder builder = TestUnpackedTypes.newBuilder();
+ setUnpackedFields(builder);
+ return builder.build();
+ }
+
+ public static TestPackedExtensions getPackedExtensionsSet() {
+ TestPackedExtensions.Builder builder = TestPackedExtensions.newBuilder();
+ setPackedExtensions(builder);
+ return builder.build();
+ }
+
+ /**
+ * Set every field of {@code message} to the values expected by
+ * {@code assertAllFieldsSet()}.
+ */
+ public static void setAllFields(TestAllTypes.Builder message) {
+ message.setOptionalInt32 (101);
+ message.setOptionalInt64 (102);
+ message.setOptionalUint32 (103);
+ message.setOptionalUint64 (104);
+ message.setOptionalSint32 (105);
+ message.setOptionalSint64 (106);
+ message.setOptionalFixed32 (107);
+ message.setOptionalFixed64 (108);
+ message.setOptionalSfixed32(109);
+ message.setOptionalSfixed64(110);
+ message.setOptionalFloat (111);
+ message.setOptionalDouble (112);
+ message.setOptionalBool (true);
+ message.setOptionalString ("115");
+ message.setOptionalBytes (toBytes("116"));
+
+ message.setOptionalGroup(
+ TestAllTypes.OptionalGroup.newBuilder().setA(117).build());
+ message.setOptionalNestedMessage(
+ TestAllTypes.NestedMessage.newBuilder().setBb(118).build());
+ message.setOptionalForeignMessage(
+ ForeignMessage.newBuilder().setC(119).build());
+ message.setOptionalImportMessage(
+ ImportMessage.newBuilder().setD(120).build());
+ message.setOptionalPublicImportMessage(
+ PublicImportMessage.newBuilder().setE(126).build());
+ message.setOptionalLazyMessage(
+ TestAllTypes.NestedMessage.newBuilder().setBb(127).build());
+
+ message.setOptionalNestedEnum (TestAllTypes.NestedEnum.BAZ);
+ message.setOptionalForeignEnum(ForeignEnum.FOREIGN_BAZ);
+ message.setOptionalImportEnum (ImportEnum.IMPORT_BAZ);
+
+ message.setOptionalStringPiece("124");
+ message.setOptionalCord("125");
+
+ // -----------------------------------------------------------------
+
+ message.addRepeatedInt32 (201);
+ message.addRepeatedInt64 (202);
+ message.addRepeatedUint32 (203);
+ message.addRepeatedUint64 (204);
+ message.addRepeatedSint32 (205);
+ message.addRepeatedSint64 (206);
+ message.addRepeatedFixed32 (207);
+ message.addRepeatedFixed64 (208);
+ message.addRepeatedSfixed32(209);
+ message.addRepeatedSfixed64(210);
+ message.addRepeatedFloat (211);
+ message.addRepeatedDouble (212);
+ message.addRepeatedBool (true);
+ message.addRepeatedString ("215");
+ message.addRepeatedBytes (toBytes("216"));
+
+ message.addRepeatedGroup(
+ TestAllTypes.RepeatedGroup.newBuilder().setA(217).build());
+ message.addRepeatedNestedMessage(
+ TestAllTypes.NestedMessage.newBuilder().setBb(218).build());
+ message.addRepeatedForeignMessage(
+ ForeignMessage.newBuilder().setC(219).build());
+ message.addRepeatedImportMessage(
+ ImportMessage.newBuilder().setD(220).build());
+ message.addRepeatedLazyMessage(
+ TestAllTypes.NestedMessage.newBuilder().setBb(227).build());
+
+ message.addRepeatedNestedEnum (TestAllTypes.NestedEnum.BAR);
+ message.addRepeatedForeignEnum(ForeignEnum.FOREIGN_BAR);
+ message.addRepeatedImportEnum (ImportEnum.IMPORT_BAR);
+
+ message.addRepeatedStringPiece("224");
+ message.addRepeatedCord("225");
+
+ // Add a second one of each field.
+ message.addRepeatedInt32 (301);
+ message.addRepeatedInt64 (302);
+ message.addRepeatedUint32 (303);
+ message.addRepeatedUint64 (304);
+ message.addRepeatedSint32 (305);
+ message.addRepeatedSint64 (306);
+ message.addRepeatedFixed32 (307);
+ message.addRepeatedFixed64 (308);
+ message.addRepeatedSfixed32(309);
+ message.addRepeatedSfixed64(310);
+ message.addRepeatedFloat (311);
+ message.addRepeatedDouble (312);
+ message.addRepeatedBool (false);
+ message.addRepeatedString ("315");
+ message.addRepeatedBytes (toBytes("316"));
+
+ message.addRepeatedGroup(
+ TestAllTypes.RepeatedGroup.newBuilder().setA(317).build());
+ message.addRepeatedNestedMessage(
+ TestAllTypes.NestedMessage.newBuilder().setBb(318).build());
+ message.addRepeatedForeignMessage(
+ ForeignMessage.newBuilder().setC(319).build());
+ message.addRepeatedImportMessage(
+ ImportMessage.newBuilder().setD(320).build());
+ message.addRepeatedLazyMessage(
+ TestAllTypes.NestedMessage.newBuilder().setBb(327).build());
+
+ message.addRepeatedNestedEnum (TestAllTypes.NestedEnum.BAZ);
+ message.addRepeatedForeignEnum(ForeignEnum.FOREIGN_BAZ);
+ message.addRepeatedImportEnum (ImportEnum.IMPORT_BAZ);
+
+ message.addRepeatedStringPiece("324");
+ message.addRepeatedCord("325");
+
+ // -----------------------------------------------------------------
+
+ message.setDefaultInt32 (401);
+ message.setDefaultInt64 (402);
+ message.setDefaultUint32 (403);
+ message.setDefaultUint64 (404);
+ message.setDefaultSint32 (405);
+ message.setDefaultSint64 (406);
+ message.setDefaultFixed32 (407);
+ message.setDefaultFixed64 (408);
+ message.setDefaultSfixed32(409);
+ message.setDefaultSfixed64(410);
+ message.setDefaultFloat (411);
+ message.setDefaultDouble (412);
+ message.setDefaultBool (false);
+ message.setDefaultString ("415");
+ message.setDefaultBytes (toBytes("416"));
+
+ message.setDefaultNestedEnum (TestAllTypes.NestedEnum.FOO);
+ message.setDefaultForeignEnum(ForeignEnum.FOREIGN_FOO);
+ message.setDefaultImportEnum (ImportEnum.IMPORT_FOO);
+
+ message.setDefaultStringPiece("424");
+ message.setDefaultCord("425");
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Modify the repeated fields of {@code message} to contain the values
+ * expected by {@code assertRepeatedFieldsModified()}.
+ */
+ public static void modifyRepeatedFields(TestAllTypes.Builder message) {
+ message.setRepeatedInt32 (1, 501);
+ message.setRepeatedInt64 (1, 502);
+ message.setRepeatedUint32 (1, 503);
+ message.setRepeatedUint64 (1, 504);
+ message.setRepeatedSint32 (1, 505);
+ message.setRepeatedSint64 (1, 506);
+ message.setRepeatedFixed32 (1, 507);
+ message.setRepeatedFixed64 (1, 508);
+ message.setRepeatedSfixed32(1, 509);
+ message.setRepeatedSfixed64(1, 510);
+ message.setRepeatedFloat (1, 511);
+ message.setRepeatedDouble (1, 512);
+ message.setRepeatedBool (1, true);
+ message.setRepeatedString (1, "515");
+ message.setRepeatedBytes (1, toBytes("516"));
+
+ message.setRepeatedGroup(1,
+ TestAllTypes.RepeatedGroup.newBuilder().setA(517).build());
+ message.setRepeatedNestedMessage(1,
+ TestAllTypes.NestedMessage.newBuilder().setBb(518).build());
+ message.setRepeatedForeignMessage(1,
+ ForeignMessage.newBuilder().setC(519).build());
+ message.setRepeatedImportMessage(1,
+ ImportMessage.newBuilder().setD(520).build());
+ message.setRepeatedLazyMessage(1,
+ TestAllTypes.NestedMessage.newBuilder().setBb(527).build());
+
+ message.setRepeatedNestedEnum (1, TestAllTypes.NestedEnum.FOO);
+ message.setRepeatedForeignEnum(1, ForeignEnum.FOREIGN_FOO);
+ message.setRepeatedImportEnum (1, ImportEnum.IMPORT_FOO);
+
+ message.setRepeatedStringPiece(1, "524");
+ message.setRepeatedCord(1, "525");
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Assert (using {@code junit.framework.Assert}} that all fields of
+ * {@code message} are set to the values assigned by {@code setAllFields}.
+ */
+ public static void assertAllFieldsSet(TestAllTypesOrBuilder message) {
+ Assert.assertTrue(message.hasOptionalInt32 ());
+ Assert.assertTrue(message.hasOptionalInt64 ());
+ Assert.assertTrue(message.hasOptionalUint32 ());
+ Assert.assertTrue(message.hasOptionalUint64 ());
+ Assert.assertTrue(message.hasOptionalSint32 ());
+ Assert.assertTrue(message.hasOptionalSint64 ());
+ Assert.assertTrue(message.hasOptionalFixed32 ());
+ Assert.assertTrue(message.hasOptionalFixed64 ());
+ Assert.assertTrue(message.hasOptionalSfixed32());
+ Assert.assertTrue(message.hasOptionalSfixed64());
+ Assert.assertTrue(message.hasOptionalFloat ());
+ Assert.assertTrue(message.hasOptionalDouble ());
+ Assert.assertTrue(message.hasOptionalBool ());
+ Assert.assertTrue(message.hasOptionalString ());
+ Assert.assertTrue(message.hasOptionalBytes ());
+
+ Assert.assertTrue(message.hasOptionalGroup ());
+ Assert.assertTrue(message.hasOptionalNestedMessage ());
+ Assert.assertTrue(message.hasOptionalForeignMessage());
+ Assert.assertTrue(message.hasOptionalImportMessage ());
+
+ Assert.assertTrue(message.getOptionalGroup ().hasA());
+ Assert.assertTrue(message.getOptionalNestedMessage ().hasBb());
+ Assert.assertTrue(message.getOptionalForeignMessage().hasC());
+ Assert.assertTrue(message.getOptionalImportMessage ().hasD());
+
+ Assert.assertTrue(message.hasOptionalNestedEnum ());
+ Assert.assertTrue(message.hasOptionalForeignEnum());
+ Assert.assertTrue(message.hasOptionalImportEnum ());
+
+ Assert.assertTrue(message.hasOptionalStringPiece());
+ Assert.assertTrue(message.hasOptionalCord());
+
+ Assert.assertEquals(101 , message.getOptionalInt32 ());
+ Assert.assertEquals(102 , message.getOptionalInt64 ());
+ Assert.assertEquals(103 , message.getOptionalUint32 ());
+ Assert.assertEquals(104 , message.getOptionalUint64 ());
+ Assert.assertEquals(105 , message.getOptionalSint32 ());
+ Assert.assertEquals(106 , message.getOptionalSint64 ());
+ Assert.assertEquals(107 , message.getOptionalFixed32 ());
+ Assert.assertEquals(108 , message.getOptionalFixed64 ());
+ Assert.assertEquals(109 , message.getOptionalSfixed32());
+ Assert.assertEquals(110 , message.getOptionalSfixed64());
+ Assert.assertEquals(111 , message.getOptionalFloat (), 0.0);
+ Assert.assertEquals(112 , message.getOptionalDouble (), 0.0);
+ Assert.assertEquals(true , message.getOptionalBool ());
+ Assert.assertEquals("115", message.getOptionalString ());
+ Assert.assertEquals(toBytes("116"), message.getOptionalBytes());
+
+ Assert.assertEquals(117, message.getOptionalGroup ().getA());
+ Assert.assertEquals(118, message.getOptionalNestedMessage ().getBb());
+ Assert.assertEquals(119, message.getOptionalForeignMessage ().getC());
+ Assert.assertEquals(120, message.getOptionalImportMessage ().getD());
+ Assert.assertEquals(126, message.getOptionalPublicImportMessage().getE());
+ Assert.assertEquals(127, message.getOptionalLazyMessage ().getBb());
+
+ Assert.assertEquals(TestAllTypes.NestedEnum.BAZ, message.getOptionalNestedEnum());
+ Assert.assertEquals(ForeignEnum.FOREIGN_BAZ, message.getOptionalForeignEnum());
+ Assert.assertEquals(ImportEnum.IMPORT_BAZ, message.getOptionalImportEnum());
+
+ Assert.assertEquals("124", message.getOptionalStringPiece());
+ Assert.assertEquals("125", message.getOptionalCord());
+
+ // -----------------------------------------------------------------
+
+ Assert.assertEquals(2, message.getRepeatedInt32Count ());
+ Assert.assertEquals(2, message.getRepeatedInt64Count ());
+ Assert.assertEquals(2, message.getRepeatedUint32Count ());
+ Assert.assertEquals(2, message.getRepeatedUint64Count ());
+ Assert.assertEquals(2, message.getRepeatedSint32Count ());
+ Assert.assertEquals(2, message.getRepeatedSint64Count ());
+ Assert.assertEquals(2, message.getRepeatedFixed32Count ());
+ Assert.assertEquals(2, message.getRepeatedFixed64Count ());
+ Assert.assertEquals(2, message.getRepeatedSfixed32Count());
+ Assert.assertEquals(2, message.getRepeatedSfixed64Count());
+ Assert.assertEquals(2, message.getRepeatedFloatCount ());
+ Assert.assertEquals(2, message.getRepeatedDoubleCount ());
+ Assert.assertEquals(2, message.getRepeatedBoolCount ());
+ Assert.assertEquals(2, message.getRepeatedStringCount ());
+ Assert.assertEquals(2, message.getRepeatedBytesCount ());
+
+ Assert.assertEquals(2, message.getRepeatedGroupCount ());
+ Assert.assertEquals(2, message.getRepeatedNestedMessageCount ());
+ Assert.assertEquals(2, message.getRepeatedForeignMessageCount());
+ Assert.assertEquals(2, message.getRepeatedImportMessageCount ());
+ Assert.assertEquals(2, message.getRepeatedLazyMessageCount ());
+ Assert.assertEquals(2, message.getRepeatedNestedEnumCount ());
+ Assert.assertEquals(2, message.getRepeatedForeignEnumCount ());
+ Assert.assertEquals(2, message.getRepeatedImportEnumCount ());
+
+ Assert.assertEquals(2, message.getRepeatedStringPieceCount());
+ Assert.assertEquals(2, message.getRepeatedCordCount());
+
+ Assert.assertEquals(201 , message.getRepeatedInt32 (0));
+ Assert.assertEquals(202 , message.getRepeatedInt64 (0));
+ Assert.assertEquals(203 , message.getRepeatedUint32 (0));
+ Assert.assertEquals(204 , message.getRepeatedUint64 (0));
+ Assert.assertEquals(205 , message.getRepeatedSint32 (0));
+ Assert.assertEquals(206 , message.getRepeatedSint64 (0));
+ Assert.assertEquals(207 , message.getRepeatedFixed32 (0));
+ Assert.assertEquals(208 , message.getRepeatedFixed64 (0));
+ Assert.assertEquals(209 , message.getRepeatedSfixed32(0));
+ Assert.assertEquals(210 , message.getRepeatedSfixed64(0));
+ Assert.assertEquals(211 , message.getRepeatedFloat (0), 0.0);
+ Assert.assertEquals(212 , message.getRepeatedDouble (0), 0.0);
+ Assert.assertEquals(true , message.getRepeatedBool (0));
+ Assert.assertEquals("215", message.getRepeatedString (0));
+ Assert.assertEquals(toBytes("216"), message.getRepeatedBytes(0));
+
+ Assert.assertEquals(217, message.getRepeatedGroup (0).getA());
+ Assert.assertEquals(218, message.getRepeatedNestedMessage (0).getBb());
+ Assert.assertEquals(219, message.getRepeatedForeignMessage(0).getC());
+ Assert.assertEquals(220, message.getRepeatedImportMessage (0).getD());
+ Assert.assertEquals(227, message.getRepeatedLazyMessage (0).getBb());
+
+ Assert.assertEquals(TestAllTypes.NestedEnum.BAR, message.getRepeatedNestedEnum (0));
+ Assert.assertEquals(ForeignEnum.FOREIGN_BAR, message.getRepeatedForeignEnum(0));
+ Assert.assertEquals(ImportEnum.IMPORT_BAR, message.getRepeatedImportEnum(0));
+
+ Assert.assertEquals("224", message.getRepeatedStringPiece(0));
+ Assert.assertEquals("225", message.getRepeatedCord(0));
+
+ Assert.assertEquals(301 , message.getRepeatedInt32 (1));
+ Assert.assertEquals(302 , message.getRepeatedInt64 (1));
+ Assert.assertEquals(303 , message.getRepeatedUint32 (1));
+ Assert.assertEquals(304 , message.getRepeatedUint64 (1));
+ Assert.assertEquals(305 , message.getRepeatedSint32 (1));
+ Assert.assertEquals(306 , message.getRepeatedSint64 (1));
+ Assert.assertEquals(307 , message.getRepeatedFixed32 (1));
+ Assert.assertEquals(308 , message.getRepeatedFixed64 (1));
+ Assert.assertEquals(309 , message.getRepeatedSfixed32(1));
+ Assert.assertEquals(310 , message.getRepeatedSfixed64(1));
+ Assert.assertEquals(311 , message.getRepeatedFloat (1), 0.0);
+ Assert.assertEquals(312 , message.getRepeatedDouble (1), 0.0);
+ Assert.assertEquals(false, message.getRepeatedBool (1));
+ Assert.assertEquals("315", message.getRepeatedString (1));
+ Assert.assertEquals(toBytes("316"), message.getRepeatedBytes(1));
+
+ Assert.assertEquals(317, message.getRepeatedGroup (1).getA());
+ Assert.assertEquals(318, message.getRepeatedNestedMessage (1).getBb());
+ Assert.assertEquals(319, message.getRepeatedForeignMessage(1).getC());
+ Assert.assertEquals(320, message.getRepeatedImportMessage (1).getD());
+ Assert.assertEquals(327, message.getRepeatedLazyMessage (1).getBb());
+
+ Assert.assertEquals(TestAllTypes.NestedEnum.BAZ, message.getRepeatedNestedEnum (1));
+ Assert.assertEquals(ForeignEnum.FOREIGN_BAZ, message.getRepeatedForeignEnum(1));
+ Assert.assertEquals(ImportEnum.IMPORT_BAZ, message.getRepeatedImportEnum(1));
+
+ Assert.assertEquals("324", message.getRepeatedStringPiece(1));
+ Assert.assertEquals("325", message.getRepeatedCord(1));
+
+ // -----------------------------------------------------------------
+
+ Assert.assertTrue(message.hasDefaultInt32 ());
+ Assert.assertTrue(message.hasDefaultInt64 ());
+ Assert.assertTrue(message.hasDefaultUint32 ());
+ Assert.assertTrue(message.hasDefaultUint64 ());
+ Assert.assertTrue(message.hasDefaultSint32 ());
+ Assert.assertTrue(message.hasDefaultSint64 ());
+ Assert.assertTrue(message.hasDefaultFixed32 ());
+ Assert.assertTrue(message.hasDefaultFixed64 ());
+ Assert.assertTrue(message.hasDefaultSfixed32());
+ Assert.assertTrue(message.hasDefaultSfixed64());
+ Assert.assertTrue(message.hasDefaultFloat ());
+ Assert.assertTrue(message.hasDefaultDouble ());
+ Assert.assertTrue(message.hasDefaultBool ());
+ Assert.assertTrue(message.hasDefaultString ());
+ Assert.assertTrue(message.hasDefaultBytes ());
+
+ Assert.assertTrue(message.hasDefaultNestedEnum ());
+ Assert.assertTrue(message.hasDefaultForeignEnum());
+ Assert.assertTrue(message.hasDefaultImportEnum ());
+
+ Assert.assertTrue(message.hasDefaultStringPiece());
+ Assert.assertTrue(message.hasDefaultCord());
+
+ Assert.assertEquals(401 , message.getDefaultInt32 ());
+ Assert.assertEquals(402 , message.getDefaultInt64 ());
+ Assert.assertEquals(403 , message.getDefaultUint32 ());
+ Assert.assertEquals(404 , message.getDefaultUint64 ());
+ Assert.assertEquals(405 , message.getDefaultSint32 ());
+ Assert.assertEquals(406 , message.getDefaultSint64 ());
+ Assert.assertEquals(407 , message.getDefaultFixed32 ());
+ Assert.assertEquals(408 , message.getDefaultFixed64 ());
+ Assert.assertEquals(409 , message.getDefaultSfixed32());
+ Assert.assertEquals(410 , message.getDefaultSfixed64());
+ Assert.assertEquals(411 , message.getDefaultFloat (), 0.0);
+ Assert.assertEquals(412 , message.getDefaultDouble (), 0.0);
+ Assert.assertEquals(false, message.getDefaultBool ());
+ Assert.assertEquals("415", message.getDefaultString ());
+ Assert.assertEquals(toBytes("416"), message.getDefaultBytes());
+
+ Assert.assertEquals(TestAllTypes.NestedEnum.FOO, message.getDefaultNestedEnum ());
+ Assert.assertEquals(ForeignEnum.FOREIGN_FOO, message.getDefaultForeignEnum());
+ Assert.assertEquals(ImportEnum.IMPORT_FOO, message.getDefaultImportEnum());
+
+ Assert.assertEquals("424", message.getDefaultStringPiece());
+ Assert.assertEquals("425", message.getDefaultCord());
+ }
+
+ // -------------------------------------------------------------------
+ /**
+ * Assert (using {@code junit.framework.Assert}} that all fields of
+ * {@code message} are cleared, and that getting the fields returns their
+ * default values.
+ */
+ public static void assertClear(TestAllTypesOrBuilder message) {
+ // hasBlah() should initially be false for all optional fields.
+ Assert.assertFalse(message.hasOptionalInt32 ());
+ Assert.assertFalse(message.hasOptionalInt64 ());
+ Assert.assertFalse(message.hasOptionalUint32 ());
+ Assert.assertFalse(message.hasOptionalUint64 ());
+ Assert.assertFalse(message.hasOptionalSint32 ());
+ Assert.assertFalse(message.hasOptionalSint64 ());
+ Assert.assertFalse(message.hasOptionalFixed32 ());
+ Assert.assertFalse(message.hasOptionalFixed64 ());
+ Assert.assertFalse(message.hasOptionalSfixed32());
+ Assert.assertFalse(message.hasOptionalSfixed64());
+ Assert.assertFalse(message.hasOptionalFloat ());
+ Assert.assertFalse(message.hasOptionalDouble ());
+ Assert.assertFalse(message.hasOptionalBool ());
+ Assert.assertFalse(message.hasOptionalString ());
+ Assert.assertFalse(message.hasOptionalBytes ());
+
+ Assert.assertFalse(message.hasOptionalGroup ());
+ Assert.assertFalse(message.hasOptionalNestedMessage ());
+ Assert.assertFalse(message.hasOptionalForeignMessage());
+ Assert.assertFalse(message.hasOptionalImportMessage ());
+
+ Assert.assertFalse(message.hasOptionalNestedEnum ());
+ Assert.assertFalse(message.hasOptionalForeignEnum());
+ Assert.assertFalse(message.hasOptionalImportEnum ());
+
+ Assert.assertFalse(message.hasOptionalStringPiece());
+ Assert.assertFalse(message.hasOptionalCord());
+
+ // Optional fields without defaults are set to zero or something like it.
+ Assert.assertEquals(0 , message.getOptionalInt32 ());
+ Assert.assertEquals(0 , message.getOptionalInt64 ());
+ Assert.assertEquals(0 , message.getOptionalUint32 ());
+ Assert.assertEquals(0 , message.getOptionalUint64 ());
+ Assert.assertEquals(0 , message.getOptionalSint32 ());
+ Assert.assertEquals(0 , message.getOptionalSint64 ());
+ Assert.assertEquals(0 , message.getOptionalFixed32 ());
+ Assert.assertEquals(0 , message.getOptionalFixed64 ());
+ Assert.assertEquals(0 , message.getOptionalSfixed32());
+ Assert.assertEquals(0 , message.getOptionalSfixed64());
+ Assert.assertEquals(0 , message.getOptionalFloat (), 0.0);
+ Assert.assertEquals(0 , message.getOptionalDouble (), 0.0);
+ Assert.assertEquals(false, message.getOptionalBool ());
+ Assert.assertEquals("" , message.getOptionalString ());
+ Assert.assertEquals(ByteString.EMPTY, message.getOptionalBytes());
+
+ // Embedded messages should also be clear.
+ Assert.assertFalse(message.getOptionalGroup ().hasA());
+ Assert.assertFalse(message.getOptionalNestedMessage ().hasBb());
+ Assert.assertFalse(message.getOptionalForeignMessage ().hasC());
+ Assert.assertFalse(message.getOptionalImportMessage ().hasD());
+ Assert.assertFalse(message.getOptionalPublicImportMessage().hasE());
+ Assert.assertFalse(message.getOptionalLazyMessage ().hasBb());
+
+ Assert.assertEquals(0, message.getOptionalGroup ().getA());
+ Assert.assertEquals(0, message.getOptionalNestedMessage ().getBb());
+ Assert.assertEquals(0, message.getOptionalForeignMessage ().getC());
+ Assert.assertEquals(0, message.getOptionalImportMessage ().getD());
+ Assert.assertEquals(0, message.getOptionalPublicImportMessage().getE());
+ Assert.assertEquals(0, message.getOptionalLazyMessage ().getBb());
+
+ // Enums without defaults are set to the first value in the enum.
+ Assert.assertEquals(TestAllTypes.NestedEnum.FOO, message.getOptionalNestedEnum ());
+ Assert.assertEquals(ForeignEnum.FOREIGN_FOO, message.getOptionalForeignEnum());
+ Assert.assertEquals(ImportEnum.IMPORT_FOO, message.getOptionalImportEnum());
+
+ Assert.assertEquals("", message.getOptionalStringPiece());
+ Assert.assertEquals("", message.getOptionalCord());
+
+ // Repeated fields are empty.
+ Assert.assertEquals(0, message.getRepeatedInt32Count ());
+ Assert.assertEquals(0, message.getRepeatedInt64Count ());
+ Assert.assertEquals(0, message.getRepeatedUint32Count ());
+ Assert.assertEquals(0, message.getRepeatedUint64Count ());
+ Assert.assertEquals(0, message.getRepeatedSint32Count ());
+ Assert.assertEquals(0, message.getRepeatedSint64Count ());
+ Assert.assertEquals(0, message.getRepeatedFixed32Count ());
+ Assert.assertEquals(0, message.getRepeatedFixed64Count ());
+ Assert.assertEquals(0, message.getRepeatedSfixed32Count());
+ Assert.assertEquals(0, message.getRepeatedSfixed64Count());
+ Assert.assertEquals(0, message.getRepeatedFloatCount ());
+ Assert.assertEquals(0, message.getRepeatedDoubleCount ());
+ Assert.assertEquals(0, message.getRepeatedBoolCount ());
+ Assert.assertEquals(0, message.getRepeatedStringCount ());
+ Assert.assertEquals(0, message.getRepeatedBytesCount ());
+
+ Assert.assertEquals(0, message.getRepeatedGroupCount ());
+ Assert.assertEquals(0, message.getRepeatedNestedMessageCount ());
+ Assert.assertEquals(0, message.getRepeatedForeignMessageCount());
+ Assert.assertEquals(0, message.getRepeatedImportMessageCount ());
+ Assert.assertEquals(0, message.getRepeatedLazyMessageCount ());
+ Assert.assertEquals(0, message.getRepeatedNestedEnumCount ());
+ Assert.assertEquals(0, message.getRepeatedForeignEnumCount ());
+ Assert.assertEquals(0, message.getRepeatedImportEnumCount ());
+
+ Assert.assertEquals(0, message.getRepeatedStringPieceCount());
+ Assert.assertEquals(0, message.getRepeatedCordCount());
+
+ // hasBlah() should also be false for all default fields.
+ Assert.assertFalse(message.hasDefaultInt32 ());
+ Assert.assertFalse(message.hasDefaultInt64 ());
+ Assert.assertFalse(message.hasDefaultUint32 ());
+ Assert.assertFalse(message.hasDefaultUint64 ());
+ Assert.assertFalse(message.hasDefaultSint32 ());
+ Assert.assertFalse(message.hasDefaultSint64 ());
+ Assert.assertFalse(message.hasDefaultFixed32 ());
+ Assert.assertFalse(message.hasDefaultFixed64 ());
+ Assert.assertFalse(message.hasDefaultSfixed32());
+ Assert.assertFalse(message.hasDefaultSfixed64());
+ Assert.assertFalse(message.hasDefaultFloat ());
+ Assert.assertFalse(message.hasDefaultDouble ());
+ Assert.assertFalse(message.hasDefaultBool ());
+ Assert.assertFalse(message.hasDefaultString ());
+ Assert.assertFalse(message.hasDefaultBytes ());
+
+ Assert.assertFalse(message.hasDefaultNestedEnum ());
+ Assert.assertFalse(message.hasDefaultForeignEnum());
+ Assert.assertFalse(message.hasDefaultImportEnum ());
+
+ Assert.assertFalse(message.hasDefaultStringPiece());
+ Assert.assertFalse(message.hasDefaultCord());
+
+ // Fields with defaults have their default values (duh).
+ Assert.assertEquals( 41 , message.getDefaultInt32 ());
+ Assert.assertEquals( 42 , message.getDefaultInt64 ());
+ Assert.assertEquals( 43 , message.getDefaultUint32 ());
+ Assert.assertEquals( 44 , message.getDefaultUint64 ());
+ Assert.assertEquals(-45 , message.getDefaultSint32 ());
+ Assert.assertEquals( 46 , message.getDefaultSint64 ());
+ Assert.assertEquals( 47 , message.getDefaultFixed32 ());
+ Assert.assertEquals( 48 , message.getDefaultFixed64 ());
+ Assert.assertEquals( 49 , message.getDefaultSfixed32());
+ Assert.assertEquals(-50 , message.getDefaultSfixed64());
+ Assert.assertEquals( 51.5 , message.getDefaultFloat (), 0.0);
+ Assert.assertEquals( 52e3 , message.getDefaultDouble (), 0.0);
+ Assert.assertEquals(true , message.getDefaultBool ());
+ Assert.assertEquals("hello", message.getDefaultString ());
+ Assert.assertEquals(toBytes("world"), message.getDefaultBytes());
+
+ Assert.assertEquals(TestAllTypes.NestedEnum.BAR, message.getDefaultNestedEnum ());
+ Assert.assertEquals(ForeignEnum.FOREIGN_BAR, message.getDefaultForeignEnum());
+ Assert.assertEquals(ImportEnum.IMPORT_BAR, message.getDefaultImportEnum());
+
+ Assert.assertEquals("abc", message.getDefaultStringPiece());
+ Assert.assertEquals("123", message.getDefaultCord());
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Assert (using {@code junit.framework.Assert}} that all fields of
+ * {@code message} are set to the values assigned by {@code setAllFields}
+ * followed by {@code modifyRepeatedFields}.
+ */
+ public static void assertRepeatedFieldsModified(
+ TestAllTypesOrBuilder message) {
+ // ModifyRepeatedFields only sets the second repeated element of each
+ // field. In addition to verifying this, we also verify that the first
+ // element and size were *not* modified.
+ Assert.assertEquals(2, message.getRepeatedInt32Count ());
+ Assert.assertEquals(2, message.getRepeatedInt64Count ());
+ Assert.assertEquals(2, message.getRepeatedUint32Count ());
+ Assert.assertEquals(2, message.getRepeatedUint64Count ());
+ Assert.assertEquals(2, message.getRepeatedSint32Count ());
+ Assert.assertEquals(2, message.getRepeatedSint64Count ());
+ Assert.assertEquals(2, message.getRepeatedFixed32Count ());
+ Assert.assertEquals(2, message.getRepeatedFixed64Count ());
+ Assert.assertEquals(2, message.getRepeatedSfixed32Count());
+ Assert.assertEquals(2, message.getRepeatedSfixed64Count());
+ Assert.assertEquals(2, message.getRepeatedFloatCount ());
+ Assert.assertEquals(2, message.getRepeatedDoubleCount ());
+ Assert.assertEquals(2, message.getRepeatedBoolCount ());
+ Assert.assertEquals(2, message.getRepeatedStringCount ());
+ Assert.assertEquals(2, message.getRepeatedBytesCount ());
+
+ Assert.assertEquals(2, message.getRepeatedGroupCount ());
+ Assert.assertEquals(2, message.getRepeatedNestedMessageCount ());
+ Assert.assertEquals(2, message.getRepeatedForeignMessageCount());
+ Assert.assertEquals(2, message.getRepeatedImportMessageCount ());
+ Assert.assertEquals(2, message.getRepeatedLazyMessageCount ());
+ Assert.assertEquals(2, message.getRepeatedNestedEnumCount ());
+ Assert.assertEquals(2, message.getRepeatedForeignEnumCount ());
+ Assert.assertEquals(2, message.getRepeatedImportEnumCount ());
+
+ Assert.assertEquals(2, message.getRepeatedStringPieceCount());
+ Assert.assertEquals(2, message.getRepeatedCordCount());
+
+ Assert.assertEquals(201 , message.getRepeatedInt32 (0));
+ Assert.assertEquals(202L , message.getRepeatedInt64 (0));
+ Assert.assertEquals(203 , message.getRepeatedUint32 (0));
+ Assert.assertEquals(204L , message.getRepeatedUint64 (0));
+ Assert.assertEquals(205 , message.getRepeatedSint32 (0));
+ Assert.assertEquals(206L , message.getRepeatedSint64 (0));
+ Assert.assertEquals(207 , message.getRepeatedFixed32 (0));
+ Assert.assertEquals(208L , message.getRepeatedFixed64 (0));
+ Assert.assertEquals(209 , message.getRepeatedSfixed32(0));
+ Assert.assertEquals(210L , message.getRepeatedSfixed64(0));
+ Assert.assertEquals(211F , message.getRepeatedFloat (0));
+ Assert.assertEquals(212D , message.getRepeatedDouble (0));
+ Assert.assertEquals(true , message.getRepeatedBool (0));
+ Assert.assertEquals("215", message.getRepeatedString (0));
+ Assert.assertEquals(toBytes("216"), message.getRepeatedBytes(0));
+
+ Assert.assertEquals(217, message.getRepeatedGroup (0).getA());
+ Assert.assertEquals(218, message.getRepeatedNestedMessage (0).getBb());
+ Assert.assertEquals(219, message.getRepeatedForeignMessage(0).getC());
+ Assert.assertEquals(220, message.getRepeatedImportMessage (0).getD());
+ Assert.assertEquals(227, message.getRepeatedLazyMessage (0).getBb());
+
+ Assert.assertEquals(TestAllTypes.NestedEnum.BAR, message.getRepeatedNestedEnum (0));
+ Assert.assertEquals(ForeignEnum.FOREIGN_BAR, message.getRepeatedForeignEnum(0));
+ Assert.assertEquals(ImportEnum.IMPORT_BAR, message.getRepeatedImportEnum(0));
+
+ Assert.assertEquals("224", message.getRepeatedStringPiece(0));
+ Assert.assertEquals("225", message.getRepeatedCord(0));
+
+ // Actually verify the second (modified) elements now.
+ Assert.assertEquals(501 , message.getRepeatedInt32 (1));
+ Assert.assertEquals(502L , message.getRepeatedInt64 (1));
+ Assert.assertEquals(503 , message.getRepeatedUint32 (1));
+ Assert.assertEquals(504L , message.getRepeatedUint64 (1));
+ Assert.assertEquals(505 , message.getRepeatedSint32 (1));
+ Assert.assertEquals(506L , message.getRepeatedSint64 (1));
+ Assert.assertEquals(507 , message.getRepeatedFixed32 (1));
+ Assert.assertEquals(508L , message.getRepeatedFixed64 (1));
+ Assert.assertEquals(509 , message.getRepeatedSfixed32(1));
+ Assert.assertEquals(510L , message.getRepeatedSfixed64(1));
+ Assert.assertEquals(511F , message.getRepeatedFloat (1));
+ Assert.assertEquals(512D , message.getRepeatedDouble (1));
+ Assert.assertEquals(true , message.getRepeatedBool (1));
+ Assert.assertEquals("515", message.getRepeatedString (1));
+ Assert.assertEquals(toBytes("516"), message.getRepeatedBytes(1));
+
+ Assert.assertEquals(517, message.getRepeatedGroup (1).getA());
+ Assert.assertEquals(518, message.getRepeatedNestedMessage (1).getBb());
+ Assert.assertEquals(519, message.getRepeatedForeignMessage(1).getC());
+ Assert.assertEquals(520, message.getRepeatedImportMessage (1).getD());
+ Assert.assertEquals(527, message.getRepeatedLazyMessage (1).getBb());
+
+ Assert.assertEquals(TestAllTypes.NestedEnum.FOO, message.getRepeatedNestedEnum (1));
+ Assert.assertEquals(ForeignEnum.FOREIGN_FOO, message.getRepeatedForeignEnum(1));
+ Assert.assertEquals(ImportEnum.IMPORT_FOO, message.getRepeatedImportEnum(1));
+
+ Assert.assertEquals("524", message.getRepeatedStringPiece(1));
+ Assert.assertEquals("525", message.getRepeatedCord(1));
+ }
+
+ /**
+ * Set every field of {@code message} to a unique value.
+ */
+ public static void setPackedFields(TestPackedTypes.Builder message) {
+ message.addPackedInt32 (601);
+ message.addPackedInt64 (602);
+ message.addPackedUint32 (603);
+ message.addPackedUint64 (604);
+ message.addPackedSint32 (605);
+ message.addPackedSint64 (606);
+ message.addPackedFixed32 (607);
+ message.addPackedFixed64 (608);
+ message.addPackedSfixed32(609);
+ message.addPackedSfixed64(610);
+ message.addPackedFloat (611);
+ message.addPackedDouble (612);
+ message.addPackedBool (true);
+ message.addPackedEnum (ForeignEnum.FOREIGN_BAR);
+ // Add a second one of each field.
+ message.addPackedInt32 (701);
+ message.addPackedInt64 (702);
+ message.addPackedUint32 (703);
+ message.addPackedUint64 (704);
+ message.addPackedSint32 (705);
+ message.addPackedSint64 (706);
+ message.addPackedFixed32 (707);
+ message.addPackedFixed64 (708);
+ message.addPackedSfixed32(709);
+ message.addPackedSfixed64(710);
+ message.addPackedFloat (711);
+ message.addPackedDouble (712);
+ message.addPackedBool (false);
+ message.addPackedEnum (ForeignEnum.FOREIGN_BAZ);
+ }
+
+ /**
+ * Set every field of {@code message} to a unique value. Must correspond with
+ * the values applied by {@code setPackedFields}.
+ */
+ public static void setUnpackedFields(TestUnpackedTypes.Builder message) {
+ message.addUnpackedInt32 (601);
+ message.addUnpackedInt64 (602);
+ message.addUnpackedUint32 (603);
+ message.addUnpackedUint64 (604);
+ message.addUnpackedSint32 (605);
+ message.addUnpackedSint64 (606);
+ message.addUnpackedFixed32 (607);
+ message.addUnpackedFixed64 (608);
+ message.addUnpackedSfixed32(609);
+ message.addUnpackedSfixed64(610);
+ message.addUnpackedFloat (611);
+ message.addUnpackedDouble (612);
+ message.addUnpackedBool (true);
+ message.addUnpackedEnum (ForeignEnum.FOREIGN_BAR);
+ // Add a second one of each field.
+ message.addUnpackedInt32 (701);
+ message.addUnpackedInt64 (702);
+ message.addUnpackedUint32 (703);
+ message.addUnpackedUint64 (704);
+ message.addUnpackedSint32 (705);
+ message.addUnpackedSint64 (706);
+ message.addUnpackedFixed32 (707);
+ message.addUnpackedFixed64 (708);
+ message.addUnpackedSfixed32(709);
+ message.addUnpackedSfixed64(710);
+ message.addUnpackedFloat (711);
+ message.addUnpackedDouble (712);
+ message.addUnpackedBool (false);
+ message.addUnpackedEnum (ForeignEnum.FOREIGN_BAZ);
+ }
+
+ /**
+ * Assert (using {@code junit.framework.Assert}} that all fields of
+ * {@code message} are set to the values assigned by {@code setPackedFields}.
+ */
+ public static void assertPackedFieldsSet(TestPackedTypes message) {
+ Assert.assertEquals(2, message.getPackedInt32Count ());
+ Assert.assertEquals(2, message.getPackedInt64Count ());
+ Assert.assertEquals(2, message.getPackedUint32Count ());
+ Assert.assertEquals(2, message.getPackedUint64Count ());
+ Assert.assertEquals(2, message.getPackedSint32Count ());
+ Assert.assertEquals(2, message.getPackedSint64Count ());
+ Assert.assertEquals(2, message.getPackedFixed32Count ());
+ Assert.assertEquals(2, message.getPackedFixed64Count ());
+ Assert.assertEquals(2, message.getPackedSfixed32Count());
+ Assert.assertEquals(2, message.getPackedSfixed64Count());
+ Assert.assertEquals(2, message.getPackedFloatCount ());
+ Assert.assertEquals(2, message.getPackedDoubleCount ());
+ Assert.assertEquals(2, message.getPackedBoolCount ());
+ Assert.assertEquals(2, message.getPackedEnumCount ());
+ Assert.assertEquals(601 , message.getPackedInt32 (0));
+ Assert.assertEquals(602 , message.getPackedInt64 (0));
+ Assert.assertEquals(603 , message.getPackedUint32 (0));
+ Assert.assertEquals(604 , message.getPackedUint64 (0));
+ Assert.assertEquals(605 , message.getPackedSint32 (0));
+ Assert.assertEquals(606 , message.getPackedSint64 (0));
+ Assert.assertEquals(607 , message.getPackedFixed32 (0));
+ Assert.assertEquals(608 , message.getPackedFixed64 (0));
+ Assert.assertEquals(609 , message.getPackedSfixed32(0));
+ Assert.assertEquals(610 , message.getPackedSfixed64(0));
+ Assert.assertEquals(611 , message.getPackedFloat (0), 0.0);
+ Assert.assertEquals(612 , message.getPackedDouble (0), 0.0);
+ Assert.assertEquals(true , message.getPackedBool (0));
+ Assert.assertEquals(ForeignEnum.FOREIGN_BAR, message.getPackedEnum(0));
+ Assert.assertEquals(701 , message.getPackedInt32 (1));
+ Assert.assertEquals(702 , message.getPackedInt64 (1));
+ Assert.assertEquals(703 , message.getPackedUint32 (1));
+ Assert.assertEquals(704 , message.getPackedUint64 (1));
+ Assert.assertEquals(705 , message.getPackedSint32 (1));
+ Assert.assertEquals(706 , message.getPackedSint64 (1));
+ Assert.assertEquals(707 , message.getPackedFixed32 (1));
+ Assert.assertEquals(708 , message.getPackedFixed64 (1));
+ Assert.assertEquals(709 , message.getPackedSfixed32(1));
+ Assert.assertEquals(710 , message.getPackedSfixed64(1));
+ Assert.assertEquals(711 , message.getPackedFloat (1), 0.0);
+ Assert.assertEquals(712 , message.getPackedDouble (1), 0.0);
+ Assert.assertEquals(false, message.getPackedBool (1));
+ Assert.assertEquals(ForeignEnum.FOREIGN_BAZ, message.getPackedEnum(1));
+ }
+
+ /**
+ * Assert (using {@code junit.framework.Assert}} that all fields of
+ * {@code message} are set to the values assigned by {@code setUnpackedFields}.
+ */
+ public static void assertUnpackedFieldsSet(TestUnpackedTypes message) {
+ Assert.assertEquals(2, message.getUnpackedInt32Count ());
+ Assert.assertEquals(2, message.getUnpackedInt64Count ());
+ Assert.assertEquals(2, message.getUnpackedUint32Count ());
+ Assert.assertEquals(2, message.getUnpackedUint64Count ());
+ Assert.assertEquals(2, message.getUnpackedSint32Count ());
+ Assert.assertEquals(2, message.getUnpackedSint64Count ());
+ Assert.assertEquals(2, message.getUnpackedFixed32Count ());
+ Assert.assertEquals(2, message.getUnpackedFixed64Count ());
+ Assert.assertEquals(2, message.getUnpackedSfixed32Count());
+ Assert.assertEquals(2, message.getUnpackedSfixed64Count());
+ Assert.assertEquals(2, message.getUnpackedFloatCount ());
+ Assert.assertEquals(2, message.getUnpackedDoubleCount ());
+ Assert.assertEquals(2, message.getUnpackedBoolCount ());
+ Assert.assertEquals(2, message.getUnpackedEnumCount ());
+ Assert.assertEquals(601 , message.getUnpackedInt32 (0));
+ Assert.assertEquals(602 , message.getUnpackedInt64 (0));
+ Assert.assertEquals(603 , message.getUnpackedUint32 (0));
+ Assert.assertEquals(604 , message.getUnpackedUint64 (0));
+ Assert.assertEquals(605 , message.getUnpackedSint32 (0));
+ Assert.assertEquals(606 , message.getUnpackedSint64 (0));
+ Assert.assertEquals(607 , message.getUnpackedFixed32 (0));
+ Assert.assertEquals(608 , message.getUnpackedFixed64 (0));
+ Assert.assertEquals(609 , message.getUnpackedSfixed32(0));
+ Assert.assertEquals(610 , message.getUnpackedSfixed64(0));
+ Assert.assertEquals(611 , message.getUnpackedFloat (0), 0.0);
+ Assert.assertEquals(612 , message.getUnpackedDouble (0), 0.0);
+ Assert.assertEquals(true , message.getUnpackedBool (0));
+ Assert.assertEquals(ForeignEnum.FOREIGN_BAR, message.getUnpackedEnum(0));
+ Assert.assertEquals(701 , message.getUnpackedInt32 (1));
+ Assert.assertEquals(702 , message.getUnpackedInt64 (1));
+ Assert.assertEquals(703 , message.getUnpackedUint32 (1));
+ Assert.assertEquals(704 , message.getUnpackedUint64 (1));
+ Assert.assertEquals(705 , message.getUnpackedSint32 (1));
+ Assert.assertEquals(706 , message.getUnpackedSint64 (1));
+ Assert.assertEquals(707 , message.getUnpackedFixed32 (1));
+ Assert.assertEquals(708 , message.getUnpackedFixed64 (1));
+ Assert.assertEquals(709 , message.getUnpackedSfixed32(1));
+ Assert.assertEquals(710 , message.getUnpackedSfixed64(1));
+ Assert.assertEquals(711 , message.getUnpackedFloat (1), 0.0);
+ Assert.assertEquals(712 , message.getUnpackedDouble (1), 0.0);
+ Assert.assertEquals(false, message.getUnpackedBool (1));
+ Assert.assertEquals(ForeignEnum.FOREIGN_BAZ, message.getUnpackedEnum(1));
+ }
+
+ // ===================================================================
+ // Like above, but for extensions
+
+ // Java gets confused with things like assertEquals(int, Integer): it can't
+ // decide whether to call assertEquals(int, int) or assertEquals(Object,
+ // Object). So we define these methods to help it.
+ private static void assertEqualsExactType(int a, int b) {
+ Assert.assertEquals(a, b);
+ }
+ private static void assertEqualsExactType(long a, long b) {
+ Assert.assertEquals(a, b);
+ }
+ private static void assertEqualsExactType(float a, float b) {
+ Assert.assertEquals(a, b, 0.0);
+ }
+ private static void assertEqualsExactType(double a, double b) {
+ Assert.assertEquals(a, b, 0.0);
+ }
+ private static void assertEqualsExactType(boolean a, boolean b) {
+ Assert.assertEquals(a, b);
+ }
+ private static void assertEqualsExactType(String a, String b) {
+ Assert.assertEquals(a, b);
+ }
+ private static void assertEqualsExactType(ByteString a, ByteString b) {
+ Assert.assertEquals(a, b);
+ }
+ private static void assertEqualsExactType(TestAllTypes.NestedEnum a,
+ TestAllTypes.NestedEnum b) {
+ Assert.assertEquals(a, b);
+ }
+ private static void assertEqualsExactType(ForeignEnum a, ForeignEnum b) {
+ Assert.assertEquals(a, b);
+ }
+ private static void assertEqualsExactType(ImportEnum a, ImportEnum b) {
+ Assert.assertEquals(a, b);
+ }
+ /**
+ * Get an unmodifiable {@link ExtensionRegistry} containing all the
+ * extensions of {@code TestAllExtensions}.
+ */
+ public static ExtensionRegistry getExtensionRegistry() {
+ ExtensionRegistry registry = ExtensionRegistry.newInstance();
+ registerAllExtensions(registry);
+ return registry.getUnmodifiable();
+ }
+
+
+ /**
+ * Register all of {@code TestAllExtensions}'s extensions with the
+ * given {@link ExtensionRegistry}.
+ */
+ public static void registerAllExtensions(ExtensionRegistry registry) {
+ UnittestProto.registerAllExtensions(registry);
+ }
+
+
+ /**
+ * Set every field of {@code message} to the values expected by
+ * {@code assertAllExtensionsSet()}.
+ */
+ public static void setAllExtensions(TestAllExtensions.Builder message) {
+ message.setExtension(optionalInt32Extension , 101);
+ message.setExtension(optionalInt64Extension , 102L);
+ message.setExtension(optionalUint32Extension , 103);
+ message.setExtension(optionalUint64Extension , 104L);
+ message.setExtension(optionalSint32Extension , 105);
+ message.setExtension(optionalSint64Extension , 106L);
+ message.setExtension(optionalFixed32Extension , 107);
+ message.setExtension(optionalFixed64Extension , 108L);
+ message.setExtension(optionalSfixed32Extension, 109);
+ message.setExtension(optionalSfixed64Extension, 110L);
+ message.setExtension(optionalFloatExtension , 111F);
+ message.setExtension(optionalDoubleExtension , 112D);
+ message.setExtension(optionalBoolExtension , true);
+ message.setExtension(optionalStringExtension , "115");
+ message.setExtension(optionalBytesExtension , toBytes("116"));
+
+ message.setExtension(optionalGroupExtension,
+ OptionalGroup_extension.newBuilder().setA(117).build());
+ message.setExtension(optionalNestedMessageExtension,
+ TestAllTypes.NestedMessage.newBuilder().setBb(118).build());
+ message.setExtension(optionalForeignMessageExtension,
+ ForeignMessage.newBuilder().setC(119).build());
+ message.setExtension(optionalImportMessageExtension,
+ ImportMessage.newBuilder().setD(120).build());
+ message.setExtension(optionalPublicImportMessageExtension,
+ PublicImportMessage.newBuilder().setE(126).build());
+ message.setExtension(optionalLazyMessageExtension,
+ TestAllTypes.NestedMessage.newBuilder().setBb(127).build());
+
+ message.setExtension(optionalNestedEnumExtension, TestAllTypes.NestedEnum.BAZ);
+ message.setExtension(optionalForeignEnumExtension, ForeignEnum.FOREIGN_BAZ);
+ message.setExtension(optionalImportEnumExtension, ImportEnum.IMPORT_BAZ);
+
+ message.setExtension(optionalStringPieceExtension, "124");
+ message.setExtension(optionalCordExtension, "125");
+
+ // -----------------------------------------------------------------
+
+ message.addExtension(repeatedInt32Extension , 201);
+ message.addExtension(repeatedInt64Extension , 202L);
+ message.addExtension(repeatedUint32Extension , 203);
+ message.addExtension(repeatedUint64Extension , 204L);
+ message.addExtension(repeatedSint32Extension , 205);
+ message.addExtension(repeatedSint64Extension , 206L);
+ message.addExtension(repeatedFixed32Extension , 207);
+ message.addExtension(repeatedFixed64Extension , 208L);
+ message.addExtension(repeatedSfixed32Extension, 209);
+ message.addExtension(repeatedSfixed64Extension, 210L);
+ message.addExtension(repeatedFloatExtension , 211F);
+ message.addExtension(repeatedDoubleExtension , 212D);
+ message.addExtension(repeatedBoolExtension , true);
+ message.addExtension(repeatedStringExtension , "215");
+ message.addExtension(repeatedBytesExtension , toBytes("216"));
+
+ message.addExtension(repeatedGroupExtension,
+ RepeatedGroup_extension.newBuilder().setA(217).build());
+ message.addExtension(repeatedNestedMessageExtension,
+ TestAllTypes.NestedMessage.newBuilder().setBb(218).build());
+ message.addExtension(repeatedForeignMessageExtension,
+ ForeignMessage.newBuilder().setC(219).build());
+ message.addExtension(repeatedImportMessageExtension,
+ ImportMessage.newBuilder().setD(220).build());
+ message.addExtension(repeatedLazyMessageExtension,
+ TestAllTypes.NestedMessage.newBuilder().setBb(227).build());
+
+ message.addExtension(repeatedNestedEnumExtension, TestAllTypes.NestedEnum.BAR);
+ message.addExtension(repeatedForeignEnumExtension, ForeignEnum.FOREIGN_BAR);
+ message.addExtension(repeatedImportEnumExtension, ImportEnum.IMPORT_BAR);
+
+ message.addExtension(repeatedStringPieceExtension, "224");
+ message.addExtension(repeatedCordExtension, "225");
+
+ // Add a second one of each field.
+ message.addExtension(repeatedInt32Extension , 301);
+ message.addExtension(repeatedInt64Extension , 302L);
+ message.addExtension(repeatedUint32Extension , 303);
+ message.addExtension(repeatedUint64Extension , 304L);
+ message.addExtension(repeatedSint32Extension , 305);
+ message.addExtension(repeatedSint64Extension , 306L);
+ message.addExtension(repeatedFixed32Extension , 307);
+ message.addExtension(repeatedFixed64Extension , 308L);
+ message.addExtension(repeatedSfixed32Extension, 309);
+ message.addExtension(repeatedSfixed64Extension, 310L);
+ message.addExtension(repeatedFloatExtension , 311F);
+ message.addExtension(repeatedDoubleExtension , 312D);
+ message.addExtension(repeatedBoolExtension , false);
+ message.addExtension(repeatedStringExtension , "315");
+ message.addExtension(repeatedBytesExtension , toBytes("316"));
+
+ message.addExtension(repeatedGroupExtension,
+ RepeatedGroup_extension.newBuilder().setA(317).build());
+ message.addExtension(repeatedNestedMessageExtension,
+ TestAllTypes.NestedMessage.newBuilder().setBb(318).build());
+ message.addExtension(repeatedForeignMessageExtension,
+ ForeignMessage.newBuilder().setC(319).build());
+ message.addExtension(repeatedImportMessageExtension,
+ ImportMessage.newBuilder().setD(320).build());
+ message.addExtension(repeatedLazyMessageExtension,
+ TestAllTypes.NestedMessage.newBuilder().setBb(327).build());
+
+ message.addExtension(repeatedNestedEnumExtension, TestAllTypes.NestedEnum.BAZ);
+ message.addExtension(repeatedForeignEnumExtension, ForeignEnum.FOREIGN_BAZ);
+ message.addExtension(repeatedImportEnumExtension, ImportEnum.IMPORT_BAZ);
+
+ message.addExtension(repeatedStringPieceExtension, "324");
+ message.addExtension(repeatedCordExtension, "325");
+
+ // -----------------------------------------------------------------
+
+ message.setExtension(defaultInt32Extension , 401);
+ message.setExtension(defaultInt64Extension , 402L);
+ message.setExtension(defaultUint32Extension , 403);
+ message.setExtension(defaultUint64Extension , 404L);
+ message.setExtension(defaultSint32Extension , 405);
+ message.setExtension(defaultSint64Extension , 406L);
+ message.setExtension(defaultFixed32Extension , 407);
+ message.setExtension(defaultFixed64Extension , 408L);
+ message.setExtension(defaultSfixed32Extension, 409);
+ message.setExtension(defaultSfixed64Extension, 410L);
+ message.setExtension(defaultFloatExtension , 411F);
+ message.setExtension(defaultDoubleExtension , 412D);
+ message.setExtension(defaultBoolExtension , false);
+ message.setExtension(defaultStringExtension , "415");
+ message.setExtension(defaultBytesExtension , toBytes("416"));
+
+ message.setExtension(defaultNestedEnumExtension, TestAllTypes.NestedEnum.FOO);
+ message.setExtension(defaultForeignEnumExtension, ForeignEnum.FOREIGN_FOO);
+ message.setExtension(defaultImportEnumExtension, ImportEnum.IMPORT_FOO);
+
+ message.setExtension(defaultStringPieceExtension, "424");
+ message.setExtension(defaultCordExtension, "425");
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Modify the repeated extensions of {@code message} to contain the values
+ * expected by {@code assertRepeatedExtensionsModified()}.
+ */
+ public static void modifyRepeatedExtensions(
+ TestAllExtensions.Builder message) {
+ message.setExtension(repeatedInt32Extension , 1, 501);
+ message.setExtension(repeatedInt64Extension , 1, 502L);
+ message.setExtension(repeatedUint32Extension , 1, 503);
+ message.setExtension(repeatedUint64Extension , 1, 504L);
+ message.setExtension(repeatedSint32Extension , 1, 505);
+ message.setExtension(repeatedSint64Extension , 1, 506L);
+ message.setExtension(repeatedFixed32Extension , 1, 507);
+ message.setExtension(repeatedFixed64Extension , 1, 508L);
+ message.setExtension(repeatedSfixed32Extension, 1, 509);
+ message.setExtension(repeatedSfixed64Extension, 1, 510L);
+ message.setExtension(repeatedFloatExtension , 1, 511F);
+ message.setExtension(repeatedDoubleExtension , 1, 512D);
+ message.setExtension(repeatedBoolExtension , 1, true);
+ message.setExtension(repeatedStringExtension , 1, "515");
+ message.setExtension(repeatedBytesExtension , 1, toBytes("516"));
+
+ message.setExtension(repeatedGroupExtension, 1,
+ RepeatedGroup_extension.newBuilder().setA(517).build());
+ message.setExtension(repeatedNestedMessageExtension, 1,
+ TestAllTypes.NestedMessage.newBuilder().setBb(518).build());
+ message.setExtension(repeatedForeignMessageExtension, 1,
+ ForeignMessage.newBuilder().setC(519).build());
+ message.setExtension(repeatedImportMessageExtension, 1,
+ ImportMessage.newBuilder().setD(520).build());
+ message.setExtension(repeatedLazyMessageExtension, 1,
+ TestAllTypes.NestedMessage.newBuilder().setBb(527).build());
+
+ message.setExtension(repeatedNestedEnumExtension , 1, TestAllTypes.NestedEnum.FOO);
+ message.setExtension(repeatedForeignEnumExtension, 1, ForeignEnum.FOREIGN_FOO);
+ message.setExtension(repeatedImportEnumExtension , 1, ImportEnum.IMPORT_FOO);
+
+ message.setExtension(repeatedStringPieceExtension, 1, "524");
+ message.setExtension(repeatedCordExtension, 1, "525");
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Assert (using {@code junit.framework.Assert}} that all extensions of
+ * {@code message} are set to the values assigned by {@code setAllExtensions}.
+ */
+ public static void assertAllExtensionsSet(
+ TestAllExtensionsOrBuilder message) {
+ Assert.assertTrue(message.hasExtension(optionalInt32Extension ));
+ Assert.assertTrue(message.hasExtension(optionalInt64Extension ));
+ Assert.assertTrue(message.hasExtension(optionalUint32Extension ));
+ Assert.assertTrue(message.hasExtension(optionalUint64Extension ));
+ Assert.assertTrue(message.hasExtension(optionalSint32Extension ));
+ Assert.assertTrue(message.hasExtension(optionalSint64Extension ));
+ Assert.assertTrue(message.hasExtension(optionalFixed32Extension ));
+ Assert.assertTrue(message.hasExtension(optionalFixed64Extension ));
+ Assert.assertTrue(message.hasExtension(optionalSfixed32Extension));
+ Assert.assertTrue(message.hasExtension(optionalSfixed64Extension));
+ Assert.assertTrue(message.hasExtension(optionalFloatExtension ));
+ Assert.assertTrue(message.hasExtension(optionalDoubleExtension ));
+ Assert.assertTrue(message.hasExtension(optionalBoolExtension ));
+ Assert.assertTrue(message.hasExtension(optionalStringExtension ));
+ Assert.assertTrue(message.hasExtension(optionalBytesExtension ));
+
+ Assert.assertTrue(message.hasExtension(optionalGroupExtension ));
+ Assert.assertTrue(message.hasExtension(optionalNestedMessageExtension ));
+ Assert.assertTrue(message.hasExtension(optionalForeignMessageExtension));
+ Assert.assertTrue(message.hasExtension(optionalImportMessageExtension ));
+
+ Assert.assertTrue(message.getExtension(optionalGroupExtension ).hasA());
+ Assert.assertTrue(message.getExtension(optionalNestedMessageExtension ).hasBb());
+ Assert.assertTrue(message.getExtension(optionalForeignMessageExtension).hasC());
+ Assert.assertTrue(message.getExtension(optionalImportMessageExtension ).hasD());
+
+ Assert.assertTrue(message.hasExtension(optionalNestedEnumExtension ));
+ Assert.assertTrue(message.hasExtension(optionalForeignEnumExtension));
+ Assert.assertTrue(message.hasExtension(optionalImportEnumExtension ));
+
+ Assert.assertTrue(message.hasExtension(optionalStringPieceExtension));
+ Assert.assertTrue(message.hasExtension(optionalCordExtension));
+
+ assertEqualsExactType(101 , message.getExtension(optionalInt32Extension ));
+ assertEqualsExactType(102L , message.getExtension(optionalInt64Extension ));
+ assertEqualsExactType(103 , message.getExtension(optionalUint32Extension ));
+ assertEqualsExactType(104L , message.getExtension(optionalUint64Extension ));
+ assertEqualsExactType(105 , message.getExtension(optionalSint32Extension ));
+ assertEqualsExactType(106L , message.getExtension(optionalSint64Extension ));
+ assertEqualsExactType(107 , message.getExtension(optionalFixed32Extension ));
+ assertEqualsExactType(108L , message.getExtension(optionalFixed64Extension ));
+ assertEqualsExactType(109 , message.getExtension(optionalSfixed32Extension));
+ assertEqualsExactType(110L , message.getExtension(optionalSfixed64Extension));
+ assertEqualsExactType(111F , message.getExtension(optionalFloatExtension ));
+ assertEqualsExactType(112D , message.getExtension(optionalDoubleExtension ));
+ assertEqualsExactType(true , message.getExtension(optionalBoolExtension ));
+ assertEqualsExactType("115", message.getExtension(optionalStringExtension ));
+ assertEqualsExactType(toBytes("116"), message.getExtension(optionalBytesExtension));
+
+ assertEqualsExactType(117, message.getExtension(optionalGroupExtension ).getA());
+ assertEqualsExactType(118, message.getExtension(optionalNestedMessageExtension ).getBb());
+ assertEqualsExactType(119, message.getExtension(optionalForeignMessageExtension ).getC());
+ assertEqualsExactType(120, message.getExtension(optionalImportMessageExtension ).getD());
+ assertEqualsExactType(126, message.getExtension(optionalPublicImportMessageExtension).getE());
+ assertEqualsExactType(127, message.getExtension(optionalLazyMessageExtension ).getBb());
+
+ assertEqualsExactType(TestAllTypes.NestedEnum.BAZ,
+ message.getExtension(optionalNestedEnumExtension));
+ assertEqualsExactType(ForeignEnum.FOREIGN_BAZ,
+ message.getExtension(optionalForeignEnumExtension));
+ assertEqualsExactType(ImportEnum.IMPORT_BAZ,
+ message.getExtension(optionalImportEnumExtension));
+
+ assertEqualsExactType("124", message.getExtension(optionalStringPieceExtension));
+ assertEqualsExactType("125", message.getExtension(optionalCordExtension));
+
+ // -----------------------------------------------------------------
+
+ Assert.assertEquals(2, message.getExtensionCount(repeatedInt32Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedInt64Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedUint32Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedUint64Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedSint32Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedSint64Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedFixed32Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedFixed64Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedSfixed32Extension));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedSfixed64Extension));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedFloatExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedDoubleExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedBoolExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedStringExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedBytesExtension ));
+
+ Assert.assertEquals(2, message.getExtensionCount(repeatedGroupExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedNestedMessageExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedForeignMessageExtension));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedImportMessageExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedLazyMessageExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedNestedEnumExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedForeignEnumExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedImportEnumExtension ));
+
+ Assert.assertEquals(2, message.getExtensionCount(repeatedStringPieceExtension));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedCordExtension));
+
+ assertEqualsExactType(201 , message.getExtension(repeatedInt32Extension , 0));
+ assertEqualsExactType(202L , message.getExtension(repeatedInt64Extension , 0));
+ assertEqualsExactType(203 , message.getExtension(repeatedUint32Extension , 0));
+ assertEqualsExactType(204L , message.getExtension(repeatedUint64Extension , 0));
+ assertEqualsExactType(205 , message.getExtension(repeatedSint32Extension , 0));
+ assertEqualsExactType(206L , message.getExtension(repeatedSint64Extension , 0));
+ assertEqualsExactType(207 , message.getExtension(repeatedFixed32Extension , 0));
+ assertEqualsExactType(208L , message.getExtension(repeatedFixed64Extension , 0));
+ assertEqualsExactType(209 , message.getExtension(repeatedSfixed32Extension, 0));
+ assertEqualsExactType(210L , message.getExtension(repeatedSfixed64Extension, 0));
+ assertEqualsExactType(211F , message.getExtension(repeatedFloatExtension , 0));
+ assertEqualsExactType(212D , message.getExtension(repeatedDoubleExtension , 0));
+ assertEqualsExactType(true , message.getExtension(repeatedBoolExtension , 0));
+ assertEqualsExactType("215", message.getExtension(repeatedStringExtension , 0));
+ assertEqualsExactType(toBytes("216"), message.getExtension(repeatedBytesExtension, 0));
+
+ assertEqualsExactType(217, message.getExtension(repeatedGroupExtension , 0).getA());
+ assertEqualsExactType(218, message.getExtension(repeatedNestedMessageExtension , 0).getBb());
+ assertEqualsExactType(219, message.getExtension(repeatedForeignMessageExtension, 0).getC());
+ assertEqualsExactType(220, message.getExtension(repeatedImportMessageExtension , 0).getD());
+ assertEqualsExactType(227, message.getExtension(repeatedLazyMessageExtension , 0).getBb());
+
+ assertEqualsExactType(TestAllTypes.NestedEnum.BAR,
+ message.getExtension(repeatedNestedEnumExtension, 0));
+ assertEqualsExactType(ForeignEnum.FOREIGN_BAR,
+ message.getExtension(repeatedForeignEnumExtension, 0));
+ assertEqualsExactType(ImportEnum.IMPORT_BAR,
+ message.getExtension(repeatedImportEnumExtension, 0));
+
+ assertEqualsExactType("224", message.getExtension(repeatedStringPieceExtension, 0));
+ assertEqualsExactType("225", message.getExtension(repeatedCordExtension, 0));
+
+ assertEqualsExactType(301 , message.getExtension(repeatedInt32Extension , 1));
+ assertEqualsExactType(302L , message.getExtension(repeatedInt64Extension , 1));
+ assertEqualsExactType(303 , message.getExtension(repeatedUint32Extension , 1));
+ assertEqualsExactType(304L , message.getExtension(repeatedUint64Extension , 1));
+ assertEqualsExactType(305 , message.getExtension(repeatedSint32Extension , 1));
+ assertEqualsExactType(306L , message.getExtension(repeatedSint64Extension , 1));
+ assertEqualsExactType(307 , message.getExtension(repeatedFixed32Extension , 1));
+ assertEqualsExactType(308L , message.getExtension(repeatedFixed64Extension , 1));
+ assertEqualsExactType(309 , message.getExtension(repeatedSfixed32Extension, 1));
+ assertEqualsExactType(310L , message.getExtension(repeatedSfixed64Extension, 1));
+ assertEqualsExactType(311F , message.getExtension(repeatedFloatExtension , 1));
+ assertEqualsExactType(312D , message.getExtension(repeatedDoubleExtension , 1));
+ assertEqualsExactType(false, message.getExtension(repeatedBoolExtension , 1));
+ assertEqualsExactType("315", message.getExtension(repeatedStringExtension , 1));
+ assertEqualsExactType(toBytes("316"), message.getExtension(repeatedBytesExtension, 1));
+
+ assertEqualsExactType(317, message.getExtension(repeatedGroupExtension , 1).getA());
+ assertEqualsExactType(318, message.getExtension(repeatedNestedMessageExtension , 1).getBb());
+ assertEqualsExactType(319, message.getExtension(repeatedForeignMessageExtension, 1).getC());
+ assertEqualsExactType(320, message.getExtension(repeatedImportMessageExtension , 1).getD());
+ assertEqualsExactType(327, message.getExtension(repeatedLazyMessageExtension , 1).getBb());
+
+ assertEqualsExactType(TestAllTypes.NestedEnum.BAZ,
+ message.getExtension(repeatedNestedEnumExtension, 1));
+ assertEqualsExactType(ForeignEnum.FOREIGN_BAZ,
+ message.getExtension(repeatedForeignEnumExtension, 1));
+ assertEqualsExactType(ImportEnum.IMPORT_BAZ,
+ message.getExtension(repeatedImportEnumExtension, 1));
+
+ assertEqualsExactType("324", message.getExtension(repeatedStringPieceExtension, 1));
+ assertEqualsExactType("325", message.getExtension(repeatedCordExtension, 1));
+
+ // -----------------------------------------------------------------
+
+ Assert.assertTrue(message.hasExtension(defaultInt32Extension ));
+ Assert.assertTrue(message.hasExtension(defaultInt64Extension ));
+ Assert.assertTrue(message.hasExtension(defaultUint32Extension ));
+ Assert.assertTrue(message.hasExtension(defaultUint64Extension ));
+ Assert.assertTrue(message.hasExtension(defaultSint32Extension ));
+ Assert.assertTrue(message.hasExtension(defaultSint64Extension ));
+ Assert.assertTrue(message.hasExtension(defaultFixed32Extension ));
+ Assert.assertTrue(message.hasExtension(defaultFixed64Extension ));
+ Assert.assertTrue(message.hasExtension(defaultSfixed32Extension));
+ Assert.assertTrue(message.hasExtension(defaultSfixed64Extension));
+ Assert.assertTrue(message.hasExtension(defaultFloatExtension ));
+ Assert.assertTrue(message.hasExtension(defaultDoubleExtension ));
+ Assert.assertTrue(message.hasExtension(defaultBoolExtension ));
+ Assert.assertTrue(message.hasExtension(defaultStringExtension ));
+ Assert.assertTrue(message.hasExtension(defaultBytesExtension ));
+
+ Assert.assertTrue(message.hasExtension(defaultNestedEnumExtension ));
+ Assert.assertTrue(message.hasExtension(defaultForeignEnumExtension));
+ Assert.assertTrue(message.hasExtension(defaultImportEnumExtension ));
+
+ Assert.assertTrue(message.hasExtension(defaultStringPieceExtension));
+ Assert.assertTrue(message.hasExtension(defaultCordExtension));
+
+ assertEqualsExactType(401 , message.getExtension(defaultInt32Extension ));
+ assertEqualsExactType(402L , message.getExtension(defaultInt64Extension ));
+ assertEqualsExactType(403 , message.getExtension(defaultUint32Extension ));
+ assertEqualsExactType(404L , message.getExtension(defaultUint64Extension ));
+ assertEqualsExactType(405 , message.getExtension(defaultSint32Extension ));
+ assertEqualsExactType(406L , message.getExtension(defaultSint64Extension ));
+ assertEqualsExactType(407 , message.getExtension(defaultFixed32Extension ));
+ assertEqualsExactType(408L , message.getExtension(defaultFixed64Extension ));
+ assertEqualsExactType(409 , message.getExtension(defaultSfixed32Extension));
+ assertEqualsExactType(410L , message.getExtension(defaultSfixed64Extension));
+ assertEqualsExactType(411F , message.getExtension(defaultFloatExtension ));
+ assertEqualsExactType(412D , message.getExtension(defaultDoubleExtension ));
+ assertEqualsExactType(false, message.getExtension(defaultBoolExtension ));
+ assertEqualsExactType("415", message.getExtension(defaultStringExtension ));
+ assertEqualsExactType(toBytes("416"), message.getExtension(defaultBytesExtension));
+
+ assertEqualsExactType(TestAllTypes.NestedEnum.FOO,
+ message.getExtension(defaultNestedEnumExtension ));
+ assertEqualsExactType(ForeignEnum.FOREIGN_FOO,
+ message.getExtension(defaultForeignEnumExtension));
+ assertEqualsExactType(ImportEnum.IMPORT_FOO,
+ message.getExtension(defaultImportEnumExtension));
+
+ assertEqualsExactType("424", message.getExtension(defaultStringPieceExtension));
+ assertEqualsExactType("425", message.getExtension(defaultCordExtension));
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Assert (using {@code junit.framework.Assert}} that all extensions of
+ * {@code message} are cleared, and that getting the extensions returns their
+ * default values.
+ */
+ public static void assertExtensionsClear(TestAllExtensionsOrBuilder message) {
+ // hasBlah() should initially be false for all optional fields.
+ Assert.assertFalse(message.hasExtension(optionalInt32Extension ));
+ Assert.assertFalse(message.hasExtension(optionalInt64Extension ));
+ Assert.assertFalse(message.hasExtension(optionalUint32Extension ));
+ Assert.assertFalse(message.hasExtension(optionalUint64Extension ));
+ Assert.assertFalse(message.hasExtension(optionalSint32Extension ));
+ Assert.assertFalse(message.hasExtension(optionalSint64Extension ));
+ Assert.assertFalse(message.hasExtension(optionalFixed32Extension ));
+ Assert.assertFalse(message.hasExtension(optionalFixed64Extension ));
+ Assert.assertFalse(message.hasExtension(optionalSfixed32Extension));
+ Assert.assertFalse(message.hasExtension(optionalSfixed64Extension));
+ Assert.assertFalse(message.hasExtension(optionalFloatExtension ));
+ Assert.assertFalse(message.hasExtension(optionalDoubleExtension ));
+ Assert.assertFalse(message.hasExtension(optionalBoolExtension ));
+ Assert.assertFalse(message.hasExtension(optionalStringExtension ));
+ Assert.assertFalse(message.hasExtension(optionalBytesExtension ));
+
+ Assert.assertFalse(message.hasExtension(optionalGroupExtension ));
+ Assert.assertFalse(message.hasExtension(optionalNestedMessageExtension ));
+ Assert.assertFalse(message.hasExtension(optionalForeignMessageExtension));
+ Assert.assertFalse(message.hasExtension(optionalImportMessageExtension ));
+
+ Assert.assertFalse(message.hasExtension(optionalNestedEnumExtension ));
+ Assert.assertFalse(message.hasExtension(optionalForeignEnumExtension));
+ Assert.assertFalse(message.hasExtension(optionalImportEnumExtension ));
+
+ Assert.assertFalse(message.hasExtension(optionalStringPieceExtension));
+ Assert.assertFalse(message.hasExtension(optionalCordExtension));
+
+ // Optional fields without defaults are set to zero or something like it.
+ assertEqualsExactType(0 , message.getExtension(optionalInt32Extension ));
+ assertEqualsExactType(0L , message.getExtension(optionalInt64Extension ));
+ assertEqualsExactType(0 , message.getExtension(optionalUint32Extension ));
+ assertEqualsExactType(0L , message.getExtension(optionalUint64Extension ));
+ assertEqualsExactType(0 , message.getExtension(optionalSint32Extension ));
+ assertEqualsExactType(0L , message.getExtension(optionalSint64Extension ));
+ assertEqualsExactType(0 , message.getExtension(optionalFixed32Extension ));
+ assertEqualsExactType(0L , message.getExtension(optionalFixed64Extension ));
+ assertEqualsExactType(0 , message.getExtension(optionalSfixed32Extension));
+ assertEqualsExactType(0L , message.getExtension(optionalSfixed64Extension));
+ assertEqualsExactType(0F , message.getExtension(optionalFloatExtension ));
+ assertEqualsExactType(0D , message.getExtension(optionalDoubleExtension ));
+ assertEqualsExactType(false, message.getExtension(optionalBoolExtension ));
+ assertEqualsExactType("" , message.getExtension(optionalStringExtension ));
+ assertEqualsExactType(ByteString.EMPTY, message.getExtension(optionalBytesExtension));
+
+ // Embedded messages should also be clear.
+ Assert.assertFalse(message.getExtension(optionalGroupExtension ).hasA());
+ Assert.assertFalse(message.getExtension(optionalNestedMessageExtension ).hasBb());
+ Assert.assertFalse(message.getExtension(optionalForeignMessageExtension).hasC());
+ Assert.assertFalse(message.getExtension(optionalImportMessageExtension ).hasD());
+
+ assertEqualsExactType(0, message.getExtension(optionalGroupExtension ).getA());
+ assertEqualsExactType(0, message.getExtension(optionalNestedMessageExtension ).getBb());
+ assertEqualsExactType(0, message.getExtension(optionalForeignMessageExtension).getC());
+ assertEqualsExactType(0, message.getExtension(optionalImportMessageExtension ).getD());
+
+ // Enums without defaults are set to the first value in the enum.
+ assertEqualsExactType(TestAllTypes.NestedEnum.FOO,
+ message.getExtension(optionalNestedEnumExtension ));
+ assertEqualsExactType(ForeignEnum.FOREIGN_FOO,
+ message.getExtension(optionalForeignEnumExtension));
+ assertEqualsExactType(ImportEnum.IMPORT_FOO,
+ message.getExtension(optionalImportEnumExtension));
+
+ assertEqualsExactType("", message.getExtension(optionalStringPieceExtension));
+ assertEqualsExactType("", message.getExtension(optionalCordExtension));
+
+ // Repeated fields are empty.
+ Assert.assertEquals(0, message.getExtensionCount(repeatedInt32Extension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedInt64Extension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedUint32Extension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedUint64Extension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedSint32Extension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedSint64Extension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedFixed32Extension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedFixed64Extension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedSfixed32Extension));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedSfixed64Extension));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedFloatExtension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedDoubleExtension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedBoolExtension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedStringExtension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedBytesExtension ));
+
+ Assert.assertEquals(0, message.getExtensionCount(repeatedGroupExtension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedNestedMessageExtension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedForeignMessageExtension));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedImportMessageExtension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedLazyMessageExtension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedNestedEnumExtension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedForeignEnumExtension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedImportEnumExtension ));
+
+ Assert.assertEquals(0, message.getExtensionCount(repeatedStringPieceExtension));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedCordExtension));
+
+ // Repeated fields are empty via getExtension().size().
+ Assert.assertEquals(0, message.getExtension(repeatedInt32Extension ).size());
+ Assert.assertEquals(0, message.getExtension(repeatedInt64Extension ).size());
+ Assert.assertEquals(0, message.getExtension(repeatedUint32Extension ).size());
+ Assert.assertEquals(0, message.getExtension(repeatedUint64Extension ).size());
+ Assert.assertEquals(0, message.getExtension(repeatedSint32Extension ).size());
+ Assert.assertEquals(0, message.getExtension(repeatedSint64Extension ).size());
+ Assert.assertEquals(0, message.getExtension(repeatedFixed32Extension ).size());
+ Assert.assertEquals(0, message.getExtension(repeatedFixed64Extension ).size());
+ Assert.assertEquals(0, message.getExtension(repeatedSfixed32Extension).size());
+ Assert.assertEquals(0, message.getExtension(repeatedSfixed64Extension).size());
+ Assert.assertEquals(0, message.getExtension(repeatedFloatExtension ).size());
+ Assert.assertEquals(0, message.getExtension(repeatedDoubleExtension ).size());
+ Assert.assertEquals(0, message.getExtension(repeatedBoolExtension ).size());
+ Assert.assertEquals(0, message.getExtension(repeatedStringExtension ).size());
+ Assert.assertEquals(0, message.getExtension(repeatedBytesExtension ).size());
+
+ Assert.assertEquals(0, message.getExtension(repeatedGroupExtension ).size());
+ Assert.assertEquals(0, message.getExtension(repeatedNestedMessageExtension ).size());
+ Assert.assertEquals(0, message.getExtension(repeatedForeignMessageExtension).size());
+ Assert.assertEquals(0, message.getExtension(repeatedImportMessageExtension ).size());
+ Assert.assertEquals(0, message.getExtension(repeatedLazyMessageExtension ).size());
+ Assert.assertEquals(0, message.getExtension(repeatedNestedEnumExtension ).size());
+ Assert.assertEquals(0, message.getExtension(repeatedForeignEnumExtension ).size());
+ Assert.assertEquals(0, message.getExtension(repeatedImportEnumExtension ).size());
+
+ Assert.assertEquals(0, message.getExtension(repeatedStringPieceExtension).size());
+ Assert.assertEquals(0, message.getExtension(repeatedCordExtension).size());
+
+ // hasBlah() should also be false for all default fields.
+ Assert.assertFalse(message.hasExtension(defaultInt32Extension ));
+ Assert.assertFalse(message.hasExtension(defaultInt64Extension ));
+ Assert.assertFalse(message.hasExtension(defaultUint32Extension ));
+ Assert.assertFalse(message.hasExtension(defaultUint64Extension ));
+ Assert.assertFalse(message.hasExtension(defaultSint32Extension ));
+ Assert.assertFalse(message.hasExtension(defaultSint64Extension ));
+ Assert.assertFalse(message.hasExtension(defaultFixed32Extension ));
+ Assert.assertFalse(message.hasExtension(defaultFixed64Extension ));
+ Assert.assertFalse(message.hasExtension(defaultSfixed32Extension));
+ Assert.assertFalse(message.hasExtension(defaultSfixed64Extension));
+ Assert.assertFalse(message.hasExtension(defaultFloatExtension ));
+ Assert.assertFalse(message.hasExtension(defaultDoubleExtension ));
+ Assert.assertFalse(message.hasExtension(defaultBoolExtension ));
+ Assert.assertFalse(message.hasExtension(defaultStringExtension ));
+ Assert.assertFalse(message.hasExtension(defaultBytesExtension ));
+
+ Assert.assertFalse(message.hasExtension(defaultNestedEnumExtension ));
+ Assert.assertFalse(message.hasExtension(defaultForeignEnumExtension));
+ Assert.assertFalse(message.hasExtension(defaultImportEnumExtension ));
+
+ Assert.assertFalse(message.hasExtension(defaultStringPieceExtension));
+ Assert.assertFalse(message.hasExtension(defaultCordExtension));
+
+ // Fields with defaults have their default values (duh).
+ assertEqualsExactType( 41 , message.getExtension(defaultInt32Extension ));
+ assertEqualsExactType( 42L , message.getExtension(defaultInt64Extension ));
+ assertEqualsExactType( 43 , message.getExtension(defaultUint32Extension ));
+ assertEqualsExactType( 44L , message.getExtension(defaultUint64Extension ));
+ assertEqualsExactType(-45 , message.getExtension(defaultSint32Extension ));
+ assertEqualsExactType( 46L , message.getExtension(defaultSint64Extension ));
+ assertEqualsExactType( 47 , message.getExtension(defaultFixed32Extension ));
+ assertEqualsExactType( 48L , message.getExtension(defaultFixed64Extension ));
+ assertEqualsExactType( 49 , message.getExtension(defaultSfixed32Extension));
+ assertEqualsExactType(-50L , message.getExtension(defaultSfixed64Extension));
+ assertEqualsExactType( 51.5F , message.getExtension(defaultFloatExtension ));
+ assertEqualsExactType( 52e3D , message.getExtension(defaultDoubleExtension ));
+ assertEqualsExactType(true , message.getExtension(defaultBoolExtension ));
+ assertEqualsExactType("hello", message.getExtension(defaultStringExtension ));
+ assertEqualsExactType(toBytes("world"), message.getExtension(defaultBytesExtension));
+
+ assertEqualsExactType(TestAllTypes.NestedEnum.BAR,
+ message.getExtension(defaultNestedEnumExtension ));
+ assertEqualsExactType(ForeignEnum.FOREIGN_BAR,
+ message.getExtension(defaultForeignEnumExtension));
+ assertEqualsExactType(ImportEnum.IMPORT_BAR,
+ message.getExtension(defaultImportEnumExtension));
+
+ assertEqualsExactType("abc", message.getExtension(defaultStringPieceExtension));
+ assertEqualsExactType("123", message.getExtension(defaultCordExtension));
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Assert (using {@code junit.framework.Assert}} that all extensions of
+ * {@code message} are set to the values assigned by {@code setAllExtensions}
+ * followed by {@code modifyRepeatedExtensions}.
+ */
+ public static void assertRepeatedExtensionsModified(
+ TestAllExtensionsOrBuilder message) {
+ // ModifyRepeatedFields only sets the second repeated element of each
+ // field. In addition to verifying this, we also verify that the first
+ // element and size were *not* modified.
+ Assert.assertEquals(2, message.getExtensionCount(repeatedInt32Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedInt64Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedUint32Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedUint64Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedSint32Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedSint64Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedFixed32Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedFixed64Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedSfixed32Extension));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedSfixed64Extension));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedFloatExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedDoubleExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedBoolExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedStringExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedBytesExtension ));
+
+ Assert.assertEquals(2, message.getExtensionCount(repeatedGroupExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedNestedMessageExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedForeignMessageExtension));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedImportMessageExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedLazyMessageExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedNestedEnumExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedForeignEnumExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedImportEnumExtension ));
+
+ Assert.assertEquals(2, message.getExtensionCount(repeatedStringPieceExtension));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedCordExtension));
+
+ assertEqualsExactType(201 , message.getExtension(repeatedInt32Extension , 0));
+ assertEqualsExactType(202L , message.getExtension(repeatedInt64Extension , 0));
+ assertEqualsExactType(203 , message.getExtension(repeatedUint32Extension , 0));
+ assertEqualsExactType(204L , message.getExtension(repeatedUint64Extension , 0));
+ assertEqualsExactType(205 , message.getExtension(repeatedSint32Extension , 0));
+ assertEqualsExactType(206L , message.getExtension(repeatedSint64Extension , 0));
+ assertEqualsExactType(207 , message.getExtension(repeatedFixed32Extension , 0));
+ assertEqualsExactType(208L , message.getExtension(repeatedFixed64Extension , 0));
+ assertEqualsExactType(209 , message.getExtension(repeatedSfixed32Extension, 0));
+ assertEqualsExactType(210L , message.getExtension(repeatedSfixed64Extension, 0));
+ assertEqualsExactType(211F , message.getExtension(repeatedFloatExtension , 0));
+ assertEqualsExactType(212D , message.getExtension(repeatedDoubleExtension , 0));
+ assertEqualsExactType(true , message.getExtension(repeatedBoolExtension , 0));
+ assertEqualsExactType("215", message.getExtension(repeatedStringExtension , 0));
+ assertEqualsExactType(toBytes("216"), message.getExtension(repeatedBytesExtension, 0));
+
+ assertEqualsExactType(217, message.getExtension(repeatedGroupExtension , 0).getA());
+ assertEqualsExactType(218, message.getExtension(repeatedNestedMessageExtension , 0).getBb());
+ assertEqualsExactType(219, message.getExtension(repeatedForeignMessageExtension, 0).getC());
+ assertEqualsExactType(220, message.getExtension(repeatedImportMessageExtension , 0).getD());
+ assertEqualsExactType(227, message.getExtension(repeatedLazyMessageExtension , 0).getBb());
+
+ assertEqualsExactType(TestAllTypes.NestedEnum.BAR,
+ message.getExtension(repeatedNestedEnumExtension, 0));
+ assertEqualsExactType(ForeignEnum.FOREIGN_BAR,
+ message.getExtension(repeatedForeignEnumExtension, 0));
+ assertEqualsExactType(ImportEnum.IMPORT_BAR,
+ message.getExtension(repeatedImportEnumExtension, 0));
+
+ assertEqualsExactType("224", message.getExtension(repeatedStringPieceExtension, 0));
+ assertEqualsExactType("225", message.getExtension(repeatedCordExtension, 0));
+
+ // Actually verify the second (modified) elements now.
+ assertEqualsExactType(501 , message.getExtension(repeatedInt32Extension , 1));
+ assertEqualsExactType(502L , message.getExtension(repeatedInt64Extension , 1));
+ assertEqualsExactType(503 , message.getExtension(repeatedUint32Extension , 1));
+ assertEqualsExactType(504L , message.getExtension(repeatedUint64Extension , 1));
+ assertEqualsExactType(505 , message.getExtension(repeatedSint32Extension , 1));
+ assertEqualsExactType(506L , message.getExtension(repeatedSint64Extension , 1));
+ assertEqualsExactType(507 , message.getExtension(repeatedFixed32Extension , 1));
+ assertEqualsExactType(508L , message.getExtension(repeatedFixed64Extension , 1));
+ assertEqualsExactType(509 , message.getExtension(repeatedSfixed32Extension, 1));
+ assertEqualsExactType(510L , message.getExtension(repeatedSfixed64Extension, 1));
+ assertEqualsExactType(511F , message.getExtension(repeatedFloatExtension , 1));
+ assertEqualsExactType(512D , message.getExtension(repeatedDoubleExtension , 1));
+ assertEqualsExactType(true , message.getExtension(repeatedBoolExtension , 1));
+ assertEqualsExactType("515", message.getExtension(repeatedStringExtension , 1));
+ assertEqualsExactType(toBytes("516"), message.getExtension(repeatedBytesExtension, 1));
+
+ assertEqualsExactType(517, message.getExtension(repeatedGroupExtension , 1).getA());
+ assertEqualsExactType(518, message.getExtension(repeatedNestedMessageExtension , 1).getBb());
+ assertEqualsExactType(519, message.getExtension(repeatedForeignMessageExtension, 1).getC());
+ assertEqualsExactType(520, message.getExtension(repeatedImportMessageExtension , 1).getD());
+ assertEqualsExactType(527, message.getExtension(repeatedLazyMessageExtension , 1).getBb());
+
+ assertEqualsExactType(TestAllTypes.NestedEnum.FOO,
+ message.getExtension(repeatedNestedEnumExtension, 1));
+ assertEqualsExactType(ForeignEnum.FOREIGN_FOO,
+ message.getExtension(repeatedForeignEnumExtension, 1));
+ assertEqualsExactType(ImportEnum.IMPORT_FOO,
+ message.getExtension(repeatedImportEnumExtension, 1));
+
+ assertEqualsExactType("524", message.getExtension(repeatedStringPieceExtension, 1));
+ assertEqualsExactType("525", message.getExtension(repeatedCordExtension, 1));
+ }
+
+ public static void setPackedExtensions(TestPackedExtensions.Builder message) {
+ message.addExtension(packedInt32Extension , 601);
+ message.addExtension(packedInt64Extension , 602L);
+ message.addExtension(packedUint32Extension , 603);
+ message.addExtension(packedUint64Extension , 604L);
+ message.addExtension(packedSint32Extension , 605);
+ message.addExtension(packedSint64Extension , 606L);
+ message.addExtension(packedFixed32Extension , 607);
+ message.addExtension(packedFixed64Extension , 608L);
+ message.addExtension(packedSfixed32Extension, 609);
+ message.addExtension(packedSfixed64Extension, 610L);
+ message.addExtension(packedFloatExtension , 611F);
+ message.addExtension(packedDoubleExtension , 612D);
+ message.addExtension(packedBoolExtension , true);
+ message.addExtension(packedEnumExtension, ForeignEnum.FOREIGN_BAR);
+ // Add a second one of each field.
+ message.addExtension(packedInt32Extension , 701);
+ message.addExtension(packedInt64Extension , 702L);
+ message.addExtension(packedUint32Extension , 703);
+ message.addExtension(packedUint64Extension , 704L);
+ message.addExtension(packedSint32Extension , 705);
+ message.addExtension(packedSint64Extension , 706L);
+ message.addExtension(packedFixed32Extension , 707);
+ message.addExtension(packedFixed64Extension , 708L);
+ message.addExtension(packedSfixed32Extension, 709);
+ message.addExtension(packedSfixed64Extension, 710L);
+ message.addExtension(packedFloatExtension , 711F);
+ message.addExtension(packedDoubleExtension , 712D);
+ message.addExtension(packedBoolExtension , false);
+ message.addExtension(packedEnumExtension, ForeignEnum.FOREIGN_BAZ);
+ }
+
+ public static void assertPackedExtensionsSet(TestPackedExtensions message) {
+ Assert.assertEquals(2, message.getExtensionCount(packedInt32Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(packedInt64Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(packedUint32Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(packedUint64Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(packedSint32Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(packedSint64Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(packedFixed32Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(packedFixed64Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(packedSfixed32Extension));
+ Assert.assertEquals(2, message.getExtensionCount(packedSfixed64Extension));
+ Assert.assertEquals(2, message.getExtensionCount(packedFloatExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(packedDoubleExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(packedBoolExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(packedEnumExtension));
+ assertEqualsExactType(601 , message.getExtension(packedInt32Extension , 0));
+ assertEqualsExactType(602L , message.getExtension(packedInt64Extension , 0));
+ assertEqualsExactType(603 , message.getExtension(packedUint32Extension , 0));
+ assertEqualsExactType(604L , message.getExtension(packedUint64Extension , 0));
+ assertEqualsExactType(605 , message.getExtension(packedSint32Extension , 0));
+ assertEqualsExactType(606L , message.getExtension(packedSint64Extension , 0));
+ assertEqualsExactType(607 , message.getExtension(packedFixed32Extension , 0));
+ assertEqualsExactType(608L , message.getExtension(packedFixed64Extension , 0));
+ assertEqualsExactType(609 , message.getExtension(packedSfixed32Extension, 0));
+ assertEqualsExactType(610L , message.getExtension(packedSfixed64Extension, 0));
+ assertEqualsExactType(611F , message.getExtension(packedFloatExtension , 0));
+ assertEqualsExactType(612D , message.getExtension(packedDoubleExtension , 0));
+ assertEqualsExactType(true , message.getExtension(packedBoolExtension , 0));
+ assertEqualsExactType(ForeignEnum.FOREIGN_BAR,
+ message.getExtension(packedEnumExtension, 0));
+ assertEqualsExactType(701 , message.getExtension(packedInt32Extension , 1));
+ assertEqualsExactType(702L , message.getExtension(packedInt64Extension , 1));
+ assertEqualsExactType(703 , message.getExtension(packedUint32Extension , 1));
+ assertEqualsExactType(704L , message.getExtension(packedUint64Extension , 1));
+ assertEqualsExactType(705 , message.getExtension(packedSint32Extension , 1));
+ assertEqualsExactType(706L , message.getExtension(packedSint64Extension , 1));
+ assertEqualsExactType(707 , message.getExtension(packedFixed32Extension , 1));
+ assertEqualsExactType(708L , message.getExtension(packedFixed64Extension , 1));
+ assertEqualsExactType(709 , message.getExtension(packedSfixed32Extension, 1));
+ assertEqualsExactType(710L , message.getExtension(packedSfixed64Extension, 1));
+ assertEqualsExactType(711F , message.getExtension(packedFloatExtension , 1));
+ assertEqualsExactType(712D , message.getExtension(packedDoubleExtension , 1));
+ assertEqualsExactType(false, message.getExtension(packedBoolExtension , 1));
+ assertEqualsExactType(ForeignEnum.FOREIGN_BAZ,
+ message.getExtension(packedEnumExtension, 1));
+ }
+
+ // =================================================================
+
+ /**
+ * Performs the same things that the methods of {@code TestUtil} do, but
+ * via the reflection interface. This is its own class because it needs
+ * to know what descriptor to use.
+ */
+ public static class ReflectionTester {
+ private final Descriptors.Descriptor baseDescriptor;
+ private final ExtensionRegistry extensionRegistry;
+
+ private final Descriptors.FileDescriptor file;
+ private final Descriptors.FileDescriptor importFile;
+ private final Descriptors.FileDescriptor publicImportFile;
+
+ private final Descriptors.Descriptor optionalGroup;
+ private final Descriptors.Descriptor repeatedGroup;
+ private final Descriptors.Descriptor nestedMessage;
+ private final Descriptors.Descriptor foreignMessage;
+ private final Descriptors.Descriptor importMessage;
+ private final Descriptors.Descriptor publicImportMessage;
+
+ private final Descriptors.FieldDescriptor groupA;
+ private final Descriptors.FieldDescriptor repeatedGroupA;
+ private final Descriptors.FieldDescriptor nestedB;
+ private final Descriptors.FieldDescriptor foreignC;
+ private final Descriptors.FieldDescriptor importD;
+ private final Descriptors.FieldDescriptor importE;
+
+ private final Descriptors.EnumDescriptor nestedEnum;
+ private final Descriptors.EnumDescriptor foreignEnum;
+ private final Descriptors.EnumDescriptor importEnum;
+
+ private final Descriptors.EnumValueDescriptor nestedFoo;
+ private final Descriptors.EnumValueDescriptor nestedBar;
+ private final Descriptors.EnumValueDescriptor nestedBaz;
+ private final Descriptors.EnumValueDescriptor foreignFoo;
+ private final Descriptors.EnumValueDescriptor foreignBar;
+ private final Descriptors.EnumValueDescriptor foreignBaz;
+ private final Descriptors.EnumValueDescriptor importFoo;
+ private final Descriptors.EnumValueDescriptor importBar;
+ private final Descriptors.EnumValueDescriptor importBaz;
+
+ /**
+ * Construct a {@code ReflectionTester} that will expect messages using
+ * the given descriptor.
+ *
+ * Normally {@code baseDescriptor} should be a descriptor for the type
+ * {@code TestAllTypes}, defined in
+ * {@code google/protobuf/unittest.proto}. However, if
+ * {@code extensionRegistry} is non-null, then {@code baseDescriptor} should
+ * be for {@code TestAllExtensions} instead, and instead of reading and
+ * writing normal fields, the tester will read and write extensions.
+ * All of {@code TestAllExtensions}' extensions must be registered in the
+ * registry.
+ */
+ public ReflectionTester(Descriptors.Descriptor baseDescriptor,
+ ExtensionRegistry extensionRegistry) {
+ this.baseDescriptor = baseDescriptor;
+ this.extensionRegistry = extensionRegistry;
+
+ this.file = baseDescriptor.getFile();
+ Assert.assertEquals(1, file.getDependencies().size());
+ this.importFile = file.getDependencies().get(0);
+ this.publicImportFile = importFile.getDependencies().get(0);
+
+ Descriptors.Descriptor testAllTypes;
+ if (baseDescriptor.getName() == "TestAllTypes") {
+ testAllTypes = baseDescriptor;
+ } else {
+ testAllTypes = file.findMessageTypeByName("TestAllTypes");
+ Assert.assertNotNull(testAllTypes);
+ }
+
+ if (extensionRegistry == null) {
+ // Use testAllTypes, rather than baseDescriptor, to allow
+ // initialization using TestPackedTypes descriptors. These objects
+ // won't be used by the methods for packed fields.
+ this.optionalGroup =
+ testAllTypes.findNestedTypeByName("OptionalGroup");
+ this.repeatedGroup =
+ testAllTypes.findNestedTypeByName("RepeatedGroup");
+ } else {
+ this.optionalGroup =
+ file.findMessageTypeByName("OptionalGroup_extension");
+ this.repeatedGroup =
+ file.findMessageTypeByName("RepeatedGroup_extension");
+ }
+ this.nestedMessage = testAllTypes.findNestedTypeByName("NestedMessage");
+ this.foreignMessage = file.findMessageTypeByName("ForeignMessage");
+ this.importMessage = importFile.findMessageTypeByName("ImportMessage");
+ this.publicImportMessage = publicImportFile.findMessageTypeByName(
+ "PublicImportMessage");
+
+ this.nestedEnum = testAllTypes.findEnumTypeByName("NestedEnum");
+ this.foreignEnum = file.findEnumTypeByName("ForeignEnum");
+ this.importEnum = importFile.findEnumTypeByName("ImportEnum");
+
+ Assert.assertNotNull(optionalGroup );
+ Assert.assertNotNull(repeatedGroup );
+ Assert.assertNotNull(nestedMessage );
+ Assert.assertNotNull(foreignMessage);
+ Assert.assertNotNull(importMessage );
+ Assert.assertNotNull(nestedEnum );
+ Assert.assertNotNull(foreignEnum );
+ Assert.assertNotNull(importEnum );
+
+ this.nestedB = nestedMessage .findFieldByName("bb");
+ this.foreignC = foreignMessage.findFieldByName("c");
+ this.importD = importMessage .findFieldByName("d");
+ this.importE = publicImportMessage.findFieldByName("e");
+ this.nestedFoo = nestedEnum.findValueByName("FOO");
+ this.nestedBar = nestedEnum.findValueByName("BAR");
+ this.nestedBaz = nestedEnum.findValueByName("BAZ");
+ this.foreignFoo = foreignEnum.findValueByName("FOREIGN_FOO");
+ this.foreignBar = foreignEnum.findValueByName("FOREIGN_BAR");
+ this.foreignBaz = foreignEnum.findValueByName("FOREIGN_BAZ");
+ this.importFoo = importEnum.findValueByName("IMPORT_FOO");
+ this.importBar = importEnum.findValueByName("IMPORT_BAR");
+ this.importBaz = importEnum.findValueByName("IMPORT_BAZ");
+
+ this.groupA = optionalGroup.findFieldByName("a");
+ this.repeatedGroupA = repeatedGroup.findFieldByName("a");
+
+ Assert.assertNotNull(groupA );
+ Assert.assertNotNull(repeatedGroupA);
+ Assert.assertNotNull(nestedB );
+ Assert.assertNotNull(foreignC );
+ Assert.assertNotNull(importD );
+ Assert.assertNotNull(importE );
+ Assert.assertNotNull(nestedFoo );
+ Assert.assertNotNull(nestedBar );
+ Assert.assertNotNull(nestedBaz );
+ Assert.assertNotNull(foreignFoo );
+ Assert.assertNotNull(foreignBar );
+ Assert.assertNotNull(foreignBaz );
+ Assert.assertNotNull(importFoo );
+ Assert.assertNotNull(importBar );
+ Assert.assertNotNull(importBaz );
+ }
+
+ /**
+ * Shorthand to get a FieldDescriptor for a field of unittest::TestAllTypes.
+ */
+ private Descriptors.FieldDescriptor f(String name) {
+ Descriptors.FieldDescriptor result;
+ if (extensionRegistry == null) {
+ result = baseDescriptor.findFieldByName(name);
+ } else {
+ result = file.findExtensionByName(name + "_extension");
+ }
+ Assert.assertNotNull(result);
+ return result;
+ }
+
+ /**
+ * Calls {@code parent.newBuilderForField()} or uses the
+ * {@code ExtensionRegistry} to find an appropriate builder, depending
+ * on what type is being tested.
+ */
+ private Message.Builder newBuilderForField(
+ Message.Builder parent, Descriptors.FieldDescriptor field) {
+ if (extensionRegistry == null) {
+ return parent.newBuilderForField(field);
+ } else {
+ ExtensionRegistry.ExtensionInfo extension =
+ extensionRegistry.findExtensionByNumber(field.getContainingType(),
+ field.getNumber());
+ Assert.assertNotNull(extension);
+ Assert.assertNotNull(extension.defaultInstance);
+ return extension.defaultInstance.newBuilderForType();
+ }
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Set every field of {@code message} to the values expected by
+ * {@code assertAllFieldsSet()}, using the {@link Message.Builder}
+ * reflection interface.
+ */
+ void setAllFieldsViaReflection(Message.Builder message) {
+ message.setField(f("optional_int32" ), 101 );
+ message.setField(f("optional_int64" ), 102L);
+ message.setField(f("optional_uint32" ), 103 );
+ message.setField(f("optional_uint64" ), 104L);
+ message.setField(f("optional_sint32" ), 105 );
+ message.setField(f("optional_sint64" ), 106L);
+ message.setField(f("optional_fixed32" ), 107 );
+ message.setField(f("optional_fixed64" ), 108L);
+ message.setField(f("optional_sfixed32"), 109 );
+ message.setField(f("optional_sfixed64"), 110L);
+ message.setField(f("optional_float" ), 111F);
+ message.setField(f("optional_double" ), 112D);
+ message.setField(f("optional_bool" ), true);
+ message.setField(f("optional_string" ), "115");
+ message.setField(f("optional_bytes" ), toBytes("116"));
+
+ message.setField(f("optionalgroup"),
+ newBuilderForField(message, f("optionalgroup"))
+ .setField(groupA, 117).build());
+ message.setField(f("optional_nested_message"),
+ newBuilderForField(message, f("optional_nested_message"))
+ .setField(nestedB, 118).build());
+ message.setField(f("optional_foreign_message"),
+ newBuilderForField(message, f("optional_foreign_message"))
+ .setField(foreignC, 119).build());
+ message.setField(f("optional_import_message"),
+ newBuilderForField(message, f("optional_import_message"))
+ .setField(importD, 120).build());
+ message.setField(f("optional_public_import_message"),
+ newBuilderForField(message, f("optional_public_import_message"))
+ .setField(importE, 126).build());
+ message.setField(f("optional_lazy_message"),
+ newBuilderForField(message, f("optional_lazy_message"))
+ .setField(nestedB, 127).build());
+
+ message.setField(f("optional_nested_enum" ), nestedBaz);
+ message.setField(f("optional_foreign_enum"), foreignBaz);
+ message.setField(f("optional_import_enum" ), importBaz);
+
+ message.setField(f("optional_string_piece" ), "124");
+ message.setField(f("optional_cord" ), "125");
+
+ // -----------------------------------------------------------------
+
+ message.addRepeatedField(f("repeated_int32" ), 201 );
+ message.addRepeatedField(f("repeated_int64" ), 202L);
+ message.addRepeatedField(f("repeated_uint32" ), 203 );
+ message.addRepeatedField(f("repeated_uint64" ), 204L);
+ message.addRepeatedField(f("repeated_sint32" ), 205 );
+ message.addRepeatedField(f("repeated_sint64" ), 206L);
+ message.addRepeatedField(f("repeated_fixed32" ), 207 );
+ message.addRepeatedField(f("repeated_fixed64" ), 208L);
+ message.addRepeatedField(f("repeated_sfixed32"), 209 );
+ message.addRepeatedField(f("repeated_sfixed64"), 210L);
+ message.addRepeatedField(f("repeated_float" ), 211F);
+ message.addRepeatedField(f("repeated_double" ), 212D);
+ message.addRepeatedField(f("repeated_bool" ), true);
+ message.addRepeatedField(f("repeated_string" ), "215");
+ message.addRepeatedField(f("repeated_bytes" ), toBytes("216"));
+
+ message.addRepeatedField(f("repeatedgroup"),
+ newBuilderForField(message, f("repeatedgroup"))
+ .setField(repeatedGroupA, 217).build());
+ message.addRepeatedField(f("repeated_nested_message"),
+ newBuilderForField(message, f("repeated_nested_message"))
+ .setField(nestedB, 218).build());
+ message.addRepeatedField(f("repeated_foreign_message"),
+ newBuilderForField(message, f("repeated_foreign_message"))
+ .setField(foreignC, 219).build());
+ message.addRepeatedField(f("repeated_import_message"),
+ newBuilderForField(message, f("repeated_import_message"))
+ .setField(importD, 220).build());
+ message.addRepeatedField(f("repeated_lazy_message"),
+ newBuilderForField(message, f("repeated_lazy_message"))
+ .setField(nestedB, 227).build());
+
+ message.addRepeatedField(f("repeated_nested_enum" ), nestedBar);
+ message.addRepeatedField(f("repeated_foreign_enum"), foreignBar);
+ message.addRepeatedField(f("repeated_import_enum" ), importBar);
+
+ message.addRepeatedField(f("repeated_string_piece" ), "224");
+ message.addRepeatedField(f("repeated_cord" ), "225");
+
+ // Add a second one of each field.
+ message.addRepeatedField(f("repeated_int32" ), 301 );
+ message.addRepeatedField(f("repeated_int64" ), 302L);
+ message.addRepeatedField(f("repeated_uint32" ), 303 );
+ message.addRepeatedField(f("repeated_uint64" ), 304L);
+ message.addRepeatedField(f("repeated_sint32" ), 305 );
+ message.addRepeatedField(f("repeated_sint64" ), 306L);
+ message.addRepeatedField(f("repeated_fixed32" ), 307 );
+ message.addRepeatedField(f("repeated_fixed64" ), 308L);
+ message.addRepeatedField(f("repeated_sfixed32"), 309 );
+ message.addRepeatedField(f("repeated_sfixed64"), 310L);
+ message.addRepeatedField(f("repeated_float" ), 311F);
+ message.addRepeatedField(f("repeated_double" ), 312D);
+ message.addRepeatedField(f("repeated_bool" ), false);
+ message.addRepeatedField(f("repeated_string" ), "315");
+ message.addRepeatedField(f("repeated_bytes" ), toBytes("316"));
+
+ message.addRepeatedField(f("repeatedgroup"),
+ newBuilderForField(message, f("repeatedgroup"))
+ .setField(repeatedGroupA, 317).build());
+ message.addRepeatedField(f("repeated_nested_message"),
+ newBuilderForField(message, f("repeated_nested_message"))
+ .setField(nestedB, 318).build());
+ message.addRepeatedField(f("repeated_foreign_message"),
+ newBuilderForField(message, f("repeated_foreign_message"))
+ .setField(foreignC, 319).build());
+ message.addRepeatedField(f("repeated_import_message"),
+ newBuilderForField(message, f("repeated_import_message"))
+ .setField(importD, 320).build());
+ message.addRepeatedField(f("repeated_lazy_message"),
+ newBuilderForField(message, f("repeated_lazy_message"))
+ .setField(nestedB, 327).build());
+
+ message.addRepeatedField(f("repeated_nested_enum" ), nestedBaz);
+ message.addRepeatedField(f("repeated_foreign_enum"), foreignBaz);
+ message.addRepeatedField(f("repeated_import_enum" ), importBaz);
+
+ message.addRepeatedField(f("repeated_string_piece" ), "324");
+ message.addRepeatedField(f("repeated_cord" ), "325");
+
+ // -----------------------------------------------------------------
+
+ message.setField(f("default_int32" ), 401 );
+ message.setField(f("default_int64" ), 402L);
+ message.setField(f("default_uint32" ), 403 );
+ message.setField(f("default_uint64" ), 404L);
+ message.setField(f("default_sint32" ), 405 );
+ message.setField(f("default_sint64" ), 406L);
+ message.setField(f("default_fixed32" ), 407 );
+ message.setField(f("default_fixed64" ), 408L);
+ message.setField(f("default_sfixed32"), 409 );
+ message.setField(f("default_sfixed64"), 410L);
+ message.setField(f("default_float" ), 411F);
+ message.setField(f("default_double" ), 412D);
+ message.setField(f("default_bool" ), false);
+ message.setField(f("default_string" ), "415");
+ message.setField(f("default_bytes" ), toBytes("416"));
+
+ message.setField(f("default_nested_enum" ), nestedFoo);
+ message.setField(f("default_foreign_enum"), foreignFoo);
+ message.setField(f("default_import_enum" ), importFoo);
+
+ message.setField(f("default_string_piece" ), "424");
+ message.setField(f("default_cord" ), "425");
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Modify the repeated fields of {@code message} to contain the values
+ * expected by {@code assertRepeatedFieldsModified()}, using the
+ * {@link Message.Builder} reflection interface.
+ */
+ void modifyRepeatedFieldsViaReflection(Message.Builder message) {
+ message.setRepeatedField(f("repeated_int32" ), 1, 501 );
+ message.setRepeatedField(f("repeated_int64" ), 1, 502L);
+ message.setRepeatedField(f("repeated_uint32" ), 1, 503 );
+ message.setRepeatedField(f("repeated_uint64" ), 1, 504L);
+ message.setRepeatedField(f("repeated_sint32" ), 1, 505 );
+ message.setRepeatedField(f("repeated_sint64" ), 1, 506L);
+ message.setRepeatedField(f("repeated_fixed32" ), 1, 507 );
+ message.setRepeatedField(f("repeated_fixed64" ), 1, 508L);
+ message.setRepeatedField(f("repeated_sfixed32"), 1, 509 );
+ message.setRepeatedField(f("repeated_sfixed64"), 1, 510L);
+ message.setRepeatedField(f("repeated_float" ), 1, 511F);
+ message.setRepeatedField(f("repeated_double" ), 1, 512D);
+ message.setRepeatedField(f("repeated_bool" ), 1, true);
+ message.setRepeatedField(f("repeated_string" ), 1, "515");
+ message.setRepeatedField(f("repeated_bytes" ), 1, toBytes("516"));
+
+ message.setRepeatedField(f("repeatedgroup"), 1,
+ newBuilderForField(message, f("repeatedgroup"))
+ .setField(repeatedGroupA, 517).build());
+ message.setRepeatedField(f("repeated_nested_message"), 1,
+ newBuilderForField(message, f("repeated_nested_message"))
+ .setField(nestedB, 518).build());
+ message.setRepeatedField(f("repeated_foreign_message"), 1,
+ newBuilderForField(message, f("repeated_foreign_message"))
+ .setField(foreignC, 519).build());
+ message.setRepeatedField(f("repeated_import_message"), 1,
+ newBuilderForField(message, f("repeated_import_message"))
+ .setField(importD, 520).build());
+ message.setRepeatedField(f("repeated_lazy_message"), 1,
+ newBuilderForField(message, f("repeated_lazy_message"))
+ .setField(nestedB, 527).build());
+
+ message.setRepeatedField(f("repeated_nested_enum" ), 1, nestedFoo);
+ message.setRepeatedField(f("repeated_foreign_enum"), 1, foreignFoo);
+ message.setRepeatedField(f("repeated_import_enum" ), 1, importFoo);
+
+ message.setRepeatedField(f("repeated_string_piece"), 1, "524");
+ message.setRepeatedField(f("repeated_cord"), 1, "525");
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Assert (using {@code junit.framework.Assert}} that all fields of
+ * {@code message} are set to the values assigned by {@code setAllFields},
+ * using the {@link Message} reflection interface.
+ */
+ public void assertAllFieldsSetViaReflection(MessageOrBuilder message) {
+ Assert.assertTrue(message.hasField(f("optional_int32" )));
+ Assert.assertTrue(message.hasField(f("optional_int64" )));
+ Assert.assertTrue(message.hasField(f("optional_uint32" )));
+ Assert.assertTrue(message.hasField(f("optional_uint64" )));
+ Assert.assertTrue(message.hasField(f("optional_sint32" )));
+ Assert.assertTrue(message.hasField(f("optional_sint64" )));
+ Assert.assertTrue(message.hasField(f("optional_fixed32" )));
+ Assert.assertTrue(message.hasField(f("optional_fixed64" )));
+ Assert.assertTrue(message.hasField(f("optional_sfixed32")));
+ Assert.assertTrue(message.hasField(f("optional_sfixed64")));
+ Assert.assertTrue(message.hasField(f("optional_float" )));
+ Assert.assertTrue(message.hasField(f("optional_double" )));
+ Assert.assertTrue(message.hasField(f("optional_bool" )));
+ Assert.assertTrue(message.hasField(f("optional_string" )));
+ Assert.assertTrue(message.hasField(f("optional_bytes" )));
+
+ Assert.assertTrue(message.hasField(f("optionalgroup" )));
+ Assert.assertTrue(message.hasField(f("optional_nested_message" )));
+ Assert.assertTrue(message.hasField(f("optional_foreign_message")));
+ Assert.assertTrue(message.hasField(f("optional_import_message" )));
+
+ Assert.assertTrue(
+ ((Message)message.getField(f("optionalgroup"))).hasField(groupA));
+ Assert.assertTrue(
+ ((Message)message.getField(f("optional_nested_message")))
+ .hasField(nestedB));
+ Assert.assertTrue(
+ ((Message)message.getField(f("optional_foreign_message")))
+ .hasField(foreignC));
+ Assert.assertTrue(
+ ((Message)message.getField(f("optional_import_message")))
+ .hasField(importD));
+
+ Assert.assertTrue(message.hasField(f("optional_nested_enum" )));
+ Assert.assertTrue(message.hasField(f("optional_foreign_enum")));
+ Assert.assertTrue(message.hasField(f("optional_import_enum" )));
+
+ Assert.assertTrue(message.hasField(f("optional_string_piece")));
+ Assert.assertTrue(message.hasField(f("optional_cord")));
+
+ Assert.assertEquals(101 , message.getField(f("optional_int32" )));
+ Assert.assertEquals(102L , message.getField(f("optional_int64" )));
+ Assert.assertEquals(103 , message.getField(f("optional_uint32" )));
+ Assert.assertEquals(104L , message.getField(f("optional_uint64" )));
+ Assert.assertEquals(105 , message.getField(f("optional_sint32" )));
+ Assert.assertEquals(106L , message.getField(f("optional_sint64" )));
+ Assert.assertEquals(107 , message.getField(f("optional_fixed32" )));
+ Assert.assertEquals(108L , message.getField(f("optional_fixed64" )));
+ Assert.assertEquals(109 , message.getField(f("optional_sfixed32")));
+ Assert.assertEquals(110L , message.getField(f("optional_sfixed64")));
+ Assert.assertEquals(111F , message.getField(f("optional_float" )));
+ Assert.assertEquals(112D , message.getField(f("optional_double" )));
+ Assert.assertEquals(true , message.getField(f("optional_bool" )));
+ Assert.assertEquals("115", message.getField(f("optional_string" )));
+ Assert.assertEquals(toBytes("116"), message.getField(f("optional_bytes")));
+
+ Assert.assertEquals(117,
+ ((Message)message.getField(f("optionalgroup"))).getField(groupA));
+ Assert.assertEquals(118,
+ ((Message)message.getField(f("optional_nested_message")))
+ .getField(nestedB));
+ Assert.assertEquals(119,
+ ((Message)message.getField(f("optional_foreign_message")))
+ .getField(foreignC));
+ Assert.assertEquals(120,
+ ((Message)message.getField(f("optional_import_message")))
+ .getField(importD));
+ Assert.assertEquals(126,
+ ((Message)message.getField(f("optional_public_import_message")))
+ .getField(importE));
+ Assert.assertEquals(127,
+ ((Message)message.getField(f("optional_lazy_message")))
+ .getField(nestedB));
+
+ Assert.assertEquals( nestedBaz, message.getField(f("optional_nested_enum" )));
+ Assert.assertEquals(foreignBaz, message.getField(f("optional_foreign_enum")));
+ Assert.assertEquals( importBaz, message.getField(f("optional_import_enum" )));
+
+ Assert.assertEquals("124", message.getField(f("optional_string_piece")));
+ Assert.assertEquals("125", message.getField(f("optional_cord")));
+
+ // -----------------------------------------------------------------
+
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_int32" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_int64" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_uint32" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_uint64" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_sint32" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_sint64" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_fixed32" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_fixed64" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_sfixed32")));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_sfixed64")));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_float" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_double" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_bool" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_string" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_bytes" )));
+
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeatedgroup" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_nested_message" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_foreign_message")));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_import_message" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_lazy_message" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_nested_enum" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_foreign_enum" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_import_enum" )));
+
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_string_piece")));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_cord")));
+
+ Assert.assertEquals(201 , message.getRepeatedField(f("repeated_int32" ), 0));
+ Assert.assertEquals(202L , message.getRepeatedField(f("repeated_int64" ), 0));
+ Assert.assertEquals(203 , message.getRepeatedField(f("repeated_uint32" ), 0));
+ Assert.assertEquals(204L , message.getRepeatedField(f("repeated_uint64" ), 0));
+ Assert.assertEquals(205 , message.getRepeatedField(f("repeated_sint32" ), 0));
+ Assert.assertEquals(206L , message.getRepeatedField(f("repeated_sint64" ), 0));
+ Assert.assertEquals(207 , message.getRepeatedField(f("repeated_fixed32" ), 0));
+ Assert.assertEquals(208L , message.getRepeatedField(f("repeated_fixed64" ), 0));
+ Assert.assertEquals(209 , message.getRepeatedField(f("repeated_sfixed32"), 0));
+ Assert.assertEquals(210L , message.getRepeatedField(f("repeated_sfixed64"), 0));
+ Assert.assertEquals(211F , message.getRepeatedField(f("repeated_float" ), 0));
+ Assert.assertEquals(212D , message.getRepeatedField(f("repeated_double" ), 0));
+ Assert.assertEquals(true , message.getRepeatedField(f("repeated_bool" ), 0));
+ Assert.assertEquals("215", message.getRepeatedField(f("repeated_string" ), 0));
+ Assert.assertEquals(toBytes("216"), message.getRepeatedField(f("repeated_bytes"), 0));
+
+ Assert.assertEquals(217,
+ ((Message)message.getRepeatedField(f("repeatedgroup"), 0))
+ .getField(repeatedGroupA));
+ Assert.assertEquals(218,
+ ((Message)message.getRepeatedField(f("repeated_nested_message"), 0))
+ .getField(nestedB));
+ Assert.assertEquals(219,
+ ((Message)message.getRepeatedField(f("repeated_foreign_message"), 0))
+ .getField(foreignC));
+ Assert.assertEquals(220,
+ ((Message)message.getRepeatedField(f("repeated_import_message"), 0))
+ .getField(importD));
+ Assert.assertEquals(227,
+ ((Message)message.getRepeatedField(f("repeated_lazy_message"), 0))
+ .getField(nestedB));
+
+ Assert.assertEquals( nestedBar, message.getRepeatedField(f("repeated_nested_enum" ),0));
+ Assert.assertEquals(foreignBar, message.getRepeatedField(f("repeated_foreign_enum"),0));
+ Assert.assertEquals( importBar, message.getRepeatedField(f("repeated_import_enum" ),0));
+
+ Assert.assertEquals("224", message.getRepeatedField(f("repeated_string_piece"), 0));
+ Assert.assertEquals("225", message.getRepeatedField(f("repeated_cord"), 0));
+
+ Assert.assertEquals(301 , message.getRepeatedField(f("repeated_int32" ), 1));
+ Assert.assertEquals(302L , message.getRepeatedField(f("repeated_int64" ), 1));
+ Assert.assertEquals(303 , message.getRepeatedField(f("repeated_uint32" ), 1));
+ Assert.assertEquals(304L , message.getRepeatedField(f("repeated_uint64" ), 1));
+ Assert.assertEquals(305 , message.getRepeatedField(f("repeated_sint32" ), 1));
+ Assert.assertEquals(306L , message.getRepeatedField(f("repeated_sint64" ), 1));
+ Assert.assertEquals(307 , message.getRepeatedField(f("repeated_fixed32" ), 1));
+ Assert.assertEquals(308L , message.getRepeatedField(f("repeated_fixed64" ), 1));
+ Assert.assertEquals(309 , message.getRepeatedField(f("repeated_sfixed32"), 1));
+ Assert.assertEquals(310L , message.getRepeatedField(f("repeated_sfixed64"), 1));
+ Assert.assertEquals(311F , message.getRepeatedField(f("repeated_float" ), 1));
+ Assert.assertEquals(312D , message.getRepeatedField(f("repeated_double" ), 1));
+ Assert.assertEquals(false, message.getRepeatedField(f("repeated_bool" ), 1));
+ Assert.assertEquals("315", message.getRepeatedField(f("repeated_string" ), 1));
+ Assert.assertEquals(toBytes("316"), message.getRepeatedField(f("repeated_bytes"), 1));
+
+ Assert.assertEquals(317,
+ ((Message)message.getRepeatedField(f("repeatedgroup"), 1))
+ .getField(repeatedGroupA));
+ Assert.assertEquals(318,
+ ((Message)message.getRepeatedField(f("repeated_nested_message"), 1))
+ .getField(nestedB));
+ Assert.assertEquals(319,
+ ((Message)message.getRepeatedField(f("repeated_foreign_message"), 1))
+ .getField(foreignC));
+ Assert.assertEquals(320,
+ ((Message)message.getRepeatedField(f("repeated_import_message"), 1))
+ .getField(importD));
+ Assert.assertEquals(327,
+ ((Message)message.getRepeatedField(f("repeated_lazy_message"), 1))
+ .getField(nestedB));
+
+ Assert.assertEquals( nestedBaz, message.getRepeatedField(f("repeated_nested_enum" ),1));
+ Assert.assertEquals(foreignBaz, message.getRepeatedField(f("repeated_foreign_enum"),1));
+ Assert.assertEquals( importBaz, message.getRepeatedField(f("repeated_import_enum" ),1));
+
+ Assert.assertEquals("324", message.getRepeatedField(f("repeated_string_piece"), 1));
+ Assert.assertEquals("325", message.getRepeatedField(f("repeated_cord"), 1));
+
+ // -----------------------------------------------------------------
+
+ Assert.assertTrue(message.hasField(f("default_int32" )));
+ Assert.assertTrue(message.hasField(f("default_int64" )));
+ Assert.assertTrue(message.hasField(f("default_uint32" )));
+ Assert.assertTrue(message.hasField(f("default_uint64" )));
+ Assert.assertTrue(message.hasField(f("default_sint32" )));
+ Assert.assertTrue(message.hasField(f("default_sint64" )));
+ Assert.assertTrue(message.hasField(f("default_fixed32" )));
+ Assert.assertTrue(message.hasField(f("default_fixed64" )));
+ Assert.assertTrue(message.hasField(f("default_sfixed32")));
+ Assert.assertTrue(message.hasField(f("default_sfixed64")));
+ Assert.assertTrue(message.hasField(f("default_float" )));
+ Assert.assertTrue(message.hasField(f("default_double" )));
+ Assert.assertTrue(message.hasField(f("default_bool" )));
+ Assert.assertTrue(message.hasField(f("default_string" )));
+ Assert.assertTrue(message.hasField(f("default_bytes" )));
+
+ Assert.assertTrue(message.hasField(f("default_nested_enum" )));
+ Assert.assertTrue(message.hasField(f("default_foreign_enum")));
+ Assert.assertTrue(message.hasField(f("default_import_enum" )));
+
+ Assert.assertTrue(message.hasField(f("default_string_piece")));
+ Assert.assertTrue(message.hasField(f("default_cord")));
+
+ Assert.assertEquals(401 , message.getField(f("default_int32" )));
+ Assert.assertEquals(402L , message.getField(f("default_int64" )));
+ Assert.assertEquals(403 , message.getField(f("default_uint32" )));
+ Assert.assertEquals(404L , message.getField(f("default_uint64" )));
+ Assert.assertEquals(405 , message.getField(f("default_sint32" )));
+ Assert.assertEquals(406L , message.getField(f("default_sint64" )));
+ Assert.assertEquals(407 , message.getField(f("default_fixed32" )));
+ Assert.assertEquals(408L , message.getField(f("default_fixed64" )));
+ Assert.assertEquals(409 , message.getField(f("default_sfixed32")));
+ Assert.assertEquals(410L , message.getField(f("default_sfixed64")));
+ Assert.assertEquals(411F , message.getField(f("default_float" )));
+ Assert.assertEquals(412D , message.getField(f("default_double" )));
+ Assert.assertEquals(false, message.getField(f("default_bool" )));
+ Assert.assertEquals("415", message.getField(f("default_string" )));
+ Assert.assertEquals(toBytes("416"), message.getField(f("default_bytes")));
+
+ Assert.assertEquals( nestedFoo, message.getField(f("default_nested_enum" )));
+ Assert.assertEquals(foreignFoo, message.getField(f("default_foreign_enum")));
+ Assert.assertEquals( importFoo, message.getField(f("default_import_enum" )));
+
+ Assert.assertEquals("424", message.getField(f("default_string_piece")));
+ Assert.assertEquals("425", message.getField(f("default_cord")));
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Assert (using {@code junit.framework.Assert}} that all fields of
+ * {@code message} are cleared, and that getting the fields returns their
+ * default values, using the {@link Message} reflection interface.
+ */
+ public void assertClearViaReflection(MessageOrBuilder message) {
+ // has_blah() should initially be false for all optional fields.
+ Assert.assertFalse(message.hasField(f("optional_int32" )));
+ Assert.assertFalse(message.hasField(f("optional_int64" )));
+ Assert.assertFalse(message.hasField(f("optional_uint32" )));
+ Assert.assertFalse(message.hasField(f("optional_uint64" )));
+ Assert.assertFalse(message.hasField(f("optional_sint32" )));
+ Assert.assertFalse(message.hasField(f("optional_sint64" )));
+ Assert.assertFalse(message.hasField(f("optional_fixed32" )));
+ Assert.assertFalse(message.hasField(f("optional_fixed64" )));
+ Assert.assertFalse(message.hasField(f("optional_sfixed32")));
+ Assert.assertFalse(message.hasField(f("optional_sfixed64")));
+ Assert.assertFalse(message.hasField(f("optional_float" )));
+ Assert.assertFalse(message.hasField(f("optional_double" )));
+ Assert.assertFalse(message.hasField(f("optional_bool" )));
+ Assert.assertFalse(message.hasField(f("optional_string" )));
+ Assert.assertFalse(message.hasField(f("optional_bytes" )));
+
+ Assert.assertFalse(message.hasField(f("optionalgroup" )));
+ Assert.assertFalse(message.hasField(f("optional_nested_message" )));
+ Assert.assertFalse(message.hasField(f("optional_foreign_message")));
+ Assert.assertFalse(message.hasField(f("optional_import_message" )));
+
+ Assert.assertFalse(message.hasField(f("optional_nested_enum" )));
+ Assert.assertFalse(message.hasField(f("optional_foreign_enum")));
+ Assert.assertFalse(message.hasField(f("optional_import_enum" )));
+
+ Assert.assertFalse(message.hasField(f("optional_string_piece")));
+ Assert.assertFalse(message.hasField(f("optional_cord")));
+
+ // Optional fields without defaults are set to zero or something like it.
+ Assert.assertEquals(0 , message.getField(f("optional_int32" )));
+ Assert.assertEquals(0L , message.getField(f("optional_int64" )));
+ Assert.assertEquals(0 , message.getField(f("optional_uint32" )));
+ Assert.assertEquals(0L , message.getField(f("optional_uint64" )));
+ Assert.assertEquals(0 , message.getField(f("optional_sint32" )));
+ Assert.assertEquals(0L , message.getField(f("optional_sint64" )));
+ Assert.assertEquals(0 , message.getField(f("optional_fixed32" )));
+ Assert.assertEquals(0L , message.getField(f("optional_fixed64" )));
+ Assert.assertEquals(0 , message.getField(f("optional_sfixed32")));
+ Assert.assertEquals(0L , message.getField(f("optional_sfixed64")));
+ Assert.assertEquals(0F , message.getField(f("optional_float" )));
+ Assert.assertEquals(0D , message.getField(f("optional_double" )));
+ Assert.assertEquals(false, message.getField(f("optional_bool" )));
+ Assert.assertEquals("" , message.getField(f("optional_string" )));
+ Assert.assertEquals(ByteString.EMPTY, message.getField(f("optional_bytes")));
+
+ // Embedded messages should also be clear.
+ Assert.assertFalse(
+ ((Message)message.getField(f("optionalgroup"))).hasField(groupA));
+ Assert.assertFalse(
+ ((Message)message.getField(f("optional_nested_message")))
+ .hasField(nestedB));
+ Assert.assertFalse(
+ ((Message)message.getField(f("optional_foreign_message")))
+ .hasField(foreignC));
+ Assert.assertFalse(
+ ((Message)message.getField(f("optional_import_message")))
+ .hasField(importD));
+ Assert.assertFalse(
+ ((Message)message.getField(f("optional_public_import_message")))
+ .hasField(importE));
+ Assert.assertFalse(
+ ((Message)message.getField(f("optional_lazy_message")))
+ .hasField(nestedB));
+
+ Assert.assertEquals(0,
+ ((Message)message.getField(f("optionalgroup"))).getField(groupA));
+ Assert.assertEquals(0,
+ ((Message)message.getField(f("optional_nested_message")))
+ .getField(nestedB));
+ Assert.assertEquals(0,
+ ((Message)message.getField(f("optional_foreign_message")))
+ .getField(foreignC));
+ Assert.assertEquals(0,
+ ((Message)message.getField(f("optional_import_message")))
+ .getField(importD));
+ Assert.assertEquals(0,
+ ((Message)message.getField(f("optional_public_import_message")))
+ .getField(importE));
+ Assert.assertEquals(0,
+ ((Message)message.getField(f("optional_lazy_message")))
+ .getField(nestedB));
+
+ // Enums without defaults are set to the first value in the enum.
+ Assert.assertEquals( nestedFoo, message.getField(f("optional_nested_enum" )));
+ Assert.assertEquals(foreignFoo, message.getField(f("optional_foreign_enum")));
+ Assert.assertEquals( importFoo, message.getField(f("optional_import_enum" )));
+
+ Assert.assertEquals("", message.getField(f("optional_string_piece")));
+ Assert.assertEquals("", message.getField(f("optional_cord")));
+
+ // Repeated fields are empty.
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_int32" )));
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_int64" )));
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_uint32" )));
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_uint64" )));
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_sint32" )));
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_sint64" )));
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_fixed32" )));
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_fixed64" )));
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_sfixed32")));
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_sfixed64")));
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_float" )));
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_double" )));
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_bool" )));
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_string" )));
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_bytes" )));
+
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeatedgroup" )));
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_nested_message" )));
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_foreign_message")));
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_import_message" )));
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_lazy_message" )));
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_nested_enum" )));
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_foreign_enum" )));
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_import_enum" )));
+
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_string_piece")));
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_cord")));
+
+ // has_blah() should also be false for all default fields.
+ Assert.assertFalse(message.hasField(f("default_int32" )));
+ Assert.assertFalse(message.hasField(f("default_int64" )));
+ Assert.assertFalse(message.hasField(f("default_uint32" )));
+ Assert.assertFalse(message.hasField(f("default_uint64" )));
+ Assert.assertFalse(message.hasField(f("default_sint32" )));
+ Assert.assertFalse(message.hasField(f("default_sint64" )));
+ Assert.assertFalse(message.hasField(f("default_fixed32" )));
+ Assert.assertFalse(message.hasField(f("default_fixed64" )));
+ Assert.assertFalse(message.hasField(f("default_sfixed32")));
+ Assert.assertFalse(message.hasField(f("default_sfixed64")));
+ Assert.assertFalse(message.hasField(f("default_float" )));
+ Assert.assertFalse(message.hasField(f("default_double" )));
+ Assert.assertFalse(message.hasField(f("default_bool" )));
+ Assert.assertFalse(message.hasField(f("default_string" )));
+ Assert.assertFalse(message.hasField(f("default_bytes" )));
+
+ Assert.assertFalse(message.hasField(f("default_nested_enum" )));
+ Assert.assertFalse(message.hasField(f("default_foreign_enum")));
+ Assert.assertFalse(message.hasField(f("default_import_enum" )));
+
+ Assert.assertFalse(message.hasField(f("default_string_piece" )));
+ Assert.assertFalse(message.hasField(f("default_cord" )));
+
+ // Fields with defaults have their default values (duh).
+ Assert.assertEquals( 41 , message.getField(f("default_int32" )));
+ Assert.assertEquals( 42L , message.getField(f("default_int64" )));
+ Assert.assertEquals( 43 , message.getField(f("default_uint32" )));
+ Assert.assertEquals( 44L , message.getField(f("default_uint64" )));
+ Assert.assertEquals(-45 , message.getField(f("default_sint32" )));
+ Assert.assertEquals( 46L , message.getField(f("default_sint64" )));
+ Assert.assertEquals( 47 , message.getField(f("default_fixed32" )));
+ Assert.assertEquals( 48L , message.getField(f("default_fixed64" )));
+ Assert.assertEquals( 49 , message.getField(f("default_sfixed32")));
+ Assert.assertEquals(-50L , message.getField(f("default_sfixed64")));
+ Assert.assertEquals( 51.5F , message.getField(f("default_float" )));
+ Assert.assertEquals( 52e3D , message.getField(f("default_double" )));
+ Assert.assertEquals(true , message.getField(f("default_bool" )));
+ Assert.assertEquals("hello", message.getField(f("default_string" )));
+ Assert.assertEquals(toBytes("world"), message.getField(f("default_bytes")));
+
+ Assert.assertEquals( nestedBar, message.getField(f("default_nested_enum" )));
+ Assert.assertEquals(foreignBar, message.getField(f("default_foreign_enum")));
+ Assert.assertEquals( importBar, message.getField(f("default_import_enum" )));
+
+ Assert.assertEquals("abc", message.getField(f("default_string_piece")));
+ Assert.assertEquals("123", message.getField(f("default_cord")));
+ }
+
+
+ // ---------------------------------------------------------------
+
+ public void assertRepeatedFieldsModifiedViaReflection(
+ MessageOrBuilder message) {
+ // ModifyRepeatedFields only sets the second repeated element of each
+ // field. In addition to verifying this, we also verify that the first
+ // element and size were *not* modified.
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_int32" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_int64" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_uint32" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_uint64" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_sint32" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_sint64" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_fixed32" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_fixed64" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_sfixed32")));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_sfixed64")));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_float" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_double" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_bool" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_string" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_bytes" )));
+
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeatedgroup" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_nested_message" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_foreign_message")));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_import_message" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_lazy_message" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_nested_enum" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_foreign_enum" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_import_enum" )));
+
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_string_piece")));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_cord")));
+
+ Assert.assertEquals(201 , message.getRepeatedField(f("repeated_int32" ), 0));
+ Assert.assertEquals(202L , message.getRepeatedField(f("repeated_int64" ), 0));
+ Assert.assertEquals(203 , message.getRepeatedField(f("repeated_uint32" ), 0));
+ Assert.assertEquals(204L , message.getRepeatedField(f("repeated_uint64" ), 0));
+ Assert.assertEquals(205 , message.getRepeatedField(f("repeated_sint32" ), 0));
+ Assert.assertEquals(206L , message.getRepeatedField(f("repeated_sint64" ), 0));
+ Assert.assertEquals(207 , message.getRepeatedField(f("repeated_fixed32" ), 0));
+ Assert.assertEquals(208L , message.getRepeatedField(f("repeated_fixed64" ), 0));
+ Assert.assertEquals(209 , message.getRepeatedField(f("repeated_sfixed32"), 0));
+ Assert.assertEquals(210L , message.getRepeatedField(f("repeated_sfixed64"), 0));
+ Assert.assertEquals(211F , message.getRepeatedField(f("repeated_float" ), 0));
+ Assert.assertEquals(212D , message.getRepeatedField(f("repeated_double" ), 0));
+ Assert.assertEquals(true , message.getRepeatedField(f("repeated_bool" ), 0));
+ Assert.assertEquals("215", message.getRepeatedField(f("repeated_string" ), 0));
+ Assert.assertEquals(toBytes("216"), message.getRepeatedField(f("repeated_bytes"), 0));
+
+ Assert.assertEquals(217,
+ ((Message)message.getRepeatedField(f("repeatedgroup"), 0))
+ .getField(repeatedGroupA));
+ Assert.assertEquals(218,
+ ((Message)message.getRepeatedField(f("repeated_nested_message"), 0))
+ .getField(nestedB));
+ Assert.assertEquals(219,
+ ((Message)message.getRepeatedField(f("repeated_foreign_message"), 0))
+ .getField(foreignC));
+ Assert.assertEquals(220,
+ ((Message)message.getRepeatedField(f("repeated_import_message"), 0))
+ .getField(importD));
+ Assert.assertEquals(227,
+ ((Message)message.getRepeatedField(f("repeated_lazy_message"), 0))
+ .getField(nestedB));
+
+ Assert.assertEquals( nestedBar, message.getRepeatedField(f("repeated_nested_enum" ),0));
+ Assert.assertEquals(foreignBar, message.getRepeatedField(f("repeated_foreign_enum"),0));
+ Assert.assertEquals( importBar, message.getRepeatedField(f("repeated_import_enum" ),0));
+
+ Assert.assertEquals("224", message.getRepeatedField(f("repeated_string_piece"), 0));
+ Assert.assertEquals("225", message.getRepeatedField(f("repeated_cord"), 0));
+
+ Assert.assertEquals(501 , message.getRepeatedField(f("repeated_int32" ), 1));
+ Assert.assertEquals(502L , message.getRepeatedField(f("repeated_int64" ), 1));
+ Assert.assertEquals(503 , message.getRepeatedField(f("repeated_uint32" ), 1));
+ Assert.assertEquals(504L , message.getRepeatedField(f("repeated_uint64" ), 1));
+ Assert.assertEquals(505 , message.getRepeatedField(f("repeated_sint32" ), 1));
+ Assert.assertEquals(506L , message.getRepeatedField(f("repeated_sint64" ), 1));
+ Assert.assertEquals(507 , message.getRepeatedField(f("repeated_fixed32" ), 1));
+ Assert.assertEquals(508L , message.getRepeatedField(f("repeated_fixed64" ), 1));
+ Assert.assertEquals(509 , message.getRepeatedField(f("repeated_sfixed32"), 1));
+ Assert.assertEquals(510L , message.getRepeatedField(f("repeated_sfixed64"), 1));
+ Assert.assertEquals(511F , message.getRepeatedField(f("repeated_float" ), 1));
+ Assert.assertEquals(512D , message.getRepeatedField(f("repeated_double" ), 1));
+ Assert.assertEquals(true , message.getRepeatedField(f("repeated_bool" ), 1));
+ Assert.assertEquals("515", message.getRepeatedField(f("repeated_string" ), 1));
+ Assert.assertEquals(toBytes("516"), message.getRepeatedField(f("repeated_bytes"), 1));
+
+ Assert.assertEquals(517,
+ ((Message)message.getRepeatedField(f("repeatedgroup"), 1))
+ .getField(repeatedGroupA));
+ Assert.assertEquals(518,
+ ((Message)message.getRepeatedField(f("repeated_nested_message"), 1))
+ .getField(nestedB));
+ Assert.assertEquals(519,
+ ((Message)message.getRepeatedField(f("repeated_foreign_message"), 1))
+ .getField(foreignC));
+ Assert.assertEquals(520,
+ ((Message)message.getRepeatedField(f("repeated_import_message"), 1))
+ .getField(importD));
+ Assert.assertEquals(527,
+ ((Message)message.getRepeatedField(f("repeated_lazy_message"), 1))
+ .getField(nestedB));
+
+ Assert.assertEquals( nestedFoo, message.getRepeatedField(f("repeated_nested_enum" ),1));
+ Assert.assertEquals(foreignFoo, message.getRepeatedField(f("repeated_foreign_enum"),1));
+ Assert.assertEquals( importFoo, message.getRepeatedField(f("repeated_import_enum" ),1));
+
+ Assert.assertEquals("524", message.getRepeatedField(f("repeated_string_piece"), 1));
+ Assert.assertEquals("525", message.getRepeatedField(f("repeated_cord"), 1));
+ }
+
+ public void setPackedFieldsViaReflection(Message.Builder message) {
+ message.addRepeatedField(f("packed_int32" ), 601 );
+ message.addRepeatedField(f("packed_int64" ), 602L);
+ message.addRepeatedField(f("packed_uint32" ), 603 );
+ message.addRepeatedField(f("packed_uint64" ), 604L);
+ message.addRepeatedField(f("packed_sint32" ), 605 );
+ message.addRepeatedField(f("packed_sint64" ), 606L);
+ message.addRepeatedField(f("packed_fixed32" ), 607 );
+ message.addRepeatedField(f("packed_fixed64" ), 608L);
+ message.addRepeatedField(f("packed_sfixed32"), 609 );
+ message.addRepeatedField(f("packed_sfixed64"), 610L);
+ message.addRepeatedField(f("packed_float" ), 611F);
+ message.addRepeatedField(f("packed_double" ), 612D);
+ message.addRepeatedField(f("packed_bool" ), true);
+ message.addRepeatedField(f("packed_enum" ), foreignBar);
+ // Add a second one of each field.
+ message.addRepeatedField(f("packed_int32" ), 701 );
+ message.addRepeatedField(f("packed_int64" ), 702L);
+ message.addRepeatedField(f("packed_uint32" ), 703 );
+ message.addRepeatedField(f("packed_uint64" ), 704L);
+ message.addRepeatedField(f("packed_sint32" ), 705 );
+ message.addRepeatedField(f("packed_sint64" ), 706L);
+ message.addRepeatedField(f("packed_fixed32" ), 707 );
+ message.addRepeatedField(f("packed_fixed64" ), 708L);
+ message.addRepeatedField(f("packed_sfixed32"), 709 );
+ message.addRepeatedField(f("packed_sfixed64"), 710L);
+ message.addRepeatedField(f("packed_float" ), 711F);
+ message.addRepeatedField(f("packed_double" ), 712D);
+ message.addRepeatedField(f("packed_bool" ), false);
+ message.addRepeatedField(f("packed_enum" ), foreignBaz);
+ }
+
+ public void assertPackedFieldsSetViaReflection(MessageOrBuilder message) {
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_int32" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_int64" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_uint32" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_uint64" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_sint32" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_sint64" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_fixed32" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_fixed64" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_sfixed32")));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_sfixed64")));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_float" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_double" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_bool" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_enum" )));
+ Assert.assertEquals(601 , message.getRepeatedField(f("packed_int32" ), 0));
+ Assert.assertEquals(602L , message.getRepeatedField(f("packed_int64" ), 0));
+ Assert.assertEquals(603 , message.getRepeatedField(f("packed_uint32" ), 0));
+ Assert.assertEquals(604L , message.getRepeatedField(f("packed_uint64" ), 0));
+ Assert.assertEquals(605 , message.getRepeatedField(f("packed_sint32" ), 0));
+ Assert.assertEquals(606L , message.getRepeatedField(f("packed_sint64" ), 0));
+ Assert.assertEquals(607 , message.getRepeatedField(f("packed_fixed32" ), 0));
+ Assert.assertEquals(608L , message.getRepeatedField(f("packed_fixed64" ), 0));
+ Assert.assertEquals(609 , message.getRepeatedField(f("packed_sfixed32"), 0));
+ Assert.assertEquals(610L , message.getRepeatedField(f("packed_sfixed64"), 0));
+ Assert.assertEquals(611F , message.getRepeatedField(f("packed_float" ), 0));
+ Assert.assertEquals(612D , message.getRepeatedField(f("packed_double" ), 0));
+ Assert.assertEquals(true , message.getRepeatedField(f("packed_bool" ), 0));
+ Assert.assertEquals(foreignBar, message.getRepeatedField(f("packed_enum" ),0));
+ Assert.assertEquals(701 , message.getRepeatedField(f("packed_int32" ), 1));
+ Assert.assertEquals(702L , message.getRepeatedField(f("packed_int64" ), 1));
+ Assert.assertEquals(703 , message.getRepeatedField(f("packed_uint32" ), 1));
+ Assert.assertEquals(704L , message.getRepeatedField(f("packed_uint64" ), 1));
+ Assert.assertEquals(705 , message.getRepeatedField(f("packed_sint32" ), 1));
+ Assert.assertEquals(706L , message.getRepeatedField(f("packed_sint64" ), 1));
+ Assert.assertEquals(707 , message.getRepeatedField(f("packed_fixed32" ), 1));
+ Assert.assertEquals(708L , message.getRepeatedField(f("packed_fixed64" ), 1));
+ Assert.assertEquals(709 , message.getRepeatedField(f("packed_sfixed32"), 1));
+ Assert.assertEquals(710L , message.getRepeatedField(f("packed_sfixed64"), 1));
+ Assert.assertEquals(711F , message.getRepeatedField(f("packed_float" ), 1));
+ Assert.assertEquals(712D , message.getRepeatedField(f("packed_double" ), 1));
+ Assert.assertEquals(false, message.getRepeatedField(f("packed_bool" ), 1));
+ Assert.assertEquals(foreignBaz, message.getRepeatedField(f("packed_enum" ),1));
+ }
+
+ /**
+ * Verifies that the reflection setters for the given.Builder object throw a
+ * NullPointerException if they are passed a null value. Uses Assert to throw an
+ * appropriate assertion failure, if the condition is not verified.
+ */
+ public void assertReflectionSettersRejectNull(Message.Builder builder)
+ throws Exception {
+ try {
+ builder.setField(f("optional_string"), null);
+ Assert.fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.setField(f("optional_bytes"), null);
+ Assert.fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.setField(f("optional_nested_enum"), null);
+ Assert.fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.setField(f("optional_nested_message"),
+ (TestAllTypes.NestedMessage) null);
+ Assert.fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.setField(f("optional_nested_message"),
+ (TestAllTypes.NestedMessage.Builder) null);
+ Assert.fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+
+ try {
+ builder.addRepeatedField(f("repeated_string"), null);
+ Assert.fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.addRepeatedField(f("repeated_bytes"), null);
+ Assert.fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.addRepeatedField(f("repeated_nested_enum"), null);
+ Assert.fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.addRepeatedField(f("repeated_nested_message"), null);
+ Assert.fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ }
+
+ /**
+ * Verifies that the reflection repeated setters for the given Builder object throw a
+ * NullPointerException if they are passed a null value. Uses Assert to throw an appropriate
+ * assertion failure, if the condition is not verified.
+ */
+ public void assertReflectionRepeatedSettersRejectNull(Message.Builder builder)
+ throws Exception {
+ builder.addRepeatedField(f("repeated_string"), "one");
+ try {
+ builder.setRepeatedField(f("repeated_string"), 0, null);
+ Assert.fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+
+ builder.addRepeatedField(f("repeated_bytes"), toBytes("one"));
+ try {
+ builder.setRepeatedField(f("repeated_bytes"), 0, null);
+ Assert.fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+
+ builder.addRepeatedField(f("repeated_nested_enum"), nestedBaz);
+ try {
+ builder.setRepeatedField(f("repeated_nested_enum"), 0, null);
+ Assert.fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+
+ builder.addRepeatedField(
+ f("repeated_nested_message"),
+ TestAllTypes.NestedMessage.newBuilder().setBb(218).build());
+ try {
+ builder.setRepeatedField(f("repeated_nested_message"), 0, null);
+ Assert.fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ }
+ }
+
+ /**
+ * @param filePath The path relative to
+ * {@link #getTestDataDir}.
+ */
+ public static String readTextFromFile(String filePath) {
+ return readBytesFromFile(filePath).toStringUtf8();
+ }
+
+ private static File getTestDataDir() {
+ // Search each parent directory looking for "src/google/protobuf".
+ File ancestor = new File(".");
+ try {
+ ancestor = ancestor.getCanonicalFile();
+ } catch (IOException e) {
+ throw new RuntimeException(
+ "Couldn't get canonical name of working directory.", e);
+ }
+ while (ancestor != null && ancestor.exists()) {
+ if (new File(ancestor, "src/google/protobuf").exists()) {
+ return new File(ancestor, "src/google/protobuf/testdata");
+ }
+ ancestor = ancestor.getParentFile();
+ }
+
+ throw new RuntimeException(
+ "Could not find golden files. This test must be run from within the " +
+ "protobuf source package so that it can read test data files from the " +
+ "C++ source tree: " + new File(".").getAbsolutePath());
+ }
+
+ /**
+ * @param filename The path relative to
+ * {@link #getTestDataDir}.
+ */
+ public static ByteString readBytesFromFile(String filename) {
+ File fullPath = new File(getTestDataDir(), filename);
+ try {
+ RandomAccessFile file = new RandomAccessFile(fullPath, "r");
+ byte[] content = new byte[(int) file.length()];
+ file.readFully(content);
+ return ByteString.copyFrom(content);
+ } catch (IOException e) {
+ // Throw a RuntimeException here so that we can call this function from
+ // static initializers.
+ throw new IllegalArgumentException(
+ "Couldn't read file: " + fullPath.getPath(), e);
+ }
+ }
+
+ /**
+ * Get the bytes of the "golden message". This is a serialized TestAllTypes
+ * with all fields set as they would be by
+ * {@link #setAllFields(TestAllTypes.Builder)}, but it is loaded from a file
+ * on disk rather than generated dynamically. The file is actually generated
+ * by C++ code, so testing against it verifies compatibility with C++.
+ */
+ public static ByteString getGoldenMessage() {
+ if (goldenMessage == null) {
+ goldenMessage = readBytesFromFile("golden_message");
+ }
+ return goldenMessage;
+ }
+ private static ByteString goldenMessage = null;
+
+ /**
+ * Get the bytes of the "golden packed fields message". This is a serialized
+ * TestPackedTypes with all fields set as they would be by
+ * {@link #setPackedFields(TestPackedTypes.Builder)}, but it is loaded from a
+ * file on disk rather than generated dynamically. The file is actually
+ * generated by C++ code, so testing against it verifies compatibility with
+ * C++.
+ */
+ public static ByteString getGoldenPackedFieldsMessage() {
+ if (goldenPackedFieldsMessage == null) {
+ goldenPackedFieldsMessage =
+ readBytesFromFile("golden_packed_fields_message");
+ }
+ return goldenPackedFieldsMessage;
+ }
+ private static ByteString goldenPackedFieldsMessage = null;
+
+ public static abstract class HackMessage extends GeneratedMessage {
+ public interface MyInterface extends BuilderParent {
+ }
+ }
+ /**
+ * Mock implementation of {@link GeneratedMessage.BuilderParent} for testing.
+ *
+ * @author jonp@google.com (Jon Perlow)
+ */
+ public static class MockBuilderParent
+ implements HackMessage.MyInterface {
+
+ private int invalidations;
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public void markDirty() {
+ invalidations++;
+ }
+
+ public int getInvalidationCount() {
+ return invalidations;
+ }
+ }
+}
diff --git a/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/TextFormatTest.java b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/TextFormatTest.java
new file mode 100644
index 00000000..edcc8908
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/TextFormatTest.java
@@ -0,0 +1,536 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf.test;
+import com.google.protobuf.*;
+
+import com.google.protobuf.Descriptors.FieldDescriptor;
+import protobuf_unittest.UnittestMset.TestMessageSet;
+import protobuf_unittest.UnittestMset.TestMessageSetExtension1;
+import protobuf_unittest.UnittestMset.TestMessageSetExtension2;
+import protobuf_unittest.UnittestProto.OneString;
+import protobuf_unittest.UnittestProto.TestAllExtensions;
+import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage;
+import protobuf_unittest.UnittestProto.TestEmptyMessage;
+
+import junit.framework.TestCase;
+
+import java.io.StringReader;
+
+/**
+ * Test case for {@link TextFormat}.
+ *
+ * TODO(wenboz): ExtensionTest and rest of text_format_unittest.cc.
+ *
+ * @author wenboz@google.com (Wenbo Zhu)
+ */
+public class TextFormatTest extends TestCase {
+
+ // A basic string with different escapable characters for testing.
+ private final static String kEscapeTestString =
+ "\"A string with ' characters \n and \r newlines and \t tabs and \001 "
+ + "slashes \\";
+
+ // A representation of the above string with all the characters escaped.
+ private final static String kEscapeTestStringEscaped =
+ "\\\"A string with \\' characters \\n and \\r newlines "
+ + "and \\t tabs and \\001 slashes \\\\";
+
+ private static String allFieldsSetText = TestUtil.readTextFromFile(
+ "text_format_unittest_data.txt");
+ private static String allExtensionsSetText = TestUtil.readTextFromFile(
+ "text_format_unittest_extensions_data.txt");
+
+ private static String exoticText =
+ "repeated_int32: -1\n" +
+ "repeated_int32: -2147483648\n" +
+ "repeated_int64: -1\n" +
+ "repeated_int64: -9223372036854775808\n" +
+ "repeated_uint32: 4294967295\n" +
+ "repeated_uint32: 2147483648\n" +
+ "repeated_uint64: 18446744073709551615\n" +
+ "repeated_uint64: 9223372036854775808\n" +
+ "repeated_double: 123.0\n" +
+ "repeated_double: 123.5\n" +
+ "repeated_double: 0.125\n" +
+ "repeated_double: .125\n" +
+ "repeated_double: -.125\n" +
+ "repeated_double: 1.23E17\n" +
+ "repeated_double: 1.23E+17\n" +
+ "repeated_double: -1.23e-17\n" +
+ "repeated_double: .23e+17\n" +
+ "repeated_double: -.23E17\n" +
+ "repeated_double: 1.235E22\n" +
+ "repeated_double: 1.235E-18\n" +
+ "repeated_double: 123.456789\n" +
+ "repeated_double: Infinity\n" +
+ "repeated_double: -Infinity\n" +
+ "repeated_double: NaN\n" +
+ "repeated_string: \"\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"" +
+ "\\341\\210\\264\"\n" +
+ "repeated_bytes: \"\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"\\376\"\n";
+
+ private static String canonicalExoticText =
+ exoticText.replace(": .", ": 0.").replace(": -.", ": -0.") // short-form double
+ .replace("23e", "23E").replace("E+", "E").replace("0.23E17", "2.3E16");
+
+ private String messageSetText =
+ "[protobuf_unittest.TestMessageSetExtension1] {\n" +
+ " i: 123\n" +
+ "}\n" +
+ "[protobuf_unittest.TestMessageSetExtension2] {\n" +
+ " str: \"foo\"\n" +
+ "}\n";
+
+ /** Print TestAllTypes and compare with golden file. */
+ public void testPrintMessage() throws Exception {
+ String javaText = TextFormat.printToString(TestUtil.getAllSet());
+
+ // Java likes to add a trailing ".0" to floats and doubles. C printf
+ // (with %g format) does not. Our golden files are used for both
+ // C++ and Java TextFormat classes, so we need to conform.
+ javaText = javaText.replace(".0\n", "\n");
+
+ assertEquals(allFieldsSetText, javaText);
+ }
+
+ /** Print TestAllTypes as Builder and compare with golden file. */
+ public void testPrintMessageBuilder() throws Exception {
+ String javaText = TextFormat.printToString(TestUtil.getAllSetBuilder());
+
+ // Java likes to add a trailing ".0" to floats and doubles. C printf
+ // (with %g format) does not. Our golden files are used for both
+ // C++ and Java TextFormat classes, so we need to conform.
+ javaText = javaText.replace(".0\n", "\n");
+
+ assertEquals(allFieldsSetText, javaText);
+ }
+
+ /** Print TestAllExtensions and compare with golden file. */
+ public void testPrintExtensions() throws Exception {
+ String javaText = TextFormat.printToString(TestUtil.getAllExtensionsSet());
+
+ // Java likes to add a trailing ".0" to floats and doubles. C printf
+ // (with %g format) does not. Our golden files are used for both
+ // C++ and Java TextFormat classes, so we need to conform.
+ javaText = javaText.replace(".0\n", "\n");
+
+ assertEquals(allExtensionsSetText, javaText);
+ }
+
+ // Creates an example unknown field set.
+ private UnknownFieldSet makeUnknownFieldSet() {
+ return UnknownFieldSet.newBuilder()
+ .addField(5,
+ UnknownFieldSet.Field.newBuilder()
+ .addVarint(1)
+ .addFixed32(2)
+ .addFixed64(3)
+ .addLengthDelimited(ByteString.copyFromUtf8("4"))
+ .addGroup(
+ UnknownFieldSet.newBuilder()
+ .addField(10,
+ UnknownFieldSet.Field.newBuilder()
+ .addVarint(5)
+ .build())
+ .build())
+ .build())
+ .addField(8,
+ UnknownFieldSet.Field.newBuilder()
+ .addVarint(1)
+ .addVarint(2)
+ .addVarint(3)
+ .build())
+ .addField(15,
+ UnknownFieldSet.Field.newBuilder()
+ .addVarint(0xABCDEF1234567890L)
+ .addFixed32(0xABCD1234)
+ .addFixed64(0xABCDEF1234567890L)
+ .build())
+ .build();
+ }
+
+ public void testPrintUnknownFields() throws Exception {
+ // Test printing of unknown fields in a message.
+
+ TestEmptyMessage message =
+ TestEmptyMessage.newBuilder()
+ .setUnknownFields(makeUnknownFieldSet())
+ .build();
+
+ assertEquals(
+ "5: 1\n" +
+ "5: 0x00000002\n" +
+ "5: 0x0000000000000003\n" +
+ "5: \"4\"\n" +
+ "5 {\n" +
+ " 10: 5\n" +
+ "}\n" +
+ "8: 1\n" +
+ "8: 2\n" +
+ "8: 3\n" +
+ "15: 12379813812177893520\n" +
+ "15: 0xabcd1234\n" +
+ "15: 0xabcdef1234567890\n",
+ TextFormat.printToString(message));
+ }
+
+ public void testPrintField() throws Exception {
+ final FieldDescriptor dataField =
+ OneString.getDescriptor().findFieldByName("data");
+ assertEquals(
+ "data: \"test data\"\n",
+ TextFormat.printFieldToString(dataField, "test data"));
+
+ final FieldDescriptor optionalField =
+ TestAllTypes.getDescriptor().findFieldByName("optional_nested_message");
+ final Object value = NestedMessage.newBuilder().setBb(42).build();
+
+ assertEquals(
+ "optional_nested_message {\n bb: 42\n}\n",
+ TextFormat.printFieldToString(optionalField, value));
+ }
+
+ /**
+ * Helper to construct a ByteString from a String containing only 8-bit
+ * characters. The characters are converted directly to bytes, *not*
+ * encoded using UTF-8.
+ */
+ private ByteString bytes(String str) throws Exception {
+ return ByteString.copyFrom(str.getBytes("ISO-8859-1"));
+ }
+
+ /**
+ * Helper to construct a ByteString from a bunch of bytes. The inputs are
+ * actually ints so that I can use hex notation and not get stupid errors
+ * about precision.
+ */
+ private ByteString bytes(int... bytesAsInts) {
+ byte[] bytes = new byte[bytesAsInts.length];
+ for (int i = 0; i < bytesAsInts.length; i++) {
+ bytes[i] = (byte) bytesAsInts[i];
+ }
+ return ByteString.copyFrom(bytes);
+ }
+
+ public void testPrintExotic() throws Exception {
+ Message message = TestAllTypes.newBuilder()
+ // Signed vs. unsigned numbers.
+ .addRepeatedInt32 (-1)
+ .addRepeatedUint32(-1)
+ .addRepeatedInt64 (-1)
+ .addRepeatedUint64(-1)
+
+ .addRepeatedInt32 (1 << 31)
+ .addRepeatedUint32(1 << 31)
+ .addRepeatedInt64 (1l << 63)
+ .addRepeatedUint64(1l << 63)
+
+ // Floats of various precisions and exponents.
+ .addRepeatedDouble(123)
+ .addRepeatedDouble(123.5)
+ .addRepeatedDouble(0.125)
+ .addRepeatedDouble(.125)
+ .addRepeatedDouble(-.125)
+ .addRepeatedDouble(123e15)
+ .addRepeatedDouble(123e15)
+ .addRepeatedDouble(-1.23e-17)
+ .addRepeatedDouble(.23e17)
+ .addRepeatedDouble(-23e15)
+ .addRepeatedDouble(123.5e20)
+ .addRepeatedDouble(123.5e-20)
+ .addRepeatedDouble(123.456789)
+ .addRepeatedDouble(Double.POSITIVE_INFINITY)
+ .addRepeatedDouble(Double.NEGATIVE_INFINITY)
+ .addRepeatedDouble(Double.NaN)
+
+ // Strings and bytes that needing escaping.
+ .addRepeatedString("\0\001\007\b\f\n\r\t\013\\\'\"\u1234")
+ .addRepeatedBytes(bytes("\0\001\007\b\f\n\r\t\013\\\'\"\u00fe"))
+ .build();
+
+ assertEquals(canonicalExoticText, message.toString());
+ }
+
+ public void testPrintMessageSet() throws Exception {
+ TestMessageSet messageSet =
+ TestMessageSet.newBuilder()
+ .setExtension(
+ TestMessageSetExtension1.messageSetExtension,
+ TestMessageSetExtension1.newBuilder().setI(123).build())
+ .setExtension(
+ TestMessageSetExtension2.messageSetExtension,
+ TestMessageSetExtension2.newBuilder().setStr("foo").build())
+ .build();
+
+ assertEquals(messageSetText, messageSet.toString());
+ }
+
+ // =================================================================
+
+ public void testParse() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TextFormat.merge(allFieldsSetText, builder);
+ TestUtil.assertAllFieldsSet(builder.build());
+ }
+
+ public void testParseReader() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TextFormat.merge(new StringReader(allFieldsSetText), builder);
+ TestUtil.assertAllFieldsSet(builder.build());
+ }
+
+ public void testParseExtensions() throws Exception {
+ TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
+ TextFormat.merge(allExtensionsSetText,
+ TestUtil.getExtensionRegistry(),
+ builder);
+ TestUtil.assertAllExtensionsSet(builder.build());
+ }
+
+ public void testParseCompatibility() throws Exception {
+ String original = "repeated_float: inf\n" +
+ "repeated_float: -inf\n" +
+ "repeated_float: nan\n" +
+ "repeated_float: inff\n" +
+ "repeated_float: -inff\n" +
+ "repeated_float: nanf\n" +
+ "repeated_float: 1.0f\n" +
+ "repeated_float: infinityf\n" +
+ "repeated_float: -Infinityf\n" +
+ "repeated_double: infinity\n" +
+ "repeated_double: -infinity\n" +
+ "repeated_double: nan\n";
+ String canonical = "repeated_float: Infinity\n" +
+ "repeated_float: -Infinity\n" +
+ "repeated_float: NaN\n" +
+ "repeated_float: Infinity\n" +
+ "repeated_float: -Infinity\n" +
+ "repeated_float: NaN\n" +
+ "repeated_float: 1.0\n" +
+ "repeated_float: Infinity\n" +
+ "repeated_float: -Infinity\n" +
+ "repeated_double: Infinity\n" +
+ "repeated_double: -Infinity\n" +
+ "repeated_double: NaN\n";
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TextFormat.merge(original, builder);
+ assertEquals(canonical, builder.build().toString());
+ }
+
+ public void testParseExotic() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TextFormat.merge(exoticText, builder);
+
+ // Too lazy to check things individually. Don't try to debug this
+ // if testPrintExotic() is failing.
+ assertEquals(canonicalExoticText, builder.build().toString());
+ }
+
+ public void testParseMessageSet() throws Exception {
+ ExtensionRegistry extensionRegistry = ExtensionRegistry.newInstance();
+ extensionRegistry.add(TestMessageSetExtension1.messageSetExtension);
+ extensionRegistry.add(TestMessageSetExtension2.messageSetExtension);
+
+ TestMessageSet.Builder builder = TestMessageSet.newBuilder();
+ TextFormat.merge(messageSetText, extensionRegistry, builder);
+ TestMessageSet messageSet = builder.build();
+
+ assertTrue(messageSet.hasExtension(
+ TestMessageSetExtension1.messageSetExtension));
+ assertEquals(123, messageSet.getExtension(
+ TestMessageSetExtension1.messageSetExtension).getI());
+ assertTrue(messageSet.hasExtension(
+ TestMessageSetExtension2.messageSetExtension));
+ assertEquals("foo", messageSet.getExtension(
+ TestMessageSetExtension2.messageSetExtension).getStr());
+ }
+
+ public void testParseNumericEnum() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TextFormat.merge("optional_nested_enum: 2", builder);
+ assertEquals(TestAllTypes.NestedEnum.BAR, builder.getOptionalNestedEnum());
+ }
+
+ public void testParseAngleBrackets() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TextFormat.merge("OptionalGroup: < a: 1 >", builder);
+ assertTrue(builder.hasOptionalGroup());
+ assertEquals(1, builder.getOptionalGroup().getA());
+ }
+
+ public void testParseComment() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TextFormat.merge(
+ "# this is a comment\n" +
+ "optional_int32: 1 # another comment\n" +
+ "optional_int64: 2\n" +
+ "# EOF comment", builder);
+ assertEquals(1, builder.getOptionalInt32());
+ assertEquals(2, builder.getOptionalInt64());
+ }
+
+ // =================================================================
+
+ public void testParseString() throws Exception {
+ final String zh = "\u9999\u6e2f\u4e0a\u6d77\ud84f\udf80\u8c50\u9280\u884c";
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TextFormat.merge("optional_string: \"" + zh + "\"", builder);
+ assertEquals(zh, builder.getOptionalString());
+ }
+
+ public void testParseLongString() throws Exception {
+ String longText =
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890";
+
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TextFormat.merge("optional_string: \"" + longText + "\"", builder);
+ assertEquals(longText, builder.getOptionalString());
+ }
+
+ public void testParseBoolean() throws Exception {
+ String goodText =
+ "repeated_bool: t repeated_bool : 0\n" +
+ "repeated_bool :f repeated_bool:1";
+ String goodTextCanonical =
+ "repeated_bool: true\n" +
+ "repeated_bool: false\n" +
+ "repeated_bool: false\n" +
+ "repeated_bool: true\n";
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TextFormat.merge(goodText, builder);
+ assertEquals(goodTextCanonical, builder.build().toString());
+
+ try {
+ TestAllTypes.Builder badBuilder = TestAllTypes.newBuilder();
+ TextFormat.merge("optional_bool:2", badBuilder);
+ fail("Should have thrown an exception.");
+ } catch (TextFormat.ParseException e) {
+ // success
+ }
+ try {
+ TestAllTypes.Builder badBuilder = TestAllTypes.newBuilder();
+ TextFormat.merge("optional_bool: foo", badBuilder);
+ fail("Should have thrown an exception.");
+ } catch (TextFormat.ParseException e) {
+ // success
+ }
+ }
+
+ public void testParseAdjacentStringLiterals() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TextFormat.merge("optional_string: \"foo\" 'corge' \"grault\"", builder);
+ assertEquals("foocorgegrault", builder.getOptionalString());
+ }
+
+ public void testPrintFieldValue() throws Exception {
+ assertPrintFieldValue("\"Hello\"", "Hello", "repeated_string");
+ assertPrintFieldValue("123.0", 123f, "repeated_float");
+ assertPrintFieldValue("123.0", 123d, "repeated_double");
+ assertPrintFieldValue("123", 123, "repeated_int32");
+ assertPrintFieldValue("123", 123L, "repeated_int64");
+ assertPrintFieldValue("true", true, "repeated_bool");
+ assertPrintFieldValue("4294967295", 0xFFFFFFFF, "repeated_uint32");
+ assertPrintFieldValue("18446744073709551615", 0xFFFFFFFFFFFFFFFFL,
+ "repeated_uint64");
+ assertPrintFieldValue("\"\\001\\002\\003\"",
+ ByteString.copyFrom(new byte[] {1, 2, 3}), "repeated_bytes");
+ }
+
+ private void assertPrintFieldValue(String expect, Object value,
+ String fieldName) throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ StringBuilder sb = new StringBuilder();
+ TextFormat.printFieldValue(
+ TestAllTypes.getDescriptor().findFieldByName(fieldName),
+ value, sb);
+ assertEquals(expect, sb.toString());
+ }
+
+ public void testShortDebugString() {
+ assertEquals("optional_nested_message { bb: 42 } repeated_int32: 1"
+ + " repeated_uint32: 2",
+ TextFormat.shortDebugString(TestAllTypes.newBuilder()
+ .addRepeatedInt32(1)
+ .addRepeatedUint32(2)
+ .setOptionalNestedMessage(
+ NestedMessage.newBuilder().setBb(42).build())
+ .build()));
+ }
+
+ public void testShortDebugString_unknown() {
+ assertEquals("5: 1 5: 0x00000002 5: 0x0000000000000003 5: \"4\" 5 { 10: 5 }"
+ + " 8: 1 8: 2 8: 3 15: 12379813812177893520 15: 0xabcd1234 15:"
+ + " 0xabcdef1234567890",
+ TextFormat.shortDebugString(makeUnknownFieldSet()));
+ }
+
+ public void testPrintToUnicodeString() {
+ assertEquals(
+ "optional_string: \"abc\u3042efg\"\n" +
+ "optional_bytes: \"\\343\\201\\202\"\n" +
+ "repeated_string: \"\u3093XYZ\"\n",
+ TextFormat.printToUnicodeString(TestAllTypes.newBuilder()
+ .setOptionalString("abc\u3042efg")
+ .setOptionalBytes(bytes(0xe3, 0x81, 0x82))
+ .addRepeatedString("\u3093XYZ")
+ .build()));
+ }
+
+ public void testPrintToUnicodeString_unknown() {
+ assertEquals(
+ "1: \"\\343\\201\\202\"\n",
+ TextFormat.printToUnicodeString(UnknownFieldSet.newBuilder()
+ .addField(1,
+ UnknownFieldSet.Field.newBuilder()
+ .addLengthDelimited(bytes(0xe3, 0x81, 0x82)).build())
+ .build()));
+ }
+}
diff --git a/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/UnknownFieldSetTest.java b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/UnknownFieldSetTest.java
new file mode 100644
index 00000000..b9bfb691
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/UnknownFieldSetTest.java
@@ -0,0 +1,438 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf.test;
+import com.google.protobuf.*;
+
+import protobuf_unittest.UnittestProto;
+import protobuf_unittest.UnittestProto.TestAllExtensions;
+import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestEmptyMessage;
+import protobuf_unittest.UnittestProto.TestEmptyMessageWithExtensions;
+
+import junit.framework.TestCase;
+
+import java.util.Arrays;
+import java.util.Map;
+
+/**
+ * Tests related to unknown field handling.
+ *
+ * @author kenton@google.com (Kenton Varda)
+ */
+public class UnknownFieldSetTest extends TestCase {
+ public void setUp() throws Exception {
+ descriptor = TestAllTypes.getDescriptor();
+ allFields = TestUtil.getAllSet();
+ allFieldsData = allFields.toByteString();
+ emptyMessage = TestEmptyMessage.parseFrom(allFieldsData);
+ unknownFields = emptyMessage.getUnknownFields();
+ }
+
+ UnknownFieldSet.Field getField(String name) {
+ Descriptors.FieldDescriptor field = descriptor.findFieldByName(name);
+ assertNotNull(field);
+ return unknownFields.getField(field.getNumber());
+ }
+
+ // Constructs a protocol buffer which contains fields with all the same
+ // numbers as allFieldsData except that each field is some other wire
+ // type.
+ ByteString getBizarroData() throws Exception {
+ UnknownFieldSet.Builder bizarroFields = UnknownFieldSet.newBuilder();
+
+ UnknownFieldSet.Field varintField =
+ UnknownFieldSet.Field.newBuilder().addVarint(1).build();
+ UnknownFieldSet.Field fixed32Field =
+ UnknownFieldSet.Field.newBuilder().addFixed32(1).build();
+
+ for (Map.Entry<Integer, UnknownFieldSet.Field> entry :
+ unknownFields.asMap().entrySet()) {
+ if (entry.getValue().getVarintList().isEmpty()) {
+ // Original field is not a varint, so use a varint.
+ bizarroFields.addField(entry.getKey(), varintField);
+ } else {
+ // Original field *is* a varint, so use something else.
+ bizarroFields.addField(entry.getKey(), fixed32Field);
+ }
+ }
+
+ return bizarroFields.build().toByteString();
+ }
+
+ Descriptors.Descriptor descriptor;
+ TestAllTypes allFields;
+ ByteString allFieldsData;
+
+ // An empty message that has been parsed from allFieldsData. So, it has
+ // unknown fields of every type.
+ TestEmptyMessage emptyMessage;
+ UnknownFieldSet unknownFields;
+
+ // =================================================================
+
+ public void testVarint() throws Exception {
+ UnknownFieldSet.Field field = getField("optional_int32");
+ assertEquals(1, field.getVarintList().size());
+ assertEquals(allFields.getOptionalInt32(),
+ (long) field.getVarintList().get(0));
+ }
+
+ public void testFixed32() throws Exception {
+ UnknownFieldSet.Field field = getField("optional_fixed32");
+ assertEquals(1, field.getFixed32List().size());
+ assertEquals(allFields.getOptionalFixed32(),
+ (int) field.getFixed32List().get(0));
+ }
+
+ public void testFixed64() throws Exception {
+ UnknownFieldSet.Field field = getField("optional_fixed64");
+ assertEquals(1, field.getFixed64List().size());
+ assertEquals(allFields.getOptionalFixed64(),
+ (long) field.getFixed64List().get(0));
+ }
+
+ public void testLengthDelimited() throws Exception {
+ UnknownFieldSet.Field field = getField("optional_bytes");
+ assertEquals(1, field.getLengthDelimitedList().size());
+ assertEquals(allFields.getOptionalBytes(),
+ field.getLengthDelimitedList().get(0));
+ }
+
+ public void testGroup() throws Exception {
+ Descriptors.FieldDescriptor nestedFieldDescriptor =
+ TestAllTypes.OptionalGroup.getDescriptor().findFieldByName("a");
+ assertNotNull(nestedFieldDescriptor);
+
+ UnknownFieldSet.Field field = getField("optionalgroup");
+ assertEquals(1, field.getGroupList().size());
+
+ UnknownFieldSet group = field.getGroupList().get(0);
+ assertEquals(1, group.asMap().size());
+ assertTrue(group.hasField(nestedFieldDescriptor.getNumber()));
+
+ UnknownFieldSet.Field nestedField =
+ group.getField(nestedFieldDescriptor.getNumber());
+ assertEquals(1, nestedField.getVarintList().size());
+ assertEquals(allFields.getOptionalGroup().getA(),
+ (long) nestedField.getVarintList().get(0));
+ }
+
+ public void testSerialize() throws Exception {
+ // Check that serializing the UnknownFieldSet produces the original data
+ // again.
+ ByteString data = emptyMessage.toByteString();
+ assertEquals(allFieldsData, data);
+ }
+
+ public void testCopyFrom() throws Exception {
+ TestEmptyMessage message =
+ TestEmptyMessage.newBuilder().mergeFrom(emptyMessage).build();
+
+ assertEquals(emptyMessage.toString(), message.toString());
+ }
+
+ public void testMergeFrom() throws Exception {
+ TestEmptyMessage source =
+ TestEmptyMessage.newBuilder()
+ .setUnknownFields(
+ UnknownFieldSet.newBuilder()
+ .addField(2,
+ UnknownFieldSet.Field.newBuilder()
+ .addVarint(2).build())
+ .addField(3,
+ UnknownFieldSet.Field.newBuilder()
+ .addVarint(4).build())
+ .build())
+ .build();
+ TestEmptyMessage destination =
+ TestEmptyMessage.newBuilder()
+ .setUnknownFields(
+ UnknownFieldSet.newBuilder()
+ .addField(1,
+ UnknownFieldSet.Field.newBuilder()
+ .addVarint(1).build())
+ .addField(3,
+ UnknownFieldSet.Field.newBuilder()
+ .addVarint(3).build())
+ .build())
+ .mergeFrom(source)
+ .build();
+
+ assertEquals(
+ "1: 1\n" +
+ "2: 2\n" +
+ "3: 3\n" +
+ "3: 4\n",
+ destination.toString());
+ }
+
+ public void testClear() throws Exception {
+ UnknownFieldSet fields =
+ UnknownFieldSet.newBuilder().mergeFrom(unknownFields).clear().build();
+ assertTrue(fields.asMap().isEmpty());
+ }
+
+ public void testClearMessage() throws Exception {
+ TestEmptyMessage message =
+ TestEmptyMessage.newBuilder().mergeFrom(emptyMessage).clear().build();
+ assertEquals(0, message.getSerializedSize());
+ }
+
+ public void testParseKnownAndUnknown() throws Exception {
+ // Test mixing known and unknown fields when parsing.
+
+ UnknownFieldSet fields =
+ UnknownFieldSet.newBuilder(unknownFields)
+ .addField(123456,
+ UnknownFieldSet.Field.newBuilder().addVarint(654321).build())
+ .build();
+
+ ByteString data = fields.toByteString();
+ TestAllTypes destination = TestAllTypes.parseFrom(data);
+
+ TestUtil.assertAllFieldsSet(destination);
+ assertEquals(1, destination.getUnknownFields().asMap().size());
+
+ UnknownFieldSet.Field field =
+ destination.getUnknownFields().getField(123456);
+ assertEquals(1, field.getVarintList().size());
+ assertEquals(654321, (long) field.getVarintList().get(0));
+ }
+
+ public void testWrongTypeTreatedAsUnknown() throws Exception {
+ // Test that fields of the wrong wire type are treated like unknown fields
+ // when parsing.
+
+ ByteString bizarroData = getBizarroData();
+ TestAllTypes allTypesMessage = TestAllTypes.parseFrom(bizarroData);
+ TestEmptyMessage emptyMessage = TestEmptyMessage.parseFrom(bizarroData);
+
+ // All fields should have been interpreted as unknown, so the debug strings
+ // should be the same.
+ assertEquals(emptyMessage.toString(), allTypesMessage.toString());
+ }
+
+ public void testUnknownExtensions() throws Exception {
+ // Make sure fields are properly parsed to the UnknownFieldSet even when
+ // they are declared as extension numbers.
+
+ TestEmptyMessageWithExtensions message =
+ TestEmptyMessageWithExtensions.parseFrom(allFieldsData);
+
+ assertEquals(unknownFields.asMap().size(),
+ message.getUnknownFields().asMap().size());
+ assertEquals(allFieldsData, message.toByteString());
+ }
+
+ public void testWrongExtensionTypeTreatedAsUnknown() throws Exception {
+ // Test that fields of the wrong wire type are treated like unknown fields
+ // when parsing extensions.
+
+ ByteString bizarroData = getBizarroData();
+ TestAllExtensions allExtensionsMessage =
+ TestAllExtensions.parseFrom(bizarroData);
+ TestEmptyMessage emptyMessage = TestEmptyMessage.parseFrom(bizarroData);
+
+ // All fields should have been interpreted as unknown, so the debug strings
+ // should be the same.
+ assertEquals(emptyMessage.toString(),
+ allExtensionsMessage.toString());
+ }
+
+ public void testParseUnknownEnumValue() throws Exception {
+ Descriptors.FieldDescriptor singularField =
+ TestAllTypes.getDescriptor().findFieldByName("optional_nested_enum");
+ Descriptors.FieldDescriptor repeatedField =
+ TestAllTypes.getDescriptor().findFieldByName("repeated_nested_enum");
+ assertNotNull(singularField);
+ assertNotNull(repeatedField);
+
+ ByteString data =
+ UnknownFieldSet.newBuilder()
+ .addField(singularField.getNumber(),
+ UnknownFieldSet.Field.newBuilder()
+ .addVarint(TestAllTypes.NestedEnum.BAR.getNumber())
+ .addVarint(5) // not valid
+ .build())
+ .addField(repeatedField.getNumber(),
+ UnknownFieldSet.Field.newBuilder()
+ .addVarint(TestAllTypes.NestedEnum.FOO.getNumber())
+ .addVarint(4) // not valid
+ .addVarint(TestAllTypes.NestedEnum.BAZ.getNumber())
+ .addVarint(6) // not valid
+ .build())
+ .build()
+ .toByteString();
+
+ {
+ TestAllTypes message = TestAllTypes.parseFrom(data);
+ assertEquals(TestAllTypes.NestedEnum.BAR,
+ message.getOptionalNestedEnum());
+ assertEquals(
+ Arrays.asList(TestAllTypes.NestedEnum.FOO, TestAllTypes.NestedEnum.BAZ),
+ message.getRepeatedNestedEnumList());
+ assertEquals(Arrays.asList(5L),
+ message.getUnknownFields()
+ .getField(singularField.getNumber())
+ .getVarintList());
+ assertEquals(Arrays.asList(4L, 6L),
+ message.getUnknownFields()
+ .getField(repeatedField.getNumber())
+ .getVarintList());
+ }
+
+ {
+ TestAllExtensions message =
+ TestAllExtensions.parseFrom(data, TestUtil.getExtensionRegistry());
+ assertEquals(TestAllTypes.NestedEnum.BAR,
+ message.getExtension(UnittestProto.optionalNestedEnumExtension));
+ assertEquals(
+ Arrays.asList(TestAllTypes.NestedEnum.FOO, TestAllTypes.NestedEnum.BAZ),
+ message.getExtension(UnittestProto.repeatedNestedEnumExtension));
+ assertEquals(Arrays.asList(5L),
+ message.getUnknownFields()
+ .getField(singularField.getNumber())
+ .getVarintList());
+ assertEquals(Arrays.asList(4L, 6L),
+ message.getUnknownFields()
+ .getField(repeatedField.getNumber())
+ .getVarintList());
+ }
+ }
+
+ public void testLargeVarint() throws Exception {
+ ByteString data =
+ UnknownFieldSet.newBuilder()
+ .addField(1,
+ UnknownFieldSet.Field.newBuilder()
+ .addVarint(0x7FFFFFFFFFFFFFFFL)
+ .build())
+ .build()
+ .toByteString();
+ UnknownFieldSet parsed = UnknownFieldSet.parseFrom(data);
+ UnknownFieldSet.Field field = parsed.getField(1);
+ assertEquals(1, field.getVarintList().size());
+ assertEquals(0x7FFFFFFFFFFFFFFFL, (long)field.getVarintList().get(0));
+ }
+
+ public void testEqualsAndHashCode() {
+ UnknownFieldSet.Field fixed32Field =
+ UnknownFieldSet.Field.newBuilder()
+ .addFixed32(1)
+ .build();
+ UnknownFieldSet.Field fixed64Field =
+ UnknownFieldSet.Field.newBuilder()
+ .addFixed64(1)
+ .build();
+ UnknownFieldSet.Field varIntField =
+ UnknownFieldSet.Field.newBuilder()
+ .addVarint(1)
+ .build();
+ UnknownFieldSet.Field lengthDelimitedField =
+ UnknownFieldSet.Field.newBuilder()
+ .addLengthDelimited(ByteString.EMPTY)
+ .build();
+ UnknownFieldSet.Field groupField =
+ UnknownFieldSet.Field.newBuilder()
+ .addGroup(unknownFields)
+ .build();
+
+ UnknownFieldSet a =
+ UnknownFieldSet.newBuilder()
+ .addField(1, fixed32Field)
+ .build();
+ UnknownFieldSet b =
+ UnknownFieldSet.newBuilder()
+ .addField(1, fixed64Field)
+ .build();
+ UnknownFieldSet c =
+ UnknownFieldSet.newBuilder()
+ .addField(1, varIntField)
+ .build();
+ UnknownFieldSet d =
+ UnknownFieldSet.newBuilder()
+ .addField(1, lengthDelimitedField)
+ .build();
+ UnknownFieldSet e =
+ UnknownFieldSet.newBuilder()
+ .addField(1, groupField)
+ .build();
+
+ checkEqualsIsConsistent(a);
+ checkEqualsIsConsistent(b);
+ checkEqualsIsConsistent(c);
+ checkEqualsIsConsistent(d);
+ checkEqualsIsConsistent(e);
+
+ checkNotEqual(a, b);
+ checkNotEqual(a, c);
+ checkNotEqual(a, d);
+ checkNotEqual(a, e);
+ checkNotEqual(b, c);
+ checkNotEqual(b, d);
+ checkNotEqual(b, e);
+ checkNotEqual(c, d);
+ checkNotEqual(c, e);
+ checkNotEqual(d, e);
+ }
+
+ /**
+ * Asserts that the given field sets are not equal and have different
+ * hash codes.
+ *
+ * @warning It's valid for non-equal objects to have the same hash code, so
+ * this test is stricter than it needs to be. However, this should happen
+ * relatively rarely.
+ */
+ private void checkNotEqual(UnknownFieldSet s1, UnknownFieldSet s2) {
+ String equalsError = String.format("%s should not be equal to %s", s1, s2);
+ assertFalse(equalsError, s1.equals(s2));
+ assertFalse(equalsError, s2.equals(s1));
+
+ assertFalse(
+ String.format("%s should have a different hash code from %s", s1, s2),
+ s1.hashCode() == s2.hashCode());
+ }
+
+ /**
+ * Asserts that the given field sets are equal and have identical hash codes.
+ */
+ private void checkEqualsIsConsistent(UnknownFieldSet set) {
+ // Object should be equal to itself.
+ assertEquals(set, set);
+
+ // Object should be equal to a copy of itself.
+ UnknownFieldSet copy = UnknownFieldSet.newBuilder(set).build();
+ assertEquals(set, copy);
+ assertEquals(copy, set);
+ assertEquals(set.hashCode(), copy.hashCode());
+ }
+}
diff --git a/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/UnmodifiableLazyStringListTest.java b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/UnmodifiableLazyStringListTest.java
new file mode 100644
index 00000000..cb75d74b
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/UnmodifiableLazyStringListTest.java
@@ -0,0 +1,153 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf.test;
+import com.google.protobuf.*;
+
+import junit.framework.TestCase;
+
+import java.util.Iterator;
+import java.util.ListIterator;
+
+/**
+ * Tests for {@link UnmodifiableLazyStringList}.
+ *
+ * @author jonp@google.com (Jon Perlow)
+ */
+public class UnmodifiableLazyStringListTest extends TestCase {
+
+ private static String STRING_A = "A";
+ private static String STRING_B = "B";
+ private static String STRING_C = "C";
+
+ private static ByteString BYTE_STRING_A = ByteString.copyFromUtf8("A");
+ private static ByteString BYTE_STRING_B = ByteString.copyFromUtf8("B");
+ private static ByteString BYTE_STRING_C = ByteString.copyFromUtf8("C");
+
+ public void testReadOnlyMethods() {
+ LazyStringArrayList rawList = createSampleList();
+ UnmodifiableLazyStringList list = new UnmodifiableLazyStringList(rawList);
+ assertEquals(3, list.size());
+ assertSame(STRING_A, list.get(0));
+ assertSame(STRING_B, list.get(1));
+ assertSame(STRING_C, list.get(2));
+ assertEquals(BYTE_STRING_A, list.getByteString(0));
+ assertEquals(BYTE_STRING_B, list.getByteString(1));
+ assertEquals(BYTE_STRING_C, list.getByteString(2));
+ }
+
+ public void testModifyMethods() {
+ LazyStringArrayList rawList = createSampleList();
+ UnmodifiableLazyStringList list = new UnmodifiableLazyStringList(rawList);
+
+ try {
+ list.remove(0);
+ fail();
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ assertEquals(3, list.size());
+
+ try {
+ list.add(STRING_B);
+ fail();
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ assertEquals(3, list.size());
+
+ try {
+ list.set(1, STRING_B);
+ fail();
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ }
+
+ public void testIterator() {
+ LazyStringArrayList rawList = createSampleList();
+ UnmodifiableLazyStringList list = new UnmodifiableLazyStringList(rawList);
+
+ Iterator<String> iter = list.iterator();
+ int count = 0;
+ while (iter.hasNext()) {
+ iter.next();
+ count++;
+ try {
+ iter.remove();
+ fail();
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ }
+ assertEquals(3, count);
+
+ }
+
+ public void testListIterator() {
+ LazyStringArrayList rawList = createSampleList();
+ UnmodifiableLazyStringList list = new UnmodifiableLazyStringList(rawList);
+
+ ListIterator<String> iter = list.listIterator();
+ int count = 0;
+ while (iter.hasNext()) {
+ iter.next();
+ count++;
+ try {
+ iter.remove();
+ fail();
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ try {
+ iter.set("bar");
+ fail();
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ try {
+ iter.add("bar");
+ fail();
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ }
+ assertEquals(3, count);
+
+ }
+
+ private LazyStringArrayList createSampleList() {
+ LazyStringArrayList rawList = new LazyStringArrayList();
+ rawList.add(STRING_A);
+ rawList.add(STRING_B);
+ rawList.add(STRING_C);
+ return rawList;
+ }
+}
diff --git a/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/WireFormatTest.java b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/WireFormatTest.java
new file mode 100644
index 00000000..74528726
--- /dev/null
+++ b/java/compatibility_tests/v2.5.0/tests/src/main/java/com/google/protobuf/test/WireFormatTest.java
@@ -0,0 +1,465 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf.test;
+import com.google.protobuf.*;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.util.List;
+
+import protobuf_unittest.UnittestProto;
+import protobuf_unittest.UnittestProto.TestAllExtensions;
+import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestFieldOrderings;
+import protobuf_unittest.UnittestProto.TestPackedExtensions;
+import protobuf_unittest.UnittestProto.TestPackedTypes;
+import protobuf_unittest.UnittestMset.TestMessageSet;
+import protobuf_unittest.UnittestMset.RawMessageSet;
+import protobuf_unittest.UnittestMset.TestMessageSetExtension1;
+import protobuf_unittest.UnittestMset.TestMessageSetExtension2;
+
+/**
+ * Tests related to parsing and serialization.
+ *
+ * @author kenton@google.com (Kenton Varda)
+ */
+public class WireFormatTest extends TestCase {
+ public void testSerialization() throws Exception {
+ TestAllTypes message = TestUtil.getAllSet();
+
+ ByteString rawBytes = message.toByteString();
+ assertEquals(rawBytes.size(), message.getSerializedSize());
+
+ TestAllTypes message2 = TestAllTypes.parseFrom(rawBytes);
+
+ TestUtil.assertAllFieldsSet(message2);
+ }
+
+ public void testSerializationPacked() throws Exception {
+ TestPackedTypes message = TestUtil.getPackedSet();
+
+ ByteString rawBytes = message.toByteString();
+ assertEquals(rawBytes.size(), message.getSerializedSize());
+
+ TestPackedTypes message2 = TestPackedTypes.parseFrom(rawBytes);
+
+ TestUtil.assertPackedFieldsSet(message2);
+ }
+
+ public void testSerializeExtensions() throws Exception {
+ // TestAllTypes and TestAllExtensions should have compatible wire formats,
+ // so if we serialize a TestAllExtensions then parse it as TestAllTypes
+ // it should work.
+
+ TestAllExtensions message = TestUtil.getAllExtensionsSet();
+ ByteString rawBytes = message.toByteString();
+ assertEquals(rawBytes.size(), message.getSerializedSize());
+
+ TestAllTypes message2 = TestAllTypes.parseFrom(rawBytes);
+
+ TestUtil.assertAllFieldsSet(message2);
+ }
+
+ public void testSerializePackedExtensions() throws Exception {
+ // TestPackedTypes and TestPackedExtensions should have compatible wire
+ // formats; check that they serialize to the same string.
+ TestPackedExtensions message = TestUtil.getPackedExtensionsSet();
+ ByteString rawBytes = message.toByteString();
+
+ TestPackedTypes message2 = TestUtil.getPackedSet();
+ ByteString rawBytes2 = message2.toByteString();
+
+ assertEquals(rawBytes, rawBytes2);
+ }
+
+ public void testSerializationPackedWithoutGetSerializedSize()
+ throws Exception {
+ // Write directly to an OutputStream, without invoking getSerializedSize()
+ // This used to be a bug where the size of a packed field was incorrect,
+ // since getSerializedSize() was never invoked.
+ TestPackedTypes message = TestUtil.getPackedSet();
+
+ // Directly construct a CodedOutputStream around the actual OutputStream,
+ // in case writeTo(OutputStream output) invokes getSerializedSize();
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ CodedOutputStream codedOutput = CodedOutputStream.newInstance(outputStream);
+
+ message.writeTo(codedOutput);
+
+ codedOutput.flush();
+
+ TestPackedTypes message2 = TestPackedTypes.parseFrom(
+ outputStream.toByteArray());
+
+ TestUtil.assertPackedFieldsSet(message2);
+ }
+
+ public void testParseExtensions() throws Exception {
+ // TestAllTypes and TestAllExtensions should have compatible wire formats,
+ // so if we serialize a TestAllTypes then parse it as TestAllExtensions
+ // it should work.
+
+ TestAllTypes message = TestUtil.getAllSet();
+ ByteString rawBytes = message.toByteString();
+
+ ExtensionRegistry registry = TestUtil.getExtensionRegistry();
+
+ TestAllExtensions message2 =
+ TestAllExtensions.parseFrom(rawBytes, registry);
+
+ TestUtil.assertAllExtensionsSet(message2);
+ }
+
+ public void testParsePackedExtensions() throws Exception {
+ // Ensure that packed extensions can be properly parsed.
+ TestPackedExtensions message = TestUtil.getPackedExtensionsSet();
+ ByteString rawBytes = message.toByteString();
+
+ ExtensionRegistry registry = TestUtil.getExtensionRegistry();
+
+ TestPackedExtensions message2 =
+ TestPackedExtensions.parseFrom(rawBytes, registry);
+
+ TestUtil.assertPackedExtensionsSet(message2);
+ }
+
+ public void testExtensionsSerializedSize() throws Exception {
+ assertEquals(TestUtil.getAllSet().getSerializedSize(),
+ TestUtil.getAllExtensionsSet().getSerializedSize());
+ }
+
+ public void testSerializeDelimited() throws Exception {
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ TestUtil.getAllSet().writeDelimitedTo(output);
+ output.write(12);
+ TestUtil.getPackedSet().writeDelimitedTo(output);
+ output.write(34);
+
+ ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray());
+
+ TestUtil.assertAllFieldsSet(TestAllTypes.parseDelimitedFrom(input));
+ assertEquals(12, input.read());
+ TestUtil.assertPackedFieldsSet(TestPackedTypes.parseDelimitedFrom(input));
+ assertEquals(34, input.read());
+ assertEquals(-1, input.read());
+
+ // We're at EOF, so parsing again should return null.
+ assertTrue(TestAllTypes.parseDelimitedFrom(input) == null);
+ }
+
+ private void assertFieldsInOrder(ByteString data) throws Exception {
+ CodedInputStream input = data.newCodedInput();
+ int previousTag = 0;
+
+ while (true) {
+ int tag = input.readTag();
+ if (tag == 0) {
+ break;
+ }
+
+ assertTrue(tag > previousTag);
+ previousTag = tag;
+ input.skipField(tag);
+ }
+ }
+
+ public void testInterleavedFieldsAndExtensions() throws Exception {
+ // Tests that fields are written in order even when extension ranges
+ // are interleaved with field numbers.
+ ByteString data =
+ TestFieldOrderings.newBuilder()
+ .setMyInt(1)
+ .setMyString("foo")
+ .setMyFloat(1.0F)
+ .setExtension(UnittestProto.myExtensionInt, 23)
+ .setExtension(UnittestProto.myExtensionString, "bar")
+ .build().toByteString();
+ assertFieldsInOrder(data);
+
+ Descriptors.Descriptor descriptor = TestFieldOrderings.getDescriptor();
+ ByteString dynamic_data =
+ DynamicMessage.newBuilder(TestFieldOrderings.getDescriptor())
+ .setField(descriptor.findFieldByName("my_int"), 1L)
+ .setField(descriptor.findFieldByName("my_string"), "foo")
+ .setField(descriptor.findFieldByName("my_float"), 1.0F)
+ .setField(UnittestProto.myExtensionInt.getDescriptor(), 23)
+ .setField(UnittestProto.myExtensionString.getDescriptor(), "bar")
+ .build().toByteString();
+ assertFieldsInOrder(dynamic_data);
+ }
+
+ private ExtensionRegistry getTestFieldOrderingsRegistry() {
+ ExtensionRegistry result = ExtensionRegistry.newInstance();
+ result.add(UnittestProto.myExtensionInt);
+ result.add(UnittestProto.myExtensionString);
+ return result;
+ }
+
+ public void testParseMultipleExtensionRanges() throws Exception {
+ // Make sure we can parse a message that contains multiple extensions
+ // ranges.
+ TestFieldOrderings source =
+ TestFieldOrderings.newBuilder()
+ .setMyInt(1)
+ .setMyString("foo")
+ .setMyFloat(1.0F)
+ .setExtension(UnittestProto.myExtensionInt, 23)
+ .setExtension(UnittestProto.myExtensionString, "bar")
+ .build();
+ TestFieldOrderings dest =
+ TestFieldOrderings.parseFrom(source.toByteString(),
+ getTestFieldOrderingsRegistry());
+ assertEquals(source, dest);
+ }
+
+ public void testParseMultipleExtensionRangesDynamic() throws Exception {
+ // Same as above except with DynamicMessage.
+ Descriptors.Descriptor descriptor = TestFieldOrderings.getDescriptor();
+ DynamicMessage source =
+ DynamicMessage.newBuilder(TestFieldOrderings.getDescriptor())
+ .setField(descriptor.findFieldByName("my_int"), 1L)
+ .setField(descriptor.findFieldByName("my_string"), "foo")
+ .setField(descriptor.findFieldByName("my_float"), 1.0F)
+ .setField(UnittestProto.myExtensionInt.getDescriptor(), 23)
+ .setField(UnittestProto.myExtensionString.getDescriptor(), "bar")
+ .build();
+ DynamicMessage dest =
+ DynamicMessage.parseFrom(descriptor, source.toByteString(),
+ getTestFieldOrderingsRegistry());
+ assertEquals(source, dest);
+ }
+
+ private static final int UNKNOWN_TYPE_ID = 1550055;
+ private static final int TYPE_ID_1 =
+ TestMessageSetExtension1.getDescriptor().getExtensions().get(0).getNumber();
+ private static final int TYPE_ID_2 =
+ TestMessageSetExtension2.getDescriptor().getExtensions().get(0).getNumber();
+
+ public void testSerializeMessageSetEagerly() throws Exception {
+ testSerializeMessageSetWithFlag(true);
+ }
+
+ public void testSerializeMessageSetNotEagerly() throws Exception {
+ testSerializeMessageSetWithFlag(false);
+ }
+
+ private void testSerializeMessageSetWithFlag(boolean eagerParsing)
+ throws Exception {
+ ExtensionRegistryLite.setEagerlyParseMessageSets(eagerParsing);
+ // Set up a TestMessageSet with two known messages and an unknown one.
+ TestMessageSet messageSet =
+ TestMessageSet.newBuilder()
+ .setExtension(
+ TestMessageSetExtension1.messageSetExtension,
+ TestMessageSetExtension1.newBuilder().setI(123).build())
+ .setExtension(
+ TestMessageSetExtension2.messageSetExtension,
+ TestMessageSetExtension2.newBuilder().setStr("foo").build())
+ .setUnknownFields(
+ UnknownFieldSet.newBuilder()
+ .addField(UNKNOWN_TYPE_ID,
+ UnknownFieldSet.Field.newBuilder()
+ .addLengthDelimited(ByteString.copyFromUtf8("bar"))
+ .build())
+ .build())
+ .build();
+
+ ByteString data = messageSet.toByteString();
+
+ // Parse back using RawMessageSet and check the contents.
+ RawMessageSet raw = RawMessageSet.parseFrom(data);
+
+ assertTrue(raw.getUnknownFields().asMap().isEmpty());
+
+ assertEquals(3, raw.getItemCount());
+ assertEquals(TYPE_ID_1, raw.getItem(0).getTypeId());
+ assertEquals(TYPE_ID_2, raw.getItem(1).getTypeId());
+ assertEquals(UNKNOWN_TYPE_ID, raw.getItem(2).getTypeId());
+
+ TestMessageSetExtension1 message1 =
+ TestMessageSetExtension1.parseFrom(
+ raw.getItem(0).getMessage().toByteArray());
+ assertEquals(123, message1.getI());
+
+ TestMessageSetExtension2 message2 =
+ TestMessageSetExtension2.parseFrom(
+ raw.getItem(1).getMessage().toByteArray());
+ assertEquals("foo", message2.getStr());
+
+ assertEquals("bar", raw.getItem(2).getMessage().toStringUtf8());
+ }
+
+ public void testParseMessageSetEagerly() throws Exception {
+ testParseMessageSetWithFlag(true);
+ }
+
+ public void testParseMessageSetNotEagerly()throws Exception {
+ testParseMessageSetWithFlag(false);
+ }
+
+ private void testParseMessageSetWithFlag(boolean eagerParsing)
+ throws Exception {
+ ExtensionRegistryLite.setEagerlyParseMessageSets(eagerParsing);
+ ExtensionRegistry extensionRegistry = ExtensionRegistry.newInstance();
+ extensionRegistry.add(TestMessageSetExtension1.messageSetExtension);
+ extensionRegistry.add(TestMessageSetExtension2.messageSetExtension);
+
+ // Set up a RawMessageSet with two known messages and an unknown one.
+ RawMessageSet raw =
+ RawMessageSet.newBuilder()
+ .addItem(
+ RawMessageSet.Item.newBuilder()
+ .setTypeId(TYPE_ID_1)
+ .setMessage(
+ TestMessageSetExtension1.newBuilder()
+ .setI(123)
+ .build().toByteString())
+ .build())
+ .addItem(
+ RawMessageSet.Item.newBuilder()
+ .setTypeId(TYPE_ID_2)
+ .setMessage(
+ TestMessageSetExtension2.newBuilder()
+ .setStr("foo")
+ .build().toByteString())
+ .build())
+ .addItem(
+ RawMessageSet.Item.newBuilder()
+ .setTypeId(UNKNOWN_TYPE_ID)
+ .setMessage(ByteString.copyFromUtf8("bar"))
+ .build())
+ .build();
+
+ ByteString data = raw.toByteString();
+
+ // Parse as a TestMessageSet and check the contents.
+ TestMessageSet messageSet =
+ TestMessageSet.parseFrom(data, extensionRegistry);
+
+ assertEquals(123, messageSet.getExtension(
+ TestMessageSetExtension1.messageSetExtension).getI());
+ assertEquals("foo", messageSet.getExtension(
+ TestMessageSetExtension2.messageSetExtension).getStr());
+
+ // Check for unknown field with type LENGTH_DELIMITED,
+ // number UNKNOWN_TYPE_ID, and contents "bar".
+ UnknownFieldSet unknownFields = messageSet.getUnknownFields();
+ assertEquals(1, unknownFields.asMap().size());
+ assertTrue(unknownFields.hasField(UNKNOWN_TYPE_ID));
+
+ UnknownFieldSet.Field field = unknownFields.getField(UNKNOWN_TYPE_ID);
+ assertEquals(1, field.getLengthDelimitedList().size());
+ assertEquals("bar", field.getLengthDelimitedList().get(0).toStringUtf8());
+ }
+
+ public void testParseMessageSetExtensionEagerly() throws Exception {
+ testParseMessageSetExtensionWithFlag(true);
+ }
+
+ public void testParseMessageSetExtensionNotEagerly() throws Exception {
+ testParseMessageSetExtensionWithFlag(false);
+ }
+
+ private void testParseMessageSetExtensionWithFlag(boolean eagerParsing)
+ throws Exception {
+ ExtensionRegistryLite.setEagerlyParseMessageSets(eagerParsing);
+ ExtensionRegistry extensionRegistry = ExtensionRegistry.newInstance();
+ extensionRegistry.add(TestMessageSetExtension1.messageSetExtension);
+
+ // Set up a RawMessageSet with a known messages.
+ int TYPE_ID_1 =
+ TestMessageSetExtension1
+ .getDescriptor().getExtensions().get(0).getNumber();
+ RawMessageSet raw =
+ RawMessageSet.newBuilder()
+ .addItem(
+ RawMessageSet.Item.newBuilder()
+ .setTypeId(TYPE_ID_1)
+ .setMessage(
+ TestMessageSetExtension1.newBuilder()
+ .setI(123)
+ .build().toByteString())
+ .build())
+ .build();
+
+ ByteString data = raw.toByteString();
+
+ // Parse as a TestMessageSet and check the contents.
+ TestMessageSet messageSet =
+ TestMessageSet.parseFrom(data, extensionRegistry);
+ assertEquals(123, messageSet.getExtension(
+ TestMessageSetExtension1.messageSetExtension).getI());
+ }
+
+ public void testMergeLazyMessageSetExtensionEagerly() throws Exception {
+ testMergeLazyMessageSetExtensionWithFlag(true);
+ }
+
+ public void testMergeLazyMessageSetExtensionNotEagerly() throws Exception {
+ testMergeLazyMessageSetExtensionWithFlag(false);
+ }
+
+ private void testMergeLazyMessageSetExtensionWithFlag(boolean eagerParsing)
+ throws Exception {
+ ExtensionRegistryLite.setEagerlyParseMessageSets(eagerParsing);
+ ExtensionRegistry extensionRegistry = ExtensionRegistry.newInstance();
+ extensionRegistry.add(TestMessageSetExtension1.messageSetExtension);
+
+ // Set up a RawMessageSet with a known messages.
+ int TYPE_ID_1 =
+ TestMessageSetExtension1
+ .getDescriptor().getExtensions().get(0).getNumber();
+ RawMessageSet raw =
+ RawMessageSet.newBuilder()
+ .addItem(
+ RawMessageSet.Item.newBuilder()
+ .setTypeId(TYPE_ID_1)
+ .setMessage(
+ TestMessageSetExtension1.newBuilder()
+ .setI(123)
+ .build().toByteString())
+ .build())
+ .build();
+
+ ByteString data = raw.toByteString();
+
+ // Parse as a TestMessageSet and store value into lazy field
+ TestMessageSet messageSet =
+ TestMessageSet.parseFrom(data, extensionRegistry);
+ // Merge lazy field check the contents.
+ messageSet =
+ messageSet.toBuilder().mergeFrom(data, extensionRegistry).build();
+ assertEquals(123, messageSet.getExtension(
+ TestMessageSetExtension1.messageSetExtension).getI());
+ }
+}
diff --git a/java/core/generate-sources-build.xml b/java/core/generate-sources-build.xml
new file mode 100644
index 00000000..0996e5ff
--- /dev/null
+++ b/java/core/generate-sources-build.xml
@@ -0,0 +1,20 @@
+<project name="generate-sources">
+ <echo message="Running protoc ..."/>
+ <mkdir dir="${generated.sources.dir}"/>
+ <exec executable="${protoc}">
+ <arg value="--java_out=${generated.sources.dir}"/>
+ <arg value="--proto_path=${protobuf.source.dir}"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/any.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/api.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/descriptor.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/duration.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/empty.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/field_mask.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/source_context.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/struct.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/timestamp.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/type.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/wrappers.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/compiler/plugin.proto"/>
+ </exec>
+</project> \ No newline at end of file
diff --git a/java/core/generate-test-sources-build.xml b/java/core/generate-test-sources-build.xml
new file mode 100644
index 00000000..ab415db6
--- /dev/null
+++ b/java/core/generate-test-sources-build.xml
@@ -0,0 +1,43 @@
+<project name="generate-test-sources">
+ <mkdir dir="${generated.testsources.dir}"/>
+ <exec executable="${protoc}">
+ <arg value="--java_out=${generated.testsources.dir}"/>
+ <arg value="--proto_path=${protobuf.source.dir}"/>
+ <arg value="--proto_path=${test.proto.dir}"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/unittest.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/unittest_import.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/unittest_import_public.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/unittest_mset.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/unittest_mset_wire_format.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/unittest_optimize_for.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/unittest_custom_options.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/unittest_lite.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/unittest_import_lite.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/unittest_import_public_lite.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/unittest_lite_imports_nonlite.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/unittest_enormous_descriptor.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/unittest_no_generic_services.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/unittest_well_known_types.proto"/>
+ <arg value="${test.proto.dir}/com/google/protobuf/lazy_fields_lite.proto"/>
+ <arg value="${test.proto.dir}/com/google/protobuf/lite_equals_and_hash.proto"/>
+ <arg value="${test.proto.dir}/com/google/protobuf/multiple_files_test.proto"/>
+ <arg value="${test.proto.dir}/com/google/protobuf/nested_builders_test.proto"/>
+ <arg value="${test.proto.dir}/com/google/protobuf/nested_extension.proto"/>
+ <arg value="${test.proto.dir}/com/google/protobuf/nested_extension_lite.proto"/>
+ <arg value="${test.proto.dir}/com/google/protobuf/non_nested_extension.proto"/>
+ <arg value="${test.proto.dir}/com/google/protobuf/non_nested_extension_lite.proto"/>
+ <arg value="${test.proto.dir}/com/google/protobuf/outer_class_name_test.proto"/>
+ <arg value="${test.proto.dir}/com/google/protobuf/outer_class_name_test2.proto"/>
+ <arg value="${test.proto.dir}/com/google/protobuf/outer_class_name_test3.proto"/>
+ <arg value="${test.proto.dir}/com/google/protobuf/test_bad_identifiers.proto"/>
+ <arg value="${test.proto.dir}/com/google/protobuf/test_check_utf8.proto"/>
+ <arg value="${test.proto.dir}/com/google/protobuf/test_check_utf8_size.proto"/>
+ <arg value="${test.proto.dir}/com/google/protobuf/test_custom_options.proto"/>
+ <arg value="${test.proto.dir}/com/google/protobuf/any_test.proto"/>
+ <arg value="${test.proto.dir}/com/google/protobuf/field_presence_test.proto"/>
+ <arg value="${test.proto.dir}/com/google/protobuf/map_for_proto2_lite_test.proto"/>
+ <arg value="${test.proto.dir}/com/google/protobuf/map_for_proto2_test.proto"/>
+ <arg value="${test.proto.dir}/com/google/protobuf/map_test.proto"/>
+ <arg value="${test.proto.dir}/com/google/protobuf/map_initialization_order_test.proto"/>
+ </exec>
+</project> \ No newline at end of file
diff --git a/java/core/pom.xml b/java/core/pom.xml
new file mode 100644
index 00000000..39d67818
--- /dev/null
+++ b/java/core/pom.xml
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>com.google.protobuf</groupId>
+ <artifactId>protobuf-parent</artifactId>
+ <version>3.0.0</version>
+ </parent>
+
+ <artifactId>protobuf-java</artifactId>
+ <packaging>bundle</packaging>
+
+ <name>Protocol Buffers [Core]</name>
+ <description>
+ Core Protocol Buffers library. Protocol Buffers are a way of encoding structured data in an
+ efficient yet extensible format.
+ </description>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.easymock</groupId>
+ <artifactId>easymock</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.easymock</groupId>
+ <artifactId>easymockclassextension</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <!-- Include core protos in the bundle as resources -->
+ <resources>
+ <resource>
+ <directory>${protobuf.source.dir}</directory>
+ <includes>
+ <include>google/protobuf/any.proto</include>
+ <include>google/protobuf/api.proto</include>
+ <include>google/protobuf/descriptor.proto</include>
+ <include>google/protobuf/duration.proto</include>
+ <include>google/protobuf/empty.proto</include>
+ <include>google/protobuf/field_mask.proto</include>
+ <include>google/protobuf/source_context.proto</include>
+ <include>google/protobuf/struct.proto</include>
+ <include>google/protobuf/timestamp.proto</include>
+ <include>google/protobuf/type.proto</include>
+ <include>google/protobuf/wrappers.proto</include>
+ <include>google/protobuf/compiler/plugin.proto</include>
+ </includes>
+ </resource>
+ </resources>
+
+ <plugins>
+ <!-- Use Antrun plugin to generate sources with protoc -->
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <executions>
+ <!-- Generate core protos -->
+ <execution>
+ <id>generate-sources</id>
+ <phase>generate-sources</phase>
+ <configuration>
+ <target>
+ <ant antfile="generate-sources-build.xml"/>
+ </target>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+
+ <!-- Generate the test protos -->
+ <execution>
+ <id>generate-test-sources</id>
+ <phase>generate-test-sources</phase>
+ <configuration>
+ <target>
+ <ant antfile="generate-test-sources-build.xml"/>
+ </target>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ <!-- Add the generated sources to the build -->
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <generatedSourcesDirectory>${generated.sources.dir}</generatedSourcesDirectory>
+ <generatedTestSourcesDirectory>${generated.testsources.dir}</generatedTestSourcesDirectory>
+ </configuration>
+ </plugin>
+
+ <!-- OSGI bundle configuration -->
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Bundle-DocURL>https://developers.google.com/protocol-buffers/</Bundle-DocURL>
+ <Bundle-SymbolicName>com.google.protobuf</Bundle-SymbolicName>
+ <Export-Package>com.google.protobuf;version=${project.version}</Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/java/src/main/java/com/google/protobuf/AbstractMessage.java b/java/core/src/main/java/com/google/protobuf/AbstractMessage.java
index cc89173a..7639efcf 100644
--- a/java/src/main/java/com/google/protobuf/AbstractMessage.java
+++ b/java/core/src/main/java/com/google/protobuf/AbstractMessage.java
@@ -30,6 +30,7 @@
package com.google.protobuf;
+import com.google.protobuf.Descriptors.EnumValueDescriptor;
import com.google.protobuf.Descriptors.FieldDescriptor;
import com.google.protobuf.Descriptors.OneofDescriptor;
import com.google.protobuf.Internal.EnumLite;
@@ -49,17 +50,51 @@ import java.util.Map;
*
* @author kenton@google.com Kenton Varda
*/
-public abstract class AbstractMessage extends AbstractMessageLite
- implements Message {
+public abstract class AbstractMessage
+ // TODO(dweis): Update GeneratedMessage to parameterize with MessageType and BuilderType.
+ extends AbstractMessageLite
+ implements Message {
+
+ @Override
public boolean isInitialized() {
return MessageReflection.isInitialized(this);
}
+ /**
+ * Interface for the parent of a Builder that allows the builder to
+ * communicate invalidations back to the parent for use when using nested
+ * builders.
+ */
+ protected interface BuilderParent {
+ /**
+ * A builder becomes dirty whenever a field is modified -- including fields
+ * in nested builders -- and becomes clean when build() is called. Thus,
+ * when a builder becomes dirty, all its parents become dirty as well, and
+ * when it becomes clean, all its children become clean. The dirtiness
+ * state is used to invalidate certain cached values.
+ * <br>
+ * To this end, a builder calls markDirty() on its parent whenever it
+ * transitions from clean to dirty. The parent must propagate this call to
+ * its own parent, unless it was already dirty, in which case the
+ * grandparent must necessarily already be dirty as well. The parent can
+ * only transition back to "clean" after calling build() on all children.
+ */
+ void markDirty();
+ }
+
+ /** Create a nested builder. */
+ protected Message.Builder newBuilderForType(BuilderParent parent) {
+ throw new UnsupportedOperationException("Nested builder is not supported for this type.");
+ }
+
+
+ @Override
public List<String> findInitializationErrors() {
return MessageReflection.findMissingFields(this);
}
+ @Override
public String getInitializationErrorString() {
return MessageReflection.delimitWithCommas(findInitializationErrors());
}
@@ -82,12 +117,14 @@ public abstract class AbstractMessage extends AbstractMessageLite
return TextFormat.printToString(this);
}
+ @Override
public void writeTo(final CodedOutputStream output) throws IOException {
MessageReflection.writeMessageTo(this, getAllFields(), output, false);
}
protected int memoizedSize = -1;
+ @Override
public int getSerializedSize() {
int size = memoizedSize;
if (size != -1) {
@@ -161,10 +198,18 @@ public abstract class AbstractMessage extends AbstractMessageLite
Descriptors.Descriptor descriptor = entry.getDescriptorForType();
Descriptors.FieldDescriptor key = descriptor.findFieldByName("key");
Descriptors.FieldDescriptor value = descriptor.findFieldByName("value");
- result.put(entry.getField(key), entry.getField(value));
+ Object fieldValue = entry.getField(value);
+ if (fieldValue instanceof EnumValueDescriptor) {
+ fieldValue = ((EnumValueDescriptor) fieldValue).getNumber();
+ }
+ result.put(entry.getField(key), fieldValue);
while (iterator.hasNext()) {
entry = (Message) iterator.next();
- result.put(entry.getField(key), entry.getField(value));
+ fieldValue = entry.getField(value);
+ if (fieldValue instanceof EnumValueDescriptor) {
+ fieldValue = ((EnumValueDescriptor) fieldValue).getNumber();
+ }
+ result.put(entry.getField(key), fieldValue);
}
return result;
}
@@ -279,8 +324,8 @@ public abstract class AbstractMessage extends AbstractMessageLite
* other methods.
*/
@SuppressWarnings("unchecked")
- public static abstract class Builder<BuilderType extends Builder>
- extends AbstractMessageLite.Builder<BuilderType>
+ public static abstract class Builder<BuilderType extends Builder<BuilderType>>
+ extends AbstractMessageLite.Builder
implements Message.Builder {
// The compiler produces an error if this is not declared explicitly.
@Override
@@ -305,6 +350,7 @@ public abstract class AbstractMessage extends AbstractMessageLite
throw new UnsupportedOperationException("clearOneof() is not implemented.");
}
+ @Override
public BuilderType clear() {
for (final Map.Entry<FieldDescriptor, Object> entry :
getAllFields().entrySet()) {
@@ -313,14 +359,22 @@ public abstract class AbstractMessage extends AbstractMessageLite
return (BuilderType) this;
}
+ @Override
public List<String> findInitializationErrors() {
return MessageReflection.findMissingFields(this);
}
+ @Override
public String getInitializationErrorString() {
return MessageReflection.delimitWithCommas(findInitializationErrors());
}
+
+ @Override
+ protected BuilderType internalMergeFrom(AbstractMessageLite other) {
+ return mergeFrom((Message) other);
+ }
+ @Override
public BuilderType mergeFrom(final Message other) {
if (other.getDescriptorForType() != getDescriptorForType()) {
throw new IllegalArgumentException(
@@ -398,6 +452,7 @@ public abstract class AbstractMessage extends AbstractMessageLite
return (BuilderType) this;
}
+ @Override
public BuilderType mergeUnknownFields(final UnknownFieldSet unknownFields) {
setUnknownFields(
UnknownFieldSet.newBuilder(getUnknownFields())
@@ -406,17 +461,19 @@ public abstract class AbstractMessage extends AbstractMessageLite
return (BuilderType) this;
}
+ @Override
public Message.Builder getFieldBuilder(final FieldDescriptor field) {
throw new UnsupportedOperationException(
"getFieldBuilder() called on an unsupported message type.");
}
- public Message.Builder getRepeatedFieldBuilder(final FieldDescriptor field,
- int index) {
+ @Override
+ public Message.Builder getRepeatedFieldBuilder(final FieldDescriptor field, int index) {
throw new UnsupportedOperationException(
"getRepeatedFieldBuilder() called on an unsupported message type.");
}
+ @Override
public String toString() {
return TextFormat.printToString(this);
}
@@ -431,6 +488,31 @@ public abstract class AbstractMessage extends AbstractMessageLite
MessageReflection.findMissingFields(message));
}
+ /**
+ * Used to support nested builders and called to mark this builder as clean.
+ * Clean builders will propagate the {@link BuilderParent#markDirty()} event
+ * to their parent builders, while dirty builders will not, as their parents
+ * should be dirty already.
+ *
+ * NOTE: Implementations that don't support nested builders don't need to
+ * override this method.
+ */
+ void markClean() {
+ throw new IllegalStateException("Should be overridden by subclasses.");
+ }
+
+ /**
+ * Used to support nested builders and called when this nested builder is
+ * no longer used by its parent builder and should release the reference
+ * to its parent builder.
+ *
+ * NOTE: Implementations that don't support nested builders don't need to
+ * override this method.
+ */
+ void dispose() {
+ throw new IllegalStateException("Should be overridden by subclasses.");
+ }
+
// ===============================================================
// The following definitions seem to be required in order to make javac
// not produce weird errors like:
@@ -453,7 +535,7 @@ public abstract class AbstractMessage extends AbstractMessageLite
@Override
public BuilderType mergeFrom(final ByteString data)
throws InvalidProtocolBufferException {
- return super.mergeFrom(data);
+ return (BuilderType) super.mergeFrom(data);
}
@Override
@@ -461,20 +543,20 @@ public abstract class AbstractMessage extends AbstractMessageLite
final ByteString data,
final ExtensionRegistryLite extensionRegistry)
throws InvalidProtocolBufferException {
- return super.mergeFrom(data, extensionRegistry);
+ return (BuilderType) super.mergeFrom(data, extensionRegistry);
}
@Override
public BuilderType mergeFrom(final byte[] data)
throws InvalidProtocolBufferException {
- return super.mergeFrom(data);
+ return (BuilderType) super.mergeFrom(data);
}
@Override
public BuilderType mergeFrom(
final byte[] data, final int off, final int len)
throws InvalidProtocolBufferException {
- return super.mergeFrom(data, off, len);
+ return (BuilderType) super.mergeFrom(data, off, len);
}
@Override
@@ -482,7 +564,7 @@ public abstract class AbstractMessage extends AbstractMessageLite
final byte[] data,
final ExtensionRegistryLite extensionRegistry)
throws InvalidProtocolBufferException {
- return super.mergeFrom(data, extensionRegistry);
+ return (BuilderType) super.mergeFrom(data, extensionRegistry);
}
@Override
@@ -490,13 +572,13 @@ public abstract class AbstractMessage extends AbstractMessageLite
final byte[] data, final int off, final int len,
final ExtensionRegistryLite extensionRegistry)
throws InvalidProtocolBufferException {
- return super.mergeFrom(data, off, len, extensionRegistry);
+ return (BuilderType) super.mergeFrom(data, off, len, extensionRegistry);
}
@Override
public BuilderType mergeFrom(final InputStream input)
throws IOException {
- return super.mergeFrom(input);
+ return (BuilderType) super.mergeFrom(input);
}
@Override
@@ -504,7 +586,7 @@ public abstract class AbstractMessage extends AbstractMessageLite
final InputStream input,
final ExtensionRegistryLite extensionRegistry)
throws IOException {
- return super.mergeFrom(input, extensionRegistry);
+ return (BuilderType) super.mergeFrom(input, extensionRegistry);
}
@Override
@@ -521,4 +603,44 @@ public abstract class AbstractMessage extends AbstractMessageLite
return super.mergeDelimitedFrom(input, extensionRegistry);
}
}
+
+ /**
+ * @deprecated from v3.0.0-beta-3+, for compatibility with v2.5.0 and v2.6.1
+ * generated code.
+ */
+ @Deprecated
+ protected static int hashLong(long n) {
+ return (int) (n ^ (n >>> 32));
+ }
+ //
+ /**
+ * @deprecated from v3.0.0-beta-3+, for compatibility with v2.5.0 and v2.6.1
+ * generated code.
+ */
+ @Deprecated
+ protected static int hashBoolean(boolean b) {
+ return b ? 1231 : 1237;
+ }
+ //
+ /**
+ * @deprecated from v3.0.0-beta-3+, for compatibility with v2.5.0 and v2.6.1
+ * generated code.
+ */
+ @Deprecated
+ protected static int hashEnum(EnumLite e) {
+ return e.getNumber();
+ }
+ //
+ /**
+ * @deprecated from v3.0.0-beta-3+, for compatibility with v2.5.0 and v2.6.1
+ * generated code.
+ */
+ @Deprecated
+ protected static int hashEnumList(List<? extends EnumLite> list) {
+ int hash = 1;
+ for (EnumLite e : list) {
+ hash = 31 * hash + hashEnum(e);
+ }
+ return hash;
+ }
}
diff --git a/java/src/main/java/com/google/protobuf/AbstractMessageLite.java b/java/core/src/main/java/com/google/protobuf/AbstractMessageLite.java
index 12384983..046030f3 100644
--- a/java/src/main/java/com/google/protobuf/AbstractMessageLite.java
+++ b/java/core/src/main/java/com/google/protobuf/AbstractMessageLite.java
@@ -43,9 +43,13 @@ import java.util.Collection;
*
* @author kenton@google.com Kenton Varda
*/
-public abstract class AbstractMessageLite implements MessageLite {
+public abstract class AbstractMessageLite<
+ MessageType extends AbstractMessageLite<MessageType, BuilderType>,
+ BuilderType extends AbstractMessageLite.Builder<MessageType, BuilderType>>
+ implements MessageLite {
protected int memoizedHashCode = 0;
+ @Override
public ByteString toByteString() {
try {
final ByteString.CodedBuilder out =
@@ -53,12 +57,11 @@ public abstract class AbstractMessageLite implements MessageLite {
writeTo(out.getCodedOutput());
return out.build();
} catch (IOException e) {
- throw new RuntimeException(
- "Serializing to a ByteString threw an IOException (should " +
- "never happen).", e);
+ throw new RuntimeException(getSerializingExceptionMessage("ByteString"), e);
}
}
+ @Override
public byte[] toByteArray() {
try {
final byte[] result = new byte[getSerializedSize()];
@@ -67,12 +70,11 @@ public abstract class AbstractMessageLite implements MessageLite {
output.checkNoSpaceLeft();
return result;
} catch (IOException e) {
- throw new RuntimeException(
- "Serializing to a byte array threw an IOException " +
- "(should never happen).", e);
+ throw new RuntimeException(getSerializingExceptionMessage("byte array"), e);
}
}
+ @Override
public void writeTo(final OutputStream output) throws IOException {
final int bufferSize =
CodedOutputStream.computePreferredBufferSize(getSerializedSize());
@@ -82,6 +84,7 @@ public abstract class AbstractMessageLite implements MessageLite {
codedOutput.flush();
}
+ @Override
public void writeDelimitedTo(final OutputStream output) throws IOException {
final int serialized = getSerializedSize();
final int bufferSize = CodedOutputStream.computePreferredBufferSize(
@@ -102,6 +105,11 @@ public abstract class AbstractMessageLite implements MessageLite {
return new UninitializedMessageException(this);
}
+ private String getSerializingExceptionMessage(String target) {
+ return "Serializing " + getClass().getName() + " to a " + target
+ + " threw an IOException (should never happen).";
+ }
+
protected static void checkByteStringIsUtf8(ByteString byteString)
throws IllegalArgumentException {
if (!byteString.isValidUtf8()) {
@@ -113,32 +121,34 @@ public abstract class AbstractMessageLite implements MessageLite {
final Collection<? super T> list) {
Builder.addAll(values, list);
}
-
+
/**
* A partial implementation of the {@link Message.Builder} interface which
* implements as many methods of that interface as possible in terms of
* other methods.
*/
@SuppressWarnings("unchecked")
- public static abstract class Builder<BuilderType extends Builder>
+ public abstract static class Builder<
+ MessageType extends AbstractMessageLite<MessageType, BuilderType>,
+ BuilderType extends Builder<MessageType, BuilderType>>
implements MessageLite.Builder {
// The compiler produces an error if this is not declared explicitly.
@Override
public abstract BuilderType clone();
- public BuilderType mergeFrom(final CodedInputStream input)
- throws IOException {
+ @Override
+ public BuilderType mergeFrom(final CodedInputStream input) throws IOException {
return mergeFrom(input, ExtensionRegistryLite.getEmptyRegistry());
}
// Re-defined here for return type covariance.
+ @Override
public abstract BuilderType mergeFrom(
- final CodedInputStream input,
- final ExtensionRegistryLite extensionRegistry)
+ final CodedInputStream input, final ExtensionRegistryLite extensionRegistry)
throws IOException;
- public BuilderType mergeFrom(final ByteString data)
- throws InvalidProtocolBufferException {
+ @Override
+ public BuilderType mergeFrom(final ByteString data) throws InvalidProtocolBufferException {
try {
final CodedInputStream input = data.newCodedInput();
mergeFrom(input);
@@ -147,15 +157,13 @@ public abstract class AbstractMessageLite implements MessageLite {
} catch (InvalidProtocolBufferException e) {
throw e;
} catch (IOException e) {
- throw new RuntimeException(
- "Reading from a ByteString threw an IOException (should " +
- "never happen).", e);
+ throw new RuntimeException(getReadingExceptionMessage("ByteString"), e);
}
}
+ @Override
public BuilderType mergeFrom(
- final ByteString data,
- final ExtensionRegistryLite extensionRegistry)
+ final ByteString data, final ExtensionRegistryLite extensionRegistry)
throws InvalidProtocolBufferException {
try {
final CodedInputStream input = data.newCodedInput();
@@ -165,20 +173,18 @@ public abstract class AbstractMessageLite implements MessageLite {
} catch (InvalidProtocolBufferException e) {
throw e;
} catch (IOException e) {
- throw new RuntimeException(
- "Reading from a ByteString threw an IOException (should " +
- "never happen).", e);
+ throw new RuntimeException(getReadingExceptionMessage("ByteString"), e);
}
}
- public BuilderType mergeFrom(final byte[] data)
- throws InvalidProtocolBufferException {
+ @Override
+ public BuilderType mergeFrom(final byte[] data) throws InvalidProtocolBufferException {
return mergeFrom(data, 0, data.length);
}
- public BuilderType mergeFrom(final byte[] data, final int off,
- final int len)
- throws InvalidProtocolBufferException {
+ @Override
+ public BuilderType mergeFrom(final byte[] data, final int off, final int len)
+ throws InvalidProtocolBufferException {
try {
final CodedInputStream input =
CodedInputStream.newInstance(data, off, len);
@@ -188,21 +194,21 @@ public abstract class AbstractMessageLite implements MessageLite {
} catch (InvalidProtocolBufferException e) {
throw e;
} catch (IOException e) {
- throw new RuntimeException(
- "Reading from a byte array threw an IOException (should " +
- "never happen).", e);
+ throw new RuntimeException(getReadingExceptionMessage("byte array"), e);
}
}
- public BuilderType mergeFrom(
- final byte[] data,
- final ExtensionRegistryLite extensionRegistry)
+ @Override
+ public BuilderType mergeFrom(final byte[] data, final ExtensionRegistryLite extensionRegistry)
throws InvalidProtocolBufferException {
return mergeFrom(data, 0, data.length, extensionRegistry);
}
+ @Override
public BuilderType mergeFrom(
- final byte[] data, final int off, final int len,
+ final byte[] data,
+ final int off,
+ final int len,
final ExtensionRegistryLite extensionRegistry)
throws InvalidProtocolBufferException {
try {
@@ -214,12 +220,11 @@ public abstract class AbstractMessageLite implements MessageLite {
} catch (InvalidProtocolBufferException e) {
throw e;
} catch (IOException e) {
- throw new RuntimeException(
- "Reading from a byte array threw an IOException (should " +
- "never happen).", e);
+ throw new RuntimeException(getReadingExceptionMessage("byte array"), e);
}
}
+ @Override
public BuilderType mergeFrom(final InputStream input) throws IOException {
final CodedInputStream codedInput = CodedInputStream.newInstance(input);
mergeFrom(codedInput);
@@ -227,10 +232,9 @@ public abstract class AbstractMessageLite implements MessageLite {
return (BuilderType) this;
}
+ @Override
public BuilderType mergeFrom(
- final InputStream input,
- final ExtensionRegistryLite extensionRegistry)
- throws IOException {
+ final InputStream input, final ExtensionRegistryLite extensionRegistry) throws IOException {
final CodedInputStream codedInput = CodedInputStream.newInstance(input);
mergeFrom(codedInput, extensionRegistry);
codedInput.checkLastTagWas(0);
@@ -292,10 +296,9 @@ public abstract class AbstractMessageLite implements MessageLite {
}
}
+ @Override
public boolean mergeDelimitedFrom(
- final InputStream input,
- final ExtensionRegistryLite extensionRegistry)
- throws IOException {
+ final InputStream input, final ExtensionRegistryLite extensionRegistry) throws IOException {
final int firstByte = input.read();
if (firstByte == -1) {
return false;
@@ -306,12 +309,30 @@ public abstract class AbstractMessageLite implements MessageLite {
return true;
}
- public boolean mergeDelimitedFrom(final InputStream input)
- throws IOException {
+ @Override
+ public boolean mergeDelimitedFrom(final InputStream input) throws IOException {
return mergeDelimitedFrom(input,
ExtensionRegistryLite.getEmptyRegistry());
}
+ @Override
+ @SuppressWarnings("unchecked") // isInstance takes care of this
+ public BuilderType mergeFrom(final MessageLite other) {
+ if (!getDefaultInstanceForType().getClass().isInstance(other)) {
+ throw new IllegalArgumentException(
+ "mergeFrom(MessageLite) can only merge messages of the same type.");
+ }
+
+ return internalMergeFrom((MessageType) other);
+ }
+
+ protected abstract BuilderType internalMergeFrom(MessageType message);
+
+ private String getReadingExceptionMessage(String target) {
+ return "Reading " + getClass().getName() + " from a " + target
+ + " threw an IOException (should never happen).";
+ }
+
/**
* Construct an UninitializedMessageException reporting missing fields in
* the given message.
diff --git a/java/src/main/java/com/google/protobuf/AbstractParser.java b/java/core/src/main/java/com/google/protobuf/AbstractParser.java
index 1a4c6311..66b0ee3b 100644
--- a/java/src/main/java/com/google/protobuf/AbstractParser.java
+++ b/java/core/src/main/java/com/google/protobuf/AbstractParser.java
@@ -78,26 +78,27 @@ public abstract class AbstractParser<MessageType extends MessageLite>
private static final ExtensionRegistryLite EMPTY_REGISTRY
= ExtensionRegistryLite.getEmptyRegistry();
+ @Override
public MessageType parsePartialFrom(CodedInputStream input)
throws InvalidProtocolBufferException {
return parsePartialFrom(input, EMPTY_REGISTRY);
}
- public MessageType parseFrom(CodedInputStream input,
- ExtensionRegistryLite extensionRegistry)
+ @Override
+ public MessageType parseFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry)
throws InvalidProtocolBufferException {
return checkMessageInitialized(
parsePartialFrom(input, extensionRegistry));
}
- public MessageType parseFrom(CodedInputStream input)
- throws InvalidProtocolBufferException {
+ @Override
+ public MessageType parseFrom(CodedInputStream input) throws InvalidProtocolBufferException {
return parseFrom(input, EMPTY_REGISTRY);
}
- public MessageType parsePartialFrom(ByteString data,
- ExtensionRegistryLite extensionRegistry)
- throws InvalidProtocolBufferException {
+ @Override
+ public MessageType parsePartialFrom(ByteString data, ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException {
MessageType message;
try {
CodedInputStream input = data.newCodedInput();
@@ -113,24 +114,25 @@ public abstract class AbstractParser<MessageType extends MessageLite>
}
}
- public MessageType parsePartialFrom(ByteString data)
- throws InvalidProtocolBufferException {
+ @Override
+ public MessageType parsePartialFrom(ByteString data) throws InvalidProtocolBufferException {
return parsePartialFrom(data, EMPTY_REGISTRY);
}
- public MessageType parseFrom(ByteString data,
- ExtensionRegistryLite extensionRegistry)
+ @Override
+ public MessageType parseFrom(ByteString data, ExtensionRegistryLite extensionRegistry)
throws InvalidProtocolBufferException {
return checkMessageInitialized(parsePartialFrom(data, extensionRegistry));
}
- public MessageType parseFrom(ByteString data)
- throws InvalidProtocolBufferException {
+ @Override
+ public MessageType parseFrom(ByteString data) throws InvalidProtocolBufferException {
return parseFrom(data, EMPTY_REGISTRY);
}
- public MessageType parsePartialFrom(byte[] data, int off, int len,
- ExtensionRegistryLite extensionRegistry)
+ @Override
+ public MessageType parsePartialFrom(
+ byte[] data, int off, int len, ExtensionRegistryLite extensionRegistry)
throws InvalidProtocolBufferException {
try {
CodedInputStream input = CodedInputStream.newInstance(data, off, len);
@@ -146,47 +148,50 @@ public abstract class AbstractParser<MessageType extends MessageLite>
}
}
+ @Override
public MessageType parsePartialFrom(byte[] data, int off, int len)
throws InvalidProtocolBufferException {
return parsePartialFrom(data, off, len, EMPTY_REGISTRY);
}
- public MessageType parsePartialFrom(byte[] data,
- ExtensionRegistryLite extensionRegistry)
+ @Override
+ public MessageType parsePartialFrom(byte[] data, ExtensionRegistryLite extensionRegistry)
throws InvalidProtocolBufferException {
return parsePartialFrom(data, 0, data.length, extensionRegistry);
}
- public MessageType parsePartialFrom(byte[] data)
- throws InvalidProtocolBufferException {
+ @Override
+ public MessageType parsePartialFrom(byte[] data) throws InvalidProtocolBufferException {
return parsePartialFrom(data, 0, data.length, EMPTY_REGISTRY);
}
- public MessageType parseFrom(byte[] data, int off, int len,
- ExtensionRegistryLite extensionRegistry)
+ @Override
+ public MessageType parseFrom(
+ byte[] data, int off, int len, ExtensionRegistryLite extensionRegistry)
throws InvalidProtocolBufferException {
return checkMessageInitialized(
parsePartialFrom(data, off, len, extensionRegistry));
}
+ @Override
public MessageType parseFrom(byte[] data, int off, int len)
throws InvalidProtocolBufferException {
return parseFrom(data, off, len, EMPTY_REGISTRY);
}
- public MessageType parseFrom(byte[] data,
- ExtensionRegistryLite extensionRegistry)
+ @Override
+ public MessageType parseFrom(byte[] data, ExtensionRegistryLite extensionRegistry)
throws InvalidProtocolBufferException {
return parseFrom(data, 0, data.length, extensionRegistry);
}
- public MessageType parseFrom(byte[] data)
- throws InvalidProtocolBufferException {
+ @Override
+ public MessageType parseFrom(byte[] data) throws InvalidProtocolBufferException {
return parseFrom(data, EMPTY_REGISTRY);
}
- public MessageType parsePartialFrom(InputStream input,
- ExtensionRegistryLite extensionRegistry)
+ @Override
+ public MessageType parsePartialFrom(InputStream input, ExtensionRegistryLite extensionRegistry)
throws InvalidProtocolBufferException {
CodedInputStream codedInput = CodedInputStream.newInstance(input);
MessageType message = parsePartialFrom(codedInput, extensionRegistry);
@@ -198,26 +203,26 @@ public abstract class AbstractParser<MessageType extends MessageLite>
return message;
}
- public MessageType parsePartialFrom(InputStream input)
- throws InvalidProtocolBufferException {
+ @Override
+ public MessageType parsePartialFrom(InputStream input) throws InvalidProtocolBufferException {
return parsePartialFrom(input, EMPTY_REGISTRY);
}
- public MessageType parseFrom(InputStream input,
- ExtensionRegistryLite extensionRegistry)
+ @Override
+ public MessageType parseFrom(InputStream input, ExtensionRegistryLite extensionRegistry)
throws InvalidProtocolBufferException {
return checkMessageInitialized(
parsePartialFrom(input, extensionRegistry));
}
- public MessageType parseFrom(InputStream input)
- throws InvalidProtocolBufferException {
+ @Override
+ public MessageType parseFrom(InputStream input) throws InvalidProtocolBufferException {
return parseFrom(input, EMPTY_REGISTRY);
}
+ @Override
public MessageType parsePartialDelimitedFrom(
- InputStream input,
- ExtensionRegistryLite extensionRegistry)
+ InputStream input, ExtensionRegistryLite extensionRegistry)
throws InvalidProtocolBufferException {
int size;
try {
@@ -233,21 +238,21 @@ public abstract class AbstractParser<MessageType extends MessageLite>
return parsePartialFrom(limitedInput, extensionRegistry);
}
+ @Override
public MessageType parsePartialDelimitedFrom(InputStream input)
throws InvalidProtocolBufferException {
return parsePartialDelimitedFrom(input, EMPTY_REGISTRY);
}
- public MessageType parseDelimitedFrom(
- InputStream input,
- ExtensionRegistryLite extensionRegistry)
+ @Override
+ public MessageType parseDelimitedFrom(InputStream input, ExtensionRegistryLite extensionRegistry)
throws InvalidProtocolBufferException {
return checkMessageInitialized(
parsePartialDelimitedFrom(input, extensionRegistry));
}
- public MessageType parseDelimitedFrom(InputStream input)
- throws InvalidProtocolBufferException {
+ @Override
+ public MessageType parseDelimitedFrom(InputStream input) throws InvalidProtocolBufferException {
return parseDelimitedFrom(input, EMPTY_REGISTRY);
}
}
diff --git a/java/src/main/java/com/google/protobuf/AbstractProtobufList.java b/java/core/src/main/java/com/google/protobuf/AbstractProtobufList.java
index bb6446b2..b17db6e0 100644
--- a/java/src/main/java/com/google/protobuf/AbstractProtobufList.java
+++ b/java/core/src/main/java/com/google/protobuf/AbstractProtobufList.java
@@ -34,19 +34,25 @@ import com.google.protobuf.Internal.ProtobufList;
import java.util.AbstractList;
import java.util.Collection;
+import java.util.List;
+import java.util.RandomAccess;
/**
* An abstract implementation of {@link ProtobufList} which manages mutability semantics. All mutate
- * methods are check if the list is mutable before proceeding. Subclasses must invoke
+ * methods must check if the list is mutable before proceeding. Subclasses must invoke
* {@link #ensureIsMutable()} manually when overriding those methods.
+ * <p>
+ * This implementation assumes all subclasses are array based, supporting random access.
*/
abstract class AbstractProtobufList<E> extends AbstractList<E> implements ProtobufList<E> {
+ protected static final int DEFAULT_CAPACITY = 10;
+
/**
* Whether or not this list is modifiable.
*/
private boolean isMutable;
-
+
/**
* Constructs a mutable list by default.
*/
@@ -55,6 +61,44 @@ abstract class AbstractProtobufList<E> extends AbstractList<E> implements Protob
}
@Override
+ public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ if (!(o instanceof List)) {
+ return false;
+ }
+ // Handle lists that do not support RandomAccess as efficiently as possible by using an iterator
+ // based approach in our super class. Otherwise our index based approach will avoid those
+ // allocations.
+ if (!(o instanceof RandomAccess)) {
+ return super.equals(o);
+ }
+
+ List<?> other = (List<?>) o;
+ final int size = size();
+ if (size != other.size()) {
+ return false;
+ }
+ for (int i = 0; i < size; i++) {
+ if (!get(i).equals(other.get(i))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ final int size = size();
+ int hashCode = 1;
+ for (int i = 0; i < size; i++) {
+ hashCode = (31 * hashCode) + get(i).hashCode();
+ }
+ return hashCode;
+ }
+
+ @Override
public boolean add(E e) {
ensureIsMutable();
return super.add(e);
diff --git a/java/src/main/java/com/google/protobuf/BlockingRpcChannel.java b/java/core/src/main/java/com/google/protobuf/BlockingRpcChannel.java
index d535efb9..d535efb9 100644
--- a/java/src/main/java/com/google/protobuf/BlockingRpcChannel.java
+++ b/java/core/src/main/java/com/google/protobuf/BlockingRpcChannel.java
diff --git a/java/src/main/java/com/google/protobuf/BlockingService.java b/java/core/src/main/java/com/google/protobuf/BlockingService.java
index d01f0b8f..d01f0b8f 100644
--- a/java/src/main/java/com/google/protobuf/BlockingService.java
+++ b/java/core/src/main/java/com/google/protobuf/BlockingService.java
diff --git a/java/src/main/java/com/google/protobuf/BooleanArrayList.java b/java/core/src/main/java/com/google/protobuf/BooleanArrayList.java
index 45492d2f..0d9f87ba 100644
--- a/java/src/main/java/com/google/protobuf/BooleanArrayList.java
+++ b/java/core/src/main/java/com/google/protobuf/BooleanArrayList.java
@@ -34,33 +34,31 @@ import com.google.protobuf.Internal.BooleanList;
import java.util.Arrays;
import java.util.Collection;
-import java.util.List;
import java.util.RandomAccess;
/**
* An implementation of {@link BooleanList} on top of a primitive array.
- *
+ *
* @author dweis@google.com (Daniel Weis)
*/
final class BooleanArrayList
- extends AbstractProtobufList<Boolean> implements BooleanList, RandomAccess {
-
- private static final int DEFAULT_CAPACITY = 10;
-
+ extends AbstractProtobufList<Boolean>
+ implements BooleanList, RandomAccess {
+
private static final BooleanArrayList EMPTY_LIST = new BooleanArrayList();
static {
EMPTY_LIST.makeImmutable();
}
-
+
public static BooleanArrayList emptyList() {
return EMPTY_LIST;
}
-
+
/**
* The backing store for the list.
*/
private boolean[] array;
-
+
/**
* The size of the list distinct from the length of the array. That is, it is the number of
* elements set in the list.
@@ -68,31 +66,61 @@ final class BooleanArrayList
private int size;
/**
- * Constructs a new mutable {@code BooleanArrayList}.
+ * Constructs a new mutable {@code BooleanArrayList} with default capacity.
*/
BooleanArrayList() {
- array = new boolean[DEFAULT_CAPACITY];
- size = 0;
+ this(new boolean[DEFAULT_CAPACITY], 0);
}
/**
- * Constructs a new mutable {@code BooleanArrayList} containing the same elements as
- * {@code other}.
+ * Constructs a new mutable {@code BooleanArrayList}
+ * containing the same elements as {@code other}.
*/
- BooleanArrayList(List<Boolean> other) {
- if (other instanceof BooleanArrayList) {
- BooleanArrayList list = (BooleanArrayList) other;
- array = list.array.clone();
- size = list.size;
- } else {
- size = other.size();
- array = new boolean[size];
- for (int i = 0; i < size; i++) {
- array[i] = other.get(i);
+ private BooleanArrayList(boolean[] other, int size) {
+ array = other;
+ this.size = size;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof BooleanArrayList)) {
+ return super.equals(o);
+ }
+ BooleanArrayList other = (BooleanArrayList) o;
+ if (size != other.size) {
+ return false;
+ }
+
+ final boolean[] arr = other.array;
+ for (int i = 0; i < size; i++) {
+ if (array[i] != arr[i]) {
+ return false;
}
}
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = 1;
+ for (int i = 0; i < size; i++) {
+ result = (31 * result) + Internal.hashBoolean(array[i]);
+ }
+ return result;
}
-
+
+ @Override
+ public BooleanList mutableCopyWithCapacity(int capacity) {
+ if (capacity < size) {
+ throw new IllegalArgumentException();
+ }
+ return new BooleanArrayList(Arrays.copyOf(array, capacity), size);
+ }
+
@Override
public Boolean get(int index) {
return getBoolean(index);
@@ -144,7 +172,7 @@ final class BooleanArrayList
if (index < 0 || index > size) {
throw new IndexOutOfBoundsException(makeOutOfBoundsExceptionMessage(index));
}
-
+
if (size < array.length) {
// Shift everything over to make room
System.arraycopy(array, index, array, index + 1, size - index);
@@ -152,10 +180,10 @@ final class BooleanArrayList
// Resize to 1.5x the size
int length = ((size * 3) / 2) + 1;
boolean[] newArray = new boolean[length];
-
+
// Copy the first part directly
System.arraycopy(array, 0, newArray, 0, index);
-
+
// Copy the rest shifted over by one to make room
System.arraycopy(array, index, newArray, index + 1, size - index);
array = newArray;
@@ -169,38 +197,38 @@ final class BooleanArrayList
@Override
public boolean addAll(Collection<? extends Boolean> collection) {
ensureIsMutable();
-
+
if (collection == null) {
throw new NullPointerException();
}
-
+
// We specialize when adding another BooleanArrayList to avoid boxing elements.
if (!(collection instanceof BooleanArrayList)) {
return super.addAll(collection);
}
-
+
BooleanArrayList list = (BooleanArrayList) collection;
if (list.size == 0) {
return false;
}
-
+
int overflow = Integer.MAX_VALUE - size;
if (overflow < list.size) {
// We can't actually represent a list this large.
throw new OutOfMemoryError();
}
-
+
int newSize = size + list.size;
if (newSize > array.length) {
array = Arrays.copyOf(array, newSize);
}
-
+
System.arraycopy(list.array, 0, array, size, list.size);
size = newSize;
modCount++;
return true;
}
-
+
@Override
public boolean remove(Object o) {
ensureIsMutable();
@@ -229,7 +257,7 @@ final class BooleanArrayList
/**
* Ensures that the provided {@code index} is within the range of {@code [0, size]}. Throws an
* {@link IndexOutOfBoundsException} if it is not.
- *
+ *
* @param index the index to verify is in range
*/
private void ensureIndexInRange(int index) {
diff --git a/java/core/src/main/java/com/google/protobuf/ByteBufferWriter.java b/java/core/src/main/java/com/google/protobuf/ByteBufferWriter.java
new file mode 100644
index 00000000..0cc38175
--- /dev/null
+++ b/java/core/src/main/java/com/google/protobuf/ByteBufferWriter.java
@@ -0,0 +1,145 @@
+// 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.
+
+package com.google.protobuf;
+
+import static java.lang.Math.max;
+import static java.lang.Math.min;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.lang.ref.SoftReference;
+import java.nio.ByteBuffer;
+
+/**
+ * Utility class to provide efficient writing of {@link ByteBuffer}s to {@link OutputStream}s.
+ */
+final class ByteBufferWriter {
+ private ByteBufferWriter() {}
+
+ /**
+ * Minimum size for a cached buffer. This prevents us from allocating buffers that are too
+ * small to be easily reused.
+ */
+ // TODO(nathanmittler): tune this property or allow configuration?
+ private static final int MIN_CACHED_BUFFER_SIZE = 1024;
+
+ /**
+ * Maximum size for a cached buffer. If a larger buffer is required, it will be allocated
+ * but not cached.
+ */
+ // TODO(nathanmittler): tune this property or allow configuration?
+ private static final int MAX_CACHED_BUFFER_SIZE = 16 * 1024;
+
+ /**
+ * The fraction of the requested buffer size under which the buffer will be reallocated.
+ */
+ // TODO(nathanmittler): tune this property or allow configuration?
+ private static final float BUFFER_REALLOCATION_THRESHOLD = 0.5f;
+
+ /**
+ * Keeping a soft reference to a thread-local buffer. This buffer is used for writing a
+ * {@link ByteBuffer} to an {@link OutputStream} when no zero-copy alternative was available.
+ * Using a "soft" reference since VMs may keep this reference around longer than "weak"
+ * (e.g. HotSpot will maintain soft references until memory pressure warrants collection).
+ */
+ private static final ThreadLocal<SoftReference<byte[]>> BUFFER =
+ new ThreadLocal<SoftReference<byte[]>>();
+
+ /**
+ * For testing purposes only. Clears the cached buffer to force a new allocation on the next
+ * invocation.
+ */
+ static void clearCachedBuffer() {
+ BUFFER.set(null);
+ }
+
+ /**
+ * Writes the remaining content of the buffer to the given stream. The buffer {@code position}
+ * will remain unchanged by this method.
+ */
+ static void write(ByteBuffer buffer, OutputStream output) throws IOException {
+ final int initialPos = buffer.position();
+ try {
+ if (buffer.hasArray()) {
+ // Optimized write for array-backed buffers.
+ // Note that we're taking the risk that a malicious OutputStream could modify the array.
+ output.write(buffer.array(), buffer.arrayOffset() + buffer.position(), buffer.remaining());
+ } else if (output instanceof FileOutputStream) {
+ // Use a channel to write out the ByteBuffer. This will automatically empty the buffer.
+ ((FileOutputStream) output).getChannel().write(buffer);
+ } else {
+ // Read all of the data from the buffer to an array.
+ // TODO(nathanmittler): Consider performance improvements for other "known" stream types.
+ final byte[] array = getOrCreateBuffer(buffer.remaining());
+ while (buffer.hasRemaining()) {
+ int length = min(buffer.remaining(), array.length);
+ buffer.get(array, 0, length);
+ output.write(array, 0, length);
+ }
+ }
+ } finally {
+ // Restore the initial position.
+ buffer.position(initialPos);
+ }
+ }
+
+ private static byte[] getOrCreateBuffer(int requestedSize) {
+ requestedSize = max(requestedSize, MIN_CACHED_BUFFER_SIZE);
+
+ byte[] buffer = getBuffer();
+ // Only allocate if we need to.
+ if (buffer == null || needToReallocate(requestedSize, buffer.length)) {
+ buffer = new byte[requestedSize];
+
+ // Only cache the buffer if it's not too big.
+ if (requestedSize <= MAX_CACHED_BUFFER_SIZE) {
+ setBuffer(buffer);
+ }
+ }
+ return buffer;
+ }
+
+ private static boolean needToReallocate(int requestedSize, int bufferLength) {
+ // First check against just the requested length to avoid the multiply.
+ return bufferLength < requestedSize
+ && bufferLength < requestedSize * BUFFER_REALLOCATION_THRESHOLD;
+ }
+
+ private static byte[] getBuffer() {
+ SoftReference<byte[]> sr = BUFFER.get();
+ return sr == null ? null : sr.get();
+ }
+
+ private static void setBuffer(byte[] value) {
+ BUFFER.set(new SoftReference<byte[]>(value));
+ }
+}
diff --git a/java/core/src/main/java/com/google/protobuf/ByteOutput.java b/java/core/src/main/java/com/google/protobuf/ByteOutput.java
new file mode 100644
index 00000000..ee588753
--- /dev/null
+++ b/java/core/src/main/java/com/google/protobuf/ByteOutput.java
@@ -0,0 +1,116 @@
+// 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.
+
+package com.google.protobuf;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+/**
+ * An output target for raw bytes. This interface provides semantics that support two types of
+ * writing:
+ *
+ * <p><b>Traditional write operations:</b>
+ * (as defined by {@link java.io.OutputStream}) where the target method is responsible for either
+ * copying the data or completing the write before returning from the method call.
+ *
+ * <p><b>Lazy write operations:</b> where the caller guarantees that it will never modify the
+ * provided buffer and it can therefore be considered immutable. The target method is free to
+ * maintain a reference to the buffer beyond the scope of the method call (e.g. until the write
+ * operation completes).
+ */
+@ExperimentalApi
+public abstract class ByteOutput {
+ /**
+ * Writes a single byte.
+ *
+ * @param value the byte to be written
+ * @throws IOException thrown if an error occurred while writing
+ */
+ public abstract void write(byte value) throws IOException;
+
+ /**
+ * Writes a sequence of bytes. The {@link ByteOutput} must copy {@code value} if it will
+ * not be processed prior to the return of this method call, since {@code value} may be
+ * reused/altered by the caller.
+ *
+ * <p>NOTE: This method <strong>MUST NOT</strong> modify the {@code value}. Doing so is a
+ * programming error and will lead to data corruption which will be difficult to debug.
+ *
+ * @param value the bytes to be written
+ * @param offset the offset of the start of the writable range
+ * @param length the number of bytes to write starting from {@code offset}
+ * @throws IOException thrown if an error occurred while writing
+ */
+ public abstract void write(byte[] value, int offset, int length) throws IOException;
+
+ /**
+ * Writes a sequence of bytes. The {@link ByteOutput} is free to retain a reference to the value
+ * beyond the scope of this method call (e.g. write later) since it is considered immutable and is
+ * guaranteed not to change by the caller.
+ *
+ * <p>NOTE: This method <strong>MUST NOT</strong> modify the {@code value}. Doing so is a
+ * programming error and will lead to data corruption which will be difficult to debug.
+ *
+ * @param value the bytes to be written
+ * @param offset the offset of the start of the writable range
+ * @param length the number of bytes to write starting from {@code offset}
+ * @throws IOException thrown if an error occurred while writing
+ */
+ public abstract void writeLazy(byte[] value, int offset, int length) throws IOException;
+
+ /**
+ * Writes a sequence of bytes. The {@link ByteOutput} must copy {@code value} if it will
+ * not be processed prior to the return of this method call, since {@code value} may be
+ * reused/altered by the caller.
+ *
+ * <p>NOTE: This method <strong>MUST NOT</strong> modify the {@code value}. Doing so is a
+ * programming error and will lead to data corruption which will be difficult to debug.
+ *
+ * @param value the bytes to be written. Upon returning from this call, the {@code position} of
+ * this buffer will be set to the {@code limit}
+ * @throws IOException thrown if an error occurred while writing
+ */
+ public abstract void write(ByteBuffer value) throws IOException;
+
+ /**
+ * Writes a sequence of bytes. The {@link ByteOutput} is free to retain a reference to the value
+ * beyond the scope of this method call (e.g. write later) since it is considered immutable and is
+ * guaranteed not to change by the caller.
+ *
+ * <p>NOTE: This method <strong>MUST NOT</strong> modify the {@code value}. Doing so is a
+ * programming error and will lead to data corruption which will be difficult to debug.
+ *
+ * @param value the bytes to be written. Upon returning from this call, the {@code position} of
+ * this buffer will be set to the {@code limit}
+ * @throws IOException thrown if an error occurred while writing
+ */
+ public abstract void writeLazy(ByteBuffer value) throws IOException;
+}
diff --git a/java/src/main/java/com/google/protobuf/ByteString.java b/java/core/src/main/java/com/google/protobuf/ByteString.java
index b092bc36..49653899 100644
--- a/java/src/main/java/com/google/protobuf/ByteString.java
+++ b/java/core/src/main/java/com/google/protobuf/ByteString.java
@@ -30,9 +30,12 @@
package com.google.protobuf;
+import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.InvalidObjectException;
+import java.io.ObjectInputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
@@ -40,7 +43,9 @@ import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
@@ -81,7 +86,62 @@ public abstract class ByteString implements Iterable<Byte>, Serializable {
/**
* Empty {@code ByteString}.
*/
- public static final ByteString EMPTY = new LiteralByteString(new byte[0]);
+ public static final ByteString EMPTY = new LiteralByteString(Internal.EMPTY_BYTE_ARRAY);
+
+ /**
+ * An interface to efficiently copy {@code byte[]}.
+ *
+ * <p>One of the noticeable costs of copying a byte[] into a new array using
+ * {@code System.arraycopy} is nullification of a new buffer before the copy. It has been shown
+ * the Hotspot VM is capable to intrisicfy {@code Arrays.copyOfRange} operation to avoid this
+ * expensive nullification and provide substantial performance gain. Unfortunately this does not
+ * hold on Android runtimes and could make the copy slightly slower due to additional code in
+ * the {@code Arrays.copyOfRange}. Thus we provide two different implementation for array copier
+ * for Hotspot and Android runtimes.
+ */
+ private interface ByteArrayCopier {
+ /**
+ * Copies the specified range of the specified array into a new array
+ */
+ byte[] copyFrom(byte[] bytes, int offset, int size);
+ }
+
+ /** Implementation of {@code ByteArrayCopier} which uses {@link System#arraycopy}. */
+ private static final class SystemByteArrayCopier implements ByteArrayCopier {
+ @Override
+ public byte[] copyFrom(byte[] bytes, int offset, int size) {
+ byte[] copy = new byte[size];
+ System.arraycopy(bytes, offset, copy, 0, size);
+ return copy;
+ }
+ }
+
+ /** Implementation of {@code ByteArrayCopier} which uses {@link Arrays#copyOfRange}. */
+ private static final class ArraysByteArrayCopier implements ByteArrayCopier {
+ @Override
+ public byte[] copyFrom(byte[] bytes, int offset, int size) {
+ return Arrays.copyOfRange(bytes, offset, offset + size);
+ }
+ }
+
+ private static final ByteArrayCopier byteArrayCopier;
+ static {
+ boolean isAndroid = true;
+ try {
+ Class.forName("android.content.Context");
+ } catch (ClassNotFoundException e) {
+ isAndroid = false;
+ }
+
+ byteArrayCopier = isAndroid ? new SystemByteArrayCopier() : new ArraysByteArrayCopier();
+ }
+
+ /**
+ * Cached hash value. Intentionally accessed via a data race, which
+ * is safe because of the Java Memory Model's "no out-of-thin-air values"
+ * guarantees for ints. A value of 0 implies that the hash has not been set.
+ */
+ private int hash = 0;
// This constructor is here to prevent subclassing outside of this package,
ByteString() {}
@@ -94,7 +154,7 @@ public abstract class ByteString implements Iterable<Byte>, Serializable {
*
* @param index index of byte
* @return the value
- * @throws ArrayIndexOutOfBoundsException {@code index < 0 or index >= size}
+ * @throws IndexOutOfBoundsException {@code index < 0 or index >= size}
*/
public abstract byte byteAt(int index);
@@ -105,7 +165,38 @@ public abstract class ByteString implements Iterable<Byte>, Serializable {
*
* @return the iterator
*/
- public abstract ByteIterator iterator();
+ @Override
+ public final ByteIterator iterator() {
+ return new ByteIterator() {
+ private int position = 0;
+ private final int limit = size();
+
+ @Override
+ public boolean hasNext() {
+ return position < limit;
+ }
+
+ @Override
+ public Byte next() {
+ // Boxing calls Byte.valueOf(byte), which does not instantiate.
+ return nextByte();
+ }
+
+ @Override
+ public byte nextByte() {
+ try {
+ return byteAt(position++);
+ } catch (IndexOutOfBoundsException e) {
+ throw new NoSuchElementException(e.getMessage());
+ }
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
/**
* This interface extends {@code Iterator<Byte>}, so that we can return an
@@ -134,7 +225,7 @@ public abstract class ByteString implements Iterable<Byte>, Serializable {
*
* @return true if this is zero bytes long
*/
- public boolean isEmpty() {
+ public final boolean isEmpty() {
return size() == 0;
}
@@ -150,7 +241,7 @@ public abstract class ByteString implements Iterable<Byte>, Serializable {
* @throws IndexOutOfBoundsException if {@code beginIndex < 0} or
* {@code beginIndex > size()}.
*/
- public ByteString substring(int beginIndex) {
+ public final ByteString substring(int beginIndex) {
return substring(beginIndex, size());
}
@@ -175,7 +266,7 @@ public abstract class ByteString implements Iterable<Byte>, Serializable {
* argument is a prefix of the byte sequence represented by
* this string; <code>false</code> otherwise.
*/
- public boolean startsWith(ByteString prefix) {
+ public final boolean startsWith(ByteString prefix) {
return size() >= prefix.size() &&
substring(0, prefix.size()).equals(prefix);
}
@@ -189,7 +280,7 @@ public abstract class ByteString implements Iterable<Byte>, Serializable {
* argument is a suffix of the byte sequence represented by
* this string; <code>false</code> otherwise.
*/
- public boolean endsWith(ByteString suffix) {
+ public final boolean endsWith(ByteString suffix) {
return size() >= suffix.size() &&
substring(size() - suffix.size()).equals(suffix);
}
@@ -206,9 +297,7 @@ public abstract class ByteString implements Iterable<Byte>, Serializable {
* @return new {@code ByteString}
*/
public static ByteString copyFrom(byte[] bytes, int offset, int size) {
- byte[] copy = new byte[size];
- System.arraycopy(bytes, offset, copy, 0, size);
- return new LiteralByteString(copy);
+ return new LiteralByteString(byteArrayCopier.copyFrom(bytes, offset, size));
}
/**
@@ -222,6 +311,24 @@ public abstract class ByteString implements Iterable<Byte>, Serializable {
}
/**
+ * Wraps the given bytes into a {@code ByteString}. Intended for internal only
+ * usage to force a classload of ByteString before LiteralByteString.
+ */
+ static ByteString wrap(byte[] bytes) {
+ // TODO(dweis): Return EMPTY when bytes are empty to reduce allocations?
+ return new LiteralByteString(bytes);
+ }
+
+ /**
+ * Wraps the given bytes into a {@code ByteString}. Intended for internal only
+ * usage to force a classload of ByteString before BoundedByteString and
+ * LiteralByteString.
+ */
+ static ByteString wrap(byte[] bytes, int offset, int length) {
+ return new BoundedByteString(bytes, offset, length);
+ }
+
+ /**
* Copies the next {@code size} bytes from a {@code java.nio.ByteBuffer} into
* a {@code ByteString}.
*
@@ -295,7 +402,7 @@ public abstract class ByteString implements Iterable<Byte>, Serializable {
* immutable tree of byte arrays ("chunks") of the stream data. The
* first chunk is small, with subsequent chunks each being double
* the size, up to 8K.
- *
+ *
* <p>Each byte read from the input stream will be copied twice to ensure
* that the resulting ByteString is truly immutable.
*
@@ -309,8 +416,7 @@ public abstract class ByteString implements Iterable<Byte>, Serializable {
*/
public static ByteString readFrom(InputStream streamToDrain)
throws IOException {
- return readFrom(
- streamToDrain, MIN_READ_FROM_CHUNK_SIZE, MAX_READ_FROM_CHUNK_SIZE);
+ return readFrom(streamToDrain, MIN_READ_FROM_CHUNK_SIZE, MAX_READ_FROM_CHUNK_SIZE);
}
/**
@@ -383,10 +489,10 @@ public abstract class ByteString implements Iterable<Byte>, Serializable {
if (bytesRead == 0) {
return null;
- } else {
- // Always make a copy since InputStream could steal a reference to buf.
- return ByteString.copyFrom(buf, 0, bytesRead);
}
+
+ // Always make a copy since InputStream could steal a reference to buf.
+ return ByteString.copyFrom(buf, 0, bytesRead);
}
// =================================================================
@@ -402,12 +508,10 @@ public abstract class ByteString implements Iterable<Byte>, Serializable {
* @param other string to concatenate
* @return a new {@code ByteString} instance
*/
- public ByteString concat(ByteString other) {
- int thisSize = size();
- int otherSize = other.size();
- if ((long) thisSize + otherSize >= Integer.MAX_VALUE) {
+ public final ByteString concat(ByteString other) {
+ if (Integer.MAX_VALUE - size() < other.size()) {
throw new IllegalArgumentException("ByteString would be too long: " +
- thisSize + "+" + otherSize);
+ size() + "+" + other.size());
}
return RopeByteString.concatenate(this, other);
@@ -426,29 +530,29 @@ public abstract class ByteString implements Iterable<Byte>, Serializable {
* @return new {@code ByteString}
*/
public static ByteString copyFrom(Iterable<ByteString> byteStrings) {
- Collection<ByteString> collection;
+ // Determine the size;
+ final int size;
if (!(byteStrings instanceof Collection)) {
- collection = new ArrayList<ByteString>();
- for (ByteString byteString : byteStrings) {
- collection.add(byteString);
+ int tempSize = 0;
+ for (Iterator<ByteString> iter = byteStrings.iterator(); iter.hasNext();
+ iter.next(), ++tempSize) {
}
+ size = tempSize;
} else {
- collection = (Collection<ByteString>) byteStrings;
+ size = ((Collection<ByteString>) byteStrings).size();
}
- ByteString result;
- if (collection.isEmpty()) {
- result = EMPTY;
- } else {
- result = balancedConcat(collection.iterator(), collection.size());
+
+ if (size == 0) {
+ return EMPTY;
}
- return result;
+
+ return balancedConcat(byteStrings.iterator(), size);
}
// Internal function used by copyFrom(Iterable<ByteString>).
// Create a balanced concatenation of the next "length" elements from the
// iterable.
- private static ByteString balancedConcat(Iterator<ByteString> iterator,
- int length) {
+ private static ByteString balancedConcat(Iterator<ByteString> iterator, int length) {
assert length >= 1;
ByteString result;
if (length == 1) {
@@ -486,25 +590,10 @@ public abstract class ByteString implements Iterable<Byte>, Serializable {
* @throws IndexOutOfBoundsException if an offset or size is negative or too
* large
*/
- public void copyTo(byte[] target, int sourceOffset, int targetOffset,
+ public final void copyTo(byte[] target, int sourceOffset, int targetOffset,
int numberToCopy) {
- if (sourceOffset < 0) {
- throw new IndexOutOfBoundsException("Source offset < 0: " + sourceOffset);
- }
- if (targetOffset < 0) {
- throw new IndexOutOfBoundsException("Target offset < 0: " + targetOffset);
- }
- if (numberToCopy < 0) {
- throw new IndexOutOfBoundsException("Length < 0: " + numberToCopy);
- }
- if (sourceOffset + numberToCopy > size()) {
- throw new IndexOutOfBoundsException(
- "Source end offset < 0: " + (sourceOffset + numberToCopy));
- }
- if (targetOffset + numberToCopy > target.length) {
- throw new IndexOutOfBoundsException(
- "Target end offset < 0: " + (targetOffset + numberToCopy));
- }
+ checkRange(sourceOffset, sourceOffset + numberToCopy, size());
+ checkRange(targetOffset, targetOffset + numberToCopy, target.length);
if (numberToCopy > 0) {
copyToInternal(target, sourceOffset, targetOffset, numberToCopy);
}
@@ -534,8 +623,8 @@ public abstract class ByteString implements Iterable<Byte>, Serializable {
*
* @return copied bytes
*/
- public byte[] toByteArray() {
- int size = size();
+ public final byte[] toByteArray() {
+ final int size = size();
if (size == 0) {
return Internal.EMPTY_BYTE_ARRAY;
}
@@ -545,8 +634,7 @@ public abstract class ByteString implements Iterable<Byte>, Serializable {
}
/**
- * Writes the complete contents of this byte string to
- * the specified output stream argument.
+ * Writes a copy of the contents of this byte string to the specified output stream argument.
*
* @param out the output stream to which to write the data.
* @throws IOException if an I/O error occurs.
@@ -560,33 +648,36 @@ public abstract class ByteString implements Iterable<Byte>, Serializable {
* @param sourceOffset offset within these bytes
* @param numberToWrite number of bytes to write
* @throws IOException if an I/O error occurs.
- * @throws IndexOutOfBoundsException if an offset or size is negative or too
- * large
+ * @throws IndexOutOfBoundsException if an offset or size is negative or too large
*/
- void writeTo(OutputStream out, int sourceOffset, int numberToWrite)
+ final void writeTo(OutputStream out, int sourceOffset, int numberToWrite)
throws IOException {
- if (sourceOffset < 0) {
- throw new IndexOutOfBoundsException("Source offset < 0: " + sourceOffset);
- }
- if (numberToWrite < 0) {
- throw new IndexOutOfBoundsException("Length < 0: " + numberToWrite);
- }
- if (sourceOffset + numberToWrite > size()) {
- throw new IndexOutOfBoundsException(
- "Source end offset exceeded: " + (sourceOffset + numberToWrite));
- }
+ checkRange(sourceOffset, sourceOffset + numberToWrite, size());
if (numberToWrite > 0) {
writeToInternal(out, sourceOffset, numberToWrite);
}
-
}
/**
* Internal version of {@link #writeTo(OutputStream,int,int)} that assumes
* all error checking has already been done.
*/
- abstract void writeToInternal(OutputStream out, int sourceOffset,
- int numberToWrite) throws IOException;
+ abstract void writeToInternal(OutputStream out, int sourceOffset, int numberToWrite)
+ throws IOException;
+
+ /**
+ * Writes this {@link ByteString} to the provided {@link ByteOutput}. Calling
+ * this method may result in multiple operations on the target {@link ByteOutput}.
+ *
+ * <p>This method may expose internal backing buffers of the {@link ByteString} to the {@link
+ * ByteOutput} in order to avoid additional copying overhead. It would be possible for a malicious
+ * {@link ByteOutput} to corrupt the {@link ByteString}. Use with caution!
+ *
+ * @param byteOutput the output target to receive the bytes
+ * @throws IOException if an I/O error occurs
+ * @see UnsafeByteOperations#unsafeWriteTo(ByteString, ByteOutput)
+ */
+ abstract void writeTo(ByteOutput byteOutput) throws IOException;
/**
* Constructs a read-only {@code java.nio.ByteBuffer} whose content
@@ -618,7 +709,7 @@ public abstract class ByteString implements Iterable<Byte>, Serializable {
* @return new string
* @throws UnsupportedEncodingException if charset isn't recognized
*/
- public String toString(String charsetName)
+ public final String toString(String charsetName)
throws UnsupportedEncodingException {
try {
return toString(Charset.forName(charsetName));
@@ -636,7 +727,7 @@ public abstract class ByteString implements Iterable<Byte>, Serializable {
* @param charset encode using this charset
* @return new string
*/
- public String toString(Charset charset) {
+ public final String toString(Charset charset) {
return size() == 0 ? "" : toStringInternal(charset);
}
@@ -657,7 +748,7 @@ public abstract class ByteString implements Iterable<Byte>, Serializable {
*
* @return new string using UTF-8 encoding
*/
- public String toStringUtf8() {
+ public final String toStringUtf8() {
return toString(Internal.UTF_8);
}
@@ -716,13 +807,51 @@ public abstract class ByteString implements Iterable<Byte>, Serializable {
public abstract boolean equals(Object o);
/**
- * Return a non-zero hashCode depending only on the sequence of bytes
- * in this ByteString.
+ * Base class for leaf {@link ByteString}s (i.e. non-ropes).
+ */
+ abstract static class LeafByteString extends ByteString {
+ @Override
+ protected final int getTreeDepth() {
+ return 0;
+ }
+
+ @Override
+ protected final boolean isBalanced() {
+ return true;
+ }
+
+ /**
+ * Check equality of the substring of given length of this object starting at
+ * zero with another {@code ByteString} substring starting at offset.
+ *
+ * @param other what to compare a substring in
+ * @param offset offset into other
+ * @param length number of bytes to compare
+ * @return true for equality of substrings, else false.
+ */
+ abstract boolean equalsRange(ByteString other, int offset, int length);
+ }
+
+ /**
+ * Compute the hashCode using the traditional algorithm from {@link
+ * ByteString}.
*
- * @return hashCode value for this object
+ * @return hashCode value
*/
@Override
- public abstract int hashCode();
+ public final int hashCode() {
+ int h = hash;
+
+ if (h == 0) {
+ int size = size();
+ h = partialHash(size, 0, size);
+ if (h == 0) {
+ h = 1;
+ }
+ hash = h;
+ }
+ return h;
+ }
// =================================================================
// Input stream
@@ -1034,7 +1163,9 @@ public abstract class ByteString implements Iterable<Byte>, Serializable {
*
* @return value of cached hash code or 0 if not computed yet
*/
- protected abstract int peekCachedHashCode();
+ protected final int peekCachedHashCode() {
+ return hash;
+ }
/**
* Compute the hash across the value bytes starting with the given hash, and
@@ -1049,9 +1180,365 @@ public abstract class ByteString implements Iterable<Byte>, Serializable {
*/
protected abstract int partialHash(int h, int offset, int length);
+ /**
+ * Checks that the given index falls within the specified array size.
+ *
+ * @param index the index position to be tested
+ * @param size the length of the array
+ * @throws IndexOutOfBoundsException if the index does not fall within the array.
+ */
+ static void checkIndex(int index, int size) {
+ if ((index | (size - (index + 1))) < 0) {
+ if (index < 0) {
+ throw new ArrayIndexOutOfBoundsException("Index < 0: " + index);
+ }
+ throw new ArrayIndexOutOfBoundsException("Index > length: " + index + ", " + size);
+ }
+ }
+
+ /**
+ * Checks that the given range falls within the bounds of an array
+ *
+ * @param startIndex the start index of the range (inclusive)
+ * @param endIndex the end index of the range (exclusive)
+ * @param size the size of the array.
+ * @return the length of the range.
+ * @throws IndexOutOfBoundsException some or all of the range falls outside of the array.
+ */
+ static int checkRange(int startIndex, int endIndex, int size) {
+ final int length = endIndex - startIndex;
+ if ((startIndex | endIndex | length | (size - endIndex)) < 0) {
+ if (startIndex < 0) {
+ throw new IndexOutOfBoundsException("Beginning index: " + startIndex + " < 0");
+ }
+ if (endIndex < startIndex) {
+ throw new IndexOutOfBoundsException(
+ "Beginning index larger than ending index: " + startIndex + ", " + endIndex);
+ }
+ // endIndex >= size
+ throw new IndexOutOfBoundsException("End index: " + endIndex + " >= " + size);
+ }
+ return length;
+ }
+
@Override
- public String toString() {
+ public final String toString() {
return String.format("<ByteString@%s size=%d>",
Integer.toHexString(System.identityHashCode(this)), size());
}
+
+ /**
+ * This class implements a {@link com.google.protobuf.ByteString} backed by a
+ * single array of bytes, contiguous in memory. It supports substring by
+ * pointing to only a sub-range of the underlying byte array, meaning that a
+ * substring will reference the full byte-array of the string it's made from,
+ * exactly as with {@link String}.
+ *
+ * @author carlanton@google.com (Carl Haverl)
+ */
+ // Keep this class private to avoid deadlocks in classloading across threads as ByteString's
+ // static initializer loads LiteralByteString and another thread loads LiteralByteString.
+ private static class LiteralByteString extends ByteString.LeafByteString {
+ private static final long serialVersionUID = 1L;
+
+ protected final byte[] bytes;
+
+ /**
+ * Creates a {@code LiteralByteString} backed by the given array, without
+ * copying.
+ *
+ * @param bytes array to wrap
+ */
+ LiteralByteString(byte[] bytes) {
+ this.bytes = bytes;
+ }
+
+ @Override
+ public byte byteAt(int index) {
+ // Unlike most methods in this class, this one is a direct implementation
+ // ignoring the potential offset because we need to do range-checking in the
+ // substring case anyway.
+ return bytes[index];
+ }
+
+ @Override
+ public int size() {
+ return bytes.length;
+ }
+
+ // =================================================================
+ // ByteString -> substring
+
+ @Override
+ public final ByteString substring(int beginIndex, int endIndex) {
+ final int length = checkRange(beginIndex, endIndex, size());
+
+ if (length == 0) {
+ return ByteString.EMPTY;
+ }
+
+ return new BoundedByteString(bytes, getOffsetIntoBytes() + beginIndex, length);
+ }
+
+ // =================================================================
+ // ByteString -> byte[]
+
+ @Override
+ protected void copyToInternal(
+ byte[] target, int sourceOffset, int targetOffset, int numberToCopy) {
+ // Optimized form, not for subclasses, since we don't call
+ // getOffsetIntoBytes() or check the 'numberToCopy' parameter.
+ // TODO(nathanmittler): Is not calling getOffsetIntoBytes really saving that much?
+ System.arraycopy(bytes, sourceOffset, target, targetOffset, numberToCopy);
+ }
+
+ @Override
+ public final void copyTo(ByteBuffer target) {
+ target.put(bytes, getOffsetIntoBytes(), size()); // Copies bytes
+ }
+
+ @Override
+ public final ByteBuffer asReadOnlyByteBuffer() {
+ return ByteBuffer.wrap(bytes, getOffsetIntoBytes(), size()).asReadOnlyBuffer();
+ }
+
+ @Override
+ public final List<ByteBuffer> asReadOnlyByteBufferList() {
+ return Collections.singletonList(asReadOnlyByteBuffer());
+ }
+
+ @Override
+ public final void writeTo(OutputStream outputStream) throws IOException {
+ outputStream.write(toByteArray());
+ }
+
+ @Override
+ final void writeToInternal(OutputStream outputStream, int sourceOffset, int numberToWrite)
+ throws IOException {
+ outputStream.write(bytes, getOffsetIntoBytes() + sourceOffset, numberToWrite);
+ }
+
+ @Override
+ final void writeTo(ByteOutput output) throws IOException {
+ output.writeLazy(bytes, getOffsetIntoBytes(), size());
+ }
+
+ @Override
+ protected final String toStringInternal(Charset charset) {
+ return new String(bytes, getOffsetIntoBytes(), size(), charset);
+ }
+
+ // =================================================================
+ // UTF-8 decoding
+
+ @Override
+ public final boolean isValidUtf8() {
+ int offset = getOffsetIntoBytes();
+ return Utf8.isValidUtf8(bytes, offset, offset + size());
+ }
+
+ @Override
+ protected final int partialIsValidUtf8(int state, int offset, int length) {
+ int index = getOffsetIntoBytes() + offset;
+ return Utf8.partialIsValidUtf8(state, bytes, index, index + length);
+ }
+
+ // =================================================================
+ // equals() and hashCode()
+
+ @Override
+ public final boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+ if (!(other instanceof ByteString)) {
+ return false;
+ }
+
+ if (size() != ((ByteString) other).size()) {
+ return false;
+ }
+ if (size() == 0) {
+ return true;
+ }
+
+ if (other instanceof LiteralByteString) {
+ LiteralByteString otherAsLiteral = (LiteralByteString) other;
+ // If we know the hash codes and they are not equal, we know the byte
+ // strings are not equal.
+ int thisHash = peekCachedHashCode();
+ int thatHash = otherAsLiteral.peekCachedHashCode();
+ if (thisHash != 0 && thatHash != 0 && thisHash != thatHash) {
+ return false;
+ }
+
+ return equalsRange((LiteralByteString) other, 0, size());
+ } else {
+ // RopeByteString and NioByteString.
+ return other.equals(this);
+ }
+ }
+
+ /**
+ * Check equality of the substring of given length of this object starting at
+ * zero with another {@code LiteralByteString} substring starting at offset.
+ *
+ * @param other what to compare a substring in
+ * @param offset offset into other
+ * @param length number of bytes to compare
+ * @return true for equality of substrings, else false.
+ */
+ @Override
+ final boolean equalsRange(ByteString other, int offset, int length) {
+ if (length > other.size()) {
+ throw new IllegalArgumentException("Length too large: " + length + size());
+ }
+ if (offset + length > other.size()) {
+ throw new IllegalArgumentException(
+ "Ran off end of other: " + offset + ", " + length + ", " + other.size());
+ }
+
+ if (other instanceof LiteralByteString) {
+ LiteralByteString lbsOther = (LiteralByteString) other;
+ byte[] thisBytes = bytes;
+ byte[] otherBytes = lbsOther.bytes;
+ int thisLimit = getOffsetIntoBytes() + length;
+ for (
+ int thisIndex = getOffsetIntoBytes(),
+ otherIndex = lbsOther.getOffsetIntoBytes() + offset;
+ (thisIndex < thisLimit); ++thisIndex, ++otherIndex) {
+ if (thisBytes[thisIndex] != otherBytes[otherIndex]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ return other.substring(offset, offset + length).equals(substring(0, length));
+ }
+
+ @Override
+ protected final int partialHash(int h, int offset, int length) {
+ return Internal.partialHash(h, bytes, getOffsetIntoBytes() + offset, length);
+ }
+
+ // =================================================================
+ // Input stream
+
+ @Override
+ public final InputStream newInput() {
+ return new ByteArrayInputStream(bytes, getOffsetIntoBytes(), size()); // No copy
+ }
+
+ @Override
+ public final CodedInputStream newCodedInput() {
+ // We trust CodedInputStream not to modify the bytes, or to give anyone
+ // else access to them.
+ return CodedInputStream.newInstance(
+ bytes, getOffsetIntoBytes(), size(), true /* bufferIsImmutable */);
+ }
+
+ // =================================================================
+ // Internal methods
+
+ /**
+ * Offset into {@code bytes[]} to use, non-zero for substrings.
+ *
+ * @return always 0 for this class
+ */
+ protected int getOffsetIntoBytes() {
+ return 0;
+ }
+ }
+
+ /**
+ * This class is used to represent the substring of a {@link ByteString} over a
+ * single byte array. In terms of the public API of {@link ByteString}, you end
+ * up here by calling {@link ByteString#copyFrom(byte[])} followed by {@link
+ * ByteString#substring(int, int)}.
+ *
+ * <p>This class contains most of the overhead involved in creating a substring
+ * from a {@link LiteralByteString}. The overhead involves some range-checking
+ * and two extra fields.
+ *
+ * @author carlanton@google.com (Carl Haverl)
+ */
+ // Keep this class private to avoid deadlocks in classloading across threads as ByteString's
+ // static initializer loads LiteralByteString and another thread loads BoundedByteString.
+ private static final class BoundedByteString extends LiteralByteString {
+
+ private final int bytesOffset;
+ private final int bytesLength;
+
+ /**
+ * Creates a {@code BoundedByteString} backed by the sub-range of given array,
+ * without copying.
+ *
+ * @param bytes array to wrap
+ * @param offset index to first byte to use in bytes
+ * @param length number of bytes to use from bytes
+ * @throws IllegalArgumentException if {@code offset < 0}, {@code length < 0},
+ * or if {@code offset + length >
+ * bytes.length}.
+ */
+ BoundedByteString(byte[] bytes, int offset, int length) {
+ super(bytes);
+ checkRange(offset, offset + length, bytes.length);
+
+ this.bytesOffset = offset;
+ this.bytesLength = length;
+ }
+
+ /**
+ * Gets the byte at the given index.
+ * Throws {@link ArrayIndexOutOfBoundsException}
+ * for backwards-compatibility reasons although it would more properly be
+ * {@link IndexOutOfBoundsException}.
+ *
+ * @param index index of byte
+ * @return the value
+ * @throws ArrayIndexOutOfBoundsException {@code index} is < 0 or >= size
+ */
+ @Override
+ public byte byteAt(int index) {
+ // We must check the index ourselves as we cannot rely on Java array index
+ // checking for substrings.
+ checkIndex(index, size());
+ return bytes[bytesOffset + index];
+ }
+
+ @Override
+ public int size() {
+ return bytesLength;
+ }
+
+ @Override
+ protected int getOffsetIntoBytes() {
+ return bytesOffset;
+ }
+
+ // =================================================================
+ // ByteString -> byte[]
+
+ @Override
+ protected void copyToInternal(byte[] target, int sourceOffset, int targetOffset,
+ int numberToCopy) {
+ System.arraycopy(bytes, getOffsetIntoBytes() + sourceOffset, target,
+ targetOffset, numberToCopy);
+ }
+
+ // =================================================================
+ // Serializable
+
+ private static final long serialVersionUID = 1L;
+
+ Object writeReplace() {
+ return ByteString.wrap(toByteArray());
+ }
+
+ private void readObject(@SuppressWarnings("unused") ObjectInputStream in) throws IOException {
+ throw new InvalidObjectException(
+ "BoundedByteStream instances are not to be serialized directly");
+ }
+ }
}
diff --git a/java/src/main/java/com/google/protobuf/CodedInputStream.java b/java/core/src/main/java/com/google/protobuf/CodedInputStream.java
index d201f7c5..e8860651 100644
--- a/java/src/main/java/com/google/protobuf/CodedInputStream.java
+++ b/java/core/src/main/java/com/google/protobuf/CodedInputStream.java
@@ -55,7 +55,14 @@ public final class CodedInputStream {
* Create a new CodedInputStream wrapping the given InputStream.
*/
public static CodedInputStream newInstance(final InputStream input) {
- return new CodedInputStream(input);
+ return new CodedInputStream(input, BUFFER_SIZE);
+ }
+
+ /**
+ * Create a new CodedInputStream wrapping the given InputStream.
+ */
+ static CodedInputStream newInstance(final InputStream input, int bufferSize) {
+ return new CodedInputStream(input, bufferSize);
}
/**
@@ -70,7 +77,15 @@ public final class CodedInputStream {
*/
public static CodedInputStream newInstance(final byte[] buf, final int off,
final int len) {
- CodedInputStream result = new CodedInputStream(buf, off, len);
+ return newInstance(buf, off, len, false /* bufferIsImmutable */);
+ }
+
+ /**
+ * Create a new CodedInputStream wrapping the given byte array slice.
+ */
+ static CodedInputStream newInstance(
+ final byte[] buf, final int off, final int len, final boolean bufferIsImmutable) {
+ CodedInputStream result = new CodedInputStream(buf, off, len, bufferIsImmutable);
try {
// Some uses of CodedInputStream can be more efficient if they know
// exactly how many bytes are available. By pushing the end point of the
@@ -113,31 +128,6 @@ public final class CodedInputStream {
}
}
- /**
- * Create a new CodedInputStream wrapping a LiteralByteString.
- */
- static CodedInputStream newInstance(LiteralByteString byteString) {
- CodedInputStream result = new CodedInputStream(byteString);
- try {
- // Some uses of CodedInputStream can be more efficient if they know
- // exactly how many bytes are available. By pushing the end point of the
- // buffer as a limit, we allow them to get this information via
- // getBytesUntilLimit(). Pushing a limit that we know is at the end of
- // the stream can never hurt, since we can never past that point anyway.
- result.pushLimit(byteString.size());
- } catch (InvalidProtocolBufferException ex) {
- // The only reason pushLimit() might throw an exception here is if len
- // is negative. Normally pushLimit()'s parameter comes directly off the
- // wire, so it's important to catch exceptions in case of corrupt or
- // malicious data. However, in this case, we expect that len is not a
- // user-supplied value, so we can assume that it being negative indicates
- // a programming error. Therefore, throwing an unchecked exception is
- // appropriate.
- throw new IllegalArgumentException(ex);
- }
- return result;
- }
-
// -----------------------------------------------------------------
/**
@@ -378,6 +368,11 @@ public final class CodedInputStream {
return result;
} else if (size == 0) {
return "";
+ } else if (size <= bufferSize) {
+ refillBuffer(size);
+ String result = new String(buffer, bufferPos, size, Internal.UTF_8);
+ bufferPos += size;
+ return result;
} else {
// Slow path: Build a byte array first then copy it.
return new String(readRawBytesSlowPath(size), Internal.UTF_8);
@@ -392,14 +387,21 @@ public final class CodedInputStream {
public String readStringRequireUtf8() throws IOException {
final int size = readRawVarint32();
final byte[] bytes;
- int pos = bufferPos;
- if (size <= (bufferSize - pos) && size > 0) {
+ final int oldPos = bufferPos;
+ final int pos;
+ if (size <= (bufferSize - oldPos) && size > 0) {
// Fast path: We already have the bytes in a contiguous buffer, so
// just copy directly from it.
bytes = buffer;
- bufferPos = pos + size;
+ bufferPos = oldPos + size;
+ pos = oldPos;
} else if (size == 0) {
return "";
+ } else if (size <= bufferSize) {
+ refillBuffer(size);
+ bytes = buffer;
+ pos = 0;
+ bufferPos = pos + size;
} else {
// Slow path: Build a byte array first then copy it.
bytes = readRawBytesSlowPath(size);
@@ -506,7 +508,7 @@ public final class CodedInputStream {
// Fast path: We already have the bytes in a contiguous buffer, so
// just copy directly from it.
final ByteString result = bufferIsImmutable && enableAliasing
- ? new BoundedByteString(buffer, bufferPos, size)
+ ? ByteString.wrap(buffer, bufferPos, size)
: ByteString.copyFrom(buffer, bufferPos, size);
bufferPos += size;
return result;
@@ -514,7 +516,7 @@ public final class CodedInputStream {
return ByteString.EMPTY;
} else {
// Slow path: Build a byte array first then copy it.
- return new LiteralByteString(readRawBytesSlowPath(size));
+ return ByteString.wrap(readRawBytesSlowPath(size));
}
}
@@ -886,17 +888,18 @@ public final class CodedInputStream {
private static final int DEFAULT_SIZE_LIMIT = 64 << 20; // 64MB
private static final int BUFFER_SIZE = 4096;
- private CodedInputStream(final byte[] buffer, final int off, final int len) {
+ private CodedInputStream(
+ final byte[] buffer, final int off, final int len, boolean bufferIsImmutable) {
this.buffer = buffer;
bufferSize = off + len;
bufferPos = off;
totalBytesRetired = -off;
input = null;
- bufferIsImmutable = false;
+ this.bufferIsImmutable = bufferIsImmutable;
}
- private CodedInputStream(final InputStream input) {
- buffer = new byte[BUFFER_SIZE];
+ private CodedInputStream(final InputStream input, int bufferSize) {
+ buffer = new byte[bufferSize];
bufferSize = 0;
bufferPos = 0;
totalBytesRetired = 0;
@@ -904,15 +907,6 @@ public final class CodedInputStream {
bufferIsImmutable = false;
}
- private CodedInputStream(final LiteralByteString byteString) {
- buffer = byteString.bytes;
- bufferPos = byteString.getOffsetIntoBytes();
- bufferSize = bufferPos + byteString.size();
- totalBytesRetired = -bufferPos;
- input = null;
- bufferIsImmutable = true;
- }
-
public void enableAliasing(boolean enabled) {
this.enableAliasing = enabled;
}
@@ -1056,20 +1050,6 @@ public final class CodedInputStream {
private RefillCallback refillCallback = null;
/**
- * Ensures that at least {@code n} bytes are available in the buffer, reading
- * more bytes from the input if necessary to make it so. Caller must ensure
- * that the requested space is less than BUFFER_SIZE.
- *
- * @throws InvalidProtocolBufferException The end of the stream or the current
- * limit was reached.
- */
- private void ensureAvailable(int n) throws IOException {
- if (bufferSize - bufferPos < n) {
- refillBuffer(n);
- }
- }
-
- /**
* Reads more bytes from the input, making at least {@code n} bytes available
* in the buffer. Caller must ensure that the requested space is not yet
* available, and that the requested space is less than BUFFER_SIZE.
@@ -1180,86 +1160,97 @@ public final class CodedInputStream {
}
}
- if (totalBytesRetired + bufferPos + size > currentLimit) {
+ // Verify that the message size so far has not exceeded sizeLimit.
+ int currentMessageSize = totalBytesRetired + bufferPos + size;
+ if (currentMessageSize > sizeLimit) {
+ throw InvalidProtocolBufferException.sizeLimitExceeded();
+ }
+
+ // Verify that the message size so far has not exceeded currentLimit.
+ if (currentMessageSize > currentLimit) {
// Read to the end of the stream anyway.
skipRawBytes(currentLimit - totalBytesRetired - bufferPos);
- // Then fail.
throw InvalidProtocolBufferException.truncatedMessage();
}
- if (size < BUFFER_SIZE) {
- // Reading more bytes than are in the buffer, but not an excessive number
- // of bytes. We can safely allocate the resulting array ahead of time.
+ // We need the input stream to proceed.
+ if (input == null) {
+ throw InvalidProtocolBufferException.truncatedMessage();
+ }
- // First copy what we have.
+ final int originalBufferPos = bufferPos;
+ final int bufferedBytes = bufferSize - bufferPos;
+
+ // Mark the current buffer consumed.
+ totalBytesRetired += bufferSize;
+ bufferPos = 0;
+ bufferSize = 0;
+
+ // Determine the number of bytes we need to read from the input stream.
+ int sizeLeft = size - bufferedBytes;
+ // TODO(nathanmittler): Consider using a value larger than BUFFER_SIZE.
+ if (sizeLeft < BUFFER_SIZE || sizeLeft <= input.available()) {
+ // Either the bytes we need are known to be available, or the required buffer is
+ // within an allowed threshold - go ahead and allocate the buffer now.
final byte[] bytes = new byte[size];
- int pos = bufferSize - bufferPos;
- System.arraycopy(buffer, bufferPos, bytes, 0, pos);
- bufferPos = bufferSize;
- // We want to refill the buffer and then copy from the buffer into our
- // byte array rather than reading directly into our byte array because
- // the input may be unbuffered.
- ensureAvailable(size - pos);
- System.arraycopy(buffer, 0, bytes, pos, size - pos);
- bufferPos = size - pos;
+ // Copy all of the buffered bytes to the result buffer.
+ System.arraycopy(buffer, originalBufferPos, bytes, 0, bufferedBytes);
- return bytes;
- } else {
- // The size is very large. For security reasons, we can't allocate the
- // entire byte array yet. The size comes directly from the input, so a
- // maliciously-crafted message could provide a bogus very large size in
- // order to trick the app into allocating a lot of memory. We avoid this
- // by allocating and reading only a small chunk at a time, so that the
- // malicious message must actually *be* extremely large to cause
- // problems. Meanwhile, we limit the allowed size of a message elsewhere.
-
- // Remember the buffer markers since we'll have to copy the bytes out of
- // it later.
- final int originalBufferPos = bufferPos;
- final int originalBufferSize = bufferSize;
-
- // Mark the current buffer consumed.
- totalBytesRetired += bufferSize;
- bufferPos = 0;
- bufferSize = 0;
-
- // Read all the rest of the bytes we need.
- int sizeLeft = size - (originalBufferSize - originalBufferPos);
- final List<byte[]> chunks = new ArrayList<byte[]>();
-
- while (sizeLeft > 0) {
- final byte[] chunk = new byte[Math.min(sizeLeft, BUFFER_SIZE)];
- int pos = 0;
- while (pos < chunk.length) {
- final int n = (input == null) ? -1 :
- input.read(chunk, pos, chunk.length - pos);
- if (n == -1) {
- throw InvalidProtocolBufferException.truncatedMessage();
- }
- totalBytesRetired += n;
- pos += n;
+ // Fill the remaining bytes from the input stream.
+ int pos = bufferedBytes;
+ while (pos < bytes.length) {
+ int n = input.read(bytes, pos, size - pos);
+ if (n == -1) {
+ throw InvalidProtocolBufferException.truncatedMessage();
}
- sizeLeft -= chunk.length;
- chunks.add(chunk);
+ totalBytesRetired += n;
+ pos += n;
}
- // OK, got everything. Now concatenate it all into one buffer.
- final byte[] bytes = new byte[size];
-
- // Start by copying the leftover bytes from this.buffer.
- int pos = originalBufferSize - originalBufferPos;
- System.arraycopy(buffer, originalBufferPos, bytes, 0, pos);
+ return bytes;
+ }
- // And now all the chunks.
- for (final byte[] chunk : chunks) {
- System.arraycopy(chunk, 0, bytes, pos, chunk.length);
- pos += chunk.length;
+ // The size is very large. For security reasons, we can't allocate the
+ // entire byte array yet. The size comes directly from the input, so a
+ // maliciously-crafted message could provide a bogus very large size in
+ // order to trick the app into allocating a lot of memory. We avoid this
+ // by allocating and reading only a small chunk at a time, so that the
+ // malicious message must actually *be* extremely large to cause
+ // problems. Meanwhile, we limit the allowed size of a message elsewhere.
+ final List<byte[]> chunks = new ArrayList<byte[]>();
+
+ while (sizeLeft > 0) {
+ // TODO(nathanmittler): Consider using a value larger than BUFFER_SIZE.
+ final byte[] chunk = new byte[Math.min(sizeLeft, BUFFER_SIZE)];
+ int pos = 0;
+ while (pos < chunk.length) {
+ final int n = input.read(chunk, pos, chunk.length - pos);
+ if (n == -1) {
+ throw InvalidProtocolBufferException.truncatedMessage();
+ }
+ totalBytesRetired += n;
+ pos += n;
}
+ sizeLeft -= chunk.length;
+ chunks.add(chunk);
+ }
- // Done.
- return bytes;
+ // OK, got everything. Now concatenate it all into one buffer.
+ final byte[] bytes = new byte[size];
+
+ // Start by copying the leftover bytes from this.buffer.
+ System.arraycopy(buffer, originalBufferPos, bytes, 0, bufferedBytes);
+
+ // And now all the chunks.
+ int pos = bufferedBytes;
+ for (final byte[] chunk : chunks) {
+ System.arraycopy(chunk, 0, bytes, pos, chunk.length);
+ pos += chunk.length;
}
+
+ // Done.
+ return bytes;
}
/**
diff --git a/java/core/src/main/java/com/google/protobuf/CodedOutputStream.java b/java/core/src/main/java/com/google/protobuf/CodedOutputStream.java
new file mode 100644
index 00000000..e5515285
--- /dev/null
+++ b/java/core/src/main/java/com/google/protobuf/CodedOutputStream.java
@@ -0,0 +1,2635 @@
+// 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.
+
+package com.google.protobuf;
+
+import static java.lang.Math.max;
+
+import com.google.protobuf.Utf8.UnpairedSurrogateException;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.BufferOverflowException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Encodes and writes protocol message fields.
+ *
+ * <p>This class contains two kinds of methods: methods that write specific
+ * protocol message constructs and field types (e.g. {@link #writeTag} and
+ * {@link #writeInt32}) and methods that write low-level values (e.g.
+ * {@link #writeRawVarint32} and {@link #writeRawBytes}). If you are
+ * writing encoded protocol messages, you should use the former methods, but if
+ * you are writing some other format of your own design, use the latter.
+ *
+ * <p>This class is totally unsynchronized.
+ */
+public abstract class CodedOutputStream extends ByteOutput {
+ private static final Logger logger = Logger.getLogger(CodedOutputStream.class.getName());
+ private static final boolean HAS_UNSAFE_ARRAY_OPERATIONS = UnsafeUtil.hasUnsafeArrayOperations();
+ private static final long ARRAY_BASE_OFFSET = UnsafeUtil.getArrayBaseOffset();
+
+ private static final int FIXED_32_SIZE = 4;
+ private static final int FIXED_64_SIZE = 8;
+ private static final int MAX_VARINT_SIZE = 10;
+
+ /**
+ * @deprecated Use {@link #computeFixed32SizeNoTag(int)} instead.
+ */
+ @Deprecated
+ public static final int LITTLE_ENDIAN_32_SIZE = FIXED_32_SIZE;
+
+ /**
+ * The buffer size used in {@link #newInstance(OutputStream)}.
+ */
+ public static final int DEFAULT_BUFFER_SIZE = 4096;
+
+ /**
+ * Returns the buffer size to efficiently write dataLength bytes to this
+ * CodedOutputStream. Used by AbstractMessageLite.
+ *
+ * @return the buffer size to efficiently write dataLength bytes to this
+ * CodedOutputStream.
+ */
+ static int computePreferredBufferSize(int dataLength) {
+ if (dataLength > DEFAULT_BUFFER_SIZE) {
+ return DEFAULT_BUFFER_SIZE;
+ }
+ return dataLength;
+ }
+
+ /**
+ * Create a new {@code CodedOutputStream} wrapping the given {@code OutputStream}.
+ *
+ * <p> NOTE: The provided {@link OutputStream} <strong>MUST NOT</strong> retain access or
+ * modify the provided byte arrays. Doing so may result in corrupted data, which would be
+ * difficult to debug.
+ */
+ public static CodedOutputStream newInstance(final OutputStream output) {
+ return newInstance(output, DEFAULT_BUFFER_SIZE);
+ }
+
+ /**
+ * Create a new {@code CodedOutputStream} wrapping the given {@code OutputStream} with a given
+ * buffer size.
+ *
+ * <p> NOTE: The provided {@link OutputStream} <strong>MUST NOT</strong> retain access or
+ * modify the provided byte arrays. Doing so may result in corrupted data, which would be
+ * difficult to debug.
+ */
+ public static CodedOutputStream newInstance(final OutputStream output, final int bufferSize) {
+ return new OutputStreamEncoder(output, bufferSize);
+ }
+
+ /**
+ * Create a new {@code CodedOutputStream} that writes directly to the given
+ * byte array. If more bytes are written than fit in the array,
+ * {@link OutOfSpaceException} will be thrown. Writing directly to a flat
+ * array is faster than writing to an {@code OutputStream}. See also
+ * {@link ByteString#newCodedBuilder}.
+ */
+ public static CodedOutputStream newInstance(final byte[] flatArray) {
+ return newInstance(flatArray, 0, flatArray.length);
+ }
+
+ /**
+ * Create a new {@code CodedOutputStream} that writes directly to the given
+ * byte array slice. If more bytes are written than fit in the slice,
+ * {@link OutOfSpaceException} will be thrown. Writing directly to a flat
+ * array is faster than writing to an {@code OutputStream}. See also
+ * {@link ByteString#newCodedBuilder}.
+ */
+ public static CodedOutputStream newInstance(
+ final byte[] flatArray, final int offset, final int length) {
+ return new ArrayEncoder(flatArray, offset, length);
+ }
+
+ /**
+ * Create a new {@code CodedOutputStream} that writes to the given {@link ByteBuffer}.
+ */
+ public static CodedOutputStream newInstance(ByteBuffer byteBuffer) {
+ if (byteBuffer.hasArray()) {
+ return new NioHeapEncoder(byteBuffer);
+ }
+ return new NioEncoder(byteBuffer);
+ }
+
+ /**
+ * Configures serialization to be deterministic.
+ *
+ * <p>The deterministic serialization guarantees that for a given binary, equal (defined by the
+ * {@code equals()} methods in protos) messages will always be serialized to the same bytes. This
+ * implies:
+ *
+ * <ul>
+ * <li>repeated serialization of a message will return the same bytes
+ * <li>different processes of the same binary (which may be executing on different machines) will
+ * serialize equal messages to the same bytes.
+ * </ul>
+ *
+ * <p>Note the deterministic serialization is NOT canonical across languages; it is also unstable
+ * across different builds with schema changes due to unknown fields. Users who need canonical
+ * serialization, e.g. persistent storage in a canonical form, fingerprinting, etc, should define
+ * their own canonicalization specification and implement the serializer using reflection APIs
+ * rather than relying on this API.
+ *
+ * <p> Once set, the serializer will: (Note this is an implementation detail and may subject to
+ * change in the future)
+ *
+ * <ul>
+ * <li> sort map entries by keys in lexicographical order or numerical order. Note: For string
+ * keys, the order is based on comparing the Unicode value of each character in the strings.
+ * The order may be different from the deterministic serialization in other languages where
+ * maps are sorted on the lexicographical order of the UTF8 encoded keys.
+ * </ul>
+ */
+ void useDeterministicSerialization() {
+ serializationDeterministic = true;
+ }
+
+ boolean isSerializationDeterministic() {
+ return serializationDeterministic;
+ }
+ private boolean serializationDeterministic;
+
+ /**
+ * Create a new {@code CodedOutputStream} that writes to the given {@link ByteBuffer}.
+ *
+ * @deprecated the size parameter is no longer used since use of an internal buffer is useless
+ * (and wasteful) when writing to a {@link ByteBuffer}. Use {@link #newInstance(ByteBuffer)}
+ * instead.
+ */
+ @Deprecated
+ public static CodedOutputStream newInstance(ByteBuffer byteBuffer,
+ @SuppressWarnings("unused") int unused) {
+ return newInstance(byteBuffer);
+ }
+
+ /**
+ * Create a new {@code CodedOutputStream} that writes to the provided {@link ByteOutput}.
+ *
+ * <p> NOTE: The {@link ByteOutput} <strong>MUST NOT</strong> modify the provided buffers. Doing
+ * so may result in corrupted data, which would be difficult to debug.
+ *
+ * @param byteOutput the output target for encoded bytes.
+ * @param bufferSize the size of the internal scratch buffer to be used for string encoding.
+ * Setting this to {@code 0} will disable buffering, requiring an allocation for each encoded
+ * string.
+ */
+ static CodedOutputStream newInstance(ByteOutput byteOutput, int bufferSize) {
+ if (bufferSize < 0) {
+ throw new IllegalArgumentException("bufferSize must be positive");
+ }
+
+ return new ByteOutputEncoder(byteOutput, bufferSize);
+ }
+
+ // Disallow construction outside of this class.
+ private CodedOutputStream() {
+ }
+
+ // -----------------------------------------------------------------
+
+ /** Encode and write a tag. */
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeTag(int fieldNumber, int wireType) throws IOException;
+
+ /** Write an {@code int32} field, including tag, to the stream. */
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeInt32(int fieldNumber, int value) throws IOException;
+
+ /** Write a {@code uint32} field, including tag, to the stream. */
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeUInt32(int fieldNumber, int value) throws IOException;
+
+ /** Write a {@code sint32} field, including tag, to the stream. */
+ public final void writeSInt32(final int fieldNumber, final int value) throws IOException {
+ writeUInt32(fieldNumber, encodeZigZag32(value));
+ }
+
+ /** Write a {@code fixed32} field, including tag, to the stream. */
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeFixed32(int fieldNumber, int value) throws IOException;
+
+ /** Write an {@code sfixed32} field, including tag, to the stream. */
+ public final void writeSFixed32(final int fieldNumber, final int value) throws IOException {
+ writeFixed32(fieldNumber, value);
+ }
+
+ /** Write an {@code int64} field, including tag, to the stream. */
+ public final void writeInt64(final int fieldNumber, final long value) throws IOException {
+ writeUInt64(fieldNumber, value);
+ }
+
+ /** Write a {@code uint64} field, including tag, to the stream. */
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeUInt64(int fieldNumber, long value) throws IOException;
+
+ /** Write an {@code sint64} field, including tag, to the stream. */
+ public final void writeSInt64(final int fieldNumber, final long value) throws IOException {
+ writeUInt64(fieldNumber, encodeZigZag64(value));
+ }
+
+ /** Write a {@code fixed64} field, including tag, to the stream. */
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeFixed64(int fieldNumber, long value) throws IOException;
+
+ /** Write an {@code sfixed64} field, including tag, to the stream. */
+ public final void writeSFixed64(final int fieldNumber, final long value) throws IOException {
+ writeFixed64(fieldNumber, value);
+ }
+
+ /** Write a {@code float} field, including tag, to the stream. */
+ public final void writeFloat(final int fieldNumber, final float value) throws IOException {
+ writeFixed32(fieldNumber, Float.floatToRawIntBits(value));
+ }
+
+ /** Write a {@code double} field, including tag, to the stream. */
+ public final void writeDouble(final int fieldNumber, final double value) throws IOException {
+ writeFixed64(fieldNumber, Double.doubleToRawLongBits(value));
+ }
+
+ /** Write a {@code bool} field, including tag, to the stream. */
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeBool(int fieldNumber, boolean value) throws IOException;
+
+ /**
+ * Write an enum field, including tag, to the stream. The provided value is the numeric
+ * value used to represent the enum value on the wire (not the enum ordinal value).
+ */
+ public final void writeEnum(final int fieldNumber, final int value) throws IOException {
+ writeInt32(fieldNumber, value);
+ }
+
+ /** Write a {@code string} field, including tag, to the stream. */
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeString(int fieldNumber, String value) throws IOException;
+
+ /** Write a {@code bytes} field, including tag, to the stream. */
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeBytes(int fieldNumber, ByteString value) throws IOException;
+
+ /** Write a {@code bytes} field, including tag, to the stream. */
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeByteArray(int fieldNumber, byte[] value) throws IOException;
+
+ /** Write a {@code bytes} field, including tag, to the stream. */
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeByteArray(int fieldNumber, byte[] value, int offset, int length)
+ throws IOException;
+
+ /**
+ * Write a {@code bytes} field, including tag, to the stream.
+ * This method will write all content of the ByteBuffer regardless of the
+ * current position and limit (i.e., the number of bytes to be written is
+ * value.capacity(), not value.remaining()). Furthermore, this method doesn't
+ * alter the state of the passed-in ByteBuffer. Its position, limit, mark,
+ * etc. will remain unchanged. If you only want to write the remaining bytes
+ * of a ByteBuffer, you can call
+ * {@code writeByteBuffer(fieldNumber, byteBuffer.slice())}.
+ */
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeByteBuffer(int fieldNumber, ByteBuffer value) throws IOException;
+
+ /**
+ * Write a single byte.
+ */
+ public final void writeRawByte(final byte value) throws IOException {
+ write(value);
+ }
+
+ /** Write a single byte, represented by an integer value. */
+ public final void writeRawByte(final int value) throws IOException {
+ write((byte) value);
+ }
+
+ /** Write an array of bytes. */
+ public final void writeRawBytes(final byte[] value) throws IOException {
+ write(value, 0, value.length);
+ }
+
+ /**
+ * Write part of an array of bytes.
+ */
+ public final void writeRawBytes(final byte[] value, int offset, int length) throws IOException {
+ write(value, offset, length);
+ }
+
+ /** Write a byte string. */
+ public final void writeRawBytes(final ByteString value) throws IOException {
+ value.writeTo(this);
+ }
+
+ /**
+ * Write a ByteBuffer. This method will write all content of the ByteBuffer
+ * regardless of the current position and limit (i.e., the number of bytes
+ * to be written is value.capacity(), not value.remaining()). Furthermore,
+ * this method doesn't alter the state of the passed-in ByteBuffer. Its
+ * position, limit, mark, etc. will remain unchanged. If you only want to
+ * write the remaining bytes of a ByteBuffer, you can call
+ * {@code writeRawBytes(byteBuffer.slice())}.
+ */
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeRawBytes(final ByteBuffer value) throws IOException;
+
+ /** Write an embedded message field, including tag, to the stream. */
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeMessage(final int fieldNumber, final MessageLite value)
+ throws IOException;
+
+ /**
+ * Write a MessageSet extension field to the stream. For historical reasons,
+ * the wire format differs from normal fields.
+ */
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeMessageSetExtension(final int fieldNumber, final MessageLite value)
+ throws IOException;
+
+ /**
+ * Write an unparsed MessageSet extension field to the stream. For
+ * historical reasons, the wire format differs from normal fields.
+ */
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeRawMessageSetExtension(final int fieldNumber, final ByteString value)
+ throws IOException;
+
+ // -----------------------------------------------------------------
+
+ /** Write an {@code int32} field to the stream. */
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeInt32NoTag(final int value) throws IOException;
+
+ /** Write a {@code uint32} field to the stream. */
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeUInt32NoTag(int value) throws IOException;
+
+ /** Write a {@code sint32} field to the stream. */
+ public final void writeSInt32NoTag(final int value) throws IOException {
+ writeUInt32NoTag(encodeZigZag32(value));
+ }
+
+ /** Write a {@code fixed32} field to the stream. */
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeFixed32NoTag(int value) throws IOException;
+
+ /** Write a {@code sfixed32} field to the stream. */
+ public final void writeSFixed32NoTag(final int value) throws IOException {
+ writeFixed32NoTag(value);
+ }
+
+ /** Write an {@code int64} field to the stream. */
+ public final void writeInt64NoTag(final long value) throws IOException {
+ writeUInt64NoTag(value);
+ }
+
+ /** Write a {@code uint64} field to the stream. */
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeUInt64NoTag(long value) throws IOException;
+
+ /** Write a {@code sint64} field to the stream. */
+ public final void writeSInt64NoTag(final long value) throws IOException {
+ writeUInt64NoTag(encodeZigZag64(value));
+ }
+
+ /** Write a {@code fixed64} field to the stream. */
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeFixed64NoTag(long value) throws IOException;
+
+ /** Write a {@code sfixed64} field to the stream. */
+ public final void writeSFixed64NoTag(final long value) throws IOException {
+ writeFixed64NoTag(value);
+ }
+
+ /** Write a {@code float} field to the stream. */
+ public final void writeFloatNoTag(final float value) throws IOException {
+ writeFixed32NoTag(Float.floatToRawIntBits(value));
+ }
+
+ /** Write a {@code double} field to the stream. */
+ public final void writeDoubleNoTag(final double value) throws IOException {
+ writeFixed64NoTag(Double.doubleToRawLongBits(value));
+ }
+
+ /** Write a {@code bool} field to the stream. */
+ public final void writeBoolNoTag(final boolean value) throws IOException {
+ write((byte) (value ? 1 : 0));
+ }
+
+ /**
+ * Write an enum field to the stream. The provided value is the numeric
+ * value used to represent the enum value on the wire (not the enum ordinal value).
+ */
+ public final void writeEnumNoTag(final int value) throws IOException {
+ writeInt32NoTag(value);
+ }
+
+ /** Write a {@code string} field to the stream. */
+ // TODO(dweis): Document behavior on ill-formed UTF-16 input.
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeStringNoTag(String value) throws IOException;
+
+ /** Write a {@code bytes} field to the stream. */
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeBytesNoTag(final ByteString value) throws IOException;
+
+ /** Write a {@code bytes} field to the stream. */
+ public final void writeByteArrayNoTag(final byte[] value) throws IOException {
+ writeByteArrayNoTag(value, 0, value.length);
+ }
+
+ /** Write an embedded message field to the stream. */
+ // Abstract to avoid overhead of additional virtual method calls.
+ public abstract void writeMessageNoTag(final MessageLite value) throws IOException;
+
+ //=================================================================
+
+ @ExperimentalApi
+ @Override
+ public abstract void write(byte value) throws IOException;
+
+ @ExperimentalApi
+ @Override
+ public abstract void write(byte[] value, int offset, int length) throws IOException;
+
+ @ExperimentalApi
+ @Override
+ public abstract void writeLazy(byte[] value, int offset, int length) throws IOException;
+
+ @Override
+ public abstract void write(ByteBuffer value) throws IOException;
+
+ @ExperimentalApi
+ @Override
+ public abstract void writeLazy(ByteBuffer value) throws IOException;
+
+ // =================================================================
+ // =================================================================
+
+ /**
+ * Compute the number of bytes that would be needed to encode an
+ * {@code int32} field, including tag.
+ */
+ public static int computeInt32Size(final int fieldNumber, final int value) {
+ return computeTagSize(fieldNumber) + computeInt32SizeNoTag(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code uint32} field, including tag.
+ */
+ public static int computeUInt32Size(final int fieldNumber, final int value) {
+ return computeTagSize(fieldNumber) + computeUInt32SizeNoTag(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode an
+ * {@code sint32} field, including tag.
+ */
+ public static int computeSInt32Size(final int fieldNumber, final int value) {
+ return computeTagSize(fieldNumber) + computeSInt32SizeNoTag(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code fixed32} field, including tag.
+ */
+ public static int computeFixed32Size(final int fieldNumber, final int value) {
+ return computeTagSize(fieldNumber) + computeFixed32SizeNoTag(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode an
+ * {@code sfixed32} field, including tag.
+ */
+ public static int computeSFixed32Size(final int fieldNumber, final int value) {
+ return computeTagSize(fieldNumber) + computeSFixed32SizeNoTag(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode an
+ * {@code int64} field, including tag.
+ */
+ public static int computeInt64Size(final int fieldNumber, final long value) {
+ return computeTagSize(fieldNumber) + computeInt64SizeNoTag(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code uint64} field, including tag.
+ */
+ public static int computeUInt64Size(final int fieldNumber, final long value) {
+ return computeTagSize(fieldNumber) + computeUInt64SizeNoTag(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode an
+ * {@code sint64} field, including tag.
+ */
+ public static int computeSInt64Size(final int fieldNumber, final long value) {
+ return computeTagSize(fieldNumber) + computeSInt64SizeNoTag(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code fixed64} field, including tag.
+ */
+ public static int computeFixed64Size(final int fieldNumber, final long value) {
+ return computeTagSize(fieldNumber) + computeFixed64SizeNoTag(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode an
+ * {@code sfixed64} field, including tag.
+ */
+ public static int computeSFixed64Size(final int fieldNumber, final long value) {
+ return computeTagSize(fieldNumber) + computeSFixed64SizeNoTag(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code float} field, including tag.
+ */
+ public static int computeFloatSize(final int fieldNumber, final float value) {
+ return computeTagSize(fieldNumber) + computeFloatSizeNoTag(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code double} field, including tag.
+ */
+ public static int computeDoubleSize(final int fieldNumber, final double value) {
+ return computeTagSize(fieldNumber) + computeDoubleSizeNoTag(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code bool} field, including tag.
+ */
+ public static int computeBoolSize(final int fieldNumber, final boolean value) {
+ return computeTagSize(fieldNumber) + computeBoolSizeNoTag(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode an
+ * enum field, including tag. The provided value is the numeric
+ * value used to represent the enum value on the wire (not the enum ordinal value).
+ */
+ public static int computeEnumSize(final int fieldNumber, final int value) {
+ return computeTagSize(fieldNumber) + computeEnumSizeNoTag(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code string} field, including tag.
+ */
+ public static int computeStringSize(final int fieldNumber, final String value) {
+ return computeTagSize(fieldNumber) + computeStringSizeNoTag(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code bytes} field, including tag.
+ */
+ public static int computeBytesSize(final int fieldNumber, final ByteString value) {
+ return computeTagSize(fieldNumber) + computeBytesSizeNoTag(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code bytes} field, including tag.
+ */
+ public static int computeByteArraySize(final int fieldNumber, final byte[] value) {
+ return computeTagSize(fieldNumber) + computeByteArraySizeNoTag(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code bytes} field, including tag.
+ */
+ public static int computeByteBufferSize(final int fieldNumber, final ByteBuffer value) {
+ return computeTagSize(fieldNumber) + computeByteBufferSizeNoTag(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode an
+ * embedded message in lazy field, including tag.
+ */
+ public static int computeLazyFieldSize(final int fieldNumber, final LazyFieldLite value) {
+ return computeTagSize(fieldNumber) + computeLazyFieldSizeNoTag(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode an
+ * embedded message field, including tag.
+ */
+ public static int computeMessageSize(final int fieldNumber, final MessageLite value) {
+ return computeTagSize(fieldNumber) + computeMessageSizeNoTag(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * MessageSet extension to the stream. For historical reasons,
+ * the wire format differs from normal fields.
+ */
+ public static int computeMessageSetExtensionSize(final int fieldNumber, final MessageLite value) {
+ return computeTagSize(WireFormat.MESSAGE_SET_ITEM) * 2
+ + computeUInt32Size(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber)
+ + computeMessageSize(WireFormat.MESSAGE_SET_MESSAGE, value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode an
+ * unparsed MessageSet extension field to the stream. For
+ * historical reasons, the wire format differs from normal fields.
+ */
+ public static int computeRawMessageSetExtensionSize(
+ final int fieldNumber, final ByteString value) {
+ return computeTagSize(WireFormat.MESSAGE_SET_ITEM) * 2
+ + computeUInt32Size(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber)
+ + computeBytesSize(WireFormat.MESSAGE_SET_MESSAGE, value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode an
+ * lazily parsed MessageSet extension field to the stream. For
+ * historical reasons, the wire format differs from normal fields.
+ */
+ public static int computeLazyFieldMessageSetExtensionSize(
+ final int fieldNumber, final LazyFieldLite value) {
+ return computeTagSize(WireFormat.MESSAGE_SET_ITEM) * 2
+ + computeUInt32Size(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber)
+ + computeLazyFieldSize(WireFormat.MESSAGE_SET_MESSAGE, value);
+ }
+
+ // -----------------------------------------------------------------
+
+ /** Compute the number of bytes that would be needed to encode a tag. */
+ public static int computeTagSize(final int fieldNumber) {
+ return computeUInt32SizeNoTag(WireFormat.makeTag(fieldNumber, 0));
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode an
+ * {@code int32} field, including tag.
+ */
+ public static int computeInt32SizeNoTag(final int value) {
+ if (value >= 0) {
+ return computeUInt32SizeNoTag(value);
+ } else {
+ // Must sign-extend.
+ return MAX_VARINT_SIZE;
+ }
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code uint32} field.
+ */
+ public static int computeUInt32SizeNoTag(final int value) {
+ if ((value & (~0 << 7)) == 0) {
+ return 1;
+ }
+ if ((value & (~0 << 14)) == 0) {
+ return 2;
+ }
+ if ((value & (~0 << 21)) == 0) {
+ return 3;
+ }
+ if ((value & (~0 << 28)) == 0) {
+ return 4;
+ }
+ return 5;
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode an
+ * {@code sint32} field.
+ */
+ public static int computeSInt32SizeNoTag(final int value) {
+ return computeUInt32SizeNoTag(encodeZigZag32(value));
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code fixed32} field.
+ */
+ public static int computeFixed32SizeNoTag(@SuppressWarnings("unused") final int unused) {
+ return FIXED_32_SIZE;
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode an
+ * {@code sfixed32} field.
+ */
+ public static int computeSFixed32SizeNoTag(@SuppressWarnings("unused") final int unused) {
+ return FIXED_32_SIZE;
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode an
+ * {@code int64} field, including tag.
+ */
+ public static int computeInt64SizeNoTag(final long value) {
+ return computeUInt64SizeNoTag(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code uint64} field, including tag.
+ */
+ public static int computeUInt64SizeNoTag(long value) {
+ // handle two popular special cases up front ...
+ if ((value & (~0L << 7)) == 0L) {
+ return 1;
+ }
+ if (value < 0L) {
+ return 10;
+ }
+ // ... leaving us with 8 remaining, which we can divide and conquer
+ int n = 2;
+ if ((value & (~0L << 35)) != 0L) {
+ n += 4; value >>>= 28;
+ }
+ if ((value & (~0L << 21)) != 0L) {
+ n += 2; value >>>= 14;
+ }
+ if ((value & (~0L << 14)) != 0L) {
+ n += 1;
+ }
+ return n;
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode an
+ * {@code sint64} field.
+ */
+ public static int computeSInt64SizeNoTag(final long value) {
+ return computeUInt64SizeNoTag(encodeZigZag64(value));
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code fixed64} field.
+ */
+ public static int computeFixed64SizeNoTag(@SuppressWarnings("unused") final long unused) {
+ return FIXED_64_SIZE;
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode an
+ * {@code sfixed64} field.
+ */
+ public static int computeSFixed64SizeNoTag(@SuppressWarnings("unused") final long unused) {
+ return FIXED_64_SIZE;
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code float} field, including tag.
+ */
+ public static int computeFloatSizeNoTag(@SuppressWarnings("unused") final float unused) {
+ return FIXED_32_SIZE;
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code double} field, including tag.
+ */
+ public static int computeDoubleSizeNoTag(@SuppressWarnings("unused") final double unused) {
+ return FIXED_64_SIZE;
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code bool} field.
+ */
+ public static int computeBoolSizeNoTag(@SuppressWarnings("unused") final boolean unused) {
+ return 1;
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode an enum field.
+ * The provided value is the numeric value used to represent the enum value on the wire
+ * (not the enum ordinal value).
+ */
+ public static int computeEnumSizeNoTag(final int value) {
+ return computeInt32SizeNoTag(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code string} field.
+ */
+ public static int computeStringSizeNoTag(final String value) {
+ int length;
+ try {
+ length = Utf8.encodedLength(value);
+ } catch (UnpairedSurrogateException e) {
+ // TODO(dweis): Consider using nio Charset methods instead.
+ final byte[] bytes = value.getBytes(Internal.UTF_8);
+ length = bytes.length;
+ }
+
+ return computeLengthDelimitedFieldSize(length);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode an embedded
+ * message stored in lazy field.
+ */
+ public static int computeLazyFieldSizeNoTag(final LazyFieldLite value) {
+ return computeLengthDelimitedFieldSize(value.getSerializedSize());
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code bytes} field.
+ */
+ public static int computeBytesSizeNoTag(final ByteString value) {
+ return computeLengthDelimitedFieldSize(value.size());
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code bytes} field.
+ */
+ public static int computeByteArraySizeNoTag(final byte[] value) {
+ return computeLengthDelimitedFieldSize(value.length);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code bytes} field.
+ */
+ public static int computeByteBufferSizeNoTag(final ByteBuffer value) {
+ return computeLengthDelimitedFieldSize(value.capacity());
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode an embedded
+ * message field.
+ */
+ public static int computeMessageSizeNoTag(final MessageLite value) {
+ return computeLengthDelimitedFieldSize(value.getSerializedSize());
+ }
+
+ static int computeLengthDelimitedFieldSize(int fieldLength) {
+ return computeUInt32SizeNoTag(fieldLength) + fieldLength;
+ }
+
+ /**
+ * Encode a ZigZag-encoded 32-bit value. ZigZag encodes signed integers
+ * into values that can be efficiently encoded with varint. (Otherwise,
+ * negative values must be sign-extended to 64 bits to be varint encoded,
+ * thus always taking 10 bytes on the wire.)
+ *
+ * @param n A signed 32-bit integer.
+ * @return An unsigned 32-bit integer, stored in a signed int because
+ * Java has no explicit unsigned support.
+ */
+ public static int encodeZigZag32(final int n) {
+ // Note: the right-shift must be arithmetic
+ return (n << 1) ^ (n >> 31);
+ }
+
+ /**
+ * Encode a ZigZag-encoded 64-bit value. ZigZag encodes signed integers
+ * into values that can be efficiently encoded with varint. (Otherwise,
+ * negative values must be sign-extended to 64 bits to be varint encoded,
+ * thus always taking 10 bytes on the wire.)
+ *
+ * @param n A signed 64-bit integer.
+ * @return An unsigned 64-bit integer, stored in a signed int because
+ * Java has no explicit unsigned support.
+ */
+ public static long encodeZigZag64(final long n) {
+ // Note: the right-shift must be arithmetic
+ return (n << 1) ^ (n >> 63);
+ }
+
+ // =================================================================
+
+ /**
+ * Flushes the stream and forces any buffered bytes to be written. This
+ * does not flush the underlying OutputStream.
+ */
+ public abstract void flush() throws IOException;
+
+ /**
+ * If writing to a flat array, return the space left in the array.
+ * Otherwise, throws {@code UnsupportedOperationException}.
+ */
+ public abstract int spaceLeft();
+
+ /**
+ * Verifies that {@link #spaceLeft()} returns zero. It's common to create
+ * a byte array that is exactly big enough to hold a message, then write to
+ * it with a {@code CodedOutputStream}. Calling {@code checkNoSpaceLeft()}
+ * after writing verifies that the message was actually as big as expected,
+ * which can help catch bugs.
+ */
+ public final void checkNoSpaceLeft() {
+ if (spaceLeft() != 0) {
+ throw new IllegalStateException("Did not write as much data as expected.");
+ }
+ }
+
+ /**
+ * If you create a CodedOutputStream around a simple flat array, you must
+ * not attempt to write more bytes than the array has space. Otherwise,
+ * this exception will be thrown.
+ */
+ public static class OutOfSpaceException extends IOException {
+ private static final long serialVersionUID = -6947486886997889499L;
+
+ private static final String MESSAGE =
+ "CodedOutputStream was writing to a flat byte array and ran out of space.";
+
+ OutOfSpaceException() {
+ super(MESSAGE);
+ }
+
+ OutOfSpaceException(Throwable cause) {
+ super(MESSAGE, cause);
+ }
+
+ OutOfSpaceException(String explanationMessage, Throwable cause) {
+ super(MESSAGE + ": " + explanationMessage, cause);
+ }
+ }
+
+ /**
+ * Get the total number of bytes successfully written to this stream. The
+ * returned value is not guaranteed to be accurate if exceptions have been
+ * found in the middle of writing.
+ */
+ public abstract int getTotalBytesWritten();
+
+ // =================================================================
+
+ /** Write a {@code bytes} field to the stream. Visible for testing. */
+ abstract void writeByteArrayNoTag(final byte[] value, final int offset, final int length)
+ throws IOException;
+
+ final void inefficientWriteStringNoTag(String value, UnpairedSurrogateException cause)
+ throws IOException {
+ logger.log(Level.WARNING,
+ "Converting ill-formed UTF-16. Your Protocol Buffer will not round trip correctly!", cause);
+
+ // Unfortunately there does not appear to be any way to tell Java to encode
+ // UTF-8 directly into our buffer, so we have to let it create its own byte
+ // array and then copy.
+ // TODO(dweis): Consider using nio Charset methods instead.
+ final byte[] bytes = value.getBytes(Internal.UTF_8);
+ try {
+ writeUInt32NoTag(bytes.length);
+ writeLazy(bytes, 0, bytes.length);
+ } catch (IndexOutOfBoundsException e) {
+ throw new OutOfSpaceException(e);
+ } catch (OutOfSpaceException e) {
+ throw e;
+ }
+ }
+
+ // =================================================================
+
+ /**
+ * Write a {@code group} field, including tag, to the stream.
+ *
+ * @deprecated groups are deprecated.
+ */
+ @Deprecated
+ public final void writeGroup(final int fieldNumber, final MessageLite value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_START_GROUP);
+ writeGroupNoTag(value);
+ writeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP);
+ }
+
+ /**
+ * Write a {@code group} field to the stream.
+ *
+ * @deprecated groups are deprecated.
+ */
+ @Deprecated
+ public final void writeGroupNoTag(final MessageLite value) throws IOException {
+ value.writeTo(this);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code group} field, including tag.
+ *
+ * @deprecated groups are deprecated.
+ */
+ @Deprecated
+ public static int computeGroupSize(final int fieldNumber, final MessageLite value) {
+ return computeTagSize(fieldNumber) * 2 + computeGroupSizeNoTag(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code group} field.
+ */
+ @Deprecated
+ public static int computeGroupSizeNoTag(final MessageLite value) {
+ return value.getSerializedSize();
+ }
+
+ /**
+ * Encode and write a varint. {@code value} is treated as
+ * unsigned, so it won't be sign-extended if negative.
+ *
+ * @deprecated use {@link #writeUInt32NoTag} instead.
+ */
+ @Deprecated
+ public final void writeRawVarint32(int value) throws IOException {
+ writeUInt32NoTag(value);
+ }
+
+ /**
+ * Encode and write a varint.
+ *
+ * @deprecated use {@link #writeUInt64NoTag} instead.
+ */
+ @Deprecated
+ public final void writeRawVarint64(long value) throws IOException {
+ writeUInt64NoTag(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a varint.
+ * {@code value} is treated as unsigned, so it won't be sign-extended if
+ * negative.
+ *
+ * @deprecated use {@link #computeUInt32SizeNoTag(int)} instead.
+ */
+ @Deprecated
+ public static int computeRawVarint32Size(final int value) {
+ return computeUInt32SizeNoTag(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a varint.
+ *
+ * @deprecated use {@link #computeUInt64SizeNoTag(long)} instead.
+ */
+ @Deprecated
+ public static int computeRawVarint64Size(long value) {
+ return computeUInt64SizeNoTag(value);
+ }
+
+ /**
+ * Write a little-endian 32-bit integer.
+ *
+ * @deprecated Use {@link #writeFixed32NoTag} instead.
+ */
+ @Deprecated
+ public final void writeRawLittleEndian32(final int value) throws IOException {
+ writeFixed32NoTag(value);
+ }
+
+ /**
+ * Write a little-endian 64-bit integer.
+ *
+ * @deprecated Use {@link #writeFixed64NoTag} instead.
+ */
+ @Deprecated
+ public final void writeRawLittleEndian64(final long value) throws IOException {
+ writeFixed64NoTag(value);
+ }
+
+ // =================================================================
+
+ /**
+ * A {@link CodedOutputStream} that writes directly to a byte array.
+ */
+ private static class ArrayEncoder extends CodedOutputStream {
+ private final byte[] buffer;
+ private final int offset;
+ private final int limit;
+ private int position;
+
+ ArrayEncoder(byte[] buffer, int offset, int length) {
+ if (buffer == null) {
+ throw new NullPointerException("buffer");
+ }
+ if ((offset | length | (buffer.length - (offset + length))) < 0) {
+ throw new IllegalArgumentException(String.format(
+ "Array range is invalid. Buffer.length=%d, offset=%d, length=%d",
+ buffer.length, offset, length));
+ }
+ this.buffer = buffer;
+ this.offset = offset;
+ position = offset;
+ limit = offset + length;
+ }
+
+ @Override
+ public final void writeTag(final int fieldNumber, final int wireType) throws IOException {
+ writeUInt32NoTag(WireFormat.makeTag(fieldNumber, wireType));
+ }
+
+ @Override
+ public final void writeInt32(final int fieldNumber, final int value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ writeInt32NoTag(value);
+ }
+
+ @Override
+ public final void writeUInt32(final int fieldNumber, final int value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ writeUInt32NoTag(value);
+ }
+
+ @Override
+ public final void writeFixed32(final int fieldNumber, final int value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
+ writeFixed32NoTag(value);
+ }
+
+ @Override
+ public final void writeUInt64(final int fieldNumber, final long value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ writeUInt64NoTag(value);
+ }
+
+ @Override
+ public final void writeFixed64(final int fieldNumber, final long value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
+ writeFixed64NoTag(value);
+ }
+
+ @Override
+ public final void writeBool(final int fieldNumber, final boolean value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ write((byte) (value ? 1 : 0));
+ }
+
+ @Override
+ public final void writeString(final int fieldNumber, final String value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ writeStringNoTag(value);
+ }
+
+ @Override
+ public final void writeBytes(final int fieldNumber, final ByteString value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ writeBytesNoTag(value);
+ }
+
+ @Override
+ public final void writeByteArray(final int fieldNumber, final byte[] value) throws IOException {
+ writeByteArray(fieldNumber, value, 0, value.length);
+ }
+
+ @Override
+ public final void writeByteArray(
+ final int fieldNumber, final byte[] value, final int offset, final int length)
+ throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ writeByteArrayNoTag(value, offset, length);
+ }
+
+ @Override
+ public final void writeByteBuffer(final int fieldNumber, final ByteBuffer value)
+ throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ writeUInt32NoTag(value.capacity());
+ writeRawBytes(value);
+ }
+
+ @Override
+ public final void writeBytesNoTag(final ByteString value) throws IOException {
+ writeUInt32NoTag(value.size());
+ value.writeTo(this);
+ }
+
+ @Override
+ public final void writeByteArrayNoTag(final byte[] value, int offset, int length)
+ throws IOException {
+ writeUInt32NoTag(length);
+ write(value, offset, length);
+ }
+
+ @Override
+ public final void writeRawBytes(final ByteBuffer value) throws IOException {
+ if (value.hasArray()) {
+ write(value.array(), value.arrayOffset(), value.capacity());
+ } else {
+ ByteBuffer duplicated = value.duplicate();
+ duplicated.clear();
+ write(duplicated);
+ }
+ }
+
+ @Override
+ public final void writeMessage(final int fieldNumber, final MessageLite value)
+ throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ writeMessageNoTag(value);
+ }
+
+ @Override
+ public final void writeMessageSetExtension(final int fieldNumber, final MessageLite value)
+ throws IOException {
+ writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP);
+ writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber);
+ writeMessage(WireFormat.MESSAGE_SET_MESSAGE, value);
+ writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP);
+ }
+
+ @Override
+ public final void writeRawMessageSetExtension(final int fieldNumber, final ByteString value)
+ throws IOException {
+ writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP);
+ writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber);
+ writeBytes(WireFormat.MESSAGE_SET_MESSAGE, value);
+ writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP);
+ }
+
+ @Override
+ public final void writeMessageNoTag(final MessageLite value) throws IOException {
+ writeUInt32NoTag(value.getSerializedSize());
+ value.writeTo(this);
+ }
+
+ @Override
+ public final void write(byte value) throws IOException {
+ try {
+ buffer[position++] = value;
+ } catch (IndexOutOfBoundsException e) {
+ throw new OutOfSpaceException(
+ String.format("Pos: %d, limit: %d, len: %d", position, limit, 1), e);
+ }
+ }
+
+ @Override
+ public final void writeInt32NoTag(int value) throws IOException {
+ if (value >= 0) {
+ writeUInt32NoTag(value);
+ } else {
+ // Must sign-extend.
+ writeUInt64NoTag(value);
+ }
+ }
+
+ @Override
+ public final void writeUInt32NoTag(int value) throws IOException {
+ if (HAS_UNSAFE_ARRAY_OPERATIONS && spaceLeft() >= MAX_VARINT_SIZE) {
+ long pos = ARRAY_BASE_OFFSET + position;
+ while (true) {
+ if ((value & ~0x7F) == 0) {
+ UnsafeUtil.putByte(buffer, pos++, (byte) value);
+ position++;
+ return;
+ } else {
+ UnsafeUtil.putByte(buffer, pos++, (byte) ((value & 0x7F) | 0x80));
+ position++;
+ value >>>= 7;
+ }
+ }
+ } else {
+ try {
+ while (true) {
+ if ((value & ~0x7F) == 0) {
+ buffer[position++] = (byte) value;
+ return;
+ } else {
+ buffer[position++] = (byte) ((value & 0x7F) | 0x80);
+ value >>>= 7;
+ }
+ }
+ } catch (IndexOutOfBoundsException e) {
+ throw new OutOfSpaceException(
+ String.format("Pos: %d, limit: %d, len: %d", position, limit, 1), e);
+ }
+ }
+ }
+
+ @Override
+ public final void writeFixed32NoTag(int value) throws IOException {
+ try {
+ buffer[position++] = (byte) (value & 0xFF);
+ buffer[position++] = (byte) ((value >> 8) & 0xFF);
+ buffer[position++] = (byte) ((value >> 16) & 0xFF);
+ buffer[position++] = (byte) ((value >> 24) & 0xFF);
+ } catch (IndexOutOfBoundsException e) {
+ throw new OutOfSpaceException(
+ String.format("Pos: %d, limit: %d, len: %d", position, limit, 1), e);
+ }
+ }
+
+ @Override
+ public final void writeUInt64NoTag(long value) throws IOException {
+ if (HAS_UNSAFE_ARRAY_OPERATIONS && spaceLeft() >= MAX_VARINT_SIZE) {
+ long pos = ARRAY_BASE_OFFSET + position;
+ while (true) {
+ if ((value & ~0x7FL) == 0) {
+ UnsafeUtil.putByte(buffer, pos++, (byte) value);
+ position++;
+ return;
+ } else {
+ UnsafeUtil.putByte(buffer, pos++, (byte) (((int) value & 0x7F) | 0x80));
+ position++;
+ value >>>= 7;
+ }
+ }
+ } else {
+ try {
+ while (true) {
+ if ((value & ~0x7FL) == 0) {
+ buffer[position++] = (byte) value;
+ return;
+ } else {
+ buffer[position++] = (byte) (((int) value & 0x7F) | 0x80);
+ value >>>= 7;
+ }
+ }
+ } catch (IndexOutOfBoundsException e) {
+ throw new OutOfSpaceException(
+ String.format("Pos: %d, limit: %d, len: %d", position, limit, 1), e);
+ }
+ }
+ }
+
+ @Override
+ public final void writeFixed64NoTag(long value) throws IOException {
+ try {
+ buffer[position++] = (byte) ((int) (value) & 0xFF);
+ buffer[position++] = (byte) ((int) (value >> 8) & 0xFF);
+ buffer[position++] = (byte) ((int) (value >> 16) & 0xFF);
+ buffer[position++] = (byte) ((int) (value >> 24) & 0xFF);
+ buffer[position++] = (byte) ((int) (value >> 32) & 0xFF);
+ buffer[position++] = (byte) ((int) (value >> 40) & 0xFF);
+ buffer[position++] = (byte) ((int) (value >> 48) & 0xFF);
+ buffer[position++] = (byte) ((int) (value >> 56) & 0xFF);
+ } catch (IndexOutOfBoundsException e) {
+ throw new OutOfSpaceException(
+ String.format("Pos: %d, limit: %d, len: %d", position, limit, 1), e);
+ }
+ }
+
+ @Override
+ public final void write(byte[] value, int offset, int length) throws IOException {
+ try {
+ System.arraycopy(value, offset, buffer, position, length);
+ position += length;
+ } catch (IndexOutOfBoundsException e) {
+ throw new OutOfSpaceException(
+ String.format("Pos: %d, limit: %d, len: %d", position, limit, length), e);
+ }
+ }
+
+ @Override
+ public final void writeLazy(byte[] value, int offset, int length) throws IOException {
+ write(value, offset, length);
+ }
+
+ @Override
+ public final void write(ByteBuffer value) throws IOException {
+ final int length = value.remaining();
+ try {
+ value.get(buffer, position, length);
+ position += length;
+ } catch (IndexOutOfBoundsException e) {
+ throw new OutOfSpaceException(
+ String.format("Pos: %d, limit: %d, len: %d", position, limit, length), e);
+ }
+ }
+
+ @Override
+ public final void writeLazy(ByteBuffer value) throws IOException {
+ write(value);
+ }
+
+ @Override
+ public final void writeStringNoTag(String value) throws IOException {
+ final int oldPosition = position;
+ try {
+ // UTF-8 byte length of the string is at least its UTF-16 code unit length (value.length()),
+ // and at most 3 times of it. We take advantage of this in both branches below.
+ final int maxLength = value.length() * Utf8.MAX_BYTES_PER_CHAR;
+ final int maxLengthVarIntSize = computeUInt32SizeNoTag(maxLength);
+ final int minLengthVarIntSize = computeUInt32SizeNoTag(value.length());
+ if (minLengthVarIntSize == maxLengthVarIntSize) {
+ position = oldPosition + minLengthVarIntSize;
+ int newPosition = Utf8.encode(value, buffer, position, spaceLeft());
+ // Since this class is stateful and tracks the position, we rewind and store the state,
+ // prepend the length, then reset it back to the end of the string.
+ position = oldPosition;
+ int length = newPosition - oldPosition - minLengthVarIntSize;
+ writeUInt32NoTag(length);
+ position = newPosition;
+ } else {
+ int length = Utf8.encodedLength(value);
+ writeUInt32NoTag(length);
+ position = Utf8.encode(value, buffer, position, spaceLeft());
+ }
+ } catch (UnpairedSurrogateException e) {
+ // Roll back the change - we fall back to inefficient path.
+ position = oldPosition;
+
+ // TODO(nathanmittler): We should throw an IOException here instead.
+ inefficientWriteStringNoTag(value, e);
+ } catch (IndexOutOfBoundsException e) {
+ throw new OutOfSpaceException(e);
+ }
+ }
+
+ @Override
+ public void flush() {
+ // Do nothing.
+ }
+
+ @Override
+ public final int spaceLeft() {
+ return limit - position;
+ }
+
+ @Override
+ public final int getTotalBytesWritten() {
+ return position - offset;
+ }
+ }
+
+ /**
+ * A {@link CodedOutputStream} that writes directly to a heap {@link ByteBuffer}. Writes are
+ * done directly to the underlying array. The buffer position is only updated after a flush.
+ */
+ private static final class NioHeapEncoder extends ArrayEncoder {
+ private final ByteBuffer byteBuffer;
+ private int initialPosition;
+
+ NioHeapEncoder(ByteBuffer byteBuffer) {
+ super(byteBuffer.array(), byteBuffer.arrayOffset() + byteBuffer.position(),
+ byteBuffer.remaining());
+ this.byteBuffer = byteBuffer;
+ this.initialPosition = byteBuffer.position();
+ }
+
+ @Override
+ public void flush() {
+ // Update the position on the buffer.
+ byteBuffer.position(initialPosition + getTotalBytesWritten());
+ }
+ }
+
+ /**
+ * A {@link CodedOutputStream} that writes directly to a {@link ByteBuffer}.
+ */
+ private static final class NioEncoder extends CodedOutputStream {
+ private final ByteBuffer originalBuffer;
+ private final ByteBuffer buffer;
+ private final int initialPosition;
+
+ NioEncoder(ByteBuffer buffer) {
+ this.originalBuffer = buffer;
+ this.buffer = buffer.duplicate().order(ByteOrder.LITTLE_ENDIAN);
+ initialPosition = buffer.position();
+ }
+
+ @Override
+ public void writeTag(final int fieldNumber, final int wireType) throws IOException {
+ writeUInt32NoTag(WireFormat.makeTag(fieldNumber, wireType));
+ }
+
+ @Override
+ public void writeInt32(final int fieldNumber, final int value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ writeInt32NoTag(value);
+ }
+
+ @Override
+ public void writeUInt32(final int fieldNumber, final int value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ writeUInt32NoTag(value);
+ }
+
+ @Override
+ public void writeFixed32(final int fieldNumber, final int value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
+ writeFixed32NoTag(value);
+ }
+
+ @Override
+ public void writeUInt64(final int fieldNumber, final long value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ writeUInt64NoTag(value);
+ }
+
+ @Override
+ public void writeFixed64(final int fieldNumber, final long value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
+ writeFixed64NoTag(value);
+ }
+
+ @Override
+ public void writeBool(final int fieldNumber, final boolean value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ write((byte) (value ? 1 : 0));
+ }
+
+ @Override
+ public void writeString(final int fieldNumber, final String value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ writeStringNoTag(value);
+ }
+
+ @Override
+ public void writeBytes(final int fieldNumber, final ByteString value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ writeBytesNoTag(value);
+ }
+
+ @Override
+ public void writeByteArray(final int fieldNumber, final byte[] value) throws IOException {
+ writeByteArray(fieldNumber, value, 0, value.length);
+ }
+
+ @Override
+ public void writeByteArray(
+ final int fieldNumber, final byte[] value, final int offset, final int length)
+ throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ writeByteArrayNoTag(value, offset, length);
+ }
+
+ @Override
+ public void writeByteBuffer(final int fieldNumber, final ByteBuffer value)
+ throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ writeUInt32NoTag(value.capacity());
+ writeRawBytes(value);
+ }
+
+ @Override
+ public void writeMessage(final int fieldNumber, final MessageLite value)
+ throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ writeMessageNoTag(value);
+ }
+
+ @Override
+ public void writeMessageSetExtension(final int fieldNumber, final MessageLite value)
+ throws IOException {
+ writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP);
+ writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber);
+ writeMessage(WireFormat.MESSAGE_SET_MESSAGE, value);
+ writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP);
+ }
+
+ @Override
+ public void writeRawMessageSetExtension(final int fieldNumber, final ByteString value)
+ throws IOException {
+ writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP);
+ writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber);
+ writeBytes(WireFormat.MESSAGE_SET_MESSAGE, value);
+ writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP);
+ }
+
+ @Override
+ public void writeMessageNoTag(final MessageLite value) throws IOException {
+ writeUInt32NoTag(value.getSerializedSize());
+ value.writeTo(this);
+ }
+
+ @Override
+ public void write(byte value) throws IOException {
+ try {
+ buffer.put(value);
+ } catch (BufferOverflowException e) {
+ throw new OutOfSpaceException(e);
+ }
+ }
+
+ @Override
+ public void writeBytesNoTag(final ByteString value) throws IOException {
+ writeUInt32NoTag(value.size());
+ value.writeTo(this);
+ }
+
+ @Override
+ public void writeByteArrayNoTag(final byte[] value, int offset, int length) throws IOException {
+ writeUInt32NoTag(length);
+ write(value, offset, length);
+ }
+
+ @Override
+ public void writeRawBytes(final ByteBuffer value) throws IOException {
+ if (value.hasArray()) {
+ write(value.array(), value.arrayOffset(), value.capacity());
+ } else {
+ ByteBuffer duplicated = value.duplicate();
+ duplicated.clear();
+ write(duplicated);
+ }
+ }
+
+ @Override
+ public void writeInt32NoTag(int value) throws IOException {
+ if (value >= 0) {
+ writeUInt32NoTag(value);
+ } else {
+ // Must sign-extend.
+ writeUInt64NoTag(value);
+ }
+ }
+
+ @Override
+ public void writeUInt32NoTag(int value) throws IOException {
+ try {
+ while (true) {
+ if ((value & ~0x7F) == 0) {
+ buffer.put((byte) value);
+ return;
+ } else {
+ buffer.put((byte) ((value & 0x7F) | 0x80));
+ value >>>= 7;
+ }
+ }
+ } catch (BufferOverflowException e) {
+ throw new OutOfSpaceException(e);
+ }
+ }
+
+ @Override
+ public void writeFixed32NoTag(int value) throws IOException {
+ try {
+ buffer.putInt(value);
+ } catch (BufferOverflowException e) {
+ throw new OutOfSpaceException(e);
+ }
+ }
+
+ @Override
+ public void writeUInt64NoTag(long value) throws IOException {
+ try {
+ while (true) {
+ if ((value & ~0x7FL) == 0) {
+ buffer.put((byte) value);
+ return;
+ } else {
+ buffer.put((byte) (((int) value & 0x7F) | 0x80));
+ value >>>= 7;
+ }
+ }
+ } catch (BufferOverflowException e) {
+ throw new OutOfSpaceException(e);
+ }
+ }
+
+ @Override
+ public void writeFixed64NoTag(long value) throws IOException {
+ try {
+ buffer.putLong(value);
+ } catch (BufferOverflowException e) {
+ throw new OutOfSpaceException(e);
+ }
+ }
+
+ @Override
+ public void write(byte[] value, int offset, int length) throws IOException {
+ try {
+ buffer.put(value, offset, length);
+ } catch (IndexOutOfBoundsException e) {
+ throw new OutOfSpaceException(e);
+ } catch (BufferOverflowException e) {
+ throw new OutOfSpaceException(e);
+ }
+ }
+
+ @Override
+ public void writeLazy(byte[] value, int offset, int length) throws IOException {
+ write(value, offset, length);
+ }
+
+ @Override
+ public void write(ByteBuffer value) throws IOException {
+ try {
+ buffer.put(value);
+ } catch (BufferOverflowException e) {
+ throw new OutOfSpaceException(e);
+ }
+ }
+
+ @Override
+ public void writeLazy(ByteBuffer value) throws IOException {
+ write(value);
+ }
+
+ @Override
+ public void writeStringNoTag(String value) throws IOException {
+ final int startPos = buffer.position();
+ try {
+ // UTF-8 byte length of the string is at least its UTF-16 code unit length (value.length()),
+ // and at most 3 times of it. We take advantage of this in both branches below.
+ final int maxEncodedSize = value.length() * Utf8.MAX_BYTES_PER_CHAR;
+ final int maxLengthVarIntSize = computeUInt32SizeNoTag(maxEncodedSize);
+ final int minLengthVarIntSize = computeUInt32SizeNoTag(value.length());
+ if (minLengthVarIntSize == maxLengthVarIntSize) {
+ // Save the current position and increment past the length field. We'll come back
+ // and write the length field after the encoding is complete.
+ final int startOfBytes = buffer.position() + minLengthVarIntSize;
+ buffer.position(startOfBytes);
+
+ // Encode the string.
+ encode(value);
+
+ // Now go back to the beginning and write the length.
+ int endOfBytes = buffer.position();
+ buffer.position(startPos);
+ writeUInt32NoTag(endOfBytes - startOfBytes);
+
+ // Reposition the buffer past the written data.
+ buffer.position(endOfBytes);
+ } else {
+ final int length = Utf8.encodedLength(value);
+ writeUInt32NoTag(length);
+ encode(value);
+ }
+ } catch (UnpairedSurrogateException e) {
+ // Roll back the change and convert to an IOException.
+ buffer.position(startPos);
+
+ // TODO(nathanmittler): We should throw an IOException here instead.
+ inefficientWriteStringNoTag(value, e);
+ } catch (IllegalArgumentException e) {
+ // Thrown by buffer.position() if out of range.
+ throw new OutOfSpaceException(e);
+ }
+ }
+
+ @Override
+ public void flush() {
+ // Update the position of the original buffer.
+ originalBuffer.position(buffer.position());
+ }
+
+ @Override
+ public int spaceLeft() {
+ return buffer.remaining();
+ }
+
+ @Override
+ public int getTotalBytesWritten() {
+ return buffer.position() - initialPosition;
+ }
+
+ private void encode(String value) throws IOException {
+ try {
+ Utf8.encodeUtf8(value, buffer);
+ } catch (IndexOutOfBoundsException e) {
+ throw new OutOfSpaceException(e);
+ }
+ }
+ }
+
+ /**
+ * Abstract base class for buffered encoders.
+ */
+ private abstract static class AbstractBufferedEncoder extends CodedOutputStream {
+ final byte[] buffer;
+ final int limit;
+ int position;
+ int totalBytesWritten;
+
+ AbstractBufferedEncoder(int bufferSize) {
+ if (bufferSize < 0) {
+ throw new IllegalArgumentException("bufferSize must be >= 0");
+ }
+ // As an optimization, we require that the buffer be able to store at least 2
+ // varints so that we can buffer any integer write (tag + value). This reduces the
+ // number of range checks for a single write to 1 (i.e. if there is not enough space
+ // to buffer the tag+value, flush and then buffer it).
+ this.buffer = new byte[max(bufferSize, MAX_VARINT_SIZE * 2)];
+ this.limit = buffer.length;
+ }
+
+ @Override
+ public final int spaceLeft() {
+ throw new UnsupportedOperationException(
+ "spaceLeft() can only be called on CodedOutputStreams that are "
+ + "writing to a flat array or ByteBuffer.");
+ }
+
+ @Override
+ public final int getTotalBytesWritten() {
+ return totalBytesWritten;
+ }
+
+ /**
+ * This method does not perform bounds checking on the array. Checking array bounds is the
+ * responsibility of the caller.
+ */
+ final void buffer(byte value) {
+ buffer[position++] = value;
+ totalBytesWritten++;
+ }
+
+ /**
+ * This method does not perform bounds checking on the array. Checking array bounds is the
+ * responsibility of the caller.
+ */
+ final void bufferTag(final int fieldNumber, final int wireType) {
+ bufferUInt32NoTag(WireFormat.makeTag(fieldNumber, wireType));
+ }
+
+ /**
+ * This method does not perform bounds checking on the array. Checking array bounds is the
+ * responsibility of the caller.
+ */
+ final void bufferInt32NoTag(final int value) {
+ if (value >= 0) {
+ bufferUInt32NoTag(value);
+ } else {
+ // Must sign-extend.
+ bufferUInt64NoTag(value);
+ }
+ }
+
+ /**
+ * This method does not perform bounds checking on the array. Checking array bounds is the
+ * responsibility of the caller.
+ */
+ final void bufferUInt32NoTag(int value) {
+ if (HAS_UNSAFE_ARRAY_OPERATIONS) {
+ final long originalPos = ARRAY_BASE_OFFSET + position;
+ long pos = originalPos;
+ while (true) {
+ if ((value & ~0x7F) == 0) {
+ UnsafeUtil.putByte(buffer, pos++, (byte) value);
+ break;
+ } else {
+ UnsafeUtil.putByte(buffer, pos++, (byte) ((value & 0x7F) | 0x80));
+ value >>>= 7;
+ }
+ }
+ int delta = (int) (pos - originalPos);
+ position += delta;
+ totalBytesWritten += delta;
+ } else {
+ while (true) {
+ if ((value & ~0x7F) == 0) {
+ buffer[position++] = (byte) value;
+ totalBytesWritten++;
+ return;
+ } else {
+ buffer[position++] = (byte) ((value & 0x7F) | 0x80);
+ totalBytesWritten++;
+ value >>>= 7;
+ }
+ }
+ }
+ }
+
+ /**
+ * This method does not perform bounds checking on the array. Checking array bounds is the
+ * responsibility of the caller.
+ */
+ final void bufferUInt64NoTag(long value) {
+ if (HAS_UNSAFE_ARRAY_OPERATIONS) {
+ final long originalPos = ARRAY_BASE_OFFSET + position;
+ long pos = originalPos;
+ while (true) {
+ if ((value & ~0x7FL) == 0) {
+ UnsafeUtil.putByte(buffer, pos++, (byte) value);
+ break;
+ } else {
+ UnsafeUtil.putByte(buffer, pos++, (byte) (((int) value & 0x7F) | 0x80));
+ value >>>= 7;
+ }
+ }
+ int delta = (int) (pos - originalPos);
+ position += delta;
+ totalBytesWritten += delta;
+ } else {
+ while (true) {
+ if ((value & ~0x7FL) == 0) {
+ buffer[position++] = (byte) value;
+ totalBytesWritten++;
+ return;
+ } else {
+ buffer[position++] = (byte) (((int) value & 0x7F) | 0x80);
+ totalBytesWritten++;
+ value >>>= 7;
+ }
+ }
+ }
+ }
+
+ /**
+ * This method does not perform bounds checking on the array. Checking array bounds is the
+ * responsibility of the caller.
+ */
+ final void bufferFixed32NoTag(int value) {
+ buffer[position++] = (byte) (value & 0xFF);
+ buffer[position++] = (byte) ((value >> 8) & 0xFF);
+ buffer[position++] = (byte) ((value >> 16) & 0xFF);
+ buffer[position++] = (byte) ((value >> 24) & 0xFF);
+ totalBytesWritten += FIXED_32_SIZE;
+ }
+
+ /**
+ * This method does not perform bounds checking on the array. Checking array bounds is the
+ * responsibility of the caller.
+ */
+ final void bufferFixed64NoTag(long value) {
+ buffer[position++] = (byte) (value & 0xFF);
+ buffer[position++] = (byte) ((value >> 8) & 0xFF);
+ buffer[position++] = (byte) ((value >> 16) & 0xFF);
+ buffer[position++] = (byte) ((value >> 24) & 0xFF);
+ buffer[position++] = (byte) ((int) (value >> 32) & 0xFF);
+ buffer[position++] = (byte) ((int) (value >> 40) & 0xFF);
+ buffer[position++] = (byte) ((int) (value >> 48) & 0xFF);
+ buffer[position++] = (byte) ((int) (value >> 56) & 0xFF);
+ totalBytesWritten += FIXED_64_SIZE;
+ }
+ }
+
+ /**
+ * A {@link CodedOutputStream} that decorates a {@link ByteOutput}. It internal buffer only to
+ * support string encoding operations. All other writes are just passed through to the
+ * {@link ByteOutput}.
+ */
+ private static final class ByteOutputEncoder extends AbstractBufferedEncoder {
+ private final ByteOutput out;
+
+ ByteOutputEncoder(ByteOutput out, int bufferSize) {
+ super(bufferSize);
+ if (out == null) {
+ throw new NullPointerException("out");
+ }
+ this.out = out;
+ }
+
+ @Override
+ public void writeTag(final int fieldNumber, final int wireType) throws IOException {
+ writeUInt32NoTag(WireFormat.makeTag(fieldNumber, wireType));
+ }
+
+ @Override
+ public void writeInt32(final int fieldNumber, final int value) throws IOException {
+ flushIfNotAvailable(MAX_VARINT_SIZE * 2);
+ bufferTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ bufferInt32NoTag(value);
+ }
+
+ @Override
+ public void writeUInt32(final int fieldNumber, final int value) throws IOException {
+ flushIfNotAvailable(MAX_VARINT_SIZE * 2);
+ bufferTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ bufferUInt32NoTag(value);
+ }
+
+ @Override
+ public void writeFixed32(final int fieldNumber, final int value) throws IOException {
+ flushIfNotAvailable(MAX_VARINT_SIZE + FIXED_32_SIZE);
+ bufferTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
+ bufferFixed32NoTag(value);
+ }
+
+ @Override
+ public void writeUInt64(final int fieldNumber, final long value) throws IOException {
+ flushIfNotAvailable(MAX_VARINT_SIZE * 2);
+ bufferTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ bufferUInt64NoTag(value);
+ }
+
+ @Override
+ public void writeFixed64(final int fieldNumber, final long value) throws IOException {
+ flushIfNotAvailable(MAX_VARINT_SIZE + FIXED_64_SIZE);
+ bufferTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
+ bufferFixed64NoTag(value);
+ }
+
+ @Override
+ public void writeBool(final int fieldNumber, final boolean value) throws IOException {
+ flushIfNotAvailable(MAX_VARINT_SIZE + 1);
+ bufferTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ buffer((byte) (value ? 1 : 0));
+ }
+
+ @Override
+ public void writeString(final int fieldNumber, final String value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ writeStringNoTag(value);
+ }
+
+ @Override
+ public void writeBytes(final int fieldNumber, final ByteString value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ writeBytesNoTag(value);
+ }
+
+ @Override
+ public void writeByteArray(final int fieldNumber, final byte[] value) throws IOException {
+ writeByteArray(fieldNumber, value, 0, value.length);
+ }
+
+ @Override
+ public void writeByteArray(
+ final int fieldNumber, final byte[] value, final int offset, final int length)
+ throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ writeByteArrayNoTag(value, offset, length);
+ }
+
+ @Override
+ public void writeByteBuffer(final int fieldNumber, final ByteBuffer value)
+ throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ writeUInt32NoTag(value.capacity());
+ writeRawBytes(value);
+ }
+
+ @Override
+ public void writeBytesNoTag(final ByteString value) throws IOException {
+ writeUInt32NoTag(value.size());
+ value.writeTo(this);
+ }
+
+ @Override
+ public void writeByteArrayNoTag(final byte[] value, int offset, int length) throws IOException {
+ writeUInt32NoTag(length);
+ write(value, offset, length);
+ }
+
+ @Override
+ public void writeRawBytes(final ByteBuffer value) throws IOException {
+ if (value.hasArray()) {
+ write(value.array(), value.arrayOffset(), value.capacity());
+ } else {
+ ByteBuffer duplicated = value.duplicate();
+ duplicated.clear();
+ write(duplicated);
+ }
+ }
+
+ @Override
+ public void writeMessage(final int fieldNumber, final MessageLite value)
+ throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ writeMessageNoTag(value);
+ }
+
+ @Override
+ public void writeMessageSetExtension(final int fieldNumber, final MessageLite value)
+ throws IOException {
+ writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP);
+ writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber);
+ writeMessage(WireFormat.MESSAGE_SET_MESSAGE, value);
+ writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP);
+ }
+
+ @Override
+ public void writeRawMessageSetExtension(final int fieldNumber, final ByteString value)
+ throws IOException {
+ writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP);
+ writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber);
+ writeBytes(WireFormat.MESSAGE_SET_MESSAGE, value);
+ writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP);
+ }
+
+ @Override
+ public void writeMessageNoTag(final MessageLite value) throws IOException {
+ writeUInt32NoTag(value.getSerializedSize());
+ value.writeTo(this);
+ }
+
+ @Override
+ public void write(byte value) throws IOException {
+ if (position == limit) {
+ doFlush();
+ }
+
+ buffer(value);
+ }
+
+ @Override
+ public void writeInt32NoTag(int value) throws IOException {
+ if (value >= 0) {
+ writeUInt32NoTag(value);
+ } else {
+ // Must sign-extend.
+ writeUInt64NoTag(value);
+ }
+ }
+
+ @Override
+ public void writeUInt32NoTag(int value) throws IOException {
+ flushIfNotAvailable(MAX_VARINT_SIZE);
+ bufferUInt32NoTag(value);
+ }
+
+ @Override
+ public void writeFixed32NoTag(final int value) throws IOException {
+ flushIfNotAvailable(FIXED_32_SIZE);
+ bufferFixed32NoTag(value);
+ }
+
+ @Override
+ public void writeUInt64NoTag(long value) throws IOException {
+ flushIfNotAvailable(MAX_VARINT_SIZE);
+ bufferUInt64NoTag(value);
+ }
+
+ @Override
+ public void writeFixed64NoTag(final long value) throws IOException {
+ flushIfNotAvailable(FIXED_64_SIZE);
+ bufferFixed64NoTag(value);
+ }
+
+ @Override
+ public void writeStringNoTag(String value) throws IOException {
+ // UTF-8 byte length of the string is at least its UTF-16 code unit length (value.length()),
+ // and at most 3 times of it. We take advantage of this in both branches below.
+ final int maxLength = value.length() * Utf8.MAX_BYTES_PER_CHAR;
+ final int maxLengthVarIntSize = computeUInt32SizeNoTag(maxLength);
+
+ // If we are streaming and the potential length is too big to fit in our buffer, we take the
+ // slower path.
+ if (maxLengthVarIntSize + maxLength > limit) {
+ // Allocate a byte[] that we know can fit the string and encode into it. String.getBytes()
+ // does the same internally and then does *another copy* to return a byte[] of exactly the
+ // right size. We can skip that copy and just writeRawBytes up to the actualLength of the
+ // UTF-8 encoded bytes.
+ final byte[] encodedBytes = new byte[maxLength];
+ int actualLength = Utf8.encode(value, encodedBytes, 0, maxLength);
+ writeUInt32NoTag(actualLength);
+ writeLazy(encodedBytes, 0, actualLength);
+ return;
+ }
+
+ // Fast path: we have enough space available in our buffer for the string...
+ if (maxLengthVarIntSize + maxLength > limit - position) {
+ // Flush to free up space.
+ doFlush();
+ }
+
+ final int oldPosition = position;
+ try {
+ // Optimize for the case where we know this length results in a constant varint length as
+ // this saves a pass for measuring the length of the string.
+ final int minLengthVarIntSize = computeUInt32SizeNoTag(value.length());
+
+ if (minLengthVarIntSize == maxLengthVarIntSize) {
+ position = oldPosition + minLengthVarIntSize;
+ int newPosition = Utf8.encode(value, buffer, position, limit - position);
+ // Since this class is stateful and tracks the position, we rewind and store the state,
+ // prepend the length, then reset it back to the end of the string.
+ position = oldPosition;
+ int length = newPosition - oldPosition - minLengthVarIntSize;
+ bufferUInt32NoTag(length);
+ position = newPosition;
+ totalBytesWritten += length;
+ } else {
+ int length = Utf8.encodedLength(value);
+ bufferUInt32NoTag(length);
+ position = Utf8.encode(value, buffer, position, length);
+ totalBytesWritten += length;
+ }
+ } catch (UnpairedSurrogateException e) {
+ // Roll back the change and convert to an IOException.
+ totalBytesWritten -= position - oldPosition;
+ position = oldPosition;
+
+ // TODO(nathanmittler): We should throw an IOException here instead.
+ inefficientWriteStringNoTag(value, e);
+ } catch (IndexOutOfBoundsException e) {
+ throw new OutOfSpaceException(e);
+ }
+ }
+
+ @Override
+ public void flush() throws IOException {
+ if (position > 0) {
+ // Flush the buffer.
+ doFlush();
+ }
+ }
+
+ @Override
+ public void write(byte[] value, int offset, int length) throws IOException {
+ flush();
+ out.write(value, offset, length);
+ totalBytesWritten += length;
+ }
+
+ @Override
+ public void writeLazy(byte[] value, int offset, int length) throws IOException {
+ flush();
+ out.writeLazy(value, offset, length);
+ totalBytesWritten += length;
+ }
+
+ @Override
+ public void write(ByteBuffer value) throws IOException {
+ flush();
+ int length = value.remaining();
+ out.write(value);
+ totalBytesWritten += length;
+ }
+
+ @Override
+ public void writeLazy(ByteBuffer value) throws IOException {
+ flush();
+ int length = value.remaining();
+ out.writeLazy(value);
+ totalBytesWritten += length;
+ }
+
+ private void flushIfNotAvailable(int requiredSize) throws IOException {
+ if (limit - position < requiredSize) {
+ doFlush();
+ }
+ }
+
+ private void doFlush() throws IOException {
+ out.write(buffer, 0, position);
+ position = 0;
+ }
+ }
+
+ /**
+ * An {@link CodedOutputStream} that decorates an {@link OutputStream}. It performs internal
+ * buffering to optimize writes to the {@link OutputStream}.
+ */
+ private static final class OutputStreamEncoder extends AbstractBufferedEncoder {
+ private final OutputStream out;
+
+ OutputStreamEncoder(OutputStream out, int bufferSize) {
+ super(bufferSize);
+ if (out == null) {
+ throw new NullPointerException("out");
+ }
+ this.out = out;
+ }
+
+ @Override
+ public void writeTag(final int fieldNumber, final int wireType) throws IOException {
+ writeUInt32NoTag(WireFormat.makeTag(fieldNumber, wireType));
+ }
+
+ @Override
+ public void writeInt32(final int fieldNumber, final int value) throws IOException {
+ flushIfNotAvailable(MAX_VARINT_SIZE * 2);
+ bufferTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ bufferInt32NoTag(value);
+ }
+
+ @Override
+ public void writeUInt32(final int fieldNumber, final int value) throws IOException {
+ flushIfNotAvailable(MAX_VARINT_SIZE * 2);
+ bufferTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ bufferUInt32NoTag(value);
+ }
+
+ @Override
+ public void writeFixed32(final int fieldNumber, final int value) throws IOException {
+ flushIfNotAvailable(MAX_VARINT_SIZE + FIXED_32_SIZE);
+ bufferTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
+ bufferFixed32NoTag(value);
+ }
+
+ @Override
+ public void writeUInt64(final int fieldNumber, final long value) throws IOException {
+ flushIfNotAvailable(MAX_VARINT_SIZE * 2);
+ bufferTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ bufferUInt64NoTag(value);
+ }
+
+ @Override
+ public void writeFixed64(final int fieldNumber, final long value) throws IOException {
+ flushIfNotAvailable(MAX_VARINT_SIZE + FIXED_64_SIZE);
+ bufferTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
+ bufferFixed64NoTag(value);
+ }
+
+ @Override
+ public void writeBool(final int fieldNumber, final boolean value) throws IOException {
+ flushIfNotAvailable(MAX_VARINT_SIZE + 1);
+ bufferTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ buffer((byte) (value ? 1 : 0));
+ }
+
+ @Override
+ public void writeString(final int fieldNumber, final String value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ writeStringNoTag(value);
+ }
+
+ @Override
+ public void writeBytes(final int fieldNumber, final ByteString value) throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ writeBytesNoTag(value);
+ }
+
+ @Override
+ public void writeByteArray(final int fieldNumber, final byte[] value) throws IOException {
+ writeByteArray(fieldNumber, value, 0, value.length);
+ }
+
+ @Override
+ public void writeByteArray(
+ final int fieldNumber, final byte[] value, final int offset, final int length)
+ throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ writeByteArrayNoTag(value, offset, length);
+ }
+
+ @Override
+ public void writeByteBuffer(final int fieldNumber, final ByteBuffer value)
+ throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ writeUInt32NoTag(value.capacity());
+ writeRawBytes(value);
+ }
+
+ @Override
+ public void writeBytesNoTag(final ByteString value) throws IOException {
+ writeUInt32NoTag(value.size());
+ value.writeTo(this);
+ }
+
+ @Override
+ public void writeByteArrayNoTag(final byte[] value, int offset, int length) throws IOException {
+ writeUInt32NoTag(length);
+ write(value, offset, length);
+ }
+
+ @Override
+ public void writeRawBytes(final ByteBuffer value) throws IOException {
+ if (value.hasArray()) {
+ write(value.array(), value.arrayOffset(), value.capacity());
+ } else {
+ ByteBuffer duplicated = value.duplicate();
+ duplicated.clear();
+ write(duplicated);
+ }
+ }
+
+ @Override
+ public void writeMessage(final int fieldNumber, final MessageLite value)
+ throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ writeMessageNoTag(value);
+ }
+
+ @Override
+ public void writeMessageSetExtension(final int fieldNumber, final MessageLite value)
+ throws IOException {
+ writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP);
+ writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber);
+ writeMessage(WireFormat.MESSAGE_SET_MESSAGE, value);
+ writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP);
+ }
+
+ @Override
+ public void writeRawMessageSetExtension(final int fieldNumber, final ByteString value)
+ throws IOException {
+ writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP);
+ writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber);
+ writeBytes(WireFormat.MESSAGE_SET_MESSAGE, value);
+ writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP);
+ }
+
+ @Override
+ public void writeMessageNoTag(final MessageLite value) throws IOException {
+ writeUInt32NoTag(value.getSerializedSize());
+ value.writeTo(this);
+ }
+
+ @Override
+ public void write(byte value) throws IOException {
+ if (position == limit) {
+ doFlush();
+ }
+
+ buffer(value);
+ }
+
+ @Override
+ public void writeInt32NoTag(int value) throws IOException {
+ if (value >= 0) {
+ writeUInt32NoTag(value);
+ } else {
+ // Must sign-extend.
+ writeUInt64NoTag(value);
+ }
+ }
+
+ @Override
+ public void writeUInt32NoTag(int value) throws IOException {
+ flushIfNotAvailable(MAX_VARINT_SIZE);
+ bufferUInt32NoTag(value);
+ }
+
+ @Override
+ public void writeFixed32NoTag(final int value) throws IOException {
+ flushIfNotAvailable(FIXED_32_SIZE);
+ bufferFixed32NoTag(value);
+ }
+
+ @Override
+ public void writeUInt64NoTag(long value) throws IOException {
+ flushIfNotAvailable(MAX_VARINT_SIZE);
+ bufferUInt64NoTag(value);
+ }
+
+ @Override
+ public void writeFixed64NoTag(final long value) throws IOException {
+ flushIfNotAvailable(FIXED_64_SIZE);
+ bufferFixed64NoTag(value);
+ }
+
+ @Override
+ public void writeStringNoTag(String value) throws IOException {
+ try {
+ // UTF-8 byte length of the string is at least its UTF-16 code unit length (value.length()),
+ // and at most 3 times of it. We take advantage of this in both branches below.
+ final int maxLength = value.length() * Utf8.MAX_BYTES_PER_CHAR;
+ final int maxLengthVarIntSize = computeUInt32SizeNoTag(maxLength);
+
+ // If we are streaming and the potential length is too big to fit in our buffer, we take the
+ // slower path.
+ if (maxLengthVarIntSize + maxLength > limit) {
+ // Allocate a byte[] that we know can fit the string and encode into it. String.getBytes()
+ // does the same internally and then does *another copy* to return a byte[] of exactly the
+ // right size. We can skip that copy and just writeRawBytes up to the actualLength of the
+ // UTF-8 encoded bytes.
+ final byte[] encodedBytes = new byte[maxLength];
+ int actualLength = Utf8.encode(value, encodedBytes, 0, maxLength);
+ writeUInt32NoTag(actualLength);
+ writeLazy(encodedBytes, 0, actualLength);
+ return;
+ }
+
+ // Fast path: we have enough space available in our buffer for the string...
+ if (maxLengthVarIntSize + maxLength > limit - position) {
+ // Flush to free up space.
+ doFlush();
+ }
+
+ // Optimize for the case where we know this length results in a constant varint length as
+ // this saves a pass for measuring the length of the string.
+ final int minLengthVarIntSize = computeUInt32SizeNoTag(value.length());
+ int oldPosition = position;
+ final int length;
+ try {
+ if (minLengthVarIntSize == maxLengthVarIntSize) {
+ position = oldPosition + minLengthVarIntSize;
+ int newPosition = Utf8.encode(value, buffer, position, limit - position);
+ // Since this class is stateful and tracks the position, we rewind and store the
+ // state, prepend the length, then reset it back to the end of the string.
+ position = oldPosition;
+ length = newPosition - oldPosition - minLengthVarIntSize;
+ bufferUInt32NoTag(length);
+ position = newPosition;
+ } else {
+ length = Utf8.encodedLength(value);
+ bufferUInt32NoTag(length);
+ position = Utf8.encode(value, buffer, position, length);
+ }
+ totalBytesWritten += length;
+ } catch (UnpairedSurrogateException e) {
+ // Be extra careful and restore the original position for retrying the write with the
+ // less efficient path.
+ totalBytesWritten -= position - oldPosition;
+ position = oldPosition;
+ throw e;
+ } catch (ArrayIndexOutOfBoundsException e) {
+ throw new OutOfSpaceException(e);
+ }
+ } catch (UnpairedSurrogateException e) {
+ inefficientWriteStringNoTag(value, e);
+ }
+ }
+
+ @Override
+ public void flush() throws IOException {
+ if (position > 0) {
+ // Flush the buffer.
+ doFlush();
+ }
+ }
+
+ @Override
+ public void write(byte[] value, int offset, int length)
+ throws IOException {
+ if (limit - position >= length) {
+ // We have room in the current buffer.
+ System.arraycopy(value, offset, buffer, position, length);
+ position += length;
+ totalBytesWritten += length;
+ } else {
+ // Write extends past current buffer. Fill the rest of this buffer and
+ // flush.
+ final int bytesWritten = limit - position;
+ System.arraycopy(value, offset, buffer, position, bytesWritten);
+ offset += bytesWritten;
+ length -= bytesWritten;
+ position = limit;
+ totalBytesWritten += bytesWritten;
+ doFlush();
+
+ // Now deal with the rest.
+ // Since we have an output stream, this is our buffer
+ // and buffer offset == 0
+ if (length <= limit) {
+ // Fits in new buffer.
+ System.arraycopy(value, offset, buffer, 0, length);
+ position = length;
+ } else {
+ // Write is very big. Let's do it all at once.
+ out.write(value, offset, length);
+ }
+ totalBytesWritten += length;
+ }
+ }
+
+ @Override
+ public void writeLazy(byte[] value, int offset, int length) throws IOException {
+ write(value, offset, length);
+ }
+
+ @Override
+ public void write(ByteBuffer value) throws IOException {
+ int length = value.remaining();
+ if (limit - position >= length) {
+ // We have room in the current buffer.
+ value.get(buffer, position, length);
+ position += length;
+ totalBytesWritten += length;
+ } else {
+ // Write extends past current buffer. Fill the rest of this buffer and
+ // flush.
+ final int bytesWritten = limit - position;
+ value.get(buffer, position, bytesWritten);
+ length -= bytesWritten;
+ position = limit;
+ totalBytesWritten += bytesWritten;
+ doFlush();
+
+ // Now deal with the rest.
+ // Since we have an output stream, this is our buffer
+ // and buffer offset == 0
+ while (length > limit) {
+ // Copy data into the buffer before writing it to OutputStream.
+ value.get(buffer, 0, limit);
+ out.write(buffer, 0, limit);
+ length -= limit;
+ totalBytesWritten += limit;
+ }
+ value.get(buffer, 0, length);
+ position = length;
+ totalBytesWritten += length;
+ }
+ }
+
+ @Override
+ public void writeLazy(ByteBuffer value) throws IOException {
+ write(value);
+ }
+
+ private void flushIfNotAvailable(int requiredSize) throws IOException {
+ if (limit - position < requiredSize) {
+ doFlush();
+ }
+ }
+
+ private void doFlush() throws IOException {
+ out.write(buffer, 0, position);
+ position = 0;
+ }
+ }
+}
diff --git a/java/src/main/java/com/google/protobuf/Descriptors.java b/java/core/src/main/java/com/google/protobuf/Descriptors.java
index 7cfc47f7..1c34c24f 100644
--- a/java/src/main/java/com/google/protobuf/Descriptors.java
+++ b/java/core/src/main/java/com/google/protobuf/Descriptors.java
@@ -74,16 +74,28 @@ public final class Descriptors {
*/
public static final class FileDescriptor extends GenericDescriptor {
/** Convert the descriptor to its protocol message representation. */
- public FileDescriptorProto toProto() { return proto; }
+ @Override
+ public FileDescriptorProto toProto() {
+ return proto;
+ }
/** Get the file name. */
- public String getName() { return proto.getName(); }
+ @Override
+ public String getName() {
+ return proto.getName();
+ }
/** Returns this object. */
- public FileDescriptor getFile() { return this; }
+ @Override
+ public FileDescriptor getFile() {
+ return this;
+ }
/** Returns the same as getName(). */
- public String getFullName() { return proto.getName(); }
+ @Override
+ public String getFullName() {
+ return proto.getName();
+ }
/**
* Get the proto package name. This is the package name given by the
@@ -272,7 +284,7 @@ public final class Descriptors {
* because a field has an undefined type or because two messages
* were defined with the same name.
*/
- private static FileDescriptor buildFrom(
+ public static FileDescriptor buildFrom(
final FileDescriptorProto proto, final FileDescriptor[] dependencies,
final boolean allowUnknownDependencies)
throws DescriptorValidationException {
@@ -582,10 +594,16 @@ public final class Descriptors {
public int getIndex() { return index; }
/** Convert the descriptor to its protocol message representation. */
- public DescriptorProto toProto() { return proto; }
+ @Override
+ public DescriptorProto toProto() {
+ return proto;
+ }
/** Get the type's unqualified name. */
- public String getName() { return proto.getName(); }
+ @Override
+ public String getName() {
+ return proto.getName();
+ }
/**
* Get the type's fully-qualified name, within the proto language's
@@ -598,10 +616,16 @@ public final class Descriptors {
* </pre>
* {@code Baz}'s full name is "foo.bar.Baz".
*/
- public String getFullName() { return fullName; }
+ @Override
+ public String getFullName() {
+ return fullName;
+ }
/** Get the {@link FileDescriptor} containing this descriptor. */
- public FileDescriptor getFile() { return file; }
+ @Override
+ public FileDescriptor getFile() {
+ return file;
+ }
/** If this is a nested type, get the outer descriptor, otherwise null. */
public Descriptor getContainingType() { return containingType; }
@@ -847,6 +871,10 @@ public final class Descriptors {
nestedTypes[i].setProto(proto.getNestedType(i));
}
+ for (int i = 0; i < oneofs.length; i++) {
+ oneofs[i].setProto(proto.getOneofDecl(i));
+ }
+
for (int i = 0; i < enumTypes.length; i++) {
enumTypes[i].setProto(proto.getEnumType(i));
}
@@ -875,19 +903,36 @@ public final class Descriptors {
public int getIndex() { return index; }
/** Convert the descriptor to its protocol message representation. */
- public FieldDescriptorProto toProto() { return proto; }
+ @Override
+ public FieldDescriptorProto toProto() {
+ return proto;
+ }
/** Get the field's unqualified name. */
- public String getName() { return proto.getName(); }
+ @Override
+ public String getName() {
+ return proto.getName();
+ }
/** Get the field's number. */
- public int getNumber() { return proto.getNumber(); }
+ @Override
+ public int getNumber() {
+ return proto.getNumber();
+ }
/**
* Get the field's fully-qualified name.
* @see Descriptors.Descriptor#getFullName()
*/
- public String getFullName() { return fullName; }
+ @Override
+ public String getFullName() {
+ return fullName;
+ }
+
+ /** Get the JSON name of this field. */
+ public String getJsonName() {
+ return jsonName;
+ }
/**
* Get the field's java type. This is just for convenience. Every
@@ -896,17 +941,22 @@ public final class Descriptors {
public JavaType getJavaType() { return type.getJavaType(); }
/** For internal use only. */
+ @Override
public WireFormat.JavaType getLiteJavaType() {
return getLiteType().getJavaType();
}
/** Get the {@code FileDescriptor} containing this descriptor. */
- public FileDescriptor getFile() { return file; }
+ @Override
+ public FileDescriptor getFile() {
+ return file;
+ }
/** Get the field's declared type. */
public Type getType() { return type; }
/** For internal use only. */
+ @Override
public WireFormat.FieldType getLiteType() {
return table[type.ordinal()];
}
@@ -948,6 +998,7 @@ public final class Descriptors {
}
/** Is this field declared repeated? */
+ @Override
public boolean isRepeated() {
return proto.getLabel() == FieldDescriptorProto.Label.LABEL_REPEATED;
}
@@ -955,6 +1006,7 @@ public final class Descriptors {
/** Does this field have the {@code [packed = true]} option or is this field
* packable in proto3 and not explicitly setted to unpacked?
*/
+ @Override
public boolean isPacked() {
if (!isPackable()) {
return false;
@@ -1043,6 +1095,7 @@ public final class Descriptors {
}
/** For enum fields, gets the field's type. */
+ @Override
public EnumDescriptor getEnumType() {
if (getJavaType() != JavaType.ENUM) {
throw new UnsupportedOperationException(
@@ -1061,6 +1114,7 @@ public final class Descriptors {
* @return negative, zero, or positive if {@code this} is less than,
* equal to, or greater than {@code other}, respectively.
*/
+ @Override
public int compareTo(final FieldDescriptor other) {
if (other.containingType != containingType) {
throw new IllegalArgumentException(
@@ -1079,6 +1133,7 @@ public final class Descriptors {
private FieldDescriptorProto proto;
private final String fullName;
+ private final String jsonName;
private final FileDescriptor file;
private final Descriptor extensionScope;
@@ -1117,7 +1172,7 @@ public final class Descriptors {
private JavaType javaType;
public FieldDescriptorProto.Type toProto() {
- return FieldDescriptorProto.Type.valueOf(ordinal() + 1);
+ return FieldDescriptorProto.Type.forNumber(ordinal() + 1);
}
public JavaType getJavaType() { return javaType; }
@@ -1157,6 +1212,38 @@ public final class Descriptors {
private final Object defaultDefault;
}
+ // TODO(xiaofeng): Implement it consistently across different languages. See b/24751348.
+ private static String fieldNameToLowerCamelCase(String name) {
+ StringBuilder result = new StringBuilder(name.length());
+ boolean isNextUpperCase = false;
+ for (int i = 0; i < name.length(); i++) {
+ Character ch = name.charAt(i);
+ if (Character.isLowerCase(ch)) {
+ if (isNextUpperCase) {
+ result.append(Character.toUpperCase(ch));
+ } else {
+ result.append(ch);
+ }
+ isNextUpperCase = false;
+ } else if (Character.isUpperCase(ch)) {
+ if (i == 0) {
+ // Force first letter to lower-case.
+ result.append(Character.toLowerCase(ch));
+ } else {
+ // Capital letters after the first are left as-is.
+ result.append(ch);
+ }
+ isNextUpperCase = false;
+ } else if (Character.isDigit(ch)) {
+ result.append(ch);
+ isNextUpperCase = false;
+ } else {
+ isNextUpperCase = true;
+ }
+ }
+ return result.toString();
+ }
+
private FieldDescriptor(final FieldDescriptorProto proto,
final FileDescriptor file,
final Descriptor parent,
@@ -1167,6 +1254,11 @@ public final class Descriptors {
this.proto = proto;
fullName = computeFullName(file, parent, proto.getName());
this.file = file;
+ if (proto.hasJsonName()) {
+ jsonName = proto.getJsonName();
+ } else {
+ jsonName = fieldNameToLowerCamelCase(proto.getName());
+ }
if (proto.hasType()) {
type = Type.valueOf(proto.getType());
@@ -1423,8 +1515,8 @@ public final class Descriptors {
* For internal use only. This is to satisfy the FieldDescriptorLite
* interface.
*/
- public MessageLite.Builder internalMergeFrom(
- MessageLite.Builder to, MessageLite from) {
+ @Override
+ public MessageLite.Builder internalMergeFrom(MessageLite.Builder to, MessageLite from) {
// FieldDescriptors are only used with non-lite messages so we can just
// down-cast and call mergeFrom directly.
return ((Message.Builder) to).mergeFrom((Message) from);
@@ -1444,19 +1536,31 @@ public final class Descriptors {
public int getIndex() { return index; }
/** Convert the descriptor to its protocol message representation. */
- public EnumDescriptorProto toProto() { return proto; }
+ @Override
+ public EnumDescriptorProto toProto() {
+ return proto;
+ }
/** Get the type's unqualified name. */
- public String getName() { return proto.getName(); }
+ @Override
+ public String getName() {
+ return proto.getName();
+ }
/**
* Get the type's fully-qualified name.
* @see Descriptors.Descriptor#getFullName()
*/
- public String getFullName() { return fullName; }
+ @Override
+ public String getFullName() {
+ return fullName;
+ }
/** Get the {@link FileDescriptor} containing this descriptor. */
- public FileDescriptor getFile() { return file; }
+ @Override
+ public FileDescriptor getFile() {
+ return file;
+ }
/** If this is a nested type, get the outer descriptor, otherwise null. */
public Descriptor getContainingType() { return containingType; }
@@ -1490,6 +1594,7 @@ public final class Descriptors {
* @param number The value's number.
* @return the value's descriptor, or {@code null} if not found.
*/
+ @Override
public EnumValueDescriptor findValueByNumber(final int number) {
return file.pool.enumValuesByNumber.get(
new DescriptorPool.DescriptorIntPair(this, number));
@@ -1616,13 +1721,22 @@ public final class Descriptors {
public int getIndex() { return index; }
/** Convert the descriptor to its protocol message representation. */
- public EnumValueDescriptorProto toProto() { return proto; }
+ @Override
+ public EnumValueDescriptorProto toProto() {
+ return proto;
+ }
/** Get the value's unqualified name. */
- public String getName() { return proto.getName(); }
+ @Override
+ public String getName() {
+ return proto.getName();
+ }
/** Get the value's number. */
- public int getNumber() { return proto.getNumber(); }
+ @Override
+ public int getNumber() {
+ return proto.getNumber();
+ }
@Override
public String toString() { return proto.getName(); }
@@ -1631,10 +1745,16 @@ public final class Descriptors {
* Get the value's fully-qualified name.
* @see Descriptors.Descriptor#getFullName()
*/
- public String getFullName() { return fullName; }
+ @Override
+ public String getFullName() {
+ return fullName;
+ }
/** Get the {@link FileDescriptor} containing this descriptor. */
- public FileDescriptor getFile() { return file; }
+ @Override
+ public FileDescriptor getFile() {
+ return file;
+ }
/** Get the value's enum type. */
public EnumDescriptor getType() { return type; }
@@ -1702,19 +1822,31 @@ public final class Descriptors {
public int getIndex() { return index; }
/** Convert the descriptor to its protocol message representation. */
- public ServiceDescriptorProto toProto() { return proto; }
+ @Override
+ public ServiceDescriptorProto toProto() {
+ return proto;
+ }
/** Get the type's unqualified name. */
- public String getName() { return proto.getName(); }
+ @Override
+ public String getName() {
+ return proto.getName();
+ }
/**
* Get the type's fully-qualified name.
* @see Descriptors.Descriptor#getFullName()
*/
- public String getFullName() { return fullName; }
+ @Override
+ public String getFullName() {
+ return fullName;
+ }
/** Get the {@link FileDescriptor} containing this descriptor. */
- public FileDescriptor getFile() { return file; }
+ @Override
+ public FileDescriptor getFile() {
+ return file;
+ }
/** Get the {@code ServiceOptions}, defined in {@code descriptor.proto}. */
public ServiceOptions getOptions() { return proto.getOptions(); }
@@ -1792,19 +1924,31 @@ public final class Descriptors {
public int getIndex() { return index; }
/** Convert the descriptor to its protocol message representation. */
- public MethodDescriptorProto toProto() { return proto; }
+ @Override
+ public MethodDescriptorProto toProto() {
+ return proto;
+ }
/** Get the method's unqualified name. */
- public String getName() { return proto.getName(); }
+ @Override
+ public String getName() {
+ return proto.getName();
+ }
/**
* Get the method's fully-qualified name.
* @see Descriptors.Descriptor#getFullName()
*/
- public String getFullName() { return fullName; }
+ @Override
+ public String getFullName() {
+ return fullName;
+ }
/** Get the {@link FileDescriptor} containing this descriptor. */
- public FileDescriptor getFile() { return file; }
+ @Override
+ public FileDescriptor getFile() {
+ return file;
+ }
/** Get the method's service type. */
public ServiceDescriptor getService() { return service; }
@@ -2205,10 +2349,22 @@ public final class Descriptors {
* that has the same name as an existing package.
*/
private static final class PackageDescriptor extends GenericDescriptor {
- public Message toProto() { return file.toProto(); }
- public String getName() { return name; }
- public String getFullName() { return fullName; }
- public FileDescriptor getFile() { return file; }
+ @Override
+ public Message toProto() {
+ return file.toProto();
+ }
+ @Override
+ public String getName() {
+ return name;
+ }
+ @Override
+ public String getFullName() {
+ return fullName;
+ }
+ @Override
+ public FileDescriptor getFile() {
+ return file;
+ }
PackageDescriptor(final String name, final String fullName,
final FileDescriptor file) {
@@ -2361,6 +2517,10 @@ public final class Descriptors {
public int getFieldCount() { return fieldCount; }
+ public OneofOptions getOptions() {
+ return proto.getOptions();
+ }
+
/** Get a list of this message type's fields. */
public List<FieldDescriptor> getFields() {
return Collections.unmodifiableList(Arrays.asList(fields));
@@ -2370,6 +2530,10 @@ public final class Descriptors {
return fields[index];
}
+ private void setProto(final OneofDescriptorProto proto) {
+ this.proto = proto;
+ }
+
private OneofDescriptor(final OneofDescriptorProto proto,
final FileDescriptor file,
final Descriptor parent,
diff --git a/java/src/main/java/com/google/protobuf/DoubleArrayList.java b/java/core/src/main/java/com/google/protobuf/DoubleArrayList.java
index 90ebe109..6177f3ca 100644
--- a/java/src/main/java/com/google/protobuf/DoubleArrayList.java
+++ b/java/core/src/main/java/com/google/protobuf/DoubleArrayList.java
@@ -34,33 +34,31 @@ import com.google.protobuf.Internal.DoubleList;
import java.util.Arrays;
import java.util.Collection;
-import java.util.List;
import java.util.RandomAccess;
/**
* An implementation of {@link DoubleList} on top of a primitive array.
- *
+ *
* @author dweis@google.com (Daniel Weis)
*/
final class DoubleArrayList
- extends AbstractProtobufList<Double> implements DoubleList, RandomAccess {
-
- private static final int DEFAULT_CAPACITY = 10;
-
+ extends AbstractProtobufList<Double>
+ implements DoubleList, RandomAccess {
+
private static final DoubleArrayList EMPTY_LIST = new DoubleArrayList();
static {
EMPTY_LIST.makeImmutable();
}
-
+
public static DoubleArrayList emptyList() {
return EMPTY_LIST;
}
-
+
/**
* The backing store for the list.
*/
private double[] array;
-
+
/**
* The size of the list distinct from the length of the array. That is, it is the number of
* elements set in the list.
@@ -68,30 +66,62 @@ final class DoubleArrayList
private int size;
/**
- * Constructs a new mutable {@code DoubleArrayList}.
+ * Constructs a new mutable {@code DoubleArrayList} with default capacity.
*/
DoubleArrayList() {
- array = new double[DEFAULT_CAPACITY];
- size = 0;
+ this(new double[DEFAULT_CAPACITY], 0);
}
/**
- * Constructs a new mutable {@code DoubleArrayList} containing the same elements as {@code other}.
+ * Constructs a new mutable {@code DoubleArrayList}
+ * containing the same elements as {@code other}.
*/
- DoubleArrayList(List<Double> other) {
- if (other instanceof DoubleArrayList) {
- DoubleArrayList list = (DoubleArrayList) other;
- array = list.array.clone();
- size = list.size;
- } else {
- size = other.size();
- array = new double[size];
- for (int i = 0; i < size; i++) {
- array[i] = other.get(i);
+ private DoubleArrayList(double[] other, int size) {
+ array = other;
+ this.size = size;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof DoubleArrayList)) {
+ return super.equals(o);
+ }
+ DoubleArrayList other = (DoubleArrayList) o;
+ if (size != other.size) {
+ return false;
+ }
+
+ final double[] arr = other.array;
+ for (int i = 0; i < size; i++) {
+ if (array[i] != arr[i]) {
+ return false;
}
}
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = 1;
+ for (int i = 0; i < size; i++) {
+ long bits = Double.doubleToLongBits(array[i]);
+ result = (31 * result) + Internal.hashLong(bits);
+ }
+ return result;
}
-
+
+ @Override
+ public DoubleList mutableCopyWithCapacity(int capacity) {
+ if (capacity < size) {
+ throw new IllegalArgumentException();
+ }
+ return new DoubleArrayList(Arrays.copyOf(array, capacity), size);
+ }
+
@Override
public Double get(int index) {
return getDouble(index);
@@ -143,7 +173,7 @@ final class DoubleArrayList
if (index < 0 || index > size) {
throw new IndexOutOfBoundsException(makeOutOfBoundsExceptionMessage(index));
}
-
+
if (size < array.length) {
// Shift everything over to make room
System.arraycopy(array, index, array, index + 1, size - index);
@@ -151,10 +181,10 @@ final class DoubleArrayList
// Resize to 1.5x the size
int length = ((size * 3) / 2) + 1;
double[] newArray = new double[length];
-
+
// Copy the first part directly
System.arraycopy(array, 0, newArray, 0, index);
-
+
// Copy the rest shifted over by one to make room
System.arraycopy(array, index, newArray, index + 1, size - index);
array = newArray;
@@ -168,38 +198,38 @@ final class DoubleArrayList
@Override
public boolean addAll(Collection<? extends Double> collection) {
ensureIsMutable();
-
+
if (collection == null) {
throw new NullPointerException();
}
-
+
// We specialize when adding another DoubleArrayList to avoid boxing elements.
if (!(collection instanceof DoubleArrayList)) {
return super.addAll(collection);
}
-
+
DoubleArrayList list = (DoubleArrayList) collection;
if (list.size == 0) {
return false;
}
-
+
int overflow = Integer.MAX_VALUE - size;
if (overflow < list.size) {
// We can't actually represent a list this large.
throw new OutOfMemoryError();
}
-
+
int newSize = size + list.size;
if (newSize > array.length) {
array = Arrays.copyOf(array, newSize);
}
-
+
System.arraycopy(list.array, 0, array, size, list.size);
size = newSize;
modCount++;
return true;
}
-
+
@Override
public boolean remove(Object o) {
ensureIsMutable();
@@ -228,7 +258,7 @@ final class DoubleArrayList
/**
* Ensures that the provided {@code index} is within the range of {@code [0, size]}. Throws an
* {@link IndexOutOfBoundsException} if it is not.
- *
+ *
* @param index the index to verify is in range
*/
private void ensureIndexInRange(int index) {
diff --git a/java/src/main/java/com/google/protobuf/DynamicMessage.java b/java/core/src/main/java/com/google/protobuf/DynamicMessage.java
index 3ea1b688..c54da67f 100644
--- a/java/src/main/java/com/google/protobuf/DynamicMessage.java
+++ b/java/core/src/main/java/com/google/protobuf/DynamicMessage.java
@@ -156,18 +156,22 @@ public final class DynamicMessage extends AbstractMessage {
// -----------------------------------------------------------------
// Implementation of Message interface.
+ @Override
public Descriptor getDescriptorForType() {
return type;
}
+ @Override
public DynamicMessage getDefaultInstanceForType() {
return getDefaultInstance(type);
}
+ @Override
public Map<FieldDescriptor, Object> getAllFields() {
return fields.getAllFields();
}
+ @Override
public boolean hasOneof(OneofDescriptor oneof) {
verifyOneofContainingType(oneof);
FieldDescriptor field = oneofCases[oneof.getIndex()];
@@ -177,16 +181,19 @@ public final class DynamicMessage extends AbstractMessage {
return true;
}
+ @Override
public FieldDescriptor getOneofFieldDescriptor(OneofDescriptor oneof) {
verifyOneofContainingType(oneof);
return oneofCases[oneof.getIndex()];
}
+ @Override
public boolean hasField(FieldDescriptor field) {
verifyContainingType(field);
return fields.hasField(field);
}
+ @Override
public Object getField(FieldDescriptor field) {
verifyContainingType(field);
Object result = fields.getField(field);
@@ -202,16 +209,19 @@ public final class DynamicMessage extends AbstractMessage {
return result;
}
+ @Override
public int getRepeatedFieldCount(FieldDescriptor field) {
verifyContainingType(field);
return fields.getRepeatedFieldCount(field);
}
+ @Override
public Object getRepeatedField(FieldDescriptor field, int index) {
verifyContainingType(field);
return fields.getRepeatedField(field, index);
}
+ @Override
public UnknownFieldSet getUnknownFields() {
return unknownFields;
}
@@ -264,19 +274,22 @@ public final class DynamicMessage extends AbstractMessage {
return size;
}
+ @Override
public Builder newBuilderForType() {
return new Builder(type);
}
+ @Override
public Builder toBuilder() {
return newBuilderForType().mergeFrom(this);
}
+ @Override
public Parser<DynamicMessage> getParserForType() {
return new AbstractParser<DynamicMessage>() {
+ @Override
public DynamicMessage parsePartialFrom(
- CodedInputStream input,
- ExtensionRegistryLite extensionRegistry)
+ CodedInputStream input, ExtensionRegistryLite extensionRegistry)
throws InvalidProtocolBufferException {
Builder builder = newBuilder(type);
try {
@@ -370,6 +383,7 @@ public final class DynamicMessage extends AbstractMessage {
}
}
+ @Override
public DynamicMessage build() {
if (!isInitialized()) {
throw newUninitializedMessageException(
@@ -394,6 +408,7 @@ public final class DynamicMessage extends AbstractMessage {
return buildPartial();
}
+ @Override
public DynamicMessage buildPartial() {
fields.makeImmutable();
DynamicMessage result =
@@ -411,22 +426,27 @@ public final class DynamicMessage extends AbstractMessage {
return result;
}
+ @Override
public boolean isInitialized() {
return DynamicMessage.isInitialized(type, fields);
}
+ @Override
public Descriptor getDescriptorForType() {
return type;
}
+ @Override
public DynamicMessage getDefaultInstanceForType() {
return getDefaultInstance(type);
}
+ @Override
public Map<FieldDescriptor, Object> getAllFields() {
return fields.getAllFields();
}
+ @Override
public Builder newBuilderForField(FieldDescriptor field) {
verifyContainingType(field);
@@ -438,6 +458,7 @@ public final class DynamicMessage extends AbstractMessage {
return new Builder(field.getMessageType());
}
+ @Override
public boolean hasOneof(OneofDescriptor oneof) {
verifyOneofContainingType(oneof);
FieldDescriptor field = oneofCases[oneof.getIndex()];
@@ -447,11 +468,13 @@ public final class DynamicMessage extends AbstractMessage {
return true;
}
+ @Override
public FieldDescriptor getOneofFieldDescriptor(OneofDescriptor oneof) {
verifyOneofContainingType(oneof);
return oneofCases[oneof.getIndex()];
}
+ @Override
public Builder clearOneof(OneofDescriptor oneof) {
verifyOneofContainingType(oneof);
FieldDescriptor field = oneofCases[oneof.getIndex()];
@@ -461,11 +484,13 @@ public final class DynamicMessage extends AbstractMessage {
return this;
}
+ @Override
public boolean hasField(FieldDescriptor field) {
verifyContainingType(field);
return fields.hasField(field);
}
+ @Override
public Object getField(FieldDescriptor field) {
verifyContainingType(field);
Object result = fields.getField(field);
@@ -481,6 +506,7 @@ public final class DynamicMessage extends AbstractMessage {
return result;
}
+ @Override
public Builder setField(FieldDescriptor field, Object value) {
verifyContainingType(field);
ensureIsMutable();
@@ -500,11 +526,20 @@ public final class DynamicMessage extends AbstractMessage {
fields.clearField(oldField);
}
oneofCases[index] = field;
+ } else if (field.getFile().getSyntax() == Descriptors.FileDescriptor.Syntax.PROTO3) {
+ if (!field.isRepeated()
+ && field.getJavaType() != FieldDescriptor.JavaType.MESSAGE
+ && value.equals(field.getDefaultValue())) {
+ // In proto3, setting a field to its default value is equivalent to clearing the field.
+ fields.clearField(field);
+ return this;
+ }
}
fields.setField(field, value);
return this;
}
+ @Override
public Builder clearField(FieldDescriptor field) {
verifyContainingType(field);
ensureIsMutable();
@@ -519,24 +554,27 @@ public final class DynamicMessage extends AbstractMessage {
return this;
}
+ @Override
public int getRepeatedFieldCount(FieldDescriptor field) {
verifyContainingType(field);
return fields.getRepeatedFieldCount(field);
}
+ @Override
public Object getRepeatedField(FieldDescriptor field, int index) {
verifyContainingType(field);
return fields.getRepeatedField(field, index);
}
- public Builder setRepeatedField(FieldDescriptor field,
- int index, Object value) {
+ @Override
+ public Builder setRepeatedField(FieldDescriptor field, int index, Object value) {
verifyContainingType(field);
ensureIsMutable();
fields.setRepeatedField(field, index, value);
return this;
}
+ @Override
public Builder addRepeatedField(FieldDescriptor field, Object value) {
verifyContainingType(field);
ensureIsMutable();
@@ -544,10 +582,12 @@ public final class DynamicMessage extends AbstractMessage {
return this;
}
+ @Override
public UnknownFieldSet getUnknownFields() {
return unknownFields;
}
+ @Override
public Builder setUnknownFields(UnknownFieldSet unknownFields) {
if (getDescriptorForType().getFile().getSyntax()
== Descriptors.FileDescriptor.Syntax.PROTO3) {
diff --git a/java/core/src/main/java/com/google/protobuf/ExperimentalApi.java b/java/core/src/main/java/com/google/protobuf/ExperimentalApi.java
new file mode 100644
index 00000000..3cd4c884
--- /dev/null
+++ b/java/core/src/main/java/com/google/protobuf/ExperimentalApi.java
@@ -0,0 +1,66 @@
+// 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.
+
+package com.google.protobuf;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Indicates a public API that can change at any time, and has no guarantee of API stability and
+ * backward-compatibility.
+ *
+ * <p>Usage guidelines:
+ * <ol>
+ * <li>This annotation is used only on public API. Internal interfaces should not use it.</li>
+ * <li>This annotation should only be added to new APIs. Adding it to an existing API is
+ * considered API-breaking.</li>
+ * <li>Removing this annotation from an API gives it stable status.</li>
+ * </ol>
+ */
+@Retention(RetentionPolicy.SOURCE)
+@Target({
+ ElementType.ANNOTATION_TYPE,
+ ElementType.CONSTRUCTOR,
+ ElementType.FIELD,
+ ElementType.METHOD,
+ ElementType.PACKAGE,
+ ElementType.TYPE})
+@Documented
+public @interface ExperimentalApi {
+ /**
+ * Context information such as links to discussion thread, tracking issue etc.
+ */
+ String value() default "";
+}
+
diff --git a/java/src/main/java/com/google/protobuf/Extension.java b/java/core/src/main/java/com/google/protobuf/Extension.java
index 68d29f33..08ec5b45 100644
--- a/java/src/main/java/com/google/protobuf/Extension.java
+++ b/java/core/src/main/java/com/google/protobuf/Extension.java
@@ -42,6 +42,7 @@ public abstract class Extension<ContainingType extends MessageLite, Type>
public abstract Descriptors.FieldDescriptor getDescriptor();
/** Returns whether or not this extension is a Lite Extension. */
+ @Override
final boolean isLite() {
return false;
}
diff --git a/java/src/main/java/com/google/protobuf/ExtensionLite.java b/java/core/src/main/java/com/google/protobuf/ExtensionLite.java
index f8f5bd2c..f8f5bd2c 100644
--- a/java/src/main/java/com/google/protobuf/ExtensionLite.java
+++ b/java/core/src/main/java/com/google/protobuf/ExtensionLite.java
diff --git a/java/src/main/java/com/google/protobuf/ExtensionRegistry.java b/java/core/src/main/java/com/google/protobuf/ExtensionRegistry.java
index 0067392f..1c2e7e6f 100644
--- a/java/src/main/java/com/google/protobuf/ExtensionRegistry.java
+++ b/java/core/src/main/java/com/google/protobuf/ExtensionRegistry.java
@@ -101,7 +101,7 @@ public class ExtensionRegistry extends ExtensionRegistryLite {
/** Get the unmodifiable singleton empty instance. */
public static ExtensionRegistry getEmptyRegistry() {
- return EMPTY;
+ return EMPTY_REGISTRY;
}
@@ -243,6 +243,11 @@ public class ExtensionRegistry extends ExtensionRegistryLite {
add(newExtensionInfo(extension), extension.getExtensionType());
}
+ /** Add an extension from a generated file to the registry. */
+ public void add(final GeneratedMessage.GeneratedExtension<?, ?> extension) {
+ add((Extension<?, ?>) extension);
+ }
+
static ExtensionInfo newExtensionInfo(final Extension<?, ?> extension) {
if (extension.getDescriptor().getJavaType() ==
FieldDescriptor.JavaType.MESSAGE) {
@@ -311,7 +316,7 @@ public class ExtensionRegistry extends ExtensionRegistryLite {
private final Map<DescriptorIntPair, ExtensionInfo> mutableExtensionsByNumber;
ExtensionRegistry(boolean empty) {
- super(ExtensionRegistryLite.getEmptyRegistry());
+ super(EMPTY_REGISTRY_LITE);
this.immutableExtensionsByName =
Collections.<String, ExtensionInfo>emptyMap();
this.mutableExtensionsByName =
@@ -321,7 +326,7 @@ public class ExtensionRegistry extends ExtensionRegistryLite {
this.mutableExtensionsByNumber =
Collections.<DescriptorIntPair, ExtensionInfo>emptyMap();
}
- private static final ExtensionRegistry EMPTY = new ExtensionRegistry(true);
+ static final ExtensionRegistry EMPTY_REGISTRY = new ExtensionRegistry(true);
private void add(
final ExtensionInfo extension,
diff --git a/java/core/src/main/java/com/google/protobuf/ExtensionRegistryFactory.java b/java/core/src/main/java/com/google/protobuf/ExtensionRegistryFactory.java
new file mode 100644
index 00000000..23174e24
--- /dev/null
+++ b/java/core/src/main/java/com/google/protobuf/ExtensionRegistryFactory.java
@@ -0,0 +1,95 @@
+// 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.
+
+package com.google.protobuf;
+
+import static com.google.protobuf.ExtensionRegistryLite.EMPTY_REGISTRY_LITE;
+
+/**
+ * A factory object to create instances of {@link ExtensionRegistryLite}.
+ *
+ * <p>
+ * This factory detects (via reflection) if the full (non-Lite) protocol buffer libraries
+ * are available, and if so, the instances returned are actually {@link ExtensionRegistry}.
+ */
+final class ExtensionRegistryFactory {
+
+ static final String FULL_REGISTRY_CLASS_NAME = "com.google.protobuf.ExtensionRegistry";
+
+ /* Visible for Testing
+ @Nullable */
+ static final Class<?> EXTENSION_REGISTRY_CLASS = reflectExtensionRegistry();
+
+ /* @Nullable */
+ static Class<?> reflectExtensionRegistry() {
+ try {
+ return Class.forName(FULL_REGISTRY_CLASS_NAME);
+ } catch (ClassNotFoundException e) {
+ // The exception allocation is potentially expensive on Android (where it can be triggered
+ // many times at start up). Is there a way to ameliorate this?
+ return null;
+ }
+ }
+
+ /** Construct a new, empty instance. */
+ public static ExtensionRegistryLite create() {
+ if (EXTENSION_REGISTRY_CLASS != null) {
+ try {
+ return invokeSubclassFactory("newInstance");
+ } catch (Exception e) {
+ // return a Lite registry.
+ }
+ }
+ return new ExtensionRegistryLite();
+ }
+
+ /** Get the unmodifiable singleton empty instance. */
+ public static ExtensionRegistryLite createEmpty() {
+ if (EXTENSION_REGISTRY_CLASS != null) {
+ try {
+ return invokeSubclassFactory("getEmptyRegistry");
+ } catch (Exception e) {
+ // return a Lite registry.
+ }
+ }
+ return EMPTY_REGISTRY_LITE;
+ }
+
+ static boolean isFullRegistry(ExtensionRegistryLite registry) {
+ return EXTENSION_REGISTRY_CLASS != null
+ && EXTENSION_REGISTRY_CLASS.isAssignableFrom(registry.getClass());
+ }
+
+ private static final ExtensionRegistryLite invokeSubclassFactory(String methodName)
+ throws Exception {
+ return (ExtensionRegistryLite) EXTENSION_REGISTRY_CLASS
+ .getMethod(methodName).invoke(null);
+ }
+}
diff --git a/java/src/main/java/com/google/protobuf/ExtensionRegistryLite.java b/java/core/src/main/java/com/google/protobuf/ExtensionRegistryLite.java
index 65cf7385..5e4d7739 100644
--- a/java/src/main/java/com/google/protobuf/ExtensionRegistryLite.java
+++ b/java/core/src/main/java/com/google/protobuf/ExtensionRegistryLite.java
@@ -79,6 +79,22 @@ public class ExtensionRegistryLite {
// applications. Need to support this feature on smaller granularity.
private static volatile boolean eagerlyParseMessageSets = false;
+ // Visible for testing.
+ static final String EXTENSION_CLASS_NAME = "com.google.protobuf.Extension";
+
+ /* @Nullable */
+ static Class<?> resolveExtensionClass() {
+ try {
+ return Class.forName(EXTENSION_CLASS_NAME);
+ } catch (ClassNotFoundException e) {
+ // See comment in ExtensionRegistryFactory on the potential expense of this.
+ return null;
+ }
+ }
+
+ /* @Nullable */
+ private static final Class<?> extensionClass = resolveExtensionClass();
+
public static boolean isEagerlyParseMessageSets() {
return eagerlyParseMessageSets;
}
@@ -87,14 +103,22 @@ public class ExtensionRegistryLite {
eagerlyParseMessageSets = isEagerlyParse;
}
- /** Construct a new, empty instance. */
+ /**
+ * Construct a new, empty instance.
+ *
+ * <p>
+ * This may be an {@code ExtensionRegistry} if the full (non-Lite) proto libraries are available.
+ */
public static ExtensionRegistryLite newInstance() {
- return new ExtensionRegistryLite();
+ return ExtensionRegistryFactory.create();
}
- /** Get the unmodifiable singleton empty instance. */
+ /**
+ * Get the unmodifiable singleton empty instance of either ExtensionRegistryLite or
+ * {@code ExtensionRegistry} (if the full (non-Lite) proto libraries are available).
+ */
public static ExtensionRegistryLite getEmptyRegistry() {
- return EMPTY;
+ return ExtensionRegistryFactory.createEmpty();
}
/** Returns an unmodifiable view of the registry. */
@@ -128,6 +152,23 @@ public class ExtensionRegistryLite {
extension);
}
+ /**
+ * Add an extension from a lite generated file to the registry only if it is
+ * a non-lite extension i.e. {@link GeneratedMessageLite.GeneratedExtension}. */
+ public final void add(ExtensionLite<?, ?> extension) {
+ if (GeneratedMessageLite.GeneratedExtension.class.isAssignableFrom(extension.getClass())) {
+ add((GeneratedMessageLite.GeneratedExtension<?, ?>) extension);
+ }
+ if (ExtensionRegistryFactory.isFullRegistry(this)) {
+ try {
+ this.getClass().getMethod("add", extensionClass).invoke(this, extension);
+ } catch (Exception e) {
+ throw new IllegalArgumentException(
+ String.format("Could not invoke ExtensionRegistry#add for %s", extension), e);
+ }
+ }
+ }
+
// =================================================================
// Private stuff.
@@ -139,9 +180,11 @@ public class ExtensionRegistryLite {
new HashMap<ObjectIntPair,
GeneratedMessageLite.GeneratedExtension<?, ?>>();
}
+ static final ExtensionRegistryLite EMPTY_REGISTRY_LITE =
+ new ExtensionRegistryLite(true);
ExtensionRegistryLite(ExtensionRegistryLite other) {
- if (other == EMPTY) {
+ if (other == EMPTY_REGISTRY_LITE) {
this.extensionsByNumber = Collections.emptyMap();
} else {
this.extensionsByNumber =
@@ -153,11 +196,9 @@ public class ExtensionRegistryLite {
GeneratedMessageLite.GeneratedExtension<?, ?>>
extensionsByNumber;
- private ExtensionRegistryLite(boolean empty) {
+ ExtensionRegistryLite(boolean empty) {
this.extensionsByNumber = Collections.emptyMap();
}
- private static final ExtensionRegistryLite EMPTY =
- new ExtensionRegistryLite(true);
/** A (Object, int) pair, used as a map key. */
private static final class ObjectIntPair {
diff --git a/java/src/main/java/com/google/protobuf/FieldSet.java b/java/core/src/main/java/com/google/protobuf/FieldSet.java
index 47924b65..5b251743 100644
--- a/java/src/main/java/com/google/protobuf/FieldSet.java
+++ b/java/core/src/main/java/com/google/protobuf/FieldSet.java
@@ -121,6 +121,25 @@ final class FieldSet<FieldDescriptorType extends
return isImmutable;
}
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+
+ if (!(o instanceof FieldSet)) {
+ return false;
+ }
+
+ FieldSet<?> other = (FieldSet<?>) o;
+ return fields.equals(other.fields);
+ }
+
+ @Override
+ public int hashCode() {
+ return fields.hashCode();
+ }
+
/**
* Clones the FieldSet. The returned FieldSet will be mutable even if the
* original FieldSet was immutable.
@@ -474,7 +493,7 @@ final class FieldSet<FieldDescriptorType extends
}
/**
- * Like {@link Message.Builder#mergeFrom(Message)}, but merges from another
+ * Like {@link Message.Builder#mergeFrom(Message)}, but merges from another
* {@link FieldSet}.
*/
public void mergeFrom(final FieldSet<FieldDescriptorType> other) {
@@ -619,10 +638,11 @@ final class FieldSet<FieldDescriptorType extends
* {@link Message#getField(Descriptors.FieldDescriptor)} for
* this field.
*/
- private static void writeElement(final CodedOutputStream output,
- final WireFormat.FieldType type,
- final int number,
- final Object value) throws IOException {
+ static void writeElement(
+ final CodedOutputStream output,
+ final WireFormat.FieldType type,
+ final int number,
+ final Object value) throws IOException {
// Special case for groups, which need a start and end tag; other fields
// can just use writeTag() and writeFieldNoTag().
if (type == WireFormat.FieldType.GROUP) {
@@ -785,9 +805,8 @@ final class FieldSet<FieldDescriptorType extends
* {@link Message#getField(Descriptors.FieldDescriptor)} for
* this field.
*/
- private static int computeElementSize(
- final WireFormat.FieldType type,
- final int number, final Object value) {
+ static int computeElementSize(
+ final WireFormat.FieldType type, final int number, final Object value) {
int tagSize = CodedOutputStream.computeTagSize(number);
if (type == WireFormat.FieldType.GROUP) {
// Only count the end group tag for proto2 messages as for proto1 the end
diff --git a/java/src/main/java/com/google/protobuf/FloatArrayList.java b/java/core/src/main/java/com/google/protobuf/FloatArrayList.java
index 293eaff6..90d6154b 100644
--- a/java/src/main/java/com/google/protobuf/FloatArrayList.java
+++ b/java/core/src/main/java/com/google/protobuf/FloatArrayList.java
@@ -34,32 +34,31 @@ import com.google.protobuf.Internal.FloatList;
import java.util.Arrays;
import java.util.Collection;
-import java.util.List;
import java.util.RandomAccess;
/**
* An implementation of {@link FloatList} on top of a primitive array.
- *
+ *
* @author dweis@google.com (Daniel Weis)
*/
-final class FloatArrayList extends AbstractProtobufList<Float> implements FloatList, RandomAccess {
-
- private static final int DEFAULT_CAPACITY = 10;
-
+final class FloatArrayList
+ extends AbstractProtobufList<Float>
+ implements FloatList, RandomAccess {
+
private static final FloatArrayList EMPTY_LIST = new FloatArrayList();
static {
EMPTY_LIST.makeImmutable();
}
-
+
public static FloatArrayList emptyList() {
return EMPTY_LIST;
}
-
+
/**
* The backing store for the list.
*/
private float[] array;
-
+
/**
* The size of the list distinct from the length of the array. That is, it is the number of
* elements set in the list.
@@ -67,30 +66,61 @@ final class FloatArrayList extends AbstractProtobufList<Float> implements FloatL
private int size;
/**
- * Constructs a new mutable {@code FloatArrayList}.
+ * Constructs a new mutable {@code FloatArrayList} with default capacity.
*/
FloatArrayList() {
- array = new float[DEFAULT_CAPACITY];
- size = 0;
+ this(new float[DEFAULT_CAPACITY], 0);
}
/**
- * Constructs a new mutable {@code FloatArrayList} containing the same elements as {@code other}.
+ * Constructs a new mutable {@code FloatArrayList}
+ * containing the same elements as {@code other}.
*/
- FloatArrayList(List<Float> other) {
- if (other instanceof FloatArrayList) {
- FloatArrayList list = (FloatArrayList) other;
- array = list.array.clone();
- size = list.size;
- } else {
- size = other.size();
- array = new float[size];
- for (int i = 0; i < size; i++) {
- array[i] = other.get(i);
+ private FloatArrayList(float[] other, int size) {
+ array = other;
+ this.size = size;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof FloatArrayList)) {
+ return super.equals(o);
+ }
+ FloatArrayList other = (FloatArrayList) o;
+ if (size != other.size) {
+ return false;
+ }
+
+ final float[] arr = other.array;
+ for (int i = 0; i < size; i++) {
+ if (array[i] != arr[i]) {
+ return false;
}
}
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = 1;
+ for (int i = 0; i < size; i++) {
+ result = (31 * result) + Float.floatToIntBits(array[i]);
+ }
+ return result;
}
-
+
+ @Override
+ public FloatList mutableCopyWithCapacity(int capacity) {
+ if (capacity < size) {
+ throw new IllegalArgumentException();
+ }
+ return new FloatArrayList(Arrays.copyOf(array, capacity), size);
+ }
+
@Override
public Float get(int index) {
return getFloat(index);
@@ -142,7 +172,7 @@ final class FloatArrayList extends AbstractProtobufList<Float> implements FloatL
if (index < 0 || index > size) {
throw new IndexOutOfBoundsException(makeOutOfBoundsExceptionMessage(index));
}
-
+
if (size < array.length) {
// Shift everything over to make room
System.arraycopy(array, index, array, index + 1, size - index);
@@ -150,10 +180,10 @@ final class FloatArrayList extends AbstractProtobufList<Float> implements FloatL
// Resize to 1.5x the size
int length = ((size * 3) / 2) + 1;
float[] newArray = new float[length];
-
+
// Copy the first part directly
System.arraycopy(array, 0, newArray, 0, index);
-
+
// Copy the rest shifted over by one to make room
System.arraycopy(array, index, newArray, index + 1, size - index);
array = newArray;
@@ -167,38 +197,38 @@ final class FloatArrayList extends AbstractProtobufList<Float> implements FloatL
@Override
public boolean addAll(Collection<? extends Float> collection) {
ensureIsMutable();
-
+
if (collection == null) {
throw new NullPointerException();
}
-
+
// We specialize when adding another FloatArrayList to avoid boxing elements.
if (!(collection instanceof FloatArrayList)) {
return super.addAll(collection);
}
-
+
FloatArrayList list = (FloatArrayList) collection;
if (list.size == 0) {
return false;
}
-
+
int overflow = Integer.MAX_VALUE - size;
if (overflow < list.size) {
// We can't actually represent a list this large.
throw new OutOfMemoryError();
}
-
+
int newSize = size + list.size;
if (newSize > array.length) {
array = Arrays.copyOf(array, newSize);
}
-
+
System.arraycopy(list.array, 0, array, size, list.size);
size = newSize;
modCount++;
return true;
}
-
+
@Override
public boolean remove(Object o) {
ensureIsMutable();
@@ -227,7 +257,7 @@ final class FloatArrayList extends AbstractProtobufList<Float> implements FloatL
/**
* Ensures that the provided {@code index} is within the range of {@code [0, size]}. Throws an
* {@link IndexOutOfBoundsException} if it is not.
- *
+ *
* @param index the index to verify is in range
*/
private void ensureIndexInRange(int index) {
diff --git a/java/src/main/java/com/google/protobuf/GeneratedMessage.java b/java/core/src/main/java/com/google/protobuf/GeneratedMessage.java
index d84fa75c..cea05794 100644
--- a/java/src/main/java/com/google/protobuf/GeneratedMessage.java
+++ b/java/core/src/main/java/com/google/protobuf/GeneratedMessage.java
@@ -36,15 +36,13 @@ import com.google.protobuf.Descriptors.EnumValueDescriptor;
import com.google.protobuf.Descriptors.FieldDescriptor;
import com.google.protobuf.Descriptors.FileDescriptor;
import com.google.protobuf.Descriptors.OneofDescriptor;
-import com.google.protobuf.GeneratedMessageLite.ExtendableMessage;
-import com.google.protobuf.GeneratedMessageLite.GeneratedExtension;
import java.io.IOException;
+import java.io.InputStream;
import java.io.ObjectStreamException;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
-import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
@@ -82,6 +80,7 @@ public abstract class GeneratedMessage extends AbstractMessage
unknownFields = builder.getUnknownFields();
}
+ @Override
public Parser<? extends GeneratedMessage> getParserForType() {
throw new UnsupportedOperationException(
"This is supposed to be overridden by subclasses.");
@@ -104,7 +103,7 @@ public abstract class GeneratedMessage extends AbstractMessage
*/
protected abstract FieldAccessorTable internalGetFieldAccessorTable();
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public Descriptor getDescriptorForType() {
return internalGetFieldAccessorTable().descriptor;
}
@@ -193,7 +192,7 @@ public abstract class GeneratedMessage extends AbstractMessage
return true;
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public Map<FieldDescriptor, Object> getAllFields() {
return Collections.unmodifiableMap(
getAllFieldsMutable(/* getBytesForString = */ false));
@@ -214,22 +213,22 @@ public abstract class GeneratedMessage extends AbstractMessage
getAllFieldsMutable(/* getBytesForString = */ true));
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public boolean hasOneof(final OneofDescriptor oneof) {
return internalGetFieldAccessorTable().getOneof(oneof).has(this);
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public FieldDescriptor getOneofFieldDescriptor(final OneofDescriptor oneof) {
return internalGetFieldAccessorTable().getOneof(oneof).get(this);
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public boolean hasField(final FieldDescriptor field) {
return internalGetFieldAccessorTable().getField(field).has(this);
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public Object getField(final FieldDescriptor field) {
return internalGetFieldAccessorTable().getField(field).get(this);
}
@@ -246,19 +245,19 @@ public abstract class GeneratedMessage extends AbstractMessage
return internalGetFieldAccessorTable().getField(field).getRaw(this);
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public int getRepeatedFieldCount(final FieldDescriptor field) {
return internalGetFieldAccessorTable().getField(field)
.getRepeatedCount(this);
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public Object getRepeatedField(final FieldDescriptor field, final int index) {
return internalGetFieldAccessorTable().getField(field)
.getRepeated(this, index);
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public UnknownFieldSet getUnknownFields() {
throw new UnsupportedOperationException(
"This is supposed to be overridden by subclasses.");
@@ -276,6 +275,60 @@ public abstract class GeneratedMessage extends AbstractMessage
return unknownFields.mergeFieldFrom(tag, input);
}
+ protected static <M extends Message> M parseWithIOException(Parser<M> parser, InputStream input)
+ throws IOException {
+ try {
+ return parser.parseFrom(input);
+ } catch (InvalidProtocolBufferException e) {
+ throw e.unwrapIOException();
+ }
+ }
+
+ protected static <M extends Message> M parseWithIOException(Parser<M> parser, InputStream input,
+ ExtensionRegistryLite extensions) throws IOException {
+ try {
+ return parser.parseFrom(input, extensions);
+ } catch (InvalidProtocolBufferException e) {
+ throw e.unwrapIOException();
+ }
+ }
+
+ protected static <M extends Message> M parseWithIOException(Parser<M> parser,
+ CodedInputStream input) throws IOException {
+ try {
+ return parser.parseFrom(input);
+ } catch (InvalidProtocolBufferException e) {
+ throw e.unwrapIOException();
+ }
+ }
+
+ protected static <M extends Message> M parseWithIOException(Parser<M> parser,
+ CodedInputStream input, ExtensionRegistryLite extensions) throws IOException {
+ try {
+ return parser.parseFrom(input, extensions);
+ } catch (InvalidProtocolBufferException e) {
+ throw e.unwrapIOException();
+ }
+ }
+
+ protected static <M extends Message> M parseDelimitedWithIOException(Parser<M> parser,
+ InputStream input) throws IOException {
+ try {
+ return parser.parseDelimitedFrom(input);
+ } catch (InvalidProtocolBufferException e) {
+ throw e.unwrapIOException();
+ }
+ }
+
+ protected static <M extends Message> M parseDelimitedWithIOException(Parser<M> parser,
+ InputStream input, ExtensionRegistryLite extensions) throws IOException {
+ try {
+ return parser.parseDelimitedFrom(input, extensions);
+ } catch (InvalidProtocolBufferException e) {
+ throw e.unwrapIOException();
+ }
+ }
+
@Override
public void writeTo(final CodedOutputStream output) throws IOException {
MessageReflection.writeMessageTo(this, getAllFieldsRaw(), output, false);
@@ -302,33 +355,32 @@ public abstract class GeneratedMessage extends AbstractMessage
// Noop for messages without extensions.
}
- protected abstract Message.Builder newBuilderForType(BuilderParent parent);
+ /**
+ * TODO(xiaofeng): remove this after b/29368482 is fixed. We need to move this
+ * interface to AbstractMessage in order to versioning GeneratedMessage but
+ * this move breaks binary compatibility for AppEngine. After AppEngine is
+ * fixed we can exlude this from google3.
+ */
+ protected interface BuilderParent extends AbstractMessage.BuilderParent {}
/**
- * Interface for the parent of a Builder that allows the builder to
- * communicate invalidations back to the parent for use when using nested
- * builders.
+ * TODO(xiaofeng): remove this together with GeneratedMessage.BuilderParent.
*/
- protected interface BuilderParent {
+ protected abstract Message.Builder newBuilderForType(BuilderParent parent);
- /**
- * A builder becomes dirty whenever a field is modified -- including fields
- * in nested builders -- and becomes clean when build() is called. Thus,
- * when a builder becomes dirty, all its parents become dirty as well, and
- * when it becomes clean, all its children become clean. The dirtiness
- * state is used to invalidate certain cached values.
- * <br>
- * To this end, a builder calls markAsDirty() on its parent whenever it
- * transitions from clean to dirty. The parent must propagate this call to
- * its own parent, unless it was already dirty, in which case the
- * grandparent must necessarily already be dirty as well. The parent can
- * only transition back to "clean" after calling build() on all children.
- */
- void markDirty();
+ @Override
+ protected Message.Builder newBuilderForType(final AbstractMessage.BuilderParent parent) {
+ return newBuilderForType(new BuilderParent() {
+ @Override
+ public void markDirty() {
+ parent.markDirty();
+ }
+ });
}
+
@SuppressWarnings("unchecked")
- public abstract static class Builder <BuilderType extends Builder>
+ public abstract static class Builder <BuilderType extends Builder<BuilderType>>
extends AbstractMessage.Builder<BuilderType> {
private BuilderParent builderParent;
@@ -350,6 +402,7 @@ public abstract class GeneratedMessage extends AbstractMessage
this.builderParent = builderParent;
}
+ @Override
void dispose() {
builderParent = null;
}
@@ -367,6 +420,7 @@ public abstract class GeneratedMessage extends AbstractMessage
* Called by the subclass or a builder to notify us that a message was
* built and may be cached and therefore invalidations are needed.
*/
+ @Override
protected void markClean() {
this.isClean = true;
}
@@ -392,6 +446,7 @@ public abstract class GeneratedMessage extends AbstractMessage
* Called by the initialization and clear code paths to allow subclasses to
* reset any of their builtin fields back to the initial values.
*/
+ @Override
public BuilderType clear() {
unknownFields = UnknownFieldSet.getDefaultInstance();
onChanged();
@@ -405,12 +460,12 @@ public abstract class GeneratedMessage extends AbstractMessage
*/
protected abstract FieldAccessorTable internalGetFieldAccessorTable();
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public Descriptor getDescriptorForType() {
return internalGetFieldAccessorTable().descriptor;
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public Map<FieldDescriptor, Object> getAllFields() {
return Collections.unmodifiableMap(getAllFieldsMutable());
}
@@ -458,39 +513,38 @@ public abstract class GeneratedMessage extends AbstractMessage
return result;
}
- public Message.Builder newBuilderForField(
- final FieldDescriptor field) {
+ @Override
+ public Message.Builder newBuilderForField(final FieldDescriptor field) {
return internalGetFieldAccessorTable().getField(field).newBuilder();
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public Message.Builder getFieldBuilder(final FieldDescriptor field) {
return internalGetFieldAccessorTable().getField(field).getBuilder(this);
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
- public Message.Builder getRepeatedFieldBuilder(final FieldDescriptor field,
- int index) {
+ @Override
+ public Message.Builder getRepeatedFieldBuilder(final FieldDescriptor field, int index) {
return internalGetFieldAccessorTable().getField(field).getRepeatedBuilder(
this, index);
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public boolean hasOneof(final OneofDescriptor oneof) {
return internalGetFieldAccessorTable().getOneof(oneof).has(this);
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public FieldDescriptor getOneofFieldDescriptor(final OneofDescriptor oneof) {
return internalGetFieldAccessorTable().getOneof(oneof).get(this);
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public boolean hasField(final FieldDescriptor field) {
return internalGetFieldAccessorTable().getField(field).has(this);
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public Object getField(final FieldDescriptor field) {
Object object = internalGetFieldAccessorTable().getField(field).get(this);
if (field.isRepeated()) {
@@ -502,52 +556,52 @@ public abstract class GeneratedMessage extends AbstractMessage
}
}
- public BuilderType setField(final FieldDescriptor field,
- final Object value) {
+ @Override
+ public BuilderType setField(final FieldDescriptor field, final Object value) {
internalGetFieldAccessorTable().getField(field).set(this, value);
return (BuilderType) this;
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public BuilderType clearField(final FieldDescriptor field) {
internalGetFieldAccessorTable().getField(field).clear(this);
return (BuilderType) this;
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public BuilderType clearOneof(final OneofDescriptor oneof) {
internalGetFieldAccessorTable().getOneof(oneof).clear(this);
return (BuilderType) this;
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public int getRepeatedFieldCount(final FieldDescriptor field) {
return internalGetFieldAccessorTable().getField(field)
.getRepeatedCount(this);
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
- public Object getRepeatedField(final FieldDescriptor field,
- final int index) {
+ @Override
+ public Object getRepeatedField(final FieldDescriptor field, final int index) {
return internalGetFieldAccessorTable().getField(field)
.getRepeated(this, index);
}
- public BuilderType setRepeatedField(final FieldDescriptor field,
- final int index, final Object value) {
+ @Override
+ public BuilderType setRepeatedField(
+ final FieldDescriptor field, final int index, final Object value) {
internalGetFieldAccessorTable().getField(field)
.setRepeated(this, index, value);
return (BuilderType) this;
}
- public BuilderType addRepeatedField(final FieldDescriptor field,
- final Object value) {
+ @Override
+ public BuilderType addRepeatedField(final FieldDescriptor field, final Object value) {
internalGetFieldAccessorTable().getField(field).addRepeated(this, value);
return (BuilderType) this;
}
- public BuilderType setUnknownFields(
- final UnknownFieldSet unknownFields) {
+ @Override
+ public BuilderType setUnknownFields(final UnknownFieldSet unknownFields) {
this.unknownFields = unknownFields;
onChanged();
return (BuilderType) this;
@@ -564,7 +618,7 @@ public abstract class GeneratedMessage extends AbstractMessage
return (BuilderType) this;
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public boolean isInitialized() {
for (final FieldDescriptor field : getDescriptorForType().getFields()) {
// Check that all required fields are present.
@@ -594,7 +648,7 @@ public abstract class GeneratedMessage extends AbstractMessage
return true;
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public final UnknownFieldSet getUnknownFields() {
return unknownFields;
}
@@ -618,7 +672,7 @@ public abstract class GeneratedMessage extends AbstractMessage
*/
private class BuilderParentImpl implements BuilderParent {
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public void markDirty() {
onChanged();
}
@@ -667,7 +721,7 @@ public abstract class GeneratedMessage extends AbstractMessage
"No map fields found in " + getClass().getName());
}
- /** Like {@link internalGetMapField} but return a mutable version. */
+ /** Like {@link #internalGetMapField} but return a mutable version. */
@SuppressWarnings({"unused", "rawtypes"})
protected MapField internalGetMutableMapField(int fieldNumber) {
// Note that we can't use descriptor names here because this method will
@@ -683,6 +737,7 @@ public abstract class GeneratedMessage extends AbstractMessage
public interface ExtendableMessageOrBuilder<
MessageType extends ExtendableMessage> extends MessageOrBuilder {
// Re-define for return type covariance.
+ @Override
Message getDefaultInstanceForType();
/** Check if a singular extension is present. */
@@ -701,6 +756,33 @@ public abstract class GeneratedMessage extends AbstractMessage
<Type> Type getExtension(
ExtensionLite<MessageType, List<Type>> extension,
int index);
+
+ /** Check if a singular extension is present. */
+ <Type> boolean hasExtension(
+ Extension<MessageType, Type> extension);
+ /** Check if a singular extension is present. */
+ <Type> boolean hasExtension(
+ GeneratedExtension<MessageType, Type> extension);
+ /** Get the number of elements in a repeated extension. */
+ <Type> int getExtensionCount(
+ Extension<MessageType, List<Type>> extension);
+ /** Get the number of elements in a repeated extension. */
+ <Type> int getExtensionCount(
+ GeneratedExtension<MessageType, List<Type>> extension);
+ /** Get the value of an extension. */
+ <Type> Type getExtension(
+ Extension<MessageType, Type> extension);
+ /** Get the value of an extension. */
+ <Type> Type getExtension(
+ GeneratedExtension<MessageType, Type> extension);
+ /** Get one element of a repeated extension. */
+ <Type> Type getExtension(
+ Extension<MessageType, List<Type>> extension,
+ int index);
+ /** Get one element of a repeated extension. */
+ <Type> Type getExtension(
+ GeneratedExtension<MessageType, List<Type>> extension,
+ int index);
}
/**
@@ -743,6 +825,8 @@ public abstract class GeneratedMessage extends AbstractMessage
extends GeneratedMessage
implements ExtendableMessageOrBuilder<MessageType> {
+ private static final long serialVersionUID = 1L;
+
private final FieldSet<FieldDescriptor> extensions;
protected ExtendableMessage() {
@@ -769,9 +853,8 @@ public abstract class GeneratedMessage extends AbstractMessage
}
/** Check if a singular extension is present. */
- //@Override (Java 1.6 override semantics, but we must support 1.5)
- public final <Type> boolean hasExtension(
- final ExtensionLite<MessageType, Type> extensionLite) {
+ @Override
+ public final <Type> boolean hasExtension(final ExtensionLite<MessageType, Type> extensionLite) {
Extension<MessageType, Type> extension = checkNotLite(extensionLite);
verifyExtensionContainingType(extension);
@@ -779,7 +862,7 @@ public abstract class GeneratedMessage extends AbstractMessage
}
/** Get the number of elements in a repeated extension. */
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public final <Type> int getExtensionCount(
final ExtensionLite<MessageType, List<Type>> extensionLite) {
Extension<MessageType, List<Type>> extension = checkNotLite(extensionLite);
@@ -790,10 +873,9 @@ public abstract class GeneratedMessage extends AbstractMessage
}
/** Get the value of an extension. */
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
@SuppressWarnings("unchecked")
- public final <Type> Type getExtension(
- final ExtensionLite<MessageType, Type> extensionLite) {
+ public final <Type> Type getExtension(final ExtensionLite<MessageType, Type> extensionLite) {
Extension<MessageType, Type> extension = checkNotLite(extensionLite);
verifyExtensionContainingType(extension);
@@ -815,11 +897,10 @@ public abstract class GeneratedMessage extends AbstractMessage
}
/** Get one element of a repeated extension. */
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
@SuppressWarnings("unchecked")
public final <Type> Type getExtension(
- final ExtensionLite<MessageType, List<Type>> extensionLite,
- final int index) {
+ final ExtensionLite<MessageType, List<Type>> extensionLite, final int index) {
Extension<MessageType, List<Type>> extension = checkNotLite(extensionLite);
verifyExtensionContainingType(extension);
@@ -828,6 +909,53 @@ public abstract class GeneratedMessage extends AbstractMessage
extensions.getRepeatedField(descriptor, index));
}
+ /** Check if a singular extension is present. */
+ @Override
+ public final <Type> boolean hasExtension(final Extension<MessageType, Type> extension) {
+ return hasExtension((ExtensionLite<MessageType, Type>) extension);
+ }
+ /** Check if a singular extension is present. */
+ @Override
+ public final <Type> boolean hasExtension(
+ final GeneratedExtension<MessageType, Type> extension) {
+ return hasExtension((ExtensionLite<MessageType, Type>) extension);
+ }
+ /** Get the number of elements in a repeated extension. */
+ @Override
+ public final <Type> int getExtensionCount(
+ final Extension<MessageType, List<Type>> extension) {
+ return getExtensionCount((ExtensionLite<MessageType, List<Type>>) extension);
+ }
+ /** Get the number of elements in a repeated extension. */
+ @Override
+ public final <Type> int getExtensionCount(
+ final GeneratedExtension<MessageType, List<Type>> extension) {
+ return getExtensionCount((ExtensionLite<MessageType, List<Type>>) extension);
+ }
+ /** Get the value of an extension. */
+ @Override
+ public final <Type> Type getExtension(final Extension<MessageType, Type> extension) {
+ return getExtension((ExtensionLite<MessageType, Type>) extension);
+ }
+ /** Get the value of an extension. */
+ @Override
+ public final <Type> Type getExtension(
+ final GeneratedExtension<MessageType, Type> extension) {
+ return getExtension((ExtensionLite<MessageType, Type>) extension);
+ }
+ /** Get one element of a repeated extension. */
+ @Override
+ public final <Type> Type getExtension(
+ final Extension<MessageType, List<Type>> extension, final int index) {
+ return getExtension((ExtensionLite<MessageType, List<Type>>) extension, index);
+ }
+ /** Get one element of a repeated extension. */
+ @Override
+ public final <Type> Type getExtension(
+ final GeneratedExtension<MessageType, List<Type>> extension, final int index) {
+ return getExtension((ExtensionLite<MessageType, List<Type>>) extension, index);
+ }
+
/** Called by subclasses to check if all extensions are initialized. */
protected boolean extensionsAreInitialized() {
return extensions.isInitialized();
@@ -967,7 +1095,9 @@ public abstract class GeneratedMessage extends AbstractMessage
verifyContainingType(field);
final Object value = extensions.getField(field);
if (value == null) {
- if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+ if (field.isRepeated()) {
+ return Collections.emptyList();
+ } else if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
// Lacking an ExtensionRegistry, we have no way to determine the
// extension's real type, so we return a DynamicMessage.
return DynamicMessage.getDefaultInstance(field.getMessageType());
@@ -1051,7 +1181,7 @@ public abstract class GeneratedMessage extends AbstractMessage
@SuppressWarnings("unchecked")
public abstract static class ExtendableBuilder<
MessageType extends ExtendableMessage,
- BuilderType extends ExtendableBuilder>
+ BuilderType extends ExtendableBuilder<MessageType, BuilderType>>
extends Builder<BuilderType>
implements ExtendableMessageOrBuilder<MessageType> {
@@ -1103,9 +1233,8 @@ public abstract class GeneratedMessage extends AbstractMessage
}
/** Check if a singular extension is present. */
- //@Override (Java 1.6 override semantics, but we must support 1.5)
- public final <Type> boolean hasExtension(
- final ExtensionLite<MessageType, Type> extensionLite) {
+ @Override
+ public final <Type> boolean hasExtension(final ExtensionLite<MessageType, Type> extensionLite) {
Extension<MessageType, Type> extension = checkNotLite(extensionLite);
verifyExtensionContainingType(extension);
@@ -1113,7 +1242,7 @@ public abstract class GeneratedMessage extends AbstractMessage
}
/** Get the number of elements in a repeated extension. */
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public final <Type> int getExtensionCount(
final ExtensionLite<MessageType, List<Type>> extensionLite) {
Extension<MessageType, List<Type>> extension = checkNotLite(extensionLite);
@@ -1124,9 +1253,8 @@ public abstract class GeneratedMessage extends AbstractMessage
}
/** Get the value of an extension. */
- //@Override (Java 1.6 override semantics, but we must support 1.5)
- public final <Type> Type getExtension(
- final ExtensionLite<MessageType, Type> extensionLite) {
+ @Override
+ public final <Type> Type getExtension(final ExtensionLite<MessageType, Type> extensionLite) {
Extension<MessageType, Type> extension = checkNotLite(extensionLite);
verifyExtensionContainingType(extension);
@@ -1148,10 +1276,9 @@ public abstract class GeneratedMessage extends AbstractMessage
}
/** Get one element of a repeated extension. */
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public final <Type> Type getExtension(
- final ExtensionLite<MessageType, List<Type>> extensionLite,
- final int index) {
+ final ExtensionLite<MessageType, List<Type>> extensionLite, final int index) {
Extension<MessageType, List<Type>> extension = checkNotLite(extensionLite);
verifyExtensionContainingType(extension);
@@ -1217,6 +1344,95 @@ public abstract class GeneratedMessage extends AbstractMessage
return (BuilderType) this;
}
+ /** Check if a singular extension is present. */
+ @Override
+ public final <Type> boolean hasExtension(final Extension<MessageType, Type> extension) {
+ return hasExtension((ExtensionLite<MessageType, Type>) extension);
+ }
+ /** Check if a singular extension is present. */
+ @Override
+ public final <Type> boolean hasExtension(
+ final GeneratedExtension<MessageType, Type> extension) {
+ return hasExtension((ExtensionLite<MessageType, Type>) extension);
+ }
+ /** Get the number of elements in a repeated extension. */
+ @Override
+ public final <Type> int getExtensionCount(
+ final Extension<MessageType, List<Type>> extension) {
+ return getExtensionCount((ExtensionLite<MessageType, List<Type>>) extension);
+ }
+ /** Get the number of elements in a repeated extension. */
+ @Override
+ public final <Type> int getExtensionCount(
+ final GeneratedExtension<MessageType, List<Type>> extension) {
+ return getExtensionCount((ExtensionLite<MessageType, List<Type>>) extension);
+ }
+ /** Get the value of an extension. */
+ @Override
+ public final <Type> Type getExtension(final Extension<MessageType, Type> extension) {
+ return getExtension((ExtensionLite<MessageType, Type>) extension);
+ }
+ /** Get the value of an extension. */
+ @Override
+ public final <Type> Type getExtension(
+ final GeneratedExtension<MessageType, Type> extension) {
+ return getExtension((ExtensionLite<MessageType, Type>) extension);
+ }
+ /** Get the value of an extension. */
+ @Override
+ public final <Type> Type getExtension(
+ final Extension<MessageType, List<Type>> extension, final int index) {
+ return getExtension((ExtensionLite<MessageType, List<Type>>) extension, index);
+ }
+ /** Get the value of an extension. */
+ @Override
+ public final <Type> Type getExtension(
+ final GeneratedExtension<MessageType, List<Type>> extension, final int index) {
+ return getExtension((ExtensionLite<MessageType, List<Type>>) extension, index);
+ }
+ /** Set the value of an extension. */
+ public final <Type> BuilderType setExtension(
+ final Extension<MessageType, Type> extension, final Type value) {
+ return setExtension((ExtensionLite<MessageType, Type>) extension, value);
+ }
+ /** Set the value of an extension. */
+ public <Type> BuilderType setExtension(
+ final GeneratedExtension<MessageType, Type> extension, final Type value) {
+ return setExtension((ExtensionLite<MessageType, Type>) extension, value);
+ }
+ /** Set the value of one element of a repeated extension. */
+ public final <Type> BuilderType setExtension(
+ final Extension<MessageType, List<Type>> extension,
+ final int index, final Type value) {
+ return setExtension((ExtensionLite<MessageType, List<Type>>) extension, index, value);
+ }
+ /** Set the value of one element of a repeated extension. */
+ public <Type> BuilderType setExtension(
+ final GeneratedExtension<MessageType, List<Type>> extension,
+ final int index, final Type value) {
+ return setExtension((ExtensionLite<MessageType, List<Type>>) extension, index, value);
+ }
+ /** Append a value to a repeated extension. */
+ public final <Type> BuilderType addExtension(
+ final Extension<MessageType, List<Type>> extension, final Type value) {
+ return addExtension((ExtensionLite<MessageType, List<Type>>) extension, value);
+ }
+ /** Append a value to a repeated extension. */
+ public <Type> BuilderType addExtension(
+ final GeneratedExtension<MessageType, List<Type>> extension, final Type value) {
+ return addExtension((ExtensionLite<MessageType, List<Type>>) extension, value);
+ }
+ /** Clear an extension. */
+ public final <Type> BuilderType clearExtension(
+ final Extension<MessageType, ?> extension) {
+ return clearExtension((ExtensionLite<MessageType, ?>) extension);
+ }
+ /** Clear an extension. */
+ public <Type> BuilderType clearExtension(
+ final GeneratedExtension<MessageType, ?> extension) {
+ return clearExtension((ExtensionLite<MessageType, ?>) extension);
+ }
+
/** Called by subclasses to check if all extensions are initialized. */
protected boolean extensionsAreInitialized() {
return extensions.isInitialized();
@@ -1404,10 +1620,9 @@ public abstract class GeneratedMessage extends AbstractMessage
// obtained.
return new GeneratedExtension<ContainingType, Type>(
new CachedDescriptorRetriever() {
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public FieldDescriptor loadDescriptor() {
- return scope.getDescriptorForType().getExtensions()
- .get(descriptorIndex);
+ return scope.getDescriptorForType().getExtensions().get(descriptorIndex);
}
},
singularType,
@@ -1435,6 +1650,7 @@ public abstract class GeneratedMessage extends AbstractMessage
private volatile FieldDescriptor descriptor;
protected abstract FieldDescriptor loadDescriptor();
+ @Override
public FieldDescriptor getDescriptor() {
if (descriptor == null) {
synchronized (this) {
@@ -1464,6 +1680,7 @@ public abstract class GeneratedMessage extends AbstractMessage
// obtained.
return new GeneratedExtension<ContainingType, Type>(
new CachedDescriptorRetriever() {
+ @Override
protected FieldDescriptor loadDescriptor() {
return scope.getDescriptorForType().findFieldByName(name);
}
@@ -1490,17 +1707,18 @@ public abstract class GeneratedMessage extends AbstractMessage
// used to obtain the extension's FieldDescriptor.
return new GeneratedExtension<ContainingType, Type>(
new CachedDescriptorRetriever() {
+ @Override
protected FieldDescriptor loadDescriptor() {
try {
- Class clazz =
- singularType.getClassLoader().loadClass(descriptorOuterClass);
- FileDescriptor file =
- (FileDescriptor) clazz.getField("descriptor").get(null);
+ Class clazz = singularType.getClassLoader().loadClass(descriptorOuterClass);
+ FileDescriptor file = (FileDescriptor) clazz.getField("descriptor").get(null);
return file.findExtensionByName(extensionName);
} catch (Exception e) {
throw new RuntimeException(
- "Cannot load descriptors: " + descriptorOuterClass +
- " is not a valid descriptor class name", e);
+ "Cannot load descriptors: "
+ + descriptorOuterClass
+ + " is not a valid descriptor class name",
+ e);
}
}
},
@@ -1582,12 +1800,13 @@ public abstract class GeneratedMessage extends AbstractMessage
if (descriptorRetriever != null) {
throw new IllegalStateException("Already initialized.");
}
- descriptorRetriever = new ExtensionDescriptorRetriever() {
- //@Override (Java 1.6 override semantics, but we must support 1.5)
- public FieldDescriptor getDescriptor() {
- return descriptor;
- }
- };
+ descriptorRetriever =
+ new ExtensionDescriptorRetriever() {
+ @Override
+ public FieldDescriptor getDescriptor() {
+ return descriptor;
+ }
+ };
}
private ExtensionDescriptorRetriever descriptorRetriever;
@@ -1597,6 +1816,7 @@ public abstract class GeneratedMessage extends AbstractMessage
private final Method enumGetValueDescriptor;
private final ExtensionType extensionType;
+ @Override
public FieldDescriptor getDescriptor() {
if (descriptorRetriever == null) {
throw new IllegalStateException(
@@ -1609,10 +1829,12 @@ public abstract class GeneratedMessage extends AbstractMessage
* If the extension is an embedded message or group, returns the default
* instance of the message.
*/
+ @Override
public Message getMessageDefaultInstance() {
return messageDefaultInstance;
}
+ @Override
protected ExtensionType getExtensionType() {
return extensionType;
}
@@ -1623,7 +1845,7 @@ public abstract class GeneratedMessage extends AbstractMessage
* EnumValueDescriptors but the native accessors use the generated enum
* type.
*/
- // @Override
+ @Override
@SuppressWarnings("unchecked")
protected Object fromReflectionType(final Object value) {
FieldDescriptor descriptor = getDescriptor();
@@ -1648,7 +1870,7 @@ public abstract class GeneratedMessage extends AbstractMessage
* Like {@link #fromReflectionType(Object)}, but if the type is a repeated
* type, this converts a single element.
*/
- // @Override
+ @Override
protected Object singularFromReflectionType(final Object value) {
FieldDescriptor descriptor = getDescriptor();
switch (descriptor.getJavaType()) {
@@ -1672,7 +1894,7 @@ public abstract class GeneratedMessage extends AbstractMessage
* EnumValueDescriptors but the native accessors use the generated enum
* type.
*/
- // @Override
+ @Override
@SuppressWarnings("unchecked")
protected Object toReflectionType(final Object value) {
FieldDescriptor descriptor = getDescriptor();
@@ -1696,7 +1918,7 @@ public abstract class GeneratedMessage extends AbstractMessage
* Like {@link #toReflectionType(Object)}, but if the type is a repeated
* type, this converts a single element.
*/
- // @Override
+ @Override
protected Object singularToReflectionType(final Object value) {
FieldDescriptor descriptor = getDescriptor();
switch (descriptor.getJavaType()) {
@@ -1707,22 +1929,22 @@ public abstract class GeneratedMessage extends AbstractMessage
}
}
- // @Override
+ @Override
public int getNumber() {
return getDescriptor().getNumber();
}
- // @Override
+ @Override
public WireFormat.FieldType getLiteType() {
return getDescriptor().getLiteType();
}
- // @Override
+ @Override
public boolean isRepeated() {
return getDescriptor().isRepeated();
}
- // @Override
+ @Override
@SuppressWarnings("unchecked")
public Type getDefaultValue() {
if (isRepeated()) {
@@ -2072,49 +2294,57 @@ public abstract class GeneratedMessage extends AbstractMessage
return ((Internal.EnumLite) invokeOrDie(caseMethodBuilder, builder)).getNumber();
}
+ @Override
public Object get(final GeneratedMessage message) {
return invokeOrDie(getMethod, message);
}
+ @Override
public Object get(GeneratedMessage.Builder builder) {
return invokeOrDie(getMethodBuilder, builder);
}
+ @Override
public Object getRaw(final GeneratedMessage message) {
return get(message);
}
+ @Override
public Object getRaw(GeneratedMessage.Builder builder) {
return get(builder);
}
+ @Override
public void set(final Builder builder, final Object value) {
invokeOrDie(setMethod, builder, value);
}
- public Object getRepeated(final GeneratedMessage message,
- final int index) {
+ @Override
+ public Object getRepeated(final GeneratedMessage message, final int index) {
throw new UnsupportedOperationException(
"getRepeatedField() called on a singular field.");
}
- public Object getRepeatedRaw(final GeneratedMessage message,
- final int index) {
+ @Override
+ public Object getRepeatedRaw(final GeneratedMessage message, final int index) {
throw new UnsupportedOperationException(
"getRepeatedFieldRaw() called on a singular field.");
}
+ @Override
public Object getRepeated(GeneratedMessage.Builder builder, int index) {
throw new UnsupportedOperationException(
"getRepeatedField() called on a singular field.");
}
- public Object getRepeatedRaw(GeneratedMessage.Builder builder,
- int index) {
+ @Override
+ public Object getRepeatedRaw(GeneratedMessage.Builder builder, int index) {
throw new UnsupportedOperationException(
"getRepeatedFieldRaw() called on a singular field.");
}
- public void setRepeated(final Builder builder, final int index,
- final Object value) {
+ @Override
+ public void setRepeated(final Builder builder, final int index, final Object value) {
throw new UnsupportedOperationException(
"setRepeatedField() called on a singular field.");
}
+ @Override
public void addRepeated(final Builder builder, final Object value) {
throw new UnsupportedOperationException(
"addRepeatedField() called on a singular field.");
}
+ @Override
public boolean has(final GeneratedMessage message) {
if (!hasHasMethod) {
if (isOneofField) {
@@ -2124,6 +2354,7 @@ public abstract class GeneratedMessage extends AbstractMessage
}
return (Boolean) invokeOrDie(hasMethod, message);
}
+ @Override
public boolean has(GeneratedMessage.Builder builder) {
if (!hasHasMethod) {
if (isOneofField) {
@@ -2133,27 +2364,32 @@ public abstract class GeneratedMessage extends AbstractMessage
}
return (Boolean) invokeOrDie(hasMethodBuilder, builder);
}
+ @Override
public int getRepeatedCount(final GeneratedMessage message) {
throw new UnsupportedOperationException(
"getRepeatedFieldSize() called on a singular field.");
}
+ @Override
public int getRepeatedCount(GeneratedMessage.Builder builder) {
throw new UnsupportedOperationException(
"getRepeatedFieldSize() called on a singular field.");
}
+ @Override
public void clear(final Builder builder) {
invokeOrDie(clearMethod, builder);
}
+ @Override
public Message.Builder newBuilder() {
throw new UnsupportedOperationException(
"newBuilderForField() called on a non-Message type.");
}
+ @Override
public Message.Builder getBuilder(GeneratedMessage.Builder builder) {
throw new UnsupportedOperationException(
"getFieldBuilder() called on a non-Message type.");
}
- public Message.Builder getRepeatedBuilder(GeneratedMessage.Builder builder,
- int index) {
+ @Override
+ public Message.Builder getRepeatedBuilder(GeneratedMessage.Builder builder, int index) {
throw new UnsupportedOperationException(
"getRepeatedFieldBuilder() called on a non-Message type.");
}
@@ -2197,18 +2433,23 @@ public abstract class GeneratedMessage extends AbstractMessage
clearMethod = getMethodOrDie(builderClass, "clear" + camelCaseName);
}
+ @Override
public Object get(final GeneratedMessage message) {
return invokeOrDie(getMethod, message);
}
+ @Override
public Object get(GeneratedMessage.Builder builder) {
return invokeOrDie(getMethodBuilder, builder);
}
+ @Override
public Object getRaw(final GeneratedMessage message) {
return get(message);
}
+ @Override
public Object getRaw(GeneratedMessage.Builder builder) {
return get(builder);
}
+ @Override
public void set(final Builder builder, final Object value) {
// Add all the elements individually. This serves two purposes:
// 1) Verifies that each element has the correct type.
@@ -2219,54 +2460,64 @@ public abstract class GeneratedMessage extends AbstractMessage
addRepeated(builder, element);
}
}
- public Object getRepeated(final GeneratedMessage message,
- final int index) {
+ @Override
+ public Object getRepeated(final GeneratedMessage message, final int index) {
return invokeOrDie(getRepeatedMethod, message, index);
}
+ @Override
public Object getRepeated(GeneratedMessage.Builder builder, int index) {
return invokeOrDie(getRepeatedMethodBuilder, builder, index);
}
+ @Override
public Object getRepeatedRaw(GeneratedMessage message, int index) {
return getRepeated(message, index);
}
- public Object getRepeatedRaw(GeneratedMessage.Builder builder,
- int index) {
+ @Override
+ public Object getRepeatedRaw(GeneratedMessage.Builder builder, int index) {
return getRepeated(builder, index);
}
- public void setRepeated(final Builder builder,
- final int index, final Object value) {
+ @Override
+ public void setRepeated(final Builder builder, final int index, final Object value) {
invokeOrDie(setRepeatedMethod, builder, index, value);
}
+ @Override
public void addRepeated(final Builder builder, final Object value) {
invokeOrDie(addRepeatedMethod, builder, value);
}
+ @Override
public boolean has(final GeneratedMessage message) {
throw new UnsupportedOperationException(
"hasField() called on a repeated field.");
}
+ @Override
public boolean has(GeneratedMessage.Builder builder) {
throw new UnsupportedOperationException(
"hasField() called on a repeated field.");
}
+ @Override
public int getRepeatedCount(final GeneratedMessage message) {
return (Integer) invokeOrDie(getCountMethod, message);
}
+ @Override
public int getRepeatedCount(GeneratedMessage.Builder builder) {
return (Integer) invokeOrDie(getCountMethodBuilder, builder);
}
+ @Override
public void clear(final Builder builder) {
invokeOrDie(clearMethod, builder);
}
+ @Override
public Message.Builder newBuilder() {
throw new UnsupportedOperationException(
"newBuilderForField() called on a non-Message type.");
}
+ @Override
public Message.Builder getBuilder(GeneratedMessage.Builder builder) {
throw new UnsupportedOperationException(
"getFieldBuilder() called on a non-Message type.");
}
- public Message.Builder getRepeatedBuilder(GeneratedMessage.Builder builder,
- int index) {
+ @Override
+ public Message.Builder getRepeatedBuilder(GeneratedMessage.Builder builder, int index) {
throw new UnsupportedOperationException(
"getRepeatedFieldBuilder() called on a non-Message type.");
}
@@ -2303,6 +2554,7 @@ public abstract class GeneratedMessage extends AbstractMessage
field.getNumber());
}
+ @Override
public Object get(GeneratedMessage message) {
List result = new ArrayList();
for (int i = 0; i < getRepeatedCount(message); i++) {
@@ -2311,6 +2563,7 @@ public abstract class GeneratedMessage extends AbstractMessage
return Collections.unmodifiableList(result);
}
+ @Override
public Object get(Builder builder) {
List result = new ArrayList();
for (int i = 0; i < getRepeatedCount(builder); i++) {
@@ -2319,14 +2572,17 @@ public abstract class GeneratedMessage extends AbstractMessage
return Collections.unmodifiableList(result);
}
+ @Override
public Object getRaw(GeneratedMessage message) {
return get(message);
}
+ @Override
public Object getRaw(GeneratedMessage.Builder builder) {
return get(builder);
}
+ @Override
public void set(Builder builder, Object value) {
clear(builder);
for (Object entry : (List) value) {
@@ -2334,63 +2590,76 @@ public abstract class GeneratedMessage extends AbstractMessage
}
}
+ @Override
public Object getRepeated(GeneratedMessage message, int index) {
return getMapField(message).getList().get(index);
}
+ @Override
public Object getRepeated(Builder builder, int index) {
return getMapField(builder).getList().get(index);
}
+ @Override
public Object getRepeatedRaw(GeneratedMessage message, int index) {
return getRepeated(message, index);
}
+ @Override
public Object getRepeatedRaw(Builder builder, int index) {
return getRepeated(builder, index);
}
+ @Override
public void setRepeated(Builder builder, int index, Object value) {
getMutableMapField(builder).getMutableList().set(index, (Message) value);
}
+ @Override
public void addRepeated(Builder builder, Object value) {
getMutableMapField(builder).getMutableList().add((Message) value);
}
+ @Override
public boolean has(GeneratedMessage message) {
throw new UnsupportedOperationException(
"hasField() is not supported for repeated fields.");
}
+ @Override
public boolean has(Builder builder) {
throw new UnsupportedOperationException(
"hasField() is not supported for repeated fields.");
}
+ @Override
public int getRepeatedCount(GeneratedMessage message) {
return getMapField(message).getList().size();
}
+ @Override
public int getRepeatedCount(Builder builder) {
return getMapField(builder).getList().size();
}
+ @Override
public void clear(Builder builder) {
getMutableMapField(builder).getMutableList().clear();
}
+ @Override
public com.google.protobuf.Message.Builder newBuilder() {
return mapEntryMessageDefaultInstance.newBuilderForType();
}
+ @Override
public com.google.protobuf.Message.Builder getBuilder(Builder builder) {
throw new UnsupportedOperationException(
"Nested builder not supported for map fields.");
}
- public com.google.protobuf.Message.Builder getRepeatedBuilder(
- Builder builder, int index) {
+ @Override
+ public com.google.protobuf.Message.Builder getRepeatedBuilder(Builder builder, int index) {
throw new UnsupportedOperationException(
"Nested builder not supported for map fields.");
}
diff --git a/java/src/main/java/com/google/protobuf/GeneratedMessageLite.java b/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java
index 4316efee..214971b1 100644
--- a/java/src/main/java/com/google/protobuf/GeneratedMessageLite.java
+++ b/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java
@@ -30,6 +30,8 @@
package com.google.protobuf;
+import com.google.protobuf.AbstractMessageLite.Builder.LimitedInputStream;
+import com.google.protobuf.GeneratedMessageLite.EqualsVisitor.NotEqualsException;
import com.google.protobuf.Internal.BooleanList;
import com.google.protobuf.Internal.DoubleList;
import com.google.protobuf.Internal.FloatList;
@@ -39,6 +41,7 @@ import com.google.protobuf.Internal.ProtobufList;
import com.google.protobuf.WireFormat.FieldType;
import java.io.IOException;
+import java.io.InputStream;
import java.io.ObjectStreamException;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
@@ -56,33 +59,109 @@ import java.util.Map;
*/
public abstract class GeneratedMessageLite<
MessageType extends GeneratedMessageLite<MessageType, BuilderType>,
- BuilderType extends GeneratedMessageLite.Builder<MessageType, BuilderType>>
- extends AbstractMessageLite
- implements Serializable {
-
- private static final long serialVersionUID = 1L;
+ BuilderType extends GeneratedMessageLite.Builder<MessageType, BuilderType>>
+ extends AbstractMessageLite<MessageType, BuilderType> {
/** For use by generated code only. Lazily initialized to reduce allocations. */
- protected UnknownFieldSetLite unknownFields = null;
-
+ protected UnknownFieldSetLite unknownFields = UnknownFieldSetLite.getDefaultInstance();
+
/** For use by generated code only. */
protected int memoizedSerializedSize = -1;
-
+
+ @Override
@SuppressWarnings("unchecked") // Guaranteed by runtime.
public final Parser<MessageType> getParserForType() {
return (Parser<MessageType>) dynamicMethod(MethodToInvoke.GET_PARSER);
}
+ @Override
@SuppressWarnings("unchecked") // Guaranteed by runtime.
public final MessageType getDefaultInstanceForType() {
return (MessageType) dynamicMethod(MethodToInvoke.GET_DEFAULT_INSTANCE);
}
+ @Override
@SuppressWarnings("unchecked") // Guaranteed by runtime.
public final BuilderType newBuilderForType() {
return (BuilderType) dynamicMethod(MethodToInvoke.NEW_BUILDER);
}
+ /**
+ * A reflective toString function. This is primarily intended as a developer aid, while keeping
+ * binary size down. The first line of the {@code toString()} representation includes a commented
+ * version of {@code super.toString()} to act as an indicator that this should not be relied on
+ * for comparisons.
+ * <p>
+ * NOTE: This method relies on the field getter methods not being stripped or renamed by proguard.
+ * If they are, the fields will not be included in the returned string representation.
+ * <p>
+ * NOTE: This implementation is liable to change in the future, and should not be relied on in
+ * code.
+ */
+ @Override
+ public String toString() {
+ return MessageLiteToString.toString(this, super.toString());
+ }
+
+ @SuppressWarnings("unchecked") // Guaranteed by runtime
+ @Override
+ public int hashCode() {
+ if (memoizedHashCode == 0) {
+ HashCodeVisitor visitor = new HashCodeVisitor();
+ visit(visitor, (MessageType) this);
+ memoizedHashCode = visitor.hashCode;
+ }
+ return memoizedHashCode;
+ }
+
+ @SuppressWarnings("unchecked") // Guaranteed by runtime
+ int hashCode(HashCodeVisitor visitor) {
+ if (memoizedHashCode == 0) {
+ int inProgressHashCode = visitor.hashCode;
+ visitor.hashCode = 0;
+ visit(visitor, (MessageType) this);
+ memoizedHashCode = visitor.hashCode;
+ visitor.hashCode = inProgressHashCode;
+ }
+ return memoizedHashCode;
+ }
+
+ @SuppressWarnings("unchecked") // Guaranteed by isInstance + runtime
+ @Override
+ public boolean equals(Object other) {
+ if (this == other) {
+ return true;
+ }
+
+ if (!getDefaultInstanceForType().getClass().isInstance(other)) {
+ return false;
+ }
+
+ try {
+ visit(EqualsVisitor.INSTANCE, (MessageType) other);
+ } catch (NotEqualsException e) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Same as {@link #equals(Object)} but throws {@code NotEqualsException}.
+ */
+ @SuppressWarnings("unchecked") // Guaranteed by isInstance + runtime
+ boolean equals(EqualsVisitor visitor, MessageLite other) {
+ if (this == other) {
+ return true;
+ }
+
+ if (!getDefaultInstanceForType().getClass().isInstance(other)) {
+ return false;
+ }
+
+ visit(visitor, (MessageType) other);
+ return true;
+ }
+
// The general strategy for unknown fields is to use an UnknownFieldSetLite that is treated as
// mutable during the parsing constructor and immutable after. This allows us to avoid
// any unnecessary intermediary allocations while reducing the generated code size.
@@ -91,17 +170,22 @@ public abstract class GeneratedMessageLite<
* Lazily initializes unknown fields.
*/
private final void ensureUnknownFieldsInitialized() {
- if (unknownFields == null) {
+ if (unknownFields == UnknownFieldSetLite.getDefaultInstance()) {
unknownFields = UnknownFieldSetLite.newInstance();
}
}
-
+
/**
* Called by subclasses to parse an unknown field. For use by generated code only.
- *
+ *
* @return {@code true} unless the tag is an end-group tag.
*/
protected boolean parseUnknownField(int tag, CodedInputStream input) throws IOException {
+ // This will avoid the allocation of unknown fields when a group tag is encountered.
+ if (WireFormat.getTagWireType(tag) == WireFormat.WIRETYPE_END_GROUP) {
+ return false;
+ }
+
ensureUnknownFieldsInitialized();
return unknownFields.mergeFieldFrom(tag, input);
}
@@ -113,7 +197,7 @@ public abstract class GeneratedMessageLite<
ensureUnknownFieldsInitialized();
unknownFields.mergeVarintField(tag, value);
}
-
+
/**
* Called by subclasses to parse an unknown field. For use by generated code only.
*/
@@ -121,22 +205,22 @@ public abstract class GeneratedMessageLite<
ensureUnknownFieldsInitialized();
unknownFields.mergeLengthDelimitedField(fieldNumber, value);
}
-
+
/**
* Called by subclasses to complete parsing. For use by generated code only.
*/
- protected void doneParsing() {
- if (unknownFields == null) {
- unknownFields = UnknownFieldSetLite.getDefaultInstance();
- } else {
- unknownFields.makeImmutable();
- }
+ protected void makeImmutable() {
+ dynamicMethod(MethodToInvoke.MAKE_IMMUTABLE);
+
+ unknownFields.makeImmutable();
}
+ @Override
public final boolean isInitialized() {
return dynamicMethod(MethodToInvoke.IS_INITIALIZED, Boolean.TRUE) != null;
}
+ @Override
public final BuilderType toBuilder() {
BuilderType builder = (BuilderType) dynamicMethod(MethodToInvoke.NEW_BUILDER);
builder.mergeFrom((MessageType) this);
@@ -150,11 +234,14 @@ public abstract class GeneratedMessageLite<
* For use by generated code only.
*/
public static enum MethodToInvoke {
+ // Rely on/modify instance state
IS_INITIALIZED,
- PARSE_PARTIAL_FROM,
- MERGE_FROM,
+ VISIT,
+ MERGE_FROM_STREAM,
MAKE_IMMUTABLE,
- NEW_INSTANCE,
+
+ // Rely on static state
+ NEW_MUTABLE_INSTANCE,
NEW_BUILDER,
GET_DEFAULT_INSTANCE,
GET_PARSER;
@@ -166,17 +253,18 @@ public abstract class GeneratedMessageLite<
* builders in the runtime. This method bundles those operations to reduce the generated methods
* count.
* <ul>
- * <li>{@code PARSE_PARTIAL_FROM} is parameterized with an {@link CodedInputStream} and
+ * <li>{@code MERGE_FROM_STREAM} is parameterized with an {@link CodedInputStream} and
* {@link ExtensionRegistryLite}. It consumes the input stream, parsing the contents into the
* returned protocol buffer. If parsing throws an {@link InvalidProtocolBufferException}, the
- * implementation wraps it in a RuntimeException
- * <li>{@code NEW_INSTANCE} returns a new instance of the protocol buffer
+ * implementation wraps it in a RuntimeException.
+ * <li>{@code NEW_INSTANCE} returns a new instance of the protocol buffer that has not yet been
+ * made immutable. See {@code MAKE_IMMUTABLE}.
* <li>{@code IS_INITIALIZED} is parameterized with a {@code Boolean} detailing whether to
* memoize. It returns {@code null} for false and the default instance for true. We optionally
* memoize to support the Builder case, where memoization is not desired.
* <li>{@code NEW_BUILDER} returns a {@code BuilderType} instance.
- * <li>{@code MERGE_FROM} is parameterized with a {@code MessageType} and merges the fields from
- * that instance into this instance.
+ * <li>{@code VISIT} is parameterized with a {@code Visitor} and a {@code MessageType} and
+ * recursively iterates through the fields side by side between this and the instance.
* <li>{@code MAKE_IMMUTABLE} sets all internal fields to an immutable state.
* </ul>
* This method, plus the implementation of the Builder, enables the Builder class to be proguarded
@@ -200,6 +288,11 @@ public abstract class GeneratedMessageLite<
return dynamicMethod(method, null, null);
}
+ void visit(Visitor visitor, MessageType other) {
+ dynamicMethod(MethodToInvoke.VISIT, visitor, other);
+ unknownFields = visitor.visitUnknownFields(unknownFields, other.unknownFields);
+ }
+
/**
* Merge some unknown fields into the {@link UnknownFieldSetLite} for this
* message.
@@ -214,7 +307,7 @@ public abstract class GeneratedMessageLite<
public abstract static class Builder<
MessageType extends GeneratedMessageLite<MessageType, BuilderType>,
BuilderType extends Builder<MessageType, BuilderType>>
- extends AbstractMessageLite.Builder<BuilderType> {
+ extends AbstractMessageLite.Builder<MessageType, BuilderType> {
private final MessageType defaultInstance;
protected MessageType instance;
@@ -222,7 +315,8 @@ public abstract class GeneratedMessageLite<
protected Builder(MessageType defaultInstance) {
this.defaultInstance = defaultInstance;
- this.instance = (MessageType) defaultInstance.dynamicMethod(MethodToInvoke.NEW_INSTANCE);
+ this.instance =
+ (MessageType) defaultInstance.dynamicMethod(MethodToInvoke.NEW_MUTABLE_INSTANCE);
isBuilt = false;
}
@@ -232,26 +326,27 @@ public abstract class GeneratedMessageLite<
*/
protected void copyOnWrite() {
if (isBuilt) {
- MessageType newInstance = (MessageType) instance.dynamicMethod(MethodToInvoke.NEW_INSTANCE);
- newInstance.dynamicMethod(MethodToInvoke.MERGE_FROM, instance);
+ MessageType newInstance =
+ (MessageType) instance.dynamicMethod(MethodToInvoke.NEW_MUTABLE_INSTANCE);
+ newInstance.visit(MergeFromVisitor.INSTANCE, instance);
instance = newInstance;
isBuilt = false;
}
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public final boolean isInitialized() {
return GeneratedMessageLite.isInitialized(instance, false /* shouldMemoize */);
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public final BuilderType clear() {
// No need to copy on write since we're dropping the instance anyways.
- instance = (MessageType) instance.dynamicMethod(MethodToInvoke.NEW_INSTANCE);
+ instance = (MessageType) instance.dynamicMethod(MethodToInvoke.NEW_MUTABLE_INSTANCE);
return (BuilderType) this;
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public BuilderType clone() {
BuilderType builder =
(BuilderType) getDefaultInstanceForType().newBuilderForType();
@@ -259,20 +354,19 @@ public abstract class GeneratedMessageLite<
return builder;
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public MessageType buildPartial() {
if (isBuilt) {
return instance;
}
-
- instance.dynamicMethod(MethodToInvoke.MAKE_IMMUTABLE);
- instance.unknownFields.makeImmutable();
-
+
+ instance.makeImmutable();
+
isBuilt = true;
return instance;
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public final MessageType build() {
MessageType result = buildPartial();
if (!result.isInitialized()) {
@@ -280,34 +374,37 @@ public abstract class GeneratedMessageLite<
}
return result;
}
-
+
+ @Override
+ protected BuilderType internalMergeFrom(MessageType message) {
+ return mergeFrom(message);
+ }
+
/** All subclasses implement this. */
public BuilderType mergeFrom(MessageType message) {
copyOnWrite();
- instance.dynamicMethod(MethodToInvoke.MERGE_FROM, message);
+ instance.visit(MergeFromVisitor.INSTANCE, message);
return (BuilderType) this;
}
-
+
+ @Override
public MessageType getDefaultInstanceForType() {
return defaultInstance;
}
-
+
+ @Override
public BuilderType mergeFrom(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
- throws java.io.IOException {
- MessageType parsedMessage = null;
+ throws IOException {
+ copyOnWrite();
try {
- parsedMessage =
- (MessageType) getDefaultInstanceForType().getParserForType().parsePartialFrom(
- input, extensionRegistry);
- } catch (com.google.protobuf.InvalidProtocolBufferException e) {
- parsedMessage = (MessageType) e.getUnfinishedMessage();
- throw e;
- } finally {
- if (parsedMessage != null) {
- mergeFrom(parsedMessage);
+ instance.dynamicMethod(MethodToInvoke.MERGE_FROM_STREAM, input, extensionRegistry);
+ } catch (RuntimeException e) {
+ if (e.getCause() instanceof IOException) {
+ throw (IOException) e.getCause();
}
+ throw e;
}
return (BuilderType) this;
}
@@ -363,12 +460,18 @@ public abstract class GeneratedMessageLite<
}
extensions.mergeFrom(((ExtendableMessage) other).extensions);
}
-
+
+ @Override
+ final void visit(Visitor visitor, MessageType other) {
+ super.visit(visitor, other);
+ extensions = visitor.visitExtensions(extensions, other.extensions);
+ }
+
/**
* Parse an unknown field or an extension. For use by generated code only.
- *
+ *
* <p>For use by generated code only.
- *
+ *
* @return {@code true} unless the tag is an end-group tag.
*/
protected <MessageType extends MessageLite> boolean parseUnknownField(
@@ -487,7 +590,7 @@ public abstract class GeneratedMessageLite<
return true;
}
-
+
private void verifyExtensionContainingType(
final GeneratedExtension<MessageType, ?> extension) {
if (extension.getContainingTypeDefaultInstance() !=
@@ -500,35 +603,33 @@ public abstract class GeneratedMessageLite<
}
/** Check if a singular extension is present. */
- //@Override (Java 1.6 override semantics, but we must support 1.5)
- public final <Type> boolean hasExtension(
- final ExtensionLite<MessageType, Type> extension) {
+ @Override
+ public final <Type> boolean hasExtension(final ExtensionLite<MessageType, Type> extension) {
GeneratedExtension<MessageType, Type> extensionLite =
checkIsLite(extension);
-
+
verifyExtensionContainingType(extensionLite);
return extensions.hasField(extensionLite.descriptor);
}
/** Get the number of elements in a repeated extension. */
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public final <Type> int getExtensionCount(
final ExtensionLite<MessageType, List<Type>> extension) {
GeneratedExtension<MessageType, List<Type>> extensionLite =
checkIsLite(extension);
-
+
verifyExtensionContainingType(extensionLite);
return extensions.getRepeatedFieldCount(extensionLite.descriptor);
}
/** Get the value of an extension. */
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
@SuppressWarnings("unchecked")
- public final <Type> Type getExtension(
- final ExtensionLite<MessageType, Type> extension) {
+ public final <Type> Type getExtension(final ExtensionLite<MessageType, Type> extension) {
GeneratedExtension<MessageType, Type> extensionLite =
checkIsLite(extension);
-
+
verifyExtensionContainingType(extensionLite);
final Object value = extensions.getField(extensionLite.descriptor);
if (value == null) {
@@ -539,11 +640,10 @@ public abstract class GeneratedMessageLite<
}
/** Get one element of a repeated extension. */
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
@SuppressWarnings("unchecked")
public final <Type> Type getExtension(
- final ExtensionLite<MessageType, List<Type>> extension,
- final int index) {
+ final ExtensionLite<MessageType, List<Type>> extension, final int index) {
GeneratedExtension<MessageType, List<Type>> extensionLite =
checkIsLite(extension);
@@ -557,11 +657,10 @@ public abstract class GeneratedMessageLite<
return extensions.isInitialized();
}
-
@Override
- protected final void doneParsing() {
- super.doneParsing();
-
+ protected final void makeImmutable() {
+ super.makeImmutable();
+
extensions.makeImmutable();
}
@@ -635,7 +734,7 @@ public abstract class GeneratedMessageLite<
implements ExtendableMessageOrBuilder<MessageType, BuilderType> {
protected ExtendableBuilder(MessageType defaultInstance) {
super(defaultInstance);
-
+
// TODO(dweis): This is kind of an unnecessary clone since we construct a
// new instance in the parent constructor which makes the extensions
// immutable. This extra allocation shouldn't matter in practice
@@ -649,17 +748,17 @@ public abstract class GeneratedMessageLite<
instance.extensions = extensions;
}
- // @Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
protected void copyOnWrite() {
if (!isBuilt) {
return;
}
-
+
super.copyOnWrite();
instance.extensions = instance.extensions.clone();
}
- // @Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public final MessageType buildPartial() {
if (isBuilt) {
return instance;
@@ -681,33 +780,30 @@ public abstract class GeneratedMessageLite<
}
/** Check if a singular extension is present. */
- //@Override (Java 1.6 override semantics, but we must support 1.5)
- public final <Type> boolean hasExtension(
- final ExtensionLite<MessageType, Type> extension) {
+ @Override
+ public final <Type> boolean hasExtension(final ExtensionLite<MessageType, Type> extension) {
return instance.hasExtension(extension);
}
/** Get the number of elements in a repeated extension. */
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public final <Type> int getExtensionCount(
final ExtensionLite<MessageType, List<Type>> extension) {
return instance.getExtensionCount(extension);
}
/** Get the value of an extension. */
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
@SuppressWarnings("unchecked")
- public final <Type> Type getExtension(
- final ExtensionLite<MessageType, Type> extension) {
+ public final <Type> Type getExtension(final ExtensionLite<MessageType, Type> extension) {
return instance.getExtension(extension);
}
/** Get one element of a repeated extension. */
+ @Override
@SuppressWarnings("unchecked")
- //@Override (Java 1.6 override semantics, but we must support 1.5)
public final <Type> Type getExtension(
- final ExtensionLite<MessageType, List<Type>> extension,
- final int index) {
+ final ExtensionLite<MessageType, List<Type>> extension, final int index) {
return instance.getExtension(extension, index);
}
@@ -718,14 +814,14 @@ public abstract class GeneratedMessageLite<
public BuilderType clone() {
return super.clone();
}
-
+
/** Set the value of an extension. */
public final <Type> BuilderType setExtension(
final ExtensionLite<MessageType, Type> extension,
final Type value) {
GeneratedExtension<MessageType, Type> extensionLite =
checkIsLite(extension);
-
+
verifyExtensionContainingType(extensionLite);
copyOnWrite();
instance.extensions.setField(extensionLite.descriptor, extensionLite.toFieldSetType(value));
@@ -738,7 +834,7 @@ public abstract class GeneratedMessageLite<
final int index, final Type value) {
GeneratedExtension<MessageType, List<Type>> extensionLite =
checkIsLite(extension);
-
+
verifyExtensionContainingType(extensionLite);
copyOnWrite();
instance.extensions.setRepeatedField(
@@ -752,7 +848,7 @@ public abstract class GeneratedMessageLite<
final Type value) {
GeneratedExtension<MessageType, List<Type>> extensionLite =
checkIsLite(extension);
-
+
verifyExtensionContainingType(extensionLite);
copyOnWrite();
instance.extensions.addRepeatedField(
@@ -764,7 +860,7 @@ public abstract class GeneratedMessageLite<
public final <Type> BuilderType clearExtension(
final ExtensionLite<MessageType, ?> extension) {
GeneratedExtension<MessageType, ?> extensionLite = checkIsLite(extension);
-
+
verifyExtensionContainingType(extensionLite);
copyOnWrite();
instance.extensions.clearField(extensionLite.descriptor);
@@ -839,37 +935,44 @@ public abstract class GeneratedMessageLite<
final boolean isRepeated;
final boolean isPacked;
+ @Override
public int getNumber() {
return number;
}
+ @Override
public WireFormat.FieldType getLiteType() {
return type;
}
+ @Override
public WireFormat.JavaType getLiteJavaType() {
return type.getJavaType();
}
+ @Override
public boolean isRepeated() {
return isRepeated;
}
+ @Override
public boolean isPacked() {
return isPacked;
}
+ @Override
public Internal.EnumLiteMap<?> getEnumType() {
return enumTypeMap;
}
+ @Override
@SuppressWarnings("unchecked")
- public MessageLite.Builder internalMergeFrom(
- MessageLite.Builder to, MessageLite from) {
+ public MessageLite.Builder internalMergeFrom(MessageLite.Builder to, MessageLite from) {
return ((Builder) to).mergeFrom((GeneratedMessageLite) from);
}
+ @Override
public int compareTo(ExtensionDescriptor other) {
return number - other.number;
}
@@ -964,6 +1067,7 @@ public abstract class GeneratedMessageLite<
}
/** Get the field number. */
+ @Override
public int getNumber() {
return descriptor.getNumber();
}
@@ -973,6 +1077,7 @@ public abstract class GeneratedMessageLite<
* If the extension is an embedded message or group, returns the default
* instance of the message.
*/
+ @Override
public MessageLite getMessageDefaultInstance() {
return messageDefaultInstance;
}
@@ -1027,14 +1132,17 @@ public abstract class GeneratedMessageLite<
}
}
+ @Override
public FieldType getLiteType() {
return descriptor.getLiteType();
}
+ @Override
public boolean isRepeated() {
return descriptor.isRepeated;
}
+ @Override
public Type getDefaultValue() {
return defaultValue;
}
@@ -1044,7 +1152,12 @@ public abstract class GeneratedMessageLite<
* A serialized (serializable) form of the generated message. Stores the
* message as a class name and a byte array.
*/
- static final class SerializedForm implements Serializable {
+ protected static final class SerializedForm implements Serializable {
+
+ public static SerializedForm of(MessageLite message) {
+ return new SerializedForm(message);
+ }
+
private static final long serialVersionUID = 0L;
private final String messageClassName;
@@ -1078,7 +1191,7 @@ public abstract class GeneratedMessageLite<
} catch (ClassNotFoundException e) {
throw new RuntimeException("Unable to find proto buffer class: " + messageClassName, e);
} catch (NoSuchFieldException e) {
- throw new RuntimeException("Unable to find DEFAULT_INSTANCE in " + messageClassName, e);
+ return readResolveFallback();
} catch (SecurityException e) {
throw new RuntimeException("Unable to call DEFAULT_INSTANCE in " + messageClassName, e);
} catch (IllegalAccessException e) {
@@ -1087,18 +1200,35 @@ public abstract class GeneratedMessageLite<
throw new RuntimeException("Unable to understand proto buffer", e);
}
}
- }
- /**
- * Replaces this object in the output stream with a serialized form.
- * Part of Java's serialization magic. Generated sub-classes must override
- * this method by calling {@code return super.writeReplace();}
- * @return a SerializedForm of this message
- */
- protected Object writeReplace() throws ObjectStreamException {
- return new SerializedForm(this);
+ /**
+ * @deprecated from v3.0.0-beta-3+, for compatibility with v2.5.0 and v2.6.1 generated code.
+ */
+ @Deprecated
+ private Object readResolveFallback() throws ObjectStreamException {
+ try {
+ Class<?> messageClass = Class.forName(messageClassName);
+ java.lang.reflect.Field defaultInstanceField =
+ messageClass.getDeclaredField("defaultInstance");
+ defaultInstanceField.setAccessible(true);
+ MessageLite defaultInstance = (MessageLite) defaultInstanceField.get(null);
+ return defaultInstance.newBuilderForType()
+ .mergeFrom(asBytes)
+ .buildPartial();
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeException("Unable to find proto buffer class: " + messageClassName, e);
+ } catch (NoSuchFieldException e) {
+ throw new RuntimeException("Unable to find defaultInstance in " + messageClassName, e);
+ } catch (SecurityException e) {
+ throw new RuntimeException("Unable to call defaultInstance in " + messageClassName, e);
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException("Unable to call parsePartialFrom", e);
+ } catch (InvalidProtocolBufferException e) {
+ throw new RuntimeException("Unable to understand proto buffer", e);
+ }
+ }
}
-
+
/**
* Checks that the {@link Extension} is Lite and returns it as a
* {@link GeneratedExtension}.
@@ -1112,7 +1242,7 @@ public abstract class GeneratedMessageLite<
if (!extension.isLite()) {
throw new IllegalArgumentException("Expected a lite extension.");
}
-
+
return (GeneratedExtension<MessageType, T>) extension;
}
@@ -1125,29 +1255,71 @@ public abstract class GeneratedMessageLite<
T message, boolean shouldMemoize) {
return message.dynamicMethod(MethodToInvoke.IS_INITIALIZED, shouldMemoize) != null;
}
-
+
protected static final <T extends GeneratedMessageLite<T, ?>> void makeImmutable(T message) {
message.dynamicMethod(MethodToInvoke.MAKE_IMMUTABLE);
}
-
- /**
- * A static helper method for parsing a partial from input using the extension registry and the
- * instance.
- */
- static <T extends GeneratedMessageLite<T, ?>> T parsePartialFrom(
- T instance, CodedInputStream input, ExtensionRegistryLite extensionRegistry)
- throws InvalidProtocolBufferException {
- try {
- return (T) instance.dynamicMethod(
- MethodToInvoke.PARSE_PARTIAL_FROM, input, extensionRegistry);
- } catch (RuntimeException e) {
- if (e.getCause() instanceof InvalidProtocolBufferException) {
- throw (InvalidProtocolBufferException) e.getCause();
- }
- throw e;
- }
+
+ protected static IntList emptyIntList() {
+ return IntArrayList.emptyList();
+ }
+
+ protected static IntList mutableCopy(IntList list) {
+ int size = list.size();
+ return list.mutableCopyWithCapacity(
+ size == 0 ? AbstractProtobufList.DEFAULT_CAPACITY : size * 2);
+ }
+
+ protected static LongList emptyLongList() {
+ return LongArrayList.emptyList();
+ }
+
+ protected static LongList mutableCopy(LongList list) {
+ int size = list.size();
+ return list.mutableCopyWithCapacity(
+ size == 0 ? AbstractProtobufList.DEFAULT_CAPACITY : size * 2);
+ }
+
+ protected static FloatList emptyFloatList() {
+ return FloatArrayList.emptyList();
+ }
+
+ protected static FloatList mutableCopy(FloatList list) {
+ int size = list.size();
+ return list.mutableCopyWithCapacity(
+ size == 0 ? AbstractProtobufList.DEFAULT_CAPACITY : size * 2);
}
-
+
+ protected static DoubleList emptyDoubleList() {
+ return DoubleArrayList.emptyList();
+ }
+
+ protected static DoubleList mutableCopy(DoubleList list) {
+ int size = list.size();
+ return list.mutableCopyWithCapacity(
+ size == 0 ? AbstractProtobufList.DEFAULT_CAPACITY : size * 2);
+ }
+
+ protected static BooleanList emptyBooleanList() {
+ return BooleanArrayList.emptyList();
+ }
+
+ protected static BooleanList mutableCopy(BooleanList list) {
+ int size = list.size();
+ return list.mutableCopyWithCapacity(
+ size == 0 ? AbstractProtobufList.DEFAULT_CAPACITY : size * 2);
+ }
+
+ protected static <E> ProtobufList<E> emptyProtobufList() {
+ return ProtobufArrayList.emptyList();
+ }
+
+ protected static <E> ProtobufList<E> mutableCopy(ProtobufList<E> list) {
+ int size = list.size();
+ return list.mutableCopyWithCapacity(
+ size == 0 ? AbstractProtobufList.DEFAULT_CAPACITY : size * 2);
+ }
+
/**
* A {@link Parser} implementation that delegates to the default instance.
* <p>
@@ -1155,93 +1327,954 @@ public abstract class GeneratedMessageLite<
*/
protected static class DefaultInstanceBasedParser<T extends GeneratedMessageLite<T, ?>>
extends AbstractParser<T> {
-
+
private T defaultInstance;
-
+
public DefaultInstanceBasedParser(T defaultInstance) {
this.defaultInstance = defaultInstance;
}
-
+
@Override
public T parsePartialFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry)
throws InvalidProtocolBufferException {
return GeneratedMessageLite.parsePartialFrom(defaultInstance, input, extensionRegistry);
}
}
-
- protected static IntList newIntList() {
- return new IntArrayList();
+
+ /**
+ * A static helper method for parsing a partial from input using the extension registry and the
+ * instance.
+ */
+ // TODO(dweis): Should this verify that the last tag was 0?
+ static <T extends GeneratedMessageLite<T, ?>> T parsePartialFrom(
+ T instance, CodedInputStream input, ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException {
+ @SuppressWarnings("unchecked") // Guaranteed by protoc
+ T result = (T) instance.dynamicMethod(MethodToInvoke.NEW_MUTABLE_INSTANCE);
+ try {
+ result.dynamicMethod(MethodToInvoke.MERGE_FROM_STREAM, input, extensionRegistry);
+ result.makeImmutable();
+ } catch (RuntimeException e) {
+ if (e.getCause() instanceof InvalidProtocolBufferException) {
+ throw (InvalidProtocolBufferException) e.getCause();
+ }
+ throw e;
+ }
+ return result;
}
-
- protected static IntList newIntList(List<Integer> toCopy) {
- return new IntArrayList(toCopy);
+
+ protected static <T extends GeneratedMessageLite<T, ?>> T parsePartialFrom(
+ T defaultInstance,
+ CodedInputStream input)
+ throws InvalidProtocolBufferException {
+ return parsePartialFrom(defaultInstance, input, ExtensionRegistryLite.getEmptyRegistry());
}
-
- protected static IntList emptyIntList() {
- return IntArrayList.emptyList();
+
+ /**
+ * Helper method to check if message is initialized.
+ *
+ * @throws InvalidProtocolBufferException if it is not initialized.
+ * @return The message to check.
+ */
+ private static <T extends GeneratedMessageLite<T, ?>> T checkMessageInitialized(T message)
+ throws InvalidProtocolBufferException {
+ if (message != null && !message.isInitialized()) {
+ throw message.newUninitializedMessageException()
+ .asInvalidProtocolBufferException()
+ .setUnfinishedMessage(message);
+ }
+ return message;
}
-
- protected static LongList newLongList() {
- return new LongArrayList();
+
+ // Validates last tag.
+ protected static <T extends GeneratedMessageLite<T, ?>> T parseFrom(
+ T defaultInstance, ByteString data)
+ throws InvalidProtocolBufferException {
+ return checkMessageInitialized(
+ parseFrom(defaultInstance, data, ExtensionRegistryLite.getEmptyRegistry()));
}
-
- protected static LongList newLongList(List<Long> toCopy) {
- return new LongArrayList(toCopy);
+
+ // Validates last tag.
+ protected static <T extends GeneratedMessageLite<T, ?>> T parseFrom(
+ T defaultInstance, ByteString data, ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException {
+ return checkMessageInitialized(parsePartialFrom(defaultInstance, data, extensionRegistry));
}
-
- protected static LongList emptyLongList() {
- return LongArrayList.emptyList();
+
+ // This is a special case since we want to verify that the last tag is 0. We assume we exhaust the
+ // ByteString.
+ private static <T extends GeneratedMessageLite<T, ?>> T parsePartialFrom(
+ T defaultInstance, ByteString data, ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException {
+ T message;
+ try {
+ CodedInputStream input = data.newCodedInput();
+ message = parsePartialFrom(defaultInstance, input, extensionRegistry);
+ try {
+ input.checkLastTagWas(0);
+ } catch (InvalidProtocolBufferException e) {
+ throw e.setUnfinishedMessage(message);
+ }
+ return message;
+ } catch (InvalidProtocolBufferException e) {
+ throw e;
+ }
}
-
- protected static FloatList newFloatList() {
- return new FloatArrayList();
+
+ // This is a special case since we want to verify that the last tag is 0. We assume we exhaust the
+ // ByteString.
+ private static <T extends GeneratedMessageLite<T, ?>> T parsePartialFrom(
+ T defaultInstance, byte[] data, ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException {
+ T message;
+ try {
+ CodedInputStream input = CodedInputStream.newInstance(data);
+ message = parsePartialFrom(defaultInstance, input, extensionRegistry);
+ try {
+ input.checkLastTagWas(0);
+ } catch (InvalidProtocolBufferException e) {
+ throw e.setUnfinishedMessage(message);
+ }
+ return message;
+ } catch (InvalidProtocolBufferException e) {
+ throw e;
+ }
}
-
- protected static FloatList newFloatList(List<Float> toCopy) {
- return new FloatArrayList(toCopy);
+
+ // Validates last tag.
+ protected static <T extends GeneratedMessageLite<T, ?>> T parseFrom(
+ T defaultInstance, byte[] data)
+ throws InvalidProtocolBufferException {
+ return checkMessageInitialized(
+ parsePartialFrom(defaultInstance, data, ExtensionRegistryLite.getEmptyRegistry()));
}
-
- protected static FloatList emptyFloatList() {
- return FloatArrayList.emptyList();
+
+ // Validates last tag.
+ protected static <T extends GeneratedMessageLite<T, ?>> T parseFrom(
+ T defaultInstance, byte[] data, ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException {
+ return checkMessageInitialized(parsePartialFrom(defaultInstance, data, extensionRegistry));
}
-
- protected static DoubleList newDoubleList() {
- return new DoubleArrayList();
+
+ // Does not validate last tag.
+ protected static <T extends GeneratedMessageLite<T, ?>> T parseFrom(
+ T defaultInstance, InputStream input)
+ throws InvalidProtocolBufferException {
+ return checkMessageInitialized(
+ parsePartialFrom(defaultInstance, CodedInputStream.newInstance(input),
+ ExtensionRegistryLite.getEmptyRegistry()));
}
-
- protected static DoubleList newDoubleList(List<Double> toCopy) {
- return new DoubleArrayList(toCopy);
+
+ // Does not validate last tag.
+ protected static <T extends GeneratedMessageLite<T, ?>> T parseFrom(
+ T defaultInstance, InputStream input, ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException {
+ return checkMessageInitialized(
+ parsePartialFrom(defaultInstance, CodedInputStream.newInstance(input), extensionRegistry));
}
-
- protected static DoubleList emptyDoubleList() {
- return DoubleArrayList.emptyList();
+
+ // Does not validate last tag.
+ protected static <T extends GeneratedMessageLite<T, ?>> T parseFrom(
+ T defaultInstance, CodedInputStream input)
+ throws InvalidProtocolBufferException {
+ return parseFrom(defaultInstance, input, ExtensionRegistryLite.getEmptyRegistry());
}
-
- protected static BooleanList newBooleanList() {
- return new BooleanArrayList();
+
+ // Does not validate last tag.
+ protected static <T extends GeneratedMessageLite<T, ?>> T parseFrom(
+ T defaultInstance, CodedInputStream input, ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException {
+ return checkMessageInitialized(
+ parsePartialFrom(defaultInstance, input, extensionRegistry));
}
-
- protected static BooleanList newBooleanList(List<Boolean> toCopy) {
- return new BooleanArrayList(toCopy);
+
+ // Validates last tag.
+ protected static <T extends GeneratedMessageLite<T, ?>> T parseDelimitedFrom(
+ T defaultInstance, InputStream input)
+ throws InvalidProtocolBufferException {
+ return checkMessageInitialized(
+ parsePartialDelimitedFrom(defaultInstance, input,
+ ExtensionRegistryLite.getEmptyRegistry()));
}
-
- protected static BooleanList emptyBooleanList() {
- return BooleanArrayList.emptyList();
+
+ // Validates last tag.
+ protected static <T extends GeneratedMessageLite<T, ?>> T parseDelimitedFrom(
+ T defaultInstance, InputStream input, ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException {
+ return checkMessageInitialized(
+ parsePartialDelimitedFrom(defaultInstance, input, extensionRegistry));
}
-
- protected static <E> ProtobufList<E> newProtobufList() {
- return new ProtobufArrayList<E>();
+
+ private static <T extends GeneratedMessageLite<T, ?>> T parsePartialDelimitedFrom(
+ T defaultInstance,
+ InputStream input,
+ ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException {
+ int size;
+ try {
+ int firstByte = input.read();
+ if (firstByte == -1) {
+ return null;
+ }
+ size = CodedInputStream.readRawVarint32(firstByte, input);
+ } catch (IOException e) {
+ throw new InvalidProtocolBufferException(e.getMessage());
+ }
+ InputStream limitedInput = new LimitedInputStream(input, size);
+ CodedInputStream codedInput = CodedInputStream.newInstance(limitedInput);
+ T message = parsePartialFrom(defaultInstance, codedInput, extensionRegistry);
+ try {
+ codedInput.checkLastTagWas(0);
+ } catch (InvalidProtocolBufferException e) {
+ throw e.setUnfinishedMessage(message);
+ }
+ return message;
}
-
- protected static <E> ProtobufList<E> newProtobufList(List<E> toCopy) {
- return new ProtobufArrayList<E>(toCopy);
+
+ /**
+ * An abstract visitor that the generated code calls into that we use to implement various
+ * features. Fields that are not members of oneofs are always visited. Members of a oneof are only
+ * visited when they are the set oneof case value on the "other" proto. The visitOneofNotSet
+ * method is invoked if other's oneof case is not set.
+ */
+ protected interface Visitor {
+ boolean visitBoolean(boolean minePresent, boolean mine, boolean otherPresent, boolean other);
+ int visitInt(boolean minePresent, int mine, boolean otherPresent, int other);
+ double visitDouble(boolean minePresent, double mine, boolean otherPresent, double other);
+ float visitFloat(boolean minePresent, float mine, boolean otherPresent, float other);
+ long visitLong(boolean minePresent, long mine, boolean otherPresent, long other);
+ String visitString(boolean minePresent, String mine, boolean otherPresent, String other);
+ ByteString visitByteString(
+ boolean minePresent, ByteString mine, boolean otherPresent, ByteString other);
+
+ Object visitOneofBoolean(boolean minePresent, Object mine, Object other);
+ Object visitOneofInt(boolean minePresent, Object mine, Object other);
+ Object visitOneofDouble(boolean minePresent, Object mine, Object other);
+ Object visitOneofFloat(boolean minePresent, Object mine, Object other);
+ Object visitOneofLong(boolean minePresent, Object mine, Object other);
+ Object visitOneofString(boolean minePresent, Object mine, Object other);
+ Object visitOneofByteString(boolean minePresent, Object mine, Object other);
+ Object visitOneofLazyMessage(boolean minePresent, Object mine, Object other);
+ Object visitOneofMessage(boolean minePresent, Object mine, Object other);
+ void visitOneofNotSet(boolean minePresent);
+
+ /**
+ * Message fields use null sentinals.
+ */
+ <T extends MessageLite> T visitMessage(T mine, T other);
+ LazyFieldLite visitLazyMessage(LazyFieldLite mine, LazyFieldLite other);
+
+ <T> ProtobufList<T> visitList(ProtobufList<T> mine, ProtobufList<T> other);
+ BooleanList visitBooleanList(BooleanList mine, BooleanList other);
+ IntList visitIntList(IntList mine, IntList other);
+ DoubleList visitDoubleList(DoubleList mine, DoubleList other);
+ FloatList visitFloatList(FloatList mine, FloatList other);
+ LongList visitLongList(LongList mine, LongList other);
+ FieldSet<ExtensionDescriptor> visitExtensions(
+ FieldSet<ExtensionDescriptor> mine, FieldSet<ExtensionDescriptor> other);
+ UnknownFieldSetLite visitUnknownFields(UnknownFieldSetLite mine, UnknownFieldSetLite other);
+ <K, V> MapFieldLite<K, V> visitMap(MapFieldLite<K, V> mine, MapFieldLite<K, V> other);
}
-
- protected static <E> ProtobufList<E> emptyProtobufList() {
- return ProtobufArrayList.emptyList();
+
+ /**
+ * Implements equals. Throws a {@link NotEqualsException} when not equal.
+ */
+ static class EqualsVisitor implements Visitor {
+
+ static final class NotEqualsException extends RuntimeException {}
+
+ static final EqualsVisitor INSTANCE = new EqualsVisitor();
+
+ static final NotEqualsException NOT_EQUALS = new NotEqualsException();
+
+ private EqualsVisitor() {}
+
+ @Override
+ public boolean visitBoolean(
+ boolean minePresent, boolean mine, boolean otherPresent, boolean other) {
+ if (minePresent != otherPresent || mine != other) {
+ throw NOT_EQUALS;
+ }
+ return mine;
+ }
+
+ @Override
+ public int visitInt(boolean minePresent, int mine, boolean otherPresent, int other) {
+ if (minePresent != otherPresent || mine != other) {
+ throw NOT_EQUALS;
+ }
+ return mine;
+ }
+
+ @Override
+ public double visitDouble(
+ boolean minePresent, double mine, boolean otherPresent, double other) {
+ if (minePresent != otherPresent || mine != other) {
+ throw NOT_EQUALS;
+ }
+ return mine;
+ }
+
+ @Override
+ public float visitFloat(boolean minePresent, float mine, boolean otherPresent, float other) {
+ if (minePresent != otherPresent || mine != other) {
+ throw NOT_EQUALS;
+ }
+ return mine;
+ }
+
+ @Override
+ public long visitLong(boolean minePresent, long mine, boolean otherPresent, long other) {
+ if (minePresent != otherPresent || mine != other) {
+ throw NOT_EQUALS;
+ }
+ return mine;
+ }
+
+ @Override
+ public String visitString(
+ boolean minePresent, String mine, boolean otherPresent, String other) {
+ if (minePresent != otherPresent || !mine.equals(other)) {
+ throw NOT_EQUALS;
+ }
+ return mine;
+ }
+
+ @Override
+ public ByteString visitByteString(
+ boolean minePresent, ByteString mine, boolean otherPresent, ByteString other) {
+ if (minePresent != otherPresent || !mine.equals(other)) {
+ throw NOT_EQUALS;
+ }
+ return mine;
+ }
+
+ @Override
+ public Object visitOneofBoolean(boolean minePresent, Object mine, Object other) {
+ if (minePresent && mine.equals(other)) {
+ return mine;
+ }
+ throw NOT_EQUALS;
+ }
+
+ @Override
+ public Object visitOneofInt(boolean minePresent, Object mine, Object other) {
+ if (minePresent && mine.equals(other)) {
+ return mine;
+ }
+ throw NOT_EQUALS;
+ }
+
+ @Override
+ public Object visitOneofDouble(boolean minePresent, Object mine, Object other) {
+ if (minePresent && mine.equals(other)) {
+ return mine;
+ }
+ throw NOT_EQUALS;
+ }
+
+ @Override
+ public Object visitOneofFloat(boolean minePresent, Object mine, Object other) {
+ if (minePresent && mine.equals(other)) {
+ return mine;
+ }
+ throw NOT_EQUALS;
+ }
+
+ @Override
+ public Object visitOneofLong(boolean minePresent, Object mine, Object other) {
+ if (minePresent && mine.equals(other)) {
+ return mine;
+ }
+ throw NOT_EQUALS;
+ }
+
+ @Override
+ public Object visitOneofString(boolean minePresent, Object mine, Object other) {
+ if (minePresent && mine.equals(other)) {
+ return mine;
+ }
+ throw NOT_EQUALS;
+ }
+
+ @Override
+ public Object visitOneofByteString(boolean minePresent, Object mine, Object other) {
+ if (minePresent && mine.equals(other)) {
+ return mine;
+ }
+ throw NOT_EQUALS;
+ }
+
+ @Override
+ public Object visitOneofLazyMessage(boolean minePresent, Object mine, Object other) {
+ if (minePresent && mine.equals(other)) {
+ return mine;
+ }
+ throw NOT_EQUALS;
+ }
+
+ @Override
+ public Object visitOneofMessage(boolean minePresent, Object mine, Object other) {
+ if (minePresent && ((GeneratedMessageLite<?, ?>) mine).equals(this, (MessageLite) other)) {
+ return mine;
+ }
+ throw NOT_EQUALS;
+ }
+
+ @Override
+ public void visitOneofNotSet(boolean minePresent) {
+ if (minePresent) {
+ throw NOT_EQUALS;
+ }
+ }
+
+ @Override
+ public <T extends MessageLite> T visitMessage(T mine, T other) {
+ if (mine == null && other == null) {
+ return null;
+ }
+
+ if (mine == null || other == null) {
+ throw NOT_EQUALS;
+ }
+
+ ((GeneratedMessageLite<?, ?>) mine).equals(this, other);
+
+ return mine;
+ }
+
+ @Override
+ public LazyFieldLite visitLazyMessage(
+ LazyFieldLite mine, LazyFieldLite other) {
+ if (mine == null && other == null) {
+ return null;
+ }
+ if (mine == null || other == null) {
+ throw NOT_EQUALS;
+ }
+ if (mine.equals(other)) {
+ return mine;
+ }
+ throw NOT_EQUALS;
+ }
+
+ @Override
+ public <T> ProtobufList<T> visitList(ProtobufList<T> mine, ProtobufList<T> other) {
+ if (!mine.equals(other)) {
+ throw NOT_EQUALS;
+ }
+ return mine;
+ }
+
+ @Override
+ public BooleanList visitBooleanList(BooleanList mine, BooleanList other) {
+ if (!mine.equals(other)) {
+ throw NOT_EQUALS;
+ }
+ return mine;
+ }
+
+ @Override
+ public IntList visitIntList(IntList mine, IntList other) {
+ if (!mine.equals(other)) {
+ throw NOT_EQUALS;
+ }
+ return mine;
+ }
+
+ @Override
+ public DoubleList visitDoubleList(DoubleList mine, DoubleList other) {
+ if (!mine.equals(other)) {
+ throw NOT_EQUALS;
+ }
+ return mine;
+ }
+
+ @Override
+ public FloatList visitFloatList(FloatList mine, FloatList other) {
+ if (!mine.equals(other)) {
+ throw NOT_EQUALS;
+ }
+ return mine;
+ }
+
+ @Override
+ public LongList visitLongList(LongList mine, LongList other) {
+ if (!mine.equals(other)) {
+ throw NOT_EQUALS;
+ }
+ return mine;
+ }
+
+ @Override
+ public FieldSet<ExtensionDescriptor> visitExtensions(
+ FieldSet<ExtensionDescriptor> mine,
+ FieldSet<ExtensionDescriptor> other) {
+ if (!mine.equals(other)) {
+ throw NOT_EQUALS;
+ }
+ return mine;
+ }
+
+ @Override
+ public UnknownFieldSetLite visitUnknownFields(
+ UnknownFieldSetLite mine,
+ UnknownFieldSetLite other) {
+ if (!mine.equals(other)) {
+ throw NOT_EQUALS;
+ }
+ return mine;
+ }
+
+ @Override
+ public <K, V> MapFieldLite<K, V> visitMap(MapFieldLite<K, V> mine, MapFieldLite<K, V> other) {
+ if (!mine.equals(other)) {
+ throw NOT_EQUALS;
+ }
+ return mine;
+ }
}
-
- protected static LazyStringArrayList emptyLazyStringArrayList() {
- return LazyStringArrayList.emptyList();
+
+ /**
+ * Implements hashCode by accumulating state.
+ */
+ private static class HashCodeVisitor implements Visitor {
+
+ // The caller must ensure that the visitor is invoked parameterized with this and this such that
+ // other is this. This is required due to how oneof cases are handled. See the class comment
+ // on Visitor for more information.
+
+ private int hashCode = 0;
+
+ @Override
+ public boolean visitBoolean(
+ boolean minePresent, boolean mine, boolean otherPresent, boolean other) {
+ hashCode = (53 * hashCode) + Internal.hashBoolean(mine);
+ return mine;
+ }
+
+ @Override
+ public int visitInt(boolean minePresent, int mine, boolean otherPresent, int other) {
+ hashCode = (53 * hashCode) + mine;
+ return mine;
+ }
+
+ @Override
+ public double visitDouble(
+ boolean minePresent, double mine, boolean otherPresent, double other) {
+ hashCode = (53 * hashCode) + Internal.hashLong(Double.doubleToLongBits(mine));
+ return mine;
+ }
+
+ @Override
+ public float visitFloat(boolean minePresent, float mine, boolean otherPresent, float other) {
+ hashCode = (53 * hashCode) + Float.floatToIntBits(mine);
+ return mine;
+ }
+
+ @Override
+ public long visitLong(boolean minePresent, long mine, boolean otherPresent, long other) {
+ hashCode = (53 * hashCode) + Internal.hashLong(mine);
+ return mine;
+ }
+
+ @Override
+ public String visitString(
+ boolean minePresent, String mine, boolean otherPresent, String other) {
+ hashCode = (53 * hashCode) + mine.hashCode();
+ return mine;
+ }
+
+ @Override
+ public ByteString visitByteString(
+ boolean minePresent, ByteString mine, boolean otherPresent, ByteString other) {
+ hashCode = (53 * hashCode) + mine.hashCode();
+ return mine;
+ }
+
+ @Override
+ public Object visitOneofBoolean(boolean minePresent, Object mine, Object other) {
+ hashCode = (53 * hashCode) + Internal.hashBoolean(((Boolean) mine));
+ return mine;
+ }
+
+ @Override
+ public Object visitOneofInt(boolean minePresent, Object mine, Object other) {
+ hashCode = (53 * hashCode) + (Integer) mine;
+ return mine;
+ }
+
+ @Override
+ public Object visitOneofDouble(boolean minePresent, Object mine, Object other) {
+ hashCode = (53 * hashCode) + Internal.hashLong(Double.doubleToLongBits((Double) mine));
+ return mine;
+ }
+
+ @Override
+ public Object visitOneofFloat(boolean minePresent, Object mine, Object other) {
+ hashCode = (53 * hashCode) + Float.floatToIntBits((Float) mine);
+ return mine;
+ }
+
+ @Override
+ public Object visitOneofLong(boolean minePresent, Object mine, Object other) {
+ hashCode = (53 * hashCode) + Internal.hashLong((Long) mine);
+ return mine;
+ }
+
+ @Override
+ public Object visitOneofString(boolean minePresent, Object mine, Object other) {
+ hashCode = (53 * hashCode) + mine.hashCode();
+ return mine;
+ }
+
+ @Override
+ public Object visitOneofByteString(boolean minePresent, Object mine, Object other) {
+ hashCode = (53 * hashCode) + mine.hashCode();
+ return mine;
+ }
+
+ @Override
+ public Object visitOneofLazyMessage(boolean minePresent, Object mine, Object other) {
+ hashCode = (53 * hashCode) + mine.hashCode();
+ return mine;
+ }
+
+ @Override
+ public Object visitOneofMessage(boolean minePresent, Object mine, Object other) {
+ return visitMessage((MessageLite) mine, (MessageLite) other);
+ }
+
+ @Override
+ public void visitOneofNotSet(boolean minePresent) {
+ if (minePresent) {
+ throw new IllegalStateException(); // Can't happen if other == this.
+ }
+ }
+
+ @Override
+ public <T extends MessageLite> T visitMessage(T mine, T other) {
+ final int protoHash;
+ if (mine != null) {
+ if (mine instanceof GeneratedMessageLite) {
+ protoHash = ((GeneratedMessageLite) mine).hashCode(this);
+ } else {
+ protoHash = mine.hashCode();
+ }
+ } else {
+ protoHash = 37;
+ }
+ hashCode = (53 * hashCode) + protoHash;
+ return mine;
+ }
+
+ @Override
+ public LazyFieldLite visitLazyMessage(LazyFieldLite mine, LazyFieldLite other) {
+ final int protoHash;
+ if (mine != null) {
+ protoHash = mine.hashCode();
+ } else {
+ protoHash = 37;
+ }
+ hashCode = (53 * hashCode) + protoHash;
+ return mine;
+ }
+
+ @Override
+ public <T> ProtobufList<T> visitList(ProtobufList<T> mine, ProtobufList<T> other) {
+ hashCode = (53 * hashCode) + mine.hashCode();
+ return mine;
+ }
+
+ @Override
+ public BooleanList visitBooleanList(BooleanList mine, BooleanList other) {
+ hashCode = (53 * hashCode) + mine.hashCode();
+ return mine;
+ }
+
+ @Override
+ public IntList visitIntList(IntList mine, IntList other) {
+ hashCode = (53 * hashCode) + mine.hashCode();
+ return mine;
+ }
+
+ @Override
+ public DoubleList visitDoubleList(DoubleList mine, DoubleList other) {
+ hashCode = (53 * hashCode) + mine.hashCode();
+ return mine;
+ }
+
+ @Override
+ public FloatList visitFloatList(FloatList mine, FloatList other) {
+ hashCode = (53 * hashCode) + mine.hashCode();
+ return mine;
+ }
+
+ @Override
+ public LongList visitLongList(LongList mine, LongList other) {
+ hashCode = (53 * hashCode) + mine.hashCode();
+ return mine;
+ }
+
+ @Override
+ public FieldSet<ExtensionDescriptor> visitExtensions(
+ FieldSet<ExtensionDescriptor> mine,
+ FieldSet<ExtensionDescriptor> other) {
+ hashCode = (53 * hashCode) + mine.hashCode();
+ return mine;
+ }
+
+ @Override
+ public UnknownFieldSetLite visitUnknownFields(
+ UnknownFieldSetLite mine,
+ UnknownFieldSetLite other) {
+ hashCode = (53 * hashCode) + mine.hashCode();
+ return mine;
+ }
+
+ @Override
+ public <K, V> MapFieldLite<K, V> visitMap(MapFieldLite<K, V> mine, MapFieldLite<K, V> other) {
+ hashCode = (53 * hashCode) + mine.hashCode();
+ return mine;
+ }
+ }
+
+ /**
+ * Implements field merging semantics over the visitor interface.
+ */
+ protected static class MergeFromVisitor implements Visitor {
+
+ public static final MergeFromVisitor INSTANCE = new MergeFromVisitor();
+
+ private MergeFromVisitor() {}
+
+ @Override
+ public boolean visitBoolean(
+ boolean minePresent, boolean mine, boolean otherPresent, boolean other) {
+ return otherPresent ? other : mine;
+ }
+
+ @Override
+ public int visitInt(boolean minePresent, int mine, boolean otherPresent, int other) {
+ return otherPresent ? other : mine;
+ }
+
+ @Override
+ public double visitDouble(
+ boolean minePresent, double mine, boolean otherPresent, double other) {
+ return otherPresent ? other : mine;
+ }
+
+ @Override
+ public float visitFloat(boolean minePresent, float mine, boolean otherPresent, float other) {
+ return otherPresent ? other : mine;
+ }
+
+ @Override
+ public long visitLong(boolean minePresent, long mine, boolean otherPresent, long other) {
+ return otherPresent ? other : mine;
+ }
+
+ @Override
+ public String visitString(
+ boolean minePresent, String mine, boolean otherPresent, String other) {
+ return otherPresent ? other : mine;
+ }
+
+ @Override
+ public ByteString visitByteString(
+ boolean minePresent, ByteString mine, boolean otherPresent, ByteString other) {
+ return otherPresent ? other : mine;
+ }
+
+ @Override
+ public Object visitOneofBoolean(boolean minePresent, Object mine, Object other) {
+ return other;
+ }
+
+ @Override
+ public Object visitOneofInt(boolean minePresent, Object mine, Object other) {
+ return other;
+ }
+
+ @Override
+ public Object visitOneofDouble(boolean minePresent, Object mine, Object other) {
+ return other;
+ }
+
+ @Override
+ public Object visitOneofFloat(boolean minePresent, Object mine, Object other) {
+ return other;
+ }
+
+ @Override
+ public Object visitOneofLong(boolean minePresent, Object mine, Object other) {
+ return other;
+ }
+
+ @Override
+ public Object visitOneofString(boolean minePresent, Object mine, Object other) {
+ return other;
+ }
+
+ @Override
+ public Object visitOneofByteString(boolean minePresent, Object mine, Object other) {
+ return other;
+ }
+
+ @Override
+ public Object visitOneofLazyMessage(boolean minePresent, Object mine, Object other) {
+ LazyFieldLite lazy = minePresent ? (LazyFieldLite) mine : new LazyFieldLite();
+ lazy.merge((LazyFieldLite) other);
+ return lazy;
+ }
+
+ @Override
+ public Object visitOneofMessage(boolean minePresent, Object mine, Object other) {
+ if (minePresent) {
+ return visitMessage((MessageLite) mine, (MessageLite) other);
+ }
+ return other;
+ }
+
+ @Override
+ public void visitOneofNotSet(boolean minePresent) {
+ return;
+ }
+
+ @SuppressWarnings("unchecked") // Guaranteed by runtime.
+ @Override
+ public <T extends MessageLite> T visitMessage(T mine, T other) {
+ if (mine != null && other != null) {
+ return (T) mine.toBuilder().mergeFrom(other).build();
+ }
+
+ return mine != null ? mine : other;
+ }
+
+ @Override
+ public LazyFieldLite visitLazyMessage(LazyFieldLite mine, LazyFieldLite other) {
+ if (other != null) {
+ if (mine == null) {
+ mine = new LazyFieldLite();
+ }
+ mine.merge(other);
+ }
+ return mine;
+ }
+
+ @Override
+ public <T> ProtobufList<T> visitList(ProtobufList<T> mine, ProtobufList<T> other) {
+ int size = mine.size();
+ int otherSize = other.size();
+ if (size > 0 && otherSize > 0) {
+ if (!mine.isModifiable()) {
+ mine = mine.mutableCopyWithCapacity(size + otherSize);
+ }
+ mine.addAll(other);
+ }
+
+ return size > 0 ? mine : other;
+ }
+
+ @Override
+ public BooleanList visitBooleanList(BooleanList mine, BooleanList other) {
+ int size = mine.size();
+ int otherSize = other.size();
+ if (size > 0 && otherSize > 0) {
+ if (!mine.isModifiable()) {
+ mine = mine.mutableCopyWithCapacity(size + otherSize);
+ }
+ mine.addAll(other);
+ }
+
+ return size > 0 ? mine : other;
+ }
+
+ @Override
+ public IntList visitIntList(IntList mine, IntList other) {
+ int size = mine.size();
+ int otherSize = other.size();
+ if (size > 0 && otherSize > 0) {
+ if (!mine.isModifiable()) {
+ mine = mine.mutableCopyWithCapacity(size + otherSize);
+ }
+ mine.addAll(other);
+ }
+
+ return size > 0 ? mine : other;
+ }
+
+ @Override
+ public DoubleList visitDoubleList(DoubleList mine, DoubleList other) {
+ int size = mine.size();
+ int otherSize = other.size();
+ if (size > 0 && otherSize > 0) {
+ if (!mine.isModifiable()) {
+ mine = mine.mutableCopyWithCapacity(size + otherSize);
+ }
+ mine.addAll(other);
+ }
+
+ return size > 0 ? mine : other;
+ }
+
+ @Override
+ public FloatList visitFloatList(FloatList mine, FloatList other) {
+ int size = mine.size();
+ int otherSize = other.size();
+ if (size > 0 && otherSize > 0) {
+ if (!mine.isModifiable()) {
+ mine = mine.mutableCopyWithCapacity(size + otherSize);
+ }
+ mine.addAll(other);
+ }
+
+ return size > 0 ? mine : other;
+ }
+
+ @Override
+ public LongList visitLongList(LongList mine, LongList other) {
+ int size = mine.size();
+ int otherSize = other.size();
+ if (size > 0 && otherSize > 0) {
+ if (!mine.isModifiable()) {
+ mine = mine.mutableCopyWithCapacity(size + otherSize);
+ }
+ mine.addAll(other);
+ }
+
+ return size > 0 ? mine : other;
+ }
+
+ @Override
+ public FieldSet<ExtensionDescriptor> visitExtensions(
+ FieldSet<ExtensionDescriptor> mine,
+ FieldSet<ExtensionDescriptor> other) {
+ if (mine.isImmutable()) {
+ mine = mine.clone();
+ }
+ mine.mergeFrom(other);
+ return mine;
+ }
+
+ @Override
+ public UnknownFieldSetLite visitUnknownFields(
+ UnknownFieldSetLite mine,
+ UnknownFieldSetLite other) {
+ return other == UnknownFieldSetLite.getDefaultInstance()
+ ? mine : UnknownFieldSetLite.mutableCopyOf(mine, other);
+ }
+
+ @Override
+ public <K, V> MapFieldLite<K, V> visitMap(MapFieldLite<K, V> mine, MapFieldLite<K, V> other) {
+ if (!other.isEmpty()) {
+ if (!mine.isMutable()) {
+ mine = mine.mutableCopy();
+ }
+ mine.mergeFrom(other);
+ }
+ return mine;
+ }
}
}
diff --git a/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java b/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java
new file mode 100644
index 00000000..5dfe7ff7
--- /dev/null
+++ b/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java
@@ -0,0 +1,2716 @@
+// 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.
+
+package com.google.protobuf;
+
+import com.google.protobuf.Descriptors.Descriptor;
+import com.google.protobuf.Descriptors.EnumDescriptor;
+import com.google.protobuf.Descriptors.EnumValueDescriptor;
+import com.google.protobuf.Descriptors.FieldDescriptor;
+import com.google.protobuf.Descriptors.FileDescriptor;
+import com.google.protobuf.Descriptors.OneofDescriptor;
+import com.google.protobuf.GeneratedMessage.GeneratedExtension;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * All generated protocol message classes extend this class. This class
+ * implements most of the Message and Builder interfaces using Java reflection.
+ * Users can ignore this class and pretend that generated messages implement
+ * the Message interface directly.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public abstract class GeneratedMessageV3 extends AbstractMessage
+ implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * For testing. Allows a test to disable the optimization that avoids using
+ * field builders for nested messages until they are requested. By disabling
+ * this optimization, existing tests can be reused to test the field builders.
+ */
+ protected static boolean alwaysUseFieldBuilders = false;
+
+ /** For use by generated code only. */
+ protected UnknownFieldSet unknownFields;
+
+ protected GeneratedMessageV3() {
+ unknownFields = UnknownFieldSet.getDefaultInstance();
+ }
+
+ protected GeneratedMessageV3(Builder<?> builder) {
+ unknownFields = builder.getUnknownFields();
+ }
+
+ @Override
+ public Parser<? extends GeneratedMessageV3> getParserForType() {
+ throw new UnsupportedOperationException(
+ "This is supposed to be overridden by subclasses.");
+ }
+
+ /**
+ * For testing. Allows a test to disable the optimization that avoids using
+ * field builders for nested messages until they are requested. By disabling
+ * this optimization, existing tests can be reused to test the field builders.
+ * See {@link RepeatedFieldBuilder} and {@link SingleFieldBuilder}.
+ */
+ static void enableAlwaysUseFieldBuildersForTesting() {
+ alwaysUseFieldBuilders = true;
+ }
+
+ /**
+ * Get the FieldAccessorTable for this type. We can't have the message
+ * class pass this in to the constructor because of bootstrapping trouble
+ * with DescriptorProtos.
+ */
+ protected abstract FieldAccessorTable internalGetFieldAccessorTable();
+
+ @Override
+ public Descriptor getDescriptorForType() {
+ return internalGetFieldAccessorTable().descriptor;
+ }
+
+ /**
+ * Internal helper to return a modifiable map containing all the fields.
+ * The returned Map is modifialbe so that the caller can add additional
+ * extension fields to implement {@link #getAllFields()}.
+ *
+ * @param getBytesForString whether to generate ByteString for string fields
+ */
+ private Map<FieldDescriptor, Object> getAllFieldsMutable(
+ boolean getBytesForString) {
+ final TreeMap<FieldDescriptor, Object> result =
+ new TreeMap<FieldDescriptor, Object>();
+ final Descriptor descriptor = internalGetFieldAccessorTable().descriptor;
+ final List<FieldDescriptor> fields = descriptor.getFields();
+
+ for (int i = 0; i < fields.size(); i++) {
+ FieldDescriptor field = fields.get(i);
+ final OneofDescriptor oneofDescriptor = field.getContainingOneof();
+
+ /*
+ * If the field is part of a Oneof, then at maximum one field in the Oneof is set
+ * and it is not repeated. There is no need to iterate through the others.
+ */
+ if (oneofDescriptor != null) {
+ // Skip other fields in the Oneof we know are not set
+ i += oneofDescriptor.getFieldCount() - 1;
+ if (!hasOneof(oneofDescriptor)) {
+ // If no field is set in the Oneof, skip all the fields in the Oneof
+ continue;
+ }
+ // Get the pointer to the only field which is set in the Oneof
+ field = getOneofFieldDescriptor(oneofDescriptor);
+ } else {
+ // If we are not in a Oneof, we need to check if the field is set and if it is repeated
+ if (field.isRepeated()) {
+ final List<?> value = (List<?>) getField(field);
+ if (!value.isEmpty()) {
+ result.put(field, value);
+ }
+ continue;
+ }
+ if (!hasField(field)) {
+ continue;
+ }
+ }
+ // Add the field to the map
+ if (getBytesForString && field.getJavaType() == FieldDescriptor.JavaType.STRING) {
+ result.put(field, getFieldRaw(field));
+ } else {
+ result.put(field, getField(field));
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public boolean isInitialized() {
+ for (final FieldDescriptor field : getDescriptorForType().getFields()) {
+ // Check that all required fields are present.
+ if (field.isRequired()) {
+ if (!hasField(field)) {
+ return false;
+ }
+ }
+ // Check that embedded messages are initialized.
+ if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+ if (field.isRepeated()) {
+ @SuppressWarnings("unchecked") final
+ List<Message> messageList = (List<Message>) getField(field);
+ for (final Message element : messageList) {
+ if (!element.isInitialized()) {
+ return false;
+ }
+ }
+ } else {
+ if (hasField(field) && !((Message) getField(field)).isInitialized()) {
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+ }
+
+ @Override
+ public Map<FieldDescriptor, Object> getAllFields() {
+ return Collections.unmodifiableMap(
+ getAllFieldsMutable(/* getBytesForString = */ false));
+ }
+
+ /**
+ * Returns a collection of all the fields in this message which are set
+ * and their corresponding values. A singular ("required" or "optional")
+ * field is set iff hasField() returns true for that field. A "repeated"
+ * field is set iff getRepeatedFieldCount() is greater than zero. The
+ * values are exactly what would be returned by calling
+ * {@link #getFieldRaw(Descriptors.FieldDescriptor)} for each field. The map
+ * is guaranteed to be a sorted map, so iterating over it will return fields
+ * in order by field number.
+ */
+ Map<FieldDescriptor, Object> getAllFieldsRaw() {
+ return Collections.unmodifiableMap(
+ getAllFieldsMutable(/* getBytesForString = */ true));
+ }
+
+ @Override
+ public boolean hasOneof(final OneofDescriptor oneof) {
+ return internalGetFieldAccessorTable().getOneof(oneof).has(this);
+ }
+
+ @Override
+ public FieldDescriptor getOneofFieldDescriptor(final OneofDescriptor oneof) {
+ return internalGetFieldAccessorTable().getOneof(oneof).get(this);
+ }
+
+ @Override
+ public boolean hasField(final FieldDescriptor field) {
+ return internalGetFieldAccessorTable().getField(field).has(this);
+ }
+
+ @Override
+ public Object getField(final FieldDescriptor field) {
+ return internalGetFieldAccessorTable().getField(field).get(this);
+ }
+
+ /**
+ * Obtains the value of the given field, or the default value if it is
+ * not set. For primitive fields, the boxed primitive value is returned.
+ * For enum fields, the EnumValueDescriptor for the value is returned. For
+ * embedded message fields, the sub-message is returned. For repeated
+ * fields, a java.util.List is returned. For present string fields, a
+ * ByteString is returned representing the bytes that the field contains.
+ */
+ Object getFieldRaw(final FieldDescriptor field) {
+ return internalGetFieldAccessorTable().getField(field).getRaw(this);
+ }
+
+ @Override
+ public int getRepeatedFieldCount(final FieldDescriptor field) {
+ return internalGetFieldAccessorTable().getField(field)
+ .getRepeatedCount(this);
+ }
+
+ @Override
+ public Object getRepeatedField(final FieldDescriptor field, final int index) {
+ return internalGetFieldAccessorTable().getField(field)
+ .getRepeated(this, index);
+ }
+
+ @Override
+ public UnknownFieldSet getUnknownFields() {
+ throw new UnsupportedOperationException(
+ "This is supposed to be overridden by subclasses.");
+ }
+
+ /**
+ * Called by subclasses to parse an unknown field.
+ * @return {@code true} unless the tag is an end-group tag.
+ */
+ protected boolean parseUnknownField(
+ CodedInputStream input,
+ UnknownFieldSet.Builder unknownFields,
+ ExtensionRegistryLite extensionRegistry,
+ int tag) throws IOException {
+ return unknownFields.mergeFieldFrom(tag, input);
+ }
+
+ protected static <M extends Message> M parseWithIOException(Parser<M> parser, InputStream input)
+ throws IOException {
+ try {
+ return parser.parseFrom(input);
+ } catch (InvalidProtocolBufferException e) {
+ throw e.unwrapIOException();
+ }
+ }
+
+ protected static <M extends Message> M parseWithIOException(Parser<M> parser, InputStream input,
+ ExtensionRegistryLite extensions) throws IOException {
+ try {
+ return parser.parseFrom(input, extensions);
+ } catch (InvalidProtocolBufferException e) {
+ throw e.unwrapIOException();
+ }
+ }
+
+ protected static <M extends Message> M parseWithIOException(Parser<M> parser,
+ CodedInputStream input) throws IOException {
+ try {
+ return parser.parseFrom(input);
+ } catch (InvalidProtocolBufferException e) {
+ throw e.unwrapIOException();
+ }
+ }
+
+ protected static <M extends Message> M parseWithIOException(Parser<M> parser,
+ CodedInputStream input, ExtensionRegistryLite extensions) throws IOException {
+ try {
+ return parser.parseFrom(input, extensions);
+ } catch (InvalidProtocolBufferException e) {
+ throw e.unwrapIOException();
+ }
+ }
+
+ protected static <M extends Message> M parseDelimitedWithIOException(Parser<M> parser,
+ InputStream input) throws IOException {
+ try {
+ return parser.parseDelimitedFrom(input);
+ } catch (InvalidProtocolBufferException e) {
+ throw e.unwrapIOException();
+ }
+ }
+
+ protected static <M extends Message> M parseDelimitedWithIOException(Parser<M> parser,
+ InputStream input, ExtensionRegistryLite extensions) throws IOException {
+ try {
+ return parser.parseDelimitedFrom(input, extensions);
+ } catch (InvalidProtocolBufferException e) {
+ throw e.unwrapIOException();
+ }
+ }
+
+ @Override
+ public void writeTo(final CodedOutputStream output) throws IOException {
+ MessageReflection.writeMessageTo(this, getAllFieldsRaw(), output, false);
+ }
+
+ @Override
+ public int getSerializedSize() {
+ int size = memoizedSize;
+ if (size != -1) {
+ return size;
+ }
+
+ memoizedSize = MessageReflection.getSerializedSize(
+ this, getAllFieldsRaw());
+ return memoizedSize;
+ }
+
+
+
+ /**
+ * Used by parsing constructors in generated classes.
+ */
+ protected void makeExtensionsImmutable() {
+ // Noop for messages without extensions.
+ }
+
+ /**
+ * TODO(xiaofeng): remove this after b/29368482 is fixed. We need to move this
+ * interface to AbstractMessage in order to versioning GeneratedMessageV3 but
+ * this move breaks binary compatibility for AppEngine. After AppEngine is
+ * fixed we can exlude this from google3.
+ */
+ protected interface BuilderParent extends AbstractMessage.BuilderParent {}
+
+ /**
+ * TODO(xiaofeng): remove this together with GeneratedMessageV3.BuilderParent.
+ */
+ protected abstract Message.Builder newBuilderForType(BuilderParent parent);
+
+ @Override
+ protected Message.Builder newBuilderForType(final AbstractMessage.BuilderParent parent) {
+ return newBuilderForType(new BuilderParent() {
+ @Override
+ public void markDirty() {
+ parent.markDirty();
+ }
+ });
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public abstract static class Builder <BuilderType extends Builder<BuilderType>>
+ extends AbstractMessage.Builder<BuilderType> {
+
+ private BuilderParent builderParent;
+
+ private BuilderParentImpl meAsParent;
+
+ // Indicates that we've built a message and so we are now obligated
+ // to dispatch dirty invalidations. See GeneratedMessageV3.BuilderListener.
+ private boolean isClean;
+
+ private UnknownFieldSet unknownFields =
+ UnknownFieldSet.getDefaultInstance();
+
+ protected Builder() {
+ this(null);
+ }
+
+ protected Builder(BuilderParent builderParent) {
+ this.builderParent = builderParent;
+ }
+
+ @Override
+ void dispose() {
+ builderParent = null;
+ }
+
+ /**
+ * Called by the subclass when a message is built.
+ */
+ protected void onBuilt() {
+ if (builderParent != null) {
+ markClean();
+ }
+ }
+
+ /**
+ * Called by the subclass or a builder to notify us that a message was
+ * built and may be cached and therefore invalidations are needed.
+ */
+ @Override
+ protected void markClean() {
+ this.isClean = true;
+ }
+
+ /**
+ * Gets whether invalidations are needed
+ *
+ * @return whether invalidations are needed
+ */
+ protected boolean isClean() {
+ return isClean;
+ }
+
+ @Override
+ public BuilderType clone() {
+ BuilderType builder =
+ (BuilderType) getDefaultInstanceForType().newBuilderForType();
+ builder.mergeFrom(buildPartial());
+ return builder;
+ }
+
+ /**
+ * Called by the initialization and clear code paths to allow subclasses to
+ * reset any of their builtin fields back to the initial values.
+ */
+ @Override
+ public BuilderType clear() {
+ unknownFields = UnknownFieldSet.getDefaultInstance();
+ onChanged();
+ return (BuilderType) this;
+ }
+
+ /**
+ * Get the FieldAccessorTable for this type. We can't have the message
+ * class pass this in to the constructor because of bootstrapping trouble
+ * with DescriptorProtos.
+ */
+ protected abstract FieldAccessorTable internalGetFieldAccessorTable();
+
+ @Override
+ public Descriptor getDescriptorForType() {
+ return internalGetFieldAccessorTable().descriptor;
+ }
+
+ @Override
+ public Map<FieldDescriptor, Object> getAllFields() {
+ return Collections.unmodifiableMap(getAllFieldsMutable());
+ }
+
+ /** Internal helper which returns a mutable map. */
+ private Map<FieldDescriptor, Object> getAllFieldsMutable() {
+ final TreeMap<FieldDescriptor, Object> result =
+ new TreeMap<FieldDescriptor, Object>();
+ final Descriptor descriptor = internalGetFieldAccessorTable().descriptor;
+ final List<FieldDescriptor> fields = descriptor.getFields();
+
+ for (int i = 0; i < fields.size(); i++) {
+ FieldDescriptor field = fields.get(i);
+ final OneofDescriptor oneofDescriptor = field.getContainingOneof();
+
+ /*
+ * If the field is part of a Oneof, then at maximum one field in the Oneof is set
+ * and it is not repeated. There is no need to iterate through the others.
+ */
+ if (oneofDescriptor != null) {
+ // Skip other fields in the Oneof we know are not set
+ i += oneofDescriptor.getFieldCount() - 1;
+ if (!hasOneof(oneofDescriptor)) {
+ // If no field is set in the Oneof, skip all the fields in the Oneof
+ continue;
+ }
+ // Get the pointer to the only field which is set in the Oneof
+ field = getOneofFieldDescriptor(oneofDescriptor);
+ } else {
+ // If we are not in a Oneof, we need to check if the field is set and if it is repeated
+ if (field.isRepeated()) {
+ final List<?> value = (List<?>) getField(field);
+ if (!value.isEmpty()) {
+ result.put(field, value);
+ }
+ continue;
+ }
+ if (!hasField(field)) {
+ continue;
+ }
+ }
+ // Add the field to the map
+ result.put(field, getField(field));
+ }
+ return result;
+ }
+
+ @Override
+ public Message.Builder newBuilderForField(final FieldDescriptor field) {
+ return internalGetFieldAccessorTable().getField(field).newBuilder();
+ }
+
+ @Override
+ public Message.Builder getFieldBuilder(final FieldDescriptor field) {
+ return internalGetFieldAccessorTable().getField(field).getBuilder(this);
+ }
+
+ @Override
+ public Message.Builder getRepeatedFieldBuilder(final FieldDescriptor field, int index) {
+ return internalGetFieldAccessorTable().getField(field).getRepeatedBuilder(
+ this, index);
+ }
+
+ @Override
+ public boolean hasOneof(final OneofDescriptor oneof) {
+ return internalGetFieldAccessorTable().getOneof(oneof).has(this);
+ }
+
+ @Override
+ public FieldDescriptor getOneofFieldDescriptor(final OneofDescriptor oneof) {
+ return internalGetFieldAccessorTable().getOneof(oneof).get(this);
+ }
+
+ @Override
+ public boolean hasField(final FieldDescriptor field) {
+ return internalGetFieldAccessorTable().getField(field).has(this);
+ }
+
+ @Override
+ public Object getField(final FieldDescriptor field) {
+ Object object = internalGetFieldAccessorTable().getField(field).get(this);
+ if (field.isRepeated()) {
+ // The underlying list object is still modifiable at this point.
+ // Make sure not to expose the modifiable list to the caller.
+ return Collections.unmodifiableList((List) object);
+ } else {
+ return object;
+ }
+ }
+
+ @Override
+ public BuilderType setField(final FieldDescriptor field, final Object value) {
+ internalGetFieldAccessorTable().getField(field).set(this, value);
+ return (BuilderType) this;
+ }
+
+ @Override
+ public BuilderType clearField(final FieldDescriptor field) {
+ internalGetFieldAccessorTable().getField(field).clear(this);
+ return (BuilderType) this;
+ }
+
+ @Override
+ public BuilderType clearOneof(final OneofDescriptor oneof) {
+ internalGetFieldAccessorTable().getOneof(oneof).clear(this);
+ return (BuilderType) this;
+ }
+
+ @Override
+ public int getRepeatedFieldCount(final FieldDescriptor field) {
+ return internalGetFieldAccessorTable().getField(field)
+ .getRepeatedCount(this);
+ }
+
+ @Override
+ public Object getRepeatedField(final FieldDescriptor field, final int index) {
+ return internalGetFieldAccessorTable().getField(field)
+ .getRepeated(this, index);
+ }
+
+ @Override
+ public BuilderType setRepeatedField(
+ final FieldDescriptor field, final int index, final Object value) {
+ internalGetFieldAccessorTable().getField(field)
+ .setRepeated(this, index, value);
+ return (BuilderType) this;
+ }
+
+ @Override
+ public BuilderType addRepeatedField(final FieldDescriptor field, final Object value) {
+ internalGetFieldAccessorTable().getField(field).addRepeated(this, value);
+ return (BuilderType) this;
+ }
+
+ @Override
+ public BuilderType setUnknownFields(final UnknownFieldSet unknownFields) {
+ this.unknownFields = unknownFields;
+ onChanged();
+ return (BuilderType) this;
+ }
+
+ @Override
+ public BuilderType mergeUnknownFields(
+ final UnknownFieldSet unknownFields) {
+ this.unknownFields =
+ UnknownFieldSet.newBuilder(this.unknownFields)
+ .mergeFrom(unknownFields)
+ .build();
+ onChanged();
+ return (BuilderType) this;
+ }
+
+ @Override
+ public boolean isInitialized() {
+ for (final FieldDescriptor field : getDescriptorForType().getFields()) {
+ // Check that all required fields are present.
+ if (field.isRequired()) {
+ if (!hasField(field)) {
+ return false;
+ }
+ }
+ // Check that embedded messages are initialized.
+ if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+ if (field.isRepeated()) {
+ @SuppressWarnings("unchecked") final
+ List<Message> messageList = (List<Message>) getField(field);
+ for (final Message element : messageList) {
+ if (!element.isInitialized()) {
+ return false;
+ }
+ }
+ } else {
+ if (hasField(field) &&
+ !((Message) getField(field)).isInitialized()) {
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public final UnknownFieldSet getUnknownFields() {
+ return unknownFields;
+ }
+
+ /**
+ * Called by subclasses to parse an unknown field.
+ * @return {@code true} unless the tag is an end-group tag.
+ */
+ protected boolean parseUnknownField(
+ final CodedInputStream input,
+ final UnknownFieldSet.Builder unknownFields,
+ final ExtensionRegistryLite extensionRegistry,
+ final int tag) throws IOException {
+ return unknownFields.mergeFieldFrom(tag, input);
+ }
+
+ /**
+ * Implementation of {@link BuilderParent} for giving to our children. This
+ * small inner class makes it so we don't publicly expose the BuilderParent
+ * methods.
+ */
+ private class BuilderParentImpl implements BuilderParent {
+
+ @Override
+ public void markDirty() {
+ onChanged();
+ }
+ }
+
+ /**
+ * Gets the {@link BuilderParent} for giving to our children.
+ * @return The builder parent for our children.
+ */
+ protected BuilderParent getParentForChildren() {
+ if (meAsParent == null) {
+ meAsParent = new BuilderParentImpl();
+ }
+ return meAsParent;
+ }
+
+ /**
+ * Called when a the builder or one of its nested children has changed
+ * and any parent should be notified of its invalidation.
+ */
+ protected final void onChanged() {
+ if (isClean && builderParent != null) {
+ builderParent.markDirty();
+
+ // Don't keep dispatching invalidations until build is called again.
+ isClean = false;
+ }
+ }
+
+ /**
+ * Gets the map field with the given field number. This method should be
+ * overridden in the generated message class if the message contains map
+ * fields.
+ *
+ * Unlike other field types, reflection support for map fields can't be
+ * implemented based on generated public API because we need to access a
+ * map field as a list in reflection API but the generated API only allows
+ * us to access it as a map. This method returns the underlying map field
+ * directly and thus enables us to access the map field as a list.
+ */
+ @SuppressWarnings({"unused", "rawtypes"})
+ protected MapField internalGetMapField(int fieldNumber) {
+ // Note that we can't use descriptor names here because this method will
+ // be called when descriptor is being initialized.
+ throw new RuntimeException(
+ "No map fields found in " + getClass().getName());
+ }
+
+ /** Like {@link #internalGetMapField} but return a mutable version. */
+ @SuppressWarnings({"unused", "rawtypes"})
+ protected MapField internalGetMutableMapField(int fieldNumber) {
+ // Note that we can't use descriptor names here because this method will
+ // be called when descriptor is being initialized.
+ throw new RuntimeException(
+ "No map fields found in " + getClass().getName());
+ }
+ }
+
+ // =================================================================
+ // Extensions-related stuff
+
+ public interface ExtendableMessageOrBuilder<
+ MessageType extends ExtendableMessage> extends MessageOrBuilder {
+ // Re-define for return type covariance.
+ @Override
+ Message getDefaultInstanceForType();
+
+ /** Check if a singular extension is present. */
+ <Type> boolean hasExtension(
+ ExtensionLite<MessageType, Type> extension);
+
+ /** Get the number of elements in a repeated extension. */
+ <Type> int getExtensionCount(
+ ExtensionLite<MessageType, List<Type>> extension);
+
+ /** Get the value of an extension. */
+ <Type> Type getExtension(
+ ExtensionLite<MessageType, Type> extension);
+
+ /** Get one element of a repeated extension. */
+ <Type> Type getExtension(
+ ExtensionLite<MessageType, List<Type>> extension,
+ int index);
+
+ /** Check if a singular extension is present. */
+ <Type> boolean hasExtension(
+ Extension<MessageType, Type> extension);
+ /** Check if a singular extension is present. */
+ <Type> boolean hasExtension(
+ GeneratedExtension<MessageType, Type> extension);
+ /** Get the number of elements in a repeated extension. */
+ <Type> int getExtensionCount(
+ Extension<MessageType, List<Type>> extension);
+ /** Get the number of elements in a repeated extension. */
+ <Type> int getExtensionCount(
+ GeneratedExtension<MessageType, List<Type>> extension);
+ /** Get the value of an extension. */
+ <Type> Type getExtension(
+ Extension<MessageType, Type> extension);
+ /** Get the value of an extension. */
+ <Type> Type getExtension(
+ GeneratedExtension<MessageType, Type> extension);
+ /** Get one element of a repeated extension. */
+ <Type> Type getExtension(
+ Extension<MessageType, List<Type>> extension,
+ int index);
+ /** Get one element of a repeated extension. */
+ <Type> Type getExtension(
+ GeneratedExtension<MessageType, List<Type>> extension,
+ int index);
+ }
+
+ /**
+ * Generated message classes for message types that contain extension ranges
+ * subclass this.
+ *
+ * <p>This class implements type-safe accessors for extensions. They
+ * implement all the same operations that you can do with normal fields --
+ * e.g. "has", "get", and "getCount" -- but for extensions. The extensions
+ * are identified using instances of the class {@link GeneratedExtension};
+ * the protocol compiler generates a static instance of this class for every
+ * extension in its input. Through the magic of generics, all is made
+ * type-safe.
+ *
+ * <p>For example, imagine you have the {@code .proto} file:
+ *
+ * <pre>
+ * option java_class = "MyProto";
+ *
+ * message Foo {
+ * extensions 1000 to max;
+ * }
+ *
+ * extend Foo {
+ * optional int32 bar;
+ * }
+ * </pre>
+ *
+ * <p>Then you might write code like:
+ *
+ * <pre>
+ * MyProto.Foo foo = getFoo();
+ * int i = foo.getExtension(MyProto.bar);
+ * </pre>
+ *
+ * <p>See also {@link ExtendableBuilder}.
+ */
+ public abstract static class ExtendableMessage<
+ MessageType extends ExtendableMessage>
+ extends GeneratedMessageV3
+ implements ExtendableMessageOrBuilder<MessageType> {
+
+ private static final long serialVersionUID = 1L;
+
+ private final FieldSet<FieldDescriptor> extensions;
+
+ protected ExtendableMessage() {
+ this.extensions = FieldSet.newFieldSet();
+ }
+
+ protected ExtendableMessage(
+ ExtendableBuilder<MessageType, ?> builder) {
+ super(builder);
+ this.extensions = builder.buildExtensions();
+ }
+
+ private void verifyExtensionContainingType(
+ final Extension<MessageType, ?> extension) {
+ if (extension.getDescriptor().getContainingType() !=
+ getDescriptorForType()) {
+ // This can only happen if someone uses unchecked operations.
+ throw new IllegalArgumentException(
+ "Extension is for type \"" +
+ extension.getDescriptor().getContainingType().getFullName() +
+ "\" which does not match message type \"" +
+ getDescriptorForType().getFullName() + "\".");
+ }
+ }
+
+ /** Check if a singular extension is present. */
+ @Override
+ public final <Type> boolean hasExtension(final ExtensionLite<MessageType, Type> extensionLite) {
+ Extension<MessageType, Type> extension = checkNotLite(extensionLite);
+
+ verifyExtensionContainingType(extension);
+ return extensions.hasField(extension.getDescriptor());
+ }
+
+ /** Get the number of elements in a repeated extension. */
+ @Override
+ public final <Type> int getExtensionCount(
+ final ExtensionLite<MessageType, List<Type>> extensionLite) {
+ Extension<MessageType, List<Type>> extension = checkNotLite(extensionLite);
+
+ verifyExtensionContainingType(extension);
+ final FieldDescriptor descriptor = extension.getDescriptor();
+ return extensions.getRepeatedFieldCount(descriptor);
+ }
+
+ /** Get the value of an extension. */
+ @Override
+ @SuppressWarnings("unchecked")
+ public final <Type> Type getExtension(final ExtensionLite<MessageType, Type> extensionLite) {
+ Extension<MessageType, Type> extension = checkNotLite(extensionLite);
+
+ verifyExtensionContainingType(extension);
+ FieldDescriptor descriptor = extension.getDescriptor();
+ final Object value = extensions.getField(descriptor);
+ if (value == null) {
+ if (descriptor.isRepeated()) {
+ return (Type) Collections.emptyList();
+ } else if (descriptor.getJavaType() ==
+ FieldDescriptor.JavaType.MESSAGE) {
+ return (Type) extension.getMessageDefaultInstance();
+ } else {
+ return (Type) extension.fromReflectionType(
+ descriptor.getDefaultValue());
+ }
+ } else {
+ return (Type) extension.fromReflectionType(value);
+ }
+ }
+
+ /** Get one element of a repeated extension. */
+ @Override
+ @SuppressWarnings("unchecked")
+ public final <Type> Type getExtension(
+ final ExtensionLite<MessageType, List<Type>> extensionLite, final int index) {
+ Extension<MessageType, List<Type>> extension = checkNotLite(extensionLite);
+
+ verifyExtensionContainingType(extension);
+ FieldDescriptor descriptor = extension.getDescriptor();
+ return (Type) extension.singularFromReflectionType(
+ extensions.getRepeatedField(descriptor, index));
+ }
+
+ /** Check if a singular extension is present. */
+ @Override
+ public final <Type> boolean hasExtension(final Extension<MessageType, Type> extension) {
+ return hasExtension((ExtensionLite<MessageType, Type>) extension);
+ }
+ /** Check if a singular extension is present. */
+ @Override
+ public final <Type> boolean hasExtension(
+ final GeneratedExtension<MessageType, Type> extension) {
+ return hasExtension((ExtensionLite<MessageType, Type>) extension);
+ }
+ /** Get the number of elements in a repeated extension. */
+ @Override
+ public final <Type> int getExtensionCount(
+ final Extension<MessageType, List<Type>> extension) {
+ return getExtensionCount((ExtensionLite<MessageType, List<Type>>) extension);
+ }
+ /** Get the number of elements in a repeated extension. */
+ @Override
+ public final <Type> int getExtensionCount(
+ final GeneratedExtension<MessageType, List<Type>> extension) {
+ return getExtensionCount((ExtensionLite<MessageType, List<Type>>) extension);
+ }
+ /** Get the value of an extension. */
+ @Override
+ public final <Type> Type getExtension(final Extension<MessageType, Type> extension) {
+ return getExtension((ExtensionLite<MessageType, Type>) extension);
+ }
+ /** Get the value of an extension. */
+ @Override
+ public final <Type> Type getExtension(
+ final GeneratedExtension<MessageType, Type> extension) {
+ return getExtension((ExtensionLite<MessageType, Type>) extension);
+ }
+ /** Get one element of a repeated extension. */
+ @Override
+ public final <Type> Type getExtension(
+ final Extension<MessageType, List<Type>> extension, final int index) {
+ return getExtension((ExtensionLite<MessageType, List<Type>>) extension, index);
+ }
+ /** Get one element of a repeated extension. */
+ @Override
+ public final <Type> Type getExtension(
+ final GeneratedExtension<MessageType, List<Type>> extension, final int index) {
+ return getExtension((ExtensionLite<MessageType, List<Type>>) extension, index);
+ }
+
+ /** Called by subclasses to check if all extensions are initialized. */
+ protected boolean extensionsAreInitialized() {
+ return extensions.isInitialized();
+ }
+
+ @Override
+ public boolean isInitialized() {
+ return super.isInitialized() && extensionsAreInitialized();
+ }
+
+ @Override
+ protected boolean parseUnknownField(
+ CodedInputStream input,
+ UnknownFieldSet.Builder unknownFields,
+ ExtensionRegistryLite extensionRegistry,
+ int tag) throws IOException {
+ return MessageReflection.mergeFieldFrom(
+ input, unknownFields, extensionRegistry, getDescriptorForType(),
+ new MessageReflection.ExtensionAdapter(extensions), tag);
+ }
+
+
+ /**
+ * Used by parsing constructors in generated classes.
+ */
+ @Override
+ protected void makeExtensionsImmutable() {
+ extensions.makeImmutable();
+ }
+
+ /**
+ * Used by subclasses to serialize extensions. Extension ranges may be
+ * interleaved with field numbers, but we must write them in canonical
+ * (sorted by field number) order. ExtensionWriter helps us write
+ * individual ranges of extensions at once.
+ */
+ protected class ExtensionWriter {
+ // Imagine how much simpler this code would be if Java iterators had
+ // a way to get the next element without advancing the iterator.
+
+ private final Iterator<Map.Entry<FieldDescriptor, Object>> iter =
+ extensions.iterator();
+ private Map.Entry<FieldDescriptor, Object> next;
+ private final boolean messageSetWireFormat;
+
+ private ExtensionWriter(final boolean messageSetWireFormat) {
+ if (iter.hasNext()) {
+ next = iter.next();
+ }
+ this.messageSetWireFormat = messageSetWireFormat;
+ }
+
+ public void writeUntil(final int end, final CodedOutputStream output)
+ throws IOException {
+ while (next != null && next.getKey().getNumber() < end) {
+ FieldDescriptor descriptor = next.getKey();
+ if (messageSetWireFormat && descriptor.getLiteJavaType() ==
+ WireFormat.JavaType.MESSAGE &&
+ !descriptor.isRepeated()) {
+ if (next instanceof LazyField.LazyEntry<?>) {
+ output.writeRawMessageSetExtension(descriptor.getNumber(),
+ ((LazyField.LazyEntry<?>) next).getField().toByteString());
+ } else {
+ output.writeMessageSetExtension(descriptor.getNumber(),
+ (Message) next.getValue());
+ }
+ } else {
+ // TODO(xiangl): Taken care of following code, it may cause
+ // problem when we use LazyField for normal fields/extensions.
+ // Due to the optional field can be duplicated at the end of
+ // serialized bytes, which will make the serialized size change
+ // after lazy field parsed. So when we use LazyField globally,
+ // we need to change the following write method to write cached
+ // bytes directly rather than write the parsed message.
+ FieldSet.writeField(descriptor, next.getValue(), output);
+ }
+ if (iter.hasNext()) {
+ next = iter.next();
+ } else {
+ next = null;
+ }
+ }
+ }
+ }
+
+ protected ExtensionWriter newExtensionWriter() {
+ return new ExtensionWriter(false);
+ }
+ protected ExtensionWriter newMessageSetExtensionWriter() {
+ return new ExtensionWriter(true);
+ }
+
+ /** Called by subclasses to compute the size of extensions. */
+ protected int extensionsSerializedSize() {
+ return extensions.getSerializedSize();
+ }
+ protected int extensionsSerializedSizeAsMessageSet() {
+ return extensions.getMessageSetSerializedSize();
+ }
+
+ // ---------------------------------------------------------------
+ // Reflection
+
+ protected Map<FieldDescriptor, Object> getExtensionFields() {
+ return extensions.getAllFields();
+ }
+
+ @Override
+ public Map<FieldDescriptor, Object> getAllFields() {
+ final Map<FieldDescriptor, Object> result =
+ super.getAllFieldsMutable(/* getBytesForString = */ false);
+ result.putAll(getExtensionFields());
+ return Collections.unmodifiableMap(result);
+ }
+
+ @Override
+ public Map<FieldDescriptor, Object> getAllFieldsRaw() {
+ final Map<FieldDescriptor, Object> result =
+ super.getAllFieldsMutable(/* getBytesForString = */ false);
+ result.putAll(getExtensionFields());
+ return Collections.unmodifiableMap(result);
+ }
+
+ @Override
+ public boolean hasField(final FieldDescriptor field) {
+ if (field.isExtension()) {
+ verifyContainingType(field);
+ return extensions.hasField(field);
+ } else {
+ return super.hasField(field);
+ }
+ }
+
+ @Override
+ public Object getField(final FieldDescriptor field) {
+ if (field.isExtension()) {
+ verifyContainingType(field);
+ final Object value = extensions.getField(field);
+ if (value == null) {
+ if (field.isRepeated()) {
+ return Collections.emptyList();
+ } else if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+ // Lacking an ExtensionRegistry, we have no way to determine the
+ // extension's real type, so we return a DynamicMessage.
+ return DynamicMessage.getDefaultInstance(field.getMessageType());
+ } else {
+ return field.getDefaultValue();
+ }
+ } else {
+ return value;
+ }
+ } else {
+ return super.getField(field);
+ }
+ }
+
+ @Override
+ public int getRepeatedFieldCount(final FieldDescriptor field) {
+ if (field.isExtension()) {
+ verifyContainingType(field);
+ return extensions.getRepeatedFieldCount(field);
+ } else {
+ return super.getRepeatedFieldCount(field);
+ }
+ }
+
+ @Override
+ public Object getRepeatedField(final FieldDescriptor field,
+ final int index) {
+ if (field.isExtension()) {
+ verifyContainingType(field);
+ return extensions.getRepeatedField(field, index);
+ } else {
+ return super.getRepeatedField(field, index);
+ }
+ }
+
+ private void verifyContainingType(final FieldDescriptor field) {
+ if (field.getContainingType() != getDescriptorForType()) {
+ throw new IllegalArgumentException(
+ "FieldDescriptor does not match message type.");
+ }
+ }
+ }
+
+ /**
+ * Generated message builders for message types that contain extension ranges
+ * subclass this.
+ *
+ * <p>This class implements type-safe accessors for extensions. They
+ * implement all the same operations that you can do with normal fields --
+ * e.g. "get", "set", and "add" -- but for extensions. The extensions are
+ * identified using instances of the class {@link GeneratedExtension}; the
+ * protocol compiler generates a static instance of this class for every
+ * extension in its input. Through the magic of generics, all is made
+ * type-safe.
+ *
+ * <p>For example, imagine you have the {@code .proto} file:
+ *
+ * <pre>
+ * option java_class = "MyProto";
+ *
+ * message Foo {
+ * extensions 1000 to max;
+ * }
+ *
+ * extend Foo {
+ * optional int32 bar;
+ * }
+ * </pre>
+ *
+ * <p>Then you might write code like:
+ *
+ * <pre>
+ * MyProto.Foo foo =
+ * MyProto.Foo.newBuilder()
+ * .setExtension(MyProto.bar, 123)
+ * .build();
+ * </pre>
+ *
+ * <p>See also {@link ExtendableMessage}.
+ */
+ @SuppressWarnings("unchecked")
+ public abstract static class ExtendableBuilder<
+ MessageType extends ExtendableMessage,
+ BuilderType extends ExtendableBuilder<MessageType, BuilderType>>
+ extends Builder<BuilderType>
+ implements ExtendableMessageOrBuilder<MessageType> {
+
+ private FieldSet<FieldDescriptor> extensions = FieldSet.emptySet();
+
+ protected ExtendableBuilder() {}
+
+ protected ExtendableBuilder(
+ BuilderParent parent) {
+ super(parent);
+ }
+
+ // For immutable message conversion.
+ void internalSetExtensionSet(FieldSet<FieldDescriptor> extensions) {
+ this.extensions = extensions;
+ }
+
+ @Override
+ public BuilderType clear() {
+ extensions = FieldSet.emptySet();
+ return super.clear();
+ }
+
+ // This is implemented here only to work around an apparent bug in the
+ // Java compiler and/or build system. See bug #1898463. The mere presence
+ // of this clone() implementation makes it go away.
+ @Override
+ public BuilderType clone() {
+ return super.clone();
+ }
+
+ private void ensureExtensionsIsMutable() {
+ if (extensions.isImmutable()) {
+ extensions = extensions.clone();
+ }
+ }
+
+ private void verifyExtensionContainingType(
+ final Extension<MessageType, ?> extension) {
+ if (extension.getDescriptor().getContainingType() !=
+ getDescriptorForType()) {
+ // This can only happen if someone uses unchecked operations.
+ throw new IllegalArgumentException(
+ "Extension is for type \"" +
+ extension.getDescriptor().getContainingType().getFullName() +
+ "\" which does not match message type \"" +
+ getDescriptorForType().getFullName() + "\".");
+ }
+ }
+
+ /** Check if a singular extension is present. */
+ @Override
+ public final <Type> boolean hasExtension(final ExtensionLite<MessageType, Type> extensionLite) {
+ Extension<MessageType, Type> extension = checkNotLite(extensionLite);
+
+ verifyExtensionContainingType(extension);
+ return extensions.hasField(extension.getDescriptor());
+ }
+
+ /** Get the number of elements in a repeated extension. */
+ @Override
+ public final <Type> int getExtensionCount(
+ final ExtensionLite<MessageType, List<Type>> extensionLite) {
+ Extension<MessageType, List<Type>> extension = checkNotLite(extensionLite);
+
+ verifyExtensionContainingType(extension);
+ final FieldDescriptor descriptor = extension.getDescriptor();
+ return extensions.getRepeatedFieldCount(descriptor);
+ }
+
+ /** Get the value of an extension. */
+ @Override
+ public final <Type> Type getExtension(final ExtensionLite<MessageType, Type> extensionLite) {
+ Extension<MessageType, Type> extension = checkNotLite(extensionLite);
+
+ verifyExtensionContainingType(extension);
+ FieldDescriptor descriptor = extension.getDescriptor();
+ final Object value = extensions.getField(descriptor);
+ if (value == null) {
+ if (descriptor.isRepeated()) {
+ return (Type) Collections.emptyList();
+ } else if (descriptor.getJavaType() ==
+ FieldDescriptor.JavaType.MESSAGE) {
+ return (Type) extension.getMessageDefaultInstance();
+ } else {
+ return (Type) extension.fromReflectionType(
+ descriptor.getDefaultValue());
+ }
+ } else {
+ return (Type) extension.fromReflectionType(value);
+ }
+ }
+
+ /** Get one element of a repeated extension. */
+ @Override
+ public final <Type> Type getExtension(
+ final ExtensionLite<MessageType, List<Type>> extensionLite, final int index) {
+ Extension<MessageType, List<Type>> extension = checkNotLite(extensionLite);
+
+ verifyExtensionContainingType(extension);
+ FieldDescriptor descriptor = extension.getDescriptor();
+ return (Type) extension.singularFromReflectionType(
+ extensions.getRepeatedField(descriptor, index));
+ }
+
+ /** Set the value of an extension. */
+ public final <Type> BuilderType setExtension(
+ final ExtensionLite<MessageType, Type> extensionLite,
+ final Type value) {
+ Extension<MessageType, Type> extension = checkNotLite(extensionLite);
+
+ verifyExtensionContainingType(extension);
+ ensureExtensionsIsMutable();
+ final FieldDescriptor descriptor = extension.getDescriptor();
+ extensions.setField(descriptor, extension.toReflectionType(value));
+ onChanged();
+ return (BuilderType) this;
+ }
+
+ /** Set the value of one element of a repeated extension. */
+ public final <Type> BuilderType setExtension(
+ final ExtensionLite<MessageType, List<Type>> extensionLite,
+ final int index, final Type value) {
+ Extension<MessageType, List<Type>> extension = checkNotLite(extensionLite);
+
+ verifyExtensionContainingType(extension);
+ ensureExtensionsIsMutable();
+ final FieldDescriptor descriptor = extension.getDescriptor();
+ extensions.setRepeatedField(
+ descriptor, index,
+ extension.singularToReflectionType(value));
+ onChanged();
+ return (BuilderType) this;
+ }
+
+ /** Append a value to a repeated extension. */
+ public final <Type> BuilderType addExtension(
+ final ExtensionLite<MessageType, List<Type>> extensionLite,
+ final Type value) {
+ Extension<MessageType, List<Type>> extension = checkNotLite(extensionLite);
+
+ verifyExtensionContainingType(extension);
+ ensureExtensionsIsMutable();
+ final FieldDescriptor descriptor = extension.getDescriptor();
+ extensions.addRepeatedField(
+ descriptor, extension.singularToReflectionType(value));
+ onChanged();
+ return (BuilderType) this;
+ }
+
+ /** Clear an extension. */
+ public final <Type> BuilderType clearExtension(
+ final ExtensionLite<MessageType, ?> extensionLite) {
+ Extension<MessageType, ?> extension = checkNotLite(extensionLite);
+
+ verifyExtensionContainingType(extension);
+ ensureExtensionsIsMutable();
+ extensions.clearField(extension.getDescriptor());
+ onChanged();
+ return (BuilderType) this;
+ }
+
+ /** Check if a singular extension is present. */
+ @Override
+ public final <Type> boolean hasExtension(final Extension<MessageType, Type> extension) {
+ return hasExtension((ExtensionLite<MessageType, Type>) extension);
+ }
+ /** Check if a singular extension is present. */
+ @Override
+ public final <Type> boolean hasExtension(
+ final GeneratedExtension<MessageType, Type> extension) {
+ return hasExtension((ExtensionLite<MessageType, Type>) extension);
+ }
+ /** Get the number of elements in a repeated extension. */
+ @Override
+ public final <Type> int getExtensionCount(
+ final Extension<MessageType, List<Type>> extension) {
+ return getExtensionCount((ExtensionLite<MessageType, List<Type>>) extension);
+ }
+ /** Get the number of elements in a repeated extension. */
+ @Override
+ public final <Type> int getExtensionCount(
+ final GeneratedExtension<MessageType, List<Type>> extension) {
+ return getExtensionCount((ExtensionLite<MessageType, List<Type>>) extension);
+ }
+ /** Get the value of an extension. */
+ @Override
+ public final <Type> Type getExtension(final Extension<MessageType, Type> extension) {
+ return getExtension((ExtensionLite<MessageType, Type>) extension);
+ }
+ /** Get the value of an extension. */
+ @Override
+ public final <Type> Type getExtension(
+ final GeneratedExtension<MessageType, Type> extension) {
+ return getExtension((ExtensionLite<MessageType, Type>) extension);
+ }
+ /** Get the value of an extension. */
+ @Override
+ public final <Type> Type getExtension(
+ final Extension<MessageType, List<Type>> extension, final int index) {
+ return getExtension((ExtensionLite<MessageType, List<Type>>) extension, index);
+ }
+ /** Get the value of an extension. */
+ @Override
+ public final <Type> Type getExtension(
+ final GeneratedExtension<MessageType, List<Type>> extension, final int index) {
+ return getExtension((ExtensionLite<MessageType, List<Type>>) extension, index);
+ }
+ /** Set the value of an extension. */
+ public final <Type> BuilderType setExtension(
+ final Extension<MessageType, Type> extension, final Type value) {
+ return setExtension((ExtensionLite<MessageType, Type>) extension, value);
+ }
+ /** Set the value of an extension. */
+ public <Type> BuilderType setExtension(
+ final GeneratedExtension<MessageType, Type> extension, final Type value) {
+ return setExtension((ExtensionLite<MessageType, Type>) extension, value);
+ }
+ /** Set the value of one element of a repeated extension. */
+ public final <Type> BuilderType setExtension(
+ final Extension<MessageType, List<Type>> extension,
+ final int index, final Type value) {
+ return setExtension((ExtensionLite<MessageType, List<Type>>) extension, index, value);
+ }
+ /** Set the value of one element of a repeated extension. */
+ public <Type> BuilderType setExtension(
+ final GeneratedExtension<MessageType, List<Type>> extension,
+ final int index, final Type value) {
+ return setExtension((ExtensionLite<MessageType, List<Type>>) extension, index, value);
+ }
+ /** Append a value to a repeated extension. */
+ public final <Type> BuilderType addExtension(
+ final Extension<MessageType, List<Type>> extension, final Type value) {
+ return addExtension((ExtensionLite<MessageType, List<Type>>) extension, value);
+ }
+ /** Append a value to a repeated extension. */
+ public <Type> BuilderType addExtension(
+ final GeneratedExtension<MessageType, List<Type>> extension, final Type value) {
+ return addExtension((ExtensionLite<MessageType, List<Type>>) extension, value);
+ }
+ /** Clear an extension. */
+ public final <Type> BuilderType clearExtension(
+ final Extension<MessageType, ?> extension) {
+ return clearExtension((ExtensionLite<MessageType, ?>) extension);
+ }
+ /** Clear an extension. */
+ public <Type> BuilderType clearExtension(
+ final GeneratedExtension<MessageType, ?> extension) {
+ return clearExtension((ExtensionLite<MessageType, ?>) extension);
+ }
+
+ /** Called by subclasses to check if all extensions are initialized. */
+ protected boolean extensionsAreInitialized() {
+ return extensions.isInitialized();
+ }
+
+ /**
+ * Called by the build code path to create a copy of the extensions for
+ * building the message.
+ */
+ private FieldSet<FieldDescriptor> buildExtensions() {
+ extensions.makeImmutable();
+ return extensions;
+ }
+
+ @Override
+ public boolean isInitialized() {
+ return super.isInitialized() && extensionsAreInitialized();
+ }
+
+ /**
+ * Called by subclasses to parse an unknown field or an extension.
+ * @return {@code true} unless the tag is an end-group tag.
+ */
+ @Override
+ protected boolean parseUnknownField(
+ final CodedInputStream input,
+ final UnknownFieldSet.Builder unknownFields,
+ final ExtensionRegistryLite extensionRegistry,
+ final int tag) throws IOException {
+ return MessageReflection.mergeFieldFrom(
+ input, unknownFields, extensionRegistry, getDescriptorForType(),
+ new MessageReflection.BuilderAdapter(this), tag);
+ }
+
+ // ---------------------------------------------------------------
+ // Reflection
+
+ @Override
+ public Map<FieldDescriptor, Object> getAllFields() {
+ final Map<FieldDescriptor, Object> result = super.getAllFieldsMutable();
+ result.putAll(extensions.getAllFields());
+ return Collections.unmodifiableMap(result);
+ }
+
+ @Override
+ public Object getField(final FieldDescriptor field) {
+ if (field.isExtension()) {
+ verifyContainingType(field);
+ final Object value = extensions.getField(field);
+ if (value == null) {
+ if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+ // Lacking an ExtensionRegistry, we have no way to determine the
+ // extension's real type, so we return a DynamicMessage.
+ return DynamicMessage.getDefaultInstance(field.getMessageType());
+ } else {
+ return field.getDefaultValue();
+ }
+ } else {
+ return value;
+ }
+ } else {
+ return super.getField(field);
+ }
+ }
+
+ @Override
+ public int getRepeatedFieldCount(final FieldDescriptor field) {
+ if (field.isExtension()) {
+ verifyContainingType(field);
+ return extensions.getRepeatedFieldCount(field);
+ } else {
+ return super.getRepeatedFieldCount(field);
+ }
+ }
+
+ @Override
+ public Object getRepeatedField(final FieldDescriptor field,
+ final int index) {
+ if (field.isExtension()) {
+ verifyContainingType(field);
+ return extensions.getRepeatedField(field, index);
+ } else {
+ return super.getRepeatedField(field, index);
+ }
+ }
+
+ @Override
+ public boolean hasField(final FieldDescriptor field) {
+ if (field.isExtension()) {
+ verifyContainingType(field);
+ return extensions.hasField(field);
+ } else {
+ return super.hasField(field);
+ }
+ }
+
+ @Override
+ public BuilderType setField(final FieldDescriptor field,
+ final Object value) {
+ if (field.isExtension()) {
+ verifyContainingType(field);
+ ensureExtensionsIsMutable();
+ extensions.setField(field, value);
+ onChanged();
+ return (BuilderType) this;
+ } else {
+ return super.setField(field, value);
+ }
+ }
+
+ @Override
+ public BuilderType clearField(final FieldDescriptor field) {
+ if (field.isExtension()) {
+ verifyContainingType(field);
+ ensureExtensionsIsMutable();
+ extensions.clearField(field);
+ onChanged();
+ return (BuilderType) this;
+ } else {
+ return super.clearField(field);
+ }
+ }
+
+ @Override
+ public BuilderType setRepeatedField(final FieldDescriptor field,
+ final int index, final Object value) {
+ if (field.isExtension()) {
+ verifyContainingType(field);
+ ensureExtensionsIsMutable();
+ extensions.setRepeatedField(field, index, value);
+ onChanged();
+ return (BuilderType) this;
+ } else {
+ return super.setRepeatedField(field, index, value);
+ }
+ }
+
+ @Override
+ public BuilderType addRepeatedField(final FieldDescriptor field,
+ final Object value) {
+ if (field.isExtension()) {
+ verifyContainingType(field);
+ ensureExtensionsIsMutable();
+ extensions.addRepeatedField(field, value);
+ onChanged();
+ return (BuilderType) this;
+ } else {
+ return super.addRepeatedField(field, value);
+ }
+ }
+
+ protected final void mergeExtensionFields(final ExtendableMessage other) {
+ ensureExtensionsIsMutable();
+ extensions.mergeFrom(other.extensions);
+ onChanged();
+ }
+
+ private void verifyContainingType(final FieldDescriptor field) {
+ if (field.getContainingType() != getDescriptorForType()) {
+ throw new IllegalArgumentException(
+ "FieldDescriptor does not match message type.");
+ }
+ }
+ }
+
+ // -----------------------------------------------------------------
+
+ /**
+ * Gets the descriptor for an extension. The implementation depends on whether
+ * the extension is scoped in the top level of a file or scoped in a Message.
+ */
+ static interface ExtensionDescriptorRetriever {
+ FieldDescriptor getDescriptor();
+ }
+
+ private abstract static class CachedDescriptorRetriever
+ implements ExtensionDescriptorRetriever {
+ private volatile FieldDescriptor descriptor;
+ protected abstract FieldDescriptor loadDescriptor();
+
+ @Override
+ public FieldDescriptor getDescriptor() {
+ if (descriptor == null) {
+ synchronized (this) {
+ if (descriptor == null) {
+ descriptor = loadDescriptor();
+ }
+ }
+ }
+ return descriptor;
+ }
+ }
+
+ // =================================================================
+
+ /** Calls Class.getMethod and throws a RuntimeException if it fails. */
+ @SuppressWarnings("unchecked")
+ private static Method getMethodOrDie(
+ final Class clazz, final String name, final Class... params) {
+ try {
+ return clazz.getMethod(name, params);
+ } catch (NoSuchMethodException e) {
+ throw new RuntimeException(
+ "Generated message class \"" + clazz.getName() +
+ "\" missing method \"" + name + "\".", e);
+ }
+ }
+
+ /** Calls invoke and throws a RuntimeException if it fails. */
+ private static Object invokeOrDie(
+ final Method method, final Object object, final Object... params) {
+ try {
+ return method.invoke(object, params);
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException(
+ "Couldn't use Java reflection to implement protocol message " +
+ "reflection.", e);
+ } catch (InvocationTargetException e) {
+ final Throwable cause = e.getCause();
+ if (cause instanceof RuntimeException) {
+ throw (RuntimeException) cause;
+ } else if (cause instanceof Error) {
+ throw (Error) cause;
+ } else {
+ throw new RuntimeException(
+ "Unexpected exception thrown by generated accessor method.", cause);
+ }
+ }
+ }
+
+ /**
+ * Gets the map field with the given field number. This method should be
+ * overridden in the generated message class if the message contains map
+ * fields.
+ *
+ * Unlike other field types, reflection support for map fields can't be
+ * implemented based on generated public API because we need to access a
+ * map field as a list in reflection API but the generated API only allows
+ * us to access it as a map. This method returns the underlying map field
+ * directly and thus enables us to access the map field as a list.
+ */
+ @SuppressWarnings({"rawtypes", "unused"})
+ protected MapField internalGetMapField(int fieldNumber) {
+ // Note that we can't use descriptor names here because this method will
+ // be called when descriptor is being initialized.
+ throw new RuntimeException(
+ "No map fields found in " + getClass().getName());
+ }
+
+ /**
+ * Users should ignore this class. This class provides the implementation
+ * with access to the fields of a message object using Java reflection.
+ */
+ public static final class FieldAccessorTable {
+
+ /**
+ * Construct a FieldAccessorTable for a particular message class. Only
+ * one FieldAccessorTable should ever be constructed per class.
+ *
+ * @param descriptor The type's descriptor.
+ * @param camelCaseNames The camelcase names of all fields in the message.
+ * These are used to derive the accessor method names.
+ * @param messageClass The message type.
+ * @param builderClass The builder type.
+ */
+ public FieldAccessorTable(
+ final Descriptor descriptor,
+ final String[] camelCaseNames,
+ final Class<? extends GeneratedMessageV3> messageClass,
+ final Class<? extends Builder> builderClass) {
+ this(descriptor, camelCaseNames);
+ ensureFieldAccessorsInitialized(messageClass, builderClass);
+ }
+
+ /**
+ * Construct a FieldAccessorTable for a particular message class without
+ * initializing FieldAccessors.
+ */
+ public FieldAccessorTable(
+ final Descriptor descriptor,
+ final String[] camelCaseNames) {
+ this.descriptor = descriptor;
+ this.camelCaseNames = camelCaseNames;
+ fields = new FieldAccessor[descriptor.getFields().size()];
+ oneofs = new OneofAccessor[descriptor.getOneofs().size()];
+ initialized = false;
+ }
+
+ private boolean isMapFieldEnabled(FieldDescriptor field) {
+ boolean result = true;
+ return result;
+ }
+
+ /**
+ * Ensures the field accessors are initialized. This method is thread-safe.
+ *
+ * @param messageClass The message type.
+ * @param builderClass The builder type.
+ * @return this
+ */
+ public FieldAccessorTable ensureFieldAccessorsInitialized(
+ Class<? extends GeneratedMessageV3> messageClass,
+ Class<? extends Builder> builderClass) {
+ if (initialized) { return this; }
+ synchronized (this) {
+ if (initialized) { return this; }
+ int fieldsSize = fields.length;
+ for (int i = 0; i < fieldsSize; i++) {
+ FieldDescriptor field = descriptor.getFields().get(i);
+ String containingOneofCamelCaseName = null;
+ if (field.getContainingOneof() != null) {
+ containingOneofCamelCaseName =
+ camelCaseNames[fieldsSize + field.getContainingOneof().getIndex()];
+ }
+ if (field.isRepeated()) {
+ if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+ if (field.isMapField() && isMapFieldEnabled(field)) {
+ fields[i] = new MapFieldAccessor(
+ field, camelCaseNames[i], messageClass, builderClass);
+ } else {
+ fields[i] = new RepeatedMessageFieldAccessor(
+ field, camelCaseNames[i], messageClass, builderClass);
+ }
+ } else if (field.getJavaType() == FieldDescriptor.JavaType.ENUM) {
+ fields[i] = new RepeatedEnumFieldAccessor(
+ field, camelCaseNames[i], messageClass, builderClass);
+ } else {
+ fields[i] = new RepeatedFieldAccessor(
+ field, camelCaseNames[i], messageClass, builderClass);
+ }
+ } else {
+ if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+ fields[i] = new SingularMessageFieldAccessor(
+ field, camelCaseNames[i], messageClass, builderClass,
+ containingOneofCamelCaseName);
+ } else if (field.getJavaType() == FieldDescriptor.JavaType.ENUM) {
+ fields[i] = new SingularEnumFieldAccessor(
+ field, camelCaseNames[i], messageClass, builderClass,
+ containingOneofCamelCaseName);
+ } else if (field.getJavaType() == FieldDescriptor.JavaType.STRING) {
+ fields[i] = new SingularStringFieldAccessor(
+ field, camelCaseNames[i], messageClass, builderClass,
+ containingOneofCamelCaseName);
+ } else {
+ fields[i] = new SingularFieldAccessor(
+ field, camelCaseNames[i], messageClass, builderClass,
+ containingOneofCamelCaseName);
+ }
+ }
+ }
+
+ int oneofsSize = oneofs.length;
+ for (int i = 0; i < oneofsSize; i++) {
+ oneofs[i] = new OneofAccessor(
+ descriptor, camelCaseNames[i + fieldsSize],
+ messageClass, builderClass);
+ }
+ initialized = true;
+ camelCaseNames = null;
+ return this;
+ }
+ }
+
+ private final Descriptor descriptor;
+ private final FieldAccessor[] fields;
+ private String[] camelCaseNames;
+ private final OneofAccessor[] oneofs;
+ private volatile boolean initialized;
+
+ /** Get the FieldAccessor for a particular field. */
+ private FieldAccessor getField(final FieldDescriptor field) {
+ if (field.getContainingType() != descriptor) {
+ throw new IllegalArgumentException(
+ "FieldDescriptor does not match message type.");
+ } else if (field.isExtension()) {
+ // If this type had extensions, it would subclass ExtendableMessage,
+ // which overrides the reflection interface to handle extensions.
+ throw new IllegalArgumentException(
+ "This type does not have extensions.");
+ }
+ return fields[field.getIndex()];
+ }
+
+ /** Get the OneofAccessor for a particular oneof. */
+ private OneofAccessor getOneof(final OneofDescriptor oneof) {
+ if (oneof.getContainingType() != descriptor) {
+ throw new IllegalArgumentException(
+ "OneofDescriptor does not match message type.");
+ }
+ return oneofs[oneof.getIndex()];
+ }
+
+ /**
+ * Abstract interface that provides access to a single field. This is
+ * implemented differently depending on the field type and cardinality.
+ */
+ private interface FieldAccessor {
+ Object get(GeneratedMessageV3 message);
+ Object get(GeneratedMessageV3.Builder builder);
+ Object getRaw(GeneratedMessageV3 message);
+ Object getRaw(GeneratedMessageV3.Builder builder);
+ void set(Builder builder, Object value);
+ Object getRepeated(GeneratedMessageV3 message, int index);
+ Object getRepeated(GeneratedMessageV3.Builder builder, int index);
+ Object getRepeatedRaw(GeneratedMessageV3 message, int index);
+ Object getRepeatedRaw(GeneratedMessageV3.Builder builder, int index);
+ void setRepeated(Builder builder,
+ int index, Object value);
+ void addRepeated(Builder builder, Object value);
+ boolean has(GeneratedMessageV3 message);
+ boolean has(GeneratedMessageV3.Builder builder);
+ int getRepeatedCount(GeneratedMessageV3 message);
+ int getRepeatedCount(GeneratedMessageV3.Builder builder);
+ void clear(Builder builder);
+ Message.Builder newBuilder();
+ Message.Builder getBuilder(GeneratedMessageV3.Builder builder);
+ Message.Builder getRepeatedBuilder(GeneratedMessageV3.Builder builder,
+ int index);
+ }
+
+ /** OneofAccessor provides access to a single oneof. */
+ private static class OneofAccessor {
+ OneofAccessor(
+ final Descriptor descriptor, final String camelCaseName,
+ final Class<? extends GeneratedMessageV3> messageClass,
+ final Class<? extends Builder> builderClass) {
+ this.descriptor = descriptor;
+ caseMethod =
+ getMethodOrDie(messageClass, "get" + camelCaseName + "Case");
+ caseMethodBuilder =
+ getMethodOrDie(builderClass, "get" + camelCaseName + "Case");
+ clearMethod = getMethodOrDie(builderClass, "clear" + camelCaseName);
+ }
+
+ private final Descriptor descriptor;
+ private final Method caseMethod;
+ private final Method caseMethodBuilder;
+ private final Method clearMethod;
+
+ public boolean has(final GeneratedMessageV3 message) {
+ if (((Internal.EnumLite) invokeOrDie(caseMethod, message)).getNumber() == 0) {
+ return false;
+ }
+ return true;
+ }
+
+ public boolean has(GeneratedMessageV3.Builder builder) {
+ if (((Internal.EnumLite) invokeOrDie(caseMethodBuilder, builder)).getNumber() == 0) {
+ return false;
+ }
+ return true;
+ }
+
+ public FieldDescriptor get(final GeneratedMessageV3 message) {
+ int fieldNumber = ((Internal.EnumLite) invokeOrDie(caseMethod, message)).getNumber();
+ if (fieldNumber > 0) {
+ return descriptor.findFieldByNumber(fieldNumber);
+ }
+ return null;
+ }
+
+ public FieldDescriptor get(GeneratedMessageV3.Builder builder) {
+ int fieldNumber = ((Internal.EnumLite) invokeOrDie(caseMethodBuilder, builder)).getNumber();
+ if (fieldNumber > 0) {
+ return descriptor.findFieldByNumber(fieldNumber);
+ }
+ return null;
+ }
+
+ public void clear(final Builder builder) {
+ invokeOrDie(clearMethod, builder);
+ }
+ }
+
+ private static boolean supportFieldPresence(FileDescriptor file) {
+ return file.getSyntax() == FileDescriptor.Syntax.PROTO2;
+ }
+
+ // ---------------------------------------------------------------
+
+ private static class SingularFieldAccessor implements FieldAccessor {
+ SingularFieldAccessor(
+ final FieldDescriptor descriptor, final String camelCaseName,
+ final Class<? extends GeneratedMessageV3> messageClass,
+ final Class<? extends Builder> builderClass,
+ final String containingOneofCamelCaseName) {
+ field = descriptor;
+ isOneofField = descriptor.getContainingOneof() != null;
+ hasHasMethod = supportFieldPresence(descriptor.getFile())
+ || (!isOneofField && descriptor.getJavaType() == FieldDescriptor.JavaType.MESSAGE);
+ getMethod = getMethodOrDie(messageClass, "get" + camelCaseName);
+ getMethodBuilder = getMethodOrDie(builderClass, "get" + camelCaseName);
+ type = getMethod.getReturnType();
+ setMethod = getMethodOrDie(builderClass, "set" + camelCaseName, type);
+ hasMethod =
+ hasHasMethod ? getMethodOrDie(messageClass, "has" + camelCaseName) : null;
+ hasMethodBuilder =
+ hasHasMethod ? getMethodOrDie(builderClass, "has" + camelCaseName) : null;
+ clearMethod = getMethodOrDie(builderClass, "clear" + camelCaseName);
+ caseMethod = isOneofField ? getMethodOrDie(
+ messageClass, "get" + containingOneofCamelCaseName + "Case") : null;
+ caseMethodBuilder = isOneofField ? getMethodOrDie(
+ builderClass, "get" + containingOneofCamelCaseName + "Case") : null;
+ }
+
+ // Note: We use Java reflection to call public methods rather than
+ // access private fields directly as this avoids runtime security
+ // checks.
+ protected final Class<?> type;
+ protected final Method getMethod;
+ protected final Method getMethodBuilder;
+ protected final Method setMethod;
+ protected final Method hasMethod;
+ protected final Method hasMethodBuilder;
+ protected final Method clearMethod;
+ protected final Method caseMethod;
+ protected final Method caseMethodBuilder;
+ protected final FieldDescriptor field;
+ protected final boolean isOneofField;
+ protected final boolean hasHasMethod;
+
+ private int getOneofFieldNumber(final GeneratedMessageV3 message) {
+ return ((Internal.EnumLite) invokeOrDie(caseMethod, message)).getNumber();
+ }
+
+ private int getOneofFieldNumber(final GeneratedMessageV3.Builder builder) {
+ return ((Internal.EnumLite) invokeOrDie(caseMethodBuilder, builder)).getNumber();
+ }
+
+ @Override
+ public Object get(final GeneratedMessageV3 message) {
+ return invokeOrDie(getMethod, message);
+ }
+ @Override
+ public Object get(GeneratedMessageV3.Builder builder) {
+ return invokeOrDie(getMethodBuilder, builder);
+ }
+ @Override
+ public Object getRaw(final GeneratedMessageV3 message) {
+ return get(message);
+ }
+ @Override
+ public Object getRaw(GeneratedMessageV3.Builder builder) {
+ return get(builder);
+ }
+ @Override
+ public void set(final Builder builder, final Object value) {
+ invokeOrDie(setMethod, builder, value);
+ }
+ @Override
+ public Object getRepeated(final GeneratedMessageV3 message, final int index) {
+ throw new UnsupportedOperationException(
+ "getRepeatedField() called on a singular field.");
+ }
+ @Override
+ public Object getRepeatedRaw(final GeneratedMessageV3 message, final int index) {
+ throw new UnsupportedOperationException(
+ "getRepeatedFieldRaw() called on a singular field.");
+ }
+ @Override
+ public Object getRepeated(GeneratedMessageV3.Builder builder, int index) {
+ throw new UnsupportedOperationException(
+ "getRepeatedField() called on a singular field.");
+ }
+ @Override
+ public Object getRepeatedRaw(GeneratedMessageV3.Builder builder, int index) {
+ throw new UnsupportedOperationException(
+ "getRepeatedFieldRaw() called on a singular field.");
+ }
+ @Override
+ public void setRepeated(final Builder builder, final int index, final Object value) {
+ throw new UnsupportedOperationException(
+ "setRepeatedField() called on a singular field.");
+ }
+ @Override
+ public void addRepeated(final Builder builder, final Object value) {
+ throw new UnsupportedOperationException(
+ "addRepeatedField() called on a singular field.");
+ }
+ @Override
+ public boolean has(final GeneratedMessageV3 message) {
+ if (!hasHasMethod) {
+ if (isOneofField) {
+ return getOneofFieldNumber(message) == field.getNumber();
+ }
+ return !get(message).equals(field.getDefaultValue());
+ }
+ return (Boolean) invokeOrDie(hasMethod, message);
+ }
+ @Override
+ public boolean has(GeneratedMessageV3.Builder builder) {
+ if (!hasHasMethod) {
+ if (isOneofField) {
+ return getOneofFieldNumber(builder) == field.getNumber();
+ }
+ return !get(builder).equals(field.getDefaultValue());
+ }
+ return (Boolean) invokeOrDie(hasMethodBuilder, builder);
+ }
+ @Override
+ public int getRepeatedCount(final GeneratedMessageV3 message) {
+ throw new UnsupportedOperationException(
+ "getRepeatedFieldSize() called on a singular field.");
+ }
+ @Override
+ public int getRepeatedCount(GeneratedMessageV3.Builder builder) {
+ throw new UnsupportedOperationException(
+ "getRepeatedFieldSize() called on a singular field.");
+ }
+ @Override
+ public void clear(final Builder builder) {
+ invokeOrDie(clearMethod, builder);
+ }
+ @Override
+ public Message.Builder newBuilder() {
+ throw new UnsupportedOperationException(
+ "newBuilderForField() called on a non-Message type.");
+ }
+ @Override
+ public Message.Builder getBuilder(GeneratedMessageV3.Builder builder) {
+ throw new UnsupportedOperationException(
+ "getFieldBuilder() called on a non-Message type.");
+ }
+ @Override
+ public Message.Builder getRepeatedBuilder(GeneratedMessageV3.Builder builder, int index) {
+ throw new UnsupportedOperationException(
+ "getRepeatedFieldBuilder() called on a non-Message type.");
+ }
+ }
+
+ private static class RepeatedFieldAccessor implements FieldAccessor {
+ protected final Class type;
+ protected final Method getMethod;
+ protected final Method getMethodBuilder;
+ protected final Method getRepeatedMethod;
+ protected final Method getRepeatedMethodBuilder;
+ protected final Method setRepeatedMethod;
+ protected final Method addRepeatedMethod;
+ protected final Method getCountMethod;
+ protected final Method getCountMethodBuilder;
+ protected final Method clearMethod;
+
+ RepeatedFieldAccessor(
+ final FieldDescriptor descriptor, final String camelCaseName,
+ final Class<? extends GeneratedMessageV3> messageClass,
+ final Class<? extends Builder> builderClass) {
+ getMethod = getMethodOrDie(messageClass,
+ "get" + camelCaseName + "List");
+ getMethodBuilder = getMethodOrDie(builderClass,
+ "get" + camelCaseName + "List");
+ getRepeatedMethod =
+ getMethodOrDie(messageClass, "get" + camelCaseName, Integer.TYPE);
+ getRepeatedMethodBuilder =
+ getMethodOrDie(builderClass, "get" + camelCaseName, Integer.TYPE);
+ type = getRepeatedMethod.getReturnType();
+ setRepeatedMethod =
+ getMethodOrDie(builderClass, "set" + camelCaseName,
+ Integer.TYPE, type);
+ addRepeatedMethod =
+ getMethodOrDie(builderClass, "add" + camelCaseName, type);
+ getCountMethod =
+ getMethodOrDie(messageClass, "get" + camelCaseName + "Count");
+ getCountMethodBuilder =
+ getMethodOrDie(builderClass, "get" + camelCaseName + "Count");
+
+ clearMethod = getMethodOrDie(builderClass, "clear" + camelCaseName);
+ }
+
+ @Override
+ public Object get(final GeneratedMessageV3 message) {
+ return invokeOrDie(getMethod, message);
+ }
+ @Override
+ public Object get(GeneratedMessageV3.Builder builder) {
+ return invokeOrDie(getMethodBuilder, builder);
+ }
+ @Override
+ public Object getRaw(final GeneratedMessageV3 message) {
+ return get(message);
+ }
+ @Override
+ public Object getRaw(GeneratedMessageV3.Builder builder) {
+ return get(builder);
+ }
+ @Override
+ public void set(final Builder builder, final Object value) {
+ // Add all the elements individually. This serves two purposes:
+ // 1) Verifies that each element has the correct type.
+ // 2) Insures that the caller cannot modify the list later on and
+ // have the modifications be reflected in the message.
+ clear(builder);
+ for (final Object element : (List<?>) value) {
+ addRepeated(builder, element);
+ }
+ }
+ @Override
+ public Object getRepeated(final GeneratedMessageV3 message, final int index) {
+ return invokeOrDie(getRepeatedMethod, message, index);
+ }
+ @Override
+ public Object getRepeated(GeneratedMessageV3.Builder builder, int index) {
+ return invokeOrDie(getRepeatedMethodBuilder, builder, index);
+ }
+ @Override
+ public Object getRepeatedRaw(GeneratedMessageV3 message, int index) {
+ return getRepeated(message, index);
+ }
+ @Override
+ public Object getRepeatedRaw(GeneratedMessageV3.Builder builder, int index) {
+ return getRepeated(builder, index);
+ }
+ @Override
+ public void setRepeated(final Builder builder, final int index, final Object value) {
+ invokeOrDie(setRepeatedMethod, builder, index, value);
+ }
+ @Override
+ public void addRepeated(final Builder builder, final Object value) {
+ invokeOrDie(addRepeatedMethod, builder, value);
+ }
+ @Override
+ public boolean has(final GeneratedMessageV3 message) {
+ throw new UnsupportedOperationException(
+ "hasField() called on a repeated field.");
+ }
+ @Override
+ public boolean has(GeneratedMessageV3.Builder builder) {
+ throw new UnsupportedOperationException(
+ "hasField() called on a repeated field.");
+ }
+ @Override
+ public int getRepeatedCount(final GeneratedMessageV3 message) {
+ return (Integer) invokeOrDie(getCountMethod, message);
+ }
+ @Override
+ public int getRepeatedCount(GeneratedMessageV3.Builder builder) {
+ return (Integer) invokeOrDie(getCountMethodBuilder, builder);
+ }
+ @Override
+ public void clear(final Builder builder) {
+ invokeOrDie(clearMethod, builder);
+ }
+ @Override
+ public Message.Builder newBuilder() {
+ throw new UnsupportedOperationException(
+ "newBuilderForField() called on a non-Message type.");
+ }
+ @Override
+ public Message.Builder getBuilder(GeneratedMessageV3.Builder builder) {
+ throw new UnsupportedOperationException(
+ "getFieldBuilder() called on a non-Message type.");
+ }
+ @Override
+ public Message.Builder getRepeatedBuilder(GeneratedMessageV3.Builder builder, int index) {
+ throw new UnsupportedOperationException(
+ "getRepeatedFieldBuilder() called on a non-Message type.");
+ }
+ }
+
+ private static class MapFieldAccessor implements FieldAccessor {
+ MapFieldAccessor(
+ final FieldDescriptor descriptor, final String camelCaseName,
+ final Class<? extends GeneratedMessageV3> messageClass,
+ final Class<? extends Builder> builderClass) {
+ field = descriptor;
+ Method getDefaultInstanceMethod =
+ getMethodOrDie(messageClass, "getDefaultInstance");
+ MapField defaultMapField = getMapField(
+ (GeneratedMessageV3) invokeOrDie(getDefaultInstanceMethod, null));
+ mapEntryMessageDefaultInstance =
+ defaultMapField.getMapEntryMessageDefaultInstance();
+ }
+
+ private final FieldDescriptor field;
+ private final Message mapEntryMessageDefaultInstance;
+
+ private MapField<?, ?> getMapField(GeneratedMessageV3 message) {
+ return (MapField<?, ?>) message.internalGetMapField(field.getNumber());
+ }
+
+ private MapField<?, ?> getMapField(GeneratedMessageV3.Builder builder) {
+ return (MapField<?, ?>) builder.internalGetMapField(field.getNumber());
+ }
+
+ private MapField<?, ?> getMutableMapField(
+ GeneratedMessageV3.Builder builder) {
+ return (MapField<?, ?>) builder.internalGetMutableMapField(
+ field.getNumber());
+ }
+
+ @Override
+ public Object get(GeneratedMessageV3 message) {
+ List result = new ArrayList();
+ for (int i = 0; i < getRepeatedCount(message); i++) {
+ result.add(getRepeated(message, i));
+ }
+ return Collections.unmodifiableList(result);
+ }
+
+ @Override
+ public Object get(Builder builder) {
+ List result = new ArrayList();
+ for (int i = 0; i < getRepeatedCount(builder); i++) {
+ result.add(getRepeated(builder, i));
+ }
+ return Collections.unmodifiableList(result);
+ }
+
+ @Override
+ public Object getRaw(GeneratedMessageV3 message) {
+ return get(message);
+ }
+
+ @Override
+ public Object getRaw(GeneratedMessageV3.Builder builder) {
+ return get(builder);
+ }
+
+ @Override
+ public void set(Builder builder, Object value) {
+ clear(builder);
+ for (Object entry : (List) value) {
+ addRepeated(builder, entry);
+ }
+ }
+
+ @Override
+ public Object getRepeated(GeneratedMessageV3 message, int index) {
+ return getMapField(message).getList().get(index);
+ }
+
+ @Override
+ public Object getRepeated(Builder builder, int index) {
+ return getMapField(builder).getList().get(index);
+ }
+
+ @Override
+ public Object getRepeatedRaw(GeneratedMessageV3 message, int index) {
+ return getRepeated(message, index);
+ }
+
+ @Override
+ public Object getRepeatedRaw(Builder builder, int index) {
+ return getRepeated(builder, index);
+ }
+
+ @Override
+ public void setRepeated(Builder builder, int index, Object value) {
+ getMutableMapField(builder).getMutableList().set(index, (Message) value);
+ }
+
+ @Override
+ public void addRepeated(Builder builder, Object value) {
+ getMutableMapField(builder).getMutableList().add((Message) value);
+ }
+
+ @Override
+ public boolean has(GeneratedMessageV3 message) {
+ throw new UnsupportedOperationException(
+ "hasField() is not supported for repeated fields.");
+ }
+
+ @Override
+ public boolean has(Builder builder) {
+ throw new UnsupportedOperationException(
+ "hasField() is not supported for repeated fields.");
+ }
+
+ @Override
+ public int getRepeatedCount(GeneratedMessageV3 message) {
+ return getMapField(message).getList().size();
+ }
+
+ @Override
+ public int getRepeatedCount(Builder builder) {
+ return getMapField(builder).getList().size();
+ }
+
+ @Override
+ public void clear(Builder builder) {
+ getMutableMapField(builder).getMutableList().clear();
+ }
+
+ @Override
+ public com.google.protobuf.Message.Builder newBuilder() {
+ return mapEntryMessageDefaultInstance.newBuilderForType();
+ }
+
+ @Override
+ public com.google.protobuf.Message.Builder getBuilder(Builder builder) {
+ throw new UnsupportedOperationException(
+ "Nested builder not supported for map fields.");
+ }
+
+ @Override
+ public com.google.protobuf.Message.Builder getRepeatedBuilder(Builder builder, int index) {
+ throw new UnsupportedOperationException(
+ "Nested builder not supported for map fields.");
+ }
+ }
+
+ // ---------------------------------------------------------------
+
+ private static final class SingularEnumFieldAccessor
+ extends SingularFieldAccessor {
+ SingularEnumFieldAccessor(
+ final FieldDescriptor descriptor, final String camelCaseName,
+ final Class<? extends GeneratedMessageV3> messageClass,
+ final Class<? extends Builder> builderClass,
+ final String containingOneofCamelCaseName) {
+ super(descriptor, camelCaseName, messageClass, builderClass, containingOneofCamelCaseName);
+
+ enumDescriptor = descriptor.getEnumType();
+
+ valueOfMethod = getMethodOrDie(type, "valueOf",
+ EnumValueDescriptor.class);
+ getValueDescriptorMethod =
+ getMethodOrDie(type, "getValueDescriptor");
+
+ supportUnknownEnumValue = descriptor.getFile().supportsUnknownEnumValue();
+ if (supportUnknownEnumValue) {
+ getValueMethod =
+ getMethodOrDie(messageClass, "get" + camelCaseName + "Value");
+ getValueMethodBuilder =
+ getMethodOrDie(builderClass, "get" + camelCaseName + "Value");
+ setValueMethod =
+ getMethodOrDie(builderClass, "set" + camelCaseName + "Value", int.class);
+ }
+ }
+
+ private EnumDescriptor enumDescriptor;
+
+ private Method valueOfMethod;
+ private Method getValueDescriptorMethod;
+
+ private boolean supportUnknownEnumValue;
+ private Method getValueMethod;
+ private Method getValueMethodBuilder;
+ private Method setValueMethod;
+
+ @Override
+ public Object get(final GeneratedMessageV3 message) {
+ if (supportUnknownEnumValue) {
+ int value = (Integer) invokeOrDie(getValueMethod, message);
+ return enumDescriptor.findValueByNumberCreatingIfUnknown(value);
+ }
+ return invokeOrDie(getValueDescriptorMethod, super.get(message));
+ }
+
+ @Override
+ public Object get(final GeneratedMessageV3.Builder builder) {
+ if (supportUnknownEnumValue) {
+ int value = (Integer) invokeOrDie(getValueMethodBuilder, builder);
+ return enumDescriptor.findValueByNumberCreatingIfUnknown(value);
+ }
+ return invokeOrDie(getValueDescriptorMethod, super.get(builder));
+ }
+
+ @Override
+ public void set(final Builder builder, final Object value) {
+ if (supportUnknownEnumValue) {
+ invokeOrDie(setValueMethod, builder,
+ ((EnumValueDescriptor) value).getNumber());
+ return;
+ }
+ super.set(builder, invokeOrDie(valueOfMethod, null, value));
+ }
+ }
+
+ private static final class RepeatedEnumFieldAccessor
+ extends RepeatedFieldAccessor {
+ RepeatedEnumFieldAccessor(
+ final FieldDescriptor descriptor, final String camelCaseName,
+ final Class<? extends GeneratedMessageV3> messageClass,
+ final Class<? extends Builder> builderClass) {
+ super(descriptor, camelCaseName, messageClass, builderClass);
+
+ enumDescriptor = descriptor.getEnumType();
+
+ valueOfMethod = getMethodOrDie(type, "valueOf",
+ EnumValueDescriptor.class);
+ getValueDescriptorMethod =
+ getMethodOrDie(type, "getValueDescriptor");
+
+ supportUnknownEnumValue = descriptor.getFile().supportsUnknownEnumValue();
+ if (supportUnknownEnumValue) {
+ getRepeatedValueMethod =
+ getMethodOrDie(messageClass, "get" + camelCaseName + "Value", int.class);
+ getRepeatedValueMethodBuilder =
+ getMethodOrDie(builderClass, "get" + camelCaseName + "Value", int.class);
+ setRepeatedValueMethod =
+ getMethodOrDie(builderClass, "set" + camelCaseName + "Value", int.class, int.class);
+ addRepeatedValueMethod =
+ getMethodOrDie(builderClass, "add" + camelCaseName + "Value", int.class);
+ }
+ }
+ private EnumDescriptor enumDescriptor;
+
+ private final Method valueOfMethod;
+ private final Method getValueDescriptorMethod;
+
+ private boolean supportUnknownEnumValue;
+ private Method getRepeatedValueMethod;
+ private Method getRepeatedValueMethodBuilder;
+ private Method setRepeatedValueMethod;
+ private Method addRepeatedValueMethod;
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public Object get(final GeneratedMessageV3 message) {
+ final List newList = new ArrayList();
+ final int size = getRepeatedCount(message);
+ for (int i = 0; i < size; i++) {
+ newList.add(getRepeated(message, i));
+ }
+ return Collections.unmodifiableList(newList);
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public Object get(final GeneratedMessageV3.Builder builder) {
+ final List newList = new ArrayList();
+ final int size = getRepeatedCount(builder);
+ for (int i = 0; i < size; i++) {
+ newList.add(getRepeated(builder, i));
+ }
+ return Collections.unmodifiableList(newList);
+ }
+
+ @Override
+ public Object getRepeated(final GeneratedMessageV3 message,
+ final int index) {
+ if (supportUnknownEnumValue) {
+ int value = (Integer) invokeOrDie(getRepeatedValueMethod, message, index);
+ return enumDescriptor.findValueByNumberCreatingIfUnknown(value);
+ }
+ return invokeOrDie(getValueDescriptorMethod,
+ super.getRepeated(message, index));
+ }
+ @Override
+ public Object getRepeated(final GeneratedMessageV3.Builder builder,
+ final int index) {
+ if (supportUnknownEnumValue) {
+ int value = (Integer) invokeOrDie(getRepeatedValueMethodBuilder, builder, index);
+ return enumDescriptor.findValueByNumberCreatingIfUnknown(value);
+ }
+ return invokeOrDie(getValueDescriptorMethod,
+ super.getRepeated(builder, index));
+ }
+ @Override
+ public void setRepeated(final Builder builder,
+ final int index, final Object value) {
+ if (supportUnknownEnumValue) {
+ invokeOrDie(setRepeatedValueMethod, builder, index,
+ ((EnumValueDescriptor) value).getNumber());
+ return;
+ }
+ super.setRepeated(builder, index, invokeOrDie(valueOfMethod, null,
+ value));
+ }
+ @Override
+ public void addRepeated(final Builder builder, final Object value) {
+ if (supportUnknownEnumValue) {
+ invokeOrDie(addRepeatedValueMethod, builder,
+ ((EnumValueDescriptor) value).getNumber());
+ return;
+ }
+ super.addRepeated(builder, invokeOrDie(valueOfMethod, null, value));
+ }
+ }
+
+ // ---------------------------------------------------------------
+
+ /**
+ * Field accessor for string fields.
+ *
+ * <p>This class makes getFooBytes() and setFooBytes() available for
+ * reflection API so that reflection based serialize/parse functions can
+ * access the raw bytes of the field to preserve non-UTF8 bytes in the
+ * string.
+ *
+ * <p>This ensures the serialize/parse round-trip safety, which is important
+ * for servers which forward messages.
+ */
+ private static final class SingularStringFieldAccessor
+ extends SingularFieldAccessor {
+ SingularStringFieldAccessor(
+ final FieldDescriptor descriptor, final String camelCaseName,
+ final Class<? extends GeneratedMessageV3> messageClass,
+ final Class<? extends Builder> builderClass,
+ final String containingOneofCamelCaseName) {
+ super(descriptor, camelCaseName, messageClass, builderClass,
+ containingOneofCamelCaseName);
+ getBytesMethod = getMethodOrDie(messageClass,
+ "get" + camelCaseName + "Bytes");
+ getBytesMethodBuilder = getMethodOrDie(builderClass,
+ "get" + camelCaseName + "Bytes");
+ setBytesMethodBuilder = getMethodOrDie(builderClass,
+ "set" + camelCaseName + "Bytes", ByteString.class);
+ }
+
+ private final Method getBytesMethod;
+ private final Method getBytesMethodBuilder;
+ private final Method setBytesMethodBuilder;
+
+ @Override
+ public Object getRaw(final GeneratedMessageV3 message) {
+ return invokeOrDie(getBytesMethod, message);
+ }
+
+ @Override
+ public Object getRaw(GeneratedMessageV3.Builder builder) {
+ return invokeOrDie(getBytesMethodBuilder, builder);
+ }
+
+ @Override
+ public void set(GeneratedMessageV3.Builder builder, Object value) {
+ if (value instanceof ByteString) {
+ invokeOrDie(setBytesMethodBuilder, builder, value);
+ } else {
+ super.set(builder, value);
+ }
+ }
+ }
+
+ // ---------------------------------------------------------------
+
+ private static final class SingularMessageFieldAccessor
+ extends SingularFieldAccessor {
+ SingularMessageFieldAccessor(
+ final FieldDescriptor descriptor, final String camelCaseName,
+ final Class<? extends GeneratedMessageV3> messageClass,
+ final Class<? extends Builder> builderClass,
+ final String containingOneofCamelCaseName) {
+ super(descriptor, camelCaseName, messageClass, builderClass,
+ containingOneofCamelCaseName);
+
+ newBuilderMethod = getMethodOrDie(type, "newBuilder");
+ getBuilderMethodBuilder =
+ getMethodOrDie(builderClass, "get" + camelCaseName + "Builder");
+ }
+
+ private final Method newBuilderMethod;
+ private final Method getBuilderMethodBuilder;
+
+ private Object coerceType(final Object value) {
+ if (type.isInstance(value)) {
+ return value;
+ } else {
+ // The value is not the exact right message type. However, if it
+ // is an alternative implementation of the same type -- e.g. a
+ // DynamicMessage -- we should accept it. In this case we can make
+ // a copy of the message.
+ return ((Message.Builder) invokeOrDie(newBuilderMethod, null))
+ .mergeFrom((Message) value).buildPartial();
+ }
+ }
+
+ @Override
+ public void set(final Builder builder, final Object value) {
+ super.set(builder, coerceType(value));
+ }
+ @Override
+ public Message.Builder newBuilder() {
+ return (Message.Builder) invokeOrDie(newBuilderMethod, null);
+ }
+ @Override
+ public Message.Builder getBuilder(GeneratedMessageV3.Builder builder) {
+ return (Message.Builder) invokeOrDie(getBuilderMethodBuilder, builder);
+ }
+ }
+
+ private static final class RepeatedMessageFieldAccessor
+ extends RepeatedFieldAccessor {
+ RepeatedMessageFieldAccessor(
+ final FieldDescriptor descriptor, final String camelCaseName,
+ final Class<? extends GeneratedMessageV3> messageClass,
+ final Class<? extends Builder> builderClass) {
+ super(descriptor, camelCaseName, messageClass, builderClass);
+
+ newBuilderMethod = getMethodOrDie(type, "newBuilder");
+ getBuilderMethodBuilder = getMethodOrDie(builderClass,
+ "get" + camelCaseName + "Builder", Integer.TYPE);
+ }
+
+ private final Method newBuilderMethod;
+ private final Method getBuilderMethodBuilder;
+
+ private Object coerceType(final Object value) {
+ if (type.isInstance(value)) {
+ return value;
+ } else {
+ // The value is not the exact right message type. However, if it
+ // is an alternative implementation of the same type -- e.g. a
+ // DynamicMessage -- we should accept it. In this case we can make
+ // a copy of the message.
+ return ((Message.Builder) invokeOrDie(newBuilderMethod, null))
+ .mergeFrom((Message) value).build();
+ }
+ }
+
+ @Override
+ public void setRepeated(final Builder builder,
+ final int index, final Object value) {
+ super.setRepeated(builder, index, coerceType(value));
+ }
+ @Override
+ public void addRepeated(final Builder builder, final Object value) {
+ super.addRepeated(builder, coerceType(value));
+ }
+ @Override
+ public Message.Builder newBuilder() {
+ return (Message.Builder) invokeOrDie(newBuilderMethod, null);
+ }
+ @Override
+ public Message.Builder getRepeatedBuilder(
+ final GeneratedMessageV3.Builder builder, final int index) {
+ return (Message.Builder) invokeOrDie(
+ getBuilderMethodBuilder, builder, index);
+ }
+ }
+ }
+
+ /**
+ * Replaces this object in the output stream with a serialized form.
+ * Part of Java's serialization magic. Generated sub-classes must override
+ * this method by calling {@code return super.writeReplace();}
+ * @return a SerializedForm of this message
+ */
+ protected Object writeReplace() throws ObjectStreamException {
+ return new GeneratedMessageLite.SerializedForm(this);
+ }
+
+ /**
+ * Checks that the {@link Extension} is non-Lite and returns it as a
+ * {@link GeneratedExtension}.
+ */
+ private static <MessageType extends ExtendableMessage<MessageType>, T>
+ Extension<MessageType, T> checkNotLite(
+ ExtensionLite<MessageType, T> extension) {
+ if (extension.isLite()) {
+ throw new IllegalArgumentException("Expected non-lite extension.");
+ }
+
+ return (Extension<MessageType, T>) extension;
+ }
+
+ protected static int computeStringSize(final int fieldNumber, final Object value) {
+ if (value instanceof String) {
+ return CodedOutputStream.computeStringSize(fieldNumber, (String) value);
+ } else {
+ return CodedOutputStream.computeBytesSize(fieldNumber, (ByteString) value);
+ }
+ }
+
+ protected static int computeStringSizeNoTag(final Object value) {
+ if (value instanceof String) {
+ return CodedOutputStream.computeStringSizeNoTag((String) value);
+ } else {
+ return CodedOutputStream.computeBytesSizeNoTag((ByteString) value);
+ }
+ }
+
+ protected static void writeString(
+ CodedOutputStream output, final int fieldNumber, final Object value) throws IOException {
+ if (value instanceof String) {
+ output.writeString(fieldNumber, (String) value);
+ } else {
+ output.writeBytes(fieldNumber, (ByteString) value);
+ }
+ }
+
+ protected static void writeStringNoTag(
+ CodedOutputStream output, final Object value) throws IOException {
+ if (value instanceof String) {
+ output.writeStringNoTag((String) value);
+ } else {
+ output.writeBytesNoTag((ByteString) value);
+ }
+ }
+}
diff --git a/java/src/main/java/com/google/protobuf/IntArrayList.java b/java/core/src/main/java/com/google/protobuf/IntArrayList.java
index f7609cc9..2f526e3f 100644
--- a/java/src/main/java/com/google/protobuf/IntArrayList.java
+++ b/java/core/src/main/java/com/google/protobuf/IntArrayList.java
@@ -34,32 +34,31 @@ import com.google.protobuf.Internal.IntList;
import java.util.Arrays;
import java.util.Collection;
-import java.util.List;
import java.util.RandomAccess;
/**
* An implementation of {@link IntList} on top of a primitive array.
- *
+ *
* @author dweis@google.com (Daniel Weis)
*/
-final class IntArrayList extends AbstractProtobufList<Integer> implements IntList, RandomAccess {
-
- private static final int DEFAULT_CAPACITY = 10;
-
+final class IntArrayList
+ extends AbstractProtobufList<Integer>
+ implements IntList, RandomAccess {
+
private static final IntArrayList EMPTY_LIST = new IntArrayList();
static {
EMPTY_LIST.makeImmutable();
}
-
+
public static IntArrayList emptyList() {
return EMPTY_LIST;
}
-
+
/**
* The backing store for the list.
*/
private int[] array;
-
+
/**
* The size of the list distinct from the length of the array. That is, it is the number of
* elements set in the list.
@@ -67,30 +66,61 @@ final class IntArrayList extends AbstractProtobufList<Integer> implements IntLis
private int size;
/**
- * Constructs a new mutable {@code IntArrayList}.
+ * Constructs a new mutable {@code IntArrayList} with default capacity.
*/
IntArrayList() {
- array = new int[DEFAULT_CAPACITY];
- size = 0;
+ this(new int[DEFAULT_CAPACITY], 0);
}
/**
- * Constructs a new mutable {@code IntArrayList} containing the same elements as {@code other}.
+ * Constructs a new mutable {@code IntArrayList}
+ * containing the same elements as {@code other}.
*/
- IntArrayList(List<Integer> other) {
- if (other instanceof IntArrayList) {
- IntArrayList list = (IntArrayList) other;
- array = list.array.clone();
- size = list.size;
- } else {
- size = other.size();
- array = new int[size];
- for (int i = 0; i < size; i++) {
- array[i] = other.get(i);
+ private IntArrayList(int[] other, int size) {
+ array = other;
+ this.size = size;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof IntArrayList)) {
+ return super.equals(o);
+ }
+ IntArrayList other = (IntArrayList) o;
+ if (size != other.size) {
+ return false;
+ }
+
+ final int[] arr = other.array;
+ for (int i = 0; i < size; i++) {
+ if (array[i] != arr[i]) {
+ return false;
}
}
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = 1;
+ for (int i = 0; i < size; i++) {
+ result = (31 * result) + array[i];
+ }
+ return result;
}
-
+
+ @Override
+ public IntList mutableCopyWithCapacity(int capacity) {
+ if (capacity < size) {
+ throw new IllegalArgumentException();
+ }
+ return new IntArrayList(Arrays.copyOf(array, capacity), size);
+ }
+
@Override
public Integer get(int index) {
return getInt(index);
@@ -142,7 +172,7 @@ final class IntArrayList extends AbstractProtobufList<Integer> implements IntLis
if (index < 0 || index > size) {
throw new IndexOutOfBoundsException(makeOutOfBoundsExceptionMessage(index));
}
-
+
if (size < array.length) {
// Shift everything over to make room
System.arraycopy(array, index, array, index + 1, size - index);
@@ -150,10 +180,10 @@ final class IntArrayList extends AbstractProtobufList<Integer> implements IntLis
// Resize to 1.5x the size
int length = ((size * 3) / 2) + 1;
int[] newArray = new int[length];
-
+
// Copy the first part directly
System.arraycopy(array, 0, newArray, 0, index);
-
+
// Copy the rest shifted over by one to make room
System.arraycopy(array, index, newArray, index + 1, size - index);
array = newArray;
@@ -167,38 +197,38 @@ final class IntArrayList extends AbstractProtobufList<Integer> implements IntLis
@Override
public boolean addAll(Collection<? extends Integer> collection) {
ensureIsMutable();
-
+
if (collection == null) {
throw new NullPointerException();
}
-
+
// We specialize when adding another IntArrayList to avoid boxing elements.
if (!(collection instanceof IntArrayList)) {
return super.addAll(collection);
}
-
+
IntArrayList list = (IntArrayList) collection;
if (list.size == 0) {
return false;
}
-
+
int overflow = Integer.MAX_VALUE - size;
if (overflow < list.size) {
// We can't actually represent a list this large.
throw new OutOfMemoryError();
}
-
+
int newSize = size + list.size;
if (newSize > array.length) {
array = Arrays.copyOf(array, newSize);
}
-
+
System.arraycopy(list.array, 0, array, size, list.size);
size = newSize;
modCount++;
return true;
}
-
+
@Override
public boolean remove(Object o) {
ensureIsMutable();
@@ -227,7 +257,7 @@ final class IntArrayList extends AbstractProtobufList<Integer> implements IntLis
/**
* Ensures that the provided {@code index} is within the range of {@code [0, size]}. Throws an
* {@link IndexOutOfBoundsException} if it is not.
- *
+ *
* @param index the index to verify is in range
*/
private void ensureIndexInRange(int index) {
diff --git a/java/src/main/java/com/google/protobuf/Internal.java b/java/core/src/main/java/com/google/protobuf/Internal.java
index 11901998..3b4a0412 100644
--- a/java/src/main/java/com/google/protobuf/Internal.java
+++ b/java/core/src/main/java/com/google/protobuf/Internal.java
@@ -41,6 +41,7 @@ import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.RandomAccess;
import java.util.Set;
/**
@@ -51,10 +52,12 @@ import java.util.Set;
*
* @author kenton@google.com (Kenton Varda)
*/
-public class Internal {
+public final class Internal {
- protected static final Charset UTF_8 = Charset.forName("UTF-8");
- protected static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
+ private Internal() {}
+
+ static final Charset UTF_8 = Charset.forName("UTF-8");
+ static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
/**
* Helper called by generated code to construct default values for string
@@ -283,10 +286,32 @@ public class Internal {
// ByteString with the same content. This is to ensure that the generated
// hashCode() method will return the same value as the pure reflection
// based hashCode() method.
- return LiteralByteString.hashCode(bytes);
+ return Internal.hashCode(bytes, 0, bytes.length);
+ }
+
+ /**
+ * Helper method for implementing {@link LiteralByteString#hashCode()}.
+ */
+ static int hashCode(byte[] bytes, int offset, int length) {
+ // The hash code for a byte array should be the same as the hash code for a
+ // ByteString with the same content. This is to ensure that the generated
+ // hashCode() method will return the same value as the pure reflection
+ // based hashCode() method.
+ int h = Internal.partialHash(length, bytes, offset, length);
+ return h == 0 ? 1 : h;
}
/**
+ * Helper method for continuously hashing bytes.
+ */
+ static int partialHash(int h, byte[] bytes, int offset, int length) {
+ for (int i = offset; i < offset + length; i++) {
+ h = h * 31 + bytes[i];
+ }
+ return h;
+ }
+
+ /**
* Helper method for implementing {@link Message#equals(Object)} for bytes
* field.
*/
@@ -337,8 +362,7 @@ public class Internal {
public static int hashCodeByteBuffer(ByteBuffer bytes) {
if (bytes.hasArray()) {
// Fast path.
- int h = LiteralByteString.hashCode(bytes.capacity(), bytes.array(),
- bytes.arrayOffset(), bytes.capacity());
+ int h = partialHash(bytes.capacity(), bytes.array(), bytes.arrayOffset(), bytes.capacity());
return h == 0 ? 1 : h;
} else {
// Read the data into a temporary byte array before calculating the
@@ -353,7 +377,7 @@ public class Internal {
final int length = duplicated.remaining() <= bufferSize ?
duplicated.remaining() : bufferSize;
duplicated.get(buffer, 0, length);
- h = LiteralByteString.hashCode(h, buffer, 0, length);
+ h = partialHash(h, buffer, 0, length);
}
return h == 0 ? 1 : h;
}
@@ -434,10 +458,13 @@ public class Internal {
public static <T extends EnumLite> Converter<Integer, T> newEnumConverter(
final EnumLiteMap<T> enumMap, final T unrecognizedValue) {
return new Converter<Integer, T>() {
+ @Override
public T doForward(Integer value) {
T result = enumMap.findValueByNumber(value);
return result == null ? unrecognizedValue : result;
}
+
+ @Override
public Integer doBackward(T value) {
return value.getNumber();
}
@@ -550,8 +577,10 @@ public class Internal {
/**
* Extends {@link List} to add the capability to make the list immutable and inspect if it is
* modifiable.
+ * <p>
+ * All implementations must support efficient random access.
*/
- public static interface ProtobufList<E> extends List<E> {
+ public static interface ProtobufList<E> extends List<E>, RandomAccess {
/**
* Makes this list immutable. All subsequent modifications will throw an
@@ -563,6 +592,11 @@ public class Internal {
* Returns whether this list can be modified via the publicly accessible {@link List} methods.
*/
boolean isModifiable();
+
+ /**
+ * Returns a mutable clone of this list with the specified capacity.
+ */
+ ProtobufList<E> mutableCopyWithCapacity(int capacity);
}
/**
@@ -585,6 +619,12 @@ public class Internal {
* Like {@link #set(int, Object)} but more efficient in that it doesn't box the element.
*/
int setInt(int index, int element);
+
+ /**
+ * Returns a mutable clone of this list with the specified capacity.
+ */
+ @Override
+ IntList mutableCopyWithCapacity(int capacity);
}
/**
@@ -607,6 +647,12 @@ public class Internal {
* Like {@link #set(int, Object)} but more efficient in that it doesn't box the element.
*/
boolean setBoolean(int index, boolean element);
+
+ /**
+ * Returns a mutable clone of this list with the specified capacity.
+ */
+ @Override
+ BooleanList mutableCopyWithCapacity(int capacity);
}
/**
@@ -629,6 +675,12 @@ public class Internal {
* Like {@link #set(int, Object)} but more efficient in that it doesn't box the element.
*/
long setLong(int index, long element);
+
+ /**
+ * Returns a mutable clone of this list with the specified capacity.
+ */
+ @Override
+ LongList mutableCopyWithCapacity(int capacity);
}
/**
@@ -651,6 +703,12 @@ public class Internal {
* Like {@link #set(int, Object)} but more efficient in that it doesn't box the element.
*/
double setDouble(int index, double element);
+
+ /**
+ * Returns a mutable clone of this list with the specified capacity.
+ */
+ @Override
+ DoubleList mutableCopyWithCapacity(int capacity);
}
/**
@@ -673,5 +731,11 @@ public class Internal {
* Like {@link #set(int, Object)} but more efficient in that it doesn't box the element.
*/
float setFloat(int index, float element);
+
+ /**
+ * Returns a mutable clone of this list with the specified capacity.
+ */
+ @Override
+ FloatList mutableCopyWithCapacity(int capacity);
}
}
diff --git a/java/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java b/java/core/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java
index 0a761052..85ce7b24 100644
--- a/java/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java
+++ b/java/core/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java
@@ -46,6 +46,10 @@ public class InvalidProtocolBufferException extends IOException {
super(description);
}
+ public InvalidProtocolBufferException(IOException e) {
+ super(e.getMessage(), e);
+ }
+
/**
* Attaches an unfinished message to the exception to support best-effort
* parsing in {@code Parser} interface.
@@ -66,6 +70,14 @@ public class InvalidProtocolBufferException extends IOException {
return unfinishedMessage;
}
+ /**
+ * Unwraps the underlying {@link IOException} if this exception was caused by an I/O
+ * problem. Otherwise, returns {@code this}.
+ */
+ public IOException unwrapIOException() {
+ return getCause() instanceof IOException ? (IOException) getCause() : this;
+ }
+
static InvalidProtocolBufferException truncatedMessage() {
return new InvalidProtocolBufferException(
"While parsing a protocol message, the input ended unexpectedly " +
diff --git a/java/src/main/java/com/google/protobuf/LazyField.java b/java/core/src/main/java/com/google/protobuf/LazyField.java
index 5e0a485c..98e13ca1 100644
--- a/java/src/main/java/com/google/protobuf/LazyField.java
+++ b/java/core/src/main/java/com/google/protobuf/LazyField.java
@@ -39,14 +39,14 @@ import java.util.Map.Entry;
*
* Most of key methods are implemented in {@link LazyFieldLite} but this class
* can contain default instance of the message to provide {@code hashCode()},
- * {@code equals()} and {@code toString()}.
+ * {@code euqals()} and {@code toString()}.
*
* @author xiangl@google.com (Xiang Li)
*/
public class LazyField extends LazyFieldLite {
/**
- * Carry a message's default instance which is used by {@code hashCode()}, {@code equals()} and
+ * Carry a message's default instance which is used by {@code hashCode()}, {@code euqals()} and
* {@code toString()}.
*/
private final MessageLite defaultInstance;
@@ -95,12 +95,12 @@ public class LazyField extends LazyFieldLite {
this.entry = entry;
}
- // @Override
+ @Override
public K getKey() {
return entry.getKey();
}
- // @Override
+ @Override
public Object getValue() {
LazyField field = entry.getValue();
if (field == null) {
@@ -113,7 +113,7 @@ public class LazyField extends LazyFieldLite {
return entry.getValue();
}
- // @Override
+ @Override
public Object setValue(Object value) {
if (!(value instanceof MessageLite)) {
throw new IllegalArgumentException(
@@ -131,13 +131,13 @@ public class LazyField extends LazyFieldLite {
this.iterator = iterator;
}
- // @Override
+ @Override
public boolean hasNext() {
return iterator.hasNext();
}
+ @Override
@SuppressWarnings("unchecked")
- // @Override
public Entry<K, Object> next() {
Entry<K, ?> entry = iterator.next();
if (entry.getValue() instanceof LazyField) {
@@ -146,7 +146,7 @@ public class LazyField extends LazyFieldLite {
return (Entry<K, Object>) entry;
}
- // @Override
+ @Override
public void remove() {
iterator.remove();
}
diff --git a/java/src/main/java/com/google/protobuf/LazyFieldLite.java b/java/core/src/main/java/com/google/protobuf/LazyFieldLite.java
index eea1fe3c..2febaace 100644
--- a/java/src/main/java/com/google/protobuf/LazyFieldLite.java
+++ b/java/core/src/main/java/com/google/protobuf/LazyFieldLite.java
@@ -30,14 +30,26 @@
package com.google.protobuf;
+import java.io.IOException;
+
/**
* LazyFieldLite encapsulates the logic of lazily parsing message fields. It stores
- * the message in a ByteString initially and then parse it on-demand.
+ * the message in a ByteString initially and then parses it on-demand.
+ *
+ * LazyFieldLite is thread-compatible: concurrent reads are safe once the proto that this
+ * LazyFieldLite is a part of is no longer being mutated by its Builder. However, explicit
+ * synchronization is needed under read/write situations.
*
- * LazyField is thread-compatible e.g. concurrent read are safe, however,
- * synchronizations are needed under read/write situations.
+ * When a LazyFieldLite is used in the context of a MessageLite object, its behavior is considered
+ * to be immutable and none of the setter methods in its API are expected to be invoked. All of the
+ * getters are expected to be thread-safe. When used in the context of a MessageLite.Builder,
+ * setters can be invoked, but there is no guarantee of thread safety.
+ *
+ * TODO(yatin,dweis): Consider splitting this class's functionality and put the mutable methods
+ * into a separate builder class to allow us to give stronger compile-time guarantees.
*
- * This class is internal implementation detail, so you don't need to use it directly.
+ * This class is internal implementation detail of the protobuf library, so you don't need to use it
+ * directly.
*
* @author xiangl@google.com (Xiang Li)
*/
@@ -46,8 +58,34 @@ public class LazyFieldLite {
ExtensionRegistryLite.getEmptyRegistry();
/**
- * A delayed-parsed version of the bytes. When this is non-null then {@code extensionRegistry } is
- * also non-null and {@code value} and {@code memoizedBytes} are null.
+ * The value associated with the LazyFieldLite object is stored in one or more of the following
+ * three fields (delayedBytes, value, memoizedBytes). They should together be interpreted as
+ * follows.
+ * 1) delayedBytes can be non-null, while value and memoizedBytes is null. The object will be in
+ * this state while the value for the object has not yet been parsed.
+ * 2) Both delayedBytes and value are non-null. The object transitions to this state as soon as
+ * some caller needs to access the value (by invoking getValue()).
+ * 3) memoizedBytes is merely an optimization for calls to LazyFieldLite.toByteString() to avoid
+ * recomputing the ByteString representation on each call. Instead, when the value is parsed
+ * from delayedBytes, we will also assign the contents of delayedBytes to memoizedBytes (since
+ * that is the ByteString representation of value).
+ * 4) Finally, if the LazyFieldLite was created directly with a parsed MessageLite value, then
+ * delayedBytes will be null, and memoizedBytes will be initialized only upon the first call to
+ * LazyFieldLite.toByteString().
+ *
+ * Given the above conditions, any caller that needs a serialized representation of this object
+ * must first check if the memoizedBytes or delayedBytes ByteString is non-null and use it
+ * directly; if both of those are null, it can look at the parsed value field. Similarly, any
+ * caller that needs a parsed value must first check if the value field is already non-null, if
+ * not it must parse the value from delayedBytes.
+ */
+
+ /**
+ * A delayed-parsed version of the contents of this field. When this field is non-null, then the
+ * "value" field is allowed to be null until the time that the value needs to be read.
+ *
+ * When delayedBytes is non-null then {@code extensionRegistry} is required to also be non-null.
+ * {@code value} and {@code memoizedBytes} will be initialized lazily.
*/
private ByteString delayedBytes;
@@ -60,12 +98,15 @@ public class LazyFieldLite {
private ExtensionRegistryLite extensionRegistry;
/**
- * The parsed value. When this is non-null then {@code delayedBytes} will be null.
+ * The parsed value. When this is null and a caller needs access to the MessageLite value, then
+ * {@code delayedBytes} will be parsed lazily at that time.
*/
protected volatile MessageLite value;
/**
- * The memoized bytes for {@code value}. Will be null when {@code value} is null.
+ * The memoized bytes for {@code value}. This is an optimization for the toByteString() method to
+ * not have to recompute its return-value on each invocation.
+ * TODO(yatin): Figure out whether this optimization is actually necessary.
*/
private volatile ByteString memoizedBytes;
@@ -94,6 +135,43 @@ public class LazyFieldLite {
return lf;
}
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+
+ if (!(o instanceof LazyFieldLite)) {
+ return false;
+ }
+
+ LazyFieldLite other = (LazyFieldLite) o;
+
+ // Lazy fields do not work well with equals... If both are delayedBytes, we do not have a
+ // mechanism to deserialize them so we rely on bytes equality. Otherwise we coerce into an
+ // actual message (if necessary) and call equals on the message itself. This implies that two
+ // messages can by unequal but then be turned equal simply be invoking a getter on a lazy field.
+ MessageLite value1 = value;
+ MessageLite value2 = other.value;
+ if (value1 == null && value2 == null) {
+ return toByteString().equals(other.toByteString());
+ } else if (value1 != null && value2 != null) {
+ return value1.equals(value2);
+ } else if (value1 != null) {
+ return value1.equals(other.getValue(value1.getDefaultInstanceForType()));
+ } else {
+ return getValue(value2.getDefaultInstanceForType()).equals(value2);
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ // We can't provide a memoizable hash code for lazy fields. The byte strings may have different
+ // hash codes but evaluate to equivalent messages. And we have no facility for constructing
+ // a message here if we were not already holding a value.
+ return 1;
+ }
+
/**
* Determines whether this LazyFieldLite instance represents the default instance of this type.
*/
@@ -230,6 +308,46 @@ public class LazyFieldLite {
return;
}
}
+
+ /**
+ * Merges another instance's contents from a stream.
+ *
+ * <p>LazyField is not thread-safe for write access. Synchronizations are needed
+ * under read/write situations.
+ */
+ public void mergeFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry)
+ throws IOException {
+ if (this.containsDefaultInstance()) {
+ setByteString(input.readBytes(), extensionRegistry);
+ return;
+ }
+
+ // If the other field has an extension registry but this does not, copy over the other extension
+ // registry.
+ if (this.extensionRegistry == null) {
+ this.extensionRegistry = extensionRegistry;
+ }
+
+ // In the case that both of them are not parsed we simply concatenate the bytes to save time. In
+ // the (probably rare) case that they have different extension registries there is a chance that
+ // some of the extensions may be dropped, but the tradeoff of making this operation fast seems
+ // to outway the benefits of combining the extension registries, which is not normally done for
+ // lite protos anyways.
+ if (this.delayedBytes != null) {
+ setByteString(this.delayedBytes.concat(input.readBytes()), this.extensionRegistry);
+ return;
+ }
+
+ // We are parsed and both contain data. We won't drop any extensions here directly, but in the
+ // case that the extension registries are not the same then we might in the future if we
+ // need to serialize and parse a message again.
+ try {
+ setValue(value.toBuilder().mergeFrom(input, extensionRegistry).build());
+ } catch (InvalidProtocolBufferException e) {
+ // Nothing is logged and no exceptions are thrown. Clients will be unaware that a proto
+ // was invalid.
+ }
+ }
private static MessageLite mergeValueAndBytes(
MessageLite value, ByteString otherBytes, ExtensionRegistryLite extensionRegistry) {
@@ -259,10 +377,12 @@ public class LazyFieldLite {
* parsed. Be careful when using this method.
*/
public int getSerializedSize() {
- if (delayedBytes != null) {
- return delayedBytes.size();
- } else if (memoizedBytes != null) {
+ // We *must* return delayed bytes size if it was ever set because the dependent messages may
+ // have memoized serialized size based off of it.
+ if (memoizedBytes != null) {
return memoizedBytes.size();
+ } else if (delayedBytes != null) {
+ return delayedBytes.size();
} else if (value != null) {
return value.getSerializedSize();
} else {
@@ -274,12 +394,14 @@ public class LazyFieldLite {
* Returns a BytesString for this field in a thread-safe way.
*/
public ByteString toByteString() {
- if (delayedBytes != null) {
- return delayedBytes;
- }
if (memoizedBytes != null) {
return memoizedBytes;
}
+ // We *must* return delayed bytes if it was set because the dependent messages may have
+ // memoized serialized size based off of it.
+ if (delayedBytes != null) {
+ return delayedBytes;
+ }
synchronized (this) {
if (memoizedBytes != null) {
return memoizedBytes;
@@ -311,18 +433,15 @@ public class LazyFieldLite {
.parseFrom(delayedBytes, extensionRegistry);
this.value = parsedValue;
this.memoizedBytes = delayedBytes;
- this.delayedBytes = null;
} else {
this.value = defaultInstance;
this.memoizedBytes = ByteString.EMPTY;
- this.delayedBytes = null;
}
} catch (InvalidProtocolBufferException e) {
// Nothing is logged and no exceptions are thrown. Clients will be unaware that this proto
// was invalid.
this.value = defaultInstance;
this.memoizedBytes = ByteString.EMPTY;
- this.delayedBytes = null;
}
}
}
diff --git a/java/src/main/java/com/google/protobuf/LazyStringArrayList.java b/java/core/src/main/java/com/google/protobuf/LazyStringArrayList.java
index c3be3cca..d474c51e 100644
--- a/java/src/main/java/com/google/protobuf/LazyStringArrayList.java
+++ b/java/core/src/main/java/com/google/protobuf/LazyStringArrayList.java
@@ -30,12 +30,12 @@
package com.google.protobuf;
-import java.util.Arrays;
-import java.util.List;
import java.util.AbstractList;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import java.util.List;
import java.util.RandomAccess;
/**
@@ -64,7 +64,7 @@ import java.util.RandomAccess;
*/
public class LazyStringArrayList extends AbstractProtobufList<String>
implements LazyStringList, RandomAccess {
-
+
private static final LazyStringArrayList EMPTY_LIST = new LazyStringArrayList();
static {
EMPTY_LIST.makeImmutable();
@@ -80,11 +80,11 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
private final List<Object> list;
public LazyStringArrayList() {
- list = new ArrayList<Object>();
+ this(DEFAULT_CAPACITY);
}
public LazyStringArrayList(int intialCapacity) {
- list = new ArrayList<Object>(intialCapacity);
+ this(new ArrayList<Object>(intialCapacity));
}
public LazyStringArrayList(LazyStringList from) {
@@ -93,7 +93,21 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
}
public LazyStringArrayList(List<String> from) {
- list = new ArrayList<Object>(from);
+ this(new ArrayList<Object>(from));
+ }
+
+ private LazyStringArrayList(ArrayList<Object> list) {
+ this.list = list;
+ }
+
+ @Override
+ public LazyStringArrayList mutableCopyWithCapacity(int capacity) {
+ if (capacity < size()) {
+ throw new IllegalArgumentException();
+ }
+ ArrayList<Object> newList = new ArrayList<Object>(capacity);
+ newList.addAll(list);
+ return new LazyStringArrayList(newList);
}
@Override
@@ -170,7 +184,7 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
return ret;
}
- // @Override
+ @Override
public boolean addAllByteString(Collection<? extends ByteString> values) {
ensureIsMutable();
boolean ret = list.addAll(values);
@@ -178,7 +192,7 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
return ret;
}
- // @Override
+ @Override
public boolean addAllByteArray(Collection<byte[]> c) {
ensureIsMutable();
boolean ret = list.addAll(c);
@@ -201,14 +215,14 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
modCount++;
}
- // @Override
+ @Override
public void add(ByteString element) {
ensureIsMutable();
list.add(element);
modCount++;
}
- // @Override
+ @Override
public void add(byte[] element) {
ensureIsMutable();
list.add(element);
@@ -220,7 +234,7 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
return list.get(index);
}
- // @Override
+ @Override
public ByteString getByteString(int index) {
Object o = list.get(index);
ByteString b = asByteString(o);
@@ -230,7 +244,7 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
return b;
}
- // @Override
+ @Override
public byte[] getByteArray(int index) {
Object o = list.get(index);
byte[] b = asByteArray(o);
@@ -240,7 +254,7 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
return b;
}
- // @Override
+ @Override
public void set(int index, ByteString s) {
setAndReturn(index, s);
}
@@ -250,7 +264,7 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
return list.set(index, s);
}
- // @Override
+ @Override
public void set(int index, byte[] s) {
setAndReturn(index, s);
}
@@ -290,12 +304,12 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
}
}
- // @Override
+ @Override
public List<?> getUnderlyingElements() {
return Collections.unmodifiableList(list);
}
- // @Override
+ @Override
public void mergeFrom(LazyStringList other) {
ensureIsMutable();
for (Object o : other.getUnderlyingElements()) {
@@ -349,7 +363,7 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
}
}
- // @Override
+ @Override
public List<byte[]> asByteArrayList() {
return new ByteArrayListView(this);
}
@@ -393,12 +407,12 @@ public class LazyStringArrayList extends AbstractProtobufList<String>
}
}
- // @Override
+ @Override
public List<ByteString> asByteStringList() {
return new ByteStringListView(this);
}
- // @Override
+ @Override
public LazyStringList getUnmodifiableView() {
if (isModifiable()) {
return new UnmodifiableLazyStringList(this);
diff --git a/java/src/main/java/com/google/protobuf/LazyStringList.java b/java/core/src/main/java/com/google/protobuf/LazyStringList.java
index 3eeedca1..3eeedca1 100644
--- a/java/src/main/java/com/google/protobuf/LazyStringList.java
+++ b/java/core/src/main/java/com/google/protobuf/LazyStringList.java
diff --git a/java/src/main/java/com/google/protobuf/LongArrayList.java b/java/core/src/main/java/com/google/protobuf/LongArrayList.java
index 298617ff..5a772e3a 100644
--- a/java/src/main/java/com/google/protobuf/LongArrayList.java
+++ b/java/core/src/main/java/com/google/protobuf/LongArrayList.java
@@ -34,32 +34,31 @@ import com.google.protobuf.Internal.LongList;
import java.util.Arrays;
import java.util.Collection;
-import java.util.List;
import java.util.RandomAccess;
/**
* An implementation of {@link LongList} on top of a primitive array.
- *
+ *
* @author dweis@google.com (Daniel Weis)
*/
-final class LongArrayList extends AbstractProtobufList<Long> implements LongList, RandomAccess {
-
- private static final int DEFAULT_CAPACITY = 10;
-
+final class LongArrayList
+ extends AbstractProtobufList<Long>
+ implements LongList, RandomAccess {
+
private static final LongArrayList EMPTY_LIST = new LongArrayList();
static {
EMPTY_LIST.makeImmutable();
}
-
+
public static LongArrayList emptyList() {
return EMPTY_LIST;
}
-
+
/**
* The backing store for the list.
*/
private long[] array;
-
+
/**
* The size of the list distinct from the length of the array. That is, it is the number of
* elements set in the list.
@@ -67,30 +66,61 @@ final class LongArrayList extends AbstractProtobufList<Long> implements LongList
private int size;
/**
- * Constructs a new mutable {@code LongArrayList}.
+ * Constructs a new mutable {@code LongArrayList} with default capacity.
*/
LongArrayList() {
- array = new long[DEFAULT_CAPACITY];
- size = 0;
+ this(new long[DEFAULT_CAPACITY], 0);
}
/**
- * Constructs a new mutable {@code LongArrayList} containing the same elements as {@code other}.
+ * Constructs a new mutable {@code LongArrayList}
+ * containing the same elements as {@code other}.
*/
- LongArrayList(List<Long> other) {
- if (other instanceof LongArrayList) {
- LongArrayList list = (LongArrayList) other;
- array = list.array.clone();
- size = list.size;
- } else {
- size = other.size();
- array = new long[size];
- for (int i = 0; i < size; i++) {
- array[i] = other.get(i);
+ private LongArrayList(long[] other, int size) {
+ array = other;
+ this.size = size;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof LongArrayList)) {
+ return super.equals(o);
+ }
+ LongArrayList other = (LongArrayList) o;
+ if (size != other.size) {
+ return false;
+ }
+
+ final long[] arr = other.array;
+ for (int i = 0; i < size; i++) {
+ if (array[i] != arr[i]) {
+ return false;
}
}
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = 1;
+ for (int i = 0; i < size; i++) {
+ result = (31 * result) + Internal.hashLong(array[i]);
+ }
+ return result;
}
-
+
+ @Override
+ public LongList mutableCopyWithCapacity(int capacity) {
+ if (capacity < size) {
+ throw new IllegalArgumentException();
+ }
+ return new LongArrayList(Arrays.copyOf(array, capacity), size);
+ }
+
@Override
public Long get(int index) {
return getLong(index);
@@ -142,7 +172,7 @@ final class LongArrayList extends AbstractProtobufList<Long> implements LongList
if (index < 0 || index > size) {
throw new IndexOutOfBoundsException(makeOutOfBoundsExceptionMessage(index));
}
-
+
if (size < array.length) {
// Shift everything over to make room
System.arraycopy(array, index, array, index + 1, size - index);
@@ -150,10 +180,10 @@ final class LongArrayList extends AbstractProtobufList<Long> implements LongList
// Resize to 1.5x the size
int length = ((size * 3) / 2) + 1;
long[] newArray = new long[length];
-
+
// Copy the first part directly
System.arraycopy(array, 0, newArray, 0, index);
-
+
// Copy the rest shifted over by one to make room
System.arraycopy(array, index, newArray, index + 1, size - index);
array = newArray;
@@ -167,38 +197,38 @@ final class LongArrayList extends AbstractProtobufList<Long> implements LongList
@Override
public boolean addAll(Collection<? extends Long> collection) {
ensureIsMutable();
-
+
if (collection == null) {
throw new NullPointerException();
}
-
+
// We specialize when adding another LongArrayList to avoid boxing elements.
if (!(collection instanceof LongArrayList)) {
return super.addAll(collection);
}
-
+
LongArrayList list = (LongArrayList) collection;
if (list.size == 0) {
return false;
}
-
+
int overflow = Integer.MAX_VALUE - size;
if (overflow < list.size) {
// We can't actually represent a list this large.
throw new OutOfMemoryError();
}
-
+
int newSize = size + list.size;
if (newSize > array.length) {
array = Arrays.copyOf(array, newSize);
}
-
+
System.arraycopy(list.array, 0, array, size, list.size);
size = newSize;
modCount++;
return true;
}
-
+
@Override
public boolean remove(Object o) {
ensureIsMutable();
@@ -227,7 +257,7 @@ final class LongArrayList extends AbstractProtobufList<Long> implements LongList
/**
* Ensures that the provided {@code index} is within the range of {@code [0, size]}. Throws an
* {@link IndexOutOfBoundsException} if it is not.
- *
+ *
* @param index the index to verify is in range
*/
private void ensureIndexInRange(int index) {
diff --git a/java/src/main/java/com/google/protobuf/MapEntry.java b/java/core/src/main/java/com/google/protobuf/MapEntry.java
index 31414bb4..117cd911 100644
--- a/java/src/main/java/com/google/protobuf/MapEntry.java
+++ b/java/core/src/main/java/com/google/protobuf/MapEntry.java
@@ -41,63 +41,83 @@ import java.util.TreeMap;
/**
* Implements MapEntry messages.
- *
+ *
* In reflection API, map fields will be treated as repeated message fields and
* each map entry is accessed as a message. This MapEntry class is used to
* represent these map entry messages in reflection API.
- *
+ *
* Protobuf internal. Users shouldn't use this class.
*/
public final class MapEntry<K, V> extends AbstractMessage {
- private static class Metadata<K, V> {
- public final Descriptor descriptor;
- public final MapEntry<K, V> defaultInstance;
- public final AbstractParser<MapEntry<K, V>> parser;
-
+
+ private static final class Metadata<K, V> extends MapEntryLite.Metadata<K, V> {
+
+ public final Descriptor descriptor;
+ public final Parser<MapEntry<K, V>> parser;
+
public Metadata(
- final Descriptor descriptor, final MapEntry<K, V> defaultInstance) {
+ Descriptor descriptor,
+ MapEntry<K, V> defaultInstance,
+ WireFormat.FieldType keyType,
+ WireFormat.FieldType valueType) {
+ super(keyType, defaultInstance.key, valueType, defaultInstance.value);
this.descriptor = descriptor;
- this.defaultInstance = defaultInstance;
- final Metadata<K, V> thisMetadata = this;
this.parser = new AbstractParser<MapEntry<K, V>>() {
- private final Parser<MapEntryLite<K, V>> dataParser =
- defaultInstance.data.getParserForType();
+
@Override
public MapEntry<K, V> parsePartialFrom(
CodedInputStream input, ExtensionRegistryLite extensionRegistry)
throws InvalidProtocolBufferException {
- MapEntryLite<K, V> data =
- dataParser.parsePartialFrom(input, extensionRegistry);
- return new MapEntry<K, V>(thisMetadata, data);
+ return new MapEntry<K, V>(Metadata.this, input, extensionRegistry);
}
-
};
}
}
-
+
+ private final K key;
+ private final V value;
private final Metadata<K, V> metadata;
- private final MapEntryLite<K, V> data;
-
+
/** Create a default MapEntry instance. */
- private MapEntry(Descriptor descriptor,
+ private MapEntry(
+ Descriptor descriptor,
WireFormat.FieldType keyType, K defaultKey,
WireFormat.FieldType valueType, V defaultValue) {
- this.data = MapEntryLite.newDefaultInstance(
- keyType, defaultKey, valueType, defaultValue);
- this.metadata = new Metadata<K, V>(descriptor, this);
+ this.key = defaultKey;
+ this.value = defaultValue;
+ this.metadata = new Metadata<K, V>(descriptor, this, keyType, valueType);
}
-
- /** Create a new MapEntry message. */
- private MapEntry(Metadata<K, V> metadata, MapEntryLite<K, V> data) {
+
+ /** Create a MapEntry with the provided key and value. */
+ private MapEntry(Metadata metadata, K key, V value) {
+ this.key = key;
+ this.value = value;
this.metadata = metadata;
- this.data = data;
}
-
+
+ /** Parsing constructor. */
+ private MapEntry(
+ Metadata<K, V> metadata,
+ CodedInputStream input,
+ ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException {
+ try {
+ this.metadata = metadata;
+ Map.Entry<K, V> entry = MapEntryLite.parseEntry(input, metadata, extensionRegistry);
+ this.key = entry.getKey();
+ this.value = entry.getValue();
+ } catch (InvalidProtocolBufferException e) {
+ throw e.setUnfinishedMessage(this);
+ } catch (IOException e) {
+ throw new InvalidProtocolBufferException(e.getMessage()).setUnfinishedMessage(this);
+ }
+ }
+
/**
* Create a default MapEntry instance. A default MapEntry instance should be
* created only once for each map entry message type. Generated code should
* store the created default instance and use it later to create new MapEntry
- * messages of the same type.
+ * messages of the same type.
*/
public static <K, V> MapEntry<K, V> newDefaultInstance(
Descriptor descriptor,
@@ -106,30 +126,38 @@ public final class MapEntry<K, V> extends AbstractMessage {
return new MapEntry<K, V>(
descriptor, keyType, defaultKey, valueType, defaultValue);
}
-
+
public K getKey() {
- return data.getKey();
+ return key;
}
-
+
public V getValue() {
- return data.getValue();
+ return value;
}
-
+
+ private volatile int cachedSerializedSize = -1;
+
@Override
public int getSerializedSize() {
- return data.getSerializedSize();
+ if (cachedSerializedSize != -1) {
+ return cachedSerializedSize;
+ }
+
+ int size = MapEntryLite.computeSerializedSize(metadata, key, value);
+ cachedSerializedSize = size;
+ return size;
}
-
+
@Override
public void writeTo(CodedOutputStream output) throws IOException {
- data.writeTo(output);
+ MapEntryLite.writeTo(output, metadata, key, value);
}
-
+
@Override
public boolean isInitialized() {
- return data.isInitialized();
+ return isInitialized(metadata, value);
}
-
+
@Override
public Parser<MapEntry<K, V>> getParserForType() {
return metadata.parser;
@@ -139,15 +167,15 @@ public final class MapEntry<K, V> extends AbstractMessage {
public Builder<K, V> newBuilderForType() {
return new Builder<K, V>(metadata);
}
-
+
@Override
public Builder<K, V> toBuilder() {
- return new Builder<K, V>(metadata, data);
+ return new Builder<K, V>(metadata, key, value);
}
@Override
public MapEntry<K, V> getDefaultInstanceForType() {
- return metadata.defaultInstance;
+ return new MapEntry<K, V>(metadata, metadata.defaultKey, metadata.defaultValue);
}
@Override
@@ -157,8 +185,7 @@ public final class MapEntry<K, V> extends AbstractMessage {
@Override
public Map<FieldDescriptor, Object> getAllFields() {
- final TreeMap<FieldDescriptor, Object> result =
- new TreeMap<FieldDescriptor, Object>();
+ TreeMap<FieldDescriptor, Object> result = new TreeMap<FieldDescriptor, Object>();
for (final FieldDescriptor field : metadata.descriptor.getFields()) {
if (hasField(field)) {
result.put(field, getField(field));
@@ -166,12 +193,12 @@ public final class MapEntry<K, V> extends AbstractMessage {
}
return Collections.unmodifiableMap(result);
}
-
+
private void checkFieldDescriptor(FieldDescriptor field) {
if (field.getContainingType() != metadata.descriptor) {
throw new RuntimeException(
"Wrong FieldDescriptor \"" + field.getFullName()
- + "\" used in message \"" + metadata.descriptor.getFullName());
+ + "\" used in message \"" + metadata.descriptor.getFullName());
}
}
@@ -217,56 +244,44 @@ public final class MapEntry<K, V> extends AbstractMessage {
public static class Builder<K, V>
extends AbstractMessage.Builder<Builder<K, V>> {
private final Metadata<K, V> metadata;
- private MapEntryLite<K, V> data;
- private MapEntryLite.Builder<K, V> dataBuilder;
-
+ private K key;
+ private V value;
+
private Builder(Metadata<K, V> metadata) {
- this.metadata = metadata;
- this.data = metadata.defaultInstance.data;
- this.dataBuilder = null;
+ this(metadata, metadata.defaultKey, metadata.defaultValue);
}
-
- private Builder(Metadata<K, V> metadata, MapEntryLite<K, V> data) {
+
+ private Builder(Metadata<K, V> metadata, K key, V value) {
this.metadata = metadata;
- this.data = data;
- this.dataBuilder = null;
+ this.key = key;
+ this.value = value;
}
-
+
public K getKey() {
- return dataBuilder == null ? data.getKey() : dataBuilder.getKey();
+ return key;
}
-
+
public V getValue() {
- return dataBuilder == null ? data.getValue() : dataBuilder.getValue();
- }
-
- private void ensureMutable() {
- if (dataBuilder == null) {
- dataBuilder = data.toBuilder();
- }
+ return value;
}
-
+
public Builder<K, V> setKey(K key) {
- ensureMutable();
- dataBuilder.setKey(key);
+ this.key = key;
return this;
}
-
+
public Builder<K, V> clearKey() {
- ensureMutable();
- dataBuilder.clearKey();
+ this.key = metadata.defaultKey;
return this;
}
-
+
public Builder<K, V> setValue(V value) {
- ensureMutable();
- dataBuilder.setValue(value);
+ this.value = value;
return this;
}
-
+
public Builder<K, V> clearValue() {
- ensureMutable();
- dataBuilder.clearValue();
+ this.value = metadata.defaultValue;
return this;
}
@@ -281,29 +296,24 @@ public final class MapEntry<K, V> extends AbstractMessage {
@Override
public MapEntry<K, V> buildPartial() {
- if (dataBuilder != null) {
- data = dataBuilder.buildPartial();
- dataBuilder = null;
- }
- return new MapEntry<K, V>(metadata, data);
+ return new MapEntry<K, V>(metadata, key, value);
}
@Override
public Descriptor getDescriptorForType() {
return metadata.descriptor;
}
-
+
private void checkFieldDescriptor(FieldDescriptor field) {
if (field.getContainingType() != metadata.descriptor) {
throw new RuntimeException(
"Wrong FieldDescriptor \"" + field.getFullName()
- + "\" used in message \"" + metadata.descriptor.getFullName());
+ + "\" used in message \"" + metadata.descriptor.getFullName());
}
}
@Override
- public com.google.protobuf.Message.Builder newBuilderForField(
- FieldDescriptor field) {
+ public Message.Builder newBuilderForField(FieldDescriptor field) {
checkFieldDescriptor(field);;
// This method should be called for message fields and in a MapEntry
// message only the value field can possibly be a message field.
@@ -312,7 +322,7 @@ public final class MapEntry<K, V> extends AbstractMessage {
throw new RuntimeException(
"\"" + field.getFullName() + "\" is not a message value field.");
}
- return ((Message) data.getValue()).newBuilderForType();
+ return ((Message) value).newBuilderForType();
}
@SuppressWarnings("unchecked")
@@ -362,22 +372,17 @@ public final class MapEntry<K, V> extends AbstractMessage {
@Override
public MapEntry<K, V> getDefaultInstanceForType() {
- return metadata.defaultInstance;
+ return new MapEntry<K, V>(metadata, metadata.defaultKey, metadata.defaultValue);
}
@Override
public boolean isInitialized() {
- if (dataBuilder != null) {
- return dataBuilder.isInitialized();
- } else {
- return data.isInitialized();
- }
+ return MapEntry.isInitialized(metadata, value);
}
@Override
public Map<FieldDescriptor, Object> getAllFields() {
- final TreeMap<FieldDescriptor, Object> result =
- new TreeMap<FieldDescriptor, Object>();
+ final TreeMap<FieldDescriptor, Object> result = new TreeMap<FieldDescriptor, Object>();
for (final FieldDescriptor field : metadata.descriptor.getFields()) {
if (hasField(field)) {
result.put(field, getField(field));
@@ -398,8 +403,7 @@ public final class MapEntry<K, V> extends AbstractMessage {
Object result = field.getNumber() == 1 ? getKey() : getValue();
// Convert enums to EnumValueDescriptor.
if (field.getType() == FieldDescriptor.Type.ENUM) {
- result = field.getEnumType().findValueByNumberCreatingIfUnknown(
- (java.lang.Integer) result);
+ result = field.getEnumType().findValueByNumberCreatingIfUnknown((Integer) result);
}
return result;
}
@@ -409,13 +413,13 @@ public final class MapEntry<K, V> extends AbstractMessage {
throw new RuntimeException(
"There is no repeated field in a map entry message.");
}
-
+
@Override
public Object getRepeatedField(FieldDescriptor field, int index) {
throw new RuntimeException(
"There is no repeated field in a map entry message.");
}
-
+
@Override
public UnknownFieldSet getUnknownFields() {
return UnknownFieldSet.getDefaultInstance();
@@ -423,11 +427,14 @@ public final class MapEntry<K, V> extends AbstractMessage {
@Override
public Builder<K, V> clone() {
- if (dataBuilder == null) {
- return new Builder<K, V>(metadata, data);
- } else {
- return new Builder<K, V>(metadata, dataBuilder.build());
- }
+ return new Builder(metadata, key, value);
}
}
+
+ private static <V> boolean isInitialized(Metadata metadata, V value) {
+ if (metadata.valueType.getJavaType() == WireFormat.JavaType.MESSAGE) {
+ return ((MessageLite) value).isInitialized();
+ }
+ return true;
+ }
}
diff --git a/java/core/src/main/java/com/google/protobuf/MapEntryLite.java b/java/core/src/main/java/com/google/protobuf/MapEntryLite.java
new file mode 100644
index 00000000..22aef8f9
--- /dev/null
+++ b/java/core/src/main/java/com/google/protobuf/MapEntryLite.java
@@ -0,0 +1,226 @@
+// 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.
+
+package com.google.protobuf;
+
+import java.io.IOException;
+import java.util.AbstractMap;
+import java.util.Map;
+
+/**
+ * Implements the lite version of map entry messages.
+ *
+ * This class serves as an utility class to help do serialization/parsing of
+ * map entries. It's used in generated code and also in the full version
+ * MapEntry message.
+ *
+ * Protobuf internal. Users shouldn't use.
+ */
+public class MapEntryLite<K, V> {
+
+ static class Metadata<K, V> {
+ public final WireFormat.FieldType keyType;
+ public final K defaultKey;
+ public final WireFormat.FieldType valueType;
+ public final V defaultValue;
+
+ public Metadata(
+ WireFormat.FieldType keyType, K defaultKey,
+ WireFormat.FieldType valueType, V defaultValue) {
+ this.keyType = keyType;
+ this.defaultKey = defaultKey;
+ this.valueType = valueType;
+ this.defaultValue = defaultValue;
+ }
+ }
+
+ private static final int KEY_FIELD_NUMBER = 1;
+ private static final int VALUE_FIELD_NUMBER = 2;
+
+ private final Metadata<K, V> metadata;
+ private final K key;
+ private final V value;
+
+ /** Creates a default MapEntryLite message instance. */
+ private MapEntryLite(
+ WireFormat.FieldType keyType, K defaultKey,
+ WireFormat.FieldType valueType, V defaultValue) {
+ this.metadata = new Metadata<K, V>(keyType, defaultKey, valueType, defaultValue);
+ this.key = defaultKey;
+ this.value = defaultValue;
+ }
+
+ /** Creates a new MapEntryLite message. */
+ private MapEntryLite(Metadata<K, V> metadata, K key, V value) {
+ this.metadata = metadata;
+ this.key = key;
+ this.value = value;
+ }
+
+ public K getKey() {
+ return key;
+ }
+
+ public V getValue() {
+ return value;
+ }
+
+ /**
+ * Creates a default MapEntryLite message instance.
+ *
+ * This method is used by generated code to create the default instance for
+ * a map entry message. The created default instance should be used to create
+ * new map entry messages of the same type. For each map entry message, only
+ * one default instance should be created.
+ */
+ public static <K, V> MapEntryLite<K, V> newDefaultInstance(
+ WireFormat.FieldType keyType, K defaultKey,
+ WireFormat.FieldType valueType, V defaultValue) {
+ return new MapEntryLite<K, V>(
+ keyType, defaultKey, valueType, defaultValue);
+ }
+
+ static <K, V> void writeTo(CodedOutputStream output, Metadata<K, V> metadata, K key, V value)
+ throws IOException {
+ FieldSet.writeElement(output, metadata.keyType, KEY_FIELD_NUMBER, key);
+ FieldSet.writeElement(output, metadata.valueType, VALUE_FIELD_NUMBER, value);
+ }
+
+ static <K, V> int computeSerializedSize(Metadata<K, V> metadata, K key, V value) {
+ return FieldSet.computeElementSize(metadata.keyType, KEY_FIELD_NUMBER, key)
+ + FieldSet.computeElementSize(metadata.valueType, VALUE_FIELD_NUMBER, value);
+ }
+
+ @SuppressWarnings("unchecked")
+ static <T> T parseField(
+ CodedInputStream input, ExtensionRegistryLite extensionRegistry,
+ WireFormat.FieldType type, T value) throws IOException {
+ switch (type) {
+ case MESSAGE:
+ MessageLite.Builder subBuilder = ((MessageLite) value).toBuilder();
+ input.readMessage(subBuilder, extensionRegistry);
+ return (T) subBuilder.buildPartial();
+ case ENUM:
+ return (T) (java.lang.Integer) input.readEnum();
+ case GROUP:
+ throw new RuntimeException("Groups are not allowed in maps.");
+ default:
+ return (T) FieldSet.readPrimitiveField(input, type, true);
+ }
+ }
+
+ /**
+ * Serializes the provided key and value as though they were wrapped by a {@link MapEntryLite}
+ * to the output stream. This helper method avoids allocation of a {@link MapEntryLite}
+ * built with a key and value and is called from generated code directly.
+ */
+ public void serializeTo(CodedOutputStream output, int fieldNumber, K key, V value)
+ throws IOException {
+ output.writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ output.writeUInt32NoTag(computeSerializedSize(metadata, key, value));
+ writeTo(output, metadata, key, value);
+ }
+
+ /**
+ * Computes the message size for the provided key and value as though they were wrapped
+ * by a {@link MapEntryLite}. This helper method avoids allocation of a {@link MapEntryLite}
+ * built with a key and value and is called from generated code directly.
+ */
+ public int computeMessageSize(int fieldNumber, K key, V value) {
+ return CodedOutputStream.computeTagSize(fieldNumber)
+ + CodedOutputStream.computeLengthDelimitedFieldSize(
+ computeSerializedSize(metadata, key, value));
+ }
+
+ /**
+ * Parses an entry off of the input as a {@link Map.Entry}. This helper requires an allocation
+ * so using {@link #parseInto} is preferred if possible.
+ */
+ public Map.Entry<K, V> parseEntry(ByteString bytes, ExtensionRegistryLite extensionRegistry)
+ throws IOException {
+ return parseEntry(bytes.newCodedInput(), metadata, extensionRegistry);
+ }
+
+ static <K, V> Map.Entry<K, V> parseEntry(
+ CodedInputStream input, Metadata<K, V> metadata, ExtensionRegistryLite extensionRegistry)
+ throws IOException{
+ K key = metadata.defaultKey;
+ V value = metadata.defaultValue;
+ while (true) {
+ int tag = input.readTag();
+ if (tag == 0) {
+ break;
+ }
+ if (tag == WireFormat.makeTag(KEY_FIELD_NUMBER, metadata.keyType.getWireType())) {
+ key = parseField(input, extensionRegistry, metadata.keyType, key);
+ } else if (tag == WireFormat.makeTag(VALUE_FIELD_NUMBER, metadata.valueType.getWireType())) {
+ value = parseField(input, extensionRegistry, metadata.valueType, value);
+ } else {
+ if (!input.skipField(tag)) {
+ break;
+ }
+ }
+ }
+ return new AbstractMap.SimpleImmutableEntry<K, V>(key, value);
+ }
+
+ /**
+ * Parses an entry off of the input into the map. This helper avoids allocaton of a
+ * {@link MapEntryLite} by parsing directly into the provided {@link MapFieldLite}.
+ */
+ public void parseInto(
+ MapFieldLite<K, V> map, CodedInputStream input, ExtensionRegistryLite extensionRegistry)
+ throws IOException {
+ int length = input.readRawVarint32();
+ final int oldLimit = input.pushLimit(length);
+ K key = metadata.defaultKey;
+ V value = metadata.defaultValue;
+
+ while (true) {
+ int tag = input.readTag();
+ if (tag == 0) {
+ break;
+ }
+ if (tag == WireFormat.makeTag(KEY_FIELD_NUMBER, metadata.keyType.getWireType())) {
+ key = parseField(input, extensionRegistry, metadata.keyType, key);
+ } else if (tag == WireFormat.makeTag(VALUE_FIELD_NUMBER, metadata.valueType.getWireType())) {
+ value = parseField(input, extensionRegistry, metadata.valueType, value);
+ } else {
+ if (!input.skipField(tag)) {
+ break;
+ }
+ }
+ }
+
+ input.checkLastTagWas(0);
+ input.popLimit(oldLimit);
+ map.put(key, value);
+ }
+}
diff --git a/java/src/main/java/com/google/protobuf/MapField.java b/java/core/src/main/java/com/google/protobuf/MapField.java
index b290993c..a6109f98 100644
--- a/java/src/main/java/com/google/protobuf/MapField.java
+++ b/java/core/src/main/java/com/google/protobuf/MapField.java
@@ -30,25 +30,26 @@
package com.google.protobuf;
-import com.google.protobuf.MapFieldLite.MutatabilityAwareMap;
-
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
+import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
/**
* Internal representation of map fields in generated messages.
- *
+ *
* This class supports accessing the map field as a {@link Map} to be used in
* generated API and also supports accessing the field as a {@link List} to be
* used in reflection API. It keeps track of where the data is currently stored
- * and do necessary conversions between map and list.
- *
+ * and do necessary conversions between map and list.
+ *
* This class is a protobuf implementation detail. Users shouldn't use this
* class directly.
- *
+ *
* THREAD-SAFETY NOTE: Read-only access is thread-safe. Users can call getMap()
* and getList() concurrently in multiple threads. If write-access is needed,
* all access must be synchronized.
@@ -56,21 +57,21 @@ import java.util.Map;
public class MapField<K, V> implements MutabilityOracle {
/**
* Indicates where the data of this map field is currently stored.
- *
+ *
* MAP: Data is stored in mapData.
* LIST: Data is stored in listData.
* BOTH: mapData and listData have the same data.
*
* When the map field is accessed (through generated API or reflection API),
* it will shift between these 3 modes:
- *
+ *
* getMap() getList() getMutableMap() getMutableList()
* MAP MAP BOTH MAP LIST
* LIST BOTH LIST MAP LIST
* BOTH BOTH BOTH MAP LIST
- *
+ *
* As the map field changes its mode, the list/map reference returned in a
- * previous method call may be invalidated.
+ * previous method call may be invalidated.
*/
private enum StorageMode {MAP, LIST, BOTH}
@@ -78,38 +79,41 @@ public class MapField<K, V> implements MutabilityOracle {
private volatile StorageMode mode;
private MutatabilityAwareMap<K, V> mapData;
private List<Message> listData;
-
+
// Convert between a map entry Message and a key-value pair.
private static interface Converter<K, V> {
Message convertKeyAndValueToMessage(K key, V value);
void convertMessageToKeyAndValue(Message message, Map<K, V> map);
-
+
Message getMessageDefaultInstance();
}
-
+
private static class ImmutableMessageConverter<K, V> implements Converter<K, V> {
private final MapEntry<K, V> defaultEntry;
public ImmutableMessageConverter(MapEntry<K, V> defaultEntry) {
this.defaultEntry = defaultEntry;
}
-
+
+ @Override
public Message convertKeyAndValueToMessage(K key, V value) {
return defaultEntry.newBuilderForType().setKey(key).setValue(value).buildPartial();
}
-
+
+ @Override
public void convertMessageToKeyAndValue(Message message, Map<K, V> map) {
MapEntry<K, V> entry = (MapEntry<K, V>) message;
map.put(entry.getKey(), entry.getValue());
}
+ @Override
public Message getMessageDefaultInstance() {
return defaultEntry;
}
}
-
+
private final Converter<K, V> converter;
-
+
private MapField(
Converter<K, V> converter,
StorageMode mode,
@@ -120,34 +124,34 @@ public class MapField<K, V> implements MutabilityOracle {
this.mapData = new MutatabilityAwareMap<K, V>(this, mapData);
this.listData = null;
}
-
+
private MapField(
MapEntry<K, V> defaultEntry,
StorageMode mode,
Map<K, V> mapData) {
this(new ImmutableMessageConverter<K, V>(defaultEntry), mode, mapData);
}
-
-
+
+
/** Returns an immutable empty MapField. */
public static <K, V> MapField<K, V> emptyMapField(
MapEntry<K, V> defaultEntry) {
return new MapField<K, V>(
defaultEntry, StorageMode.MAP, Collections.<K, V>emptyMap());
}
-
-
+
+
/** Creates a new mutable empty MapField. */
public static <K, V> MapField<K, V> newMapField(MapEntry<K, V> defaultEntry) {
return new MapField<K, V>(
defaultEntry, StorageMode.MAP, new LinkedHashMap<K, V>());
}
-
-
+
+
private Message convertKeyAndValueToMessage(K key, V value) {
return converter.convertKeyAndValueToMessage(key, value);
}
-
+
@SuppressWarnings("unchecked")
private void convertMessageToKeyAndValue(Message message, Map<K, V> map) {
converter.convertMessageToKeyAndValue(message, map);
@@ -170,7 +174,7 @@ public class MapField<K, V> implements MutabilityOracle {
}
return new MutatabilityAwareMap<K, V>(this, mapData);
}
-
+
/** Returns the content of this MapField as a read-only Map. */
public Map<K, V> getMap() {
if (mode == StorageMode.LIST) {
@@ -183,7 +187,7 @@ public class MapField<K, V> implements MutabilityOracle {
}
return Collections.unmodifiableMap(mapData);
}
-
+
/** Gets a mutable Map view of this MapField. */
public Map<K, V> getMutableMap() {
if (mode != StorageMode.MAP) {
@@ -191,20 +195,20 @@ public class MapField<K, V> implements MutabilityOracle {
mapData = convertListToMap(listData);
}
listData = null;
- mode = StorageMode.MAP;
+ mode = StorageMode.MAP;
}
return mapData;
}
-
+
public void mergeFrom(MapField<K, V> other) {
getMutableMap().putAll(MapFieldLite.copy(other.getMap()));
}
-
+
public void clear() {
mapData = new MutatabilityAwareMap<K, V>(this, new LinkedHashMap<K, V>());
mode = StorageMode.MAP;
}
-
+
@SuppressWarnings("unchecked")
@Override
public boolean equals(Object object) {
@@ -214,18 +218,18 @@ public class MapField<K, V> implements MutabilityOracle {
MapField<K, V> other = (MapField<K, V>) object;
return MapFieldLite.<K, V>equals(getMap(), other.getMap());
}
-
+
@Override
public int hashCode() {
return MapFieldLite.<K, V>calculateHashCodeForMap(getMap());
}
-
+
/** Returns a deep copy of this MapField. */
public MapField<K, V> copy() {
return new MapField<K, V>(
converter, StorageMode.MAP, MapFieldLite.copy(getMap()));
}
-
+
/** Gets the content of this MapField as a read-only List. */
List<Message> getList() {
if (mode == StorageMode.MAP) {
@@ -238,7 +242,7 @@ public class MapField<K, V> implements MutabilityOracle {
}
return Collections.unmodifiableList(listData);
}
-
+
/** Gets a mutable List view of this MapField. */
List<Message> getMutableList() {
if (mode != StorageMode.LIST) {
@@ -250,7 +254,7 @@ public class MapField<K, V> implements MutabilityOracle {
}
return listData;
}
-
+
/**
* Gets the default instance of the message stored in the list view of this
* map field.
@@ -258,7 +262,7 @@ public class MapField<K, V> implements MutabilityOracle {
Message getMapEntryMessageDefaultInstance() {
return converter.getMessageDefaultInstance();
}
-
+
/**
* Makes this list immutable. All subsequent modifications will throw an
* {@link UnsupportedOperationException}.
@@ -266,14 +270,14 @@ public class MapField<K, V> implements MutabilityOracle {
public void makeImmutable() {
isMutable = false;
}
-
+
/**
* Returns whether this field can be modified.
*/
public boolean isMutable() {
return isMutable;
}
-
+
/* (non-Javadoc)
* @see com.google.protobuf.MutabilityOracle#ensureMutable()
*/
@@ -283,4 +287,338 @@ public class MapField<K, V> implements MutabilityOracle {
throw new UnsupportedOperationException();
}
}
+
+ /**
+ * An internal map that checks for mutability before delegating.
+ */
+ private static class MutatabilityAwareMap<K, V> implements Map<K, V> {
+ private final MutabilityOracle mutabilityOracle;
+ private final Map<K, V> delegate;
+
+ MutatabilityAwareMap(MutabilityOracle mutabilityOracle, Map<K, V> delegate) {
+ this.mutabilityOracle = mutabilityOracle;
+ this.delegate = delegate;
+ }
+
+ @Override
+ public int size() {
+ return delegate.size();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return delegate.isEmpty();
+ }
+
+ @Override
+ public boolean containsKey(Object key) {
+ return delegate.containsKey(key);
+ }
+
+ @Override
+ public boolean containsValue(Object value) {
+ return delegate.containsValue(value);
+ }
+
+ @Override
+ public V get(Object key) {
+ return delegate.get(key);
+ }
+
+ @Override
+ public V put(K key, V value) {
+ mutabilityOracle.ensureMutable();
+ return delegate.put(key, value);
+ }
+
+ @Override
+ public V remove(Object key) {
+ mutabilityOracle.ensureMutable();
+ return delegate.remove(key);
+ }
+
+ @Override
+ public void putAll(Map<? extends K, ? extends V> m) {
+ mutabilityOracle.ensureMutable();
+ delegate.putAll(m);
+ }
+
+ @Override
+ public void clear() {
+ mutabilityOracle.ensureMutable();
+ delegate.clear();
+ }
+
+ @Override
+ public Set<K> keySet() {
+ return new MutatabilityAwareSet<K>(mutabilityOracle, delegate.keySet());
+ }
+
+ @Override
+ public Collection<V> values() {
+ return new MutatabilityAwareCollection<V>(mutabilityOracle, delegate.values());
+ }
+
+ @Override
+ public Set<java.util.Map.Entry<K, V>> entrySet() {
+ return new MutatabilityAwareSet<Entry<K, V>>(mutabilityOracle, delegate.entrySet());
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return delegate.equals(o);
+ }
+
+ @Override
+ public int hashCode() {
+ return delegate.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return delegate.toString();
+ }
+
+ /**
+ * An internal collection that checks for mutability before delegating.
+ */
+ private static class MutatabilityAwareCollection<E> implements Collection<E> {
+ private final MutabilityOracle mutabilityOracle;
+ private final Collection<E> delegate;
+
+ MutatabilityAwareCollection(MutabilityOracle mutabilityOracle, Collection<E> delegate) {
+ this.mutabilityOracle = mutabilityOracle;
+ this.delegate = delegate;
+ }
+
+ @Override
+ public int size() {
+ return delegate.size();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return delegate.isEmpty();
+ }
+
+ @Override
+ public boolean contains(Object o) {
+ return delegate.contains(o);
+ }
+
+ @Override
+ public Iterator<E> iterator() {
+ return new MutatabilityAwareIterator<E>(mutabilityOracle, delegate.iterator());
+ }
+
+ @Override
+ public Object[] toArray() {
+ return delegate.toArray();
+ }
+
+ @Override
+ public <T> T[] toArray(T[] a) {
+ return delegate.toArray(a);
+ }
+
+ @Override
+ public boolean add(E e) {
+ // Unsupported operation in the delegate.
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean remove(Object o) {
+ mutabilityOracle.ensureMutable();
+ return delegate.remove(o);
+ }
+
+ @Override
+ public boolean containsAll(Collection<?> c) {
+ return delegate.containsAll(c);
+ }
+
+ @Override
+ public boolean addAll(Collection<? extends E> c) {
+ // Unsupported operation in the delegate.
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean removeAll(Collection<?> c) {
+ mutabilityOracle.ensureMutable();
+ return delegate.removeAll(c);
+ }
+
+ @Override
+ public boolean retainAll(Collection<?> c) {
+ mutabilityOracle.ensureMutable();
+ return delegate.retainAll(c);
+ }
+
+ @Override
+ public void clear() {
+ mutabilityOracle.ensureMutable();
+ delegate.clear();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return delegate.equals(o);
+ }
+
+ @Override
+ public int hashCode() {
+ return delegate.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return delegate.toString();
+ }
+ }
+
+ /**
+ * An internal set that checks for mutability before delegating.
+ */
+ private static class MutatabilityAwareSet<E> implements Set<E> {
+ private final MutabilityOracle mutabilityOracle;
+ private final Set<E> delegate;
+
+ MutatabilityAwareSet(MutabilityOracle mutabilityOracle, Set<E> delegate) {
+ this.mutabilityOracle = mutabilityOracle;
+ this.delegate = delegate;
+ }
+
+ @Override
+ public int size() {
+ return delegate.size();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return delegate.isEmpty();
+ }
+
+ @Override
+ public boolean contains(Object o) {
+ return delegate.contains(o);
+ }
+
+ @Override
+ public Iterator<E> iterator() {
+ return new MutatabilityAwareIterator<E>(mutabilityOracle, delegate.iterator());
+ }
+
+ @Override
+ public Object[] toArray() {
+ return delegate.toArray();
+ }
+
+ @Override
+ public <T> T[] toArray(T[] a) {
+ return delegate.toArray(a);
+ }
+
+ @Override
+ public boolean add(E e) {
+ mutabilityOracle.ensureMutable();
+ return delegate.add(e);
+ }
+
+ @Override
+ public boolean remove(Object o) {
+ mutabilityOracle.ensureMutable();
+ return delegate.remove(o);
+ }
+
+ @Override
+ public boolean containsAll(Collection<?> c) {
+ return delegate.containsAll(c);
+ }
+
+ @Override
+ public boolean addAll(Collection<? extends E> c) {
+ mutabilityOracle.ensureMutable();
+ return delegate.addAll(c);
+ }
+
+ @Override
+ public boolean retainAll(Collection<?> c) {
+ mutabilityOracle.ensureMutable();
+ return delegate.retainAll(c);
+ }
+
+ @Override
+ public boolean removeAll(Collection<?> c) {
+ mutabilityOracle.ensureMutable();
+ return delegate.removeAll(c);
+ }
+
+ @Override
+ public void clear() {
+ mutabilityOracle.ensureMutable();
+ delegate.clear();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return delegate.equals(o);
+ }
+
+ @Override
+ public int hashCode() {
+ return delegate.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return delegate.toString();
+ }
+ }
+
+ /**
+ * An internal iterator that checks for mutability before delegating.
+ */
+ private static class MutatabilityAwareIterator<E> implements Iterator<E> {
+ private final MutabilityOracle mutabilityOracle;
+ private final Iterator<E> delegate;
+
+ MutatabilityAwareIterator(MutabilityOracle mutabilityOracle, Iterator<E> delegate) {
+ this.mutabilityOracle = mutabilityOracle;
+ this.delegate = delegate;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return delegate.hasNext();
+ }
+
+ @Override
+ public E next() {
+ return delegate.next();
+ }
+
+ @Override
+ public void remove() {
+ mutabilityOracle.ensureMutable();
+ delegate.remove();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return delegate.equals(obj);
+ }
+
+ @Override
+ public int hashCode() {
+ return delegate.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return delegate.toString();
+ }
+ }
+ }
}
diff --git a/java/core/src/main/java/com/google/protobuf/MapFieldLite.java b/java/core/src/main/java/com/google/protobuf/MapFieldLite.java
new file mode 100644
index 00000000..3c0ad89a
--- /dev/null
+++ b/java/core/src/main/java/com/google/protobuf/MapFieldLite.java
@@ -0,0 +1,224 @@
+// 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.
+
+package com.google.protobuf;
+
+import com.google.protobuf.Internal.EnumLite;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Internal representation of map fields in generated lite-runtime messages.
+ *
+ * This class is a protobuf implementation detail. Users shouldn't use this
+ * class directly.
+ */
+public final class MapFieldLite<K, V> extends LinkedHashMap<K, V> {
+
+ private boolean isMutable;
+
+ private MapFieldLite() {
+ this.isMutable = true;
+ }
+
+ private MapFieldLite(Map<K, V> mapData) {
+ super(mapData);
+ this.isMutable = true;
+ }
+
+ @SuppressWarnings({"rawtypes", "unchecked"})
+ private static final MapFieldLite EMPTY_MAP_FIELD = new MapFieldLite(Collections.emptyMap());
+ static {
+ EMPTY_MAP_FIELD.makeImmutable();
+ }
+
+ /** Returns an singleton immutable empty MapFieldLite instance. */
+ @SuppressWarnings({"unchecked", "cast"})
+ public static <K, V> MapFieldLite<K, V> emptyMapField() {
+ return (MapFieldLite<K, V>) EMPTY_MAP_FIELD;
+ }
+
+ public void mergeFrom(MapFieldLite<K, V> other) {
+ ensureMutable();
+ if (!other.isEmpty()) {
+ putAll(other);
+ }
+ }
+
+ @SuppressWarnings({"unchecked", "cast"})
+ @Override public Set<Map.Entry<K, V>> entrySet() {
+ return isEmpty() ? Collections.<Map.Entry<K, V>>emptySet() : super.entrySet();
+ }
+
+ @Override public void clear() {
+ ensureMutable();
+ clear();
+ }
+
+ @Override public V put(K key, V value) {
+ ensureMutable();
+ return super.put(key, value);
+ }
+
+ public V put(Map.Entry<K, V> entry) {
+ return put(entry.getKey(), entry.getValue());
+ }
+
+ @Override public void putAll(Map<? extends K, ? extends V> m) {
+ ensureMutable();
+ super.putAll(m);
+ }
+
+ @Override public V remove(Object key) {
+ ensureMutable();
+ return super.remove(key);
+ }
+
+ private static boolean equals(Object a, Object b) {
+ if (a instanceof byte[] && b instanceof byte[]) {
+ return Arrays.equals((byte[]) a, (byte[]) b);
+ }
+ return a.equals(b);
+ }
+
+ /**
+ * Checks whether two {@link Map}s are equal. We don't use the default equals
+ * method of {@link Map} because it compares by identity not by content for
+ * byte arrays.
+ */
+ static <K, V> boolean equals(Map<K, V> a, Map<K, V> b) {
+ if (a == b) {
+ return true;
+ }
+ if (a.size() != b.size()) {
+ return false;
+ }
+ for (Map.Entry<K, V> entry : a.entrySet()) {
+ if (!b.containsKey(entry.getKey())) {
+ return false;
+ }
+ if (!equals(entry.getValue(), b.get(entry.getKey()))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Checks whether two map fields are equal.
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public boolean equals(Object object) {
+ return (object instanceof Map) && equals(this, (Map<K, V>) object);
+ }
+
+ private static int calculateHashCodeForObject(Object a) {
+ if (a instanceof byte[]) {
+ return Internal.hashCode((byte[]) a);
+ }
+ // Enums should be stored as integers internally.
+ if (a instanceof EnumLite) {
+ throw new UnsupportedOperationException();
+ }
+ return a.hashCode();
+ }
+
+ /**
+ * Calculates the hash code for a {@link Map}. We don't use the default hash
+ * code method of {@link Map} because for byte arrays and protobuf enums it
+ * use {@link Object#hashCode()}.
+ */
+ static <K, V> int calculateHashCodeForMap(Map<K, V> a) {
+ int result = 0;
+ for (Map.Entry<K, V> entry : a.entrySet()) {
+ result += calculateHashCodeForObject(entry.getKey())
+ ^ calculateHashCodeForObject(entry.getValue());
+ }
+ return result;
+ }
+
+ @Override
+ public int hashCode() {
+ return calculateHashCodeForMap(this);
+ }
+
+ private static Object copy(Object object) {
+ if (object instanceof byte[]) {
+ byte[] data = (byte[]) object;
+ return Arrays.copyOf(data, data.length);
+ }
+ return object;
+ }
+
+ /**
+ * Makes a deep copy of a {@link Map}. Immutable objects in the map will be
+ * shared (e.g., integers, strings, immutable messages) and mutable ones will
+ * have a copy (e.g., byte arrays, mutable messages).
+ */
+ @SuppressWarnings("unchecked")
+ static <K, V> Map<K, V> copy(Map<K, V> map) {
+ Map<K, V> result = new LinkedHashMap<K, V>();
+ for (Map.Entry<K, V> entry : map.entrySet()) {
+ result.put(entry.getKey(), (V) copy(entry.getValue()));
+ }
+ return result;
+ }
+
+ /** Returns a deep copy of this map field. */
+ public MapFieldLite<K, V> mutableCopy() {
+ return isEmpty() ? new MapFieldLite<K, V>() : new MapFieldLite<K, V>(this);
+ }
+
+ /**
+ * Makes this field immutable. All subsequent modifications will throw an
+ * {@link UnsupportedOperationException}.
+ */
+ public void makeImmutable() {
+ isMutable = false;
+ }
+
+ /**
+ * Returns whether this field can be modified.
+ */
+ public boolean isMutable() {
+ return isMutable;
+ }
+
+ private void ensureMutable() {
+ if (!isMutable()) {
+ throw new UnsupportedOperationException();
+ }
+ }
+}
diff --git a/java/src/main/java/com/google/protobuf/Message.java b/java/core/src/main/java/com/google/protobuf/Message.java
index 9516d71f..94590fb9 100644
--- a/java/src/main/java/com/google/protobuf/Message.java
+++ b/java/core/src/main/java/com/google/protobuf/Message.java
@@ -51,6 +51,7 @@ import java.util.Map;
public interface Message extends MessageLite, MessageOrBuilder {
// (From MessageLite, re-declared here only for return type covariance.)
+ @Override
Parser<? extends Message> getParserForType();
@@ -97,7 +98,10 @@ public interface Message extends MessageLite, MessageOrBuilder {
// Builders
// (From MessageLite, re-declared here only for return type covariance.)
+ @Override
Builder newBuilderForType();
+
+ @Override
Builder toBuilder();
/**
@@ -106,6 +110,7 @@ public interface Message extends MessageLite, MessageOrBuilder {
interface Builder extends MessageLite.Builder, MessageOrBuilder {
// (From MessageLite.Builder, re-declared here only for return type
// covariance.)
+ @Override
Builder clear();
/**
@@ -131,18 +136,27 @@ public interface Message extends MessageLite, MessageOrBuilder {
// (From MessageLite.Builder, re-declared here only for return type
// covariance.)
+ @Override
Message build();
+
+ @Override
Message buildPartial();
+
+ @Override
Builder clone();
+
+ @Override
Builder mergeFrom(CodedInputStream input) throws IOException;
- Builder mergeFrom(CodedInputStream input,
- ExtensionRegistryLite extensionRegistry)
- throws IOException;
+
+ @Override
+ Builder mergeFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry)
+ throws IOException;
/**
* Get the message's type's descriptor.
* See {@link Message#getDescriptorForType()}.
*/
+ @Override
Descriptors.Descriptor getDescriptorForType();
/**
@@ -240,27 +254,39 @@ public interface Message extends MessageLite, MessageOrBuilder {
// (From MessageLite.Builder, re-declared here only for return type
// covariance.)
+ @Override
Builder mergeFrom(ByteString data) throws InvalidProtocolBufferException;
- Builder mergeFrom(ByteString data,
- ExtensionRegistryLite extensionRegistry)
- throws InvalidProtocolBufferException;
+
+ @Override
+ Builder mergeFrom(ByteString data, ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException;
+
+ @Override
Builder mergeFrom(byte[] data) throws InvalidProtocolBufferException;
- Builder mergeFrom(byte[] data, int off, int len)
- throws InvalidProtocolBufferException;
- Builder mergeFrom(byte[] data,
- ExtensionRegistryLite extensionRegistry)
- throws InvalidProtocolBufferException;
- Builder mergeFrom(byte[] data, int off, int len,
- ExtensionRegistryLite extensionRegistry)
- throws InvalidProtocolBufferException;
+
+ @Override
+ Builder mergeFrom(byte[] data, int off, int len) throws InvalidProtocolBufferException;
+
+ @Override
+ Builder mergeFrom(byte[] data, ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException;
+
+ @Override
+ Builder mergeFrom(byte[] data, int off, int len, ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException;
+
+ @Override
Builder mergeFrom(InputStream input) throws IOException;
- Builder mergeFrom(InputStream input,
- ExtensionRegistryLite extensionRegistry)
- throws IOException;
- boolean mergeDelimitedFrom(InputStream input)
- throws IOException;
- boolean mergeDelimitedFrom(InputStream input,
- ExtensionRegistryLite extensionRegistry)
- throws IOException;
+
+ @Override
+ Builder mergeFrom(InputStream input, ExtensionRegistryLite extensionRegistry)
+ throws IOException;
+
+ @Override
+ boolean mergeDelimitedFrom(InputStream input) throws IOException;
+
+ @Override
+ boolean mergeDelimitedFrom(InputStream input, ExtensionRegistryLite extensionRegistry)
+ throws IOException;
}
}
diff --git a/java/src/main/java/com/google/protobuf/MessageLite.java b/java/core/src/main/java/com/google/protobuf/MessageLite.java
index 798b7943..88f531df 100644
--- a/java/src/main/java/com/google/protobuf/MessageLite.java
+++ b/java/core/src/main/java/com/google/protobuf/MessageLite.java
@@ -295,6 +295,27 @@ public interface MessageLite extends MessageLiteOrBuilder {
Builder mergeFrom(InputStream input,
ExtensionRegistryLite extensionRegistry)
throws IOException;
+
+ /**
+ * Merge {@code other} into the message being built. {@code other} must
+ * have the exact same type as {@code this} (i.e.
+ * {@code getClass().equals(getDefaultInstanceForType().getClass())}).
+ *
+ * Merging occurs as follows. For each field:<br>
+ * * For singular primitive fields, if the field is set in {@code other},
+ * then {@code other}'s value overwrites the value in this message.<br>
+ * * For singular message fields, if the field is set in {@code other},
+ * it is merged into the corresponding sub-message of this message
+ * using the same merging rules.<br>
+ * * For repeated fields, the elements in {@code other} are concatenated
+ * with the elements in this message.
+ * * For oneof groups, if the other message has one of the fields set,
+ * the group of this message is cleared and replaced by the field
+ * of the other message, so that the oneof constraint is preserved.
+ *
+ * This is equivalent to the {@code Message::MergeFrom} method in C++.
+ */
+ Builder mergeFrom(MessageLite other);
/**
* Like {@link #mergeFrom(InputStream)}, but does not read until EOF.
diff --git a/java/src/main/java/com/google/protobuf/MessageLiteOrBuilder.java b/java/core/src/main/java/com/google/protobuf/MessageLiteOrBuilder.java
index 818386ce..818386ce 100644
--- a/java/src/main/java/com/google/protobuf/MessageLiteOrBuilder.java
+++ b/java/core/src/main/java/com/google/protobuf/MessageLiteOrBuilder.java
diff --git a/java/core/src/main/java/com/google/protobuf/MessageLiteToString.java b/java/core/src/main/java/com/google/protobuf/MessageLiteToString.java
new file mode 100644
index 00000000..43847651
--- /dev/null
+++ b/java/core/src/main/java/com/google/protobuf/MessageLiteToString.java
@@ -0,0 +1,239 @@
+// 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.
+
+package com.google.protobuf;
+
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+/**
+ * Helps generate {@link String} representations of {@link MessageLite} protos.
+ */
+// TODO(dweis): Fix map fields.
+final class MessageLiteToString {
+
+ private static final String LIST_SUFFIX = "List";
+ private static final String BUILDER_LIST_SUFFIX = "OrBuilderList";
+ private static final String BYTES_SUFFIX = "Bytes";
+
+ /**
+ * Returns a {@link String} representation of the {@link MessageLite} object. The first line of
+ * the {@code String} representation representation includes a comment string to uniquely identify
+ * the objcet instance. This acts as an indicator that this should not be relied on for
+ * comparisons.
+ *
+ * <p>For use by generated code only.
+ */
+ static String toString(MessageLite messageLite, String commentString) {
+ StringBuilder buffer = new StringBuilder();
+ buffer.append("# ").append(commentString);
+ reflectivePrintWithIndent(messageLite, buffer, 0);
+ return buffer.toString();
+ }
+
+ /**
+ * Reflectively prints the {@link MessageLite} to the buffer at given {@code indent} level.
+ *
+ * @param buffer the buffer to write to
+ * @param indent the number of spaces to indent the proto by
+ */
+ private static void reflectivePrintWithIndent(
+ MessageLite messageLite, StringBuilder buffer, int indent) {
+ // Build a map of method name to method. We're looking for methods like getFoo(), hasFoo(), and
+ // getFooList() which might be useful for building an object's string representation.
+ Map<String, Method> nameToNoArgMethod = new HashMap<String, Method>();
+ Map<String, Method> nameToMethod = new HashMap<String, Method>();
+ Set<String> getters = new TreeSet<String>();
+ for (Method method : messageLite.getClass().getDeclaredMethods()) {
+ nameToMethod.put(method.getName(), method);
+ if (method.getParameterTypes().length == 0) {
+ nameToNoArgMethod.put(method.getName(), method);
+
+ if (method.getName().startsWith("get")) {
+ getters.add(method.getName());
+ }
+ }
+ }
+
+ for (String getter : getters) {
+ String suffix = getter.replaceFirst("get", "");
+ if (suffix.endsWith(LIST_SUFFIX) && !suffix.endsWith(BUILDER_LIST_SUFFIX)) {
+ String camelCase = suffix.substring(0, 1).toLowerCase()
+ + suffix.substring(1, suffix.length() - LIST_SUFFIX.length());
+ // Try to reflectively get the value and toString() the field as if it were repeated. This
+ // only works if the method names have not be proguarded out or renamed.
+ Method listMethod = nameToNoArgMethod.get("get" + suffix);
+ if (listMethod != null) {
+ printField(
+ buffer,
+ indent,
+ camelCaseToSnakeCase(camelCase),
+ GeneratedMessageLite.invokeOrDie(listMethod, messageLite));
+ continue;
+ }
+ }
+
+ Method setter = nameToMethod.get("set" + suffix);
+ if (setter == null) {
+ continue;
+ }
+ if (suffix.endsWith(BYTES_SUFFIX)
+ && nameToNoArgMethod.containsKey(
+ "get" + suffix.substring(0, suffix.length() - "Bytes".length()))) {
+ // Heuristic to skip bytes based accessors for string fields.
+ continue;
+ }
+
+ String camelCase = suffix.substring(0, 1).toLowerCase() + suffix.substring(1);
+
+ // Try to reflectively get the value and toString() the field as if it were optional. This
+ // only works if the method names have not be proguarded out or renamed.
+ Method getMethod = nameToNoArgMethod.get("get" + suffix);
+ Method hasMethod = nameToNoArgMethod.get("has" + suffix);
+ // TODO(dweis): Fix proto3 semantics.
+ if (getMethod != null) {
+ Object value = GeneratedMessageLite.invokeOrDie(getMethod, messageLite);
+ final boolean hasValue = hasMethod == null
+ ? !isDefaultValue(value)
+ : (Boolean) GeneratedMessageLite.invokeOrDie(hasMethod, messageLite);
+ // TODO(dweis): This doesn't stop printing oneof case twice: value and enum style.
+ if (hasValue) {
+ printField(
+ buffer,
+ indent,
+ camelCaseToSnakeCase(camelCase),
+ value);
+ }
+ continue;
+ }
+ }
+
+ if (messageLite instanceof GeneratedMessageLite.ExtendableMessage) {
+ Iterator<Map.Entry<GeneratedMessageLite.ExtensionDescriptor, Object>> iter =
+ ((GeneratedMessageLite.ExtendableMessage<?, ?>) messageLite).extensions.iterator();
+ while (iter.hasNext()) {
+ Map.Entry<GeneratedMessageLite.ExtensionDescriptor, Object> entry = iter.next();
+ printField(buffer, indent, "[" + entry.getKey().getNumber() + "]", entry.getValue());
+ }
+ }
+
+ if (((GeneratedMessageLite<?, ?>) messageLite).unknownFields != null) {
+ ((GeneratedMessageLite<?, ?>) messageLite).unknownFields.printWithIndent(buffer, indent);
+ }
+ }
+
+ private static boolean isDefaultValue(Object o) {
+ if (o instanceof Boolean) {
+ return !((Boolean) o);
+ }
+ if (o instanceof Integer) {
+ return ((Integer) o) == 0;
+ }
+ if (o instanceof Float) {
+ return ((Float) o) == 0f;
+ }
+ if (o instanceof Double) {
+ return ((Double) o) == 0d;
+ }
+ if (o instanceof String) {
+ return o.equals("");
+ }
+ if (o instanceof ByteString) {
+ return o.equals(ByteString.EMPTY);
+ }
+ if (o instanceof MessageLite) { // Can happen in oneofs.
+ return o == ((MessageLite) o).getDefaultInstanceForType();
+ }
+ if (o instanceof java.lang.Enum<?>) { // Catches oneof enums.
+ return ((java.lang.Enum<?>) o).ordinal() == 0;
+ }
+
+ return false;
+ }
+
+ /**
+ * Formats a text proto field.
+ *
+ * <p>For use by generated code only.
+ *
+ * @param buffer the buffer to write to
+ * @param indent the number of spaces the proto should be indented by
+ * @param name the field name (in lower underscore case)
+ * @param object the object value of the field
+ */
+ static final void printField(StringBuilder buffer, int indent, String name, Object object) {
+ if (object instanceof List<?>) {
+ List<?> list = (List<?>) object;
+ for (Object entry : list) {
+ printField(buffer, indent, name, entry);
+ }
+ return;
+ }
+
+ buffer.append('\n');
+ for (int i = 0; i < indent; i++) {
+ buffer.append(' ');
+ }
+ buffer.append(name);
+
+ if (object instanceof String) {
+ buffer.append(": \"").append(TextFormatEscaper.escapeText((String) object)).append('"');
+ } else if (object instanceof ByteString) {
+ buffer.append(": \"").append(TextFormatEscaper.escapeBytes((ByteString) object)).append('"');
+ } else if (object instanceof GeneratedMessageLite) {
+ buffer.append(" {");
+ reflectivePrintWithIndent((GeneratedMessageLite<?, ?>) object, buffer, indent + 2);
+ buffer.append("\n");
+ for (int i = 0; i < indent; i++) {
+ buffer.append(' ');
+ }
+ buffer.append("}");
+ } else {
+ buffer.append(": ").append(object.toString());
+ }
+ }
+
+ private static final String camelCaseToSnakeCase(String camelCase) {
+ StringBuilder builder = new StringBuilder();
+ for (int i = 0; i < camelCase.length(); i++) {
+ char ch = camelCase.charAt(i);
+ if (Character.isUpperCase(ch)) {
+ builder.append("_");
+ }
+ builder.append(Character.toLowerCase(ch));
+ }
+ return builder.toString();
+ }
+}
diff --git a/java/src/main/java/com/google/protobuf/MessageOrBuilder.java b/java/core/src/main/java/com/google/protobuf/MessageOrBuilder.java
index f0fc4859..5e7d7821 100644
--- a/java/src/main/java/com/google/protobuf/MessageOrBuilder.java
+++ b/java/core/src/main/java/com/google/protobuf/MessageOrBuilder.java
@@ -42,7 +42,7 @@ import java.util.Map;
public interface MessageOrBuilder extends MessageLiteOrBuilder {
// (From MessageLite, re-declared here only for return type covariance.)
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
Message getDefaultInstanceForType();
/**
diff --git a/java/src/main/java/com/google/protobuf/MessageReflection.java b/java/core/src/main/java/com/google/protobuf/MessageReflection.java
index de4bfd3e..3d73efb3 100644
--- a/java/src/main/java/com/google/protobuf/MessageReflection.java
+++ b/java/core/src/main/java/com/google/protobuf/MessageReflection.java
@@ -370,6 +370,7 @@ class MessageReflection {
private final Message.Builder builder;
+ @Override
public Descriptors.Descriptor getDescriptorForType() {
return builder.getDescriptorForType();
}
@@ -378,6 +379,7 @@ class MessageReflection {
this.builder = builder;
}
+ @Override
public Object getField(Descriptors.FieldDescriptor field) {
return builder.getField(field);
}
@@ -387,25 +389,27 @@ class MessageReflection {
return builder.hasField(field);
}
- public MergeTarget setField(Descriptors.FieldDescriptor field,
- Object value) {
+ @Override
+ public MergeTarget setField(Descriptors.FieldDescriptor field, Object value) {
builder.setField(field, value);
return this;
}
+ @Override
public MergeTarget clearField(Descriptors.FieldDescriptor field) {
builder.clearField(field);
return this;
}
+ @Override
public MergeTarget setRepeatedField(
Descriptors.FieldDescriptor field, int index, Object value) {
builder.setRepeatedField(field, index, value);
return this;
}
- public MergeTarget addRepeatedField(
- Descriptors.FieldDescriptor field, Object value) {
+ @Override
+ public MergeTarget addRepeatedField(Descriptors.FieldDescriptor field, Object value) {
builder.addRepeatedField(field, value);
return this;
}
@@ -426,25 +430,30 @@ class MessageReflection {
return builder.getOneofFieldDescriptor(oneof);
}
+ @Override
public ContainerType getContainerType() {
return ContainerType.MESSAGE;
}
+ @Override
public ExtensionRegistry.ExtensionInfo findExtensionByName(
ExtensionRegistry registry, String name) {
return registry.findImmutableExtensionByName(name);
}
+ @Override
public ExtensionRegistry.ExtensionInfo findExtensionByNumber(
- ExtensionRegistry registry, Descriptors.Descriptor containingType,
- int fieldNumber) {
+ ExtensionRegistry registry, Descriptors.Descriptor containingType, int fieldNumber) {
return registry.findImmutableExtensionByNumber(containingType,
fieldNumber);
}
- public Object parseGroup(CodedInputStream input,
+ @Override
+ public Object parseGroup(
+ CodedInputStream input,
ExtensionRegistryLite extensionRegistry,
- Descriptors.FieldDescriptor field, Message defaultInstance)
+ Descriptors.FieldDescriptor field,
+ Message defaultInstance)
throws IOException {
Message.Builder subBuilder;
// When default instance is not null. The field is an extension field.
@@ -463,9 +472,12 @@ class MessageReflection {
return subBuilder.buildPartial();
}
- public Object parseMessage(CodedInputStream input,
+ @Override
+ public Object parseMessage(
+ CodedInputStream input,
ExtensionRegistryLite extensionRegistry,
- Descriptors.FieldDescriptor field, Message defaultInstance)
+ Descriptors.FieldDescriptor field,
+ Message defaultInstance)
throws IOException {
Message.Builder subBuilder;
// When default instance is not null. The field is an extension field.
@@ -484,9 +496,12 @@ class MessageReflection {
return subBuilder.buildPartial();
}
- public Object parseMessageFromBytes(ByteString bytes,
+ @Override
+ public Object parseMessageFromBytes(
+ ByteString bytes,
ExtensionRegistryLite extensionRegistry,
- Descriptors.FieldDescriptor field, Message defaultInstance)
+ Descriptors.FieldDescriptor field,
+ Message defaultInstance)
throws IOException {
Message.Builder subBuilder;
// When default instance is not null. The field is an extension field.
@@ -505,8 +520,9 @@ class MessageReflection {
return subBuilder.buildPartial();
}
- public MergeTarget newMergeTargetForField(Descriptors.FieldDescriptor field,
- Message defaultInstance) {
+ @Override
+ public MergeTarget newMergeTargetForField(
+ Descriptors.FieldDescriptor field, Message defaultInstance) {
if (defaultInstance != null) {
return new BuilderAdapter(
defaultInstance.newBuilderForType());
@@ -515,8 +531,8 @@ class MessageReflection {
}
}
- public WireFormat.Utf8Validation
- getUtf8Validation(Descriptors.FieldDescriptor descriptor) {
+ @Override
+ public WireFormat.Utf8Validation getUtf8Validation(Descriptors.FieldDescriptor descriptor) {
if (descriptor.needsUtf8Check()) {
return WireFormat.Utf8Validation.STRICT;
}
@@ -528,6 +544,7 @@ class MessageReflection {
return WireFormat.Utf8Validation.LOOSE;
}
+ @Override
public Object finish() {
return builder.buildPartial();
}
@@ -542,38 +559,43 @@ class MessageReflection {
this.extensions = extensions;
}
+ @Override
public Descriptors.Descriptor getDescriptorForType() {
throw new UnsupportedOperationException(
"getDescriptorForType() called on FieldSet object");
}
+ @Override
public Object getField(Descriptors.FieldDescriptor field) {
return extensions.getField(field);
}
+ @Override
public boolean hasField(Descriptors.FieldDescriptor field) {
return extensions.hasField(field);
}
- public MergeTarget setField(Descriptors.FieldDescriptor field,
- Object value) {
+ @Override
+ public MergeTarget setField(Descriptors.FieldDescriptor field, Object value) {
extensions.setField(field, value);
return this;
}
+ @Override
public MergeTarget clearField(Descriptors.FieldDescriptor field) {
extensions.clearField(field);
return this;
}
+ @Override
public MergeTarget setRepeatedField(
Descriptors.FieldDescriptor field, int index, Object value) {
extensions.setRepeatedField(field, index, value);
return this;
}
- public MergeTarget addRepeatedField(
- Descriptors.FieldDescriptor field, Object value) {
+ @Override
+ public MergeTarget addRepeatedField(Descriptors.FieldDescriptor field, Object value) {
extensions.addRepeatedField(field, value);
return this;
}
@@ -594,25 +616,31 @@ class MessageReflection {
return null;
}
+ @Override
public ContainerType getContainerType() {
return ContainerType.EXTENSION_SET;
}
+ @Override
public ExtensionRegistry.ExtensionInfo findExtensionByName(
ExtensionRegistry registry, String name) {
return registry.findImmutableExtensionByName(name);
}
+ @Override
public ExtensionRegistry.ExtensionInfo findExtensionByNumber(
- ExtensionRegistry registry, Descriptors.Descriptor containingType,
- int fieldNumber) {
+ ExtensionRegistry registry, Descriptors.Descriptor containingType, int fieldNumber) {
return registry.findImmutableExtensionByNumber(containingType,
fieldNumber);
}
- public Object parseGroup(CodedInputStream input,
- ExtensionRegistryLite registry, Descriptors.FieldDescriptor field,
- Message defaultInstance) throws IOException {
+ @Override
+ public Object parseGroup(
+ CodedInputStream input,
+ ExtensionRegistryLite registry,
+ Descriptors.FieldDescriptor field,
+ Message defaultInstance)
+ throws IOException {
Message.Builder subBuilder =
defaultInstance.newBuilderForType();
if (!field.isRepeated()) {
@@ -625,9 +653,13 @@ class MessageReflection {
return subBuilder.buildPartial();
}
- public Object parseMessage(CodedInputStream input,
- ExtensionRegistryLite registry, Descriptors.FieldDescriptor field,
- Message defaultInstance) throws IOException {
+ @Override
+ public Object parseMessage(
+ CodedInputStream input,
+ ExtensionRegistryLite registry,
+ Descriptors.FieldDescriptor field,
+ Message defaultInstance)
+ throws IOException {
Message.Builder subBuilder =
defaultInstance.newBuilderForType();
if (!field.isRepeated()) {
@@ -640,9 +672,13 @@ class MessageReflection {
return subBuilder.buildPartial();
}
- public Object parseMessageFromBytes(ByteString bytes,
- ExtensionRegistryLite registry, Descriptors.FieldDescriptor field,
- Message defaultInstance) throws IOException {
+ @Override
+ public Object parseMessageFromBytes(
+ ByteString bytes,
+ ExtensionRegistryLite registry,
+ Descriptors.FieldDescriptor field,
+ Message defaultInstance)
+ throws IOException {
Message.Builder subBuilder = defaultInstance.newBuilderForType();
if (!field.isRepeated()) {
Message originalMessage = (Message) getField(field);
@@ -654,14 +690,15 @@ class MessageReflection {
return subBuilder.buildPartial();
}
+ @Override
public MergeTarget newMergeTargetForField(
Descriptors.FieldDescriptor descriptor, Message defaultInstance) {
throw new UnsupportedOperationException(
"newMergeTargetForField() called on FieldSet object");
}
- public WireFormat.Utf8Validation
- getUtf8Validation(Descriptors.FieldDescriptor descriptor) {
+ @Override
+ public WireFormat.Utf8Validation getUtf8Validation(Descriptors.FieldDescriptor descriptor) {
if (descriptor.needsUtf8Check()) {
return WireFormat.Utf8Validation.STRICT;
}
@@ -669,6 +706,7 @@ class MessageReflection {
return WireFormat.Utf8Validation.LOOSE;
}
+ @Override
public Object finish() {
throw new UnsupportedOperationException(
"finish() called on FieldSet object");
diff --git a/java/src/main/java/com/google/protobuf/MutabilityOracle.java b/java/core/src/main/java/com/google/protobuf/MutabilityOracle.java
index 82b723c9..82b723c9 100644
--- a/java/src/main/java/com/google/protobuf/MutabilityOracle.java
+++ b/java/core/src/main/java/com/google/protobuf/MutabilityOracle.java
diff --git a/java/core/src/main/java/com/google/protobuf/NioByteString.java b/java/core/src/main/java/com/google/protobuf/NioByteString.java
new file mode 100644
index 00000000..6163c7b1
--- /dev/null
+++ b/java/core/src/main/java/com/google/protobuf/NioByteString.java
@@ -0,0 +1,290 @@
+// 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.
+
+package com.google.protobuf;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InvalidObjectException;
+import java.io.ObjectInputStream;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.InvalidMarkException;
+import java.nio.charset.Charset;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * A {@link ByteString} that wraps around a {@link ByteBuffer}.
+ */
+final class NioByteString extends ByteString.LeafByteString {
+ private final ByteBuffer buffer;
+
+ NioByteString(ByteBuffer buffer) {
+ if (buffer == null) {
+ throw new NullPointerException("buffer");
+ }
+
+ this.buffer = buffer.slice().order(ByteOrder.nativeOrder());
+ }
+
+ // =================================================================
+ // Serializable
+
+ /**
+ * Magic method that lets us override serialization behavior.
+ */
+ private Object writeReplace() {
+ return ByteString.copyFrom(buffer.slice());
+ }
+
+ /**
+ * Magic method that lets us override deserialization behavior.
+ */
+ private void readObject(@SuppressWarnings("unused") ObjectInputStream in) throws IOException {
+ throw new InvalidObjectException("NioByteString instances are not to be serialized directly");
+ }
+
+ // =================================================================
+
+ @Override
+ public byte byteAt(int index) {
+ try {
+ return buffer.get(index);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ throw e;
+ } catch (IndexOutOfBoundsException e) {
+ throw new ArrayIndexOutOfBoundsException(e.getMessage());
+ }
+ }
+
+ @Override
+ public int size() {
+ return buffer.remaining();
+ }
+
+ @Override
+ public ByteString substring(int beginIndex, int endIndex) {
+ try {
+ ByteBuffer slice = slice(beginIndex, endIndex);
+ return new NioByteString(slice);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ throw e;
+ } catch (IndexOutOfBoundsException e) {
+ throw new ArrayIndexOutOfBoundsException(e.getMessage());
+ }
+ }
+
+ @Override
+ protected void copyToInternal(
+ byte[] target, int sourceOffset, int targetOffset, int numberToCopy) {
+ ByteBuffer slice = buffer.slice();
+ slice.position(sourceOffset);
+ slice.get(target, targetOffset, numberToCopy);
+ }
+
+ @Override
+ public void copyTo(ByteBuffer target) {
+ target.put(buffer.slice());
+ }
+
+ @Override
+ public void writeTo(OutputStream out) throws IOException {
+ out.write(toByteArray());
+ }
+
+ @Override
+ boolean equalsRange(ByteString other, int offset, int length) {
+ return substring(0, length).equals(other.substring(offset, offset + length));
+ }
+
+ @Override
+ void writeToInternal(OutputStream out, int sourceOffset, int numberToWrite) throws IOException {
+ if (buffer.hasArray()) {
+ // Optimized write for array-backed buffers.
+ // Note that we're taking the risk that a malicious OutputStream could modify the array.
+ int bufferOffset = buffer.arrayOffset() + buffer.position() + sourceOffset;
+ out.write(buffer.array(), bufferOffset, numberToWrite);
+ return;
+ }
+
+ ByteBufferWriter.write(slice(sourceOffset, sourceOffset + numberToWrite), out);
+ }
+
+ @Override
+ void writeTo(ByteOutput output) throws IOException {
+ output.writeLazy(buffer.slice());
+ }
+
+ @Override
+ public ByteBuffer asReadOnlyByteBuffer() {
+ return buffer.asReadOnlyBuffer();
+ }
+
+ @Override
+ public List<ByteBuffer> asReadOnlyByteBufferList() {
+ return Collections.singletonList(asReadOnlyByteBuffer());
+ }
+
+ @Override
+ protected String toStringInternal(Charset charset) {
+ final byte[] bytes;
+ final int offset;
+ final int length;
+ if (buffer.hasArray()) {
+ bytes = buffer.array();
+ offset = buffer.arrayOffset() + buffer.position();
+ length = buffer.remaining();
+ } else {
+ // TODO(nathanmittler): Can we optimize this?
+ bytes = toByteArray();
+ offset = 0;
+ length = bytes.length;
+ }
+ return new String(bytes, offset, length, charset);
+ }
+
+ @Override
+ public boolean isValidUtf8() {
+ return Utf8.isValidUtf8(buffer);
+ }
+
+ @Override
+ protected int partialIsValidUtf8(int state, int offset, int length) {
+ return Utf8.partialIsValidUtf8(state, buffer, offset, offset + length);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) {
+ return true;
+ }
+ if (!(other instanceof ByteString)) {
+ return false;
+ }
+ ByteString otherString = ((ByteString) other);
+ if (size() != otherString.size()) {
+ return false;
+ }
+ if (size() == 0) {
+ return true;
+ }
+ if (other instanceof NioByteString) {
+ return buffer.equals(((NioByteString) other).buffer);
+ }
+ if (other instanceof RopeByteString) {
+ return other.equals(this);
+ }
+ return buffer.equals(otherString.asReadOnlyByteBuffer());
+ }
+
+ @Override
+ protected int partialHash(int h, int offset, int length) {
+ for (int i = offset; i < offset + length; i++) {
+ h = h * 31 + buffer.get(i);
+ }
+ return h;
+ }
+
+ @Override
+ public InputStream newInput() {
+ return new InputStream() {
+ private final ByteBuffer buf = buffer.slice();
+
+ @Override
+ public void mark(int readlimit) {
+ buf.mark();
+ }
+
+ @Override
+ public boolean markSupported() {
+ return true;
+ }
+
+ @Override
+ public void reset() throws IOException {
+ try {
+ buf.reset();
+ } catch (InvalidMarkException e) {
+ throw new IOException(e);
+ }
+ }
+
+ @Override
+ public int available() throws IOException {
+ return buf.remaining();
+ }
+
+ @Override
+ public int read() throws IOException {
+ if (!buf.hasRemaining()) {
+ return -1;
+ }
+ return buf.get() & 0xFF;
+ }
+
+ @Override
+ public int read(byte[] bytes, int off, int len) throws IOException {
+ if (!buf.hasRemaining()) {
+ return -1;
+ }
+
+ len = Math.min(len, buf.remaining());
+ buf.get(bytes, off, len);
+ return len;
+ }
+ };
+ }
+
+ @Override
+ public CodedInputStream newCodedInput() {
+ return CodedInputStream.newInstance(buffer);
+ }
+
+ /**
+ * Creates a slice of a range of this buffer.
+ *
+ * @param beginIndex the beginning index of the slice (inclusive).
+ * @param endIndex the end index of the slice (exclusive).
+ * @return the requested slice.
+ */
+ private ByteBuffer slice(int beginIndex, int endIndex) {
+ if (beginIndex < buffer.position() || endIndex > buffer.limit() || beginIndex > endIndex) {
+ throw new IllegalArgumentException(
+ String.format("Invalid indices [%d, %d]", beginIndex, endIndex));
+ }
+
+ ByteBuffer slice = buffer.slice();
+ slice.position(beginIndex - buffer.position());
+ slice.limit(endIndex - buffer.position());
+ return slice;
+ }
+}
diff --git a/java/src/main/java/com/google/protobuf/Parser.java b/java/core/src/main/java/com/google/protobuf/Parser.java
index 227c02b7..cfbcb442 100644
--- a/java/src/main/java/com/google/protobuf/Parser.java
+++ b/java/core/src/main/java/com/google/protobuf/Parser.java
@@ -37,9 +37,20 @@ import java.io.InputStream;
*
* The implementation should be stateless and thread-safe.
*
+ * <p>All methods may throw {@link InvalidProtocolBufferException}. In the event of invalid data,
+ * like an encoding error, the cause of the thrown exception will be {@code null}. However, if an
+ * I/O problem occurs, an exception is thrown with an {@link java.io.IOException} cause.
+ *
* @author liujisi@google.com (Pherl Liu)
*/
public interface Parser<MessageType> {
+
+ // NB(jh): Other parts of the protobuf API that parse messages distinguish between an I/O problem
+ // (like failure reading bytes from a socket) and invalid data (encoding error) via the type of
+ // thrown exception. But it would be source-incompatible to make the methods in this interface do
+ // so since they were originally spec'ed to only throw InvalidProtocolBufferException. So callers
+ // must inspect the cause of the exception to distinguish these two cases.
+
/**
* Parses a message of {@code MessageType} from the input.
*
diff --git a/java/src/main/java/com/google/protobuf/ProtobufArrayList.java b/java/core/src/main/java/com/google/protobuf/ProtobufArrayList.java
index 759368c9..81255ec2 100644
--- a/java/src/main/java/com/google/protobuf/ProtobufArrayList.java
+++ b/java/core/src/main/java/com/google/protobuf/ProtobufArrayList.java
@@ -38,7 +38,7 @@ import java.util.List;
/**
* Implements {@link ProtobufList} for non-primitive and {@link String} types.
*/
-class ProtobufArrayList<E> extends AbstractProtobufList<E> {
+final class ProtobufArrayList<E> extends AbstractProtobufList<E> {
private static final ProtobufArrayList<Object> EMPTY_LIST = new ProtobufArrayList<Object>();
static {
@@ -51,13 +51,23 @@ class ProtobufArrayList<E> extends AbstractProtobufList<E> {
}
private final List<E> list;
-
+
ProtobufArrayList() {
- list = new ArrayList<E>();
+ this(new ArrayList<E>(DEFAULT_CAPACITY));
}
- ProtobufArrayList(List<E> toCopy) {
- list = new ArrayList<E>(toCopy);
+ private ProtobufArrayList(List<E> list) {
+ this.list = list;
+ }
+
+ @Override
+ public ProtobufArrayList<E> mutableCopyWithCapacity(int capacity) {
+ if (capacity < size()) {
+ throw new IllegalArgumentException();
+ }
+ List<E> newList = new ArrayList<E>(capacity);
+ newList.addAll(list);
+ return new ProtobufArrayList<E>(newList);
}
@Override
diff --git a/java/src/main/java/com/google/protobuf/ProtocolMessageEnum.java b/java/core/src/main/java/com/google/protobuf/ProtocolMessageEnum.java
index 0c8df989..a596d301 100644
--- a/java/src/main/java/com/google/protobuf/ProtocolMessageEnum.java
+++ b/java/core/src/main/java/com/google/protobuf/ProtocolMessageEnum.java
@@ -42,6 +42,7 @@ public interface ProtocolMessageEnum extends Internal.EnumLite {
/**
* Return the value's numeric value as defined in the .proto file.
*/
+ @Override
int getNumber();
/**
diff --git a/java/src/main/java/com/google/protobuf/ProtocolStringList.java b/java/core/src/main/java/com/google/protobuf/ProtocolStringList.java
index d553b41e..d553b41e 100644
--- a/java/src/main/java/com/google/protobuf/ProtocolStringList.java
+++ b/java/core/src/main/java/com/google/protobuf/ProtocolStringList.java
diff --git a/java/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java b/java/core/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java
index f91cdbce..29f567dc 100644
--- a/java/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java
+++ b/java/core/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java
@@ -579,7 +579,7 @@ public class RepeatedFieldBuilder
}
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public void markDirty() {
onChanged();
}
@@ -621,10 +621,12 @@ public class RepeatedFieldBuilder
this.builder = builder;
}
+ @Override
public int size() {
return this.builder.getCount();
}
+ @Override
public MType get(int index) {
return builder.getMessage(index);
}
@@ -654,10 +656,12 @@ public class RepeatedFieldBuilder
this.builder = builder;
}
+ @Override
public int size() {
return this.builder.getCount();
}
+ @Override
public BType get(int index) {
return builder.getBuilder(index);
}
@@ -687,10 +691,12 @@ public class RepeatedFieldBuilder
this.builder = builder;
}
+ @Override
public int size() {
return this.builder.getCount();
}
+ @Override
public IType get(int index) {
return builder.getMessageOrBuilder(index);
}
diff --git a/java/core/src/main/java/com/google/protobuf/RepeatedFieldBuilderV3.java b/java/core/src/main/java/com/google/protobuf/RepeatedFieldBuilderV3.java
new file mode 100644
index 00000000..77b61b5f
--- /dev/null
+++ b/java/core/src/main/java/com/google/protobuf/RepeatedFieldBuilderV3.java
@@ -0,0 +1,708 @@
+// 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.
+
+package com.google.protobuf;
+
+import java.util.AbstractList;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * {@code RepeatedFieldBuilderV3} implements a structure that a protocol
+ * message uses to hold a repeated field of other protocol messages. It supports
+ * the classical use case of adding immutable {@link Message}'s to the
+ * repeated field and is highly optimized around this (no extra memory
+ * allocations and sharing of immutable arrays).
+ * <br>
+ * It also supports the additional use case of adding a {@link Message.Builder}
+ * to the repeated field and deferring conversion of that {@code Builder}
+ * to an immutable {@code Message}. In this way, it's possible to maintain
+ * a tree of {@code Builder}'s that acts as a fully read/write data
+ * structure.
+ * <br>
+ * Logically, one can think of a tree of builders as converting the entire tree
+ * to messages when build is called on the root or when any method is called
+ * that desires a Message instead of a Builder. In terms of the implementation,
+ * the {@code SingleFieldBuilderV3} and {@code RepeatedFieldBuilderV3}
+ * classes cache messages that were created so that messages only need to be
+ * created when some change occurred in its builder or a builder for one of its
+ * descendants.
+ *
+ * @param <MType> the type of message for the field
+ * @param <BType> the type of builder for the field
+ * @param <IType> the common interface for the message and the builder
+ *
+ * @author jonp@google.com (Jon Perlow)
+ */
+public class RepeatedFieldBuilderV3
+ <MType extends AbstractMessage,
+ BType extends AbstractMessage.Builder,
+ IType extends MessageOrBuilder>
+ implements AbstractMessage.BuilderParent {
+
+ // Parent to send changes to.
+ private AbstractMessage.BuilderParent parent;
+
+ // List of messages. Never null. It may be immutable, in which case
+ // isMessagesListMutable will be false. See note below.
+ private List<MType> messages;
+
+ // Whether messages is an mutable array that can be modified.
+ private boolean isMessagesListMutable;
+
+ // List of builders. May be null, in which case, no nested builders were
+ // created. If not null, entries represent the builder for that index.
+ private List<SingleFieldBuilderV3<MType, BType, IType>> builders;
+
+ // Here are the invariants for messages and builders:
+ // 1. messages is never null and its count corresponds to the number of items
+ // in the repeated field.
+ // 2. If builders is non-null, messages and builders MUST always
+ // contain the same number of items.
+ // 3. Entries in either array can be null, but for any index, there MUST be
+ // either a Message in messages or a builder in builders.
+ // 4. If the builder at an index is non-null, the builder is
+ // authoritative. This is the case where a Builder was set on the index.
+ // Any message in the messages array MUST be ignored.
+ // t. If the builder at an index is null, the message in the messages
+ // list is authoritative. This is the case where a Message (not a Builder)
+ // was set directly for an index.
+
+ // Indicates that we've built a message and so we are now obligated
+ // to dispatch dirty invalidations. See AbstractMessage.BuilderListener.
+ private boolean isClean;
+
+ // A view of this builder that exposes a List interface of messages. This is
+ // initialized on demand. This is fully backed by this object and all changes
+ // are reflected in it. Access to any item converts it to a message if it
+ // was a builder.
+ private MessageExternalList<MType, BType, IType> externalMessageList;
+
+ // A view of this builder that exposes a List interface of builders. This is
+ // initialized on demand. This is fully backed by this object and all changes
+ // are reflected in it. Access to any item converts it to a builder if it
+ // was a message.
+ private BuilderExternalList<MType, BType, IType> externalBuilderList;
+
+ // A view of this builder that exposes a List interface of the interface
+ // implemented by messages and builders. This is initialized on demand. This
+ // is fully backed by this object and all changes are reflected in it.
+ // Access to any item returns either a builder or message depending on
+ // what is most efficient.
+ private MessageOrBuilderExternalList<MType, BType, IType>
+ externalMessageOrBuilderList;
+
+ /**
+ * Constructs a new builder with an empty list of messages.
+ *
+ * @param messages the current list of messages
+ * @param isMessagesListMutable Whether the messages list is mutable
+ * @param parent a listener to notify of changes
+ * @param isClean whether the builder is initially marked clean
+ */
+ public RepeatedFieldBuilderV3(
+ List<MType> messages,
+ boolean isMessagesListMutable,
+ AbstractMessage.BuilderParent parent,
+ boolean isClean) {
+ this.messages = messages;
+ this.isMessagesListMutable = isMessagesListMutable;
+ this.parent = parent;
+ this.isClean = isClean;
+ }
+
+ public void dispose() {
+ // Null out parent so we stop sending it invalidations.
+ parent = null;
+ }
+
+ /**
+ * Ensures that the list of messages is mutable so it can be updated. If it's
+ * immutable, a copy is made.
+ */
+ private void ensureMutableMessageList() {
+ if (!isMessagesListMutable) {
+ messages = new ArrayList<MType>(messages);
+ isMessagesListMutable = true;
+ }
+ }
+
+ /**
+ * Ensures that the list of builders is not null. If it's null, the list is
+ * created and initialized to be the same size as the messages list with
+ * null entries.
+ */
+ private void ensureBuilders() {
+ if (this.builders == null) {
+ this.builders =
+ new ArrayList<SingleFieldBuilderV3<MType, BType, IType>>(
+ messages.size());
+ for (int i = 0; i < messages.size(); i++) {
+ builders.add(null);
+ }
+ }
+ }
+
+ /**
+ * Gets the count of items in the list.
+ *
+ * @return the count of items in the list.
+ */
+ public int getCount() {
+ return messages.size();
+ }
+
+ /**
+ * Gets whether the list is empty.
+ *
+ * @return whether the list is empty
+ */
+ public boolean isEmpty() {
+ return messages.isEmpty();
+ }
+
+ /**
+ * Get the message at the specified index. If the message is currently stored
+ * as a {@code Builder}, it is converted to a {@code Message} by
+ * calling {@link Message.Builder#buildPartial} on it.
+ *
+ * @param index the index of the message to get
+ * @return the message for the specified index
+ */
+ public MType getMessage(int index) {
+ return getMessage(index, false);
+ }
+
+ /**
+ * Get the message at the specified index. If the message is currently stored
+ * as a {@code Builder}, it is converted to a {@code Message} by
+ * calling {@link Message.Builder#buildPartial} on it.
+ *
+ * @param index the index of the message to get
+ * @param forBuild this is being called for build so we want to make sure
+ * we SingleFieldBuilderV3.build to send dirty invalidations
+ * @return the message for the specified index
+ */
+ private MType getMessage(int index, boolean forBuild) {
+ if (this.builders == null) {
+ // We don't have any builders -- return the current Message.
+ // This is the case where no builder was created, so we MUST have a
+ // Message.
+ return messages.get(index);
+ }
+
+ SingleFieldBuilderV3<MType, BType, IType> builder = builders.get(index);
+ if (builder == null) {
+ // We don't have a builder -- return the current message.
+ // This is the case where no builder was created for the entry at index,
+ // so we MUST have a message.
+ return messages.get(index);
+
+ } else {
+ return forBuild ? builder.build() : builder.getMessage();
+ }
+ }
+
+ /**
+ * Gets a builder for the specified index. If no builder has been created for
+ * that index, a builder is created on demand by calling
+ * {@link Message#toBuilder}.
+ *
+ * @param index the index of the message to get
+ * @return The builder for that index
+ */
+ public BType getBuilder(int index) {
+ ensureBuilders();
+ SingleFieldBuilderV3<MType, BType, IType> builder = builders.get(index);
+ if (builder == null) {
+ MType message = messages.get(index);
+ builder = new SingleFieldBuilderV3<MType, BType, IType>(
+ message, this, isClean);
+ builders.set(index, builder);
+ }
+ return builder.getBuilder();
+ }
+
+ /**
+ * Gets the base class interface for the specified index. This may either be
+ * a builder or a message. It will return whatever is more efficient.
+ *
+ * @param index the index of the message to get
+ * @return the message or builder for the index as the base class interface
+ */
+ @SuppressWarnings("unchecked")
+ public IType getMessageOrBuilder(int index) {
+ if (this.builders == null) {
+ // We don't have any builders -- return the current Message.
+ // This is the case where no builder was created, so we MUST have a
+ // Message.
+ return (IType) messages.get(index);
+ }
+
+ SingleFieldBuilderV3<MType, BType, IType> builder = builders.get(index);
+ if (builder == null) {
+ // We don't have a builder -- return the current message.
+ // This is the case where no builder was created for the entry at index,
+ // so we MUST have a message.
+ return (IType) messages.get(index);
+
+ } else {
+ return builder.getMessageOrBuilder();
+ }
+ }
+
+ /**
+ * Sets a message at the specified index replacing the existing item at
+ * that index.
+ *
+ * @param index the index to set.
+ * @param message the message to set
+ * @return the builder
+ */
+ public RepeatedFieldBuilderV3<MType, BType, IType> setMessage(
+ int index, MType message) {
+ if (message == null) {
+ throw new NullPointerException();
+ }
+ ensureMutableMessageList();
+ messages.set(index, message);
+ if (builders != null) {
+ SingleFieldBuilderV3<MType, BType, IType> entry =
+ builders.set(index, null);
+ if (entry != null) {
+ entry.dispose();
+ }
+ }
+ onChanged();
+ incrementModCounts();
+ return this;
+ }
+
+ /**
+ * Appends the specified element to the end of this list.
+ *
+ * @param message the message to add
+ * @return the builder
+ */
+ public RepeatedFieldBuilderV3<MType, BType, IType> addMessage(
+ MType message) {
+ if (message == null) {
+ throw new NullPointerException();
+ }
+ ensureMutableMessageList();
+ messages.add(message);
+ if (builders != null) {
+ builders.add(null);
+ }
+ onChanged();
+ incrementModCounts();
+ return this;
+ }
+
+ /**
+ * Inserts the specified message at the specified position in this list.
+ * Shifts the element currently at that position (if any) and any subsequent
+ * elements to the right (adds one to their indices).
+ *
+ * @param index the index at which to insert the message
+ * @param message the message to add
+ * @return the builder
+ */
+ public RepeatedFieldBuilderV3<MType, BType, IType> addMessage(
+ int index, MType message) {
+ if (message == null) {
+ throw new NullPointerException();
+ }
+ ensureMutableMessageList();
+ messages.add(index, message);
+ if (builders != null) {
+ builders.add(index, null);
+ }
+ onChanged();
+ incrementModCounts();
+ return this;
+ }
+
+ /**
+ * Appends all of the messages in the specified collection to the end of
+ * this list, in the order that they are returned by the specified
+ * collection's iterator.
+ *
+ * @param values the messages to add
+ * @return the builder
+ */
+ public RepeatedFieldBuilderV3<MType, BType, IType> addAllMessages(
+ Iterable<? extends MType> values) {
+ for (final MType value : values) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ }
+
+ // If we can inspect the size, we can more efficiently add messages.
+ int size = -1;
+ if (values instanceof Collection) {
+ @SuppressWarnings("unchecked") final
+ Collection<MType> collection = (Collection<MType>) values;
+ if (collection.size() == 0) {
+ return this;
+ }
+ size = collection.size();
+ }
+ ensureMutableMessageList();
+
+ if (size >= 0 && messages instanceof ArrayList) {
+ ((ArrayList<MType>) messages)
+ .ensureCapacity(messages.size() + size);
+ }
+
+ for (MType value : values) {
+ addMessage(value);
+ }
+
+ onChanged();
+ incrementModCounts();
+ return this;
+ }
+
+ /**
+ * Appends a new builder to the end of this list and returns the builder.
+ *
+ * @param message the message to add which is the basis of the builder
+ * @return the new builder
+ */
+ public BType addBuilder(MType message) {
+ ensureMutableMessageList();
+ ensureBuilders();
+ SingleFieldBuilderV3<MType, BType, IType> builder =
+ new SingleFieldBuilderV3<MType, BType, IType>(
+ message, this, isClean);
+ messages.add(null);
+ builders.add(builder);
+ onChanged();
+ incrementModCounts();
+ return builder.getBuilder();
+ }
+
+ /**
+ * Inserts a new builder at the specified position in this list.
+ * Shifts the element currently at that position (if any) and any subsequent
+ * elements to the right (adds one to their indices).
+ *
+ * @param index the index at which to insert the builder
+ * @param message the message to add which is the basis of the builder
+ * @return the builder
+ */
+ public BType addBuilder(int index, MType message) {
+ ensureMutableMessageList();
+ ensureBuilders();
+ SingleFieldBuilderV3<MType, BType, IType> builder =
+ new SingleFieldBuilderV3<MType, BType, IType>(
+ message, this, isClean);
+ messages.add(index, null);
+ builders.add(index, builder);
+ onChanged();
+ incrementModCounts();
+ return builder.getBuilder();
+ }
+
+ /**
+ * Removes the element at the specified position in this list. Shifts any
+ * subsequent elements to the left (subtracts one from their indices).
+ * Returns the element that was removed from the list.
+ *
+ * @param index the index at which to remove the message
+ */
+ public void remove(int index) {
+ ensureMutableMessageList();
+ messages.remove(index);
+ if (builders != null) {
+ SingleFieldBuilderV3<MType, BType, IType> entry =
+ builders.remove(index);
+ if (entry != null) {
+ entry.dispose();
+ }
+ }
+ onChanged();
+ incrementModCounts();
+ }
+
+ /**
+ * Removes all of the elements from this list.
+ * The list will be empty after this call returns.
+ */
+ public void clear() {
+ messages = Collections.emptyList();
+ isMessagesListMutable = false;
+ if (builders != null) {
+ for (SingleFieldBuilderV3<MType, BType, IType> entry :
+ builders) {
+ if (entry != null) {
+ entry.dispose();
+ }
+ }
+ builders = null;
+ }
+ onChanged();
+ incrementModCounts();
+ }
+
+ /**
+ * Builds the list of messages from the builder and returns them.
+ *
+ * @return an immutable list of messages
+ */
+ public List<MType> build() {
+ // Now that build has been called, we are required to dispatch
+ // invalidations.
+ isClean = true;
+
+ if (!isMessagesListMutable && builders == null) {
+ // We still have an immutable list and we never created a builder.
+ return messages;
+ }
+
+ boolean allMessagesInSync = true;
+ if (!isMessagesListMutable) {
+ // We still have an immutable list. Let's see if any of them are out
+ // of sync with their builders.
+ for (int i = 0; i < messages.size(); i++) {
+ Message message = messages.get(i);
+ SingleFieldBuilderV3<MType, BType, IType> builder = builders.get(i);
+ if (builder != null) {
+ if (builder.build() != message) {
+ allMessagesInSync = false;
+ break;
+ }
+ }
+ }
+ if (allMessagesInSync) {
+ // Immutable list is still in sync.
+ return messages;
+ }
+ }
+
+ // Need to make sure messages is up to date
+ ensureMutableMessageList();
+ for (int i = 0; i < messages.size(); i++) {
+ messages.set(i, getMessage(i, true));
+ }
+
+ // We're going to return our list as immutable so we mark that we can
+ // no longer update it.
+ messages = Collections.unmodifiableList(messages);
+ isMessagesListMutable = false;
+ return messages;
+ }
+
+ /**
+ * Gets a view of the builder as a list of messages. The returned list is live
+ * and will reflect any changes to the underlying builder.
+ *
+ * @return the messages in the list
+ */
+ public List<MType> getMessageList() {
+ if (externalMessageList == null) {
+ externalMessageList =
+ new MessageExternalList<MType, BType, IType>(this);
+ }
+ return externalMessageList;
+ }
+
+ /**
+ * Gets a view of the builder as a list of builders. This returned list is
+ * live and will reflect any changes to the underlying builder.
+ *
+ * @return the builders in the list
+ */
+ public List<BType> getBuilderList() {
+ if (externalBuilderList == null) {
+ externalBuilderList =
+ new BuilderExternalList<MType, BType, IType>(this);
+ }
+ return externalBuilderList;
+ }
+
+ /**
+ * Gets a view of the builder as a list of MessageOrBuilders. This returned
+ * list is live and will reflect any changes to the underlying builder.
+ *
+ * @return the builders in the list
+ */
+ public List<IType> getMessageOrBuilderList() {
+ if (externalMessageOrBuilderList == null) {
+ externalMessageOrBuilderList =
+ new MessageOrBuilderExternalList<MType, BType, IType>(this);
+ }
+ return externalMessageOrBuilderList;
+ }
+
+ /**
+ * Called when a the builder or one of its nested children has changed
+ * and any parent should be notified of its invalidation.
+ */
+ private void onChanged() {
+ if (isClean && parent != null) {
+ parent.markDirty();
+
+ // Don't keep dispatching invalidations until build is called again.
+ isClean = false;
+ }
+ }
+
+ @Override
+ public void markDirty() {
+ onChanged();
+ }
+
+ /**
+ * Increments the mod counts so that an ConcurrentModificationException can
+ * be thrown if calling code tries to modify the builder while its iterating
+ * the list.
+ */
+ private void incrementModCounts() {
+ if (externalMessageList != null) {
+ externalMessageList.incrementModCount();
+ }
+ if (externalBuilderList != null) {
+ externalBuilderList.incrementModCount();
+ }
+ if (externalMessageOrBuilderList != null) {
+ externalMessageOrBuilderList.incrementModCount();
+ }
+ }
+
+ /**
+ * Provides a live view of the builder as a list of messages.
+ *
+ * @param <MType> the type of message for the field
+ * @param <BType> the type of builder for the field
+ * @param <IType> the common interface for the message and the builder
+ */
+ private static class MessageExternalList<
+ MType extends AbstractMessage,
+ BType extends AbstractMessage.Builder,
+ IType extends MessageOrBuilder>
+ extends AbstractList<MType> implements List<MType> {
+
+ RepeatedFieldBuilderV3<MType, BType, IType> builder;
+
+ MessageExternalList(
+ RepeatedFieldBuilderV3<MType, BType, IType> builder) {
+ this.builder = builder;
+ }
+
+ @Override
+ public int size() {
+ return this.builder.getCount();
+ }
+
+ @Override
+ public MType get(int index) {
+ return builder.getMessage(index);
+ }
+
+ void incrementModCount() {
+ modCount++;
+ }
+ }
+
+ /**
+ * Provides a live view of the builder as a list of builders.
+ *
+ * @param <MType> the type of message for the field
+ * @param <BType> the type of builder for the field
+ * @param <IType> the common interface for the message and the builder
+ */
+ private static class BuilderExternalList<
+ MType extends AbstractMessage,
+ BType extends AbstractMessage.Builder,
+ IType extends MessageOrBuilder>
+ extends AbstractList<BType> implements List<BType> {
+
+ RepeatedFieldBuilderV3<MType, BType, IType> builder;
+
+ BuilderExternalList(
+ RepeatedFieldBuilderV3<MType, BType, IType> builder) {
+ this.builder = builder;
+ }
+
+ @Override
+ public int size() {
+ return this.builder.getCount();
+ }
+
+ @Override
+ public BType get(int index) {
+ return builder.getBuilder(index);
+ }
+
+ void incrementModCount() {
+ modCount++;
+ }
+ }
+
+ /**
+ * Provides a live view of the builder as a list of builders.
+ *
+ * @param <MType> the type of message for the field
+ * @param <BType> the type of builder for the field
+ * @param <IType> the common interface for the message and the builder
+ */
+ private static class MessageOrBuilderExternalList<
+ MType extends AbstractMessage,
+ BType extends AbstractMessage.Builder,
+ IType extends MessageOrBuilder>
+ extends AbstractList<IType> implements List<IType> {
+
+ RepeatedFieldBuilderV3<MType, BType, IType> builder;
+
+ MessageOrBuilderExternalList(
+ RepeatedFieldBuilderV3<MType, BType, IType> builder) {
+ this.builder = builder;
+ }
+
+ @Override
+ public int size() {
+ return this.builder.getCount();
+ }
+
+ @Override
+ public IType get(int index) {
+ return builder.getMessageOrBuilder(index);
+ }
+
+ void incrementModCount() {
+ modCount++;
+ }
+ }
+}
diff --git a/java/src/main/java/com/google/protobuf/RopeByteString.java b/java/core/src/main/java/com/google/protobuf/RopeByteString.java
index 2c332624..3f3e9bd1 100644
--- a/java/src/main/java/com/google/protobuf/RopeByteString.java
+++ b/java/core/src/main/java/com/google/protobuf/RopeByteString.java
@@ -48,10 +48,11 @@ import java.util.Stack;
/**
* Class to represent {@code ByteStrings} formed by concatenation of other
* ByteStrings, without copying the data in the pieces. The concatenation is
- * represented as a tree whose leaf nodes are each a {@link LiteralByteString}.
+ * represented as a tree whose leaf nodes are each a
+ * {@link com.google.protobuf.ByteString.LeafByteString}.
*
* <p>Most of the operation here is inspired by the now-famous paper <a
- * href="http://www.cs.ubc.ca/local/reading/proceedings/spe91-95/spe/vol25/issue12/spe986.pdf">
+ * href="https://web.archive.org/web/20060202015456/http://www.cs.ubc.ca/local/reading/proceedings/spe91-95/spe/vol25/issue12/spe986.pdf">
* BAP95 </a> Ropes: an Alternative to Strings hans-j. boehm, russ atkinson and
* michael plass
*
@@ -69,7 +70,7 @@ import java.util.Stack;
*
* @author carlanton@google.com (Carl Haverl)
*/
-class RopeByteString extends ByteString {
+final class RopeByteString extends ByteString {
/**
* BAP95. Let Fn be the nth Fibonacci number. A {@link RopeByteString} of
@@ -139,8 +140,9 @@ class RopeByteString extends ByteString {
/**
* Concatenate the given strings while performing various optimizations to
* slow the growth rate of tree depth and tree node count. The result is
- * either a {@link LiteralByteString} or a {@link RopeByteString}
- * depending on which optimizations, if any, were applied.
+ * either a {@link com.google.protobuf.ByteString.LeafByteString} or a
+ * {@link RopeByteString} depending on which optimizations, if any, were
+ * applied.
*
* <p>Small pieces of length less than {@link
* ByteString#CONCATENATE_BY_COPY_SIZE} may be copied by value here, as in
@@ -151,21 +153,24 @@ class RopeByteString extends ByteString {
* @return concatenation representing the same sequence as the given strings
*/
static ByteString concatenate(ByteString left, ByteString right) {
- ByteString result;
- RopeByteString leftRope =
- (left instanceof RopeByteString) ? (RopeByteString) left : null;
if (right.size() == 0) {
- result = left;
- } else if (left.size() == 0) {
- result = right;
- } else {
- int newLength = left.size() + right.size();
- if (newLength < ByteString.CONCATENATE_BY_COPY_SIZE) {
- // Optimization from BAP95: For short (leaves in paper, but just short
- // here) total length, do a copy of data to a new leaf.
- result = concatenateBytes(left, right);
- } else if (leftRope != null
- && leftRope.right.size() + right.size() < CONCATENATE_BY_COPY_SIZE) {
+ return left;
+ }
+
+ if (left.size() == 0) {
+ return right;
+ }
+
+ final int newLength = left.size() + right.size();
+ if (newLength < ByteString.CONCATENATE_BY_COPY_SIZE) {
+ // Optimization from BAP95: For short (leaves in paper, but just short
+ // here) total length, do a copy of data to a new leaf.
+ return concatenateBytes(left, right);
+ }
+
+ if (left instanceof RopeByteString) {
+ final RopeByteString leftRope = (RopeByteString) left;
+ if (leftRope.right.size() + right.size() < CONCATENATE_BY_COPY_SIZE) {
// Optimization from BAP95: As an optimization of the case where the
// ByteString is constructed by repeated concatenate, recognize the case
// where a short string is concatenated to a left-hand node whose
@@ -177,30 +182,29 @@ class RopeByteString extends ByteString {
// new parent node so that the depth of the result is the same as the
// given left tree.
ByteString newRight = concatenateBytes(leftRope.right, right);
- result = new RopeByteString(leftRope.left, newRight);
- } else if (leftRope != null
- && leftRope.left.getTreeDepth() > leftRope.right.getTreeDepth()
+ return new RopeByteString(leftRope.left, newRight);
+ }
+
+ if (leftRope.left.getTreeDepth() > leftRope.right.getTreeDepth()
&& leftRope.getTreeDepth() > right.getTreeDepth()) {
// Typically for concatenate-built strings the left-side is deeper than
// the right. This is our final attempt to concatenate without
- // increasing the tree depth. We'll redo the the node on the RHS. This
+ // increasing the tree depth. We'll redo the node on the RHS. This
// is yet another optimization for building the string by repeatedly
// concatenating on the right.
ByteString newRight = new RopeByteString(leftRope.right, right);
- result = new RopeByteString(leftRope.left, newRight);
- } else {
- // Fine, we'll add a node and increase the tree depth--unless we
- // rebalance ;^)
- int newDepth = Math.max(left.getTreeDepth(), right.getTreeDepth()) + 1;
- if (newLength >= minLengthByDepth[newDepth]) {
- // The tree is shallow enough, so don't rebalance
- result = new RopeByteString(left, right);
- } else {
- result = new Balancer().balance(left, right);
- }
+ return new RopeByteString(leftRope.left, newRight);
}
}
- return result;
+
+ // Fine, we'll add a node and increase the tree depth--unless we rebalance ;^)
+ int newDepth = Math.max(left.getTreeDepth(), right.getTreeDepth()) + 1;
+ if (newLength >= minLengthByDepth[newDepth]) {
+ // The tree is shallow enough, so don't rebalance
+ return new RopeByteString(left, right);
+ }
+
+ return new Balancer().balance(left, right);
}
/**
@@ -211,14 +215,14 @@ class RopeByteString extends ByteString {
* @param right string on the right
* @return string formed by copying data bytes
*/
- private static LiteralByteString concatenateBytes(ByteString left,
+ private static ByteString concatenateBytes(ByteString left,
ByteString right) {
int leftSize = left.size();
int rightSize = right.size();
byte[] bytes = new byte[leftSize + rightSize];
left.copyTo(bytes, 0, 0, leftSize);
right.copyTo(bytes, 0, leftSize, rightSize);
- return new LiteralByteString(bytes); // Constructor wraps bytes
+ return ByteString.wrap(bytes); // Constructor wraps bytes
}
/**
@@ -248,22 +252,14 @@ class RopeByteString extends ByteString {
*/
@Override
public byte byteAt(int index) {
- if (index < 0) {
- throw new ArrayIndexOutOfBoundsException("Index < 0: " + index);
- }
- if (index > totalLength) {
- throw new ArrayIndexOutOfBoundsException(
- "Index > length: " + index + ", " + totalLength);
- }
+ checkIndex(index, totalLength);
- byte result;
// Find the relevant piece by recursive descent
if (index < leftLength) {
- result = left.byteAt(index);
- } else {
- result = right.byteAt(index - leftLength);
+ return left.byteAt(index);
}
- return result;
+
+ return right.byteAt(index - leftLength);
}
@Override
@@ -300,8 +296,7 @@ class RopeByteString extends ByteString {
*
* <p>Substrings of {@code length < 2} should result in at most a single
* recursive call chain, terminating at a leaf node. Thus the result will be a
- * {@link LiteralByteString}. {@link #RopeByteString(ByteString,
- * ByteString)}.
+ * {@link com.google.protobuf.ByteString.LeafByteString}.
*
* @param beginIndex start at this index
* @param endIndex the last character is the one before this index
@@ -309,48 +304,36 @@ class RopeByteString extends ByteString {
*/
@Override
public ByteString substring(int beginIndex, int endIndex) {
- if (beginIndex < 0) {
- throw new IndexOutOfBoundsException(
- "Beginning index: " + beginIndex + " < 0");
+ final int length = checkRange(beginIndex, endIndex, totalLength);
+
+ if (length == 0) {
+ // Empty substring
+ return ByteString.EMPTY;
}
- if (endIndex > totalLength) {
- throw new IndexOutOfBoundsException(
- "End index: " + endIndex + " > " + totalLength);
+
+ if (length == totalLength) {
+ // The whole string
+ return this;
}
- int substringLength = endIndex - beginIndex;
- if (substringLength < 0) {
- throw new IndexOutOfBoundsException(
- "Beginning index larger than ending index: " + beginIndex + ", "
- + endIndex);
+
+ // Proper substring
+ if (endIndex <= leftLength) {
+ // Substring on the left
+ return left.substring(beginIndex, endIndex);
}
- ByteString result;
- if (substringLength == 0) {
- // Empty substring
- result = ByteString.EMPTY;
- } else if (substringLength == totalLength) {
- // The whole string
- result = this;
- } else {
- // Proper substring
- if (endIndex <= leftLength) {
- // Substring on the left
- result = left.substring(beginIndex, endIndex);
- } else if (beginIndex >= leftLength) {
- // Substring on the right
- result = right
- .substring(beginIndex - leftLength, endIndex - leftLength);
- } else {
- // Split substring
- ByteString leftSub = left.substring(beginIndex);
- ByteString rightSub = right.substring(0, endIndex - leftLength);
- // Intentionally not rebalancing, since in many cases these two
- // substrings will already be less deep than the top-level
- // RopeByteString we're taking a substring of.
- result = new RopeByteString(leftSub, rightSub);
- }
+ if (beginIndex >= leftLength) {
+ // Substring on the right
+ return right.substring(beginIndex - leftLength, endIndex - leftLength);
}
- return result;
+
+ // Split substring
+ ByteString leftSub = left.substring(beginIndex);
+ ByteString rightSub = right.substring(0, endIndex - leftLength);
+ // Intentionally not rebalancing, since in many cases these two
+ // substrings will already be less deep than the top-level
+ // RopeByteString we're taking a substring of.
+ return new RopeByteString(leftSub, rightSub);
}
// =================================================================
@@ -386,12 +369,12 @@ class RopeByteString extends ByteString {
@Override
public List<ByteBuffer> asReadOnlyByteBufferList() {
- // Walk through the list of LiteralByteString's that make up this
+ // Walk through the list of LeafByteString's that make up this
// rope, and add each one as a read-only ByteBuffer.
List<ByteBuffer> result = new ArrayList<ByteBuffer>();
PieceIterator pieces = new PieceIterator(this);
while (pieces.hasNext()) {
- LiteralByteString byteString = pieces.next();
+ LeafByteString byteString = pieces.next();
result.add(byteString.asReadOnlyByteBuffer());
}
return result;
@@ -418,6 +401,12 @@ class RopeByteString extends ByteString {
}
@Override
+ void writeTo(ByteOutput output) throws IOException {
+ left.writeTo(output);
+ right.writeTo(output);
+ }
+
+ @Override
protected String toStringInternal(Charset charset) {
return new String(toByteArray(), charset);
}
@@ -471,11 +460,10 @@ class RopeByteString extends ByteString {
// hashCode if it's already computed. It's arguable we should compute the
// hashCode here, and if we're going to be testing a bunch of byteStrings,
// it might even make sense.
- if (hash != 0) {
- int cachedOtherHash = otherByteString.peekCachedHashCode();
- if (cachedOtherHash != 0 && hash != cachedOtherHash) {
- return false;
- }
+ int thisHash = peekCachedHashCode();
+ int thatHash = otherByteString.peekCachedHashCode();
+ if (thisHash != 0 && thatHash != 0 && thisHash != thatHash) {
+ return false;
}
return equalsFragments(otherByteString);
@@ -492,12 +480,12 @@ class RopeByteString extends ByteString {
*/
private boolean equalsFragments(ByteString other) {
int thisOffset = 0;
- Iterator<LiteralByteString> thisIter = new PieceIterator(this);
- LiteralByteString thisString = thisIter.next();
+ Iterator<LeafByteString> thisIter = new PieceIterator(this);
+ LeafByteString thisString = thisIter.next();
int thatOffset = 0;
- Iterator<LiteralByteString> thatIter = new PieceIterator(other);
- LiteralByteString thatString = thatIter.next();
+ Iterator<LeafByteString> thatIter = new PieceIterator(other);
+ LeafByteString thatString = thatIter.next();
int pos = 0;
while (true) {
@@ -536,33 +524,6 @@ class RopeByteString extends ByteString {
}
}
- /**
- * Cached hash value. Intentionally accessed via a data race, which is safe
- * because of the Java Memory Model's "no out-of-thin-air values" guarantees
- * for ints.
- */
- private int hash = 0;
-
- @Override
- public int hashCode() {
- int h = hash;
-
- if (h == 0) {
- h = totalLength;
- h = partialHash(h, 0, totalLength);
- if (h == 0) {
- h = 1;
- }
- hash = h;
- }
- return h;
- }
-
- @Override
- protected int peekCachedHashCode() {
- return hash;
- }
-
@Override
protected int partialHash(int h, int offset, int length) {
int toIndex = offset + length;
@@ -714,34 +675,34 @@ class RopeByteString extends ByteString {
* <p>This iterator is used to implement
* {@link RopeByteString#equalsFragments(ByteString)}.
*/
- private static class PieceIterator implements Iterator<LiteralByteString> {
+ private static class PieceIterator implements Iterator<LeafByteString> {
private final Stack<RopeByteString> breadCrumbs =
new Stack<RopeByteString>();
- private LiteralByteString next;
+ private LeafByteString next;
private PieceIterator(ByteString root) {
next = getLeafByLeft(root);
}
- private LiteralByteString getLeafByLeft(ByteString root) {
+ private LeafByteString getLeafByLeft(ByteString root) {
ByteString pos = root;
while (pos instanceof RopeByteString) {
RopeByteString rbs = (RopeByteString) pos;
breadCrumbs.push(rbs);
pos = rbs.left;
}
- return (LiteralByteString) pos;
+ return (LeafByteString) pos;
}
- private LiteralByteString getNextNonEmptyLeaf() {
+ private LeafByteString getNextNonEmptyLeaf() {
while (true) {
// Almost always, we go through this loop exactly once. However, if
// we discover an empty string in the rope, we toss it and try again.
if (breadCrumbs.isEmpty()) {
return null;
} else {
- LiteralByteString result = getLeafByLeft(breadCrumbs.pop().right);
+ LeafByteString result = getLeafByLeft(breadCrumbs.pop().right);
if (!result.isEmpty()) {
return result;
}
@@ -749,24 +710,28 @@ class RopeByteString extends ByteString {
}
}
+ @Override
public boolean hasNext() {
return next != null;
}
/**
- * Returns the next item and advances one {@code LiteralByteString}.
+ * Returns the next item and advances one
+ * {@link com.google.protobuf.ByteString.LeafByteString}.
*
- * @return next non-empty LiteralByteString or {@code null}
+ * @return next non-empty LeafByteString or {@code null}
*/
- public LiteralByteString next() {
+ @Override
+ public LeafByteString next() {
if (next == null) {
throw new NoSuchElementException();
}
- LiteralByteString result = next;
+ LeafByteString result = next;
next = getNextNonEmptyLeaf();
return result;
}
+ @Override
public void remove() {
throw new UnsupportedOperationException();
}
@@ -778,55 +743,14 @@ class RopeByteString extends ByteString {
private static final long serialVersionUID = 1L;
Object writeReplace() {
- return new LiteralByteString(toByteArray());
+ return ByteString.wrap(toByteArray());
}
- private void readObject(ObjectInputStream in) throws IOException {
+ private void readObject(@SuppressWarnings("unused") ObjectInputStream in) throws IOException {
throw new InvalidObjectException(
"RopeByteStream instances are not to be serialized directly");
}
- // =================================================================
- // ByteIterator
-
- @Override
- public ByteIterator iterator() {
- return new RopeByteIterator();
- }
-
- private class RopeByteIterator implements ByteString.ByteIterator {
-
- private final PieceIterator pieces;
- private ByteIterator bytes;
- int bytesRemaining;
-
- private RopeByteIterator() {
- pieces = new PieceIterator(RopeByteString.this);
- bytes = pieces.next().iterator();
- bytesRemaining = size();
- }
-
- public boolean hasNext() {
- return (bytesRemaining > 0);
- }
-
- public Byte next() {
- return nextByte(); // Does not instantiate a Byte
- }
-
- public byte nextByte() {
- if (!bytes.hasNext()) {
- bytes = pieces.next().iterator();
- }
- --bytesRemaining;
- return bytes.nextByte();
- }
-
- public void remove() {
- throw new UnsupportedOperationException();
- }
- }
-
/**
* This class is the {@link RopeByteString} equivalent for
* {@link ByteArrayInputStream}.
@@ -835,7 +759,7 @@ class RopeByteString extends ByteString {
// Iterates through the pieces of the rope
private PieceIterator pieceIterator;
// The current piece
- private LiteralByteString currentPiece;
+ private LeafByteString currentPiece;
// The size of the current piece
private int currentPieceSize;
// The index of the next byte to read in the current piece
@@ -872,7 +796,7 @@ class RopeByteString extends ByteString {
/**
* Internal implementation of read and skip. If b != null, then read the
* next {@code length} bytes into the buffer {@code b} at
- * offset {@code offset}. If b == null, then skip the next {@code length)
+ * offset {@code offset}. If b == null, then skip the next {@code length}
* bytes.
* <p>
* This method assumes that all error checking has already happened.
diff --git a/java/src/main/java/com/google/protobuf/RpcCallback.java b/java/core/src/main/java/com/google/protobuf/RpcCallback.java
index 10752968..10752968 100644
--- a/java/src/main/java/com/google/protobuf/RpcCallback.java
+++ b/java/core/src/main/java/com/google/protobuf/RpcCallback.java
diff --git a/java/src/main/java/com/google/protobuf/RpcChannel.java b/java/core/src/main/java/com/google/protobuf/RpcChannel.java
index f272f4ad..f272f4ad 100644
--- a/java/src/main/java/com/google/protobuf/RpcChannel.java
+++ b/java/core/src/main/java/com/google/protobuf/RpcChannel.java
diff --git a/java/src/main/java/com/google/protobuf/RpcController.java b/java/core/src/main/java/com/google/protobuf/RpcController.java
index a92dd7be..a92dd7be 100644
--- a/java/src/main/java/com/google/protobuf/RpcController.java
+++ b/java/core/src/main/java/com/google/protobuf/RpcController.java
diff --git a/java/src/main/java/com/google/protobuf/RpcUtil.java b/java/core/src/main/java/com/google/protobuf/RpcUtil.java
index 694b8d13..f7d555ae 100644
--- a/java/src/main/java/com/google/protobuf/RpcUtil.java
+++ b/java/core/src/main/java/com/google/protobuf/RpcUtil.java
@@ -71,6 +71,7 @@ public final class RpcUtil {
final Class<Type> originalClass,
final Type defaultInstance) {
return new RpcCallback<Message>() {
+ @Override
public void run(final Message parameter) {
Type typedParameter;
try {
@@ -107,8 +108,9 @@ public final class RpcUtil {
return new RpcCallback<ParameterType>() {
private boolean alreadyCalled = false;
+ @Override
public void run(final ParameterType parameter) {
- synchronized(this) {
+ synchronized (this) {
if (alreadyCalled) {
throw new AlreadyCalledException();
}
diff --git a/java/src/main/java/com/google/protobuf/Service.java b/java/core/src/main/java/com/google/protobuf/Service.java
index ba7b033e..ba7b033e 100644
--- a/java/src/main/java/com/google/protobuf/Service.java
+++ b/java/core/src/main/java/com/google/protobuf/Service.java
diff --git a/java/src/main/java/com/google/protobuf/ServiceException.java b/java/core/src/main/java/com/google/protobuf/ServiceException.java
index 00d57075..00d57075 100644
--- a/java/src/main/java/com/google/protobuf/ServiceException.java
+++ b/java/core/src/main/java/com/google/protobuf/ServiceException.java
diff --git a/java/src/main/java/com/google/protobuf/SingleFieldBuilder.java b/java/core/src/main/java/com/google/protobuf/SingleFieldBuilder.java
index aba65e32..941b5def 100644
--- a/java/src/main/java/com/google/protobuf/SingleFieldBuilder.java
+++ b/java/core/src/main/java/com/google/protobuf/SingleFieldBuilder.java
@@ -234,7 +234,7 @@ public class SingleFieldBuilder
}
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public void markDirty() {
onChanged();
}
diff --git a/java/core/src/main/java/com/google/protobuf/SingleFieldBuilderV3.java b/java/core/src/main/java/com/google/protobuf/SingleFieldBuilderV3.java
new file mode 100644
index 00000000..fb1f76a7
--- /dev/null
+++ b/java/core/src/main/java/com/google/protobuf/SingleFieldBuilderV3.java
@@ -0,0 +1,241 @@
+// 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.
+
+package com.google.protobuf;
+
+/**
+ * {@code SingleFieldBuilderV3} implements a structure that a protocol
+ * message uses to hold a single field of another protocol message. It supports
+ * the classical use case of setting an immutable {@link Message} as the value
+ * of the field and is highly optimized around this.
+ * <br>
+ * It also supports the additional use case of setting a {@link Message.Builder}
+ * as the field and deferring conversion of that {@code Builder}
+ * to an immutable {@code Message}. In this way, it's possible to maintain
+ * a tree of {@code Builder}'s that acts as a fully read/write data
+ * structure.
+ * <br>
+ * Logically, one can think of a tree of builders as converting the entire tree
+ * to messages when build is called on the root or when any method is called
+ * that desires a Message instead of a Builder. In terms of the implementation,
+ * the {@code SingleFieldBuilderV3} and {@code RepeatedFieldBuilderV3}
+ * classes cache messages that were created so that messages only need to be
+ * created when some change occurred in its builder or a builder for one of its
+ * descendants.
+ *
+ * @param <MType> the type of message for the field
+ * @param <BType> the type of builder for the field
+ * @param <IType> the common interface for the message and the builder
+ *
+ * @author jonp@google.com (Jon Perlow)
+ */
+public class SingleFieldBuilderV3
+ <MType extends AbstractMessage,
+ BType extends AbstractMessage.Builder,
+ IType extends MessageOrBuilder>
+ implements AbstractMessage.BuilderParent {
+
+ // Parent to send changes to.
+ private AbstractMessage.BuilderParent parent;
+
+ // Invariant: one of builder or message fields must be non-null.
+
+ // If set, this is the case where we are backed by a builder. In this case,
+ // message field represents a cached message for the builder (or null if
+ // there is no cached message).
+ private BType builder;
+
+ // If builder is non-null, this represents a cached message from the builder.
+ // If builder is null, this is the authoritative message for the field.
+ private MType message;
+
+ // Indicates that we've built a message and so we are now obligated
+ // to dispatch dirty invalidations. See AbstractMessage.BuilderListener.
+ private boolean isClean;
+
+ public SingleFieldBuilderV3(
+ MType message,
+ AbstractMessage.BuilderParent parent,
+ boolean isClean) {
+ if (message == null) {
+ throw new NullPointerException();
+ }
+ this.message = message;
+ this.parent = parent;
+ this.isClean = isClean;
+ }
+
+ public void dispose() {
+ // Null out parent so we stop sending it invalidations.
+ parent = null;
+ }
+
+ /**
+ * Get the message for the field. If the message is currently stored
+ * as a {@code Builder}, it is converted to a {@code Message} by
+ * calling {@link Message.Builder#buildPartial} on it. If no message has
+ * been set, returns the default instance of the message.
+ *
+ * @return the message for the field
+ */
+ @SuppressWarnings("unchecked")
+ public MType getMessage() {
+ if (message == null) {
+ // If message is null, the invariant is that we must be have a builder.
+ message = (MType) builder.buildPartial();
+ }
+ return message;
+ }
+
+ /**
+ * Builds the message and returns it.
+ *
+ * @return the message
+ */
+ public MType build() {
+ // Now that build has been called, we are required to dispatch
+ // invalidations.
+ isClean = true;
+ return getMessage();
+ }
+
+ /**
+ * Gets a builder for the field. If no builder has been created yet, a
+ * builder is created on demand by calling {@link Message#toBuilder}.
+ *
+ * @return The builder for the field
+ */
+ @SuppressWarnings("unchecked")
+ public BType getBuilder() {
+ if (builder == null) {
+ // builder.mergeFrom() on a fresh builder
+ // does not create any sub-objects with independent clean/dirty states,
+ // therefore setting the builder itself to clean without actually calling
+ // build() cannot break any invariants.
+ builder = (BType) message.newBuilderForType(this);
+ builder.mergeFrom(message); // no-op if message is the default message
+ builder.markClean();
+ }
+ return builder;
+ }
+
+ /**
+ * Gets the base class interface for the field. This may either be a builder
+ * or a message. It will return whatever is more efficient.
+ *
+ * @return the message or builder for the field as the base class interface
+ */
+ @SuppressWarnings("unchecked")
+ public IType getMessageOrBuilder() {
+ if (builder != null) {
+ return (IType) builder;
+ } else {
+ return (IType) message;
+ }
+ }
+
+ /**
+ * Sets a message for the field replacing any existing value.
+ *
+ * @param message the message to set
+ * @return the builder
+ */
+ public SingleFieldBuilderV3<MType, BType, IType> setMessage(
+ MType message) {
+ if (message == null) {
+ throw new NullPointerException();
+ }
+ this.message = message;
+ if (builder != null) {
+ builder.dispose();
+ builder = null;
+ }
+ onChanged();
+ return this;
+ }
+
+ /**
+ * Merges the field from another field.
+ *
+ * @param value the value to merge from
+ * @return the builder
+ */
+ public SingleFieldBuilderV3<MType, BType, IType> mergeFrom(
+ MType value) {
+ if (builder == null && message == message.getDefaultInstanceForType()) {
+ message = value;
+ } else {
+ getBuilder().mergeFrom(value);
+ }
+ onChanged();
+ return this;
+ }
+
+ /**
+ * Clears the value of the field.
+ *
+ * @return the builder
+ */
+ @SuppressWarnings("unchecked")
+ public SingleFieldBuilderV3<MType, BType, IType> clear() {
+ message = (MType) (message != null ?
+ message.getDefaultInstanceForType() :
+ builder.getDefaultInstanceForType());
+ if (builder != null) {
+ builder.dispose();
+ builder = null;
+ }
+ onChanged();
+ return this;
+ }
+
+ /**
+ * Called when a the builder or one of its nested children has changed
+ * and any parent should be notified of its invalidation.
+ */
+ private void onChanged() {
+ // If builder is null, this is the case where onChanged is being called
+ // from setMessage or clear.
+ if (builder != null) {
+ message = null;
+ }
+ if (isClean && parent != null) {
+ parent.markDirty();
+
+ // Don't keep dispatching invalidations until build is called again.
+ isClean = false;
+ }
+ }
+
+ @Override
+ public void markDirty() {
+ onChanged();
+ }
+}
diff --git a/java/src/main/java/com/google/protobuf/SmallSortedMap.java b/java/core/src/main/java/com/google/protobuf/SmallSortedMap.java
index 0674d2e2..409fec10 100644
--- a/java/src/main/java/com/google/protobuf/SmallSortedMap.java
+++ b/java/core/src/main/java/com/google/protobuf/SmallSortedMap.java
@@ -35,12 +35,12 @@ import java.util.AbstractSet;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
-import java.util.TreeMap;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.SortedMap;
+import java.util.TreeMap;
/**
* A custom map implementation from FieldDescriptor to Object optimized to
@@ -411,22 +411,22 @@ class SmallSortedMap<K extends Comparable<K>, V> extends AbstractMap<K, V> {
this.value = value;
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public K getKey() {
return key;
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public V getValue() {
return value;
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public int compareTo(Entry other) {
return getKey().compareTo(other.getKey());
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public V setValue(V newValue) {
checkMutable();
final V oldValue = this.value;
@@ -535,13 +535,13 @@ class SmallSortedMap<K extends Comparable<K>, V> extends AbstractMap<K, V> {
private boolean nextCalledBeforeRemove;
private Iterator<Map.Entry<K, V>> lazyOverflowIterator;
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public boolean hasNext() {
return (pos + 1) < entryList.size() ||
getOverflowIterator().hasNext();
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public Map.Entry<K, V> next() {
nextCalledBeforeRemove = true;
// Always increment pos so that we know whether the last returned value
@@ -552,7 +552,7 @@ class SmallSortedMap<K extends Comparable<K>, V> extends AbstractMap<K, V> {
return getOverflowIterator().next();
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public void remove() {
if (!nextCalledBeforeRemove) {
throw new IllegalStateException("remove() was called before next()");
@@ -588,31 +588,83 @@ class SmallSortedMap<K extends Comparable<K>, V> extends AbstractMap<K, V> {
*/
private static class EmptySet {
- private static final Iterator<Object> ITERATOR = new Iterator<Object>() {
- //@Override (Java 1.6 override semantics, but we must support 1.5)
- public boolean hasNext() {
- return false;
- }
- //@Override (Java 1.6 override semantics, but we must support 1.5)
- public Object next() {
- throw new NoSuchElementException();
- }
- //@Override (Java 1.6 override semantics, but we must support 1.5)
- public void remove() {
- throw new UnsupportedOperationException();
- }
- };
+ private static final Iterator<Object> ITERATOR =
+ new Iterator<Object>() {
+ @Override
+ public boolean hasNext() {
+ return false;
+ }
+ @Override
+ public Object next() {
+ throw new NoSuchElementException();
+ }
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
- private static final Iterable<Object> ITERABLE = new Iterable<Object>() {
- //@Override (Java 1.6 override semantics, but we must support 1.5)
- public Iterator<Object> iterator() {
- return ITERATOR;
- }
- };
+ private static final Iterable<Object> ITERABLE =
+ new Iterable<Object>() {
+ @Override
+ public Iterator<Object> iterator() {
+ return ITERATOR;
+ }
+ };
@SuppressWarnings("unchecked")
static <T> Iterable<T> iterable() {
return (Iterable<T>) ITERABLE;
}
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+
+ if (!(o instanceof SmallSortedMap)) {
+ return super.equals(o);
+ }
+
+ SmallSortedMap<?, ?> other = (SmallSortedMap<?, ?>) o;
+ final int size = size();
+ if (size != other.size()) {
+ return false;
+ }
+
+ // Best effort try to avoid allocating an entry set.
+ final int numArrayEntries = getNumArrayEntries();
+ if (numArrayEntries != other.getNumArrayEntries()) {
+ return entrySet().equals(other.entrySet());
+ }
+
+ for (int i = 0; i < numArrayEntries; i++) {
+ if (!getArrayEntryAt(i).equals(other.getArrayEntryAt(i))) {
+ return false;
+ }
+ }
+
+ if (numArrayEntries != size) {
+ return overflowEntries.equals(other.overflowEntries);
+ }
+
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int h = 0;
+ final int listSize = getNumArrayEntries();
+ for (int i = 0; i < listSize; i++) {
+ h += entryList.get(i).hashCode();
+ }
+ // Avoid the iterator allocation if possible.
+ if (getNumOverflowEntries() > 0) {
+ h += overflowEntries.hashCode();
+ }
+ return h;
+ }
}
diff --git a/java/src/main/java/com/google/protobuf/TextFormat.java b/java/core/src/main/java/com/google/protobuf/TextFormat.java
index 44d036c1..ff13675d 100644
--- a/java/src/main/java/com/google/protobuf/TextFormat.java
+++ b/java/core/src/main/java/com/google/protobuf/TextFormat.java
@@ -425,7 +425,7 @@ public final class TextFormat {
case STRING:
generator.print("\"");
generator.print(escapeNonAscii
- ? escapeText((String) value)
+ ? TextFormatEscaper.escapeText((String) value)
: escapeDoubleQuotesAndBackslashes((String) value)
.replace("\n", "\\n"));
generator.print("\"");
@@ -661,6 +661,22 @@ public final class TextFormat {
nextToken();
}
+ int getPreviousLine() {
+ return previousLine;
+ }
+
+ int getPreviousColumn() {
+ return previousColumn;
+ }
+
+ int getLine() {
+ return line;
+ }
+
+ int getColumn() {
+ return column;
+ }
+
/** Are we at the end of the input? */
public boolean atEnd() {
return currentToken.length() == 0;
@@ -957,11 +973,13 @@ public final class TextFormat {
*/
public boolean consumeBoolean() throws ParseException {
if (currentToken.equals("true")
+ || currentToken.equals("True")
|| currentToken.equals("t")
|| currentToken.equals("1")) {
nextToken();
return true;
} else if (currentToken.equals("false")
+ || currentToken.equals("False")
|| currentToken.equals("f")
|| currentToken.equals("0")) {
nextToken();
@@ -1074,6 +1092,18 @@ public final class TextFormat {
private ParseException floatParseException(final NumberFormatException e) {
return parseException("Couldn't parse number: " + e.getMessage());
}
+
+ /**
+ * Returns a {@link UnknownFieldParseException} with the line and column
+ * numbers of the previous token in the description, and the unknown field
+ * name, suitable for throwing.
+ */
+ public UnknownFieldParseException unknownFieldParseExceptionPreviousToken(
+ final String unknownField, final String description) {
+ // Note: People generally prefer one-based line and column numbers.
+ return new UnknownFieldParseException(
+ previousLine + 1, previousColumn + 1, unknownField, description);
+ }
}
/** Thrown when parsing an invalid text format message. */
@@ -1122,6 +1152,45 @@ public final class TextFormat {
}
}
+ /**
+ * Thrown when encountering an unknown field while parsing
+ * a text format message.
+ */
+ public static class UnknownFieldParseException extends ParseException {
+ private final String unknownField;
+
+ /**
+ * Create a new instance, with -1 as the line and column numbers, and an
+ * empty unknown field name.
+ */
+ public UnknownFieldParseException(final String message) {
+ this(-1, -1, "", message);
+ }
+
+ /**
+ * Create a new instance
+ *
+ * @param line the line number where the parse error occurred,
+ * using 1-offset.
+ * @param column the column number where the parser error occurred,
+ * using 1-offset.
+ * @param unknownField the name of the unknown field found while parsing.
+ */
+ public UnknownFieldParseException(final int line, final int column,
+ final String unknownField, final String message) {
+ super(line, column, message);
+ this.unknownField = unknownField;
+ }
+
+ /**
+ * Return the name of the unknown field encountered while parsing the
+ * protocol buffer string.
+ */
+ public String getUnknownField() {
+ return unknownField;
+ }
+ }
+
private static final Parser PARSER = Parser.newBuilder().build();
/**
@@ -1206,11 +1275,14 @@ public final class TextFormat {
private final boolean allowUnknownFields;
private final SingularOverwritePolicy singularOverwritePolicy;
+ private TextFormatParseInfoTree.Builder parseInfoTreeBuilder;
- private Parser(boolean allowUnknownFields,
- SingularOverwritePolicy singularOverwritePolicy) {
+ private Parser(
+ boolean allowUnknownFields, SingularOverwritePolicy singularOverwritePolicy,
+ TextFormatParseInfoTree.Builder parseInfoTreeBuilder) {
this.allowUnknownFields = allowUnknownFields;
this.singularOverwritePolicy = singularOverwritePolicy;
+ this.parseInfoTreeBuilder = parseInfoTreeBuilder;
}
/**
@@ -1227,6 +1299,7 @@ public final class TextFormat {
private boolean allowUnknownFields = false;
private SingularOverwritePolicy singularOverwritePolicy =
SingularOverwritePolicy.ALLOW_SINGULAR_OVERWRITES;
+ private TextFormatParseInfoTree.Builder parseInfoTreeBuilder = null;
/**
@@ -1237,8 +1310,15 @@ public final class TextFormat {
return this;
}
+ public Builder setParseInfoTreeBuilder(
+ TextFormatParseInfoTree.Builder parseInfoTreeBuilder) {
+ this.parseInfoTreeBuilder = parseInfoTreeBuilder;
+ return this;
+ }
+
public Parser build() {
- return new Parser(allowUnknownFields, singularOverwritePolicy);
+ return new Parser(
+ allowUnknownFields, singularOverwritePolicy, parseInfoTreeBuilder);
}
}
@@ -1302,6 +1382,28 @@ public final class TextFormat {
return text;
}
+ // Check both unknown fields and unknown extensions and log warming messages
+ // or throw exceptions according to the flag.
+ private void checkUnknownFields(final List<String> unknownFields)
+ throws ParseException {
+ if (unknownFields.isEmpty()) {
+ return;
+ }
+
+ StringBuilder msg = new StringBuilder("Input contains unknown fields and/or extensions:");
+ for (String field : unknownFields) {
+ msg.append('\n').append(field);
+ }
+
+ if (allowUnknownFields) {
+ logger.warning(msg.toString());
+ } else {
+ String[] lineColumn = unknownFields.get(0).split(":");
+ throw new ParseException(Integer.valueOf(lineColumn[0]),
+ Integer.valueOf(lineColumn[1]), msg.toString());
+ }
+ }
+
/**
* Parse a text-format message from {@code input} and merge the contents
* into {@code builder}. Extensions will be recognized if they are
@@ -1315,9 +1417,13 @@ public final class TextFormat {
MessageReflection.BuilderAdapter target =
new MessageReflection.BuilderAdapter(builder);
+ List<String> unknownFields = new ArrayList<String>();
+
while (!tokenizer.atEnd()) {
- mergeField(tokenizer, extensionRegistry, target);
+ mergeField(tokenizer, extensionRegistry, target, unknownFields);
}
+
+ checkUnknownFields(unknownFields);
}
@@ -1327,9 +1433,26 @@ public final class TextFormat {
*/
private void mergeField(final Tokenizer tokenizer,
final ExtensionRegistry extensionRegistry,
- final MessageReflection.MergeTarget target)
+ final MessageReflection.MergeTarget target,
+ List<String> unknownFields)
+ throws ParseException {
+ mergeField(tokenizer, extensionRegistry, target, parseInfoTreeBuilder,
+ unknownFields);
+ }
+
+ /**
+ * Parse a single field from {@code tokenizer} and merge it into
+ * {@code builder}.
+ */
+ private void mergeField(final Tokenizer tokenizer,
+ final ExtensionRegistry extensionRegistry,
+ final MessageReflection.MergeTarget target,
+ TextFormatParseInfoTree.Builder parseTreeBuilder,
+ List<String> unknownFields)
throws ParseException {
FieldDescriptor field = null;
+ int startLine = tokenizer.getLine();
+ int startColumn = tokenizer.getColumn();
final Descriptor type = target.getDescriptorForType();
ExtensionRegistry.ExtensionInfo extension = null;
@@ -1346,13 +1469,9 @@ public final class TextFormat {
extensionRegistry, name.toString());
if (extension == null) {
- if (!allowUnknownFields) {
- throw tokenizer.parseExceptionPreviousToken(
- "Extension \"" + name + "\" not found in the ExtensionRegistry.");
- } else {
- logger.warning(
- "Extension \"" + name + "\" not found in the ExtensionRegistry.");
- }
+ unknownFields.add((tokenizer.getPreviousLine() + 1) + ":" +
+ (tokenizer.getPreviousColumn() + 1) + ":\t" +
+ type.getFullName() + ".[" + name + "]");
} else {
if (extension.descriptor.getContainingType() != type) {
throw tokenizer.parseExceptionPreviousToken(
@@ -1387,15 +1506,9 @@ public final class TextFormat {
}
if (field == null) {
- if (!allowUnknownFields) {
- throw tokenizer.parseExceptionPreviousToken(
- "Message type \"" + type.getFullName()
- + "\" has no field named \"" + name + "\".");
- } else {
- logger.warning(
- "Message type \"" + type.getFullName()
- + "\" has no field named \"" + name + "\".");
- }
+ unknownFields.add((tokenizer.getPreviousLine() + 1) + ":" +
+ (tokenizer.getPreviousColumn() + 1) + ":\t" +
+ type.getFullName() + "." + name);
}
}
@@ -1420,14 +1533,52 @@ public final class TextFormat {
// Handle potential ':'.
if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
tokenizer.tryConsume(":"); // optional
+ if (parseTreeBuilder != null) {
+ TextFormatParseInfoTree.Builder childParseTreeBuilder =
+ parseTreeBuilder.getBuilderForSubMessageField(field);
+ consumeFieldValues(tokenizer, extensionRegistry, target, field, extension,
+ childParseTreeBuilder, unknownFields);
+ } else {
+ consumeFieldValues(tokenizer, extensionRegistry, target, field, extension,
+ parseTreeBuilder, unknownFields);
+ }
} else {
tokenizer.consume(":"); // required
+ consumeFieldValues(tokenizer, extensionRegistry, target, field,
+ extension, parseTreeBuilder, unknownFields);
}
+
+ if (parseTreeBuilder != null) {
+ parseTreeBuilder.setLocation(
+ field, TextFormatParseLocation.create(startLine, startColumn));
+ }
+
+ // For historical reasons, fields may optionally be separated by commas or
+ // semicolons.
+ if (!tokenizer.tryConsume(";")) {
+ tokenizer.tryConsume(",");
+ }
+ }
+
+ /**
+ * Parse a one or more field values from {@code tokenizer} and merge it into
+ * {@code builder}.
+ */
+ private void consumeFieldValues(
+ final Tokenizer tokenizer,
+ final ExtensionRegistry extensionRegistry,
+ final MessageReflection.MergeTarget target,
+ final FieldDescriptor field,
+ final ExtensionRegistry.ExtensionInfo extension,
+ final TextFormatParseInfoTree.Builder parseTreeBuilder,
+ List<String> unknownFields)
+ throws ParseException {
// Support specifying repeated field values as a comma-separated list.
// Ex."foo: [1, 2, 3]"
if (field.isRepeated() && tokenizer.tryConsume("[")) {
while (true) {
- consumeFieldValue(tokenizer, extensionRegistry, target, field, extension);
+ consumeFieldValue(tokenizer, extensionRegistry, target, field, extension,
+ parseTreeBuilder, unknownFields);
if (tokenizer.tryConsume("]")) {
// End of list.
break;
@@ -1435,13 +1586,8 @@ public final class TextFormat {
tokenizer.consume(",");
}
} else {
- consumeFieldValue(tokenizer, extensionRegistry, target, field, extension);
- }
-
- // For historical reasons, fields may optionally be separated by commas or
- // semicolons.
- if (!tokenizer.tryConsume(";")) {
- tokenizer.tryConsume(",");
+ consumeFieldValue(tokenizer, extensionRegistry, target, field,
+ extension, parseTreeBuilder, unknownFields);
}
}
@@ -1454,7 +1600,9 @@ public final class TextFormat {
final ExtensionRegistry extensionRegistry,
final MessageReflection.MergeTarget target,
final FieldDescriptor field,
- final ExtensionRegistry.ExtensionInfo extension)
+ final ExtensionRegistry.ExtensionInfo extension,
+ final TextFormatParseInfoTree.Builder parseTreeBuilder,
+ List<String> unknownFields)
throws ParseException {
Object value = null;
@@ -1476,7 +1624,8 @@ public final class TextFormat {
throw tokenizer.parseException(
"Expected \"" + endToken + "\".");
}
- mergeField(tokenizer, extensionRegistry, subField);
+ mergeField(tokenizer, extensionRegistry, subField, parseTreeBuilder,
+ unknownFields);
}
value = subField.finish();
@@ -1652,52 +1801,6 @@ public final class TextFormat {
// Some of these methods are package-private because Descriptors.java uses
// them.
- private interface ByteSequence {
- int size();
- byte byteAt(int offset);
- }
-
- /**
- * Escapes bytes in the format used in protocol buffer text format, which
- * is the same as the format used for C string literals. All bytes
- * that are not printable 7-bit ASCII characters are escaped, as well as
- * backslash, single-quote, and double-quote characters. Characters for
- * which no defined short-hand escape sequence is defined will be escaped
- * using 3-digit octal sequences.
- */
- public static String escapeBytes(final ByteSequence input) {
- final StringBuilder builder = new StringBuilder(input.size());
- for (int i = 0; i < input.size(); i++) {
- final byte b = input.byteAt(i);
- switch (b) {
- // Java does not recognize \a or \v, apparently.
- case 0x07: builder.append("\\a"); break;
- case '\b': builder.append("\\b"); break;
- case '\f': builder.append("\\f"); break;
- case '\n': builder.append("\\n"); break;
- case '\r': builder.append("\\r"); break;
- case '\t': builder.append("\\t"); break;
- case 0x0b: builder.append("\\v"); break;
- case '\\': builder.append("\\\\"); break;
- case '\'': builder.append("\\\'"); break;
- case '"' : builder.append("\\\""); break;
- default:
- // Only ASCII characters between 0x20 (space) and 0x7e (tilde) are
- // printable. Other byte values must be escaped.
- if (b >= 0x20 && b <= 0x7e) {
- builder.append((char) b);
- } else {
- builder.append('\\');
- builder.append((char) ('0' + ((b >>> 6) & 3)));
- builder.append((char) ('0' + ((b >>> 3) & 7)));
- builder.append((char) ('0' + (b & 7)));
- }
- break;
- }
- }
- return builder.toString();
- }
-
/**
* Escapes bytes in the format used in protocol buffer text format, which
* is the same as the format used for C string literals. All bytes
@@ -1706,33 +1809,15 @@ public final class TextFormat {
* which no defined short-hand escape sequence is defined will be escaped
* using 3-digit octal sequences.
*/
- public static String escapeBytes(final ByteString input) {
- return escapeBytes(new ByteSequence() {
- @Override
- public int size() {
- return input.size();
- }
- @Override
- public byte byteAt(int offset) {
- return input.byteAt(offset);
- }
- });
+ public static String escapeBytes(ByteString input) {
+ return TextFormatEscaper.escapeBytes(input);
}
/**
* Like {@link #escapeBytes(ByteString)}, but used for byte array.
*/
- public static String escapeBytes(final byte[] input) {
- return escapeBytes(new ByteSequence() {
- @Override
- public int size() {
- return input.length;
- }
- @Override
- public byte byteAt(int offset) {
- return input[offset];
- }
- });
+ public static String escapeBytes(byte[] input) {
+ return TextFormatEscaper.escapeBytes(input);
}
/**
@@ -1816,7 +1901,9 @@ public final class TextFormat {
}
}
- return ByteString.copyFrom(result, 0, pos);
+ return result.length == pos
+ ? ByteString.wrap(result) // This reference has not been out of our control.
+ : ByteString.copyFrom(result, 0, pos);
}
/**
@@ -1844,7 +1931,7 @@ public final class TextFormat {
* Escape double quotes and backslashes in a String for unicode output of a message.
*/
public static String escapeDoubleQuotesAndBackslashes(final String input) {
- return input.replace("\\", "\\\\").replace("\"", "\\\"");
+ return TextFormatEscaper.escapeDoubleQuotesAndBackslashes(input);
}
/**
diff --git a/java/core/src/main/java/com/google/protobuf/TextFormatEscaper.java b/java/core/src/main/java/com/google/protobuf/TextFormatEscaper.java
new file mode 100644
index 00000000..da9ceadd
--- /dev/null
+++ b/java/core/src/main/java/com/google/protobuf/TextFormatEscaper.java
@@ -0,0 +1,137 @@
+// 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.
+
+package com.google.protobuf;
+
+/**
+ * Provide text format escaping support for proto2 instances.
+ */
+final class TextFormatEscaper {
+ private TextFormatEscaper() {}
+
+ private interface ByteSequence {
+ int size();
+ byte byteAt(int offset);
+ }
+
+ /**
+ * Escapes bytes in the format used in protocol buffer text format, which
+ * is the same as the format used for C string literals. All bytes
+ * that are not printable 7-bit ASCII characters are escaped, as well as
+ * backslash, single-quote, and double-quote characters. Characters for
+ * which no defined short-hand escape sequence is defined will be escaped
+ * using 3-digit octal sequences.
+ */
+ static String escapeBytes(final ByteSequence input) {
+ final StringBuilder builder = new StringBuilder(input.size());
+ for (int i = 0; i < input.size(); i++) {
+ final byte b = input.byteAt(i);
+ switch (b) {
+ // Java does not recognize \a or \v, apparently.
+ case 0x07: builder.append("\\a"); break;
+ case '\b': builder.append("\\b"); break;
+ case '\f': builder.append("\\f"); break;
+ case '\n': builder.append("\\n"); break;
+ case '\r': builder.append("\\r"); break;
+ case '\t': builder.append("\\t"); break;
+ case 0x0b: builder.append("\\v"); break;
+ case '\\': builder.append("\\\\"); break;
+ case '\'': builder.append("\\\'"); break;
+ case '"' : builder.append("\\\""); break;
+ default:
+ // Only ASCII characters between 0x20 (space) and 0x7e (tilde) are
+ // printable. Other byte values must be escaped.
+ if (b >= 0x20 && b <= 0x7e) {
+ builder.append((char) b);
+ } else {
+ builder.append('\\');
+ builder.append((char) ('0' + ((b >>> 6) & 3)));
+ builder.append((char) ('0' + ((b >>> 3) & 7)));
+ builder.append((char) ('0' + (b & 7)));
+ }
+ break;
+ }
+ }
+ return builder.toString();
+ }
+
+ /**
+ * Escapes bytes in the format used in protocol buffer text format, which
+ * is the same as the format used for C string literals. All bytes
+ * that are not printable 7-bit ASCII characters are escaped, as well as
+ * backslash, single-quote, and double-quote characters. Characters for
+ * which no defined short-hand escape sequence is defined will be escaped
+ * using 3-digit octal sequences.
+ */
+ static String escapeBytes(final ByteString input) {
+ return escapeBytes(new ByteSequence() {
+ @Override
+ public int size() {
+ return input.size();
+ }
+ @Override
+ public byte byteAt(int offset) {
+ return input.byteAt(offset);
+ }
+ });
+ }
+
+ /**
+ * Like {@link #escapeBytes(ByteString)}, but used for byte array.
+ */
+ static String escapeBytes(final byte[] input) {
+ return escapeBytes(new ByteSequence() {
+ @Override
+ public int size() {
+ return input.length;
+ }
+ @Override
+ public byte byteAt(int offset) {
+ return input[offset];
+ }
+ });
+ }
+
+ /**
+ * Like {@link #escapeBytes(ByteString)}, but escapes a text string.
+ * Non-ASCII characters are first encoded as UTF-8, then each byte is escaped
+ * individually as a 3-digit octal escape. Yes, it's weird.
+ */
+ static String escapeText(final String input) {
+ return escapeBytes(ByteString.copyFromUtf8(input));
+ }
+
+ /**
+ * Escape double quotes and backslashes in a String for unicode output of a message.
+ */
+ static String escapeDoubleQuotesAndBackslashes(final String input) {
+ return input.replace("\\", "\\\\").replace("\"", "\\\"");
+ }
+}
diff --git a/java/core/src/main/java/com/google/protobuf/TextFormatParseInfoTree.java b/java/core/src/main/java/com/google/protobuf/TextFormatParseInfoTree.java
new file mode 100644
index 00000000..5c43b2c3
--- /dev/null
+++ b/java/core/src/main/java/com/google/protobuf/TextFormatParseInfoTree.java
@@ -0,0 +1,225 @@
+// 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.
+
+package com.google.protobuf;
+
+import com.google.protobuf.Descriptors.FieldDescriptor;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+
+/**
+ * Data structure which is populated with the locations of each field value parsed from the text.
+ *
+ * <p>The locations of primary fields values are retrieved by {@code getLocation} or
+ * {@code getLocations}. The locations of sub message values are within nested
+ * {@code TextFormatParseInfoTree}s and are retrieve by {@code getNestedTree} or {@code getNestedTrees}.
+ *
+ * <p>The {@code TextFormatParseInfoTree} is created by a Builder.
+ */
+public class TextFormatParseInfoTree {
+
+ // Defines a mapping between each field's descriptor to the list of locations where
+ // its value(s) were was encountered.
+ private Map<FieldDescriptor, List<TextFormatParseLocation>> locationsFromField;
+
+ // Defines a mapping between a field's descriptor to a list of TextFormatParseInfoTrees for
+ // sub message location information.
+ Map<FieldDescriptor, List<TextFormatParseInfoTree>> subtreesFromField;
+
+ /**
+ * Construct a {@code TextFormatParseInfoTree}.
+ *
+ * @param locationsFromField a map of fields to location in the source code
+ * @param subtreeBuildersFromField a map of fields to parse tree location information builders
+ */
+ private TextFormatParseInfoTree(
+ Map<FieldDescriptor, List<TextFormatParseLocation>> locationsFromField,
+ Map<FieldDescriptor, List<TextFormatParseInfoTree.Builder>> subtreeBuildersFromField) {
+
+ // The maps are unmodifiable. The values in the maps are unmodifiable.
+ Map<FieldDescriptor, List<TextFormatParseLocation>> locs =
+ new HashMap<FieldDescriptor, List<TextFormatParseLocation>>();
+ for (Entry<FieldDescriptor, List<TextFormatParseLocation>> kv : locationsFromField.entrySet()) {
+ locs.put(kv.getKey(), Collections.unmodifiableList(kv.getValue()));
+ }
+ this.locationsFromField = Collections.unmodifiableMap(locs);
+
+ Map<FieldDescriptor, List<TextFormatParseInfoTree>> subs =
+ new HashMap<FieldDescriptor, List<TextFormatParseInfoTree>>();
+ for (Entry<FieldDescriptor, List<Builder>> kv : subtreeBuildersFromField.entrySet()) {
+ List<TextFormatParseInfoTree> submessagesOfField = new ArrayList<TextFormatParseInfoTree>();
+ for (Builder subBuilder : kv.getValue()) {
+ submessagesOfField.add(subBuilder.build());
+ }
+ subs.put(kv.getKey(), Collections.unmodifiableList(submessagesOfField));
+ }
+ this.subtreesFromField = Collections.unmodifiableMap(subs);
+ }
+
+ /**
+ * Retrieve all the locations of a field.
+ *
+ * @param fieldDescriptor the the @{link FieldDescriptor} of the desired field
+ * @return a list of the locations of values of the field. If there are not values
+ * or the field doesn't exist, an empty list is returned.
+ */
+ public List<TextFormatParseLocation> getLocations(final FieldDescriptor fieldDescriptor) {
+ List<TextFormatParseLocation> result = locationsFromField.get(fieldDescriptor);
+ return (result == null) ? Collections.<TextFormatParseLocation>emptyList() : result;
+ }
+
+ /**
+ * Get the location in the source of a field's value.
+ *
+ * <p>Returns the {@link TextFormatParseLocation} for index-th value of the field in the parsed
+ * text.
+ *
+ * @param fieldDescriptor the @{link FieldDescriptor} of the desired field
+ * @param index the index of the value.
+ * @return the {@link TextFormatParseLocation} of the value
+ * @throws IllegalArgumentException index is out of range
+ */
+ public TextFormatParseLocation getLocation(final FieldDescriptor fieldDescriptor, int index) {
+ return getFromList(getLocations(fieldDescriptor), index, fieldDescriptor);
+ }
+
+ /**
+ * Retrieve a list of all the location information trees for a sub message field.
+ *
+ * @param fieldDescriptor the @{link FieldDescriptor} of the desired field
+ * @return A list of {@link TextFormatParseInfoTree}
+ */
+ public List<TextFormatParseInfoTree> getNestedTrees(final FieldDescriptor fieldDescriptor) {
+ List<TextFormatParseInfoTree> result = subtreesFromField.get(fieldDescriptor);
+ return result == null ? Collections.<TextFormatParseInfoTree>emptyList() : result;
+ }
+
+ /**
+ * Returns the parse info tree for the given field, which must be a message type.
+ *
+ * @param fieldDescriptor the @{link FieldDescriptor} of the desired sub message
+ * @param index the index of message value.
+ * @return the {@code ParseInfoTree} of the message value. {@code null} is returned if the field
+ * doesn't exist or the index is out of range.
+ * @throws IllegalArgumentException if index is out of range
+ */
+ public TextFormatParseInfoTree getNestedTree(final FieldDescriptor fieldDescriptor, int index) {
+ return getFromList(getNestedTrees(fieldDescriptor), index, fieldDescriptor);
+ }
+
+ /**
+ * Create a builder for a {@code ParseInfoTree}.
+ *
+ * @return the builder
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ private static <T> T getFromList(List<T> list, int index, FieldDescriptor fieldDescriptor) {
+ if (index >= list.size() || index < 0) {
+ throw new IllegalArgumentException(String.format("Illegal index field: %s, index %d",
+ fieldDescriptor == null ? "<null>" : fieldDescriptor.getName(), index));
+ }
+ return list.get(index);
+ }
+
+ /**
+ * Builder for a {@link TextFormatParseInfoTree}.
+ */
+ public static class Builder {
+
+ private Map<FieldDescriptor, List<TextFormatParseLocation>> locationsFromField;
+
+ // Defines a mapping between a field's descriptor to a list of ParseInfoTrees builders for
+ // sub message location information.
+ private Map<FieldDescriptor, List<Builder>> subtreeBuildersFromField;
+
+ /**
+ * Create a root level {@ParseInfoTree} builder.
+ */
+ private Builder() {
+ locationsFromField = new HashMap<FieldDescriptor, List<TextFormatParseLocation>>();
+ subtreeBuildersFromField = new HashMap<FieldDescriptor, List<Builder>>();
+ }
+
+ /**
+ * Record the starting location of a single value for a field.
+ *
+ * @param fieldDescriptor the field
+ * @param location source code location information
+ */
+ public Builder setLocation(
+ final FieldDescriptor fieldDescriptor, TextFormatParseLocation location) {
+ List<TextFormatParseLocation> fieldLocations = locationsFromField.get(fieldDescriptor);
+ if (fieldLocations == null) {
+ fieldLocations = new ArrayList<TextFormatParseLocation>();
+ locationsFromField.put(fieldDescriptor, fieldLocations);
+ }
+ fieldLocations.add(location);
+ return this;
+ }
+
+ /**
+ * Set for a sub message.
+ *
+ * <p>A new builder is created for a sub message. The builder that is returned is a new builder.
+ * The return is <em>not</em> the invoked {@code builder.getBuilderForSubMessageField}.
+ *
+ * @param fieldDescriptor the field whose value is the submessage
+ * @return a new Builder for the sub message
+ */
+ public Builder getBuilderForSubMessageField(final FieldDescriptor fieldDescriptor) {
+ List<Builder> submessageBuilders = subtreeBuildersFromField.get(fieldDescriptor);
+ if (submessageBuilders == null) {
+ submessageBuilders = new ArrayList<Builder>();
+ subtreeBuildersFromField.put(fieldDescriptor, submessageBuilders);
+ }
+ Builder subtreeBuilder = new Builder();
+ submessageBuilders.add(subtreeBuilder);
+ return subtreeBuilder;
+ }
+
+ /**
+ * Build the {@code TextFormatParseInfoTree}.
+ *
+ * @return the {@code TextFormatParseInfoTree}
+ */
+ public TextFormatParseInfoTree build() {
+ return new TextFormatParseInfoTree(locationsFromField, subtreeBuildersFromField);
+ }
+ }
+}
diff --git a/java/core/src/main/java/com/google/protobuf/TextFormatParseLocation.java b/java/core/src/main/java/com/google/protobuf/TextFormatParseLocation.java
new file mode 100644
index 00000000..cce286e1
--- /dev/null
+++ b/java/core/src/main/java/com/google/protobuf/TextFormatParseLocation.java
@@ -0,0 +1,104 @@
+// 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.
+
+package com.google.protobuf;
+
+import java.util.Arrays;
+
+/**
+ * A location in the source code.
+ *
+ * <p>A location is the starting line number and starting column number.
+ */
+public final class TextFormatParseLocation {
+
+ /**
+ * The empty location.
+ */
+ public static final TextFormatParseLocation EMPTY = new TextFormatParseLocation(-1, -1);
+
+ /**
+ * Create a location.
+ *
+ * @param line the starting line number
+ * @param column the starting column number
+ * @return a {@code ParseLocation}
+ */
+ static TextFormatParseLocation create(int line, int column) {
+ if (line == -1 && column == -1) {
+ return EMPTY;
+ }
+ if (line < 0 || column < 0) {
+ throw new IllegalArgumentException(
+ String.format("line and column values must be >= 0: line %d, column: %d", line, column));
+ }
+ return new TextFormatParseLocation(line, column);
+ }
+
+ private final int line;
+ private final int column;
+
+ private TextFormatParseLocation(int line, int column) {
+ this.line = line;
+ this.column = column;
+ }
+
+ public int getLine() {
+ return line;
+ }
+
+ public int getColumn() {
+ return column;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("ParseLocation{line=%d, column=%d}", line, column);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ if (!(o instanceof TextFormatParseLocation)) {
+ return false;
+ }
+ TextFormatParseLocation that = (TextFormatParseLocation) o;
+ return (this.line == that.getLine())
+ && (this.column == that.getColumn());
+ }
+
+ @Override
+ public int hashCode() {
+ int[] values = {line, column};
+ return Arrays.hashCode(values);
+ }
+}
diff --git a/java/src/main/java/com/google/protobuf/UninitializedMessageException.java b/java/core/src/main/java/com/google/protobuf/UninitializedMessageException.java
index 5714c063..5714c063 100644
--- a/java/src/main/java/com/google/protobuf/UninitializedMessageException.java
+++ b/java/core/src/main/java/com/google/protobuf/UninitializedMessageException.java
diff --git a/java/src/main/java/com/google/protobuf/UnknownFieldSet.java b/java/core/src/main/java/com/google/protobuf/UnknownFieldSet.java
index 7cd2250e..6d33d3a8 100644
--- a/java/src/main/java/com/google/protobuf/UnknownFieldSet.java
+++ b/java/core/src/main/java/com/google/protobuf/UnknownFieldSet.java
@@ -57,6 +57,7 @@ import java.util.TreeMap;
* @author kenton@google.com Kenton Varda
*/
public final class UnknownFieldSet implements MessageLite {
+
private UnknownFieldSet() {}
/** Create a new {@link Builder}. */
@@ -76,6 +77,7 @@ public final class UnknownFieldSet implements MessageLite {
public static UnknownFieldSet getDefaultInstance() {
return defaultInstance;
}
+ @Override
public UnknownFieldSet getDefaultInstanceForType() {
return defaultInstance;
}
@@ -126,9 +128,11 @@ public final class UnknownFieldSet implements MessageLite {
}
/** Serializes the set and writes it to {@code output}. */
+ @Override
public void writeTo(final CodedOutputStream output) throws IOException {
for (final Map.Entry<Integer, Field> entry : fields.entrySet()) {
- entry.getValue().writeTo(entry.getKey(), output);
+ Field field = entry.getValue();
+ field.writeTo(entry.getKey(), output);
}
}
@@ -146,6 +150,7 @@ public final class UnknownFieldSet implements MessageLite {
* Serializes the message to a {@code ByteString} and returns it. This is
* just a trivial wrapper around {@link #writeTo(CodedOutputStream)}.
*/
+ @Override
public ByteString toByteString() {
try {
final ByteString.CodedBuilder out =
@@ -163,6 +168,7 @@ public final class UnknownFieldSet implements MessageLite {
* Serializes the message to a {@code byte} array and returns it. This is
* just a trivial wrapper around {@link #writeTo(CodedOutputStream)}.
*/
+ @Override
public byte[] toByteArray() {
try {
final byte[] result = new byte[getSerializedSize()];
@@ -181,12 +187,14 @@ public final class UnknownFieldSet implements MessageLite {
* Serializes the message and writes it to {@code output}. This is just a
* trivial wrapper around {@link #writeTo(CodedOutputStream)}.
*/
+ @Override
public void writeTo(final OutputStream output) throws IOException {
final CodedOutputStream codedOutput = CodedOutputStream.newInstance(output);
writeTo(codedOutput);
codedOutput.flush();
}
+ @Override
public void writeDelimitedTo(OutputStream output) throws IOException {
final CodedOutputStream codedOutput = CodedOutputStream.newInstance(output);
codedOutput.writeRawVarint32(getSerializedSize());
@@ -195,6 +203,7 @@ public final class UnknownFieldSet implements MessageLite {
}
/** Get the number of bytes required to encode this set. */
+ @Override
public int getSerializedSize() {
int result = 0;
for (final Map.Entry<Integer, Field> entry : fields.entrySet()) {
@@ -228,6 +237,7 @@ public final class UnknownFieldSet implements MessageLite {
return result;
}
+ @Override
public boolean isInitialized() {
// UnknownFieldSets do not have required fields, so they are always
// initialized.
@@ -258,10 +268,12 @@ public final class UnknownFieldSet implements MessageLite {
return newBuilder().mergeFrom(input).build();
}
+ @Override
public Builder newBuilderForType() {
return newBuilder();
}
+ @Override
public Builder toBuilder() {
return newBuilder().mergeFrom(this);
}
@@ -329,6 +341,7 @@ public final class UnknownFieldSet implements MessageLite {
* in undefined behavior and can cause a {@code NullPointerException} to be
* thrown.
*/
+ @Override
public UnknownFieldSet build() {
getFieldBuilder(0); // Force lastField to be built.
final UnknownFieldSet result;
@@ -341,6 +354,7 @@ public final class UnknownFieldSet implements MessageLite {
return result;
}
+ @Override
public UnknownFieldSet buildPartial() {
// No required fields, so this is the same as build().
return build();
@@ -353,6 +367,7 @@ public final class UnknownFieldSet implements MessageLite {
new UnknownFieldSet(fields));
}
+ @Override
public UnknownFieldSet getDefaultInstanceForType() {
return UnknownFieldSet.getDefaultInstance();
}
@@ -364,6 +379,7 @@ public final class UnknownFieldSet implements MessageLite {
}
/** Reset the builder to an empty set. */
+ @Override
public Builder clear() {
reinitialize();
return this;
@@ -487,6 +503,7 @@ public final class UnknownFieldSet implements MessageLite {
* Parse an entire message from {@code input} and merge its fields into
* this set.
*/
+ @Override
public Builder mergeFrom(final CodedInputStream input) throws IOException {
while (true) {
final int tag = input.readTag();
@@ -536,8 +553,8 @@ public final class UnknownFieldSet implements MessageLite {
* set being built. This is just a small wrapper around
* {@link #mergeFrom(CodedInputStream)}.
*/
- public Builder mergeFrom(final ByteString data)
- throws InvalidProtocolBufferException {
+ @Override
+ public Builder mergeFrom(final ByteString data) throws InvalidProtocolBufferException {
try {
final CodedInputStream input = data.newCodedInput();
mergeFrom(input);
@@ -557,8 +574,8 @@ public final class UnknownFieldSet implements MessageLite {
* set being built. This is just a small wrapper around
* {@link #mergeFrom(CodedInputStream)}.
*/
- public Builder mergeFrom(final byte[] data)
- throws InvalidProtocolBufferException {
+ @Override
+ public Builder mergeFrom(final byte[] data) throws InvalidProtocolBufferException {
try {
final CodedInputStream input = CodedInputStream.newInstance(data);
mergeFrom(input);
@@ -578,6 +595,7 @@ public final class UnknownFieldSet implements MessageLite {
* set being built. This is just a small wrapper around
* {@link #mergeFrom(CodedInputStream)}.
*/
+ @Override
public Builder mergeFrom(final InputStream input) throws IOException {
final CodedInputStream codedInput = CodedInputStream.newInstance(input);
mergeFrom(codedInput);
@@ -585,8 +603,8 @@ public final class UnknownFieldSet implements MessageLite {
return this;
}
- public boolean mergeDelimitedFrom(InputStream input)
- throws IOException {
+ @Override
+ public boolean mergeDelimitedFrom(InputStream input) throws IOException {
final int firstByte = input.read();
if (firstByte == -1) {
return false;
@@ -597,30 +615,29 @@ public final class UnknownFieldSet implements MessageLite {
return true;
}
- public boolean mergeDelimitedFrom(
- InputStream input,
- ExtensionRegistryLite extensionRegistry) throws IOException {
+ @Override
+ public boolean mergeDelimitedFrom(InputStream input, ExtensionRegistryLite extensionRegistry)
+ throws IOException {
// UnknownFieldSet has no extensions.
return mergeDelimitedFrom(input);
}
- public Builder mergeFrom(
- CodedInputStream input,
- ExtensionRegistryLite extensionRegistry) throws IOException {
+ @Override
+ public Builder mergeFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry)
+ throws IOException {
// UnknownFieldSet has no extensions.
return mergeFrom(input);
}
- public Builder mergeFrom(
- ByteString data,
- ExtensionRegistryLite extensionRegistry)
+ @Override
+ public Builder mergeFrom(ByteString data, ExtensionRegistryLite extensionRegistry)
throws InvalidProtocolBufferException {
// UnknownFieldSet has no extensions.
return mergeFrom(data);
}
- public Builder mergeFrom(byte[] data, int off, int len)
- throws InvalidProtocolBufferException {
+ @Override
+ public Builder mergeFrom(byte[] data, int off, int len) throws InvalidProtocolBufferException {
try {
final CodedInputStream input =
CodedInputStream.newInstance(data, off, len);
@@ -636,29 +653,37 @@ public final class UnknownFieldSet implements MessageLite {
}
}
- public Builder mergeFrom(
- byte[] data,
- ExtensionRegistryLite extensionRegistry)
+ @Override
+ public Builder mergeFrom(byte[] data, ExtensionRegistryLite extensionRegistry)
throws InvalidProtocolBufferException {
// UnknownFieldSet has no extensions.
return mergeFrom(data);
}
- public Builder mergeFrom(
- byte[] data, int off, int len,
- ExtensionRegistryLite extensionRegistry)
+ @Override
+ public Builder mergeFrom(byte[] data, int off, int len, ExtensionRegistryLite extensionRegistry)
throws InvalidProtocolBufferException {
// UnknownFieldSet has no extensions.
return mergeFrom(data, off, len);
}
- public Builder mergeFrom(
- InputStream input,
- ExtensionRegistryLite extensionRegistry) throws IOException {
+ @Override
+ public Builder mergeFrom(InputStream input, ExtensionRegistryLite extensionRegistry)
+ throws IOException {
// UnknownFieldSet has no extensions.
return mergeFrom(input);
}
+ @Override
+ public Builder mergeFrom(MessageLite m) {
+ if (m instanceof UnknownFieldSet) {
+ return mergeFrom((UnknownFieldSet) m);
+ }
+ throw new IllegalArgumentException(
+ "mergeFrom(MessageLite) can only merge messages of the same type.");
+ }
+
+ @Override
public boolean isInitialized() {
// UnknownFieldSets do not have required fields, so they are always
// initialized.
@@ -987,6 +1012,7 @@ public final class UnknownFieldSet implements MessageLite {
* Parser to implement MessageLite interface.
*/
public static final class Parser extends AbstractParser<UnknownFieldSet> {
+ @Override
public UnknownFieldSet parsePartialFrom(
CodedInputStream input, ExtensionRegistryLite extensionRegistry)
throws InvalidProtocolBufferException {
@@ -1004,6 +1030,7 @@ public final class UnknownFieldSet implements MessageLite {
}
private static final Parser PARSER = new Parser();
+ @Override
public final Parser getParserForType() {
return PARSER;
}
diff --git a/java/src/main/java/com/google/protobuf/UnknownFieldSetLite.java b/java/core/src/main/java/com/google/protobuf/UnknownFieldSetLite.java
index 435ad4d4..9500f905 100644
--- a/java/src/main/java/com/google/protobuf/UnknownFieldSetLite.java
+++ b/java/core/src/main/java/com/google/protobuf/UnknownFieldSetLite.java
@@ -61,15 +61,6 @@ public final class UnknownFieldSetLite {
public static UnknownFieldSetLite getDefaultInstance() {
return DEFAULT_INSTANCE;
}
-
- /**
- * Returns an empty {@code UnknownFieldSetLite.Builder}.
- *
- * <p>For use by generated code only.
- */
- public static Builder newBuilder() {
- return new Builder();
- }
/**
* Returns a new mutable instance.
@@ -262,6 +253,21 @@ public final class UnknownFieldSetLite {
return hashCode;
}
+ /**
+ * Prints a String representation of the unknown field set.
+ *
+ * <p>For use by generated code only.
+ *
+ * @param buffer the buffer to write to
+ * @param indent the number of spaces the fields should be indented by
+ */
+ final void printWithIndent(StringBuilder buffer, int indent) {
+ for (int i = 0; i < count; i++) {
+ int fieldNumber = WireFormat.getTagFieldNumber(tags[i]);
+ MessageLiteToString.printField(buffer, indent, String.valueOf(fieldNumber), objects[i]);
+ }
+ }
+
private void storeField(int tag, Object value) {
ensureCapacity();
@@ -369,90 +375,4 @@ public final class UnknownFieldSetLite {
}
return this;
}
-
- /**
- * Builder for {@link UnknownFieldSetLite}s.
- *
- * <p>Use {@link UnknownFieldSet#newBuilder()} to construct a {@code Builder}.
- *
- * <p>For use by generated code only.
- */
- // TODO(dweis): Update the mutable API to no longer need this builder and delete.
- public static final class Builder {
-
- private UnknownFieldSetLite set;
-
- private Builder() {
- this.set = null;
- }
-
- /**
- * Ensures internal state is initialized for use.
- */
- private void ensureNotBuilt() {
- if (set == null) {
- set = new UnknownFieldSetLite();
- }
-
- set.checkMutable();
- }
-
- /**
- * Parse a single field from {@code input} and merge it into this set.
- *
- * <p>For use by generated code only.
- *
- * @param tag The field's tag number, which was already parsed.
- * @return {@code false} if the tag is an end group tag.
- */
- boolean mergeFieldFrom(final int tag, final CodedInputStream input) throws IOException {
- ensureNotBuilt();
- return set.mergeFieldFrom(tag, input);
- }
-
- /**
- * Convenience method for merging a new field containing a single varint
- * value. This is used in particular when an unknown enum value is
- * encountered.
- *
- * <p>For use by generated code only.
- */
- Builder mergeVarintField(int fieldNumber, int value) {
- ensureNotBuilt();
- set.mergeVarintField(fieldNumber, value);
- return this;
- }
-
- /**
- * Convenience method for merging a length-delimited field.
- *
- * <p>For use by generated code only.
- */
- public Builder mergeLengthDelimitedField(final int fieldNumber, final ByteString value) {
- ensureNotBuilt();
- set.mergeLengthDelimitedField(fieldNumber, value);
- return this;
- }
-
- /**
- * Build the {@link UnknownFieldSetLite} and return it.
- *
- * <p>Once {@code build()} has been called, the {@code Builder} will no
- * longer be usable. Calling any method after {@code build()} will result
- * in undefined behavior and can cause an
- * {@code UnsupportedOperationException} to be thrown.
- *
- * <p>For use by generated code only.
- */
- public UnknownFieldSetLite build() {
- if (set == null) {
- return DEFAULT_INSTANCE;
- }
-
- set.checkMutable();
- set.makeImmutable();
-
- return set;
- }
- }
}
diff --git a/java/src/main/java/com/google/protobuf/UnmodifiableLazyStringList.java b/java/core/src/main/java/com/google/protobuf/UnmodifiableLazyStringList.java
index 5257c5a2..30e87911 100644
--- a/java/src/main/java/com/google/protobuf/UnmodifiableLazyStringList.java
+++ b/java/core/src/main/java/com/google/protobuf/UnmodifiableLazyStringList.java
@@ -68,42 +68,42 @@ public class UnmodifiableLazyStringList extends AbstractList<String>
return list.size();
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public ByteString getByteString(int index) {
return list.getByteString(index);
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public void add(ByteString element) {
throw new UnsupportedOperationException();
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public void set(int index, ByteString element) {
throw new UnsupportedOperationException();
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public boolean addAllByteString(Collection<? extends ByteString> element) {
throw new UnsupportedOperationException();
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public byte[] getByteArray(int index) {
return list.getByteArray(index);
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public void add(byte[] element) {
throw new UnsupportedOperationException();
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public void set(int index, byte[] element) {
throw new UnsupportedOperationException();
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public boolean addAllByteArray(Collection<byte[]> element) {
throw new UnsupportedOperationException();
}
@@ -113,47 +113,47 @@ public class UnmodifiableLazyStringList extends AbstractList<String>
return new ListIterator<String>() {
ListIterator<String> iter = list.listIterator(index);
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public boolean hasNext() {
return iter.hasNext();
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public String next() {
return iter.next();
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public boolean hasPrevious() {
return iter.hasPrevious();
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public String previous() {
return iter.previous();
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public int nextIndex() {
return iter.nextIndex();
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public int previousIndex() {
return iter.previousIndex();
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public void remove() {
throw new UnsupportedOperationException();
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public void set(String o) {
throw new UnsupportedOperationException();
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public void add(String o) {
throw new UnsupportedOperationException();
}
@@ -165,45 +165,45 @@ public class UnmodifiableLazyStringList extends AbstractList<String>
return new Iterator<String>() {
Iterator<String> iter = list.iterator();
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public boolean hasNext() {
return iter.hasNext();
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public String next() {
return iter.next();
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public List<?> getUnderlyingElements() {
// The returned value is already unmodifiable.
return list.getUnderlyingElements();
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public void mergeFrom(LazyStringList other) {
throw new UnsupportedOperationException();
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public List<byte[]> asByteArrayList() {
return Collections.unmodifiableList(list.asByteArrayList());
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public List<ByteString> asByteStringList() {
return Collections.unmodifiableList(list.asByteStringList());
}
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public LazyStringList getUnmodifiableView() {
return this;
}
diff --git a/java/core/src/main/java/com/google/protobuf/UnsafeByteOperations.java b/java/core/src/main/java/com/google/protobuf/UnsafeByteOperations.java
new file mode 100644
index 00000000..e72a6b4d
--- /dev/null
+++ b/java/core/src/main/java/com/google/protobuf/UnsafeByteOperations.java
@@ -0,0 +1,101 @@
+// 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.
+
+package com.google.protobuf;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+/**
+ * Provides a number of unsafe byte operations to be used by advanced applications with high
+ * performance requirements. These methods are referred to as "unsafe" due to the fact that they
+ * potentially expose the backing buffer of a {@link ByteString} to the application.
+ *
+ * <p><strong>DISCLAIMER:</strong> The methods in this class should only be called if it is
+ * guaranteed that the buffer backing the {@link ByteString} will never change! Mutation of a
+ * {@link ByteString} can lead to unexpected and undesirable consequences in your application,
+ * and will likely be difficult to debug. Proceed with caution!
+ *
+ * <p>This can have a number of significant side affects that have
+ * spooky-action-at-a-distance-like behavior. In particular, if the bytes value changes out from
+ * under a Protocol Buffer:
+ * <ul>
+ * <li>serialization may throw
+ * <li>serialization may succeed but the wrong bytes may be written out
+ * <li>messages are no longer threadsafe
+ * <li>hashCode may be incorrect
+ * <ul>
+ * <li>can result in a permanent memory leak when used as a key in a long-lived HashMap
+ * <li> the semantics of many programs may be violated if this is the case
+ * </ul>
+ * </ul>
+ * Each of these issues will occur in parts of the code base that are entirely distinct from the
+ * parts of the code base modifying the buffer. In fact, both parts of the code base may be correct
+ * - it is the bridging with the unsafe operations that was in error!
+ */
+@ExperimentalApi
+public final class UnsafeByteOperations {
+ private UnsafeByteOperations() {}
+
+ /**
+ * An unsafe operation that returns a {@link ByteString} that is backed by the provided buffer.
+ *
+ * @param buffer the Java NIO buffer to be wrapped
+ * @return a {@link ByteString} backed by the provided buffer
+ */
+ public static ByteString unsafeWrap(ByteBuffer buffer) {
+ if (buffer.hasArray()) {
+ final int offset = buffer.arrayOffset();
+ return ByteString.wrap(buffer.array(), offset + buffer.position(), buffer.remaining());
+ } else {
+ return new NioByteString(buffer);
+ }
+ }
+
+ /**
+ * Writes the given {@link ByteString} to the provided {@link ByteOutput}. Calling this method may
+ * result in multiple operations on the target {@link ByteOutput}
+ * (i.e. for roped {@link ByteString}s).
+ *
+ * <p>This method exposes the internal backing buffer(s) of the {@link ByteString} to the {@link
+ * ByteOutput} in order to avoid additional copying overhead. It would be possible for a malicious
+ * {@link ByteOutput} to corrupt the {@link ByteString}. Use with caution!
+ *
+ * <p> NOTE: The {@link ByteOutput} <strong>MUST NOT</strong> modify the provided buffers. Doing
+ * so may result in corrupted data, which would be difficult to debug.
+ *
+ * @param bytes the {@link ByteString} to be written
+ * @param output the output to receive the bytes
+ * @throws IOException if an I/O error occurs
+ */
+ public static void unsafeWriteTo(ByteString bytes, ByteOutput output) throws IOException {
+ bytes.writeTo(output);
+ }
+}
diff --git a/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java b/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java
new file mode 100644
index 00000000..6a4787d1
--- /dev/null
+++ b/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java
@@ -0,0 +1,210 @@
+// 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.
+
+package com.google.protobuf;
+
+import sun.misc.Unsafe;
+
+import java.lang.reflect.Field;
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
+import java.security.AccessController;
+import java.security.PrivilegedExceptionAction;
+
+/**
+ * Utility class for working with unsafe operations.
+ */
+// TODO(nathanmittler): Add support for Android Memory/MemoryBlock
+final class UnsafeUtil {
+ private static final sun.misc.Unsafe UNSAFE = getUnsafe();
+ private static final boolean HAS_UNSAFE_BYTEBUFFER_OPERATIONS =
+ supportsUnsafeByteBufferOperations();
+ private static final boolean HAS_UNSAFE_ARRAY_OPERATIONS = supportsUnsafeArrayOperations();
+ private static final long ARRAY_BASE_OFFSET = byteArrayBaseOffset();
+ private static final long BUFFER_ADDRESS_OFFSET = fieldOffset(field(Buffer.class, "address"));
+
+ private UnsafeUtil() {
+ }
+
+ static boolean hasUnsafeArrayOperations() {
+ return HAS_UNSAFE_ARRAY_OPERATIONS;
+ }
+
+ static boolean hasUnsafeByteBufferOperations() {
+ return HAS_UNSAFE_BYTEBUFFER_OPERATIONS;
+ }
+
+ static long getArrayBaseOffset() {
+ return ARRAY_BASE_OFFSET;
+ }
+
+ static byte getByte(byte[] target, long offset) {
+ return UNSAFE.getByte(target, offset);
+ }
+
+ static void putByte(byte[] target, long offset, byte value) {
+ UNSAFE.putByte(target, offset, value);
+ }
+
+ static void copyMemory(
+ byte[] src, long srcOffset, byte[] target, long targetOffset, long length) {
+ UNSAFE.copyMemory(src, srcOffset, target, targetOffset, length);
+ }
+
+ static long getLong(byte[] target, long offset) {
+ return UNSAFE.getLong(target, offset);
+ }
+
+ static byte getByte(long address) {
+ return UNSAFE.getByte(address);
+ }
+
+ static void putByte(long address, byte value) {
+ UNSAFE.putByte(address, value);
+ }
+
+ static long getLong(long address) {
+ return UNSAFE.getLong(address);
+ }
+
+ static void copyMemory(long srcAddress, long targetAddress, long length) {
+ UNSAFE.copyMemory(srcAddress, targetAddress, length);
+ }
+
+ /**
+ * Gets the offset of the {@code address} field of the given direct {@link ByteBuffer}.
+ */
+ static long addressOffset(ByteBuffer buffer) {
+ return UNSAFE.getLong(buffer, BUFFER_ADDRESS_OFFSET);
+ }
+
+ /**
+ * Gets the {@code sun.misc.Unsafe} instance, or {@code null} if not available on this platform.
+ */
+ private static sun.misc.Unsafe getUnsafe() {
+ sun.misc.Unsafe unsafe = null;
+ try {
+ unsafe =
+ AccessController.doPrivileged(
+ new PrivilegedExceptionAction<Unsafe>() {
+ @Override
+ public sun.misc.Unsafe run() throws Exception {
+ Class<sun.misc.Unsafe> k = sun.misc.Unsafe.class;
+
+ for (Field f : k.getDeclaredFields()) {
+ f.setAccessible(true);
+ Object x = f.get(null);
+ if (k.isInstance(x)) {
+ return k.cast(x);
+ }
+ }
+ // The sun.misc.Unsafe field does not exist.
+ return null;
+ }
+ });
+ } catch (Throwable e) {
+ // Catching Throwable here due to the fact that Google AppEngine raises NoClassDefFoundError
+ // for Unsafe.
+ }
+ return unsafe;
+ }
+
+ /**
+ * Indicates whether or not unsafe array operations are supported on this platform.
+ */
+ private static boolean supportsUnsafeArrayOperations() {
+ boolean supported = false;
+ if (UNSAFE != null) {
+ try {
+ Class<?> clazz = UNSAFE.getClass();
+ clazz.getMethod("arrayBaseOffset", Class.class);
+ clazz.getMethod("getByte", Object.class, long.class);
+ clazz.getMethod("putByte", Object.class, long.class, byte.class);
+ clazz.getMethod("getLong", Object.class, long.class);
+ clazz.getMethod(
+ "copyMemory", Object.class, long.class, Object.class, long.class, long.class);
+ supported = true;
+ } catch (Throwable e) {
+ // Do nothing.
+ }
+ }
+ return supported;
+ }
+
+ private static boolean supportsUnsafeByteBufferOperations() {
+ boolean supported = false;
+ if (UNSAFE != null) {
+ try {
+ Class<?> clazz = UNSAFE.getClass();
+ clazz.getMethod("objectFieldOffset", Field.class);
+ clazz.getMethod("getByte", long.class);
+ clazz.getMethod("getLong", Object.class, long.class);
+ clazz.getMethod("putByte", long.class, byte.class);
+ clazz.getMethod("getLong", long.class);
+ clazz.getMethod("copyMemory", long.class, long.class, long.class);
+ supported = true;
+ } catch (Throwable e) {
+ // Do nothing.
+ }
+ }
+ return supported;
+ }
+
+ /**
+ * Get the base offset for byte arrays, or {@code -1} if {@code sun.misc.Unsafe} is not available.
+ */
+ private static int byteArrayBaseOffset() {
+ return HAS_UNSAFE_ARRAY_OPERATIONS ? UNSAFE.arrayBaseOffset(byte[].class) : -1;
+ }
+
+ /**
+ * Returns the offset of the provided field, or {@code -1} if {@code sun.misc.Unsafe} is not
+ * available.
+ */
+ private static long fieldOffset(Field field) {
+ return field == null || UNSAFE == null ? -1 : UNSAFE.objectFieldOffset(field);
+ }
+
+ /**
+ * Gets the field with the given name within the class, or {@code null} if not found. If found,
+ * the field is made accessible.
+ */
+ private static Field field(Class<?> clazz, String fieldName) {
+ Field field;
+ try {
+ field = clazz.getDeclaredField(fieldName);
+ field.setAccessible(true);
+ } catch (Throwable t) {
+ // Failed to access the fields.
+ field = null;
+ }
+ return field;
+ }
+}
diff --git a/java/core/src/main/java/com/google/protobuf/Utf8.java b/java/core/src/main/java/com/google/protobuf/Utf8.java
new file mode 100644
index 00000000..5b80d405
--- /dev/null
+++ b/java/core/src/main/java/com/google/protobuf/Utf8.java
@@ -0,0 +1,1573 @@
+// 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.
+
+package com.google.protobuf;
+
+import static com.google.protobuf.UnsafeUtil.addressOffset;
+import static com.google.protobuf.UnsafeUtil.getArrayBaseOffset;
+import static com.google.protobuf.UnsafeUtil.hasUnsafeArrayOperations;
+import static com.google.protobuf.UnsafeUtil.hasUnsafeByteBufferOperations;
+import static java.lang.Character.MAX_SURROGATE;
+import static java.lang.Character.MIN_SURROGATE;
+import static java.lang.Character.isSurrogatePair;
+import static java.lang.Character.toCodePoint;
+
+import java.nio.ByteBuffer;
+
+/**
+ * A set of low-level, high-performance static utility methods related
+ * to the UTF-8 character encoding. This class has no dependencies
+ * outside of the core JDK libraries.
+ *
+ * <p>There are several variants of UTF-8. The one implemented by
+ * this class is the restricted definition of UTF-8 introduced in
+ * Unicode 3.1, which mandates the rejection of "overlong" byte
+ * sequences as well as rejection of 3-byte surrogate codepoint byte
+ * sequences. Note that the UTF-8 decoder included in Oracle's JDK
+ * has been modified to also reject "overlong" byte sequences, but (as
+ * of 2011) still accepts 3-byte surrogate codepoint byte sequences.
+ *
+ * <p>The byte sequences considered valid by this class are exactly
+ * those that can be roundtrip converted to Strings and back to bytes
+ * using the UTF-8 charset, without loss: <pre> {@code
+ * Arrays.equals(bytes, new String(bytes, Internal.UTF_8).getBytes(Internal.UTF_8))
+ * }</pre>
+ *
+ * <p>See the Unicode Standard,</br>
+ * Table 3-6. <em>UTF-8 Bit Distribution</em>,</br>
+ * Table 3-7. <em>Well Formed UTF-8 Byte Sequences</em>.
+ *
+ * <p>This class supports decoding of partial byte sequences, so that the
+ * bytes in a complete UTF-8 byte sequences can be stored in multiple
+ * segments. Methods typically return {@link #MALFORMED} if the partial
+ * byte sequence is definitely not well-formed, {@link #COMPLETE} if it is
+ * well-formed in the absence of additional input, or if the byte sequence
+ * apparently terminated in the middle of a character, an opaque integer
+ * "state" value containing enough information to decode the character when
+ * passed to a subsequent invocation of a partial decoding method.
+ *
+ * @author martinrb@google.com (Martin Buchholz)
+ */
+// TODO(nathanmittler): Copy changes in this class back to Guava
+final class Utf8 {
+
+ /**
+ * UTF-8 is a runtime hot spot so we attempt to provide heavily optimized implementations
+ * depending on what is available on the platform. The processor is the platform-optimized
+ * delegate for which all methods are delegated directly to.
+ */
+ private static final Processor processor =
+ UnsafeProcessor.isAvailable() ? new UnsafeProcessor() : new SafeProcessor();
+
+ /**
+ * A mask used when performing unsafe reads to determine if a long value contains any non-ASCII
+ * characters (i.e. any byte >= 0x80).
+ */
+ private static final long ASCII_MASK_LONG = 0x8080808080808080L;
+
+ /**
+ * Maximum number of bytes per Java UTF-16 char in UTF-8.
+ * @see java.nio.charset.CharsetEncoder#maxBytesPerChar()
+ */
+ static final int MAX_BYTES_PER_CHAR = 3;
+
+ /**
+ * State value indicating that the byte sequence is well-formed and
+ * complete (no further bytes are needed to complete a character).
+ */
+ public static final int COMPLETE = 0;
+
+ /**
+ * State value indicating that the byte sequence is definitely not
+ * well-formed.
+ */
+ public static final int MALFORMED = -1;
+
+ /**
+ * Used by {@code Unsafe} UTF-8 string validation logic to determine the minimum string length
+ * above which to employ an optimized algorithm for counting ASCII characters. The reason for this
+ * threshold is that for small strings, the optimization may not be beneficial or may even
+ * negatively impact performance since it requires additional logic to avoid unaligned reads
+ * (when calling {@code Unsafe.getLong}). This threshold guarantees that even if the initial
+ * offset is unaligned, we're guaranteed to make at least one call to {@code Unsafe.getLong()}
+ * which provides a performance improvement that entirely subsumes the cost of the additional
+ * logic.
+ */
+ private static final int UNSAFE_COUNT_ASCII_THRESHOLD = 16;
+
+ // Other state values include the partial bytes of the incomplete
+ // character to be decoded in the simplest way: we pack the bytes
+ // into the state int in little-endian order. For example:
+ //
+ // int state = byte1 ^ (byte2 << 8) ^ (byte3 << 16);
+ //
+ // Such a state is unpacked thus (note the ~ operation for byte2 to
+ // undo byte1's sign-extension bits):
+ //
+ // int byte1 = (byte) state;
+ // int byte2 = (byte) ~(state >> 8);
+ // int byte3 = (byte) (state >> 16);
+ //
+ // We cannot store a zero byte in the state because it would be
+ // indistinguishable from the absence of a byte. But we don't need
+ // to, because partial bytes must always be negative. When building
+ // a state, we ensure that byte1 is negative and subsequent bytes
+ // are valid trailing bytes.
+
+ /**
+ * Returns {@code true} if the given byte array is a well-formed
+ * UTF-8 byte sequence.
+ *
+ * <p>This is a convenience method, equivalent to a call to {@code
+ * isValidUtf8(bytes, 0, bytes.length)}.
+ */
+ public static boolean isValidUtf8(byte[] bytes) {
+ return processor.isValidUtf8(bytes, 0, bytes.length);
+ }
+
+ /**
+ * Returns {@code true} if the given byte array slice is a
+ * well-formed UTF-8 byte sequence. The range of bytes to be
+ * checked extends from index {@code index}, inclusive, to {@code
+ * limit}, exclusive.
+ *
+ * <p>This is a convenience method, equivalent to {@code
+ * partialIsValidUtf8(bytes, index, limit) == Utf8.COMPLETE}.
+ */
+ public static boolean isValidUtf8(byte[] bytes, int index, int limit) {
+ return processor.isValidUtf8(bytes, index, limit);
+ }
+
+ /**
+ * Tells whether the given byte array slice is a well-formed,
+ * malformed, or incomplete UTF-8 byte sequence. The range of bytes
+ * to be checked extends from index {@code index}, inclusive, to
+ * {@code limit}, exclusive.
+ *
+ * @param state either {@link Utf8#COMPLETE} (if this is the initial decoding
+ * operation) or the value returned from a call to a partial decoding method
+ * for the previous bytes
+ *
+ * @return {@link #MALFORMED} if the partial byte sequence is
+ * definitely not well-formed, {@link #COMPLETE} if it is well-formed
+ * (no additional input needed), or if the byte sequence is
+ * "incomplete", i.e. apparently terminated in the middle of a character,
+ * an opaque integer "state" value containing enough information to
+ * decode the character when passed to a subsequent invocation of a
+ * partial decoding method.
+ */
+ public static int partialIsValidUtf8(int state, byte[] bytes, int index, int limit) {
+ return processor.partialIsValidUtf8(state, bytes, index, limit);
+ }
+
+ private static int incompleteStateFor(int byte1) {
+ return (byte1 > (byte) 0xF4) ?
+ MALFORMED : byte1;
+ }
+
+ private static int incompleteStateFor(int byte1, int byte2) {
+ return (byte1 > (byte) 0xF4 ||
+ byte2 > (byte) 0xBF) ?
+ MALFORMED : byte1 ^ (byte2 << 8);
+ }
+
+ private static int incompleteStateFor(int byte1, int byte2, int byte3) {
+ return (byte1 > (byte) 0xF4 ||
+ byte2 > (byte) 0xBF ||
+ byte3 > (byte) 0xBF) ?
+ MALFORMED : byte1 ^ (byte2 << 8) ^ (byte3 << 16);
+ }
+
+ private static int incompleteStateFor(byte[] bytes, int index, int limit) {
+ int byte1 = bytes[index - 1];
+ switch (limit - index) {
+ case 0: return incompleteStateFor(byte1);
+ case 1: return incompleteStateFor(byte1, bytes[index]);
+ case 2: return incompleteStateFor(byte1, bytes[index], bytes[index + 1]);
+ default: throw new AssertionError();
+ }
+ }
+
+ private static int incompleteStateFor(
+ final ByteBuffer buffer, final int byte1, final int index, final int remaining) {
+ switch (remaining) {
+ case 0:
+ return incompleteStateFor(byte1);
+ case 1:
+ return incompleteStateFor(byte1, buffer.get(index));
+ case 2:
+ return incompleteStateFor(byte1, buffer.get(index), buffer.get(index + 1));
+ default:
+ throw new AssertionError();
+ }
+ }
+
+ // These UTF-8 handling methods are copied from Guava's Utf8 class with a modification to throw
+ // a protocol buffer local exception. This exception is then caught in CodedOutputStream so it can
+ // fallback to more lenient behavior.
+
+ static class UnpairedSurrogateException extends IllegalArgumentException {
+ UnpairedSurrogateException(int index, int length) {
+ super("Unpaired surrogate at index " + index + " of " + length);
+ }
+ }
+
+ /**
+ * Returns the number of bytes in the UTF-8-encoded form of {@code sequence}. For a string,
+ * this method is equivalent to {@code string.getBytes(UTF_8).length}, but is more efficient in
+ * both time and space.
+ *
+ * @throws IllegalArgumentException if {@code sequence} contains ill-formed UTF-16 (unpaired
+ * surrogates)
+ */
+ static int encodedLength(CharSequence sequence) {
+ // Warning to maintainers: this implementation is highly optimized.
+ int utf16Length = sequence.length();
+ int utf8Length = utf16Length;
+ int i = 0;
+
+ // This loop optimizes for pure ASCII.
+ while (i < utf16Length && sequence.charAt(i) < 0x80) {
+ i++;
+ }
+
+ // This loop optimizes for chars less than 0x800.
+ for (; i < utf16Length; i++) {
+ char c = sequence.charAt(i);
+ if (c < 0x800) {
+ utf8Length += ((0x7f - c) >>> 31); // branch free!
+ } else {
+ utf8Length += encodedLengthGeneral(sequence, i);
+ break;
+ }
+ }
+
+ if (utf8Length < utf16Length) {
+ // Necessary and sufficient condition for overflow because of maximum 3x expansion
+ throw new IllegalArgumentException("UTF-8 length does not fit in int: "
+ + (utf8Length + (1L << 32)));
+ }
+ return utf8Length;
+ }
+
+ private static int encodedLengthGeneral(CharSequence sequence, int start) {
+ int utf16Length = sequence.length();
+ int utf8Length = 0;
+ for (int i = start; i < utf16Length; i++) {
+ char c = sequence.charAt(i);
+ if (c < 0x800) {
+ utf8Length += (0x7f - c) >>> 31; // branch free!
+ } else {
+ utf8Length += 2;
+ // jdk7+: if (Character.isSurrogate(c)) {
+ if (Character.MIN_SURROGATE <= c && c <= Character.MAX_SURROGATE) {
+ // Check that we have a well-formed surrogate pair.
+ int cp = Character.codePointAt(sequence, i);
+ if (cp < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
+ throw new UnpairedSurrogateException(i, utf16Length);
+ }
+ i++;
+ }
+ }
+ }
+ return utf8Length;
+ }
+
+ static int encode(CharSequence in, byte[] out, int offset, int length) {
+ return processor.encodeUtf8(in, out, offset, length);
+ }
+ // End Guava UTF-8 methods.
+
+ /**
+ * Determines if the given {@link ByteBuffer} is a valid UTF-8 string.
+ *
+ * <p>Selects an optimal algorithm based on the type of {@link ByteBuffer} (i.e. heap or direct)
+ * and the capabilities of the platform.
+ *
+ * @param buffer the buffer to check.
+ * @see Utf8#isValidUtf8(byte[], int, int)
+ */
+ static boolean isValidUtf8(ByteBuffer buffer) {
+ return processor.isValidUtf8(buffer, buffer.position(), buffer.remaining());
+ }
+
+ /**
+ * Determines if the given {@link ByteBuffer} is a partially valid UTF-8 string.
+ *
+ * <p>Selects an optimal algorithm based on the type of {@link ByteBuffer} (i.e. heap or direct)
+ * and the capabilities of the platform.
+ *
+ * @param buffer the buffer to check.
+ * @see Utf8#partialIsValidUtf8(int, byte[], int, int)
+ */
+ static int partialIsValidUtf8(int state, ByteBuffer buffer, int index, int limit) {
+ return processor.partialIsValidUtf8(state, buffer, index, limit);
+ }
+
+ /**
+ * Encodes the given characters to the target {@link ByteBuffer} using UTF-8 encoding.
+ *
+ * <p>Selects an optimal algorithm based on the type of {@link ByteBuffer} (i.e. heap or direct)
+ * and the capabilities of the platform.
+ *
+ * @param in the source string to be encoded
+ * @param out the target buffer to receive the encoded string.
+ * @see Utf8#encode(CharSequence, byte[], int, int)
+ */
+ static void encodeUtf8(CharSequence in, ByteBuffer out) {
+ processor.encodeUtf8(in, out);
+ }
+
+ /**
+ * Counts (approximately) the number of consecutive ASCII characters in the given buffer.
+ * The byte order of the {@link ByteBuffer} does not matter, so performance can be improved if
+ * native byte order is used (i.e. no byte-swapping in {@link ByteBuffer#getLong(int)}).
+ *
+ * @param buffer the buffer to be scanned for ASCII chars
+ * @param index the starting index of the scan
+ * @param limit the limit within buffer for the scan
+ * @return the number of ASCII characters found. The stopping position will be at or
+ * before the first non-ASCII byte.
+ */
+ private static int estimateConsecutiveAscii(ByteBuffer buffer, int index, int limit) {
+ int i = index;
+ final int lim = limit - 7;
+ // This simple loop stops when we encounter a byte >= 0x80 (i.e. non-ASCII).
+ // To speed things up further, we're reading longs instead of bytes so we use a mask to
+ // determine if any byte in the current long is non-ASCII.
+ for (; i < lim && (buffer.getLong(i) & ASCII_MASK_LONG) == 0; i += 8) {}
+ return i - index;
+ }
+
+ /**
+ * A processor of UTF-8 strings, providing methods for checking validity and encoding.
+ */
+ // TODO(nathanmittler): Add support for Memory/MemoryBlock on Android.
+ abstract static class Processor {
+ /**
+ * Returns {@code true} if the given byte array slice is a
+ * well-formed UTF-8 byte sequence. The range of bytes to be
+ * checked extends from index {@code index}, inclusive, to {@code
+ * limit}, exclusive.
+ *
+ * <p>This is a convenience method, equivalent to {@code
+ * partialIsValidUtf8(bytes, index, limit) == Utf8.COMPLETE}.
+ */
+ final boolean isValidUtf8(byte[] bytes, int index, int limit) {
+ return partialIsValidUtf8(COMPLETE, bytes, index, limit) == COMPLETE;
+ }
+
+ /**
+ * Tells whether the given byte array slice is a well-formed,
+ * malformed, or incomplete UTF-8 byte sequence. The range of bytes
+ * to be checked extends from index {@code index}, inclusive, to
+ * {@code limit}, exclusive.
+ *
+ * @param state either {@link Utf8#COMPLETE} (if this is the initial decoding
+ * operation) or the value returned from a call to a partial decoding method
+ * for the previous bytes
+ *
+ * @return {@link #MALFORMED} if the partial byte sequence is
+ * definitely not well-formed, {@link #COMPLETE} if it is well-formed
+ * (no additional input needed), or if the byte sequence is
+ * "incomplete", i.e. apparently terminated in the middle of a character,
+ * an opaque integer "state" value containing enough information to
+ * decode the character when passed to a subsequent invocation of a
+ * partial decoding method.
+ */
+ abstract int partialIsValidUtf8(int state, byte[] bytes, int index, int limit);
+
+ /**
+ * Returns {@code true} if the given portion of the {@link ByteBuffer} is a
+ * well-formed UTF-8 byte sequence. The range of bytes to be
+ * checked extends from index {@code index}, inclusive, to {@code
+ * limit}, exclusive.
+ *
+ * <p>This is a convenience method, equivalent to {@code
+ * partialIsValidUtf8(bytes, index, limit) == Utf8.COMPLETE}.
+ */
+ final boolean isValidUtf8(ByteBuffer buffer, int index, int limit) {
+ return partialIsValidUtf8(COMPLETE, buffer, index, limit) == COMPLETE;
+ }
+
+ /**
+ * Indicates whether or not the given buffer contains a valid UTF-8 string.
+ *
+ * @param buffer the buffer to check.
+ * @return {@code true} if the given buffer contains a valid UTF-8 string.
+ */
+ final int partialIsValidUtf8(
+ final int state, final ByteBuffer buffer, int index, final int limit) {
+ if (buffer.hasArray()) {
+ final int offset = buffer.arrayOffset();
+ return partialIsValidUtf8(state, buffer.array(), offset + index, offset + limit);
+ } else if (buffer.isDirect()){
+ return partialIsValidUtf8Direct(state, buffer, index, limit);
+ }
+ return partialIsValidUtf8Default(state, buffer, index, limit);
+ }
+
+ /**
+ * Performs validation for direct {@link ByteBuffer} instances.
+ */
+ abstract int partialIsValidUtf8Direct(
+ final int state, final ByteBuffer buffer, int index, final int limit);
+
+ /**
+ * Performs validation for {@link ByteBuffer} instances using the {@link ByteBuffer} API rather
+ * than potentially faster approaches. This first completes validation for the current
+ * character (provided by {@code state}) and then finishes validation for the sequence.
+ */
+ final int partialIsValidUtf8Default(
+ final int state, final ByteBuffer buffer, int index, final int limit) {
+ if (state != COMPLETE) {
+ // The previous decoding operation was incomplete (or malformed).
+ // We look for a well-formed sequence consisting of bytes from
+ // the previous decoding operation (stored in state) together
+ // with bytes from the array slice.
+ //
+ // We expect such "straddler characters" to be rare.
+
+ if (index >= limit) { // No bytes? No progress.
+ return state;
+ }
+
+ byte byte1 = (byte) state;
+ // byte1 is never ASCII.
+ if (byte1 < (byte) 0xE0) {
+ // two-byte form
+
+ // Simultaneously checks for illegal trailing-byte in
+ // leading position and overlong 2-byte form.
+ if (byte1 < (byte) 0xC2
+ // byte2 trailing-byte test
+ || buffer.get(index++) > (byte) 0xBF) {
+ return MALFORMED;
+ }
+ } else if (byte1 < (byte) 0xF0) {
+ // three-byte form
+
+ // Get byte2 from saved state or array
+ byte byte2 = (byte) ~(state >> 8);
+ if (byte2 == 0) {
+ byte2 = buffer.get(index++);
+ if (index >= limit) {
+ return incompleteStateFor(byte1, byte2);
+ }
+ }
+ if (byte2 > (byte) 0xBF
+ // overlong? 5 most significant bits must not all be zero
+ || (byte1 == (byte) 0xE0 && byte2 < (byte) 0xA0)
+ // illegal surrogate codepoint?
+ || (byte1 == (byte) 0xED && byte2 >= (byte) 0xA0)
+ // byte3 trailing-byte test
+ || buffer.get(index++) > (byte) 0xBF) {
+ return MALFORMED;
+ }
+ } else {
+ // four-byte form
+
+ // Get byte2 and byte3 from saved state or array
+ byte byte2 = (byte) ~(state >> 8);
+ byte byte3 = 0;
+ if (byte2 == 0) {
+ byte2 = buffer.get(index++);
+ if (index >= limit) {
+ return incompleteStateFor(byte1, byte2);
+ }
+ } else {
+ byte3 = (byte) (state >> 16);
+ }
+ if (byte3 == 0) {
+ byte3 = buffer.get(index++);
+ if (index >= limit) {
+ return incompleteStateFor(byte1, byte2, byte3);
+ }
+ }
+
+ // If we were called with state == MALFORMED, then byte1 is 0xFF,
+ // which never occurs in well-formed UTF-8, and so we will return
+ // MALFORMED again below.
+
+ if (byte2 > (byte) 0xBF
+ // Check that 1 <= plane <= 16. Tricky optimized form of:
+ // if (byte1 > (byte) 0xF4 ||
+ // byte1 == (byte) 0xF0 && byte2 < (byte) 0x90 ||
+ // byte1 == (byte) 0xF4 && byte2 > (byte) 0x8F)
+ || (((byte1 << 28) + (byte2 - (byte) 0x90)) >> 30) != 0
+ // byte3 trailing-byte test
+ || byte3 > (byte) 0xBF
+ // byte4 trailing-byte test
+ || buffer.get(index++) > (byte) 0xBF) {
+ return MALFORMED;
+ }
+ }
+ }
+
+ // Finish validation for the sequence.
+ return partialIsValidUtf8(buffer, index, limit);
+ }
+
+ /**
+ * Performs validation for {@link ByteBuffer} instances using the {@link ByteBuffer} API rather
+ * than potentially faster approaches.
+ */
+ private static int partialIsValidUtf8(final ByteBuffer buffer, int index, final int limit) {
+ index += estimateConsecutiveAscii(buffer, index, limit);
+
+ for (;;) {
+ // Optimize for interior runs of ASCII bytes.
+ // TODO(nathanmittler): Consider checking 8 bytes at a time after some threshold?
+ // Maybe after seeing a few in a row that are ASCII, go back to fast mode?
+ int byte1;
+ do {
+ if (index >= limit) {
+ return COMPLETE;
+ }
+ } while ((byte1 = buffer.get(index++)) >= 0);
+
+ // If we're here byte1 is not ASCII. Only need to handle 2-4 byte forms.
+ if (byte1 < (byte) 0xE0) {
+ // Two-byte form (110xxxxx 10xxxxxx)
+ if (index >= limit) {
+ // Incomplete sequence
+ return byte1;
+ }
+
+ // Simultaneously checks for illegal trailing-byte in
+ // leading position and overlong 2-byte form.
+ if (byte1 < (byte) 0xC2 || buffer.get(index) > (byte) 0xBF) {
+ return MALFORMED;
+ }
+ index++;
+ } else if (byte1 < (byte) 0xF0) {
+ // Three-byte form (1110xxxx 10xxxxxx 10xxxxxx)
+ if (index >= limit - 1) {
+ // Incomplete sequence
+ return incompleteStateFor(buffer, byte1, index, limit - index);
+ }
+
+ final byte byte2 = buffer.get(index++);
+ if (byte2 > (byte) 0xBF
+ // overlong? 5 most significant bits must not all be zero
+ || (byte1 == (byte) 0xE0 && byte2 < (byte) 0xA0)
+ // check for illegal surrogate codepoints
+ || (byte1 == (byte) 0xED && byte2 >= (byte) 0xA0)
+ // byte3 trailing-byte test
+ || buffer.get(index) > (byte) 0xBF) {
+ return MALFORMED;
+ }
+ index++;
+ } else {
+ // Four-byte form (1110xxxx 10xxxxxx 10xxxxxx 10xxxxxx)
+ if (index >= limit - 2) {
+ // Incomplete sequence
+ return incompleteStateFor(buffer, byte1, index, limit - index);
+ }
+
+ // TODO(nathanmittler): Consider using getInt() to improve performance.
+ final int byte2 = buffer.get(index++);
+ if (byte2 > (byte) 0xBF
+ // Check that 1 <= plane <= 16. Tricky optimized form of:
+ // if (byte1 > (byte) 0xF4 ||
+ // byte1 == (byte) 0xF0 && byte2 < (byte) 0x90 ||
+ // byte1 == (byte) 0xF4 && byte2 > (byte) 0x8F)
+ || (((byte1 << 28) + (byte2 - (byte) 0x90)) >> 30) != 0
+ // byte3 trailing-byte test
+ || buffer.get(index++) > (byte) 0xBF
+ // byte4 trailing-byte test
+ || buffer.get(index++) > (byte) 0xBF) {
+ return MALFORMED;
+ }
+ }
+ }
+ }
+
+ /**
+ * Encodes an input character sequence ({@code in}) to UTF-8 in the target array ({@code out}).
+ * For a string, this method is similar to
+ * <pre>{@code
+ * byte[] a = string.getBytes(UTF_8);
+ * System.arraycopy(a, 0, bytes, offset, a.length);
+ * return offset + a.length;
+ * }</pre>
+ *
+ * but is more efficient in both time and space. One key difference is that this method
+ * requires paired surrogates, and therefore does not support chunking.
+ * While {@code String.getBytes(UTF_8)} replaces unpaired surrogates with the default
+ * replacement character, this method throws {@link UnpairedSurrogateException}.
+ *
+ * <p>To ensure sufficient space in the output buffer, either call {@link #encodedLength} to
+ * compute the exact amount needed, or leave room for
+ * {@code Utf8.MAX_BYTES_PER_CHAR * sequence.length()}, which is the largest possible number
+ * of bytes that any input can be encoded to.
+ *
+ * @param in the input character sequence to be encoded
+ * @param out the target array
+ * @param offset the starting offset in {@code bytes} to start writing at
+ * @param length the length of the {@code bytes}, starting from {@code offset}
+ * @throws UnpairedSurrogateException if {@code sequence} contains ill-formed UTF-16 (unpaired
+ * surrogates)
+ * @throws ArrayIndexOutOfBoundsException if {@code sequence} encoded in UTF-8 is longer than
+ * {@code bytes.length - offset}
+ * @return the new offset, equivalent to {@code offset + Utf8.encodedLength(sequence)}
+ */
+ abstract int encodeUtf8(CharSequence in, byte[] out, int offset, int length);
+
+ /**
+ * Encodes an input character sequence ({@code in}) to UTF-8 in the target buffer ({@code out}).
+ * Upon returning from this method, the {@code out} position will point to the position after
+ * the last encoded byte. This method requires paired surrogates, and therefore does not
+ * support chunking.
+ *
+ * <p>To ensure sufficient space in the output buffer, either call {@link #encodedLength} to
+ * compute the exact amount needed, or leave room for
+ * {@code Utf8.MAX_BYTES_PER_CHAR * in.length()}, which is the largest possible number
+ * of bytes that any input can be encoded to.
+ *
+ * @param in the source character sequence to be encoded
+ * @param out the target buffer
+ * @throws UnpairedSurrogateException if {@code in} contains ill-formed UTF-16 (unpaired
+ * surrogates)
+ * @throws ArrayIndexOutOfBoundsException if {@code in} encoded in UTF-8 is longer than
+ * {@code out.remaining()}
+ */
+ final void encodeUtf8(CharSequence in, ByteBuffer out) {
+ if (out.hasArray()) {
+ final int offset = out.arrayOffset();
+ int endIndex =
+ Utf8.encode(in, out.array(), offset + out.position(), out.remaining());
+ out.position(endIndex - offset);
+ } else if (out.isDirect()) {
+ encodeUtf8Direct(in, out);
+ } else {
+ encodeUtf8Default(in, out);
+ }
+ }
+
+ /**
+ * Encodes the input character sequence to a direct {@link ByteBuffer} instance.
+ */
+ abstract void encodeUtf8Direct(CharSequence in, ByteBuffer out);
+
+ /**
+ * Encodes the input character sequence to a {@link ByteBuffer} instance using the {@link
+ * ByteBuffer} API, rather than potentially faster approaches.
+ */
+ final void encodeUtf8Default(CharSequence in, ByteBuffer out) {
+ final int inLength = in.length();
+ int outIx = out.position();
+ int inIx = 0;
+
+ // Since ByteBuffer.putXXX() already checks boundaries for us, no need to explicitly check
+ // access. Assume the buffer is big enough and let it handle the out of bounds exception
+ // if it occurs.
+ try {
+ // Designed to take advantage of
+ // https://wikis.oracle.com/display/HotSpotInternals/RangeCheckElimination
+ for (char c; inIx < inLength && (c = in.charAt(inIx)) < 0x80; ++inIx) {
+ out.put(outIx + inIx, (byte) c);
+ }
+ if (inIx == inLength) {
+ // Successfully encoded the entire string.
+ out.position(outIx + inIx);
+ return;
+ }
+
+ outIx += inIx;
+ for (char c; inIx < inLength; ++inIx, ++outIx) {
+ c = in.charAt(inIx);
+ if (c < 0x80) {
+ // One byte (0xxx xxxx)
+ out.put(outIx, (byte) c);
+ } else if (c < 0x800) {
+ // Two bytes (110x xxxx 10xx xxxx)
+
+ // Benchmarks show put performs better than putShort here (for HotSpot).
+ out.put(outIx++, (byte) (0xC0 | (c >>> 6)));
+ out.put(outIx, (byte) (0x80 | (0x3F & c)));
+ } else if (c < MIN_SURROGATE || MAX_SURROGATE < c) {
+ // Three bytes (1110 xxxx 10xx xxxx 10xx xxxx)
+ // Maximum single-char code point is 0xFFFF, 16 bits.
+
+ // Benchmarks show put performs better than putShort here (for HotSpot).
+ out.put(outIx++, (byte) (0xE0 | (c >>> 12)));
+ out.put(outIx++, (byte) (0x80 | (0x3F & (c >>> 6))));
+ out.put(outIx, (byte) (0x80 | (0x3F & c)));
+ } else {
+ // Four bytes (1111 xxxx 10xx xxxx 10xx xxxx 10xx xxxx)
+
+ // Minimum code point represented by a surrogate pair is 0x10000, 17 bits, four UTF-8
+ // bytes
+ final char low;
+ if (inIx + 1 == inLength || !isSurrogatePair(c, (low = in.charAt(++inIx)))) {
+ throw new UnpairedSurrogateException(inIx, inLength);
+ }
+ // TODO(nathanmittler): Consider using putInt() to improve performance.
+ int codePoint = toCodePoint(c, low);
+ out.put(outIx++, (byte) ((0xF << 4) | (codePoint >>> 18)));
+ out.put(outIx++, (byte) (0x80 | (0x3F & (codePoint >>> 12))));
+ out.put(outIx++, (byte) (0x80 | (0x3F & (codePoint >>> 6))));
+ out.put(outIx, (byte) (0x80 | (0x3F & codePoint)));
+ }
+ }
+
+ // Successfully encoded the entire string.
+ out.position(outIx);
+ } catch (IndexOutOfBoundsException e) {
+ // TODO(nathanmittler): Consider making the API throw IndexOutOfBoundsException instead.
+
+ // If we failed in the outer ASCII loop, outIx will not have been updated. In this case,
+ // use inIx to determine the bad write index.
+ int badWriteIndex = out.position() + Math.max(inIx, outIx - out.position() + 1);
+ throw new ArrayIndexOutOfBoundsException(
+ "Failed writing " + in.charAt(inIx) + " at index " + badWriteIndex);
+ }
+ }
+ }
+
+ /**
+ * {@link Processor} implementation that does not use any {@code sun.misc.Unsafe} methods.
+ */
+ static final class SafeProcessor extends Processor {
+ @Override
+ int partialIsValidUtf8(int state, byte[] bytes, int index, int limit) {
+ if (state != COMPLETE) {
+ // The previous decoding operation was incomplete (or malformed).
+ // We look for a well-formed sequence consisting of bytes from
+ // the previous decoding operation (stored in state) together
+ // with bytes from the array slice.
+ //
+ // We expect such "straddler characters" to be rare.
+
+ if (index >= limit) { // No bytes? No progress.
+ return state;
+ }
+ int byte1 = (byte) state;
+ // byte1 is never ASCII.
+ if (byte1 < (byte) 0xE0) {
+ // two-byte form
+
+ // Simultaneously checks for illegal trailing-byte in
+ // leading position and overlong 2-byte form.
+ if (byte1 < (byte) 0xC2
+ // byte2 trailing-byte test
+ || bytes[index++] > (byte) 0xBF) {
+ return MALFORMED;
+ }
+ } else if (byte1 < (byte) 0xF0) {
+ // three-byte form
+
+ // Get byte2 from saved state or array
+ int byte2 = (byte) ~(state >> 8);
+ if (byte2 == 0) {
+ byte2 = bytes[index++];
+ if (index >= limit) {
+ return incompleteStateFor(byte1, byte2);
+ }
+ }
+ if (byte2 > (byte) 0xBF
+ // overlong? 5 most significant bits must not all be zero
+ || (byte1 == (byte) 0xE0 && byte2 < (byte) 0xA0)
+ // illegal surrogate codepoint?
+ || (byte1 == (byte) 0xED && byte2 >= (byte) 0xA0)
+ // byte3 trailing-byte test
+ || bytes[index++] > (byte) 0xBF) {
+ return MALFORMED;
+ }
+ } else {
+ // four-byte form
+
+ // Get byte2 and byte3 from saved state or array
+ int byte2 = (byte) ~(state >> 8);
+ int byte3 = 0;
+ if (byte2 == 0) {
+ byte2 = bytes[index++];
+ if (index >= limit) {
+ return incompleteStateFor(byte1, byte2);
+ }
+ } else {
+ byte3 = (byte) (state >> 16);
+ }
+ if (byte3 == 0) {
+ byte3 = bytes[index++];
+ if (index >= limit) {
+ return incompleteStateFor(byte1, byte2, byte3);
+ }
+ }
+
+ // If we were called with state == MALFORMED, then byte1 is 0xFF,
+ // which never occurs in well-formed UTF-8, and so we will return
+ // MALFORMED again below.
+
+ if (byte2 > (byte) 0xBF
+ // Check that 1 <= plane <= 16. Tricky optimized form of:
+ // if (byte1 > (byte) 0xF4 ||
+ // byte1 == (byte) 0xF0 && byte2 < (byte) 0x90 ||
+ // byte1 == (byte) 0xF4 && byte2 > (byte) 0x8F)
+ || (((byte1 << 28) + (byte2 - (byte) 0x90)) >> 30) != 0
+ // byte3 trailing-byte test
+ || byte3 > (byte) 0xBF
+ // byte4 trailing-byte test
+ || bytes[index++] > (byte) 0xBF) {
+ return MALFORMED;
+ }
+ }
+ }
+
+ return partialIsValidUtf8(bytes, index, limit);
+ }
+
+ @Override
+ int partialIsValidUtf8Direct(int state, ByteBuffer buffer, int index, int limit) {
+ // For safe processing, we have to use the ByteBuffer API.
+ return partialIsValidUtf8Default(state, buffer, index, limit);
+ }
+
+ @Override
+ int encodeUtf8(CharSequence in, byte[] out, int offset, int length) {
+ int utf16Length = in.length();
+ int j = offset;
+ int i = 0;
+ int limit = offset + length;
+ // Designed to take advantage of
+ // https://wikis.oracle.com/display/HotSpotInternals/RangeCheckElimination
+ for (char c; i < utf16Length && i + j < limit && (c = in.charAt(i)) < 0x80; i++) {
+ out[j + i] = (byte) c;
+ }
+ if (i == utf16Length) {
+ return j + utf16Length;
+ }
+ j += i;
+ for (char c; i < utf16Length; i++) {
+ c = in.charAt(i);
+ if (c < 0x80 && j < limit) {
+ out[j++] = (byte) c;
+ } else if (c < 0x800 && j <= limit - 2) { // 11 bits, two UTF-8 bytes
+ out[j++] = (byte) ((0xF << 6) | (c >>> 6));
+ out[j++] = (byte) (0x80 | (0x3F & c));
+ } else if ((c < Character.MIN_SURROGATE || Character.MAX_SURROGATE < c) && j <= limit - 3) {
+ // Maximum single-char code point is 0xFFFF, 16 bits, three UTF-8 bytes
+ out[j++] = (byte) ((0xF << 5) | (c >>> 12));
+ out[j++] = (byte) (0x80 | (0x3F & (c >>> 6)));
+ out[j++] = (byte) (0x80 | (0x3F & c));
+ } else if (j <= limit - 4) {
+ // Minimum code point represented by a surrogate pair is 0x10000, 17 bits,
+ // four UTF-8 bytes
+ final char low;
+ if (i + 1 == in.length()
+ || !Character.isSurrogatePair(c, (low = in.charAt(++i)))) {
+ throw new UnpairedSurrogateException((i - 1), utf16Length);
+ }
+ int codePoint = Character.toCodePoint(c, low);
+ out[j++] = (byte) ((0xF << 4) | (codePoint >>> 18));
+ out[j++] = (byte) (0x80 | (0x3F & (codePoint >>> 12)));
+ out[j++] = (byte) (0x80 | (0x3F & (codePoint >>> 6)));
+ out[j++] = (byte) (0x80 | (0x3F & codePoint));
+ } else {
+ // If we are surrogates and we're not a surrogate pair, always throw an
+ // UnpairedSurrogateException instead of an ArrayOutOfBoundsException.
+ if ((Character.MIN_SURROGATE <= c && c <= Character.MAX_SURROGATE)
+ && (i + 1 == in.length()
+ || !Character.isSurrogatePair(c, in.charAt(i + 1)))) {
+ throw new UnpairedSurrogateException(i, utf16Length);
+ }
+ throw new ArrayIndexOutOfBoundsException("Failed writing " + c + " at index " + j);
+ }
+ }
+ return j;
+ }
+
+ @Override
+ void encodeUtf8Direct(CharSequence in, ByteBuffer out) {
+ // For safe processing, we have to use the ByteBuffer API.
+ encodeUtf8Default(in, out);
+ }
+
+ private static int partialIsValidUtf8(byte[] bytes, int index, int limit) {
+ // Optimize for 100% ASCII (Hotspot loves small simple top-level loops like this).
+ // This simple loop stops when we encounter a byte >= 0x80 (i.e. non-ASCII).
+ while (index < limit && bytes[index] >= 0) {
+ index++;
+ }
+
+ return (index >= limit) ? COMPLETE : partialIsValidUtf8NonAscii(bytes, index, limit);
+ }
+
+ private static int partialIsValidUtf8NonAscii(byte[] bytes, int index, int limit) {
+ for (;;) {
+ int byte1, byte2;
+
+ // Optimize for interior runs of ASCII bytes.
+ do {
+ if (index >= limit) {
+ return COMPLETE;
+ }
+ } while ((byte1 = bytes[index++]) >= 0);
+
+ if (byte1 < (byte) 0xE0) {
+ // two-byte form
+
+ if (index >= limit) {
+ // Incomplete sequence
+ return byte1;
+ }
+
+ // Simultaneously checks for illegal trailing-byte in
+ // leading position and overlong 2-byte form.
+ if (byte1 < (byte) 0xC2
+ || bytes[index++] > (byte) 0xBF) {
+ return MALFORMED;
+ }
+ } else if (byte1 < (byte) 0xF0) {
+ // three-byte form
+
+ if (index >= limit - 1) { // incomplete sequence
+ return incompleteStateFor(bytes, index, limit);
+ }
+ if ((byte2 = bytes[index++]) > (byte) 0xBF
+ // overlong? 5 most significant bits must not all be zero
+ || (byte1 == (byte) 0xE0 && byte2 < (byte) 0xA0)
+ // check for illegal surrogate codepoints
+ || (byte1 == (byte) 0xED && byte2 >= (byte) 0xA0)
+ // byte3 trailing-byte test
+ || bytes[index++] > (byte) 0xBF) {
+ return MALFORMED;
+ }
+ } else {
+ // four-byte form
+
+ if (index >= limit - 2) { // incomplete sequence
+ return incompleteStateFor(bytes, index, limit);
+ }
+ if ((byte2 = bytes[index++]) > (byte) 0xBF
+ // Check that 1 <= plane <= 16. Tricky optimized form of:
+ // if (byte1 > (byte) 0xF4 ||
+ // byte1 == (byte) 0xF0 && byte2 < (byte) 0x90 ||
+ // byte1 == (byte) 0xF4 && byte2 > (byte) 0x8F)
+ || (((byte1 << 28) + (byte2 - (byte) 0x90)) >> 30) != 0
+ // byte3 trailing-byte test
+ || bytes[index++] > (byte) 0xBF
+ // byte4 trailing-byte test
+ || bytes[index++] > (byte) 0xBF) {
+ return MALFORMED;
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * {@link Processor} that uses {@code sun.misc.Unsafe} where possible to improve performance.
+ */
+ static final class UnsafeProcessor extends Processor {
+ /**
+ * Indicates whether or not all required unsafe operations are supported on this platform.
+ */
+ static boolean isAvailable() {
+ return hasUnsafeArrayOperations() && hasUnsafeByteBufferOperations();
+ }
+
+ @Override
+ int partialIsValidUtf8(int state, byte[] bytes, final int index, final int limit) {
+ if ((index | limit | bytes.length - limit) < 0) {
+ throw new ArrayIndexOutOfBoundsException(
+ String.format("Array length=%d, index=%d, limit=%d", bytes.length, index, limit));
+ }
+ long offset = getArrayBaseOffset() + index;
+ final long offsetLimit = getArrayBaseOffset() + limit;
+ if (state != COMPLETE) {
+ // The previous decoding operation was incomplete (or malformed).
+ // We look for a well-formed sequence consisting of bytes from
+ // the previous decoding operation (stored in state) together
+ // with bytes from the array slice.
+ //
+ // We expect such "straddler characters" to be rare.
+
+ if (offset >= offsetLimit) { // No bytes? No progress.
+ return state;
+ }
+ int byte1 = (byte) state;
+ // byte1 is never ASCII.
+ if (byte1 < (byte) 0xE0) {
+ // two-byte form
+
+ // Simultaneously checks for illegal trailing-byte in
+ // leading position and overlong 2-byte form.
+ if (byte1 < (byte) 0xC2
+ // byte2 trailing-byte test
+ || UnsafeUtil.getByte(bytes, offset++) > (byte) 0xBF) {
+ return MALFORMED;
+ }
+ } else if (byte1 < (byte) 0xF0) {
+ // three-byte form
+
+ // Get byte2 from saved state or array
+ int byte2 = (byte) ~(state >> 8);
+ if (byte2 == 0) {
+ byte2 = UnsafeUtil.getByte(bytes, offset++);
+ if (offset >= offsetLimit) {
+ return incompleteStateFor(byte1, byte2);
+ }
+ }
+ if (byte2 > (byte) 0xBF
+ // overlong? 5 most significant bits must not all be zero
+ || (byte1 == (byte) 0xE0 && byte2 < (byte) 0xA0)
+ // illegal surrogate codepoint?
+ || (byte1 == (byte) 0xED && byte2 >= (byte) 0xA0)
+ // byte3 trailing-byte test
+ || UnsafeUtil.getByte(bytes, offset++) > (byte) 0xBF) {
+ return MALFORMED;
+ }
+ } else {
+ // four-byte form
+
+ // Get byte2 and byte3 from saved state or array
+ int byte2 = (byte) ~(state >> 8);
+ int byte3 = 0;
+ if (byte2 == 0) {
+ byte2 = UnsafeUtil.getByte(bytes, offset++);
+ if (offset >= offsetLimit) {
+ return incompleteStateFor(byte1, byte2);
+ }
+ } else {
+ byte3 = (byte) (state >> 16);
+ }
+ if (byte3 == 0) {
+ byte3 = UnsafeUtil.getByte(bytes, offset++);
+ if (offset >= offsetLimit) {
+ return incompleteStateFor(byte1, byte2, byte3);
+ }
+ }
+
+ // If we were called with state == MALFORMED, then byte1 is 0xFF,
+ // which never occurs in well-formed UTF-8, and so we will return
+ // MALFORMED again below.
+
+ if (byte2 > (byte) 0xBF
+ // Check that 1 <= plane <= 16. Tricky optimized form of:
+ // if (byte1 > (byte) 0xF4 ||
+ // byte1 == (byte) 0xF0 && byte2 < (byte) 0x90 ||
+ // byte1 == (byte) 0xF4 && byte2 > (byte) 0x8F)
+ || (((byte1 << 28) + (byte2 - (byte) 0x90)) >> 30) != 0
+ // byte3 trailing-byte test
+ || byte3 > (byte) 0xBF
+ // byte4 trailing-byte test
+ || UnsafeUtil.getByte(bytes, offset++) > (byte) 0xBF) {
+ return MALFORMED;
+ }
+ }
+ }
+
+ return partialIsValidUtf8(bytes, offset, (int) (offsetLimit - offset));
+ }
+
+ @Override
+ int partialIsValidUtf8Direct(
+ final int state, ByteBuffer buffer, final int index, final int limit) {
+ if ((index | limit | buffer.limit() - limit) < 0) {
+ throw new ArrayIndexOutOfBoundsException(
+ String.format("buffer limit=%d, index=%d, limit=%d", buffer.limit(), index, limit));
+ }
+ long address = addressOffset(buffer) + index;
+ final long addressLimit = address + (limit - index);
+ if (state != COMPLETE) {
+ // The previous decoding operation was incomplete (or malformed).
+ // We look for a well-formed sequence consisting of bytes from
+ // the previous decoding operation (stored in state) together
+ // with bytes from the array slice.
+ //
+ // We expect such "straddler characters" to be rare.
+
+ if (address >= addressLimit) { // No bytes? No progress.
+ return state;
+ }
+
+ final int byte1 = (byte) state;
+ // byte1 is never ASCII.
+ if (byte1 < (byte) 0xE0) {
+ // two-byte form
+
+ // Simultaneously checks for illegal trailing-byte in
+ // leading position and overlong 2-byte form.
+ if (byte1 < (byte) 0xC2
+ // byte2 trailing-byte test
+ || UnsafeUtil.getByte(address++) > (byte) 0xBF) {
+ return MALFORMED;
+ }
+ } else if (byte1 < (byte) 0xF0) {
+ // three-byte form
+
+ // Get byte2 from saved state or array
+ int byte2 = (byte) ~(state >> 8);
+ if (byte2 == 0) {
+ byte2 = UnsafeUtil.getByte(address++);
+ if (address >= addressLimit) {
+ return incompleteStateFor(byte1, byte2);
+ }
+ }
+ if (byte2 > (byte) 0xBF
+ // overlong? 5 most significant bits must not all be zero
+ || (byte1 == (byte) 0xE0 && byte2 < (byte) 0xA0)
+ // illegal surrogate codepoint?
+ || (byte1 == (byte) 0xED && byte2 >= (byte) 0xA0)
+ // byte3 trailing-byte test
+ || UnsafeUtil.getByte(address++) > (byte) 0xBF) {
+ return MALFORMED;
+ }
+ } else {
+ // four-byte form
+
+ // Get byte2 and byte3 from saved state or array
+ int byte2 = (byte) ~(state >> 8);
+ int byte3 = 0;
+ if (byte2 == 0) {
+ byte2 = UnsafeUtil.getByte(address++);
+ if (address >= addressLimit) {
+ return incompleteStateFor(byte1, byte2);
+ }
+ } else {
+ byte3 = (byte) (state >> 16);
+ }
+ if (byte3 == 0) {
+ byte3 = UnsafeUtil.getByte(address++);
+ if (address >= addressLimit) {
+ return incompleteStateFor(byte1, byte2, byte3);
+ }
+ }
+
+ // If we were called with state == MALFORMED, then byte1 is 0xFF,
+ // which never occurs in well-formed UTF-8, and so we will return
+ // MALFORMED again below.
+
+ if (byte2 > (byte) 0xBF
+ // Check that 1 <= plane <= 16. Tricky optimized form of:
+ // if (byte1 > (byte) 0xF4 ||
+ // byte1 == (byte) 0xF0 && byte2 < (byte) 0x90 ||
+ // byte1 == (byte) 0xF4 && byte2 > (byte) 0x8F)
+ || (((byte1 << 28) + (byte2 - (byte) 0x90)) >> 30) != 0
+ // byte3 trailing-byte test
+ || byte3 > (byte) 0xBF
+ // byte4 trailing-byte test
+ || UnsafeUtil.getByte(address++) > (byte) 0xBF) {
+ return MALFORMED;
+ }
+ }
+ }
+
+ return partialIsValidUtf8(address, (int) (addressLimit - address));
+ }
+
+ @Override
+ int encodeUtf8(final CharSequence in, final byte[] out, final int offset, final int length) {
+ long outIx = getArrayBaseOffset() + offset;
+ final long outLimit = outIx + length;
+ final int inLimit = in.length();
+ if (inLimit > length || out.length - length < offset) {
+ // Not even enough room for an ASCII-encoded string.
+ throw new ArrayIndexOutOfBoundsException(
+ "Failed writing " + in.charAt(inLimit - 1) + " at index " + (offset + length));
+ }
+
+ // Designed to take advantage of
+ // https://wikis.oracle.com/display/HotSpotInternals/RangeCheckElimination
+ int inIx = 0;
+ for (char c; inIx < inLimit && (c = in.charAt(inIx)) < 0x80; ++inIx) {
+ UnsafeUtil.putByte(out, outIx++, (byte) c);
+ }
+ if (inIx == inLimit) {
+ // We're done, it was ASCII encoded.
+ return (int) (outIx - getArrayBaseOffset());
+ }
+
+ for (char c; inIx < inLimit; ++inIx) {
+ c = in.charAt(inIx);
+ if (c < 0x80 && outIx < outLimit) {
+ UnsafeUtil.putByte(out, outIx++, (byte) c);
+ } else if (c < 0x800 && outIx <= outLimit - 2L) { // 11 bits, two UTF-8 bytes
+ UnsafeUtil.putByte(out, outIx++, (byte) ((0xF << 6) | (c >>> 6)));
+ UnsafeUtil.putByte(out, outIx++, (byte) (0x80 | (0x3F & c)));
+ } else if ((c < MIN_SURROGATE || MAX_SURROGATE < c) && outIx <= outLimit - 3L) {
+ // Maximum single-char code point is 0xFFFF, 16 bits, three UTF-8 bytes
+ UnsafeUtil.putByte(out, outIx++, (byte) ((0xF << 5) | (c >>> 12)));
+ UnsafeUtil.putByte(out, outIx++, (byte) (0x80 | (0x3F & (c >>> 6))));
+ UnsafeUtil.putByte(out, outIx++, (byte) (0x80 | (0x3F & c)));
+ } else if (outIx <= outLimit - 4L) {
+ // Minimum code point represented by a surrogate pair is 0x10000, 17 bits, four UTF-8
+ // bytes
+ final char low;
+ if (inIx + 1 == inLimit || !isSurrogatePair(c, (low = in.charAt(++inIx)))) {
+ throw new UnpairedSurrogateException((inIx - 1), inLimit);
+ }
+ int codePoint = toCodePoint(c, low);
+ UnsafeUtil.putByte(out, outIx++, (byte) ((0xF << 4) | (codePoint >>> 18)));
+ UnsafeUtil.putByte(out, outIx++, (byte) (0x80 | (0x3F & (codePoint >>> 12))));
+ UnsafeUtil.putByte(out, outIx++, (byte) (0x80 | (0x3F & (codePoint >>> 6))));
+ UnsafeUtil.putByte(out, outIx++, (byte) (0x80 | (0x3F & codePoint)));
+ } else {
+ if ((MIN_SURROGATE <= c && c <= MAX_SURROGATE)
+ && (inIx + 1 == inLimit || !isSurrogatePair(c, in.charAt(inIx + 1)))) {
+ // We are surrogates and we're not a surrogate pair.
+ throw new UnpairedSurrogateException(inIx, inLimit);
+ }
+ // Not enough space in the output buffer.
+ throw new ArrayIndexOutOfBoundsException("Failed writing " + c + " at index " + outIx);
+ }
+ }
+
+ // All bytes have been encoded.
+ return (int) (outIx - getArrayBaseOffset());
+ }
+
+ @Override
+ void encodeUtf8Direct(CharSequence in, ByteBuffer out) {
+ final long address = addressOffset(out);
+ long outIx = address + out.position();
+ final long outLimit = address + out.limit();
+ final int inLimit = in.length();
+ if (inLimit > outLimit - outIx) {
+ // Not even enough room for an ASCII-encoded string.
+ throw new ArrayIndexOutOfBoundsException(
+ "Failed writing " + in.charAt(inLimit - 1) + " at index " + out.limit());
+ }
+
+ // Designed to take advantage of
+ // https://wikis.oracle.com/display/HotSpotInternals/RangeCheckElimination
+ int inIx = 0;
+ for (char c; inIx < inLimit && (c = in.charAt(inIx)) < 0x80; ++inIx) {
+ UnsafeUtil.putByte(outIx++, (byte) c);
+ }
+ if (inIx == inLimit) {
+ // We're done, it was ASCII encoded.
+ out.position((int) (outIx - address));
+ return;
+ }
+
+ for (char c; inIx < inLimit; ++inIx) {
+ c = in.charAt(inIx);
+ if (c < 0x80 && outIx < outLimit) {
+ UnsafeUtil.putByte(outIx++, (byte) c);
+ } else if (c < 0x800 && outIx <= outLimit - 2L) { // 11 bits, two UTF-8 bytes
+ UnsafeUtil.putByte(outIx++, (byte) ((0xF << 6) | (c >>> 6)));
+ UnsafeUtil.putByte(outIx++, (byte) (0x80 | (0x3F & c)));
+ } else if ((c < MIN_SURROGATE || MAX_SURROGATE < c) && outIx <= outLimit - 3L) {
+ // Maximum single-char code point is 0xFFFF, 16 bits, three UTF-8 bytes
+ UnsafeUtil.putByte(outIx++, (byte) ((0xF << 5) | (c >>> 12)));
+ UnsafeUtil.putByte(outIx++, (byte) (0x80 | (0x3F & (c >>> 6))));
+ UnsafeUtil.putByte(outIx++, (byte) (0x80 | (0x3F & c)));
+ } else if (outIx <= outLimit - 4L) {
+ // Minimum code point represented by a surrogate pair is 0x10000, 17 bits, four UTF-8
+ // bytes
+ final char low;
+ if (inIx + 1 == inLimit || !isSurrogatePair(c, (low = in.charAt(++inIx)))) {
+ throw new UnpairedSurrogateException((inIx - 1), inLimit);
+ }
+ int codePoint = toCodePoint(c, low);
+ UnsafeUtil.putByte(outIx++, (byte) ((0xF << 4) | (codePoint >>> 18)));
+ UnsafeUtil.putByte(outIx++, (byte) (0x80 | (0x3F & (codePoint >>> 12))));
+ UnsafeUtil.putByte(outIx++, (byte) (0x80 | (0x3F & (codePoint >>> 6))));
+ UnsafeUtil.putByte(outIx++, (byte) (0x80 | (0x3F & codePoint)));
+ } else {
+ if ((MIN_SURROGATE <= c && c <= MAX_SURROGATE)
+ && (inIx + 1 == inLimit || !isSurrogatePair(c, in.charAt(inIx + 1)))) {
+ // We are surrogates and we're not a surrogate pair.
+ throw new UnpairedSurrogateException(inIx, inLimit);
+ }
+ // Not enough space in the output buffer.
+ throw new ArrayIndexOutOfBoundsException("Failed writing " + c + " at index " + outIx);
+ }
+ }
+
+ // All bytes have been encoded.
+ out.position((int) (outIx - address));
+ }
+
+ /**
+ * Counts (approximately) the number of consecutive ASCII characters starting from the given
+ * position, using the most efficient method available to the platform.
+ *
+ * @param bytes the array containing the character sequence
+ * @param offset the offset position of the index (same as index + arrayBaseOffset)
+ * @param maxChars the maximum number of characters to count
+ * @return the number of ASCII characters found. The stopping position will be at or
+ * before the first non-ASCII byte.
+ */
+ private static int unsafeEstimateConsecutiveAscii(
+ byte[] bytes, long offset, final int maxChars) {
+ int remaining = maxChars;
+ if (remaining < UNSAFE_COUNT_ASCII_THRESHOLD) {
+ // Don't bother with small strings.
+ return 0;
+ }
+
+ // Read bytes until 8-byte aligned so that we can read longs in the loop below.
+ // Byte arrays are already either 8 or 16-byte aligned, so we just need to make sure that
+ // the index (relative to the start of the array) is also 8-byte aligned. We do this by
+ // ANDing the index with 7 to determine the number of bytes that need to be read before
+ // we're 8-byte aligned.
+ final int unaligned = (int) offset & 7;
+ for (int j = unaligned; j > 0; j--) {
+ if (UnsafeUtil.getByte(bytes, offset++) < 0) {
+ return unaligned - j;
+ }
+ }
+
+ // This simple loop stops when we encounter a byte >= 0x80 (i.e. non-ASCII).
+ // To speed things up further, we're reading longs instead of bytes so we use a mask to
+ // determine if any byte in the current long is non-ASCII.
+ remaining -= unaligned;
+ for (; remaining >= 8 && (UnsafeUtil.getLong(bytes, offset) & ASCII_MASK_LONG) == 0;
+ offset += 8, remaining -= 8) {}
+ return maxChars - remaining;
+ }
+
+ /**
+ * Same as {@link Utf8#estimateConsecutiveAscii(ByteBuffer, int, int)} except that it uses the
+ * most efficient method available to the platform.
+ */
+ private static int unsafeEstimateConsecutiveAscii(long address, final int maxChars) {
+ int remaining = maxChars;
+ if (remaining < UNSAFE_COUNT_ASCII_THRESHOLD) {
+ // Don't bother with small strings.
+ return 0;
+ }
+
+ // Read bytes until 8-byte aligned so that we can read longs in the loop below.
+ // We do this by ANDing the address with 7 to determine the number of bytes that need to
+ // be read before we're 8-byte aligned.
+ final int unaligned = (int) address & 7;
+ for (int j = unaligned; j > 0; j--) {
+ if (UnsafeUtil.getByte(address++) < 0) {
+ return unaligned - j;
+ }
+ }
+
+ // This simple loop stops when we encounter a byte >= 0x80 (i.e. non-ASCII).
+ // To speed things up further, we're reading longs instead of bytes so we use a mask to
+ // determine if any byte in the current long is non-ASCII.
+ remaining -= unaligned;
+ for (; remaining >= 8 && (UnsafeUtil.getLong(address) & ASCII_MASK_LONG) == 0;
+ address += 8, remaining -= 8) {}
+ return maxChars - remaining;
+ }
+
+ private static int partialIsValidUtf8(final byte[] bytes, long offset, int remaining) {
+ // Skip past ASCII characters as quickly as possible.
+ final int skipped = unsafeEstimateConsecutiveAscii(bytes, offset, remaining);
+ remaining -= skipped;
+ offset += skipped;
+
+ for (;;) {
+ // Optimize for interior runs of ASCII bytes.
+ // TODO(nathanmittler): Consider checking 8 bytes at a time after some threshold?
+ // Maybe after seeing a few in a row that are ASCII, go back to fast mode?
+ int byte1 = 0;
+ for (; remaining > 0 && (byte1 = UnsafeUtil.getByte(bytes, offset++)) >= 0; --remaining) {
+ }
+ if (remaining == 0) {
+ return COMPLETE;
+ }
+ remaining--;
+
+ // If we're here byte1 is not ASCII. Only need to handle 2-4 byte forms.
+ if (byte1 < (byte) 0xE0) {
+ // Two-byte form (110xxxxx 10xxxxxx)
+ if (remaining == 0) {
+ // Incomplete sequence
+ return byte1;
+ }
+ remaining--;
+
+ // Simultaneously checks for illegal trailing-byte in
+ // leading position and overlong 2-byte form.
+ if (byte1 < (byte) 0xC2
+ || UnsafeUtil.getByte(bytes, offset++) > (byte) 0xBF) {
+ return MALFORMED;
+ }
+ } else if (byte1 < (byte) 0xF0) {
+ // Three-byte form (1110xxxx 10xxxxxx 10xxxxxx)
+ if (remaining < 2) {
+ // Incomplete sequence
+ return unsafeIncompleteStateFor(bytes, byte1, offset, remaining);
+ }
+ remaining -= 2;
+
+ final int byte2;
+ if ((byte2 = UnsafeUtil.getByte(bytes, offset++)) > (byte) 0xBF
+ // overlong? 5 most significant bits must not all be zero
+ || (byte1 == (byte) 0xE0 && byte2 < (byte) 0xA0)
+ // check for illegal surrogate codepoints
+ || (byte1 == (byte) 0xED && byte2 >= (byte) 0xA0)
+ // byte3 trailing-byte test
+ || UnsafeUtil.getByte(bytes, offset++) > (byte) 0xBF) {
+ return MALFORMED;
+ }
+ } else {
+ // Four-byte form (1110xxxx 10xxxxxx 10xxxxxx 10xxxxxx)
+ if (remaining < 3) {
+ // Incomplete sequence
+ return unsafeIncompleteStateFor(bytes, byte1, offset, remaining);
+ }
+ remaining -= 3;
+
+ final int byte2;
+ if ((byte2 = UnsafeUtil.getByte(bytes, offset++)) > (byte) 0xBF
+ // Check that 1 <= plane <= 16. Tricky optimized form of:
+ // if (byte1 > (byte) 0xF4 ||
+ // byte1 == (byte) 0xF0 && byte2 < (byte) 0x90 ||
+ // byte1 == (byte) 0xF4 && byte2 > (byte) 0x8F)
+ || (((byte1 << 28) + (byte2 - (byte) 0x90)) >> 30) != 0
+ // byte3 trailing-byte test
+ || UnsafeUtil.getByte(bytes, offset++) > (byte) 0xBF
+ // byte4 trailing-byte test
+ || UnsafeUtil.getByte(bytes, offset++) > (byte) 0xBF) {
+ return MALFORMED;
+ }
+ }
+ }
+ }
+
+ private static int partialIsValidUtf8(long address, int remaining) {
+ // Skip past ASCII characters as quickly as possible.
+ final int skipped = unsafeEstimateConsecutiveAscii(address, remaining);
+ address += skipped;
+ remaining -= skipped;
+
+ for (;;) {
+ // Optimize for interior runs of ASCII bytes.
+ // TODO(nathanmittler): Consider checking 8 bytes at a time after some threshold?
+ // Maybe after seeing a few in a row that are ASCII, go back to fast mode?
+ int byte1 = 0;
+ for (; remaining > 0 && (byte1 = UnsafeUtil.getByte(address++)) >= 0; --remaining) {
+ }
+ if (remaining == 0) {
+ return COMPLETE;
+ }
+ remaining--;
+
+ if (byte1 < (byte) 0xE0) {
+ // Two-byte form
+
+ if (remaining == 0) {
+ // Incomplete sequence
+ return byte1;
+ }
+ remaining--;
+
+ // Simultaneously checks for illegal trailing-byte in
+ // leading position and overlong 2-byte form.
+ if (byte1 < (byte) 0xC2 || UnsafeUtil.getByte(address++) > (byte) 0xBF) {
+ return MALFORMED;
+ }
+ } else if (byte1 < (byte) 0xF0) {
+ // Three-byte form
+
+ if (remaining < 2) {
+ // Incomplete sequence
+ return unsafeIncompleteStateFor(address, byte1, remaining);
+ }
+ remaining -= 2;
+
+ final byte byte2 = UnsafeUtil.getByte(address++);
+ if (byte2 > (byte) 0xBF
+ // overlong? 5 most significant bits must not all be zero
+ || (byte1 == (byte) 0xE0 && byte2 < (byte) 0xA0)
+ // check for illegal surrogate codepoints
+ || (byte1 == (byte) 0xED && byte2 >= (byte) 0xA0)
+ // byte3 trailing-byte test
+ || UnsafeUtil.getByte(address++) > (byte) 0xBF) {
+ return MALFORMED;
+ }
+ } else {
+ // Four-byte form
+
+ if (remaining < 3) {
+ // Incomplete sequence
+ return unsafeIncompleteStateFor(address, byte1, remaining);
+ }
+ remaining -= 3;
+
+ final byte byte2 = UnsafeUtil.getByte(address++);
+ if (byte2 > (byte) 0xBF
+ // Check that 1 <= plane <= 16. Tricky optimized form of:
+ // if (byte1 > (byte) 0xF4 ||
+ // byte1 == (byte) 0xF0 && byte2 < (byte) 0x90 ||
+ // byte1 == (byte) 0xF4 && byte2 > (byte) 0x8F)
+ || (((byte1 << 28) + (byte2 - (byte) 0x90)) >> 30) != 0
+ // byte3 trailing-byte test
+ || UnsafeUtil.getByte(address++) > (byte) 0xBF
+ // byte4 trailing-byte test
+ || UnsafeUtil.getByte(address++) > (byte) 0xBF) {
+ return MALFORMED;
+ }
+ }
+ }
+ }
+
+ private static int unsafeIncompleteStateFor(byte[] bytes, int byte1, long offset,
+ int remaining) {
+ switch (remaining) {
+ case 0: {
+ return incompleteStateFor(byte1);
+ }
+ case 1: {
+ return incompleteStateFor(byte1, UnsafeUtil.getByte(bytes, offset));
+ }
+ case 2: {
+ return incompleteStateFor(byte1, UnsafeUtil.getByte(bytes, offset),
+ UnsafeUtil.getByte(bytes, offset + 1));
+ }
+ default: {
+ throw new AssertionError();
+ }
+ }
+ }
+
+ private static int unsafeIncompleteStateFor(long address, final int byte1, int remaining) {
+ switch (remaining) {
+ case 0: {
+ return incompleteStateFor(byte1);
+ }
+ case 1: {
+ return incompleteStateFor(byte1, UnsafeUtil.getByte(address));
+ }
+ case 2: {
+ return incompleteStateFor(byte1, UnsafeUtil.getByte(address),
+ UnsafeUtil.getByte(address + 1));
+ }
+ default: {
+ throw new AssertionError();
+ }
+ }
+ }
+ }
+
+ private Utf8() {}
+}
diff --git a/java/src/main/java/com/google/protobuf/WireFormat.java b/java/core/src/main/java/com/google/protobuf/WireFormat.java
index 8dbe1ae3..6a58b081 100644
--- a/java/src/main/java/com/google/protobuf/WireFormat.java
+++ b/java/core/src/main/java/com/google/protobuf/WireFormat.java
@@ -116,16 +116,24 @@ public final class WireFormat {
FIXED32 (JavaType.INT , WIRETYPE_FIXED32 ),
BOOL (JavaType.BOOLEAN , WIRETYPE_VARINT ),
STRING (JavaType.STRING , WIRETYPE_LENGTH_DELIMITED) {
- public boolean isPackable() { return false; }
+ @Override
+ public boolean isPackable() {
+ return false; }
},
GROUP (JavaType.MESSAGE , WIRETYPE_START_GROUP ) {
- public boolean isPackable() { return false; }
+ @Override
+ public boolean isPackable() {
+ return false; }
},
MESSAGE (JavaType.MESSAGE , WIRETYPE_LENGTH_DELIMITED) {
- public boolean isPackable() { return false; }
+ @Override
+ public boolean isPackable() {
+ return false; }
},
BYTES (JavaType.BYTE_STRING, WIRETYPE_LENGTH_DELIMITED) {
- public boolean isPackable() { return false; }
+ @Override
+ public boolean isPackable() {
+ return false; }
},
UINT32 (JavaType.INT , WIRETYPE_VARINT ),
ENUM (JavaType.ENUM , WIRETYPE_VARINT ),
@@ -170,18 +178,21 @@ public final class WireFormat {
enum Utf8Validation {
/** Eagerly parses to String; silently accepts invalid UTF8 bytes. */
LOOSE {
+ @Override
Object readString(CodedInputStream input) throws IOException {
return input.readString();
}
},
/** Eagerly parses to String; throws an IOException on invalid bytes. */
STRICT {
+ @Override
Object readString(CodedInputStream input) throws IOException {
return input.readStringRequireUtf8();
}
},
/** Keep data as ByteString; validation/conversion to String is lazy. */
LAZY {
+ @Override
Object readString(CodedInputStream input) throws IOException {
return input.readBytes();
}
diff --git a/java/src/test/java/com/google/protobuf/AbstractMessageTest.java b/java/core/src/test/java/com/google/protobuf/AbstractMessageTest.java
index d964ef59..7dc9fc15 100644
--- a/java/src/test/java/com/google/protobuf/AbstractMessageTest.java
+++ b/java/core/src/test/java/com/google/protobuf/AbstractMessageTest.java
@@ -40,7 +40,6 @@ import protobuf_unittest.UnittestProto.TestPackedTypes;
import protobuf_unittest.UnittestProto.TestRequired;
import protobuf_unittest.UnittestProto.TestRequiredForeign;
import protobuf_unittest.UnittestProto.TestUnpackedTypes;
-
import junit.framework.TestCase;
import java.util.Map;
@@ -65,35 +64,44 @@ public class AbstractMessageTest extends TestCase {
this.wrappedMessage = wrappedMessage;
}
+ @Override
public Descriptors.Descriptor getDescriptorForType() {
return wrappedMessage.getDescriptorForType();
}
+ @Override
public AbstractMessageWrapper getDefaultInstanceForType() {
return new AbstractMessageWrapper(
wrappedMessage.getDefaultInstanceForType());
}
+ @Override
public Map<Descriptors.FieldDescriptor, Object> getAllFields() {
return wrappedMessage.getAllFields();
}
+ @Override
public boolean hasField(Descriptors.FieldDescriptor field) {
return wrappedMessage.hasField(field);
}
+ @Override
public Object getField(Descriptors.FieldDescriptor field) {
return wrappedMessage.getField(field);
}
+ @Override
public int getRepeatedFieldCount(Descriptors.FieldDescriptor field) {
return wrappedMessage.getRepeatedFieldCount(field);
}
- public Object getRepeatedField(
- Descriptors.FieldDescriptor field, int index) {
+ @Override
+ public Object getRepeatedField(Descriptors.FieldDescriptor field, int index) {
return wrappedMessage.getRepeatedField(field, index);
}
+ @Override
public UnknownFieldSet getUnknownFields() {
return wrappedMessage.getUnknownFields();
}
+ @Override
public Builder newBuilderForType() {
return new Builder(wrappedMessage.newBuilderForType());
}
+ @Override
public Builder toBuilder() {
return new Builder(wrappedMessage.toBuilder());
}
@@ -105,65 +113,80 @@ public class AbstractMessageTest extends TestCase {
this.wrappedBuilder = wrappedBuilder;
}
+ @Override
public AbstractMessageWrapper build() {
return new AbstractMessageWrapper(wrappedBuilder.build());
}
+ @Override
public AbstractMessageWrapper buildPartial() {
return new AbstractMessageWrapper(wrappedBuilder.buildPartial());
}
+ @Override
public Builder clone() {
return new Builder(wrappedBuilder.clone());
}
+ @Override
public boolean isInitialized() {
return clone().buildPartial().isInitialized();
}
+ @Override
public Descriptors.Descriptor getDescriptorForType() {
return wrappedBuilder.getDescriptorForType();
}
+ @Override
public AbstractMessageWrapper getDefaultInstanceForType() {
return new AbstractMessageWrapper(
wrappedBuilder.getDefaultInstanceForType());
}
+ @Override
public Map<Descriptors.FieldDescriptor, Object> getAllFields() {
return wrappedBuilder.getAllFields();
}
+ @Override
public Builder newBuilderForField(Descriptors.FieldDescriptor field) {
return new Builder(wrappedBuilder.newBuilderForField(field));
}
+ @Override
public boolean hasField(Descriptors.FieldDescriptor field) {
return wrappedBuilder.hasField(field);
}
+ @Override
public Object getField(Descriptors.FieldDescriptor field) {
return wrappedBuilder.getField(field);
}
+ @Override
public Builder setField(Descriptors.FieldDescriptor field, Object value) {
wrappedBuilder.setField(field, value);
return this;
}
+ @Override
public Builder clearField(Descriptors.FieldDescriptor field) {
wrappedBuilder.clearField(field);
return this;
}
+ @Override
public int getRepeatedFieldCount(Descriptors.FieldDescriptor field) {
return wrappedBuilder.getRepeatedFieldCount(field);
}
- public Object getRepeatedField(
- Descriptors.FieldDescriptor field, int index) {
+ @Override
+ public Object getRepeatedField(Descriptors.FieldDescriptor field, int index) {
return wrappedBuilder.getRepeatedField(field, index);
}
- public Builder setRepeatedField(Descriptors.FieldDescriptor field,
- int index, Object value) {
+ @Override
+ public Builder setRepeatedField(Descriptors.FieldDescriptor field, int index, Object value) {
wrappedBuilder.setRepeatedField(field, index, value);
return this;
}
- public Builder addRepeatedField(
- Descriptors.FieldDescriptor field, Object value) {
+ @Override
+ public Builder addRepeatedField(Descriptors.FieldDescriptor field, Object value) {
wrappedBuilder.addRepeatedField(field, value);
return this;
}
+ @Override
public UnknownFieldSet getUnknownFields() {
return wrappedBuilder.getUnknownFields();
}
+ @Override
public Builder setUnknownFields(UnknownFieldSet unknownFields) {
wrappedBuilder.setUnknownFields(unknownFields);
return this;
@@ -173,6 +196,7 @@ public class AbstractMessageTest extends TestCase {
return wrappedBuilder.getFieldBuilder(field);
}
}
+ @Override
public Parser<? extends Message> getParserForType() {
return wrappedMessage.getParserForType();
}
diff --git a/java/src/test/java/com/google/protobuf/AnyTest.java b/java/core/src/test/java/com/google/protobuf/AnyTest.java
index e169f69d..cf91ed91 100644
--- a/java/src/test/java/com/google/protobuf/AnyTest.java
+++ b/java/core/src/test/java/com/google/protobuf/AnyTest.java
@@ -75,6 +75,51 @@ public class AnyTest extends TestCase {
}
}
+ public void testCustomTypeUrls() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TestUtil.setAllFields(builder);
+ TestAllTypes message = builder.build();
+
+ TestAny container = TestAny.newBuilder()
+ .setValue(Any.pack(message, "xxx.com")).build();
+
+ assertEquals(
+ "xxx.com/" + TestAllTypes.getDescriptor().getFullName(),
+ container.getValue().getTypeUrl());
+
+ assertTrue(container.getValue().is(TestAllTypes.class));
+ assertFalse(container.getValue().is(TestAny.class));
+
+ TestAllTypes result = container.getValue().unpack(TestAllTypes.class);
+ TestUtil.assertAllFieldsSet(result);
+
+ container = TestAny.newBuilder()
+ .setValue(Any.pack(message, "yyy.com/")).build();
+
+ assertEquals(
+ "yyy.com/" + TestAllTypes.getDescriptor().getFullName(),
+ container.getValue().getTypeUrl());
+
+ assertTrue(container.getValue().is(TestAllTypes.class));
+ assertFalse(container.getValue().is(TestAny.class));
+
+ result = container.getValue().unpack(TestAllTypes.class);
+ TestUtil.assertAllFieldsSet(result);
+
+ container = TestAny.newBuilder()
+ .setValue(Any.pack(message, "")).build();
+
+ assertEquals(
+ "/" + TestAllTypes.getDescriptor().getFullName(),
+ container.getValue().getTypeUrl());
+
+ assertTrue(container.getValue().is(TestAllTypes.class));
+ assertFalse(container.getValue().is(TestAny.class));
+
+ result = container.getValue().unpack(TestAllTypes.class);
+ TestUtil.assertAllFieldsSet(result);
+ }
+
public void testCachedUnpackResult() throws Exception {
TestAllTypes.Builder builder = TestAllTypes.newBuilder();
TestUtil.setAllFields(builder);
diff --git a/java/src/test/java/com/google/protobuf/BooleanArrayListTest.java b/java/core/src/test/java/com/google/protobuf/BooleanArrayListTest.java
index df89c263..ec139225 100644
--- a/java/src/test/java/com/google/protobuf/BooleanArrayListTest.java
+++ b/java/core/src/test/java/com/google/protobuf/BooleanArrayListTest.java
@@ -40,30 +40,31 @@ import java.util.Iterator;
/**
* Tests for {@link BooleanArrayList}.
- *
+ *
* @author dweis@google.com (Daniel Weis)
*/
public class BooleanArrayListTest extends TestCase {
-
- private static final BooleanArrayList UNARY_LIST = newImmutableBooleanArrayList(true);
+
+ private static final BooleanArrayList UNARY_LIST =
+ newImmutableBooleanArrayList(true);
private static final BooleanArrayList TERTIARY_LIST =
- newImmutableBooleanArrayList(true, true, false);
-
+ newImmutableBooleanArrayList(true, false, true);
+
private BooleanArrayList list;
-
+
@Override
protected void setUp() throws Exception {
list = new BooleanArrayList();
}
-
+
public void testEmptyListReturnsSameInstance() {
assertSame(BooleanArrayList.emptyList(), BooleanArrayList.emptyList());
}
-
+
public void testEmptyListIsImmutable() {
assertImmutable(BooleanArrayList.emptyList());
}
-
+
public void testMakeImmutable() {
list.addBoolean(true);
list.addBoolean(false);
@@ -72,30 +73,16 @@ public class BooleanArrayListTest extends TestCase {
list.makeImmutable();
assertImmutable(list);
}
-
- public void testCopyConstructor() {
- BooleanArrayList copy = new BooleanArrayList(TERTIARY_LIST);
- assertEquals(TERTIARY_LIST, copy);
-
- copy = new BooleanArrayList(BooleanArrayList.emptyList());
- assertEquals(BooleanArrayList.emptyList(), copy);
-
- copy = new BooleanArrayList(asList(false, false, true));
- assertEquals(asList(false, false, true), copy);
-
- copy = new BooleanArrayList(Collections.<Boolean>emptyList());
- assertEquals(BooleanArrayList.emptyList(), copy);
- }
-
+
public void testModificationWithIteration() {
- list.addAll(asList(true, false, false, true));
+ list.addAll(asList(true, false, true, false));
Iterator<Boolean> iterator = list.iterator();
assertEquals(4, list.size());
assertEquals(true, (boolean) list.get(0));
assertEquals(true, (boolean) iterator.next());
list.set(0, true);
assertEquals(false, (boolean) iterator.next());
-
+
list.remove(0);
try {
iterator.next();
@@ -103,7 +90,7 @@ public class BooleanArrayListTest extends TestCase {
} catch (ConcurrentModificationException e) {
// expected
}
-
+
iterator = list.iterator();
list.add(0, false);
try {
@@ -113,19 +100,19 @@ public class BooleanArrayListTest extends TestCase {
// expected
}
}
-
+
public void testGet() {
assertEquals(true, (boolean) TERTIARY_LIST.get(0));
- assertEquals(true, (boolean) TERTIARY_LIST.get(1));
- assertEquals(false, (boolean) TERTIARY_LIST.get(2));
-
+ assertEquals(false, (boolean) TERTIARY_LIST.get(1));
+ assertEquals(true, (boolean) TERTIARY_LIST.get(2));
+
try {
TERTIARY_LIST.get(-1);
fail();
} catch (IndexOutOfBoundsException e) {
// expected
}
-
+
try {
TERTIARY_LIST.get(3);
fail();
@@ -133,19 +120,19 @@ public class BooleanArrayListTest extends TestCase {
// expected
}
}
-
- public void testGetInt() {
+
+ public void testGetBoolean() {
assertEquals(true, TERTIARY_LIST.getBoolean(0));
- assertEquals(true, TERTIARY_LIST.getBoolean(1));
- assertEquals(false, TERTIARY_LIST.getBoolean(2));
-
+ assertEquals(false, TERTIARY_LIST.getBoolean(1));
+ assertEquals(true, TERTIARY_LIST.getBoolean(2));
+
try {
TERTIARY_LIST.get(-1);
fail();
} catch (IndexOutOfBoundsException e) {
// expected
}
-
+
try {
TERTIARY_LIST.get(3);
fail();
@@ -153,7 +140,7 @@ public class BooleanArrayListTest extends TestCase {
// expected
}
}
-
+
public void testSize() {
assertEquals(0, BooleanArrayList.emptyList().size());
assertEquals(1, UNARY_LIST.size());
@@ -164,26 +151,26 @@ public class BooleanArrayListTest extends TestCase {
list.addBoolean(false);
list.addBoolean(false);
assertEquals(4, list.size());
-
+
list.remove(0);
assertEquals(3, list.size());
-
+
list.add(true);
assertEquals(4, list.size());
}
-
+
public void testSet() {
list.addBoolean(false);
list.addBoolean(false);
-
+
assertEquals(false, (boolean) list.set(0, true));
assertEquals(true, list.getBoolean(0));
assertEquals(false, (boolean) list.set(1, false));
assertEquals(false, list.getBoolean(1));
-
+
try {
- list.set(-1, true);
+ list.set(-1, false);
fail();
} catch (IndexOutOfBoundsException e) {
// expected
@@ -196,17 +183,17 @@ public class BooleanArrayListTest extends TestCase {
// expected
}
}
-
- public void testSetInt() {
+
+ public void testSetBoolean() {
list.addBoolean(true);
list.addBoolean(true);
-
+
assertEquals(true, list.setBoolean(0, false));
assertEquals(false, list.getBoolean(0));
assertEquals(true, list.setBoolean(1, false));
assertEquals(false, list.getBoolean(1));
-
+
try {
list.setBoolean(-1, false);
fail();
@@ -215,76 +202,78 @@ public class BooleanArrayListTest extends TestCase {
}
try {
- list.setBoolean(2, true);
+ list.setBoolean(2, false);
fail();
} catch (IndexOutOfBoundsException e) {
// expected
}
}
-
+
public void testAdd() {
assertEquals(0, list.size());
- assertTrue(list.add(true));
- assertEquals(asList(true), list);
-
assertTrue(list.add(false));
+ assertEquals(asList(false), list);
+
+ assertTrue(list.add(true));
list.add(0, false);
- assertEquals(asList(false, true, false), list);
-
- list.add(0, false);
+ assertEquals(asList(false, false, true), list);
+
list.add(0, true);
+ list.add(0, false);
// Force a resize by getting up to 11 elements.
for (int i = 0; i < 6; i++) {
- list.add(true);
+ list.add(i % 2 == 0);
}
- assertEquals(asList(true, false, false, true, false, true, true, true, true, true, true), list);
-
+ assertEquals(
+ asList(false, true, false, false, true, true, false, true, false, true, false),
+ list);
+
try {
- list.add(-1, false);
+ list.add(-1, true);
} catch (IndexOutOfBoundsException e) {
// expected
}
-
+
try {
list.add(4, true);
} catch (IndexOutOfBoundsException e) {
// expected
}
}
-
- public void testAddInt() {
- assertEquals(0, list.size());
- list.addBoolean(true);
- assertEquals(asList(true), list);
+ public void testAddBoolean() {
+ assertEquals(0, list.size());
list.addBoolean(false);
- assertEquals(asList(true, false), list);
+ assertEquals(asList(false), list);
+
+ list.addBoolean(true);
+ assertEquals(asList(false, true), list);
}
-
+
public void testAddAll() {
assertEquals(0, list.size());
- assertTrue(list.addAll(Collections.singleton(false)));
+ assertTrue(list.addAll(Collections.singleton(true)));
assertEquals(1, list.size());
- assertEquals(false, (boolean) list.get(0));
- assertEquals(false, list.getBoolean(0));
-
- assertTrue(list.addAll(asList(true, false, false, false, true)));
- assertEquals(asList(false, true, false, false, false, true), list);
-
+ assertEquals(true, (boolean) list.get(0));
+ assertEquals(true, list.getBoolean(0));
+
+ assertTrue(list.addAll(asList(false, true, false, true, false)));
+ assertEquals(asList(true, false, true, false, true, false), list);
+
assertTrue(list.addAll(TERTIARY_LIST));
- assertEquals(asList(false, true, false, false, false, true, true, true, false), list);
+ assertEquals(asList(true, false, true, false, true, false, true, false, true), list);
assertFalse(list.addAll(Collections.<Boolean>emptyList()));
assertFalse(list.addAll(BooleanArrayList.emptyList()));
}
-
+
public void testRemove() {
list.addAll(TERTIARY_LIST);
assertEquals(true, (boolean) list.remove(0));
- assertEquals(asList(true, false), list);
+ assertEquals(asList(false, true), list);
assertTrue(list.remove(Boolean.TRUE));
assertEquals(asList(false), list);
@@ -294,96 +283,93 @@ public class BooleanArrayListTest extends TestCase {
assertEquals(false, (boolean) list.remove(0));
assertEquals(asList(), list);
-
+
try {
list.remove(-1);
fail();
} catch (IndexOutOfBoundsException e) {
// expected
}
-
+
try {
list.remove(0);
} catch (IndexOutOfBoundsException e) {
// expected
}
}
-
+
private void assertImmutable(BooleanArrayList list) {
- if (list.contains(1)) {
- throw new RuntimeException("Cannot test the immutability of lists that contain 1.");
- }
-
+
try {
- list.add(false);
+ list.add(true);
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.add(0, true);
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.addAll(Collections.<Boolean>emptyList());
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
- list.addAll(Collections.singletonList(false));
+ list.addAll(Collections.singletonList(true));
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.addAll(new BooleanArrayList());
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.addAll(UNARY_LIST);
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.addAll(0, Collections.singleton(true));
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.addAll(0, UNARY_LIST);
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.addAll(0, Collections.<Boolean>emptyList());
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
- list.addBoolean(true);
+ list.addBoolean(false);
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.clear();
fail();
@@ -397,63 +383,63 @@ public class BooleanArrayListTest extends TestCase {
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.remove(new Object());
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.removeAll(Collections.<Boolean>emptyList());
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
- list.removeAll(Collections.singleton(1));
+ list.removeAll(Collections.singleton(Boolean.TRUE));
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.removeAll(UNARY_LIST);
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.retainAll(Collections.<Boolean>emptyList());
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
- list.retainAll(Collections.singleton(1));
+ list.removeAll(Collections.singleton(Boolean.TRUE));
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.retainAll(UNARY_LIST);
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
- list.set(0, true);
+ list.set(0, false);
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.setBoolean(0, false);
fail();
@@ -461,7 +447,7 @@ public class BooleanArrayListTest extends TestCase {
// expected
}
}
-
+
private static BooleanArrayList newImmutableBooleanArrayList(boolean... elements) {
BooleanArrayList list = new BooleanArrayList();
for (boolean element : elements) {
diff --git a/java/src/test/java/com/google/protobuf/BoundedByteStringTest.java b/java/core/src/test/java/com/google/protobuf/BoundedByteStringTest.java
index 447e6ef3..db10ee74 100644
--- a/java/src/test/java/com/google/protobuf/BoundedByteStringTest.java
+++ b/java/core/src/test/java/com/google/protobuf/BoundedByteStringTest.java
@@ -37,7 +37,6 @@ import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.UnsupportedEncodingException;
-
/**
* This class tests {@link BoundedByteString}, which extends {@link LiteralByteString},
* by inheriting the tests from {@link LiteralByteStringTest}. The only method which
@@ -62,7 +61,7 @@ public class BoundedByteStringTest extends LiteralByteStringTest {
@Override
public void testToString() throws UnsupportedEncodingException {
String testString = "I love unicode \u1234\u5678 characters";
- LiteralByteString unicode = new LiteralByteString(testString.getBytes(Internal.UTF_8));
+ ByteString unicode = ByteString.wrap(testString.getBytes(Internal.UTF_8));
ByteString chopped = unicode.substring(2, unicode.size() - 6);
assertEquals(classUnderTest + ".substring() must have the expected type",
classUnderTest, getActualClassName(chopped));
@@ -73,9 +72,9 @@ public class BoundedByteStringTest extends LiteralByteStringTest {
}
@Override
- public void testCharsetToString() throws UnsupportedEncodingException {
+ public void testCharsetToString() {
String testString = "I love unicode \u1234\u5678 characters";
- LiteralByteString unicode = new LiteralByteString(testString.getBytes(Internal.UTF_8));
+ ByteString unicode = ByteString.wrap(testString.getBytes(Internal.UTF_8));
ByteString chopped = unicode.substring(2, unicode.size() - 6);
assertEquals(classUnderTest + ".substring() must have the expected type",
classUnderTest, getActualClassName(chopped));
diff --git a/java/core/src/test/java/com/google/protobuf/ByteBufferWriterTest.java b/java/core/src/test/java/com/google/protobuf/ByteBufferWriterTest.java
new file mode 100644
index 00000000..cbe742e5
--- /dev/null
+++ b/java/core/src/test/java/com/google/protobuf/ByteBufferWriterTest.java
@@ -0,0 +1,81 @@
+// 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.
+
+package com.google.protobuf;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.Random;
+
+/**
+ * Tests for {@link ByteBufferWriter}.
+ */
+public class ByteBufferWriterTest extends TestCase {
+
+ public void testHeapBuffer() throws IOException {
+ // Test a small and large buffer.
+ testWrite(ByteBuffer.allocate(100));
+ testWrite(ByteBuffer.allocate(1024 * 100));
+ }
+
+ public void testDirectBuffer() throws IOException {
+ // Test a small and large buffer.
+ testWrite(ByteBuffer.allocateDirect(100));
+ testWrite(ByteBuffer.allocateDirect(1024 * 100));
+ }
+
+ private void testWrite(ByteBuffer buffer) throws IOException {
+ fillRandom(buffer);
+ ByteArrayOutputStream os = new ByteArrayOutputStream(buffer.remaining());
+ ByteBufferWriter.write(buffer, os);
+ assertEquals(0, buffer.position());
+ assertTrue(Arrays.equals(toArray(buffer), os.toByteArray()));
+ }
+
+ private void fillRandom(ByteBuffer buf) {
+ byte[] bytes = new byte[buf.remaining()];
+ new Random().nextBytes(bytes);
+ buf.put(bytes);
+ buf.flip();
+ return;
+ }
+
+ private byte[] toArray(ByteBuffer buf) {
+ int originalPosition = buf.position();
+ byte[] bytes = new byte[buf.remaining()];
+ buf.get(bytes);
+ buf.position(originalPosition);
+ return bytes;
+ }
+}
diff --git a/java/src/test/java/com/google/protobuf/ByteStringTest.java b/java/core/src/test/java/com/google/protobuf/ByteStringTest.java
index 8af5dcde..ad9f266e 100644
--- a/java/src/test/java/com/google/protobuf/ByteStringTest.java
+++ b/java/core/src/test/java/com/google/protobuf/ByteStringTest.java
@@ -39,7 +39,7 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
+import java.lang.reflect.Field;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.ArrayList;
@@ -129,7 +129,7 @@ public class ByteStringTest extends TestCase {
isArrayRange(byteString.toByteArray(), bytes, 500, bytes.length - 500));
}
- public void testCopyFrom_StringEncoding() throws UnsupportedEncodingException {
+ public void testCopyFrom_StringEncoding() {
String testString = "I love unicode \u1234\u5678 characters";
ByteString byteString = ByteString.copyFrom(testString, UTF_16);
byte[] testBytes = testString.getBytes(UTF_16);
@@ -137,7 +137,7 @@ public class ByteStringTest extends TestCase {
isArrayRange(byteString.toByteArray(), testBytes, 0, testBytes.length));
}
- public void testCopyFrom_Utf8() throws UnsupportedEncodingException {
+ public void testCopyFrom_Utf8() {
String testString = "I love unicode \u1234\u5678 characters";
ByteString byteString = ByteString.copyFromUtf8(testString);
byte[] testBytes = testString.getBytes(Internal.UTF_8);
@@ -154,6 +154,7 @@ public class ByteStringTest extends TestCase {
isArrayRange(byteString.toByteArray(), testBytes, 0, testBytes.length));
// Call copyFrom on an iteration that's not a collection
ByteString byteStringAlt = ByteString.copyFrom(new Iterable<ByteString>() {
+ @Override
public Iterator<ByteString> iterator() {
return pieces.iterator();
}
@@ -399,7 +400,7 @@ public class ByteStringTest extends TestCase {
}
}
- public void testToStringUtf8() throws UnsupportedEncodingException {
+ public void testToStringUtf8() {
String testString = "I love unicode \u1234\u5678 characters";
byte[] testBytes = testString.getBytes(Internal.UTF_8);
ByteString byteString = ByteString.copyFrom(testBytes);
@@ -419,7 +420,7 @@ public class ByteStringTest extends TestCase {
// Test newOutput() using a variety of buffer sizes and a variety of (fixed)
// write sizes
- public void testNewOutput_ArrayWrite() throws IOException {
+ public void testNewOutput_ArrayWrite() {
byte[] bytes = getTestBytes();
int length = bytes.length;
int[] bufferSizes = {128, 256, length / 2, length - 1, length, length + 1,
@@ -442,7 +443,7 @@ public class ByteStringTest extends TestCase {
// Test newOutput() using a variety of buffer sizes, but writing all the
// characters using write(byte);
- public void testNewOutput_WriteChar() throws IOException {
+ public void testNewOutput_WriteChar() {
byte[] bytes = getTestBytes();
int length = bytes.length;
int[] bufferSizes = {0, 1, 128, 256, length / 2,
@@ -461,7 +462,7 @@ public class ByteStringTest extends TestCase {
// Test newOutput() in which we write the bytes using a variety of methods
// and sizes, and in which we repeatedly call toByteString() in the middle.
- public void testNewOutput_Mixed() throws IOException {
+ public void testNewOutput_Mixed() {
Random rng = new Random(1);
byte[] bytes = getTestBytes();
int length = bytes.length;
@@ -494,7 +495,7 @@ public class ByteStringTest extends TestCase {
}
}
- public void testNewOutputEmpty() throws IOException {
+ public void testNewOutputEmpty() {
// Make sure newOutput() correctly builds empty byte strings
ByteString byteString = ByteString.newOutput().toByteString();
assertEquals(ByteString.EMPTY, byteString);
@@ -655,11 +656,11 @@ public class ByteStringTest extends TestCase {
// trees of empty leaves, to make a string that will fail this test.
for (int i = 1; i < duo.size(); ++i) {
assertTrue("Substrings of size() < 2 must not be RopeByteStrings",
- duo.substring(i - 1, i) instanceof LiteralByteString);
+ duo.substring(i - 1, i) instanceof ByteString.LeafByteString);
}
for (int i = 1; i < quintet.size(); ++i) {
assertTrue("Substrings of size() < 2 must not be RopeByteStrings",
- quintet.substring(i - 1, i) instanceof LiteralByteString);
+ quintet.substring(i - 1, i) instanceof ByteString.LeafByteString);
}
}
@@ -724,7 +725,7 @@ public class ByteStringTest extends TestCase {
}
data1[1] = (byte) 11;
// Test LiteralByteString.writeTo(OutputStream,int,int)
- LiteralByteString left = new LiteralByteString(data1);
+ ByteString left = ByteString.wrap(data1);
byte[] result = substringUsingWriteTo(left, 1, 1);
assertEquals(1, result.length);
assertEquals((byte) 11, result[0]);
@@ -733,7 +734,7 @@ public class ByteStringTest extends TestCase {
for (int i = 0; i < data1.length; i++) {
data2[i] = (byte) 2;
}
- LiteralByteString right = new LiteralByteString(data2);
+ ByteString right = ByteString.wrap(data2);
// Concatenate two ByteStrings to create a RopeByteString.
ByteString root = left.concat(right);
// Make sure we are actually testing a RopeByteString with a simple tree
@@ -757,4 +758,17 @@ public class ByteStringTest extends TestCase {
assertEquals((byte) 2, result[dataSize - dataSize / 2]);
assertEquals((byte) 2, result[dataSize - 1]);
}
+
+ /**
+ * Tests ByteString uses Arrays based byte copier when running under Hotstop VM.
+ */
+ public void testByteArrayCopier() throws Exception {
+ Field field = ByteString.class.getDeclaredField("byteArrayCopier");
+ field.setAccessible(true);
+ Object byteArrayCopier = field.get(null);
+ assertNotNull(byteArrayCopier);
+ assertTrue(
+ byteArrayCopier.toString(),
+ byteArrayCopier.getClass().getSimpleName().endsWith("ArraysByteArrayCopier"));
+ }
}
diff --git a/java/src/test/java/com/google/protobuf/CheckUtf8Test.java b/java/core/src/test/java/com/google/protobuf/CheckUtf8Test.java
index 3d6381c9..cc65d19a 100644
--- a/java/src/test/java/com/google/protobuf/CheckUtf8Test.java
+++ b/java/core/src/test/java/com/google/protobuf/CheckUtf8Test.java
@@ -34,6 +34,7 @@ import proto2_test_check_utf8.TestCheckUtf8.BytesWrapper;
import proto2_test_check_utf8.TestCheckUtf8.StringWrapper;
import proto2_test_check_utf8_size.TestCheckUtf8Size.BytesWrapperSize;
import proto2_test_check_utf8_size.TestCheckUtf8Size.StringWrapperSize;
+
import junit.framework.TestCase;
/**
diff --git a/java/src/test/java/com/google/protobuf/CodedInputStreamTest.java b/java/core/src/test/java/com/google/protobuf/CodedInputStreamTest.java
index 18d8142c..ca940ced 100644
--- a/java/src/test/java/com/google/protobuf/CodedInputStreamTest.java
+++ b/java/core/src/test/java/com/google/protobuf/CodedInputStreamTest.java
@@ -81,10 +81,12 @@ public class CodedInputStreamTest extends TestCase {
this.blockSize = blockSize;
}
+ @Override
public int read(byte[] b) throws IOException {
return super.read(b, 0, Math.min(b.length, blockSize));
}
+ @Override
public int read(byte[] b, int off, int len) throws IOException {
return super.read(b, off, Math.min(len, blockSize));
}
@@ -547,6 +549,56 @@ public class CodedInputStreamTest extends TestCase {
}
}
+ public void testReadString() throws Exception {
+ String lorem = "Lorem ipsum dolor sit amet ";
+ StringBuilder builder = new StringBuilder();
+ for (int i = 0; i < 4096; i += lorem.length()) {
+ builder.append(lorem);
+ }
+ lorem = builder.toString().substring(0, 4096);
+ byte[] bytes = lorem.getBytes("UTF-8");
+ ByteString.Output rawOutput = ByteString.newOutput();
+ CodedOutputStream output = CodedOutputStream.newInstance(rawOutput, bytes.length);
+
+ int tag = WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ output.writeRawVarint32(tag);
+ output.writeRawVarint32(bytes.length);
+ output.writeRawBytes(bytes);
+ output.flush();
+
+ CodedInputStream input =
+ CodedInputStream.newInstance(
+ new ByteArrayInputStream(rawOutput.toByteString().toByteArray()));
+ assertEquals(tag, input.readTag());
+ String text = input.readString();
+ assertEquals(lorem, text);
+ }
+
+ public void testReadStringRequireUtf8() throws Exception {
+ String lorem = "Lorem ipsum dolor sit amet ";
+ StringBuilder builder = new StringBuilder();
+ for (int i = 0; i < 4096; i += lorem.length()) {
+ builder.append(lorem);
+ }
+ lorem = builder.toString().substring(0, 4096);
+ byte[] bytes = lorem.getBytes("UTF-8");
+ ByteString.Output rawOutput = ByteString.newOutput();
+ CodedOutputStream output = CodedOutputStream.newInstance(rawOutput, bytes.length);
+
+ int tag = WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ output.writeRawVarint32(tag);
+ output.writeRawVarint32(bytes.length);
+ output.writeRawBytes(bytes);
+ output.flush();
+
+ CodedInputStream input =
+ CodedInputStream.newInstance(
+ new ByteArrayInputStream(rawOutput.toByteString().toByteArray()));
+ assertEquals(tag, input.readTag());
+ String text = input.readStringRequireUtf8();
+ assertEquals(lorem, text);
+ }
+
/**
* Tests that if we readString invalid UTF-8 bytes, no exception
* is thrown. Instead, the invalid bytes are replaced with the Unicode
diff --git a/java/core/src/test/java/com/google/protobuf/CodedOutputStreamTest.java b/java/core/src/test/java/com/google/protobuf/CodedOutputStreamTest.java
new file mode 100644
index 00000000..33aa4357
--- /dev/null
+++ b/java/core/src/test/java/com/google/protobuf/CodedOutputStreamTest.java
@@ -0,0 +1,776 @@
+// 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.
+
+package com.google.protobuf;
+
+import com.google.protobuf.CodedOutputStream.OutOfSpaceException;
+import protobuf_unittest.UnittestProto.SparseEnumMessage;
+import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestPackedTypes;
+import protobuf_unittest.UnittestProto.TestSparseEnum;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Unit test for {@link CodedOutputStream}.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public class CodedOutputStreamTest extends TestCase {
+ private interface Coder {
+ CodedOutputStream stream();
+
+ byte[] toByteArray();
+
+ OutputType getOutputType();
+ }
+
+ private static final class OutputStreamCoder implements Coder {
+ private final CodedOutputStream stream;
+ private final ByteArrayOutputStream output;
+
+ OutputStreamCoder(int size) {
+ output = new ByteArrayOutputStream();
+ stream = CodedOutputStream.newInstance(output, size);
+ }
+
+ @Override
+ public CodedOutputStream stream() {
+ return stream;
+ }
+
+ @Override
+ public byte[] toByteArray() {
+ return output.toByteArray();
+ }
+
+ @Override
+ public OutputType getOutputType() {
+ return OutputType.STREAM;
+ }
+ }
+
+ private static final class ArrayCoder implements Coder {
+ private final CodedOutputStream stream;
+ private final byte[] bytes;
+
+ ArrayCoder(int size) {
+ bytes = new byte[size];
+ stream = CodedOutputStream.newInstance(bytes);
+ }
+
+ @Override
+ public CodedOutputStream stream() {
+ return stream;
+ }
+
+ @Override
+ public byte[] toByteArray() {
+ return Arrays.copyOf(bytes, stream.getTotalBytesWritten());
+ }
+
+ @Override
+ public OutputType getOutputType() {
+ return OutputType.ARRAY;
+ }
+ }
+
+ private static final class NioHeapCoder implements Coder {
+ private final CodedOutputStream stream;
+ private final ByteBuffer buffer;
+ private final int initialPosition;
+
+ NioHeapCoder(int size) {
+ this(size, 0);
+ }
+
+ NioHeapCoder(int size, int initialPosition) {
+ this.initialPosition = initialPosition;
+ buffer = ByteBuffer.allocate(size);
+ buffer.position(initialPosition);
+ stream = CodedOutputStream.newInstance(buffer);
+ }
+
+ @Override
+ public CodedOutputStream stream() {
+ return stream;
+ }
+
+ @Override
+ public byte[] toByteArray() {
+ ByteBuffer dup = buffer.duplicate();
+ dup.position(initialPosition);
+ dup.limit(buffer.position());
+
+ byte[] bytes = new byte[dup.remaining()];
+ dup.get(bytes);
+ return bytes;
+ }
+
+ @Override
+ public OutputType getOutputType() {
+ return OutputType.NIO_HEAP;
+ }
+ }
+
+ private static final class NioDirectCoder implements Coder {
+ private final int initialPosition;
+ private final CodedOutputStream stream;
+ private final ByteBuffer buffer;
+
+ NioDirectCoder(int size) {
+ this(size, 0);
+ }
+
+ NioDirectCoder(int size, int initialPosition) {
+ this.initialPosition = initialPosition;
+ buffer = ByteBuffer.allocateDirect(size);
+ buffer.position(initialPosition);
+ stream = CodedOutputStream.newInstance(buffer);
+ }
+
+ @Override
+ public CodedOutputStream stream() {
+ return stream;
+ }
+
+ @Override
+ public byte[] toByteArray() {
+ ByteBuffer dup = buffer.duplicate();
+ dup.position(initialPosition);
+ dup.limit(buffer.position());
+
+ byte[] bytes = new byte[dup.remaining()];
+ dup.get(bytes);
+ return bytes;
+ }
+
+ @Override
+ public OutputType getOutputType() {
+ return OutputType.NIO_DIRECT;
+ }
+ }
+
+ private enum OutputType {
+ ARRAY() {
+ @Override
+ Coder newCoder(int size) {
+ return new ArrayCoder(size);
+ }
+ },
+ NIO_HEAP() {
+ @Override
+ Coder newCoder(int size) {
+ return new NioHeapCoder(size);
+ }
+ },
+ NIO_DIRECT() {
+ @Override
+ Coder newCoder(int size) {
+ return new NioDirectCoder(size);
+ }
+ },
+ STREAM() {
+ @Override
+ Coder newCoder(int size) {
+ return new OutputStreamCoder(size);
+ }
+ };
+
+ abstract Coder newCoder(int size);
+ }
+
+ /** Checks that invariants are maintained for varint round trip input and output. */
+ public void testVarintRoundTrips() throws Exception {
+ for (OutputType outputType : OutputType.values()) {
+ assertVarintRoundTrip(outputType, 0L);
+ for (int bits = 0; bits < 64; bits++) {
+ long value = 1L << bits;
+ assertVarintRoundTrip(outputType, value);
+ assertVarintRoundTrip(outputType, value + 1);
+ assertVarintRoundTrip(outputType, value - 1);
+ assertVarintRoundTrip(outputType, -value);
+ }
+ }
+ }
+
+ /** Tests writeRawVarint32() and writeRawVarint64(). */
+ public void testWriteVarint() throws Exception {
+ assertWriteVarint(bytes(0x00), 0);
+ assertWriteVarint(bytes(0x01), 1);
+ assertWriteVarint(bytes(0x7f), 127);
+ // 14882
+ assertWriteVarint(bytes(0xa2, 0x74), (0x22 << 0) | (0x74 << 7));
+ // 2961488830
+ assertWriteVarint(
+ bytes(0xbe, 0xf7, 0x92, 0x84, 0x0b),
+ (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) | (0x0bL << 28));
+
+ // 64-bit
+ // 7256456126
+ assertWriteVarint(
+ bytes(0xbe, 0xf7, 0x92, 0x84, 0x1b),
+ (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) | (0x1bL << 28));
+ // 41256202580718336
+ assertWriteVarint(
+ bytes(0x80, 0xe6, 0xeb, 0x9c, 0xc3, 0xc9, 0xa4, 0x49),
+ (0x00 << 0) | (0x66 << 7) | (0x6b << 14) | (0x1c << 21) | (0x43L << 28) | (0x49L << 35)
+ | (0x24L << 42) | (0x49L << 49));
+ // 11964378330978735131
+ assertWriteVarint(
+ bytes(0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85, 0xa6, 0x01),
+ (0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) | (0x3bL << 28) | (0x56L << 35)
+ | (0x00L << 42) | (0x05L << 49) | (0x26L << 56) | (0x01L << 63));
+ }
+
+ /** Tests writeRawLittleEndian32() and writeRawLittleEndian64(). */
+ public void testWriteLittleEndian() throws Exception {
+ assertWriteLittleEndian32(bytes(0x78, 0x56, 0x34, 0x12), 0x12345678);
+ assertWriteLittleEndian32(bytes(0xf0, 0xde, 0xbc, 0x9a), 0x9abcdef0);
+
+ assertWriteLittleEndian64(
+ bytes(0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12), 0x123456789abcdef0L);
+ assertWriteLittleEndian64(
+ bytes(0x78, 0x56, 0x34, 0x12, 0xf0, 0xde, 0xbc, 0x9a), 0x9abcdef012345678L);
+ }
+
+ /** Test encodeZigZag32() and encodeZigZag64(). */
+ public void testEncodeZigZag() throws Exception {
+ assertEquals(0, CodedOutputStream.encodeZigZag32(0));
+ assertEquals(1, CodedOutputStream.encodeZigZag32(-1));
+ assertEquals(2, CodedOutputStream.encodeZigZag32(1));
+ assertEquals(3, CodedOutputStream.encodeZigZag32(-2));
+ assertEquals(0x7FFFFFFE, CodedOutputStream.encodeZigZag32(0x3FFFFFFF));
+ assertEquals(0x7FFFFFFF, CodedOutputStream.encodeZigZag32(0xC0000000));
+ assertEquals(0xFFFFFFFE, CodedOutputStream.encodeZigZag32(0x7FFFFFFF));
+ assertEquals(0xFFFFFFFF, CodedOutputStream.encodeZigZag32(0x80000000));
+
+ assertEquals(0, CodedOutputStream.encodeZigZag64(0));
+ assertEquals(1, CodedOutputStream.encodeZigZag64(-1));
+ assertEquals(2, CodedOutputStream.encodeZigZag64(1));
+ assertEquals(3, CodedOutputStream.encodeZigZag64(-2));
+ assertEquals(0x000000007FFFFFFEL, CodedOutputStream.encodeZigZag64(0x000000003FFFFFFFL));
+ assertEquals(0x000000007FFFFFFFL, CodedOutputStream.encodeZigZag64(0xFFFFFFFFC0000000L));
+ assertEquals(0x00000000FFFFFFFEL, CodedOutputStream.encodeZigZag64(0x000000007FFFFFFFL));
+ assertEquals(0x00000000FFFFFFFFL, CodedOutputStream.encodeZigZag64(0xFFFFFFFF80000000L));
+ assertEquals(0xFFFFFFFFFFFFFFFEL, CodedOutputStream.encodeZigZag64(0x7FFFFFFFFFFFFFFFL));
+ assertEquals(0xFFFFFFFFFFFFFFFFL, CodedOutputStream.encodeZigZag64(0x8000000000000000L));
+
+ // Some easier-to-verify round-trip tests. The inputs (other than 0, 1, -1)
+ // were chosen semi-randomly via keyboard bashing.
+ assertEquals(0, CodedOutputStream.encodeZigZag32(CodedInputStream.decodeZigZag32(0)));
+ assertEquals(1, CodedOutputStream.encodeZigZag32(CodedInputStream.decodeZigZag32(1)));
+ assertEquals(-1, CodedOutputStream.encodeZigZag32(CodedInputStream.decodeZigZag32(-1)));
+ assertEquals(14927, CodedOutputStream.encodeZigZag32(CodedInputStream.decodeZigZag32(14927)));
+ assertEquals(-3612, CodedOutputStream.encodeZigZag32(CodedInputStream.decodeZigZag32(-3612)));
+
+ assertEquals(0, CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(0)));
+ assertEquals(1, CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(1)));
+ assertEquals(-1, CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(-1)));
+ assertEquals(14927, CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(14927)));
+ assertEquals(-3612, CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(-3612)));
+
+ assertEquals(
+ 856912304801416L,
+ CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(856912304801416L)));
+ assertEquals(
+ -75123905439571256L,
+ CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(-75123905439571256L)));
+ }
+
+ /** Tests writing a whole message with every field type. */
+ public void testWriteWholeMessage() throws Exception {
+ final byte[] expectedBytes = TestUtil.getGoldenMessage().toByteArray();
+ TestAllTypes message = TestUtil.getAllSet();
+
+ for (OutputType outputType : OutputType.values()) {
+ Coder coder = outputType.newCoder(message.getSerializedSize());
+ message.writeTo(coder.stream());
+ coder.stream().flush();
+ byte[] rawBytes = coder.toByteArray();
+ assertEqualBytes(outputType, expectedBytes, rawBytes);
+ }
+
+ // Try different block sizes.
+ for (int blockSize = 1; blockSize < 256; blockSize *= 2) {
+ Coder coder = OutputType.STREAM.newCoder(blockSize);
+ message.writeTo(coder.stream());
+ coder.stream().flush();
+ assertEqualBytes(OutputType.STREAM, expectedBytes, coder.toByteArray());
+ }
+ }
+
+ /**
+ * Tests writing a whole message with every packed field type. Ensures the
+ * wire format of packed fields is compatible with C++.
+ */
+ public void testWriteWholePackedFieldsMessage() throws Exception {
+ byte[] expectedBytes = TestUtil.getGoldenPackedFieldsMessage().toByteArray();
+ TestPackedTypes message = TestUtil.getPackedSet();
+
+ for (OutputType outputType : OutputType.values()) {
+ Coder coder = outputType.newCoder(message.getSerializedSize());
+ message.writeTo(coder.stream());
+ coder.stream().flush();
+ byte[] rawBytes = coder.toByteArray();
+ assertEqualBytes(outputType, expectedBytes, rawBytes);
+ }
+ }
+
+ /**
+ * Test writing a message containing a negative enum value. This used to
+ * fail because the size was not properly computed as a sign-extended varint.
+ */
+ public void testWriteMessageWithNegativeEnumValue() throws Exception {
+ SparseEnumMessage message =
+ SparseEnumMessage.newBuilder().setSparseEnum(TestSparseEnum.SPARSE_E).build();
+ assertTrue(message.getSparseEnum().getNumber() < 0);
+ for (OutputType outputType : OutputType.values()) {
+ Coder coder = outputType.newCoder(message.getSerializedSize());
+ message.writeTo(coder.stream());
+ coder.stream().flush();
+ byte[] rawBytes = coder.toByteArray();
+ SparseEnumMessage message2 = SparseEnumMessage.parseFrom(rawBytes);
+ assertEquals(TestSparseEnum.SPARSE_E, message2.getSparseEnum());
+ }
+ }
+
+ /** Test getTotalBytesWritten() */
+ public void testGetTotalBytesWritten() throws Exception {
+ Coder coder = OutputType.STREAM.newCoder(4 * 1024);
+
+ // Write some some bytes (more than the buffer can hold) and verify that totalWritten
+ // is correct.
+ byte[] value = "abcde".getBytes(Internal.UTF_8);
+ for (int i = 0; i < 1024; ++i) {
+ coder.stream().writeRawBytes(value, 0, value.length);
+ }
+ assertEquals(value.length * 1024, coder.stream().getTotalBytesWritten());
+
+ // Now write an encoded string.
+ String string =
+ "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz";
+ // Ensure we take the slower fast path.
+ assertTrue(CodedOutputStream.computeUInt32SizeNoTag(string.length())
+ != CodedOutputStream.computeUInt32SizeNoTag(string.length() * Utf8.MAX_BYTES_PER_CHAR));
+
+ coder.stream().writeStringNoTag(string);
+ int stringSize = CodedOutputStream.computeStringSizeNoTag(string);
+
+ // Verify that the total bytes written is correct
+ assertEquals((value.length * 1024) + stringSize, coder.stream().getTotalBytesWritten());
+ }
+
+ // TODO(dweis): Write a comprehensive test suite for CodedOutputStream that covers more than just
+ // this case.
+ public void testWriteStringNoTag_fastpath() throws Exception {
+ int bufferSize = 153;
+ String threeBytesPer = "\u0981";
+ String string = threeBytesPer;
+ for (int i = 0; i < 50; i++) {
+ string += threeBytesPer;
+ }
+ // These checks ensure we will tickle the slower fast path.
+ assertEquals(1, CodedOutputStream.computeUInt32SizeNoTag(string.length()));
+ assertEquals(
+ 2, CodedOutputStream.computeUInt32SizeNoTag(string.length() * Utf8.MAX_BYTES_PER_CHAR));
+ assertEquals(bufferSize, string.length() * Utf8.MAX_BYTES_PER_CHAR);
+
+ for (OutputType outputType : OutputType.values()) {
+ Coder coder = outputType.newCoder(bufferSize + 2);
+ coder.stream().writeStringNoTag(string);
+ coder.stream().flush();
+ }
+ }
+
+ public void testWriteToByteBuffer() throws Exception {
+ final int bufferSize = 16 * 1024;
+ ByteBuffer buffer = ByteBuffer.allocate(bufferSize);
+ CodedOutputStream codedStream = CodedOutputStream.newInstance(buffer);
+ // Write raw bytes into the ByteBuffer.
+ final int length1 = 5000;
+ for (int i = 0; i < length1; i++) {
+ codedStream.writeRawByte((byte) 1);
+ }
+ final int length2 = 8 * 1024;
+ byte[] data = new byte[length2];
+ for (int i = 0; i < length2; i++) {
+ data[i] = (byte) 2;
+ }
+ codedStream.writeRawBytes(data);
+ final int length3 = bufferSize - length1 - length2;
+ for (int i = 0; i < length3; i++) {
+ codedStream.writeRawByte((byte) 3);
+ }
+ codedStream.flush();
+
+ // Check that data is correctly written to the ByteBuffer.
+ assertEquals(0, buffer.remaining());
+ buffer.flip();
+ for (int i = 0; i < length1; i++) {
+ assertEquals((byte) 1, buffer.get());
+ }
+ for (int i = 0; i < length2; i++) {
+ assertEquals((byte) 2, buffer.get());
+ }
+ for (int i = 0; i < length3; i++) {
+ assertEquals((byte) 3, buffer.get());
+ }
+ }
+
+ public void testWriteByteBuffer() throws Exception {
+ byte[] value = "abcde".getBytes(Internal.UTF_8);
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ CodedOutputStream codedStream = CodedOutputStream.newInstance(outputStream);
+ ByteBuffer byteBuffer = ByteBuffer.wrap(value, 0, 1);
+ // This will actually write 5 bytes into the CodedOutputStream as the
+ // ByteBuffer's capacity() is 5.
+ codedStream.writeRawBytes(byteBuffer);
+ // The above call shouldn't affect the ByteBuffer's state.
+ assertEquals(0, byteBuffer.position());
+ assertEquals(1, byteBuffer.limit());
+
+ // The correct way to write part of an array using ByteBuffer.
+ codedStream.writeRawBytes(ByteBuffer.wrap(value, 2, 1).slice());
+
+ codedStream.flush();
+ byte[] result = outputStream.toByteArray();
+ assertEquals(6, result.length);
+ for (int i = 0; i < 5; i++) {
+ assertEquals(value[i], result[i]);
+ }
+ assertEquals(value[2], result[5]);
+ }
+
+ public void testWriteByteArrayWithOffsets() throws Exception {
+ byte[] fullArray = bytes(0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88);
+ byte[] destination = new byte[4];
+ CodedOutputStream codedStream = CodedOutputStream.newInstance(destination);
+ codedStream.writeByteArrayNoTag(fullArray, 2, 2);
+ assertEqualBytes(OutputType.ARRAY, bytes(0x02, 0x33, 0x44, 0x00), destination);
+ assertEquals(3, codedStream.getTotalBytesWritten());
+ }
+
+ public void testSerializeUtf8_MultipleSmallWrites() throws Exception {
+ final String source = "abcdefghijklmnopqrstuvwxyz";
+
+ // Generate the expected output if the source string is written 2 bytes at a time.
+ ByteArrayOutputStream expectedBytesStream = new ByteArrayOutputStream();
+ for (int pos = 0; pos < source.length(); pos += 2) {
+ String substr = source.substring(pos, pos + 2);
+ expectedBytesStream.write(2);
+ expectedBytesStream.write(substr.getBytes(Internal.UTF_8));
+ }
+ final byte[] expectedBytes = expectedBytesStream.toByteArray();
+
+ // For each output type, write the source string 2 bytes at a time and verify the output.
+ for (OutputType outputType : OutputType.values()) {
+ Coder coder = outputType.newCoder(expectedBytes.length);
+ for (int pos = 0; pos < source.length(); pos += 2) {
+ String substr = source.substring(pos, pos + 2);
+ coder.stream().writeStringNoTag(substr);
+ }
+ coder.stream().flush();
+ assertEqualBytes(outputType, expectedBytes, coder.toByteArray());
+ }
+ }
+
+ public void testSerializeInvalidUtf8() throws Exception {
+ String[] invalidStrings = new String[] {newString(Character.MIN_HIGH_SURROGATE),
+ "foobar" + newString(Character.MIN_HIGH_SURROGATE), newString(Character.MIN_LOW_SURROGATE),
+ "foobar" + newString(Character.MIN_LOW_SURROGATE),
+ newString(Character.MIN_HIGH_SURROGATE, Character.MIN_HIGH_SURROGATE)};
+
+ CodedOutputStream outputWithStream = CodedOutputStream.newInstance(new ByteArrayOutputStream());
+ CodedOutputStream outputWithArray = CodedOutputStream.newInstance(new byte[10000]);
+ CodedOutputStream outputWithByteBuffer =
+ CodedOutputStream.newInstance(ByteBuffer.allocate(10000));
+ for (String s : invalidStrings) {
+ // TODO(dweis): These should all fail; instead they are corrupting data.
+ CodedOutputStream.computeStringSizeNoTag(s);
+ outputWithStream.writeStringNoTag(s);
+ outputWithArray.writeStringNoTag(s);
+ outputWithByteBuffer.writeStringNoTag(s);
+ }
+ }
+
+ // TODO(nathanmittler): This test can be deleted once we properly throw IOException while
+ // encoding invalid UTF-8 strings.
+ public void testSerializeInvalidUtf8FollowedByOutOfSpace() throws Exception {
+ final int notEnoughBytes = 4;
+ CodedOutputStream outputWithArray = CodedOutputStream.newInstance(new byte[notEnoughBytes]);
+ CodedOutputStream outputWithByteBuffer =
+ CodedOutputStream.newInstance(ByteBuffer.allocate(notEnoughBytes));
+
+ String invalidString = newString(Character.MIN_HIGH_SURROGATE, 'f', 'o', 'o', 'b', 'a', 'r');
+ try {
+ outputWithArray.writeStringNoTag(invalidString);
+ fail("Expected OutOfSpaceException");
+ } catch (OutOfSpaceException e) {
+ assertTrue(e.getCause() instanceof IndexOutOfBoundsException);
+ }
+ try {
+ outputWithByteBuffer.writeStringNoTag(invalidString);
+ fail("Expected OutOfSpaceException");
+ } catch (OutOfSpaceException e) {
+ assertTrue(e.getCause() instanceof IndexOutOfBoundsException);
+ }
+ }
+
+ /** Regression test for https://github.com/google/protobuf/issues/292 */
+ public void testCorrectExceptionThrowWhenEncodingStringsWithoutEnoughSpace() throws Exception {
+ String testCase = "Foooooooo";
+ assertEquals(
+ CodedOutputStream.computeUInt32SizeNoTag(testCase.length()),
+ CodedOutputStream.computeUInt32SizeNoTag(testCase.length() * 3));
+ assertEquals(11, CodedOutputStream.computeStringSize(1, testCase));
+ // Tag is one byte, varint describing string length is 1 byte, string length is 9 bytes.
+ // An array of size 1 will cause a failure when trying to write the varint.
+ for (OutputType outputType :
+ new OutputType[] {OutputType.ARRAY, OutputType.NIO_HEAP, OutputType.NIO_DIRECT}) {
+ for (int i = 0; i < 11; i++) {
+ Coder coder = outputType.newCoder(i);
+ try {
+ coder.stream().writeString(1, testCase);
+ fail("Should have thrown an out of space exception");
+ } catch (CodedOutputStream.OutOfSpaceException expected) {
+ }
+ }
+ }
+ }
+
+ public void testDifferentStringLengths() throws Exception {
+ // Test string serialization roundtrip using strings of the following lengths,
+ // with ASCII and Unicode characters requiring different UTF-8 byte counts per
+ // char, hence causing the length delimiter varint to sometimes require more
+ // bytes for the Unicode strings than the ASCII string of the same length.
+ int[] lengths = new int[] {
+ 0,
+ 1,
+ (1 << 4) - 1, // 1 byte for ASCII and Unicode
+ (1 << 7) - 1, // 1 byte for ASCII, 2 bytes for Unicode
+ (1 << 11) - 1, // 2 bytes for ASCII and Unicode
+ (1 << 14) - 1, // 2 bytes for ASCII, 3 bytes for Unicode
+ (1 << 17) - 1,
+ // 3 bytes for ASCII and Unicode
+ };
+ for (OutputType outputType : OutputType.values()) {
+ for (int i : lengths) {
+ testEncodingOfString(outputType, 'q', i); // 1 byte per char
+ testEncodingOfString(outputType, '\u07FF', i); // 2 bytes per char
+ testEncodingOfString(outputType, '\u0981', i); // 3 bytes per char
+ }
+ }
+ }
+
+ public void testNioEncodersWithInitialOffsets() throws Exception {
+ String value = "abc";
+ for (Coder coder : new Coder[] {new NioHeapCoder(10, 2), new NioDirectCoder(10, 2)}) {
+ coder.stream().writeStringNoTag(value);
+ coder.stream().flush();
+ assertEqualBytes(coder.getOutputType(), new byte[]{3, 'a', 'b', 'c'}, coder.toByteArray());
+ }
+ }
+
+ /**
+ * Parses the given bytes using writeRawLittleEndian32() and checks
+ * that the result matches the given value.
+ */
+ private static void assertWriteLittleEndian32(byte[] data, int value) throws Exception {
+ for (OutputType outputType : OutputType.values()) {
+ Coder coder = outputType.newCoder(data.length);
+ coder.stream().writeFixed32NoTag(value);
+ coder.stream().flush();
+ assertEqualBytes(outputType, data, coder.toByteArray());
+ }
+
+ // Try different block sizes.
+ for (int blockSize = 1; blockSize <= 16; blockSize *= 2) {
+ Coder coder = OutputType.STREAM.newCoder(blockSize);
+ coder.stream().writeFixed32NoTag(value);
+ coder.stream().flush();
+ assertEqualBytes(OutputType.STREAM, data, coder.toByteArray());
+ }
+ }
+
+ /**
+ * Parses the given bytes using writeRawLittleEndian64() and checks
+ * that the result matches the given value.
+ */
+ private static void assertWriteLittleEndian64(byte[] data, long value) throws Exception {
+ for (OutputType outputType : OutputType.values()) {
+ Coder coder = outputType.newCoder(data.length);
+ coder.stream().writeFixed64NoTag(value);
+ coder.stream().flush();
+ assertEqualBytes(outputType, data, coder.toByteArray());
+ }
+
+ // Try different block sizes.
+ for (int blockSize = 1; blockSize <= 16; blockSize *= 2) {
+ Coder coder = OutputType.STREAM.newCoder(blockSize);
+ coder.stream().writeFixed64NoTag(value);
+ coder.stream().flush();
+ assertEqualBytes(OutputType.STREAM, data, coder.toByteArray());
+ }
+ }
+
+ private static String newString(char... chars) {
+ return new String(chars);
+ }
+
+ private static void testEncodingOfString(OutputType outputType, char c, int length)
+ throws Exception {
+ String fullString = fullString(c, length);
+ TestAllTypes testAllTypes = TestAllTypes.newBuilder().setOptionalString(fullString).build();
+ Coder coder = outputType.newCoder(testAllTypes.getSerializedSize());
+ testAllTypes.writeTo(coder.stream());
+ coder.stream().flush();
+ assertEquals(
+ "OuputType: " + outputType,
+ fullString,
+ TestAllTypes.parseFrom(coder.toByteArray()).getOptionalString());
+ }
+
+ private static String fullString(char c, int length) {
+ char[] result = new char[length];
+ Arrays.fill(result, c);
+ return new String(result);
+ }
+
+ /**
+ * Helper to construct a byte array from a bunch of bytes. The inputs are
+ * actually ints so that I can use hex notation and not get stupid errors
+ * about precision.
+ */
+ private static byte[] bytes(int... bytesAsInts) {
+ byte[] bytes = new byte[bytesAsInts.length];
+ for (int i = 0; i < bytesAsInts.length; i++) {
+ bytes[i] = (byte) bytesAsInts[i];
+ }
+ return bytes;
+ }
+
+ /** Arrays.asList() does not work with arrays of primitives. :( */
+ private static List<Byte> toList(byte[] bytes) {
+ List<Byte> result = new ArrayList<Byte>();
+ for (byte b : bytes) {
+ result.add(b);
+ }
+ return result;
+ }
+
+ private static void assertEqualBytes(OutputType outputType, byte[] a, byte[] b) {
+ assertEquals(outputType.name(), toList(a), toList(b));
+ }
+
+ /**
+ * Writes the given value using writeRawVarint32() and writeRawVarint64() and
+ * checks that the result matches the given bytes.
+ */
+ private static void assertWriteVarint(byte[] data, long value) throws Exception {
+ for (OutputType outputType : OutputType.values()) {
+ // Only test 32-bit write if the value fits into an int.
+ if (value == (int) value) {
+ Coder coder = outputType.newCoder(10);
+ coder.stream().writeUInt32NoTag((int) value);
+ coder.stream().flush();
+ assertEqualBytes(outputType, data, coder.toByteArray());
+
+ // Also try computing size.
+ assertEquals(data.length, CodedOutputStream.computeUInt32SizeNoTag((int) value));
+ }
+
+ {
+ Coder coder = outputType.newCoder(10);
+ coder.stream().writeUInt64NoTag(value);
+ coder.stream().flush();
+ assertEqualBytes(outputType, data, coder.toByteArray());
+
+ // Also try computing size.
+ assertEquals(data.length, CodedOutputStream.computeUInt64SizeNoTag(value));
+ }
+ }
+
+ // Try different block sizes.
+ for (int blockSize = 1; blockSize <= 16; blockSize *= 2) {
+ // Only test 32-bit write if the value fits into an int.
+ if (value == (int) value) {
+ Coder coder = OutputType.STREAM.newCoder(blockSize);
+ coder.stream().writeUInt64NoTag((int) value);
+ coder.stream().flush();
+ assertEqualBytes(OutputType.STREAM, data, coder.toByteArray());
+
+ ByteArrayOutputStream rawOutput = new ByteArrayOutputStream();
+ CodedOutputStream output = CodedOutputStream.newInstance(rawOutput, blockSize);
+ output.writeUInt32NoTag((int) value);
+ output.flush();
+ assertEqualBytes(OutputType.STREAM, data, rawOutput.toByteArray());
+ }
+
+ {
+ Coder coder = OutputType.STREAM.newCoder(blockSize);
+ coder.stream().writeUInt64NoTag(value);
+ coder.stream().flush();
+ assertEqualBytes(OutputType.STREAM, data, coder.toByteArray());
+ }
+ }
+ }
+
+ private static void assertVarintRoundTrip(OutputType outputType, long value) throws Exception {
+ {
+ Coder coder = outputType.newCoder(10);
+ coder.stream().writeUInt64NoTag(value);
+ coder.stream().flush();
+ byte[] bytes = coder.toByteArray();
+ assertEquals(
+ outputType.name(), bytes.length, CodedOutputStream.computeUInt64SizeNoTag(value));
+ CodedInputStream input = CodedInputStream.newInstance(new ByteArrayInputStream(bytes));
+ assertEquals(outputType.name(), value, input.readRawVarint64());
+ }
+
+ if (value == (int) value) {
+ Coder coder = outputType.newCoder(10);
+ coder.stream().writeUInt32NoTag((int) value);
+ coder.stream().flush();
+ byte[] bytes = coder.toByteArray();
+ assertEquals(
+ outputType.name(), bytes.length, CodedOutputStream.computeUInt32SizeNoTag((int) value));
+ CodedInputStream input = CodedInputStream.newInstance(new ByteArrayInputStream(bytes));
+ assertEquals(outputType.name(), value, input.readRawVarint32());
+ }
+ }
+}
diff --git a/java/src/test/java/com/google/protobuf/DeprecatedFieldTest.java b/java/core/src/test/java/com/google/protobuf/DeprecatedFieldTest.java
index e7905f79..ce85ae2e 100644
--- a/java/src/test/java/com/google/protobuf/DeprecatedFieldTest.java
+++ b/java/core/src/test/java/com/google/protobuf/DeprecatedFieldTest.java
@@ -36,6 +36,7 @@ import junit.framework.TestCase;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Method;
+
/**
* Test field deprecation
*
diff --git a/java/src/test/java/com/google/protobuf/DescriptorsTest.java b/java/core/src/test/java/com/google/protobuf/DescriptorsTest.java
index 30da2487..b3302441 100644
--- a/java/src/test/java/com/google/protobuf/DescriptorsTest.java
+++ b/java/core/src/test/java/com/google/protobuf/DescriptorsTest.java
@@ -59,7 +59,6 @@ import protobuf_unittest.UnittestProto.TestMultipleExtensionRanges;
import protobuf_unittest.UnittestProto.TestRequired;
import protobuf_unittest.UnittestProto.TestReservedFields;
import protobuf_unittest.UnittestProto.TestService;
-
import junit.framework.TestCase;
import java.util.Arrays;
@@ -274,6 +273,15 @@ public class DescriptorsTest extends TestCase {
assertFalse(repeatedField.isRequired());
assertTrue(repeatedField.isRepeated());
}
+
+ public void testFieldDescriptorJsonName() throws Exception {
+ FieldDescriptor requiredField = TestRequired.getDescriptor().findFieldByName("a");
+ FieldDescriptor optionalField = TestAllTypes.getDescriptor().findFieldByName("optional_int32");
+ FieldDescriptor repeatedField = TestAllTypes.getDescriptor().findFieldByName("repeated_int32");
+ assertEquals("a", requiredField.getJsonName());
+ assertEquals("optionalInt32", optionalField.getJsonName());
+ assertEquals("repeatedInt32", repeatedField.getJsonName());
+ }
public void testFieldDescriptorDefault() throws Exception {
Descriptor d = TestAllTypes.getDescriptor();
@@ -374,6 +382,14 @@ public class DescriptorsTest extends TestCase {
assertEquals(Long.valueOf(8765432109L),
field.getOptions().getExtension(UnittestCustomOptions.fieldOpt1));
+ OneofDescriptor oneof = descriptor.getOneofs().get(0);
+ assertNotNull(oneof);
+
+ assertTrue(
+ oneof.getOptions().hasExtension(UnittestCustomOptions.oneofOpt1));
+ assertEquals(Integer.valueOf(-99),
+ oneof.getOptions().getExtension(UnittestCustomOptions.oneofOpt1));
+
EnumDescriptor enumType =
UnittestCustomOptions.TestMessageWithCustomOptions.AnEnum.getDescriptor();
@@ -564,6 +580,42 @@ public class DescriptorsTest extends TestCase {
}
}
+ public void testUnknownFieldsDenied() throws Exception {
+ FileDescriptorProto fooProto = FileDescriptorProto.newBuilder()
+ .setName("foo.proto")
+ .addMessageType(DescriptorProto.newBuilder()
+ .setName("Foo")
+ .addField(FieldDescriptorProto.newBuilder()
+ .setLabel(FieldDescriptorProto.Label.LABEL_OPTIONAL)
+ .setTypeName("Bar")
+ .setName("bar")
+ .setNumber(1)))
+ .build();
+
+ try {
+ Descriptors.FileDescriptor.buildFrom(fooProto, new FileDescriptor[0]);
+ fail("DescriptorValidationException expected");
+ } catch (DescriptorValidationException e) {
+ assertTrue(e.getMessage().indexOf("Bar") != -1);
+ assertTrue(e.getMessage().indexOf("is not defined") != -1);
+ }
+ }
+
+ public void testUnknownFieldsAllowed() throws Exception {
+ FileDescriptorProto fooProto = FileDescriptorProto.newBuilder()
+ .setName("foo.proto")
+ .addDependency("bar.proto")
+ .addMessageType(DescriptorProto.newBuilder()
+ .setName("Foo")
+ .addField(FieldDescriptorProto.newBuilder()
+ .setLabel(FieldDescriptorProto.Label.LABEL_OPTIONAL)
+ .setTypeName("Bar")
+ .setName("bar")
+ .setNumber(1)))
+ .build();
+ Descriptors.FileDescriptor.buildFrom(fooProto, new FileDescriptor[0], true);
+ }
+
public void testHiddenDependency() throws Exception {
FileDescriptorProto barProto = FileDescriptorProto.newBuilder()
.setName("bar.proto")
diff --git a/java/src/test/java/com/google/protobuf/DoubleArrayListTest.java b/java/core/src/test/java/com/google/protobuf/DoubleArrayListTest.java
index e7a73d70..8e8e4fe2 100644
--- a/java/src/test/java/com/google/protobuf/DoubleArrayListTest.java
+++ b/java/core/src/test/java/com/google/protobuf/DoubleArrayListTest.java
@@ -40,53 +40,40 @@ import java.util.Iterator;
/**
* Tests for {@link DoubleArrayList}.
- *
+ *
* @author dweis@google.com (Daniel Weis)
*/
public class DoubleArrayListTest extends TestCase {
-
- private static final DoubleArrayList UNARY_LIST = newImmutableDoubleArrayList(1);
+
+ private static final DoubleArrayList UNARY_LIST =
+ newImmutableDoubleArrayList(1);
private static final DoubleArrayList TERTIARY_LIST =
newImmutableDoubleArrayList(1, 2, 3);
-
+
private DoubleArrayList list;
-
+
@Override
protected void setUp() throws Exception {
list = new DoubleArrayList();
}
-
+
public void testEmptyListReturnsSameInstance() {
assertSame(DoubleArrayList.emptyList(), DoubleArrayList.emptyList());
}
-
+
public void testEmptyListIsImmutable() {
assertImmutable(DoubleArrayList.emptyList());
}
-
+
public void testMakeImmutable() {
- list.addDouble(2);
+ list.addDouble(3);
list.addDouble(4);
- list.addDouble(6);
- list.addDouble(8);
+ list.addDouble(5);
+ list.addDouble(7);
list.makeImmutable();
assertImmutable(list);
}
-
- public void testCopyConstructor() {
- DoubleArrayList copy = new DoubleArrayList(TERTIARY_LIST);
- assertEquals(TERTIARY_LIST, copy);
-
- copy = new DoubleArrayList(DoubleArrayList.emptyList());
- assertEquals(DoubleArrayList.emptyList(), copy);
-
- copy = new DoubleArrayList(asList(1D, 2D, 3D));
- assertEquals(asList(1D, 2D, 3D), copy);
-
- copy = new DoubleArrayList(Collections.<Double>emptyList());
- assertEquals(DoubleArrayList.emptyList(), copy);
- }
-
+
public void testModificationWithIteration() {
list.addAll(asList(1D, 2D, 3D, 4D));
Iterator<Double> iterator = list.iterator();
@@ -95,7 +82,7 @@ public class DoubleArrayListTest extends TestCase {
assertEquals(1D, (double) iterator.next());
list.set(0, 1D);
assertEquals(2D, (double) iterator.next());
-
+
list.remove(0);
try {
iterator.next();
@@ -103,7 +90,7 @@ public class DoubleArrayListTest extends TestCase {
} catch (ConcurrentModificationException e) {
// expected
}
-
+
iterator = list.iterator();
list.add(0, 0D);
try {
@@ -113,19 +100,19 @@ public class DoubleArrayListTest extends TestCase {
// expected
}
}
-
+
public void testGet() {
assertEquals(1D, (double) TERTIARY_LIST.get(0));
assertEquals(2D, (double) TERTIARY_LIST.get(1));
assertEquals(3D, (double) TERTIARY_LIST.get(2));
-
+
try {
TERTIARY_LIST.get(-1);
fail();
} catch (IndexOutOfBoundsException e) {
// expected
}
-
+
try {
TERTIARY_LIST.get(3);
fail();
@@ -133,19 +120,19 @@ public class DoubleArrayListTest extends TestCase {
// expected
}
}
-
- public void testGetInt() {
+
+ public void testGetDouble() {
assertEquals(1D, TERTIARY_LIST.getDouble(0));
assertEquals(2D, TERTIARY_LIST.getDouble(1));
assertEquals(3D, TERTIARY_LIST.getDouble(2));
-
+
try {
TERTIARY_LIST.get(-1);
fail();
} catch (IndexOutOfBoundsException e) {
// expected
}
-
+
try {
TERTIARY_LIST.get(3);
fail();
@@ -153,35 +140,35 @@ public class DoubleArrayListTest extends TestCase {
// expected
}
}
-
+
public void testSize() {
assertEquals(0, DoubleArrayList.emptyList().size());
assertEquals(1, UNARY_LIST.size());
assertEquals(3, TERTIARY_LIST.size());
- list.addDouble(2);
+ list.addDouble(3);
list.addDouble(4);
list.addDouble(6);
list.addDouble(8);
assertEquals(4, list.size());
-
+
list.remove(0);
assertEquals(3, list.size());
-
- list.add(16D);
+
+ list.add(17D);
assertEquals(4, list.size());
}
-
+
public void testSet() {
list.addDouble(2);
list.addDouble(4);
-
- assertEquals(2D, (double) list.set(0, 0D));
- assertEquals(0D, list.getDouble(0));
+
+ assertEquals(2D, (double) list.set(0, 3D));
+ assertEquals(3D, list.getDouble(0));
assertEquals(4D, (double) list.set(1, 0D));
assertEquals(0D, list.getDouble(1));
-
+
try {
list.set(-1, 0D);
fail();
@@ -196,17 +183,17 @@ public class DoubleArrayListTest extends TestCase {
// expected
}
}
-
- public void testSetInt() {
- list.addDouble(2);
- list.addDouble(4);
-
- assertEquals(2D, list.setDouble(0, 0));
+
+ public void testSetDouble() {
+ list.addDouble(1);
+ list.addDouble(3);
+
+ assertEquals(1D, list.setDouble(0, 0));
assertEquals(0D, list.getDouble(0));
- assertEquals(4D, list.setDouble(1, 0));
+ assertEquals(3D, list.setDouble(1, 0));
assertEquals(0D, list.getDouble(1));
-
+
try {
list.setDouble(-1, 0);
fail();
@@ -221,7 +208,7 @@ public class DoubleArrayListTest extends TestCase {
// expected
}
}
-
+
public void testAdd() {
assertEquals(0, list.size());
@@ -231,29 +218,31 @@ public class DoubleArrayListTest extends TestCase {
assertTrue(list.add(3D));
list.add(0, 4D);
assertEquals(asList(4D, 2D, 3D), list);
-
+
list.add(0, 1D);
list.add(0, 0D);
// Force a resize by getting up to 11 elements.
for (int i = 0; i < 6; i++) {
list.add(Double.valueOf(5 + i));
}
- assertEquals(asList(0D, 1D, 4D, 2D, 3D, 5D, 6D, 7D, 8D, 9D, 10D), list);
-
+ assertEquals(
+ asList(0D, 1D, 4D, 2D, 3D, 5D, 6D, 7D, 8D, 9D, 10D),
+ list);
+
try {
list.add(-1, 5D);
} catch (IndexOutOfBoundsException e) {
// expected
}
-
+
try {
list.add(4, 5D);
} catch (IndexOutOfBoundsException e) {
// expected
}
}
-
- public void testAddInt() {
+
+ public void testAddDouble() {
assertEquals(0, list.size());
list.addDouble(2);
@@ -262,7 +251,7 @@ public class DoubleArrayListTest extends TestCase {
list.addDouble(3);
assertEquals(asList(2D, 3D), list);
}
-
+
public void testAddAll() {
assertEquals(0, list.size());
@@ -270,17 +259,17 @@ public class DoubleArrayListTest extends TestCase {
assertEquals(1, list.size());
assertEquals(1D, (double) list.get(0));
assertEquals(1D, list.getDouble(0));
-
+
assertTrue(list.addAll(asList(2D, 3D, 4D, 5D, 6D)));
assertEquals(asList(1D, 2D, 3D, 4D, 5D, 6D), list);
-
+
assertTrue(list.addAll(TERTIARY_LIST));
assertEquals(asList(1D, 2D, 3D, 4D, 5D, 6D, 1D, 2D, 3D), list);
assertFalse(list.addAll(Collections.<Double>emptyList()));
assertFalse(list.addAll(DoubleArrayList.emptyList()));
}
-
+
public void testRemove() {
list.addAll(TERTIARY_LIST);
assertEquals(1D, (double) list.remove(0));
@@ -294,96 +283,96 @@ public class DoubleArrayListTest extends TestCase {
assertEquals(2D, (double) list.remove(0));
assertEquals(asList(), list);
-
+
try {
list.remove(-1);
fail();
} catch (IndexOutOfBoundsException e) {
// expected
}
-
+
try {
list.remove(0);
} catch (IndexOutOfBoundsException e) {
// expected
}
}
-
+
private void assertImmutable(DoubleArrayList list) {
- if (list.contains(1)) {
+ if (list.contains(1D)) {
throw new RuntimeException("Cannot test the immutability of lists that contain 1.");
}
-
+
try {
list.add(1D);
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.add(0, 1D);
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.addAll(Collections.<Double>emptyList());
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.addAll(Collections.singletonList(1D));
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.addAll(new DoubleArrayList());
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.addAll(UNARY_LIST);
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.addAll(0, Collections.singleton(1D));
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.addAll(0, UNARY_LIST);
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.addAll(0, Collections.<Double>emptyList());
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.addDouble(0);
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.clear();
fail();
@@ -397,28 +386,28 @@ public class DoubleArrayListTest extends TestCase {
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.remove(new Object());
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.removeAll(Collections.<Double>emptyList());
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
- list.removeAll(Collections.singleton(1));
+ list.removeAll(Collections.singleton(1D));
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.removeAll(UNARY_LIST);
fail();
@@ -432,28 +421,28 @@ public class DoubleArrayListTest extends TestCase {
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
- list.retainAll(Collections.singleton(1));
+ list.retainAll(Collections.singleton(1D));
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.retainAll(UNARY_LIST);
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.set(0, 0D);
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.setDouble(0, 0);
fail();
@@ -461,7 +450,7 @@ public class DoubleArrayListTest extends TestCase {
// expected
}
}
-
+
private static DoubleArrayList newImmutableDoubleArrayList(double... elements) {
DoubleArrayList list = new DoubleArrayList();
for (double element : elements) {
diff --git a/java/src/test/java/com/google/protobuf/DynamicMessageTest.java b/java/core/src/test/java/com/google/protobuf/DynamicMessageTest.java
index 55144e7c..8f3a74c1 100644
--- a/java/src/test/java/com/google/protobuf/DynamicMessageTest.java
+++ b/java/core/src/test/java/com/google/protobuf/DynamicMessageTest.java
@@ -33,13 +33,13 @@ package com.google.protobuf;
import com.google.protobuf.Descriptors.EnumDescriptor;
import com.google.protobuf.Descriptors.FieldDescriptor;
import com.google.protobuf.Descriptors.OneofDescriptor;
-
import protobuf_unittest.UnittestProto.TestAllExtensions;
import protobuf_unittest.UnittestProto.TestAllTypes;
import protobuf_unittest.UnittestProto.TestEmptyMessage;
import protobuf_unittest.UnittestProto.TestPackedTypes;
import junit.framework.TestCase;
+
import java.util.Arrays;
/**
diff --git a/java/core/src/test/java/com/google/protobuf/EnumTest.java b/java/core/src/test/java/com/google/protobuf/EnumTest.java
new file mode 100644
index 00000000..14c7406b
--- /dev/null
+++ b/java/core/src/test/java/com/google/protobuf/EnumTest.java
@@ -0,0 +1,76 @@
+// 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.
+
+package com.google.protobuf;
+
+import com.google.protobuf.UnittestLite.ForeignEnumLite;
+import com.google.protobuf.UnittestLite.TestAllTypesLite;
+import protobuf_unittest.UnittestProto.ForeignEnum;
+import protobuf_unittest.UnittestProto.TestAllTypes;
+
+import junit.framework.TestCase;
+
+public class EnumTest extends TestCase {
+
+ public void testForNumber() {
+ ForeignEnum e = ForeignEnum.forNumber(ForeignEnum.FOREIGN_BAR.getNumber());
+ assertEquals(ForeignEnum.FOREIGN_BAR, e);
+
+ e = ForeignEnum.forNumber(1000);
+ assertEquals(null, e);
+ }
+
+ public void testForNumber_oneof() {
+ TestAllTypes.OneofFieldCase e = TestAllTypes.OneofFieldCase.forNumber(
+ TestAllTypes.OneofFieldCase.ONEOF_NESTED_MESSAGE.getNumber());
+ assertEquals(TestAllTypes.OneofFieldCase.ONEOF_NESTED_MESSAGE, e);
+
+ e = TestAllTypes.OneofFieldCase.forNumber(1000);
+ assertEquals(null, e);
+ }
+
+ public void testForNumberLite() {
+ ForeignEnumLite e = ForeignEnumLite.forNumber(ForeignEnumLite.FOREIGN_LITE_BAR.getNumber());
+ assertEquals(ForeignEnumLite.FOREIGN_LITE_BAR, e);
+
+ e = ForeignEnumLite.forNumber(1000);
+ assertEquals(null, e);
+ }
+
+ public void testForNumberLite_oneof() {
+ TestAllTypesLite.OneofFieldCase e = TestAllTypesLite.OneofFieldCase.forNumber(
+ TestAllTypesLite.OneofFieldCase.ONEOF_NESTED_MESSAGE.getNumber());
+ assertEquals(TestAllTypesLite.OneofFieldCase.ONEOF_NESTED_MESSAGE, e);
+
+ e = TestAllTypesLite.OneofFieldCase.forNumber(1000);
+ assertEquals(null, e);
+ }
+}
+
diff --git a/java/core/src/test/java/com/google/protobuf/ExtensionRegistryFactoryTest.java b/java/core/src/test/java/com/google/protobuf/ExtensionRegistryFactoryTest.java
new file mode 100644
index 00000000..c1246782
--- /dev/null
+++ b/java/core/src/test/java/com/google/protobuf/ExtensionRegistryFactoryTest.java
@@ -0,0 +1,245 @@
+// 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.
+
+package com.google.protobuf;
+
+import protobuf_unittest.NonNestedExtension;
+import protobuf_unittest.NonNestedExtensionLite;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import java.lang.reflect.Method;
+import java.net.URLClassLoader;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Tests for {@link ExtensionRegistryFactory} and the {@link ExtensionRegistry} instances it
+ * creates.
+ *
+ * <p>This test simulates the runtime behaviour of the ExtensionRegistryFactory by delegating test
+ * definitions to two inner classes {@link InnerTest} and {@link InnerLiteTest}, the latter of
+ * which is executed using a custom ClassLoader, simulating the ProtoLite environment.
+ *
+ * <p>The test mechanism employed here is based on the pattern in
+ * {@code com.google.common.util.concurrent.AbstractFutureFallbackAtomicHelperTest}
+ */
+public class ExtensionRegistryFactoryTest extends TestCase {
+
+ // A classloader which blacklists some non-Lite classes.
+ private static final ClassLoader LITE_CLASS_LOADER = getLiteOnlyClassLoader();
+
+ /**
+ * Defines the set of test methods which will be run.
+ */
+ static interface RegistryTests {
+ void testCreate();
+ void testEmpty();
+ void testIsFullRegistry();
+ void testAdd();
+ }
+
+ /**
+ * Test implementations for the non-Lite usage of ExtensionRegistryFactory.
+ */
+ public static class InnerTest implements RegistryTests {
+
+ @Override
+ public void testCreate() {
+ ExtensionRegistryLite registry = ExtensionRegistryFactory.create();
+
+ assertEquals(registry.getClass(), ExtensionRegistry.class);
+ }
+
+ @Override
+ public void testEmpty() {
+ ExtensionRegistryLite emptyRegistry = ExtensionRegistryFactory.createEmpty();
+
+ assertEquals(emptyRegistry.getClass(), ExtensionRegistry.class);
+ assertEquals(emptyRegistry, ExtensionRegistry.EMPTY_REGISTRY);
+ }
+
+ @Override
+ public void testIsFullRegistry() {
+ ExtensionRegistryLite registry = ExtensionRegistryFactory.create();
+ assertTrue(ExtensionRegistryFactory.isFullRegistry(registry));
+ }
+
+ @Override
+ public void testAdd() {
+ ExtensionRegistryLite registry1 = ExtensionRegistryLite.newInstance();
+ NonNestedExtensionLite.registerAllExtensions(registry1);
+ registry1.add(NonNestedExtensionLite.nonNestedExtensionLite);
+
+ ExtensionRegistryLite registry2 = ExtensionRegistryLite.newInstance();
+ NonNestedExtension.registerAllExtensions((ExtensionRegistry) registry2);
+ registry2.add(NonNestedExtension.nonNestedExtension);
+
+ ExtensionRegistry fullRegistry1 = (ExtensionRegistry) registry1;
+ ExtensionRegistry fullRegistry2 = (ExtensionRegistry) registry2;
+
+ assertTrue("Test is using a non-lite extension",
+ GeneratedMessageLite.GeneratedExtension.class.isAssignableFrom(
+ NonNestedExtensionLite.nonNestedExtensionLite.getClass()));
+ assertNull("Extension is not registered in masqueraded full registry",
+ fullRegistry1.findImmutableExtensionByName("protobuf_unittest.nonNestedExtension"));
+ GeneratedMessageLite.GeneratedExtension<NonNestedExtensionLite.MessageLiteToBeExtended, ?>
+ extension = registry1.findLiteExtensionByNumber(
+ NonNestedExtensionLite.MessageLiteToBeExtended.getDefaultInstance(), 1);
+ assertNotNull("Extension registered in lite registry", extension);
+
+ assertTrue("Test is using a non-lite extension",
+ GeneratedMessage.GeneratedExtension.class.isAssignableFrom(
+ NonNestedExtension.nonNestedExtension.getClass()));
+ assertNotNull("Extension is registered in masqueraded full registry",
+ fullRegistry2.findImmutableExtensionByName("protobuf_unittest.nonNestedExtension"));
+ }
+ }
+
+ /**
+ * Test implementations for the Lite usage of ExtensionRegistryFactory.
+ */
+ public static final class InnerLiteTest implements RegistryTests {
+
+ @Override
+ public void testCreate() {
+ ExtensionRegistryLite registry = ExtensionRegistryFactory.create();
+
+ assertEquals(registry.getClass(), ExtensionRegistryLite.class);
+ }
+
+ @Override
+ public void testEmpty() {
+ ExtensionRegistryLite emptyRegistry = ExtensionRegistryFactory.createEmpty();
+
+ assertEquals(emptyRegistry.getClass(), ExtensionRegistryLite.class);
+ assertEquals(emptyRegistry, ExtensionRegistryLite.EMPTY_REGISTRY_LITE);
+ }
+
+ @Override
+ public void testIsFullRegistry() {
+ ExtensionRegistryLite registry = ExtensionRegistryFactory.create();
+ assertFalse(ExtensionRegistryFactory.isFullRegistry(registry));
+ }
+
+ @Override
+ public void testAdd() {
+ ExtensionRegistryLite registry = ExtensionRegistryLite.newInstance();
+ NonNestedExtensionLite.registerAllExtensions(registry);
+ GeneratedMessageLite.GeneratedExtension<NonNestedExtensionLite.MessageLiteToBeExtended, ?>
+ extension = registry.findLiteExtensionByNumber(
+ NonNestedExtensionLite.MessageLiteToBeExtended.getDefaultInstance(), 1);
+ assertNotNull("Extension is registered in Lite registry", extension);
+ }
+ }
+
+ /**
+ * Defines a suite of tests which the JUnit3 runner retrieves by reflection.
+ */
+ public static Test suite() {
+ TestSuite suite = new TestSuite();
+ for (Method method : RegistryTests.class.getMethods()) {
+ suite.addTest(TestSuite.createTest(ExtensionRegistryFactoryTest.class, method.getName()));
+ }
+ return suite;
+ }
+
+ /**
+ * Sequentially runs first the Lite and then the non-Lite test variant via classloader
+ * manipulation.
+ */
+ @Override
+ public void runTest() throws Exception {
+ ClassLoader storedClassLoader = Thread.currentThread().getContextClassLoader();
+ Thread.currentThread().setContextClassLoader(LITE_CLASS_LOADER);
+ try {
+ runTestMethod(LITE_CLASS_LOADER, InnerLiteTest.class);
+ } finally {
+ Thread.currentThread().setContextClassLoader(storedClassLoader);
+ }
+ try {
+ runTestMethod(storedClassLoader, InnerTest.class);
+ } finally {
+ Thread.currentThread().setContextClassLoader(storedClassLoader);
+ }
+ }
+
+ private void runTestMethod(ClassLoader classLoader, Class<? extends RegistryTests> testClass)
+ throws Exception {
+ classLoader.loadClass(ExtensionRegistryFactory.class.getName());
+ Class<?> test = classLoader.loadClass(testClass.getName());
+ String testName = getName();
+ test.getMethod(testName).invoke(test.newInstance());
+ }
+
+ /**
+ * Constructs a custom ClassLoader blacklisting the classes which are inspected in the SUT
+ * to determine the Lite/non-Lite runtime.
+ */
+ private static ClassLoader getLiteOnlyClassLoader() {
+ ClassLoader testClassLoader = ExtensionRegistryFactoryTest.class.getClassLoader();
+ final Set<String> classNamesNotInLite =
+ Collections.unmodifiableSet(
+ new HashSet<String>(
+ Arrays.asList(
+ ExtensionRegistryFactory.FULL_REGISTRY_CLASS_NAME,
+ ExtensionRegistry.EXTENSION_CLASS_NAME)));
+
+ // Construct a URLClassLoader delegating to the system ClassLoader, and looking up classes
+ // in jar files based on the URLs already configured for this test's UrlClassLoader.
+ // Certain classes throw a ClassNotFoundException by design.
+ return new URLClassLoader(((URLClassLoader) testClassLoader).getURLs(),
+ ClassLoader.getSystemClassLoader()) {
+ @Override
+ public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
+ if (classNamesNotInLite.contains(name)) {
+ throw new ClassNotFoundException("Class deliberately blacklisted by test.");
+ }
+ Class<?> loadedClass = null;
+ try {
+ loadedClass = findLoadedClass(name);
+ if (loadedClass == null) {
+ loadedClass = findClass(name);
+ if (resolve) {
+ resolveClass(loadedClass);
+ }
+ }
+ } catch (ClassNotFoundException e) {
+ loadedClass = super.loadClass(name, resolve);
+ }
+ return loadedClass;
+ }
+ };
+ }
+}
diff --git a/java/src/test/java/com/google/protobuf/FieldPresenceTest.java b/java/core/src/test/java/com/google/protobuf/FieldPresenceTest.java
index eaeec0b8..4a42c897 100644
--- a/java/src/test/java/com/google/protobuf/FieldPresenceTest.java
+++ b/java/core/src/test/java/com/google/protobuf/FieldPresenceTest.java
@@ -31,6 +31,8 @@
package com.google.protobuf;
import com.google.protobuf.Descriptors.Descriptor;
+import com.google.protobuf.Descriptors.EnumDescriptor;
+import com.google.protobuf.Descriptors.EnumValueDescriptor;
import com.google.protobuf.Descriptors.FieldDescriptor;
import com.google.protobuf.FieldPresenceTestProto.TestAllTypes;
import com.google.protobuf.FieldPresenceTestProto.TestOptionalFieldsOnly;
@@ -44,9 +46,9 @@ import junit.framework.TestCase;
* non-message fields.
*/
public class FieldPresenceTest extends TestCase {
- private static boolean hasMethod(Class clazz, String name) {
+ private static boolean hasMethod(Class<?> clazz, String name) {
try {
- if (clazz.getMethod(name, new Class[]{}) != null) {
+ if (clazz.getMethod(name) != null) {
return true;
} else {
return false;
@@ -56,90 +58,90 @@ public class FieldPresenceTest extends TestCase {
}
}
- private static boolean isHasMethodRemoved(
- Class classWithFieldPresence,
- Class classWithoutFieldPresence,
+ private static void assertHasMethodRemoved(
+ Class<?> classWithFieldPresence,
+ Class<?> classWithoutFieldPresence,
String camelName) {
- return hasMethod(classWithFieldPresence, "get" + camelName)
- && hasMethod(classWithFieldPresence, "has" + camelName)
- && hasMethod(classWithoutFieldPresence, "get" + camelName)
- && !hasMethod(classWithoutFieldPresence, "has" + camelName);
+ assertTrue(hasMethod(classWithFieldPresence, "get" + camelName));
+ assertTrue(hasMethod(classWithFieldPresence, "has" + camelName));
+ assertTrue(hasMethod(classWithoutFieldPresence, "get" + camelName));
+ assertFalse(hasMethod(classWithoutFieldPresence, "has" + camelName));
}
public void testHasMethod() {
// Optional non-message fields don't have a hasFoo() method generated.
- assertTrue(isHasMethodRemoved(
+ assertHasMethodRemoved(
UnittestProto.TestAllTypes.class,
TestAllTypes.class,
- "OptionalInt32"));
- assertTrue(isHasMethodRemoved(
+ "OptionalInt32");
+ assertHasMethodRemoved(
UnittestProto.TestAllTypes.class,
TestAllTypes.class,
- "OptionalString"));
- assertTrue(isHasMethodRemoved(
+ "OptionalString");
+ assertHasMethodRemoved(
UnittestProto.TestAllTypes.class,
TestAllTypes.class,
- "OptionalBytes"));
- assertTrue(isHasMethodRemoved(
+ "OptionalBytes");
+ assertHasMethodRemoved(
UnittestProto.TestAllTypes.class,
TestAllTypes.class,
- "OptionalNestedEnum"));
+ "OptionalNestedEnum");
- assertTrue(isHasMethodRemoved(
+ assertHasMethodRemoved(
UnittestProto.TestAllTypes.Builder.class,
TestAllTypes.Builder.class,
- "OptionalInt32"));
- assertTrue(isHasMethodRemoved(
+ "OptionalInt32");
+ assertHasMethodRemoved(
UnittestProto.TestAllTypes.Builder.class,
TestAllTypes.Builder.class,
- "OptionalString"));
- assertTrue(isHasMethodRemoved(
+ "OptionalString");
+ assertHasMethodRemoved(
UnittestProto.TestAllTypes.Builder.class,
TestAllTypes.Builder.class,
- "OptionalBytes"));
- assertTrue(isHasMethodRemoved(
+ "OptionalBytes");
+ assertHasMethodRemoved(
UnittestProto.TestAllTypes.Builder.class,
TestAllTypes.Builder.class,
- "OptionalNestedEnum"));
+ "OptionalNestedEnum");
// message fields still have the hasFoo() method generated.
assertFalse(TestAllTypes.newBuilder().build().hasOptionalNestedMessage());
assertFalse(TestAllTypes.newBuilder().hasOptionalNestedMessage());
// oneof fields don't have hasFoo() methods (even for message types).
- assertTrue(isHasMethodRemoved(
+ assertHasMethodRemoved(
UnittestProto.TestAllTypes.class,
TestAllTypes.class,
- "OneofUint32"));
- assertTrue(isHasMethodRemoved(
+ "OneofUint32");
+ assertHasMethodRemoved(
UnittestProto.TestAllTypes.class,
TestAllTypes.class,
- "OneofString"));
- assertTrue(isHasMethodRemoved(
+ "OneofString");
+ assertHasMethodRemoved(
UnittestProto.TestAllTypes.class,
TestAllTypes.class,
- "OneofBytes"));
- assertTrue(isHasMethodRemoved(
+ "OneofBytes");
+ assertHasMethodRemoved(
UnittestProto.TestAllTypes.class,
TestAllTypes.class,
- "OneofNestedMessage"));
+ "OneofNestedMessage");
- assertTrue(isHasMethodRemoved(
+ assertHasMethodRemoved(
UnittestProto.TestAllTypes.Builder.class,
TestAllTypes.Builder.class,
- "OneofUint32"));
- assertTrue(isHasMethodRemoved(
+ "OneofUint32");
+ assertHasMethodRemoved(
UnittestProto.TestAllTypes.Builder.class,
TestAllTypes.Builder.class,
- "OneofString"));
- assertTrue(isHasMethodRemoved(
+ "OneofString");
+ assertHasMethodRemoved(
UnittestProto.TestAllTypes.Builder.class,
TestAllTypes.Builder.class,
- "OneofBytes"));
- assertTrue(isHasMethodRemoved(
+ "OneofBytes");
+ assertHasMethodRemoved(
UnittestProto.TestAllTypes.Builder.class,
TestAllTypes.Builder.class,
- "OneofNestedMessage"));
+ "OneofNestedMessage");
}
public void testOneofEquals() throws Exception {
@@ -152,6 +154,26 @@ public class FieldPresenceTest extends TestCase {
assertFalse(message1.equals(message2));
}
+ public void testLazyField() throws Exception {
+ // Test default constructed message.
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TestAllTypes message = builder.build();
+ assertFalse(message.hasOptionalLazyMessage());
+ assertEquals(0, message.getSerializedSize());
+ assertEquals(ByteString.EMPTY, message.toByteString());
+
+ // Set default instance to the field.
+ builder.setOptionalLazyMessage(TestAllTypes.NestedMessage.getDefaultInstance());
+ message = builder.build();
+ assertTrue(message.hasOptionalLazyMessage());
+ assertEquals(2, message.getSerializedSize());
+
+ // Test parse zero-length from wire sets the presence.
+ TestAllTypes parsed = TestAllTypes.parseFrom(message.toByteString());
+ assertTrue(parsed.hasOptionalLazyMessage());
+ assertEquals(message.getOptionalLazyMessage(), parsed.getOptionalLazyMessage());
+ }
+
public void testFieldPresence() {
// Optional non-message fields set to their default value are treated the
// same way as not set.
@@ -232,24 +254,72 @@ public class FieldPresenceTest extends TestCase {
assertTrue(message.hasField(optionalNestedEnumField));
assertEquals(4, message.getAllFields().size());
}
-
+
+ public void testFieldPresenceDynamicMessage() {
+ Descriptor descriptor = TestAllTypes.getDescriptor();
+ FieldDescriptor optionalInt32Field = descriptor.findFieldByName("optional_int32");
+ FieldDescriptor optionalStringField = descriptor.findFieldByName("optional_string");
+ FieldDescriptor optionalBytesField = descriptor.findFieldByName("optional_bytes");
+ FieldDescriptor optionalNestedEnumField = descriptor.findFieldByName("optional_nested_enum");
+ EnumDescriptor enumDescriptor = optionalNestedEnumField.getEnumType();
+ EnumValueDescriptor defaultEnumValueDescriptor = enumDescriptor.getValues().get(0);
+ EnumValueDescriptor nonDefaultEnumValueDescriptor = enumDescriptor.getValues().get(1);
+
+ DynamicMessage defaultInstance = DynamicMessage.getDefaultInstance(descriptor);
+ // Field not present.
+ DynamicMessage message = defaultInstance.newBuilderForType().build();
+ assertFalse(message.hasField(optionalInt32Field));
+ assertFalse(message.hasField(optionalStringField));
+ assertFalse(message.hasField(optionalBytesField));
+ assertFalse(message.hasField(optionalNestedEnumField));
+ assertEquals(0, message.getAllFields().size());
+
+ // Field set to non-default value is seen as present.
+ message =
+ defaultInstance
+ .newBuilderForType()
+ .setField(optionalInt32Field, 1)
+ .setField(optionalStringField, "x")
+ .setField(optionalBytesField, ByteString.copyFromUtf8("y"))
+ .setField(optionalNestedEnumField, nonDefaultEnumValueDescriptor)
+ .build();
+ assertTrue(message.hasField(optionalInt32Field));
+ assertTrue(message.hasField(optionalStringField));
+ assertTrue(message.hasField(optionalBytesField));
+ assertTrue(message.hasField(optionalNestedEnumField));
+ assertEquals(4, message.getAllFields().size());
+
+ // Field set to default value is seen as not present.
+ message = message.toBuilder()
+ .setField(optionalInt32Field, 0)
+ .setField(optionalStringField, "")
+ .setField(optionalBytesField, ByteString.EMPTY)
+ .setField(optionalNestedEnumField, defaultEnumValueDescriptor)
+ .build();
+ assertFalse(message.hasField(optionalInt32Field));
+ assertFalse(message.hasField(optionalStringField));
+ assertFalse(message.hasField(optionalBytesField));
+ assertFalse(message.hasField(optionalNestedEnumField));
+ assertEquals(0, message.getAllFields().size());
+ }
+
public void testMessageField() {
TestAllTypes.Builder builder = TestAllTypes.newBuilder();
assertFalse(builder.hasOptionalNestedMessage());
assertFalse(builder.build().hasOptionalNestedMessage());
-
+
TestAllTypes.NestedMessage.Builder nestedBuilder =
builder.getOptionalNestedMessageBuilder();
assertTrue(builder.hasOptionalNestedMessage());
assertTrue(builder.build().hasOptionalNestedMessage());
-
+
nestedBuilder.setValue(1);
assertEquals(1, builder.build().getOptionalNestedMessage().getValue());
-
+
builder.clearOptionalNestedMessage();
assertFalse(builder.hasOptionalNestedMessage());
assertFalse(builder.build().hasOptionalNestedMessage());
-
+
// Unlike non-message fields, if we set a message field to its default value (i.e.,
// default instance), the field should be seen as present.
builder.setOptionalNestedMessage(TestAllTypes.NestedMessage.getDefaultInstance());
@@ -340,7 +410,7 @@ public class FieldPresenceTest extends TestCase {
assertTrue(builder.buildPartial().isInitialized());
}
-
+
// Test that unknown fields are dropped.
public void testUnknownFields() throws Exception {
TestAllTypes.Builder builder = TestAllTypes.newBuilder();
@@ -348,7 +418,7 @@ public class FieldPresenceTest extends TestCase {
builder.addRepeatedInt32(5678);
TestAllTypes message = builder.build();
ByteString data = message.toByteString();
-
+
TestOptionalFieldsOnly optionalOnlyMessage =
TestOptionalFieldsOnly.parseFrom(data);
// UnknownFieldSet should be empty.
@@ -360,7 +430,7 @@ public class FieldPresenceTest extends TestCase {
// The repeated field is discarded because it's unknown to the optional-only
// message.
assertEquals(0, message.getRepeatedInt32Count());
-
+
DynamicMessage dynamicOptionalOnlyMessage =
DynamicMessage.getDefaultInstance(
TestOptionalFieldsOnly.getDescriptor())
diff --git a/java/src/test/java/com/google/protobuf/FloatArrayListTest.java b/java/core/src/test/java/com/google/protobuf/FloatArrayListTest.java
index 8f3e93dc..0e13a598 100644
--- a/java/src/test/java/com/google/protobuf/FloatArrayListTest.java
+++ b/java/core/src/test/java/com/google/protobuf/FloatArrayListTest.java
@@ -40,53 +40,40 @@ import java.util.Iterator;
/**
* Tests for {@link FloatArrayList}.
- *
+ *
* @author dweis@google.com (Daniel Weis)
*/
public class FloatArrayListTest extends TestCase {
-
- private static final FloatArrayList UNARY_LIST = newImmutableFloatArrayList(1);
+
+ private static final FloatArrayList UNARY_LIST =
+ newImmutableFloatArrayList(1);
private static final FloatArrayList TERTIARY_LIST =
newImmutableFloatArrayList(1, 2, 3);
-
+
private FloatArrayList list;
-
+
@Override
protected void setUp() throws Exception {
list = new FloatArrayList();
}
-
+
public void testEmptyListReturnsSameInstance() {
assertSame(FloatArrayList.emptyList(), FloatArrayList.emptyList());
}
-
+
public void testEmptyListIsImmutable() {
assertImmutable(FloatArrayList.emptyList());
}
-
+
public void testMakeImmutable() {
- list.addFloat(2);
+ list.addFloat(3);
list.addFloat(4);
- list.addFloat(6);
- list.addFloat(8);
+ list.addFloat(5);
+ list.addFloat(7);
list.makeImmutable();
assertImmutable(list);
}
-
- public void testCopyConstructor() {
- FloatArrayList copy = new FloatArrayList(TERTIARY_LIST);
- assertEquals(TERTIARY_LIST, copy);
-
- copy = new FloatArrayList(FloatArrayList.emptyList());
- assertEquals(FloatArrayList.emptyList(), copy);
-
- copy = new FloatArrayList(asList(1F, 2F, 3F));
- assertEquals(asList(1F, 2F, 3F), copy);
-
- copy = new FloatArrayList(Collections.<Float>emptyList());
- assertEquals(FloatArrayList.emptyList(), copy);
- }
-
+
public void testModificationWithIteration() {
list.addAll(asList(1F, 2F, 3F, 4F));
Iterator<Float> iterator = list.iterator();
@@ -95,7 +82,7 @@ public class FloatArrayListTest extends TestCase {
assertEquals(1F, (float) iterator.next());
list.set(0, 1F);
assertEquals(2F, (float) iterator.next());
-
+
list.remove(0);
try {
iterator.next();
@@ -103,7 +90,7 @@ public class FloatArrayListTest extends TestCase {
} catch (ConcurrentModificationException e) {
// expected
}
-
+
iterator = list.iterator();
list.add(0, 0F);
try {
@@ -113,19 +100,19 @@ public class FloatArrayListTest extends TestCase {
// expected
}
}
-
+
public void testGet() {
assertEquals(1F, (float) TERTIARY_LIST.get(0));
assertEquals(2F, (float) TERTIARY_LIST.get(1));
assertEquals(3F, (float) TERTIARY_LIST.get(2));
-
+
try {
TERTIARY_LIST.get(-1);
fail();
} catch (IndexOutOfBoundsException e) {
// expected
}
-
+
try {
TERTIARY_LIST.get(3);
fail();
@@ -133,19 +120,19 @@ public class FloatArrayListTest extends TestCase {
// expected
}
}
-
+
public void testGetFloat() {
assertEquals(1F, TERTIARY_LIST.getFloat(0));
assertEquals(2F, TERTIARY_LIST.getFloat(1));
assertEquals(3F, TERTIARY_LIST.getFloat(2));
-
+
try {
TERTIARY_LIST.get(-1);
fail();
} catch (IndexOutOfBoundsException e) {
// expected
}
-
+
try {
TERTIARY_LIST.get(3);
fail();
@@ -153,35 +140,35 @@ public class FloatArrayListTest extends TestCase {
// expected
}
}
-
+
public void testSize() {
assertEquals(0, FloatArrayList.emptyList().size());
assertEquals(1, UNARY_LIST.size());
assertEquals(3, TERTIARY_LIST.size());
- list.addFloat(2);
+ list.addFloat(3);
list.addFloat(4);
list.addFloat(6);
list.addFloat(8);
assertEquals(4, list.size());
-
+
list.remove(0);
assertEquals(3, list.size());
-
- list.add(16F);
+
+ list.add(17F);
assertEquals(4, list.size());
}
-
+
public void testSet() {
list.addFloat(2);
list.addFloat(4);
-
- assertEquals(2F, (float) list.set(0, 0F));
- assertEquals(0F, list.getFloat(0));
+
+ assertEquals(2F, (float) list.set(0, 3F));
+ assertEquals(3F, list.getFloat(0));
assertEquals(4F, (float) list.set(1, 0F));
assertEquals(0F, list.getFloat(1));
-
+
try {
list.set(-1, 0F);
fail();
@@ -196,17 +183,17 @@ public class FloatArrayListTest extends TestCase {
// expected
}
}
-
+
public void testSetFloat() {
- list.addFloat(2);
- list.addFloat(4);
-
- assertEquals(2F, list.setFloat(0, 0));
+ list.addFloat(1);
+ list.addFloat(3);
+
+ assertEquals(1F, list.setFloat(0, 0));
assertEquals(0F, list.getFloat(0));
- assertEquals(4F, list.setFloat(1, 0));
+ assertEquals(3F, list.setFloat(1, 0));
assertEquals(0F, list.getFloat(1));
-
+
try {
list.setFloat(-1, 0);
fail();
@@ -221,7 +208,7 @@ public class FloatArrayListTest extends TestCase {
// expected
}
}
-
+
public void testAdd() {
assertEquals(0, list.size());
@@ -231,28 +218,30 @@ public class FloatArrayListTest extends TestCase {
assertTrue(list.add(3F));
list.add(0, 4F);
assertEquals(asList(4F, 2F, 3F), list);
-
+
list.add(0, 1F);
list.add(0, 0F);
// Force a resize by getting up to 11 elements.
for (int i = 0; i < 6; i++) {
list.add(Float.valueOf(5 + i));
}
- assertEquals(asList(0F, 1F, 4F, 2F, 3F, 5F, 6F, 7F, 8F, 9F, 10F), list);
-
+ assertEquals(
+ asList(0F, 1F, 4F, 2F, 3F, 5F, 6F, 7F, 8F, 9F, 10F),
+ list);
+
try {
list.add(-1, 5F);
} catch (IndexOutOfBoundsException e) {
// expected
}
-
+
try {
list.add(4, 5F);
} catch (IndexOutOfBoundsException e) {
// expected
}
}
-
+
public void testAddFloat() {
assertEquals(0, list.size());
@@ -262,7 +251,7 @@ public class FloatArrayListTest extends TestCase {
list.addFloat(3);
assertEquals(asList(2F, 3F), list);
}
-
+
public void testAddAll() {
assertEquals(0, list.size());
@@ -270,17 +259,17 @@ public class FloatArrayListTest extends TestCase {
assertEquals(1, list.size());
assertEquals(1F, (float) list.get(0));
assertEquals(1F, list.getFloat(0));
-
+
assertTrue(list.addAll(asList(2F, 3F, 4F, 5F, 6F)));
assertEquals(asList(1F, 2F, 3F, 4F, 5F, 6F), list);
-
+
assertTrue(list.addAll(TERTIARY_LIST));
assertEquals(asList(1F, 2F, 3F, 4F, 5F, 6F, 1F, 2F, 3F), list);
assertFalse(list.addAll(Collections.<Float>emptyList()));
assertFalse(list.addAll(FloatArrayList.emptyList()));
}
-
+
public void testRemove() {
list.addAll(TERTIARY_LIST);
assertEquals(1F, (float) list.remove(0));
@@ -294,96 +283,96 @@ public class FloatArrayListTest extends TestCase {
assertEquals(2F, (float) list.remove(0));
assertEquals(asList(), list);
-
+
try {
list.remove(-1);
fail();
} catch (IndexOutOfBoundsException e) {
// expected
}
-
+
try {
list.remove(0);
} catch (IndexOutOfBoundsException e) {
// expected
}
}
-
+
private void assertImmutable(FloatArrayList list) {
- if (list.contains(1)) {
+ if (list.contains(1F)) {
throw new RuntimeException("Cannot test the immutability of lists that contain 1.");
}
-
+
try {
list.add(1F);
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.add(0, 1F);
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.addAll(Collections.<Float>emptyList());
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.addAll(Collections.singletonList(1F));
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.addAll(new FloatArrayList());
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.addAll(UNARY_LIST);
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.addAll(0, Collections.singleton(1F));
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.addAll(0, UNARY_LIST);
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.addAll(0, Collections.<Float>emptyList());
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.addFloat(0);
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.clear();
fail();
@@ -397,63 +386,63 @@ public class FloatArrayListTest extends TestCase {
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.remove(new Object());
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.removeAll(Collections.<Float>emptyList());
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
- list.removeAll(Collections.singleton(1));
+ list.removeAll(Collections.singleton(1F));
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.removeAll(UNARY_LIST);
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.retainAll(Collections.<Float>emptyList());
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
- list.retainAll(Collections.singleton(1));
+ list.retainAll(Collections.singleton(1F));
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.retainAll(UNARY_LIST);
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.set(0, 0F);
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.setFloat(0, 0);
fail();
@@ -461,10 +450,10 @@ public class FloatArrayListTest extends TestCase {
// expected
}
}
-
- private static FloatArrayList newImmutableFloatArrayList(int... elements) {
+
+ private static FloatArrayList newImmutableFloatArrayList(float... elements) {
FloatArrayList list = new FloatArrayList();
- for (int element : elements) {
+ for (float element : elements) {
list.addFloat(element);
}
list.makeImmutable();
diff --git a/java/src/test/java/com/google/protobuf/ForceFieldBuildersPreRun.java b/java/core/src/test/java/com/google/protobuf/ForceFieldBuildersPreRun.java
index a92ba374..b7eaebf5 100644
--- a/java/src/test/java/com/google/protobuf/ForceFieldBuildersPreRun.java
+++ b/java/core/src/test/java/com/google/protobuf/ForceFieldBuildersPreRun.java
@@ -41,7 +41,7 @@ package com.google.protobuf;
*/
public class ForceFieldBuildersPreRun implements Runnable {
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public void run() {
GeneratedMessage.enableAlwaysUseFieldBuildersForTesting();
}
diff --git a/java/src/test/java/com/google/protobuf/GeneratedMessageTest.java b/java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java
index 70812b95..127e06fd 100644
--- a/java/src/test/java/com/google/protobuf/GeneratedMessageTest.java
+++ b/java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java
@@ -620,6 +620,21 @@ public class GeneratedMessageTest extends TestCase {
TestUtil.assertExtensionsClear(TestAllExtensions.newBuilder().build());
}
+ public void testUnsetRepeatedExtensionGetField() {
+ TestAllExtensions message = TestAllExtensions.getDefaultInstance();
+ Object value;
+
+ value = message.getField(UnittestProto.repeatedStringExtension.getDescriptor());
+ assertTrue(value instanceof List);
+ assertTrue(((List<?>) value).isEmpty());
+ assertIsUnmodifiable((List<?>) value);
+
+ value = message.getField(UnittestProto.repeatedNestedMessageExtension.getDescriptor());
+ assertTrue(value instanceof List);
+ assertTrue(((List<?>) value).isEmpty());
+ assertIsUnmodifiable((List<?>) value);
+ }
+
public void testExtensionReflectionGetters() throws Exception {
TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
TestUtil.setAllExtensions(builder);
@@ -708,7 +723,7 @@ public class GeneratedMessageTest extends TestCase {
public void testLiteExtensionMessageOrBuilder() throws Exception {
TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.newBuilder();
- TestUtil.setAllExtensions(builder);
+ TestUtilLite.setAllExtensions(builder);
TestUtil.assertAllExtensionsSet(builder);
TestAllExtensionsLite message = builder.build();
@@ -717,8 +732,8 @@ public class GeneratedMessageTest extends TestCase {
public void testLiteExtensionRepeatedSetters() throws Exception {
TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.newBuilder();
- TestUtil.setAllExtensions(builder);
- TestUtil.modifyRepeatedExtensions(builder);
+ TestUtilLite.setAllExtensions(builder);
+ TestUtilLite.modifyRepeatedExtensions(builder);
TestUtil.assertRepeatedExtensionsModified(builder);
TestAllExtensionsLite message = builder.build();
@@ -745,7 +760,7 @@ public class GeneratedMessageTest extends TestCase {
}
public void testLiteExtensionCopy() throws Exception {
- TestAllExtensionsLite original = TestUtil.getAllLiteExtensionsSet();
+ TestAllExtensionsLite original = TestUtilLite.getAllLiteExtensionsSet();
TestAllExtensionsLite copy =
TestAllExtensionsLite.newBuilder(original).build();
TestUtil.assertAllExtensionsSet(copy);
@@ -957,7 +972,7 @@ public class GeneratedMessageTest extends TestCase {
TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent();
TestAllTypes.Builder builder = (TestAllTypes.Builder)
- ((GeneratedMessage) TestAllTypes.getDefaultInstance()).
+ ((AbstractMessage) TestAllTypes.getDefaultInstance()).
newBuilderForType(mockParent);
builder.setOptionalInt32(1);
builder.setOptionalNestedEnum(TestAllTypes.NestedEnum.BAR);
@@ -1012,7 +1027,7 @@ public class GeneratedMessageTest extends TestCase {
TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent();
TestAllExtensions.Builder builder = (TestAllExtensions.Builder)
- ((GeneratedMessage) TestAllExtensions.getDefaultInstance()).
+ ((AbstractMessage) TestAllExtensions.getDefaultInstance()).
newBuilderForType(mockParent);
builder.addExtension(UnittestProto.repeatedInt32Extension, 1);
diff --git a/java/src/test/java/com/google/protobuf/IntArrayListTest.java b/java/core/src/test/java/com/google/protobuf/IntArrayListTest.java
index 3733eb30..e59e3c6e 100644
--- a/java/src/test/java/com/google/protobuf/IntArrayListTest.java
+++ b/java/core/src/test/java/com/google/protobuf/IntArrayListTest.java
@@ -40,52 +40,39 @@ import java.util.Iterator;
/**
* Tests for {@link IntArrayList}.
- *
+ *
* @author dweis@google.com (Daniel Weis)
*/
public class IntArrayListTest extends TestCase {
-
- private static final IntArrayList UNARY_LIST = newImmutableIntArrayList(1);
+
+ private static final IntArrayList UNARY_LIST =
+ newImmutableIntArrayList(1);
private static final IntArrayList TERTIARY_LIST =
newImmutableIntArrayList(1, 2, 3);
-
+
private IntArrayList list;
-
+
@Override
protected void setUp() throws Exception {
list = new IntArrayList();
}
-
+
public void testEmptyListReturnsSameInstance() {
assertSame(IntArrayList.emptyList(), IntArrayList.emptyList());
}
-
+
public void testEmptyListIsImmutable() {
assertImmutable(IntArrayList.emptyList());
}
-
+
public void testMakeImmutable() {
- list.addInt(2);
+ list.addInt(3);
list.addInt(4);
- list.addInt(6);
- list.addInt(8);
+ list.addInt(5);
+ list.addInt(7);
list.makeImmutable();
assertImmutable(list);
}
-
- public void testCopyConstructor() {
- IntArrayList copy = new IntArrayList(TERTIARY_LIST);
- assertEquals(TERTIARY_LIST, copy);
-
- copy = new IntArrayList(IntArrayList.emptyList());
- assertEquals(IntArrayList.emptyList(), copy);
-
- copy = new IntArrayList(asList(1, 2, 3));
- assertEquals(asList(1, 2, 3), copy);
-
- copy = new IntArrayList(Collections.<Integer>emptyList());
- assertEquals(IntArrayList.emptyList(), copy);
- }
public void testModificationWithIteration() {
list.addAll(asList(1, 2, 3, 4));
@@ -95,7 +82,7 @@ public class IntArrayListTest extends TestCase {
assertEquals(1, (int) iterator.next());
list.set(0, 1);
assertEquals(2, (int) iterator.next());
-
+
list.remove(0);
try {
iterator.next();
@@ -113,19 +100,19 @@ public class IntArrayListTest extends TestCase {
// expected
}
}
-
+
public void testGet() {
assertEquals(1, (int) TERTIARY_LIST.get(0));
assertEquals(2, (int) TERTIARY_LIST.get(1));
assertEquals(3, (int) TERTIARY_LIST.get(2));
-
+
try {
TERTIARY_LIST.get(-1);
fail();
} catch (IndexOutOfBoundsException e) {
// expected
}
-
+
try {
TERTIARY_LIST.get(3);
fail();
@@ -133,19 +120,19 @@ public class IntArrayListTest extends TestCase {
// expected
}
}
-
+
public void testGetInt() {
assertEquals(1, TERTIARY_LIST.getInt(0));
assertEquals(2, TERTIARY_LIST.getInt(1));
assertEquals(3, TERTIARY_LIST.getInt(2));
-
+
try {
TERTIARY_LIST.get(-1);
fail();
} catch (IndexOutOfBoundsException e) {
// expected
}
-
+
try {
TERTIARY_LIST.get(3);
fail();
@@ -153,35 +140,35 @@ public class IntArrayListTest extends TestCase {
// expected
}
}
-
+
public void testSize() {
assertEquals(0, IntArrayList.emptyList().size());
assertEquals(1, UNARY_LIST.size());
assertEquals(3, TERTIARY_LIST.size());
- list.addInt(2);
+ list.addInt(3);
list.addInt(4);
list.addInt(6);
list.addInt(8);
assertEquals(4, list.size());
-
+
list.remove(0);
assertEquals(3, list.size());
-
- list.add(16);
+
+ list.add(17);
assertEquals(4, list.size());
}
-
+
public void testSet() {
list.addInt(2);
list.addInt(4);
-
- assertEquals(2, (int) list.set(0, 0));
- assertEquals(0, list.getInt(0));
+
+ assertEquals(2, (int) list.set(0, 3));
+ assertEquals(3, list.getInt(0));
assertEquals(4, (int) list.set(1, 0));
assertEquals(0, list.getInt(1));
-
+
try {
list.set(-1, 0);
fail();
@@ -196,17 +183,17 @@ public class IntArrayListTest extends TestCase {
// expected
}
}
-
+
public void testSetInt() {
- list.addInt(2);
- list.addInt(4);
-
- assertEquals(2, list.setInt(0, 0));
+ list.addInt(1);
+ list.addInt(3);
+
+ assertEquals(1, list.setInt(0, 0));
assertEquals(0, list.getInt(0));
- assertEquals(4, list.setInt(1, 0));
+ assertEquals(3, list.setInt(1, 0));
assertEquals(0, list.getInt(1));
-
+
try {
list.setInt(-1, 0);
fail();
@@ -221,7 +208,7 @@ public class IntArrayListTest extends TestCase {
// expected
}
}
-
+
public void testAdd() {
assertEquals(0, list.size());
@@ -231,28 +218,30 @@ public class IntArrayListTest extends TestCase {
assertTrue(list.add(3));
list.add(0, 4);
assertEquals(asList(4, 2, 3), list);
-
+
list.add(0, 1);
list.add(0, 0);
// Force a resize by getting up to 11 elements.
for (int i = 0; i < 6; i++) {
- list.add(5 + i);
+ list.add(Integer.valueOf(5 + i));
}
- assertEquals(asList(0, 1, 4, 2, 3, 5, 6, 7, 8, 9, 10), list);
-
+ assertEquals(
+ asList(0, 1, 4, 2, 3, 5, 6, 7, 8, 9, 10),
+ list);
+
try {
list.add(-1, 5);
} catch (IndexOutOfBoundsException e) {
// expected
}
-
+
try {
list.add(4, 5);
} catch (IndexOutOfBoundsException e) {
// expected
}
}
-
+
public void testAddInt() {
assertEquals(0, list.size());
@@ -262,7 +251,7 @@ public class IntArrayListTest extends TestCase {
list.addInt(3);
assertEquals(asList(2, 3), list);
}
-
+
public void testAddAll() {
assertEquals(0, list.size());
@@ -270,17 +259,17 @@ public class IntArrayListTest extends TestCase {
assertEquals(1, list.size());
assertEquals(1, (int) list.get(0));
assertEquals(1, list.getInt(0));
-
+
assertTrue(list.addAll(asList(2, 3, 4, 5, 6)));
assertEquals(asList(1, 2, 3, 4, 5, 6), list);
-
+
assertTrue(list.addAll(TERTIARY_LIST));
assertEquals(asList(1, 2, 3, 4, 5, 6, 1, 2, 3), list);
assertFalse(list.addAll(Collections.<Integer>emptyList()));
assertFalse(list.addAll(IntArrayList.emptyList()));
}
-
+
public void testRemove() {
list.addAll(TERTIARY_LIST);
assertEquals(1, (int) list.remove(0));
@@ -294,96 +283,96 @@ public class IntArrayListTest extends TestCase {
assertEquals(2, (int) list.remove(0));
assertEquals(asList(), list);
-
+
try {
list.remove(-1);
fail();
} catch (IndexOutOfBoundsException e) {
// expected
}
-
+
try {
list.remove(0);
} catch (IndexOutOfBoundsException e) {
// expected
}
}
-
+
private void assertImmutable(IntArrayList list) {
if (list.contains(1)) {
throw new RuntimeException("Cannot test the immutability of lists that contain 1.");
}
-
+
try {
list.add(1);
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.add(0, 1);
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.addAll(Collections.<Integer>emptyList());
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.addAll(Collections.singletonList(1));
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.addAll(new IntArrayList());
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.addAll(UNARY_LIST);
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.addAll(0, Collections.singleton(1));
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.addAll(0, UNARY_LIST);
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.addAll(0, Collections.<Integer>emptyList());
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.addInt(0);
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.clear();
fail();
@@ -397,63 +386,63 @@ public class IntArrayListTest extends TestCase {
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.remove(new Object());
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.removeAll(Collections.<Integer>emptyList());
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.removeAll(Collections.singleton(1));
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.removeAll(UNARY_LIST);
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.retainAll(Collections.<Integer>emptyList());
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.retainAll(Collections.singleton(1));
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.retainAll(UNARY_LIST);
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.set(0, 0);
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.setInt(0, 0);
fail();
@@ -461,7 +450,7 @@ public class IntArrayListTest extends TestCase {
// expected
}
}
-
+
private static IntArrayList newImmutableIntArrayList(int... elements) {
IntArrayList list = new IntArrayList();
for (int element : elements) {
diff --git a/java/src/test/java/com/google/protobuf/IsValidUtf8Test.java b/java/core/src/test/java/com/google/protobuf/IsValidUtf8Test.java
index 8751baae..756049b4 100644
--- a/java/src/test/java/com/google/protobuf/IsValidUtf8Test.java
+++ b/java/core/src/test/java/com/google/protobuf/IsValidUtf8Test.java
@@ -30,12 +30,18 @@
package com.google.protobuf;
+import static com.google.protobuf.IsValidUtf8TestUtil.DIRECT_NIO_FACTORY;
+import static com.google.protobuf.IsValidUtf8TestUtil.EXPECTED_ONE_BYTE_ROUNDTRIPPABLE_COUNT;
+import static com.google.protobuf.IsValidUtf8TestUtil.EXPECTED_THREE_BYTE_ROUNDTRIPPABLE_COUNT;
+import static com.google.protobuf.IsValidUtf8TestUtil.HEAP_NIO_FACTORY;
+import static com.google.protobuf.IsValidUtf8TestUtil.LITERAL_FACTORY;
+import static com.google.protobuf.IsValidUtf8TestUtil.testBytes;
+
+import com.google.protobuf.IsValidUtf8TestUtil.ByteStringFactory;
import com.google.protobuf.IsValidUtf8TestUtil.Shard;
import junit.framework.TestCase;
-import java.io.UnsupportedEncodingException;
-
/**
* Tests cases for {@link ByteString#isValidUtf8()}. This includes three
* brute force tests that actually test every permutation of one byte, two byte,
@@ -51,31 +57,33 @@ import java.io.UnsupportedEncodingException;
* @author martinrb@google.com (Martin Buchholz)
*/
public class IsValidUtf8Test extends TestCase {
-
/**
* Tests that round tripping of all two byte permutations work.
*/
- public void testIsValidUtf8_1Byte() throws UnsupportedEncodingException {
- IsValidUtf8TestUtil.testBytes(1,
- IsValidUtf8TestUtil.EXPECTED_ONE_BYTE_ROUNDTRIPPABLE_COUNT);
+ public void testIsValidUtf8_1Byte() {
+ testBytes(LITERAL_FACTORY, 1, EXPECTED_ONE_BYTE_ROUNDTRIPPABLE_COUNT);
+ testBytes(HEAP_NIO_FACTORY, 1, EXPECTED_ONE_BYTE_ROUNDTRIPPABLE_COUNT);
+ testBytes(DIRECT_NIO_FACTORY, 1, EXPECTED_ONE_BYTE_ROUNDTRIPPABLE_COUNT);
}
/**
* Tests that round tripping of all two byte permutations work.
*/
- public void testIsValidUtf8_2Bytes() throws UnsupportedEncodingException {
- IsValidUtf8TestUtil.testBytes(2,
- IsValidUtf8TestUtil.EXPECTED_TWO_BYTE_ROUNDTRIPPABLE_COUNT);
+ public void testIsValidUtf8_2Bytes() {
+ testBytes(LITERAL_FACTORY, 2, IsValidUtf8TestUtil.EXPECTED_TWO_BYTE_ROUNDTRIPPABLE_COUNT);
+ testBytes(HEAP_NIO_FACTORY, 2, IsValidUtf8TestUtil.EXPECTED_TWO_BYTE_ROUNDTRIPPABLE_COUNT);
+ testBytes(DIRECT_NIO_FACTORY, 2, IsValidUtf8TestUtil.EXPECTED_TWO_BYTE_ROUNDTRIPPABLE_COUNT);
}
/**
* Tests that round tripping of all three byte permutations work.
*/
- public void testIsValidUtf8_3Bytes() throws UnsupportedEncodingException {
+ public void testIsValidUtf8_3Bytes() {
// Travis' OOM killer doesn't like this test
if (System.getenv("TRAVIS") == null) {
- IsValidUtf8TestUtil.testBytes(3,
- IsValidUtf8TestUtil.EXPECTED_THREE_BYTE_ROUNDTRIPPABLE_COUNT);
+ testBytes(LITERAL_FACTORY, 3, EXPECTED_THREE_BYTE_ROUNDTRIPPABLE_COUNT);
+ testBytes(HEAP_NIO_FACTORY, 3, EXPECTED_THREE_BYTE_ROUNDTRIPPABLE_COUNT);
+ testBytes(DIRECT_NIO_FACTORY, 3, EXPECTED_THREE_BYTE_ROUNDTRIPPABLE_COUNT);
}
}
@@ -85,8 +93,7 @@ public class IsValidUtf8Test extends TestCase {
* {@link IsValidUtf8FourByteTest} is used for full coverage. This method
* tests specific four-byte cases.
*/
- public void testIsValidUtf8_4BytesSamples()
- throws UnsupportedEncodingException {
+ public void testIsValidUtf8_4BytesSamples() {
// Valid 4 byte.
assertValidUtf8(0xF0, 0xA4, 0xAD, 0xA2);
@@ -119,9 +126,7 @@ public class IsValidUtf8Test extends TestCase {
assertTrue(asBytes("\u024B62\u024B62").isValidUtf8());
// Mixed string
- assertTrue(
- asBytes("a\u020ac\u00a2b\\u024B62u020acc\u00a2de\u024B62")
- .isValidUtf8());
+ assertTrue(asBytes("a\u020ac\u00a2b\\u024B62u020acc\u00a2de\u024B62").isValidUtf8());
// Not a valid string
assertInvalidUtf8(-1, 0, -1, 0);
@@ -135,36 +140,35 @@ public class IsValidUtf8Test extends TestCase {
return realBytes;
}
- private ByteString toByteString(int... bytes) {
- return ByteString.copyFrom(toByteArray(bytes));
- }
-
- private void assertValidUtf8(int[] bytes, boolean not) {
+ private void assertValidUtf8(ByteStringFactory factory, int[] bytes, boolean not) {
byte[] realBytes = toByteArray(bytes);
assertTrue(not ^ Utf8.isValidUtf8(realBytes));
assertTrue(not ^ Utf8.isValidUtf8(realBytes, 0, bytes.length));
- ByteString lit = ByteString.copyFrom(realBytes);
- ByteString sub = lit.substring(0, bytes.length);
- assertTrue(not ^ lit.isValidUtf8());
+ ByteString leaf = factory.newByteString(realBytes);
+ ByteString sub = leaf.substring(0, bytes.length);
+ assertTrue(not ^ leaf.isValidUtf8());
assertTrue(not ^ sub.isValidUtf8());
ByteString[] ropes = {
- RopeByteString.newInstanceForTest(ByteString.EMPTY, lit),
- RopeByteString.newInstanceForTest(ByteString.EMPTY, sub),
- RopeByteString.newInstanceForTest(lit, ByteString.EMPTY),
- RopeByteString.newInstanceForTest(sub, ByteString.EMPTY),
- RopeByteString.newInstanceForTest(sub, lit)
- };
+ RopeByteString.newInstanceForTest(ByteString.EMPTY, leaf),
+ RopeByteString.newInstanceForTest(ByteString.EMPTY, sub),
+ RopeByteString.newInstanceForTest(leaf, ByteString.EMPTY),
+ RopeByteString.newInstanceForTest(sub, ByteString.EMPTY),
+ RopeByteString.newInstanceForTest(sub, leaf)};
for (ByteString rope : ropes) {
assertTrue(not ^ rope.isValidUtf8());
}
}
private void assertValidUtf8(int... bytes) {
- assertValidUtf8(bytes, false);
+ assertValidUtf8(LITERAL_FACTORY, bytes, false);
+ assertValidUtf8(HEAP_NIO_FACTORY, bytes, false);
+ assertValidUtf8(DIRECT_NIO_FACTORY, bytes, false);
}
private void assertInvalidUtf8(int... bytes) {
- assertValidUtf8(bytes, true);
+ assertValidUtf8(LITERAL_FACTORY, bytes, true);
+ assertValidUtf8(HEAP_NIO_FACTORY, bytes, true);
+ assertValidUtf8(DIRECT_NIO_FACTORY, bytes, true);
}
private static ByteString asBytes(String s) {
@@ -177,7 +181,6 @@ public class IsValidUtf8Test extends TestCase {
for (Shard shard : IsValidUtf8TestUtil.FOUR_BYTE_SHARDS) {
actual += shard.expected;
}
- assertEquals(IsValidUtf8TestUtil.EXPECTED_FOUR_BYTE_ROUNDTRIPPABLE_COUNT,
- actual);
+ assertEquals(IsValidUtf8TestUtil.EXPECTED_FOUR_BYTE_ROUNDTRIPPABLE_COUNT, actual);
}
}
diff --git a/java/src/test/java/com/google/protobuf/IsValidUtf8TestUtil.java b/java/core/src/test/java/com/google/protobuf/IsValidUtf8TestUtil.java
index 321669f3..16a808bf 100644
--- a/java/src/test/java/com/google/protobuf/IsValidUtf8TestUtil.java
+++ b/java/core/src/test/java/com/google/protobuf/IsValidUtf8TestUtil.java
@@ -30,9 +30,13 @@
package com.google.protobuf;
-import static junit.framework.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
-import java.io.UnsupportedEncodingException;
+import java.lang.ref.SoftReference;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharsetDecoder;
@@ -52,64 +56,105 @@ import java.util.logging.Logger;
* @author jonp@google.com (Jon Perlow)
* @author martinrb@google.com (Martin Buchholz)
*/
-class IsValidUtf8TestUtil {
- private static Logger logger = Logger.getLogger(
- IsValidUtf8TestUtil.class.getName());
+final class IsValidUtf8TestUtil {
+ private static Logger logger = Logger.getLogger(IsValidUtf8TestUtil.class.getName());
+
+ private IsValidUtf8TestUtil() {}
+
+ static interface ByteStringFactory {
+ ByteString newByteString(byte[] bytes);
+ }
+
+ static final ByteStringFactory LITERAL_FACTORY = new ByteStringFactory() {
+ @Override
+ public ByteString newByteString(byte[] bytes) {
+ return ByteString.wrap(bytes);
+ }
+ };
+
+ static final ByteStringFactory HEAP_NIO_FACTORY = new ByteStringFactory() {
+ @Override
+ public ByteString newByteString(byte[] bytes) {
+ return new NioByteString(ByteBuffer.wrap(bytes));
+ }
+ };
+
+ private static ThreadLocal<SoftReference<ByteBuffer>> directBuffer =
+ new ThreadLocal<SoftReference<ByteBuffer>>();
+
+ /**
+ * Factory for direct {@link ByteBuffer} instances. To reduce direct memory usage, this
+ * uses a thread local direct buffer. This means that each call will overwrite the buffer's
+ * contents from the previous call, so the calling code must be careful not to continue using
+ * a buffer returned from a previous invocation.
+ */
+ static final ByteStringFactory DIRECT_NIO_FACTORY = new ByteStringFactory() {
+ @Override
+ public ByteString newByteString(byte[] bytes) {
+ SoftReference<ByteBuffer> ref = directBuffer.get();
+ ByteBuffer buffer = ref == null ? null : ref.get();
+ if (buffer == null || buffer.capacity() < bytes.length) {
+ buffer = ByteBuffer.allocateDirect(bytes.length);
+ directBuffer.set(new SoftReference<ByteBuffer>(buffer));
+ }
+ buffer.clear();
+ buffer.put(bytes);
+ buffer.flip();
+ return new NioByteString(buffer);
+ }
+ };
// 128 - [chars 0x0000 to 0x007f]
- static long ONE_BYTE_ROUNDTRIPPABLE_CHARACTERS = 0x007f - 0x0000 + 1;
+ static final long ONE_BYTE_ROUNDTRIPPABLE_CHARACTERS = 0x007f - 0x0000 + 1;
// 128
- static long EXPECTED_ONE_BYTE_ROUNDTRIPPABLE_COUNT =
- ONE_BYTE_ROUNDTRIPPABLE_CHARACTERS;
+ static final long EXPECTED_ONE_BYTE_ROUNDTRIPPABLE_COUNT = ONE_BYTE_ROUNDTRIPPABLE_CHARACTERS;
// 1920 [chars 0x0080 to 0x07FF]
- static long TWO_BYTE_ROUNDTRIPPABLE_CHARACTERS = 0x07FF - 0x0080 + 1;
+ static final long TWO_BYTE_ROUNDTRIPPABLE_CHARACTERS = 0x07FF - 0x0080 + 1;
// 18,304
- static long EXPECTED_TWO_BYTE_ROUNDTRIPPABLE_COUNT =
+ static final long EXPECTED_TWO_BYTE_ROUNDTRIPPABLE_COUNT =
// Both bytes are one byte characters
(long) Math.pow(EXPECTED_ONE_BYTE_ROUNDTRIPPABLE_COUNT, 2) +
// The possible number of two byte characters
TWO_BYTE_ROUNDTRIPPABLE_CHARACTERS;
// 2048
- static long THREE_BYTE_SURROGATES = 2 * 1024;
+ static final long THREE_BYTE_SURROGATES = 2 * 1024;
// 61,440 [chars 0x0800 to 0xFFFF, minus surrogates]
- static long THREE_BYTE_ROUNDTRIPPABLE_CHARACTERS =
+ static final long THREE_BYTE_ROUNDTRIPPABLE_CHARACTERS =
0xFFFF - 0x0800 + 1 - THREE_BYTE_SURROGATES;
// 2,650,112
- static long EXPECTED_THREE_BYTE_ROUNDTRIPPABLE_COUNT =
+ static final long EXPECTED_THREE_BYTE_ROUNDTRIPPABLE_COUNT =
// All one byte characters
(long) Math.pow(EXPECTED_ONE_BYTE_ROUNDTRIPPABLE_COUNT, 3) +
// One two byte character and a one byte character
- 2 * TWO_BYTE_ROUNDTRIPPABLE_CHARACTERS *
- ONE_BYTE_ROUNDTRIPPABLE_CHARACTERS +
- // Three byte characters
+ 2 * TWO_BYTE_ROUNDTRIPPABLE_CHARACTERS * ONE_BYTE_ROUNDTRIPPABLE_CHARACTERS +
+ // Three byte characters
THREE_BYTE_ROUNDTRIPPABLE_CHARACTERS;
// 1,048,576 [chars 0x10000L to 0x10FFFF]
- static long FOUR_BYTE_ROUNDTRIPPABLE_CHARACTERS = 0x10FFFF - 0x10000L + 1;
+ static final long FOUR_BYTE_ROUNDTRIPPABLE_CHARACTERS = 0x10FFFF - 0x10000L + 1;
// 289,571,839
- static long EXPECTED_FOUR_BYTE_ROUNDTRIPPABLE_COUNT =
+ static final long EXPECTED_FOUR_BYTE_ROUNDTRIPPABLE_COUNT =
// All one byte characters
(long) Math.pow(EXPECTED_ONE_BYTE_ROUNDTRIPPABLE_COUNT, 4) +
// One and three byte characters
- 2 * THREE_BYTE_ROUNDTRIPPABLE_CHARACTERS *
- ONE_BYTE_ROUNDTRIPPABLE_CHARACTERS +
+ 2 * THREE_BYTE_ROUNDTRIPPABLE_CHARACTERS * ONE_BYTE_ROUNDTRIPPABLE_CHARACTERS +
// Two two byte characters
TWO_BYTE_ROUNDTRIPPABLE_CHARACTERS * TWO_BYTE_ROUNDTRIPPABLE_CHARACTERS +
// Permutations of one and two byte characters
- 3 * TWO_BYTE_ROUNDTRIPPABLE_CHARACTERS *
- ONE_BYTE_ROUNDTRIPPABLE_CHARACTERS *
- ONE_BYTE_ROUNDTRIPPABLE_CHARACTERS +
+ 3 * TWO_BYTE_ROUNDTRIPPABLE_CHARACTERS * ONE_BYTE_ROUNDTRIPPABLE_CHARACTERS
+ * ONE_BYTE_ROUNDTRIPPABLE_CHARACTERS
+ +
// Four byte characters
FOUR_BYTE_ROUNDTRIPPABLE_CHARACTERS;
- static class Shard {
+ static final class Shard {
final long index;
final long start;
final long lim;
@@ -138,7 +183,7 @@ class IsValidUtf8TestUtil {
// 97-111 are all 2342912
for (int i = 97; i <= 111; i++) {
- expected[i] = 2342912;
+ expected[i] = 2342912;
}
// 113-117 are all 1048576
@@ -158,22 +203,18 @@ class IsValidUtf8TestUtil {
return expected;
}
- static final List<Shard> FOUR_BYTE_SHARDS = generateFourByteShards(
- 128, FOUR_BYTE_SHARDS_EXPECTED_ROUNTRIPPABLES);
+ static final List<Shard> FOUR_BYTE_SHARDS =
+ generateFourByteShards(128, FOUR_BYTE_SHARDS_EXPECTED_ROUNTRIPPABLES);
- private static List<Shard> generateFourByteShards(
- int numShards, long[] expected) {
+ private static List<Shard> generateFourByteShards(int numShards, long[] expected) {
assertEquals(numShards, expected.length);
List<Shard> shards = new ArrayList<Shard>(numShards);
long LIM = 1L << 32;
long increment = LIM / numShards;
assertTrue(LIM % numShards == 0);
for (int i = 0; i < numShards; i++) {
- shards.add(new Shard(i,
- increment * i,
- increment * (i + 1),
- expected[i]));
+ shards.add(new Shard(i, increment * i, increment * (i + 1), expected[i]));
}
return shards;
}
@@ -182,12 +223,12 @@ class IsValidUtf8TestUtil {
* Helper to run the loop to test all the permutations for the number of bytes
* specified.
*
+ * @param factory the factory for {@link ByteString} instances.
* @param numBytes the number of bytes in the byte array
* @param expectedCount the expected number of roundtrippable permutations
*/
- static void testBytes(int numBytes, long expectedCount)
- throws UnsupportedEncodingException {
- testBytes(numBytes, expectedCount, 0, -1);
+ static void testBytes(ByteStringFactory factory, int numBytes, long expectedCount) {
+ testBytes(factory, numBytes, expectedCount, 0, -1);
}
/**
@@ -195,14 +236,15 @@ class IsValidUtf8TestUtil {
* specified. This overload is useful for debugging to get the loop to start
* at a certain character.
*
+ * @param factory the factory for {@link ByteString} instances.
* @param numBytes the number of bytes in the byte array
* @param expectedCount the expected number of roundtrippable permutations
* @param start the starting bytes encoded as a long as big-endian
* @param lim the limit of bytes to process encoded as a long as big-endian,
* or -1 to mean the max limit for numBytes
*/
- static void testBytes(int numBytes, long expectedCount, long start, long lim)
- throws UnsupportedEncodingException {
+ static void testBytes(
+ ByteStringFactory factory, int numBytes, long expectedCount, long start, long lim) {
Random rnd = new Random();
byte[] bytes = new byte[numBytes];
@@ -217,7 +259,7 @@ class IsValidUtf8TestUtil {
bytes[bytes.length - i - 1] = (byte) tmpByteChar;
tmpByteChar = tmpByteChar >> 8;
}
- ByteString bs = ByteString.copyFrom(bytes);
+ ByteString bs = factory.newByteString(bytes);
boolean isRoundTrippable = bs.isValidUtf8();
String s = new String(bytes, Internal.UTF_8);
byte[] bytesReencoded = s.getBytes(Internal.UTF_8);
@@ -236,14 +278,15 @@ class IsValidUtf8TestUtil {
int i = rnd.nextInt(numBytes);
int j = rnd.nextInt(numBytes);
if (j < i) {
- int tmp = i; i = j; j = tmp;
+ int tmp = i;
+ i = j;
+ j = tmp;
}
int state1 = Utf8.partialIsValidUtf8(Utf8.COMPLETE, bytes, 0, i);
int state2 = Utf8.partialIsValidUtf8(state1, bytes, i, j);
int state3 = Utf8.partialIsValidUtf8(state2, bytes, j, numBytes);
if (isRoundTrippable != (state3 == Utf8.COMPLETE)) {
- System.out.printf("state=%04x %04x %04x i=%d j=%d%n",
- state1, state2, state3, i, j);
+ System.out.printf("state=%04x %04x %04x i=%d j=%d%n", state1, state2, state3, i, j);
outputFailure(byteChar, bytes, bytesReencoded);
}
assertEquals(isRoundTrippable, (state3 == Utf8.COMPLETE));
@@ -251,36 +294,24 @@ class IsValidUtf8TestUtil {
// Test ropes built out of small partial sequences
ByteString rope = RopeByteString.newInstanceForTest(
bs.substring(0, i),
- RopeByteString.newInstanceForTest(
- bs.substring(i, j),
- bs.substring(j, numBytes)));
+ RopeByteString.newInstanceForTest(bs.substring(i, j), bs.substring(j, numBytes)));
assertSame(RopeByteString.class, rope.getClass());
- ByteString[] byteStrings = { bs, bs.substring(0, numBytes), rope };
+ ByteString[] byteStrings = {bs, bs.substring(0, numBytes), rope};
for (ByteString x : byteStrings) {
- assertEquals(isRoundTrippable,
- x.isValidUtf8());
- assertEquals(state3,
- x.partialIsValidUtf8(Utf8.COMPLETE, 0, numBytes));
-
- assertEquals(state1,
- x.partialIsValidUtf8(Utf8.COMPLETE, 0, i));
- assertEquals(state1,
- x.substring(0, i).partialIsValidUtf8(Utf8.COMPLETE, 0, i));
- assertEquals(state2,
- x.partialIsValidUtf8(state1, i, j - i));
- assertEquals(state2,
- x.substring(i, j).partialIsValidUtf8(state1, 0, j - i));
- assertEquals(state3,
- x.partialIsValidUtf8(state2, j, numBytes - j));
- assertEquals(state3,
- x.substring(j, numBytes)
- .partialIsValidUtf8(state2, 0, numBytes - j));
+ assertEquals(isRoundTrippable, x.isValidUtf8());
+ assertEquals(state3, x.partialIsValidUtf8(Utf8.COMPLETE, 0, numBytes));
+
+ assertEquals(state1, x.partialIsValidUtf8(Utf8.COMPLETE, 0, i));
+ assertEquals(state1, x.substring(0, i).partialIsValidUtf8(Utf8.COMPLETE, 0, i));
+ assertEquals(state2, x.partialIsValidUtf8(state1, i, j - i));
+ assertEquals(state2, x.substring(i, j).partialIsValidUtf8(state1, 0, j - i));
+ assertEquals(state3, x.partialIsValidUtf8(state2, j, numBytes - j));
+ assertEquals(state3, x.substring(j, numBytes).partialIsValidUtf8(state2, 0, numBytes - j));
}
// ByteString reduplication should not affect its UTF-8 validity.
- ByteString ropeADope =
- RopeByteString.newInstanceForTest(bs, bs.substring(0, numBytes));
+ ByteString ropeADope = RopeByteString.newInstanceForTest(bs, bs.substring(0, numBytes));
assertEquals(isRoundTrippable, ropeADope.isValidUtf8());
if (isRoundTrippable) {
@@ -288,8 +319,7 @@ class IsValidUtf8TestUtil {
}
count++;
if (byteChar != 0 && byteChar % 1000000L == 0) {
- logger.info("Processed " + (byteChar / 1000000L) +
- " million characters");
+ logger.info("Processed " + (byteChar / 1000000L) + " million characters");
}
}
logger.info("Round tripped " + countRoundTripped + " of " + count);
@@ -303,25 +333,26 @@ class IsValidUtf8TestUtil {
* actual String class, it's possible for incompatibilities to develop
* (although unlikely).
*
+ * @param factory the factory for {@link ByteString} instances.
* @param numBytes the number of bytes in the byte array
* @param expectedCount the expected number of roundtrippable permutations
* @param start the starting bytes encoded as a long as big-endian
* @param lim the limit of bytes to process encoded as a long as big-endian,
* or -1 to mean the max limit for numBytes
*/
- void testBytesUsingByteBuffers(
- int numBytes, long expectedCount, long start, long lim)
- throws UnsupportedEncodingException {
- CharsetDecoder decoder = Internal.UTF_8.newDecoder()
- .onMalformedInput(CodingErrorAction.REPLACE)
- .onUnmappableCharacter(CodingErrorAction.REPLACE);
- CharsetEncoder encoder = Internal.UTF_8.newEncoder()
- .onMalformedInput(CodingErrorAction.REPLACE)
- .onUnmappableCharacter(CodingErrorAction.REPLACE);
+ static void testBytesUsingByteBuffers(
+ ByteStringFactory factory, int numBytes, long expectedCount, long start, long lim) {
+ CharsetDecoder decoder =
+ Internal.UTF_8.newDecoder()
+ .onMalformedInput(CodingErrorAction.REPLACE)
+ .onUnmappableCharacter(CodingErrorAction.REPLACE);
+ CharsetEncoder encoder =
+ Internal.UTF_8.newEncoder()
+ .onMalformedInput(CodingErrorAction.REPLACE)
+ .onUnmappableCharacter(CodingErrorAction.REPLACE);
byte[] bytes = new byte[numBytes];
int maxChars = (int) (decoder.maxCharsPerByte() * numBytes) + 1;
- char[] charsDecoded =
- new char[(int) (decoder.maxCharsPerByte() * numBytes) + 1];
+ char[] charsDecoded = new char[(int) (decoder.maxCharsPerByte() * numBytes) + 1];
int maxBytes = (int) (encoder.maxBytesPerChar() * maxChars) + 1;
byte[] bytesReencoded = new byte[maxBytes];
@@ -347,7 +378,7 @@ class IsValidUtf8TestUtil {
bytes[bytes.length - i - 1] = (byte) tmpByteChar;
tmpByteChar = tmpByteChar >> 8;
}
- boolean isRoundTrippable = ByteString.copyFrom(bytes).isValidUtf8();
+ boolean isRoundTrippable = factory.newByteString(bytes).isValidUtf8();
CoderResult result = decoder.decode(bb, cb, true);
assertFalse(result.isError());
result = decoder.flush(cb);
@@ -382,8 +413,7 @@ class IsValidUtf8TestUtil {
countRoundTripped++;
}
if (byteChar != 0 && byteChar % 1000000 == 0) {
- logger.info("Processed " + (byteChar / 1000000) +
- " million characters");
+ logger.info("Processed " + (byteChar / 1000000) + " million characters");
}
}
logger.info("Round tripped " + countRoundTripped + " of " + count);
@@ -394,10 +424,9 @@ class IsValidUtf8TestUtil {
outputFailure(byteChar, bytes, after, after.length);
}
- private static void outputFailure(long byteChar, byte[] bytes, byte[] after,
- int len) {
- fail("Failure: (" + Long.toHexString(byteChar) + ") " +
- toHexString(bytes) + " => " + toHexString(after, len));
+ private static void outputFailure(long byteChar, byte[] bytes, byte[] after, int len) {
+ fail("Failure: (" + Long.toHexString(byteChar) + ") " + toHexString(bytes) + " => "
+ + toHexString(after, len));
}
private static String toHexString(byte[] b) {
@@ -416,5 +445,4 @@ class IsValidUtf8TestUtil {
s.append("\"");
return s.toString();
}
-
}
diff --git a/java/src/test/java/com/google/protobuf/LazyFieldLiteTest.java b/java/core/src/test/java/com/google/protobuf/LazyFieldLiteTest.java
index 211b5697..8d1de6dc 100644
--- a/java/src/test/java/com/google/protobuf/LazyFieldLiteTest.java
+++ b/java/core/src/test/java/com/google/protobuf/LazyFieldLiteTest.java
@@ -36,9 +36,10 @@ import static protobuf_unittest.UnittestProto.optionalInt64Extension;
import protobuf_unittest.UnittestProto.TestAllExtensions;
import protobuf_unittest.UnittestProto.TestAllTypes;
-import java.io.IOException;
import junit.framework.TestCase;
+import java.io.IOException;
+
/**
* Unit test for {@link LazyFieldLite}.
*
diff --git a/java/src/test/java/com/google/protobuf/LazyFieldTest.java b/java/core/src/test/java/com/google/protobuf/LazyFieldTest.java
index 2b900065..ce473ae9 100644
--- a/java/src/test/java/com/google/protobuf/LazyFieldTest.java
+++ b/java/core/src/test/java/com/google/protobuf/LazyFieldTest.java
@@ -33,9 +33,10 @@ package com.google.protobuf;
import protobuf_unittest.UnittestProto.TestAllExtensions;
import protobuf_unittest.UnittestProto.TestAllTypes;
-import java.io.IOException;
import junit.framework.TestCase;
+import java.io.IOException;
+
/**
* Unit test for {@link LazyField}.
*
diff --git a/java/src/test/java/com/google/protobuf/LazyMessageLiteTest.java b/java/core/src/test/java/com/google/protobuf/LazyMessageLiteTest.java
index afe0fffd..e5b11cf1 100644
--- a/java/src/test/java/com/google/protobuf/LazyMessageLiteTest.java
+++ b/java/core/src/test/java/com/google/protobuf/LazyMessageLiteTest.java
@@ -251,6 +251,23 @@ public class LazyMessageLiteTest extends TestCase {
assertEquals(42, merged.getOneofInner().getNumWithDefault());
}
+ // Regression test for b/28198805.
+ public void testMergeOneofMessages() throws Exception {
+ LazyInnerMessageLite inner = LazyInnerMessageLite.newBuilder().build();
+ LazyMessageLite outer = LazyMessageLite.newBuilder().setOneofInner(inner).build();
+ ByteString data1 = outer.toByteString();
+
+ // The following should not alter the content of the 'outer' message.
+ LazyMessageLite.Builder merged = LazyMessageLite.newBuilder().mergeFrom(outer);
+ LazyInnerMessageLite anotherInner = LazyInnerMessageLite.newBuilder().setNum(12345).build();
+ merged.setOneofInner(anotherInner);
+
+ // Check that the 'outer' stays the same.
+ ByteString data2 = outer.toByteString();
+ assertEquals(data1, data2);
+ assertEquals(0, outer.getOneofInner().getNum());
+ }
+
public void testSerialize() throws InvalidProtocolBufferException {
LazyNestedInnerMessageLite nested = LazyNestedInnerMessageLite.newBuilder()
.setNum(3)
diff --git a/java/src/test/java/com/google/protobuf/LazyStringArrayListTest.java b/java/core/src/test/java/com/google/protobuf/LazyStringArrayListTest.java
index 0f42ac50..497c4df2 100644
--- a/java/src/test/java/com/google/protobuf/LazyStringArrayListTest.java
+++ b/java/core/src/test/java/com/google/protobuf/LazyStringArrayListTest.java
@@ -35,6 +35,7 @@ import static java.util.Arrays.asList;
import junit.framework.TestCase;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.List;
@@ -233,7 +234,7 @@ public class LazyStringArrayListTest extends TestCase {
}
try {
- list.addAllByteArray(asList(BYTE_STRING_A.toByteArray()));
+ list.addAllByteArray(Collections.singletonList(BYTE_STRING_A.toByteArray()));
fail();
} catch (UnsupportedOperationException e) {
// expected
diff --git a/java/src/test/java/com/google/protobuf/LazyStringEndToEndTest.java b/java/core/src/test/java/com/google/protobuf/LazyStringEndToEndTest.java
index 0ef414aa..0ef414aa 100644
--- a/java/src/test/java/com/google/protobuf/LazyStringEndToEndTest.java
+++ b/java/core/src/test/java/com/google/protobuf/LazyStringEndToEndTest.java
diff --git a/java/src/test/java/com/google/protobuf/LiteEqualsAndHashTest.java b/java/core/src/test/java/com/google/protobuf/LiteEqualsAndHashTest.java
index 035917c8..4764ca1b 100644
--- a/java/src/test/java/com/google/protobuf/LiteEqualsAndHashTest.java
+++ b/java/core/src/test/java/com/google/protobuf/LiteEqualsAndHashTest.java
@@ -33,6 +33,8 @@ package com.google.protobuf;
import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.Bar;
import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.BarPrime;
import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.Foo;
+import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.TestOneofEquals;
+import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.TestRecursiveOneof;
import junit.framework.TestCase;
@@ -53,7 +55,7 @@ public class LiteEqualsAndHashTest extends TestCase {
// correctly when linked only against the lite library.
// We do however do some basic testing to make sure that equals is actually
- // overriden to test for value equality rather than simple object equality.
+ // overridden to test for value equality rather than simple object equality.
// Check that two identical objs are equal.
Foo foo1a = Foo.newBuilder()
@@ -83,6 +85,16 @@ public class LiteEqualsAndHashTest extends TestCase {
assertFalse(bar.equals(barPrime));
}
+ public void testOneofEquals() throws Exception {
+ TestOneofEquals.Builder builder = TestOneofEquals.newBuilder();
+ TestOneofEquals message1 = builder.build();
+ // Set message2's name field to default value. The two messages should be different when we
+ // check with the oneof case.
+ builder.setName("");
+ TestOneofEquals message2 = builder.build();
+ assertFalse(message1.equals(message2));
+ }
+
public void testEqualsAndHashCodeWithUnknownFields() throws InvalidProtocolBufferException {
Foo fooWithOnlyValue = Foo.newBuilder()
.setValue(1)
@@ -105,4 +117,9 @@ public class LiteEqualsAndHashTest extends TestCase {
assertFalse(o1.equals(o2));
assertFalse(o1.hashCode() == o2.hashCode());
}
+
+ public void testRecursiveHashcode() {
+ // This tests that we don't infinite loop.
+ TestRecursiveOneof.getDefaultInstance().hashCode();
+ }
}
diff --git a/java/src/test/java/com/google/protobuf/LiteTest.java b/java/core/src/test/java/com/google/protobuf/LiteTest.java
index b1f298ff..b3a246dc 100644
--- a/java/src/test/java/com/google/protobuf/LiteTest.java
+++ b/java/core/src/test/java/com/google/protobuf/LiteTest.java
@@ -33,22 +33,31 @@ package com.google.protobuf;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
+import com.google.protobuf.UnittestImportLite.ImportEnumLite;
+import com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite;
import com.google.protobuf.UnittestLite;
import com.google.protobuf.UnittestLite.ForeignEnumLite;
import com.google.protobuf.UnittestLite.ForeignMessageLite;
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.OneofFieldCase;
import com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup;
import com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup;
import com.google.protobuf.UnittestLite.TestAllTypesLiteOrBuilder;
import com.google.protobuf.UnittestLite.TestNestedExtensionLite;
+import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.Bar;
+import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.BarPrime;
+import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.Foo;
+import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.TestOneofEquals;
+import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.TestRecursiveOneof;
import junit.framework.TestCase;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
+import java.io.NotSerializableException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
@@ -58,6 +67,7 @@ import java.io.ObjectOutputStream;
* @author kenton@google.com Kenton Varda
*/
public class LiteTest extends TestCase {
+ @Override
public void setUp() throws Exception {
// Test that nested extensions are initialized correctly even if the outer
// class has not been accessed directly. This was once a bug with lite
@@ -128,33 +138,7 @@ public class LiteTest extends TestCase {
assertEquals(7, message2.getExtension(
UnittestLite.optionalNestedMessageExtensionLite).getBb());
}
-
- public void testSerialize() throws Exception {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- TestAllTypesLite expected =
- TestAllTypesLite.newBuilder()
- .setOptionalInt32(123)
- .addRepeatedString("hello")
- .setOptionalNestedMessage(
- TestAllTypesLite.NestedMessage.newBuilder().setBb(7))
- .build();
- ObjectOutputStream out = new ObjectOutputStream(baos);
- try {
- out.writeObject(expected);
- } finally {
- out.close();
- }
- ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
- ObjectInputStream in = new ObjectInputStream(bais);
- TestAllTypesLite actual = (TestAllTypesLite) in.readObject();
- assertEquals(expected.getOptionalInt32(), actual.getOptionalInt32());
- assertEquals(expected.getRepeatedStringCount(),
- actual.getRepeatedStringCount());
- assertEquals(expected.getRepeatedString(0),
- actual.getRepeatedString(0));
- assertEquals(expected.getOptionalNestedMessage().getBb(),
- actual.getOptionalNestedMessage().getBb());
- }
+
public void testClone() {
TestAllTypesLite.Builder expected = TestAllTypesLite.newBuilder()
@@ -327,11 +311,9 @@ public class LiteTest extends TestCase {
assertEquals(
ForeignMessageLite.getDefaultInstance(),
message.getOptionalForeignMessage());
- // LITE_RUNTIME doesn't implement equals so we compare on a property and
- // ensure the property isn't set on foreignMessage.
- assertEquals(3, builder.getOptionalForeignMessage().getC());
+ assertEquals(foreignMessageBuilder.build(), builder.getOptionalForeignMessage());
messageAfterBuild = builder.build();
- assertEquals(3, messageAfterBuild.getOptionalForeignMessage().getC());
+ assertEquals(foreignMessageBuilder.build(), messageAfterBuild.getOptionalForeignMessage());
assertEquals(
ForeignMessageLite.getDefaultInstance(),
message.getOptionalForeignMessage());
@@ -339,7 +321,7 @@ public class LiteTest extends TestCase {
assertEquals(
ForeignMessageLite.getDefaultInstance(),
builder.getOptionalForeignMessage());
- assertEquals(3, messageAfterBuild.getOptionalForeignMessage().getC());
+ assertEquals(foreignMessageBuilder.build(), messageAfterBuild.getOptionalForeignMessage());
message = builder.build();
OptionalGroup optionalGroup = OptionalGroup.newBuilder()
@@ -364,17 +346,15 @@ public class LiteTest extends TestCase {
builder.setOptionalGroup(optionalGroupBuilder);
assertEquals(
OptionalGroup.getDefaultInstance(), message.getOptionalGroup());
- // LITE_RUNTIME doesn't implement equals so we compare on a property and
- // ensure the property isn't set on optionalGroup.
- assertEquals(3, builder.getOptionalGroup().getA());
+ assertEquals(optionalGroupBuilder.build(), builder.getOptionalGroup());
messageAfterBuild = builder.build();
- assertEquals(3, messageAfterBuild.getOptionalGroup().getA());
+ assertEquals(optionalGroupBuilder.build(), messageAfterBuild.getOptionalGroup());
assertEquals(
OptionalGroup.getDefaultInstance(), message.getOptionalGroup());
builder.clearOptionalGroup();
assertEquals(
OptionalGroup.getDefaultInstance(), builder.getOptionalGroup());
- assertEquals(3, messageAfterBuild.getOptionalGroup().getA());
+ assertEquals(optionalGroupBuilder.build(), messageAfterBuild.getOptionalGroup());
message = builder.build();
builder.setOptionalInt32(1);
@@ -425,17 +405,16 @@ public class LiteTest extends TestCase {
assertEquals(
NestedMessage.getDefaultInstance(),
message.getOptionalLazyMessage());
- // LITE_RUNTIME doesn't implement equals so we compare on a property.
- assertEquals(3, builder.getOptionalLazyMessage().getBb());
+ assertEquals(nestedMessageBuilder.build(), builder.getOptionalLazyMessage());
messageAfterBuild = builder.build();
- assertEquals(3, messageAfterBuild.getOptionalLazyMessage().getBb());
+ assertEquals(nestedMessageBuilder.build(), messageAfterBuild.getOptionalLazyMessage());
assertEquals(
NestedMessage.getDefaultInstance(),
message.getOptionalLazyMessage());
builder.clearOptionalLazyMessage();
assertEquals(
NestedMessage.getDefaultInstance(), builder.getOptionalLazyMessage());
- assertEquals(3, messageAfterBuild.getOptionalLazyMessage().getBb());
+ assertEquals(nestedMessageBuilder.build(), messageAfterBuild.getOptionalLazyMessage());
message = builder.build();
builder.setOptionalSfixed32(1);
@@ -1125,8 +1104,7 @@ public class LiteTest extends TestCase {
assertEquals(0, message.getRepeatedForeignMessageCount());
builder.setRepeatedForeignMessage(
0, ForeignMessageLite.getDefaultInstance());
- // LITE_RUNTIME doesn't implement equals so we compare on a property.
- assertEquals(3, messageAfterBuild.getRepeatedForeignMessage(0).getC());
+ assertEquals(foreignMessageBuilder.build(), messageAfterBuild.getRepeatedForeignMessage(0));
assertEquals(
ForeignMessageLite.getDefaultInstance(),
builder.getRepeatedForeignMessage(0));
@@ -1139,8 +1117,7 @@ public class LiteTest extends TestCase {
builder.setRepeatedForeignMessage(0, foreignMessageBuilder);
assertEquals(
foreignMessage, messageAfterBuild.getRepeatedForeignMessage(0));
- // LITE_RUNTIME doesn't implement equals so we compare on a property.
- assertEquals(3, builder.getRepeatedForeignMessage(0).getC());
+ assertEquals(foreignMessageBuilder.build(), builder.getRepeatedForeignMessage(0));
builder.clearRepeatedForeignMessage();
message = builder.build();
@@ -1173,9 +1150,7 @@ public class LiteTest extends TestCase {
messageAfterBuild = builder.build();
assertEquals(0, message.getRepeatedGroupCount());
builder.setRepeatedGroup(0, RepeatedGroup.getDefaultInstance());
- // LITE_RUNTIME doesn't implement equals so we compare on a property and
- // ensure the property isn't set on repeatedGroup.
- assertEquals(3, messageAfterBuild.getRepeatedGroup(0).getA());
+ assertEquals(repeatedGroupBuilder.build(), messageAfterBuild.getRepeatedGroup(0));
assertEquals(
RepeatedGroup.getDefaultInstance(), builder.getRepeatedGroup(0));
builder.clearRepeatedGroup();
@@ -1185,9 +1160,7 @@ public class LiteTest extends TestCase {
messageAfterBuild = builder.build();
assertEquals(0, message.getRepeatedGroupCount());
builder.setRepeatedGroup(0, RepeatedGroup.getDefaultInstance());
- // LITE_RUNTIME doesn't implement equals so we compare on a property and
- // ensure the property isn't set on repeatedGroup.
- assertEquals(3, messageAfterBuild.getRepeatedGroup(0).getA());
+ assertEquals(repeatedGroupBuilder.build(), messageAfterBuild.getRepeatedGroup(0));
assertEquals(
RepeatedGroup.getDefaultInstance(), builder.getRepeatedGroup(0));
builder.clearRepeatedGroup();
@@ -1235,9 +1208,7 @@ public class LiteTest extends TestCase {
messageAfterBuild = builder.build();
assertEquals(0, message.getRepeatedLazyMessageCount());
builder.setRepeatedLazyMessage(0, NestedMessage.getDefaultInstance());
- // LITE_RUNTIME doesn't implement equals so we compare on a property and
- // ensure the property isn't set on repeatedGroup.
- assertEquals(3, messageAfterBuild.getRepeatedLazyMessage(0).getBb());
+ assertEquals(nestedMessageBuilder.build(), messageAfterBuild.getRepeatedLazyMessage(0));
assertEquals(
NestedMessage.getDefaultInstance(), builder.getRepeatedLazyMessage(0));
builder.clearRepeatedLazyMessage();
@@ -1247,9 +1218,7 @@ public class LiteTest extends TestCase {
messageAfterBuild = builder.build();
assertEquals(0, message.getRepeatedLazyMessageCount());
builder.setRepeatedLazyMessage(0, NestedMessage.getDefaultInstance());
- // LITE_RUNTIME doesn't implement equals so we compare on a property and
- // ensure the property isn't set on repeatedGroup.
- assertEquals(3, messageAfterBuild.getRepeatedLazyMessage(0).getBb());
+ assertEquals(nestedMessageBuilder.build(), messageAfterBuild.getRepeatedLazyMessage(0));
assertEquals(
NestedMessage.getDefaultInstance(), builder.getRepeatedLazyMessage(0));
builder.clearRepeatedLazyMessage();
@@ -1459,4 +1428,829 @@ public class LiteTest extends TestCase {
11, (int) extendableMessage.getExtension(
UnittestLite.optionalFixed32ExtensionLite));
}
+
+ public void testToStringDefaultInstance() throws Exception {
+ assertToStringEquals("", TestAllTypesLite.getDefaultInstance());
+ }
+
+ public void testToStringPrimitives() throws Exception {
+ TestAllTypesLite proto = TestAllTypesLite.newBuilder()
+ .setOptionalInt32(1)
+ .setOptionalInt64(9223372036854775807L)
+ .build();
+ assertToStringEquals("optional_int32: 1\noptional_int64: 9223372036854775807", proto);
+
+ proto = TestAllTypesLite.newBuilder()
+ .setOptionalBool(true)
+ .setOptionalNestedEnum(TestAllTypesLite.NestedEnum.BAZ)
+ .build();
+ assertToStringEquals("optional_bool: true\noptional_nested_enum: BAZ", proto);
+
+ proto = TestAllTypesLite.newBuilder()
+ .setOptionalFloat(2.72f)
+ .setOptionalDouble(3.14)
+ .build();
+ assertToStringEquals("optional_double: 3.14\noptional_float: 2.72", proto);
+ }
+
+ public void testToStringStringFields() throws Exception {
+ TestAllTypesLite proto = TestAllTypesLite.newBuilder()
+ .setOptionalString("foo\"bar\nbaz\\")
+ .build();
+ assertToStringEquals("optional_string: \"foo\\\"bar\\nbaz\\\\\"", proto);
+
+ proto = TestAllTypesLite.newBuilder()
+ .setOptionalString("\u6587")
+ .build();
+ assertToStringEquals("optional_string: \"\\346\\226\\207\"", proto);
+ }
+
+ public void testToStringNestedMessage() throws Exception {
+ TestAllTypesLite proto = TestAllTypesLite.newBuilder()
+ .setOptionalNestedMessage(TestAllTypesLite.NestedMessage.getDefaultInstance())
+ .build();
+ assertToStringEquals("optional_nested_message {\n}", proto);
+
+ proto = TestAllTypesLite.newBuilder()
+ .setOptionalNestedMessage(
+ TestAllTypesLite.NestedMessage.newBuilder().setBb(7))
+ .build();
+ assertToStringEquals("optional_nested_message {\n bb: 7\n}", proto);
+ }
+
+ public void testToStringRepeatedFields() throws Exception {
+ TestAllTypesLite proto = TestAllTypesLite.newBuilder()
+ .addRepeatedInt32(32)
+ .addRepeatedInt32(32)
+ .addRepeatedInt64(64)
+ .build();
+ assertToStringEquals("repeated_int32: 32\nrepeated_int32: 32\nrepeated_int64: 64", proto);
+
+ proto = TestAllTypesLite.newBuilder()
+ .addRepeatedLazyMessage(
+ TestAllTypesLite.NestedMessage.newBuilder().setBb(7))
+ .addRepeatedLazyMessage(
+ TestAllTypesLite.NestedMessage.newBuilder().setBb(8))
+ .build();
+ assertToStringEquals(
+ "repeated_lazy_message {\n bb: 7\n}\nrepeated_lazy_message {\n bb: 8\n}",
+ proto);
+ }
+
+ public void testToStringForeignFields() throws Exception {
+ TestAllTypesLite proto = TestAllTypesLite.newBuilder()
+ .setOptionalForeignEnum(ForeignEnumLite.FOREIGN_LITE_BAR)
+ .setOptionalForeignMessage(
+ ForeignMessageLite.newBuilder()
+ .setC(3))
+ .build();
+ assertToStringEquals(
+ "optional_foreign_enum: FOREIGN_LITE_BAR\noptional_foreign_message {\n c: 3\n}",
+ proto);
+ }
+
+ public void testToStringExtensions() throws Exception {
+ TestAllExtensionsLite message = TestAllExtensionsLite.newBuilder()
+ .setExtension(UnittestLite.optionalInt32ExtensionLite, 123)
+ .addExtension(UnittestLite.repeatedStringExtensionLite, "spam")
+ .addExtension(UnittestLite.repeatedStringExtensionLite, "eggs")
+ .setExtension(UnittestLite.optionalNestedEnumExtensionLite,
+ TestAllTypesLite.NestedEnum.BAZ)
+ .setExtension(UnittestLite.optionalNestedMessageExtensionLite,
+ TestAllTypesLite.NestedMessage.newBuilder().setBb(7).build())
+ .build();
+ assertToStringEquals(
+ "[1]: 123\n[18] {\n bb: 7\n}\n[21]: 3\n[44]: \"spam\"\n[44]: \"eggs\"",
+ message);
+ }
+
+ public void testToStringUnknownFields() throws Exception {
+ TestAllExtensionsLite messageWithExtensions = TestAllExtensionsLite.newBuilder()
+ .setExtension(UnittestLite.optionalInt32ExtensionLite, 123)
+ .addExtension(UnittestLite.repeatedStringExtensionLite, "spam")
+ .addExtension(UnittestLite.repeatedStringExtensionLite, "eggs")
+ .setExtension(UnittestLite.optionalNestedEnumExtensionLite,
+ TestAllTypesLite.NestedEnum.BAZ)
+ .setExtension(UnittestLite.optionalNestedMessageExtensionLite,
+ TestAllTypesLite.NestedMessage.newBuilder().setBb(7).build())
+ .build();
+ TestAllExtensionsLite messageWithUnknownFields = TestAllExtensionsLite.parseFrom(
+ messageWithExtensions.toByteArray());
+ assertToStringEquals(
+ "1: 123\n18: \"\\b\\a\"\n21: 3\n44: \"spam\"\n44: \"eggs\"",
+ messageWithUnknownFields);
+ }
+
+ public void testToStringLazyMessage() throws Exception {
+ TestAllTypesLite message = TestAllTypesLite.newBuilder()
+ .setOptionalLazyMessage(NestedMessage.newBuilder().setBb(1).build())
+ .build();
+ assertToStringEquals("optional_lazy_message {\n bb: 1\n}", message);
+ }
+
+ public void testToStringGroup() throws Exception {
+ TestAllTypesLite message = TestAllTypesLite.newBuilder()
+ .setOptionalGroup(OptionalGroup.newBuilder().setA(1).build())
+ .build();
+ assertToStringEquals("optional_group {\n a: 1\n}", message);
+ }
+
+ public void testToStringOneof() throws Exception {
+ TestAllTypesLite message = TestAllTypesLite.newBuilder()
+ .setOneofString("hello")
+ .build();
+ assertToStringEquals("oneof_string: \"hello\"", message);
+ }
+
+ // Asserts that the toString() representation of the message matches the expected. This verifies
+ // the first line starts with a comment; but, does not factor in said comment as part of the
+ // comparison as it contains unstable addresses.
+ private static void assertToStringEquals(String expected, MessageLite message) {
+ String toString = message.toString();
+ assertEquals('#', toString.charAt(0));
+ if (toString.indexOf("\n") >= 0) {
+ toString = toString.substring(toString.indexOf("\n") + 1);
+ } else {
+ toString = "";
+ }
+ assertEquals(expected, toString);
+ }
+
+ public void testParseLazy() throws Exception {
+ ByteString bb = TestAllTypesLite.newBuilder()
+ .setOptionalLazyMessage(NestedMessage.newBuilder()
+ .setBb(11)
+ .build())
+ .build().toByteString();
+ ByteString cc = TestAllTypesLite.newBuilder()
+ .setOptionalLazyMessage(NestedMessage.newBuilder()
+ .setCc(22)
+ .build())
+ .build().toByteString();
+
+ ByteString concat = bb.concat(cc);
+ TestAllTypesLite message = TestAllTypesLite.parseFrom(concat);
+
+ assertEquals(11, message.getOptionalLazyMessage().getBb());
+ assertEquals(22L, message.getOptionalLazyMessage().getCc());
+ }
+
+ public void testParseLazy_oneOf() throws Exception {
+ ByteString bb = TestAllTypesLite.newBuilder()
+ .setOneofLazyNestedMessage(NestedMessage.newBuilder()
+ .setBb(11)
+ .build())
+ .build().toByteString();
+ ByteString cc = TestAllTypesLite.newBuilder()
+ .setOneofLazyNestedMessage(NestedMessage.newBuilder()
+ .setCc(22)
+ .build())
+ .build().toByteString();
+
+ ByteString concat = bb.concat(cc);
+ TestAllTypesLite message = TestAllTypesLite.parseFrom(concat);
+
+ assertEquals(11, message.getOneofLazyNestedMessage().getBb());
+ assertEquals(22L, message.getOneofLazyNestedMessage().getCc());
+ }
+
+ public void testMergeFromStream_repeatedField() throws Exception {
+ TestAllTypesLite.Builder builder = TestAllTypesLite.newBuilder()
+ .addRepeatedString("hello");
+ builder.mergeFrom(CodedInputStream.newInstance(builder.build().toByteArray()));
+
+ assertEquals(2, builder.getRepeatedStringCount());
+ }
+
+ public void testMergeFromStream_invalidBytes() throws Exception {
+ TestAllTypesLite.Builder builder = TestAllTypesLite.newBuilder()
+ .setDefaultBool(true);
+ try {
+ builder.mergeFrom(CodedInputStream.newInstance("Invalid bytes".getBytes(Internal.UTF_8)));
+ fail();
+ } catch (InvalidProtocolBufferException expected) {}
+ }
+
+ public void testMergeFrom_sanity() throws Exception {
+ TestAllTypesLite one = TestUtilLite.getAllLiteSetBuilder().build();
+ byte[] bytes = one.toByteArray();
+ TestAllTypesLite two = TestAllTypesLite.parseFrom(bytes);
+
+ one = one.toBuilder().mergeFrom(one).build();
+ two = two.toBuilder().mergeFrom(bytes).build();
+ assertEquals(one, two);
+ assertEquals(two, one);
+ assertEquals(one.hashCode(), two.hashCode());
+ }
+
+ public void testMergeFromNoLazyFieldSharing() throws Exception {
+ TestAllTypesLite.Builder sourceBuilder = TestAllTypesLite.newBuilder().setOptionalLazyMessage(
+ TestAllTypesLite.NestedMessage.newBuilder().setBb(1));
+ TestAllTypesLite.Builder targetBuilder =
+ TestAllTypesLite.newBuilder().mergeFrom(sourceBuilder.build());
+ assertEquals(1, sourceBuilder.getOptionalLazyMessage().getBb());
+ // now change the sourceBuilder, and target value shouldn't be affected.
+ sourceBuilder.setOptionalLazyMessage(
+ TestAllTypesLite.NestedMessage.newBuilder().setBb(2));
+ assertEquals(1, targetBuilder.getOptionalLazyMessage().getBb());
+ }
+
+ public void testEquals_notEqual() throws Exception {
+ TestAllTypesLite one = TestUtilLite.getAllLiteSetBuilder().build();
+ byte[] bytes = one.toByteArray();
+ TestAllTypesLite two = one.toBuilder().mergeFrom(one).mergeFrom(bytes).build();
+
+ assertFalse(one.equals(two));
+ assertFalse(two.equals(one));
+
+ assertFalse(one.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(one));
+
+ TestAllTypesLite oneFieldSet = TestAllTypesLite.newBuilder()
+ .setDefaultBool(true)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setDefaultBytes(ByteString.EMPTY)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setDefaultCord("")
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setDefaultCordBytes(ByteString.EMPTY)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setDefaultDouble(0)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setDefaultFixed32(0)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setDefaultFixed64(0)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setDefaultFloat(0)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setDefaultForeignEnum(ForeignEnumLite.FOREIGN_LITE_BAR)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setDefaultImportEnum(ImportEnumLite.IMPORT_LITE_BAR)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setDefaultInt32(0)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setDefaultInt64(0)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setDefaultNestedEnum(NestedEnum.BAR)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setDefaultSfixed32(0)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setDefaultSfixed64(0)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setDefaultSint32(0)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setDefaultSint64(0)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setDefaultString("")
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setDefaultStringBytes(ByteString.EMPTY)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setDefaultStringPiece("")
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setDefaultStringPieceBytes(ByteString.EMPTY)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setDefaultUint32(0)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setDefaultUint64(0)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .addRepeatedBool(true)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .addRepeatedBytes(ByteString.EMPTY)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .addRepeatedCord("")
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .addRepeatedCordBytes(ByteString.EMPTY)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .addRepeatedDouble(0)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .addRepeatedFixed32(0)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .addRepeatedFixed64(0)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .addRepeatedFloat(0)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .addRepeatedForeignEnum(ForeignEnumLite.FOREIGN_LITE_BAR)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .addRepeatedImportEnum(ImportEnumLite.IMPORT_LITE_BAR)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .addRepeatedInt32(0)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .addRepeatedInt64(0)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .addRepeatedNestedEnum(NestedEnum.BAR)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .addRepeatedSfixed32(0)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .addRepeatedSfixed64(0)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .addRepeatedSint32(0)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .addRepeatedSint64(0)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .addRepeatedString("")
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .addRepeatedStringBytes(ByteString.EMPTY)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .addRepeatedStringPiece("")
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .addRepeatedStringPieceBytes(ByteString.EMPTY)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .addRepeatedUint32(0)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .addRepeatedUint64(0)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setOptionalBool(true)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setOptionalBytes(ByteString.EMPTY)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setOptionalCord("")
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setOptionalCordBytes(ByteString.EMPTY)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setOptionalDouble(0)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setOptionalFixed32(0)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setOptionalFixed64(0)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setOptionalFloat(0)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setOptionalForeignEnum(ForeignEnumLite.FOREIGN_LITE_BAR)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setOptionalImportEnum(ImportEnumLite.IMPORT_LITE_BAR)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setOptionalInt32(0)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setOptionalInt64(0)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setOptionalNestedEnum(NestedEnum.BAR)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setOptionalSfixed32(0)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setOptionalSfixed64(0)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setOptionalSint32(0)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setOptionalSint64(0)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setOptionalString("")
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setOptionalStringBytes(ByteString.EMPTY)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setOptionalStringPiece("")
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setOptionalStringPieceBytes(ByteString.EMPTY)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setOptionalUint32(0)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setOptionalUint64(0)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setOneofBytes(ByteString.EMPTY)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setOneofLazyNestedMessage(NestedMessage.getDefaultInstance())
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setOneofNestedMessage(NestedMessage.getDefaultInstance())
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setOneofString("")
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setOneofStringBytes(ByteString.EMPTY)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setOneofUint32(0)
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setOptionalForeignMessage(ForeignMessageLite.getDefaultInstance())
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setOptionalGroup(OptionalGroup.getDefaultInstance())
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setOptionalPublicImportMessage(PublicImportMessageLite.getDefaultInstance())
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .setOptionalLazyMessage(NestedMessage.getDefaultInstance())
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+ oneFieldSet = TestAllTypesLite.newBuilder()
+ .addRepeatedLazyMessage(NestedMessage.getDefaultInstance())
+ .build();
+ assertFalse(oneFieldSet.equals(TestAllTypesLite.getDefaultInstance()));
+ assertFalse(TestAllTypesLite.getDefaultInstance().equals(oneFieldSet));
+ }
+
+ public void testEquals() throws Exception {
+ // Check that two identical objs are equal.
+ Foo foo1a = Foo.newBuilder()
+ .setValue(1)
+ .addBar(Bar.newBuilder().setName("foo1"))
+ .build();
+ Foo foo1b = Foo.newBuilder()
+ .setValue(1)
+ .addBar(Bar.newBuilder().setName("foo1"))
+ .build();
+ Foo foo2 = Foo.newBuilder()
+ .setValue(1)
+ .addBar(Bar.newBuilder().setName("foo2"))
+ .build();
+
+ // Check that equals is doing value rather than object equality.
+ assertEquals(foo1a, foo1b);
+ assertEquals(foo1a.hashCode(), foo1b.hashCode());
+
+ // Check that a diffeent object is not equal.
+ assertFalse(foo1a.equals(foo2));
+
+ // Check that two objects which have different types but the same field values are not
+ // considered to be equal.
+ Bar bar = Bar.newBuilder().setName("bar").build();
+ BarPrime barPrime = BarPrime.newBuilder().setName("bar").build();
+ assertFalse(bar.equals(barPrime));
+ }
+
+ public void testOneofEquals() throws Exception {
+ TestOneofEquals.Builder builder = TestOneofEquals.newBuilder();
+ TestOneofEquals message1 = builder.build();
+ // Set message2's name field to default value. The two messages should be different when we
+ // check with the oneof case.
+ builder.setName("");
+ TestOneofEquals message2 = builder.build();
+ assertFalse(message1.equals(message2));
+ }
+
+ public void testEquals_sanity() throws Exception {
+ TestAllTypesLite one = TestUtilLite.getAllLiteSetBuilder().build();
+ TestAllTypesLite two = TestAllTypesLite.parseFrom(one.toByteArray());
+ assertEquals(one, two);
+ assertEquals(one.hashCode(), two.hashCode());
+
+ assertEquals(
+ one.toBuilder().mergeFrom(two).build(),
+ two.toBuilder().mergeFrom(two.toByteArray()).build());
+ }
+
+ public void testEqualsAndHashCodeWithUnknownFields() throws InvalidProtocolBufferException {
+ Foo fooWithOnlyValue = Foo.newBuilder()
+ .setValue(1)
+ .build();
+
+ Foo fooWithValueAndExtension = fooWithOnlyValue.toBuilder()
+ .setValue(1)
+ .setExtension(Bar.fooExt, Bar.newBuilder()
+ .setName("name")
+ .build())
+ .build();
+
+ Foo fooWithValueAndUnknownFields = Foo.parseFrom(fooWithValueAndExtension.toByteArray());
+
+ assertEqualsAndHashCodeAreFalse(fooWithOnlyValue, fooWithValueAndUnknownFields);
+ assertEqualsAndHashCodeAreFalse(fooWithValueAndExtension, fooWithValueAndUnknownFields);
+ }
+
+ public void testEqualsAndHashCodeWithExtensions() throws InvalidProtocolBufferException {
+ Foo fooWithOnlyValue = Foo.newBuilder()
+ .setValue(1)
+ .build();
+
+ Foo fooWithValueAndExtension = fooWithOnlyValue.toBuilder()
+ .setValue(1)
+ .setExtension(Bar.fooExt, Bar.newBuilder()
+ .setName("name")
+ .build())
+ .build();
+
+ assertEqualsAndHashCodeAreFalse(fooWithOnlyValue, fooWithValueAndExtension);
+ }
+
+ // Test to ensure we avoid a class cast exception with oneofs.
+ public void testEquals_oneOfMessages() {
+ TestAllTypesLite mine = TestAllTypesLite.newBuilder()
+ .setOneofString("Hello")
+ .build();
+
+ TestAllTypesLite other = TestAllTypesLite.newBuilder()
+ .setOneofNestedMessage(NestedMessage.getDefaultInstance())
+ .build();
+
+ assertFalse(mine.equals(other));
+ assertFalse(other.equals(mine));
+ }
+
+ private void assertEqualsAndHashCodeAreFalse(Object o1, Object o2) {
+ assertFalse(o1.equals(o2));
+ assertFalse(o1.hashCode() == o2.hashCode());
+ }
+
+ public void testRecursiveHashcode() {
+ // This tests that we don't infinite loop.
+ TestRecursiveOneof.getDefaultInstance().hashCode();
+ }
}
diff --git a/java/src/test/java/com/google/protobuf/LiteralByteStringTest.java b/java/core/src/test/java/com/google/protobuf/LiteralByteStringTest.java
index 7dfda2ae..2e7792a8 100644
--- a/java/src/test/java/com/google/protobuf/LiteralByteStringTest.java
+++ b/java/core/src/test/java/com/google/protobuf/LiteralByteStringTest.java
@@ -47,9 +47,9 @@ import java.util.List;
import java.util.NoSuchElementException;
/**
- * Test {@link LiteralByteString} by setting up a reference string in {@link #setUp()}.
- * This class is designed to be extended for testing extensions of {@link LiteralByteString}
- * such as {@link BoundedByteString}, see {@link BoundedByteStringTest}.
+ * Test {@code LiteralByteString} by setting up a reference string in {@link #setUp()}.
+ * This class is designed to be extended for testing extensions of {@code LiteralByteString}
+ * such as {@code BoundedByteString}, see {@link BoundedByteStringTest}.
*
* @author carlanton@google.com (Carl Haverl)
*/
@@ -75,9 +75,7 @@ public class LiteralByteStringTest extends TestCase {
}
protected String getActualClassName(Object object) {
- String actualClassName = object.getClass().getName();
- actualClassName = actualClassName.substring(actualClassName.lastIndexOf('.') + 1);
- return actualClassName;
+ return object.getClass().getSimpleName();
}
public void testByteAt() {
@@ -306,25 +304,75 @@ public class LiteralByteStringTest extends TestCase {
Arrays.equals(referenceBytes, roundTripBytes));
}
- public void testWriteTo_mutating() throws IOException {
+ public void testWriteToShouldNotExposeInternalBufferToOutputStream() throws IOException {
OutputStream os = new OutputStream() {
@Override
public void write(byte[] b, int off, int len) {
- for (int x = 0; x < len; ++x) {
- b[off + x] = (byte) 0;
- }
+ Arrays.fill(b, off, off + len, (byte) 0);
}
@Override
public void write(int b) {
- // Purposefully left blank.
+ throw new UnsupportedOperationException();
}
};
stringUnderTest.writeTo(os);
- byte[] newBytes = stringUnderTest.toByteArray();
assertTrue(classUnderTest + ".writeTo() must not grant access to underlying array",
- Arrays.equals(referenceBytes, newBytes));
+ Arrays.equals(referenceBytes, stringUnderTest.toByteArray()));
+ }
+
+ public void testWriteToInternalShouldExposeInternalBufferToOutputStream() throws IOException {
+ OutputStream os = new OutputStream() {
+ @Override
+ public void write(byte[] b, int off, int len) {
+ Arrays.fill(b, off, off + len, (byte) 0);
+ }
+
+ @Override
+ public void write(int b) {
+ throw new UnsupportedOperationException();
+ }
+ };
+
+ stringUnderTest.writeToInternal(os, 0, stringUnderTest.size());
+ byte[] allZeros = new byte[stringUnderTest.size()];
+ assertTrue(classUnderTest + ".writeToInternal() must grant access to underlying array",
+ Arrays.equals(allZeros, stringUnderTest.toByteArray()));
+ }
+
+ public void testWriteToShouldExposeInternalBufferToByteOutput() throws IOException {
+ ByteOutput out = new ByteOutput() {
+ @Override
+ public void write(byte value) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void write(byte[] value, int offset, int length) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void writeLazy(byte[] value, int offset, int length) throws IOException {
+ Arrays.fill(value, offset, offset + length, (byte) 0);
+ }
+
+ @Override
+ public void write(ByteBuffer value) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void writeLazy(ByteBuffer value) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+ };
+
+ stringUnderTest.writeTo(out);
+ byte[] allZeros = new byte[stringUnderTest.size()];
+ assertTrue(classUnderTest + ".writeToInternal() must grant access to underlying array",
+ Arrays.equals(allZeros, stringUnderTest.toByteArray()));
}
public void testNewOutput() throws IOException {
@@ -350,14 +398,14 @@ public class LiteralByteStringTest extends TestCase {
public void testToString() throws UnsupportedEncodingException {
String testString = "I love unicode \u1234\u5678 characters";
- LiteralByteString unicode = new LiteralByteString(testString.getBytes(Internal.UTF_8));
+ ByteString unicode = ByteString.wrap(testString.getBytes(Internal.UTF_8));
String roundTripString = unicode.toString(UTF_8);
assertEquals(classUnderTest + " unicode must match", testString, roundTripString);
}
- public void testCharsetToString() throws UnsupportedEncodingException {
+ public void testCharsetToString() {
String testString = "I love unicode \u1234\u5678 characters";
- LiteralByteString unicode = new LiteralByteString(testString.getBytes(Internal.UTF_8));
+ ByteString unicode = ByteString.wrap(testString.getBytes(Internal.UTF_8));
String roundTripString = unicode.toString(Internal.UTF_8);
assertEquals(classUnderTest + " unicode must match", testString, roundTripString);
}
@@ -365,7 +413,7 @@ public class LiteralByteStringTest extends TestCase {
public void testToString_returnsCanonicalEmptyString() {
assertSame(classUnderTest + " must be the same string references",
ByteString.EMPTY.toString(Internal.UTF_8),
- new LiteralByteString(new byte[]{}).toString(Internal.UTF_8));
+ ByteString.wrap(new byte[]{}).toString(Internal.UTF_8));
}
public void testToString_raisesException() {
@@ -377,7 +425,7 @@ public class LiteralByteStringTest extends TestCase {
}
try {
- new LiteralByteString(referenceBytes).toString("invalid");
+ ByteString.wrap(referenceBytes).toString("invalid");
fail("Should have thrown an exception.");
} catch (UnsupportedEncodingException expected) {
// This is success
@@ -390,15 +438,15 @@ public class LiteralByteStringTest extends TestCase {
assertFalse(classUnderTest + " must not equal the empty string",
stringUnderTest.equals(ByteString.EMPTY));
assertEquals(classUnderTest + " empty strings must be equal",
- new LiteralByteString(new byte[]{}), stringUnderTest.substring(55, 55));
+ ByteString.wrap(new byte[]{}), stringUnderTest.substring(55, 55));
assertEquals(classUnderTest + " must equal another string with the same value",
- stringUnderTest, new LiteralByteString(referenceBytes));
+ stringUnderTest, ByteString.wrap(referenceBytes));
byte[] mungedBytes = new byte[referenceBytes.length];
System.arraycopy(referenceBytes, 0, mungedBytes, 0, referenceBytes.length);
mungedBytes[mungedBytes.length - 5] = (byte) (mungedBytes[mungedBytes.length - 5] ^ 0xFF);
assertFalse(classUnderTest + " must not equal every string with the same length",
- stringUnderTest.equals(new LiteralByteString(mungedBytes)));
+ stringUnderTest.equals(ByteString.wrap(mungedBytes)));
}
public void testHashCode() {
diff --git a/java/src/test/java/com/google/protobuf/LongArrayListTest.java b/java/core/src/test/java/com/google/protobuf/LongArrayListTest.java
index 3a52ec7f..6aaf85d7 100644
--- a/java/src/test/java/com/google/protobuf/LongArrayListTest.java
+++ b/java/core/src/test/java/com/google/protobuf/LongArrayListTest.java
@@ -40,62 +40,49 @@ import java.util.Iterator;
/**
* Tests for {@link LongArrayList}.
- *
+ *
* @author dweis@google.com (Daniel Weis)
*/
public class LongArrayListTest extends TestCase {
-
- private static final LongArrayList UNARY_LIST = newImmutableLongArrayList(1);
+
+ private static final LongArrayList UNARY_LIST =
+ newImmutableLongArrayList(1);
private static final LongArrayList TERTIARY_LIST =
newImmutableLongArrayList(1, 2, 3);
-
+
private LongArrayList list;
-
+
@Override
protected void setUp() throws Exception {
list = new LongArrayList();
}
-
+
public void testEmptyListReturnsSameInstance() {
assertSame(LongArrayList.emptyList(), LongArrayList.emptyList());
}
-
+
public void testEmptyListIsImmutable() {
assertImmutable(LongArrayList.emptyList());
}
-
+
public void testMakeImmutable() {
- list.addLong(2);
+ list.addLong(3);
list.addLong(4);
- list.addLong(6);
- list.addLong(8);
+ list.addLong(5);
+ list.addLong(7);
list.makeImmutable();
assertImmutable(list);
}
-
- public void testCopyConstructor() {
- LongArrayList copy = new LongArrayList(TERTIARY_LIST);
- assertEquals(TERTIARY_LIST, copy);
-
- copy = new LongArrayList(LongArrayList.emptyList());
- assertEquals(LongArrayList.emptyList(), copy);
-
- copy = new LongArrayList(asList(1L, 2L, 3L));
- assertEquals(asList(1L, 2L, 3L), copy);
-
- copy = new LongArrayList(Collections.<Long>emptyList());
- assertEquals(LongArrayList.emptyList(), copy);
- }
-
+
public void testModificationWithIteration() {
list.addAll(asList(1L, 2L, 3L, 4L));
Iterator<Long> iterator = list.iterator();
assertEquals(4, list.size());
- assertEquals(1, (long) list.get(0));
- assertEquals(1, (long) iterator.next());
+ assertEquals(1L, (long) list.get(0));
+ assertEquals(1L, (long) iterator.next());
list.set(0, 1L);
- assertEquals(2, (long) iterator.next());
-
+ assertEquals(2L, (long) iterator.next());
+
list.remove(0);
try {
iterator.next();
@@ -103,7 +90,7 @@ public class LongArrayListTest extends TestCase {
} catch (ConcurrentModificationException e) {
// expected
}
-
+
iterator = list.iterator();
list.add(0, 0L);
try {
@@ -113,19 +100,19 @@ public class LongArrayListTest extends TestCase {
// expected
}
}
-
+
public void testGet() {
- assertEquals(1, (long) TERTIARY_LIST.get(0));
- assertEquals(2, (long) TERTIARY_LIST.get(1));
- assertEquals(3, (long) TERTIARY_LIST.get(2));
-
+ assertEquals(1L, (long) TERTIARY_LIST.get(0));
+ assertEquals(2L, (long) TERTIARY_LIST.get(1));
+ assertEquals(3L, (long) TERTIARY_LIST.get(2));
+
try {
TERTIARY_LIST.get(-1);
fail();
} catch (IndexOutOfBoundsException e) {
// expected
}
-
+
try {
TERTIARY_LIST.get(3);
fail();
@@ -133,19 +120,19 @@ public class LongArrayListTest extends TestCase {
// expected
}
}
-
+
public void testGetLong() {
- assertEquals(1, TERTIARY_LIST.getLong(0));
- assertEquals(2, TERTIARY_LIST.getLong(1));
- assertEquals(3, TERTIARY_LIST.getLong(2));
-
+ assertEquals(1L, TERTIARY_LIST.getLong(0));
+ assertEquals(2L, TERTIARY_LIST.getLong(1));
+ assertEquals(3L, TERTIARY_LIST.getLong(2));
+
try {
TERTIARY_LIST.get(-1);
fail();
} catch (IndexOutOfBoundsException e) {
// expected
}
-
+
try {
TERTIARY_LIST.get(3);
fail();
@@ -153,35 +140,35 @@ public class LongArrayListTest extends TestCase {
// expected
}
}
-
+
public void testSize() {
assertEquals(0, LongArrayList.emptyList().size());
assertEquals(1, UNARY_LIST.size());
assertEquals(3, TERTIARY_LIST.size());
- list.addLong(2);
+ list.addLong(3);
list.addLong(4);
list.addLong(6);
list.addLong(8);
assertEquals(4, list.size());
-
+
list.remove(0);
assertEquals(3, list.size());
-
- list.add(16L);
+
+ list.add(17L);
assertEquals(4, list.size());
}
-
+
public void testSet() {
list.addLong(2);
list.addLong(4);
-
- assertEquals(2, (long) list.set(0, 0L));
- assertEquals(0, list.getLong(0));
- assertEquals(4, (long) list.set(1, 0L));
- assertEquals(0, list.getLong(1));
-
+ assertEquals(2L, (long) list.set(0, 3L));
+ assertEquals(3L, list.getLong(0));
+
+ assertEquals(4L, (long) list.set(1, 0L));
+ assertEquals(0L, list.getLong(1));
+
try {
list.set(-1, 0L);
fail();
@@ -196,17 +183,17 @@ public class LongArrayListTest extends TestCase {
// expected
}
}
-
+
public void testSetLong() {
- list.addLong(2);
- list.addLong(4);
-
- assertEquals(2, list.setLong(0, 0));
- assertEquals(0, list.getLong(0));
+ list.addLong(1);
+ list.addLong(3);
+
+ assertEquals(1L, list.setLong(0, 0));
+ assertEquals(0L, list.getLong(0));
+
+ assertEquals(3L, list.setLong(1, 0));
+ assertEquals(0L, list.getLong(1));
- assertEquals(4, list.setLong(1, 0));
- assertEquals(0, list.getLong(1));
-
try {
list.setLong(-1, 0);
fail();
@@ -221,7 +208,7 @@ public class LongArrayListTest extends TestCase {
// expected
}
}
-
+
public void testAdd() {
assertEquals(0, list.size());
@@ -231,28 +218,30 @@ public class LongArrayListTest extends TestCase {
assertTrue(list.add(3L));
list.add(0, 4L);
assertEquals(asList(4L, 2L, 3L), list);
-
+
list.add(0, 1L);
list.add(0, 0L);
// Force a resize by getting up to 11 elements.
for (int i = 0; i < 6; i++) {
list.add(Long.valueOf(5 + i));
}
- assertEquals(asList(0L, 1L, 4L, 2L, 3L, 5L, 6L, 7L, 8L, 9L, 10L), list);
-
+ assertEquals(
+ asList(0L, 1L, 4L, 2L, 3L, 5L, 6L, 7L, 8L, 9L, 10L),
+ list);
+
try {
list.add(-1, 5L);
} catch (IndexOutOfBoundsException e) {
// expected
}
-
+
try {
list.add(4, 5L);
} catch (IndexOutOfBoundsException e) {
// expected
}
}
-
+
public void testAddLong() {
assertEquals(0, list.size());
@@ -262,128 +251,128 @@ public class LongArrayListTest extends TestCase {
list.addLong(3);
assertEquals(asList(2L, 3L), list);
}
-
+
public void testAddAll() {
assertEquals(0, list.size());
assertTrue(list.addAll(Collections.singleton(1L)));
assertEquals(1, list.size());
- assertEquals(1, (long) list.get(0));
- assertEquals(1, list.getLong(0));
-
+ assertEquals(1L, (long) list.get(0));
+ assertEquals(1L, list.getLong(0));
+
assertTrue(list.addAll(asList(2L, 3L, 4L, 5L, 6L)));
assertEquals(asList(1L, 2L, 3L, 4L, 5L, 6L), list);
-
+
assertTrue(list.addAll(TERTIARY_LIST));
assertEquals(asList(1L, 2L, 3L, 4L, 5L, 6L, 1L, 2L, 3L), list);
assertFalse(list.addAll(Collections.<Long>emptyList()));
assertFalse(list.addAll(LongArrayList.emptyList()));
}
-
+
public void testRemove() {
list.addAll(TERTIARY_LIST);
- assertEquals(1, (long) list.remove(0));
+ assertEquals(1L, (long) list.remove(0));
assertEquals(asList(2L, 3L), list);
- assertTrue(list.remove(3L));
+ assertTrue(list.remove(Long.valueOf(3)));
assertEquals(asList(2L), list);
- assertFalse(list.remove(3L));
+ assertFalse(list.remove(Long.valueOf(3)));
assertEquals(asList(2L), list);
- assertEquals(2, (long) list.remove(0));
+ assertEquals(2L, (long) list.remove(0));
assertEquals(asList(), list);
-
+
try {
list.remove(-1);
fail();
} catch (IndexOutOfBoundsException e) {
// expected
}
-
+
try {
list.remove(0);
} catch (IndexOutOfBoundsException e) {
// expected
}
}
-
+
private void assertImmutable(LongArrayList list) {
- if (list.contains(1)) {
+ if (list.contains(1L)) {
throw new RuntimeException("Cannot test the immutability of lists that contain 1.");
}
-
+
try {
list.add(1L);
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.add(0, 1L);
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.addAll(Collections.<Long>emptyList());
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.addAll(Collections.singletonList(1L));
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.addAll(new LongArrayList());
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.addAll(UNARY_LIST);
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.addAll(0, Collections.singleton(1L));
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.addAll(0, UNARY_LIST);
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.addAll(0, Collections.<Long>emptyList());
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.addLong(0);
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.clear();
fail();
@@ -397,63 +386,63 @@ public class LongArrayListTest extends TestCase {
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.remove(new Object());
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.removeAll(Collections.<Long>emptyList());
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
- list.removeAll(Collections.singleton(1));
+ list.removeAll(Collections.singleton(1L));
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.removeAll(UNARY_LIST);
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.retainAll(Collections.<Long>emptyList());
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
- list.retainAll(Collections.singleton(1));
+ list.retainAll(Collections.singleton(1L));
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.retainAll(UNARY_LIST);
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.set(0, 0L);
fail();
} catch (UnsupportedOperationException e) {
// expected
}
-
+
try {
list.setLong(0, 0);
fail();
@@ -461,7 +450,7 @@ public class LongArrayListTest extends TestCase {
// expected
}
}
-
+
private static LongArrayList newImmutableLongArrayList(long... elements) {
LongArrayList list = new LongArrayList();
for (long element : elements) {
diff --git a/java/core/src/test/java/com/google/protobuf/MapForProto2LiteTest.java b/java/core/src/test/java/com/google/protobuf/MapForProto2LiteTest.java
new file mode 100644
index 00000000..04d58006
--- /dev/null
+++ b/java/core/src/test/java/com/google/protobuf/MapForProto2LiteTest.java
@@ -0,0 +1,799 @@
+// 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.
+
+package com.google.protobuf;
+
+import map_lite_test.MapForProto2TestProto.BizarroTestMap;
+import map_lite_test.MapForProto2TestProto.TestMap;
+import map_lite_test.MapForProto2TestProto.TestMap.MessageValue;
+import map_lite_test.MapForProto2TestProto.TestMapOrBuilder;
+import map_lite_test.MapForProto2TestProto.TestUnknownEnumValue;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Unit tests for map fields.
+ */
+public final class MapForProto2LiteTest extends TestCase {
+
+ private void setMapValues(TestMap.Builder builder) {
+ builder
+ .putInt32ToInt32Field(1, 11)
+ .putInt32ToInt32Field(2, 22)
+ .putInt32ToInt32Field(3, 33)
+
+ .putInt32ToStringField(1, "11")
+ .putInt32ToStringField(2, "22")
+ .putInt32ToStringField(3, "33")
+
+ .putInt32ToBytesField(1, TestUtil.toBytes("11"))
+ .putInt32ToBytesField(2, TestUtil.toBytes("22"))
+ .putInt32ToBytesField(3, TestUtil.toBytes("33"))
+
+ .putInt32ToEnumField(1, TestMap.EnumValue.FOO)
+ .putInt32ToEnumField(2, TestMap.EnumValue.BAR)
+ .putInt32ToEnumField(3, TestMap.EnumValue.BAZ)
+
+ .putInt32ToMessageField(1, MessageValue.newBuilder().setValue(11).build())
+ .putInt32ToMessageField(2, MessageValue.newBuilder().setValue(22).build())
+ .putInt32ToMessageField(3, MessageValue.newBuilder().setValue(33).build())
+
+ .putStringToInt32Field("1", 11)
+ .putStringToInt32Field("2", 22)
+ .putStringToInt32Field("3", 33);
+ }
+
+ public void testSetMapValues() {
+ TestMap.Builder mapBuilder = TestMap.newBuilder();
+ setMapValues(mapBuilder);
+ TestMap map = mapBuilder.build();
+ assertMapValuesSet(map);
+ }
+
+ private void copyMapValues(TestMap source, TestMap.Builder destination) {
+ destination
+ .putAllInt32ToInt32Field(source.getInt32ToInt32Field())
+ .putAllInt32ToStringField(source.getInt32ToStringField())
+ .putAllInt32ToBytesField(source.getInt32ToBytesField())
+ .putAllInt32ToEnumField(source.getInt32ToEnumField())
+ .putAllInt32ToMessageField(source.getInt32ToMessageField())
+ .putAllStringToInt32Field(source.getStringToInt32Field());
+ }
+
+ private void assertMapValuesSet(TestMap message) {
+ assertEquals(3, message.getInt32ToInt32Field().size());
+ assertEquals(11, message.getInt32ToInt32Field().get(1).intValue());
+ assertEquals(22, message.getInt32ToInt32Field().get(2).intValue());
+ assertEquals(33, message.getInt32ToInt32Field().get(3).intValue());
+
+ assertEquals(3, message.getInt32ToStringField().size());
+ assertEquals("11", message.getInt32ToStringField().get(1));
+ assertEquals("22", message.getInt32ToStringField().get(2));
+ assertEquals("33", message.getInt32ToStringField().get(3));
+
+ assertEquals(3, message.getInt32ToBytesField().size());
+ assertEquals(TestUtil.toBytes("11"), message.getInt32ToBytesField().get(1));
+ assertEquals(TestUtil.toBytes("22"), message.getInt32ToBytesField().get(2));
+ assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3));
+
+ assertEquals(3, message.getInt32ToEnumField().size());
+ assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumField().get(1));
+ assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(2));
+ assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3));
+
+ assertEquals(3, message.getInt32ToMessageField().size());
+ assertEquals(11, message.getInt32ToMessageField().get(1).getValue());
+ assertEquals(22, message.getInt32ToMessageField().get(2).getValue());
+ assertEquals(33, message.getInt32ToMessageField().get(3).getValue());
+
+ assertEquals(3, message.getStringToInt32Field().size());
+ assertEquals(11, message.getStringToInt32Field().get("1").intValue());
+ assertEquals(22, message.getStringToInt32Field().get("2").intValue());
+ assertEquals(33, message.getStringToInt32Field().get("3").intValue());
+ }
+
+ private void updateMapValues(TestMap.Builder builder) {
+ builder
+ .putInt32ToInt32Field(1, 111)
+ .removeInt32ToInt32Field(2)
+ .putInt32ToInt32Field(4, 44)
+
+ .putInt32ToStringField(1, "111")
+ .removeInt32ToStringField(2)
+ .putInt32ToStringField(4, "44")
+
+ .putInt32ToBytesField(1, TestUtil.toBytes("111"))
+ .removeInt32ToBytesField(2)
+ .putInt32ToBytesField(4, TestUtil.toBytes("44"))
+
+ .putInt32ToEnumField(1, TestMap.EnumValue.BAR)
+ .removeInt32ToEnumField(2)
+ .putInt32ToEnumField(4, TestMap.EnumValue.QUX)
+
+ .putInt32ToMessageField(1, MessageValue.newBuilder().setValue(111).build())
+ .removeInt32ToMessageField(2)
+ .putInt32ToMessageField(4, MessageValue.newBuilder().setValue(44).build())
+
+ .putStringToInt32Field("1", 111)
+ .removeStringToInt32Field("2")
+ .putStringToInt32Field("4", 44);
+ }
+
+ public void testUpdateMapValues() {
+ TestMap.Builder mapBuilder = TestMap.newBuilder();
+ setMapValues(mapBuilder);
+ TestMap map = mapBuilder.build();
+ assertMapValuesSet(map);
+
+ mapBuilder = map.toBuilder();
+ updateMapValues(mapBuilder);
+ map = mapBuilder.build();
+ assertMapValuesUpdated(map);
+ }
+
+ private void assertMapValuesUpdated(TestMap message) {
+ assertEquals(3, message.getInt32ToInt32Field().size());
+ assertEquals(111, message.getInt32ToInt32Field().get(1).intValue());
+ assertEquals(33, message.getInt32ToInt32Field().get(3).intValue());
+ assertEquals(44, message.getInt32ToInt32Field().get(4).intValue());
+
+ assertEquals(3, message.getInt32ToStringField().size());
+ assertEquals("111", message.getInt32ToStringField().get(1));
+ assertEquals("33", message.getInt32ToStringField().get(3));
+ assertEquals("44", message.getInt32ToStringField().get(4));
+
+ assertEquals(3, message.getInt32ToBytesField().size());
+ assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesField().get(1));
+ assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3));
+ assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesField().get(4));
+
+ assertEquals(3, message.getInt32ToEnumField().size());
+ assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1));
+ assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3));
+ assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumField().get(4));
+
+ assertEquals(3, message.getInt32ToMessageField().size());
+ assertEquals(111, message.getInt32ToMessageField().get(1).getValue());
+ assertEquals(33, message.getInt32ToMessageField().get(3).getValue());
+ assertEquals(44, message.getInt32ToMessageField().get(4).getValue());
+
+ assertEquals(3, message.getStringToInt32Field().size());
+ assertEquals(111, message.getStringToInt32Field().get("1").intValue());
+ assertEquals(33, message.getStringToInt32Field().get("3").intValue());
+ assertEquals(44, message.getStringToInt32Field().get("4").intValue());
+ }
+
+ private void assertMapValuesCleared(TestMapOrBuilder testMapOrBuilder) {
+ assertEquals(0, testMapOrBuilder.getInt32ToInt32Field().size());
+ assertEquals(0, testMapOrBuilder.getInt32ToInt32FieldCount());
+ assertEquals(0, testMapOrBuilder.getInt32ToStringField().size());
+ assertEquals(0, testMapOrBuilder.getInt32ToStringFieldCount());
+ assertEquals(0, testMapOrBuilder.getInt32ToBytesField().size());
+ assertEquals(0, testMapOrBuilder.getInt32ToBytesFieldCount());
+ assertEquals(0, testMapOrBuilder.getInt32ToEnumField().size());
+ assertEquals(0, testMapOrBuilder.getInt32ToEnumFieldCount());
+ assertEquals(0, testMapOrBuilder.getInt32ToMessageField().size());
+ assertEquals(0, testMapOrBuilder.getInt32ToMessageFieldCount());
+ assertEquals(0, testMapOrBuilder.getStringToInt32Field().size());
+ assertEquals(0, testMapOrBuilder.getStringToInt32FieldCount());
+ }
+
+ public void testSanityCopyOnWrite() throws InvalidProtocolBufferException {
+ // Since builders are implemented as a thin wrapper around a message
+ // instance, we attempt to verify that we can't cause the builder to modify
+ // a produced message.
+
+ TestMap.Builder builder = TestMap.newBuilder();
+ TestMap message = builder.build();
+ builder.putInt32ToInt32Field(1, 2);
+ assertTrue(message.getInt32ToInt32Field().isEmpty());
+ message = builder.build();
+ assertEquals(newMap(1, 2), message.getInt32ToInt32Field());
+ assertEquals(newMap(1, 2), builder.getInt32ToInt32Field());
+ builder.putInt32ToInt32Field(2, 3);
+ assertEquals(newMap(1, 2), message.getInt32ToInt32Field());
+ assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32Field());
+ }
+
+ public void testGetMapIsImmutable() {
+ TestMap.Builder builder = TestMap.newBuilder();
+ assertMapsAreImmutable(builder);
+ assertMapsAreImmutable(builder.build());
+
+ setMapValues(builder);
+ assertMapsAreImmutable(builder);
+ assertMapsAreImmutable(builder.build());
+ }
+
+ private void assertMapsAreImmutable(TestMapOrBuilder testMapOrBuilder) {
+ assertImmutable(testMapOrBuilder.getInt32ToInt32Field(), 1, 2);
+ assertImmutable(testMapOrBuilder.getInt32ToStringField(), 1, "2");
+ assertImmutable(testMapOrBuilder.getInt32ToBytesField(), 1, TestUtil.toBytes("2"));
+ assertImmutable(testMapOrBuilder.getInt32ToEnumField(), 1, TestMap.EnumValue.FOO);
+ assertImmutable(
+ testMapOrBuilder.getInt32ToMessageField(), 1, MessageValue.getDefaultInstance());
+ assertImmutable(testMapOrBuilder.getStringToInt32Field(), "1", 2);
+ }
+
+ private <K, V> void assertImmutable(Map<K, V> map, K key, V value) {
+ try {
+ map.put(key, value);
+ fail();
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ if (!map.isEmpty()) {
+ try {
+ map.entrySet().remove(map.entrySet().iterator().next());
+ fail();
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ }
+ }
+
+ public void testMutableMapLifecycle() {
+ TestMap.Builder builder = TestMap.newBuilder()
+ .putInt32ToInt32Field(1, 2);
+ assertEquals(newMap(1, 2), builder.build().getInt32ToInt32Field());
+ assertEquals(newMap(1, 2), builder.getInt32ToInt32Field());
+ builder.putInt32ToInt32Field(2, 3);
+ assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32Field());
+
+ builder.putInt32ToEnumField(1, TestMap.EnumValue.BAR);
+ assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.build().getInt32ToEnumField());
+ assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.getInt32ToEnumField());
+ builder.putInt32ToEnumField(2, TestMap.EnumValue.FOO);
+ assertEquals(
+ newMap(1, TestMap.EnumValue.BAR, 2, TestMap.EnumValue.FOO),
+ builder.getInt32ToEnumField());
+
+ builder.putInt32ToStringField(1, "1");
+ assertEquals(newMap(1, "1"), builder.build().getInt32ToStringField());
+ assertEquals(newMap(1, "1"), builder.getInt32ToStringField());
+ builder.putInt32ToStringField(2, "2");
+ assertEquals(newMap(1, "1", 2, "2"), builder.getInt32ToStringField());
+
+ builder.putInt32ToMessageField(1, TestMap.MessageValue.getDefaultInstance());
+ assertEquals(newMap(1, TestMap.MessageValue.getDefaultInstance()),
+ builder.build().getInt32ToMessageField());
+ assertEquals(newMap(1, TestMap.MessageValue.getDefaultInstance()),
+ builder.getInt32ToMessageField());
+ builder.putInt32ToMessageField(2, TestMap.MessageValue.getDefaultInstance());
+ assertEquals(
+ newMap(1, TestMap.MessageValue.getDefaultInstance(),
+ 2, TestMap.MessageValue.getDefaultInstance()),
+ builder.getInt32ToMessageField());
+ }
+
+ public void testGettersAndSetters() throws Exception {
+ TestMap.Builder builder = TestMap.newBuilder();
+ TestMap message = builder.build();
+ assertMapValuesCleared(message);
+
+ builder = message.toBuilder();
+ setMapValues(builder);
+ message = builder.build();
+ assertMapValuesSet(message);
+
+ builder = message.toBuilder();
+ updateMapValues(builder);
+ message = builder.build();
+ assertMapValuesUpdated(message);
+
+ builder = message.toBuilder();
+ builder.clear();
+ assertMapValuesCleared(builder);
+ message = builder.build();
+ assertMapValuesCleared(message);
+ }
+
+ public void testPutAll() throws Exception {
+ TestMap.Builder sourceBuilder = TestMap.newBuilder();
+ setMapValues(sourceBuilder);
+ TestMap source = sourceBuilder.build();
+ assertMapValuesSet(source);
+
+ TestMap.Builder destination = TestMap.newBuilder();
+ copyMapValues(source, destination);
+ assertMapValuesSet(destination.build());
+ }
+
+ public void testPutChecksNullKeysAndValues() throws Exception {
+ TestMap.Builder builder = TestMap.newBuilder();
+
+ try {
+ builder.putInt32ToStringField(1, null);
+ fail();
+ } catch (NullPointerException e) {
+ // expected.
+ }
+
+ try {
+ builder.putInt32ToBytesField(1, null);
+ fail();
+ } catch (NullPointerException e) {
+ // expected.
+ }
+
+ try {
+ builder.putInt32ToEnumField(1, null);
+ fail();
+ } catch (NullPointerException e) {
+ // expected.
+ }
+
+ try {
+ builder.putInt32ToMessageField(1, null);
+ fail();
+ } catch (NullPointerException e) {
+ // expected.
+ }
+
+ try {
+ builder.putStringToInt32Field(null, 1);
+ fail();
+ } catch (NullPointerException e) {
+ // expected.
+ }
+ }
+
+ public void testSerializeAndParse() throws Exception {
+ TestMap.Builder builder = TestMap.newBuilder();
+ setMapValues(builder);
+ TestMap message = builder.build();
+ assertEquals(message.getSerializedSize(), message.toByteString().size());
+ message = TestMap.parser().parseFrom(message.toByteString());
+ assertMapValuesSet(message);
+
+ builder = message.toBuilder();
+ updateMapValues(builder);
+ message = builder.build();
+ assertEquals(message.getSerializedSize(), message.toByteString().size());
+ message = TestMap.parser().parseFrom(message.toByteString());
+ assertMapValuesUpdated(message);
+
+ builder = message.toBuilder();
+ builder.clear();
+ message = builder.build();
+ assertEquals(message.getSerializedSize(), message.toByteString().size());
+ message = TestMap.parser().parseFrom(message.toByteString());
+ assertMapValuesCleared(message);
+ }
+
+ private TestMap tryParseTestMap(BizarroTestMap bizarroMap) throws IOException {
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ CodedOutputStream output = CodedOutputStream.newInstance(byteArrayOutputStream);
+ bizarroMap.writeTo(output);
+ output.flush();
+ return TestMap.parser().parseFrom(ByteString.copyFrom(byteArrayOutputStream.toByteArray()));
+ }
+
+ public void testParseError() throws Exception {
+ ByteString bytes = TestUtil.toBytes("SOME BYTES");
+ String stringKey = "a string key";
+
+ TestMap map = tryParseTestMap(BizarroTestMap.newBuilder()
+ .putInt32ToInt32Field(5, bytes)
+ .build());
+ assertEquals(map.getInt32ToInt32FieldOrDefault(5, -1), 0);
+
+ map = tryParseTestMap(BizarroTestMap.newBuilder()
+ .putInt32ToStringField(stringKey, 5)
+ .build());
+ assertEquals(map.getInt32ToStringFieldOrDefault(0, null), "");
+
+ map = tryParseTestMap(BizarroTestMap.newBuilder()
+ .putInt32ToBytesField(stringKey, 5)
+ .build());
+ assertEquals(map.getInt32ToBytesFieldOrDefault(0, null), ByteString.EMPTY);
+
+ map = tryParseTestMap(BizarroTestMap.newBuilder()
+ .putInt32ToEnumField(stringKey, bytes)
+ .build());
+ assertEquals(map.getInt32ToEnumFieldOrDefault(0, null), TestMap.EnumValue.FOO);
+
+ try {
+ tryParseTestMap(BizarroTestMap.newBuilder()
+ .putInt32ToMessageField(stringKey, bytes)
+ .build());
+ fail();
+ } catch (InvalidProtocolBufferException expected) {
+ assertTrue(expected.getUnfinishedMessage() instanceof TestMap);
+ map = (TestMap) expected.getUnfinishedMessage();
+ assertTrue(map.getInt32ToMessageField().isEmpty());
+ }
+
+ map = tryParseTestMap(BizarroTestMap.newBuilder()
+ .putStringToInt32Field(stringKey, bytes)
+ .build());
+ assertEquals(map.getStringToInt32FieldOrDefault(stringKey, -1), 0);
+ }
+
+ public void testMergeFrom() throws Exception {
+ TestMap.Builder builder = TestMap.newBuilder();
+ setMapValues(builder);
+ TestMap message = builder.build();
+
+ TestMap.Builder other = TestMap.newBuilder();
+ other.mergeFrom(message);
+ assertMapValuesSet(other.build());
+ }
+
+ public void testEqualsAndHashCode() throws Exception {
+ // Test that generated equals() and hashCode() will disregard the order
+ // of map entries when comparing/hashing map fields.
+
+ // We can't control the order of elements in a HashMap. The best we can do
+ // here is to add elements in different order.
+ TestMap.Builder b1 = TestMap.newBuilder()
+ .putInt32ToInt32Field(1, 2)
+ .putInt32ToInt32Field(3, 4)
+ .putInt32ToInt32Field(5, 6);
+ TestMap m1 = b1.build();
+
+ TestMap.Builder b2 = TestMap.newBuilder()
+ .putInt32ToInt32Field(5, 6)
+ .putInt32ToInt32Field(1, 2)
+ .putInt32ToInt32Field(3, 4);
+ TestMap m2 = b2.build();
+
+ assertEquals(m1, m2);
+ assertEquals(m1.hashCode(), m2.hashCode());
+
+ // Make sure we did compare map fields.
+ b2.putInt32ToInt32Field(1, 0);
+ m2 = b2.build();
+ assertFalse(m1.equals(m2));
+ // Don't check m1.hashCode() != m2.hashCode() because it's not guaranteed
+ // to be different.
+ }
+
+ public void testUnknownEnumValues() throws Exception {
+ TestUnknownEnumValue.Builder builder = TestUnknownEnumValue.newBuilder()
+ .putInt32ToInt32Field(1, 1)
+ .putInt32ToInt32Field(2, 54321);
+ ByteString data = builder.build().toByteString();
+
+ TestMap message = TestMap.parseFrom(data);
+ // Entries with unknown enum values will be stored into UnknownFieldSet so
+ // there is only one entry in the map.
+ assertEquals(1, message.getInt32ToEnumField().size());
+ assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1));
+ // Serializing and parsing should preserve the unknown entry.
+ data = message.toByteString();
+ TestUnknownEnumValue messageWithUnknownEnums =
+ TestUnknownEnumValue.parseFrom(data);
+ assertEquals(2, messageWithUnknownEnums.getInt32ToInt32Field().size());
+ assertEquals(1, messageWithUnknownEnums.getInt32ToInt32Field().get(1).intValue());
+ assertEquals(54321, messageWithUnknownEnums.getInt32ToInt32Field().get(2).intValue());
+ }
+
+
+ public void testIterationOrder() throws Exception {
+ TestMap.Builder builder = TestMap.newBuilder();
+ setMapValues(builder);
+ TestMap message = builder.build();
+
+ assertEquals(Arrays.asList("1", "2", "3"),
+ new ArrayList<String>(message.getStringToInt32Field().keySet()));
+ }
+
+ private static <K, V> Map<K, V> newMap(K key1, V value1) {
+ Map<K, V> map = new HashMap<K, V>();
+ map.put(key1, value1);
+ return map;
+ }
+
+ private static <K, V> Map<K, V> newMap(K key1, V value1, K key2, V value2) {
+ Map<K, V> map = new HashMap<K, V>();
+ map.put(key1, value1);
+ map.put(key2, value2);
+ return map;
+ }
+
+ public void testGetMap() {
+ TestMap.Builder builder = TestMap.newBuilder();
+ setMapValues(builder);
+ TestMap message = builder.build();
+ assertEquals(
+ message.getStringToInt32Field(),
+ message.getStringToInt32FieldMap());
+ assertEquals(
+ message.getInt32ToBytesField(),
+ message.getInt32ToBytesFieldMap());
+ assertEquals(
+ message.getInt32ToEnumField(),
+ message.getInt32ToEnumFieldMap());
+ assertEquals(
+ message.getInt32ToMessageField(),
+ message.getInt32ToMessageFieldMap());
+ }
+
+ public void testContains() {
+ TestMap.Builder builder = TestMap.newBuilder();
+ setMapValues(builder);
+ assertMapContainsSetValues(builder);
+ assertMapContainsSetValues(builder.build());
+ }
+
+ private void assertMapContainsSetValues(TestMapOrBuilder testMapOrBuilder) {
+ assertTrue(testMapOrBuilder.containsInt32ToInt32Field(1));
+ assertTrue(testMapOrBuilder.containsInt32ToInt32Field(2));
+ assertTrue(testMapOrBuilder.containsInt32ToInt32Field(3));
+ assertFalse(testMapOrBuilder.containsInt32ToInt32Field(-1));
+
+ assertTrue(testMapOrBuilder.containsInt32ToStringField(1));
+ assertTrue(testMapOrBuilder.containsInt32ToStringField(2));
+ assertTrue(testMapOrBuilder.containsInt32ToStringField(3));
+ assertFalse(testMapOrBuilder.containsInt32ToStringField(-1));
+
+ assertTrue(testMapOrBuilder.containsInt32ToBytesField(1));
+ assertTrue(testMapOrBuilder.containsInt32ToBytesField(2));
+ assertTrue(testMapOrBuilder.containsInt32ToBytesField(3));
+ assertFalse(testMapOrBuilder.containsInt32ToBytesField(-1));
+
+ assertTrue(testMapOrBuilder.containsInt32ToEnumField(1));
+ assertTrue(testMapOrBuilder.containsInt32ToEnumField(2));
+ assertTrue(testMapOrBuilder.containsInt32ToEnumField(3));
+ assertFalse(testMapOrBuilder.containsInt32ToEnumField(-1));
+
+ assertTrue(testMapOrBuilder.containsInt32ToMessageField(1));
+ assertTrue(testMapOrBuilder.containsInt32ToMessageField(2));
+ assertTrue(testMapOrBuilder.containsInt32ToMessageField(3));
+ assertFalse(testMapOrBuilder.containsInt32ToMessageField(-1));
+
+ assertTrue(testMapOrBuilder.containsStringToInt32Field("1"));
+ assertTrue(testMapOrBuilder.containsStringToInt32Field("2"));
+ assertTrue(testMapOrBuilder.containsStringToInt32Field("3"));
+ assertFalse(testMapOrBuilder.containsStringToInt32Field("-1"));
+ }
+
+ public void testCount() {
+ TestMap.Builder builder = TestMap.newBuilder();
+ assertMapCounts(0, builder);
+
+ setMapValues(builder);
+ assertMapCounts(3, builder);
+
+ TestMap message = builder.build();
+ assertMapCounts(3, message);
+
+ builder = message.toBuilder().putInt32ToInt32Field(4, 44);
+ assertEquals(4, builder.getInt32ToInt32FieldCount());
+ assertEquals(4, builder.build().getInt32ToInt32FieldCount());
+
+ // already present - should be unchanged
+ builder.putInt32ToInt32Field(4, 44);
+ assertEquals(4, builder.getInt32ToInt32FieldCount());
+ }
+
+ private void assertMapCounts(int expectedCount, TestMapOrBuilder testMapOrBuilder) {
+ assertEquals(expectedCount, testMapOrBuilder.getInt32ToInt32FieldCount());
+ assertEquals(expectedCount, testMapOrBuilder.getInt32ToStringFieldCount());
+ assertEquals(expectedCount, testMapOrBuilder.getInt32ToBytesFieldCount());
+ assertEquals(expectedCount, testMapOrBuilder.getInt32ToEnumFieldCount());
+ assertEquals(expectedCount, testMapOrBuilder.getInt32ToMessageFieldCount());
+ assertEquals(expectedCount, testMapOrBuilder.getStringToInt32FieldCount());
+ }
+
+ public void testGetOrDefault() {
+ TestMap.Builder builder = TestMap.newBuilder();
+ assertMapCounts(0, builder);
+ setMapValues(builder);
+ doTestGetOrDefault(builder);
+ doTestGetOrDefault(builder.build());
+ }
+
+ public void doTestGetOrDefault(TestMapOrBuilder testMapOrBuilder) {
+ assertEquals(11, testMapOrBuilder.getInt32ToInt32FieldOrDefault(1, -11));
+ assertEquals(-11, testMapOrBuilder.getInt32ToInt32FieldOrDefault(-1, -11));
+
+ assertEquals("11", testMapOrBuilder.getInt32ToStringFieldOrDefault(1, "-11"));
+ assertNull("-11", testMapOrBuilder.getInt32ToStringFieldOrDefault(-1, null));
+
+ assertEquals(TestUtil.toBytes("11"), testMapOrBuilder.getInt32ToBytesFieldOrDefault(1, null));
+ assertNull(testMapOrBuilder.getInt32ToBytesFieldOrDefault(-1, null));
+
+ assertEquals(TestMap.EnumValue.FOO, testMapOrBuilder.getInt32ToEnumFieldOrDefault(1, null));
+ assertNull(testMapOrBuilder.getInt32ToEnumFieldOrDefault(-1, null));
+
+ assertEquals(MessageValue.newBuilder().setValue(11).build(),
+ testMapOrBuilder.getInt32ToMessageFieldOrDefault(1, null));
+ assertNull(testMapOrBuilder.getInt32ToMessageFieldOrDefault(-1, null));
+
+ assertEquals(11, testMapOrBuilder.getStringToInt32FieldOrDefault("1", -11));
+ assertEquals(-11, testMapOrBuilder.getStringToInt32FieldOrDefault("-1", -11));
+
+ try {
+ testMapOrBuilder.getStringToInt32FieldOrDefault(null, -11);
+ fail();
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ public void testGetOrThrow() {
+ TestMap.Builder builder = TestMap.newBuilder();
+ assertMapCounts(0, builder);
+ setMapValues(builder);
+ doTestGetOrDefault(builder);
+ doTestGetOrDefault(builder.build());
+ }
+
+ public void doTestGetOrThrow(TestMapOrBuilder testMapOrBuilder) {
+ assertEquals(11, testMapOrBuilder.getInt32ToInt32FieldOrThrow(1));
+ try {
+ testMapOrBuilder.getInt32ToInt32FieldOrThrow(-1);
+ fail();
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ assertEquals("11", testMapOrBuilder.getInt32ToStringFieldOrThrow(1));
+
+ try {
+ testMapOrBuilder.getInt32ToStringFieldOrThrow(-1);
+ fail();
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ assertEquals(TestUtil.toBytes("11"), testMapOrBuilder.getInt32ToBytesFieldOrThrow(1));
+
+ try {
+ testMapOrBuilder.getInt32ToBytesFieldOrThrow(-1);
+ fail();
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ assertEquals(TestMap.EnumValue.FOO, testMapOrBuilder.getInt32ToEnumFieldOrThrow(1));
+ try {
+ testMapOrBuilder.getInt32ToEnumFieldOrThrow(-1);
+ fail();
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ assertEquals(MessageValue.newBuilder().setValue(11).build(),
+ testMapOrBuilder.getInt32ToMessageFieldOrThrow(1));
+ try {
+ testMapOrBuilder.getInt32ToMessageFieldOrThrow(-1);
+ fail();
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ assertEquals(11, testMapOrBuilder.getStringToInt32FieldOrThrow("1"));
+ try {
+ testMapOrBuilder.getStringToInt32FieldOrThrow("-1");
+ fail();
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ testMapOrBuilder.getStringToInt32FieldOrThrow(null);
+ fail();
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ public void testPut() {
+ TestMap.Builder builder = TestMap.newBuilder();
+ builder.putInt32ToInt32Field(1, 11);
+ assertEquals(11, builder.getInt32ToInt32FieldOrThrow(1));
+
+ builder.putInt32ToStringField(1, "a");
+ assertEquals("a", builder.getInt32ToStringFieldOrThrow(1));
+ try {
+ builder.putInt32ToStringField(1, null);
+ fail();
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ builder.putInt32ToBytesField(1, TestUtil.toBytes("11"));
+ assertEquals(TestUtil.toBytes("11"), builder.getInt32ToBytesFieldOrThrow(1));
+ try {
+ builder.putInt32ToBytesField(1, null);
+ fail();
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ builder.putInt32ToEnumField(1, TestMap.EnumValue.FOO);
+ assertEquals(TestMap.EnumValue.FOO, builder.getInt32ToEnumFieldOrThrow(1));
+ try {
+ builder.putInt32ToEnumField(1, null);
+ fail();
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ builder.putStringToInt32Field("a", 1);
+ assertEquals(1, builder.getStringToInt32FieldOrThrow("a"));
+ try {
+ builder.putStringToInt32Field(null, -1);
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ public void testRemove() {
+ TestMap.Builder builder = TestMap.newBuilder();
+ setMapValues(builder);
+ assertEquals(11, builder.getInt32ToInt32FieldOrThrow(1));
+ for (int times = 0; times < 2; times++) {
+ builder.removeInt32ToInt32Field(1);
+ assertEquals(-1, builder.getInt32ToInt32FieldOrDefault(1, -1));
+ }
+
+ assertEquals("11", builder.getInt32ToStringFieldOrThrow(1));
+ for (int times = 0; times < 2; times++) {
+ builder.removeInt32ToStringField(1);
+ assertNull(builder.getInt32ToStringFieldOrDefault(1, null));
+ }
+
+ assertEquals(TestUtil.toBytes("11"), builder.getInt32ToBytesFieldOrThrow(1));
+ for (int times = 0; times < 2; times++) {
+ builder.removeInt32ToBytesField(1);
+ assertNull(builder.getInt32ToBytesFieldOrDefault(1, null));
+ }
+
+ assertEquals(TestMap.EnumValue.FOO, builder.getInt32ToEnumFieldOrThrow(1));
+ for (int times = 0; times < 2; times++) {
+ builder.removeInt32ToEnumField(1);
+ assertNull(builder.getInt32ToEnumFieldOrDefault(1, null));
+ }
+
+ assertEquals(11, builder.getStringToInt32FieldOrThrow("1"));
+ for (int times = 0; times < 2; times++) {
+ builder.removeStringToInt32Field("1");
+ assertEquals(-1, builder.getStringToInt32FieldOrDefault("1", -1));
+ }
+
+ try {
+ builder.removeStringToInt32Field(null);
+ fail();
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+}
diff --git a/java/src/test/java/com/google/protobuf/MapForProto2Test.java b/java/core/src/test/java/com/google/protobuf/MapForProto2Test.java
index 1fa3cbdb..e8246bf6 100644
--- a/java/src/test/java/com/google/protobuf/MapForProto2Test.java
+++ b/java/core/src/test/java/com/google/protobuf/MapForProto2Test.java
@@ -31,14 +31,17 @@
package com.google.protobuf;
import com.google.protobuf.Descriptors.FieldDescriptor;
+import map_test.MapForProto2TestProto.BizarroTestMap;
import map_test.MapForProto2TestProto.TestMap;
import map_test.MapForProto2TestProto.TestMap.MessageValue;
import map_test.MapForProto2TestProto.TestMap.MessageWithRequiredFields;
+import map_test.MapForProto2TestProto.TestMapOrBuilder;
import map_test.MapForProto2TestProto.TestRecursiveMap;
import map_test.MapForProto2TestProto.TestUnknownEnumValue;
-
import junit.framework.TestCase;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@@ -49,7 +52,8 @@ import java.util.Map;
* Unit tests for map fields in proto2 protos.
*/
public class MapForProto2Test extends TestCase {
- private void setMapValues(TestMap.Builder builder) {
+
+ private void setMapValuesUsingMutableMap(TestMap.Builder builder) {
builder.getMutableInt32ToInt32Field().put(1, 11);
builder.getMutableInt32ToInt32Field().put(2, 22);
builder.getMutableInt32ToInt32Field().put(3, 33);
@@ -57,27 +61,67 @@ public class MapForProto2Test extends TestCase {
builder.getMutableInt32ToStringField().put(1, "11");
builder.getMutableInt32ToStringField().put(2, "22");
builder.getMutableInt32ToStringField().put(3, "33");
-
+
builder.getMutableInt32ToBytesField().put(1, TestUtil.toBytes("11"));
builder.getMutableInt32ToBytesField().put(2, TestUtil.toBytes("22"));
builder.getMutableInt32ToBytesField().put(3, TestUtil.toBytes("33"));
-
+
builder.getMutableInt32ToEnumField().put(1, TestMap.EnumValue.FOO);
builder.getMutableInt32ToEnumField().put(2, TestMap.EnumValue.BAR);
builder.getMutableInt32ToEnumField().put(3, TestMap.EnumValue.BAZ);
-
+
builder.getMutableInt32ToMessageField().put(
1, MessageValue.newBuilder().setValue(11).build());
builder.getMutableInt32ToMessageField().put(
2, MessageValue.newBuilder().setValue(22).build());
builder.getMutableInt32ToMessageField().put(
3, MessageValue.newBuilder().setValue(33).build());
-
+
builder.getMutableStringToInt32Field().put("1", 11);
builder.getMutableStringToInt32Field().put("2", 22);
builder.getMutableStringToInt32Field().put("3", 33);
}
+ private void setMapValuesUsingAccessors(TestMap.Builder builder) {
+ builder
+ .putInt32ToInt32Field(1, 11)
+ .putInt32ToInt32Field(2, 22)
+ .putInt32ToInt32Field(3, 33)
+
+ .putInt32ToStringField(1, "11")
+ .putInt32ToStringField(2, "22")
+ .putInt32ToStringField(3, "33")
+
+ .putInt32ToBytesField(1, TestUtil.toBytes("11"))
+ .putInt32ToBytesField(2, TestUtil.toBytes("22"))
+ .putInt32ToBytesField(3, TestUtil.toBytes("33"))
+
+ .putInt32ToEnumField(1, TestMap.EnumValue.FOO)
+ .putInt32ToEnumField(2, TestMap.EnumValue.BAR)
+ .putInt32ToEnumField(3, TestMap.EnumValue.BAZ)
+
+ .putInt32ToMessageField(1, MessageValue.newBuilder().setValue(11).build())
+ .putInt32ToMessageField(2, MessageValue.newBuilder().setValue(22).build())
+ .putInt32ToMessageField(3, MessageValue.newBuilder().setValue(33).build())
+
+ .putStringToInt32Field("1", 11)
+ .putStringToInt32Field("2", 22)
+ .putStringToInt32Field("3", 33);
+ }
+
+ public void testSetMapValues() {
+ TestMap.Builder usingMutableMapBuilder = TestMap.newBuilder();
+ setMapValuesUsingMutableMap(usingMutableMapBuilder);
+ TestMap usingMutableMap = usingMutableMapBuilder.build();
+ assertMapValuesSet(usingMutableMap);
+
+ TestMap.Builder usingAccessorsBuilder = TestMap.newBuilder();
+ setMapValuesUsingAccessors(usingAccessorsBuilder);
+ TestMap usingAccessors = usingAccessorsBuilder.build();
+ assertMapValuesSet(usingAccessors);
+ assertEquals(usingAccessors, usingMutableMap);
+ }
+
private void copyMapValues(TestMap source, TestMap.Builder destination) {
destination
.putAllInt32ToInt32Field(source.getInt32ToInt32Field())
@@ -88,7 +132,7 @@ public class MapForProto2Test extends TestCase {
.putAllStringToInt32Field(source.getStringToInt32Field());
}
- private void assertMapValuesSet(TestMap message) {
+ private void assertMapValuesSet(TestMapOrBuilder message) {
assertEquals(3, message.getInt32ToInt32Field().size());
assertEquals(11, message.getInt32ToInt32Field().get(1).intValue());
assertEquals(22, message.getInt32ToInt32Field().get(2).intValue());
@@ -98,29 +142,29 @@ public class MapForProto2Test extends TestCase {
assertEquals("11", message.getInt32ToStringField().get(1));
assertEquals("22", message.getInt32ToStringField().get(2));
assertEquals("33", message.getInt32ToStringField().get(3));
-
+
assertEquals(3, message.getInt32ToBytesField().size());
assertEquals(TestUtil.toBytes("11"), message.getInt32ToBytesField().get(1));
assertEquals(TestUtil.toBytes("22"), message.getInt32ToBytesField().get(2));
assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3));
-
+
assertEquals(3, message.getInt32ToEnumField().size());
assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumField().get(1));
assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(2));
assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3));
-
+
assertEquals(3, message.getInt32ToMessageField().size());
assertEquals(11, message.getInt32ToMessageField().get(1).getValue());
assertEquals(22, message.getInt32ToMessageField().get(2).getValue());
assertEquals(33, message.getInt32ToMessageField().get(3).getValue());
-
+
assertEquals(3, message.getStringToInt32Field().size());
assertEquals(11, message.getStringToInt32Field().get("1").intValue());
assertEquals(22, message.getStringToInt32Field().get("2").intValue());
assertEquals(33, message.getStringToInt32Field().get("3").intValue());
}
- private void updateMapValues(TestMap.Builder builder) {
+ private void updateMapValuesUsingMutableMap(TestMap.Builder builder) {
builder.getMutableInt32ToInt32Field().put(1, 111);
builder.getMutableInt32ToInt32Field().remove(2);
builder.getMutableInt32ToInt32Field().put(4, 44);
@@ -128,26 +172,78 @@ public class MapForProto2Test extends TestCase {
builder.getMutableInt32ToStringField().put(1, "111");
builder.getMutableInt32ToStringField().remove(2);
builder.getMutableInt32ToStringField().put(4, "44");
-
+
builder.getMutableInt32ToBytesField().put(1, TestUtil.toBytes("111"));
builder.getMutableInt32ToBytesField().remove(2);
builder.getMutableInt32ToBytesField().put(4, TestUtil.toBytes("44"));
-
+
builder.getMutableInt32ToEnumField().put(1, TestMap.EnumValue.BAR);
builder.getMutableInt32ToEnumField().remove(2);
builder.getMutableInt32ToEnumField().put(4, TestMap.EnumValue.QUX);
-
+
builder.getMutableInt32ToMessageField().put(
1, MessageValue.newBuilder().setValue(111).build());
builder.getMutableInt32ToMessageField().remove(2);
builder.getMutableInt32ToMessageField().put(
4, MessageValue.newBuilder().setValue(44).build());
-
+
builder.getMutableStringToInt32Field().put("1", 111);
builder.getMutableStringToInt32Field().remove("2");
builder.getMutableStringToInt32Field().put("4", 44);
}
+ private void updateMapValuesUsingAccessors(TestMap.Builder builder) {
+ builder
+ .putInt32ToInt32Field(1, 111)
+ .removeInt32ToInt32Field(2)
+ .putInt32ToInt32Field(4, 44)
+
+ .putInt32ToStringField(1, "111")
+ .removeInt32ToStringField(2)
+ .putInt32ToStringField(4, "44")
+
+ .putInt32ToBytesField(1, TestUtil.toBytes("111"))
+ .removeInt32ToBytesField(2)
+ .putInt32ToBytesField(4, TestUtil.toBytes("44"))
+
+ .putInt32ToEnumField(1, TestMap.EnumValue.BAR)
+ .removeInt32ToEnumField(2)
+ .putInt32ToEnumField(4, TestMap.EnumValue.QUX)
+
+ .putInt32ToMessageField(1, MessageValue.newBuilder().setValue(111).build())
+ .removeInt32ToMessageField(2)
+ .putInt32ToMessageField(4, MessageValue.newBuilder().setValue(44).build())
+
+ .putStringToInt32Field("1", 111)
+ .removeStringToInt32Field("2")
+ .putStringToInt32Field("4", 44);
+ }
+
+ public void testUpdateMapValues() {
+ TestMap.Builder usingMutableMapBuilder = TestMap.newBuilder();
+ setMapValuesUsingMutableMap(usingMutableMapBuilder);
+ TestMap usingMutableMap = usingMutableMapBuilder.build();
+ assertMapValuesSet(usingMutableMap);
+
+ TestMap.Builder usingAccessorsBuilder = TestMap.newBuilder();
+ setMapValuesUsingAccessors(usingAccessorsBuilder);
+ TestMap usingAccessors = usingAccessorsBuilder.build();
+ assertMapValuesSet(usingAccessors);
+ assertEquals(usingAccessors, usingMutableMap);
+
+ usingMutableMapBuilder = usingMutableMap.toBuilder();
+ updateMapValuesUsingMutableMap(usingMutableMapBuilder);
+ usingMutableMap = usingMutableMapBuilder.build();
+ assertMapValuesUpdated(usingMutableMap);
+
+ usingAccessorsBuilder = usingAccessors.toBuilder();
+ updateMapValuesUsingAccessors(usingAccessorsBuilder);
+ usingAccessors = usingAccessorsBuilder.build();
+ assertMapValuesUpdated(usingAccessors);
+
+ assertEquals(usingAccessors, usingMutableMap);
+ }
+
private void assertMapValuesUpdated(TestMap message) {
assertEquals(3, message.getInt32ToInt32Field().size());
assertEquals(111, message.getInt32ToInt32Field().get(1).intValue());
@@ -158,37 +254,72 @@ public class MapForProto2Test extends TestCase {
assertEquals("111", message.getInt32ToStringField().get(1));
assertEquals("33", message.getInt32ToStringField().get(3));
assertEquals("44", message.getInt32ToStringField().get(4));
-
+
assertEquals(3, message.getInt32ToBytesField().size());
assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesField().get(1));
assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3));
assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesField().get(4));
-
+
assertEquals(3, message.getInt32ToEnumField().size());
assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1));
assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3));
assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumField().get(4));
-
+
assertEquals(3, message.getInt32ToMessageField().size());
assertEquals(111, message.getInt32ToMessageField().get(1).getValue());
assertEquals(33, message.getInt32ToMessageField().get(3).getValue());
assertEquals(44, message.getInt32ToMessageField().get(4).getValue());
-
+
assertEquals(3, message.getStringToInt32Field().size());
assertEquals(111, message.getStringToInt32Field().get("1").intValue());
assertEquals(33, message.getStringToInt32Field().get("3").intValue());
assertEquals(44, message.getStringToInt32Field().get("4").intValue());
}
- private void assertMapValuesCleared(TestMap message) {
- assertEquals(0, message.getInt32ToInt32Field().size());
- assertEquals(0, message.getInt32ToStringField().size());
- assertEquals(0, message.getInt32ToBytesField().size());
- assertEquals(0, message.getInt32ToEnumField().size());
- assertEquals(0, message.getInt32ToMessageField().size());
- assertEquals(0, message.getStringToInt32Field().size());
+ private void assertMapValuesCleared(TestMapOrBuilder testMapOrBuilder) {
+ assertEquals(0, testMapOrBuilder.getInt32ToInt32Field().size());
+ assertEquals(0, testMapOrBuilder.getInt32ToInt32FieldCount());
+ assertEquals(0, testMapOrBuilder.getInt32ToStringField().size());
+ assertEquals(0, testMapOrBuilder.getInt32ToStringFieldCount());
+ assertEquals(0, testMapOrBuilder.getInt32ToBytesField().size());
+ assertEquals(0, testMapOrBuilder.getInt32ToBytesFieldCount());
+ assertEquals(0, testMapOrBuilder.getInt32ToEnumField().size());
+ assertEquals(0, testMapOrBuilder.getInt32ToEnumFieldCount());
+ assertEquals(0, testMapOrBuilder.getInt32ToMessageField().size());
+ assertEquals(0, testMapOrBuilder.getInt32ToMessageFieldCount());
+ assertEquals(0, testMapOrBuilder.getStringToInt32Field().size());
+ assertEquals(0, testMapOrBuilder.getStringToInt32FieldCount());
+ }
+
+ public void testGetMapIsImmutable() {
+ TestMap.Builder builder = TestMap.newBuilder();
+ assertMapsAreImmutable(builder);
+ assertMapsAreImmutable(builder.build());
+
+ setMapValuesUsingAccessors(builder);
+ assertMapsAreImmutable(builder);
+ assertMapsAreImmutable(builder.build());
+ }
+
+ private void assertMapsAreImmutable(TestMapOrBuilder testMapOrBuilder) {
+ assertImmutable(testMapOrBuilder.getInt32ToInt32Field(), 1, 2);
+ assertImmutable(testMapOrBuilder.getInt32ToStringField(), 1, "2");
+ assertImmutable(testMapOrBuilder.getInt32ToBytesField(), 1, TestUtil.toBytes("2"));
+ assertImmutable(testMapOrBuilder.getInt32ToEnumField(), 1, TestMap.EnumValue.FOO);
+ assertImmutable(
+ testMapOrBuilder.getInt32ToMessageField(), 1, MessageValue.getDefaultInstance());
+ assertImmutable(testMapOrBuilder.getStringToInt32Field(), "1", 2);
}
-
+
+ private <K, V> void assertImmutable(Map<K, V> map, K key, V value) {
+ try {
+ map.put(key, value);
+ fail();
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ }
+
public void testMutableMapLifecycle() {
TestMap.Builder builder = TestMap.newBuilder();
Map<Integer, Integer> intMap = builder.getMutableInt32ToInt32Field();
@@ -218,7 +349,7 @@ public class MapForProto2Test extends TestCase {
assertEquals(
newMap(1, TestMap.EnumValue.BAR, 2, TestMap.EnumValue.FOO),
builder.getInt32ToEnumField());
-
+
Map<Integer, String> stringMap = builder.getMutableInt32ToStringField();
stringMap.put(1, "1");
assertEquals(newMap(1, "1"), builder.build().getInt32ToStringField());
@@ -233,7 +364,7 @@ public class MapForProto2Test extends TestCase {
assertEquals(
newMap(1, "1", 2, "2"),
builder.getInt32ToStringField());
-
+
Map<Integer, TestMap.MessageValue> messageMap = builder.getMutableInt32ToMessageField();
messageMap.put(1, TestMap.MessageValue.getDefaultInstance());
assertEquals(newMap(1, TestMap.MessageValue.getDefaultInstance()),
@@ -303,48 +434,91 @@ public class MapForProto2Test extends TestCase {
TestMap.Builder builder = TestMap.newBuilder();
TestMap message = builder.build();
assertMapValuesCleared(message);
-
+
builder = message.toBuilder();
- setMapValues(builder);
+ setMapValuesUsingMutableMap(builder);
message = builder.build();
assertMapValuesSet(message);
-
+
builder = message.toBuilder();
- updateMapValues(builder);
+ updateMapValuesUsingMutableMap(builder);
message = builder.build();
assertMapValuesUpdated(message);
-
+
builder = message.toBuilder();
builder.clear();
+ assertMapValuesCleared(builder);
message = builder.build();
assertMapValuesCleared(message);
}
public void testPutAll() throws Exception {
TestMap.Builder sourceBuilder = TestMap.newBuilder();
- setMapValues(sourceBuilder);
+ setMapValuesUsingMutableMap(sourceBuilder);
TestMap source = sourceBuilder.build();
+ assertMapValuesSet(source);
TestMap.Builder destination = TestMap.newBuilder();
copyMapValues(source, destination);
assertMapValuesSet(destination.build());
+
+ assertEquals(3, destination.getInt32ToEnumFieldCount());
+ }
+
+ public void testPutChecksNullKeysAndValues() throws Exception {
+ TestMap.Builder builder = TestMap.newBuilder();
+
+ try {
+ builder.putInt32ToStringField(1, null);
+ fail();
+ } catch (NullPointerException e) {
+ // expected.
+ }
+
+ try {
+ builder.putInt32ToBytesField(1, null);
+ fail();
+ } catch (NullPointerException e) {
+ // expected.
+ }
+
+ try {
+ builder.putInt32ToEnumField(1, null);
+ fail();
+ } catch (NullPointerException e) {
+ // expected.
+ }
+
+ try {
+ builder.putInt32ToMessageField(1, null);
+ fail();
+ } catch (NullPointerException e) {
+ // expected.
+ }
+
+ try {
+ builder.putStringToInt32Field(null, 1);
+ fail();
+ } catch (NullPointerException e) {
+ // expected.
+ }
}
public void testSerializeAndParse() throws Exception {
TestMap.Builder builder = TestMap.newBuilder();
- setMapValues(builder);
+ setMapValuesUsingMutableMap(builder);
TestMap message = builder.build();
assertEquals(message.getSerializedSize(), message.toByteString().size());
message = TestMap.parser().parseFrom(message.toByteString());
assertMapValuesSet(message);
-
+
builder = message.toBuilder();
- updateMapValues(builder);
+ updateMapValuesUsingMutableMap(builder);
message = builder.build();
assertEquals(message.getSerializedSize(), message.toByteString().size());
message = TestMap.parser().parseFrom(message.toByteString());
assertMapValuesUpdated(message);
-
+
builder = message.toBuilder();
builder.clear();
message = builder.build();
@@ -352,12 +526,61 @@ public class MapForProto2Test extends TestCase {
message = TestMap.parser().parseFrom(message.toByteString());
assertMapValuesCleared(message);
}
-
+
+ private TestMap tryParseTestMap(BizarroTestMap bizarroMap) throws IOException {
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ CodedOutputStream output = CodedOutputStream.newInstance(byteArrayOutputStream);
+ bizarroMap.writeTo(output);
+ output.flush();
+ return TestMap.parser().parseFrom(ByteString.copyFrom(byteArrayOutputStream.toByteArray()));
+ }
+
+ public void testParseError() throws Exception {
+ ByteString bytes = TestUtil.toBytes("SOME BYTES");
+ String stringKey = "a string key";
+
+ TestMap map = tryParseTestMap(BizarroTestMap.newBuilder()
+ .putInt32ToInt32Field(5, bytes)
+ .build());
+ assertEquals(map.getInt32ToInt32FieldOrDefault(5, -1), 0);
+
+ map = tryParseTestMap(BizarroTestMap.newBuilder()
+ .putInt32ToStringField(stringKey, 5)
+ .build());
+ assertEquals(map.getInt32ToStringFieldOrDefault(0, null), "");
+
+ map = tryParseTestMap(BizarroTestMap.newBuilder()
+ .putInt32ToBytesField(stringKey, 5)
+ .build());
+ assertEquals(map.getInt32ToBytesFieldOrDefault(0, null), ByteString.EMPTY);
+
+ map = tryParseTestMap(BizarroTestMap.newBuilder()
+ .putInt32ToEnumField(stringKey, bytes)
+ .build());
+ assertEquals(map.getInt32ToEnumFieldOrDefault(0, null), TestMap.EnumValue.FOO);
+
+ try {
+ tryParseTestMap(BizarroTestMap.newBuilder()
+ .putInt32ToMessageField(stringKey, bytes)
+ .build());
+ fail();
+ } catch (InvalidProtocolBufferException expected) {
+ assertTrue(expected.getUnfinishedMessage() instanceof TestMap);
+ map = (TestMap) expected.getUnfinishedMessage();
+ assertTrue(map.getInt32ToMessageField().isEmpty());
+ }
+
+ map = tryParseTestMap(BizarroTestMap.newBuilder()
+ .putStringToInt32Field(stringKey, bytes)
+ .build());
+ assertEquals(map.getStringToInt32FieldOrDefault(stringKey, -1), 0);
+ }
+
public void testMergeFrom() throws Exception {
TestMap.Builder builder = TestMap.newBuilder();
- setMapValues(builder);
+ setMapValuesUsingMutableMap(builder);
TestMap message = builder.build();
-
+
TestMap.Builder other = TestMap.newBuilder();
other.mergeFrom(message);
assertMapValuesSet(other.build());
@@ -366,7 +589,7 @@ public class MapForProto2Test extends TestCase {
public void testEqualsAndHashCode() throws Exception {
// Test that generated equals() and hashCode() will disregard the order
// of map entries when comparing/hashing map fields.
-
+
// We can't control the order of elements in a HashMap. The best we can do
// here is to add elements in different order.
TestMap.Builder b1 = TestMap.newBuilder();
@@ -374,16 +597,16 @@ public class MapForProto2Test extends TestCase {
b1.getMutableInt32ToInt32Field().put(3, 4);
b1.getMutableInt32ToInt32Field().put(5, 6);
TestMap m1 = b1.build();
-
+
TestMap.Builder b2 = TestMap.newBuilder();
b2.getMutableInt32ToInt32Field().put(5, 6);
b2.getMutableInt32ToInt32Field().put(1, 2);
b2.getMutableInt32ToInt32Field().put(3, 4);
TestMap m2 = b2.build();
-
+
assertEquals(m1, m2);
assertEquals(m1.hashCode(), m2.hashCode());
-
+
// Make sure we did compare map fields.
b2.getMutableInt32ToInt32Field().put(1, 0);
m2 = b2.build();
@@ -391,26 +614,26 @@ public class MapForProto2Test extends TestCase {
// Don't check m1.hashCode() != m2.hashCode() because it's not guaranteed
// to be different.
}
-
-
+
+
// The following methods are used to test reflection API.
-
+
private static FieldDescriptor f(String name) {
return TestMap.getDescriptor().findFieldByName(name);
}
-
+
private static Object getFieldValue(Message mapEntry, String name) {
FieldDescriptor field = mapEntry.getDescriptorForType().findFieldByName(name);
return mapEntry.getField(field);
}
-
+
private static Message.Builder setFieldValue(
Message.Builder mapEntry, String name, Object value) {
FieldDescriptor field = mapEntry.getDescriptorForType().findFieldByName(name);
mapEntry.setField(field, value);
return mapEntry;
}
-
+
private static void assertHasMapValues(Message message, String name, Map<?, ?> values) {
FieldDescriptor field = f(name);
for (Object entry : (List<?>) message.getField(field)) {
@@ -429,7 +652,7 @@ public class MapForProto2Test extends TestCase {
assertEquals(value, values.get(key));
}
}
-
+
private static <KeyType, ValueType>
Message newMapEntry(Message.Builder builder, String name, KeyType key, ValueType value) {
FieldDescriptor field = builder.getDescriptorForType().findFieldByName(name);
@@ -440,7 +663,7 @@ public class MapForProto2Test extends TestCase {
entryBuilder.setField(valueField, value);
return entryBuilder.build();
}
-
+
private static void setMapValues(Message.Builder builder, String name, Map<?, ?> values) {
List<Message> entryList = new ArrayList<Message>();
for (Map.Entry<?, ?> entry : values.entrySet()) {
@@ -449,9 +672,8 @@ public class MapForProto2Test extends TestCase {
FieldDescriptor field = builder.getDescriptorForType().findFieldByName(name);
builder.setField(field, entryList);
}
-
- private static <KeyType, ValueType>
- Map<KeyType, ValueType> mapForValues(
+
+ private static <KeyType, ValueType> Map<KeyType, ValueType> mapForValues(
KeyType key1, ValueType value1, KeyType key2, ValueType value2) {
Map<KeyType, ValueType> map = new HashMap<KeyType, ValueType>();
map.put(key1, value1);
@@ -477,14 +699,14 @@ public class MapForProto2Test extends TestCase {
mapForValues(
11, MessageValue.newBuilder().setValue(22).build(),
33, MessageValue.newBuilder().setValue(44).build()));
-
+
// Test clearField()
builder.clearField(f("int32_to_int32_field"));
builder.clearField(f("int32_to_message_field"));
message = builder.build();
assertEquals(0, message.getInt32ToInt32Field().size());
assertEquals(0, message.getInt32ToMessageField().size());
-
+
// Test setField()
setMapValues(builder, "int32_to_int32_field",
mapForValues(11, 22, 33, 44));
@@ -497,7 +719,7 @@ public class MapForProto2Test extends TestCase {
assertEquals(44, message.getInt32ToInt32Field().get(33).intValue());
assertEquals(222, message.getInt32ToMessageField().get(111).getValue());
assertEquals(444, message.getInt32ToMessageField().get(333).getValue());
-
+
// Test addRepeatedField
builder.addRepeatedField(f("int32_to_int32_field"),
newMapEntry(builder, "int32_to_int32_field", 55, 66));
@@ -517,7 +739,7 @@ public class MapForProto2Test extends TestCase {
message = builder.build();
assertEquals(55, message.getInt32ToInt32Field().get(55).intValue());
assertEquals(555, message.getInt32ToMessageField().get(555).getValue());
-
+
// Test setRepeatedField
for (int i = 0; i < builder.getRepeatedFieldCount(f("int32_to_int32_field")); i++) {
Message mapEntry = (Message) builder.getRepeatedField(f("int32_to_int32_field"), i);
@@ -534,35 +756,35 @@ public class MapForProto2Test extends TestCase {
assertEquals(33, message.getInt32ToInt32Field().get(44).intValue());
assertEquals(55, message.getInt32ToInt32Field().get(55).intValue());
}
-
+
public void testTextFormat() throws Exception {
TestMap.Builder builder = TestMap.newBuilder();
- setMapValues(builder);
+ setMapValuesUsingMutableMap(builder);
TestMap message = builder.build();
-
+
String textData = TextFormat.printToString(message);
-
+
builder = TestMap.newBuilder();
TextFormat.merge(textData, builder);
message = builder.build();
-
+
assertMapValuesSet(message);
}
-
+
public void testDynamicMessage() throws Exception {
TestMap.Builder builder = TestMap.newBuilder();
- setMapValues(builder);
+ setMapValuesUsingMutableMap(builder);
TestMap message = builder.build();
-
+
Message dynamicDefaultInstance =
DynamicMessage.getDefaultInstance(TestMap.getDescriptor());
Message dynamicMessage = dynamicDefaultInstance
.newBuilderForType().mergeFrom(message.toByteString()).build();
-
+
assertEquals(message, dynamicMessage);
assertEquals(message.hashCode(), dynamicMessage.hashCode());
}
-
+
public void testReflectionEqualsAndHashCode() throws Exception {
// Test that generated equals() and hashCode() will disregard the order
// of map entries when comparing/hashing map fields.
@@ -571,22 +793,22 @@ public class MapForProto2Test extends TestCase {
Message dynamicDefaultInstance =
DynamicMessage.getDefaultInstance(TestMap.getDescriptor());
FieldDescriptor field = f("int32_to_int32_field");
-
+
Message.Builder b1 = dynamicDefaultInstance.newBuilderForType();
b1.addRepeatedField(field, newMapEntry(b1, "int32_to_int32_field", 1, 2));
b1.addRepeatedField(field, newMapEntry(b1, "int32_to_int32_field", 3, 4));
b1.addRepeatedField(field, newMapEntry(b1, "int32_to_int32_field", 5, 6));
Message m1 = b1.build();
-
+
Message.Builder b2 = dynamicDefaultInstance.newBuilderForType();
b2.addRepeatedField(field, newMapEntry(b2, "int32_to_int32_field", 5, 6));
b2.addRepeatedField(field, newMapEntry(b2, "int32_to_int32_field", 1, 2));
b2.addRepeatedField(field, newMapEntry(b2, "int32_to_int32_field", 3, 4));
Message m2 = b2.build();
-
+
assertEquals(m1, m2);
assertEquals(m1.hashCode(), m2.hashCode());
-
+
// Make sure we did compare map fields.
b2.setRepeatedField(field, 0, newMapEntry(b1, "int32_to_int32_field", 0, 0));
m2 = b2.build();
@@ -594,7 +816,7 @@ public class MapForProto2Test extends TestCase {
// Don't check m1.hashCode() != m2.hashCode() because it's not guaranteed
// to be different.
}
-
+
public void testUnknownEnumValues() throws Exception {
TestUnknownEnumValue.Builder builder =
TestUnknownEnumValue.newBuilder();
@@ -647,13 +869,266 @@ public class MapForProto2Test extends TestCase {
public void testIterationOrder() throws Exception {
TestMap.Builder builder = TestMap.newBuilder();
- setMapValues(builder);
+ setMapValuesUsingMutableMap(builder);
TestMap message = builder.build();
assertEquals(Arrays.asList("1", "2", "3"),
new ArrayList<String>(message.getStringToInt32Field().keySet()));
}
+ public void testContains() {
+ TestMap.Builder builder = TestMap.newBuilder();
+ setMapValuesUsingMutableMap(builder);
+ assertMapContainsSetValues(builder);
+ assertMapContainsSetValues(builder.build());
+ }
+
+ private void assertMapContainsSetValues(TestMapOrBuilder testMapOrBuilder) {
+ assertTrue(testMapOrBuilder.containsInt32ToInt32Field(1));
+ assertTrue(testMapOrBuilder.containsInt32ToInt32Field(2));
+ assertTrue(testMapOrBuilder.containsInt32ToInt32Field(3));
+ assertFalse(testMapOrBuilder.containsInt32ToInt32Field(-1));
+
+ assertTrue(testMapOrBuilder.containsInt32ToStringField(1));
+ assertTrue(testMapOrBuilder.containsInt32ToStringField(2));
+ assertTrue(testMapOrBuilder.containsInt32ToStringField(3));
+ assertFalse(testMapOrBuilder.containsInt32ToStringField(-1));
+
+ assertTrue(testMapOrBuilder.containsInt32ToBytesField(1));
+ assertTrue(testMapOrBuilder.containsInt32ToBytesField(2));
+ assertTrue(testMapOrBuilder.containsInt32ToBytesField(3));
+ assertFalse(testMapOrBuilder.containsInt32ToBytesField(-1));
+
+ assertTrue(testMapOrBuilder.containsInt32ToEnumField(1));
+ assertTrue(testMapOrBuilder.containsInt32ToEnumField(2));
+ assertTrue(testMapOrBuilder.containsInt32ToEnumField(3));
+ assertFalse(testMapOrBuilder.containsInt32ToEnumField(-1));
+
+ assertTrue(testMapOrBuilder.containsInt32ToMessageField(1));
+ assertTrue(testMapOrBuilder.containsInt32ToMessageField(2));
+ assertTrue(testMapOrBuilder.containsInt32ToMessageField(3));
+ assertFalse(testMapOrBuilder.containsInt32ToMessageField(-1));
+
+ assertTrue(testMapOrBuilder.containsStringToInt32Field("1"));
+ assertTrue(testMapOrBuilder.containsStringToInt32Field("2"));
+ assertTrue(testMapOrBuilder.containsStringToInt32Field("3"));
+ assertFalse(testMapOrBuilder.containsStringToInt32Field("-1"));
+ }
+
+ public void testCount() {
+ TestMap.Builder builder = TestMap.newBuilder();
+ assertMapCounts(0, builder);
+
+ setMapValuesUsingMutableMap(builder);
+ assertMapCounts(3, builder);
+
+ TestMap message = builder.build();
+ assertMapCounts(3, message);
+
+ builder = message.toBuilder().putInt32ToInt32Field(4, 44);
+ assertEquals(4, builder.getInt32ToInt32FieldCount());
+ assertEquals(4, builder.build().getInt32ToInt32FieldCount());
+
+ // already present - should be unchanged
+ builder.putInt32ToInt32Field(4, 44);
+ assertEquals(4, builder.getInt32ToInt32FieldCount());
+ }
+
+ private void assertMapCounts(int expectedCount, TestMapOrBuilder testMapOrBuilder) {
+ assertEquals(expectedCount, testMapOrBuilder.getInt32ToInt32FieldCount());
+ assertEquals(expectedCount, testMapOrBuilder.getInt32ToStringFieldCount());
+ assertEquals(expectedCount, testMapOrBuilder.getInt32ToBytesFieldCount());
+ assertEquals(expectedCount, testMapOrBuilder.getInt32ToEnumFieldCount());
+ assertEquals(expectedCount, testMapOrBuilder.getInt32ToMessageFieldCount());
+ assertEquals(expectedCount, testMapOrBuilder.getStringToInt32FieldCount());
+ }
+
+ public void testGetOrDefault() {
+ TestMap.Builder builder = TestMap.newBuilder();
+ assertMapCounts(0, builder);
+ setMapValuesUsingAccessors(builder);
+ doTestGetOrDefault(builder);
+ doTestGetOrDefault(builder.build());
+ }
+
+ public void doTestGetOrDefault(TestMapOrBuilder testMapOrBuilder) {
+ assertEquals(11, testMapOrBuilder.getInt32ToInt32FieldOrDefault(1, -11));
+ assertEquals(-11, testMapOrBuilder.getInt32ToInt32FieldOrDefault(-1, -11));
+
+ assertEquals("11", testMapOrBuilder.getInt32ToStringFieldOrDefault(1, "-11"));
+ assertNull("-11", testMapOrBuilder.getInt32ToStringFieldOrDefault(-1, null));
+
+ assertEquals(TestUtil.toBytes("11"), testMapOrBuilder.getInt32ToBytesFieldOrDefault(1, null));
+ assertNull(testMapOrBuilder.getInt32ToBytesFieldOrDefault(-1, null));
+
+ assertEquals(TestMap.EnumValue.FOO, testMapOrBuilder.getInt32ToEnumFieldOrDefault(1, null));
+ assertNull(testMapOrBuilder.getInt32ToEnumFieldOrDefault(-1, null));
+
+ assertEquals(MessageValue.newBuilder().setValue(11).build(),
+ testMapOrBuilder.getInt32ToMessageFieldOrDefault(1, null));
+ assertNull(testMapOrBuilder.getInt32ToMessageFieldOrDefault(-1, null));
+
+ assertEquals(11, testMapOrBuilder.getStringToInt32FieldOrDefault("1", -11));
+ assertEquals(-11, testMapOrBuilder.getStringToInt32FieldOrDefault("-1", -11));
+
+ try {
+ testMapOrBuilder.getStringToInt32FieldOrDefault(null, -11);
+ fail();
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ public void testGetOrThrow() {
+ TestMap.Builder builder = TestMap.newBuilder();
+ assertMapCounts(0, builder);
+ setMapValuesUsingAccessors(builder);
+ doTestGetOrDefault(builder);
+ doTestGetOrDefault(builder.build());
+ }
+
+ public void doTestGetOrThrow(TestMapOrBuilder testMapOrBuilder) {
+ assertEquals(11, testMapOrBuilder.getInt32ToInt32FieldOrThrow(1));
+ try {
+ testMapOrBuilder.getInt32ToInt32FieldOrThrow(-1);
+ fail();
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ assertEquals("11", testMapOrBuilder.getInt32ToStringFieldOrThrow(1));
+
+ try {
+ testMapOrBuilder.getInt32ToStringFieldOrThrow(-1);
+ fail();
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ assertEquals(TestUtil.toBytes("11"), testMapOrBuilder.getInt32ToBytesFieldOrThrow(1));
+
+ try {
+ testMapOrBuilder.getInt32ToBytesFieldOrThrow(-1);
+ fail();
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ assertEquals(TestMap.EnumValue.FOO, testMapOrBuilder.getInt32ToEnumFieldOrThrow(1));
+ try {
+ testMapOrBuilder.getInt32ToEnumFieldOrThrow(-1);
+ fail();
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ assertEquals(MessageValue.newBuilder().setValue(11).build(),
+ testMapOrBuilder.getInt32ToMessageFieldOrThrow(1));
+ try {
+ testMapOrBuilder.getInt32ToMessageFieldOrThrow(-1);
+ fail();
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ assertEquals(11, testMapOrBuilder.getStringToInt32FieldOrThrow("1"));
+ try {
+ testMapOrBuilder.getStringToInt32FieldOrThrow("-1");
+ fail();
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ testMapOrBuilder.getStringToInt32FieldOrThrow(null);
+ fail();
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ public void testPut() {
+ TestMap.Builder builder = TestMap.newBuilder();
+ builder.putInt32ToInt32Field(1, 11);
+ assertEquals(11, builder.getInt32ToInt32FieldOrThrow(1));
+
+ builder.putInt32ToStringField(1, "a");
+ assertEquals("a", builder.getInt32ToStringFieldOrThrow(1));
+ try {
+ builder.putInt32ToStringField(1, null);
+ fail();
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ builder.putInt32ToBytesField(1, TestUtil.toBytes("11"));
+ assertEquals(TestUtil.toBytes("11"), builder.getInt32ToBytesFieldOrThrow(1));
+ try {
+ builder.putInt32ToBytesField(1, null);
+ fail();
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ builder.putInt32ToEnumField(1, TestMap.EnumValue.FOO);
+ assertEquals(TestMap.EnumValue.FOO, builder.getInt32ToEnumFieldOrThrow(1));
+ try {
+ builder.putInt32ToEnumField(1, null);
+ fail();
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ builder.putStringToInt32Field("a", 1);
+ assertEquals(1, builder.getStringToInt32FieldOrThrow("a"));
+ try {
+ builder.putStringToInt32Field(null, -1);
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ public void testRemove() {
+ TestMap.Builder builder = TestMap.newBuilder();
+ setMapValuesUsingMutableMap(builder);
+ assertEquals(11, builder.getInt32ToInt32FieldOrThrow(1));
+ for (int times = 0; times < 2; times++) {
+ builder.removeInt32ToInt32Field(1);
+ assertEquals(-1, builder.getInt32ToInt32FieldOrDefault(1, -1));
+ }
+
+ assertEquals("11", builder.getInt32ToStringFieldOrThrow(1));
+ for (int times = 0; times < 2; times++) {
+ builder.removeInt32ToStringField(1);
+ assertNull(builder.getInt32ToStringFieldOrDefault(1, null));
+ }
+
+ assertEquals(TestUtil.toBytes("11"), builder.getInt32ToBytesFieldOrThrow(1));
+ for (int times = 0; times < 2; times++) {
+ builder.removeInt32ToBytesField(1);
+ assertNull(builder.getInt32ToBytesFieldOrDefault(1, null));
+ }
+
+ assertEquals(TestMap.EnumValue.FOO, builder.getInt32ToEnumFieldOrThrow(1));
+ for (int times = 0; times < 2; times++) {
+ builder.removeInt32ToEnumField(1);
+ assertNull(builder.getInt32ToEnumFieldOrDefault(1, null));
+ }
+
+ assertEquals(11, builder.getStringToInt32FieldOrThrow("1"));
+ for (int times = 0; times < 2; times++) {
+ builder.removeStringToInt32Field("1");
+ assertEquals(-1, builder.getStringToInt32FieldOrDefault("1", -1));
+ }
+
+ try {
+ builder.removeStringToInt32Field(null);
+ fail();
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
// Regression test for b/20494788
public void testMapInitializationOrder() throws Exception {
assertEquals("RedactAllTypes", map_test.RedactAllTypes
@@ -667,18 +1142,36 @@ public class MapForProto2Test extends TestCase {
message.getDescriptorForType().findFieldByName("map_field"), 0);
assertEquals(2, mapEntry.getAllFields().size());
}
-
+
private static <K, V> Map<K, V> newMap(K key1, V value1) {
Map<K, V> map = new HashMap<K, V>();
map.put(key1, value1);
return map;
}
-
+
private static <K, V> Map<K, V> newMap(K key1, V value1, K key2, V value2) {
Map<K, V> map = new HashMap<K, V>();
map.put(key1, value1);
map.put(key2, value2);
return map;
}
-}
+ public void testGetMap() {
+ TestMap.Builder builder = TestMap.newBuilder();
+ setMapValuesUsingAccessors(builder);
+ assertMapValuesSet(builder);
+ TestMap message = builder.build();
+ assertEquals(
+ message.getStringToInt32Field(),
+ message.getStringToInt32FieldMap());
+ assertEquals(
+ message.getInt32ToBytesField(),
+ message.getInt32ToBytesFieldMap());
+ assertEquals(
+ message.getInt32ToEnumField(),
+ message.getInt32ToEnumFieldMap());
+ assertEquals(
+ message.getInt32ToMessageField(),
+ message.getInt32ToMessageFieldMap());
+ }
+}
diff --git a/java/src/test/java/com/google/protobuf/MapTest.java b/java/core/src/test/java/com/google/protobuf/MapTest.java
index 0e5c1284..caef246b 100644
--- a/java/src/test/java/com/google/protobuf/MapTest.java
+++ b/java/core/src/test/java/com/google/protobuf/MapTest.java
@@ -30,16 +30,20 @@
package com.google.protobuf;
+
import com.google.protobuf.Descriptors.Descriptor;
import com.google.protobuf.Descriptors.EnumDescriptor;
import com.google.protobuf.Descriptors.EnumValueDescriptor;
import com.google.protobuf.Descriptors.FieldDescriptor;
+import map_test.MapTestProto.BizarroTestMap;
import map_test.MapTestProto.TestMap;
import map_test.MapTestProto.TestMap.MessageValue;
+import map_test.MapTestProto.TestMapOrBuilder;
import map_test.MapTestProto.TestOnChangeEventPropagation;
-
import junit.framework.TestCase;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@@ -50,7 +54,8 @@ import java.util.Map;
* Unit tests for map fields.
*/
public class MapTest extends TestCase {
- private void setMapValues(TestMap.Builder builder) {
+
+ private void setMapValuesUsingMutableMap(TestMap.Builder builder) {
builder.getMutableInt32ToInt32Field().put(1, 11);
builder.getMutableInt32ToInt32Field().put(2, 22);
builder.getMutableInt32ToInt32Field().put(3, 33);
@@ -79,6 +84,46 @@ public class MapTest extends TestCase {
builder.getMutableStringToInt32Field().put("3", 33);
}
+ private void setMapValuesUsingAccessors(TestMap.Builder builder) {
+ builder
+ .putInt32ToInt32Field(1, 11)
+ .putInt32ToInt32Field(2, 22)
+ .putInt32ToInt32Field(3, 33)
+
+ .putInt32ToStringField(1, "11")
+ .putInt32ToStringField(2, "22")
+ .putInt32ToStringField(3, "33")
+
+ .putInt32ToBytesField(1, TestUtil.toBytes("11"))
+ .putInt32ToBytesField(2, TestUtil.toBytes("22"))
+ .putInt32ToBytesField(3, TestUtil.toBytes("33"))
+
+ .putInt32ToEnumField(1, TestMap.EnumValue.FOO)
+ .putInt32ToEnumField(2, TestMap.EnumValue.BAR)
+ .putInt32ToEnumField(3, TestMap.EnumValue.BAZ)
+
+ .putInt32ToMessageField(1, MessageValue.newBuilder().setValue(11).build())
+ .putInt32ToMessageField(2, MessageValue.newBuilder().setValue(22).build())
+ .putInt32ToMessageField(3, MessageValue.newBuilder().setValue(33).build())
+
+ .putStringToInt32Field("1", 11)
+ .putStringToInt32Field("2", 22)
+ .putStringToInt32Field("3", 33);
+ }
+
+ public void testSetMapValues() {
+ TestMap.Builder usingMutableMapBuilder = TestMap.newBuilder();
+ setMapValuesUsingMutableMap(usingMutableMapBuilder);
+ TestMap usingMutableMap = usingMutableMapBuilder.build();
+ assertMapValuesSet(usingMutableMap);
+
+ TestMap.Builder usingAccessorsBuilder = TestMap.newBuilder();
+ setMapValuesUsingAccessors(usingAccessorsBuilder);
+ TestMap usingAccessors = usingAccessorsBuilder.build();
+ assertMapValuesSet(usingAccessors);
+ assertEquals(usingAccessors, usingMutableMap);
+ }
+
private void copyMapValues(TestMap source, TestMap.Builder destination) {
destination
.putAllInt32ToInt32Field(source.getInt32ToInt32Field())
@@ -121,7 +166,7 @@ public class MapTest extends TestCase {
assertEquals(33, message.getStringToInt32Field().get("3").intValue());
}
- private void updateMapValues(TestMap.Builder builder) {
+ private void updateMapValuesUsingMutableMap(TestMap.Builder builder) {
builder.getMutableInt32ToInt32Field().put(1, 111);
builder.getMutableInt32ToInt32Field().remove(2);
builder.getMutableInt32ToInt32Field().put(4, 44);
@@ -149,6 +194,58 @@ public class MapTest extends TestCase {
builder.getMutableStringToInt32Field().put("4", 44);
}
+ private void updateMapValuesUsingAccessors(TestMap.Builder builder) {
+ builder
+ .putInt32ToInt32Field(1, 111)
+ .removeInt32ToInt32Field(2)
+ .putInt32ToInt32Field(4, 44)
+
+ .putInt32ToStringField(1, "111")
+ .removeInt32ToStringField(2)
+ .putInt32ToStringField(4, "44")
+
+ .putInt32ToBytesField(1, TestUtil.toBytes("111"))
+ .removeInt32ToBytesField(2)
+ .putInt32ToBytesField(4, TestUtil.toBytes("44"))
+
+ .putInt32ToEnumField(1, TestMap.EnumValue.BAR)
+ .removeInt32ToEnumField(2)
+ .putInt32ToEnumField(4, TestMap.EnumValue.QUX)
+
+ .putInt32ToMessageField(1, MessageValue.newBuilder().setValue(111).build())
+ .removeInt32ToMessageField(2)
+ .putInt32ToMessageField(4, MessageValue.newBuilder().setValue(44).build())
+
+ .putStringToInt32Field("1", 111)
+ .removeStringToInt32Field("2")
+ .putStringToInt32Field("4", 44);
+ }
+
+ public void testUpdateMapValues() {
+ TestMap.Builder usingMutableMapBuilder = TestMap.newBuilder();
+ setMapValuesUsingMutableMap(usingMutableMapBuilder);
+ TestMap usingMutableMap = usingMutableMapBuilder.build();
+ assertMapValuesSet(usingMutableMap);
+
+ TestMap.Builder usingAccessorsBuilder = TestMap.newBuilder();
+ setMapValuesUsingAccessors(usingAccessorsBuilder);
+ TestMap usingAccessors = usingAccessorsBuilder.build();
+ assertMapValuesSet(usingAccessors);
+ assertEquals(usingAccessors, usingMutableMap);
+
+ usingMutableMapBuilder = usingMutableMap.toBuilder();
+ updateMapValuesUsingMutableMap(usingMutableMapBuilder);
+ usingMutableMap = usingMutableMapBuilder.build();
+ assertMapValuesUpdated(usingMutableMap);
+
+ usingAccessorsBuilder = usingAccessors.toBuilder();
+ updateMapValuesUsingAccessors(usingAccessorsBuilder);
+ usingAccessors = usingAccessorsBuilder.build();
+ assertMapValuesUpdated(usingAccessors);
+
+ assertEquals(usingAccessors, usingMutableMap);
+ }
+
private void assertMapValuesUpdated(TestMap message) {
assertEquals(3, message.getInt32ToInt32Field().size());
assertEquals(111, message.getInt32ToInt32Field().get(1).intValue());
@@ -181,15 +278,50 @@ public class MapTest extends TestCase {
assertEquals(44, message.getStringToInt32Field().get("4").intValue());
}
- private void assertMapValuesCleared(TestMap message) {
- assertEquals(0, message.getInt32ToInt32Field().size());
- assertEquals(0, message.getInt32ToStringField().size());
- assertEquals(0, message.getInt32ToBytesField().size());
- assertEquals(0, message.getInt32ToEnumField().size());
- assertEquals(0, message.getInt32ToMessageField().size());
- assertEquals(0, message.getStringToInt32Field().size());
+ private void assertMapValuesCleared(TestMapOrBuilder testMapOrBuilder) {
+ assertEquals(0, testMapOrBuilder.getInt32ToInt32Field().size());
+ assertEquals(0, testMapOrBuilder.getInt32ToInt32FieldCount());
+ assertEquals(0, testMapOrBuilder.getInt32ToStringField().size());
+ assertEquals(0, testMapOrBuilder.getInt32ToStringFieldCount());
+ assertEquals(0, testMapOrBuilder.getInt32ToBytesField().size());
+ assertEquals(0, testMapOrBuilder.getInt32ToBytesFieldCount());
+ assertEquals(0, testMapOrBuilder.getInt32ToEnumField().size());
+ assertEquals(0, testMapOrBuilder.getInt32ToEnumFieldCount());
+ assertEquals(0, testMapOrBuilder.getInt32ToMessageField().size());
+ assertEquals(0, testMapOrBuilder.getInt32ToMessageFieldCount());
+ assertEquals(0, testMapOrBuilder.getStringToInt32Field().size());
+ assertEquals(0, testMapOrBuilder.getStringToInt32FieldCount());
}
-
+
+ public void testGetMapIsImmutable() {
+ TestMap.Builder builder = TestMap.newBuilder();
+ assertMapsAreImmutable(builder);
+ assertMapsAreImmutable(builder.build());
+
+ setMapValuesUsingAccessors(builder);
+ assertMapsAreImmutable(builder);
+ assertMapsAreImmutable(builder.build());
+ }
+
+ private void assertMapsAreImmutable(TestMapOrBuilder testMapOrBuilder) {
+ assertImmutable(testMapOrBuilder.getInt32ToInt32Field(), 1, 2);
+ assertImmutable(testMapOrBuilder.getInt32ToStringField(), 1, "2");
+ assertImmutable(testMapOrBuilder.getInt32ToBytesField(), 1, TestUtil.toBytes("2"));
+ assertImmutable(testMapOrBuilder.getInt32ToEnumField(), 1, TestMap.EnumValue.FOO);
+ assertImmutable(
+ testMapOrBuilder.getInt32ToMessageField(), 1, MessageValue.getDefaultInstance());
+ assertImmutable(testMapOrBuilder.getStringToInt32Field(), "1", 2);
+ }
+
+ private <K, V> void assertImmutable(Map<K, V> map, K key, V value) {
+ try {
+ map.put(key, value);
+ fail();
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ }
+
public void testMutableMapLifecycle() {
TestMap.Builder builder = TestMap.newBuilder();
Map<Integer, Integer> intMap = builder.getMutableInt32ToInt32Field();
@@ -219,7 +351,7 @@ public class MapTest extends TestCase {
assertEquals(
newMap(1, TestMap.EnumValue.BAR, 2, TestMap.EnumValue.FOO),
builder.getInt32ToEnumField());
-
+
Map<Integer, String> stringMap = builder.getMutableInt32ToStringField();
stringMap.put(1, "1");
assertEquals(newMap(1, "1"), builder.build().getInt32ToStringField());
@@ -234,7 +366,7 @@ public class MapTest extends TestCase {
assertEquals(
newMap(1, "1", 2, "2"),
builder.getInt32ToStringField());
-
+
Map<Integer, TestMap.MessageValue> messageMap = builder.getMutableInt32ToMessageField();
messageMap.put(1, TestMap.MessageValue.getDefaultInstance());
assertEquals(newMap(1, TestMap.MessageValue.getDefaultInstance()),
@@ -299,32 +431,34 @@ public class MapTest extends TestCase {
assertEquals(newMap(1, 2), builder.getInt32ToInt32Field());
assertEquals(newMap(1, 2), builder.build().getInt32ToInt32Field());
}
-
+
public void testGettersAndSetters() throws Exception {
TestMap.Builder builder = TestMap.newBuilder();
TestMap message = builder.build();
assertMapValuesCleared(message);
builder = message.toBuilder();
- setMapValues(builder);
+ setMapValuesUsingMutableMap(builder);
message = builder.build();
assertMapValuesSet(message);
builder = message.toBuilder();
- updateMapValues(builder);
+ updateMapValuesUsingMutableMap(builder);
message = builder.build();
assertMapValuesUpdated(message);
builder = message.toBuilder();
builder.clear();
+ assertMapValuesCleared(builder);
message = builder.build();
assertMapValuesCleared(message);
}
public void testPutAll() throws Exception {
TestMap.Builder sourceBuilder = TestMap.newBuilder();
- setMapValues(sourceBuilder);
+ setMapValuesUsingMutableMap(sourceBuilder);
TestMap source = sourceBuilder.build();
+ assertMapValuesSet(source);
TestMap.Builder destination = TestMap.newBuilder();
copyMapValues(source, destination);
@@ -345,18 +479,76 @@ public class MapTest extends TestCase {
assertEquals(0, destination.getInt32ToEnumFieldValue().get(0).intValue());
assertEquals(1, destination.getInt32ToEnumFieldValue().get(1).intValue());
assertEquals(1000, destination.getInt32ToEnumFieldValue().get(2).intValue());
+ assertEquals(3, destination.getInt32ToEnumFieldCount());
+ }
+
+ public void testPutForUnknownEnumValues() throws Exception {
+ TestMap.Builder builder = TestMap.newBuilder()
+ .putInt32ToEnumFieldValue(0, 0)
+ .putInt32ToEnumFieldValue(1, 1);
+
+ try {
+ builder.putInt32ToEnumFieldValue(2, 1000); // unknown value.
+ fail();
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ TestMap message = builder.build();
+ assertEquals(0, message.getInt32ToEnumFieldValueOrThrow(0));
+ assertEquals(1, message.getInt32ToEnumFieldValueOrThrow(1));
+ assertEquals(2, message.getInt32ToEnumFieldCount());
+ }
+
+ public void testPutChecksNullKeysAndValues() throws Exception {
+ TestMap.Builder builder = TestMap.newBuilder();
+
+ try {
+ builder.putInt32ToStringField(1, null);
+ fail();
+ } catch (NullPointerException e) {
+ // expected.
+ }
+
+ try {
+ builder.putInt32ToBytesField(1, null);
+ fail();
+ } catch (NullPointerException e) {
+ // expected.
+ }
+
+ try {
+ builder.putInt32ToEnumField(1, null);
+ fail();
+ } catch (NullPointerException e) {
+ // expected.
+ }
+
+ try {
+ builder.putInt32ToMessageField(1, null);
+ fail();
+ } catch (NullPointerException e) {
+ // expected.
+ }
+
+ try {
+ builder.putStringToInt32Field(null, 1);
+ fail();
+ } catch (NullPointerException e) {
+ // expected.
+ }
}
public void testSerializeAndParse() throws Exception {
TestMap.Builder builder = TestMap.newBuilder();
- setMapValues(builder);
+ setMapValuesUsingMutableMap(builder);
TestMap message = builder.build();
assertEquals(message.getSerializedSize(), message.toByteString().size());
message = TestMap.parser().parseFrom(message.toByteString());
assertMapValuesSet(message);
builder = message.toBuilder();
- updateMapValues(builder);
+ updateMapValuesUsingMutableMap(builder);
message = builder.build();
assertEquals(message.getSerializedSize(), message.toByteString().size());
message = TestMap.parser().parseFrom(message.toByteString());
@@ -370,9 +562,58 @@ public class MapTest extends TestCase {
assertMapValuesCleared(message);
}
+ private TestMap tryParseTestMap(BizarroTestMap bizarroMap) throws IOException {
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ CodedOutputStream output = CodedOutputStream.newInstance(byteArrayOutputStream);
+ bizarroMap.writeTo(output);
+ output.flush();
+ return TestMap.parser().parseFrom(ByteString.copyFrom(byteArrayOutputStream.toByteArray()));
+ }
+
+ public void testParseError() throws Exception {
+ ByteString bytes = TestUtil.toBytes("SOME BYTES");
+ String stringKey = "a string key";
+
+ TestMap map = tryParseTestMap(BizarroTestMap.newBuilder()
+ .putInt32ToInt32Field(5, bytes)
+ .build());
+ assertEquals(map.getInt32ToInt32FieldOrDefault(5, -1), 0);
+
+ map = tryParseTestMap(BizarroTestMap.newBuilder()
+ .putInt32ToStringField(stringKey, 5)
+ .build());
+ assertEquals(map.getInt32ToStringFieldOrDefault(0, null), "");
+
+ map = tryParseTestMap(BizarroTestMap.newBuilder()
+ .putInt32ToBytesField(stringKey, 5)
+ .build());
+ assertEquals(map.getInt32ToBytesFieldOrDefault(0, null), ByteString.EMPTY);
+
+ map = tryParseTestMap(BizarroTestMap.newBuilder()
+ .putInt32ToEnumField(stringKey, bytes)
+ .build());
+ assertEquals(map.getInt32ToEnumFieldOrDefault(0, null), TestMap.EnumValue.FOO);
+
+ try {
+ tryParseTestMap(BizarroTestMap.newBuilder()
+ .putInt32ToMessageField(stringKey, bytes)
+ .build());
+ fail();
+ } catch (InvalidProtocolBufferException expected) {
+ assertTrue(expected.getUnfinishedMessage() instanceof TestMap);
+ map = (TestMap) expected.getUnfinishedMessage();
+ assertTrue(map.getInt32ToMessageField().isEmpty());
+ }
+
+ map = tryParseTestMap(BizarroTestMap.newBuilder()
+ .putStringToInt32Field(stringKey, bytes)
+ .build());
+ assertEquals(map.getStringToInt32FieldOrDefault(stringKey, -1), 0);
+ }
+
public void testMergeFrom() throws Exception {
TestMap.Builder builder = TestMap.newBuilder();
- setMapValues(builder);
+ setMapValuesUsingMutableMap(builder);
TestMap message = builder.build();
TestMap.Builder other = TestMap.newBuilder();
@@ -630,7 +871,7 @@ public class MapTest extends TestCase {
public void testTextFormat() throws Exception {
TestMap.Builder builder = TestMap.newBuilder();
- setMapValues(builder);
+ setMapValuesUsingMutableMap(builder);
TestMap message = builder.build();
String textData = TextFormat.printToString(message);
@@ -644,7 +885,7 @@ public class MapTest extends TestCase {
public void testDynamicMessage() throws Exception {
TestMap.Builder builder = TestMap.newBuilder();
- setMapValues(builder);
+ setMapValuesUsingMutableMap(builder);
TestMap message = builder.build();
Message dynamicDefaultInstance =
@@ -761,19 +1002,317 @@ public class MapTest extends TestCase {
public void testIterationOrder() throws Exception {
TestMap.Builder builder = TestMap.newBuilder();
- setMapValues(builder);
+ setMapValuesUsingMutableMap(builder);
TestMap message = builder.build();
assertEquals(Arrays.asList("1", "2", "3"),
new ArrayList<String>(message.getStringToInt32Field().keySet()));
}
-
+
+ public void testGetMap() {
+ TestMap.Builder builder = TestMap.newBuilder();
+ setMapValuesUsingMutableMap(builder);
+ TestMap message = builder.build();
+ assertEquals(
+ message.getStringToInt32Field(),
+ message.getStringToInt32FieldMap());
+ assertEquals(
+ message.getInt32ToBytesField(),
+ message.getInt32ToBytesFieldMap());
+ assertEquals(
+ message.getInt32ToEnumField(),
+ message.getInt32ToEnumFieldMap());
+ assertEquals(
+ message.getInt32ToEnumFieldValue(),
+ message.getInt32ToEnumFieldValueMap());
+ assertEquals(
+ message.getInt32ToMessageField(),
+ message.getInt32ToMessageFieldMap());
+ }
+
+ public void testContains() {
+ TestMap.Builder builder = TestMap.newBuilder();
+ setMapValuesUsingMutableMap(builder);
+ assertMapContainsSetValues(builder);
+ assertMapContainsSetValues(builder.build());
+ }
+
+ private void assertMapContainsSetValues(TestMapOrBuilder testMapOrBuilder) {
+ assertTrue(testMapOrBuilder.containsInt32ToInt32Field(1));
+ assertTrue(testMapOrBuilder.containsInt32ToInt32Field(2));
+ assertTrue(testMapOrBuilder.containsInt32ToInt32Field(3));
+ assertFalse(testMapOrBuilder.containsInt32ToInt32Field(-1));
+
+ assertTrue(testMapOrBuilder.containsInt32ToStringField(1));
+ assertTrue(testMapOrBuilder.containsInt32ToStringField(2));
+ assertTrue(testMapOrBuilder.containsInt32ToStringField(3));
+ assertFalse(testMapOrBuilder.containsInt32ToStringField(-1));
+
+ assertTrue(testMapOrBuilder.containsInt32ToBytesField(1));
+ assertTrue(testMapOrBuilder.containsInt32ToBytesField(2));
+ assertTrue(testMapOrBuilder.containsInt32ToBytesField(3));
+ assertFalse(testMapOrBuilder.containsInt32ToBytesField(-1));
+
+ assertTrue(testMapOrBuilder.containsInt32ToEnumField(1));
+ assertTrue(testMapOrBuilder.containsInt32ToEnumField(2));
+ assertTrue(testMapOrBuilder.containsInt32ToEnumField(3));
+ assertFalse(testMapOrBuilder.containsInt32ToEnumField(-1));
+
+ assertTrue(testMapOrBuilder.containsInt32ToMessageField(1));
+ assertTrue(testMapOrBuilder.containsInt32ToMessageField(2));
+ assertTrue(testMapOrBuilder.containsInt32ToMessageField(3));
+ assertFalse(testMapOrBuilder.containsInt32ToMessageField(-1));
+
+ assertTrue(testMapOrBuilder.containsStringToInt32Field("1"));
+ assertTrue(testMapOrBuilder.containsStringToInt32Field("2"));
+ assertTrue(testMapOrBuilder.containsStringToInt32Field("3"));
+ assertFalse(testMapOrBuilder.containsStringToInt32Field("-1"));
+ }
+
+ public void testCount() {
+ TestMap.Builder builder = TestMap.newBuilder();
+ assertMapCounts(0, builder);
+
+ setMapValuesUsingMutableMap(builder);
+ assertMapCounts(3, builder);
+
+ TestMap message = builder.build();
+ assertMapCounts(3, message);
+
+ builder = message.toBuilder().putInt32ToInt32Field(4, 44);
+ assertEquals(4, builder.getInt32ToInt32FieldCount());
+ assertEquals(4, builder.build().getInt32ToInt32FieldCount());
+
+ // already present - should be unchanged
+ builder.putInt32ToInt32Field(4, 44);
+ assertEquals(4, builder.getInt32ToInt32FieldCount());
+ }
+
+ private void assertMapCounts(int expectedCount, TestMapOrBuilder testMapOrBuilder) {
+ assertEquals(expectedCount, testMapOrBuilder.getInt32ToInt32FieldCount());
+ assertEquals(expectedCount, testMapOrBuilder.getInt32ToStringFieldCount());
+ assertEquals(expectedCount, testMapOrBuilder.getInt32ToBytesFieldCount());
+ assertEquals(expectedCount, testMapOrBuilder.getInt32ToEnumFieldCount());
+ assertEquals(expectedCount, testMapOrBuilder.getInt32ToMessageFieldCount());
+ assertEquals(expectedCount, testMapOrBuilder.getStringToInt32FieldCount());
+ }
+
+ public void testGetOrDefault() {
+ TestMap.Builder builder = TestMap.newBuilder();
+ assertMapCounts(0, builder);
+ setMapValuesUsingAccessors(builder);
+ doTestGetOrDefault(builder);
+ doTestGetOrDefault(builder.build());
+ }
+
+ public void doTestGetOrDefault(TestMapOrBuilder testMapOrBuilder) {
+ assertEquals(11, testMapOrBuilder.getInt32ToInt32FieldOrDefault(1, -11));
+ assertEquals(-11, testMapOrBuilder.getInt32ToInt32FieldOrDefault(-1, -11));
+
+ assertEquals("11", testMapOrBuilder.getInt32ToStringFieldOrDefault(1, "-11"));
+ assertNull("-11", testMapOrBuilder.getInt32ToStringFieldOrDefault(-1, null));
+
+ assertEquals(TestUtil.toBytes("11"), testMapOrBuilder.getInt32ToBytesFieldOrDefault(1, null));
+ assertNull(testMapOrBuilder.getInt32ToBytesFieldOrDefault(-1, null));
+
+ assertEquals(TestMap.EnumValue.FOO, testMapOrBuilder.getInt32ToEnumFieldOrDefault(1, null));
+ assertNull(testMapOrBuilder.getInt32ToEnumFieldOrDefault(-1, null));
+
+ assertEquals(
+ TestMap.EnumValue.BAR.getNumber(),
+ (int) testMapOrBuilder.getInt32ToEnumFieldValueOrDefault(2, -1));
+ assertEquals(-1, testMapOrBuilder.getInt32ToEnumFieldValueOrDefault(-1000, -1));
+
+ assertEquals(MessageValue.newBuilder().setValue(11).build(),
+ testMapOrBuilder.getInt32ToMessageFieldOrDefault(1, null));
+ assertNull(testMapOrBuilder.getInt32ToMessageFieldOrDefault(-1, null));
+
+ assertEquals(11, testMapOrBuilder.getStringToInt32FieldOrDefault("1", -11));
+ assertEquals(-11, testMapOrBuilder.getStringToInt32FieldOrDefault("-1", -11));
+
+ try {
+ testMapOrBuilder.getStringToInt32FieldOrDefault(null, -11);
+ fail();
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ public void testGetOrThrow() {
+ TestMap.Builder builder = TestMap.newBuilder();
+ assertMapCounts(0, builder);
+ setMapValuesUsingAccessors(builder);
+ doTestGetOrDefault(builder);
+ doTestGetOrDefault(builder.build());
+ }
+
+ public void doTestGetOrThrow(TestMapOrBuilder testMapOrBuilder) {
+ assertEquals(11, testMapOrBuilder.getInt32ToInt32FieldOrThrow(1));
+ try {
+ testMapOrBuilder.getInt32ToInt32FieldOrThrow(-1);
+ fail();
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ assertEquals("11", testMapOrBuilder.getInt32ToStringFieldOrThrow(1));
+
+ try {
+ testMapOrBuilder.getInt32ToStringFieldOrThrow(-1);
+ fail();
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ assertEquals(TestUtil.toBytes("11"), testMapOrBuilder.getInt32ToBytesFieldOrThrow(1));
+
+ try {
+ testMapOrBuilder.getInt32ToBytesFieldOrThrow(-1);
+ fail();
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ assertEquals(TestMap.EnumValue.FOO, testMapOrBuilder.getInt32ToEnumFieldOrThrow(1));
+ try {
+ testMapOrBuilder.getInt32ToEnumFieldOrThrow(-1);
+ fail();
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ assertEquals(
+ TestMap.EnumValue.BAR.getNumber(), testMapOrBuilder.getInt32ToEnumFieldValueOrThrow(2));
+ try {
+ testMapOrBuilder.getInt32ToEnumFieldValueOrThrow(-1);
+ fail();
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ assertEquals(MessageValue.newBuilder().setValue(11).build(),
+ testMapOrBuilder.getInt32ToMessageFieldOrThrow(1));
+ try {
+ testMapOrBuilder.getInt32ToMessageFieldOrThrow(-1);
+ fail();
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ assertEquals(11, testMapOrBuilder.getStringToInt32FieldOrThrow("1"));
+ try {
+ testMapOrBuilder.getStringToInt32FieldOrThrow("-1");
+ fail();
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ testMapOrBuilder.getStringToInt32FieldOrThrow(null);
+ fail();
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ public void testPut() {
+ TestMap.Builder builder = TestMap.newBuilder();
+ builder.putInt32ToInt32Field(1, 11);
+ assertEquals(11, builder.getInt32ToInt32FieldOrThrow(1));
+
+ builder.putInt32ToStringField(1, "a");
+ assertEquals("a", builder.getInt32ToStringFieldOrThrow(1));
+ try {
+ builder.putInt32ToStringField(1, null);
+ fail();
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ builder.putInt32ToBytesField(1, TestUtil.toBytes("11"));
+ assertEquals(TestUtil.toBytes("11"), builder.getInt32ToBytesFieldOrThrow(1));
+ try {
+ builder.putInt32ToBytesField(1, null);
+ fail();
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ builder.putInt32ToEnumField(1, TestMap.EnumValue.FOO);
+ assertEquals(TestMap.EnumValue.FOO, builder.getInt32ToEnumFieldOrThrow(1));
+ try {
+ builder.putInt32ToEnumField(1, null);
+ fail();
+ } catch (NullPointerException e) {
+ // expected
+ }
+
+ builder.putInt32ToEnumFieldValue(1, TestMap.EnumValue.BAR.getNumber());
+ assertEquals(
+ TestMap.EnumValue.BAR.getNumber(), builder.getInt32ToEnumFieldValueOrThrow(1));
+ try {
+ builder.putInt32ToEnumFieldValue(1, -1);
+ fail();
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ builder.putStringToInt32Field("a", 1);
+ assertEquals(1, builder.getStringToInt32FieldOrThrow("a"));
+ try {
+ builder.putStringToInt32Field(null, -1);
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
+ public void testRemove() {
+ TestMap.Builder builder = TestMap.newBuilder();
+ setMapValuesUsingMutableMap(builder);
+ assertEquals(11, builder.getInt32ToInt32FieldOrThrow(1));
+ for (int times = 0; times < 2; times++) {
+ builder.removeInt32ToInt32Field(1);
+ assertEquals(-1, builder.getInt32ToInt32FieldOrDefault(1, -1));
+ }
+
+ assertEquals("11", builder.getInt32ToStringFieldOrThrow(1));
+ for (int times = 0; times < 2; times++) {
+ builder.removeInt32ToStringField(1);
+ assertNull(builder.getInt32ToStringFieldOrDefault(1, null));
+ }
+
+ assertEquals(TestUtil.toBytes("11"), builder.getInt32ToBytesFieldOrThrow(1));
+ for (int times = 0; times < 2; times++) {
+ builder.removeInt32ToBytesField(1);
+ assertNull(builder.getInt32ToBytesFieldOrDefault(1, null));
+ }
+
+ assertEquals(TestMap.EnumValue.FOO, builder.getInt32ToEnumFieldOrThrow(1));
+ for (int times = 0; times < 2; times++) {
+ builder.removeInt32ToEnumField(1);
+ assertNull(builder.getInt32ToEnumFieldOrDefault(1, null));
+ }
+
+ assertEquals(11, builder.getStringToInt32FieldOrThrow("1"));
+ for (int times = 0; times < 2; times++) {
+ builder.removeStringToInt32Field("1");
+ assertEquals(-1, builder.getStringToInt32FieldOrDefault("1", -1));
+ }
+
+ try {
+ builder.removeStringToInt32Field(null);
+ fail();
+ } catch (NullPointerException e) {
+ // expected
+ }
+ }
+
private static <K, V> Map<K, V> newMap(K key1, V value1) {
Map<K, V> map = new HashMap<K, V>();
map.put(key1, value1);
return map;
}
-
+
private static <K, V> Map<K, V> newMap(K key1, V value1, K key2, V value2) {
Map<K, V> map = new HashMap<K, V>();
map.put(key1, value1);
diff --git a/java/src/test/java/com/google/protobuf/MessageTest.java b/java/core/src/test/java/com/google/protobuf/MessageTest.java
index abcd3a1d..dcd1aba7 100644
--- a/java/src/test/java/com/google/protobuf/MessageTest.java
+++ b/java/core/src/test/java/com/google/protobuf/MessageTest.java
@@ -30,11 +30,11 @@
package com.google.protobuf;
-import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.ForeignMessage;
import protobuf_unittest.UnittestProto.TestAllExtensions;
+import protobuf_unittest.UnittestProto.TestAllTypes;
import protobuf_unittest.UnittestProto.TestRequired;
import protobuf_unittest.UnittestProto.TestRequiredForeign;
-import protobuf_unittest.UnittestProto.ForeignMessage;
import junit.framework.TestCase;
diff --git a/java/src/test/java/com/google/protobuf/NestedBuildersTest.java b/java/core/src/test/java/com/google/protobuf/NestedBuildersTest.java
index 23653126..542e28c0 100644
--- a/java/src/test/java/com/google/protobuf/NestedBuildersTest.java
+++ b/java/core/src/test/java/com/google/protobuf/NestedBuildersTest.java
@@ -35,8 +35,8 @@ import protobuf_unittest.Wheel;
import junit.framework.TestCase;
-import java.util.List;
import java.util.ArrayList;
+import java.util.List;
/**
* Test cases that exercise end-to-end use cases involving
diff --git a/java/core/src/test/java/com/google/protobuf/NioByteStringTest.java b/java/core/src/test/java/com/google/protobuf/NioByteStringTest.java
new file mode 100644
index 00000000..6be5b93c
--- /dev/null
+++ b/java/core/src/test/java/com/google/protobuf/NioByteStringTest.java
@@ -0,0 +1,620 @@
+// 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.
+
+package com.google.protobuf;
+
+import static com.google.protobuf.Internal.UTF_8;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.nio.BufferOverflowException;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+/**
+ * Tests for {@link NioByteString}.
+ */
+public class NioByteStringTest extends TestCase {
+ private static final ByteString EMPTY = new NioByteString(ByteBuffer.wrap(new byte[0]));
+ private static final String CLASSNAME = NioByteString.class.getSimpleName();
+ private static final byte[] BYTES = ByteStringTest.getTestBytes(1234, 11337766L);
+ private static final int EXPECTED_HASH = ByteString.wrap(BYTES).hashCode();
+
+ private final ByteBuffer backingBuffer = ByteBuffer.wrap(BYTES.clone());
+ private final ByteString testString = new NioByteString(backingBuffer);
+
+ public void testExpectedType() {
+ String actualClassName = getActualClassName(testString);
+ assertEquals(CLASSNAME + " should match type exactly", CLASSNAME, actualClassName);
+ }
+
+ protected String getActualClassName(Object object) {
+ String actualClassName = object.getClass().getName();
+ actualClassName = actualClassName.substring(actualClassName.lastIndexOf('.') + 1);
+ return actualClassName;
+ }
+
+ public void testByteAt() {
+ boolean stillEqual = true;
+ for (int i = 0; stillEqual && i < BYTES.length; ++i) {
+ stillEqual = (BYTES[i] == testString.byteAt(i));
+ }
+ assertTrue(CLASSNAME + " must capture the right bytes", stillEqual);
+ }
+
+ public void testByteIterator() {
+ boolean stillEqual = true;
+ ByteString.ByteIterator iter = testString.iterator();
+ for (int i = 0; stillEqual && i < BYTES.length; ++i) {
+ stillEqual = (iter.hasNext() && BYTES[i] == iter.nextByte());
+ }
+ assertTrue(CLASSNAME + " must capture the right bytes", stillEqual);
+ assertFalse(CLASSNAME + " must have exhausted the itertor", iter.hasNext());
+
+ try {
+ iter.nextByte();
+ fail("Should have thrown an exception.");
+ } catch (NoSuchElementException e) {
+ // This is success
+ }
+ }
+
+ public void testByteIterable() {
+ boolean stillEqual = true;
+ int j = 0;
+ for (byte quantum : testString) {
+ stillEqual = (BYTES[j] == quantum);
+ ++j;
+ }
+ assertTrue(CLASSNAME + " must capture the right bytes as Bytes", stillEqual);
+ assertEquals(CLASSNAME + " iterable character count", BYTES.length, j);
+ }
+
+ public void testSize() {
+ assertEquals(CLASSNAME + " must have the expected size", BYTES.length,
+ testString.size());
+ }
+
+ public void testGetTreeDepth() {
+ assertEquals(CLASSNAME + " must have depth 0", 0, testString.getTreeDepth());
+ }
+
+ public void testIsBalanced() {
+ assertTrue(CLASSNAME + " is technically balanced", testString.isBalanced());
+ }
+
+ public void testCopyTo_ByteArrayOffsetLength() {
+ int destinationOffset = 50;
+ int length = 100;
+ byte[] destination = new byte[destinationOffset + length];
+ int sourceOffset = 213;
+ testString.copyTo(destination, sourceOffset, destinationOffset, length);
+ boolean stillEqual = true;
+ for (int i = 0; stillEqual && i < length; ++i) {
+ stillEqual = BYTES[i + sourceOffset] == destination[i + destinationOffset];
+ }
+ assertTrue(CLASSNAME + ".copyTo(4 arg) must give the expected bytes", stillEqual);
+ }
+
+ public void testCopyTo_ByteArrayOffsetLengthErrors() {
+ int destinationOffset = 50;
+ int length = 100;
+ byte[] destination = new byte[destinationOffset + length];
+
+ try {
+ // Copy one too many bytes
+ testString.copyTo(destination, testString.size() + 1 - length,
+ destinationOffset, length);
+ fail("Should have thrown an exception when copying too many bytes of a "
+ + CLASSNAME);
+ } catch (IndexOutOfBoundsException expected) {
+ // This is success
+ }
+
+ try {
+ // Copy with illegal negative sourceOffset
+ testString.copyTo(destination, -1, destinationOffset, length);
+ fail("Should have thrown an exception when given a negative sourceOffset in "
+ + CLASSNAME);
+ } catch (IndexOutOfBoundsException expected) {
+ // This is success
+ }
+
+ try {
+ // Copy with illegal negative destinationOffset
+ testString.copyTo(destination, 0, -1, length);
+ fail("Should have thrown an exception when given a negative destinationOffset in "
+ + CLASSNAME);
+ } catch (IndexOutOfBoundsException expected) {
+ // This is success
+ }
+
+ try {
+ // Copy with illegal negative size
+ testString.copyTo(destination, 0, 0, -1);
+ fail("Should have thrown an exception when given a negative size in "
+ + CLASSNAME);
+ } catch (IndexOutOfBoundsException expected) {
+ // This is success
+ }
+
+ try {
+ // Copy with illegal too-large sourceOffset
+ testString.copyTo(destination, 2 * testString.size(), 0, length);
+ fail("Should have thrown an exception when the destinationOffset is too large in "
+ + CLASSNAME);
+ } catch (IndexOutOfBoundsException expected) {
+ // This is success
+ }
+
+ try {
+ // Copy with illegal too-large destinationOffset
+ testString.copyTo(destination, 0, 2 * destination.length, length);
+ fail("Should have thrown an exception when the destinationOffset is too large in "
+ + CLASSNAME);
+ } catch (IndexOutOfBoundsException expected) {
+ // This is success
+ }
+ }
+
+ public void testCopyTo_ByteBuffer() {
+ // Same length.
+ ByteBuffer myBuffer = ByteBuffer.allocate(BYTES.length);
+ testString.copyTo(myBuffer);
+ myBuffer.flip();
+ assertEquals(CLASSNAME + ".copyTo(ByteBuffer) must give back the same bytes",
+ backingBuffer, myBuffer);
+
+ // Target buffer bigger than required.
+ myBuffer = ByteBuffer.allocate(testString.size() + 1);
+ testString.copyTo(myBuffer);
+ myBuffer.flip();
+ assertEquals(backingBuffer, myBuffer);
+
+ // Target buffer has no space.
+ myBuffer = ByteBuffer.allocate(0);
+ try {
+ testString.copyTo(myBuffer);
+ fail("Should have thrown an exception when target ByteBuffer has insufficient capacity");
+ } catch (BufferOverflowException e) {
+ // Expected.
+ }
+
+ // Target buffer too small.
+ myBuffer = ByteBuffer.allocate(1);
+ try {
+ testString.copyTo(myBuffer);
+ fail("Should have thrown an exception when target ByteBuffer has insufficient capacity");
+ } catch (BufferOverflowException e) {
+ // Expected.
+ }
+ }
+
+ public void testMarkSupported() {
+ InputStream stream = testString.newInput();
+ assertTrue(CLASSNAME + ".newInput() must support marking", stream.markSupported());
+ }
+
+ public void testMarkAndReset() throws IOException {
+ int fraction = testString.size() / 3;
+
+ InputStream stream = testString.newInput();
+ stream.mark(testString.size()); // First, mark() the end.
+
+ skipFully(stream, fraction); // Skip a large fraction, but not all.
+ assertEquals(
+ CLASSNAME + ": after skipping to the 'middle', half the bytes are available",
+ (testString.size() - fraction), stream.available());
+ stream.reset();
+ assertEquals(
+ CLASSNAME + ": after resetting, all bytes are available",
+ testString.size(), stream.available());
+
+ skipFully(stream, testString.size()); // Skip to the end.
+ assertEquals(
+ CLASSNAME + ": after skipping to the end, no more bytes are available",
+ 0, stream.available());
+ }
+
+ /**
+ * Discards {@code n} bytes of data from the input stream. This method
+ * will block until the full amount has been skipped. Does not close the
+ * stream.
+ * <p>Copied from com.google.common.io.ByteStreams to avoid adding dependency.
+ *
+ * @param in the input stream to read from
+ * @param n the number of bytes to skip
+ * @throws EOFException if this stream reaches the end before skipping all
+ * the bytes
+ * @throws IOException if an I/O error occurs, or the stream does not
+ * support skipping
+ */
+ static void skipFully(InputStream in, long n) throws IOException {
+ long toSkip = n;
+ while (n > 0) {
+ long amt = in.skip(n);
+ if (amt == 0) {
+ // Force a blocking read to avoid infinite loop
+ if (in.read() == -1) {
+ long skipped = toSkip - n;
+ throw new EOFException("reached end of stream after skipping "
+ + skipped + " bytes; " + toSkip + " bytes expected");
+ }
+ n--;
+ } else {
+ n -= amt;
+ }
+ }
+ }
+
+ public void testAsReadOnlyByteBuffer() {
+ ByteBuffer byteBuffer = testString.asReadOnlyByteBuffer();
+ byte[] roundTripBytes = new byte[BYTES.length];
+ assertTrue(byteBuffer.remaining() == BYTES.length);
+ assertTrue(byteBuffer.isReadOnly());
+ byteBuffer.get(roundTripBytes);
+ assertTrue(CLASSNAME + ".asReadOnlyByteBuffer() must give back the same bytes",
+ Arrays.equals(BYTES, roundTripBytes));
+ }
+
+ public void testAsReadOnlyByteBufferList() {
+ List<ByteBuffer> byteBuffers = testString.asReadOnlyByteBufferList();
+ int bytesSeen = 0;
+ byte[] roundTripBytes = new byte[BYTES.length];
+ for (ByteBuffer byteBuffer : byteBuffers) {
+ int thisLength = byteBuffer.remaining();
+ assertTrue(byteBuffer.isReadOnly());
+ assertTrue(bytesSeen + thisLength <= BYTES.length);
+ byteBuffer.get(roundTripBytes, bytesSeen, thisLength);
+ bytesSeen += thisLength;
+ }
+ assertTrue(bytesSeen == BYTES.length);
+ assertTrue(CLASSNAME + ".asReadOnlyByteBufferTest() must give back the same bytes",
+ Arrays.equals(BYTES, roundTripBytes));
+ }
+
+ public void testToByteArray() {
+ byte[] roundTripBytes = testString.toByteArray();
+ assertTrue(CLASSNAME + ".toByteArray() must give back the same bytes",
+ Arrays.equals(BYTES, roundTripBytes));
+ }
+
+ public void testWriteTo() throws IOException {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ testString.writeTo(bos);
+ byte[] roundTripBytes = bos.toByteArray();
+ assertTrue(CLASSNAME + ".writeTo() must give back the same bytes",
+ Arrays.equals(BYTES, roundTripBytes));
+ }
+
+ public void testWriteToShouldNotExposeInternalBufferToOutputStream() throws IOException {
+ OutputStream os = new OutputStream() {
+ @Override
+ public void write(byte[] b, int off, int len) {
+ Arrays.fill(b, off, off + len, (byte) 0);
+ }
+
+ @Override
+ public void write(int b) {
+ throw new UnsupportedOperationException();
+ }
+ };
+
+ byte[] original = Arrays.copyOf(BYTES, BYTES.length);
+ testString.writeTo(os);
+ assertTrue(CLASSNAME + ".writeTo() must NOT grant access to underlying buffer",
+ Arrays.equals(original, BYTES));
+ }
+
+ public void testWriteToInternalShouldExposeInternalBufferToOutputStream() throws IOException {
+ OutputStream os = new OutputStream() {
+ @Override
+ public void write(byte[] b, int off, int len) {
+ Arrays.fill(b, off, off + len, (byte) 0);
+ }
+
+ @Override
+ public void write(int b) {
+ throw new UnsupportedOperationException();
+ }
+ };
+
+ testString.writeToInternal(os, 0, testString.size());
+ byte[] allZeros = new byte[testString.size()];
+ assertTrue(CLASSNAME + ".writeToInternal() must grant access to underlying buffer",
+ Arrays.equals(allZeros, backingBuffer.array()));
+ }
+
+ public void testWriteToShouldExposeInternalBufferToByteOutput() throws IOException {
+ ByteOutput out = new ByteOutput() {
+ @Override
+ public void write(byte value) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void write(byte[] value, int offset, int length) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void writeLazy(byte[] value, int offset, int length) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void write(ByteBuffer value) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void writeLazy(ByteBuffer value) throws IOException {
+ Arrays.fill(value.array(), value.arrayOffset(), value.arrayOffset() + value.limit(),
+ (byte) 0);
+ }
+ };
+
+ testString.writeTo(out);
+ byte[] allZeros = new byte[testString.size()];
+ assertTrue(CLASSNAME + ".writeTo() must grant access to underlying buffer",
+ Arrays.equals(allZeros, backingBuffer.array()));
+ }
+
+ public void testNewOutput() throws IOException {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ByteString.Output output = ByteString.newOutput();
+ testString.writeTo(output);
+ assertEquals("Output Size returns correct result",
+ output.size(), testString.size());
+ output.writeTo(bos);
+ assertTrue("Output.writeTo() must give back the same bytes",
+ Arrays.equals(BYTES, bos.toByteArray()));
+
+ // write the output stream to itself! This should cause it to double
+ output.writeTo(output);
+ assertEquals("Writing an output stream to itself is successful",
+ testString.concat(testString), output.toByteString());
+
+ output.reset();
+ assertEquals("Output.reset() resets the output", 0, output.size());
+ assertEquals("Output.reset() resets the output",
+ EMPTY, output.toByteString());
+ }
+
+ public void testToString() {
+ String testString = "I love unicode \u1234\u5678 characters";
+ ByteString unicode = forString(testString);
+ String roundTripString = unicode.toString(UTF_8);
+ assertEquals(CLASSNAME + " unicode must match", testString, roundTripString);
+ }
+
+ public void testCharsetToString() {
+ String testString = "I love unicode \u1234\u5678 characters";
+ ByteString unicode = forString(testString);
+ String roundTripString = unicode.toString(UTF_8);
+ assertEquals(CLASSNAME + " unicode must match", testString, roundTripString);
+ }
+
+ public void testToString_returnsCanonicalEmptyString() {
+ assertSame(CLASSNAME + " must be the same string references",
+ EMPTY.toString(UTF_8),
+ new NioByteString(ByteBuffer.wrap(new byte[0])).toString(UTF_8));
+ }
+
+ public void testToString_raisesException() {
+ try {
+ EMPTY.toString("invalid");
+ fail("Should have thrown an exception.");
+ } catch (UnsupportedEncodingException expected) {
+ // This is success
+ }
+
+ try {
+ testString.toString("invalid");
+ fail("Should have thrown an exception.");
+ } catch (UnsupportedEncodingException expected) {
+ // This is success
+ }
+ }
+
+ public void testEquals() {
+ assertEquals(CLASSNAME + " must not equal null", false, testString.equals(null));
+ assertEquals(CLASSNAME + " must equal self", testString, testString);
+ assertFalse(CLASSNAME + " must not equal the empty string",
+ testString.equals(EMPTY));
+ assertEquals(CLASSNAME + " empty strings must be equal",
+ EMPTY, testString.substring(55, 55));
+ assertEquals(CLASSNAME + " must equal another string with the same value",
+ testString, new NioByteString(backingBuffer));
+
+ byte[] mungedBytes = mungedBytes();
+ assertFalse(CLASSNAME + " must not equal every string with the same length",
+ testString.equals(new NioByteString(ByteBuffer.wrap(mungedBytes))));
+ }
+
+ public void testEqualsLiteralByteString() {
+ ByteString literal = ByteString.copyFrom(BYTES);
+ assertEquals(CLASSNAME + " must equal LiteralByteString with same value", literal,
+ testString);
+ assertEquals(CLASSNAME + " must equal LiteralByteString with same value", testString,
+ literal);
+ assertFalse(CLASSNAME + " must not equal the empty string",
+ testString.equals(ByteString.EMPTY));
+ assertEquals(CLASSNAME + " empty strings must be equal",
+ ByteString.EMPTY, testString.substring(55, 55));
+
+ literal = ByteString.copyFrom(mungedBytes());
+ assertFalse(CLASSNAME + " must not equal every LiteralByteString with the same length",
+ testString.equals(literal));
+ assertFalse(CLASSNAME + " must not equal every LiteralByteString with the same length",
+ literal.equals(testString));
+ }
+
+ public void testEqualsRopeByteString() {
+ ByteString p1 = ByteString.copyFrom(BYTES, 0, 5);
+ ByteString p2 = ByteString.copyFrom(BYTES, 5, BYTES.length - 5);
+ ByteString rope = p1.concat(p2);
+
+ assertEquals(CLASSNAME + " must equal RopeByteString with same value", rope,
+ testString);
+ assertEquals(CLASSNAME + " must equal RopeByteString with same value", testString,
+ rope);
+ assertFalse(CLASSNAME + " must not equal the empty string",
+ testString.equals(ByteString.EMPTY.concat(ByteString.EMPTY)));
+ assertEquals(CLASSNAME + " empty strings must be equal",
+ ByteString.EMPTY.concat(ByteString.EMPTY), testString.substring(55, 55));
+
+ byte[] mungedBytes = mungedBytes();
+ p1 = ByteString.copyFrom(mungedBytes, 0, 5);
+ p2 = ByteString.copyFrom(mungedBytes, 5, mungedBytes.length - 5);
+ rope = p1.concat(p2);
+ assertFalse(CLASSNAME + " must not equal every RopeByteString with the same length",
+ testString.equals(rope));
+ assertFalse(CLASSNAME + " must not equal every RopeByteString with the same length",
+ rope.equals(testString));
+ }
+
+ private byte[] mungedBytes() {
+ byte[] mungedBytes = new byte[BYTES.length];
+ System.arraycopy(BYTES, 0, mungedBytes, 0, BYTES.length);
+ mungedBytes[mungedBytes.length - 5] = (byte) (mungedBytes[mungedBytes.length - 5] ^ 0xFF);
+ return mungedBytes;
+ }
+
+ public void testHashCode() {
+ int hash = testString.hashCode();
+ assertEquals(CLASSNAME + " must have expected hashCode", EXPECTED_HASH, hash);
+ }
+
+ public void testPeekCachedHashCode() {
+ ByteString newString = new NioByteString(backingBuffer);
+ assertEquals(CLASSNAME + ".peekCachedHashCode() should return zero at first", 0,
+ newString.peekCachedHashCode());
+ newString.hashCode();
+ assertEquals(CLASSNAME + ".peekCachedHashCode should return zero at first",
+ EXPECTED_HASH, newString.peekCachedHashCode());
+ }
+
+ public void testPartialHash() {
+ // partialHash() is more strenuously tested elsewhere by testing hashes of substrings.
+ // This test would fail if the expected hash were 1. It's not.
+ int hash = testString.partialHash(testString.size(), 0, testString.size());
+ assertEquals(CLASSNAME + ".partialHash() must yield expected hashCode",
+ EXPECTED_HASH, hash);
+ }
+
+ public void testNewInput() throws IOException {
+ InputStream input = testString.newInput();
+ assertEquals("InputStream.available() returns correct value",
+ testString.size(), input.available());
+ boolean stillEqual = true;
+ for (byte referenceByte : BYTES) {
+ int expectedInt = (referenceByte & 0xFF);
+ stillEqual = (expectedInt == input.read());
+ }
+ assertEquals("InputStream.available() returns correct value",
+ 0, input.available());
+ assertTrue(CLASSNAME + " must give the same bytes from the InputStream", stillEqual);
+ assertEquals(CLASSNAME + " InputStream must now be exhausted", -1, input.read());
+ }
+
+ public void testNewInput_skip() throws IOException {
+ InputStream input = testString.newInput();
+ int stringSize = testString.size();
+ int nearEndIndex = stringSize * 2 / 3;
+ long skipped1 = input.skip(nearEndIndex);
+ assertEquals("InputStream.skip()", skipped1, nearEndIndex);
+ assertEquals("InputStream.available()",
+ stringSize - skipped1, input.available());
+ assertTrue("InputStream.mark() is available", input.markSupported());
+ input.mark(0);
+ assertEquals("InputStream.skip(), read()",
+ testString.byteAt(nearEndIndex) & 0xFF, input.read());
+ assertEquals("InputStream.available()",
+ stringSize - skipped1 - 1, input.available());
+ long skipped2 = input.skip(stringSize);
+ assertEquals("InputStream.skip() incomplete",
+ skipped2, stringSize - skipped1 - 1);
+ assertEquals("InputStream.skip(), no more input", 0, input.available());
+ assertEquals("InputStream.skip(), no more input", -1, input.read());
+ input.reset();
+ assertEquals("InputStream.reset() succeded",
+ stringSize - skipped1, input.available());
+ assertEquals("InputStream.reset(), read()",
+ testString.byteAt(nearEndIndex) & 0xFF, input.read());
+ }
+
+ public void testNewCodedInput() throws IOException {
+ CodedInputStream cis = testString.newCodedInput();
+ byte[] roundTripBytes = cis.readRawBytes(BYTES.length);
+ assertTrue(CLASSNAME + " must give the same bytes back from the CodedInputStream",
+ Arrays.equals(BYTES, roundTripBytes));
+ assertTrue(CLASSNAME + " CodedInputStream must now be exhausted", cis.isAtEnd());
+ }
+
+ /**
+ * Make sure we keep things simple when concatenating with empty. See also
+ * {@link ByteStringTest#testConcat_empty()}.
+ */
+ public void testConcat_empty() {
+ assertSame(CLASSNAME + " concatenated with empty must give " + CLASSNAME,
+ testString.concat(EMPTY), testString);
+ assertSame("empty concatenated with " + CLASSNAME + " must give " + CLASSNAME,
+ EMPTY.concat(testString), testString);
+ }
+
+ public void testJavaSerialization() throws Exception {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(out);
+ oos.writeObject(testString);
+ oos.close();
+ byte[] pickled = out.toByteArray();
+ InputStream in = new ByteArrayInputStream(pickled);
+ ObjectInputStream ois = new ObjectInputStream(in);
+ Object o = ois.readObject();
+ assertTrue("Didn't get a ByteString back", o instanceof ByteString);
+ assertEquals("Should get an equal ByteString back", testString, o);
+ }
+
+ private static ByteString forString(String str) {
+ return new NioByteString(ByteBuffer.wrap(str.getBytes(UTF_8)));
+ }
+}
diff --git a/java/core/src/test/java/com/google/protobuf/ParseExceptionsTest.java b/java/core/src/test/java/com/google/protobuf/ParseExceptionsTest.java
new file mode 100644
index 00000000..bf1f1d71
--- /dev/null
+++ b/java/core/src/test/java/com/google/protobuf/ParseExceptionsTest.java
@@ -0,0 +1,273 @@
+// 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.
+
+package com.google.protobuf;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import com.google.protobuf.DescriptorProtos.DescriptorProto;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Tests the exceptions thrown when parsing from a stream. The methods on the {@link Parser}
+ * interface are specified to only throw {@link InvalidProtocolBufferException}. But we really want
+ * to distinguish between invalid protos vs. actual I/O errors (like failures reading from a
+ * socket, etc.). So, when we're not using the parser directly, an {@link IOException} should be
+ * thrown where appropriate, instead of always an {@link InvalidProtocolBufferException}.
+ *
+ * @author jh@squareup.com (Joshua Humphries)
+ */
+@RunWith(JUnit4.class)
+public class ParseExceptionsTest {
+
+ private interface ParseTester {
+ DescriptorProto parse(InputStream in) throws IOException;
+ }
+
+ private byte serializedProto[];
+
+ private void setup() {
+ serializedProto = DescriptorProto.getDescriptor().toProto().toByteArray();
+ }
+
+ private void setupDelimited() {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ try {
+ DescriptorProto.getDescriptor().toProto().writeDelimitedTo(bos);
+ } catch (IOException e) {
+ fail("Exception not expected: " + e);
+ }
+ serializedProto = bos.toByteArray();
+ }
+
+ @Test public void message_parseFrom_InputStream() {
+ setup();
+ verifyExceptions(
+ new ParseTester() {
+ @Override
+ public DescriptorProto parse(InputStream in) throws IOException {
+ return DescriptorProto.parseFrom(in);
+ }
+ });
+ }
+
+ @Test public void message_parseFrom_InputStreamAndExtensionRegistry() {
+ setup();
+ verifyExceptions(
+ new ParseTester() {
+ @Override
+ public DescriptorProto parse(InputStream in) throws IOException {
+ return DescriptorProto.parseFrom(in, ExtensionRegistry.newInstance());
+ }
+ });
+ }
+
+ @Test public void message_parseFrom_CodedInputStream() {
+ setup();
+ verifyExceptions(
+ new ParseTester() {
+ @Override
+ public DescriptorProto parse(InputStream in) throws IOException {
+ return DescriptorProto.parseFrom(CodedInputStream.newInstance(in));
+ }
+ });
+ }
+
+ @Test public void message_parseFrom_CodedInputStreamAndExtensionRegistry() {
+ setup();
+ verifyExceptions(
+ new ParseTester() {
+ @Override
+ public DescriptorProto parse(InputStream in) throws IOException {
+ return DescriptorProto.parseFrom(
+ CodedInputStream.newInstance(in), ExtensionRegistry.newInstance());
+ }
+ });
+ }
+
+ @Test public void message_parseDelimitedFrom_InputStream() {
+ setupDelimited();
+ verifyExceptions(
+ new ParseTester() {
+ @Override
+ public DescriptorProto parse(InputStream in) throws IOException {
+ return DescriptorProto.parseDelimitedFrom(in);
+ }
+ });
+ }
+
+ @Test public void message_parseDelimitedFrom_InputStreamAndExtensionRegistry() {
+ setupDelimited();
+ verifyExceptions(
+ new ParseTester() {
+ @Override
+ public DescriptorProto parse(InputStream in) throws IOException {
+ return DescriptorProto.parseDelimitedFrom(in, ExtensionRegistry.newInstance());
+ }
+ });
+ }
+
+ @Test public void messageBuilder_mergeFrom_InputStream() {
+ setup();
+ verifyExceptions(
+ new ParseTester() {
+ @Override
+ public DescriptorProto parse(InputStream in) throws IOException {
+ return DescriptorProto.newBuilder().mergeFrom(in).build();
+ }
+ });
+ }
+
+ @Test public void messageBuilder_mergeFrom_InputStreamAndExtensionRegistry() {
+ setup();
+ verifyExceptions(
+ new ParseTester() {
+ @Override
+ public DescriptorProto parse(InputStream in) throws IOException {
+ return DescriptorProto.newBuilder()
+ .mergeFrom(in, ExtensionRegistry.newInstance())
+ .build();
+ }
+ });
+ }
+
+ @Test public void messageBuilder_mergeFrom_CodedInputStream() {
+ setup();
+ verifyExceptions(
+ new ParseTester() {
+ @Override
+ public DescriptorProto parse(InputStream in) throws IOException {
+ return DescriptorProto.newBuilder().mergeFrom(CodedInputStream.newInstance(in)).build();
+ }
+ });
+ }
+
+ @Test public void messageBuilder_mergeFrom_CodedInputStreamAndExtensionRegistry() {
+ setup();
+ verifyExceptions(
+ new ParseTester() {
+ @Override
+ public DescriptorProto parse(InputStream in) throws IOException {
+ return DescriptorProto.newBuilder()
+ .mergeFrom(CodedInputStream.newInstance(in), ExtensionRegistry.newInstance())
+ .build();
+ }
+ });
+ }
+
+ @Test public void messageBuilder_mergeDelimitedFrom_InputStream() {
+ setupDelimited();
+ verifyExceptions(
+ new ParseTester() {
+ @Override
+ public DescriptorProto parse(InputStream in) throws IOException {
+ DescriptorProto.Builder builder = DescriptorProto.newBuilder();
+ builder.mergeDelimitedFrom(in);
+ return builder.build();
+ }
+ });
+ }
+
+ @Test public void messageBuilder_mergeDelimitedFrom_InputStreamAndExtensionRegistry() {
+ setupDelimited();
+ verifyExceptions(
+ new ParseTester() {
+ @Override
+ public DescriptorProto parse(InputStream in) throws IOException {
+ DescriptorProto.Builder builder = DescriptorProto.newBuilder();
+ builder.mergeDelimitedFrom(in, ExtensionRegistry.newInstance());
+ return builder.build();
+ }
+ });
+ }
+
+ private void verifyExceptions(ParseTester parseTester) {
+ // No exception
+ try {
+ assertEquals(DescriptorProto.getDescriptor().toProto(),
+ parseTester.parse(new ByteArrayInputStream(serializedProto)));
+ } catch (IOException e) {
+ fail("No exception expected: " + e);
+ }
+
+ // IOException
+ try {
+ // using a "broken" stream that will throw part-way through reading the message
+ parseTester.parse(broken(new ByteArrayInputStream(serializedProto)));
+ fail("IOException expected but not thrown");
+ } catch (IOException e) {
+ assertFalse(e instanceof InvalidProtocolBufferException);
+ }
+
+ // InvalidProtocolBufferException
+ try {
+ // make the serialized proto invalid
+ for (int i = 0; i < 50; i++) {
+ serializedProto[i] = -1;
+ }
+ parseTester.parse(new ByteArrayInputStream(serializedProto));
+ fail("InvalidProtocolBufferException expected but not thrown");
+ } catch (IOException e) {
+ assertTrue(e instanceof InvalidProtocolBufferException);
+ }
+ }
+
+ private InputStream broken(InputStream i) {
+ return new FilterInputStream(i) {
+ int count = 0;
+
+ @Override public int read() throws IOException {
+ if (count++ >= 50) {
+ throw new IOException("I'm broken!");
+ }
+ return super.read();
+ }
+
+ @Override public int read(byte b[], int off, int len) throws IOException {
+ if ((count += len) >= 50) {
+ throw new IOException("I'm broken!");
+ }
+ return super.read(b, off, len);
+ }
+ };
+ }
+}
diff --git a/java/src/test/java/com/google/protobuf/ParserTest.java b/java/core/src/test/java/com/google/protobuf/ParserTest.java
index 5a92bacf..30842d2c 100644
--- a/java/src/test/java/com/google/protobuf/ParserTest.java
+++ b/java/core/src/test/java/com/google/protobuf/ParserTest.java
@@ -33,15 +33,15 @@ package com.google.protobuf;
import com.google.protobuf.UnittestLite.TestAllTypesLite;
import com.google.protobuf.UnittestLite.TestPackedExtensionsLite;
import com.google.protobuf.UnittestLite.TestParsingMergeLite;
+import protobuf_unittest.UnittestOptimizeFor;
import protobuf_unittest.UnittestOptimizeFor.TestOptimizedForSize;
import protobuf_unittest.UnittestOptimizeFor.TestRequiredOptimizedForSize;
-import protobuf_unittest.UnittestOptimizeFor;
+import protobuf_unittest.UnittestProto;
import protobuf_unittest.UnittestProto.ForeignMessage;
import protobuf_unittest.UnittestProto.TestAllTypes;
import protobuf_unittest.UnittestProto.TestEmptyMessage;
import protobuf_unittest.UnittestProto.TestParsingMerge;
import protobuf_unittest.UnittestProto.TestRequired;
-import protobuf_unittest.UnittestProto;
import junit.framework.TestCase;
@@ -179,16 +179,16 @@ public class ParserTest extends TestCase {
public void testParseExtensions() throws Exception {
assertRoundTripEquals(TestUtil.getAllExtensionsSet(),
TestUtil.getExtensionRegistry());
- assertRoundTripEquals(TestUtil.getAllLiteExtensionsSet(),
- TestUtil.getExtensionRegistryLite());
+ assertRoundTripEquals(
+ TestUtilLite.getAllLiteExtensionsSet(), TestUtilLite.getExtensionRegistryLite());
}
public void testParsePacked() throws Exception {
assertRoundTripEquals(TestUtil.getPackedSet());
assertRoundTripEquals(TestUtil.getPackedExtensionsSet(),
TestUtil.getExtensionRegistry());
- assertRoundTripEquals(TestUtil.getLitePackedExtensionsSet(),
- TestUtil.getExtensionRegistryLite());
+ assertRoundTripEquals(
+ TestUtilLite.getLitePackedExtensionsSet(), TestUtilLite.getExtensionRegistryLite());
}
public void testParseDelimitedTo() throws Exception {
@@ -198,8 +198,7 @@ public class ParserTest extends TestCase {
normalMessage.writeDelimitedTo(output);
// Write MessageLite with packed extension fields.
- TestPackedExtensionsLite packedMessage =
- TestUtil.getLitePackedExtensionsSet();
+ TestPackedExtensionsLite packedMessage = TestUtilLite.getLitePackedExtensionsSet();
packedMessage.writeDelimitedTo(output);
InputStream input = new ByteArrayInputStream(output.toByteArray());
@@ -208,8 +207,9 @@ public class ParserTest extends TestCase {
normalMessage.getParserForType().parseDelimitedFrom(input));
assertMessageEquals(
packedMessage,
- packedMessage.getParserForType().parseDelimitedFrom(
- input, TestUtil.getExtensionRegistryLite()));
+ packedMessage
+ .getParserForType()
+ .parseDelimitedFrom(input, TestUtilLite.getExtensionRegistryLite()));
}
public void testParseUnknownFields() throws Exception {
diff --git a/java/src/test/java/com/google/protobuf/ProtobufArrayListTest.java b/java/core/src/test/java/com/google/protobuf/ProtobufArrayListTest.java
index f9f5e9c7..3f45e226 100644
--- a/java/src/test/java/com/google/protobuf/ProtobufArrayListTest.java
+++ b/java/core/src/test/java/com/google/protobuf/ProtobufArrayListTest.java
@@ -63,20 +63,6 @@ public class ProtobufArrayListTest extends TestCase {
assertImmutable(ProtobufArrayList.<Integer>emptyList());
}
- public void testCopyConstructor() {
- ProtobufArrayList<Integer> copy = new ProtobufArrayList<Integer>(TERTIARY_LIST);
- assertEquals(TERTIARY_LIST, copy);
-
- copy = new ProtobufArrayList<Integer>(IntArrayList.emptyList());
- assertEquals(ProtobufArrayList.emptyList(), copy);
-
- copy = new ProtobufArrayList<Integer>(asList(1, 2, 3));
- assertEquals(asList(1, 2, 3), copy);
-
- copy = new ProtobufArrayList<Integer>(Collections.<Integer>emptyList());
- assertEquals(ProtobufArrayList.emptyList(), copy);
- }
-
public void testModificationWithIteration() {
list.addAll(asList(1, 2, 3, 4));
Iterator<Integer> iterator = list.iterator();
@@ -243,7 +229,7 @@ public class ProtobufArrayListTest extends TestCase {
}
try {
- list.removeAll(Collections.<Double>emptyList());
+ list.removeAll(Collections.emptyList());
fail();
} catch (UnsupportedOperationException e) {
// expected
@@ -264,7 +250,7 @@ public class ProtobufArrayListTest extends TestCase {
}
try {
- list.retainAll(Collections.<Double>emptyList());
+ list.retainAll(Collections.emptyList());
fail();
} catch (UnsupportedOperationException e) {
// expected
diff --git a/java/src/test/java/com/google/protobuf/RepeatedFieldBuilderTest.java b/java/core/src/test/java/com/google/protobuf/RepeatedFieldBuilderV3Test.java
index 49d52321..241a4354 100644
--- a/java/src/test/java/com/google/protobuf/RepeatedFieldBuilderTest.java
+++ b/java/core/src/test/java/com/google/protobuf/RepeatedFieldBuilderV3Test.java
@@ -39,18 +39,18 @@ import java.util.Collections;
import java.util.List;
/**
- * Tests for {@link RepeatedFieldBuilder}. This tests basic functionality.
+ * Tests for {@link RepeatedFieldBuilderV3}. This tests basic functionality.
* More extensive testing is provided via other tests that exercise the
* builder.
*
* @author jonp@google.com (Jon Perlow)
*/
-public class RepeatedFieldBuilderTest extends TestCase {
+public class RepeatedFieldBuilderV3Test extends TestCase {
public void testBasicUse() {
TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent();
- RepeatedFieldBuilder<TestAllTypes, TestAllTypes.Builder,
- TestAllTypesOrBuilder> builder = newRepeatedFieldBuilder(mockParent);
+ RepeatedFieldBuilderV3<TestAllTypes, TestAllTypes.Builder,
+ TestAllTypesOrBuilder> builder = newRepeatedFieldBuilderV3(mockParent);
builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(0).build());
builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(1).build());
assertEquals(0, builder.getMessage(0).getOptionalInt32());
@@ -70,8 +70,8 @@ public class RepeatedFieldBuilderTest extends TestCase {
public void testGoingBackAndForth() {
TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent();
- RepeatedFieldBuilder<TestAllTypes, TestAllTypes.Builder,
- TestAllTypesOrBuilder> builder = newRepeatedFieldBuilder(mockParent);
+ RepeatedFieldBuilderV3<TestAllTypes, TestAllTypes.Builder,
+ TestAllTypesOrBuilder> builder = newRepeatedFieldBuilderV3(mockParent);
builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(0).build());
builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(1).build());
assertEquals(0, builder.getMessage(0).getOptionalInt32());
@@ -99,8 +99,8 @@ public class RepeatedFieldBuilderTest extends TestCase {
public void testVariousMethods() {
TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent();
- RepeatedFieldBuilder<TestAllTypes, TestAllTypes.Builder,
- TestAllTypesOrBuilder> builder = newRepeatedFieldBuilder(mockParent);
+ RepeatedFieldBuilderV3<TestAllTypes, TestAllTypes.Builder,
+ TestAllTypesOrBuilder> builder = newRepeatedFieldBuilderV3(mockParent);
builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(1).build());
builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(2).build());
builder.addBuilder(0, TestAllTypes.getDefaultInstance())
@@ -141,8 +141,8 @@ public class RepeatedFieldBuilderTest extends TestCase {
public void testLists() {
TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent();
- RepeatedFieldBuilder<TestAllTypes, TestAllTypes.Builder,
- TestAllTypesOrBuilder> builder = newRepeatedFieldBuilder(mockParent);
+ RepeatedFieldBuilderV3<TestAllTypes, TestAllTypes.Builder,
+ TestAllTypesOrBuilder> builder = newRepeatedFieldBuilderV3(mockParent);
builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(1).build());
builder.addMessage(0,
TestAllTypes.newBuilder().setOptionalInt32(0).build());
@@ -180,10 +180,10 @@ public class RepeatedFieldBuilderTest extends TestCase {
}
}
- private RepeatedFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+ private RepeatedFieldBuilderV3<TestAllTypes, TestAllTypes.Builder,
TestAllTypesOrBuilder>
- newRepeatedFieldBuilder(GeneratedMessage.BuilderParent parent) {
- return new RepeatedFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+ newRepeatedFieldBuilderV3(GeneratedMessage.BuilderParent parent) {
+ return new RepeatedFieldBuilderV3<TestAllTypes, TestAllTypes.Builder,
TestAllTypesOrBuilder>(Collections.<TestAllTypes>emptyList(), false,
parent, false);
}
diff --git a/java/src/test/java/com/google/protobuf/RopeByteStringSubstringTest.java b/java/core/src/test/java/com/google/protobuf/RopeByteStringSubstringTest.java
index cc385599..dc56f2e9 100644
--- a/java/src/test/java/com/google/protobuf/RopeByteStringSubstringTest.java
+++ b/java/core/src/test/java/com/google/protobuf/RopeByteStringSubstringTest.java
@@ -96,7 +96,7 @@ public class RopeByteStringSubstringTest extends LiteralByteStringTest {
}
@Override
- public void testCharsetToString() throws UnsupportedEncodingException {
+ public void testCharsetToString() {
String sourceString = "I love unicode \u1234\u5678 characters";
ByteString sourceByteString = ByteString.copyFromUtf8(sourceString);
int copies = 250;
diff --git a/java/src/test/java/com/google/protobuf/RopeByteStringTest.java b/java/core/src/test/java/com/google/protobuf/RopeByteStringTest.java
index 4ec3a409..4ec3a409 100644
--- a/java/src/test/java/com/google/protobuf/RopeByteStringTest.java
+++ b/java/core/src/test/java/com/google/protobuf/RopeByteStringTest.java
diff --git a/java/core/src/test/java/com/google/protobuf/ServiceTest.java b/java/core/src/test/java/com/google/protobuf/ServiceTest.java
new file mode 100644
index 00000000..b902737d
--- /dev/null
+++ b/java/core/src/test/java/com/google/protobuf/ServiceTest.java
@@ -0,0 +1,326 @@
+// 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.
+
+package com.google.protobuf;
+
+import com.google.protobuf.Descriptors.FileDescriptor;
+import com.google.protobuf.Descriptors.MethodDescriptor;
+import google.protobuf.no_generic_services_test.UnittestNoGenericServices;
+import protobuf_unittest.MessageWithNoOuter;
+import protobuf_unittest.ServiceWithNoOuter;
+import protobuf_unittest.UnittestProto.BarRequest;
+import protobuf_unittest.UnittestProto.BarResponse;
+import protobuf_unittest.UnittestProto.FooRequest;
+import protobuf_unittest.UnittestProto.FooResponse;
+import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestService;
+
+import junit.framework.TestCase;
+
+import org.easymock.classextension.EasyMock;
+import org.easymock.IArgumentMatcher;
+import org.easymock.classextension.IMocksControl;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Tests services and stubs.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public class ServiceTest extends TestCase {
+ private IMocksControl control;
+ private RpcController mockController;
+
+ private final Descriptors.MethodDescriptor fooDescriptor =
+ TestService.getDescriptor().getMethods().get(0);
+ private final Descriptors.MethodDescriptor barDescriptor =
+ TestService.getDescriptor().getMethods().get(1);
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ control = EasyMock.createStrictControl();
+ mockController = control.createMock(RpcController.class);
+ }
+
+ // =================================================================
+
+ /** Tests Service.callMethod(). */
+ public void testCallMethod() throws Exception {
+ FooRequest fooRequest = FooRequest.newBuilder().build();
+ BarRequest barRequest = BarRequest.newBuilder().build();
+ MockCallback<Message> fooCallback = new MockCallback<Message>();
+ MockCallback<Message> barCallback = new MockCallback<Message>();
+ TestService mockService = control.createMock(TestService.class);
+
+ mockService.foo(EasyMock.same(mockController), EasyMock.same(fooRequest),
+ this.<FooResponse>wrapsCallback(fooCallback));
+ mockService.bar(EasyMock.same(mockController), EasyMock.same(barRequest),
+ this.<BarResponse>wrapsCallback(barCallback));
+ control.replay();
+
+ mockService.callMethod(fooDescriptor, mockController,
+ fooRequest, fooCallback);
+ mockService.callMethod(barDescriptor, mockController,
+ barRequest, barCallback);
+ control.verify();
+ }
+
+ /** Tests Service.get{Request,Response}Prototype(). */
+ public void testGetPrototype() throws Exception {
+ TestService mockService = control.createMock(TestService.class);
+
+ assertSame(mockService.getRequestPrototype(fooDescriptor),
+ FooRequest.getDefaultInstance());
+ assertSame(mockService.getResponsePrototype(fooDescriptor),
+ FooResponse.getDefaultInstance());
+ assertSame(mockService.getRequestPrototype(barDescriptor),
+ BarRequest.getDefaultInstance());
+ assertSame(mockService.getResponsePrototype(barDescriptor),
+ BarResponse.getDefaultInstance());
+ }
+
+ /** Tests generated stubs. */
+ public void testStub() throws Exception {
+ FooRequest fooRequest = FooRequest.newBuilder().build();
+ BarRequest barRequest = BarRequest.newBuilder().build();
+ MockCallback<FooResponse> fooCallback = new MockCallback<FooResponse>();
+ MockCallback<BarResponse> barCallback = new MockCallback<BarResponse>();
+ RpcChannel mockChannel = control.createMock(RpcChannel.class);
+ TestService stub = TestService.newStub(mockChannel);
+
+ mockChannel.callMethod(
+ EasyMock.same(fooDescriptor),
+ EasyMock.same(mockController),
+ EasyMock.same(fooRequest),
+ EasyMock.same(FooResponse.getDefaultInstance()),
+ this.<Message>wrapsCallback(fooCallback));
+ mockChannel.callMethod(
+ EasyMock.same(barDescriptor),
+ EasyMock.same(mockController),
+ EasyMock.same(barRequest),
+ EasyMock.same(BarResponse.getDefaultInstance()),
+ this.<Message>wrapsCallback(barCallback));
+ control.replay();
+
+ stub.foo(mockController, fooRequest, fooCallback);
+ stub.bar(mockController, barRequest, barCallback);
+ control.verify();
+ }
+
+ /** Tests generated blocking stubs. */
+ public void testBlockingStub() throws Exception {
+ FooRequest fooRequest = FooRequest.newBuilder().build();
+ BarRequest barRequest = BarRequest.newBuilder().build();
+ BlockingRpcChannel mockChannel =
+ control.createMock(BlockingRpcChannel.class);
+ TestService.BlockingInterface stub =
+ TestService.newBlockingStub(mockChannel);
+
+ FooResponse fooResponse = FooResponse.newBuilder().build();
+ BarResponse barResponse = BarResponse.newBuilder().build();
+
+ EasyMock.expect(mockChannel.callBlockingMethod(
+ EasyMock.same(fooDescriptor),
+ EasyMock.same(mockController),
+ EasyMock.same(fooRequest),
+ EasyMock.same(FooResponse.getDefaultInstance()))).andReturn(fooResponse);
+ EasyMock.expect(mockChannel.callBlockingMethod(
+ EasyMock.same(barDescriptor),
+ EasyMock.same(mockController),
+ EasyMock.same(barRequest),
+ EasyMock.same(BarResponse.getDefaultInstance()))).andReturn(barResponse);
+ control.replay();
+
+ assertSame(fooResponse, stub.foo(mockController, fooRequest));
+ assertSame(barResponse, stub.bar(mockController, barRequest));
+ control.verify();
+ }
+
+ public void testNewReflectiveService() {
+ ServiceWithNoOuter.Interface impl =
+ control.createMock(ServiceWithNoOuter.Interface.class);
+ RpcController controller = control.createMock(RpcController.class);
+ Service service = ServiceWithNoOuter.newReflectiveService(impl);
+
+ MethodDescriptor fooMethod =
+ ServiceWithNoOuter.getDescriptor().findMethodByName("Foo");
+ MessageWithNoOuter request = MessageWithNoOuter.getDefaultInstance();
+ RpcCallback<Message> callback =
+ new RpcCallback<Message>() {
+ @Override
+ public void run(Message parameter) {
+ // No reason this should be run.
+ fail();
+ }
+ };
+ RpcCallback<TestAllTypes> specializedCallback =
+ RpcUtil.specializeCallback(callback);
+
+ impl.foo(EasyMock.same(controller), EasyMock.same(request),
+ EasyMock.same(specializedCallback));
+ EasyMock.expectLastCall();
+
+ control.replay();
+
+ service.callMethod(fooMethod, controller, request, callback);
+
+ control.verify();
+ }
+
+ public void testNewReflectiveBlockingService() throws ServiceException {
+ ServiceWithNoOuter.BlockingInterface impl =
+ control.createMock(ServiceWithNoOuter.BlockingInterface.class);
+ RpcController controller = control.createMock(RpcController.class);
+ BlockingService service =
+ ServiceWithNoOuter.newReflectiveBlockingService(impl);
+
+ MethodDescriptor fooMethod =
+ ServiceWithNoOuter.getDescriptor().findMethodByName("Foo");
+ MessageWithNoOuter request = MessageWithNoOuter.getDefaultInstance();
+
+ TestAllTypes expectedResponse = TestAllTypes.getDefaultInstance();
+ EasyMock.expect(impl.foo(EasyMock.same(controller), EasyMock.same(request)))
+ .andReturn(expectedResponse);
+
+ control.replay();
+
+ Message response =
+ service.callBlockingMethod(fooMethod, controller, request);
+ assertEquals(expectedResponse, response);
+
+ control.verify();
+ }
+
+ public void testNoGenericServices() throws Exception {
+ // Non-services should be usable.
+ UnittestNoGenericServices.TestMessage message =
+ UnittestNoGenericServices.TestMessage.newBuilder()
+ .setA(123)
+ .setExtension(UnittestNoGenericServices.testExtension, 456)
+ .build();
+ assertEquals(123, message.getA());
+ assertEquals(1, UnittestNoGenericServices.TestEnum.FOO.getNumber());
+
+ // Build a list of the class names nested in UnittestNoGenericServices.
+ String outerName = "google.protobuf.no_generic_services_test." +
+ "UnittestNoGenericServices";
+ Class<?> outerClass = Class.forName(outerName);
+
+ Set<String> innerClassNames = new HashSet<String>();
+ for (Class<?> innerClass : outerClass.getClasses()) {
+ String fullName = innerClass.getName();
+ // Figure out the unqualified name of the inner class.
+ // Note: Surprisingly, the full name of an inner class will be separated
+ // from the outer class name by a '$' rather than a '.'. This is not
+ // mentioned in the documentation for java.lang.Class. I don't want to
+ // make assumptions, so I'm just going to accept any character as the
+ // separator.
+ assertTrue(fullName.startsWith(outerName));
+
+ if (!Service.class.isAssignableFrom(innerClass) &&
+ !Message.class.isAssignableFrom(innerClass) &&
+ !ProtocolMessageEnum.class.isAssignableFrom(innerClass)) {
+ // Ignore any classes not generated by the base code generator.
+ continue;
+ }
+
+ innerClassNames.add(fullName.substring(outerName.length() + 1));
+ }
+
+ // No service class should have been generated.
+ assertTrue(innerClassNames.contains("TestMessage"));
+ assertTrue(innerClassNames.contains("TestEnum"));
+ assertFalse(innerClassNames.contains("TestService"));
+
+ // But descriptors are there.
+ FileDescriptor file = UnittestNoGenericServices.getDescriptor();
+ assertEquals(1, file.getServices().size());
+ assertEquals("TestService", file.getServices().get(0).getName());
+ assertEquals(1, file.getServices().get(0).getMethods().size());
+ assertEquals("Foo",
+ file.getServices().get(0).getMethods().get(0).getName());
+ }
+
+ // =================================================================
+
+ /**
+ * wrapsCallback() is an EasyMock argument predicate. wrapsCallback(c)
+ * matches a callback if calling that callback causes c to be called.
+ * In other words, c wraps the given callback.
+ */
+ private <Type extends Message> RpcCallback<Type> wrapsCallback(
+ MockCallback<?> callback) {
+ EasyMock.reportMatcher(new WrapsCallback(callback));
+ return null;
+ }
+
+ /** The parameter to wrapsCallback() must be a MockCallback. */
+ private static class MockCallback<Type extends Message>
+ implements RpcCallback<Type> {
+ private boolean called = false;
+
+ public boolean isCalled() { return called; }
+
+ public void reset() { called = false; }
+ @Override
+ public void run(Type message) {
+ called = true; }
+ }
+
+ /** Implementation of the wrapsCallback() argument matcher. */
+ private static class WrapsCallback implements IArgumentMatcher {
+ private MockCallback<?> callback;
+
+ public WrapsCallback(MockCallback<?> callback) {
+ this.callback = callback;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public boolean matches(Object actual) {
+ if (!(actual instanceof RpcCallback)) {
+ return false;
+ }
+ RpcCallback actualCallback = (RpcCallback)actual;
+
+ callback.reset();
+ actualCallback.run(null);
+ return callback.isCalled();
+ }
+
+ @Override
+ public void appendTo(StringBuffer buffer) {
+ buffer.append("wrapsCallback(mockCallback)");
+ }
+ }
+}
diff --git a/java/src/test/java/com/google/protobuf/SingleFieldBuilderTest.java b/java/core/src/test/java/com/google/protobuf/SingleFieldBuilderV3Test.java
index 58b80007..e3a8d4f4 100644
--- a/java/src/test/java/com/google/protobuf/SingleFieldBuilderTest.java
+++ b/java/core/src/test/java/com/google/protobuf/SingleFieldBuilderV3Test.java
@@ -36,19 +36,19 @@ import protobuf_unittest.UnittestProto.TestAllTypesOrBuilder;
import junit.framework.TestCase;
/**
- * Tests for {@link SingleFieldBuilder}. This tests basic functionality.
+ * Tests for {@link SingleFieldBuilderV3}. This tests basic functionality.
* More extensive testing is provided via other tests that exercise the
* builder.
*
* @author jonp@google.com (Jon Perlow)
*/
-public class SingleFieldBuilderTest extends TestCase {
+public class SingleFieldBuilderV3Test extends TestCase {
public void testBasicUseAndInvalidations() {
TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent();
- SingleFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+ SingleFieldBuilderV3<TestAllTypes, TestAllTypes.Builder,
TestAllTypesOrBuilder> builder =
- new SingleFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+ new SingleFieldBuilderV3<TestAllTypes, TestAllTypes.Builder,
TestAllTypesOrBuilder>(
TestAllTypes.getDefaultInstance(),
mockParent,
@@ -76,9 +76,9 @@ public class SingleFieldBuilderTest extends TestCase {
public void testSetMessage() {
TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent();
- SingleFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+ SingleFieldBuilderV3<TestAllTypes, TestAllTypes.Builder,
TestAllTypesOrBuilder> builder =
- new SingleFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+ new SingleFieldBuilderV3<TestAllTypes, TestAllTypes.Builder,
TestAllTypesOrBuilder>(
TestAllTypes.getDefaultInstance(),
mockParent,
@@ -102,9 +102,9 @@ public class SingleFieldBuilderTest extends TestCase {
public void testClear() {
TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent();
- SingleFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+ SingleFieldBuilderV3<TestAllTypes, TestAllTypes.Builder,
TestAllTypesOrBuilder> builder =
- new SingleFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+ new SingleFieldBuilderV3<TestAllTypes, TestAllTypes.Builder,
TestAllTypesOrBuilder>(
TestAllTypes.getDefaultInstance(),
mockParent,
@@ -122,9 +122,9 @@ public class SingleFieldBuilderTest extends TestCase {
public void testMerge() {
TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent();
- SingleFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+ SingleFieldBuilderV3<TestAllTypes, TestAllTypes.Builder,
TestAllTypesOrBuilder> builder =
- new SingleFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+ new SingleFieldBuilderV3<TestAllTypes, TestAllTypes.Builder,
TestAllTypesOrBuilder>(
TestAllTypes.getDefaultInstance(),
mockParent,
diff --git a/java/src/test/java/com/google/protobuf/SmallSortedMapTest.java b/java/core/src/test/java/com/google/protobuf/SmallSortedMapTest.java
index 366086d3..e96ecd65 100644
--- a/java/src/test/java/com/google/protobuf/SmallSortedMapTest.java
+++ b/java/core/src/test/java/com/google/protobuf/SmallSortedMapTest.java
@@ -56,14 +56,17 @@ public class SmallSortedMapTest extends TestCase {
this.value = value;
}
+ @Override
public K getKey() {
return key;
}
+ @Override
public V getValue() {
return value;
}
+ @Override
public V setValue(V value) {
V oldValue = this.value;
this.value = value;
diff --git a/java/src/test/java/com/google/protobuf/TestBadIdentifiers.java b/java/core/src/test/java/com/google/protobuf/TestBadIdentifiers.java
index 2c60fe0e..2c60fe0e 100644
--- a/java/src/test/java/com/google/protobuf/TestBadIdentifiers.java
+++ b/java/core/src/test/java/com/google/protobuf/TestBadIdentifiers.java
diff --git a/java/src/test/java/com/google/protobuf/TestUtil.java b/java/core/src/test/java/com/google/protobuf/TestUtil.java
index 792e8665..d94f99e3 100644
--- a/java/src/test/java/com/google/protobuf/TestUtil.java
+++ b/java/core/src/test/java/com/google/protobuf/TestUtil.java
@@ -30,205 +30,200 @@
package com.google.protobuf;
-import protobuf_unittest.UnittestProto;
-import com.google.protobuf.UnittestLite;
-
+import static com.google.protobuf.UnittestLite.defaultBoolExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultBytesExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultCordExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultDoubleExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultFixed32ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultFixed64ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultFloatExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultForeignEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultImportEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultInt32ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultInt64ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultNestedEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultSfixed32ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultSfixed64ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultSint32ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultSint64ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultStringExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultStringPieceExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultUint32ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultUint64ExtensionLite;
+import static com.google.protobuf.UnittestLite.oneofBytesExtensionLite;
+import static com.google.protobuf.UnittestLite.oneofNestedMessageExtensionLite;
+import static com.google.protobuf.UnittestLite.oneofStringExtensionLite;
+import static com.google.protobuf.UnittestLite.oneofUint32ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalBoolExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalBytesExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalCordExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalDoubleExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalFixed32ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalFixed64ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalFloatExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalForeignEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalForeignMessageExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalGroupExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalImportEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalImportMessageExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalInt32ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalInt64ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalLazyMessageExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalNestedEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalNestedMessageExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalPublicImportMessageExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalSfixed32ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalSfixed64ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalSint32ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalSint64ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalStringExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalStringPieceExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalUint32ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalUint64ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedBoolExtensionLite;
+import static com.google.protobuf.UnittestLite.packedDoubleExtensionLite;
+import static com.google.protobuf.UnittestLite.packedEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.packedFixed32ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedFixed64ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedFloatExtensionLite;
+import static com.google.protobuf.UnittestLite.packedInt32ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedInt64ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedSfixed32ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedSfixed64ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedSint32ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedSint64ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedUint32ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedUint64ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedBoolExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedBytesExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedCordExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedDoubleExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedFixed32ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedFixed64ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedFloatExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedForeignEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedForeignMessageExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedGroupExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedImportEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedImportMessageExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedInt32ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedInt64ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedLazyMessageExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedNestedEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedNestedMessageExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedSfixed32ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedSfixed64ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedSint32ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedSint64ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedStringExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedStringPieceExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedUint32ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedUint64ExtensionLite;
+import static protobuf_unittest.UnittestProto.OptionalGroup_extension;
+import static protobuf_unittest.UnittestProto.RepeatedGroup_extension;
+import static protobuf_unittest.UnittestProto.defaultBoolExtension;
+import static protobuf_unittest.UnittestProto.defaultBytesExtension;
+import static protobuf_unittest.UnittestProto.defaultCordExtension;
+import static protobuf_unittest.UnittestProto.defaultDoubleExtension;
+import static protobuf_unittest.UnittestProto.defaultFixed32Extension;
+import static protobuf_unittest.UnittestProto.defaultFixed64Extension;
+import static protobuf_unittest.UnittestProto.defaultFloatExtension;
+import static protobuf_unittest.UnittestProto.defaultForeignEnumExtension;
+import static protobuf_unittest.UnittestProto.defaultImportEnumExtension;
// The static imports are to avoid 100+ char lines. The following is roughly equivalent to
// import static protobuf_unittest.UnittestProto.*;
import static protobuf_unittest.UnittestProto.defaultInt32Extension;
import static protobuf_unittest.UnittestProto.defaultInt64Extension;
-import static protobuf_unittest.UnittestProto.defaultUint32Extension;
-import static protobuf_unittest.UnittestProto.defaultUint64Extension;
-import static protobuf_unittest.UnittestProto.defaultSint32Extension;
-import static protobuf_unittest.UnittestProto.defaultSint64Extension;
-import static protobuf_unittest.UnittestProto.defaultFixed32Extension;
-import static protobuf_unittest.UnittestProto.defaultFixed64Extension;
+import static protobuf_unittest.UnittestProto.defaultNestedEnumExtension;
import static protobuf_unittest.UnittestProto.defaultSfixed32Extension;
import static protobuf_unittest.UnittestProto.defaultSfixed64Extension;
-import static protobuf_unittest.UnittestProto.defaultFloatExtension;
-import static protobuf_unittest.UnittestProto.defaultDoubleExtension;
-import static protobuf_unittest.UnittestProto.defaultBoolExtension;
+import static protobuf_unittest.UnittestProto.defaultSint32Extension;
+import static protobuf_unittest.UnittestProto.defaultSint64Extension;
import static protobuf_unittest.UnittestProto.defaultStringExtension;
-import static protobuf_unittest.UnittestProto.defaultBytesExtension;
-import static protobuf_unittest.UnittestProto.defaultNestedEnumExtension;
-import static protobuf_unittest.UnittestProto.defaultForeignEnumExtension;
-import static protobuf_unittest.UnittestProto.defaultImportEnumExtension;
import static protobuf_unittest.UnittestProto.defaultStringPieceExtension;
-import static protobuf_unittest.UnittestProto.defaultCordExtension;
-
-import static protobuf_unittest.UnittestProto.oneofUint32Extension;
+import static protobuf_unittest.UnittestProto.defaultUint32Extension;
+import static protobuf_unittest.UnittestProto.defaultUint64Extension;
+import static protobuf_unittest.UnittestProto.oneofBytesExtension;
import static protobuf_unittest.UnittestProto.oneofNestedMessageExtension;
import static protobuf_unittest.UnittestProto.oneofStringExtension;
-import static protobuf_unittest.UnittestProto.oneofBytesExtension;
-
-import static protobuf_unittest.UnittestProto.optionalInt32Extension;
-import static protobuf_unittest.UnittestProto.optionalInt64Extension;
-import static protobuf_unittest.UnittestProto.optionalUint32Extension;
-import static protobuf_unittest.UnittestProto.optionalUint64Extension;
-import static protobuf_unittest.UnittestProto.optionalSint32Extension;
-import static protobuf_unittest.UnittestProto.optionalSint64Extension;
-import static protobuf_unittest.UnittestProto.optionalFixed32Extension;
-import static protobuf_unittest.UnittestProto.optionalFixed64Extension;
-import static protobuf_unittest.UnittestProto.optionalSfixed32Extension;
-import static protobuf_unittest.UnittestProto.optionalSfixed64Extension;
-import static protobuf_unittest.UnittestProto.optionalFloatExtension;
-import static protobuf_unittest.UnittestProto.optionalDoubleExtension;
+import static protobuf_unittest.UnittestProto.oneofUint32Extension;
import static protobuf_unittest.UnittestProto.optionalBoolExtension;
-import static protobuf_unittest.UnittestProto.optionalStringExtension;
import static protobuf_unittest.UnittestProto.optionalBytesExtension;
-import static protobuf_unittest.UnittestProto.optionalGroupExtension;
import static protobuf_unittest.UnittestProto.optionalCordExtension;
+import static protobuf_unittest.UnittestProto.optionalDoubleExtension;
+import static protobuf_unittest.UnittestProto.optionalFixed32Extension;
+import static protobuf_unittest.UnittestProto.optionalFixed64Extension;
+import static protobuf_unittest.UnittestProto.optionalFloatExtension;
import static protobuf_unittest.UnittestProto.optionalForeignEnumExtension;
import static protobuf_unittest.UnittestProto.optionalForeignMessageExtension;
+import static protobuf_unittest.UnittestProto.optionalGroupExtension;
import static protobuf_unittest.UnittestProto.optionalImportEnumExtension;
import static protobuf_unittest.UnittestProto.optionalImportMessageExtension;
+import static protobuf_unittest.UnittestProto.optionalInt32Extension;
+import static protobuf_unittest.UnittestProto.optionalInt64Extension;
+import static protobuf_unittest.UnittestProto.optionalLazyMessageExtension;
import static protobuf_unittest.UnittestProto.optionalNestedEnumExtension;
import static protobuf_unittest.UnittestProto.optionalNestedMessageExtension;
import static protobuf_unittest.UnittestProto.optionalPublicImportMessageExtension;
-import static protobuf_unittest.UnittestProto.optionalLazyMessageExtension;
+import static protobuf_unittest.UnittestProto.optionalSfixed32Extension;
+import static protobuf_unittest.UnittestProto.optionalSfixed64Extension;
+import static protobuf_unittest.UnittestProto.optionalSint32Extension;
+import static protobuf_unittest.UnittestProto.optionalSint64Extension;
+import static protobuf_unittest.UnittestProto.optionalStringExtension;
import static protobuf_unittest.UnittestProto.optionalStringPieceExtension;
-
-import static protobuf_unittest.UnittestProto.repeatedInt32Extension;
-import static protobuf_unittest.UnittestProto.repeatedInt64Extension;
-import static protobuf_unittest.UnittestProto.repeatedUint32Extension;
-import static protobuf_unittest.UnittestProto.repeatedUint64Extension;
-import static protobuf_unittest.UnittestProto.repeatedSint32Extension;
-import static protobuf_unittest.UnittestProto.repeatedSint64Extension;
+import static protobuf_unittest.UnittestProto.optionalUint32Extension;
+import static protobuf_unittest.UnittestProto.optionalUint64Extension;
+import static protobuf_unittest.UnittestProto.packedBoolExtension;
+import static protobuf_unittest.UnittestProto.packedDoubleExtension;
+import static protobuf_unittest.UnittestProto.packedEnumExtension;
+import static protobuf_unittest.UnittestProto.packedFixed32Extension;
+import static protobuf_unittest.UnittestProto.packedFixed64Extension;
+import static protobuf_unittest.UnittestProto.packedFloatExtension;
+import static protobuf_unittest.UnittestProto.packedInt32Extension;
+import static protobuf_unittest.UnittestProto.packedInt64Extension;
+import static protobuf_unittest.UnittestProto.packedSfixed32Extension;
+import static protobuf_unittest.UnittestProto.packedSfixed64Extension;
+import static protobuf_unittest.UnittestProto.packedSint32Extension;
+import static protobuf_unittest.UnittestProto.packedSint64Extension;
+import static protobuf_unittest.UnittestProto.packedUint32Extension;
+import static protobuf_unittest.UnittestProto.packedUint64Extension;
+import static protobuf_unittest.UnittestProto.repeatedBoolExtension;
+import static protobuf_unittest.UnittestProto.repeatedBytesExtension;
+import static protobuf_unittest.UnittestProto.repeatedCordExtension;
+import static protobuf_unittest.UnittestProto.repeatedDoubleExtension;
import static protobuf_unittest.UnittestProto.repeatedFixed32Extension;
import static protobuf_unittest.UnittestProto.repeatedFixed64Extension;
-import static protobuf_unittest.UnittestProto.repeatedSfixed32Extension;
-import static protobuf_unittest.UnittestProto.repeatedSfixed64Extension;
import static protobuf_unittest.UnittestProto.repeatedFloatExtension;
-import static protobuf_unittest.UnittestProto.repeatedDoubleExtension;
-import static protobuf_unittest.UnittestProto.repeatedBoolExtension;
-import static protobuf_unittest.UnittestProto.repeatedStringExtension;
-import static protobuf_unittest.UnittestProto.repeatedBytesExtension;
-import static protobuf_unittest.UnittestProto.repeatedGroupExtension;
-import static protobuf_unittest.UnittestProto.repeatedNestedMessageExtension;
+import static protobuf_unittest.UnittestProto.repeatedForeignEnumExtension;
import static protobuf_unittest.UnittestProto.repeatedForeignMessageExtension;
+import static protobuf_unittest.UnittestProto.repeatedGroupExtension;
+import static protobuf_unittest.UnittestProto.repeatedImportEnumExtension;
import static protobuf_unittest.UnittestProto.repeatedImportMessageExtension;
+import static protobuf_unittest.UnittestProto.repeatedInt32Extension;
+import static protobuf_unittest.UnittestProto.repeatedInt64Extension;
import static protobuf_unittest.UnittestProto.repeatedLazyMessageExtension;
import static protobuf_unittest.UnittestProto.repeatedNestedEnumExtension;
-import static protobuf_unittest.UnittestProto.repeatedForeignEnumExtension;
-import static protobuf_unittest.UnittestProto.repeatedImportEnumExtension;
+import static protobuf_unittest.UnittestProto.repeatedNestedMessageExtension;
+import static protobuf_unittest.UnittestProto.repeatedSfixed32Extension;
+import static protobuf_unittest.UnittestProto.repeatedSfixed64Extension;
+import static protobuf_unittest.UnittestProto.repeatedSint32Extension;
+import static protobuf_unittest.UnittestProto.repeatedSint64Extension;
+import static protobuf_unittest.UnittestProto.repeatedStringExtension;
import static protobuf_unittest.UnittestProto.repeatedStringPieceExtension;
-import static protobuf_unittest.UnittestProto.repeatedCordExtension;
-
-import static protobuf_unittest.UnittestProto.OptionalGroup_extension;
-import static protobuf_unittest.UnittestProto.RepeatedGroup_extension;
-
-import static protobuf_unittest.UnittestProto.packedInt32Extension;
-import static protobuf_unittest.UnittestProto.packedInt64Extension;
-import static protobuf_unittest.UnittestProto.packedUint32Extension;
-import static protobuf_unittest.UnittestProto.packedUint64Extension;
-import static protobuf_unittest.UnittestProto.packedSint32Extension;
-import static protobuf_unittest.UnittestProto.packedSint64Extension;
-import static protobuf_unittest.UnittestProto.packedFixed32Extension;
-import static protobuf_unittest.UnittestProto.packedFixed64Extension;
-import static protobuf_unittest.UnittestProto.packedSfixed32Extension;
-import static protobuf_unittest.UnittestProto.packedSfixed64Extension;
-import static protobuf_unittest.UnittestProto.packedFloatExtension;
-import static protobuf_unittest.UnittestProto.packedDoubleExtension;
-import static protobuf_unittest.UnittestProto.packedBoolExtension;
-import static protobuf_unittest.UnittestProto.packedEnumExtension;
-
-import static com.google.protobuf.UnittestLite.defaultInt32ExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultInt64ExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultUint32ExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultUint64ExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultSint32ExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultSint64ExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultFixed32ExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultFixed64ExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultSfixed32ExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultSfixed64ExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultFloatExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultDoubleExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultBoolExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultStringExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultBytesExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultNestedEnumExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultForeignEnumExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultImportEnumExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultStringPieceExtensionLite;
-import static com.google.protobuf.UnittestLite.defaultCordExtensionLite;
-
-import static com.google.protobuf.UnittestLite.oneofUint32ExtensionLite;
-import static com.google.protobuf.UnittestLite.oneofNestedMessageExtensionLite;
-import static com.google.protobuf.UnittestLite.oneofStringExtensionLite;
-import static com.google.protobuf.UnittestLite.oneofBytesExtensionLite;
-
-import static com.google.protobuf.UnittestLite.optionalInt32ExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalInt64ExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalUint32ExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalUint64ExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalSint32ExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalSint64ExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalFixed32ExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalFixed64ExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalSfixed32ExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalSfixed64ExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalFloatExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalDoubleExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalBoolExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalStringExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalBytesExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalGroupExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalNestedMessageExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalForeignEnumExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalForeignMessageExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalImportEnumExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalImportMessageExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalNestedEnumExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalPublicImportMessageExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalLazyMessageExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalStringPieceExtensionLite;
-import static com.google.protobuf.UnittestLite.optionalCordExtensionLite;
-
-import static com.google.protobuf.UnittestLite.repeatedInt32ExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedInt64ExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedUint32ExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedUint64ExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedSint32ExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedSint64ExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedFixed32ExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedFixed64ExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedSfixed32ExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedSfixed64ExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedFloatExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedDoubleExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedBoolExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedStringExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedBytesExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedGroupExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedNestedMessageExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedForeignMessageExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedImportMessageExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedLazyMessageExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedNestedEnumExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedForeignEnumExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedImportEnumExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedStringPieceExtensionLite;
-import static com.google.protobuf.UnittestLite.repeatedCordExtensionLite;
-
-import static com.google.protobuf.UnittestLite.OptionalGroup_extension_lite;
-import static com.google.protobuf.UnittestLite.RepeatedGroup_extension_lite;
-
-import static com.google.protobuf.UnittestLite.packedInt32ExtensionLite;
-import static com.google.protobuf.UnittestLite.packedInt64ExtensionLite;
-import static com.google.protobuf.UnittestLite.packedUint32ExtensionLite;
-import static com.google.protobuf.UnittestLite.packedUint64ExtensionLite;
-import static com.google.protobuf.UnittestLite.packedSint32ExtensionLite;
-import static com.google.protobuf.UnittestLite.packedSint64ExtensionLite;
-import static com.google.protobuf.UnittestLite.packedFixed32ExtensionLite;
-import static com.google.protobuf.UnittestLite.packedFixed64ExtensionLite;
-import static com.google.protobuf.UnittestLite.packedSfixed32ExtensionLite;
-import static com.google.protobuf.UnittestLite.packedSfixed64ExtensionLite;
-import static com.google.protobuf.UnittestLite.packedFloatExtensionLite;
-import static com.google.protobuf.UnittestLite.packedDoubleExtensionLite;
-import static com.google.protobuf.UnittestLite.packedBoolExtensionLite;
-import static com.google.protobuf.UnittestLite.packedEnumExtensionLite;
+import static protobuf_unittest.UnittestProto.repeatedUint32Extension;
+import static protobuf_unittest.UnittestProto.repeatedUint64Extension;
+import com.google.protobuf.UnittestImportLite.ImportEnumLite;
+import com.google.protobuf.UnittestLite.ForeignEnumLite;
+import com.google.protobuf.UnittestLite.TestAllExtensionsLiteOrBuilder;
+import com.google.protobuf.UnittestLite.TestAllTypesLite;
+import com.google.protobuf.UnittestLite.TestPackedExtensionsLite;
+import com.google.protobuf.test.UnittestImport.ImportEnum;
+import com.google.protobuf.test.UnittestImport.ImportMessage;
+import com.google.protobuf.test.UnittestImportPublic.PublicImportMessage;
+import protobuf_unittest.UnittestProto;
+import protobuf_unittest.UnittestProto.ForeignEnum;
+import protobuf_unittest.UnittestProto.ForeignMessage;
import protobuf_unittest.UnittestProto.TestAllExtensions;
import protobuf_unittest.UnittestProto.TestAllExtensionsOrBuilder;
import protobuf_unittest.UnittestProto.TestAllTypes;
@@ -237,21 +232,6 @@ import protobuf_unittest.UnittestProto.TestOneof2;
import protobuf_unittest.UnittestProto.TestPackedExtensions;
import protobuf_unittest.UnittestProto.TestPackedTypes;
import protobuf_unittest.UnittestProto.TestUnpackedTypes;
-import protobuf_unittest.UnittestProto.ForeignMessage;
-import protobuf_unittest.UnittestProto.ForeignEnum;
-import com.google.protobuf.test.UnittestImport.ImportEnum;
-import com.google.protobuf.test.UnittestImport.ImportMessage;
-import com.google.protobuf.test.UnittestImportPublic.PublicImportMessage;
-
-import com.google.protobuf.UnittestLite.TestAllTypesLite;
-import com.google.protobuf.UnittestLite.TestAllExtensionsLite;
-import com.google.protobuf.UnittestLite.TestAllExtensionsLiteOrBuilder;
-import com.google.protobuf.UnittestLite.TestPackedExtensionsLite;
-import com.google.protobuf.UnittestLite.ForeignMessageLite;
-import com.google.protobuf.UnittestLite.ForeignEnumLite;
-import com.google.protobuf.UnittestImportLite.ImportEnumLite;
-import com.google.protobuf.UnittestImportLite.ImportMessageLite;
-import com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite;
import junit.framework.Assert;
@@ -309,12 +289,6 @@ public final class TestUtil {
return builder.build();
}
- public static TestAllExtensionsLite getAllLiteExtensionsSet() {
- TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.newBuilder();
- setAllExtensions(builder);
- return builder.build();
- }
-
public static TestPackedTypes getPackedSet() {
TestPackedTypes.Builder builder = TestPackedTypes.newBuilder();
setPackedFields(builder);
@@ -333,13 +307,6 @@ public final class TestUtil {
return builder.build();
}
- public static TestPackedExtensionsLite getLitePackedExtensionsSet() {
- TestPackedExtensionsLite.Builder builder =
- TestPackedExtensionsLite.newBuilder();
- setPackedExtensions(builder);
- return builder.build();
- }
-
/**
* Set every field of {@code message} to the values expected by
* {@code assertAllFieldsSet()}.
@@ -1229,23 +1196,13 @@ public final class TestUtil {
return registry.getUnmodifiable();
}
- public static ExtensionRegistryLite getExtensionRegistryLite() {
- ExtensionRegistryLite registry = ExtensionRegistryLite.newInstance();
- registerAllExtensionsLite(registry);
- return registry.getUnmodifiable();
- }
-
/**
* Register all of {@code TestAllExtensions}'s extensions with the
* given {@link ExtensionRegistry}.
*/
public static void registerAllExtensions(ExtensionRegistry registry) {
UnittestProto.registerAllExtensions(registry);
- registerAllExtensionsLite(registry);
- }
-
- public static void registerAllExtensionsLite(ExtensionRegistryLite registry) {
- UnittestLite.registerAllExtensions(registry);
+ TestUtilLite.registerAllExtensionsLite(registry);
}
/**
@@ -2039,195 +1996,6 @@ public final class TestUtil {
// Lite extensions
/**
- * Set every field of {@code message} to the values expected by
- * {@code assertAllExtensionsSet()}.
- */
- public static void setAllExtensions(TestAllExtensionsLite.Builder message) {
- message.setExtension(optionalInt32ExtensionLite , 101);
- message.setExtension(optionalInt64ExtensionLite , 102L);
- message.setExtension(optionalUint32ExtensionLite , 103);
- message.setExtension(optionalUint64ExtensionLite , 104L);
- message.setExtension(optionalSint32ExtensionLite , 105);
- message.setExtension(optionalSint64ExtensionLite , 106L);
- message.setExtension(optionalFixed32ExtensionLite , 107);
- message.setExtension(optionalFixed64ExtensionLite , 108L);
- message.setExtension(optionalSfixed32ExtensionLite, 109);
- message.setExtension(optionalSfixed64ExtensionLite, 110L);
- message.setExtension(optionalFloatExtensionLite , 111F);
- message.setExtension(optionalDoubleExtensionLite , 112D);
- message.setExtension(optionalBoolExtensionLite , true);
- message.setExtension(optionalStringExtensionLite , "115");
- message.setExtension(optionalBytesExtensionLite , toBytes("116"));
-
- message.setExtension(optionalGroupExtensionLite,
- OptionalGroup_extension_lite.newBuilder().setA(117).build());
- message.setExtension(optionalNestedMessageExtensionLite,
- TestAllTypesLite.NestedMessage.newBuilder().setBb(118).build());
- message.setExtension(optionalForeignMessageExtensionLite,
- ForeignMessageLite.newBuilder().setC(119).build());
- message.setExtension(optionalImportMessageExtensionLite,
- ImportMessageLite.newBuilder().setD(120).build());
- message.setExtension(optionalPublicImportMessageExtensionLite,
- PublicImportMessageLite.newBuilder().setE(126).build());
- message.setExtension(optionalLazyMessageExtensionLite,
- TestAllTypesLite.NestedMessage.newBuilder().setBb(127).build());
-
- message.setExtension(optionalNestedEnumExtensionLite, TestAllTypesLite.NestedEnum.BAZ);
- message.setExtension(optionalForeignEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAZ);
- message.setExtension(optionalImportEnumExtensionLite, ImportEnumLite.IMPORT_LITE_BAZ);
-
- message.setExtension(optionalStringPieceExtensionLite, "124");
- message.setExtension(optionalCordExtensionLite, "125");
-
- // -----------------------------------------------------------------
-
- message.addExtension(repeatedInt32ExtensionLite , 201);
- message.addExtension(repeatedInt64ExtensionLite , 202L);
- message.addExtension(repeatedUint32ExtensionLite , 203);
- message.addExtension(repeatedUint64ExtensionLite , 204L);
- message.addExtension(repeatedSint32ExtensionLite , 205);
- message.addExtension(repeatedSint64ExtensionLite , 206L);
- message.addExtension(repeatedFixed32ExtensionLite , 207);
- message.addExtension(repeatedFixed64ExtensionLite , 208L);
- message.addExtension(repeatedSfixed32ExtensionLite, 209);
- message.addExtension(repeatedSfixed64ExtensionLite, 210L);
- message.addExtension(repeatedFloatExtensionLite , 211F);
- message.addExtension(repeatedDoubleExtensionLite , 212D);
- message.addExtension(repeatedBoolExtensionLite , true);
- message.addExtension(repeatedStringExtensionLite , "215");
- message.addExtension(repeatedBytesExtensionLite , toBytes("216"));
-
- message.addExtension(repeatedGroupExtensionLite,
- RepeatedGroup_extension_lite.newBuilder().setA(217).build());
- message.addExtension(repeatedNestedMessageExtensionLite,
- TestAllTypesLite.NestedMessage.newBuilder().setBb(218).build());
- message.addExtension(repeatedForeignMessageExtensionLite,
- ForeignMessageLite.newBuilder().setC(219).build());
- message.addExtension(repeatedImportMessageExtensionLite,
- ImportMessageLite.newBuilder().setD(220).build());
- message.addExtension(repeatedLazyMessageExtensionLite,
- TestAllTypesLite.NestedMessage.newBuilder().setBb(227).build());
-
- message.addExtension(repeatedNestedEnumExtensionLite, TestAllTypesLite.NestedEnum.BAR);
- message.addExtension(repeatedForeignEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAR);
- message.addExtension(repeatedImportEnumExtensionLite, ImportEnumLite.IMPORT_LITE_BAR);
-
- message.addExtension(repeatedStringPieceExtensionLite, "224");
- message.addExtension(repeatedCordExtensionLite, "225");
-
- // Add a second one of each field.
- message.addExtension(repeatedInt32ExtensionLite , 301);
- message.addExtension(repeatedInt64ExtensionLite , 302L);
- message.addExtension(repeatedUint32ExtensionLite , 303);
- message.addExtension(repeatedUint64ExtensionLite , 304L);
- message.addExtension(repeatedSint32ExtensionLite , 305);
- message.addExtension(repeatedSint64ExtensionLite , 306L);
- message.addExtension(repeatedFixed32ExtensionLite , 307);
- message.addExtension(repeatedFixed64ExtensionLite , 308L);
- message.addExtension(repeatedSfixed32ExtensionLite, 309);
- message.addExtension(repeatedSfixed64ExtensionLite, 310L);
- message.addExtension(repeatedFloatExtensionLite , 311F);
- message.addExtension(repeatedDoubleExtensionLite , 312D);
- message.addExtension(repeatedBoolExtensionLite , false);
- message.addExtension(repeatedStringExtensionLite , "315");
- message.addExtension(repeatedBytesExtensionLite , toBytes("316"));
-
- message.addExtension(repeatedGroupExtensionLite,
- RepeatedGroup_extension_lite.newBuilder().setA(317).build());
- message.addExtension(repeatedNestedMessageExtensionLite,
- TestAllTypesLite.NestedMessage.newBuilder().setBb(318).build());
- message.addExtension(repeatedForeignMessageExtensionLite,
- ForeignMessageLite.newBuilder().setC(319).build());
- message.addExtension(repeatedImportMessageExtensionLite,
- ImportMessageLite.newBuilder().setD(320).build());
- message.addExtension(repeatedLazyMessageExtensionLite,
- TestAllTypesLite.NestedMessage.newBuilder().setBb(327).build());
-
- message.addExtension(repeatedNestedEnumExtensionLite, TestAllTypesLite.NestedEnum.BAZ);
- message.addExtension(repeatedForeignEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAZ);
- message.addExtension(repeatedImportEnumExtensionLite, ImportEnumLite.IMPORT_LITE_BAZ);
-
- message.addExtension(repeatedStringPieceExtensionLite, "324");
- message.addExtension(repeatedCordExtensionLite, "325");
-
- // -----------------------------------------------------------------
-
- message.setExtension(defaultInt32ExtensionLite , 401);
- message.setExtension(defaultInt64ExtensionLite , 402L);
- message.setExtension(defaultUint32ExtensionLite , 403);
- message.setExtension(defaultUint64ExtensionLite , 404L);
- message.setExtension(defaultSint32ExtensionLite , 405);
- message.setExtension(defaultSint64ExtensionLite , 406L);
- message.setExtension(defaultFixed32ExtensionLite , 407);
- message.setExtension(defaultFixed64ExtensionLite , 408L);
- message.setExtension(defaultSfixed32ExtensionLite, 409);
- message.setExtension(defaultSfixed64ExtensionLite, 410L);
- message.setExtension(defaultFloatExtensionLite , 411F);
- message.setExtension(defaultDoubleExtensionLite , 412D);
- message.setExtension(defaultBoolExtensionLite , false);
- message.setExtension(defaultStringExtensionLite , "415");
- message.setExtension(defaultBytesExtensionLite , toBytes("416"));
-
- message.setExtension(defaultNestedEnumExtensionLite, TestAllTypesLite.NestedEnum.FOO);
- message.setExtension(defaultForeignEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_FOO);
- message.setExtension(defaultImportEnumExtensionLite, ImportEnumLite.IMPORT_LITE_FOO);
-
- message.setExtension(defaultStringPieceExtensionLite, "424");
- message.setExtension(defaultCordExtensionLite, "425");
-
- message.setExtension(oneofUint32ExtensionLite, 601);
- message.setExtension(oneofNestedMessageExtensionLite,
- TestAllTypesLite.NestedMessage.newBuilder().setBb(602).build());
- message.setExtension(oneofStringExtensionLite, "603");
- message.setExtension(oneofBytesExtensionLite, toBytes("604"));
- }
-
- // -------------------------------------------------------------------
-
- /**
- * Modify the repeated extensions of {@code message} to contain the values
- * expected by {@code assertRepeatedExtensionsModified()}.
- */
- public static void modifyRepeatedExtensions(
- TestAllExtensionsLite.Builder message) {
- message.setExtension(repeatedInt32ExtensionLite , 1, 501);
- message.setExtension(repeatedInt64ExtensionLite , 1, 502L);
- message.setExtension(repeatedUint32ExtensionLite , 1, 503);
- message.setExtension(repeatedUint64ExtensionLite , 1, 504L);
- message.setExtension(repeatedSint32ExtensionLite , 1, 505);
- message.setExtension(repeatedSint64ExtensionLite , 1, 506L);
- message.setExtension(repeatedFixed32ExtensionLite , 1, 507);
- message.setExtension(repeatedFixed64ExtensionLite , 1, 508L);
- message.setExtension(repeatedSfixed32ExtensionLite, 1, 509);
- message.setExtension(repeatedSfixed64ExtensionLite, 1, 510L);
- message.setExtension(repeatedFloatExtensionLite , 1, 511F);
- message.setExtension(repeatedDoubleExtensionLite , 1, 512D);
- message.setExtension(repeatedBoolExtensionLite , 1, true);
- message.setExtension(repeatedStringExtensionLite , 1, "515");
- message.setExtension(repeatedBytesExtensionLite , 1, toBytes("516"));
-
- message.setExtension(repeatedGroupExtensionLite, 1,
- RepeatedGroup_extension_lite.newBuilder().setA(517).build());
- message.setExtension(repeatedNestedMessageExtensionLite, 1,
- TestAllTypesLite.NestedMessage.newBuilder().setBb(518).build());
- message.setExtension(repeatedForeignMessageExtensionLite, 1,
- ForeignMessageLite.newBuilder().setC(519).build());
- message.setExtension(repeatedImportMessageExtensionLite, 1,
- ImportMessageLite.newBuilder().setD(520).build());
- message.setExtension(repeatedLazyMessageExtensionLite, 1,
- TestAllTypesLite.NestedMessage.newBuilder().setBb(527).build());
-
- message.setExtension(repeatedNestedEnumExtensionLite , 1, TestAllTypesLite.NestedEnum.FOO);
- message.setExtension(repeatedForeignEnumExtensionLite, 1, ForeignEnumLite.FOREIGN_LITE_FOO);
- message.setExtension(repeatedImportEnumExtensionLite , 1, ImportEnumLite.IMPORT_LITE_FOO);
-
- message.setExtension(repeatedStringPieceExtensionLite, 1, "524");
- message.setExtension(repeatedCordExtensionLite, 1, "525");
- }
-
- // -------------------------------------------------------------------
-
- /**
* Assert (using {@code junit.framework.Assert}} that all extensions of
* {@code message} are set to the values assigned by {@code setAllExtensions}.
*/
@@ -2726,38 +2494,6 @@ public final class TestUtil {
assertEqualsExactType("525", message.getExtension(repeatedCordExtensionLite, 1));
}
- public static void setPackedExtensions(TestPackedExtensionsLite.Builder message) {
- message.addExtension(packedInt32ExtensionLite , 601);
- message.addExtension(packedInt64ExtensionLite , 602L);
- message.addExtension(packedUint32ExtensionLite , 603);
- message.addExtension(packedUint64ExtensionLite , 604L);
- message.addExtension(packedSint32ExtensionLite , 605);
- message.addExtension(packedSint64ExtensionLite , 606L);
- message.addExtension(packedFixed32ExtensionLite , 607);
- message.addExtension(packedFixed64ExtensionLite , 608L);
- message.addExtension(packedSfixed32ExtensionLite, 609);
- message.addExtension(packedSfixed64ExtensionLite, 610L);
- message.addExtension(packedFloatExtensionLite , 611F);
- message.addExtension(packedDoubleExtensionLite , 612D);
- message.addExtension(packedBoolExtensionLite , true);
- message.addExtension(packedEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAR);
- // Add a second one of each field.
- message.addExtension(packedInt32ExtensionLite , 701);
- message.addExtension(packedInt64ExtensionLite , 702L);
- message.addExtension(packedUint32ExtensionLite , 703);
- message.addExtension(packedUint64ExtensionLite , 704L);
- message.addExtension(packedSint32ExtensionLite , 705);
- message.addExtension(packedSint64ExtensionLite , 706L);
- message.addExtension(packedFixed32ExtensionLite , 707);
- message.addExtension(packedFixed64ExtensionLite , 708L);
- message.addExtension(packedSfixed32ExtensionLite, 709);
- message.addExtension(packedSfixed64ExtensionLite, 710L);
- message.addExtension(packedFloatExtensionLite , 711F);
- message.addExtension(packedDoubleExtensionLite , 712D);
- message.addExtension(packedBoolExtensionLite , false);
- message.addExtension(packedEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAZ);
- }
-
public static void assertPackedExtensionsSet(TestPackedExtensionsLite message) {
Assert.assertEquals(2, message.getExtensionCount(packedInt32ExtensionLite ));
Assert.assertEquals(2, message.getExtensionCount(packedInt64ExtensionLite ));
@@ -4028,7 +3764,8 @@ public final class TestUtil {
private static File getTestDataDir() {
// Search each parent directory looking for "src/google/protobuf".
- File ancestor = new File(".");
+ File ancestor = new File(System.getProperty("protobuf.dir", "."));
+ String initialPath = ancestor.getAbsolutePath();
try {
ancestor = ancestor.getCanonicalFile();
} catch (IOException e) {
@@ -4045,7 +3782,7 @@ public final class TestUtil {
throw new RuntimeException(
"Could not find golden files. This test must be run from within the " +
"protobuf source package so that it can read test data files from the " +
- "C++ source tree.");
+ "C++ source tree: " + initialPath);
}
/**
@@ -4109,7 +3846,7 @@ public final class TestUtil {
private int invalidations;
- //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @Override
public void markDirty() {
invalidations++;
}
diff --git a/java/core/src/test/java/com/google/protobuf/TestUtilLite.java b/java/core/src/test/java/com/google/protobuf/TestUtilLite.java
new file mode 100644
index 00000000..8f33fa14
--- /dev/null
+++ b/java/core/src/test/java/com/google/protobuf/TestUtilLite.java
@@ -0,0 +1,559 @@
+// 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.
+
+package com.google.protobuf;
+
+import static com.google.protobuf.UnittestLite.OptionalGroup_extension_lite;
+import static com.google.protobuf.UnittestLite.RepeatedGroup_extension_lite;
+import static com.google.protobuf.UnittestLite.defaultBoolExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultBytesExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultCordExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultDoubleExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultFixed32ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultFixed64ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultFloatExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultForeignEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultImportEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultInt32ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultInt64ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultNestedEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultSfixed32ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultSfixed64ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultSint32ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultSint64ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultStringExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultStringPieceExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultUint32ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultUint64ExtensionLite;
+import static com.google.protobuf.UnittestLite.oneofBytesExtensionLite;
+import static com.google.protobuf.UnittestLite.oneofNestedMessageExtensionLite;
+import static com.google.protobuf.UnittestLite.oneofStringExtensionLite;
+import static com.google.protobuf.UnittestLite.oneofUint32ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalBoolExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalBytesExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalCordExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalDoubleExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalFixed32ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalFixed64ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalFloatExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalForeignEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalForeignMessageExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalGroupExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalImportEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalImportMessageExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalInt32ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalInt64ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalLazyMessageExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalNestedEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalNestedMessageExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalPublicImportMessageExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalSfixed32ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalSfixed64ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalSint32ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalSint64ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalStringExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalStringPieceExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalUint32ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalUint64ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedBoolExtensionLite;
+import static com.google.protobuf.UnittestLite.packedDoubleExtensionLite;
+import static com.google.protobuf.UnittestLite.packedEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.packedFixed32ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedFixed64ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedFloatExtensionLite;
+import static com.google.protobuf.UnittestLite.packedInt32ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedInt64ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedSfixed32ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedSfixed64ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedSint32ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedSint64ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedUint32ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedUint64ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedBoolExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedBytesExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedCordExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedDoubleExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedFixed32ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedFixed64ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedFloatExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedForeignEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedForeignMessageExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedGroupExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedImportEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedImportMessageExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedInt32ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedInt64ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedLazyMessageExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedNestedEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedNestedMessageExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedSfixed32ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedSfixed64ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedSint32ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedSint64ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedStringExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedStringPieceExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedUint32ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedUint64ExtensionLite;
+
+import com.google.protobuf.UnittestImportLite.ImportEnumLite;
+import com.google.protobuf.UnittestImportLite.ImportMessageLite;
+import com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite;
+import com.google.protobuf.UnittestLite.ForeignEnumLite;
+import com.google.protobuf.UnittestLite.ForeignMessageLite;
+import com.google.protobuf.UnittestLite.TestAllExtensionsLite;
+import com.google.protobuf.UnittestLite.TestAllTypesLite;
+import com.google.protobuf.UnittestLite.TestPackedExtensionsLite;
+
+/**
+ * Contains methods for setting fields of {@code TestAllTypesLite}, {@code TestAllExtensionsLite},
+ * and {@code TestPackedExtensionsLite}. This is analogous to the functionality in TestUtil.java but
+ * does not depend on the presence of any non-lite protos.
+ *
+ * <p>This code is not to be used outside of {@code com.google.protobuf} and
+ * subpackages.
+ */
+public final class TestUtilLite {
+ private TestUtilLite() {}
+
+ /** Helper to convert a String to ByteString. */
+ static ByteString toBytes(String str) {
+ return ByteString.copyFrom(str.getBytes(Internal.UTF_8));
+ }
+
+ /**
+ * Get a {@code TestAllTypesLite.Builder} with all fields set as they would be by
+ * {@link #setAllFields(TestAllTypesLite.Builder)}.
+ */
+ public static TestAllTypesLite.Builder getAllLiteSetBuilder() {
+ TestAllTypesLite.Builder builder = TestAllTypesLite.newBuilder();
+ setAllFields(builder);
+ return builder;
+ }
+
+ /**
+ * Get a {@code TestAllExtensionsLite} with all fields set as they would be by
+ * {@link #setAllExtensions(TestAllExtensionsLite.Builder)}.
+ */
+ public static TestAllExtensionsLite getAllLiteExtensionsSet() {
+ TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.newBuilder();
+ setAllExtensions(builder);
+ return builder.build();
+ }
+
+ public static TestPackedExtensionsLite getLitePackedExtensionsSet() {
+ TestPackedExtensionsLite.Builder builder = TestPackedExtensionsLite.newBuilder();
+ setPackedExtensions(builder);
+ return builder.build();
+ }
+
+ /**
+ * Set every field of {@code builder} to the values expected by
+ * {@code assertAllFieldsSet()}.
+ */
+ public static void setAllFields(TestAllTypesLite.Builder builder) {
+ builder.setOptionalInt32 (101);
+ builder.setOptionalInt64 (102);
+ builder.setOptionalUint32 (103);
+ builder.setOptionalUint64 (104);
+ builder.setOptionalSint32 (105);
+ builder.setOptionalSint64 (106);
+ builder.setOptionalFixed32 (107);
+ builder.setOptionalFixed64 (108);
+ builder.setOptionalSfixed32(109);
+ builder.setOptionalSfixed64(110);
+ builder.setOptionalFloat (111);
+ builder.setOptionalDouble (112);
+ builder.setOptionalBool (true);
+ builder.setOptionalString ("115");
+ builder.setOptionalBytes (toBytes("116"));
+
+ builder.setOptionalGroup(
+ TestAllTypesLite.OptionalGroup.newBuilder().setA(117).build());
+ builder.setOptionalNestedMessage(
+ TestAllTypesLite.NestedMessage.newBuilder().setBb(118).build());
+ builder.setOptionalForeignMessage(
+ ForeignMessageLite.newBuilder().setC(119).build());
+ builder.setOptionalImportMessage(
+ ImportMessageLite.newBuilder().setD(120).build());
+ builder.setOptionalPublicImportMessage(
+ PublicImportMessageLite.newBuilder().setE(126).build());
+ builder.setOptionalLazyMessage(
+ TestAllTypesLite.NestedMessage.newBuilder().setBb(127).build());
+
+ builder.setOptionalNestedEnum (TestAllTypesLite.NestedEnum.BAZ);
+ builder.setOptionalForeignEnum(ForeignEnumLite.FOREIGN_LITE_BAZ);
+ builder.setOptionalImportEnum (ImportEnumLite.IMPORT_LITE_BAZ);
+
+ builder.setOptionalStringPiece("124");
+ builder.setOptionalCord("125");
+
+ // -----------------------------------------------------------------
+
+ builder.addRepeatedInt32 (201);
+ builder.addRepeatedInt64 (202);
+ builder.addRepeatedUint32 (203);
+ builder.addRepeatedUint64 (204);
+ builder.addRepeatedSint32 (205);
+ builder.addRepeatedSint64 (206);
+ builder.addRepeatedFixed32 (207);
+ builder.addRepeatedFixed64 (208);
+ builder.addRepeatedSfixed32(209);
+ builder.addRepeatedSfixed64(210);
+ builder.addRepeatedFloat (211);
+ builder.addRepeatedDouble (212);
+ builder.addRepeatedBool (true);
+ builder.addRepeatedString ("215");
+ builder.addRepeatedBytes (toBytes("216"));
+
+ builder.addRepeatedGroup(
+ TestAllTypesLite.RepeatedGroup.newBuilder().setA(217).build());
+ builder.addRepeatedNestedMessage(
+ TestAllTypesLite.NestedMessage.newBuilder().setBb(218).build());
+ builder.addRepeatedForeignMessage(
+ ForeignMessageLite.newBuilder().setC(219).build());
+ builder.addRepeatedImportMessage(
+ ImportMessageLite.newBuilder().setD(220).build());
+ builder.addRepeatedLazyMessage(
+ TestAllTypesLite.NestedMessage.newBuilder().setBb(227).build());
+
+ builder.addRepeatedNestedEnum (TestAllTypesLite.NestedEnum.BAR);
+ builder.addRepeatedForeignEnum(ForeignEnumLite.FOREIGN_LITE_BAR);
+ builder.addRepeatedImportEnum (ImportEnumLite.IMPORT_LITE_BAR);
+
+ builder.addRepeatedStringPiece("224");
+ builder.addRepeatedCord("225");
+
+ // Add a second one of each field.
+ builder.addRepeatedInt32 (301);
+ builder.addRepeatedInt64 (302);
+ builder.addRepeatedUint32 (303);
+ builder.addRepeatedUint64 (304);
+ builder.addRepeatedSint32 (305);
+ builder.addRepeatedSint64 (306);
+ builder.addRepeatedFixed32 (307);
+ builder.addRepeatedFixed64 (308);
+ builder.addRepeatedSfixed32(309);
+ builder.addRepeatedSfixed64(310);
+ builder.addRepeatedFloat (311);
+ builder.addRepeatedDouble (312);
+ builder.addRepeatedBool (false);
+ builder.addRepeatedString ("315");
+ builder.addRepeatedBytes (toBytes("316"));
+
+ builder.addRepeatedGroup(
+ TestAllTypesLite.RepeatedGroup.newBuilder().setA(317).build());
+ builder.addRepeatedNestedMessage(
+ TestAllTypesLite.NestedMessage.newBuilder().setBb(318).build());
+ builder.addRepeatedForeignMessage(
+ ForeignMessageLite.newBuilder().setC(319).build());
+ builder.addRepeatedImportMessage(
+ ImportMessageLite.newBuilder().setD(320).build());
+ builder.addRepeatedLazyMessage(
+ TestAllTypesLite.NestedMessage.newBuilder().setBb(327).build());
+
+ builder.addRepeatedNestedEnum (TestAllTypesLite.NestedEnum.BAZ);
+ builder.addRepeatedForeignEnum(ForeignEnumLite.FOREIGN_LITE_BAZ);
+ builder.addRepeatedImportEnum (ImportEnumLite.IMPORT_LITE_BAZ);
+
+ builder.addRepeatedStringPiece("324");
+ builder.addRepeatedCord("325");
+
+ // -----------------------------------------------------------------
+
+ builder.setDefaultInt32 (401);
+ builder.setDefaultInt64 (402);
+ builder.setDefaultUint32 (403);
+ builder.setDefaultUint64 (404);
+ builder.setDefaultSint32 (405);
+ builder.setDefaultSint64 (406);
+ builder.setDefaultFixed32 (407);
+ builder.setDefaultFixed64 (408);
+ builder.setDefaultSfixed32(409);
+ builder.setDefaultSfixed64(410);
+ builder.setDefaultFloat (411);
+ builder.setDefaultDouble (412);
+ builder.setDefaultBool (false);
+ builder.setDefaultString ("415");
+ builder.setDefaultBytes (toBytes("416"));
+
+ builder.setDefaultNestedEnum (TestAllTypesLite.NestedEnum.FOO);
+ builder.setDefaultForeignEnum(ForeignEnumLite.FOREIGN_LITE_FOO);
+ builder.setDefaultImportEnum (ImportEnumLite.IMPORT_LITE_FOO);
+
+ builder.setDefaultStringPiece("424");
+ builder.setDefaultCord("425");
+
+ builder.setOneofUint32(601);
+ builder.setOneofNestedMessage(
+ TestAllTypesLite.NestedMessage.newBuilder().setBb(602).build());
+ builder.setOneofString("603");
+ builder.setOneofBytes(toBytes("604"));
+ }
+
+ /**
+ * Get an unmodifiable {@link ExtensionRegistryLite} containing all the
+ * extensions of {@code TestAllExtensionsLite}.
+ */
+ public static ExtensionRegistryLite getExtensionRegistryLite() {
+ ExtensionRegistryLite registry = ExtensionRegistryLite.newInstance();
+ registerAllExtensionsLite(registry);
+ return registry.getUnmodifiable();
+ }
+
+ /**
+ * Register all of {@code TestAllExtensionsLite}'s extensions with the
+ * given {@link ExtensionRegistryLite}.
+ */
+ public static void registerAllExtensionsLite(ExtensionRegistryLite registry) {
+ UnittestLite.registerAllExtensions(registry);
+ }
+
+ // ===================================================================
+ // Lite extensions
+
+ /**
+ * Set every field of {@code message} to the values expected by
+ * {@code assertAllExtensionsSet()}.
+ */
+ public static void setAllExtensions(TestAllExtensionsLite.Builder message) {
+ message.setExtension(optionalInt32ExtensionLite , 101);
+ message.setExtension(optionalInt64ExtensionLite , 102L);
+ message.setExtension(optionalUint32ExtensionLite , 103);
+ message.setExtension(optionalUint64ExtensionLite , 104L);
+ message.setExtension(optionalSint32ExtensionLite , 105);
+ message.setExtension(optionalSint64ExtensionLite , 106L);
+ message.setExtension(optionalFixed32ExtensionLite , 107);
+ message.setExtension(optionalFixed64ExtensionLite , 108L);
+ message.setExtension(optionalSfixed32ExtensionLite, 109);
+ message.setExtension(optionalSfixed64ExtensionLite, 110L);
+ message.setExtension(optionalFloatExtensionLite , 111F);
+ message.setExtension(optionalDoubleExtensionLite , 112D);
+ message.setExtension(optionalBoolExtensionLite , true);
+ message.setExtension(optionalStringExtensionLite , "115");
+ message.setExtension(optionalBytesExtensionLite , toBytes("116"));
+
+ message.setExtension(optionalGroupExtensionLite,
+ OptionalGroup_extension_lite.newBuilder().setA(117).build());
+ message.setExtension(optionalNestedMessageExtensionLite,
+ TestAllTypesLite.NestedMessage.newBuilder().setBb(118).build());
+ message.setExtension(optionalForeignMessageExtensionLite,
+ ForeignMessageLite.newBuilder().setC(119).build());
+ message.setExtension(optionalImportMessageExtensionLite,
+ ImportMessageLite.newBuilder().setD(120).build());
+ message.setExtension(optionalPublicImportMessageExtensionLite,
+ PublicImportMessageLite.newBuilder().setE(126).build());
+ message.setExtension(optionalLazyMessageExtensionLite,
+ TestAllTypesLite.NestedMessage.newBuilder().setBb(127).build());
+
+ message.setExtension(optionalNestedEnumExtensionLite, TestAllTypesLite.NestedEnum.BAZ);
+ message.setExtension(optionalForeignEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAZ);
+ message.setExtension(optionalImportEnumExtensionLite, ImportEnumLite.IMPORT_LITE_BAZ);
+
+ message.setExtension(optionalStringPieceExtensionLite, "124");
+ message.setExtension(optionalCordExtensionLite, "125");
+
+ // -----------------------------------------------------------------
+
+ message.addExtension(repeatedInt32ExtensionLite , 201);
+ message.addExtension(repeatedInt64ExtensionLite , 202L);
+ message.addExtension(repeatedUint32ExtensionLite , 203);
+ message.addExtension(repeatedUint64ExtensionLite , 204L);
+ message.addExtension(repeatedSint32ExtensionLite , 205);
+ message.addExtension(repeatedSint64ExtensionLite , 206L);
+ message.addExtension(repeatedFixed32ExtensionLite , 207);
+ message.addExtension(repeatedFixed64ExtensionLite , 208L);
+ message.addExtension(repeatedSfixed32ExtensionLite, 209);
+ message.addExtension(repeatedSfixed64ExtensionLite, 210L);
+ message.addExtension(repeatedFloatExtensionLite , 211F);
+ message.addExtension(repeatedDoubleExtensionLite , 212D);
+ message.addExtension(repeatedBoolExtensionLite , true);
+ message.addExtension(repeatedStringExtensionLite , "215");
+ message.addExtension(repeatedBytesExtensionLite , toBytes("216"));
+
+ message.addExtension(repeatedGroupExtensionLite,
+ RepeatedGroup_extension_lite.newBuilder().setA(217).build());
+ message.addExtension(repeatedNestedMessageExtensionLite,
+ TestAllTypesLite.NestedMessage.newBuilder().setBb(218).build());
+ message.addExtension(repeatedForeignMessageExtensionLite,
+ ForeignMessageLite.newBuilder().setC(219).build());
+ message.addExtension(repeatedImportMessageExtensionLite,
+ ImportMessageLite.newBuilder().setD(220).build());
+ message.addExtension(repeatedLazyMessageExtensionLite,
+ TestAllTypesLite.NestedMessage.newBuilder().setBb(227).build());
+
+ message.addExtension(repeatedNestedEnumExtensionLite, TestAllTypesLite.NestedEnum.BAR);
+ message.addExtension(repeatedForeignEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAR);
+ message.addExtension(repeatedImportEnumExtensionLite, ImportEnumLite.IMPORT_LITE_BAR);
+
+ message.addExtension(repeatedStringPieceExtensionLite, "224");
+ message.addExtension(repeatedCordExtensionLite, "225");
+
+ // Add a second one of each field.
+ message.addExtension(repeatedInt32ExtensionLite , 301);
+ message.addExtension(repeatedInt64ExtensionLite , 302L);
+ message.addExtension(repeatedUint32ExtensionLite , 303);
+ message.addExtension(repeatedUint64ExtensionLite , 304L);
+ message.addExtension(repeatedSint32ExtensionLite , 305);
+ message.addExtension(repeatedSint64ExtensionLite , 306L);
+ message.addExtension(repeatedFixed32ExtensionLite , 307);
+ message.addExtension(repeatedFixed64ExtensionLite , 308L);
+ message.addExtension(repeatedSfixed32ExtensionLite, 309);
+ message.addExtension(repeatedSfixed64ExtensionLite, 310L);
+ message.addExtension(repeatedFloatExtensionLite , 311F);
+ message.addExtension(repeatedDoubleExtensionLite , 312D);
+ message.addExtension(repeatedBoolExtensionLite , false);
+ message.addExtension(repeatedStringExtensionLite , "315");
+ message.addExtension(repeatedBytesExtensionLite , toBytes("316"));
+
+ message.addExtension(repeatedGroupExtensionLite,
+ RepeatedGroup_extension_lite.newBuilder().setA(317).build());
+ message.addExtension(repeatedNestedMessageExtensionLite,
+ TestAllTypesLite.NestedMessage.newBuilder().setBb(318).build());
+ message.addExtension(repeatedForeignMessageExtensionLite,
+ ForeignMessageLite.newBuilder().setC(319).build());
+ message.addExtension(repeatedImportMessageExtensionLite,
+ ImportMessageLite.newBuilder().setD(320).build());
+ message.addExtension(repeatedLazyMessageExtensionLite,
+ TestAllTypesLite.NestedMessage.newBuilder().setBb(327).build());
+
+ message.addExtension(repeatedNestedEnumExtensionLite, TestAllTypesLite.NestedEnum.BAZ);
+ message.addExtension(repeatedForeignEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAZ);
+ message.addExtension(repeatedImportEnumExtensionLite, ImportEnumLite.IMPORT_LITE_BAZ);
+
+ message.addExtension(repeatedStringPieceExtensionLite, "324");
+ message.addExtension(repeatedCordExtensionLite, "325");
+
+ // -----------------------------------------------------------------
+
+ message.setExtension(defaultInt32ExtensionLite , 401);
+ message.setExtension(defaultInt64ExtensionLite , 402L);
+ message.setExtension(defaultUint32ExtensionLite , 403);
+ message.setExtension(defaultUint64ExtensionLite , 404L);
+ message.setExtension(defaultSint32ExtensionLite , 405);
+ message.setExtension(defaultSint64ExtensionLite , 406L);
+ message.setExtension(defaultFixed32ExtensionLite , 407);
+ message.setExtension(defaultFixed64ExtensionLite , 408L);
+ message.setExtension(defaultSfixed32ExtensionLite, 409);
+ message.setExtension(defaultSfixed64ExtensionLite, 410L);
+ message.setExtension(defaultFloatExtensionLite , 411F);
+ message.setExtension(defaultDoubleExtensionLite , 412D);
+ message.setExtension(defaultBoolExtensionLite , false);
+ message.setExtension(defaultStringExtensionLite , "415");
+ message.setExtension(defaultBytesExtensionLite , toBytes("416"));
+
+ message.setExtension(defaultNestedEnumExtensionLite, TestAllTypesLite.NestedEnum.FOO);
+ message.setExtension(defaultForeignEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_FOO);
+ message.setExtension(defaultImportEnumExtensionLite, ImportEnumLite.IMPORT_LITE_FOO);
+
+ message.setExtension(defaultStringPieceExtensionLite, "424");
+ message.setExtension(defaultCordExtensionLite, "425");
+
+ message.setExtension(oneofUint32ExtensionLite, 601);
+ message.setExtension(oneofNestedMessageExtensionLite,
+ TestAllTypesLite.NestedMessage.newBuilder().setBb(602).build());
+ message.setExtension(oneofStringExtensionLite, "603");
+ message.setExtension(oneofBytesExtensionLite, toBytes("604"));
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Modify the repeated extensions of {@code message} to contain the values
+ * expected by {@code assertRepeatedExtensionsModified()}.
+ */
+ public static void modifyRepeatedExtensions(
+ TestAllExtensionsLite.Builder message) {
+ message.setExtension(repeatedInt32ExtensionLite , 1, 501);
+ message.setExtension(repeatedInt64ExtensionLite , 1, 502L);
+ message.setExtension(repeatedUint32ExtensionLite , 1, 503);
+ message.setExtension(repeatedUint64ExtensionLite , 1, 504L);
+ message.setExtension(repeatedSint32ExtensionLite , 1, 505);
+ message.setExtension(repeatedSint64ExtensionLite , 1, 506L);
+ message.setExtension(repeatedFixed32ExtensionLite , 1, 507);
+ message.setExtension(repeatedFixed64ExtensionLite , 1, 508L);
+ message.setExtension(repeatedSfixed32ExtensionLite, 1, 509);
+ message.setExtension(repeatedSfixed64ExtensionLite, 1, 510L);
+ message.setExtension(repeatedFloatExtensionLite , 1, 511F);
+ message.setExtension(repeatedDoubleExtensionLite , 1, 512D);
+ message.setExtension(repeatedBoolExtensionLite , 1, true);
+ message.setExtension(repeatedStringExtensionLite , 1, "515");
+ message.setExtension(repeatedBytesExtensionLite , 1, toBytes("516"));
+
+ message.setExtension(repeatedGroupExtensionLite, 1,
+ RepeatedGroup_extension_lite.newBuilder().setA(517).build());
+ message.setExtension(repeatedNestedMessageExtensionLite, 1,
+ TestAllTypesLite.NestedMessage.newBuilder().setBb(518).build());
+ message.setExtension(repeatedForeignMessageExtensionLite, 1,
+ ForeignMessageLite.newBuilder().setC(519).build());
+ message.setExtension(repeatedImportMessageExtensionLite, 1,
+ ImportMessageLite.newBuilder().setD(520).build());
+ message.setExtension(repeatedLazyMessageExtensionLite, 1,
+ TestAllTypesLite.NestedMessage.newBuilder().setBb(527).build());
+
+ message.setExtension(repeatedNestedEnumExtensionLite , 1, TestAllTypesLite.NestedEnum.FOO);
+ message.setExtension(repeatedForeignEnumExtensionLite, 1, ForeignEnumLite.FOREIGN_LITE_FOO);
+ message.setExtension(repeatedImportEnumExtensionLite , 1, ImportEnumLite.IMPORT_LITE_FOO);
+
+ message.setExtension(repeatedStringPieceExtensionLite, 1, "524");
+ message.setExtension(repeatedCordExtensionLite, 1, "525");
+ }
+
+ public static void setPackedExtensions(TestPackedExtensionsLite.Builder message) {
+ message.addExtension(packedInt32ExtensionLite , 601);
+ message.addExtension(packedInt64ExtensionLite , 602L);
+ message.addExtension(packedUint32ExtensionLite , 603);
+ message.addExtension(packedUint64ExtensionLite , 604L);
+ message.addExtension(packedSint32ExtensionLite , 605);
+ message.addExtension(packedSint64ExtensionLite , 606L);
+ message.addExtension(packedFixed32ExtensionLite , 607);
+ message.addExtension(packedFixed64ExtensionLite , 608L);
+ message.addExtension(packedSfixed32ExtensionLite, 609);
+ message.addExtension(packedSfixed64ExtensionLite, 610L);
+ message.addExtension(packedFloatExtensionLite , 611F);
+ message.addExtension(packedDoubleExtensionLite , 612D);
+ message.addExtension(packedBoolExtensionLite , true);
+ message.addExtension(packedEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAR);
+ // Add a second one of each field.
+ message.addExtension(packedInt32ExtensionLite , 701);
+ message.addExtension(packedInt64ExtensionLite , 702L);
+ message.addExtension(packedUint32ExtensionLite , 703);
+ message.addExtension(packedUint64ExtensionLite , 704L);
+ message.addExtension(packedSint32ExtensionLite , 705);
+ message.addExtension(packedSint64ExtensionLite , 706L);
+ message.addExtension(packedFixed32ExtensionLite , 707);
+ message.addExtension(packedFixed64ExtensionLite , 708L);
+ message.addExtension(packedSfixed32ExtensionLite, 709);
+ message.addExtension(packedSfixed64ExtensionLite, 710L);
+ message.addExtension(packedFloatExtensionLite , 711F);
+ message.addExtension(packedDoubleExtensionLite , 712D);
+ message.addExtension(packedBoolExtensionLite , false);
+ message.addExtension(packedEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAZ);
+ }
+}
diff --git a/java/core/src/test/java/com/google/protobuf/TextFormatParseInfoTreeTest.java b/java/core/src/test/java/com/google/protobuf/TextFormatParseInfoTreeTest.java
new file mode 100644
index 00000000..e338af21
--- /dev/null
+++ b/java/core/src/test/java/com/google/protobuf/TextFormatParseInfoTreeTest.java
@@ -0,0 +1,182 @@
+// 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.
+
+package com.google.protobuf;
+
+import com.google.protobuf.Descriptors.Descriptor;
+import com.google.protobuf.Descriptors.FieldDescriptor;
+import protobuf_unittest.UnittestProto.TestAllTypes;
+
+import junit.framework.TestCase;
+
+/**
+ * Test @{link TextFormatParseInfoTree}.
+ */
+public class TextFormatParseInfoTreeTest extends TestCase {
+
+ private static final Descriptor DESCRIPTOR = TestAllTypes.getDescriptor();
+ private static final FieldDescriptor OPTIONAL_INT32 =
+ DESCRIPTOR.findFieldByName("optional_int32");
+ private static final FieldDescriptor OPTIONAL_BOOLEAN =
+ DESCRIPTOR.findFieldByName("optional_boolean");
+ private static final FieldDescriptor REPEATED_INT32 =
+ DESCRIPTOR.findFieldByName("repeated_int32");
+ private static final FieldDescriptor OPTIONAL_NESTED_MESSAGE =
+ DESCRIPTOR.findFieldByName("optional_nested_message");
+ private static final FieldDescriptor REPEATED_NESTED_MESSAGE =
+ DESCRIPTOR.findFieldByName("repeated_nested_message");
+ private static final FieldDescriptor FIELD_BB =
+ TestAllTypes.NestedMessage.getDescriptor().findFieldByName("bb");
+
+ private static final TextFormatParseLocation LOC0 = TextFormatParseLocation.create(1, 2);
+ private static final TextFormatParseLocation LOC1 = TextFormatParseLocation.create(2, 3);
+
+ private TextFormatParseInfoTree.Builder rootBuilder;
+
+ @Override
+ public void setUp() {
+ rootBuilder = TextFormatParseInfoTree.builder();
+ }
+
+ public void testBuildEmptyParseTree() {
+ TextFormatParseInfoTree tree = rootBuilder.build();
+ assertTrue(tree.getLocations(null).isEmpty());
+ }
+
+ public void testGetLocationReturnsSingleLocation() {
+ rootBuilder.setLocation(OPTIONAL_INT32, LOC0);
+ TextFormatParseInfoTree root = rootBuilder.build();
+ assertEquals(LOC0, root.getLocation(OPTIONAL_INT32, 0));
+ assertEquals(1, root.getLocations(OPTIONAL_INT32).size());
+ }
+
+ public void testGetLocationsReturnsNoParseLocationsForUnknownField() {
+ assertTrue(rootBuilder.build().getLocations(OPTIONAL_INT32).isEmpty());
+ rootBuilder.setLocation(OPTIONAL_BOOLEAN, LOC0);
+ TextFormatParseInfoTree root = rootBuilder.build();
+ assertTrue(root.getLocations(OPTIONAL_INT32).isEmpty());
+ assertEquals(LOC0, root.getLocations(OPTIONAL_BOOLEAN).get(0));
+ }
+
+ public void testGetLocationThrowsIllegalArgumentExceptionForUnknownField() {
+ rootBuilder.setLocation(REPEATED_INT32, LOC0);
+ TextFormatParseInfoTree root = rootBuilder.build();
+ try {
+ root.getNestedTree(OPTIONAL_INT32, 0);
+ fail("Did not detect unknown field");
+ } catch (IllegalArgumentException expected) {
+ // pass
+ }
+ }
+
+ public void testGetLocationThrowsIllegalArgumentExceptionForInvalidIndex() {
+ TextFormatParseInfoTree root = rootBuilder.setLocation(OPTIONAL_INT32, LOC0).build();
+ try {
+ root.getLocation(OPTIONAL_INT32, 1);
+ fail("Invalid index not detected");
+ } catch (IllegalArgumentException expected) {
+ // pass
+ }
+ try {
+ root.getLocation(OPTIONAL_INT32, -1);
+ fail("Negative index not detected");
+ } catch (IllegalArgumentException expected) {
+ // pass
+ }
+ }
+
+ public void testGetLocationsReturnsMultipleLocations() {
+ rootBuilder.setLocation(REPEATED_INT32, LOC0);
+ rootBuilder.setLocation(REPEATED_INT32, LOC1);
+ TextFormatParseInfoTree root = rootBuilder.build();
+ assertEquals(LOC0, root.getLocation(REPEATED_INT32, 0));
+ assertEquals(LOC1, root.getLocation(REPEATED_INT32, 1));
+ assertEquals(2, root.getLocations(REPEATED_INT32).size());
+ }
+
+ public void testGetNestedTreeThrowsIllegalArgumentExceptionForUnknownField() {
+ rootBuilder.setLocation(REPEATED_INT32, LOC0);
+ TextFormatParseInfoTree root = rootBuilder.build();
+ try {
+ root.getNestedTree(OPTIONAL_NESTED_MESSAGE, 0);
+ fail("Did not detect unknown field");
+ } catch (IllegalArgumentException expected) {
+ // pass
+ }
+ }
+
+ public void testGetNestedTreesReturnsNoParseInfoTreesForUnknownField() {
+ rootBuilder.setLocation(REPEATED_INT32, LOC0);
+ TextFormatParseInfoTree root = rootBuilder.build();
+ assertTrue(root.getNestedTrees(OPTIONAL_NESTED_MESSAGE).isEmpty());
+ }
+
+ public void testGetNestedTreeThrowsIllegalArgumentExceptionForInvalidIndex() {
+ rootBuilder.setLocation(REPEATED_INT32, LOC0);
+ rootBuilder.getBuilderForSubMessageField(OPTIONAL_NESTED_MESSAGE);
+ TextFormatParseInfoTree root = rootBuilder.build();
+ try {
+ root.getNestedTree(OPTIONAL_NESTED_MESSAGE, 1);
+ fail("Submessage index that is too large not detected");
+ } catch (IllegalArgumentException expected) {
+ // pass
+ }
+ try {
+ rootBuilder.build().getNestedTree(OPTIONAL_NESTED_MESSAGE, -1);
+ fail("Invalid submessage index (-1) not detected");
+ } catch (IllegalArgumentException expected) {
+ // pass
+ }
+ }
+
+ public void testGetNestedTreesReturnsSingleTree() {
+ rootBuilder.getBuilderForSubMessageField(OPTIONAL_NESTED_MESSAGE);
+ TextFormatParseInfoTree root = rootBuilder.build();
+ assertEquals(1, root.getNestedTrees(OPTIONAL_NESTED_MESSAGE).size());
+ TextFormatParseInfoTree subtree = root.getNestedTrees(OPTIONAL_NESTED_MESSAGE).get(0);
+ assertNotNull(subtree);
+ }
+
+ public void testGetNestedTreesReturnsMultipleTrees() {
+ TextFormatParseInfoTree.Builder subtree1Builder =
+ rootBuilder.getBuilderForSubMessageField(REPEATED_NESTED_MESSAGE);
+ subtree1Builder.getBuilderForSubMessageField(FIELD_BB);
+ subtree1Builder.getBuilderForSubMessageField(FIELD_BB);
+ TextFormatParseInfoTree.Builder subtree2Builder =
+ rootBuilder.getBuilderForSubMessageField(REPEATED_NESTED_MESSAGE);
+ subtree2Builder.getBuilderForSubMessageField(FIELD_BB);
+ TextFormatParseInfoTree root = rootBuilder.build();
+ assertEquals(2, root.getNestedTrees(REPEATED_NESTED_MESSAGE).size());
+ assertEquals(
+ 2, root.getNestedTrees(REPEATED_NESTED_MESSAGE).get(0).getNestedTrees(FIELD_BB).size());
+ assertEquals(
+ 1, root.getNestedTrees(REPEATED_NESTED_MESSAGE).get(1).getNestedTrees(FIELD_BB).size());
+ }
+}
diff --git a/java/core/src/test/java/com/google/protobuf/TextFormatParseLocationTest.java b/java/core/src/test/java/com/google/protobuf/TextFormatParseLocationTest.java
new file mode 100644
index 00000000..c42bfa6e
--- /dev/null
+++ b/java/core/src/test/java/com/google/protobuf/TextFormatParseLocationTest.java
@@ -0,0 +1,86 @@
+// 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.
+
+package com.google.protobuf;
+
+import junit.framework.TestCase;
+
+/**
+ * Test @{link TextFormatParseLocation}.
+ */
+public class TextFormatParseLocationTest extends TestCase {
+
+ public void testCreateEmpty() {
+ TextFormatParseLocation location = TextFormatParseLocation.create(-1, -1);
+ assertEquals(TextFormatParseLocation.EMPTY, location);
+ }
+
+ public void testCreate() {
+ TextFormatParseLocation location = TextFormatParseLocation.create(2, 1);
+ assertEquals(2, location.getLine());
+ assertEquals(1, location.getColumn());
+ }
+
+ public void testCreateThrowsIllegalArgumentExceptionForInvalidIndex() {
+ try {
+ TextFormatParseLocation.create(-1, 0);
+ fail("Should throw IllegalArgumentException if line is less than 0");
+ } catch (IllegalArgumentException unused) {
+ // pass
+ }
+ try {
+ TextFormatParseLocation.create(0, -1);
+ fail("Should throw, column < 0");
+ } catch (IllegalArgumentException unused) {
+ // pass
+ }
+ }
+
+ public void testHashCode() {
+ TextFormatParseLocation loc0 = TextFormatParseLocation.create(2, 1);
+ TextFormatParseLocation loc1 = TextFormatParseLocation.create(2, 1);
+
+ assertEquals(loc0.hashCode(), loc1.hashCode());
+ assertEquals(
+ TextFormatParseLocation.EMPTY.hashCode(), TextFormatParseLocation.EMPTY.hashCode());
+ }
+
+ public void testEquals() {
+ TextFormatParseLocation loc0 = TextFormatParseLocation.create(2, 1);
+ TextFormatParseLocation loc1 = TextFormatParseLocation.create(1, 2);
+ TextFormatParseLocation loc2 = TextFormatParseLocation.create(2, 2);
+ TextFormatParseLocation loc3 = TextFormatParseLocation.create(2, 1);
+
+ assertEquals(loc0, loc3);
+ assertNotSame(loc0, loc1);
+ assertNotSame(loc0, loc2);
+ assertNotSame(loc1, loc2);
+ }
+}
diff --git a/java/src/test/java/com/google/protobuf/TextFormatTest.java b/java/core/src/test/java/com/google/protobuf/TextFormatTest.java
index 1df4fad7..14783b0a 100644
--- a/java/src/test/java/com/google/protobuf/TextFormatTest.java
+++ b/java/core/src/test/java/com/google/protobuf/TextFormatTest.java
@@ -30,6 +30,7 @@
package com.google.protobuf;
+import com.google.protobuf.Descriptors.Descriptor;
import com.google.protobuf.Descriptors.FieldDescriptor;
import com.google.protobuf.TextFormat.Parser.SingularOverwritePolicy;
import protobuf_unittest.UnittestMset.TestMessageSetExtension1;
@@ -45,6 +46,7 @@ import proto2_wireformat_unittest.UnittestMsetWireFormat.TestMessageSet;
import junit.framework.TestCase;
import java.io.StringReader;
+import java.util.List;
/**
* Test case for {@link TextFormat}.
@@ -520,15 +522,16 @@ public class TextFormatTest extends TestCase {
"optional_string: \"ueoauaoe\n" +
"optional_int32: 123");
assertParseError(
- "1:2: Extension \"nosuchext\" not found in the ExtensionRegistry.",
+ "1:2: Input contains unknown fields and/or extensions:\n" +
+ "1:2:\tprotobuf_unittest.TestAllTypes.[nosuchext]",
"[nosuchext]: 123");
assertParseError(
"1:20: Extension \"protobuf_unittest.optional_int32_extension\" does " +
"not extend message type \"protobuf_unittest.TestAllTypes\".",
"[protobuf_unittest.optional_int32_extension]: 123");
assertParseError(
- "1:1: Message type \"protobuf_unittest.TestAllTypes\" has no field " +
- "named \"nosuchfield\".",
+ "1:1: Input contains unknown fields and/or extensions:\n" +
+ "1:1:\tprotobuf_unittest.TestAllTypes.nosuchfield",
"nosuchfield: 123");
assertParseError(
"1:21: Expected \">\".",
@@ -568,6 +571,16 @@ public class TextFormatTest extends TestCase {
assertEquals(kEscapeTestString,
TextFormat.unescapeText(kEscapeTestStringEscaped));
+ // Invariant
+ assertEquals("hello",
+ TextFormat.escapeBytes(bytes("hello")));
+ assertEquals("hello",
+ TextFormat.escapeText("hello"));
+ assertEquals(bytes("hello"),
+ TextFormat.unescapeBytes("hello"));
+ assertEquals("hello",
+ TextFormat.unescapeText("hello"));
+
// Unicode handling.
assertEquals("\\341\\210\\264", TextFormat.escapeText("\u1234"));
assertEquals("\\341\\210\\264",
@@ -763,11 +776,14 @@ public class TextFormatTest extends TestCase {
public void testParseBoolean() throws Exception {
String goodText =
"repeated_bool: t repeated_bool : 0\n" +
- "repeated_bool :f repeated_bool:1";
+ "repeated_bool :f repeated_bool:1\n" +
+ "repeated_bool: False repeated_bool: True";
String goodTextCanonical =
"repeated_bool: true\n" +
"repeated_bool: false\n" +
"repeated_bool: false\n" +
+ "repeated_bool: true\n" +
+ "repeated_bool: false\n" +
"repeated_bool: true\n";
TestAllTypes.Builder builder = TestAllTypes.newBuilder();
TextFormat.merge(goodText, builder);
@@ -811,7 +827,6 @@ public class TextFormatTest extends TestCase {
private void assertPrintFieldValue(String expect, Object value,
String fieldName) throws Exception {
- TestAllTypes.Builder builder = TestAllTypes.newBuilder();
StringBuilder sb = new StringBuilder();
TextFormat.printFieldValue(
TestAllTypes.getDescriptor().findFieldByName(fieldName),
@@ -1018,4 +1033,98 @@ public class TextFormatTest extends TestCase {
assertFalse(oneof.hasFooString());
assertTrue(oneof.hasFooInt());
}
+
+ // =======================================================================
+ // test location information
+
+ public void testParseInfoTreeBuilding() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+
+ Descriptor descriptor = TestAllTypes.getDescriptor();
+ TextFormatParseInfoTree.Builder treeBuilder = TextFormatParseInfoTree.builder();
+ // Set to allow unknown fields
+ TextFormat.Parser parser =
+ TextFormat.Parser.newBuilder()
+ .setParseInfoTreeBuilder(treeBuilder)
+ .build();
+
+ final String stringData =
+ "optional_int32: 1\n"
+ + "optional_int64: 2\n"
+ + " optional_double: 2.4\n"
+ + "repeated_int32: 5\n"
+ + "repeated_int32: 10\n"
+ + "optional_nested_message <\n"
+ + " bb: 78\n"
+ + ">\n"
+ + "repeated_nested_message <\n"
+ + " bb: 79\n"
+ + ">\n"
+ + "repeated_nested_message <\n"
+ + " bb: 80\n"
+ + ">";
+
+ parser.merge(stringData, builder);
+ TextFormatParseInfoTree tree = treeBuilder.build();
+
+ // Verify that the tree has the correct positions.
+ assertLocation(tree, descriptor, "optional_int32", 0, 0, 0);
+ assertLocation(tree, descriptor, "optional_int64", 0, 1, 0);
+ assertLocation(tree, descriptor, "optional_double", 0, 2, 2);
+
+ assertLocation(tree, descriptor, "repeated_int32", 0, 3, 0);
+ assertLocation(tree, descriptor, "repeated_int32", 1, 4, 0);
+
+ assertLocation(tree, descriptor, "optional_nested_message", 0, 5, 0);
+ assertLocation(tree, descriptor, "repeated_nested_message", 0, 8, 0);
+ assertLocation(tree, descriptor, "repeated_nested_message", 1, 11, 0);
+
+ // Check for fields not set. For an invalid field, the location returned should be -1, -1.
+ assertLocation(tree, descriptor, "repeated_int64", 0, -1, -1);
+ assertLocation(tree, descriptor, "repeated_int32", 6, -1, -1);
+
+ // Verify inside the nested message.
+ FieldDescriptor nestedField = descriptor.findFieldByName("optional_nested_message");
+
+ TextFormatParseInfoTree nestedTree = tree.getNestedTrees(nestedField).get(0);
+ assertLocation(nestedTree, nestedField.getMessageType(), "bb", 0, 6, 2);
+
+ // Verify inside another nested message.
+ nestedField = descriptor.findFieldByName("repeated_nested_message");
+ nestedTree = tree.getNestedTrees(nestedField).get(0);
+ assertLocation(nestedTree, nestedField.getMessageType(), "bb", 0, 9, 2);
+
+ nestedTree = tree.getNestedTrees(nestedField).get(1);
+ assertLocation(nestedTree, nestedField.getMessageType(), "bb", 0, 12, 2);
+
+ // Verify a NULL tree for an unknown nested field.
+ try {
+ tree.getNestedTree(nestedField, 2);
+ fail("unknown nested field should throw");
+ } catch (IllegalArgumentException unused) {
+ // pass
+ }
+ }
+
+ private void assertLocation(
+ TextFormatParseInfoTree tree,
+ final Descriptor descriptor,
+ final String fieldName,
+ int index,
+ int line,
+ int column) {
+ List<TextFormatParseLocation> locs = tree.getLocations(descriptor.findFieldByName(fieldName));
+ if (index < locs.size()) {
+ TextFormatParseLocation location = locs.get(index);
+ TextFormatParseLocation expected = TextFormatParseLocation.create(line, column);
+ assertEquals(expected, location);
+ } else if (line != -1 && column != -1) {
+ fail(
+ String.format(
+ "Tree/descriptor/fieldname did not contain index %d, line %d column %d expected",
+ index,
+ line,
+ column));
+ }
+ }
}
diff --git a/java/src/test/java/com/google/protobuf/UnknownEnumValueTest.java b/java/core/src/test/java/com/google/protobuf/UnknownEnumValueTest.java
index 8f45976f..8f45976f 100644
--- a/java/src/test/java/com/google/protobuf/UnknownEnumValueTest.java
+++ b/java/core/src/test/java/com/google/protobuf/UnknownEnumValueTest.java
diff --git a/java/src/test/java/com/google/protobuf/UnknownFieldSetLiteTest.java b/java/core/src/test/java/com/google/protobuf/UnknownFieldSetLiteTest.java
index dc987379..573cd665 100644
--- a/java/src/test/java/com/google/protobuf/UnknownFieldSetLiteTest.java
+++ b/java/core/src/test/java/com/google/protobuf/UnknownFieldSetLiteTest.java
@@ -47,46 +47,6 @@ import java.io.IOException;
* @author dweis@google.com (Daniel Weis)
*/
public class UnknownFieldSetLiteTest extends TestCase {
-
- public void testNoDataIsDefaultInstance() {
- assertSame(
- UnknownFieldSetLite.getDefaultInstance(),
- UnknownFieldSetLite.newBuilder()
- .build());
- }
-
- public void testBuilderReuse() throws IOException {
- UnknownFieldSetLite.Builder builder = UnknownFieldSetLite.newBuilder();
- builder.mergeVarintField(10, 2);
- builder.build();
-
- try {
- builder.build();
- fail();
- } catch (UnsupportedOperationException e) {
- // Expected.
- }
-
- try {
- builder.mergeFieldFrom(0, CodedInputStream.newInstance(new byte[0]));
- fail();
- } catch (UnsupportedOperationException e) {
- // Expected.
- }
-
- try {
- builder.mergeVarintField(5, 1);
- fail();
- } catch (UnsupportedOperationException e) {
- // Expected.
- }
- }
-
- public void testBuilderReuse_empty() {
- UnknownFieldSetLite.Builder builder = UnknownFieldSetLite.newBuilder();
- builder.build();
- builder.build();
- }
public void testDefaultInstance() {
UnknownFieldSetLite unknownFields = UnknownFieldSetLite.getDefaultInstance();
diff --git a/java/src/test/java/com/google/protobuf/UnknownFieldSetTest.java b/java/core/src/test/java/com/google/protobuf/UnknownFieldSetTest.java
index 8c9dcafe..32380f70 100644
--- a/java/src/test/java/com/google/protobuf/UnknownFieldSetTest.java
+++ b/java/core/src/test/java/com/google/protobuf/UnknownFieldSetTest.java
@@ -50,6 +50,7 @@ import java.util.Map;
* @author kenton@google.com (Kenton Varda)
*/
public class UnknownFieldSetTest extends TestCase {
+ @Override
public void setUp() throws Exception {
descriptor = TestAllTypes.getDescriptor();
allFields = TestUtil.getAllSet();
diff --git a/java/src/test/java/com/google/protobuf/UnmodifiableLazyStringListTest.java b/java/core/src/test/java/com/google/protobuf/UnmodifiableLazyStringListTest.java
index b1c75fc3..b1c75fc3 100644
--- a/java/src/test/java/com/google/protobuf/UnmodifiableLazyStringListTest.java
+++ b/java/core/src/test/java/com/google/protobuf/UnmodifiableLazyStringListTest.java
diff --git a/java/src/test/java/com/google/protobuf/WellKnownTypesTest.java b/java/core/src/test/java/com/google/protobuf/WellKnownTypesTest.java
index 982e200f..982e200f 100644
--- a/java/src/test/java/com/google/protobuf/WellKnownTypesTest.java
+++ b/java/core/src/test/java/com/google/protobuf/WellKnownTypesTest.java
diff --git a/java/src/test/java/com/google/protobuf/WireFormatTest.java b/java/core/src/test/java/com/google/protobuf/WireFormatTest.java
index 0175005d..e66b371c 100644
--- a/java/src/test/java/com/google/protobuf/WireFormatTest.java
+++ b/java/core/src/test/java/com/google/protobuf/WireFormatTest.java
@@ -30,12 +30,11 @@
package com.google.protobuf;
-import junit.framework.TestCase;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.util.List;
-
+import com.google.protobuf.UnittestLite.TestAllExtensionsLite;
+import com.google.protobuf.UnittestLite.TestPackedExtensionsLite;
+import protobuf_unittest.UnittestMset.RawMessageSet;
+import protobuf_unittest.UnittestMset.TestMessageSetExtension1;
+import protobuf_unittest.UnittestMset.TestMessageSetExtension2;
import protobuf_unittest.UnittestProto;
import protobuf_unittest.UnittestProto.TestAllExtensions;
import protobuf_unittest.UnittestProto.TestAllTypes;
@@ -44,12 +43,13 @@ import protobuf_unittest.UnittestProto.TestOneof2;
import protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible;
import protobuf_unittest.UnittestProto.TestPackedExtensions;
import protobuf_unittest.UnittestProto.TestPackedTypes;
-import protobuf_unittest.UnittestMset.RawMessageSet;
-import protobuf_unittest.UnittestMset.TestMessageSetExtension1;
-import protobuf_unittest.UnittestMset.TestMessageSetExtension2;
import proto2_wireformat_unittest.UnittestMsetWireFormat.TestMessageSet;
-import com.google.protobuf.UnittestLite.TestAllExtensionsLite;
-import com.google.protobuf.UnittestLite.TestPackedExtensionsLite;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.util.List;
/**
* Tests related to parsing and serialization.
@@ -132,7 +132,7 @@ public class WireFormatTest extends TestCase {
// so if we serialize a TestAllExtensions then parse it as TestAllTypes
// it should work.
- TestAllExtensionsLite message = TestUtil.getAllLiteExtensionsSet();
+ TestAllExtensionsLite message = TestUtilLite.getAllLiteExtensionsSet();
ByteString rawBytes = message.toByteString();
assertEquals(rawBytes.size(), message.getSerializedSize());
@@ -144,7 +144,7 @@ public class WireFormatTest extends TestCase {
public void testSerializePackedExtensionsLite() throws Exception {
// TestPackedTypes and TestPackedExtensions should have compatible wire
// formats; check that they serialize to the same string.
- TestPackedExtensionsLite message = TestUtil.getLitePackedExtensionsSet();
+ TestPackedExtensionsLite message = TestUtilLite.getLitePackedExtensionsSet();
ByteString rawBytes = message.toByteString();
TestPackedTypes message2 = TestUtil.getPackedSet();
@@ -190,7 +190,7 @@ public class WireFormatTest extends TestCase {
TestAllTypes message = TestUtil.getAllSet();
ByteString rawBytes = message.toByteString();
- ExtensionRegistryLite registry_lite = TestUtil.getExtensionRegistryLite();
+ ExtensionRegistryLite registry_lite = TestUtilLite.getExtensionRegistryLite();
TestAllExtensionsLite message2 =
TestAllExtensionsLite.parseFrom(rawBytes, registry_lite);
@@ -208,10 +208,10 @@ public class WireFormatTest extends TestCase {
public void testParsePackedExtensionsLite() throws Exception {
// Ensure that packed extensions can be properly parsed.
- TestPackedExtensionsLite message = TestUtil.getLitePackedExtensionsSet();
+ TestPackedExtensionsLite message = TestUtilLite.getLitePackedExtensionsSet();
ByteString rawBytes = message.toByteString();
- ExtensionRegistryLite registry = TestUtil.getExtensionRegistryLite();
+ ExtensionRegistryLite registry = TestUtilLite.getExtensionRegistryLite();
TestPackedExtensionsLite message2 =
TestPackedExtensionsLite.parseFrom(rawBytes, registry);
diff --git a/java/src/test/java/com/google/protobuf/any_test.proto b/java/core/src/test/proto/com/google/protobuf/any_test.proto
index 80173d8a..80173d8a 100644
--- a/java/src/test/java/com/google/protobuf/any_test.proto
+++ b/java/core/src/test/proto/com/google/protobuf/any_test.proto
diff --git a/java/src/test/java/com/google/protobuf/field_presence_test.proto b/java/core/src/test/proto/com/google/protobuf/field_presence_test.proto
index 8f3ca8c6..86cdd286 100644
--- a/java/src/test/java/com/google/protobuf/field_presence_test.proto
+++ b/java/core/src/test/proto/com/google/protobuf/field_presence_test.proto
@@ -54,6 +54,7 @@ message TestAllTypes {
NestedEnum optional_nested_enum = 4;
NestedMessage optional_nested_message = 5;
protobuf_unittest.TestRequired optional_proto2_message = 6;
+ NestedMessage optional_lazy_message = 7 [lazy=true];
oneof oneof_field {
int32 oneof_int32 = 11;
@@ -81,6 +82,7 @@ message TestOptionalFieldsOnly {
TestAllTypes.NestedEnum optional_nested_enum = 4;
TestAllTypes.NestedMessage optional_nested_message = 5;
protobuf_unittest.TestRequired optional_proto2_message = 6;
+ TestAllTypes.NestedMessage optional_lazy_message = 7 [lazy=true];
}
message TestRepeatedFieldsOnly {
diff --git a/java/src/test/java/com/google/protobuf/lazy_fields_lite.proto b/java/core/src/test/proto/com/google/protobuf/lazy_fields_lite.proto
index 5580f72d..5580f72d 100644
--- a/java/src/test/java/com/google/protobuf/lazy_fields_lite.proto
+++ b/java/core/src/test/proto/com/google/protobuf/lazy_fields_lite.proto
diff --git a/java/src/test/java/com/google/protobuf/lite_equals_and_hash.proto b/java/core/src/test/proto/com/google/protobuf/lite_equals_and_hash.proto
index 86837250..6eef42c5 100644
--- a/java/src/test/java/com/google/protobuf/lite_equals_and_hash.proto
+++ b/java/core/src/test/proto/com/google/protobuf/lite_equals_and_hash.proto
@@ -34,11 +34,15 @@ syntax = "proto2";
package protobuf_unittest.lite_equals_and_hash;
-// This proto definition is used to test that java_generate_equals_and_hash
-// works correctly with the LITE_RUNTIME.
-option java_generate_equals_and_hash = true;
option optimize_for = LITE_RUNTIME;
+message TestOneofEquals {
+ oneof oneof_field {
+ string name = 1;
+ int32 value = 2;
+ }
+}
+
message Foo {
optional int32 value = 1;
repeated Bar bar = 2;
@@ -70,3 +74,8 @@ extend Foo {
}
}
+message TestRecursiveOneof {
+ oneof Foo {
+ TestRecursiveOneof r = 1;
+ }
+}
diff --git a/java/src/test/java/com/google/protobuf/map_for_proto2_lite_test.proto b/java/core/src/test/proto/com/google/protobuf/map_for_proto2_lite_test.proto
index d5418f28..de3336a5 100644
--- a/java/src/test/java/com/google/protobuf/map_for_proto2_lite_test.proto
+++ b/java/core/src/test/proto/com/google/protobuf/map_for_proto2_lite_test.proto
@@ -70,6 +70,17 @@ message TestRecursiveMap {
optional int32 value = 1;
map<int32, TestRecursiveMap> recursive_map_field = 2;
}
+
+
+// a decoy of TestMap for testing parsing errors
+message BizarroTestMap {
+ map<int32, bytes> int32_to_int32_field = 1; // same key type, different value
+ map<string, int32> int32_to_string_field = 2; // different key and value types
+ map<string, int32> int32_to_bytes_field = 3; // different key types, same value
+ map<string, bytes> int32_to_enum_field = 4; // different key and value types
+ map<string, bytes> int32_to_message_field = 5; // different key and value types
+ map<string, bytes> string_to_int32_field = 6; // same key type, different value
+}
package map_for_proto2_lite_test;
option java_package = "map_lite_test";
option optimize_for = LITE_RUNTIME;
diff --git a/java/src/test/java/com/google/protobuf/map_for_proto2_test.proto b/java/core/src/test/proto/com/google/protobuf/map_for_proto2_test.proto
index a9be5166..0c92b0ae 100644
--- a/java/src/test/java/com/google/protobuf/map_for_proto2_test.proto
+++ b/java/core/src/test/proto/com/google/protobuf/map_for_proto2_test.proto
@@ -72,3 +72,14 @@ message TestRecursiveMap {
optional int32 value = 1;
map<int32, TestRecursiveMap> recursive_map_field = 2;
}
+
+
+// a decoy of TestMap for testing parsing errors
+message BizarroTestMap {
+ map<int32, bytes> int32_to_int32_field = 1; // same key type, different value
+ map<string, int32> int32_to_string_field = 2; // different key and value types
+ map<string, int32> int32_to_bytes_field = 3; // different key types, same value
+ map<string, bytes> int32_to_enum_field = 4; // different key and value types
+ map<string, bytes> int32_to_message_field = 5; // different key and value types
+ map<string, bytes> string_to_int32_field = 6; // same key type, different value
+}
diff --git a/java/src/test/java/com/google/protobuf/map_initialization_order_test.proto b/java/core/src/test/proto/com/google/protobuf/map_initialization_order_test.proto
index b02ac599..b02ac599 100644
--- a/java/src/test/java/com/google/protobuf/map_initialization_order_test.proto
+++ b/java/core/src/test/proto/com/google/protobuf/map_initialization_order_test.proto
diff --git a/java/src/test/java/com/google/protobuf/map_test.proto b/java/core/src/test/proto/com/google/protobuf/map_test.proto
index 2f7709be..9eb63fc3 100644
--- a/java/src/test/java/com/google/protobuf/map_test.proto
+++ b/java/core/src/test/proto/com/google/protobuf/map_test.proto
@@ -36,7 +36,6 @@ option java_package = "map_test";
option java_outer_classname = "MapTestProto";
option java_generate_equals_and_hash = true;
-
message TestMap {
message MessageValue {
int32 value = 1;
@@ -56,9 +55,19 @@ message TestMap {
map<string, int32> string_to_int32_field = 6;
}
-// Used to test that a nested bulider containing map fields will properly
+// Used to test that a nested builder containing map fields will properly
// propagate the onChange event and mark its parent dirty when a change
// is made to a map field.
message TestOnChangeEventPropagation {
TestMap optional_message = 1;
}
+
+// a decoy of TestMap for testing parsing errors
+message BizarroTestMap {
+ map<int32, bytes> int32_to_int32_field = 1; // same key type, different value
+ map<string, int32> int32_to_string_field = 2; // different key and value types
+ map<string, int32> int32_to_bytes_field = 3; // different key types, same value
+ map<string, bytes> int32_to_enum_field = 4; // different key and value types
+ map<string, bytes> int32_to_message_field = 5; // different key and value types
+ map<string, bytes> string_to_int32_field = 6; // same key type, different value
+}
diff --git a/java/src/test/java/com/google/protobuf/multiple_files_test.proto b/java/core/src/test/proto/com/google/protobuf/multiple_files_test.proto
index 92790506..92790506 100644
--- a/java/src/test/java/com/google/protobuf/multiple_files_test.proto
+++ b/java/core/src/test/proto/com/google/protobuf/multiple_files_test.proto
diff --git a/java/src/test/java/com/google/protobuf/nested_builders_test.proto b/java/core/src/test/proto/com/google/protobuf/nested_builders_test.proto
index a5dd66d8..a5dd66d8 100644
--- a/java/src/test/java/com/google/protobuf/nested_builders_test.proto
+++ b/java/core/src/test/proto/com/google/protobuf/nested_builders_test.proto
diff --git a/java/src/test/java/com/google/protobuf/nested_extension.proto b/java/core/src/test/proto/com/google/protobuf/nested_extension.proto
index 704e649e..704e649e 100644
--- a/java/src/test/java/com/google/protobuf/nested_extension.proto
+++ b/java/core/src/test/proto/com/google/protobuf/nested_extension.proto
diff --git a/java/src/test/java/com/google/protobuf/nested_extension_lite.proto b/java/core/src/test/proto/com/google/protobuf/nested_extension_lite.proto
index a95c38b2..a95c38b2 100644
--- a/java/src/test/java/com/google/protobuf/nested_extension_lite.proto
+++ b/java/core/src/test/proto/com/google/protobuf/nested_extension_lite.proto
diff --git a/java/src/test/java/com/google/protobuf/non_nested_extension.proto b/java/core/src/test/proto/com/google/protobuf/non_nested_extension.proto
index 31fac552..31fac552 100644
--- a/java/src/test/java/com/google/protobuf/non_nested_extension.proto
+++ b/java/core/src/test/proto/com/google/protobuf/non_nested_extension.proto
diff --git a/java/src/test/java/com/google/protobuf/non_nested_extension_lite.proto b/java/core/src/test/proto/com/google/protobuf/non_nested_extension_lite.proto
index 37c369ed..37c369ed 100644
--- a/java/src/test/java/com/google/protobuf/non_nested_extension_lite.proto
+++ b/java/core/src/test/proto/com/google/protobuf/non_nested_extension_lite.proto
diff --git a/java/src/test/java/com/google/protobuf/outer_class_name_test.proto b/java/core/src/test/proto/com/google/protobuf/outer_class_name_test.proto
index 42083681..42083681 100644
--- a/java/src/test/java/com/google/protobuf/outer_class_name_test.proto
+++ b/java/core/src/test/proto/com/google/protobuf/outer_class_name_test.proto
diff --git a/java/src/test/java/com/google/protobuf/outer_class_name_test2.proto b/java/core/src/test/proto/com/google/protobuf/outer_class_name_test2.proto
index 3e5956b0..3e5956b0 100644
--- a/java/src/test/java/com/google/protobuf/outer_class_name_test2.proto
+++ b/java/core/src/test/proto/com/google/protobuf/outer_class_name_test2.proto
diff --git a/java/src/test/java/com/google/protobuf/outer_class_name_test3.proto b/java/core/src/test/proto/com/google/protobuf/outer_class_name_test3.proto
index 74a8ba3c..74a8ba3c 100644
--- a/java/src/test/java/com/google/protobuf/outer_class_name_test3.proto
+++ b/java/core/src/test/proto/com/google/protobuf/outer_class_name_test3.proto
diff --git a/java/src/test/java/com/google/protobuf/test_bad_identifiers.proto b/java/core/src/test/proto/com/google/protobuf/test_bad_identifiers.proto
index 8c37c03c..2b1f65e4 100644
--- a/java/src/test/java/com/google/protobuf/test_bad_identifiers.proto
+++ b/java/core/src/test/proto/com/google/protobuf/test_bad_identifiers.proto
@@ -45,7 +45,6 @@ option java_package = "com.google.protobuf";
option java_outer_classname = "TestBadIdentifiersProto";
option java_generate_equals_and_hash = true;
-
message TestMessage {
optional string cached_size = 1;
optional string serialized_size = 2;
diff --git a/java/src/test/java/com/google/protobuf/test_check_utf8.proto b/java/core/src/test/proto/com/google/protobuf/test_check_utf8.proto
index 119c1dcb..119c1dcb 100644
--- a/java/src/test/java/com/google/protobuf/test_check_utf8.proto
+++ b/java/core/src/test/proto/com/google/protobuf/test_check_utf8.proto
diff --git a/java/src/test/java/com/google/protobuf/test_check_utf8_size.proto b/java/core/src/test/proto/com/google/protobuf/test_check_utf8_size.proto
index f06d76d6..f06d76d6 100644
--- a/java/src/test/java/com/google/protobuf/test_check_utf8_size.proto
+++ b/java/core/src/test/proto/com/google/protobuf/test_check_utf8_size.proto
diff --git a/java/src/test/java/com/google/protobuf/test_custom_options.proto b/java/core/src/test/proto/com/google/protobuf/test_custom_options.proto
index f8efd455..f8efd455 100644
--- a/java/src/test/java/com/google/protobuf/test_custom_options.proto
+++ b/java/core/src/test/proto/com/google/protobuf/test_custom_options.proto
diff --git a/java/src/test/java/com/google/protobuf/test_extra_interfaces.proto b/java/core/src/test/proto/com/google/protobuf/test_extra_interfaces.proto
index 645f57b4..645f57b4 100644
--- a/java/src/test/java/com/google/protobuf/test_extra_interfaces.proto
+++ b/java/core/src/test/proto/com/google/protobuf/test_extra_interfaces.proto
diff --git a/java/lite/generate-sources-build.xml b/java/lite/generate-sources-build.xml
new file mode 100644
index 00000000..89c21c13
--- /dev/null
+++ b/java/lite/generate-sources-build.xml
@@ -0,0 +1,20 @@
+<project name="generate-sources">
+ <echo message="Running protoc ..."/>
+ <mkdir dir="${generated.sources.lite.dir}"/>
+ <exec executable="${protoc}">
+ <arg value="--java_out=lite:${generated.sources.lite.dir}"/>
+ <arg value="--proto_path=${protobuf.source.dir}"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/any.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/api.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/descriptor.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/duration.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/empty.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/field_mask.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/source_context.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/struct.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/timestamp.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/type.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/wrappers.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/compiler/plugin.proto"/>
+ </exec>
+</project>
diff --git a/java/lite/generate-test-sources-build.xml b/java/lite/generate-test-sources-build.xml
new file mode 100644
index 00000000..cdd1ee89
--- /dev/null
+++ b/java/lite/generate-test-sources-build.xml
@@ -0,0 +1,43 @@
+<project name="generate-test-sources">
+ <mkdir dir="${generated.testsources.lite.dir}"/>
+ <exec executable="${protoc}">
+ <arg value="--java_out=lite:${generated.testsources.lite.dir}"/>
+ <arg value="--proto_path=${protobuf.source.dir}"/>
+ <arg value="--proto_path=${test.proto.dir}"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/unittest.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/unittest_import.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/unittest_import_public.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/unittest_mset.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/unittest_mset_wire_format.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/unittest_optimize_for.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/unittest_custom_options.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/unittest_lite.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/unittest_import_lite.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/unittest_import_public_lite.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/unittest_lite_imports_nonlite.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/unittest_enormous_descriptor.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/unittest_no_generic_services.proto"/>
+ <arg value="${protobuf.source.dir}/google/protobuf/unittest_well_known_types.proto"/>
+ <arg value="${test.proto.dir}/com/google/protobuf/lazy_fields_lite.proto"/>
+ <arg value="${test.proto.dir}/com/google/protobuf/lite_equals_and_hash.proto"/>
+ <arg value="${test.proto.dir}/com/google/protobuf/multiple_files_test.proto"/>
+ <arg value="${test.proto.dir}/com/google/protobuf/nested_builders_test.proto"/>
+ <arg value="${test.proto.dir}/com/google/protobuf/nested_extension.proto"/>
+ <arg value="${test.proto.dir}/com/google/protobuf/nested_extension_lite.proto"/>
+ <arg value="${test.proto.dir}/com/google/protobuf/non_nested_extension.proto"/>
+ <arg value="${test.proto.dir}/com/google/protobuf/non_nested_extension_lite.proto"/>
+ <arg value="${test.proto.dir}/com/google/protobuf/outer_class_name_test.proto"/>
+ <arg value="${test.proto.dir}/com/google/protobuf/outer_class_name_test2.proto"/>
+ <arg value="${test.proto.dir}/com/google/protobuf/outer_class_name_test3.proto"/>
+ <arg value="${test.proto.dir}/com/google/protobuf/test_bad_identifiers.proto"/>
+ <arg value="${test.proto.dir}/com/google/protobuf/test_check_utf8.proto"/>
+ <arg value="${test.proto.dir}/com/google/protobuf/test_check_utf8_size.proto"/>
+ <arg value="${test.proto.dir}/com/google/protobuf/test_custom_options.proto"/>
+ <arg value="${test.proto.dir}/com/google/protobuf/any_test.proto"/>
+ <arg value="${test.proto.dir}/com/google/protobuf/field_presence_test.proto"/>
+ <arg value="${test.proto.dir}/com/google/protobuf/map_for_proto2_lite_test.proto"/>
+ <arg value="${test.proto.dir}/com/google/protobuf/map_for_proto2_test.proto"/>
+ <arg value="${test.proto.dir}/com/google/protobuf/map_test.proto"/>
+ <arg value="${test.proto.dir}/com/google/protobuf/map_initialization_order_test.proto"/>
+ </exec>
+</project>
diff --git a/java/lite/pom.xml b/java/lite/pom.xml
new file mode 100644
index 00000000..9862cd94
--- /dev/null
+++ b/java/lite/pom.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>com.google.protobuf</groupId>
+ <artifactId>protobuf-parent</artifactId>
+ <version>3.0.0</version>
+ </parent>
+
+ <artifactId>protobuf-lite</artifactId>
+ <packaging>bundle</packaging>
+
+ <name>Protocol Buffers [Lite]</name>
+ <description>A trimmed-down version of the Protocol Buffers library.</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.easymock</groupId>
+ <artifactId>easymock</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.easymock</groupId>
+ <artifactId>easymockclassextension</artifactId>
+ </dependency>
+ </dependencies>
+
+ <properties>
+ <core.root>../core</core.root>
+ <test.proto.dir>${core.root}/src/test/proto</test.proto.dir>
+ </properties>
+
+ <build>
+ <sourceDirectory>${core.root}/src/main/java</sourceDirectory>
+ <testSourceDirectory>${core.root}/src/test/java</testSourceDirectory>
+
+ <plugins>
+ <!-- Use Antrun plugin to generate sources with protoc -->
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <executions>
+ <!-- Generate core protos -->
+ <execution>
+ <id>generate-sources</id>
+ <phase>generate-sources</phase>
+ <configuration>
+ <target>
+ <ant antfile="generate-sources-build.xml"/>
+ </target>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+
+ <!-- Generate the test protos -->
+ <execution>
+ <id>generate-test-sources</id>
+ <phase>generate-test-sources</phase>
+ <configuration>
+ <target>
+ <ant antfile="generate-test-sources-build.xml"/>
+ </target>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ <!-- Only compile a subset of the files -->
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <generatedSourcesDirectory>${generated.sources.lite.dir}</generatedSourcesDirectory>
+ <generatedTestSourcesDirectory>${generated.testsources.lite.dir}</generatedTestSourcesDirectory>
+ <includes>
+ <include>**/AbstractMessageLite.java</include>
+ <include>**/AbstractParser.java</include>
+ <include>**/AbstractProtobufList.java</include>
+ <include>**/BooleanArrayList.java</include>
+ <include>**/ByteString.java</include>
+ <include>**/CodedInputStream.java</include>
+ <include>**/CodedOutputStream.java</include>
+ <include>**/DoubleArrayList.java</include>
+ <include>**/ExtensionLite.java</include>
+ <include>**/ExtensionRegistryLite.java</include>
+ <include>**/FieldSet.java</include>
+ <include>**/FloatArrayList.java</include>
+ <include>**/GeneratedMessageLite.java</include>
+ <include>**/IntArrayList.java</include>
+ <include>**/Internal.java</include>
+ <include>**/InvalidProtocolBufferException.java</include>
+ <include>**/LazyFieldLite.java</include>
+ <include>**/LazyStringArrayList.java</include>
+ <include>**/LazyStringList.java</include>
+ <include>**/LongArrayList.java</include>
+ <include>**/MapEntryLite.java</include>
+ <include>**/MapFieldLite.java</include>
+ <include>**/MessageLite.java</include>
+ <include>**/MessageLiteOrBuilder.java</include>
+ <include>**/MessageLiteToString.java</include>
+ <include>**/MutabilityOracle.java</include>
+ <include>**/NioByteString.java</include>
+ <include>**/Parser.java</include>
+ <include>**/ProtobufArrayList.java</include>
+ <include>**/ProtocolStringList.java</include>
+ <include>**/RopeByteString.java</include>
+ <include>**/SmallSortedMap.java</include>
+ <include>**/TextFormatEscaper.java</include>
+ <include>**/UninitializedMessageException.java</include>
+ <include>**/UnknownFieldSetLite.java</include>
+ <include>**/UnmodifiableLazyStringList.java</include>
+ <include>**/UnsafeByteOperations.java</include>
+ <include>**/Utf8.java</include>
+ <include>**/WireFormat.java</include>
+ </includes>
+ <testIncludes>
+ <testInclude>**/*Lite.java</testInclude>
+ <testInclude>**/BooleanArrayListTest.java</testInclude>
+ <testInclude>**/DoubleArrayListTest.java</testInclude>
+ <testInclude>**/FloatArrayListTest.java</testInclude>
+ <testInclude>**/IntArrayListTest.java</testInclude>
+ <testInclude>**/LazyMessageLiteTest.java</testInclude>
+ <testInclude>**/LiteTest.java</testInclude>
+ <testInclude>**/LongArrayListTest.java</testInclude>
+ <testInclude>**/NioByteStringTest.java</testInclude>
+ <testInclude>**/ProtobufArrayListTest.java</testInclude>
+ <testInclude>**/UnknownFieldSetLiteTest.java</testInclude>
+ </testIncludes>
+ </configuration>
+ </plugin>
+
+ <!-- OSGI bundle configuration -->
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Bundle-DocURL>https://developers.google.com/protocol-buffers/</Bundle-DocURL>
+ <Bundle-SymbolicName>com.google.protobuf</Bundle-SymbolicName>
+ <Export-Package>com.google.${project.artifactId};version=${project.version}</Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/java/pom.xml b/java/pom.xml
index 7b99c035..3a91a0ba 100644
--- a/java/pom.xml
+++ b/java/pom.xml
@@ -8,17 +8,35 @@
<artifactId>google</artifactId>
<version>1</version>
</parent>
+
<groupId>com.google.protobuf</groupId>
- <artifactId>protobuf-java</artifactId>
- <version>3.0.0-beta-1</version>
- <packaging>bundle</packaging>
- <name>Protocol Buffer Java API</name>
+ <artifactId>protobuf-parent</artifactId>
+ <version>3.0.0</version>
+ <packaging>pom</packaging>
+
+ <name>Protocol Buffers [Parent]</name>
+ <inceptionYear>2008</inceptionYear>
+ <url>https://developers.google.com/protocol-buffers/</url>
<description>
Protocol Buffers are a way of encoding structured data in an efficient yet
extensible format.
</description>
- <inceptionYear>2008</inceptionYear>
- <url>https://developers.google.com/protocol-buffers/</url>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+
+ <!-- These are relative to the submodules -->
+ <protobuf.basedir>${project.basedir}/../..</protobuf.basedir>
+ <protobuf.source.dir>${protobuf.basedir}/src</protobuf.source.dir>
+ <protoc>${protobuf.source.dir}/protoc</protoc>
+ <test.proto.dir>src/test/proto</test.proto.dir>
+ <generated.sources.dir>${project.build.directory}/generated-sources</generated.sources.dir>
+ <generated.testsources.dir>${project.build.directory}/generated-test-sources</generated.testsources.dir>
+ <generated.sources.lite.dir>${project.build.directory}/generated-sources-lite</generated.sources.lite.dir>
+ <generated.testsources.lite.dir>${project.build.directory}/generated-test-sources-lite</generated.testsources.lite.dir>
+ </properties>
+
<licenses>
<license>
<name>New BSD license</name>
@@ -26,185 +44,111 @@
<distribution>repo</distribution>
</license>
</licenses>
+
<scm>
<url>https://github.com/google/protobuf</url>
- <connection>
- scm:git:https://github.com/google/protobuf.git
- </connection>
+ <connection>scm:git:https://github.com/google/protobuf.git</connection>
</scm>
- <dependencies>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>4.4</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.easymock</groupId>
- <artifactId>easymock</artifactId>
- <version>2.2</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.easymock</groupId>
- <artifactId>easymockclassextension</artifactId>
- <version>2.2.1</version>
- <scope>test</scope>
- </dependency>
- </dependencies>
+
+ <distributionManagement>
+ <snapshotRepository>
+ <id>sonatype-nexus-staging</id>
+ <url>https://oss.sonatype.org/content/repositories/snapshots</url>
+ </snapshotRepository>
+ <repository>
+ <id>sonatype-nexus-staging</id>
+ <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
+ </repository>
+ </distributionManagement>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.12</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.easymock</groupId>
+ <artifactId>easymock</artifactId>
+ <version>2.2</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.easymock</groupId>
+ <artifactId>easymockclassextension</artifactId>
+ <version>2.2.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ <version>18.0</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
<build>
- <plugins>
- <plugin>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <source>1.5</source>
- <target>1.5</target>
- </configuration>
- </plugin>
- <plugin>
- <artifactId>maven-surefire-plugin</artifactId>
- <configuration>
- <includes>
- <include>**/*Test.java</include>
- </includes>
- </configuration>
- </plugin>
- <plugin>
- <artifactId>maven-antrun-plugin</artifactId>
- <executions>
- <execution>
- <id>generate-sources</id>
- <phase>generate-sources</phase>
- <configuration>
- <tasks>
- <mkdir dir="target/generated-sources" />
- <exec executable="../src/protoc">
- <arg value="--java_out=target/generated-sources" />
- <arg value="--proto_path=../src" />
- <arg value="../src/google/protobuf/any.proto" />
- <arg value="../src/google/protobuf/api.proto" />
- <arg value="../src/google/protobuf/descriptor.proto" />
- <arg value="../src/google/protobuf/duration.proto" />
- <arg value="../src/google/protobuf/empty.proto" />
- <arg value="../src/google/protobuf/field_mask.proto" />
- <arg value="../src/google/protobuf/source_context.proto" />
- <arg value="../src/google/protobuf/struct.proto" />
- <arg value="../src/google/protobuf/timestamp.proto" />
- <arg value="../src/google/protobuf/type.proto" />
- <arg value="../src/google/protobuf/wrappers.proto" />
- <arg value="../src/google/protobuf/compiler/plugin.proto" />
- </exec>
- </tasks>
- <sourceRoot>target/generated-sources</sourceRoot>
- </configuration>
- <goals>
- <goal>run</goal>
- </goals>
- </execution>
- <execution>
- <id>generate-test-sources</id>
- <phase>generate-test-sources</phase>
- <configuration>
- <tasks>
- <mkdir dir="target/generated-test-sources" />
- <exec executable="../src/protoc">
- <arg value="--java_out=target/generated-test-sources" />
- <arg value="--proto_path=../src" />
- <arg value="--proto_path=src/test/java" />
- <arg value="../src/google/protobuf/unittest.proto" />
- <arg value="../src/google/protobuf/unittest_import.proto" />
- <arg value="../src/google/protobuf/unittest_import_public.proto" />
- <arg value="../src/google/protobuf/unittest_mset.proto" />
- <arg value="../src/google/protobuf/unittest_mset_wire_format.proto" />
- <arg value="src/test/java/com/google/protobuf/lazy_fields_lite.proto" />
- <arg value="src/test/java/com/google/protobuf/lite_equals_and_hash.proto" />
- <arg
- value="src/test/java/com/google/protobuf/multiple_files_test.proto" />
- <arg value="src/test/java/com/google/protobuf/nested_builders_test.proto" />
- <arg value="src/test/java/com/google/protobuf/nested_extension.proto" />
- <arg value="src/test/java/com/google/protobuf/nested_extension_lite.proto" />
- <arg value="src/test/java/com/google/protobuf/non_nested_extension.proto" />
- <arg value="src/test/java/com/google/protobuf/non_nested_extension_lite.proto" />
- <arg value="src/test/java/com/google/protobuf/outer_class_name_test.proto" />
- <arg value="src/test/java/com/google/protobuf/outer_class_name_test2.proto" />
- <arg value="src/test/java/com/google/protobuf/outer_class_name_test3.proto" />
- <arg value="src/test/java/com/google/protobuf/test_bad_identifiers.proto" />
- <arg value="src/test/java/com/google/protobuf/test_check_utf8.proto" />
- <arg value="src/test/java/com/google/protobuf/test_check_utf8_size.proto" />
- <arg value="src/test/java/com/google/protobuf/test_custom_options.proto" />
- <arg
- value="../src/google/protobuf/unittest_optimize_for.proto" />
- <arg
- value="../src/google/protobuf/unittest_custom_options.proto" />
- <arg value="../src/google/protobuf/unittest_lite.proto" />
- <arg value="../src/google/protobuf/unittest_import_lite.proto" />
- <arg value="../src/google/protobuf/unittest_import_public_lite.proto" />
- <arg value="../src/google/protobuf/unittest_lite_imports_nonlite.proto" />
- <arg value="../src/google/protobuf/unittest_enormous_descriptor.proto" />
- <arg value="../src/google/protobuf/unittest_no_generic_services.proto" />
- <arg value="../src/google/protobuf/unittest_well_known_types.proto" />
- <arg value="src/test/java/com/google/protobuf/any_test.proto" />
- <arg value="src/test/java/com/google/protobuf/field_presence_test.proto" />
- <arg value="src/test/java/com/google/protobuf/map_for_proto2_lite_test.proto" />
- <arg value="src/test/java/com/google/protobuf/map_for_proto2_test.proto" />
- <arg value="src/test/java/com/google/protobuf/map_test.proto" />
- <arg value="src/test/java/com/google/protobuf/map_initialization_order_test.proto" />
- </exec>
- </tasks>
- <testSourceRoot>target/generated-test-sources</testSourceRoot>
- </configuration>
- <goals>
- <goal>run</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <extensions>true</extensions>
- <configuration>
- <instructions>
- <Bundle-DocURL>https://developers.google.com/protocol-buffers/</Bundle-DocURL>
- <Bundle-SymbolicName>com.google.protobuf</Bundle-SymbolicName>
- <Export-Package>com.google.protobuf;version=3.0.0-beta-1</Export-Package>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- <resources>
- <resource>
- <directory>../src</directory>
- <includes>
- <include>google/protobuf/any.proto</include>
- <include>google/protobuf/api.proto</include>
- <include>google/protobuf/descriptor.proto</include>
- <include>google/protobuf/duration.proto</include>
- <include>google/protobuf/empty.proto</include>
- <include>google/protobuf/field_mask.proto</include>
- <include>google/protobuf/source_context.proto</include>
- <include>google/protobuf/struct.proto</include>
- <include>google/protobuf/timestamp.proto</include>
- <include>google/protobuf/type.proto</include>
- <include>google/protobuf/wrappers.proto</include>
- <include>google/protobuf/compiler/plugin.proto</include>
- </includes>
- </resource>
- </resources>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.3</version>
+ <configuration>
+ <source>1.6</source>
+ <target>1.6</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-source-plugin</artifactId>
+ <version>2.4</version>
+ <executions>
+ <execution>
+ <id>attach-sources</id>
+ <goals>
+ <goal>jar-no-fork</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>2.10.3</version>
+ <executions>
+ <execution>
+ <id>attach-javadocs</id>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.6</version>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <version>1.10</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <version>3.0.1</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <version>1.8</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
</build>
+
<profiles>
<profile>
<id>release</id>
- <distributionManagement>
- <snapshotRepository>
- <id>sonatype-nexus-staging</id>
- <url>https://oss.sonatype.org/content/repositories/snapshots</url>
- </snapshotRepository>
- <repository>
- <id>sonatype-nexus-staging</id>
- <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
- </repository>
- </distributionManagement>
<build>
<plugins>
<plugin>
@@ -234,9 +178,8 @@
</executions>
</plugin>
<plugin>
- <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
- <version>1.5</version>
+ <version>1.6</version>
<executions>
<execution>
<id>sign-artifacts</id>
@@ -250,93 +193,23 @@
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
- <version>1.6.3</version>
+ <version>1.6.6</version>
<extensions>true</extensions>
<configuration>
- <serverId>sonatype-nexus-staging</serverId>
- <nexusUrl>https://oss.sonatype.org/</nexusUrl>
- <autoReleaseAfterClose>false</autoReleaseAfterClose>
- </configuration>
- </plugin>
- </plugins>
- </build>
- </profile>
- <profile>
- <id>lite</id>
- <build>
- <plugins>
- <plugin>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <includes>
- <include>**/AbstractMessageLite.java</include>
- <include>**/AbstractParser.java</include>
- <include>**/AbstractProtobufList.java</include>
- <include>**/BoundedByteString.java</include>
- <include>**/BooleanArrayList.java</include>
- <include>**/ByteString.java</include>
- <include>**/CodedInputStream.java</include>
- <include>**/CodedOutputStream.java</include>
- <include>**/DoublerrayList.java</include>
- <include>**/ExtensionLite.java</include>
- <include>**/ExtensionRegistryLite.java</include>
- <include>**/FieldSet.java</include>
- <include>**/FloatArrayList.java</include>
- <include>**/GeneratedMessageLite.java</include>
- <include>**/IntArrayList.java</include>
- <include>**/Internal.java</include>
- <include>**/InvalidProtocolBufferException.java</include>
- <include>**/LazyFieldLite.java</include>
- <include>**/LazyStringArrayList.java</include>
- <include>**/LazyStringList.java</include>
- <include>**/LiteralByteString.java</include>
- <include>**/LongArrayList.java</include>
- <include>**/MapEntryLite.java</include>
- <include>**/MapFieldLite.java</include>
- <include>**/MessageLite.java</include>
- <include>**/MessageLiteOrBuilder.java</include>
- <include>**/MutabilityOracle.java</include>
- <include>**/Parser.java</include>
- <include>**/ProtobufArrayList.java</include>
- <include>**/ProtocolStringList.java</include>
- <include>**/RopeByteString.java</include>
- <include>**/SmallSortedMap.java</include>
- <include>**/UninitializedMessageException.java</include>
- <include>**/UnknownFieldSetLite.java</include>
- <include>**/UnmodifiableLazyStringList.java</include>
- <include>**/Utf8.java</include>
- <include>**/WireFormat.java</include>
- </includes>
- <testIncludes>
- <testInclude>**/*Lite.java</testInclude>
- <testInclude>**/BooleanArrayListTest.java</testInclude>
- <testInclude>**/DoubleArrayListTest.java</testInclude>
- <testInclude>**/FloatArrayListTest.java</testInclude>
- <testInclude>**/IntArrayListTest.java</testInclude>
- <testInclude>**/LazyMessageLiteTest.java</testInclude>
- <testInclude>**/LiteTest.java</testInclude>
- <testInclude>**/LongArrayListTest.java</testInclude>
- <testInclude>**/ProtobufArrayListTest.java</testInclude>
- <testInclude>**/UnknownFieldSetLiteTest.java</testInclude>
- </testIncludes>
- </configuration>
- </plugin>
- <plugin>
- <artifactId>maven-surefire-plugin</artifactId>
- <configuration>
- <includes>
- <include>**/*Test.java</include>
- </includes>
- </configuration>
- </plugin>
- <plugin>
- <artifactId>maven-jar-plugin</artifactId>
- <configuration>
- <classifier>lite</classifier>
+ <serverId>sonatype-nexus-staging</serverId>
+ <nexusUrl>https://oss.sonatype.org/</nexusUrl>
+ <autoReleaseAfterClose>false</autoReleaseAfterClose>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
+
+ <modules>
+ <module>core</module>
+ <!-- <module>lite</module> -->
+ <module>util</module>
+ </modules>
+
</project>
diff --git a/java/src/main/java/com/google/protobuf/BoundedByteString.java b/java/src/main/java/com/google/protobuf/BoundedByteString.java
deleted file mode 100644
index b4c3fb1b..00000000
--- a/java/src/main/java/com/google/protobuf/BoundedByteString.java
+++ /dev/null
@@ -1,180 +0,0 @@
-// 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.
-
-package com.google.protobuf;
-
-import java.io.IOException;
-import java.io.InvalidObjectException;
-import java.io.ObjectInputStream;
-import java.util.NoSuchElementException;
-
-/**
- * This class is used to represent the substring of a {@link ByteString} over a
- * single byte array. In terms of the public API of {@link ByteString}, you end
- * up here by calling {@link ByteString#copyFrom(byte[])} followed by {@link
- * ByteString#substring(int, int)}.
- *
- * <p>This class contains most of the overhead involved in creating a substring
- * from a {@link LiteralByteString}. The overhead involves some range-checking
- * and two extra fields.
- *
- * @author carlanton@google.com (Carl Haverl)
- */
-class BoundedByteString extends LiteralByteString {
-
- private final int bytesOffset;
- private final int bytesLength;
-
- /**
- * Creates a {@code BoundedByteString} backed by the sub-range of given array,
- * without copying.
- *
- * @param bytes array to wrap
- * @param offset index to first byte to use in bytes
- * @param length number of bytes to use from bytes
- * @throws IllegalArgumentException if {@code offset < 0}, {@code length < 0},
- * or if {@code offset + length >
- * bytes.length}.
- */
- BoundedByteString(byte[] bytes, int offset, int length) {
- super(bytes);
- if (offset < 0) {
- throw new IllegalArgumentException("Offset too small: " + offset);
- }
- if (length < 0) {
- throw new IllegalArgumentException("Length too small: " + offset);
- }
- if ((long) offset + length > bytes.length) {
- throw new IllegalArgumentException(
- "Offset+Length too large: " + offset + "+" + length);
- }
-
- this.bytesOffset = offset;
- this.bytesLength = length;
- }
-
- /**
- * Gets the byte at the given index.
- * Throws {@link ArrayIndexOutOfBoundsException}
- * for backwards-compatibility reasons although it would more properly be
- * {@link IndexOutOfBoundsException}.
- *
- * @param index index of byte
- * @return the value
- * @throws ArrayIndexOutOfBoundsException {@code index} is < 0 or >= size
- */
- @Override
- public byte byteAt(int index) {
- // We must check the index ourselves as we cannot rely on Java array index
- // checking for substrings.
- if (index < 0) {
- throw new ArrayIndexOutOfBoundsException("Index too small: " + index);
- }
- if (index >= size()) {
- throw new ArrayIndexOutOfBoundsException(
- "Index too large: " + index + ", " + size());
- }
-
- return bytes[bytesOffset + index];
- }
-
- @Override
- public int size() {
- return bytesLength;
- }
-
- @Override
- protected int getOffsetIntoBytes() {
- return bytesOffset;
- }
-
- // =================================================================
- // ByteString -> byte[]
-
- @Override
- protected void copyToInternal(byte[] target, int sourceOffset,
- int targetOffset, int numberToCopy) {
- System.arraycopy(bytes, getOffsetIntoBytes() + sourceOffset, target,
- targetOffset, numberToCopy);
- }
-
- // =================================================================
- // Serializable
-
- private static final long serialVersionUID = 1L;
-
- Object writeReplace() {
- return new LiteralByteString(toByteArray());
- }
-
- private void readObject(ObjectInputStream in) throws IOException {
- throw new InvalidObjectException(
- "BoundedByteStream instances are not to be serialized directly");
- }
-
- // =================================================================
- // ByteIterator
-
- @Override
- public ByteIterator iterator() {
- return new BoundedByteIterator();
- }
-
- private class BoundedByteIterator implements ByteIterator {
-
- private int position;
- private final int limit;
-
- private BoundedByteIterator() {
- position = getOffsetIntoBytes();
- limit = position + size();
- }
-
- public boolean hasNext() {
- return (position < limit);
- }
-
- public Byte next() {
- // Boxing calls Byte.valueOf(byte), which does not instantiate.
- return nextByte();
- }
-
- public byte nextByte() {
- if (position >= limit) {
- throw new NoSuchElementException();
- }
- return bytes[position++];
- }
-
- public void remove() {
- throw new UnsupportedOperationException();
- }
- }
-}
diff --git a/java/src/main/java/com/google/protobuf/CodedOutputStream.java b/java/src/main/java/com/google/protobuf/CodedOutputStream.java
deleted file mode 100644
index 291bd20a..00000000
--- a/java/src/main/java/com/google/protobuf/CodedOutputStream.java
+++ /dev/null
@@ -1,1385 +0,0 @@
-// 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.
-
-package com.google.protobuf;
-
-import com.google.protobuf.Utf8.UnpairedSurrogateException;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.nio.ByteBuffer;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Encodes and writes protocol message fields.
- *
- * <p>This class contains two kinds of methods: methods that write specific
- * protocol message constructs and field types (e.g. {@link #writeTag} and
- * {@link #writeInt32}) and methods that write low-level values (e.g.
- * {@link #writeRawVarint32} and {@link #writeRawBytes}). If you are
- * writing encoded protocol messages, you should use the former methods, but if
- * you are writing some other format of your own design, use the latter.
- *
- * <p>This class is totally unsynchronized.
- *
- * @author kneton@google.com Kenton Varda
- */
-public final class CodedOutputStream {
-
- private static final Logger logger = Logger.getLogger(CodedOutputStream.class.getName());
-
- // TODO(dweis): Consider migrating to a ByteBuffer.
- private final byte[] buffer;
- private final int limit;
- private int position;
- private int totalBytesWritten = 0;
-
- private final OutputStream output;
-
- /**
- * The buffer size used in {@link #newInstance(OutputStream)}.
- */
- public static final int DEFAULT_BUFFER_SIZE = 4096;
-
- /**
- * Returns the buffer size to efficiently write dataLength bytes to this
- * CodedOutputStream. Used by AbstractMessageLite.
- *
- * @return the buffer size to efficiently write dataLength bytes to this
- * CodedOutputStream.
- */
- static int computePreferredBufferSize(int dataLength) {
- if (dataLength > DEFAULT_BUFFER_SIZE) return DEFAULT_BUFFER_SIZE;
- return dataLength;
- }
-
- private CodedOutputStream(final byte[] buffer, final int offset,
- final int length) {
- output = null;
- this.buffer = buffer;
- position = offset;
- limit = offset + length;
- }
-
- private CodedOutputStream(final OutputStream output, final byte[] buffer) {
- this.output = output;
- this.buffer = buffer;
- position = 0;
- limit = buffer.length;
- }
-
- /**
- * Create a new {@code CodedOutputStream} wrapping the given
- * {@code OutputStream}.
- */
- public static CodedOutputStream newInstance(final OutputStream output) {
- return newInstance(output, DEFAULT_BUFFER_SIZE);
- }
-
- /**
- * Create a new {@code CodedOutputStream} wrapping the given
- * {@code OutputStream} with a given buffer size.
- */
- public static CodedOutputStream newInstance(final OutputStream output,
- final int bufferSize) {
- return new CodedOutputStream(output, new byte[bufferSize]);
- }
-
- /**
- * Create a new {@code CodedOutputStream} that writes directly to the given
- * byte array. If more bytes are written than fit in the array,
- * {@link OutOfSpaceException} will be thrown. Writing directly to a flat
- * array is faster than writing to an {@code OutputStream}. See also
- * {@link ByteString#newCodedBuilder}.
- */
- public static CodedOutputStream newInstance(final byte[] flatArray) {
- return newInstance(flatArray, 0, flatArray.length);
- }
-
- /**
- * Create a new {@code CodedOutputStream} that writes directly to the given
- * byte array slice. If more bytes are written than fit in the slice,
- * {@link OutOfSpaceException} will be thrown. Writing directly to a flat
- * array is faster than writing to an {@code OutputStream}. See also
- * {@link ByteString#newCodedBuilder}.
- */
- public static CodedOutputStream newInstance(final byte[] flatArray,
- final int offset,
- final int length) {
- return new CodedOutputStream(flatArray, offset, length);
- }
-
- /**
- * Create a new {@code CodedOutputStream} that writes to the given ByteBuffer.
- */
- public static CodedOutputStream newInstance(ByteBuffer byteBuffer) {
- return newInstance(byteBuffer, DEFAULT_BUFFER_SIZE);
- }
-
- /**
- * Create a new {@code CodedOutputStream} that writes to the given ByteBuffer.
- */
- public static CodedOutputStream newInstance(ByteBuffer byteBuffer,
- int bufferSize) {
- return newInstance(new ByteBufferOutputStream(byteBuffer), bufferSize);
- }
-
- private static class ByteBufferOutputStream extends OutputStream {
- private final ByteBuffer byteBuffer;
- public ByteBufferOutputStream(ByteBuffer byteBuffer) {
- this.byteBuffer = byteBuffer;
- }
-
- @Override
- public void write(int b) throws IOException {
- byteBuffer.put((byte) b);
- }
-
- @Override
- public void write(byte[] data, int offset, int length) throws IOException {
- byteBuffer.put(data, offset, length);
- }
- }
-
- // -----------------------------------------------------------------
-
- /** Write a {@code double} field, including tag, to the stream. */
- public void writeDouble(final int fieldNumber, final double value)
- throws IOException {
- writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
- writeDoubleNoTag(value);
- }
-
- /** Write a {@code float} field, including tag, to the stream. */
- public void writeFloat(final int fieldNumber, final float value)
- throws IOException {
- writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
- writeFloatNoTag(value);
- }
-
- /** Write a {@code uint64} field, including tag, to the stream. */
- public void writeUInt64(final int fieldNumber, final long value)
- throws IOException {
- writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
- writeUInt64NoTag(value);
- }
-
- /** Write an {@code int64} field, including tag, to the stream. */
- public void writeInt64(final int fieldNumber, final long value)
- throws IOException {
- writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
- writeInt64NoTag(value);
- }
-
- /** Write an {@code int32} field, including tag, to the stream. */
- public void writeInt32(final int fieldNumber, final int value)
- throws IOException {
- writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
- writeInt32NoTag(value);
- }
-
- /** Write a {@code fixed64} field, including tag, to the stream. */
- public void writeFixed64(final int fieldNumber, final long value)
- throws IOException {
- writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
- writeFixed64NoTag(value);
- }
-
- /** Write a {@code fixed32} field, including tag, to the stream. */
- public void writeFixed32(final int fieldNumber, final int value)
- throws IOException {
- writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
- writeFixed32NoTag(value);
- }
-
- /** Write a {@code bool} field, including tag, to the stream. */
- public void writeBool(final int fieldNumber, final boolean value)
- throws IOException {
- writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
- writeBoolNoTag(value);
- }
-
- /** Write a {@code string} field, including tag, to the stream. */
- public void writeString(final int fieldNumber, final String value)
- throws IOException {
- writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
- writeStringNoTag(value);
- }
-
- /** Write a {@code group} field, including tag, to the stream. */
- public void writeGroup(final int fieldNumber, final MessageLite value)
- throws IOException {
- writeTag(fieldNumber, WireFormat.WIRETYPE_START_GROUP);
- writeGroupNoTag(value);
- writeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP);
- }
-
-
- /**
- * Write a group represented by an {@link UnknownFieldSet}.
- *
- * @deprecated UnknownFieldSet now implements MessageLite, so you can just
- * call {@link #writeGroup}.
- */
- @Deprecated
- public void writeUnknownGroup(final int fieldNumber,
- final MessageLite value)
- throws IOException {
- writeGroup(fieldNumber, value);
- }
-
- /** Write an embedded message field, including tag, to the stream. */
- public void writeMessage(final int fieldNumber, final MessageLite value)
- throws IOException {
- writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
- writeMessageNoTag(value);
- }
-
-
- /** Write a {@code bytes} field, including tag, to the stream. */
- public void writeBytes(final int fieldNumber, final ByteString value)
- throws IOException {
- writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
- writeBytesNoTag(value);
- }
-
- /** Write a {@code bytes} field, including tag, to the stream. */
- public void writeByteArray(final int fieldNumber, final byte[] value)
- throws IOException {
- writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
- writeByteArrayNoTag(value);
- }
-
- /** Write a {@code bytes} field, including tag, to the stream. */
- public void writeByteArray(final int fieldNumber,
- final byte[] value,
- final int offset,
- final int length)
- throws IOException {
- writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
- writeByteArrayNoTag(value, offset, length);
- }
-
- /**
- * Write a {@code bytes} field, including tag, to the stream.
- * This method will write all content of the ByteBuffer regardless of the
- * current position and limit (i.e., the number of bytes to be written is
- * value.capacity(), not value.remaining()). Furthermore, this method doesn't
- * alter the state of the passed-in ByteBuffer. Its position, limit, mark,
- * etc. will remain unchanged. If you only want to write the remaining bytes
- * of a ByteBuffer, you can call
- * {@code writeByteBuffer(fieldNumber, byteBuffer.slice())}.
- */
- public void writeByteBuffer(final int fieldNumber, final ByteBuffer value)
- throws IOException {
- writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
- writeByteBufferNoTag(value);
- }
-
- /** Write a {@code uint32} field, including tag, to the stream. */
- public void writeUInt32(final int fieldNumber, final int value)
- throws IOException {
- writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
- writeUInt32NoTag(value);
- }
-
- /**
- * Write an enum field, including tag, to the stream. Caller is responsible
- * for converting the enum value to its numeric value.
- */
- public void writeEnum(final int fieldNumber, final int value)
- throws IOException {
- writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
- writeEnumNoTag(value);
- }
-
- /** Write an {@code sfixed32} field, including tag, to the stream. */
- public void writeSFixed32(final int fieldNumber, final int value)
- throws IOException {
- writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
- writeSFixed32NoTag(value);
- }
-
- /** Write an {@code sfixed64} field, including tag, to the stream. */
- public void writeSFixed64(final int fieldNumber, final long value)
- throws IOException {
- writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
- writeSFixed64NoTag(value);
- }
-
- /** Write an {@code sint32} field, including tag, to the stream. */
- public void writeSInt32(final int fieldNumber, final int value)
- throws IOException {
- writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
- writeSInt32NoTag(value);
- }
-
- /** Write an {@code sint64} field, including tag, to the stream. */
- public void writeSInt64(final int fieldNumber, final long value)
- throws IOException {
- writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
- writeSInt64NoTag(value);
- }
-
- /**
- * Write a MessageSet extension field to the stream. For historical reasons,
- * the wire format differs from normal fields.
- */
- public void writeMessageSetExtension(final int fieldNumber,
- final MessageLite value)
- throws IOException {
- writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP);
- writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber);
- writeMessage(WireFormat.MESSAGE_SET_MESSAGE, value);
- writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP);
- }
-
- /**
- * Write an unparsed MessageSet extension field to the stream. For
- * historical reasons, the wire format differs from normal fields.
- */
- public void writeRawMessageSetExtension(final int fieldNumber,
- final ByteString value)
- throws IOException {
- writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP);
- writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber);
- writeBytes(WireFormat.MESSAGE_SET_MESSAGE, value);
- writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP);
- }
-
- // -----------------------------------------------------------------
-
- /** Write a {@code double} field to the stream. */
- public void writeDoubleNoTag(final double value) throws IOException {
- writeRawLittleEndian64(Double.doubleToRawLongBits(value));
- }
-
- /** Write a {@code float} field to the stream. */
- public void writeFloatNoTag(final float value) throws IOException {
- writeRawLittleEndian32(Float.floatToRawIntBits(value));
- }
-
- /** Write a {@code uint64} field to the stream. */
- public void writeUInt64NoTag(final long value) throws IOException {
- writeRawVarint64(value);
- }
-
- /** Write an {@code int64} field to the stream. */
- public void writeInt64NoTag(final long value) throws IOException {
- writeRawVarint64(value);
- }
-
- /** Write an {@code int32} field to the stream. */
- public void writeInt32NoTag(final int value) throws IOException {
- if (value >= 0) {
- writeRawVarint32(value);
- } else {
- // Must sign-extend.
- writeRawVarint64(value);
- }
- }
-
- /** Write a {@code fixed64} field to the stream. */
- public void writeFixed64NoTag(final long value) throws IOException {
- writeRawLittleEndian64(value);
- }
-
- /** Write a {@code fixed32} field to the stream. */
- public void writeFixed32NoTag(final int value) throws IOException {
- writeRawLittleEndian32(value);
- }
-
- /** Write a {@code bool} field to the stream. */
- public void writeBoolNoTag(final boolean value) throws IOException {
- writeRawByte(value ? 1 : 0);
- }
-
- /** Write a {@code string} field to the stream. */
- // TODO(dweis): Document behavior on ill-formed UTF-16 input.
- public void writeStringNoTag(final String value) throws IOException {
- try {
- efficientWriteStringNoTag(value);
- } catch (UnpairedSurrogateException e) {
- logger.log(Level.WARNING,
- "Converting ill-formed UTF-16. Your Protocol Buffer will not round trip correctly!", e);
- inefficientWriteStringNoTag(value);
- }
- }
-
- /** Write a {@code string} field to the stream. */
- private void inefficientWriteStringNoTag(final String value) throws IOException {
- // Unfortunately there does not appear to be any way to tell Java to encode
- // UTF-8 directly into our buffer, so we have to let it create its own byte
- // array and then copy.
- // TODO(dweis): Consider using nio Charset methods instead.
- final byte[] bytes = value.getBytes(Internal.UTF_8);
- writeRawVarint32(bytes.length);
- writeRawBytes(bytes);
- }
-
- /**
- * Write a {@code string} field to the stream efficiently. If the {@code string} is malformed,
- * this method rolls back its changes and throws an {@link UnpairedSurrogateException} with the
- * intent that the caller will catch and retry with {@link #inefficientWriteStringNoTag(String)}.
- *
- * @param value the string to write to the stream
- *
- * @throws UnpairedSurrogateException when {@code value} is ill-formed UTF-16.
- */
- private void efficientWriteStringNoTag(final String value) throws IOException {
- // UTF-8 byte length of the string is at least its UTF-16 code unit length (value.length()),
- // and at most 3 times of it. We take advantage of this in both branches below.
- final int maxLength = value.length() * Utf8.MAX_BYTES_PER_CHAR;
- final int maxLengthVarIntSize = computeRawVarint32Size(maxLength);
-
- // If we are streaming and the potential length is too big to fit in our buffer, we take the
- // slower path. Otherwise, we're good to try the fast path.
- if (output != null && maxLengthVarIntSize + maxLength > limit - position) {
- // Allocate a byte[] that we know can fit the string and encode into it. String.getBytes()
- // does the same internally and then does *another copy* to return a byte[] of exactly the
- // right size. We can skip that copy and just writeRawBytes up to the actualLength of the
- // UTF-8 encoded bytes.
- final byte[] encodedBytes = new byte[maxLength];
- int actualLength = Utf8.encode(value, encodedBytes, 0, maxLength);
- writeRawVarint32(actualLength);
- writeRawBytes(encodedBytes, 0, actualLength);
- } else {
- // Optimize for the case where we know this length results in a constant varint length as this
- // saves a pass for measuring the length of the string.
- final int minLengthVarIntSize = computeRawVarint32Size(value.length());
- int oldPosition = position;
- final int length;
- try {
- if (minLengthVarIntSize == maxLengthVarIntSize) {
- position = oldPosition + minLengthVarIntSize;
- int newPosition = Utf8.encode(value, buffer, position, limit - position);
- // Since this class is stateful and tracks the position, we rewind and store the state,
- // prepend the length, then reset it back to the end of the string.
- position = oldPosition;
- length = newPosition - oldPosition - minLengthVarIntSize;
- writeRawVarint32(length);
- position = newPosition;
- } else {
- length = Utf8.encodedLength(value);
- writeRawVarint32(length);
- position = Utf8.encode(value, buffer, position, limit - position);
- }
- } catch (UnpairedSurrogateException e) {
- // Be extra careful and restore the original position for retrying the write with the less
- // efficient path.
- position = oldPosition;
- throw e;
- } catch (ArrayIndexOutOfBoundsException e) {
- throw new OutOfSpaceException(e);
- }
- totalBytesWritten += length;
- }
- }
-
- /** Write a {@code group} field to the stream. */
- public void writeGroupNoTag(final MessageLite value) throws IOException {
- value.writeTo(this);
- }
-
-
- /**
- * Write a group represented by an {@link UnknownFieldSet}.
- *
- * @deprecated UnknownFieldSet now implements MessageLite, so you can just
- * call {@link #writeGroupNoTag}.
- */
- @Deprecated
- public void writeUnknownGroupNoTag(final MessageLite value)
- throws IOException {
- writeGroupNoTag(value);
- }
-
- /** Write an embedded message field to the stream. */
- public void writeMessageNoTag(final MessageLite value) throws IOException {
- writeRawVarint32(value.getSerializedSize());
- value.writeTo(this);
- }
-
-
- /** Write a {@code bytes} field to the stream. */
- public void writeBytesNoTag(final ByteString value) throws IOException {
- writeRawVarint32(value.size());
- writeRawBytes(value);
- }
-
- /** Write a {@code bytes} field to the stream. */
- public void writeByteArrayNoTag(final byte[] value) throws IOException {
- writeRawVarint32(value.length);
- writeRawBytes(value);
- }
-
- /** Write a {@code bytes} field to the stream. */
- public void writeByteArrayNoTag(final byte[] value,
- final int offset,
- final int length) throws IOException {
- writeRawVarint32(length);
- writeRawBytes(value, offset, length);
- }
-
- /**
- * Write a {@code bytes} field to the stream. This method will write all
- * content of the ByteBuffer regardless of the current position and limit
- * (i.e., the number of bytes to be written is value.capacity(), not
- * value.remaining()). Furthermore, this method doesn't alter the state of
- * the passed-in ByteBuffer. Its position, limit, mark, etc. will remain
- * unchanged. If you only want to write the remaining bytes of a ByteBuffer,
- * you can call {@code writeByteBufferNoTag(byteBuffer.slice())}.
- */
- public void writeByteBufferNoTag(final ByteBuffer value) throws IOException {
- writeRawVarint32(value.capacity());
- writeRawBytes(value);
- }
-
- /** Write a {@code uint32} field to the stream. */
- public void writeUInt32NoTag(final int value) throws IOException {
- writeRawVarint32(value);
- }
-
- /**
- * Write an enum field to the stream. Caller is responsible
- * for converting the enum value to its numeric value.
- */
- public void writeEnumNoTag(final int value) throws IOException {
- writeInt32NoTag(value);
- }
-
- /** Write an {@code sfixed32} field to the stream. */
- public void writeSFixed32NoTag(final int value) throws IOException {
- writeRawLittleEndian32(value);
- }
-
- /** Write an {@code sfixed64} field to the stream. */
- public void writeSFixed64NoTag(final long value) throws IOException {
- writeRawLittleEndian64(value);
- }
-
- /** Write an {@code sint32} field to the stream. */
- public void writeSInt32NoTag(final int value) throws IOException {
- writeRawVarint32(encodeZigZag32(value));
- }
-
- /** Write an {@code sint64} field to the stream. */
- public void writeSInt64NoTag(final long value) throws IOException {
- writeRawVarint64(encodeZigZag64(value));
- }
-
- // =================================================================
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * {@code double} field, including tag.
- */
- public static int computeDoubleSize(final int fieldNumber,
- final double value) {
- return computeTagSize(fieldNumber) + computeDoubleSizeNoTag(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * {@code float} field, including tag.
- */
- public static int computeFloatSize(final int fieldNumber, final float value) {
- return computeTagSize(fieldNumber) + computeFloatSizeNoTag(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * {@code uint64} field, including tag.
- */
- public static int computeUInt64Size(final int fieldNumber, final long value) {
- return computeTagSize(fieldNumber) + computeUInt64SizeNoTag(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode an
- * {@code int64} field, including tag.
- */
- public static int computeInt64Size(final int fieldNumber, final long value) {
- return computeTagSize(fieldNumber) + computeInt64SizeNoTag(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode an
- * {@code int32} field, including tag.
- */
- public static int computeInt32Size(final int fieldNumber, final int value) {
- return computeTagSize(fieldNumber) + computeInt32SizeNoTag(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * {@code fixed64} field, including tag.
- */
- public static int computeFixed64Size(final int fieldNumber,
- final long value) {
- return computeTagSize(fieldNumber) + computeFixed64SizeNoTag(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * {@code fixed32} field, including tag.
- */
- public static int computeFixed32Size(final int fieldNumber,
- final int value) {
- return computeTagSize(fieldNumber) + computeFixed32SizeNoTag(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * {@code bool} field, including tag.
- */
- public static int computeBoolSize(final int fieldNumber,
- final boolean value) {
- return computeTagSize(fieldNumber) + computeBoolSizeNoTag(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * {@code string} field, including tag.
- */
- public static int computeStringSize(final int fieldNumber,
- final String value) {
- return computeTagSize(fieldNumber) + computeStringSizeNoTag(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * {@code group} field, including tag.
- */
- public static int computeGroupSize(final int fieldNumber,
- final MessageLite value) {
- return computeTagSize(fieldNumber) * 2 + computeGroupSizeNoTag(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * {@code group} field represented by an {@code UnknownFieldSet}, including
- * tag.
- *
- * @deprecated UnknownFieldSet now implements MessageLite, so you can just
- * call {@link #computeGroupSize}.
- */
- @Deprecated
- public static int computeUnknownGroupSize(final int fieldNumber,
- final MessageLite value) {
- return computeGroupSize(fieldNumber, value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode an
- * embedded message field, including tag.
- */
- public static int computeMessageSize(final int fieldNumber,
- final MessageLite value) {
- return computeTagSize(fieldNumber) + computeMessageSizeNoTag(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * {@code bytes} field, including tag.
- */
- public static int computeBytesSize(final int fieldNumber,
- final ByteString value) {
- return computeTagSize(fieldNumber) + computeBytesSizeNoTag(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * {@code bytes} field, including tag.
- */
- public static int computeByteArraySize(final int fieldNumber,
- final byte[] value) {
- return computeTagSize(fieldNumber) + computeByteArraySizeNoTag(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * {@code bytes} field, including tag.
- */
- public static int computeByteBufferSize(final int fieldNumber,
- final ByteBuffer value) {
- return computeTagSize(fieldNumber) + computeByteBufferSizeNoTag(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode an
- * embedded message in lazy field, including tag.
- */
- public static int computeLazyFieldSize(final int fieldNumber,
- final LazyFieldLite value) {
- return computeTagSize(fieldNumber) + computeLazyFieldSizeNoTag(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * {@code uint32} field, including tag.
- */
- public static int computeUInt32Size(final int fieldNumber, final int value) {
- return computeTagSize(fieldNumber) + computeUInt32SizeNoTag(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode an
- * enum field, including tag. Caller is responsible for converting the
- * enum value to its numeric value.
- */
- public static int computeEnumSize(final int fieldNumber, final int value) {
- return computeTagSize(fieldNumber) + computeEnumSizeNoTag(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode an
- * {@code sfixed32} field, including tag.
- */
- public static int computeSFixed32Size(final int fieldNumber,
- final int value) {
- return computeTagSize(fieldNumber) + computeSFixed32SizeNoTag(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode an
- * {@code sfixed64} field, including tag.
- */
- public static int computeSFixed64Size(final int fieldNumber,
- final long value) {
- return computeTagSize(fieldNumber) + computeSFixed64SizeNoTag(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode an
- * {@code sint32} field, including tag.
- */
- public static int computeSInt32Size(final int fieldNumber, final int value) {
- return computeTagSize(fieldNumber) + computeSInt32SizeNoTag(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode an
- * {@code sint64} field, including tag.
- */
- public static int computeSInt64Size(final int fieldNumber, final long value) {
- return computeTagSize(fieldNumber) + computeSInt64SizeNoTag(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * MessageSet extension to the stream. For historical reasons,
- * the wire format differs from normal fields.
- */
- public static int computeMessageSetExtensionSize(
- final int fieldNumber, final MessageLite value) {
- return computeTagSize(WireFormat.MESSAGE_SET_ITEM) * 2 +
- computeUInt32Size(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber) +
- computeMessageSize(WireFormat.MESSAGE_SET_MESSAGE, value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode an
- * unparsed MessageSet extension field to the stream. For
- * historical reasons, the wire format differs from normal fields.
- */
- public static int computeRawMessageSetExtensionSize(
- final int fieldNumber, final ByteString value) {
- return computeTagSize(WireFormat.MESSAGE_SET_ITEM) * 2 +
- computeUInt32Size(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber) +
- computeBytesSize(WireFormat.MESSAGE_SET_MESSAGE, value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode an
- * lazily parsed MessageSet extension field to the stream. For
- * historical reasons, the wire format differs from normal fields.
- */
- public static int computeLazyFieldMessageSetExtensionSize(
- final int fieldNumber, final LazyFieldLite value) {
- return computeTagSize(WireFormat.MESSAGE_SET_ITEM) * 2 +
- computeUInt32Size(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber) +
- computeLazyFieldSize(WireFormat.MESSAGE_SET_MESSAGE, value);
- }
-
- // -----------------------------------------------------------------
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * {@code double} field, including tag.
- */
- public static int computeDoubleSizeNoTag(final double value) {
- return LITTLE_ENDIAN_64_SIZE;
- }
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * {@code float} field, including tag.
- */
- public static int computeFloatSizeNoTag(final float value) {
- return LITTLE_ENDIAN_32_SIZE;
- }
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * {@code uint64} field, including tag.
- */
- public static int computeUInt64SizeNoTag(final long value) {
- return computeRawVarint64Size(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode an
- * {@code int64} field, including tag.
- */
- public static int computeInt64SizeNoTag(final long value) {
- return computeRawVarint64Size(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode an
- * {@code int32} field, including tag.
- */
- public static int computeInt32SizeNoTag(final int value) {
- if (value >= 0) {
- return computeRawVarint32Size(value);
- } else {
- // Must sign-extend.
- return 10;
- }
- }
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * {@code fixed64} field.
- */
- public static int computeFixed64SizeNoTag(final long value) {
- return LITTLE_ENDIAN_64_SIZE;
- }
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * {@code fixed32} field.
- */
- public static int computeFixed32SizeNoTag(final int value) {
- return LITTLE_ENDIAN_32_SIZE;
- }
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * {@code bool} field.
- */
- public static int computeBoolSizeNoTag(final boolean value) {
- return 1;
- }
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * {@code string} field.
- */
- public static int computeStringSizeNoTag(final String value) {
- int length;
- try {
- length = Utf8.encodedLength(value);
- } catch (UnpairedSurrogateException e) {
- // TODO(dweis): Consider using nio Charset methods instead.
- final byte[] bytes = value.getBytes(Internal.UTF_8);
- length = bytes.length;
- }
-
- return computeRawVarint32Size(length) + length;
- }
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * {@code group} field.
- */
- public static int computeGroupSizeNoTag(final MessageLite value) {
- return value.getSerializedSize();
- }
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * {@code group} field represented by an {@code UnknownFieldSet}, including
- * tag.
- *
- * @deprecated UnknownFieldSet now implements MessageLite, so you can just
- * call {@link #computeUnknownGroupSizeNoTag}.
- */
- @Deprecated
- public static int computeUnknownGroupSizeNoTag(final MessageLite value) {
- return computeGroupSizeNoTag(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode an embedded
- * message field.
- */
- public static int computeMessageSizeNoTag(final MessageLite value) {
- final int size = value.getSerializedSize();
- return computeRawVarint32Size(size) + size;
- }
-
- /**
- * Compute the number of bytes that would be needed to encode an embedded
- * message stored in lazy field.
- */
- public static int computeLazyFieldSizeNoTag(final LazyFieldLite value) {
- final int size = value.getSerializedSize();
- return computeRawVarint32Size(size) + size;
- }
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * {@code bytes} field.
- */
- public static int computeBytesSizeNoTag(final ByteString value) {
- return computeRawVarint32Size(value.size()) +
- value.size();
- }
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * {@code bytes} field.
- */
- public static int computeByteArraySizeNoTag(final byte[] value) {
- return computeRawVarint32Size(value.length) + value.length;
- }
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * {@code bytes} field.
- */
- public static int computeByteBufferSizeNoTag(final ByteBuffer value) {
- return computeRawVarint32Size(value.capacity()) + value.capacity();
- }
-
- /**
- * Compute the number of bytes that would be needed to encode a
- * {@code uint32} field.
- */
- public static int computeUInt32SizeNoTag(final int value) {
- return computeRawVarint32Size(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode an enum field.
- * Caller is responsible for converting the enum value to its numeric value.
- */
- public static int computeEnumSizeNoTag(final int value) {
- return computeInt32SizeNoTag(value);
- }
-
- /**
- * Compute the number of bytes that would be needed to encode an
- * {@code sfixed32} field.
- */
- public static int computeSFixed32SizeNoTag(final int value) {
- return LITTLE_ENDIAN_32_SIZE;
- }
-
- /**
- * Compute the number of bytes that would be needed to encode an
- * {@code sfixed64} field.
- */
- public static int computeSFixed64SizeNoTag(final long value) {
- return LITTLE_ENDIAN_64_SIZE;
- }
-
- /**
- * Compute the number of bytes that would be needed to encode an
- * {@code sint32} field.
- */
- public static int computeSInt32SizeNoTag(final int value) {
- return computeRawVarint32Size(encodeZigZag32(value));
- }
-
- /**
- * Compute the number of bytes that would be needed to encode an
- * {@code sint64} field.
- */
- public static int computeSInt64SizeNoTag(final long value) {
- return computeRawVarint64Size(encodeZigZag64(value));
- }
-
- // =================================================================
-
- /**
- * Internal helper that writes the current buffer to the output. The
- * buffer position is reset to its initial value when this returns.
- */
- private void refreshBuffer() throws IOException {
- if (output == null) {
- // We're writing to a single buffer.
- throw new OutOfSpaceException();
- }
-
- // Since we have an output stream, this is our buffer
- // and buffer offset == 0
- output.write(buffer, 0, position);
- position = 0;
- }
-
- /**
- * Flushes the stream and forces any buffered bytes to be written. This
- * does not flush the underlying OutputStream.
- */
- public void flush() throws IOException {
- if (output != null) {
- refreshBuffer();
- }
- }
-
- /**
- * If writing to a flat array, return the space left in the array.
- * Otherwise, throws {@code UnsupportedOperationException}.
- */
- public int spaceLeft() {
- if (output == null) {
- return limit - position;
- } else {
- throw new UnsupportedOperationException(
- "spaceLeft() can only be called on CodedOutputStreams that are " +
- "writing to a flat array.");
- }
- }
-
- /**
- * Verifies that {@link #spaceLeft()} returns zero. It's common to create
- * a byte array that is exactly big enough to hold a message, then write to
- * it with a {@code CodedOutputStream}. Calling {@code checkNoSpaceLeft()}
- * after writing verifies that the message was actually as big as expected,
- * which can help catch bugs.
- */
- public void checkNoSpaceLeft() {
- if (spaceLeft() != 0) {
- throw new IllegalStateException(
- "Did not write as much data as expected.");
- }
- }
-
- /**
- * If you create a CodedOutputStream around a simple flat array, you must
- * not attempt to write more bytes than the array has space. Otherwise,
- * this exception will be thrown.
- */
- public static class OutOfSpaceException extends IOException {
- private static final long serialVersionUID = -6947486886997889499L;
-
- private static final String MESSAGE =
- "CodedOutputStream was writing to a flat byte array and ran out of space.";
-
- OutOfSpaceException() {
- super(MESSAGE);
- }
-
- OutOfSpaceException(Throwable cause) {
- super(MESSAGE, cause);
- }
- }
-
- /**
- * Get the total number of bytes successfully written to this stream. The
- * returned value is not guaranteed to be accurate if exceptions have been
- * found in the middle of writing.
- */
- public int getTotalBytesWritten() {
- return totalBytesWritten;
- }
-
- /** Write a single byte. */
- public void writeRawByte(final byte value) throws IOException {
- if (position == limit) {
- refreshBuffer();
- }
-
- buffer[position++] = value;
- ++totalBytesWritten;
- }
-
- /** Write a single byte, represented by an integer value. */
- public void writeRawByte(final int value) throws IOException {
- writeRawByte((byte) value);
- }
-
- /** Write a byte string. */
- public void writeRawBytes(final ByteString value) throws IOException {
- writeRawBytes(value, 0, value.size());
- }
-
- /** Write an array of bytes. */
- public void writeRawBytes(final byte[] value) throws IOException {
- writeRawBytes(value, 0, value.length);
- }
-
- /**
- * Write a ByteBuffer. This method will write all content of the ByteBuffer
- * regardless of the current position and limit (i.e., the number of bytes
- * to be written is value.capacity(), not value.remaining()). Furthermore,
- * this method doesn't alter the state of the passed-in ByteBuffer. Its
- * position, limit, mark, etc. will remain unchanged. If you only want to
- * write the remaining bytes of a ByteBuffer, you can call
- * {@code writeRawBytes(byteBuffer.slice())}.
- */
- public void writeRawBytes(final ByteBuffer value) throws IOException {
- if (value.hasArray()) {
- writeRawBytes(value.array(), value.arrayOffset(), value.capacity());
- } else {
- ByteBuffer duplicated = value.duplicate();
- duplicated.clear();
- writeRawBytesInternal(duplicated);
- }
- }
-
- /** Write a ByteBuffer that isn't backed by an array. */
- private void writeRawBytesInternal(final ByteBuffer value)
- throws IOException {
- int length = value.remaining();
- if (limit - position >= length) {
- // We have room in the current buffer.
- value.get(buffer, position, length);
- position += length;
- totalBytesWritten += length;
- } else {
- // Write extends past current buffer. Fill the rest of this buffer and
- // flush.
- final int bytesWritten = limit - position;
- value.get(buffer, position, bytesWritten);
- length -= bytesWritten;
- position = limit;
- totalBytesWritten += bytesWritten;
- refreshBuffer();
-
- // Now deal with the rest.
- // Since we have an output stream, this is our buffer
- // and buffer offset == 0
- while (length > limit) {
- // Copy data into the buffer before writing it to OutputStream.
- // TODO(xiaofeng): Introduce ZeroCopyOutputStream to avoid this copy.
- value.get(buffer, 0, limit);
- output.write(buffer, 0, limit);
- length -= limit;
- totalBytesWritten += limit;
- }
- value.get(buffer, 0, length);
- position = length;
- totalBytesWritten += length;
- }
- }
-
- /** Write part of an array of bytes. */
- public void writeRawBytes(final byte[] value, int offset, int length)
- throws IOException {
- if (limit - position >= length) {
- // We have room in the current buffer.
- System.arraycopy(value, offset, buffer, position, length);
- position += length;
- totalBytesWritten += length;
- } else {
- // Write extends past current buffer. Fill the rest of this buffer and
- // flush.
- final int bytesWritten = limit - position;
- System.arraycopy(value, offset, buffer, position, bytesWritten);
- offset += bytesWritten;
- length -= bytesWritten;
- position = limit;
- totalBytesWritten += bytesWritten;
- refreshBuffer();
-
- // Now deal with the rest.
- // Since we have an output stream, this is our buffer
- // and buffer offset == 0
- if (length <= limit) {
- // Fits in new buffer.
- System.arraycopy(value, offset, buffer, 0, length);
- position = length;
- } else {
- // Write is very big. Let's do it all at once.
- output.write(value, offset, length);
- }
- totalBytesWritten += length;
- }
- }
-
- /** Write part of a byte string. */
- public void writeRawBytes(final ByteString value, int offset, int length)
- throws IOException {
- if (limit - position >= length) {
- // We have room in the current buffer.
- value.copyTo(buffer, offset, position, length);
- position += length;
- totalBytesWritten += length;
- } else {
- // Write extends past current buffer. Fill the rest of this buffer and
- // flush.
- final int bytesWritten = limit - position;
- value.copyTo(buffer, offset, position, bytesWritten);
- offset += bytesWritten;
- length -= bytesWritten;
- position = limit;
- totalBytesWritten += bytesWritten;
- refreshBuffer();
-
- // Now deal with the rest.
- // Since we have an output stream, this is our buffer
- // and buffer offset == 0
- if (length <= limit) {
- // Fits in new buffer.
- value.copyTo(buffer, offset, 0, length);
- position = length;
- } else {
- value.writeTo(output, offset, length);
- }
- totalBytesWritten += length;
- }
- }
-
- /** Encode and write a tag. */
- public void writeTag(final int fieldNumber, final int wireType)
- throws IOException {
- writeRawVarint32(WireFormat.makeTag(fieldNumber, wireType));
- }
-
- /** Compute the number of bytes that would be needed to encode a tag. */
- public static int computeTagSize(final int fieldNumber) {
- return computeRawVarint32Size(WireFormat.makeTag(fieldNumber, 0));
- }
-
- /**
- * Encode and write a varint. {@code value} is treated as
- * unsigned, so it won't be sign-extended if negative.
- */
- public void writeRawVarint32(int value) throws IOException {
- while (true) {
- if ((value & ~0x7F) == 0) {
- writeRawByte(value);
- return;
- } else {
- writeRawByte((value & 0x7F) | 0x80);
- value >>>= 7;
- }
- }
- }
-
- /**
- * Compute the number of bytes that would be needed to encode a varint.
- * {@code value} is treated as unsigned, so it won't be sign-extended if
- * negative.
- */
- public static int computeRawVarint32Size(final int value) {
- if ((value & (0xffffffff << 7)) == 0) return 1;
- if ((value & (0xffffffff << 14)) == 0) return 2;
- if ((value & (0xffffffff << 21)) == 0) return 3;
- if ((value & (0xffffffff << 28)) == 0) return 4;
- return 5;
- }
-
- /** Encode and write a varint. */
- public void writeRawVarint64(long value) throws IOException {
- while (true) {
- if ((value & ~0x7FL) == 0) {
- writeRawByte((int)value);
- return;
- } else {
- writeRawByte(((int)value & 0x7F) | 0x80);
- value >>>= 7;
- }
- }
- }
-
- /** Compute the number of bytes that would be needed to encode a varint. */
- public static int computeRawVarint64Size(final long value) {
- if ((value & (0xffffffffffffffffL << 7)) == 0) return 1;
- if ((value & (0xffffffffffffffffL << 14)) == 0) return 2;
- if ((value & (0xffffffffffffffffL << 21)) == 0) return 3;
- if ((value & (0xffffffffffffffffL << 28)) == 0) return 4;
- if ((value & (0xffffffffffffffffL << 35)) == 0) return 5;
- if ((value & (0xffffffffffffffffL << 42)) == 0) return 6;
- if ((value & (0xffffffffffffffffL << 49)) == 0) return 7;
- if ((value & (0xffffffffffffffffL << 56)) == 0) return 8;
- if ((value & (0xffffffffffffffffL << 63)) == 0) return 9;
- return 10;
- }
-
- /** Write a little-endian 32-bit integer. */
- public void writeRawLittleEndian32(final int value) throws IOException {
- writeRawByte((value ) & 0xFF);
- writeRawByte((value >> 8) & 0xFF);
- writeRawByte((value >> 16) & 0xFF);
- writeRawByte((value >> 24) & 0xFF);
- }
-
- public static final int LITTLE_ENDIAN_32_SIZE = 4;
-
- /** Write a little-endian 64-bit integer. */
- public void writeRawLittleEndian64(final long value) throws IOException {
- writeRawByte((int)(value ) & 0xFF);
- writeRawByte((int)(value >> 8) & 0xFF);
- writeRawByte((int)(value >> 16) & 0xFF);
- writeRawByte((int)(value >> 24) & 0xFF);
- writeRawByte((int)(value >> 32) & 0xFF);
- writeRawByte((int)(value >> 40) & 0xFF);
- writeRawByte((int)(value >> 48) & 0xFF);
- writeRawByte((int)(value >> 56) & 0xFF);
- }
-
- public static final int LITTLE_ENDIAN_64_SIZE = 8;
-
- /**
- * Encode a ZigZag-encoded 32-bit value. ZigZag encodes signed integers
- * into values that can be efficiently encoded with varint. (Otherwise,
- * negative values must be sign-extended to 64 bits to be varint encoded,
- * thus always taking 10 bytes on the wire.)
- *
- * @param n A signed 32-bit integer.
- * @return An unsigned 32-bit integer, stored in a signed int because
- * Java has no explicit unsigned support.
- */
- public static int encodeZigZag32(final int n) {
- // Note: the right-shift must be arithmetic
- return (n << 1) ^ (n >> 31);
- }
-
- /**
- * Encode a ZigZag-encoded 64-bit value. ZigZag encodes signed integers
- * into values that can be efficiently encoded with varint. (Otherwise,
- * negative values must be sign-extended to 64 bits to be varint encoded,
- * thus always taking 10 bytes on the wire.)
- *
- * @param n A signed 64-bit integer.
- * @return An unsigned 64-bit integer, stored in a signed int because
- * Java has no explicit unsigned support.
- */
- public static long encodeZigZag64(final long n) {
- // Note: the right-shift must be arithmetic
- return (n << 1) ^ (n >> 63);
- }
-}
diff --git a/java/src/main/java/com/google/protobuf/LiteralByteString.java b/java/src/main/java/com/google/protobuf/LiteralByteString.java
deleted file mode 100644
index c5a8512a..00000000
--- a/java/src/main/java/com/google/protobuf/LiteralByteString.java
+++ /dev/null
@@ -1,372 +0,0 @@
-// 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.
-
-package com.google.protobuf;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.NoSuchElementException;
-
-/**
- * This class implements a {@link com.google.protobuf.ByteString} backed by a
- * single array of bytes, contiguous in memory. It supports substring by
- * pointing to only a sub-range of the underlying byte array, meaning that a
- * substring will reference the full byte-array of the string it's made from,
- * exactly as with {@link String}.
- *
- * @author carlanton@google.com (Carl Haverl)
- */
-class LiteralByteString extends ByteString {
-
- private static final long serialVersionUID = 1L;
-
- protected final byte[] bytes;
-
- /**
- * Creates a {@code LiteralByteString} backed by the given array, without
- * copying.
- *
- * @param bytes array to wrap
- */
- LiteralByteString(byte[] bytes) {
- this.bytes = bytes;
- }
-
- @Override
- public byte byteAt(int index) {
- // Unlike most methods in this class, this one is a direct implementation
- // ignoring the potential offset because we need to do range-checking in the
- // substring case anyway.
- return bytes[index];
- }
-
- @Override
- public int size() {
- return bytes.length;
- }
-
- // =================================================================
- // ByteString -> substring
-
- @Override
- public ByteString substring(int beginIndex, int endIndex) {
- if (beginIndex < 0) {
- throw new IndexOutOfBoundsException(
- "Beginning index: " + beginIndex + " < 0");
- }
- if (endIndex > size()) {
- throw new IndexOutOfBoundsException("End index: " + endIndex + " > " +
- size());
- }
- int substringLength = endIndex - beginIndex;
- if (substringLength < 0) {
- throw new IndexOutOfBoundsException(
- "Beginning index larger than ending index: " + beginIndex + ", "
- + endIndex);
- }
-
- ByteString result;
- if (substringLength == 0) {
- result = ByteString.EMPTY;
- } else {
- result = new BoundedByteString(bytes, getOffsetIntoBytes() + beginIndex,
- substringLength);
- }
- return result;
- }
-
- // =================================================================
- // ByteString -> byte[]
-
- @Override
- protected void copyToInternal(byte[] target, int sourceOffset,
- int targetOffset, int numberToCopy) {
- // Optimized form, not for subclasses, since we don't call
- // getOffsetIntoBytes() or check the 'numberToCopy' parameter.
- System.arraycopy(bytes, sourceOffset, target, targetOffset, numberToCopy);
- }
-
- @Override
- public void copyTo(ByteBuffer target) {
- target.put(bytes, getOffsetIntoBytes(), size()); // Copies bytes
- }
-
- @Override
- public ByteBuffer asReadOnlyByteBuffer() {
- ByteBuffer byteBuffer =
- ByteBuffer.wrap(bytes, getOffsetIntoBytes(), size());
- return byteBuffer.asReadOnlyBuffer();
- }
-
- @Override
- public List<ByteBuffer> asReadOnlyByteBufferList() {
- // Return the ByteBuffer generated by asReadOnlyByteBuffer() as a singleton
- List<ByteBuffer> result = new ArrayList<ByteBuffer>(1);
- result.add(asReadOnlyByteBuffer());
- return result;
- }
-
- @Override
- public void writeTo(OutputStream outputStream) throws IOException {
- outputStream.write(toByteArray());
- }
-
- @Override
- void writeToInternal(OutputStream outputStream, int sourceOffset,
- int numberToWrite) throws IOException {
- outputStream.write(bytes, getOffsetIntoBytes() + sourceOffset,
- numberToWrite);
- }
-
- @Override
- protected String toStringInternal(Charset charset) {
- return new String(bytes, getOffsetIntoBytes(), size(), charset);
- }
-
- // =================================================================
- // UTF-8 decoding
-
- @Override
- public boolean isValidUtf8() {
- int offset = getOffsetIntoBytes();
- return Utf8.isValidUtf8(bytes, offset, offset + size());
- }
-
- @Override
- protected int partialIsValidUtf8(int state, int offset, int length) {
- int index = getOffsetIntoBytes() + offset;
- return Utf8.partialIsValidUtf8(state, bytes, index, index + length);
- }
-
- // =================================================================
- // equals() and hashCode()
-
- @Override
- public boolean equals(Object other) {
- if (other == this) {
- return true;
- }
- if (!(other instanceof ByteString)) {
- return false;
- }
-
- if (size() != ((ByteString) other).size()) {
- return false;
- }
- if (size() == 0) {
- return true;
- }
-
- if (other instanceof LiteralByteString) {
- LiteralByteString otherAsLiteral = (LiteralByteString) other;
- // If we know the hash codes and they are not equal, we know the byte
- // strings are not equal.
- if (hash != 0
- && otherAsLiteral.hash != 0
- && hash != otherAsLiteral.hash) {
- return false;
- }
-
- return equalsRange((LiteralByteString) other, 0, size());
- } else if (other instanceof RopeByteString) {
- return other.equals(this);
- } else {
- throw new IllegalArgumentException(
- "Has a new type of ByteString been created? Found "
- + other.getClass());
- }
- }
-
- /**
- * Check equality of the substring of given length of this object starting at
- * zero with another {@code LiteralByteString} substring starting at offset.
- *
- * @param other what to compare a substring in
- * @param offset offset into other
- * @param length number of bytes to compare
- * @return true for equality of substrings, else false.
- */
- boolean equalsRange(LiteralByteString other, int offset, int length) {
- if (length > other.size()) {
- throw new IllegalArgumentException(
- "Length too large: " + length + size());
- }
- if (offset + length > other.size()) {
- throw new IllegalArgumentException(
- "Ran off end of other: " + offset + ", " + length + ", " +
- other.size());
- }
-
- byte[] thisBytes = bytes;
- byte[] otherBytes = other.bytes;
- int thisLimit = getOffsetIntoBytes() + length;
- for (int thisIndex = getOffsetIntoBytes(), otherIndex =
- other.getOffsetIntoBytes() + offset;
- (thisIndex < thisLimit); ++thisIndex, ++otherIndex) {
- if (thisBytes[thisIndex] != otherBytes[otherIndex]) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Cached hash value. Intentionally accessed via a data race, which
- * is safe because of the Java Memory Model's "no out-of-thin-air values"
- * guarantees for ints.
- */
- private int hash = 0;
-
- /**
- * Compute the hashCode using the traditional algorithm from {@link
- * ByteString}.
- *
- * @return hashCode value
- */
- @Override
- public int hashCode() {
- int h = hash;
-
- if (h == 0) {
- int size = size();
- h = partialHash(size, 0, size);
- if (h == 0) {
- h = 1;
- }
- hash = h;
- }
- return h;
- }
-
- @Override
- protected int peekCachedHashCode() {
- return hash;
- }
-
- @Override
- protected int partialHash(int h, int offset, int length) {
- return hashCode(h, bytes, getOffsetIntoBytes() + offset, length);
- }
-
- static int hashCode(int h, byte[] bytes, int offset, int length) {
- for (int i = offset; i < offset + length; i++) {
- h = h * 31 + bytes[i];
- }
- return h;
- }
-
- static int hashCode(byte[] bytes) {
- int h = hashCode(bytes.length, bytes, 0, bytes.length);
- return h == 0 ? 1 : h;
- }
-
- // =================================================================
- // Input stream
-
- @Override
- public InputStream newInput() {
- return new ByteArrayInputStream(bytes, getOffsetIntoBytes(),
- size()); // No copy
- }
-
- @Override
- public CodedInputStream newCodedInput() {
- // We trust CodedInputStream not to modify the bytes, or to give anyone
- // else access to them.
- return CodedInputStream.newInstance(this);
- }
-
- // =================================================================
- // ByteIterator
-
- @Override
- public ByteIterator iterator() {
- return new LiteralByteIterator();
- }
-
- private class LiteralByteIterator implements ByteIterator {
- private int position;
- private final int limit;
-
- private LiteralByteIterator() {
- position = 0;
- limit = size();
- }
-
- public boolean hasNext() {
- return (position < limit);
- }
-
- public Byte next() {
- // Boxing calls Byte.valueOf(byte), which does not instantiate.
- return nextByte();
- }
-
- public byte nextByte() {
- try {
- return bytes[position++];
- } catch (ArrayIndexOutOfBoundsException e) {
- throw new NoSuchElementException(e.getMessage());
- }
- }
-
- public void remove() {
- throw new UnsupportedOperationException();
- }
- }
-
- // =================================================================
- // Internal methods
-
- @Override
- protected int getTreeDepth() {
- return 0;
- }
-
- @Override
- protected boolean isBalanced() {
- return true;
- }
-
- /**
- * Offset into {@code bytes[]} to use, non-zero for substrings.
- *
- * @return always 0 for this class
- */
- protected int getOffsetIntoBytes() {
- return 0;
- }
-}
diff --git a/java/src/main/java/com/google/protobuf/MapEntryLite.java b/java/src/main/java/com/google/protobuf/MapEntryLite.java
deleted file mode 100644
index bcffa946..00000000
--- a/java/src/main/java/com/google/protobuf/MapEntryLite.java
+++ /dev/null
@@ -1,331 +0,0 @@
-// 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.
-
-package com.google.protobuf;
-
-import java.io.IOException;
-
-/**
- * Implements the lite version of map entry messages.
- *
- * This class serves as an utility class to help do serialization/parsing of
- * map entries. It's used in generated code and also in the full version
- * MapEntry message.
- *
- * Protobuf internal. Users shouldn't use.
- */
-public class MapEntryLite<K, V> extends AbstractMessageLite {
- private static class Metadata<K, V> {
- public final MapEntryLite<K, V> defaultInstance;
- public final WireFormat.FieldType keyType;
- public final WireFormat.FieldType valueType;
- public final Parser<MapEntryLite<K, V>> parser;
- public Metadata(
- MapEntryLite<K, V> defaultInstance,
- WireFormat.FieldType keyType,
- WireFormat.FieldType valueType) {
- this.defaultInstance = defaultInstance;
- this.keyType = keyType;
- this.valueType = valueType;
- final Metadata<K, V> finalThis = this;
- this.parser = new AbstractParser<MapEntryLite<K, V>>() {
- @Override
- public MapEntryLite<K, V> parsePartialFrom(
- CodedInputStream input, ExtensionRegistryLite extensionRegistry)
- throws InvalidProtocolBufferException {
- return new MapEntryLite<K, V>(finalThis, input, extensionRegistry);
- }
- };
- }
- }
-
- private static final int KEY_FIELD_NUMBER = 1;
- private static final int VALUE_FIELD_NUMBER = 2;
-
- private final Metadata<K, V> metadata;
- private final K key;
- private final V value;
-
- /** Creates a default MapEntryLite message instance. */
- private MapEntryLite(
- WireFormat.FieldType keyType, K defaultKey,
- WireFormat.FieldType valueType, V defaultValue) {
- this.metadata = new Metadata<K, V>(this, keyType, valueType);
- this.key = defaultKey;
- this.value = defaultValue;
- }
-
- /** Creates a new MapEntryLite message. */
- private MapEntryLite(Metadata<K, V> metadata, K key, V value) {
- this.metadata = metadata;
- this.key = key;
- this.value = value;
- }
-
- public K getKey() {
- return key;
- }
-
- public V getValue() {
- return value;
- }
-
- /**
- * Creates a default MapEntryLite message instance.
- *
- * This method is used by generated code to create the default instance for
- * a map entry message. The created default instance should be used to create
- * new map entry messages of the same type. For each map entry message, only
- * one default instance should be created.
- */
- public static <K, V> MapEntryLite<K, V> newDefaultInstance(
- WireFormat.FieldType keyType, K defaultKey,
- WireFormat.FieldType valueType, V defaultValue) {
- return new MapEntryLite<K, V>(
- keyType, defaultKey, valueType, defaultValue);
- }
-
- @Override
- public void writeTo(CodedOutputStream output) throws IOException {
- writeField(KEY_FIELD_NUMBER, metadata.keyType, key, output);
- writeField(VALUE_FIELD_NUMBER, metadata.valueType, value, output);
- }
-
- private void writeField(
- int number, WireFormat.FieldType type, Object value,
- CodedOutputStream output) throws IOException {
- output.writeTag(number, type.getWireType());
- FieldSet.writeElementNoTag(output, type, value);
- }
-
- private volatile int cachedSerializedSize = -1;
- @Override
- public int getSerializedSize() {
- if (cachedSerializedSize != -1) {
- return cachedSerializedSize;
- }
- int size = 0;
- size += getFieldSize(KEY_FIELD_NUMBER, metadata.keyType, key);
- size += getFieldSize(VALUE_FIELD_NUMBER, metadata.valueType, value);
- cachedSerializedSize = size;
- return size;
- }
-
- private int getFieldSize(
- int number, WireFormat.FieldType type, Object value) {
- return CodedOutputStream.computeTagSize(number)
- + FieldSet.computeElementSizeNoTag(type, value);
- }
-
- /** Parsing constructor. */
- private MapEntryLite(
- Metadata<K, V> metadata,
- CodedInputStream input,
- ExtensionRegistryLite extensionRegistry)
- throws InvalidProtocolBufferException {
- try {
- K key = metadata.defaultInstance.key;
- V value = metadata.defaultInstance.value;
- while (true) {
- int tag = input.readTag();
- if (tag == 0) {
- break;
- }
- if (tag == WireFormat.makeTag(
- KEY_FIELD_NUMBER, metadata.keyType.getWireType())) {
- key = mergeField(
- input, extensionRegistry, metadata.keyType, key);
- } else if (tag == WireFormat.makeTag(
- VALUE_FIELD_NUMBER, metadata.valueType.getWireType())) {
- value = mergeField(
- input, extensionRegistry, metadata.valueType, value);
- } else {
- if (!input.skipField(tag)) {
- break;
- }
- }
- }
- this.metadata = metadata;
- this.key = key;
- this.value = value;
- } catch (InvalidProtocolBufferException e) {
- throw e.setUnfinishedMessage(this);
- } catch (IOException e) {
- throw new InvalidProtocolBufferException(e.getMessage())
- .setUnfinishedMessage(this);
- }
- }
-
- @SuppressWarnings("unchecked")
- private <T> T mergeField(
- CodedInputStream input, ExtensionRegistryLite extensionRegistry,
- WireFormat.FieldType type, T value) throws IOException {
- switch (type) {
- case MESSAGE:
- MessageLite.Builder subBuilder = ((MessageLite) value).toBuilder();
- input.readMessage(subBuilder, extensionRegistry);
- return (T) subBuilder.buildPartial();
- case ENUM:
- return (T) (java.lang.Integer) input.readEnum();
- case GROUP:
- throw new RuntimeException("Groups are not allowed in maps.");
- default:
- return (T) FieldSet.readPrimitiveField(input, type, true);
- }
- }
-
- @Override
- public Parser<MapEntryLite<K, V>> getParserForType() {
- return metadata.parser;
- }
-
- @Override
- public Builder<K, V> newBuilderForType() {
- return new Builder<K, V>(metadata);
- }
-
- @Override
- public Builder<K, V> toBuilder() {
- return new Builder<K, V>(metadata, key, value);
- }
-
- @Override
- public MapEntryLite<K, V> getDefaultInstanceForType() {
- return metadata.defaultInstance;
- }
-
- @Override
- public boolean isInitialized() {
- if (metadata.valueType.getJavaType() == WireFormat.JavaType.MESSAGE) {
- return ((MessageLite) value).isInitialized();
- }
- return true;
- }
-
- /**
- * Builder used to create {@link MapEntryLite} messages.
- */
- public static class Builder<K, V>
- extends AbstractMessageLite.Builder<Builder<K, V>> {
- private final Metadata<K, V> metadata;
- private K key;
- private V value;
-
- private Builder(Metadata<K, V> metadata) {
- this.metadata = metadata;
- this.key = metadata.defaultInstance.key;
- this.value = metadata.defaultInstance.value;
- }
-
- public K getKey() {
- return key;
- }
-
- public V getValue() {
- return value;
- }
-
- public Builder<K, V> setKey(K key) {
- this.key = key;
- return this;
- }
-
- public Builder<K, V> setValue(V value) {
- this.value = value;
- return this;
- }
-
- public Builder<K, V> clearKey() {
- this.key = metadata.defaultInstance.key;
- return this;
- }
-
- public Builder<K, V> clearValue() {
- this.value = metadata.defaultInstance.value;
- return this;
- }
-
- @Override
- public Builder<K, V> clear() {
- this.key = metadata.defaultInstance.key;
- this.value = metadata.defaultInstance.value;
- return this;
- }
-
- @Override
- public MapEntryLite<K, V> build() {
- MapEntryLite<K, V> result = buildPartial();
- if (!result.isInitialized()) {
- throw newUninitializedMessageException(result);
- }
- return result;
- }
-
- @Override
- public MapEntryLite<K, V> buildPartial() {
- return new MapEntryLite<K, V>(metadata, key, value);
- }
-
- @Override
- public MessageLite getDefaultInstanceForType() {
- return metadata.defaultInstance;
- }
-
- @Override
- public boolean isInitialized() {
- if (metadata.valueType.getJavaType() == WireFormat.JavaType.MESSAGE) {
- return ((MessageLite) value).isInitialized();
- }
- return true;
- }
-
- private Builder(Metadata<K, V> metadata, K key, V value) {
- this.metadata = metadata;
- this.key = key;
- this.value = value;
- }
-
- @Override
- public Builder<K, V> clone() {
- return new Builder<K, V>(metadata, key, value);
- }
-
- @Override
- public Builder<K, V> mergeFrom(
- CodedInputStream input, ExtensionRegistryLite extensionRegistry)
- throws IOException {
- MapEntryLite<K, V> entry =
- new MapEntryLite<K, V>(metadata, input, extensionRegistry);
- this.key = entry.key;
- this.value = entry.value;
- return this;
- }
- }
-}
diff --git a/java/src/main/java/com/google/protobuf/MapFieldLite.java b/java/src/main/java/com/google/protobuf/MapFieldLite.java
deleted file mode 100644
index c17fa7b1..00000000
--- a/java/src/main/java/com/google/protobuf/MapFieldLite.java
+++ /dev/null
@@ -1,546 +0,0 @@
-// 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.
-
-package com.google.protobuf;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Internal representation of map fields in generated lite-runtime messages.
- *
- * This class is a protobuf implementation detail. Users shouldn't use this
- * class directly.
- */
-public class MapFieldLite<K, V> implements MutabilityOracle {
- private MutatabilityAwareMap<K, V> mapData;
- private boolean isMutable;
-
- private MapFieldLite(Map<K, V> mapData) {
- this.mapData = new MutatabilityAwareMap<K, V>(this, mapData);
- this.isMutable = true;
- }
-
- @SuppressWarnings({"rawtypes", "unchecked"})
- private static final MapFieldLite EMPTY_MAP_FIELD =
- new MapFieldLite(Collections.emptyMap());
- static {
- EMPTY_MAP_FIELD.makeImmutable();
- }
-
- /** Returns an singleton immutable empty MapFieldLite instance. */
- @SuppressWarnings({"unchecked", "cast"})
- public static <K, V> MapFieldLite<K, V> emptyMapField() {
- return (MapFieldLite<K, V>) EMPTY_MAP_FIELD;
- }
-
- /** Creates a new MapFieldLite instance. */
- public static <K, V> MapFieldLite<K, V> newMapField() {
- return new MapFieldLite<K, V>(new LinkedHashMap<K, V>());
- }
-
- /** Gets the content of this MapField as a read-only Map. */
- public Map<K, V> getMap() {
- return Collections.unmodifiableMap(mapData);
- }
-
- /** Gets a mutable Map view of this MapField. */
- public Map<K, V> getMutableMap() {
- return mapData;
- }
-
- public void mergeFrom(MapFieldLite<K, V> other) {
- mapData.putAll(copy(other.mapData));
- }
-
- public void clear() {
- mapData.clear();
- }
-
- private static boolean equals(Object a, Object b) {
- if (a instanceof byte[] && b instanceof byte[]) {
- return Arrays.equals((byte[]) a, (byte[]) b);
- }
- return a.equals(b);
- }
-
- /**
- * Checks whether two {@link Map}s are equal. We don't use the default equals
- * method of {@link Map} because it compares by identity not by content for
- * byte arrays.
- */
- static <K, V> boolean equals(Map<K, V> a, Map<K, V> b) {
- if (a == b) {
- return true;
- }
- if (a.size() != b.size()) {
- return false;
- }
- for (Map.Entry<K, V> entry : a.entrySet()) {
- if (!b.containsKey(entry.getKey())) {
- return false;
- }
- if (!equals(entry.getValue(), b.get(entry.getKey()))) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Checks whether two map fields are equal.
- */
- @SuppressWarnings("unchecked")
- @Override
- public boolean equals(Object object) {
- if (!(object instanceof MapFieldLite)) {
- return false;
- }
- MapFieldLite<K, V> other = (MapFieldLite<K, V>) object;
- return equals(mapData, other.mapData);
- }
-
- private static int calculateHashCodeForObject(Object a) {
- if (a instanceof byte[]) {
- return LiteralByteString.hashCode((byte[]) a);
- }
- if (a instanceof Internal.EnumLite) {
- return Internal.hashEnum((Internal.EnumLite) a);
- }
- return a.hashCode();
- }
-
- /**
- * Calculates the hash code for a {@link Map}. We don't use the default hash
- * code method of {@link Map} because for byte arrays and protobuf enums it
- * use {@link Object#hashCode()}.
- */
- static <K, V> int calculateHashCodeForMap(Map<K, V> a) {
- int result = 0;
- for (Map.Entry<K, V> entry : a.entrySet()) {
- result += calculateHashCodeForObject(entry.getKey())
- ^ calculateHashCodeForObject(entry.getValue());
- }
- return result;
- }
-
- @Override
- public int hashCode() {
- return calculateHashCodeForMap(mapData);
- }
-
- private static Object copy(Object object) {
- if (object instanceof byte[]) {
- byte[] data = (byte[]) object;
- return Arrays.copyOf(data, data.length);
- }
- return object;
- }
-
- /**
- * Makes a deep copy of a {@link Map}. Immutable objects in the map will be
- * shared (e.g., integers, strings, immutable messages) and mutable ones will
- * have a copy (e.g., byte arrays, mutable messages).
- */
- @SuppressWarnings("unchecked")
- static <K, V> Map<K, V> copy(Map<K, V> map) {
- Map<K, V> result = new LinkedHashMap<K, V>();
- for (Map.Entry<K, V> entry : map.entrySet()) {
- result.put(entry.getKey(), (V) copy(entry.getValue()));
- }
- return result;
- }
-
- /** Returns a deep copy of this map field. */
- public MapFieldLite<K, V> copy() {
- return new MapFieldLite<K, V>(copy(mapData));
- }
-
- /**
- * Makes this field immutable. All subsequent modifications will throw an
- * {@link UnsupportedOperationException}.
- */
- public void makeImmutable() {
- isMutable = false;
- }
-
- /**
- * Returns whether this field can be modified.
- */
- public boolean isMutable() {
- return isMutable;
- }
-
- @Override
- public void ensureMutable() {
- if (!isMutable()) {
- throw new UnsupportedOperationException();
- }
- }
-
- /**
- * An internal map that checks for mutability before delegating.
- */
- static class MutatabilityAwareMap<K, V> implements Map<K, V> {
- private final MutabilityOracle mutabilityOracle;
- private final Map<K, V> delegate;
-
- MutatabilityAwareMap(MutabilityOracle mutabilityOracle, Map<K, V> delegate) {
- this.mutabilityOracle = mutabilityOracle;
- this.delegate = delegate;
- }
-
- @Override
- public int size() {
- return delegate.size();
- }
-
- @Override
- public boolean isEmpty() {
- return delegate.isEmpty();
- }
-
- @Override
- public boolean containsKey(Object key) {
- return delegate.containsKey(key);
- }
-
- @Override
- public boolean containsValue(Object value) {
- return delegate.containsValue(value);
- }
-
- @Override
- public V get(Object key) {
- return delegate.get(key);
- }
-
- @Override
- public V put(K key, V value) {
- mutabilityOracle.ensureMutable();
- return delegate.put(key, value);
- }
-
- @Override
- public V remove(Object key) {
- mutabilityOracle.ensureMutable();
- return delegate.remove(key);
- }
-
- @Override
- public void putAll(Map<? extends K, ? extends V> m) {
- mutabilityOracle.ensureMutable();
- delegate.putAll(m);
- }
-
- @Override
- public void clear() {
- mutabilityOracle.ensureMutable();
- delegate.clear();
- }
-
- @Override
- public Set<K> keySet() {
- return new MutatabilityAwareSet<K>(mutabilityOracle, delegate.keySet());
- }
-
- @Override
- public Collection<V> values() {
- return new MutatabilityAwareCollection<V>(mutabilityOracle, delegate.values());
- }
-
- @Override
- public Set<java.util.Map.Entry<K, V>> entrySet() {
- return new MutatabilityAwareSet<Entry<K, V>>(mutabilityOracle, delegate.entrySet());
- }
-
- @Override
- public boolean equals(Object o) {
- return delegate.equals(o);
- }
-
- @Override
- public int hashCode() {
- return delegate.hashCode();
- }
-
- @Override
- public String toString() {
- return delegate.toString();
- }
- }
-
- /**
- * An internal collection that checks for mutability before delegating.
- */
- private static class MutatabilityAwareCollection<E> implements Collection<E> {
- private final MutabilityOracle mutabilityOracle;
- private final Collection<E> delegate;
-
- MutatabilityAwareCollection(MutabilityOracle mutabilityOracle, Collection<E> delegate) {
- this.mutabilityOracle = mutabilityOracle;
- this.delegate = delegate;
- }
-
- @Override
- public int size() {
- return delegate.size();
- }
-
- @Override
- public boolean isEmpty() {
- return delegate.isEmpty();
- }
-
- @Override
- public boolean contains(Object o) {
- return delegate.contains(o);
- }
-
- @Override
- public Iterator<E> iterator() {
- return new MutatabilityAwareIterator<E>(mutabilityOracle, delegate.iterator());
- }
-
- @Override
- public Object[] toArray() {
- return delegate.toArray();
- }
-
- @Override
- public <T> T[] toArray(T[] a) {
- return delegate.toArray(a);
- }
-
- @Override
- public boolean add(E e) {
- // Unsupported operation in the delegate.
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean remove(Object o) {
- mutabilityOracle.ensureMutable();
- return delegate.remove(o);
- }
-
- @Override
- public boolean containsAll(Collection<?> c) {
- return delegate.containsAll(c);
- }
-
- @Override
- public boolean addAll(Collection<? extends E> c) {
- // Unsupported operation in the delegate.
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean removeAll(Collection<?> c) {
- mutabilityOracle.ensureMutable();
- return delegate.removeAll(c);
- }
-
- @Override
- public boolean retainAll(Collection<?> c) {
- mutabilityOracle.ensureMutable();
- return delegate.retainAll(c);
- }
-
- @Override
- public void clear() {
- mutabilityOracle.ensureMutable();
- delegate.clear();
- }
-
- @Override
- public boolean equals(Object o) {
- return delegate.equals(o);
- }
-
- @Override
- public int hashCode() {
- return delegate.hashCode();
- }
-
- @Override
- public String toString() {
- return delegate.toString();
- }
- }
-
- /**
- * An internal set that checks for mutability before delegating.
- */
- private static class MutatabilityAwareSet<E> implements Set<E> {
- private final MutabilityOracle mutabilityOracle;
- private final Set<E> delegate;
-
- MutatabilityAwareSet(MutabilityOracle mutabilityOracle, Set<E> delegate) {
- this.mutabilityOracle = mutabilityOracle;
- this.delegate = delegate;
- }
-
- @Override
- public int size() {
- return delegate.size();
- }
-
- @Override
- public boolean isEmpty() {
- return delegate.isEmpty();
- }
-
- @Override
- public boolean contains(Object o) {
- return delegate.contains(o);
- }
-
- @Override
- public Iterator<E> iterator() {
- return new MutatabilityAwareIterator<E>(mutabilityOracle, delegate.iterator());
- }
-
- @Override
- public Object[] toArray() {
- return delegate.toArray();
- }
-
- @Override
- public <T> T[] toArray(T[] a) {
- return delegate.toArray(a);
- }
-
- @Override
- public boolean add(E e) {
- mutabilityOracle.ensureMutable();
- return delegate.add(e);
- }
-
- @Override
- public boolean remove(Object o) {
- mutabilityOracle.ensureMutable();
- return delegate.remove(o);
- }
-
- @Override
- public boolean containsAll(Collection<?> c) {
- return delegate.containsAll(c);
- }
-
- @Override
- public boolean addAll(Collection<? extends E> c) {
- mutabilityOracle.ensureMutable();
- return delegate.addAll(c);
- }
-
- @Override
- public boolean retainAll(Collection<?> c) {
- mutabilityOracle.ensureMutable();
- return delegate.retainAll(c);
- }
-
- @Override
- public boolean removeAll(Collection<?> c) {
- mutabilityOracle.ensureMutable();
- return delegate.removeAll(c);
- }
-
- @Override
- public void clear() {
- mutabilityOracle.ensureMutable();
- delegate.clear();
- }
-
- @Override
- public boolean equals(Object o) {
- return delegate.equals(o);
- }
-
- @Override
- public int hashCode() {
- return delegate.hashCode();
- }
-
- @Override
- public String toString() {
- return delegate.toString();
- }
- }
-
- /**
- * An internal iterator that checks for mutability before delegating.
- */
- private static class MutatabilityAwareIterator<E> implements Iterator<E> {
- private final MutabilityOracle mutabilityOracle;
- private final Iterator<E> delegate;
-
- MutatabilityAwareIterator(MutabilityOracle mutabilityOracle, Iterator<E> delegate) {
- this.mutabilityOracle = mutabilityOracle;
- this.delegate = delegate;
- }
-
- @Override
- public boolean hasNext() {
- return delegate.hasNext();
- }
-
- @Override
- public E next() {
- return delegate.next();
- }
-
- @Override
- public void remove() {
- mutabilityOracle.ensureMutable();
- delegate.remove();
- }
-
- @Override
- public boolean equals(Object obj) {
- return delegate.equals(obj);
- }
-
- @Override
- public int hashCode() {
- return delegate.hashCode();
- }
-
- @Override
- public String toString() {
- return delegate.toString();
- }
- }
-}
diff --git a/java/src/main/java/com/google/protobuf/Utf8.java b/java/src/main/java/com/google/protobuf/Utf8.java
deleted file mode 100644
index 48c7e9e6..00000000
--- a/java/src/main/java/com/google/protobuf/Utf8.java
+++ /dev/null
@@ -1,481 +0,0 @@
-// 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.
-
-package com.google.protobuf;
-
-/**
- * A set of low-level, high-performance static utility methods related
- * to the UTF-8 character encoding. This class has no dependencies
- * outside of the core JDK libraries.
- *
- * <p>There are several variants of UTF-8. The one implemented by
- * this class is the restricted definition of UTF-8 introduced in
- * Unicode 3.1, which mandates the rejection of "overlong" byte
- * sequences as well as rejection of 3-byte surrogate codepoint byte
- * sequences. Note that the UTF-8 decoder included in Oracle's JDK
- * has been modified to also reject "overlong" byte sequences, but (as
- * of 2011) still accepts 3-byte surrogate codepoint byte sequences.
- *
- * <p>The byte sequences considered valid by this class are exactly
- * those that can be roundtrip converted to Strings and back to bytes
- * using the UTF-8 charset, without loss: <pre> {@code
- * Arrays.equals(bytes, new String(bytes, Internal.UTF_8).getBytes(Internal.UTF_8))
- * }</pre>
- *
- * <p>See the Unicode Standard,</br>
- * Table 3-6. <em>UTF-8 Bit Distribution</em>,</br>
- * Table 3-7. <em>Well Formed UTF-8 Byte Sequences</em>.
- *
- * <p>This class supports decoding of partial byte sequences, so that the
- * bytes in a complete UTF-8 byte sequences can be stored in multiple
- * segments. Methods typically return {@link #MALFORMED} if the partial
- * byte sequence is definitely not well-formed, {@link #COMPLETE} if it is
- * well-formed in the absence of additional input, or if the byte sequence
- * apparently terminated in the middle of a character, an opaque integer
- * "state" value containing enough information to decode the character when
- * passed to a subsequent invocation of a partial decoding method.
- *
- * @author martinrb@google.com (Martin Buchholz)
- */
-final class Utf8 {
- private Utf8() {}
-
- /**
- * Maximum number of bytes per Java UTF-16 char in UTF-8.
- * @see java.nio.charset.CharsetEncoder#maxBytesPerChar()
- */
- static final int MAX_BYTES_PER_CHAR = 3;
-
- /**
- * State value indicating that the byte sequence is well-formed and
- * complete (no further bytes are needed to complete a character).
- */
- public static final int COMPLETE = 0;
-
- /**
- * State value indicating that the byte sequence is definitely not
- * well-formed.
- */
- public static final int MALFORMED = -1;
-
- // Other state values include the partial bytes of the incomplete
- // character to be decoded in the simplest way: we pack the bytes
- // into the state int in little-endian order. For example:
- //
- // int state = byte1 ^ (byte2 << 8) ^ (byte3 << 16);
- //
- // Such a state is unpacked thus (note the ~ operation for byte2 to
- // undo byte1's sign-extension bits):
- //
- // int byte1 = (byte) state;
- // int byte2 = (byte) ~(state >> 8);
- // int byte3 = (byte) (state >> 16);
- //
- // We cannot store a zero byte in the state because it would be
- // indistinguishable from the absence of a byte. But we don't need
- // to, because partial bytes must always be negative. When building
- // a state, we ensure that byte1 is negative and subsequent bytes
- // are valid trailing bytes.
-
- /**
- * Returns {@code true} if the given byte array is a well-formed
- * UTF-8 byte sequence.
- *
- * <p>This is a convenience method, equivalent to a call to {@code
- * isValidUtf8(bytes, 0, bytes.length)}.
- */
- public static boolean isValidUtf8(byte[] bytes) {
- return isValidUtf8(bytes, 0, bytes.length);
- }
-
- /**
- * Returns {@code true} if the given byte array slice is a
- * well-formed UTF-8 byte sequence. The range of bytes to be
- * checked extends from index {@code index}, inclusive, to {@code
- * limit}, exclusive.
- *
- * <p>This is a convenience method, equivalent to {@code
- * partialIsValidUtf8(bytes, index, limit) == Utf8.COMPLETE}.
- */
- public static boolean isValidUtf8(byte[] bytes, int index, int limit) {
- return partialIsValidUtf8(bytes, index, limit) == COMPLETE;
- }
-
- /**
- * Tells whether the given byte array slice is a well-formed,
- * malformed, or incomplete UTF-8 byte sequence. The range of bytes
- * to be checked extends from index {@code index}, inclusive, to
- * {@code limit}, exclusive.
- *
- * @param state either {@link Utf8#COMPLETE} (if this is the initial decoding
- * operation) or the value returned from a call to a partial decoding method
- * for the previous bytes
- *
- * @return {@link #MALFORMED} if the partial byte sequence is
- * definitely not well-formed, {@link #COMPLETE} if it is well-formed
- * (no additional input needed), or if the byte sequence is
- * "incomplete", i.e. apparently terminated in the middle of a character,
- * an opaque integer "state" value containing enough information to
- * decode the character when passed to a subsequent invocation of a
- * partial decoding method.
- */
- public static int partialIsValidUtf8(
- int state, byte[] bytes, int index, int limit) {
- if (state != COMPLETE) {
- // The previous decoding operation was incomplete (or malformed).
- // We look for a well-formed sequence consisting of bytes from
- // the previous decoding operation (stored in state) together
- // with bytes from the array slice.
- //
- // We expect such "straddler characters" to be rare.
-
- if (index >= limit) { // No bytes? No progress.
- return state;
- }
- int byte1 = (byte) state;
- // byte1 is never ASCII.
- if (byte1 < (byte) 0xE0) {
- // two-byte form
-
- // Simultaneously checks for illegal trailing-byte in
- // leading position and overlong 2-byte form.
- if (byte1 < (byte) 0xC2 ||
- // byte2 trailing-byte test
- bytes[index++] > (byte) 0xBF) {
- return MALFORMED;
- }
- } else if (byte1 < (byte) 0xF0) {
- // three-byte form
-
- // Get byte2 from saved state or array
- int byte2 = (byte) ~(state >> 8);
- if (byte2 == 0) {
- byte2 = bytes[index++];
- if (index >= limit) {
- return incompleteStateFor(byte1, byte2);
- }
- }
- if (byte2 > (byte) 0xBF ||
- // overlong? 5 most significant bits must not all be zero
- (byte1 == (byte) 0xE0 && byte2 < (byte) 0xA0) ||
- // illegal surrogate codepoint?
- (byte1 == (byte) 0xED && byte2 >= (byte) 0xA0) ||
- // byte3 trailing-byte test
- bytes[index++] > (byte) 0xBF) {
- return MALFORMED;
- }
- } else {
- // four-byte form
-
- // Get byte2 and byte3 from saved state or array
- int byte2 = (byte) ~(state >> 8);
- int byte3 = 0;
- if (byte2 == 0) {
- byte2 = bytes[index++];
- if (index >= limit) {
- return incompleteStateFor(byte1, byte2);
- }
- } else {
- byte3 = (byte) (state >> 16);
- }
- if (byte3 == 0) {
- byte3 = bytes[index++];
- if (index >= limit) {
- return incompleteStateFor(byte1, byte2, byte3);
- }
- }
-
- // If we were called with state == MALFORMED, then byte1 is 0xFF,
- // which never occurs in well-formed UTF-8, and so we will return
- // MALFORMED again below.
-
- if (byte2 > (byte) 0xBF ||
- // Check that 1 <= plane <= 16. Tricky optimized form of:
- // if (byte1 > (byte) 0xF4 ||
- // byte1 == (byte) 0xF0 && byte2 < (byte) 0x90 ||
- // byte1 == (byte) 0xF4 && byte2 > (byte) 0x8F)
- (((byte1 << 28) + (byte2 - (byte) 0x90)) >> 30) != 0 ||
- // byte3 trailing-byte test
- byte3 > (byte) 0xBF ||
- // byte4 trailing-byte test
- bytes[index++] > (byte) 0xBF) {
- return MALFORMED;
- }
- }
- }
-
- return partialIsValidUtf8(bytes, index, limit);
- }
-
- /**
- * Tells whether the given byte array slice is a well-formed,
- * malformed, or incomplete UTF-8 byte sequence. The range of bytes
- * to be checked extends from index {@code index}, inclusive, to
- * {@code limit}, exclusive.
- *
- * <p>This is a convenience method, equivalent to a call to {@code
- * partialIsValidUtf8(Utf8.COMPLETE, bytes, index, limit)}.
- *
- * @return {@link #MALFORMED} if the partial byte sequence is
- * definitely not well-formed, {@link #COMPLETE} if it is well-formed
- * (no additional input needed), or if the byte sequence is
- * "incomplete", i.e. apparently terminated in the middle of a character,
- * an opaque integer "state" value containing enough information to
- * decode the character when passed to a subsequent invocation of a
- * partial decoding method.
- */
- public static int partialIsValidUtf8(
- byte[] bytes, int index, int limit) {
- // Optimize for 100% ASCII.
- // Hotspot loves small simple top-level loops like this.
- while (index < limit && bytes[index] >= 0) {
- index++;
- }
-
- return (index >= limit) ? COMPLETE :
- partialIsValidUtf8NonAscii(bytes, index, limit);
- }
-
- private static int partialIsValidUtf8NonAscii(
- byte[] bytes, int index, int limit) {
- for (;;) {
- int byte1, byte2;
-
- // Optimize for interior runs of ASCII bytes.
- do {
- if (index >= limit) {
- return COMPLETE;
- }
- } while ((byte1 = bytes[index++]) >= 0);
-
- if (byte1 < (byte) 0xE0) {
- // two-byte form
-
- if (index >= limit) {
- return byte1;
- }
-
- // Simultaneously checks for illegal trailing-byte in
- // leading position and overlong 2-byte form.
- if (byte1 < (byte) 0xC2 ||
- bytes[index++] > (byte) 0xBF) {
- return MALFORMED;
- }
- } else if (byte1 < (byte) 0xF0) {
- // three-byte form
-
- if (index >= limit - 1) { // incomplete sequence
- return incompleteStateFor(bytes, index, limit);
- }
- if ((byte2 = bytes[index++]) > (byte) 0xBF ||
- // overlong? 5 most significant bits must not all be zero
- (byte1 == (byte) 0xE0 && byte2 < (byte) 0xA0) ||
- // check for illegal surrogate codepoints
- (byte1 == (byte) 0xED && byte2 >= (byte) 0xA0) ||
- // byte3 trailing-byte test
- bytes[index++] > (byte) 0xBF) {
- return MALFORMED;
- }
- } else {
- // four-byte form
-
- if (index >= limit - 2) { // incomplete sequence
- return incompleteStateFor(bytes, index, limit);
- }
- if ((byte2 = bytes[index++]) > (byte) 0xBF ||
- // Check that 1 <= plane <= 16. Tricky optimized form of:
- // if (byte1 > (byte) 0xF4 ||
- // byte1 == (byte) 0xF0 && byte2 < (byte) 0x90 ||
- // byte1 == (byte) 0xF4 && byte2 > (byte) 0x8F)
- (((byte1 << 28) + (byte2 - (byte) 0x90)) >> 30) != 0 ||
- // byte3 trailing-byte test
- bytes[index++] > (byte) 0xBF ||
- // byte4 trailing-byte test
- bytes[index++] > (byte) 0xBF) {
- return MALFORMED;
- }
- }
- }
- }
-
- private static int incompleteStateFor(int byte1) {
- return (byte1 > (byte) 0xF4) ?
- MALFORMED : byte1;
- }
-
- private static int incompleteStateFor(int byte1, int byte2) {
- return (byte1 > (byte) 0xF4 ||
- byte2 > (byte) 0xBF) ?
- MALFORMED : byte1 ^ (byte2 << 8);
- }
-
- private static int incompleteStateFor(int byte1, int byte2, int byte3) {
- return (byte1 > (byte) 0xF4 ||
- byte2 > (byte) 0xBF ||
- byte3 > (byte) 0xBF) ?
- MALFORMED : byte1 ^ (byte2 << 8) ^ (byte3 << 16);
- }
-
- private static int incompleteStateFor(byte[] bytes, int index, int limit) {
- int byte1 = bytes[index - 1];
- switch (limit - index) {
- case 0: return incompleteStateFor(byte1);
- case 1: return incompleteStateFor(byte1, bytes[index]);
- case 2: return incompleteStateFor(byte1, bytes[index], bytes[index + 1]);
- default: throw new AssertionError();
- }
- }
-
-
- // These UTF-8 handling methods are copied from Guava's Utf8 class with a modification to throw
- // a protocol buffer local exception. This exception is then caught in CodedOutputStream so it can
- // fallback to more lenient behavior.
-
- static class UnpairedSurrogateException extends IllegalArgumentException {
-
- private UnpairedSurrogateException(int index, int length) {
- super("Unpaired surrogate at index " + index + " of " + length);
- }
- }
-
- /**
- * Returns the number of bytes in the UTF-8-encoded form of {@code sequence}. For a string,
- * this method is equivalent to {@code string.getBytes(UTF_8).length}, but is more efficient in
- * both time and space.
- *
- * @throws IllegalArgumentException if {@code sequence} contains ill-formed UTF-16 (unpaired
- * surrogates)
- */
- static int encodedLength(CharSequence sequence) {
- // Warning to maintainers: this implementation is highly optimized.
- int utf16Length = sequence.length();
- int utf8Length = utf16Length;
- int i = 0;
-
- // This loop optimizes for pure ASCII.
- while (i < utf16Length && sequence.charAt(i) < 0x80) {
- i++;
- }
-
- // This loop optimizes for chars less than 0x800.
- for (; i < utf16Length; i++) {
- char c = sequence.charAt(i);
- if (c < 0x800) {
- utf8Length += ((0x7f - c) >>> 31); // branch free!
- } else {
- utf8Length += encodedLengthGeneral(sequence, i);
- break;
- }
- }
-
- if (utf8Length < utf16Length) {
- // Necessary and sufficient condition for overflow because of maximum 3x expansion
- throw new IllegalArgumentException("UTF-8 length does not fit in int: "
- + (utf8Length + (1L << 32)));
- }
- return utf8Length;
- }
-
- private static int encodedLengthGeneral(CharSequence sequence, int start) {
- int utf16Length = sequence.length();
- int utf8Length = 0;
- for (int i = start; i < utf16Length; i++) {
- char c = sequence.charAt(i);
- if (c < 0x800) {
- utf8Length += (0x7f - c) >>> 31; // branch free!
- } else {
- utf8Length += 2;
- // jdk7+: if (Character.isSurrogate(c)) {
- if (Character.MIN_SURROGATE <= c && c <= Character.MAX_SURROGATE) {
- // Check that we have a well-formed surrogate pair.
- int cp = Character.codePointAt(sequence, i);
- if (cp < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
- throw new UnpairedSurrogateException(i, utf16Length);
- }
- i++;
- }
- }
- }
- return utf8Length;
- }
-
- static int encode(CharSequence sequence, byte[] bytes, int offset, int length) {
- int utf16Length = sequence.length();
- int j = offset;
- int i = 0;
- int limit = offset + length;
- // Designed to take advantage of
- // https://wikis.oracle.com/display/HotSpotInternals/RangeCheckElimination
- for (char c; i < utf16Length && i + j < limit && (c = sequence.charAt(i)) < 0x80; i++) {
- bytes[j + i] = (byte) c;
- }
- if (i == utf16Length) {
- return j + utf16Length;
- }
- j += i;
- for (char c; i < utf16Length; i++) {
- c = sequence.charAt(i);
- if (c < 0x80 && j < limit) {
- bytes[j++] = (byte) c;
- } else if (c < 0x800 && j <= limit - 2) { // 11 bits, two UTF-8 bytes
- bytes[j++] = (byte) ((0xF << 6) | (c >>> 6));
- bytes[j++] = (byte) (0x80 | (0x3F & c));
- } else if ((c < Character.MIN_SURROGATE || Character.MAX_SURROGATE < c) && j <= limit - 3) {
- // Maximum single-char code point is 0xFFFF, 16 bits, three UTF-8 bytes
- bytes[j++] = (byte) ((0xF << 5) | (c >>> 12));
- bytes[j++] = (byte) (0x80 | (0x3F & (c >>> 6)));
- bytes[j++] = (byte) (0x80 | (0x3F & c));
- } else if (j <= limit - 4) {
- // Minimum code point represented by a surrogate pair is 0x10000, 17 bits, four UTF-8 bytes
- final char low;
- if (i + 1 == sequence.length()
- || !Character.isSurrogatePair(c, (low = sequence.charAt(++i)))) {
- throw new UnpairedSurrogateException((i - 1), utf16Length);
- }
- int codePoint = Character.toCodePoint(c, low);
- bytes[j++] = (byte) ((0xF << 4) | (codePoint >>> 18));
- bytes[j++] = (byte) (0x80 | (0x3F & (codePoint >>> 12)));
- bytes[j++] = (byte) (0x80 | (0x3F & (codePoint >>> 6)));
- bytes[j++] = (byte) (0x80 | (0x3F & codePoint));
- } else {
- // If we are surrogates and we're not a surrogate pair, always throw an
- // IllegalArgumentException instead of an ArrayOutOfBoundsException.
- if ((Character.MIN_SURROGATE <= c && c <= Character.MAX_SURROGATE)
- && (i + 1 == sequence.length()
- || !Character.isSurrogatePair(c, sequence.charAt(i + 1)))) {
- throw new UnpairedSurrogateException(i, utf16Length);
- }
- throw new ArrayIndexOutOfBoundsException("Failed writing " + c + " at index " + j);
- }
- }
- return j;
- }
- // End Guava UTF-8 methods.
-}
diff --git a/java/src/test/java/com/google/protobuf/MapForProto2LiteTest.java b/java/src/test/java/com/google/protobuf/MapForProto2LiteTest.java
deleted file mode 100644
index 3d8c9bc4..00000000
--- a/java/src/test/java/com/google/protobuf/MapForProto2LiteTest.java
+++ /dev/null
@@ -1,458 +0,0 @@
-// 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.
-
-package com.google.protobuf;
-
-import map_lite_test.MapForProto2TestProto.TestMap;
-import map_lite_test.MapForProto2TestProto.TestMap.MessageValue;
-import map_lite_test.MapForProto2TestProto.TestUnknownEnumValue;
-
-import junit.framework.TestCase;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Unit tests for map fields.
- */
-public class MapForProto2LiteTest extends TestCase {
- private void setMapValues(TestMap.Builder builder) {
- builder.getMutableInt32ToInt32Field().put(1, 11);
- builder.getMutableInt32ToInt32Field().put(2, 22);
- builder.getMutableInt32ToInt32Field().put(3, 33);
-
- builder.getMutableInt32ToStringField().put(1, "11");
- builder.getMutableInt32ToStringField().put(2, "22");
- builder.getMutableInt32ToStringField().put(3, "33");
-
- builder.getMutableInt32ToBytesField().put(1, TestUtil.toBytes("11"));
- builder.getMutableInt32ToBytesField().put(2, TestUtil.toBytes("22"));
- builder.getMutableInt32ToBytesField().put(3, TestUtil.toBytes("33"));
-
- builder.getMutableInt32ToEnumField().put(1, TestMap.EnumValue.FOO);
- builder.getMutableInt32ToEnumField().put(2, TestMap.EnumValue.BAR);
- builder.getMutableInt32ToEnumField().put(3, TestMap.EnumValue.BAZ);
-
- builder.getMutableInt32ToMessageField().put(
- 1, MessageValue.newBuilder().setValue(11).build());
- builder.getMutableInt32ToMessageField().put(
- 2, MessageValue.newBuilder().setValue(22).build());
- builder.getMutableInt32ToMessageField().put(
- 3, MessageValue.newBuilder().setValue(33).build());
-
- builder.getMutableStringToInt32Field().put("1", 11);
- builder.getMutableStringToInt32Field().put("2", 22);
- builder.getMutableStringToInt32Field().put("3", 33);
- }
-
- private void copyMapValues(TestMap source, TestMap.Builder destination) {
- destination
- .putAllInt32ToInt32Field(source.getInt32ToInt32Field())
- .putAllInt32ToStringField(source.getInt32ToStringField())
- .putAllInt32ToBytesField(source.getInt32ToBytesField())
- .putAllInt32ToEnumField(source.getInt32ToEnumField())
- .putAllInt32ToMessageField(source.getInt32ToMessageField())
- .putAllStringToInt32Field(source.getStringToInt32Field());
- }
-
- private void assertMapValuesSet(TestMap message) {
- assertEquals(3, message.getInt32ToInt32Field().size());
- assertEquals(11, message.getInt32ToInt32Field().get(1).intValue());
- assertEquals(22, message.getInt32ToInt32Field().get(2).intValue());
- assertEquals(33, message.getInt32ToInt32Field().get(3).intValue());
-
- assertEquals(3, message.getInt32ToStringField().size());
- assertEquals("11", message.getInt32ToStringField().get(1));
- assertEquals("22", message.getInt32ToStringField().get(2));
- assertEquals("33", message.getInt32ToStringField().get(3));
-
- assertEquals(3, message.getInt32ToBytesField().size());
- assertEquals(TestUtil.toBytes("11"), message.getInt32ToBytesField().get(1));
- assertEquals(TestUtil.toBytes("22"), message.getInt32ToBytesField().get(2));
- assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3));
-
- assertEquals(3, message.getInt32ToEnumField().size());
- assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumField().get(1));
- assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(2));
- assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3));
-
- assertEquals(3, message.getInt32ToMessageField().size());
- assertEquals(11, message.getInt32ToMessageField().get(1).getValue());
- assertEquals(22, message.getInt32ToMessageField().get(2).getValue());
- assertEquals(33, message.getInt32ToMessageField().get(3).getValue());
-
- assertEquals(3, message.getStringToInt32Field().size());
- assertEquals(11, message.getStringToInt32Field().get("1").intValue());
- assertEquals(22, message.getStringToInt32Field().get("2").intValue());
- assertEquals(33, message.getStringToInt32Field().get("3").intValue());
- }
-
- private void updateMapValues(TestMap.Builder builder) {
- builder.getMutableInt32ToInt32Field().put(1, 111);
- builder.getMutableInt32ToInt32Field().remove(2);
- builder.getMutableInt32ToInt32Field().put(4, 44);
-
- builder.getMutableInt32ToStringField().put(1, "111");
- builder.getMutableInt32ToStringField().remove(2);
- builder.getMutableInt32ToStringField().put(4, "44");
-
- builder.getMutableInt32ToBytesField().put(1, TestUtil.toBytes("111"));
- builder.getMutableInt32ToBytesField().remove(2);
- builder.getMutableInt32ToBytesField().put(4, TestUtil.toBytes("44"));
-
- builder.getMutableInt32ToEnumField().put(1, TestMap.EnumValue.BAR);
- builder.getMutableInt32ToEnumField().remove(2);
- builder.getMutableInt32ToEnumField().put(4, TestMap.EnumValue.QUX);
-
- builder.getMutableInt32ToMessageField().put(
- 1, MessageValue.newBuilder().setValue(111).build());
- builder.getMutableInt32ToMessageField().remove(2);
- builder.getMutableInt32ToMessageField().put(
- 4, MessageValue.newBuilder().setValue(44).build());
-
- builder.getMutableStringToInt32Field().put("1", 111);
- builder.getMutableStringToInt32Field().remove("2");
- builder.getMutableStringToInt32Field().put("4", 44);
- }
-
- private void assertMapValuesUpdated(TestMap message) {
- assertEquals(3, message.getInt32ToInt32Field().size());
- assertEquals(111, message.getInt32ToInt32Field().get(1).intValue());
- assertEquals(33, message.getInt32ToInt32Field().get(3).intValue());
- assertEquals(44, message.getInt32ToInt32Field().get(4).intValue());
-
- assertEquals(3, message.getInt32ToStringField().size());
- assertEquals("111", message.getInt32ToStringField().get(1));
- assertEquals("33", message.getInt32ToStringField().get(3));
- assertEquals("44", message.getInt32ToStringField().get(4));
-
- assertEquals(3, message.getInt32ToBytesField().size());
- assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesField().get(1));
- assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3));
- assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesField().get(4));
-
- assertEquals(3, message.getInt32ToEnumField().size());
- assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1));
- assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3));
- assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumField().get(4));
-
- assertEquals(3, message.getInt32ToMessageField().size());
- assertEquals(111, message.getInt32ToMessageField().get(1).getValue());
- assertEquals(33, message.getInt32ToMessageField().get(3).getValue());
- assertEquals(44, message.getInt32ToMessageField().get(4).getValue());
-
- assertEquals(3, message.getStringToInt32Field().size());
- assertEquals(111, message.getStringToInt32Field().get("1").intValue());
- assertEquals(33, message.getStringToInt32Field().get("3").intValue());
- assertEquals(44, message.getStringToInt32Field().get("4").intValue());
- }
-
- private void assertMapValuesCleared(TestMap message) {
- assertEquals(0, message.getInt32ToInt32Field().size());
- assertEquals(0, message.getInt32ToStringField().size());
- assertEquals(0, message.getInt32ToBytesField().size());
- assertEquals(0, message.getInt32ToEnumField().size());
- assertEquals(0, message.getInt32ToMessageField().size());
- assertEquals(0, message.getStringToInt32Field().size());
- }
-
- public void testSanityCopyOnWrite() throws InvalidProtocolBufferException {
- // Since builders are implemented as a thin wrapper around a message
- // instance, we attempt to verify that we can't cause the builder to modify
- // a produced message.
-
- TestMap.Builder builder = TestMap.newBuilder();
- TestMap message = builder.build();
- Map<Integer, Integer> intMap = builder.getMutableInt32ToInt32Field();
- intMap.put(1, 2);
- assertTrue(message.getInt32ToInt32Field().isEmpty());
- message = builder.build();
- try {
- intMap.put(2, 3);
- fail();
- } catch (UnsupportedOperationException e) {
- // expected
- }
- assertEquals(newMap(1, 2), message.getInt32ToInt32Field());
- assertEquals(newMap(1, 2), builder.getInt32ToInt32Field());
- builder.getMutableInt32ToInt32Field().put(2, 3);
- assertEquals(newMap(1, 2), message.getInt32ToInt32Field());
- assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32Field());
- }
-
- public void testMutableMapLifecycle() {
- TestMap.Builder builder = TestMap.newBuilder();
- Map<Integer, Integer> intMap = builder.getMutableInt32ToInt32Field();
- intMap.put(1, 2);
- assertEquals(newMap(1, 2), builder.build().getInt32ToInt32Field());
- try {
- intMap.put(2, 3);
- fail();
- } catch (UnsupportedOperationException e) {
- // expected
- }
- assertEquals(newMap(1, 2), builder.getInt32ToInt32Field());
- builder.getMutableInt32ToInt32Field().put(2, 3);
- assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32Field());
-
- Map<Integer, TestMap.EnumValue> enumMap = builder.getMutableInt32ToEnumField();
- enumMap.put(1, TestMap.EnumValue.BAR);
- assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.build().getInt32ToEnumField());
- try {
- enumMap.put(2, TestMap.EnumValue.FOO);
- fail();
- } catch (UnsupportedOperationException e) {
- // expected
- }
- assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.getInt32ToEnumField());
- builder.getMutableInt32ToEnumField().put(2, TestMap.EnumValue.FOO);
- assertEquals(
- newMap(1, TestMap.EnumValue.BAR, 2, TestMap.EnumValue.FOO),
- builder.getInt32ToEnumField());
-
- Map<Integer, String> stringMap = builder.getMutableInt32ToStringField();
- stringMap.put(1, "1");
- assertEquals(newMap(1, "1"), builder.build().getInt32ToStringField());
- try {
- stringMap.put(2, "2");
- fail();
- } catch (UnsupportedOperationException e) {
- // expected
- }
- assertEquals(newMap(1, "1"), builder.getInt32ToStringField());
- builder.getMutableInt32ToStringField().put(2, "2");
- assertEquals(
- newMap(1, "1", 2, "2"),
- builder.getInt32ToStringField());
-
- Map<Integer, TestMap.MessageValue> messageMap = builder.getMutableInt32ToMessageField();
- messageMap.put(1, TestMap.MessageValue.getDefaultInstance());
- assertEquals(newMap(1, TestMap.MessageValue.getDefaultInstance()),
- builder.build().getInt32ToMessageField());
- try {
- messageMap.put(2, TestMap.MessageValue.getDefaultInstance());
- fail();
- } catch (UnsupportedOperationException e) {
- // expected
- }
- assertEquals(newMap(1, TestMap.MessageValue.getDefaultInstance()),
- builder.getInt32ToMessageField());
- builder.getMutableInt32ToMessageField().put(2, TestMap.MessageValue.getDefaultInstance());
- assertEquals(
- newMap(1, TestMap.MessageValue.getDefaultInstance(),
- 2, TestMap.MessageValue.getDefaultInstance()),
- builder.getInt32ToMessageField());
- }
-
- public void testMutableMapLifecycle_collections() {
- TestMap.Builder builder = TestMap.newBuilder();
- Map<Integer, Integer> intMap = builder.getMutableInt32ToInt32Field();
- intMap.put(1, 2);
- assertEquals(newMap(1, 2), builder.build().getInt32ToInt32Field());
- try {
- intMap.remove(2);
- fail();
- } catch (UnsupportedOperationException e) {
- // expected
- }
- try {
- intMap.entrySet().remove(new Object());
- fail();
- } catch (UnsupportedOperationException e) {
- // expected
- }
- try {
- intMap.entrySet().iterator().remove();
- fail();
- } catch (UnsupportedOperationException e) {
- // expected
- }
- try {
- intMap.keySet().remove(new Object());
- fail();
- } catch (UnsupportedOperationException e) {
- // expected
- }
- try {
- intMap.values().remove(new Object());
- fail();
- } catch (UnsupportedOperationException e) {
- // expected
- }
- try {
- intMap.values().iterator().remove();
- fail();
- } catch (UnsupportedOperationException e) {
- // expected
- }
- assertEquals(newMap(1, 2), intMap);
- assertEquals(newMap(1, 2), builder.getInt32ToInt32Field());
- assertEquals(newMap(1, 2), builder.build().getInt32ToInt32Field());
- }
-
- public void testGettersAndSetters() throws Exception {
- TestMap.Builder builder = TestMap.newBuilder();
- TestMap message = builder.build();
- assertMapValuesCleared(message);
-
- builder = message.toBuilder();
- setMapValues(builder);
- message = builder.build();
- assertMapValuesSet(message);
-
- builder = message.toBuilder();
- updateMapValues(builder);
- message = builder.build();
- assertMapValuesUpdated(message);
-
- builder = message.toBuilder();
- builder.clear();
- message = builder.build();
- assertMapValuesCleared(message);
- }
-
- public void testPutAll() throws Exception {
- TestMap.Builder sourceBuilder = TestMap.newBuilder();
- setMapValues(sourceBuilder);
- TestMap source = sourceBuilder.build();
-
- TestMap.Builder destination = TestMap.newBuilder();
- copyMapValues(source, destination);
- assertMapValuesSet(destination.build());
- }
-
- public void testSerializeAndParse() throws Exception {
- TestMap.Builder builder = TestMap.newBuilder();
- setMapValues(builder);
- TestMap message = builder.build();
- assertEquals(message.getSerializedSize(), message.toByteString().size());
- message = TestMap.parser().parseFrom(message.toByteString());
- assertMapValuesSet(message);
-
- builder = message.toBuilder();
- updateMapValues(builder);
- message = builder.build();
- assertEquals(message.getSerializedSize(), message.toByteString().size());
- message = TestMap.parser().parseFrom(message.toByteString());
- assertMapValuesUpdated(message);
-
- builder = message.toBuilder();
- builder.clear();
- message = builder.build();
- assertEquals(message.getSerializedSize(), message.toByteString().size());
- message = TestMap.parser().parseFrom(message.toByteString());
- assertMapValuesCleared(message);
- }
-
- public void testMergeFrom() throws Exception {
- TestMap.Builder builder = TestMap.newBuilder();
- setMapValues(builder);
- TestMap message = builder.build();
-
- TestMap.Builder other = TestMap.newBuilder();
- other.mergeFrom(message);
- assertMapValuesSet(other.build());
- }
-
- public void testEqualsAndHashCode() throws Exception {
- // Test that generated equals() and hashCode() will disregard the order
- // of map entries when comparing/hashing map fields.
-
- // We can't control the order of elements in a HashMap. The best we can do
- // here is to add elements in different order.
- TestMap.Builder b1 = TestMap.newBuilder();
- b1.getMutableInt32ToInt32Field().put(1, 2);
- b1.getMutableInt32ToInt32Field().put(3, 4);
- b1.getMutableInt32ToInt32Field().put(5, 6);
- TestMap m1 = b1.build();
-
- TestMap.Builder b2 = TestMap.newBuilder();
- b2.getMutableInt32ToInt32Field().put(5, 6);
- b2.getMutableInt32ToInt32Field().put(1, 2);
- b2.getMutableInt32ToInt32Field().put(3, 4);
- TestMap m2 = b2.build();
-
- assertEquals(m1, m2);
- assertEquals(m1.hashCode(), m2.hashCode());
-
- // Make sure we did compare map fields.
- b2.getMutableInt32ToInt32Field().put(1, 0);
- m2 = b2.build();
- assertFalse(m1.equals(m2));
- // Don't check m1.hashCode() != m2.hashCode() because it's not guaranteed
- // to be different.
- }
-
- public void testUnknownEnumValues() throws Exception {
- TestUnknownEnumValue.Builder builder =
- TestUnknownEnumValue.newBuilder();
- builder.getMutableInt32ToInt32Field().put(1, 1);
- builder.getMutableInt32ToInt32Field().put(2, 54321);
- ByteString data = builder.build().toByteString();
-
- TestMap message = TestMap.parseFrom(data);
- // Entries with unknown enum values will be stored into UnknownFieldSet so
- // there is only one entry in the map.
- assertEquals(1, message.getInt32ToEnumField().size());
- assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1));
- // Serializing and parsing should preserve the unknown entry.
- data = message.toByteString();
- TestUnknownEnumValue messageWithUnknownEnums =
- TestUnknownEnumValue.parseFrom(data);
- assertEquals(2, messageWithUnknownEnums.getInt32ToInt32Field().size());
- assertEquals(1, messageWithUnknownEnums.getInt32ToInt32Field().get(1).intValue());
- assertEquals(54321, messageWithUnknownEnums.getInt32ToInt32Field().get(2).intValue());
- }
-
-
- public void testIterationOrder() throws Exception {
- TestMap.Builder builder = TestMap.newBuilder();
- setMapValues(builder);
- TestMap message = builder.build();
-
- assertEquals(Arrays.asList("1", "2", "3"),
- new ArrayList<String>(message.getStringToInt32Field().keySet()));
- }
-
- private static <K, V> Map<K, V> newMap(K key1, V value1) {
- Map<K, V> map = new HashMap<K, V>();
- map.put(key1, value1);
- return map;
- }
-
- private static <K, V> Map<K, V> newMap(K key1, V value1, K key2, V value2) {
- Map<K, V> map = new HashMap<K, V>();
- map.put(key1, value1);
- map.put(key2, value2);
- return map;
- }
-}
diff --git a/java/util/pom.xml b/java/util/pom.xml
index 44a5662d..0d5e8e37 100644
--- a/java/util/pom.xml
+++ b/java/util/pom.xml
@@ -4,110 +4,73 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
- <groupId>com.google</groupId>
- <artifactId>google</artifactId>
- <version>1</version>
+ <groupId>com.google.protobuf</groupId>
+ <artifactId>protobuf-parent</artifactId>
+ <version>3.0.0</version>
</parent>
- <groupId>com.google.protobuf</groupId>
+
<artifactId>protobuf-java-util</artifactId>
- <version>3.0.0-beta-1</version>
<packaging>bundle</packaging>
- <name>Protocol Buffer Java API</name>
- <description>
- Protocol Buffers are a way of encoding structured data in an efficient yet
- extensible format.
- </description>
- <inceptionYear>2008</inceptionYear>
- <url>https://developers.google.com/protocol-buffers/</url>
- <licenses>
- <license>
- <name>New BSD license</name>
- <url>http://www.opensource.org/licenses/bsd-license.php</url>
- <distribution>repo</distribution>
- </license>
- </licenses>
- <scm>
- <url>https://github.com/google/protobuf</url>
- <connection>
- scm:git:https://github.com/google/protobuf.git
- </connection>
- </scm>
+
+ <name>Protocol Buffers [Util]</name>
+ <description>Utilities for Protocol Buffers</description>
+
<dependencies>
<dependency>
- <groupId>com.google.protobuf</groupId>
+ <groupId>${project.groupId}</groupId>
<artifactId>protobuf-java</artifactId>
- <version>3.0.0-beta-1</version>
- <scope>compile</scope>
+ <version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
- <version>18.0</version>
- <scope>compile</scope>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.3</version>
- <scope>compile</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
- <version>4.4</version>
- <scope>test</scope>
</dependency>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
- <version>2.2</version>
- <scope>test</scope>
</dependency>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymockclassextension</artifactId>
- <version>2.2.1</version>
- <scope>test</scope>
</dependency>
</dependencies>
+
+ <properties>
+ <!-- Use the core proto dir so that we can call the core generation script -->
+ <test.proto.dir>../core/src/test/proto</test.proto.dir>
+ </properties>
+
<build>
<plugins>
<plugin>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <source>1.5</source>
- <target>1.5</target>
- </configuration>
- </plugin>
- <plugin>
- <artifactId>maven-surefire-plugin</artifactId>
- <configuration>
- <includes>
- <include>**/*Test.java</include>
- <include>../src/main/java/com/google/protobuf/TestUtil.java</include>
- </includes>
- </configuration>
- </plugin>
- <plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
+ <!-- Generate the test protos -->
<execution>
<id>generate-test-sources</id>
<phase>generate-test-sources</phase>
<configuration>
- <tasks>
- <mkdir dir="target/generated-test-sources" />
- <exec executable="../../src/protoc">
- <arg value="--java_out=target/generated-test-sources" />
- <arg value="--proto_path=../../src" />
- <arg value="--proto_path=src/test/java" />
- <arg value="../../src/google/protobuf/unittest.proto" />
- <arg value="../../src/google/protobuf/unittest_import.proto" />
- <arg value="../../src/google/protobuf/unittest_import_public.proto" />
- <arg value="src/test/java/com/google/protobuf/util/json_test.proto" />
+ <target>
+ <!-- Generate all of the test protos from the core module -->
+ <ant antfile="../core/generate-test-sources-build.xml"/>
+
+ <!-- Generate additional test protos for this module -->
+ <exec executable="${protoc}">
+ <arg value="--java_out=${generated.testsources.dir}" />
+ <arg value="--proto_path=${protobuf.source.dir}" />
+ <arg value="--proto_path=src/test/proto" />
+ <arg value="src/test/proto/com/google/protobuf/util/json_test.proto" />
</exec>
- </tasks>
- <testSourceRoot>target/generated-test-sources</testSourceRoot>
+ </target>
</configuration>
<goals>
<goal>run</goal>
@@ -115,6 +78,16 @@
</execution>
</executions>
</plugin>
+
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <!-- Add the generated test sources to the build -->
+ <generatedTestSourcesDirectory>${generated.testsources.dir}</generatedTestSourcesDirectory>
+ </configuration>
+ </plugin>
+
+ <!-- Configure the OSGI bundle -->
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
@@ -123,80 +96,20 @@
<instructions>
<Bundle-DocURL>https://developers.google.com/protocol-buffers/</Bundle-DocURL>
<Bundle-SymbolicName>com.google.protobuf.util</Bundle-SymbolicName>
- <Export-Package>com.google.protobuf.util;version=3.0.0-beta-1</Export-Package>
+ <Export-Package>com.google.protobuf.util;version=${project.version}</Export-Package>
</instructions>
</configuration>
</plugin>
+
+ <!-- Configure the fat jar to include all dependencies -->
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <configuration>
+ <descriptorRefs>
+ <descriptorRef>jar-with-dependencies</descriptorRef>
+ </descriptorRefs>
+ </configuration>
+ </plugin>
</plugins>
</build>
- <profiles>
- <profile>
- <id>release</id>
- <distributionManagement>
- <snapshotRepository>
- <id>sonatype-nexus-staging</id>
- <url>https://oss.sonatype.org/content/repositories/snapshots</url>
- </snapshotRepository>
- <repository>
- <id>sonatype-nexus-staging</id>
- <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
- </repository>
- </distributionManagement>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-source-plugin</artifactId>
- <version>2.2.1</version>
- <executions>
- <execution>
- <id>attach-sources</id>
- <goals>
- <goal>jar-no-fork</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-javadoc-plugin</artifactId>
- <version>2.9.1</version>
- <executions>
- <execution>
- <id>attach-javadocs</id>
- <goals>
- <goal>jar</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-gpg-plugin</artifactId>
- <version>1.5</version>
- <executions>
- <execution>
- <id>sign-artifacts</id>
- <phase>verify</phase>
- <goals>
- <goal>sign</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.sonatype.plugins</groupId>
- <artifactId>nexus-staging-maven-plugin</artifactId>
- <version>1.6.3</version>
- <extensions>true</extensions>
- <configuration>
- <serverId>sonatype-nexus-staging</serverId>
- <nexusUrl>https://oss.sonatype.org/</nexusUrl>
- <autoReleaseAfterClose>false</autoReleaseAfterClose>
- </configuration>
- </plugin>
- </plugins>
- </build>
- </profile>
- </profiles>
</project>
diff --git a/java/util/src/main/java/com/google/protobuf/util/Durations.java b/java/util/src/main/java/com/google/protobuf/util/Durations.java
new file mode 100644
index 00000000..5fe6ebca
--- /dev/null
+++ b/java/util/src/main/java/com/google/protobuf/util/Durations.java
@@ -0,0 +1,256 @@
+// 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.
+
+package com.google.protobuf.util;
+
+import static com.google.protobuf.util.Timestamps.MICROS_PER_SECOND;
+import static com.google.protobuf.util.Timestamps.MILLIS_PER_SECOND;
+import static com.google.protobuf.util.Timestamps.NANOS_PER_MICROSECOND;
+import static com.google.protobuf.util.Timestamps.NANOS_PER_MILLISECOND;
+import static com.google.protobuf.util.Timestamps.NANOS_PER_SECOND;
+
+import com.google.protobuf.Duration;
+
+import java.text.ParseException;
+
+/**
+ * Utilities to help create/manipulate {@code protobuf/duration.proto}.
+ */
+public final class Durations {
+ static final long DURATION_SECONDS_MIN = -315576000000L;
+ static final long DURATION_SECONDS_MAX = 315576000000L;
+
+ // TODO(kak): Do we want to expose Duration constants for MAX/MIN?
+
+ private Durations() {}
+
+ /**
+ * Returns true if the given {@link Duration} is valid. The {@code seconds} value must be in the
+ * range [-315,576,000,000, +315,576,000,000]. The {@code nanos} value must be in the range
+ * [-999,999,999, +999,999,999].
+ *
+ * <p>Note: Durations less than one second are represented with a 0 {@code seconds} field and a
+ * positive or negative {@code nanos} field. For durations of one second or more, a non-zero value
+ * for the {@code nanos} field must be of the same sign as the {@code seconds} field.
+ */
+ public static boolean isValid(Duration duration) {
+ return isValid(duration.getSeconds(), duration.getNanos());
+ }
+
+ /**
+ * Returns true if the given number of seconds and nanos is a valid {@link Duration}. The
+ * {@code seconds} value must be in the range [-315,576,000,000, +315,576,000,000]. The
+ * {@code nanos} value must be in the range [-999,999,999, +999,999,999].
+ *
+ * <p>Note: Durations less than one second are represented with a 0 {@code seconds} field and a
+ * positive or negative {@code nanos} field. For durations of one second or more, a non-zero value
+ * for the {@code nanos} field must be of the same sign as the {@code seconds} field.
+ */
+ public static boolean isValid(long seconds, long nanos) {
+ if (seconds < DURATION_SECONDS_MIN || seconds > DURATION_SECONDS_MAX) {
+ return false;
+ }
+ if (nanos < -999999999L || nanos >= NANOS_PER_SECOND) {
+ return false;
+ }
+ if (seconds < 0 || nanos < 0) {
+ if (seconds > 0 || nanos > 0) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Throws an {@link IllegalArgumentException} if the given seconds/nanos are not
+ * a valid {@link Duration}.
+ */
+ private static void checkValid(long seconds, int nanos) {
+ if (!isValid(seconds, nanos)) {
+ throw new IllegalArgumentException(String.format(
+ "Duration is not valid. See proto definition for valid values. "
+ + "Seconds (%s) must be in range [-315,576,000,000, +315,576,000,000]."
+ + "Nanos (%s) must be in range [-999,999,999, +999,999,999]. "
+ + "Nanos must have the same sign as seconds", seconds, nanos));
+ }
+ }
+
+ /**
+ * Convert Duration to string format. The string format will contains 3, 6,
+ * or 9 fractional digits depending on the precision required to represent
+ * the exact Duration value. For example: "1s", "1.010s", "1.000000100s",
+ * "-3.100s" The range that can be represented by Duration is from
+ * -315,576,000,000 to +315,576,000,000 inclusive (in seconds).
+ *
+ * @return The string representation of the given duration.
+ * @throws IllegalArgumentException if the given duration is not in the valid
+ * range.
+ */
+ public static String toString(Duration duration) {
+ long seconds = duration.getSeconds();
+ int nanos = duration.getNanos();
+ checkValid(seconds, nanos);
+
+ StringBuilder result = new StringBuilder();
+ if (seconds < 0 || nanos < 0) {
+ result.append("-");
+ seconds = -seconds;
+ nanos = -nanos;
+ }
+ result.append(seconds);
+ if (nanos != 0) {
+ result.append(".");
+ result.append(Timestamps.formatNanos(nanos));
+ }
+ result.append("s");
+ return result.toString();
+ }
+
+ /**
+ * Parse from a string to produce a duration.
+ *
+ * @return A Duration parsed from the string.
+ * @throws ParseException if parsing fails.
+ */
+ public static Duration parse(String value) throws ParseException {
+ // Must ended with "s".
+ if (value.isEmpty() || value.charAt(value.length() - 1) != 's') {
+ throw new ParseException("Invalid duration string: " + value, 0);
+ }
+ boolean negative = false;
+ if (value.charAt(0) == '-') {
+ negative = true;
+ value = value.substring(1);
+ }
+ String secondValue = value.substring(0, value.length() - 1);
+ String nanoValue = "";
+ int pointPosition = secondValue.indexOf('.');
+ if (pointPosition != -1) {
+ nanoValue = secondValue.substring(pointPosition + 1);
+ secondValue = secondValue.substring(0, pointPosition);
+ }
+ long seconds = Long.parseLong(secondValue);
+ int nanos = nanoValue.isEmpty() ? 0 : Timestamps.parseNanos(nanoValue);
+ if (seconds < 0) {
+ throw new ParseException("Invalid duration string: " + value, 0);
+ }
+ if (negative) {
+ seconds = -seconds;
+ nanos = -nanos;
+ }
+ try {
+ return normalizedDuration(seconds, nanos);
+ } catch (IllegalArgumentException e) {
+ throw new ParseException("Duration value is out of range.", 0);
+ }
+ }
+
+ /**
+ * Create a Duration from the number of milliseconds.
+ */
+ public static Duration fromMillis(long milliseconds) {
+ return normalizedDuration(
+ milliseconds / MILLIS_PER_SECOND,
+ (int) (milliseconds % MILLIS_PER_SECOND * NANOS_PER_MILLISECOND));
+ }
+
+ /**
+ * Convert a Duration to the number of milliseconds.The result will be
+ * rounded towards 0 to the nearest millisecond. E.g., if the duration
+ * represents -1 nanosecond, it will be rounded to 0.
+ */
+ public static long toMillis(Duration duration) {
+ return duration.getSeconds() * MILLIS_PER_SECOND + duration.getNanos() / NANOS_PER_MILLISECOND;
+ }
+
+ /**
+ * Create a Duration from the number of microseconds.
+ */
+ public static Duration fromMicros(long microseconds) {
+ return normalizedDuration(
+ microseconds / MICROS_PER_SECOND,
+ (int) (microseconds % MICROS_PER_SECOND * NANOS_PER_MICROSECOND));
+ }
+
+ /**
+ * Convert a Duration to the number of microseconds.The result will be
+ * rounded towards 0 to the nearest microseconds. E.g., if the duration
+ * represents -1 nanosecond, it will be rounded to 0.
+ */
+ public static long toMicros(Duration duration) {
+ return duration.getSeconds() * MICROS_PER_SECOND + duration.getNanos() / NANOS_PER_MICROSECOND;
+ }
+
+ /**
+ * Create a Duration from the number of nanoseconds.
+ */
+ public static Duration fromNanos(long nanoseconds) {
+ return normalizedDuration(
+ nanoseconds / NANOS_PER_SECOND, (int) (nanoseconds % NANOS_PER_SECOND));
+ }
+
+ /**
+ * Convert a Duration to the number of nanoseconds.
+ */
+ public static long toNanos(Duration duration) {
+ return duration.getSeconds() * NANOS_PER_SECOND + duration.getNanos();
+ }
+
+ /**
+ * Add two durations.
+ */
+ public static Duration add(Duration d1, Duration d2) {
+ return normalizedDuration(d1.getSeconds() + d2.getSeconds(), d1.getNanos() + d2.getNanos());
+ }
+
+ /**
+ * Subtract a duration from another.
+ */
+ public static Duration subtract(Duration d1, Duration d2) {
+ return normalizedDuration(d1.getSeconds() - d2.getSeconds(), d1.getNanos() - d2.getNanos());
+ }
+
+ static Duration normalizedDuration(long seconds, int nanos) {
+ if (nanos <= -NANOS_PER_SECOND || nanos >= NANOS_PER_SECOND) {
+ seconds += nanos / NANOS_PER_SECOND;
+ nanos %= NANOS_PER_SECOND;
+ }
+ if (seconds > 0 && nanos < 0) {
+ nanos += NANOS_PER_SECOND;
+ seconds -= 1;
+ }
+ if (seconds < 0 && nanos > 0) {
+ nanos -= NANOS_PER_SECOND;
+ seconds += 1;
+ }
+ checkValid(seconds, nanos);
+ return Duration.newBuilder().setSeconds(seconds).setNanos(nanos).build();
+ }
+}
diff --git a/java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java b/java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java
index dc2f4b84..b577495d 100644
--- a/java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java
+++ b/java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java
@@ -38,6 +38,7 @@ import com.google.protobuf.Message;
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;
+import java.util.SortedMap;
import java.util.TreeMap;
import java.util.logging.Logger;
@@ -59,26 +60,29 @@ import java.util.logging.Logger;
* intersection to two FieldMasks and traverse all fields specified by the
* FieldMask in a message tree.
*/
-class FieldMaskTree {
- private static final Logger logger =
- Logger.getLogger(FieldMaskTree.class.getName());
-
- private static final String FIELD_PATH_SEPARATOR_REGEX = "\\.";
+final class FieldMaskTree {
+ private static final Logger logger = Logger.getLogger(FieldMaskTree.class.getName());
- private static class Node {
- public TreeMap<String, Node> children = new TreeMap<String, Node>();
+ private static final String FIELD_PATH_SEPARATOR_REGEX = "\\.";
+
+ private static final class Node {
+ final SortedMap<String, Node> children = new TreeMap<String, Node>();
}
private final Node root = new Node();
- /** Creates an empty FieldMaskTree. */
- public FieldMaskTree() {}
-
- /** Creates a FieldMaskTree for a given FieldMask. */
- public FieldMaskTree(FieldMask mask) {
+ /**
+ * Creates an empty FieldMaskTree.
+ */
+ FieldMaskTree() {}
+
+ /**
+ * Creates a FieldMaskTree for a given FieldMask.
+ */
+ FieldMaskTree(FieldMask mask) {
mergeFromFieldMask(mask);
}
-
+
@Override
public String toString() {
return FieldMaskUtil.toString(toFieldMask());
@@ -94,7 +98,7 @@ class FieldMaskTree {
* Likewise, if the field path to add is a sub-path of an existing leaf node,
* nothing will be changed in the tree.
*/
- public FieldMaskTree addFieldPath(String path) {
+ FieldMaskTree addFieldPath(String path) {
String[] parts = path.split(FIELD_PATH_SEPARATOR_REGEX);
if (parts.length == 0) {
return this;
@@ -121,19 +125,21 @@ class FieldMaskTree {
node.children.clear();
return this;
}
-
+
/**
* Merges all field paths in a FieldMask into this tree.
*/
- public FieldMaskTree mergeFromFieldMask(FieldMask mask) {
+ FieldMaskTree mergeFromFieldMask(FieldMask mask) {
for (String path : mask.getPathsList()) {
addFieldPath(path);
}
return this;
}
- /** Converts this tree to a FieldMask. */
- public FieldMask toFieldMask() {
+ /**
+ * Converts this tree to a FieldMask.
+ */
+ FieldMask toFieldMask() {
if (root.children.isEmpty()) {
return FieldMask.getDefaultInstance();
}
@@ -142,24 +148,24 @@ class FieldMaskTree {
return FieldMask.newBuilder().addAllPaths(paths).build();
}
- /** Gathers all field paths in a sub-tree. */
+ /**
+ * Gathers all field paths in a sub-tree.
+ */
private void getFieldPaths(Node node, String path, List<String> paths) {
if (node.children.isEmpty()) {
paths.add(path);
return;
}
for (Entry<String, Node> entry : node.children.entrySet()) {
- String childPath = path.isEmpty()
- ? entry.getKey() : path + "." + entry.getKey();
+ String childPath = path.isEmpty() ? entry.getKey() : path + "." + entry.getKey();
getFieldPaths(entry.getValue(), childPath, paths);
}
}
/**
- * Adds the intersection of this tree with the given {@code path} to
- * {@code output}.
+ * Adds the intersection of this tree with the given {@code path} to {@code output}.
*/
- public void intersectFieldPath(String path, FieldMaskTree output) {
+ void intersectFieldPath(String path, FieldMaskTree output) {
if (root.children.isEmpty()) {
return;
}
@@ -190,14 +196,11 @@ class FieldMaskTree {
}
/**
- * Merges all fields specified by this FieldMaskTree from {@code source} to
- * {@code destination}.
+ * Merges all fields specified by this FieldMaskTree from {@code source} to {@code destination}.
*/
- public void merge(Message source, Message.Builder destination,
- FieldMaskUtil.MergeOptions options) {
+ void merge(Message source, Message.Builder destination, FieldMaskUtil.MergeOptions options) {
if (source.getDescriptorForType() != destination.getDescriptorForType()) {
- throw new IllegalArgumentException(
- "Cannot merge messages of different types.");
+ throw new IllegalArgumentException("Cannot merge messages of different types.");
}
if (root.children.isEmpty()) {
return;
@@ -205,33 +208,44 @@ class FieldMaskTree {
merge(root, "", source, destination, options);
}
- /** Merges all fields specified by a sub-tree from {@code source} to
- * {@code destination}.
+ /**
+ * Merges all fields specified by a sub-tree from {@code source} to {@code destination}.
*/
- private void merge(Node node, String path, Message source,
- Message.Builder destination, FieldMaskUtil.MergeOptions options) {
+ private void merge(
+ Node node,
+ String path,
+ Message source,
+ Message.Builder destination,
+ FieldMaskUtil.MergeOptions options) {
assert source.getDescriptorForType() == destination.getDescriptorForType();
-
+
Descriptor descriptor = source.getDescriptorForType();
for (Entry<String, Node> entry : node.children.entrySet()) {
- FieldDescriptor field =
- descriptor.findFieldByName(entry.getKey());
+ FieldDescriptor field = descriptor.findFieldByName(entry.getKey());
if (field == null) {
- logger.warning("Cannot find field \"" + entry.getKey()
- + "\" in message type " + descriptor.getFullName());
+ logger.warning(
+ "Cannot find field \""
+ + entry.getKey()
+ + "\" in message type "
+ + descriptor.getFullName());
continue;
}
if (!entry.getValue().children.isEmpty()) {
- if (field.isRepeated()
- || field.getJavaType() != FieldDescriptor.JavaType.MESSAGE) {
- logger.warning("Field \"" + field.getFullName() + "\" is not a "
- + "singluar message field and cannot have sub-fields.");
+ if (field.isRepeated() || field.getJavaType() != FieldDescriptor.JavaType.MESSAGE) {
+ logger.warning(
+ "Field \""
+ + field.getFullName()
+ + "\" is not a "
+ + "singluar message field and cannot have sub-fields.");
continue;
}
- String childPath = path.isEmpty()
- ? entry.getKey() : path + "." + entry.getKey();
- merge(entry.getValue(), childPath, (Message) source.getField(field),
- destination.getFieldBuilder(field), options);
+ String childPath = path.isEmpty() ? entry.getKey() : path + "." + entry.getKey();
+ merge(
+ entry.getValue(),
+ childPath,
+ (Message) source.getField(field),
+ destination.getFieldBuilder(field),
+ options);
continue;
}
if (field.isRepeated()) {
@@ -245,13 +259,22 @@ class FieldMaskTree {
} else {
if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
if (options.replaceMessageFields()) {
- destination.setField(field, source.getField(field));
+ if (!source.hasField(field)) {
+ destination.clearField(field);
+ } else {
+ destination.setField(field, source.getField(field));
+ }
} else {
- destination.getFieldBuilder(field).mergeFrom(
- (Message) source.getField(field));
+ if (source.hasField(field)) {
+ destination.getFieldBuilder(field).mergeFrom((Message) source.getField(field));
+ }
}
} else {
- destination.setField(field, source.getField(field));
+ if (source.hasField(field) || !options.replacePrimitiveFields()) {
+ destination.setField(field, source.getField(field));
+ } else {
+ destination.clearField(field);
+ }
}
}
}
diff --git a/java/util/src/main/java/com/google/protobuf/util/FieldMaskUtil.java b/java/util/src/main/java/com/google/protobuf/util/FieldMaskUtil.java
index 7bf87858..21d11b2c 100644
--- a/java/util/src/main/java/com/google/protobuf/util/FieldMaskUtil.java
+++ b/java/util/src/main/java/com/google/protobuf/util/FieldMaskUtil.java
@@ -30,12 +30,19 @@
package com.google.protobuf.util;
+import static com.google.common.base.Preconditions.checkArgument;
+
+import com.google.common.base.CaseFormat;
+import com.google.common.base.Joiner;
+import com.google.common.base.Splitter;
+import com.google.common.primitives.Ints;
import com.google.protobuf.Descriptors.Descriptor;
import com.google.protobuf.Descriptors.FieldDescriptor;
import com.google.protobuf.FieldMask;
import com.google.protobuf.Internal;
import com.google.protobuf.Message;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -46,13 +53,14 @@ public class FieldMaskUtil {
private static final String FIELD_PATH_SEPARATOR = ",";
private static final String FIELD_PATH_SEPARATOR_REGEX = ",";
private static final String FIELD_SEPARATOR_REGEX = "\\.";
-
+
private FieldMaskUtil() {}
/**
* Converts a FieldMask to a string.
*/
public static String toString(FieldMask fieldMask) {
+ // TODO(xiaofeng): Consider using com.google.common.base.Joiner here instead.
StringBuilder result = new StringBuilder();
boolean first = true;
for (String value : fieldMask.getPathsList()) {
@@ -74,19 +82,18 @@ public class FieldMaskUtil {
* Parses from a string to a FieldMask.
*/
public static FieldMask fromString(String value) {
- return fromStringList(
- null, Arrays.asList(value.split(FIELD_PATH_SEPARATOR_REGEX)));
+ // TODO(xiaofeng): Consider using com.google.common.base.Splitter here instead.
+ return fromStringList(null, Arrays.asList(value.split(FIELD_PATH_SEPARATOR_REGEX)));
}
/**
* Parses from a string to a FieldMask and validates all field paths.
- *
+ *
* @throws IllegalArgumentException if any of the field path is invalid.
*/
- public static FieldMask fromString(Class<? extends Message> type, String value)
- throws IllegalArgumentException {
- return fromStringList(
- type, Arrays.asList(value.split(FIELD_PATH_SEPARATOR_REGEX)));
+ public static FieldMask fromString(Class<? extends Message> type, String value) {
+ // TODO(xiaofeng): Consider using com.google.common.base.Splitter here instead.
+ return fromStringList(type, Arrays.asList(value.split(FIELD_PATH_SEPARATOR_REGEX)));
}
/**
@@ -94,9 +101,8 @@ public class FieldMaskUtil {
*
* @throws IllegalArgumentException if any of the field path is not valid.
*/
- public static FieldMask fromStringList(
- Class<? extends Message> type, List<String> paths)
- throws IllegalArgumentException {
+ // TODO(xiaofeng): Consider renaming fromStrings()
+ public static FieldMask fromStringList(Class<? extends Message> type, Iterable<String> paths) {
FieldMask.Builder builder = FieldMask.newBuilder();
for (String path : paths) {
if (path.isEmpty()) {
@@ -104,8 +110,7 @@ public class FieldMaskUtil {
continue;
}
if (type != null && !isValid(type, path)) {
- throw new IllegalArgumentException(
- path + " is not a valid path for " + type);
+ throw new IllegalArgumentException(path + " is not a valid path for " + type);
}
builder.addPaths(path);
}
@@ -113,15 +118,103 @@ public class FieldMaskUtil {
}
/**
+ * Constructs a FieldMask from the passed field numbers.
+ *
+ * @throws IllegalArgumentException if any of the fields are invalid for the message.
+ */
+ public static FieldMask fromFieldNumbers(Class<? extends Message> type, int... fieldNumbers) {
+ return fromFieldNumbers(type, Ints.asList(fieldNumbers));
+ }
+
+ /**
+ * Constructs a FieldMask from the passed field numbers.
+ *
+ * @throws IllegalArgumentException if any of the fields are invalid for the message.
+ */
+ public static FieldMask fromFieldNumbers(
+ Class<? extends Message> type, Iterable<Integer> fieldNumbers) {
+ Descriptor descriptor = Internal.getDefaultInstance(type).getDescriptorForType();
+
+ FieldMask.Builder builder = FieldMask.newBuilder();
+ for (Integer fieldNumber : fieldNumbers) {
+ FieldDescriptor field = descriptor.findFieldByNumber(fieldNumber);
+ checkArgument(
+ field != null,
+ String.format("%s is not a valid field number for %s.", fieldNumber, type));
+ builder.addPaths(field.getName());
+ }
+ return builder.build();
+ }
+
+ /**
+ * Converts a field mask to a Proto3 JSON string, that is converting from snake case to camel
+ * case and joining all paths into one string with commas.
+ */
+ public static String toJsonString(FieldMask fieldMask) {
+ List<String> paths = new ArrayList<String>(fieldMask.getPathsCount());
+ for (String path : fieldMask.getPathsList()) {
+ if (path.isEmpty()) {
+ continue;
+ }
+ paths.add(CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, path));
+ }
+ return Joiner.on(FIELD_PATH_SEPARATOR).join(paths);
+ }
+
+ /**
+ * Converts a field mask from a Proto3 JSON string, that is splitting the paths along commas and
+ * converting from camel case to snake case.
+ */
+ public static FieldMask fromJsonString(String value) {
+ Iterable<String> paths = Splitter.on(FIELD_PATH_SEPARATOR).split(value);
+ FieldMask.Builder builder = FieldMask.newBuilder();
+ for (String path : paths) {
+ if (path.isEmpty()) {
+ continue;
+ }
+ builder.addPaths(CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, path));
+ }
+ return builder.build();
+ }
+
+ /**
+ * Checks whether paths in a given fields mask are valid.
+ */
+ public static boolean isValid(Class<? extends Message> type, FieldMask fieldMask) {
+ Descriptor descriptor = Internal.getDefaultInstance(type).getDescriptorForType();
+
+ return isValid(descriptor, fieldMask);
+ }
+
+ /**
+ * Checks whether paths in a given fields mask are valid.
+ */
+ public static boolean isValid(Descriptor descriptor, FieldMask fieldMask) {
+ for (String path : fieldMask.getPathsList()) {
+ if (!isValid(descriptor, path)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
* Checks whether a given field path is valid.
*/
public static boolean isValid(Class<? extends Message> type, String path) {
+ Descriptor descriptor = Internal.getDefaultInstance(type).getDescriptorForType();
+
+ return isValid(descriptor, path);
+ }
+
+ /**
+ * Checks whether paths in a given fields mask are valid.
+ */
+ public static boolean isValid(Descriptor descriptor, String path) {
String[] parts = path.split(FIELD_SEPARATOR_REGEX);
if (parts.length == 0) {
return false;
}
- Descriptor descriptor =
- Internal.getDefaultInstance(type).getDescriptorForType();
for (String name : parts) {
if (descriptor == null) {
return false;
@@ -130,8 +223,7 @@ public class FieldMaskUtil {
if (field == null) {
return false;
}
- if (!field.isRepeated()
- && field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+ if (!field.isRepeated() && field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
descriptor = field.getMessageType();
} else {
descriptor = null;
@@ -139,7 +231,7 @@ public class FieldMaskUtil {
}
return true;
}
-
+
/**
* Converts a FieldMask to its canonical form. In the canonical form of a
* FieldMask, all field paths are sorted alphabetically and redundant field
@@ -148,14 +240,19 @@ public class FieldMaskUtil {
public static FieldMask normalize(FieldMask mask) {
return new FieldMaskTree(mask).toFieldMask();
}
-
+
/**
- * Creates an union of two FieldMasks.
+ * Creates a union of two or more FieldMasks.
*/
- public static FieldMask union(FieldMask mask1, FieldMask mask2) {
- return new FieldMaskTree(mask1).mergeFromFieldMask(mask2).toFieldMask();
+ public static FieldMask union(
+ FieldMask firstMask, FieldMask secondMask, FieldMask... otherMasks) {
+ FieldMaskTree maskTree = new FieldMaskTree(firstMask).mergeFromFieldMask(secondMask);
+ for (FieldMask mask : otherMasks) {
+ maskTree.mergeFromFieldMask(mask);
+ }
+ return maskTree.toFieldMask();
}
-
+
/**
* Calculates the intersection of two FieldMasks.
*/
@@ -171,16 +268,19 @@ public class FieldMaskUtil {
/**
* Options to customize merging behavior.
*/
- public static class MergeOptions {
+ public static final class MergeOptions {
private boolean replaceMessageFields = false;
private boolean replaceRepeatedFields = false;
+ // TODO(b/28277137): change the default behavior to always replace primitive fields after
+ // fixing all failing TAP tests.
+ private boolean replacePrimitiveFields = false;
/**
* Whether to replace message fields (i.e., discard existing content in
* destination message fields) when merging.
* Default behavior is to merge the source message field into the
* destination message field.
- */
+ */
public boolean replaceMessageFields() {
return replaceMessageFields;
}
@@ -194,7 +294,23 @@ public class FieldMaskUtil {
public boolean replaceRepeatedFields() {
return replaceRepeatedFields;
}
-
+
+ /**
+ * Whether to replace primitive (non-repeated and non-message) fields in
+ * destination message fields with the source primitive fields (i.e., if the
+ * field is set in the source, the value is copied to the
+ * destination; if the field is unset in the source, the field is cleared
+ * from the destination) when merging.
+ *
+ * <p>Default behavior is to always set the value of the source primitive
+ * field to the destination primitive field, and if the source field is
+ * unset, the default value of the source field is copied to the
+ * destination.
+ */
+ public boolean replacePrimitiveFields() {
+ return replacePrimitiveFields;
+ }
+
public void setReplaceMessageFields(boolean value) {
replaceMessageFields = value;
}
@@ -202,21 +318,25 @@ public class FieldMaskUtil {
public void setReplaceRepeatedFields(boolean value) {
replaceRepeatedFields = value;
}
+
+ public void setReplacePrimitiveFields(boolean value) {
+ replacePrimitiveFields = value;
+ }
}
-
+
/**
- * Merges fields specified by a FieldMask from one message to another.
+ * Merges fields specified by a FieldMask from one message to another with the
+ * specified merge options.
*/
- public static void merge(FieldMask mask, Message source,
- Message.Builder destination, MergeOptions options) {
+ public static void merge(
+ FieldMask mask, Message source, Message.Builder destination, MergeOptions options) {
new FieldMaskTree(mask).merge(source, destination, options);
}
/**
* Merges fields specified by a FieldMask from one message to another.
*/
- public static void merge(FieldMask mask, Message source,
- Message.Builder destination) {
+ public static void merge(FieldMask mask, Message source, Message.Builder destination) {
merge(mask, source, destination, new MergeOptions());
}
}
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 c9a39153..ad50cc0e 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
@@ -32,6 +32,7 @@ package com.google.protobuf.util;
import com.google.common.io.BaseEncoding;
import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonNull;
@@ -59,6 +60,7 @@ import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.ListValue;
import com.google.protobuf.Message;
import com.google.protobuf.MessageOrBuilder;
+import com.google.protobuf.NullValue;
import com.google.protobuf.StringValue;
import com.google.protobuf.Struct;
import com.google.protobuf.Timestamp;
@@ -78,6 +80,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.TreeMap;
import java.util.logging.Logger;
/**
@@ -90,61 +93,120 @@ import java.util.logging.Logger;
* as well.
*/
public class JsonFormat {
- private static final Logger logger =
- Logger.getLogger(JsonFormat.class.getName());
+ private static final Logger logger = Logger.getLogger(JsonFormat.class.getName());
private JsonFormat() {}
-
+
/**
* Creates a {@link Printer} with default configurations.
*/
public static Printer printer() {
- return new Printer(TypeRegistry.getEmptyTypeRegistry());
+ return new Printer(TypeRegistry.getEmptyTypeRegistry(), false, false, false);
}
-
+
/**
* A Printer converts protobuf message to JSON format.
*/
public static class Printer {
private final TypeRegistry registry;
-
- private Printer(TypeRegistry registry) {
+ private final boolean includingDefaultValueFields;
+ private final boolean preservingProtoFieldNames;
+ private final boolean omittingInsignificantWhitespace;
+
+ private Printer(
+ TypeRegistry registry,
+ boolean includingDefaultValueFields,
+ boolean preservingProtoFieldNames,
+ boolean omittingInsignificantWhitespace) {
this.registry = registry;
+ this.includingDefaultValueFields = includingDefaultValueFields;
+ this.preservingProtoFieldNames = preservingProtoFieldNames;
+ this.omittingInsignificantWhitespace = omittingInsignificantWhitespace;
}
-
+
/**
* Creates a new {@link Printer} using the given registry. The new Printer
* clones all other configurations from the current {@link Printer}.
- *
+ *
* @throws IllegalArgumentException if a registry is already set.
*/
public Printer usingTypeRegistry(TypeRegistry registry) {
if (this.registry != TypeRegistry.getEmptyTypeRegistry()) {
throw new IllegalArgumentException("Only one registry is allowed.");
}
- return new Printer(registry);
+ return new Printer(
+ registry,
+ includingDefaultValueFields,
+ preservingProtoFieldNames,
+ omittingInsignificantWhitespace);
+ }
+
+ /**
+ * Creates a new {@link Printer} that will also print fields set to their
+ * defaults. Empty repeated fields and map fields will be printed as well.
+ * The new Printer clones all other configurations from the current
+ * {@link Printer}.
+ */
+ public Printer includingDefaultValueFields() {
+ return new Printer(
+ registry, true, preservingProtoFieldNames, omittingInsignificantWhitespace);
+ }
+
+ /**
+ * Creates a new {@link Printer} that is configured to use the original proto
+ * field names as defined in the .proto file rather than converting them to
+ * lowerCamelCase. The new Printer clones all other configurations from the
+ * current {@link Printer}.
+ */
+ public Printer preservingProtoFieldNames() {
+ return new Printer(
+ registry, includingDefaultValueFields, true, omittingInsignificantWhitespace);
+ }
+
+
+ /**
+ * Create a new {@link Printer} that will omit all insignificant whitespace
+ * in the JSON output. This new Printer clones all other configurations from the
+ * current Printer. Insignificant whitespace is defined by the JSON spec as whitespace
+ * that appear between JSON structural elements:
+ * <pre>
+ * ws = *(
+ * %x20 / ; Space
+ * %x09 / ; Horizontal tab
+ * %x0A / ; Line feed or New line
+ * %x0D ) ; Carriage return
+ * </pre>
+ * See <a href="https://tools.ietf.org/html/rfc7159">https://tools.ietf.org/html/rfc7159</a>
+ * current {@link Printer}.
+ */
+ public Printer omittingInsignificantWhitespace() {
+ return new Printer(registry, includingDefaultValueFields, preservingProtoFieldNames, true);
}
-
+
/**
* Converts a protobuf message to JSON format.
- *
+ *
* @throws InvalidProtocolBufferException if the message contains Any types
* that can't be resolved.
* @throws IOException if writing to the output fails.
*/
- public void appendTo(MessageOrBuilder message, Appendable output)
- throws IOException {
+ public void appendTo(MessageOrBuilder message, Appendable output) throws IOException {
// TODO(xiaofeng): Investigate the allocation overhead and optimize for
// mobile.
- new PrinterImpl(registry, output).print(message);
+ new PrinterImpl(
+ registry,
+ includingDefaultValueFields,
+ preservingProtoFieldNames,
+ output,
+ omittingInsignificantWhitespace)
+ .print(message);
}
/**
* Converts a protobuf message to JSON format. Throws exceptions if there
- * are unknown Any types in the message.
+ * are unknown Any types in the message.
*/
- public String print(MessageOrBuilder message)
- throws InvalidProtocolBufferException {
+ public String print(MessageOrBuilder message) throws InvalidProtocolBufferException {
try {
StringBuilder builder = new StringBuilder();
appendTo(message, builder);
@@ -164,21 +226,21 @@ public class JsonFormat {
public static Parser parser() {
return new Parser(TypeRegistry.getEmptyTypeRegistry());
}
-
+
/**
* A Parser parses JSON to protobuf message.
*/
public static class Parser {
private final TypeRegistry registry;
-
+
private Parser(TypeRegistry registry) {
- this.registry = registry;
+ this.registry = registry;
}
-
+
/**
* Creates a new {@link Parser} using the given registry. The new Parser
* clones all other configurations from this Parser.
- *
+ *
* @throws IllegalArgumentException if a registry is already set.
*/
public Parser usingTypeRegistry(TypeRegistry registry) {
@@ -187,29 +249,27 @@ public class JsonFormat {
}
return new Parser(registry);
}
-
+
/**
* Parses from JSON into a protobuf message.
- *
+ *
* @throws InvalidProtocolBufferException if the input is not valid JSON
* format or there are unknown fields in the input.
*/
- public void merge(String json, Message.Builder builder)
- throws InvalidProtocolBufferException {
+ public void merge(String json, Message.Builder builder) throws InvalidProtocolBufferException {
// TODO(xiaofeng): Investigate the allocation overhead and optimize for
// mobile.
new ParserImpl(registry).merge(json, builder);
}
-
+
/**
* Parses from JSON into a protobuf message.
- *
+ *
* @throws InvalidProtocolBufferException if the input is not valid JSON
* format or there are unknown fields in the input.
* @throws IOException if reading from the input throws.
*/
- public void merge(Reader json, Message.Builder builder)
- throws IOException {
+ public void merge(Reader json, Message.Builder builder) throws IOException {
// TODO(xiaofeng): Investigate the allocation overhead and optimize for
// mobile.
new ParserImpl(registry).merge(json, builder);
@@ -225,8 +285,8 @@ public class JsonFormat {
*/
public static class TypeRegistry {
private static class EmptyTypeRegistryHolder {
- private static final TypeRegistry EMPTY = new TypeRegistry(
- Collections.<String, Descriptor>emptyMap());
+ private static final TypeRegistry EMPTY =
+ new TypeRegistry(Collections.<String, Descriptor>emptyMap());
}
public static TypeRegistry getEmptyTypeRegistry() {
@@ -263,8 +323,7 @@ public class JsonFormat {
*/
public Builder add(Descriptor messageType) {
if (types == null) {
- throw new IllegalStateException(
- "A TypeRegistry.Builer can only be used once.");
+ throw new IllegalStateException("A TypeRegistry.Builer can only be used once.");
}
addFile(messageType.getFile());
return this;
@@ -276,8 +335,7 @@ public class JsonFormat {
*/
public Builder add(Iterable<Descriptor> messageTypes) {
if (types == null) {
- throw new IllegalStateException(
- "A TypeRegistry.Builer can only be used once.");
+ throw new IllegalStateException("A TypeRegistry.Builer can only be used once.");
}
for (Descriptor type : messageTypes) {
addFile(type.getFile());
@@ -298,7 +356,7 @@ public class JsonFormat {
private void addFile(FileDescriptor file) {
// Skip the file if it's already added.
- if (files.contains(file.getName())) {
+ if (!files.add(file.getFullName())) {
return;
}
for (FileDescriptor dependency : file.getDependencies()) {
@@ -315,8 +373,7 @@ public class JsonFormat {
}
if (types.containsKey(message.getFullName())) {
- logger.warning("Type " + message.getFullName()
- + " is added multiple times.");
+ logger.warning("Type " + message.getFullName() + " is added multiple times.");
return;
}
@@ -324,20 +381,58 @@ public class JsonFormat {
}
private final Set<String> files = new HashSet<String>();
- private Map<String, Descriptor> types =
- new HashMap<String, Descriptor>();
+ private Map<String, Descriptor> types = new HashMap<String, Descriptor>();
}
}
/**
+ * An interface for json formatting that can be used in
+ * combination with the omittingInsignificantWhitespace() method
+ */
+ interface TextGenerator {
+ void indent();
+
+ void outdent();
+
+ void print(final CharSequence text) throws IOException;
+ }
+
+ /**
+ * Format the json without indentation
+ */
+ private static final class CompactTextGenerator implements TextGenerator {
+ private final Appendable output;
+
+ private CompactTextGenerator(final Appendable output) {
+ this.output = output;
+ }
+
+ /**
+ * ignored by compact printer
+ */
+ public void indent() {}
+
+ /**
+ * ignored by compact printer
+ */
+ public void outdent() {}
+
+ /**
+ * Print text to the output stream.
+ */
+ public void print(final CharSequence text) throws IOException {
+ output.append(text);
+ }
+ }
+ /**
* A TextGenerator adds indentation when writing formatted text.
*/
- private static final class TextGenerator {
+ private static final class PrettyTextGenerator implements TextGenerator {
private final Appendable output;
private final StringBuilder indent = new StringBuilder();
private boolean atStartOfLine = true;
- private TextGenerator(final Appendable output) {
+ private PrettyTextGenerator(final Appendable output) {
this.output = output;
}
@@ -357,8 +452,7 @@ public class JsonFormat {
public void outdent() {
final int length = indent.length();
if (length < 2) {
- throw new IllegalArgumentException(
- " Outdent() without matching Indent().");
+ throw new IllegalArgumentException(" Outdent() without matching Indent().");
}
indent.delete(length - 2, length);
}
@@ -397,60 +491,76 @@ public class JsonFormat {
*/
private static final class PrinterImpl {
private final TypeRegistry registry;
+ private final boolean includingDefaultValueFields;
+ private final boolean preservingProtoFieldNames;
private final TextGenerator generator;
// We use Gson to help handle string escapes.
private final Gson gson;
+ private final CharSequence blankOrSpace;
+ private final CharSequence blankOrNewLine;
private static class GsonHolder {
- private static final Gson DEFAULT_GSON = new Gson();
+ private static final Gson DEFAULT_GSON = new GsonBuilder().disableHtmlEscaping().create();
}
- PrinterImpl(TypeRegistry registry, Appendable jsonOutput) {
+ PrinterImpl(
+ TypeRegistry registry,
+ boolean includingDefaultValueFields,
+ boolean preservingProtoFieldNames,
+ Appendable jsonOutput,
+ boolean omittingInsignificantWhitespace) {
this.registry = registry;
- this.generator = new TextGenerator(jsonOutput);
+ this.includingDefaultValueFields = includingDefaultValueFields;
+ this.preservingProtoFieldNames = preservingProtoFieldNames;
this.gson = GsonHolder.DEFAULT_GSON;
+ // json format related properties, determined by printerType
+ if (omittingInsignificantWhitespace) {
+ this.generator = new CompactTextGenerator(jsonOutput);
+ this.blankOrSpace = "";
+ this.blankOrNewLine = "";
+ } else {
+ this.generator = new PrettyTextGenerator(jsonOutput);
+ this.blankOrSpace = " ";
+ this.blankOrNewLine = "\n";
+ }
}
void print(MessageOrBuilder message) throws IOException {
- WellKnownTypePrinter specialPrinter = wellKnownTypePrinters.get(
- message.getDescriptorForType().getFullName());
+ WellKnownTypePrinter specialPrinter =
+ wellKnownTypePrinters.get(message.getDescriptorForType().getFullName());
if (specialPrinter != null) {
specialPrinter.print(this, message);
return;
}
print(message, null);
}
-
+
private interface WellKnownTypePrinter {
- void print(PrinterImpl printer, MessageOrBuilder message)
- throws IOException;
- }
-
- private static final Map<String, WellKnownTypePrinter>
- wellKnownTypePrinters = buildWellKnownTypePrinters();
-
- private static Map<String, WellKnownTypePrinter>
- buildWellKnownTypePrinters() {
- Map<String, WellKnownTypePrinter> printers =
- new HashMap<String, WellKnownTypePrinter>();
+ void print(PrinterImpl printer, MessageOrBuilder message) throws IOException;
+ }
+
+ private static final Map<String, WellKnownTypePrinter> wellKnownTypePrinters =
+ buildWellKnownTypePrinters();
+
+ private static Map<String, WellKnownTypePrinter> buildWellKnownTypePrinters() {
+ Map<String, WellKnownTypePrinter> printers = new HashMap<String, WellKnownTypePrinter>();
// Special-case Any.
- printers.put(Any.getDescriptor().getFullName(),
+ printers.put(
+ Any.getDescriptor().getFullName(),
new WellKnownTypePrinter() {
- @Override
- public void print(PrinterImpl printer, MessageOrBuilder message)
- throws IOException {
- printer.printAny(message);
- }
- });
+ @Override
+ public void print(PrinterImpl printer, MessageOrBuilder message) throws IOException {
+ printer.printAny(message);
+ }
+ });
// Special-case wrapper types.
- WellKnownTypePrinter wrappersPrinter = new WellKnownTypePrinter() {
- @Override
- public void print(PrinterImpl printer, MessageOrBuilder message)
- throws IOException {
- printer.printWrapper(message);
-
- }
- };
+ WellKnownTypePrinter wrappersPrinter =
+ new WellKnownTypePrinter() {
+ @Override
+ public void print(PrinterImpl printer, MessageOrBuilder message) throws IOException {
+ printer.printWrapper(message);
+ }
+ };
printers.put(BoolValue.getDescriptor().getFullName(), wrappersPrinter);
printers.put(Int32Value.getDescriptor().getFullName(), wrappersPrinter);
printers.put(UInt32Value.getDescriptor().getFullName(), wrappersPrinter);
@@ -461,70 +571,71 @@ public class JsonFormat {
printers.put(FloatValue.getDescriptor().getFullName(), wrappersPrinter);
printers.put(DoubleValue.getDescriptor().getFullName(), wrappersPrinter);
// Special-case Timestamp.
- printers.put(Timestamp.getDescriptor().getFullName(),
+ printers.put(
+ Timestamp.getDescriptor().getFullName(),
new WellKnownTypePrinter() {
- @Override
- public void print(PrinterImpl printer, MessageOrBuilder message)
- throws IOException {
- printer.printTimestamp(message);
- }
- });
+ @Override
+ public void print(PrinterImpl printer, MessageOrBuilder message) throws IOException {
+ printer.printTimestamp(message);
+ }
+ });
// Special-case Duration.
- printers.put(Duration.getDescriptor().getFullName(),
+ printers.put(
+ Duration.getDescriptor().getFullName(),
new WellKnownTypePrinter() {
- @Override
- public void print(PrinterImpl printer, MessageOrBuilder message)
- throws IOException {
- printer.printDuration(message);
- }
- });
+ @Override
+ public void print(PrinterImpl printer, MessageOrBuilder message) throws IOException {
+ printer.printDuration(message);
+ }
+ });
// Special-case FieldMask.
- printers.put(FieldMask.getDescriptor().getFullName(),
+ printers.put(
+ FieldMask.getDescriptor().getFullName(),
new WellKnownTypePrinter() {
- @Override
- public void print(PrinterImpl printer, MessageOrBuilder message)
- throws IOException {
- printer.printFieldMask(message);
- }
- });
+ @Override
+ public void print(PrinterImpl printer, MessageOrBuilder message) throws IOException {
+ printer.printFieldMask(message);
+ }
+ });
// Special-case Struct.
- printers.put(Struct.getDescriptor().getFullName(),
+ printers.put(
+ Struct.getDescriptor().getFullName(),
new WellKnownTypePrinter() {
- @Override
- public void print(PrinterImpl printer, MessageOrBuilder message)
- throws IOException {
- printer.printStruct(message);
- }
- });
+ @Override
+ public void print(PrinterImpl printer, MessageOrBuilder message) throws IOException {
+ printer.printStruct(message);
+ }
+ });
// Special-case Value.
- printers.put(Value.getDescriptor().getFullName(),
+ printers.put(
+ Value.getDescriptor().getFullName(),
new WellKnownTypePrinter() {
- @Override
- public void print(PrinterImpl printer, MessageOrBuilder message)
- throws IOException {
- printer.printValue(message);
- }
- });
+ @Override
+ public void print(PrinterImpl printer, MessageOrBuilder message) throws IOException {
+ printer.printValue(message);
+ }
+ });
// Special-case ListValue.
- printers.put(ListValue.getDescriptor().getFullName(),
+ printers.put(
+ ListValue.getDescriptor().getFullName(),
new WellKnownTypePrinter() {
- @Override
- public void print(PrinterImpl printer, MessageOrBuilder message)
- throws IOException {
- printer.printListValue(message);
- }
- });
+ @Override
+ public void print(PrinterImpl printer, MessageOrBuilder message) throws IOException {
+ printer.printListValue(message);
+ }
+ });
return printers;
}
-
+
/** Prints google.protobuf.Any */
private void printAny(MessageOrBuilder message) throws IOException {
Descriptor descriptor = message.getDescriptorForType();
FieldDescriptor typeUrlField = descriptor.findFieldByName("type_url");
FieldDescriptor valueField = descriptor.findFieldByName("value");
// Validates type of the message. Note that we can't just cast the message
- // to com.google.protobuf.Any because it might be a DynamicMessage.
- if (typeUrlField == null || valueField == null
+ // to com.google.protobuf.Any because it might be a DynamicMessage.
+ if (typeUrlField == null
+ || valueField == null
|| typeUrlField.getType() != FieldDescriptor.Type.STRING
|| valueField.getType() != FieldDescriptor.Type.BYTES) {
throw new InvalidProtocolBufferException("Invalid Any type.");
@@ -533,22 +644,21 @@ public class JsonFormat {
String typeName = getTypeName(typeUrl);
Descriptor type = registry.find(typeName);
if (type == null) {
- throw new InvalidProtocolBufferException(
- "Cannot find type for url: " + typeUrl);
+ throw new InvalidProtocolBufferException("Cannot find type for url: " + typeUrl);
}
ByteString content = (ByteString) message.getField(valueField);
- Message contentMessage = DynamicMessage.getDefaultInstance(type)
- .getParserForType().parseFrom(content);
+ Message contentMessage =
+ DynamicMessage.getDefaultInstance(type).getParserForType().parseFrom(content);
WellKnownTypePrinter printer = wellKnownTypePrinters.get(typeName);
if (printer != null) {
// If the type is one of the well-known types, we use a special
// formatting.
- generator.print("{\n");
+ generator.print("{" + blankOrNewLine);
generator.indent();
- generator.print("\"@type\": " + gson.toJson(typeUrl) + ",\n");
- generator.print("\"value\": ");
+ generator.print("\"@type\":" + blankOrSpace + gson.toJson(typeUrl) + "," + blankOrNewLine);
+ generator.print("\"value\":" + blankOrSpace);
printer.print(this, contentMessage);
- generator.print("\n");
+ generator.print(blankOrNewLine);
generator.outdent();
generator.print("}");
} else {
@@ -556,7 +666,7 @@ public class JsonFormat {
print(contentMessage, typeUrl);
}
}
-
+
/** Prints wrapper types (e.g., google.protobuf.Int32Value) */
private void printWrapper(MessageOrBuilder message) throws IOException {
Descriptor descriptor = message.getDescriptorForType();
@@ -568,7 +678,7 @@ public class JsonFormat {
// the whole message.
printSingleFieldValue(valueField, message.getField(valueField));
}
-
+
private ByteString toByteString(MessageOrBuilder message) {
if (message instanceof Message) {
return ((Message) message).toByteString();
@@ -576,26 +686,25 @@ public class JsonFormat {
return ((Message.Builder) message).build().toByteString();
}
}
-
+
/** Prints google.protobuf.Timestamp */
private void printTimestamp(MessageOrBuilder message) throws IOException {
Timestamp value = Timestamp.parseFrom(toByteString(message));
- generator.print("\"" + TimeUtil.toString(value) + "\"");
+ generator.print("\"" + Timestamps.toString(value) + "\"");
}
-
+
/** Prints google.protobuf.Duration */
private void printDuration(MessageOrBuilder message) throws IOException {
Duration value = Duration.parseFrom(toByteString(message));
- generator.print("\"" + TimeUtil.toString(value) + "\"");
-
+ generator.print("\"" + Durations.toString(value) + "\"");
}
-
+
/** Prints google.protobuf.FieldMask */
private void printFieldMask(MessageOrBuilder message) throws IOException {
FieldMask value = FieldMask.parseFrom(toByteString(message));
- generator.print("\"" + FieldMaskUtil.toString(value) + "\"");
+ generator.print("\"" + FieldMaskUtil.toJsonString(value) + "\"");
}
-
+
/** Prints google.protobuf.Struct */
private void printStruct(MessageOrBuilder message) throws IOException {
Descriptor descriptor = message.getDescriptorForType();
@@ -606,7 +715,7 @@ public class JsonFormat {
// Struct is formatted as a map object.
printMapFieldValue(field, message.getField(field));
}
-
+
/** Prints google.protobuf.Value */
private void printValue(MessageOrBuilder message) throws IOException {
// For a Value message, only the value of the field is formatted.
@@ -625,7 +734,7 @@ public class JsonFormat {
printSingleFieldValue(entry.getKey(), entry.getValue());
}
}
-
+
/** Prints google.protobuf.ListValue */
private void printListValue(MessageOrBuilder message) throws IOException {
Descriptor descriptor = message.getDescriptorForType();
@@ -637,43 +746,55 @@ public class JsonFormat {
}
/** Prints a regular message with an optional type URL. */
- private void print(MessageOrBuilder message, String typeUrl)
- throws IOException {
- generator.print("{\n");
+ private void print(MessageOrBuilder message, String typeUrl) throws IOException {
+ generator.print("{" + blankOrNewLine);
generator.indent();
boolean printedField = false;
if (typeUrl != null) {
- generator.print("\"@type\": " + gson.toJson(typeUrl));
+ generator.print("\"@type\":" + blankOrSpace + gson.toJson(typeUrl));
printedField = true;
}
- for (Map.Entry<FieldDescriptor, Object> field
- : message.getAllFields().entrySet()) {
- // Skip unknown enum fields.
- if (field.getValue() instanceof EnumValueDescriptor
- && ((EnumValueDescriptor) field.getValue()).getIndex() == -1) {
- continue;
+ Map<FieldDescriptor, Object> fieldsToPrint = null;
+ if (includingDefaultValueFields) {
+ fieldsToPrint = new TreeMap<FieldDescriptor, Object>();
+ for (FieldDescriptor field : message.getDescriptorForType().getFields()) {
+ if (field.isOptional()
+ && field.getJavaType() == FieldDescriptor.JavaType.MESSAGE
+ && !message.hasField(field)) {
+ // Always skip empty optional message fields. If not we will recurse indefinitely if
+ // a message has itself as a sub-field.
+ continue;
+ }
+ fieldsToPrint.put(field, message.getField(field));
}
+ } else {
+ fieldsToPrint = message.getAllFields();
+ }
+ for (Map.Entry<FieldDescriptor, Object> field : fieldsToPrint.entrySet()) {
if (printedField) {
// Add line-endings for the previous field.
- generator.print(",\n");
+ generator.print("," + blankOrNewLine);
} else {
printedField = true;
}
printField(field.getKey(), field.getValue());
}
-
+
// Add line-endings for the last field.
if (printedField) {
- generator.print("\n");
+ generator.print(blankOrNewLine);
}
generator.outdent();
generator.print("}");
}
- private void printField(FieldDescriptor field, Object value)
- throws IOException {
- generator.print("\"" + fieldNameToCamelName(field.getName()) + "\": ");
+ private void printField(FieldDescriptor field, Object value) throws IOException {
+ if (preservingProtoFieldNames) {
+ generator.print("\"" + field.getName() + "\":" + blankOrSpace);
+ } else {
+ generator.print("\"" + field.getJsonName() + "\":" + blankOrSpace);
+ }
if (field.isMapField()) {
printMapFieldValue(field, value);
} else if (field.isRepeated()) {
@@ -682,20 +803,14 @@ public class JsonFormat {
printSingleFieldValue(field, value);
}
}
-
+
@SuppressWarnings("rawtypes")
- private void printRepeatedFieldValue(FieldDescriptor field, Object value)
- throws IOException {
+ private void printRepeatedFieldValue(FieldDescriptor field, Object value) throws IOException {
generator.print("[");
boolean printedElement = false;
for (Object element : (List) value) {
- // Skip unknown enum entries.
- if (element instanceof EnumValueDescriptor
- && ((EnumValueDescriptor) element).getIndex() == -1) {
- continue;
- }
if (printedElement) {
- generator.print(", ");
+ generator.print("," + blankOrSpace);
} else {
printedElement = true;
}
@@ -703,59 +818,52 @@ public class JsonFormat {
}
generator.print("]");
}
-
+
@SuppressWarnings("rawtypes")
- private void printMapFieldValue(FieldDescriptor field, Object value)
- throws IOException {
+ private void printMapFieldValue(FieldDescriptor field, Object value) throws IOException {
Descriptor type = field.getMessageType();
FieldDescriptor keyField = type.findFieldByName("key");
FieldDescriptor valueField = type.findFieldByName("value");
if (keyField == null || valueField == null) {
throw new InvalidProtocolBufferException("Invalid map field.");
}
- generator.print("{\n");
+ generator.print("{" + blankOrNewLine);
generator.indent();
boolean printedElement = false;
for (Object element : (List) value) {
Message entry = (Message) element;
Object entryKey = entry.getField(keyField);
Object entryValue = entry.getField(valueField);
- // Skip unknown enum entries.
- if (entryValue instanceof EnumValueDescriptor
- && ((EnumValueDescriptor) entryValue).getIndex() == -1) {
- continue;
- }
if (printedElement) {
- generator.print(",\n");
+ generator.print("," + blankOrNewLine);
} else {
printedElement = true;
}
// Key fields are always double-quoted.
printSingleFieldValue(keyField, entryKey, true);
- generator.print(": ");
+ generator.print(":" + blankOrSpace);
printSingleFieldValue(valueField, entryValue);
}
if (printedElement) {
- generator.print("\n");
+ generator.print(blankOrNewLine);
}
generator.outdent();
generator.print("}");
}
-
- private void printSingleFieldValue(FieldDescriptor field, Object value)
- throws IOException {
+
+ private void printSingleFieldValue(FieldDescriptor field, Object value) throws IOException {
printSingleFieldValue(field, value, false);
}
/**
* Prints a field's value in JSON format.
- *
+ *
* @param alwaysWithQuotes whether to always add double-quotes to primitive
* types.
*/
private void printSingleFieldValue(
- final FieldDescriptor field, final Object value,
- boolean alwaysWithQuotes) throws IOException {
+ final FieldDescriptor field, final Object value, boolean alwaysWithQuotes)
+ throws IOException {
switch (field.getType()) {
case INT32:
case SINT32:
@@ -809,7 +917,7 @@ public class JsonFormat {
}
}
break;
-
+
case DOUBLE:
Double doubleValue = (Double) value;
if (doubleValue.isNaN()) {
@@ -853,15 +961,13 @@ public class JsonFormat {
case BYTES:
generator.print("\"");
- generator.print(
- BaseEncoding.base64().encode(((ByteString) value).toByteArray()));
+ generator.print(BaseEncoding.base64().encode(((ByteString) value).toByteArray()));
generator.print("\"");
break;
case ENUM:
// Special-case google.protobuf.NullValue (it's an Enum).
- if (field.getEnumType().getFullName().equals(
- "google.protobuf.NullValue")) {
+ if (field.getEnumType().getFullName().equals("google.protobuf.NullValue")) {
// No matter what value it contains, we always print it as "null".
if (alwaysWithQuotes) {
generator.print("\"");
@@ -871,8 +977,11 @@ public class JsonFormat {
generator.print("\"");
}
} else {
- generator.print(
- "\"" + ((EnumValueDescriptor) value).getName() + "\"");
+ if (((EnumValueDescriptor) value).getIndex() == -1) {
+ generator.print(String.valueOf(((EnumValueDescriptor) value).getNumber()));
+ } else {
+ generator.print("\"" + ((EnumValueDescriptor) value).getName() + "\"");
+ }
}
break;
@@ -900,73 +1009,34 @@ public class JsonFormat {
} else {
// Pull off the most-significant bit so that BigInteger doesn't think
// the number is negative, then set it again using setBit().
- return BigInteger.valueOf(value & Long.MAX_VALUE)
- .setBit(Long.SIZE - 1).toString();
+ return BigInteger.valueOf(value & Long.MAX_VALUE).setBit(Long.SIZE - 1).toString();
}
}
-
- private static final String TYPE_URL_PREFIX = "type.googleapis.com";
-
- private static String getTypeName(String typeUrl)
- throws InvalidProtocolBufferException {
+
+ private static String getTypeName(String typeUrl) throws InvalidProtocolBufferException {
String[] parts = typeUrl.split("/");
- if (parts.length != 2 || !parts[0].equals(TYPE_URL_PREFIX)) {
- throw new InvalidProtocolBufferException(
- "Invalid type url found: " + typeUrl);
+ if (parts.length == 1) {
+ throw new InvalidProtocolBufferException("Invalid type url found: " + typeUrl);
}
- return parts[1];
+ return parts[parts.length - 1];
}
- private static String fieldNameToCamelName(String name) {
- StringBuilder result = new StringBuilder(name.length());
- boolean isNextUpperCase = false;
- for (int i = 0; i < name.length(); i++) {
- Character ch = name.charAt(i);
- if (Character.isLowerCase(ch)) {
- if (isNextUpperCase) {
- result.append(Character.toUpperCase(ch));
- } else {
- result.append(ch);
- }
- isNextUpperCase = false;
- } else if (Character.isUpperCase(ch)) {
- if (i == 0 && !isNextUpperCase) {
- // Force first letter to lower-case unless explicitly told to
- // capitalize it.
- result.append(Character.toLowerCase(ch));
- } else {
- // Capital letters after the first are left as-is.
- result.append(ch);
- }
- isNextUpperCase = false;
- } else if (Character.isDigit(ch)) {
- result.append(ch);
- isNextUpperCase = true;
- } else {
- isNextUpperCase = true;
- }
- }
- return result.toString();
- }
-
private static class ParserImpl {
private final TypeRegistry registry;
private final JsonParser jsonParser;
-
+
ParserImpl(TypeRegistry registry) {
this.registry = registry;
this.jsonParser = new JsonParser();
}
-
- void merge(Reader json, Message.Builder builder)
- throws IOException {
+
+ void merge(Reader json, Message.Builder builder) throws IOException {
JsonReader reader = new JsonReader(json);
reader.setLenient(false);
merge(jsonParser.parse(reader), builder);
}
-
- void merge(String json, Message.Builder builder)
- throws InvalidProtocolBufferException {
+
+ void merge(String json, Message.Builder builder) throws InvalidProtocolBufferException {
try {
JsonReader reader = new JsonReader(new StringReader(json));
reader.setLenient(false);
@@ -978,35 +1048,36 @@ public class JsonFormat {
throw new InvalidProtocolBufferException(e.getMessage());
}
}
-
+
private interface WellKnownTypeParser {
void merge(ParserImpl parser, JsonElement json, Message.Builder builder)
throws InvalidProtocolBufferException;
}
-
+
private static final Map<String, WellKnownTypeParser> wellKnownTypeParsers =
buildWellKnownTypeParsers();
-
- private static Map<String, WellKnownTypeParser>
- buildWellKnownTypeParsers() {
- Map<String, WellKnownTypeParser> parsers =
- new HashMap<String, WellKnownTypeParser>();
+
+ private static Map<String, WellKnownTypeParser> buildWellKnownTypeParsers() {
+ Map<String, WellKnownTypeParser> parsers = new HashMap<String, WellKnownTypeParser>();
// Special-case Any.
- parsers.put(Any.getDescriptor().getFullName(), new WellKnownTypeParser() {
- @Override
- public void merge(ParserImpl parser, JsonElement json,
- Message.Builder builder) throws InvalidProtocolBufferException {
- parser.mergeAny(json, builder);
- }
- });
+ parsers.put(
+ Any.getDescriptor().getFullName(),
+ new WellKnownTypeParser() {
+ @Override
+ public void merge(ParserImpl parser, JsonElement json, Message.Builder builder)
+ throws InvalidProtocolBufferException {
+ parser.mergeAny(json, builder);
+ }
+ });
// Special-case wrapper types.
- WellKnownTypeParser wrappersPrinter = new WellKnownTypeParser() {
- @Override
- public void merge(ParserImpl parser, JsonElement json,
- Message.Builder builder) throws InvalidProtocolBufferException {
- parser.mergeWrapper(json, builder);
- }
- };
+ WellKnownTypeParser wrappersPrinter =
+ new WellKnownTypeParser() {
+ @Override
+ public void merge(ParserImpl parser, JsonElement json, Message.Builder builder)
+ throws InvalidProtocolBufferException {
+ parser.mergeWrapper(json, builder);
+ }
+ };
parsers.put(BoolValue.getDescriptor().getFullName(), wrappersPrinter);
parsers.put(Int32Value.getDescriptor().getFullName(), wrappersPrinter);
parsers.put(UInt32Value.getDescriptor().getFullName(), wrappersPrinter);
@@ -1017,91 +1088,103 @@ public class JsonFormat {
parsers.put(FloatValue.getDescriptor().getFullName(), wrappersPrinter);
parsers.put(DoubleValue.getDescriptor().getFullName(), wrappersPrinter);
// Special-case Timestamp.
- parsers.put(Timestamp.getDescriptor().getFullName(),
+ parsers.put(
+ Timestamp.getDescriptor().getFullName(),
new WellKnownTypeParser() {
- @Override
- public void merge(ParserImpl parser, JsonElement json,
- Message.Builder builder) throws InvalidProtocolBufferException {
- parser.mergeTimestamp(json, builder);
- }
- });
+ @Override
+ public void merge(ParserImpl parser, JsonElement json, Message.Builder builder)
+ throws InvalidProtocolBufferException {
+ parser.mergeTimestamp(json, builder);
+ }
+ });
// Special-case Duration.
- parsers.put(Duration.getDescriptor().getFullName(),
+ parsers.put(
+ Duration.getDescriptor().getFullName(),
new WellKnownTypeParser() {
- @Override
- public void merge(ParserImpl parser, JsonElement json,
- Message.Builder builder) throws InvalidProtocolBufferException {
- parser.mergeDuration(json, builder);
- }
- });
+ @Override
+ public void merge(ParserImpl parser, JsonElement json, Message.Builder builder)
+ throws InvalidProtocolBufferException {
+ parser.mergeDuration(json, builder);
+ }
+ });
// Special-case FieldMask.
- parsers.put(FieldMask.getDescriptor().getFullName(),
+ parsers.put(
+ FieldMask.getDescriptor().getFullName(),
new WellKnownTypeParser() {
- @Override
- public void merge(ParserImpl parser, JsonElement json,
- Message.Builder builder) throws InvalidProtocolBufferException {
- parser.mergeFieldMask(json, builder);
- }
- });
+ @Override
+ public void merge(ParserImpl parser, JsonElement json, Message.Builder builder)
+ throws InvalidProtocolBufferException {
+ parser.mergeFieldMask(json, builder);
+ }
+ });
// Special-case Struct.
- parsers.put(Struct.getDescriptor().getFullName(),
+ parsers.put(
+ Struct.getDescriptor().getFullName(),
new WellKnownTypeParser() {
- @Override
- public void merge(ParserImpl parser, JsonElement json,
- Message.Builder builder) throws InvalidProtocolBufferException {
- parser.mergeStruct(json, builder);
- }
- });
+ @Override
+ public void merge(ParserImpl parser, JsonElement json, Message.Builder builder)
+ throws InvalidProtocolBufferException {
+ parser.mergeStruct(json, builder);
+ }
+ });
+ // Special-case ListValue.
+ parsers.put(
+ ListValue.getDescriptor().getFullName(),
+ new WellKnownTypeParser() {
+ @Override
+ public void merge(ParserImpl parser, JsonElement json, Message.Builder builder)
+ throws InvalidProtocolBufferException {
+ parser.mergeListValue(json, builder);
+ }
+ });
// Special-case Value.
- parsers.put(Value.getDescriptor().getFullName(),
+ parsers.put(
+ Value.getDescriptor().getFullName(),
new WellKnownTypeParser() {
- @Override
- public void merge(ParserImpl parser, JsonElement json,
- Message.Builder builder) throws InvalidProtocolBufferException {
- parser.mergeValue(json, builder);
- }
- });
+ @Override
+ public void merge(ParserImpl parser, JsonElement json, Message.Builder builder)
+ throws InvalidProtocolBufferException {
+ parser.mergeValue(json, builder);
+ }
+ });
return parsers;
}
-
+
private void merge(JsonElement json, Message.Builder builder)
throws InvalidProtocolBufferException {
- WellKnownTypeParser specialParser = wellKnownTypeParsers.get(
- builder.getDescriptorForType().getFullName());
+ WellKnownTypeParser specialParser =
+ wellKnownTypeParsers.get(builder.getDescriptorForType().getFullName());
if (specialParser != null) {
specialParser.merge(this, json, builder);
return;
}
mergeMessage(json, builder, false);
}
-
+
// Maps from camel-case field names to FieldDescriptor.
private final Map<Descriptor, Map<String, FieldDescriptor>> fieldNameMaps =
new HashMap<Descriptor, Map<String, FieldDescriptor>>();
-
- private Map<String, FieldDescriptor> getFieldNameMap(
- Descriptor descriptor) {
+
+ private Map<String, FieldDescriptor> getFieldNameMap(Descriptor descriptor) {
if (!fieldNameMaps.containsKey(descriptor)) {
- Map<String, FieldDescriptor> fieldNameMap =
- new HashMap<String, FieldDescriptor>();
+ Map<String, FieldDescriptor> fieldNameMap = new HashMap<String, FieldDescriptor>();
for (FieldDescriptor field : descriptor.getFields()) {
- fieldNameMap.put(fieldNameToCamelName(field.getName()), field);
+ fieldNameMap.put(field.getName(), field);
+ fieldNameMap.put(field.getJsonName(), field);
}
fieldNameMaps.put(descriptor, fieldNameMap);
return fieldNameMap;
}
return fieldNameMaps.get(descriptor);
}
-
- private void mergeMessage(JsonElement json, Message.Builder builder,
- boolean skipTypeUrl) throws InvalidProtocolBufferException {
+
+ private void mergeMessage(JsonElement json, Message.Builder builder, boolean skipTypeUrl)
+ throws InvalidProtocolBufferException {
if (!(json instanceof JsonObject)) {
- throw new InvalidProtocolBufferException(
- "Expect message object but got: " + json);
+ throw new InvalidProtocolBufferException("Expect message object but got: " + json);
}
JsonObject object = (JsonObject) json;
- Map<String, FieldDescriptor> fieldNameMap =
- getFieldNameMap(builder.getDescriptorForType());
+ Map<String, FieldDescriptor> fieldNameMap = getFieldNameMap(builder.getDescriptorForType());
for (Map.Entry<String, JsonElement> entry : object.entrySet()) {
if (skipTypeUrl && entry.getKey().equals("@type")) {
continue;
@@ -1109,47 +1192,46 @@ public class JsonFormat {
FieldDescriptor field = fieldNameMap.get(entry.getKey());
if (field == null) {
throw new InvalidProtocolBufferException(
- "Cannot find field: " + entry.getKey() + " in message "
- + builder.getDescriptorForType().getFullName());
+ "Cannot find field: "
+ + entry.getKey()
+ + " in message "
+ + builder.getDescriptorForType().getFullName());
}
mergeField(field, entry.getValue(), builder);
}
}
-
+
private void mergeAny(JsonElement json, Message.Builder builder)
throws InvalidProtocolBufferException {
Descriptor descriptor = builder.getDescriptorForType();
FieldDescriptor typeUrlField = descriptor.findFieldByName("type_url");
FieldDescriptor valueField = descriptor.findFieldByName("value");
// Validates type of the message. Note that we can't just cast the message
- // to com.google.protobuf.Any because it might be a DynamicMessage.
- if (typeUrlField == null || valueField == null
+ // to com.google.protobuf.Any because it might be a DynamicMessage.
+ if (typeUrlField == null
+ || valueField == null
|| typeUrlField.getType() != FieldDescriptor.Type.STRING
|| valueField.getType() != FieldDescriptor.Type.BYTES) {
throw new InvalidProtocolBufferException("Invalid Any type.");
}
-
+
if (!(json instanceof JsonObject)) {
- throw new InvalidProtocolBufferException(
- "Expect message object but got: " + json);
+ throw new InvalidProtocolBufferException("Expect message object but got: " + json);
}
JsonObject object = (JsonObject) json;
JsonElement typeUrlElement = object.get("@type");
if (typeUrlElement == null) {
- throw new InvalidProtocolBufferException(
- "Missing type url when parsing: " + json);
+ throw new InvalidProtocolBufferException("Missing type url when parsing: " + json);
}
String typeUrl = typeUrlElement.getAsString();
Descriptor contentType = registry.find(getTypeName(typeUrl));
if (contentType == null) {
- throw new InvalidProtocolBufferException(
- "Cannot resolve type: " + typeUrl);
+ throw new InvalidProtocolBufferException("Cannot resolve type: " + typeUrl);
}
builder.setField(typeUrlField, typeUrl);
Message.Builder contentBuilder =
DynamicMessage.getDefaultInstance(contentType).newBuilderForType();
- WellKnownTypeParser specialParser =
- wellKnownTypeParsers.get(contentType.getFullName());
+ WellKnownTypeParser specialParser = wellKnownTypeParsers.get(contentType.getFullName());
if (specialParser != null) {
JsonElement value = object.get("value");
if (value != null) {
@@ -1160,35 +1242,33 @@ public class JsonFormat {
}
builder.setField(valueField, contentBuilder.build().toByteString());
}
-
+
private void mergeFieldMask(JsonElement json, Message.Builder builder)
throws InvalidProtocolBufferException {
- FieldMask value = FieldMaskUtil.fromString(json.getAsString());
+ FieldMask value = FieldMaskUtil.fromJsonString(json.getAsString());
builder.mergeFrom(value.toByteString());
}
-
+
private void mergeTimestamp(JsonElement json, Message.Builder builder)
throws InvalidProtocolBufferException {
try {
- Timestamp value = TimeUtil.parseTimestamp(json.getAsString());
+ Timestamp value = Timestamps.parse(json.getAsString());
builder.mergeFrom(value.toByteString());
} catch (ParseException e) {
- throw new InvalidProtocolBufferException(
- "Failed to parse timestamp: " + json);
+ throw new InvalidProtocolBufferException("Failed to parse timestamp: " + json);
}
}
-
+
private void mergeDuration(JsonElement json, Message.Builder builder)
throws InvalidProtocolBufferException {
try {
- Duration value = TimeUtil.parseDuration(json.getAsString());
+ Duration value = Durations.parse(json.getAsString());
builder.mergeFrom(value.toByteString());
} catch (ParseException e) {
- throw new InvalidProtocolBufferException(
- "Failed to parse duration: " + json);
+ throw new InvalidProtocolBufferException("Failed to parse duration: " + json);
}
}
-
+
private void mergeStruct(JsonElement json, Message.Builder builder)
throws InvalidProtocolBufferException {
Descriptor descriptor = builder.getDescriptorForType();
@@ -1198,21 +1278,28 @@ public class JsonFormat {
}
mergeMapField(field, json, builder);
}
-
+
+ private void mergeListValue(JsonElement json, Message.Builder builder)
+ throws InvalidProtocolBufferException {
+ Descriptor descriptor = builder.getDescriptorForType();
+ FieldDescriptor field = descriptor.findFieldByName("values");
+ if (field == null) {
+ throw new InvalidProtocolBufferException("Invalid ListValue type.");
+ }
+ mergeRepeatedField(field, json, builder);
+ }
+
private void mergeValue(JsonElement json, Message.Builder builder)
throws InvalidProtocolBufferException {
Descriptor type = builder.getDescriptorForType();
if (json instanceof JsonPrimitive) {
JsonPrimitive primitive = (JsonPrimitive) json;
if (primitive.isBoolean()) {
- builder.setField(type.findFieldByName("bool_value"),
- primitive.getAsBoolean());
+ builder.setField(type.findFieldByName("bool_value"), primitive.getAsBoolean());
} else if (primitive.isNumber()) {
- builder.setField(type.findFieldByName("number_value"),
- primitive.getAsDouble());
+ builder.setField(type.findFieldByName("number_value"), primitive.getAsDouble());
} else {
- builder.setField(type.findFieldByName("string_value"),
- primitive.getAsString());
+ builder.setField(type.findFieldByName("string_value"), primitive.getAsString());
}
} else if (json instanceof JsonObject) {
FieldDescriptor field = type.findFieldByName("struct_value");
@@ -1222,29 +1309,47 @@ public class JsonFormat {
} else if (json instanceof JsonArray) {
FieldDescriptor field = type.findFieldByName("list_value");
Message.Builder listBuilder = builder.newBuilderForField(field);
- FieldDescriptor listField =
- listBuilder.getDescriptorForType().findFieldByName("values");
- mergeRepeatedField(listField, json, listBuilder);
+ merge(json, listBuilder);
builder.setField(field, listBuilder.build());
} else {
throw new IllegalStateException("Unexpected json data: " + json);
}
}
-
+
private void mergeWrapper(JsonElement json, Message.Builder builder)
throws InvalidProtocolBufferException {
Descriptor type = builder.getDescriptorForType();
FieldDescriptor field = type.findFieldByName("value");
if (field == null) {
- throw new InvalidProtocolBufferException(
- "Invalid wrapper type: " + type.getFullName());
+ throw new InvalidProtocolBufferException("Invalid wrapper type: " + type.getFullName());
}
builder.setField(field, parseFieldValue(field, json, builder));
}
-
- private void mergeField(FieldDescriptor field, JsonElement json,
- Message.Builder builder) throws InvalidProtocolBufferException {
- if (json instanceof JsonNull) {
+
+ private void mergeField(FieldDescriptor field, JsonElement json, Message.Builder builder)
+ throws InvalidProtocolBufferException {
+ if (field.isRepeated()) {
+ if (builder.getRepeatedFieldCount(field) > 0) {
+ throw new InvalidProtocolBufferException(
+ "Field " + field.getFullName() + " has already been set.");
+ }
+ } else {
+ if (builder.hasField(field)) {
+ throw new InvalidProtocolBufferException(
+ "Field " + field.getFullName() + " has already been set.");
+ }
+ if (field.getContainingOneof() != null
+ && builder.getOneofFieldDescriptor(field.getContainingOneof()) != null) {
+ FieldDescriptor other = builder.getOneofFieldDescriptor(field.getContainingOneof());
+ throw new InvalidProtocolBufferException(
+ "Cannot set field "
+ + field.getFullName()
+ + " because another field "
+ + other.getFullName()
+ + " belonging to the same oneof has already been set ");
+ }
+ }
+ if (field.isRepeated() && json instanceof JsonNull) {
// We allow "null" as value for all field types and treat it as if the
// field is not present.
return;
@@ -1260,43 +1365,38 @@ public class JsonFormat {
}
}
}
-
- private void mergeMapField(FieldDescriptor field, JsonElement json,
- Message.Builder builder) throws InvalidProtocolBufferException {
+
+ private void mergeMapField(FieldDescriptor field, JsonElement json, Message.Builder builder)
+ throws InvalidProtocolBufferException {
if (!(json instanceof JsonObject)) {
- throw new InvalidProtocolBufferException(
- "Expect a map object but found: " + json);
+ throw new InvalidProtocolBufferException("Expect a map object but found: " + json);
}
Descriptor type = field.getMessageType();
FieldDescriptor keyField = type.findFieldByName("key");
FieldDescriptor valueField = type.findFieldByName("value");
if (keyField == null || valueField == null) {
- throw new InvalidProtocolBufferException(
- "Invalid map field: " + field.getFullName());
+ throw new InvalidProtocolBufferException("Invalid map field: " + field.getFullName());
}
JsonObject object = (JsonObject) json;
for (Map.Entry<String, JsonElement> entry : object.entrySet()) {
Message.Builder entryBuilder = builder.newBuilderForField(field);
- Object key = parseFieldValue(
- keyField, new JsonPrimitive(entry.getKey()), entryBuilder);
- Object value = parseFieldValue(
- valueField, entry.getValue(), entryBuilder);
+ Object key = parseFieldValue(keyField, new JsonPrimitive(entry.getKey()), entryBuilder);
+ Object value = parseFieldValue(valueField, entry.getValue(), entryBuilder);
if (value == null) {
- value = getDefaultValue(valueField, entryBuilder);
+ throw new InvalidProtocolBufferException("Map value cannot be null.");
}
entryBuilder.setField(keyField, key);
entryBuilder.setField(valueField, value);
builder.addRepeatedField(field, entryBuilder.build());
}
}
-
+
/**
* Gets the default value for a field type. Note that we use proto3
* language defaults and ignore any default values set through the
- * proto "default" option.
+ * proto "default" option.
*/
- private Object getDefaultValue(FieldDescriptor field,
- Message.Builder builder) {
+ private Object getDefaultValue(FieldDescriptor field, Message.Builder builder) {
switch (field.getType()) {
case INT32:
case SINT32:
@@ -1326,85 +1426,107 @@ public class JsonFormat {
case GROUP:
return builder.newBuilderForField(field).getDefaultInstanceForType();
default:
- throw new IllegalStateException(
- "Invalid field type: " + field.getType());
+ throw new IllegalStateException("Invalid field type: " + field.getType());
}
}
-
- private void mergeRepeatedField(FieldDescriptor field, JsonElement json,
- Message.Builder builder) throws InvalidProtocolBufferException {
+
+ private void mergeRepeatedField(
+ FieldDescriptor field, JsonElement json, Message.Builder builder)
+ throws InvalidProtocolBufferException {
if (!(json instanceof JsonArray)) {
- throw new InvalidProtocolBufferException(
- "Expect an array but found: " + json);
+ throw new InvalidProtocolBufferException("Expect an array but found: " + json);
}
JsonArray array = (JsonArray) json;
for (int i = 0; i < array.size(); ++i) {
Object value = parseFieldValue(field, array.get(i), builder);
if (value == null) {
- value = getDefaultValue(field, builder);
+ throw new InvalidProtocolBufferException("Repeated field elements cannot be null");
}
builder.addRepeatedField(field, value);
}
}
-
- private int parseInt32(JsonElement json)
- throws InvalidProtocolBufferException {
+
+ private int parseInt32(JsonElement json) throws InvalidProtocolBufferException {
try {
return Integer.parseInt(json.getAsString());
} catch (Exception e) {
+ // Fall through.
+ }
+ // JSON doesn't distinguish between integer values and floating point values so "1" and
+ // "1.000" are treated as equal in JSON. For this reason we accept floating point values for
+ // integer fields as well as long as it actually is an integer (i.e., round(value) == value).
+ try {
+ BigDecimal value = new BigDecimal(json.getAsString());
+ return value.intValueExact();
+ } catch (Exception e) {
throw new InvalidProtocolBufferException("Not an int32 value: " + json);
}
}
-
- private long parseInt64(JsonElement json)
- throws InvalidProtocolBufferException {
+
+ private long parseInt64(JsonElement json) throws InvalidProtocolBufferException {
try {
return Long.parseLong(json.getAsString());
} catch (Exception e) {
- throw new InvalidProtocolBufferException("Not an int64 value: " + json);
+ // Fall through.
+ }
+ // JSON doesn't distinguish between integer values and floating point values so "1" and
+ // "1.000" are treated as equal in JSON. For this reason we accept floating point values for
+ // integer fields as well as long as it actually is an integer (i.e., round(value) == value).
+ try {
+ BigDecimal value = new BigDecimal(json.getAsString());
+ return value.longValueExact();
+ } catch (Exception e) {
+ throw new InvalidProtocolBufferException("Not an int32 value: " + json);
}
}
-
- private int parseUint32(JsonElement json)
- throws InvalidProtocolBufferException {
+
+ private int parseUint32(JsonElement json) throws InvalidProtocolBufferException {
try {
long result = Long.parseLong(json.getAsString());
if (result < 0 || result > 0xFFFFFFFFL) {
- throw new InvalidProtocolBufferException(
- "Out of range uint32 value: " + json);
+ throw new InvalidProtocolBufferException("Out of range uint32 value: " + json);
}
return (int) result;
} catch (InvalidProtocolBufferException e) {
throw e;
} catch (Exception e) {
- throw new InvalidProtocolBufferException(
- "Not an uint32 value: " + json);
+ // Fall through.
+ }
+ // JSON doesn't distinguish between integer values and floating point values so "1" and
+ // "1.000" are treated as equal in JSON. For this reason we accept floating point values for
+ // integer fields as well as long as it actually is an integer (i.e., round(value) == value).
+ try {
+ BigDecimal decimalValue = new BigDecimal(json.getAsString());
+ BigInteger value = decimalValue.toBigIntegerExact();
+ if (value.signum() < 0 || value.compareTo(new BigInteger("FFFFFFFF", 16)) > 0) {
+ throw new InvalidProtocolBufferException("Out of range uint32 value: " + json);
+ }
+ return value.intValue();
+ } catch (InvalidProtocolBufferException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new InvalidProtocolBufferException("Not an uint32 value: " + json);
}
}
-
- private static final BigInteger MAX_UINT64 =
- new BigInteger("FFFFFFFFFFFFFFFF", 16);
-
- private long parseUint64(JsonElement json)
- throws InvalidProtocolBufferException {
+
+ private static final BigInteger MAX_UINT64 = new BigInteger("FFFFFFFFFFFFFFFF", 16);
+
+ private long parseUint64(JsonElement json) throws InvalidProtocolBufferException {
try {
- BigInteger value = new BigInteger(json.getAsString());
- if (value.compareTo(BigInteger.ZERO) < 0
- || value.compareTo(MAX_UINT64) > 0) {
- throw new InvalidProtocolBufferException(
- "Out of range uint64 value: " + json);
+ BigDecimal decimalValue = new BigDecimal(json.getAsString());
+ BigInteger value = decimalValue.toBigIntegerExact();
+ if (value.compareTo(BigInteger.ZERO) < 0 || value.compareTo(MAX_UINT64) > 0) {
+ throw new InvalidProtocolBufferException("Out of range uint64 value: " + json);
}
return value.longValue();
} catch (InvalidProtocolBufferException e) {
throw e;
} catch (Exception e) {
- throw new InvalidProtocolBufferException(
- "Not an uint64 value: " + json);
+ throw new InvalidProtocolBufferException("Not an uint64 value: " + json);
}
}
-
- private boolean parseBool(JsonElement json)
- throws InvalidProtocolBufferException {
+
+ private boolean parseBool(JsonElement json) throws InvalidProtocolBufferException {
if (json.getAsString().equals("true")) {
return true;
}
@@ -1413,11 +1535,10 @@ public class JsonFormat {
}
throw new InvalidProtocolBufferException("Invalid bool value: " + json);
}
-
+
private static final double EPSILON = 1e-6;
-
- private float parseFloat(JsonElement json)
- throws InvalidProtocolBufferException {
+
+ private float parseFloat(JsonElement json) throws InvalidProtocolBufferException {
if (json.getAsString().equals("NaN")) {
return Float.NaN;
} else if (json.getAsString().equals("Infinity")) {
@@ -1435,8 +1556,7 @@ public class JsonFormat {
// of tolerance when checking whether the float value is in range.
if (value > Float.MAX_VALUE * (1.0 + EPSILON)
|| value < -Float.MAX_VALUE * (1.0 + EPSILON)) {
- throw new InvalidProtocolBufferException(
- "Out of range float value: " + json);
+ throw new InvalidProtocolBufferException("Out of range float value: " + json);
}
return (float) value;
} catch (InvalidProtocolBufferException e) {
@@ -1445,19 +1565,17 @@ public class JsonFormat {
throw new InvalidProtocolBufferException("Not a float value: " + json);
}
}
-
- private static final BigDecimal MORE_THAN_ONE = new BigDecimal(
- String.valueOf(1.0 + EPSILON));
+
+ private static final BigDecimal MORE_THAN_ONE = new BigDecimal(String.valueOf(1.0 + EPSILON));
// When a float value is printed, the printed value might be a little
// larger or smaller due to precision loss. Here we need to add a bit
// of tolerance when checking whether the float value is in range.
- private static final BigDecimal MAX_DOUBLE = new BigDecimal(
- String.valueOf(Double.MAX_VALUE)).multiply(MORE_THAN_ONE);
- private static final BigDecimal MIN_DOUBLE = new BigDecimal(
- String.valueOf(-Double.MAX_VALUE)).multiply(MORE_THAN_ONE);
-
- private double parseDouble(JsonElement json)
- throws InvalidProtocolBufferException {
+ private static final BigDecimal MAX_DOUBLE =
+ new BigDecimal(String.valueOf(Double.MAX_VALUE)).multiply(MORE_THAN_ONE);
+ private static final BigDecimal MIN_DOUBLE =
+ new BigDecimal(String.valueOf(-Double.MAX_VALUE)).multiply(MORE_THAN_ONE);
+
+ private double parseDouble(JsonElement json) throws InvalidProtocolBufferException {
if (json.getAsString().equals("NaN")) {
return Double.NaN;
} else if (json.getAsString().equals("Infinity")) {
@@ -1470,52 +1588,70 @@ public class JsonFormat {
// accepts all values. Here we parse the value into a BigDecimal and do
// explicit range check on it.
BigDecimal value = new BigDecimal(json.getAsString());
- if (value.compareTo(MAX_DOUBLE) > 0
- || value.compareTo(MIN_DOUBLE) < 0) {
- throw new InvalidProtocolBufferException(
- "Out of range double value: " + json);
+ if (value.compareTo(MAX_DOUBLE) > 0 || value.compareTo(MIN_DOUBLE) < 0) {
+ throw new InvalidProtocolBufferException("Out of range double value: " + json);
}
return value.doubleValue();
} catch (InvalidProtocolBufferException e) {
throw e;
} catch (Exception e) {
- throw new InvalidProtocolBufferException(
- "Not an double value: " + json);
+ throw new InvalidProtocolBufferException("Not an double value: " + json);
}
}
-
+
private String parseString(JsonElement json) {
return json.getAsString();
}
-
- private ByteString parseBytes(JsonElement json) {
- return ByteString.copyFrom(
- BaseEncoding.base64().decode(json.getAsString()));
+
+ private ByteString parseBytes(JsonElement json) throws InvalidProtocolBufferException {
+ String encoded = json.getAsString();
+ if (encoded.length() % 4 != 0) {
+ throw new InvalidProtocolBufferException(
+ "Bytes field is not encoded in standard BASE64 with paddings: " + encoded);
+ }
+ return ByteString.copyFrom(BaseEncoding.base64().decode(json.getAsString()));
}
-
- private EnumValueDescriptor parseEnum(EnumDescriptor enumDescriptor,
- JsonElement json) throws InvalidProtocolBufferException {
+
+ private EnumValueDescriptor parseEnum(EnumDescriptor enumDescriptor, JsonElement json)
+ throws InvalidProtocolBufferException {
String value = json.getAsString();
EnumValueDescriptor result = enumDescriptor.findValueByName(value);
if (result == null) {
- throw new InvalidProtocolBufferException(
- "Invalid enum value: " + value + " for enum type: "
- + enumDescriptor.getFullName());
+ // Try to interpret the value as a number.
+ try {
+ int numericValue = parseInt32(json);
+ if (enumDescriptor.getFile().getSyntax() == FileDescriptor.Syntax.PROTO3) {
+ result = enumDescriptor.findValueByNumberCreatingIfUnknown(numericValue);
+ } else {
+ result = enumDescriptor.findValueByNumber(numericValue);
+ }
+ } catch (InvalidProtocolBufferException e) {
+ // Fall through. This exception is about invalid int32 value we get from parseInt32() but
+ // that's not the exception we want the user to see. Since result == null, we will throw
+ // an exception later.
+ }
+
+ if (result == null) {
+ throw new InvalidProtocolBufferException(
+ "Invalid enum value: " + value + " for enum type: " + enumDescriptor.getFullName());
+ }
}
return result;
}
-
- private Object parseFieldValue(FieldDescriptor field, JsonElement json,
- Message.Builder builder) throws InvalidProtocolBufferException {
+
+ private Object parseFieldValue(FieldDescriptor field, JsonElement json, Message.Builder builder)
+ throws InvalidProtocolBufferException {
if (json instanceof JsonNull) {
if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE
- && field.getMessageType().getFullName().equals(
- Value.getDescriptor().getFullName())) {
+ && field.getMessageType().getFullName().equals(Value.getDescriptor().getFullName())) {
// For every other type, "null" means absence, but for the special
// Value message, it means the "null_value" field has been set.
Value value = Value.newBuilder().setNullValueValue(0).build();
- return builder.newBuilderForField(field).mergeFrom(
- value.toByteString()).build();
+ return builder.newBuilderForField(field).mergeFrom(value.toByteString()).build();
+ } else if (field.getJavaType() == FieldDescriptor.JavaType.ENUM
+ && field.getEnumType().getFullName().equals(NullValue.getDescriptor().getFullName())) {
+ // If the type of the field is a NullValue, then the value should be explicitly set.
+ return field.getEnumType().findValueByNumber(0);
}
return null;
}
@@ -1535,7 +1671,7 @@ public class JsonFormat {
case FLOAT:
return parseFloat(json);
-
+
case DOUBLE:
return parseDouble(json);
@@ -1561,11 +1697,10 @@ public class JsonFormat {
Message.Builder subBuilder = builder.newBuilderForField(field);
merge(json, subBuilder);
return subBuilder.build();
-
+
default:
- throw new InvalidProtocolBufferException(
- "Invalid field type: " + field.getType());
- }
+ throw new InvalidProtocolBufferException("Invalid field type: " + field.getType());
+ }
}
}
}
diff --git a/java/util/src/main/java/com/google/protobuf/util/TimeUtil.java b/java/util/src/main/java/com/google/protobuf/util/TimeUtil.java
index 6e4b7c03..04758473 100644
--- a/java/util/src/main/java/com/google/protobuf/util/TimeUtil.java
+++ b/java/util/src/main/java/com/google/protobuf/util/TimeUtil.java
@@ -35,15 +35,14 @@ import com.google.protobuf.Timestamp;
import java.math.BigInteger;
import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.GregorianCalendar;
-import java.util.TimeZone;
/**
* Utilities to help create/manipulate Timestamp/Duration
+ *
+ * @deprecated Use {@link Durations} and {@link Timestamps} instead.
*/
-public class TimeUtil {
+@Deprecated
+public final class TimeUtil {
// Timestamp for "0001-01-01T00:00:00Z"
public static final long TIMESTAMP_SECONDS_MIN = -62135596800L;
@@ -53,24 +52,6 @@ public class TimeUtil {
public static final long DURATION_SECONDS_MAX = 315576000000L;
private static final long NANOS_PER_SECOND = 1000000000;
- private static final long NANOS_PER_MILLISECOND = 1000000;
- private static final long NANOS_PER_MICROSECOND = 1000;
- private static final long MILLIS_PER_SECOND = 1000;
- private static final long MICROS_PER_SECOND = 1000000;
-
- private static final SimpleDateFormat timestampFormat =
- createTimestampFormat();
-
- private static SimpleDateFormat createTimestampFormat() {
- SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
- GregorianCalendar calendar =
- new GregorianCalendar(TimeZone.getTimeZone("UTC"));
- // We use Proleptic Gregorian Calendar (i.e., Gregorian calendar extends
- // backwards to year one) for timestamp formating.
- calendar.setGregorianChange(new Date(Long.MIN_VALUE));
- sdf.setCalendar(calendar);
- return sdf;
- }
private TimeUtil() {}
@@ -86,27 +67,11 @@ public class TimeUtil {
* @return The string representation of the given timestamp.
* @throws IllegalArgumentException if the given timestamp is not in the
* valid range.
+ * @deprecated Use {@link Timestamps#toString} instead.
*/
- public static String toString(Timestamp timestamp)
- throws IllegalArgumentException {
- StringBuilder result = new StringBuilder();
- // Format the seconds part.
- if (timestamp.getSeconds() < TIMESTAMP_SECONDS_MIN
- || timestamp.getSeconds() > TIMESTAMP_SECONDS_MAX) {
- throw new IllegalArgumentException("Timestamp is out of range.");
- }
- Date date = new Date(timestamp.getSeconds() * MILLIS_PER_SECOND);
- result.append(timestampFormat.format(date));
- // Format the nanos part.
- if (timestamp.getNanos() < 0 || timestamp.getNanos() >= NANOS_PER_SECOND) {
- throw new IllegalArgumentException("Timestamp has invalid nanos value.");
- }
- if (timestamp.getNanos() != 0) {
- result.append(".");
- result.append(formatNanos(timestamp.getNanos()));
- }
- result.append("Z");
- return result.toString();
+ @Deprecated
+ public static String toString(Timestamp timestamp) {
+ return Timestamps.toString(timestamp);
}
/**
@@ -119,59 +84,11 @@ public class TimeUtil {
*
* @return A Timestamp parsed from the string.
* @throws ParseException if parsing fails.
+ * @deprecated Use {@link Timestamps#parse} instead.
*/
-
+ @Deprecated
public static Timestamp parseTimestamp(String value) throws ParseException {
- int dayOffset = value.indexOf('T');
- if (dayOffset == -1) {
- throw new ParseException(
- "Failed to parse timestamp: invalid timestamp \"" + value + "\"", 0);
- }
- int timezoneOffsetPosition = value.indexOf('Z', dayOffset);
- if (timezoneOffsetPosition == -1) {
- timezoneOffsetPosition = value.indexOf('+', dayOffset);
- }
- if (timezoneOffsetPosition == -1) {
- timezoneOffsetPosition = value.indexOf('-', dayOffset);
- }
- if (timezoneOffsetPosition == -1) {
- throw new ParseException(
- "Failed to parse timestamp: missing valid timezone offset.", 0);
- }
- // Parse seconds and nanos.
- String timeValue = value.substring(0, timezoneOffsetPosition);
- String secondValue = timeValue;
- String nanoValue = "";
- int pointPosition = timeValue.indexOf('.');
- if (pointPosition != -1) {
- secondValue = timeValue.substring(0, pointPosition);
- nanoValue = timeValue.substring(pointPosition + 1);
- }
- Date date = timestampFormat.parse(secondValue);
- long seconds = date.getTime() / MILLIS_PER_SECOND;
- int nanos = nanoValue.isEmpty() ? 0 : parseNanos(nanoValue);
- // Parse timezone offsets.
- if (value.charAt(timezoneOffsetPosition) == 'Z') {
- if (value.length() != timezoneOffsetPosition + 1) {
- throw new ParseException(
- "Failed to parse timestamp: invalid trailing data \""
- + value.substring(timezoneOffsetPosition) + "\"", 0);
- }
- } else {
- String offsetValue = value.substring(timezoneOffsetPosition + 1);
- long offset = parseTimezoneOffset(offsetValue);
- if (value.charAt(timezoneOffsetPosition) == '+') {
- seconds -= offset;
- } else {
- seconds += offset;
- }
- }
- try {
- return normalizedTimestamp(seconds, nanos);
- } catch (IllegalArgumentException e) {
- throw new ParseException(
- "Failed to parse timestmap: timestamp is out of range.", 0);
- }
+ return Timestamps.parse(value);
}
/**
@@ -184,33 +101,11 @@ public class TimeUtil {
* @return The string representation of the given duration.
* @throws IllegalArgumentException if the given duration is not in the valid
* range.
+ * @deprecated Use {@link Durations#toString} instead.
*/
- public static String toString(Duration duration)
- throws IllegalArgumentException {
- if (duration.getSeconds() < DURATION_SECONDS_MIN
- || duration.getSeconds() > DURATION_SECONDS_MAX) {
- throw new IllegalArgumentException("Duration is out of valid range.");
- }
- StringBuilder result = new StringBuilder();
- long seconds = duration.getSeconds();
- int nanos = duration.getNanos();
- if (seconds < 0 || nanos < 0) {
- if (seconds > 0 || nanos > 0) {
- throw new IllegalArgumentException(
- "Invalid duration: seconds value and nanos value must have the same"
- + "sign.");
- }
- result.append("-");
- seconds = -seconds;
- nanos = -nanos;
- }
- result.append(seconds);
- if (nanos != 0) {
- result.append(".");
- result.append(formatNanos(nanos));
- }
- result.append("s");
- return result.toString();
+ @Deprecated
+ public static String toString(Duration duration) {
+ return Durations.toString(duration);
}
/**
@@ -218,54 +113,31 @@ public class TimeUtil {
*
* @return A Duration parsed from the string.
* @throws ParseException if parsing fails.
+ * @deprecated Use {@link Durations#parse} instead.
*/
+ @Deprecated
public static Duration parseDuration(String value) throws ParseException {
- // Must ended with "s".
- if (value.isEmpty() || value.charAt(value.length() - 1) != 's') {
- throw new ParseException("Invalid duration string: " + value, 0);
- }
- boolean negative = false;
- if (value.charAt(0) == '-') {
- negative = true;
- value = value.substring(1);
- }
- String secondValue = value.substring(0, value.length() - 1);
- String nanoValue = "";
- int pointPosition = secondValue.indexOf('.');
- if (pointPosition != -1) {
- nanoValue = secondValue.substring(pointPosition + 1);
- secondValue = secondValue.substring(0, pointPosition);
- }
- long seconds = Long.parseLong(secondValue);
- int nanos = nanoValue.isEmpty() ? 0 : parseNanos(nanoValue);
- if (seconds < 0) {
- throw new ParseException("Invalid duration string: " + value, 0);
- }
- if (negative) {
- seconds = -seconds;
- nanos = -nanos;
- }
- try {
- return normalizedDuration(seconds, nanos);
- } catch (IllegalArgumentException e) {
- throw new ParseException("Duration value is out of range.", 0);
- }
+ return Durations.parse(value);
}
/**
* Create a Timestamp from the number of milliseconds elapsed from the epoch.
+ *
+ * @deprecated Use {@link Timestamps#fromMillis} instead.
*/
+ @Deprecated
public static Timestamp createTimestampFromMillis(long milliseconds) {
- return normalizedTimestamp(milliseconds / MILLIS_PER_SECOND,
- (int) (milliseconds % MILLIS_PER_SECOND * NANOS_PER_MILLISECOND));
+ return Timestamps.fromMillis(milliseconds);
}
/**
* Create a Duration from the number of milliseconds.
+ *
+ * @deprecated Use {@link Durations#fromMillis} instead.
*/
+ @Deprecated
public static Duration createDurationFromMillis(long milliseconds) {
- return normalizedDuration(milliseconds / MILLIS_PER_SECOND,
- (int) (milliseconds % MILLIS_PER_SECOND * NANOS_PER_MILLISECOND));
+ return Durations.fromMillis(milliseconds);
}
/**
@@ -274,36 +146,44 @@ public class TimeUtil {
* <p>The result will be rounded down to the nearest millisecond. E.g., if the
* timestamp represents "1969-12-31T23:59:59.999999999Z", it will be rounded
* to -1 millisecond.
+ *
+ * @deprecated Use {@link Timestamps#toMillis} instead.
*/
+ @Deprecated
public static long toMillis(Timestamp timestamp) {
- return timestamp.getSeconds() * MILLIS_PER_SECOND + timestamp.getNanos()
- / NANOS_PER_MILLISECOND;
+ return Timestamps.toMillis(timestamp);
}
/**
* Convert a Duration to the number of milliseconds.The result will be
* rounded towards 0 to the nearest millisecond. E.g., if the duration
* represents -1 nanosecond, it will be rounded to 0.
+ *
+ * @deprecated Use {@link Durations#toMillis} instead.
*/
+ @Deprecated
public static long toMillis(Duration duration) {
- return duration.getSeconds() * MILLIS_PER_SECOND + duration.getNanos()
- / NANOS_PER_MILLISECOND;
+ return Durations.toMillis(duration);
}
/**
* Create a Timestamp from the number of microseconds elapsed from the epoch.
+ *
+ * @deprecated Use {@link Timestamps#fromMicros} instead.
*/
+ @Deprecated
public static Timestamp createTimestampFromMicros(long microseconds) {
- return normalizedTimestamp(microseconds / MICROS_PER_SECOND,
- (int) (microseconds % MICROS_PER_SECOND * NANOS_PER_MICROSECOND));
+ return Timestamps.fromMicros(microseconds);
}
/**
* Create a Duration from the number of microseconds.
+ *
+ * @deprecated Use {@link Durations#fromMicros} instead.
*/
+ @Deprecated
public static Duration createDurationFromMicros(long microseconds) {
- return normalizedDuration(microseconds / MICROS_PER_SECOND,
- (int) (microseconds % MICROS_PER_SECOND * NANOS_PER_MICROSECOND));
+ return Durations.fromMicros(microseconds);
}
/**
@@ -312,111 +192,141 @@ public class TimeUtil {
* <p>The result will be rounded down to the nearest microsecond. E.g., if the
* timestamp represents "1969-12-31T23:59:59.999999999Z", it will be rounded
* to -1 millisecond.
+ *
+ * @deprecated Use {@link Timestamps#toMicros} instead.
*/
+ @Deprecated
public static long toMicros(Timestamp timestamp) {
- return timestamp.getSeconds() * MICROS_PER_SECOND + timestamp.getNanos()
- / NANOS_PER_MICROSECOND;
+ return Timestamps.toMicros(timestamp);
}
/**
* Convert a Duration to the number of microseconds.The result will be
* rounded towards 0 to the nearest microseconds. E.g., if the duration
* represents -1 nanosecond, it will be rounded to 0.
+ *
+ * @deprecated Use {@link Durations#toMicros} instead.
*/
+ @Deprecated
public static long toMicros(Duration duration) {
- return duration.getSeconds() * MICROS_PER_SECOND + duration.getNanos()
- / NANOS_PER_MICROSECOND;
+ return Durations.toMicros(duration);
}
/**
* Create a Timestamp from the number of nanoseconds elapsed from the epoch.
+ *
+ * @deprecated Use {@link Timestamps#fromNanos} instead.
*/
+ @Deprecated
public static Timestamp createTimestampFromNanos(long nanoseconds) {
- return normalizedTimestamp(nanoseconds / NANOS_PER_SECOND,
- (int) (nanoseconds % NANOS_PER_SECOND));
+ return Timestamps.fromNanos(nanoseconds);
}
/**
* Create a Duration from the number of nanoseconds.
+ *
+ * @deprecated Use {@link Durations#fromNanos} instead.
*/
+ @Deprecated
public static Duration createDurationFromNanos(long nanoseconds) {
- return normalizedDuration(nanoseconds / NANOS_PER_SECOND,
- (int) (nanoseconds % NANOS_PER_SECOND));
+ return Durations.fromNanos(nanoseconds);
}
/**
* Convert a Timestamp to the number of nanoseconds elapsed from the epoch.
+ *
+ * @deprecated Use {@link Timestamps#toNanos} instead.
*/
+ @Deprecated
public static long toNanos(Timestamp timestamp) {
- return timestamp.getSeconds() * NANOS_PER_SECOND + timestamp.getNanos();
+ return Timestamps.toNanos(timestamp);
}
/**
* Convert a Duration to the number of nanoseconds.
+ *
+ * @deprecated Use {@link Durations#toNanos} instead.
*/
+ @Deprecated
public static long toNanos(Duration duration) {
- return duration.getSeconds() * NANOS_PER_SECOND + duration.getNanos();
+ return Durations.toNanos(duration);
}
/**
* Get the current time.
+ *
+ * @deprecated Use {@code Timestamps.fromMillis(System.currentTimeMillis())} instead.
*/
+ @Deprecated
public static Timestamp getCurrentTime() {
- return createTimestampFromMillis(System.currentTimeMillis());
+ return Timestamps.fromMillis(System.currentTimeMillis());
}
/**
* Get the epoch.
+ *
+ * @deprecated Use {@code Timestamps.fromMillis(0)} instead.
*/
+ @Deprecated
public static Timestamp getEpoch() {
return Timestamp.getDefaultInstance();
}
/**
* Calculate the difference between two timestamps.
+ *
+ * @deprecated Use {@link Timestamps#between} instead.
*/
+ @Deprecated
public static Duration distance(Timestamp from, Timestamp to) {
- return normalizedDuration(to.getSeconds() - from.getSeconds(),
- to.getNanos() - from.getNanos());
+ return Timestamps.between(from, to);
}
/**
* Add a duration to a timestamp.
+ *
+ * @deprecated Use {@link Timestamps#add} instead.
*/
+ @Deprecated
public static Timestamp add(Timestamp start, Duration length) {
- return normalizedTimestamp(start.getSeconds() + length.getSeconds(),
- start.getNanos() + length.getNanos());
+ return Timestamps.add(start, length);
}
/**
* Subtract a duration from a timestamp.
+ *
+ * @deprecated Use {@link Timestamps#subtract} instead.
*/
+ @Deprecated
public static Timestamp subtract(Timestamp start, Duration length) {
- return normalizedTimestamp(start.getSeconds() - length.getSeconds(),
- start.getNanos() - length.getNanos());
+ return Timestamps.subtract(start, length);
}
/**
* Add two durations.
+ *
+ * @deprecated Use {@link Durations#add} instead.
*/
+ @Deprecated
public static Duration add(Duration d1, Duration d2) {
- return normalizedDuration(d1.getSeconds() + d2.getSeconds(),
- d1.getNanos() + d2.getNanos());
+ return Durations.add(d1, d2);
}
/**
* Subtract a duration from another.
+ *
+ * @deprecated Use {@link Durations#subtract} instead.
*/
+ @Deprecated
public static Duration subtract(Duration d1, Duration d2) {
- return normalizedDuration(d1.getSeconds() - d2.getSeconds(),
- d1.getNanos() - d2.getNanos());
+ return Durations.subtract(d1, d2);
}
// Multiplications and divisions.
+ // TODO(kak): Delete this.
public static Duration multiply(Duration duration, double times) {
- double result = duration.getSeconds() * times + duration.getNanos() * times
- / 1000000000.0;
+ double result = duration.getSeconds() * times + duration.getNanos() * times / 1000000000.0;
if (result < Long.MIN_VALUE || result > Long.MAX_VALUE) {
throw new IllegalArgumentException("Result is out of valid range.");
}
@@ -424,50 +334,49 @@ public class TimeUtil {
int nanos = (int) ((result - seconds) * 1000000000);
return normalizedDuration(seconds, nanos);
}
-
+
+ // TODO(kak): Delete this.
public static Duration divide(Duration duration, double value) {
return multiply(duration, 1.0 / value);
}
-
+
+ // TODO(kak): Delete this.
public static Duration multiply(Duration duration, long times) {
- return createDurationFromBigInteger(
- toBigInteger(duration).multiply(toBigInteger(times)));
+ return createDurationFromBigInteger(toBigInteger(duration).multiply(toBigInteger(times)));
}
-
+
+ // TODO(kak): Delete this.
public static Duration divide(Duration duration, long times) {
- return createDurationFromBigInteger(
- toBigInteger(duration).divide(toBigInteger(times)));
+ return createDurationFromBigInteger(toBigInteger(duration).divide(toBigInteger(times)));
}
-
+
+ // TODO(kak): Delete this.
public static long divide(Duration d1, Duration d2) {
return toBigInteger(d1).divide(toBigInteger(d2)).longValue();
}
-
+
+ // TODO(kak): Delete this.
public static Duration remainder(Duration d1, Duration d2) {
- return createDurationFromBigInteger(
- toBigInteger(d1).remainder(toBigInteger(d2)));
+ return createDurationFromBigInteger(toBigInteger(d1).remainder(toBigInteger(d2)));
}
-
+
private static final BigInteger NANOS_PER_SECOND_BIG_INTEGER =
new BigInteger(String.valueOf(NANOS_PER_SECOND));
-
+
private static BigInteger toBigInteger(Duration duration) {
return toBigInteger(duration.getSeconds())
- .multiply(NANOS_PER_SECOND_BIG_INTEGER)
- .add(toBigInteger(duration.getNanos()));
+ .multiply(NANOS_PER_SECOND_BIG_INTEGER)
+ .add(toBigInteger(duration.getNanos()));
}
-
+
private static BigInteger toBigInteger(long value) {
return new BigInteger(String.valueOf(value));
}
-
+
private static Duration createDurationFromBigInteger(BigInteger value) {
- long seconds = value.divide(
- new BigInteger(String.valueOf(NANOS_PER_SECOND))).longValue();
- int nanos = value.remainder(
- new BigInteger(String.valueOf(NANOS_PER_SECOND))).intValue();
+ long seconds = value.divide(new BigInteger(String.valueOf(NANOS_PER_SECOND))).longValue();
+ int nanos = value.remainder(new BigInteger(String.valueOf(NANOS_PER_SECOND))).intValue();
return normalizedDuration(seconds, nanos);
-
}
private static Duration normalizedDuration(long seconds, int nanos) {
@@ -488,58 +397,4 @@ public class TimeUtil {
}
return Duration.newBuilder().setSeconds(seconds).setNanos(nanos).build();
}
-
- private static Timestamp normalizedTimestamp(long seconds, int nanos) {
- if (nanos <= -NANOS_PER_SECOND || nanos >= NANOS_PER_SECOND) {
- seconds += nanos / NANOS_PER_SECOND;
- nanos %= NANOS_PER_SECOND;
- }
- if (nanos < 0) {
- nanos += NANOS_PER_SECOND;
- seconds -= 1;
- }
- if (seconds < TIMESTAMP_SECONDS_MIN || seconds > TIMESTAMP_SECONDS_MAX) {
- throw new IllegalArgumentException("Timestamp is out of valid range.");
- }
- return Timestamp.newBuilder().setSeconds(seconds).setNanos(nanos).build();
- }
-
- /**
- * Format the nano part of a timestamp or a duration.
- */
- private static String formatNanos(int nanos) {
- assert nanos >= 1 && nanos <= 999999999;
- // Determine whether to use 3, 6, or 9 digits for the nano part.
- if (nanos % NANOS_PER_MILLISECOND == 0) {
- return String.format("%1$03d", nanos / NANOS_PER_MILLISECOND);
- } else if (nanos % NANOS_PER_MICROSECOND == 0) {
- return String.format("%1$06d", nanos / NANOS_PER_MICROSECOND);
- } else {
- return String.format("%1$09d", nanos);
- }
- }
-
- private static int parseNanos(String value) throws ParseException {
- int result = 0;
- for (int i = 0; i < 9; ++i) {
- result = result * 10;
- if (i < value.length()) {
- if (value.charAt(i) < '0' || value.charAt(i) > '9') {
- throw new ParseException("Invalid nanosecnds.", 0);
- }
- result += value.charAt(i) - '0';
- }
- }
- return result;
- }
-
- private static long parseTimezoneOffset(String value) throws ParseException {
- int pos = value.indexOf(':');
- if (pos == -1) {
- throw new ParseException("Invalid offset value: " + value, 0);
- }
- String hours = value.substring(0, pos);
- String minutes = value.substring(pos + 1);
- return (Long.parseLong(hours) * 60 + Long.parseLong(minutes)) * 60;
- }
}
diff --git a/java/util/src/main/java/com/google/protobuf/util/Timestamps.java b/java/util/src/main/java/com/google/protobuf/util/Timestamps.java
new file mode 100644
index 00000000..f1f202da
--- /dev/null
+++ b/java/util/src/main/java/com/google/protobuf/util/Timestamps.java
@@ -0,0 +1,349 @@
+// 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.
+
+package com.google.protobuf.util;
+
+import com.google.protobuf.Duration;
+import com.google.protobuf.Timestamp;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.TimeZone;
+
+/**
+ * Utilities to help create/manipulate {@code protobuf/timestamp.proto}.
+ */
+public final class Timestamps {
+ // Timestamp for "0001-01-01T00:00:00Z"
+ static final long TIMESTAMP_SECONDS_MIN = -62135596800L;
+
+ // Timestamp for "9999-12-31T23:59:59Z"
+ static final long TIMESTAMP_SECONDS_MAX = 253402300799L;
+
+ static final long NANOS_PER_SECOND = 1000000000;
+ static final long NANOS_PER_MILLISECOND = 1000000;
+ static final long NANOS_PER_MICROSECOND = 1000;
+ static final long MILLIS_PER_SECOND = 1000;
+ static final long MICROS_PER_SECOND = 1000000;
+
+ // TODO(kak): Do we want to expose Timestamp constants for MAX/MIN?
+
+ private static final ThreadLocal<SimpleDateFormat> timestampFormat =
+ new ThreadLocal<SimpleDateFormat>() {
+ protected SimpleDateFormat initialValue() {
+ return createTimestampFormat();
+ }
+ };
+
+ private static SimpleDateFormat createTimestampFormat() {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
+ GregorianCalendar calendar = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
+ // We use Proleptic Gregorian Calendar (i.e., Gregorian calendar extends
+ // backwards to year one) for timestamp formating.
+ calendar.setGregorianChange(new Date(Long.MIN_VALUE));
+ sdf.setCalendar(calendar);
+ return sdf;
+ }
+
+ private Timestamps() {}
+
+ /**
+ * Returns true if the given {@link Timestamp} is valid. The {@code seconds} value must be in the
+ * range [-62,135,596,800, +253,402,300,799] (i.e., between 0001-01-01T00:00:00Z and
+ * 9999-12-31T23:59:59Z). The {@code nanos} value must be in the range [0, +999,999,999].
+ *
+ * <p>Note: Negative second values with fractions must still have non-negative nanos value that
+ * counts forward in time.
+ */
+ public static boolean isValid(Timestamp timestamp) {
+ return isValid(timestamp.getSeconds(), timestamp.getNanos());
+ }
+
+ /**
+ * Returns true if the given number of seconds and nanos is a valid {@link Timestamp}. The
+ * {@code seconds} value must be in the range [-62,135,596,800, +253,402,300,799] (i.e., between
+ * 0001-01-01T00:00:00Z and 9999-12-31T23:59:59Z). The {@code nanos} value must be in the range
+ * [0, +999,999,999].
+ *
+ * <p>Note: Negative second values with fractions must still have non-negative nanos value that
+ * counts forward in time.
+ */
+ public static boolean isValid(long seconds, long nanos) {
+ if (seconds < TIMESTAMP_SECONDS_MIN || seconds > TIMESTAMP_SECONDS_MAX) {
+ return false;
+ }
+ if (nanos < 0 || nanos >= NANOS_PER_SECOND) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Throws an {@link IllegalArgumentException} if the given seconds/nanos are not
+ * a valid {@link Timestamp}.
+ */
+ private static void checkValid(long seconds, int nanos) {
+ if (!isValid(seconds, nanos)) {
+ throw new IllegalArgumentException(String.format(
+ "Timestamp is not valid. See proto definition for valid values. "
+ + "Seconds (%s) must be in range [-62,135,596,800, +253,402,300,799]."
+ + "Nanos (%s) must be in range [0, +999,999,999].",
+ seconds, nanos));
+ }
+ }
+
+ /**
+ * Convert Timestamp to RFC 3339 date string format. The output will always
+ * be Z-normalized and uses 3, 6 or 9 fractional digits as required to
+ * represent the exact value. Note that Timestamp can only represent time
+ * from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. See
+ * https://www.ietf.org/rfc/rfc3339.txt
+ *
+ * <p>Example of generated format: "1972-01-01T10:00:20.021Z"
+ *
+ * @return The string representation of the given timestamp.
+ * @throws IllegalArgumentException if the given timestamp is not in the
+ * valid range.
+ */
+ public static String toString(Timestamp timestamp) {
+ long seconds = timestamp.getSeconds();
+ int nanos = timestamp.getNanos();
+ checkValid(seconds, nanos);
+ StringBuilder result = new StringBuilder();
+ // Format the seconds part.
+ Date date = new Date(seconds * MILLIS_PER_SECOND);
+ result.append(timestampFormat.get().format(date));
+ // Format the nanos part.
+ if (nanos != 0) {
+ result.append(".");
+ result.append(formatNanos(nanos));
+ }
+ result.append("Z");
+ return result.toString();
+ }
+
+ /**
+ * Parse from RFC 3339 date string to Timestamp. This method accepts all
+ * outputs of {@link #toString(Timestamp)} and it also accepts any fractional
+ * digits (or none) and any offset as long as they fit into nano-seconds
+ * precision.
+ *
+ * <p>Example of accepted format: "1972-01-01T10:00:20.021-05:00"
+ *
+ * @return A Timestamp parsed from the string.
+ * @throws ParseException if parsing fails.
+ */
+ public static Timestamp parse(String value) throws ParseException {
+ int dayOffset = value.indexOf('T');
+ if (dayOffset == -1) {
+ throw new ParseException("Failed to parse timestamp: invalid timestamp \"" + value + "\"", 0);
+ }
+ int timezoneOffsetPosition = value.indexOf('Z', dayOffset);
+ if (timezoneOffsetPosition == -1) {
+ timezoneOffsetPosition = value.indexOf('+', dayOffset);
+ }
+ if (timezoneOffsetPosition == -1) {
+ timezoneOffsetPosition = value.indexOf('-', dayOffset);
+ }
+ if (timezoneOffsetPosition == -1) {
+ throw new ParseException("Failed to parse timestamp: missing valid timezone offset.", 0);
+ }
+ // Parse seconds and nanos.
+ String timeValue = value.substring(0, timezoneOffsetPosition);
+ String secondValue = timeValue;
+ String nanoValue = "";
+ int pointPosition = timeValue.indexOf('.');
+ if (pointPosition != -1) {
+ secondValue = timeValue.substring(0, pointPosition);
+ nanoValue = timeValue.substring(pointPosition + 1);
+ }
+ Date date = timestampFormat.get().parse(secondValue);
+ long seconds = date.getTime() / MILLIS_PER_SECOND;
+ int nanos = nanoValue.isEmpty() ? 0 : parseNanos(nanoValue);
+ // Parse timezone offsets.
+ if (value.charAt(timezoneOffsetPosition) == 'Z') {
+ if (value.length() != timezoneOffsetPosition + 1) {
+ throw new ParseException(
+ "Failed to parse timestamp: invalid trailing data \""
+ + value.substring(timezoneOffsetPosition)
+ + "\"",
+ 0);
+ }
+ } else {
+ String offsetValue = value.substring(timezoneOffsetPosition + 1);
+ long offset = parseTimezoneOffset(offsetValue);
+ if (value.charAt(timezoneOffsetPosition) == '+') {
+ seconds -= offset;
+ } else {
+ seconds += offset;
+ }
+ }
+ try {
+ return normalizedTimestamp(seconds, nanos);
+ } catch (IllegalArgumentException e) {
+ throw new ParseException("Failed to parse timestmap: timestamp is out of range.", 0);
+ }
+ }
+
+ /**
+ * Create a Timestamp from the number of milliseconds elapsed from the epoch.
+ */
+ public static Timestamp fromMillis(long milliseconds) {
+ return normalizedTimestamp(
+ milliseconds / MILLIS_PER_SECOND,
+ (int) (milliseconds % MILLIS_PER_SECOND * NANOS_PER_MILLISECOND));
+ }
+
+ /**
+ * Convert a Timestamp to the number of milliseconds elapsed from the epoch.
+ *
+ * <p>The result will be rounded down to the nearest millisecond. E.g., if the
+ * timestamp represents "1969-12-31T23:59:59.999999999Z", it will be rounded
+ * to -1 millisecond.
+ */
+ public static long toMillis(Timestamp timestamp) {
+ return timestamp.getSeconds() * MILLIS_PER_SECOND
+ + timestamp.getNanos() / NANOS_PER_MILLISECOND;
+ }
+
+ /**
+ * Create a Timestamp from the number of microseconds elapsed from the epoch.
+ */
+ public static Timestamp fromMicros(long microseconds) {
+ return normalizedTimestamp(
+ microseconds / MICROS_PER_SECOND,
+ (int) (microseconds % MICROS_PER_SECOND * NANOS_PER_MICROSECOND));
+ }
+
+ /**
+ * Convert a Timestamp to the number of microseconds elapsed from the epoch.
+ *
+ * <p>The result will be rounded down to the nearest microsecond. E.g., if the
+ * timestamp represents "1969-12-31T23:59:59.999999999Z", it will be rounded
+ * to -1 millisecond.
+ */
+ public static long toMicros(Timestamp timestamp) {
+ return timestamp.getSeconds() * MICROS_PER_SECOND
+ + timestamp.getNanos() / NANOS_PER_MICROSECOND;
+ }
+
+ /**
+ * Create a Timestamp from the number of nanoseconds elapsed from the epoch.
+ */
+ public static Timestamp fromNanos(long nanoseconds) {
+ return normalizedTimestamp(
+ nanoseconds / NANOS_PER_SECOND, (int) (nanoseconds % NANOS_PER_SECOND));
+ }
+
+ /**
+ * Convert a Timestamp to the number of nanoseconds elapsed from the epoch.
+ */
+ public static long toNanos(Timestamp timestamp) {
+ return timestamp.getSeconds() * NANOS_PER_SECOND + timestamp.getNanos();
+ }
+
+ /**
+ * Calculate the difference between two timestamps.
+ */
+ public static Duration between(Timestamp from, Timestamp to) {
+ return Durations.normalizedDuration(
+ to.getSeconds() - from.getSeconds(), to.getNanos() - from.getNanos());
+ }
+
+ /**
+ * Add a duration to a timestamp.
+ */
+ public static Timestamp add(Timestamp start, Duration length) {
+ return normalizedTimestamp(
+ start.getSeconds() + length.getSeconds(), start.getNanos() + length.getNanos());
+ }
+
+ /**
+ * Subtract a duration from a timestamp.
+ */
+ public static Timestamp subtract(Timestamp start, Duration length) {
+ return normalizedTimestamp(
+ start.getSeconds() - length.getSeconds(), start.getNanos() - length.getNanos());
+ }
+
+ private static Timestamp normalizedTimestamp(long seconds, int nanos) {
+ if (nanos <= -NANOS_PER_SECOND || nanos >= NANOS_PER_SECOND) {
+ seconds += nanos / NANOS_PER_SECOND;
+ nanos %= NANOS_PER_SECOND;
+ }
+ if (nanos < 0) {
+ nanos += NANOS_PER_SECOND;
+ seconds -= 1;
+ }
+ checkValid(seconds, nanos);
+ return Timestamp.newBuilder().setSeconds(seconds).setNanos(nanos).build();
+ }
+
+ private static long parseTimezoneOffset(String value) throws ParseException {
+ int pos = value.indexOf(':');
+ if (pos == -1) {
+ throw new ParseException("Invalid offset value: " + value, 0);
+ }
+ String hours = value.substring(0, pos);
+ String minutes = value.substring(pos + 1);
+ return (Long.parseLong(hours) * 60 + Long.parseLong(minutes)) * 60;
+ }
+
+ static int parseNanos(String value) throws ParseException {
+ int result = 0;
+ for (int i = 0; i < 9; ++i) {
+ result = result * 10;
+ if (i < value.length()) {
+ if (value.charAt(i) < '0' || value.charAt(i) > '9') {
+ throw new ParseException("Invalid nanosecnds.", 0);
+ }
+ result += value.charAt(i) - '0';
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Format the nano part of a timestamp or a duration.
+ */
+ static String formatNanos(int nanos) {
+ assert nanos >= 1 && nanos <= 999999999;
+ // Determine whether to use 3, 6, or 9 digits for the nano part.
+ if (nanos % NANOS_PER_MILLISECOND == 0) {
+ return String.format("%1$03d", nanos / NANOS_PER_MILLISECOND);
+ } else if (nanos % NANOS_PER_MICROSECOND == 0) {
+ return String.format("%1$06d", nanos / NANOS_PER_MICROSECOND);
+ } else {
+ return String.format("%1$09d", nanos);
+ }
+ }
+}
diff --git a/java/util/src/test/java/com/google/protobuf/util/FieldMaskTreeTest.java b/java/util/src/test/java/com/google/protobuf/util/FieldMaskTreeTest.java
index 3391f239..3ee0fc6e 100644
--- a/java/util/src/test/java/com/google/protobuf/util/FieldMaskTreeTest.java
+++ b/java/util/src/test/java/com/google/protobuf/util/FieldMaskTreeTest.java
@@ -61,19 +61,16 @@ public class FieldMaskTreeTest extends TestCase {
tree.addFieldPath("bar");
assertEquals("bar,foo", tree.toString());
}
-
+
public void testMergeFromFieldMask() throws Exception {
- FieldMaskTree tree = new FieldMaskTree(
- FieldMaskUtil.fromString("foo,bar.baz,bar.quz"));
+ FieldMaskTree tree = new FieldMaskTree(FieldMaskUtil.fromString("foo,bar.baz,bar.quz"));
assertEquals("bar.baz,bar.quz,foo", tree.toString());
- tree.mergeFromFieldMask(
- FieldMaskUtil.fromString("foo.bar,bar"));
+ tree.mergeFromFieldMask(FieldMaskUtil.fromString("foo.bar,bar"));
assertEquals("bar,foo", tree.toString());
}
-
+
public void testIntersectFieldPath() throws Exception {
- FieldMaskTree tree = new FieldMaskTree(
- FieldMaskUtil.fromString("foo,bar.baz,bar.quz"));
+ FieldMaskTree tree = new FieldMaskTree(FieldMaskUtil.fromString("foo,bar.baz,bar.quz"));
FieldMaskTree result = new FieldMaskTree();
// Empty path.
tree.intersectFieldPath("", result);
@@ -96,16 +93,18 @@ public class FieldMaskTreeTest extends TestCase {
}
public void testMerge() throws Exception {
- TestAllTypes value = TestAllTypes.newBuilder()
- .setOptionalInt32(1234)
- .setOptionalNestedMessage(NestedMessage.newBuilder().setBb(5678))
- .addRepeatedInt32(4321)
- .addRepeatedNestedMessage(NestedMessage.newBuilder().setBb(8765))
- .build();
- NestedTestAllTypes source = NestedTestAllTypes.newBuilder()
- .setPayload(value)
- .setChild(NestedTestAllTypes.newBuilder().setPayload(value))
- .build();
+ TestAllTypes value =
+ TestAllTypes.newBuilder()
+ .setOptionalInt32(1234)
+ .setOptionalNestedMessage(NestedMessage.newBuilder().setBb(5678))
+ .addRepeatedInt32(4321)
+ .addRepeatedNestedMessage(NestedMessage.newBuilder().setBb(8765))
+ .build();
+ NestedTestAllTypes source =
+ NestedTestAllTypes.newBuilder()
+ .setPayload(value)
+ .setChild(NestedTestAllTypes.newBuilder().setPayload(value))
+ .build();
// Now we have a message source with the following structure:
// [root] -+- payload -+- optional_int32
// | +- optional_nested_message
@@ -116,114 +115,147 @@ public class FieldMaskTreeTest extends TestCase {
// +- optional_nested_message
// +- repeated_int32
// +- repeated_nested_message
-
+
FieldMaskUtil.MergeOptions options = new FieldMaskUtil.MergeOptions();
-
+
// Test merging each individual field.
NestedTestAllTypes.Builder builder = NestedTestAllTypes.newBuilder();
- new FieldMaskTree().addFieldPath("payload.optional_int32")
- .merge(source, builder, options);
+ new FieldMaskTree().addFieldPath("payload.optional_int32").merge(source, builder, options);
NestedTestAllTypes.Builder expected = NestedTestAllTypes.newBuilder();
expected.getPayloadBuilder().setOptionalInt32(1234);
assertEquals(expected.build(), builder.build());
builder = NestedTestAllTypes.newBuilder();
- new FieldMaskTree().addFieldPath("payload.optional_nested_message")
+ new FieldMaskTree()
+ .addFieldPath("payload.optional_nested_message")
.merge(source, builder, options);
expected = NestedTestAllTypes.newBuilder();
- expected.getPayloadBuilder().setOptionalNestedMessage(
- NestedMessage.newBuilder().setBb(5678));
+ expected.getPayloadBuilder().setOptionalNestedMessage(NestedMessage.newBuilder().setBb(5678));
assertEquals(expected.build(), builder.build());
-
builder = NestedTestAllTypes.newBuilder();
- new FieldMaskTree().addFieldPath("payload.repeated_int32")
- .merge(source, builder, options);
+ new FieldMaskTree().addFieldPath("payload.repeated_int32").merge(source, builder, options);
expected = NestedTestAllTypes.newBuilder();
expected.getPayloadBuilder().addRepeatedInt32(4321);
assertEquals(expected.build(), builder.build());
builder = NestedTestAllTypes.newBuilder();
- new FieldMaskTree().addFieldPath("payload.repeated_nested_message")
+ new FieldMaskTree()
+ .addFieldPath("payload.repeated_nested_message")
.merge(source, builder, options);
expected = NestedTestAllTypes.newBuilder();
- expected.getPayloadBuilder().addRepeatedNestedMessage(
- NestedMessage.newBuilder().setBb(8765));
+ expected.getPayloadBuilder().addRepeatedNestedMessage(NestedMessage.newBuilder().setBb(8765));
assertEquals(expected.build(), builder.build());
builder = NestedTestAllTypes.newBuilder();
- new FieldMaskTree().addFieldPath("child.payload.optional_int32")
+ new FieldMaskTree()
+ .addFieldPath("child.payload.optional_int32")
.merge(source, builder, options);
expected = NestedTestAllTypes.newBuilder();
expected.getChildBuilder().getPayloadBuilder().setOptionalInt32(1234);
assertEquals(expected.build(), builder.build());
builder = NestedTestAllTypes.newBuilder();
- new FieldMaskTree().addFieldPath("child.payload.optional_nested_message")
+ new FieldMaskTree()
+ .addFieldPath("child.payload.optional_nested_message")
.merge(source, builder, options);
expected = NestedTestAllTypes.newBuilder();
- expected.getChildBuilder().getPayloadBuilder().setOptionalNestedMessage(
- NestedMessage.newBuilder().setBb(5678));
+ expected
+ .getChildBuilder()
+ .getPayloadBuilder()
+ .setOptionalNestedMessage(NestedMessage.newBuilder().setBb(5678));
assertEquals(expected.build(), builder.build());
-
builder = NestedTestAllTypes.newBuilder();
- new FieldMaskTree().addFieldPath("child.payload.repeated_int32")
+ new FieldMaskTree()
+ .addFieldPath("child.payload.repeated_int32")
.merge(source, builder, options);
expected = NestedTestAllTypes.newBuilder();
expected.getChildBuilder().getPayloadBuilder().addRepeatedInt32(4321);
assertEquals(expected.build(), builder.build());
-
builder = NestedTestAllTypes.newBuilder();
- new FieldMaskTree().addFieldPath("child.payload.repeated_nested_message")
+ new FieldMaskTree()
+ .addFieldPath("child.payload.repeated_nested_message")
.merge(source, builder, options);
expected = NestedTestAllTypes.newBuilder();
- expected.getChildBuilder().getPayloadBuilder().addRepeatedNestedMessage(
- NestedMessage.newBuilder().setBb(8765));
+ expected
+ .getChildBuilder()
+ .getPayloadBuilder()
+ .addRepeatedNestedMessage(NestedMessage.newBuilder().setBb(8765));
assertEquals(expected.build(), builder.build());
-
+
// Test merging all fields.
builder = NestedTestAllTypes.newBuilder();
- new FieldMaskTree().addFieldPath("child").addFieldPath("payload")
- .merge(source, builder, options);
+ new FieldMaskTree()
+ .addFieldPath("child")
+ .addFieldPath("payload")
+ .merge(source, builder, options);
assertEquals(source, builder.build());
-
+
// Test repeated options.
builder = NestedTestAllTypes.newBuilder();
builder.getPayloadBuilder().addRepeatedInt32(1000);
- new FieldMaskTree().addFieldPath("payload.repeated_int32")
- .merge(source, builder, options);
+ new FieldMaskTree().addFieldPath("payload.repeated_int32").merge(source, builder, options);
// Default behavior is to append repeated fields.
assertEquals(2, builder.getPayload().getRepeatedInt32Count());
assertEquals(1000, builder.getPayload().getRepeatedInt32(0));
assertEquals(4321, builder.getPayload().getRepeatedInt32(1));
// Change to replace repeated fields.
options.setReplaceRepeatedFields(true);
- new FieldMaskTree().addFieldPath("payload.repeated_int32")
- .merge(source, builder, options);
+ new FieldMaskTree().addFieldPath("payload.repeated_int32").merge(source, builder, options);
assertEquals(1, builder.getPayload().getRepeatedInt32Count());
assertEquals(4321, builder.getPayload().getRepeatedInt32(0));
-
+
// Test message options.
builder = NestedTestAllTypes.newBuilder();
builder.getPayloadBuilder().setOptionalInt32(1000);
builder.getPayloadBuilder().setOptionalUint32(2000);
- new FieldMaskTree().addFieldPath("payload")
- .merge(source, builder, options);
+ new FieldMaskTree().addFieldPath("payload").merge(source, builder, options);
// Default behavior is to merge message fields.
assertEquals(1234, builder.getPayload().getOptionalInt32());
assertEquals(2000, builder.getPayload().getOptionalUint32());
-
+
+ // Test merging unset message fields.
+ NestedTestAllTypes clearedSource = source.toBuilder().clearPayload().build();
+ builder = NestedTestAllTypes.newBuilder();
+ new FieldMaskTree().addFieldPath("payload").merge(clearedSource, builder, options);
+ assertEquals(false, builder.hasPayload());
+
// Change to replace message fields.
options.setReplaceMessageFields(true);
builder = NestedTestAllTypes.newBuilder();
builder.getPayloadBuilder().setOptionalInt32(1000);
builder.getPayloadBuilder().setOptionalUint32(2000);
- new FieldMaskTree().addFieldPath("payload")
- .merge(source, builder, options);
+ new FieldMaskTree().addFieldPath("payload").merge(source, builder, options);
assertEquals(1234, builder.getPayload().getOptionalInt32());
assertEquals(0, builder.getPayload().getOptionalUint32());
+
+ // Test merging unset message fields.
+ builder = NestedTestAllTypes.newBuilder();
+ builder.getPayloadBuilder().setOptionalInt32(1000);
+ builder.getPayloadBuilder().setOptionalUint32(2000);
+ new FieldMaskTree().addFieldPath("payload").merge(clearedSource, builder, options);
+ assertEquals(false, builder.hasPayload());
+
+ // Test merging unset primitive fields.
+ builder = source.toBuilder();
+ builder.getPayloadBuilder().clearOptionalInt32();
+ NestedTestAllTypes sourceWithPayloadInt32Unset = builder.build();
+ builder = source.toBuilder();
+ new FieldMaskTree()
+ .addFieldPath("payload.optional_int32")
+ .merge(sourceWithPayloadInt32Unset, builder, options);
+ assertEquals(true, builder.getPayload().hasOptionalInt32());
+ assertEquals(0, builder.getPayload().getOptionalInt32());
+
+ // Change to clear unset primitive fields.
+ options.setReplacePrimitiveFields(true);
+ builder = source.toBuilder();
+ new FieldMaskTree()
+ .addFieldPath("payload.optional_int32")
+ .merge(sourceWithPayloadInt32Unset, builder, options);
+ assertEquals(true, builder.hasPayload());
+ assertEquals(false, builder.getPayload().hasOptionalInt32());
}
}
-
diff --git a/java/util/src/test/java/com/google/protobuf/util/FieldMaskUtilTest.java b/java/util/src/test/java/com/google/protobuf/util/FieldMaskUtilTest.java
index 67fbe0b1..1a998570 100644
--- a/java/util/src/test/java/com/google/protobuf/util/FieldMaskUtilTest.java
+++ b/java/util/src/test/java/com/google/protobuf/util/FieldMaskUtilTest.java
@@ -41,40 +41,58 @@ public class FieldMaskUtilTest extends TestCase {
public void testIsValid() throws Exception {
assertTrue(FieldMaskUtil.isValid(NestedTestAllTypes.class, "payload"));
assertFalse(FieldMaskUtil.isValid(NestedTestAllTypes.class, "nonexist"));
- assertTrue(FieldMaskUtil.isValid(
- NestedTestAllTypes.class, "payload.optional_int32"));
- assertTrue(FieldMaskUtil.isValid(
- NestedTestAllTypes.class, "payload.repeated_int32"));
- assertTrue(FieldMaskUtil.isValid(
- NestedTestAllTypes.class, "payload.optional_nested_message"));
- assertTrue(FieldMaskUtil.isValid(
- NestedTestAllTypes.class, "payload.repeated_nested_message"));
- assertFalse(FieldMaskUtil.isValid(
- NestedTestAllTypes.class, "payload.nonexist"));
-
- assertTrue(FieldMaskUtil.isValid(
- NestedTestAllTypes.class, "payload.optional_nested_message.bb"));
+ assertTrue(FieldMaskUtil.isValid(NestedTestAllTypes.class, "payload.optional_int32"));
+ assertTrue(FieldMaskUtil.isValid(NestedTestAllTypes.class, "payload.repeated_int32"));
+ assertTrue(FieldMaskUtil.isValid(NestedTestAllTypes.class, "payload.optional_nested_message"));
+ assertTrue(FieldMaskUtil.isValid(NestedTestAllTypes.class, "payload.repeated_nested_message"));
+ assertFalse(FieldMaskUtil.isValid(NestedTestAllTypes.class, "payload.nonexist"));
+
+ assertTrue(
+ FieldMaskUtil.isValid(NestedTestAllTypes.class, FieldMaskUtil.fromString("payload")));
+ assertFalse(
+ FieldMaskUtil.isValid(NestedTestAllTypes.class, FieldMaskUtil.fromString("nonexist")));
+ assertFalse(
+ FieldMaskUtil.isValid(
+ NestedTestAllTypes.class, FieldMaskUtil.fromString("payload,nonexist")));
+
+ assertTrue(FieldMaskUtil.isValid(NestedTestAllTypes.getDescriptor(), "payload"));
+ assertFalse(FieldMaskUtil.isValid(NestedTestAllTypes.getDescriptor(), "nonexist"));
+
+ assertTrue(
+ FieldMaskUtil.isValid(
+ NestedTestAllTypes.getDescriptor(), FieldMaskUtil.fromString("payload")));
+ assertFalse(
+ FieldMaskUtil.isValid(
+ NestedTestAllTypes.getDescriptor(), FieldMaskUtil.fromString("nonexist")));
+
+ assertTrue(
+ FieldMaskUtil.isValid(NestedTestAllTypes.class, "payload.optional_nested_message.bb"));
// Repeated fields cannot have sub-paths.
- assertFalse(FieldMaskUtil.isValid(
- NestedTestAllTypes.class, "payload.repeated_nested_message.bb"));
+ assertFalse(
+ FieldMaskUtil.isValid(NestedTestAllTypes.class, "payload.repeated_nested_message.bb"));
// Non-message fields cannot have sub-paths.
- assertFalse(FieldMaskUtil.isValid(
- NestedTestAllTypes.class, "payload.optional_int32.bb"));
+ assertFalse(FieldMaskUtil.isValid(NestedTestAllTypes.class, "payload.optional_int32.bb"));
}
-
+
public void testToString() throws Exception {
assertEquals("", FieldMaskUtil.toString(FieldMask.getDefaultInstance()));
FieldMask mask = FieldMask.newBuilder().addPaths("foo").build();
assertEquals("foo", FieldMaskUtil.toString(mask));
mask = FieldMask.newBuilder().addPaths("foo").addPaths("bar").build();
assertEquals("foo,bar", FieldMaskUtil.toString(mask));
-
+
// Empty field paths are ignored.
- mask = FieldMask.newBuilder().addPaths("").addPaths("foo").addPaths("").
- addPaths("bar").addPaths("").build();
+ mask =
+ FieldMask.newBuilder()
+ .addPaths("")
+ .addPaths("foo")
+ .addPaths("")
+ .addPaths("bar")
+ .addPaths("")
+ .build();
assertEquals("foo,bar", FieldMaskUtil.toString(mask));
}
-
+
public void testFromString() throws Exception {
FieldMask mask = FieldMaskUtil.fromString("");
assertEquals(0, mask.getPathsCount());
@@ -85,25 +103,75 @@ public class FieldMaskUtilTest extends TestCase {
assertEquals(2, mask.getPathsCount());
assertEquals("foo", mask.getPaths(0));
assertEquals("bar.baz", mask.getPaths(1));
-
+
// Empty field paths are ignore.
mask = FieldMaskUtil.fromString(",foo,,bar,");
assertEquals(2, mask.getPathsCount());
assertEquals("foo", mask.getPaths(0));
assertEquals("bar", mask.getPaths(1));
-
+
// Check whether the field paths are valid if a class parameter is provided.
mask = FieldMaskUtil.fromString(NestedTestAllTypes.class, ",payload");
-
+
try {
- mask = FieldMaskUtil.fromString(
- NestedTestAllTypes.class, "payload,nonexist");
+ mask = FieldMaskUtil.fromString(NestedTestAllTypes.class, "payload,nonexist");
fail("Exception is expected.");
} catch (IllegalArgumentException e) {
// Expected.
}
}
-
+
+ public void testFromFieldNumbers() throws Exception {
+ FieldMask mask = FieldMaskUtil.fromFieldNumbers(TestAllTypes.class);
+ assertEquals(0, mask.getPathsCount());
+ mask =
+ FieldMaskUtil.fromFieldNumbers(
+ TestAllTypes.class, TestAllTypes.OPTIONAL_INT32_FIELD_NUMBER);
+ assertEquals(1, mask.getPathsCount());
+ assertEquals("optional_int32", mask.getPaths(0));
+ mask =
+ FieldMaskUtil.fromFieldNumbers(
+ TestAllTypes.class,
+ TestAllTypes.OPTIONAL_INT32_FIELD_NUMBER,
+ TestAllTypes.OPTIONAL_INT64_FIELD_NUMBER);
+ assertEquals(2, mask.getPathsCount());
+ assertEquals("optional_int32", mask.getPaths(0));
+ assertEquals("optional_int64", mask.getPaths(1));
+
+ try {
+ int invalidFieldNumber = 1000;
+ mask = FieldMaskUtil.fromFieldNumbers(TestAllTypes.class, invalidFieldNumber);
+ fail("Exception is expected.");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ public void testToJsonString() throws Exception {
+ FieldMask mask = FieldMask.getDefaultInstance();
+ assertEquals("", FieldMaskUtil.toJsonString(mask));
+ mask = FieldMask.newBuilder().addPaths("foo").build();
+ assertEquals("foo", FieldMaskUtil.toJsonString(mask));
+ mask = FieldMask.newBuilder().addPaths("foo.bar_baz").addPaths("").build();
+ assertEquals("foo.barBaz", FieldMaskUtil.toJsonString(mask));
+ mask = FieldMask.newBuilder().addPaths("foo").addPaths("bar_baz").build();
+ assertEquals("foo,barBaz", FieldMaskUtil.toJsonString(mask));
+ }
+
+ public void testFromJsonString() throws Exception {
+ FieldMask mask = FieldMaskUtil.fromJsonString("");
+ assertEquals(0, mask.getPathsCount());
+ mask = FieldMaskUtil.fromJsonString("foo");
+ assertEquals(1, mask.getPathsCount());
+ assertEquals("foo", mask.getPaths(0));
+ mask = FieldMaskUtil.fromJsonString("foo.barBaz");
+ assertEquals(1, mask.getPathsCount());
+ assertEquals("foo.bar_baz", mask.getPaths(0));
+ mask = FieldMaskUtil.fromJsonString("foo,barBaz");
+ assertEquals(2, mask.getPathsCount());
+ assertEquals("foo", mask.getPaths(0));
+ assertEquals("bar_baz", mask.getPaths(1));
+ }
+
public void testUnion() throws Exception {
// Only test a simple case here and expect
// {@link FieldMaskTreeTest#testAddFieldPath} to cover all scenarios.
@@ -112,7 +180,16 @@ public class FieldMaskUtilTest extends TestCase {
FieldMask result = FieldMaskUtil.union(mask1, mask2);
assertEquals("bar,foo", FieldMaskUtil.toString(result));
}
-
+
+ public void testUnion_usingVarArgs() throws Exception {
+ FieldMask mask1 = FieldMaskUtil.fromString("foo");
+ FieldMask mask2 = FieldMaskUtil.fromString("foo.bar,bar.quz");
+ FieldMask mask3 = FieldMaskUtil.fromString("bar.quz");
+ FieldMask mask4 = FieldMaskUtil.fromString("bar");
+ FieldMask result = FieldMaskUtil.union(mask1, mask2, mask3, mask4);
+ assertEquals("bar,foo", FieldMaskUtil.toString(result));
+ }
+
public void testIntersection() throws Exception {
// Only test a simple case here and expect
// {@link FieldMaskTreeTest#testIntersectFieldPath} to cover all scenarios.
@@ -121,13 +198,14 @@ public class FieldMaskUtilTest extends TestCase {
FieldMask result = FieldMaskUtil.intersection(mask1, mask2);
assertEquals("bar.baz,bar.quz,foo.bar", FieldMaskUtil.toString(result));
}
-
+
public void testMerge() throws Exception {
// Only test a simple case here and expect
// {@link FieldMaskTreeTest#testMerge} to cover all scenarios.
- NestedTestAllTypes source = NestedTestAllTypes.newBuilder()
- .setPayload(TestAllTypes.newBuilder().setOptionalInt32(1234))
- .build();
+ NestedTestAllTypes source =
+ NestedTestAllTypes.newBuilder()
+ .setPayload(TestAllTypes.newBuilder().setOptionalInt32(1234))
+ .build();
NestedTestAllTypes.Builder builder = NestedTestAllTypes.newBuilder();
FieldMaskUtil.merge(FieldMaskUtil.fromString("payload"), source, builder);
assertEquals(1234, builder.getPayload().getOptionalInt32());
diff --git a/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java b/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java
index ddf5ad2a..6fc784ef 100644
--- a/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java
+++ b/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java
@@ -41,6 +41,7 @@ import com.google.protobuf.Int64Value;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.ListValue;
import com.google.protobuf.Message;
+import com.google.protobuf.NullValue;
import com.google.protobuf.StringValue;
import com.google.protobuf.Struct;
import com.google.protobuf.UInt32Value;
@@ -51,9 +52,11 @@ import com.google.protobuf.util.JsonTestProto.TestAllTypes;
import com.google.protobuf.util.JsonTestProto.TestAllTypes.NestedEnum;
import com.google.protobuf.util.JsonTestProto.TestAllTypes.NestedMessage;
import com.google.protobuf.util.JsonTestProto.TestAny;
+import com.google.protobuf.util.JsonTestProto.TestCustomJsonName;
import com.google.protobuf.util.JsonTestProto.TestDuration;
import com.google.protobuf.util.JsonTestProto.TestFieldMask;
import com.google.protobuf.util.JsonTestProto.TestMap;
+import com.google.protobuf.util.JsonTestProto.TestOneof;
import com.google.protobuf.util.JsonTestProto.TestStruct;
import com.google.protobuf.util.JsonTestProto.TestTimestamp;
import com.google.protobuf.util.JsonTestProto.TestWrappers;
@@ -80,7 +83,7 @@ public class JsonFormatTest extends TestCase {
builder.setOptionalDouble(1.25);
builder.setOptionalBool(true);
builder.setOptionalString("Hello world!");
- builder.setOptionalBytes(ByteString.copyFrom(new byte[]{0, 1, 2}));
+ builder.setOptionalBytes(ByteString.copyFrom(new byte[] {0, 1, 2}));
builder.setOptionalNestedEnum(NestedEnum.BAR);
builder.getOptionalNestedMessageBuilder().setValue(100);
@@ -98,7 +101,7 @@ public class JsonFormatTest extends TestCase {
builder.addRepeatedDouble(1.25);
builder.addRepeatedBool(true);
builder.addRepeatedString("Hello world!");
- builder.addRepeatedBytes(ByteString.copyFrom(new byte[]{0, 1, 2}));
+ builder.addRepeatedBytes(ByteString.copyFrom(new byte[] {0, 1, 2}));
builder.addRepeatedNestedEnum(NestedEnum.BAR);
builder.addRepeatedNestedMessageBuilder().setValue(100);
@@ -116,15 +119,15 @@ public class JsonFormatTest extends TestCase {
builder.addRepeatedDouble(11.25);
builder.addRepeatedBool(true);
builder.addRepeatedString("ello world!");
- builder.addRepeatedBytes(ByteString.copyFrom(new byte[]{1, 2}));
+ builder.addRepeatedBytes(ByteString.copyFrom(new byte[] {1, 2}));
builder.addRepeatedNestedEnum(NestedEnum.BAZ);
builder.addRepeatedNestedMessageBuilder().setValue(200);
}
-
+
private void assertRoundTripEquals(Message message) throws Exception {
assertRoundTripEquals(message, TypeRegistry.getEmptyTypeRegistry());
}
-
+
private void assertRoundTripEquals(Message message, TypeRegistry registry) throws Exception {
JsonFormat.Printer printer = JsonFormat.printer().usingTypeRegistry(registry);
JsonFormat.Parser parser = JsonFormat.parser().usingTypeRegistry(registry);
@@ -133,125 +136,135 @@ public class JsonFormatTest extends TestCase {
Message parsedMessage = builder.build();
assertEquals(message.toString(), parsedMessage.toString());
}
-
+
private String toJsonString(Message message) throws IOException {
return JsonFormat.printer().print(message);
}
-
+ private String toCompactJsonString(Message message) throws IOException {
+ return JsonFormat.printer().omittingInsignificantWhitespace().print(message);
+ }
+
private void mergeFromJson(String json, Message.Builder builder) throws IOException {
JsonFormat.parser().merge(json, builder);
}
-
+
public void testAllFields() throws Exception {
TestAllTypes.Builder builder = TestAllTypes.newBuilder();
setAllFields(builder);
TestAllTypes message = builder.build();
-
- assertEquals(
+
+ assertEquals(
"{\n"
- + " \"optionalInt32\": 1234,\n"
- + " \"optionalInt64\": \"1234567890123456789\",\n"
- + " \"optionalUint32\": 5678,\n"
- + " \"optionalUint64\": \"2345678901234567890\",\n"
- + " \"optionalSint32\": 9012,\n"
- + " \"optionalSint64\": \"3456789012345678901\",\n"
- + " \"optionalFixed32\": 3456,\n"
- + " \"optionalFixed64\": \"4567890123456789012\",\n"
- + " \"optionalSfixed32\": 7890,\n"
- + " \"optionalSfixed64\": \"5678901234567890123\",\n"
- + " \"optionalFloat\": 1.5,\n"
- + " \"optionalDouble\": 1.25,\n"
- + " \"optionalBool\": true,\n"
- + " \"optionalString\": \"Hello world!\",\n"
- + " \"optionalBytes\": \"AAEC\",\n"
- + " \"optionalNestedMessage\": {\n"
- + " \"value\": 100\n"
- + " },\n"
- + " \"optionalNestedEnum\": \"BAR\",\n"
- + " \"repeatedInt32\": [1234, 234],\n"
- + " \"repeatedInt64\": [\"1234567890123456789\", \"234567890123456789\"],\n"
- + " \"repeatedUint32\": [5678, 678],\n"
- + " \"repeatedUint64\": [\"2345678901234567890\", \"345678901234567890\"],\n"
- + " \"repeatedSint32\": [9012, 10],\n"
- + " \"repeatedSint64\": [\"3456789012345678901\", \"456789012345678901\"],\n"
- + " \"repeatedFixed32\": [3456, 456],\n"
- + " \"repeatedFixed64\": [\"4567890123456789012\", \"567890123456789012\"],\n"
- + " \"repeatedSfixed32\": [7890, 890],\n"
- + " \"repeatedSfixed64\": [\"5678901234567890123\", \"678901234567890123\"],\n"
- + " \"repeatedFloat\": [1.5, 11.5],\n"
- + " \"repeatedDouble\": [1.25, 11.25],\n"
- + " \"repeatedBool\": [true, true],\n"
- + " \"repeatedString\": [\"Hello world!\", \"ello world!\"],\n"
- + " \"repeatedBytes\": [\"AAEC\", \"AQI=\"],\n"
- + " \"repeatedNestedMessage\": [{\n"
- + " \"value\": 100\n"
- + " }, {\n"
- + " \"value\": 200\n"
- + " }],\n"
- + " \"repeatedNestedEnum\": [\"BAR\", \"BAZ\"]\n"
- + "}",
+ + " \"optionalInt32\": 1234,\n"
+ + " \"optionalInt64\": \"1234567890123456789\",\n"
+ + " \"optionalUint32\": 5678,\n"
+ + " \"optionalUint64\": \"2345678901234567890\",\n"
+ + " \"optionalSint32\": 9012,\n"
+ + " \"optionalSint64\": \"3456789012345678901\",\n"
+ + " \"optionalFixed32\": 3456,\n"
+ + " \"optionalFixed64\": \"4567890123456789012\",\n"
+ + " \"optionalSfixed32\": 7890,\n"
+ + " \"optionalSfixed64\": \"5678901234567890123\",\n"
+ + " \"optionalFloat\": 1.5,\n"
+ + " \"optionalDouble\": 1.25,\n"
+ + " \"optionalBool\": true,\n"
+ + " \"optionalString\": \"Hello world!\",\n"
+ + " \"optionalBytes\": \"AAEC\",\n"
+ + " \"optionalNestedMessage\": {\n"
+ + " \"value\": 100\n"
+ + " },\n"
+ + " \"optionalNestedEnum\": \"BAR\",\n"
+ + " \"repeatedInt32\": [1234, 234],\n"
+ + " \"repeatedInt64\": [\"1234567890123456789\", \"234567890123456789\"],\n"
+ + " \"repeatedUint32\": [5678, 678],\n"
+ + " \"repeatedUint64\": [\"2345678901234567890\", \"345678901234567890\"],\n"
+ + " \"repeatedSint32\": [9012, 10],\n"
+ + " \"repeatedSint64\": [\"3456789012345678901\", \"456789012345678901\"],\n"
+ + " \"repeatedFixed32\": [3456, 456],\n"
+ + " \"repeatedFixed64\": [\"4567890123456789012\", \"567890123456789012\"],\n"
+ + " \"repeatedSfixed32\": [7890, 890],\n"
+ + " \"repeatedSfixed64\": [\"5678901234567890123\", \"678901234567890123\"],\n"
+ + " \"repeatedFloat\": [1.5, 11.5],\n"
+ + " \"repeatedDouble\": [1.25, 11.25],\n"
+ + " \"repeatedBool\": [true, true],\n"
+ + " \"repeatedString\": [\"Hello world!\", \"ello world!\"],\n"
+ + " \"repeatedBytes\": [\"AAEC\", \"AQI=\"],\n"
+ + " \"repeatedNestedMessage\": [{\n"
+ + " \"value\": 100\n"
+ + " }, {\n"
+ + " \"value\": 200\n"
+ + " }],\n"
+ + " \"repeatedNestedEnum\": [\"BAR\", \"BAZ\"]\n"
+ + "}",
toJsonString(message));
-
+
assertRoundTripEquals(message);
}
-
+
public void testUnknownEnumValues() throws Exception {
- // Unknown enum values will be dropped.
- // TODO(xiaofeng): We may want to revisit this (whether we should omit
- // unknown enum values).
- TestAllTypes message = TestAllTypes.newBuilder()
- .setOptionalNestedEnumValue(12345)
- .addRepeatedNestedEnumValue(12345)
- .addRepeatedNestedEnumValue(0)
- .build();
+ TestAllTypes message =
+ TestAllTypes.newBuilder()
+ .setOptionalNestedEnumValue(12345)
+ .addRepeatedNestedEnumValue(12345)
+ .addRepeatedNestedEnumValue(0)
+ .build();
assertEquals(
"{\n"
- + " \"repeatedNestedEnum\": [\"FOO\"]\n"
- + "}", toJsonString(message));
-
+ + " \"optionalNestedEnum\": 12345,\n"
+ + " \"repeatedNestedEnum\": [12345, \"FOO\"]\n"
+ + "}",
+ toJsonString(message));
+ assertRoundTripEquals(message);
+
TestMap.Builder mapBuilder = TestMap.newBuilder();
- mapBuilder.getMutableInt32ToEnumMapValue().put(1, 0);
+ mapBuilder.putInt32ToEnumMapValue(1, 0);
mapBuilder.getMutableInt32ToEnumMapValue().put(2, 12345);
TestMap mapMessage = mapBuilder.build();
assertEquals(
- "{\n"
- + " \"int32ToEnumMap\": {\n"
- + " \"1\": \"FOO\"\n"
- + " }\n"
- + "}", toJsonString(mapMessage));
+ "{\n"
+ + " \"int32ToEnumMap\": {\n"
+ + " \"1\": \"FOO\",\n"
+ + " \"2\": 12345\n"
+ + " }\n"
+ + "}",
+ toJsonString(mapMessage));
+ assertRoundTripEquals(mapMessage);
}
-
+
public void testSpecialFloatValues() throws Exception {
- TestAllTypes message = TestAllTypes.newBuilder()
- .addRepeatedFloat(Float.NaN)
- .addRepeatedFloat(Float.POSITIVE_INFINITY)
- .addRepeatedFloat(Float.NEGATIVE_INFINITY)
- .addRepeatedDouble(Double.NaN)
- .addRepeatedDouble(Double.POSITIVE_INFINITY)
- .addRepeatedDouble(Double.NEGATIVE_INFINITY)
- .build();
+ TestAllTypes message =
+ TestAllTypes.newBuilder()
+ .addRepeatedFloat(Float.NaN)
+ .addRepeatedFloat(Float.POSITIVE_INFINITY)
+ .addRepeatedFloat(Float.NEGATIVE_INFINITY)
+ .addRepeatedDouble(Double.NaN)
+ .addRepeatedDouble(Double.POSITIVE_INFINITY)
+ .addRepeatedDouble(Double.NEGATIVE_INFINITY)
+ .build();
assertEquals(
"{\n"
- + " \"repeatedFloat\": [\"NaN\", \"Infinity\", \"-Infinity\"],\n"
- + " \"repeatedDouble\": [\"NaN\", \"Infinity\", \"-Infinity\"]\n"
- + "}", toJsonString(message));
-
+ + " \"repeatedFloat\": [\"NaN\", \"Infinity\", \"-Infinity\"],\n"
+ + " \"repeatedDouble\": [\"NaN\", \"Infinity\", \"-Infinity\"]\n"
+ + "}",
+ toJsonString(message));
+
assertRoundTripEquals(message);
}
-
+
public void testParserAcceptStringForNumbericField() throws Exception {
TestAllTypes.Builder builder = TestAllTypes.newBuilder();
mergeFromJson(
"{\n"
- + " \"optionalInt32\": \"1234\",\n"
- + " \"optionalUint32\": \"5678\",\n"
- + " \"optionalSint32\": \"9012\",\n"
- + " \"optionalFixed32\": \"3456\",\n"
- + " \"optionalSfixed32\": \"7890\",\n"
- + " \"optionalFloat\": \"1.5\",\n"
- + " \"optionalDouble\": \"1.25\",\n"
- + " \"optionalBool\": \"true\"\n"
- + "}", builder);
+ + " \"optionalInt32\": \"1234\",\n"
+ + " \"optionalUint32\": \"5678\",\n"
+ + " \"optionalSint32\": \"9012\",\n"
+ + " \"optionalFixed32\": \"3456\",\n"
+ + " \"optionalSfixed32\": \"7890\",\n"
+ + " \"optionalFloat\": \"1.5\",\n"
+ + " \"optionalDouble\": \"1.25\",\n"
+ + " \"optionalBool\": \"true\"\n"
+ + "}",
+ builder);
TestAllTypes message = builder.build();
assertEquals(1234, message.getOptionalInt32());
assertEquals(5678, message.getOptionalUint32());
@@ -262,7 +275,37 @@ public class JsonFormatTest extends TestCase {
assertEquals(1.25, message.getOptionalDouble());
assertEquals(true, message.getOptionalBool());
}
-
+
+ public void testParserAcceptFloatingPointValueForIntegerField() throws Exception {
+ // Test that numeric values like "1.000", "1e5" will also be accepted.
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ mergeFromJson(
+ "{\n"
+ + " \"repeatedInt32\": [1.000, 1e5, \"1.000\", \"1e5\"],\n"
+ + " \"repeatedUint32\": [1.000, 1e5, \"1.000\", \"1e5\"],\n"
+ + " \"repeatedInt64\": [1.000, 1e5, \"1.000\", \"1e5\"],\n"
+ + " \"repeatedUint64\": [1.000, 1e5, \"1.000\", \"1e5\"]\n"
+ + "}",
+ builder);
+ int[] expectedValues = new int[] {1, 100000, 1, 100000};
+ assertEquals(4, builder.getRepeatedInt32Count());
+ assertEquals(4, builder.getRepeatedUint32Count());
+ assertEquals(4, builder.getRepeatedInt64Count());
+ assertEquals(4, builder.getRepeatedUint64Count());
+ for (int i = 0; i < 4; ++i) {
+ assertEquals(expectedValues[i], builder.getRepeatedInt32(i));
+ assertEquals(expectedValues[i], builder.getRepeatedUint32(i));
+ assertEquals(expectedValues[i], builder.getRepeatedInt64(i));
+ assertEquals(expectedValues[i], builder.getRepeatedUint64(i));
+ }
+
+ // Non-integers will still be rejected.
+ assertRejects("optionalInt32", "1.5");
+ assertRejects("optionalUint32", "1.5");
+ assertRejects("optionalInt64", "1.5");
+ assertRejects("optionalUint64", "1.5");
+ }
+
private void assertRejects(String name, String value) {
TestAllTypes.Builder builder = TestAllTypes.newBuilder();
try {
@@ -280,24 +323,25 @@ public class JsonFormatTest extends TestCase {
// Expected.
}
}
-
+
private void assertAccepts(String name, String value) throws IOException {
TestAllTypes.Builder builder = TestAllTypes.newBuilder();
// Both numeric form and string form are accepted.
mergeFromJson("{\"" + name + "\":" + value + "}", builder);
+ builder.clear();
mergeFromJson("{\"" + name + "\":\"" + value + "\"}", builder);
}
-
+
public void testParserRejectOutOfRangeNumericValues() throws Exception {
assertAccepts("optionalInt32", String.valueOf(Integer.MAX_VALUE));
assertAccepts("optionalInt32", String.valueOf(Integer.MIN_VALUE));
assertRejects("optionalInt32", String.valueOf(Integer.MAX_VALUE + 1L));
assertRejects("optionalInt32", String.valueOf(Integer.MIN_VALUE - 1L));
-
+
assertAccepts("optionalUint32", String.valueOf(Integer.MAX_VALUE + 1L));
assertRejects("optionalUint32", "123456789012345");
assertRejects("optionalUint32", "-1");
-
+
BigInteger one = new BigInteger("1");
BigInteger maxLong = new BigInteger(String.valueOf(Long.MAX_VALUE));
BigInteger minLong = new BigInteger(String.valueOf(Long.MIN_VALUE));
@@ -318,7 +362,7 @@ public class JsonFormatTest extends TestCase {
assertAccepts("optionalFloat", String.valueOf(-Float.MAX_VALUE));
assertRejects("optionalFloat", String.valueOf(Double.MAX_VALUE));
assertRejects("optionalFloat", String.valueOf(-Double.MAX_VALUE));
-
+
BigDecimal moreThanOne = new BigDecimal("1.000001");
BigDecimal maxDouble = new BigDecimal(Double.MAX_VALUE);
BigDecimal minDouble = new BigDecimal(-Double.MAX_VALUE);
@@ -327,297 +371,294 @@ public class JsonFormatTest extends TestCase {
assertRejects("optionalDouble", maxDouble.multiply(moreThanOne).toString());
assertRejects("optionalDouble", minDouble.multiply(moreThanOne).toString());
}
-
+
public void testParserAcceptNull() throws Exception {
TestAllTypes.Builder builder = TestAllTypes.newBuilder();
mergeFromJson(
"{\n"
- + " \"optionalInt32\": null,\n"
- + " \"optionalInt64\": null,\n"
- + " \"optionalUint32\": null,\n"
- + " \"optionalUint64\": null,\n"
- + " \"optionalSint32\": null,\n"
- + " \"optionalSint64\": null,\n"
- + " \"optionalFixed32\": null,\n"
- + " \"optionalFixed64\": null,\n"
- + " \"optionalSfixed32\": null,\n"
- + " \"optionalSfixed64\": null,\n"
- + " \"optionalFloat\": null,\n"
- + " \"optionalDouble\": null,\n"
- + " \"optionalBool\": null,\n"
- + " \"optionalString\": null,\n"
- + " \"optionalBytes\": null,\n"
- + " \"optionalNestedMessage\": null,\n"
- + " \"optionalNestedEnum\": null,\n"
- + " \"repeatedInt32\": null,\n"
- + " \"repeatedInt64\": null,\n"
- + " \"repeatedUint32\": null,\n"
- + " \"repeatedUint64\": null,\n"
- + " \"repeatedSint32\": null,\n"
- + " \"repeatedSint64\": null,\n"
- + " \"repeatedFixed32\": null,\n"
- + " \"repeatedFixed64\": null,\n"
- + " \"repeatedSfixed32\": null,\n"
- + " \"repeatedSfixed64\": null,\n"
- + " \"repeatedFloat\": null,\n"
- + " \"repeatedDouble\": null,\n"
- + " \"repeatedBool\": null,\n"
- + " \"repeatedString\": null,\n"
- + " \"repeatedBytes\": null,\n"
- + " \"repeatedNestedMessage\": null,\n"
- + " \"repeatedNestedEnum\": null\n"
- + "}", builder);
+ + " \"optionalInt32\": null,\n"
+ + " \"optionalInt64\": null,\n"
+ + " \"optionalUint32\": null,\n"
+ + " \"optionalUint64\": null,\n"
+ + " \"optionalSint32\": null,\n"
+ + " \"optionalSint64\": null,\n"
+ + " \"optionalFixed32\": null,\n"
+ + " \"optionalFixed64\": null,\n"
+ + " \"optionalSfixed32\": null,\n"
+ + " \"optionalSfixed64\": null,\n"
+ + " \"optionalFloat\": null,\n"
+ + " \"optionalDouble\": null,\n"
+ + " \"optionalBool\": null,\n"
+ + " \"optionalString\": null,\n"
+ + " \"optionalBytes\": null,\n"
+ + " \"optionalNestedMessage\": null,\n"
+ + " \"optionalNestedEnum\": null,\n"
+ + " \"repeatedInt32\": null,\n"
+ + " \"repeatedInt64\": null,\n"
+ + " \"repeatedUint32\": null,\n"
+ + " \"repeatedUint64\": null,\n"
+ + " \"repeatedSint32\": null,\n"
+ + " \"repeatedSint64\": null,\n"
+ + " \"repeatedFixed32\": null,\n"
+ + " \"repeatedFixed64\": null,\n"
+ + " \"repeatedSfixed32\": null,\n"
+ + " \"repeatedSfixed64\": null,\n"
+ + " \"repeatedFloat\": null,\n"
+ + " \"repeatedDouble\": null,\n"
+ + " \"repeatedBool\": null,\n"
+ + " \"repeatedString\": null,\n"
+ + " \"repeatedBytes\": null,\n"
+ + " \"repeatedNestedMessage\": null,\n"
+ + " \"repeatedNestedEnum\": null\n"
+ + "}",
+ builder);
TestAllTypes message = builder.build();
assertEquals(TestAllTypes.getDefaultInstance(), message);
-
- // Repeated field elements can also be null.
- builder = TestAllTypes.newBuilder();
- mergeFromJson(
- "{\n"
- + " \"repeatedInt32\": [null, null],\n"
- + " \"repeatedInt64\": [null, null],\n"
- + " \"repeatedUint32\": [null, null],\n"
- + " \"repeatedUint64\": [null, null],\n"
- + " \"repeatedSint32\": [null, null],\n"
- + " \"repeatedSint64\": [null, null],\n"
- + " \"repeatedFixed32\": [null, null],\n"
- + " \"repeatedFixed64\": [null, null],\n"
- + " \"repeatedSfixed32\": [null, null],\n"
- + " \"repeatedSfixed64\": [null, null],\n"
- + " \"repeatedFloat\": [null, null],\n"
- + " \"repeatedDouble\": [null, null],\n"
- + " \"repeatedBool\": [null, null],\n"
- + " \"repeatedString\": [null, null],\n"
- + " \"repeatedBytes\": [null, null],\n"
- + " \"repeatedNestedMessage\": [null, null],\n"
- + " \"repeatedNestedEnum\": [null, null]\n"
- + "}", builder);
- message = builder.build();
- // "null" elements will be parsed to default values.
- assertEquals(2, message.getRepeatedInt32Count());
- assertEquals(0, message.getRepeatedInt32(0));
- assertEquals(0, message.getRepeatedInt32(1));
- assertEquals(2, message.getRepeatedInt32Count());
- assertEquals(0, message.getRepeatedInt32(0));
- assertEquals(0, message.getRepeatedInt32(1));
- assertEquals(2, message.getRepeatedInt64Count());
- assertEquals(0, message.getRepeatedInt64(0));
- assertEquals(0, message.getRepeatedInt64(1));
- assertEquals(2, message.getRepeatedUint32Count());
- assertEquals(0, message.getRepeatedUint32(0));
- assertEquals(0, message.getRepeatedUint32(1));
- assertEquals(2, message.getRepeatedUint64Count());
- assertEquals(0, message.getRepeatedUint64(0));
- assertEquals(0, message.getRepeatedUint64(1));
- assertEquals(2, message.getRepeatedSint32Count());
- assertEquals(0, message.getRepeatedSint32(0));
- assertEquals(0, message.getRepeatedSint32(1));
- assertEquals(2, message.getRepeatedSint64Count());
- assertEquals(0, message.getRepeatedSint64(0));
- assertEquals(0, message.getRepeatedSint64(1));
- assertEquals(2, message.getRepeatedFixed32Count());
- assertEquals(0, message.getRepeatedFixed32(0));
- assertEquals(0, message.getRepeatedFixed32(1));
- assertEquals(2, message.getRepeatedFixed64Count());
- assertEquals(0, message.getRepeatedFixed64(0));
- assertEquals(0, message.getRepeatedFixed64(1));
- assertEquals(2, message.getRepeatedSfixed32Count());
- assertEquals(0, message.getRepeatedSfixed32(0));
- assertEquals(0, message.getRepeatedSfixed32(1));
- assertEquals(2, message.getRepeatedSfixed64Count());
- assertEquals(0, message.getRepeatedSfixed64(0));
- assertEquals(0, message.getRepeatedSfixed64(1));
- assertEquals(2, message.getRepeatedFloatCount());
- assertEquals(0f, message.getRepeatedFloat(0));
- assertEquals(0f, message.getRepeatedFloat(1));
- assertEquals(2, message.getRepeatedDoubleCount());
- assertEquals(0.0, message.getRepeatedDouble(0));
- assertEquals(0.0, message.getRepeatedDouble(1));
- assertEquals(2, message.getRepeatedBoolCount());
- assertFalse(message.getRepeatedBool(0));
- assertFalse(message.getRepeatedBool(1));
- assertEquals(2, message.getRepeatedStringCount());
- assertTrue(message.getRepeatedString(0).isEmpty());
- assertTrue(message.getRepeatedString(1).isEmpty());
- assertEquals(2, message.getRepeatedBytesCount());
- assertTrue(message.getRepeatedBytes(0).isEmpty());
- assertTrue(message.getRepeatedBytes(1).isEmpty());
- assertEquals(2, message.getRepeatedNestedMessageCount());
- assertEquals(NestedMessage.getDefaultInstance(), message.getRepeatedNestedMessage(0));
- assertEquals(NestedMessage.getDefaultInstance(), message.getRepeatedNestedMessage(1));
- assertEquals(2, message.getRepeatedNestedEnumCount());
- assertEquals(0, message.getRepeatedNestedEnumValue(0));
- assertEquals(0, message.getRepeatedNestedEnumValue(1));
- }
-
+
+ // Repeated field elements cannot be null.
+ try {
+ builder = TestAllTypes.newBuilder();
+ mergeFromJson("{\n" + " \"repeatedInt32\": [null, null],\n" + "}", builder);
+ fail();
+ } catch (InvalidProtocolBufferException e) {
+ // Exception expected.
+ }
+
+ try {
+ builder = TestAllTypes.newBuilder();
+ mergeFromJson("{\n" + " \"repeatedNestedMessage\": [null, null],\n" + "}", builder);
+ fail();
+ } catch (InvalidProtocolBufferException e) {
+ // Exception expected.
+ }
+ }
+
+ public void testNullInOneof() throws Exception {
+ TestOneof.Builder builder = TestOneof.newBuilder();
+ mergeFromJson("{\n" + " \"oneofNullValue\": null \n" + "}", builder);
+ TestOneof message = builder.build();
+ assertEquals(TestOneof.OneofFieldCase.ONEOF_NULL_VALUE, message.getOneofFieldCase());
+ assertEquals(NullValue.NULL_VALUE, message.getOneofNullValue());
+ }
+
+ public void testParserRejectDuplicatedFields() throws Exception {
+ // TODO(xiaofeng): The parser we are currently using (GSON) will accept and keep the last
+ // one if multiple entries have the same name. This is not the desired behavior but it can
+ // only be fixed by using our own parser. Here we only test the cases where the names are
+ // different but still referring to the same field.
+
+ // Duplicated optional fields.
+ try {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ mergeFromJson(
+ "{\n"
+ + " \"optionalNestedMessage\": {},\n"
+ + " \"optional_nested_message\": {}\n"
+ + "}",
+ builder);
+ fail();
+ } catch (InvalidProtocolBufferException e) {
+ // Exception expected.
+ }
+
+ // Duplicated repeated fields.
+ try {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ mergeFromJson(
+ "{\n"
+ + " \"repeatedNestedMessage\": [null, null],\n"
+ + " \"repeated_nested_message\": [null, null]\n"
+ + "}",
+ builder);
+ fail();
+ } catch (InvalidProtocolBufferException e) {
+ // Exception expected.
+ }
+
+ // Duplicated oneof fields.
+ try {
+ TestOneof.Builder builder = TestOneof.newBuilder();
+ mergeFromJson("{\n" + " \"oneofInt32\": 1,\n" + " \"oneof_int32\": 2\n" + "}", builder);
+ fail();
+ } catch (InvalidProtocolBufferException e) {
+ // Exception expected.
+ }
+ }
+
public void testMapFields() throws Exception {
TestMap.Builder builder = TestMap.newBuilder();
- builder.getMutableInt32ToInt32Map().put(1, 10);
- builder.getMutableInt64ToInt32Map().put(1234567890123456789L, 10);
- builder.getMutableUint32ToInt32Map().put(2, 20);
- builder.getMutableUint64ToInt32Map().put(2234567890123456789L, 20);
- builder.getMutableSint32ToInt32Map().put(3, 30);
- builder.getMutableSint64ToInt32Map().put(3234567890123456789L, 30);
- builder.getMutableFixed32ToInt32Map().put(4, 40);
- builder.getMutableFixed64ToInt32Map().put(4234567890123456789L, 40);
- builder.getMutableSfixed32ToInt32Map().put(5, 50);
- builder.getMutableSfixed64ToInt32Map().put(5234567890123456789L, 50);
- builder.getMutableBoolToInt32Map().put(false, 6);
- builder.getMutableStringToInt32Map().put("Hello", 10);
-
- builder.getMutableInt32ToInt64Map().put(1, 1234567890123456789L);
- builder.getMutableInt32ToUint32Map().put(2, 20);
- builder.getMutableInt32ToUint64Map().put(2, 2234567890123456789L);
- builder.getMutableInt32ToSint32Map().put(3, 30);
- builder.getMutableInt32ToSint64Map().put(3, 3234567890123456789L);
- builder.getMutableInt32ToFixed32Map().put(4, 40);
- builder.getMutableInt32ToFixed64Map().put(4, 4234567890123456789L);
- builder.getMutableInt32ToSfixed32Map().put(5, 50);
- builder.getMutableInt32ToSfixed64Map().put(5, 5234567890123456789L);
- builder.getMutableInt32ToFloatMap().put(6, 1.5f);
- builder.getMutableInt32ToDoubleMap().put(6, 1.25);
- builder.getMutableInt32ToBoolMap().put(7, false);
- builder.getMutableInt32ToStringMap().put(7, "World");
- builder.getMutableInt32ToBytesMap().put(
- 8, ByteString.copyFrom(new byte[]{1, 2, 3}));
- builder.getMutableInt32ToMessageMap().put(
- 8, NestedMessage.newBuilder().setValue(1234).build());
- builder.getMutableInt32ToEnumMap().put(9, NestedEnum.BAR);
+ builder.putInt32ToInt32Map(1, 10);
+ builder.putInt64ToInt32Map(1234567890123456789L, 10);
+ builder.putUint32ToInt32Map(2, 20);
+ builder.putUint64ToInt32Map(2234567890123456789L, 20);
+ builder.putSint32ToInt32Map(3, 30);
+ builder.putSint64ToInt32Map(3234567890123456789L, 30);
+ builder.putFixed32ToInt32Map(4, 40);
+ builder.putFixed64ToInt32Map(4234567890123456789L, 40);
+ builder.putSfixed32ToInt32Map(5, 50);
+ builder.putSfixed64ToInt32Map(5234567890123456789L, 50);
+ builder.putBoolToInt32Map(false, 6);
+ builder.putStringToInt32Map("Hello", 10);
+
+ builder.putInt32ToInt64Map(1, 1234567890123456789L);
+ builder.putInt32ToUint32Map(2, 20);
+ builder.putInt32ToUint64Map(2, 2234567890123456789L);
+ builder.putInt32ToSint32Map(3, 30);
+ builder.putInt32ToSint64Map(3, 3234567890123456789L);
+ builder.putInt32ToFixed32Map(4, 40);
+ builder.putInt32ToFixed64Map(4, 4234567890123456789L);
+ builder.putInt32ToSfixed32Map(5, 50);
+ builder.putInt32ToSfixed64Map(5, 5234567890123456789L);
+ builder.putInt32ToFloatMap(6, 1.5f);
+ builder.putInt32ToDoubleMap(6, 1.25);
+ builder.putInt32ToBoolMap(7, false);
+ builder.putInt32ToStringMap(7, "World");
+ builder.putInt32ToBytesMap(8, ByteString.copyFrom(new byte[] {1, 2, 3}));
+ builder.putInt32ToMessageMap(8, NestedMessage.newBuilder().setValue(1234).build());
+ builder.putInt32ToEnumMap(9, NestedEnum.BAR);
TestMap message = builder.build();
-
+
assertEquals(
"{\n"
- + " \"int32ToInt32Map\": {\n"
- + " \"1\": 10\n"
- + " },\n"
- + " \"int64ToInt32Map\": {\n"
- + " \"1234567890123456789\": 10\n"
- + " },\n"
- + " \"uint32ToInt32Map\": {\n"
- + " \"2\": 20\n"
- + " },\n"
- + " \"uint64ToInt32Map\": {\n"
- + " \"2234567890123456789\": 20\n"
- + " },\n"
- + " \"sint32ToInt32Map\": {\n"
- + " \"3\": 30\n"
- + " },\n"
- + " \"sint64ToInt32Map\": {\n"
- + " \"3234567890123456789\": 30\n"
- + " },\n"
- + " \"fixed32ToInt32Map\": {\n"
- + " \"4\": 40\n"
- + " },\n"
- + " \"fixed64ToInt32Map\": {\n"
- + " \"4234567890123456789\": 40\n"
- + " },\n"
- + " \"sfixed32ToInt32Map\": {\n"
- + " \"5\": 50\n"
- + " },\n"
- + " \"sfixed64ToInt32Map\": {\n"
- + " \"5234567890123456789\": 50\n"
- + " },\n"
- + " \"boolToInt32Map\": {\n"
- + " \"false\": 6\n"
- + " },\n"
- + " \"stringToInt32Map\": {\n"
- + " \"Hello\": 10\n"
- + " },\n"
- + " \"int32ToInt64Map\": {\n"
- + " \"1\": \"1234567890123456789\"\n"
- + " },\n"
- + " \"int32ToUint32Map\": {\n"
- + " \"2\": 20\n"
- + " },\n"
- + " \"int32ToUint64Map\": {\n"
- + " \"2\": \"2234567890123456789\"\n"
- + " },\n"
- + " \"int32ToSint32Map\": {\n"
- + " \"3\": 30\n"
- + " },\n"
- + " \"int32ToSint64Map\": {\n"
- + " \"3\": \"3234567890123456789\"\n"
- + " },\n"
- + " \"int32ToFixed32Map\": {\n"
- + " \"4\": 40\n"
- + " },\n"
- + " \"int32ToFixed64Map\": {\n"
- + " \"4\": \"4234567890123456789\"\n"
- + " },\n"
- + " \"int32ToSfixed32Map\": {\n"
- + " \"5\": 50\n"
- + " },\n"
- + " \"int32ToSfixed64Map\": {\n"
- + " \"5\": \"5234567890123456789\"\n"
- + " },\n"
- + " \"int32ToFloatMap\": {\n"
- + " \"6\": 1.5\n"
- + " },\n"
- + " \"int32ToDoubleMap\": {\n"
- + " \"6\": 1.25\n"
- + " },\n"
- + " \"int32ToBoolMap\": {\n"
- + " \"7\": false\n"
- + " },\n"
- + " \"int32ToStringMap\": {\n"
- + " \"7\": \"World\"\n"
- + " },\n"
- + " \"int32ToBytesMap\": {\n"
- + " \"8\": \"AQID\"\n"
- + " },\n"
- + " \"int32ToMessageMap\": {\n"
- + " \"8\": {\n"
- + " \"value\": 1234\n"
- + " }\n"
- + " },\n"
- + " \"int32ToEnumMap\": {\n"
- + " \"9\": \"BAR\"\n"
- + " }\n"
- + "}", toJsonString(message));
+ + " \"int32ToInt32Map\": {\n"
+ + " \"1\": 10\n"
+ + " },\n"
+ + " \"int64ToInt32Map\": {\n"
+ + " \"1234567890123456789\": 10\n"
+ + " },\n"
+ + " \"uint32ToInt32Map\": {\n"
+ + " \"2\": 20\n"
+ + " },\n"
+ + " \"uint64ToInt32Map\": {\n"
+ + " \"2234567890123456789\": 20\n"
+ + " },\n"
+ + " \"sint32ToInt32Map\": {\n"
+ + " \"3\": 30\n"
+ + " },\n"
+ + " \"sint64ToInt32Map\": {\n"
+ + " \"3234567890123456789\": 30\n"
+ + " },\n"
+ + " \"fixed32ToInt32Map\": {\n"
+ + " \"4\": 40\n"
+ + " },\n"
+ + " \"fixed64ToInt32Map\": {\n"
+ + " \"4234567890123456789\": 40\n"
+ + " },\n"
+ + " \"sfixed32ToInt32Map\": {\n"
+ + " \"5\": 50\n"
+ + " },\n"
+ + " \"sfixed64ToInt32Map\": {\n"
+ + " \"5234567890123456789\": 50\n"
+ + " },\n"
+ + " \"boolToInt32Map\": {\n"
+ + " \"false\": 6\n"
+ + " },\n"
+ + " \"stringToInt32Map\": {\n"
+ + " \"Hello\": 10\n"
+ + " },\n"
+ + " \"int32ToInt64Map\": {\n"
+ + " \"1\": \"1234567890123456789\"\n"
+ + " },\n"
+ + " \"int32ToUint32Map\": {\n"
+ + " \"2\": 20\n"
+ + " },\n"
+ + " \"int32ToUint64Map\": {\n"
+ + " \"2\": \"2234567890123456789\"\n"
+ + " },\n"
+ + " \"int32ToSint32Map\": {\n"
+ + " \"3\": 30\n"
+ + " },\n"
+ + " \"int32ToSint64Map\": {\n"
+ + " \"3\": \"3234567890123456789\"\n"
+ + " },\n"
+ + " \"int32ToFixed32Map\": {\n"
+ + " \"4\": 40\n"
+ + " },\n"
+ + " \"int32ToFixed64Map\": {\n"
+ + " \"4\": \"4234567890123456789\"\n"
+ + " },\n"
+ + " \"int32ToSfixed32Map\": {\n"
+ + " \"5\": 50\n"
+ + " },\n"
+ + " \"int32ToSfixed64Map\": {\n"
+ + " \"5\": \"5234567890123456789\"\n"
+ + " },\n"
+ + " \"int32ToFloatMap\": {\n"
+ + " \"6\": 1.5\n"
+ + " },\n"
+ + " \"int32ToDoubleMap\": {\n"
+ + " \"6\": 1.25\n"
+ + " },\n"
+ + " \"int32ToBoolMap\": {\n"
+ + " \"7\": false\n"
+ + " },\n"
+ + " \"int32ToStringMap\": {\n"
+ + " \"7\": \"World\"\n"
+ + " },\n"
+ + " \"int32ToBytesMap\": {\n"
+ + " \"8\": \"AQID\"\n"
+ + " },\n"
+ + " \"int32ToMessageMap\": {\n"
+ + " \"8\": {\n"
+ + " \"value\": 1234\n"
+ + " }\n"
+ + " },\n"
+ + " \"int32ToEnumMap\": {\n"
+ + " \"9\": \"BAR\"\n"
+ + " }\n"
+ + "}",
+ toJsonString(message));
assertRoundTripEquals(message);
-
+
// Test multiple entries.
builder = TestMap.newBuilder();
- builder.getMutableInt32ToInt32Map().put(1, 2);
- builder.getMutableInt32ToInt32Map().put(3, 4);
+ builder.putInt32ToInt32Map(1, 2);
+ builder.putInt32ToInt32Map(3, 4);
message = builder.build();
-
+
assertEquals(
- "{\n"
- + " \"int32ToInt32Map\": {\n"
- + " \"1\": 2,\n"
- + " \"3\": 4\n"
- + " }\n"
- + "}", toJsonString(message));
+ "{\n" + " \"int32ToInt32Map\": {\n" + " \"1\": 2,\n" + " \"3\": 4\n" + " }\n" + "}",
+ toJsonString(message));
assertRoundTripEquals(message);
}
-
- public void testMapNullValueIsDefault() throws Exception {
- TestMap.Builder builder = TestMap.newBuilder();
- mergeFromJson(
- "{\n"
- + " \"int32ToInt32Map\": {\"1\": null},\n"
- + " \"int32ToMessageMap\": {\"2\": null}\n"
- + "}", builder);
- TestMap message = builder.build();
- assertTrue(message.getInt32ToInt32Map().containsKey(1));
- assertEquals(0, message.getInt32ToInt32Map().get(1).intValue());
- assertTrue(message.getInt32ToMessageMap().containsKey(2));
- assertEquals(0, message.getInt32ToMessageMap().get(2).getValue());
+
+ public void testMapNullValueIsRejected() throws Exception {
+ try {
+ TestMap.Builder builder = TestMap.newBuilder();
+ mergeFromJson(
+ "{\n"
+ + " \"int32ToInt32Map\": {null: 1},\n"
+ + " \"int32ToMessageMap\": {null: 2}\n"
+ + "}",
+ builder);
+ fail();
+ } catch (InvalidProtocolBufferException e) {
+ // Exception expected.
+ }
+
+ try {
+ TestMap.Builder builder = TestMap.newBuilder();
+ mergeFromJson(
+ "{\n"
+ + " \"int32ToInt32Map\": {\"1\": null},\n"
+ + " \"int32ToMessageMap\": {\"2\": null}\n"
+ + "}",
+ builder);
+ fail();
+ } catch (InvalidProtocolBufferException e) {
+ // Exception expected.
+ }
}
-
+
public void testParserAcceptNonQuotedObjectKey() throws Exception {
TestMap.Builder builder = TestMap.newBuilder();
mergeFromJson(
- "{\n"
- + " int32ToInt32Map: {1: 2},\n"
- + " stringToInt32Map: {hello: 3}\n"
- + "}", builder);
+ "{\n" + " int32ToInt32Map: {1: 2},\n" + " stringToInt32Map: {hello: 3}\n" + "}", builder);
TestMap message = builder.build();
assertEquals(2, message.getInt32ToInt32Map().get(1).intValue());
assertEquals(3, message.getStringToInt32Map().get("hello").intValue());
}
-
+
public void testWrappers() throws Exception {
TestWrappers.Builder builder = TestWrappers.newBuilder();
builder.getBoolValueBuilder().setValue(false);
@@ -630,19 +671,20 @@ public class JsonFormatTest extends TestCase {
builder.getStringValueBuilder().setValue("");
builder.getBytesValueBuilder().setValue(ByteString.EMPTY);
TestWrappers message = builder.build();
-
+
assertEquals(
"{\n"
- + " \"int32Value\": 0,\n"
- + " \"uint32Value\": 0,\n"
- + " \"int64Value\": \"0\",\n"
- + " \"uint64Value\": \"0\",\n"
- + " \"floatValue\": 0.0,\n"
- + " \"doubleValue\": 0.0,\n"
- + " \"boolValue\": false,\n"
- + " \"stringValue\": \"\",\n"
- + " \"bytesValue\": \"\"\n"
- + "}", toJsonString(message));
+ + " \"int32Value\": 0,\n"
+ + " \"uint32Value\": 0,\n"
+ + " \"int64Value\": \"0\",\n"
+ + " \"uint64Value\": \"0\",\n"
+ + " \"floatValue\": 0.0,\n"
+ + " \"doubleValue\": 0.0,\n"
+ + " \"boolValue\": false,\n"
+ + " \"stringValue\": \"\",\n"
+ + " \"bytesValue\": \"\"\n"
+ + "}",
+ toJsonString(message));
assertRoundTripEquals(message);
builder = TestWrappers.newBuilder();
@@ -654,101 +696,107 @@ public class JsonFormatTest extends TestCase {
builder.getFloatValueBuilder().setValue(5.0f);
builder.getDoubleValueBuilder().setValue(6.0);
builder.getStringValueBuilder().setValue("7");
- builder.getBytesValueBuilder().setValue(ByteString.copyFrom(new byte[]{8}));
+ builder.getBytesValueBuilder().setValue(ByteString.copyFrom(new byte[] {8}));
message = builder.build();
-
+
assertEquals(
"{\n"
- + " \"int32Value\": 1,\n"
- + " \"uint32Value\": 3,\n"
- + " \"int64Value\": \"2\",\n"
- + " \"uint64Value\": \"4\",\n"
- + " \"floatValue\": 5.0,\n"
- + " \"doubleValue\": 6.0,\n"
- + " \"boolValue\": true,\n"
- + " \"stringValue\": \"7\",\n"
- + " \"bytesValue\": \"CA==\"\n"
- + "}", toJsonString(message));
+ + " \"int32Value\": 1,\n"
+ + " \"uint32Value\": 3,\n"
+ + " \"int64Value\": \"2\",\n"
+ + " \"uint64Value\": \"4\",\n"
+ + " \"floatValue\": 5.0,\n"
+ + " \"doubleValue\": 6.0,\n"
+ + " \"boolValue\": true,\n"
+ + " \"stringValue\": \"7\",\n"
+ + " \"bytesValue\": \"CA==\"\n"
+ + "}",
+ toJsonString(message));
assertRoundTripEquals(message);
}
-
+
public void testTimestamp() throws Exception {
- TestTimestamp message = TestTimestamp.newBuilder()
- .setTimestampValue(TimeUtil.parseTimestamp("1970-01-01T00:00:00Z"))
- .build();
-
+ TestTimestamp message =
+ TestTimestamp.newBuilder()
+ .setTimestampValue(Timestamps.parse("1970-01-01T00:00:00Z"))
+ .build();
+
assertEquals(
- "{\n"
- + " \"timestampValue\": \"1970-01-01T00:00:00Z\"\n"
- + "}", toJsonString(message));
+ "{\n" + " \"timestampValue\": \"1970-01-01T00:00:00Z\"\n" + "}", toJsonString(message));
assertRoundTripEquals(message);
}
-
+
public void testDuration() throws Exception {
- TestDuration message = TestDuration.newBuilder()
- .setDurationValue(TimeUtil.parseDuration("12345s"))
- .build();
-
- assertEquals(
- "{\n"
- + " \"durationValue\": \"12345s\"\n"
- + "}", toJsonString(message));
+ TestDuration message =
+ TestDuration.newBuilder().setDurationValue(Durations.parse("12345s")).build();
+
+ assertEquals("{\n" + " \"durationValue\": \"12345s\"\n" + "}", toJsonString(message));
assertRoundTripEquals(message);
}
-
+
public void testFieldMask() throws Exception {
- TestFieldMask message = TestFieldMask.newBuilder()
- .setFieldMaskValue(FieldMaskUtil.fromString("foo.bar,baz"))
- .build();
-
+ TestFieldMask message =
+ TestFieldMask.newBuilder()
+ .setFieldMaskValue(FieldMaskUtil.fromString("foo.bar,baz,foo_bar.baz"))
+ .build();
+
assertEquals(
- "{\n"
- + " \"fieldMaskValue\": \"foo.bar,baz\"\n"
- + "}", toJsonString(message));
+ "{\n" + " \"fieldMaskValue\": \"foo.bar,baz,fooBar.baz\"\n" + "}", toJsonString(message));
assertRoundTripEquals(message);
}
-
+
public void testStruct() throws Exception {
// Build a struct with all possible values.
TestStruct.Builder builder = TestStruct.newBuilder();
Struct.Builder structBuilder = builder.getStructValueBuilder();
- structBuilder.getMutableFields().put(
- "null_value", Value.newBuilder().setNullValueValue(0).build());
- structBuilder.getMutableFields().put(
- "number_value", Value.newBuilder().setNumberValue(1.25).build());
- structBuilder.getMutableFields().put(
- "string_value", Value.newBuilder().setStringValue("hello").build());
+ structBuilder.putFields("null_value", Value.newBuilder().setNullValueValue(0).build());
+ structBuilder.putFields("number_value", Value.newBuilder().setNumberValue(1.25).build());
+ structBuilder.putFields("string_value", Value.newBuilder().setStringValue("hello").build());
Struct.Builder subStructBuilder = Struct.newBuilder();
- subStructBuilder.getMutableFields().put(
- "number_value", Value.newBuilder().setNumberValue(1234).build());
- structBuilder.getMutableFields().put(
+ subStructBuilder.putFields("number_value", Value.newBuilder().setNumberValue(1234).build());
+ structBuilder.putFields(
"struct_value", Value.newBuilder().setStructValue(subStructBuilder.build()).build());
ListValue.Builder listBuilder = ListValue.newBuilder();
listBuilder.addValues(Value.newBuilder().setNumberValue(1.125).build());
listBuilder.addValues(Value.newBuilder().setNullValueValue(0).build());
- structBuilder.getMutableFields().put(
+ structBuilder.putFields(
"list_value", Value.newBuilder().setListValue(listBuilder.build()).build());
TestStruct message = builder.build();
-
+
assertEquals(
"{\n"
- + " \"structValue\": {\n"
- + " \"null_value\": null,\n"
- + " \"number_value\": 1.25,\n"
- + " \"string_value\": \"hello\",\n"
- + " \"struct_value\": {\n"
- + " \"number_value\": 1234.0\n"
- + " },\n"
- + " \"list_value\": [1.125, null]\n"
- + " }\n"
- + "}", toJsonString(message));
+ + " \"structValue\": {\n"
+ + " \"null_value\": null,\n"
+ + " \"number_value\": 1.25,\n"
+ + " \"string_value\": \"hello\",\n"
+ + " \"struct_value\": {\n"
+ + " \"number_value\": 1234.0\n"
+ + " },\n"
+ + " \"list_value\": [1.125, null]\n"
+ + " }\n"
+ + "}",
+ toJsonString(message));
+ assertRoundTripEquals(message);
+
+ builder = TestStruct.newBuilder();
+ builder.setValue(Value.newBuilder().setNullValueValue(0).build());
+ message = builder.build();
+ assertEquals("{\n" + " \"value\": null\n" + "}", toJsonString(message));
+ assertRoundTripEquals(message);
+
+ builder = TestStruct.newBuilder();
+ listBuilder = builder.getListValueBuilder();
+ listBuilder.addValues(Value.newBuilder().setNumberValue(31831.125).build());
+ listBuilder.addValues(Value.newBuilder().setNullValueValue(0).build());
+ message = builder.build();
+ assertEquals("{\n" + " \"listValue\": [31831.125, null]\n" + "}", toJsonString(message));
assertRoundTripEquals(message);
}
-
+
public void testAnyFields() throws Exception {
TestAllTypes content = TestAllTypes.newBuilder().setOptionalInt32(1234).build();
TestAny message = TestAny.newBuilder().setAnyValue(Any.pack(content)).build();
-
+
// A TypeRegistry must be provided in order to convert Any types.
try {
toJsonString(message);
@@ -756,177 +804,195 @@ public class JsonFormatTest extends TestCase {
} catch (IOException e) {
// Expected.
}
-
- JsonFormat.TypeRegistry registry = JsonFormat.TypeRegistry.newBuilder()
- .add(TestAllTypes.getDescriptor()).build();
+
+ JsonFormat.TypeRegistry registry =
+ JsonFormat.TypeRegistry.newBuilder().add(TestAllTypes.getDescriptor()).build();
JsonFormat.Printer printer = JsonFormat.printer().usingTypeRegistry(registry);
-
+
assertEquals(
"{\n"
- + " \"anyValue\": {\n"
- + " \"@type\": \"type.googleapis.com/json_test.TestAllTypes\",\n"
- + " \"optionalInt32\": 1234\n"
- + " }\n"
- + "}" , printer.print(message));
+ + " \"anyValue\": {\n"
+ + " \"@type\": \"type.googleapis.com/json_test.TestAllTypes\",\n"
+ + " \"optionalInt32\": 1234\n"
+ + " }\n"
+ + "}",
+ printer.print(message));
assertRoundTripEquals(message, registry);
-
-
+
// Well-known types have a special formatting when embedded in Any.
//
// 1. Any in Any.
Any anyMessage = Any.pack(Any.pack(content));
assertEquals(
"{\n"
- + " \"@type\": \"type.googleapis.com/google.protobuf.Any\",\n"
- + " \"value\": {\n"
- + " \"@type\": \"type.googleapis.com/json_test.TestAllTypes\",\n"
- + " \"optionalInt32\": 1234\n"
- + " }\n"
- + "}", printer.print(anyMessage));
+ + " \"@type\": \"type.googleapis.com/google.protobuf.Any\",\n"
+ + " \"value\": {\n"
+ + " \"@type\": \"type.googleapis.com/json_test.TestAllTypes\",\n"
+ + " \"optionalInt32\": 1234\n"
+ + " }\n"
+ + "}",
+ printer.print(anyMessage));
assertRoundTripEquals(anyMessage, registry);
-
+
// 2. Wrappers in Any.
anyMessage = Any.pack(Int32Value.newBuilder().setValue(12345).build());
assertEquals(
"{\n"
- + " \"@type\": \"type.googleapis.com/google.protobuf.Int32Value\",\n"
- + " \"value\": 12345\n"
- + "}", printer.print(anyMessage));
+ + " \"@type\": \"type.googleapis.com/google.protobuf.Int32Value\",\n"
+ + " \"value\": 12345\n"
+ + "}",
+ printer.print(anyMessage));
assertRoundTripEquals(anyMessage, registry);
anyMessage = Any.pack(UInt32Value.newBuilder().setValue(12345).build());
assertEquals(
"{\n"
- + " \"@type\": \"type.googleapis.com/google.protobuf.UInt32Value\",\n"
- + " \"value\": 12345\n"
- + "}", printer.print(anyMessage));
+ + " \"@type\": \"type.googleapis.com/google.protobuf.UInt32Value\",\n"
+ + " \"value\": 12345\n"
+ + "}",
+ printer.print(anyMessage));
assertRoundTripEquals(anyMessage, registry);
anyMessage = Any.pack(Int64Value.newBuilder().setValue(12345).build());
assertEquals(
"{\n"
- + " \"@type\": \"type.googleapis.com/google.protobuf.Int64Value\",\n"
- + " \"value\": \"12345\"\n"
- + "}", printer.print(anyMessage));
+ + " \"@type\": \"type.googleapis.com/google.protobuf.Int64Value\",\n"
+ + " \"value\": \"12345\"\n"
+ + "}",
+ printer.print(anyMessage));
assertRoundTripEquals(anyMessage, registry);
anyMessage = Any.pack(UInt64Value.newBuilder().setValue(12345).build());
assertEquals(
"{\n"
- + " \"@type\": \"type.googleapis.com/google.protobuf.UInt64Value\",\n"
- + " \"value\": \"12345\"\n"
- + "}", printer.print(anyMessage));
+ + " \"@type\": \"type.googleapis.com/google.protobuf.UInt64Value\",\n"
+ + " \"value\": \"12345\"\n"
+ + "}",
+ printer.print(anyMessage));
assertRoundTripEquals(anyMessage, registry);
anyMessage = Any.pack(FloatValue.newBuilder().setValue(12345).build());
assertEquals(
"{\n"
- + " \"@type\": \"type.googleapis.com/google.protobuf.FloatValue\",\n"
- + " \"value\": 12345.0\n"
- + "}", printer.print(anyMessage));
+ + " \"@type\": \"type.googleapis.com/google.protobuf.FloatValue\",\n"
+ + " \"value\": 12345.0\n"
+ + "}",
+ printer.print(anyMessage));
assertRoundTripEquals(anyMessage, registry);
anyMessage = Any.pack(DoubleValue.newBuilder().setValue(12345).build());
assertEquals(
"{\n"
- + " \"@type\": \"type.googleapis.com/google.protobuf.DoubleValue\",\n"
- + " \"value\": 12345.0\n"
- + "}", printer.print(anyMessage));
+ + " \"@type\": \"type.googleapis.com/google.protobuf.DoubleValue\",\n"
+ + " \"value\": 12345.0\n"
+ + "}",
+ printer.print(anyMessage));
assertRoundTripEquals(anyMessage, registry);
anyMessage = Any.pack(BoolValue.newBuilder().setValue(true).build());
assertEquals(
"{\n"
- + " \"@type\": \"type.googleapis.com/google.protobuf.BoolValue\",\n"
- + " \"value\": true\n"
- + "}", printer.print(anyMessage));
+ + " \"@type\": \"type.googleapis.com/google.protobuf.BoolValue\",\n"
+ + " \"value\": true\n"
+ + "}",
+ printer.print(anyMessage));
assertRoundTripEquals(anyMessage, registry);
anyMessage = Any.pack(StringValue.newBuilder().setValue("Hello").build());
assertEquals(
"{\n"
- + " \"@type\": \"type.googleapis.com/google.protobuf.StringValue\",\n"
- + " \"value\": \"Hello\"\n"
- + "}", printer.print(anyMessage));
+ + " \"@type\": \"type.googleapis.com/google.protobuf.StringValue\",\n"
+ + " \"value\": \"Hello\"\n"
+ + "}",
+ printer.print(anyMessage));
assertRoundTripEquals(anyMessage, registry);
- anyMessage = Any.pack(BytesValue.newBuilder().setValue(
- ByteString.copyFrom(new byte[]{1, 2})).build());
+ anyMessage =
+ Any.pack(BytesValue.newBuilder().setValue(ByteString.copyFrom(new byte[] {1, 2})).build());
assertEquals(
"{\n"
- + " \"@type\": \"type.googleapis.com/google.protobuf.BytesValue\",\n"
- + " \"value\": \"AQI=\"\n"
- + "}", printer.print(anyMessage));
+ + " \"@type\": \"type.googleapis.com/google.protobuf.BytesValue\",\n"
+ + " \"value\": \"AQI=\"\n"
+ + "}",
+ printer.print(anyMessage));
assertRoundTripEquals(anyMessage, registry);
-
+
// 3. Timestamp in Any.
- anyMessage = Any.pack(TimeUtil.parseTimestamp("1969-12-31T23:59:59Z"));
+ anyMessage = Any.pack(Timestamps.parse("1969-12-31T23:59:59Z"));
assertEquals(
"{\n"
- + " \"@type\": \"type.googleapis.com/google.protobuf.Timestamp\",\n"
- + " \"value\": \"1969-12-31T23:59:59Z\"\n"
- + "}", printer.print(anyMessage));
+ + " \"@type\": \"type.googleapis.com/google.protobuf.Timestamp\",\n"
+ + " \"value\": \"1969-12-31T23:59:59Z\"\n"
+ + "}",
+ printer.print(anyMessage));
assertRoundTripEquals(anyMessage, registry);
-
+
// 4. Duration in Any
- anyMessage = Any.pack(TimeUtil.parseDuration("12345.10s"));
+ anyMessage = Any.pack(Durations.parse("12345.10s"));
assertEquals(
"{\n"
- + " \"@type\": \"type.googleapis.com/google.protobuf.Duration\",\n"
- + " \"value\": \"12345.100s\"\n"
- + "}", printer.print(anyMessage));
+ + " \"@type\": \"type.googleapis.com/google.protobuf.Duration\",\n"
+ + " \"value\": \"12345.100s\"\n"
+ + "}",
+ printer.print(anyMessage));
assertRoundTripEquals(anyMessage, registry);
// 5. FieldMask in Any
anyMessage = Any.pack(FieldMaskUtil.fromString("foo.bar,baz"));
assertEquals(
"{\n"
- + " \"@type\": \"type.googleapis.com/google.protobuf.FieldMask\",\n"
- + " \"value\": \"foo.bar,baz\"\n"
- + "}", printer.print(anyMessage));
+ + " \"@type\": \"type.googleapis.com/google.protobuf.FieldMask\",\n"
+ + " \"value\": \"foo.bar,baz\"\n"
+ + "}",
+ printer.print(anyMessage));
assertRoundTripEquals(anyMessage, registry);
// 6. Struct in Any
Struct.Builder structBuilder = Struct.newBuilder();
- structBuilder.getMutableFields().put(
- "number", Value.newBuilder().setNumberValue(1.125).build());
+ structBuilder.putFields("number", Value.newBuilder().setNumberValue(1.125).build());
anyMessage = Any.pack(structBuilder.build());
assertEquals(
"{\n"
- + " \"@type\": \"type.googleapis.com/google.protobuf.Struct\",\n"
- + " \"value\": {\n"
- + " \"number\": 1.125\n"
- + " }\n"
- + "}", printer.print(anyMessage));
+ + " \"@type\": \"type.googleapis.com/google.protobuf.Struct\",\n"
+ + " \"value\": {\n"
+ + " \"number\": 1.125\n"
+ + " }\n"
+ + "}",
+ printer.print(anyMessage));
+ assertRoundTripEquals(anyMessage, registry);
+ Value.Builder valueBuilder = Value.newBuilder();
+ valueBuilder.setNumberValue(1);
+ anyMessage = Any.pack(valueBuilder.build());
+ assertEquals(
+ "{\n"
+ + " \"@type\": \"type.googleapis.com/google.protobuf.Value\",\n"
+ + " \"value\": 1.0\n"
+ + "}",
+ printer.print(anyMessage));
assertRoundTripEquals(anyMessage, registry);
}
-
+
public void testParserMissingTypeUrl() throws Exception {
try {
Any.Builder builder = Any.newBuilder();
- mergeFromJson(
- "{\n"
- + " \"optionalInt32\": 1234\n"
- + "}", builder);
+ mergeFromJson("{\n" + " \"optionalInt32\": 1234\n" + "}", builder);
fail("Exception is expected.");
} catch (IOException e) {
// Expected.
}
}
-
+
public void testParserUnexpectedTypeUrl() throws Exception {
try {
TestAllTypes.Builder builder = TestAllTypes.newBuilder();
mergeFromJson(
"{\n"
- + " \"@type\": \"type.googleapis.com/json_test.TestAllTypes\",\n"
- + " \"optionalInt32\": 12345\n"
- + "}", builder);
+ + " \"@type\": \"type.googleapis.com/json_test.TestAllTypes\",\n"
+ + " \"optionalInt32\": 12345\n"
+ + "}",
+ builder);
fail("Exception is expected.");
} catch (IOException e) {
// Expected.
- }
+ }
}
-
+
public void testParserRejectTrailingComma() throws Exception {
try {
TestAllTypes.Builder builder = TestAllTypes.newBuilder();
- mergeFromJson(
- "{\n"
- + " \"optionalInt32\": 12345,\n"
- + "}", builder);
+ mergeFromJson("{\n" + " \"optionalInt32\": 12345,\n" + "}", builder);
fail("Exception is expected.");
} catch (IOException e) {
// Expected.
@@ -947,30 +1013,233 @@ public class JsonFormatTest extends TestCase {
// // Expected.
// }
}
-
+
public void testParserRejectInvalidBase64() throws Exception {
- try {
- TestAllTypes.Builder builder = TestAllTypes.newBuilder();
- mergeFromJson(
- "{\n"
- + " \"optionalBytes\": \"!@#$\"\n"
- + "}", builder);
- fail("Exception is expected.");
- } catch (InvalidProtocolBufferException e) {
- // Expected.
- }
+ assertRejects("optionalBytes", "!@#$");
+ // We use standard BASE64 with paddings.
+ assertRejects("optionalBytes", "AQI");
}
-
+
public void testParserRejectInvalidEnumValue() throws Exception {
try {
TestAllTypes.Builder builder = TestAllTypes.newBuilder();
- mergeFromJson(
- "{\n"
- + " \"optionalNestedEnum\": \"XXX\"\n"
- + "}", builder);
+ mergeFromJson("{\n" + " \"optionalNestedEnum\": \"XXX\"\n" + "}", builder);
fail("Exception is expected.");
} catch (InvalidProtocolBufferException e) {
// Expected.
- }
+ }
+ }
+
+ public void testCustomJsonName() throws Exception {
+ TestCustomJsonName message = TestCustomJsonName.newBuilder().setValue(12345).build();
+ assertEquals("{\n" + " \"@value\": 12345\n" + "}", JsonFormat.printer().print(message));
+ assertRoundTripEquals(message);
+ }
+
+ public void testDefaultGsonDoesNotHtmlEscape() throws Exception {
+ TestAllTypes message = TestAllTypes.newBuilder().setOptionalString("=").build();
+ assertEquals(
+ "{\n" + " \"optionalString\": \"=\"" + "\n}", JsonFormat.printer().print(message));
+ }
+
+ public void testIncludingDefaultValueFields() throws Exception {
+ TestAllTypes message = TestAllTypes.getDefaultInstance();
+ assertEquals("{\n}", JsonFormat.printer().print(message));
+ assertEquals(
+ "{\n"
+ + " \"optionalInt32\": 0,\n"
+ + " \"optionalInt64\": \"0\",\n"
+ + " \"optionalUint32\": 0,\n"
+ + " \"optionalUint64\": \"0\",\n"
+ + " \"optionalSint32\": 0,\n"
+ + " \"optionalSint64\": \"0\",\n"
+ + " \"optionalFixed32\": 0,\n"
+ + " \"optionalFixed64\": \"0\",\n"
+ + " \"optionalSfixed32\": 0,\n"
+ + " \"optionalSfixed64\": \"0\",\n"
+ + " \"optionalFloat\": 0.0,\n"
+ + " \"optionalDouble\": 0.0,\n"
+ + " \"optionalBool\": false,\n"
+ + " \"optionalString\": \"\",\n"
+ + " \"optionalBytes\": \"\",\n"
+ + " \"optionalNestedEnum\": \"FOO\",\n"
+ + " \"repeatedInt32\": [],\n"
+ + " \"repeatedInt64\": [],\n"
+ + " \"repeatedUint32\": [],\n"
+ + " \"repeatedUint64\": [],\n"
+ + " \"repeatedSint32\": [],\n"
+ + " \"repeatedSint64\": [],\n"
+ + " \"repeatedFixed32\": [],\n"
+ + " \"repeatedFixed64\": [],\n"
+ + " \"repeatedSfixed32\": [],\n"
+ + " \"repeatedSfixed64\": [],\n"
+ + " \"repeatedFloat\": [],\n"
+ + " \"repeatedDouble\": [],\n"
+ + " \"repeatedBool\": [],\n"
+ + " \"repeatedString\": [],\n"
+ + " \"repeatedBytes\": [],\n"
+ + " \"repeatedNestedMessage\": [],\n"
+ + " \"repeatedNestedEnum\": []\n"
+ + "}",
+ JsonFormat.printer().includingDefaultValueFields().print(message));
+
+ TestMap mapMessage = TestMap.getDefaultInstance();
+ assertEquals("{\n}", JsonFormat.printer().print(mapMessage));
+ assertEquals(
+ "{\n"
+ + " \"int32ToInt32Map\": {\n"
+ + " },\n"
+ + " \"int64ToInt32Map\": {\n"
+ + " },\n"
+ + " \"uint32ToInt32Map\": {\n"
+ + " },\n"
+ + " \"uint64ToInt32Map\": {\n"
+ + " },\n"
+ + " \"sint32ToInt32Map\": {\n"
+ + " },\n"
+ + " \"sint64ToInt32Map\": {\n"
+ + " },\n"
+ + " \"fixed32ToInt32Map\": {\n"
+ + " },\n"
+ + " \"fixed64ToInt32Map\": {\n"
+ + " },\n"
+ + " \"sfixed32ToInt32Map\": {\n"
+ + " },\n"
+ + " \"sfixed64ToInt32Map\": {\n"
+ + " },\n"
+ + " \"boolToInt32Map\": {\n"
+ + " },\n"
+ + " \"stringToInt32Map\": {\n"
+ + " },\n"
+ + " \"int32ToInt64Map\": {\n"
+ + " },\n"
+ + " \"int32ToUint32Map\": {\n"
+ + " },\n"
+ + " \"int32ToUint64Map\": {\n"
+ + " },\n"
+ + " \"int32ToSint32Map\": {\n"
+ + " },\n"
+ + " \"int32ToSint64Map\": {\n"
+ + " },\n"
+ + " \"int32ToFixed32Map\": {\n"
+ + " },\n"
+ + " \"int32ToFixed64Map\": {\n"
+ + " },\n"
+ + " \"int32ToSfixed32Map\": {\n"
+ + " },\n"
+ + " \"int32ToSfixed64Map\": {\n"
+ + " },\n"
+ + " \"int32ToFloatMap\": {\n"
+ + " },\n"
+ + " \"int32ToDoubleMap\": {\n"
+ + " },\n"
+ + " \"int32ToBoolMap\": {\n"
+ + " },\n"
+ + " \"int32ToStringMap\": {\n"
+ + " },\n"
+ + " \"int32ToBytesMap\": {\n"
+ + " },\n"
+ + " \"int32ToMessageMap\": {\n"
+ + " },\n"
+ + " \"int32ToEnumMap\": {\n"
+ + " }\n"
+ + "}",
+ JsonFormat.printer().includingDefaultValueFields().print(mapMessage));
+ }
+
+ public void testPreservingProtoFieldNames() throws Exception {
+ TestAllTypes message = TestAllTypes.newBuilder().setOptionalInt32(12345).build();
+ assertEquals("{\n" + " \"optionalInt32\": 12345\n" + "}", JsonFormat.printer().print(message));
+ assertEquals(
+ "{\n" + " \"optional_int32\": 12345\n" + "}",
+ JsonFormat.printer().preservingProtoFieldNames().print(message));
+
+ // The json_name field option is ignored when configured to use original proto field names.
+ TestCustomJsonName messageWithCustomJsonName =
+ TestCustomJsonName.newBuilder().setValue(12345).build();
+ assertEquals(
+ "{\n" + " \"value\": 12345\n" + "}",
+ JsonFormat.printer().preservingProtoFieldNames().print(messageWithCustomJsonName));
+
+ // Parsers accept both original proto field names and lowerCamelCase names.
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ JsonFormat.parser().merge("{\"optionalInt32\": 12345}", builder);
+ assertEquals(12345, builder.getOptionalInt32());
+ builder.clear();
+ JsonFormat.parser().merge("{\"optional_int32\": 54321}", builder);
+ assertEquals(54321, builder.getOptionalInt32());
+ }
+
+ public void testOmittingInsignificantWhiteSpace() throws Exception {
+ TestAllTypes message = TestAllTypes.newBuilder().setOptionalInt32(12345).build();
+ assertEquals(
+ "{" + "\"optionalInt32\":12345" + "}",
+ JsonFormat.printer().omittingInsignificantWhitespace().print(message));
+ TestAllTypes message1 = TestAllTypes.getDefaultInstance();
+ assertEquals("{}", JsonFormat.printer().omittingInsignificantWhitespace().print(message1));
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ setAllFields(builder);
+ TestAllTypes message2 = builder.build();
+ assertEquals(
+ "{"
+ + "\"optionalInt32\":1234,"
+ + "\"optionalInt64\":\"1234567890123456789\","
+ + "\"optionalUint32\":5678,"
+ + "\"optionalUint64\":\"2345678901234567890\","
+ + "\"optionalSint32\":9012,"
+ + "\"optionalSint64\":\"3456789012345678901\","
+ + "\"optionalFixed32\":3456,"
+ + "\"optionalFixed64\":\"4567890123456789012\","
+ + "\"optionalSfixed32\":7890,"
+ + "\"optionalSfixed64\":\"5678901234567890123\","
+ + "\"optionalFloat\":1.5,"
+ + "\"optionalDouble\":1.25,"
+ + "\"optionalBool\":true,"
+ + "\"optionalString\":\"Hello world!\","
+ + "\"optionalBytes\":\"AAEC\","
+ + "\"optionalNestedMessage\":{"
+ + "\"value\":100"
+ + "},"
+ + "\"optionalNestedEnum\":\"BAR\","
+ + "\"repeatedInt32\":[1234,234],"
+ + "\"repeatedInt64\":[\"1234567890123456789\",\"234567890123456789\"],"
+ + "\"repeatedUint32\":[5678,678],"
+ + "\"repeatedUint64\":[\"2345678901234567890\",\"345678901234567890\"],"
+ + "\"repeatedSint32\":[9012,10],"
+ + "\"repeatedSint64\":[\"3456789012345678901\",\"456789012345678901\"],"
+ + "\"repeatedFixed32\":[3456,456],"
+ + "\"repeatedFixed64\":[\"4567890123456789012\",\"567890123456789012\"],"
+ + "\"repeatedSfixed32\":[7890,890],"
+ + "\"repeatedSfixed64\":[\"5678901234567890123\",\"678901234567890123\"],"
+ + "\"repeatedFloat\":[1.5,11.5],"
+ + "\"repeatedDouble\":[1.25,11.25],"
+ + "\"repeatedBool\":[true,true],"
+ + "\"repeatedString\":[\"Hello world!\",\"ello world!\"],"
+ + "\"repeatedBytes\":[\"AAEC\",\"AQI=\"],"
+ + "\"repeatedNestedMessage\":[{"
+ + "\"value\":100"
+ + "},{"
+ + "\"value\":200"
+ + "}],"
+ + "\"repeatedNestedEnum\":[\"BAR\",\"BAZ\"]"
+ + "}",
+ toCompactJsonString(message2));
+ }
+
+ // Regression test for b/29892357
+ public void testEmptyWrapperTypesInAny() throws Exception {
+ JsonFormat.TypeRegistry registry =
+ JsonFormat.TypeRegistry.newBuilder().add(TestAllTypes.getDescriptor()).build();
+ JsonFormat.Parser parser = JsonFormat.parser().usingTypeRegistry(registry);
+
+ Any.Builder builder = Any.newBuilder();
+ parser.merge(
+ "{\n"
+ + " \"@type\": \"type.googleapis.com/google.protobuf.BoolValue\",\n"
+ + " \"value\": false\n"
+ + "}\n",
+ builder);
+ Any any = builder.build();
+ assertEquals(0, any.getValue().size());
}
}
diff --git a/java/util/src/test/java/com/google/protobuf/util/TimeUtilTest.java b/java/util/src/test/java/com/google/protobuf/util/TimeUtilTest.java
index fe5617e1..a41528ec 100644
--- a/java/util/src/test/java/com/google/protobuf/util/TimeUtilTest.java
+++ b/java/util/src/test/java/com/google/protobuf/util/TimeUtilTest.java
@@ -38,6 +38,8 @@ import junit.framework.TestCase;
import org.junit.Assert;
import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.List;
/** Unit tests for {@link TimeUtil}. */
public class TimeUtilTest extends TestCase {
@@ -76,11 +78,77 @@ public class TimeUtilTest extends TestCase {
assertEquals("1970-01-01T08:00:00.010Z", TimeUtil.toString(value));
}
+ private volatile boolean stopParsingThreads = false;
+ private volatile String errorMessage = "";
+
+ private class ParseTimestampThread extends Thread {
+ private final String[] strings;
+ private final Timestamp[] values;
+
+ public ParseTimestampThread(String[] strings, Timestamp[] values) {
+ this.strings = strings;
+ this.values = values;
+ }
+
+ @Override
+ public void run() {
+ int index = 0;
+ while (!stopParsingThreads) {
+ Timestamp result;
+ try {
+ result = TimeUtil.parseTimestamp(strings[index]);
+ } catch (ParseException e) {
+ errorMessage = "Failed to parse timestamp: " + strings[index];
+ break;
+ }
+ if (result.getSeconds() != values[index].getSeconds()
+ || result.getNanos() != values[index].getNanos()) {
+ errorMessage =
+ "Actual result: " + result.toString() + ", expected: " + values[index].toString();
+ break;
+ }
+ index = (index + 1) % strings.length;
+ }
+ }
+ }
+
+ public void testTimestampConcurrentParsing() throws Exception {
+ String[] timestampStrings =
+ new String[] {
+ "0001-01-01T00:00:00Z",
+ "9999-12-31T23:59:59.999999999Z",
+ "1970-01-01T00:00:00Z",
+ "1969-12-31T23:59:59.999Z",
+ };
+ Timestamp[] timestampValues = new Timestamp[timestampStrings.length];
+ for (int i = 0; i < timestampStrings.length; i++) {
+ timestampValues[i] = TimeUtil.parseTimestamp(timestampStrings[i]);
+ }
+
+ final int THREAD_COUNT = 16;
+ final int RUNNING_TIME = 5000; // in milliseconds.
+ final List<Thread> threads = new ArrayList<Thread>();
+
+ stopParsingThreads = false;
+ errorMessage = "";
+ for (int i = 0; i < THREAD_COUNT; i++) {
+ Thread thread = new ParseTimestampThread(timestampStrings, timestampValues);
+ thread.start();
+ threads.add(thread);
+ }
+ Thread.sleep(RUNNING_TIME);
+ stopParsingThreads = true;
+ for (Thread thread : threads) {
+ thread.join();
+ }
+ Assert.assertEquals("", errorMessage);
+ }
+
public void testTimetampInvalidFormat() throws Exception {
try {
// Value too small.
- Timestamp value = Timestamp.newBuilder()
- .setSeconds(TimeUtil.TIMESTAMP_SECONDS_MIN - 1).build();
+ Timestamp value =
+ Timestamp.newBuilder().setSeconds(TimeUtil.TIMESTAMP_SECONDS_MIN - 1).build();
TimeUtil.toString(value);
Assert.fail("Exception is expected.");
} catch (IllegalArgumentException e) {
@@ -89,14 +157,14 @@ public class TimeUtilTest extends TestCase {
try {
// Value too large.
- Timestamp value = Timestamp.newBuilder()
- .setSeconds(TimeUtil.TIMESTAMP_SECONDS_MAX + 1).build();
+ Timestamp value =
+ Timestamp.newBuilder().setSeconds(TimeUtil.TIMESTAMP_SECONDS_MAX + 1).build();
TimeUtil.toString(value);
Assert.fail("Exception is expected.");
} catch (IllegalArgumentException e) {
// Expected.
}
-
+
try {
// Invalid nanos value.
Timestamp value = Timestamp.newBuilder().setNanos(-1).build();
@@ -212,8 +280,7 @@ public class TimeUtilTest extends TestCase {
public void testDurationInvalidFormat() throws Exception {
try {
// Value too small.
- Duration value = Duration.newBuilder()
- .setSeconds(TimeUtil.DURATION_SECONDS_MIN - 1).build();
+ Duration value = Duration.newBuilder().setSeconds(TimeUtil.DURATION_SECONDS_MIN - 1).build();
TimeUtil.toString(value);
Assert.fail("Exception is expected.");
} catch (IllegalArgumentException e) {
@@ -222,18 +289,16 @@ public class TimeUtilTest extends TestCase {
try {
// Value too large.
- Duration value = Duration.newBuilder()
- .setSeconds(TimeUtil.DURATION_SECONDS_MAX + 1).build();
+ Duration value = Duration.newBuilder().setSeconds(TimeUtil.DURATION_SECONDS_MAX + 1).build();
TimeUtil.toString(value);
Assert.fail("Exception is expected.");
} catch (IllegalArgumentException e) {
// Expected.
}
-
+
try {
// Invalid nanos value.
- Duration value = Duration.newBuilder().setSeconds(1).setNanos(-1)
- .build();
+ Duration value = Duration.newBuilder().setSeconds(1).setNanos(-1).build();
TimeUtil.toString(value);
Assert.fail("Exception is expected.");
} catch (IllegalArgumentException e) {
@@ -242,8 +307,7 @@ public class TimeUtilTest extends TestCase {
try {
// Invalid nanos value.
- Duration value = Duration.newBuilder().setSeconds(-1).setNanos(1)
- .build();
+ Duration value = Duration.newBuilder().setSeconds(-1).setNanos(1).build();
TimeUtil.toString(value);
Assert.fail("Exception is expected.");
} catch (IllegalArgumentException e) {
@@ -300,8 +364,7 @@ public class TimeUtilTest extends TestCase {
}
public void testTimestampConversion() throws Exception {
- Timestamp timestamp =
- TimeUtil.parseTimestamp("1970-01-01T00:00:01.111111111Z");
+ Timestamp timestamp = TimeUtil.parseTimestamp("1970-01-01T00:00:01.111111111Z");
assertEquals(1111111111, TimeUtil.toNanos(timestamp));
assertEquals(1111111, TimeUtil.toMicros(timestamp));
assertEquals(1111, TimeUtil.toMillis(timestamp));
@@ -311,7 +374,7 @@ public class TimeUtilTest extends TestCase {
assertEquals("1970-01-01T00:00:01.111111Z", TimeUtil.toString(timestamp));
timestamp = TimeUtil.createTimestampFromMillis(1111);
assertEquals("1970-01-01T00:00:01.111Z", TimeUtil.toString(timestamp));
-
+
timestamp = TimeUtil.parseTimestamp("1969-12-31T23:59:59.111111111Z");
assertEquals(-888888889, TimeUtil.toNanos(timestamp));
assertEquals(-888889, TimeUtil.toMicros(timestamp));
@@ -335,7 +398,7 @@ public class TimeUtilTest extends TestCase {
assertEquals("1.111111s", TimeUtil.toString(duration));
duration = TimeUtil.createDurationFromMillis(1111);
assertEquals("1.111s", TimeUtil.toString(duration));
-
+
duration = TimeUtil.parseDuration("-1.111111111s");
assertEquals(-1111111111, TimeUtil.toNanos(duration));
assertEquals(-1111111, TimeUtil.toMicros(duration));
@@ -392,29 +455,28 @@ public class TimeUtilTest extends TestCase {
duration = TimeUtil.add(duration, duration);
assertEquals("-2.250s", TimeUtil.toString(duration));
-
+
duration = TimeUtil.subtract(duration, TimeUtil.parseDuration("-1s"));
assertEquals("-1.250s", TimeUtil.toString(duration));
-
+
// Multiplications (with results larger than Long.MAX_VALUE in nanoseconds).
duration = TimeUtil.parseDuration("0.999999999s");
- assertEquals("315575999684.424s",
- TimeUtil.toString(TimeUtil.multiply(duration, 315576000000L)));
+ assertEquals(
+ "315575999684.424s", TimeUtil.toString(TimeUtil.multiply(duration, 315576000000L)));
duration = TimeUtil.parseDuration("-0.999999999s");
- assertEquals("-315575999684.424s",
- TimeUtil.toString(TimeUtil.multiply(duration, 315576000000L)));
- assertEquals("315575999684.424s",
- TimeUtil.toString(TimeUtil.multiply(duration, -315576000000L)));
-
+ assertEquals(
+ "-315575999684.424s", TimeUtil.toString(TimeUtil.multiply(duration, 315576000000L)));
+ assertEquals(
+ "315575999684.424s", TimeUtil.toString(TimeUtil.multiply(duration, -315576000000L)));
+
// Divisions (with values larger than Long.MAX_VALUE in nanoseconds).
Duration d1 = TimeUtil.parseDuration("315576000000s");
Duration d2 = TimeUtil.subtract(d1, TimeUtil.createDurationFromNanos(1));
assertEquals(1, TimeUtil.divide(d1, d2));
assertEquals(0, TimeUtil.divide(d2, d1));
assertEquals("0.000000001s", TimeUtil.toString(TimeUtil.remainder(d1, d2)));
- assertEquals("315575999999.999999999s",
- TimeUtil.toString(TimeUtil.remainder(d2, d1)));
-
+ assertEquals("315575999999.999999999s", TimeUtil.toString(TimeUtil.remainder(d2, d1)));
+
// Divisions involving negative values.
//
// (-5) / 2 = -2, remainder = -1
diff --git a/java/util/src/test/java/com/google/protobuf/util/json_test.proto b/java/util/src/test/proto/com/google/protobuf/util/json_test.proto
index b2753af6..4bf223f2 100644
--- a/java/util/src/test/java/com/google/protobuf/util/json_test.proto
+++ b/java/util/src/test/proto/com/google/protobuf/util/json_test.proto
@@ -28,6 +28,36 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// 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.
+
syntax = "proto3";
package json_test;
@@ -90,6 +120,14 @@ message TestAllTypes {
repeated NestedEnum repeated_nested_enum = 51;
}
+message TestOneof {
+ oneof oneof_field {
+ int32 oneof_int32 = 1;
+ TestAllTypes.NestedMessage oneof_nested_message = 2;
+ google.protobuf.NullValue oneof_null_value = 3;
+ }
+}
+
message TestMap {
// Instead of testing all combinations (too many), we only make sure all
// valid types have been used at least in one field as key and in one
@@ -151,8 +189,14 @@ message TestFieldMask {
message TestStruct {
google.protobuf.Struct struct_value = 1;
+ google.protobuf.Value value = 2;
+ google.protobuf.ListValue list_value = 3;
}
message TestAny {
google.protobuf.Any any_value = 1;
}
+
+message TestCustomJsonName {
+ int32 value = 1 [json_name = "@value"];
+}
diff --git a/javanano/pom.xml b/javanano/pom.xml
index 1a95a43e..e6a03d15 100644
--- a/javanano/pom.xml
+++ b/javanano/pom.xml
@@ -10,7 +10,7 @@
</parent>
<groupId>com.google.protobuf.nano</groupId>
<artifactId>protobuf-javanano</artifactId>
- <version>3.0.0-alpha-4</version>
+ <version>3.0.0-alpha-7</version>
<packaging>bundle</packaging>
<name>Protocol Buffer JavaNano API</name>
<description>
@@ -165,7 +165,7 @@
<instructions>
<Bundle-DocURL>https://developers.google.com/protocol-buffers/</Bundle-DocURL>
<Bundle-SymbolicName>com.google.protobuf</Bundle-SymbolicName>
- <Export-Package>com.google.protobuf;version=3.0.0-alpha-4</Export-Package>
+ <Export-Package>com.google.protobuf;version=3.0.0-alpha-7</Export-Package>
</instructions>
</configuration>
</plugin>
diff --git a/javanano/src/main/java/com/google/protobuf/nano/FieldArray.java b/javanano/src/main/java/com/google/protobuf/nano/FieldArray.java
index eca9c0d9..b49a97fa 100644
--- a/javanano/src/main/java/com/google/protobuf/nano/FieldArray.java
+++ b/javanano/src/main/java/com/google/protobuf/nano/FieldArray.java
@@ -32,13 +32,13 @@ package com.google.protobuf.nano;
/**
- * A custom version of {@link android.util.SparseArray} with the minimal API
+ * A custom version of {@code android.util.SparseArray} with the minimal API
* for storing {@link FieldData} objects.
*
* <p>This class is an internal implementation detail of nano and should not
* be called directly by clients.
*
- * Based on {@link android.support.v4.util.SpareArrayCompat}.
+ * Based on {@code android.support.v4.util.SpareArrayCompat}.
*/
public final class FieldArray implements Cloneable {
private static final FieldData DELETED = new FieldData();
diff --git a/javanano/src/main/java/com/google/protobuf/nano/MessageNanoPrinter.java b/javanano/src/main/java/com/google/protobuf/nano/MessageNanoPrinter.java
index d9500bb9..5f329f02 100644
--- a/javanano/src/main/java/com/google/protobuf/nano/MessageNanoPrinter.java
+++ b/javanano/src/main/java/com/google/protobuf/nano/MessageNanoPrinter.java
@@ -156,7 +156,7 @@ public final class MessageNanoPrinter {
} catch (NoSuchMethodException e) {
continue;
}
- // If hazzer does't exist or returns false, no need to continue
+ // If hazzer doesn't exist or returns false, no need to continue
if (!(Boolean) hazzer.invoke(object)) {
continue;
}
diff --git a/jenkins/README.md b/jenkins/README.md
new file mode 100644
index 00000000..29f664f2
--- /dev/null
+++ b/jenkins/README.md
@@ -0,0 +1,6 @@
+
+Jenkins Infrastructure
+----------------------
+
+The scripts in this directory serve as plumbing for running the protobuf
+tests under Jenkins.
diff --git a/jenkins/build_and_run_docker.sh b/jenkins/build_and_run_docker.sh
new file mode 100755
index 00000000..abc6f055
--- /dev/null
+++ b/jenkins/build_and_run_docker.sh
@@ -0,0 +1,56 @@
+#!/bin/bash
+#
+# Builds docker image and runs a command under it.
+# This is a generic script that is configured with the following variables:
+#
+# DOCKERFILE_DIR - Directory in which Dockerfile file is located.
+# DOCKER_RUN_SCRIPT - Script to run under docker (relative to protobuf repo root)
+# OUTPUT_DIR - Directory that will be copied from inside docker after finishing.
+# $@ - Extra args to pass to docker run
+
+
+set -ex
+
+cd $(dirname $0)/..
+git_root=$(pwd)
+cd -
+
+# Use image name based on Dockerfile location checksum
+DOCKER_IMAGE_NAME=$(basename $DOCKERFILE_DIR)_$(sha1sum $DOCKERFILE_DIR/Dockerfile | cut -f1 -d\ )
+
+# Make sure docker image has been built. Should be instantaneous if so.
+docker build -t $DOCKER_IMAGE_NAME $DOCKERFILE_DIR
+
+# Ensure existence of ccache directory
+CCACHE_DIR=/tmp/protobuf-ccache
+mkdir -p $CCACHE_DIR
+
+# Choose random name for docker container
+CONTAINER_NAME="build_and_run_docker_$(uuidgen)"
+
+# Run command inside docker
+docker run \
+ "$@" \
+ -e CCACHE_DIR=$CCACHE_DIR \
+ -e EXTERNAL_GIT_ROOT="/var/local/jenkins/protobuf" \
+ -e THIS_IS_REALLY_NEEDED='see https://github.com/docker/docker/issues/14203 for why docker is awful' \
+ -v "$git_root:/var/local/jenkins/protobuf:ro" \
+ -v $CCACHE_DIR:$CCACHE_DIR \
+ -w /var/local/git/protobuf \
+ --name=$CONTAINER_NAME \
+ $DOCKER_IMAGE_NAME \
+ bash -l "/var/local/jenkins/protobuf/$DOCKER_RUN_SCRIPT" || FAILED="true"
+
+# Copy output artifacts
+if [ "$OUTPUT_DIR" != "" ]
+then
+ docker cp "$CONTAINER_NAME:/var/local/git/protobuf/$OUTPUT_DIR" "$git_root" || FAILED="true"
+fi
+
+# remove the container, possibly killing it first
+docker rm -f $CONTAINER_NAME || true
+
+if [ "$FAILED" != "" ]
+then
+ exit 1
+fi
diff --git a/jenkins/buildcmds/README.md b/jenkins/buildcmds/README.md
new file mode 100644
index 00000000..7a48f2d5
--- /dev/null
+++ b/jenkins/buildcmds/README.md
@@ -0,0 +1,6 @@
+
+Jenkins Build Commands
+----------------------
+
+The scripts in this directory are designed to be top-level entry points for
+Jenkins projects.
diff --git a/jenkins/buildcmds/pull_request.sh b/jenkins/buildcmds/pull_request.sh
new file mode 100755
index 00000000..01fda798
--- /dev/null
+++ b/jenkins/buildcmds/pull_request.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+#
+# This is the top-level script we give to Jenkins as the entry point for
+# running the "pull request" project:
+#
+# https://grpc-testing.appspot.com/view/Protocol%20Buffers/job/protobuf_pull_request/
+#
+# 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.
+
+export DOCKERFILE_DIR=jenkins/docker
+export DOCKER_RUN_SCRIPT=jenkins/pull_request_in_docker.sh
+export OUTPUT_DIR=testoutput
+./jenkins/build_and_run_docker.sh
diff --git a/jenkins/docker/Dockerfile b/jenkins/docker/Dockerfile
new file mode 100644
index 00000000..53ac38f3
--- /dev/null
+++ b/jenkins/docker/Dockerfile
@@ -0,0 +1,153 @@
+# This Dockerfile specifies the recipe for creating an image for the tests
+# to run in.
+#
+# We install as many test dependencies here as we can, because these setup
+# steps can be cached. They do *not* run every time we run the build.
+# The Docker image is only rebuilt when the Dockerfile (ie. this file)
+# changes.
+
+# Base Dockerfile for gRPC dev images
+FROM debian:latest
+
+# Apt source for old Python versions.
+RUN echo 'deb http://ppa.launchpad.net/fkrull/deadsnakes/ubuntu trusty main' > /etc/apt/sources.list.d/deadsnakes.list && \
+ apt-key adv --keyserver keyserver.ubuntu.com --recv-keys DB82666C
+
+# Apt source for Oracle Java.
+run echo 'deb http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main' > /etc/apt/sources.list.d/webupd8team-java-trusty.list && \
+ apt-key adv --keyserver keyserver.ubuntu.com --recv-keys EEA14886 && \
+ echo "oracle-java7-installer shared/accepted-oracle-license-v1-1 select true" | debconf-set-selections
+
+# Apt source for Mono
+run echo "deb http://download.mono-project.com/repo/debian wheezy main" | tee /etc/apt/sources.list.d/mono-xamarin.list && \
+ echo "deb http://download.mono-project.com/repo/debian wheezy-libjpeg62-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list && \
+ apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
+
+# Install dotnet SDK based on https://www.microsoft.com/net/core#debian
+# (Ubuntu instructions need apt to support https)
+RUN apt-get update && apt-get install -y curl libunwind8 gettext && \
+ curl -sSL -o dotnet.tar.gz https://go.microsoft.com/fwlink/?LinkID=809130 && \
+ mkdir -p /opt/dotnet && tar zxf dotnet.tar.gz -C /opt/dotnet && \
+ ln -s /opt/dotnet/dotnet /usr/local/bin
+
+# 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 \
+ # -- For csharp --
+ mono-devel \
+ referenceassemblies-pcl \
+ nunit \
+ # -- For all Java builds -- \
+ maven \
+ # -- For java_jdk6 -- \
+ # oops! not in jessie. too old? openjdk-6-jdk \
+ # -- For java_jdk7 -- \
+ openjdk-7-jdk \
+ # -- For java_oracle7 -- \
+ oracle-java7-installer \
+ # -- For python / python_cpp -- \
+ python-setuptools \
+ python-pip \
+ python-dev \
+ python2.6-dev \
+ python3.3-dev \
+ python3.4-dev \
+ # -- For Ruby --
+ ruby \
+ && apt-get clean
+
+##################
+# C# dependencies
+
+RUN wget www.nuget.org/NuGet.exe -O /usr/local/bin/nuget.exe
+
+##################
+# Python dependencies
+
+# These packages exist in apt-get, but their versions are too old, so we have
+# to get updates from pip.
+
+RUN pip install pip --upgrade
+RUN pip install virtualenv tox yattag
+
+##################
+# Ruby dependencies
+
+# Install rvm
+RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
+RUN \curl -sSL https://get.rvm.io | bash -s stable
+
+# Install Ruby 2.1, Ruby 2.2 and JRuby 1.7
+RUN /bin/bash -l -c "rvm install ruby-2.1"
+RUN /bin/bash -l -c "rvm install ruby-2.2"
+RUN /bin/bash -l -c "rvm install jruby-1.7"
+RUN /bin/bash -l -c "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc"
+RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc"
+RUN /bin/bash -l -c "gem install bundler --no-ri --no-rdoc"
+
+##################
+# Java dependencies
+
+# This step requires compiling protoc. :(
+
+ENV MAVEN_REPO /var/maven_local_repository
+ENV MVN mvn --batch-mode
+
+RUN cd /tmp && \
+ git clone https://github.com/google/protobuf.git && \
+ cd protobuf && \
+ ./autogen.sh && \
+ ./configure && \
+ make -j6 && \
+ cd java && \
+ $MVN install dependency:go-offline -Dmaven.repo.local=$MAVEN_REPO && \
+ cd ../javanano && \
+ $MVN install dependency:go-offline -Dmaven.repo.local=$MAVEN_REPO
+
+##################
+# Go dependencies.
+RUN apt-get install -y \
+ # -- For go -- \
+ golang
+
+##################
+# Javascript dependencies.
+Run apt-get install -y \
+ # -- For javascript -- \
+ npm
+
+# On Debian/Ubuntu, nodejs binary is named 'nodejs' because the name 'node'
+# is taken by another legacy binary. We don't have that legacy binary and
+# npm expects the binary to be named 'node', so we just create a symbol
+# link here.
+RUN ln -s `which nodejs` /usr/bin/node
+
+##################
+# Prepare ccache
+
+RUN ln -s /usr/bin/ccache /usr/local/bin/gcc
+RUN ln -s /usr/bin/ccache /usr/local/bin/g++
+RUN ln -s /usr/bin/ccache /usr/local/bin/cc
+RUN ln -s /usr/bin/ccache /usr/local/bin/c++
+RUN ln -s /usr/bin/ccache /usr/local/bin/clang
+RUN ln -s /usr/bin/ccache /usr/local/bin/clang++
+
+# Define the default command.
+CMD ["bash"]
diff --git a/jenkins/make_test_output.py b/jenkins/make_test_output.py
new file mode 100644
index 00000000..b1f2e2c0
--- /dev/null
+++ b/jenkins/make_test_output.py
@@ -0,0 +1,91 @@
+"""Gathers output from test runs and create an XML file in JUnit format.
+
+The output files from the individual tests have been written in a directory
+structure like:
+
+ $DIR/joblog (output from "parallel --joblog joblog")
+ $DIR/logs/1/cpp/stdout
+ $DIR/logs/1/cpp/stderr
+ $DIR/logs/1/csharp/stdout
+ $DIR/logs/1/csharp/stderr
+ $DIR/logs/1/java_jdk7/stdout
+ $DIR/logs/1/java_jdk7/stderr
+ etc.
+
+This script bundles them into a single output XML file so Jenkins can show
+detailed test results. It runs as the last step before the Jenkins build
+finishes.
+"""
+
+import os;
+import sys;
+from yattag import Doc
+from collections import defaultdict
+
+def readtests(basedir):
+ tests = defaultdict(dict)
+
+ # Sample input (note: separators are tabs).
+ #
+ # Seq Host Starttime Runtime Send Receive Exitval Signal Command
+ # 1 : 1456263838.313 0.005 0 0 0 0 echo A
+ with open(basedir + "/joblog") as jobs:
+ firstline = next(jobs)
+ for line in jobs:
+ values = line.split("\t")
+
+ name = values[8].split()[-1]
+ test = tests[name]
+ test["name"] = name
+ test["time"] = values[3]
+
+ exitval = values[6]
+ if int(exitval):
+ # We don't have a more specific message. User should look at stderr.
+ test["failure"] = "TEST FAILURE"
+ else:
+ test["failure"] = False
+
+ for testname in os.listdir(basedir + "/logs/1"):
+ test = tests[testname]
+
+ with open(basedir + "/logs/1/" + testname + "/stdout") as f:
+ test["stdout"] = f.read()
+
+ with open(basedir + "/logs/1/" + testname + "/stderr") as f:
+ test["stderr"] = f.read()
+
+ # The cpp test is special since it doesn't run under parallel so doesn't show
+ # up in the job log.
+ tests["cpp"]["name"] = "cpp"
+
+ with open(basedir + '/logs/1/cpp/build_time', 'r') as f:
+ tests["cpp"]["time"] = f.read().strip()
+ tests["cpp"]["failure"] = False
+
+ ret = tests.values()
+ ret.sort(key=lambda x: x["name"])
+
+ return ret
+
+def genxml(tests):
+ doc, tag, text = Doc().tagtext()
+
+ with tag("testsuites"):
+ with tag("testsuite", name="Protobuf Tests"):
+ for test in tests:
+ with tag("testcase", name=test["name"], classname=test["name"],
+ time=test["time"]):
+ with tag("system-out"):
+ text(test["stdout"])
+ with tag("system-err"):
+ text(test["stderr"])
+ if test["failure"]:
+ with tag("failure"):
+ text(test["failure"])
+
+ return doc.getvalue()
+
+sys.stderr.write("make_test_output.py: writing XML from directory: " +
+ sys.argv[1] + "\n");
+print genxml(readtests(sys.argv[1]))
diff --git a/jenkins/pull_request_in_docker.sh b/jenkins/pull_request_in_docker.sh
new file mode 100755
index 00000000..78a9253a
--- /dev/null
+++ b/jenkins/pull_request_in_docker.sh
@@ -0,0 +1,74 @@
+#!/bin/bash
+#
+# This is the script that runs inside Docker, once the image has been built,
+# to execute all tests for the "pull request" project.
+
+WORKSPACE_BASE=`pwd`
+MY_DIR="$(dirname "$0")"
+TEST_SCRIPT=$MY_DIR/../tests.sh
+BUILD_DIR=/tmp/protobuf
+
+set -e # exit immediately on error
+set -x # display all commands
+
+# The protobuf repository is mounted into our Docker image, but read-only.
+# We clone into a directory inside Docker (this is faster than cp).
+rm -rf $BUILD_DIR
+mkdir -p $BUILD_DIR
+cd $BUILD_DIR
+git clone /var/local/jenkins/protobuf
+cd protobuf
+
+# Set up the directory where our test output is going to go.
+OUTPUT_DIR=`mktemp -d`
+LOG_OUTPUT_DIR=$OUTPUT_DIR/logs
+mkdir -p $LOG_OUTPUT_DIR/1/cpp
+
+################################################################################
+# cpp build needs to run first, non-parallelized, so that protoc is available
+# for other builds.
+
+# Output filenames to follow the overall scheme used by parallel, ie:
+# $DIR/logs/1/cpp/stdout
+# $DIR/logs/1/cpp/stderr
+# $DIR/logs/1/csharp/stdout
+# $DIR/logs/1/csharp/stderr
+# $DIR/logs/1/java_jdk7/stdout
+# $DIR/logs/1/java_jdk7/stderr
+CPP_STDOUT=$LOG_OUTPUT_DIR/1/cpp/stdout
+CPP_STDERR=$LOG_OUTPUT_DIR/1/cpp/stderr
+
+# Time the C++ build, so we can put this info in the test output.
+# It's important that we get /usr/bin/time (which supports -f and -o) and not
+# the bash builtin "time" which doesn't.
+TIME_CMD="/usr/bin/time -f %e -o $LOG_OUTPUT_DIR/1/cpp/build_time"
+
+$TIME_CMD $TEST_SCRIPT cpp > >(tee $CPP_STDOUT) 2> >(tee $CPP_STDERR >&2)
+
+# Other tests are run in parallel.
+
+parallel --results $LOG_OUTPUT_DIR --joblog $OUTPUT_DIR/joblog $TEST_SCRIPT ::: \
+ csharp \
+ java_jdk7 \
+ javanano_jdk7 \
+ java_oracle7 \
+ javanano_oracle7 \
+ python \
+ python_cpp \
+ ruby_all \
+ javascript \
+ golang \
+ || true # Process test results even if tests fail.
+
+cat $OUTPUT_DIR/joblog
+
+# The directory that is copied from Docker back into the Jenkins workspace.
+COPY_FROM_DOCKER=/var/local/git/protobuf/testoutput
+mkdir -p $COPY_FROM_DOCKER
+TESTOUTPUT_XML_FILE=$COPY_FROM_DOCKER/testresults.xml
+
+# Process all the output files from "parallel" and package them into a single
+# .xml file with detailed, broken-down test output.
+python $MY_DIR/make_test_output.py $OUTPUT_DIR > $TESTOUTPUT_XML_FILE
+
+ls -l $TESTOUTPUT_XML_FILE
diff --git a/js/README.md b/js/README.md
new file mode 100644
index 00000000..f4184621
--- /dev/null
+++ b/js/README.md
@@ -0,0 +1,158 @@
+Protocol Buffers - Google's data interchange format
+===================================================
+
+[![Build Status](https://travis-ci.org/google/protobuf.svg?branch=master)](https://travis-ci.org/google/protobuf)
+
+Copyright 2008 Google Inc.
+
+This directory contains the JavaScript Protocol Buffers runtime library.
+
+The library is currently compatible with:
+
+1. CommonJS-style imports (eg. `var protos = require('my-protos');`)
+2. Closure-style imports (eg. `goog.require('my.package.MyProto');`)
+
+Support for ES6-style imports is not implemented yet. Browsers can
+be supported by using Browserify, webpack, Closure Compiler, etc. to
+resolve imports at compile time.
+
+To use Protocol Buffers with JavaScript, you need two main components:
+
+1. The protobuf runtime library. You can install this with
+ `npm install google-protobuf`, or use the files in this directory.
+2. The Protocol Compiler `protoc`. This translates `.proto` files
+ into `.js` files. The compiler is not currently available via
+ npm, but you can download a pre-built binary
+ [on GitHub](https://github.com/google/protobuf/releases)
+ (look for the `protoc-*.zip` files under **Downloads**).
+
+
+Setup
+=====
+
+First, obtain the Protocol Compiler. The easiest way is to download
+a pre-built binary from [https://github.com/google/protobuf/releases](https://github.com/google/protobuf/releases).
+
+If you want, you can compile `protoc` from source instead. To do this
+follow the instructions in [the top-level
+README](https://github.com/google/protobuf/blob/master/src/README.md).
+
+Once you have `protoc` compiled, you can run the tests by typing:
+
+ $ cd js
+ $ npm install
+ $ npm test
+
+ # If your protoc is somewhere else than ../src/protoc, instead do this.
+ # But make sure your protoc is the same version as this (or compatible)!
+ $ PROTOC=/usr/local/bin/protoc npm test
+
+This will run two separate copies of the tests: one that uses
+Closure Compiler style imports and one that uses CommonJS imports.
+You can see all the CommonJS files in `commonjs_out/`.
+If all of these tests pass, you know you have a working setup.
+
+
+Using Protocol Buffers in your own project
+==========================================
+
+To use Protocol Buffers in your own project, you need to integrate
+the Protocol Compiler into your build system. The details are a
+little different depending on whether you are using Closure imports
+or CommonJS imports:
+
+Closure Imports
+---------------
+
+If you want to use Closure imports, your build should run a command
+like this:
+
+ $ protoc --js_out=library=myproto_libs,binary:. messages.proto base.proto
+
+For Closure imports, `protoc` will generate a single output file
+(`myproto_libs.js` in this example). The generated file will `goog.provide()`
+all of the types defined in your .proto files. For example, for the unit
+tests the generated files contain many `goog.provide` statements like:
+
+ goog.provide('proto.google.protobuf.DescriptorProto');
+ goog.provide('proto.google.protobuf.DescriptorProto.ExtensionRange');
+ goog.provide('proto.google.protobuf.DescriptorProto.ReservedRange');
+ goog.provide('proto.google.protobuf.EnumDescriptorProto');
+ goog.provide('proto.google.protobuf.EnumOptions');
+
+The generated code will also `goog.require()` many types in the core library,
+and they will require many types in the Google Closure library. So make sure
+that your `goog.provide()` / `goog.require()` setup can find all of your
+generated code, the core library `.js` files in this directory, and the
+Google Closure library itself.
+
+Once you've done this, you should be able to import your types with
+statements like:
+
+ goog.require('proto.my.package.MyMessage');
+
+ var message = proto.my.package.MyMessage();
+
+CommonJS imports
+----------------
+
+If you want to use CommonJS imports, your build should run a command
+like this:
+
+ $ protoc --js_out=import_style=commonjs,binary:. messages.proto base.proto
+
+For CommonJS imports, `protoc` will spit out one file per input file
+(so `messages_pb.js` and `base_pb.js` in this example). The generated
+code will depend on the core runtime, which should be in a file called
+`google-protobuf.js`. If you are installing from `npm`, this file should
+already be built and available. If you are running from GitHub, you need
+to build it first by running:
+
+ $ gulp dist
+
+Once you've done this, you should be able to import your types with
+statements like:
+
+ var messages = require('./messages_pb');
+
+ var message = new messages.MyMessage();
+
+The `--js_out` flag
+-------------------
+
+The syntax of the `--js_out` flag is:
+
+ --js_out=[OPTIONS:]output_dir
+
+Where `OPTIONS` are separated by commas. Options are either `opt=val` or
+just `opt` (for options that don't take a value). The available options
+are specified and documented in the `GeneratorOptions` struct in
+[src/google/protobuf/compiler/js/js_generator.h](https://github.com/google/protobuf/blob/master/src/google/protobuf/compiler/js/js_generator.h#L53).
+
+Some examples:
+
+- `--js_out=library=myprotos_lib.js,binary:.`: this contains the options
+ `library=myprotos.lib.js` and `binary` and outputs to the current directory.
+ The `import_style` option is left to the default, which is `closure`.
+- `--js_out=import_style=commonjs,binary:protos`: this contains the options
+ `import_style=commonjs` and `binary` and outputs to the directory `protos`.
+
+API
+===
+
+The API is not well-documented yet. Here is a quick example to give you an
+idea of how the library generally works:
+
+ var message = new MyMessage();
+
+ message.setName("John Doe");
+ message.setAge(25);
+ message.setPhoneNumbers(["800-555-1212", "800-555-0000"]);
+
+ // Serializes to a UInt8Array.
+ bytes = message.serializeBinary();
+
+ var message2 = MyMessage.deserializeBinary(bytes);
+
+For more examples, see the tests. You can also look at the generated code
+to see what methods are defined for your generated messages.
diff --git a/js/binary/arith.js b/js/binary/arith.js
new file mode 100644
index 00000000..70257de7
--- /dev/null
+++ b/js/binary/arith.js
@@ -0,0 +1,413 @@
+// 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.
+
+/**
+ * @fileoverview This file contains helper code used by jspb.utils to
+ * handle 64-bit integer conversion to/from strings.
+ *
+ * @author cfallin@google.com (Chris Fallin)
+ *
+ * TODO(haberman): move this to javascript/closure/math?
+ */
+
+goog.provide('jspb.arith.Int64');
+goog.provide('jspb.arith.UInt64');
+
+/**
+ * UInt64 implements some 64-bit arithmetic routines necessary for properly
+ * handling 64-bit integer fields. It implements lossless integer arithmetic on
+ * top of JavaScript's number type, which has only 53 bits of precision, by
+ * representing 64-bit integers as two 32-bit halves.
+ *
+ * @param {number} lo The low 32 bits.
+ * @param {number} hi The high 32 bits.
+ * @constructor
+ */
+jspb.arith.UInt64 = function(lo, hi) {
+ /**
+ * The low 32 bits.
+ * @public {number}
+ */
+ this.lo = lo;
+ /**
+ * The high 32 bits.
+ * @public {number}
+ */
+ this.hi = hi;
+};
+
+
+/**
+ * Compare two 64-bit numbers. Returns -1 if the first is
+ * less, +1 if the first is greater, or 0 if both are equal.
+ * @param {!jspb.arith.UInt64} other
+ * @return {number}
+ */
+jspb.arith.UInt64.prototype.cmp = function(other) {
+ if (this.hi < other.hi || (this.hi == other.hi && this.lo < other.lo)) {
+ return -1;
+ } else if (this.hi == other.hi && this.lo == other.lo) {
+ return 0;
+ } else {
+ return 1;
+ }
+};
+
+
+/**
+ * Right-shift this number by one bit.
+ * @return {!jspb.arith.UInt64}
+ */
+jspb.arith.UInt64.prototype.rightShift = function() {
+ var hi = this.hi >>> 1;
+ var lo = (this.lo >>> 1) | ((this.hi & 1) << 31);
+ return new jspb.arith.UInt64(lo >>> 0, hi >>> 0);
+};
+
+
+/**
+ * Left-shift this number by one bit.
+ * @return {!jspb.arith.UInt64}
+ */
+jspb.arith.UInt64.prototype.leftShift = function() {
+ var lo = this.lo << 1;
+ var hi = (this.hi << 1) | (this.lo >>> 31);
+ return new jspb.arith.UInt64(lo >>> 0, hi >>> 0);
+};
+
+
+/**
+ * Test the MSB.
+ * @return {boolean}
+ */
+jspb.arith.UInt64.prototype.msb = function() {
+ return !!(this.hi & 0x80000000);
+};
+
+
+/**
+ * Test the LSB.
+ * @return {boolean}
+ */
+jspb.arith.UInt64.prototype.lsb = function() {
+ return !!(this.lo & 1);
+};
+
+
+/**
+ * Test whether this number is zero.
+ * @return {boolean}
+ */
+jspb.arith.UInt64.prototype.zero = function() {
+ return this.lo == 0 && this.hi == 0;
+};
+
+
+/**
+ * Add two 64-bit numbers to produce a 64-bit number.
+ * @param {!jspb.arith.UInt64} other
+ * @return {!jspb.arith.UInt64}
+ */
+jspb.arith.UInt64.prototype.add = function(other) {
+ var lo = ((this.lo + other.lo) & 0xffffffff) >>> 0;
+ var hi =
+ (((this.hi + other.hi) & 0xffffffff) >>> 0) +
+ (((this.lo + other.lo) >= 0x100000000) ? 1 : 0);
+ return new jspb.arith.UInt64(lo >>> 0, hi >>> 0);
+};
+
+
+/**
+ * Subtract two 64-bit numbers to produce a 64-bit number.
+ * @param {!jspb.arith.UInt64} other
+ * @return {!jspb.arith.UInt64}
+ */
+jspb.arith.UInt64.prototype.sub = function(other) {
+ var lo = ((this.lo - other.lo) & 0xffffffff) >>> 0;
+ var hi =
+ (((this.hi - other.hi) & 0xffffffff) >>> 0) -
+ (((this.lo - other.lo) < 0) ? 1 : 0);
+ return new jspb.arith.UInt64(lo >>> 0, hi >>> 0);
+};
+
+
+/**
+ * Multiply two 32-bit numbers to produce a 64-bit number.
+ * @param {number} a The first integer: must be in [0, 2^32-1).
+ * @param {number} b The second integer: must be in [0, 2^32-1).
+ * @return {!jspb.arith.UInt64}
+ */
+jspb.arith.UInt64.mul32x32 = function(a, b) {
+ // Directly multiplying two 32-bit numbers may produce up to 64 bits of
+ // precision, thus losing precision because of the 53-bit mantissa of
+ // JavaScript numbers. So we multiply with 16-bit digits (radix 65536)
+ // instead.
+ var aLow = (a & 0xffff);
+ var aHigh = (a >>> 16);
+ var bLow = (b & 0xffff);
+ var bHigh = (b >>> 16);
+ var productLow =
+ // 32-bit result, result bits 0-31, take all 32 bits
+ (aLow * bLow) +
+ // 32-bit result, result bits 16-47, take bottom 16 as our top 16
+ ((aLow * bHigh) & 0xffff) * 0x10000 +
+ // 32-bit result, result bits 16-47, take bottom 16 as our top 16
+ ((aHigh * bLow) & 0xffff) * 0x10000;
+ var productHigh =
+ // 32-bit result, result bits 32-63, take all 32 bits
+ (aHigh * bHigh) +
+ // 32-bit result, result bits 16-47, take top 16 as our bottom 16
+ ((aLow * bHigh) >>> 16) +
+ // 32-bit result, result bits 16-47, take top 16 as our bottom 16
+ ((aHigh * bLow) >>> 16);
+
+ // Carry. Note that we actually have up to *two* carries due to addition of
+ // three terms.
+ while (productLow >= 0x100000000) {
+ productLow -= 0x100000000;
+ productHigh += 1;
+ }
+
+ return new jspb.arith.UInt64(productLow >>> 0, productHigh >>> 0);
+};
+
+
+/**
+ * Multiply this number by a 32-bit number, producing a 96-bit number, then
+ * truncate the top 32 bits.
+ * @param {number} a The multiplier.
+ * @return {!jspb.arith.UInt64}
+ */
+jspb.arith.UInt64.prototype.mul = function(a) {
+ // Produce two parts: at bits 0-63, and 32-95.
+ var lo = jspb.arith.UInt64.mul32x32(this.lo, a);
+ var hi = jspb.arith.UInt64.mul32x32(this.hi, a);
+ // Left-shift hi by 32 bits, truncating its top bits. The parts will then be
+ // aligned for addition.
+ hi.hi = hi.lo;
+ hi.lo = 0;
+ return lo.add(hi);
+};
+
+
+/**
+ * Divide a 64-bit number by a 32-bit number to produce a
+ * 64-bit quotient and a 32-bit remainder.
+ * @param {number} _divisor
+ * @return {Array.<jspb.arith.UInt64>} array of [quotient, remainder],
+ * unless divisor is 0, in which case an empty array is returned.
+ */
+jspb.arith.UInt64.prototype.div = function(_divisor) {
+ if (_divisor == 0) {
+ return [];
+ }
+
+ // We perform long division using a radix-2 algorithm, for simplicity (i.e.,
+ // one bit at a time). TODO: optimize to a radix-2^32 algorithm, taking care
+ // to get the variable shifts right.
+ var quotient = new jspb.arith.UInt64(0, 0);
+ var remainder = new jspb.arith.UInt64(this.lo, this.hi);
+ var divisor = new jspb.arith.UInt64(_divisor, 0);
+ var unit = new jspb.arith.UInt64(1, 0);
+
+ // Left-shift the divisor and unit until the high bit of divisor is set.
+ while (!divisor.msb()) {
+ divisor = divisor.leftShift();
+ unit = unit.leftShift();
+ }
+
+ // Perform long division one bit at a time.
+ while (!unit.zero()) {
+ // If divisor < remainder, add unit to quotient and subtract divisor from
+ // remainder.
+ if (divisor.cmp(remainder) <= 0) {
+ quotient = quotient.add(unit);
+ remainder = remainder.sub(divisor);
+ }
+ // Right-shift the divisor and unit.
+ divisor = divisor.rightShift();
+ unit = unit.rightShift();
+ }
+
+ return [quotient, remainder];
+};
+
+
+/**
+ * Convert a 64-bit number to a string.
+ * @return {string}
+ * @override
+ */
+jspb.arith.UInt64.prototype.toString = function() {
+ var result = '';
+ var num = this;
+ while (!num.zero()) {
+ var divResult = num.div(10);
+ var quotient = divResult[0], remainder = divResult[1];
+ result = remainder.lo + result;
+ num = quotient;
+ }
+ if (result == '') {
+ result = '0';
+ }
+ return result;
+};
+
+
+/**
+ * Parse a string into a 64-bit number. Returns `null` on a parse error.
+ * @param {string} s
+ * @return {?jspb.arith.UInt64}
+ */
+jspb.arith.UInt64.fromString = function(s) {
+ var result = new jspb.arith.UInt64(0, 0);
+ // optimization: reuse this instance for each digit.
+ var digit64 = new jspb.arith.UInt64(0, 0);
+ for (var i = 0; i < s.length; i++) {
+ if (s[i] < '0' || s[i] > '9') {
+ return null;
+ }
+ var digit = parseInt(s[i], 10);
+ digit64.lo = digit;
+ result = result.mul(10).add(digit64);
+ }
+ return result;
+};
+
+
+/**
+ * Make a copy of the uint64.
+ * @return {!jspb.arith.UInt64}
+ */
+jspb.arith.UInt64.prototype.clone = function() {
+ return new jspb.arith.UInt64(this.lo, this.hi);
+};
+
+
+/**
+ * Int64 is like UInt64, but modifies string conversions to interpret the stored
+ * 64-bit value as a twos-complement-signed integer. It does *not* support the
+ * full range of operations that UInt64 does: only add, subtract, and string
+ * conversions.
+ *
+ * N.B. that multiply and divide routines are *NOT* supported. They will throw
+ * exceptions. (They are not necessary to implement string conversions, which
+ * are the only operations we really need in jspb.)
+ *
+ * @param {number} lo The low 32 bits.
+ * @param {number} hi The high 32 bits.
+ * @constructor
+ */
+jspb.arith.Int64 = function(lo, hi) {
+ /**
+ * The low 32 bits.
+ * @public {number}
+ */
+ this.lo = lo;
+ /**
+ * The high 32 bits.
+ * @public {number}
+ */
+ this.hi = hi;
+};
+
+
+/**
+ * Add two 64-bit numbers to produce a 64-bit number.
+ * @param {!jspb.arith.Int64} other
+ * @return {!jspb.arith.Int64}
+ */
+jspb.arith.Int64.prototype.add = function(other) {
+ var lo = ((this.lo + other.lo) & 0xffffffff) >>> 0;
+ var hi =
+ (((this.hi + other.hi) & 0xffffffff) >>> 0) +
+ (((this.lo + other.lo) >= 0x100000000) ? 1 : 0);
+ return new jspb.arith.Int64(lo >>> 0, hi >>> 0);
+};
+
+
+/**
+ * Subtract two 64-bit numbers to produce a 64-bit number.
+ * @param {!jspb.arith.Int64} other
+ * @return {!jspb.arith.Int64}
+ */
+jspb.arith.Int64.prototype.sub = function(other) {
+ var lo = ((this.lo - other.lo) & 0xffffffff) >>> 0;
+ var hi =
+ (((this.hi - other.hi) & 0xffffffff) >>> 0) -
+ (((this.lo - other.lo) < 0) ? 1 : 0);
+ return new jspb.arith.Int64(lo >>> 0, hi >>> 0);
+};
+
+
+/**
+ * Make a copy of the int64.
+ * @return {!jspb.arith.Int64}
+ */
+jspb.arith.Int64.prototype.clone = function() {
+ return new jspb.arith.Int64(this.lo, this.hi);
+};
+
+
+/**
+ * Convert a 64-bit number to a string.
+ * @return {string}
+ * @override
+ */
+jspb.arith.Int64.prototype.toString = function() {
+ // If the number is negative, find its twos-complement inverse.
+ var sign = (this.hi & 0x80000000) != 0;
+ var num = new jspb.arith.UInt64(this.lo, this.hi);
+ if (sign) {
+ num = new jspb.arith.UInt64(0, 0).sub(num);
+ }
+ return (sign ? '-' : '') + num.toString();
+};
+
+
+/**
+ * Parse a string into a 64-bit number. Returns `null` on a parse error.
+ * @param {string} s
+ * @return {?jspb.arith.Int64}
+ */
+jspb.arith.Int64.fromString = function(s) {
+ var hasNegative = (s.length > 0 && s[0] == '-');
+ if (hasNegative) {
+ s = s.substring(1);
+ }
+ var num = jspb.arith.UInt64.fromString(s);
+ if (num === null) {
+ return null;
+ }
+ if (hasNegative) {
+ num = new jspb.arith.UInt64(0, 0).sub(num);
+ }
+ return new jspb.arith.Int64(num.lo, num.hi);
+};
diff --git a/js/binary/arith_test.js b/js/binary/arith_test.js
new file mode 100644
index 00000000..89796bf7
--- /dev/null
+++ b/js/binary/arith_test.js
@@ -0,0 +1,355 @@
+// 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.
+
+/**
+ * @fileoverview Test cases for Int64-manipulation functions.
+ *
+ * Test suite is written using Jasmine -- see http://jasmine.github.io/
+ *
+ * @author cfallin@google.com (Chris Fallin)
+ */
+
+goog.require('goog.testing.asserts');
+goog.require('jspb.arith.Int64');
+goog.require('jspb.arith.UInt64');
+
+
+describe('binaryArithTest', function() {
+ /**
+ * Tests comparison operations.
+ */
+ it('testCompare', function() {
+ var a = new jspb.arith.UInt64(1234, 5678);
+ var b = new jspb.arith.UInt64(1234, 5678);
+ assertEquals(a.cmp(b), 0);
+ assertEquals(b.cmp(a), 0);
+ b.lo -= 1;
+ assertEquals(a.cmp(b), 1);
+ assertEquals(b.cmp(a), -1);
+ b.lo += 2;
+ assertEquals(a.cmp(b), -1);
+ assertEquals(b.cmp(a), 1);
+ b.lo = a.lo;
+ b.hi = a.hi - 1;
+ assertEquals(a.cmp(b), 1);
+ assertEquals(b.cmp(a), -1);
+
+ assertEquals(a.zero(), false);
+ assertEquals(a.msb(), false);
+ assertEquals(a.lsb(), false);
+ a.hi = 0;
+ a.lo = 0;
+ assertEquals(a.zero(), true);
+ a.hi = 0x80000000;
+ assertEquals(a.zero(), false);
+ assertEquals(a.msb(), true);
+ a.lo = 0x00000001;
+ assertEquals(a.lsb(), true);
+ });
+
+
+ /**
+ * Tests shifts.
+ */
+ it('testShifts', function() {
+ var a = new jspb.arith.UInt64(1, 0);
+ assertEquals(a.lo, 1);
+ assertEquals(a.hi, 0);
+ var orig = a;
+ a = a.leftShift();
+ assertEquals(orig.lo, 1); // original unmodified.
+ assertEquals(orig.hi, 0);
+ assertEquals(a.lo, 2);
+ assertEquals(a.hi, 0);
+ a = a.leftShift();
+ assertEquals(a.lo, 4);
+ assertEquals(a.hi, 0);
+ for (var i = 0; i < 29; i++) {
+ a = a.leftShift();
+ }
+ assertEquals(a.lo, 0x80000000);
+ assertEquals(a.hi, 0);
+ a = a.leftShift();
+ assertEquals(a.lo, 0);
+ assertEquals(a.hi, 1);
+ a = a.leftShift();
+ assertEquals(a.lo, 0);
+ assertEquals(a.hi, 2);
+ a = a.rightShift();
+ a = a.rightShift();
+ assertEquals(a.lo, 0x80000000);
+ assertEquals(a.hi, 0);
+ a = a.rightShift();
+ assertEquals(a.lo, 0x40000000);
+ assertEquals(a.hi, 0);
+ });
+
+
+ /**
+ * Tests additions.
+ */
+ it('testAdd', function() {
+ var a = new jspb.arith.UInt64(/* lo = */ 0x89abcdef,
+ /* hi = */ 0x01234567);
+ var b = new jspb.arith.UInt64(/* lo = */ 0xff52ab91,
+ /* hi = */ 0x92fa2123);
+ // Addition with carry.
+ var c = a.add(b);
+ assertEquals(a.lo, 0x89abcdef); // originals unmodified.
+ assertEquals(a.hi, 0x01234567);
+ assertEquals(b.lo, 0xff52ab91);
+ assertEquals(b.hi, 0x92fa2123);
+ assertEquals(c.lo, 0x88fe7980);
+ assertEquals(c.hi, 0x941d668b);
+
+ // Simple addition without carry.
+ a.lo = 2;
+ a.hi = 0;
+ b.lo = 3;
+ b.hi = 0;
+ c = a.add(b);
+ assertEquals(c.lo, 5);
+ assertEquals(c.hi, 0);
+ });
+
+
+ /**
+ * Test subtractions.
+ */
+ it('testSub', function() {
+ var kLength = 10;
+ var hiValues = [0x1682ef32,
+ 0x583902f7,
+ 0xb62f5955,
+ 0x6ea99bbf,
+ 0x25a39c20,
+ 0x0700a08b,
+ 0x00f7304d,
+ 0x91a5b5af,
+ 0x89077fd2,
+ 0xe09e347c];
+ var loValues = [0xe1538b18,
+ 0xbeacd556,
+ 0x74100758,
+ 0x96e3cb26,
+ 0x56c37c3f,
+ 0xe00b3f7d,
+ 0x859f25d7,
+ 0xc2ee614a,
+ 0xe1d21cd7,
+ 0x30aae6a4];
+ for (var i = 0; i < kLength; i++) {
+ for (var j = 0; j < kLength; j++) {
+ var a = new jspb.arith.UInt64(loValues[i], hiValues[j]);
+ var b = new jspb.arith.UInt64(loValues[j], hiValues[i]);
+ var c = a.add(b).sub(b);
+ assertEquals(c.hi, a.hi);
+ assertEquals(c.lo, a.lo);
+ }
+ }
+ });
+
+
+ /**
+ * Tests 32-by-32 multiplication.
+ */
+ it('testMul32x32', function() {
+ var testData = [
+ // a b low(a*b) high(a*b)
+ [0xc0abe2f8, 0x1607898a, 0x5de711b0, 0x109471b8],
+ [0x915eb3cb, 0x4fb66d0e, 0xbd0d441a, 0x2d43d0bc],
+ [0xfe4efe70, 0x80b48c37, 0xbcddea10, 0x7fdada0c],
+ [0xe222fd4a, 0xe43d524a, 0xd5e0eb64, 0xc99d549c],
+ [0xd171f469, 0xb94ebd01, 0x4be17969, 0x979bc4fa],
+ [0x829cc1df, 0xe2598b38, 0xf4157dc8, 0x737c12ad],
+ [0xf10c3767, 0x8382881e, 0x942b3612, 0x7bd428b8],
+ [0xb0f6dd24, 0x232597e1, 0x079c98a4, 0x184bbce7],
+ [0xfcdb05a7, 0x902f55bc, 0x636199a4, 0x8e69f412],
+ [0x0dd0bfa9, 0x916e27b1, 0x6e2542d9, 0x07d92e65]
+ ];
+
+ for (var i = 0; i < testData.length; i++) {
+ var a = testData[i][0] >>> 0;
+ var b = testData[i][1] >>> 0;
+ var cLow = testData[i][2] >>> 0;
+ var cHigh = testData[i][3] >>> 0;
+ var c = jspb.arith.UInt64.mul32x32(a, b);
+ assertEquals(c.lo, cLow);
+ assertEquals(c.hi, cHigh);
+ }
+ });
+
+
+ /**
+ * Tests 64-by-32 multiplication.
+ */
+ it('testMul', function() {
+ // 64x32 bits produces 96 bits of product. The multiplication function under
+ // test truncates the top 32 bits, so we compare against a 64-bit expected
+ // product.
+ var testData = [
+ // low(a) high(a) low(a*b) high(a*b)
+ [0xec10955b, 0x360eb168, 0x4b7f3f5b, 0xbfcb7c59, 0x9517da5f],
+ [0x42b000fc, 0x9d101642, 0x6fa1ab72, 0x2584c438, 0x6a9e6d2b],
+ [0xf42d4fb4, 0xae366403, 0xa65a1000, 0x92434000, 0x1ff978df],
+ [0x17e2f56b, 0x25487693, 0xf13f98c7, 0x73794e2d, 0xa96b0c6a],
+ [0x492f241f, 0x76c0eb67, 0x7377ac44, 0xd4336c3c, 0xfc4b1ebe],
+ [0xd6b92321, 0xe184fa48, 0xd6e76904, 0x93141584, 0xcbf44da1],
+ [0x4bf007ea, 0x968c0a9e, 0xf5e4026a, 0x4fdb1ae4, 0x61b9fb7d],
+ [0x10a83be7, 0x2d685ba6, 0xc9e5fb7f, 0x2ad43499, 0x3742473d],
+ [0x2f261829, 0x1aca681a, 0x3d3494e3, 0x8213205b, 0x283719f8],
+ [0xe4f2ce21, 0x2e74b7bd, 0xd801b38b, 0xbc17feeb, 0xc6c44e0f]
+ ];
+
+ for (var i = 0; i < testData.length; i++) {
+ var a = new jspb.arith.UInt64(testData[i][0], testData[i][1]);
+ var prod = a.mul(testData[i][2]);
+ assertEquals(prod.lo, testData[i][3]);
+ assertEquals(prod.hi, testData[i][4]);
+ }
+ });
+
+
+ /**
+ * Tests 64-div-by-32 division.
+ */
+ it('testDiv', function() {
+ // Compute a/b, yielding quot = a/b and rem = a%b.
+ var testData = [
+ // --- divisors in (0, 2^32-1) to test full divisor range
+ // low(a) high(a) b low(quot) high(quot) rem
+ [0x712443f1, 0xe85cefcc, 0xc1a7050b, 0x332c79ad, 0x00000001, 0x92ffa882],
+ [0x11912915, 0xb2699eb5, 0x30467cbe, 0xb21b4be4, 0x00000003, 0x283465dd],
+ [0x0d917982, 0x201f2a6e, 0x3f35bf03, 0x8217c8e4, 0x00000000, 0x153402d6],
+ [0xa072c108, 0x74020c96, 0xc60568fd, 0x95f9613e, 0x00000000, 0x3f4676c2],
+ [0xd845d5d8, 0xcdd235c4, 0x20426475, 0x6154e78b, 0x00000006, 0x202fb751],
+ [0xa4dbf71f, 0x9e90465e, 0xf08e022f, 0xa8be947f, 0x00000000, 0xbe43b5ce],
+ [0x3dbe627f, 0xa791f4b9, 0x28a5bd89, 0x1f5dfe93, 0x00000004, 0x02bf9ed4],
+ [0x5c1c53ee, 0xccf5102e, 0x198576e7, 0x07e3ae31, 0x00000008, 0x02ea8fb7],
+ [0xfef1e581, 0x04714067, 0xca6540c1, 0x059e73ec, 0x00000000, 0x31658095],
+ [0x1e2dd90c, 0x13dd6667, 0x8b2184c3, 0x248d1a42, 0x00000000, 0x4ca6d0c6],
+ // --- divisors in (0, 2^16-1) to test larger quotient high-words
+ // low(a) high(a) b low(quot) high(quot) rem
+ [0x86722b47, 0x2cd57c9a, 0x00003123, 0x2ae41b7a, 0x0000e995, 0x00000f99],
+ [0x1dd7884c, 0xf5e839bc, 0x00009eeb, 0x5c886242, 0x00018c21, 0x000099b6],
+ [0x5c53d625, 0x899fc7e5, 0x000087d7, 0xd625007a, 0x0001035c, 0x000019af],
+ [0x6932d932, 0x9d0a5488, 0x000051fb, 0x9d976143, 0x0001ea63, 0x00004981],
+ [0x4d18bb85, 0x0c92fb31, 0x00001d9f, 0x03265ab4, 0x00006cac, 0x000001b9],
+ [0xbe756768, 0xdea67ccb, 0x00008a03, 0x58add442, 0x00019cff, 0x000056a2],
+ [0xe2466f9a, 0x2521f114, 0x0000c350, 0xa0c0860d, 0x000030ab, 0x0000a48a],
+ [0xf00ddad1, 0xe2f5446a, 0x00002cfc, 0x762697a6, 0x00050b96, 0x00000b69],
+ [0xa879152a, 0x0a70e0a5, 0x00007cdf, 0xb44151b3, 0x00001567, 0x0000363d],
+ [0x7179a74c, 0x46083fff, 0x0000253c, 0x4d39ba6e, 0x0001e17f, 0x00000f84]
+ ];
+
+ for (var i = 0; i < testData.length; i++) {
+ var a = new jspb.arith.UInt64(testData[i][0], testData[i][1]);
+ var result = a.div(testData[i][2]);
+ var quotient = result[0];
+ var remainder = result[1];
+ assertEquals(quotient.lo, testData[i][3]);
+ assertEquals(quotient.hi, testData[i][4]);
+ assertEquals(remainder.lo, testData[i][5]);
+ }
+ });
+
+
+ /**
+ * Tests .toString() and .fromString().
+ */
+ it('testStrings', function() {
+ var testData = [
+ [0x5e84c935, 0xcae33d0e, '14619595947299359029'],
+ [0x62b3b8b8, 0x93480544, '10612738313170434232'],
+ [0x319bfb13, 0xc01c4172, '13843011313344445203'],
+ [0x5b8a65fb, 0xa5885b31, '11927883880638080507'],
+ [0x6bdb80f1, 0xb0d1b16b, '12741159895737008369'],
+ [0x4b82b442, 0x2e0d8c97, '3318463081876730946'],
+ [0x780d5208, 0x7d76752c, '9040542135845999112'],
+ [0x2e46800f, 0x0993778d, '690026616168284175'],
+ [0xf00a7e32, 0xcd8e3931, '14811839111111540274'],
+ [0x1baeccd6, 0x923048c4, '10533999535534820566'],
+ [0x03669d29, 0xbff3ab72, '13831587386756603177'],
+ [0x2526073e, 0x01affc81, '121593346566522686'],
+ [0xc24244e0, 0xd7f40d0e, '15561076969511732448'],
+ [0xc56a341e, 0xa68b66a7, '12000798502816461854'],
+ [0x8738d64d, 0xbfe78604, '13828168534871037517'],
+ [0x5baff03b, 0xd7572aea, '15516918227177304123'],
+ [0x4a843d8a, 0x864e132b, '9677693725920476554'],
+ [0x25b4e94d, 0x22b54dc6, '2500990681505655117'],
+ [0x6bbe664b, 0x55a5cc0e, '6171563226690381387'],
+ [0xee916c81, 0xb00aabb3, '12685140089732426881']
+ ];
+
+ for (var i = 0; i < testData.length; i++) {
+ var a = new jspb.arith.UInt64(testData[i][0], testData[i][1]);
+ var roundtrip = jspb.arith.UInt64.fromString(a.toString());
+ assertEquals(roundtrip.lo, a.lo);
+ assertEquals(roundtrip.hi, a.hi);
+ assertEquals(a.toString(), testData[i][2]);
+ }
+ });
+
+
+ /**
+ * Tests signed Int64s. These are built on UInt64s, so we only need to test
+ * the explicit overrides: .toString() and .fromString().
+ */
+ it('testSignedInt64', function() {
+ var testStrings = [
+ '-7847499644178593666',
+ '3771946501229139523',
+ '2872856549054995060',
+ '-5780049594274350904',
+ '3383785956695105201',
+ '2973055184857072610',
+ '-3879428459215627206',
+ '4589812431064156631',
+ '8484075557333689940',
+ '1075325817098092407',
+ '-4346697501012292314',
+ '2488620459718316637',
+ '6112655187423520672',
+ '-3655278273928612104',
+ '3439154019435803196',
+ '1004112478843763757',
+ '-6587790776614368413',
+ '664320065099714586',
+ '4760412909973292912',
+ '-7911903989602274672'
+ ];
+
+ for (var i = 0; i < testStrings.length; i++) {
+ var roundtrip =
+ jspb.arith.Int64.fromString(testStrings[i]).toString();
+ assertEquals(roundtrip, testStrings[i]);
+ }
+ });
+});
diff --git a/js/binary/constants.js b/js/binary/constants.js
new file mode 100644
index 00000000..ef5fecdd
--- /dev/null
+++ b/js/binary/constants.js
@@ -0,0 +1,360 @@
+// 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.
+
+/**
+ * @fileoverview This file contains constants and typedefs used by
+ * jspb.BinaryReader and BinaryWriter.
+ *
+ * @author aappleby@google.com (Austin Appleby)
+ */
+
+goog.provide('jspb.AnyFieldType');
+goog.provide('jspb.BinaryConstants');
+goog.provide('jspb.BinaryMessage');
+goog.provide('jspb.BuilderFunction');
+goog.provide('jspb.ByteSource');
+goog.provide('jspb.ClonerFunction');
+goog.provide('jspb.ComparerFunction');
+goog.provide('jspb.ConstBinaryMessage');
+goog.provide('jspb.PrunerFunction');
+goog.provide('jspb.ReaderFunction');
+goog.provide('jspb.RecyclerFunction');
+goog.provide('jspb.RepeatedFieldType');
+goog.provide('jspb.ScalarFieldType');
+goog.provide('jspb.WriterFunction');
+
+
+goog.forwardDeclare('jspb.Message');
+goog.forwardDeclare('jsproto.BinaryExtension');
+
+
+
+/**
+ * Base interface class for all const messages. Does __not__ define any
+ * methods, as doing so on a widely-used interface defeats dead-code
+ * elimination.
+ * @interface
+ */
+jspb.ConstBinaryMessage = function() {};
+
+
+
+/**
+ * Base interface class for all messages. Does __not__ define any methods, as
+ * doing so on a widely-used interface defeats dead-code elimination.
+ * @interface
+ * @extends {jspb.ConstBinaryMessage}
+ */
+jspb.BinaryMessage = function() {};
+
+
+/**
+ * The types convertible to Uint8Arrays. Strings are assumed to be
+ * base64-encoded.
+ * @typedef {ArrayBuffer|Uint8Array|Array<number>|string}
+ */
+jspb.ByteSource;
+
+
+/**
+ * A scalar field in jspb can be a boolean, number, or string.
+ * @typedef {boolean|number|string}
+ */
+jspb.ScalarFieldType;
+
+
+/**
+ * A repeated field in jspb is an array of scalars, blobs, or messages.
+ * @typedef {!Array<jspb.ScalarFieldType>|
+ !Array<!Uint8Array>|
+ !Array<!jspb.BinaryMessage>}
+ */
+jspb.RepeatedFieldType;
+
+
+/**
+ * A field in jspb can be a scalar, a block of bytes, another proto, or an
+ * array of any of the above.
+ * @typedef {jspb.ScalarFieldType|
+ jspb.RepeatedFieldType|
+ !Uint8Array|
+ !jspb.BinaryMessage|
+ !jsproto.BinaryExtension}
+ */
+jspb.AnyFieldType;
+
+
+/**
+ * A builder function creates an instance of a message object.
+ * @typedef {function():!jspb.BinaryMessage}
+ */
+jspb.BuilderFunction;
+
+
+/**
+ * A cloner function creates a deep copy of a message object.
+ * @typedef {function(jspb.ConstBinaryMessage):jspb.BinaryMessage}
+ */
+jspb.ClonerFunction;
+
+
+/**
+ * A recycler function destroys an instance of a message object.
+ * @typedef {function(!jspb.BinaryMessage):void}
+ */
+jspb.RecyclerFunction;
+
+
+/**
+ * A reader function initializes a message using data from a BinaryReader.
+ * @typedef {function(!jspb.BinaryMessage, !jspb.BinaryReader):void}
+ */
+jspb.ReaderFunction;
+
+
+/**
+ * A writer function serializes a message to a BinaryWriter.
+ * @typedef {function((!jspb.Message|!jspb.ConstBinaryMessage),
+ * !jspb.BinaryWriter):void}
+ */
+jspb.WriterFunction;
+
+
+/**
+ * A pruner function removes default-valued fields and empty submessages from a
+ * message and returns either the pruned message or null if the entire message
+ * was pruned away.
+ * @typedef {function(?jspb.BinaryMessage):?jspb.BinaryMessage}
+ */
+jspb.PrunerFunction;
+
+
+/**
+ * A comparer function returns true if two protos are equal.
+ * @typedef {!function(?jspb.ConstBinaryMessage,
+ * ?jspb.ConstBinaryMessage):boolean}
+ */
+jspb.ComparerFunction;
+
+
+/**
+ * Field type codes, taken from proto2/public/wire_format_lite.h.
+ * @enum {number}
+ */
+jspb.BinaryConstants.FieldType = {
+ INVALID: -1,
+ DOUBLE: 1,
+ FLOAT: 2,
+ INT64: 3,
+ UINT64: 4,
+ INT32: 5,
+ FIXED64: 6,
+ FIXED32: 7,
+ BOOL: 8,
+ STRING: 9,
+ GROUP: 10,
+ MESSAGE: 11,
+ BYTES: 12,
+ UINT32: 13,
+ ENUM: 14,
+ SFIXED32: 15,
+ SFIXED64: 16,
+ SINT32: 17,
+ SINT64: 18,
+
+ // Extended types for Javascript
+
+ FHASH64: 30, // 64-bit hash string, fixed-length encoding.
+ VHASH64: 31 // 64-bit hash string, varint encoding.
+};
+
+
+/**
+ * Wire-format type codes, taken from proto2/public/wire_format_lite.h.
+ * @enum {number}
+ */
+jspb.BinaryConstants.WireType = {
+ INVALID: -1,
+ VARINT: 0,
+ FIXED64: 1,
+ DELIMITED: 2,
+ START_GROUP: 3,
+ END_GROUP: 4,
+ FIXED32: 5
+};
+
+
+/**
+ * Translates field type to wire type.
+ * @param {jspb.BinaryConstants.FieldType} fieldType
+ * @return {jspb.BinaryConstants.WireType}
+ */
+jspb.BinaryConstants.FieldTypeToWireType = function(fieldType) {
+ var fieldTypes = jspb.BinaryConstants.FieldType;
+ var wireTypes = jspb.BinaryConstants.WireType;
+ switch (fieldType) {
+ case fieldTypes.INT32:
+ case fieldTypes.INT64:
+ case fieldTypes.UINT32:
+ case fieldTypes.UINT64:
+ case fieldTypes.SINT32:
+ case fieldTypes.SINT64:
+ case fieldTypes.BOOL:
+ case fieldTypes.ENUM:
+ case fieldTypes.VHASH64:
+ return wireTypes.VARINT;
+
+ case fieldTypes.DOUBLE:
+ case fieldTypes.FIXED64:
+ case fieldTypes.SFIXED64:
+ case fieldTypes.FHASH64:
+ return wireTypes.FIXED64;
+
+ case fieldTypes.STRING:
+ case fieldTypes.MESSAGE:
+ case fieldTypes.BYTES:
+ return wireTypes.DELIMITED;
+
+ case fieldTypes.FLOAT:
+ case fieldTypes.FIXED32:
+ case fieldTypes.SFIXED32:
+ return wireTypes.FIXED32;
+
+ case fieldTypes.INVALID:
+ case fieldTypes.GROUP:
+ default:
+ return wireTypes.INVALID;
+ }
+};
+
+
+/**
+ * Flag to indicate a missing field.
+ * @const {number}
+ */
+jspb.BinaryConstants.INVALID_FIELD_NUMBER = -1;
+
+
+/**
+ * The smallest denormal float32 value.
+ * @const {number}
+ */
+jspb.BinaryConstants.FLOAT32_EPS = 1.401298464324817e-45;
+
+
+/**
+ * The smallest normal float64 value.
+ * @const {number}
+ */
+jspb.BinaryConstants.FLOAT32_MIN = 1.1754943508222875e-38;
+
+
+/**
+ * The largest finite float32 value.
+ * @const {number}
+ */
+jspb.BinaryConstants.FLOAT32_MAX = 3.4028234663852886e+38;
+
+
+/**
+ * The smallest denormal float64 value.
+ * @const {number}
+ */
+jspb.BinaryConstants.FLOAT64_EPS = 5e-324;
+
+
+/**
+ * The smallest normal float64 value.
+ * @const {number}
+ */
+jspb.BinaryConstants.FLOAT64_MIN = 2.2250738585072014e-308;
+
+
+/**
+ * The largest finite float64 value.
+ * @const {number}
+ */
+jspb.BinaryConstants.FLOAT64_MAX = 1.7976931348623157e+308;
+
+
+/**
+ * Convenience constant equal to 2^20.
+ * @const {number}
+ */
+jspb.BinaryConstants.TWO_TO_20 = 1048576;
+
+
+/**
+ * Convenience constant equal to 2^23.
+ * @const {number}
+ */
+jspb.BinaryConstants.TWO_TO_23 = 8388608;
+
+
+/**
+ * Convenience constant equal to 2^31.
+ * @const {number}
+ */
+jspb.BinaryConstants.TWO_TO_31 = 2147483648;
+
+
+/**
+ * Convenience constant equal to 2^32.
+ * @const {number}
+ */
+jspb.BinaryConstants.TWO_TO_32 = 4294967296;
+
+
+/**
+ * Convenience constant equal to 2^52.
+ * @const {number}
+ */
+jspb.BinaryConstants.TWO_TO_52 = 4503599627370496;
+
+
+/**
+ * Convenience constant equal to 2^63.
+ * @const {number}
+ */
+jspb.BinaryConstants.TWO_TO_63 = 9223372036854775808;
+
+
+/**
+ * Convenience constant equal to 2^64.
+ * @const {number}
+ */
+jspb.BinaryConstants.TWO_TO_64 = 18446744073709551616;
+
+
+/**
+ * Eight-character string of zeros, used as the default 64-bit hash value.
+ * @const {string}
+ */
+jspb.BinaryConstants.ZERO_HASH = '\0\0\0\0\0\0\0\0';
diff --git a/js/binary/decoder.js b/js/binary/decoder.js
new file mode 100644
index 00000000..41094a36
--- /dev/null
+++ b/js/binary/decoder.js
@@ -0,0 +1,1007 @@
+// 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.
+
+/**
+ * @fileoverview This file contains utilities for decoding primitive values
+ * (signed and unsigned integers, varints, booleans, enums, hashes, strings,
+ * and raw bytes) embedded in Uint8Arrays into their corresponding Javascript
+ * types.
+ *
+ * Major caveat - Javascript is unable to accurately represent integers larger
+ * than 2^53 due to its use of a double-precision floating point format or all
+ * numbers. If you need to guarantee that 64-bit values survive with all bits
+ * intact, you _must_ read them using one of the Hash64 methods, which return
+ * an 8-character string.
+ *
+ * @author aappleby@google.com (Austin Appleby)
+ */
+
+goog.provide('jspb.BinaryDecoder');
+goog.provide('jspb.BinaryIterator');
+
+goog.require('goog.asserts');
+goog.require('jspb.utils');
+
+
+
+/**
+ * Simple helper class for traversing the contents of repeated scalar fields.
+ * that may or may not have been packed into a wire-format blob.
+ * @param {?jspb.BinaryDecoder=} opt_decoder
+ * @param {?function(this:jspb.BinaryDecoder):(number|boolean|string)=}
+ * opt_next The decoder method to use for next().
+ * @param {?Array.<number|boolean|string>=} opt_elements
+ * @constructor
+ * @struct
+ */
+jspb.BinaryIterator = function(opt_decoder, opt_next, opt_elements) {
+ /** @private {jspb.BinaryDecoder} */
+ this.decoder_ = null;
+
+ /**
+ * The BinaryDecoder member function used when iterating over packed data.
+ * @private {?function(this:jspb.BinaryDecoder):(number|boolean|string)}
+ */
+ this.nextMethod_ = null;
+
+ /** @private {Array.<number>} */
+ this.elements_ = null;
+
+ /** @private {number} */
+ this.cursor_ = 0;
+
+ /** @private {number|boolean|string|null} */
+ this.nextValue_ = null;
+
+ /** @private {boolean} */
+ this.atEnd_ = true;
+
+ this.init_(opt_decoder, opt_next, opt_elements);
+};
+
+
+/**
+ * @param {?jspb.BinaryDecoder=} opt_decoder
+ * @param {?function(this:jspb.BinaryDecoder):(number|boolean|string)=}
+ * opt_next The decoder method to use for next().
+ * @param {?Array.<number|boolean|string>=} opt_elements
+ * @private
+ */
+jspb.BinaryIterator.prototype.init_ =
+ function(opt_decoder, opt_next, opt_elements) {
+ if (opt_decoder && opt_next) {
+ this.decoder_ = opt_decoder;
+ this.nextMethod_ = opt_next;
+ }
+ this.elements_ = opt_elements ? opt_elements : null;
+ this.cursor_ = 0;
+ this.nextValue_ = null;
+ this.atEnd_ = !this.decoder_ && !this.elements_;
+
+ this.next();
+};
+
+
+/**
+ * Global pool of BinaryIterator instances.
+ * @private {!Array.<!jspb.BinaryIterator>}
+ */
+jspb.BinaryIterator.instanceCache_ = [];
+
+
+/**
+ * Allocates a BinaryIterator from the cache, creating a new one if the cache
+ * is empty.
+ * @param {?jspb.BinaryDecoder=} opt_decoder
+ * @param {?function(this:jspb.BinaryDecoder):(number|boolean|string)=}
+ * opt_next The decoder method to use for next().
+ * @param {?Array.<number|boolean|string>=} opt_elements
+ * @return {!jspb.BinaryIterator}
+ */
+jspb.BinaryIterator.alloc = function(opt_decoder, opt_next, opt_elements) {
+ if (jspb.BinaryIterator.instanceCache_.length) {
+ var iterator = jspb.BinaryIterator.instanceCache_.pop();
+ iterator.init_(opt_decoder, opt_next, opt_elements);
+ return iterator;
+ } else {
+ return new jspb.BinaryIterator(opt_decoder, opt_next, opt_elements);
+ }
+};
+
+
+/**
+ * Puts this instance back in the instance cache.
+ */
+jspb.BinaryIterator.prototype.free = function() {
+ this.clear();
+ if (jspb.BinaryIterator.instanceCache_.length < 100) {
+ jspb.BinaryIterator.instanceCache_.push(this);
+ }
+};
+
+
+/**
+ * Clears the iterator.
+ */
+jspb.BinaryIterator.prototype.clear = function() {
+ if (this.decoder_) {
+ this.decoder_.free();
+ }
+ this.decoder_ = null;
+ this.nextMethod_ = null;
+ this.elements_ = null;
+ this.cursor_ = 0;
+ this.nextValue_ = null;
+ this.atEnd_ = true;
+};
+
+
+/**
+ * Returns the element at the iterator, or null if the iterator is invalid or
+ * past the end of the decoder/array.
+ * @return {number|boolean|string|null}
+ */
+jspb.BinaryIterator.prototype.get = function() {
+ return this.nextValue_;
+};
+
+
+/**
+ * Returns true if the iterator is at the end of the decoder/array.
+ * @return {boolean}
+ */
+jspb.BinaryIterator.prototype.atEnd = function() {
+ return this.atEnd_;
+};
+
+
+/**
+ * Returns the element at the iterator and steps to the next element,
+ * equivalent to '*pointer++' in C.
+ * @return {number|boolean|string|null}
+ */
+jspb.BinaryIterator.prototype.next = function() {
+ var lastValue = this.nextValue_;
+ if (this.decoder_) {
+ if (this.decoder_.atEnd()) {
+ this.nextValue_ = null;
+ this.atEnd_ = true;
+ } else {
+ this.nextValue_ = this.nextMethod_.call(this.decoder_);
+ }
+ } else if (this.elements_) {
+ if (this.cursor_ == this.elements_.length) {
+ this.nextValue_ = null;
+ this.atEnd_ = true;
+ } else {
+ this.nextValue_ = this.elements_[this.cursor_++];
+ }
+ }
+ return lastValue;
+};
+
+
+
+/**
+ * BinaryDecoder implements the decoders for all the wire types specified in
+ * https://developers.google.com/protocol-buffers/docs/encoding.
+ *
+ * @param {jspb.ByteSource=} opt_bytes The bytes we're reading from.
+ * @param {number=} opt_start The optional offset to start reading at.
+ * @param {number=} opt_length The optional length of the block to read -
+ * we'll throw an assertion if we go off the end of the block.
+ * @constructor
+ * @struct
+ */
+jspb.BinaryDecoder = function(opt_bytes, opt_start, opt_length) {
+ /**
+ * Typed byte-wise view of the source buffer.
+ * @private {?Uint8Array}
+ */
+ this.bytes_ = null;
+
+ /**
+ * Start point of the block to read.
+ * @private {number}
+ */
+ this.start_ = 0;
+
+ /**
+ * End point of the block to read.
+ * @private {number}
+ */
+ this.end_ = 0;
+
+ /**
+ * Current read location in bytes_.
+ * @private {number}
+ */
+ this.cursor_ = 0;
+
+ /**
+ * Temporary storage for the low 32 bits of 64-bit data types that we're
+ * decoding.
+ * @private {number}
+ */
+ this.tempLow_ = 0;
+
+ /**
+ * Temporary storage for the high 32 bits of 64-bit data types that we're
+ * decoding.
+ * @private {number}
+ */
+ this.tempHigh_ = 0;
+
+ /**
+ * Set to true if this decoder encountered an error due to corrupt data.
+ * @private {boolean}
+ */
+ this.error_ = false;
+
+ if (opt_bytes) {
+ this.setBlock(opt_bytes, opt_start, opt_length);
+ }
+};
+
+
+/**
+ * Global pool of BinaryDecoder instances.
+ * @private {!Array.<!jspb.BinaryDecoder>}
+ */
+jspb.BinaryDecoder.instanceCache_ = [];
+
+
+/**
+ * Pops an instance off the instance cache, or creates one if the cache is
+ * empty.
+ * @param {jspb.ByteSource=} opt_bytes The bytes we're reading from.
+ * @param {number=} opt_start The optional offset to start reading at.
+ * @param {number=} opt_length The optional length of the block to read -
+ * we'll throw an assertion if we go off the end of the block.
+ * @return {!jspb.BinaryDecoder}
+ */
+jspb.BinaryDecoder.alloc = function(opt_bytes, opt_start, opt_length) {
+ if (jspb.BinaryDecoder.instanceCache_.length) {
+ var newDecoder = jspb.BinaryDecoder.instanceCache_.pop();
+ if (opt_bytes) {
+ newDecoder.setBlock(opt_bytes, opt_start, opt_length);
+ }
+ return newDecoder;
+ } else {
+ return new jspb.BinaryDecoder(opt_bytes, opt_start, opt_length);
+ }
+};
+
+
+/**
+ * Puts this instance back in the instance cache.
+ */
+jspb.BinaryDecoder.prototype.free = function() {
+ this.clear();
+ if (jspb.BinaryDecoder.instanceCache_.length < 100) {
+ jspb.BinaryDecoder.instanceCache_.push(this);
+ }
+};
+
+
+/**
+ * Makes a copy of this decoder.
+ * @return {!jspb.BinaryDecoder}
+ */
+jspb.BinaryDecoder.prototype.clone = function() {
+ return jspb.BinaryDecoder.alloc(this.bytes_,
+ this.start_, this.end_ - this.start_);
+};
+
+
+/**
+ * Clears the decoder.
+ */
+jspb.BinaryDecoder.prototype.clear = function() {
+ this.bytes_ = null;
+ this.start_ = 0;
+ this.end_ = 0;
+ this.cursor_ = 0;
+ this.error_ = false;
+};
+
+
+/**
+ * Returns the raw buffer.
+ * @return {?Uint8Array} The raw buffer.
+ */
+jspb.BinaryDecoder.prototype.getBuffer = function() {
+ return this.bytes_;
+};
+
+
+/**
+ * Changes the block of bytes we're decoding.
+ * @param {!jspb.ByteSource} data The bytes we're reading from.
+ * @param {number=} opt_start The optional offset to start reading at.
+ * @param {number=} opt_length The optional length of the block to read -
+ * we'll throw an assertion if we go off the end of the block.
+ */
+jspb.BinaryDecoder.prototype.setBlock =
+ function(data, opt_start, opt_length) {
+ this.bytes_ = jspb.utils.byteSourceToUint8Array(data);
+ this.start_ = goog.isDef(opt_start) ? opt_start : 0;
+ this.end_ =
+ goog.isDef(opt_length) ? this.start_ + opt_length : this.bytes_.length;
+ this.cursor_ = this.start_;
+};
+
+
+/**
+ * @return {number}
+ */
+jspb.BinaryDecoder.prototype.getEnd = function() {
+ return this.end_;
+};
+
+
+/**
+ * @param {number} end
+ */
+jspb.BinaryDecoder.prototype.setEnd = function(end) {
+ this.end_ = end;
+};
+
+
+/**
+ * Moves the read cursor back to the start of the block.
+ */
+jspb.BinaryDecoder.prototype.reset = function() {
+ this.cursor_ = this.start_;
+};
+
+
+/**
+ * Returns the internal read cursor.
+ * @return {number} The internal read cursor.
+ */
+jspb.BinaryDecoder.prototype.getCursor = function() {
+ return this.cursor_;
+};
+
+
+/**
+ * Returns the internal read cursor.
+ * @param {number} cursor The new cursor.
+ */
+jspb.BinaryDecoder.prototype.setCursor = function(cursor) {
+ this.cursor_ = cursor;
+};
+
+
+/**
+ * Advances the stream cursor by the given number of bytes.
+ * @param {number} count The number of bytes to advance by.
+ */
+jspb.BinaryDecoder.prototype.advance = function(count) {
+ this.cursor_ += count;
+ goog.asserts.assert(this.cursor_ <= this.end_);
+};
+
+
+/**
+ * Returns true if this decoder is at the end of the block.
+ * @return {boolean}
+ */
+jspb.BinaryDecoder.prototype.atEnd = function() {
+ return this.cursor_ == this.end_;
+};
+
+
+/**
+ * Returns true if this decoder is at the end of the block.
+ * @return {boolean}
+ */
+jspb.BinaryDecoder.prototype.pastEnd = function() {
+ return this.cursor_ > this.end_;
+};
+
+
+/**
+ * Returns true if this decoder encountered an error due to corrupt data.
+ * @return {boolean}
+ */
+jspb.BinaryDecoder.prototype.getError = function() {
+ return this.error_ ||
+ (this.cursor_ < 0) ||
+ (this.cursor_ > this.end_);
+};
+
+
+/**
+ * Reads an unsigned varint from the binary stream and stores it as a split
+ * 64-bit integer. Since this does not convert the value to a number, no
+ * precision is lost.
+ *
+ * It's possible for an unsigned varint to be incorrectly encoded - more than
+ * 64 bits' worth of data could be present. If this happens, this method will
+ * throw an error.
+ *
+ * Decoding varints requires doing some funny base-128 math - for more
+ * details on the format, see
+ * https://developers.google.com/protocol-buffers/docs/encoding
+ *
+ * @private
+ */
+jspb.BinaryDecoder.prototype.readSplitVarint64_ = function() {
+ var temp;
+ var lowBits = 0;
+ var highBits = 0;
+
+ // Read the first four bytes of the varint, stopping at the terminator if we
+ // see it.
+ for (var i = 0; i < 4; i++) {
+ temp = this.bytes_[this.cursor_++];
+ lowBits |= (temp & 0x7F) << (i * 7);
+ if (temp < 128) {
+ this.tempLow_ = lowBits >>> 0;
+ this.tempHigh_ = 0;
+ return;
+ }
+ }
+
+ // Read the fifth byte, which straddles the low and high dwords.
+ temp = this.bytes_[this.cursor_++];
+ lowBits |= (temp & 0x7F) << 28;
+ highBits |= (temp & 0x7F) >> 4;
+ if (temp < 128) {
+ this.tempLow_ = lowBits >>> 0;
+ this.tempHigh_ = highBits >>> 0;
+ return;
+ }
+
+ // Read the sixth through tenth byte.
+ for (var i = 0; i < 5; i++) {
+ temp = this.bytes_[this.cursor_++];
+ highBits |= (temp & 0x7F) << (i * 7 + 3);
+ if (temp < 128) {
+ this.tempLow_ = lowBits >>> 0;
+ this.tempHigh_ = highBits >>> 0;
+ return;
+ }
+ }
+
+ // If we did not see the terminator, the encoding was invalid.
+ goog.asserts.fail('Failed to read varint, encoding is invalid.');
+ this.error_ = true;
+};
+
+
+/**
+ * Skips over a varint in the block without decoding it.
+ */
+jspb.BinaryDecoder.prototype.skipVarint = function() {
+ while (this.bytes_[this.cursor_] & 0x80) {
+ this.cursor_++;
+ }
+ this.cursor_++;
+};
+
+
+/**
+ * Skips backwards over a varint in the block - to do this correctly, we have
+ * to know the value we're skipping backwards over or things are ambiguous.
+ * @param {number} value The varint value to unskip.
+ */
+jspb.BinaryDecoder.prototype.unskipVarint = function(value) {
+ while (value > 128) {
+ this.cursor_--;
+ value = value >>> 7;
+ }
+ this.cursor_--;
+};
+
+
+/**
+ * Reads a 32-bit varint from the binary stream. Due to a quirk of the encoding
+ * format and Javascript's handling of bitwise math, this actually works
+ * correctly for both signed and unsigned 32-bit varints.
+ *
+ * This function is called vastly more frequently than any other in
+ * BinaryDecoder, so it has been unrolled and tweaked for performance.
+ *
+ * If there are more than 32 bits of data in the varint, it _must_ be due to
+ * sign-extension. If we're in debug mode and the high 32 bits don't match the
+ * expected sign extension, this method will throw an error.
+ *
+ * Decoding varints requires doing some funny base-128 math - for more
+ * details on the format, see
+ * https://developers.google.com/protocol-buffers/docs/encoding
+ *
+ * @return {number} The decoded unsigned 32-bit varint.
+ */
+jspb.BinaryDecoder.prototype.readUnsignedVarint32 = function() {
+ var temp;
+ var bytes = this.bytes_;
+
+ temp = bytes[this.cursor_ + 0];
+ var x = (temp & 0x7F);
+ if (temp < 128) {
+ this.cursor_ += 1;
+ goog.asserts.assert(this.cursor_ <= this.end_);
+ return x;
+ }
+
+ temp = bytes[this.cursor_ + 1];
+ x |= (temp & 0x7F) << 7;
+ if (temp < 128) {
+ this.cursor_ += 2;
+ goog.asserts.assert(this.cursor_ <= this.end_);
+ return x;
+ }
+
+ temp = bytes[this.cursor_ + 2];
+ x |= (temp & 0x7F) << 14;
+ if (temp < 128) {
+ this.cursor_ += 3;
+ goog.asserts.assert(this.cursor_ <= this.end_);
+ return x;
+ }
+
+ temp = bytes[this.cursor_ + 3];
+ x |= (temp & 0x7F) << 21;
+ if (temp < 128) {
+ this.cursor_ += 4;
+ goog.asserts.assert(this.cursor_ <= this.end_);
+ return x;
+ }
+
+ temp = bytes[this.cursor_ + 4];
+ x |= (temp & 0x0F) << 28;
+ if (temp < 128) {
+ // We're reading the high bits of an unsigned varint. The byte we just read
+ // also contains bits 33 through 35, which we're going to discard. Those
+ // bits _must_ be zero, or the encoding is invalid.
+ goog.asserts.assert((temp & 0xF0) == 0);
+ this.cursor_ += 5;
+ goog.asserts.assert(this.cursor_ <= this.end_);
+ return x >>> 0;
+ }
+
+ // If we get here, we're reading the sign extension of a negative 32-bit int.
+ // We can skip these bytes, as we know in advance that they have to be all
+ // 1's if the varint is correctly encoded. Since we also know the value is
+ // negative, we don't have to coerce it to unsigned before we return it.
+
+ goog.asserts.assert((temp & 0xF0) == 0xF0);
+ goog.asserts.assert(bytes[this.cursor_ + 5] == 0xFF);
+ goog.asserts.assert(bytes[this.cursor_ + 6] == 0xFF);
+ goog.asserts.assert(bytes[this.cursor_ + 7] == 0xFF);
+ goog.asserts.assert(bytes[this.cursor_ + 8] == 0xFF);
+ goog.asserts.assert(bytes[this.cursor_ + 9] == 0x01);
+
+ this.cursor_ += 10;
+ goog.asserts.assert(this.cursor_ <= this.end_);
+ return x;
+};
+
+
+/**
+ * The readUnsignedVarint32 above deals with signed 32-bit varints correctly,
+ * so this is just an alias.
+ *
+ * @return {number} The decoded signed 32-bit varint.
+ */
+jspb.BinaryDecoder.prototype.readSignedVarint32 =
+ jspb.BinaryDecoder.prototype.readUnsignedVarint32;
+
+
+/**
+ * Reads a 32-bit unsigned variant and returns its value as a string.
+ *
+ * @return {string} The decoded unsigned 32-bit varint as a string.
+ */
+jspb.BinaryDecoder.prototype.readUnsignedVarint32String = function() {
+ // 32-bit integers fit in JavaScript numbers without loss of precision, so
+ // string variants of 32-bit varint readers can simply delegate then convert
+ // to string.
+ var value = this.readUnsignedVarint32();
+ return value.toString();
+};
+
+
+/**
+ * Reads a 32-bit signed variant and returns its value as a string.
+ *
+ * @return {string} The decoded signed 32-bit varint as a string.
+ */
+jspb.BinaryDecoder.prototype.readSignedVarint32String = function() {
+ // 32-bit integers fit in JavaScript numbers without loss of precision, so
+ // string variants of 32-bit varint readers can simply delegate then convert
+ // to string.
+ var value = this.readSignedVarint32();
+ return value.toString();
+};
+
+
+/**
+ * Reads a signed, zigzag-encoded 32-bit varint from the binary stream.
+ *
+ * Zigzag encoding is a modification of varint encoding that reduces the
+ * storage overhead for small negative integers - for more details on the
+ * format, see https://developers.google.com/protocol-buffers/docs/encoding
+ *
+ * @return {number} The decoded signed, zigzag-encoded 32-bit varint.
+ */
+jspb.BinaryDecoder.prototype.readZigzagVarint32 = function() {
+ var result = this.readUnsignedVarint32();
+ return (result >>> 1) ^ - (result & 1);
+};
+
+
+/**
+ * Reads an unsigned 64-bit varint from the binary stream. Note that since
+ * Javascript represents all numbers as double-precision floats, there will be
+ * precision lost if the absolute value of the varint is larger than 2^53.
+ *
+ * @return {number} The decoded unsigned varint. Precision will be lost if the
+ * integer exceeds 2^53.
+ */
+jspb.BinaryDecoder.prototype.readUnsignedVarint64 = function() {
+ this.readSplitVarint64_();
+ return jspb.utils.joinUint64(this.tempLow_, this.tempHigh_);
+};
+
+
+/**
+ * Reads an unsigned 64-bit varint from the binary stream and returns the value
+ * as a decimal string.
+ *
+ * @return {string} The decoded unsigned varint as a decimal string.
+ */
+jspb.BinaryDecoder.prototype.readUnsignedVarint64String = function() {
+ this.readSplitVarint64_();
+ return jspb.utils.joinUnsignedDecimalString(this.tempLow_, this.tempHigh_);
+};
+
+
+/**
+ * Reads a signed 64-bit varint from the binary stream. Note that since
+ * Javascript represents all numbers as double-precision floats, there will be
+ * precision lost if the absolute value of the varint is larger than 2^53.
+ *
+ * @return {number} The decoded signed varint. Precision will be lost if the
+ * integer exceeds 2^53.
+ */
+jspb.BinaryDecoder.prototype.readSignedVarint64 = function() {
+ this.readSplitVarint64_();
+ return jspb.utils.joinInt64(this.tempLow_, this.tempHigh_);
+};
+
+
+/**
+ * Reads an signed 64-bit varint from the binary stream and returns the value
+ * as a decimal string.
+ *
+ * @return {string} The decoded signed varint as a decimal string.
+ */
+jspb.BinaryDecoder.prototype.readSignedVarint64String = function() {
+ this.readSplitVarint64_();
+ return jspb.utils.joinSignedDecimalString(this.tempLow_, this.tempHigh_);
+};
+
+
+/**
+ * Reads a signed, zigzag-encoded 64-bit varint from the binary stream. Note
+ * that since Javascript represents all numbers as double-precision floats,
+ * there will be precision lost if the absolute value of the varint is larger
+ * than 2^53.
+ *
+ * Zigzag encoding is a modification of varint encoding that reduces the
+ * storage overhead for small negative integers - for more details on the
+ * format, see https://developers.google.com/protocol-buffers/docs/encoding
+ *
+ * @return {number} The decoded zigzag varint. Precision will be lost if the
+ * integer exceeds 2^53.
+ */
+jspb.BinaryDecoder.prototype.readZigzagVarint64 = function() {
+ this.readSplitVarint64_();
+ return jspb.utils.joinZigzag64(this.tempLow_, this.tempHigh_);
+};
+
+
+/**
+ * Reads a raw unsigned 8-bit integer from the binary stream.
+ *
+ * @return {number} The unsigned 8-bit integer read from the binary stream.
+ */
+jspb.BinaryDecoder.prototype.readUint8 = function() {
+ var a = this.bytes_[this.cursor_ + 0];
+ this.cursor_ += 1;
+ goog.asserts.assert(this.cursor_ <= this.end_);
+ return a;
+};
+
+
+/**
+ * Reads a raw unsigned 16-bit integer from the binary stream.
+ *
+ * @return {number} The unsigned 16-bit integer read from the binary stream.
+ */
+jspb.BinaryDecoder.prototype.readUint16 = function() {
+ var a = this.bytes_[this.cursor_ + 0];
+ var b = this.bytes_[this.cursor_ + 1];
+ this.cursor_ += 2;
+ goog.asserts.assert(this.cursor_ <= this.end_);
+ return (a << 0) | (b << 8);
+};
+
+
+/**
+ * Reads a raw unsigned 32-bit integer from the binary stream.
+ *
+ * @return {number} The unsigned 32-bit integer read from the binary stream.
+ */
+jspb.BinaryDecoder.prototype.readUint32 = function() {
+ var a = this.bytes_[this.cursor_ + 0];
+ var b = this.bytes_[this.cursor_ + 1];
+ var c = this.bytes_[this.cursor_ + 2];
+ var d = this.bytes_[this.cursor_ + 3];
+ this.cursor_ += 4;
+ goog.asserts.assert(this.cursor_ <= this.end_);
+ return ((a << 0) | (b << 8) | (c << 16) | (d << 24)) >>> 0;
+};
+
+
+/**
+ * Reads a raw unsigned 64-bit integer from the binary stream. Note that since
+ * Javascript represents all numbers as double-precision floats, there will be
+ * precision lost if the absolute value of the integer is larger than 2^53.
+ *
+ * @return {number} The unsigned 64-bit integer read from the binary stream.
+ * Precision will be lost if the integer exceeds 2^53.
+ */
+jspb.BinaryDecoder.prototype.readUint64 = function() {
+ var bitsLow = this.readUint32();
+ var bitsHigh = this.readUint32();
+ return jspb.utils.joinUint64(bitsLow, bitsHigh);
+};
+
+
+/**
+ * Reads a raw signed 8-bit integer from the binary stream.
+ *
+ * @return {number} The signed 8-bit integer read from the binary stream.
+ */
+jspb.BinaryDecoder.prototype.readInt8 = function() {
+ var a = this.bytes_[this.cursor_ + 0];
+ this.cursor_ += 1;
+ goog.asserts.assert(this.cursor_ <= this.end_);
+ return (a << 24) >> 24;
+};
+
+
+/**
+ * Reads a raw signed 16-bit integer from the binary stream.
+ *
+ * @return {number} The signed 16-bit integer read from the binary stream.
+ */
+jspb.BinaryDecoder.prototype.readInt16 = function() {
+ var a = this.bytes_[this.cursor_ + 0];
+ var b = this.bytes_[this.cursor_ + 1];
+ this.cursor_ += 2;
+ goog.asserts.assert(this.cursor_ <= this.end_);
+ return (((a << 0) | (b << 8)) << 16) >> 16;
+};
+
+
+/**
+ * Reads a raw signed 32-bit integer from the binary stream.
+ *
+ * @return {number} The signed 32-bit integer read from the binary stream.
+ */
+jspb.BinaryDecoder.prototype.readInt32 = function() {
+ var a = this.bytes_[this.cursor_ + 0];
+ var b = this.bytes_[this.cursor_ + 1];
+ var c = this.bytes_[this.cursor_ + 2];
+ var d = this.bytes_[this.cursor_ + 3];
+ this.cursor_ += 4;
+ goog.asserts.assert(this.cursor_ <= this.end_);
+ return (a << 0) | (b << 8) | (c << 16) | (d << 24);
+};
+
+
+/**
+ * Reads a raw signed 64-bit integer from the binary stream. Note that since
+ * Javascript represents all numbers as double-precision floats, there will be
+ * precision lost if the absolute vlaue of the integer is larger than 2^53.
+ *
+ * @return {number} The signed 64-bit integer read from the binary stream.
+ * Precision will be lost if the integer exceeds 2^53.
+ */
+jspb.BinaryDecoder.prototype.readInt64 = function() {
+ var bitsLow = this.readUint32();
+ var bitsHigh = this.readUint32();
+ return jspb.utils.joinInt64(bitsLow, bitsHigh);
+};
+
+
+/**
+ * Reads a 32-bit floating-point number from the binary stream, using the
+ * temporary buffer to realign the data.
+ *
+ * @return {number} The float read from the binary stream.
+ */
+jspb.BinaryDecoder.prototype.readFloat = function() {
+ var bitsLow = this.readUint32();
+ var bitsHigh = 0;
+ return jspb.utils.joinFloat32(bitsLow, bitsHigh);
+};
+
+
+/**
+ * Reads a 64-bit floating-point number from the binary stream, using the
+ * temporary buffer to realign the data.
+ *
+ * @return {number} The double read from the binary stream.
+ */
+jspb.BinaryDecoder.prototype.readDouble = function() {
+ var bitsLow = this.readUint32();
+ var bitsHigh = this.readUint32();
+ return jspb.utils.joinFloat64(bitsLow, bitsHigh);
+};
+
+
+/**
+ * Reads a boolean value from the binary stream.
+ * @return {boolean} The boolean read from the binary stream.
+ */
+jspb.BinaryDecoder.prototype.readBool = function() {
+ return !!this.bytes_[this.cursor_++];
+};
+
+
+/**
+ * Reads an enum value from the binary stream, which are always encoded as
+ * signed varints.
+ * @return {number} The enum value read from the binary stream.
+ */
+jspb.BinaryDecoder.prototype.readEnum = function() {
+ return this.readSignedVarint32();
+};
+
+
+/**
+ * Reads and parses a UTF-8 encoded unicode string from the stream.
+ * The code is inspired by maps.vectortown.parse.StreamedDataViewReader, with
+ * the exception that the implementation here does not get confused if it
+ * encounters characters longer than three bytes. These characters are ignored
+ * though, as they are extremely rare: three UTF-8 bytes cover virtually all
+ * characters in common use (http://en.wikipedia.org/wiki/UTF-8).
+ * @param {number} length The length of the string to read.
+ * @return {string} The decoded string.
+ */
+jspb.BinaryDecoder.prototype.readString = function(length) {
+ var bytes = this.bytes_;
+ var cursor = this.cursor_;
+ var end = cursor + length;
+ var chars = [];
+
+ while (cursor < end) {
+ var c = bytes[cursor++];
+ if (c < 128) { // Regular 7-bit ASCII.
+ chars.push(c);
+ } else if (c < 192) {
+ // UTF-8 continuation mark. We are out of sync. This
+ // might happen if we attempted to read a character
+ // with more than three bytes.
+ continue;
+ } else if (c < 224) { // UTF-8 with two bytes.
+ var c2 = bytes[cursor++];
+ chars.push(((c & 31) << 6) | (c2 & 63));
+ } else if (c < 240) { // UTF-8 with three bytes.
+ var c2 = bytes[cursor++];
+ var c3 = bytes[cursor++];
+ chars.push(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
+ }
+ }
+
+ // String.fromCharCode.apply is faster than manually appending characters on
+ // Chrome 25+, and generates no additional cons string garbage.
+ var result = String.fromCharCode.apply(null, chars);
+ this.cursor_ = cursor;
+ return result;
+};
+
+
+/**
+ * Reads and parses a UTF-8 encoded unicode string (with length prefix) from
+ * the stream.
+ * @return {string} The decoded string.
+ */
+jspb.BinaryDecoder.prototype.readStringWithLength = function() {
+ var length = this.readUnsignedVarint32();
+ return this.readString(length);
+};
+
+
+/**
+ * Reads a block of raw bytes from the binary stream.
+ *
+ * @param {number} length The number of bytes to read.
+ * @return {!Uint8Array} The decoded block of bytes, or an empty block if the
+ * length was invalid.
+ */
+jspb.BinaryDecoder.prototype.readBytes = function(length) {
+ if (length < 0 ||
+ this.cursor_ + length > this.bytes_.length) {
+ this.error_ = true;
+ goog.asserts.fail('Invalid byte length!');
+ return new Uint8Array(0);
+ }
+
+ var result = this.bytes_.subarray(this.cursor_, this.cursor_ + length);
+
+ this.cursor_ += length;
+ goog.asserts.assert(this.cursor_ <= this.end_);
+ return result;
+};
+
+
+/**
+ * Reads a 64-bit varint from the stream and returns it as an 8-character
+ * Unicode string for use as a hash table key.
+ *
+ * @return {string} The hash value.
+ */
+jspb.BinaryDecoder.prototype.readVarintHash64 = function() {
+ this.readSplitVarint64_();
+ return jspb.utils.joinHash64(this.tempLow_, this.tempHigh_);
+};
+
+
+/**
+ * Reads a 64-bit fixed-width value from the stream and returns it as an
+ * 8-character Unicode string for use as a hash table key.
+ *
+ * @return {string} The hash value.
+ */
+jspb.BinaryDecoder.prototype.readFixedHash64 = function() {
+ var bytes = this.bytes_;
+ var cursor = this.cursor_;
+
+ var a = bytes[cursor + 0];
+ var b = bytes[cursor + 1];
+ var c = bytes[cursor + 2];
+ var d = bytes[cursor + 3];
+ var e = bytes[cursor + 4];
+ var f = bytes[cursor + 5];
+ var g = bytes[cursor + 6];
+ var h = bytes[cursor + 7];
+
+ this.cursor_ += 8;
+
+ return String.fromCharCode(a, b, c, d, e, f, g, h);
+};
diff --git a/js/binary/decoder_test.js b/js/binary/decoder_test.js
new file mode 100644
index 00000000..ac312648
--- /dev/null
+++ b/js/binary/decoder_test.js
@@ -0,0 +1,334 @@
+// 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.
+
+/**
+ * @fileoverview Test cases for jspb's binary protocol buffer decoder.
+ *
+ * There are two particular magic numbers that need to be pointed out -
+ * 2^64-1025 is the largest number representable as both a double and an
+ * unsigned 64-bit integer, and 2^63-513 is the largest number representable as
+ * both a double and a signed 64-bit integer.
+ *
+ * Test suite is written using Jasmine -- see http://jasmine.github.io/
+ *
+ * @author aappleby@google.com (Austin Appleby)
+ */
+
+goog.require('goog.testing.asserts');
+goog.require('jspb.BinaryConstants');
+goog.require('jspb.BinaryDecoder');
+goog.require('jspb.BinaryEncoder');
+
+
+/**
+ * Tests encoding and decoding of unsigned types.
+ * @param {Function} readValue
+ * @param {Function} writeValue
+ * @param {number} epsilon
+ * @param {number} upperLimit
+ * @param {Function} filter
+ * @suppress {missingProperties|visibility}
+ */
+function doTestUnsignedValue(readValue,
+ writeValue, epsilon, upperLimit, filter) {
+ var encoder = new jspb.BinaryEncoder();
+
+ // Encode zero and limits.
+ writeValue.call(encoder, filter(0));
+ writeValue.call(encoder, filter(epsilon));
+ writeValue.call(encoder, filter(upperLimit));
+
+ // Encode positive values.
+ for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) {
+ writeValue.call(encoder, filter(cursor));
+ }
+
+ var decoder = jspb.BinaryDecoder.alloc(encoder.end());
+
+ // Check zero and limits.
+ assertEquals(filter(0), readValue.call(decoder));
+ assertEquals(filter(epsilon), readValue.call(decoder));
+ assertEquals(filter(upperLimit), readValue.call(decoder));
+
+ // Check positive values.
+ for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) {
+ if (filter(cursor) != readValue.call(decoder)) throw 'fail!';
+ }
+
+ // Encoding values outside the valid range should assert.
+ assertThrows(function() {writeValue.call(encoder, -1);});
+ assertThrows(function() {writeValue.call(encoder, upperLimit * 1.1);});
+}
+
+
+/**
+ * Tests encoding and decoding of signed types.
+ * @param {Function} readValue
+ * @param {Function} writeValue
+ * @param {number} epsilon
+ * @param {number} lowerLimit
+ * @param {number} upperLimit
+ * @param {Function} filter
+ * @suppress {missingProperties}
+ */
+function doTestSignedValue(readValue,
+ writeValue, epsilon, lowerLimit, upperLimit, filter) {
+ var encoder = new jspb.BinaryEncoder();
+
+ // Encode zero and limits.
+ writeValue.call(encoder, filter(lowerLimit));
+ writeValue.call(encoder, filter(-epsilon));
+ writeValue.call(encoder, filter(0));
+ writeValue.call(encoder, filter(epsilon));
+ writeValue.call(encoder, filter(upperLimit));
+
+ var inputValues = [];
+
+ // Encode negative values.
+ for (var cursor = lowerLimit; cursor < -epsilon; cursor /= 1.1) {
+ var val = filter(cursor);
+ writeValue.call(encoder, val);
+ inputValues.push(val);
+ }
+
+ // Encode positive values.
+ for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) {
+ var val = filter(cursor);
+ writeValue.call(encoder, val);
+ inputValues.push(val);
+ }
+
+ var decoder = jspb.BinaryDecoder.alloc(encoder.end());
+
+ // Check zero and limits.
+ assertEquals(filter(lowerLimit), readValue.call(decoder));
+ assertEquals(filter(-epsilon), readValue.call(decoder));
+ assertEquals(filter(0), readValue.call(decoder));
+ assertEquals(filter(epsilon), readValue.call(decoder));
+ assertEquals(filter(upperLimit), readValue.call(decoder));
+
+ // Verify decoded values.
+ for (var i = 0; i < inputValues.length; i++) {
+ assertEquals(inputValues[i], readValue.call(decoder));
+ }
+
+ // Encoding values outside the valid range should assert.
+ assertThrows(function() {writeValue.call(encoder, lowerLimit * 1.1);});
+ assertThrows(function() {writeValue.call(encoder, upperLimit * 1.1);});
+}
+
+describe('binaryDecoderTest', function() {
+ /**
+ * Tests the decoder instance cache.
+ */
+ it('testInstanceCache', /** @suppress {visibility} */ function() {
+ // Empty the instance caches.
+ jspb.BinaryDecoder.instanceCache_ = [];
+
+ // Allocating and then freeing a decoder should put it in the instance
+ // cache.
+ jspb.BinaryDecoder.alloc().free();
+
+ assertEquals(1, jspb.BinaryDecoder.instanceCache_.length);
+
+ // Allocating and then freeing three decoders should leave us with three in
+ // the cache.
+
+ var decoder1 = jspb.BinaryDecoder.alloc();
+ var decoder2 = jspb.BinaryDecoder.alloc();
+ var decoder3 = jspb.BinaryDecoder.alloc();
+ decoder1.free();
+ decoder2.free();
+ decoder3.free();
+
+ assertEquals(3, jspb.BinaryDecoder.instanceCache_.length);
+ });
+
+
+ /**
+ * Tests reading 64-bit integers as hash strings.
+ */
+ it('testHashStrings', function() {
+ var encoder = new jspb.BinaryEncoder();
+
+ var hashA = String.fromCharCode(0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00);
+ var hashB = String.fromCharCode(0x12, 0x34, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00);
+ var hashC = String.fromCharCode(0x12, 0x34, 0x56, 0x78,
+ 0x87, 0x65, 0x43, 0x21);
+ var hashD = String.fromCharCode(0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF);
+
+ encoder.writeVarintHash64(hashA);
+ encoder.writeVarintHash64(hashB);
+ encoder.writeVarintHash64(hashC);
+ encoder.writeVarintHash64(hashD);
+
+ encoder.writeFixedHash64(hashA);
+ encoder.writeFixedHash64(hashB);
+ encoder.writeFixedHash64(hashC);
+ encoder.writeFixedHash64(hashD);
+
+ var decoder = jspb.BinaryDecoder.alloc(encoder.end());
+
+ assertEquals(hashA, decoder.readVarintHash64());
+ assertEquals(hashB, decoder.readVarintHash64());
+ assertEquals(hashC, decoder.readVarintHash64());
+ assertEquals(hashD, decoder.readVarintHash64());
+
+ assertEquals(hashA, decoder.readFixedHash64());
+ assertEquals(hashB, decoder.readFixedHash64());
+ assertEquals(hashC, decoder.readFixedHash64());
+ assertEquals(hashD, decoder.readFixedHash64());
+ });
+
+
+ /**
+ * Verifies that misuse of the decoder class triggers assertions.
+ * @suppress {checkTypes|visibility}
+ */
+ it('testDecodeErrors', function() {
+ // Reading a value past the end of the stream should trigger an assertion.
+ var decoder = jspb.BinaryDecoder.alloc([0, 1, 2]);
+ assertThrows(function() {decoder.readUint64()});
+
+ // Overlong varints should trigger assertions.
+ decoder.setBlock([255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 0]);
+ assertThrows(function() {decoder.readUnsignedVarint64()});
+ decoder.reset();
+ assertThrows(function() {decoder.readSignedVarint64()});
+ decoder.reset();
+ assertThrows(function() {decoder.readZigzagVarint64()});
+
+ // Positive 32-bit varints encoded with 1 bits in positions 33 through 35
+ // should trigger assertions.
+ decoder.setBlock([255, 255, 255, 255, 0x1F]);
+ assertThrows(function() {decoder.readUnsignedVarint32()});
+
+ decoder.setBlock([255, 255, 255, 255, 0x2F]);
+ assertThrows(function() {decoder.readUnsignedVarint32()});
+
+ decoder.setBlock([255, 255, 255, 255, 0x4F]);
+ assertThrows(function() {decoder.readUnsignedVarint32()});
+
+ // Negative 32-bit varints encoded with non-1 bits in the high dword should
+ // trigger assertions.
+ decoder.setBlock([255, 255, 255, 255, 255, 255, 0, 255, 255, 1]);
+ assertThrows(function() {decoder.readUnsignedVarint32()});
+
+ decoder.setBlock([255, 255, 255, 255, 255, 255, 255, 255, 255, 0]);
+ assertThrows(function() {decoder.readUnsignedVarint32()});
+ });
+
+
+ /**
+ * Tests encoding and decoding of unsigned integers.
+ */
+ it('testUnsignedIntegers', function() {
+ doTestUnsignedValue(
+ jspb.BinaryDecoder.prototype.readUint8,
+ jspb.BinaryEncoder.prototype.writeUint8,
+ 1, 0xFF, Math.round);
+
+ doTestUnsignedValue(
+ jspb.BinaryDecoder.prototype.readUint16,
+ jspb.BinaryEncoder.prototype.writeUint16,
+ 1, 0xFFFF, Math.round);
+
+ doTestUnsignedValue(
+ jspb.BinaryDecoder.prototype.readUint32,
+ jspb.BinaryEncoder.prototype.writeUint32,
+ 1, 0xFFFFFFFF, Math.round);
+
+ doTestUnsignedValue(
+ jspb.BinaryDecoder.prototype.readUint64,
+ jspb.BinaryEncoder.prototype.writeUint64,
+ 1, Math.pow(2, 64) - 1025, Math.round);
+ });
+
+
+ /**
+ * Tests encoding and decoding of signed integers.
+ */
+ it('testSignedIntegers', function() {
+ doTestSignedValue(
+ jspb.BinaryDecoder.prototype.readInt8,
+ jspb.BinaryEncoder.prototype.writeInt8,
+ 1, -0x80, 0x7F, Math.round);
+
+ doTestSignedValue(
+ jspb.BinaryDecoder.prototype.readInt16,
+ jspb.BinaryEncoder.prototype.writeInt16,
+ 1, -0x8000, 0x7FFF, Math.round);
+
+ doTestSignedValue(
+ jspb.BinaryDecoder.prototype.readInt32,
+ jspb.BinaryEncoder.prototype.writeInt32,
+ 1, -0x80000000, 0x7FFFFFFF, Math.round);
+
+ doTestSignedValue(
+ jspb.BinaryDecoder.prototype.readInt64,
+ jspb.BinaryEncoder.prototype.writeInt64,
+ 1, -Math.pow(2, 63), Math.pow(2, 63) - 513, Math.round);
+ });
+
+
+ /**
+ * Tests encoding and decoding of floats.
+ */
+ it('testFloats', function() {
+ /**
+ * @param {number} x
+ * @return {number}
+ */
+ function truncate(x) {
+ var temp = new Float32Array(1);
+ temp[0] = x;
+ return temp[0];
+ }
+ doTestSignedValue(
+ jspb.BinaryDecoder.prototype.readFloat,
+ jspb.BinaryEncoder.prototype.writeFloat,
+ jspb.BinaryConstants.FLOAT32_EPS,
+ -jspb.BinaryConstants.FLOAT32_MAX,
+ jspb.BinaryConstants.FLOAT32_MAX,
+ truncate);
+
+ doTestSignedValue(
+ jspb.BinaryDecoder.prototype.readDouble,
+ jspb.BinaryEncoder.prototype.writeDouble,
+ jspb.BinaryConstants.FLOAT64_EPS * 10,
+ -jspb.BinaryConstants.FLOAT64_MAX,
+ jspb.BinaryConstants.FLOAT64_MAX,
+ function(x) { return x; });
+ });
+});
diff --git a/js/binary/encoder.js b/js/binary/encoder.js
new file mode 100644
index 00000000..c9b0c2ae
--- /dev/null
+++ b/js/binary/encoder.js
@@ -0,0 +1,430 @@
+// 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.
+
+/**
+ * @fileoverview BinaryEncode defines methods for encoding Javascript values
+ * into arrays of bytes compatible with the Protocol Buffer wire format.
+ *
+ * @author aappleby@google.com (Austin Appleby)
+ */
+
+goog.provide('jspb.BinaryEncoder');
+
+goog.require('goog.asserts');
+goog.require('jspb.BinaryConstants');
+goog.require('jspb.utils');
+
+
+
+/**
+ * BinaryEncoder implements encoders for all the wire types specified in
+ * https://developers.google.com/protocol-buffers/docs/encoding.
+ *
+ * @constructor
+ * @struct
+ */
+jspb.BinaryEncoder = function() {
+ /** @private {!Array.<number>} */
+ this.buffer_ = [];
+};
+
+
+/**
+ * @return {number}
+ */
+jspb.BinaryEncoder.prototype.length = function() {
+ return this.buffer_.length;
+};
+
+
+/**
+ * @return {!Array.<number>}
+ */
+jspb.BinaryEncoder.prototype.end = function() {
+ var buffer = this.buffer_;
+ this.buffer_ = [];
+ return buffer;
+};
+
+
+/**
+ * Encodes a 64-bit integer in 32:32 split representation into its wire-format
+ * varint representation and stores it in the buffer.
+ * @param {number} lowBits The low 32 bits of the int.
+ * @param {number} highBits The high 32 bits of the int.
+ */
+jspb.BinaryEncoder.prototype.writeSplitVarint64 = function(lowBits, highBits) {
+ goog.asserts.assert(lowBits == Math.floor(lowBits));
+ goog.asserts.assert(highBits == Math.floor(highBits));
+ goog.asserts.assert((lowBits >= 0) &&
+ (lowBits < jspb.BinaryConstants.TWO_TO_32));
+ goog.asserts.assert((highBits >= 0) &&
+ (highBits < jspb.BinaryConstants.TWO_TO_32));
+
+ // Break the binary representation into chunks of 7 bits, set the 8th bit
+ // in each chunk if it's not the final chunk, and append to the result.
+ while (highBits > 0 || lowBits > 127) {
+ this.buffer_.push((lowBits & 0x7f) | 0x80);
+ lowBits = ((lowBits >>> 7) | (highBits << 25)) >>> 0;
+ highBits = highBits >>> 7;
+ }
+ this.buffer_.push(lowBits);
+};
+
+
+/**
+ * Encodes a 32-bit unsigned integer into its wire-format varint representation
+ * and stores it in the buffer.
+ * @param {number} value The integer to convert.
+ */
+jspb.BinaryEncoder.prototype.writeUnsignedVarint32 = function(value) {
+ goog.asserts.assert(value == Math.floor(value));
+ goog.asserts.assert((value >= 0) &&
+ (value < jspb.BinaryConstants.TWO_TO_32));
+
+ while (value > 127) {
+ this.buffer_.push((value & 0x7f) | 0x80);
+ value = value >>> 7;
+ }
+
+ this.buffer_.push(value);
+};
+
+
+/**
+ * Encodes a 32-bit signed integer into its wire-format varint representation
+ * and stores it in the buffer.
+ * @param {number} value The integer to convert.
+ */
+jspb.BinaryEncoder.prototype.writeSignedVarint32 = function(value) {
+ goog.asserts.assert(value == Math.floor(value));
+ goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_31) &&
+ (value < jspb.BinaryConstants.TWO_TO_31));
+
+ // Use the unsigned version if the value is not negative.
+ if (value >= 0) {
+ this.writeUnsignedVarint32(value);
+ return;
+ }
+
+ // Write nine bytes with a _signed_ right shift so we preserve the sign bit.
+ for (var i = 0; i < 9; i++) {
+ this.buffer_.push((value & 0x7f) | 0x80);
+ value = value >> 7;
+ }
+
+ // The above loop writes out 63 bits, so the last byte is always the sign bit
+ // which is always set for negative numbers.
+ this.buffer_.push(1);
+};
+
+
+/**
+ * Encodes a 64-bit unsigned integer into its wire-format varint representation
+ * and stores it in the buffer. Integers that are not representable in 64 bits
+ * will be truncated.
+ * @param {number} value The integer to convert.
+ */
+jspb.BinaryEncoder.prototype.writeUnsignedVarint64 = function(value) {
+ goog.asserts.assert(value == Math.floor(value));
+ goog.asserts.assert((value >= 0) &&
+ (value < jspb.BinaryConstants.TWO_TO_64));
+ jspb.utils.splitInt64(value);
+ this.writeSplitVarint64(jspb.utils.split64Low,
+ jspb.utils.split64High);
+};
+
+
+/**
+ * Encodes a 64-bit signed integer into its wire-format varint representation
+ * and stores it in the buffer. Integers that are not representable in 64 bits
+ * will be truncated.
+ * @param {number} value The integer to convert.
+ */
+jspb.BinaryEncoder.prototype.writeSignedVarint64 = function(value) {
+ goog.asserts.assert(value == Math.floor(value));
+ goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_63) &&
+ (value < jspb.BinaryConstants.TWO_TO_63));
+ jspb.utils.splitInt64(value);
+ this.writeSplitVarint64(jspb.utils.split64Low,
+ jspb.utils.split64High);
+};
+
+
+/**
+ * Encodes a JavaScript integer into its wire-format, zigzag-encoded varint
+ * representation and stores it in the buffer.
+ * @param {number} value The integer to convert.
+ */
+jspb.BinaryEncoder.prototype.writeZigzagVarint32 = function(value) {
+ goog.asserts.assert(value == Math.floor(value));
+ goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_31) &&
+ (value < jspb.BinaryConstants.TWO_TO_31));
+ this.writeUnsignedVarint32(((value << 1) ^ (value >> 31)) >>> 0);
+};
+
+
+/**
+ * Encodes a JavaScript integer into its wire-format, zigzag-encoded varint
+ * representation and stores it in the buffer. Integers not representable in 64
+ * bits will be truncated.
+ * @param {number} value The integer to convert.
+ */
+jspb.BinaryEncoder.prototype.writeZigzagVarint64 = function(value) {
+ goog.asserts.assert(value == Math.floor(value));
+ goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_63) &&
+ (value < jspb.BinaryConstants.TWO_TO_63));
+ jspb.utils.splitZigzag64(value);
+ this.writeSplitVarint64(jspb.utils.split64Low,
+ jspb.utils.split64High);
+};
+
+
+/**
+ * Writes a 8-bit unsigned integer to the buffer. Numbers outside the range
+ * [0,2^8) will be truncated.
+ * @param {number} value The value to write.
+ */
+jspb.BinaryEncoder.prototype.writeUint8 = function(value) {
+ goog.asserts.assert(value == Math.floor(value));
+ goog.asserts.assert((value >= 0) && (value < 256));
+ this.buffer_.push((value >>> 0) & 0xFF);
+};
+
+
+/**
+ * Writes a 16-bit unsigned integer to the buffer. Numbers outside the
+ * range [0,2^16) will be truncated.
+ * @param {number} value The value to write.
+ */
+jspb.BinaryEncoder.prototype.writeUint16 = function(value) {
+ goog.asserts.assert(value == Math.floor(value));
+ goog.asserts.assert((value >= 0) && (value < 65536));
+ this.buffer_.push((value >>> 0) & 0xFF);
+ this.buffer_.push((value >>> 8) & 0xFF);
+};
+
+
+/**
+ * Writes a 32-bit unsigned integer to the buffer. Numbers outside the
+ * range [0,2^32) will be truncated.
+ * @param {number} value The value to write.
+ */
+jspb.BinaryEncoder.prototype.writeUint32 = function(value) {
+ goog.asserts.assert(value == Math.floor(value));
+ goog.asserts.assert((value >= 0) &&
+ (value < jspb.BinaryConstants.TWO_TO_32));
+ this.buffer_.push((value >>> 0) & 0xFF);
+ this.buffer_.push((value >>> 8) & 0xFF);
+ this.buffer_.push((value >>> 16) & 0xFF);
+ this.buffer_.push((value >>> 24) & 0xFF);
+};
+
+
+/**
+ * Writes a 64-bit unsigned integer to the buffer. Numbers outside the
+ * range [0,2^64) will be truncated.
+ * @param {number} value The value to write.
+ */
+jspb.BinaryEncoder.prototype.writeUint64 = function(value) {
+ goog.asserts.assert(value == Math.floor(value));
+ goog.asserts.assert((value >= 0) &&
+ (value < jspb.BinaryConstants.TWO_TO_64));
+ jspb.utils.splitUint64(value);
+ this.writeUint32(jspb.utils.split64Low);
+ this.writeUint32(jspb.utils.split64High);
+};
+
+
+/**
+ * Writes a 8-bit integer to the buffer. Numbers outside the range
+ * [-2^7,2^7) will be truncated.
+ * @param {number} value The value to write.
+ */
+jspb.BinaryEncoder.prototype.writeInt8 = function(value) {
+ goog.asserts.assert(value == Math.floor(value));
+ goog.asserts.assert((value >= -128) && (value < 128));
+ this.buffer_.push((value >>> 0) & 0xFF);
+};
+
+
+/**
+ * Writes a 16-bit integer to the buffer. Numbers outside the range
+ * [-2^15,2^15) will be truncated.
+ * @param {number} value The value to write.
+ */
+jspb.BinaryEncoder.prototype.writeInt16 = function(value) {
+ goog.asserts.assert(value == Math.floor(value));
+ goog.asserts.assert((value >= -32768) && (value < 32768));
+ this.buffer_.push((value >>> 0) & 0xFF);
+ this.buffer_.push((value >>> 8) & 0xFF);
+};
+
+
+/**
+ * Writes a 32-bit integer to the buffer. Numbers outside the range
+ * [-2^31,2^31) will be truncated.
+ * @param {number} value The value to write.
+ */
+jspb.BinaryEncoder.prototype.writeInt32 = function(value) {
+ goog.asserts.assert(value == Math.floor(value));
+ goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_31) &&
+ (value < jspb.BinaryConstants.TWO_TO_31));
+ this.buffer_.push((value >>> 0) & 0xFF);
+ this.buffer_.push((value >>> 8) & 0xFF);
+ this.buffer_.push((value >>> 16) & 0xFF);
+ this.buffer_.push((value >>> 24) & 0xFF);
+};
+
+
+/**
+ * Writes a 64-bit integer to the buffer. Numbers outside the range
+ * [-2^63,2^63) will be truncated.
+ * @param {number} value The value to write.
+ */
+jspb.BinaryEncoder.prototype.writeInt64 = function(value) {
+ goog.asserts.assert(value == Math.floor(value));
+ goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_63) &&
+ (value < jspb.BinaryConstants.TWO_TO_63));
+ jspb.utils.splitInt64(value);
+ this.writeUint32(jspb.utils.split64Low);
+ this.writeUint32(jspb.utils.split64High);
+};
+
+
+/**
+ * Writes a single-precision floating point value to the buffer. Numbers
+ * requiring more than 32 bits of precision will be truncated.
+ * @param {number} value The value to write.
+ */
+jspb.BinaryEncoder.prototype.writeFloat = function(value) {
+ goog.asserts.assert((value >= -jspb.BinaryConstants.FLOAT32_MAX) &&
+ (value <= jspb.BinaryConstants.FLOAT32_MAX));
+ jspb.utils.splitFloat32(value);
+ this.writeUint32(jspb.utils.split64Low);
+};
+
+
+/**
+ * Writes a double-precision floating point value to the buffer. As this is
+ * the native format used by JavaScript, no precision will be lost.
+ * @param {number} value The value to write.
+ */
+jspb.BinaryEncoder.prototype.writeDouble = function(value) {
+ goog.asserts.assert((value >= -jspb.BinaryConstants.FLOAT64_MAX) &&
+ (value <= jspb.BinaryConstants.FLOAT64_MAX));
+ jspb.utils.splitFloat64(value);
+ this.writeUint32(jspb.utils.split64Low);
+ this.writeUint32(jspb.utils.split64High);
+};
+
+
+/**
+ * Writes a boolean value to the buffer as a varint.
+ * @param {boolean} value The value to write.
+ */
+jspb.BinaryEncoder.prototype.writeBool = function(value) {
+ goog.asserts.assert(goog.isBoolean(value));
+ this.buffer_.push(value ? 1 : 0);
+};
+
+
+/**
+ * Writes an enum value to the buffer as a varint.
+ * @param {number} value The value to write.
+ */
+jspb.BinaryEncoder.prototype.writeEnum = function(value) {
+ goog.asserts.assert(value == Math.floor(value));
+ goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_31) &&
+ (value < jspb.BinaryConstants.TWO_TO_31));
+ this.writeSignedVarint32(value);
+};
+
+
+/**
+ * Writes an arbitrary byte array to the buffer.
+ * @param {!Uint8Array} bytes The array of bytes to write.
+ */
+jspb.BinaryEncoder.prototype.writeBytes = function(bytes) {
+ this.buffer_.push.apply(this.buffer_, bytes);
+};
+
+
+/**
+ * Writes a 64-bit hash string (8 characters @ 8 bits of data each) to the
+ * buffer as a varint.
+ * @param {string} hash The hash to write.
+ */
+jspb.BinaryEncoder.prototype.writeVarintHash64 = function(hash) {
+ jspb.utils.splitHash64(hash);
+ this.writeSplitVarint64(jspb.utils.split64Low,
+ jspb.utils.split64High);
+};
+
+
+/**
+ * Writes a 64-bit hash string (8 characters @ 8 bits of data each) to the
+ * buffer as a fixed64.
+ * @param {string} hash The hash to write.
+ */
+jspb.BinaryEncoder.prototype.writeFixedHash64 = function(hash) {
+ jspb.utils.splitHash64(hash);
+ this.writeUint32(jspb.utils.split64Low);
+ this.writeUint32(jspb.utils.split64High);
+};
+
+
+/**
+ * Writes a UTF16 Javascript string to the buffer encoded as UTF8.
+ * TODO(aappleby): Add support for surrogate pairs, reject unpaired surrogates.
+ * @param {string} value The string to write.
+ * @return {number} The number of bytes used to encode the string.
+ */
+jspb.BinaryEncoder.prototype.writeString = function(value) {
+ var oldLength = this.buffer_.length;
+
+ // UTF16 to UTF8 conversion loop swiped from goog.crypt.stringToUtf8ByteArray.
+ for (var i = 0; i < value.length; i++) {
+ var c = value.charCodeAt(i);
+ if (c < 128) {
+ this.buffer_.push(c);
+ } else if (c < 2048) {
+ this.buffer_.push((c >> 6) | 192);
+ this.buffer_.push((c & 63) | 128);
+ } else {
+ this.buffer_.push((c >> 12) | 224);
+ this.buffer_.push(((c >> 6) & 63) | 128);
+ this.buffer_.push((c & 63) | 128);
+ }
+ }
+
+ var length = this.buffer_.length - oldLength;
+ return length;
+};
diff --git a/js/binary/proto_test.js b/js/binary/proto_test.js
new file mode 100644
index 00000000..14d0f42e
--- /dev/null
+++ b/js/binary/proto_test.js
@@ -0,0 +1,628 @@
+// 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.
+
+// Test suite is written using Jasmine -- see http://jasmine.github.io/
+
+goog.require('goog.crypt.base64');
+goog.require('goog.testing.asserts');
+goog.require('jspb.Message');
+
+// CommonJS-LoadFromFile: ../testbinary_pb proto.jspb.test
+goog.require('proto.jspb.test.ExtendsWithMessage');
+goog.require('proto.jspb.test.ForeignEnum');
+goog.require('proto.jspb.test.ForeignMessage');
+goog.require('proto.jspb.test.TestAllTypes');
+goog.require('proto.jspb.test.TestExtendable');
+goog.require('proto.jspb.test.extendOptionalBool');
+goog.require('proto.jspb.test.extendOptionalBytes');
+goog.require('proto.jspb.test.extendOptionalDouble');
+goog.require('proto.jspb.test.extendOptionalFixed32');
+goog.require('proto.jspb.test.extendOptionalFixed64');
+goog.require('proto.jspb.test.extendOptionalFloat');
+goog.require('proto.jspb.test.extendOptionalForeignEnum');
+goog.require('proto.jspb.test.extendOptionalInt32');
+goog.require('proto.jspb.test.extendOptionalInt64');
+goog.require('proto.jspb.test.extendOptionalSfixed32');
+goog.require('proto.jspb.test.extendOptionalSfixed64');
+goog.require('proto.jspb.test.extendOptionalSint32');
+goog.require('proto.jspb.test.extendOptionalSint64');
+goog.require('proto.jspb.test.extendOptionalString');
+goog.require('proto.jspb.test.extendOptionalUint32');
+goog.require('proto.jspb.test.extendOptionalUint64');
+goog.require('proto.jspb.test.extendPackedRepeatedBoolList');
+goog.require('proto.jspb.test.extendPackedRepeatedDoubleList');
+goog.require('proto.jspb.test.extendPackedRepeatedFixed32List');
+goog.require('proto.jspb.test.extendPackedRepeatedFixed64List');
+goog.require('proto.jspb.test.extendPackedRepeatedFloatList');
+goog.require('proto.jspb.test.extendPackedRepeatedForeignEnumList');
+goog.require('proto.jspb.test.extendPackedRepeatedInt32List');
+goog.require('proto.jspb.test.extendPackedRepeatedInt64List');
+goog.require('proto.jspb.test.extendPackedRepeatedSfixed32List');
+goog.require('proto.jspb.test.extendPackedRepeatedSfixed64List');
+goog.require('proto.jspb.test.extendPackedRepeatedSint32List');
+goog.require('proto.jspb.test.extendPackedRepeatedSint64List');
+goog.require('proto.jspb.test.extendPackedRepeatedUint32List');
+goog.require('proto.jspb.test.extendPackedRepeatedUint64List');
+goog.require('proto.jspb.test.extendRepeatedBoolList');
+goog.require('proto.jspb.test.extendRepeatedBytesList');
+goog.require('proto.jspb.test.extendRepeatedDoubleList');
+goog.require('proto.jspb.test.extendRepeatedFixed32List');
+goog.require('proto.jspb.test.extendRepeatedFixed64List');
+goog.require('proto.jspb.test.extendRepeatedFloatList');
+goog.require('proto.jspb.test.extendRepeatedForeignEnumList');
+goog.require('proto.jspb.test.extendRepeatedInt32List');
+goog.require('proto.jspb.test.extendRepeatedInt64List');
+goog.require('proto.jspb.test.extendRepeatedSfixed32List');
+goog.require('proto.jspb.test.extendRepeatedSfixed64List');
+goog.require('proto.jspb.test.extendRepeatedSint32List');
+goog.require('proto.jspb.test.extendRepeatedSint64List');
+goog.require('proto.jspb.test.extendRepeatedStringList');
+goog.require('proto.jspb.test.extendRepeatedUint32List');
+goog.require('proto.jspb.test.extendRepeatedUint64List');
+
+
+var suite = {};
+
+var BYTES = new Uint8Array([1, 2, 8, 9]);
+
+var BYTES_B64 = goog.crypt.base64.encodeByteArray(BYTES);
+
+
+/**
+ * Helper: fill all fields on a TestAllTypes message.
+ * @param {proto.jspb.test.TestAllTypes} msg
+ */
+function fillAllFields(msg) {
+ msg.setOptionalInt32(-42);
+ // can be exactly represented by JS number (64-bit double, i.e., 52-bit
+ // mantissa).
+ msg.setOptionalInt64(-0x7fffffff00000000);
+ msg.setOptionalUint32(0x80000000);
+ msg.setOptionalUint64(0xf000000000000000);
+ msg.setOptionalSint32(-100);
+ msg.setOptionalSint64(-0x8000000000000000);
+ msg.setOptionalFixed32(1234);
+ msg.setOptionalFixed64(0x1234567800000000);
+ msg.setOptionalSfixed32(-1234);
+ msg.setOptionalSfixed64(-0x1234567800000000);
+ msg.setOptionalFloat(1.5);
+ msg.setOptionalDouble(-1.5);
+ msg.setOptionalBool(true);
+ msg.setOptionalString('hello world');
+ msg.setOptionalBytes(BYTES);
+ msg.setOptionalGroup(new proto.jspb.test.TestAllTypes.OptionalGroup());
+ msg.getOptionalGroup().setA(100);
+ var submsg = new proto.jspb.test.ForeignMessage();
+ submsg.setC(16);
+ msg.setOptionalForeignMessage(submsg);
+ msg.setOptionalForeignEnum(proto.jspb.test.ForeignEnum.FOREIGN_FOO);
+ msg.setOneofString('oneof');
+
+
+ msg.setRepeatedInt32List([-42]);
+ msg.setRepeatedInt64List([-0x7fffffff00000000]);
+ msg.setRepeatedUint32List([0x80000000]);
+ msg.setRepeatedUint64List([0xf000000000000000]);
+ msg.setRepeatedSint32List([-100]);
+ msg.setRepeatedSint64List([-0x8000000000000000]);
+ msg.setRepeatedFixed32List([1234]);
+ msg.setRepeatedFixed64List([0x1234567800000000]);
+ msg.setRepeatedSfixed32List([-1234]);
+ msg.setRepeatedSfixed64List([-0x1234567800000000]);
+ msg.setRepeatedFloatList([1.5]);
+ msg.setRepeatedDoubleList([-1.5]);
+ msg.setRepeatedBoolList([true]);
+ msg.setRepeatedStringList(['hello world']);
+ msg.setRepeatedBytesList([BYTES, BYTES]);
+ msg.setRepeatedGroupList([new proto.jspb.test.TestAllTypes.RepeatedGroup()]);
+ msg.getRepeatedGroupList()[0].setA(100);
+ submsg = new proto.jspb.test.ForeignMessage();
+ submsg.setC(1000);
+ msg.setRepeatedForeignMessageList([submsg]);
+ msg.setRepeatedForeignEnumList([proto.jspb.test.ForeignEnum.FOREIGN_FOO]);
+
+ msg.setPackedRepeatedInt32List([-42]);
+ msg.setPackedRepeatedInt64List([-0x7fffffff00000000]);
+ msg.setPackedRepeatedUint32List([0x80000000]);
+ msg.setPackedRepeatedUint64List([0xf000000000000000]);
+ msg.setPackedRepeatedSint32List([-100]);
+ msg.setPackedRepeatedSint64List([-0x8000000000000000]);
+ msg.setPackedRepeatedFixed32List([1234]);
+ msg.setPackedRepeatedFixed64List([0x1234567800000000]);
+ msg.setPackedRepeatedSfixed32List([-1234]);
+ msg.setPackedRepeatedSfixed64List([-0x1234567800000000]);
+ msg.setPackedRepeatedFloatList([1.5]);
+ msg.setPackedRepeatedDoubleList([-1.5]);
+ msg.setPackedRepeatedBoolList([true]);
+
+}
+
+
+/**
+ * Helper: compare a bytes field to an expected value
+ * @param {Uint8Array|string} arr
+ * @param {Uint8Array} expected
+ * @return {boolean}
+ */
+function bytesCompare(arr, expected) {
+ if (goog.isString(arr)) {
+ arr = goog.crypt.base64.decodeStringToUint8Array(arr);
+ }
+ if (arr.length != expected.length) {
+ return false;
+ }
+ for (var i = 0; i < arr.length; i++) {
+ if (arr[i] != expected[i]) {
+ return false;
+ }
+ }
+ return true;
+}
+
+
+/**
+ * Helper: verify contents of given TestAllTypes message as set by
+ * fillAllFields().
+ * @param {proto.jspb.test.TestAllTypes} original
+ * @param {proto.jspb.test.TestAllTypes} copy
+ */
+function checkAllFields(original, copy) {
+ assertTrue(jspb.Message.equals(original, copy));
+
+ assertEquals(copy.getOptionalInt32(), -42);
+ assertEquals(copy.getOptionalInt64(), -0x7fffffff00000000);
+ assertEquals(copy.getOptionalUint32(), 0x80000000);
+ assertEquals(copy.getOptionalUint64(), 0xf000000000000000);
+ assertEquals(copy.getOptionalSint32(), -100);
+ assertEquals(copy.getOptionalSint64(), -0x8000000000000000);
+ assertEquals(copy.getOptionalFixed32(), 1234);
+ assertEquals(copy.getOptionalFixed64(), 0x1234567800000000);
+ assertEquals(copy.getOptionalSfixed32(), -1234);
+ assertEquals(copy.getOptionalSfixed64(), -0x1234567800000000);
+ assertEquals(copy.getOptionalFloat(), 1.5);
+ assertEquals(copy.getOptionalDouble(), -1.5);
+ assertEquals(copy.getOptionalBool(), true);
+ assertEquals(copy.getOptionalString(), 'hello world');
+ assertEquals(true, bytesCompare(copy.getOptionalBytes(), BYTES));
+ assertEquals(true, bytesCompare(copy.getOptionalBytes_asU8(), BYTES));
+ assertEquals(
+ copy.getOptionalBytes_asB64(), goog.crypt.base64.encodeByteArray(BYTES));
+
+ assertEquals(copy.getOptionalGroup().getA(), 100);
+ assertEquals(copy.getOptionalForeignMessage().getC(), 16);
+ assertEquals(copy.getOptionalForeignEnum(),
+ proto.jspb.test.ForeignEnum.FOREIGN_FOO);
+
+
+ assertEquals(copy.getOneofString(), 'oneof');
+ assertEquals(copy.getOneofFieldCase(),
+ proto.jspb.test.TestAllTypes.OneofFieldCase.ONEOF_STRING);
+
+ assertElementsEquals(copy.getRepeatedInt32List(), [-42]);
+ assertElementsEquals(copy.getRepeatedInt64List(), [-0x7fffffff00000000]);
+ assertElementsEquals(copy.getRepeatedUint32List(), [0x80000000]);
+ assertElementsEquals(copy.getRepeatedUint64List(), [0xf000000000000000]);
+ assertElementsEquals(copy.getRepeatedSint32List(), [-100]);
+ assertElementsEquals(copy.getRepeatedSint64List(), [-0x8000000000000000]);
+ assertElementsEquals(copy.getRepeatedFixed32List(), [1234]);
+ assertElementsEquals(copy.getRepeatedFixed64List(), [0x1234567800000000]);
+ assertElementsEquals(copy.getRepeatedSfixed32List(), [-1234]);
+ assertElementsEquals(copy.getRepeatedSfixed64List(), [-0x1234567800000000]);
+ assertElementsEquals(copy.getRepeatedFloatList(), [1.5]);
+ assertElementsEquals(copy.getRepeatedDoubleList(), [-1.5]);
+ assertElementsEquals(copy.getRepeatedBoolList(), [true]);
+ assertElementsEquals(copy.getRepeatedStringList(), ['hello world']);
+ assertEquals(copy.getRepeatedBytesList().length, 2);
+ assertEquals(true, bytesCompare(copy.getRepeatedBytesList_asU8()[0], BYTES));
+ assertEquals(true, bytesCompare(copy.getRepeatedBytesList()[0], BYTES));
+ assertEquals(true, bytesCompare(copy.getRepeatedBytesList_asU8()[1], BYTES));
+ assertEquals(copy.getRepeatedBytesList_asB64()[0], BYTES_B64);
+ assertEquals(copy.getRepeatedBytesList_asB64()[1], BYTES_B64);
+ assertEquals(copy.getRepeatedGroupList().length, 1);
+ assertEquals(copy.getRepeatedGroupList()[0].getA(), 100);
+ assertEquals(copy.getRepeatedForeignMessageList().length, 1);
+ assertEquals(copy.getRepeatedForeignMessageList()[0].getC(), 1000);
+ assertElementsEquals(copy.getRepeatedForeignEnumList(),
+ [proto.jspb.test.ForeignEnum.FOREIGN_FOO]);
+
+ assertElementsEquals(copy.getPackedRepeatedInt32List(), [-42]);
+ assertElementsEquals(copy.getPackedRepeatedInt64List(),
+ [-0x7fffffff00000000]);
+ assertElementsEquals(copy.getPackedRepeatedUint32List(), [0x80000000]);
+ assertElementsEquals(copy.getPackedRepeatedUint64List(),
+ [0xf000000000000000]);
+ assertElementsEquals(copy.getPackedRepeatedSint32List(), [-100]);
+ assertElementsEquals(copy.getPackedRepeatedSint64List(),
+ [-0x8000000000000000]);
+ assertElementsEquals(copy.getPackedRepeatedFixed32List(), [1234]);
+ assertElementsEquals(copy.getPackedRepeatedFixed64List(),
+ [0x1234567800000000]);
+ assertElementsEquals(copy.getPackedRepeatedSfixed32List(), [-1234]);
+ assertElementsEquals(copy.getPackedRepeatedSfixed64List(),
+ [-0x1234567800000000]);
+ assertElementsEquals(copy.getPackedRepeatedFloatList(), [1.5]);
+ assertElementsEquals(copy.getPackedRepeatedDoubleList(), [-1.5]);
+
+}
+
+
+/**
+ * Helper: verify that all expected extensions are present.
+ * @param {!proto.jspb.test.TestExtendable} msg
+ */
+function checkExtensions(msg) {
+ assertEquals(-42,
+ msg.getExtension(proto.jspb.test.extendOptionalInt32));
+ assertEquals(-0x7fffffff00000000,
+ msg.getExtension(proto.jspb.test.extendOptionalInt64));
+ assertEquals(0x80000000,
+ msg.getExtension(proto.jspb.test.extendOptionalUint32));
+ assertEquals(0xf000000000000000,
+ msg.getExtension(proto.jspb.test.extendOptionalUint64));
+ assertEquals(-100,
+ msg.getExtension(proto.jspb.test.extendOptionalSint32));
+ assertEquals(-0x8000000000000000,
+ msg.getExtension(proto.jspb.test.extendOptionalSint64));
+ assertEquals(1234,
+ msg.getExtension(proto.jspb.test.extendOptionalFixed32));
+ assertEquals(0x1234567800000000,
+ msg.getExtension(proto.jspb.test.extendOptionalFixed64));
+ assertEquals(-1234,
+ msg.getExtension(proto.jspb.test.extendOptionalSfixed32));
+ assertEquals(-0x1234567800000000,
+ msg.getExtension(proto.jspb.test.extendOptionalSfixed64));
+ assertEquals(1.5,
+ msg.getExtension(proto.jspb.test.extendOptionalFloat));
+ assertEquals(-1.5,
+ msg.getExtension(proto.jspb.test.extendOptionalDouble));
+ assertEquals(true,
+ msg.getExtension(proto.jspb.test.extendOptionalBool));
+ assertEquals('hello world',
+ msg.getExtension(proto.jspb.test.extendOptionalString));
+ assertEquals(
+ true, bytesCompare(
+ msg.getExtension(proto.jspb.test.extendOptionalBytes), BYTES));
+ assertEquals(16,
+ msg.getExtension(
+ proto.jspb.test.ExtendsWithMessage.optionalExtension).getFoo());
+
+
+ assertElementsEquals(
+ msg.getExtension(proto.jspb.test.extendRepeatedInt32List),
+ [-42]);
+ assertElementsEquals(
+ msg.getExtension(proto.jspb.test.extendRepeatedInt64List),
+ [-0x7fffffff00000000]);
+ assertElementsEquals(
+ msg.getExtension(proto.jspb.test.extendRepeatedUint32List),
+ [0x80000000]);
+ assertElementsEquals(
+ msg.getExtension(proto.jspb.test.extendRepeatedUint64List),
+ [0xf000000000000000]);
+ assertElementsEquals(
+ msg.getExtension(proto.jspb.test.extendRepeatedSint32List),
+ [-100]);
+ assertElementsEquals(
+ msg.getExtension(proto.jspb.test.extendRepeatedSint64List),
+ [-0x8000000000000000]);
+ assertElementsEquals(
+ msg.getExtension(proto.jspb.test.extendRepeatedFixed32List),
+ [1234]);
+ assertElementsEquals(
+ msg.getExtension(proto.jspb.test.extendRepeatedFixed64List),
+ [0x1234567800000000]);
+ assertElementsEquals(
+ msg.getExtension(proto.jspb.test.extendRepeatedSfixed32List),
+ [-1234]);
+ assertElementsEquals(
+ msg.getExtension(proto.jspb.test.extendRepeatedSfixed64List),
+ [-0x1234567800000000]);
+ assertElementsEquals(
+ msg.getExtension(proto.jspb.test.extendRepeatedFloatList),
+ [1.5]);
+ assertElementsEquals(
+ msg.getExtension(proto.jspb.test.extendRepeatedDoubleList),
+ [-1.5]);
+ assertElementsEquals(
+ msg.getExtension(proto.jspb.test.extendRepeatedBoolList),
+ [true]);
+ assertElementsEquals(
+ msg.getExtension(proto.jspb.test.extendRepeatedStringList),
+ ['hello world']);
+ assertEquals(
+ true,
+ bytesCompare(
+ msg.getExtension(proto.jspb.test.extendRepeatedBytesList)[0], BYTES));
+ assertEquals(1000,
+ msg.getExtension(
+ proto.jspb.test.ExtendsWithMessage.repeatedExtensionList)[0]
+ .getFoo());
+ assertElementsEquals(
+ msg.getExtension(proto.jspb.test.extendRepeatedForeignEnumList),
+ [proto.jspb.test.ForeignEnum.FOREIGN_FOO]);
+
+
+ assertElementsEquals(
+ msg.getExtension(proto.jspb.test.extendPackedRepeatedInt32List),
+ [-42]);
+ assertElementsEquals(
+ msg.getExtension(proto.jspb.test.extendPackedRepeatedInt64List),
+ [-0x7fffffff00000000]);
+ assertElementsEquals(
+ msg.getExtension(proto.jspb.test.extendPackedRepeatedUint32List),
+ [0x80000000]);
+ assertElementsEquals(
+ msg.getExtension(proto.jspb.test.extendPackedRepeatedUint64List),
+ [0xf000000000000000]);
+ assertElementsEquals(
+ msg.getExtension(proto.jspb.test.extendPackedRepeatedSint32List),
+ [-100]);
+ assertElementsEquals(
+ msg.getExtension(proto.jspb.test.extendPackedRepeatedSint64List),
+ [-0x8000000000000000]);
+ assertElementsEquals(
+ msg.getExtension(proto.jspb.test.extendPackedRepeatedFixed32List),
+ [1234]);
+ assertElementsEquals(
+ msg.getExtension(proto.jspb.test.extendPackedRepeatedFixed64List),
+ [0x1234567800000000]);
+ assertElementsEquals(
+ msg.getExtension(proto.jspb.test.extendPackedRepeatedSfixed32List),
+ [-1234]);
+ assertElementsEquals(
+ msg.getExtension(proto.jspb.test.extendPackedRepeatedSfixed64List),
+ [-0x1234567800000000]);
+ assertElementsEquals(
+ msg.getExtension(proto.jspb.test.extendPackedRepeatedFloatList),
+ [1.5]);
+ assertElementsEquals(
+ msg.getExtension(proto.jspb.test.extendPackedRepeatedDoubleList),
+ [-1.5]);
+ assertElementsEquals(
+ msg.getExtension(proto.jspb.test.extendPackedRepeatedBoolList),
+ [true]);
+ assertElementsEquals(
+ msg.getExtension(proto.jspb.test.extendPackedRepeatedForeignEnumList),
+ [proto.jspb.test.ForeignEnum.FOREIGN_FOO]);
+
+}
+
+
+describe('protoBinaryTest', function() {
+ /**
+ * Tests a basic serialization-deserializaton round-trip with all supported
+ * field types (on the TestAllTypes message type).
+ */
+ it('testRoundTrip', function() {
+ var msg = new proto.jspb.test.TestAllTypes();
+ fillAllFields(msg);
+ var encoded = msg.serializeBinary();
+ var decoded = proto.jspb.test.TestAllTypes.deserializeBinary(encoded);
+ checkAllFields(msg, decoded);
+ });
+
+ /**
+ * Test that base64 string and Uint8Array are interchangeable in bytes fields.
+ */
+ it('testBytesFieldsGettersInterop', function() {
+ var msg = new proto.jspb.test.TestAllTypes();
+ // Set from a base64 string and check all the getters work.
+ msg.setOptionalBytes(BYTES_B64);
+ assertTrue(bytesCompare(msg.getOptionalBytes_asU8(), BYTES));
+ assertTrue(bytesCompare(msg.getOptionalBytes_asB64(), BYTES));
+ assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES));
+
+ // Test binary serialize round trip doesn't break it.
+ msg = proto.jspb.test.TestAllTypes.deserializeBinary(msg.serializeBinary());
+ assertTrue(bytesCompare(msg.getOptionalBytes_asU8(), BYTES));
+ assertTrue(bytesCompare(msg.getOptionalBytes_asB64(), BYTES));
+ assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES));
+
+ msg = new proto.jspb.test.TestAllTypes();
+ // Set from a Uint8Array and check all the getters work.
+ msg.setOptionalBytes(BYTES);
+ assertTrue(bytesCompare(msg.getOptionalBytes_asU8(), BYTES));
+ assertTrue(bytesCompare(msg.getOptionalBytes_asB64(), BYTES));
+ assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES));
+
+ });
+
+ /**
+ * Test that bytes setters will receive result of any of the getters.
+ */
+ it('testBytesFieldsSettersInterop', function() {
+ var msg = new proto.jspb.test.TestAllTypes();
+ msg.setOptionalBytes(BYTES);
+ assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES));
+
+ msg.setOptionalBytes(msg.getOptionalBytes());
+ assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES));
+ msg.setOptionalBytes(msg.getOptionalBytes_asB64());
+ assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES));
+ msg.setOptionalBytes(msg.getOptionalBytes_asU8());
+ assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES));
+ });
+
+ /**
+ * Test that bytes setters will receive result of any of the getters.
+ */
+ it('testRepeatedBytesGetters', function() {
+ var msg = new proto.jspb.test.TestAllTypes();
+
+ function assertGetters() {
+ assertTrue(goog.isString(msg.getRepeatedBytesList_asB64()[0]));
+ assertTrue(goog.isString(msg.getRepeatedBytesList_asB64()[1]));
+ assertTrue(msg.getRepeatedBytesList_asU8()[0] instanceof Uint8Array);
+ assertTrue(msg.getRepeatedBytesList_asU8()[1] instanceof Uint8Array);
+
+ assertTrue(bytesCompare(msg.getRepeatedBytesList()[0], BYTES));
+ assertTrue(bytesCompare(msg.getRepeatedBytesList()[1], BYTES));
+ assertTrue(bytesCompare(msg.getRepeatedBytesList_asB64()[0], BYTES));
+ assertTrue(bytesCompare(msg.getRepeatedBytesList_asB64()[1], BYTES));
+ assertTrue(bytesCompare(msg.getRepeatedBytesList_asU8()[0], BYTES));
+ assertTrue(bytesCompare(msg.getRepeatedBytesList_asU8()[1], BYTES));
+ }
+
+ msg.setRepeatedBytesList([BYTES, BYTES]);
+ assertGetters();
+
+ msg.setRepeatedBytesList([BYTES_B64, BYTES_B64]);
+ assertGetters();
+
+ msg.setRepeatedBytesList(null);
+ assertEquals(0, msg.getRepeatedBytesList().length);
+ assertEquals(0, msg.getRepeatedBytesList_asB64().length);
+ assertEquals(0, msg.getRepeatedBytesList_asU8().length);
+ });
+
+ /**
+ * Helper: fill all extension values.
+ * @param {proto.jspb.test.TestExtendable} msg
+ */
+ function fillExtensions(msg) {
+ msg.setExtension(
+ proto.jspb.test.extendOptionalInt32, -42);
+ msg.setExtension(
+ proto.jspb.test.extendOptionalInt64, -0x7fffffff00000000);
+ msg.setExtension(
+ proto.jspb.test.extendOptionalUint32, 0x80000000);
+ msg.setExtension(
+ proto.jspb.test.extendOptionalUint64, 0xf000000000000000);
+ msg.setExtension(
+ proto.jspb.test.extendOptionalSint32, -100);
+ msg.setExtension(
+ proto.jspb.test.extendOptionalSint64, -0x8000000000000000);
+ msg.setExtension(
+ proto.jspb.test.extendOptionalFixed32, 1234);
+ msg.setExtension(
+ proto.jspb.test.extendOptionalFixed64, 0x1234567800000000);
+ msg.setExtension(
+ proto.jspb.test.extendOptionalSfixed32, -1234);
+ msg.setExtension(
+ proto.jspb.test.extendOptionalSfixed64, -0x1234567800000000);
+ msg.setExtension(
+ proto.jspb.test.extendOptionalFloat, 1.5);
+ msg.setExtension(
+ proto.jspb.test.extendOptionalDouble, -1.5);
+ msg.setExtension(
+ proto.jspb.test.extendOptionalBool, true);
+ msg.setExtension(
+ proto.jspb.test.extendOptionalString, 'hello world');
+ msg.setExtension(proto.jspb.test.extendOptionalBytes, BYTES);
+ var submsg = new proto.jspb.test.ExtendsWithMessage();
+ submsg.setFoo(16);
+ msg.setExtension(
+ proto.jspb.test.ExtendsWithMessage.optionalExtension, submsg);
+ msg.setExtension(
+ proto.jspb.test.extendOptionalForeignEnum,
+ proto.jspb.test.ForeignEnum.FOREIGN_FOO);
+
+
+ msg.setExtension(
+ proto.jspb.test.extendRepeatedInt32List, [-42]);
+ msg.setExtension(
+ proto.jspb.test.extendRepeatedInt64List, [-0x7fffffff00000000]);
+ msg.setExtension(
+ proto.jspb.test.extendRepeatedUint32List, [0x80000000]);
+ msg.setExtension(
+ proto.jspb.test.extendRepeatedUint64List, [0xf000000000000000]);
+ msg.setExtension(
+ proto.jspb.test.extendRepeatedSint32List, [-100]);
+ msg.setExtension(
+ proto.jspb.test.extendRepeatedSint64List, [-0x8000000000000000]);
+ msg.setExtension(
+ proto.jspb.test.extendRepeatedFixed32List, [1234]);
+ msg.setExtension(
+ proto.jspb.test.extendRepeatedFixed64List, [0x1234567800000000]);
+ msg.setExtension(
+ proto.jspb.test.extendRepeatedSfixed32List, [-1234]);
+ msg.setExtension(
+ proto.jspb.test.extendRepeatedSfixed64List, [-0x1234567800000000]);
+ msg.setExtension(
+ proto.jspb.test.extendRepeatedFloatList, [1.5]);
+ msg.setExtension(
+ proto.jspb.test.extendRepeatedDoubleList, [-1.5]);
+ msg.setExtension(
+ proto.jspb.test.extendRepeatedBoolList, [true]);
+ msg.setExtension(
+ proto.jspb.test.extendRepeatedStringList, ['hello world']);
+ msg.setExtension(proto.jspb.test.extendRepeatedBytesList, [BYTES]);
+ submsg = new proto.jspb.test.ExtendsWithMessage();
+ submsg.setFoo(1000);
+ msg.setExtension(
+ proto.jspb.test.ExtendsWithMessage.repeatedExtensionList, [submsg]);
+ msg.setExtension(proto.jspb.test.extendRepeatedForeignEnumList,
+ [proto.jspb.test.ForeignEnum.FOREIGN_FOO]);
+
+
+ msg.setExtension(
+ proto.jspb.test.extendPackedRepeatedInt32List, [-42]);
+ msg.setExtension(
+ proto.jspb.test.extendPackedRepeatedInt64List, [-0x7fffffff00000000]);
+ msg.setExtension(
+ proto.jspb.test.extendPackedRepeatedUint32List, [0x80000000]);
+ msg.setExtension(
+ proto.jspb.test.extendPackedRepeatedUint64List, [0xf000000000000000]);
+ msg.setExtension(
+ proto.jspb.test.extendPackedRepeatedSint32List, [-100]);
+ msg.setExtension(
+ proto.jspb.test.extendPackedRepeatedSint64List, [-0x8000000000000000]);
+ msg.setExtension(
+ proto.jspb.test.extendPackedRepeatedFixed32List, [1234]);
+ msg.setExtension(
+ proto.jspb.test.extendPackedRepeatedFixed64List, [0x1234567800000000]);
+ msg.setExtension(
+ proto.jspb.test.extendPackedRepeatedSfixed32List, [-1234]);
+ msg.setExtension(
+ proto.jspb.test.extendPackedRepeatedSfixed64List,
+ [-0x1234567800000000]);
+ msg.setExtension(
+ proto.jspb.test.extendPackedRepeatedFloatList, [1.5]);
+ msg.setExtension(
+ proto.jspb.test.extendPackedRepeatedDoubleList, [-1.5]);
+ msg.setExtension(
+ proto.jspb.test.extendPackedRepeatedBoolList, [true]);
+ msg.setExtension(proto.jspb.test.extendPackedRepeatedForeignEnumList,
+ [proto.jspb.test.ForeignEnum.FOREIGN_FOO]);
+
+ }
+
+
+ /**
+ * Tests extension serialization and deserialization.
+ */
+ it('testExtensions', function() {
+ var msg = new proto.jspb.test.TestExtendable();
+ fillExtensions(msg);
+ var encoded = msg.serializeBinary();
+ var decoded = proto.jspb.test.TestExtendable.deserializeBinary(encoded);
+ checkExtensions(decoded);
+ });
+});
diff --git a/js/binary/reader.js b/js/binary/reader.js
new file mode 100644
index 00000000..15f90432
--- /dev/null
+++ b/js/binary/reader.js
@@ -0,0 +1,1127 @@
+// 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.
+
+/**
+ * @fileoverview This file contains utilities for converting binary,
+ * wire-format protocol buffers into Javascript data structures.
+ *
+ * jspb's BinaryReader class wraps the BinaryDecoder class to add methods
+ * that understand the protocol buffer syntax and can do the type checking and
+ * bookkeeping necessary to parse trees of nested messages.
+ *
+ * Major caveat - Users of this library _must_ keep their Javascript proto
+ * parsing code in sync with the original .proto file - presumably you'll be
+ * using the typed jspb code generator, but if you bypass that you'll need
+ * to keep things in sync by hand.
+ *
+ * @author aappleby@google.com (Austin Appleby)
+ */
+
+goog.provide('jspb.BinaryReader');
+
+goog.require('goog.asserts');
+goog.require('jspb.BinaryConstants');
+goog.require('jspb.BinaryDecoder');
+
+
+
+/**
+ * BinaryReader implements the decoders for all the wire types specified in
+ * https://developers.google.com/protocol-buffers/docs/encoding.
+ *
+ * @param {jspb.ByteSource=} opt_bytes The bytes we're reading from.
+ * @param {number=} opt_start The optional offset to start reading at.
+ * @param {number=} opt_length The optional length of the block to read -
+ * we'll throw an assertion if we go off the end of the block.
+ * @constructor
+ * @struct
+ */
+jspb.BinaryReader = function(opt_bytes, opt_start, opt_length) {
+ /**
+ * Wire-format decoder.
+ * @private {!jspb.BinaryDecoder}
+ */
+ this.decoder_ = jspb.BinaryDecoder.alloc(opt_bytes, opt_start, opt_length);
+
+ /**
+ * Cursor immediately before the field tag.
+ * @private {number}
+ */
+ this.fieldCursor_ = this.decoder_.getCursor();
+
+ /**
+ * Field number of the next field in the buffer, filled in by nextField().
+ * @private {number}
+ */
+ this.nextField_ = jspb.BinaryConstants.INVALID_FIELD_NUMBER;
+
+ /**
+ * Wire type of the next proto field in the buffer, filled in by
+ * nextField().
+ * @private {jspb.BinaryConstants.WireType}
+ */
+ this.nextWireType_ = jspb.BinaryConstants.WireType.INVALID;
+
+ /**
+ * Set to true if this reader encountered an error due to corrupt data.
+ * @private {boolean}
+ */
+ this.error_ = false;
+
+ /**
+ * User-defined reader callbacks.
+ * @private {Object.<string, function(!jspb.BinaryReader):*>}
+ */
+ this.readCallbacks_ = null;
+};
+
+
+/**
+ * Global pool of BinaryReader instances.
+ * @private {!Array.<!jspb.BinaryReader>}
+ */
+jspb.BinaryReader.instanceCache_ = [];
+
+
+/**
+ * Pops an instance off the instance cache, or creates one if the cache is
+ * empty.
+ * @param {jspb.ByteSource=} opt_bytes The bytes we're reading from.
+ * @param {number=} opt_start The optional offset to start reading at.
+ * @param {number=} opt_length The optional length of the block to read -
+ * we'll throw an assertion if we go off the end of the block.
+ * @return {!jspb.BinaryReader}
+ */
+jspb.BinaryReader.alloc =
+ function(opt_bytes, opt_start, opt_length) {
+ if (jspb.BinaryReader.instanceCache_.length) {
+ var newReader = jspb.BinaryReader.instanceCache_.pop();
+ if (opt_bytes) {
+ newReader.decoder_.setBlock(opt_bytes, opt_start, opt_length);
+ }
+ return newReader;
+ } else {
+ return new jspb.BinaryReader(opt_bytes, opt_start, opt_length);
+ }
+};
+
+
+/**
+ * Alias for the above method.
+ * @param {jspb.ByteSource=} opt_bytes The bytes we're reading from.
+ * @param {number=} opt_start The optional offset to start reading at.
+ * @param {number=} opt_length The optional length of the block to read -
+ * we'll throw an assertion if we go off the end of the block.
+ * @return {!jspb.BinaryReader}
+ */
+jspb.BinaryReader.prototype.alloc = jspb.BinaryReader.alloc;
+
+
+/**
+ * Puts this instance back in the instance cache.
+ */
+jspb.BinaryReader.prototype.free = function() {
+ this.decoder_.clear();
+ this.nextField_ = jspb.BinaryConstants.INVALID_FIELD_NUMBER;
+ this.nextWireType_ = jspb.BinaryConstants.WireType.INVALID;
+ this.error_ = false;
+ this.readCallbacks_ = null;
+
+ if (jspb.BinaryReader.instanceCache_.length < 100) {
+ jspb.BinaryReader.instanceCache_.push(this);
+ }
+};
+
+
+/**
+ * Returns the cursor immediately before the current field's tag.
+ * @return {number} The internal read cursor.
+ */
+jspb.BinaryReader.prototype.getFieldCursor = function() {
+ return this.fieldCursor_;
+};
+
+
+/**
+ * Returns the internal read cursor.
+ * @return {number} The internal read cursor.
+ */
+jspb.BinaryReader.prototype.getCursor = function() {
+ return this.decoder_.getCursor();
+};
+
+
+/**
+ * Returns the raw buffer.
+ * @return {?Uint8Array} The raw buffer.
+ */
+jspb.BinaryReader.prototype.getBuffer = function() {
+ return this.decoder_.getBuffer();
+};
+
+
+/**
+ * @return {number} The field number of the next field in the buffer, or
+ * INVALID_FIELD_NUMBER if there is no next field.
+ */
+jspb.BinaryReader.prototype.getFieldNumber = function() {
+ return this.nextField_;
+};
+
+
+/**
+ * @return {jspb.BinaryConstants.WireType} The wire type of the next field
+ * in the stream, or WireType.INVALID if there is no next field.
+ */
+jspb.BinaryReader.prototype.getWireType = function() {
+ return this.nextWireType_;
+};
+
+
+/**
+ * @return {boolean} Whether the current wire type is an end-group tag. Used as
+ * an exit condition in decoder loops in generated code.
+ */
+jspb.BinaryReader.prototype.isEndGroup = function() {
+ return this.nextWireType_ == jspb.BinaryConstants.WireType.END_GROUP;
+};
+
+
+/**
+ * Returns true if this reader hit an error due to corrupt data.
+ * @return {boolean}
+ */
+jspb.BinaryReader.prototype.getError = function() {
+ return this.error_ || this.decoder_.getError();
+};
+
+
+/**
+ * Points this reader at a new block of bytes.
+ * @param {!Uint8Array} bytes The block of bytes we're reading from.
+ * @param {number} start The offset to start reading at.
+ * @param {number} length The length of the block to read.
+ */
+jspb.BinaryReader.prototype.setBlock = function(bytes, start, length) {
+ this.decoder_.setBlock(bytes, start, length);
+ this.nextField_ = jspb.BinaryConstants.INVALID_FIELD_NUMBER;
+ this.nextWireType_ = jspb.BinaryConstants.WireType.INVALID;
+};
+
+
+/**
+ * Rewinds the stream cursor to the beginning of the buffer and resets all
+ * internal state.
+ */
+jspb.BinaryReader.prototype.reset = function() {
+ this.decoder_.reset();
+ this.nextField_ = jspb.BinaryConstants.INVALID_FIELD_NUMBER;
+ this.nextWireType_ = jspb.BinaryConstants.WireType.INVALID;
+};
+
+
+/**
+ * Advances the stream cursor by the given number of bytes.
+ * @param {number} count The number of bytes to advance by.
+ */
+jspb.BinaryReader.prototype.advance = function(count) {
+ this.decoder_.advance(count);
+};
+
+
+/**
+ * Reads the next field header in the stream if there is one, returns true if
+ * we saw a valid field header or false if we've read the whole stream.
+ * Throws an error if we encountered a deprecated START_GROUP/END_GROUP field.
+ * @return {boolean} True if the stream contains more fields.
+ */
+jspb.BinaryReader.prototype.nextField = function() {
+ // If we're at the end of the block, there are no more fields.
+ if (this.decoder_.atEnd()) {
+ return false;
+ }
+
+ // If we hit an error decoding the previous field, stop now before we
+ // try to decode anything else
+ if (this.getError()) {
+ goog.asserts.fail('Decoder hit an error');
+ return false;
+ }
+
+ // Otherwise just read the header of the next field.
+ this.fieldCursor_ = this.decoder_.getCursor();
+ var header = this.decoder_.readUnsignedVarint32();
+
+ var nextField = header >>> 3;
+ var nextWireType = /** @type {jspb.BinaryConstants.WireType} */
+ (header & 0x7);
+
+ // If the wire type isn't one of the valid ones, something's broken.
+ if (nextWireType != jspb.BinaryConstants.WireType.VARINT &&
+ nextWireType != jspb.BinaryConstants.WireType.FIXED32 &&
+ nextWireType != jspb.BinaryConstants.WireType.FIXED64 &&
+ nextWireType != jspb.BinaryConstants.WireType.DELIMITED &&
+ nextWireType != jspb.BinaryConstants.WireType.START_GROUP &&
+ nextWireType != jspb.BinaryConstants.WireType.END_GROUP) {
+ goog.asserts.fail('Invalid wire type');
+ this.error_ = true;
+ return false;
+ }
+
+ this.nextField_ = nextField;
+ this.nextWireType_ = nextWireType;
+
+ return true;
+};
+
+
+/**
+ * Winds the reader back to just before this field's header.
+ */
+jspb.BinaryReader.prototype.unskipHeader = function() {
+ this.decoder_.unskipVarint((this.nextField_ << 3) | this.nextWireType_);
+};
+
+
+/**
+ * Skips all contiguous fields whose header matches the one we just read.
+ */
+jspb.BinaryReader.prototype.skipMatchingFields = function() {
+ var field = this.nextField_;
+ this.unskipHeader();
+
+ while (this.nextField() && (this.getFieldNumber() == field)) {
+ this.skipField();
+ }
+
+ if (!this.decoder_.atEnd()) {
+ this.unskipHeader();
+ }
+};
+
+
+/**
+ * Skips over the next varint field in the binary stream.
+ */
+jspb.BinaryReader.prototype.skipVarintField = function() {
+ if (this.nextWireType_ != jspb.BinaryConstants.WireType.VARINT) {
+ goog.asserts.fail('Invalid wire type for skipVarintField');
+ this.skipField();
+ return;
+ }
+
+ this.decoder_.skipVarint();
+};
+
+
+/**
+ * Skips over the next delimited field in the binary stream.
+ */
+jspb.BinaryReader.prototype.skipDelimitedField = function() {
+ if (this.nextWireType_ != jspb.BinaryConstants.WireType.DELIMITED) {
+ goog.asserts.fail('Invalid wire type for skipDelimitedField');
+ this.skipField();
+ return;
+ }
+
+ var length = this.decoder_.readUnsignedVarint32();
+ this.decoder_.advance(length);
+};
+
+
+/**
+ * Skips over the next fixed32 field in the binary stream.
+ */
+jspb.BinaryReader.prototype.skipFixed32Field = function() {
+ if (this.nextWireType_ != jspb.BinaryConstants.WireType.FIXED32) {
+ goog.asserts.fail('Invalid wire type for skipFixed32Field');
+ this.skipField();
+ return;
+ }
+
+ this.decoder_.advance(4);
+};
+
+
+/**
+ * Skips over the next fixed64 field in the binary stream.
+ */
+jspb.BinaryReader.prototype.skipFixed64Field = function() {
+ if (this.nextWireType_ != jspb.BinaryConstants.WireType.FIXED64) {
+ goog.asserts.fail('Invalid wire type for skipFixed64Field');
+ this.skipField();
+ return;
+ }
+
+ this.decoder_.advance(8);
+};
+
+
+/**
+ * Skips over the next group field in the binary stream.
+ */
+jspb.BinaryReader.prototype.skipGroup = function() {
+ // Keep a stack of start-group tags that must be matched by end-group tags.
+ var nestedGroups = [this.nextField_];
+ do {
+ if (!this.nextField()) {
+ goog.asserts.fail('Unmatched start-group tag: stream EOF');
+ this.error_ = true;
+ return;
+ }
+ if (this.nextWireType_ ==
+ jspb.BinaryConstants.WireType.START_GROUP) {
+ // Nested group start.
+ nestedGroups.push(this.nextField_);
+ } else if (this.nextWireType_ ==
+ jspb.BinaryConstants.WireType.END_GROUP) {
+ // Group end: check that it matches top-of-stack.
+ if (this.nextField_ != nestedGroups.pop()) {
+ goog.asserts.fail('Unmatched end-group tag');
+ this.error_ = true;
+ return;
+ }
+ }
+ } while (nestedGroups.length > 0);
+};
+
+
+/**
+ * Skips over the next field in the binary stream - this is useful if we're
+ * decoding a message that contain unknown fields.
+ */
+jspb.BinaryReader.prototype.skipField = function() {
+ switch (this.nextWireType_) {
+ case jspb.BinaryConstants.WireType.VARINT:
+ this.skipVarintField();
+ break;
+ case jspb.BinaryConstants.WireType.FIXED64:
+ this.skipFixed64Field();
+ break;
+ case jspb.BinaryConstants.WireType.DELIMITED:
+ this.skipDelimitedField();
+ break;
+ case jspb.BinaryConstants.WireType.FIXED32:
+ this.skipFixed32Field();
+ break;
+ case jspb.BinaryConstants.WireType.START_GROUP:
+ this.skipGroup();
+ break;
+ default:
+ goog.asserts.fail('Invalid wire encoding for field.');
+ }
+};
+
+
+/**
+ * Registers a user-defined read callback.
+ * @param {string} callbackName
+ * @param {function(!jspb.BinaryReader):*} callback
+ */
+jspb.BinaryReader.prototype.registerReadCallback =
+ function(callbackName, callback) {
+ if (goog.isNull(this.readCallbacks_)) {
+ this.readCallbacks_ = {};
+ }
+ goog.asserts.assert(!this.readCallbacks_[callbackName]);
+ this.readCallbacks_[callbackName] = callback;
+};
+
+
+/**
+ * Runs a registered read callback.
+ * @param {string} callbackName The name the callback is registered under.
+ * @return {*} The value returned by the callback.
+ */
+jspb.BinaryReader.prototype.runReadCallback = function(callbackName) {
+ goog.asserts.assert(!goog.isNull(this.readCallbacks_));
+ var callback = this.readCallbacks_[callbackName];
+ goog.asserts.assert(callback);
+ return callback(this);
+};
+
+
+/**
+ * Reads a field of any valid non-message type from the binary stream.
+ * @param {jspb.BinaryConstants.FieldType} fieldType
+ * @return {jspb.AnyFieldType}
+ */
+jspb.BinaryReader.prototype.readAny = function(fieldType) {
+ this.nextWireType_ = jspb.BinaryConstants.FieldTypeToWireType(fieldType);
+ var fieldTypes = jspb.BinaryConstants.FieldType;
+ switch (fieldType) {
+ case fieldTypes.DOUBLE:
+ return this.readDouble();
+ case fieldTypes.FLOAT:
+ return this.readFloat();
+ case fieldTypes.INT64:
+ return this.readInt64();
+ case fieldTypes.UINT64:
+ return this.readUint64();
+ case fieldTypes.INT32:
+ return this.readInt32();
+ case fieldTypes.FIXED64:
+ return this.readFixed64();
+ case fieldTypes.FIXED32:
+ return this.readFixed32();
+ case fieldTypes.BOOL:
+ return this.readBool();
+ case fieldTypes.STRING:
+ return this.readString();
+ case fieldTypes.GROUP:
+ goog.asserts.fail('Group field type not supported in readAny()');
+ case fieldTypes.MESSAGE:
+ goog.asserts.fail('Message field type not supported in readAny()');
+ case fieldTypes.BYTES:
+ return this.readBytes();
+ case fieldTypes.UINT32:
+ return this.readUint32();
+ case fieldTypes.ENUM:
+ return this.readEnum();
+ case fieldTypes.SFIXED32:
+ return this.readSfixed32();
+ case fieldTypes.SFIXED64:
+ return this.readSfixed64();
+ case fieldTypes.SINT32:
+ return this.readSint32();
+ case fieldTypes.SINT64:
+ return this.readSint64();
+ case fieldTypes.FHASH64:
+ return this.readFixedHash64();
+ case fieldTypes.VHASH64:
+ return this.readVarintHash64();
+ default:
+ goog.asserts.fail('Invalid field type in readAny()');
+ }
+ return 0;
+};
+
+
+/**
+ * Deserialize a proto into the provided message object using the provided
+ * reader function. This function is templated as we currently have one client
+ * who is using manual deserialization instead of the code-generated versions.
+ * @template T
+ * @param {T} message
+ * @param {function(T, !jspb.BinaryReader)} reader
+ */
+jspb.BinaryReader.prototype.readMessage = function(message, reader) {
+ goog.asserts.assert(
+ this.nextWireType_ == jspb.BinaryConstants.WireType.DELIMITED);
+
+ // Save the current endpoint of the decoder and move it to the end of the
+ // embedded message.
+ var oldEnd = this.decoder_.getEnd();
+ var length = this.decoder_.readUnsignedVarint32();
+ var newEnd = this.decoder_.getCursor() + length;
+ this.decoder_.setEnd(newEnd);
+
+ // Deserialize the embedded message.
+ reader(message, this);
+
+ // Advance the decoder past the embedded message and restore the endpoint.
+ this.decoder_.setCursor(newEnd);
+ this.decoder_.setEnd(oldEnd);
+};
+
+
+/**
+ * Deserialize a proto into the provided message object using the provided
+ * reader function, assuming that the message is serialized as a group
+ * with the given tag.
+ * @template T
+ * @param {number} field
+ * @param {T} message
+ * @param {function(T, !jspb.BinaryReader)} reader
+ */
+jspb.BinaryReader.prototype.readGroup =
+ function(field, message, reader) {
+ // Ensure that the wire type is correct.
+ goog.asserts.assert(
+ this.nextWireType_ == jspb.BinaryConstants.WireType.START_GROUP);
+ // Ensure that the field number is correct.
+ goog.asserts.assert(this.nextField_ == field);
+
+ // Deserialize the message. The deserialization will stop at an END_GROUP tag.
+ reader(message, this);
+
+ if (!this.error_ &&
+ this.nextWireType_ != jspb.BinaryConstants.WireType.END_GROUP) {
+ goog.asserts.fail('Group submessage did not end with an END_GROUP tag');
+ this.error_ = true;
+ }
+};
+
+
+/**
+ * Return a decoder that wraps the current delimited field.
+ * @return {!jspb.BinaryDecoder}
+ */
+jspb.BinaryReader.prototype.getFieldDecoder = function() {
+ goog.asserts.assert(
+ this.nextWireType_ == jspb.BinaryConstants.WireType.DELIMITED);
+
+ var length = this.decoder_.readUnsignedVarint32();
+ var start = this.decoder_.getCursor();
+ var end = start + length;
+
+ var innerDecoder =
+ jspb.BinaryDecoder.alloc(this.decoder_.getBuffer(), start, length);
+ this.decoder_.setCursor(end);
+ return innerDecoder;
+};
+
+
+/**
+ * Reads a signed 32-bit integer field from the binary stream, or throws an
+ * error if the next field in the stream is not of the correct wire type.
+ *
+ * @return {number} The value of the signed 32-bit integer field.
+ */
+jspb.BinaryReader.prototype.readInt32 = function() {
+ goog.asserts.assert(
+ this.nextWireType_ == jspb.BinaryConstants.WireType.VARINT);
+ return this.decoder_.readSignedVarint32();
+};
+
+
+/**
+ * Reads a signed 32-bit integer field from the binary stream, or throws an
+ * error if the next field in the stream is not of the correct wire type.
+ *
+ * Returns the value as a string.
+ *
+ * @return {string} The value of the signed 32-bit integer field as a decimal
+ * string.
+ */
+jspb.BinaryReader.prototype.readInt32String = function() {
+ goog.asserts.assert(
+ this.nextWireType_ == jspb.BinaryConstants.WireType.VARINT);
+ return this.decoder_.readSignedVarint32String();
+};
+
+
+/**
+ * Reads a signed 64-bit integer field from the binary stream, or throws an
+ * error if the next field in the stream is not of the correct wire type.
+ *
+ * @return {number} The value of the signed 64-bit integer field.
+ */
+jspb.BinaryReader.prototype.readInt64 = function() {
+ goog.asserts.assert(
+ this.nextWireType_ == jspb.BinaryConstants.WireType.VARINT);
+ return this.decoder_.readSignedVarint64();
+};
+
+
+/**
+ * Reads a signed 64-bit integer field from the binary stream, or throws an
+ * error if the next field in the stream is not of the correct wire type.
+ *
+ * Returns the value as a string.
+ *
+ * @return {string} The value of the signed 64-bit integer field as a decimal
+ * string.
+ */
+jspb.BinaryReader.prototype.readInt64String = function() {
+ goog.asserts.assert(
+ this.nextWireType_ == jspb.BinaryConstants.WireType.VARINT);
+ return this.decoder_.readSignedVarint64String();
+};
+
+
+/**
+ * Reads an unsigned 32-bit integer field from the binary stream, or throws an
+ * error if the next field in the stream is not of the correct wire type.
+ *
+ * @return {number} The value of the unsigned 32-bit integer field.
+ */
+jspb.BinaryReader.prototype.readUint32 = function() {
+ goog.asserts.assert(
+ this.nextWireType_ == jspb.BinaryConstants.WireType.VARINT);
+ return this.decoder_.readUnsignedVarint32();
+};
+
+
+/**
+ * Reads an unsigned 32-bit integer field from the binary stream, or throws an
+ * error if the next field in the stream is not of the correct wire type.
+ *
+ * Returns the value as a string.
+ *
+ * @return {string} The value of the unsigned 32-bit integer field as a decimal
+ * string.
+ */
+jspb.BinaryReader.prototype.readUint32String = function() {
+ goog.asserts.assert(
+ this.nextWireType_ == jspb.BinaryConstants.WireType.VARINT);
+ return this.decoder_.readUnsignedVarint32String();
+};
+
+
+/**
+ * Reads an unsigned 64-bit integer field from the binary stream, or throws an
+ * error if the next field in the stream is not of the correct wire type.
+ *
+ * @return {number} The value of the unsigned 64-bit integer field.
+ */
+jspb.BinaryReader.prototype.readUint64 = function() {
+ goog.asserts.assert(
+ this.nextWireType_ == jspb.BinaryConstants.WireType.VARINT);
+ return this.decoder_.readUnsignedVarint64();
+};
+
+
+/**
+ * Reads an unsigned 64-bit integer field from the binary stream, or throws an
+ * error if the next field in the stream is not of the correct wire type.
+ *
+ * Returns the value as a string.
+ *
+ * @return {string} The value of the unsigned 64-bit integer field as a decimal
+ * string.
+ */
+jspb.BinaryReader.prototype.readUint64String = function() {
+ goog.asserts.assert(
+ this.nextWireType_ == jspb.BinaryConstants.WireType.VARINT);
+ return this.decoder_.readUnsignedVarint64String();
+};
+
+
+/**
+ * Reads a signed zigzag-encoded 32-bit integer field from the binary stream,
+ * or throws an error if the next field in the stream is not of the correct
+ * wire type.
+ *
+ * @return {number} The value of the signed 32-bit integer field.
+ */
+jspb.BinaryReader.prototype.readSint32 = function() {
+ goog.asserts.assert(
+ this.nextWireType_ == jspb.BinaryConstants.WireType.VARINT);
+ return this.decoder_.readZigzagVarint32();
+};
+
+
+/**
+ * Reads a signed zigzag-encoded 64-bit integer field from the binary stream,
+ * or throws an error if the next field in the stream is not of the correct
+ * wire type.
+ *
+ * @return {number} The value of the signed 64-bit integer field.
+ */
+jspb.BinaryReader.prototype.readSint64 = function() {
+ goog.asserts.assert(
+ this.nextWireType_ == jspb.BinaryConstants.WireType.VARINT);
+ return this.decoder_.readZigzagVarint64();
+};
+
+
+/**
+ * Reads an unsigned 32-bit fixed-length integer fiield from the binary stream,
+ * or throws an error if the next field in the stream is not of the correct
+ * wire type.
+ *
+ * @return {number} The value of the double field.
+ */
+jspb.BinaryReader.prototype.readFixed32 = function() {
+ goog.asserts.assert(
+ this.nextWireType_ == jspb.BinaryConstants.WireType.FIXED32);
+ return this.decoder_.readUint32();
+};
+
+
+/**
+ * Reads an unsigned 64-bit fixed-length integer fiield from the binary stream,
+ * or throws an error if the next field in the stream is not of the correct
+ * wire type.
+ *
+ * @return {number} The value of the float field.
+ */
+jspb.BinaryReader.prototype.readFixed64 = function() {
+ goog.asserts.assert(
+ this.nextWireType_ == jspb.BinaryConstants.WireType.FIXED64);
+ return this.decoder_.readUint64();
+};
+
+
+/**
+ * Reads a signed 32-bit fixed-length integer fiield from the binary stream, or
+ * throws an error if the next field in the stream is not of the correct wire
+ * type.
+ *
+ * @return {number} The value of the double field.
+ */
+jspb.BinaryReader.prototype.readSfixed32 = function() {
+ goog.asserts.assert(
+ this.nextWireType_ == jspb.BinaryConstants.WireType.FIXED32);
+ return this.decoder_.readInt32();
+};
+
+
+/**
+ * Reads a signed 64-bit fixed-length integer fiield from the binary stream, or
+ * throws an error if the next field in the stream is not of the correct wire
+ * type.
+ *
+ * @return {number} The value of the float field.
+ */
+jspb.BinaryReader.prototype.readSfixed64 = function() {
+ goog.asserts.assert(
+ this.nextWireType_ == jspb.BinaryConstants.WireType.FIXED64);
+ return this.decoder_.readInt64();
+};
+
+
+/**
+ * Reads a 32-bit floating-point field from the binary stream, or throws an
+ * error if the next field in the stream is not of the correct wire type.
+ *
+ * @return {number} The value of the float field.
+ */
+jspb.BinaryReader.prototype.readFloat = function() {
+ goog.asserts.assert(
+ this.nextWireType_ == jspb.BinaryConstants.WireType.FIXED32);
+ return this.decoder_.readFloat();
+};
+
+
+/**
+ * Reads a 64-bit floating-point field from the binary stream, or throws an
+ * error if the next field in the stream is not of the correct wire type.
+ *
+ * @return {number} The value of the double field.
+ */
+jspb.BinaryReader.prototype.readDouble = function() {
+ goog.asserts.assert(
+ this.nextWireType_ == jspb.BinaryConstants.WireType.FIXED64);
+ return this.decoder_.readDouble();
+};
+
+
+/**
+ * Reads a boolean field from the binary stream, or throws an error if the next
+ * field in the stream is not of the correct wire type.
+ *
+ * @return {boolean} The value of the boolean field.
+ */
+jspb.BinaryReader.prototype.readBool = function() {
+ goog.asserts.assert(
+ this.nextWireType_ == jspb.BinaryConstants.WireType.VARINT);
+ return !!this.decoder_.readUnsignedVarint32();
+};
+
+
+/**
+ * Reads an enum field from the binary stream, or throws an error if the next
+ * field in the stream is not of the correct wire type.
+ *
+ * @return {number} The value of the enum field.
+ */
+jspb.BinaryReader.prototype.readEnum = function() {
+ goog.asserts.assert(
+ this.nextWireType_ == jspb.BinaryConstants.WireType.VARINT);
+ return this.decoder_.readSignedVarint64();
+};
+
+
+/**
+ * Reads a string field from the binary stream, or throws an error if the next
+ * field in the stream is not of the correct wire type.
+ *
+ * @return {string} The value of the string field.
+ */
+jspb.BinaryReader.prototype.readString = function() {
+ goog.asserts.assert(
+ this.nextWireType_ == jspb.BinaryConstants.WireType.DELIMITED);
+ var length = this.decoder_.readUnsignedVarint32();
+ return this.decoder_.readString(length);
+};
+
+
+/**
+ * Reads a length-prefixed block of bytes from the binary stream, or returns
+ * null if the next field in the stream has an invalid length value.
+ *
+ * @return {!Uint8Array} The block of bytes.
+ */
+jspb.BinaryReader.prototype.readBytes = function() {
+ goog.asserts.assert(
+ this.nextWireType_ == jspb.BinaryConstants.WireType.DELIMITED);
+ var length = this.decoder_.readUnsignedVarint32();
+ return this.decoder_.readBytes(length);
+};
+
+
+/**
+ * Reads a 64-bit varint or fixed64 field from the stream and returns it as a
+ * 8-character Unicode string for use as a hash table key, or throws an error
+ * if the next field in the stream is not of the correct wire type.
+ *
+ * @return {string} The hash value.
+ */
+jspb.BinaryReader.prototype.readVarintHash64 = function() {
+ goog.asserts.assert(
+ this.nextWireType_ == jspb.BinaryConstants.WireType.VARINT);
+ return this.decoder_.readVarintHash64();
+};
+
+
+/**
+ * Reads a 64-bit varint or fixed64 field from the stream and returns it as a
+ * 8-character Unicode string for use as a hash table key, or throws an error
+ * if the next field in the stream is not of the correct wire type.
+ *
+ * @return {string} The hash value.
+ */
+jspb.BinaryReader.prototype.readFixedHash64 = function() {
+ goog.asserts.assert(
+ this.nextWireType_ == jspb.BinaryConstants.WireType.FIXED64);
+ return this.decoder_.readFixedHash64();
+};
+
+
+/**
+ * Reads a packed scalar field using the supplied raw reader function.
+ * @param {function()} decodeMethod
+ * @return {!Array}
+ * @private
+ */
+jspb.BinaryReader.prototype.readPackedField_ = function(decodeMethod) {
+ goog.asserts.assert(
+ this.nextWireType_ == jspb.BinaryConstants.WireType.DELIMITED);
+ var length = this.decoder_.readUnsignedVarint32();
+ var end = this.decoder_.getCursor() + length;
+ var result = [];
+ while (this.decoder_.getCursor() < end) {
+ // TODO(aappleby): .call is slow
+ result.push(decodeMethod.call(this.decoder_));
+ }
+ return result;
+};
+
+
+/**
+ * Reads a packed int32 field, which consists of a length header and a list of
+ * signed varints.
+ * @return {!Array.<number>}
+ */
+jspb.BinaryReader.prototype.readPackedInt32 = function() {
+ return this.readPackedField_(this.decoder_.readSignedVarint32);
+};
+
+
+/**
+ * Reads a packed int32 field, which consists of a length header and a list of
+ * signed varints. Returns a list of strings.
+ * @return {!Array.<string>}
+ */
+jspb.BinaryReader.prototype.readPackedInt32String = function() {
+ return this.readPackedField_(this.decoder_.readSignedVarint32String);
+};
+
+
+/**
+ * Reads a packed int64 field, which consists of a length header and a list of
+ * signed varints.
+ * @return {!Array.<number>}
+ */
+jspb.BinaryReader.prototype.readPackedInt64 = function() {
+ return this.readPackedField_(this.decoder_.readSignedVarint64);
+};
+
+
+/**
+ * Reads a packed int64 field, which consists of a length header and a list of
+ * signed varints. Returns a list of strings.
+ * @return {!Array.<string>}
+ */
+jspb.BinaryReader.prototype.readPackedInt64String = function() {
+ return this.readPackedField_(this.decoder_.readSignedVarint64String);
+};
+
+
+/**
+ * Reads a packed uint32 field, which consists of a length header and a list of
+ * unsigned varints.
+ * @return {!Array.<number>}
+ */
+jspb.BinaryReader.prototype.readPackedUint32 = function() {
+ return this.readPackedField_(this.decoder_.readUnsignedVarint32);
+};
+
+
+/**
+ * Reads a packed uint32 field, which consists of a length header and a list of
+ * unsigned varints. Returns a list of strings.
+ * @return {!Array.<string>}
+ */
+jspb.BinaryReader.prototype.readPackedUint32String = function() {
+ return this.readPackedField_(this.decoder_.readUnsignedVarint32String);
+};
+
+
+/**
+ * Reads a packed uint64 field, which consists of a length header and a list of
+ * unsigned varints.
+ * @return {!Array.<number>}
+ */
+jspb.BinaryReader.prototype.readPackedUint64 = function() {
+ return this.readPackedField_(this.decoder_.readUnsignedVarint64);
+};
+
+
+/**
+ * Reads a packed uint64 field, which consists of a length header and a list of
+ * unsigned varints. Returns a list of strings.
+ * @return {!Array.<string>}
+ */
+jspb.BinaryReader.prototype.readPackedUint64String = function() {
+ return this.readPackedField_(this.decoder_.readUnsignedVarint64String);
+};
+
+
+/**
+ * Reads a packed sint32 field, which consists of a length header and a list of
+ * zigzag varints.
+ * @return {!Array.<number>}
+ */
+jspb.BinaryReader.prototype.readPackedSint32 = function() {
+ return this.readPackedField_(this.decoder_.readZigzagVarint32);
+};
+
+
+/**
+ * Reads a packed sint64 field, which consists of a length header and a list of
+ * zigzag varints.
+ * @return {!Array.<number>}
+ */
+jspb.BinaryReader.prototype.readPackedSint64 = function() {
+ return this.readPackedField_(this.decoder_.readZigzagVarint64);
+};
+
+
+/**
+ * Reads a packed fixed32 field, which consists of a length header and a list
+ * of unsigned 32-bit ints.
+ * @return {!Array.<number>}
+ */
+jspb.BinaryReader.prototype.readPackedFixed32 = function() {
+ return this.readPackedField_(this.decoder_.readUint32);
+};
+
+
+/**
+ * Reads a packed fixed64 field, which consists of a length header and a list
+ * of unsigned 64-bit ints.
+ * @return {!Array.<number>}
+ */
+jspb.BinaryReader.prototype.readPackedFixed64 = function() {
+ return this.readPackedField_(this.decoder_.readUint64);
+};
+
+
+/**
+ * Reads a packed sfixed32 field, which consists of a length header and a list
+ * of 32-bit ints.
+ * @return {!Array.<number>}
+ */
+jspb.BinaryReader.prototype.readPackedSfixed32 = function() {
+ return this.readPackedField_(this.decoder_.readInt32);
+};
+
+
+/**
+ * Reads a packed sfixed64 field, which consists of a length header and a list
+ * of 64-bit ints.
+ * @return {!Array.<number>}
+ */
+jspb.BinaryReader.prototype.readPackedSfixed64 = function() {
+ return this.readPackedField_(this.decoder_.readInt64);
+};
+
+
+/**
+ * Reads a packed float field, which consists of a length header and a list of
+ * floats.
+ * @return {!Array.<number>}
+ */
+jspb.BinaryReader.prototype.readPackedFloat = function() {
+ return this.readPackedField_(this.decoder_.readFloat);
+};
+
+
+/**
+ * Reads a packed double field, which consists of a length header and a list of
+ * doubles.
+ * @return {!Array.<number>}
+ */
+jspb.BinaryReader.prototype.readPackedDouble = function() {
+ return this.readPackedField_(this.decoder_.readDouble);
+};
+
+
+/**
+ * Reads a packed bool field, which consists of a length header and a list of
+ * unsigned varints.
+ * @return {!Array.<boolean>}
+ */
+jspb.BinaryReader.prototype.readPackedBool = function() {
+ return this.readPackedField_(this.decoder_.readBool);
+};
+
+
+/**
+ * Reads a packed enum field, which consists of a length header and a list of
+ * unsigned varints.
+ * @return {!Array.<number>}
+ */
+jspb.BinaryReader.prototype.readPackedEnum = function() {
+ return this.readPackedField_(this.decoder_.readEnum);
+};
+
+
+/**
+ * Reads a packed varint hash64 field, which consists of a length header and a
+ * list of varint hash64s.
+ * @return {!Array.<string>}
+ */
+jspb.BinaryReader.prototype.readPackedVarintHash64 = function() {
+ return this.readPackedField_(this.decoder_.readVarintHash64);
+};
+
+
+/**
+ * Reads a packed fixed hash64 field, which consists of a length header and a
+ * list of fixed hash64s.
+ * @return {!Array.<string>}
+ */
+jspb.BinaryReader.prototype.readPackedFixedHash64 = function() {
+ return this.readPackedField_(this.decoder_.readFixedHash64);
+};
diff --git a/js/binary/reader_test.js b/js/binary/reader_test.js
new file mode 100644
index 00000000..95711385
--- /dev/null
+++ b/js/binary/reader_test.js
@@ -0,0 +1,922 @@
+// 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.
+
+/**
+ * @fileoverview Test cases for jspb's binary protocol buffer reader.
+ *
+ * There are two particular magic numbers that need to be pointed out -
+ * 2^64-1025 is the largest number representable as both a double and an
+ * unsigned 64-bit integer, and 2^63-513 is the largest number representable as
+ * both a double and a signed 64-bit integer.
+ *
+ * Test suite is written using Jasmine -- see http://jasmine.github.io/
+ *
+ * @author aappleby@google.com (Austin Appleby)
+ */
+
+goog.require('goog.testing.asserts');
+goog.require('jspb.BinaryConstants');
+goog.require('jspb.BinaryDecoder');
+goog.require('jspb.BinaryReader');
+goog.require('jspb.BinaryWriter');
+
+
+
+describe('binaryReaderTest', function() {
+ /**
+ * Tests the reader instance cache.
+ */
+ it('testInstanceCaches', /** @suppress {visibility} */ function() {
+ var writer = new jspb.BinaryWriter();
+ var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
+ writer.writeMessage(1, dummyMessage, goog.nullFunction);
+ writer.writeMessage(2, dummyMessage, goog.nullFunction);
+
+ var buffer = writer.getResultBuffer();
+
+ // Empty the instance caches.
+ jspb.BinaryReader.instanceCache_ = [];
+
+ // Allocating and then freeing three decoders should leave us with three in
+ // the cache.
+
+ var decoder1 = jspb.BinaryDecoder.alloc();
+ var decoder2 = jspb.BinaryDecoder.alloc();
+ var decoder3 = jspb.BinaryDecoder.alloc();
+ decoder1.free();
+ decoder2.free();
+ decoder3.free();
+
+ assertEquals(3, jspb.BinaryDecoder.instanceCache_.length);
+ assertEquals(0, jspb.BinaryReader.instanceCache_.length);
+
+ // Allocating and then freeing a reader should remove one decoder from its
+ // cache, but it should stay stuck to the reader afterwards since we can't
+ // have a reader without a decoder.
+ jspb.BinaryReader.alloc().free();
+
+ assertEquals(2, jspb.BinaryDecoder.instanceCache_.length);
+ assertEquals(1, jspb.BinaryReader.instanceCache_.length);
+
+ // Allocating a reader should remove a reader from the cache.
+ var reader = jspb.BinaryReader.alloc(buffer);
+
+ assertEquals(2, jspb.BinaryDecoder.instanceCache_.length);
+ assertEquals(0, jspb.BinaryReader.instanceCache_.length);
+
+ // Processing the message reuses the current reader.
+ reader.nextField();
+ assertEquals(1, reader.getFieldNumber());
+ reader.readMessage(dummyMessage, function() {
+ assertEquals(0, jspb.BinaryReader.instanceCache_.length);
+ });
+
+ reader.nextField();
+ assertEquals(2, reader.getFieldNumber());
+ reader.readMessage(dummyMessage, function() {
+ assertEquals(0, jspb.BinaryReader.instanceCache_.length);
+ });
+
+ assertEquals(false, reader.nextField());
+
+ assertEquals(2, jspb.BinaryDecoder.instanceCache_.length);
+ assertEquals(0, jspb.BinaryReader.instanceCache_.length);
+
+ // Freeing the reader should put it back into the cache.
+ reader.free();
+
+ assertEquals(2, jspb.BinaryDecoder.instanceCache_.length);
+ assertEquals(1, jspb.BinaryReader.instanceCache_.length);
+ });
+
+
+ /**
+ * @param {number} x
+ * @return {number}
+ */
+ function truncate(x) {
+ var temp = new Float32Array(1);
+ temp[0] = x;
+ return temp[0];
+ }
+
+
+ /**
+ * Verifies that misuse of the reader class triggers assertions.
+ */
+ it('testReadErrors', /** @suppress {checkTypes|visibility} */ function() {
+ // Calling readMessage on a non-delimited field should trigger an
+ // assertion.
+ var reader = jspb.BinaryReader.alloc([8, 1]);
+ var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
+ reader.nextField();
+ assertThrows(function() {
+ reader.readMessage(dummyMessage, goog.nullFunction);
+ });
+
+ // Reading past the end of the stream should trigger an assertion.
+ reader = jspb.BinaryReader.alloc([9, 1]);
+ reader.nextField();
+ assertThrows(function() {reader.readFixed64()});
+
+ // Reading past the end of a submessage should trigger an assertion.
+ reader = jspb.BinaryReader.alloc([10, 4, 13, 1, 1, 1]);
+ reader.nextField();
+ reader.readMessage(dummyMessage, function() {
+ reader.nextField();
+ assertThrows(function() {reader.readFixed32()});
+ });
+
+ // Skipping an invalid field should trigger an assertion.
+ reader = jspb.BinaryReader.alloc([12, 1]);
+ reader.nextWireType_ = 1000;
+ assertThrows(function() {reader.skipField()});
+
+ // Reading fields with the wrong wire type should assert.
+ reader = jspb.BinaryReader.alloc([9, 0, 0, 0, 0, 0, 0, 0, 0]);
+ reader.nextField();
+ assertThrows(function() {reader.readInt32()});
+ assertThrows(function() {reader.readInt32String()});
+ assertThrows(function() {reader.readInt64()});
+ assertThrows(function() {reader.readInt64String()});
+ assertThrows(function() {reader.readUint32()});
+ assertThrows(function() {reader.readUint32String()});
+ assertThrows(function() {reader.readUint64()});
+ assertThrows(function() {reader.readUint64String()});
+ assertThrows(function() {reader.readSint32()});
+ assertThrows(function() {reader.readBool()});
+ assertThrows(function() {reader.readEnum()});
+
+ reader = jspb.BinaryReader.alloc([8, 1]);
+ reader.nextField();
+ assertThrows(function() {reader.readFixed32()});
+ assertThrows(function() {reader.readFixed64()});
+ assertThrows(function() {reader.readSfixed32()});
+ assertThrows(function() {reader.readSfixed64()});
+ assertThrows(function() {reader.readFloat()});
+ assertThrows(function() {reader.readDouble()});
+
+ assertThrows(function() {reader.readString()});
+ assertThrows(function() {reader.readBytes()});
+ });
+
+
+ /**
+ * Tests encoding and decoding of unsigned field types.
+ * @param {Function} readField
+ * @param {Function} writeField
+ * @param {number} epsilon
+ * @param {number} upperLimit
+ * @param {Function} filter
+ * @private
+ * @suppress {missingProperties}
+ */
+ var doTestUnsignedField_ = function(readField,
+ writeField, epsilon, upperLimit, filter) {
+ assertNotNull(readField);
+ assertNotNull(writeField);
+
+ var writer = new jspb.BinaryWriter();
+
+ // Encode zero and limits.
+ writeField.call(writer, 1, filter(0));
+ writeField.call(writer, 2, filter(epsilon));
+ writeField.call(writer, 3, filter(upperLimit));
+
+ // Encode positive values.
+ for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) {
+ writeField.call(writer, 4, filter(cursor));
+ }
+
+ var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());
+
+ // Check zero and limits.
+ reader.nextField();
+ assertEquals(1, reader.getFieldNumber());
+ assertEquals(filter(0), readField.call(reader));
+
+ reader.nextField();
+ assertEquals(2, reader.getFieldNumber());
+ assertEquals(filter(epsilon), readField.call(reader));
+
+ reader.nextField();
+ assertEquals(3, reader.getFieldNumber());
+ assertEquals(filter(upperLimit), readField.call(reader));
+
+ // Check positive values.
+ for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) {
+ reader.nextField();
+ if (4 != reader.getFieldNumber()) throw 'fail!';
+ if (filter(cursor) != readField.call(reader)) throw 'fail!';
+ }
+ };
+
+
+ /**
+ * Tests encoding and decoding of signed field types.
+ * @param {Function} readField
+ * @param {Function} writeField
+ * @param {number} epsilon
+ * @param {number} lowerLimit
+ * @param {number} upperLimit
+ * @param {Function} filter
+ * @private
+ * @suppress {missingProperties}
+ */
+ var doTestSignedField_ = function(readField,
+ writeField, epsilon, lowerLimit, upperLimit, filter) {
+ var writer = new jspb.BinaryWriter();
+
+ // Encode zero and limits.
+ writeField.call(writer, 1, filter(lowerLimit));
+ writeField.call(writer, 2, filter(-epsilon));
+ writeField.call(writer, 3, filter(0));
+ writeField.call(writer, 4, filter(epsilon));
+ writeField.call(writer, 5, filter(upperLimit));
+
+ var inputValues = [];
+
+ // Encode negative values.
+ for (var cursor = lowerLimit; cursor < -epsilon; cursor /= 1.1) {
+ var val = filter(cursor);
+ writeField.call(writer, 6, val);
+ inputValues.push({
+ fieldNumber: 6,
+ value: val
+ });
+ }
+
+ // Encode positive values.
+ for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) {
+ var val = filter(cursor);
+ writeField.call(writer, 7, val);
+ inputValues.push({
+ fieldNumber: 7,
+ value: val
+ });
+ }
+
+ var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());
+
+ // Check zero and limits.
+ reader.nextField();
+ assertEquals(1, reader.getFieldNumber());
+ assertEquals(filter(lowerLimit), readField.call(reader));
+
+ reader.nextField();
+ assertEquals(2, reader.getFieldNumber());
+ assertEquals(filter(-epsilon), readField.call(reader));
+
+ reader.nextField();
+ assertEquals(3, reader.getFieldNumber());
+ assertEquals(filter(0), readField.call(reader));
+
+ reader.nextField();
+ assertEquals(4, reader.getFieldNumber());
+ assertEquals(filter(epsilon), readField.call(reader));
+
+ reader.nextField();
+ assertEquals(5, reader.getFieldNumber());
+ assertEquals(filter(upperLimit), readField.call(reader));
+
+ for (var i = 0; i < inputValues.length; i++) {
+ var expected = inputValues[i];
+ reader.nextField();
+ assertEquals(expected.fieldNumber, reader.getFieldNumber());
+ assertEquals(expected.value, readField.call(reader));
+ }
+ };
+
+
+ /**
+ * Tests fields that use varint encoding.
+ */
+ it('testVarintFields', function() {
+ assertNotUndefined(jspb.BinaryReader.prototype.readUint32);
+ assertNotUndefined(jspb.BinaryWriter.prototype.writeUint32);
+ assertNotUndefined(jspb.BinaryReader.prototype.readUint64);
+ assertNotUndefined(jspb.BinaryWriter.prototype.writeUint64);
+ assertNotUndefined(jspb.BinaryReader.prototype.readBool);
+ assertNotUndefined(jspb.BinaryWriter.prototype.writeBool);
+ doTestUnsignedField_(
+ jspb.BinaryReader.prototype.readUint32,
+ jspb.BinaryWriter.prototype.writeUint32,
+ 1, Math.pow(2, 32) - 1, Math.round);
+
+ doTestUnsignedField_(
+ jspb.BinaryReader.prototype.readUint64,
+ jspb.BinaryWriter.prototype.writeUint64,
+ 1, Math.pow(2, 64) - 1025, Math.round);
+
+ doTestSignedField_(
+ jspb.BinaryReader.prototype.readInt32,
+ jspb.BinaryWriter.prototype.writeInt32,
+ 1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round);
+
+ doTestSignedField_(
+ jspb.BinaryReader.prototype.readInt64,
+ jspb.BinaryWriter.prototype.writeInt64,
+ 1, -Math.pow(2, 63), Math.pow(2, 63) - 513, Math.round);
+
+ doTestSignedField_(
+ jspb.BinaryReader.prototype.readEnum,
+ jspb.BinaryWriter.prototype.writeEnum,
+ 1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round);
+
+ doTestUnsignedField_(
+ jspb.BinaryReader.prototype.readBool,
+ jspb.BinaryWriter.prototype.writeBool,
+ 1, 1, function(x) { return !!x; });
+ });
+
+
+ /**
+ * Tests reading a field from hexadecimal string (format: '08 BE EF').
+ * @param {Function} readField
+ * @param {number} expected
+ * @param {string} hexString
+ */
+ function doTestHexStringVarint_(readField, expected, hexString) {
+ var bytesCount = (hexString.length + 1) / 3;
+ var bytes = new Uint8Array(bytesCount);
+ for (var i = 0; i < bytesCount; i++) {
+ bytes[i] = parseInt(hexString.substring(i * 3, i * 3 + 2), 16);
+ }
+ var reader = jspb.BinaryReader.alloc(bytes);
+ reader.nextField();
+ assertEquals(expected, readField.call(reader));
+ }
+
+
+ /**
+ * Tests non-canonical redundant varint decoding.
+ */
+ it('testRedundantVarintFields', function() {
+ assertNotNull(jspb.BinaryReader.prototype.readUint32);
+ assertNotNull(jspb.BinaryReader.prototype.readUint64);
+ assertNotNull(jspb.BinaryReader.prototype.readSint32);
+ assertNotNull(jspb.BinaryReader.prototype.readSint64);
+
+ // uint32 and sint32 take no more than 5 bytes
+ // 08 - field prefix (type = 0 means varint)
+ doTestHexStringVarint_(
+ jspb.BinaryReader.prototype.readUint32,
+ 12, '08 8C 80 80 80 00');
+
+ // 11 stands for -6 in zigzag encoding
+ doTestHexStringVarint_(
+ jspb.BinaryReader.prototype.readSint32,
+ -6, '08 8B 80 80 80 00');
+
+ // uint64 and sint64 take no more than 10 bytes
+ // 08 - field prefix (type = 0 means varint)
+ doTestHexStringVarint_(
+ jspb.BinaryReader.prototype.readUint64,
+ 12, '08 8C 80 80 80 80 80 80 80 80 00');
+
+ // 11 stands for -6 in zigzag encoding
+ doTestHexStringVarint_(
+ jspb.BinaryReader.prototype.readSint64,
+ -6, '08 8B 80 80 80 80 80 80 80 80 00');
+ });
+
+
+ /**
+ * Tests 64-bit fields that are handled as strings.
+ */
+ it('testStringInt64Fields', function() {
+ var writer = new jspb.BinaryWriter();
+
+ var testSignedData = [
+ '2730538252207801776',
+ '-2688470994844604560',
+ '3398529779486536359',
+ '3568577411627971000',
+ '272477188847484900',
+ '-6649058714086158188',
+ '-7695254765712060806',
+ '-4525541438037104029',
+ '-4993706538836508568',
+ '4990160321893729138'
+ ];
+ var testUnsignedData = [
+ '7822732630241694882',
+ '6753602971916687352',
+ '2399935075244442116',
+ '8724292567325338867',
+ '16948784802625696584',
+ '4136275908516066934',
+ '3575388346793700364',
+ '5167142028379259461',
+ '1557573948689737699',
+ '17100725280812548567'
+ ];
+
+ for (var i = 0; i < testSignedData.length; i++) {
+ writer.writeInt64String(2 * i + 1, testSignedData[i]);
+ writer.writeUint64String(2 * i + 2, testUnsignedData[i]);
+ }
+
+ var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());
+
+ for (var i = 0; i < testSignedData.length; i++) {
+ reader.nextField();
+ assertEquals(2 * i + 1, reader.getFieldNumber());
+ assertEquals(testSignedData[i], reader.readInt64String());
+ reader.nextField();
+ assertEquals(2 * i + 2, reader.getFieldNumber());
+ assertEquals(testUnsignedData[i], reader.readUint64String());
+ }
+ });
+
+
+ /**
+ * Tests fields that use zigzag encoding.
+ */
+ it('testZigzagFields', function() {
+ doTestSignedField_(
+ jspb.BinaryReader.prototype.readSint32,
+ jspb.BinaryWriter.prototype.writeSint32,
+ 1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round);
+
+ doTestSignedField_(
+ jspb.BinaryReader.prototype.readSint64,
+ jspb.BinaryWriter.prototype.writeSint64,
+ 1, -Math.pow(2, 63), Math.pow(2, 63) - 513, Math.round);
+ });
+
+
+ /**
+ * Tests fields that use fixed-length encoding.
+ */
+ it('testFixedFields', function() {
+ doTestUnsignedField_(
+ jspb.BinaryReader.prototype.readFixed32,
+ jspb.BinaryWriter.prototype.writeFixed32,
+ 1, Math.pow(2, 32) - 1, Math.round);
+
+ doTestUnsignedField_(
+ jspb.BinaryReader.prototype.readFixed64,
+ jspb.BinaryWriter.prototype.writeFixed64,
+ 1, Math.pow(2, 64) - 1025, Math.round);
+
+ doTestSignedField_(
+ jspb.BinaryReader.prototype.readSfixed32,
+ jspb.BinaryWriter.prototype.writeSfixed32,
+ 1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round);
+
+ doTestSignedField_(
+ jspb.BinaryReader.prototype.readSfixed64,
+ jspb.BinaryWriter.prototype.writeSfixed64,
+ 1, -Math.pow(2, 63), Math.pow(2, 63) - 513, Math.round);
+ });
+
+
+ /**
+ * Tests floating point fields.
+ */
+ it('testFloatFields', function() {
+ doTestSignedField_(
+ jspb.BinaryReader.prototype.readFloat,
+ jspb.BinaryWriter.prototype.writeFloat,
+ jspb.BinaryConstants.FLOAT32_MIN,
+ -jspb.BinaryConstants.FLOAT32_MAX,
+ jspb.BinaryConstants.FLOAT32_MAX,
+ truncate);
+
+ doTestSignedField_(
+ jspb.BinaryReader.prototype.readDouble,
+ jspb.BinaryWriter.prototype.writeDouble,
+ jspb.BinaryConstants.FLOAT64_EPS * 10,
+ -jspb.BinaryConstants.FLOAT64_MIN,
+ jspb.BinaryConstants.FLOAT64_MIN,
+ function(x) { return x; });
+ });
+
+
+ /**
+ * Tests length-delimited string fields.
+ */
+ it('testStringFields', function() {
+ var s1 = 'The quick brown fox jumps over the lazy dog.';
+ var s2 = '人人生而自由,在尊嚴和權利上一律平等。';
+
+ var writer = new jspb.BinaryWriter();
+
+ writer.writeString(1, s1);
+ writer.writeString(2, s2);
+
+ var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());
+
+ reader.nextField();
+ assertEquals(1, reader.getFieldNumber());
+ assertEquals(s1, reader.readString());
+
+ reader.nextField();
+ assertEquals(2, reader.getFieldNumber());
+ assertEquals(s2, reader.readString());
+ });
+
+
+ /**
+ * Tests length-delimited byte fields.
+ */
+ it('testByteFields', function() {
+ var message = [];
+ var lowerLimit = 1;
+ var upperLimit = 256;
+ var scale = 1.1;
+
+ var writer = new jspb.BinaryWriter();
+
+ for (var cursor = lowerLimit; cursor < upperLimit; cursor *= 1.1) {
+ var len = Math.round(cursor);
+ var bytes = [];
+ for (var i = 0; i < len; i++) bytes.push(i % 256);
+
+ writer.writeBytes(len, bytes);
+ }
+
+ var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());
+
+ for (var cursor = lowerLimit; reader.nextField(); cursor *= 1.1) {
+ var len = Math.round(cursor);
+ if (len != reader.getFieldNumber()) throw 'fail!';
+
+ var bytes = reader.readBytes();
+ if (len != bytes.length) throw 'fail!';
+ for (var i = 0; i < bytes.length; i++) {
+ if (i % 256 != bytes[i]) throw 'fail!';
+ }
+ }
+ });
+
+
+ /**
+ * Tests nested messages.
+ */
+ it('testNesting', function() {
+ var writer = new jspb.BinaryWriter();
+ var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
+
+ writer.writeInt32(1, 100);
+
+ // Add one message with 3 int fields.
+ writer.writeMessage(2, dummyMessage, function() {
+ writer.writeInt32(3, 300);
+ writer.writeInt32(4, 400);
+ writer.writeInt32(5, 500);
+ });
+
+ // Add one empty message.
+ writer.writeMessage(6, dummyMessage, goog.nullFunction);
+
+ writer.writeInt32(7, 700);
+
+ var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());
+
+ // Validate outermost message.
+
+ reader.nextField();
+ assertEquals(1, reader.getFieldNumber());
+ assertEquals(100, reader.readInt32());
+
+ reader.nextField();
+ assertEquals(2, reader.getFieldNumber());
+ reader.readMessage(dummyMessage, function() {
+ // Validate embedded message 1.
+ reader.nextField();
+ assertEquals(3, reader.getFieldNumber());
+ assertEquals(300, reader.readInt32());
+
+ reader.nextField();
+ assertEquals(4, reader.getFieldNumber());
+ assertEquals(400, reader.readInt32());
+
+ reader.nextField();
+ assertEquals(5, reader.getFieldNumber());
+ assertEquals(500, reader.readInt32());
+
+ assertEquals(false, reader.nextField());
+ });
+
+ reader.nextField();
+ assertEquals(6, reader.getFieldNumber());
+ reader.readMessage(dummyMessage, function() {
+ // Validate embedded message 2.
+
+ assertEquals(false, reader.nextField());
+ });
+
+ reader.nextField();
+ assertEquals(7, reader.getFieldNumber());
+ assertEquals(700, reader.readInt32());
+
+ assertEquals(false, reader.nextField());
+ });
+
+ /**
+ * Tests skipping fields of each type by interleaving them with sentinel
+ * values and skipping everything that's not a sentinel.
+ */
+ it('testSkipField', function() {
+ var writer = new jspb.BinaryWriter();
+
+ var sentinel = 123456789;
+
+ // Write varint fields of different sizes.
+ writer.writeInt32(1, sentinel);
+ writer.writeInt32(1, 1);
+ writer.writeInt32(1, 1000);
+ writer.writeInt32(1, 1000000);
+ writer.writeInt32(1, 1000000000);
+
+ // Write fixed 64-bit encoded fields.
+ writer.writeInt32(2, sentinel);
+ writer.writeDouble(2, 1);
+ writer.writeFixed64(2, 1);
+ writer.writeSfixed64(2, 1);
+
+ // Write fixed 32-bit encoded fields.
+ writer.writeInt32(3, sentinel);
+ writer.writeFloat(3, 1);
+ writer.writeFixed32(3, 1);
+ writer.writeSfixed32(3, 1);
+
+ // Write delimited fields.
+ writer.writeInt32(4, sentinel);
+ writer.writeBytes(4, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
+ writer.writeString(4, 'The quick brown fox jumps over the lazy dog');
+
+ // Write a group with a nested group inside.
+ writer.writeInt32(5, sentinel);
+ var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
+ writer.writeGroup(5, dummyMessage, function() {
+ writer.writeInt64(42, 42);
+ writer.writeGroup(6, dummyMessage, function() {
+ writer.writeInt64(84, 42);
+ });
+ });
+
+ // Write final sentinel.
+ writer.writeInt32(6, sentinel);
+
+ var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());
+
+ function skip(field, count) {
+ for (var i = 0; i < count; i++) {
+ reader.nextField();
+ if (field != reader.getFieldNumber()) throw 'fail!';
+ reader.skipField();
+ }
+ }
+
+ reader.nextField();
+ assertEquals(1, reader.getFieldNumber());
+ assertEquals(sentinel, reader.readInt32());
+ skip(1, 4);
+
+ reader.nextField();
+ assertEquals(2, reader.getFieldNumber());
+ assertEquals(sentinel, reader.readInt32());
+ skip(2, 3);
+
+ reader.nextField();
+ assertEquals(3, reader.getFieldNumber());
+ assertEquals(sentinel, reader.readInt32());
+ skip(3, 3);
+
+ reader.nextField();
+ assertEquals(4, reader.getFieldNumber());
+ assertEquals(sentinel, reader.readInt32());
+ skip(4, 2);
+
+ reader.nextField();
+ assertEquals(5, reader.getFieldNumber());
+ assertEquals(sentinel, reader.readInt32());
+ skip(5, 1);
+
+ reader.nextField();
+ assertEquals(6, reader.getFieldNumber());
+ assertEquals(sentinel, reader.readInt32());
+ });
+
+
+ /**
+ * Tests packed fields.
+ */
+ it('testPackedFields', function() {
+ var writer = new jspb.BinaryWriter();
+
+ var sentinel = 123456789;
+
+ var unsignedData = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+ var signedData = [-1, 2, -3, 4, -5, 6, -7, 8, -9, 10];
+ var floatData = [1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 10.10];
+ var doubleData = [1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 10.10];
+ var boolData = [true, false, true, true, false, false, true, false];
+
+ for (var i = 0; i < floatData.length; i++) {
+ floatData[i] = truncate(floatData[i]);
+ }
+
+ writer.writeInt32(1, sentinel);
+
+ writer.writePackedInt32(2, signedData);
+ writer.writePackedInt64(2, signedData);
+ writer.writePackedUint32(2, unsignedData);
+ writer.writePackedUint64(2, unsignedData);
+ writer.writePackedSint32(2, signedData);
+ writer.writePackedSint64(2, signedData);
+ writer.writePackedFixed32(2, unsignedData);
+ writer.writePackedFixed64(2, unsignedData);
+ writer.writePackedSfixed32(2, signedData);
+ writer.writePackedSfixed64(2, signedData);
+ writer.writePackedFloat(2, floatData);
+ writer.writePackedDouble(2, doubleData);
+ writer.writePackedBool(2, boolData);
+ writer.writePackedEnum(2, unsignedData);
+
+ writer.writeInt32(3, sentinel);
+
+ var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());
+
+ reader.nextField();
+ assertEquals(sentinel, reader.readInt32());
+
+ reader.nextField();
+ assertElementsEquals(reader.readPackedInt32(), signedData);
+
+ reader.nextField();
+ assertElementsEquals(reader.readPackedInt64(), signedData);
+
+ reader.nextField();
+ assertElementsEquals(reader.readPackedUint32(), unsignedData);
+
+ reader.nextField();
+ assertElementsEquals(reader.readPackedUint64(), unsignedData);
+
+ reader.nextField();
+ assertElementsEquals(reader.readPackedSint32(), signedData);
+
+ reader.nextField();
+ assertElementsEquals(reader.readPackedSint64(), signedData);
+
+ reader.nextField();
+ assertElementsEquals(reader.readPackedFixed32(), unsignedData);
+
+ reader.nextField();
+ assertElementsEquals(reader.readPackedFixed64(), unsignedData);
+
+ reader.nextField();
+ assertElementsEquals(reader.readPackedSfixed32(), signedData);
+
+ reader.nextField();
+ assertElementsEquals(reader.readPackedSfixed64(), signedData);
+
+ reader.nextField();
+ assertElementsEquals(reader.readPackedFloat(), floatData);
+
+ reader.nextField();
+ assertElementsEquals(reader.readPackedDouble(), doubleData);
+
+ reader.nextField();
+ assertElementsEquals(reader.readPackedBool(), boolData);
+
+ reader.nextField();
+ assertElementsEquals(reader.readPackedEnum(), unsignedData);
+
+ reader.nextField();
+ assertEquals(sentinel, reader.readInt32());
+ });
+
+
+ /**
+ * Byte blobs inside nested messages should always have their byte offset set
+ * relative to the start of the outermost blob, not the start of their parent
+ * blob.
+ */
+ it('testNestedBlobs', function() {
+ // Create a proto consisting of two nested messages, with the inner one
+ // containing a blob of bytes.
+
+ var fieldTag = (1 << 3) | jspb.BinaryConstants.WireType.DELIMITED;
+ var blob = [1, 2, 3, 4, 5];
+ var writer = new jspb.BinaryWriter();
+ var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
+
+ writer.writeMessage(1, dummyMessage, function() {
+ writer.writeMessage(1, dummyMessage, function() {
+ writer.writeBytes(1, blob);
+ });
+ });
+
+ // Peel off the outer two message layers. Each layer should have two bytes
+ // of overhead, one for the field tag and one for the length of the inner
+ // blob.
+
+ var decoder1 = new jspb.BinaryDecoder(writer.getResultBuffer());
+ assertEquals(fieldTag, decoder1.readUnsignedVarint32());
+ assertEquals(blob.length + 4, decoder1.readUnsignedVarint32());
+
+ var decoder2 = new jspb.BinaryDecoder(decoder1.readBytes(blob.length + 4));
+ assertEquals(fieldTag, decoder2.readUnsignedVarint32());
+ assertEquals(blob.length + 2, decoder2.readUnsignedVarint32());
+
+ assertEquals(fieldTag, decoder2.readUnsignedVarint32());
+ assertEquals(blob.length, decoder2.readUnsignedVarint32());
+ var bytes = decoder2.readBytes(blob.length);
+
+ assertElementsEquals(bytes, blob);
+ });
+
+
+ /**
+ * Tests read callbacks.
+ */
+ it('testReadCallbacks', function() {
+ var writer = new jspb.BinaryWriter();
+ var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
+
+ // Add an int, a submessage, and another int.
+ writer.writeInt32(1, 100);
+
+ writer.writeMessage(2, dummyMessage, function() {
+ writer.writeInt32(3, 300);
+ writer.writeInt32(4, 400);
+ writer.writeInt32(5, 500);
+ });
+
+ writer.writeInt32(7, 700);
+
+ // Create the reader and register a custom read callback.
+ var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());
+
+ /**
+ * @param {!jspb.BinaryReader} reader
+ * @return {*}
+ */
+ function readCallback(reader) {
+ reader.nextField();
+ assertEquals(3, reader.getFieldNumber());
+ assertEquals(300, reader.readInt32());
+
+ reader.nextField();
+ assertEquals(4, reader.getFieldNumber());
+ assertEquals(400, reader.readInt32());
+
+ reader.nextField();
+ assertEquals(5, reader.getFieldNumber());
+ assertEquals(500, reader.readInt32());
+
+ assertEquals(false, reader.nextField());
+ };
+
+ reader.registerReadCallback('readCallback', readCallback);
+
+ // Read the container message.
+ reader.nextField();
+ assertEquals(1, reader.getFieldNumber());
+ assertEquals(100, reader.readInt32());
+
+ reader.nextField();
+ assertEquals(2, reader.getFieldNumber());
+ reader.readMessage(dummyMessage, function() {
+ // Decode the embedded message using the registered callback.
+ reader.runReadCallback('readCallback');
+ });
+
+ reader.nextField();
+ assertEquals(7, reader.getFieldNumber());
+ assertEquals(700, reader.readInt32());
+
+ assertEquals(false, reader.nextField());
+ });
+});
diff --git a/js/binary/utils.js b/js/binary/utils.js
new file mode 100644
index 00000000..51405553
--- /dev/null
+++ b/js/binary/utils.js
@@ -0,0 +1,975 @@
+// 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.
+
+/**
+ * @fileoverview This file contains helper code used by jspb.BinaryReader
+ * and BinaryWriter.
+ *
+ * @author aappleby@google.com (Austin Appleby)
+ */
+
+goog.provide('jspb.utils');
+
+goog.require('goog.asserts');
+goog.require('goog.crypt.base64');
+goog.require('goog.string');
+goog.require('jspb.BinaryConstants');
+
+
+/**
+ * Javascript can't natively handle 64-bit data types, so to manipulate them we
+ * have to split them into two 32-bit halves and do the math manually.
+ *
+ * Instead of instantiating and passing small structures around to do this, we
+ * instead just use two global temporary values. This one stores the low 32
+ * bits of a split value - for example, if the original value was a 64-bit
+ * integer, this temporary value will contain the low 32 bits of that integer.
+ * If the original value was a double, this temporary value will contain the
+ * low 32 bits of the binary representation of that double, etcetera.
+ * @type {number}
+ */
+jspb.utils.split64Low = 0;
+
+
+/**
+ * And correspondingly, this temporary variable will contain the high 32 bits
+ * of whatever value was split.
+ * @type {number}
+ */
+jspb.utils.split64High = 0;
+
+
+/**
+ * Splits an unsigned Javascript integer into two 32-bit halves and stores it
+ * in the temp values above.
+ * @param {number} value The number to split.
+ */
+jspb.utils.splitUint64 = function(value) {
+ // Extract low 32 bits and high 32 bits as unsigned integers.
+ var lowBits = value >>> 0;
+ var highBits = Math.floor((value - lowBits) /
+ jspb.BinaryConstants.TWO_TO_32) >>> 0;
+
+ jspb.utils.split64Low = lowBits;
+ jspb.utils.split64High = highBits;
+};
+
+
+/**
+ * Splits a signed Javascript integer into two 32-bit halves and stores it in
+ * the temp values above.
+ * @param {number} value The number to split.
+ */
+jspb.utils.splitInt64 = function(value) {
+ // Convert to sign-magnitude representation.
+ var sign = (value < 0);
+ value = Math.abs(value);
+
+ // Extract low 32 bits and high 32 bits as unsigned integers.
+ var lowBits = value >>> 0;
+ var highBits = Math.floor((value - lowBits) /
+ jspb.BinaryConstants.TWO_TO_32);
+ highBits = highBits >>> 0;
+
+ // Perform two's complement conversion if the sign bit was set.
+ if (sign) {
+ highBits = ~highBits >>> 0;
+ lowBits = ~lowBits >>> 0;
+ lowBits += 1;
+ if (lowBits > 0xFFFFFFFF) {
+ lowBits = 0;
+ highBits++;
+ if (highBits > 0xFFFFFFFF) highBits = 0;
+ }
+ }
+
+ jspb.utils.split64Low = lowBits;
+ jspb.utils.split64High = highBits;
+};
+
+
+/**
+ * Convers a signed Javascript integer into zigzag format, splits it into two
+ * 32-bit halves, and stores it in the temp values above.
+ * @param {number} value The number to split.
+ */
+jspb.utils.splitZigzag64 = function(value) {
+ // Convert to sign-magnitude and scale by 2 before we split the value.
+ var sign = (value < 0);
+ value = Math.abs(value) * 2;
+
+ jspb.utils.splitUint64(value);
+ var lowBits = jspb.utils.split64Low;
+ var highBits = jspb.utils.split64High;
+
+ // If the value is negative, subtract 1 from the split representation so we
+ // don't lose the sign bit due to precision issues.
+ if (sign) {
+ if (lowBits == 0) {
+ if (highBits == 0) {
+ lowBits = 0xFFFFFFFF;
+ highBits = 0xFFFFFFFF;
+ } else {
+ highBits--;
+ lowBits = 0xFFFFFFFF;
+ }
+ } else {
+ lowBits--;
+ }
+ }
+
+ jspb.utils.split64Low = lowBits;
+ jspb.utils.split64High = highBits;
+};
+
+
+/**
+ * Converts a floating-point number into 32-bit IEEE representation and stores
+ * it in the temp values above.
+ * @param {number} value
+ */
+jspb.utils.splitFloat32 = function(value) {
+ var sign = (value < 0) ? 1 : 0;
+ value = sign ? -value : value;
+ var exp;
+ var mant;
+
+ // Handle zeros.
+ if (value === 0) {
+ if ((1 / value) > 0) {
+ // Positive zero.
+ jspb.utils.split64High = 0;
+ jspb.utils.split64Low = 0x00000000;
+ } else {
+ // Negative zero.
+ jspb.utils.split64High = 0;
+ jspb.utils.split64Low = 0x80000000;
+ }
+ return;
+ }
+
+ // Handle nans.
+ if (isNaN(value)) {
+ jspb.utils.split64High = 0;
+ jspb.utils.split64Low = 0x7FFFFFFF;
+ return;
+ }
+
+ // Handle infinities.
+ if (value > jspb.BinaryConstants.FLOAT32_MAX) {
+ jspb.utils.split64High = 0;
+ jspb.utils.split64Low = ((sign << 31) | (0x7F800000)) >>> 0;
+ return;
+ }
+
+ // Handle denormals.
+ if (value < jspb.BinaryConstants.FLOAT32_MIN) {
+ // Number is a denormal.
+ mant = Math.round(value / Math.pow(2, -149));
+ jspb.utils.split64High = 0;
+ jspb.utils.split64Low = ((sign << 31) | mant) >>> 0;
+ return;
+ }
+
+ exp = Math.floor(Math.log(value) / Math.LN2);
+ mant = value * Math.pow(2, -exp);
+ mant = Math.round(mant * jspb.BinaryConstants.TWO_TO_23) & 0x7FFFFF;
+
+ jspb.utils.split64High = 0;
+ jspb.utils.split64Low = ((sign << 31) | ((exp + 127) << 23) | mant) >>> 0;
+};
+
+
+/**
+ * Converts a floating-point number into 64-bit IEEE representation and stores
+ * it in the temp values above.
+ * @param {number} value
+ */
+jspb.utils.splitFloat64 = function(value) {
+ var sign = (value < 0) ? 1 : 0;
+ value = sign ? -value : value;
+
+ // Handle zeros.
+ if (value === 0) {
+ if ((1 / value) > 0) {
+ // Positive zero.
+ jspb.utils.split64High = 0x00000000;
+ jspb.utils.split64Low = 0x00000000;
+ } else {
+ // Negative zero.
+ jspb.utils.split64High = 0x80000000;
+ jspb.utils.split64Low = 0x00000000;
+ }
+ return;
+ }
+
+ // Handle nans.
+ if (isNaN(value)) {
+ jspb.utils.split64High = 0x7FFFFFFF;
+ jspb.utils.split64Low = 0xFFFFFFFF;
+ return;
+ }
+
+ // Handle infinities.
+ if (value > jspb.BinaryConstants.FLOAT64_MAX) {
+ jspb.utils.split64High = ((sign << 31) | (0x7FF00000)) >>> 0;
+ jspb.utils.split64Low = 0;
+ return;
+ }
+
+ // Handle denormals.
+ if (value < jspb.BinaryConstants.FLOAT64_MIN) {
+ // Number is a denormal.
+ var mant = value / Math.pow(2, -1074);
+ var mantHigh = (mant / jspb.BinaryConstants.TWO_TO_32);
+ jspb.utils.split64High = ((sign << 31) | mantHigh) >>> 0;
+ jspb.utils.split64Low = (mant >>> 0);
+ return;
+ }
+
+ var exp = Math.floor(Math.log(value) / Math.LN2);
+ if (exp == 1024) exp = 1023;
+ var mant = value * Math.pow(2, -exp);
+
+ var mantHigh = (mant * jspb.BinaryConstants.TWO_TO_20) & 0xFFFFF;
+ var mantLow = (mant * jspb.BinaryConstants.TWO_TO_52) >>> 0;
+
+ jspb.utils.split64High =
+ ((sign << 31) | ((exp + 1023) << 20) | mantHigh) >>> 0;
+ jspb.utils.split64Low = mantLow;
+};
+
+
+/**
+ * Converts an 8-character hash string into two 32-bit numbers and stores them
+ * in the temp values above.
+ * @param {string} hash
+ */
+jspb.utils.splitHash64 = function(hash) {
+ var a = hash.charCodeAt(0);
+ var b = hash.charCodeAt(1);
+ var c = hash.charCodeAt(2);
+ var d = hash.charCodeAt(3);
+ var e = hash.charCodeAt(4);
+ var f = hash.charCodeAt(5);
+ var g = hash.charCodeAt(6);
+ var h = hash.charCodeAt(7);
+
+ jspb.utils.split64Low = (a + (b << 8) + (c << 16) + (d << 24)) >>> 0;
+ jspb.utils.split64High = (e + (f << 8) + (g << 16) + (h << 24)) >>> 0;
+};
+
+
+/**
+ * Joins two 32-bit values into a 64-bit unsigned integer. Precision will be
+ * lost if the result is greater than 2^52.
+ * @param {number} bitsLow
+ * @param {number} bitsHigh
+ * @return {number}
+ */
+jspb.utils.joinUint64 = function(bitsLow, bitsHigh) {
+ return bitsHigh * jspb.BinaryConstants.TWO_TO_32 + bitsLow;
+};
+
+
+/**
+ * Joins two 32-bit values into a 64-bit signed integer. Precision will be lost
+ * if the result is greater than 2^52.
+ * @param {number} bitsLow
+ * @param {number} bitsHigh
+ * @return {number}
+ */
+jspb.utils.joinInt64 = function(bitsLow, bitsHigh) {
+ // If the high bit is set, do a manual two's complement conversion.
+ var sign = (bitsHigh & 0x80000000);
+ if (sign) {
+ bitsLow = (~bitsLow + 1) >>> 0;
+ bitsHigh = ~bitsHigh >>> 0;
+ if (bitsLow == 0) {
+ bitsHigh = (bitsHigh + 1) >>> 0;
+ }
+ }
+
+ var result = jspb.utils.joinUint64(bitsLow, bitsHigh);
+ return sign ? -result : result;
+};
+
+
+/**
+ * Joins two 32-bit values into a 64-bit unsigned integer and applies zigzag
+ * decoding. Precision will be lost if the result is greater than 2^52.
+ * @param {number} bitsLow
+ * @param {number} bitsHigh
+ * @return {number}
+ */
+jspb.utils.joinZigzag64 = function(bitsLow, bitsHigh) {
+ // Extract the sign bit and shift right by one.
+ var sign = bitsLow & 1;
+ bitsLow = ((bitsLow >>> 1) | (bitsHigh << 31)) >>> 0;
+ bitsHigh = bitsHigh >>> 1;
+
+ // Increment the split value if the sign bit was set.
+ if (sign) {
+ bitsLow = (bitsLow + 1) >>> 0;
+ if (bitsLow == 0) {
+ bitsHigh = (bitsHigh + 1) >>> 0;
+ }
+ }
+
+ var result = jspb.utils.joinUint64(bitsLow, bitsHigh);
+ return sign ? -result : result;
+};
+
+
+/**
+ * Joins two 32-bit values into a 32-bit IEEE floating point number and
+ * converts it back into a Javascript number.
+ * @param {number} bitsLow The low 32 bits of the binary number;
+ * @param {number} bitsHigh The high 32 bits of the binary number.
+ * @return {number}
+ */
+jspb.utils.joinFloat32 = function(bitsLow, bitsHigh) {
+ var sign = ((bitsLow >> 31) * 2 + 1);
+ var exp = (bitsLow >>> 23) & 0xFF;
+ var mant = bitsLow & 0x7FFFFF;
+
+ if (exp == 0xFF) {
+ if (mant) {
+ return NaN;
+ } else {
+ return sign * Infinity;
+ }
+ }
+
+ if (exp == 0) {
+ // Denormal.
+ return sign * Math.pow(2, -149) * mant;
+ } else {
+ return sign * Math.pow(2, exp - 150) *
+ (mant + Math.pow(2, 23));
+ }
+};
+
+
+/**
+ * Joins two 32-bit values into a 64-bit IEEE floating point number and
+ * converts it back into a Javascript number.
+ * @param {number} bitsLow The low 32 bits of the binary number;
+ * @param {number} bitsHigh The high 32 bits of the binary number.
+ * @return {number}
+ */
+jspb.utils.joinFloat64 = function(bitsLow, bitsHigh) {
+ var sign = ((bitsHigh >> 31) * 2 + 1);
+ var exp = (bitsHigh >>> 20) & 0x7FF;
+ var mant = jspb.BinaryConstants.TWO_TO_32 * (bitsHigh & 0xFFFFF) + bitsLow;
+
+ if (exp == 0x7FF) {
+ if (mant) {
+ return NaN;
+ } else {
+ return sign * Infinity;
+ }
+ }
+
+ if (exp == 0) {
+ // Denormal.
+ return sign * Math.pow(2, -1074) * mant;
+ } else {
+ return sign * Math.pow(2, exp - 1075) *
+ (mant + jspb.BinaryConstants.TWO_TO_52);
+ }
+};
+
+
+/**
+ * Joins two 32-bit values into an 8-character hash string.
+ * @param {number} bitsLow
+ * @param {number} bitsHigh
+ * @return {string}
+ */
+jspb.utils.joinHash64 = function(bitsLow, bitsHigh) {
+ var a = (bitsLow >>> 0) & 0xFF;
+ var b = (bitsLow >>> 8) & 0xFF;
+ var c = (bitsLow >>> 16) & 0xFF;
+ var d = (bitsLow >>> 24) & 0xFF;
+ var e = (bitsHigh >>> 0) & 0xFF;
+ var f = (bitsHigh >>> 8) & 0xFF;
+ var g = (bitsHigh >>> 16) & 0xFF;
+ var h = (bitsHigh >>> 24) & 0xFF;
+
+ return String.fromCharCode(a, b, c, d, e, f, g, h);
+};
+
+
+/**
+ * Individual digits for number->string conversion.
+ * @const {!Array.<number>}
+ */
+jspb.utils.DIGITS = [
+ '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
+];
+
+
+/**
+ * Losslessly converts a 64-bit unsigned integer in 32:32 split representation
+ * into a decimal string.
+ * @param {number} bitsLow The low 32 bits of the binary number;
+ * @param {number} bitsHigh The high 32 bits of the binary number.
+ * @return {string} The binary number represented as a string.
+ */
+jspb.utils.joinUnsignedDecimalString = function(bitsLow, bitsHigh) {
+ // Skip the expensive conversion if the number is small enough to use the
+ // built-in conversions.
+ if (bitsHigh <= 0x1FFFFF) {
+ return '' + (jspb.BinaryConstants.TWO_TO_32 * bitsHigh + bitsLow);
+ }
+
+ // What this code is doing is essentially converting the input number from
+ // base-2 to base-1e7, which allows us to represent the 64-bit range with
+ // only 3 (very large) digits. Those digits are then trivial to convert to
+ // a base-10 string.
+
+ // The magic numbers used here are -
+ // 2^24 = 16777216 = (1,6777216) in base-1e7.
+ // 2^48 = 281474976710656 = (2,8147497,6710656) in base-1e7.
+
+ // Split 32:32 representation into 16:24:24 representation so our
+ // intermediate digits don't overflow.
+ var low = bitsLow & 0xFFFFFF;
+ var mid = (((bitsLow >>> 24) | (bitsHigh << 8)) >>> 0) & 0xFFFFFF;
+ var high = (bitsHigh >> 16) & 0xFFFF;
+
+ // Assemble our three base-1e7 digits, ignoring carries. The maximum
+ // value in a digit at this step is representable as a 48-bit integer, which
+ // can be stored in a 64-bit floating point number.
+ var digitA = low + (mid * 6777216) + (high * 6710656);
+ var digitB = mid + (high * 8147497);
+ var digitC = (high * 2);
+
+ // Apply carries from A to B and from B to C.
+ var base = 10000000;
+ if (digitA >= base) {
+ digitB += Math.floor(digitA / base);
+ digitA %= base;
+ }
+
+ if (digitB >= base) {
+ digitC += Math.floor(digitB / base);
+ digitB %= base;
+ }
+
+ // Convert base-1e7 digits to base-10, omitting leading zeroes.
+ var table = jspb.utils.DIGITS;
+ var start = false;
+ var result = '';
+
+ function emit(digit) {
+ var temp = base;
+ for (var i = 0; i < 7; i++) {
+ temp /= 10;
+ var decimalDigit = ((digit / temp) % 10) >>> 0;
+ if ((decimalDigit == 0) && !start) continue;
+ start = true;
+ result += table[decimalDigit];
+ }
+ }
+
+ if (digitC || start) emit(digitC);
+ if (digitB || start) emit(digitB);
+ if (digitA || start) emit(digitA);
+
+ return result;
+};
+
+
+/**
+ * Losslessly converts a 64-bit signed integer in 32:32 split representation
+ * into a decimal string.
+ * @param {number} bitsLow The low 32 bits of the binary number;
+ * @param {number} bitsHigh The high 32 bits of the binary number.
+ * @return {string} The binary number represented as a string.
+ */
+jspb.utils.joinSignedDecimalString = function(bitsLow, bitsHigh) {
+ // If we're treating the input as a signed value and the high bit is set, do
+ // a manual two's complement conversion before the decimal conversion.
+ var negative = (bitsHigh & 0x80000000);
+ if (negative) {
+ bitsLow = (~bitsLow + 1) >>> 0;
+ var carry = (bitsLow == 0) ? 1 : 0;
+ bitsHigh = (~bitsHigh + carry) >>> 0;
+ }
+
+ var result = jspb.utils.joinUnsignedDecimalString(bitsLow, bitsHigh);
+ return negative ? '-' + result : result;
+};
+
+
+/**
+ * Convert an 8-character hash string representing either a signed or unsigned
+ * 64-bit integer into its decimal representation without losing accuracy.
+ * @param {string} hash The hash string to convert.
+ * @param {boolean} signed True if we should treat the hash string as encoding
+ * a signed integer.
+ * @return {string}
+ */
+jspb.utils.hash64ToDecimalString = function(hash, signed) {
+ jspb.utils.splitHash64(hash);
+ var bitsLow = jspb.utils.split64Low;
+ var bitsHigh = jspb.utils.split64High;
+ return signed ?
+ jspb.utils.joinSignedDecimalString(bitsLow, bitsHigh) :
+ jspb.utils.joinUnsignedDecimalString(bitsLow, bitsHigh);
+};
+
+
+/**
+ * Converts an array of 8-character hash strings into their decimal
+ * representations.
+ * @param {!Array.<string>} hashes The array of hash strings to convert.
+ * @param {boolean} signed True if we should treat the hash string as encoding
+ * a signed integer.
+ * @return {!Array.<string>}
+ */
+jspb.utils.hash64ArrayToDecimalStrings = function(hashes, signed) {
+ var result = new Array(hashes.length);
+ for (var i = 0; i < hashes.length; i++) {
+ result[i] = jspb.utils.hash64ToDecimalString(hashes[i], signed);
+ }
+ return result;
+};
+
+
+/**
+ * Converts a signed or unsigned decimal string into its hash string
+ * representation.
+ * @param {string} dec
+ * @return {string}
+ */
+jspb.utils.decimalStringToHash64 = function(dec) {
+ goog.asserts.assert(dec.length > 0);
+
+ // Check for minus sign.
+ var minus = false;
+ if (dec[0] === '-') {
+ minus = true;
+ dec = dec.slice(1);
+ }
+
+ // Store result as a byte array.
+ var resultBytes = [0, 0, 0, 0, 0, 0, 0, 0];
+
+ // Set result to m*result + c.
+ function muladd(m, c) {
+ for (var i = 0; i < 8 && (m !== 1 || c > 0); i++) {
+ var r = m * resultBytes[i] + c;
+ resultBytes[i] = r & 0xFF;
+ c = r >>> 8;
+ }
+ }
+
+ // Negate the result bits.
+ function neg() {
+ for (var i = 0; i < 8; i++) {
+ resultBytes[i] = (~resultBytes[i]) & 0xFF;
+ }
+ }
+
+ // For each decimal digit, set result to 10*result + digit.
+ for (var i = 0; i < dec.length; i++) {
+ muladd(10, jspb.utils.DIGITS.indexOf(dec[i]));
+ }
+
+ // If there's a minus sign, convert into two's complement.
+ if (minus) {
+ neg();
+ muladd(1, 1);
+ }
+
+ return String.fromCharCode.apply(null, resultBytes);
+};
+
+
+/**
+ * Converts an 8-character hash string into its hexadecimal representation.
+ * @param {string} hash
+ * @return {string}
+ */
+jspb.utils.hash64ToHexString = function(hash) {
+ var temp = new Array(18);
+ temp[0] = '0';
+ temp[1] = 'x';
+
+ for (var i = 0; i < 8; i++) {
+ var c = hash.charCodeAt(7 - i);
+ temp[i * 2 + 2] = jspb.utils.DIGITS[c >> 4];
+ temp[i * 2 + 3] = jspb.utils.DIGITS[c & 0xF];
+ }
+
+ var result = temp.join('');
+ return result;
+};
+
+
+/**
+ * Converts a '0x<16 digits>' hex string into its hash string representation.
+ * @param {string} hex
+ * @return {string}
+ */
+jspb.utils.hexStringToHash64 = function(hex) {
+ hex = hex.toLowerCase();
+ goog.asserts.assert(hex.length == 18);
+ goog.asserts.assert(hex[0] == '0');
+ goog.asserts.assert(hex[1] == 'x');
+
+ var result = '';
+ for (var i = 0; i < 8; i++) {
+ var hi = jspb.utils.DIGITS.indexOf(hex[i * 2 + 2]);
+ var lo = jspb.utils.DIGITS.indexOf(hex[i * 2 + 3]);
+ result = String.fromCharCode(hi * 16 + lo) + result;
+ }
+
+ return result;
+};
+
+
+/**
+ * Convert an 8-character hash string representing either a signed or unsigned
+ * 64-bit integer into a Javascript number. Will lose accuracy if the result is
+ * larger than 2^52.
+ * @param {string} hash The hash string to convert.
+ * @param {boolean} signed True if the has should be interpreted as a signed
+ * number.
+ * @return {number}
+ */
+jspb.utils.hash64ToNumber = function(hash, signed) {
+ jspb.utils.splitHash64(hash);
+ var bitsLow = jspb.utils.split64Low;
+ var bitsHigh = jspb.utils.split64High;
+ return signed ? jspb.utils.joinInt64(bitsLow, bitsHigh) :
+ jspb.utils.joinUint64(bitsLow, bitsHigh);
+};
+
+
+/**
+ * Convert a Javascript number into an 8-character hash string. Will lose
+ * precision if the value is non-integral or greater than 2^64.
+ * @param {number} value The integer to convert.
+ * @return {string}
+ */
+jspb.utils.numberToHash64 = function(value) {
+ jspb.utils.splitInt64(value);
+ return jspb.utils.joinHash64(jspb.utils.split64Low,
+ jspb.utils.split64High);
+};
+
+
+/**
+ * Counts the number of contiguous varints in a buffer.
+ * @param {!Uint8Array} buffer The buffer to scan.
+ * @param {number} start The starting point in the buffer to scan.
+ * @param {number} end The end point in the buffer to scan.
+ * @return {number} The number of varints in the buffer.
+ */
+jspb.utils.countVarints = function(buffer, start, end) {
+ // Count how many high bits of each byte were set in the buffer.
+ var count = 0;
+ for (var i = start; i < end; i++) {
+ count += buffer[i] >> 7;
+ }
+
+ // The number of varints in the buffer equals the size of the buffer minus
+ // the number of non-terminal bytes in the buffer (those with the high bit
+ // set).
+ return (end - start) - count;
+};
+
+
+/**
+ * Counts the number of contiguous varint fields with the given field number in
+ * the buffer.
+ * @param {!Uint8Array} buffer The buffer to scan.
+ * @param {number} start The starting point in the buffer to scan.
+ * @param {number} end The end point in the buffer to scan.
+ * @param {number} field The field number to count.
+ * @return {number} The number of matching fields in the buffer.
+ */
+jspb.utils.countVarintFields = function(buffer, start, end, field) {
+ var count = 0;
+ var cursor = start;
+ var tag = field * 8 + jspb.BinaryConstants.WireType.VARINT;
+
+ if (tag < 128) {
+ // Single-byte field tag, we can use a slightly quicker count.
+ while (cursor < end) {
+ // Skip the field tag, or exit if we find a non-matching tag.
+ if (buffer[cursor++] != tag) return count;
+
+ // Field tag matches, we've found a valid field.
+ count++;
+
+ // Skip the varint.
+ while (1) {
+ var x = buffer[cursor++];
+ if ((x & 0x80) == 0) break;
+ }
+ }
+ } else {
+ while (cursor < end) {
+ // Skip the field tag, or exit if we find a non-matching tag.
+ var temp = tag;
+ while (temp > 128) {
+ if (buffer[cursor] != ((temp & 0x7F) | 0x80)) return count;
+ cursor++;
+ temp >>= 7;
+ }
+ if (buffer[cursor++] != temp) return count;
+
+ // Field tag matches, we've found a valid field.
+ count++;
+
+ // Skip the varint.
+ while (1) {
+ var x = buffer[cursor++];
+ if ((x & 0x80) == 0) break;
+ }
+ }
+ }
+ return count;
+};
+
+
+/**
+ * Counts the number of contiguous fixed32 fields with the given tag in the
+ * buffer.
+ * @param {!Uint8Array} buffer The buffer to scan.
+ * @param {number} start The starting point in the buffer to scan.
+ * @param {number} end The end point in the buffer to scan.
+ * @param {number} tag The tag value to count.
+ * @param {number} stride The number of bytes to skip per field.
+ * @return {number} The number of fields with a matching tag in the buffer.
+ * @private
+ */
+jspb.utils.countFixedFields_ =
+ function(buffer, start, end, tag, stride) {
+ var count = 0;
+ var cursor = start;
+
+ if (tag < 128) {
+ // Single-byte field tag, we can use a slightly quicker count.
+ while (cursor < end) {
+ // Skip the field tag, or exit if we find a non-matching tag.
+ if (buffer[cursor++] != tag) return count;
+
+ // Field tag matches, we've found a valid field.
+ count++;
+
+ // Skip the value.
+ cursor += stride;
+ }
+ } else {
+ while (cursor < end) {
+ // Skip the field tag, or exit if we find a non-matching tag.
+ var temp = tag;
+ while (temp > 128) {
+ if (buffer[cursor++] != ((temp & 0x7F) | 0x80)) return count;
+ temp >>= 7;
+ }
+ if (buffer[cursor++] != temp) return count;
+
+ // Field tag matches, we've found a valid field.
+ count++;
+
+ // Skip the value.
+ cursor += stride;
+ }
+ }
+ return count;
+};
+
+
+/**
+ * Counts the number of contiguous fixed32 fields with the given field number
+ * in the buffer.
+ * @param {!Uint8Array} buffer The buffer to scan.
+ * @param {number} start The starting point in the buffer to scan.
+ * @param {number} end The end point in the buffer to scan.
+ * @param {number} field The field number to count.
+ * @return {number} The number of matching fields in the buffer.
+ */
+jspb.utils.countFixed32Fields = function(buffer, start, end, field) {
+ var tag = field * 8 + jspb.BinaryConstants.WireType.FIXED32;
+ return jspb.utils.countFixedFields_(buffer, start, end, tag, 4);
+};
+
+
+/**
+ * Counts the number of contiguous fixed64 fields with the given field number
+ * in the buffer.
+ * @param {!Uint8Array} buffer The buffer to scan.
+ * @param {number} start The starting point in the buffer to scan.
+ * @param {number} end The end point in the buffer to scan.
+ * @param {number} field The field number to count
+ * @return {number} The number of matching fields in the buffer.
+ */
+jspb.utils.countFixed64Fields = function(buffer, start, end, field) {
+ var tag = field * 8 + jspb.BinaryConstants.WireType.FIXED64;
+ return jspb.utils.countFixedFields_(buffer, start, end, tag, 8);
+};
+
+
+/**
+ * Counts the number of contiguous delimited fields with the given field number
+ * in the buffer.
+ * @param {!Uint8Array} buffer The buffer to scan.
+ * @param {number} start The starting point in the buffer to scan.
+ * @param {number} end The end point in the buffer to scan.
+ * @param {number} field The field number to count.
+ * @return {number} The number of matching fields in the buffer.
+ */
+jspb.utils.countDelimitedFields = function(buffer, start, end, field) {
+ var count = 0;
+ var cursor = start;
+ var tag = field * 8 + jspb.BinaryConstants.WireType.DELIMITED;
+
+ while (cursor < end) {
+ // Skip the field tag, or exit if we find a non-matching tag.
+ var temp = tag;
+ while (temp > 128) {
+ if (buffer[cursor++] != ((temp & 0x7F) | 0x80)) return count;
+ temp >>= 7;
+ }
+ if (buffer[cursor++] != temp) return count;
+
+ // Field tag matches, we've found a valid field.
+ count++;
+
+ // Decode the length prefix.
+ var length = 0;
+ var shift = 1;
+ while (1) {
+ temp = buffer[cursor++];
+ length += (temp & 0x7f) * shift;
+ shift *= 128;
+ if ((temp & 0x80) == 0) break;
+ }
+
+ // Advance the cursor past the blob.
+ cursor += length;
+ }
+ return count;
+};
+
+
+/**
+ * String-ify bytes for text format. Should be optimized away in non-debug.
+ * The returned string uses \xXX escapes for all values and is itself quoted.
+ * [1, 31] serializes to '"\x01\x1f"'.
+ * @param {jspb.ByteSource} byteSource The bytes to serialize.
+ * @return {string} Stringified bytes for text format.
+ */
+jspb.utils.debugBytesToTextFormat = function(byteSource) {
+ var s = '"';
+ if (byteSource) {
+ var bytes = jspb.utils.byteSourceToUint8Array(byteSource);
+ for (var i = 0; i < bytes.length; i++) {
+ s += '\\x';
+ if (bytes[i] < 16) s += '0';
+ s += bytes[i].toString(16);
+ }
+ }
+ return s + '"';
+};
+
+
+/**
+ * String-ify a scalar for text format. Should be optimized away in non-debug.
+ * @param {string|number|boolean} scalar The scalar to stringify.
+ * @return {string} Stringified scalar for text format.
+ */
+jspb.utils.debugScalarToTextFormat = function(scalar) {
+ if (goog.isString(scalar)) {
+ return goog.string.quote(scalar);
+ } else {
+ return scalar.toString();
+ }
+};
+
+
+/**
+ * Utility function: convert a string with codepoints 0--255 inclusive to a
+ * Uint8Array. If any codepoints greater than 255 exist in the string, throws an
+ * exception.
+ * @param {string} str
+ * @return {!Uint8Array}
+ */
+jspb.utils.stringToByteArray = function(str) {
+ var arr = new Uint8Array(str.length);
+ for (var i = 0; i < str.length; i++) {
+ var codepoint = str.charCodeAt(i);
+ if (codepoint > 255) {
+ throw new Error('Conversion error: string contains codepoint ' +
+ 'outside of byte range');
+ }
+ arr[i] = codepoint;
+ }
+ return arr;
+};
+
+
+/**
+ * Converts any type defined in jspb.ByteSource into a Uint8Array.
+ * @param {!jspb.ByteSource} data
+ * @return {!Uint8Array}
+ * @suppress {invalidCasts}
+ */
+jspb.utils.byteSourceToUint8Array = function(data) {
+ if (data.constructor === Uint8Array) {
+ return /** @type {!Uint8Array} */(data);
+ }
+
+ if (data.constructor === ArrayBuffer) {
+ data = /** @type {!ArrayBuffer} */(data);
+ return /** @type {!Uint8Array} */(new Uint8Array(data));
+ }
+
+ if (data.constructor === Array) {
+ data = /** @type {!Array.<number>} */(data);
+ return /** @type {!Uint8Array} */(new Uint8Array(data));
+ }
+
+ if (data.constructor === String) {
+ data = /** @type {string} */(data);
+ return goog.crypt.base64.decodeStringToUint8Array(data);
+ }
+
+ goog.asserts.fail('Type not convertible to Uint8Array.');
+ return /** @type {!Uint8Array} */(new Uint8Array(0));
+};
diff --git a/js/binary/utils_test.js b/js/binary/utils_test.js
new file mode 100644
index 00000000..d27e5ea2
--- /dev/null
+++ b/js/binary/utils_test.js
@@ -0,0 +1,668 @@
+// 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.
+
+/**
+ * @fileoverview Test cases for jspb's helper functions.
+ *
+ * Test suite is written using Jasmine -- see http://jasmine.github.io/
+ *
+ * @author aappleby@google.com (Austin Appleby)
+ */
+
+goog.require('goog.crypt.base64');
+goog.require('goog.testing.asserts');
+goog.require('jspb.BinaryConstants');
+goog.require('jspb.BinaryWriter');
+goog.require('jspb.utils');
+
+
+/**
+ * @param {number} x
+ * @return {number}
+ */
+function truncate(x) {
+ var temp = new Float32Array(1);
+ temp[0] = x;
+ return temp[0];
+}
+
+
+/**
+ * Converts an 64-bit integer in split representation to a 64-bit hash string
+ * (8 bits encoded per character).
+ * @param {number} bitsLow The low 32 bits of the split 64-bit integer.
+ * @param {number} bitsHigh The high 32 bits of the split 64-bit integer.
+ * @return {string} The encoded hash string, 8 bits per character.
+ */
+function toHashString(bitsLow, bitsHigh) {
+ return String.fromCharCode((bitsLow >>> 0) & 0xFF,
+ (bitsLow >>> 8) & 0xFF,
+ (bitsLow >>> 16) & 0xFF,
+ (bitsLow >>> 24) & 0xFF,
+ (bitsHigh >>> 0) & 0xFF,
+ (bitsHigh >>> 8) & 0xFF,
+ (bitsHigh >>> 16) & 0xFF,
+ (bitsHigh >>> 24) & 0xFF);
+}
+
+
+describe('binaryUtilsTest', function() {
+ /**
+ * Tests lossless binary-to-decimal conversion.
+ */
+ it('testDecimalConversion', function() {
+ // Check some magic numbers.
+ var result =
+ jspb.utils.joinUnsignedDecimalString(0x89e80001, 0x8ac72304);
+ assertEquals('10000000000000000001', result);
+
+ result = jspb.utils.joinUnsignedDecimalString(0xacd05f15, 0x1b69b4b);
+ assertEquals('123456789123456789', result);
+
+ result = jspb.utils.joinUnsignedDecimalString(0xeb1f0ad2, 0xab54a98c);
+ assertEquals('12345678901234567890', result);
+
+ result = jspb.utils.joinUnsignedDecimalString(0xe3b70cb1, 0x891087b8);
+ assertEquals('9876543210987654321', result);
+
+ // Check limits.
+ result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00000000);
+ assertEquals('0', result);
+
+ result = jspb.utils.joinUnsignedDecimalString(0xFFFFFFFF, 0xFFFFFFFF);
+ assertEquals('18446744073709551615', result);
+
+ // Check each bit of the low dword.
+ for (var i = 0; i < 32; i++) {
+ var low = (1 << i) >>> 0;
+ result = jspb.utils.joinUnsignedDecimalString(low, 0);
+ assertEquals('' + Math.pow(2, i), result);
+ }
+
+ // Check the first 20 bits of the high dword.
+ for (var i = 0; i < 20; i++) {
+ var high = (1 << i) >>> 0;
+ result = jspb.utils.joinUnsignedDecimalString(0, high);
+ assertEquals('' + Math.pow(2, 32 + i), result);
+ }
+
+ // V8's internal double-to-string conversion is inaccurate for values above
+ // 2^52, even if they're representable integers - check the rest of the bits
+ // manually against the correct string representations of 2^N.
+
+ result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00100000);
+ assertEquals('4503599627370496', result);
+
+ result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00200000);
+ assertEquals('9007199254740992', result);
+
+ result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00400000);
+ assertEquals('18014398509481984', result);
+
+ result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00800000);
+ assertEquals('36028797018963968', result);
+
+ result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x01000000);
+ assertEquals('72057594037927936', result);
+
+ result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x02000000);
+ assertEquals('144115188075855872', result);
+
+ result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x04000000);
+ assertEquals('288230376151711744', result);
+
+ result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x08000000);
+ assertEquals('576460752303423488', result);
+
+ result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x10000000);
+ assertEquals('1152921504606846976', result);
+
+ result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x20000000);
+ assertEquals('2305843009213693952', result);
+
+ result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x40000000);
+ assertEquals('4611686018427387904', result);
+
+ result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x80000000);
+ assertEquals('9223372036854775808', result);
+ });
+
+
+ /**
+ * Going from hash strings to decimal strings should also be lossless.
+ */
+ it('testHashToDecimalConversion', function() {
+ var result;
+ var convert = jspb.utils.hash64ToDecimalString;
+
+ result = convert(toHashString(0x00000000, 0x00000000), false);
+ assertEquals('0', result);
+
+ result = convert(toHashString(0x00000000, 0x00000000), true);
+ assertEquals('0', result);
+
+ result = convert(toHashString(0xFFFFFFFF, 0xFFFFFFFF), false);
+ assertEquals('18446744073709551615', result);
+
+ result = convert(toHashString(0xFFFFFFFF, 0xFFFFFFFF), true);
+ assertEquals('-1', result);
+
+ result = convert(toHashString(0x00000000, 0x80000000), false);
+ assertEquals('9223372036854775808', result);
+
+ result = convert(toHashString(0x00000000, 0x80000000), true);
+ assertEquals('-9223372036854775808', result);
+
+ result = convert(toHashString(0xacd05f15, 0x01b69b4b), false);
+ assertEquals('123456789123456789', result);
+
+ result = convert(toHashString(~0xacd05f15 + 1, ~0x01b69b4b), true);
+ assertEquals('-123456789123456789', result);
+
+ // And converting arrays of hashes should work the same way.
+ result = jspb.utils.hash64ArrayToDecimalStrings([
+ toHashString(0xFFFFFFFF, 0xFFFFFFFF),
+ toHashString(0x00000000, 0x80000000),
+ toHashString(0xacd05f15, 0x01b69b4b)], false);
+ assertEquals(3, result.length);
+ assertEquals('18446744073709551615', result[0]);
+ assertEquals('9223372036854775808', result[1]);
+ assertEquals('123456789123456789', result[2]);
+ });
+
+ /*
+ * Going from decimal strings to hash strings should be lossless.
+ */
+ it('testDecimalToHashConversion', function() {
+ var result;
+ var convert = jspb.utils.decimalStringToHash64;
+
+ result = convert('0');
+ assertEquals(String.fromCharCode.apply(null,
+ [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), result);
+
+ result = convert('-1');
+ assertEquals(String.fromCharCode.apply(null,
+ [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]), result);
+
+ result = convert('18446744073709551615');
+ assertEquals(String.fromCharCode.apply(null,
+ [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]), result);
+
+ result = convert('9223372036854775808');
+ assertEquals(String.fromCharCode.apply(null,
+ [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80]), result);
+
+ result = convert('-9223372036854775808');
+ assertEquals(String.fromCharCode.apply(null,
+ [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80]), result);
+
+ result = convert('123456789123456789');
+ assertEquals(String.fromCharCode.apply(null,
+ [0x15, 0x5F, 0xD0, 0xAC, 0x4B, 0x9B, 0xB6, 0x01]), result);
+
+ result = convert('-123456789123456789');
+ assertEquals(String.fromCharCode.apply(null,
+ [0xEB, 0xA0, 0x2F, 0x53, 0xB4, 0x64, 0x49, 0xFE]), result);
+ });
+
+ /**
+ * Going from hash strings to hex strings should be lossless.
+ */
+ it('testHashToHexConversion', function() {
+ var result;
+ var convert = jspb.utils.hash64ToHexString;
+
+ result = convert(toHashString(0x00000000, 0x00000000));
+ assertEquals('0x0000000000000000', result);
+
+ result = convert(toHashString(0xFFFFFFFF, 0xFFFFFFFF));
+ assertEquals('0xffffffffffffffff', result);
+
+ result = convert(toHashString(0x12345678, 0x9ABCDEF0));
+ assertEquals('0x9abcdef012345678', result);
+ });
+
+
+ /**
+ * Going from hex strings to hash strings should be lossless.
+ */
+ it('testHexToHashConversion', function() {
+ var result;
+ var convert = jspb.utils.hexStringToHash64;
+
+ result = convert('0x0000000000000000');
+ assertEquals(String.fromCharCode.apply(null,
+ [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), result);
+
+ result = convert('0xffffffffffffffff');
+ assertEquals(String.fromCharCode.apply(null,
+ [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]), result);
+
+ // Hex string is big-endian, hash string is little-endian.
+ result = convert('0x123456789ABCDEF0');
+ assertEquals(String.fromCharCode.apply(null,
+ [0xF0, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]), result);
+
+ // Capitalization should not matter.
+ result = convert('0x0000abcdefABCDEF');
+ assertEquals(String.fromCharCode.apply(null,
+ [0xEF, 0xCD, 0xAB, 0xEF, 0xCD, 0xAB, 0x00, 0x00]), result);
+ });
+
+
+ /**
+ * Going from numbers to hash strings should be lossless for up to 53 bits of
+ * precision.
+ */
+ it('testNumberToHashConversion', function() {
+ var result;
+ var convert = jspb.utils.numberToHash64;
+
+ result = convert(0x0000000000000);
+ assertEquals('0x0000000000000000', jspb.utils.hash64ToHexString(result));
+
+ result = convert(0xFFFFFFFFFFFFF);
+ assertEquals('0x000fffffffffffff', jspb.utils.hash64ToHexString(result));
+
+ result = convert(0x123456789ABCD);
+ assertEquals('0x000123456789abcd', jspb.utils.hash64ToHexString(result));
+
+ result = convert(0xDCBA987654321);
+ assertEquals('0x000dcba987654321', jspb.utils.hash64ToHexString(result));
+
+ // 53 bits of precision should not be truncated.
+ result = convert(0x10000000000001);
+ assertEquals('0x0010000000000001', jspb.utils.hash64ToHexString(result));
+
+ // 54 bits of precision should be truncated.
+ result = convert(0x20000000000001);
+ assertNotEquals(
+ '0x0020000000000001', jspb.utils.hash64ToHexString(result));
+ });
+
+
+ /**
+ * Sanity check the behavior of Javascript's strings when doing funny things
+ * with unicode characters.
+ */
+ it('sanityCheckUnicodeStrings', function() {
+ var strings = new Array(65536);
+
+ // All possible unsigned 16-bit values should be storable in a string, they
+ // shouldn't do weird things with the length of the string, and they should
+ // come back out of the string unchanged.
+ for (var i = 0; i < 65536; i++) {
+ strings[i] = 'a' + String.fromCharCode(i) + 'a';
+ if (3 != strings[i].length) throw 'fail!';
+ if (i != strings[i].charCodeAt(1)) throw 'fail!';
+ }
+
+ // Each unicode character should compare equal to itself and not equal to a
+ // different unicode character.
+ for (var i = 0; i < 65536; i++) {
+ if (strings[i] != strings[i]) throw 'fail!';
+ if (strings[i] == strings[(i + 1) % 65536]) throw 'fail!';
+ }
+ });
+
+
+ /**
+ * Tests conversion from 32-bit floating point numbers to split64 numbers.
+ */
+ it('testFloat32ToSplit64', function() {
+ var f32_eps = jspb.BinaryConstants.FLOAT32_EPS;
+ var f32_min = jspb.BinaryConstants.FLOAT32_MIN;
+ var f32_max = jspb.BinaryConstants.FLOAT32_MAX;
+
+ // NaN.
+ jspb.utils.splitFloat32(NaN);
+ if (!isNaN(jspb.utils.joinFloat32(jspb.utils.split64Low,
+ jspb.utils.split64High))) {
+ throw 'fail!';
+ }
+
+ /**
+ * @param {number} x
+ * @param {number=} opt_bits
+ */
+ function test(x, opt_bits) {
+ jspb.utils.splitFloat32(x);
+ if (goog.isDef(opt_bits)) {
+ if (opt_bits != jspb.utils.split64Low) throw 'fail!';
+ }
+ if (truncate(x) != jspb.utils.joinFloat32(jspb.utils.split64Low,
+ jspb.utils.split64High)) {
+ throw 'fail!';
+ }
+ }
+
+ // Positive and negative infinity.
+ test(Infinity, 0x7f800000);
+ test(-Infinity, 0xff800000);
+
+ // Positive and negative zero.
+ test(0, 0x00000000);
+ test(-0, 0x80000000);
+
+ // Positive and negative epsilon.
+ test(f32_eps, 0x00000001);
+ test(-f32_eps, 0x80000001);
+
+ // Positive and negative min.
+ test(f32_min, 0x00800000);
+ test(-f32_min, 0x80800000);
+
+ // Positive and negative max.
+ test(f32_max, 0x7F7FFFFF);
+ test(-f32_max, 0xFF7FFFFF);
+
+ // Various positive values.
+ var cursor = f32_eps * 10;
+ while (cursor != Infinity) {
+ test(cursor);
+ cursor *= 1.1;
+ }
+
+ // Various negative values.
+ cursor = -f32_eps * 10;
+ while (cursor != -Infinity) {
+ test(cursor);
+ cursor *= 1.1;
+ }
+ });
+
+
+ /**
+ * Tests conversion from 64-bit floating point numbers to split64 numbers.
+ */
+ it('testFloat64ToSplit64', function() {
+ var f64_eps = jspb.BinaryConstants.FLOAT64_EPS;
+ var f64_min = jspb.BinaryConstants.FLOAT64_MIN;
+ var f64_max = jspb.BinaryConstants.FLOAT64_MAX;
+
+ // NaN.
+ jspb.utils.splitFloat64(NaN);
+ if (!isNaN(jspb.utils.joinFloat64(jspb.utils.split64Low,
+ jspb.utils.split64High))) {
+ throw 'fail!';
+ }
+
+ /**
+ * @param {number} x
+ * @param {number=} opt_highBits
+ * @param {number=} opt_lowBits
+ */
+ function test(x, opt_highBits, opt_lowBits) {
+ jspb.utils.splitFloat64(x);
+ if (goog.isDef(opt_highBits)) {
+ if (opt_highBits != jspb.utils.split64High) throw 'fail!';
+ }
+ if (goog.isDef(opt_lowBits)) {
+ if (opt_lowBits != jspb.utils.split64Low) throw 'fail!';
+ }
+ if (x != jspb.utils.joinFloat64(jspb.utils.split64Low,
+ jspb.utils.split64High)) {
+ throw 'fail!';
+ }
+ }
+
+ // Positive and negative infinity.
+ test(Infinity, 0x7ff00000, 0x00000000);
+ test(-Infinity, 0xfff00000, 0x00000000);
+
+ // Positive and negative zero.
+ test(0, 0x00000000, 0x00000000);
+ test(-0, 0x80000000, 0x00000000);
+
+ // Positive and negative epsilon.
+ test(f64_eps, 0x00000000, 0x00000001);
+ test(-f64_eps, 0x80000000, 0x00000001);
+
+ // Positive and negative min.
+ test(f64_min, 0x00100000, 0x00000000);
+ test(-f64_min, 0x80100000, 0x00000000);
+
+ // Positive and negative max.
+ test(f64_max, 0x7FEFFFFF, 0xFFFFFFFF);
+ test(-f64_max, 0xFFEFFFFF, 0xFFFFFFFF);
+
+ // Various positive values.
+ var cursor = f64_eps * 10;
+ while (cursor != Infinity) {
+ test(cursor);
+ cursor *= 1.1;
+ }
+
+ // Various negative values.
+ cursor = -f64_eps * 10;
+ while (cursor != -Infinity) {
+ test(cursor);
+ cursor *= 1.1;
+ }
+ });
+
+
+ /**
+ * Tests counting packed varints.
+ */
+ it('testCountVarints', function() {
+ var values = [];
+ for (var i = 1; i < 1000000000; i *= 1.1) {
+ values.push(Math.floor(i));
+ }
+
+ var writer = new jspb.BinaryWriter();
+ writer.writePackedUint64(1, values);
+
+ var buffer = new Uint8Array(writer.getResultBuffer());
+
+ // We should have two more varints than we started with - one for the field
+ // tag, one for the packed length.
+ assertEquals(values.length + 2,
+ jspb.utils.countVarints(buffer, 0, buffer.length));
+ });
+
+
+ /**
+ * Tests counting matching varint fields.
+ */
+ it('testCountVarintFields', function() {
+ var writer = new jspb.BinaryWriter();
+
+ var count = 0;
+ for (var i = 1; i < 1000000000; i *= 1.1) {
+ writer.writeUint64(1, Math.floor(i));
+ count++;
+ }
+ writer.writeString(2, 'terminator');
+
+ var buffer = new Uint8Array(writer.getResultBuffer());
+ assertEquals(count,
+ jspb.utils.countVarintFields(buffer, 0, buffer.length, 1));
+
+ writer = new jspb.BinaryWriter();
+
+ count = 0;
+ for (var i = 1; i < 1000000000; i *= 1.1) {
+ writer.writeUint64(123456789, Math.floor(i));
+ count++;
+ }
+ writer.writeString(2, 'terminator');
+
+ buffer = new Uint8Array(writer.getResultBuffer());
+ assertEquals(count,
+ jspb.utils.countVarintFields(buffer, 0, buffer.length, 123456789));
+ });
+
+
+ /**
+ * Tests counting matching fixed32 fields.
+ */
+ it('testCountFixed32Fields', function() {
+ var writer = new jspb.BinaryWriter();
+
+ var count = 0;
+ for (var i = 1; i < 1000000000; i *= 1.1) {
+ writer.writeFixed32(1, Math.floor(i));
+ count++;
+ }
+ writer.writeString(2, 'terminator');
+
+ var buffer = new Uint8Array(writer.getResultBuffer());
+ assertEquals(count,
+ jspb.utils.countFixed32Fields(buffer, 0, buffer.length, 1));
+
+ writer = new jspb.BinaryWriter();
+
+ count = 0;
+ for (var i = 1; i < 1000000000; i *= 1.1) {
+ writer.writeFixed32(123456789, Math.floor(i));
+ count++;
+ }
+ writer.writeString(2, 'terminator');
+
+ buffer = new Uint8Array(writer.getResultBuffer());
+ assertEquals(count,
+ jspb.utils.countFixed32Fields(buffer, 0, buffer.length, 123456789));
+ });
+
+
+ /**
+ * Tests counting matching fixed64 fields.
+ */
+ it('testCountFixed64Fields', function() {
+ var writer = new jspb.BinaryWriter();
+
+ var count = 0;
+ for (var i = 1; i < 1000000000; i *= 1.1) {
+ writer.writeDouble(1, i);
+ count++;
+ }
+ writer.writeString(2, 'terminator');
+
+ var buffer = new Uint8Array(writer.getResultBuffer());
+ assertEquals(count,
+ jspb.utils.countFixed64Fields(buffer, 0, buffer.length, 1));
+
+ writer = new jspb.BinaryWriter();
+
+ count = 0;
+ for (var i = 1; i < 1000000000; i *= 1.1) {
+ writer.writeDouble(123456789, i);
+ count++;
+ }
+ writer.writeString(2, 'terminator');
+
+ buffer = new Uint8Array(writer.getResultBuffer());
+ assertEquals(count,
+ jspb.utils.countFixed64Fields(buffer, 0, buffer.length, 123456789));
+ });
+
+
+ /**
+ * Tests counting matching delimited fields.
+ */
+ it('testCountDelimitedFields', function() {
+ var writer = new jspb.BinaryWriter();
+
+ var count = 0;
+ for (var i = 1; i < 1000; i *= 1.1) {
+ writer.writeBytes(1, [Math.floor(i)]);
+ count++;
+ }
+ writer.writeString(2, 'terminator');
+
+ var buffer = new Uint8Array(writer.getResultBuffer());
+ assertEquals(count,
+ jspb.utils.countDelimitedFields(buffer, 0, buffer.length, 1));
+
+ writer = new jspb.BinaryWriter();
+
+ count = 0;
+ for (var i = 1; i < 1000; i *= 1.1) {
+ writer.writeBytes(123456789, [Math.floor(i)]);
+ count++;
+ }
+ writer.writeString(2, 'terminator');
+
+ buffer = new Uint8Array(writer.getResultBuffer());
+ assertEquals(count,
+ jspb.utils.countDelimitedFields(buffer, 0, buffer.length, 123456789));
+ });
+
+
+ /**
+ * Tests byte format for debug strings.
+ */
+ it('testDebugBytesToTextFormat', function() {
+ assertEquals('""', jspb.utils.debugBytesToTextFormat(null));
+ assertEquals('"\\x00\\x10\\xff"',
+ jspb.utils.debugBytesToTextFormat([0, 16, 255]));
+ });
+
+
+ /**
+ * Tests converting byte blob sources into byte blobs.
+ */
+ it('testByteSourceToUint8Array', function() {
+ var convert = jspb.utils.byteSourceToUint8Array;
+
+ var sourceData = [];
+ for (var i = 0; i < 256; i++) {
+ sourceData.push(i);
+ }
+
+ var sourceBytes = new Uint8Array(sourceData);
+ var sourceBuffer = sourceBytes.buffer;
+ var sourceBase64 = goog.crypt.base64.encodeByteArray(sourceData);
+ var sourceString = String.fromCharCode.apply(null, sourceData);
+
+ function check(result) {
+ assertEquals(Uint8Array, result.constructor);
+ assertEquals(sourceData.length, result.length);
+ for (var i = 0; i < result.length; i++) {
+ assertEquals(sourceData[i], result[i]);
+ }
+ }
+
+ // Converting Uint8Arrays into Uint8Arrays should be a no-op.
+ assertEquals(sourceBytes, convert(sourceBytes));
+
+ // Converting Array.<numbers> into Uint8Arrays should work.
+ check(convert(sourceData));
+
+ // Converting ArrayBuffers into Uint8Arrays should work.
+ check(convert(sourceBuffer));
+
+ // Converting base64-encoded strings into Uint8Arrays should work.
+ check(convert(sourceBase64));
+ });
+});
diff --git a/js/binary/writer.js b/js/binary/writer.js
new file mode 100644
index 00000000..3eb2f1bd
--- /dev/null
+++ b/js/binary/writer.js
@@ -0,0 +1,1577 @@
+// 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.
+
+/**
+ * @fileoverview This file contains utilities for encoding Javascript objects
+ * into binary, wire-format protocol buffers (in the form of Uint8Arrays) that
+ * a server can consume directly.
+ *
+ * jspb's BinaryWriter class defines methods for efficiently encoding
+ * Javascript objects into binary, wire-format protocol buffers and supports
+ * all the fundamental field types used in protocol buffers.
+ *
+ * Major caveat 1 - Users of this library _must_ keep their Javascript proto
+ * parsing code in sync with the original .proto file - presumably you'll be
+ * using the typed jspb code generator, but if you bypass that you'll need
+ * to keep things in sync by hand.
+ *
+ * Major caveat 2 - Javascript is unable to accurately represent integers
+ * larger than 2^53 due to its use of a double-precision floating point format
+ * for all numbers. BinaryWriter does not make any special effort to preserve
+ * precision for values above this limit - if you need to pass 64-bit integers
+ * (hash codes, for example) between the client and server without precision
+ * loss, do _not_ use this library.
+ *
+ * Major caveat 3 - This class uses typed arrays and must not be used on older
+ * browsers that do not support them.
+ *
+ * @author aappleby@google.com (Austin Appleby)
+ */
+
+goog.provide('jspb.BinaryWriter');
+
+goog.require('goog.asserts');
+goog.require('goog.crypt.base64');
+goog.require('jspb.BinaryConstants');
+goog.require('jspb.BinaryEncoder');
+goog.require('jspb.arith.Int64');
+goog.require('jspb.arith.UInt64');
+goog.require('jspb.utils');
+
+
+
+/**
+ * BinaryWriter implements encoders for all the wire types specified in
+ * https://developers.google.com/protocol-buffers/docs/encoding.
+ *
+ * @constructor
+ * @struct
+ */
+jspb.BinaryWriter = function() {
+ /**
+ * Blocks of serialized data that will be concatenated once all messages have
+ * been written.
+ * @private {!Array<!Uint8Array|!Array<number>>}
+ */
+ this.blocks_ = [];
+
+ /**
+ * Total number of bytes in the blocks_ array. Does _not_ include bytes in
+ * the encoder below.
+ * @private {number}
+ */
+ this.totalLength_ = 0;
+
+ /**
+ * Binary encoder holding pieces of a message that we're still serializing.
+ * When we get to a stopping point (either the start of a new submessage, or
+ * when we need to append a raw Uint8Array), the encoder's buffer will be
+ * added to the block array above and the encoder will be reset.
+ * @private {!jspb.BinaryEncoder}
+ */
+ this.encoder_ = new jspb.BinaryEncoder();
+
+ /**
+ * A stack of bookmarks containing the parent blocks for each message started
+ * via beginSubMessage(), needed as bookkeeping for endSubMessage().
+ * TODO(aappleby): Deprecated, users should be calling writeMessage().
+ * @private {!Array.<!Array.<number>>}
+ */
+ this.bookmarks_ = [];
+};
+
+
+/**
+ * Append a typed array of bytes onto the buffer.
+ *
+ * @param {!Uint8Array} arr The byte array to append.
+ * @private
+ */
+jspb.BinaryWriter.prototype.appendUint8Array_ = function(arr) {
+ var temp = this.encoder_.end();
+ this.blocks_.push(temp);
+ this.blocks_.push(arr);
+ this.totalLength_ += temp.length + arr.length;
+};
+
+
+/**
+ * Begins a new message by writing the field header and returning a bookmark
+ * which we will use to patch in the message length to in endDelimited_ below.
+ * @param {number} field
+ * @return {!Array.<number>}
+ * @private
+ */
+jspb.BinaryWriter.prototype.beginDelimited_ = function(field) {
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
+ var bookmark = this.encoder_.end();
+ this.blocks_.push(bookmark);
+ this.totalLength_ += bookmark.length;
+ bookmark.push(this.totalLength_);
+ return bookmark;
+};
+
+
+/**
+ * Ends a message by encoding the _change_ in length of the buffer to the
+ * parent block and adds the number of bytes needed to encode that length to
+ * the total byte length.
+ * @param {!Array.<number>} bookmark
+ * @private
+ */
+jspb.BinaryWriter.prototype.endDelimited_ = function(bookmark) {
+ var oldLength = bookmark.pop();
+ var messageLength = this.totalLength_ + this.encoder_.length() - oldLength;
+ goog.asserts.assert(messageLength >= 0);
+
+ while (messageLength > 127) {
+ bookmark.push((messageLength & 0x7f) | 0x80);
+ messageLength = messageLength >>> 7;
+ this.totalLength_++;
+ }
+
+ bookmark.push(messageLength);
+ this.totalLength_++;
+};
+
+
+/**
+ * Writes a pre-serialized message to the buffer.
+ * @param {!Uint8Array} bytes The array of bytes to write.
+ * @param {number} start The start of the range to write.
+ * @param {number} end The end of the range to write.
+ */
+jspb.BinaryWriter.prototype.writeSerializedMessage = function(
+ bytes, start, end) {
+ this.appendUint8Array_(bytes.subarray(start, end));
+};
+
+
+/**
+ * Writes a pre-serialized message to the buffer if the message and endpoints
+ * are non-null.
+ * @param {?Uint8Array} bytes The array of bytes to write.
+ * @param {?number} start The start of the range to write.
+ * @param {?number} end The end of the range to write.
+ */
+jspb.BinaryWriter.prototype.maybeWriteSerializedMessage = function(
+ bytes, start, end) {
+ if (bytes != null && start != null && end != null) {
+ this.writeSerializedMessage(bytes, start, end);
+ }
+};
+
+
+/**
+ * Resets the writer, throwing away any accumulated buffers.
+ */
+jspb.BinaryWriter.prototype.reset = function() {
+ this.blocks_ = [];
+ this.encoder_.end();
+ this.totalLength_ = 0;
+ this.bookmarks_ = [];
+};
+
+
+/**
+ * Converts the encoded data into a Uint8Array.
+ * @return {!Uint8Array}
+ */
+jspb.BinaryWriter.prototype.getResultBuffer = function() {
+ goog.asserts.assert(this.bookmarks_.length == 0);
+
+ var flat = new Uint8Array(this.totalLength_ + this.encoder_.length());
+
+ var blocks = this.blocks_;
+ var blockCount = blocks.length;
+ var offset = 0;
+
+ for (var i = 0; i < blockCount; i++) {
+ var block = blocks[i];
+ flat.set(block, offset);
+ offset += block.length;
+ }
+
+ var tail = this.encoder_.end();
+ flat.set(tail, offset);
+ offset += tail.length;
+
+ // Post condition: `flattened` must have had every byte written.
+ goog.asserts.assert(offset == flat.length);
+
+ // Replace our block list with the flattened block, which lets GC reclaim
+ // the temp blocks sooner.
+ this.blocks_ = [flat];
+
+ return flat;
+};
+
+
+/**
+ * Converts the encoded data into a bas64-encoded string.
+ * @return {string}
+ */
+jspb.BinaryWriter.prototype.getResultBase64String = function() {
+ return goog.crypt.base64.encodeByteArray(this.getResultBuffer());
+};
+
+
+/**
+ * Begins a new sub-message. The client must call endSubMessage() when they're
+ * done.
+ * TODO(aappleby): Deprecated. Move callers to writeMessage().
+ * @param {number} field The field number of the sub-message.
+ */
+jspb.BinaryWriter.prototype.beginSubMessage = function(field) {
+ this.bookmarks_.push(this.beginDelimited_(field));
+};
+
+
+/**
+ * Finishes a sub-message and packs it into the parent messages' buffer.
+ * TODO(aappleby): Deprecated. Move callers to writeMessage().
+ */
+jspb.BinaryWriter.prototype.endSubMessage = function() {
+ goog.asserts.assert(this.bookmarks_.length >= 0);
+ this.endDelimited_(this.bookmarks_.pop());
+};
+
+
+/**
+ * Encodes a (field number, wire type) tuple into a wire-format field header
+ * and stores it in the buffer as a varint.
+ * @param {number} field The field number.
+ * @param {number} wireType The wire-type of the field, as specified in the
+ * protocol buffer documentation.
+ * @private
+ */
+jspb.BinaryWriter.prototype.writeFieldHeader_ =
+ function(field, wireType) {
+ goog.asserts.assert(field >= 1 && field == Math.floor(field));
+ var x = field * 8 + wireType;
+ this.encoder_.writeUnsignedVarint32(x);
+};
+
+
+/**
+ * Writes a field of any valid scalar type to the binary stream.
+ * @param {jspb.BinaryConstants.FieldType} fieldType
+ * @param {number} field
+ * @param {jspb.AnyFieldType} value
+ */
+jspb.BinaryWriter.prototype.writeAny = function(fieldType, field, value) {
+ var fieldTypes = jspb.BinaryConstants.FieldType;
+ switch (fieldType) {
+ case fieldTypes.DOUBLE:
+ this.writeDouble(field, /** @type {number} */(value));
+ return;
+ case fieldTypes.FLOAT:
+ this.writeFloat(field, /** @type {number} */(value));
+ return;
+ case fieldTypes.INT64:
+ this.writeInt64(field, /** @type {number} */(value));
+ return;
+ case fieldTypes.UINT64:
+ this.writeUint64(field, /** @type {number} */(value));
+ return;
+ case fieldTypes.INT32:
+ this.writeInt32(field, /** @type {number} */(value));
+ return;
+ case fieldTypes.FIXED64:
+ this.writeFixed64(field, /** @type {number} */(value));
+ return;
+ case fieldTypes.FIXED32:
+ this.writeFixed32(field, /** @type {number} */(value));
+ return;
+ case fieldTypes.BOOL:
+ this.writeBool(field, /** @type {boolean} */(value));
+ return;
+ case fieldTypes.STRING:
+ this.writeString(field, /** @type {string} */(value));
+ return;
+ case fieldTypes.GROUP:
+ goog.asserts.fail('Group field type not supported in writeAny()');
+ return;
+ case fieldTypes.MESSAGE:
+ goog.asserts.fail('Message field type not supported in writeAny()');
+ return;
+ case fieldTypes.BYTES:
+ this.writeBytes(field, /** @type {?Uint8Array} */(value));
+ return;
+ case fieldTypes.UINT32:
+ this.writeUint32(field, /** @type {number} */(value));
+ return;
+ case fieldTypes.ENUM:
+ this.writeEnum(field, /** @type {number} */(value));
+ return;
+ case fieldTypes.SFIXED32:
+ this.writeSfixed32(field, /** @type {number} */(value));
+ return;
+ case fieldTypes.SFIXED64:
+ this.writeSfixed64(field, /** @type {number} */(value));
+ return;
+ case fieldTypes.SINT32:
+ this.writeSint32(field, /** @type {number} */(value));
+ return;
+ case fieldTypes.SINT64:
+ this.writeSint64(field, /** @type {number} */(value));
+ return;
+ case fieldTypes.FHASH64:
+ this.writeFixedHash64(field, /** @type {string} */(value));
+ return;
+ case fieldTypes.VHASH64:
+ this.writeVarintHash64(field, /** @type {string} */(value));
+ return;
+ default:
+ goog.asserts.fail('Invalid field type in writeAny()');
+ return;
+ }
+};
+
+
+/**
+ * Writes a varint field to the buffer without range checking.
+ * @param {number} field The field number.
+ * @param {number?} value The value to write.
+ * @private
+ */
+jspb.BinaryWriter.prototype.writeUnsignedVarint32_ = function(field, value) {
+ if (value == null) return;
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
+ this.encoder_.writeUnsignedVarint32(value);
+};
+
+
+/**
+ * Writes a varint field to the buffer without range checking.
+ * @param {number} field The field number.
+ * @param {number?} value The value to write.
+ * @private
+ */
+jspb.BinaryWriter.prototype.writeSignedVarint32_ = function(field, value) {
+ if (value == null) return;
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
+ this.encoder_.writeSignedVarint32(value);
+};
+
+
+/**
+ * Writes a varint field to the buffer without range checking.
+ * @param {number} field The field number.
+ * @param {number?} value The value to write.
+ * @private
+ */
+jspb.BinaryWriter.prototype.writeUnsignedVarint64_ = function(field, value) {
+ if (value == null) return;
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
+ this.encoder_.writeUnsignedVarint64(value);
+};
+
+
+/**
+ * Writes a varint field to the buffer without range checking.
+ * @param {number} field The field number.
+ * @param {number?} value The value to write.
+ * @private
+ */
+jspb.BinaryWriter.prototype.writeSignedVarint64_ = function(field, value) {
+ if (value == null) return;
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
+ this.encoder_.writeSignedVarint64(value);
+};
+
+
+/**
+ * Writes a zigzag varint field to the buffer without range checking.
+ * @param {number} field The field number.
+ * @param {number?} value The value to write.
+ * @private
+ */
+jspb.BinaryWriter.prototype.writeZigzagVarint32_ = function(field, value) {
+ if (value == null) return;
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
+ this.encoder_.writeZigzagVarint32(value);
+};
+
+
+/**
+ * Writes a zigzag varint field to the buffer without range checking.
+ * @param {number} field The field number.
+ * @param {number?} value The value to write.
+ * @private
+ */
+jspb.BinaryWriter.prototype.writeZigzagVarint64_ = function(field, value) {
+ if (value == null) return;
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
+ this.encoder_.writeZigzagVarint64(value);
+};
+
+
+/**
+ * Writes an int32 field to the buffer. Numbers outside the range [-2^31,2^31)
+ * will be truncated.
+ * @param {number} field The field number.
+ * @param {number?} value The value to write.
+ */
+jspb.BinaryWriter.prototype.writeInt32 = function(field, value) {
+ if (value == null) return;
+ goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_31) &&
+ (value < jspb.BinaryConstants.TWO_TO_31));
+ this.writeSignedVarint32_(field, value);
+};
+
+
+/**
+ * Writes an int32 field represented as a string to the buffer. Numbers outside
+ * the range [-2^31,2^31) will be truncated.
+ * @param {number} field The field number.
+ * @param {string?} value The value to write.
+ */
+jspb.BinaryWriter.prototype.writeInt32String = function(field, value) {
+ if (value == null) return;
+ var intValue = /** {number} */ parseInt(value, 10);
+ goog.asserts.assert((intValue >= -jspb.BinaryConstants.TWO_TO_31) &&
+ (intValue < jspb.BinaryConstants.TWO_TO_31));
+ this.writeSignedVarint32_(field, intValue);
+};
+
+
+/**
+ * Writes an int64 field to the buffer. Numbers outside the range [-2^63,2^63)
+ * will be truncated.
+ * @param {number} field The field number.
+ * @param {number?} value The value to write.
+ */
+jspb.BinaryWriter.prototype.writeInt64 = function(field, value) {
+ if (value == null) return;
+ goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_63) &&
+ (value < jspb.BinaryConstants.TWO_TO_63));
+ this.writeSignedVarint64_(field, value);
+};
+
+
+/**
+ * Writes a int64 field (with value as a string) to the buffer.
+ * @param {number} field The field number.
+ * @param {string?} value The value to write.
+ */
+jspb.BinaryWriter.prototype.writeInt64String = function(field, value) {
+ if (value == null) return;
+ var num = jspb.arith.Int64.fromString(value);
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
+ this.encoder_.writeSplitVarint64(num.lo, num.hi);
+};
+
+
+/**
+ * Writes a uint32 field to the buffer. Numbers outside the range [0,2^32)
+ * will be truncated.
+ * @param {number} field The field number.
+ * @param {number?} value The value to write.
+ */
+jspb.BinaryWriter.prototype.writeUint32 = function(field, value) {
+ if (value == null) return;
+ goog.asserts.assert((value >= 0) &&
+ (value < jspb.BinaryConstants.TWO_TO_32));
+ this.writeUnsignedVarint32_(field, value);
+};
+
+
+/**
+ * Writes a uint32 field represented as a string to the buffer. Numbers outside
+ * the range [0,2^32) will be truncated.
+ * @param {number} field The field number.
+ * @param {string?} value The value to write.
+ */
+jspb.BinaryWriter.prototype.writeUint32String = function(field, value) {
+ if (value == null) return;
+ var intValue = /** {number} */ parseInt(value, 10);
+ goog.asserts.assert((intValue >= 0) &&
+ (intValue < jspb.BinaryConstants.TWO_TO_32));
+ this.writeUnsignedVarint32_(field, intValue);
+};
+
+
+/**
+ * Writes a uint64 field to the buffer. Numbers outside the range [0,2^64)
+ * will be truncated.
+ * @param {number} field The field number.
+ * @param {number?} value The value to write.
+ */
+jspb.BinaryWriter.prototype.writeUint64 = function(field, value) {
+ if (value == null) return;
+ goog.asserts.assert((value >= 0) &&
+ (value < jspb.BinaryConstants.TWO_TO_64));
+ this.writeUnsignedVarint64_(field, value);
+};
+
+
+/**
+ * Writes a uint64 field (with value as a string) to the buffer.
+ * @param {number} field The field number.
+ * @param {string?} value The value to write.
+ */
+jspb.BinaryWriter.prototype.writeUint64String = function(field, value) {
+ if (value == null) return;
+ var num = jspb.arith.UInt64.fromString(value);
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
+ this.encoder_.writeSplitVarint64(num.lo, num.hi);
+};
+
+
+/**
+ * Writes a sint32 field to the buffer. Numbers outside the range [-2^31,2^31)
+ * will be truncated.
+ * @param {number} field The field number.
+ * @param {number?} value The value to write.
+ */
+jspb.BinaryWriter.prototype.writeSint32 = function(field, value) {
+ if (value == null) return;
+ goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_31) &&
+ (value < jspb.BinaryConstants.TWO_TO_31));
+ this.writeZigzagVarint32_(field, value);
+};
+
+
+/**
+ * Writes a sint64 field to the buffer. Numbers outside the range [-2^63,2^63)
+ * will be truncated.
+ * @param {number} field The field number.
+ * @param {number?} value The value to write.
+ */
+jspb.BinaryWriter.prototype.writeSint64 = function(field, value) {
+ if (value == null) return;
+ goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_63) &&
+ (value < jspb.BinaryConstants.TWO_TO_63));
+ this.writeZigzagVarint64_(field, value);
+};
+
+
+/**
+ * Writes a fixed32 field to the buffer. Numbers outside the range [0,2^32)
+ * will be truncated.
+ * @param {number} field The field number.
+ * @param {number?} value The value to write.
+ */
+jspb.BinaryWriter.prototype.writeFixed32 = function(field, value) {
+ if (value == null) return;
+ goog.asserts.assert((value >= 0) &&
+ (value < jspb.BinaryConstants.TWO_TO_32));
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED32);
+ this.encoder_.writeUint32(value);
+};
+
+
+/**
+ * Writes a fixed64 field to the buffer. Numbers outside the range [0,2^64)
+ * will be truncated.
+ * @param {number} field The field number.
+ * @param {number?} value The value to write.
+ */
+jspb.BinaryWriter.prototype.writeFixed64 = function(field, value) {
+ if (value == null) return;
+ goog.asserts.assert((value >= 0) &&
+ (value < jspb.BinaryConstants.TWO_TO_64));
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED64);
+ this.encoder_.writeUint64(value);
+};
+
+
+/**
+ * Writes a sfixed32 field to the buffer. Numbers outside the range
+ * [-2^31,2^31) will be truncated.
+ * @param {number} field The field number.
+ * @param {number?} value The value to write.
+ */
+jspb.BinaryWriter.prototype.writeSfixed32 = function(field, value) {
+ if (value == null) return;
+ goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_31) &&
+ (value < jspb.BinaryConstants.TWO_TO_31));
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED32);
+ this.encoder_.writeInt32(value);
+};
+
+
+/**
+ * Writes a sfixed64 field to the buffer. Numbers outside the range
+ * [-2^63,2^63) will be truncated.
+ * @param {number} field The field number.
+ * @param {number?} value The value to write.
+ */
+jspb.BinaryWriter.prototype.writeSfixed64 = function(field, value) {
+ if (value == null) return;
+ goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_63) &&
+ (value < jspb.BinaryConstants.TWO_TO_63));
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED64);
+ this.encoder_.writeInt64(value);
+};
+
+
+/**
+ * Writes a single-precision floating point field to the buffer. Numbers
+ * requiring more than 32 bits of precision will be truncated.
+ * @param {number} field The field number.
+ * @param {number?} value The value to write.
+ */
+jspb.BinaryWriter.prototype.writeFloat = function(field, value) {
+ if (value == null) return;
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED32);
+ this.encoder_.writeFloat(value);
+};
+
+
+/**
+ * Writes a double-precision floating point field to the buffer. As this is the
+ * native format used by JavaScript, no precision will be lost.
+ * @param {number} field The field number.
+ * @param {number?} value The value to write.
+ */
+jspb.BinaryWriter.prototype.writeDouble = function(field, value) {
+ if (value == null) return;
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED64);
+ this.encoder_.writeDouble(value);
+};
+
+
+/**
+ * Writes a boolean field to the buffer.
+ * @param {number} field The field number.
+ * @param {boolean?} value The value to write.
+ */
+jspb.BinaryWriter.prototype.writeBool = function(field, value) {
+ if (value == null) return;
+ goog.asserts.assert(goog.isBoolean(value));
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
+ this.encoder_.writeBool(value);
+};
+
+
+/**
+ * Writes an enum field to the buffer.
+ * @param {number} field The field number.
+ * @param {number?} value The value to write.
+ */
+jspb.BinaryWriter.prototype.writeEnum = function(field, value) {
+ if (value == null) return;
+ goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_31) &&
+ (value < jspb.BinaryConstants.TWO_TO_31));
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
+ this.encoder_.writeSignedVarint32(value);
+};
+
+
+/**
+ * Writes a string field to the buffer.
+ * @param {number} field The field number.
+ * @param {string?} value The string to write.
+ */
+jspb.BinaryWriter.prototype.writeString = function(field, value) {
+ if (value == null) return;
+ var bookmark = this.beginDelimited_(field);
+ this.encoder_.writeString(value);
+ this.endDelimited_(bookmark);
+};
+
+
+/**
+ * Writes an arbitrary byte field to the buffer. Note - to match the behavior
+ * of the C++ implementation, empty byte arrays _are_ serialized.
+ * @param {number} field The field number.
+ * @param {?jspb.ByteSource} value The array of bytes to write.
+ */
+jspb.BinaryWriter.prototype.writeBytes = function(field, value) {
+ if (value == null) return;
+ var bytes = jspb.utils.byteSourceToUint8Array(value);
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
+ this.encoder_.writeUnsignedVarint32(bytes.length);
+ this.appendUint8Array_(bytes);
+};
+
+
+/**
+ * Writes a message to the buffer.
+ * @param {number} field The field number.
+ * @param {?MessageType} value The message to write.
+ * @param {function(MessageTypeNonNull, !jspb.BinaryWriter)} writerCallback
+ * Will be invoked with the value to write and the writer to write it with.
+ * @template MessageType
+ * Use go/closure-ttl to declare a non-nullable version of MessageType. Replace
+ * the null in blah|null with none. This is necessary because the compiler will
+ * infer MessageType to be nullable if the value parameter is nullable.
+ * @template MessageTypeNonNull :=
+ * cond(isUnknown(MessageType), unknown(),
+ * mapunion(MessageType, (X) =>
+ * cond(eq(X, 'null'), none(), X)))
+ * =:
+ */
+jspb.BinaryWriter.prototype.writeMessage = function(
+ field, value, writerCallback) {
+ if (value == null) return;
+ var bookmark = this.beginDelimited_(field);
+ writerCallback(value, this);
+ this.endDelimited_(bookmark);
+};
+
+
+/**
+ * Writes a group message to the buffer.
+ *
+ * @param {number} field The field number.
+ * @param {?MessageType} value The message to write, wrapped with START_GROUP /
+ * END_GROUP tags. Will be a no-op if 'value' is null.
+ * @param {function(MessageTypeNonNull, !jspb.BinaryWriter)} writerCallback
+ * Will be invoked with the value to write and the writer to write it with.
+ * @template MessageType
+ * Use go/closure-ttl to declare a non-nullable version of MessageType. Replace
+ * the null in blah|null with none. This is necessary because the compiler will
+ * infer MessageType to be nullable if the value parameter is nullable.
+ * @template MessageTypeNonNull :=
+ * cond(isUnknown(MessageType), unknown(),
+ * mapunion(MessageType, (X) =>
+ * cond(eq(X, 'null'), none(), X)))
+ * =:
+ */
+jspb.BinaryWriter.prototype.writeGroup = function(
+ field, value, writerCallback) {
+ if (value == null) return;
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.START_GROUP);
+ writerCallback(value, this);
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.END_GROUP);
+};
+
+
+/**
+ * Writes a 64-bit hash string field (8 characters @ 8 bits of data each) to
+ * the buffer.
+ * @param {number} field The field number.
+ * @param {string?} value The hash string.
+ */
+jspb.BinaryWriter.prototype.writeFixedHash64 = function(field, value) {
+ if (value == null) return;
+ goog.asserts.assert(value.length == 8);
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED64);
+ this.encoder_.writeFixedHash64(value);
+};
+
+
+/**
+ * Writes a 64-bit hash string field (8 characters @ 8 bits of data each) to
+ * the buffer.
+ * @param {number} field The field number.
+ * @param {string?} value The hash string.
+ */
+jspb.BinaryWriter.prototype.writeVarintHash64 = function(field, value) {
+ if (value == null) return;
+ goog.asserts.assert(value.length == 8);
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
+ this.encoder_.writeVarintHash64(value);
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a repeated varint field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ * @private
+ */
+jspb.BinaryWriter.prototype.writeRepeatedUnsignedVarint32_ =
+ function(field, value) {
+ if (value == null) return;
+ for (var i = 0; i < value.length; i++) {
+ this.writeUnsignedVarint32_(field, value[i]);
+ }
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a repeated varint field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ * @private
+ */
+jspb.BinaryWriter.prototype.writeRepeatedSignedVarint32_ =
+ function(field, value) {
+ if (value == null) return;
+ for (var i = 0; i < value.length; i++) {
+ this.writeSignedVarint32_(field, value[i]);
+ }
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a repeated varint field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ * @private
+ */
+jspb.BinaryWriter.prototype.writeRepeatedUnsignedVarint64_ =
+ function(field, value) {
+ if (value == null) return;
+ for (var i = 0; i < value.length; i++) {
+ this.writeUnsignedVarint64_(field, value[i]);
+ }
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a repeated varint field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ * @private
+ */
+jspb.BinaryWriter.prototype.writeRepeatedSignedVarint64_ =
+ function(field, value) {
+ if (value == null) return;
+ for (var i = 0; i < value.length; i++) {
+ this.writeSignedVarint64_(field, value[i]);
+ }
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a repeated zigzag field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ * @private
+ */
+jspb.BinaryWriter.prototype.writeRepeatedZigzag32_ = function(field, value) {
+ if (value == null) return;
+ for (var i = 0; i < value.length; i++) {
+ this.writeZigzagVarint32_(field, value[i]);
+ }
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a repeated zigzag field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ * @private
+ */
+jspb.BinaryWriter.prototype.writeRepeatedZigzag_ = function(field, value) {
+ if (value == null) return;
+ for (var i = 0; i < value.length; i++) {
+ this.writeZigzagVarint64_(field, value[i]);
+ }
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a repeated 32-bit int field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedInt32 =
+ jspb.BinaryWriter.prototype.writeRepeatedSignedVarint32_;
+
+
+/**
+ * Writes an array of numbers formatted as strings to the buffer as a repeated
+ * 32-bit int field.
+ * @param {number} field The field number.
+ * @param {?Array.<string>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedInt32String =
+ function(field, value) {
+ if (value == null) return;
+ for (var i = 0; i < value.length; i++) {
+ this.writeInt32String(field, value[i]);
+ }
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a repeated 64-bit int field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedInt64 =
+ jspb.BinaryWriter.prototype.writeRepeatedSignedVarint64_;
+
+
+/**
+ * Writes an array of numbers formatted as strings to the buffer as a repeated
+ * 64-bit int field.
+ * @param {number} field The field number.
+ * @param {?Array.<string>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedInt64String =
+ function(field, value) {
+ if (value == null) return;
+ for (var i = 0; i < value.length; i++) {
+ this.writeInt64String(field, value[i]);
+ }
+};
+
+
+/**
+ * Writes an array numbers to the buffer as a repeated unsigned 32-bit int
+ * field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedUint32 =
+ jspb.BinaryWriter.prototype.writeRepeatedUnsignedVarint32_;
+
+
+/**
+ * Writes an array of numbers formatted as strings to the buffer as a repeated
+ * unsigned 32-bit int field.
+ * @param {number} field The field number.
+ * @param {?Array.<string>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedUint32String =
+ function(field, value) {
+ if (value == null) return;
+ for (var i = 0; i < value.length; i++) {
+ this.writeUint32String(field, value[i]);
+ }
+};
+
+
+/**
+ * Writes an array numbers to the buffer as a repeated unsigned 64-bit int
+ * field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedUint64 =
+ jspb.BinaryWriter.prototype.writeRepeatedUnsignedVarint64_;
+
+
+/**
+ * Writes an array of numbers formatted as strings to the buffer as a repeated
+ * unsigned 64-bit int field.
+ * @param {number} field The field number.
+ * @param {?Array.<string>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedUint64String =
+ function(field, value) {
+ if (value == null) return;
+ for (var i = 0; i < value.length; i++) {
+ this.writeUint64String(field, value[i]);
+ }
+};
+
+
+/**
+ * Writes an array numbers to the buffer as a repeated signed 32-bit int field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedSint32 =
+ jspb.BinaryWriter.prototype.writeRepeatedZigzag32_;
+
+
+/**
+ * Writes an array numbers to the buffer as a repeated signed 64-bit int field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedSint64 =
+ jspb.BinaryWriter.prototype.writeRepeatedZigzag_;
+
+
+/**
+ * Writes an array of numbers to the buffer as a repeated fixed32 field. This
+ * works for both signed and unsigned fixed32s.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedFixed32 = function(field, value) {
+ if (value == null) return;
+ for (var i = 0; i < value.length; i++) {
+ this.writeFixed32(field, value[i]);
+ }
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a repeated fixed64 field. This
+ * works for both signed and unsigned fixed64s.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedFixed64 = function(field, value) {
+ if (value == null) return;
+ for (var i = 0; i < value.length; i++) {
+ this.writeFixed64(field, value[i]);
+ }
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a repeated sfixed32 field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedSfixed32 = function(field, value) {
+ if (value == null) return;
+ for (var i = 0; i < value.length; i++) {
+ this.writeSfixed32(field, value[i]);
+ }
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a repeated sfixed64 field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedSfixed64 = function(field, value) {
+ if (value == null) return;
+ for (var i = 0; i < value.length; i++) {
+ this.writeSfixed64(field, value[i]);
+ }
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a repeated float field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedFloat = function(field, value) {
+ if (value == null) return;
+ for (var i = 0; i < value.length; i++) {
+ this.writeFloat(field, value[i]);
+ }
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a repeated double field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedDouble = function(field, value) {
+ if (value == null) return;
+ for (var i = 0; i < value.length; i++) {
+ this.writeDouble(field, value[i]);
+ }
+};
+
+
+/**
+ * Writes an array of booleans to the buffer as a repeated bool field.
+ * @param {number} field The field number.
+ * @param {?Array.<boolean>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedBool = function(field, value) {
+ if (value == null) return;
+ for (var i = 0; i < value.length; i++) {
+ this.writeBool(field, value[i]);
+ }
+};
+
+
+/**
+ * Writes an array of enums to the buffer as a repeated enum field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedEnum = function(field, value) {
+ if (value == null) return;
+ for (var i = 0; i < value.length; i++) {
+ this.writeEnum(field, value[i]);
+ }
+};
+
+
+/**
+ * Writes an array of strings to the buffer as a repeated string field.
+ * @param {number} field The field number.
+ * @param {?Array.<string>} value The array of strings to write.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedString = function(field, value) {
+ if (value == null) return;
+ for (var i = 0; i < value.length; i++) {
+ this.writeString(field, value[i]);
+ }
+};
+
+
+/**
+ * Writes an array of arbitrary byte fields to the buffer.
+ * @param {number} field The field number.
+ * @param {?Array.<!jspb.ByteSource>} value The arrays of arrays of bytes to
+ * write.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedBytes = function(field, value) {
+ if (value == null) return;
+ for (var i = 0; i < value.length; i++) {
+ this.writeBytes(field, value[i]);
+ }
+};
+
+
+/**
+ * Writes an array of messages to the buffer.
+ * @template MessageType
+ * @param {number} field The field number.
+ * @param {?Array.<MessageType>} value The array of messages to
+ * write.
+ * @param {function(MessageType, !jspb.BinaryWriter)} writerCallback
+ * Will be invoked with the value to write and the writer to write it with.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedMessage = function(
+ field, value, writerCallback) {
+ if (value == null) return;
+ for (var i = 0; i < value.length; i++) {
+ var bookmark = this.beginDelimited_(field);
+ writerCallback(value[i], this);
+ this.endDelimited_(bookmark);
+ }
+};
+
+
+/**
+ * Writes an array of group messages to the buffer.
+ * @template MessageType
+ * @param {number} field The field number.
+ * @param {?Array.<MessageType>} value The array of messages to
+ * write.
+ * @param {function(MessageType, !jspb.BinaryWriter)} writerCallback
+ * Will be invoked with the value to write and the writer to write it with.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedGroup = function(
+ field, value, writerCallback) {
+ if (value == null) return;
+ for (var i = 0; i < value.length; i++) {
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.START_GROUP);
+ writerCallback(value[i], this);
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.END_GROUP);
+ }
+};
+
+
+/**
+ * Writes a 64-bit hash string field (8 characters @ 8 bits of data each) to
+ * the buffer.
+ * @param {number} field The field number.
+ * @param {?Array.<string>} value The array of hashes to write.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedFixedHash64 =
+ function(field, value) {
+ if (value == null) return;
+ for (var i = 0; i < value.length; i++) {
+ this.writeFixedHash64(field, value[i]);
+ }
+};
+
+
+/**
+ * Writes a repeated 64-bit hash string field (8 characters @ 8 bits of data
+ * each) to the buffer.
+ * @param {number} field The field number.
+ * @param {?Array.<string>} value The array of hashes to write.
+ */
+jspb.BinaryWriter.prototype.writeRepeatedVarintHash64 =
+ function(field, value) {
+ if (value == null) return;
+ for (var i = 0; i < value.length; i++) {
+ this.writeVarintHash64(field, value[i]);
+ }
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a packed varint field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ * @private
+ */
+jspb.BinaryWriter.prototype.writePackedUnsignedVarint32_ = function(
+ field, value) {
+ if (value == null || !value.length) return;
+ var bookmark = this.beginDelimited_(field);
+ for (var i = 0; i < value.length; i++) {
+ this.encoder_.writeUnsignedVarint32(value[i]);
+ }
+ this.endDelimited_(bookmark);
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a packed varint field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ * @private
+ */
+jspb.BinaryWriter.prototype.writePackedSignedVarint32_ = function(
+ field, value) {
+ if (value == null || !value.length) return;
+ var bookmark = this.beginDelimited_(field);
+ for (var i = 0; i < value.length; i++) {
+ this.encoder_.writeSignedVarint32(value[i]);
+ }
+ this.endDelimited_(bookmark);
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a packed varint field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ * @private
+ */
+jspb.BinaryWriter.prototype.writePackedUnsignedVarint64_ = function(
+ field, value) {
+ if (value == null || !value.length) return;
+ var bookmark = this.beginDelimited_(field);
+ for (var i = 0; i < value.length; i++) {
+ this.encoder_.writeUnsignedVarint64(value[i]);
+ }
+ this.endDelimited_(bookmark);
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a packed varint field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ * @private
+ */
+jspb.BinaryWriter.prototype.writePackedSignedVarint64_ = function(
+ field, value) {
+ if (value == null || !value.length) return;
+ var bookmark = this.beginDelimited_(field);
+ for (var i = 0; i < value.length; i++) {
+ this.encoder_.writeSignedVarint64(value[i]);
+ }
+ this.endDelimited_(bookmark);
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a packed zigzag field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ * @private
+ */
+jspb.BinaryWriter.prototype.writePackedZigzag32_ = function(field, value) {
+ if (value == null || !value.length) return;
+ var bookmark = this.beginDelimited_(field);
+ for (var i = 0; i < value.length; i++) {
+ this.encoder_.writeZigzagVarint32(value[i]);
+ }
+ this.endDelimited_(bookmark);
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a packed zigzag field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ * @private
+ */
+jspb.BinaryWriter.prototype.writePackedZigzag64_ = function(field, value) {
+ if (value == null || !value.length) return;
+ var bookmark = this.beginDelimited_(field);
+ for (var i = 0; i < value.length; i++) {
+ this.encoder_.writeZigzagVarint64(value[i]);
+ }
+ this.endDelimited_(bookmark);
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a packed 32-bit int field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writePackedInt32 =
+ jspb.BinaryWriter.prototype.writePackedSignedVarint32_;
+
+
+/**
+ * Writes an array of numbers represented as strings to the buffer as a packed
+ * 32-bit int field.
+ * @param {number} field
+ * @param {?Array.<string>} value
+ */
+jspb.BinaryWriter.prototype.writePackedInt32String = function(field, value) {
+ if (value == null || !value.length) return;
+ var bookmark = this.beginDelimited_(field);
+ for (var i = 0; i < value.length; i++) {
+ this.encoder_.writeSignedVarint32(parseInt(value[i], 10));
+ }
+ this.endDelimited_(bookmark);
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a packed 64-bit int field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writePackedInt64 =
+ jspb.BinaryWriter.prototype.writePackedSignedVarint64_;
+
+
+/**
+ * Writes an array of numbers represented as strings to the buffer as a packed
+ * 64-bit int field.
+ * @param {number} field
+ * @param {?Array.<string>} value
+ */
+jspb.BinaryWriter.prototype.writePackedInt64String =
+ function(field, value) {
+ if (value == null || !value.length) return;
+ var bookmark = this.beginDelimited_(field);
+ for (var i = 0; i < value.length; i++) {
+ var num = jspb.arith.Int64.fromString(value[i]);
+ this.encoder_.writeSplitVarint64(num.lo, num.hi);
+ }
+ this.endDelimited_(bookmark);
+};
+
+
+/**
+ * Writes an array numbers to the buffer as a packed unsigned 32-bit int field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writePackedUint32 =
+ jspb.BinaryWriter.prototype.writePackedUnsignedVarint32_;
+
+
+/**
+ * Writes an array of numbers represented as strings to the buffer as a packed
+ * unsigned 32-bit int field.
+ * @param {number} field
+ * @param {?Array.<string>} value
+ */
+jspb.BinaryWriter.prototype.writePackedUint32String =
+ function(field, value) {
+ if (value == null || !value.length) return;
+ var bookmark = this.beginDelimited_(field);
+ for (var i = 0; i < value.length; i++) {
+ this.encoder_.writeUnsignedVarint32(parseInt(value[i], 10));
+ }
+ this.endDelimited_(bookmark);
+};
+
+
+/**
+ * Writes an array numbers to the buffer as a packed unsigned 64-bit int field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writePackedUint64 =
+ jspb.BinaryWriter.prototype.writePackedUnsignedVarint64_;
+
+
+/**
+ * Writes an array of numbers represented as strings to the buffer as a packed
+ * unsigned 64-bit int field.
+ * @param {number} field
+ * @param {?Array.<string>} value
+ */
+jspb.BinaryWriter.prototype.writePackedUint64String =
+ function(field, value) {
+ if (value == null || !value.length) return;
+ var bookmark = this.beginDelimited_(field);
+ for (var i = 0; i < value.length; i++) {
+ var num = jspb.arith.UInt64.fromString(value[i]);
+ this.encoder_.writeSplitVarint64(num.lo, num.hi);
+ }
+ this.endDelimited_(bookmark);
+};
+
+
+/**
+ * Writes an array numbers to the buffer as a packed signed 32-bit int field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writePackedSint32 =
+ jspb.BinaryWriter.prototype.writePackedZigzag32_;
+
+
+/**
+ * Writes an array numbers to the buffer as a packed signed 64-bit int field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writePackedSint64 =
+ jspb.BinaryWriter.prototype.writePackedZigzag64_;
+
+
+/**
+ * Writes an array of numbers to the buffer as a packed fixed32 field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writePackedFixed32 = function(field, value) {
+ if (value == null || !value.length) return;
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
+ this.encoder_.writeUnsignedVarint32(value.length * 4);
+ for (var i = 0; i < value.length; i++) {
+ this.encoder_.writeUint32(value[i]);
+ }
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a packed fixed64 field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writePackedFixed64 = function(field, value) {
+ if (value == null || !value.length) return;
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
+ this.encoder_.writeUnsignedVarint32(value.length * 8);
+ for (var i = 0; i < value.length; i++) {
+ this.encoder_.writeUint64(value[i]);
+ }
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a packed sfixed32 field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writePackedSfixed32 = function(field, value) {
+ if (value == null || !value.length) return;
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
+ this.encoder_.writeUnsignedVarint32(value.length * 4);
+ for (var i = 0; i < value.length; i++) {
+ this.encoder_.writeInt32(value[i]);
+ }
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a packed sfixed64 field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writePackedSfixed64 = function(field, value) {
+ if (value == null || !value.length) return;
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
+ this.encoder_.writeUnsignedVarint32(value.length * 8);
+ for (var i = 0; i < value.length; i++) {
+ this.encoder_.writeInt64(value[i]);
+ }
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a packed float field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writePackedFloat = function(field, value) {
+ if (value == null || !value.length) return;
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
+ this.encoder_.writeUnsignedVarint32(value.length * 4);
+ for (var i = 0; i < value.length; i++) {
+ this.encoder_.writeFloat(value[i]);
+ }
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a packed double field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writePackedDouble = function(field, value) {
+ if (value == null || !value.length) return;
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
+ this.encoder_.writeUnsignedVarint32(value.length * 8);
+ for (var i = 0; i < value.length; i++) {
+ this.encoder_.writeDouble(value[i]);
+ }
+};
+
+
+/**
+ * Writes an array of booleans to the buffer as a packed bool field.
+ * @param {number} field The field number.
+ * @param {?Array.<boolean>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writePackedBool = function(field, value) {
+ if (value == null || !value.length) return;
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
+ this.encoder_.writeUnsignedVarint32(value.length);
+ for (var i = 0; i < value.length; i++) {
+ this.encoder_.writeBool(value[i]);
+ }
+};
+
+
+/**
+ * Writes an array of enums to the buffer as a packed enum field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ */
+jspb.BinaryWriter.prototype.writePackedEnum = function(field, value) {
+ if (value == null || !value.length) return;
+ var bookmark = this.beginDelimited_(field);
+ for (var i = 0; i < value.length; i++) {
+ this.encoder_.writeEnum(value[i]);
+ }
+ this.endDelimited_(bookmark);
+};
+
+
+/**
+ * Writes a 64-bit hash string field (8 characters @ 8 bits of data each) to
+ * the buffer.
+ * @param {number} field The field number.
+ * @param {?Array.<string>} value The array of hashes to write.
+ */
+jspb.BinaryWriter.prototype.writePackedFixedHash64 = function(field, value) {
+ if (value == null || !value.length) return;
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
+ this.encoder_.writeUnsignedVarint32(value.length * 8);
+ for (var i = 0; i < value.length; i++) {
+ this.encoder_.writeFixedHash64(value[i]);
+ }
+};
+
+
+/**
+ * Writes a 64-bit hash string field (8 characters @ 8 bits of data each) to
+ * the buffer.
+ * @param {number} field The field number.
+ * @param {?Array.<string>} value The array of hashes to write.
+ */
+jspb.BinaryWriter.prototype.writePackedVarintHash64 = function(field, value) {
+ if (value == null || !value.length) return;
+ var bookmark = this.beginDelimited_(field);
+ for (var i = 0; i < value.length; i++) {
+ this.encoder_.writeVarintHash64(value[i]);
+ }
+ this.endDelimited_(bookmark);
+};
diff --git a/js/binary/writer_test.js b/js/binary/writer_test.js
new file mode 100644
index 00000000..54d37a21
--- /dev/null
+++ b/js/binary/writer_test.js
@@ -0,0 +1,123 @@
+// 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.
+
+/**
+ * @fileoverview Test cases for jspb's binary protocol buffer writer. In
+ * practice BinaryWriter is used to drive the Decoder and Reader test cases,
+ * so only writer-specific tests are here.
+ *
+ * Test suite is written using Jasmine -- see http://jasmine.github.io/
+ *
+ * @author aappleby@google.com (Austin Appleby)
+ */
+
+goog.require('goog.crypt');
+goog.require('goog.testing.asserts');
+goog.require('jspb.BinaryWriter');
+
+
+/**
+ * @param {function()} func This function should throw an error when run.
+ */
+function assertFails(func) {
+ var e = assertThrows(func);
+ console.log(e);
+ //assertNotNull(e.toString().match(/Error/));
+}
+
+
+describe('binaryWriterTest', function() {
+ /**
+ * Verifies that misuse of the writer class triggers assertions.
+ */
+ it('testWriteErrors', function() {
+ // Submessages with invalid field indices should assert.
+ var writer = new jspb.BinaryWriter();
+ var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
+
+ assertFails(function() {
+ writer.writeMessage(-1, dummyMessage, goog.nullFunction);
+ });
+
+ // Writing invalid field indices should assert.
+ writer = new jspb.BinaryWriter();
+ assertFails(function() {writer.writeUint64(-1, 1);});
+
+ // Writing out-of-range field values should assert.
+ writer = new jspb.BinaryWriter();
+
+ assertFails(function() {writer.writeInt32(1, -Infinity);});
+ assertFails(function() {writer.writeInt32(1, Infinity);});
+
+ assertFails(function() {writer.writeInt64(1, -Infinity);});
+ assertFails(function() {writer.writeInt64(1, Infinity);});
+
+ assertFails(function() {writer.writeUint32(1, -1);});
+ assertFails(function() {writer.writeUint32(1, Infinity);});
+
+ assertFails(function() {writer.writeUint64(1, -1);});
+ assertFails(function() {writer.writeUint64(1, Infinity);});
+
+ assertFails(function() {writer.writeSint32(1, -Infinity);});
+ assertFails(function() {writer.writeSint32(1, Infinity);});
+
+ assertFails(function() {writer.writeSint64(1, -Infinity);});
+ assertFails(function() {writer.writeSint64(1, Infinity);});
+
+ assertFails(function() {writer.writeFixed32(1, -1);});
+ assertFails(function() {writer.writeFixed32(1, Infinity);});
+
+ assertFails(function() {writer.writeFixed64(1, -1);});
+ assertFails(function() {writer.writeFixed64(1, Infinity);});
+
+ assertFails(function() {writer.writeSfixed32(1, -Infinity);});
+ assertFails(function() {writer.writeSfixed32(1, Infinity);});
+
+ assertFails(function() {writer.writeSfixed64(1, -Infinity);});
+ assertFails(function() {writer.writeSfixed64(1, Infinity);});
+ });
+
+
+ /**
+ * Basic test of retrieving the result as a Uint8Array buffer
+ */
+ it('testGetResultBuffer', function() {
+ var expected = '0864120b48656c6c6f20776f726c641a0301020320c801';
+
+ var writer = new jspb.BinaryWriter();
+ writer.writeUint32(1, 100);
+ writer.writeString(2, 'Hello world');
+ writer.writeBytes(3, new Uint8Array([1, 2, 3]));
+ writer.writeUint32(4, 200);
+
+ var buffer = writer.getResultBuffer();
+ assertEquals(expected, goog.crypt.byteArrayToHex(buffer));
+ });
+});
diff --git a/js/commonjs/export.js b/js/commonjs/export.js
new file mode 100644
index 00000000..fb56b30b
--- /dev/null
+++ b/js/commonjs/export.js
@@ -0,0 +1,24 @@
+/**
+ * @fileoverview Export symbols needed by generated code in CommonJS style.
+ *
+ * This effectively is our canonical list of what we publicly export from
+ * the google-protobuf.js file that we build at distribution time.
+ */
+
+goog.require('goog.object');
+goog.require('jspb.BinaryReader');
+goog.require('jspb.BinaryWriter');
+goog.require('jspb.ExtensionFieldBinaryInfo');
+goog.require('jspb.ExtensionFieldInfo');
+goog.require('jspb.Message');
+
+exports.Message = jspb.Message;
+exports.BinaryReader = jspb.BinaryReader;
+exports.BinaryWriter = jspb.BinaryWriter;
+exports.ExtensionFieldInfo = jspb.ExtensionFieldInfo;
+exports.ExtensionFieldBinaryInfo = jspb.ExtensionFieldBinaryInfo;
+
+// These are used by generated code but should not be used directly by clients.
+exports.exportSymbol = goog.exportSymbol;
+exports.inherits = goog.inherits;
+exports.object = {extend: goog.object.extend};
diff --git a/js/commonjs/export_asserts.js b/js/commonjs/export_asserts.js
new file mode 100644
index 00000000..5219d120
--- /dev/null
+++ b/js/commonjs/export_asserts.js
@@ -0,0 +1,37 @@
+/**
+ * @fileoverview Exports symbols needed only by tests.
+ *
+ * This file exports several Closure Library symbols that are only
+ * used by tests. It is used to generate a file
+ * closure_asserts_commonjs.js that is only used at testing time.
+ */
+
+goog.require('goog.testing.asserts');
+
+var global = Function('return this')();
+
+// All of the closure "assert" functions are exported at the global level.
+//
+// The Google Closure assert functions start with assert, eg.
+// assertThrows
+// assertNotThrows
+// assertTrue
+// ...
+//
+// The one exception is the "fail" function.
+function shouldExport(str) {
+ return str.lastIndexOf('assert') === 0 || str == 'fail';
+}
+
+for (var key in global) {
+ if ((typeof key == "string") && global.hasOwnProperty(key) &&
+ shouldExport(key)) {
+ exports[key] = global[key];
+ }
+}
+
+// The COMPILED variable is set by Closure compiler to "true" when it compiles
+// JavaScript, so in practice this is equivalent to "exports.COMPILED = true".
+// This will disable some debugging functionality in debug.js. We could
+// investigate whether this can/should be enabled in CommonJS builds.
+exports.COMPILED = COMPILED
diff --git a/js/commonjs/export_testdeps.js b/js/commonjs/export_testdeps.js
new file mode 100644
index 00000000..59c77ca2
--- /dev/null
+++ b/js/commonjs/export_testdeps.js
@@ -0,0 +1,18 @@
+/**
+ * @fileoverview Export symbols needed by tests in CommonJS style.
+ *
+ * This file is like export.js, but for symbols that are only used by tests.
+ * However we exclude assert functions here, because they are exported into
+ * the global namespace, so those are handled as a special case in
+ * export_asserts.js.
+ */
+
+goog.require('goog.crypt.base64');
+goog.require('jspb.arith.Int64');
+goog.require('jspb.arith.UInt64');
+goog.require('jspb.BinaryEncoder');
+goog.require('jspb.BinaryDecoder');
+goog.require('jspb.utils');
+
+exports.goog = goog;
+exports.jspb = jspb;
diff --git a/js/commonjs/import_test.js b/js/commonjs/import_test.js
new file mode 100644
index 00000000..ffa34fea
--- /dev/null
+++ b/js/commonjs/import_test.js
@@ -0,0 +1,52 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2016 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.
+
+// Test suite is written using Jasmine -- see http://jasmine.github.io/
+
+
+
+var googleProtobuf = require('google-protobuf');
+var asserts = require('closure_asserts_commonjs');
+var global = Function('return this')();
+
+// Bring asserts into the global namespace.
+googleProtobuf.object.extend(global, asserts);
+googleProtobuf.exportSymbol('jspb.Message', googleProtobuf.Message, global);
+
+var test7_pb = require('./test7/test7_pb');
+googleProtobuf.exportSymbol('proto.jspb.test.framing.FramingMessage', test7_pb.FramingMessage, global);
+
+describe('Import test suite', function() {
+ it('testImportedMessage', function() {
+ var framing1 = new proto.jspb.test.framing.FramingMessage([]);
+ var framing2 = new proto.jspb.test.framing.FramingMessage([]);
+ assertObjectEquals(framing1.toObject(), framing2.toObject());
+ });
+});
diff --git a/js/commonjs/jasmine.json b/js/commonjs/jasmine.json
new file mode 100644
index 00000000..666b8edb
--- /dev/null
+++ b/js/commonjs/jasmine.json
@@ -0,0 +1,9 @@
+{
+ "spec_dir": "",
+ "spec_files": [
+ "*_test.js",
+ "binary/proto_test.js"
+ ],
+ "helpers": [
+ ]
+}
diff --git a/js/commonjs/rewrite_tests_for_commonjs.js b/js/commonjs/rewrite_tests_for_commonjs.js
new file mode 100644
index 00000000..b6d90d28
--- /dev/null
+++ b/js/commonjs/rewrite_tests_for_commonjs.js
@@ -0,0 +1,97 @@
+/**
+ * @fileoverview Utility to translate test files to CommonJS imports.
+ *
+ * This is a somewhat hacky tool designed to do one very specific thing.
+ * All of the test files in *_test.js are written with Closure-style
+ * imports (goog.require()). This works great for running the tests
+ * against Closure-style generated code, but we also want to run the
+ * tests against CommonJS-style generated code without having to fork
+ * the tests.
+ *
+ * Closure-style imports import each individual type by name. This is
+ * very different than CommonJS imports which are by file. So we put
+ * special comments in these tests like:
+ *
+ * // CommonJS-LoadFromFile: test_pb
+ * goog.require('proto.jspb.test.CloneExtension');
+ * goog.require('proto.jspb.test.Complex');
+ * goog.require('proto.jspb.test.DefaultValues');
+ *
+ * This script parses that special comment and uses it to generate proper
+ * CommonJS require() statements so that the tests can run and pass using
+ * CommonJS imports. The script will change the above statements into:
+ *
+ * var test_pb = require('test_pb');
+ * googleProtobuf.exportSymbol('proto.jspb.test.CloneExtension', test_pb.CloneExtension, global);
+ * googleProtobuf.exportSymbol('proto.jspb.test.Complex', test_pb.Complex, global);
+ * googleProtobuf.exportSymbol('proto.jspb.test.DefaultValues', test_pb.DefaultValues, global);
+ *
+ * (The "exportSymbol" function will define the given names in the global
+ * namespace, taking care not to overwrite any previous value for
+ * "proto.jspb.test").
+ */
+
+var lineReader = require('readline').createInterface({
+ input: process.stdin,
+ output: process.stdout
+});
+
+function tryStripPrefix(str, prefix) {
+ if (str.lastIndexOf(prefix) !== 0) {
+ throw "String: " + str + " didn't start with: " + prefix;
+ }
+ return str.substr(prefix.length);
+}
+
+function camelCase(str) {
+ var ret = '';
+ var ucaseNext = false;
+ for (var i = 0; i < str.length; i++) {
+ if (str[i] == '-') {
+ ucaseNext = true;
+ } else if (ucaseNext) {
+ ret += str[i].toUpperCase();
+ ucaseNext = false;
+ } else {
+ ret += str[i];
+ }
+ }
+ return ret;
+}
+
+var module = null;
+var pkg = null;
+
+// Header: goes in every file at the top.
+console.log("var global = Function('return this')();");
+console.log("var googleProtobuf = require('google-protobuf');");
+console.log("var testdeps = require('testdeps_commonjs');");
+console.log("global.goog = testdeps.goog;");
+console.log("global.jspb = testdeps.jspb;");
+console.log("var asserts = require('closure_asserts_commonjs');");
+console.log("");
+console.log("// Bring asserts into the global namespace.");
+console.log("googleProtobuf.object.extend(global, asserts);");
+
+lineReader.on('line', function(line) {
+ var isRequire = line.match(/goog\.require\('([^']*)'\)/);
+ var isLoadFromFile = line.match(/CommonJS-LoadFromFile: (\S*) (.*)/);
+ var isSetTestOnly = line.match(/goog.setTestOnly()/);
+ if (isRequire) {
+ if (module) { // Skip goog.require() lines before the first directive.
+ var fullSym = isRequire[1];
+ var sym = tryStripPrefix(fullSym, pkg);
+ console.log("googleProtobuf.exportSymbol('" + fullSym + "', " + module + sym + ', global);');
+ }
+ } else if (isLoadFromFile) {
+ var module_path = isLoadFromFile[1].split('/');
+ module = camelCase(module_path[module_path.length - 1]);
+ pkg = isLoadFromFile[2];
+
+ if (module != "googleProtobuf") { // We unconditionally require this in the header.
+ console.log("var " + module + " = require('./" + isLoadFromFile[1] + "');");
+ }
+ } else if (!isSetTestOnly) { // Remove goog.setTestOnly() lines.
+ console.log(line);
+ }
+});
diff --git a/js/commonjs/test6/test6.proto b/js/commonjs/test6/test6.proto
new file mode 100644
index 00000000..a060925f
--- /dev/null
+++ b/js/commonjs/test6/test6.proto
@@ -0,0 +1,40 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2016 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.
+
+syntax = "proto3";
+
+option java_package = "com.google.apps.jspb.proto";
+option java_multiple_files = true;
+
+package jspb.test.importing;
+
+message ImportedMessage {
+ string string_value = 1;
+}
diff --git a/js/commonjs/test7/test7.proto b/js/commonjs/test7/test7.proto
new file mode 100644
index 00000000..f5574a3d
--- /dev/null
+++ b/js/commonjs/test7/test7.proto
@@ -0,0 +1,42 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2016 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.
+
+syntax = "proto3";
+
+option java_package = "com.google.apps.jspb.proto";
+option java_multiple_files = true;
+
+package jspb.test.framing;
+
+import "test6/test6.proto";
+
+message FramingMessage {
+ jspb.test.importing.ImportedMessage imported_message = 1;
+}
diff --git a/js/data.proto b/js/data.proto
new file mode 100644
index 00000000..74a8a994
--- /dev/null
+++ b/js/data.proto
@@ -0,0 +1,51 @@
+// 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.
+
+// Author: mwr@google.com (Mark Rawling)
+
+syntax = "proto2";
+
+option java_package = "com.google.apps.jspb.proto";
+option java_multiple_files = true;
+
+package jspb.test;
+
+// legacy data, must be nested
+message data {
+ message NestedData {
+ required string str = 1;
+ }
+}
+
+// new data, does not require nesting
+message UnnestedData {
+ required string str = 1;
+}
+
diff --git a/js/debug.js b/js/debug.js
new file mode 100644
index 00000000..3c1ada02
--- /dev/null
+++ b/js/debug.js
@@ -0,0 +1,142 @@
+// 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.
+
+/**
+ * @fileoverview Utilities to debug JSPB based proto objects.
+ */
+
+goog.provide('jspb.debug');
+
+goog.require('goog.array');
+goog.require('goog.asserts');
+goog.require('goog.object');
+goog.require('jspb.Message');
+
+
+/**
+ * Turns a proto into a human readable object that can i.e. be written to the
+ * console: {@code console.log(jspb.debug.dump(myProto))}.
+ * This function makes a best effort and may not work in all cases. It will not
+ * work in obfuscated and or optimized code.
+ * Use this in environments where {@see jspb.Message.prototype.toObject} is
+ * not available for code size reasons.
+ * @param {jspb.Message} message A jspb.Message.
+ * @return {Object}
+ */
+jspb.debug.dump = function(message) {
+ if (!goog.DEBUG) {
+ return null;
+ }
+ goog.asserts.assert(message instanceof jspb.Message,
+ 'jspb.Message instance expected');
+ /** @type {Object} */
+ var object = message;
+ goog.asserts.assert(object['getExtension'],
+ 'Only unobfuscated and unoptimized compilation modes supported.');
+ return /** @type {Object} */ (jspb.debug.dump_(message));
+};
+
+
+/**
+ * Recursively introspects a message and the values its getters return to
+ * make a best effort in creating a human readable representation of the
+ * message.
+ * @param {?} thing A jspb.Message, Array or primitive type to dump.
+ * @return {*}
+ * @private
+ */
+jspb.debug.dump_ = function(thing) {
+ var type = goog.typeOf(thing);
+ if (type == 'number' || type == 'string' || type == 'boolean' ||
+ type == 'null' || type == 'undefined') {
+ return thing;
+ }
+ if (type == 'array') {
+ goog.asserts.assertArray(thing);
+ return goog.array.map(thing, jspb.debug.dump_);
+ }
+ var message = thing; // Copy because we don't want type inference on thing.
+ goog.asserts.assert(message instanceof jspb.Message,
+ 'Only messages expected: ' + thing);
+ var ctor = message.constructor;
+ var messageName = ctor.name || ctor.displayName;
+ var object = {
+ '$name': messageName
+ };
+ for (var name in ctor.prototype) {
+ var match = /^get([A-Z]\w*)/.exec(name);
+ if (match && name != 'getExtension' &&
+ name != 'getJsPbMessageId') {
+ var has = 'has' + match[1];
+ if (!thing[has] || thing[has]())
+ {
+ var val = thing[name]();
+ object[jspb.debug.formatFieldName_(match[1])] = jspb.debug.dump_(val);
+ }
+ }
+ }
+ if (COMPILED && thing['extensionObject_']) {
+ object['$extensions'] = 'Recursive dumping of extensions not supported ' +
+ 'in compiled code. Switch to uncompiled or dump extension object ' +
+ 'directly';
+ return object;
+ }
+ var extensionsObject;
+ for (var id in ctor['extensions']) {
+ if (/^\d+$/.test(id)) {
+ var ext = ctor['extensions'][id];
+ var extVal = thing.getExtension(ext);
+ var fieldName = goog.object.getKeys(ext.fieldName)[0];
+ if (extVal != null) {
+ if (!extensionsObject) {
+ extensionsObject = object['$extensions'] = {};
+ }
+ extensionsObject[jspb.debug.formatFieldName_(fieldName)] =
+ jspb.debug.dump_(extVal);
+ }
+ }
+ }
+ return object;
+};
+
+
+/**
+ * Formats a field name for output as camelCase.
+ *
+ * @param {string} name Name of the field.
+ * @return {string}
+ * @private
+ */
+jspb.debug.formatFieldName_ = function(name) {
+ // Name may be in TitleCase.
+ return name.replace(/^[A-Z]/, function(c) {
+ return c.toLowerCase();
+ });
+};
diff --git a/js/debug_test.js b/js/debug_test.js
new file mode 100644
index 00000000..01cbf891
--- /dev/null
+++ b/js/debug_test.js
@@ -0,0 +1,105 @@
+// 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.
+
+goog.setTestOnly();
+
+goog.require('goog.testing.asserts');
+
+// CommonJS-LoadFromFile: google-protobuf
+goog.require('jspb.debug');
+
+// CommonJS-LoadFromFile: test_pb
+goog.require('proto.jspb.test.HasExtensions');
+goog.require('proto.jspb.test.IsExtension');
+goog.require('proto.jspb.test.Simple1');
+
+
+
+describe('debugTest', function() {
+ it('testSimple1', function() {
+ if (COMPILED) {
+ return;
+ }
+ var message = new proto.jspb.test.Simple1();
+ message.setAString('foo');
+ assertObjectEquals({
+ $name: 'proto.jspb.test.Simple1',
+ 'aString': 'foo',
+ 'aRepeatedStringList': []
+ }, jspb.debug.dump(message));
+
+ message.setABoolean(true);
+ message.setARepeatedStringList(['1', '2']);
+
+ assertObjectEquals({
+ $name: 'proto.jspb.test.Simple1',
+ 'aString': 'foo',
+ 'aRepeatedStringList': ['1', '2'],
+ 'aBoolean': true
+ }, jspb.debug.dump(message));
+
+ message.setAString(undefined);
+
+ assertObjectEquals({
+ $name: 'proto.jspb.test.Simple1',
+ 'aRepeatedStringList': ['1', '2'],
+ 'aBoolean': true
+ }, jspb.debug.dump(message));
+ });
+
+
+ it('testExtensions', function() {
+ if (COMPILED) {
+ return;
+ }
+ var extension = new proto.jspb.test.IsExtension();
+ extension.setExt1('ext1field');
+ var extendable = new proto.jspb.test.HasExtensions();
+ extendable.setStr1('v1');
+ extendable.setStr2('v2');
+ extendable.setStr3('v3');
+ extendable.setExtension(proto.jspb.test.IsExtension.extField, extension);
+
+ assertObjectEquals({
+ '$name': 'proto.jspb.test.HasExtensions',
+ 'str1': 'v1',
+ 'str2': 'v2',
+ 'str3': 'v3',
+ '$extensions': {
+ 'extField': {
+ '$name': 'proto.jspb.test.IsExtension',
+ 'ext1': 'ext1field'
+ },
+ 'repeatedSimpleList': []
+ }
+ }, jspb.debug.dump(extendable));
+ });
+
+});
diff --git a/js/gulpfile.js b/js/gulpfile.js
new file mode 100644
index 00000000..cca99131
--- /dev/null
+++ b/js/gulpfile.js
@@ -0,0 +1,143 @@
+var gulp = require('gulp');
+var execFile = require('child_process').execFile;
+var glob = require('glob');
+
+function exec(command, cb) {
+ execFile('sh', ['-c', command], cb);
+}
+
+var protoc = process.env.PROTOC || '../src/protoc';
+
+var wellKnownTypes = [
+ '../src/google/protobuf/any.proto',
+ '../src/google/protobuf/api.proto',
+ '../src/google/protobuf/compiler/plugin.proto',
+ '../src/google/protobuf/descriptor.proto',
+ '../src/google/protobuf/duration.proto',
+ '../src/google/protobuf/empty.proto',
+ '../src/google/protobuf/field_mask.proto',
+ '../src/google/protobuf/source_context.proto',
+ '../src/google/protobuf/struct.proto',
+ '../src/google/protobuf/timestamp.proto',
+ '../src/google/protobuf/type.proto',
+ '../src/google/protobuf/wrappers.proto',
+];
+
+gulp.task('genproto_closure', function (cb) {
+ exec(protoc + ' --js_out=library=testproto_libs,binary:. -I ../src -I . *.proto ../src/google/protobuf/descriptor.proto',
+ function (err, stdout, stderr) {
+ console.log(stdout);
+ console.log(stderr);
+ cb(err);
+ });
+});
+
+gulp.task('genproto_commonjs', function (cb) {
+ exec('mkdir -p commonjs_out && ' + protoc + ' --js_out=import_style=commonjs,binary:commonjs_out -I ../src -I commonjs -I . *.proto commonjs/test*/*.proto ../src/google/protobuf/descriptor.proto',
+ function (err, stdout, stderr) {
+ console.log(stdout);
+ console.log(stderr);
+ cb(err);
+ });
+});
+
+gulp.task('genproto_commonjs_wellknowntypes', function (cb) {
+ exec('mkdir -p commonjs_out/node_modules/google-protobuf && ' + protoc + ' --js_out=import_style=commonjs,binary:commonjs_out/node_modules/google-protobuf -I ../src ../src/google/protobuf/descriptor.proto',
+ function (err, stdout, stderr) {
+ console.log(stdout);
+ console.log(stderr);
+ cb(err);
+ });
+});
+
+gulp.task('genproto_wellknowntypes', function (cb) {
+ exec(protoc + ' --js_out=import_style=commonjs,binary:. -I ../src ' + wellKnownTypes.join(' '),
+ function (err, stdout, stderr) {
+ console.log(stdout);
+ console.log(stderr);
+ cb(err);
+ });
+});
+
+gulp.task('dist', ['genproto_wellknowntypes'], function (cb) {
+ // TODO(haberman): minify this more aggressively.
+ // Will require proper externs/exports.
+ exec('./node_modules/google-closure-library/closure/bin/calcdeps.py -i message.js -i binary/reader.js -i binary/writer.js -i commonjs/export.js -p . -p node_modules/google-closure-library/closure -o compiled --compiler_jar node_modules/google-closure-compiler/compiler.jar > google-protobuf.js',
+ function (err, stdout, stderr) {
+ console.log(stdout);
+ console.log(stderr);
+ cb(err);
+ });
+});
+
+gulp.task('commonjs_asserts', function (cb) {
+ exec('mkdir -p commonjs_out/test_node_modules && ./node_modules/google-closure-library/closure/bin/calcdeps.py -i commonjs/export_asserts.js -p . -p node_modules/google-closure-library/closure -o compiled --compiler_jar node_modules/google-closure-compiler/compiler.jar > commonjs_out/test_node_modules/closure_asserts_commonjs.js',
+ function (err, stdout, stderr) {
+ console.log(stdout);
+ console.log(stderr);
+ cb(err);
+ });
+});
+
+gulp.task('commonjs_testdeps', function (cb) {
+ exec('mkdir -p commonjs_out/test_node_modules && ./node_modules/google-closure-library/closure/bin/calcdeps.py -i commonjs/export_testdeps.js -p . -p node_modules/google-closure-library/closure -o compiled --compiler_jar node_modules/google-closure-compiler/compiler.jar > commonjs_out/test_node_modules/testdeps_commonjs.js',
+ function (err, stdout, stderr) {
+ console.log(stdout);
+ console.log(stderr);
+ cb(err);
+ });
+});
+
+gulp.task('make_commonjs_out', ['dist', 'genproto_commonjs', 'genproto_commonjs_wellknowntypes', 'commonjs_asserts', 'commonjs_testdeps'], function (cb) {
+ // TODO(haberman): minify this more aggressively.
+ // Will require proper externs/exports.
+ var cmd = "mkdir -p commonjs_out/binary && mkdir -p commonjs_out/test_node_modules && ";
+ function addTestFile(file) {
+ cmd += 'node commonjs/rewrite_tests_for_commonjs.js < ' + file +
+ ' > commonjs_out/' + file + '&& ';
+ }
+
+ glob.sync('*_test.js').forEach(addTestFile);
+ glob.sync('binary/*_test.js').forEach(addTestFile);
+
+ exec(cmd +
+ 'cp commonjs/jasmine.json commonjs_out/jasmine.json && ' +
+ 'cp google-protobuf.js commonjs_out/test_node_modules && ' +
+ 'cp commonjs/import_test.js commonjs_out/import_test.js',
+ function (err, stdout, stderr) {
+ console.log(stdout);
+ console.log(stderr);
+ cb(err);
+ });
+});
+
+gulp.task('deps', ['genproto_closure'], function (cb) {
+ exec('./node_modules/google-closure-library/closure/bin/build/depswriter.py *.js binary/*.js > deps.js',
+ function (err, stdout, stderr) {
+ console.log(stdout);
+ console.log(stderr);
+ cb(err);
+ });
+});
+
+gulp.task('test_closure', ['genproto_closure', 'deps'], function (cb) {
+ exec('JASMINE_CONFIG_PATH=jasmine.json ./node_modules/.bin/jasmine',
+ function (err, stdout, stderr) {
+ console.log(stdout);
+ console.log(stderr);
+ cb(err);
+ });
+});
+
+gulp.task('test_commonjs', ['make_commonjs_out'], function (cb) {
+ exec('cd commonjs_out && JASMINE_CONFIG_PATH=jasmine.json NODE_PATH=test_node_modules ../node_modules/.bin/jasmine',
+ function (err, stdout, stderr) {
+ console.log(stdout);
+ console.log(stderr);
+ cb(err);
+ });
+});
+
+gulp.task('test', ['test_closure', 'test_commonjs'], function(cb) {
+ cb();
+});
diff --git a/js/jasmine.json b/js/jasmine.json
new file mode 100644
index 00000000..f83c54c0
--- /dev/null
+++ b/js/jasmine.json
@@ -0,0 +1,12 @@
+{
+ "spec_dir": "",
+ "spec_files": [
+ "*_test.js",
+ "binary/*_test.js"
+ ],
+ "helpers": [
+ "node_modules/google-closure-library/closure/goog/bootstrap/nodejs.js",
+ "node_loader.js",
+ "deps.js"
+ ]
+}
diff --git a/js/map.js b/js/map.js
new file mode 100644
index 00000000..e6406a60
--- /dev/null
+++ b/js/map.js
@@ -0,0 +1,463 @@
+// 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.
+
+goog.provide('jspb.Map');
+
+goog.require('goog.asserts');
+
+goog.forwardDeclare('jspb.BinaryReader');
+goog.forwardDeclare('jspb.BinaryWriter');
+
+
+
+/**
+ * Constructs a new Map. A Map is a container that is used to implement map
+ * fields on message objects. It closely follows the ES6 Map API; however,
+ * it is distinct because we do not want to depend on external polyfills or
+ * on ES6 itself.
+ *
+ * This constructor should only be called from generated message code. It is not
+ * intended for general use by library consumers.
+ *
+ * @template K, V
+ *
+ * @param {!Array<!Array<!Object>>} arr
+ *
+ * @param {?function(new:V)|function(new:V,?)=} opt_valueCtor
+ * The constructor for type V, if type V is a message type.
+ *
+ * @constructor
+ * @struct
+ */
+jspb.Map = function(arr, opt_valueCtor) {
+ /** @const @private */
+ this.arr_ = arr;
+ /** @const @private */
+ this.valueCtor_ = opt_valueCtor;
+
+ /** @type {!Object<string, !jspb.Map.Entry_<K,V>>} @private */
+ this.map_ = {};
+
+ /**
+ * Is `this.arr_ updated with respect to `this.map_`?
+ * @type {boolean}
+ */
+ this.arrClean = true;
+
+ if (this.arr_.length > 0) {
+ this.loadFromArray_();
+ }
+};
+
+
+/**
+ * Load initial content from underlying array.
+ * @private
+ */
+jspb.Map.prototype.loadFromArray_ = function() {
+ for (var i = 0; i < this.arr_.length; i++) {
+ var record = this.arr_[i];
+ var key = record[0];
+ var value = record[1];
+ this.map_[key.toString()] = new jspb.Map.Entry_(key, value);
+ }
+ this.arrClean = true;
+};
+
+
+/**
+ * Synchronize content to underlying array, if needed, and return it.
+ * @return {!Array<!Array<!Object>>}
+ */
+jspb.Map.prototype.toArray = function() {
+ if (this.arrClean) {
+ if (this.valueCtor_) {
+ // We need to recursively sync maps in submessages to their arrays.
+ var m = this.map_;
+ for (var p in m) {
+ if (Object.prototype.hasOwnProperty.call(m, p)) {
+ m[p].valueWrapper.toArray();
+ }
+ }
+ }
+ } else {
+ // Delete all elements.
+ this.arr_.length = 0;
+ var strKeys = this.stringKeys_();
+ // Output keys in deterministic (sorted) order.
+ strKeys.sort();
+ for (var i = 0; i < strKeys.length; i++) {
+ var entry = this.map_[strKeys[i]];
+ var valueWrapper = /** @type {!Object} */ (entry.valueWrapper);
+ if (valueWrapper) {
+ valueWrapper.toArray();
+ }
+ this.arr_.push([entry.key, entry.value]);
+ }
+ this.arrClean = true;
+ }
+ return this.arr_;
+};
+
+
+/**
+ * Helper: return an iterator over an array.
+ * @template T
+ * @param {!Array<T>} arr the array
+ * @return {!Iterator<T>} an iterator
+ * @private
+ */
+jspb.Map.arrayIterator_ = function(arr) {
+ var idx = 0;
+ return /** @type {!Iterator} */ ({
+ next: function() {
+ if (idx < arr.length) {
+ return { done: false, value: arr[idx++] };
+ } else {
+ return { done: true };
+ }
+ }
+ });
+};
+
+
+/**
+ * Returns the map's length (number of key/value pairs).
+ * @return {number}
+ */
+jspb.Map.prototype.getLength = function() {
+ return this.stringKeys_().length;
+};
+
+
+/**
+ * Clears the map.
+ */
+jspb.Map.prototype.clear = function() {
+ this.map_ = {};
+ this.arrClean = false;
+};
+
+
+/**
+ * Deletes a particular key from the map.
+ * N.B.: differs in name from ES6 Map's `delete` because IE8 does not support
+ * reserved words as property names.
+ * @this {jspb.Map}
+ * @param {K} key
+ * @return {boolean} Whether any entry with this key was deleted.
+ */
+jspb.Map.prototype.del = function(key) {
+ var keyValue = key.toString();
+ var hadKey = this.map_.hasOwnProperty(keyValue);
+ delete this.map_[keyValue];
+ this.arrClean = false;
+ return hadKey;
+};
+
+
+/**
+ * Returns an array of [key, value] pairs in the map.
+ *
+ * This is redundant compared to the plain entries() method, but we provide this
+ * to help out Angular 1.x users. Still evaluating whether this is the best
+ * option.
+ *
+ * @return {!Array<K|V>}
+ */
+jspb.Map.prototype.getEntryList = function() {
+ var entries = [];
+ var strKeys = this.stringKeys_();
+ strKeys.sort();
+ for (var i = 0; i < strKeys.length; i++) {
+ var entry = this.map_[strKeys[i]];
+ entries.push([entry.key, entry.value]);
+ }
+ return entries;
+};
+
+
+/**
+ * Returns an iterator over [key, value] pairs in the map.
+ * Closure compiler sadly doesn't support tuples, ie. Iterator<[K,V]>.
+ * @return {!Iterator<!Array<K|V>>}
+ * The iterator
+ */
+jspb.Map.prototype.entries = function() {
+ var entries = [];
+ var strKeys = this.stringKeys_();
+ strKeys.sort();
+ for (var i = 0; i < strKeys.length; i++) {
+ var entry = this.map_[strKeys[i]];
+ entries.push([entry.key, this.wrapEntry_(entry)]);
+ }
+ return jspb.Map.arrayIterator_(entries);
+};
+
+
+/**
+ * Returns an iterator over keys in the map.
+ * @return {!Iterator<K>} The iterator
+ */
+jspb.Map.prototype.keys = function() {
+ var keys = [];
+ var strKeys = this.stringKeys_();
+ strKeys.sort();
+ for (var i = 0; i < strKeys.length; i++) {
+ var entry = this.map_[strKeys[i]];
+ keys.push(entry.key);
+ }
+ return jspb.Map.arrayIterator_(keys);
+};
+
+
+/**
+ * Returns an iterator over values in the map.
+ * @return {!Iterator<V>} The iterator
+ */
+jspb.Map.prototype.values = function() {
+ var values = [];
+ var strKeys = this.stringKeys_();
+ strKeys.sort();
+ for (var i = 0; i < strKeys.length; i++) {
+ var entry = this.map_[strKeys[i]];
+ values.push(this.wrapEntry_(entry));
+ }
+ return jspb.Map.arrayIterator_(values);
+};
+
+
+/**
+ * Iterates over entries in the map, calling a function on each.
+ * @template T
+ * @param {function(this:T, V, K, ?jspb.Map<K, V>)} cb
+ * @param {T=} opt_thisArg
+ */
+jspb.Map.prototype.forEach = function(cb, opt_thisArg) {
+ var strKeys = this.stringKeys_();
+ strKeys.sort();
+ for (var i = 0; i < strKeys.length; i++) {
+ var entry = this.map_[strKeys[i]];
+ cb.call(opt_thisArg, this.wrapEntry_(entry), entry.key, this);
+ }
+};
+
+
+/**
+ * Sets a key in the map to the given value.
+ * @param {K} key The key
+ * @param {V} value The value
+ * @return {!jspb.Map<K,V>}
+ */
+jspb.Map.prototype.set = function(key, value) {
+ var entry = new jspb.Map.Entry_(key);
+ if (this.valueCtor_) {
+ entry.valueWrapper = value;
+ // .toArray() on a message returns a reference to the underlying array
+ // rather than a copy.
+ entry.value = value.toArray();
+ } else {
+ entry.value = value;
+ }
+ this.map_[key.toString()] = entry;
+ this.arrClean = false;
+ return this;
+};
+
+
+/**
+ * Helper: lazily construct a wrapper around an entry, if needed, and return the
+ * user-visible type.
+ * @param {!jspb.Map.Entry_<K,V>} entry
+ * @return {V}
+ * @private
+ */
+jspb.Map.prototype.wrapEntry_ = function(entry) {
+ if (this.valueCtor_) {
+ if (!entry.valueWrapper) {
+ entry.valueWrapper = new this.valueCtor_(entry.value);
+ }
+ return /** @type {V} */ (entry.valueWrapper);
+ } else {
+ return entry.value;
+ }
+};
+
+
+/**
+ * Gets the value corresponding to a key in the map.
+ * @param {K} key
+ * @return {V|undefined} The value, or `undefined` if key not present
+ */
+jspb.Map.prototype.get = function(key) {
+ var keyValue = key.toString();
+ var entry = this.map_[keyValue];
+ if (entry) {
+ return this.wrapEntry_(entry);
+ } else {
+ return undefined;
+ }
+};
+
+
+/**
+ * Determines whether the given key is present in the map.
+ * @param {K} key
+ * @return {boolean} `true` if the key is present
+ */
+jspb.Map.prototype.has = function(key) {
+ var keyValue = key.toString();
+ return (keyValue in this.map_);
+};
+
+
+/**
+ * Write this Map field in wire format to a BinaryWriter, using the given field
+ * number.
+ * @param {number} fieldNumber
+ * @param {!jspb.BinaryWriter} writer
+ * @param {function(this:jspb.BinaryWriter,number,K)=} keyWriterFn
+ * The method on BinaryWriter that writes type K to the stream.
+ * @param {function(this:jspb.BinaryWriter,number,V)|
+ * function(this:jspb.BinaryReader,V,?)=} valueWriterFn
+ * The method on BinaryWriter that writes type V to the stream. May be
+ * writeMessage, in which case the second callback arg form is used.
+ * @param {?function(V,!jspb.BinaryWriter)=} opt_valueWriterCallback
+ * The BinaryWriter serialization callback for type V, if V is a message
+ * type.
+ */
+jspb.Map.prototype.serializeBinary = function(
+ fieldNumber, writer, keyWriterFn, valueWriterFn, opt_valueWriterCallback) {
+ var strKeys = this.stringKeys_();
+ strKeys.sort();
+ for (var i = 0; i < strKeys.length; i++) {
+ var entry = this.map_[strKeys[i]];
+ writer.beginSubMessage(fieldNumber);
+ keyWriterFn.call(writer, 1, entry.key);
+ if (this.valueCtor_) {
+ valueWriterFn.call(writer, 2, this.wrapEntry_(entry),
+ opt_valueWriterCallback);
+ } else {
+ valueWriterFn.call(writer, 2, entry.value);
+ }
+ writer.endSubMessage();
+ }
+};
+
+
+/**
+ * Read one key/value message from the given BinaryReader. Compatible as the
+ * `reader` callback parameter to jspb.BinaryReader.readMessage, to be called
+ * when a key/value pair submessage is encountered.
+ * @param {!jspb.Map} map
+ * @param {!jspb.BinaryReader} reader
+ * @param {function(this:jspb.BinaryReader):K=} keyReaderFn
+ * The method on BinaryReader that reads type K from the stream.
+ *
+ * @param {function(this:jspb.BinaryReader):V|
+ * function(this:jspb.BinaryReader,V,
+ * function(V,!jspb.BinaryReader))=} valueReaderFn
+ * The method on BinaryReader that reads type V from the stream. May be
+ * readMessage, in which case the second callback arg form is used.
+ *
+ * @param {?function(V,!jspb.BinaryReader)=} opt_valueReaderCallback
+ * The BinaryReader parsing callback for type V, if V is a message type.
+ *
+ */
+jspb.Map.deserializeBinary = function(map, reader, keyReaderFn, valueReaderFn,
+ opt_valueReaderCallback) {
+ var key = undefined;
+ var value = undefined;
+
+ while (reader.nextField()) {
+ if (reader.isEndGroup()) {
+ break;
+ }
+ var field = reader.getFieldNumber();
+ if (field == 1) {
+ // Key.
+ key = keyReaderFn.call(reader);
+ } else if (field == 2) {
+ // Value.
+ if (map.valueCtor_) {
+ value = new map.valueCtor_();
+ valueReaderFn.call(reader, value, opt_valueReaderCallback);
+ } else {
+ value = valueReaderFn.call(reader);
+ }
+ }
+ }
+
+ goog.asserts.assert(key != undefined);
+ goog.asserts.assert(value != undefined);
+ map.set(key, value);
+};
+
+
+/**
+ * Helper: compute the list of all stringified keys in the underlying Object
+ * map.
+ * @return {!Array<string>}
+ * @private
+ */
+jspb.Map.prototype.stringKeys_ = function() {
+ var m = this.map_;
+ var ret = [];
+ for (var p in m) {
+ if (Object.prototype.hasOwnProperty.call(m, p)) {
+ ret.push(p);
+ }
+ }
+ return ret;
+};
+
+
+
+/**
+ * @param {!K} key The entry's key.
+ * @param {V=} opt_value The entry's value wrapper.
+ * @constructor
+ * @struct
+ * @template K, V
+ * @private
+ */
+jspb.Map.Entry_ = function(key, opt_value) {
+ /** @const {K} */
+ this.key = key;
+
+ // The JSPB-serializable value. For primitive types this will be of type V.
+ // For message types it will be an array.
+ /** @type {V} */
+ this.value = opt_value;
+
+ // Only used for submessage values.
+ /** @type {V} */
+ this.valueWrapper = undefined;
+};
diff --git a/js/message.js b/js/message.js
new file mode 100644
index 00000000..631ebe69
--- /dev/null
+++ b/js/message.js
@@ -0,0 +1,1431 @@
+// 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.
+
+/**
+ * @fileoverview Definition of jspb.Message.
+ *
+ * @author mwr@google.com (Mark Rawling)
+ */
+
+goog.provide('jspb.ExtensionFieldBinaryInfo');
+goog.provide('jspb.ExtensionFieldInfo');
+goog.provide('jspb.Message');
+
+goog.require('goog.array');
+goog.require('goog.asserts');
+goog.require('goog.crypt.base64');
+goog.require('goog.json');
+goog.require('jspb.Map');
+
+// Not needed in compilation units that have no protos with xids.
+goog.forwardDeclare('xid.String');
+
+
+
+/**
+ * Stores information for a single extension field.
+ *
+ * For example, an extension field defined like so:
+ *
+ * extend BaseMessage {
+ * optional MyMessage my_field = 123;
+ * }
+ *
+ * will result in an ExtensionFieldInfo object with these properties:
+ *
+ * {
+ * fieldIndex: 123,
+ * fieldName: {my_field_renamed: 0},
+ * ctor: proto.example.MyMessage,
+ * toObjectFn: proto.example.MyMessage.toObject,
+ * isRepeated: 0
+ * }
+ *
+ * We include `toObjectFn` to allow the JSCompiler to perform dead-code removal
+ * on unused toObject() methods.
+ *
+ * If an extension field is primitive, ctor and toObjectFn will be null.
+ * isRepeated should be 0 or 1.
+ *
+ * binary{Reader,Writer}Fn and (if message type) binaryMessageSerializeFn are
+ * always provided. binaryReaderFn and binaryWriterFn are references to the
+ * appropriate methods on BinaryReader/BinaryWriter to read/write the value of
+ * this extension, and binaryMessageSerializeFn is a reference to the message
+ * class's .serializeBinary method, if available.
+ *
+ * @param {number} fieldNumber
+ * @param {Object} fieldName This has the extension field name as a property.
+ * @param {?function(new: jspb.Message, Array=)} ctor
+ * @param {?function((boolean|undefined),!jspb.Message):!Object} toObjectFn
+ * @param {number} isRepeated
+ * @constructor
+ * @struct
+ * @template T
+ */
+jspb.ExtensionFieldInfo = function(fieldNumber, fieldName, ctor, toObjectFn,
+ isRepeated) {
+ /** @const */
+ this.fieldIndex = fieldNumber;
+ /** @const */
+ this.fieldName = fieldName;
+ /** @const */
+ this.ctor = ctor;
+ /** @const */
+ this.toObjectFn = toObjectFn;
+ /** @const */
+ this.isRepeated = isRepeated;
+};
+
+/**
+ * Stores binary-related information for a single extension field.
+ * @param {!jspb.ExtensionFieldInfo<T>} fieldInfo
+ * @param {?function(number,?)=} binaryReaderFn
+ * @param {?function(number,?)|function(number,?,?,?,?,?)=} binaryWriterFn
+ * @param {?function(?,?)=} opt_binaryMessageSerializeFn
+ * @param {?function(?,?)=} opt_binaryMessageDeserializeFn
+ * @param {?boolean=} opt_isPacked
+ * @constructor
+ * @struct
+ * @template T
+ */
+jspb.ExtensionFieldBinaryInfo = function(fieldInfo, binaryReaderFn, binaryWriterFn,
+ binaryMessageSerializeFn, binaryMessageDeserializeFn, isPacked) {
+ /** @const */
+ this.fieldInfo = fieldInfo;
+ /** @const */
+ this.binaryReaderFn = binaryReaderFn;
+ /** @const */
+ this.binaryWriterFn = binaryWriterFn;
+ /** @const */
+ this.binaryMessageSerializeFn = binaryMessageSerializeFn;
+ /** @const */
+ this.binaryMessageDeserializeFn = binaryMessageDeserializeFn;
+ /** @const */
+ this.isPacked = isPacked;
+};
+
+/**
+ * @return {boolean} Does this field represent a sub Message?
+ */
+jspb.ExtensionFieldInfo.prototype.isMessageType = function() {
+ return !!this.ctor;
+};
+
+
+/**
+ * Base class for all JsPb messages.
+ * @constructor
+ * @struct
+ */
+jspb.Message = function() {
+};
+
+
+/**
+ * @define {boolean} Whether to generate toObject methods for objects. Turn
+ * this off, if you do not want toObject to be ever used in your project.
+ * When turning off this flag, consider adding a conformance test that bans
+ * calling toObject. Enabling this will disable the JSCompiler's ability to
+ * dead code eliminate fields used in protocol buffers that are never used
+ * in an application.
+ */
+goog.define('jspb.Message.GENERATE_TO_OBJECT', true);
+
+
+/**
+ * @define {boolean} Whether to generate fromObject methods for objects. Turn
+ * this off, if you do not want fromObject to be ever used in your project.
+ * When turning off this flag, consider adding a conformance test that bans
+ * calling fromObject. Enabling this might disable the JSCompiler's ability
+ * to dead code eliminate fields used in protocol buffers that are never
+ * used in an application.
+ * NOTE: By default no protos actually have a fromObject method. You need to
+ * add the jspb.generate_from_object options to the proto definition to
+ * activate the feature.
+ * By default this is enabled for test code only.
+ */
+goog.define('jspb.Message.GENERATE_FROM_OBJECT', !goog.DISALLOW_TEST_ONLY_CODE);
+
+
+/**
+ * @define {boolean} Turning on this flag does NOT change the behavior of JSPB
+ * and only affects private internal state. It may, however, break some
+ * tests that use naive deeply-equals algorithms, because using a proto
+ * mutates its internal state.
+ * Projects are advised to turn this flag always on.
+ */
+goog.define('jspb.Message.MINIMIZE_MEMORY_ALLOCATIONS', COMPILED);
+// TODO(b/19419436) Turn this on by default.
+
+
+/**
+ * Does this browser support Uint8Aray typed arrays?
+ * @type {boolean}
+ * @private
+ */
+jspb.Message.SUPPORTS_UINT8ARRAY_ = (typeof Uint8Array == 'function');
+
+
+/**
+ * The internal data array.
+ * @type {!Array}
+ * @protected
+ */
+jspb.Message.prototype.array;
+
+
+/**
+ * Wrappers are the constructed instances of message-type fields. They are built
+ * on demand from the raw array data. Includes message fields, repeated message
+ * fields and extension message fields. Indexed by field number.
+ * @type {Object}
+ * @private
+ */
+jspb.Message.prototype.wrappers_;
+
+
+/**
+ * The object that contains extension fields, if any. This is an object that
+ * maps from a proto field number to the field's value.
+ * @type {Object}
+ * @private
+ */
+jspb.Message.prototype.extensionObject_;
+
+
+/**
+ * Non-extension fields with a field number at or above the pivot are
+ * stored in the extension object (in addition to all extension fields).
+ * @type {number}
+ * @private
+ */
+jspb.Message.prototype.pivot_;
+
+
+/**
+ * The JsPb message_id of this proto.
+ * @type {string|undefined} the message id or undefined if this message
+ * has no id.
+ * @private
+ */
+jspb.Message.prototype.messageId_;
+
+
+/**
+ * Repeated float or double fields which have been converted to include only
+ * numbers and not strings holding "NaN", "Infinity" and "-Infinity".
+ * @private {!Object<number,boolean>|undefined}
+ */
+jspb.Message.prototype.convertedFloatingPointFields_;
+
+
+/**
+ * The xid of this proto type (The same for all instances of a proto). Provides
+ * a way to identify a proto by stable obfuscated name.
+ * @see {xid}.
+ * Available if {@link jspb.generate_xid} is added as a Message option to
+ * a protocol buffer.
+ * @const {!xid.String|undefined} The xid or undefined if message is
+ * annotated to generate the xid.
+ */
+jspb.Message.prototype.messageXid;
+
+
+
+/**
+ * Returns the JsPb message_id of this proto.
+ * @return {string|undefined} the message id or undefined if this message
+ * has no id.
+ */
+jspb.Message.prototype.getJsPbMessageId = function() {
+ return this.messageId_;
+};
+
+
+/**
+ * An offset applied to lookups into this.array to account for the presence or
+ * absence of a messageId at position 0. For response messages, this will be 0.
+ * Otherwise, it will be -1 so that the first array position is not wasted.
+ * @type {number}
+ * @private
+ */
+jspb.Message.prototype.arrayIndexOffset_;
+
+
+/**
+ * Returns the index into msg.array at which the proto field with tag number
+ * fieldNumber will be located.
+ * @param {!jspb.Message} msg Message for which we're calculating an index.
+ * @param {number} fieldNumber The field number.
+ * @return {number} The index.
+ * @private
+ */
+jspb.Message.getIndex_ = function(msg, fieldNumber) {
+ return fieldNumber + msg.arrayIndexOffset_;
+};
+
+
+/**
+ * Initializes a JsPb Message.
+ * @param {!jspb.Message} msg The JsPb proto to modify.
+ * @param {Array|undefined} data An initial data array.
+ * @param {string|number} messageId For response messages, the message id or ''
+ * if no message id is specified. For non-response messages, 0.
+ * @param {number} suggestedPivot The field number at which to start putting
+ * fields into the extension object. This is only used if data does not
+ * contain an extension object already. -1 if no extension object is
+ * required for this message type.
+ * @param {Array<number>} repeatedFields The message's repeated fields.
+ * @param {Array<!Array<number>>=} opt_oneofFields The fields belonging to
+ * each of the message's oneof unions.
+ * @protected
+ */
+jspb.Message.initialize = function(
+ msg, data, messageId, suggestedPivot, repeatedFields, opt_oneofFields) {
+ msg.wrappers_ = jspb.Message.MINIMIZE_MEMORY_ALLOCATIONS ? null : {};
+ if (!data) {
+ data = messageId ? [messageId] : [];
+ }
+ msg.messageId_ = messageId ? String(messageId) : undefined;
+ // If the messageId is 0, this message is not a response message, so we shift
+ // array indices down by 1 so as not to waste the first position in the array,
+ // which would otherwise go unused.
+ msg.arrayIndexOffset_ = messageId === 0 ? -1 : 0;
+ msg.array = data;
+ jspb.Message.materializeExtensionObject_(msg, suggestedPivot);
+ msg.convertedFloatingPointFields_ = {};
+
+ if (repeatedFields) {
+ for (var i = 0; i < repeatedFields.length; i++) {
+ var fieldNumber = repeatedFields[i];
+ if (fieldNumber < msg.pivot_) {
+ var index = jspb.Message.getIndex_(msg, fieldNumber);
+ msg.array[index] = msg.array[index] ||
+ (jspb.Message.MINIMIZE_MEMORY_ALLOCATIONS ?
+ jspb.Message.EMPTY_LIST_SENTINEL_ :
+ []);
+ } else {
+ msg.extensionObject_[fieldNumber] =
+ msg.extensionObject_[fieldNumber] ||
+ (jspb.Message.MINIMIZE_MEMORY_ALLOCATIONS ?
+ jspb.Message.EMPTY_LIST_SENTINEL_ :
+ []);
+ }
+ }
+ }
+
+ if (opt_oneofFields && opt_oneofFields.length) {
+ // Compute the oneof case for each union. This ensures only one value is
+ // set in the union.
+ goog.array.forEach(
+ opt_oneofFields, goog.partial(jspb.Message.computeOneofCase, msg));
+ }
+};
+
+
+/**
+ * Used to mark empty repeated fields. Serializes to null when serialized
+ * to JSON.
+ * When reading a repeated field readers must check the return value against
+ * this value and return and replace it with a new empty array if it is
+ * present.
+ * @private @const {!Object}
+ */
+jspb.Message.EMPTY_LIST_SENTINEL_ = goog.DEBUG && Object.freeze ?
+ Object.freeze([]) :
+ [];
+
+
+/**
+ * Ensures that the array contains an extension object if necessary.
+ * If the array contains an extension object in its last position, then the
+ * object is kept in place and its position is used as the pivot. If not, then
+ * create an extension object using suggestedPivot. If suggestedPivot is -1,
+ * we don't have an extension object at all, in which case all fields are stored
+ * in the array.
+ * @param {!jspb.Message} msg The JsPb proto to modify.
+ * @param {number} suggestedPivot See description for initialize().
+ * @private
+ */
+jspb.Message.materializeExtensionObject_ = function(msg, suggestedPivot) {
+ if (msg.array.length) {
+ var foundIndex = msg.array.length - 1;
+ var obj = msg.array[foundIndex];
+ // Normal fields are never objects, so we can be sure that if we find an
+ // object here, then it's the extension object. However, we must ensure that
+ // the object is not an array, since arrays are valid field values.
+ // NOTE(lukestebbing): We avoid looking at .length to avoid a JIT bug
+ // in Safari on iOS 8. See the description of CL/86511464 for details.
+ if (obj && typeof obj == 'object' && !goog.isArray(obj) &&
+ !(jspb.Message.SUPPORTS_UINT8ARRAY_ && obj instanceof Uint8Array)) {
+ msg.pivot_ = foundIndex - msg.arrayIndexOffset_;
+ msg.extensionObject_ = obj;
+ return;
+ }
+ }
+ // This complexity exists because we keep all extension fields in the
+ // extensionObject_ regardless of proto field number. Changing this would
+ // simplify the code here, but it would require changing the serialization
+ // format from the server, which is not backwards compatible.
+ // TODO(jshneier): Should we just treat extension fields the same as
+ // non-extension fields, and select whether they appear in the object or in
+ // the array purely based on tag number? This would allow simplifying all the
+ // get/setExtension logic, but it would require the breaking change described
+ // above.
+ if (suggestedPivot > -1) {
+ msg.pivot_ = suggestedPivot;
+ var pivotIndex = jspb.Message.getIndex_(msg, suggestedPivot);
+ if (!jspb.Message.MINIMIZE_MEMORY_ALLOCATIONS) {
+ msg.extensionObject_ = msg.array[pivotIndex] = {};
+ } else {
+ // Initialize to null to avoid changing the shape of the proto when it
+ // gets eventually set.
+ msg.extensionObject_ = null;
+ }
+ } else {
+ msg.pivot_ = Number.MAX_VALUE;
+ }
+};
+
+
+/**
+ * Creates an empty extensionObject_ if non exists.
+ * @param {!jspb.Message} msg The JsPb proto to modify.
+ * @private
+ */
+jspb.Message.maybeInitEmptyExtensionObject_ = function(msg) {
+ var pivotIndex = jspb.Message.getIndex_(msg, msg.pivot_);
+ if (!msg.array[pivotIndex]) {
+ msg.extensionObject_ = msg.array[pivotIndex] = {};
+ }
+};
+
+
+/**
+ * Converts a JsPb repeated message field into an object list.
+ * @param {!Array<T>} field The repeated message field to be
+ * converted.
+ * @param {?function(boolean=): Object|
+ * function((boolean|undefined),T): Object} toObjectFn The toObject
+ * function for this field. We need to pass this for effective dead code
+ * removal.
+ * @param {boolean=} opt_includeInstance Whether to include the JSPB instance
+ * for transitional soy proto support: http://goto/soy-param-migration
+ * @return {!Array<Object>} An array of converted message objects.
+ * @template T
+ */
+jspb.Message.toObjectList = function(field, toObjectFn, opt_includeInstance) {
+ // Not using goog.array.map in the generated code to keep it small.
+ // And not using it here to avoid a function call.
+ var result = [];
+ for (var i = 0; i < field.length; i++) {
+ result[i] = toObjectFn.call(field[i], opt_includeInstance,
+ /** @type {!jspb.Message} */ (field[i]));
+ }
+ return result;
+};
+
+
+/**
+ * Adds a proto's extension data to a Soy rendering object.
+ * @param {!jspb.Message} proto The proto whose extensions to convert.
+ * @param {!Object} obj The Soy object to add converted extension data to.
+ * @param {!Object} extensions The proto class' registered extensions.
+ * @param {function(this:?, jspb.ExtensionFieldInfo) : *} getExtensionFn
+ * The proto class' getExtension function. Passed for effective dead code
+ * removal.
+ * @param {boolean=} opt_includeInstance Whether to include the JSPB instance
+ * for transitional soy proto support: http://goto/soy-param-migration
+ */
+jspb.Message.toObjectExtension = function(proto, obj, extensions,
+ getExtensionFn, opt_includeInstance) {
+ for (var fieldNumber in extensions) {
+ var fieldInfo = extensions[fieldNumber];
+ var value = getExtensionFn.call(proto, fieldInfo);
+ if (value) {
+ for (var name in fieldInfo.fieldName) {
+ if (fieldInfo.fieldName.hasOwnProperty(name)) {
+ break; // the compiled field name
+ }
+ }
+ if (!fieldInfo.toObjectFn) {
+ obj[name] = value;
+ } else {
+ if (fieldInfo.isRepeated) {
+ obj[name] = jspb.Message.toObjectList(
+ /** @type {!Array<jspb.Message>} */ (value),
+ fieldInfo.toObjectFn, opt_includeInstance);
+ } else {
+ obj[name] = fieldInfo.toObjectFn(opt_includeInstance, value);
+ }
+ }
+ }
+ }
+};
+
+
+/**
+ * Writes a proto's extension data to a binary-format output stream.
+ * @param {!jspb.Message} proto The proto whose extensions to convert.
+ * @param {*} writer The binary-format writer to write to.
+ * @param {!Object} extensions The proto class' registered extensions.
+ * @param {function(jspb.ExtensionFieldInfo) : *} getExtensionFn The proto
+ * class' getExtension function. Passed for effective dead code removal.
+ */
+jspb.Message.serializeBinaryExtensions = function(proto, writer, extensions,
+ getExtensionFn) {
+ for (var fieldNumber in extensions) {
+ var binaryFieldInfo = extensions[fieldNumber];
+ var fieldInfo = binaryFieldInfo.fieldInfo;
+
+ // The old codegen doesn't add the extra fields to ExtensionFieldInfo, so we
+ // need to gracefully error-out here rather than produce a null dereference
+ // below.
+ if (!binaryFieldInfo.binaryWriterFn) {
+ throw new Error('Message extension present that was generated ' +
+ 'without binary serialization support');
+ }
+ var value = getExtensionFn.call(proto, fieldInfo);
+ if (value) {
+ if (fieldInfo.isMessageType()) {
+ // If the message type of the extension was generated without binary
+ // support, there may not be a binary message serializer function, and
+ // we can't know when we codegen the extending message that the extended
+ // message may require binary support, so we can *only* catch this error
+ // here, at runtime (and this decoupled codegen is the whole point of
+ // extensions!).
+ if (binaryFieldInfo.binaryMessageSerializeFn) {
+ binaryFieldInfo.binaryWriterFn.call(writer, fieldInfo.fieldIndex,
+ value, binaryFieldInfo.binaryMessageSerializeFn);
+ } else {
+ throw new Error('Message extension present holding submessage ' +
+ 'without binary support enabled, and message is ' +
+ 'being serialized to binary format');
+ }
+ } else {
+ binaryFieldInfo.binaryWriterFn.call(
+ writer, fieldInfo.fieldIndex, value);
+ }
+ }
+ }
+};
+
+
+/**
+ * Reads an extension field from the given reader and, if a valid extension,
+ * sets the extension value.
+ * @param {!jspb.Message} msg A jspb proto.
+ * @param {{skipField:function(),getFieldNumber:function():number}} reader
+ * @param {!Object} extensions The extensions object.
+ * @param {function(jspb.ExtensionFieldInfo)} getExtensionFn
+ * @param {function(jspb.ExtensionFieldInfo, ?)} setExtensionFn
+ */
+jspb.Message.readBinaryExtension = function(msg, reader, extensions,
+ getExtensionFn, setExtensionFn) {
+ var binaryFieldInfo = extensions[reader.getFieldNumber()];
+ var fieldInfo = binaryFieldInfo.fieldInfo;
+ if (!binaryFieldInfo) {
+ reader.skipField();
+ return;
+ }
+ if (!binaryFieldInfo.binaryReaderFn) {
+ throw new Error('Deserializing extension whose generated code does not ' +
+ 'support binary format');
+ }
+
+ var value;
+ if (fieldInfo.isMessageType()) {
+ value = new fieldInfo.ctor();
+ binaryFieldInfo.binaryReaderFn.call(
+ reader, value, binaryFieldInfo.binaryMessageDeserializeFn);
+ } else {
+ // All other types.
+ value = binaryFieldInfo.binaryReaderFn.call(reader);
+ }
+
+ if (fieldInfo.isRepeated && !binaryFieldInfo.isPacked) {
+ var currentList = getExtensionFn.call(msg, fieldInfo);
+ if (!currentList) {
+ setExtensionFn.call(msg, fieldInfo, [value]);
+ } else {
+ currentList.push(value);
+ }
+ } else {
+ setExtensionFn.call(msg, fieldInfo, value);
+ }
+};
+
+
+/**
+ * Gets the value of a non-extension field.
+ * @param {!jspb.Message} msg A jspb proto.
+ * @param {number} fieldNumber The field number.
+ * @return {string|number|boolean|Uint8Array|Array|null|undefined}
+ * The field's value.
+ * @protected
+ */
+jspb.Message.getField = function(msg, fieldNumber) {
+ if (fieldNumber < msg.pivot_) {
+ var index = jspb.Message.getIndex_(msg, fieldNumber);
+ var val = msg.array[index];
+ if (val === jspb.Message.EMPTY_LIST_SENTINEL_) {
+ return msg.array[index] = [];
+ }
+ return val;
+ } else {
+ var val = msg.extensionObject_[fieldNumber];
+ if (val === jspb.Message.EMPTY_LIST_SENTINEL_) {
+ return msg.extensionObject_[fieldNumber] = [];
+ }
+ return val;
+ }
+};
+
+
+/**
+ * Gets the value of an optional float or double field.
+ * @param {!jspb.Message} msg A jspb proto.
+ * @param {number} fieldNumber The field number.
+ * @return {?number|undefined} The field's value.
+ * @protected
+ */
+jspb.Message.getOptionalFloatingPointField = function(msg, fieldNumber) {
+ var value = jspb.Message.getField(msg, fieldNumber);
+ // Converts "NaN", "Infinity" and "-Infinity" to their corresponding numbers.
+ return value == null ? value : +value;
+};
+
+
+/**
+ * Gets the value of a repeated float or double field.
+ * @param {!jspb.Message} msg A jspb proto.
+ * @param {number} fieldNumber The field number.
+ * @return {!Array<number>} The field's value.
+ * @protected
+ */
+jspb.Message.getRepeatedFloatingPointField = function(msg, fieldNumber) {
+ var values = jspb.Message.getField(msg, fieldNumber);
+ if (!msg.convertedFloatingPointFields_) {
+ msg.convertedFloatingPointFields_ = {};
+ }
+ if (!msg.convertedFloatingPointFields_[fieldNumber]) {
+ for (var i = 0; i < values.length; i++) {
+ // Converts "NaN", "Infinity" and "-Infinity" to their corresponding
+ // numbers.
+ values[i] = +values[i];
+ }
+ msg.convertedFloatingPointFields_[fieldNumber] = true;
+ }
+ return /** @type {!Array<number>} */ (values);
+};
+
+
+/**
+ * Coerce a 'bytes' field to a base 64 string.
+ * @param {string|Uint8Array|null} value
+ * @return {?string} The field's coerced value.
+ */
+jspb.Message.bytesAsB64 = function(value) {
+ if (value == null || goog.isString(value)) {
+ return value;
+ }
+ if (jspb.Message.SUPPORTS_UINT8ARRAY_ && value instanceof Uint8Array) {
+ return goog.crypt.base64.encodeByteArray(value);
+ }
+ goog.asserts.fail('Cannot coerce to b64 string: ' + goog.typeOf(value));
+ return null;
+};
+
+
+/**
+ * Coerce a 'bytes' field to a Uint8Array byte buffer.
+ * Note that Uint8Array is not supported on IE versions before 10 nor on Opera
+ * Mini. @see http://caniuse.com/Uint8Array
+ * @param {string|Uint8Array|null} value
+ * @return {?Uint8Array} The field's coerced value.
+ */
+jspb.Message.bytesAsU8 = function(value) {
+ if (value == null || value instanceof Uint8Array) {
+ return value;
+ }
+ if (goog.isString(value)) {
+ return goog.crypt.base64.decodeStringToUint8Array(value);
+ }
+ goog.asserts.fail('Cannot coerce to Uint8Array: ' + goog.typeOf(value));
+ return null;
+};
+
+
+/**
+ * Coerce a repeated 'bytes' field to an array of base 64 strings.
+ * Note: the returned array should be treated as immutable.
+ * @param {!Array<string>|!Array<!Uint8Array>} value
+ * @return {!Array<string?>} The field's coerced value.
+ */
+jspb.Message.bytesListAsB64 = function(value) {
+ jspb.Message.assertConsistentTypes_(value);
+ if (!value.length || goog.isString(value[0])) {
+ return /** @type {!Array<string>} */ (value);
+ }
+ return goog.array.map(value, jspb.Message.bytesAsB64);
+};
+
+
+/**
+ * Coerce a repeated 'bytes' field to an array of Uint8Array byte buffers.
+ * Note: the returned array should be treated as immutable.
+ * Note that Uint8Array is not supported on IE versions before 10 nor on Opera
+ * Mini. @see http://caniuse.com/Uint8Array
+ * @param {!Array<string>|!Array<!Uint8Array>} value
+ * @return {!Array<Uint8Array?>} The field's coerced value.
+ */
+jspb.Message.bytesListAsU8 = function(value) {
+ jspb.Message.assertConsistentTypes_(value);
+ if (!value.length || value[0] instanceof Uint8Array) {
+ return /** @type {!Array<!Uint8Array>} */ (value);
+ }
+ return goog.array.map(value, jspb.Message.bytesAsU8);
+};
+
+
+/**
+ * Asserts that all elements of an array are of the same type.
+ * @param {Array?} array The array to test.
+ * @private
+ */
+jspb.Message.assertConsistentTypes_ = function(array) {
+ if (goog.DEBUG && array && array.length > 1) {
+ var expected = goog.typeOf(array[0]);
+ goog.array.forEach(array, function(e) {
+ if (goog.typeOf(e) != expected) {
+ goog.asserts.fail('Inconsistent type in JSPB repeated field array. ' +
+ 'Got ' + goog.typeOf(e) + ' expected ' + expected);
+ }
+ });
+ }
+};
+
+
+/**
+ * Gets the value of a non-extension primitive field, with proto3 (non-nullable
+ * primitives) semantics. Returns `defaultValue` if the field is not otherwise
+ * set.
+ * @template T
+ * @param {!jspb.Message} msg A jspb proto.
+ * @param {number} fieldNumber The field number.
+ * @param {T} defaultValue The default value.
+ * @return {T} The field's value.
+ * @protected
+ */
+jspb.Message.getFieldProto3 = function(msg, fieldNumber, defaultValue) {
+ var value = jspb.Message.getField(msg, fieldNumber);
+ if (value == null) {
+ return defaultValue;
+ } else {
+ return value;
+ }
+};
+
+
+/**
+ * Gets the value of a map field, lazily creating the map container if
+ * necessary.
+ *
+ * This should only be called from generated code, because it requires knowledge
+ * of serialization/parsing callbacks (which are required by the map at
+ * construction time, and the map may be constructed here).
+ *
+ * @template K, V
+ * @param {!jspb.Message} msg
+ * @param {number} fieldNumber
+ * @param {boolean|undefined} noLazyCreate
+ * @param {?=} opt_valueCtor
+ * @return {!jspb.Map<K, V>|undefined}
+ * @protected
+ */
+jspb.Message.getMapField = function(msg, fieldNumber, noLazyCreate,
+ opt_valueCtor) {
+ if (!msg.wrappers_) {
+ msg.wrappers_ = {};
+ }
+ // If we already have a map in the map wrappers, return that.
+ if (fieldNumber in msg.wrappers_) {
+ return msg.wrappers_[fieldNumber];
+ } else if (noLazyCreate) {
+ return undefined;
+ } else {
+ // Wrap the underlying elements array with a Map.
+ var arr = jspb.Message.getField(msg, fieldNumber);
+ if (!arr) {
+ arr = [];
+ jspb.Message.setField(msg, fieldNumber, arr);
+ }
+ return msg.wrappers_[fieldNumber] =
+ new jspb.Map(
+ /** @type {!Array<!Array<!Object>>} */ (arr), opt_valueCtor);
+ }
+};
+
+
+/**
+ * Sets the value of a non-extension field.
+ * @param {!jspb.Message} msg A jspb proto.
+ * @param {number} fieldNumber The field number.
+ * @param {string|number|boolean|Uint8Array|Array|undefined} value New value
+ * @protected
+ */
+jspb.Message.setField = function(msg, fieldNumber, value) {
+ if (fieldNumber < msg.pivot_) {
+ msg.array[jspb.Message.getIndex_(msg, fieldNumber)] = value;
+ } else {
+ msg.extensionObject_[fieldNumber] = value;
+ }
+};
+
+
+/**
+ * Sets the value of a field in a oneof union and clears all other fields in
+ * the union.
+ * @param {!jspb.Message} msg A jspb proto.
+ * @param {number} fieldNumber The field number.
+ * @param {!Array<number>} oneof The fields belonging to the union.
+ * @param {string|number|boolean|Uint8Array|Array|undefined} value New value
+ * @protected
+ */
+jspb.Message.setOneofField = function(msg, fieldNumber, oneof, value) {
+ var currentCase = jspb.Message.computeOneofCase(msg, oneof);
+ if (currentCase && currentCase !== fieldNumber && value !== undefined) {
+ if (msg.wrappers_ && currentCase in msg.wrappers_) {
+ msg.wrappers_[currentCase] = undefined;
+ }
+ jspb.Message.setField(msg, currentCase, undefined);
+ }
+ jspb.Message.setField(msg, fieldNumber, value);
+};
+
+
+/**
+ * Computes the selection in a oneof group for the given message, ensuring
+ * only one field is set in the process.
+ *
+ * According to the protobuf language guide (
+ * https://developers.google.com/protocol-buffers/docs/proto#oneof), "if the
+ * parser encounters multiple members of the same oneof on the wire, only the
+ * last member seen is used in the parsed message." Since JSPB serializes
+ * messages to a JSON array, the "last member seen" will always be the field
+ * with the greatest field number (directly corresponding to the greatest
+ * array index).
+ *
+ * @param {!jspb.Message} msg A jspb proto.
+ * @param {!Array<number>} oneof The field numbers belonging to the union.
+ * @return {number} The field number currently set in the union, or 0 if none.
+ * @protected
+ */
+jspb.Message.computeOneofCase = function(msg, oneof) {
+ var oneofField;
+ var oneofValue;
+
+ goog.array.forEach(oneof, function(fieldNumber) {
+ var value = jspb.Message.getField(msg, fieldNumber);
+ if (goog.isDefAndNotNull(value)) {
+ oneofField = fieldNumber;
+ oneofValue = value;
+ jspb.Message.setField(msg, fieldNumber, undefined);
+ }
+ });
+
+ if (oneofField) {
+ // NB: We know the value is unique, so we can call jspb.Message.setField
+ // directly instead of jpsb.Message.setOneofField. Also, setOneofField
+ // calls this function.
+ jspb.Message.setField(msg, oneofField, oneofValue);
+ return oneofField;
+ }
+
+ return 0;
+};
+
+
+/**
+ * Gets and wraps a proto field on access.
+ * @param {!jspb.Message} msg A jspb proto.
+ * @param {function(new:jspb.Message, Array)} ctor Constructor for the field.
+ * @param {number} fieldNumber The field number.
+ * @param {number=} opt_required True (1) if this is a required field.
+ * @return {jspb.Message} The field as a jspb proto.
+ * @protected
+ */
+jspb.Message.getWrapperField = function(msg, ctor, fieldNumber, opt_required) {
+ // TODO(mwr): Consider copying data and/or arrays.
+ if (!msg.wrappers_) {
+ msg.wrappers_ = {};
+ }
+ if (!msg.wrappers_[fieldNumber]) {
+ var data = /** @type {Array} */ (jspb.Message.getField(msg, fieldNumber));
+ if (opt_required || data) {
+ // TODO(mwr): Remove existence test for always valid default protos.
+ msg.wrappers_[fieldNumber] = new ctor(data);
+ }
+ }
+ return /** @type {jspb.Message} */ (msg.wrappers_[fieldNumber]);
+};
+
+
+/**
+ * Gets and wraps a repeated proto field on access.
+ * @param {!jspb.Message} msg A jspb proto.
+ * @param {function(new:jspb.Message, Array)} ctor Constructor for the field.
+ * @param {number} fieldNumber The field number.
+ * @return {Array<!jspb.Message>} The repeated field as an array of protos.
+ * @protected
+ */
+jspb.Message.getRepeatedWrapperField = function(msg, ctor, fieldNumber) {
+ if (!msg.wrappers_) {
+ msg.wrappers_ = {};
+ }
+ if (!msg.wrappers_[fieldNumber]) {
+ var data = jspb.Message.getField(msg, fieldNumber);
+ for (var wrappers = [], i = 0; i < data.length; i++) {
+ wrappers[i] = new ctor(data[i]);
+ }
+ msg.wrappers_[fieldNumber] = wrappers;
+ }
+ var val = msg.wrappers_[fieldNumber];
+ if (val == jspb.Message.EMPTY_LIST_SENTINEL_) {
+ val = msg.wrappers_[fieldNumber] = [];
+ }
+ return /** @type {Array<!jspb.Message>} */ (val);
+};
+
+
+/**
+ * Sets a proto field and syncs it to the backing array.
+ * @param {!jspb.Message} msg A jspb proto.
+ * @param {number} fieldNumber The field number.
+ * @param {jspb.Message|undefined} value A new value for this proto field.
+ * @protected
+ */
+jspb.Message.setWrapperField = function(msg, fieldNumber, value) {
+ if (!msg.wrappers_) {
+ msg.wrappers_ = {};
+ }
+ var data = value ? value.toArray() : value;
+ msg.wrappers_[fieldNumber] = value;
+ jspb.Message.setField(msg, fieldNumber, data);
+};
+
+
+/**
+ * Sets a proto field in a oneof union and syncs it to the backing array.
+ * @param {!jspb.Message} msg A jspb proto.
+ * @param {number} fieldNumber The field number.
+ * @param {!Array<number>} oneof The fields belonging to the union.
+ * @param {jspb.Message|undefined} value A new value for this proto field.
+ * @protected
+ */
+jspb.Message.setOneofWrapperField = function(msg, fieldNumber, oneof, value) {
+ if (!msg.wrappers_) {
+ msg.wrappers_ = {};
+ }
+ var data = value ? value.toArray() : value;
+ msg.wrappers_[fieldNumber] = value;
+ jspb.Message.setOneofField(msg, fieldNumber, oneof, data);
+};
+
+
+/**
+ * Sets a repeated proto field and syncs it to the backing array.
+ * @param {!jspb.Message} msg A jspb proto.
+ * @param {number} fieldNumber The field number.
+ * @param {Array<!jspb.Message>|undefined} value An array of protos.
+ * @protected
+ */
+jspb.Message.setRepeatedWrapperField = function(msg, fieldNumber, value) {
+ if (!msg.wrappers_) {
+ msg.wrappers_ = {};
+ }
+ value = value || [];
+ for (var data = [], i = 0; i < value.length; i++) {
+ data[i] = value[i].toArray();
+ }
+ msg.wrappers_[fieldNumber] = value;
+ jspb.Message.setField(msg, fieldNumber, data);
+};
+
+
+/**
+ * Converts a JsPb repeated message field into a map. The map will contain
+ * protos unless an optional toObject function is given, in which case it will
+ * contain objects suitable for Soy rendering.
+ * @param {!Array<T>} field The repeated message field to be
+ * converted.
+ * @param {function() : string?} mapKeyGetterFn The function to get the key of
+ * the map.
+ * @param {?function(boolean=): Object|
+ * function((boolean|undefined),T): Object} opt_toObjectFn The
+ * toObject function for this field. We need to pass this for effective
+ * dead code removal.
+ * @param {boolean=} opt_includeInstance Whether to include the JSPB instance
+ * for transitional soy proto support: http://goto/soy-param-migration
+ * @return {!Object.<string, Object>} A map of proto or Soy objects.
+ * @template T
+ */
+jspb.Message.toMap = function(
+ field, mapKeyGetterFn, opt_toObjectFn, opt_includeInstance) {
+ var result = {};
+ for (var i = 0; i < field.length; i++) {
+ result[mapKeyGetterFn.call(field[i])] = opt_toObjectFn ?
+ opt_toObjectFn.call(field[i], opt_includeInstance,
+ /** @type {!jspb.Message} */ (field[i])) : field[i];
+ }
+ return result;
+};
+
+
+/**
+ * Syncs all map fields' contents back to their underlying arrays.
+ * @private
+ */
+jspb.Message.prototype.syncMapFields_ = function() {
+ // This iterates over submessage, map, and repeated fields, which is intended.
+ // Submessages can contain maps which also need to be synced.
+ //
+ // There is a lot of opportunity for optimization here. For example we could
+ // statically determine that some messages have no submessages with maps and
+ // optimize this method away for those just by generating one extra static
+ // boolean per message type.
+ if (this.wrappers_) {
+ for (var fieldNumber in this.wrappers_) {
+ var val = this.wrappers_[fieldNumber];
+ if (goog.isArray(val)) {
+ for (var i = 0; i < val.length; i++) {
+ if (val[i]) {
+ val[i].toArray();
+ }
+ }
+ } else {
+ // Works for submessages and maps.
+ if (val) {
+ val.toArray();
+ }
+ }
+ }
+ }
+};
+
+
+/**
+ * Returns the internal array of this proto.
+ * <p>Note: If you use this array to construct a second proto, the content
+ * would then be partially shared between the two protos.
+ * @return {!Array} The proto represented as an array.
+ */
+jspb.Message.prototype.toArray = function() {
+ this.syncMapFields_();
+ return this.array;
+};
+
+
+
+
+/**
+ * Creates a string representation of the internal data array of this proto.
+ * <p>NOTE: This string is *not* suitable for use in server requests.
+ * @return {string} A string representation of this proto.
+ * @override
+ */
+jspb.Message.prototype.toString = function() {
+ this.syncMapFields_();
+ return this.array.toString();
+};
+
+
+/**
+ * Gets the value of the extension field from the extended object.
+ * @param {jspb.ExtensionFieldInfo.<T>} fieldInfo Specifies the field to get.
+ * @return {T} The value of the field.
+ * @template T
+ */
+jspb.Message.prototype.getExtension = function(fieldInfo) {
+ if (!this.extensionObject_) {
+ return undefined;
+ }
+ if (!this.wrappers_) {
+ this.wrappers_ = {};
+ }
+ var fieldNumber = fieldInfo.fieldIndex;
+ if (fieldInfo.isRepeated) {
+ if (fieldInfo.isMessageType()) {
+ if (!this.wrappers_[fieldNumber]) {
+ this.wrappers_[fieldNumber] =
+ goog.array.map(this.extensionObject_[fieldNumber] || [],
+ function(arr) {
+ return new fieldInfo.ctor(arr);
+ });
+ }
+ return this.wrappers_[fieldNumber];
+ } else {
+ return this.extensionObject_[fieldNumber];
+ }
+ } else {
+ if (fieldInfo.isMessageType()) {
+ if (!this.wrappers_[fieldNumber] && this.extensionObject_[fieldNumber]) {
+ this.wrappers_[fieldNumber] = new fieldInfo.ctor(
+ /** @type {Array|undefined} */ (
+ this.extensionObject_[fieldNumber]));
+ }
+ return this.wrappers_[fieldNumber];
+ } else {
+ return this.extensionObject_[fieldNumber];
+ }
+ }
+};
+
+
+/**
+ * Sets the value of the extension field in the extended object.
+ * @param {jspb.ExtensionFieldInfo} fieldInfo Specifies the field to set.
+ * @param {jspb.Message|string|Uint8Array|number|boolean|Array?} value The value
+ * to set.
+ */
+jspb.Message.prototype.setExtension = function(fieldInfo, value) {
+ if (!this.wrappers_) {
+ this.wrappers_ = {};
+ }
+ jspb.Message.maybeInitEmptyExtensionObject_(this);
+ var fieldNumber = fieldInfo.fieldIndex;
+ if (fieldInfo.isRepeated) {
+ value = value || [];
+ if (fieldInfo.isMessageType()) {
+ this.wrappers_[fieldNumber] = value;
+ this.extensionObject_[fieldNumber] = goog.array.map(
+ /** @type {Array<jspb.Message>} */ (value), function(msg) {
+ return msg.toArray();
+ });
+ } else {
+ this.extensionObject_[fieldNumber] = value;
+ }
+ } else {
+ if (fieldInfo.isMessageType()) {
+ this.wrappers_[fieldNumber] = value;
+ this.extensionObject_[fieldNumber] = value ? value.toArray() : value;
+ } else {
+ this.extensionObject_[fieldNumber] = value;
+ }
+ }
+};
+
+
+/**
+ * Creates a difference object between two messages.
+ *
+ * The result will contain the top-level fields of m2 that differ from those of
+ * m1 at any level of nesting. No data is cloned, the result object will
+ * share its top-level elements with m2 (but not with m1).
+ *
+ * Note that repeated fields should not have null/undefined elements, but if
+ * they do, this operation will treat repeated fields of different length as
+ * the same if the only difference between them is due to trailing
+ * null/undefined values.
+ *
+ * @param {!jspb.Message} m1 The first message object.
+ * @param {!jspb.Message} m2 The second message object.
+ * @return {!jspb.Message} The difference returned as a proto message.
+ * Note that the returned message may be missing required fields. This is
+ * currently tolerated in Js, but would cause an error if you tried to
+ * send such a proto to the server. You can access the raw difference
+ * array with result.toArray().
+ * @throws {Error} If the messages are responses with different types.
+ */
+jspb.Message.difference = function(m1, m2) {
+ if (!(m1 instanceof m2.constructor)) {
+ throw new Error('Messages have different types.');
+ }
+ var arr1 = m1.toArray();
+ var arr2 = m2.toArray();
+ var res = [];
+ var start = 0;
+ var length = arr1.length > arr2.length ? arr1.length : arr2.length;
+ if (m1.getJsPbMessageId()) {
+ res[0] = m1.getJsPbMessageId();
+ start = 1;
+ }
+ for (var i = start; i < length; i++) {
+ if (!jspb.Message.compareFields(arr1[i], arr2[i])) {
+ res[i] = arr2[i];
+ }
+ }
+ return new m1.constructor(res);
+};
+
+
+/**
+ * Tests whether two messages are equal.
+ * @param {jspb.Message|undefined} m1 The first message object.
+ * @param {jspb.Message|undefined} m2 The second message object.
+ * @return {boolean} true if both messages are null/undefined, or if both are
+ * of the same type and have the same field values.
+ */
+jspb.Message.equals = function(m1, m2) {
+ return m1 == m2 || (!!(m1 && m2) && (m1 instanceof m2.constructor) &&
+ jspb.Message.compareFields(m1.toArray(), m2.toArray()));
+};
+
+
+/**
+ * Compares two message extension fields recursively.
+ * @param {!Object} extension1 The first field.
+ * @param {!Object} extension2 The second field.
+ * @return {boolean} true if the extensions are null/undefined, or otherwise
+ * equal.
+ */
+jspb.Message.compareExtensions = function(extension1, extension2) {
+ extension1 = extension1 || {};
+ extension2 = extension2 || {};
+
+ var keys = {};
+ for (var name in extension1) {
+ keys[name] = 0;
+ }
+ for (var name in extension2) {
+ keys[name] = 0;
+ }
+ for (name in keys) {
+ if (!jspb.Message.compareFields(extension1[name], extension2[name])) {
+ return false;
+ }
+ }
+ return true;
+};
+
+
+/**
+ * Compares two message fields recursively.
+ * @param {*} field1 The first field.
+ * @param {*} field2 The second field.
+ * @return {boolean} true if the fields are null/undefined, or otherwise equal.
+ */
+jspb.Message.compareFields = function(field1, field2) {
+ // If the fields are trivially equal, they're equal.
+ if (field1 == field2) return true;
+
+ // If the fields aren't trivially equal and one of them isn't an object,
+ // they can't possibly be equal.
+ if (!goog.isObject(field1) || !goog.isObject(field2)) {
+ return false;
+ }
+
+ // We have two objects. If they're different types, they're not equal.
+ field1 = /** @type {!Object} */(field1);
+ field2 = /** @type {!Object} */(field2);
+ if (field1.constructor != field2.constructor) return false;
+
+ // If both are Uint8Arrays, compare them element-by-element.
+ if (jspb.Message.SUPPORTS_UINT8ARRAY_ && field1.constructor === Uint8Array) {
+ var bytes1 = /** @type {!Uint8Array} */(field1);
+ var bytes2 = /** @type {!Uint8Array} */(field2);
+ if (bytes1.length != bytes2.length) return false;
+ for (var i = 0; i < bytes1.length; i++) {
+ if (bytes1[i] != bytes2[i]) return false;
+ }
+ return true;
+ }
+
+ // If they're both Arrays, compare them element by element except for the
+ // optional extension objects at the end, which we compare separately.
+ if (field1.constructor === Array) {
+ var extension1 = undefined;
+ var extension2 = undefined;
+
+ var length = Math.max(field1.length, field2.length);
+ for (var i = 0; i < length; i++) {
+ var val1 = field1[i];
+ var val2 = field2[i];
+
+ if (val1 && (val1.constructor == Object)) {
+ goog.asserts.assert(extension1 === undefined);
+ goog.asserts.assert(i === field1.length - 1);
+ extension1 = val1;
+ val1 = undefined;
+ }
+
+ if (val2 && (val2.constructor == Object)) {
+ goog.asserts.assert(extension2 === undefined);
+ goog.asserts.assert(i === field2.length - 1);
+ extension2 = val2;
+ val2 = undefined;
+ }
+
+ if (!jspb.Message.compareFields(val1, val2)) {
+ return false;
+ }
+ }
+
+ if (extension1 || extension2) {
+ extension1 = extension1 || {};
+ extension2 = extension2 || {};
+ return jspb.Message.compareExtensions(extension1, extension2);
+ }
+
+ return true;
+ }
+
+ // If they're both plain Objects (i.e. extensions), compare them as
+ // extensions.
+ if (field1.constructor === Object) {
+ return jspb.Message.compareExtensions(field1, field2);
+ }
+
+ throw new Error('Invalid type in JSPB array');
+};
+
+
+/**
+ * Static clone function. NOTE: A type-safe method called "cloneMessage" exists
+ * on each generated JsPb class. Do not call this function directly.
+ * @param {!jspb.Message} msg A message to clone.
+ * @return {!jspb.Message} A deep clone of the given message.
+ */
+jspb.Message.clone = function(msg) {
+ // Although we could include the wrappers, we leave them out here.
+ return jspb.Message.cloneMessage(msg);
+};
+
+
+/**
+ * @param {!jspb.Message} msg A message to clone.
+ * @return {!jspb.Message} A deep clone of the given message.
+ * @protected
+ */
+jspb.Message.cloneMessage = function(msg) {
+ // Although we could include the wrappers, we leave them out here.
+ return new msg.constructor(jspb.Message.clone_(msg.toArray()));
+};
+
+
+/**
+ * Takes 2 messages of the same type and copies the contents of the first
+ * message into the second. After this the 2 messages will equals in terms of
+ * value semantics but share no state. All data in the destination message will
+ * be overridden.
+ *
+ * @param {MESSAGE} fromMessage Message that will be copied into toMessage.
+ * @param {MESSAGE} toMessage Message which will receive a copy of fromMessage
+ * as its contents.
+ * @template MESSAGE
+ */
+jspb.Message.copyInto = function(fromMessage, toMessage) {
+ goog.asserts.assertInstanceof(fromMessage, jspb.Message);
+ goog.asserts.assertInstanceof(toMessage, jspb.Message);
+ goog.asserts.assert(fromMessage.constructor == toMessage.constructor,
+ 'Copy source and target message should have the same type.');
+ var copyOfFrom = jspb.Message.clone(fromMessage);
+
+ var to = toMessage.toArray();
+ var from = copyOfFrom.toArray();
+
+ // Empty destination in case it has more values at the end of the array.
+ to.length = 0;
+ // and then copy everything from the new to the existing message.
+ for (var i = 0; i < from.length; i++) {
+ to[i] = from[i];
+ }
+
+ // This is either null or empty for a fresh copy.
+ toMessage.wrappers_ = copyOfFrom.wrappers_;
+ // Just a reference into the shared array.
+ toMessage.extensionObject_ = copyOfFrom.extensionObject_;
+};
+
+
+/**
+ * Helper for cloning an internal JsPb object.
+ * @param {!Object} obj A JsPb object, eg, a field, to be cloned.
+ * @return {!Object} A clone of the input object.
+ * @private
+ */
+jspb.Message.clone_ = function(obj) {
+ var o;
+ if (goog.isArray(obj)) {
+ // Allocate array of correct size.
+ var clonedArray = new Array(obj.length);
+ // Use array iteration where possible because it is faster than for-in.
+ for (var i = 0; i < obj.length; i++) {
+ if ((o = obj[i]) != null) {
+ clonedArray[i] = typeof o == 'object' ? jspb.Message.clone_(o) : o;
+ }
+ }
+ return clonedArray;
+ }
+ if (jspb.Message.SUPPORTS_UINT8ARRAY_ && obj instanceof Uint8Array) {
+ return new Uint8Array(obj);
+ }
+ var clone = {};
+ for (var key in obj) {
+ if ((o = obj[key]) != null) {
+ clone[key] = typeof o == 'object' ? jspb.Message.clone_(o) : o;
+ }
+ }
+ return clone;
+};
+
+
+/**
+ * Registers a JsPb message type id with its constructor.
+ * @param {string} id The id for this type of message.
+ * @param {Function} constructor The message constructor.
+ */
+jspb.Message.registerMessageType = function(id, constructor) {
+ jspb.Message.registry_[id] = constructor;
+ // This is needed so we can later access messageId directly on the contructor,
+ // otherwise it is not available due to 'property collapsing' by the compiler.
+ constructor.messageId = id;
+};
+
+
+/**
+ * The registry of message ids to message constructors.
+ * @private
+ */
+jspb.Message.registry_ = {};
+
+
+/**
+ * The extensions registered on MessageSet. This is a map of extension
+ * field number to field info object. This should be considered as a
+ * private API.
+ *
+ * This is similar to [jspb class name].extensions object for
+ * non-MessageSet. We special case MessageSet so that we do not need
+ * to goog.require MessageSet from classes that extends MessageSet.
+ *
+ * @type {!Object.<number, jspb.ExtensionFieldInfo>}
+ */
+jspb.Message.messageSetExtensions = {};
diff --git a/js/message_test.js b/js/message_test.js
new file mode 100644
index 00000000..b7791431
--- /dev/null
+++ b/js/message_test.js
@@ -0,0 +1,1080 @@
+// 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.
+
+// Test suite is written using Jasmine -- see http://jasmine.github.io/
+
+goog.setTestOnly();
+
+goog.require('goog.json');
+goog.require('goog.testing.asserts');
+goog.require('goog.userAgent');
+
+// CommonJS-LoadFromFile: google-protobuf jspb
+goog.require('jspb.Message');
+
+// CommonJS-LoadFromFile: test5_pb proto.jspb.exttest.beta
+goog.require('proto.jspb.exttest.beta.floatingStrField');
+
+// CommonJS-LoadFromFile: test3_pb proto.jspb.exttest
+goog.require('proto.jspb.exttest.floatingMsgField');
+
+// CommonJS-LoadFromFile: test4_pb proto.jspb.exttest
+goog.require('proto.jspb.exttest.floatingMsgFieldTwo');
+
+// CommonJS-LoadFromFile: test_pb proto.jspb.test
+goog.require('proto.jspb.test.CloneExtension');
+goog.require('proto.jspb.test.Complex');
+goog.require('proto.jspb.test.DefaultValues');
+goog.require('proto.jspb.test.Empty');
+goog.require('proto.jspb.test.EnumContainer');
+goog.require('proto.jspb.test.floatingMsgField');
+goog.require('proto.jspb.test.FloatingPointFields');
+goog.require('proto.jspb.test.floatingStrField');
+goog.require('proto.jspb.test.HasExtensions');
+goog.require('proto.jspb.test.IndirectExtension');
+goog.require('proto.jspb.test.IsExtension');
+goog.require('proto.jspb.test.OptionalFields');
+goog.require('proto.jspb.test.OuterEnum');
+goog.require('proto.jspb.test.OuterMessage.Complex');
+goog.require('proto.jspb.test.Simple1');
+goog.require('proto.jspb.test.Simple2');
+goog.require('proto.jspb.test.SpecialCases');
+goog.require('proto.jspb.test.TestClone');
+goog.require('proto.jspb.test.TestEndsWithBytes');
+goog.require('proto.jspb.test.TestGroup');
+goog.require('proto.jspb.test.TestGroup1');
+goog.require('proto.jspb.test.TestMessageWithOneof');
+goog.require('proto.jspb.test.TestReservedNames');
+goog.require('proto.jspb.test.TestReservedNamesExtension');
+
+// CommonJS-LoadFromFile: test2_pb proto.jspb.test
+goog.require('proto.jspb.test.ExtensionMessage');
+goog.require('proto.jspb.test.TestExtensionsMessage');
+
+
+
+
+describe('Message test suite', function() {
+ it('testEmptyProto', function() {
+ var empty1 = new proto.jspb.test.Empty([]);
+ var empty2 = new proto.jspb.test.Empty([]);
+ assertObjectEquals({}, empty1.toObject());
+ assertObjectEquals('Message should not be corrupted:', empty2, empty1);
+ });
+
+ it('testTopLevelEnum', function() {
+ var response = new proto.jspb.test.EnumContainer([]);
+ response.setOuterEnum(proto.jspb.test.OuterEnum.FOO);
+ assertEquals(proto.jspb.test.OuterEnum.FOO, response.getOuterEnum());
+ });
+
+ it('testByteStrings', function() {
+ var data = new proto.jspb.test.DefaultValues([]);
+ data.setBytesField('some_bytes');
+ assertEquals('some_bytes', data.getBytesField());
+ });
+
+ it('testComplexConversion', function() {
+ var data1 = ['a',,, [, 11], [[, 22], [, 33]],, ['s1', 's2'],, 1];
+ var data2 = ['a',,, [, 11], [[, 22], [, 33]],, ['s1', 's2'],, 1];
+ var foo = new proto.jspb.test.Complex(data1);
+ var bar = new proto.jspb.test.Complex(data2);
+ var result = foo.toObject();
+ assertObjectEquals({
+ aString: 'a',
+ anOutOfOrderBool: 1,
+ aNestedMessage: {
+ anInt: 11
+ },
+ aRepeatedMessageList: [{anInt: 22}, {anInt: 33}],
+ aRepeatedStringList: ['s1', 's2']
+ }, result);
+
+ // Now test with the jspb instances included.
+ result = foo.toObject(true /* opt_includeInstance */);
+ assertObjectEquals({
+ aString: 'a',
+ anOutOfOrderBool: 1,
+ aNestedMessage: {
+ anInt: 11,
+ $jspbMessageInstance: foo.getANestedMessage()
+ },
+ aRepeatedMessageList: [
+ {anInt: 22, $jspbMessageInstance: foo.getARepeatedMessageList()[0]},
+ {anInt: 33, $jspbMessageInstance: foo.getARepeatedMessageList()[1]}
+ ],
+ aRepeatedStringList: ['s1', 's2'],
+ $jspbMessageInstance: foo
+ }, result);
+
+ });
+
+ it('testMissingFields', function() {
+ var foo = new proto.jspb.test.Complex([
+ undefined, undefined, undefined, [],
+ undefined, undefined, undefined, undefined]);
+ var bar = new proto.jspb.test.Complex([
+ undefined, undefined, undefined, [],
+ undefined, undefined, undefined, undefined]);
+ var result = foo.toObject();
+ assertObjectEquals({
+ aString: undefined,
+ anOutOfOrderBool: undefined,
+ aNestedMessage: {
+ anInt: undefined
+ },
+ // Note: JsPb converts undefined repeated fields to empty arrays.
+ aRepeatedMessageList: [],
+ aRepeatedStringList: []
+ }, result);
+
+ });
+
+ it('testNestedComplexMessage', function() {
+ // Instantiate the message and set a unique field, just to ensure that we
+ // are not getting jspb.test.Complex instead.
+ var msg = new proto.jspb.test.OuterMessage.Complex();
+ msg.setInnerComplexField(5);
+ });
+
+ it('testSpecialCases', function() {
+ // Note: Some property names are reserved in JavaScript.
+ // These names are converted to the Js property named pb_<reserved_name>.
+ var special =
+ new proto.jspb.test.SpecialCases(['normal', 'default', 'function',
+ 'var']);
+ var result = special.toObject();
+ assertObjectEquals({
+ normal: 'normal',
+ pb_default: 'default',
+ pb_function: 'function',
+ pb_var: 'var'
+ }, result);
+ });
+
+ it('testDefaultValues', function() {
+ var defaultString = "default<>\'\"abc";
+ var response = new proto.jspb.test.DefaultValues();
+
+ // Test toObject
+ var expectedObject = {
+ stringField: defaultString,
+ boolField: true,
+ intField: 11,
+ enumField: 13,
+ emptyField: '',
+ bytesField: 'bW9v'
+ };
+ assertObjectEquals(expectedObject, response.toObject());
+
+
+ // Test getters
+ response = new proto.jspb.test.DefaultValues();
+ assertEquals(defaultString, response.getStringField());
+ assertEquals(true, response.getBoolField());
+ assertEquals(11, response.getIntField());
+ assertEquals(13, response.getEnumField());
+ assertEquals('', response.getEmptyField());
+ assertEquals('bW9v', response.getBytesField());
+
+ function makeDefault(values) {
+ return new proto.jspb.test.DefaultValues(values);
+ }
+
+ // Test with undefined values,
+ // Use push to workaround IE treating undefined array elements as holes.
+ response = makeDefault([undefined, undefined, undefined, undefined]);
+ assertEquals(defaultString, response.getStringField());
+ assertEquals(true, response.getBoolField());
+ assertEquals(11, response.getIntField());
+ assertEquals(13, response.getEnumField());
+ assertFalse(response.hasStringField());
+ assertFalse(response.hasBoolField());
+ assertFalse(response.hasIntField());
+ assertFalse(response.hasEnumField());
+
+ // Test with null values, as would be returned by a JSON serializer.
+ response = makeDefault([null, null, null, null]);
+ assertEquals(defaultString, response.getStringField());
+ assertEquals(true, response.getBoolField());
+ assertEquals(11, response.getIntField());
+ assertEquals(13, response.getEnumField());
+ assertFalse(response.hasStringField());
+ assertFalse(response.hasBoolField());
+ assertFalse(response.hasIntField());
+ assertFalse(response.hasEnumField());
+
+ // Test with false-like values.
+ response = makeDefault(['', false, 0, 0]);
+ assertEquals('', response.getStringField());
+ assertEquals(false, response.getBoolField());
+ assertEquals(true, response.getIntField() == 0);
+ assertEquals(true, response.getEnumField() == 0);
+ assertTrue(response.hasStringField());
+ assertTrue(response.hasBoolField());
+ assertTrue(response.hasIntField());
+ assertTrue(response.hasEnumField());
+
+ // Test that clearing the values reverts them to the default state.
+ response = makeDefault(['blah', false, 111, 77]);
+ response.clearStringField(); response.clearBoolField();
+ response.clearIntField(); response.clearEnumField();
+ assertEquals(defaultString, response.getStringField());
+ assertEquals(true, response.getBoolField());
+ assertEquals(11, response.getIntField());
+ assertEquals(13, response.getEnumField());
+ assertFalse(response.hasStringField());
+ assertFalse(response.hasBoolField());
+ assertFalse(response.hasIntField());
+ assertFalse(response.hasEnumField());
+
+ // Test that setFoo(null) clears the values.
+ response = makeDefault(['blah', false, 111, 77]);
+ response.setStringField(null); response.setBoolField(null);
+ response.setIntField(undefined); response.setEnumField(undefined);
+ assertEquals(defaultString, response.getStringField());
+ assertEquals(true, response.getBoolField());
+ assertEquals(11, response.getIntField());
+ assertEquals(13, response.getEnumField());
+ assertFalse(response.hasStringField());
+ assertFalse(response.hasBoolField());
+ assertFalse(response.hasIntField());
+ assertFalse(response.hasEnumField());
+ });
+
+ it('testMessageRegistration', function() {
+ // goog.require(SomeResponse) will include its library, which will in
+ // turn add SomeResponse to the message registry.
+ assertEquals(jspb.Message.registry_['res'], proto.jspb.test.SomeResponse);
+ });
+
+ it('testClearFields', function() {
+ var data = ['str', true, [11], [[22], [33]], ['s1', 's2']];
+ var foo = new proto.jspb.test.OptionalFields(data);
+ foo.clearAString();
+ foo.clearABool();
+ foo.clearANestedMessage();
+ foo.clearARepeatedMessageList();
+ foo.clearARepeatedStringList();
+ assertEquals('', foo.getAString());
+ assertEquals(false, foo.getABool());
+ assertUndefined(foo.getANestedMessage());
+ assertFalse(foo.hasAString());
+ assertFalse(foo.hasABool());
+ assertObjectEquals([], foo.getARepeatedMessageList());
+ assertObjectEquals([], foo.getARepeatedStringList());
+ // NOTE: We want the missing fields in 'expected' to be undefined,
+ // but we actually get a sparse array instead. We could use something
+ // like [1,undefined,2] to avoid this, except that this is still
+ // sparse on IE. No comment...
+ var expected = [,,, [], []];
+ expected[0] = expected[1] = expected[2] = undefined;
+ assertObjectEquals(expected, foo.toArray());
+
+ // Test set(null). We could deprecated this in favor of clear(), but
+ // it's also convenient to have.
+ data = ['str', true, [11], [[22], [33]], ['s1', 's2']];
+ foo = new proto.jspb.test.OptionalFields(data);
+ foo.setAString(null);
+ foo.setABool(null);
+ foo.setANestedMessage(null);
+ foo.setARepeatedMessageList(null);
+ foo.setARepeatedStringList(null);
+ assertEquals('', foo.getAString());
+ assertEquals(false, foo.getABool());
+ assertNull(foo.getANestedMessage());
+ assertFalse(foo.hasAString());
+ assertFalse(foo.hasABool());
+ assertObjectEquals([], foo.getARepeatedMessageList());
+ assertObjectEquals([], foo.getARepeatedStringList());
+ assertObjectEquals([null, null, null, [], []], foo.toArray());
+
+ // Test set(undefined). Again, not something we really need, and not
+ // supported directly by our typing, but it should 'do the right thing'.
+ data = ['str', true, [11], [[22], [33]], ['s1', 's2']];
+ foo = new proto.jspb.test.OptionalFields(data);
+ foo.setAString(undefined);
+ foo.setABool(undefined);
+ foo.setANestedMessage(undefined);
+ foo.setARepeatedMessageList(undefined);
+ foo.setARepeatedStringList(undefined);
+ assertEquals('', foo.getAString());
+ assertEquals(false, foo.getABool());
+ assertUndefined(foo.getANestedMessage());
+ assertFalse(foo.hasAString());
+ assertFalse(foo.hasABool());
+ assertObjectEquals([], foo.getARepeatedMessageList());
+ assertObjectEquals([], foo.getARepeatedStringList());
+ expected = [,,, [], []];
+ expected[0] = expected[1] = expected[2] = undefined;
+ assertObjectEquals(expected, foo.toArray());
+ });
+
+ it('testDifferenceRawObject', function() {
+ var p1 = new proto.jspb.test.HasExtensions(['hi', 'diff', {}]);
+ var p2 = new proto.jspb.test.HasExtensions(['hi', 'what',
+ {1000: 'unique'}]);
+ var diff = /** @type {proto.jspb.test.HasExtensions} */
+ (jspb.Message.difference(p1, p2));
+ assertEquals('', diff.getStr1());
+ assertEquals('what', diff.getStr2());
+ assertEquals('', diff.getStr3());
+ assertEquals('unique', diff.extensionObject_[1000]);
+ });
+
+ it('testEqualsSimple', function() {
+ var s1 = new proto.jspb.test.Simple1(['hi']);
+ assertTrue(jspb.Message.equals(s1, new proto.jspb.test.Simple1(['hi'])));
+ assertFalse(jspb.Message.equals(s1, new proto.jspb.test.Simple1(['bye'])));
+ var s1b = new proto.jspb.test.Simple1(['hi', ['hello']]);
+ assertTrue(jspb.Message.equals(s1b,
+ new proto.jspb.test.Simple1(['hi', ['hello']])));
+ assertTrue(jspb.Message.equals(s1b,
+ new proto.jspb.test.Simple1(['hi', ['hello', undefined,
+ undefined, undefined]])));
+ assertFalse(jspb.Message.equals(s1b,
+ new proto.jspb.test.Simple1(['no', ['hello']])));
+ // Test with messages of different types
+ var s2 = new proto.jspb.test.Simple2(['hi']);
+ assertFalse(jspb.Message.equals(s1, s2));
+ });
+
+ it('testEquals_softComparison', function() {
+ var s1 = new proto.jspb.test.Simple1(['hi', [], null]);
+ assertTrue(jspb.Message.equals(s1,
+ new proto.jspb.test.Simple1(['hi', []])));
+
+ var s1b = new proto.jspb.test.Simple1(['hi', [], true]);
+ assertTrue(jspb.Message.equals(s1b,
+ new proto.jspb.test.Simple1(['hi', [], 1])));
+ });
+
+ it('testEqualsComplex', function() {
+ var data1 = ['a',,, [, 11], [[, 22], [, 33]],, ['s1', 's2'],, 1];
+ var data2 = ['a',,, [, 11], [[, 22], [, 34]],, ['s1', 's2'],, 1];
+ var data3 = ['a',,, [, 11], [[, 22]],, ['s1', 's2'],, 1];
+ var data4 = ['hi'];
+ var c1a = new proto.jspb.test.Complex(data1);
+ var c1b = new proto.jspb.test.Complex(data1);
+ var c2 = new proto.jspb.test.Complex(data2);
+ var c3 = new proto.jspb.test.Complex(data3);
+ var s1 = new proto.jspb.test.Simple1(data4);
+
+ assertTrue(jspb.Message.equals(c1a, c1b));
+ assertFalse(jspb.Message.equals(c1a, c2));
+ assertFalse(jspb.Message.equals(c2, c3));
+ assertFalse(jspb.Message.equals(c1a, s1));
+ });
+
+ it('testEqualsExtensionsConstructed', function() {
+ assertTrue(jspb.Message.equals(
+ new proto.jspb.test.HasExtensions([]),
+ new proto.jspb.test.HasExtensions([{}])
+ ));
+ assertTrue(jspb.Message.equals(
+ new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}]),
+ new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}])
+ ));
+ assertFalse(jspb.Message.equals(
+ new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}]),
+ new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'b'}]}])
+ ));
+ assertTrue(jspb.Message.equals(
+ new proto.jspb.test.HasExtensions([{100: [{200: 'a'}]}]),
+ new proto.jspb.test.HasExtensions([{100: [{200: 'a'}]}])
+ ));
+ assertTrue(jspb.Message.equals(
+ new proto.jspb.test.HasExtensions([{100: [{200: 'a'}]}]),
+ new proto.jspb.test.HasExtensions([,,, {100: [{200: 'a'}]}])
+ ));
+ assertTrue(jspb.Message.equals(
+ new proto.jspb.test.HasExtensions([,,, {100: [{200: 'a'}]}]),
+ new proto.jspb.test.HasExtensions([{100: [{200: 'a'}]}])
+ ));
+ assertTrue(jspb.Message.equals(
+ new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}]),
+ new proto.jspb.test.HasExtensions(['hi',,, {100: [{200: 'a'}]}])
+ ));
+ assertTrue(jspb.Message.equals(
+ new proto.jspb.test.HasExtensions(['hi',,, {100: [{200: 'a'}]}]),
+ new proto.jspb.test.HasExtensions(['hi', {100: [{200: 'a'}]}])
+ ));
+ });
+
+ it('testEqualsExtensionsUnconstructed', function() {
+ assertTrue(jspb.Message.compareFields([], [{}]));
+ assertTrue(jspb.Message.compareFields([,,, {}], []));
+ assertTrue(jspb.Message.compareFields([,,, {}], [,, {}]));
+ assertTrue(jspb.Message.compareFields(
+ ['hi', {100: [{200: 'a'}]}], ['hi', {100: [{200: 'a'}]}]));
+ assertFalse(jspb.Message.compareFields(
+ ['hi', {100: [{200: 'a'}]}], ['hi', {100: [{200: 'b'}]}]));
+ assertTrue(jspb.Message.compareFields(
+ [{100: [{200: 'a'}]}], [{100: [{200: 'a'}]}]));
+ assertTrue(jspb.Message.compareFields(
+ [{100: [{200: 'a'}]}], [,,, {100: [{200: 'a'}]}]));
+ assertTrue(jspb.Message.compareFields(
+ [,,, {100: [{200: 'a'}]}], [{100: [{200: 'a'}]}]));
+ assertTrue(jspb.Message.compareFields(
+ ['hi', {100: [{200: 'a'}]}], ['hi',,, {100: [{200: 'a'}]}]));
+ assertTrue(jspb.Message.compareFields(
+ ['hi',,, {100: [{200: 'a'}]}], ['hi', {100: [{200: 'a'}]}]));
+ });
+
+ it('testToMap', function() {
+ var p1 = new proto.jspb.test.Simple1(['k', ['v']]);
+ var p2 = new proto.jspb.test.Simple1(['k1', ['v1', 'v2']]);
+ var soymap = jspb.Message.toMap([p1, p2],
+ proto.jspb.test.Simple1.prototype.getAString,
+ proto.jspb.test.Simple1.prototype.toObject);
+ assertEquals('k', soymap['k'].aString);
+ assertArrayEquals(['v'], soymap['k'].aRepeatedStringList);
+ var protomap = jspb.Message.toMap([p1, p2],
+ proto.jspb.test.Simple1.prototype.getAString);
+ assertEquals('k', protomap['k'].getAString());
+ assertArrayEquals(['v'], protomap['k'].getARepeatedStringList());
+ });
+
+ it('testClone', function() {
+ var supportsUint8Array =
+ !goog.userAgent.IE || goog.userAgent.isVersionOrHigher('10');
+ var original = new proto.jspb.test.TestClone();
+ original.setStr('v1');
+ var simple1 = new proto.jspb.test.Simple1(['x1', ['y1', 'z1']]);
+ var simple2 = new proto.jspb.test.Simple1(['x2', ['y2', 'z2']]);
+ var simple3 = new proto.jspb.test.Simple1(['x3', ['y3', 'z3']]);
+ original.setSimple1(simple1);
+ original.setSimple2List([simple2, simple3]);
+ var bytes1 = supportsUint8Array ? new Uint8Array([1, 2, 3]) : '123';
+ original.setBytesField(bytes1);
+ var extension = new proto.jspb.test.CloneExtension();
+ extension.setExt('e1');
+ original.setExtension(proto.jspb.test.IsExtension.extField, extension);
+ var clone = original.cloneMessage();
+ assertArrayEquals(['v1',, ['x1', ['y1', 'z1']],,
+ [['x2', ['y2', 'z2']], ['x3', ['y3', 'z3']]], bytes1,, { 100: [, 'e1'] }],
+ clone.toArray());
+ clone.setStr('v2');
+ var simple4 = new proto.jspb.test.Simple1(['a1', ['b1', 'c1']]);
+ var simple5 = new proto.jspb.test.Simple1(['a2', ['b2', 'c2']]);
+ var simple6 = new proto.jspb.test.Simple1(['a3', ['b3', 'c3']]);
+ clone.setSimple1(simple4);
+ clone.setSimple2List([simple5, simple6]);
+ if (supportsUint8Array) {
+ clone.getBytesField()[0] = 4;
+ assertObjectEquals(bytes1, original.getBytesField());
+ }
+ var bytes2 = supportsUint8Array ? new Uint8Array([4, 5, 6]) : '456';
+ clone.setBytesField(bytes2);
+ var newExtension = new proto.jspb.test.CloneExtension();
+ newExtension.setExt('e2');
+ clone.setExtension(proto.jspb.test.CloneExtension.extField, newExtension);
+ assertArrayEquals(['v2',, ['a1', ['b1', 'c1']],,
+ [['a2', ['b2', 'c2']], ['a3', ['b3', 'c3']]], bytes2,, { 100: [, 'e2'] }],
+ clone.toArray());
+ assertArrayEquals(['v1',, ['x1', ['y1', 'z1']],,
+ [['x2', ['y2', 'z2']], ['x3', ['y3', 'z3']]], bytes1,, { 100: [, 'e1'] }],
+ original.toArray());
+ });
+
+ it('testCopyInto', function() {
+ var supportsUint8Array =
+ !goog.userAgent.IE || goog.userAgent.isVersionOrHigher('10');
+ var original = new proto.jspb.test.TestClone();
+ original.setStr('v1');
+ var dest = new proto.jspb.test.TestClone();
+ dest.setStr('override');
+ var simple1 = new proto.jspb.test.Simple1(['x1', ['y1', 'z1']]);
+ var simple2 = new proto.jspb.test.Simple1(['x2', ['y2', 'z2']]);
+ var simple3 = new proto.jspb.test.Simple1(['x3', ['y3', 'z3']]);
+ var destSimple1 = new proto.jspb.test.Simple1(['ox1', ['oy1', 'oz1']]);
+ var destSimple2 = new proto.jspb.test.Simple1(['ox2', ['oy2', 'oz2']]);
+ var destSimple3 = new proto.jspb.test.Simple1(['ox3', ['oy3', 'oz3']]);
+ original.setSimple1(simple1);
+ original.setSimple2List([simple2, simple3]);
+ dest.setSimple1(destSimple1);
+ dest.setSimple2List([destSimple2, destSimple3]);
+ var bytes1 = supportsUint8Array ? new Uint8Array([1, 2, 3]) : '123';
+ var bytes2 = supportsUint8Array ? new Uint8Array([4, 5, 6]) : '456';
+ original.setBytesField(bytes1);
+ dest.setBytesField(bytes2);
+ var extension = new proto.jspb.test.CloneExtension();
+ extension.setExt('e1');
+ original.setExtension(proto.jspb.test.CloneExtension.extField, extension);
+
+ jspb.Message.copyInto(original, dest);
+ assertArrayEquals(original.toArray(), dest.toArray());
+ assertEquals('x1', dest.getSimple1().getAString());
+ assertEquals('e1',
+ dest.getExtension(proto.jspb.test.CloneExtension.extField).getExt());
+ dest.getSimple1().setAString('new value');
+ assertNotEquals(dest.getSimple1().getAString(),
+ original.getSimple1().getAString());
+ if (supportsUint8Array) {
+ dest.getBytesField()[0] = 7;
+ assertObjectEquals(bytes1, original.getBytesField());
+ assertObjectEquals(new Uint8Array([7, 2, 3]), dest.getBytesField());
+ } else {
+ dest.setBytesField('789');
+ assertObjectEquals(bytes1, original.getBytesField());
+ assertObjectEquals('789', dest.getBytesField());
+ }
+ dest.getExtension(proto.jspb.test.CloneExtension.extField).
+ setExt('new value');
+ assertNotEquals(
+ dest.getExtension(proto.jspb.test.CloneExtension.extField).getExt(),
+ original.getExtension(
+ proto.jspb.test.CloneExtension.extField).getExt());
+ });
+
+ it('testCopyInto_notSameType', function() {
+ var a = new proto.jspb.test.TestClone();
+ var b = new proto.jspb.test.Simple1(['str', ['s1', 's2']]);
+
+ var e = assertThrows(function() {
+ jspb.Message.copyInto(a, b);
+ });
+ assertContains('should have the same type', e.message);
+ });
+
+ it('testExtensions', function() {
+ var extension1 = new proto.jspb.test.IsExtension(['ext1field']);
+ var extension2 = new proto.jspb.test.Simple1(['str', ['s1', 's2']]);
+ var extendable = new proto.jspb.test.HasExtensions(['v1', 'v2', 'v3']);
+ extendable.setExtension(proto.jspb.test.IsExtension.extField, extension1);
+ extendable.setExtension(proto.jspb.test.IndirectExtension.simple,
+ extension2);
+ extendable.setExtension(proto.jspb.test.IndirectExtension.str, 'xyzzy');
+ extendable.setExtension(proto.jspb.test.IndirectExtension.repeatedStrList,
+ ['a', 'b']);
+ var s1 = new proto.jspb.test.Simple1(['foo', ['s1', 's2']]);
+ var s2 = new proto.jspb.test.Simple1(['bar', ['t1', 't2']]);
+ extendable.setExtension(
+ proto.jspb.test.IndirectExtension.repeatedSimpleList,
+ [s1, s2]);
+ assertObjectEquals(extension1,
+ extendable.getExtension(proto.jspb.test.IsExtension.extField));
+ assertObjectEquals(extension2,
+ extendable.getExtension(proto.jspb.test.IndirectExtension.simple));
+ assertObjectEquals('xyzzy',
+ extendable.getExtension(proto.jspb.test.IndirectExtension.str));
+ assertObjectEquals(['a', 'b'], extendable.getExtension(
+ proto.jspb.test.IndirectExtension.repeatedStrList));
+ assertObjectEquals([s1, s2], extendable.getExtension(
+ proto.jspb.test.IndirectExtension.repeatedSimpleList));
+ // Not supported yet, but it should work...
+ extendable.setExtension(proto.jspb.test.IndirectExtension.simple, null);
+ assertNull(
+ extendable.getExtension(proto.jspb.test.IndirectExtension.simple));
+ extendable.setExtension(proto.jspb.test.IndirectExtension.str, null);
+ assertNull(extendable.getExtension(proto.jspb.test.IndirectExtension.str));
+
+
+ // Extension fields with jspb.ignore = true are ignored.
+ assertUndefined(proto.jspb.test.IndirectExtension['ignored']);
+ assertUndefined(proto.jspb.test.HasExtensions['ignoredFloating']);
+ });
+
+ it('testFloatingExtensions', function() {
+ // From an autogenerated container.
+ var extendable = new proto.jspb.test.HasExtensions(['v1', 'v2', 'v3']);
+ var extension = new proto.jspb.test.Simple1(['foo', ['s1', 's2']]);
+ extendable.setExtension(proto.jspb.test.simple1, extension);
+ assertObjectEquals(extension,
+ extendable.getExtension(proto.jspb.test.simple1));
+
+ // From _lib mode.
+ extension = new proto.jspb.test.ExtensionMessage(['s1']);
+ extendable = new proto.jspb.test.TestExtensionsMessage([16]);
+ extendable.setExtension(proto.jspb.test.floatingMsgField, extension);
+ extendable.setExtension(proto.jspb.test.floatingStrField, 's2');
+ assertObjectEquals(extension,
+ extendable.getExtension(proto.jspb.test.floatingMsgField));
+ assertObjectEquals('s2',
+ extendable.getExtension(proto.jspb.test.floatingStrField));
+ assertNotUndefined(proto.jspb.exttest.floatingMsgField);
+ assertNotUndefined(proto.jspb.exttest.floatingMsgFieldTwo);
+ assertNotUndefined(proto.jspb.exttest.beta.floatingStrField);
+ });
+
+ it('testToObject_extendedObject', function() {
+ var extension1 = new proto.jspb.test.IsExtension(['ext1field']);
+ var extension2 = new proto.jspb.test.Simple1(['str', ['s1', 's2'], true]);
+ var extendable = new proto.jspb.test.HasExtensions(['v1', 'v2', 'v3']);
+ extendable.setExtension(proto.jspb.test.IsExtension.extField, extension1);
+ extendable.setExtension(proto.jspb.test.IndirectExtension.simple,
+ extension2);
+ extendable.setExtension(proto.jspb.test.IndirectExtension.str, 'xyzzy');
+ extendable.setExtension(proto.jspb.test.IndirectExtension.repeatedStrList,
+ ['a', 'b']);
+ var s1 = new proto.jspb.test.Simple1(['foo', ['s1', 's2'], true]);
+ var s2 = new proto.jspb.test.Simple1(['bar', ['t1', 't2'], false]);
+ extendable.setExtension(
+ proto.jspb.test.IndirectExtension.repeatedSimpleList,
+ [s1, s2]);
+ assertObjectEquals({
+ str1: 'v1', str2: 'v2', str3: 'v3',
+ extField: { ext1: 'ext1field' },
+ simple: {
+ aString: 'str', aRepeatedStringList: ['s1', 's2'], aBoolean: true
+ },
+ str: 'xyzzy',
+ repeatedStrList: ['a', 'b'],
+ repeatedSimpleList: [
+ { aString: 'foo', aRepeatedStringList: ['s1', 's2'], aBoolean: true},
+ { aString: 'bar', aRepeatedStringList: ['t1', 't2'], aBoolean: false}
+ ]
+ }, extendable.toObject());
+
+ // Now, with instances included.
+ assertObjectEquals({
+ str1: 'v1', str2: 'v2', str3: 'v3',
+ extField: {
+ ext1: 'ext1field',
+ $jspbMessageInstance:
+ extendable.getExtension(proto.jspb.test.IsExtension.extField)
+ },
+ simple: {
+ aString: 'str',
+ aRepeatedStringList: ['s1', 's2'],
+ aBoolean: true,
+ $jspbMessageInstance:
+ extendable.getExtension(proto.jspb.test.IndirectExtension.simple)
+ },
+ str: 'xyzzy',
+ repeatedStrList: ['a', 'b'],
+ repeatedSimpleList: [{
+ aString: 'foo',
+ aRepeatedStringList: ['s1', 's2'],
+ aBoolean: true,
+ $jspbMessageInstance: s1
+ }, {
+ aString: 'bar',
+ aRepeatedStringList: ['t1', 't2'],
+ aBoolean: false,
+ $jspbMessageInstance: s2
+ }],
+ $jspbMessageInstance: extendable
+ }, extendable.toObject(true /* opt_includeInstance */));
+ });
+
+ it('testInitialization_emptyArray', function() {
+ var msg = new proto.jspb.test.HasExtensions([]);
+ if (jspb.Message.MINIMIZE_MEMORY_ALLOCATIONS) {
+ assertArrayEquals([], msg.toArray());
+ } else {
+ // Extension object is created past all regular fields.
+ assertArrayEquals([,,, {}], msg.toArray());
+ }
+ });
+
+ it('testInitialization_justExtensionObject', function() {
+ var msg = new proto.jspb.test.Empty([{1: 'hi'}]);
+ // The extensionObject is not moved from its original location.
+ assertArrayEquals([{1: 'hi'}], msg.toArray());
+ });
+
+ it('testInitialization_incompleteList', function() {
+ var msg = new proto.jspb.test.Empty([1, {4: 'hi'}]);
+ // The extensionObject is not moved from its original location.
+ assertArrayEquals([1, {4: 'hi'}], msg.toArray());
+ });
+
+ it('testInitialization_forwardCompatible', function() {
+ var msg = new proto.jspb.test.Empty([1, 2, 3, {1: 'hi'}]);
+ assertArrayEquals([1, 2, 3, {1: 'hi'}], msg.toArray());
+ });
+
+ it('testExtendedMessageEnsureObject', function() {
+ var data = new proto.jspb.test.HasExtensions(['str1',
+ {'a_key': 'an_object'}]);
+ assertEquals('an_object', data.extensionObject_['a_key']);
+ });
+
+ it('testToObject_hasExtensionField', function() {
+ var data = new proto.jspb.test.HasExtensions(['str1', {100: ['ext1']}]);
+ var obj = data.toObject();
+ assertEquals('str1', obj.str1);
+ assertEquals('ext1', obj.extField.ext1);
+ });
+
+ it('testGetExtension', function() {
+ var data = new proto.jspb.test.HasExtensions(['str1', {100: ['ext1']}]);
+ assertEquals('str1', data.getStr1());
+ var extension = data.getExtension(proto.jspb.test.IsExtension.extField);
+ assertNotNull(extension);
+ assertEquals('ext1', extension.getExt1());
+ });
+
+ it('testSetExtension', function() {
+ var data = new proto.jspb.test.HasExtensions();
+ var extensionMessage = new proto.jspb.test.IsExtension(['is_extension']);
+ data.setExtension(proto.jspb.test.IsExtension.extField, extensionMessage);
+ var obj = data.toObject();
+ assertNotNull(
+ data.getExtension(proto.jspb.test.IsExtension.extField));
+ assertEquals('is_extension', obj.extField.ext1);
+ });
+
+ /**
+ * Note that group is long deprecated, we only support it because JsPb has
+ * a goal of being able to generate JS classes for all proto descriptors.
+ */
+ it('testGroups', function() {
+ var group = new proto.jspb.test.TestGroup();
+ var someGroup = new proto.jspb.test.TestGroup.RepeatedGroup();
+ someGroup.setId('g1');
+ someGroup.setSomeBoolList([true, false]);
+ group.setRepeatedGroupList([someGroup]);
+ var groups = group.getRepeatedGroupList();
+ assertEquals('g1', groups[0].getId());
+ assertObjectEquals([true, false], groups[0].getSomeBoolList());
+ assertObjectEquals({id: 'g1', someBoolList: [true, false]},
+ groups[0].toObject());
+ assertObjectEquals({
+ repeatedGroupList: [{id: 'g1', someBoolList: [true, false]}],
+ requiredGroup: {id: undefined},
+ optionalGroup: undefined,
+ requiredSimple: {aRepeatedStringList: [], aString: undefined},
+ optionalSimple: undefined,
+ id: undefined
+ }, group.toObject());
+ var group1 = new proto.jspb.test.TestGroup1();
+ group1.setGroup(someGroup);
+ assertEquals(someGroup, group1.getGroup());
+ });
+
+ it('testNonExtensionFieldsAfterExtensionRange', function() {
+ var data = [{'1': 'a_string'}];
+ var message = new proto.jspb.test.Complex(data);
+ assertArrayEquals([], message.getARepeatedStringList());
+ });
+
+ it('testReservedGetterNames', function() {
+ var message = new proto.jspb.test.TestReservedNames();
+ message.setExtension$(11);
+ message.setExtension(proto.jspb.test.TestReservedNamesExtension.foo, 12);
+ assertEquals(11, message.getExtension$());
+ assertEquals(12, message.getExtension(
+ proto.jspb.test.TestReservedNamesExtension.foo));
+ assertObjectEquals({extension: 11, foo: 12}, message.toObject());
+ });
+
+ it('testInitializeMessageWithUnsetOneof', function() {
+ var message = new proto.jspb.test.TestMessageWithOneof([]);
+ assertEquals(
+ proto.jspb.test.TestMessageWithOneof.PartialOneofCase.
+ PARTIAL_ONEOF_NOT_SET,
+ message.getPartialOneofCase());
+ assertEquals(
+ proto.jspb.test.TestMessageWithOneof.RecursiveOneofCase.
+ RECURSIVE_ONEOF_NOT_SET,
+ message.getRecursiveOneofCase());
+ });
+
+ it('testInitializeMessageWithSingleValueSetInOneof', function() {
+ var message = new proto.jspb.test.TestMessageWithOneof([,, 'x']);
+
+ assertEquals('x', message.getPone());
+ assertEquals('', message.getPthree());
+ assertEquals(
+ proto.jspb.test.TestMessageWithOneof.PartialOneofCase.PONE,
+ message.getPartialOneofCase());
+ });
+
+ it('testKeepsLastWireValueSetInUnion_multipleValues', function() {
+ var message = new proto.jspb.test.TestMessageWithOneof([,, 'x',, 'y']);
+
+ assertEquals('', message.getPone());
+ assertEquals('y', message.getPthree());
+ assertEquals(
+ proto.jspb.test.TestMessageWithOneof.PartialOneofCase.PTHREE,
+ message.getPartialOneofCase());
+ });
+
+ it('testSettingOneofFieldClearsOthers', function() {
+ var message = new proto.jspb.test.TestMessageWithOneof;
+ assertEquals('', message.getPone());
+ assertEquals('', message.getPthree());
+ assertFalse(message.hasPone());
+ assertFalse(message.hasPthree());
+
+ message.setPone('hi');
+ assertEquals('hi', message.getPone());
+ assertEquals('', message.getPthree());
+ assertTrue(message.hasPone());
+ assertFalse(message.hasPthree());
+
+ message.setPthree('bye');
+ assertEquals('', message.getPone());
+ assertEquals('bye', message.getPthree());
+ assertFalse(message.hasPone());
+ assertTrue(message.hasPthree());
+ });
+
+ it('testSettingOneofFieldDoesNotClearFieldsFromOtherUnions', function() {
+ var other = new proto.jspb.test.TestMessageWithOneof;
+ var message = new proto.jspb.test.TestMessageWithOneof;
+ assertEquals('', message.getPone());
+ assertEquals('', message.getPthree());
+ assertUndefined(message.getRone());
+ assertFalse(message.hasPone());
+ assertFalse(message.hasPthree());
+
+ message.setPone('hi');
+ message.setRone(other);
+ assertEquals('hi', message.getPone());
+ assertEquals('', message.getPthree());
+ assertEquals(other, message.getRone());
+ assertTrue(message.hasPone());
+ assertFalse(message.hasPthree());
+
+ message.setPthree('bye');
+ assertEquals('', message.getPone());
+ assertEquals('bye', message.getPthree());
+ assertEquals(other, message.getRone());
+ assertFalse(message.hasPone());
+ assertTrue(message.hasPthree());
+ });
+
+ it('testUnsetsOneofCaseWhenFieldIsCleared', function() {
+ var message = new proto.jspb.test.TestMessageWithOneof;
+ assertEquals(
+ proto.jspb.test.TestMessageWithOneof.PartialOneofCase.
+ PARTIAL_ONEOF_NOT_SET,
+ message.getPartialOneofCase());
+
+ message.setPone('hi');
+ assertEquals(
+ proto.jspb.test.TestMessageWithOneof.PartialOneofCase.PONE,
+ message.getPartialOneofCase());
+
+ message.clearPone();
+ assertEquals(
+ proto.jspb.test.TestMessageWithOneof.PartialOneofCase.
+ PARTIAL_ONEOF_NOT_SET,
+ message.getPartialOneofCase());
+ });
+
+ it('testMessageWithDefaultOneofValues', function() {
+ var message = new proto.jspb.test.TestMessageWithOneof;
+ assertEquals(1234, message.getAone());
+ assertEquals(0, message.getAtwo());
+ assertEquals(
+ proto.jspb.test.TestMessageWithOneof.DefaultOneofACase
+ .DEFAULT_ONEOF_A_NOT_SET,
+ message.getDefaultOneofACase());
+
+ message.setAone(567);
+ assertEquals(567, message.getAone());
+ assertEquals(0, message.getAtwo());
+ assertEquals(
+ proto.jspb.test.TestMessageWithOneof.DefaultOneofACase.AONE,
+ message.getDefaultOneofACase());
+
+ message.setAtwo(890);
+ assertEquals(1234, message.getAone());
+ assertEquals(890, message.getAtwo());
+ assertEquals(
+ proto.jspb.test.TestMessageWithOneof.DefaultOneofACase.ATWO,
+ message.getDefaultOneofACase());
+
+ message.clearAtwo();
+ assertEquals(1234, message.getAone());
+ assertEquals(0, message.getAtwo());
+ assertEquals(
+ proto.jspb.test.TestMessageWithOneof.DefaultOneofACase
+ .DEFAULT_ONEOF_A_NOT_SET,
+ message.getDefaultOneofACase());
+ });
+
+ it('testMessageWithDefaultOneofValues_defaultNotOnFirstField', function() {
+ var message = new proto.jspb.test.TestMessageWithOneof;
+ assertEquals(0, message.getBone());
+ assertEquals(1234, message.getBtwo());
+ assertFalse(message.hasBone());
+ assertFalse(message.hasBtwo());
+ assertEquals(
+ proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase
+ .DEFAULT_ONEOF_B_NOT_SET,
+ message.getDefaultOneofBCase());
+
+ message.setBone(2);
+ assertEquals(2, message.getBone());
+ assertEquals(1234, message.getBtwo());
+ assertTrue(message.hasBone());
+ assertFalse(message.hasBtwo());
+ assertEquals(
+ proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BONE,
+ message.getDefaultOneofBCase());
+
+ message.setBtwo(3);
+ assertEquals(0, message.getBone());
+ assertFalse(message.hasBone());
+ assertTrue(message.hasBtwo());
+ assertEquals(3, message.getBtwo());
+ assertEquals(
+ proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BTWO,
+ message.getDefaultOneofBCase());
+
+ message.clearBtwo();
+ assertEquals(0, message.getBone());
+ assertFalse(message.hasBone());
+ assertFalse(message.hasBtwo());
+ assertEquals(1234, message.getBtwo());
+ assertEquals(
+ proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase
+ .DEFAULT_ONEOF_B_NOT_SET,
+ message.getDefaultOneofBCase());
+ });
+
+ it('testInitializeMessageWithOneofDefaults', function() {
+ var message =
+ new proto.jspb.test.TestMessageWithOneof(new Array(9).concat(567));
+ assertEquals(567, message.getAone());
+ assertEquals(0, message.getAtwo());
+ assertEquals(
+ proto.jspb.test.TestMessageWithOneof.DefaultOneofACase.AONE,
+ message.getDefaultOneofACase());
+
+ message =
+ new proto.jspb.test.TestMessageWithOneof(new Array(10).concat(890));
+ assertEquals(1234, message.getAone());
+ assertEquals(890, message.getAtwo());
+ assertEquals(
+ proto.jspb.test.TestMessageWithOneof.DefaultOneofACase.ATWO,
+ message.getDefaultOneofACase());
+
+ message =
+ new proto.jspb.test.TestMessageWithOneof(new Array(9).concat(567, 890));
+ assertEquals(1234, message.getAone());
+ assertEquals(890, message.getAtwo());
+ assertEquals(
+ proto.jspb.test.TestMessageWithOneof.DefaultOneofACase.ATWO,
+ message.getDefaultOneofACase());
+ });
+
+ it('testInitializeMessageWithOneofDefaults_defaultNotSetOnFirstField',
+ function() {
+ var message;
+
+ message =
+ new proto.jspb.test.TestMessageWithOneof(new Array(11).concat(567));
+ assertEquals(567, message.getBone());
+ assertEquals(1234, message.getBtwo());
+ assertEquals(
+ proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BONE,
+ message.getDefaultOneofBCase());
+
+ message =
+ new proto.jspb.test.TestMessageWithOneof(new Array(12).concat(890));
+ assertEquals(0, message.getBone());
+ assertEquals(890, message.getBtwo());
+ assertEquals(
+ proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BTWO,
+ message.getDefaultOneofBCase());
+
+ message = new proto.jspb.test.TestMessageWithOneof(
+ new Array(11).concat(567, 890));
+ assertEquals(0, message.getBone());
+ assertEquals(890, message.getBtwo());
+ assertEquals(
+ proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BTWO,
+ message.getDefaultOneofBCase());
+ });
+
+ it('testOneofContainingAnotherMessage', function() {
+ var message = new proto.jspb.test.TestMessageWithOneof;
+ assertEquals(
+ proto.jspb.test.TestMessageWithOneof.RecursiveOneofCase.
+ RECURSIVE_ONEOF_NOT_SET,
+ message.getRecursiveOneofCase());
+
+ var other = new proto.jspb.test.TestMessageWithOneof;
+ message.setRone(other);
+ assertEquals(other, message.getRone());
+ assertEquals('', message.getRtwo());
+ assertEquals(
+ proto.jspb.test.TestMessageWithOneof.RecursiveOneofCase.RONE,
+ message.getRecursiveOneofCase());
+
+ message.setRtwo('hi');
+ assertUndefined(message.getRone());
+ assertEquals('hi', message.getRtwo());
+ assertEquals(
+ proto.jspb.test.TestMessageWithOneof.RecursiveOneofCase.RTWO,
+ message.getRecursiveOneofCase());
+ });
+
+ it('testQueryingOneofCaseEnsuresOnlyOneFieldIsSetInUnderlyingArray',
+ function() {
+ var message = new proto.jspb.test.TestMessageWithOneof;
+ message.setPone('x');
+ assertEquals('x', message.getPone());
+ assertEquals('', message.getPthree());
+ assertEquals(
+ proto.jspb.test.TestMessageWithOneof.PartialOneofCase.PONE,
+ message.getPartialOneofCase());
+
+ var array = message.toArray();
+ assertEquals('x', array[2]);
+ assertUndefined(array[4]);
+ array[4] = 'y';
+
+ assertEquals(
+ proto.jspb.test.TestMessageWithOneof.PartialOneofCase.PTHREE,
+ message.getPartialOneofCase());
+ assertUndefined(array[2]);
+ assertEquals('y', array[4]);
+ });
+
+ it('testFloatingPointFieldsSupportNan', function() {
+ var assertNan = function(x) {
+ assertTrue('Expected ' + x + ' (' + goog.typeOf(x) + ') to be NaN.',
+ goog.isNumber(x) && isNaN(x));
+ };
+
+ var message = new proto.jspb.test.FloatingPointFields([
+ 'NaN', 'NaN', ['NaN', 'NaN'], 'NaN',
+ 'NaN', 'NaN', ['NaN', 'NaN'], 'NaN'
+ ]);
+ assertNan(message.getOptionalFloatField());
+ assertNan(message.getRequiredFloatField());
+ assertNan(message.getRepeatedFloatFieldList()[0]);
+ assertNan(message.getRepeatedFloatFieldList()[1]);
+ assertNan(message.getDefaultFloatField());
+ assertNan(message.getOptionalDoubleField());
+ assertNan(message.getRequiredDoubleField());
+ assertNan(message.getRepeatedDoubleFieldList()[0]);
+ assertNan(message.getRepeatedDoubleFieldList()[1]);
+ assertNan(message.getDefaultDoubleField());
+ });
+
+});
diff --git a/src/google/protobuf/util/internal/snake2camel_objectwriter_test.cc b/js/node_loader.js
index e5db844c..79211add 100644
--- a/src/google/protobuf/util/internal/snake2camel_objectwriter_test.cc
+++ b/js/node_loader.js
@@ -28,30 +28,22 @@
// (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 <google/protobuf/util/internal/snake2camel_objectwriter.h>
-#include <google/protobuf/util/internal/expecting_objectwriter.h>
-#include <gtest/gtest.h>
+/**
+ * @fileoverview Loader that handles goog.require() for Node.JS.
+ */
-namespace google {
-namespace protobuf {
-namespace util {
-namespace converter {
+var oldLoader = goog.global.CLOSURE_IMPORT_SCRIPT;
-class Snake2CamelObjectWriterTest : public ::testing::Test {
- protected:
- Snake2CamelObjectWriterTest() : mock_(), expects_(&mock_), testing_(&mock_) {}
- virtual ~Snake2CamelObjectWriterTest() {}
+goog.global.CLOSURE_IMPORT_SCRIPT = function(src, opt_sourceText) {
+ if (opt_sourceText === undefined) {
+ try {
+ // Load from the current directory.
+ require("./" + src);
+ return true;
+ } catch (e) {
+ // Fall back to the Closure loader.
+ }
+ }
- MockObjectWriter mock_;
- ExpectingObjectWriter expects_;
- Snake2CamelObjectWriter testing_;
+ return oldLoader(src, opt_sourceText);
};
-
-// All tests are deleted as they are no longer needed. This file will be removed
-// after the component dependecies are cleaned up.
-// TODO(skarvaje): Remove this file.
-
-} // namespace converter
-} // namespace util
-} // namespace protobuf
-} // namespace google
diff --git a/js/package.json b/js/package.json
new file mode 100644
index 00000000..3f51d96b
--- /dev/null
+++ b/js/package.json
@@ -0,0 +1,26 @@
+{
+ "name": "google-protobuf",
+ "version": "3.0.0",
+ "description": "Protocol Buffers for JavaScript",
+ "main": "google-protobuf.js",
+ "files": [
+ "google"
+ ],
+ "dependencies": {},
+ "devDependencies": {
+ "glob": "~6.0.4",
+ "google-closure-compiler": "~20160619.0.0",
+ "google-closure-library": "~20160125.0.0",
+ "gulp": "~3.9.0",
+ "jasmine": "~2.4.1"
+ },
+ "scripts": {
+ "test": "node ./node_modules/gulp/bin/gulp.js test"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/google/protobuf/tree/master/js"
+ },
+ "author": "Google Protocol Buffers Team",
+ "license": "Apache-2.0"
+}
diff --git a/js/proto3_test.js b/js/proto3_test.js
new file mode 100644
index 00000000..fab0fd44
--- /dev/null
+++ b/js/proto3_test.js
@@ -0,0 +1,329 @@
+// 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.
+
+goog.require('goog.crypt.base64');
+goog.require('goog.testing.asserts');
+
+// CommonJS-LoadFromFile: testbinary_pb proto.jspb.test
+goog.require('proto.jspb.test.ForeignMessage');
+
+// CommonJS-LoadFromFile: proto3_test_pb proto.jspb.test
+goog.require('proto.jspb.test.Proto3Enum');
+goog.require('proto.jspb.test.TestProto3');
+
+
+var BYTES = new Uint8Array([1, 2, 8, 9]);
+var BYTES_B64 = goog.crypt.base64.encodeByteArray(BYTES);
+
+
+/**
+ * Helper: compare a bytes field to an expected value
+ * @param {Uint8Array|string} arr
+ * @param {Uint8Array} expected
+ * @return {boolean}
+ */
+function bytesCompare(arr, expected) {
+ if (goog.isString(arr)) {
+ arr = goog.crypt.base64.decodeStringToUint8Array(arr);
+ }
+ if (arr.length != expected.length) {
+ return false;
+ }
+ for (var i = 0; i < arr.length; i++) {
+ if (arr[i] != expected[i]) {
+ return false;
+ }
+ }
+ return true;
+}
+
+
+describe('proto3Test', function() {
+ /**
+ * Test defaults for proto3 message fields.
+ */
+ it('testProto3FieldDefaults', function() {
+ var msg = new proto.jspb.test.TestProto3();
+
+ assertEquals(msg.getOptionalInt32(), 0);
+ assertEquals(msg.getOptionalInt64(), 0);
+ assertEquals(msg.getOptionalUint32(), 0);
+ assertEquals(msg.getOptionalUint64(), 0);
+ assertEquals(msg.getOptionalSint32(), 0);
+ assertEquals(msg.getOptionalSint64(), 0);
+ assertEquals(msg.getOptionalFixed32(), 0);
+ assertEquals(msg.getOptionalFixed64(), 0);
+ assertEquals(msg.getOptionalSfixed32(), 0);
+ assertEquals(msg.getOptionalSfixed64(), 0);
+ assertEquals(msg.getOptionalFloat(), 0);
+ assertEquals(msg.getOptionalDouble(), 0);
+ assertEquals(msg.getOptionalString(), '');
+
+ // TODO(b/26173701): when we change bytes fields default getter to return
+ // Uint8Array, we'll want to switch this assertion to match the u8 case.
+ assertEquals(typeof msg.getOptionalBytes(), 'string');
+ assertEquals(msg.getOptionalBytes_asU8() instanceof Uint8Array, true);
+ assertEquals(typeof msg.getOptionalBytes_asB64(), 'string');
+ assertEquals(msg.getOptionalBytes().length, 0);
+ assertEquals(msg.getOptionalBytes_asU8().length, 0);
+ assertEquals(msg.getOptionalBytes_asB64(), '');
+
+ assertEquals(msg.getOptionalForeignEnum(),
+ proto.jspb.test.Proto3Enum.PROTO3_FOO);
+ assertEquals(msg.getOptionalForeignMessage(), undefined);
+ assertEquals(msg.getOptionalForeignMessage(), undefined);
+
+ assertEquals(msg.getRepeatedInt32List().length, 0);
+ assertEquals(msg.getRepeatedInt64List().length, 0);
+ assertEquals(msg.getRepeatedUint32List().length, 0);
+ assertEquals(msg.getRepeatedUint64List().length, 0);
+ assertEquals(msg.getRepeatedSint32List().length, 0);
+ assertEquals(msg.getRepeatedSint64List().length, 0);
+ assertEquals(msg.getRepeatedFixed32List().length, 0);
+ assertEquals(msg.getRepeatedFixed64List().length, 0);
+ assertEquals(msg.getRepeatedSfixed32List().length, 0);
+ assertEquals(msg.getRepeatedSfixed64List().length, 0);
+ assertEquals(msg.getRepeatedFloatList().length, 0);
+ assertEquals(msg.getRepeatedDoubleList().length, 0);
+ assertEquals(msg.getRepeatedStringList().length, 0);
+ assertEquals(msg.getRepeatedBytesList().length, 0);
+ assertEquals(msg.getRepeatedForeignEnumList().length, 0);
+ assertEquals(msg.getRepeatedForeignMessageList().length, 0);
+
+ });
+
+
+ /**
+ * Test that all fields can be set and read via a serialization roundtrip.
+ */
+ it('testProto3FieldSetGet', function() {
+ var msg = new proto.jspb.test.TestProto3();
+
+ msg.setOptionalInt32(-42);
+ msg.setOptionalInt64(-0x7fffffff00000000);
+ msg.setOptionalUint32(0x80000000);
+ msg.setOptionalUint64(0xf000000000000000);
+ msg.setOptionalSint32(-100);
+ msg.setOptionalSint64(-0x8000000000000000);
+ msg.setOptionalFixed32(1234);
+ msg.setOptionalFixed64(0x1234567800000000);
+ msg.setOptionalSfixed32(-1234);
+ msg.setOptionalSfixed64(-0x1234567800000000);
+ msg.setOptionalFloat(1.5);
+ msg.setOptionalDouble(-1.5);
+ msg.setOptionalBool(true);
+ msg.setOptionalString('hello world');
+ msg.setOptionalBytes(BYTES);
+ var submsg = new proto.jspb.test.ForeignMessage();
+ submsg.setC(16);
+ msg.setOptionalForeignMessage(submsg);
+ msg.setOptionalForeignEnum(proto.jspb.test.Proto3Enum.PROTO3_BAR);
+
+ msg.setRepeatedInt32List([-42]);
+ msg.setRepeatedInt64List([-0x7fffffff00000000]);
+ msg.setRepeatedUint32List([0x80000000]);
+ msg.setRepeatedUint64List([0xf000000000000000]);
+ msg.setRepeatedSint32List([-100]);
+ msg.setRepeatedSint64List([-0x8000000000000000]);
+ msg.setRepeatedFixed32List([1234]);
+ msg.setRepeatedFixed64List([0x1234567800000000]);
+ msg.setRepeatedSfixed32List([-1234]);
+ msg.setRepeatedSfixed64List([-0x1234567800000000]);
+ msg.setRepeatedFloatList([1.5]);
+ msg.setRepeatedDoubleList([-1.5]);
+ msg.setRepeatedBoolList([true]);
+ msg.setRepeatedStringList(['hello world']);
+ msg.setRepeatedBytesList([BYTES]);
+ submsg = new proto.jspb.test.ForeignMessage();
+ submsg.setC(1000);
+ msg.setRepeatedForeignMessageList([submsg]);
+ msg.setRepeatedForeignEnumList([proto.jspb.test.Proto3Enum.PROTO3_BAR]);
+
+ msg.setOneofString('asdf');
+
+ var serialized = msg.serializeBinary();
+ msg = proto.jspb.test.TestProto3.deserializeBinary(serialized);
+
+ assertEquals(msg.getOptionalInt32(), -42);
+ assertEquals(msg.getOptionalInt64(), -0x7fffffff00000000);
+ assertEquals(msg.getOptionalUint32(), 0x80000000);
+ assertEquals(msg.getOptionalUint64(), 0xf000000000000000);
+ assertEquals(msg.getOptionalSint32(), -100);
+ assertEquals(msg.getOptionalSint64(), -0x8000000000000000);
+ assertEquals(msg.getOptionalFixed32(), 1234);
+ assertEquals(msg.getOptionalFixed64(), 0x1234567800000000);
+ assertEquals(msg.getOptionalSfixed32(), -1234);
+ assertEquals(msg.getOptionalSfixed64(), -0x1234567800000000);
+ assertEquals(msg.getOptionalFloat(), 1.5);
+ assertEquals(msg.getOptionalDouble(), -1.5);
+ assertEquals(msg.getOptionalBool(), true);
+ assertEquals(msg.getOptionalString(), 'hello world');
+ assertEquals(true, bytesCompare(msg.getOptionalBytes(), BYTES));
+ assertEquals(msg.getOptionalForeignMessage().getC(), 16);
+ assertEquals(msg.getOptionalForeignEnum(),
+ proto.jspb.test.Proto3Enum.PROTO3_BAR);
+
+ assertElementsEquals(msg.getRepeatedInt32List(), [-42]);
+ assertElementsEquals(msg.getRepeatedInt64List(), [-0x7fffffff00000000]);
+ assertElementsEquals(msg.getRepeatedUint32List(), [0x80000000]);
+ assertElementsEquals(msg.getRepeatedUint64List(), [0xf000000000000000]);
+ assertElementsEquals(msg.getRepeatedSint32List(), [-100]);
+ assertElementsEquals(msg.getRepeatedSint64List(), [-0x8000000000000000]);
+ assertElementsEquals(msg.getRepeatedFixed32List(), [1234]);
+ assertElementsEquals(msg.getRepeatedFixed64List(), [0x1234567800000000]);
+ assertElementsEquals(msg.getRepeatedSfixed32List(), [-1234]);
+ assertElementsEquals(msg.getRepeatedSfixed64List(), [-0x1234567800000000]);
+ assertElementsEquals(msg.getRepeatedFloatList(), [1.5]);
+ assertElementsEquals(msg.getRepeatedDoubleList(), [-1.5]);
+ assertElementsEquals(msg.getRepeatedBoolList(), [true]);
+ assertElementsEquals(msg.getRepeatedStringList(), ['hello world']);
+ assertEquals(msg.getRepeatedBytesList().length, 1);
+ assertEquals(true, bytesCompare(msg.getRepeatedBytesList()[0], BYTES));
+ assertEquals(msg.getRepeatedForeignMessageList().length, 1);
+ assertEquals(msg.getRepeatedForeignMessageList()[0].getC(), 1000);
+ assertElementsEquals(msg.getRepeatedForeignEnumList(),
+ [proto.jspb.test.Proto3Enum.PROTO3_BAR]);
+
+ assertEquals(msg.getOneofString(), 'asdf');
+ });
+
+
+ /**
+ * Test that oneofs continue to have a notion of field presence.
+ */
+ it('testOneofs', function() {
+ var msg = new proto.jspb.test.TestProto3();
+
+ assertEquals(msg.getOneofUint32(), 0);
+ assertEquals(msg.getOneofForeignMessage(), undefined);
+ assertEquals(msg.getOneofString(), '');
+ assertEquals(msg.getOneofBytes(), '');
+ assertFalse(msg.hasOneofUint32());
+ assertFalse(msg.hasOneofString());
+ assertFalse(msg.hasOneofBytes());
+
+ msg.setOneofUint32(42);
+ assertEquals(msg.getOneofUint32(), 42);
+ assertEquals(msg.getOneofForeignMessage(), undefined);
+ assertEquals(msg.getOneofString(), '');
+ assertEquals(msg.getOneofBytes(), '');
+ assertTrue(msg.hasOneofUint32());
+ assertFalse(msg.hasOneofString());
+ assertFalse(msg.hasOneofBytes());
+
+
+ var submsg = new proto.jspb.test.ForeignMessage();
+ msg.setOneofForeignMessage(submsg);
+ assertEquals(msg.getOneofUint32(), 0);
+ assertEquals(msg.getOneofForeignMessage(), submsg);
+ assertEquals(msg.getOneofString(), '');
+ assertEquals(msg.getOneofBytes(), '');
+ assertFalse(msg.hasOneofUint32());
+ assertFalse(msg.hasOneofString());
+ assertFalse(msg.hasOneofBytes());
+
+ msg.setOneofString('hello');
+ assertEquals(msg.getOneofUint32(), 0);
+ assertEquals(msg.getOneofForeignMessage(), undefined);
+ assertEquals(msg.getOneofString(), 'hello');
+ assertEquals(msg.getOneofBytes(), '');
+ assertFalse(msg.hasOneofUint32());
+ assertTrue(msg.hasOneofString());
+ assertFalse(msg.hasOneofBytes());
+
+ msg.setOneofBytes(goog.crypt.base64.encodeString('\u00FF\u00FF'));
+ assertEquals(msg.getOneofUint32(), 0);
+ assertEquals(msg.getOneofForeignMessage(), undefined);
+ assertEquals(msg.getOneofString(), '');
+ assertEquals(msg.getOneofBytes_asB64(),
+ goog.crypt.base64.encodeString('\u00FF\u00FF'));
+ assertFalse(msg.hasOneofUint32());
+ assertFalse(msg.hasOneofString());
+ assertTrue(msg.hasOneofBytes());
+ });
+
+
+ /**
+ * Test that "default"-valued primitive fields are not emitted on the wire.
+ */
+ it('testNoSerializeDefaults', function() {
+ var msg = new proto.jspb.test.TestProto3();
+
+ // Set each primitive to a non-default value, then back to its default, to
+ // ensure that the serialization is actually checking the value and not just
+ // whether it has ever been set.
+ msg.setOptionalInt32(42);
+ msg.setOptionalInt32(0);
+ msg.setOptionalDouble(3.14);
+ msg.setOptionalDouble(0.0);
+ msg.setOptionalBool(true);
+ msg.setOptionalBool(false);
+ msg.setOptionalString('hello world');
+ msg.setOptionalString('');
+ msg.setOptionalBytes(goog.crypt.base64.encodeString('\u00FF\u00FF'));
+ msg.setOptionalBytes('');
+ msg.setOptionalForeignMessage(new proto.jspb.test.ForeignMessage());
+ msg.setOptionalForeignMessage(null);
+ msg.setOptionalForeignEnum(proto.jspb.test.Proto3Enum.PROTO3_BAR);
+ msg.setOptionalForeignEnum(proto.jspb.test.Proto3Enum.PROTO3_FOO);
+ msg.setOneofUint32(32);
+ msg.setOneofUint32(null);
+
+
+ var serialized = msg.serializeBinary();
+ assertEquals(0, serialized.length);
+ });
+
+ /**
+ * Test that base64 string and Uint8Array are interchangeable in bytes fields.
+ */
+ it('testBytesFieldsInterop', function() {
+ var msg = new proto.jspb.test.TestProto3();
+ // Set as a base64 string and check all the getters work.
+ msg.setOptionalBytes(BYTES_B64);
+ assertTrue(bytesCompare(msg.getOptionalBytes_asU8(), BYTES));
+ assertTrue(bytesCompare(msg.getOptionalBytes_asB64(), BYTES));
+ assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES));
+
+ // Test binary serialize round trip doesn't break it.
+ msg = proto.jspb.test.TestProto3.deserializeBinary(msg.serializeBinary());
+ assertTrue(bytesCompare(msg.getOptionalBytes_asU8(), BYTES));
+ assertTrue(bytesCompare(msg.getOptionalBytes_asB64(), BYTES));
+ assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES));
+
+ msg = new proto.jspb.test.TestProto3();
+ // Set as a Uint8Array and check all the getters work.
+ msg.setOptionalBytes(BYTES);
+ assertTrue(bytesCompare(msg.getOptionalBytes_asU8(), BYTES));
+ assertTrue(bytesCompare(msg.getOptionalBytes_asB64(), BYTES));
+ assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES));
+
+ });
+});
diff --git a/js/proto3_test.proto b/js/proto3_test.proto
new file mode 100644
index 00000000..acb67164
--- /dev/null
+++ b/js/proto3_test.proto
@@ -0,0 +1,89 @@
+// 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.
+
+syntax = "proto3";
+
+import "testbinary.proto";
+
+package jspb.test;
+
+message TestProto3 {
+ int32 optional_int32 = 1;
+ int64 optional_int64 = 2;
+ uint32 optional_uint32 = 3;
+ uint64 optional_uint64 = 4;
+ sint32 optional_sint32 = 5;
+ sint64 optional_sint64 = 6;
+ fixed32 optional_fixed32 = 7;
+ fixed64 optional_fixed64 = 8;
+ sfixed32 optional_sfixed32 = 9;
+ sfixed64 optional_sfixed64 = 10;
+ float optional_float = 11;
+ double optional_double = 12;
+ bool optional_bool = 13;
+ string optional_string = 14;
+ bytes optional_bytes = 15;
+
+ ForeignMessage optional_foreign_message = 19;
+ Proto3Enum optional_foreign_enum = 22;
+
+ repeated int32 repeated_int32 = 31;
+ repeated int64 repeated_int64 = 32;
+ repeated uint32 repeated_uint32 = 33;
+ repeated uint64 repeated_uint64 = 34;
+ repeated sint32 repeated_sint32 = 35;
+ repeated sint64 repeated_sint64 = 36;
+ repeated fixed32 repeated_fixed32 = 37;
+ repeated fixed64 repeated_fixed64 = 38;
+ repeated sfixed32 repeated_sfixed32 = 39;
+ repeated sfixed64 repeated_sfixed64 = 40;
+ repeated float repeated_float = 41;
+ repeated double repeated_double = 42;
+ repeated bool repeated_bool = 43;
+ repeated string repeated_string = 44;
+ repeated bytes repeated_bytes = 45;
+
+ repeated ForeignMessage repeated_foreign_message = 49;
+ repeated Proto3Enum repeated_foreign_enum = 52;
+
+
+ oneof oneof_field {
+ uint32 oneof_uint32 = 111;
+ ForeignMessage oneof_foreign_message = 112;
+ string oneof_string = 113;
+ bytes oneof_bytes = 114;
+ }
+}
+
+enum Proto3Enum {
+ PROTO3_FOO = 0;
+ PROTO3_BAR = 1;
+ PROTO3_BAZ = 2;
+}
diff --git a/js/test.proto b/js/test.proto
new file mode 100644
index 00000000..937ffb89
--- /dev/null
+++ b/js/test.proto
@@ -0,0 +1,236 @@
+// 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.
+
+// Author: mwr@google.com (Mark Rawling)
+
+syntax = "proto2";
+
+option java_package = "com.google.apps.jspb.proto";
+option java_multiple_files = true;
+
+import "google/protobuf/descriptor.proto";
+
+package jspb.test;
+
+message Empty {
+}
+
+enum OuterEnum {
+ FOO = 1;
+ BAR = 2;
+}
+
+message EnumContainer {
+ optional OuterEnum outer_enum = 1;
+}
+
+message Simple1 {
+ required string a_string = 1;
+ repeated string a_repeated_string = 2;
+ optional bool a_boolean = 3;
+}
+
+// A message that differs from Simple1 only by name
+message Simple2 {
+ required string a_string = 1;
+ repeated string a_repeated_string = 2;
+}
+
+message SpecialCases {
+ required string normal = 1;
+ // Examples of Js reserved names that are converted to pb_<name>.
+ required string default = 2;
+ required string function = 3;
+ required string var = 4;
+}
+
+message OptionalFields {
+ message Nested {
+ optional int32 an_int = 1;
+ }
+ optional string a_string = 1;
+ required bool a_bool = 2;
+ optional Nested a_nested_message = 3;
+ repeated Nested a_repeated_message = 4;
+ repeated string a_repeated_string = 5;
+}
+
+message HasExtensions {
+ optional string str1 = 1;
+ optional string str2 = 2;
+ optional string str3 = 3;
+ extensions 10 to max;
+}
+
+message Complex {
+ message Nested {
+ required int32 an_int = 2;
+ }
+ required string a_string = 1;
+ required bool an_out_of_order_bool = 9;
+ optional Nested a_nested_message = 4;
+ repeated Nested a_repeated_message = 5;
+ repeated string a_repeated_string = 7;
+}
+
+message OuterMessage {
+ // Make sure this doesn't conflict with the other Complex message.
+ message Complex {
+ optional int32 inner_complex_field = 1;
+ }
+}
+
+message IsExtension {
+ extend HasExtensions {
+ optional IsExtension ext_field = 100;
+ }
+ optional string ext1 = 1;
+
+ // Extensions of proto2 Descriptor messages will be ignored.
+ extend google.protobuf.EnumOptions {
+ optional string simple_option = 42113038;
+ }
+}
+
+message IndirectExtension {
+ extend HasExtensions {
+ optional Simple1 simple = 101;
+ optional string str = 102;
+ repeated string repeated_str = 103;
+ repeated Simple1 repeated_simple = 104;
+ }
+}
+
+extend HasExtensions {
+ optional Simple1 simple1 = 105;
+}
+
+message DefaultValues {
+ enum Enum {
+ E1 = 13;
+ E2 = 77;
+ }
+ optional string string_field = 1 [default="default<>\'\"abc"];
+ optional bool bool_field = 2 [default=true];
+ optional int64 int_field = 3 [default=11];
+ optional Enum enum_field = 4 [default=E1];
+ optional string empty_field = 6 [default=""];
+ optional bytes bytes_field = 8 [default="moo"]; // Base64 encoding is "bW9v"
+}
+
+message FloatingPointFields {
+ optional float optional_float_field = 1;
+ required float required_float_field = 2;
+ repeated float repeated_float_field = 3;
+ optional float default_float_field = 4 [default = 2.0];
+ optional double optional_double_field = 5;
+ required double required_double_field = 6;
+ repeated double repeated_double_field = 7;
+ optional double default_double_field = 8 [default = 2.0];
+}
+
+message TestClone {
+ optional string str = 1;
+ optional Simple1 simple1 = 3;
+ repeated Simple1 simple2 = 5;
+ optional bytes bytes_field = 6;
+ optional string unused = 7;
+ extensions 10 to max;
+}
+
+message CloneExtension {
+ extend TestClone {
+ optional CloneExtension ext_field = 100;
+ }
+ optional string ext = 2;
+}
+
+message TestGroup {
+ repeated group RepeatedGroup = 1 {
+ required string id = 1;
+ repeated bool some_bool = 2;
+ }
+ required group RequiredGroup = 2 {
+ required string id = 1;
+ }
+ optional group OptionalGroup = 3 {
+ required string id = 1;
+ }
+ optional string id = 4;
+ required Simple2 required_simple = 5;
+ optional Simple2 optional_simple = 6;
+}
+
+message TestGroup1 {
+ optional TestGroup.RepeatedGroup group = 1;
+}
+
+message TestReservedNames {
+ optional int32 extension = 1;
+ extensions 10 to max;
+}
+
+message TestReservedNamesExtension {
+ extend TestReservedNames {
+ optional int32 foo = 10;
+ }
+}
+
+message TestMessageWithOneof {
+
+ oneof partial_oneof {
+ string pone = 3;
+ string pthree = 5;
+ }
+
+ oneof recursive_oneof {
+ TestMessageWithOneof rone = 6;
+ string rtwo = 7;
+ }
+
+ optional bool normal_field = 8;
+ repeated string repeated_field = 9;
+
+ oneof default_oneof_a {
+ int32 aone = 10 [default = 1234];
+ int32 atwo = 11;
+ }
+
+ oneof default_oneof_b {
+ int32 bone = 12;
+ int32 btwo = 13 [default = 1234];
+ }
+}
+
+message TestEndsWithBytes {
+ optional int32 value = 1;
+ optional bytes data = 2;
+}
+
diff --git a/js/test2.proto b/js/test2.proto
new file mode 100644
index 00000000..44e55eff
--- /dev/null
+++ b/js/test2.proto
@@ -0,0 +1,54 @@
+// 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.
+
+syntax = "proto2";
+
+option java_package = "com.google.apps.jspb.proto";
+option java_multiple_files = true;
+
+package jspb.test;
+
+message TestExtensionsMessage {
+ optional int32 intfield = 1;
+ extensions 100 to max;
+}
+
+message ExtensionMessage {
+ extend TestExtensionsMessage {
+ optional ExtensionMessage ext_field = 100;
+ }
+ optional string ext1 = 1;
+}
+
+// Floating extensions are only supported when generating a _lib.js library.
+extend TestExtensionsMessage {
+ optional ExtensionMessage floating_msg_field = 101;
+ optional string floating_str_field = 102;
+}
diff --git a/js/test3.proto b/js/test3.proto
new file mode 100644
index 00000000..940a552e
--- /dev/null
+++ b/js/test3.proto
@@ -0,0 +1,53 @@
+// 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.
+
+syntax = "proto2";
+
+option java_package = "com.google.apps.jspb.proto";
+option java_multiple_files = true;
+
+package jspb.exttest;
+
+message TestExtensionsMessage {
+ optional int32 intfield = 1;
+ extensions 100 to max;
+}
+
+message ExtensionMessage {
+ extend TestExtensionsMessage {
+ optional ExtensionMessage ext_field = 100;
+ }
+ optional string ext1 = 1;
+}
+
+extend TestExtensionsMessage {
+ optional ExtensionMessage floating_msg_field = 101;
+ optional string floating_str_field = 102;
+}
diff --git a/src/google/protobuf/compiler/cpp/test_large_enum_value.proto b/js/test4.proto
index cb6ca1b1..cf2451e9 100644
--- a/src/google/protobuf/compiler/cpp/test_large_enum_value.proto
+++ b/js/test4.proto
@@ -28,16 +28,15 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Test that proto2 compiler can generate valid code when the enum value
-// is INT_MAX. Note that this is a compile-only test and this proto is not
-// referenced in any C++ code.
syntax = "proto2";
-package protobuf_unittest;
+option java_package = "com.google.apps.jspb.proto";
+option java_multiple_files = true;
-message TestLargeEnumValue {
- enum EnumWithLargeValue {
- VALUE_1 = 1;
- VALUE_MAX = 0x7fffffff;
- }
+package jspb.exttest;
+
+import "test3.proto";
+
+extend TestExtensionsMessage {
+ optional ExtensionMessage floating_msg_field_two = 103;
}
diff --git a/js/test5.proto b/js/test5.proto
new file mode 100644
index 00000000..34979517
--- /dev/null
+++ b/js/test5.proto
@@ -0,0 +1,44 @@
+// 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.
+
+syntax = "proto2";
+
+option java_package = "com.google.apps.jspb.proto";
+option java_multiple_files = true;
+
+package jspb.exttest.beta;
+
+message TestBetaExtensionsMessage {
+ extensions 100 to max;
+}
+
+extend TestBetaExtensionsMessage {
+ optional string floating_str_field = 101;
+}
diff --git a/js/test_bootstrap.js b/js/test_bootstrap.js
new file mode 100644
index 00000000..9d00a1c4
--- /dev/null
+++ b/js/test_bootstrap.js
@@ -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.
+
+/**
+ * @fileoverview Sets flags for uncompiled JSUnit tests.
+ */
+
+/**
+ * Set uncompiled flags.
+ */
+var CLOSURE_DEFINES = {
+ // Enable the fromObject method on the message class.
+ 'jspb.Message.GENERATE_FROM_OBJECT': true
+};
diff --git a/js/testbinary.proto b/js/testbinary.proto
new file mode 100644
index 00000000..116f17fb
--- /dev/null
+++ b/js/testbinary.proto
@@ -0,0 +1,212 @@
+// 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.
+
+// LINT: ALLOW_GROUPS
+
+syntax = "proto2";
+
+
+package jspb.test;
+
+// These types are borrowed from `unittest.proto` in the protobuf tree. We want
+// to ensure that the binary-format support will handle all field types
+// properly.
+message TestAllTypes {
+ optional int32 optional_int32 = 1;
+ optional int64 optional_int64 = 2;
+ optional uint32 optional_uint32 = 3;
+ optional uint64 optional_uint64 = 4;
+ optional sint32 optional_sint32 = 5;
+ optional sint64 optional_sint64 = 6;
+ optional fixed32 optional_fixed32 = 7;
+ optional fixed64 optional_fixed64 = 8;
+ optional sfixed32 optional_sfixed32 = 9;
+ optional sfixed64 optional_sfixed64 = 10;
+ optional float optional_float = 11;
+ optional double optional_double = 12;
+ optional bool optional_bool = 13;
+ optional string optional_string = 14;
+ optional bytes optional_bytes = 15;
+ optional group OptionalGroup = 16 {
+ optional int32 a = 17;
+ }
+
+ optional ForeignMessage optional_foreign_message = 19;
+ optional ForeignEnum optional_foreign_enum = 22;
+
+ // Repeated
+ repeated int32 repeated_int32 = 31;
+ repeated int64 repeated_int64 = 32;
+ repeated uint32 repeated_uint32 = 33;
+ repeated uint64 repeated_uint64 = 34;
+ repeated sint32 repeated_sint32 = 35;
+ repeated sint64 repeated_sint64 = 36;
+ repeated fixed32 repeated_fixed32 = 37;
+ repeated fixed64 repeated_fixed64 = 38;
+ repeated sfixed32 repeated_sfixed32 = 39;
+ repeated sfixed64 repeated_sfixed64 = 40;
+ repeated float repeated_float = 41;
+ repeated double repeated_double = 42;
+ repeated bool repeated_bool = 43;
+ repeated string repeated_string = 44;
+ repeated bytes repeated_bytes = 45;
+
+ repeated group RepeatedGroup = 46 {
+ optional int32 a = 47;
+ }
+
+ repeated ForeignMessage repeated_foreign_message = 49;
+ repeated ForeignEnum repeated_foreign_enum = 52;
+
+ // Packed repeated
+ repeated int32 packed_repeated_int32 = 61 [packed=true];
+ repeated int64 packed_repeated_int64 = 62 [packed=true];
+ repeated uint32 packed_repeated_uint32 = 63 [packed=true];
+ repeated uint64 packed_repeated_uint64 = 64 [packed=true];
+ repeated sint32 packed_repeated_sint32 = 65 [packed=true];
+ repeated sint64 packed_repeated_sint64 = 66 [packed=true];
+ repeated fixed32 packed_repeated_fixed32 = 67 [packed=true];
+ repeated fixed64 packed_repeated_fixed64 = 68 [packed=true];
+ repeated sfixed32 packed_repeated_sfixed32 = 69 [packed=true];
+ repeated sfixed64 packed_repeated_sfixed64 = 70 [packed=true];
+ repeated float packed_repeated_float = 71 [packed=true];
+ repeated double packed_repeated_double = 72 [packed=true];
+ repeated bool packed_repeated_bool = 73 [packed=true];
+
+ oneof oneof_field {
+ uint32 oneof_uint32 = 111;
+ ForeignMessage oneof_foreign_message = 112;
+ string oneof_string = 113;
+ bytes oneof_bytes = 114;
+ }
+
+}
+
+message ForeignMessage {
+ optional int32 c = 1;
+}
+
+enum ForeignEnum {
+ FOREIGN_FOO = 4;
+ FOREIGN_BAR = 5;
+ FOREIGN_BAZ = 6;
+}
+
+message TestExtendable {
+ extensions 1 to max;
+}
+
+message ExtendsWithMessage {
+ extend TestExtendable {
+ optional ExtendsWithMessage optional_extension = 19;
+ repeated ExtendsWithMessage repeated_extension = 49;
+ }
+ optional int32 foo = 1;
+}
+
+extend TestExtendable {
+ optional int32 extend_optional_int32 = 1;
+ optional int64 extend_optional_int64 = 2;
+ optional uint32 extend_optional_uint32 = 3;
+ optional uint64 extend_optional_uint64 = 4;
+ optional sint32 extend_optional_sint32 = 5;
+ optional sint64 extend_optional_sint64 = 6;
+ optional fixed32 extend_optional_fixed32 = 7;
+ optional fixed64 extend_optional_fixed64 = 8;
+ optional sfixed32 extend_optional_sfixed32 = 9;
+ optional sfixed64 extend_optional_sfixed64 = 10;
+ optional float extend_optional_float = 11;
+ optional double extend_optional_double = 12;
+ optional bool extend_optional_bool = 13;
+ optional string extend_optional_string = 14;
+ optional bytes extend_optional_bytes = 15;
+ optional ForeignEnum extend_optional_foreign_enum = 22;
+
+ repeated int32 extend_repeated_int32 = 31;
+ repeated int64 extend_repeated_int64 = 32;
+ repeated uint32 extend_repeated_uint32 = 33;
+ repeated uint64 extend_repeated_uint64 = 34;
+ repeated sint32 extend_repeated_sint32 = 35;
+ repeated sint64 extend_repeated_sint64 = 36;
+ repeated fixed32 extend_repeated_fixed32 = 37;
+ repeated fixed64 extend_repeated_fixed64 = 38;
+ repeated sfixed32 extend_repeated_sfixed32 = 39;
+ repeated sfixed64 extend_repeated_sfixed64 = 40;
+ repeated float extend_repeated_float = 41;
+ repeated double extend_repeated_double = 42;
+ repeated bool extend_repeated_bool = 43;
+ repeated string extend_repeated_string = 44;
+ repeated bytes extend_repeated_bytes = 45;
+ repeated ForeignEnum extend_repeated_foreign_enum = 52;
+
+ repeated int32 extend_packed_repeated_int32 = 61 [packed=true];
+ repeated int64 extend_packed_repeated_int64 = 62 [packed=true];
+ repeated uint32 extend_packed_repeated_uint32 = 63 [packed=true];
+ repeated uint64 extend_packed_repeated_uint64 = 64 [packed=true];
+ repeated sint32 extend_packed_repeated_sint32 = 65 [packed=true];
+ repeated sint64 extend_packed_repeated_sint64 = 66 [packed=true];
+ repeated fixed32 extend_packed_repeated_fixed32 = 67 [packed=true];
+ repeated fixed64 extend_packed_repeated_fixed64 = 68 [packed=true];
+ repeated sfixed32 extend_packed_repeated_sfixed32 = 69 [packed=true];
+ repeated sfixed64 extend_packed_repeated_sfixed64 = 70 [packed=true];
+ repeated float extend_packed_repeated_float = 71 [packed=true];
+ repeated double extend_packed_repeated_double = 72 [packed=true];
+ repeated bool extend_packed_repeated_bool = 73 [packed=true];
+ repeated ForeignEnum extend_packed_repeated_foreign_enum = 82
+ [packed=true];
+
+}
+
+message TestMapFields {
+ map<string, string> map_string_string = 1;
+ map<string, int32> map_string_int32 = 2;
+ map<string, int64> map_string_int64 = 3;
+ map<string, bool> map_string_bool = 4;
+ map<string, double> map_string_double = 5;
+ map<string, MapValueEnum> map_string_enum = 6;
+ map<string, MapValueMessage> map_string_msg = 7;
+
+ map<int32, string> map_int32_string = 8;
+ map<int64, string> map_int64_string = 9;
+ map<bool, string> map_bool_string = 10;
+
+ optional TestMapFields test_map_fields = 11;
+ map<string, TestMapFields> map_string_testmapfields = 12;
+}
+
+enum MapValueEnum {
+ MAP_VALUE_FOO = 0;
+ MAP_VALUE_BAR = 1;
+ MAP_VALUE_BAZ = 2;
+}
+
+message MapValueMessage {
+ optional int32 foo = 1;
+}
diff --git a/js/testempty.proto b/js/testempty.proto
new file mode 100644
index 00000000..960bce4e
--- /dev/null
+++ b/js/testempty.proto
@@ -0,0 +1,34 @@
+// 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.
+
+syntax = "proto2";
+
+package javatests.com.google.apps.jspb;
+
diff --git a/m4/acx_check_suncc.m4 b/m4/acx_check_suncc.m4
index 89185932..8bc0a890 100644
--- a/m4/acx_check_suncc.m4
+++ b/m4/acx_check_suncc.m4
@@ -42,7 +42,6 @@ AC_DEFUN([ACX_CHECK_SUNCC],[
AS_IF([test "x$ac_enable_64bit" = "xyes"],[
- AC_DEFINE([SOLARIS_64BIT_ENABLED], [1], [64bit enabled])
AS_IF([test "x$libdir" = "x\${exec_prefix}/lib"],[
dnl The user hasn't overridden the default libdir, so we'll
dnl the dir suffix to match solaris 32/64-bit policy
@@ -52,17 +51,13 @@ AC_DEFUN([ACX_CHECK_SUNCC],[
dnl This should just be set in CPPFLAGS and in LDFLAGS, but libtool
dnl does the wrong thing if you don't put it into CXXFLAGS. sigh.
dnl (It also needs it in CFLAGS, or it does a different wrong thing!)
- AS_IF([test "x${ac_cv_env_CXXFLAGS_set}" = "x"],[
- CXXFLAGS="${CXXFLAGS} -m64"
- ac_cv_env_CXXFLAGS_set=set
- ac_cv_env_CXXFLAGS_value='-m64'
- ])
+ CXXFLAGS="${CXXFLAGS} -m64"
+ ac_cv_env_CXXFLAGS_set=set
+ ac_cv_env_CXXFLAGS_value='-m64'
- AS_IF([test "x${ac_cv_env_CFLAGS_set}" = "x"],[
- CFLAGS="${CFLAGS} -m64"
- ac_cv_env_CFLAGS_set=set
- ac_cv_env_CFLAGS_value='-m64'
- ])
+ CFLAGS="${CFLAGS} -m64"
+ ac_cv_env_CFLAGS_set=set
+ ac_cv_env_CFLAGS_value='-m64'
AS_IF([test "$target_cpu" = "sparc" -a "x$SUNCC" = "xyes" ],[
CXXFLAGS="-xmemalign=8s ${CXXFLAGS}"
diff --git a/m4/stl_hash.m4 b/m4/stl_hash.m4
index 0722b14a..d7def1af 100644
--- a/m4/stl_hash.m4
+++ b/m4/stl_hash.m4
@@ -4,8 +4,7 @@
# include AC_TRY_COMPILE for all the combinations we've seen in the
# wild. We define HASH_MAP_H to the location of the header file, and
# HASH_NAMESPACE to the namespace the class (unordered_map or
-# hash_map) is in. We define HAVE_UNORDERED_MAP if the class we found
-# is named unordered_map, or leave it undefined if not.
+# hash_map) is in.
# This also checks if unordered map exists.
AC_DEFUN([AC_CXX_STL_HASH],
diff --git a/objectivec/.gitignore b/objectivec/.gitignore
new file mode 100644
index 00000000..f786ffce
--- /dev/null
+++ b/objectivec/.gitignore
@@ -0,0 +1,23 @@
+## Build generated
+build/
+DerivedData/
+
+## Various settings
+*.pbxuser
+!default.pbxuser
+*.mode1v3
+!default.mode1v3
+*.mode2v3
+!default.mode2v3
+*.perspectivev3
+!default.perspectivev3
+xcuserdata/
+
+## Other
+*.moved-aside
+*.xccheckout
+*.xcscmblueprint
+
+## Obj-C/Swift specific
+*.hmap
+*.ipa
diff --git a/objectivec/DevTools/compile_testing_protos.sh b/objectivec/DevTools/compile_testing_protos.sh
index e9c5fe61..82953130 100755
--- a/objectivec/DevTools/compile_testing_protos.sh
+++ b/objectivec/DevTools/compile_testing_protos.sh
@@ -67,29 +67,36 @@ fi
# Ensure the output dir exists
mkdir -p "${OUTPUT_DIR}/google/protobuf"
-CORE_PROTO_FILES=( \
- src/google/protobuf/unittest_arena.proto \
- src/google/protobuf/unittest_custom_options.proto \
- src/google/protobuf/unittest_enormous_descriptor.proto \
- src/google/protobuf/unittest_embed_optimize_for.proto \
- src/google/protobuf/unittest_empty.proto \
- src/google/protobuf/unittest_import.proto \
- src/google/protobuf/unittest_import_lite.proto \
- src/google/protobuf/unittest_lite.proto \
- src/google/protobuf/unittest_mset.proto \
- src/google/protobuf/unittest_mset_wire_format.proto \
- src/google/protobuf/unittest_no_arena.proto \
- src/google/protobuf/unittest_no_arena_import.proto \
- src/google/protobuf/unittest_no_generic_services.proto \
- src/google/protobuf/unittest_optimize_for.proto \
- src/google/protobuf/unittest.proto \
- src/google/protobuf/unittest_import_public.proto \
- src/google/protobuf/unittest_import_public_lite.proto \
- src/google/protobuf/unittest_drop_unknown_fields.proto \
- src/google/protobuf/unittest_preserve_unknown_enum.proto \
- src/google/protobuf/map_lite_unittest.proto \
- src/google/protobuf/map_proto2_unittest.proto \
- src/google/protobuf/map_unittest.proto \
+CORE_PROTO_FILES=(
+ src/google/protobuf/unittest_arena.proto
+ src/google/protobuf/unittest_custom_options.proto
+ src/google/protobuf/unittest_enormous_descriptor.proto
+ src/google/protobuf/unittest_embed_optimize_for.proto
+ src/google/protobuf/unittest_empty.proto
+ src/google/protobuf/unittest_import.proto
+ src/google/protobuf/unittest_import_lite.proto
+ src/google/protobuf/unittest_lite.proto
+ src/google/protobuf/unittest_mset.proto
+ src/google/protobuf/unittest_mset_wire_format.proto
+ src/google/protobuf/unittest_no_arena.proto
+ src/google/protobuf/unittest_no_arena_import.proto
+ src/google/protobuf/unittest_no_generic_services.proto
+ src/google/protobuf/unittest_optimize_for.proto
+ src/google/protobuf/unittest.proto
+ src/google/protobuf/unittest_import_public.proto
+ src/google/protobuf/unittest_import_public_lite.proto
+ src/google/protobuf/unittest_drop_unknown_fields.proto
+ src/google/protobuf/unittest_preserve_unknown_enum.proto
+ src/google/protobuf/map_lite_unittest.proto
+ src/google/protobuf/map_proto2_unittest.proto
+ src/google/protobuf/map_unittest.proto
+)
+
+# The unittest_custom_options.proto extends the messages in descriptor.proto
+# so we build it in to test extending in general. The library doesn't provide
+# a descriptor as it doesn't use the classes/enums.
+CORE_PROTO_FILES+=(
+ src/google/protobuf/descriptor.proto
)
compile_proto() {
@@ -104,12 +111,12 @@ for a_proto in "${CORE_PROTO_FILES[@]}" ; do
compile_proto "${a_proto}"
done
-OBJC_PROTO_FILES=( \
- objectivec/Tests/unittest_cycle.proto \
- objectivec/Tests/unittest_runtime_proto2.proto \
- objectivec/Tests/unittest_runtime_proto3.proto \
- objectivec/Tests/unittest_objc.proto \
- objectivec/Tests/unittest_objc_startup.proto \
+OBJC_PROTO_FILES=(
+ objectivec/Tests/unittest_cycle.proto
+ objectivec/Tests/unittest_runtime_proto2.proto
+ objectivec/Tests/unittest_runtime_proto3.proto
+ objectivec/Tests/unittest_objc.proto
+ objectivec/Tests/unittest_objc_startup.proto
)
for a_proto in "${OBJC_PROTO_FILES[@]}" ; do
diff --git a/objectivec/DevTools/full_mac_build.sh b/objectivec/DevTools/full_mac_build.sh
index 709aae0a..89240ee0 100755
--- a/objectivec/DevTools/full_mac_build.sh
+++ b/objectivec/DevTools/full_mac_build.sh
@@ -26,8 +26,9 @@ OPTIONS:
Issue a clean before the normal build.
-a, --autogen
Start by rerunning autogen & configure.
- -r, --regenerate-cpp-descriptors
- The descriptor.proto is checked in generated, cause it to regenerate.
+ -r, --regenerate-descriptors
+ Run generate_descriptor_proto.sh to regenerate all the checked in
+ proto sources.
-j #, --jobs #
Force the number of parallel jobs (useful for debugging build issues).
--core-only
@@ -36,6 +37,10 @@ OPTIONS:
Skip the invoke of Xcode to test the runtime on both iOS and OS X.
--skip-xcode-ios
Skip the invoke of Xcode to test the runtime on iOS.
+ --skip-xcode-debug
+ Skip the Xcode Debug configuration.
+ --skip-xcode-release
+ Skip the Xcode Release configuration.
--skip-xcode-osx
Skip the invoke of Xcode to test the runtime on OS X.
--skip-objc-conformance
@@ -65,16 +70,18 @@ wrapped_make() {
}
NUM_MAKE_JOBS=$(/usr/sbin/sysctl -n hw.ncpu)
-if [[ "${NUM_MAKE_JOBS}" -lt 4 ]] ; then
- NUM_MAKE_JOBS=4
+if [[ "${NUM_MAKE_JOBS}" -lt 2 ]] ; then
+ NUM_MAKE_JOBS=2
fi
DO_AUTOGEN=no
DO_CLEAN=no
-REGEN_CPP_DESCRIPTORS=no
+REGEN_DESCRIPTORS=no
CORE_ONLY=no
DO_XCODE_IOS_TESTS=yes
DO_XCODE_OSX_TESTS=yes
+DO_XCODE_DEBUG=yes
+DO_XCODE_RELEASE=yes
DO_OBJC_CONFORMANCE_TESTS=yes
while [[ $# != 0 ]]; do
case "${1}" in
@@ -88,8 +95,8 @@ while [[ $# != 0 ]]; do
-a | --autogen )
DO_AUTOGEN=yes
;;
- -r | --regenerate-cpp-descriptors )
- REGEN_CPP_DESCRIPTORS=yes
+ -r | --regenerate-descriptors )
+ REGEN_DESCRIPTORS=yes
;;
-j | --jobs )
shift
@@ -108,6 +115,12 @@ while [[ $# != 0 ]]; do
--skip-xcode-osx )
DO_XCODE_OSX_TESTS=no
;;
+ --skip-xcode-debug )
+ DO_XCODE_DEBUG=no
+ ;;
+ --skip-xcode-release )
+ DO_XCODE_RELEASE=no
+ ;;
--skip-objc-conformance )
DO_OBJC_CONFORMANCE_TESTS=no
;;
@@ -150,8 +163,12 @@ if [[ "${DO_CLEAN}" == "yes" ]] ; then
-project objectivec/ProtocolBuffers_iOS.xcodeproj
-scheme ProtocolBuffers
)
- "${XCODEBUILD_CLEAN_BASE_IOS[@]}" -configuration Debug clean
- "${XCODEBUILD_CLEAN_BASE_IOS[@]}" -configuration Release clean
+ if [[ "${DO_XCODE_DEBUG}" == "yes" ]] ; then
+ "${XCODEBUILD_CLEAN_BASE_IOS[@]}" -configuration Debug clean
+ fi
+ if [[ "${DO_XCODE_RELEASE}" == "yes" ]] ; then
+ "${XCODEBUILD_CLEAN_BASE_IOS[@]}" -configuration Release clean
+ fi
fi
if [[ "${DO_XCODE_OSX_TESTS}" == "yes" ]] ; then
XCODEBUILD_CLEAN_BASE_OSX=(
@@ -159,13 +176,17 @@ if [[ "${DO_CLEAN}" == "yes" ]] ; then
-project objectivec/ProtocolBuffers_OSX.xcodeproj
-scheme ProtocolBuffers
)
- "${XCODEBUILD_CLEAN_BASE_OSX[@]}" -configuration Debug clean
- "${XCODEBUILD_CLEAN_BASE_OSX[@]}" -configuration Release clean
+ if [[ "${DO_XCODE_DEBUG}" == "yes" ]] ; then
+ "${XCODEBUILD_CLEAN_BASE_OSX[@]}" -configuration Debug clean
+ fi
+ if [[ "${DO_XCODE_RELEASE}" == "yes" ]] ; then
+ "${XCODEBUILD_CLEAN_BASE_OSX[@]}" -configuration Release clean
+ fi
fi
fi
-if [[ "${REGEN_CPP_DESCRIPTORS}" == "yes" ]] ; then
- header "Regenerating the C++ descriptor sources."
+if [[ "${REGEN_DESCRIPTORS}" == "yes" ]] ; then
+ header "Regenerating the descriptor sources."
./generate_descriptor_proto.sh -j "${NUM_MAKE_JOBS}"
fi
@@ -184,29 +205,8 @@ else
cd ..
fi
-header "Ensuring the ObjC descriptors are current."
-# Find the newest input file (protos, compiler, and the generator script).
-# (these patterns catch some extra stuff, but better to over sample than under)
-readonly NewestInput=$(find \
- src/google/protobuf/*.proto \
- src/.libs src/*.la src/protoc \
- objectivec/generate_descriptors_proto.sh \
- -type f -print0 \
- | xargs -0 stat -f "%m %N" \
- | sort -n | tail -n1 | cut -f2- -d" ")
-# Find the oldest output file.
-readonly OldestOutput=$(find \
- "${ProtoRootDir}/objectivec/google" \
- -type f -print0 \
- | xargs -0 stat -f "%m %N" \
- | sort -n -r | tail -n1 | cut -f2- -d" ")
-# If the newest input is newer than the oldest output, regenerate.
-if [[ "${NewestInput}" -nt "${OldestOutput}" ]] ; then
- echo ">> Newest input is newer than oldest output, regenerating."
- objectivec/generate_descriptors_proto.sh -j "${NUM_MAKE_JOBS}"
-else
- echo ">> Newest input is older than oldest output, no need to regenerating."
-fi
+# Ensure the WKT sources checked in are current.
+objectivec/generate_well_known_types.sh --check-only -j "${NUM_MAKE_JOBS}"
header "Checking on the ObjC Runtime Code"
objectivec/DevTools/pddm_tests.py
@@ -234,7 +234,7 @@ if [[ "${DO_XCODE_IOS_TESTS}" == "yes" ]] ; then
echo "ERROR: Xcode 6.3/6.4 no longer supported for building, please use 7.0 or higher." 1>&2
exit 10
;;
- 7.* )
+ 7.1* )
XCODEBUILD_TEST_BASE_IOS+=(
-destination "platform=iOS Simulator,name=iPhone 4s,OS=8.1" # 32bit
-destination "platform=iOS Simulator,name=iPhone 6,OS=9.0" # 64bit
@@ -242,15 +242,35 @@ if [[ "${DO_XCODE_IOS_TESTS}" == "yes" ]] ; then
-destination "platform=iOS Simulator,name=iPad Air,OS=9.0" # 64bit
)
;;
+ 7.2* )
+ XCODEBUILD_TEST_BASE_IOS+=(
+ -destination "platform=iOS Simulator,name=iPhone 4s,OS=8.1" # 32bit
+ -destination "platform=iOS Simulator,name=iPhone 6,OS=9.2" # 64bit
+ -destination "platform=iOS Simulator,name=iPad 2,OS=8.1" # 32bit
+ -destination "platform=iOS Simulator,name=iPad Air,OS=9.2" # 64bit
+ )
+ ;;
+ 7.3* )
+ XCODEBUILD_TEST_BASE_IOS+=(
+ -destination "platform=iOS Simulator,name=iPhone 4s,OS=8.1" # 32bit
+ -destination "platform=iOS Simulator,name=iPhone 6,OS=9.3" # 64bit
+ -destination "platform=iOS Simulator,name=iPad 2,OS=8.1" # 32bit
+ -destination "platform=iOS Simulator,name=iPad Air,OS=9.3" # 64bit
+ )
+ ;;
* )
echo "Time to update the simulator targets for Xcode ${XCODE_VERSION}"
exit 2
;;
esac
- header "Doing Xcode iOS build/tests - Debug"
- "${XCODEBUILD_TEST_BASE_IOS[@]}" -configuration Debug test
- header "Doing Xcode iOS build/tests - Release"
- "${XCODEBUILD_TEST_BASE_IOS[@]}" -configuration Release test
+ if [[ "${DO_XCODE_DEBUG}" == "yes" ]] ; then
+ header "Doing Xcode iOS build/tests - Debug"
+ "${XCODEBUILD_TEST_BASE_IOS[@]}" -configuration Debug test
+ fi
+ if [[ "${DO_XCODE_RELEASE}" == "yes" ]] ; then
+ header "Doing Xcode iOS build/tests - Release"
+ "${XCODEBUILD_TEST_BASE_IOS[@]}" -configuration Release test
+ fi
# Don't leave the simulator in the developer's face.
killall "${IOS_SIMULATOR_NAME}"
fi
@@ -262,13 +282,18 @@ if [[ "${DO_XCODE_OSX_TESTS}" == "yes" ]] ; then
# Since the ObjC 2.0 Runtime is required, 32bit OS X isn't supported.
-destination "platform=OS X,arch=x86_64" # 64bit
)
- header "Doing Xcode OS X build/tests - Debug"
- "${XCODEBUILD_TEST_BASE_OSX[@]}" -configuration Debug test
- header "Doing Xcode OS X build/tests - Release"
- "${XCODEBUILD_TEST_BASE_OSX[@]}" -configuration Release test
+ if [[ "${DO_XCODE_DEBUG}" == "yes" ]] ; then
+ header "Doing Xcode OS X build/tests - Debug"
+ "${XCODEBUILD_TEST_BASE_OSX[@]}" -configuration Debug test
+ fi
+ if [[ "${DO_XCODE_RELEASE}" == "yes" ]] ; then
+ header "Doing Xcode OS X build/tests - Release"
+ "${XCODEBUILD_TEST_BASE_OSX[@]}" -configuration Release test
+ fi
fi
if [[ "${DO_OBJC_CONFORMANCE_TESTS}" == "yes" ]] ; then
+ header "Running ObjC Conformance Tests"
cd conformance
wrapped_make -j "${NUM_MAKE_JOBS}" test_objc
cd ..
diff --git a/objectivec/DevTools/pddm.py b/objectivec/DevTools/pddm.py
index d1b53f5a..9a11fec4 100755
--- a/objectivec/DevTools/pddm.py
+++ b/objectivec/DevTools/pddm.py
@@ -625,8 +625,7 @@ class SourceFile(object):
def main(args):
usage = '%prog [OPTIONS] PATH ...'
description = (
- 'Processes PDDM directives in the the given paths and write them back'
- ' out.'
+ 'Processes PDDM directives in the given paths and write them back out.'
)
parser = optparse.OptionParser(usage=usage, description=description)
parser.add_option('--dry-run',
diff --git a/objectivec/GPBArray.h b/objectivec/GPBArray.h
index 8c6396a9..afda57f3 100644
--- a/objectivec/GPBArray.h
+++ b/objectivec/GPBArray.h
@@ -53,9 +53,10 @@ NS_ASSUME_NONNULL_BEGIN
+ (instancetype)arrayWithValueArray:(GPBInt32Array *)array;
+ (instancetype)arrayWithCapacity:(NSUInteger)count;
+- (instancetype)init NS_DESIGNATED_INITIALIZER;
// Initializes the array, copying the values.
- (instancetype)initWithValues:(const int32_t [])values
- count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
+ count:(NSUInteger)count;
- (instancetype)initWithValueArray:(GPBInt32Array *)array;
- (instancetype)initWithCapacity:(NSUInteger)count;
@@ -92,9 +93,10 @@ NS_ASSUME_NONNULL_BEGIN
+ (instancetype)arrayWithValueArray:(GPBUInt32Array *)array;
+ (instancetype)arrayWithCapacity:(NSUInteger)count;
+- (instancetype)init NS_DESIGNATED_INITIALIZER;
// Initializes the array, copying the values.
- (instancetype)initWithValues:(const uint32_t [])values
- count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
+ count:(NSUInteger)count;
- (instancetype)initWithValueArray:(GPBUInt32Array *)array;
- (instancetype)initWithCapacity:(NSUInteger)count;
@@ -131,9 +133,10 @@ NS_ASSUME_NONNULL_BEGIN
+ (instancetype)arrayWithValueArray:(GPBInt64Array *)array;
+ (instancetype)arrayWithCapacity:(NSUInteger)count;
+- (instancetype)init NS_DESIGNATED_INITIALIZER;
// Initializes the array, copying the values.
- (instancetype)initWithValues:(const int64_t [])values
- count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
+ count:(NSUInteger)count;
- (instancetype)initWithValueArray:(GPBInt64Array *)array;
- (instancetype)initWithCapacity:(NSUInteger)count;
@@ -170,9 +173,10 @@ NS_ASSUME_NONNULL_BEGIN
+ (instancetype)arrayWithValueArray:(GPBUInt64Array *)array;
+ (instancetype)arrayWithCapacity:(NSUInteger)count;
+- (instancetype)init NS_DESIGNATED_INITIALIZER;
// Initializes the array, copying the values.
- (instancetype)initWithValues:(const uint64_t [])values
- count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
+ count:(NSUInteger)count;
- (instancetype)initWithValueArray:(GPBUInt64Array *)array;
- (instancetype)initWithCapacity:(NSUInteger)count;
@@ -209,9 +213,10 @@ NS_ASSUME_NONNULL_BEGIN
+ (instancetype)arrayWithValueArray:(GPBFloatArray *)array;
+ (instancetype)arrayWithCapacity:(NSUInteger)count;
+- (instancetype)init NS_DESIGNATED_INITIALIZER;
// Initializes the array, copying the values.
- (instancetype)initWithValues:(const float [])values
- count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
+ count:(NSUInteger)count;
- (instancetype)initWithValueArray:(GPBFloatArray *)array;
- (instancetype)initWithCapacity:(NSUInteger)count;
@@ -248,9 +253,10 @@ NS_ASSUME_NONNULL_BEGIN
+ (instancetype)arrayWithValueArray:(GPBDoubleArray *)array;
+ (instancetype)arrayWithCapacity:(NSUInteger)count;
+- (instancetype)init NS_DESIGNATED_INITIALIZER;
// Initializes the array, copying the values.
- (instancetype)initWithValues:(const double [])values
- count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
+ count:(NSUInteger)count;
- (instancetype)initWithValueArray:(GPBDoubleArray *)array;
- (instancetype)initWithCapacity:(NSUInteger)count;
@@ -287,9 +293,10 @@ NS_ASSUME_NONNULL_BEGIN
+ (instancetype)arrayWithValueArray:(GPBBoolArray *)array;
+ (instancetype)arrayWithCapacity:(NSUInteger)count;
+- (instancetype)init NS_DESIGNATED_INITIALIZER;
// Initializes the array, copying the values.
- (instancetype)initWithValues:(const BOOL [])values
- count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
+ count:(NSUInteger)count;
- (instancetype)initWithValueArray:(GPBBoolArray *)array;
- (instancetype)initWithCapacity:(NSUInteger)count;
@@ -330,12 +337,13 @@ NS_ASSUME_NONNULL_BEGIN
+ (instancetype)arrayWithValidationFunction:(nullable GPBEnumValidationFunc)func
capacity:(NSUInteger)count;
-- (instancetype)initWithValidationFunction:(nullable GPBEnumValidationFunc)func;
+- (instancetype)initWithValidationFunction:(nullable GPBEnumValidationFunc)func
+ NS_DESIGNATED_INITIALIZER;
// Initializes the array, copying the values.
- (instancetype)initWithValidationFunction:(nullable GPBEnumValidationFunc)func
rawValues:(const int32_t [])values
- count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
+ count:(NSUInteger)count;
- (instancetype)initWithValueArray:(GPBEnumArray *)array;
- (instancetype)initWithValidationFunction:(nullable GPBEnumValidationFunc)func
capacity:(NSUInteger)count;
@@ -422,9 +430,10 @@ NS_ASSUME_NONNULL_END
//%+ (instancetype)arrayWithValueArray:(GPB##NAME##Array *)array;
//%+ (instancetype)arrayWithCapacity:(NSUInteger)count;
//%
+//%- (instancetype)init NS_DESIGNATED_INITIALIZER;
//%// Initializes the array, copying the values.
//%- (instancetype)initWithValues:(const TYPE [])values
-//% count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
+//% count:(NSUInteger)count;
//%- (instancetype)initWithValueArray:(GPB##NAME##Array *)array;
//%- (instancetype)initWithCapacity:(NSUInteger)count;
//%
@@ -455,12 +464,13 @@ NS_ASSUME_NONNULL_END
//%+ (instancetype)arrayWithValidationFunction:(nullable GPBEnumValidationFunc)func
//% capacity:(NSUInteger)count;
//%
-//%- (instancetype)initWithValidationFunction:(nullable GPBEnumValidationFunc)func;
+//%- (instancetype)initWithValidationFunction:(nullable GPBEnumValidationFunc)func
+//% NS_DESIGNATED_INITIALIZER;
//%
//%// Initializes the array, copying the values.
//%- (instancetype)initWithValidationFunction:(nullable GPBEnumValidationFunc)func
//% rawValues:(const TYPE [])values
-//% count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
+//% count:(NSUInteger)count;
//%- (instancetype)initWithValueArray:(GPB##NAME##Array *)array;
//%- (instancetype)initWithValidationFunction:(nullable GPBEnumValidationFunc)func
//% capacity:(NSUInteger)count;
diff --git a/objectivec/GPBArray.m b/objectivec/GPBArray.m
index 60b08ad1..64869bbb 100644
--- a/objectivec/GPBArray.m
+++ b/objectivec/GPBArray.m
@@ -32,6 +32,12 @@
#import "GPBMessage_PackagePrivate.h"
+// Direct access is use for speed, to avoid even internally declaring things
+// read/write, etc. The warning is enabled in the project to ensure code calling
+// protos can turn on -Wdirect-ivar-access without issues.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdirect-ivar-access"
+
// Mutable arrays use an internal buffer that can always hold a multiple of this elements.
#define kChunkSize 16
#define CapacityFromCount(x) (((x / kChunkSize) + 1) * kChunkSize)
@@ -75,7 +81,7 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
//%@synthesize count = _count;
//%
//%+ (instancetype)array {
-//% return [[[self alloc] initWithValues:NULL count:0] autorelease];
+//% return [[[self alloc] init] autorelease];
//%}
//%
//%+ (instancetype)arrayWithValue:(TYPE)value {
@@ -93,7 +99,9 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
//%}
//%
//%- (instancetype)init {
-//% return [self initWithValues:NULL count:0];
+//% self = [super init];
+//% // No work needed;
+//% return self;
//%}
//%
//%- (instancetype)initWithValueArray:(GPB##NAME##Array *)array {
@@ -101,11 +109,11 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
//%}
//%
//%- (instancetype)initWithValues:(const TYPE [])values count:(NSUInteger)count {
-//% self = [super init];
+//% self = [self init];
//% if (self) {
//% if (count && values) {
-//% _values = malloc(count * sizeof(TYPE));
-//% if (values != NULL) {
+//% _values = reallocf(_values, count * sizeof(TYPE));
+//% if (_values != NULL) {
//% _capacity = count;
//% memcpy(_values, values, count * sizeof(TYPE));
//% _count = count;
@@ -156,15 +164,16 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
//% [super dealloc];
//%}
//%
-//%- (BOOL)isEqual:(GPB##NAME##Array *)other {
+//%- (BOOL)isEqual:(id)other {
//% if (self == other) {
//% return YES;
//% }
//% if (![other isKindOfClass:[GPB##NAME##Array class]]) {
//% return NO;
//% }
-//% return (_count == other->_count
-//% && memcmp(_values, other->_values, (_count * sizeof(TYPE))) == 0);
+//% GPB##NAME##Array *otherArray = other;
+//% return (_count == otherArray->_count
+//% && memcmp(_values, otherArray->_values, (_count * sizeof(TYPE))) == 0);
//%}
//%
//%- (NSUInteger)hash {
@@ -299,7 +308,7 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
@synthesize count = _count;
+ (instancetype)array {
- return [[[self alloc] initWithValues:NULL count:0] autorelease];
+ return [[[self alloc] init] autorelease];
}
+ (instancetype)arrayWithValue:(int32_t)value {
@@ -317,7 +326,9 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
}
- (instancetype)init {
- return [self initWithValues:NULL count:0];
+ self = [super init];
+ // No work needed;
+ return self;
}
- (instancetype)initWithValueArray:(GPBInt32Array *)array {
@@ -325,11 +336,11 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
}
- (instancetype)initWithValues:(const int32_t [])values count:(NSUInteger)count {
- self = [super init];
+ self = [self init];
if (self) {
if (count && values) {
- _values = malloc(count * sizeof(int32_t));
- if (values != NULL) {
+ _values = reallocf(_values, count * sizeof(int32_t));
+ if (_values != NULL) {
_capacity = count;
memcpy(_values, values, count * sizeof(int32_t));
_count = count;
@@ -364,15 +375,16 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
[super dealloc];
}
-- (BOOL)isEqual:(GPBInt32Array *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBInt32Array class]]) {
return NO;
}
- return (_count == other->_count
- && memcmp(_values, other->_values, (_count * sizeof(int32_t))) == 0);
+ GPBInt32Array *otherArray = other;
+ return (_count == otherArray->_count
+ && memcmp(_values, otherArray->_values, (_count * sizeof(int32_t))) == 0);
}
- (NSUInteger)hash {
@@ -544,7 +556,7 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
@synthesize count = _count;
+ (instancetype)array {
- return [[[self alloc] initWithValues:NULL count:0] autorelease];
+ return [[[self alloc] init] autorelease];
}
+ (instancetype)arrayWithValue:(uint32_t)value {
@@ -562,7 +574,9 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
}
- (instancetype)init {
- return [self initWithValues:NULL count:0];
+ self = [super init];
+ // No work needed;
+ return self;
}
- (instancetype)initWithValueArray:(GPBUInt32Array *)array {
@@ -570,11 +584,11 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
}
- (instancetype)initWithValues:(const uint32_t [])values count:(NSUInteger)count {
- self = [super init];
+ self = [self init];
if (self) {
if (count && values) {
- _values = malloc(count * sizeof(uint32_t));
- if (values != NULL) {
+ _values = reallocf(_values, count * sizeof(uint32_t));
+ if (_values != NULL) {
_capacity = count;
memcpy(_values, values, count * sizeof(uint32_t));
_count = count;
@@ -609,15 +623,16 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
[super dealloc];
}
-- (BOOL)isEqual:(GPBUInt32Array *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBUInt32Array class]]) {
return NO;
}
- return (_count == other->_count
- && memcmp(_values, other->_values, (_count * sizeof(uint32_t))) == 0);
+ GPBUInt32Array *otherArray = other;
+ return (_count == otherArray->_count
+ && memcmp(_values, otherArray->_values, (_count * sizeof(uint32_t))) == 0);
}
- (NSUInteger)hash {
@@ -789,7 +804,7 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
@synthesize count = _count;
+ (instancetype)array {
- return [[[self alloc] initWithValues:NULL count:0] autorelease];
+ return [[[self alloc] init] autorelease];
}
+ (instancetype)arrayWithValue:(int64_t)value {
@@ -807,7 +822,9 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
}
- (instancetype)init {
- return [self initWithValues:NULL count:0];
+ self = [super init];
+ // No work needed;
+ return self;
}
- (instancetype)initWithValueArray:(GPBInt64Array *)array {
@@ -815,11 +832,11 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
}
- (instancetype)initWithValues:(const int64_t [])values count:(NSUInteger)count {
- self = [super init];
+ self = [self init];
if (self) {
if (count && values) {
- _values = malloc(count * sizeof(int64_t));
- if (values != NULL) {
+ _values = reallocf(_values, count * sizeof(int64_t));
+ if (_values != NULL) {
_capacity = count;
memcpy(_values, values, count * sizeof(int64_t));
_count = count;
@@ -854,15 +871,16 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
[super dealloc];
}
-- (BOOL)isEqual:(GPBInt64Array *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBInt64Array class]]) {
return NO;
}
- return (_count == other->_count
- && memcmp(_values, other->_values, (_count * sizeof(int64_t))) == 0);
+ GPBInt64Array *otherArray = other;
+ return (_count == otherArray->_count
+ && memcmp(_values, otherArray->_values, (_count * sizeof(int64_t))) == 0);
}
- (NSUInteger)hash {
@@ -1034,7 +1052,7 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
@synthesize count = _count;
+ (instancetype)array {
- return [[[self alloc] initWithValues:NULL count:0] autorelease];
+ return [[[self alloc] init] autorelease];
}
+ (instancetype)arrayWithValue:(uint64_t)value {
@@ -1052,7 +1070,9 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
}
- (instancetype)init {
- return [self initWithValues:NULL count:0];
+ self = [super init];
+ // No work needed;
+ return self;
}
- (instancetype)initWithValueArray:(GPBUInt64Array *)array {
@@ -1060,11 +1080,11 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
}
- (instancetype)initWithValues:(const uint64_t [])values count:(NSUInteger)count {
- self = [super init];
+ self = [self init];
if (self) {
if (count && values) {
- _values = malloc(count * sizeof(uint64_t));
- if (values != NULL) {
+ _values = reallocf(_values, count * sizeof(uint64_t));
+ if (_values != NULL) {
_capacity = count;
memcpy(_values, values, count * sizeof(uint64_t));
_count = count;
@@ -1099,15 +1119,16 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
[super dealloc];
}
-- (BOOL)isEqual:(GPBUInt64Array *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBUInt64Array class]]) {
return NO;
}
- return (_count == other->_count
- && memcmp(_values, other->_values, (_count * sizeof(uint64_t))) == 0);
+ GPBUInt64Array *otherArray = other;
+ return (_count == otherArray->_count
+ && memcmp(_values, otherArray->_values, (_count * sizeof(uint64_t))) == 0);
}
- (NSUInteger)hash {
@@ -1279,7 +1300,7 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
@synthesize count = _count;
+ (instancetype)array {
- return [[[self alloc] initWithValues:NULL count:0] autorelease];
+ return [[[self alloc] init] autorelease];
}
+ (instancetype)arrayWithValue:(float)value {
@@ -1297,7 +1318,9 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
}
- (instancetype)init {
- return [self initWithValues:NULL count:0];
+ self = [super init];
+ // No work needed;
+ return self;
}
- (instancetype)initWithValueArray:(GPBFloatArray *)array {
@@ -1305,11 +1328,11 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
}
- (instancetype)initWithValues:(const float [])values count:(NSUInteger)count {
- self = [super init];
+ self = [self init];
if (self) {
if (count && values) {
- _values = malloc(count * sizeof(float));
- if (values != NULL) {
+ _values = reallocf(_values, count * sizeof(float));
+ if (_values != NULL) {
_capacity = count;
memcpy(_values, values, count * sizeof(float));
_count = count;
@@ -1344,15 +1367,16 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
[super dealloc];
}
-- (BOOL)isEqual:(GPBFloatArray *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBFloatArray class]]) {
return NO;
}
- return (_count == other->_count
- && memcmp(_values, other->_values, (_count * sizeof(float))) == 0);
+ GPBFloatArray *otherArray = other;
+ return (_count == otherArray->_count
+ && memcmp(_values, otherArray->_values, (_count * sizeof(float))) == 0);
}
- (NSUInteger)hash {
@@ -1524,7 +1548,7 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
@synthesize count = _count;
+ (instancetype)array {
- return [[[self alloc] initWithValues:NULL count:0] autorelease];
+ return [[[self alloc] init] autorelease];
}
+ (instancetype)arrayWithValue:(double)value {
@@ -1542,7 +1566,9 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
}
- (instancetype)init {
- return [self initWithValues:NULL count:0];
+ self = [super init];
+ // No work needed;
+ return self;
}
- (instancetype)initWithValueArray:(GPBDoubleArray *)array {
@@ -1550,11 +1576,11 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
}
- (instancetype)initWithValues:(const double [])values count:(NSUInteger)count {
- self = [super init];
+ self = [self init];
if (self) {
if (count && values) {
- _values = malloc(count * sizeof(double));
- if (values != NULL) {
+ _values = reallocf(_values, count * sizeof(double));
+ if (_values != NULL) {
_capacity = count;
memcpy(_values, values, count * sizeof(double));
_count = count;
@@ -1589,15 +1615,16 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
[super dealloc];
}
-- (BOOL)isEqual:(GPBDoubleArray *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBDoubleArray class]]) {
return NO;
}
- return (_count == other->_count
- && memcmp(_values, other->_values, (_count * sizeof(double))) == 0);
+ GPBDoubleArray *otherArray = other;
+ return (_count == otherArray->_count
+ && memcmp(_values, otherArray->_values, (_count * sizeof(double))) == 0);
}
- (NSUInteger)hash {
@@ -1769,7 +1796,7 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
@synthesize count = _count;
+ (instancetype)array {
- return [[[self alloc] initWithValues:NULL count:0] autorelease];
+ return [[[self alloc] init] autorelease];
}
+ (instancetype)arrayWithValue:(BOOL)value {
@@ -1787,7 +1814,9 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
}
- (instancetype)init {
- return [self initWithValues:NULL count:0];
+ self = [super init];
+ // No work needed;
+ return self;
}
- (instancetype)initWithValueArray:(GPBBoolArray *)array {
@@ -1795,11 +1824,11 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
}
- (instancetype)initWithValues:(const BOOL [])values count:(NSUInteger)count {
- self = [super init];
+ self = [self init];
if (self) {
if (count && values) {
- _values = malloc(count * sizeof(BOOL));
- if (values != NULL) {
+ _values = reallocf(_values, count * sizeof(BOOL));
+ if (_values != NULL) {
_capacity = count;
memcpy(_values, values, count * sizeof(BOOL));
_count = count;
@@ -1834,15 +1863,16 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
[super dealloc];
}
-- (BOOL)isEqual:(GPBBoolArray *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBBoolArray class]]) {
return NO;
}
- return (_count == other->_count
- && memcmp(_values, other->_values, (_count * sizeof(BOOL))) == 0);
+ GPBBoolArray *otherArray = other;
+ return (_count == otherArray->_count
+ && memcmp(_values, otherArray->_values, (_count * sizeof(BOOL))) == 0);
}
- (NSUInteger)hash {
@@ -2015,15 +2045,11 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
@synthesize validationFunc = _validationFunc;
+ (instancetype)array {
- return [[[self alloc] initWithValidationFunction:NULL
- rawValues:NULL
- count:0] autorelease];
+ return [[[self alloc] initWithValidationFunction:NULL] autorelease];
}
+ (instancetype)arrayWithValidationFunction:(GPBEnumValidationFunc)func {
- return [[[self alloc] initWithValidationFunction:func
- rawValues:NULL
- count:0] autorelease];
+ return [[[self alloc] initWithValidationFunction:func] autorelease];
}
+ (instancetype)arrayWithValidationFunction:(GPBEnumValidationFunc)func
@@ -2043,7 +2069,7 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
}
- (instancetype)init {
- return [self initWithValidationFunction:NULL rawValues:NULL count:0];
+ return [self initWithValidationFunction:NULL];
}
- (instancetype)initWithValueArray:(GPBEnumArray *)array {
@@ -2053,18 +2079,21 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
}
- (instancetype)initWithValidationFunction:(GPBEnumValidationFunc)func {
- return [self initWithValidationFunction:func rawValues:NULL count:0];
+ self = [super init];
+ if (self) {
+ _validationFunc = (func != NULL ? func : ArrayDefault_IsValidValue);
+ }
+ return self;
}
- (instancetype)initWithValidationFunction:(GPBEnumValidationFunc)func
rawValues:(const int32_t [])values
count:(NSUInteger)count {
- self = [super init];
+ self = [self initWithValidationFunction:func];
if (self) {
- _validationFunc = (func != NULL ? func : ArrayDefault_IsValidValue);
if (count && values) {
- _values = malloc(count * sizeof(int32_t));
- if (values != NULL) {
+ _values = reallocf(_values, count * sizeof(int32_t));
+ if (_values != NULL) {
_capacity = count;
memcpy(_values, values, count * sizeof(int32_t));
_count = count;
@@ -2081,7 +2110,7 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
- (instancetype)initWithValidationFunction:(GPBEnumValidationFunc)func
capacity:(NSUInteger)count {
- self = [self initWithValidationFunction:func rawValues:NULL count:0];
+ self = [self initWithValidationFunction:func];
if (self && count) {
[self internalResizeToCapacity:count];
}
@@ -2106,15 +2135,16 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
[super dealloc];
}
-- (BOOL)isEqual:(GPBEnumArray *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBEnumArray class]]) {
return NO;
}
- return (_count == other->_count
- && memcmp(_values, other->_values, (_count * sizeof(int32_t))) == 0);
+ GPBEnumArray *otherArray = other;
+ return (_count == otherArray->_count
+ && memcmp(_values, otherArray->_values, (_count * sizeof(int32_t))) == 0);
}
- (NSUInteger)hash {
@@ -2517,3 +2547,5 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
}
@end
+
+#pragma clang diagnostic pop
diff --git a/objectivec/GPBBootstrap.h b/objectivec/GPBBootstrap.h
index c49c7e20..4db08e80 100644
--- a/objectivec/GPBBootstrap.h
+++ b/objectivec/GPBBootstrap.h
@@ -37,13 +37,6 @@
#define GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS 0
#endif
-// Most uses of protocol buffers don't need field options, by default the
-// static data will be compiled out, define this to 1 to include it. The only
-// time you need this is if you are doing introspection of the protocol buffers.
-#ifndef GPBOBJC_INCLUDE_FIELD_OPTIONS
-#define GPBOBJC_INCLUDE_FIELD_OPTIONS 0
-#endif
-
// Used in the generated code to give sizes to enums. int32_t was chosen based
// on the fact that Protocol Buffers enums are limited to this range.
#if !__has_feature(objc_fixed_enum)
@@ -55,7 +48,7 @@
// doesn't allow us to forward declare. We work around this one case by
// providing a local definition. The default case has to use NS_ENUM for the
// magic that is Swift bridging of enums.
-#if (__cplusplus && __cplusplus < 201103L)
+#if (defined(__cplusplus) && __cplusplus && __cplusplus < 201103L)
#define GPB_ENUM(X) enum X : int32_t X; enum X : int32_t
#else
#define GPB_ENUM(X) NS_ENUM(int32_t, X)
@@ -89,4 +82,4 @@
// generated Objective C sources. In general we don't want to change the
// runtime interfaces (or this version) as it means everything has to be
// regenerated.
-#define GOOGLE_PROTOBUF_OBJC_GEN_VERSION 30000
+#define GOOGLE_PROTOBUF_OBJC_GEN_VERSION 30001
diff --git a/objectivec/GPBCodedInputStream.h b/objectivec/GPBCodedInputStream.h
index 42a04941..df9d97ba 100644
--- a/objectivec/GPBCodedInputStream.h
+++ b/objectivec/GPBCodedInputStream.h
@@ -35,52 +35,128 @@
NS_ASSUME_NONNULL_BEGIN
-// Reads and decodes protocol message fields.
-// Subclassing of GPBCodedInputStream is NOT supported.
+CF_EXTERN_C_BEGIN
+
+/// GPBCodedInputStream exception name. Exceptions raised from
+/// GPBCodedInputStream contain an underlying error in the userInfo dictionary
+/// under the GPBCodedInputStreamUnderlyingErrorKey key.
+extern NSString *const GPBCodedInputStreamException;
+
+/// The key under which the underlying NSError from the exception is stored.
+extern NSString *const GPBCodedInputStreamUnderlyingErrorKey;
+
+/// NSError domain used for GPBCodedInputStream errors.
+extern NSString *const GPBCodedInputStreamErrorDomain;
+
+/// Error code for NSError with GPBCodedInputStreamErrorDomain.
+typedef NS_ENUM(NSInteger, GPBCodedInputStreamErrorCode) {
+ /// The size does not fit in the remaining bytes to be read.
+ GPBCodedInputStreamErrorInvalidSize = -100,
+ /// Attempted to read beyond the subsection limit.
+ GPBCodedInputStreamErrorSubsectionLimitReached = -101,
+ /// The requested subsection limit is invalid.
+ GPBCodedInputStreamErrorInvalidSubsectionLimit = -102,
+ /// Invalid tag read.
+ GPBCodedInputStreamErrorInvalidTag = -103,
+ /// Invalid UTF-8 character in a string.
+ GPBCodedInputStreamErrorInvalidUTF8 = -104,
+ /// Invalid VarInt read.
+ GPBCodedInputStreamErrorInvalidVarInt = -105,
+ /// The maximum recursion depth of messages was exceeded.
+ GPBCodedInputStreamErrorRecursionDepthExceeded = -106,
+};
+
+CF_EXTERN_C_END
+
+/// Reads and decodes protocol message fields.
+///
+/// The common uses of protocol buffers shouldn't need to use this class.
+/// @c GPBMessage's provide a @c +parseFromData:error: and @c
+/// +parseFromData:extensionRegistry:error: method that will decode a
+/// message for you.
+///
+/// @note Subclassing of GPBCodedInputStream is NOT supported.
@interface GPBCodedInputStream : NSObject
+/// Creates a new stream wrapping some data.
+ (instancetype)streamWithData:(NSData *)data;
+
+/// Initializes a stream wrapping some data.
- (instancetype)initWithData:(NSData *)data;
-// Attempt to read a field tag, returning zero if we have reached EOF.
-// Protocol message parsers use this to read tags, since a protocol message
-// may legally end wherever a tag occurs, and zero is not a valid tag number.
+/// Attempt to read a field tag, returning zero if we have reached EOF.
+/// Protocol message parsers use this to read tags, since a protocol message
+/// may legally end wherever a tag occurs, and zero is not a valid tag number.
- (int32_t)readTag;
+/// Read and return a double.
- (double)readDouble;
+/// Read and return a float.
- (float)readFloat;
+/// Read and return a uint64.
- (uint64_t)readUInt64;
+/// Read and return a uint32.
- (uint32_t)readUInt32;
+/// Read and return an int64.
- (int64_t)readInt64;
+/// Read and return an int32.
- (int32_t)readInt32;
+/// Read and return a fixed64.
- (uint64_t)readFixed64;
+/// Read and return a fixed32.
- (uint32_t)readFixed32;
+/// Read and return an enum (int).
- (int32_t)readEnum;
+/// Read and return a sfixed32.
- (int32_t)readSFixed32;
+/// Read and return a sfixed64.
- (int64_t)readSFixed64;
+/// Read and return a sint32.
- (int32_t)readSInt32;
+/// Read and return a sint64.
- (int64_t)readSInt64;
+/// Read and return a boolean.
- (BOOL)readBool;
+/// Read and return a string.
- (NSString *)readString;
+/// Read and return length delimited data.
- (NSData *)readBytes;
-// Read an embedded message field value from the stream.
+/// Read an embedded message field value from the stream.
+///
+/// @param message The message to set fields on as they are read.
+/// @param extensionRegistry An optional extension registry to use to lookup
+/// extensions for @c message.
- (void)readMessage:(GPBMessage *)message
- extensionRegistry:(nullable GPBExtensionRegistry *)extensionRegistry;
+ extensionRegistry:(nullable GPBExtensionRegistry *)extensionRegistry;
-// Reads and discards a single field, given its tag value. Returns NO if the
-// tag is an endgroup tag, in which case nothing is skipped. Otherwise,
-// returns YES.
+/// Reads and discards a single field, given its tag value.
+///
+/// @param tag The tag number of the field to skip.
+///
+/// @return NO if the tag is an endgroup tag (in which case nothing is skipped),
+/// YES in all other cases.
- (BOOL)skipField:(int32_t)tag;
-// Reads and discards an entire message. This will read either until EOF
-// or until an endgroup tag, whichever comes first.
+/// Reads and discards an entire message. This will read either until EOF
+/// or until an endgroup tag, whichever comes first.
- (void)skipMessage;
-// Verifies that the last call to readTag() returned the given tag value.
-// This is used to verify that a nested group ended with the correct end tag.
-// Throws NSParseErrorException if value does not match the last tag.
-- (void)checkLastTagWas:(int32_t)value;
+/// Check to see if the logical end of the stream has been reached.
+///
+/// This can return NO when there is no more data, but the current parsing
+/// expected more data.
+- (BOOL)isAtEnd;
+
+/// The offset into the stream.
+- (size_t)position;
+
+/// Verifies that the last call to @c -readTag returned the given tag value.
+/// This is used to verify that a nested group ended with the correct end tag.
+/// Throws @c NSParseErrorException if value does not match the last tag.
+///
+/// @param expected The tag that was expected.
+- (void)checkLastTagWas:(int32_t)expected;
@end
diff --git a/objectivec/GPBCodedInputStream.m b/objectivec/GPBCodedInputStream.m
index 9371228a..2b578dd5 100644
--- a/objectivec/GPBCodedInputStream.m
+++ b/objectivec/GPBCodedInputStream.m
@@ -36,17 +36,42 @@
#import "GPBUtilities_PackagePrivate.h"
#import "GPBWireFormat.h"
+NSString *const GPBCodedInputStreamException =
+ GPBNSStringifySymbol(GPBCodedInputStreamException);
+
+NSString *const GPBCodedInputStreamUnderlyingErrorKey =
+ GPBNSStringifySymbol(GPBCodedInputStreamUnderlyingErrorKey);
+
+NSString *const GPBCodedInputStreamErrorDomain =
+ GPBNSStringifySymbol(GPBCodedInputStreamErrorDomain);
+
static const NSUInteger kDefaultRecursionLimit = 64;
+static void RaiseException(NSInteger code, NSString *reason) {
+ NSDictionary *errorInfo = nil;
+ if ([reason length]) {
+ errorInfo = @{ GPBErrorReasonKey: reason };
+ }
+ NSError *error = [NSError errorWithDomain:GPBCodedInputStreamErrorDomain
+ code:code
+ userInfo:errorInfo];
+
+ NSDictionary *exceptionInfo =
+ @{ GPBCodedInputStreamUnderlyingErrorKey: error };
+ [[[NSException alloc] initWithName:GPBCodedInputStreamException
+ reason:reason
+ userInfo:exceptionInfo] raise];
+}
+
static void CheckSize(GPBCodedInputStreamState *state, size_t size) {
size_t newSize = state->bufferPos + size;
if (newSize > state->bufferSize) {
- [NSException raise:NSParseErrorException format:@""];
+ RaiseException(GPBCodedInputStreamErrorInvalidSize, nil);
}
if (newSize > state->currentLimit) {
// Fast forward to end of currentLimit;
state->bufferPos = state->currentLimit;
- [NSException raise:NSParseErrorException format:@""];
+ RaiseException(GPBCodedInputStreamErrorSubsectionLimitReached, nil);
}
}
@@ -95,8 +120,8 @@ static int32_t ReadRawVarint32(GPBCodedInputStreamState *state) {
return result;
}
}
- [NSException raise:NSParseErrorException
- format:@"Unable to read varint32"];
+ RaiseException(GPBCodedInputStreamErrorInvalidVarInt,
+ @"Invalid VarInt32");
}
}
}
@@ -115,7 +140,7 @@ static int64_t ReadRawVarint64(GPBCodedInputStreamState *state) {
}
shift += 7;
}
- [NSException raise:NSParseErrorException format:@"Unable to read varint64"];
+ RaiseException(GPBCodedInputStreamErrorInvalidVarInt, @"Invalid VarInt64");
return 0;
}
@@ -202,8 +227,13 @@ int32_t GPBCodedInputStreamReadTag(GPBCodedInputStreamState *state) {
state->lastTag = ReadRawVarint32(state);
if (state->lastTag == 0) {
// If we actually read zero, that's not a valid tag.
- [NSException raise:NSParseErrorException
- format:@"Invalid last tag %d", state->lastTag];
+ RaiseException(GPBCodedInputStreamErrorInvalidTag,
+ @"A zero tag on the wire is invalid.");
+ }
+ // Tags have to include a valid wireformat, check that also.
+ if (!GPBWireFormatIsValidTag(state->lastTag)) {
+ RaiseException(GPBCodedInputStreamErrorInvalidTag,
+ @"Invalid wireformat in tag.");
}
return state->lastTag;
}
@@ -216,8 +246,18 @@ NSString *GPBCodedInputStreamReadRetainedString(
result = @"";
} else {
CheckSize(state, size);
- result = GPBCreateGPBStringWithUTF8(&state->bytes[state->bufferPos], size);
+ result = [[NSString alloc] initWithBytes:&state->bytes[state->bufferPos]
+ length:size
+ encoding:NSUTF8StringEncoding];
state->bufferPos += size;
+ if (!result) {
+#ifdef DEBUG
+ // https://developers.google.com/protocol-buffers/docs/proto#scalar
+ NSLog(@"UTF-8 failure, is some field type 'string' when it should be "
+ @"'bytes'?");
+#endif
+ RaiseException(GPBCodedInputStreamErrorInvalidUTF8, nil);
+ }
}
return result;
}
@@ -251,8 +291,7 @@ size_t GPBCodedInputStreamPushLimit(GPBCodedInputStreamState *state,
byteLimit += state->bufferPos;
size_t oldLimit = state->currentLimit;
if (byteLimit > oldLimit) {
- [NSException raise:NSInvalidArgumentException
- format:@"byteLimit > oldLimit: %tu > %tu", byteLimit, oldLimit];
+ RaiseException(GPBCodedInputStreamErrorInvalidSubsectionLimit, nil);
}
state->currentLimit = byteLimit;
return oldLimit;
@@ -275,8 +314,7 @@ BOOL GPBCodedInputStreamIsAtEnd(GPBCodedInputStreamState *state) {
void GPBCodedInputStreamCheckLastTagWas(GPBCodedInputStreamState *state,
int32_t value) {
if (state->lastTag != value) {
- [NSException raise:NSParseErrorException
- format:@"Last tag: %d should be %d", state->lastTag, value];
+ RaiseException(GPBCodedInputStreamErrorInvalidTag, @"Unexpected tag read");
}
}
@@ -305,6 +343,12 @@ void GPBCodedInputStreamCheckLastTagWas(GPBCodedInputStreamState *state,
[super dealloc];
}
+// Direct access is use for speed, to avoid even internally declaring things
+// read/write, etc. The warning is enabled in the project to ensure code calling
+// protos can turn on -Wdirect-ivar-access without issues.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdirect-ivar-access"
+
- (int32_t)readTag {
return GPBCodedInputStreamReadTag(&state_);
}
@@ -314,6 +358,7 @@ void GPBCodedInputStreamCheckLastTagWas(GPBCodedInputStreamState *state,
}
- (BOOL)skipField:(int32_t)tag {
+ NSAssert(GPBWireFormatIsValidTag(tag), @"Invalid tag");
switch (GPBWireFormatGetTagWireType(tag)) {
case GPBWireFormatVarint:
GPBCodedInputStreamReadInt32(&state_);
@@ -336,8 +381,6 @@ void GPBCodedInputStreamCheckLastTagWas(GPBCodedInputStreamState *state,
SkipRawData(&state_, sizeof(int32_t));
return YES;
}
- [NSException raise:NSParseErrorException format:@"Invalid tag %d", tag];
- return NO;
}
- (void)skipMessage {
@@ -349,6 +392,14 @@ void GPBCodedInputStreamCheckLastTagWas(GPBCodedInputStreamState *state,
}
}
+- (BOOL)isAtEnd {
+ return GPBCodedInputStreamIsAtEnd(&state_);
+}
+
+- (size_t)position {
+ return state_.bufferPos;
+}
+
- (double)readDouble {
return GPBCodedInputStreamReadDouble(&state_);
}
@@ -389,9 +440,7 @@ void GPBCodedInputStreamCheckLastTagWas(GPBCodedInputStreamState *state,
message:(GPBMessage *)message
extensionRegistry:(GPBExtensionRegistry *)extensionRegistry {
if (state_.recursionDepth >= kDefaultRecursionLimit) {
- [NSException raise:NSParseErrorException
- format:@"recursionDepth(%tu) >= %tu", state_.recursionDepth,
- kDefaultRecursionLimit];
+ RaiseException(GPBCodedInputStreamErrorRecursionDepthExceeded, nil);
}
++state_.recursionDepth;
[message mergeFromCodedInputStream:self extensionRegistry:extensionRegistry];
@@ -403,9 +452,7 @@ void GPBCodedInputStreamCheckLastTagWas(GPBCodedInputStreamState *state,
- (void)readUnknownGroup:(int32_t)fieldNumber
message:(GPBUnknownFieldSet *)message {
if (state_.recursionDepth >= kDefaultRecursionLimit) {
- [NSException raise:NSParseErrorException
- format:@"recursionDepth(%tu) >= %tu", state_.recursionDepth,
- kDefaultRecursionLimit];
+ RaiseException(GPBCodedInputStreamErrorRecursionDepthExceeded, nil);
}
++state_.recursionDepth;
[message mergeFromCodedInputStream:self];
@@ -418,9 +465,7 @@ void GPBCodedInputStreamCheckLastTagWas(GPBCodedInputStreamState *state,
extensionRegistry:(GPBExtensionRegistry *)extensionRegistry {
int32_t length = ReadRawVarint32(&state_);
if (state_.recursionDepth >= kDefaultRecursionLimit) {
- [NSException raise:NSParseErrorException
- format:@"recursionDepth(%tu) >= %tu", state_.recursionDepth,
- kDefaultRecursionLimit];
+ RaiseException(GPBCodedInputStreamErrorRecursionDepthExceeded, nil);
}
size_t oldLimit = GPBCodedInputStreamPushLimit(&state_, length);
++state_.recursionDepth;
@@ -436,9 +481,7 @@ void GPBCodedInputStreamCheckLastTagWas(GPBCodedInputStreamState *state,
parentMessage:(GPBMessage *)parentMessage {
int32_t length = ReadRawVarint32(&state_);
if (state_.recursionDepth >= kDefaultRecursionLimit) {
- [NSException raise:NSParseErrorException
- format:@"recursionDepth(%tu) >= %tu", state_.recursionDepth,
- kDefaultRecursionLimit];
+ RaiseException(GPBCodedInputStreamErrorRecursionDepthExceeded, nil);
}
size_t oldLimit = GPBCodedInputStreamPushLimit(&state_, length);
++state_.recursionDepth;
@@ -477,321 +520,6 @@ void GPBCodedInputStreamCheckLastTagWas(GPBCodedInputStreamState *state,
return GPBCodedInputStreamReadSInt64(&state_);
}
-@end
-
-@implementation GPBString {
- @package
- CFStringRef string_;
- unsigned char *utf8_;
- NSUInteger utf8Len_;
-
- // This lock is used to gate access to utf8_. Once GPBStringInitStringValue()
- // has been called, string_ will be filled in, and utf8_ will be NULL.
- OSSpinLock lock_;
-
- BOOL hasBOM_;
- BOOL is7BitAscii_;
-}
-
-// Returns true if the passed in bytes are 7 bit ascii.
-// This routine needs to be fast.
-static bool AreBytesIn7BitASCII(const uint8_t *bytes, NSUInteger len) {
-// In the loops below, it's more efficient to collect rather than do
-// conditional at every step.
-#if __LP64__
- // Align bytes. This is especially important in case of 3 byte BOM.
- while (len > 0 && ((size_t)bytes & 0x07)) {
- if (*bytes++ & 0x80) return false;
- len--;
- }
- while (len >= 32) {
- uint64_t val = *(const uint64_t *)bytes;
- uint64_t hiBits = (val & 0x8080808080808080ULL);
- bytes += 8;
- val = *(const uint64_t *)bytes;
- hiBits |= (val & 0x8080808080808080ULL);
- bytes += 8;
- val = *(const uint64_t *)bytes;
- hiBits |= (val & 0x8080808080808080ULL);
- bytes += 8;
- val = *(const uint64_t *)bytes;
- if (hiBits | (val & 0x8080808080808080ULL)) return false;
- bytes += 8;
- len -= 32;
- }
-
- while (len >= 16) {
- uint64_t val = *(const uint64_t *)bytes;
- uint64_t hiBits = (val & 0x8080808080808080ULL);
- bytes += 8;
- val = *(const uint64_t *)bytes;
- if (hiBits | (val & 0x8080808080808080ULL)) return false;
- bytes += 8;
- len -= 16;
- }
-
- while (len >= 8) {
- uint64_t val = *(const uint64_t *)bytes;
- if (val & 0x8080808080808080ULL) return false;
- bytes += 8;
- len -= 8;
- }
-#else // __LP64__
- // Align bytes. This is especially important in case of 3 byte BOM.
- while (len > 0 && ((size_t)bytes & 0x03)) {
- if (*bytes++ & 0x80) return false;
- len--;
- }
- while (len >= 16) {
- uint32_t val = *(const uint32_t *)bytes;
- uint32_t hiBits = (val & 0x80808080U);
- bytes += 4;
- val = *(const uint32_t *)bytes;
- hiBits |= (val & 0x80808080U);
- bytes += 4;
- val = *(const uint32_t *)bytes;
- hiBits |= (val & 0x80808080U);
- bytes += 4;
- val = *(const uint32_t *)bytes;
- if (hiBits | (val & 0x80808080U)) return false;
- bytes += 4;
- len -= 16;
- }
-
- while (len >= 8) {
- uint32_t val = *(const uint32_t *)bytes;
- uint32_t hiBits = (val & 0x80808080U);
- bytes += 4;
- val = *(const uint32_t *)bytes;
- if (hiBits | (val & 0x80808080U)) return false;
- bytes += 4;
- len -= 8;
- }
-#endif // __LP64__
-
- while (len >= 4) {
- uint32_t val = *(const uint32_t *)bytes;
- if (val & 0x80808080U) return false;
- bytes += 4;
- len -= 4;
- }
-
- while (len--) {
- if (*bytes++ & 0x80) return false;
- }
-
- return true;
-}
-
-static void GPBStringInitStringValue(GPBString *string) {
- OSSpinLockLock(&string->lock_);
- GPBStringInitStringValueAlreadyLocked(string);
- OSSpinLockUnlock(&string->lock_);
-}
-
-static void GPBStringInitStringValueAlreadyLocked(GPBString *string) {
- if (string->string_ == NULL && string->utf8_ != NULL) {
- // Using kCFAllocatorMalloc for contentsDeallocator, as buffer in
- // string->utf8_ is being handed off.
- string->string_ = CFStringCreateWithBytesNoCopy(
- NULL, string->utf8_, string->utf8Len_, kCFStringEncodingUTF8, false,
- kCFAllocatorMalloc);
- if (!string->string_) {
-#ifdef DEBUG
- // https://developers.google.com/protocol-buffers/docs/proto#scalar
- NSLog(@"UTF8 failure, is some field type 'string' when it should be "
- @"'bytes'?");
-#endif
- string->string_ = CFSTR("");
- string->utf8Len_ = 0;
- // On failure, we have to clean up the buffer.
- free(string->utf8_);
- }
- string->utf8_ = NULL;
- }
-}
-
-GPBString *GPBCreateGPBStringWithUTF8(const void *bytes, NSUInteger length) {
- GPBString *result = [[GPBString alloc] initWithBytes:bytes length:length];
- return result;
-}
-
-- (instancetype)initWithBytes:(const void *)bytes length:(NSUInteger)length {
- self = [super init];
- if (self) {
- utf8_ = malloc(length);
- memcpy(utf8_, bytes, length);
- utf8Len_ = length;
- lock_ = OS_SPINLOCK_INIT;
- is7BitAscii_ = AreBytesIn7BitASCII(bytes, length);
- if (length >= 3 && memcmp(utf8_, "\xef\xbb\xbf", 3) == 0) {
- // We can't just remove the BOM from the string here, because in the case
- // where we have > 1 BOM at the beginning of the string, we will remove one,
- // and the internal NSString we create will remove the next one, and we will
- // end up with a GPBString != NSString issue.
- // We also just can't remove all the BOMs because then we would end up with
- // potential cases where a GPBString and an NSString made with the same
- // UTF8 buffer would in fact be different.
- // We record the fact we have a BOM, and use it as necessary to simulate
- // what NSString would return for various calls.
- hasBOM_ = YES;
-#if DEBUG
- // Sending BOMs across the line is just wasting bits.
- NSLog(@"Bad data? String should not have BOM!");
-#endif // DEBUG
- }
- }
- return self;
-}
-
-- (void)dealloc {
- if (string_ != NULL) {
- CFRelease(string_);
- }
- if (utf8_ != NULL) {
- free(utf8_);
- }
- [super dealloc];
-}
-
-// Required NSString overrides.
-- (NSUInteger)length {
- if (is7BitAscii_) {
- return utf8Len_;
- } else {
- GPBStringInitStringValue(self);
- return CFStringGetLength(string_);
- }
-}
-
-- (unichar)characterAtIndex:(NSUInteger)anIndex {
- OSSpinLockLock(&lock_);
- if (is7BitAscii_ && utf8_) {
- unichar result = utf8_[anIndex];
- OSSpinLockUnlock(&lock_);
- return result;
- } else {
- GPBStringInitStringValueAlreadyLocked(self);
- OSSpinLockUnlock(&lock_);
- return CFStringGetCharacterAtIndex(string_, anIndex);
- }
-}
-
-// Override a couple of methods that typically want high performance.
-
-- (id)copyWithZone:(NSZone *)zone {
- GPBStringInitStringValue(self);
- return [(NSString *)string_ copyWithZone:zone];
-}
-
-- (id)mutableCopyWithZone:(NSZone *)zone {
- GPBStringInitStringValue(self);
- return [(NSString *)string_ mutableCopyWithZone:zone];
-}
-
-- (NSUInteger)hash {
- // Must convert to string here to make sure that the hash is always
- // consistent no matter what state the GPBString is in.
- GPBStringInitStringValue(self);
- return CFHash(string_);
-}
-
-- (BOOL)isEqual:(id)object {
- if (self == object) {
- return YES;
- }
- if ([object isKindOfClass:[NSString class]]) {
- GPBStringInitStringValue(self);
- return CFStringCompare(string_, (CFStringRef)object, 0) ==
- kCFCompareEqualTo;
- }
- return NO;
-}
-
-- (void)getCharacters:(unichar *)buffer range:(NSRange)aRange {
- OSSpinLockLock(&lock_);
- if (is7BitAscii_ && utf8_) {
- unsigned char *bytes = &(utf8_[aRange.location]);
- for (NSUInteger i = 0; i < aRange.length; ++i) {
- buffer[i] = bytes[i];
- }
- OSSpinLockUnlock(&lock_);
- } else {
- GPBStringInitStringValueAlreadyLocked(self);
- OSSpinLockUnlock(&lock_);
- CFStringGetCharacters(string_, CFRangeMake(aRange.location, aRange.length),
- buffer);
- }
-}
-
-- (NSUInteger)lengthOfBytesUsingEncoding:(NSStringEncoding)encoding {
- if ((encoding == NSUTF8StringEncoding) ||
- (encoding == NSASCIIStringEncoding && is7BitAscii_)) {
- return utf8Len_ - (hasBOM_ ? 3 : 0);
- } else {
- GPBStringInitStringValue(self);
- return [(NSString *)string_ lengthOfBytesUsingEncoding:encoding];
- }
-}
-
-- (BOOL)getBytes:(void *)buffer
- maxLength:(NSUInteger)maxLength
- usedLength:(NSUInteger *)usedLength
- encoding:(NSStringEncoding)encoding
- options:(NSStringEncodingConversionOptions)options
- range:(NSRange)range
- remainingRange:(NSRangePointer)remainingRange {
- // [NSString getBytes:maxLength:usedLength:encoding:options:range:remainingRange]
- // does not return reliable results if the maxLength argument is 0
- // (Radar 16385183). Therefore we have special cased it as a slow case so
- // that it behaves however Apple intends it to behave. It should be a rare
- // case.
- //
- // [NSString getBytes:maxLength:usedLength:encoding:options:range:remainingRange]
- // does not return reliable results if the range is outside of the strings
- // length (Radar 16396177). Therefore we have special cased it as a slow
- // case so that it behaves however Apple intends it to behave. It should
- // be a rare case.
- //
- // We can optimize the UTF8StringEncoding and NSASCIIStringEncoding with no
- // options cases.
- if ((options == 0) &&
- (encoding == NSUTF8StringEncoding || encoding == NSASCIIStringEncoding) &&
- (maxLength != 0) &&
- (NSMaxRange(range) <= utf8Len_)) {
- // Might be able to optimize it.
- OSSpinLockLock(&lock_);
- if (is7BitAscii_ && utf8_) {
- NSUInteger length = range.length;
- length = (length < maxLength) ? length : maxLength;
- memcpy(buffer, utf8_ + range.location, length);
- if (usedLength) {
- *usedLength = length;
- }
- if (remainingRange) {
- remainingRange->location = range.location + length;
- remainingRange->length = range.length - length;
- }
- OSSpinLockUnlock(&lock_);
- if (length > 0) {
- return YES;
- } else {
- return NO;
- }
- } else {
- GPBStringInitStringValueAlreadyLocked(self);
- OSSpinLockUnlock(&lock_);
- }
- } else {
- GPBStringInitStringValue(self);
- }
- return [(NSString *)string_ getBytes:buffer
- maxLength:maxLength
- usedLength:usedLength
- encoding:encoding
- options:options
- range:range
- remainingRange:remainingRange];
-}
+#pragma clang diagnostic pop
@end
diff --git a/objectivec/GPBCodedInputStream_PackagePrivate.h b/objectivec/GPBCodedInputStream_PackagePrivate.h
index e482b4c9..90bd0c92 100644
--- a/objectivec/GPBCodedInputStream_PackagePrivate.h
+++ b/objectivec/GPBCodedInputStream_PackagePrivate.h
@@ -39,19 +39,6 @@
@class GPBUnknownFieldSet;
@class GPBFieldDescriptor;
-// GPBString is a string subclass that avoids the overhead of initializing
-// a full NSString until it is actually needed. Lots of protocol buffers contain
-// strings, and instantiating all of those strings and having them parsed to
-// verify correctness when the message was being read was expensive, when many
-// of the strings were never being used.
-//
-// Note for future-self. I tried implementing this using a NSProxy.
-// Turned out the performance was horrible in client apps because folks
-// like to use libraries like SBJSON that grab characters one at a time.
-// The proxy overhead was a killer.
-@interface GPBString : NSString
-@end
-
typedef struct GPBCodedInputStreamState {
const uint8_t *bytes;
size_t bufferSize;
@@ -92,10 +79,6 @@ typedef struct GPBCodedInputStreamState {
CF_EXTERN_C_BEGIN
-// Returns a GPBString with a +1 retain count.
-GPBString *GPBCreateGPBStringWithUTF8(const void *bytes, NSUInteger length)
- __attribute__((ns_returns_retained));
-
int32_t GPBCodedInputStreamReadTag(GPBCodedInputStreamState *state);
double GPBCodedInputStreamReadDouble(GPBCodedInputStreamState *state);
diff --git a/objectivec/GPBCodedOutputStream.h b/objectivec/GPBCodedOutputStream.h
index a5aef170..8272880d 100644
--- a/objectivec/GPBCodedOutputStream.h
+++ b/objectivec/GPBCodedOutputStream.h
@@ -46,36 +46,63 @@
NS_ASSUME_NONNULL_BEGIN
+/// Writes out protocol message fields.
+///
+/// The common uses of protocol buffers shouldn't need to use this class.
+/// @c GPBMessage's provide a @c -data method that will serialize the message
+/// for you.
+///
+/// @note Subclassing of GPBCodedOutputStream is NOT supported.
@interface GPBCodedOutputStream : NSObject
-// Creates a new stream to write into data. Data must be sized to fit or it
-// will error when it runs out of space.
+/// Creates a stream to fill in the given data. Data must be sized to fit or
+/// an error will be raised when out of space.
+ (instancetype)streamWithData:(NSMutableData *)data;
+
+/// Creates a stream to write into the given @c NSOutputStream.
+ (instancetype)streamWithOutputStream:(NSOutputStream *)output;
-+ (instancetype)streamWithOutputStream:(NSOutputStream *)output
- bufferSize:(size_t)bufferSize;
+/// Initializes a stream to fill in the given data. Data must be sized to fit
+/// or an error will be raised when out of space.
- (instancetype)initWithData:(NSMutableData *)data;
+
+/// Initializes a stream to write into the given @c NSOutputStream.
- (instancetype)initWithOutputStream:(NSOutputStream *)output;
-- (instancetype)initWithOutputStream:(NSOutputStream *)output
- bufferSize:(size_t)bufferSize;
+/// Flush any buffered data out.
- (void)flush;
+/// Write the raw byte out.
- (void)writeRawByte:(uint8_t)value;
+/// Write the tag for the given field number and wire format.
+///
+/// @param fieldNumber The field number.
+/// @param format The wire format the data for the field will be in.
- (void)writeTag:(uint32_t)fieldNumber format:(GPBWireFormat)format;
+/// Write a 32bit value out in little endian format.
- (void)writeRawLittleEndian32:(int32_t)value;
+/// Write a 64bit value out in little endian format.
- (void)writeRawLittleEndian64:(int64_t)value;
+/// Write a 32bit value out in varint format.
- (void)writeRawVarint32:(int32_t)value;
+/// Write a 64bit value out in varint format.
- (void)writeRawVarint64:(int64_t)value;
-// Note that this will truncate 64 bit values to 32.
+/// Write a size_t out as a 32bit varint value.
+///
+/// @note This will truncate 64 bit values to 32.
- (void)writeRawVarintSizeTAs32:(size_t)value;
+/// Writes the contents of an @c NSData out.
- (void)writeRawData:(NSData *)data;
+/// Writes out the given data.
+///
+/// @param data The data blob to write out.
+/// @param offset The offset into the blob to start writing out.
+/// @param length The number of bytes from the blob to write out.
- (void)writeRawPtr:(const void *)data
offset:(size_t)offset
length:(size_t)length;
@@ -83,240 +110,215 @@ NS_ASSUME_NONNULL_BEGIN
//%PDDM-EXPAND _WRITE_DECLS()
// This block of code is generated, do not edit it directly.
+/// Write a double for the given field number.
- (void)writeDouble:(int32_t)fieldNumber value:(double)value;
+/// Write a packed array of double for the given field number.
- (void)writeDoubleArray:(int32_t)fieldNumber
values:(GPBDoubleArray *)values
tag:(uint32_t)tag;
+/// Write a double without any tag.
- (void)writeDoubleNoTag:(double)value;
+/// Write a float for the given field number.
- (void)writeFloat:(int32_t)fieldNumber value:(float)value;
+/// Write a packed array of float for the given field number.
- (void)writeFloatArray:(int32_t)fieldNumber
values:(GPBFloatArray *)values
tag:(uint32_t)tag;
+/// Write a float without any tag.
- (void)writeFloatNoTag:(float)value;
+/// Write a uint64_t for the given field number.
- (void)writeUInt64:(int32_t)fieldNumber value:(uint64_t)value;
+/// Write a packed array of uint64_t for the given field number.
- (void)writeUInt64Array:(int32_t)fieldNumber
values:(GPBUInt64Array *)values
tag:(uint32_t)tag;
+/// Write a uint64_t without any tag.
- (void)writeUInt64NoTag:(uint64_t)value;
+/// Write a int64_t for the given field number.
- (void)writeInt64:(int32_t)fieldNumber value:(int64_t)value;
+/// Write a packed array of int64_t for the given field number.
- (void)writeInt64Array:(int32_t)fieldNumber
values:(GPBInt64Array *)values
tag:(uint32_t)tag;
+/// Write a int64_t without any tag.
- (void)writeInt64NoTag:(int64_t)value;
+/// Write a int32_t for the given field number.
- (void)writeInt32:(int32_t)fieldNumber value:(int32_t)value;
+/// Write a packed array of int32_t for the given field number.
- (void)writeInt32Array:(int32_t)fieldNumber
values:(GPBInt32Array *)values
tag:(uint32_t)tag;
+/// Write a int32_t without any tag.
- (void)writeInt32NoTag:(int32_t)value;
+/// Write a uint32_t for the given field number.
- (void)writeUInt32:(int32_t)fieldNumber value:(uint32_t)value;
+/// Write a packed array of uint32_t for the given field number.
- (void)writeUInt32Array:(int32_t)fieldNumber
values:(GPBUInt32Array *)values
tag:(uint32_t)tag;
+/// Write a uint32_t without any tag.
- (void)writeUInt32NoTag:(uint32_t)value;
+/// Write a uint64_t for the given field number.
- (void)writeFixed64:(int32_t)fieldNumber value:(uint64_t)value;
+/// Write a packed array of uint64_t for the given field number.
- (void)writeFixed64Array:(int32_t)fieldNumber
values:(GPBUInt64Array *)values
tag:(uint32_t)tag;
+/// Write a uint64_t without any tag.
- (void)writeFixed64NoTag:(uint64_t)value;
+/// Write a uint32_t for the given field number.
- (void)writeFixed32:(int32_t)fieldNumber value:(uint32_t)value;
+/// Write a packed array of uint32_t for the given field number.
- (void)writeFixed32Array:(int32_t)fieldNumber
values:(GPBUInt32Array *)values
tag:(uint32_t)tag;
+/// Write a uint32_t without any tag.
- (void)writeFixed32NoTag:(uint32_t)value;
+/// Write a int32_t for the given field number.
- (void)writeSInt32:(int32_t)fieldNumber value:(int32_t)value;
+/// Write a packed array of int32_t for the given field number.
- (void)writeSInt32Array:(int32_t)fieldNumber
values:(GPBInt32Array *)values
tag:(uint32_t)tag;
+/// Write a int32_t without any tag.
- (void)writeSInt32NoTag:(int32_t)value;
+/// Write a int64_t for the given field number.
- (void)writeSInt64:(int32_t)fieldNumber value:(int64_t)value;
+/// Write a packed array of int64_t for the given field number.
- (void)writeSInt64Array:(int32_t)fieldNumber
values:(GPBInt64Array *)values
tag:(uint32_t)tag;
+/// Write a int64_t without any tag.
- (void)writeSInt64NoTag:(int64_t)value;
+/// Write a int64_t for the given field number.
- (void)writeSFixed64:(int32_t)fieldNumber value:(int64_t)value;
+/// Write a packed array of int64_t for the given field number.
- (void)writeSFixed64Array:(int32_t)fieldNumber
values:(GPBInt64Array *)values
tag:(uint32_t)tag;
+/// Write a int64_t without any tag.
- (void)writeSFixed64NoTag:(int64_t)value;
+/// Write a int32_t for the given field number.
- (void)writeSFixed32:(int32_t)fieldNumber value:(int32_t)value;
+/// Write a packed array of int32_t for the given field number.
- (void)writeSFixed32Array:(int32_t)fieldNumber
values:(GPBInt32Array *)values
tag:(uint32_t)tag;
+/// Write a int32_t without any tag.
- (void)writeSFixed32NoTag:(int32_t)value;
+/// Write a BOOL for the given field number.
- (void)writeBool:(int32_t)fieldNumber value:(BOOL)value;
+/// Write a packed array of BOOL for the given field number.
- (void)writeBoolArray:(int32_t)fieldNumber
values:(GPBBoolArray *)values
tag:(uint32_t)tag;
+/// Write a BOOL without any tag.
- (void)writeBoolNoTag:(BOOL)value;
+/// Write a int32_t for the given field number.
- (void)writeEnum:(int32_t)fieldNumber value:(int32_t)value;
+/// Write a packed array of int32_t for the given field number.
- (void)writeEnumArray:(int32_t)fieldNumber
values:(GPBEnumArray *)values
tag:(uint32_t)tag;
+/// Write a int32_t without any tag.
- (void)writeEnumNoTag:(int32_t)value;
+/// Write a NSString for the given field number.
- (void)writeString:(int32_t)fieldNumber value:(NSString *)value;
-- (void)writeStringArray:(int32_t)fieldNumber values:(NSArray *)values;
+/// Write an array of NSString for the given field number.
+- (void)writeStringArray:(int32_t)fieldNumber values:(NSArray<NSString*> *)values;
+/// Write a NSString without any tag.
- (void)writeStringNoTag:(NSString *)value;
+/// Write a GPBMessage for the given field number.
- (void)writeMessage:(int32_t)fieldNumber value:(GPBMessage *)value;
-- (void)writeMessageArray:(int32_t)fieldNumber values:(NSArray *)values;
+/// Write an array of GPBMessage for the given field number.
+- (void)writeMessageArray:(int32_t)fieldNumber values:(NSArray<GPBMessage*> *)values;
+/// Write a GPBMessage without any tag.
- (void)writeMessageNoTag:(GPBMessage *)value;
+/// Write a NSData for the given field number.
- (void)writeBytes:(int32_t)fieldNumber value:(NSData *)value;
-- (void)writeBytesArray:(int32_t)fieldNumber values:(NSArray *)values;
+/// Write an array of NSData for the given field number.
+- (void)writeBytesArray:(int32_t)fieldNumber values:(NSArray<NSData*> *)values;
+/// Write a NSData without any tag.
- (void)writeBytesNoTag:(NSData *)value;
+/// Write a GPBMessage for the given field number.
- (void)writeGroup:(int32_t)fieldNumber
value:(GPBMessage *)value;
-- (void)writeGroupArray:(int32_t)fieldNumber values:(NSArray *)values;
+/// Write an array of GPBMessage for the given field number.
+- (void)writeGroupArray:(int32_t)fieldNumber values:(NSArray<GPBMessage*> *)values;
+/// Write a GPBMessage without any tag (but does write the endGroup tag).
- (void)writeGroupNoTag:(int32_t)fieldNumber
value:(GPBMessage *)value;
+/// Write a GPBUnknownFieldSet for the given field number.
- (void)writeUnknownGroup:(int32_t)fieldNumber
value:(GPBUnknownFieldSet *)value;
-- (void)writeUnknownGroupArray:(int32_t)fieldNumber values:(NSArray *)values;
+/// Write an array of GPBUnknownFieldSet for the given field number.
+- (void)writeUnknownGroupArray:(int32_t)fieldNumber values:(NSArray<GPBUnknownFieldSet*> *)values;
+/// Write a GPBUnknownFieldSet without any tag (but does write the endGroup tag).
- (void)writeUnknownGroupNoTag:(int32_t)fieldNumber
value:(GPBUnknownFieldSet *)value;
//%PDDM-EXPAND-END _WRITE_DECLS()
-// Write a MessageSet extension field to the stream. For historical reasons,
-// the wire format differs from normal fields.
+/// Write a MessageSet extension field to the stream. For historical reasons,
+/// the wire format differs from normal fields.
- (void)writeMessageSetExtension:(int32_t)fieldNumber value:(GPBMessage *)value;
-// Write an unparsed MessageSet extension field to the stream. For
-// historical reasons, the wire format differs from normal fields.
+/// Write an unparsed MessageSet extension field to the stream. For
+/// historical reasons, the wire format differs from normal fields.
- (void)writeRawMessageSetExtension:(int32_t)fieldNumber value:(NSData *)value;
@end
-CF_EXTERN_C_BEGIN
-
-size_t GPBComputeDoubleSize(int32_t fieldNumber, double value)
- __attribute__((const));
-size_t GPBComputeFloatSize(int32_t fieldNumber, float value)
- __attribute__((const));
-size_t GPBComputeUInt64Size(int32_t fieldNumber, uint64_t value)
- __attribute__((const));
-size_t GPBComputeInt64Size(int32_t fieldNumber, int64_t value)
- __attribute__((const));
-size_t GPBComputeInt32Size(int32_t fieldNumber, int32_t value)
- __attribute__((const));
-size_t GPBComputeFixed64Size(int32_t fieldNumber, uint64_t value)
- __attribute__((const));
-size_t GPBComputeFixed32Size(int32_t fieldNumber, uint32_t value)
- __attribute__((const));
-size_t GPBComputeBoolSize(int32_t fieldNumber, BOOL value)
- __attribute__((const));
-size_t GPBComputeStringSize(int32_t fieldNumber, NSString *value)
- __attribute__((const));
-size_t GPBComputeGroupSize(int32_t fieldNumber, GPBMessage *value)
- __attribute__((const));
-size_t GPBComputeUnknownGroupSize(int32_t fieldNumber,
- GPBUnknownFieldSet *value)
- __attribute__((const));
-size_t GPBComputeMessageSize(int32_t fieldNumber, GPBMessage *value)
- __attribute__((const));
-size_t GPBComputeBytesSize(int32_t fieldNumber, NSData *value)
- __attribute__((const));
-size_t GPBComputeUInt32Size(int32_t fieldNumber, uint32_t value)
- __attribute__((const));
-size_t GPBComputeSFixed32Size(int32_t fieldNumber, int32_t value)
- __attribute__((const));
-size_t GPBComputeSFixed64Size(int32_t fieldNumber, int64_t value)
- __attribute__((const));
-size_t GPBComputeSInt32Size(int32_t fieldNumber, int32_t value)
- __attribute__((const));
-size_t GPBComputeSInt64Size(int32_t fieldNumber, int64_t value)
- __attribute__((const));
-size_t GPBComputeTagSize(int32_t fieldNumber) __attribute__((const));
-size_t GPBComputeWireFormatTagSize(int field_number, GPBDataType dataType)
- __attribute__((const));
-
-size_t GPBComputeDoubleSizeNoTag(double value) __attribute__((const));
-size_t GPBComputeFloatSizeNoTag(float value) __attribute__((const));
-size_t GPBComputeUInt64SizeNoTag(uint64_t value) __attribute__((const));
-size_t GPBComputeInt64SizeNoTag(int64_t value) __attribute__((const));
-size_t GPBComputeInt32SizeNoTag(int32_t value) __attribute__((const));
-size_t GPBComputeFixed64SizeNoTag(uint64_t value) __attribute__((const));
-size_t GPBComputeFixed32SizeNoTag(uint32_t value) __attribute__((const));
-size_t GPBComputeBoolSizeNoTag(BOOL value) __attribute__((const));
-size_t GPBComputeStringSizeNoTag(NSString *value) __attribute__((const));
-size_t GPBComputeGroupSizeNoTag(GPBMessage *value) __attribute__((const));
-size_t GPBComputeUnknownGroupSizeNoTag(GPBUnknownFieldSet *value)
- __attribute__((const));
-size_t GPBComputeMessageSizeNoTag(GPBMessage *value) __attribute__((const));
-size_t GPBComputeBytesSizeNoTag(NSData *value) __attribute__((const));
-size_t GPBComputeUInt32SizeNoTag(int32_t value) __attribute__((const));
-size_t GPBComputeEnumSizeNoTag(int32_t value) __attribute__((const));
-size_t GPBComputeSFixed32SizeNoTag(int32_t value) __attribute__((const));
-size_t GPBComputeSFixed64SizeNoTag(int64_t value) __attribute__((const));
-size_t GPBComputeSInt32SizeNoTag(int32_t value) __attribute__((const));
-size_t GPBComputeSInt64SizeNoTag(int64_t value) __attribute__((const));
-
-// Note that this will calculate the size of 64 bit values truncated to 32.
-size_t GPBComputeSizeTSizeAsInt32NoTag(size_t value) __attribute__((const));
-
-size_t GPBComputeRawVarint32Size(int32_t value) __attribute__((const));
-size_t GPBComputeRawVarint64Size(int64_t value) __attribute__((const));
-
-// Note that this will calculate the size of 64 bit values truncated to 32.
-size_t GPBComputeRawVarint32SizeForInteger(NSInteger value)
- __attribute__((const));
-
-// Compute the number of bytes that would be needed to encode a
-// MessageSet extension to the stream. For historical reasons,
-// the wire format differs from normal fields.
-size_t GPBComputeMessageSetExtensionSize(int32_t fieldNumber, GPBMessage *value)
- __attribute__((const));
-
-// Compute the number of bytes that would be needed to encode an
-// unparsed MessageSet extension field to the stream. For
-// historical reasons, the wire format differs from normal fields.
-size_t GPBComputeRawMessageSetExtensionSize(int32_t fieldNumber, NSData *value)
- __attribute__((const));
-
-size_t GPBComputeEnumSize(int32_t fieldNumber, int32_t value)
- __attribute__((const));
-
-CF_EXTERN_C_END
-
NS_ASSUME_NONNULL_END
// Write methods for types that can be in packed arrays.
//%PDDM-DEFINE _WRITE_PACKABLE_DECLS(NAME, ARRAY_TYPE, TYPE)
+//%/// Write a TYPE for the given field number.
//%- (void)write##NAME:(int32_t)fieldNumber value:(TYPE)value;
+//%/// Write a packed array of TYPE for the given field number.
//%- (void)write##NAME##Array:(int32_t)fieldNumber
//% NAME$S values:(GPB##ARRAY_TYPE##Array *)values
//% NAME$S tag:(uint32_t)tag;
+//%/// Write a TYPE without any tag.
//%- (void)write##NAME##NoTag:(TYPE)value;
//%
// Write methods for types that aren't in packed arrays.
//%PDDM-DEFINE _WRITE_UNPACKABLE_DECLS(NAME, TYPE)
-//%- (void)write##NAME:(int32_t)fieldNumber value:(TYPE)value;
-//%- (void)write##NAME##Array:(int32_t)fieldNumber values:(NSArray *)values;
-//%- (void)write##NAME##NoTag:(TYPE)value;
+//%/// Write a TYPE for the given field number.
+//%- (void)write##NAME:(int32_t)fieldNumber value:(TYPE *)value;
+//%/// Write an array of TYPE for the given field number.
+//%- (void)write##NAME##Array:(int32_t)fieldNumber values:(NSArray<##TYPE##*> *)values;
+//%/// Write a TYPE without any tag.
+//%- (void)write##NAME##NoTag:(TYPE *)value;
//%
// Special write methods for Groups.
//%PDDM-DEFINE _WRITE_GROUP_DECLS(NAME, TYPE)
+//%/// Write a TYPE for the given field number.
//%- (void)write##NAME:(int32_t)fieldNumber
-//% NAME$S value:(TYPE)value;
-//%- (void)write##NAME##Array:(int32_t)fieldNumber values:(NSArray *)values;
+//% NAME$S value:(TYPE *)value;
+//%/// Write an array of TYPE for the given field number.
+//%- (void)write##NAME##Array:(int32_t)fieldNumber values:(NSArray<##TYPE##*> *)values;
+//%/// Write a TYPE without any tag (but does write the endGroup tag).
//%- (void)write##NAME##NoTag:(int32_t)fieldNumber
-//% NAME$S value:(TYPE)value;
+//% NAME$S value:(TYPE *)value;
//%
// One macro to hide it all up above.
@@ -335,8 +337,8 @@ NS_ASSUME_NONNULL_END
//%_WRITE_PACKABLE_DECLS(SFixed32, Int32, int32_t)
//%_WRITE_PACKABLE_DECLS(Bool, Bool, BOOL)
//%_WRITE_PACKABLE_DECLS(Enum, Enum, int32_t)
-//%_WRITE_UNPACKABLE_DECLS(String, NSString *)
-//%_WRITE_UNPACKABLE_DECLS(Message, GPBMessage *)
-//%_WRITE_UNPACKABLE_DECLS(Bytes, NSData *)
-//%_WRITE_GROUP_DECLS(Group, GPBMessage *)
-//%_WRITE_GROUP_DECLS(UnknownGroup, GPBUnknownFieldSet *)
+//%_WRITE_UNPACKABLE_DECLS(String, NSString)
+//%_WRITE_UNPACKABLE_DECLS(Message, GPBMessage)
+//%_WRITE_UNPACKABLE_DECLS(Bytes, NSData)
+//%_WRITE_GROUP_DECLS(Group, GPBMessage)
+//%_WRITE_GROUP_DECLS(UnknownGroup, GPBUnknownFieldSet)
diff --git a/objectivec/GPBCodedOutputStream.m b/objectivec/GPBCodedOutputStream.m
index 70142e6f..63ba8068 100644
--- a/objectivec/GPBCodedOutputStream.m
+++ b/objectivec/GPBCodedOutputStream.m
@@ -28,7 +28,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#import "GPBCodedOutputStream.h"
+#import "GPBCodedOutputStream_PackagePrivate.h"
#import <mach/vm_param.h>
@@ -144,7 +144,7 @@ static void GPBWriteRawLittleEndian64(GPBOutputBufferState *state,
GPBWriteRawByte(state, (int32_t)(value >> 56) & 0xFF);
}
-#if DEBUG && !defined(NS_BLOCK_ASSERTIONS)
+#if defined(DEBUG) && DEBUG && !defined(NS_BLOCK_ASSERTIONS)
+ (void)load {
// This test exists to verify that CFStrings with embedded NULLs will work
// for us. If this Assert fails, all code below that depends on
@@ -178,12 +178,6 @@ static void GPBWriteRawLittleEndian64(GPBOutputBufferState *state,
return [self initWithOutputStream:nil data:data];
}
-- (instancetype)initWithOutputStream:(NSOutputStream *)output
- bufferSize:(size_t)bufferSize {
- NSMutableData *data = [NSMutableData dataWithLength:bufferSize];
- return [self initWithOutputStream:output data:data];
-}
-
// This initializer isn't exposed, but it is the designated initializer.
// Setting OutputStream and NSData is to control the buffering behavior/size
// of the work, but that is more obvious via the bufferSize: version.
@@ -199,21 +193,22 @@ static void GPBWriteRawLittleEndian64(GPBOutputBufferState *state,
return self;
}
-+ (instancetype)streamWithOutputStream:(NSOutputStream *)output
- bufferSize:(size_t)bufferSize {
- return [[[self alloc] initWithOutputStream:output
- bufferSize:bufferSize] autorelease];
-}
-
+ (instancetype)streamWithOutputStream:(NSOutputStream *)output {
+ NSMutableData *data = [NSMutableData dataWithLength:PAGE_SIZE];
return [[[self alloc] initWithOutputStream:output
- bufferSize:PAGE_SIZE] autorelease];
+ data:data] autorelease];
}
+ (instancetype)streamWithData:(NSMutableData *)data {
return [[[self alloc] initWithData:data] autorelease];
}
+// Direct access is use for speed, to avoid even internally declaring things
+// read/write, etc. The warning is enabled in the project to ensure code calling
+// protos can turn on -Wdirect-ivar-access without issues.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdirect-ivar-access"
+
- (void)writeDoubleNoTag:(double)value {
GPBWriteRawLittleEndian64(&state_, GPBConvertDoubleToInt64(value));
}
@@ -992,6 +987,8 @@ static void GPBWriteRawLittleEndian64(GPBOutputBufferState *state,
GPBWriteRawLittleEndian64(&state_, value);
}
+#pragma clang diagnostic pop
+
@end
size_t GPBComputeDoubleSizeNoTag(Float64 value) {
diff --git a/objectivec/GPBCodedOutputStream_PackagePrivate.h b/objectivec/GPBCodedOutputStream_PackagePrivate.h
new file mode 100644
index 00000000..2e7bb4c4
--- /dev/null
+++ b/objectivec/GPBCodedOutputStream_PackagePrivate.h
@@ -0,0 +1,126 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2016 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.
+
+#import "GPBCodedOutputStream.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+CF_EXTERN_C_BEGIN
+
+size_t GPBComputeDoubleSize(int32_t fieldNumber, double value)
+ __attribute__((const));
+size_t GPBComputeFloatSize(int32_t fieldNumber, float value)
+ __attribute__((const));
+size_t GPBComputeUInt64Size(int32_t fieldNumber, uint64_t value)
+ __attribute__((const));
+size_t GPBComputeInt64Size(int32_t fieldNumber, int64_t value)
+ __attribute__((const));
+size_t GPBComputeInt32Size(int32_t fieldNumber, int32_t value)
+ __attribute__((const));
+size_t GPBComputeFixed64Size(int32_t fieldNumber, uint64_t value)
+ __attribute__((const));
+size_t GPBComputeFixed32Size(int32_t fieldNumber, uint32_t value)
+ __attribute__((const));
+size_t GPBComputeBoolSize(int32_t fieldNumber, BOOL value)
+ __attribute__((const));
+size_t GPBComputeStringSize(int32_t fieldNumber, NSString *value)
+ __attribute__((const));
+size_t GPBComputeGroupSize(int32_t fieldNumber, GPBMessage *value)
+ __attribute__((const));
+size_t GPBComputeUnknownGroupSize(int32_t fieldNumber,
+ GPBUnknownFieldSet *value)
+ __attribute__((const));
+size_t GPBComputeMessageSize(int32_t fieldNumber, GPBMessage *value)
+ __attribute__((const));
+size_t GPBComputeBytesSize(int32_t fieldNumber, NSData *value)
+ __attribute__((const));
+size_t GPBComputeUInt32Size(int32_t fieldNumber, uint32_t value)
+ __attribute__((const));
+size_t GPBComputeSFixed32Size(int32_t fieldNumber, int32_t value)
+ __attribute__((const));
+size_t GPBComputeSFixed64Size(int32_t fieldNumber, int64_t value)
+ __attribute__((const));
+size_t GPBComputeSInt32Size(int32_t fieldNumber, int32_t value)
+ __attribute__((const));
+size_t GPBComputeSInt64Size(int32_t fieldNumber, int64_t value)
+ __attribute__((const));
+size_t GPBComputeTagSize(int32_t fieldNumber) __attribute__((const));
+size_t GPBComputeWireFormatTagSize(int field_number, GPBDataType dataType)
+ __attribute__((const));
+
+size_t GPBComputeDoubleSizeNoTag(double value) __attribute__((const));
+size_t GPBComputeFloatSizeNoTag(float value) __attribute__((const));
+size_t GPBComputeUInt64SizeNoTag(uint64_t value) __attribute__((const));
+size_t GPBComputeInt64SizeNoTag(int64_t value) __attribute__((const));
+size_t GPBComputeInt32SizeNoTag(int32_t value) __attribute__((const));
+size_t GPBComputeFixed64SizeNoTag(uint64_t value) __attribute__((const));
+size_t GPBComputeFixed32SizeNoTag(uint32_t value) __attribute__((const));
+size_t GPBComputeBoolSizeNoTag(BOOL value) __attribute__((const));
+size_t GPBComputeStringSizeNoTag(NSString *value) __attribute__((const));
+size_t GPBComputeGroupSizeNoTag(GPBMessage *value) __attribute__((const));
+size_t GPBComputeUnknownGroupSizeNoTag(GPBUnknownFieldSet *value)
+ __attribute__((const));
+size_t GPBComputeMessageSizeNoTag(GPBMessage *value) __attribute__((const));
+size_t GPBComputeBytesSizeNoTag(NSData *value) __attribute__((const));
+size_t GPBComputeUInt32SizeNoTag(int32_t value) __attribute__((const));
+size_t GPBComputeEnumSizeNoTag(int32_t value) __attribute__((const));
+size_t GPBComputeSFixed32SizeNoTag(int32_t value) __attribute__((const));
+size_t GPBComputeSFixed64SizeNoTag(int64_t value) __attribute__((const));
+size_t GPBComputeSInt32SizeNoTag(int32_t value) __attribute__((const));
+size_t GPBComputeSInt64SizeNoTag(int64_t value) __attribute__((const));
+
+// Note that this will calculate the size of 64 bit values truncated to 32.
+size_t GPBComputeSizeTSizeAsInt32NoTag(size_t value) __attribute__((const));
+
+size_t GPBComputeRawVarint32Size(int32_t value) __attribute__((const));
+size_t GPBComputeRawVarint64Size(int64_t value) __attribute__((const));
+
+// Note that this will calculate the size of 64 bit values truncated to 32.
+size_t GPBComputeRawVarint32SizeForInteger(NSInteger value)
+ __attribute__((const));
+
+// Compute the number of bytes that would be needed to encode a
+// MessageSet extension to the stream. For historical reasons,
+// the wire format differs from normal fields.
+size_t GPBComputeMessageSetExtensionSize(int32_t fieldNumber, GPBMessage *value)
+ __attribute__((const));
+
+// Compute the number of bytes that would be needed to encode an
+// unparsed MessageSet extension field to the stream. For
+// historical reasons, the wire format differs from normal fields.
+size_t GPBComputeRawMessageSetExtensionSize(int32_t fieldNumber, NSData *value)
+ __attribute__((const));
+
+size_t GPBComputeEnumSize(int32_t fieldNumber, int32_t value)
+ __attribute__((const));
+
+CF_EXTERN_C_END
+
+NS_ASSUME_NONNULL_END
diff --git a/objectivec/GPBDescriptor.h b/objectivec/GPBDescriptor.h
index 360afe96..fe4ff390 100644
--- a/objectivec/GPBDescriptor.h
+++ b/objectivec/GPBDescriptor.h
@@ -34,19 +34,18 @@
@class GPBEnumDescriptor;
@class GPBFieldDescriptor;
-@class GPBFieldOptions;
@class GPBFileDescriptor;
@class GPBOneofDescriptor;
NS_ASSUME_NONNULL_BEGIN
-typedef NS_ENUM(NSInteger, GPBFileSyntax) {
+typedef NS_ENUM(uint8_t, GPBFileSyntax) {
GPBFileSyntaxUnknown = 0,
GPBFileSyntaxProto2 = 2,
GPBFileSyntaxProto3 = 3,
};
-typedef NS_ENUM(NSInteger, GPBFieldType) {
+typedef NS_ENUM(uint8_t, GPBFieldType) {
GPBFieldTypeSingle, // optional/required
GPBFieldTypeRepeated, // repeated
GPBFieldTypeMap, // map<K,V>
@@ -55,11 +54,10 @@ typedef NS_ENUM(NSInteger, GPBFieldType) {
@interface GPBDescriptor : NSObject<NSCopying>
@property(nonatomic, readonly, copy) NSString *name;
-@property(nonatomic, readonly, strong, nullable) NSArray *fields;
-@property(nonatomic, readonly, strong, nullable) NSArray *oneofs;
-@property(nonatomic, readonly, strong, nullable) NSArray *enums;
+@property(nonatomic, readonly, strong, nullable) NSArray<GPBFieldDescriptor*> *fields;
+@property(nonatomic, readonly, strong, nullable) NSArray<GPBOneofDescriptor*> *oneofs;
@property(nonatomic, readonly, nullable) const GPBExtensionRange *extensionRanges;
-@property(nonatomic, readonly) NSUInteger extensionRangesCount;
+@property(nonatomic, readonly) uint32_t extensionRangesCount;
@property(nonatomic, readonly, assign) GPBFileDescriptor *file;
@property(nonatomic, readonly, getter=isWireFormat) BOOL wireFormat;
@@ -68,7 +66,6 @@ typedef NS_ENUM(NSInteger, GPBFieldType) {
- (nullable GPBFieldDescriptor *)fieldWithNumber:(uint32_t)fieldNumber;
- (nullable GPBFieldDescriptor *)fieldWithName:(NSString *)name;
- (nullable GPBOneofDescriptor *)oneofWithName:(NSString *)name;
-- (nullable GPBEnumDescriptor *)enumWithName:(NSString *)name;
@end
@@ -81,7 +78,7 @@ typedef NS_ENUM(NSInteger, GPBFieldType) {
@interface GPBOneofDescriptor : NSObject
@property(nonatomic, readonly) NSString *name;
-@property(nonatomic, readonly) NSArray *fields;
+@property(nonatomic, readonly) NSArray<GPBFieldDescriptor*> *fields;
- (nullable GPBFieldDescriptor *)fieldWithNumber:(uint32_t)fieldNumber;
- (nullable GPBFieldDescriptor *)fieldWithName:(NSString *)name;
@@ -103,8 +100,6 @@ typedef NS_ENUM(NSInteger, GPBFieldType) {
@property(nonatomic, readonly, assign, nullable) GPBOneofDescriptor *containingOneof;
-@property(nonatomic, readonly, nullable) GPBFieldOptions *fieldOptions;
-
// Message properties
@property(nonatomic, readonly, assign, nullable) Class msgClass;
@@ -128,6 +123,7 @@ typedef NS_ENUM(NSInteger, GPBFieldType) {
- (BOOL)getValue:(nullable int32_t *)outValue forEnumName:(NSString *)name;
- (nullable NSString *)textFormatNameForValue:(int32_t)number;
+- (BOOL)getValue:(nullable int32_t *)outValue forEnumTextFormatName:(NSString *)textFormatName;
@end
@@ -140,7 +136,7 @@ typedef NS_ENUM(NSInteger, GPBFieldType) {
@property(nonatomic, readonly, assign) Class msgClass;
@property(nonatomic, readonly) NSString *singletonName;
@property(nonatomic, readonly, strong, nullable) GPBEnumDescriptor *enumDescriptor;
-@property(nonatomic, readonly) id defaultValue;
+@property(nonatomic, readonly, nullable) id defaultValue;
@end
NS_ASSUME_NONNULL_END
diff --git a/objectivec/GPBDescriptor.m b/objectivec/GPBDescriptor.m
index bae9187e..dccb9bc8 100644
--- a/objectivec/GPBDescriptor.m
+++ b/objectivec/GPBDescriptor.m
@@ -35,7 +35,12 @@
#import "GPBUtilities_PackagePrivate.h"
#import "GPBWireFormat.h"
#import "GPBMessage_PackagePrivate.h"
-#import "google/protobuf/Descriptor.pbobjc.h"
+
+// Direct access is use for speed, to avoid even internally declaring things
+// read/write, etc. The warning is enabled in the project to ensure code calling
+// protos can turn on -Wdirect-ivar-access without issues.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdirect-ivar-access"
// The address of this variable is used as a key for obj_getAssociatedObject.
static const char kTextFormatExtraValueKey = 0;
@@ -92,7 +97,6 @@ static NSArray *NewFieldsArrayForHasIndex(int hasIndex,
@implementation GPBDescriptor {
Class messageClass_;
- NSArray *enums_;
GPBFileDescriptor *file_;
BOOL wireFormat_;
}
@@ -100,7 +104,6 @@ static NSArray *NewFieldsArrayForHasIndex(int hasIndex,
@synthesize messageClass = messageClass_;
@synthesize fields = fields_;
@synthesize oneofs = oneofs_;
-@synthesize enums = enums_;
@synthesize extensionRanges = extensionRanges_;
@synthesize extensionRangesCount = extensionRangesCount_;
@synthesize file = file_;
@@ -110,130 +113,58 @@ static NSArray *NewFieldsArrayForHasIndex(int hasIndex,
allocDescriptorForClass:(Class)messageClass
rootClass:(Class)rootClass
file:(GPBFileDescriptor *)file
- fields:(GPBMessageFieldDescription *)fieldDescriptions
- fieldCount:(NSUInteger)fieldCount
- oneofs:(GPBMessageOneofDescription *)oneofDescriptions
- oneofCount:(NSUInteger)oneofCount
- enums:(GPBMessageEnumDescription *)enumDescriptions
- enumCount:(NSUInteger)enumCount
- ranges:(const GPBExtensionRange *)ranges
- rangeCount:(NSUInteger)rangeCount
- storageSize:(size_t)storageSize
- wireFormat:(BOOL)wireFormat {
+ fields:(void *)fieldDescriptions
+ fieldCount:(uint32_t)fieldCount
+ storageSize:(uint32_t)storageSize
+ flags:(GPBDescriptorInitializationFlags)flags {
+ // The rootClass is no longer used, but it is passed in to ensure it
+ // was started up during initialization also.
+ (void)rootClass;
NSMutableArray *fields = nil;
- NSMutableArray *oneofs = nil;
- NSMutableArray *enums = nil;
- NSMutableArray *extensionRanges = nil;
GPBFileSyntax syntax = file.syntax;
- for (NSUInteger i = 0; i < fieldCount; ++i) {
+ BOOL fieldsIncludeDefault =
+ (flags & GPBDescriptorInitializationFlag_FieldsWithDefault) != 0;
+
+ void *desc;
+ for (uint32_t i = 0; i < fieldCount; ++i) {
if (fields == nil) {
fields = [[NSMutableArray alloc] initWithCapacity:fieldCount];
}
- GPBFieldDescriptor *fieldDescriptor = [[GPBFieldDescriptor alloc]
- initWithFieldDescription:&fieldDescriptions[i]
- rootClass:rootClass
- syntax:syntax];
+ // Need correctly typed pointer for array indexing below to work.
+ if (fieldsIncludeDefault) {
+ GPBMessageFieldDescriptionWithDefault *fieldDescWithDefault = fieldDescriptions;
+ desc = &(fieldDescWithDefault[i]);
+ } else {
+ GPBMessageFieldDescription *fieldDesc = fieldDescriptions;
+ desc = &(fieldDesc[i]);
+ }
+ GPBFieldDescriptor *fieldDescriptor =
+ [[GPBFieldDescriptor alloc] initWithFieldDescription:desc
+ includesDefault:fieldsIncludeDefault
+ syntax:syntax];
[fields addObject:fieldDescriptor];
[fieldDescriptor release];
}
- for (NSUInteger i = 0; i < oneofCount; ++i) {
- if (oneofs == nil) {
- oneofs = [[NSMutableArray alloc] initWithCapacity:oneofCount];
- }
- GPBMessageOneofDescription *oneofDescription = &oneofDescriptions[i];
- NSArray *fieldsForOneof =
- NewFieldsArrayForHasIndex(oneofDescription->index, fields);
- GPBOneofDescriptor *oneofDescriptor =
- [[GPBOneofDescriptor alloc] initWithOneofDescription:oneofDescription
- fields:fieldsForOneof];
- [oneofs addObject:oneofDescriptor];
- [oneofDescriptor release];
- [fieldsForOneof release];
- }
- for (NSUInteger i = 0; i < enumCount; ++i) {
- if (enums == nil) {
- enums = [[NSMutableArray alloc] initWithCapacity:enumCount];
- }
- GPBEnumDescriptor *enumDescriptor =
- enumDescriptions[i].enumDescriptorFunc();
- [enums addObject:enumDescriptor];
- }
+ BOOL wireFormat = (flags & GPBDescriptorInitializationFlag_WireFormat) != 0;
GPBDescriptor *descriptor = [[self alloc] initWithClass:messageClass
file:file
fields:fields
- oneofs:oneofs
- enums:enums
- extensionRanges:ranges
- extensionRangesCount:rangeCount
storageSize:storageSize
wireFormat:wireFormat];
[fields release];
- [oneofs release];
- [enums release];
- [extensionRanges release];
- return descriptor;
-}
-
-+ (instancetype)
- allocDescriptorForClass:(Class)messageClass
- rootClass:(Class)rootClass
- file:(GPBFileDescriptor *)file
- fields:(GPBMessageFieldDescription *)fieldDescriptions
- fieldCount:(NSUInteger)fieldCount
- oneofs:(GPBMessageOneofDescription *)oneofDescriptions
- oneofCount:(NSUInteger)oneofCount
- enums:(GPBMessageEnumDescription *)enumDescriptions
- enumCount:(NSUInteger)enumCount
- ranges:(const GPBExtensionRange *)ranges
- rangeCount:(NSUInteger)rangeCount
- storageSize:(size_t)storageSize
- wireFormat:(BOOL)wireFormat
- extraTextFormatInfo:(const char *)extraTextFormatInfo {
- GPBDescriptor *descriptor = [self allocDescriptorForClass:messageClass
- rootClass:rootClass
- file:file
- fields:fieldDescriptions
- fieldCount:fieldCount
- oneofs:oneofDescriptions
- oneofCount:oneofCount
- enums:enumDescriptions
- enumCount:enumCount
- ranges:ranges
- rangeCount:rangeCount
- storageSize:storageSize
- wireFormat:wireFormat];
- // Extra info is a compile time option, so skip the work if not needed.
- if (extraTextFormatInfo) {
- NSValue *extraInfoValue = [NSValue valueWithPointer:extraTextFormatInfo];
- for (GPBFieldDescriptor *fieldDescriptor in descriptor->fields_) {
- if (fieldDescriptor->description_->flags & GPBFieldTextFormatNameCustom) {
- objc_setAssociatedObject(fieldDescriptor, &kTextFormatExtraValueKey,
- extraInfoValue,
- OBJC_ASSOCIATION_RETAIN_NONATOMIC);
- }
- }
- }
return descriptor;
}
- (instancetype)initWithClass:(Class)messageClass
file:(GPBFileDescriptor *)file
fields:(NSArray *)fields
- oneofs:(NSArray *)oneofs
- enums:(NSArray *)enums
- extensionRanges:(const GPBExtensionRange *)extensionRanges
- extensionRangesCount:(NSUInteger)extensionRangesCount
- storageSize:(size_t)storageSize
+ storageSize:(uint32_t)storageSize
wireFormat:(BOOL)wireFormat {
if ((self = [super init])) {
messageClass_ = messageClass;
file_ = file;
fields_ = [fields retain];
- oneofs_ = [oneofs retain];
- enums_ = [enums retain];
- extensionRanges_ = extensionRanges;
- extensionRangesCount_ = extensionRangesCount;
storageSize_ = storageSize;
wireFormat_ = wireFormat;
}
@@ -243,10 +174,47 @@ static NSArray *NewFieldsArrayForHasIndex(int hasIndex,
- (void)dealloc {
[fields_ release];
[oneofs_ release];
- [enums_ release];
[super dealloc];
}
+- (void)setupOneofs:(const char **)oneofNames
+ count:(uint32_t)count
+ firstHasIndex:(int32_t)firstHasIndex {
+ NSCAssert(firstHasIndex < 0, @"Should always be <0");
+ NSMutableArray *oneofs = [[NSMutableArray alloc] initWithCapacity:count];
+ for (uint32_t i = 0, hasIndex = firstHasIndex; i < count; ++i, --hasIndex) {
+ const char *name = oneofNames[i];
+ NSArray *fieldsForOneof = NewFieldsArrayForHasIndex(hasIndex, fields_);
+ NSCAssert(fieldsForOneof.count > 0,
+ @"No fields for this oneof? (%s:%d)", name, hasIndex);
+ GPBOneofDescriptor *oneofDescriptor =
+ [[GPBOneofDescriptor alloc] initWithName:name fields:fieldsForOneof];
+ [oneofs addObject:oneofDescriptor];
+ [oneofDescriptor release];
+ [fieldsForOneof release];
+ }
+ oneofs_ = oneofs;
+}
+
+- (void)setupExtraTextInfo:(const char *)extraTextFormatInfo {
+ // Extra info is a compile time option, so skip the work if not needed.
+ if (extraTextFormatInfo) {
+ NSValue *extraInfoValue = [NSValue valueWithPointer:extraTextFormatInfo];
+ for (GPBFieldDescriptor *fieldDescriptor in fields_) {
+ if (fieldDescriptor->description_->flags & GPBFieldTextFormatNameCustom) {
+ objc_setAssociatedObject(fieldDescriptor, &kTextFormatExtraValueKey,
+ extraInfoValue,
+ OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+ }
+ }
+ }
+}
+
+- (void)setupExtensionRanges:(const GPBExtensionRange *)ranges count:(int32_t)count {
+ extensionRanges_ = ranges;
+ extensionRangesCount_ = count;
+}
+
- (NSString *)name {
return NSStringFromClass(messageClass_);
}
@@ -283,15 +251,6 @@ static NSArray *NewFieldsArrayForHasIndex(int hasIndex,
return nil;
}
-- (GPBEnumDescriptor *)enumWithName:(NSString *)name {
- for (GPBEnumDescriptor *descriptor in enums_) {
- if ([descriptor.name isEqual:name]) {
- return descriptor;
- }
- }
- return nil;
-}
-
@end
@implementation GPBFileDescriptor {
@@ -312,25 +271,27 @@ static NSArray *NewFieldsArrayForHasIndex(int hasIndex,
return self;
}
+- (void)dealloc {
+ [package_ release];
+ [super dealloc];
+}
+
@end
@implementation GPBOneofDescriptor
@synthesize fields = fields_;
-- (instancetype)initWithOneofDescription:
- (GPBMessageOneofDescription *)oneofDescription
- fields:(NSArray *)fields {
+- (instancetype)initWithName:(const char *)name fields:(NSArray *)fields {
self = [super init];
if (self) {
- NSAssert(oneofDescription->index < 0, @"Should always be <0");
- oneofDescription_ = oneofDescription;
+ name_ = name;
fields_ = [fields retain];
for (GPBFieldDescriptor *fieldDesc in fields) {
fieldDesc->containingOneof_ = self;
}
- caseSel_ = SelFromStrings(NULL, oneofDescription->name, "OneOfCase", NO);
+ caseSel_ = SelFromStrings(NULL, name, "OneOfCase", NO);
}
return self;
}
@@ -341,7 +302,7 @@ static NSArray *NewFieldsArrayForHasIndex(int hasIndex,
}
- (NSString *)name {
- return @(oneofDescription_->name);
+ return @(name_);
}
- (GPBFieldDescriptor *)fieldWithNumber:(uint32_t)fieldNumber {
@@ -389,7 +350,6 @@ uint32_t GPBFieldAlternateTag(GPBFieldDescriptor *self) {
@implementation GPBFieldDescriptor {
GPBGenericValue defaultValue_;
- GPBFieldOptions *fieldOptions_;
// Message ivars
Class msgClass_;
@@ -403,7 +363,6 @@ uint32_t GPBFieldAlternateTag(GPBFieldDescriptor *self) {
} enumHandling_;
}
-@synthesize fieldOptions = fieldOptions_;
@synthesize msgClass = msgClass_;
@synthesize containingOneof = containingOneof_;
@@ -417,16 +376,21 @@ uint32_t GPBFieldAlternateTag(GPBFieldDescriptor *self) {
return self;
}
-- (instancetype)initWithFieldDescription:
- (GPBMessageFieldDescription *)description
- rootClass:(Class)rootClass
+- (instancetype)initWithFieldDescription:(void *)description
+ includesDefault:(BOOL)includesDefault
syntax:(GPBFileSyntax)syntax {
if ((self = [super init])) {
- description_ = description;
- getSel_ = sel_getUid(description->name);
- setSel_ = SelFromStrings("set", description->name, NULL, YES);
+ GPBMessageFieldDescription *coreDesc;
+ if (includesDefault) {
+ coreDesc = &(((GPBMessageFieldDescriptionWithDefault *)description)->core);
+ } else {
+ coreDesc = description;
+ }
+ description_ = coreDesc;
+ getSel_ = sel_getUid(coreDesc->name);
+ setSel_ = SelFromStrings("set", coreDesc->name, NULL, YES);
- GPBDataType dataType = description->dataType;
+ GPBDataType dataType = coreDesc->dataType;
BOOL isMessage = GPBDataTypeIsMessage(dataType);
BOOL isMapOrArray = GPBFieldIsMapOrArray(self);
@@ -434,39 +398,39 @@ uint32_t GPBFieldAlternateTag(GPBFieldDescriptor *self) {
// map<>/repeated fields get a *Count property (inplace of a has*) to
// support checking if there are any entries without triggering
// autocreation.
- hasOrCountSel_ = SelFromStrings(NULL, description->name, "_Count", NO);
+ hasOrCountSel_ = SelFromStrings(NULL, coreDesc->name, "_Count", NO);
} else {
// If there is a positive hasIndex, then:
// - All fields types for proto2 messages get has* selectors.
// - Only message fields for proto3 messages get has* selectors.
// Note: the positive check is to handle oneOfs, we can't check
// containingOneof_ because it isn't set until after initialization.
- if ((description->hasIndex >= 0) &&
- (description->hasIndex != GPBNoHasBit) &&
+ if ((coreDesc->hasIndex >= 0) &&
+ (coreDesc->hasIndex != GPBNoHasBit) &&
((syntax != GPBFileSyntaxProto3) || isMessage)) {
- hasOrCountSel_ = SelFromStrings("has", description->name, NULL, NO);
- setHasSel_ = SelFromStrings("setHas", description->name, NULL, YES);
+ hasOrCountSel_ = SelFromStrings("has", coreDesc->name, NULL, NO);
+ setHasSel_ = SelFromStrings("setHas", coreDesc->name, NULL, YES);
}
}
// Extra type specific data.
if (isMessage) {
- const char *className = description->dataTypeSpecific.className;
+ const char *className = coreDesc->dataTypeSpecific.className;
msgClass_ = objc_getClass(className);
NSAssert(msgClass_, @"Class %s not defined", className);
} else if (dataType == GPBDataTypeEnum) {
- if ((description_->flags & GPBFieldHasEnumDescriptor) != 0) {
+ if ((coreDesc->flags & GPBFieldHasEnumDescriptor) != 0) {
enumHandling_.enumDescriptor_ =
- description->dataTypeSpecific.enumDescFunc();
+ coreDesc->dataTypeSpecific.enumDescFunc();
} else {
enumHandling_.enumVerifier_ =
- description->dataTypeSpecific.enumVerifier;
+ coreDesc->dataTypeSpecific.enumVerifier;
}
}
- // Non map<>/repeated fields can have defaults.
- if (!isMapOrArray) {
- defaultValue_ = description->defaultValue;
+ // Non map<>/repeated fields can have defaults in proto2 syntax.
+ if (!isMapOrArray && includesDefault) {
+ defaultValue_ = ((GPBMessageFieldDescriptionWithDefault *)description)->defaultValue;
if (dataType == GPBDataTypeBytes) {
// Data stored as a length prefixed (network byte order) c-string in
// descriptor structure.
@@ -480,24 +444,6 @@ uint32_t GPBFieldAlternateTag(GPBFieldDescriptor *self) {
}
}
}
-
- // FieldOptions stored as a length prefixed (network byte order) c-escaped
- // string in descriptor records.
- if (description->fieldOptions) {
- uint8_t *optionsBytes = (uint8_t *)description->fieldOptions;
- uint32_t optionsLength = *((uint32_t *)optionsBytes);
- optionsLength = ntohl(optionsLength);
- if (optionsLength > 0) {
- optionsBytes += sizeof(optionsLength);
- NSData *optionsData = [NSData dataWithBytesNoCopy:optionsBytes
- length:optionsLength
- freeWhenDone:NO];
- GPBExtensionRegistry *registry = [rootClass extensionRegistry];
- fieldOptions_ = [[GPBFieldOptions parseFromData:optionsData
- extensionRegistry:registry
- error:NULL] retain];
- }
- }
}
return self;
}
@@ -666,7 +612,7 @@ uint32_t GPBFieldAlternateTag(GPBFieldDescriptor *self) {
} else {
// Undo the CamelCase.
NSMutableString *result = [NSMutableString stringWithCapacity:len];
- for (NSUInteger i = 0; i < len; i++) {
+ for (uint32_t i = 0; i < len; i++) {
unichar c = [name characterAtIndex:i];
if (c >= 'A' && c <= 'Z') {
if (i > 0) {
@@ -686,10 +632,16 @@ uint32_t GPBFieldAlternateTag(GPBFieldDescriptor *self) {
@implementation GPBEnumDescriptor {
NSString *name_;
- GPBMessageEnumValueDescription *valueDescriptions_;
- NSUInteger valueDescriptionsCount_;
+ // valueNames_ is a single c string with all of the value names appended
+ // together, each null terminated. -calcValueNameOffsets fills in
+ // nameOffsets_ with the offsets to allow quicker access to the individual
+ // names.
+ const char *valueNames_;
+ const int32_t *values_;
GPBEnumValidationFunc enumVerifier_;
const uint8_t *extraTextFormatInfo_;
+ uint32_t *nameOffsets_;
+ uint32_t valueCount_;
}
@synthesize name = name_;
@@ -697,26 +649,30 @@ uint32_t GPBFieldAlternateTag(GPBFieldDescriptor *self) {
+ (instancetype)
allocDescriptorForName:(NSString *)name
- values:(GPBMessageEnumValueDescription *)valueDescriptions
- valueCount:(NSUInteger)valueCount
+ valueNames:(const char *)valueNames
+ values:(const int32_t *)values
+ count:(uint32_t)valueCount
enumVerifier:(GPBEnumValidationFunc)enumVerifier {
GPBEnumDescriptor *descriptor = [[self alloc] initWithName:name
- values:valueDescriptions
- valueCount:valueCount
+ valueNames:valueNames
+ values:values
+ count:valueCount
enumVerifier:enumVerifier];
return descriptor;
}
+ (instancetype)
allocDescriptorForName:(NSString *)name
- values:(GPBMessageEnumValueDescription *)valueDescriptions
- valueCount:(NSUInteger)valueCount
+ valueNames:(const char *)valueNames
+ values:(const int32_t *)values
+ count:(uint32_t)valueCount
enumVerifier:(GPBEnumValidationFunc)enumVerifier
extraTextFormatInfo:(const char *)extraTextFormatInfo {
// Call the common case.
GPBEnumDescriptor *descriptor = [self allocDescriptorForName:name
- values:valueDescriptions
- valueCount:valueCount
+ valueNames:valueNames
+ values:values
+ count:valueCount
enumVerifier:enumVerifier];
// Set the extra info.
descriptor->extraTextFormatInfo_ = (const uint8_t *)extraTextFormatInfo;
@@ -724,24 +680,49 @@ uint32_t GPBFieldAlternateTag(GPBFieldDescriptor *self) {
}
- (instancetype)initWithName:(NSString *)name
- values:(GPBMessageEnumValueDescription *)valueDescriptions
- valueCount:(NSUInteger)valueCount
+ valueNames:(const char *)valueNames
+ values:(const int32_t *)values
+ count:(uint32_t)valueCount
enumVerifier:(GPBEnumValidationFunc)enumVerifier {
if ((self = [super init])) {
name_ = [name copy];
- valueDescriptions_ = valueDescriptions;
- valueDescriptionsCount_ = valueCount;
+ valueNames_ = valueNames;
+ values_ = values;
+ valueCount_ = valueCount;
enumVerifier_ = enumVerifier;
}
return self;
}
+- (void)dealloc {
+ [name_ release];
+ if (nameOffsets_) free(nameOffsets_);
+ [super dealloc];
+}
+
+- (void)calcValueNameOffsets {
+ @synchronized(self) {
+ if (nameOffsets_ != NULL) {
+ return;
+ }
+ uint32_t *offsets = malloc(valueCount_ * sizeof(uint32_t));
+ const char *scan = valueNames_;
+ for (uint32_t i = 0; i < valueCount_; ++i) {
+ offsets[i] = (uint32_t)(scan - valueNames_);
+ while (*scan != '\0') ++scan;
+ ++scan; // Step over the null.
+ }
+ nameOffsets_ = offsets;
+ }
+}
+
- (NSString *)enumNameForValue:(int32_t)number {
- for (NSUInteger i = 0; i < valueDescriptionsCount_; ++i) {
- GPBMessageEnumValueDescription *scan = &valueDescriptions_[i];
- if ((scan->number == number) && (scan->name != NULL)) {
- NSString *fullName =
- [NSString stringWithFormat:@"%@_%s", name_, scan->name];
+ if (nameOffsets_ == NULL) [self calcValueNameOffsets];
+
+ for (uint32_t i = 0; i < valueCount_; ++i) {
+ if (values_[i] == number) {
+ const char *valueName = valueNames_ + nameOffsets_[i];
+ NSString *fullName = [NSString stringWithFormat:@"%@_%s", name_, valueName];
return fullName;
}
}
@@ -760,12 +741,14 @@ uint32_t GPBFieldAlternateTag(GPBFieldDescriptor *self) {
const char *nameAsCStr = [name UTF8String];
nameAsCStr += prefixLen;
+ if (nameOffsets_ == NULL) [self calcValueNameOffsets];
+
// Find it.
- for (NSUInteger i = 0; i < valueDescriptionsCount_; ++i) {
- GPBMessageEnumValueDescription *scan = &valueDescriptions_[i];
- if ((scan->name != NULL) && (strcmp(nameAsCStr, scan->name) == 0)) {
+ for (uint32_t i = 0; i < valueCount_; ++i) {
+ const char *valueName = valueNames_ + nameOffsets_[i];
+ if (strcmp(nameAsCStr, valueName) == 0) {
if (outValue) {
- *outValue = scan->number;
+ *outValue = values_[i];
}
return YES;
}
@@ -773,34 +756,44 @@ uint32_t GPBFieldAlternateTag(GPBFieldDescriptor *self) {
return NO;
}
-- (void)dealloc {
- [name_ release];
- [super dealloc];
+- (BOOL)getValue:(int32_t *)outValue forEnumTextFormatName:(NSString *)textFormatName {
+ if (nameOffsets_ == NULL) [self calcValueNameOffsets];
+
+ for (uint32_t i = 0; i < valueCount_; ++i) {
+ int32_t value = values_[i];
+ NSString *valueTextFormatName = [self textFormatNameForValue:value];
+ if ([valueTextFormatName isEqual:textFormatName]) {
+ if (outValue) {
+ *outValue = value;
+ }
+ return YES;
+ }
+ }
+ return NO;
}
- (NSString *)textFormatNameForValue:(int32_t)number {
+ if (nameOffsets_ == NULL) [self calcValueNameOffsets];
+
// Find the EnumValue descriptor and its index.
- GPBMessageEnumValueDescription *valueDescriptor = NULL;
- NSUInteger valueDescriptorIndex;
- for (valueDescriptorIndex = 0; valueDescriptorIndex < valueDescriptionsCount_;
+ BOOL foundIt = NO;
+ uint32_t valueDescriptorIndex;
+ for (valueDescriptorIndex = 0; valueDescriptorIndex < valueCount_;
++valueDescriptorIndex) {
- GPBMessageEnumValueDescription *scan =
- &valueDescriptions_[valueDescriptorIndex];
- if (scan->number == number) {
- valueDescriptor = scan;
+ if (values_[valueDescriptorIndex] == number) {
+ foundIt = YES;
break;
}
}
- // If we didn't find it, or names were disable at proto compile time, nothing
- // we can do.
- if (!valueDescriptor || !valueDescriptor->name) {
+ if (!foundIt) {
return nil;
}
NSString *result = nil;
// Naming adds an underscore between enum name and value name, skip that also.
- NSString *shortName = @(valueDescriptor->name);
+ const char *valueName = valueNames_ + nameOffsets_[valueDescriptorIndex];
+ NSString *shortName = @(valueName);
// See if it is in the map of special format handling.
if (extraTextFormatInfo_) {
@@ -837,7 +830,7 @@ uint32_t GPBFieldAlternateTag(GPBFieldDescriptor *self) {
if ((self = [super init])) {
description_ = description;
-#if DEBUG
+#if defined(DEBUG) && DEBUG
const char *className = description->messageOrGroupClassName;
if (className) {
NSAssert(objc_lookUpClass(className) != Nil,
@@ -995,3 +988,5 @@ uint32_t GPBFieldAlternateTag(GPBFieldDescriptor *self) {
}
@end
+
+#pragma clang diagnostic pop
diff --git a/objectivec/GPBDescriptor_PackagePrivate.h b/objectivec/GPBDescriptor_PackagePrivate.h
index 7987d928..c20ff6b0 100644
--- a/objectivec/GPBDescriptor_PackagePrivate.h
+++ b/objectivec/GPBDescriptor_PackagePrivate.h
@@ -36,7 +36,7 @@
#import "GPBWireFormat.h"
// Describes attributes of the field.
-typedef NS_OPTIONS(uint32_t, GPBFieldFlags) {
+typedef NS_OPTIONS(uint16_t, GPBFieldFlags) {
// These map to standard protobuf concepts.
GPBFieldRequired = 1 << 0,
GPBFieldRepeated = 1 << 1,
@@ -44,6 +44,12 @@ typedef NS_OPTIONS(uint32_t, GPBFieldFlags) {
GPBFieldOptional = 1 << 3,
GPBFieldHasDefaultValue = 1 << 4,
+ // Indicates the field needs custom handling for the TextFormat name, if not
+ // set, the name can be derived from the ObjC name.
+ GPBFieldTextFormatNameCustom = 1 << 6,
+ // Indicates the field has an enum descriptor.
+ GPBFieldHasEnumDescriptor = 1 << 7,
+
// These are not standard protobuf concepts, they are specific to the
// Objective C runtime.
@@ -62,67 +68,49 @@ typedef NS_OPTIONS(uint32_t, GPBFieldFlags) {
GPBFieldMapKeySFixed64 = 10 << 8,
GPBFieldMapKeyBool = 11 << 8,
GPBFieldMapKeyString = 12 << 8,
-
- // Indicates the field needs custom handling for the TextFormat name, if not
- // set, the name can be derived from the ObjC name.
- GPBFieldTextFormatNameCustom = 1 << 16,
- // Indicates the field has an enum descriptor.
- GPBFieldHasEnumDescriptor = 1 << 17,
};
+// NOTE: The structures defined here have their members ordered to minimize
+// their size. This directly impacts the size of apps since these exist per
+// field/extension.
+
// Describes a single field in a protobuf as it is represented as an ivar.
typedef struct GPBMessageFieldDescription {
// Name of ivar.
const char *name;
+ union {
+ const char *className; // Name for message class.
+ // For enums only: If EnumDescriptors are compiled in, it will be that,
+ // otherwise it will be the verifier.
+ GPBEnumDescriptorFunc enumDescFunc;
+ GPBEnumValidationFunc enumVerifier;
+ } dataTypeSpecific;
// The field number for the ivar.
uint32_t number;
// The index (in bits) into _has_storage_.
- // > 0: the bit to use for a value being set.
- // = 0: no storage used.
+ // >= 0: the bit to use for a value being set.
+ // = GPBNoHasBit(INT32_MAX): no storage used.
// < 0: in a oneOf, use a full int32 to record the field active.
int32_t hasIndex;
+ // Offset of the variable into it's structure struct.
+ uint32_t offset;
// Field flags. Use accessor functions below.
GPBFieldFlags flags;
// Data type of the ivar.
GPBDataType dataType;
- // Offset of the variable into it's structure struct.
- size_t offset;
- // FieldOptions protobuf, serialized as string.
- const char *fieldOptions;
-
- GPBGenericValue defaultValue; // Default value for the ivar.
- union {
- const char *className; // Name for message class.
- // For enums only: If EnumDescriptors are compiled in, it will be that,
- // otherwise it will be the verifier.
- GPBEnumDescriptorFunc enumDescFunc;
- GPBEnumValidationFunc enumVerifier;
- } dataTypeSpecific;
} GPBMessageFieldDescription;
-// Describes a oneof.
-typedef struct GPBMessageOneofDescription {
- // Name of this enum oneof.
- const char *name;
- // The index of this oneof in the has_storage.
- int32_t index;
-} GPBMessageOneofDescription;
-
-// Describes an enum type defined in a .proto file.
-typedef struct GPBMessageEnumDescription {
- GPBEnumDescriptorFunc enumDescriptorFunc;
-} GPBMessageEnumDescription;
+// Fields in messages defined in a 'proto2' syntax file can provide a default
+// value. This struct provides the default along with the field info.
+typedef struct GPBMessageFieldDescriptionWithDefault {
+ // Default value for the ivar.
+ GPBGenericValue defaultValue;
-// Describes an individual enum constant of a particular type.
-typedef struct GPBMessageEnumValueDescription {
- // Name of this enum constant.
- const char *name;
- // Numeric value of this enum constant.
- int32_t number;
-} GPBMessageEnumValueDescription;
+ GPBMessageFieldDescription core;
+} GPBMessageFieldDescriptionWithDefault;
// Describes attributes of the extension.
-typedef NS_OPTIONS(uint32_t, GPBExtensionOptions) {
+typedef NS_OPTIONS(uint8_t, GPBExtensionOptions) {
// These map to standard protobuf concepts.
GPBExtensionRepeated = 1 << 0,
GPBExtensionPacked = 1 << 1,
@@ -131,65 +119,53 @@ typedef NS_OPTIONS(uint32_t, GPBExtensionOptions) {
// An extension
typedef struct GPBExtensionDescription {
+ GPBGenericValue defaultValue;
const char *singletonName;
- GPBDataType dataType;
const char *extendedClass;
- int32_t fieldNumber;
- GPBGenericValue defaultValue;
const char *messageOrGroupClassName;
- GPBExtensionOptions options;
GPBEnumDescriptorFunc enumDescriptorFunc;
+ int32_t fieldNumber;
+ GPBDataType dataType;
+ GPBExtensionOptions options;
} GPBExtensionDescription;
+typedef NS_OPTIONS(uint32_t, GPBDescriptorInitializationFlags) {
+ GPBDescriptorInitializationFlag_FieldsWithDefault = 1 << 0,
+ GPBDescriptorInitializationFlag_WireFormat = 1 << 1,
+};
+
@interface GPBDescriptor () {
@package
NSArray *fields_;
NSArray *oneofs_;
- size_t storageSize_;
+ uint32_t storageSize_;
}
-// fieldDescriptions, enumDescriptions, rangeDescriptions, and
-// extraTextFormatInfo have to be long lived, they are held as raw pointers.
-+ (instancetype)
- allocDescriptorForClass:(Class)messageClass
- rootClass:(Class)rootClass
- file:(GPBFileDescriptor *)file
- fields:(GPBMessageFieldDescription *)fieldDescriptions
- fieldCount:(NSUInteger)fieldCount
- oneofs:(GPBMessageOneofDescription *)oneofDescriptions
- oneofCount:(NSUInteger)oneofCount
- enums:(GPBMessageEnumDescription *)enumDescriptions
- enumCount:(NSUInteger)enumCount
- ranges:(const GPBExtensionRange *)ranges
- rangeCount:(NSUInteger)rangeCount
- storageSize:(size_t)storageSize
- wireFormat:(BOOL)wireFormat;
+// fieldDescriptions have to be long lived, they are held as raw pointers.
+ (instancetype)
allocDescriptorForClass:(Class)messageClass
rootClass:(Class)rootClass
file:(GPBFileDescriptor *)file
- fields:(GPBMessageFieldDescription *)fieldDescriptions
- fieldCount:(NSUInteger)fieldCount
- oneofs:(GPBMessageOneofDescription *)oneofDescriptions
- oneofCount:(NSUInteger)oneofCount
- enums:(GPBMessageEnumDescription *)enumDescriptions
- enumCount:(NSUInteger)enumCount
- ranges:(const GPBExtensionRange *)ranges
- rangeCount:(NSUInteger)rangeCount
- storageSize:(size_t)storageSize
- wireFormat:(BOOL)wireFormat
- extraTextFormatInfo:(const char *)extraTextFormatInfo;
+ fields:(void *)fieldDescriptions
+ fieldCount:(uint32_t)fieldCount
+ storageSize:(uint32_t)storageSize
+ flags:(GPBDescriptorInitializationFlags)flags;
- (instancetype)initWithClass:(Class)messageClass
file:(GPBFileDescriptor *)file
fields:(NSArray *)fields
- oneofs:(NSArray *)oneofs
- enums:(NSArray *)enums
- extensionRanges:(const GPBExtensionRange *)ranges
- extensionRangesCount:(NSUInteger)rangeCount
- storageSize:(size_t)storage
+ storageSize:(uint32_t)storage
wireFormat:(BOOL)wireFormat;
+// Called right after init to provide extra information to avoid init having
+// an explosion of args. These pointers are recorded, so they are expected
+// to live for the lifetime of the app.
+- (void)setupOneofs:(const char **)oneofNames
+ count:(uint32_t)count
+ firstHasIndex:(int32_t)firstHasIndex;
+- (void)setupExtraTextInfo:(const char *)extraTextFormatInfo;
+- (void)setupExtensionRanges:(const GPBExtensionRange *)ranges count:(int32_t)count;
+
@end
@interface GPBFileDescriptor ()
@@ -199,14 +175,12 @@ typedef struct GPBExtensionDescription {
@interface GPBOneofDescriptor () {
@package
- GPBMessageOneofDescription *oneofDescription_;
+ const char *name_;
NSArray *fields_;
-
SEL caseSel_;
}
-- (instancetype)initWithOneofDescription:
- (GPBMessageOneofDescription *)oneofDescription
- fields:(NSArray *)fields;
+// name must be long lived.
+- (instancetype)initWithName:(const char *)name fields:(NSArray *)fields;
@end
@interface GPBFieldDescriptor () {
@@ -222,30 +196,32 @@ typedef struct GPBExtensionDescription {
// Single initializer
// description has to be long lived, it is held as a raw pointer.
-- (instancetype)initWithFieldDescription:
- (GPBMessageFieldDescription *)description
- rootClass:(Class)rootClass
+- (instancetype)initWithFieldDescription:(void *)description
+ includesDefault:(BOOL)includesDefault
syntax:(GPBFileSyntax)syntax;
@end
@interface GPBEnumDescriptor ()
-// valueDescriptions and extraTextFormatInfo have to be long lived, they are
+// valueNames, values and extraTextFormatInfo have to be long lived, they are
// held as raw pointers.
+ (instancetype)
allocDescriptorForName:(NSString *)name
- values:(GPBMessageEnumValueDescription *)valueDescriptions
- valueCount:(NSUInteger)valueCount
+ valueNames:(const char *)valueNames
+ values:(const int32_t *)values
+ count:(uint32_t)valueCount
enumVerifier:(GPBEnumValidationFunc)enumVerifier;
+ (instancetype)
allocDescriptorForName:(NSString *)name
- values:(GPBMessageEnumValueDescription *)valueDescriptions
- valueCount:(NSUInteger)valueCount
+ valueNames:(const char *)valueNames
+ values:(const int32_t *)values
+ count:(uint32_t)valueCount
enumVerifier:(GPBEnumValidationFunc)enumVerifier
extraTextFormatInfo:(const char *)extraTextFormatInfo;
- (instancetype)initWithName:(NSString *)name
- values:(GPBMessageEnumValueDescription *)valueDescriptions
- valueCount:(NSUInteger)valueCount
+ valueNames:(const char *)valueNames
+ values:(const int32_t *)values
+ count:(uint32_t)valueCount
enumVerifier:(GPBEnumValidationFunc)enumVerifier;
@end
@@ -269,6 +245,12 @@ typedef struct GPBExtensionDescription {
CF_EXTERN_C_BEGIN
+// Direct access is use for speed, to avoid even internally declaring things
+// read/write, etc. The warning is enabled in the project to ensure code calling
+// protos can turn on -Wdirect-ivar-access without issues.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdirect-ivar-access"
+
GPB_INLINE BOOL GPBFieldIsMapOrArray(GPBFieldDescriptor *field) {
return (field->description_->flags &
(GPBFieldRepeated | GPBFieldMapKeyMask)) != 0;
@@ -286,6 +268,8 @@ GPB_INLINE uint32_t GPBFieldNumber(GPBFieldDescriptor *field) {
return field->description_->number;
}
+#pragma clang diagnostic pop
+
uint32_t GPBFieldTag(GPBFieldDescriptor *self);
// For repeated fields, alternateWireType is the wireType with the opposite
@@ -314,5 +298,24 @@ GPB_INLINE BOOL GPBExtensionIsWireFormat(GPBExtensionDescription *description) {
return (description->options & GPBExtensionSetWireFormat) != 0;
}
+// Helper for compile time assets.
+#ifndef GPBInternalCompileAssert
+ #if __has_feature(c_static_assert) || __has_extension(c_static_assert)
+ #define GPBInternalCompileAssert(test, msg) _Static_assert((test), #msg)
+ #else
+ // Pre-Xcode 7 support.
+ #define GPBInternalCompileAssertSymbolInner(line, msg) GPBInternalCompileAssert ## line ## __ ## msg
+ #define GPBInternalCompileAssertSymbol(line, msg) GPBInternalCompileAssertSymbolInner(line, msg)
+ #define GPBInternalCompileAssert(test, msg) \
+ typedef char GPBInternalCompileAssertSymbol(__LINE__, msg) [ ((test) ? 1 : -1) ]
+ #endif // __has_feature(c_static_assert) || __has_extension(c_static_assert)
+#endif // GPBInternalCompileAssert
+
+// Sanity check that there isn't padding between the field description
+// structures with and without a default.
+GPBInternalCompileAssert(sizeof(GPBMessageFieldDescriptionWithDefault) ==
+ (sizeof(GPBGenericValue) +
+ sizeof(GPBMessageFieldDescription)),
+ DescriptionsWithDefault_different_size_than_expected);
CF_EXTERN_C_END
diff --git a/objectivec/GPBDictionary.h b/objectivec/GPBDictionary.h
index 6961cfc3..f7959960 100644
--- a/objectivec/GPBDictionary.h
+++ b/objectivec/GPBDictionary.h
@@ -37,6 +37,15 @@
// Note: These are not meant to be subclassed.
+// Note on naming: for the classes holding numeric values, a more natural
+// naming of the method might be things like "-valueForKey:",
+// "-setValue:forKey:"; etc. But those selectors are also defined by Key Value
+// Coding (KVC) as categories on NSObject. So "overloading" the selectors with
+// other meanings can cause warnings (based on compiler settings), but more
+// importantly, some of those selector get called as KVC breaks up keypaths.
+// So if those selectors are used, using KVC will compile cleanly, but could
+// crash as it invokes those selectors with the wrong types of arguments.
+
NS_ASSUME_NONNULL_BEGIN
//%PDDM-EXPAND DECLARE_DICTIONARIES()
@@ -49,30 +58,32 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithValue:(uint32_t)value
- forKey:(uint32_t)key;
-+ (instancetype)dictionaryWithValues:(const uint32_t [])values
- forKeys:(const uint32_t [])keys
- count:(NSUInteger)count;
++ (instancetype)dictionaryWithUInt32:(uint32_t)value
+ forKey:(uint32_t)key;
++ (instancetype)dictionaryWithUInt32s:(const uint32_t [])values
+ forKeys:(const uint32_t [])keys
+ count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBUInt32UInt32Dictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithValues:(const uint32_t [])values
- forKeys:(const uint32_t [])keys
- count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithUInt32s:(const uint32_t [])values
+ forKeys:(const uint32_t [])keys
+ count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBUInt32UInt32Dictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (BOOL)valueForKey:(uint32_t)key value:(nullable uint32_t *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getUInt32:(nullable uint32_t *)value forKey:(uint32_t)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndUInt32sUsingBlock:
(void (^)(uint32_t key, uint32_t value, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBUInt32UInt32Dictionary *)otherDictionary;
-- (void)setValue:(uint32_t)value forKey:(uint32_t)key;
+- (void)setUInt32:(uint32_t)value forKey:(uint32_t)key;
-- (void)removeValueForKey:(uint32_t)aKey;
+- (void)removeUInt32ForKey:(uint32_t)aKey;
- (void)removeAll;
@end
@@ -84,30 +95,32 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithValue:(int32_t)value
++ (instancetype)dictionaryWithInt32:(int32_t)value
forKey:(uint32_t)key;
-+ (instancetype)dictionaryWithValues:(const int32_t [])values
++ (instancetype)dictionaryWithInt32s:(const int32_t [])values
forKeys:(const uint32_t [])keys
count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBUInt32Int32Dictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithValues:(const int32_t [])values
+- (instancetype)initWithInt32s:(const int32_t [])values
forKeys:(const uint32_t [])keys
count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBUInt32Int32Dictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (BOOL)valueForKey:(uint32_t)key value:(nullable int32_t *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getInt32:(nullable int32_t *)value forKey:(uint32_t)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndInt32sUsingBlock:
(void (^)(uint32_t key, int32_t value, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBUInt32Int32Dictionary *)otherDictionary;
-- (void)setValue:(int32_t)value forKey:(uint32_t)key;
+- (void)setInt32:(int32_t)value forKey:(uint32_t)key;
-- (void)removeValueForKey:(uint32_t)aKey;
+- (void)removeInt32ForKey:(uint32_t)aKey;
- (void)removeAll;
@end
@@ -119,30 +132,32 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithValue:(uint64_t)value
- forKey:(uint32_t)key;
-+ (instancetype)dictionaryWithValues:(const uint64_t [])values
- forKeys:(const uint32_t [])keys
- count:(NSUInteger)count;
++ (instancetype)dictionaryWithUInt64:(uint64_t)value
+ forKey:(uint32_t)key;
++ (instancetype)dictionaryWithUInt64s:(const uint64_t [])values
+ forKeys:(const uint32_t [])keys
+ count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBUInt32UInt64Dictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithValues:(const uint64_t [])values
- forKeys:(const uint32_t [])keys
- count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithUInt64s:(const uint64_t [])values
+ forKeys:(const uint32_t [])keys
+ count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBUInt32UInt64Dictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (BOOL)valueForKey:(uint32_t)key value:(nullable uint64_t *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getUInt64:(nullable uint64_t *)value forKey:(uint32_t)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndUInt64sUsingBlock:
(void (^)(uint32_t key, uint64_t value, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBUInt32UInt64Dictionary *)otherDictionary;
-- (void)setValue:(uint64_t)value forKey:(uint32_t)key;
+- (void)setUInt64:(uint64_t)value forKey:(uint32_t)key;
-- (void)removeValueForKey:(uint32_t)aKey;
+- (void)removeUInt64ForKey:(uint32_t)aKey;
- (void)removeAll;
@end
@@ -154,30 +169,32 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithValue:(int64_t)value
++ (instancetype)dictionaryWithInt64:(int64_t)value
forKey:(uint32_t)key;
-+ (instancetype)dictionaryWithValues:(const int64_t [])values
++ (instancetype)dictionaryWithInt64s:(const int64_t [])values
forKeys:(const uint32_t [])keys
count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBUInt32Int64Dictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithValues:(const int64_t [])values
+- (instancetype)initWithInt64s:(const int64_t [])values
forKeys:(const uint32_t [])keys
count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBUInt32Int64Dictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (BOOL)valueForKey:(uint32_t)key value:(nullable int64_t *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getInt64:(nullable int64_t *)value forKey:(uint32_t)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndInt64sUsingBlock:
(void (^)(uint32_t key, int64_t value, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBUInt32Int64Dictionary *)otherDictionary;
-- (void)setValue:(int64_t)value forKey:(uint32_t)key;
+- (void)setInt64:(int64_t)value forKey:(uint32_t)key;
-- (void)removeValueForKey:(uint32_t)aKey;
+- (void)removeInt64ForKey:(uint32_t)aKey;
- (void)removeAll;
@end
@@ -189,30 +206,32 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithValue:(BOOL)value
- forKey:(uint32_t)key;
-+ (instancetype)dictionaryWithValues:(const BOOL [])values
- forKeys:(const uint32_t [])keys
- count:(NSUInteger)count;
++ (instancetype)dictionaryWithBool:(BOOL)value
+ forKey:(uint32_t)key;
++ (instancetype)dictionaryWithBools:(const BOOL [])values
+ forKeys:(const uint32_t [])keys
+ count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBUInt32BoolDictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithValues:(const BOOL [])values
- forKeys:(const uint32_t [])keys
- count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithBools:(const BOOL [])values
+ forKeys:(const uint32_t [])keys
+ count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBUInt32BoolDictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (BOOL)valueForKey:(uint32_t)key value:(nullable BOOL *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getBool:(nullable BOOL *)value forKey:(uint32_t)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndBoolsUsingBlock:
(void (^)(uint32_t key, BOOL value, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBUInt32BoolDictionary *)otherDictionary;
-- (void)setValue:(BOOL)value forKey:(uint32_t)key;
+- (void)setBool:(BOOL)value forKey:(uint32_t)key;
-- (void)removeValueForKey:(uint32_t)aKey;
+- (void)removeBoolForKey:(uint32_t)aKey;
- (void)removeAll;
@end
@@ -224,30 +243,32 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithValue:(float)value
++ (instancetype)dictionaryWithFloat:(float)value
forKey:(uint32_t)key;
-+ (instancetype)dictionaryWithValues:(const float [])values
++ (instancetype)dictionaryWithFloats:(const float [])values
forKeys:(const uint32_t [])keys
count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBUInt32FloatDictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithValues:(const float [])values
+- (instancetype)initWithFloats:(const float [])values
forKeys:(const uint32_t [])keys
count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBUInt32FloatDictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (BOOL)valueForKey:(uint32_t)key value:(nullable float *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getFloat:(nullable float *)value forKey:(uint32_t)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndFloatsUsingBlock:
(void (^)(uint32_t key, float value, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBUInt32FloatDictionary *)otherDictionary;
-- (void)setValue:(float)value forKey:(uint32_t)key;
+- (void)setFloat:(float)value forKey:(uint32_t)key;
-- (void)removeValueForKey:(uint32_t)aKey;
+- (void)removeFloatForKey:(uint32_t)aKey;
- (void)removeAll;
@end
@@ -259,30 +280,32 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithValue:(double)value
- forKey:(uint32_t)key;
-+ (instancetype)dictionaryWithValues:(const double [])values
- forKeys:(const uint32_t [])keys
- count:(NSUInteger)count;
++ (instancetype)dictionaryWithDouble:(double)value
+ forKey:(uint32_t)key;
++ (instancetype)dictionaryWithDoubles:(const double [])values
+ forKeys:(const uint32_t [])keys
+ count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBUInt32DoubleDictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithValues:(const double [])values
- forKeys:(const uint32_t [])keys
- count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithDoubles:(const double [])values
+ forKeys:(const uint32_t [])keys
+ count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBUInt32DoubleDictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (BOOL)valueForKey:(uint32_t)key value:(nullable double *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getDouble:(nullable double *)value forKey:(uint32_t)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndDoublesUsingBlock:
(void (^)(uint32_t key, double value, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBUInt32DoubleDictionary *)otherDictionary;
-- (void)setValue:(double)value forKey:(uint32_t)key;
+- (void)setDouble:(double)value forKey:(uint32_t)key;
-- (void)removeValueForKey:(uint32_t)aKey;
+- (void)removeDoubleForKey:(uint32_t)aKey;
- (void)removeAll;
@end
@@ -320,15 +343,19 @@ NS_ASSUME_NONNULL_BEGIN
// is not a valid enumerator as defined by validationFunc. If the actual value is
// desired, use "raw" version of the method.
-- (BOOL)valueForKey:(uint32_t)key value:(nullable int32_t *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getEnum:(nullable int32_t *)value forKey:(uint32_t)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndEnumsUsingBlock:
(void (^)(uint32_t key, int32_t value, BOOL *stop))block;
// These methods bypass the validationFunc to provide access to values that were not
// known at the time the binary was compiled.
-- (BOOL)valueForKey:(uint32_t)key rawValue:(nullable int32_t *)rawValue;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getRawValue:(nullable int32_t *)rawValue forKey:(uint32_t)key;
- (void)enumerateKeysAndRawValuesUsingBlock:
(void (^)(uint32_t key, int32_t rawValue, BOOL *stop))block;
@@ -340,7 +367,7 @@ NS_ASSUME_NONNULL_BEGIN
// to the default value. Use the rawValue methods below to assign non enumerator
// values.
-- (void)setValue:(int32_t)value forKey:(uint32_t)key;
+- (void)setEnum:(int32_t)value forKey:(uint32_t)key;
// This method bypass the validationFunc to provide setting of values that were not
// known at the time the binary was compiled.
@@ -348,40 +375,40 @@ NS_ASSUME_NONNULL_BEGIN
// No validation applies to these methods.
-- (void)removeValueForKey:(uint32_t)aKey;
+- (void)removeEnumForKey:(uint32_t)aKey;
- (void)removeAll;
@end
#pragma mark - UInt32 -> Object
-@interface GPBUInt32ObjectDictionary : NSObject <NSCopying>
+@interface GPBUInt32ObjectDictionary<__covariant ObjectType> : NSObject <NSCopying>
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithObject:(id)object
++ (instancetype)dictionaryWithObject:(ObjectType)object
forKey:(uint32_t)key;
-+ (instancetype)dictionaryWithObjects:(const id GPB_UNSAFE_UNRETAINED [])objects
++ (instancetype)dictionaryWithObjects:(const ObjectType GPB_UNSAFE_UNRETAINED [])objects
forKeys:(const uint32_t [])keys
count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBUInt32ObjectDictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithObjects:(const id GPB_UNSAFE_UNRETAINED [])objects
+- (instancetype)initWithObjects:(const ObjectType GPB_UNSAFE_UNRETAINED [])objects
forKeys:(const uint32_t [])keys
count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBUInt32ObjectDictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (id)objectForKey:(uint32_t)key;
+- (ObjectType)objectForKey:(uint32_t)key;
- (void)enumerateKeysAndObjectsUsingBlock:
- (void (^)(uint32_t key, id object, BOOL *stop))block;
+ (void (^)(uint32_t key, ObjectType object, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBUInt32ObjectDictionary *)otherDictionary;
-- (void)setObject:(id)object forKey:(uint32_t)key;
+- (void)setObject:(ObjectType)object forKey:(uint32_t)key;
- (void)removeObjectForKey:(uint32_t)aKey;
- (void)removeAll;
@@ -395,30 +422,32 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithValue:(uint32_t)value
- forKey:(int32_t)key;
-+ (instancetype)dictionaryWithValues:(const uint32_t [])values
- forKeys:(const int32_t [])keys
- count:(NSUInteger)count;
++ (instancetype)dictionaryWithUInt32:(uint32_t)value
+ forKey:(int32_t)key;
++ (instancetype)dictionaryWithUInt32s:(const uint32_t [])values
+ forKeys:(const int32_t [])keys
+ count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBInt32UInt32Dictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithValues:(const uint32_t [])values
- forKeys:(const int32_t [])keys
- count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithUInt32s:(const uint32_t [])values
+ forKeys:(const int32_t [])keys
+ count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBInt32UInt32Dictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (BOOL)valueForKey:(int32_t)key value:(nullable uint32_t *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getUInt32:(nullable uint32_t *)value forKey:(int32_t)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndUInt32sUsingBlock:
(void (^)(int32_t key, uint32_t value, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBInt32UInt32Dictionary *)otherDictionary;
-- (void)setValue:(uint32_t)value forKey:(int32_t)key;
+- (void)setUInt32:(uint32_t)value forKey:(int32_t)key;
-- (void)removeValueForKey:(int32_t)aKey;
+- (void)removeUInt32ForKey:(int32_t)aKey;
- (void)removeAll;
@end
@@ -430,30 +459,32 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithValue:(int32_t)value
++ (instancetype)dictionaryWithInt32:(int32_t)value
forKey:(int32_t)key;
-+ (instancetype)dictionaryWithValues:(const int32_t [])values
++ (instancetype)dictionaryWithInt32s:(const int32_t [])values
forKeys:(const int32_t [])keys
count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBInt32Int32Dictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithValues:(const int32_t [])values
+- (instancetype)initWithInt32s:(const int32_t [])values
forKeys:(const int32_t [])keys
count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBInt32Int32Dictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (BOOL)valueForKey:(int32_t)key value:(nullable int32_t *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getInt32:(nullable int32_t *)value forKey:(int32_t)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndInt32sUsingBlock:
(void (^)(int32_t key, int32_t value, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBInt32Int32Dictionary *)otherDictionary;
-- (void)setValue:(int32_t)value forKey:(int32_t)key;
+- (void)setInt32:(int32_t)value forKey:(int32_t)key;
-- (void)removeValueForKey:(int32_t)aKey;
+- (void)removeInt32ForKey:(int32_t)aKey;
- (void)removeAll;
@end
@@ -465,30 +496,32 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithValue:(uint64_t)value
- forKey:(int32_t)key;
-+ (instancetype)dictionaryWithValues:(const uint64_t [])values
- forKeys:(const int32_t [])keys
- count:(NSUInteger)count;
++ (instancetype)dictionaryWithUInt64:(uint64_t)value
+ forKey:(int32_t)key;
++ (instancetype)dictionaryWithUInt64s:(const uint64_t [])values
+ forKeys:(const int32_t [])keys
+ count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBInt32UInt64Dictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithValues:(const uint64_t [])values
- forKeys:(const int32_t [])keys
- count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithUInt64s:(const uint64_t [])values
+ forKeys:(const int32_t [])keys
+ count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBInt32UInt64Dictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (BOOL)valueForKey:(int32_t)key value:(nullable uint64_t *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getUInt64:(nullable uint64_t *)value forKey:(int32_t)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndUInt64sUsingBlock:
(void (^)(int32_t key, uint64_t value, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBInt32UInt64Dictionary *)otherDictionary;
-- (void)setValue:(uint64_t)value forKey:(int32_t)key;
+- (void)setUInt64:(uint64_t)value forKey:(int32_t)key;
-- (void)removeValueForKey:(int32_t)aKey;
+- (void)removeUInt64ForKey:(int32_t)aKey;
- (void)removeAll;
@end
@@ -500,30 +533,32 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithValue:(int64_t)value
++ (instancetype)dictionaryWithInt64:(int64_t)value
forKey:(int32_t)key;
-+ (instancetype)dictionaryWithValues:(const int64_t [])values
++ (instancetype)dictionaryWithInt64s:(const int64_t [])values
forKeys:(const int32_t [])keys
count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBInt32Int64Dictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithValues:(const int64_t [])values
+- (instancetype)initWithInt64s:(const int64_t [])values
forKeys:(const int32_t [])keys
count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBInt32Int64Dictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (BOOL)valueForKey:(int32_t)key value:(nullable int64_t *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getInt64:(nullable int64_t *)value forKey:(int32_t)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndInt64sUsingBlock:
(void (^)(int32_t key, int64_t value, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBInt32Int64Dictionary *)otherDictionary;
-- (void)setValue:(int64_t)value forKey:(int32_t)key;
+- (void)setInt64:(int64_t)value forKey:(int32_t)key;
-- (void)removeValueForKey:(int32_t)aKey;
+- (void)removeInt64ForKey:(int32_t)aKey;
- (void)removeAll;
@end
@@ -535,30 +570,32 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithValue:(BOOL)value
- forKey:(int32_t)key;
-+ (instancetype)dictionaryWithValues:(const BOOL [])values
- forKeys:(const int32_t [])keys
- count:(NSUInteger)count;
++ (instancetype)dictionaryWithBool:(BOOL)value
+ forKey:(int32_t)key;
++ (instancetype)dictionaryWithBools:(const BOOL [])values
+ forKeys:(const int32_t [])keys
+ count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBInt32BoolDictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithValues:(const BOOL [])values
- forKeys:(const int32_t [])keys
- count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithBools:(const BOOL [])values
+ forKeys:(const int32_t [])keys
+ count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBInt32BoolDictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (BOOL)valueForKey:(int32_t)key value:(nullable BOOL *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getBool:(nullable BOOL *)value forKey:(int32_t)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndBoolsUsingBlock:
(void (^)(int32_t key, BOOL value, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBInt32BoolDictionary *)otherDictionary;
-- (void)setValue:(BOOL)value forKey:(int32_t)key;
+- (void)setBool:(BOOL)value forKey:(int32_t)key;
-- (void)removeValueForKey:(int32_t)aKey;
+- (void)removeBoolForKey:(int32_t)aKey;
- (void)removeAll;
@end
@@ -570,30 +607,32 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithValue:(float)value
++ (instancetype)dictionaryWithFloat:(float)value
forKey:(int32_t)key;
-+ (instancetype)dictionaryWithValues:(const float [])values
++ (instancetype)dictionaryWithFloats:(const float [])values
forKeys:(const int32_t [])keys
count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBInt32FloatDictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithValues:(const float [])values
+- (instancetype)initWithFloats:(const float [])values
forKeys:(const int32_t [])keys
count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBInt32FloatDictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (BOOL)valueForKey:(int32_t)key value:(nullable float *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getFloat:(nullable float *)value forKey:(int32_t)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndFloatsUsingBlock:
(void (^)(int32_t key, float value, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBInt32FloatDictionary *)otherDictionary;
-- (void)setValue:(float)value forKey:(int32_t)key;
+- (void)setFloat:(float)value forKey:(int32_t)key;
-- (void)removeValueForKey:(int32_t)aKey;
+- (void)removeFloatForKey:(int32_t)aKey;
- (void)removeAll;
@end
@@ -605,30 +644,32 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithValue:(double)value
- forKey:(int32_t)key;
-+ (instancetype)dictionaryWithValues:(const double [])values
- forKeys:(const int32_t [])keys
- count:(NSUInteger)count;
++ (instancetype)dictionaryWithDouble:(double)value
+ forKey:(int32_t)key;
++ (instancetype)dictionaryWithDoubles:(const double [])values
+ forKeys:(const int32_t [])keys
+ count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBInt32DoubleDictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithValues:(const double [])values
- forKeys:(const int32_t [])keys
- count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithDoubles:(const double [])values
+ forKeys:(const int32_t [])keys
+ count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBInt32DoubleDictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (BOOL)valueForKey:(int32_t)key value:(nullable double *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getDouble:(nullable double *)value forKey:(int32_t)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndDoublesUsingBlock:
(void (^)(int32_t key, double value, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBInt32DoubleDictionary *)otherDictionary;
-- (void)setValue:(double)value forKey:(int32_t)key;
+- (void)setDouble:(double)value forKey:(int32_t)key;
-- (void)removeValueForKey:(int32_t)aKey;
+- (void)removeDoubleForKey:(int32_t)aKey;
- (void)removeAll;
@end
@@ -666,15 +707,19 @@ NS_ASSUME_NONNULL_BEGIN
// is not a valid enumerator as defined by validationFunc. If the actual value is
// desired, use "raw" version of the method.
-- (BOOL)valueForKey:(int32_t)key value:(nullable int32_t *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getEnum:(nullable int32_t *)value forKey:(int32_t)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndEnumsUsingBlock:
(void (^)(int32_t key, int32_t value, BOOL *stop))block;
// These methods bypass the validationFunc to provide access to values that were not
// known at the time the binary was compiled.
-- (BOOL)valueForKey:(int32_t)key rawValue:(nullable int32_t *)rawValue;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getRawValue:(nullable int32_t *)rawValue forKey:(int32_t)key;
- (void)enumerateKeysAndRawValuesUsingBlock:
(void (^)(int32_t key, int32_t rawValue, BOOL *stop))block;
@@ -686,7 +731,7 @@ NS_ASSUME_NONNULL_BEGIN
// to the default value. Use the rawValue methods below to assign non enumerator
// values.
-- (void)setValue:(int32_t)value forKey:(int32_t)key;
+- (void)setEnum:(int32_t)value forKey:(int32_t)key;
// This method bypass the validationFunc to provide setting of values that were not
// known at the time the binary was compiled.
@@ -694,40 +739,40 @@ NS_ASSUME_NONNULL_BEGIN
// No validation applies to these methods.
-- (void)removeValueForKey:(int32_t)aKey;
+- (void)removeEnumForKey:(int32_t)aKey;
- (void)removeAll;
@end
#pragma mark - Int32 -> Object
-@interface GPBInt32ObjectDictionary : NSObject <NSCopying>
+@interface GPBInt32ObjectDictionary<__covariant ObjectType> : NSObject <NSCopying>
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithObject:(id)object
++ (instancetype)dictionaryWithObject:(ObjectType)object
forKey:(int32_t)key;
-+ (instancetype)dictionaryWithObjects:(const id GPB_UNSAFE_UNRETAINED [])objects
++ (instancetype)dictionaryWithObjects:(const ObjectType GPB_UNSAFE_UNRETAINED [])objects
forKeys:(const int32_t [])keys
count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBInt32ObjectDictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithObjects:(const id GPB_UNSAFE_UNRETAINED [])objects
+- (instancetype)initWithObjects:(const ObjectType GPB_UNSAFE_UNRETAINED [])objects
forKeys:(const int32_t [])keys
count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBInt32ObjectDictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (id)objectForKey:(int32_t)key;
+- (ObjectType)objectForKey:(int32_t)key;
- (void)enumerateKeysAndObjectsUsingBlock:
- (void (^)(int32_t key, id object, BOOL *stop))block;
+ (void (^)(int32_t key, ObjectType object, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBInt32ObjectDictionary *)otherDictionary;
-- (void)setObject:(id)object forKey:(int32_t)key;
+- (void)setObject:(ObjectType)object forKey:(int32_t)key;
- (void)removeObjectForKey:(int32_t)aKey;
- (void)removeAll;
@@ -741,30 +786,32 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithValue:(uint32_t)value
- forKey:(uint64_t)key;
-+ (instancetype)dictionaryWithValues:(const uint32_t [])values
- forKeys:(const uint64_t [])keys
- count:(NSUInteger)count;
++ (instancetype)dictionaryWithUInt32:(uint32_t)value
+ forKey:(uint64_t)key;
++ (instancetype)dictionaryWithUInt32s:(const uint32_t [])values
+ forKeys:(const uint64_t [])keys
+ count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBUInt64UInt32Dictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithValues:(const uint32_t [])values
- forKeys:(const uint64_t [])keys
- count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithUInt32s:(const uint32_t [])values
+ forKeys:(const uint64_t [])keys
+ count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBUInt64UInt32Dictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (BOOL)valueForKey:(uint64_t)key value:(nullable uint32_t *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getUInt32:(nullable uint32_t *)value forKey:(uint64_t)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndUInt32sUsingBlock:
(void (^)(uint64_t key, uint32_t value, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBUInt64UInt32Dictionary *)otherDictionary;
-- (void)setValue:(uint32_t)value forKey:(uint64_t)key;
+- (void)setUInt32:(uint32_t)value forKey:(uint64_t)key;
-- (void)removeValueForKey:(uint64_t)aKey;
+- (void)removeUInt32ForKey:(uint64_t)aKey;
- (void)removeAll;
@end
@@ -776,30 +823,32 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithValue:(int32_t)value
++ (instancetype)dictionaryWithInt32:(int32_t)value
forKey:(uint64_t)key;
-+ (instancetype)dictionaryWithValues:(const int32_t [])values
++ (instancetype)dictionaryWithInt32s:(const int32_t [])values
forKeys:(const uint64_t [])keys
count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBUInt64Int32Dictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithValues:(const int32_t [])values
+- (instancetype)initWithInt32s:(const int32_t [])values
forKeys:(const uint64_t [])keys
count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBUInt64Int32Dictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (BOOL)valueForKey:(uint64_t)key value:(nullable int32_t *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getInt32:(nullable int32_t *)value forKey:(uint64_t)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndInt32sUsingBlock:
(void (^)(uint64_t key, int32_t value, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBUInt64Int32Dictionary *)otherDictionary;
-- (void)setValue:(int32_t)value forKey:(uint64_t)key;
+- (void)setInt32:(int32_t)value forKey:(uint64_t)key;
-- (void)removeValueForKey:(uint64_t)aKey;
+- (void)removeInt32ForKey:(uint64_t)aKey;
- (void)removeAll;
@end
@@ -811,30 +860,32 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithValue:(uint64_t)value
- forKey:(uint64_t)key;
-+ (instancetype)dictionaryWithValues:(const uint64_t [])values
- forKeys:(const uint64_t [])keys
- count:(NSUInteger)count;
++ (instancetype)dictionaryWithUInt64:(uint64_t)value
+ forKey:(uint64_t)key;
++ (instancetype)dictionaryWithUInt64s:(const uint64_t [])values
+ forKeys:(const uint64_t [])keys
+ count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBUInt64UInt64Dictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithValues:(const uint64_t [])values
- forKeys:(const uint64_t [])keys
- count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithUInt64s:(const uint64_t [])values
+ forKeys:(const uint64_t [])keys
+ count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBUInt64UInt64Dictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (BOOL)valueForKey:(uint64_t)key value:(nullable uint64_t *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getUInt64:(nullable uint64_t *)value forKey:(uint64_t)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndUInt64sUsingBlock:
(void (^)(uint64_t key, uint64_t value, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBUInt64UInt64Dictionary *)otherDictionary;
-- (void)setValue:(uint64_t)value forKey:(uint64_t)key;
+- (void)setUInt64:(uint64_t)value forKey:(uint64_t)key;
-- (void)removeValueForKey:(uint64_t)aKey;
+- (void)removeUInt64ForKey:(uint64_t)aKey;
- (void)removeAll;
@end
@@ -846,30 +897,32 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithValue:(int64_t)value
++ (instancetype)dictionaryWithInt64:(int64_t)value
forKey:(uint64_t)key;
-+ (instancetype)dictionaryWithValues:(const int64_t [])values
++ (instancetype)dictionaryWithInt64s:(const int64_t [])values
forKeys:(const uint64_t [])keys
count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBUInt64Int64Dictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithValues:(const int64_t [])values
+- (instancetype)initWithInt64s:(const int64_t [])values
forKeys:(const uint64_t [])keys
count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBUInt64Int64Dictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (BOOL)valueForKey:(uint64_t)key value:(nullable int64_t *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getInt64:(nullable int64_t *)value forKey:(uint64_t)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndInt64sUsingBlock:
(void (^)(uint64_t key, int64_t value, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBUInt64Int64Dictionary *)otherDictionary;
-- (void)setValue:(int64_t)value forKey:(uint64_t)key;
+- (void)setInt64:(int64_t)value forKey:(uint64_t)key;
-- (void)removeValueForKey:(uint64_t)aKey;
+- (void)removeInt64ForKey:(uint64_t)aKey;
- (void)removeAll;
@end
@@ -881,30 +934,32 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithValue:(BOOL)value
- forKey:(uint64_t)key;
-+ (instancetype)dictionaryWithValues:(const BOOL [])values
- forKeys:(const uint64_t [])keys
- count:(NSUInteger)count;
++ (instancetype)dictionaryWithBool:(BOOL)value
+ forKey:(uint64_t)key;
++ (instancetype)dictionaryWithBools:(const BOOL [])values
+ forKeys:(const uint64_t [])keys
+ count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBUInt64BoolDictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithValues:(const BOOL [])values
- forKeys:(const uint64_t [])keys
- count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithBools:(const BOOL [])values
+ forKeys:(const uint64_t [])keys
+ count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBUInt64BoolDictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (BOOL)valueForKey:(uint64_t)key value:(nullable BOOL *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getBool:(nullable BOOL *)value forKey:(uint64_t)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndBoolsUsingBlock:
(void (^)(uint64_t key, BOOL value, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBUInt64BoolDictionary *)otherDictionary;
-- (void)setValue:(BOOL)value forKey:(uint64_t)key;
+- (void)setBool:(BOOL)value forKey:(uint64_t)key;
-- (void)removeValueForKey:(uint64_t)aKey;
+- (void)removeBoolForKey:(uint64_t)aKey;
- (void)removeAll;
@end
@@ -916,30 +971,32 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithValue:(float)value
++ (instancetype)dictionaryWithFloat:(float)value
forKey:(uint64_t)key;
-+ (instancetype)dictionaryWithValues:(const float [])values
++ (instancetype)dictionaryWithFloats:(const float [])values
forKeys:(const uint64_t [])keys
count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBUInt64FloatDictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithValues:(const float [])values
+- (instancetype)initWithFloats:(const float [])values
forKeys:(const uint64_t [])keys
count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBUInt64FloatDictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (BOOL)valueForKey:(uint64_t)key value:(nullable float *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getFloat:(nullable float *)value forKey:(uint64_t)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndFloatsUsingBlock:
(void (^)(uint64_t key, float value, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBUInt64FloatDictionary *)otherDictionary;
-- (void)setValue:(float)value forKey:(uint64_t)key;
+- (void)setFloat:(float)value forKey:(uint64_t)key;
-- (void)removeValueForKey:(uint64_t)aKey;
+- (void)removeFloatForKey:(uint64_t)aKey;
- (void)removeAll;
@end
@@ -951,30 +1008,32 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithValue:(double)value
- forKey:(uint64_t)key;
-+ (instancetype)dictionaryWithValues:(const double [])values
- forKeys:(const uint64_t [])keys
- count:(NSUInteger)count;
++ (instancetype)dictionaryWithDouble:(double)value
+ forKey:(uint64_t)key;
++ (instancetype)dictionaryWithDoubles:(const double [])values
+ forKeys:(const uint64_t [])keys
+ count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBUInt64DoubleDictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithValues:(const double [])values
- forKeys:(const uint64_t [])keys
- count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithDoubles:(const double [])values
+ forKeys:(const uint64_t [])keys
+ count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBUInt64DoubleDictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (BOOL)valueForKey:(uint64_t)key value:(nullable double *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getDouble:(nullable double *)value forKey:(uint64_t)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndDoublesUsingBlock:
(void (^)(uint64_t key, double value, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBUInt64DoubleDictionary *)otherDictionary;
-- (void)setValue:(double)value forKey:(uint64_t)key;
+- (void)setDouble:(double)value forKey:(uint64_t)key;
-- (void)removeValueForKey:(uint64_t)aKey;
+- (void)removeDoubleForKey:(uint64_t)aKey;
- (void)removeAll;
@end
@@ -1012,15 +1071,19 @@ NS_ASSUME_NONNULL_BEGIN
// is not a valid enumerator as defined by validationFunc. If the actual value is
// desired, use "raw" version of the method.
-- (BOOL)valueForKey:(uint64_t)key value:(nullable int32_t *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getEnum:(nullable int32_t *)value forKey:(uint64_t)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndEnumsUsingBlock:
(void (^)(uint64_t key, int32_t value, BOOL *stop))block;
// These methods bypass the validationFunc to provide access to values that were not
// known at the time the binary was compiled.
-- (BOOL)valueForKey:(uint64_t)key rawValue:(nullable int32_t *)rawValue;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getRawValue:(nullable int32_t *)rawValue forKey:(uint64_t)key;
- (void)enumerateKeysAndRawValuesUsingBlock:
(void (^)(uint64_t key, int32_t rawValue, BOOL *stop))block;
@@ -1032,7 +1095,7 @@ NS_ASSUME_NONNULL_BEGIN
// to the default value. Use the rawValue methods below to assign non enumerator
// values.
-- (void)setValue:(int32_t)value forKey:(uint64_t)key;
+- (void)setEnum:(int32_t)value forKey:(uint64_t)key;
// This method bypass the validationFunc to provide setting of values that were not
// known at the time the binary was compiled.
@@ -1040,40 +1103,40 @@ NS_ASSUME_NONNULL_BEGIN
// No validation applies to these methods.
-- (void)removeValueForKey:(uint64_t)aKey;
+- (void)removeEnumForKey:(uint64_t)aKey;
- (void)removeAll;
@end
#pragma mark - UInt64 -> Object
-@interface GPBUInt64ObjectDictionary : NSObject <NSCopying>
+@interface GPBUInt64ObjectDictionary<__covariant ObjectType> : NSObject <NSCopying>
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithObject:(id)object
++ (instancetype)dictionaryWithObject:(ObjectType)object
forKey:(uint64_t)key;
-+ (instancetype)dictionaryWithObjects:(const id GPB_UNSAFE_UNRETAINED [])objects
++ (instancetype)dictionaryWithObjects:(const ObjectType GPB_UNSAFE_UNRETAINED [])objects
forKeys:(const uint64_t [])keys
count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBUInt64ObjectDictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithObjects:(const id GPB_UNSAFE_UNRETAINED [])objects
+- (instancetype)initWithObjects:(const ObjectType GPB_UNSAFE_UNRETAINED [])objects
forKeys:(const uint64_t [])keys
count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBUInt64ObjectDictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (id)objectForKey:(uint64_t)key;
+- (ObjectType)objectForKey:(uint64_t)key;
- (void)enumerateKeysAndObjectsUsingBlock:
- (void (^)(uint64_t key, id object, BOOL *stop))block;
+ (void (^)(uint64_t key, ObjectType object, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBUInt64ObjectDictionary *)otherDictionary;
-- (void)setObject:(id)object forKey:(uint64_t)key;
+- (void)setObject:(ObjectType)object forKey:(uint64_t)key;
- (void)removeObjectForKey:(uint64_t)aKey;
- (void)removeAll;
@@ -1087,30 +1150,32 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithValue:(uint32_t)value
- forKey:(int64_t)key;
-+ (instancetype)dictionaryWithValues:(const uint32_t [])values
- forKeys:(const int64_t [])keys
- count:(NSUInteger)count;
++ (instancetype)dictionaryWithUInt32:(uint32_t)value
+ forKey:(int64_t)key;
++ (instancetype)dictionaryWithUInt32s:(const uint32_t [])values
+ forKeys:(const int64_t [])keys
+ count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBInt64UInt32Dictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithValues:(const uint32_t [])values
- forKeys:(const int64_t [])keys
- count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithUInt32s:(const uint32_t [])values
+ forKeys:(const int64_t [])keys
+ count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBInt64UInt32Dictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (BOOL)valueForKey:(int64_t)key value:(nullable uint32_t *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getUInt32:(nullable uint32_t *)value forKey:(int64_t)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndUInt32sUsingBlock:
(void (^)(int64_t key, uint32_t value, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBInt64UInt32Dictionary *)otherDictionary;
-- (void)setValue:(uint32_t)value forKey:(int64_t)key;
+- (void)setUInt32:(uint32_t)value forKey:(int64_t)key;
-- (void)removeValueForKey:(int64_t)aKey;
+- (void)removeUInt32ForKey:(int64_t)aKey;
- (void)removeAll;
@end
@@ -1122,30 +1187,32 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithValue:(int32_t)value
++ (instancetype)dictionaryWithInt32:(int32_t)value
forKey:(int64_t)key;
-+ (instancetype)dictionaryWithValues:(const int32_t [])values
++ (instancetype)dictionaryWithInt32s:(const int32_t [])values
forKeys:(const int64_t [])keys
count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBInt64Int32Dictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithValues:(const int32_t [])values
+- (instancetype)initWithInt32s:(const int32_t [])values
forKeys:(const int64_t [])keys
count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBInt64Int32Dictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (BOOL)valueForKey:(int64_t)key value:(nullable int32_t *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getInt32:(nullable int32_t *)value forKey:(int64_t)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndInt32sUsingBlock:
(void (^)(int64_t key, int32_t value, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBInt64Int32Dictionary *)otherDictionary;
-- (void)setValue:(int32_t)value forKey:(int64_t)key;
+- (void)setInt32:(int32_t)value forKey:(int64_t)key;
-- (void)removeValueForKey:(int64_t)aKey;
+- (void)removeInt32ForKey:(int64_t)aKey;
- (void)removeAll;
@end
@@ -1157,30 +1224,32 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithValue:(uint64_t)value
- forKey:(int64_t)key;
-+ (instancetype)dictionaryWithValues:(const uint64_t [])values
- forKeys:(const int64_t [])keys
- count:(NSUInteger)count;
++ (instancetype)dictionaryWithUInt64:(uint64_t)value
+ forKey:(int64_t)key;
++ (instancetype)dictionaryWithUInt64s:(const uint64_t [])values
+ forKeys:(const int64_t [])keys
+ count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBInt64UInt64Dictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithValues:(const uint64_t [])values
- forKeys:(const int64_t [])keys
- count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithUInt64s:(const uint64_t [])values
+ forKeys:(const int64_t [])keys
+ count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBInt64UInt64Dictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (BOOL)valueForKey:(int64_t)key value:(nullable uint64_t *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getUInt64:(nullable uint64_t *)value forKey:(int64_t)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndUInt64sUsingBlock:
(void (^)(int64_t key, uint64_t value, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBInt64UInt64Dictionary *)otherDictionary;
-- (void)setValue:(uint64_t)value forKey:(int64_t)key;
+- (void)setUInt64:(uint64_t)value forKey:(int64_t)key;
-- (void)removeValueForKey:(int64_t)aKey;
+- (void)removeUInt64ForKey:(int64_t)aKey;
- (void)removeAll;
@end
@@ -1192,30 +1261,32 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithValue:(int64_t)value
++ (instancetype)dictionaryWithInt64:(int64_t)value
forKey:(int64_t)key;
-+ (instancetype)dictionaryWithValues:(const int64_t [])values
++ (instancetype)dictionaryWithInt64s:(const int64_t [])values
forKeys:(const int64_t [])keys
count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBInt64Int64Dictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithValues:(const int64_t [])values
+- (instancetype)initWithInt64s:(const int64_t [])values
forKeys:(const int64_t [])keys
count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBInt64Int64Dictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (BOOL)valueForKey:(int64_t)key value:(nullable int64_t *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getInt64:(nullable int64_t *)value forKey:(int64_t)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndInt64sUsingBlock:
(void (^)(int64_t key, int64_t value, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBInt64Int64Dictionary *)otherDictionary;
-- (void)setValue:(int64_t)value forKey:(int64_t)key;
+- (void)setInt64:(int64_t)value forKey:(int64_t)key;
-- (void)removeValueForKey:(int64_t)aKey;
+- (void)removeInt64ForKey:(int64_t)aKey;
- (void)removeAll;
@end
@@ -1227,30 +1298,32 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithValue:(BOOL)value
- forKey:(int64_t)key;
-+ (instancetype)dictionaryWithValues:(const BOOL [])values
- forKeys:(const int64_t [])keys
- count:(NSUInteger)count;
++ (instancetype)dictionaryWithBool:(BOOL)value
+ forKey:(int64_t)key;
++ (instancetype)dictionaryWithBools:(const BOOL [])values
+ forKeys:(const int64_t [])keys
+ count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBInt64BoolDictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithValues:(const BOOL [])values
- forKeys:(const int64_t [])keys
- count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithBools:(const BOOL [])values
+ forKeys:(const int64_t [])keys
+ count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBInt64BoolDictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (BOOL)valueForKey:(int64_t)key value:(nullable BOOL *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getBool:(nullable BOOL *)value forKey:(int64_t)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndBoolsUsingBlock:
(void (^)(int64_t key, BOOL value, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBInt64BoolDictionary *)otherDictionary;
-- (void)setValue:(BOOL)value forKey:(int64_t)key;
+- (void)setBool:(BOOL)value forKey:(int64_t)key;
-- (void)removeValueForKey:(int64_t)aKey;
+- (void)removeBoolForKey:(int64_t)aKey;
- (void)removeAll;
@end
@@ -1262,30 +1335,32 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithValue:(float)value
++ (instancetype)dictionaryWithFloat:(float)value
forKey:(int64_t)key;
-+ (instancetype)dictionaryWithValues:(const float [])values
++ (instancetype)dictionaryWithFloats:(const float [])values
forKeys:(const int64_t [])keys
count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBInt64FloatDictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithValues:(const float [])values
+- (instancetype)initWithFloats:(const float [])values
forKeys:(const int64_t [])keys
count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBInt64FloatDictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (BOOL)valueForKey:(int64_t)key value:(nullable float *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getFloat:(nullable float *)value forKey:(int64_t)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndFloatsUsingBlock:
(void (^)(int64_t key, float value, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBInt64FloatDictionary *)otherDictionary;
-- (void)setValue:(float)value forKey:(int64_t)key;
+- (void)setFloat:(float)value forKey:(int64_t)key;
-- (void)removeValueForKey:(int64_t)aKey;
+- (void)removeFloatForKey:(int64_t)aKey;
- (void)removeAll;
@end
@@ -1297,30 +1372,32 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithValue:(double)value
- forKey:(int64_t)key;
-+ (instancetype)dictionaryWithValues:(const double [])values
- forKeys:(const int64_t [])keys
- count:(NSUInteger)count;
++ (instancetype)dictionaryWithDouble:(double)value
+ forKey:(int64_t)key;
++ (instancetype)dictionaryWithDoubles:(const double [])values
+ forKeys:(const int64_t [])keys
+ count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBInt64DoubleDictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithValues:(const double [])values
- forKeys:(const int64_t [])keys
- count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithDoubles:(const double [])values
+ forKeys:(const int64_t [])keys
+ count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBInt64DoubleDictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (BOOL)valueForKey:(int64_t)key value:(nullable double *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getDouble:(nullable double *)value forKey:(int64_t)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndDoublesUsingBlock:
(void (^)(int64_t key, double value, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBInt64DoubleDictionary *)otherDictionary;
-- (void)setValue:(double)value forKey:(int64_t)key;
+- (void)setDouble:(double)value forKey:(int64_t)key;
-- (void)removeValueForKey:(int64_t)aKey;
+- (void)removeDoubleForKey:(int64_t)aKey;
- (void)removeAll;
@end
@@ -1358,15 +1435,19 @@ NS_ASSUME_NONNULL_BEGIN
// is not a valid enumerator as defined by validationFunc. If the actual value is
// desired, use "raw" version of the method.
-- (BOOL)valueForKey:(int64_t)key value:(nullable int32_t *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getEnum:(nullable int32_t *)value forKey:(int64_t)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndEnumsUsingBlock:
(void (^)(int64_t key, int32_t value, BOOL *stop))block;
// These methods bypass the validationFunc to provide access to values that were not
// known at the time the binary was compiled.
-- (BOOL)valueForKey:(int64_t)key rawValue:(nullable int32_t *)rawValue;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getRawValue:(nullable int32_t *)rawValue forKey:(int64_t)key;
- (void)enumerateKeysAndRawValuesUsingBlock:
(void (^)(int64_t key, int32_t rawValue, BOOL *stop))block;
@@ -1378,7 +1459,7 @@ NS_ASSUME_NONNULL_BEGIN
// to the default value. Use the rawValue methods below to assign non enumerator
// values.
-- (void)setValue:(int32_t)value forKey:(int64_t)key;
+- (void)setEnum:(int32_t)value forKey:(int64_t)key;
// This method bypass the validationFunc to provide setting of values that were not
// known at the time the binary was compiled.
@@ -1386,40 +1467,40 @@ NS_ASSUME_NONNULL_BEGIN
// No validation applies to these methods.
-- (void)removeValueForKey:(int64_t)aKey;
+- (void)removeEnumForKey:(int64_t)aKey;
- (void)removeAll;
@end
#pragma mark - Int64 -> Object
-@interface GPBInt64ObjectDictionary : NSObject <NSCopying>
+@interface GPBInt64ObjectDictionary<__covariant ObjectType> : NSObject <NSCopying>
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithObject:(id)object
++ (instancetype)dictionaryWithObject:(ObjectType)object
forKey:(int64_t)key;
-+ (instancetype)dictionaryWithObjects:(const id GPB_UNSAFE_UNRETAINED [])objects
++ (instancetype)dictionaryWithObjects:(const ObjectType GPB_UNSAFE_UNRETAINED [])objects
forKeys:(const int64_t [])keys
count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBInt64ObjectDictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithObjects:(const id GPB_UNSAFE_UNRETAINED [])objects
+- (instancetype)initWithObjects:(const ObjectType GPB_UNSAFE_UNRETAINED [])objects
forKeys:(const int64_t [])keys
count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBInt64ObjectDictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (id)objectForKey:(int64_t)key;
+- (ObjectType)objectForKey:(int64_t)key;
- (void)enumerateKeysAndObjectsUsingBlock:
- (void (^)(int64_t key, id object, BOOL *stop))block;
+ (void (^)(int64_t key, ObjectType object, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBInt64ObjectDictionary *)otherDictionary;
-- (void)setObject:(id)object forKey:(int64_t)key;
+- (void)setObject:(ObjectType)object forKey:(int64_t)key;
- (void)removeObjectForKey:(int64_t)aKey;
- (void)removeAll;
@@ -1433,30 +1514,32 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithValue:(uint32_t)value
- forKey:(BOOL)key;
-+ (instancetype)dictionaryWithValues:(const uint32_t [])values
- forKeys:(const BOOL [])keys
- count:(NSUInteger)count;
++ (instancetype)dictionaryWithUInt32:(uint32_t)value
+ forKey:(BOOL)key;
++ (instancetype)dictionaryWithUInt32s:(const uint32_t [])values
+ forKeys:(const BOOL [])keys
+ count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBBoolUInt32Dictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithValues:(const uint32_t [])values
- forKeys:(const BOOL [])keys
- count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithUInt32s:(const uint32_t [])values
+ forKeys:(const BOOL [])keys
+ count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBBoolUInt32Dictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (BOOL)valueForKey:(BOOL)key value:(nullable uint32_t *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getUInt32:(nullable uint32_t *)value forKey:(BOOL)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndUInt32sUsingBlock:
(void (^)(BOOL key, uint32_t value, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBBoolUInt32Dictionary *)otherDictionary;
-- (void)setValue:(uint32_t)value forKey:(BOOL)key;
+- (void)setUInt32:(uint32_t)value forKey:(BOOL)key;
-- (void)removeValueForKey:(BOOL)aKey;
+- (void)removeUInt32ForKey:(BOOL)aKey;
- (void)removeAll;
@end
@@ -1468,30 +1551,32 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithValue:(int32_t)value
++ (instancetype)dictionaryWithInt32:(int32_t)value
forKey:(BOOL)key;
-+ (instancetype)dictionaryWithValues:(const int32_t [])values
++ (instancetype)dictionaryWithInt32s:(const int32_t [])values
forKeys:(const BOOL [])keys
count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBBoolInt32Dictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithValues:(const int32_t [])values
+- (instancetype)initWithInt32s:(const int32_t [])values
forKeys:(const BOOL [])keys
count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBBoolInt32Dictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (BOOL)valueForKey:(BOOL)key value:(nullable int32_t *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getInt32:(nullable int32_t *)value forKey:(BOOL)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndInt32sUsingBlock:
(void (^)(BOOL key, int32_t value, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBBoolInt32Dictionary *)otherDictionary;
-- (void)setValue:(int32_t)value forKey:(BOOL)key;
+- (void)setInt32:(int32_t)value forKey:(BOOL)key;
-- (void)removeValueForKey:(BOOL)aKey;
+- (void)removeInt32ForKey:(BOOL)aKey;
- (void)removeAll;
@end
@@ -1503,30 +1588,32 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithValue:(uint64_t)value
- forKey:(BOOL)key;
-+ (instancetype)dictionaryWithValues:(const uint64_t [])values
- forKeys:(const BOOL [])keys
- count:(NSUInteger)count;
++ (instancetype)dictionaryWithUInt64:(uint64_t)value
+ forKey:(BOOL)key;
++ (instancetype)dictionaryWithUInt64s:(const uint64_t [])values
+ forKeys:(const BOOL [])keys
+ count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBBoolUInt64Dictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithValues:(const uint64_t [])values
- forKeys:(const BOOL [])keys
- count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithUInt64s:(const uint64_t [])values
+ forKeys:(const BOOL [])keys
+ count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBBoolUInt64Dictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (BOOL)valueForKey:(BOOL)key value:(nullable uint64_t *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getUInt64:(nullable uint64_t *)value forKey:(BOOL)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndUInt64sUsingBlock:
(void (^)(BOOL key, uint64_t value, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBBoolUInt64Dictionary *)otherDictionary;
-- (void)setValue:(uint64_t)value forKey:(BOOL)key;
+- (void)setUInt64:(uint64_t)value forKey:(BOOL)key;
-- (void)removeValueForKey:(BOOL)aKey;
+- (void)removeUInt64ForKey:(BOOL)aKey;
- (void)removeAll;
@end
@@ -1538,30 +1625,32 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithValue:(int64_t)value
++ (instancetype)dictionaryWithInt64:(int64_t)value
forKey:(BOOL)key;
-+ (instancetype)dictionaryWithValues:(const int64_t [])values
++ (instancetype)dictionaryWithInt64s:(const int64_t [])values
forKeys:(const BOOL [])keys
count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBBoolInt64Dictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithValues:(const int64_t [])values
+- (instancetype)initWithInt64s:(const int64_t [])values
forKeys:(const BOOL [])keys
count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBBoolInt64Dictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (BOOL)valueForKey:(BOOL)key value:(nullable int64_t *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getInt64:(nullable int64_t *)value forKey:(BOOL)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndInt64sUsingBlock:
(void (^)(BOOL key, int64_t value, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBBoolInt64Dictionary *)otherDictionary;
-- (void)setValue:(int64_t)value forKey:(BOOL)key;
+- (void)setInt64:(int64_t)value forKey:(BOOL)key;
-- (void)removeValueForKey:(BOOL)aKey;
+- (void)removeInt64ForKey:(BOOL)aKey;
- (void)removeAll;
@end
@@ -1573,30 +1662,32 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithValue:(BOOL)value
- forKey:(BOOL)key;
-+ (instancetype)dictionaryWithValues:(const BOOL [])values
- forKeys:(const BOOL [])keys
- count:(NSUInteger)count;
++ (instancetype)dictionaryWithBool:(BOOL)value
+ forKey:(BOOL)key;
++ (instancetype)dictionaryWithBools:(const BOOL [])values
+ forKeys:(const BOOL [])keys
+ count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBBoolBoolDictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithValues:(const BOOL [])values
- forKeys:(const BOOL [])keys
- count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithBools:(const BOOL [])values
+ forKeys:(const BOOL [])keys
+ count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBBoolBoolDictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (BOOL)valueForKey:(BOOL)key value:(nullable BOOL *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getBool:(nullable BOOL *)value forKey:(BOOL)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndBoolsUsingBlock:
(void (^)(BOOL key, BOOL value, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBBoolBoolDictionary *)otherDictionary;
-- (void)setValue:(BOOL)value forKey:(BOOL)key;
+- (void)setBool:(BOOL)value forKey:(BOOL)key;
-- (void)removeValueForKey:(BOOL)aKey;
+- (void)removeBoolForKey:(BOOL)aKey;
- (void)removeAll;
@end
@@ -1608,30 +1699,32 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithValue:(float)value
++ (instancetype)dictionaryWithFloat:(float)value
forKey:(BOOL)key;
-+ (instancetype)dictionaryWithValues:(const float [])values
++ (instancetype)dictionaryWithFloats:(const float [])values
forKeys:(const BOOL [])keys
count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBBoolFloatDictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithValues:(const float [])values
+- (instancetype)initWithFloats:(const float [])values
forKeys:(const BOOL [])keys
count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBBoolFloatDictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (BOOL)valueForKey:(BOOL)key value:(nullable float *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getFloat:(nullable float *)value forKey:(BOOL)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndFloatsUsingBlock:
(void (^)(BOOL key, float value, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBBoolFloatDictionary *)otherDictionary;
-- (void)setValue:(float)value forKey:(BOOL)key;
+- (void)setFloat:(float)value forKey:(BOOL)key;
-- (void)removeValueForKey:(BOOL)aKey;
+- (void)removeFloatForKey:(BOOL)aKey;
- (void)removeAll;
@end
@@ -1643,30 +1736,32 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithValue:(double)value
- forKey:(BOOL)key;
-+ (instancetype)dictionaryWithValues:(const double [])values
- forKeys:(const BOOL [])keys
- count:(NSUInteger)count;
++ (instancetype)dictionaryWithDouble:(double)value
+ forKey:(BOOL)key;
++ (instancetype)dictionaryWithDoubles:(const double [])values
+ forKeys:(const BOOL [])keys
+ count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBBoolDoubleDictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithValues:(const double [])values
- forKeys:(const BOOL [])keys
- count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithDoubles:(const double [])values
+ forKeys:(const BOOL [])keys
+ count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBBoolDoubleDictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (BOOL)valueForKey:(BOOL)key value:(nullable double *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getDouble:(nullable double *)value forKey:(BOOL)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndDoublesUsingBlock:
(void (^)(BOOL key, double value, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBBoolDoubleDictionary *)otherDictionary;
-- (void)setValue:(double)value forKey:(BOOL)key;
+- (void)setDouble:(double)value forKey:(BOOL)key;
-- (void)removeValueForKey:(BOOL)aKey;
+- (void)removeDoubleForKey:(BOOL)aKey;
- (void)removeAll;
@end
@@ -1704,15 +1799,19 @@ NS_ASSUME_NONNULL_BEGIN
// is not a valid enumerator as defined by validationFunc. If the actual value is
// desired, use "raw" version of the method.
-- (BOOL)valueForKey:(BOOL)key value:(nullable int32_t *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getEnum:(nullable int32_t *)value forKey:(BOOL)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndEnumsUsingBlock:
(void (^)(BOOL key, int32_t value, BOOL *stop))block;
// These methods bypass the validationFunc to provide access to values that were not
// known at the time the binary was compiled.
-- (BOOL)valueForKey:(BOOL)key rawValue:(nullable int32_t *)rawValue;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getRawValue:(nullable int32_t *)rawValue forKey:(BOOL)key;
- (void)enumerateKeysAndRawValuesUsingBlock:
(void (^)(BOOL key, int32_t rawValue, BOOL *stop))block;
@@ -1724,7 +1823,7 @@ NS_ASSUME_NONNULL_BEGIN
// to the default value. Use the rawValue methods below to assign non enumerator
// values.
-- (void)setValue:(int32_t)value forKey:(BOOL)key;
+- (void)setEnum:(int32_t)value forKey:(BOOL)key;
// This method bypass the validationFunc to provide setting of values that were not
// known at the time the binary was compiled.
@@ -1732,40 +1831,40 @@ NS_ASSUME_NONNULL_BEGIN
// No validation applies to these methods.
-- (void)removeValueForKey:(BOOL)aKey;
+- (void)removeEnumForKey:(BOOL)aKey;
- (void)removeAll;
@end
#pragma mark - Bool -> Object
-@interface GPBBoolObjectDictionary : NSObject <NSCopying>
+@interface GPBBoolObjectDictionary<__covariant ObjectType> : NSObject <NSCopying>
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithObject:(id)object
++ (instancetype)dictionaryWithObject:(ObjectType)object
forKey:(BOOL)key;
-+ (instancetype)dictionaryWithObjects:(const id GPB_UNSAFE_UNRETAINED [])objects
++ (instancetype)dictionaryWithObjects:(const ObjectType GPB_UNSAFE_UNRETAINED [])objects
forKeys:(const BOOL [])keys
count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBBoolObjectDictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithObjects:(const id GPB_UNSAFE_UNRETAINED [])objects
+- (instancetype)initWithObjects:(const ObjectType GPB_UNSAFE_UNRETAINED [])objects
forKeys:(const BOOL [])keys
count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBBoolObjectDictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (id)objectForKey:(BOOL)key;
+- (ObjectType)objectForKey:(BOOL)key;
- (void)enumerateKeysAndObjectsUsingBlock:
- (void (^)(BOOL key, id object, BOOL *stop))block;
+ (void (^)(BOOL key, ObjectType object, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBBoolObjectDictionary *)otherDictionary;
-- (void)setObject:(id)object forKey:(BOOL)key;
+- (void)setObject:(ObjectType)object forKey:(BOOL)key;
- (void)removeObjectForKey:(BOOL)aKey;
- (void)removeAll;
@@ -1779,30 +1878,32 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithValue:(uint32_t)value
- forKey:(NSString *)key;
-+ (instancetype)dictionaryWithValues:(const uint32_t [])values
- forKeys:(const NSString * GPB_UNSAFE_UNRETAINED [])keys
- count:(NSUInteger)count;
++ (instancetype)dictionaryWithUInt32:(uint32_t)value
+ forKey:(NSString *)key;
++ (instancetype)dictionaryWithUInt32s:(const uint32_t [])values
+ forKeys:(const NSString * GPB_UNSAFE_UNRETAINED [])keys
+ count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBStringUInt32Dictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithValues:(const uint32_t [])values
- forKeys:(const NSString * GPB_UNSAFE_UNRETAINED [])keys
- count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithUInt32s:(const uint32_t [])values
+ forKeys:(const NSString * GPB_UNSAFE_UNRETAINED [])keys
+ count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBStringUInt32Dictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (BOOL)valueForKey:(NSString *)key value:(nullable uint32_t *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getUInt32:(nullable uint32_t *)value forKey:(NSString *)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndUInt32sUsingBlock:
(void (^)(NSString *key, uint32_t value, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBStringUInt32Dictionary *)otherDictionary;
-- (void)setValue:(uint32_t)value forKey:(NSString *)key;
+- (void)setUInt32:(uint32_t)value forKey:(NSString *)key;
-- (void)removeValueForKey:(NSString *)aKey;
+- (void)removeUInt32ForKey:(NSString *)aKey;
- (void)removeAll;
@end
@@ -1814,30 +1915,32 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithValue:(int32_t)value
++ (instancetype)dictionaryWithInt32:(int32_t)value
forKey:(NSString *)key;
-+ (instancetype)dictionaryWithValues:(const int32_t [])values
++ (instancetype)dictionaryWithInt32s:(const int32_t [])values
forKeys:(const NSString * GPB_UNSAFE_UNRETAINED [])keys
count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBStringInt32Dictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithValues:(const int32_t [])values
+- (instancetype)initWithInt32s:(const int32_t [])values
forKeys:(const NSString * GPB_UNSAFE_UNRETAINED [])keys
count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBStringInt32Dictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (BOOL)valueForKey:(NSString *)key value:(nullable int32_t *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getInt32:(nullable int32_t *)value forKey:(NSString *)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndInt32sUsingBlock:
(void (^)(NSString *key, int32_t value, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBStringInt32Dictionary *)otherDictionary;
-- (void)setValue:(int32_t)value forKey:(NSString *)key;
+- (void)setInt32:(int32_t)value forKey:(NSString *)key;
-- (void)removeValueForKey:(NSString *)aKey;
+- (void)removeInt32ForKey:(NSString *)aKey;
- (void)removeAll;
@end
@@ -1849,30 +1952,32 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithValue:(uint64_t)value
- forKey:(NSString *)key;
-+ (instancetype)dictionaryWithValues:(const uint64_t [])values
- forKeys:(const NSString * GPB_UNSAFE_UNRETAINED [])keys
- count:(NSUInteger)count;
++ (instancetype)dictionaryWithUInt64:(uint64_t)value
+ forKey:(NSString *)key;
++ (instancetype)dictionaryWithUInt64s:(const uint64_t [])values
+ forKeys:(const NSString * GPB_UNSAFE_UNRETAINED [])keys
+ count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBStringUInt64Dictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithValues:(const uint64_t [])values
- forKeys:(const NSString * GPB_UNSAFE_UNRETAINED [])keys
- count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithUInt64s:(const uint64_t [])values
+ forKeys:(const NSString * GPB_UNSAFE_UNRETAINED [])keys
+ count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBStringUInt64Dictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (BOOL)valueForKey:(NSString *)key value:(nullable uint64_t *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getUInt64:(nullable uint64_t *)value forKey:(NSString *)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndUInt64sUsingBlock:
(void (^)(NSString *key, uint64_t value, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBStringUInt64Dictionary *)otherDictionary;
-- (void)setValue:(uint64_t)value forKey:(NSString *)key;
+- (void)setUInt64:(uint64_t)value forKey:(NSString *)key;
-- (void)removeValueForKey:(NSString *)aKey;
+- (void)removeUInt64ForKey:(NSString *)aKey;
- (void)removeAll;
@end
@@ -1884,30 +1989,32 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithValue:(int64_t)value
++ (instancetype)dictionaryWithInt64:(int64_t)value
forKey:(NSString *)key;
-+ (instancetype)dictionaryWithValues:(const int64_t [])values
++ (instancetype)dictionaryWithInt64s:(const int64_t [])values
forKeys:(const NSString * GPB_UNSAFE_UNRETAINED [])keys
count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBStringInt64Dictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithValues:(const int64_t [])values
+- (instancetype)initWithInt64s:(const int64_t [])values
forKeys:(const NSString * GPB_UNSAFE_UNRETAINED [])keys
count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBStringInt64Dictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (BOOL)valueForKey:(NSString *)key value:(nullable int64_t *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getInt64:(nullable int64_t *)value forKey:(NSString *)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndInt64sUsingBlock:
(void (^)(NSString *key, int64_t value, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBStringInt64Dictionary *)otherDictionary;
-- (void)setValue:(int64_t)value forKey:(NSString *)key;
+- (void)setInt64:(int64_t)value forKey:(NSString *)key;
-- (void)removeValueForKey:(NSString *)aKey;
+- (void)removeInt64ForKey:(NSString *)aKey;
- (void)removeAll;
@end
@@ -1919,30 +2026,32 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithValue:(BOOL)value
- forKey:(NSString *)key;
-+ (instancetype)dictionaryWithValues:(const BOOL [])values
- forKeys:(const NSString * GPB_UNSAFE_UNRETAINED [])keys
- count:(NSUInteger)count;
++ (instancetype)dictionaryWithBool:(BOOL)value
+ forKey:(NSString *)key;
++ (instancetype)dictionaryWithBools:(const BOOL [])values
+ forKeys:(const NSString * GPB_UNSAFE_UNRETAINED [])keys
+ count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBStringBoolDictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithValues:(const BOOL [])values
- forKeys:(const NSString * GPB_UNSAFE_UNRETAINED [])keys
- count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithBools:(const BOOL [])values
+ forKeys:(const NSString * GPB_UNSAFE_UNRETAINED [])keys
+ count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBStringBoolDictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (BOOL)valueForKey:(NSString *)key value:(nullable BOOL *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getBool:(nullable BOOL *)value forKey:(NSString *)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndBoolsUsingBlock:
(void (^)(NSString *key, BOOL value, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBStringBoolDictionary *)otherDictionary;
-- (void)setValue:(BOOL)value forKey:(NSString *)key;
+- (void)setBool:(BOOL)value forKey:(NSString *)key;
-- (void)removeValueForKey:(NSString *)aKey;
+- (void)removeBoolForKey:(NSString *)aKey;
- (void)removeAll;
@end
@@ -1954,30 +2063,32 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithValue:(float)value
++ (instancetype)dictionaryWithFloat:(float)value
forKey:(NSString *)key;
-+ (instancetype)dictionaryWithValues:(const float [])values
++ (instancetype)dictionaryWithFloats:(const float [])values
forKeys:(const NSString * GPB_UNSAFE_UNRETAINED [])keys
count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBStringFloatDictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithValues:(const float [])values
+- (instancetype)initWithFloats:(const float [])values
forKeys:(const NSString * GPB_UNSAFE_UNRETAINED [])keys
count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBStringFloatDictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (BOOL)valueForKey:(NSString *)key value:(nullable float *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getFloat:(nullable float *)value forKey:(NSString *)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndFloatsUsingBlock:
(void (^)(NSString *key, float value, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBStringFloatDictionary *)otherDictionary;
-- (void)setValue:(float)value forKey:(NSString *)key;
+- (void)setFloat:(float)value forKey:(NSString *)key;
-- (void)removeValueForKey:(NSString *)aKey;
+- (void)removeFloatForKey:(NSString *)aKey;
- (void)removeAll;
@end
@@ -1989,30 +2100,32 @@ NS_ASSUME_NONNULL_BEGIN
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)dictionary;
-+ (instancetype)dictionaryWithValue:(double)value
- forKey:(NSString *)key;
-+ (instancetype)dictionaryWithValues:(const double [])values
- forKeys:(const NSString * GPB_UNSAFE_UNRETAINED [])keys
- count:(NSUInteger)count;
++ (instancetype)dictionaryWithDouble:(double)value
+ forKey:(NSString *)key;
++ (instancetype)dictionaryWithDoubles:(const double [])values
+ forKeys:(const NSString * GPB_UNSAFE_UNRETAINED [])keys
+ count:(NSUInteger)count;
+ (instancetype)dictionaryWithDictionary:(GPBStringDoubleDictionary *)dictionary;
+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
-- (instancetype)initWithValues:(const double [])values
- forKeys:(const NSString * GPB_UNSAFE_UNRETAINED [])keys
- count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithDoubles:(const double [])values
+ forKeys:(const NSString * GPB_UNSAFE_UNRETAINED [])keys
+ count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithDictionary:(GPBStringDoubleDictionary *)dictionary;
- (instancetype)initWithCapacity:(NSUInteger)numItems;
-- (BOOL)valueForKey:(NSString *)key value:(nullable double *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getDouble:(nullable double *)value forKey:(NSString *)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndDoublesUsingBlock:
(void (^)(NSString *key, double value, BOOL *stop))block;
- (void)addEntriesFromDictionary:(GPBStringDoubleDictionary *)otherDictionary;
-- (void)setValue:(double)value forKey:(NSString *)key;
+- (void)setDouble:(double)value forKey:(NSString *)key;
-- (void)removeValueForKey:(NSString *)aKey;
+- (void)removeDoubleForKey:(NSString *)aKey;
- (void)removeAll;
@end
@@ -2050,15 +2163,19 @@ NS_ASSUME_NONNULL_BEGIN
// is not a valid enumerator as defined by validationFunc. If the actual value is
// desired, use "raw" version of the method.
-- (BOOL)valueForKey:(NSString *)key value:(nullable int32_t *)value;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getEnum:(nullable int32_t *)value forKey:(NSString *)key;
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndEnumsUsingBlock:
(void (^)(NSString *key, int32_t value, BOOL *stop))block;
// These methods bypass the validationFunc to provide access to values that were not
// known at the time the binary was compiled.
-- (BOOL)valueForKey:(NSString *)key rawValue:(nullable int32_t *)rawValue;
+// Returns YES/NO to indicate if the key was found or not, filling in the value
+// only when the key was found.
+- (BOOL)getRawValue:(nullable int32_t *)rawValue forKey:(NSString *)key;
- (void)enumerateKeysAndRawValuesUsingBlock:
(void (^)(NSString *key, int32_t rawValue, BOOL *stop))block;
@@ -2070,7 +2187,7 @@ NS_ASSUME_NONNULL_BEGIN
// to the default value. Use the rawValue methods below to assign non enumerator
// values.
-- (void)setValue:(int32_t)value forKey:(NSString *)key;
+- (void)setEnum:(int32_t)value forKey:(NSString *)key;
// This method bypass the validationFunc to provide setting of values that were not
// known at the time the binary was compiled.
@@ -2078,7 +2195,7 @@ NS_ASSUME_NONNULL_BEGIN
// No validation applies to these methods.
-- (void)removeValueForKey:(NSString *)aKey;
+- (void)removeEnumForKey:(NSString *)aKey;
- (void)removeAll;
@end
@@ -2096,7 +2213,7 @@ NS_ASSUME_NONNULL_END
//%DICTIONARY_POD_INTERFACES_FOR_KEY(String, NSString, *, OBJECT)
//%PDDM-DEFINE DICTIONARY_INTERFACES_FOR_POD_KEY(KEY_NAME, KEY_TYPE)
//%DICTIONARY_POD_INTERFACES_FOR_KEY(KEY_NAME, KEY_TYPE, , POD)
-//%DICTIONARY_POD_KEY_TO_OBJECT_INTERFACE(KEY_NAME, KEY_TYPE, Object, id)
+//%DICTIONARY_POD_KEY_TO_OBJECT_INTERFACE(KEY_NAME, KEY_TYPE, Object, ObjectType)
//%PDDM-DEFINE DICTIONARY_POD_INTERFACES_FOR_KEY(KEY_NAME, KEY_TYPE, KisP, KHELPER)
//%DICTIONARY_KEY_TO_POD_INTERFACE(KEY_NAME, KEY_TYPE, KisP, KHELPER, UInt32, uint32_t)
//%DICTIONARY_KEY_TO_POD_INTERFACE(KEY_NAME, KEY_TYPE, KisP, KHELPER, Int32, int32_t)
@@ -2107,48 +2224,56 @@ NS_ASSUME_NONNULL_END
//%DICTIONARY_KEY_TO_POD_INTERFACE(KEY_NAME, KEY_TYPE, KisP, KHELPER, Double, double)
//%DICTIONARY_KEY_TO_ENUM_INTERFACE(KEY_NAME, KEY_TYPE, KisP, KHELPER, Enum, int32_t)
//%PDDM-DEFINE DICTIONARY_KEY_TO_POD_INTERFACE(KEY_NAME, KEY_TYPE, KisP, KHELPER, VALUE_NAME, VALUE_TYPE)
-//%DICTIONARY_COMMON_INTERFACE(KEY_NAME, KEY_TYPE, KisP, KHELPER, VALUE_NAME, VALUE_TYPE, POD, value)
+//%DICTIONARY_COMMON_INTERFACE(KEY_NAME, KEY_TYPE, KisP, KHELPER, VALUE_NAME, VALUE_TYPE, POD, VALUE_NAME, value)
//%PDDM-DEFINE DICTIONARY_POD_KEY_TO_OBJECT_INTERFACE(KEY_NAME, KEY_TYPE, VALUE_NAME, VALUE_TYPE)
-//%DICTIONARY_COMMON_INTERFACE(KEY_NAME, KEY_TYPE, , POD, VALUE_NAME, VALUE_TYPE, OBJECT, object)
-//%PDDM-DEFINE VALUE_FOR_KEY_POD(KEY_TYPE, VALUE_TYPE)
-//%- (BOOL)valueForKey:(KEY_TYPE)key value:(nullable VALUE_TYPE *)value;
-//%PDDM-DEFINE VALUE_FOR_KEY_OBJECT(KEY_TYPE, VALUE_TYPE)
+//%DICTIONARY_COMMON_INTERFACE(KEY_NAME, KEY_TYPE, , POD, VALUE_NAME, VALUE_TYPE, OBJECT, Object, object)
+//%PDDM-DEFINE VALUE_FOR_KEY_POD(KEY_TYPE, VALUE_TYPE, VNAME)
+//%// Returns YES/NO to indicate if the key was found or not, filling in the value
+//%// only when the key was found.
+//%- (BOOL)get##VNAME##:(nullable VALUE_TYPE *)value forKey:(KEY_TYPE)key;
+//%PDDM-DEFINE VALUE_FOR_KEY_OBJECT(KEY_TYPE, VALUE_TYPE, VNAME)
//%- (VALUE_TYPE)objectForKey:(KEY_TYPE)key;
-//%PDDM-DEFINE VALUE_FOR_KEY_Enum(KEY_TYPE, VALUE_TYPE)
-//%VALUE_FOR_KEY_POD(KEY_TYPE, VALUE_TYPE)
+//%PDDM-DEFINE VALUE_FOR_KEY_Enum(KEY_TYPE, VALUE_TYPE, VNAME)
+//%VALUE_FOR_KEY_POD(KEY_TYPE, VALUE_TYPE, VNAME)
//%PDDM-DEFINE ARRAY_ARG_MODIFIERPOD()
// Nothing
//%PDDM-DEFINE ARRAY_ARG_MODIFIEREnum()
// Nothing
//%PDDM-DEFINE ARRAY_ARG_MODIFIEROBJECT()
//%GPB_UNSAFE_UNRETAINED ##
-//%PDDM-DEFINE DICTIONARY_COMMON_INTERFACE(KEY_NAME, KEY_TYPE, KisP, KHELPER, VALUE_NAME, VALUE_TYPE, VHELPER, VNAME)
+//%PDDM-DEFINE DICTIONARY_CLASS_DECLPOD(KEY_NAME, VALUE_NAME, VALUE_TYPE)
+//%GPB##KEY_NAME##VALUE_NAME##Dictionary
+//%PDDM-DEFINE DICTIONARY_CLASS_DECLEnum(KEY_NAME, VALUE_NAME, VALUE_TYPE)
+//%GPB##KEY_NAME##VALUE_NAME##Dictionary
+//%PDDM-DEFINE DICTIONARY_CLASS_DECLOBJECT(KEY_NAME, VALUE_NAME, VALUE_TYPE)
+//%GPB##KEY_NAME##VALUE_NAME##Dictionary<__covariant VALUE_TYPE>
+//%PDDM-DEFINE DICTIONARY_COMMON_INTERFACE(KEY_NAME, KEY_TYPE, KisP, KHELPER, VALUE_NAME, VALUE_TYPE, VHELPER, VNAME, VNAME_VAR)
//%#pragma mark - KEY_NAME -> VALUE_NAME
//%
-//%@interface GPB##KEY_NAME##VALUE_NAME##Dictionary : NSObject <NSCopying>
+//%@interface DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) : NSObject <NSCopying>
//%
//%@property(nonatomic, readonly) NSUInteger count;
//%
//%+ (instancetype)dictionary;
-//%+ (instancetype)dictionaryWith##VNAME$u##:(VALUE_TYPE)##VNAME
+//%+ (instancetype)dictionaryWith##VNAME##:(VALUE_TYPE)##VNAME_VAR
//% ##VNAME$S## forKey:(KEY_TYPE##KisP$S##KisP)key;
-//%+ (instancetype)dictionaryWith##VNAME$u##s:(const VALUE_TYPE ARRAY_ARG_MODIFIER##VHELPER()[])##VNAME##s
+//%+ (instancetype)dictionaryWith##VNAME##s:(const VALUE_TYPE ARRAY_ARG_MODIFIER##VHELPER()[])##VNAME_VAR##s
//% ##VNAME$S## forKeys:(const KEY_TYPE##KisP$S##KisP ARRAY_ARG_MODIFIER##KHELPER()[])keys
//% ##VNAME$S## count:(NSUInteger)count;
//%+ (instancetype)dictionaryWithDictionary:(GPB##KEY_NAME##VALUE_NAME##Dictionary *)dictionary;
//%+ (instancetype)dictionaryWithCapacity:(NSUInteger)numItems;
//%
-//%- (instancetype)initWith##VNAME$u##s:(const VALUE_TYPE ARRAY_ARG_MODIFIER##VHELPER()[])##VNAME##s
+//%- (instancetype)initWith##VNAME##s:(const VALUE_TYPE ARRAY_ARG_MODIFIER##VHELPER()[])##VNAME_VAR##s
//% ##VNAME$S## forKeys:(const KEY_TYPE##KisP$S##KisP ARRAY_ARG_MODIFIER##KHELPER()[])keys
//% ##VNAME$S## count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
//%- (instancetype)initWithDictionary:(GPB##KEY_NAME##VALUE_NAME##Dictionary *)dictionary;
//%- (instancetype)initWithCapacity:(NSUInteger)numItems;
//%
-//%DICTIONARY_IMMUTABLE_INTERFACE(KEY_NAME, KEY_TYPE, KisP, VALUE_NAME, VALUE_TYPE, VHELPER, VNAME)
+//%DICTIONARY_IMMUTABLE_INTERFACE(KEY_NAME, KEY_TYPE, KisP, VALUE_NAME, VALUE_TYPE, VHELPER, VNAME, VNAME_VAR)
//%
//%- (void)addEntriesFromDictionary:(GPB##KEY_NAME##VALUE_NAME##Dictionary *)otherDictionary;
//%
-//%DICTIONARY_MUTABLE_INTERFACE(KEY_NAME, KEY_TYPE, KisP, VALUE_NAME, VALUE_TYPE, VHELPER, VNAME)
+//%DICTIONARY_MUTABLE_INTERFACE(KEY_NAME, KEY_TYPE, KisP, VALUE_NAME, VALUE_TYPE, VHELPER, VNAME, VNAME_VAR)
//%
//%@end
//%
@@ -2189,12 +2314,14 @@ NS_ASSUME_NONNULL_END
//%// is not a valid enumerator as defined by validationFunc. If the actual value is
//%// desired, use "raw" version of the method.
//%
-//%DICTIONARY_IMMUTABLE_INTERFACE(KEY_NAME, KEY_TYPE, KisP, VALUE_NAME, VALUE_TYPE, VHELPER, value)
+//%DICTIONARY_IMMUTABLE_INTERFACE(KEY_NAME, KEY_TYPE, KisP, VALUE_NAME, VALUE_TYPE, VHELPER, Enum, value)
//%
//%// These methods bypass the validationFunc to provide access to values that were not
//%// known at the time the binary was compiled.
//%
-//%- (BOOL)valueForKey:(KEY_TYPE##KisP$S##KisP)key rawValue:(nullable VALUE_TYPE *)rawValue;
+//%// Returns YES/NO to indicate if the key was found or not, filling in the value
+//%// only when the key was found.
+//%- (BOOL)getRawValue:(nullable VALUE_TYPE *)rawValue forKey:(KEY_TYPE##KisP$S##KisP)key;
//%
//%- (void)enumerateKeysAndRawValuesUsingBlock:
//% (void (^)(KEY_TYPE KisP##key, VALUE_TYPE rawValue, BOOL *stop))block;
@@ -2206,21 +2333,21 @@ NS_ASSUME_NONNULL_END
//%// to the default value. Use the rawValue methods below to assign non enumerator
//%// values.
//%
-//%DICTIONARY_MUTABLE_INTERFACE(KEY_NAME, KEY_TYPE, KisP, VALUE_NAME, VALUE_TYPE, VHELPER, value)
+//%DICTIONARY_MUTABLE_INTERFACE(KEY_NAME, KEY_TYPE, KisP, VALUE_NAME, VALUE_TYPE, VHELPER, Enum, value)
//%
//%@end
//%
-//%PDDM-DEFINE DICTIONARY_IMMUTABLE_INTERFACE(KEY_NAME, KEY_TYPE, KisP, VALUE_NAME, VALUE_TYPE, VHELPER, VNAME)
-//%VALUE_FOR_KEY_##VHELPER(KEY_TYPE##KisP$S##KisP, VALUE_TYPE)
+//%PDDM-DEFINE DICTIONARY_IMMUTABLE_INTERFACE(KEY_NAME, KEY_TYPE, KisP, VALUE_NAME, VALUE_TYPE, VHELPER, VNAME, VNAME_VAR)
+//%VALUE_FOR_KEY_##VHELPER(KEY_TYPE##KisP$S##KisP, VALUE_TYPE, VNAME)
//%
-//%- (void)enumerateKeysAnd##VNAME$u##sUsingBlock:
-//% (void (^)(KEY_TYPE KisP##key, VALUE_TYPE VNAME, BOOL *stop))block;
+//%- (void)enumerateKeysAnd##VNAME##sUsingBlock:
+//% (void (^)(KEY_TYPE KisP##key, VALUE_TYPE VNAME_VAR, BOOL *stop))block;
-//%PDDM-DEFINE DICTIONARY_MUTABLE_INTERFACE(KEY_NAME, KEY_TYPE, KisP, VALUE_NAME, VALUE_TYPE, VHELPER, VNAME)
-//%- (void)set##VNAME$u##:(VALUE_TYPE)##VNAME forKey:(KEY_TYPE##KisP$S##KisP)key;
+//%PDDM-DEFINE DICTIONARY_MUTABLE_INTERFACE(KEY_NAME, KEY_TYPE, KisP, VALUE_NAME, VALUE_TYPE, VHELPER, VNAME, VNAME_VAR)
+//%- (void)set##VNAME##:(VALUE_TYPE)##VNAME_VAR forKey:(KEY_TYPE##KisP$S##KisP)key;
//%DICTIONARY_EXTRA_MUTABLE_METHODS_##VHELPER(KEY_NAME, KEY_TYPE, KisP, VALUE_NAME, VALUE_TYPE)
-//%- (void)remove##VNAME$u##ForKey:(KEY_TYPE##KisP$S##KisP)aKey;
+//%- (void)remove##VNAME##ForKey:(KEY_TYPE##KisP$S##KisP)aKey;
//%- (void)removeAll;
//%PDDM-DEFINE DICTIONARY_EXTRA_MUTABLE_METHODS_POD(KEY_NAME, KEY_TYPE, KisP, VALUE_NAME, VALUE_TYPE)
diff --git a/objectivec/GPBDictionary.m b/objectivec/GPBDictionary.m
index 6baa2a18..fd8bd1ce 100644
--- a/objectivec/GPBDictionary.m
+++ b/objectivec/GPBDictionary.m
@@ -31,7 +31,7 @@
#import "GPBDictionary_PackagePrivate.h"
#import "GPBCodedInputStream_PackagePrivate.h"
-#import "GPBCodedOutputStream.h"
+#import "GPBCodedOutputStream_PackagePrivate.h"
#import "GPBDescriptor_PackagePrivate.h"
#import "GPBMessage_PackagePrivate.h"
#import "GPBUtilities_PackagePrivate.h"
@@ -45,6 +45,12 @@
// directly.
// ------------------------------------------------------------------
+// Direct access is use for speed, to avoid even internally declaring things
+// read/write, etc. The warning is enabled in the project to ensure code calling
+// protos can turn on -Wdirect-ivar-access without issues.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdirect-ivar-access"
+
// Used to include code only visible to specific versions of the static
// analyzer. Useful for wrapping code that only exists to silence the analyzer.
// Determine the values you want to use for BEGIN_APPLE_BUILD_VERSION,
@@ -484,6 +490,8 @@ void GPBDictionaryReadEntry(id mapDictionary,
key.valueString = [@"" retain];
}
if (GPBDataTypeIsObject(valueDataType) && value.valueString == nil) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wswitch-enum"
switch (valueDataType) {
case GPBDataTypeString:
value.valueString = [@"" retain];
@@ -505,6 +513,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
// Nothing
break;
}
+#pragma clang diagnostic pop
}
if ((keyDataType == GPBDataTypeString) && GPBDataTypeIsObject(valueDataType)) {
@@ -568,12 +577,12 @@ void GPBDictionaryReadEntry(id mapDictionary,
//%DICTIONARY_KEY_TO_ENUM_IMPL(KEY_NAME, KEY_TYPE, KisP, Enum, int32_t, KHELPER)
//%PDDM-DEFINE DICTIONARY_KEY_TO_POD_IMPL(KEY_NAME, KEY_TYPE, KisP, VALUE_NAME, VALUE_TYPE, KHELPER)
-//%DICTIONARY_COMMON_IMPL(KEY_NAME, KEY_TYPE, KisP, VALUE_NAME, VALUE_TYPE, KHELPER, POD, value)
+//%DICTIONARY_COMMON_IMPL(KEY_NAME, KEY_TYPE, KisP, VALUE_NAME, VALUE_TYPE, KHELPER, POD, VALUE_NAME, value)
//%PDDM-DEFINE DICTIONARY_POD_KEY_TO_OBJECT_IMPL(KEY_NAME, KEY_TYPE, VALUE_NAME, VALUE_TYPE)
-//%DICTIONARY_COMMON_IMPL(KEY_NAME, KEY_TYPE, , VALUE_NAME, VALUE_TYPE, POD, OBJECT, object)
+//%DICTIONARY_COMMON_IMPL(KEY_NAME, KEY_TYPE, , VALUE_NAME, VALUE_TYPE, POD, OBJECT, Object, object)
-//%PDDM-DEFINE DICTIONARY_COMMON_IMPL(KEY_NAME, KEY_TYPE, KisP, VALUE_NAME, VALUE_TYPE, KHELPER, VHELPER, VNAME)
+//%PDDM-DEFINE DICTIONARY_COMMON_IMPL(KEY_NAME, KEY_TYPE, KisP, VALUE_NAME, VALUE_TYPE, KHELPER, VHELPER, VNAME, VNAME_VAR)
//%#pragma mark - KEY_NAME -> VALUE_NAME
//%
//%@implementation GPB##KEY_NAME##VALUE_NAME##Dictionary {
@@ -582,24 +591,24 @@ void GPBDictionaryReadEntry(id mapDictionary,
//%}
//%
//%+ (instancetype)dictionary {
-//% return [[[self alloc] initWith##VNAME$u##s:NULL forKeys:NULL count:0] autorelease];
+//% return [[[self alloc] initWith##VNAME##s:NULL forKeys:NULL count:0] autorelease];
//%}
//%
-//%+ (instancetype)dictionaryWith##VNAME$u##:(VALUE_TYPE)##VNAME
+//%+ (instancetype)dictionaryWith##VNAME##:(VALUE_TYPE)##VNAME_VAR
//% ##VNAME$S## forKey:(KEY_TYPE##KisP$S##KisP)key {
-//% // Cast is needed so the compiler knows what class we are invoking initWith##VNAME$u##s:forKeys:count:
+//% // Cast is needed so the compiler knows what class we are invoking initWith##VNAME##s:forKeys:count:
//% // on to get the type correct.
-//% return [[(GPB##KEY_NAME##VALUE_NAME##Dictionary*)[self alloc] initWith##VNAME$u##s:&##VNAME
+//% return [[(GPB##KEY_NAME##VALUE_NAME##Dictionary*)[self alloc] initWith##VNAME##s:&##VNAME_VAR
//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## forKeys:&key
//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## count:1] autorelease];
//%}
//%
-//%+ (instancetype)dictionaryWith##VNAME$u##s:(const VALUE_TYPE [])##VNAME##s
+//%+ (instancetype)dictionaryWith##VNAME##s:(const VALUE_TYPE [])##VNAME_VAR##s
//% ##VNAME$S## forKeys:(const KEY_TYPE##KisP$S##KisP [])keys
//% ##VNAME$S## count:(NSUInteger)count {
-//% // Cast is needed so the compiler knows what class we are invoking initWith##VNAME$u##s:forKeys:count:
+//% // Cast is needed so the compiler knows what class we are invoking initWith##VNAME##s:forKeys:count:
//% // on to get the type correct.
-//% return [[(GPB##KEY_NAME##VALUE_NAME##Dictionary*)[self alloc] initWith##VNAME$u##s:##VNAME##s
+//% return [[(GPB##KEY_NAME##VALUE_NAME##Dictionary*)[self alloc] initWith##VNAME##s:##VNAME_VAR##s
//% KEY_NAME$S VALUE_NAME$S forKeys:keys
//% KEY_NAME$S VALUE_NAME$S count:count] autorelease];
//%}
@@ -615,18 +624,18 @@ void GPBDictionaryReadEntry(id mapDictionary,
//%}
//%
//%- (instancetype)init {
-//% return [self initWith##VNAME$u##s:NULL forKeys:NULL count:0];
+//% return [self initWith##VNAME##s:NULL forKeys:NULL count:0];
//%}
//%
-//%- (instancetype)initWith##VNAME$u##s:(const VALUE_TYPE [])##VNAME##s
+//%- (instancetype)initWith##VNAME##s:(const VALUE_TYPE [])##VNAME_VAR##s
//% ##VNAME$S## forKeys:(const KEY_TYPE##KisP$S##KisP [])keys
//% ##VNAME$S## count:(NSUInteger)count {
//% self = [super init];
//% if (self) {
//% _dictionary = [[NSMutableDictionary alloc] init];
-//% if (count && VNAME##s && keys) {
+//% if (count && VNAME_VAR##s && keys) {
//% for (NSUInteger i = 0; i < count; ++i) {
-//%DICTIONARY_VALIDATE_VALUE_##VHELPER(VNAME##s[i], ______)##DICTIONARY_VALIDATE_KEY_##KHELPER(keys[i], ______) [_dictionary setObject:WRAPPED##VHELPER(VNAME##s[i]) forKey:WRAPPED##KHELPER(keys[i])];
+//%DICTIONARY_VALIDATE_VALUE_##VHELPER(VNAME_VAR##s[i], ______)##DICTIONARY_VALIDATE_KEY_##KHELPER(keys[i], ______) [_dictionary setObject:WRAPPED##VHELPER(VNAME_VAR##s[i]) forKey:WRAPPED##KHELPER(keys[i])];
//% }
//% }
//% }
@@ -634,7 +643,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
//%}
//%
//%- (instancetype)initWithDictionary:(GPB##KEY_NAME##VALUE_NAME##Dictionary *)dictionary {
-//% self = [self initWith##VNAME$u##s:NULL forKeys:NULL count:0];
+//% self = [self initWith##VNAME##s:NULL forKeys:NULL count:0];
//% if (self) {
//% if (dictionary) {
//% [_dictionary addEntriesFromDictionary:dictionary->_dictionary];
@@ -645,14 +654,14 @@ void GPBDictionaryReadEntry(id mapDictionary,
//%
//%- (instancetype)initWithCapacity:(NSUInteger)numItems {
//% #pragma unused(numItems)
-//% return [self initWith##VNAME$u##s:NULL forKeys:NULL count:0];
+//% return [self initWith##VNAME##s:NULL forKeys:NULL count:0];
//%}
//%
-//%DICTIONARY_IMMUTABLE_CORE(KEY_NAME, KEY_TYPE, KisP, VALUE_NAME, VALUE_TYPE, KHELPER, VHELPER, VNAME, )
+//%DICTIONARY_IMMUTABLE_CORE(KEY_NAME, KEY_TYPE, KisP, VALUE_NAME, VALUE_TYPE, KHELPER, VHELPER, VNAME, VNAME_VAR, )
//%
//%VALUE_FOR_KEY_##VHELPER(KEY_TYPE##KisP$S##KisP, VALUE_NAME, VALUE_TYPE, KHELPER)
//%
-//%DICTIONARY_MUTABLE_CORE(KEY_NAME, KEY_TYPE, KisP, VALUE_NAME, VALUE_TYPE, KHELPER, VHELPER, VNAME, )
+//%DICTIONARY_MUTABLE_CORE(KEY_NAME, KEY_TYPE, KisP, VALUE_NAME, VALUE_TYPE, KHELPER, VHELPER, VNAME, VNAME_VAR, )
//%
//%@end
//%
@@ -762,9 +771,9 @@ void GPBDictionaryReadEntry(id mapDictionary,
//% return [self initWithValidationFunction:func rawValues:NULL forKeys:NULL count:0];
//%}
//%
-//%DICTIONARY_IMMUTABLE_CORE(KEY_NAME, KEY_TYPE, KisP, VALUE_NAME, VALUE_TYPE, KHELPER, VHELPER, value, Raw)
+//%DICTIONARY_IMMUTABLE_CORE(KEY_NAME, KEY_TYPE, KisP, VALUE_NAME, VALUE_TYPE, KHELPER, VHELPER, Value, value, Raw)
//%
-//%- (BOOL)valueForKey:(KEY_TYPE##KisP$S##KisP)key value:(VALUE_TYPE *)value {
+//%- (BOOL)getEnum:(VALUE_TYPE *)value forKey:(KEY_TYPE##KisP$S##KisP)key {
//% NSNumber *wrapped = [_dictionary objectForKey:WRAPPED##KHELPER(key)];
//% if (wrapped && value) {
//% VALUE_TYPE result = UNWRAP##VALUE_NAME(wrapped);
@@ -776,7 +785,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
//% return (wrapped != NULL);
//%}
//%
-//%- (BOOL)valueForKey:(KEY_TYPE##KisP$S##KisP)key rawValue:(VALUE_TYPE *)rawValue {
+//%- (BOOL)getRawValue:(VALUE_TYPE *)rawValue forKey:(KEY_TYPE##KisP$S##KisP)key {
//% NSNumber *wrapped = [_dictionary objectForKey:WRAPPED##KHELPER(key)];
//% if (wrapped && rawValue) {
//% *rawValue = UNWRAP##VALUE_NAME(wrapped);
@@ -784,7 +793,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
//% return (wrapped != NULL);
//%}
//%
-//%- (void)enumerateKeysAndValuesUsingBlock:
+//%- (void)enumerateKeysAndEnumsUsingBlock:
//% (void (^)(KEY_TYPE KisP##key, VALUE_TYPE value, BOOL *stop))block {
//% GPBEnumValidationFunc func = _validationFunc;
//% [_dictionary enumerateKeysAndObjectsUsingBlock:^(ENUM_TYPE##KHELPER(KEY_TYPE)##aKey,
@@ -798,9 +807,9 @@ void GPBDictionaryReadEntry(id mapDictionary,
//% }];
//%}
//%
-//%DICTIONARY_MUTABLE_CORE(KEY_NAME, KEY_TYPE, KisP, VALUE_NAME, VALUE_TYPE, KHELPER, VHELPER, value, Raw)
+//%DICTIONARY_MUTABLE_CORE2(KEY_NAME, KEY_TYPE, KisP, VALUE_NAME, VALUE_TYPE, KHELPER, VHELPER, Value, Enum, value, Raw)
//%
-//%- (void)setValue:(VALUE_TYPE)value forKey:(KEY_TYPE##KisP$S##KisP)key {
+//%- (void)setEnum:(VALUE_TYPE)value forKey:(KEY_TYPE##KisP$S##KisP)key {
//%DICTIONARY_VALIDATE_KEY_##KHELPER(key, ) if (!_validationFunc(value)) {
//% [NSException raise:NSInvalidArgumentException
//% format:@"GPB##KEY_NAME##VALUE_NAME##Dictionary: Attempt to set an unknown enum value (%d)",
@@ -816,7 +825,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
//%@end
//%
-//%PDDM-DEFINE DICTIONARY_IMMUTABLE_CORE(KEY_NAME, KEY_TYPE, KisP, VALUE_NAME, VALUE_TYPE, KHELPER, VHELPER, VNAME, ACCESSOR_NAME)
+//%PDDM-DEFINE DICTIONARY_IMMUTABLE_CORE(KEY_NAME, KEY_TYPE, KisP, VALUE_NAME, VALUE_TYPE, KHELPER, VHELPER, VNAME, VNAME_VAR, ACCESSOR_NAME)
//%- (void)dealloc {
//% NSAssert(!_autocreator,
//% @"%@: Autocreator must be cleared before release, autocreator: %@",
@@ -829,14 +838,15 @@ void GPBDictionaryReadEntry(id mapDictionary,
//% return [[GPB##KEY_NAME##VALUE_NAME##Dictionary allocWithZone:zone] initWithDictionary:self];
//%}
//%
-//%- (BOOL)isEqual:(GPB##KEY_NAME##VALUE_NAME##Dictionary *)other {
+//%- (BOOL)isEqual:(id)other {
//% if (self == other) {
//% return YES;
//% }
//% if (![other isKindOfClass:[GPB##KEY_NAME##VALUE_NAME##Dictionary class]]) {
//% return NO;
//% }
-//% return [_dictionary isEqual:other->_dictionary];
+//% GPB##KEY_NAME##VALUE_NAME##Dictionary *otherDictionary = other;
+//% return [_dictionary isEqual:otherDictionary->_dictionary];
//%}
//%
//%- (NSUInteger)hash {
@@ -851,12 +861,12 @@ void GPBDictionaryReadEntry(id mapDictionary,
//% return _dictionary.count;
//%}
//%
-//%- (void)enumerateKeysAnd##ACCESSOR_NAME##VNAME$u##sUsingBlock:
-//% (void (^)(KEY_TYPE KisP##key, VALUE_TYPE VNAME, BOOL *stop))block {
+//%- (void)enumerateKeysAnd##ACCESSOR_NAME##VNAME##sUsingBlock:
+//% (void (^)(KEY_TYPE KisP##key, VALUE_TYPE VNAME_VAR, BOOL *stop))block {
//% [_dictionary enumerateKeysAndObjectsUsingBlock:^(ENUM_TYPE##KHELPER(KEY_TYPE)##aKey,
-//% ENUM_TYPE##VHELPER(VALUE_TYPE)##a##VNAME$u,
+//% ENUM_TYPE##VHELPER(VALUE_TYPE)##a##VNAME_VAR$u,
//% BOOL *stop) {
-//% block(UNWRAP##KEY_NAME(aKey), UNWRAP##VALUE_NAME(a##VNAME$u), stop);
+//% block(UNWRAP##KEY_NAME(aKey), UNWRAP##VALUE_NAME(a##VNAME_VAR$u), stop);
//% }];
//%}
//%
@@ -870,11 +880,11 @@ void GPBDictionaryReadEntry(id mapDictionary,
//% GPBDataType keyDataType = field.mapKeyDataType;
//% __block size_t result = 0;
//% [_dictionary enumerateKeysAndObjectsUsingBlock:^(ENUM_TYPE##KHELPER(KEY_TYPE)##aKey,
-//% ENUM_TYPE##VHELPER(VALUE_TYPE)##a##VNAME$u##,
+//% ENUM_TYPE##VHELPER(VALUE_TYPE)##a##VNAME_VAR$u##,
//% BOOL *stop) {
//% #pragma unused(stop)
//% size_t msgSize = ComputeDict##KEY_NAME##FieldSize(UNWRAP##KEY_NAME(aKey), kMapKeyFieldNumber, keyDataType);
-//% msgSize += ComputeDict##VALUE_NAME##FieldSize(UNWRAP##VALUE_NAME(a##VNAME$u), kMapValueFieldNumber, valueDataType);
+//% msgSize += ComputeDict##VALUE_NAME##FieldSize(UNWRAP##VALUE_NAME(a##VNAME_VAR$u), kMapValueFieldNumber, valueDataType);
//% result += GPBComputeRawVarint32SizeForInteger(msgSize) + msgSize;
//% }];
//% size_t tagSize = GPBComputeWireFormatTagSize(GPBFieldNumber(field), GPBDataTypeMessage);
@@ -888,18 +898,18 @@ void GPBDictionaryReadEntry(id mapDictionary,
//% GPBDataType keyDataType = field.mapKeyDataType;
//% uint32_t tag = GPBWireFormatMakeTag(GPBFieldNumber(field), GPBWireFormatLengthDelimited);
//% [_dictionary enumerateKeysAndObjectsUsingBlock:^(ENUM_TYPE##KHELPER(KEY_TYPE)##aKey,
-//% ENUM_TYPE##VHELPER(VALUE_TYPE)##a##VNAME$u,
+//% ENUM_TYPE##VHELPER(VALUE_TYPE)##a##VNAME_VAR$u,
//% BOOL *stop) {
//% #pragma unused(stop)
//% // Write the tag.
//% [outputStream writeInt32NoTag:tag];
//% // Write the size of the message.
//% size_t msgSize = ComputeDict##KEY_NAME##FieldSize(UNWRAP##KEY_NAME(aKey), kMapKeyFieldNumber, keyDataType);
-//% msgSize += ComputeDict##VALUE_NAME##FieldSize(UNWRAP##VALUE_NAME(a##VNAME$u), kMapValueFieldNumber, valueDataType);
+//% msgSize += ComputeDict##VALUE_NAME##FieldSize(UNWRAP##VALUE_NAME(a##VNAME_VAR$u), kMapValueFieldNumber, valueDataType);
//% [outputStream writeInt32NoTag:(int32_t)msgSize];
//% // Write the fields.
//% WriteDict##KEY_NAME##Field(outputStream, UNWRAP##KEY_NAME(aKey), kMapKeyFieldNumber, keyDataType);
-//% WriteDict##VALUE_NAME##Field(outputStream, UNWRAP##VALUE_NAME(a##VNAME$u), kMapValueFieldNumber, valueDataType);
+//% WriteDict##VALUE_NAME##Field(outputStream, UNWRAP##VALUE_NAME(a##VNAME_VAR$u), kMapValueFieldNumber, valueDataType);
//% }];
//%}
//%
@@ -909,12 +919,14 @@ void GPBDictionaryReadEntry(id mapDictionary,
//%}
//%
//%- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block {
-//% [self enumerateKeysAnd##ACCESSOR_NAME##VNAME$u##sUsingBlock:^(KEY_TYPE KisP##key, VALUE_TYPE VNAME, BOOL *stop) {
+//% [self enumerateKeysAnd##ACCESSOR_NAME##VNAME##sUsingBlock:^(KEY_TYPE KisP##key, VALUE_TYPE VNAME_VAR, BOOL *stop) {
//% #pragma unused(stop)
-//% block(TEXT_FORMAT_OBJ##KEY_NAME(key), TEXT_FORMAT_OBJ##VALUE_NAME(VNAME));
+//% block(TEXT_FORMAT_OBJ##KEY_NAME(key), TEXT_FORMAT_OBJ##VALUE_NAME(VNAME_VAR));
//% }];
//%}
-//%PDDM-DEFINE DICTIONARY_MUTABLE_CORE(KEY_NAME, KEY_TYPE, KisP, VALUE_NAME, VALUE_TYPE, KHELPER, VHELPER, VNAME, ACCESSOR_NAME)
+//%PDDM-DEFINE DICTIONARY_MUTABLE_CORE(KEY_NAME, KEY_TYPE, KisP, VALUE_NAME, VALUE_TYPE, KHELPER, VHELPER, VNAME, VNAME_VAR, ACCESSOR_NAME)
+//%DICTIONARY_MUTABLE_CORE2(KEY_NAME, KEY_TYPE, KisP, VALUE_NAME, VALUE_TYPE, KHELPER, VHELPER, VNAME, VNAME, VNAME_VAR, ACCESSOR_NAME)
+//%PDDM-DEFINE DICTIONARY_MUTABLE_CORE2(KEY_NAME, KEY_TYPE, KisP, VALUE_NAME, VALUE_TYPE, KHELPER, VHELPER, VNAME, VNAME_REMOVE, VNAME_VAR, ACCESSOR_NAME)
//%- (void)add##ACCESSOR_NAME##EntriesFromDictionary:(GPB##KEY_NAME##VALUE_NAME##Dictionary *)otherDictionary {
//% if (otherDictionary) {
//% [_dictionary addEntriesFromDictionary:otherDictionary->_dictionary];
@@ -924,14 +936,14 @@ void GPBDictionaryReadEntry(id mapDictionary,
//% }
//%}
//%
-//%- (void)set##ACCESSOR_NAME##VNAME$u##:(VALUE_TYPE)VNAME forKey:(KEY_TYPE##KisP$S##KisP)key {
-//%DICTIONARY_VALIDATE_VALUE_##VHELPER(VNAME, )##DICTIONARY_VALIDATE_KEY_##KHELPER(key, ) [_dictionary setObject:WRAPPED##VHELPER(VNAME) forKey:WRAPPED##KHELPER(key)];
+//%- (void)set##ACCESSOR_NAME##VNAME##:(VALUE_TYPE)VNAME_VAR forKey:(KEY_TYPE##KisP$S##KisP)key {
+//%DICTIONARY_VALIDATE_VALUE_##VHELPER(VNAME_VAR, )##DICTIONARY_VALIDATE_KEY_##KHELPER(key, ) [_dictionary setObject:WRAPPED##VHELPER(VNAME_VAR) forKey:WRAPPED##KHELPER(key)];
//% if (_autocreator) {
//% GPBAutocreatedDictionaryModified(_autocreator, self);
//% }
//%}
//%
-//%- (void)remove##VNAME$u##ForKey:(KEY_TYPE##KisP$S##KisP)aKey {
+//%- (void)remove##VNAME_REMOVE##ForKey:(KEY_TYPE##KisP$S##KisP)aKey {
//% [_dictionary removeObjectForKey:WRAPPED##KHELPER(aKey)];
//%}
//%
@@ -944,11 +956,11 @@ void GPBDictionaryReadEntry(id mapDictionary,
//
//%PDDM-DEFINE DICTIONARY_BOOL_KEY_TO_POD_IMPL(VALUE_NAME, VALUE_TYPE)
-//%DICTIONARY_BOOL_KEY_TO_VALUE_IMPL(VALUE_NAME, VALUE_TYPE, POD, value)
+//%DICTIONARY_BOOL_KEY_TO_VALUE_IMPL(VALUE_NAME, VALUE_TYPE, POD, VALUE_NAME, value)
//%PDDM-DEFINE DICTIONARY_BOOL_KEY_TO_OBJECT_IMPL(VALUE_NAME, VALUE_TYPE)
-//%DICTIONARY_BOOL_KEY_TO_VALUE_IMPL(VALUE_NAME, VALUE_TYPE, OBJECT, object)
+//%DICTIONARY_BOOL_KEY_TO_VALUE_IMPL(VALUE_NAME, VALUE_TYPE, OBJECT, Object, object)
-//%PDDM-DEFINE DICTIONARY_BOOL_KEY_TO_VALUE_IMPL(VALUE_NAME, VALUE_TYPE, HELPER, VNAME)
+//%PDDM-DEFINE DICTIONARY_BOOL_KEY_TO_VALUE_IMPL(VALUE_NAME, VALUE_TYPE, HELPER, VNAME, VNAME_VAR)
//%#pragma mark - Bool -> VALUE_NAME
//%
//%@implementation GPBBool##VALUE_NAME##Dictionary {
@@ -957,24 +969,24 @@ void GPBDictionaryReadEntry(id mapDictionary,
//%BOOL_DICT_HAS_STORAGE_##HELPER()}
//%
//%+ (instancetype)dictionary {
-//% return [[[self alloc] initWith##VNAME$u##s:NULL forKeys:NULL count:0] autorelease];
+//% return [[[self alloc] initWith##VNAME##s:NULL forKeys:NULL count:0] autorelease];
//%}
//%
-//%+ (instancetype)dictionaryWith##VNAME$u##:(VALUE_TYPE)VNAME
+//%+ (instancetype)dictionaryWith##VNAME##:(VALUE_TYPE)VNAME_VAR
//% ##VNAME$S## forKey:(BOOL)key {
-//% // Cast is needed so the compiler knows what class we are invoking initWith##VNAME$u##s:forKeys:count:
+//% // Cast is needed so the compiler knows what class we are invoking initWith##VNAME##s:forKeys:count:
//% // on to get the type correct.
-//% return [[(GPBBool##VALUE_NAME##Dictionary*)[self alloc] initWith##VNAME$u##s:&##VNAME
+//% return [[(GPBBool##VALUE_NAME##Dictionary*)[self alloc] initWith##VNAME##s:&##VNAME_VAR
//% VALUE_NAME$S ##VNAME$S## forKeys:&key
//% VALUE_NAME$S ##VNAME$S## count:1] autorelease];
//%}
//%
-//%+ (instancetype)dictionaryWith##VNAME$u##s:(const VALUE_TYPE [])##VNAME##s
+//%+ (instancetype)dictionaryWith##VNAME##s:(const VALUE_TYPE [])##VNAME_VAR##s
//% ##VNAME$S## forKeys:(const BOOL [])keys
//% ##VNAME$S## count:(NSUInteger)count {
-//% // Cast is needed so the compiler knows what class we are invoking initWith##VNAME$u##s:forKeys:count:
+//% // Cast is needed so the compiler knows what class we are invoking initWith##VNAME##s:forKeys:count:
//% // on to get the type correct.
-//% return [[(GPBBool##VALUE_NAME##Dictionary*)[self alloc] initWith##VNAME$u##s:##VNAME##s
+//% return [[(GPBBool##VALUE_NAME##Dictionary*)[self alloc] initWith##VNAME##s:##VNAME_VAR##s
//% VALUE_NAME$S ##VNAME$S## forKeys:keys
//% VALUE_NAME$S ##VNAME$S## count:count] autorelease];
//%}
@@ -990,14 +1002,14 @@ void GPBDictionaryReadEntry(id mapDictionary,
//%}
//%
//%- (instancetype)init {
-//% return [self initWith##VNAME$u##s:NULL forKeys:NULL count:0];
+//% return [self initWith##VNAME##s:NULL forKeys:NULL count:0];
//%}
//%
//%BOOL_DICT_INITS_##HELPER(VALUE_NAME, VALUE_TYPE)
//%
//%- (instancetype)initWithCapacity:(NSUInteger)numItems {
//% #pragma unused(numItems)
-//% return [self initWith##VNAME$u##s:NULL forKeys:NULL count:0];
+//% return [self initWith##VNAME##s:NULL forKeys:NULL count:0];
//%}
//%
//%BOOL_DICT_DEALLOC##HELPER()
@@ -1006,19 +1018,20 @@ void GPBDictionaryReadEntry(id mapDictionary,
//% return [[GPBBool##VALUE_NAME##Dictionary allocWithZone:zone] initWithDictionary:self];
//%}
//%
-//%- (BOOL)isEqual:(GPBBool##VALUE_NAME##Dictionary *)other {
+//%- (BOOL)isEqual:(id)other {
//% if (self == other) {
//% return YES;
//% }
//% if (![other isKindOfClass:[GPBBool##VALUE_NAME##Dictionary class]]) {
//% return NO;
//% }
-//% if ((BOOL_DICT_W_HAS##HELPER(0, ) != BOOL_DICT_W_HAS##HELPER(0, other->)) ||
-//% (BOOL_DICT_W_HAS##HELPER(1, ) != BOOL_DICT_W_HAS##HELPER(1, other->))) {
+//% GPBBool##VALUE_NAME##Dictionary *otherDictionary = other;
+//% if ((BOOL_DICT_W_HAS##HELPER(0, ) != BOOL_DICT_W_HAS##HELPER(0, otherDictionary->)) ||
+//% (BOOL_DICT_W_HAS##HELPER(1, ) != BOOL_DICT_W_HAS##HELPER(1, otherDictionary->))) {
//% return NO;
//% }
-//% if ((BOOL_DICT_W_HAS##HELPER(0, ) && (NEQ_##HELPER(_values[0], other->_values[0]))) ||
-//% (BOOL_DICT_W_HAS##HELPER(1, ) && (NEQ_##HELPER(_values[1], other->_values[1])))) {
+//% if ((BOOL_DICT_W_HAS##HELPER(0, ) && (NEQ_##HELPER(_values[0], otherDictionary->_values[0]))) ||
+//% (BOOL_DICT_W_HAS##HELPER(1, ) && (NEQ_##HELPER(_values[1], otherDictionary->_values[1])))) {
//% return NO;
//% }
//% return YES;
@@ -1044,7 +1057,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
//% return (BOOL_DICT_W_HAS##HELPER(0, ) ? 1 : 0) + (BOOL_DICT_W_HAS##HELPER(1, ) ? 1 : 0);
//%}
//%
-//%BOOL_VALUE_FOR_KEY_##HELPER(VALUE_TYPE)
+//%BOOL_VALUE_FOR_KEY_##HELPER(VALUE_NAME, VALUE_TYPE)
//%
//%BOOL_SET_GPBVALUE_FOR_KEY_##HELPER(VALUE_NAME, VALUE_TYPE, VisP)
//%
@@ -1057,8 +1070,8 @@ void GPBDictionaryReadEntry(id mapDictionary,
//% }
//%}
//%
-//%- (void)enumerateKeysAnd##VNAME$u##sUsingBlock:
-//% (void (^)(BOOL key, VALUE_TYPE VNAME, BOOL *stop))block {
+//%- (void)enumerateKeysAnd##VNAME##sUsingBlock:
+//% (void (^)(BOOL key, VALUE_TYPE VNAME_VAR, BOOL *stop))block {
//% BOOL stop = NO;
//% if (BOOL_DICT_HAS##HELPER(0, )) {
//% block(NO, _values[0], &stop);
@@ -1115,7 +1128,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
//
//%PDDM-DEFINE VALUE_FOR_KEY_POD(KEY_TYPE, VALUE_NAME, VALUE_TYPE, KHELPER)
-//%- (BOOL)valueForKey:(KEY_TYPE)key value:(VALUE_TYPE *)value {
+//%- (BOOL)get##VALUE_NAME##:(nullable VALUE_TYPE *)value forKey:(KEY_TYPE)key {
//% NSNumber *wrapped = [_dictionary objectForKey:WRAPPED##KHELPER(key)];
//% if (wrapped && value) {
//% *value = UNWRAP##VALUE_NAME(wrapped);
@@ -1205,9 +1218,9 @@ void GPBDictionaryReadEntry(id mapDictionary,
//% BOOL _valueSet[2];
//%
//%PDDM-DEFINE BOOL_DICT_INITS_POD(VALUE_NAME, VALUE_TYPE)
-//%- (instancetype)initWithValues:(const VALUE_TYPE [])values
-//% forKeys:(const BOOL [])keys
-//% count:(NSUInteger)count {
+//%- (instancetype)initWith##VALUE_NAME##s:(const VALUE_TYPE [])values
+//% ##VALUE_NAME$S## forKeys:(const BOOL [])keys
+//% ##VALUE_NAME$S## count:(NSUInteger)count {
//% self = [super init];
//% if (self) {
//% for (NSUInteger i = 0; i < count; ++i) {
@@ -1220,7 +1233,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
//%}
//%
//%- (instancetype)initWithDictionary:(GPBBool##VALUE_NAME##Dictionary *)dictionary {
-//% self = [self initWithValues:NULL forKeys:NULL count:0];
+//% self = [self initWith##VALUE_NAME##s:NULL forKeys:NULL count:0];
//% if (self) {
//% if (dictionary) {
//% for (int i = 0; i < 2; ++i) {
@@ -1246,8 +1259,8 @@ void GPBDictionaryReadEntry(id mapDictionary,
//%BOOL_DICT_HASPOD(IDX, REF)
//%PDDM-DEFINE BOOL_DICT_HASPOD(IDX, REF)
//%REF##_valueSet[IDX]
-//%PDDM-DEFINE BOOL_VALUE_FOR_KEY_POD(VALUE_TYPE)
-//%- (BOOL)valueForKey:(BOOL)key value:(VALUE_TYPE *)value {
+//%PDDM-DEFINE BOOL_VALUE_FOR_KEY_POD(VALUE_NAME, VALUE_TYPE)
+//%- (BOOL)get##VALUE_NAME##:(VALUE_TYPE *)value forKey:(BOOL)key {
//% int idx = (key ? 1 : 0);
//% if (_valueSet[idx]) {
//% if (value) {
@@ -1279,7 +1292,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
//% }
//%}
//%
-//%- (void)setValue:(VALUE_TYPE)value forKey:(BOOL)key {
+//%- (void)set##VALUE_NAME:(VALUE_TYPE)value forKey:(BOOL)key {
//% int idx = (key ? 1 : 0);
//% _values[idx] = value;
//% _valueSet[idx] = YES;
@@ -1288,7 +1301,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
//% }
//%}
//%
-//%- (void)removeValueForKey:(BOOL)aKey {
+//%- (void)remove##VALUE_NAME##ForKey:(BOOL)aKey {
//% _valueSet[aKey ? 1 : 0] = NO;
//%}
//%
@@ -1449,7 +1462,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
//%(BOOL_DICT_HASOBJECT(IDX, REF))
//%PDDM-DEFINE BOOL_DICT_HASOBJECT(IDX, REF)
//%REF##_values[IDX] != nil
-//%PDDM-DEFINE BOOL_VALUE_FOR_KEY_OBJECT(VALUE_TYPE)
+//%PDDM-DEFINE BOOL_VALUE_FOR_KEY_OBJECT(VALUE_NAME, VALUE_TYPE)
//%- (VALUE_TYPE)objectForKey:(BOOL)key {
//% return _values[key ? 1 : 0];
//%}
@@ -1516,24 +1529,24 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
+ (instancetype)dictionary {
- return [[[self alloc] initWithValues:NULL forKeys:NULL count:0] autorelease];
+ return [[[self alloc] initWithUInt32s:NULL forKeys:NULL count:0] autorelease];
}
-+ (instancetype)dictionaryWithValue:(uint32_t)value
- forKey:(uint32_t)key {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithUInt32:(uint32_t)value
+ forKey:(uint32_t)key {
+ // Cast is needed so the compiler knows what class we are invoking initWithUInt32s:forKeys:count:
// on to get the type correct.
- return [[(GPBUInt32UInt32Dictionary*)[self alloc] initWithValues:&value
- forKeys:&key
- count:1] autorelease];
+ return [[(GPBUInt32UInt32Dictionary*)[self alloc] initWithUInt32s:&value
+ forKeys:&key
+ count:1] autorelease];
}
-+ (instancetype)dictionaryWithValues:(const uint32_t [])values
- forKeys:(const uint32_t [])keys
- count:(NSUInteger)count {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithUInt32s:(const uint32_t [])values
+ forKeys:(const uint32_t [])keys
+ count:(NSUInteger)count {
+ // Cast is needed so the compiler knows what class we are invoking initWithUInt32s:forKeys:count:
// on to get the type correct.
- return [[(GPBUInt32UInt32Dictionary*)[self alloc] initWithValues:values
+ return [[(GPBUInt32UInt32Dictionary*)[self alloc] initWithUInt32s:values
forKeys:keys
count:count] autorelease];
}
@@ -1549,12 +1562,12 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)init {
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithUInt32s:NULL forKeys:NULL count:0];
}
-- (instancetype)initWithValues:(const uint32_t [])values
- forKeys:(const uint32_t [])keys
- count:(NSUInteger)count {
+- (instancetype)initWithUInt32s:(const uint32_t [])values
+ forKeys:(const uint32_t [])keys
+ count:(NSUInteger)count {
self = [super init];
if (self) {
_dictionary = [[NSMutableDictionary alloc] init];
@@ -1568,7 +1581,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)initWithDictionary:(GPBUInt32UInt32Dictionary *)dictionary {
- self = [self initWithValues:NULL forKeys:NULL count:0];
+ self = [self initWithUInt32s:NULL forKeys:NULL count:0];
if (self) {
if (dictionary) {
[_dictionary addEntriesFromDictionary:dictionary->_dictionary];
@@ -1579,7 +1592,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
- (instancetype)initWithCapacity:(NSUInteger)numItems {
#pragma unused(numItems)
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithUInt32s:NULL forKeys:NULL count:0];
}
- (void)dealloc {
@@ -1594,14 +1607,15 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBUInt32UInt32Dictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBUInt32UInt32Dictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBUInt32UInt32Dictionary class]]) {
return NO;
}
- return [_dictionary isEqual:other->_dictionary];
+ GPBUInt32UInt32Dictionary *otherDictionary = other;
+ return [_dictionary isEqual:otherDictionary->_dictionary];
}
- (NSUInteger)hash {
@@ -1616,7 +1630,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return _dictionary.count;
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndUInt32sUsingBlock:
(void (^)(uint32_t key, uint32_t value, BOOL *stop))block {
[_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
NSNumber *aValue,
@@ -1674,13 +1688,13 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block {
- [self enumerateKeysAndValuesUsingBlock:^(uint32_t key, uint32_t value, BOOL *stop) {
+ [self enumerateKeysAndUInt32sUsingBlock:^(uint32_t key, uint32_t value, BOOL *stop) {
#pragma unused(stop)
block([NSString stringWithFormat:@"%u", key], [NSString stringWithFormat:@"%u", value]);
}];
}
-- (BOOL)valueForKey:(uint32_t)key value:(uint32_t *)value {
+- (BOOL)getUInt32:(nullable uint32_t *)value forKey:(uint32_t)key {
NSNumber *wrapped = [_dictionary objectForKey:@(key)];
if (wrapped && value) {
*value = [wrapped unsignedIntValue];
@@ -1697,14 +1711,14 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)setValue:(uint32_t)value forKey:(uint32_t)key {
+- (void)setUInt32:(uint32_t)value forKey:(uint32_t)key {
[_dictionary setObject:@(value) forKey:@(key)];
if (_autocreator) {
GPBAutocreatedDictionaryModified(_autocreator, self);
}
}
-- (void)removeValueForKey:(uint32_t)aKey {
+- (void)removeUInt32ForKey:(uint32_t)aKey {
[_dictionary removeObjectForKey:@(aKey)];
}
@@ -1722,24 +1736,24 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
+ (instancetype)dictionary {
- return [[[self alloc] initWithValues:NULL forKeys:NULL count:0] autorelease];
+ return [[[self alloc] initWithInt32s:NULL forKeys:NULL count:0] autorelease];
}
-+ (instancetype)dictionaryWithValue:(int32_t)value
++ (instancetype)dictionaryWithInt32:(int32_t)value
forKey:(uint32_t)key {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
+ // Cast is needed so the compiler knows what class we are invoking initWithInt32s:forKeys:count:
// on to get the type correct.
- return [[(GPBUInt32Int32Dictionary*)[self alloc] initWithValues:&value
+ return [[(GPBUInt32Int32Dictionary*)[self alloc] initWithInt32s:&value
forKeys:&key
count:1] autorelease];
}
-+ (instancetype)dictionaryWithValues:(const int32_t [])values
++ (instancetype)dictionaryWithInt32s:(const int32_t [])values
forKeys:(const uint32_t [])keys
count:(NSUInteger)count {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
+ // Cast is needed so the compiler knows what class we are invoking initWithInt32s:forKeys:count:
// on to get the type correct.
- return [[(GPBUInt32Int32Dictionary*)[self alloc] initWithValues:values
+ return [[(GPBUInt32Int32Dictionary*)[self alloc] initWithInt32s:values
forKeys:keys
count:count] autorelease];
}
@@ -1755,10 +1769,10 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)init {
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithInt32s:NULL forKeys:NULL count:0];
}
-- (instancetype)initWithValues:(const int32_t [])values
+- (instancetype)initWithInt32s:(const int32_t [])values
forKeys:(const uint32_t [])keys
count:(NSUInteger)count {
self = [super init];
@@ -1774,7 +1788,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)initWithDictionary:(GPBUInt32Int32Dictionary *)dictionary {
- self = [self initWithValues:NULL forKeys:NULL count:0];
+ self = [self initWithInt32s:NULL forKeys:NULL count:0];
if (self) {
if (dictionary) {
[_dictionary addEntriesFromDictionary:dictionary->_dictionary];
@@ -1785,7 +1799,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
- (instancetype)initWithCapacity:(NSUInteger)numItems {
#pragma unused(numItems)
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithInt32s:NULL forKeys:NULL count:0];
}
- (void)dealloc {
@@ -1800,14 +1814,15 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBUInt32Int32Dictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBUInt32Int32Dictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBUInt32Int32Dictionary class]]) {
return NO;
}
- return [_dictionary isEqual:other->_dictionary];
+ GPBUInt32Int32Dictionary *otherDictionary = other;
+ return [_dictionary isEqual:otherDictionary->_dictionary];
}
- (NSUInteger)hash {
@@ -1822,7 +1837,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return _dictionary.count;
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndInt32sUsingBlock:
(void (^)(uint32_t key, int32_t value, BOOL *stop))block {
[_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
NSNumber *aValue,
@@ -1880,13 +1895,13 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block {
- [self enumerateKeysAndValuesUsingBlock:^(uint32_t key, int32_t value, BOOL *stop) {
+ [self enumerateKeysAndInt32sUsingBlock:^(uint32_t key, int32_t value, BOOL *stop) {
#pragma unused(stop)
block([NSString stringWithFormat:@"%u", key], [NSString stringWithFormat:@"%d", value]);
}];
}
-- (BOOL)valueForKey:(uint32_t)key value:(int32_t *)value {
+- (BOOL)getInt32:(nullable int32_t *)value forKey:(uint32_t)key {
NSNumber *wrapped = [_dictionary objectForKey:@(key)];
if (wrapped && value) {
*value = [wrapped intValue];
@@ -1903,14 +1918,14 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)setValue:(int32_t)value forKey:(uint32_t)key {
+- (void)setInt32:(int32_t)value forKey:(uint32_t)key {
[_dictionary setObject:@(value) forKey:@(key)];
if (_autocreator) {
GPBAutocreatedDictionaryModified(_autocreator, self);
}
}
-- (void)removeValueForKey:(uint32_t)aKey {
+- (void)removeInt32ForKey:(uint32_t)aKey {
[_dictionary removeObjectForKey:@(aKey)];
}
@@ -1928,24 +1943,24 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
+ (instancetype)dictionary {
- return [[[self alloc] initWithValues:NULL forKeys:NULL count:0] autorelease];
+ return [[[self alloc] initWithUInt64s:NULL forKeys:NULL count:0] autorelease];
}
-+ (instancetype)dictionaryWithValue:(uint64_t)value
- forKey:(uint32_t)key {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithUInt64:(uint64_t)value
+ forKey:(uint32_t)key {
+ // Cast is needed so the compiler knows what class we are invoking initWithUInt64s:forKeys:count:
// on to get the type correct.
- return [[(GPBUInt32UInt64Dictionary*)[self alloc] initWithValues:&value
- forKeys:&key
- count:1] autorelease];
+ return [[(GPBUInt32UInt64Dictionary*)[self alloc] initWithUInt64s:&value
+ forKeys:&key
+ count:1] autorelease];
}
-+ (instancetype)dictionaryWithValues:(const uint64_t [])values
- forKeys:(const uint32_t [])keys
- count:(NSUInteger)count {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithUInt64s:(const uint64_t [])values
+ forKeys:(const uint32_t [])keys
+ count:(NSUInteger)count {
+ // Cast is needed so the compiler knows what class we are invoking initWithUInt64s:forKeys:count:
// on to get the type correct.
- return [[(GPBUInt32UInt64Dictionary*)[self alloc] initWithValues:values
+ return [[(GPBUInt32UInt64Dictionary*)[self alloc] initWithUInt64s:values
forKeys:keys
count:count] autorelease];
}
@@ -1961,12 +1976,12 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)init {
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithUInt64s:NULL forKeys:NULL count:0];
}
-- (instancetype)initWithValues:(const uint64_t [])values
- forKeys:(const uint32_t [])keys
- count:(NSUInteger)count {
+- (instancetype)initWithUInt64s:(const uint64_t [])values
+ forKeys:(const uint32_t [])keys
+ count:(NSUInteger)count {
self = [super init];
if (self) {
_dictionary = [[NSMutableDictionary alloc] init];
@@ -1980,7 +1995,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)initWithDictionary:(GPBUInt32UInt64Dictionary *)dictionary {
- self = [self initWithValues:NULL forKeys:NULL count:0];
+ self = [self initWithUInt64s:NULL forKeys:NULL count:0];
if (self) {
if (dictionary) {
[_dictionary addEntriesFromDictionary:dictionary->_dictionary];
@@ -1991,7 +2006,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
- (instancetype)initWithCapacity:(NSUInteger)numItems {
#pragma unused(numItems)
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithUInt64s:NULL forKeys:NULL count:0];
}
- (void)dealloc {
@@ -2006,14 +2021,15 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBUInt32UInt64Dictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBUInt32UInt64Dictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBUInt32UInt64Dictionary class]]) {
return NO;
}
- return [_dictionary isEqual:other->_dictionary];
+ GPBUInt32UInt64Dictionary *otherDictionary = other;
+ return [_dictionary isEqual:otherDictionary->_dictionary];
}
- (NSUInteger)hash {
@@ -2028,7 +2044,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return _dictionary.count;
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndUInt64sUsingBlock:
(void (^)(uint32_t key, uint64_t value, BOOL *stop))block {
[_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
NSNumber *aValue,
@@ -2086,13 +2102,13 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block {
- [self enumerateKeysAndValuesUsingBlock:^(uint32_t key, uint64_t value, BOOL *stop) {
+ [self enumerateKeysAndUInt64sUsingBlock:^(uint32_t key, uint64_t value, BOOL *stop) {
#pragma unused(stop)
block([NSString stringWithFormat:@"%u", key], [NSString stringWithFormat:@"%llu", value]);
}];
}
-- (BOOL)valueForKey:(uint32_t)key value:(uint64_t *)value {
+- (BOOL)getUInt64:(nullable uint64_t *)value forKey:(uint32_t)key {
NSNumber *wrapped = [_dictionary objectForKey:@(key)];
if (wrapped && value) {
*value = [wrapped unsignedLongLongValue];
@@ -2109,14 +2125,14 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)setValue:(uint64_t)value forKey:(uint32_t)key {
+- (void)setUInt64:(uint64_t)value forKey:(uint32_t)key {
[_dictionary setObject:@(value) forKey:@(key)];
if (_autocreator) {
GPBAutocreatedDictionaryModified(_autocreator, self);
}
}
-- (void)removeValueForKey:(uint32_t)aKey {
+- (void)removeUInt64ForKey:(uint32_t)aKey {
[_dictionary removeObjectForKey:@(aKey)];
}
@@ -2134,24 +2150,24 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
+ (instancetype)dictionary {
- return [[[self alloc] initWithValues:NULL forKeys:NULL count:0] autorelease];
+ return [[[self alloc] initWithInt64s:NULL forKeys:NULL count:0] autorelease];
}
-+ (instancetype)dictionaryWithValue:(int64_t)value
++ (instancetype)dictionaryWithInt64:(int64_t)value
forKey:(uint32_t)key {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
+ // Cast is needed so the compiler knows what class we are invoking initWithInt64s:forKeys:count:
// on to get the type correct.
- return [[(GPBUInt32Int64Dictionary*)[self alloc] initWithValues:&value
+ return [[(GPBUInt32Int64Dictionary*)[self alloc] initWithInt64s:&value
forKeys:&key
count:1] autorelease];
}
-+ (instancetype)dictionaryWithValues:(const int64_t [])values
++ (instancetype)dictionaryWithInt64s:(const int64_t [])values
forKeys:(const uint32_t [])keys
count:(NSUInteger)count {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
+ // Cast is needed so the compiler knows what class we are invoking initWithInt64s:forKeys:count:
// on to get the type correct.
- return [[(GPBUInt32Int64Dictionary*)[self alloc] initWithValues:values
+ return [[(GPBUInt32Int64Dictionary*)[self alloc] initWithInt64s:values
forKeys:keys
count:count] autorelease];
}
@@ -2167,10 +2183,10 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)init {
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithInt64s:NULL forKeys:NULL count:0];
}
-- (instancetype)initWithValues:(const int64_t [])values
+- (instancetype)initWithInt64s:(const int64_t [])values
forKeys:(const uint32_t [])keys
count:(NSUInteger)count {
self = [super init];
@@ -2186,7 +2202,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)initWithDictionary:(GPBUInt32Int64Dictionary *)dictionary {
- self = [self initWithValues:NULL forKeys:NULL count:0];
+ self = [self initWithInt64s:NULL forKeys:NULL count:0];
if (self) {
if (dictionary) {
[_dictionary addEntriesFromDictionary:dictionary->_dictionary];
@@ -2197,7 +2213,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
- (instancetype)initWithCapacity:(NSUInteger)numItems {
#pragma unused(numItems)
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithInt64s:NULL forKeys:NULL count:0];
}
- (void)dealloc {
@@ -2212,14 +2228,15 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBUInt32Int64Dictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBUInt32Int64Dictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBUInt32Int64Dictionary class]]) {
return NO;
}
- return [_dictionary isEqual:other->_dictionary];
+ GPBUInt32Int64Dictionary *otherDictionary = other;
+ return [_dictionary isEqual:otherDictionary->_dictionary];
}
- (NSUInteger)hash {
@@ -2234,7 +2251,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return _dictionary.count;
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndInt64sUsingBlock:
(void (^)(uint32_t key, int64_t value, BOOL *stop))block {
[_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
NSNumber *aValue,
@@ -2292,13 +2309,13 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block {
- [self enumerateKeysAndValuesUsingBlock:^(uint32_t key, int64_t value, BOOL *stop) {
+ [self enumerateKeysAndInt64sUsingBlock:^(uint32_t key, int64_t value, BOOL *stop) {
#pragma unused(stop)
block([NSString stringWithFormat:@"%u", key], [NSString stringWithFormat:@"%lld", value]);
}];
}
-- (BOOL)valueForKey:(uint32_t)key value:(int64_t *)value {
+- (BOOL)getInt64:(nullable int64_t *)value forKey:(uint32_t)key {
NSNumber *wrapped = [_dictionary objectForKey:@(key)];
if (wrapped && value) {
*value = [wrapped longLongValue];
@@ -2315,14 +2332,14 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)setValue:(int64_t)value forKey:(uint32_t)key {
+- (void)setInt64:(int64_t)value forKey:(uint32_t)key {
[_dictionary setObject:@(value) forKey:@(key)];
if (_autocreator) {
GPBAutocreatedDictionaryModified(_autocreator, self);
}
}
-- (void)removeValueForKey:(uint32_t)aKey {
+- (void)removeInt64ForKey:(uint32_t)aKey {
[_dictionary removeObjectForKey:@(aKey)];
}
@@ -2340,24 +2357,24 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
+ (instancetype)dictionary {
- return [[[self alloc] initWithValues:NULL forKeys:NULL count:0] autorelease];
+ return [[[self alloc] initWithBools:NULL forKeys:NULL count:0] autorelease];
}
-+ (instancetype)dictionaryWithValue:(BOOL)value
- forKey:(uint32_t)key {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithBool:(BOOL)value
+ forKey:(uint32_t)key {
+ // Cast is needed so the compiler knows what class we are invoking initWithBools:forKeys:count:
// on to get the type correct.
- return [[(GPBUInt32BoolDictionary*)[self alloc] initWithValues:&value
- forKeys:&key
- count:1] autorelease];
+ return [[(GPBUInt32BoolDictionary*)[self alloc] initWithBools:&value
+ forKeys:&key
+ count:1] autorelease];
}
-+ (instancetype)dictionaryWithValues:(const BOOL [])values
- forKeys:(const uint32_t [])keys
- count:(NSUInteger)count {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithBools:(const BOOL [])values
+ forKeys:(const uint32_t [])keys
+ count:(NSUInteger)count {
+ // Cast is needed so the compiler knows what class we are invoking initWithBools:forKeys:count:
// on to get the type correct.
- return [[(GPBUInt32BoolDictionary*)[self alloc] initWithValues:values
+ return [[(GPBUInt32BoolDictionary*)[self alloc] initWithBools:values
forKeys:keys
count:count] autorelease];
}
@@ -2373,12 +2390,12 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)init {
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithBools:NULL forKeys:NULL count:0];
}
-- (instancetype)initWithValues:(const BOOL [])values
- forKeys:(const uint32_t [])keys
- count:(NSUInteger)count {
+- (instancetype)initWithBools:(const BOOL [])values
+ forKeys:(const uint32_t [])keys
+ count:(NSUInteger)count {
self = [super init];
if (self) {
_dictionary = [[NSMutableDictionary alloc] init];
@@ -2392,7 +2409,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)initWithDictionary:(GPBUInt32BoolDictionary *)dictionary {
- self = [self initWithValues:NULL forKeys:NULL count:0];
+ self = [self initWithBools:NULL forKeys:NULL count:0];
if (self) {
if (dictionary) {
[_dictionary addEntriesFromDictionary:dictionary->_dictionary];
@@ -2403,7 +2420,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
- (instancetype)initWithCapacity:(NSUInteger)numItems {
#pragma unused(numItems)
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithBools:NULL forKeys:NULL count:0];
}
- (void)dealloc {
@@ -2418,14 +2435,15 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBUInt32BoolDictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBUInt32BoolDictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBUInt32BoolDictionary class]]) {
return NO;
}
- return [_dictionary isEqual:other->_dictionary];
+ GPBUInt32BoolDictionary *otherDictionary = other;
+ return [_dictionary isEqual:otherDictionary->_dictionary];
}
- (NSUInteger)hash {
@@ -2440,7 +2458,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return _dictionary.count;
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndBoolsUsingBlock:
(void (^)(uint32_t key, BOOL value, BOOL *stop))block {
[_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
NSNumber *aValue,
@@ -2498,13 +2516,13 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block {
- [self enumerateKeysAndValuesUsingBlock:^(uint32_t key, BOOL value, BOOL *stop) {
+ [self enumerateKeysAndBoolsUsingBlock:^(uint32_t key, BOOL value, BOOL *stop) {
#pragma unused(stop)
block([NSString stringWithFormat:@"%u", key], (value ? @"true" : @"false"));
}];
}
-- (BOOL)valueForKey:(uint32_t)key value:(BOOL *)value {
+- (BOOL)getBool:(nullable BOOL *)value forKey:(uint32_t)key {
NSNumber *wrapped = [_dictionary objectForKey:@(key)];
if (wrapped && value) {
*value = [wrapped boolValue];
@@ -2521,14 +2539,14 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)setValue:(BOOL)value forKey:(uint32_t)key {
+- (void)setBool:(BOOL)value forKey:(uint32_t)key {
[_dictionary setObject:@(value) forKey:@(key)];
if (_autocreator) {
GPBAutocreatedDictionaryModified(_autocreator, self);
}
}
-- (void)removeValueForKey:(uint32_t)aKey {
+- (void)removeBoolForKey:(uint32_t)aKey {
[_dictionary removeObjectForKey:@(aKey)];
}
@@ -2546,24 +2564,24 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
+ (instancetype)dictionary {
- return [[[self alloc] initWithValues:NULL forKeys:NULL count:0] autorelease];
+ return [[[self alloc] initWithFloats:NULL forKeys:NULL count:0] autorelease];
}
-+ (instancetype)dictionaryWithValue:(float)value
++ (instancetype)dictionaryWithFloat:(float)value
forKey:(uint32_t)key {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
+ // Cast is needed so the compiler knows what class we are invoking initWithFloats:forKeys:count:
// on to get the type correct.
- return [[(GPBUInt32FloatDictionary*)[self alloc] initWithValues:&value
+ return [[(GPBUInt32FloatDictionary*)[self alloc] initWithFloats:&value
forKeys:&key
count:1] autorelease];
}
-+ (instancetype)dictionaryWithValues:(const float [])values
++ (instancetype)dictionaryWithFloats:(const float [])values
forKeys:(const uint32_t [])keys
count:(NSUInteger)count {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
+ // Cast is needed so the compiler knows what class we are invoking initWithFloats:forKeys:count:
// on to get the type correct.
- return [[(GPBUInt32FloatDictionary*)[self alloc] initWithValues:values
+ return [[(GPBUInt32FloatDictionary*)[self alloc] initWithFloats:values
forKeys:keys
count:count] autorelease];
}
@@ -2579,10 +2597,10 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)init {
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithFloats:NULL forKeys:NULL count:0];
}
-- (instancetype)initWithValues:(const float [])values
+- (instancetype)initWithFloats:(const float [])values
forKeys:(const uint32_t [])keys
count:(NSUInteger)count {
self = [super init];
@@ -2598,7 +2616,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)initWithDictionary:(GPBUInt32FloatDictionary *)dictionary {
- self = [self initWithValues:NULL forKeys:NULL count:0];
+ self = [self initWithFloats:NULL forKeys:NULL count:0];
if (self) {
if (dictionary) {
[_dictionary addEntriesFromDictionary:dictionary->_dictionary];
@@ -2609,7 +2627,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
- (instancetype)initWithCapacity:(NSUInteger)numItems {
#pragma unused(numItems)
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithFloats:NULL forKeys:NULL count:0];
}
- (void)dealloc {
@@ -2624,14 +2642,15 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBUInt32FloatDictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBUInt32FloatDictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBUInt32FloatDictionary class]]) {
return NO;
}
- return [_dictionary isEqual:other->_dictionary];
+ GPBUInt32FloatDictionary *otherDictionary = other;
+ return [_dictionary isEqual:otherDictionary->_dictionary];
}
- (NSUInteger)hash {
@@ -2646,7 +2665,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return _dictionary.count;
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndFloatsUsingBlock:
(void (^)(uint32_t key, float value, BOOL *stop))block {
[_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
NSNumber *aValue,
@@ -2704,13 +2723,13 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block {
- [self enumerateKeysAndValuesUsingBlock:^(uint32_t key, float value, BOOL *stop) {
+ [self enumerateKeysAndFloatsUsingBlock:^(uint32_t key, float value, BOOL *stop) {
#pragma unused(stop)
block([NSString stringWithFormat:@"%u", key], [NSString stringWithFormat:@"%.*g", FLT_DIG, value]);
}];
}
-- (BOOL)valueForKey:(uint32_t)key value:(float *)value {
+- (BOOL)getFloat:(nullable float *)value forKey:(uint32_t)key {
NSNumber *wrapped = [_dictionary objectForKey:@(key)];
if (wrapped && value) {
*value = [wrapped floatValue];
@@ -2727,14 +2746,14 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)setValue:(float)value forKey:(uint32_t)key {
+- (void)setFloat:(float)value forKey:(uint32_t)key {
[_dictionary setObject:@(value) forKey:@(key)];
if (_autocreator) {
GPBAutocreatedDictionaryModified(_autocreator, self);
}
}
-- (void)removeValueForKey:(uint32_t)aKey {
+- (void)removeFloatForKey:(uint32_t)aKey {
[_dictionary removeObjectForKey:@(aKey)];
}
@@ -2752,24 +2771,24 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
+ (instancetype)dictionary {
- return [[[self alloc] initWithValues:NULL forKeys:NULL count:0] autorelease];
+ return [[[self alloc] initWithDoubles:NULL forKeys:NULL count:0] autorelease];
}
-+ (instancetype)dictionaryWithValue:(double)value
- forKey:(uint32_t)key {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithDouble:(double)value
+ forKey:(uint32_t)key {
+ // Cast is needed so the compiler knows what class we are invoking initWithDoubles:forKeys:count:
// on to get the type correct.
- return [[(GPBUInt32DoubleDictionary*)[self alloc] initWithValues:&value
- forKeys:&key
- count:1] autorelease];
+ return [[(GPBUInt32DoubleDictionary*)[self alloc] initWithDoubles:&value
+ forKeys:&key
+ count:1] autorelease];
}
-+ (instancetype)dictionaryWithValues:(const double [])values
- forKeys:(const uint32_t [])keys
- count:(NSUInteger)count {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithDoubles:(const double [])values
+ forKeys:(const uint32_t [])keys
+ count:(NSUInteger)count {
+ // Cast is needed so the compiler knows what class we are invoking initWithDoubles:forKeys:count:
// on to get the type correct.
- return [[(GPBUInt32DoubleDictionary*)[self alloc] initWithValues:values
+ return [[(GPBUInt32DoubleDictionary*)[self alloc] initWithDoubles:values
forKeys:keys
count:count] autorelease];
}
@@ -2785,12 +2804,12 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)init {
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithDoubles:NULL forKeys:NULL count:0];
}
-- (instancetype)initWithValues:(const double [])values
- forKeys:(const uint32_t [])keys
- count:(NSUInteger)count {
+- (instancetype)initWithDoubles:(const double [])values
+ forKeys:(const uint32_t [])keys
+ count:(NSUInteger)count {
self = [super init];
if (self) {
_dictionary = [[NSMutableDictionary alloc] init];
@@ -2804,7 +2823,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)initWithDictionary:(GPBUInt32DoubleDictionary *)dictionary {
- self = [self initWithValues:NULL forKeys:NULL count:0];
+ self = [self initWithDoubles:NULL forKeys:NULL count:0];
if (self) {
if (dictionary) {
[_dictionary addEntriesFromDictionary:dictionary->_dictionary];
@@ -2815,7 +2834,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
- (instancetype)initWithCapacity:(NSUInteger)numItems {
#pragma unused(numItems)
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithDoubles:NULL forKeys:NULL count:0];
}
- (void)dealloc {
@@ -2830,14 +2849,15 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBUInt32DoubleDictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBUInt32DoubleDictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBUInt32DoubleDictionary class]]) {
return NO;
}
- return [_dictionary isEqual:other->_dictionary];
+ GPBUInt32DoubleDictionary *otherDictionary = other;
+ return [_dictionary isEqual:otherDictionary->_dictionary];
}
- (NSUInteger)hash {
@@ -2852,7 +2872,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return _dictionary.count;
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndDoublesUsingBlock:
(void (^)(uint32_t key, double value, BOOL *stop))block {
[_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
NSNumber *aValue,
@@ -2910,13 +2930,13 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block {
- [self enumerateKeysAndValuesUsingBlock:^(uint32_t key, double value, BOOL *stop) {
+ [self enumerateKeysAndDoublesUsingBlock:^(uint32_t key, double value, BOOL *stop) {
#pragma unused(stop)
block([NSString stringWithFormat:@"%u", key], [NSString stringWithFormat:@"%.*lg", DBL_DIG, value]);
}];
}
-- (BOOL)valueForKey:(uint32_t)key value:(double *)value {
+- (BOOL)getDouble:(nullable double *)value forKey:(uint32_t)key {
NSNumber *wrapped = [_dictionary objectForKey:@(key)];
if (wrapped && value) {
*value = [wrapped doubleValue];
@@ -2933,14 +2953,14 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)setValue:(double)value forKey:(uint32_t)key {
+- (void)setDouble:(double)value forKey:(uint32_t)key {
[_dictionary setObject:@(value) forKey:@(key)];
if (_autocreator) {
GPBAutocreatedDictionaryModified(_autocreator, self);
}
}
-- (void)removeValueForKey:(uint32_t)aKey {
+- (void)removeDoubleForKey:(uint32_t)aKey {
[_dictionary removeObjectForKey:@(aKey)];
}
@@ -3064,14 +3084,15 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBUInt32EnumDictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBUInt32EnumDictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBUInt32EnumDictionary class]]) {
return NO;
}
- return [_dictionary isEqual:other->_dictionary];
+ GPBUInt32EnumDictionary *otherDictionary = other;
+ return [_dictionary isEqual:otherDictionary->_dictionary];
}
- (NSUInteger)hash {
@@ -3162,7 +3183,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}];
}
-- (BOOL)valueForKey:(uint32_t)key value:(int32_t *)value {
+- (BOOL)getEnum:(int32_t *)value forKey:(uint32_t)key {
NSNumber *wrapped = [_dictionary objectForKey:@(key)];
if (wrapped && value) {
int32_t result = [wrapped intValue];
@@ -3174,7 +3195,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return (wrapped != NULL);
}
-- (BOOL)valueForKey:(uint32_t)key rawValue:(int32_t *)rawValue {
+- (BOOL)getRawValue:(int32_t *)rawValue forKey:(uint32_t)key {
NSNumber *wrapped = [_dictionary objectForKey:@(key)];
if (wrapped && rawValue) {
*rawValue = [wrapped intValue];
@@ -3182,7 +3203,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return (wrapped != NULL);
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndEnumsUsingBlock:
(void (^)(uint32_t key, int32_t value, BOOL *stop))block {
GPBEnumValidationFunc func = _validationFunc;
[_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
@@ -3212,7 +3233,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)removeValueForKey:(uint32_t)aKey {
+- (void)removeEnumForKey:(uint32_t)aKey {
[_dictionary removeObjectForKey:@(aKey)];
}
@@ -3220,7 +3241,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
[_dictionary removeAllObjects];
}
-- (void)setValue:(int32_t)value forKey:(uint32_t)key {
+- (void)setEnum:(int32_t)value forKey:(uint32_t)key {
if (!_validationFunc(value)) {
[NSException raise:NSInvalidArgumentException
format:@"GPBUInt32EnumDictionary: Attempt to set an unknown enum value (%d)",
@@ -3325,14 +3346,15 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBUInt32ObjectDictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBUInt32ObjectDictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBUInt32ObjectDictionary class]]) {
return NO;
}
- return [_dictionary isEqual:other->_dictionary];
+ GPBUInt32ObjectDictionary *otherDictionary = other;
+ return [_dictionary isEqual:otherDictionary->_dictionary];
}
- (NSUInteger)hash {
@@ -3480,24 +3502,24 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
+ (instancetype)dictionary {
- return [[[self alloc] initWithValues:NULL forKeys:NULL count:0] autorelease];
+ return [[[self alloc] initWithUInt32s:NULL forKeys:NULL count:0] autorelease];
}
-+ (instancetype)dictionaryWithValue:(uint32_t)value
- forKey:(int32_t)key {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithUInt32:(uint32_t)value
+ forKey:(int32_t)key {
+ // Cast is needed so the compiler knows what class we are invoking initWithUInt32s:forKeys:count:
// on to get the type correct.
- return [[(GPBInt32UInt32Dictionary*)[self alloc] initWithValues:&value
- forKeys:&key
- count:1] autorelease];
+ return [[(GPBInt32UInt32Dictionary*)[self alloc] initWithUInt32s:&value
+ forKeys:&key
+ count:1] autorelease];
}
-+ (instancetype)dictionaryWithValues:(const uint32_t [])values
- forKeys:(const int32_t [])keys
- count:(NSUInteger)count {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithUInt32s:(const uint32_t [])values
+ forKeys:(const int32_t [])keys
+ count:(NSUInteger)count {
+ // Cast is needed so the compiler knows what class we are invoking initWithUInt32s:forKeys:count:
// on to get the type correct.
- return [[(GPBInt32UInt32Dictionary*)[self alloc] initWithValues:values
+ return [[(GPBInt32UInt32Dictionary*)[self alloc] initWithUInt32s:values
forKeys:keys
count:count] autorelease];
}
@@ -3513,12 +3535,12 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)init {
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithUInt32s:NULL forKeys:NULL count:0];
}
-- (instancetype)initWithValues:(const uint32_t [])values
- forKeys:(const int32_t [])keys
- count:(NSUInteger)count {
+- (instancetype)initWithUInt32s:(const uint32_t [])values
+ forKeys:(const int32_t [])keys
+ count:(NSUInteger)count {
self = [super init];
if (self) {
_dictionary = [[NSMutableDictionary alloc] init];
@@ -3532,7 +3554,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)initWithDictionary:(GPBInt32UInt32Dictionary *)dictionary {
- self = [self initWithValues:NULL forKeys:NULL count:0];
+ self = [self initWithUInt32s:NULL forKeys:NULL count:0];
if (self) {
if (dictionary) {
[_dictionary addEntriesFromDictionary:dictionary->_dictionary];
@@ -3543,7 +3565,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
- (instancetype)initWithCapacity:(NSUInteger)numItems {
#pragma unused(numItems)
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithUInt32s:NULL forKeys:NULL count:0];
}
- (void)dealloc {
@@ -3558,14 +3580,15 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBInt32UInt32Dictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBInt32UInt32Dictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBInt32UInt32Dictionary class]]) {
return NO;
}
- return [_dictionary isEqual:other->_dictionary];
+ GPBInt32UInt32Dictionary *otherDictionary = other;
+ return [_dictionary isEqual:otherDictionary->_dictionary];
}
- (NSUInteger)hash {
@@ -3580,7 +3603,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return _dictionary.count;
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndUInt32sUsingBlock:
(void (^)(int32_t key, uint32_t value, BOOL *stop))block {
[_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
NSNumber *aValue,
@@ -3638,13 +3661,13 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block {
- [self enumerateKeysAndValuesUsingBlock:^(int32_t key, uint32_t value, BOOL *stop) {
+ [self enumerateKeysAndUInt32sUsingBlock:^(int32_t key, uint32_t value, BOOL *stop) {
#pragma unused(stop)
block([NSString stringWithFormat:@"%d", key], [NSString stringWithFormat:@"%u", value]);
}];
}
-- (BOOL)valueForKey:(int32_t)key value:(uint32_t *)value {
+- (BOOL)getUInt32:(nullable uint32_t *)value forKey:(int32_t)key {
NSNumber *wrapped = [_dictionary objectForKey:@(key)];
if (wrapped && value) {
*value = [wrapped unsignedIntValue];
@@ -3661,14 +3684,14 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)setValue:(uint32_t)value forKey:(int32_t)key {
+- (void)setUInt32:(uint32_t)value forKey:(int32_t)key {
[_dictionary setObject:@(value) forKey:@(key)];
if (_autocreator) {
GPBAutocreatedDictionaryModified(_autocreator, self);
}
}
-- (void)removeValueForKey:(int32_t)aKey {
+- (void)removeUInt32ForKey:(int32_t)aKey {
[_dictionary removeObjectForKey:@(aKey)];
}
@@ -3686,24 +3709,24 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
+ (instancetype)dictionary {
- return [[[self alloc] initWithValues:NULL forKeys:NULL count:0] autorelease];
+ return [[[self alloc] initWithInt32s:NULL forKeys:NULL count:0] autorelease];
}
-+ (instancetype)dictionaryWithValue:(int32_t)value
++ (instancetype)dictionaryWithInt32:(int32_t)value
forKey:(int32_t)key {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
+ // Cast is needed so the compiler knows what class we are invoking initWithInt32s:forKeys:count:
// on to get the type correct.
- return [[(GPBInt32Int32Dictionary*)[self alloc] initWithValues:&value
+ return [[(GPBInt32Int32Dictionary*)[self alloc] initWithInt32s:&value
forKeys:&key
count:1] autorelease];
}
-+ (instancetype)dictionaryWithValues:(const int32_t [])values
++ (instancetype)dictionaryWithInt32s:(const int32_t [])values
forKeys:(const int32_t [])keys
count:(NSUInteger)count {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
+ // Cast is needed so the compiler knows what class we are invoking initWithInt32s:forKeys:count:
// on to get the type correct.
- return [[(GPBInt32Int32Dictionary*)[self alloc] initWithValues:values
+ return [[(GPBInt32Int32Dictionary*)[self alloc] initWithInt32s:values
forKeys:keys
count:count] autorelease];
}
@@ -3719,10 +3742,10 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)init {
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithInt32s:NULL forKeys:NULL count:0];
}
-- (instancetype)initWithValues:(const int32_t [])values
+- (instancetype)initWithInt32s:(const int32_t [])values
forKeys:(const int32_t [])keys
count:(NSUInteger)count {
self = [super init];
@@ -3738,7 +3761,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)initWithDictionary:(GPBInt32Int32Dictionary *)dictionary {
- self = [self initWithValues:NULL forKeys:NULL count:0];
+ self = [self initWithInt32s:NULL forKeys:NULL count:0];
if (self) {
if (dictionary) {
[_dictionary addEntriesFromDictionary:dictionary->_dictionary];
@@ -3749,7 +3772,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
- (instancetype)initWithCapacity:(NSUInteger)numItems {
#pragma unused(numItems)
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithInt32s:NULL forKeys:NULL count:0];
}
- (void)dealloc {
@@ -3764,14 +3787,15 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBInt32Int32Dictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBInt32Int32Dictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBInt32Int32Dictionary class]]) {
return NO;
}
- return [_dictionary isEqual:other->_dictionary];
+ GPBInt32Int32Dictionary *otherDictionary = other;
+ return [_dictionary isEqual:otherDictionary->_dictionary];
}
- (NSUInteger)hash {
@@ -3786,7 +3810,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return _dictionary.count;
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndInt32sUsingBlock:
(void (^)(int32_t key, int32_t value, BOOL *stop))block {
[_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
NSNumber *aValue,
@@ -3844,13 +3868,13 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block {
- [self enumerateKeysAndValuesUsingBlock:^(int32_t key, int32_t value, BOOL *stop) {
+ [self enumerateKeysAndInt32sUsingBlock:^(int32_t key, int32_t value, BOOL *stop) {
#pragma unused(stop)
block([NSString stringWithFormat:@"%d", key], [NSString stringWithFormat:@"%d", value]);
}];
}
-- (BOOL)valueForKey:(int32_t)key value:(int32_t *)value {
+- (BOOL)getInt32:(nullable int32_t *)value forKey:(int32_t)key {
NSNumber *wrapped = [_dictionary objectForKey:@(key)];
if (wrapped && value) {
*value = [wrapped intValue];
@@ -3867,14 +3891,14 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)setValue:(int32_t)value forKey:(int32_t)key {
+- (void)setInt32:(int32_t)value forKey:(int32_t)key {
[_dictionary setObject:@(value) forKey:@(key)];
if (_autocreator) {
GPBAutocreatedDictionaryModified(_autocreator, self);
}
}
-- (void)removeValueForKey:(int32_t)aKey {
+- (void)removeInt32ForKey:(int32_t)aKey {
[_dictionary removeObjectForKey:@(aKey)];
}
@@ -3892,24 +3916,24 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
+ (instancetype)dictionary {
- return [[[self alloc] initWithValues:NULL forKeys:NULL count:0] autorelease];
+ return [[[self alloc] initWithUInt64s:NULL forKeys:NULL count:0] autorelease];
}
-+ (instancetype)dictionaryWithValue:(uint64_t)value
- forKey:(int32_t)key {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithUInt64:(uint64_t)value
+ forKey:(int32_t)key {
+ // Cast is needed so the compiler knows what class we are invoking initWithUInt64s:forKeys:count:
// on to get the type correct.
- return [[(GPBInt32UInt64Dictionary*)[self alloc] initWithValues:&value
- forKeys:&key
- count:1] autorelease];
+ return [[(GPBInt32UInt64Dictionary*)[self alloc] initWithUInt64s:&value
+ forKeys:&key
+ count:1] autorelease];
}
-+ (instancetype)dictionaryWithValues:(const uint64_t [])values
- forKeys:(const int32_t [])keys
- count:(NSUInteger)count {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithUInt64s:(const uint64_t [])values
+ forKeys:(const int32_t [])keys
+ count:(NSUInteger)count {
+ // Cast is needed so the compiler knows what class we are invoking initWithUInt64s:forKeys:count:
// on to get the type correct.
- return [[(GPBInt32UInt64Dictionary*)[self alloc] initWithValues:values
+ return [[(GPBInt32UInt64Dictionary*)[self alloc] initWithUInt64s:values
forKeys:keys
count:count] autorelease];
}
@@ -3925,12 +3949,12 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)init {
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithUInt64s:NULL forKeys:NULL count:0];
}
-- (instancetype)initWithValues:(const uint64_t [])values
- forKeys:(const int32_t [])keys
- count:(NSUInteger)count {
+- (instancetype)initWithUInt64s:(const uint64_t [])values
+ forKeys:(const int32_t [])keys
+ count:(NSUInteger)count {
self = [super init];
if (self) {
_dictionary = [[NSMutableDictionary alloc] init];
@@ -3944,7 +3968,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)initWithDictionary:(GPBInt32UInt64Dictionary *)dictionary {
- self = [self initWithValues:NULL forKeys:NULL count:0];
+ self = [self initWithUInt64s:NULL forKeys:NULL count:0];
if (self) {
if (dictionary) {
[_dictionary addEntriesFromDictionary:dictionary->_dictionary];
@@ -3955,7 +3979,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
- (instancetype)initWithCapacity:(NSUInteger)numItems {
#pragma unused(numItems)
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithUInt64s:NULL forKeys:NULL count:0];
}
- (void)dealloc {
@@ -3970,14 +3994,15 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBInt32UInt64Dictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBInt32UInt64Dictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBInt32UInt64Dictionary class]]) {
return NO;
}
- return [_dictionary isEqual:other->_dictionary];
+ GPBInt32UInt64Dictionary *otherDictionary = other;
+ return [_dictionary isEqual:otherDictionary->_dictionary];
}
- (NSUInteger)hash {
@@ -3992,7 +4017,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return _dictionary.count;
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndUInt64sUsingBlock:
(void (^)(int32_t key, uint64_t value, BOOL *stop))block {
[_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
NSNumber *aValue,
@@ -4050,13 +4075,13 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block {
- [self enumerateKeysAndValuesUsingBlock:^(int32_t key, uint64_t value, BOOL *stop) {
+ [self enumerateKeysAndUInt64sUsingBlock:^(int32_t key, uint64_t value, BOOL *stop) {
#pragma unused(stop)
block([NSString stringWithFormat:@"%d", key], [NSString stringWithFormat:@"%llu", value]);
}];
}
-- (BOOL)valueForKey:(int32_t)key value:(uint64_t *)value {
+- (BOOL)getUInt64:(nullable uint64_t *)value forKey:(int32_t)key {
NSNumber *wrapped = [_dictionary objectForKey:@(key)];
if (wrapped && value) {
*value = [wrapped unsignedLongLongValue];
@@ -4073,14 +4098,14 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)setValue:(uint64_t)value forKey:(int32_t)key {
+- (void)setUInt64:(uint64_t)value forKey:(int32_t)key {
[_dictionary setObject:@(value) forKey:@(key)];
if (_autocreator) {
GPBAutocreatedDictionaryModified(_autocreator, self);
}
}
-- (void)removeValueForKey:(int32_t)aKey {
+- (void)removeUInt64ForKey:(int32_t)aKey {
[_dictionary removeObjectForKey:@(aKey)];
}
@@ -4098,24 +4123,24 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
+ (instancetype)dictionary {
- return [[[self alloc] initWithValues:NULL forKeys:NULL count:0] autorelease];
+ return [[[self alloc] initWithInt64s:NULL forKeys:NULL count:0] autorelease];
}
-+ (instancetype)dictionaryWithValue:(int64_t)value
++ (instancetype)dictionaryWithInt64:(int64_t)value
forKey:(int32_t)key {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
+ // Cast is needed so the compiler knows what class we are invoking initWithInt64s:forKeys:count:
// on to get the type correct.
- return [[(GPBInt32Int64Dictionary*)[self alloc] initWithValues:&value
+ return [[(GPBInt32Int64Dictionary*)[self alloc] initWithInt64s:&value
forKeys:&key
count:1] autorelease];
}
-+ (instancetype)dictionaryWithValues:(const int64_t [])values
++ (instancetype)dictionaryWithInt64s:(const int64_t [])values
forKeys:(const int32_t [])keys
count:(NSUInteger)count {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
+ // Cast is needed so the compiler knows what class we are invoking initWithInt64s:forKeys:count:
// on to get the type correct.
- return [[(GPBInt32Int64Dictionary*)[self alloc] initWithValues:values
+ return [[(GPBInt32Int64Dictionary*)[self alloc] initWithInt64s:values
forKeys:keys
count:count] autorelease];
}
@@ -4131,10 +4156,10 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)init {
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithInt64s:NULL forKeys:NULL count:0];
}
-- (instancetype)initWithValues:(const int64_t [])values
+- (instancetype)initWithInt64s:(const int64_t [])values
forKeys:(const int32_t [])keys
count:(NSUInteger)count {
self = [super init];
@@ -4150,7 +4175,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)initWithDictionary:(GPBInt32Int64Dictionary *)dictionary {
- self = [self initWithValues:NULL forKeys:NULL count:0];
+ self = [self initWithInt64s:NULL forKeys:NULL count:0];
if (self) {
if (dictionary) {
[_dictionary addEntriesFromDictionary:dictionary->_dictionary];
@@ -4161,7 +4186,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
- (instancetype)initWithCapacity:(NSUInteger)numItems {
#pragma unused(numItems)
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithInt64s:NULL forKeys:NULL count:0];
}
- (void)dealloc {
@@ -4176,14 +4201,15 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBInt32Int64Dictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBInt32Int64Dictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBInt32Int64Dictionary class]]) {
return NO;
}
- return [_dictionary isEqual:other->_dictionary];
+ GPBInt32Int64Dictionary *otherDictionary = other;
+ return [_dictionary isEqual:otherDictionary->_dictionary];
}
- (NSUInteger)hash {
@@ -4198,7 +4224,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return _dictionary.count;
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndInt64sUsingBlock:
(void (^)(int32_t key, int64_t value, BOOL *stop))block {
[_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
NSNumber *aValue,
@@ -4256,13 +4282,13 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block {
- [self enumerateKeysAndValuesUsingBlock:^(int32_t key, int64_t value, BOOL *stop) {
+ [self enumerateKeysAndInt64sUsingBlock:^(int32_t key, int64_t value, BOOL *stop) {
#pragma unused(stop)
block([NSString stringWithFormat:@"%d", key], [NSString stringWithFormat:@"%lld", value]);
}];
}
-- (BOOL)valueForKey:(int32_t)key value:(int64_t *)value {
+- (BOOL)getInt64:(nullable int64_t *)value forKey:(int32_t)key {
NSNumber *wrapped = [_dictionary objectForKey:@(key)];
if (wrapped && value) {
*value = [wrapped longLongValue];
@@ -4279,14 +4305,14 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)setValue:(int64_t)value forKey:(int32_t)key {
+- (void)setInt64:(int64_t)value forKey:(int32_t)key {
[_dictionary setObject:@(value) forKey:@(key)];
if (_autocreator) {
GPBAutocreatedDictionaryModified(_autocreator, self);
}
}
-- (void)removeValueForKey:(int32_t)aKey {
+- (void)removeInt64ForKey:(int32_t)aKey {
[_dictionary removeObjectForKey:@(aKey)];
}
@@ -4304,24 +4330,24 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
+ (instancetype)dictionary {
- return [[[self alloc] initWithValues:NULL forKeys:NULL count:0] autorelease];
+ return [[[self alloc] initWithBools:NULL forKeys:NULL count:0] autorelease];
}
-+ (instancetype)dictionaryWithValue:(BOOL)value
- forKey:(int32_t)key {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithBool:(BOOL)value
+ forKey:(int32_t)key {
+ // Cast is needed so the compiler knows what class we are invoking initWithBools:forKeys:count:
// on to get the type correct.
- return [[(GPBInt32BoolDictionary*)[self alloc] initWithValues:&value
- forKeys:&key
- count:1] autorelease];
+ return [[(GPBInt32BoolDictionary*)[self alloc] initWithBools:&value
+ forKeys:&key
+ count:1] autorelease];
}
-+ (instancetype)dictionaryWithValues:(const BOOL [])values
- forKeys:(const int32_t [])keys
- count:(NSUInteger)count {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithBools:(const BOOL [])values
+ forKeys:(const int32_t [])keys
+ count:(NSUInteger)count {
+ // Cast is needed so the compiler knows what class we are invoking initWithBools:forKeys:count:
// on to get the type correct.
- return [[(GPBInt32BoolDictionary*)[self alloc] initWithValues:values
+ return [[(GPBInt32BoolDictionary*)[self alloc] initWithBools:values
forKeys:keys
count:count] autorelease];
}
@@ -4337,12 +4363,12 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)init {
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithBools:NULL forKeys:NULL count:0];
}
-- (instancetype)initWithValues:(const BOOL [])values
- forKeys:(const int32_t [])keys
- count:(NSUInteger)count {
+- (instancetype)initWithBools:(const BOOL [])values
+ forKeys:(const int32_t [])keys
+ count:(NSUInteger)count {
self = [super init];
if (self) {
_dictionary = [[NSMutableDictionary alloc] init];
@@ -4356,7 +4382,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)initWithDictionary:(GPBInt32BoolDictionary *)dictionary {
- self = [self initWithValues:NULL forKeys:NULL count:0];
+ self = [self initWithBools:NULL forKeys:NULL count:0];
if (self) {
if (dictionary) {
[_dictionary addEntriesFromDictionary:dictionary->_dictionary];
@@ -4367,7 +4393,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
- (instancetype)initWithCapacity:(NSUInteger)numItems {
#pragma unused(numItems)
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithBools:NULL forKeys:NULL count:0];
}
- (void)dealloc {
@@ -4382,14 +4408,15 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBInt32BoolDictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBInt32BoolDictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBInt32BoolDictionary class]]) {
return NO;
}
- return [_dictionary isEqual:other->_dictionary];
+ GPBInt32BoolDictionary *otherDictionary = other;
+ return [_dictionary isEqual:otherDictionary->_dictionary];
}
- (NSUInteger)hash {
@@ -4404,7 +4431,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return _dictionary.count;
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndBoolsUsingBlock:
(void (^)(int32_t key, BOOL value, BOOL *stop))block {
[_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
NSNumber *aValue,
@@ -4462,13 +4489,13 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block {
- [self enumerateKeysAndValuesUsingBlock:^(int32_t key, BOOL value, BOOL *stop) {
+ [self enumerateKeysAndBoolsUsingBlock:^(int32_t key, BOOL value, BOOL *stop) {
#pragma unused(stop)
block([NSString stringWithFormat:@"%d", key], (value ? @"true" : @"false"));
}];
}
-- (BOOL)valueForKey:(int32_t)key value:(BOOL *)value {
+- (BOOL)getBool:(nullable BOOL *)value forKey:(int32_t)key {
NSNumber *wrapped = [_dictionary objectForKey:@(key)];
if (wrapped && value) {
*value = [wrapped boolValue];
@@ -4485,14 +4512,14 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)setValue:(BOOL)value forKey:(int32_t)key {
+- (void)setBool:(BOOL)value forKey:(int32_t)key {
[_dictionary setObject:@(value) forKey:@(key)];
if (_autocreator) {
GPBAutocreatedDictionaryModified(_autocreator, self);
}
}
-- (void)removeValueForKey:(int32_t)aKey {
+- (void)removeBoolForKey:(int32_t)aKey {
[_dictionary removeObjectForKey:@(aKey)];
}
@@ -4510,24 +4537,24 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
+ (instancetype)dictionary {
- return [[[self alloc] initWithValues:NULL forKeys:NULL count:0] autorelease];
+ return [[[self alloc] initWithFloats:NULL forKeys:NULL count:0] autorelease];
}
-+ (instancetype)dictionaryWithValue:(float)value
++ (instancetype)dictionaryWithFloat:(float)value
forKey:(int32_t)key {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
+ // Cast is needed so the compiler knows what class we are invoking initWithFloats:forKeys:count:
// on to get the type correct.
- return [[(GPBInt32FloatDictionary*)[self alloc] initWithValues:&value
+ return [[(GPBInt32FloatDictionary*)[self alloc] initWithFloats:&value
forKeys:&key
count:1] autorelease];
}
-+ (instancetype)dictionaryWithValues:(const float [])values
++ (instancetype)dictionaryWithFloats:(const float [])values
forKeys:(const int32_t [])keys
count:(NSUInteger)count {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
+ // Cast is needed so the compiler knows what class we are invoking initWithFloats:forKeys:count:
// on to get the type correct.
- return [[(GPBInt32FloatDictionary*)[self alloc] initWithValues:values
+ return [[(GPBInt32FloatDictionary*)[self alloc] initWithFloats:values
forKeys:keys
count:count] autorelease];
}
@@ -4543,10 +4570,10 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)init {
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithFloats:NULL forKeys:NULL count:0];
}
-- (instancetype)initWithValues:(const float [])values
+- (instancetype)initWithFloats:(const float [])values
forKeys:(const int32_t [])keys
count:(NSUInteger)count {
self = [super init];
@@ -4562,7 +4589,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)initWithDictionary:(GPBInt32FloatDictionary *)dictionary {
- self = [self initWithValues:NULL forKeys:NULL count:0];
+ self = [self initWithFloats:NULL forKeys:NULL count:0];
if (self) {
if (dictionary) {
[_dictionary addEntriesFromDictionary:dictionary->_dictionary];
@@ -4573,7 +4600,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
- (instancetype)initWithCapacity:(NSUInteger)numItems {
#pragma unused(numItems)
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithFloats:NULL forKeys:NULL count:0];
}
- (void)dealloc {
@@ -4588,14 +4615,15 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBInt32FloatDictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBInt32FloatDictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBInt32FloatDictionary class]]) {
return NO;
}
- return [_dictionary isEqual:other->_dictionary];
+ GPBInt32FloatDictionary *otherDictionary = other;
+ return [_dictionary isEqual:otherDictionary->_dictionary];
}
- (NSUInteger)hash {
@@ -4610,7 +4638,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return _dictionary.count;
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndFloatsUsingBlock:
(void (^)(int32_t key, float value, BOOL *stop))block {
[_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
NSNumber *aValue,
@@ -4668,13 +4696,13 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block {
- [self enumerateKeysAndValuesUsingBlock:^(int32_t key, float value, BOOL *stop) {
+ [self enumerateKeysAndFloatsUsingBlock:^(int32_t key, float value, BOOL *stop) {
#pragma unused(stop)
block([NSString stringWithFormat:@"%d", key], [NSString stringWithFormat:@"%.*g", FLT_DIG, value]);
}];
}
-- (BOOL)valueForKey:(int32_t)key value:(float *)value {
+- (BOOL)getFloat:(nullable float *)value forKey:(int32_t)key {
NSNumber *wrapped = [_dictionary objectForKey:@(key)];
if (wrapped && value) {
*value = [wrapped floatValue];
@@ -4691,14 +4719,14 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)setValue:(float)value forKey:(int32_t)key {
+- (void)setFloat:(float)value forKey:(int32_t)key {
[_dictionary setObject:@(value) forKey:@(key)];
if (_autocreator) {
GPBAutocreatedDictionaryModified(_autocreator, self);
}
}
-- (void)removeValueForKey:(int32_t)aKey {
+- (void)removeFloatForKey:(int32_t)aKey {
[_dictionary removeObjectForKey:@(aKey)];
}
@@ -4716,24 +4744,24 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
+ (instancetype)dictionary {
- return [[[self alloc] initWithValues:NULL forKeys:NULL count:0] autorelease];
+ return [[[self alloc] initWithDoubles:NULL forKeys:NULL count:0] autorelease];
}
-+ (instancetype)dictionaryWithValue:(double)value
- forKey:(int32_t)key {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithDouble:(double)value
+ forKey:(int32_t)key {
+ // Cast is needed so the compiler knows what class we are invoking initWithDoubles:forKeys:count:
// on to get the type correct.
- return [[(GPBInt32DoubleDictionary*)[self alloc] initWithValues:&value
- forKeys:&key
- count:1] autorelease];
+ return [[(GPBInt32DoubleDictionary*)[self alloc] initWithDoubles:&value
+ forKeys:&key
+ count:1] autorelease];
}
-+ (instancetype)dictionaryWithValues:(const double [])values
- forKeys:(const int32_t [])keys
- count:(NSUInteger)count {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithDoubles:(const double [])values
+ forKeys:(const int32_t [])keys
+ count:(NSUInteger)count {
+ // Cast is needed so the compiler knows what class we are invoking initWithDoubles:forKeys:count:
// on to get the type correct.
- return [[(GPBInt32DoubleDictionary*)[self alloc] initWithValues:values
+ return [[(GPBInt32DoubleDictionary*)[self alloc] initWithDoubles:values
forKeys:keys
count:count] autorelease];
}
@@ -4749,12 +4777,12 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)init {
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithDoubles:NULL forKeys:NULL count:0];
}
-- (instancetype)initWithValues:(const double [])values
- forKeys:(const int32_t [])keys
- count:(NSUInteger)count {
+- (instancetype)initWithDoubles:(const double [])values
+ forKeys:(const int32_t [])keys
+ count:(NSUInteger)count {
self = [super init];
if (self) {
_dictionary = [[NSMutableDictionary alloc] init];
@@ -4768,7 +4796,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)initWithDictionary:(GPBInt32DoubleDictionary *)dictionary {
- self = [self initWithValues:NULL forKeys:NULL count:0];
+ self = [self initWithDoubles:NULL forKeys:NULL count:0];
if (self) {
if (dictionary) {
[_dictionary addEntriesFromDictionary:dictionary->_dictionary];
@@ -4779,7 +4807,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
- (instancetype)initWithCapacity:(NSUInteger)numItems {
#pragma unused(numItems)
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithDoubles:NULL forKeys:NULL count:0];
}
- (void)dealloc {
@@ -4794,14 +4822,15 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBInt32DoubleDictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBInt32DoubleDictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBInt32DoubleDictionary class]]) {
return NO;
}
- return [_dictionary isEqual:other->_dictionary];
+ GPBInt32DoubleDictionary *otherDictionary = other;
+ return [_dictionary isEqual:otherDictionary->_dictionary];
}
- (NSUInteger)hash {
@@ -4816,7 +4845,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return _dictionary.count;
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndDoublesUsingBlock:
(void (^)(int32_t key, double value, BOOL *stop))block {
[_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
NSNumber *aValue,
@@ -4874,13 +4903,13 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block {
- [self enumerateKeysAndValuesUsingBlock:^(int32_t key, double value, BOOL *stop) {
+ [self enumerateKeysAndDoublesUsingBlock:^(int32_t key, double value, BOOL *stop) {
#pragma unused(stop)
block([NSString stringWithFormat:@"%d", key], [NSString stringWithFormat:@"%.*lg", DBL_DIG, value]);
}];
}
-- (BOOL)valueForKey:(int32_t)key value:(double *)value {
+- (BOOL)getDouble:(nullable double *)value forKey:(int32_t)key {
NSNumber *wrapped = [_dictionary objectForKey:@(key)];
if (wrapped && value) {
*value = [wrapped doubleValue];
@@ -4897,14 +4926,14 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)setValue:(double)value forKey:(int32_t)key {
+- (void)setDouble:(double)value forKey:(int32_t)key {
[_dictionary setObject:@(value) forKey:@(key)];
if (_autocreator) {
GPBAutocreatedDictionaryModified(_autocreator, self);
}
}
-- (void)removeValueForKey:(int32_t)aKey {
+- (void)removeDoubleForKey:(int32_t)aKey {
[_dictionary removeObjectForKey:@(aKey)];
}
@@ -5028,14 +5057,15 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBInt32EnumDictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBInt32EnumDictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBInt32EnumDictionary class]]) {
return NO;
}
- return [_dictionary isEqual:other->_dictionary];
+ GPBInt32EnumDictionary *otherDictionary = other;
+ return [_dictionary isEqual:otherDictionary->_dictionary];
}
- (NSUInteger)hash {
@@ -5126,7 +5156,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}];
}
-- (BOOL)valueForKey:(int32_t)key value:(int32_t *)value {
+- (BOOL)getEnum:(int32_t *)value forKey:(int32_t)key {
NSNumber *wrapped = [_dictionary objectForKey:@(key)];
if (wrapped && value) {
int32_t result = [wrapped intValue];
@@ -5138,7 +5168,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return (wrapped != NULL);
}
-- (BOOL)valueForKey:(int32_t)key rawValue:(int32_t *)rawValue {
+- (BOOL)getRawValue:(int32_t *)rawValue forKey:(int32_t)key {
NSNumber *wrapped = [_dictionary objectForKey:@(key)];
if (wrapped && rawValue) {
*rawValue = [wrapped intValue];
@@ -5146,7 +5176,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return (wrapped != NULL);
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndEnumsUsingBlock:
(void (^)(int32_t key, int32_t value, BOOL *stop))block {
GPBEnumValidationFunc func = _validationFunc;
[_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
@@ -5176,7 +5206,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)removeValueForKey:(int32_t)aKey {
+- (void)removeEnumForKey:(int32_t)aKey {
[_dictionary removeObjectForKey:@(aKey)];
}
@@ -5184,7 +5214,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
[_dictionary removeAllObjects];
}
-- (void)setValue:(int32_t)value forKey:(int32_t)key {
+- (void)setEnum:(int32_t)value forKey:(int32_t)key {
if (!_validationFunc(value)) {
[NSException raise:NSInvalidArgumentException
format:@"GPBInt32EnumDictionary: Attempt to set an unknown enum value (%d)",
@@ -5289,14 +5319,15 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBInt32ObjectDictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBInt32ObjectDictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBInt32ObjectDictionary class]]) {
return NO;
}
- return [_dictionary isEqual:other->_dictionary];
+ GPBInt32ObjectDictionary *otherDictionary = other;
+ return [_dictionary isEqual:otherDictionary->_dictionary];
}
- (NSUInteger)hash {
@@ -5444,24 +5475,24 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
+ (instancetype)dictionary {
- return [[[self alloc] initWithValues:NULL forKeys:NULL count:0] autorelease];
+ return [[[self alloc] initWithUInt32s:NULL forKeys:NULL count:0] autorelease];
}
-+ (instancetype)dictionaryWithValue:(uint32_t)value
- forKey:(uint64_t)key {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithUInt32:(uint32_t)value
+ forKey:(uint64_t)key {
+ // Cast is needed so the compiler knows what class we are invoking initWithUInt32s:forKeys:count:
// on to get the type correct.
- return [[(GPBUInt64UInt32Dictionary*)[self alloc] initWithValues:&value
- forKeys:&key
- count:1] autorelease];
+ return [[(GPBUInt64UInt32Dictionary*)[self alloc] initWithUInt32s:&value
+ forKeys:&key
+ count:1] autorelease];
}
-+ (instancetype)dictionaryWithValues:(const uint32_t [])values
- forKeys:(const uint64_t [])keys
- count:(NSUInteger)count {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithUInt32s:(const uint32_t [])values
+ forKeys:(const uint64_t [])keys
+ count:(NSUInteger)count {
+ // Cast is needed so the compiler knows what class we are invoking initWithUInt32s:forKeys:count:
// on to get the type correct.
- return [[(GPBUInt64UInt32Dictionary*)[self alloc] initWithValues:values
+ return [[(GPBUInt64UInt32Dictionary*)[self alloc] initWithUInt32s:values
forKeys:keys
count:count] autorelease];
}
@@ -5477,12 +5508,12 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)init {
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithUInt32s:NULL forKeys:NULL count:0];
}
-- (instancetype)initWithValues:(const uint32_t [])values
- forKeys:(const uint64_t [])keys
- count:(NSUInteger)count {
+- (instancetype)initWithUInt32s:(const uint32_t [])values
+ forKeys:(const uint64_t [])keys
+ count:(NSUInteger)count {
self = [super init];
if (self) {
_dictionary = [[NSMutableDictionary alloc] init];
@@ -5496,7 +5527,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)initWithDictionary:(GPBUInt64UInt32Dictionary *)dictionary {
- self = [self initWithValues:NULL forKeys:NULL count:0];
+ self = [self initWithUInt32s:NULL forKeys:NULL count:0];
if (self) {
if (dictionary) {
[_dictionary addEntriesFromDictionary:dictionary->_dictionary];
@@ -5507,7 +5538,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
- (instancetype)initWithCapacity:(NSUInteger)numItems {
#pragma unused(numItems)
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithUInt32s:NULL forKeys:NULL count:0];
}
- (void)dealloc {
@@ -5522,14 +5553,15 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBUInt64UInt32Dictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBUInt64UInt32Dictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBUInt64UInt32Dictionary class]]) {
return NO;
}
- return [_dictionary isEqual:other->_dictionary];
+ GPBUInt64UInt32Dictionary *otherDictionary = other;
+ return [_dictionary isEqual:otherDictionary->_dictionary];
}
- (NSUInteger)hash {
@@ -5544,7 +5576,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return _dictionary.count;
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndUInt32sUsingBlock:
(void (^)(uint64_t key, uint32_t value, BOOL *stop))block {
[_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
NSNumber *aValue,
@@ -5602,13 +5634,13 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block {
- [self enumerateKeysAndValuesUsingBlock:^(uint64_t key, uint32_t value, BOOL *stop) {
+ [self enumerateKeysAndUInt32sUsingBlock:^(uint64_t key, uint32_t value, BOOL *stop) {
#pragma unused(stop)
block([NSString stringWithFormat:@"%llu", key], [NSString stringWithFormat:@"%u", value]);
}];
}
-- (BOOL)valueForKey:(uint64_t)key value:(uint32_t *)value {
+- (BOOL)getUInt32:(nullable uint32_t *)value forKey:(uint64_t)key {
NSNumber *wrapped = [_dictionary objectForKey:@(key)];
if (wrapped && value) {
*value = [wrapped unsignedIntValue];
@@ -5625,14 +5657,14 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)setValue:(uint32_t)value forKey:(uint64_t)key {
+- (void)setUInt32:(uint32_t)value forKey:(uint64_t)key {
[_dictionary setObject:@(value) forKey:@(key)];
if (_autocreator) {
GPBAutocreatedDictionaryModified(_autocreator, self);
}
}
-- (void)removeValueForKey:(uint64_t)aKey {
+- (void)removeUInt32ForKey:(uint64_t)aKey {
[_dictionary removeObjectForKey:@(aKey)];
}
@@ -5650,24 +5682,24 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
+ (instancetype)dictionary {
- return [[[self alloc] initWithValues:NULL forKeys:NULL count:0] autorelease];
+ return [[[self alloc] initWithInt32s:NULL forKeys:NULL count:0] autorelease];
}
-+ (instancetype)dictionaryWithValue:(int32_t)value
++ (instancetype)dictionaryWithInt32:(int32_t)value
forKey:(uint64_t)key {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
+ // Cast is needed so the compiler knows what class we are invoking initWithInt32s:forKeys:count:
// on to get the type correct.
- return [[(GPBUInt64Int32Dictionary*)[self alloc] initWithValues:&value
+ return [[(GPBUInt64Int32Dictionary*)[self alloc] initWithInt32s:&value
forKeys:&key
count:1] autorelease];
}
-+ (instancetype)dictionaryWithValues:(const int32_t [])values
++ (instancetype)dictionaryWithInt32s:(const int32_t [])values
forKeys:(const uint64_t [])keys
count:(NSUInteger)count {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
+ // Cast is needed so the compiler knows what class we are invoking initWithInt32s:forKeys:count:
// on to get the type correct.
- return [[(GPBUInt64Int32Dictionary*)[self alloc] initWithValues:values
+ return [[(GPBUInt64Int32Dictionary*)[self alloc] initWithInt32s:values
forKeys:keys
count:count] autorelease];
}
@@ -5683,10 +5715,10 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)init {
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithInt32s:NULL forKeys:NULL count:0];
}
-- (instancetype)initWithValues:(const int32_t [])values
+- (instancetype)initWithInt32s:(const int32_t [])values
forKeys:(const uint64_t [])keys
count:(NSUInteger)count {
self = [super init];
@@ -5702,7 +5734,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)initWithDictionary:(GPBUInt64Int32Dictionary *)dictionary {
- self = [self initWithValues:NULL forKeys:NULL count:0];
+ self = [self initWithInt32s:NULL forKeys:NULL count:0];
if (self) {
if (dictionary) {
[_dictionary addEntriesFromDictionary:dictionary->_dictionary];
@@ -5713,7 +5745,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
- (instancetype)initWithCapacity:(NSUInteger)numItems {
#pragma unused(numItems)
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithInt32s:NULL forKeys:NULL count:0];
}
- (void)dealloc {
@@ -5728,14 +5760,15 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBUInt64Int32Dictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBUInt64Int32Dictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBUInt64Int32Dictionary class]]) {
return NO;
}
- return [_dictionary isEqual:other->_dictionary];
+ GPBUInt64Int32Dictionary *otherDictionary = other;
+ return [_dictionary isEqual:otherDictionary->_dictionary];
}
- (NSUInteger)hash {
@@ -5750,7 +5783,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return _dictionary.count;
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndInt32sUsingBlock:
(void (^)(uint64_t key, int32_t value, BOOL *stop))block {
[_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
NSNumber *aValue,
@@ -5808,13 +5841,13 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block {
- [self enumerateKeysAndValuesUsingBlock:^(uint64_t key, int32_t value, BOOL *stop) {
+ [self enumerateKeysAndInt32sUsingBlock:^(uint64_t key, int32_t value, BOOL *stop) {
#pragma unused(stop)
block([NSString stringWithFormat:@"%llu", key], [NSString stringWithFormat:@"%d", value]);
}];
}
-- (BOOL)valueForKey:(uint64_t)key value:(int32_t *)value {
+- (BOOL)getInt32:(nullable int32_t *)value forKey:(uint64_t)key {
NSNumber *wrapped = [_dictionary objectForKey:@(key)];
if (wrapped && value) {
*value = [wrapped intValue];
@@ -5831,14 +5864,14 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)setValue:(int32_t)value forKey:(uint64_t)key {
+- (void)setInt32:(int32_t)value forKey:(uint64_t)key {
[_dictionary setObject:@(value) forKey:@(key)];
if (_autocreator) {
GPBAutocreatedDictionaryModified(_autocreator, self);
}
}
-- (void)removeValueForKey:(uint64_t)aKey {
+- (void)removeInt32ForKey:(uint64_t)aKey {
[_dictionary removeObjectForKey:@(aKey)];
}
@@ -5856,24 +5889,24 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
+ (instancetype)dictionary {
- return [[[self alloc] initWithValues:NULL forKeys:NULL count:0] autorelease];
+ return [[[self alloc] initWithUInt64s:NULL forKeys:NULL count:0] autorelease];
}
-+ (instancetype)dictionaryWithValue:(uint64_t)value
- forKey:(uint64_t)key {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithUInt64:(uint64_t)value
+ forKey:(uint64_t)key {
+ // Cast is needed so the compiler knows what class we are invoking initWithUInt64s:forKeys:count:
// on to get the type correct.
- return [[(GPBUInt64UInt64Dictionary*)[self alloc] initWithValues:&value
- forKeys:&key
- count:1] autorelease];
+ return [[(GPBUInt64UInt64Dictionary*)[self alloc] initWithUInt64s:&value
+ forKeys:&key
+ count:1] autorelease];
}
-+ (instancetype)dictionaryWithValues:(const uint64_t [])values
- forKeys:(const uint64_t [])keys
- count:(NSUInteger)count {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithUInt64s:(const uint64_t [])values
+ forKeys:(const uint64_t [])keys
+ count:(NSUInteger)count {
+ // Cast is needed so the compiler knows what class we are invoking initWithUInt64s:forKeys:count:
// on to get the type correct.
- return [[(GPBUInt64UInt64Dictionary*)[self alloc] initWithValues:values
+ return [[(GPBUInt64UInt64Dictionary*)[self alloc] initWithUInt64s:values
forKeys:keys
count:count] autorelease];
}
@@ -5889,12 +5922,12 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)init {
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithUInt64s:NULL forKeys:NULL count:0];
}
-- (instancetype)initWithValues:(const uint64_t [])values
- forKeys:(const uint64_t [])keys
- count:(NSUInteger)count {
+- (instancetype)initWithUInt64s:(const uint64_t [])values
+ forKeys:(const uint64_t [])keys
+ count:(NSUInteger)count {
self = [super init];
if (self) {
_dictionary = [[NSMutableDictionary alloc] init];
@@ -5908,7 +5941,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)initWithDictionary:(GPBUInt64UInt64Dictionary *)dictionary {
- self = [self initWithValues:NULL forKeys:NULL count:0];
+ self = [self initWithUInt64s:NULL forKeys:NULL count:0];
if (self) {
if (dictionary) {
[_dictionary addEntriesFromDictionary:dictionary->_dictionary];
@@ -5919,7 +5952,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
- (instancetype)initWithCapacity:(NSUInteger)numItems {
#pragma unused(numItems)
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithUInt64s:NULL forKeys:NULL count:0];
}
- (void)dealloc {
@@ -5934,14 +5967,15 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBUInt64UInt64Dictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBUInt64UInt64Dictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBUInt64UInt64Dictionary class]]) {
return NO;
}
- return [_dictionary isEqual:other->_dictionary];
+ GPBUInt64UInt64Dictionary *otherDictionary = other;
+ return [_dictionary isEqual:otherDictionary->_dictionary];
}
- (NSUInteger)hash {
@@ -5956,7 +5990,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return _dictionary.count;
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndUInt64sUsingBlock:
(void (^)(uint64_t key, uint64_t value, BOOL *stop))block {
[_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
NSNumber *aValue,
@@ -6014,13 +6048,13 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block {
- [self enumerateKeysAndValuesUsingBlock:^(uint64_t key, uint64_t value, BOOL *stop) {
+ [self enumerateKeysAndUInt64sUsingBlock:^(uint64_t key, uint64_t value, BOOL *stop) {
#pragma unused(stop)
block([NSString stringWithFormat:@"%llu", key], [NSString stringWithFormat:@"%llu", value]);
}];
}
-- (BOOL)valueForKey:(uint64_t)key value:(uint64_t *)value {
+- (BOOL)getUInt64:(nullable uint64_t *)value forKey:(uint64_t)key {
NSNumber *wrapped = [_dictionary objectForKey:@(key)];
if (wrapped && value) {
*value = [wrapped unsignedLongLongValue];
@@ -6037,14 +6071,14 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)setValue:(uint64_t)value forKey:(uint64_t)key {
+- (void)setUInt64:(uint64_t)value forKey:(uint64_t)key {
[_dictionary setObject:@(value) forKey:@(key)];
if (_autocreator) {
GPBAutocreatedDictionaryModified(_autocreator, self);
}
}
-- (void)removeValueForKey:(uint64_t)aKey {
+- (void)removeUInt64ForKey:(uint64_t)aKey {
[_dictionary removeObjectForKey:@(aKey)];
}
@@ -6062,24 +6096,24 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
+ (instancetype)dictionary {
- return [[[self alloc] initWithValues:NULL forKeys:NULL count:0] autorelease];
+ return [[[self alloc] initWithInt64s:NULL forKeys:NULL count:0] autorelease];
}
-+ (instancetype)dictionaryWithValue:(int64_t)value
++ (instancetype)dictionaryWithInt64:(int64_t)value
forKey:(uint64_t)key {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
+ // Cast is needed so the compiler knows what class we are invoking initWithInt64s:forKeys:count:
// on to get the type correct.
- return [[(GPBUInt64Int64Dictionary*)[self alloc] initWithValues:&value
+ return [[(GPBUInt64Int64Dictionary*)[self alloc] initWithInt64s:&value
forKeys:&key
count:1] autorelease];
}
-+ (instancetype)dictionaryWithValues:(const int64_t [])values
++ (instancetype)dictionaryWithInt64s:(const int64_t [])values
forKeys:(const uint64_t [])keys
count:(NSUInteger)count {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
+ // Cast is needed so the compiler knows what class we are invoking initWithInt64s:forKeys:count:
// on to get the type correct.
- return [[(GPBUInt64Int64Dictionary*)[self alloc] initWithValues:values
+ return [[(GPBUInt64Int64Dictionary*)[self alloc] initWithInt64s:values
forKeys:keys
count:count] autorelease];
}
@@ -6095,10 +6129,10 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)init {
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithInt64s:NULL forKeys:NULL count:0];
}
-- (instancetype)initWithValues:(const int64_t [])values
+- (instancetype)initWithInt64s:(const int64_t [])values
forKeys:(const uint64_t [])keys
count:(NSUInteger)count {
self = [super init];
@@ -6114,7 +6148,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)initWithDictionary:(GPBUInt64Int64Dictionary *)dictionary {
- self = [self initWithValues:NULL forKeys:NULL count:0];
+ self = [self initWithInt64s:NULL forKeys:NULL count:0];
if (self) {
if (dictionary) {
[_dictionary addEntriesFromDictionary:dictionary->_dictionary];
@@ -6125,7 +6159,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
- (instancetype)initWithCapacity:(NSUInteger)numItems {
#pragma unused(numItems)
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithInt64s:NULL forKeys:NULL count:0];
}
- (void)dealloc {
@@ -6140,14 +6174,15 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBUInt64Int64Dictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBUInt64Int64Dictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBUInt64Int64Dictionary class]]) {
return NO;
}
- return [_dictionary isEqual:other->_dictionary];
+ GPBUInt64Int64Dictionary *otherDictionary = other;
+ return [_dictionary isEqual:otherDictionary->_dictionary];
}
- (NSUInteger)hash {
@@ -6162,7 +6197,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return _dictionary.count;
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndInt64sUsingBlock:
(void (^)(uint64_t key, int64_t value, BOOL *stop))block {
[_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
NSNumber *aValue,
@@ -6220,13 +6255,13 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block {
- [self enumerateKeysAndValuesUsingBlock:^(uint64_t key, int64_t value, BOOL *stop) {
+ [self enumerateKeysAndInt64sUsingBlock:^(uint64_t key, int64_t value, BOOL *stop) {
#pragma unused(stop)
block([NSString stringWithFormat:@"%llu", key], [NSString stringWithFormat:@"%lld", value]);
}];
}
-- (BOOL)valueForKey:(uint64_t)key value:(int64_t *)value {
+- (BOOL)getInt64:(nullable int64_t *)value forKey:(uint64_t)key {
NSNumber *wrapped = [_dictionary objectForKey:@(key)];
if (wrapped && value) {
*value = [wrapped longLongValue];
@@ -6243,14 +6278,14 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)setValue:(int64_t)value forKey:(uint64_t)key {
+- (void)setInt64:(int64_t)value forKey:(uint64_t)key {
[_dictionary setObject:@(value) forKey:@(key)];
if (_autocreator) {
GPBAutocreatedDictionaryModified(_autocreator, self);
}
}
-- (void)removeValueForKey:(uint64_t)aKey {
+- (void)removeInt64ForKey:(uint64_t)aKey {
[_dictionary removeObjectForKey:@(aKey)];
}
@@ -6268,24 +6303,24 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
+ (instancetype)dictionary {
- return [[[self alloc] initWithValues:NULL forKeys:NULL count:0] autorelease];
+ return [[[self alloc] initWithBools:NULL forKeys:NULL count:0] autorelease];
}
-+ (instancetype)dictionaryWithValue:(BOOL)value
- forKey:(uint64_t)key {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithBool:(BOOL)value
+ forKey:(uint64_t)key {
+ // Cast is needed so the compiler knows what class we are invoking initWithBools:forKeys:count:
// on to get the type correct.
- return [[(GPBUInt64BoolDictionary*)[self alloc] initWithValues:&value
- forKeys:&key
- count:1] autorelease];
+ return [[(GPBUInt64BoolDictionary*)[self alloc] initWithBools:&value
+ forKeys:&key
+ count:1] autorelease];
}
-+ (instancetype)dictionaryWithValues:(const BOOL [])values
- forKeys:(const uint64_t [])keys
- count:(NSUInteger)count {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithBools:(const BOOL [])values
+ forKeys:(const uint64_t [])keys
+ count:(NSUInteger)count {
+ // Cast is needed so the compiler knows what class we are invoking initWithBools:forKeys:count:
// on to get the type correct.
- return [[(GPBUInt64BoolDictionary*)[self alloc] initWithValues:values
+ return [[(GPBUInt64BoolDictionary*)[self alloc] initWithBools:values
forKeys:keys
count:count] autorelease];
}
@@ -6301,12 +6336,12 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)init {
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithBools:NULL forKeys:NULL count:0];
}
-- (instancetype)initWithValues:(const BOOL [])values
- forKeys:(const uint64_t [])keys
- count:(NSUInteger)count {
+- (instancetype)initWithBools:(const BOOL [])values
+ forKeys:(const uint64_t [])keys
+ count:(NSUInteger)count {
self = [super init];
if (self) {
_dictionary = [[NSMutableDictionary alloc] init];
@@ -6320,7 +6355,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)initWithDictionary:(GPBUInt64BoolDictionary *)dictionary {
- self = [self initWithValues:NULL forKeys:NULL count:0];
+ self = [self initWithBools:NULL forKeys:NULL count:0];
if (self) {
if (dictionary) {
[_dictionary addEntriesFromDictionary:dictionary->_dictionary];
@@ -6331,7 +6366,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
- (instancetype)initWithCapacity:(NSUInteger)numItems {
#pragma unused(numItems)
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithBools:NULL forKeys:NULL count:0];
}
- (void)dealloc {
@@ -6346,14 +6381,15 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBUInt64BoolDictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBUInt64BoolDictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBUInt64BoolDictionary class]]) {
return NO;
}
- return [_dictionary isEqual:other->_dictionary];
+ GPBUInt64BoolDictionary *otherDictionary = other;
+ return [_dictionary isEqual:otherDictionary->_dictionary];
}
- (NSUInteger)hash {
@@ -6368,7 +6404,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return _dictionary.count;
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndBoolsUsingBlock:
(void (^)(uint64_t key, BOOL value, BOOL *stop))block {
[_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
NSNumber *aValue,
@@ -6426,13 +6462,13 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block {
- [self enumerateKeysAndValuesUsingBlock:^(uint64_t key, BOOL value, BOOL *stop) {
+ [self enumerateKeysAndBoolsUsingBlock:^(uint64_t key, BOOL value, BOOL *stop) {
#pragma unused(stop)
block([NSString stringWithFormat:@"%llu", key], (value ? @"true" : @"false"));
}];
}
-- (BOOL)valueForKey:(uint64_t)key value:(BOOL *)value {
+- (BOOL)getBool:(nullable BOOL *)value forKey:(uint64_t)key {
NSNumber *wrapped = [_dictionary objectForKey:@(key)];
if (wrapped && value) {
*value = [wrapped boolValue];
@@ -6449,14 +6485,14 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)setValue:(BOOL)value forKey:(uint64_t)key {
+- (void)setBool:(BOOL)value forKey:(uint64_t)key {
[_dictionary setObject:@(value) forKey:@(key)];
if (_autocreator) {
GPBAutocreatedDictionaryModified(_autocreator, self);
}
}
-- (void)removeValueForKey:(uint64_t)aKey {
+- (void)removeBoolForKey:(uint64_t)aKey {
[_dictionary removeObjectForKey:@(aKey)];
}
@@ -6474,24 +6510,24 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
+ (instancetype)dictionary {
- return [[[self alloc] initWithValues:NULL forKeys:NULL count:0] autorelease];
+ return [[[self alloc] initWithFloats:NULL forKeys:NULL count:0] autorelease];
}
-+ (instancetype)dictionaryWithValue:(float)value
++ (instancetype)dictionaryWithFloat:(float)value
forKey:(uint64_t)key {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
+ // Cast is needed so the compiler knows what class we are invoking initWithFloats:forKeys:count:
// on to get the type correct.
- return [[(GPBUInt64FloatDictionary*)[self alloc] initWithValues:&value
+ return [[(GPBUInt64FloatDictionary*)[self alloc] initWithFloats:&value
forKeys:&key
count:1] autorelease];
}
-+ (instancetype)dictionaryWithValues:(const float [])values
++ (instancetype)dictionaryWithFloats:(const float [])values
forKeys:(const uint64_t [])keys
count:(NSUInteger)count {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
+ // Cast is needed so the compiler knows what class we are invoking initWithFloats:forKeys:count:
// on to get the type correct.
- return [[(GPBUInt64FloatDictionary*)[self alloc] initWithValues:values
+ return [[(GPBUInt64FloatDictionary*)[self alloc] initWithFloats:values
forKeys:keys
count:count] autorelease];
}
@@ -6507,10 +6543,10 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)init {
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithFloats:NULL forKeys:NULL count:0];
}
-- (instancetype)initWithValues:(const float [])values
+- (instancetype)initWithFloats:(const float [])values
forKeys:(const uint64_t [])keys
count:(NSUInteger)count {
self = [super init];
@@ -6526,7 +6562,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)initWithDictionary:(GPBUInt64FloatDictionary *)dictionary {
- self = [self initWithValues:NULL forKeys:NULL count:0];
+ self = [self initWithFloats:NULL forKeys:NULL count:0];
if (self) {
if (dictionary) {
[_dictionary addEntriesFromDictionary:dictionary->_dictionary];
@@ -6537,7 +6573,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
- (instancetype)initWithCapacity:(NSUInteger)numItems {
#pragma unused(numItems)
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithFloats:NULL forKeys:NULL count:0];
}
- (void)dealloc {
@@ -6552,14 +6588,15 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBUInt64FloatDictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBUInt64FloatDictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBUInt64FloatDictionary class]]) {
return NO;
}
- return [_dictionary isEqual:other->_dictionary];
+ GPBUInt64FloatDictionary *otherDictionary = other;
+ return [_dictionary isEqual:otherDictionary->_dictionary];
}
- (NSUInteger)hash {
@@ -6574,7 +6611,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return _dictionary.count;
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndFloatsUsingBlock:
(void (^)(uint64_t key, float value, BOOL *stop))block {
[_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
NSNumber *aValue,
@@ -6632,13 +6669,13 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block {
- [self enumerateKeysAndValuesUsingBlock:^(uint64_t key, float value, BOOL *stop) {
+ [self enumerateKeysAndFloatsUsingBlock:^(uint64_t key, float value, BOOL *stop) {
#pragma unused(stop)
block([NSString stringWithFormat:@"%llu", key], [NSString stringWithFormat:@"%.*g", FLT_DIG, value]);
}];
}
-- (BOOL)valueForKey:(uint64_t)key value:(float *)value {
+- (BOOL)getFloat:(nullable float *)value forKey:(uint64_t)key {
NSNumber *wrapped = [_dictionary objectForKey:@(key)];
if (wrapped && value) {
*value = [wrapped floatValue];
@@ -6655,14 +6692,14 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)setValue:(float)value forKey:(uint64_t)key {
+- (void)setFloat:(float)value forKey:(uint64_t)key {
[_dictionary setObject:@(value) forKey:@(key)];
if (_autocreator) {
GPBAutocreatedDictionaryModified(_autocreator, self);
}
}
-- (void)removeValueForKey:(uint64_t)aKey {
+- (void)removeFloatForKey:(uint64_t)aKey {
[_dictionary removeObjectForKey:@(aKey)];
}
@@ -6680,24 +6717,24 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
+ (instancetype)dictionary {
- return [[[self alloc] initWithValues:NULL forKeys:NULL count:0] autorelease];
+ return [[[self alloc] initWithDoubles:NULL forKeys:NULL count:0] autorelease];
}
-+ (instancetype)dictionaryWithValue:(double)value
- forKey:(uint64_t)key {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithDouble:(double)value
+ forKey:(uint64_t)key {
+ // Cast is needed so the compiler knows what class we are invoking initWithDoubles:forKeys:count:
// on to get the type correct.
- return [[(GPBUInt64DoubleDictionary*)[self alloc] initWithValues:&value
- forKeys:&key
- count:1] autorelease];
+ return [[(GPBUInt64DoubleDictionary*)[self alloc] initWithDoubles:&value
+ forKeys:&key
+ count:1] autorelease];
}
-+ (instancetype)dictionaryWithValues:(const double [])values
- forKeys:(const uint64_t [])keys
- count:(NSUInteger)count {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithDoubles:(const double [])values
+ forKeys:(const uint64_t [])keys
+ count:(NSUInteger)count {
+ // Cast is needed so the compiler knows what class we are invoking initWithDoubles:forKeys:count:
// on to get the type correct.
- return [[(GPBUInt64DoubleDictionary*)[self alloc] initWithValues:values
+ return [[(GPBUInt64DoubleDictionary*)[self alloc] initWithDoubles:values
forKeys:keys
count:count] autorelease];
}
@@ -6713,12 +6750,12 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)init {
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithDoubles:NULL forKeys:NULL count:0];
}
-- (instancetype)initWithValues:(const double [])values
- forKeys:(const uint64_t [])keys
- count:(NSUInteger)count {
+- (instancetype)initWithDoubles:(const double [])values
+ forKeys:(const uint64_t [])keys
+ count:(NSUInteger)count {
self = [super init];
if (self) {
_dictionary = [[NSMutableDictionary alloc] init];
@@ -6732,7 +6769,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)initWithDictionary:(GPBUInt64DoubleDictionary *)dictionary {
- self = [self initWithValues:NULL forKeys:NULL count:0];
+ self = [self initWithDoubles:NULL forKeys:NULL count:0];
if (self) {
if (dictionary) {
[_dictionary addEntriesFromDictionary:dictionary->_dictionary];
@@ -6743,7 +6780,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
- (instancetype)initWithCapacity:(NSUInteger)numItems {
#pragma unused(numItems)
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithDoubles:NULL forKeys:NULL count:0];
}
- (void)dealloc {
@@ -6758,14 +6795,15 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBUInt64DoubleDictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBUInt64DoubleDictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBUInt64DoubleDictionary class]]) {
return NO;
}
- return [_dictionary isEqual:other->_dictionary];
+ GPBUInt64DoubleDictionary *otherDictionary = other;
+ return [_dictionary isEqual:otherDictionary->_dictionary];
}
- (NSUInteger)hash {
@@ -6780,7 +6818,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return _dictionary.count;
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndDoublesUsingBlock:
(void (^)(uint64_t key, double value, BOOL *stop))block {
[_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
NSNumber *aValue,
@@ -6838,13 +6876,13 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block {
- [self enumerateKeysAndValuesUsingBlock:^(uint64_t key, double value, BOOL *stop) {
+ [self enumerateKeysAndDoublesUsingBlock:^(uint64_t key, double value, BOOL *stop) {
#pragma unused(stop)
block([NSString stringWithFormat:@"%llu", key], [NSString stringWithFormat:@"%.*lg", DBL_DIG, value]);
}];
}
-- (BOOL)valueForKey:(uint64_t)key value:(double *)value {
+- (BOOL)getDouble:(nullable double *)value forKey:(uint64_t)key {
NSNumber *wrapped = [_dictionary objectForKey:@(key)];
if (wrapped && value) {
*value = [wrapped doubleValue];
@@ -6861,14 +6899,14 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)setValue:(double)value forKey:(uint64_t)key {
+- (void)setDouble:(double)value forKey:(uint64_t)key {
[_dictionary setObject:@(value) forKey:@(key)];
if (_autocreator) {
GPBAutocreatedDictionaryModified(_autocreator, self);
}
}
-- (void)removeValueForKey:(uint64_t)aKey {
+- (void)removeDoubleForKey:(uint64_t)aKey {
[_dictionary removeObjectForKey:@(aKey)];
}
@@ -6992,14 +7030,15 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBUInt64EnumDictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBUInt64EnumDictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBUInt64EnumDictionary class]]) {
return NO;
}
- return [_dictionary isEqual:other->_dictionary];
+ GPBUInt64EnumDictionary *otherDictionary = other;
+ return [_dictionary isEqual:otherDictionary->_dictionary];
}
- (NSUInteger)hash {
@@ -7090,7 +7129,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}];
}
-- (BOOL)valueForKey:(uint64_t)key value:(int32_t *)value {
+- (BOOL)getEnum:(int32_t *)value forKey:(uint64_t)key {
NSNumber *wrapped = [_dictionary objectForKey:@(key)];
if (wrapped && value) {
int32_t result = [wrapped intValue];
@@ -7102,7 +7141,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return (wrapped != NULL);
}
-- (BOOL)valueForKey:(uint64_t)key rawValue:(int32_t *)rawValue {
+- (BOOL)getRawValue:(int32_t *)rawValue forKey:(uint64_t)key {
NSNumber *wrapped = [_dictionary objectForKey:@(key)];
if (wrapped && rawValue) {
*rawValue = [wrapped intValue];
@@ -7110,7 +7149,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return (wrapped != NULL);
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndEnumsUsingBlock:
(void (^)(uint64_t key, int32_t value, BOOL *stop))block {
GPBEnumValidationFunc func = _validationFunc;
[_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
@@ -7140,7 +7179,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)removeValueForKey:(uint64_t)aKey {
+- (void)removeEnumForKey:(uint64_t)aKey {
[_dictionary removeObjectForKey:@(aKey)];
}
@@ -7148,7 +7187,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
[_dictionary removeAllObjects];
}
-- (void)setValue:(int32_t)value forKey:(uint64_t)key {
+- (void)setEnum:(int32_t)value forKey:(uint64_t)key {
if (!_validationFunc(value)) {
[NSException raise:NSInvalidArgumentException
format:@"GPBUInt64EnumDictionary: Attempt to set an unknown enum value (%d)",
@@ -7253,14 +7292,15 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBUInt64ObjectDictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBUInt64ObjectDictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBUInt64ObjectDictionary class]]) {
return NO;
}
- return [_dictionary isEqual:other->_dictionary];
+ GPBUInt64ObjectDictionary *otherDictionary = other;
+ return [_dictionary isEqual:otherDictionary->_dictionary];
}
- (NSUInteger)hash {
@@ -7408,24 +7448,24 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
+ (instancetype)dictionary {
- return [[[self alloc] initWithValues:NULL forKeys:NULL count:0] autorelease];
+ return [[[self alloc] initWithUInt32s:NULL forKeys:NULL count:0] autorelease];
}
-+ (instancetype)dictionaryWithValue:(uint32_t)value
- forKey:(int64_t)key {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithUInt32:(uint32_t)value
+ forKey:(int64_t)key {
+ // Cast is needed so the compiler knows what class we are invoking initWithUInt32s:forKeys:count:
// on to get the type correct.
- return [[(GPBInt64UInt32Dictionary*)[self alloc] initWithValues:&value
- forKeys:&key
- count:1] autorelease];
+ return [[(GPBInt64UInt32Dictionary*)[self alloc] initWithUInt32s:&value
+ forKeys:&key
+ count:1] autorelease];
}
-+ (instancetype)dictionaryWithValues:(const uint32_t [])values
- forKeys:(const int64_t [])keys
- count:(NSUInteger)count {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithUInt32s:(const uint32_t [])values
+ forKeys:(const int64_t [])keys
+ count:(NSUInteger)count {
+ // Cast is needed so the compiler knows what class we are invoking initWithUInt32s:forKeys:count:
// on to get the type correct.
- return [[(GPBInt64UInt32Dictionary*)[self alloc] initWithValues:values
+ return [[(GPBInt64UInt32Dictionary*)[self alloc] initWithUInt32s:values
forKeys:keys
count:count] autorelease];
}
@@ -7441,12 +7481,12 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)init {
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithUInt32s:NULL forKeys:NULL count:0];
}
-- (instancetype)initWithValues:(const uint32_t [])values
- forKeys:(const int64_t [])keys
- count:(NSUInteger)count {
+- (instancetype)initWithUInt32s:(const uint32_t [])values
+ forKeys:(const int64_t [])keys
+ count:(NSUInteger)count {
self = [super init];
if (self) {
_dictionary = [[NSMutableDictionary alloc] init];
@@ -7460,7 +7500,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)initWithDictionary:(GPBInt64UInt32Dictionary *)dictionary {
- self = [self initWithValues:NULL forKeys:NULL count:0];
+ self = [self initWithUInt32s:NULL forKeys:NULL count:0];
if (self) {
if (dictionary) {
[_dictionary addEntriesFromDictionary:dictionary->_dictionary];
@@ -7471,7 +7511,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
- (instancetype)initWithCapacity:(NSUInteger)numItems {
#pragma unused(numItems)
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithUInt32s:NULL forKeys:NULL count:0];
}
- (void)dealloc {
@@ -7486,14 +7526,15 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBInt64UInt32Dictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBInt64UInt32Dictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBInt64UInt32Dictionary class]]) {
return NO;
}
- return [_dictionary isEqual:other->_dictionary];
+ GPBInt64UInt32Dictionary *otherDictionary = other;
+ return [_dictionary isEqual:otherDictionary->_dictionary];
}
- (NSUInteger)hash {
@@ -7508,7 +7549,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return _dictionary.count;
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndUInt32sUsingBlock:
(void (^)(int64_t key, uint32_t value, BOOL *stop))block {
[_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
NSNumber *aValue,
@@ -7566,13 +7607,13 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block {
- [self enumerateKeysAndValuesUsingBlock:^(int64_t key, uint32_t value, BOOL *stop) {
+ [self enumerateKeysAndUInt32sUsingBlock:^(int64_t key, uint32_t value, BOOL *stop) {
#pragma unused(stop)
block([NSString stringWithFormat:@"%lld", key], [NSString stringWithFormat:@"%u", value]);
}];
}
-- (BOOL)valueForKey:(int64_t)key value:(uint32_t *)value {
+- (BOOL)getUInt32:(nullable uint32_t *)value forKey:(int64_t)key {
NSNumber *wrapped = [_dictionary objectForKey:@(key)];
if (wrapped && value) {
*value = [wrapped unsignedIntValue];
@@ -7589,14 +7630,14 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)setValue:(uint32_t)value forKey:(int64_t)key {
+- (void)setUInt32:(uint32_t)value forKey:(int64_t)key {
[_dictionary setObject:@(value) forKey:@(key)];
if (_autocreator) {
GPBAutocreatedDictionaryModified(_autocreator, self);
}
}
-- (void)removeValueForKey:(int64_t)aKey {
+- (void)removeUInt32ForKey:(int64_t)aKey {
[_dictionary removeObjectForKey:@(aKey)];
}
@@ -7614,24 +7655,24 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
+ (instancetype)dictionary {
- return [[[self alloc] initWithValues:NULL forKeys:NULL count:0] autorelease];
+ return [[[self alloc] initWithInt32s:NULL forKeys:NULL count:0] autorelease];
}
-+ (instancetype)dictionaryWithValue:(int32_t)value
++ (instancetype)dictionaryWithInt32:(int32_t)value
forKey:(int64_t)key {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
+ // Cast is needed so the compiler knows what class we are invoking initWithInt32s:forKeys:count:
// on to get the type correct.
- return [[(GPBInt64Int32Dictionary*)[self alloc] initWithValues:&value
+ return [[(GPBInt64Int32Dictionary*)[self alloc] initWithInt32s:&value
forKeys:&key
count:1] autorelease];
}
-+ (instancetype)dictionaryWithValues:(const int32_t [])values
++ (instancetype)dictionaryWithInt32s:(const int32_t [])values
forKeys:(const int64_t [])keys
count:(NSUInteger)count {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
+ // Cast is needed so the compiler knows what class we are invoking initWithInt32s:forKeys:count:
// on to get the type correct.
- return [[(GPBInt64Int32Dictionary*)[self alloc] initWithValues:values
+ return [[(GPBInt64Int32Dictionary*)[self alloc] initWithInt32s:values
forKeys:keys
count:count] autorelease];
}
@@ -7647,10 +7688,10 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)init {
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithInt32s:NULL forKeys:NULL count:0];
}
-- (instancetype)initWithValues:(const int32_t [])values
+- (instancetype)initWithInt32s:(const int32_t [])values
forKeys:(const int64_t [])keys
count:(NSUInteger)count {
self = [super init];
@@ -7666,7 +7707,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)initWithDictionary:(GPBInt64Int32Dictionary *)dictionary {
- self = [self initWithValues:NULL forKeys:NULL count:0];
+ self = [self initWithInt32s:NULL forKeys:NULL count:0];
if (self) {
if (dictionary) {
[_dictionary addEntriesFromDictionary:dictionary->_dictionary];
@@ -7677,7 +7718,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
- (instancetype)initWithCapacity:(NSUInteger)numItems {
#pragma unused(numItems)
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithInt32s:NULL forKeys:NULL count:0];
}
- (void)dealloc {
@@ -7692,14 +7733,15 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBInt64Int32Dictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBInt64Int32Dictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBInt64Int32Dictionary class]]) {
return NO;
}
- return [_dictionary isEqual:other->_dictionary];
+ GPBInt64Int32Dictionary *otherDictionary = other;
+ return [_dictionary isEqual:otherDictionary->_dictionary];
}
- (NSUInteger)hash {
@@ -7714,7 +7756,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return _dictionary.count;
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndInt32sUsingBlock:
(void (^)(int64_t key, int32_t value, BOOL *stop))block {
[_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
NSNumber *aValue,
@@ -7772,13 +7814,13 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block {
- [self enumerateKeysAndValuesUsingBlock:^(int64_t key, int32_t value, BOOL *stop) {
+ [self enumerateKeysAndInt32sUsingBlock:^(int64_t key, int32_t value, BOOL *stop) {
#pragma unused(stop)
block([NSString stringWithFormat:@"%lld", key], [NSString stringWithFormat:@"%d", value]);
}];
}
-- (BOOL)valueForKey:(int64_t)key value:(int32_t *)value {
+- (BOOL)getInt32:(nullable int32_t *)value forKey:(int64_t)key {
NSNumber *wrapped = [_dictionary objectForKey:@(key)];
if (wrapped && value) {
*value = [wrapped intValue];
@@ -7795,14 +7837,14 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)setValue:(int32_t)value forKey:(int64_t)key {
+- (void)setInt32:(int32_t)value forKey:(int64_t)key {
[_dictionary setObject:@(value) forKey:@(key)];
if (_autocreator) {
GPBAutocreatedDictionaryModified(_autocreator, self);
}
}
-- (void)removeValueForKey:(int64_t)aKey {
+- (void)removeInt32ForKey:(int64_t)aKey {
[_dictionary removeObjectForKey:@(aKey)];
}
@@ -7820,24 +7862,24 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
+ (instancetype)dictionary {
- return [[[self alloc] initWithValues:NULL forKeys:NULL count:0] autorelease];
+ return [[[self alloc] initWithUInt64s:NULL forKeys:NULL count:0] autorelease];
}
-+ (instancetype)dictionaryWithValue:(uint64_t)value
- forKey:(int64_t)key {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithUInt64:(uint64_t)value
+ forKey:(int64_t)key {
+ // Cast is needed so the compiler knows what class we are invoking initWithUInt64s:forKeys:count:
// on to get the type correct.
- return [[(GPBInt64UInt64Dictionary*)[self alloc] initWithValues:&value
- forKeys:&key
- count:1] autorelease];
+ return [[(GPBInt64UInt64Dictionary*)[self alloc] initWithUInt64s:&value
+ forKeys:&key
+ count:1] autorelease];
}
-+ (instancetype)dictionaryWithValues:(const uint64_t [])values
- forKeys:(const int64_t [])keys
- count:(NSUInteger)count {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithUInt64s:(const uint64_t [])values
+ forKeys:(const int64_t [])keys
+ count:(NSUInteger)count {
+ // Cast is needed so the compiler knows what class we are invoking initWithUInt64s:forKeys:count:
// on to get the type correct.
- return [[(GPBInt64UInt64Dictionary*)[self alloc] initWithValues:values
+ return [[(GPBInt64UInt64Dictionary*)[self alloc] initWithUInt64s:values
forKeys:keys
count:count] autorelease];
}
@@ -7853,12 +7895,12 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)init {
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithUInt64s:NULL forKeys:NULL count:0];
}
-- (instancetype)initWithValues:(const uint64_t [])values
- forKeys:(const int64_t [])keys
- count:(NSUInteger)count {
+- (instancetype)initWithUInt64s:(const uint64_t [])values
+ forKeys:(const int64_t [])keys
+ count:(NSUInteger)count {
self = [super init];
if (self) {
_dictionary = [[NSMutableDictionary alloc] init];
@@ -7872,7 +7914,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)initWithDictionary:(GPBInt64UInt64Dictionary *)dictionary {
- self = [self initWithValues:NULL forKeys:NULL count:0];
+ self = [self initWithUInt64s:NULL forKeys:NULL count:0];
if (self) {
if (dictionary) {
[_dictionary addEntriesFromDictionary:dictionary->_dictionary];
@@ -7883,7 +7925,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
- (instancetype)initWithCapacity:(NSUInteger)numItems {
#pragma unused(numItems)
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithUInt64s:NULL forKeys:NULL count:0];
}
- (void)dealloc {
@@ -7898,14 +7940,15 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBInt64UInt64Dictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBInt64UInt64Dictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBInt64UInt64Dictionary class]]) {
return NO;
}
- return [_dictionary isEqual:other->_dictionary];
+ GPBInt64UInt64Dictionary *otherDictionary = other;
+ return [_dictionary isEqual:otherDictionary->_dictionary];
}
- (NSUInteger)hash {
@@ -7920,7 +7963,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return _dictionary.count;
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndUInt64sUsingBlock:
(void (^)(int64_t key, uint64_t value, BOOL *stop))block {
[_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
NSNumber *aValue,
@@ -7978,13 +8021,13 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block {
- [self enumerateKeysAndValuesUsingBlock:^(int64_t key, uint64_t value, BOOL *stop) {
+ [self enumerateKeysAndUInt64sUsingBlock:^(int64_t key, uint64_t value, BOOL *stop) {
#pragma unused(stop)
block([NSString stringWithFormat:@"%lld", key], [NSString stringWithFormat:@"%llu", value]);
}];
}
-- (BOOL)valueForKey:(int64_t)key value:(uint64_t *)value {
+- (BOOL)getUInt64:(nullable uint64_t *)value forKey:(int64_t)key {
NSNumber *wrapped = [_dictionary objectForKey:@(key)];
if (wrapped && value) {
*value = [wrapped unsignedLongLongValue];
@@ -8001,14 +8044,14 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)setValue:(uint64_t)value forKey:(int64_t)key {
+- (void)setUInt64:(uint64_t)value forKey:(int64_t)key {
[_dictionary setObject:@(value) forKey:@(key)];
if (_autocreator) {
GPBAutocreatedDictionaryModified(_autocreator, self);
}
}
-- (void)removeValueForKey:(int64_t)aKey {
+- (void)removeUInt64ForKey:(int64_t)aKey {
[_dictionary removeObjectForKey:@(aKey)];
}
@@ -8026,24 +8069,24 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
+ (instancetype)dictionary {
- return [[[self alloc] initWithValues:NULL forKeys:NULL count:0] autorelease];
+ return [[[self alloc] initWithInt64s:NULL forKeys:NULL count:0] autorelease];
}
-+ (instancetype)dictionaryWithValue:(int64_t)value
++ (instancetype)dictionaryWithInt64:(int64_t)value
forKey:(int64_t)key {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
+ // Cast is needed so the compiler knows what class we are invoking initWithInt64s:forKeys:count:
// on to get the type correct.
- return [[(GPBInt64Int64Dictionary*)[self alloc] initWithValues:&value
+ return [[(GPBInt64Int64Dictionary*)[self alloc] initWithInt64s:&value
forKeys:&key
count:1] autorelease];
}
-+ (instancetype)dictionaryWithValues:(const int64_t [])values
++ (instancetype)dictionaryWithInt64s:(const int64_t [])values
forKeys:(const int64_t [])keys
count:(NSUInteger)count {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
+ // Cast is needed so the compiler knows what class we are invoking initWithInt64s:forKeys:count:
// on to get the type correct.
- return [[(GPBInt64Int64Dictionary*)[self alloc] initWithValues:values
+ return [[(GPBInt64Int64Dictionary*)[self alloc] initWithInt64s:values
forKeys:keys
count:count] autorelease];
}
@@ -8059,10 +8102,10 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)init {
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithInt64s:NULL forKeys:NULL count:0];
}
-- (instancetype)initWithValues:(const int64_t [])values
+- (instancetype)initWithInt64s:(const int64_t [])values
forKeys:(const int64_t [])keys
count:(NSUInteger)count {
self = [super init];
@@ -8078,7 +8121,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)initWithDictionary:(GPBInt64Int64Dictionary *)dictionary {
- self = [self initWithValues:NULL forKeys:NULL count:0];
+ self = [self initWithInt64s:NULL forKeys:NULL count:0];
if (self) {
if (dictionary) {
[_dictionary addEntriesFromDictionary:dictionary->_dictionary];
@@ -8089,7 +8132,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
- (instancetype)initWithCapacity:(NSUInteger)numItems {
#pragma unused(numItems)
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithInt64s:NULL forKeys:NULL count:0];
}
- (void)dealloc {
@@ -8104,14 +8147,15 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBInt64Int64Dictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBInt64Int64Dictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBInt64Int64Dictionary class]]) {
return NO;
}
- return [_dictionary isEqual:other->_dictionary];
+ GPBInt64Int64Dictionary *otherDictionary = other;
+ return [_dictionary isEqual:otherDictionary->_dictionary];
}
- (NSUInteger)hash {
@@ -8126,7 +8170,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return _dictionary.count;
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndInt64sUsingBlock:
(void (^)(int64_t key, int64_t value, BOOL *stop))block {
[_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
NSNumber *aValue,
@@ -8184,13 +8228,13 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block {
- [self enumerateKeysAndValuesUsingBlock:^(int64_t key, int64_t value, BOOL *stop) {
+ [self enumerateKeysAndInt64sUsingBlock:^(int64_t key, int64_t value, BOOL *stop) {
#pragma unused(stop)
block([NSString stringWithFormat:@"%lld", key], [NSString stringWithFormat:@"%lld", value]);
}];
}
-- (BOOL)valueForKey:(int64_t)key value:(int64_t *)value {
+- (BOOL)getInt64:(nullable int64_t *)value forKey:(int64_t)key {
NSNumber *wrapped = [_dictionary objectForKey:@(key)];
if (wrapped && value) {
*value = [wrapped longLongValue];
@@ -8207,14 +8251,14 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)setValue:(int64_t)value forKey:(int64_t)key {
+- (void)setInt64:(int64_t)value forKey:(int64_t)key {
[_dictionary setObject:@(value) forKey:@(key)];
if (_autocreator) {
GPBAutocreatedDictionaryModified(_autocreator, self);
}
}
-- (void)removeValueForKey:(int64_t)aKey {
+- (void)removeInt64ForKey:(int64_t)aKey {
[_dictionary removeObjectForKey:@(aKey)];
}
@@ -8232,24 +8276,24 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
+ (instancetype)dictionary {
- return [[[self alloc] initWithValues:NULL forKeys:NULL count:0] autorelease];
+ return [[[self alloc] initWithBools:NULL forKeys:NULL count:0] autorelease];
}
-+ (instancetype)dictionaryWithValue:(BOOL)value
- forKey:(int64_t)key {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithBool:(BOOL)value
+ forKey:(int64_t)key {
+ // Cast is needed so the compiler knows what class we are invoking initWithBools:forKeys:count:
// on to get the type correct.
- return [[(GPBInt64BoolDictionary*)[self alloc] initWithValues:&value
- forKeys:&key
- count:1] autorelease];
+ return [[(GPBInt64BoolDictionary*)[self alloc] initWithBools:&value
+ forKeys:&key
+ count:1] autorelease];
}
-+ (instancetype)dictionaryWithValues:(const BOOL [])values
- forKeys:(const int64_t [])keys
- count:(NSUInteger)count {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithBools:(const BOOL [])values
+ forKeys:(const int64_t [])keys
+ count:(NSUInteger)count {
+ // Cast is needed so the compiler knows what class we are invoking initWithBools:forKeys:count:
// on to get the type correct.
- return [[(GPBInt64BoolDictionary*)[self alloc] initWithValues:values
+ return [[(GPBInt64BoolDictionary*)[self alloc] initWithBools:values
forKeys:keys
count:count] autorelease];
}
@@ -8265,12 +8309,12 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)init {
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithBools:NULL forKeys:NULL count:0];
}
-- (instancetype)initWithValues:(const BOOL [])values
- forKeys:(const int64_t [])keys
- count:(NSUInteger)count {
+- (instancetype)initWithBools:(const BOOL [])values
+ forKeys:(const int64_t [])keys
+ count:(NSUInteger)count {
self = [super init];
if (self) {
_dictionary = [[NSMutableDictionary alloc] init];
@@ -8284,7 +8328,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)initWithDictionary:(GPBInt64BoolDictionary *)dictionary {
- self = [self initWithValues:NULL forKeys:NULL count:0];
+ self = [self initWithBools:NULL forKeys:NULL count:0];
if (self) {
if (dictionary) {
[_dictionary addEntriesFromDictionary:dictionary->_dictionary];
@@ -8295,7 +8339,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
- (instancetype)initWithCapacity:(NSUInteger)numItems {
#pragma unused(numItems)
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithBools:NULL forKeys:NULL count:0];
}
- (void)dealloc {
@@ -8310,14 +8354,15 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBInt64BoolDictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBInt64BoolDictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBInt64BoolDictionary class]]) {
return NO;
}
- return [_dictionary isEqual:other->_dictionary];
+ GPBInt64BoolDictionary *otherDictionary = other;
+ return [_dictionary isEqual:otherDictionary->_dictionary];
}
- (NSUInteger)hash {
@@ -8332,7 +8377,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return _dictionary.count;
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndBoolsUsingBlock:
(void (^)(int64_t key, BOOL value, BOOL *stop))block {
[_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
NSNumber *aValue,
@@ -8390,13 +8435,13 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block {
- [self enumerateKeysAndValuesUsingBlock:^(int64_t key, BOOL value, BOOL *stop) {
+ [self enumerateKeysAndBoolsUsingBlock:^(int64_t key, BOOL value, BOOL *stop) {
#pragma unused(stop)
block([NSString stringWithFormat:@"%lld", key], (value ? @"true" : @"false"));
}];
}
-- (BOOL)valueForKey:(int64_t)key value:(BOOL *)value {
+- (BOOL)getBool:(nullable BOOL *)value forKey:(int64_t)key {
NSNumber *wrapped = [_dictionary objectForKey:@(key)];
if (wrapped && value) {
*value = [wrapped boolValue];
@@ -8413,14 +8458,14 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)setValue:(BOOL)value forKey:(int64_t)key {
+- (void)setBool:(BOOL)value forKey:(int64_t)key {
[_dictionary setObject:@(value) forKey:@(key)];
if (_autocreator) {
GPBAutocreatedDictionaryModified(_autocreator, self);
}
}
-- (void)removeValueForKey:(int64_t)aKey {
+- (void)removeBoolForKey:(int64_t)aKey {
[_dictionary removeObjectForKey:@(aKey)];
}
@@ -8438,24 +8483,24 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
+ (instancetype)dictionary {
- return [[[self alloc] initWithValues:NULL forKeys:NULL count:0] autorelease];
+ return [[[self alloc] initWithFloats:NULL forKeys:NULL count:0] autorelease];
}
-+ (instancetype)dictionaryWithValue:(float)value
++ (instancetype)dictionaryWithFloat:(float)value
forKey:(int64_t)key {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
+ // Cast is needed so the compiler knows what class we are invoking initWithFloats:forKeys:count:
// on to get the type correct.
- return [[(GPBInt64FloatDictionary*)[self alloc] initWithValues:&value
+ return [[(GPBInt64FloatDictionary*)[self alloc] initWithFloats:&value
forKeys:&key
count:1] autorelease];
}
-+ (instancetype)dictionaryWithValues:(const float [])values
++ (instancetype)dictionaryWithFloats:(const float [])values
forKeys:(const int64_t [])keys
count:(NSUInteger)count {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
+ // Cast is needed so the compiler knows what class we are invoking initWithFloats:forKeys:count:
// on to get the type correct.
- return [[(GPBInt64FloatDictionary*)[self alloc] initWithValues:values
+ return [[(GPBInt64FloatDictionary*)[self alloc] initWithFloats:values
forKeys:keys
count:count] autorelease];
}
@@ -8471,10 +8516,10 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)init {
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithFloats:NULL forKeys:NULL count:0];
}
-- (instancetype)initWithValues:(const float [])values
+- (instancetype)initWithFloats:(const float [])values
forKeys:(const int64_t [])keys
count:(NSUInteger)count {
self = [super init];
@@ -8490,7 +8535,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)initWithDictionary:(GPBInt64FloatDictionary *)dictionary {
- self = [self initWithValues:NULL forKeys:NULL count:0];
+ self = [self initWithFloats:NULL forKeys:NULL count:0];
if (self) {
if (dictionary) {
[_dictionary addEntriesFromDictionary:dictionary->_dictionary];
@@ -8501,7 +8546,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
- (instancetype)initWithCapacity:(NSUInteger)numItems {
#pragma unused(numItems)
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithFloats:NULL forKeys:NULL count:0];
}
- (void)dealloc {
@@ -8516,14 +8561,15 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBInt64FloatDictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBInt64FloatDictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBInt64FloatDictionary class]]) {
return NO;
}
- return [_dictionary isEqual:other->_dictionary];
+ GPBInt64FloatDictionary *otherDictionary = other;
+ return [_dictionary isEqual:otherDictionary->_dictionary];
}
- (NSUInteger)hash {
@@ -8538,7 +8584,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return _dictionary.count;
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndFloatsUsingBlock:
(void (^)(int64_t key, float value, BOOL *stop))block {
[_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
NSNumber *aValue,
@@ -8596,13 +8642,13 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block {
- [self enumerateKeysAndValuesUsingBlock:^(int64_t key, float value, BOOL *stop) {
+ [self enumerateKeysAndFloatsUsingBlock:^(int64_t key, float value, BOOL *stop) {
#pragma unused(stop)
block([NSString stringWithFormat:@"%lld", key], [NSString stringWithFormat:@"%.*g", FLT_DIG, value]);
}];
}
-- (BOOL)valueForKey:(int64_t)key value:(float *)value {
+- (BOOL)getFloat:(nullable float *)value forKey:(int64_t)key {
NSNumber *wrapped = [_dictionary objectForKey:@(key)];
if (wrapped && value) {
*value = [wrapped floatValue];
@@ -8619,14 +8665,14 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)setValue:(float)value forKey:(int64_t)key {
+- (void)setFloat:(float)value forKey:(int64_t)key {
[_dictionary setObject:@(value) forKey:@(key)];
if (_autocreator) {
GPBAutocreatedDictionaryModified(_autocreator, self);
}
}
-- (void)removeValueForKey:(int64_t)aKey {
+- (void)removeFloatForKey:(int64_t)aKey {
[_dictionary removeObjectForKey:@(aKey)];
}
@@ -8644,24 +8690,24 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
+ (instancetype)dictionary {
- return [[[self alloc] initWithValues:NULL forKeys:NULL count:0] autorelease];
+ return [[[self alloc] initWithDoubles:NULL forKeys:NULL count:0] autorelease];
}
-+ (instancetype)dictionaryWithValue:(double)value
- forKey:(int64_t)key {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithDouble:(double)value
+ forKey:(int64_t)key {
+ // Cast is needed so the compiler knows what class we are invoking initWithDoubles:forKeys:count:
// on to get the type correct.
- return [[(GPBInt64DoubleDictionary*)[self alloc] initWithValues:&value
- forKeys:&key
- count:1] autorelease];
+ return [[(GPBInt64DoubleDictionary*)[self alloc] initWithDoubles:&value
+ forKeys:&key
+ count:1] autorelease];
}
-+ (instancetype)dictionaryWithValues:(const double [])values
- forKeys:(const int64_t [])keys
- count:(NSUInteger)count {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithDoubles:(const double [])values
+ forKeys:(const int64_t [])keys
+ count:(NSUInteger)count {
+ // Cast is needed so the compiler knows what class we are invoking initWithDoubles:forKeys:count:
// on to get the type correct.
- return [[(GPBInt64DoubleDictionary*)[self alloc] initWithValues:values
+ return [[(GPBInt64DoubleDictionary*)[self alloc] initWithDoubles:values
forKeys:keys
count:count] autorelease];
}
@@ -8677,12 +8723,12 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)init {
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithDoubles:NULL forKeys:NULL count:0];
}
-- (instancetype)initWithValues:(const double [])values
- forKeys:(const int64_t [])keys
- count:(NSUInteger)count {
+- (instancetype)initWithDoubles:(const double [])values
+ forKeys:(const int64_t [])keys
+ count:(NSUInteger)count {
self = [super init];
if (self) {
_dictionary = [[NSMutableDictionary alloc] init];
@@ -8696,7 +8742,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)initWithDictionary:(GPBInt64DoubleDictionary *)dictionary {
- self = [self initWithValues:NULL forKeys:NULL count:0];
+ self = [self initWithDoubles:NULL forKeys:NULL count:0];
if (self) {
if (dictionary) {
[_dictionary addEntriesFromDictionary:dictionary->_dictionary];
@@ -8707,7 +8753,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
- (instancetype)initWithCapacity:(NSUInteger)numItems {
#pragma unused(numItems)
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithDoubles:NULL forKeys:NULL count:0];
}
- (void)dealloc {
@@ -8722,14 +8768,15 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBInt64DoubleDictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBInt64DoubleDictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBInt64DoubleDictionary class]]) {
return NO;
}
- return [_dictionary isEqual:other->_dictionary];
+ GPBInt64DoubleDictionary *otherDictionary = other;
+ return [_dictionary isEqual:otherDictionary->_dictionary];
}
- (NSUInteger)hash {
@@ -8744,7 +8791,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return _dictionary.count;
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndDoublesUsingBlock:
(void (^)(int64_t key, double value, BOOL *stop))block {
[_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
NSNumber *aValue,
@@ -8802,13 +8849,13 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block {
- [self enumerateKeysAndValuesUsingBlock:^(int64_t key, double value, BOOL *stop) {
+ [self enumerateKeysAndDoublesUsingBlock:^(int64_t key, double value, BOOL *stop) {
#pragma unused(stop)
block([NSString stringWithFormat:@"%lld", key], [NSString stringWithFormat:@"%.*lg", DBL_DIG, value]);
}];
}
-- (BOOL)valueForKey:(int64_t)key value:(double *)value {
+- (BOOL)getDouble:(nullable double *)value forKey:(int64_t)key {
NSNumber *wrapped = [_dictionary objectForKey:@(key)];
if (wrapped && value) {
*value = [wrapped doubleValue];
@@ -8825,14 +8872,14 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)setValue:(double)value forKey:(int64_t)key {
+- (void)setDouble:(double)value forKey:(int64_t)key {
[_dictionary setObject:@(value) forKey:@(key)];
if (_autocreator) {
GPBAutocreatedDictionaryModified(_autocreator, self);
}
}
-- (void)removeValueForKey:(int64_t)aKey {
+- (void)removeDoubleForKey:(int64_t)aKey {
[_dictionary removeObjectForKey:@(aKey)];
}
@@ -8956,14 +9003,15 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBInt64EnumDictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBInt64EnumDictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBInt64EnumDictionary class]]) {
return NO;
}
- return [_dictionary isEqual:other->_dictionary];
+ GPBInt64EnumDictionary *otherDictionary = other;
+ return [_dictionary isEqual:otherDictionary->_dictionary];
}
- (NSUInteger)hash {
@@ -9054,7 +9102,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}];
}
-- (BOOL)valueForKey:(int64_t)key value:(int32_t *)value {
+- (BOOL)getEnum:(int32_t *)value forKey:(int64_t)key {
NSNumber *wrapped = [_dictionary objectForKey:@(key)];
if (wrapped && value) {
int32_t result = [wrapped intValue];
@@ -9066,7 +9114,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return (wrapped != NULL);
}
-- (BOOL)valueForKey:(int64_t)key rawValue:(int32_t *)rawValue {
+- (BOOL)getRawValue:(int32_t *)rawValue forKey:(int64_t)key {
NSNumber *wrapped = [_dictionary objectForKey:@(key)];
if (wrapped && rawValue) {
*rawValue = [wrapped intValue];
@@ -9074,7 +9122,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return (wrapped != NULL);
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndEnumsUsingBlock:
(void (^)(int64_t key, int32_t value, BOOL *stop))block {
GPBEnumValidationFunc func = _validationFunc;
[_dictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *aKey,
@@ -9104,7 +9152,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)removeValueForKey:(int64_t)aKey {
+- (void)removeEnumForKey:(int64_t)aKey {
[_dictionary removeObjectForKey:@(aKey)];
}
@@ -9112,7 +9160,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
[_dictionary removeAllObjects];
}
-- (void)setValue:(int32_t)value forKey:(int64_t)key {
+- (void)setEnum:(int32_t)value forKey:(int64_t)key {
if (!_validationFunc(value)) {
[NSException raise:NSInvalidArgumentException
format:@"GPBInt64EnumDictionary: Attempt to set an unknown enum value (%d)",
@@ -9217,14 +9265,15 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBInt64ObjectDictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBInt64ObjectDictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBInt64ObjectDictionary class]]) {
return NO;
}
- return [_dictionary isEqual:other->_dictionary];
+ GPBInt64ObjectDictionary *otherDictionary = other;
+ return [_dictionary isEqual:otherDictionary->_dictionary];
}
- (NSUInteger)hash {
@@ -9372,24 +9421,24 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
+ (instancetype)dictionary {
- return [[[self alloc] initWithValues:NULL forKeys:NULL count:0] autorelease];
+ return [[[self alloc] initWithUInt32s:NULL forKeys:NULL count:0] autorelease];
}
-+ (instancetype)dictionaryWithValue:(uint32_t)value
- forKey:(NSString *)key {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithUInt32:(uint32_t)value
+ forKey:(NSString *)key {
+ // Cast is needed so the compiler knows what class we are invoking initWithUInt32s:forKeys:count:
// on to get the type correct.
- return [[(GPBStringUInt32Dictionary*)[self alloc] initWithValues:&value
- forKeys:&key
- count:1] autorelease];
+ return [[(GPBStringUInt32Dictionary*)[self alloc] initWithUInt32s:&value
+ forKeys:&key
+ count:1] autorelease];
}
-+ (instancetype)dictionaryWithValues:(const uint32_t [])values
- forKeys:(const NSString * [])keys
- count:(NSUInteger)count {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithUInt32s:(const uint32_t [])values
+ forKeys:(const NSString * [])keys
+ count:(NSUInteger)count {
+ // Cast is needed so the compiler knows what class we are invoking initWithUInt32s:forKeys:count:
// on to get the type correct.
- return [[(GPBStringUInt32Dictionary*)[self alloc] initWithValues:values
+ return [[(GPBStringUInt32Dictionary*)[self alloc] initWithUInt32s:values
forKeys:keys
count:count] autorelease];
}
@@ -9405,12 +9454,12 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)init {
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithUInt32s:NULL forKeys:NULL count:0];
}
-- (instancetype)initWithValues:(const uint32_t [])values
- forKeys:(const NSString * [])keys
- count:(NSUInteger)count {
+- (instancetype)initWithUInt32s:(const uint32_t [])values
+ forKeys:(const NSString * [])keys
+ count:(NSUInteger)count {
self = [super init];
if (self) {
_dictionary = [[NSMutableDictionary alloc] init];
@@ -9428,7 +9477,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)initWithDictionary:(GPBStringUInt32Dictionary *)dictionary {
- self = [self initWithValues:NULL forKeys:NULL count:0];
+ self = [self initWithUInt32s:NULL forKeys:NULL count:0];
if (self) {
if (dictionary) {
[_dictionary addEntriesFromDictionary:dictionary->_dictionary];
@@ -9439,7 +9488,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
- (instancetype)initWithCapacity:(NSUInteger)numItems {
#pragma unused(numItems)
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithUInt32s:NULL forKeys:NULL count:0];
}
- (void)dealloc {
@@ -9454,14 +9503,15 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBStringUInt32Dictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBStringUInt32Dictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBStringUInt32Dictionary class]]) {
return NO;
}
- return [_dictionary isEqual:other->_dictionary];
+ GPBStringUInt32Dictionary *otherDictionary = other;
+ return [_dictionary isEqual:otherDictionary->_dictionary];
}
- (NSUInteger)hash {
@@ -9476,7 +9526,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return _dictionary.count;
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndUInt32sUsingBlock:
(void (^)(NSString *key, uint32_t value, BOOL *stop))block {
[_dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *aKey,
NSNumber *aValue,
@@ -9534,13 +9584,13 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block {
- [self enumerateKeysAndValuesUsingBlock:^(NSString *key, uint32_t value, BOOL *stop) {
+ [self enumerateKeysAndUInt32sUsingBlock:^(NSString *key, uint32_t value, BOOL *stop) {
#pragma unused(stop)
block(key, [NSString stringWithFormat:@"%u", value]);
}];
}
-- (BOOL)valueForKey:(NSString *)key value:(uint32_t *)value {
+- (BOOL)getUInt32:(nullable uint32_t *)value forKey:(NSString *)key {
NSNumber *wrapped = [_dictionary objectForKey:key];
if (wrapped && value) {
*value = [wrapped unsignedIntValue];
@@ -9557,7 +9607,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)setValue:(uint32_t)value forKey:(NSString *)key {
+- (void)setUInt32:(uint32_t)value forKey:(NSString *)key {
if (!key) {
[NSException raise:NSInvalidArgumentException
format:@"Attempting to add nil key to a Dictionary"];
@@ -9568,7 +9618,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)removeValueForKey:(NSString *)aKey {
+- (void)removeUInt32ForKey:(NSString *)aKey {
[_dictionary removeObjectForKey:aKey];
}
@@ -9586,24 +9636,24 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
+ (instancetype)dictionary {
- return [[[self alloc] initWithValues:NULL forKeys:NULL count:0] autorelease];
+ return [[[self alloc] initWithInt32s:NULL forKeys:NULL count:0] autorelease];
}
-+ (instancetype)dictionaryWithValue:(int32_t)value
++ (instancetype)dictionaryWithInt32:(int32_t)value
forKey:(NSString *)key {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
+ // Cast is needed so the compiler knows what class we are invoking initWithInt32s:forKeys:count:
// on to get the type correct.
- return [[(GPBStringInt32Dictionary*)[self alloc] initWithValues:&value
+ return [[(GPBStringInt32Dictionary*)[self alloc] initWithInt32s:&value
forKeys:&key
count:1] autorelease];
}
-+ (instancetype)dictionaryWithValues:(const int32_t [])values
++ (instancetype)dictionaryWithInt32s:(const int32_t [])values
forKeys:(const NSString * [])keys
count:(NSUInteger)count {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
+ // Cast is needed so the compiler knows what class we are invoking initWithInt32s:forKeys:count:
// on to get the type correct.
- return [[(GPBStringInt32Dictionary*)[self alloc] initWithValues:values
+ return [[(GPBStringInt32Dictionary*)[self alloc] initWithInt32s:values
forKeys:keys
count:count] autorelease];
}
@@ -9619,10 +9669,10 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)init {
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithInt32s:NULL forKeys:NULL count:0];
}
-- (instancetype)initWithValues:(const int32_t [])values
+- (instancetype)initWithInt32s:(const int32_t [])values
forKeys:(const NSString * [])keys
count:(NSUInteger)count {
self = [super init];
@@ -9642,7 +9692,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)initWithDictionary:(GPBStringInt32Dictionary *)dictionary {
- self = [self initWithValues:NULL forKeys:NULL count:0];
+ self = [self initWithInt32s:NULL forKeys:NULL count:0];
if (self) {
if (dictionary) {
[_dictionary addEntriesFromDictionary:dictionary->_dictionary];
@@ -9653,7 +9703,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
- (instancetype)initWithCapacity:(NSUInteger)numItems {
#pragma unused(numItems)
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithInt32s:NULL forKeys:NULL count:0];
}
- (void)dealloc {
@@ -9668,14 +9718,15 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBStringInt32Dictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBStringInt32Dictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBStringInt32Dictionary class]]) {
return NO;
}
- return [_dictionary isEqual:other->_dictionary];
+ GPBStringInt32Dictionary *otherDictionary = other;
+ return [_dictionary isEqual:otherDictionary->_dictionary];
}
- (NSUInteger)hash {
@@ -9690,7 +9741,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return _dictionary.count;
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndInt32sUsingBlock:
(void (^)(NSString *key, int32_t value, BOOL *stop))block {
[_dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *aKey,
NSNumber *aValue,
@@ -9748,13 +9799,13 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block {
- [self enumerateKeysAndValuesUsingBlock:^(NSString *key, int32_t value, BOOL *stop) {
+ [self enumerateKeysAndInt32sUsingBlock:^(NSString *key, int32_t value, BOOL *stop) {
#pragma unused(stop)
block(key, [NSString stringWithFormat:@"%d", value]);
}];
}
-- (BOOL)valueForKey:(NSString *)key value:(int32_t *)value {
+- (BOOL)getInt32:(nullable int32_t *)value forKey:(NSString *)key {
NSNumber *wrapped = [_dictionary objectForKey:key];
if (wrapped && value) {
*value = [wrapped intValue];
@@ -9771,7 +9822,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)setValue:(int32_t)value forKey:(NSString *)key {
+- (void)setInt32:(int32_t)value forKey:(NSString *)key {
if (!key) {
[NSException raise:NSInvalidArgumentException
format:@"Attempting to add nil key to a Dictionary"];
@@ -9782,7 +9833,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)removeValueForKey:(NSString *)aKey {
+- (void)removeInt32ForKey:(NSString *)aKey {
[_dictionary removeObjectForKey:aKey];
}
@@ -9800,24 +9851,24 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
+ (instancetype)dictionary {
- return [[[self alloc] initWithValues:NULL forKeys:NULL count:0] autorelease];
+ return [[[self alloc] initWithUInt64s:NULL forKeys:NULL count:0] autorelease];
}
-+ (instancetype)dictionaryWithValue:(uint64_t)value
- forKey:(NSString *)key {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithUInt64:(uint64_t)value
+ forKey:(NSString *)key {
+ // Cast is needed so the compiler knows what class we are invoking initWithUInt64s:forKeys:count:
// on to get the type correct.
- return [[(GPBStringUInt64Dictionary*)[self alloc] initWithValues:&value
- forKeys:&key
- count:1] autorelease];
+ return [[(GPBStringUInt64Dictionary*)[self alloc] initWithUInt64s:&value
+ forKeys:&key
+ count:1] autorelease];
}
-+ (instancetype)dictionaryWithValues:(const uint64_t [])values
- forKeys:(const NSString * [])keys
- count:(NSUInteger)count {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithUInt64s:(const uint64_t [])values
+ forKeys:(const NSString * [])keys
+ count:(NSUInteger)count {
+ // Cast is needed so the compiler knows what class we are invoking initWithUInt64s:forKeys:count:
// on to get the type correct.
- return [[(GPBStringUInt64Dictionary*)[self alloc] initWithValues:values
+ return [[(GPBStringUInt64Dictionary*)[self alloc] initWithUInt64s:values
forKeys:keys
count:count] autorelease];
}
@@ -9833,12 +9884,12 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)init {
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithUInt64s:NULL forKeys:NULL count:0];
}
-- (instancetype)initWithValues:(const uint64_t [])values
- forKeys:(const NSString * [])keys
- count:(NSUInteger)count {
+- (instancetype)initWithUInt64s:(const uint64_t [])values
+ forKeys:(const NSString * [])keys
+ count:(NSUInteger)count {
self = [super init];
if (self) {
_dictionary = [[NSMutableDictionary alloc] init];
@@ -9856,7 +9907,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)initWithDictionary:(GPBStringUInt64Dictionary *)dictionary {
- self = [self initWithValues:NULL forKeys:NULL count:0];
+ self = [self initWithUInt64s:NULL forKeys:NULL count:0];
if (self) {
if (dictionary) {
[_dictionary addEntriesFromDictionary:dictionary->_dictionary];
@@ -9867,7 +9918,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
- (instancetype)initWithCapacity:(NSUInteger)numItems {
#pragma unused(numItems)
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithUInt64s:NULL forKeys:NULL count:0];
}
- (void)dealloc {
@@ -9882,14 +9933,15 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBStringUInt64Dictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBStringUInt64Dictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBStringUInt64Dictionary class]]) {
return NO;
}
- return [_dictionary isEqual:other->_dictionary];
+ GPBStringUInt64Dictionary *otherDictionary = other;
+ return [_dictionary isEqual:otherDictionary->_dictionary];
}
- (NSUInteger)hash {
@@ -9904,7 +9956,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return _dictionary.count;
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndUInt64sUsingBlock:
(void (^)(NSString *key, uint64_t value, BOOL *stop))block {
[_dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *aKey,
NSNumber *aValue,
@@ -9962,13 +10014,13 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block {
- [self enumerateKeysAndValuesUsingBlock:^(NSString *key, uint64_t value, BOOL *stop) {
+ [self enumerateKeysAndUInt64sUsingBlock:^(NSString *key, uint64_t value, BOOL *stop) {
#pragma unused(stop)
block(key, [NSString stringWithFormat:@"%llu", value]);
}];
}
-- (BOOL)valueForKey:(NSString *)key value:(uint64_t *)value {
+- (BOOL)getUInt64:(nullable uint64_t *)value forKey:(NSString *)key {
NSNumber *wrapped = [_dictionary objectForKey:key];
if (wrapped && value) {
*value = [wrapped unsignedLongLongValue];
@@ -9985,7 +10037,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)setValue:(uint64_t)value forKey:(NSString *)key {
+- (void)setUInt64:(uint64_t)value forKey:(NSString *)key {
if (!key) {
[NSException raise:NSInvalidArgumentException
format:@"Attempting to add nil key to a Dictionary"];
@@ -9996,7 +10048,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)removeValueForKey:(NSString *)aKey {
+- (void)removeUInt64ForKey:(NSString *)aKey {
[_dictionary removeObjectForKey:aKey];
}
@@ -10014,24 +10066,24 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
+ (instancetype)dictionary {
- return [[[self alloc] initWithValues:NULL forKeys:NULL count:0] autorelease];
+ return [[[self alloc] initWithInt64s:NULL forKeys:NULL count:0] autorelease];
}
-+ (instancetype)dictionaryWithValue:(int64_t)value
++ (instancetype)dictionaryWithInt64:(int64_t)value
forKey:(NSString *)key {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
+ // Cast is needed so the compiler knows what class we are invoking initWithInt64s:forKeys:count:
// on to get the type correct.
- return [[(GPBStringInt64Dictionary*)[self alloc] initWithValues:&value
+ return [[(GPBStringInt64Dictionary*)[self alloc] initWithInt64s:&value
forKeys:&key
count:1] autorelease];
}
-+ (instancetype)dictionaryWithValues:(const int64_t [])values
++ (instancetype)dictionaryWithInt64s:(const int64_t [])values
forKeys:(const NSString * [])keys
count:(NSUInteger)count {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
+ // Cast is needed so the compiler knows what class we are invoking initWithInt64s:forKeys:count:
// on to get the type correct.
- return [[(GPBStringInt64Dictionary*)[self alloc] initWithValues:values
+ return [[(GPBStringInt64Dictionary*)[self alloc] initWithInt64s:values
forKeys:keys
count:count] autorelease];
}
@@ -10047,10 +10099,10 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)init {
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithInt64s:NULL forKeys:NULL count:0];
}
-- (instancetype)initWithValues:(const int64_t [])values
+- (instancetype)initWithInt64s:(const int64_t [])values
forKeys:(const NSString * [])keys
count:(NSUInteger)count {
self = [super init];
@@ -10070,7 +10122,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)initWithDictionary:(GPBStringInt64Dictionary *)dictionary {
- self = [self initWithValues:NULL forKeys:NULL count:0];
+ self = [self initWithInt64s:NULL forKeys:NULL count:0];
if (self) {
if (dictionary) {
[_dictionary addEntriesFromDictionary:dictionary->_dictionary];
@@ -10081,7 +10133,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
- (instancetype)initWithCapacity:(NSUInteger)numItems {
#pragma unused(numItems)
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithInt64s:NULL forKeys:NULL count:0];
}
- (void)dealloc {
@@ -10096,14 +10148,15 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBStringInt64Dictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBStringInt64Dictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBStringInt64Dictionary class]]) {
return NO;
}
- return [_dictionary isEqual:other->_dictionary];
+ GPBStringInt64Dictionary *otherDictionary = other;
+ return [_dictionary isEqual:otherDictionary->_dictionary];
}
- (NSUInteger)hash {
@@ -10118,7 +10171,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return _dictionary.count;
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndInt64sUsingBlock:
(void (^)(NSString *key, int64_t value, BOOL *stop))block {
[_dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *aKey,
NSNumber *aValue,
@@ -10176,13 +10229,13 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block {
- [self enumerateKeysAndValuesUsingBlock:^(NSString *key, int64_t value, BOOL *stop) {
+ [self enumerateKeysAndInt64sUsingBlock:^(NSString *key, int64_t value, BOOL *stop) {
#pragma unused(stop)
block(key, [NSString stringWithFormat:@"%lld", value]);
}];
}
-- (BOOL)valueForKey:(NSString *)key value:(int64_t *)value {
+- (BOOL)getInt64:(nullable int64_t *)value forKey:(NSString *)key {
NSNumber *wrapped = [_dictionary objectForKey:key];
if (wrapped && value) {
*value = [wrapped longLongValue];
@@ -10199,7 +10252,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)setValue:(int64_t)value forKey:(NSString *)key {
+- (void)setInt64:(int64_t)value forKey:(NSString *)key {
if (!key) {
[NSException raise:NSInvalidArgumentException
format:@"Attempting to add nil key to a Dictionary"];
@@ -10210,7 +10263,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)removeValueForKey:(NSString *)aKey {
+- (void)removeInt64ForKey:(NSString *)aKey {
[_dictionary removeObjectForKey:aKey];
}
@@ -10228,24 +10281,24 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
+ (instancetype)dictionary {
- return [[[self alloc] initWithValues:NULL forKeys:NULL count:0] autorelease];
+ return [[[self alloc] initWithBools:NULL forKeys:NULL count:0] autorelease];
}
-+ (instancetype)dictionaryWithValue:(BOOL)value
- forKey:(NSString *)key {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithBool:(BOOL)value
+ forKey:(NSString *)key {
+ // Cast is needed so the compiler knows what class we are invoking initWithBools:forKeys:count:
// on to get the type correct.
- return [[(GPBStringBoolDictionary*)[self alloc] initWithValues:&value
- forKeys:&key
- count:1] autorelease];
+ return [[(GPBStringBoolDictionary*)[self alloc] initWithBools:&value
+ forKeys:&key
+ count:1] autorelease];
}
-+ (instancetype)dictionaryWithValues:(const BOOL [])values
- forKeys:(const NSString * [])keys
- count:(NSUInteger)count {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithBools:(const BOOL [])values
+ forKeys:(const NSString * [])keys
+ count:(NSUInteger)count {
+ // Cast is needed so the compiler knows what class we are invoking initWithBools:forKeys:count:
// on to get the type correct.
- return [[(GPBStringBoolDictionary*)[self alloc] initWithValues:values
+ return [[(GPBStringBoolDictionary*)[self alloc] initWithBools:values
forKeys:keys
count:count] autorelease];
}
@@ -10261,12 +10314,12 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)init {
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithBools:NULL forKeys:NULL count:0];
}
-- (instancetype)initWithValues:(const BOOL [])values
- forKeys:(const NSString * [])keys
- count:(NSUInteger)count {
+- (instancetype)initWithBools:(const BOOL [])values
+ forKeys:(const NSString * [])keys
+ count:(NSUInteger)count {
self = [super init];
if (self) {
_dictionary = [[NSMutableDictionary alloc] init];
@@ -10284,7 +10337,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)initWithDictionary:(GPBStringBoolDictionary *)dictionary {
- self = [self initWithValues:NULL forKeys:NULL count:0];
+ self = [self initWithBools:NULL forKeys:NULL count:0];
if (self) {
if (dictionary) {
[_dictionary addEntriesFromDictionary:dictionary->_dictionary];
@@ -10295,7 +10348,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
- (instancetype)initWithCapacity:(NSUInteger)numItems {
#pragma unused(numItems)
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithBools:NULL forKeys:NULL count:0];
}
- (void)dealloc {
@@ -10310,14 +10363,15 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBStringBoolDictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBStringBoolDictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBStringBoolDictionary class]]) {
return NO;
}
- return [_dictionary isEqual:other->_dictionary];
+ GPBStringBoolDictionary *otherDictionary = other;
+ return [_dictionary isEqual:otherDictionary->_dictionary];
}
- (NSUInteger)hash {
@@ -10332,7 +10386,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return _dictionary.count;
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndBoolsUsingBlock:
(void (^)(NSString *key, BOOL value, BOOL *stop))block {
[_dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *aKey,
NSNumber *aValue,
@@ -10390,13 +10444,13 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block {
- [self enumerateKeysAndValuesUsingBlock:^(NSString *key, BOOL value, BOOL *stop) {
+ [self enumerateKeysAndBoolsUsingBlock:^(NSString *key, BOOL value, BOOL *stop) {
#pragma unused(stop)
block(key, (value ? @"true" : @"false"));
}];
}
-- (BOOL)valueForKey:(NSString *)key value:(BOOL *)value {
+- (BOOL)getBool:(nullable BOOL *)value forKey:(NSString *)key {
NSNumber *wrapped = [_dictionary objectForKey:key];
if (wrapped && value) {
*value = [wrapped boolValue];
@@ -10413,7 +10467,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)setValue:(BOOL)value forKey:(NSString *)key {
+- (void)setBool:(BOOL)value forKey:(NSString *)key {
if (!key) {
[NSException raise:NSInvalidArgumentException
format:@"Attempting to add nil key to a Dictionary"];
@@ -10424,7 +10478,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)removeValueForKey:(NSString *)aKey {
+- (void)removeBoolForKey:(NSString *)aKey {
[_dictionary removeObjectForKey:aKey];
}
@@ -10442,24 +10496,24 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
+ (instancetype)dictionary {
- return [[[self alloc] initWithValues:NULL forKeys:NULL count:0] autorelease];
+ return [[[self alloc] initWithFloats:NULL forKeys:NULL count:0] autorelease];
}
-+ (instancetype)dictionaryWithValue:(float)value
++ (instancetype)dictionaryWithFloat:(float)value
forKey:(NSString *)key {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
+ // Cast is needed so the compiler knows what class we are invoking initWithFloats:forKeys:count:
// on to get the type correct.
- return [[(GPBStringFloatDictionary*)[self alloc] initWithValues:&value
+ return [[(GPBStringFloatDictionary*)[self alloc] initWithFloats:&value
forKeys:&key
count:1] autorelease];
}
-+ (instancetype)dictionaryWithValues:(const float [])values
++ (instancetype)dictionaryWithFloats:(const float [])values
forKeys:(const NSString * [])keys
count:(NSUInteger)count {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
+ // Cast is needed so the compiler knows what class we are invoking initWithFloats:forKeys:count:
// on to get the type correct.
- return [[(GPBStringFloatDictionary*)[self alloc] initWithValues:values
+ return [[(GPBStringFloatDictionary*)[self alloc] initWithFloats:values
forKeys:keys
count:count] autorelease];
}
@@ -10475,10 +10529,10 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)init {
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithFloats:NULL forKeys:NULL count:0];
}
-- (instancetype)initWithValues:(const float [])values
+- (instancetype)initWithFloats:(const float [])values
forKeys:(const NSString * [])keys
count:(NSUInteger)count {
self = [super init];
@@ -10498,7 +10552,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)initWithDictionary:(GPBStringFloatDictionary *)dictionary {
- self = [self initWithValues:NULL forKeys:NULL count:0];
+ self = [self initWithFloats:NULL forKeys:NULL count:0];
if (self) {
if (dictionary) {
[_dictionary addEntriesFromDictionary:dictionary->_dictionary];
@@ -10509,7 +10563,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
- (instancetype)initWithCapacity:(NSUInteger)numItems {
#pragma unused(numItems)
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithFloats:NULL forKeys:NULL count:0];
}
- (void)dealloc {
@@ -10524,14 +10578,15 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBStringFloatDictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBStringFloatDictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBStringFloatDictionary class]]) {
return NO;
}
- return [_dictionary isEqual:other->_dictionary];
+ GPBStringFloatDictionary *otherDictionary = other;
+ return [_dictionary isEqual:otherDictionary->_dictionary];
}
- (NSUInteger)hash {
@@ -10546,7 +10601,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return _dictionary.count;
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndFloatsUsingBlock:
(void (^)(NSString *key, float value, BOOL *stop))block {
[_dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *aKey,
NSNumber *aValue,
@@ -10604,13 +10659,13 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block {
- [self enumerateKeysAndValuesUsingBlock:^(NSString *key, float value, BOOL *stop) {
+ [self enumerateKeysAndFloatsUsingBlock:^(NSString *key, float value, BOOL *stop) {
#pragma unused(stop)
block(key, [NSString stringWithFormat:@"%.*g", FLT_DIG, value]);
}];
}
-- (BOOL)valueForKey:(NSString *)key value:(float *)value {
+- (BOOL)getFloat:(nullable float *)value forKey:(NSString *)key {
NSNumber *wrapped = [_dictionary objectForKey:key];
if (wrapped && value) {
*value = [wrapped floatValue];
@@ -10627,7 +10682,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)setValue:(float)value forKey:(NSString *)key {
+- (void)setFloat:(float)value forKey:(NSString *)key {
if (!key) {
[NSException raise:NSInvalidArgumentException
format:@"Attempting to add nil key to a Dictionary"];
@@ -10638,7 +10693,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)removeValueForKey:(NSString *)aKey {
+- (void)removeFloatForKey:(NSString *)aKey {
[_dictionary removeObjectForKey:aKey];
}
@@ -10656,24 +10711,24 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
+ (instancetype)dictionary {
- return [[[self alloc] initWithValues:NULL forKeys:NULL count:0] autorelease];
+ return [[[self alloc] initWithDoubles:NULL forKeys:NULL count:0] autorelease];
}
-+ (instancetype)dictionaryWithValue:(double)value
- forKey:(NSString *)key {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithDouble:(double)value
+ forKey:(NSString *)key {
+ // Cast is needed so the compiler knows what class we are invoking initWithDoubles:forKeys:count:
// on to get the type correct.
- return [[(GPBStringDoubleDictionary*)[self alloc] initWithValues:&value
- forKeys:&key
- count:1] autorelease];
+ return [[(GPBStringDoubleDictionary*)[self alloc] initWithDoubles:&value
+ forKeys:&key
+ count:1] autorelease];
}
-+ (instancetype)dictionaryWithValues:(const double [])values
- forKeys:(const NSString * [])keys
- count:(NSUInteger)count {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithDoubles:(const double [])values
+ forKeys:(const NSString * [])keys
+ count:(NSUInteger)count {
+ // Cast is needed so the compiler knows what class we are invoking initWithDoubles:forKeys:count:
// on to get the type correct.
- return [[(GPBStringDoubleDictionary*)[self alloc] initWithValues:values
+ return [[(GPBStringDoubleDictionary*)[self alloc] initWithDoubles:values
forKeys:keys
count:count] autorelease];
}
@@ -10689,12 +10744,12 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)init {
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithDoubles:NULL forKeys:NULL count:0];
}
-- (instancetype)initWithValues:(const double [])values
- forKeys:(const NSString * [])keys
- count:(NSUInteger)count {
+- (instancetype)initWithDoubles:(const double [])values
+ forKeys:(const NSString * [])keys
+ count:(NSUInteger)count {
self = [super init];
if (self) {
_dictionary = [[NSMutableDictionary alloc] init];
@@ -10712,7 +10767,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)initWithDictionary:(GPBStringDoubleDictionary *)dictionary {
- self = [self initWithValues:NULL forKeys:NULL count:0];
+ self = [self initWithDoubles:NULL forKeys:NULL count:0];
if (self) {
if (dictionary) {
[_dictionary addEntriesFromDictionary:dictionary->_dictionary];
@@ -10723,7 +10778,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
- (instancetype)initWithCapacity:(NSUInteger)numItems {
#pragma unused(numItems)
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithDoubles:NULL forKeys:NULL count:0];
}
- (void)dealloc {
@@ -10738,14 +10793,15 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBStringDoubleDictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBStringDoubleDictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBStringDoubleDictionary class]]) {
return NO;
}
- return [_dictionary isEqual:other->_dictionary];
+ GPBStringDoubleDictionary *otherDictionary = other;
+ return [_dictionary isEqual:otherDictionary->_dictionary];
}
- (NSUInteger)hash {
@@ -10760,7 +10816,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return _dictionary.count;
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndDoublesUsingBlock:
(void (^)(NSString *key, double value, BOOL *stop))block {
[_dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *aKey,
NSNumber *aValue,
@@ -10818,13 +10874,13 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block {
- [self enumerateKeysAndValuesUsingBlock:^(NSString *key, double value, BOOL *stop) {
+ [self enumerateKeysAndDoublesUsingBlock:^(NSString *key, double value, BOOL *stop) {
#pragma unused(stop)
block(key, [NSString stringWithFormat:@"%.*lg", DBL_DIG, value]);
}];
}
-- (BOOL)valueForKey:(NSString *)key value:(double *)value {
+- (BOOL)getDouble:(nullable double *)value forKey:(NSString *)key {
NSNumber *wrapped = [_dictionary objectForKey:key];
if (wrapped && value) {
*value = [wrapped doubleValue];
@@ -10841,7 +10897,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)setValue:(double)value forKey:(NSString *)key {
+- (void)setDouble:(double)value forKey:(NSString *)key {
if (!key) {
[NSException raise:NSInvalidArgumentException
format:@"Attempting to add nil key to a Dictionary"];
@@ -10852,7 +10908,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)removeValueForKey:(NSString *)aKey {
+- (void)removeDoubleForKey:(NSString *)aKey {
[_dictionary removeObjectForKey:aKey];
}
@@ -10980,14 +11036,15 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBStringEnumDictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBStringEnumDictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBStringEnumDictionary class]]) {
return NO;
}
- return [_dictionary isEqual:other->_dictionary];
+ GPBStringEnumDictionary *otherDictionary = other;
+ return [_dictionary isEqual:otherDictionary->_dictionary];
}
- (NSUInteger)hash {
@@ -11078,7 +11135,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}];
}
-- (BOOL)valueForKey:(NSString *)key value:(int32_t *)value {
+- (BOOL)getEnum:(int32_t *)value forKey:(NSString *)key {
NSNumber *wrapped = [_dictionary objectForKey:key];
if (wrapped && value) {
int32_t result = [wrapped intValue];
@@ -11090,7 +11147,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return (wrapped != NULL);
}
-- (BOOL)valueForKey:(NSString *)key rawValue:(int32_t *)rawValue {
+- (BOOL)getRawValue:(int32_t *)rawValue forKey:(NSString *)key {
NSNumber *wrapped = [_dictionary objectForKey:key];
if (wrapped && rawValue) {
*rawValue = [wrapped intValue];
@@ -11098,7 +11155,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return (wrapped != NULL);
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndEnumsUsingBlock:
(void (^)(NSString *key, int32_t value, BOOL *stop))block {
GPBEnumValidationFunc func = _validationFunc;
[_dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *aKey,
@@ -11132,7 +11189,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)removeValueForKey:(NSString *)aKey {
+- (void)removeEnumForKey:(NSString *)aKey {
[_dictionary removeObjectForKey:aKey];
}
@@ -11140,7 +11197,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
[_dictionary removeAllObjects];
}
-- (void)setValue:(int32_t)value forKey:(NSString *)key {
+- (void)setEnum:(int32_t)value forKey:(NSString *)key {
if (!key) {
[NSException raise:NSInvalidArgumentException
format:@"Attempting to add nil key to a Dictionary"];
@@ -11174,26 +11231,26 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
+ (instancetype)dictionary {
- return [[[self alloc] initWithValues:NULL forKeys:NULL count:0] autorelease];
+ return [[[self alloc] initWithUInt32s:NULL forKeys:NULL count:0] autorelease];
}
-+ (instancetype)dictionaryWithValue:(uint32_t)value
- forKey:(BOOL)key {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithUInt32:(uint32_t)value
+ forKey:(BOOL)key {
+ // Cast is needed so the compiler knows what class we are invoking initWithUInt32s:forKeys:count:
// on to get the type correct.
- return [[(GPBBoolUInt32Dictionary*)[self alloc] initWithValues:&value
- forKeys:&key
- count:1] autorelease];
+ return [[(GPBBoolUInt32Dictionary*)[self alloc] initWithUInt32s:&value
+ forKeys:&key
+ count:1] autorelease];
}
-+ (instancetype)dictionaryWithValues:(const uint32_t [])values
- forKeys:(const BOOL [])keys
- count:(NSUInteger)count {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithUInt32s:(const uint32_t [])values
+ forKeys:(const BOOL [])keys
+ count:(NSUInteger)count {
+ // Cast is needed so the compiler knows what class we are invoking initWithUInt32s:forKeys:count:
// on to get the type correct.
- return [[(GPBBoolUInt32Dictionary*)[self alloc] initWithValues:values
- forKeys:keys
- count:count] autorelease];
+ return [[(GPBBoolUInt32Dictionary*)[self alloc] initWithUInt32s:values
+ forKeys:keys
+ count:count] autorelease];
}
+ (instancetype)dictionaryWithDictionary:(GPBBoolUInt32Dictionary *)dictionary {
@@ -11207,12 +11264,12 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)init {
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithUInt32s:NULL forKeys:NULL count:0];
}
-- (instancetype)initWithValues:(const uint32_t [])values
- forKeys:(const BOOL [])keys
- count:(NSUInteger)count {
+- (instancetype)initWithUInt32s:(const uint32_t [])values
+ forKeys:(const BOOL [])keys
+ count:(NSUInteger)count {
self = [super init];
if (self) {
for (NSUInteger i = 0; i < count; ++i) {
@@ -11225,7 +11282,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)initWithDictionary:(GPBBoolUInt32Dictionary *)dictionary {
- self = [self initWithValues:NULL forKeys:NULL count:0];
+ self = [self initWithUInt32s:NULL forKeys:NULL count:0];
if (self) {
if (dictionary) {
for (int i = 0; i < 2; ++i) {
@@ -11241,7 +11298,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
- (instancetype)initWithCapacity:(NSUInteger)numItems {
#pragma unused(numItems)
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithUInt32s:NULL forKeys:NULL count:0];
}
#if !defined(NS_BLOCK_ASSERTIONS)
@@ -11257,19 +11314,20 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBBoolUInt32Dictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBBoolUInt32Dictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBBoolUInt32Dictionary class]]) {
return NO;
}
- if ((_valueSet[0] != other->_valueSet[0]) ||
- (_valueSet[1] != other->_valueSet[1])) {
+ GPBBoolUInt32Dictionary *otherDictionary = other;
+ if ((_valueSet[0] != otherDictionary->_valueSet[0]) ||
+ (_valueSet[1] != otherDictionary->_valueSet[1])) {
return NO;
}
- if ((_valueSet[0] && (_values[0] != other->_values[0])) ||
- (_valueSet[1] && (_values[1] != other->_values[1]))) {
+ if ((_valueSet[0] && (_values[0] != otherDictionary->_values[0])) ||
+ (_valueSet[1] && (_values[1] != otherDictionary->_values[1]))) {
return NO;
}
return YES;
@@ -11295,7 +11353,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return (_valueSet[0] ? 1 : 0) + (_valueSet[1] ? 1 : 0);
}
-- (BOOL)valueForKey:(BOOL)key value:(uint32_t *)value {
+- (BOOL)getUInt32:(uint32_t *)value forKey:(BOOL)key {
int idx = (key ? 1 : 0);
if (_valueSet[idx]) {
if (value) {
@@ -11322,7 +11380,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndUInt32sUsingBlock:
(void (^)(BOOL key, uint32_t value, BOOL *stop))block {
BOOL stop = NO;
if (_valueSet[0]) {
@@ -11383,7 +11441,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)setValue:(uint32_t)value forKey:(BOOL)key {
+- (void)setUInt32:(uint32_t)value forKey:(BOOL)key {
int idx = (key ? 1 : 0);
_values[idx] = value;
_valueSet[idx] = YES;
@@ -11392,7 +11450,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)removeValueForKey:(BOOL)aKey {
+- (void)removeUInt32ForKey:(BOOL)aKey {
_valueSet[aKey ? 1 : 0] = NO;
}
@@ -11415,24 +11473,24 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
+ (instancetype)dictionary {
- return [[[self alloc] initWithValues:NULL forKeys:NULL count:0] autorelease];
+ return [[[self alloc] initWithInt32s:NULL forKeys:NULL count:0] autorelease];
}
-+ (instancetype)dictionaryWithValue:(int32_t)value
++ (instancetype)dictionaryWithInt32:(int32_t)value
forKey:(BOOL)key {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
+ // Cast is needed so the compiler knows what class we are invoking initWithInt32s:forKeys:count:
// on to get the type correct.
- return [[(GPBBoolInt32Dictionary*)[self alloc] initWithValues:&value
+ return [[(GPBBoolInt32Dictionary*)[self alloc] initWithInt32s:&value
forKeys:&key
count:1] autorelease];
}
-+ (instancetype)dictionaryWithValues:(const int32_t [])values
++ (instancetype)dictionaryWithInt32s:(const int32_t [])values
forKeys:(const BOOL [])keys
count:(NSUInteger)count {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
+ // Cast is needed so the compiler knows what class we are invoking initWithInt32s:forKeys:count:
// on to get the type correct.
- return [[(GPBBoolInt32Dictionary*)[self alloc] initWithValues:values
+ return [[(GPBBoolInt32Dictionary*)[self alloc] initWithInt32s:values
forKeys:keys
count:count] autorelease];
}
@@ -11448,10 +11506,10 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)init {
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithInt32s:NULL forKeys:NULL count:0];
}
-- (instancetype)initWithValues:(const int32_t [])values
+- (instancetype)initWithInt32s:(const int32_t [])values
forKeys:(const BOOL [])keys
count:(NSUInteger)count {
self = [super init];
@@ -11466,7 +11524,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)initWithDictionary:(GPBBoolInt32Dictionary *)dictionary {
- self = [self initWithValues:NULL forKeys:NULL count:0];
+ self = [self initWithInt32s:NULL forKeys:NULL count:0];
if (self) {
if (dictionary) {
for (int i = 0; i < 2; ++i) {
@@ -11482,7 +11540,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
- (instancetype)initWithCapacity:(NSUInteger)numItems {
#pragma unused(numItems)
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithInt32s:NULL forKeys:NULL count:0];
}
#if !defined(NS_BLOCK_ASSERTIONS)
@@ -11498,19 +11556,20 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBBoolInt32Dictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBBoolInt32Dictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBBoolInt32Dictionary class]]) {
return NO;
}
- if ((_valueSet[0] != other->_valueSet[0]) ||
- (_valueSet[1] != other->_valueSet[1])) {
+ GPBBoolInt32Dictionary *otherDictionary = other;
+ if ((_valueSet[0] != otherDictionary->_valueSet[0]) ||
+ (_valueSet[1] != otherDictionary->_valueSet[1])) {
return NO;
}
- if ((_valueSet[0] && (_values[0] != other->_values[0])) ||
- (_valueSet[1] && (_values[1] != other->_values[1]))) {
+ if ((_valueSet[0] && (_values[0] != otherDictionary->_values[0])) ||
+ (_valueSet[1] && (_values[1] != otherDictionary->_values[1]))) {
return NO;
}
return YES;
@@ -11536,7 +11595,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return (_valueSet[0] ? 1 : 0) + (_valueSet[1] ? 1 : 0);
}
-- (BOOL)valueForKey:(BOOL)key value:(int32_t *)value {
+- (BOOL)getInt32:(int32_t *)value forKey:(BOOL)key {
int idx = (key ? 1 : 0);
if (_valueSet[idx]) {
if (value) {
@@ -11563,7 +11622,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndInt32sUsingBlock:
(void (^)(BOOL key, int32_t value, BOOL *stop))block {
BOOL stop = NO;
if (_valueSet[0]) {
@@ -11624,7 +11683,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)setValue:(int32_t)value forKey:(BOOL)key {
+- (void)setInt32:(int32_t)value forKey:(BOOL)key {
int idx = (key ? 1 : 0);
_values[idx] = value;
_valueSet[idx] = YES;
@@ -11633,7 +11692,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)removeValueForKey:(BOOL)aKey {
+- (void)removeInt32ForKey:(BOOL)aKey {
_valueSet[aKey ? 1 : 0] = NO;
}
@@ -11656,26 +11715,26 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
+ (instancetype)dictionary {
- return [[[self alloc] initWithValues:NULL forKeys:NULL count:0] autorelease];
+ return [[[self alloc] initWithUInt64s:NULL forKeys:NULL count:0] autorelease];
}
-+ (instancetype)dictionaryWithValue:(uint64_t)value
- forKey:(BOOL)key {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithUInt64:(uint64_t)value
+ forKey:(BOOL)key {
+ // Cast is needed so the compiler knows what class we are invoking initWithUInt64s:forKeys:count:
// on to get the type correct.
- return [[(GPBBoolUInt64Dictionary*)[self alloc] initWithValues:&value
- forKeys:&key
- count:1] autorelease];
+ return [[(GPBBoolUInt64Dictionary*)[self alloc] initWithUInt64s:&value
+ forKeys:&key
+ count:1] autorelease];
}
-+ (instancetype)dictionaryWithValues:(const uint64_t [])values
- forKeys:(const BOOL [])keys
- count:(NSUInteger)count {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithUInt64s:(const uint64_t [])values
+ forKeys:(const BOOL [])keys
+ count:(NSUInteger)count {
+ // Cast is needed so the compiler knows what class we are invoking initWithUInt64s:forKeys:count:
// on to get the type correct.
- return [[(GPBBoolUInt64Dictionary*)[self alloc] initWithValues:values
- forKeys:keys
- count:count] autorelease];
+ return [[(GPBBoolUInt64Dictionary*)[self alloc] initWithUInt64s:values
+ forKeys:keys
+ count:count] autorelease];
}
+ (instancetype)dictionaryWithDictionary:(GPBBoolUInt64Dictionary *)dictionary {
@@ -11689,12 +11748,12 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)init {
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithUInt64s:NULL forKeys:NULL count:0];
}
-- (instancetype)initWithValues:(const uint64_t [])values
- forKeys:(const BOOL [])keys
- count:(NSUInteger)count {
+- (instancetype)initWithUInt64s:(const uint64_t [])values
+ forKeys:(const BOOL [])keys
+ count:(NSUInteger)count {
self = [super init];
if (self) {
for (NSUInteger i = 0; i < count; ++i) {
@@ -11707,7 +11766,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)initWithDictionary:(GPBBoolUInt64Dictionary *)dictionary {
- self = [self initWithValues:NULL forKeys:NULL count:0];
+ self = [self initWithUInt64s:NULL forKeys:NULL count:0];
if (self) {
if (dictionary) {
for (int i = 0; i < 2; ++i) {
@@ -11723,7 +11782,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
- (instancetype)initWithCapacity:(NSUInteger)numItems {
#pragma unused(numItems)
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithUInt64s:NULL forKeys:NULL count:0];
}
#if !defined(NS_BLOCK_ASSERTIONS)
@@ -11739,19 +11798,20 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBBoolUInt64Dictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBBoolUInt64Dictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBBoolUInt64Dictionary class]]) {
return NO;
}
- if ((_valueSet[0] != other->_valueSet[0]) ||
- (_valueSet[1] != other->_valueSet[1])) {
+ GPBBoolUInt64Dictionary *otherDictionary = other;
+ if ((_valueSet[0] != otherDictionary->_valueSet[0]) ||
+ (_valueSet[1] != otherDictionary->_valueSet[1])) {
return NO;
}
- if ((_valueSet[0] && (_values[0] != other->_values[0])) ||
- (_valueSet[1] && (_values[1] != other->_values[1]))) {
+ if ((_valueSet[0] && (_values[0] != otherDictionary->_values[0])) ||
+ (_valueSet[1] && (_values[1] != otherDictionary->_values[1]))) {
return NO;
}
return YES;
@@ -11777,7 +11837,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return (_valueSet[0] ? 1 : 0) + (_valueSet[1] ? 1 : 0);
}
-- (BOOL)valueForKey:(BOOL)key value:(uint64_t *)value {
+- (BOOL)getUInt64:(uint64_t *)value forKey:(BOOL)key {
int idx = (key ? 1 : 0);
if (_valueSet[idx]) {
if (value) {
@@ -11804,7 +11864,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndUInt64sUsingBlock:
(void (^)(BOOL key, uint64_t value, BOOL *stop))block {
BOOL stop = NO;
if (_valueSet[0]) {
@@ -11865,7 +11925,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)setValue:(uint64_t)value forKey:(BOOL)key {
+- (void)setUInt64:(uint64_t)value forKey:(BOOL)key {
int idx = (key ? 1 : 0);
_values[idx] = value;
_valueSet[idx] = YES;
@@ -11874,7 +11934,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)removeValueForKey:(BOOL)aKey {
+- (void)removeUInt64ForKey:(BOOL)aKey {
_valueSet[aKey ? 1 : 0] = NO;
}
@@ -11897,24 +11957,24 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
+ (instancetype)dictionary {
- return [[[self alloc] initWithValues:NULL forKeys:NULL count:0] autorelease];
+ return [[[self alloc] initWithInt64s:NULL forKeys:NULL count:0] autorelease];
}
-+ (instancetype)dictionaryWithValue:(int64_t)value
++ (instancetype)dictionaryWithInt64:(int64_t)value
forKey:(BOOL)key {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
+ // Cast is needed so the compiler knows what class we are invoking initWithInt64s:forKeys:count:
// on to get the type correct.
- return [[(GPBBoolInt64Dictionary*)[self alloc] initWithValues:&value
+ return [[(GPBBoolInt64Dictionary*)[self alloc] initWithInt64s:&value
forKeys:&key
count:1] autorelease];
}
-+ (instancetype)dictionaryWithValues:(const int64_t [])values
++ (instancetype)dictionaryWithInt64s:(const int64_t [])values
forKeys:(const BOOL [])keys
count:(NSUInteger)count {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
+ // Cast is needed so the compiler knows what class we are invoking initWithInt64s:forKeys:count:
// on to get the type correct.
- return [[(GPBBoolInt64Dictionary*)[self alloc] initWithValues:values
+ return [[(GPBBoolInt64Dictionary*)[self alloc] initWithInt64s:values
forKeys:keys
count:count] autorelease];
}
@@ -11930,10 +11990,10 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)init {
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithInt64s:NULL forKeys:NULL count:0];
}
-- (instancetype)initWithValues:(const int64_t [])values
+- (instancetype)initWithInt64s:(const int64_t [])values
forKeys:(const BOOL [])keys
count:(NSUInteger)count {
self = [super init];
@@ -11948,7 +12008,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)initWithDictionary:(GPBBoolInt64Dictionary *)dictionary {
- self = [self initWithValues:NULL forKeys:NULL count:0];
+ self = [self initWithInt64s:NULL forKeys:NULL count:0];
if (self) {
if (dictionary) {
for (int i = 0; i < 2; ++i) {
@@ -11964,7 +12024,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
- (instancetype)initWithCapacity:(NSUInteger)numItems {
#pragma unused(numItems)
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithInt64s:NULL forKeys:NULL count:0];
}
#if !defined(NS_BLOCK_ASSERTIONS)
@@ -11980,19 +12040,20 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBBoolInt64Dictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBBoolInt64Dictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBBoolInt64Dictionary class]]) {
return NO;
}
- if ((_valueSet[0] != other->_valueSet[0]) ||
- (_valueSet[1] != other->_valueSet[1])) {
+ GPBBoolInt64Dictionary *otherDictionary = other;
+ if ((_valueSet[0] != otherDictionary->_valueSet[0]) ||
+ (_valueSet[1] != otherDictionary->_valueSet[1])) {
return NO;
}
- if ((_valueSet[0] && (_values[0] != other->_values[0])) ||
- (_valueSet[1] && (_values[1] != other->_values[1]))) {
+ if ((_valueSet[0] && (_values[0] != otherDictionary->_values[0])) ||
+ (_valueSet[1] && (_values[1] != otherDictionary->_values[1]))) {
return NO;
}
return YES;
@@ -12018,7 +12079,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return (_valueSet[0] ? 1 : 0) + (_valueSet[1] ? 1 : 0);
}
-- (BOOL)valueForKey:(BOOL)key value:(int64_t *)value {
+- (BOOL)getInt64:(int64_t *)value forKey:(BOOL)key {
int idx = (key ? 1 : 0);
if (_valueSet[idx]) {
if (value) {
@@ -12045,7 +12106,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndInt64sUsingBlock:
(void (^)(BOOL key, int64_t value, BOOL *stop))block {
BOOL stop = NO;
if (_valueSet[0]) {
@@ -12106,7 +12167,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)setValue:(int64_t)value forKey:(BOOL)key {
+- (void)setInt64:(int64_t)value forKey:(BOOL)key {
int idx = (key ? 1 : 0);
_values[idx] = value;
_valueSet[idx] = YES;
@@ -12115,7 +12176,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)removeValueForKey:(BOOL)aKey {
+- (void)removeInt64ForKey:(BOOL)aKey {
_valueSet[aKey ? 1 : 0] = NO;
}
@@ -12138,26 +12199,26 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
+ (instancetype)dictionary {
- return [[[self alloc] initWithValues:NULL forKeys:NULL count:0] autorelease];
+ return [[[self alloc] initWithBools:NULL forKeys:NULL count:0] autorelease];
}
-+ (instancetype)dictionaryWithValue:(BOOL)value
- forKey:(BOOL)key {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithBool:(BOOL)value
+ forKey:(BOOL)key {
+ // Cast is needed so the compiler knows what class we are invoking initWithBools:forKeys:count:
// on to get the type correct.
- return [[(GPBBoolBoolDictionary*)[self alloc] initWithValues:&value
- forKeys:&key
- count:1] autorelease];
+ return [[(GPBBoolBoolDictionary*)[self alloc] initWithBools:&value
+ forKeys:&key
+ count:1] autorelease];
}
-+ (instancetype)dictionaryWithValues:(const BOOL [])values
- forKeys:(const BOOL [])keys
- count:(NSUInteger)count {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithBools:(const BOOL [])values
+ forKeys:(const BOOL [])keys
+ count:(NSUInteger)count {
+ // Cast is needed so the compiler knows what class we are invoking initWithBools:forKeys:count:
// on to get the type correct.
- return [[(GPBBoolBoolDictionary*)[self alloc] initWithValues:values
- forKeys:keys
- count:count] autorelease];
+ return [[(GPBBoolBoolDictionary*)[self alloc] initWithBools:values
+ forKeys:keys
+ count:count] autorelease];
}
+ (instancetype)dictionaryWithDictionary:(GPBBoolBoolDictionary *)dictionary {
@@ -12171,12 +12232,12 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)init {
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithBools:NULL forKeys:NULL count:0];
}
-- (instancetype)initWithValues:(const BOOL [])values
- forKeys:(const BOOL [])keys
- count:(NSUInteger)count {
+- (instancetype)initWithBools:(const BOOL [])values
+ forKeys:(const BOOL [])keys
+ count:(NSUInteger)count {
self = [super init];
if (self) {
for (NSUInteger i = 0; i < count; ++i) {
@@ -12189,7 +12250,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)initWithDictionary:(GPBBoolBoolDictionary *)dictionary {
- self = [self initWithValues:NULL forKeys:NULL count:0];
+ self = [self initWithBools:NULL forKeys:NULL count:0];
if (self) {
if (dictionary) {
for (int i = 0; i < 2; ++i) {
@@ -12205,7 +12266,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
- (instancetype)initWithCapacity:(NSUInteger)numItems {
#pragma unused(numItems)
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithBools:NULL forKeys:NULL count:0];
}
#if !defined(NS_BLOCK_ASSERTIONS)
@@ -12221,19 +12282,20 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBBoolBoolDictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBBoolBoolDictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBBoolBoolDictionary class]]) {
return NO;
}
- if ((_valueSet[0] != other->_valueSet[0]) ||
- (_valueSet[1] != other->_valueSet[1])) {
+ GPBBoolBoolDictionary *otherDictionary = other;
+ if ((_valueSet[0] != otherDictionary->_valueSet[0]) ||
+ (_valueSet[1] != otherDictionary->_valueSet[1])) {
return NO;
}
- if ((_valueSet[0] && (_values[0] != other->_values[0])) ||
- (_valueSet[1] && (_values[1] != other->_values[1]))) {
+ if ((_valueSet[0] && (_values[0] != otherDictionary->_values[0])) ||
+ (_valueSet[1] && (_values[1] != otherDictionary->_values[1]))) {
return NO;
}
return YES;
@@ -12259,7 +12321,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return (_valueSet[0] ? 1 : 0) + (_valueSet[1] ? 1 : 0);
}
-- (BOOL)valueForKey:(BOOL)key value:(BOOL *)value {
+- (BOOL)getBool:(BOOL *)value forKey:(BOOL)key {
int idx = (key ? 1 : 0);
if (_valueSet[idx]) {
if (value) {
@@ -12286,7 +12348,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndBoolsUsingBlock:
(void (^)(BOOL key, BOOL value, BOOL *stop))block {
BOOL stop = NO;
if (_valueSet[0]) {
@@ -12347,7 +12409,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)setValue:(BOOL)value forKey:(BOOL)key {
+- (void)setBool:(BOOL)value forKey:(BOOL)key {
int idx = (key ? 1 : 0);
_values[idx] = value;
_valueSet[idx] = YES;
@@ -12356,7 +12418,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)removeValueForKey:(BOOL)aKey {
+- (void)removeBoolForKey:(BOOL)aKey {
_valueSet[aKey ? 1 : 0] = NO;
}
@@ -12379,24 +12441,24 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
+ (instancetype)dictionary {
- return [[[self alloc] initWithValues:NULL forKeys:NULL count:0] autorelease];
+ return [[[self alloc] initWithFloats:NULL forKeys:NULL count:0] autorelease];
}
-+ (instancetype)dictionaryWithValue:(float)value
++ (instancetype)dictionaryWithFloat:(float)value
forKey:(BOOL)key {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
+ // Cast is needed so the compiler knows what class we are invoking initWithFloats:forKeys:count:
// on to get the type correct.
- return [[(GPBBoolFloatDictionary*)[self alloc] initWithValues:&value
+ return [[(GPBBoolFloatDictionary*)[self alloc] initWithFloats:&value
forKeys:&key
count:1] autorelease];
}
-+ (instancetype)dictionaryWithValues:(const float [])values
++ (instancetype)dictionaryWithFloats:(const float [])values
forKeys:(const BOOL [])keys
count:(NSUInteger)count {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
+ // Cast is needed so the compiler knows what class we are invoking initWithFloats:forKeys:count:
// on to get the type correct.
- return [[(GPBBoolFloatDictionary*)[self alloc] initWithValues:values
+ return [[(GPBBoolFloatDictionary*)[self alloc] initWithFloats:values
forKeys:keys
count:count] autorelease];
}
@@ -12412,10 +12474,10 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)init {
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithFloats:NULL forKeys:NULL count:0];
}
-- (instancetype)initWithValues:(const float [])values
+- (instancetype)initWithFloats:(const float [])values
forKeys:(const BOOL [])keys
count:(NSUInteger)count {
self = [super init];
@@ -12430,7 +12492,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)initWithDictionary:(GPBBoolFloatDictionary *)dictionary {
- self = [self initWithValues:NULL forKeys:NULL count:0];
+ self = [self initWithFloats:NULL forKeys:NULL count:0];
if (self) {
if (dictionary) {
for (int i = 0; i < 2; ++i) {
@@ -12446,7 +12508,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
- (instancetype)initWithCapacity:(NSUInteger)numItems {
#pragma unused(numItems)
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithFloats:NULL forKeys:NULL count:0];
}
#if !defined(NS_BLOCK_ASSERTIONS)
@@ -12462,19 +12524,20 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBBoolFloatDictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBBoolFloatDictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBBoolFloatDictionary class]]) {
return NO;
}
- if ((_valueSet[0] != other->_valueSet[0]) ||
- (_valueSet[1] != other->_valueSet[1])) {
+ GPBBoolFloatDictionary *otherDictionary = other;
+ if ((_valueSet[0] != otherDictionary->_valueSet[0]) ||
+ (_valueSet[1] != otherDictionary->_valueSet[1])) {
return NO;
}
- if ((_valueSet[0] && (_values[0] != other->_values[0])) ||
- (_valueSet[1] && (_values[1] != other->_values[1]))) {
+ if ((_valueSet[0] && (_values[0] != otherDictionary->_values[0])) ||
+ (_valueSet[1] && (_values[1] != otherDictionary->_values[1]))) {
return NO;
}
return YES;
@@ -12500,7 +12563,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return (_valueSet[0] ? 1 : 0) + (_valueSet[1] ? 1 : 0);
}
-- (BOOL)valueForKey:(BOOL)key value:(float *)value {
+- (BOOL)getFloat:(float *)value forKey:(BOOL)key {
int idx = (key ? 1 : 0);
if (_valueSet[idx]) {
if (value) {
@@ -12527,7 +12590,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndFloatsUsingBlock:
(void (^)(BOOL key, float value, BOOL *stop))block {
BOOL stop = NO;
if (_valueSet[0]) {
@@ -12588,7 +12651,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)setValue:(float)value forKey:(BOOL)key {
+- (void)setFloat:(float)value forKey:(BOOL)key {
int idx = (key ? 1 : 0);
_values[idx] = value;
_valueSet[idx] = YES;
@@ -12597,7 +12660,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)removeValueForKey:(BOOL)aKey {
+- (void)removeFloatForKey:(BOOL)aKey {
_valueSet[aKey ? 1 : 0] = NO;
}
@@ -12620,26 +12683,26 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
+ (instancetype)dictionary {
- return [[[self alloc] initWithValues:NULL forKeys:NULL count:0] autorelease];
+ return [[[self alloc] initWithDoubles:NULL forKeys:NULL count:0] autorelease];
}
-+ (instancetype)dictionaryWithValue:(double)value
- forKey:(BOOL)key {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithDouble:(double)value
+ forKey:(BOOL)key {
+ // Cast is needed so the compiler knows what class we are invoking initWithDoubles:forKeys:count:
// on to get the type correct.
- return [[(GPBBoolDoubleDictionary*)[self alloc] initWithValues:&value
- forKeys:&key
- count:1] autorelease];
+ return [[(GPBBoolDoubleDictionary*)[self alloc] initWithDoubles:&value
+ forKeys:&key
+ count:1] autorelease];
}
-+ (instancetype)dictionaryWithValues:(const double [])values
- forKeys:(const BOOL [])keys
- count:(NSUInteger)count {
- // Cast is needed so the compiler knows what class we are invoking initWithValues:forKeys:count:
++ (instancetype)dictionaryWithDoubles:(const double [])values
+ forKeys:(const BOOL [])keys
+ count:(NSUInteger)count {
+ // Cast is needed so the compiler knows what class we are invoking initWithDoubles:forKeys:count:
// on to get the type correct.
- return [[(GPBBoolDoubleDictionary*)[self alloc] initWithValues:values
- forKeys:keys
- count:count] autorelease];
+ return [[(GPBBoolDoubleDictionary*)[self alloc] initWithDoubles:values
+ forKeys:keys
+ count:count] autorelease];
}
+ (instancetype)dictionaryWithDictionary:(GPBBoolDoubleDictionary *)dictionary {
@@ -12653,12 +12716,12 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)init {
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithDoubles:NULL forKeys:NULL count:0];
}
-- (instancetype)initWithValues:(const double [])values
- forKeys:(const BOOL [])keys
- count:(NSUInteger)count {
+- (instancetype)initWithDoubles:(const double [])values
+ forKeys:(const BOOL [])keys
+ count:(NSUInteger)count {
self = [super init];
if (self) {
for (NSUInteger i = 0; i < count; ++i) {
@@ -12671,7 +12734,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
- (instancetype)initWithDictionary:(GPBBoolDoubleDictionary *)dictionary {
- self = [self initWithValues:NULL forKeys:NULL count:0];
+ self = [self initWithDoubles:NULL forKeys:NULL count:0];
if (self) {
if (dictionary) {
for (int i = 0; i < 2; ++i) {
@@ -12687,7 +12750,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
- (instancetype)initWithCapacity:(NSUInteger)numItems {
#pragma unused(numItems)
- return [self initWithValues:NULL forKeys:NULL count:0];
+ return [self initWithDoubles:NULL forKeys:NULL count:0];
}
#if !defined(NS_BLOCK_ASSERTIONS)
@@ -12703,19 +12766,20 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBBoolDoubleDictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBBoolDoubleDictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBBoolDoubleDictionary class]]) {
return NO;
}
- if ((_valueSet[0] != other->_valueSet[0]) ||
- (_valueSet[1] != other->_valueSet[1])) {
+ GPBBoolDoubleDictionary *otherDictionary = other;
+ if ((_valueSet[0] != otherDictionary->_valueSet[0]) ||
+ (_valueSet[1] != otherDictionary->_valueSet[1])) {
return NO;
}
- if ((_valueSet[0] && (_values[0] != other->_values[0])) ||
- (_valueSet[1] && (_values[1] != other->_values[1]))) {
+ if ((_valueSet[0] && (_values[0] != otherDictionary->_values[0])) ||
+ (_valueSet[1] && (_values[1] != otherDictionary->_values[1]))) {
return NO;
}
return YES;
@@ -12741,7 +12805,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return (_valueSet[0] ? 1 : 0) + (_valueSet[1] ? 1 : 0);
}
-- (BOOL)valueForKey:(BOOL)key value:(double *)value {
+- (BOOL)getDouble:(double *)value forKey:(BOOL)key {
int idx = (key ? 1 : 0);
if (_valueSet[idx]) {
if (value) {
@@ -12768,7 +12832,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndDoublesUsingBlock:
(void (^)(BOOL key, double value, BOOL *stop))block {
BOOL stop = NO;
if (_valueSet[0]) {
@@ -12829,7 +12893,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)setValue:(double)value forKey:(BOOL)key {
+- (void)setDouble:(double)value forKey:(BOOL)key {
int idx = (key ? 1 : 0);
_values[idx] = value;
_valueSet[idx] = YES;
@@ -12838,7 +12902,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)removeValueForKey:(BOOL)aKey {
+- (void)removeDoubleForKey:(BOOL)aKey {
_valueSet[aKey ? 1 : 0] = NO;
}
@@ -12943,19 +13007,20 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBBoolObjectDictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBBoolObjectDictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBBoolObjectDictionary class]]) {
return NO;
}
- if (((_values[0] != nil) != (other->_values[0] != nil)) ||
- ((_values[1] != nil) != (other->_values[1] != nil))) {
+ GPBBoolObjectDictionary *otherDictionary = other;
+ if (((_values[0] != nil) != (otherDictionary->_values[0] != nil)) ||
+ ((_values[1] != nil) != (otherDictionary->_values[1] != nil))) {
return NO;
}
- if (((_values[0] != nil) && (![_values[0] isEqual:other->_values[0]])) ||
- ((_values[1] != nil) && (![_values[1] isEqual:other->_values[1]]))) {
+ if (((_values[0] != nil) && (![_values[0] isEqual:otherDictionary->_values[0]])) ||
+ ((_values[1] != nil) && (![_values[1] isEqual:otherDictionary->_values[1]]))) {
return NO;
}
return YES;
@@ -13233,19 +13298,20 @@ void GPBDictionaryReadEntry(id mapDictionary,
return [[GPBBoolEnumDictionary allocWithZone:zone] initWithDictionary:self];
}
-- (BOOL)isEqual:(GPBBoolEnumDictionary *)other {
+- (BOOL)isEqual:(id)other {
if (self == other) {
return YES;
}
if (![other isKindOfClass:[GPBBoolEnumDictionary class]]) {
return NO;
}
- if ((_valueSet[0] != other->_valueSet[0]) ||
- (_valueSet[1] != other->_valueSet[1])) {
+ GPBBoolEnumDictionary *otherDictionary = other;
+ if ((_valueSet[0] != otherDictionary->_valueSet[0]) ||
+ (_valueSet[1] != otherDictionary->_valueSet[1])) {
return NO;
}
- if ((_valueSet[0] && (_values[0] != other->_values[0])) ||
- (_valueSet[1] && (_values[1] != other->_values[1]))) {
+ if ((_valueSet[0] && (_values[0] != otherDictionary->_values[0])) ||
+ (_valueSet[1] && (_values[1] != otherDictionary->_values[1]))) {
return NO;
}
return YES;
@@ -13271,7 +13337,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return (_valueSet[0] ? 1 : 0) + (_valueSet[1] ? 1 : 0);
}
-- (BOOL)valueForKey:(BOOL)key value:(int32_t*)value {
+- (BOOL)getEnum:(int32_t*)value forKey:(BOOL)key {
int idx = (key ? 1 : 0);
if (_valueSet[idx]) {
if (value) {
@@ -13286,7 +13352,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return NO;
}
-- (BOOL)valueForKey:(BOOL)key rawValue:(int32_t*)rawValue {
+- (BOOL)getRawValue:(int32_t*)rawValue forKey:(BOOL)key {
int idx = (key ? 1 : 0);
if (_valueSet[idx]) {
if (rawValue) {
@@ -13297,7 +13363,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
return NO;
}
-- (void)enumerateKeysAndValuesUsingBlock:
+- (void)enumerateKeysAndRawValuesUsingBlock:
(void (^)(BOOL key, int32_t value, BOOL *stop))block {
BOOL stop = NO;
if (_valueSet[0]) {
@@ -13308,7 +13374,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)enumerateKeysAndRawValuesUsingBlock:
+- (void)enumerateKeysAndEnumsUsingBlock:
(void (^)(BOOL key, int32_t rawValue, BOOL *stop))block {
BOOL stop = NO;
GPBEnumValidationFunc func = _validationFunc;
@@ -13413,7 +13479,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)setValue:(int32_t)value forKey:(BOOL)key {
+- (void)setEnum:(int32_t)value forKey:(BOOL)key {
if (!_validationFunc(value)) {
[NSException raise:NSInvalidArgumentException
format:@"GPBBoolEnumDictionary: Attempt to set an unknown enum value (%d)",
@@ -13436,7 +13502,7 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
}
-- (void)removeValueForKey:(BOOL)aKey {
+- (void)removeEnumForKey:(BOOL)aKey {
_valueSet[aKey ? 1 : 0] = NO;
}
@@ -13553,3 +13619,5 @@ void GPBDictionaryReadEntry(id mapDictionary,
}
@end
+
+#pragma clang diagnostic pop
diff --git a/objectivec/GPBExtensionInternals.m b/objectivec/GPBExtensionInternals.m
index 634c3369..290c82a1 100644
--- a/objectivec/GPBExtensionInternals.m
+++ b/objectivec/GPBExtensionInternals.m
@@ -33,7 +33,7 @@
#import <objc/runtime.h>
#import "GPBCodedInputStream_PackagePrivate.h"
-#import "GPBCodedOutputStream.h"
+#import "GPBCodedOutputStream_PackagePrivate.h"
#import "GPBDescriptor_PackagePrivate.h"
#import "GPBMessage_PackagePrivate.h"
#import "GPBUtilities_PackagePrivate.h"
@@ -45,6 +45,8 @@ static id NewSingleValueFromInputStream(GPBExtensionDescriptor *extension,
__attribute__((ns_returns_retained));
GPB_INLINE size_t DataTypeSize(GPBDataType dataType) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wswitch-enum"
switch (dataType) {
case GPBDataTypeBool:
return 1;
@@ -59,6 +61,7 @@ GPB_INLINE size_t DataTypeSize(GPBDataType dataType) {
default:
return 0;
}
+#pragma clang diagnostic pop
}
static size_t ComputePBSerializedSizeNoTagOfObject(GPBDataType dataType, id object) {
@@ -261,6 +264,12 @@ static void WriteArrayIncludingTagsToCodedOutputStream(
}
}
+// Direct access is use for speed, to avoid even internally declaring things
+// read/write, etc. The warning is enabled in the project to ensure code calling
+// protos can turn on -Wdirect-ivar-access without issues.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdirect-ivar-access"
+
void GPBExtensionMergeFromInputStream(GPBExtensionDescriptor *extension,
BOOL isPackedOnStream,
GPBCodedInputStream *input,
@@ -378,3 +387,5 @@ static id NewSingleValueFromInputStream(GPBExtensionDescriptor *extension,
return nil;
}
+
+#pragma clang diagnostic pop
diff --git a/objectivec/GPBExtensionRegistry.h b/objectivec/GPBExtensionRegistry.h
index 0363c70a..08a6472a 100644
--- a/objectivec/GPBExtensionRegistry.h
+++ b/objectivec/GPBExtensionRegistry.h
@@ -35,30 +35,45 @@
NS_ASSUME_NONNULL_BEGIN
-// A table of known extensions, searchable by name or field number. When
-// parsing a protocol message that might have extensions, you must provide an
-// ExtensionRegistry in which you have registered any extensions that you want
-// to be able to parse. Otherwise, those extensions will just be treated like
-// unknown fields.
-//
-// The *Root classes provide +extensionRegistry for the extensions defined in a
-// given file *and* all files it imports. You can also create a
-// GPBExtensionRegistry, and merge those registries to handle parsing extensions
-// defined from non overlapping files.
-//
-// GPBExtensionRegistry *registry =
-// [[[MyProtoFileRoot extensionRegistry] copy] autorelease];
-// [registry addExtension:[OtherMessage neededExtension]; // Not in MyProtoFile
-// NSError *parseError = nil;
-// MyMessage *msg = [MyMessage parseData:data
-// extensionRegistry:registry
-// error:&parseError];
-//
+/// A table of known extensions, searchable by name or field number. When
+/// parsing a protocol message that might have extensions, you must provide a
+/// @c GPBExtensionRegistry in which you have registered any extensions that you
+/// want to be able to parse. Otherwise, those extensions will just be treated
+/// like unknown fields.
+///
+/// The @c *Root classes provide @c +extensionRegistry for the extensions defined
+/// in a given file *and* all files it imports. You can also create a
+/// @c GPBExtensionRegistry, and merge those registries to handle parsing
+/// extensions defined from non overlapping files.
+///
+/// @code
+/// GPBExtensionRegistry *registry =
+/// [[[MyProtoFileRoot extensionRegistry] copy] autorelease];
+/// [registry addExtension:[OtherMessage neededExtension]; // Not in MyProtoFile
+/// NSError *parseError = nil;
+/// MyMessage *msg = [MyMessage parseData:data
+/// extensionRegistry:registry
+/// error:&parseError];
+/// @endcode
@interface GPBExtensionRegistry : NSObject<NSCopying>
+/// Add the given @c GPBExtensionDescriptor to this registry.
+///
+/// @param extension The extension description to add.
- (void)addExtension:(GPBExtensionDescriptor *)extension;
+
+/// Adds all the extensions from another registry to this registry.
+///
+/// @param registry The registry to merge into this registry.
- (void)addExtensions:(GPBExtensionRegistry *)registry;
+/// Looks for the extension registered for the given field number on a given
+/// @c GPBDescriptor.
+///
+/// @param descriptor The descriptor to look for a registered extension on.
+/// @param fieldNumber The field number of an extension to look for.
+///
+/// @return The registered @c GPBExtensionDescripto or nil if none was found.
- (nullable GPBExtensionDescriptor *)extensionForDescriptor:(GPBDescriptor *)descriptor
fieldNumber:(NSInteger)fieldNumber;
diff --git a/objectivec/GPBExtensionRegistry.m b/objectivec/GPBExtensionRegistry.m
index df61a17b..01eb761f 100644
--- a/objectivec/GPBExtensionRegistry.m
+++ b/objectivec/GPBExtensionRegistry.m
@@ -51,6 +51,12 @@
[super dealloc];
}
+// Direct access is use for speed, to avoid even internally declaring things
+// read/write, etc. The warning is enabled in the project to ensure code calling
+// protos can turn on -Wdirect-ivar-access without issues.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdirect-ivar-access"
+
- (instancetype)copyWithZone:(NSZone *)zone {
GPBExtensionRegistry *result = [[[self class] allocWithZone:zone] init];
if (result && mutableClassMap_.count) {
@@ -105,4 +111,6 @@
}
}
+#pragma clang diagnostic pop
+
@end
diff --git a/objectivec/GPBMessage.h b/objectivec/GPBMessage.h
index 332393ed..7e0f58a3 100644
--- a/objectivec/GPBMessage.h
+++ b/objectivec/GPBMessage.h
@@ -44,23 +44,23 @@ NS_ASSUME_NONNULL_BEGIN
CF_EXTERN_C_BEGIN
-// NSError domain used for errors.
+/// NSError domain used for errors.
extern NSString *const GPBMessageErrorDomain;
+/// Error code for NSError with GPBMessageErrorDomain.
typedef NS_ENUM(NSInteger, GPBMessageErrorCode) {
- GPBMessageErrorCodeMalformedData = -100,
+ /// Uncategorized error.
+ GPBMessageErrorCodeOther = -100,
+ /// A message can't be serialized because it is missing required fields.
GPBMessageErrorCodeMissingRequiredField = -101,
};
-// In DEBUG ONLY, an NSException is thrown when a parsed message doesn't
-// contain required fields. This key allows you to retrieve the parsed message
-// from the exception's |userInfo| dictionary.
-#ifdef DEBUG
-extern NSString *const GPBExceptionMessageKey;
-#endif // DEBUG
+/// Key under which the error's reason is stored inside the userInfo dictionary.
+extern NSString *const GPBErrorReasonKey;
CF_EXTERN_C_END
+/// Base class for all of the generated message classes.
@interface GPBMessage : NSObject<NSSecureCoding, NSCopying>
// NOTE: If you add a instance method/property to this class that may conflict
@@ -68,108 +68,259 @@ CF_EXTERN_C_END
// The main cases are methods that take no arguments, or setFoo:/hasFoo: type
// methods.
+/// The unknown fields for this message.
+///
+/// Only messages from proto files declared with "proto2" syntax support unknown
+/// fields. For "proto3" syntax, any unknown fields found while parsing are
+/// dropped.
@property(nonatomic, copy, nullable) GPBUnknownFieldSet *unknownFields;
-// Are all required fields in the message and all embedded messages set.
+/// Are all required fields set in the message and all embedded messages.
@property(nonatomic, readonly, getter=isInitialized) BOOL initialized;
-// Returns an autoreleased instance.
+/// Returns an autoreleased instance.
+ (instancetype)message;
-// Create a message based on a variety of inputs. If there is a data parse
-// error, nil is returned and if not NULL, errorPtr is filled in.
-// NOTE: In DEBUG ONLY, the message is also checked for all required field,
-// if one is missing, the parse will fail (returning nil, filling in errorPtr).
-+ (instancetype)parseFromData:(NSData *)data error:(NSError **)errorPtr;
-+ (instancetype)parseFromData:(NSData *)data
- extensionRegistry:(nullable GPBExtensionRegistry *)extensionRegistry
- error:(NSError **)errorPtr;
-+ (instancetype)parseFromCodedInputStream:(GPBCodedInputStream *)input
- extensionRegistry:
- (nullable GPBExtensionRegistry *)extensionRegistry
- error:(NSError **)errorPtr;
-
-// Create a message based on delimited input. If there is a data parse
-// error, nil is returned and if not NULL, errorPtr is filled in.
-+ (instancetype)parseDelimitedFromCodedInputStream:(GPBCodedInputStream *)input
+/// Creates a new instance by parsing the data. This method should be sent to
+/// the generated message class that the data should be interpreted as. If
+/// there is an error the method returns nil and the error is returned in
+/// errorPtr (when provided).
+///
+/// @note In DEBUG builds, the parsed message is checked to be sure all required
+/// fields were provided, and the parse will fail if some are missing.
+///
+/// @note The errors returned are likely coming from the domain and codes listed
+/// at the top of this file and GPBCodedInputStream.h.
+///
+/// @param data The data to parse.
+/// @param errorPtr An optional error pointer to fill in with a failure reason if
+/// the data can not be parsed.
+///
+/// @return A new instance of the class messaged.
++ (nullable instancetype)parseFromData:(NSData *)data error:(NSError **)errorPtr;
+
+/// Creates a new instance by parsing the data. This method should be sent to
+/// the generated message class that the data should be interpreted as. If
+/// there is an error the method returns nil and the error is returned in
+/// errorPtr (when provided).
+///
+/// @note In DEBUG builds, the parsed message is checked to be sure all required
+/// fields were provided, and the parse will fail if some are missing.
+///
+/// @note The errors returned are likely coming from the domain and codes listed
+/// at the top of this file and GPBCodedInputStream.h.
+///
+/// @param data The data to parse.
+/// @param extensionRegistry The extension registry to use to look up extensions.
+/// @param errorPtr An optional error pointer to fill in with a failure
+/// reason if the data can not be parsed.
+///
+/// @return A new instance of the class messaged.
++ (nullable instancetype)parseFromData:(NSData *)data
+ extensionRegistry:(nullable GPBExtensionRegistry *)extensionRegistry
+ error:(NSError **)errorPtr;
+
+/// Creates a new instance by parsing the data from the given input stream. This
+/// method should be sent to the generated message class that the data should
+/// be interpreted as. If there is an error the method returns nil and the error
+/// is returned in errorPtr (when provided).
+///
+/// @note In DEBUG builds, the parsed message is checked to be sure all required
+/// fields were provided, and the parse will fail if some are missing.
+///
+/// @note The errors returned are likely coming from the domain and codes listed
+/// at the top of this file and GPBCodedInputStream.h.
+///
+/// @param input The stream to read data from.
+/// @param extensionRegistry The extension registry to use to look up extensions.
+/// @param errorPtr An optional error pointer to fill in with a failure
+/// reason if the data can not be parsed.
+///
+/// @return A new instance of the class messaged.
++ (nullable instancetype)parseFromCodedInputStream:(GPBCodedInputStream *)input
extensionRegistry:
(nullable GPBExtensionRegistry *)extensionRegistry
error:(NSError **)errorPtr;
-// If there is a data parse error, nil is returned and if not NULL, errorPtr is
-// filled in.
-// NOTE: In DEBUG ONLY, the message is also checked for all required field,
-// if one is missing, the parse will fail (returning nil, filling in errorPtr).
-- (instancetype)initWithData:(NSData *)data error:(NSError **)errorPtr;
-- (instancetype)initWithData:(NSData *)data
- extensionRegistry:(nullable GPBExtensionRegistry *)extensionRegistry
- error:(NSError **)errorPtr;
-- (instancetype)initWithCodedInputStream:(GPBCodedInputStream *)input
- extensionRegistry:
- (nullable GPBExtensionRegistry *)extensionRegistry
- error:(NSError **)errorPtr;
-
-// Serializes the message and writes it to output.
+/// Creates a new instance by parsing the data from the given input stream. This
+/// method should be sent to the generated message class that the data should
+/// be interpreted as. If there is an error the method returns nil and the error
+/// is returned in errorPtr (when provided).
+///
+/// @note Unlike the parseFrom... methods, this never checks to see if all of
+/// the required fields are set. So this method can be used to reload
+/// messages that may not be complete.
+///
+/// @note The errors returned are likely coming from the domain and codes listed
+/// at the top of this file and GPBCodedInputStream.h.
+///
+/// @param input The stream to read data from.
+/// @param extensionRegistry The extension registry to use to look up extensions.
+/// @param errorPtr An optional error pointer to fill in with a failure
+/// reason if the data can not be parsed.
+///
+/// @return A new instance of the class messaged.
++ (nullable instancetype)parseDelimitedFromCodedInputStream:(GPBCodedInputStream *)input
+ extensionRegistry:
+ (nullable GPBExtensionRegistry *)extensionRegistry
+ error:(NSError **)errorPtr;
+
+/// Initializes an instance by parsing the data. This method should be sent to
+/// the generated message class that the data should be interpreted as. If
+/// there is an error the method returns nil and the error is returned in
+/// errorPtr (when provided).
+///
+/// @note In DEBUG builds, the parsed message is checked to be sure all required
+/// fields were provided, and the parse will fail if some are missing.
+///
+/// @note The errors returned are likely coming from the domain and codes listed
+/// at the top of this file and GPBCodedInputStream.h.
+///
+/// @param data The data to parse.
+/// @param errorPtr An optional error pointer to fill in with a failure reason if
+/// the data can not be parsed.
+- (nullable instancetype)initWithData:(NSData *)data error:(NSError **)errorPtr;
+
+/// Initializes an instance by parsing the data. This method should be sent to
+/// the generated message class that the data should be interpreted as. If
+/// there is an error the method returns nil and the error is returned in
+/// errorPtr (when provided).
+///
+/// @note In DEBUG builds, the parsed message is checked to be sure all required
+/// fields were provided, and the parse will fail if some are missing.
+///
+/// @note The errors returned are likely coming from the domain and codes listed
+/// at the top of this file and GPBCodedInputStream.h.
+///
+/// @param data The data to parse.
+/// @param extensionRegistry The extension registry to use to look up extensions.
+/// @param errorPtr An optional error pointer to fill in with a failure
+/// reason if the data can not be parsed.
+- (nullable instancetype)initWithData:(NSData *)data
+ extensionRegistry:(nullable GPBExtensionRegistry *)extensionRegistry
+ error:(NSError **)errorPtr;
+
+/// Initializes an instance by parsing the data from the given input stream. This
+/// method should be sent to the generated message class that the data should
+/// be interpreted as. If there is an error the method returns nil and the error
+/// is returned in errorPtr (when provided).
+///
+/// @note Unlike the parseFrom... methods, this never checks to see if all of
+/// the required fields are set. So this method can be used to reload
+/// messages that may not be complete.
+///
+/// @note The errors returned are likely coming from the domain and codes listed
+/// at the top of this file and GPBCodedInputStream.h.
+///
+/// @param input The stream to read data from.
+/// @param extensionRegistry The extension registry to use to look up extensions.
+/// @param errorPtr An optional error pointer to fill in with a failure
+/// reason if the data can not be parsed.
+- (nullable instancetype)initWithCodedInputStream:(GPBCodedInputStream *)input
+ extensionRegistry:
+ (nullable GPBExtensionRegistry *)extensionRegistry
+ error:(NSError **)errorPtr;
+
+/// Writes out the message to the given output stream.
- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)output;
+/// Writes out the message to the given output stream.
- (void)writeToOutputStream:(NSOutputStream *)output;
-// Serializes the message and writes it to output, but writes the size of the
-// message as a variant before writing the message.
+/// Writes out a varint for the message size followed by the the message to
+/// the given output stream.
- (void)writeDelimitedToCodedOutputStream:(GPBCodedOutputStream *)output;
+/// Writes out a varint for the message size followed by the the message to
+/// the given output stream.
- (void)writeDelimitedToOutputStream:(NSOutputStream *)output;
-// Serializes the message to an NSData. Note that this value is not cached, so
-// if you are using it repeatedly, cache it yourself. If there is an error
-// while generating the data, nil is returned.
-// NOTE: In DEBUG ONLY, the message is also checked for all required field,
-// if one is missing, nil will be returned.
+/// Serializes the message to a @c NSData.
+///
+/// If there is an error while generating the data, nil is returned.
+///
+/// @note This value is not cached, so if you are using it repeatedly, cache
+/// it yourself.
+///
+/// @note In DEBUG ONLY, the message is also checked for all required field,
+/// if one is missing, nil will be returned.
- (nullable NSData *)data;
-// Same as -[data], except a delimiter is added to the start of the data
-// indicating the size of the message data that follows.
+/// Serializes a varint with the message size followed by the message data,
+/// returning that as a @c NSData.
+///
+/// @note This value is not cached, so if you are using it repeatedly, cache
+/// it yourself.
- (NSData *)delimitedData;
-// Returns the size of the object if it were serialized.
-// This is not a cached value. If you are following a pattern like this:
-// size_t size = [aMsg serializedSize];
-// NSMutableData *foo = [NSMutableData dataWithCapacity:size + sizeof(size)];
-// [foo writeSize:size];
-// [foo appendData:[aMsg data]];
-// you would be better doing:
-// NSData *data = [aMsg data];
-// NSUInteger size = [aMsg length];
-// NSMutableData *foo = [NSMutableData dataWithCapacity:size + sizeof(size)];
-// [foo writeSize:size];
-// [foo appendData:data];
+/// Calculates the size of the object if it were serialized.
+///
+/// This is not a cached value. If you are following a pattern like this:
+/// @code
+/// size_t size = [aMsg serializedSize];
+/// NSMutableData *foo = [NSMutableData dataWithCapacity:size + sizeof(size)];
+/// [foo writeSize:size];
+/// [foo appendData:[aMsg data]];
+/// @endcode
+/// you would be better doing:
+/// @code
+/// NSData *data = [aMsg data];
+/// NSUInteger size = [aMsg length];
+/// NSMutableData *foo = [NSMutableData dataWithCapacity:size + sizeof(size)];
+/// [foo writeSize:size];
+/// [foo appendData:data];
+/// @endcode
- (size_t)serializedSize;
-// Return the descriptor for the message
+/// Return the descriptor for the message class.
+ (GPBDescriptor *)descriptor;
+/// Return the descriptor for the message.
- (GPBDescriptor *)descriptor;
-// Extensions use boxed values (NSNumbers) for PODs, NSMutableArrays for
-// repeated. If the extension is a Message one will be auto created for you
-// and returned similar to fields.
+/// Returns an array with the currently set GPBExtensionDescriptors.
+- (NSArray *)extensionsCurrentlySet;
+
+/// Test to see if the given extension is set on the message.
- (BOOL)hasExtension:(GPBExtensionDescriptor *)extension;
+
+/// Fetches the given extension's value for this message.
+///
+/// Extensions use boxed values (NSNumbers) for PODs and NSMutableArrays for
+/// repeated fields. If the extension is a Message one will be auto created for you
+/// and returned similar to fields.
- (nullable id)getExtension:(GPBExtensionDescriptor *)extension;
+
+/// Sets the given extension's value for this message. This is only for single
+/// field extensions (i.e. - not repeated fields).
+///
+/// Extensions use boxed values (@c NSNumbers).
- (void)setExtension:(GPBExtensionDescriptor *)extension value:(nullable id)value;
+
+/// Adds the given value to the extension for this message. This is only for
+/// repeated field extensions. If the field is a repeated POD type the @c value
+/// is a @c NSNumber.
- (void)addExtension:(GPBExtensionDescriptor *)extension value:(id)value;
+
+/// Replaces the given value at an index for the extension on this message. This
+/// is only for repeated field extensions. If the field is a repeated POD type
+/// the @c value is a @c NSNumber.
- (void)setExtension:(GPBExtensionDescriptor *)extension
index:(NSUInteger)index
value:(id)value;
+
+/// Clears the given extension for this message.
- (void)clearExtension:(GPBExtensionDescriptor *)extension;
-// Resets all fields to their default values.
+/// Resets all of the fields of this message to their default values.
- (void)clear;
-// Parses a message of this type from the input and merges it with this
-// message.
-// NOTE: This will throw if there is an error parsing the data.
+/// Parses a message of this type from the input and merges it with this
+/// message.
+///
+/// @note This will throw if there is an error parsing the data.
- (void)mergeFromData:(NSData *)data
extensionRegistry:(nullable GPBExtensionRegistry *)extensionRegistry;
-// Merges the fields from another message (of the same type) into this
-// message.
+/// Merges the fields from another message (of the same type) into this
+/// message.
- (void)mergeFrom:(GPBMessage *)other;
@end
diff --git a/objectivec/GPBMessage.m b/objectivec/GPBMessage.m
index d9080c3f..4a6f0612 100644
--- a/objectivec/GPBMessage.m
+++ b/objectivec/GPBMessage.m
@@ -35,7 +35,7 @@
#import "GPBArray_PackagePrivate.h"
#import "GPBCodedInputStream_PackagePrivate.h"
-#import "GPBCodedOutputStream.h"
+#import "GPBCodedOutputStream_PackagePrivate.h"
#import "GPBDescriptor_PackagePrivate.h"
#import "GPBDictionary_PackagePrivate.h"
#import "GPBExtensionInternals.h"
@@ -44,28 +44,19 @@
#import "GPBUnknownFieldSet_PackagePrivate.h"
#import "GPBUtilities_PackagePrivate.h"
+// Direct access is use for speed, to avoid even internally declaring things
+// read/write, etc. The warning is enabled in the project to ensure code calling
+// protos can turn on -Wdirect-ivar-access without issues.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdirect-ivar-access"
+
NSString *const GPBMessageErrorDomain =
GPBNSStringifySymbol(GPBMessageErrorDomain);
-#ifdef DEBUG
-NSString *const GPBExceptionMessageKey =
- GPBNSStringifySymbol(GPBExceptionMessage);
-#endif // DEBUG
+NSString *const GPBErrorReasonKey = @"Reason";
static NSString *const kGPBDataCoderKey = @"GPBData";
-#ifndef _GPBCompileAssert
- #if __has_feature(c_static_assert) || __has_extension(c_static_assert)
- #define _GPBCompileAssert(test, msg) _Static_assert((test), #msg)
- #else
- // Pre-Xcode 7 support.
- #define _GPBCompileAssertSymbolInner(line, msg) _GPBCompileAssert ## line ## __ ## msg
- #define _GPBCompileAssertSymbol(line, msg) _GPBCompileAssertSymbolInner(line, msg)
- #define _GPBCompileAssert(test, msg) \
- typedef char _GPBCompileAssertSymbol(__LINE__, msg) [ ((test) ? 1 : -1) ]
- #endif // __has_feature(c_static_assert) || __has_extension(c_static_assert)
-#endif // _GPBCompileAssert
-
//
// PLEASE REMEMBER:
//
@@ -107,20 +98,35 @@ static NSMutableDictionary *CloneExtensionMap(NSDictionary *extensionMap,
NSZone *zone)
__attribute__((ns_returns_retained));
+#ifdef DEBUG
static NSError *MessageError(NSInteger code, NSDictionary *userInfo) {
return [NSError errorWithDomain:GPBMessageErrorDomain
code:code
userInfo:userInfo];
}
+#endif
+
+static NSError *ErrorFromException(NSException *exception) {
+ NSError *error = nil;
-static NSError *MessageErrorWithReason(NSInteger code, NSString *reason) {
- NSDictionary *userInfo = nil;
- if ([reason length]) {
- userInfo = @{ @"Reason" : reason };
+ if ([exception.name isEqual:GPBCodedInputStreamException]) {
+ NSDictionary *exceptionInfo = exception.userInfo;
+ error = exceptionInfo[GPBCodedInputStreamUnderlyingErrorKey];
}
- return MessageError(code, userInfo);
-}
+ if (!error) {
+ NSString *reason = exception.reason;
+ NSDictionary *userInfo = nil;
+ if ([reason length]) {
+ userInfo = @{ GPBErrorReasonKey : reason };
+ }
+
+ error = [NSError errorWithDomain:GPBMessageErrorDomain
+ code:GPBMessageErrorCodeOther
+ userInfo:userInfo];
+ }
+ return error;
+}
static void CheckExtension(GPBMessage *self,
GPBExtensionDescriptor *extension) {
@@ -568,13 +574,14 @@ static id GetArrayIvarWithField(GPBMessage *self, GPBFieldDescriptor *field) {
id array = GPBGetObjectIvarWithFieldNoAutocreate(self, field);
if (!array) {
// Check again after getting the lock.
- OSSpinLockLock(&self->readOnlyMutex_);
+ GPBPrepareReadOnlySemaphore(self);
+ dispatch_semaphore_wait(self->readOnlySemaphore_, DISPATCH_TIME_FOREVER);
array = GPBGetObjectIvarWithFieldNoAutocreate(self, field);
if (!array) {
array = CreateArrayForField(field, self);
GPBSetAutocreatedRetainedObjectIvarWithField(self, field, array);
}
- OSSpinLockUnlock(&self->readOnlyMutex_);
+ dispatch_semaphore_signal(self->readOnlySemaphore_);
}
return array;
}
@@ -598,13 +605,14 @@ static id GetMapIvarWithField(GPBMessage *self, GPBFieldDescriptor *field) {
id dict = GPBGetObjectIvarWithFieldNoAutocreate(self, field);
if (!dict) {
// Check again after getting the lock.
- OSSpinLockLock(&self->readOnlyMutex_);
+ GPBPrepareReadOnlySemaphore(self);
+ dispatch_semaphore_wait(self->readOnlySemaphore_, DISPATCH_TIME_FOREVER);
dict = GPBGetObjectIvarWithFieldNoAutocreate(self, field);
if (!dict) {
dict = CreateMapForField(field, self);
GPBSetAutocreatedRetainedObjectIvarWithField(self, field, dict);
}
- OSSpinLockUnlock(&self->readOnlyMutex_);
+ dispatch_semaphore_signal(self->readOnlySemaphore_);
}
return dict;
}
@@ -704,7 +712,7 @@ void GPBClearMessageAutocreator(GPBMessage *self) {
return;
}
-#if DEBUG && !defined(NS_BLOCK_ASSERTIONS)
+#if defined(DEBUG) && DEBUG && !defined(NS_BLOCK_ASSERTIONS)
// Either the autocreator must have its "has" flag set to YES, or it must be
// NO and not equal to ourselves.
BOOL autocreatorHas =
@@ -789,14 +797,8 @@ static GPBUnknownFieldSet *GetOrMakeUnknownFields(GPBMessage *self) {
file:fileDescriptor
fields:NULL
fieldCount:0
- oneofs:NULL
- oneofCount:0
- enums:NULL
- enumCount:0
- ranges:NULL
- rangeCount:0
storageSize:0
- wireFormat:NO];
+ flags:0];
}
return descriptor;
}
@@ -809,8 +811,6 @@ static GPBUnknownFieldSet *GetOrMakeUnknownFields(GPBMessage *self) {
if ((self = [super init])) {
messageStorage_ = (GPBMessage_StoragePtr)(
((uint8_t *)self) + class_getInstanceSize([self class]));
-
- readOnlyMutex_ = OS_SPINLOCK_INIT;
}
return self;
@@ -834,8 +834,7 @@ static GPBUnknownFieldSet *GetOrMakeUnknownFields(GPBMessage *self) {
[self release];
self = nil;
if (errorPtr) {
- *errorPtr = MessageErrorWithReason(GPBMessageErrorCodeMalformedData,
- exception.reason);
+ *errorPtr = ErrorFromException(exception);
}
}
#ifdef DEBUG
@@ -866,8 +865,7 @@ static GPBUnknownFieldSet *GetOrMakeUnknownFields(GPBMessage *self) {
[self release];
self = nil;
if (errorPtr) {
- *errorPtr = MessageErrorWithReason(GPBMessageErrorCodeMalformedData,
- exception.reason);
+ *errorPtr = ErrorFromException(exception);
}
}
#ifdef DEBUG
@@ -886,6 +884,9 @@ static GPBUnknownFieldSet *GetOrMakeUnknownFields(GPBMessage *self) {
- (void)dealloc {
[self internalClear:NO];
NSCAssert(!autocreator_, @"Autocreator was not cleared before dealloc.");
+ if (readOnlySemaphore_) {
+ dispatch_release(readOnlySemaphore_);
+ }
[super dealloc];
}
@@ -1723,7 +1724,8 @@ static GPBUnknownFieldSet *GetOrMakeUnknownFields(GPBMessage *self) {
}
// Check for an autocreated value.
- OSSpinLockLock(&readOnlyMutex_);
+ GPBPrepareReadOnlySemaphore(self);
+ dispatch_semaphore_wait(readOnlySemaphore_, DISPATCH_TIME_FOREVER);
value = [autocreatedExtensionMap_ objectForKey:extension];
if (!value) {
// Auto create the message extensions to match normal fields.
@@ -1740,7 +1742,7 @@ static GPBUnknownFieldSet *GetOrMakeUnknownFields(GPBMessage *self) {
[value release];
}
- OSSpinLockUnlock(&readOnlyMutex_);
+ dispatch_semaphore_signal(readOnlySemaphore_);
return value;
}
@@ -1750,7 +1752,7 @@ static GPBUnknownFieldSet *GetOrMakeUnknownFields(GPBMessage *self) {
}
- (BOOL)hasExtension:(GPBExtensionDescriptor *)extension {
-#if DEBUG
+#if defined(DEBUG) && DEBUG
CheckExtension(self, extension);
#endif // DEBUG
return nil != [extensionMap_ objectForKey:extension];
@@ -1775,11 +1777,6 @@ static GPBUnknownFieldSet *GetOrMakeUnknownFields(GPBMessage *self) {
}
}
-- (NSArray *)sortedExtensionsInUse {
- return [[extensionMap_ allKeys]
- sortedArrayUsingSelector:@selector(compareByFieldNumber:)];
-}
-
- (void)setExtension:(GPBExtensionDescriptor *)extension value:(id)value {
if (!value) {
[self clearExtension:extension];
@@ -1934,16 +1931,13 @@ static GPBUnknownFieldSet *GetOrMakeUnknownFields(GPBMessage *self) {
}
}
@catch (NSException *exception) {
- [message release];
message = nil;
if (errorPtr) {
- *errorPtr = MessageErrorWithReason(GPBMessageErrorCodeMalformedData,
- exception.reason);
+ *errorPtr = ErrorFromException(exception);
}
}
#ifdef DEBUG
if (message && !message.initialized) {
- [message release];
message = nil;
if (errorPtr) {
*errorPtr = MessageError(GPBMessageErrorCodeMissingRequiredField, nil);
@@ -2280,6 +2274,9 @@ static void MergeRepeatedNotPackedFieldFromCodedInputStream(
while (YES) {
BOOL merged = NO;
tag = GPBCodedInputStreamReadTag(state);
+ if (tag == 0) {
+ break; // Reached end.
+ }
for (NSUInteger i = 0; i < numFields; ++i) {
if (startingIndex >= numFields) startingIndex = 0;
GPBFieldDescriptor *fieldDescriptor = fields[startingIndex];
@@ -2318,7 +2315,7 @@ static void MergeRepeatedNotPackedFieldFromCodedInputStream(
}
} // for(i < numFields)
- if (!merged) {
+ if (!merged && (tag != 0)) {
// Primitive, repeated types can be packed on unpacked on the wire, and
// are parsed either way. The above loop covered tag in the preferred
// for, so this need to check the alternate form.
@@ -2573,7 +2570,7 @@ static void MergeRepeatedNotPackedFieldFromCodedInputStream(
#pragma mark - isEqual: & hash Support
-- (BOOL)isEqual:(GPBMessage *)other {
+- (BOOL)isEqual:(id)other {
if (other == self) {
return YES;
}
@@ -2582,9 +2579,10 @@ static void MergeRepeatedNotPackedFieldFromCodedInputStream(
return NO;
}
+ GPBMessage *otherMsg = other;
GPBDescriptor *descriptor = [[self class] descriptor];
uint8_t *selfStorage = (uint8_t *)messageStorage_;
- uint8_t *otherStorage = (uint8_t *)other->messageStorage_;
+ uint8_t *otherStorage = (uint8_t *)otherMsg->messageStorage_;
for (GPBFieldDescriptor *field in descriptor->fields_) {
if (GPBFieldIsMapOrArray(field)) {
@@ -2619,9 +2617,13 @@ static void MergeRepeatedNotPackedFieldFromCodedInputStream(
size_t fieldOffset = field->description_->offset;
switch (fieldDataType) {
case GPBDataTypeBool: {
- BOOL *selfValPtr = (BOOL *)&selfStorage[fieldOffset];
- BOOL *otherValPtr = (BOOL *)&otherStorage[fieldOffset];
- if (*selfValPtr != *otherValPtr) {
+ // Bools are stored in has_bits to avoid needing explicit space in
+ // the storage structure.
+ // (the field number passed to the HasIvar helper doesn't really
+ // matter since the offset is never negative)
+ BOOL selfValue = GPBGetHasIvar(self, (int32_t)(fieldOffset), 0);
+ BOOL otherValue = GPBGetHasIvar(other, (int32_t)(fieldOffset), 0);
+ if (selfValue != otherValue) {
return NO;
}
break;
@@ -2633,7 +2635,7 @@ static void MergeRepeatedNotPackedFieldFromCodedInputStream(
case GPBDataTypeFixed32:
case GPBDataTypeUInt32:
case GPBDataTypeFloat: {
- _GPBCompileAssert(sizeof(float) == sizeof(uint32_t), float_not_32_bits);
+ GPBInternalCompileAssert(sizeof(float) == sizeof(uint32_t), float_not_32_bits);
// These are all 32bit, signed/unsigned doesn't matter for equality.
uint32_t *selfValPtr = (uint32_t *)&selfStorage[fieldOffset];
uint32_t *otherValPtr = (uint32_t *)&otherStorage[fieldOffset];
@@ -2648,7 +2650,7 @@ static void MergeRepeatedNotPackedFieldFromCodedInputStream(
case GPBDataTypeFixed64:
case GPBDataTypeUInt64:
case GPBDataTypeDouble: {
- _GPBCompileAssert(sizeof(double) == sizeof(uint64_t), double_not_64_bits);
+ GPBInternalCompileAssert(sizeof(double) == sizeof(uint64_t), double_not_64_bits);
// These are all 64bit, signed/unsigned doesn't matter for equality.
uint64_t *selfValPtr = (uint64_t *)&selfStorage[fieldOffset];
uint64_t *otherValPtr = (uint64_t *)&otherStorage[fieldOffset];
@@ -2674,14 +2676,14 @@ static void MergeRepeatedNotPackedFieldFromCodedInputStream(
} // for(fields)
// nil and empty are equal
- if (extensionMap_.count != 0 || other->extensionMap_.count != 0) {
- if (![extensionMap_ isEqual:other->extensionMap_]) {
+ if (extensionMap_.count != 0 || otherMsg->extensionMap_.count != 0) {
+ if (![extensionMap_ isEqual:otherMsg->extensionMap_]) {
return NO;
}
}
// nil and empty are equal
- GPBUnknownFieldSet *otherUnknowns = other->unknownFields_;
+ GPBUnknownFieldSet *otherUnknowns = otherMsg->unknownFields_;
if ([unknownFields_ countOfFields] != 0 ||
[otherUnknowns countOfFields] != 0) {
if (![unknownFields_ isEqual:otherUnknowns]) {
@@ -2730,8 +2732,12 @@ static void MergeRepeatedNotPackedFieldFromCodedInputStream(
size_t fieldOffset = field->description_->offset;
switch (fieldDataType) {
case GPBDataTypeBool: {
- BOOL *valPtr = (BOOL *)&storage[fieldOffset];
- result = prime * result + *valPtr;
+ // Bools are stored in has_bits to avoid needing explicit space in
+ // the storage structure.
+ // (the field number passed to the HasIvar helper doesn't really
+ // matter since the offset is never negative)
+ BOOL value = GPBGetHasIvar(self, (int32_t)(fieldOffset), 0);
+ result = prime * result + value;
break;
}
case GPBDataTypeSFixed32:
@@ -2741,7 +2747,7 @@ static void MergeRepeatedNotPackedFieldFromCodedInputStream(
case GPBDataTypeFixed32:
case GPBDataTypeUInt32:
case GPBDataTypeFloat: {
- _GPBCompileAssert(sizeof(float) == sizeof(uint32_t), float_not_32_bits);
+ GPBInternalCompileAssert(sizeof(float) == sizeof(uint32_t), float_not_32_bits);
// These are all 32bit, just mix it in.
uint32_t *valPtr = (uint32_t *)&storage[fieldOffset];
result = prime * result + *valPtr;
@@ -2753,7 +2759,7 @@ static void MergeRepeatedNotPackedFieldFromCodedInputStream(
case GPBDataTypeFixed64:
case GPBDataTypeUInt64:
case GPBDataTypeDouble: {
- _GPBCompileAssert(sizeof(double) == sizeof(uint64_t), double_not_64_bits);
+ GPBInternalCompileAssert(sizeof(double) == sizeof(uint64_t), double_not_64_bits);
// These are all 64bit, just mix what fits into an NSUInteger in.
uint64_t *valPtr = (uint64_t *)&storage[fieldOffset];
result = prime * result + (NSUInteger)(*valPtr);
@@ -2800,7 +2806,7 @@ static void MergeRepeatedNotPackedFieldFromCodedInputStream(
return description;
}
-#if DEBUG
+#if defined(DEBUG) && DEBUG
// Xcode 5.1 added support for custom quick look info.
// https://developer.apple.com/library/ios/documentation/IDEs/Conceptual/CustomClassDisplay_in_QuickLook/CH01-quick_look_for_custom_objects/CH01-quick_look_for_custom_objects.html#//apple_ref/doc/uid/TP40014001-CH2-SW1
@@ -3095,7 +3101,7 @@ static void ResolveIvarSet(GPBFieldDescriptor *field,
} else {
GPBOneofDescriptor *oneof = field->containingOneof_;
if (oneof && (sel == oneof->caseSel_)) {
- int32_t index = oneof->oneofDescription_->index;
+ int32_t index = GPBFieldHasIndex(field);
result.impToAdd = imp_implementationWithBlock(^(id obj) {
return GPBGetHasOneof(obj, index);
});
@@ -3190,3 +3196,35 @@ static void ResolveIvarSet(GPBFieldDescriptor *field,
}
@end
+
+#pragma mark - Messages from GPBUtilities.h but defined here for access to helpers.
+
+// Only exists for public api, no core code should use this.
+id GPBGetMessageRepeatedField(GPBMessage *self, GPBFieldDescriptor *field) {
+#if defined(DEBUG) && DEBUG
+ if (field.fieldType != GPBFieldTypeRepeated) {
+ [NSException raise:NSInvalidArgumentException
+ format:@"%@.%@ is not a repeated field.",
+ [self class], field.name];
+ }
+#endif
+ GPBDescriptor *descriptor = [[self class] descriptor];
+ GPBFileSyntax syntax = descriptor.file.syntax;
+ return GetOrCreateArrayIvarWithField(self, field, syntax);
+}
+
+// Only exists for public api, no core code should use this.
+id GPBGetMessageMapField(GPBMessage *self, GPBFieldDescriptor *field) {
+#if defined(DEBUG) && DEBUG
+ if (field.fieldType != GPBFieldTypeMap) {
+ [NSException raise:NSInvalidArgumentException
+ format:@"%@.%@ is not a map<> field.",
+ [self class], field.name];
+ }
+#endif
+ GPBDescriptor *descriptor = [[self class] descriptor];
+ GPBFileSyntax syntax = descriptor.file.syntax;
+ return GetOrCreateMapIvarWithField(self, field, syntax);
+}
+
+#pragma clang diagnostic pop
diff --git a/objectivec/GPBMessage_PackagePrivate.h b/objectivec/GPBMessage_PackagePrivate.h
index d4c3501a..02d0e16e 100644
--- a/objectivec/GPBMessage_PackagePrivate.h
+++ b/objectivec/GPBMessage_PackagePrivate.h
@@ -62,17 +62,22 @@ typedef struct GPBMessage_Storage *GPBMessage_StoragePtr;
// by *read* operations such as getters (autocreation of message fields and
// message extensions, not setting of values). Used to guarantee thread safety
// for concurrent reads on the message.
- OSSpinLock readOnlyMutex_;
+ // NOTE: OSSpinLock may seem like a good fit here but Apple engineers have
+ // pointed out that they are vulnerable to live locking on iOS in cases of
+ // priority inversion:
+ // http://mjtsai.com/blog/2015/12/16/osspinlock-is-unsafe/
+ // https://lists.swift.org/pipermail/swift-dev/Week-of-Mon-20151214/000372.html
+ // Use of readOnlySemaphore_ must be prefaced by a call to
+ // GPBPrepareReadOnlySemaphore to ensure it has been created. This allows
+ // readOnlySemaphore_ to be only created when actually needed.
+ dispatch_once_t readOnlySemaphoreCreationOnce_;
+ dispatch_semaphore_t readOnlySemaphore_;
}
// Gets an extension value without autocreating the result if not found. (i.e.
// returns nil if the extension is not set)
- (id)getExistingExtension:(GPBExtensionDescriptor *)extension;
-// Returns an array of GPBExtensionDescriptor* for all the extensions currently
-// in use on the message. They are sorted by field number.
-- (NSArray *)sortedExtensionsInUse;
-
// Parses a message of this type from the input and merges it with this
// message.
//
@@ -98,6 +103,17 @@ typedef struct GPBMessage_Storage *GPBMessage_StoragePtr;
CF_EXTERN_C_BEGIN
+
+// Call this before using the readOnlySemaphore_. This ensures it is created only once.
+NS_INLINE void GPBPrepareReadOnlySemaphore(GPBMessage *self) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdirect-ivar-access"
+ dispatch_once(&self->readOnlySemaphoreCreationOnce_, ^{
+ self->readOnlySemaphore_ = dispatch_semaphore_create(1);
+ });
+#pragma clang diagnostic pop
+}
+
// Returns a new instance that was automatically created by |autocreator| for
// its field |field|.
GPBMessage *GPBCreateMessageWithAutocreator(Class msgClass,
diff --git a/objectivec/GPBProtocolBuffers.h b/objectivec/GPBProtocolBuffers.h
index 677903ed..68d8854e 100644
--- a/objectivec/GPBProtocolBuffers.h
+++ b/objectivec/GPBProtocolBuffers.h
@@ -44,14 +44,33 @@
#import "GPBWellKnownTypes.h"
#import "GPBWireFormat.h"
+// This CPP symbol can be defined to use imports that match up to the framework
+// imports needed when using CocoaPods.
+#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS)
+ #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0
+#endif
+
// Well-known proto types
-#import "google/protobuf/Any.pbobjc.h"
-#import "google/protobuf/Api.pbobjc.h"
-#import "google/protobuf/Duration.pbobjc.h"
-#import "google/protobuf/Empty.pbobjc.h"
-#import "google/protobuf/FieldMask.pbobjc.h"
-#import "google/protobuf/SourceContext.pbobjc.h"
-#import "google/protobuf/Struct.pbobjc.h"
-#import "google/protobuf/Timestamp.pbobjc.h"
-#import "google/protobuf/Type.pbobjc.h"
-#import "google/protobuf/Wrappers.pbobjc.h"
+#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS
+ #import <Protobuf/Any.pbobjc.h>
+ #import <Protobuf/Api.pbobjc.h>
+ #import <Protobuf/Duration.pbobjc.h>
+ #import <Protobuf/Empty.pbobjc.h>
+ #import <Protobuf/FieldMask.pbobjc.h>
+ #import <Protobuf/SourceContext.pbobjc.h>
+ #import <Protobuf/Struct.pbobjc.h>
+ #import <Protobuf/Timestamp.pbobjc.h>
+ #import <Protobuf/Type.pbobjc.h>
+ #import <Protobuf/Wrappers.pbobjc.h>
+#else
+ #import "google/protobuf/Any.pbobjc.h"
+ #import "google/protobuf/Api.pbobjc.h"
+ #import "google/protobuf/Duration.pbobjc.h"
+ #import "google/protobuf/Empty.pbobjc.h"
+ #import "google/protobuf/FieldMask.pbobjc.h"
+ #import "google/protobuf/SourceContext.pbobjc.h"
+ #import "google/protobuf/Struct.pbobjc.h"
+ #import "google/protobuf/Timestamp.pbobjc.h"
+ #import "google/protobuf/Type.pbobjc.h"
+ #import "google/protobuf/Wrappers.pbobjc.h"
+#endif
diff --git a/objectivec/GPBProtocolBuffers.m b/objectivec/GPBProtocolBuffers.m
index e9cbfb42..d04c8be1 100644
--- a/objectivec/GPBProtocolBuffers.m
+++ b/objectivec/GPBProtocolBuffers.m
@@ -31,6 +31,14 @@
// If you want to build protocol buffers in your own project without adding the
// project dependency, you can just add this file.
+
+// This warning seems to treat code differently when it is #imported than when
+// it is inline in the file. GPBDictionary.m compiles cleanly in other targets,
+// but when #imported here it triggers a bunch of warnings that don't make
+// much sense, and don't trigger when compiled directly. So we shut off the
+// warnings here.
+#pragma clang diagnostic ignored "-Wnullability-completeness"
+
#import "GPBArray.m"
#import "GPBCodedInputStream.m"
#import "GPBCodedOutputStream.m"
@@ -46,17 +54,13 @@
#import "GPBWellKnownTypes.m"
#import "GPBWireFormat.m"
-#import "google/protobuf/Descriptor.pbobjc.m"
-
-// Duration and Timestamp are #imported into GPBWellKnownTypes.m to the
-// Objective C categories added will always be linked in with the classes.
#import "google/protobuf/Any.pbobjc.m"
#import "google/protobuf/Api.pbobjc.m"
-// #import "google/protobuf/Duration.pbobjc.m"
+#import "google/protobuf/Duration.pbobjc.m"
#import "google/protobuf/Empty.pbobjc.m"
#import "google/protobuf/FieldMask.pbobjc.m"
#import "google/protobuf/SourceContext.pbobjc.m"
#import "google/protobuf/Struct.pbobjc.m"
-// #import "google/protobuf/Timestamp.pbobjc.m"
+#import "google/protobuf/Timestamp.pbobjc.m"
#import "google/protobuf/Type.pbobjc.m"
#import "google/protobuf/Wrappers.pbobjc.m"
diff --git a/objectivec/GPBRootObject.h b/objectivec/GPBRootObject.h
index e2af5d97..c05b5c62 100644
--- a/objectivec/GPBRootObject.h
+++ b/objectivec/GPBRootObject.h
@@ -34,11 +34,12 @@
NS_ASSUME_NONNULL_BEGIN
-// All Root Objects derive from GPBRootObject. It supplies a registry
-// for derived classes to register their extensions to.
+/// Every generated proto file defines a local "Root" class that exposes a
+/// @c GPBExtensionRegistry for all the extensions defined by that file and
+/// the files it depends on.
@interface GPBRootObject : NSObject
-// Per class registry.
+/// An extension registry for the given file and all the files it depends on.
+ (GPBExtensionRegistry *)extensionRegistry;
@end
diff --git a/objectivec/GPBRootObject.m b/objectivec/GPBRootObject.m
index 7036723f..4570716f 100644
--- a/objectivec/GPBRootObject.m
+++ b/objectivec/GPBRootObject.m
@@ -31,7 +31,6 @@
#import "GPBRootObject_PackagePrivate.h"
#import <objc/runtime.h>
-#import <libkern/OSAtomic.h>
#import <CoreFoundation/CoreFoundation.h>
@@ -96,13 +95,19 @@ static CFHashCode GPBRootExtensionKeyHash(const void *value) {
return jenkins_one_at_a_time_hash(key);
}
-static OSSpinLock gExtensionSingletonDictionaryLock_ = OS_SPINLOCK_INIT;
+// NOTE: OSSpinLock may seem like a good fit here but Apple engineers have
+// pointed out that they are vulnerable to live locking on iOS in cases of
+// priority inversion:
+// http://mjtsai.com/blog/2015/12/16/osspinlock-is-unsafe/
+// https://lists.swift.org/pipermail/swift-dev/Week-of-Mon-20151214/000372.html
+static dispatch_semaphore_t gExtensionSingletonDictionarySemaphore;
static CFMutableDictionaryRef gExtensionSingletonDictionary = NULL;
static GPBExtensionRegistry *gDefaultExtensionRegistry = NULL;
+ (void)initialize {
// Ensure the global is started up.
if (!gExtensionSingletonDictionary) {
+ gExtensionSingletonDictionarySemaphore = dispatch_semaphore_create(1);
CFDictionaryKeyCallBacks keyCallBacks = {
// See description above for reason for using custom dictionary.
0,
@@ -134,9 +139,10 @@ static GPBExtensionRegistry *gDefaultExtensionRegistry = NULL;
+ (void)globallyRegisterExtension:(GPBExtensionDescriptor *)field {
const char *key = [field singletonNameC];
- OSSpinLockLock(&gExtensionSingletonDictionaryLock_);
+ dispatch_semaphore_wait(gExtensionSingletonDictionarySemaphore,
+ DISPATCH_TIME_FOREVER);
CFDictionarySetValue(gExtensionSingletonDictionary, key, field);
- OSSpinLockUnlock(&gExtensionSingletonDictionaryLock_);
+ dispatch_semaphore_signal(gExtensionSingletonDictionarySemaphore);
}
static id ExtensionForName(id self, SEL _cmd) {
@@ -166,14 +172,24 @@ static id ExtensionForName(id self, SEL _cmd) {
key[classNameLen] = '_';
memcpy(&key[classNameLen + 1], selName, selNameLen);
key[classNameLen + 1 + selNameLen] = '\0';
- OSSpinLockLock(&gExtensionSingletonDictionaryLock_);
+
+ // NOTE: Even though this method is called from another C function,
+ // gExtensionSingletonDictionarySemaphore and gExtensionSingletonDictionary
+ // will always be initialized. This is because this call flow is just to
+ // lookup the Extension, meaning the code is calling an Extension class
+ // message on a Message or Root class. This guarantees that the class was
+ // initialized and Message classes ensure their Root was also initialized.
+ NSAssert(gExtensionSingletonDictionary, @"Startup order broken!");
+
+ dispatch_semaphore_wait(gExtensionSingletonDictionarySemaphore,
+ DISPATCH_TIME_FOREVER);
id extension = (id)CFDictionaryGetValue(gExtensionSingletonDictionary, key);
if (extension) {
// The method is getting wired in to the class, so no need to keep it in
// the dictionary.
CFDictionaryRemoveValue(gExtensionSingletonDictionary, key);
}
- OSSpinLockUnlock(&gExtensionSingletonDictionaryLock_);
+ dispatch_semaphore_signal(gExtensionSingletonDictionarySemaphore);
return extension;
}
diff --git a/objectivec/GPBRuntimeTypes.h b/objectivec/GPBRuntimeTypes.h
index e91d86a6..0a38b110 100644
--- a/objectivec/GPBRuntimeTypes.h
+++ b/objectivec/GPBRuntimeTypes.h
@@ -67,7 +67,7 @@ typedef union {
// Do not change the order of this enum (or add things to it) without thinking
// about it very carefully. There are several things that depend on the order.
-typedef enum {
+typedef NS_ENUM(uint8_t, GPBDataType) {
GPBDataTypeBool = 0,
GPBDataTypeFixed32,
GPBDataTypeSFixed32,
@@ -86,7 +86,7 @@ typedef enum {
GPBDataTypeMessage,
GPBDataTypeGroup,
GPBDataTypeEnum,
-} GPBDataType;
+};
enum {
// A count of the number of types in GPBDataType. Separated out from the
diff --git a/objectivec/GPBUnknownField.h b/objectivec/GPBUnknownField.h
index 12d72a9a..0f301e47 100644
--- a/objectivec/GPBUnknownField.h
+++ b/objectivec/GPBUnknownField.h
@@ -37,22 +37,51 @@
NS_ASSUME_NONNULL_BEGIN
+/// Store an unknown field. These are used in conjunction with @c GPBUnknownFieldSet
@interface GPBUnknownField : NSObject<NSCopying>
+/// The field number the data is stored under.
@property(nonatomic, readonly, assign) int32_t number;
-// Only one of these will be set.
+/// An array of varint values for this field.
@property(nonatomic, readonly, strong) GPBUInt64Array *varintList;
+
+/// An array of fixed32 values for this field.
@property(nonatomic, readonly, strong) GPBUInt32Array *fixed32List;
+
+/// An array of fixed64 values for this field.
@property(nonatomic, readonly, strong) GPBUInt64Array *fixed64List;
-@property(nonatomic, readonly, strong) NSArray *lengthDelimitedList; // NSData
-@property(nonatomic, readonly, strong) NSArray *groupList; // GPBUnknownFieldSet
-// Only one of these should be used per Field.
+/// An array of data values for this field.
+@property(nonatomic, readonly, strong) NSArray<NSData*> *lengthDelimitedList;
+
+/// An array of groups of values for this field.
+@property(nonatomic, readonly, strong) NSArray<GPBUnknownFieldSet*> *groupList;
+
+
+/// Add a value to the varintList.
+///
+/// @param value The value to add.
- (void)addVarint:(uint64_t)value;
+
+/// Add a value to the fixed32List.
+///
+/// @param value The value to add.
- (void)addFixed32:(uint32_t)value;
+
+/// Add a value to the fixed64List.
+///
+/// @param value The value to add.
- (void)addFixed64:(uint64_t)value;
+
+/// Add a value to the lengthDelimitedList.
+///
+/// @param value The value to add.
- (void)addLengthDelimited:(NSData *)value;
+
+/// Add a value to the groupList.
+///
+/// @param value The value to add.
- (void)addGroup:(GPBUnknownFieldSet *)value;
@end
diff --git a/objectivec/GPBUnknownField.m b/objectivec/GPBUnknownField.m
index c49c0dfc..30efe756 100644
--- a/objectivec/GPBUnknownField.m
+++ b/objectivec/GPBUnknownField.m
@@ -31,7 +31,7 @@
#import "GPBUnknownField_PackagePrivate.h"
#import "GPBArray.h"
-#import "GPBCodedOutputStream.h"
+#import "GPBCodedOutputStream_PackagePrivate.h"
@implementation GPBUnknownField {
@protected
@@ -39,8 +39,8 @@
GPBUInt64Array *mutableVarintList_;
GPBUInt32Array *mutableFixed32List_;
GPBUInt64Array *mutableFixed64List_;
- NSMutableArray *mutableLengthDelimitedList_;
- NSMutableArray *mutableGroupList_;
+ NSMutableArray<NSData*> *mutableLengthDelimitedList_;
+ NSMutableArray<GPBUnknownFieldSet*> *mutableGroupList_;
}
@synthesize number = number_;
@@ -67,6 +67,12 @@
[super dealloc];
}
+// Direct access is use for speed, to avoid even internally declaring things
+// read/write, etc. The warning is enabled in the project to ensure code calling
+// protos can turn on -Wdirect-ivar-access without issues.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdirect-ivar-access"
+
- (id)copyWithZone:(NSZone *)zone {
GPBUnknownField *result =
[[GPBUnknownField allocWithZone:zone] initWithNumber:number_];
@@ -323,4 +329,6 @@
}
}
+#pragma clang diagnostic pop
+
@end
diff --git a/objectivec/GPBUnknownFieldSet.h b/objectivec/GPBUnknownFieldSet.h
index d785ca16..cf612993 100644
--- a/objectivec/GPBUnknownFieldSet.h
+++ b/objectivec/GPBUnknownFieldSet.h
@@ -34,16 +34,31 @@
NS_ASSUME_NONNULL_BEGIN
+/// A collection of unknown fields.
@interface GPBUnknownFieldSet : NSObject<NSCopying>
+/// Tests to see if the given field number has a value.
+///
+/// @param number The field number to check.
+///
+/// @return YES if there is an unknown field for the given field number.
- (BOOL)hasField:(int32_t)number;
+
+/// Fetches the @c GPBUnknownField for the given field number.
+///
+/// @param number The field number to look up.
+///
+/// @return The @c GPBUnknownField or nil.
- (nullable GPBUnknownField *)getField:(int32_t)number;
+
+/// Returns the number of fields in this set.
- (NSUInteger)countOfFields;
+/// Adds the given field to the set.
- (void)addField:(GPBUnknownField *)field;
-// Returns an NSArray of the GPBFields sorted by the field numbers.
-- (NSArray *)sortedFields;
+/// Returns an NSArray of the @c GPBUnknownFields sorted by the field numbers.
+- (NSArray<GPBUnknownField*> *)sortedFields;
@end
diff --git a/objectivec/GPBUnknownFieldSet.m b/objectivec/GPBUnknownFieldSet.m
index 4ddc0d2a..9ba1d65c 100644
--- a/objectivec/GPBUnknownFieldSet.m
+++ b/objectivec/GPBUnknownFieldSet.m
@@ -93,6 +93,12 @@ static void CopyWorker(const void *key, const void *value, void *context) {
[copied release];
}
+// Direct access is use for speed, to avoid even internally declaring things
+// read/write, etc. The warning is enabled in the project to ensure code calling
+// protos can turn on -Wdirect-ivar-access without issues.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdirect-ivar-access"
+
- (id)copyWithZone:(NSZone *)zone {
GPBUnknownFieldSet *result = [[GPBUnknownFieldSet allocWithZone:zone] init];
if (fields_) {
@@ -148,7 +154,7 @@ static void CopyWorker(const void *key, const void *value, void *context) {
}
- (NSArray *)sortedFields {
- if (!fields_) return nil;
+ if (!fields_) return [NSArray array];
size_t count = CFDictionaryGetCount(fields_);
ssize_t keys[count];
GPBUnknownField *values[count];
@@ -353,6 +359,7 @@ static void GPBUnknownFieldSetMergeUnknownFields(const void *key,
}
- (BOOL)mergeFieldFrom:(int32_t)tag input:(GPBCodedInputStream *)input {
+ NSAssert(GPBWireFormatIsValidTag(tag), @"Got passed an invalid tag");
int32_t number = GPBWireFormatGetTagFieldNumber(tag);
GPBCodedInputStreamState *state = &input->state_;
switch (GPBWireFormatGetTagWireType(tag)) {
@@ -420,4 +427,6 @@ static void GPBUnknownFieldSetMergeUnknownFields(const void *key,
}
}
+#pragma clang diagnostic pop
+
@end
diff --git a/objectivec/GPBUtilities.h b/objectivec/GPBUtilities.h
index 5b55104b..b7209324 100644
--- a/objectivec/GPBUtilities.h
+++ b/objectivec/GPBUtilities.h
@@ -38,24 +38,34 @@ CF_EXTERN_C_BEGIN
NS_ASSUME_NONNULL_BEGIN
-// Generates a string that should be a valid "Text Format" for the C++ version
-// of Protocol Buffers. lineIndent can be nil if no additional line indent is
-// needed. The comments provide the names according to the ObjC library, they
-// most likely won't exactly match the original .proto file.
+/// Generates a string that should be a valid "Text Format" for the C++ version
+/// of Protocol Buffers.
+///
+/// @param message The message to generate from.
+/// @param lineIndent A string to use as the prefix for all lines generated. Can
+/// be nil if no extra indent is needed.
+///
+/// @return A @c NSString with the Text Format of the message.
NSString *GPBTextFormatForMessage(GPBMessage *message,
NSString * __nullable lineIndent);
+
+/// Generates a string that should be a valid "Text Format" for the C++ version
+/// of Protocol Buffers.
+///
+/// @param unknownSet The unknown field set to generate from.
+/// @param lineIndent A string to use as the prefix for all lines generated. Can
+/// be nil if no extra indent is needed.
+///
+/// @return A @c NSString with the Text Format of the unknown field set.
NSString *GPBTextFormatForUnknownFieldSet(GPBUnknownFieldSet * __nullable unknownSet,
NSString * __nullable lineIndent);
-//
-// Test if the given field is set on a message.
-//
+/// Test if the given field is set on a message.
BOOL GPBMessageHasFieldNumberSet(GPBMessage *self, uint32_t fieldNumber);
+/// Test if the given field is set on a message.
BOOL GPBMessageHasFieldSet(GPBMessage *self, GPBFieldDescriptor *field);
-//
-// Clear the given field of a message.
-//
+/// Clear the given field of a message.
void GPBClearMessageField(GPBMessage *self, GPBFieldDescriptor *field);
//%PDDM-EXPAND GPB_ACCESSORS()
@@ -68,60 +78,100 @@ void GPBClearMessageField(GPBMessage *self, GPBFieldDescriptor *field);
// Single Fields
+/// Gets the value of a bytes field.
NSData *GPBGetMessageBytesField(GPBMessage *self, GPBFieldDescriptor *field);
+/// Sets the value of a bytes field.
void GPBSetMessageBytesField(GPBMessage *self, GPBFieldDescriptor *field, NSData *value);
+/// Gets the value of a string field.
NSString *GPBGetMessageStringField(GPBMessage *self, GPBFieldDescriptor *field);
+/// Sets the value of a string field.
void GPBSetMessageStringField(GPBMessage *self, GPBFieldDescriptor *field, NSString *value);
+/// Gets the value of a message field.
GPBMessage *GPBGetMessageMessageField(GPBMessage *self, GPBFieldDescriptor *field);
+/// Sets the value of a message field.
void GPBSetMessageMessageField(GPBMessage *self, GPBFieldDescriptor *field, GPBMessage *value);
+/// Gets the value of a group field.
GPBMessage *GPBGetMessageGroupField(GPBMessage *self, GPBFieldDescriptor *field);
+/// Sets the value of a group field.
void GPBSetMessageGroupField(GPBMessage *self, GPBFieldDescriptor *field, GPBMessage *value);
+/// Gets the value of a bool field.
BOOL GPBGetMessageBoolField(GPBMessage *self, GPBFieldDescriptor *field);
+/// Sets the value of a bool field.
void GPBSetMessageBoolField(GPBMessage *self, GPBFieldDescriptor *field, BOOL value);
+/// Gets the value of an int32 field.
int32_t GPBGetMessageInt32Field(GPBMessage *self, GPBFieldDescriptor *field);
+/// Sets the value of an int32 field.
void GPBSetMessageInt32Field(GPBMessage *self, GPBFieldDescriptor *field, int32_t value);
+/// Gets the value of an uint32 field.
uint32_t GPBGetMessageUInt32Field(GPBMessage *self, GPBFieldDescriptor *field);
+/// Sets the value of an uint32 field.
void GPBSetMessageUInt32Field(GPBMessage *self, GPBFieldDescriptor *field, uint32_t value);
+/// Gets the value of an int64 field.
int64_t GPBGetMessageInt64Field(GPBMessage *self, GPBFieldDescriptor *field);
+/// Sets the value of an int64 field.
void GPBSetMessageInt64Field(GPBMessage *self, GPBFieldDescriptor *field, int64_t value);
+/// Gets the value of an uint64 field.
uint64_t GPBGetMessageUInt64Field(GPBMessage *self, GPBFieldDescriptor *field);
+/// Sets the value of an uint64 field.
void GPBSetMessageUInt64Field(GPBMessage *self, GPBFieldDescriptor *field, uint64_t value);
+/// Gets the value of a float field.
float GPBGetMessageFloatField(GPBMessage *self, GPBFieldDescriptor *field);
+/// Sets the value of a float field.
void GPBSetMessageFloatField(GPBMessage *self, GPBFieldDescriptor *field, float value);
+/// Gets the value of a double field.
double GPBGetMessageDoubleField(GPBMessage *self, GPBFieldDescriptor *field);
+/// Sets the value of a double field.
void GPBSetMessageDoubleField(GPBMessage *self, GPBFieldDescriptor *field, double value);
-// Get/Set the given enum field of a message. You can only Set values that are
-// members of the enum. For proto3, when doing a Get, if the value isn't a
-// memeber of the enum, kGPBUnrecognizedEnumeratorValue will be returned. The
-// the functions with "Raw" in the will bypass all checks.
+/// Get the given enum field of a message. For proto3, if the value isn't a
+/// member of the enum, @c kGPBUnrecognizedEnumeratorValue will be returned.
+/// GPBGetMessageRawEnumField will bypass the check and return whatever value
+/// was set.
int32_t GPBGetMessageEnumField(GPBMessage *self, GPBFieldDescriptor *field);
+/// Set the given enum field of a message. You can only set values that are
+/// members of the enum.
void GPBSetMessageEnumField(GPBMessage *self, GPBFieldDescriptor *field, int32_t value);
+/// Get the given enum field of a message. No check is done to ensure the value
+/// was defined in the enum.
int32_t GPBGetMessageRawEnumField(GPBMessage *self, GPBFieldDescriptor *field);
+/// Set the given enum field of a message. You can set the value to anything,
+/// even a value that is not a member of the enum.
void GPBSetMessageRawEnumField(GPBMessage *self, GPBFieldDescriptor *field, int32_t value);
// Repeated Fields
-// The object will/should be GPB*Array or NSMutableArray based on the field's
-// type.
+/// Gets the value of a repeated field.
+///
+/// The result will be @c GPB*Array or @c NSMutableArray based on the
+/// field's type.
id GPBGetMessageRepeatedField(GPBMessage *self, GPBFieldDescriptor *field);
+/// Sets the value of a repeated field.
+///
+/// The value should be @c GPB*Array or @c NSMutableArray based on the
+/// field's type.
void GPBSetMessageRepeatedField(GPBMessage *self, GPBFieldDescriptor *field, id array);
// Map Fields
-// The object will/should be GPB*Dictionary or NSMutableDictionary based on the
-// field's type.
+/// Gets the value of a map<> field.
+///
+/// The result will be @c GPB*Dictionary or @c NSMutableDictionary based on
+/// the field's type.
id GPBGetMessageMapField(GPBMessage *self, GPBFieldDescriptor *field);
+/// Sets the value of a map<> field.
+///
+/// The object should be @c GPB*Dictionary or @c NSMutableDictionary based
+/// on the field's type.
void GPBSetMessageMapField(GPBMessage *self, GPBFieldDescriptor *field, id dictionary);
//%PDDM-EXPAND-END GPB_ACCESSORS()
@@ -144,44 +194,64 @@ CF_EXTERN_C_END
//%
//%// Single Fields
//%
-//%GPB_ACCESSOR_SINGLE_FULL(Bytes, NSData, *)
-//%GPB_ACCESSOR_SINGLE_FULL(String, NSString, *)
-//%GPB_ACCESSOR_SINGLE_FULL(Message, GPBMessage, *)
-//%GPB_ACCESSOR_SINGLE_FULL(Group, GPBMessage, *)
-//%GPB_ACCESSOR_SINGLE(Bool, BOOL)
-//%GPB_ACCESSOR_SINGLE(Int32, int32_t)
-//%GPB_ACCESSOR_SINGLE(UInt32, uint32_t)
-//%GPB_ACCESSOR_SINGLE(Int64, int64_t)
-//%GPB_ACCESSOR_SINGLE(UInt64, uint64_t)
-//%GPB_ACCESSOR_SINGLE(Float, float)
-//%GPB_ACCESSOR_SINGLE(Double, double)
-//%// Get/Set the given enum field of a message. You can only Set values that are
-//%// members of the enum. For proto3, when doing a Get, if the value isn't a
-//%// memeber of the enum, kGPBUnrecognizedEnumeratorValue will be returned. The
-//%// the functions with "Raw" in the will bypass all checks.
+//%GPB_ACCESSOR_SINGLE_FULL(Bytes, NSData, , *)
+//%GPB_ACCESSOR_SINGLE_FULL(String, NSString, , *)
+//%GPB_ACCESSOR_SINGLE_FULL(Message, GPBMessage, , *)
+//%GPB_ACCESSOR_SINGLE_FULL(Group, GPBMessage, , *)
+//%GPB_ACCESSOR_SINGLE(Bool, BOOL, )
+//%GPB_ACCESSOR_SINGLE(Int32, int32_t, n)
+//%GPB_ACCESSOR_SINGLE(UInt32, uint32_t, n)
+//%GPB_ACCESSOR_SINGLE(Int64, int64_t, n)
+//%GPB_ACCESSOR_SINGLE(UInt64, uint64_t, n)
+//%GPB_ACCESSOR_SINGLE(Float, float, )
+//%GPB_ACCESSOR_SINGLE(Double, double, )
+//%/// Get the given enum field of a message. For proto3, if the value isn't a
+//%/// member of the enum, @c kGPBUnrecognizedEnumeratorValue will be returned.
+//%/// GPBGetMessageRawEnumField will bypass the check and return whatever value
+//%/// was set.
//%int32_t GPBGetMessageEnumField(GPBMessage *self, GPBFieldDescriptor *field);
+//%/// Set the given enum field of a message. You can only set values that are
+//%/// members of the enum.
//%void GPBSetMessageEnumField(GPBMessage *self, GPBFieldDescriptor *field, int32_t value);
+//%/// Get the given enum field of a message. No check is done to ensure the value
+//%/// was defined in the enum.
//%int32_t GPBGetMessageRawEnumField(GPBMessage *self, GPBFieldDescriptor *field);
+//%/// Set the given enum field of a message. You can set the value to anything,
+//%/// even a value that is not a member of the enum.
//%void GPBSetMessageRawEnumField(GPBMessage *self, GPBFieldDescriptor *field, int32_t value);
//%
//%// Repeated Fields
//%
-//%// The object will/should be GPB*Array or NSMutableArray based on the field's
-//%// type.
+//%/// Gets the value of a repeated field.
+//%///
+//%/// The result will be @c GPB*Array or @c NSMutableArray based on the
+//%/// field's type.
//%id GPBGetMessageRepeatedField(GPBMessage *self, GPBFieldDescriptor *field);
+//%/// Sets the value of a repeated field.
+//%///
+//%/// The value should be @c GPB*Array or @c NSMutableArray based on the
+//%/// field's type.
//%void GPBSetMessageRepeatedField(GPBMessage *self, GPBFieldDescriptor *field, id array);
//%
//%// Map Fields
//%
-//%// The object will/should be GPB*Dictionary or NSMutableDictionary based on the
-//%// field's type.
+//%/// Gets the value of a map<> field.
+//%///
+//%/// The result will be @c GPB*Dictionary or @c NSMutableDictionary based on
+//%/// the field's type.
//%id GPBGetMessageMapField(GPBMessage *self, GPBFieldDescriptor *field);
+//%/// Sets the value of a map<> field.
+//%///
+//%/// The object should be @c GPB*Dictionary or @c NSMutableDictionary based
+//%/// on the field's type.
//%void GPBSetMessageMapField(GPBMessage *self, GPBFieldDescriptor *field, id dictionary);
//%
-//%PDDM-DEFINE GPB_ACCESSOR_SINGLE(NAME, TYPE)
-//%GPB_ACCESSOR_SINGLE_FULL(NAME, TYPE, )
-//%PDDM-DEFINE GPB_ACCESSOR_SINGLE_FULL(NAME, TYPE, TisP)
+//%PDDM-DEFINE GPB_ACCESSOR_SINGLE(NAME, TYPE, AN)
+//%GPB_ACCESSOR_SINGLE_FULL(NAME, TYPE, AN, )
+//%PDDM-DEFINE GPB_ACCESSOR_SINGLE_FULL(NAME, TYPE, AN, TisP)
+//%/// Gets the value of a##AN NAME$L field.
//%TYPE TisP##GPBGetMessage##NAME##Field(GPBMessage *self, GPBFieldDescriptor *field);
+//%/// Sets the value of a##AN NAME$L field.
//%void GPBSetMessage##NAME##Field(GPBMessage *self, GPBFieldDescriptor *field, TYPE TisP##value);
//%
diff --git a/objectivec/GPBUtilities.m b/objectivec/GPBUtilities.m
index 5ee61230..ee84fb45 100644
--- a/objectivec/GPBUtilities.m
+++ b/objectivec/GPBUtilities.m
@@ -39,6 +39,12 @@
#import "GPBUnknownField.h"
#import "GPBUnknownFieldSet.h"
+// Direct access is use for speed, to avoid even internally declaring things
+// read/write, etc. The warning is enabled in the project to ensure code calling
+// protos can turn on -Wdirect-ivar-access without issues.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdirect-ivar-access"
+
static void AppendTextFormatForMessage(GPBMessage *message,
NSMutableString *toStr,
NSString *lineIndent);
@@ -145,9 +151,8 @@ void GPBSetHasIvar(GPBMessage *self, int32_t idx, uint32_t fieldNumber,
}
void GPBMaybeClearOneof(GPBMessage *self, GPBOneofDescriptor *oneof,
- uint32_t fieldNumberNotToClear) {
- int32_t hasIndex = oneof->oneofDescription_->index;
- uint32_t fieldNumberSet = GPBGetHasOneof(self, hasIndex);
+ int32_t oneofHasIndex, uint32_t fieldNumberNotToClear) {
+ uint32_t fieldNumberSet = GPBGetHasOneof(self, oneofHasIndex);
if ((fieldNumberSet == fieldNumberNotToClear) || (fieldNumberSet == 0)) {
// Do nothing/nothing set in the oneof.
return;
@@ -168,7 +173,7 @@ void GPBMaybeClearOneof(GPBMessage *self, GPBOneofDescriptor *oneof,
// Set to nothing stored in the oneof.
// (field number doesn't matter since setting to nothing).
- GPBSetHasIvar(self, hasIndex, 1, NO);
+ GPBSetHasIvar(self, oneofHasIndex, 1, NO);
}
#pragma mark - IVar accessors
@@ -200,7 +205,8 @@ void GPBMaybeClearOneof(GPBMessage *self, GPBOneofDescriptor *oneof,
//% NAME$S GPBFileSyntax syntax) {
//% GPBOneofDescriptor *oneof = field->containingOneof_;
//% if (oneof) {
-//% GPBMaybeClearOneof(self, oneof, GPBFieldNumber(field));
+//% GPBMessageFieldDescription *fieldDesc = field->description_;
+//% GPBMaybeClearOneof(self, oneof, fieldDesc->hasIndex, fieldDesc->number);
//% }
//% NSCAssert(self->messageStorage_ != NULL,
//% @"%@: All messages should have storage (from init)",
@@ -321,7 +327,8 @@ void GPBSetRetainedObjectIvarWithFieldInternal(GPBMessage *self,
// oneof.
GPBOneofDescriptor *oneof = field->containingOneof_;
if (oneof) {
- GPBMaybeClearOneof(self, oneof, GPBFieldNumber(field));
+ GPBMessageFieldDescription *fieldDesc = field->description_;
+ GPBMaybeClearOneof(self, oneof, fieldDesc->hasIndex, fieldDesc->number);
}
// Clear "has" if they are being set to nil.
BOOL setHasValue = (value != nil);
@@ -411,7 +418,8 @@ id GPBGetObjectIvarWithField(GPBMessage *self, GPBFieldDescriptor *field) {
return field.defaultValue.valueMessage;
}
- OSSpinLockLock(&self->readOnlyMutex_);
+ GPBPrepareReadOnlySemaphore(self);
+ dispatch_semaphore_wait(self->readOnlySemaphore_, DISPATCH_TIME_FOREVER);
GPBMessage *result = GPBGetObjectIvarWithFieldNoAutocreate(self, field);
if (!result) {
// For non repeated messages, create the object, set it and return it.
@@ -420,7 +428,7 @@ id GPBGetObjectIvarWithField(GPBMessage *self, GPBFieldDescriptor *field) {
result = GPBCreateMessageWithAutocreator(field.msgClass, self, field);
GPBSetAutocreatedRetainedObjectIvarWithField(self, field, result);
}
- OSSpinLockUnlock(&self->readOnlyMutex_);
+ dispatch_semaphore_signal(self->readOnlySemaphore_);
return result;
}
@@ -476,15 +484,15 @@ void GPBSetMessageRawEnumField(GPBMessage *self, GPBFieldDescriptor *field,
GPBSetInt32IvarWithFieldInternal(self, field, value, syntax);
}
-//%PDDM-EXPAND IVAR_POD_ACCESSORS_DEFN(Bool, BOOL)
-// This block of code is generated, do not edit it directly.
-
BOOL GPBGetMessageBoolField(GPBMessage *self,
GPBFieldDescriptor *field) {
if (GPBGetHasIvarField(self, field)) {
- uint8_t *storage = (uint8_t *)self->messageStorage_;
- BOOL *typePtr = (BOOL *)&storage[field->description_->offset];
- return *typePtr;
+ // Bools are stored in the has bits to avoid needing explicit space in the
+ // storage structure.
+ // (the field number passed to the HasIvar helper doesn't really matter
+ // since the offset is never negative)
+ GPBMessageFieldDescription *fieldDesc = field->description_;
+ return GPBGetHasIvar(self, (int32_t)(fieldDesc->offset), fieldDesc->number);
} else {
return field.defaultValue.valueBool;
}
@@ -503,19 +511,18 @@ void GPBSetBoolIvarWithFieldInternal(GPBMessage *self,
GPBFieldDescriptor *field,
BOOL value,
GPBFileSyntax syntax) {
+ GPBMessageFieldDescription *fieldDesc = field->description_;
GPBOneofDescriptor *oneof = field->containingOneof_;
if (oneof) {
- GPBMaybeClearOneof(self, oneof, GPBFieldNumber(field));
+ GPBMaybeClearOneof(self, oneof, fieldDesc->hasIndex, fieldDesc->number);
}
- NSCAssert(self->messageStorage_ != NULL,
- @"%@: All messages should have storage (from init)",
- [self class]);
-#if defined(__clang_analyzer__)
- if (self->messageStorage_ == NULL) return;
-#endif
- uint8_t *storage = (uint8_t *)self->messageStorage_;
- BOOL *typePtr = (BOOL *)&storage[field->description_->offset];
- *typePtr = value;
+
+ // Bools are stored in the has bits to avoid needing explicit space in the
+ // storage structure.
+ // (the field number passed to the HasIvar helper doesn't really matter since
+ // the offset is never negative)
+ GPBSetHasIvar(self, (int32_t)(fieldDesc->offset), fieldDesc->number, value);
+
// proto2: any value counts as having been set; proto3, it
// has to be a non zero value.
BOOL hasValue =
@@ -553,7 +560,8 @@ void GPBSetInt32IvarWithFieldInternal(GPBMessage *self,
GPBFileSyntax syntax) {
GPBOneofDescriptor *oneof = field->containingOneof_;
if (oneof) {
- GPBMaybeClearOneof(self, oneof, GPBFieldNumber(field));
+ GPBMessageFieldDescription *fieldDesc = field->description_;
+ GPBMaybeClearOneof(self, oneof, fieldDesc->hasIndex, fieldDesc->number);
}
NSCAssert(self->messageStorage_ != NULL,
@"%@: All messages should have storage (from init)",
@@ -601,7 +609,8 @@ void GPBSetUInt32IvarWithFieldInternal(GPBMessage *self,
GPBFileSyntax syntax) {
GPBOneofDescriptor *oneof = field->containingOneof_;
if (oneof) {
- GPBMaybeClearOneof(self, oneof, GPBFieldNumber(field));
+ GPBMessageFieldDescription *fieldDesc = field->description_;
+ GPBMaybeClearOneof(self, oneof, fieldDesc->hasIndex, fieldDesc->number);
}
NSCAssert(self->messageStorage_ != NULL,
@"%@: All messages should have storage (from init)",
@@ -649,7 +658,8 @@ void GPBSetInt64IvarWithFieldInternal(GPBMessage *self,
GPBFileSyntax syntax) {
GPBOneofDescriptor *oneof = field->containingOneof_;
if (oneof) {
- GPBMaybeClearOneof(self, oneof, GPBFieldNumber(field));
+ GPBMessageFieldDescription *fieldDesc = field->description_;
+ GPBMaybeClearOneof(self, oneof, fieldDesc->hasIndex, fieldDesc->number);
}
NSCAssert(self->messageStorage_ != NULL,
@"%@: All messages should have storage (from init)",
@@ -697,7 +707,8 @@ void GPBSetUInt64IvarWithFieldInternal(GPBMessage *self,
GPBFileSyntax syntax) {
GPBOneofDescriptor *oneof = field->containingOneof_;
if (oneof) {
- GPBMaybeClearOneof(self, oneof, GPBFieldNumber(field));
+ GPBMessageFieldDescription *fieldDesc = field->description_;
+ GPBMaybeClearOneof(self, oneof, fieldDesc->hasIndex, fieldDesc->number);
}
NSCAssert(self->messageStorage_ != NULL,
@"%@: All messages should have storage (from init)",
@@ -745,7 +756,8 @@ void GPBSetFloatIvarWithFieldInternal(GPBMessage *self,
GPBFileSyntax syntax) {
GPBOneofDescriptor *oneof = field->containingOneof_;
if (oneof) {
- GPBMaybeClearOneof(self, oneof, GPBFieldNumber(field));
+ GPBMessageFieldDescription *fieldDesc = field->description_;
+ GPBMaybeClearOneof(self, oneof, fieldDesc->hasIndex, fieldDesc->number);
}
NSCAssert(self->messageStorage_ != NULL,
@"%@: All messages should have storage (from init)",
@@ -793,7 +805,8 @@ void GPBSetDoubleIvarWithFieldInternal(GPBMessage *self,
GPBFileSyntax syntax) {
GPBOneofDescriptor *oneof = field->containingOneof_;
if (oneof) {
- GPBMaybeClearOneof(self, oneof, GPBFieldNumber(field));
+ GPBMessageFieldDescription *fieldDesc = field->description_;
+ GPBMaybeClearOneof(self, oneof, fieldDesc->hasIndex, fieldDesc->number);
}
NSCAssert(self->messageStorage_ != NULL,
@"%@: All messages should have storage (from init)",
@@ -812,7 +825,7 @@ void GPBSetDoubleIvarWithFieldInternal(GPBMessage *self,
GPBBecomeVisibleToAutocreator(self);
}
-//%PDDM-EXPAND-END (7 expansions)
+//%PDDM-EXPAND-END (6 expansions)
// Aliases are function calls that are virtually the same.
@@ -882,21 +895,11 @@ void GPBSetMessageGroupField(GPBMessage *self,
//%PDDM-EXPAND-END (4 expansions)
-// Only exists for public api, no core code should use this.
-id GPBGetMessageRepeatedField(GPBMessage *self, GPBFieldDescriptor *field) {
-#if DEBUG
- if (field.fieldType != GPBFieldTypeRepeated) {
- [NSException raise:NSInvalidArgumentException
- format:@"%@.%@ is not a repeated field.",
- [self class], field.name];
- }
-#endif
- return GPBGetObjectIvarWithField(self, field);
-}
+// GPBGetMessageRepeatedField is defined in GPBMessage.m
// Only exists for public api, no core code should use this.
void GPBSetMessageRepeatedField(GPBMessage *self, GPBFieldDescriptor *field, id array) {
-#if DEBUG
+#if defined(DEBUG) && DEBUG
if (field.fieldType != GPBFieldTypeRepeated) {
[NSException raise:NSInvalidArgumentException
format:@"%@.%@ is not a repeated field.",
@@ -935,10 +938,10 @@ void GPBSetMessageRepeatedField(GPBMessage *self, GPBFieldDescriptor *field, id
case GPBDataTypeString:
case GPBDataTypeMessage:
case GPBDataTypeGroup:
- expectedClass = [NSMutableDictionary class];
+ expectedClass = [NSMutableArray class];
break;
case GPBDataTypeEnum:
- expectedClass = [GPBBoolArray class];
+ expectedClass = [GPBEnumArray class];
break;
}
if (array && ![array isKindOfClass:expectedClass]) {
@@ -950,7 +953,7 @@ void GPBSetMessageRepeatedField(GPBMessage *self, GPBFieldDescriptor *field, id
GPBSetObjectIvarWithField(self, field, array);
}
-#if DEBUG
+#if defined(DEBUG) && DEBUG
static NSString *TypeToStr(GPBDataType dataType) {
switch (dataType) {
case GPBDataTypeBool:
@@ -984,22 +987,12 @@ static NSString *TypeToStr(GPBDataType dataType) {
}
#endif
-// Only exists for public api, no core code should use this.
-id GPBGetMessageMapField(GPBMessage *self, GPBFieldDescriptor *field) {
-#if DEBUG
- if (field.fieldType != GPBFieldTypeMap) {
- [NSException raise:NSInvalidArgumentException
- format:@"%@.%@ is not a map<> field.",
- [self class], field.name];
- }
-#endif
- return GPBGetObjectIvarWithField(self, field);
-}
+// GPBGetMessageMapField is defined in GPBMessage.m
// Only exists for public api, no core code should use this.
void GPBSetMessageMapField(GPBMessage *self, GPBFieldDescriptor *field,
id dictionary) {
-#if DEBUG
+#if defined(DEBUG) && DEBUG
if (field.fieldType != GPBFieldTypeMap) {
[NSException raise:NSInvalidArgumentException
format:@"%@.%@ is not a map<> field.",
@@ -1126,6 +1119,8 @@ static void AppendTextFormatForMapMessageField(
[toStr appendString:@"\n"];
[toStr appendString:valueLine];
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wswitch-enum"
switch (valueDataType) {
case GPBDataTypeString:
AppendStringEscaped(value, toStr);
@@ -1146,6 +1141,7 @@ static void AppendTextFormatForMapMessageField(
NSCAssert(NO, @"Can't happen");
break;
}
+#pragma clang diagnostic pop
[toStr appendString:@"\n"];
[toStr appendString:msgEnd];
@@ -1167,6 +1163,8 @@ static void AppendTextFormatForMapMessageField(
}
[toStr appendString:valueLine];
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wswitch-enum"
switch (valueDataType) {
case GPBDataTypeString:
AppendStringEscaped(valueObj, toStr);
@@ -1204,6 +1202,7 @@ static void AppendTextFormatForMapMessageField(
[toStr appendString:valueObj];
break;
}
+#pragma clang diagnostic pop
[toStr appendString:@"\n"];
[toStr appendString:msgEnd];
@@ -1253,7 +1252,7 @@ static void AppendTextFormatForMessageField(GPBMessage *message,
if ([fieldName length] == 0) {
fieldName = [NSString stringWithFormat:@"%u", GPBFieldNumber(field)];
// If there is only one entry, put the objc name as a comment, other wise
- // add it before the the repeated values.
+ // add it before the repeated values.
if (count > 1) {
[toStr appendFormat:@"%@# %@\n", lineIndent, field.name];
} else {
@@ -1473,7 +1472,8 @@ static void AppendTextFormatForMessage(GPBMessage *message,
NSUInteger fieldCount = fieldsArray.count;
const GPBExtensionRange *extensionRanges = descriptor.extensionRanges;
NSUInteger extensionRangesCount = descriptor.extensionRangesCount;
- NSArray *activeExtensions = [message sortedExtensionsInUse];
+ NSArray *activeExtensions = [[message extensionsCurrentlySet]
+ sortedArrayUsingSelector:@selector(compareByFieldNumber:)];
for (NSUInteger i = 0, j = 0; i < fieldCount || j < extensionRangesCount;) {
if (i == fieldCount) {
AppendTextFormatForMessageExtensionRange(
@@ -1699,6 +1699,8 @@ NSString *GPBDecodeTextFormatName(const uint8_t *decodeData, int32_t key,
return result;
}
+#pragma clang diagnostic pop
+
#pragma mark - GPBMessageSignatureProtocol
// A series of selectors that are used solely to get @encoding values
diff --git a/objectivec/GPBUtilities_PackagePrivate.h b/objectivec/GPBUtilities_PackagePrivate.h
index cac551f6..c02493b2 100644
--- a/objectivec/GPBUtilities_PackagePrivate.h
+++ b/objectivec/GPBUtilities_PackagePrivate.h
@@ -52,7 +52,7 @@ CF_EXTERN_C_BEGIN
// generated sources to make sure they are linked with a supporting runtime.
void GPBCheckRuntimeVersionInternal(int32_t version);
GPB_INLINE void GPBDebugCheckRuntimeVersion() {
-#if DEBUG
+#if defined(DEBUG) && DEBUG
GPBCheckRuntimeVersionInternal(GOOGLE_PROTOBUF_OBJC_GEN_VERSION);
#endif
}
@@ -125,6 +125,10 @@ GPB_INLINE uint64_t GPBEncodeZigZag64(int64_t n) {
return (n << 1) ^ (n >> 63);
}
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wswitch-enum"
+#pragma clang diagnostic ignored "-Wdirect-ivar-access"
+
GPB_INLINE BOOL GPBDataTypeIsObject(GPBDataType type) {
switch (type) {
case GPBDataTypeBytes:
@@ -185,7 +189,9 @@ GPB_INLINE void GPBSetHasIvarField(GPBMessage *self, GPBFieldDescriptor *field,
}
void GPBMaybeClearOneof(GPBMessage *self, GPBOneofDescriptor *oneof,
- uint32_t fieldNumberNotToClear);
+ int32_t oneofHasIndex, uint32_t fieldNumberNotToClear);
+
+#pragma clang diagnostic pop
//%PDDM-DEFINE GPB_IVAR_SET_DECL(NAME, TYPE)
//%void GPBSet##NAME##IvarWithFieldInternal(GPBMessage *self,
diff --git a/objectivec/GPBWellKnownTypes.h b/objectivec/GPBWellKnownTypes.h
index 28442fbe..311ac58e 100644
--- a/objectivec/GPBWellKnownTypes.h
+++ b/objectivec/GPBWellKnownTypes.h
@@ -30,8 +30,19 @@
#import <Foundation/Foundation.h>
-#import "google/protobuf/Duration.pbobjc.h"
-#import "google/protobuf/Timestamp.pbobjc.h"
+// This CPP symbol can be defined to use imports that match up to the framework
+// imports needed when using CocoaPods.
+#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS)
+ #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0
+#endif
+
+#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS
+ #import <Protobuf/Duration.pbobjc.h>
+ #import <Protobuf/Timestamp.pbobjc.h>
+#else
+ #import "google/protobuf/Duration.pbobjc.h"
+ #import "google/protobuf/Timestamp.pbobjc.h"
+#endif
NS_ASSUME_NONNULL_BEGIN
diff --git a/objectivec/GPBWellKnownTypes.m b/objectivec/GPBWellKnownTypes.m
index fe02f5de..5cdd62d5 100644
--- a/objectivec/GPBWellKnownTypes.m
+++ b/objectivec/GPBWellKnownTypes.m
@@ -32,8 +32,6 @@
// the static library. If these were compiled separately, the category methods
// below would be stripped by the linker.
-#import "google/protobuf/Timestamp.pbobjc.m"
-#import "google/protobuf/Duration.pbobjc.m"
#import "GPBWellKnownTypes.h"
static NSTimeInterval TimeIntervalSince1970FromSecondsAndNanos(int64_t seconds,
diff --git a/objectivec/GPBWireFormat.h b/objectivec/GPBWireFormat.h
index 29cf2f0b..c5941a38 100644
--- a/objectivec/GPBWireFormat.h
+++ b/objectivec/GPBWireFormat.h
@@ -53,6 +53,7 @@ uint32_t GPBWireFormatMakeTag(uint32_t fieldNumber, GPBWireFormat wireType)
__attribute__((const));
GPBWireFormat GPBWireFormatGetTagWireType(uint32_t tag) __attribute__((const));
uint32_t GPBWireFormatGetTagFieldNumber(uint32_t tag) __attribute__((const));
+BOOL GPBWireFormatIsValidTag(uint32_t tag) __attribute__((const));
GPBWireFormat GPBWireFormatForType(GPBDataType dataType, BOOL isPacked)
__attribute__((const));
diff --git a/objectivec/GPBWireFormat.m b/objectivec/GPBWireFormat.m
index 193235d6..860a339f 100644
--- a/objectivec/GPBWireFormat.m
+++ b/objectivec/GPBWireFormat.m
@@ -49,6 +49,13 @@ uint32_t GPBWireFormatGetTagFieldNumber(uint32_t tag) {
return GPBLogicalRightShift32(tag, GPBWireFormatTagTypeBits);
}
+BOOL GPBWireFormatIsValidTag(uint32_t tag) {
+ uint32_t formatBits = (tag & GPBWireFormatTagTypeMask);
+ // The valid GPBWireFormat* values are 0-5, anything else is not a valid tag.
+ BOOL result = (formatBits <= 5);
+ return result;
+}
+
GPBWireFormat GPBWireFormatForType(GPBDataType type, BOOL isPacked) {
if (isPacked) {
return GPBWireFormatLengthDelimited;
diff --git a/objectivec/ProtocolBuffers_OSX.xcodeproj/project.pbxproj b/objectivec/ProtocolBuffers_OSX.xcodeproj/project.pbxproj
index 1c834bb2..32067910 100644
--- a/objectivec/ProtocolBuffers_OSX.xcodeproj/project.pbxproj
+++ b/objectivec/ProtocolBuffers_OSX.xcodeproj/project.pbxproj
@@ -7,7 +7,6 @@
objects = {
/* Begin PBXBuildFile section */
- 2CFB390415C718CE00CBF84D /* Descriptor.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BD3982214BE5B0C0081D629 /* Descriptor.pbobjc.m */; };
5102DABC1891A073002037B6 /* GPBConcurrencyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5102DABB1891A052002037B6 /* GPBConcurrencyTests.m */; };
7461B5360F94FB4600A0C422 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; };
7461B53C0F94FB4E00A0C422 /* GPBCodedInputStream.m in Sources */ = {isa = PBXBuildFile; fileRef = 7461B48F0F94F99000A0C422 /* GPBCodedInputStream.m */; };
@@ -24,11 +23,8 @@
8B4248D21A927E1500BC1EC6 /* GPBWellKnownTypes.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B4248D01A927E1500BC1EC6 /* GPBWellKnownTypes.m */; };
8B4248DC1A92933A00BC1EC6 /* GPBWellKnownTypesTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B4248DB1A92933A00BC1EC6 /* GPBWellKnownTypesTest.m */; };
8B79657B14992E3F002FFBFC /* GPBRootObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B79657914992E3E002FFBFC /* GPBRootObject.m */; };
- 8B79657D14992E3F002FFBFC /* GPBRootObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B79657914992E3E002FFBFC /* GPBRootObject.m */; };
8B8B615D17DF7056002EE618 /* GPBARCUnittestProtos.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B8B615C17DF7056002EE618 /* GPBARCUnittestProtos.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; };
8B96157414C8C38C00A2AC0B /* GPBDescriptor.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B96157314C8C38C00A2AC0B /* GPBDescriptor.m */; };
- 8B96157514CA019D00A2AC0B /* Descriptor.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BD3982214BE5B0C0081D629 /* Descriptor.pbobjc.m */; };
- 8BA9364518DA5F4C0056FA2A /* GPBStringTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BA9364418DA5F4B0056FA2A /* GPBStringTests.m */; };
8BBEA4A9147C727D00C4ADB7 /* GPBCodedInputStreamTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7461B69B0F94FDF800A0C422 /* GPBCodedInputStreamTests.m */; };
8BBEA4AA147C727D00C4ADB7 /* GPBCodedOuputStreamTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7461B69D0F94FDF800A0C422 /* GPBCodedOuputStreamTests.m */; };
8BBEA4AC147C727D00C4ADB7 /* GPBMessageTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7461B6A30F94FDF800A0C422 /* GPBMessageTests.m */; };
@@ -58,6 +54,8 @@
F4487C831AAF6AB300531423 /* GPBMessageTests+Merge.m in Sources */ = {isa = PBXBuildFile; fileRef = F4487C821AAF6AB300531423 /* GPBMessageTests+Merge.m */; };
F45C69CC16DFD08D0081955B /* GPBExtensionInternals.m in Sources */ = {isa = PBXBuildFile; fileRef = F45C69CB16DFD08D0081955B /* GPBExtensionInternals.m */; };
F45E57C71AE6DC6A000B7D99 /* text_format_map_unittest_data.txt in Resources */ = {isa = PBXBuildFile; fileRef = F45E57C61AE6DC6A000B7D99 /* text_format_map_unittest_data.txt */; };
+ F47476E51D21A524007C7B1A /* Duration.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B4248D41A92826400BC1EC6 /* Duration.pbobjc.m */; };
+ F47476E61D21A524007C7B1A /* Timestamp.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B4248D61A92826400BC1EC6 /* Timestamp.pbobjc.m */; };
F4B51B1E1BBC610700744318 /* GPBObjectiveCPlusPlusTest.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4B51B1D1BBC610700744318 /* GPBObjectiveCPlusPlusTest.mm */; };
F4E675971B21D0000054530B /* Any.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E675871B21D0000054530B /* Any.pbobjc.m */; };
F4E675991B21D0000054530B /* Api.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E675891B21D0000054530B /* Api.pbobjc.m */; };
@@ -67,14 +65,6 @@
F4E675A11B21D0000054530B /* Struct.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E675911B21D0000054530B /* Struct.pbobjc.m */; };
F4E675A31B21D0000054530B /* Type.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E675931B21D0000054530B /* Type.pbobjc.m */; };
F4E675A51B21D0000054530B /* Wrappers.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E675951B21D0000054530B /* Wrappers.pbobjc.m */; };
- F4E675AE1B21D0A70054530B /* Any.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E675871B21D0000054530B /* Any.pbobjc.m */; };
- F4E675AF1B21D0A70054530B /* Api.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E675891B21D0000054530B /* Api.pbobjc.m */; };
- F4E675B01B21D0A70054530B /* Empty.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E6758B1B21D0000054530B /* Empty.pbobjc.m */; };
- F4E675B11B21D0A70054530B /* FieldMask.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E6758D1B21D0000054530B /* FieldMask.pbobjc.m */; };
- F4E675B21B21D0A70054530B /* SourceContext.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E6758F1B21D0000054530B /* SourceContext.pbobjc.m */; };
- F4E675B31B21D0A70054530B /* Struct.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E675911B21D0000054530B /* Struct.pbobjc.m */; };
- F4E675B41B21D0A70054530B /* Type.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E675931B21D0000054530B /* Type.pbobjc.m */; };
- F4E675B51B21D0A70054530B /* Wrappers.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E675951B21D0000054530B /* Wrappers.pbobjc.m */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -141,10 +131,8 @@
8B4248D51A92826400BC1EC6 /* Timestamp.pbobjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Timestamp.pbobjc.h; path = google/protobuf/Timestamp.pbobjc.h; sourceTree = "<group>"; };
8B4248D61A92826400BC1EC6 /* Timestamp.pbobjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Timestamp.pbobjc.m; path = google/protobuf/Timestamp.pbobjc.m; sourceTree = "<group>"; };
8B4248DB1A92933A00BC1EC6 /* GPBWellKnownTypesTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBWellKnownTypesTest.m; sourceTree = "<group>"; };
- 8B42494B1A92A16600BC1EC6 /* descriptor.proto */ = {isa = PBXFileReference; lastKnownFileType = text; name = descriptor.proto; path = ../src/google/protobuf/descriptor.proto; sourceTree = "<group>"; };
8B42494C1A92A16600BC1EC6 /* duration.proto */ = {isa = PBXFileReference; lastKnownFileType = text; name = duration.proto; path = ../src/google/protobuf/duration.proto; sourceTree = "<group>"; };
8B42494D1A92A16600BC1EC6 /* timestamp.proto */ = {isa = PBXFileReference; lastKnownFileType = text; name = timestamp.proto; path = ../src/google/protobuf/timestamp.proto; sourceTree = "<group>"; };
- 8B54585814DCC34E003D7338 /* Descriptor.pbobjc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Descriptor.pbobjc.h; path = google/protobuf/Descriptor.pbobjc.h; sourceTree = SOURCE_ROOT; };
8B79657814992E3E002FFBFC /* GPBRootObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBRootObject.h; sourceTree = "<group>"; };
8B79657914992E3E002FFBFC /* GPBRootObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBRootObject.m; sourceTree = "<group>"; };
8B7E6A7414893DBA00F8884A /* unittest_custom_options.proto */ = {isa = PBXFileReference; lastKnownFileType = text; name = unittest_custom_options.proto; path = ../../src/google/protobuf/unittest_custom_options.proto; sourceTree = "<group>"; };
@@ -158,13 +146,11 @@
8B8B615C17DF7056002EE618 /* GPBARCUnittestProtos.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBARCUnittestProtos.m; sourceTree = "<group>"; };
8B96157214C8B06000A2AC0B /* GPBDescriptor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPBDescriptor.h; sourceTree = "<group>"; };
8B96157314C8C38C00A2AC0B /* GPBDescriptor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBDescriptor.m; sourceTree = "<group>"; };
- 8BA9364418DA5F4B0056FA2A /* GPBStringTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBStringTests.m; sourceTree = "<group>"; };
8BBD9DB016DD1DC8008E1EC1 /* unittest_lite.proto */ = {isa = PBXFileReference; lastKnownFileType = text; name = unittest_lite.proto; path = ../../src/google/protobuf/unittest_lite.proto; sourceTree = "<group>"; };
8BBEA4A6147C727100C4ADB7 /* UnitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UnitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
8BCF338814ED799900BC5317 /* GPBProtocolBuffers.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GPBProtocolBuffers.m; sourceTree = "<group>"; };
8BD3981D14BE54220081D629 /* unittest_enormous_descriptor.proto */ = {isa = PBXFileReference; lastKnownFileType = text; name = unittest_enormous_descriptor.proto; path = ../../src/google/protobuf/unittest_enormous_descriptor.proto; sourceTree = "<group>"; };
8BD3981E14BE59D70081D629 /* GPBUnittestProtos.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBUnittestProtos.m; sourceTree = "<group>"; };
- 8BD3982214BE5B0C0081D629 /* Descriptor.pbobjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Descriptor.pbobjc.m; path = google/protobuf/Descriptor.pbobjc.m; sourceTree = SOURCE_ROOT; };
8BEB5AE01498033E0078BF9D /* GPBRuntimeTypes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPBRuntimeTypes.h; sourceTree = "<group>"; };
F401DC2A1A8D444600FCC765 /* GPBArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBArray.h; sourceTree = "<group>"; };
F401DC2B1A8D444600FCC765 /* GPBArray.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBArray.m; sourceTree = "<group>"; };
@@ -190,6 +176,7 @@
F4487C7C1AAE06AC00531423 /* GPBUtilities_PackagePrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPBUtilities_PackagePrivate.h; sourceTree = "<group>"; };
F4487C7E1AAF62CD00531423 /* GPBMessageTests+Serialization.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GPBMessageTests+Serialization.m"; sourceTree = "<group>"; };
F4487C821AAF6AB300531423 /* GPBMessageTests+Merge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GPBMessageTests+Merge.m"; sourceTree = "<group>"; };
+ F44929001C866B1900C2548A /* GPBCodedOutputStream_PackagePrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBCodedOutputStream_PackagePrivate.h; sourceTree = "<group>"; };
F451D3F51A8AAE8700B8A22C /* GPBProtocolBuffers_RuntimeSupport.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPBProtocolBuffers_RuntimeSupport.h; sourceTree = "<group>"; };
F45C69CB16DFD08D0081955B /* GPBExtensionInternals.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBExtensionInternals.m; sourceTree = "<group>"; };
F45E57C61AE6DC6A000B7D99 /* text_format_map_unittest_data.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = text_format_map_unittest_data.txt; sourceTree = "<group>"; };
@@ -301,9 +288,6 @@
F4E675881B21D0000054530B /* Api.pbobjc.h */,
F4E675891B21D0000054530B /* Api.pbobjc.m */,
F4E675A71B21D05C0054530B /* api.proto */,
- 8B54585814DCC34E003D7338 /* Descriptor.pbobjc.h */,
- 8BD3982214BE5B0C0081D629 /* Descriptor.pbobjc.m */,
- 8B42494B1A92A16600BC1EC6 /* descriptor.proto */,
8B4248D31A92826400BC1EC6 /* Duration.pbobjc.h */,
8B4248D41A92826400BC1EC6 /* Duration.pbobjc.m */,
8B42494C1A92A16600BC1EC6 /* duration.proto */,
@@ -370,9 +354,10 @@
7461B4860F94F96B00A0C422 /* IO */ = {
isa = PBXGroup;
children = (
- 7461B48E0F94F99000A0C422 /* GPBCodedInputStream.h */,
51457B5F18D0B7AF00CCC606 /* GPBCodedInputStream_PackagePrivate.h */,
+ 7461B48E0F94F99000A0C422 /* GPBCodedInputStream.h */,
7461B48F0F94F99000A0C422 /* GPBCodedInputStream.m */,
+ F44929001C866B1900C2548A /* GPBCodedOutputStream_PackagePrivate.h */,
7461B4900F94F99000A0C422 /* GPBCodedOutputStream.h */,
7461B4910F94F99000A0C422 /* GPBCodedOutputStream.m */,
7461B4E70F94F99000A0C422 /* GPBWireFormat.h */,
@@ -419,7 +404,6 @@
F4487C7E1AAF62CD00531423 /* GPBMessageTests+Serialization.m */,
F4B51B1D1BBC610700744318 /* GPBObjectiveCPlusPlusTest.mm */,
F41C175C1833D3310064ED4D /* GPBPerfTests.m */,
- 8BA9364418DA5F4B0056FA2A /* GPBStringTests.m */,
8B4248BA1A8C256A00BC1EC6 /* GPBSwiftTests.swift */,
7461B6AB0F94FDF800A0C422 /* GPBTestUtilities.h */,
7461B6AC0F94FDF800A0C422 /* GPBTestUtilities.m */,
@@ -635,7 +619,6 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- 2CFB390415C718CE00CBF84D /* Descriptor.pbobjc.m in Sources */,
7461B53C0F94FB4E00A0C422 /* GPBCodedInputStream.m in Sources */,
F4E6759B1B21D0000054530B /* Empty.pbobjc.m in Sources */,
7461B53D0F94FB4E00A0C422 /* GPBCodedOutputStream.m in Sources */,
@@ -644,6 +627,7 @@
F4E6759D1B21D0000054530B /* FieldMask.pbobjc.m in Sources */,
7461B54C0F94FB4E00A0C422 /* GPBUnknownField.m in Sources */,
7461B5530F94FB4E00A0C422 /* GPBMessage.m in Sources */,
+ F47476E51D21A524007C7B1A /* Duration.pbobjc.m in Sources */,
7461B5610F94FB4E00A0C422 /* GPBUnknownFieldSet.m in Sources */,
7461B5630F94FB4E00A0C422 /* GPBUtilities.m in Sources */,
7461B5640F94FB4E00A0C422 /* GPBWireFormat.m in Sources */,
@@ -658,6 +642,7 @@
F4E675A31B21D0000054530B /* Type.pbobjc.m in Sources */,
F4E675A11B21D0000054530B /* Struct.pbobjc.m in Sources */,
F4E675A51B21D0000054530B /* Wrappers.pbobjc.m in Sources */,
+ F47476E61D21A524007C7B1A /* Timestamp.pbobjc.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -670,37 +655,26 @@
F4353D361AC06F10005A6198 /* GPBDictionaryTests+Int64.m in Sources */,
F4353D391AC06F10005A6198 /* GPBDictionaryTests+UInt64.m in Sources */,
8BBEA4AA147C727D00C4ADB7 /* GPBCodedOuputStreamTests.m in Sources */,
- F4E675B21B21D0A70054530B /* SourceContext.pbobjc.m in Sources */,
8BBEA4AC147C727D00C4ADB7 /* GPBMessageTests.m in Sources */,
F4B51B1E1BBC610700744318 /* GPBObjectiveCPlusPlusTest.mm in Sources */,
F4487C7F1AAF62CD00531423 /* GPBMessageTests+Serialization.m in Sources */,
8B4248DC1A92933A00BC1EC6 /* GPBWellKnownTypesTest.m in Sources */,
- F4E675B01B21D0A70054530B /* Empty.pbobjc.m in Sources */,
- F4E675B41B21D0A70054530B /* Type.pbobjc.m in Sources */,
F4353D1D1AB8822D005A6198 /* GPBDescriptorTests.m in Sources */,
- F4E675B51B21D0A70054530B /* Wrappers.pbobjc.m in Sources */,
- F4E675AE1B21D0A70054530B /* Any.pbobjc.m in Sources */,
8B4248BB1A8C256A00BC1EC6 /* GPBSwiftTests.swift in Sources */,
5102DABC1891A073002037B6 /* GPBConcurrencyTests.m in Sources */,
- F4E675B31B21D0A70054530B /* Struct.pbobjc.m in Sources */,
F4487C751AADF7F500531423 /* GPBMessageTests+Runtime.m in Sources */,
F4353D351AC06F10005A6198 /* GPBDictionaryTests+Int32.m in Sources */,
8BBEA4B0147C727D00C4ADB7 /* GPBTestUtilities.m in Sources */,
F41C175D1833D3310064ED4D /* GPBPerfTests.m in Sources */,
F4353D341AC06F10005A6198 /* GPBDictionaryTests+Bool.m in Sources */,
F4487C831AAF6AB300531423 /* GPBMessageTests+Merge.m in Sources */,
- 8BA9364518DA5F4C0056FA2A /* GPBStringTests.m in Sources */,
8BBEA4B6147C727D00C4ADB7 /* GPBUnknownFieldSetTest.m in Sources */,
F4353D371AC06F10005A6198 /* GPBDictionaryTests+String.m in Sources */,
F4353D381AC06F10005A6198 /* GPBDictionaryTests+UInt32.m in Sources */,
8BBEA4B7147C727D00C4ADB7 /* GPBUtilitiesTests.m in Sources */,
8BBEA4B8147C727D00C4ADB7 /* GPBWireFormatTests.m in Sources */,
- 8B79657D14992E3F002FFBFC /* GPBRootObject.m in Sources */,
8BD3981F14BE59D70081D629 /* GPBUnittestProtos.m in Sources */,
- F4E675B11B21D0A70054530B /* FieldMask.pbobjc.m in Sources */,
- 8B96157514CA019D00A2AC0B /* Descriptor.pbobjc.m in Sources */,
8B8B615D17DF7056002EE618 /* GPBARCUnittestProtos.m in Sources */,
- F4E675AF1B21D0A70054530B /* Api.pbobjc.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -757,10 +731,17 @@
);
INFOPLIST_FILE = "Tests/UnitTests-Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
+ OTHER_LDFLAGS = "-ObjC";
PRODUCT_BUNDLE_IDENTIFIER = "com.yourcompany.${PRODUCT_NAME:identifier}";
PRODUCT_NAME = UnitTests;
SWIFT_OBJC_BRIDGING_HEADER = "Tests/UnitTests-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ WARNING_CFLAGS = (
+ "$(inherited)",
+ "-Wno-documentation-unknown-command",
+ "-Wno-reserved-id-macro",
+ "-Wno-direct-ivar-access",
+ );
};
name = Debug;
};
@@ -775,9 +756,16 @@
);
INFOPLIST_FILE = "Tests/UnitTests-Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
+ OTHER_LDFLAGS = "-ObjC";
PRODUCT_BUNDLE_IDENTIFIER = "com.yourcompany.${PRODUCT_NAME:identifier}";
PRODUCT_NAME = UnitTests;
SWIFT_OBJC_BRIDGING_HEADER = "Tests/UnitTests-Bridging-Header.h";
+ WARNING_CFLAGS = (
+ "$(inherited)",
+ "-Wno-documentation-unknown-command",
+ "-Wno-reserved-id-macro",
+ "-Wno-direct-ivar-access",
+ );
};
name = Release;
};
@@ -785,15 +773,20 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = YES;
+ CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES;
CLANG_ANALYZER_SECURITY_INSECUREAPI_RAND = YES;
CLANG_ANALYZER_SECURITY_INSECUREAPI_STRCPY = YES;
CLANG_STATIC_ANALYZER_MODE = deep;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_NULLABLE_TO_NONNULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_EXPLICIT_OWNERSHIP_TYPE = YES;
CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_MISSING_PROPERTY_SYNTHESIS = YES;
CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES_AGGRESSIVE;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = c99;
@@ -814,6 +807,7 @@
GCC_WARN_SHADOW = YES;
GCC_WARN_SIGN_COMPARE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNKNOWN_PRAGMAS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_LABEL = YES;
@@ -824,6 +818,14 @@
ONLY_ACTIVE_ARCH = YES;
RUN_CLANG_STATIC_ANALYZER = YES;
SDKROOT = macosx;
+ WARNING_CFLAGS = (
+ "-Wdocumentation-unknown-command",
+ "-Wundef",
+ "-Wreserved-id-macro",
+ "-Wswitch-enum",
+ "-Wdirect-ivar-access",
+ "-Woverriding-method-mismatch",
+ );
};
name = Debug;
};
@@ -831,15 +833,20 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = YES;
+ CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES;
CLANG_ANALYZER_SECURITY_INSECUREAPI_RAND = YES;
CLANG_ANALYZER_SECURITY_INSECUREAPI_STRCPY = YES;
CLANG_STATIC_ANALYZER_MODE = deep;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_NULLABLE_TO_NONNULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_EXPLICIT_OWNERSHIP_TYPE = YES;
CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_MISSING_PROPERTY_SYNTHESIS = YES;
CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES_AGGRESSIVE;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
ENABLE_NS_ASSERTIONS = NO;
GCC_C_LANGUAGE_STANDARD = c99;
@@ -858,6 +865,7 @@
GCC_WARN_SHADOW = YES;
GCC_WARN_SIGN_COMPARE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNKNOWN_PRAGMAS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_LABEL = YES;
@@ -867,6 +875,14 @@
MACOSX_DEPLOYMENT_TARGET = 10.9;
RUN_CLANG_STATIC_ANALYZER = YES;
SDKROOT = macosx;
+ WARNING_CFLAGS = (
+ "-Wdocumentation-unknown-command",
+ "-Wundef",
+ "-Wreserved-id-macro",
+ "-Wswitch-enum",
+ "-Wdirect-ivar-access",
+ "-Woverriding-method-mismatch",
+ );
};
name = Release;
};
diff --git a/objectivec/ProtocolBuffers_OSX.xcodeproj/xcshareddata/xcschemes/PerformanceTests.xcscheme b/objectivec/ProtocolBuffers_OSX.xcodeproj/xcshareddata/xcschemes/PerformanceTests.xcscheme
index 7ddf283d..25814c5f 100644
--- a/objectivec/ProtocolBuffers_OSX.xcodeproj/xcshareddata/xcschemes/PerformanceTests.xcscheme
+++ b/objectivec/ProtocolBuffers_OSX.xcodeproj/xcshareddata/xcschemes/PerformanceTests.xcscheme
@@ -159,6 +159,9 @@
Identifier = "GPBInt64UInt64DictionaryTests">
</Test>
<Test
+ Identifier = "GPBObjectiveCPlusPlusTests">
+ </Test>
+ <Test
Identifier = "GPBStringBoolDictionaryTests">
</Test>
<Test
@@ -180,9 +183,6 @@
Identifier = "GPBStringInt64DictionaryTests">
</Test>
<Test
- Identifier = "GPBStringTests">
- </Test>
- <Test
Identifier = "GPBStringUInt32DictionaryTests">
</Test>
<Test
diff --git a/objectivec/ProtocolBuffers_OSX.xcodeproj/xcshareddata/xcschemes/ProtocolBuffers.xcscheme b/objectivec/ProtocolBuffers_OSX.xcodeproj/xcshareddata/xcschemes/ProtocolBuffers.xcscheme
index 8f510f5d..3eb4f92b 100644
--- a/objectivec/ProtocolBuffers_OSX.xcodeproj/xcshareddata/xcschemes/ProtocolBuffers.xcscheme
+++ b/objectivec/ProtocolBuffers_OSX.xcodeproj/xcshareddata/xcschemes/ProtocolBuffers.xcscheme
@@ -54,7 +54,8 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
- shouldUseLaunchSchemeArgsEnv = "YES">
+ shouldUseLaunchSchemeArgsEnv = "YES"
+ codeCoverageEnabled = "YES">
<Testables>
<TestableReference
skipped = "NO">
diff --git a/objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj b/objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj
index 55013641..9f688f8d 100644
--- a/objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj
+++ b/objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj
@@ -7,7 +7,6 @@
objects = {
/* Begin PBXBuildFile section */
- 2CFB390415C718CE00CBF84D /* Descriptor.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BD3982214BE5B0C0081D629 /* Descriptor.pbobjc.m */; };
5102DABC1891A073002037B6 /* GPBConcurrencyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5102DABB1891A052002037B6 /* GPBConcurrencyTests.m */; };
7461B5360F94FB4600A0C422 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; };
7461B53C0F94FB4E00A0C422 /* GPBCodedInputStream.m in Sources */ = {isa = PBXBuildFile; fileRef = 7461B48F0F94F99000A0C422 /* GPBCodedInputStream.m */; };
@@ -24,10 +23,8 @@
8B4248E41A929C8900BC1EC6 /* GPBWellKnownTypes.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B4248E21A929C8900BC1EC6 /* GPBWellKnownTypes.m */; };
8B4248E61A929C9900BC1EC6 /* GPBWellKnownTypesTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B4248E51A929C9900BC1EC6 /* GPBWellKnownTypesTest.m */; };
8B79657B14992E3F002FFBFC /* GPBRootObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B79657914992E3E002FFBFC /* GPBRootObject.m */; };
- 8B79657D14992E3F002FFBFC /* GPBRootObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B79657914992E3E002FFBFC /* GPBRootObject.m */; };
8B8B615D17DF7056002EE618 /* GPBARCUnittestProtos.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B8B615C17DF7056002EE618 /* GPBARCUnittestProtos.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; };
8B96157414C8C38C00A2AC0B /* GPBDescriptor.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B96157314C8C38C00A2AC0B /* GPBDescriptor.m */; };
- 8B96157514CA019D00A2AC0B /* Descriptor.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BD3982214BE5B0C0081D629 /* Descriptor.pbobjc.m */; };
8B9742331A89D19F00DCE92C /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 8B9742321A89D19F00DCE92C /* LaunchScreen.xib */; };
8B9742431A8AAA7800DCE92C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B9742421A8AAA7800DCE92C /* CoreGraphics.framework */; };
8B9A5EA61831993600A9D33B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; };
@@ -36,7 +33,6 @@
8B9A5EB41831993600A9D33B /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B9A5EB31831993600A9D33B /* AppDelegate.m */; };
8B9A5EB61831993600A9D33B /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8B9A5EB51831993600A9D33B /* Images.xcassets */; };
8B9A5EEC18330A0F00A9D33B /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B9A5E9F1831913D00A9D33B /* UIKit.framework */; };
- 8BA9364518DA5F4C0056FA2A /* GPBStringTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BA9364418DA5F4B0056FA2A /* GPBStringTests.m */; };
8BBEA4A9147C727D00C4ADB7 /* GPBCodedInputStreamTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7461B69B0F94FDF800A0C422 /* GPBCodedInputStreamTests.m */; };
8BBEA4AA147C727D00C4ADB7 /* GPBCodedOuputStreamTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7461B69D0F94FDF800A0C422 /* GPBCodedOuputStreamTests.m */; };
8BBEA4AC147C727D00C4ADB7 /* GPBMessageTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7461B6A30F94FDF800A0C422 /* GPBMessageTests.m */; };
@@ -66,15 +62,9 @@
F4487C851AAF6AC500531423 /* GPBMessageTests+Merge.m in Sources */ = {isa = PBXBuildFile; fileRef = F4487C841AAF6AC500531423 /* GPBMessageTests+Merge.m */; };
F45C69CC16DFD08D0081955B /* GPBExtensionInternals.m in Sources */ = {isa = PBXBuildFile; fileRef = F45C69CB16DFD08D0081955B /* GPBExtensionInternals.m */; };
F45E57C91AE6DC98000B7D99 /* text_format_map_unittest_data.txt in Resources */ = {isa = PBXBuildFile; fileRef = F45E57C81AE6DC98000B7D99 /* text_format_map_unittest_data.txt */; };
+ F47476E91D21A537007C7B1A /* Duration.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B4248DE1A929C7D00BC1EC6 /* Duration.pbobjc.m */; };
+ F47476EA1D21A537007C7B1A /* Timestamp.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B4248E01A929C7D00BC1EC6 /* Timestamp.pbobjc.m */; };
F4B51B1C1BBC5C7100744318 /* GPBObjectiveCPlusPlusTest.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4B51B1B1BBC5C7100744318 /* GPBObjectiveCPlusPlusTest.mm */; };
- F4E675C81B21D1610054530B /* Any.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E675B71B21D1440054530B /* Any.pbobjc.m */; };
- F4E675C91B21D1610054530B /* Api.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E675B91B21D1440054530B /* Api.pbobjc.m */; };
- F4E675CA1B21D1610054530B /* Empty.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E675BC1B21D1440054530B /* Empty.pbobjc.m */; };
- F4E675CB1B21D1610054530B /* FieldMask.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E675BE1B21D1440054530B /* FieldMask.pbobjc.m */; };
- F4E675CC1B21D1610054530B /* SourceContext.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E675C01B21D1440054530B /* SourceContext.pbobjc.m */; };
- F4E675CD1B21D1610054530B /* Struct.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E675C21B21D1440054530B /* Struct.pbobjc.m */; };
- F4E675CE1B21D1610054530B /* Type.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E675C51B21D1440054530B /* Type.pbobjc.m */; };
- F4E675CF1B21D1610054530B /* Wrappers.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E675C71B21D1440054530B /* Wrappers.pbobjc.m */; };
F4E675D01B21D1620054530B /* Any.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E675B71B21D1440054530B /* Any.pbobjc.m */; };
F4E675D11B21D1620054530B /* Api.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E675B91B21D1440054530B /* Api.pbobjc.m */; };
F4E675D21B21D1620054530B /* Empty.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E675BC1B21D1440054530B /* Empty.pbobjc.m */; };
@@ -156,7 +146,6 @@
8B4248E21A929C8900BC1EC6 /* GPBWellKnownTypes.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBWellKnownTypes.m; sourceTree = "<group>"; };
8B4248E51A929C9900BC1EC6 /* GPBWellKnownTypesTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBWellKnownTypesTest.m; sourceTree = "<group>"; };
8B4249481A92A02300BC1EC6 /* timestamp.proto */ = {isa = PBXFileReference; lastKnownFileType = text; name = timestamp.proto; path = ../src/google/protobuf/timestamp.proto; sourceTree = "<group>"; };
- 8B4249491A92A0BA00BC1EC6 /* descriptor.proto */ = {isa = PBXFileReference; lastKnownFileType = text; name = descriptor.proto; path = ../src/google/protobuf/descriptor.proto; sourceTree = "<group>"; };
8B42494A1A92A0BA00BC1EC6 /* duration.proto */ = {isa = PBXFileReference; lastKnownFileType = text; name = duration.proto; path = ../src/google/protobuf/duration.proto; sourceTree = "<group>"; };
8B79657814992E3E002FFBFC /* GPBRootObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBRootObject.h; sourceTree = "<group>"; };
8B79657914992E3E002FFBFC /* GPBRootObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBRootObject.m; sourceTree = "<group>"; };
@@ -179,13 +168,11 @@
8B9A5EAD1831993600A9D33B /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
8B9A5EB31831993600A9D33B /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
8B9A5EB51831993600A9D33B /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
- 8BA9364418DA5F4B0056FA2A /* GPBStringTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBStringTests.m; sourceTree = "<group>"; };
8BBD9DB016DD1DC8008E1EC1 /* unittest_lite.proto */ = {isa = PBXFileReference; lastKnownFileType = text; name = unittest_lite.proto; path = ../../src/google/protobuf/unittest_lite.proto; sourceTree = "<group>"; };
8BBEA4A6147C727100C4ADB7 /* UnitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UnitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
8BCF338814ED799900BC5317 /* GPBProtocolBuffers.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GPBProtocolBuffers.m; sourceTree = "<group>"; };
8BD3981D14BE54220081D629 /* unittest_enormous_descriptor.proto */ = {isa = PBXFileReference; lastKnownFileType = text; name = unittest_enormous_descriptor.proto; path = ../../src/google/protobuf/unittest_enormous_descriptor.proto; sourceTree = "<group>"; };
8BD3981E14BE59D70081D629 /* GPBUnittestProtos.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBUnittestProtos.m; sourceTree = "<group>"; };
- 8BD3982214BE5B0C0081D629 /* Descriptor.pbobjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Descriptor.pbobjc.m; path = google/protobuf/Descriptor.pbobjc.m; sourceTree = SOURCE_ROOT; };
8BEB5AE01498033E0078BF9D /* GPBRuntimeTypes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPBRuntimeTypes.h; sourceTree = "<group>"; };
F401DC341A8E5C6F00FCC765 /* GPBArrayTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBArrayTests.m; sourceTree = "<group>"; };
F41C175C1833D3310064ED4D /* GPBPerfTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBPerfTests.m; sourceTree = "<group>"; };
@@ -211,6 +198,7 @@
F4487C7D1AAE06C500531423 /* GPBUtilities_PackagePrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPBUtilities_PackagePrivate.h; sourceTree = "<group>"; };
F4487C801AAF62FC00531423 /* GPBMessageTests+Serialization.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GPBMessageTests+Serialization.m"; sourceTree = "<group>"; };
F4487C841AAF6AC500531423 /* GPBMessageTests+Merge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GPBMessageTests+Merge.m"; sourceTree = "<group>"; };
+ F44929021C866B3B00C2548A /* GPBCodedOutputStream_PackagePrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBCodedOutputStream_PackagePrivate.h; sourceTree = "<group>"; };
F451D3F61A8AAEA600B8A22C /* GPBProtocolBuffers_RuntimeSupport.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPBProtocolBuffers_RuntimeSupport.h; sourceTree = "<group>"; };
F45C69CB16DFD08D0081955B /* GPBExtensionInternals.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBExtensionInternals.m; sourceTree = "<group>"; };
F45E57C81AE6DC98000B7D99 /* text_format_map_unittest_data.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = text_format_map_unittest_data.txt; sourceTree = "<group>"; };
@@ -225,7 +213,6 @@
F4E675B71B21D1440054530B /* Any.pbobjc.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = Any.pbobjc.m; path = google/protobuf/Any.pbobjc.m; sourceTree = "<group>"; };
F4E675B81B21D1440054530B /* Api.pbobjc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Api.pbobjc.h; path = google/protobuf/Api.pbobjc.h; sourceTree = "<group>"; };
F4E675B91B21D1440054530B /* Api.pbobjc.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = Api.pbobjc.m; path = google/protobuf/Api.pbobjc.m; sourceTree = "<group>"; };
- F4E675BA1B21D1440054530B /* Descriptor.pbobjc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Descriptor.pbobjc.h; path = google/protobuf/Descriptor.pbobjc.h; sourceTree = "<group>"; };
F4E675BB1B21D1440054530B /* Empty.pbobjc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Empty.pbobjc.h; path = google/protobuf/Empty.pbobjc.h; sourceTree = "<group>"; };
F4E675BC1B21D1440054530B /* Empty.pbobjc.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = Empty.pbobjc.m; path = google/protobuf/Empty.pbobjc.m; sourceTree = "<group>"; };
F4E675BD1B21D1440054530B /* FieldMask.pbobjc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FieldMask.pbobjc.h; path = google/protobuf/FieldMask.pbobjc.h; sourceTree = "<group>"; };
@@ -336,9 +323,6 @@
F4E675B81B21D1440054530B /* Api.pbobjc.h */,
F4E675B91B21D1440054530B /* Api.pbobjc.m */,
F4E675D91B21D1DE0054530B /* api.proto */,
- F4E675BA1B21D1440054530B /* Descriptor.pbobjc.h */,
- 8BD3982214BE5B0C0081D629 /* Descriptor.pbobjc.m */,
- 8B4249491A92A0BA00BC1EC6 /* descriptor.proto */,
8B4248DD1A929C7D00BC1EC6 /* Duration.pbobjc.h */,
8B4248DE1A929C7D00BC1EC6 /* Duration.pbobjc.m */,
8B42494A1A92A0BA00BC1EC6 /* duration.proto */,
@@ -407,9 +391,10 @@
7461B4860F94F96B00A0C422 /* IO */ = {
isa = PBXGroup;
children = (
- 7461B48E0F94F99000A0C422 /* GPBCodedInputStream.h */,
51457B5F18D0B7AF00CCC606 /* GPBCodedInputStream_PackagePrivate.h */,
+ 7461B48E0F94F99000A0C422 /* GPBCodedInputStream.h */,
7461B48F0F94F99000A0C422 /* GPBCodedInputStream.m */,
+ F44929021C866B3B00C2548A /* GPBCodedOutputStream_PackagePrivate.h */,
7461B4900F94F99000A0C422 /* GPBCodedOutputStream.h */,
7461B4910F94F99000A0C422 /* GPBCodedOutputStream.m */,
7461B4E70F94F99000A0C422 /* GPBWireFormat.h */,
@@ -457,7 +442,6 @@
F4487C801AAF62FC00531423 /* GPBMessageTests+Serialization.m */,
F4B51B1B1BBC5C7100744318 /* GPBObjectiveCPlusPlusTest.mm */,
F41C175C1833D3310064ED4D /* GPBPerfTests.m */,
- 8BA9364418DA5F4B0056FA2A /* GPBStringTests.m */,
8B4248B31A8BD96E00BC1EC6 /* GPBSwiftTests.swift */,
7461B6AB0F94FDF800A0C422 /* GPBTestUtilities.h */,
7461B6AC0F94FDF800A0C422 /* GPBTestUtilities.m */,
@@ -723,7 +707,6 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- 2CFB390415C718CE00CBF84D /* Descriptor.pbobjc.m in Sources */,
7461B53C0F94FB4E00A0C422 /* GPBCodedInputStream.m in Sources */,
F4E675D21B21D1620054530B /* Empty.pbobjc.m in Sources */,
F4487C731A9F906200531423 /* GPBArray.m in Sources */,
@@ -732,6 +715,7 @@
F4E675D31B21D1620054530B /* FieldMask.pbobjc.m in Sources */,
7461B54C0F94FB4E00A0C422 /* GPBUnknownField.m in Sources */,
7461B5530F94FB4E00A0C422 /* GPBMessage.m in Sources */,
+ F47476E91D21A537007C7B1A /* Duration.pbobjc.m in Sources */,
7461B5610F94FB4E00A0C422 /* GPBUnknownFieldSet.m in Sources */,
7461B5630F94FB4E00A0C422 /* GPBUtilities.m in Sources */,
7461B5640F94FB4E00A0C422 /* GPBWireFormat.m in Sources */,
@@ -746,6 +730,7 @@
F4E675D61B21D1620054530B /* Type.pbobjc.m in Sources */,
F4E675D51B21D1620054530B /* Struct.pbobjc.m in Sources */,
F4E675D71B21D1620054530B /* Wrappers.pbobjc.m in Sources */,
+ F47476EA1D21A537007C7B1A /* Timestamp.pbobjc.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -766,37 +751,26 @@
F4353D441AC06F31005A6198 /* GPBDictionaryTests+Int64.m in Sources */,
F4353D471AC06F31005A6198 /* GPBDictionaryTests+UInt64.m in Sources */,
8BBEA4AA147C727D00C4ADB7 /* GPBCodedOuputStreamTests.m in Sources */,
- F4E675CC1B21D1610054530B /* SourceContext.pbobjc.m in Sources */,
8BBEA4AC147C727D00C4ADB7 /* GPBMessageTests.m in Sources */,
F4487C811AAF62FC00531423 /* GPBMessageTests+Serialization.m in Sources */,
8B4248E61A929C9900BC1EC6 /* GPBWellKnownTypesTest.m in Sources */,
- F4E675CA1B21D1610054530B /* Empty.pbobjc.m in Sources */,
- F4E675CE1B21D1610054530B /* Type.pbobjc.m in Sources */,
F4353D1F1AB88243005A6198 /* GPBDescriptorTests.m in Sources */,
- F4E675CF1B21D1610054530B /* Wrappers.pbobjc.m in Sources */,
F4B51B1C1BBC5C7100744318 /* GPBObjectiveCPlusPlusTest.mm in Sources */,
- F4E675C81B21D1610054530B /* Any.pbobjc.m in Sources */,
8B4248B41A8BD96E00BC1EC6 /* GPBSwiftTests.swift in Sources */,
5102DABC1891A073002037B6 /* GPBConcurrencyTests.m in Sources */,
- F4E675CD1B21D1610054530B /* Struct.pbobjc.m in Sources */,
F4487C771AADF84900531423 /* GPBMessageTests+Runtime.m in Sources */,
F4353D431AC06F31005A6198 /* GPBDictionaryTests+Int32.m in Sources */,
8BBEA4B0147C727D00C4ADB7 /* GPBTestUtilities.m in Sources */,
F41C175D1833D3310064ED4D /* GPBPerfTests.m in Sources */,
F4353D421AC06F31005A6198 /* GPBDictionaryTests+Bool.m in Sources */,
F4487C851AAF6AC500531423 /* GPBMessageTests+Merge.m in Sources */,
- 8BA9364518DA5F4C0056FA2A /* GPBStringTests.m in Sources */,
8BBEA4B6147C727D00C4ADB7 /* GPBUnknownFieldSetTest.m in Sources */,
F4353D451AC06F31005A6198 /* GPBDictionaryTests+String.m in Sources */,
F4353D461AC06F31005A6198 /* GPBDictionaryTests+UInt32.m in Sources */,
8BBEA4B7147C727D00C4ADB7 /* GPBUtilitiesTests.m in Sources */,
8BBEA4B8147C727D00C4ADB7 /* GPBWireFormatTests.m in Sources */,
- 8B79657D14992E3F002FFBFC /* GPBRootObject.m in Sources */,
8BD3981F14BE59D70081D629 /* GPBUnittestProtos.m in Sources */,
- F4E675CB1B21D1610054530B /* FieldMask.pbobjc.m in Sources */,
- 8B96157514CA019D00A2AC0B /* Descriptor.pbobjc.m in Sources */,
8B8B615D17DF7056002EE618 /* GPBARCUnittestProtos.m in Sources */,
- F4E675C91B21D1610054530B /* Api.pbobjc.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -908,11 +882,18 @@
"$(inherited)",
"\"$(DEVELOPER_DIR)/usr/lib\"",
);
+ OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = UnitTests;
SWIFT_OBJC_BRIDGING_HEADER = "Tests/UnitTests-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
TARGETED_DEVICE_FAMILY = "1,2";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/iOSTestHarness.app/iOSTestHarness";
+ WARNING_CFLAGS = (
+ "$(inherited)",
+ "-Wno-documentation-unknown-command",
+ "-Wno-reserved-id-macro",
+ "-Wno-direct-ivar-access",
+ );
};
name = Debug;
};
@@ -936,10 +917,17 @@
"$(inherited)",
"\"$(DEVELOPER_DIR)/usr/lib\"",
);
+ OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = UnitTests;
SWIFT_OBJC_BRIDGING_HEADER = "Tests/UnitTests-Bridging-Header.h";
TARGETED_DEVICE_FAMILY = "1,2";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/iOSTestHarness.app/iOSTestHarness";
+ WARNING_CFLAGS = (
+ "$(inherited)",
+ "-Wno-documentation-unknown-command",
+ "-Wno-reserved-id-macro",
+ "-Wno-direct-ivar-access",
+ );
};
name = Release;
};
@@ -947,15 +935,20 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = YES;
+ CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES;
CLANG_ANALYZER_SECURITY_INSECUREAPI_RAND = YES;
CLANG_ANALYZER_SECURITY_INSECUREAPI_STRCPY = YES;
CLANG_STATIC_ANALYZER_MODE = deep;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_NULLABLE_TO_NONNULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_EXPLICIT_OWNERSHIP_TYPE = YES;
CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_MISSING_PROPERTY_SYNTHESIS = YES;
CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES_AGGRESSIVE;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
ENABLE_TESTABILITY = YES;
@@ -977,6 +970,7 @@
GCC_WARN_SHADOW = YES;
GCC_WARN_SIGN_COMPARE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNKNOWN_PRAGMAS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_LABEL = YES;
@@ -987,6 +981,14 @@
ONLY_ACTIVE_ARCH = YES;
RUN_CLANG_STATIC_ANALYZER = YES;
SDKROOT = iphoneos;
+ WARNING_CFLAGS = (
+ "-Wdocumentation-unknown-command",
+ "-Wundef",
+ "-Wreserved-id-macro",
+ "-Wswitch-enum",
+ "-Wdirect-ivar-access",
+ "-Woverriding-method-mismatch",
+ );
};
name = Debug;
};
@@ -994,15 +996,20 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = YES;
+ CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES;
CLANG_ANALYZER_SECURITY_INSECUREAPI_RAND = YES;
CLANG_ANALYZER_SECURITY_INSECUREAPI_STRCPY = YES;
CLANG_STATIC_ANALYZER_MODE = deep;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_NULLABLE_TO_NONNULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_EXPLICIT_OWNERSHIP_TYPE = YES;
CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_MISSING_PROPERTY_SYNTHESIS = YES;
CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES_AGGRESSIVE;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
ENABLE_NS_ASSERTIONS = NO;
@@ -1022,6 +1029,7 @@
GCC_WARN_SHADOW = YES;
GCC_WARN_SIGN_COMPARE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNKNOWN_PRAGMAS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_LABEL = YES;
@@ -1031,6 +1039,14 @@
IPHONEOS_DEPLOYMENT_TARGET = 6.1;
RUN_CLANG_STATIC_ANALYZER = YES;
SDKROOT = iphoneos;
+ WARNING_CFLAGS = (
+ "-Wdocumentation-unknown-command",
+ "-Wundef",
+ "-Wreserved-id-macro",
+ "-Wswitch-enum",
+ "-Wdirect-ivar-access",
+ "-Woverriding-method-mismatch",
+ );
};
name = Release;
};
diff --git a/objectivec/ProtocolBuffers_iOS.xcodeproj/xcshareddata/xcbaselines/8BBEA4A5147C727100C4ADB7.xcbaseline/FFE465CA-0E74-40E8-9F09-500B66B7DCB2.plist b/objectivec/ProtocolBuffers_iOS.xcodeproj/xcshareddata/xcbaselines/8BBEA4A5147C727100C4ADB7.xcbaseline/FFE465CA-0E74-40E8-9F09-500B66B7DCB2.plist
deleted file mode 100644
index 0ac0943a..00000000
--- a/objectivec/ProtocolBuffers_iOS.xcodeproj/xcshareddata/xcbaselines/8BBEA4A5147C727100C4ADB7.xcbaseline/FFE465CA-0E74-40E8-9F09-500B66B7DCB2.plist
+++ /dev/null
@@ -1,62 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>classNames</key>
- <dict>
- <key>PerfTests</key>
- <dict>
- <key>testExtensionsPerformance</key>
- <dict>
- <key>com.apple.XCTPerformanceMetric_WallClockTime</key>
- <dict>
- <key>baselineAverage</key>
- <real>0.9</real>
- <key>baselineIntegrationDisplayName</key>
- <string>Feb 5, 2015, 9:42:41 AM</string>
- </dict>
- </dict>
- <key>testHas</key>
- <dict>
- <key>com.apple.XCTPerformanceMetric_WallClockTime</key>
- <dict>
- <key>baselineAverage</key>
- <real>0.09</real>
- <key>baselineIntegrationDisplayName</key>
- <string>Feb 5, 2015, 9:42:35 AM</string>
- </dict>
- </dict>
- <key>testMessagePerformance</key>
- <dict>
- <key>com.apple.XCTPerformanceMetric_WallClockTime</key>
- <dict>
- <key>baselineAverage</key>
- <real>0.57</real>
- <key>baselineIntegrationDisplayName</key>
- <string>Feb 5, 2015, 9:42:47 AM</string>
- </dict>
- </dict>
- <key>testPackedExtensionsPerformance</key>
- <dict>
- <key>com.apple.XCTPerformanceMetric_WallClockTime</key>
- <dict>
- <key>baselineAverage</key>
- <real>0.75</real>
- <key>baselineIntegrationDisplayName</key>
- <string>Feb 5, 2015, 9:42:51 AM</string>
- </dict>
- </dict>
- <key>testPackedTypesPerformance</key>
- <dict>
- <key>com.apple.XCTPerformanceMetric_WallClockTime</key>
- <dict>
- <key>baselineAverage</key>
- <real>0.26</real>
- <key>baselineIntegrationDisplayName</key>
- <string>Feb 5, 2015, 9:42:55 AM</string>
- </dict>
- </dict>
- </dict>
- </dict>
-</dict>
-</plist>
diff --git a/objectivec/ProtocolBuffers_iOS.xcodeproj/xcshareddata/xcbaselines/8BBEA4A5147C727100C4ADB7.xcbaseline/Info.plist b/objectivec/ProtocolBuffers_iOS.xcodeproj/xcshareddata/xcbaselines/8BBEA4A5147C727100C4ADB7.xcbaseline/Info.plist
deleted file mode 100644
index 45bb9c1b..00000000
--- a/objectivec/ProtocolBuffers_iOS.xcodeproj/xcshareddata/xcbaselines/8BBEA4A5147C727100C4ADB7.xcbaseline/Info.plist
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>runDestinationsByUUID</key>
- <dict>
- <key>FFE465CA-0E74-40E8-9F09-500B66B7DCB2</key>
- <dict>
- <key>targetArchitecture</key>
- <string>arm64</string>
- <key>targetDevice</key>
- <dict>
- <key>modelCode</key>
- <string>iPhone7,1</string>
- <key>platformIdentifier</key>
- <string>com.apple.platform.iphoneos</string>
- </dict>
- </dict>
- </dict>
-</dict>
-</plist>
diff --git a/objectivec/ProtocolBuffers_iOS.xcodeproj/xcshareddata/xcschemes/PerformanceTests.xcscheme b/objectivec/ProtocolBuffers_iOS.xcodeproj/xcshareddata/xcschemes/PerformanceTests.xcscheme
index 100bd828..0b96b75f 100644
--- a/objectivec/ProtocolBuffers_iOS.xcodeproj/xcshareddata/xcschemes/PerformanceTests.xcscheme
+++ b/objectivec/ProtocolBuffers_iOS.xcodeproj/xcshareddata/xcschemes/PerformanceTests.xcscheme
@@ -159,6 +159,9 @@
Identifier = "GPBInt64UInt64DictionaryTests">
</Test>
<Test
+ Identifier = "GPBObjectiveCPlusPlusTests">
+ </Test>
+ <Test
Identifier = "GPBStringBoolDictionaryTests">
</Test>
<Test
@@ -180,9 +183,6 @@
Identifier = "GPBStringInt64DictionaryTests">
</Test>
<Test
- Identifier = "GPBStringTests">
- </Test>
- <Test
Identifier = "GPBStringUInt32DictionaryTests">
</Test>
<Test
diff --git a/objectivec/ProtocolBuffers_iOS.xcodeproj/xcshareddata/xcschemes/ProtocolBuffers.xcscheme b/objectivec/ProtocolBuffers_iOS.xcodeproj/xcshareddata/xcschemes/ProtocolBuffers.xcscheme
index 7d219bcd..d53a75f9 100644
--- a/objectivec/ProtocolBuffers_iOS.xcodeproj/xcshareddata/xcschemes/ProtocolBuffers.xcscheme
+++ b/objectivec/ProtocolBuffers_iOS.xcodeproj/xcshareddata/xcschemes/ProtocolBuffers.xcscheme
@@ -54,7 +54,8 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
- shouldUseLaunchSchemeArgsEnv = "YES">
+ shouldUseLaunchSchemeArgsEnv = "YES"
+ codeCoverageEnabled = "YES">
<Testables>
<TestableReference
skipped = "NO">
diff --git a/objectivec/README.md b/objectivec/README.md
index 452feca4..06118349 100644
--- a/objectivec/README.md
+++ b/objectivec/README.md
@@ -10,7 +10,7 @@ This directory contains the Objective C Protocol Buffers runtime library.
Requirements
------------
-The Objective C implemention requires:
+The Objective C implementation requires:
- Objective C 2.0 Runtime (32bit & 64bit iOS, 64bit OS X).
- Xcode 7.0 (or later).
@@ -123,8 +123,8 @@ never included when the message is encoded.
The Objective C classes/enums can be used from Swift code.
-Objective C Generator Options
------------------------------
+Objective C Generator Proto File Options
+----------------------------------------
**objc_class_prefix=\<prefix\>** (no default)
@@ -133,6 +133,42 @@ be collisions. This option provides a prefix that will be added to the Enums
and Objects (for messages) generated from the proto. Convention is to base
the prefix on the package the proto is in.
+Objective C Generator `protoc` Options
+--------------------------------------
+
+When generating Objective C code, `protoc` supports a `--objc_opt` argument; the
+argument is comma-delimited name/value pairs (_key=value,key2=value2_). The
+_keys_ are used to change the behavior during generation. The currently
+supported keys are:
+
+ * `generate_for_named_framework`: The `value` used for this key will be used
+ when generating the `#import` statements in the generated code. Instead
+ of being plain `#import "some/path/file.pbobjc.h"` lines, they will be
+ framework based, i.e. - `#import <VALUE/file.pbobjc.h>`.
+
+ _NOTE:_ If this is used with `named_framework_to_proto_path_mappings_path`,
+ then this is effectively the _default_ to use for everything that wasn't
+ mapped by the other.
+
+ * `named_framework_to_proto_path_mappings_path`: The `value` used for this key
+ is a path to a file containing the listing of framework names and proto
+ files. The generator uses this to decide if another proto file referenced
+ should use a framework style import vs. a user level import
+ (`#import <FRAMEWORK/file.pbobjc.h>` vs `#import "dir/file.pbobjc.h"`).
+
+ The format of the file is:
+ * An entry is a line of `frameworkName: file.proto, dir/file2.proto`.
+ * Comments start with `#`.
+ * A comment can go on a line after an entry.
+ (i.e. - `frameworkName: file.proto # comment`)
+
+ 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
+ lot of proto files included in it; and having multiple lines makes things
+ easier to read.
+
Contributing
------------
diff --git a/objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester.xcodeproj/project.pbxproj b/objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester.xcodeproj/project.pbxproj
new file mode 100644
index 00000000..b9df381a
--- /dev/null
+++ b/objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester.xcodeproj/project.pbxproj
@@ -0,0 +1,290 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ F4D5A0AE1CEE2D8F00562D79 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = F4D5A0AD1CEE2D8F00562D79 /* AppDelegate.m */; };
+ F4D5A0B11CEE2D8F00562D79 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = F4D5A0B01CEE2D8F00562D79 /* main.m */; };
+ F4D5A0B31CEE2D8F00562D79 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F4D5A0B21CEE2D8F00562D79 /* Assets.xcassets */; };
+ F4D5A0B61CEE2D8F00562D79 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = F4D5A0B41CEE2D8F00562D79 /* MainMenu.xib */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ F4D5A0A91CEE2D8F00562D79 /* OSXCocoaPodsTester.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = OSXCocoaPodsTester.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ F4D5A0AC1CEE2D8F00562D79 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
+ F4D5A0AD1CEE2D8F00562D79 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
+ F4D5A0B01CEE2D8F00562D79 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
+ F4D5A0B21CEE2D8F00562D79 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
+ F4D5A0B51CEE2D8F00562D79 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
+ F4D5A0B71CEE2D8F00562D79 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ F4D5A0A61CEE2D8F00562D79 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ F4D5A0A01CEE2D8F00562D79 = {
+ isa = PBXGroup;
+ children = (
+ F4D5A0AB1CEE2D8F00562D79 /* OSXCocoaPodsTester */,
+ F4D5A0AA1CEE2D8F00562D79 /* Products */,
+ );
+ sourceTree = "<group>";
+ };
+ F4D5A0AA1CEE2D8F00562D79 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ F4D5A0A91CEE2D8F00562D79 /* OSXCocoaPodsTester.app */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ F4D5A0AB1CEE2D8F00562D79 /* OSXCocoaPodsTester */ = {
+ isa = PBXGroup;
+ children = (
+ F4D5A0AC1CEE2D8F00562D79 /* AppDelegate.h */,
+ F4D5A0AD1CEE2D8F00562D79 /* AppDelegate.m */,
+ F4D5A0B21CEE2D8F00562D79 /* Assets.xcassets */,
+ F4D5A0B41CEE2D8F00562D79 /* MainMenu.xib */,
+ F4D5A0B71CEE2D8F00562D79 /* Info.plist */,
+ F4D5A0AF1CEE2D8F00562D79 /* Supporting Files */,
+ );
+ path = OSXCocoaPodsTester;
+ sourceTree = "<group>";
+ };
+ F4D5A0AF1CEE2D8F00562D79 /* Supporting Files */ = {
+ isa = PBXGroup;
+ children = (
+ F4D5A0B01CEE2D8F00562D79 /* main.m */,
+ );
+ name = "Supporting Files";
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ F4D5A0A81CEE2D8F00562D79 /* OSXCocoaPodsTester */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = F4D5A0BA1CEE2D8F00562D79 /* Build configuration list for PBXNativeTarget "OSXCocoaPodsTester" */;
+ buildPhases = (
+ F4D5A0A51CEE2D8F00562D79 /* Sources */,
+ F4D5A0A61CEE2D8F00562D79 /* Frameworks */,
+ F4D5A0A71CEE2D8F00562D79 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = OSXCocoaPodsTester;
+ productName = OSXCocoaPodsTester;
+ productReference = F4D5A0A91CEE2D8F00562D79 /* OSXCocoaPodsTester.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ F4D5A0A11CEE2D8F00562D79 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 0730;
+ ORGANIZATIONNAME = Google;
+ TargetAttributes = {
+ F4D5A0A81CEE2D8F00562D79 = {
+ CreatedOnToolsVersion = 7.3.1;
+ };
+ };
+ };
+ buildConfigurationList = F4D5A0A41CEE2D8F00562D79 /* Build configuration list for PBXProject "OSXCocoaPodsTester" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = F4D5A0A01CEE2D8F00562D79;
+ productRefGroup = F4D5A0AA1CEE2D8F00562D79 /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ F4D5A0A81CEE2D8F00562D79 /* OSXCocoaPodsTester */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ F4D5A0A71CEE2D8F00562D79 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F4D5A0B31CEE2D8F00562D79 /* Assets.xcassets in Resources */,
+ F4D5A0B61CEE2D8F00562D79 /* MainMenu.xib in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ F4D5A0A51CEE2D8F00562D79 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F4D5A0B11CEE2D8F00562D79 /* main.m in Sources */,
+ F4D5A0AE1CEE2D8F00562D79 /* AppDelegate.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+ F4D5A0B41CEE2D8F00562D79 /* MainMenu.xib */ = {
+ isa = PBXVariantGroup;
+ children = (
+ F4D5A0B51CEE2D8F00562D79 /* Base */,
+ );
+ name = MainMenu.xib;
+ sourceTree = "<group>";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ F4D5A0B81CEE2D8F00562D79 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_IDENTITY = "-";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ MACOSX_DEPLOYMENT_TARGET = 10.11;
+ MTL_ENABLE_DEBUG_INFO = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = macosx;
+ };
+ name = Debug;
+ };
+ F4D5A0B91CEE2D8F00562D79 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_IDENTITY = "-";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ MACOSX_DEPLOYMENT_TARGET = 10.11;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = macosx;
+ };
+ name = Release;
+ };
+ F4D5A0BB1CEE2D8F00562D79 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ COMBINE_HIDPI_IMAGES = YES;
+ INFOPLIST_FILE = OSXCocoaPodsTester/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = com.google.OSXCocoaPodsTester;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Debug;
+ };
+ F4D5A0BC1CEE2D8F00562D79 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ COMBINE_HIDPI_IMAGES = YES;
+ INFOPLIST_FILE = OSXCocoaPodsTester/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = com.google.OSXCocoaPodsTester;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ F4D5A0A41CEE2D8F00562D79 /* Build configuration list for PBXProject "OSXCocoaPodsTester" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ F4D5A0B81CEE2D8F00562D79 /* Debug */,
+ F4D5A0B91CEE2D8F00562D79 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ F4D5A0BA1CEE2D8F00562D79 /* Build configuration list for PBXNativeTarget "OSXCocoaPodsTester" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ F4D5A0BB1CEE2D8F00562D79 /* Debug */,
+ F4D5A0BC1CEE2D8F00562D79 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = F4D5A0A11CEE2D8F00562D79 /* Project object */;
+}
diff --git a/objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 00000000..6d874e28
--- /dev/null
+++ b/objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+ version = "1.0">
+ <FileRef
+ location = "self:OSXCocoaPodsTester.xcodeproj">
+ </FileRef>
+</Workspace>
diff --git a/objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester.xcodeproj/xcshareddata/xcschemes/OSXCocoaPodsTester.xcscheme b/objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester.xcodeproj/xcshareddata/xcschemes/OSXCocoaPodsTester.xcscheme
new file mode 100644
index 00000000..56f8782e
--- /dev/null
+++ b/objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester.xcodeproj/xcshareddata/xcschemes/OSXCocoaPodsTester.xcscheme
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+ LastUpgradeVersion = "0730"
+ version = "1.3">
+ <BuildAction
+ parallelizeBuildables = "YES"
+ buildImplicitDependencies = "YES">
+ <BuildActionEntries>
+ <BuildActionEntry
+ buildForTesting = "YES"
+ buildForRunning = "YES"
+ buildForProfiling = "YES"
+ buildForArchiving = "YES"
+ buildForAnalyzing = "YES">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "F4D5A0A81CEE2D8F00562D79"
+ BuildableName = "OSXCocoaPodsTester.app"
+ BlueprintName = "OSXCocoaPodsTester"
+ ReferencedContainer = "container:OSXCocoaPodsTester.xcodeproj">
+ </BuildableReference>
+ </BuildActionEntry>
+ </BuildActionEntries>
+ </BuildAction>
+ <TestAction
+ buildConfiguration = "Debug"
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ shouldUseLaunchSchemeArgsEnv = "YES">
+ <Testables>
+ </Testables>
+ <MacroExpansion>
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "F4D5A0A81CEE2D8F00562D79"
+ BuildableName = "OSXCocoaPodsTester.app"
+ BlueprintName = "OSXCocoaPodsTester"
+ ReferencedContainer = "container:OSXCocoaPodsTester.xcodeproj">
+ </BuildableReference>
+ </MacroExpansion>
+ <AdditionalOptions>
+ </AdditionalOptions>
+ </TestAction>
+ <LaunchAction
+ buildConfiguration = "Debug"
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ launchStyle = "0"
+ useCustomWorkingDirectory = "NO"
+ ignoresPersistentStateOnLaunch = "NO"
+ debugDocumentVersioning = "YES"
+ debugServiceExtension = "internal"
+ allowLocationSimulation = "YES">
+ <BuildableProductRunnable
+ runnableDebuggingMode = "0">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "F4D5A0A81CEE2D8F00562D79"
+ BuildableName = "OSXCocoaPodsTester.app"
+ BlueprintName = "OSXCocoaPodsTester"
+ ReferencedContainer = "container:OSXCocoaPodsTester.xcodeproj">
+ </BuildableReference>
+ </BuildableProductRunnable>
+ <AdditionalOptions>
+ </AdditionalOptions>
+ </LaunchAction>
+ <ProfileAction
+ buildConfiguration = "Release"
+ shouldUseLaunchSchemeArgsEnv = "YES"
+ savedToolIdentifier = ""
+ useCustomWorkingDirectory = "NO"
+ debugDocumentVersioning = "YES">
+ <BuildableProductRunnable
+ runnableDebuggingMode = "0">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "F4D5A0A81CEE2D8F00562D79"
+ BuildableName = "OSXCocoaPodsTester.app"
+ BlueprintName = "OSXCocoaPodsTester"
+ ReferencedContainer = "container:OSXCocoaPodsTester.xcodeproj">
+ </BuildableReference>
+ </BuildableProductRunnable>
+ </ProfileAction>
+ <AnalyzeAction
+ buildConfiguration = "Debug">
+ </AnalyzeAction>
+ <ArchiveAction
+ buildConfiguration = "Release"
+ revealArchiveInOrganizer = "YES">
+ </ArchiveAction>
+</Scheme>
diff --git a/objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/AppDelegate.h b/objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/AppDelegate.h
new file mode 100644
index 00000000..c7ab521d
--- /dev/null
+++ b/objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/AppDelegate.h
@@ -0,0 +1,37 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2016 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.
+
+#import <Cocoa/Cocoa.h>
+
+@interface AppDelegate : NSObject <NSApplicationDelegate>
+
+
+@end
+
diff --git a/objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/AppDelegate.m b/objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/AppDelegate.m
new file mode 100644
index 00000000..08735a00
--- /dev/null
+++ b/objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/AppDelegate.m
@@ -0,0 +1,48 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2016 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.
+
+#import "AppDelegate.h"
+
+@interface AppDelegate ()
+
+@property (weak) IBOutlet NSWindow *window;
+@end
+
+@implementation AppDelegate
+
+- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
+ // Insert code here to initialize your application
+}
+
+- (void)applicationWillTerminate:(NSNotification *)aNotification {
+ // Insert code here to tear down your application
+}
+
+@end
diff --git a/objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/Assets.xcassets/AppIcon.appiconset/Contents.json b/objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 00000000..2db2b1c7
--- /dev/null
+++ b/objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,58 @@
+{
+ "images" : [
+ {
+ "idiom" : "mac",
+ "size" : "16x16",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "16x16",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "32x32",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "32x32",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "128x128",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "128x128",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "256x256",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "256x256",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "512x512",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "512x512",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+} \ No newline at end of file
diff --git a/objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/Base.lproj/MainMenu.xib b/objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/Base.lproj/MainMenu.xib
new file mode 100644
index 00000000..aa3547ca
--- /dev/null
+++ b/objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/Base.lproj/MainMenu.xib
@@ -0,0 +1,680 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="6233" systemVersion="14A329f" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
+ <dependencies>
+ <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="6233"/>
+ </dependencies>
+ <objects>
+ <customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
+ <connections>
+ <outlet property="delegate" destination="Voe-Tx-rLC" id="GzC-gU-4Uq"/>
+ </connections>
+ </customObject>
+ <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
+ <customObject id="-3" userLabel="Application" customClass="NSObject"/>
+ <customObject id="Voe-Tx-rLC" customClass="AppDelegate" customModuleProvider="">
+ <connections>
+ <outlet property="window" destination="QvC-M9-y7g" id="gIp-Ho-8D9"/>
+ </connections>
+ </customObject>
+ <customObject id="YLy-65-1bz" customClass="NSFontManager"/>
+ <menu title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
+ <items>
+ <menuItem title="OSXCocoaPodsTester" id="1Xt-HY-uBw">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="OSXCocoaPodsTester" systemMenu="apple" id="uQy-DD-JDr">
+ <items>
+ <menuItem title="About OSXCocoaPodsTester" id="5kV-Vb-QxS">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="orderFrontStandardAboutPanel:" target="-1" id="Exp-CZ-Vem"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="VOq-y0-SEH"/>
+ <menuItem title="Preferences…" keyEquivalent="," id="BOF-NM-1cW"/>
+ <menuItem isSeparatorItem="YES" id="wFC-TO-SCJ"/>
+ <menuItem title="Services" id="NMo-om-nkz">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Services" systemMenu="services" id="hz9-B4-Xy5"/>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="4je-JR-u6R"/>
+ <menuItem title="Hide OSXCocoaPodsTester" keyEquivalent="h" id="Olw-nP-bQN">
+ <connections>
+ <action selector="hide:" target="-1" id="PnN-Uc-m68"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Hide Others" keyEquivalent="h" id="Vdr-fp-XzO">
+ <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
+ <connections>
+ <action selector="hideOtherApplications:" target="-1" id="VT4-aY-XCT"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Show All" id="Kd2-mp-pUS">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="unhideAllApplications:" target="-1" id="Dhg-Le-xox"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/>
+ <menuItem title="Quit OSXCocoaPodsTester" keyEquivalent="q" id="4sb-4s-VLi">
+ <connections>
+ <action selector="terminate:" target="-1" id="Te7-pn-YzF"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="File" id="dMs-cI-mzQ">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="File" id="bib-Uj-vzu">
+ <items>
+ <menuItem title="New" keyEquivalent="n" id="Was-JA-tGl">
+ <connections>
+ <action selector="newDocument:" target="-1" id="4Si-XN-c54"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Open…" keyEquivalent="o" id="IAo-SY-fd9">
+ <connections>
+ <action selector="openDocument:" target="-1" id="bVn-NM-KNZ"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Open Recent" id="tXI-mr-wws">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Open Recent" systemMenu="recentDocuments" id="oas-Oc-fiZ">
+ <items>
+ <menuItem title="Clear Menu" id="vNY-rz-j42">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="clearRecentDocuments:" target="-1" id="Daa-9d-B3U"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="m54-Is-iLE"/>
+ <menuItem title="Close" keyEquivalent="w" id="DVo-aG-piG">
+ <connections>
+ <action selector="performClose:" target="-1" id="HmO-Ls-i7Q"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Save…" keyEquivalent="s" id="pxx-59-PXV">
+ <connections>
+ <action selector="saveDocument:" target="-1" id="teZ-XB-qJY"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Save As…" keyEquivalent="S" id="Bw7-FT-i3A">
+ <connections>
+ <action selector="saveDocumentAs:" target="-1" id="mDf-zr-I0C"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Revert to Saved" id="KaW-ft-85H">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="revertDocumentToSaved:" target="-1" id="iJ3-Pv-kwq"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="aJh-i4-bef"/>
+ <menuItem title="Page Setup…" keyEquivalent="P" id="qIS-W8-SiK">
+ <modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
+ <connections>
+ <action selector="runPageLayout:" target="-1" id="Din-rz-gC5"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Print…" keyEquivalent="p" id="aTl-1u-JFS">
+ <connections>
+ <action selector="print:" target="-1" id="qaZ-4w-aoO"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Edit" id="5QF-Oa-p0T">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Edit" id="W48-6f-4Dl">
+ <items>
+ <menuItem title="Undo" keyEquivalent="z" id="dRJ-4n-Yzg">
+ <connections>
+ <action selector="undo:" target="-1" id="M6e-cu-g7V"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Redo" keyEquivalent="Z" id="6dh-zS-Vam">
+ <connections>
+ <action selector="redo:" target="-1" id="oIA-Rs-6OD"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="WRV-NI-Exz"/>
+ <menuItem title="Cut" keyEquivalent="x" id="uRl-iY-unG">
+ <connections>
+ <action selector="cut:" target="-1" id="YJe-68-I9s"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Copy" keyEquivalent="c" id="x3v-GG-iWU">
+ <connections>
+ <action selector="copy:" target="-1" id="G1f-GL-Joy"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Paste" keyEquivalent="v" id="gVA-U4-sdL">
+ <connections>
+ <action selector="paste:" target="-1" id="UvS-8e-Qdg"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Paste and Match Style" keyEquivalent="V" id="WeT-3V-zwk">
+ <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
+ <connections>
+ <action selector="pasteAsPlainText:" target="-1" id="cEh-KX-wJQ"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Delete" id="pa3-QI-u2k">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="delete:" target="-1" id="0Mk-Ml-PaM"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Select All" keyEquivalent="a" id="Ruw-6m-B2m">
+ <connections>
+ <action selector="selectAll:" target="-1" id="VNm-Mi-diN"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="uyl-h8-XO2"/>
+ <menuItem title="Find" id="4EN-yA-p0u">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Find" id="1b7-l0-nxx">
+ <items>
+ <menuItem title="Find…" tag="1" keyEquivalent="f" id="Xz5-n4-O0W">
+ <connections>
+ <action selector="performFindPanelAction:" target="-1" id="cD7-Qs-BN4"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Find and Replace…" tag="12" keyEquivalent="f" id="YEy-JH-Tfz">
+ <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
+ <connections>
+ <action selector="performFindPanelAction:" target="-1" id="WD3-Gg-5AJ"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Find Next" tag="2" keyEquivalent="g" id="q09-fT-Sye">
+ <connections>
+ <action selector="performFindPanelAction:" target="-1" id="NDo-RZ-v9R"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Find Previous" tag="3" keyEquivalent="G" id="OwM-mh-QMV">
+ <connections>
+ <action selector="performFindPanelAction:" target="-1" id="HOh-sY-3ay"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="buJ-ug-pKt">
+ <connections>
+ <action selector="performFindPanelAction:" target="-1" id="U76-nv-p5D"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Jump to Selection" keyEquivalent="j" id="S0p-oC-mLd">
+ <connections>
+ <action selector="centerSelectionInVisibleArea:" target="-1" id="IOG-6D-g5B"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Spelling and Grammar" id="Dv1-io-Yv7">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Spelling" id="3IN-sU-3Bg">
+ <items>
+ <menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="HFo-cy-zxI">
+ <connections>
+ <action selector="showGuessPanel:" target="-1" id="vFj-Ks-hy3"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Check Document Now" keyEquivalent=";" id="hz2-CU-CR7">
+ <connections>
+ <action selector="checkSpelling:" target="-1" id="fz7-VC-reM"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="bNw-od-mp5"/>
+ <menuItem title="Check Spelling While Typing" id="rbD-Rh-wIN">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleContinuousSpellChecking:" target="-1" id="7w6-Qz-0kB"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Check Grammar With Spelling" id="mK6-2p-4JG">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleGrammarChecking:" target="-1" id="muD-Qn-j4w"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Correct Spelling Automatically" id="78Y-hA-62v">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleAutomaticSpellingCorrection:" target="-1" id="2lM-Qi-WAP"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Substitutions" id="9ic-FL-obx">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Substitutions" id="FeM-D8-WVr">
+ <items>
+ <menuItem title="Show Substitutions" id="z6F-FW-3nz">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="orderFrontSubstitutionsPanel:" target="-1" id="oku-mr-iSq"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="gPx-C9-uUO"/>
+ <menuItem title="Smart Copy/Paste" id="9yt-4B-nSM">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleSmartInsertDelete:" target="-1" id="3IJ-Se-DZD"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Smart Quotes" id="hQb-2v-fYv">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleAutomaticQuoteSubstitution:" target="-1" id="ptq-xd-QOA"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Smart Dashes" id="rgM-f4-ycn">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleAutomaticDashSubstitution:" target="-1" id="oCt-pO-9gS"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Smart Links" id="cwL-P1-jid">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleAutomaticLinkDetection:" target="-1" id="Gip-E3-Fov"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Data Detectors" id="tRr-pd-1PS">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleAutomaticDataDetection:" target="-1" id="R1I-Nq-Kbl"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Text Replacement" id="HFQ-gK-NFA">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleAutomaticTextReplacement:" target="-1" id="DvP-Fe-Py6"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Transformations" id="2oI-Rn-ZJC">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Transformations" id="c8a-y6-VQd">
+ <items>
+ <menuItem title="Make Upper Case" id="vmV-6d-7jI">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="uppercaseWord:" target="-1" id="sPh-Tk-edu"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Make Lower Case" id="d9M-CD-aMd">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="lowercaseWord:" target="-1" id="iUZ-b5-hil"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Capitalize" id="UEZ-Bs-lqG">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="capitalizeWord:" target="-1" id="26H-TL-nsh"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Speech" id="xrE-MZ-jX0">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Speech" id="3rS-ZA-NoH">
+ <items>
+ <menuItem title="Start Speaking" id="Ynk-f8-cLZ">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="startSpeaking:" target="-1" id="654-Ng-kyl"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Stop Speaking" id="Oyz-dy-DGm">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="stopSpeaking:" target="-1" id="dX8-6p-jy9"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Format" id="jxT-CU-nIS">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Format" id="GEO-Iw-cKr">
+ <items>
+ <menuItem title="Font" id="Gi5-1S-RQB">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Font" systemMenu="font" id="aXa-aM-Jaq">
+ <items>
+ <menuItem title="Show Fonts" keyEquivalent="t" id="Q5e-8K-NDq">
+ <connections>
+ <action selector="orderFrontFontPanel:" target="YLy-65-1bz" id="WHr-nq-2xA"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Bold" tag="2" keyEquivalent="b" id="GB9-OM-e27">
+ <connections>
+ <action selector="addFontTrait:" target="YLy-65-1bz" id="hqk-hr-sYV"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Italic" tag="1" keyEquivalent="i" id="Vjx-xi-njq">
+ <connections>
+ <action selector="addFontTrait:" target="YLy-65-1bz" id="IHV-OB-c03"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Underline" keyEquivalent="u" id="WRG-CD-K1S">
+ <connections>
+ <action selector="underline:" target="-1" id="FYS-2b-JAY"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="5gT-KC-WSO"/>
+ <menuItem title="Bigger" tag="3" keyEquivalent="+" id="Ptp-SP-VEL">
+ <connections>
+ <action selector="modifyFont:" target="YLy-65-1bz" id="Uc7-di-UnL"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Smaller" tag="4" keyEquivalent="-" id="i1d-Er-qST">
+ <connections>
+ <action selector="modifyFont:" target="YLy-65-1bz" id="HcX-Lf-eNd"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="kx3-Dk-x3B"/>
+ <menuItem title="Kern" id="jBQ-r6-VK2">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Kern" id="tlD-Oa-oAM">
+ <items>
+ <menuItem title="Use Default" id="GUa-eO-cwY">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="useStandardKerning:" target="-1" id="6dk-9l-Ckg"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Use None" id="cDB-IK-hbR">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="turnOffKerning:" target="-1" id="U8a-gz-Maa"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Tighten" id="46P-cB-AYj">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="tightenKerning:" target="-1" id="hr7-Nz-8ro"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Loosen" id="ogc-rX-tC1">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="loosenKerning:" target="-1" id="8i4-f9-FKE"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Ligatures" id="o6e-r0-MWq">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Ligatures" id="w0m-vy-SC9">
+ <items>
+ <menuItem title="Use Default" id="agt-UL-0e3">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="useStandardLigatures:" target="-1" id="7uR-wd-Dx6"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Use None" id="J7y-lM-qPV">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="turnOffLigatures:" target="-1" id="iX2-gA-Ilz"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Use All" id="xQD-1f-W4t">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="useAllLigatures:" target="-1" id="KcB-kA-TuK"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Baseline" id="OaQ-X3-Vso">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Baseline" id="ijk-EB-dga">
+ <items>
+ <menuItem title="Use Default" id="3Om-Ey-2VK">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="unscript:" target="-1" id="0vZ-95-Ywn"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Superscript" id="Rqc-34-cIF">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="superscript:" target="-1" id="3qV-fo-wpU"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Subscript" id="I0S-gh-46l">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="subscript:" target="-1" id="Q6W-4W-IGz"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Raise" id="2h7-ER-AoG">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="raiseBaseline:" target="-1" id="4sk-31-7Q9"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Lower" id="1tx-W0-xDw">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="lowerBaseline:" target="-1" id="OF1-bc-KW4"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="Ndw-q3-faq"/>
+ <menuItem title="Show Colors" keyEquivalent="C" id="bgn-CT-cEk">
+ <connections>
+ <action selector="orderFrontColorPanel:" target="-1" id="mSX-Xz-DV3"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="iMs-zA-UFJ"/>
+ <menuItem title="Copy Style" keyEquivalent="c" id="5Vv-lz-BsD">
+ <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
+ <connections>
+ <action selector="copyFont:" target="-1" id="GJO-xA-L4q"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Paste Style" keyEquivalent="v" id="vKC-jM-MkH">
+ <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
+ <connections>
+ <action selector="pasteFont:" target="-1" id="JfD-CL-leO"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Text" id="Fal-I4-PZk">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Text" id="d9c-me-L2H">
+ <items>
+ <menuItem title="Align Left" keyEquivalent="{" id="ZM1-6Q-yy1">
+ <connections>
+ <action selector="alignLeft:" target="-1" id="zUv-R1-uAa"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Center" keyEquivalent="|" id="VIY-Ag-zcb">
+ <connections>
+ <action selector="alignCenter:" target="-1" id="spX-mk-kcS"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Justify" id="J5U-5w-g23">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="alignJustified:" target="-1" id="ljL-7U-jND"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Align Right" keyEquivalent="}" id="wb2-vD-lq4">
+ <connections>
+ <action selector="alignRight:" target="-1" id="r48-bG-YeY"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="4s2-GY-VfK"/>
+ <menuItem title="Writing Direction" id="H1b-Si-o9J">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Writing Direction" id="8mr-sm-Yjd">
+ <items>
+ <menuItem title="Paragraph" enabled="NO" id="ZvO-Gk-QUH">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ </menuItem>
+ <menuItem id="YGs-j5-SAR">
+ <string key="title"> Default</string>
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="makeBaseWritingDirectionNatural:" target="-1" id="qtV-5e-UBP"/>
+ </connections>
+ </menuItem>
+ <menuItem id="Lbh-J2-qVU">
+ <string key="title"> Left to Right</string>
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="makeBaseWritingDirectionLeftToRight:" target="-1" id="S0X-9S-QSf"/>
+ </connections>
+ </menuItem>
+ <menuItem id="jFq-tB-4Kx">
+ <string key="title"> Right to Left</string>
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="makeBaseWritingDirectionRightToLeft:" target="-1" id="5fk-qB-AqJ"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="swp-gr-a21"/>
+ <menuItem title="Selection" enabled="NO" id="cqv-fj-IhA">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ </menuItem>
+ <menuItem id="Nop-cj-93Q">
+ <string key="title"> Default</string>
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="makeTextWritingDirectionNatural:" target="-1" id="lPI-Se-ZHp"/>
+ </connections>
+ </menuItem>
+ <menuItem id="BgM-ve-c93">
+ <string key="title"> Left to Right</string>
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="makeTextWritingDirectionLeftToRight:" target="-1" id="caW-Bv-w94"/>
+ </connections>
+ </menuItem>
+ <menuItem id="RB4-Sm-HuC">
+ <string key="title"> Right to Left</string>
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="makeTextWritingDirectionRightToLeft:" target="-1" id="EXD-6r-ZUu"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="fKy-g9-1gm"/>
+ <menuItem title="Show Ruler" id="vLm-3I-IUL">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleRuler:" target="-1" id="FOx-HJ-KwY"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Copy Ruler" keyEquivalent="c" id="MkV-Pr-PK5">
+ <modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
+ <connections>
+ <action selector="copyRuler:" target="-1" id="71i-fW-3W2"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Paste Ruler" keyEquivalent="v" id="LVM-kO-fVI">
+ <modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
+ <connections>
+ <action selector="pasteRuler:" target="-1" id="cSh-wd-qM2"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="View" id="H8h-7b-M4v">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="View" id="HyV-fh-RgO">
+ <items>
+ <menuItem title="Show Toolbar" keyEquivalent="t" id="snW-S8-Cw5">
+ <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
+ <connections>
+ <action selector="toggleToolbarShown:" target="-1" id="BXY-wc-z0C"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Customize Toolbar…" id="1UK-8n-QPP">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="runToolbarCustomizationPalette:" target="-1" id="pQI-g3-MTW"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Window" id="aUF-d1-5bR">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Window" systemMenu="window" id="Td7-aD-5lo">
+ <items>
+ <menuItem title="Minimize" keyEquivalent="m" id="OY7-WF-poV">
+ <connections>
+ <action selector="performMiniaturize:" target="-1" id="VwT-WD-YPe"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Zoom" id="R4o-n2-Eq4">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="performZoom:" target="-1" id="DIl-cC-cCs"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="eu3-7i-yIM"/>
+ <menuItem title="Bring All to Front" id="LE2-aR-0XJ">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="arrangeInFront:" target="-1" id="DRN-fu-gQh"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Help" id="wpr-3q-Mcd">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Help" systemMenu="help" id="F2S-fz-NVQ">
+ <items>
+ <menuItem title="OSXCocoaPodsTester Help" keyEquivalent="?" id="FKE-Sm-Kum">
+ <connections>
+ <action selector="showHelp:" target="-1" id="y7X-2Q-9no"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ </items>
+ </menu>
+ <window title="OSXCocoaPodsTester" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="QvC-M9-y7g">
+ <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
+ <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
+ <rect key="contentRect" x="335" y="390" width="480" height="360"/>
+ <rect key="screenRect" x="0.0" y="0.0" width="1920" height="1177"/>
+ <view key="contentView" id="EiT-Mj-1SZ">
+ <rect key="frame" x="0.0" y="0.0" width="480" height="360"/>
+ <autoresizingMask key="autoresizingMask"/>
+ </view>
+ </window>
+ </objects>
+</document>
diff --git a/objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/Info.plist b/objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/Info.plist
new file mode 100644
index 00000000..ed806e40
--- /dev/null
+++ b/objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/Info.plist
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>en</string>
+ <key>CFBundleExecutable</key>
+ <string>$(EXECUTABLE_NAME)</string>
+ <key>CFBundleIconFile</key>
+ <string></string>
+ <key>CFBundleIdentifier</key>
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>$(PRODUCT_NAME)</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1</string>
+ <key>LSMinimumSystemVersion</key>
+ <string>$(MACOSX_DEPLOYMENT_TARGET)</string>
+ <key>NSHumanReadableCopyright</key>
+ <string>Copyright © 2016 Google. All rights reserved.</string>
+ <key>NSMainNibFile</key>
+ <string>MainMenu</string>
+ <key>NSPrincipalClass</key>
+ <string>NSApplication</string>
+</dict>
+</plist>
diff --git a/objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/main.m b/objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/main.m
new file mode 100644
index 00000000..b230090e
--- /dev/null
+++ b/objectivec/Tests/CocoaPods/OSXCocoaPodsTester/OSXCocoaPodsTester/main.m
@@ -0,0 +1,35 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2016 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.
+
+#import <Cocoa/Cocoa.h>
+
+int main(int argc, const char * argv[]) {
+ return NSApplicationMain(argc, argv);
+}
diff --git a/objectivec/Tests/CocoaPods/OSXCocoaPodsTester/Podfile-framework b/objectivec/Tests/CocoaPods/OSXCocoaPodsTester/Podfile-framework
new file mode 100644
index 00000000..27eeafc9
--- /dev/null
+++ b/objectivec/Tests/CocoaPods/OSXCocoaPodsTester/Podfile-framework
@@ -0,0 +1,10 @@
+source 'https://github.com/CocoaPods/Specs.git'
+platform :osx, '10.9'
+
+install! 'cocoapods', :deterministic_uuids => false
+
+use_frameworks!
+
+target 'OSXCocoaPodsTester' do
+ pod 'Protobuf', :path => '../../../..'
+end
diff --git a/objectivec/Tests/CocoaPods/OSXCocoaPodsTester/Podfile-static b/objectivec/Tests/CocoaPods/OSXCocoaPodsTester/Podfile-static
new file mode 100644
index 00000000..5dfc8de5
--- /dev/null
+++ b/objectivec/Tests/CocoaPods/OSXCocoaPodsTester/Podfile-static
@@ -0,0 +1,8 @@
+source 'https://github.com/CocoaPods/Specs.git'
+platform :osx, '10.9'
+
+install! 'cocoapods', :deterministic_uuids => false
+
+target 'OSXCocoaPodsTester' do
+ pod 'Protobuf', :path => '../../../..'
+end
diff --git a/objectivec/Tests/CocoaPods/README.md b/objectivec/Tests/CocoaPods/README.md
new file mode 100644
index 00000000..08785918
--- /dev/null
+++ b/objectivec/Tests/CocoaPods/README.md
@@ -0,0 +1,9 @@
+CocoaPods Protocol Buffers Integration Tests
+============================================
+
+The sub directories are the basic projects as created by Xcode 6.3. They are
+used to then drive `pod` and `xcodebuild` to ensure things integrate/build
+as expected.
+
+`run_tests.sh` defaults to running all the tests, invoke it with `--help` to
+see the arguments to control what tests are run.
diff --git a/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/Podfile-framework b/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/Podfile-framework
new file mode 100644
index 00000000..913a289b
--- /dev/null
+++ b/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/Podfile-framework
@@ -0,0 +1,10 @@
+source 'https://github.com/CocoaPods/Specs.git'
+platform :ios, '8.0'
+
+install! 'cocoapods', :deterministic_uuids => false
+
+use_frameworks!
+
+target 'iOSCocoaPodsTester' do
+ pod 'Protobuf', :path => '../../../..'
+end
diff --git a/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/Podfile-static b/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/Podfile-static
new file mode 100644
index 00000000..e9b3c235
--- /dev/null
+++ b/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/Podfile-static
@@ -0,0 +1,8 @@
+source 'https://github.com/CocoaPods/Specs.git'
+platform :ios, '8.0'
+
+install! 'cocoapods', :deterministic_uuids => false
+
+target 'iOSCocoaPodsTester' do
+ pod 'Protobuf', :path => '../../../..'
+end
diff --git a/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester.xcodeproj/project.pbxproj b/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester.xcodeproj/project.pbxproj
new file mode 100644
index 00000000..27fb553f
--- /dev/null
+++ b/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester.xcodeproj/project.pbxproj
@@ -0,0 +1,309 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ F4D5A08B1CEE01E200562D79 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = F4D5A08A1CEE01E200562D79 /* main.m */; };
+ F4D5A08E1CEE01E200562D79 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = F4D5A08D1CEE01E200562D79 /* AppDelegate.m */; };
+ F4D5A0911CEE01E200562D79 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F4D5A0901CEE01E200562D79 /* ViewController.m */; };
+ F4D5A0941CEE01E200562D79 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F4D5A0921CEE01E200562D79 /* Main.storyboard */; };
+ F4D5A0961CEE01E200562D79 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F4D5A0951CEE01E200562D79 /* Assets.xcassets */; };
+ F4D5A0991CEE01E200562D79 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F4D5A0971CEE01E200562D79 /* LaunchScreen.storyboard */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ F4D5A0861CEE01E200562D79 /* iOSCocoaPodsTester.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iOSCocoaPodsTester.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ F4D5A08A1CEE01E200562D79 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
+ F4D5A08C1CEE01E200562D79 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
+ F4D5A08D1CEE01E200562D79 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
+ F4D5A08F1CEE01E200562D79 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = "<group>"; };
+ F4D5A0901CEE01E200562D79 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = "<group>"; };
+ F4D5A0931CEE01E200562D79 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
+ F4D5A0951CEE01E200562D79 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
+ F4D5A0981CEE01E200562D79 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
+ F4D5A09A1CEE01E200562D79 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ F4D5A0831CEE01E200562D79 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ F4D5A07D1CEE01E200562D79 = {
+ isa = PBXGroup;
+ children = (
+ F4D5A0881CEE01E200562D79 /* iOSCocoaPodsTester */,
+ F4D5A0871CEE01E200562D79 /* Products */,
+ );
+ sourceTree = "<group>";
+ };
+ F4D5A0871CEE01E200562D79 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ F4D5A0861CEE01E200562D79 /* iOSCocoaPodsTester.app */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ F4D5A0881CEE01E200562D79 /* iOSCocoaPodsTester */ = {
+ isa = PBXGroup;
+ children = (
+ F4D5A08C1CEE01E200562D79 /* AppDelegate.h */,
+ F4D5A08D1CEE01E200562D79 /* AppDelegate.m */,
+ F4D5A08F1CEE01E200562D79 /* ViewController.h */,
+ F4D5A0901CEE01E200562D79 /* ViewController.m */,
+ F4D5A0921CEE01E200562D79 /* Main.storyboard */,
+ F4D5A0951CEE01E200562D79 /* Assets.xcassets */,
+ F4D5A0971CEE01E200562D79 /* LaunchScreen.storyboard */,
+ F4D5A09A1CEE01E200562D79 /* Info.plist */,
+ F4D5A0891CEE01E200562D79 /* Supporting Files */,
+ );
+ path = iOSCocoaPodsTester;
+ sourceTree = "<group>";
+ };
+ F4D5A0891CEE01E200562D79 /* Supporting Files */ = {
+ isa = PBXGroup;
+ children = (
+ F4D5A08A1CEE01E200562D79 /* main.m */,
+ );
+ name = "Supporting Files";
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ F4D5A0851CEE01E200562D79 /* iOSCocoaPodsTester */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = F4D5A09D1CEE01E200562D79 /* Build configuration list for PBXNativeTarget "iOSCocoaPodsTester" */;
+ buildPhases = (
+ F4D5A0821CEE01E200562D79 /* Sources */,
+ F4D5A0831CEE01E200562D79 /* Frameworks */,
+ F4D5A0841CEE01E200562D79 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = iOSCocoaPodsTester;
+ productName = iOSCocoaPodsTester;
+ productReference = F4D5A0861CEE01E200562D79 /* iOSCocoaPodsTester.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ F4D5A07E1CEE01E200562D79 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 0730;
+ ORGANIZATIONNAME = Google;
+ TargetAttributes = {
+ F4D5A0851CEE01E200562D79 = {
+ CreatedOnToolsVersion = 7.3.1;
+ };
+ };
+ };
+ buildConfigurationList = F4D5A0811CEE01E200562D79 /* Build configuration list for PBXProject "iOSCocoaPodsTester" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = F4D5A07D1CEE01E200562D79;
+ productRefGroup = F4D5A0871CEE01E200562D79 /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ F4D5A0851CEE01E200562D79 /* iOSCocoaPodsTester */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ F4D5A0841CEE01E200562D79 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F4D5A0991CEE01E200562D79 /* LaunchScreen.storyboard in Resources */,
+ F4D5A0961CEE01E200562D79 /* Assets.xcassets in Resources */,
+ F4D5A0941CEE01E200562D79 /* Main.storyboard in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ F4D5A0821CEE01E200562D79 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F4D5A0911CEE01E200562D79 /* ViewController.m in Sources */,
+ F4D5A08E1CEE01E200562D79 /* AppDelegate.m in Sources */,
+ F4D5A08B1CEE01E200562D79 /* main.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+ F4D5A0921CEE01E200562D79 /* Main.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ F4D5A0931CEE01E200562D79 /* Base */,
+ );
+ name = Main.storyboard;
+ sourceTree = "<group>";
+ };
+ F4D5A0971CEE01E200562D79 /* LaunchScreen.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ F4D5A0981CEE01E200562D79 /* Base */,
+ );
+ name = LaunchScreen.storyboard;
+ sourceTree = "<group>";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ F4D5A09B1CEE01E200562D79 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 9.3;
+ MTL_ENABLE_DEBUG_INFO = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ F4D5A09C1CEE01E200562D79 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 9.3;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ F4D5A09E1CEE01E200562D79 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ INFOPLIST_FILE = iOSCocoaPodsTester/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = com.google.iOSCocoaPodsTester;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Debug;
+ };
+ F4D5A09F1CEE01E200562D79 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ INFOPLIST_FILE = iOSCocoaPodsTester/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = com.google.iOSCocoaPodsTester;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ F4D5A0811CEE01E200562D79 /* Build configuration list for PBXProject "iOSCocoaPodsTester" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ F4D5A09B1CEE01E200562D79 /* Debug */,
+ F4D5A09C1CEE01E200562D79 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ F4D5A09D1CEE01E200562D79 /* Build configuration list for PBXNativeTarget "iOSCocoaPodsTester" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ F4D5A09E1CEE01E200562D79 /* Debug */,
+ F4D5A09F1CEE01E200562D79 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = F4D5A07E1CEE01E200562D79 /* Project object */;
+}
diff --git a/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 00000000..008f7b4a
--- /dev/null
+++ b/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+ version = "1.0">
+ <FileRef
+ location = "self:iOSCocoaPodsTester.xcodeproj">
+ </FileRef>
+</Workspace>
diff --git a/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester.xcodeproj/xcshareddata/xcschemes/iOSCocoaPodsTester.xcscheme b/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester.xcodeproj/xcshareddata/xcschemes/iOSCocoaPodsTester.xcscheme
new file mode 100644
index 00000000..9558dd7a
--- /dev/null
+++ b/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester.xcodeproj/xcshareddata/xcschemes/iOSCocoaPodsTester.xcscheme
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+ LastUpgradeVersion = "0730"
+ version = "1.3">
+ <BuildAction
+ parallelizeBuildables = "YES"
+ buildImplicitDependencies = "YES">
+ <BuildActionEntries>
+ <BuildActionEntry
+ buildForTesting = "YES"
+ buildForRunning = "YES"
+ buildForProfiling = "YES"
+ buildForArchiving = "YES"
+ buildForAnalyzing = "YES">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "F4D5A0851CEE01E200562D79"
+ BuildableName = "iOSCocoaPodsTester.app"
+ BlueprintName = "iOSCocoaPodsTester"
+ ReferencedContainer = "container:iOSCocoaPodsTester.xcodeproj">
+ </BuildableReference>
+ </BuildActionEntry>
+ </BuildActionEntries>
+ </BuildAction>
+ <TestAction
+ buildConfiguration = "Debug"
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ shouldUseLaunchSchemeArgsEnv = "YES">
+ <Testables>
+ </Testables>
+ <MacroExpansion>
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "F4D5A0851CEE01E200562D79"
+ BuildableName = "iOSCocoaPodsTester.app"
+ BlueprintName = "iOSCocoaPodsTester"
+ ReferencedContainer = "container:iOSCocoaPodsTester.xcodeproj">
+ </BuildableReference>
+ </MacroExpansion>
+ <AdditionalOptions>
+ </AdditionalOptions>
+ </TestAction>
+ <LaunchAction
+ buildConfiguration = "Debug"
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ launchStyle = "0"
+ useCustomWorkingDirectory = "NO"
+ ignoresPersistentStateOnLaunch = "NO"
+ debugDocumentVersioning = "YES"
+ debugServiceExtension = "internal"
+ allowLocationSimulation = "YES">
+ <BuildableProductRunnable
+ runnableDebuggingMode = "0">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "F4D5A0851CEE01E200562D79"
+ BuildableName = "iOSCocoaPodsTester.app"
+ BlueprintName = "iOSCocoaPodsTester"
+ ReferencedContainer = "container:iOSCocoaPodsTester.xcodeproj">
+ </BuildableReference>
+ </BuildableProductRunnable>
+ <AdditionalOptions>
+ </AdditionalOptions>
+ </LaunchAction>
+ <ProfileAction
+ buildConfiguration = "Release"
+ shouldUseLaunchSchemeArgsEnv = "YES"
+ savedToolIdentifier = ""
+ useCustomWorkingDirectory = "NO"
+ debugDocumentVersioning = "YES">
+ <BuildableProductRunnable
+ runnableDebuggingMode = "0">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "F4D5A0851CEE01E200562D79"
+ BuildableName = "iOSCocoaPodsTester.app"
+ BlueprintName = "iOSCocoaPodsTester"
+ ReferencedContainer = "container:iOSCocoaPodsTester.xcodeproj">
+ </BuildableReference>
+ </BuildableProductRunnable>
+ </ProfileAction>
+ <AnalyzeAction
+ buildConfiguration = "Debug">
+ </AnalyzeAction>
+ <ArchiveAction
+ buildConfiguration = "Release"
+ revealArchiveInOrganizer = "YES">
+ </ArchiveAction>
+</Scheme>
diff --git a/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/AppDelegate.h b/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/AppDelegate.h
new file mode 100644
index 00000000..5eca690c
--- /dev/null
+++ b/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/AppDelegate.h
@@ -0,0 +1,39 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2016 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.
+
+#import <UIKit/UIKit.h>
+
+@interface AppDelegate : UIResponder <UIApplicationDelegate>
+
+@property (strong, nonatomic) UIWindow *window;
+
+
+@end
+
diff --git a/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/AppDelegate.m b/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/AppDelegate.m
new file mode 100644
index 00000000..dd7b969a
--- /dev/null
+++ b/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/AppDelegate.m
@@ -0,0 +1,67 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2016 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.
+
+#import "AppDelegate.h"
+
+@interface AppDelegate ()
+
+@end
+
+@implementation AppDelegate
+
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+ // Override point for customization after application launch.
+ return YES;
+}
+
+- (void)applicationWillResignActive:(UIApplication *)application {
+ // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
+ // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
+}
+
+- (void)applicationDidEnterBackground:(UIApplication *)application {
+ // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
+ // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
+}
+
+- (void)applicationWillEnterForeground:(UIApplication *)application {
+ // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
+}
+
+- (void)applicationDidBecomeActive:(UIApplication *)application {
+ // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
+}
+
+- (void)applicationWillTerminate:(UIApplication *)application {
+ // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
+}
+
+@end
diff --git a/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/Assets.xcassets/AppIcon.appiconset/Contents.json b/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 00000000..36d2c80d
--- /dev/null
+++ b/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,68 @@
+{
+ "images" : [
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "60x60",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "60x60",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "76x76",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "76x76",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+} \ No newline at end of file
diff --git a/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/Base.lproj/LaunchScreen.storyboard b/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/Base.lproj/LaunchScreen.storyboard
new file mode 100644
index 00000000..2e721e18
--- /dev/null
+++ b/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/Base.lproj/LaunchScreen.storyboard
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="8150" systemVersion="15A204g" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" initialViewController="01J-lp-oVM">
+ <dependencies>
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="8122"/>
+ </dependencies>
+ <scenes>
+ <!--View Controller-->
+ <scene sceneID="EHf-IW-A2E">
+ <objects>
+ <viewController id="01J-lp-oVM" sceneMemberID="viewController">
+ <layoutGuides>
+ <viewControllerLayoutGuide type="top" id="Llm-lL-Icb"/>
+ <viewControllerLayoutGuide type="bottom" id="xb3-aO-Qok"/>
+ </layoutGuides>
+ <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
+ <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+ <animations/>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
+ </view>
+ </viewController>
+ <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
+ </objects>
+ <point key="canvasLocation" x="53" y="375"/>
+ </scene>
+ </scenes>
+</document>
diff --git a/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/Base.lproj/Main.storyboard b/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/Base.lproj/Main.storyboard
new file mode 100644
index 00000000..82cd159a
--- /dev/null
+++ b/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/Base.lproj/Main.storyboard
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15E65" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
+ <dependencies>
+ <deployment identifier="iOS"/>
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
+ </dependencies>
+ <scenes>
+ <!--View Controller-->
+ <scene sceneID="tne-QT-ifu">
+ <objects>
+ <viewController id="BYZ-38-t0r" customClass="ViewController" sceneMemberID="viewController">
+ <layoutGuides>
+ <viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
+ <viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
+ </layoutGuides>
+ <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
+ <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
+ </view>
+ </viewController>
+ <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
+ </objects>
+ </scene>
+ </scenes>
+</document>
diff --git a/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/Info.plist b/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/Info.plist
new file mode 100644
index 00000000..40c6215d
--- /dev/null
+++ b/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/Info.plist
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>en</string>
+ <key>CFBundleExecutable</key>
+ <string>$(EXECUTABLE_NAME)</string>
+ <key>CFBundleIdentifier</key>
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>$(PRODUCT_NAME)</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1</string>
+ <key>LSRequiresIPhoneOS</key>
+ <true/>
+ <key>UILaunchStoryboardName</key>
+ <string>LaunchScreen</string>
+ <key>UIMainStoryboardFile</key>
+ <string>Main</string>
+ <key>UIRequiredDeviceCapabilities</key>
+ <array>
+ <string>armv7</string>
+ </array>
+ <key>UISupportedInterfaceOrientations</key>
+ <array>
+ <string>UIInterfaceOrientationPortrait</string>
+ <string>UIInterfaceOrientationLandscapeLeft</string>
+ <string>UIInterfaceOrientationLandscapeRight</string>
+ </array>
+ <key>UISupportedInterfaceOrientations~ipad</key>
+ <array>
+ <string>UIInterfaceOrientationPortrait</string>
+ <string>UIInterfaceOrientationPortraitUpsideDown</string>
+ <string>UIInterfaceOrientationLandscapeLeft</string>
+ <string>UIInterfaceOrientationLandscapeRight</string>
+ </array>
+</dict>
+</plist>
diff --git a/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/ViewController.h b/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/ViewController.h
new file mode 100644
index 00000000..777257b8
--- /dev/null
+++ b/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/ViewController.h
@@ -0,0 +1,37 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2016 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.
+
+#import <UIKit/UIKit.h>
+
+@interface ViewController : UIViewController
+
+
+@end
+
diff --git a/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/ViewController.m b/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/ViewController.m
new file mode 100644
index 00000000..c3b7e6c0
--- /dev/null
+++ b/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/ViewController.m
@@ -0,0 +1,49 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2016 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.
+
+#import "ViewController.h"
+
+@interface ViewController ()
+
+@end
+
+@implementation ViewController
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+ // Do any additional setup after loading the view, typically from a nib.
+}
+
+- (void)didReceiveMemoryWarning {
+ [super didReceiveMemoryWarning];
+ // Dispose of any resources that can be recreated.
+}
+
+@end
diff --git a/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/main.m b/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/main.m
new file mode 100644
index 00000000..4df0b769
--- /dev/null
+++ b/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/iOSCocoaPodsTester/main.m
@@ -0,0 +1,39 @@
+//
+// Protocol Buffers - Google's data interchange format
+// Copyright 2016 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.
+
+#import <UIKit/UIKit.h>
+#import "AppDelegate.h"
+
+int main(int argc, char * argv[]) {
+ @autoreleasepool {
+ return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
+ }
+}
diff --git a/objectivec/Tests/CocoaPods/run_tests.sh b/objectivec/Tests/CocoaPods/run_tests.sh
new file mode 100755
index 00000000..6d3e12be
--- /dev/null
+++ b/objectivec/Tests/CocoaPods/run_tests.sh
@@ -0,0 +1,150 @@
+#!/bin/bash
+#
+# Helper to run the pods tests.
+
+set -eu
+
+readonly ScriptDir=$(dirname "$(echo $0 | sed -e "s,^\([^/]\),$(pwd)/\1,")")
+
+printUsage() {
+ NAME=$(basename "${0}")
+ cat << EOF
+usage: ${NAME} [OPTIONS]
+
+This script runs some test to check the CocoaPods integration.
+
+OPTIONS:
+
+ General:
+
+ -h, --help
+ Show this message
+ --skip-static
+ Skip the static based pods tests.
+ --skip-framework
+ Skip the framework based pods tests.
+ --skip-ios
+ Skip the iOS pods tests.
+ --skip-osx
+ Skip the OS X pods tests.
+
+EOF
+}
+
+TEST_MODES=( "static" "framework" )
+TEST_NAMES=( "iOSCocoaPodsTester" "OSXCocoaPodsTester" )
+while [[ $# != 0 ]]; do
+ case "${1}" in
+ -h | --help )
+ printUsage
+ exit 0
+ ;;
+ --skip-static )
+ TEST_MODES=(${TEST_MODES[@]/static})
+ ;;
+ --skip-framework )
+ TEST_MODES=(${TEST_MODES[@]/framework})
+ ;;
+ --skip-ios )
+ TEST_NAMES=(${TEST_NAMES[@]/iOSCocoaPodsTester})
+ ;;
+ --skip-osx )
+ TEST_NAMES=(${TEST_NAMES[@]/OSXCocoaPodsTester})
+ ;;
+ -*)
+ echo "ERROR: Unknown option: ${1}" 1>&2
+ printUsage
+ exit 1
+ ;;
+ *)
+ echo "ERROR: Unknown argument: ${1}" 1>&2
+ printUsage
+ exit 1
+ ;;
+ esac
+ shift
+done
+
+# Sanity check.
+if [[ "${#TEST_NAMES[@]}" == 0 ]] ; then
+ echo "ERROR: Need to run at least iOS or OS X tests." 1>&2
+ exit 2
+fi
+if [[ "${#TEST_MODES[@]}" == 0 ]] ; then
+ echo "ERROR: Need to run at least static or frameworks tests." 1>&2
+ exit 2
+fi
+
+header() {
+ echo ""
+ echo "========================================================================"
+ echo " ${@}"
+ echo "========================================================================"
+ echo ""
+}
+
+# Cleanup hook for do_test, assumes directory is correct.
+cleanup() {
+ local TEST_NAME="$1"
+
+ echo "Cleaning up..."
+
+ # Generally don't let things fail, and eat common stdout, but let stderr show
+ # incase 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.
+ pod cache clean --all || true
+ # Delete the files left after pod deintegrate.
+ rm -f Podfile.lock || true
+ rm -rf "${TEST_NAME}.xcworkspace" || true
+ git checkout -- "${TEST_NAME}.xcodeproj" || true
+ # Remove the Podfile that was put in place.
+ rm -f Podfile || true
+}
+
+do_test() {
+ local TEST_NAME="$1"
+ local TEST_MODE="$2"
+
+ header "${TEST_NAME}" - Mode: "${TEST_MODE}"
+ cd "${ScriptDir}/${TEST_NAME}"
+
+ # Hook in cleanup for any failures.
+ trap "cleanup ${TEST_NAME}" EXIT
+
+ # Ensure nothing is cached by pods to start with that could throw things off.
+ pod cache clean --all
+
+ # Put the right Podfile in place.
+ cp -f "Podfile-${TEST_MODE}" "Podfile"
+
+ xcodebuild_args=( "-workspace" "${TEST_NAME}.xcworkspace" "-scheme" "${TEST_NAME}" )
+
+ # For iOS, if the SDK is not provided it tries to use iphoneos, and the test
+ # fail on Travis since those machines don't have a Code Signing identity.
+ if [[ "${TEST_NAME}" == iOS* ]] ; then
+ # Apparently the destination flag is required to avoid "Unsupported architecture"
+ # errors.
+ xcodebuild_args+=(
+ -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO
+ -destination "platform=iOS Simulator,name=iPad 2,OS=9.3"
+ )
+ fi
+
+ # Do the work!
+ pod install --verbose
+
+ xcodebuild "${xcodebuild_args[@]}" build
+
+ # Clear the hook and manually run cleanup.
+ trap - EXIT
+ cleanup "${TEST_NAME}"
+}
+
+# Run the tests.
+for TEST_NAME in "${TEST_NAMES[@]}" ; do
+ for TEST_MODE in "${TEST_MODES[@]}" ; do
+ do_test "${TEST_NAME}" "${TEST_MODE}"
+ done
+done
diff --git a/objectivec/Tests/GPBARCUnittestProtos.m b/objectivec/Tests/GPBARCUnittestProtos.m
index d0408869..28d2396c 100644
--- a/objectivec/Tests/GPBARCUnittestProtos.m
+++ b/objectivec/Tests/GPBARCUnittestProtos.m
@@ -34,6 +34,11 @@
// Makes sure all the generated headers compile with ARC on.
+// The unittest_custom_options.proto extends the messages in descriptor.proto
+// so we build it in to test extending in general. The library doesn't provide
+// a descriptor as it doesn't use the classes/enums.
+#import "google/protobuf/Descriptor.pbobjc.h"
+
#import "google/protobuf/Unittest.pbobjc.h"
#import "google/protobuf/UnittestCustomOptions.pbobjc.h"
#import "google/protobuf/UnittestCycle.pbobjc.h"
diff --git a/objectivec/Tests/GPBCodedInputStreamTests.m b/objectivec/Tests/GPBCodedInputStreamTests.m
index 7c3c006b..cc402156 100644
--- a/objectivec/Tests/GPBCodedInputStreamTests.m
+++ b/objectivec/Tests/GPBCodedInputStreamTests.m
@@ -266,6 +266,9 @@
}
// Verifies fix for b/10315336.
+// Note: Now that there isn't a custom string class under the hood, this test
+// isn't as critical, but it does cover bad input and if a custom class is added
+// again, it will help validate that class' handing of bad utf8.
- (void)testReadMalformedString {
NSOutputStream* rawOutput = [NSOutputStream outputStreamToMemory];
GPBCodedOutputStream* output =
@@ -276,19 +279,57 @@
[output writeRawVarint32:tag];
[output writeRawVarint32:5];
// Create an invalid utf-8 byte array.
- uint8_t bytes[5] = {0xc2, 0xf2};
+ uint8_t bytes[] = {0xc2, 0xf2, 0x0, 0x0, 0x0};
[output writeRawData:[NSData dataWithBytes:bytes length:sizeof(bytes)]];
[output flush];
- NSData* data =
+ NSData *data =
[rawOutput propertyForKey:NSStreamDataWrittenToMemoryStreamKey];
GPBCodedInputStream* input = [GPBCodedInputStream streamWithData:data];
+ NSError *error = nil;
TestAllTypes* message = [TestAllTypes parseFromCodedInputStream:input
extensionRegistry:nil
- error:NULL];
- // Make sure we can read string properties twice without crashing.
- XCTAssertEqual([message.defaultString length], (NSUInteger)0);
- XCTAssertEqualObjects(@"", message.defaultString);
+ error:&error];
+ XCTAssertNotNil(error);
+ XCTAssertNil(message);
+}
+
+- (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
+ // used again.)
+ const char* strs[] = {
+ "\xEF\xBB\xBF String with BOM",
+ "String with \xEF\xBB\xBF in middle",
+ "String with end bom \xEF\xBB\xBF",
+ "\xEF\xBB\xBF\xe2\x99\xa1", // BOM White Heart
+ "\xEF\xBB\xBF\xEF\xBB\xBF String with Two BOM",
+ };
+ for (size_t i = 0; i < GPBARRAYSIZE(strs); ++i) {
+ NSOutputStream* rawOutput = [NSOutputStream outputStreamToMemory];
+ GPBCodedOutputStream* output =
+ [GPBCodedOutputStream streamWithOutputStream:rawOutput];
+
+ int32_t tag = GPBWireFormatMakeTag(TestAllTypes_FieldNumber_DefaultString,
+ GPBWireFormatLengthDelimited);
+ [output writeRawVarint32:tag];
+ size_t length = strlen(strs[i]);
+ [output writeRawVarint32:(int32_t)length];
+ [output writeRawData:[NSData dataWithBytes:strs[i] length:length]];
+ [output flush];
+
+ NSData* data =
+ [rawOutput propertyForKey:NSStreamDataWrittenToMemoryStreamKey];
+ GPBCodedInputStream* input = [GPBCodedInputStream streamWithData:data];
+ TestAllTypes* message = [TestAllTypes parseFromCodedInputStream:input
+ extensionRegistry:nil
+ error:NULL];
+ XCTAssertNotNil(message, @"Loop %zd", i);
+ // Ensure the string is there. NSString can consume the BOM in some
+ // cases, so don't actually check the string for exact equality.
+ XCTAssertTrue(message.defaultString.length > 0, @"Loop %zd", i);
+ }
}
@end
diff --git a/objectivec/Tests/GPBCodedOuputStreamTests.m b/objectivec/Tests/GPBCodedOuputStreamTests.m
index 77d88033..0723b645 100644
--- a/objectivec/Tests/GPBCodedOuputStreamTests.m
+++ b/objectivec/Tests/GPBCodedOuputStreamTests.m
@@ -30,11 +30,30 @@
#import "GPBTestUtilities.h"
-#import "GPBCodedOutputStream.h"
+#import "GPBCodedOutputStream_PackagePrivate.h"
#import "GPBCodedInputStream.h"
#import "GPBUtilities_PackagePrivate.h"
#import "google/protobuf/Unittest.pbobjc.h"
+@interface GPBCodedOutputStream (InternalMethods)
+// Declared in the .m file, expose for testing.
+- (instancetype)initWithOutputStream:(NSOutputStream *)output
+ data:(NSMutableData *)data;
+@end
+
+@interface GPBCodedOutputStream (Helper)
++ (instancetype)streamWithOutputStream:(NSOutputStream *)output
+ bufferSize:(size_t)bufferSize;
+@end
+
+@implementation GPBCodedOutputStream (Helper)
++ (instancetype)streamWithOutputStream:(NSOutputStream *)output
+ bufferSize:(size_t)bufferSize {
+ NSMutableData *data = [NSMutableData dataWithLength:bufferSize];
+ return [[[self alloc] initWithOutputStream:output data:data] autorelease];
+}
+@end
+
@interface CodedOutputStreamTests : GPBTestCase
@end
diff --git a/objectivec/Tests/GPBDescriptorTests.m b/objectivec/Tests/GPBDescriptorTests.m
index ccdbb645..74e3172b 100644
--- a/objectivec/Tests/GPBDescriptorTests.m
+++ b/objectivec/Tests/GPBDescriptorTests.m
@@ -125,6 +125,12 @@
[descriptor getValue:&value forEnumName:@"TestAllTypes_NestedEnum_Baz"]);
XCTAssertEqual(value, TestAllTypes_NestedEnum_Baz);
+ // TextFormat
+ enumName = [descriptor textFormatNameForValue:1];
+ XCTAssertNotNil(enumName);
+ XCTAssertTrue([descriptor getValue:&value forEnumTextFormatName:@"FOO"]);
+ XCTAssertEqual(value, TestAllTypes_NestedEnum_Foo);
+
// Bad values
enumName = [descriptor enumNameForValue:0];
XCTAssertNil(enumName);
@@ -134,6 +140,8 @@
forEnumName:@"TestAllTypes_NestedEnum_Unknown"]);
XCTAssertFalse([descriptor getValue:NULL
forEnumName:@"TestAllTypes_NestedEnum_Unknown"]);
+ XCTAssertFalse([descriptor getValue:NULL forEnumTextFormatName:@"Unknown"]);
+ XCTAssertFalse([descriptor getValue:&value forEnumTextFormatName:@"Unknown"]);
}
- (void)testEnumValueValidator {
@@ -153,19 +161,6 @@
XCTAssertFalse([fieldDescriptor isValidEnumValue:-2]);
}
-- (void)testEnumDescriptorLookup {
- GPBDescriptor *descriptor = [TestAllTypes descriptor];
- GPBEnumDescriptor *enumDescriptor =
- [descriptor enumWithName:@"TestAllTypes_NestedEnum"];
- XCTAssertNotNil(enumDescriptor);
-
- // Descriptor cannot find foreign or imported enums.
- enumDescriptor = [descriptor enumWithName:@"ForeignEnumEnum"];
- XCTAssertNil(enumDescriptor);
- enumDescriptor = [descriptor enumWithName:@"ImportEnumEnum"];
- XCTAssertNil(enumDescriptor);
-}
-
- (void)testOneofDescriptor {
GPBDescriptor *descriptor = [TestOneof2 descriptor];
diff --git a/objectivec/Tests/GPBDictionaryTests+Bool.m b/objectivec/Tests/GPBDictionaryTests+Bool.m
index 8b1900fe..0dbe07b6 100644
--- a/objectivec/Tests/GPBDictionaryTests+Bool.m
+++ b/objectivec/Tests/GPBDictionaryTests+Bool.m
@@ -54,8 +54,8 @@
GPBBoolUInt32Dictionary *dict = [[GPBBoolUInt32Dictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:YES value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(BOOL aKey, uint32_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getUInt32:NULL forKey:YES]);
+ [dict enumerateKeysAndUInt32sUsingBlock:^(BOOL aKey, uint32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -63,15 +63,15 @@
}
- (void)testOne {
- GPBBoolUInt32Dictionary *dict = [GPBBoolUInt32Dictionary dictionaryWithValue:100U forKey:YES];
+ GPBBoolUInt32Dictionary *dict = [GPBBoolUInt32Dictionary dictionaryWithUInt32:100U forKey:YES];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
uint32_t value;
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:YES]);
+ XCTAssertTrue([dict getUInt32:&value forKey:YES]);
XCTAssertEqual(value, 100U);
- XCTAssertFalse([dict valueForKey:NO value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(BOOL aKey, uint32_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getUInt32:NULL forKey:NO]);
+ [dict enumerateKeysAndUInt32sUsingBlock:^(BOOL aKey, uint32_t aValue, BOOL *stop) {
XCTAssertEqual(aKey, YES);
XCTAssertEqual(aValue, 100U);
XCTAssertNotEqual(stop, NULL);
@@ -82,23 +82,23 @@
const BOOL kKeys[] = { YES, NO };
const uint32_t kValues[] = { 100U, 101U };
GPBBoolUInt32Dictionary *dict =
- [[GPBBoolUInt32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBBoolUInt32Dictionary alloc] initWithUInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 2U);
uint32_t value;
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:YES]);
+ XCTAssertTrue([dict getUInt32:&value forKey:YES]);
XCTAssertEqual(value, 100U);
- XCTAssertTrue([dict valueForKey:NO value:NULL]);
- XCTAssertTrue([dict valueForKey:NO value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:NO]);
+ XCTAssertTrue([dict getUInt32:&value forKey:NO]);
XCTAssertEqual(value, 101U);
__block NSUInteger idx = 0;
BOOL *seenKeys = malloc(2 * sizeof(BOOL));
uint32_t *seenValues = malloc(2 * sizeof(uint32_t));
- [dict enumerateKeysAndValuesUsingBlock:^(BOOL aKey, uint32_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndUInt32sUsingBlock:^(BOOL aKey, uint32_t aValue, BOOL *stop) {
XCTAssertLessThan(idx, 2U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -120,7 +120,7 @@
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(BOOL aKey, uint32_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndUInt32sUsingBlock:^(BOOL aKey, uint32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 0) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -136,29 +136,29 @@
const uint32_t kValues2[] = { 101U, 100U };
const uint32_t kValues3[] = { 101U };
GPBBoolUInt32Dictionary *dict1 =
- [[GPBBoolUInt32Dictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBBoolUInt32Dictionary alloc] initWithUInt32s:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBBoolUInt32Dictionary *dict1prime =
- [[GPBBoolUInt32Dictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBBoolUInt32Dictionary alloc] initWithUInt32s:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBBoolUInt32Dictionary *dict2 =
- [[GPBBoolUInt32Dictionary alloc] initWithValues:kValues2
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBBoolUInt32Dictionary alloc] initWithUInt32s:kValues2
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBBoolUInt32Dictionary *dict3 =
- [[GPBBoolUInt32Dictionary alloc] initWithValues:kValues1
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBBoolUInt32Dictionary alloc] initWithUInt32s:kValues1
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBBoolUInt32Dictionary *dict4 =
- [[GPBBoolUInt32Dictionary alloc] initWithValues:kValues3
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues3)];
+ [[GPBBoolUInt32Dictionary alloc] initWithUInt32s:kValues3
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
// 1/1Prime should be different objects, but equal.
@@ -187,9 +187,9 @@
const BOOL kKeys[] = { YES, NO };
const uint32_t kValues[] = { 100U, 101U };
GPBBoolUInt32Dictionary *dict =
- [[GPBBoolUInt32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBBoolUInt32Dictionary alloc] initWithUInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBBoolUInt32Dictionary *dict2 = [dict copy];
@@ -208,9 +208,9 @@
const BOOL kKeys[] = { YES, NO };
const uint32_t kValues[] = { 100U, 101U };
GPBBoolUInt32Dictionary *dict =
- [[GPBBoolUInt32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBBoolUInt32Dictionary alloc] initWithUInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBBoolUInt32Dictionary *dict2 =
@@ -228,25 +228,25 @@
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:100U forKey:YES];
+ [dict setUInt32:100U forKey:YES];
XCTAssertEqual(dict.count, 1U);
const BOOL kKeys[] = { NO };
const uint32_t kValues[] = { 101U };
GPBBoolUInt32Dictionary *dict2 =
- [[GPBBoolUInt32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBBoolUInt32Dictionary alloc] initWithUInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 2U);
uint32_t value;
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:YES]);
+ XCTAssertTrue([dict getUInt32:&value forKey:YES]);
XCTAssertEqual(value, 100U);
- XCTAssertTrue([dict valueForKey:NO value:NULL]);
- XCTAssertTrue([dict valueForKey:NO value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:NO]);
+ XCTAssertTrue([dict getUInt32:&value forKey:NO]);
XCTAssertEqual(value, 101U);
[dict2 release];
}
@@ -255,32 +255,32 @@
const BOOL kKeys[] = { YES, NO};
const uint32_t kValues[] = { 100U, 101U };
GPBBoolUInt32Dictionary *dict =
- [[GPBBoolUInt32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBBoolUInt32Dictionary alloc] initWithUInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 2U);
- [dict removeValueForKey:NO];
+ [dict removeUInt32ForKey:NO];
XCTAssertEqual(dict.count, 1U);
uint32_t value;
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:YES]);
+ XCTAssertTrue([dict getUInt32:&value forKey:YES]);
XCTAssertEqual(value, 100U);
- XCTAssertFalse([dict valueForKey:NO value:NULL]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:NO]);
// Remove again does nothing.
- [dict removeValueForKey:NO];
+ [dict removeUInt32ForKey:NO];
XCTAssertEqual(dict.count, 1U);
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:YES]);
+ XCTAssertTrue([dict getUInt32:&value forKey:YES]);
XCTAssertEqual(value, 100U);
- XCTAssertFalse([dict valueForKey:NO value:NULL]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:NO]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:YES value:NULL]);
- XCTAssertFalse([dict valueForKey:NO value:NULL]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:YES]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:NO]);
[dict release];
}
@@ -288,51 +288,51 @@
const BOOL kKeys[] = { YES, NO };
const uint32_t kValues[] = { 100U, 101U };
GPBBoolUInt32Dictionary *dict =
- [[GPBBoolUInt32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBBoolUInt32Dictionary alloc] initWithUInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 2U);
uint32_t value;
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:YES]);
+ XCTAssertTrue([dict getUInt32:&value forKey:YES]);
XCTAssertEqual(value, 100U);
- XCTAssertTrue([dict valueForKey:NO value:NULL]);
- XCTAssertTrue([dict valueForKey:NO value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:NO]);
+ XCTAssertTrue([dict getUInt32:&value forKey:NO]);
XCTAssertEqual(value, 101U);
- [dict setValue:101U forKey:YES];
+ [dict setUInt32:101U forKey:YES];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:YES]);
+ XCTAssertTrue([dict getUInt32:&value forKey:YES]);
XCTAssertEqual(value, 101U);
- XCTAssertTrue([dict valueForKey:NO value:NULL]);
- XCTAssertTrue([dict valueForKey:NO value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:NO]);
+ XCTAssertTrue([dict getUInt32:&value forKey:NO]);
XCTAssertEqual(value, 101U);
- [dict setValue:100U forKey:NO];
+ [dict setUInt32:100U forKey:NO];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:YES]);
+ XCTAssertTrue([dict getUInt32:&value forKey:YES]);
XCTAssertEqual(value, 101U);
- XCTAssertTrue([dict valueForKey:NO value:NULL]);
- XCTAssertTrue([dict valueForKey:NO value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:NO]);
+ XCTAssertTrue([dict getUInt32:&value forKey:NO]);
XCTAssertEqual(value, 100U);
const BOOL kKeys2[] = { NO, YES };
const uint32_t kValues2[] = { 101U, 100U };
GPBBoolUInt32Dictionary *dict2 =
- [[GPBBoolUInt32Dictionary alloc] initWithValues:kValues2
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBBoolUInt32Dictionary alloc] initWithUInt32s:kValues2
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:YES]);
+ XCTAssertTrue([dict getUInt32:&value forKey:YES]);
XCTAssertEqual(value, 100U);
- XCTAssertTrue([dict valueForKey:NO value:NULL]);
- XCTAssertTrue([dict valueForKey:NO value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:NO]);
+ XCTAssertTrue([dict getUInt32:&value forKey:NO]);
XCTAssertEqual(value, 101U);
[dict2 release];
@@ -355,8 +355,8 @@
GPBBoolInt32Dictionary *dict = [[GPBBoolInt32Dictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:YES value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(BOOL aKey, int32_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getInt32:NULL forKey:YES]);
+ [dict enumerateKeysAndInt32sUsingBlock:^(BOOL aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -364,15 +364,15 @@
}
- (void)testOne {
- GPBBoolInt32Dictionary *dict = [GPBBoolInt32Dictionary dictionaryWithValue:200 forKey:YES];
+ GPBBoolInt32Dictionary *dict = [GPBBoolInt32Dictionary dictionaryWithInt32:200 forKey:YES];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
int32_t value;
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:YES]);
+ XCTAssertTrue([dict getInt32:&value forKey:YES]);
XCTAssertEqual(value, 200);
- XCTAssertFalse([dict valueForKey:NO value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(BOOL aKey, int32_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getInt32:NULL forKey:NO]);
+ [dict enumerateKeysAndInt32sUsingBlock:^(BOOL aKey, int32_t aValue, BOOL *stop) {
XCTAssertEqual(aKey, YES);
XCTAssertEqual(aValue, 200);
XCTAssertNotEqual(stop, NULL);
@@ -383,23 +383,23 @@
const BOOL kKeys[] = { YES, NO };
const int32_t kValues[] = { 200, 201 };
GPBBoolInt32Dictionary *dict =
- [[GPBBoolInt32Dictionary alloc] initWithValues:kValues
+ [[GPBBoolInt32Dictionary alloc] initWithInt32s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 2U);
int32_t value;
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:YES]);
+ XCTAssertTrue([dict getInt32:&value forKey:YES]);
XCTAssertEqual(value, 200);
- XCTAssertTrue([dict valueForKey:NO value:NULL]);
- XCTAssertTrue([dict valueForKey:NO value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:NO]);
+ XCTAssertTrue([dict getInt32:&value forKey:NO]);
XCTAssertEqual(value, 201);
__block NSUInteger idx = 0;
BOOL *seenKeys = malloc(2 * sizeof(BOOL));
int32_t *seenValues = malloc(2 * sizeof(int32_t));
- [dict enumerateKeysAndValuesUsingBlock:^(BOOL aKey, int32_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndInt32sUsingBlock:^(BOOL aKey, int32_t aValue, BOOL *stop) {
XCTAssertLessThan(idx, 2U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -421,7 +421,7 @@
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(BOOL aKey, int32_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndInt32sUsingBlock:^(BOOL aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 0) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -437,27 +437,27 @@
const int32_t kValues2[] = { 201, 200 };
const int32_t kValues3[] = { 201 };
GPBBoolInt32Dictionary *dict1 =
- [[GPBBoolInt32Dictionary alloc] initWithValues:kValues1
+ [[GPBBoolInt32Dictionary alloc] initWithInt32s:kValues1
forKeys:kKeys1
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBBoolInt32Dictionary *dict1prime =
- [[GPBBoolInt32Dictionary alloc] initWithValues:kValues1
+ [[GPBBoolInt32Dictionary alloc] initWithInt32s:kValues1
forKeys:kKeys1
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBBoolInt32Dictionary *dict2 =
- [[GPBBoolInt32Dictionary alloc] initWithValues:kValues2
+ [[GPBBoolInt32Dictionary alloc] initWithInt32s:kValues2
forKeys:kKeys1
count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBBoolInt32Dictionary *dict3 =
- [[GPBBoolInt32Dictionary alloc] initWithValues:kValues1
+ [[GPBBoolInt32Dictionary alloc] initWithInt32s:kValues1
forKeys:kKeys2
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBBoolInt32Dictionary *dict4 =
- [[GPBBoolInt32Dictionary alloc] initWithValues:kValues3
+ [[GPBBoolInt32Dictionary alloc] initWithInt32s:kValues3
forKeys:kKeys1
count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
@@ -488,7 +488,7 @@
const BOOL kKeys[] = { YES, NO };
const int32_t kValues[] = { 200, 201 };
GPBBoolInt32Dictionary *dict =
- [[GPBBoolInt32Dictionary alloc] initWithValues:kValues
+ [[GPBBoolInt32Dictionary alloc] initWithInt32s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
@@ -509,7 +509,7 @@
const BOOL kKeys[] = { YES, NO };
const int32_t kValues[] = { 200, 201 };
GPBBoolInt32Dictionary *dict =
- [[GPBBoolInt32Dictionary alloc] initWithValues:kValues
+ [[GPBBoolInt32Dictionary alloc] initWithInt32s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
@@ -529,13 +529,13 @@
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:200 forKey:YES];
+ [dict setInt32:200 forKey:YES];
XCTAssertEqual(dict.count, 1U);
const BOOL kKeys[] = { NO };
const int32_t kValues[] = { 201 };
GPBBoolInt32Dictionary *dict2 =
- [[GPBBoolInt32Dictionary alloc] initWithValues:kValues
+ [[GPBBoolInt32Dictionary alloc] initWithInt32s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
@@ -543,11 +543,11 @@
XCTAssertEqual(dict.count, 2U);
int32_t value;
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:YES]);
+ XCTAssertTrue([dict getInt32:&value forKey:YES]);
XCTAssertEqual(value, 200);
- XCTAssertTrue([dict valueForKey:NO value:NULL]);
- XCTAssertTrue([dict valueForKey:NO value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:NO]);
+ XCTAssertTrue([dict getInt32:&value forKey:NO]);
XCTAssertEqual(value, 201);
[dict2 release];
}
@@ -556,32 +556,32 @@
const BOOL kKeys[] = { YES, NO};
const int32_t kValues[] = { 200, 201 };
GPBBoolInt32Dictionary *dict =
- [[GPBBoolInt32Dictionary alloc] initWithValues:kValues
+ [[GPBBoolInt32Dictionary alloc] initWithInt32s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 2U);
- [dict removeValueForKey:NO];
+ [dict removeInt32ForKey:NO];
XCTAssertEqual(dict.count, 1U);
int32_t value;
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:YES]);
+ XCTAssertTrue([dict getInt32:&value forKey:YES]);
XCTAssertEqual(value, 200);
- XCTAssertFalse([dict valueForKey:NO value:NULL]);
+ XCTAssertFalse([dict getInt32:NULL forKey:NO]);
// Remove again does nothing.
- [dict removeValueForKey:NO];
+ [dict removeInt32ForKey:NO];
XCTAssertEqual(dict.count, 1U);
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:YES]);
+ XCTAssertTrue([dict getInt32:&value forKey:YES]);
XCTAssertEqual(value, 200);
- XCTAssertFalse([dict valueForKey:NO value:NULL]);
+ XCTAssertFalse([dict getInt32:NULL forKey:NO]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:YES value:NULL]);
- XCTAssertFalse([dict valueForKey:NO value:NULL]);
+ XCTAssertFalse([dict getInt32:NULL forKey:YES]);
+ XCTAssertFalse([dict getInt32:NULL forKey:NO]);
[dict release];
}
@@ -589,51 +589,51 @@
const BOOL kKeys[] = { YES, NO };
const int32_t kValues[] = { 200, 201 };
GPBBoolInt32Dictionary *dict =
- [[GPBBoolInt32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBBoolInt32Dictionary alloc] initWithInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 2U);
int32_t value;
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:YES]);
+ XCTAssertTrue([dict getInt32:&value forKey:YES]);
XCTAssertEqual(value, 200);
- XCTAssertTrue([dict valueForKey:NO value:NULL]);
- XCTAssertTrue([dict valueForKey:NO value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:NO]);
+ XCTAssertTrue([dict getInt32:&value forKey:NO]);
XCTAssertEqual(value, 201);
- [dict setValue:201 forKey:YES];
+ [dict setInt32:201 forKey:YES];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:YES]);
+ XCTAssertTrue([dict getInt32:&value forKey:YES]);
XCTAssertEqual(value, 201);
- XCTAssertTrue([dict valueForKey:NO value:NULL]);
- XCTAssertTrue([dict valueForKey:NO value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:NO]);
+ XCTAssertTrue([dict getInt32:&value forKey:NO]);
XCTAssertEqual(value, 201);
- [dict setValue:200 forKey:NO];
+ [dict setInt32:200 forKey:NO];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:YES]);
+ XCTAssertTrue([dict getInt32:&value forKey:YES]);
XCTAssertEqual(value, 201);
- XCTAssertTrue([dict valueForKey:NO value:NULL]);
- XCTAssertTrue([dict valueForKey:NO value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:NO]);
+ XCTAssertTrue([dict getInt32:&value forKey:NO]);
XCTAssertEqual(value, 200);
const BOOL kKeys2[] = { NO, YES };
const int32_t kValues2[] = { 201, 200 };
GPBBoolInt32Dictionary *dict2 =
- [[GPBBoolInt32Dictionary alloc] initWithValues:kValues2
+ [[GPBBoolInt32Dictionary alloc] initWithInt32s:kValues2
forKeys:kKeys2
count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:YES]);
+ XCTAssertTrue([dict getInt32:&value forKey:YES]);
XCTAssertEqual(value, 200);
- XCTAssertTrue([dict valueForKey:NO value:NULL]);
- XCTAssertTrue([dict valueForKey:NO value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:NO]);
+ XCTAssertTrue([dict getInt32:&value forKey:NO]);
XCTAssertEqual(value, 201);
[dict2 release];
@@ -656,8 +656,8 @@
GPBBoolUInt64Dictionary *dict = [[GPBBoolUInt64Dictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:YES value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(BOOL aKey, uint64_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getUInt64:NULL forKey:YES]);
+ [dict enumerateKeysAndUInt64sUsingBlock:^(BOOL aKey, uint64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -665,15 +665,15 @@
}
- (void)testOne {
- GPBBoolUInt64Dictionary *dict = [GPBBoolUInt64Dictionary dictionaryWithValue:300U forKey:YES];
+ GPBBoolUInt64Dictionary *dict = [GPBBoolUInt64Dictionary dictionaryWithUInt64:300U forKey:YES];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
uint64_t value;
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:YES]);
+ XCTAssertTrue([dict getUInt64:&value forKey:YES]);
XCTAssertEqual(value, 300U);
- XCTAssertFalse([dict valueForKey:NO value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(BOOL aKey, uint64_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getUInt64:NULL forKey:NO]);
+ [dict enumerateKeysAndUInt64sUsingBlock:^(BOOL aKey, uint64_t aValue, BOOL *stop) {
XCTAssertEqual(aKey, YES);
XCTAssertEqual(aValue, 300U);
XCTAssertNotEqual(stop, NULL);
@@ -684,23 +684,23 @@
const BOOL kKeys[] = { YES, NO };
const uint64_t kValues[] = { 300U, 301U };
GPBBoolUInt64Dictionary *dict =
- [[GPBBoolUInt64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBBoolUInt64Dictionary alloc] initWithUInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 2U);
uint64_t value;
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:YES]);
+ XCTAssertTrue([dict getUInt64:&value forKey:YES]);
XCTAssertEqual(value, 300U);
- XCTAssertTrue([dict valueForKey:NO value:NULL]);
- XCTAssertTrue([dict valueForKey:NO value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:NO]);
+ XCTAssertTrue([dict getUInt64:&value forKey:NO]);
XCTAssertEqual(value, 301U);
__block NSUInteger idx = 0;
BOOL *seenKeys = malloc(2 * sizeof(BOOL));
uint64_t *seenValues = malloc(2 * sizeof(uint64_t));
- [dict enumerateKeysAndValuesUsingBlock:^(BOOL aKey, uint64_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndUInt64sUsingBlock:^(BOOL aKey, uint64_t aValue, BOOL *stop) {
XCTAssertLessThan(idx, 2U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -722,7 +722,7 @@
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(BOOL aKey, uint64_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndUInt64sUsingBlock:^(BOOL aKey, uint64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 0) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -738,29 +738,29 @@
const uint64_t kValues2[] = { 301U, 300U };
const uint64_t kValues3[] = { 301U };
GPBBoolUInt64Dictionary *dict1 =
- [[GPBBoolUInt64Dictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBBoolUInt64Dictionary alloc] initWithUInt64s:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBBoolUInt64Dictionary *dict1prime =
- [[GPBBoolUInt64Dictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBBoolUInt64Dictionary alloc] initWithUInt64s:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBBoolUInt64Dictionary *dict2 =
- [[GPBBoolUInt64Dictionary alloc] initWithValues:kValues2
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBBoolUInt64Dictionary alloc] initWithUInt64s:kValues2
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBBoolUInt64Dictionary *dict3 =
- [[GPBBoolUInt64Dictionary alloc] initWithValues:kValues1
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBBoolUInt64Dictionary alloc] initWithUInt64s:kValues1
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBBoolUInt64Dictionary *dict4 =
- [[GPBBoolUInt64Dictionary alloc] initWithValues:kValues3
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues3)];
+ [[GPBBoolUInt64Dictionary alloc] initWithUInt64s:kValues3
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
// 1/1Prime should be different objects, but equal.
@@ -789,9 +789,9 @@
const BOOL kKeys[] = { YES, NO };
const uint64_t kValues[] = { 300U, 301U };
GPBBoolUInt64Dictionary *dict =
- [[GPBBoolUInt64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBBoolUInt64Dictionary alloc] initWithUInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBBoolUInt64Dictionary *dict2 = [dict copy];
@@ -810,9 +810,9 @@
const BOOL kKeys[] = { YES, NO };
const uint64_t kValues[] = { 300U, 301U };
GPBBoolUInt64Dictionary *dict =
- [[GPBBoolUInt64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBBoolUInt64Dictionary alloc] initWithUInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBBoolUInt64Dictionary *dict2 =
@@ -830,25 +830,25 @@
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:300U forKey:YES];
+ [dict setUInt64:300U forKey:YES];
XCTAssertEqual(dict.count, 1U);
const BOOL kKeys[] = { NO };
const uint64_t kValues[] = { 301U };
GPBBoolUInt64Dictionary *dict2 =
- [[GPBBoolUInt64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBBoolUInt64Dictionary alloc] initWithUInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 2U);
uint64_t value;
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:YES]);
+ XCTAssertTrue([dict getUInt64:&value forKey:YES]);
XCTAssertEqual(value, 300U);
- XCTAssertTrue([dict valueForKey:NO value:NULL]);
- XCTAssertTrue([dict valueForKey:NO value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:NO]);
+ XCTAssertTrue([dict getUInt64:&value forKey:NO]);
XCTAssertEqual(value, 301U);
[dict2 release];
}
@@ -857,32 +857,32 @@
const BOOL kKeys[] = { YES, NO};
const uint64_t kValues[] = { 300U, 301U };
GPBBoolUInt64Dictionary *dict =
- [[GPBBoolUInt64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBBoolUInt64Dictionary alloc] initWithUInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 2U);
- [dict removeValueForKey:NO];
+ [dict removeUInt64ForKey:NO];
XCTAssertEqual(dict.count, 1U);
uint64_t value;
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:YES]);
+ XCTAssertTrue([dict getUInt64:&value forKey:YES]);
XCTAssertEqual(value, 300U);
- XCTAssertFalse([dict valueForKey:NO value:NULL]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:NO]);
// Remove again does nothing.
- [dict removeValueForKey:NO];
+ [dict removeUInt64ForKey:NO];
XCTAssertEqual(dict.count, 1U);
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:YES]);
+ XCTAssertTrue([dict getUInt64:&value forKey:YES]);
XCTAssertEqual(value, 300U);
- XCTAssertFalse([dict valueForKey:NO value:NULL]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:NO]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:YES value:NULL]);
- XCTAssertFalse([dict valueForKey:NO value:NULL]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:YES]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:NO]);
[dict release];
}
@@ -890,51 +890,51 @@
const BOOL kKeys[] = { YES, NO };
const uint64_t kValues[] = { 300U, 301U };
GPBBoolUInt64Dictionary *dict =
- [[GPBBoolUInt64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBBoolUInt64Dictionary alloc] initWithUInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 2U);
uint64_t value;
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:YES]);
+ XCTAssertTrue([dict getUInt64:&value forKey:YES]);
XCTAssertEqual(value, 300U);
- XCTAssertTrue([dict valueForKey:NO value:NULL]);
- XCTAssertTrue([dict valueForKey:NO value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:NO]);
+ XCTAssertTrue([dict getUInt64:&value forKey:NO]);
XCTAssertEqual(value, 301U);
- [dict setValue:301U forKey:YES];
+ [dict setUInt64:301U forKey:YES];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:YES]);
+ XCTAssertTrue([dict getUInt64:&value forKey:YES]);
XCTAssertEqual(value, 301U);
- XCTAssertTrue([dict valueForKey:NO value:NULL]);
- XCTAssertTrue([dict valueForKey:NO value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:NO]);
+ XCTAssertTrue([dict getUInt64:&value forKey:NO]);
XCTAssertEqual(value, 301U);
- [dict setValue:300U forKey:NO];
+ [dict setUInt64:300U forKey:NO];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:YES]);
+ XCTAssertTrue([dict getUInt64:&value forKey:YES]);
XCTAssertEqual(value, 301U);
- XCTAssertTrue([dict valueForKey:NO value:NULL]);
- XCTAssertTrue([dict valueForKey:NO value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:NO]);
+ XCTAssertTrue([dict getUInt64:&value forKey:NO]);
XCTAssertEqual(value, 300U);
const BOOL kKeys2[] = { NO, YES };
const uint64_t kValues2[] = { 301U, 300U };
GPBBoolUInt64Dictionary *dict2 =
- [[GPBBoolUInt64Dictionary alloc] initWithValues:kValues2
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBBoolUInt64Dictionary alloc] initWithUInt64s:kValues2
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:YES]);
+ XCTAssertTrue([dict getUInt64:&value forKey:YES]);
XCTAssertEqual(value, 300U);
- XCTAssertTrue([dict valueForKey:NO value:NULL]);
- XCTAssertTrue([dict valueForKey:NO value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:NO]);
+ XCTAssertTrue([dict getUInt64:&value forKey:NO]);
XCTAssertEqual(value, 301U);
[dict2 release];
@@ -957,8 +957,8 @@
GPBBoolInt64Dictionary *dict = [[GPBBoolInt64Dictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:YES value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(BOOL aKey, int64_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getInt64:NULL forKey:YES]);
+ [dict enumerateKeysAndInt64sUsingBlock:^(BOOL aKey, int64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -966,15 +966,15 @@
}
- (void)testOne {
- GPBBoolInt64Dictionary *dict = [GPBBoolInt64Dictionary dictionaryWithValue:400 forKey:YES];
+ GPBBoolInt64Dictionary *dict = [GPBBoolInt64Dictionary dictionaryWithInt64:400 forKey:YES];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
int64_t value;
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:YES]);
+ XCTAssertTrue([dict getInt64:&value forKey:YES]);
XCTAssertEqual(value, 400);
- XCTAssertFalse([dict valueForKey:NO value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(BOOL aKey, int64_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getInt64:NULL forKey:NO]);
+ [dict enumerateKeysAndInt64sUsingBlock:^(BOOL aKey, int64_t aValue, BOOL *stop) {
XCTAssertEqual(aKey, YES);
XCTAssertEqual(aValue, 400);
XCTAssertNotEqual(stop, NULL);
@@ -985,23 +985,23 @@
const BOOL kKeys[] = { YES, NO };
const int64_t kValues[] = { 400, 401 };
GPBBoolInt64Dictionary *dict =
- [[GPBBoolInt64Dictionary alloc] initWithValues:kValues
+ [[GPBBoolInt64Dictionary alloc] initWithInt64s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 2U);
int64_t value;
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:YES]);
+ XCTAssertTrue([dict getInt64:&value forKey:YES]);
XCTAssertEqual(value, 400);
- XCTAssertTrue([dict valueForKey:NO value:NULL]);
- XCTAssertTrue([dict valueForKey:NO value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:NO]);
+ XCTAssertTrue([dict getInt64:&value forKey:NO]);
XCTAssertEqual(value, 401);
__block NSUInteger idx = 0;
BOOL *seenKeys = malloc(2 * sizeof(BOOL));
int64_t *seenValues = malloc(2 * sizeof(int64_t));
- [dict enumerateKeysAndValuesUsingBlock:^(BOOL aKey, int64_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndInt64sUsingBlock:^(BOOL aKey, int64_t aValue, BOOL *stop) {
XCTAssertLessThan(idx, 2U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -1023,7 +1023,7 @@
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(BOOL aKey, int64_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndInt64sUsingBlock:^(BOOL aKey, int64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 0) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -1039,27 +1039,27 @@
const int64_t kValues2[] = { 401, 400 };
const int64_t kValues3[] = { 401 };
GPBBoolInt64Dictionary *dict1 =
- [[GPBBoolInt64Dictionary alloc] initWithValues:kValues1
+ [[GPBBoolInt64Dictionary alloc] initWithInt64s:kValues1
forKeys:kKeys1
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBBoolInt64Dictionary *dict1prime =
- [[GPBBoolInt64Dictionary alloc] initWithValues:kValues1
+ [[GPBBoolInt64Dictionary alloc] initWithInt64s:kValues1
forKeys:kKeys1
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBBoolInt64Dictionary *dict2 =
- [[GPBBoolInt64Dictionary alloc] initWithValues:kValues2
+ [[GPBBoolInt64Dictionary alloc] initWithInt64s:kValues2
forKeys:kKeys1
count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBBoolInt64Dictionary *dict3 =
- [[GPBBoolInt64Dictionary alloc] initWithValues:kValues1
+ [[GPBBoolInt64Dictionary alloc] initWithInt64s:kValues1
forKeys:kKeys2
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBBoolInt64Dictionary *dict4 =
- [[GPBBoolInt64Dictionary alloc] initWithValues:kValues3
+ [[GPBBoolInt64Dictionary alloc] initWithInt64s:kValues3
forKeys:kKeys1
count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
@@ -1090,7 +1090,7 @@
const BOOL kKeys[] = { YES, NO };
const int64_t kValues[] = { 400, 401 };
GPBBoolInt64Dictionary *dict =
- [[GPBBoolInt64Dictionary alloc] initWithValues:kValues
+ [[GPBBoolInt64Dictionary alloc] initWithInt64s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
@@ -1111,7 +1111,7 @@
const BOOL kKeys[] = { YES, NO };
const int64_t kValues[] = { 400, 401 };
GPBBoolInt64Dictionary *dict =
- [[GPBBoolInt64Dictionary alloc] initWithValues:kValues
+ [[GPBBoolInt64Dictionary alloc] initWithInt64s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
@@ -1131,13 +1131,13 @@
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:400 forKey:YES];
+ [dict setInt64:400 forKey:YES];
XCTAssertEqual(dict.count, 1U);
const BOOL kKeys[] = { NO };
const int64_t kValues[] = { 401 };
GPBBoolInt64Dictionary *dict2 =
- [[GPBBoolInt64Dictionary alloc] initWithValues:kValues
+ [[GPBBoolInt64Dictionary alloc] initWithInt64s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
@@ -1145,11 +1145,11 @@
XCTAssertEqual(dict.count, 2U);
int64_t value;
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:YES]);
+ XCTAssertTrue([dict getInt64:&value forKey:YES]);
XCTAssertEqual(value, 400);
- XCTAssertTrue([dict valueForKey:NO value:NULL]);
- XCTAssertTrue([dict valueForKey:NO value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:NO]);
+ XCTAssertTrue([dict getInt64:&value forKey:NO]);
XCTAssertEqual(value, 401);
[dict2 release];
}
@@ -1158,32 +1158,32 @@
const BOOL kKeys[] = { YES, NO};
const int64_t kValues[] = { 400, 401 };
GPBBoolInt64Dictionary *dict =
- [[GPBBoolInt64Dictionary alloc] initWithValues:kValues
+ [[GPBBoolInt64Dictionary alloc] initWithInt64s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 2U);
- [dict removeValueForKey:NO];
+ [dict removeInt64ForKey:NO];
XCTAssertEqual(dict.count, 1U);
int64_t value;
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:YES]);
+ XCTAssertTrue([dict getInt64:&value forKey:YES]);
XCTAssertEqual(value, 400);
- XCTAssertFalse([dict valueForKey:NO value:NULL]);
+ XCTAssertFalse([dict getInt64:NULL forKey:NO]);
// Remove again does nothing.
- [dict removeValueForKey:NO];
+ [dict removeInt64ForKey:NO];
XCTAssertEqual(dict.count, 1U);
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:YES]);
+ XCTAssertTrue([dict getInt64:&value forKey:YES]);
XCTAssertEqual(value, 400);
- XCTAssertFalse([dict valueForKey:NO value:NULL]);
+ XCTAssertFalse([dict getInt64:NULL forKey:NO]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:YES value:NULL]);
- XCTAssertFalse([dict valueForKey:NO value:NULL]);
+ XCTAssertFalse([dict getInt64:NULL forKey:YES]);
+ XCTAssertFalse([dict getInt64:NULL forKey:NO]);
[dict release];
}
@@ -1191,51 +1191,51 @@
const BOOL kKeys[] = { YES, NO };
const int64_t kValues[] = { 400, 401 };
GPBBoolInt64Dictionary *dict =
- [[GPBBoolInt64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBBoolInt64Dictionary alloc] initWithInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 2U);
int64_t value;
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:YES]);
+ XCTAssertTrue([dict getInt64:&value forKey:YES]);
XCTAssertEqual(value, 400);
- XCTAssertTrue([dict valueForKey:NO value:NULL]);
- XCTAssertTrue([dict valueForKey:NO value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:NO]);
+ XCTAssertTrue([dict getInt64:&value forKey:NO]);
XCTAssertEqual(value, 401);
- [dict setValue:401 forKey:YES];
+ [dict setInt64:401 forKey:YES];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:YES]);
+ XCTAssertTrue([dict getInt64:&value forKey:YES]);
XCTAssertEqual(value, 401);
- XCTAssertTrue([dict valueForKey:NO value:NULL]);
- XCTAssertTrue([dict valueForKey:NO value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:NO]);
+ XCTAssertTrue([dict getInt64:&value forKey:NO]);
XCTAssertEqual(value, 401);
- [dict setValue:400 forKey:NO];
+ [dict setInt64:400 forKey:NO];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:YES]);
+ XCTAssertTrue([dict getInt64:&value forKey:YES]);
XCTAssertEqual(value, 401);
- XCTAssertTrue([dict valueForKey:NO value:NULL]);
- XCTAssertTrue([dict valueForKey:NO value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:NO]);
+ XCTAssertTrue([dict getInt64:&value forKey:NO]);
XCTAssertEqual(value, 400);
const BOOL kKeys2[] = { NO, YES };
const int64_t kValues2[] = { 401, 400 };
GPBBoolInt64Dictionary *dict2 =
- [[GPBBoolInt64Dictionary alloc] initWithValues:kValues2
+ [[GPBBoolInt64Dictionary alloc] initWithInt64s:kValues2
forKeys:kKeys2
count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:YES]);
+ XCTAssertTrue([dict getInt64:&value forKey:YES]);
XCTAssertEqual(value, 400);
- XCTAssertTrue([dict valueForKey:NO value:NULL]);
- XCTAssertTrue([dict valueForKey:NO value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:NO]);
+ XCTAssertTrue([dict getInt64:&value forKey:NO]);
XCTAssertEqual(value, 401);
[dict2 release];
@@ -1258,8 +1258,8 @@
GPBBoolBoolDictionary *dict = [[GPBBoolBoolDictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:YES value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(BOOL aKey, BOOL aValue, BOOL *stop) {
+ XCTAssertFalse([dict getBool:NULL forKey:YES]);
+ [dict enumerateKeysAndBoolsUsingBlock:^(BOOL aKey, BOOL aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -1267,15 +1267,15 @@
}
- (void)testOne {
- GPBBoolBoolDictionary *dict = [GPBBoolBoolDictionary dictionaryWithValue:NO forKey:YES];
+ GPBBoolBoolDictionary *dict = [GPBBoolBoolDictionary dictionaryWithBool:NO forKey:YES];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
BOOL value;
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:YES]);
+ XCTAssertTrue([dict getBool:&value forKey:YES]);
XCTAssertEqual(value, NO);
- XCTAssertFalse([dict valueForKey:NO value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(BOOL aKey, BOOL aValue, BOOL *stop) {
+ XCTAssertFalse([dict getBool:NULL forKey:NO]);
+ [dict enumerateKeysAndBoolsUsingBlock:^(BOOL aKey, BOOL aValue, BOOL *stop) {
XCTAssertEqual(aKey, YES);
XCTAssertEqual(aValue, NO);
XCTAssertNotEqual(stop, NULL);
@@ -1286,23 +1286,23 @@
const BOOL kKeys[] = { YES, NO };
const BOOL kValues[] = { NO, YES };
GPBBoolBoolDictionary *dict =
- [[GPBBoolBoolDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBBoolBoolDictionary alloc] initWithBools:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 2U);
BOOL value;
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:YES]);
+ XCTAssertTrue([dict getBool:&value forKey:YES]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:NO value:NULL]);
- XCTAssertTrue([dict valueForKey:NO value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:NO]);
+ XCTAssertTrue([dict getBool:&value forKey:NO]);
XCTAssertEqual(value, YES);
__block NSUInteger idx = 0;
BOOL *seenKeys = malloc(2 * sizeof(BOOL));
BOOL *seenValues = malloc(2 * sizeof(BOOL));
- [dict enumerateKeysAndValuesUsingBlock:^(BOOL aKey, BOOL aValue, BOOL *stop) {
+ [dict enumerateKeysAndBoolsUsingBlock:^(BOOL aKey, BOOL aValue, BOOL *stop) {
XCTAssertLessThan(idx, 2U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -1324,7 +1324,7 @@
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(BOOL aKey, BOOL aValue, BOOL *stop) {
+ [dict enumerateKeysAndBoolsUsingBlock:^(BOOL aKey, BOOL aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 0) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -1340,29 +1340,29 @@
const BOOL kValues2[] = { YES, NO };
const BOOL kValues3[] = { YES };
GPBBoolBoolDictionary *dict1 =
- [[GPBBoolBoolDictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBBoolBoolDictionary alloc] initWithBools:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBBoolBoolDictionary *dict1prime =
- [[GPBBoolBoolDictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBBoolBoolDictionary alloc] initWithBools:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBBoolBoolDictionary *dict2 =
- [[GPBBoolBoolDictionary alloc] initWithValues:kValues2
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBBoolBoolDictionary alloc] initWithBools:kValues2
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBBoolBoolDictionary *dict3 =
- [[GPBBoolBoolDictionary alloc] initWithValues:kValues1
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBBoolBoolDictionary alloc] initWithBools:kValues1
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBBoolBoolDictionary *dict4 =
- [[GPBBoolBoolDictionary alloc] initWithValues:kValues3
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues3)];
+ [[GPBBoolBoolDictionary alloc] initWithBools:kValues3
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
// 1/1Prime should be different objects, but equal.
@@ -1391,9 +1391,9 @@
const BOOL kKeys[] = { YES, NO };
const BOOL kValues[] = { NO, YES };
GPBBoolBoolDictionary *dict =
- [[GPBBoolBoolDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBBoolBoolDictionary alloc] initWithBools:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBBoolBoolDictionary *dict2 = [dict copy];
@@ -1412,9 +1412,9 @@
const BOOL kKeys[] = { YES, NO };
const BOOL kValues[] = { NO, YES };
GPBBoolBoolDictionary *dict =
- [[GPBBoolBoolDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBBoolBoolDictionary alloc] initWithBools:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBBoolBoolDictionary *dict2 =
@@ -1432,25 +1432,25 @@
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:NO forKey:YES];
+ [dict setBool:NO forKey:YES];
XCTAssertEqual(dict.count, 1U);
const BOOL kKeys[] = { NO };
const BOOL kValues[] = { YES };
GPBBoolBoolDictionary *dict2 =
- [[GPBBoolBoolDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBBoolBoolDictionary alloc] initWithBools:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 2U);
BOOL value;
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:YES]);
+ XCTAssertTrue([dict getBool:&value forKey:YES]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:NO value:NULL]);
- XCTAssertTrue([dict valueForKey:NO value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:NO]);
+ XCTAssertTrue([dict getBool:&value forKey:NO]);
XCTAssertEqual(value, YES);
[dict2 release];
}
@@ -1459,32 +1459,32 @@
const BOOL kKeys[] = { YES, NO};
const BOOL kValues[] = { NO, YES };
GPBBoolBoolDictionary *dict =
- [[GPBBoolBoolDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBBoolBoolDictionary alloc] initWithBools:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 2U);
- [dict removeValueForKey:NO];
+ [dict removeBoolForKey:NO];
XCTAssertEqual(dict.count, 1U);
BOOL value;
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:YES]);
+ XCTAssertTrue([dict getBool:&value forKey:YES]);
XCTAssertEqual(value, NO);
- XCTAssertFalse([dict valueForKey:NO value:NULL]);
+ XCTAssertFalse([dict getBool:NULL forKey:NO]);
// Remove again does nothing.
- [dict removeValueForKey:NO];
+ [dict removeBoolForKey:NO];
XCTAssertEqual(dict.count, 1U);
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:YES]);
+ XCTAssertTrue([dict getBool:&value forKey:YES]);
XCTAssertEqual(value, NO);
- XCTAssertFalse([dict valueForKey:NO value:NULL]);
+ XCTAssertFalse([dict getBool:NULL forKey:NO]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:YES value:NULL]);
- XCTAssertFalse([dict valueForKey:NO value:NULL]);
+ XCTAssertFalse([dict getBool:NULL forKey:YES]);
+ XCTAssertFalse([dict getBool:NULL forKey:NO]);
[dict release];
}
@@ -1492,51 +1492,51 @@
const BOOL kKeys[] = { YES, NO };
const BOOL kValues[] = { NO, YES };
GPBBoolBoolDictionary *dict =
- [[GPBBoolBoolDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBBoolBoolDictionary alloc] initWithBools:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 2U);
BOOL value;
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:YES]);
+ XCTAssertTrue([dict getBool:&value forKey:YES]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:NO value:NULL]);
- XCTAssertTrue([dict valueForKey:NO value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:NO]);
+ XCTAssertTrue([dict getBool:&value forKey:NO]);
XCTAssertEqual(value, YES);
- [dict setValue:YES forKey:YES];
+ [dict setBool:YES forKey:YES];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:YES]);
+ XCTAssertTrue([dict getBool:&value forKey:YES]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:NO value:NULL]);
- XCTAssertTrue([dict valueForKey:NO value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:NO]);
+ XCTAssertTrue([dict getBool:&value forKey:NO]);
XCTAssertEqual(value, YES);
- [dict setValue:NO forKey:NO];
+ [dict setBool:NO forKey:NO];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:YES]);
+ XCTAssertTrue([dict getBool:&value forKey:YES]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:NO value:NULL]);
- XCTAssertTrue([dict valueForKey:NO value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:NO]);
+ XCTAssertTrue([dict getBool:&value forKey:NO]);
XCTAssertEqual(value, NO);
const BOOL kKeys2[] = { NO, YES };
const BOOL kValues2[] = { YES, NO };
GPBBoolBoolDictionary *dict2 =
- [[GPBBoolBoolDictionary alloc] initWithValues:kValues2
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBBoolBoolDictionary alloc] initWithBools:kValues2
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:YES]);
+ XCTAssertTrue([dict getBool:&value forKey:YES]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:NO value:NULL]);
- XCTAssertTrue([dict valueForKey:NO value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:NO]);
+ XCTAssertTrue([dict getBool:&value forKey:NO]);
XCTAssertEqual(value, YES);
[dict2 release];
@@ -1559,8 +1559,8 @@
GPBBoolFloatDictionary *dict = [[GPBBoolFloatDictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:YES value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(BOOL aKey, float aValue, BOOL *stop) {
+ XCTAssertFalse([dict getFloat:NULL forKey:YES]);
+ [dict enumerateKeysAndFloatsUsingBlock:^(BOOL aKey, float aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -1568,15 +1568,15 @@
}
- (void)testOne {
- GPBBoolFloatDictionary *dict = [GPBBoolFloatDictionary dictionaryWithValue:500.f forKey:YES];
+ GPBBoolFloatDictionary *dict = [GPBBoolFloatDictionary dictionaryWithFloat:500.f forKey:YES];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
float value;
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:YES]);
+ XCTAssertTrue([dict getFloat:&value forKey:YES]);
XCTAssertEqual(value, 500.f);
- XCTAssertFalse([dict valueForKey:NO value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(BOOL aKey, float aValue, BOOL *stop) {
+ XCTAssertFalse([dict getFloat:NULL forKey:NO]);
+ [dict enumerateKeysAndFloatsUsingBlock:^(BOOL aKey, float aValue, BOOL *stop) {
XCTAssertEqual(aKey, YES);
XCTAssertEqual(aValue, 500.f);
XCTAssertNotEqual(stop, NULL);
@@ -1587,23 +1587,23 @@
const BOOL kKeys[] = { YES, NO };
const float kValues[] = { 500.f, 501.f };
GPBBoolFloatDictionary *dict =
- [[GPBBoolFloatDictionary alloc] initWithValues:kValues
+ [[GPBBoolFloatDictionary alloc] initWithFloats:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 2U);
float value;
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:YES]);
+ XCTAssertTrue([dict getFloat:&value forKey:YES]);
XCTAssertEqual(value, 500.f);
- XCTAssertTrue([dict valueForKey:NO value:NULL]);
- XCTAssertTrue([dict valueForKey:NO value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:NO]);
+ XCTAssertTrue([dict getFloat:&value forKey:NO]);
XCTAssertEqual(value, 501.f);
__block NSUInteger idx = 0;
BOOL *seenKeys = malloc(2 * sizeof(BOOL));
float *seenValues = malloc(2 * sizeof(float));
- [dict enumerateKeysAndValuesUsingBlock:^(BOOL aKey, float aValue, BOOL *stop) {
+ [dict enumerateKeysAndFloatsUsingBlock:^(BOOL aKey, float aValue, BOOL *stop) {
XCTAssertLessThan(idx, 2U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -1625,7 +1625,7 @@
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(BOOL aKey, float aValue, BOOL *stop) {
+ [dict enumerateKeysAndFloatsUsingBlock:^(BOOL aKey, float aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 0) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -1641,27 +1641,27 @@
const float kValues2[] = { 501.f, 500.f };
const float kValues3[] = { 501.f };
GPBBoolFloatDictionary *dict1 =
- [[GPBBoolFloatDictionary alloc] initWithValues:kValues1
+ [[GPBBoolFloatDictionary alloc] initWithFloats:kValues1
forKeys:kKeys1
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBBoolFloatDictionary *dict1prime =
- [[GPBBoolFloatDictionary alloc] initWithValues:kValues1
+ [[GPBBoolFloatDictionary alloc] initWithFloats:kValues1
forKeys:kKeys1
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBBoolFloatDictionary *dict2 =
- [[GPBBoolFloatDictionary alloc] initWithValues:kValues2
+ [[GPBBoolFloatDictionary alloc] initWithFloats:kValues2
forKeys:kKeys1
count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBBoolFloatDictionary *dict3 =
- [[GPBBoolFloatDictionary alloc] initWithValues:kValues1
+ [[GPBBoolFloatDictionary alloc] initWithFloats:kValues1
forKeys:kKeys2
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBBoolFloatDictionary *dict4 =
- [[GPBBoolFloatDictionary alloc] initWithValues:kValues3
+ [[GPBBoolFloatDictionary alloc] initWithFloats:kValues3
forKeys:kKeys1
count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
@@ -1692,7 +1692,7 @@
const BOOL kKeys[] = { YES, NO };
const float kValues[] = { 500.f, 501.f };
GPBBoolFloatDictionary *dict =
- [[GPBBoolFloatDictionary alloc] initWithValues:kValues
+ [[GPBBoolFloatDictionary alloc] initWithFloats:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
@@ -1713,7 +1713,7 @@
const BOOL kKeys[] = { YES, NO };
const float kValues[] = { 500.f, 501.f };
GPBBoolFloatDictionary *dict =
- [[GPBBoolFloatDictionary alloc] initWithValues:kValues
+ [[GPBBoolFloatDictionary alloc] initWithFloats:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
@@ -1733,13 +1733,13 @@
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:500.f forKey:YES];
+ [dict setFloat:500.f forKey:YES];
XCTAssertEqual(dict.count, 1U);
const BOOL kKeys[] = { NO };
const float kValues[] = { 501.f };
GPBBoolFloatDictionary *dict2 =
- [[GPBBoolFloatDictionary alloc] initWithValues:kValues
+ [[GPBBoolFloatDictionary alloc] initWithFloats:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
@@ -1747,11 +1747,11 @@
XCTAssertEqual(dict.count, 2U);
float value;
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:YES]);
+ XCTAssertTrue([dict getFloat:&value forKey:YES]);
XCTAssertEqual(value, 500.f);
- XCTAssertTrue([dict valueForKey:NO value:NULL]);
- XCTAssertTrue([dict valueForKey:NO value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:NO]);
+ XCTAssertTrue([dict getFloat:&value forKey:NO]);
XCTAssertEqual(value, 501.f);
[dict2 release];
}
@@ -1760,32 +1760,32 @@
const BOOL kKeys[] = { YES, NO};
const float kValues[] = { 500.f, 501.f };
GPBBoolFloatDictionary *dict =
- [[GPBBoolFloatDictionary alloc] initWithValues:kValues
+ [[GPBBoolFloatDictionary alloc] initWithFloats:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 2U);
- [dict removeValueForKey:NO];
+ [dict removeFloatForKey:NO];
XCTAssertEqual(dict.count, 1U);
float value;
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:YES]);
+ XCTAssertTrue([dict getFloat:&value forKey:YES]);
XCTAssertEqual(value, 500.f);
- XCTAssertFalse([dict valueForKey:NO value:NULL]);
+ XCTAssertFalse([dict getFloat:NULL forKey:NO]);
// Remove again does nothing.
- [dict removeValueForKey:NO];
+ [dict removeFloatForKey:NO];
XCTAssertEqual(dict.count, 1U);
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:YES]);
+ XCTAssertTrue([dict getFloat:&value forKey:YES]);
XCTAssertEqual(value, 500.f);
- XCTAssertFalse([dict valueForKey:NO value:NULL]);
+ XCTAssertFalse([dict getFloat:NULL forKey:NO]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:YES value:NULL]);
- XCTAssertFalse([dict valueForKey:NO value:NULL]);
+ XCTAssertFalse([dict getFloat:NULL forKey:YES]);
+ XCTAssertFalse([dict getFloat:NULL forKey:NO]);
[dict release];
}
@@ -1793,51 +1793,51 @@
const BOOL kKeys[] = { YES, NO };
const float kValues[] = { 500.f, 501.f };
GPBBoolFloatDictionary *dict =
- [[GPBBoolFloatDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBBoolFloatDictionary alloc] initWithFloats:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 2U);
float value;
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:YES]);
+ XCTAssertTrue([dict getFloat:&value forKey:YES]);
XCTAssertEqual(value, 500.f);
- XCTAssertTrue([dict valueForKey:NO value:NULL]);
- XCTAssertTrue([dict valueForKey:NO value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:NO]);
+ XCTAssertTrue([dict getFloat:&value forKey:NO]);
XCTAssertEqual(value, 501.f);
- [dict setValue:501.f forKey:YES];
+ [dict setFloat:501.f forKey:YES];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:YES]);
+ XCTAssertTrue([dict getFloat:&value forKey:YES]);
XCTAssertEqual(value, 501.f);
- XCTAssertTrue([dict valueForKey:NO value:NULL]);
- XCTAssertTrue([dict valueForKey:NO value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:NO]);
+ XCTAssertTrue([dict getFloat:&value forKey:NO]);
XCTAssertEqual(value, 501.f);
- [dict setValue:500.f forKey:NO];
+ [dict setFloat:500.f forKey:NO];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:YES]);
+ XCTAssertTrue([dict getFloat:&value forKey:YES]);
XCTAssertEqual(value, 501.f);
- XCTAssertTrue([dict valueForKey:NO value:NULL]);
- XCTAssertTrue([dict valueForKey:NO value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:NO]);
+ XCTAssertTrue([dict getFloat:&value forKey:NO]);
XCTAssertEqual(value, 500.f);
const BOOL kKeys2[] = { NO, YES };
const float kValues2[] = { 501.f, 500.f };
GPBBoolFloatDictionary *dict2 =
- [[GPBBoolFloatDictionary alloc] initWithValues:kValues2
+ [[GPBBoolFloatDictionary alloc] initWithFloats:kValues2
forKeys:kKeys2
count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:YES]);
+ XCTAssertTrue([dict getFloat:&value forKey:YES]);
XCTAssertEqual(value, 500.f);
- XCTAssertTrue([dict valueForKey:NO value:NULL]);
- XCTAssertTrue([dict valueForKey:NO value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:NO]);
+ XCTAssertTrue([dict getFloat:&value forKey:NO]);
XCTAssertEqual(value, 501.f);
[dict2 release];
@@ -1860,8 +1860,8 @@
GPBBoolDoubleDictionary *dict = [[GPBBoolDoubleDictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:YES value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(BOOL aKey, double aValue, BOOL *stop) {
+ XCTAssertFalse([dict getDouble:NULL forKey:YES]);
+ [dict enumerateKeysAndDoublesUsingBlock:^(BOOL aKey, double aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -1869,15 +1869,15 @@
}
- (void)testOne {
- GPBBoolDoubleDictionary *dict = [GPBBoolDoubleDictionary dictionaryWithValue:600. forKey:YES];
+ GPBBoolDoubleDictionary *dict = [GPBBoolDoubleDictionary dictionaryWithDouble:600. forKey:YES];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
double value;
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:YES]);
+ XCTAssertTrue([dict getDouble:&value forKey:YES]);
XCTAssertEqual(value, 600.);
- XCTAssertFalse([dict valueForKey:NO value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(BOOL aKey, double aValue, BOOL *stop) {
+ XCTAssertFalse([dict getDouble:NULL forKey:NO]);
+ [dict enumerateKeysAndDoublesUsingBlock:^(BOOL aKey, double aValue, BOOL *stop) {
XCTAssertEqual(aKey, YES);
XCTAssertEqual(aValue, 600.);
XCTAssertNotEqual(stop, NULL);
@@ -1888,23 +1888,23 @@
const BOOL kKeys[] = { YES, NO };
const double kValues[] = { 600., 601. };
GPBBoolDoubleDictionary *dict =
- [[GPBBoolDoubleDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBBoolDoubleDictionary alloc] initWithDoubles:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 2U);
double value;
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:YES]);
+ XCTAssertTrue([dict getDouble:&value forKey:YES]);
XCTAssertEqual(value, 600.);
- XCTAssertTrue([dict valueForKey:NO value:NULL]);
- XCTAssertTrue([dict valueForKey:NO value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:NO]);
+ XCTAssertTrue([dict getDouble:&value forKey:NO]);
XCTAssertEqual(value, 601.);
__block NSUInteger idx = 0;
BOOL *seenKeys = malloc(2 * sizeof(BOOL));
double *seenValues = malloc(2 * sizeof(double));
- [dict enumerateKeysAndValuesUsingBlock:^(BOOL aKey, double aValue, BOOL *stop) {
+ [dict enumerateKeysAndDoublesUsingBlock:^(BOOL aKey, double aValue, BOOL *stop) {
XCTAssertLessThan(idx, 2U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -1926,7 +1926,7 @@
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(BOOL aKey, double aValue, BOOL *stop) {
+ [dict enumerateKeysAndDoublesUsingBlock:^(BOOL aKey, double aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 0) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -1942,29 +1942,29 @@
const double kValues2[] = { 601., 600. };
const double kValues3[] = { 601. };
GPBBoolDoubleDictionary *dict1 =
- [[GPBBoolDoubleDictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBBoolDoubleDictionary alloc] initWithDoubles:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBBoolDoubleDictionary *dict1prime =
- [[GPBBoolDoubleDictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBBoolDoubleDictionary alloc] initWithDoubles:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBBoolDoubleDictionary *dict2 =
- [[GPBBoolDoubleDictionary alloc] initWithValues:kValues2
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBBoolDoubleDictionary alloc] initWithDoubles:kValues2
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBBoolDoubleDictionary *dict3 =
- [[GPBBoolDoubleDictionary alloc] initWithValues:kValues1
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBBoolDoubleDictionary alloc] initWithDoubles:kValues1
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBBoolDoubleDictionary *dict4 =
- [[GPBBoolDoubleDictionary alloc] initWithValues:kValues3
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues3)];
+ [[GPBBoolDoubleDictionary alloc] initWithDoubles:kValues3
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
// 1/1Prime should be different objects, but equal.
@@ -1993,9 +1993,9 @@
const BOOL kKeys[] = { YES, NO };
const double kValues[] = { 600., 601. };
GPBBoolDoubleDictionary *dict =
- [[GPBBoolDoubleDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBBoolDoubleDictionary alloc] initWithDoubles:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBBoolDoubleDictionary *dict2 = [dict copy];
@@ -2014,9 +2014,9 @@
const BOOL kKeys[] = { YES, NO };
const double kValues[] = { 600., 601. };
GPBBoolDoubleDictionary *dict =
- [[GPBBoolDoubleDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBBoolDoubleDictionary alloc] initWithDoubles:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBBoolDoubleDictionary *dict2 =
@@ -2034,25 +2034,25 @@
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:600. forKey:YES];
+ [dict setDouble:600. forKey:YES];
XCTAssertEqual(dict.count, 1U);
const BOOL kKeys[] = { NO };
const double kValues[] = { 601. };
GPBBoolDoubleDictionary *dict2 =
- [[GPBBoolDoubleDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBBoolDoubleDictionary alloc] initWithDoubles:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 2U);
double value;
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:YES]);
+ XCTAssertTrue([dict getDouble:&value forKey:YES]);
XCTAssertEqual(value, 600.);
- XCTAssertTrue([dict valueForKey:NO value:NULL]);
- XCTAssertTrue([dict valueForKey:NO value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:NO]);
+ XCTAssertTrue([dict getDouble:&value forKey:NO]);
XCTAssertEqual(value, 601.);
[dict2 release];
}
@@ -2061,32 +2061,32 @@
const BOOL kKeys[] = { YES, NO};
const double kValues[] = { 600., 601. };
GPBBoolDoubleDictionary *dict =
- [[GPBBoolDoubleDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBBoolDoubleDictionary alloc] initWithDoubles:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 2U);
- [dict removeValueForKey:NO];
+ [dict removeDoubleForKey:NO];
XCTAssertEqual(dict.count, 1U);
double value;
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:YES]);
+ XCTAssertTrue([dict getDouble:&value forKey:YES]);
XCTAssertEqual(value, 600.);
- XCTAssertFalse([dict valueForKey:NO value:NULL]);
+ XCTAssertFalse([dict getDouble:NULL forKey:NO]);
// Remove again does nothing.
- [dict removeValueForKey:NO];
+ [dict removeDoubleForKey:NO];
XCTAssertEqual(dict.count, 1U);
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:YES]);
+ XCTAssertTrue([dict getDouble:&value forKey:YES]);
XCTAssertEqual(value, 600.);
- XCTAssertFalse([dict valueForKey:NO value:NULL]);
+ XCTAssertFalse([dict getDouble:NULL forKey:NO]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:YES value:NULL]);
- XCTAssertFalse([dict valueForKey:NO value:NULL]);
+ XCTAssertFalse([dict getDouble:NULL forKey:YES]);
+ XCTAssertFalse([dict getDouble:NULL forKey:NO]);
[dict release];
}
@@ -2094,51 +2094,51 @@
const BOOL kKeys[] = { YES, NO };
const double kValues[] = { 600., 601. };
GPBBoolDoubleDictionary *dict =
- [[GPBBoolDoubleDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBBoolDoubleDictionary alloc] initWithDoubles:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 2U);
double value;
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:YES]);
+ XCTAssertTrue([dict getDouble:&value forKey:YES]);
XCTAssertEqual(value, 600.);
- XCTAssertTrue([dict valueForKey:NO value:NULL]);
- XCTAssertTrue([dict valueForKey:NO value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:NO]);
+ XCTAssertTrue([dict getDouble:&value forKey:NO]);
XCTAssertEqual(value, 601.);
- [dict setValue:601. forKey:YES];
+ [dict setDouble:601. forKey:YES];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:YES]);
+ XCTAssertTrue([dict getDouble:&value forKey:YES]);
XCTAssertEqual(value, 601.);
- XCTAssertTrue([dict valueForKey:NO value:NULL]);
- XCTAssertTrue([dict valueForKey:NO value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:NO]);
+ XCTAssertTrue([dict getDouble:&value forKey:NO]);
XCTAssertEqual(value, 601.);
- [dict setValue:600. forKey:NO];
+ [dict setDouble:600. forKey:NO];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:YES]);
+ XCTAssertTrue([dict getDouble:&value forKey:YES]);
XCTAssertEqual(value, 601.);
- XCTAssertTrue([dict valueForKey:NO value:NULL]);
- XCTAssertTrue([dict valueForKey:NO value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:NO]);
+ XCTAssertTrue([dict getDouble:&value forKey:NO]);
XCTAssertEqual(value, 600.);
const BOOL kKeys2[] = { NO, YES };
const double kValues2[] = { 601., 600. };
GPBBoolDoubleDictionary *dict2 =
- [[GPBBoolDoubleDictionary alloc] initWithValues:kValues2
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBBoolDoubleDictionary alloc] initWithDoubles:kValues2
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:YES value:NULL]);
- XCTAssertTrue([dict valueForKey:YES value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:YES]);
+ XCTAssertTrue([dict getDouble:&value forKey:YES]);
XCTAssertEqual(value, 600.);
- XCTAssertTrue([dict valueForKey:NO value:NULL]);
- XCTAssertTrue([dict valueForKey:NO value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:NO]);
+ XCTAssertTrue([dict getDouble:&value forKey:NO]);
XCTAssertEqual(value, 601.);
[dict2 release];
@@ -2147,7 +2147,7 @@
@end
-//%PDDM-EXPAND TESTS_FOR_BOOL_KEY_OBJECT_VALUE(Object, id, @"abc", @"def")
+//%PDDM-EXPAND TESTS_FOR_BOOL_KEY_OBJECT_VALUE(Object, NSString*, @"abc", @"def")
// This block of code is generated, do not edit it directly.
#pragma mark - Bool -> Object
@@ -2158,11 +2158,11 @@
@implementation GPBBoolObjectDictionaryTests
- (void)testEmpty {
- GPBBoolObjectDictionary *dict = [[GPBBoolObjectDictionary alloc] init];
+ GPBBoolObjectDictionary<NSString*> *dict = [[GPBBoolObjectDictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertNil([dict objectForKey:YES]);
- [dict enumerateKeysAndObjectsUsingBlock:^(BOOL aKey, id aObject, BOOL *stop) {
+ [dict enumerateKeysAndObjectsUsingBlock:^(BOOL aKey, NSString* aObject, BOOL *stop) {
#pragma unused(aKey, aObject, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -2170,12 +2170,12 @@
}
- (void)testOne {
- GPBBoolObjectDictionary *dict = [GPBBoolObjectDictionary dictionaryWithObject:@"abc" forKey:YES];
+ GPBBoolObjectDictionary<NSString*> *dict = [GPBBoolObjectDictionary dictionaryWithObject:@"abc" forKey:YES];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
XCTAssertEqualObjects([dict objectForKey:YES], @"abc");
XCTAssertNil([dict objectForKey:NO]);
- [dict enumerateKeysAndObjectsUsingBlock:^(BOOL aKey, id aObject, BOOL *stop) {
+ [dict enumerateKeysAndObjectsUsingBlock:^(BOOL aKey, NSString* aObject, BOOL *stop) {
XCTAssertEqual(aKey, YES);
XCTAssertEqualObjects(aObject, @"abc");
XCTAssertNotEqual(stop, NULL);
@@ -2184,8 +2184,8 @@
- (void)testBasics {
const BOOL kKeys[] = { YES, NO };
- const id kObjects[] = { @"abc", @"def" };
- GPBBoolObjectDictionary *dict =
+ const NSString* kObjects[] = { @"abc", @"def" };
+ GPBBoolObjectDictionary<NSString*> *dict =
[[GPBBoolObjectDictionary alloc] initWithObjects:kObjects
forKeys:kKeys
count:GPBARRAYSIZE(kObjects)];
@@ -2196,8 +2196,8 @@
__block NSUInteger idx = 0;
BOOL *seenKeys = malloc(2 * sizeof(BOOL));
- id *seenObjects = malloc(2 * sizeof(id));
- [dict enumerateKeysAndObjectsUsingBlock:^(BOOL aKey, id aObject, BOOL *stop) {
+ NSString* *seenObjects = malloc(2 * sizeof(NSString*));
+ [dict enumerateKeysAndObjectsUsingBlock:^(BOOL aKey, NSString* aObject, BOOL *stop) {
XCTAssertLessThan(idx, 2U);
seenKeys[idx] = aKey;
seenObjects[idx] = aObject;
@@ -2219,7 +2219,7 @@
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndObjectsUsingBlock:^(BOOL aKey, id aObject, BOOL *stop) {
+ [dict enumerateKeysAndObjectsUsingBlock:^(BOOL aKey, NSString* aObject, BOOL *stop) {
#pragma unused(aKey, aObject)
if (idx == 0) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -2231,30 +2231,30 @@
- (void)testEquality {
const BOOL kKeys1[] = { YES, NO };
const BOOL kKeys2[] = { NO, YES };
- const id kObjects1[] = { @"abc", @"def" };
- const id kObjects2[] = { @"def", @"abc" };
- const id kObjects3[] = { @"def" };
- GPBBoolObjectDictionary *dict1 =
+ const NSString* kObjects1[] = { @"abc", @"def" };
+ const NSString* kObjects2[] = { @"def", @"abc" };
+ const NSString* kObjects3[] = { @"def" };
+ GPBBoolObjectDictionary<NSString*> *dict1 =
[[GPBBoolObjectDictionary alloc] initWithObjects:kObjects1
forKeys:kKeys1
count:GPBARRAYSIZE(kObjects1)];
XCTAssertNotNil(dict1);
- GPBBoolObjectDictionary *dict1prime =
+ GPBBoolObjectDictionary<NSString*> *dict1prime =
[[GPBBoolObjectDictionary alloc] initWithObjects:kObjects1
forKeys:kKeys1
count:GPBARRAYSIZE(kObjects1)];
XCTAssertNotNil(dict1prime);
- GPBBoolObjectDictionary *dict2 =
+ GPBBoolObjectDictionary<NSString*> *dict2 =
[[GPBBoolObjectDictionary alloc] initWithObjects:kObjects2
forKeys:kKeys1
count:GPBARRAYSIZE(kObjects2)];
XCTAssertNotNil(dict2);
- GPBBoolObjectDictionary *dict3 =
+ GPBBoolObjectDictionary<NSString*> *dict3 =
[[GPBBoolObjectDictionary alloc] initWithObjects:kObjects1
forKeys:kKeys2
count:GPBARRAYSIZE(kObjects1)];
XCTAssertNotNil(dict3);
- GPBBoolObjectDictionary *dict4 =
+ GPBBoolObjectDictionary<NSString*> *dict4 =
[[GPBBoolObjectDictionary alloc] initWithObjects:kObjects3
forKeys:kKeys1
count:GPBARRAYSIZE(kObjects3)];
@@ -2284,14 +2284,14 @@
- (void)testCopy {
const BOOL kKeys[] = { YES, NO };
- const id kObjects[] = { @"abc", @"def" };
- GPBBoolObjectDictionary *dict =
+ const NSString* kObjects[] = { @"abc", @"def" };
+ GPBBoolObjectDictionary<NSString*> *dict =
[[GPBBoolObjectDictionary alloc] initWithObjects:kObjects
forKeys:kKeys
count:GPBARRAYSIZE(kObjects)];
XCTAssertNotNil(dict);
- GPBBoolObjectDictionary *dict2 = [dict copy];
+ GPBBoolObjectDictionary<NSString*> *dict2 = [dict copy];
XCTAssertNotNil(dict2);
// Should be new object but equal.
@@ -2305,14 +2305,14 @@
- (void)testDictionaryFromDictionary {
const BOOL kKeys[] = { YES, NO };
- const id kObjects[] = { @"abc", @"def" };
- GPBBoolObjectDictionary *dict =
+ const NSString* kObjects[] = { @"abc", @"def" };
+ GPBBoolObjectDictionary<NSString*> *dict =
[[GPBBoolObjectDictionary alloc] initWithObjects:kObjects
forKeys:kKeys
count:GPBARRAYSIZE(kObjects)];
XCTAssertNotNil(dict);
- GPBBoolObjectDictionary *dict2 =
+ GPBBoolObjectDictionary<NSString*> *dict2 =
[GPBBoolObjectDictionary dictionaryWithDictionary:dict];
XCTAssertNotNil(dict2);
@@ -2323,7 +2323,7 @@
}
- (void)testAdds {
- GPBBoolObjectDictionary *dict = [GPBBoolObjectDictionary dictionary];
+ GPBBoolObjectDictionary<NSString*> *dict = [GPBBoolObjectDictionary dictionary];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
@@ -2331,8 +2331,8 @@
XCTAssertEqual(dict.count, 1U);
const BOOL kKeys[] = { NO };
- const id kObjects[] = { @"def" };
- GPBBoolObjectDictionary *dict2 =
+ const NSString* kObjects[] = { @"def" };
+ GPBBoolObjectDictionary<NSString*> *dict2 =
[[GPBBoolObjectDictionary alloc] initWithObjects:kObjects
forKeys:kKeys
count:GPBARRAYSIZE(kObjects)];
@@ -2347,8 +2347,8 @@
- (void)testRemove {
const BOOL kKeys[] = { YES, NO};
- const id kObjects[] = { @"abc", @"def" };
- GPBBoolObjectDictionary *dict =
+ const NSString* kObjects[] = { @"abc", @"def" };
+ GPBBoolObjectDictionary<NSString*> *dict =
[[GPBBoolObjectDictionary alloc] initWithObjects:kObjects
forKeys:kKeys
count:GPBARRAYSIZE(kObjects)];
@@ -2375,11 +2375,11 @@
- (void)testInplaceMutation {
const BOOL kKeys[] = { YES, NO };
- const id kObjects[] = { @"abc", @"def" };
- GPBBoolObjectDictionary *dict =
+ const NSString* kObjects[] = { @"abc", @"def" };
+ GPBBoolObjectDictionary<NSString*> *dict =
[[GPBBoolObjectDictionary alloc] initWithObjects:kObjects
- forKeys:kKeys
- count:GPBARRAYSIZE(kObjects)];
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kObjects)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 2U);
XCTAssertEqualObjects([dict objectForKey:YES], @"abc");
@@ -2396,8 +2396,8 @@
XCTAssertEqualObjects([dict objectForKey:NO], @"abc");
const BOOL kKeys2[] = { NO, YES };
- const id kObjects2[] = { @"def", @"abc" };
- GPBBoolObjectDictionary *dict2 =
+ const NSString* kObjects2[] = { @"def", @"abc" };
+ GPBBoolObjectDictionary<NSString*> *dict2 =
[[GPBBoolObjectDictionary alloc] initWithObjects:kObjects2
forKeys:kKeys2
count:GPBARRAYSIZE(kObjects2)];
diff --git a/objectivec/Tests/GPBDictionaryTests+Int32.m b/objectivec/Tests/GPBDictionaryTests+Int32.m
index 21d3f07d..c539bdc2 100644
--- a/objectivec/Tests/GPBDictionaryTests+Int32.m
+++ b/objectivec/Tests/GPBDictionaryTests+Int32.m
@@ -45,10 +45,10 @@
// To let the testing macros work, add some extra methods to simplify things.
@interface GPBInt32EnumDictionary (TestingTweak)
-+ (instancetype)dictionaryWithValue:(int32_t)value forKey:(int32_t)key;
-- (instancetype)initWithValues:(const int32_t [])values
- forKeys:(const int32_t [])keys
- count:(NSUInteger)count;
++ (instancetype)dictionaryWithEnum:(int32_t)value forKey:(int32_t)key;
+- (instancetype)initWithEnums:(const int32_t [])values
+ forKeys:(const int32_t [])keys
+ count:(NSUInteger)count;
@end
static BOOL TestingEnum_IsValidValue(int32_t value) {
@@ -64,7 +64,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
@implementation GPBInt32EnumDictionary (TestingTweak)
-+ (instancetype)dictionaryWithValue:(int32_t)value forKey:(int32_t)key {
++ (instancetype)dictionaryWithEnum:(int32_t)value forKey:(int32_t)key {
// Cast is needed to compiler knows what class we are invoking initWithValues: on to get the
// type correct.
return [[(GPBInt32EnumDictionary*)[self alloc] initWithValidationFunction:TestingEnum_IsValidValue
@@ -72,9 +72,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
forKeys:&key
count:1] autorelease];
}
-- (instancetype)initWithValues:(const int32_t [])values
- forKeys:(const int32_t [])keys
- count:(NSUInteger)count {
+- (instancetype)initWithEnums:(const int32_t [])values
+ forKeys:(const int32_t [])keys
+ count:(NSUInteger)count {
return [self initWithValidationFunction:TestingEnum_IsValidValue
rawValues:values
forKeys:keys
@@ -94,8 +94,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
GPBInt32UInt32Dictionary *dict = [[GPBInt32UInt32Dictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:11 value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(int32_t aKey, uint32_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getUInt32:NULL forKey:11]);
+ [dict enumerateKeysAndUInt32sUsingBlock:^(int32_t aKey, uint32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -103,15 +103,15 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testOne {
- GPBInt32UInt32Dictionary *dict = [GPBInt32UInt32Dictionary dictionaryWithValue:100U forKey:11];
+ GPBInt32UInt32Dictionary *dict = [GPBInt32UInt32Dictionary dictionaryWithUInt32:100U forKey:11];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
uint32_t value;
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:11]);
+ XCTAssertTrue([dict getUInt32:&value forKey:11]);
XCTAssertEqual(value, 100U);
- XCTAssertFalse([dict valueForKey:12 value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(int32_t aKey, uint32_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getUInt32:NULL forKey:12]);
+ [dict enumerateKeysAndUInt32sUsingBlock:^(int32_t aKey, uint32_t aValue, BOOL *stop) {
XCTAssertEqual(aKey, 11);
XCTAssertEqual(aValue, 100U);
XCTAssertNotEqual(stop, NULL);
@@ -122,27 +122,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kKeys[] = { 11, 12, 13 };
const uint32_t kValues[] = { 100U, 101U, 102U };
GPBInt32UInt32Dictionary *dict =
- [[GPBInt32UInt32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt32UInt32Dictionary alloc] initWithUInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 3U);
uint32_t value;
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:11]);
+ XCTAssertTrue([dict getUInt32:&value forKey:11]);
XCTAssertEqual(value, 100U);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:12]);
+ XCTAssertTrue([dict getUInt32:&value forKey:12]);
XCTAssertEqual(value, 101U);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:13]);
+ XCTAssertTrue([dict getUInt32:&value forKey:13]);
XCTAssertEqual(value, 102U);
- XCTAssertFalse([dict valueForKey:14 value:NULL]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:14]);
__block NSUInteger idx = 0;
int32_t *seenKeys = malloc(3 * sizeof(int32_t));
uint32_t *seenValues = malloc(3 * sizeof(uint32_t));
- [dict enumerateKeysAndValuesUsingBlock:^(int32_t aKey, uint32_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndUInt32sUsingBlock:^(int32_t aKey, uint32_t aValue, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -164,7 +164,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(int32_t aKey, uint32_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndUInt32sUsingBlock:^(int32_t aKey, uint32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -180,29 +180,29 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint32_t kValues2[] = { 100U, 103U, 102U };
const uint32_t kValues3[] = { 100U, 101U, 102U, 103U };
GPBInt32UInt32Dictionary *dict1 =
- [[GPBInt32UInt32Dictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBInt32UInt32Dictionary alloc] initWithUInt32s:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBInt32UInt32Dictionary *dict1prime =
- [[GPBInt32UInt32Dictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBInt32UInt32Dictionary alloc] initWithUInt32s:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBInt32UInt32Dictionary *dict2 =
- [[GPBInt32UInt32Dictionary alloc] initWithValues:kValues2
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBInt32UInt32Dictionary alloc] initWithUInt32s:kValues2
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBInt32UInt32Dictionary *dict3 =
- [[GPBInt32UInt32Dictionary alloc] initWithValues:kValues1
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBInt32UInt32Dictionary alloc] initWithUInt32s:kValues1
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBInt32UInt32Dictionary *dict4 =
- [[GPBInt32UInt32Dictionary alloc] initWithValues:kValues3
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues3)];
+ [[GPBInt32UInt32Dictionary alloc] initWithUInt32s:kValues3
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
// 1/1Prime should be different objects, but equal.
@@ -231,9 +231,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kKeys[] = { 11, 12, 13, 14 };
const uint32_t kValues[] = { 100U, 101U, 102U, 103U };
GPBInt32UInt32Dictionary *dict =
- [[GPBInt32UInt32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt32UInt32Dictionary alloc] initWithUInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBInt32UInt32Dictionary *dict2 = [dict copy];
@@ -252,9 +252,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kKeys[] = { 11, 12, 13, 14 };
const uint32_t kValues[] = { 100U, 101U, 102U, 103U };
GPBInt32UInt32Dictionary *dict =
- [[GPBInt32UInt32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt32UInt32Dictionary alloc] initWithUInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBInt32UInt32Dictionary *dict2 =
@@ -272,31 +272,31 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:100U forKey:11];
+ [dict setUInt32:100U forKey:11];
XCTAssertEqual(dict.count, 1U);
const int32_t kKeys[] = { 12, 13, 14 };
const uint32_t kValues[] = { 101U, 102U, 103U };
GPBInt32UInt32Dictionary *dict2 =
- [[GPBInt32UInt32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt32UInt32Dictionary alloc] initWithUInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
uint32_t value;
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:11]);
+ XCTAssertTrue([dict getUInt32:&value forKey:11]);
XCTAssertEqual(value, 100U);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:12]);
+ XCTAssertTrue([dict getUInt32:&value forKey:12]);
XCTAssertEqual(value, 101U);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:13]);
+ XCTAssertTrue([dict getUInt32:&value forKey:13]);
XCTAssertEqual(value, 102U);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:14]);
+ XCTAssertTrue([dict getUInt32:&value forKey:14]);
XCTAssertEqual(value, 103U);
[dict2 release];
}
@@ -305,57 +305,57 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kKeys[] = { 11, 12, 13, 14 };
const uint32_t kValues[] = { 100U, 101U, 102U, 103U };
GPBInt32UInt32Dictionary *dict =
- [[GPBInt32UInt32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt32UInt32Dictionary alloc] initWithUInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
- [dict removeValueForKey:12];
+ [dict removeUInt32ForKey:12];
XCTAssertEqual(dict.count, 3U);
uint32_t value;
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:11]);
+ XCTAssertTrue([dict getUInt32:&value forKey:11]);
XCTAssertEqual(value, 100U);
- XCTAssertFalse([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:12]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:13]);
+ XCTAssertTrue([dict getUInt32:&value forKey:13]);
XCTAssertEqual(value, 102U);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:14]);
+ XCTAssertTrue([dict getUInt32:&value forKey:14]);
XCTAssertEqual(value, 103U);
// Remove again does nothing.
- [dict removeValueForKey:12];
+ [dict removeUInt32ForKey:12];
XCTAssertEqual(dict.count, 3U);
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:11]);
+ XCTAssertTrue([dict getUInt32:&value forKey:11]);
XCTAssertEqual(value, 100U);
- XCTAssertFalse([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:12]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:13]);
+ XCTAssertTrue([dict getUInt32:&value forKey:13]);
XCTAssertEqual(value, 102U);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:14]);
+ XCTAssertTrue([dict getUInt32:&value forKey:14]);
XCTAssertEqual(value, 103U);
- [dict removeValueForKey:14];
+ [dict removeUInt32ForKey:14];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:11]);
+ XCTAssertTrue([dict getUInt32:&value forKey:11]);
XCTAssertEqual(value, 100U);
- XCTAssertFalse([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:12]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:13]);
+ XCTAssertTrue([dict getUInt32:&value forKey:13]);
XCTAssertEqual(value, 102U);
- XCTAssertFalse([dict valueForKey:14 value:NULL]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:14]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:11 value:NULL]);
- XCTAssertFalse([dict valueForKey:12 value:NULL]);
- XCTAssertFalse([dict valueForKey:13 value:NULL]);
- XCTAssertFalse([dict valueForKey:14 value:NULL]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:11]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:12]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:13]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:14]);
[dict release];
}
@@ -363,75 +363,75 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kKeys[] = { 11, 12, 13, 14 };
const uint32_t kValues[] = { 100U, 101U, 102U, 103U };
GPBInt32UInt32Dictionary *dict =
- [[GPBInt32UInt32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt32UInt32Dictionary alloc] initWithUInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
uint32_t value;
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:11]);
+ XCTAssertTrue([dict getUInt32:&value forKey:11]);
XCTAssertEqual(value, 100U);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:12]);
+ XCTAssertTrue([dict getUInt32:&value forKey:12]);
XCTAssertEqual(value, 101U);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:13]);
+ XCTAssertTrue([dict getUInt32:&value forKey:13]);
XCTAssertEqual(value, 102U);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:14]);
+ XCTAssertTrue([dict getUInt32:&value forKey:14]);
XCTAssertEqual(value, 103U);
- [dict setValue:103U forKey:11];
+ [dict setUInt32:103U forKey:11];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:11]);
+ XCTAssertTrue([dict getUInt32:&value forKey:11]);
XCTAssertEqual(value, 103U);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:12]);
+ XCTAssertTrue([dict getUInt32:&value forKey:12]);
XCTAssertEqual(value, 101U);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:13]);
+ XCTAssertTrue([dict getUInt32:&value forKey:13]);
XCTAssertEqual(value, 102U);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:14]);
+ XCTAssertTrue([dict getUInt32:&value forKey:14]);
XCTAssertEqual(value, 103U);
- [dict setValue:101U forKey:14];
+ [dict setUInt32:101U forKey:14];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:11]);
+ XCTAssertTrue([dict getUInt32:&value forKey:11]);
XCTAssertEqual(value, 103U);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:12]);
+ XCTAssertTrue([dict getUInt32:&value forKey:12]);
XCTAssertEqual(value, 101U);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:13]);
+ XCTAssertTrue([dict getUInt32:&value forKey:13]);
XCTAssertEqual(value, 102U);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:14]);
+ XCTAssertTrue([dict getUInt32:&value forKey:14]);
XCTAssertEqual(value, 101U);
const int32_t kKeys2[] = { 12, 13 };
const uint32_t kValues2[] = { 102U, 100U };
GPBInt32UInt32Dictionary *dict2 =
- [[GPBInt32UInt32Dictionary alloc] initWithValues:kValues2
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBInt32UInt32Dictionary alloc] initWithUInt32s:kValues2
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:11]);
+ XCTAssertTrue([dict getUInt32:&value forKey:11]);
XCTAssertEqual(value, 103U);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:12]);
+ XCTAssertTrue([dict getUInt32:&value forKey:12]);
XCTAssertEqual(value, 102U);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:13]);
+ XCTAssertTrue([dict getUInt32:&value forKey:13]);
XCTAssertEqual(value, 100U);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:14]);
+ XCTAssertTrue([dict getUInt32:&value forKey:14]);
XCTAssertEqual(value, 101U);
[dict2 release];
@@ -451,8 +451,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
GPBInt32Int32Dictionary *dict = [[GPBInt32Int32Dictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:11 value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(int32_t aKey, int32_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getInt32:NULL forKey:11]);
+ [dict enumerateKeysAndInt32sUsingBlock:^(int32_t aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -460,15 +460,15 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testOne {
- GPBInt32Int32Dictionary *dict = [GPBInt32Int32Dictionary dictionaryWithValue:200 forKey:11];
+ GPBInt32Int32Dictionary *dict = [GPBInt32Int32Dictionary dictionaryWithInt32:200 forKey:11];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
int32_t value;
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:11]);
+ XCTAssertTrue([dict getInt32:&value forKey:11]);
XCTAssertEqual(value, 200);
- XCTAssertFalse([dict valueForKey:12 value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(int32_t aKey, int32_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getInt32:NULL forKey:12]);
+ [dict enumerateKeysAndInt32sUsingBlock:^(int32_t aKey, int32_t aValue, BOOL *stop) {
XCTAssertEqual(aKey, 11);
XCTAssertEqual(aValue, 200);
XCTAssertNotEqual(stop, NULL);
@@ -479,27 +479,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kKeys[] = { 11, 12, 13 };
const int32_t kValues[] = { 200, 201, 202 };
GPBInt32Int32Dictionary *dict =
- [[GPBInt32Int32Dictionary alloc] initWithValues:kValues
+ [[GPBInt32Int32Dictionary alloc] initWithInt32s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 3U);
int32_t value;
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:11]);
+ XCTAssertTrue([dict getInt32:&value forKey:11]);
XCTAssertEqual(value, 200);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:12]);
+ XCTAssertTrue([dict getInt32:&value forKey:12]);
XCTAssertEqual(value, 201);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:13]);
+ XCTAssertTrue([dict getInt32:&value forKey:13]);
XCTAssertEqual(value, 202);
- XCTAssertFalse([dict valueForKey:14 value:NULL]);
+ XCTAssertFalse([dict getInt32:NULL forKey:14]);
__block NSUInteger idx = 0;
int32_t *seenKeys = malloc(3 * sizeof(int32_t));
int32_t *seenValues = malloc(3 * sizeof(int32_t));
- [dict enumerateKeysAndValuesUsingBlock:^(int32_t aKey, int32_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndInt32sUsingBlock:^(int32_t aKey, int32_t aValue, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -521,7 +521,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(int32_t aKey, int32_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndInt32sUsingBlock:^(int32_t aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -537,27 +537,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kValues2[] = { 200, 203, 202 };
const int32_t kValues3[] = { 200, 201, 202, 203 };
GPBInt32Int32Dictionary *dict1 =
- [[GPBInt32Int32Dictionary alloc] initWithValues:kValues1
+ [[GPBInt32Int32Dictionary alloc] initWithInt32s:kValues1
forKeys:kKeys1
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBInt32Int32Dictionary *dict1prime =
- [[GPBInt32Int32Dictionary alloc] initWithValues:kValues1
+ [[GPBInt32Int32Dictionary alloc] initWithInt32s:kValues1
forKeys:kKeys1
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBInt32Int32Dictionary *dict2 =
- [[GPBInt32Int32Dictionary alloc] initWithValues:kValues2
+ [[GPBInt32Int32Dictionary alloc] initWithInt32s:kValues2
forKeys:kKeys1
count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBInt32Int32Dictionary *dict3 =
- [[GPBInt32Int32Dictionary alloc] initWithValues:kValues1
+ [[GPBInt32Int32Dictionary alloc] initWithInt32s:kValues1
forKeys:kKeys2
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBInt32Int32Dictionary *dict4 =
- [[GPBInt32Int32Dictionary alloc] initWithValues:kValues3
+ [[GPBInt32Int32Dictionary alloc] initWithInt32s:kValues3
forKeys:kKeys1
count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
@@ -588,7 +588,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kKeys[] = { 11, 12, 13, 14 };
const int32_t kValues[] = { 200, 201, 202, 203 };
GPBInt32Int32Dictionary *dict =
- [[GPBInt32Int32Dictionary alloc] initWithValues:kValues
+ [[GPBInt32Int32Dictionary alloc] initWithInt32s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
@@ -609,7 +609,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kKeys[] = { 11, 12, 13, 14 };
const int32_t kValues[] = { 200, 201, 202, 203 };
GPBInt32Int32Dictionary *dict =
- [[GPBInt32Int32Dictionary alloc] initWithValues:kValues
+ [[GPBInt32Int32Dictionary alloc] initWithInt32s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
@@ -629,13 +629,13 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:200 forKey:11];
+ [dict setInt32:200 forKey:11];
XCTAssertEqual(dict.count, 1U);
const int32_t kKeys[] = { 12, 13, 14 };
const int32_t kValues[] = { 201, 202, 203 };
GPBInt32Int32Dictionary *dict2 =
- [[GPBInt32Int32Dictionary alloc] initWithValues:kValues
+ [[GPBInt32Int32Dictionary alloc] initWithInt32s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
@@ -643,17 +643,17 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertEqual(dict.count, 4U);
int32_t value;
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:11]);
+ XCTAssertTrue([dict getInt32:&value forKey:11]);
XCTAssertEqual(value, 200);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:12]);
+ XCTAssertTrue([dict getInt32:&value forKey:12]);
XCTAssertEqual(value, 201);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:13]);
+ XCTAssertTrue([dict getInt32:&value forKey:13]);
XCTAssertEqual(value, 202);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:14]);
+ XCTAssertTrue([dict getInt32:&value forKey:14]);
XCTAssertEqual(value, 203);
[dict2 release];
}
@@ -662,57 +662,57 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kKeys[] = { 11, 12, 13, 14 };
const int32_t kValues[] = { 200, 201, 202, 203 };
GPBInt32Int32Dictionary *dict =
- [[GPBInt32Int32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt32Int32Dictionary alloc] initWithInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
- [dict removeValueForKey:12];
+ [dict removeInt32ForKey:12];
XCTAssertEqual(dict.count, 3U);
int32_t value;
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:11]);
+ XCTAssertTrue([dict getInt32:&value forKey:11]);
XCTAssertEqual(value, 200);
- XCTAssertFalse([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertFalse([dict getInt32:NULL forKey:12]);
+ XCTAssertTrue([dict getInt32:NULL forKey:13]);
+ XCTAssertTrue([dict getInt32:&value forKey:13]);
XCTAssertEqual(value, 202);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:14]);
+ XCTAssertTrue([dict getInt32:&value forKey:14]);
XCTAssertEqual(value, 203);
// Remove again does nothing.
- [dict removeValueForKey:12];
+ [dict removeInt32ForKey:12];
XCTAssertEqual(dict.count, 3U);
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:11]);
+ XCTAssertTrue([dict getInt32:&value forKey:11]);
XCTAssertEqual(value, 200);
- XCTAssertFalse([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertFalse([dict getInt32:NULL forKey:12]);
+ XCTAssertTrue([dict getInt32:NULL forKey:13]);
+ XCTAssertTrue([dict getInt32:&value forKey:13]);
XCTAssertEqual(value, 202);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:14]);
+ XCTAssertTrue([dict getInt32:&value forKey:14]);
XCTAssertEqual(value, 203);
- [dict removeValueForKey:14];
+ [dict removeInt32ForKey:14];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:11]);
+ XCTAssertTrue([dict getInt32:&value forKey:11]);
XCTAssertEqual(value, 200);
- XCTAssertFalse([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertFalse([dict getInt32:NULL forKey:12]);
+ XCTAssertTrue([dict getInt32:NULL forKey:13]);
+ XCTAssertTrue([dict getInt32:&value forKey:13]);
XCTAssertEqual(value, 202);
- XCTAssertFalse([dict valueForKey:14 value:NULL]);
+ XCTAssertFalse([dict getInt32:NULL forKey:14]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:11 value:NULL]);
- XCTAssertFalse([dict valueForKey:12 value:NULL]);
- XCTAssertFalse([dict valueForKey:13 value:NULL]);
- XCTAssertFalse([dict valueForKey:14 value:NULL]);
+ XCTAssertFalse([dict getInt32:NULL forKey:11]);
+ XCTAssertFalse([dict getInt32:NULL forKey:12]);
+ XCTAssertFalse([dict getInt32:NULL forKey:13]);
+ XCTAssertFalse([dict getInt32:NULL forKey:14]);
[dict release];
}
@@ -720,75 +720,75 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kKeys[] = { 11, 12, 13, 14 };
const int32_t kValues[] = { 200, 201, 202, 203 };
GPBInt32Int32Dictionary *dict =
- [[GPBInt32Int32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt32Int32Dictionary alloc] initWithInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
int32_t value;
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:11]);
+ XCTAssertTrue([dict getInt32:&value forKey:11]);
XCTAssertEqual(value, 200);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:12]);
+ XCTAssertTrue([dict getInt32:&value forKey:12]);
XCTAssertEqual(value, 201);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:13]);
+ XCTAssertTrue([dict getInt32:&value forKey:13]);
XCTAssertEqual(value, 202);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:14]);
+ XCTAssertTrue([dict getInt32:&value forKey:14]);
XCTAssertEqual(value, 203);
- [dict setValue:203 forKey:11];
+ [dict setInt32:203 forKey:11];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:11]);
+ XCTAssertTrue([dict getInt32:&value forKey:11]);
XCTAssertEqual(value, 203);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:12]);
+ XCTAssertTrue([dict getInt32:&value forKey:12]);
XCTAssertEqual(value, 201);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:13]);
+ XCTAssertTrue([dict getInt32:&value forKey:13]);
XCTAssertEqual(value, 202);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:14]);
+ XCTAssertTrue([dict getInt32:&value forKey:14]);
XCTAssertEqual(value, 203);
- [dict setValue:201 forKey:14];
+ [dict setInt32:201 forKey:14];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:11]);
+ XCTAssertTrue([dict getInt32:&value forKey:11]);
XCTAssertEqual(value, 203);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:12]);
+ XCTAssertTrue([dict getInt32:&value forKey:12]);
XCTAssertEqual(value, 201);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:13]);
+ XCTAssertTrue([dict getInt32:&value forKey:13]);
XCTAssertEqual(value, 202);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:14]);
+ XCTAssertTrue([dict getInt32:&value forKey:14]);
XCTAssertEqual(value, 201);
const int32_t kKeys2[] = { 12, 13 };
const int32_t kValues2[] = { 202, 200 };
GPBInt32Int32Dictionary *dict2 =
- [[GPBInt32Int32Dictionary alloc] initWithValues:kValues2
+ [[GPBInt32Int32Dictionary alloc] initWithInt32s:kValues2
forKeys:kKeys2
count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:11]);
+ XCTAssertTrue([dict getInt32:&value forKey:11]);
XCTAssertEqual(value, 203);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:12]);
+ XCTAssertTrue([dict getInt32:&value forKey:12]);
XCTAssertEqual(value, 202);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:13]);
+ XCTAssertTrue([dict getInt32:&value forKey:13]);
XCTAssertEqual(value, 200);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:14]);
+ XCTAssertTrue([dict getInt32:&value forKey:14]);
XCTAssertEqual(value, 201);
[dict2 release];
@@ -808,8 +808,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
GPBInt32UInt64Dictionary *dict = [[GPBInt32UInt64Dictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:11 value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(int32_t aKey, uint64_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getUInt64:NULL forKey:11]);
+ [dict enumerateKeysAndUInt64sUsingBlock:^(int32_t aKey, uint64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -817,15 +817,15 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testOne {
- GPBInt32UInt64Dictionary *dict = [GPBInt32UInt64Dictionary dictionaryWithValue:300U forKey:11];
+ GPBInt32UInt64Dictionary *dict = [GPBInt32UInt64Dictionary dictionaryWithUInt64:300U forKey:11];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
uint64_t value;
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:11]);
+ XCTAssertTrue([dict getUInt64:&value forKey:11]);
XCTAssertEqual(value, 300U);
- XCTAssertFalse([dict valueForKey:12 value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(int32_t aKey, uint64_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getUInt64:NULL forKey:12]);
+ [dict enumerateKeysAndUInt64sUsingBlock:^(int32_t aKey, uint64_t aValue, BOOL *stop) {
XCTAssertEqual(aKey, 11);
XCTAssertEqual(aValue, 300U);
XCTAssertNotEqual(stop, NULL);
@@ -836,27 +836,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kKeys[] = { 11, 12, 13 };
const uint64_t kValues[] = { 300U, 301U, 302U };
GPBInt32UInt64Dictionary *dict =
- [[GPBInt32UInt64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt32UInt64Dictionary alloc] initWithUInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 3U);
uint64_t value;
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:11]);
+ XCTAssertTrue([dict getUInt64:&value forKey:11]);
XCTAssertEqual(value, 300U);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:12]);
+ XCTAssertTrue([dict getUInt64:&value forKey:12]);
XCTAssertEqual(value, 301U);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:13]);
+ XCTAssertTrue([dict getUInt64:&value forKey:13]);
XCTAssertEqual(value, 302U);
- XCTAssertFalse([dict valueForKey:14 value:NULL]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:14]);
__block NSUInteger idx = 0;
int32_t *seenKeys = malloc(3 * sizeof(int32_t));
uint64_t *seenValues = malloc(3 * sizeof(uint64_t));
- [dict enumerateKeysAndValuesUsingBlock:^(int32_t aKey, uint64_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndUInt64sUsingBlock:^(int32_t aKey, uint64_t aValue, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -878,7 +878,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(int32_t aKey, uint64_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndUInt64sUsingBlock:^(int32_t aKey, uint64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -894,29 +894,29 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint64_t kValues2[] = { 300U, 303U, 302U };
const uint64_t kValues3[] = { 300U, 301U, 302U, 303U };
GPBInt32UInt64Dictionary *dict1 =
- [[GPBInt32UInt64Dictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBInt32UInt64Dictionary alloc] initWithUInt64s:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBInt32UInt64Dictionary *dict1prime =
- [[GPBInt32UInt64Dictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBInt32UInt64Dictionary alloc] initWithUInt64s:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBInt32UInt64Dictionary *dict2 =
- [[GPBInt32UInt64Dictionary alloc] initWithValues:kValues2
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBInt32UInt64Dictionary alloc] initWithUInt64s:kValues2
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBInt32UInt64Dictionary *dict3 =
- [[GPBInt32UInt64Dictionary alloc] initWithValues:kValues1
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBInt32UInt64Dictionary alloc] initWithUInt64s:kValues1
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBInt32UInt64Dictionary *dict4 =
- [[GPBInt32UInt64Dictionary alloc] initWithValues:kValues3
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues3)];
+ [[GPBInt32UInt64Dictionary alloc] initWithUInt64s:kValues3
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
// 1/1Prime should be different objects, but equal.
@@ -945,9 +945,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kKeys[] = { 11, 12, 13, 14 };
const uint64_t kValues[] = { 300U, 301U, 302U, 303U };
GPBInt32UInt64Dictionary *dict =
- [[GPBInt32UInt64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt32UInt64Dictionary alloc] initWithUInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBInt32UInt64Dictionary *dict2 = [dict copy];
@@ -966,9 +966,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kKeys[] = { 11, 12, 13, 14 };
const uint64_t kValues[] = { 300U, 301U, 302U, 303U };
GPBInt32UInt64Dictionary *dict =
- [[GPBInt32UInt64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt32UInt64Dictionary alloc] initWithUInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBInt32UInt64Dictionary *dict2 =
@@ -986,31 +986,31 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:300U forKey:11];
+ [dict setUInt64:300U forKey:11];
XCTAssertEqual(dict.count, 1U);
const int32_t kKeys[] = { 12, 13, 14 };
const uint64_t kValues[] = { 301U, 302U, 303U };
GPBInt32UInt64Dictionary *dict2 =
- [[GPBInt32UInt64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt32UInt64Dictionary alloc] initWithUInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
uint64_t value;
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:11]);
+ XCTAssertTrue([dict getUInt64:&value forKey:11]);
XCTAssertEqual(value, 300U);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:12]);
+ XCTAssertTrue([dict getUInt64:&value forKey:12]);
XCTAssertEqual(value, 301U);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:13]);
+ XCTAssertTrue([dict getUInt64:&value forKey:13]);
XCTAssertEqual(value, 302U);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:14]);
+ XCTAssertTrue([dict getUInt64:&value forKey:14]);
XCTAssertEqual(value, 303U);
[dict2 release];
}
@@ -1019,57 +1019,57 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kKeys[] = { 11, 12, 13, 14 };
const uint64_t kValues[] = { 300U, 301U, 302U, 303U };
GPBInt32UInt64Dictionary *dict =
- [[GPBInt32UInt64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt32UInt64Dictionary alloc] initWithUInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
- [dict removeValueForKey:12];
+ [dict removeUInt64ForKey:12];
XCTAssertEqual(dict.count, 3U);
uint64_t value;
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:11]);
+ XCTAssertTrue([dict getUInt64:&value forKey:11]);
XCTAssertEqual(value, 300U);
- XCTAssertFalse([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:12]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:13]);
+ XCTAssertTrue([dict getUInt64:&value forKey:13]);
XCTAssertEqual(value, 302U);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:14]);
+ XCTAssertTrue([dict getUInt64:&value forKey:14]);
XCTAssertEqual(value, 303U);
// Remove again does nothing.
- [dict removeValueForKey:12];
+ [dict removeUInt64ForKey:12];
XCTAssertEqual(dict.count, 3U);
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:11]);
+ XCTAssertTrue([dict getUInt64:&value forKey:11]);
XCTAssertEqual(value, 300U);
- XCTAssertFalse([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:12]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:13]);
+ XCTAssertTrue([dict getUInt64:&value forKey:13]);
XCTAssertEqual(value, 302U);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:14]);
+ XCTAssertTrue([dict getUInt64:&value forKey:14]);
XCTAssertEqual(value, 303U);
- [dict removeValueForKey:14];
+ [dict removeUInt64ForKey:14];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:11]);
+ XCTAssertTrue([dict getUInt64:&value forKey:11]);
XCTAssertEqual(value, 300U);
- XCTAssertFalse([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:12]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:13]);
+ XCTAssertTrue([dict getUInt64:&value forKey:13]);
XCTAssertEqual(value, 302U);
- XCTAssertFalse([dict valueForKey:14 value:NULL]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:14]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:11 value:NULL]);
- XCTAssertFalse([dict valueForKey:12 value:NULL]);
- XCTAssertFalse([dict valueForKey:13 value:NULL]);
- XCTAssertFalse([dict valueForKey:14 value:NULL]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:11]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:12]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:13]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:14]);
[dict release];
}
@@ -1077,75 +1077,75 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kKeys[] = { 11, 12, 13, 14 };
const uint64_t kValues[] = { 300U, 301U, 302U, 303U };
GPBInt32UInt64Dictionary *dict =
- [[GPBInt32UInt64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt32UInt64Dictionary alloc] initWithUInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
uint64_t value;
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:11]);
+ XCTAssertTrue([dict getUInt64:&value forKey:11]);
XCTAssertEqual(value, 300U);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:12]);
+ XCTAssertTrue([dict getUInt64:&value forKey:12]);
XCTAssertEqual(value, 301U);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:13]);
+ XCTAssertTrue([dict getUInt64:&value forKey:13]);
XCTAssertEqual(value, 302U);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:14]);
+ XCTAssertTrue([dict getUInt64:&value forKey:14]);
XCTAssertEqual(value, 303U);
- [dict setValue:303U forKey:11];
+ [dict setUInt64:303U forKey:11];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:11]);
+ XCTAssertTrue([dict getUInt64:&value forKey:11]);
XCTAssertEqual(value, 303U);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:12]);
+ XCTAssertTrue([dict getUInt64:&value forKey:12]);
XCTAssertEqual(value, 301U);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:13]);
+ XCTAssertTrue([dict getUInt64:&value forKey:13]);
XCTAssertEqual(value, 302U);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:14]);
+ XCTAssertTrue([dict getUInt64:&value forKey:14]);
XCTAssertEqual(value, 303U);
- [dict setValue:301U forKey:14];
+ [dict setUInt64:301U forKey:14];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:11]);
+ XCTAssertTrue([dict getUInt64:&value forKey:11]);
XCTAssertEqual(value, 303U);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:12]);
+ XCTAssertTrue([dict getUInt64:&value forKey:12]);
XCTAssertEqual(value, 301U);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:13]);
+ XCTAssertTrue([dict getUInt64:&value forKey:13]);
XCTAssertEqual(value, 302U);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:14]);
+ XCTAssertTrue([dict getUInt64:&value forKey:14]);
XCTAssertEqual(value, 301U);
const int32_t kKeys2[] = { 12, 13 };
const uint64_t kValues2[] = { 302U, 300U };
GPBInt32UInt64Dictionary *dict2 =
- [[GPBInt32UInt64Dictionary alloc] initWithValues:kValues2
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBInt32UInt64Dictionary alloc] initWithUInt64s:kValues2
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:11]);
+ XCTAssertTrue([dict getUInt64:&value forKey:11]);
XCTAssertEqual(value, 303U);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:12]);
+ XCTAssertTrue([dict getUInt64:&value forKey:12]);
XCTAssertEqual(value, 302U);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:13]);
+ XCTAssertTrue([dict getUInt64:&value forKey:13]);
XCTAssertEqual(value, 300U);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:14]);
+ XCTAssertTrue([dict getUInt64:&value forKey:14]);
XCTAssertEqual(value, 301U);
[dict2 release];
@@ -1165,8 +1165,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
GPBInt32Int64Dictionary *dict = [[GPBInt32Int64Dictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:11 value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(int32_t aKey, int64_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getInt64:NULL forKey:11]);
+ [dict enumerateKeysAndInt64sUsingBlock:^(int32_t aKey, int64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -1174,15 +1174,15 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testOne {
- GPBInt32Int64Dictionary *dict = [GPBInt32Int64Dictionary dictionaryWithValue:400 forKey:11];
+ GPBInt32Int64Dictionary *dict = [GPBInt32Int64Dictionary dictionaryWithInt64:400 forKey:11];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
int64_t value;
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:11]);
+ XCTAssertTrue([dict getInt64:&value forKey:11]);
XCTAssertEqual(value, 400);
- XCTAssertFalse([dict valueForKey:12 value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(int32_t aKey, int64_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getInt64:NULL forKey:12]);
+ [dict enumerateKeysAndInt64sUsingBlock:^(int32_t aKey, int64_t aValue, BOOL *stop) {
XCTAssertEqual(aKey, 11);
XCTAssertEqual(aValue, 400);
XCTAssertNotEqual(stop, NULL);
@@ -1193,27 +1193,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kKeys[] = { 11, 12, 13 };
const int64_t kValues[] = { 400, 401, 402 };
GPBInt32Int64Dictionary *dict =
- [[GPBInt32Int64Dictionary alloc] initWithValues:kValues
+ [[GPBInt32Int64Dictionary alloc] initWithInt64s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 3U);
int64_t value;
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:11]);
+ XCTAssertTrue([dict getInt64:&value forKey:11]);
XCTAssertEqual(value, 400);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:12]);
+ XCTAssertTrue([dict getInt64:&value forKey:12]);
XCTAssertEqual(value, 401);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:13]);
+ XCTAssertTrue([dict getInt64:&value forKey:13]);
XCTAssertEqual(value, 402);
- XCTAssertFalse([dict valueForKey:14 value:NULL]);
+ XCTAssertFalse([dict getInt64:NULL forKey:14]);
__block NSUInteger idx = 0;
int32_t *seenKeys = malloc(3 * sizeof(int32_t));
int64_t *seenValues = malloc(3 * sizeof(int64_t));
- [dict enumerateKeysAndValuesUsingBlock:^(int32_t aKey, int64_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndInt64sUsingBlock:^(int32_t aKey, int64_t aValue, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -1235,7 +1235,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(int32_t aKey, int64_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndInt64sUsingBlock:^(int32_t aKey, int64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -1251,27 +1251,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int64_t kValues2[] = { 400, 403, 402 };
const int64_t kValues3[] = { 400, 401, 402, 403 };
GPBInt32Int64Dictionary *dict1 =
- [[GPBInt32Int64Dictionary alloc] initWithValues:kValues1
+ [[GPBInt32Int64Dictionary alloc] initWithInt64s:kValues1
forKeys:kKeys1
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBInt32Int64Dictionary *dict1prime =
- [[GPBInt32Int64Dictionary alloc] initWithValues:kValues1
+ [[GPBInt32Int64Dictionary alloc] initWithInt64s:kValues1
forKeys:kKeys1
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBInt32Int64Dictionary *dict2 =
- [[GPBInt32Int64Dictionary alloc] initWithValues:kValues2
+ [[GPBInt32Int64Dictionary alloc] initWithInt64s:kValues2
forKeys:kKeys1
count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBInt32Int64Dictionary *dict3 =
- [[GPBInt32Int64Dictionary alloc] initWithValues:kValues1
+ [[GPBInt32Int64Dictionary alloc] initWithInt64s:kValues1
forKeys:kKeys2
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBInt32Int64Dictionary *dict4 =
- [[GPBInt32Int64Dictionary alloc] initWithValues:kValues3
+ [[GPBInt32Int64Dictionary alloc] initWithInt64s:kValues3
forKeys:kKeys1
count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
@@ -1302,7 +1302,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kKeys[] = { 11, 12, 13, 14 };
const int64_t kValues[] = { 400, 401, 402, 403 };
GPBInt32Int64Dictionary *dict =
- [[GPBInt32Int64Dictionary alloc] initWithValues:kValues
+ [[GPBInt32Int64Dictionary alloc] initWithInt64s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
@@ -1323,7 +1323,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kKeys[] = { 11, 12, 13, 14 };
const int64_t kValues[] = { 400, 401, 402, 403 };
GPBInt32Int64Dictionary *dict =
- [[GPBInt32Int64Dictionary alloc] initWithValues:kValues
+ [[GPBInt32Int64Dictionary alloc] initWithInt64s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
@@ -1343,13 +1343,13 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:400 forKey:11];
+ [dict setInt64:400 forKey:11];
XCTAssertEqual(dict.count, 1U);
const int32_t kKeys[] = { 12, 13, 14 };
const int64_t kValues[] = { 401, 402, 403 };
GPBInt32Int64Dictionary *dict2 =
- [[GPBInt32Int64Dictionary alloc] initWithValues:kValues
+ [[GPBInt32Int64Dictionary alloc] initWithInt64s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
@@ -1357,17 +1357,17 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertEqual(dict.count, 4U);
int64_t value;
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:11]);
+ XCTAssertTrue([dict getInt64:&value forKey:11]);
XCTAssertEqual(value, 400);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:12]);
+ XCTAssertTrue([dict getInt64:&value forKey:12]);
XCTAssertEqual(value, 401);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:13]);
+ XCTAssertTrue([dict getInt64:&value forKey:13]);
XCTAssertEqual(value, 402);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:14]);
+ XCTAssertTrue([dict getInt64:&value forKey:14]);
XCTAssertEqual(value, 403);
[dict2 release];
}
@@ -1376,57 +1376,57 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kKeys[] = { 11, 12, 13, 14 };
const int64_t kValues[] = { 400, 401, 402, 403 };
GPBInt32Int64Dictionary *dict =
- [[GPBInt32Int64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt32Int64Dictionary alloc] initWithInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
- [dict removeValueForKey:12];
+ [dict removeInt64ForKey:12];
XCTAssertEqual(dict.count, 3U);
int64_t value;
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:11]);
+ XCTAssertTrue([dict getInt64:&value forKey:11]);
XCTAssertEqual(value, 400);
- XCTAssertFalse([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertFalse([dict getInt64:NULL forKey:12]);
+ XCTAssertTrue([dict getInt64:NULL forKey:13]);
+ XCTAssertTrue([dict getInt64:&value forKey:13]);
XCTAssertEqual(value, 402);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:14]);
+ XCTAssertTrue([dict getInt64:&value forKey:14]);
XCTAssertEqual(value, 403);
// Remove again does nothing.
- [dict removeValueForKey:12];
+ [dict removeInt64ForKey:12];
XCTAssertEqual(dict.count, 3U);
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:11]);
+ XCTAssertTrue([dict getInt64:&value forKey:11]);
XCTAssertEqual(value, 400);
- XCTAssertFalse([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertFalse([dict getInt64:NULL forKey:12]);
+ XCTAssertTrue([dict getInt64:NULL forKey:13]);
+ XCTAssertTrue([dict getInt64:&value forKey:13]);
XCTAssertEqual(value, 402);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:14]);
+ XCTAssertTrue([dict getInt64:&value forKey:14]);
XCTAssertEqual(value, 403);
- [dict removeValueForKey:14];
+ [dict removeInt64ForKey:14];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:11]);
+ XCTAssertTrue([dict getInt64:&value forKey:11]);
XCTAssertEqual(value, 400);
- XCTAssertFalse([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertFalse([dict getInt64:NULL forKey:12]);
+ XCTAssertTrue([dict getInt64:NULL forKey:13]);
+ XCTAssertTrue([dict getInt64:&value forKey:13]);
XCTAssertEqual(value, 402);
- XCTAssertFalse([dict valueForKey:14 value:NULL]);
+ XCTAssertFalse([dict getInt64:NULL forKey:14]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:11 value:NULL]);
- XCTAssertFalse([dict valueForKey:12 value:NULL]);
- XCTAssertFalse([dict valueForKey:13 value:NULL]);
- XCTAssertFalse([dict valueForKey:14 value:NULL]);
+ XCTAssertFalse([dict getInt64:NULL forKey:11]);
+ XCTAssertFalse([dict getInt64:NULL forKey:12]);
+ XCTAssertFalse([dict getInt64:NULL forKey:13]);
+ XCTAssertFalse([dict getInt64:NULL forKey:14]);
[dict release];
}
@@ -1434,75 +1434,75 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kKeys[] = { 11, 12, 13, 14 };
const int64_t kValues[] = { 400, 401, 402, 403 };
GPBInt32Int64Dictionary *dict =
- [[GPBInt32Int64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt32Int64Dictionary alloc] initWithInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
int64_t value;
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:11]);
+ XCTAssertTrue([dict getInt64:&value forKey:11]);
XCTAssertEqual(value, 400);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:12]);
+ XCTAssertTrue([dict getInt64:&value forKey:12]);
XCTAssertEqual(value, 401);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:13]);
+ XCTAssertTrue([dict getInt64:&value forKey:13]);
XCTAssertEqual(value, 402);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:14]);
+ XCTAssertTrue([dict getInt64:&value forKey:14]);
XCTAssertEqual(value, 403);
- [dict setValue:403 forKey:11];
+ [dict setInt64:403 forKey:11];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:11]);
+ XCTAssertTrue([dict getInt64:&value forKey:11]);
XCTAssertEqual(value, 403);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:12]);
+ XCTAssertTrue([dict getInt64:&value forKey:12]);
XCTAssertEqual(value, 401);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:13]);
+ XCTAssertTrue([dict getInt64:&value forKey:13]);
XCTAssertEqual(value, 402);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:14]);
+ XCTAssertTrue([dict getInt64:&value forKey:14]);
XCTAssertEqual(value, 403);
- [dict setValue:401 forKey:14];
+ [dict setInt64:401 forKey:14];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:11]);
+ XCTAssertTrue([dict getInt64:&value forKey:11]);
XCTAssertEqual(value, 403);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:12]);
+ XCTAssertTrue([dict getInt64:&value forKey:12]);
XCTAssertEqual(value, 401);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:13]);
+ XCTAssertTrue([dict getInt64:&value forKey:13]);
XCTAssertEqual(value, 402);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:14]);
+ XCTAssertTrue([dict getInt64:&value forKey:14]);
XCTAssertEqual(value, 401);
const int32_t kKeys2[] = { 12, 13 };
const int64_t kValues2[] = { 402, 400 };
GPBInt32Int64Dictionary *dict2 =
- [[GPBInt32Int64Dictionary alloc] initWithValues:kValues2
+ [[GPBInt32Int64Dictionary alloc] initWithInt64s:kValues2
forKeys:kKeys2
count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:11]);
+ XCTAssertTrue([dict getInt64:&value forKey:11]);
XCTAssertEqual(value, 403);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:12]);
+ XCTAssertTrue([dict getInt64:&value forKey:12]);
XCTAssertEqual(value, 402);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:13]);
+ XCTAssertTrue([dict getInt64:&value forKey:13]);
XCTAssertEqual(value, 400);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:14]);
+ XCTAssertTrue([dict getInt64:&value forKey:14]);
XCTAssertEqual(value, 401);
[dict2 release];
@@ -1522,8 +1522,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
GPBInt32BoolDictionary *dict = [[GPBInt32BoolDictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:11 value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(int32_t aKey, BOOL aValue, BOOL *stop) {
+ XCTAssertFalse([dict getBool:NULL forKey:11]);
+ [dict enumerateKeysAndBoolsUsingBlock:^(int32_t aKey, BOOL aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -1531,15 +1531,15 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testOne {
- GPBInt32BoolDictionary *dict = [GPBInt32BoolDictionary dictionaryWithValue:YES forKey:11];
+ GPBInt32BoolDictionary *dict = [GPBInt32BoolDictionary dictionaryWithBool:YES forKey:11];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
BOOL value;
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:11]);
+ XCTAssertTrue([dict getBool:&value forKey:11]);
XCTAssertEqual(value, YES);
- XCTAssertFalse([dict valueForKey:12 value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(int32_t aKey, BOOL aValue, BOOL *stop) {
+ XCTAssertFalse([dict getBool:NULL forKey:12]);
+ [dict enumerateKeysAndBoolsUsingBlock:^(int32_t aKey, BOOL aValue, BOOL *stop) {
XCTAssertEqual(aKey, 11);
XCTAssertEqual(aValue, YES);
XCTAssertNotEqual(stop, NULL);
@@ -1550,27 +1550,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kKeys[] = { 11, 12, 13 };
const BOOL kValues[] = { YES, YES, NO };
GPBInt32BoolDictionary *dict =
- [[GPBInt32BoolDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt32BoolDictionary alloc] initWithBools:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 3U);
BOOL value;
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:11]);
+ XCTAssertTrue([dict getBool:&value forKey:11]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:12]);
+ XCTAssertTrue([dict getBool:&value forKey:12]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:13]);
+ XCTAssertTrue([dict getBool:&value forKey:13]);
XCTAssertEqual(value, NO);
- XCTAssertFalse([dict valueForKey:14 value:NULL]);
+ XCTAssertFalse([dict getBool:NULL forKey:14]);
__block NSUInteger idx = 0;
int32_t *seenKeys = malloc(3 * sizeof(int32_t));
BOOL *seenValues = malloc(3 * sizeof(BOOL));
- [dict enumerateKeysAndValuesUsingBlock:^(int32_t aKey, BOOL aValue, BOOL *stop) {
+ [dict enumerateKeysAndBoolsUsingBlock:^(int32_t aKey, BOOL aValue, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -1592,7 +1592,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(int32_t aKey, BOOL aValue, BOOL *stop) {
+ [dict enumerateKeysAndBoolsUsingBlock:^(int32_t aKey, BOOL aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -1608,29 +1608,29 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const BOOL kValues2[] = { YES, NO, NO };
const BOOL kValues3[] = { YES, YES, NO, NO };
GPBInt32BoolDictionary *dict1 =
- [[GPBInt32BoolDictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBInt32BoolDictionary alloc] initWithBools:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBInt32BoolDictionary *dict1prime =
- [[GPBInt32BoolDictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBInt32BoolDictionary alloc] initWithBools:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBInt32BoolDictionary *dict2 =
- [[GPBInt32BoolDictionary alloc] initWithValues:kValues2
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBInt32BoolDictionary alloc] initWithBools:kValues2
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBInt32BoolDictionary *dict3 =
- [[GPBInt32BoolDictionary alloc] initWithValues:kValues1
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBInt32BoolDictionary alloc] initWithBools:kValues1
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBInt32BoolDictionary *dict4 =
- [[GPBInt32BoolDictionary alloc] initWithValues:kValues3
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues3)];
+ [[GPBInt32BoolDictionary alloc] initWithBools:kValues3
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
// 1/1Prime should be different objects, but equal.
@@ -1659,9 +1659,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kKeys[] = { 11, 12, 13, 14 };
const BOOL kValues[] = { YES, YES, NO, NO };
GPBInt32BoolDictionary *dict =
- [[GPBInt32BoolDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt32BoolDictionary alloc] initWithBools:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBInt32BoolDictionary *dict2 = [dict copy];
@@ -1680,9 +1680,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kKeys[] = { 11, 12, 13, 14 };
const BOOL kValues[] = { YES, YES, NO, NO };
GPBInt32BoolDictionary *dict =
- [[GPBInt32BoolDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt32BoolDictionary alloc] initWithBools:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBInt32BoolDictionary *dict2 =
@@ -1700,31 +1700,31 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:YES forKey:11];
+ [dict setBool:YES forKey:11];
XCTAssertEqual(dict.count, 1U);
const int32_t kKeys[] = { 12, 13, 14 };
const BOOL kValues[] = { YES, NO, NO };
GPBInt32BoolDictionary *dict2 =
- [[GPBInt32BoolDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt32BoolDictionary alloc] initWithBools:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
BOOL value;
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:11]);
+ XCTAssertTrue([dict getBool:&value forKey:11]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:12]);
+ XCTAssertTrue([dict getBool:&value forKey:12]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:13]);
+ XCTAssertTrue([dict getBool:&value forKey:13]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:14]);
+ XCTAssertTrue([dict getBool:&value forKey:14]);
XCTAssertEqual(value, NO);
[dict2 release];
}
@@ -1733,57 +1733,57 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kKeys[] = { 11, 12, 13, 14 };
const BOOL kValues[] = { YES, YES, NO, NO };
GPBInt32BoolDictionary *dict =
- [[GPBInt32BoolDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt32BoolDictionary alloc] initWithBools:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
- [dict removeValueForKey:12];
+ [dict removeBoolForKey:12];
XCTAssertEqual(dict.count, 3U);
BOOL value;
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:11]);
+ XCTAssertTrue([dict getBool:&value forKey:11]);
XCTAssertEqual(value, YES);
- XCTAssertFalse([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertFalse([dict getBool:NULL forKey:12]);
+ XCTAssertTrue([dict getBool:NULL forKey:13]);
+ XCTAssertTrue([dict getBool:&value forKey:13]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:14]);
+ XCTAssertTrue([dict getBool:&value forKey:14]);
XCTAssertEqual(value, NO);
// Remove again does nothing.
- [dict removeValueForKey:12];
+ [dict removeBoolForKey:12];
XCTAssertEqual(dict.count, 3U);
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:11]);
+ XCTAssertTrue([dict getBool:&value forKey:11]);
XCTAssertEqual(value, YES);
- XCTAssertFalse([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertFalse([dict getBool:NULL forKey:12]);
+ XCTAssertTrue([dict getBool:NULL forKey:13]);
+ XCTAssertTrue([dict getBool:&value forKey:13]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:14]);
+ XCTAssertTrue([dict getBool:&value forKey:14]);
XCTAssertEqual(value, NO);
- [dict removeValueForKey:14];
+ [dict removeBoolForKey:14];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:11]);
+ XCTAssertTrue([dict getBool:&value forKey:11]);
XCTAssertEqual(value, YES);
- XCTAssertFalse([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertFalse([dict getBool:NULL forKey:12]);
+ XCTAssertTrue([dict getBool:NULL forKey:13]);
+ XCTAssertTrue([dict getBool:&value forKey:13]);
XCTAssertEqual(value, NO);
- XCTAssertFalse([dict valueForKey:14 value:NULL]);
+ XCTAssertFalse([dict getBool:NULL forKey:14]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:11 value:NULL]);
- XCTAssertFalse([dict valueForKey:12 value:NULL]);
- XCTAssertFalse([dict valueForKey:13 value:NULL]);
- XCTAssertFalse([dict valueForKey:14 value:NULL]);
+ XCTAssertFalse([dict getBool:NULL forKey:11]);
+ XCTAssertFalse([dict getBool:NULL forKey:12]);
+ XCTAssertFalse([dict getBool:NULL forKey:13]);
+ XCTAssertFalse([dict getBool:NULL forKey:14]);
[dict release];
}
@@ -1791,75 +1791,75 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kKeys[] = { 11, 12, 13, 14 };
const BOOL kValues[] = { YES, YES, NO, NO };
GPBInt32BoolDictionary *dict =
- [[GPBInt32BoolDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt32BoolDictionary alloc] initWithBools:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
BOOL value;
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:11]);
+ XCTAssertTrue([dict getBool:&value forKey:11]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:12]);
+ XCTAssertTrue([dict getBool:&value forKey:12]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:13]);
+ XCTAssertTrue([dict getBool:&value forKey:13]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:14]);
+ XCTAssertTrue([dict getBool:&value forKey:14]);
XCTAssertEqual(value, NO);
- [dict setValue:NO forKey:11];
+ [dict setBool:NO forKey:11];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:11]);
+ XCTAssertTrue([dict getBool:&value forKey:11]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:12]);
+ XCTAssertTrue([dict getBool:&value forKey:12]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:13]);
+ XCTAssertTrue([dict getBool:&value forKey:13]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:14]);
+ XCTAssertTrue([dict getBool:&value forKey:14]);
XCTAssertEqual(value, NO);
- [dict setValue:YES forKey:14];
+ [dict setBool:YES forKey:14];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:11]);
+ XCTAssertTrue([dict getBool:&value forKey:11]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:12]);
+ XCTAssertTrue([dict getBool:&value forKey:12]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:13]);
+ XCTAssertTrue([dict getBool:&value forKey:13]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:14]);
+ XCTAssertTrue([dict getBool:&value forKey:14]);
XCTAssertEqual(value, YES);
const int32_t kKeys2[] = { 12, 13 };
const BOOL kValues2[] = { NO, YES };
GPBInt32BoolDictionary *dict2 =
- [[GPBInt32BoolDictionary alloc] initWithValues:kValues2
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBInt32BoolDictionary alloc] initWithBools:kValues2
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:11]);
+ XCTAssertTrue([dict getBool:&value forKey:11]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:12]);
+ XCTAssertTrue([dict getBool:&value forKey:12]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:13]);
+ XCTAssertTrue([dict getBool:&value forKey:13]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:14]);
+ XCTAssertTrue([dict getBool:&value forKey:14]);
XCTAssertEqual(value, YES);
[dict2 release];
@@ -1879,8 +1879,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
GPBInt32FloatDictionary *dict = [[GPBInt32FloatDictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:11 value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(int32_t aKey, float aValue, BOOL *stop) {
+ XCTAssertFalse([dict getFloat:NULL forKey:11]);
+ [dict enumerateKeysAndFloatsUsingBlock:^(int32_t aKey, float aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -1888,15 +1888,15 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testOne {
- GPBInt32FloatDictionary *dict = [GPBInt32FloatDictionary dictionaryWithValue:500.f forKey:11];
+ GPBInt32FloatDictionary *dict = [GPBInt32FloatDictionary dictionaryWithFloat:500.f forKey:11];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
float value;
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:11]);
+ XCTAssertTrue([dict getFloat:&value forKey:11]);
XCTAssertEqual(value, 500.f);
- XCTAssertFalse([dict valueForKey:12 value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(int32_t aKey, float aValue, BOOL *stop) {
+ XCTAssertFalse([dict getFloat:NULL forKey:12]);
+ [dict enumerateKeysAndFloatsUsingBlock:^(int32_t aKey, float aValue, BOOL *stop) {
XCTAssertEqual(aKey, 11);
XCTAssertEqual(aValue, 500.f);
XCTAssertNotEqual(stop, NULL);
@@ -1907,27 +1907,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kKeys[] = { 11, 12, 13 };
const float kValues[] = { 500.f, 501.f, 502.f };
GPBInt32FloatDictionary *dict =
- [[GPBInt32FloatDictionary alloc] initWithValues:kValues
+ [[GPBInt32FloatDictionary alloc] initWithFloats:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 3U);
float value;
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:11]);
+ XCTAssertTrue([dict getFloat:&value forKey:11]);
XCTAssertEqual(value, 500.f);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:12]);
+ XCTAssertTrue([dict getFloat:&value forKey:12]);
XCTAssertEqual(value, 501.f);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:13]);
+ XCTAssertTrue([dict getFloat:&value forKey:13]);
XCTAssertEqual(value, 502.f);
- XCTAssertFalse([dict valueForKey:14 value:NULL]);
+ XCTAssertFalse([dict getFloat:NULL forKey:14]);
__block NSUInteger idx = 0;
int32_t *seenKeys = malloc(3 * sizeof(int32_t));
float *seenValues = malloc(3 * sizeof(float));
- [dict enumerateKeysAndValuesUsingBlock:^(int32_t aKey, float aValue, BOOL *stop) {
+ [dict enumerateKeysAndFloatsUsingBlock:^(int32_t aKey, float aValue, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -1949,7 +1949,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(int32_t aKey, float aValue, BOOL *stop) {
+ [dict enumerateKeysAndFloatsUsingBlock:^(int32_t aKey, float aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -1965,27 +1965,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const float kValues2[] = { 500.f, 503.f, 502.f };
const float kValues3[] = { 500.f, 501.f, 502.f, 503.f };
GPBInt32FloatDictionary *dict1 =
- [[GPBInt32FloatDictionary alloc] initWithValues:kValues1
+ [[GPBInt32FloatDictionary alloc] initWithFloats:kValues1
forKeys:kKeys1
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBInt32FloatDictionary *dict1prime =
- [[GPBInt32FloatDictionary alloc] initWithValues:kValues1
+ [[GPBInt32FloatDictionary alloc] initWithFloats:kValues1
forKeys:kKeys1
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBInt32FloatDictionary *dict2 =
- [[GPBInt32FloatDictionary alloc] initWithValues:kValues2
+ [[GPBInt32FloatDictionary alloc] initWithFloats:kValues2
forKeys:kKeys1
count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBInt32FloatDictionary *dict3 =
- [[GPBInt32FloatDictionary alloc] initWithValues:kValues1
+ [[GPBInt32FloatDictionary alloc] initWithFloats:kValues1
forKeys:kKeys2
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBInt32FloatDictionary *dict4 =
- [[GPBInt32FloatDictionary alloc] initWithValues:kValues3
+ [[GPBInt32FloatDictionary alloc] initWithFloats:kValues3
forKeys:kKeys1
count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
@@ -2016,7 +2016,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kKeys[] = { 11, 12, 13, 14 };
const float kValues[] = { 500.f, 501.f, 502.f, 503.f };
GPBInt32FloatDictionary *dict =
- [[GPBInt32FloatDictionary alloc] initWithValues:kValues
+ [[GPBInt32FloatDictionary alloc] initWithFloats:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
@@ -2037,7 +2037,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kKeys[] = { 11, 12, 13, 14 };
const float kValues[] = { 500.f, 501.f, 502.f, 503.f };
GPBInt32FloatDictionary *dict =
- [[GPBInt32FloatDictionary alloc] initWithValues:kValues
+ [[GPBInt32FloatDictionary alloc] initWithFloats:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
@@ -2057,13 +2057,13 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:500.f forKey:11];
+ [dict setFloat:500.f forKey:11];
XCTAssertEqual(dict.count, 1U);
const int32_t kKeys[] = { 12, 13, 14 };
const float kValues[] = { 501.f, 502.f, 503.f };
GPBInt32FloatDictionary *dict2 =
- [[GPBInt32FloatDictionary alloc] initWithValues:kValues
+ [[GPBInt32FloatDictionary alloc] initWithFloats:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
@@ -2071,17 +2071,17 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertEqual(dict.count, 4U);
float value;
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:11]);
+ XCTAssertTrue([dict getFloat:&value forKey:11]);
XCTAssertEqual(value, 500.f);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:12]);
+ XCTAssertTrue([dict getFloat:&value forKey:12]);
XCTAssertEqual(value, 501.f);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:13]);
+ XCTAssertTrue([dict getFloat:&value forKey:13]);
XCTAssertEqual(value, 502.f);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:14]);
+ XCTAssertTrue([dict getFloat:&value forKey:14]);
XCTAssertEqual(value, 503.f);
[dict2 release];
}
@@ -2090,57 +2090,57 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kKeys[] = { 11, 12, 13, 14 };
const float kValues[] = { 500.f, 501.f, 502.f, 503.f };
GPBInt32FloatDictionary *dict =
- [[GPBInt32FloatDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt32FloatDictionary alloc] initWithFloats:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
- [dict removeValueForKey:12];
+ [dict removeFloatForKey:12];
XCTAssertEqual(dict.count, 3U);
float value;
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:11]);
+ XCTAssertTrue([dict getFloat:&value forKey:11]);
XCTAssertEqual(value, 500.f);
- XCTAssertFalse([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertFalse([dict getFloat:NULL forKey:12]);
+ XCTAssertTrue([dict getFloat:NULL forKey:13]);
+ XCTAssertTrue([dict getFloat:&value forKey:13]);
XCTAssertEqual(value, 502.f);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:14]);
+ XCTAssertTrue([dict getFloat:&value forKey:14]);
XCTAssertEqual(value, 503.f);
// Remove again does nothing.
- [dict removeValueForKey:12];
+ [dict removeFloatForKey:12];
XCTAssertEqual(dict.count, 3U);
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:11]);
+ XCTAssertTrue([dict getFloat:&value forKey:11]);
XCTAssertEqual(value, 500.f);
- XCTAssertFalse([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertFalse([dict getFloat:NULL forKey:12]);
+ XCTAssertTrue([dict getFloat:NULL forKey:13]);
+ XCTAssertTrue([dict getFloat:&value forKey:13]);
XCTAssertEqual(value, 502.f);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:14]);
+ XCTAssertTrue([dict getFloat:&value forKey:14]);
XCTAssertEqual(value, 503.f);
- [dict removeValueForKey:14];
+ [dict removeFloatForKey:14];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:11]);
+ XCTAssertTrue([dict getFloat:&value forKey:11]);
XCTAssertEqual(value, 500.f);
- XCTAssertFalse([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertFalse([dict getFloat:NULL forKey:12]);
+ XCTAssertTrue([dict getFloat:NULL forKey:13]);
+ XCTAssertTrue([dict getFloat:&value forKey:13]);
XCTAssertEqual(value, 502.f);
- XCTAssertFalse([dict valueForKey:14 value:NULL]);
+ XCTAssertFalse([dict getFloat:NULL forKey:14]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:11 value:NULL]);
- XCTAssertFalse([dict valueForKey:12 value:NULL]);
- XCTAssertFalse([dict valueForKey:13 value:NULL]);
- XCTAssertFalse([dict valueForKey:14 value:NULL]);
+ XCTAssertFalse([dict getFloat:NULL forKey:11]);
+ XCTAssertFalse([dict getFloat:NULL forKey:12]);
+ XCTAssertFalse([dict getFloat:NULL forKey:13]);
+ XCTAssertFalse([dict getFloat:NULL forKey:14]);
[dict release];
}
@@ -2148,75 +2148,75 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kKeys[] = { 11, 12, 13, 14 };
const float kValues[] = { 500.f, 501.f, 502.f, 503.f };
GPBInt32FloatDictionary *dict =
- [[GPBInt32FloatDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt32FloatDictionary alloc] initWithFloats:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
float value;
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:11]);
+ XCTAssertTrue([dict getFloat:&value forKey:11]);
XCTAssertEqual(value, 500.f);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:12]);
+ XCTAssertTrue([dict getFloat:&value forKey:12]);
XCTAssertEqual(value, 501.f);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:13]);
+ XCTAssertTrue([dict getFloat:&value forKey:13]);
XCTAssertEqual(value, 502.f);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:14]);
+ XCTAssertTrue([dict getFloat:&value forKey:14]);
XCTAssertEqual(value, 503.f);
- [dict setValue:503.f forKey:11];
+ [dict setFloat:503.f forKey:11];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:11]);
+ XCTAssertTrue([dict getFloat:&value forKey:11]);
XCTAssertEqual(value, 503.f);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:12]);
+ XCTAssertTrue([dict getFloat:&value forKey:12]);
XCTAssertEqual(value, 501.f);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:13]);
+ XCTAssertTrue([dict getFloat:&value forKey:13]);
XCTAssertEqual(value, 502.f);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:14]);
+ XCTAssertTrue([dict getFloat:&value forKey:14]);
XCTAssertEqual(value, 503.f);
- [dict setValue:501.f forKey:14];
+ [dict setFloat:501.f forKey:14];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:11]);
+ XCTAssertTrue([dict getFloat:&value forKey:11]);
XCTAssertEqual(value, 503.f);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:12]);
+ XCTAssertTrue([dict getFloat:&value forKey:12]);
XCTAssertEqual(value, 501.f);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:13]);
+ XCTAssertTrue([dict getFloat:&value forKey:13]);
XCTAssertEqual(value, 502.f);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:14]);
+ XCTAssertTrue([dict getFloat:&value forKey:14]);
XCTAssertEqual(value, 501.f);
const int32_t kKeys2[] = { 12, 13 };
const float kValues2[] = { 502.f, 500.f };
GPBInt32FloatDictionary *dict2 =
- [[GPBInt32FloatDictionary alloc] initWithValues:kValues2
+ [[GPBInt32FloatDictionary alloc] initWithFloats:kValues2
forKeys:kKeys2
count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:11]);
+ XCTAssertTrue([dict getFloat:&value forKey:11]);
XCTAssertEqual(value, 503.f);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:12]);
+ XCTAssertTrue([dict getFloat:&value forKey:12]);
XCTAssertEqual(value, 502.f);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:13]);
+ XCTAssertTrue([dict getFloat:&value forKey:13]);
XCTAssertEqual(value, 500.f);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:14]);
+ XCTAssertTrue([dict getFloat:&value forKey:14]);
XCTAssertEqual(value, 501.f);
[dict2 release];
@@ -2236,8 +2236,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
GPBInt32DoubleDictionary *dict = [[GPBInt32DoubleDictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:11 value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(int32_t aKey, double aValue, BOOL *stop) {
+ XCTAssertFalse([dict getDouble:NULL forKey:11]);
+ [dict enumerateKeysAndDoublesUsingBlock:^(int32_t aKey, double aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -2245,15 +2245,15 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testOne {
- GPBInt32DoubleDictionary *dict = [GPBInt32DoubleDictionary dictionaryWithValue:600. forKey:11];
+ GPBInt32DoubleDictionary *dict = [GPBInt32DoubleDictionary dictionaryWithDouble:600. forKey:11];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
double value;
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:11]);
+ XCTAssertTrue([dict getDouble:&value forKey:11]);
XCTAssertEqual(value, 600.);
- XCTAssertFalse([dict valueForKey:12 value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(int32_t aKey, double aValue, BOOL *stop) {
+ XCTAssertFalse([dict getDouble:NULL forKey:12]);
+ [dict enumerateKeysAndDoublesUsingBlock:^(int32_t aKey, double aValue, BOOL *stop) {
XCTAssertEqual(aKey, 11);
XCTAssertEqual(aValue, 600.);
XCTAssertNotEqual(stop, NULL);
@@ -2264,27 +2264,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kKeys[] = { 11, 12, 13 };
const double kValues[] = { 600., 601., 602. };
GPBInt32DoubleDictionary *dict =
- [[GPBInt32DoubleDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt32DoubleDictionary alloc] initWithDoubles:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 3U);
double value;
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:11]);
+ XCTAssertTrue([dict getDouble:&value forKey:11]);
XCTAssertEqual(value, 600.);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:12]);
+ XCTAssertTrue([dict getDouble:&value forKey:12]);
XCTAssertEqual(value, 601.);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:13]);
+ XCTAssertTrue([dict getDouble:&value forKey:13]);
XCTAssertEqual(value, 602.);
- XCTAssertFalse([dict valueForKey:14 value:NULL]);
+ XCTAssertFalse([dict getDouble:NULL forKey:14]);
__block NSUInteger idx = 0;
int32_t *seenKeys = malloc(3 * sizeof(int32_t));
double *seenValues = malloc(3 * sizeof(double));
- [dict enumerateKeysAndValuesUsingBlock:^(int32_t aKey, double aValue, BOOL *stop) {
+ [dict enumerateKeysAndDoublesUsingBlock:^(int32_t aKey, double aValue, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -2306,7 +2306,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(int32_t aKey, double aValue, BOOL *stop) {
+ [dict enumerateKeysAndDoublesUsingBlock:^(int32_t aKey, double aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -2322,29 +2322,29 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const double kValues2[] = { 600., 603., 602. };
const double kValues3[] = { 600., 601., 602., 603. };
GPBInt32DoubleDictionary *dict1 =
- [[GPBInt32DoubleDictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBInt32DoubleDictionary alloc] initWithDoubles:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBInt32DoubleDictionary *dict1prime =
- [[GPBInt32DoubleDictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBInt32DoubleDictionary alloc] initWithDoubles:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBInt32DoubleDictionary *dict2 =
- [[GPBInt32DoubleDictionary alloc] initWithValues:kValues2
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBInt32DoubleDictionary alloc] initWithDoubles:kValues2
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBInt32DoubleDictionary *dict3 =
- [[GPBInt32DoubleDictionary alloc] initWithValues:kValues1
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBInt32DoubleDictionary alloc] initWithDoubles:kValues1
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBInt32DoubleDictionary *dict4 =
- [[GPBInt32DoubleDictionary alloc] initWithValues:kValues3
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues3)];
+ [[GPBInt32DoubleDictionary alloc] initWithDoubles:kValues3
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
// 1/1Prime should be different objects, but equal.
@@ -2373,9 +2373,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kKeys[] = { 11, 12, 13, 14 };
const double kValues[] = { 600., 601., 602., 603. };
GPBInt32DoubleDictionary *dict =
- [[GPBInt32DoubleDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt32DoubleDictionary alloc] initWithDoubles:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBInt32DoubleDictionary *dict2 = [dict copy];
@@ -2394,9 +2394,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kKeys[] = { 11, 12, 13, 14 };
const double kValues[] = { 600., 601., 602., 603. };
GPBInt32DoubleDictionary *dict =
- [[GPBInt32DoubleDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt32DoubleDictionary alloc] initWithDoubles:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBInt32DoubleDictionary *dict2 =
@@ -2414,31 +2414,31 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:600. forKey:11];
+ [dict setDouble:600. forKey:11];
XCTAssertEqual(dict.count, 1U);
const int32_t kKeys[] = { 12, 13, 14 };
const double kValues[] = { 601., 602., 603. };
GPBInt32DoubleDictionary *dict2 =
- [[GPBInt32DoubleDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt32DoubleDictionary alloc] initWithDoubles:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
double value;
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:11]);
+ XCTAssertTrue([dict getDouble:&value forKey:11]);
XCTAssertEqual(value, 600.);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:12]);
+ XCTAssertTrue([dict getDouble:&value forKey:12]);
XCTAssertEqual(value, 601.);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:13]);
+ XCTAssertTrue([dict getDouble:&value forKey:13]);
XCTAssertEqual(value, 602.);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:14]);
+ XCTAssertTrue([dict getDouble:&value forKey:14]);
XCTAssertEqual(value, 603.);
[dict2 release];
}
@@ -2447,57 +2447,57 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kKeys[] = { 11, 12, 13, 14 };
const double kValues[] = { 600., 601., 602., 603. };
GPBInt32DoubleDictionary *dict =
- [[GPBInt32DoubleDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt32DoubleDictionary alloc] initWithDoubles:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
- [dict removeValueForKey:12];
+ [dict removeDoubleForKey:12];
XCTAssertEqual(dict.count, 3U);
double value;
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:11]);
+ XCTAssertTrue([dict getDouble:&value forKey:11]);
XCTAssertEqual(value, 600.);
- XCTAssertFalse([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertFalse([dict getDouble:NULL forKey:12]);
+ XCTAssertTrue([dict getDouble:NULL forKey:13]);
+ XCTAssertTrue([dict getDouble:&value forKey:13]);
XCTAssertEqual(value, 602.);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:14]);
+ XCTAssertTrue([dict getDouble:&value forKey:14]);
XCTAssertEqual(value, 603.);
// Remove again does nothing.
- [dict removeValueForKey:12];
+ [dict removeDoubleForKey:12];
XCTAssertEqual(dict.count, 3U);
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:11]);
+ XCTAssertTrue([dict getDouble:&value forKey:11]);
XCTAssertEqual(value, 600.);
- XCTAssertFalse([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertFalse([dict getDouble:NULL forKey:12]);
+ XCTAssertTrue([dict getDouble:NULL forKey:13]);
+ XCTAssertTrue([dict getDouble:&value forKey:13]);
XCTAssertEqual(value, 602.);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:14]);
+ XCTAssertTrue([dict getDouble:&value forKey:14]);
XCTAssertEqual(value, 603.);
- [dict removeValueForKey:14];
+ [dict removeDoubleForKey:14];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:11]);
+ XCTAssertTrue([dict getDouble:&value forKey:11]);
XCTAssertEqual(value, 600.);
- XCTAssertFalse([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertFalse([dict getDouble:NULL forKey:12]);
+ XCTAssertTrue([dict getDouble:NULL forKey:13]);
+ XCTAssertTrue([dict getDouble:&value forKey:13]);
XCTAssertEqual(value, 602.);
- XCTAssertFalse([dict valueForKey:14 value:NULL]);
+ XCTAssertFalse([dict getDouble:NULL forKey:14]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:11 value:NULL]);
- XCTAssertFalse([dict valueForKey:12 value:NULL]);
- XCTAssertFalse([dict valueForKey:13 value:NULL]);
- XCTAssertFalse([dict valueForKey:14 value:NULL]);
+ XCTAssertFalse([dict getDouble:NULL forKey:11]);
+ XCTAssertFalse([dict getDouble:NULL forKey:12]);
+ XCTAssertFalse([dict getDouble:NULL forKey:13]);
+ XCTAssertFalse([dict getDouble:NULL forKey:14]);
[dict release];
}
@@ -2505,75 +2505,75 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kKeys[] = { 11, 12, 13, 14 };
const double kValues[] = { 600., 601., 602., 603. };
GPBInt32DoubleDictionary *dict =
- [[GPBInt32DoubleDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt32DoubleDictionary alloc] initWithDoubles:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
double value;
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:11]);
+ XCTAssertTrue([dict getDouble:&value forKey:11]);
XCTAssertEqual(value, 600.);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:12]);
+ XCTAssertTrue([dict getDouble:&value forKey:12]);
XCTAssertEqual(value, 601.);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:13]);
+ XCTAssertTrue([dict getDouble:&value forKey:13]);
XCTAssertEqual(value, 602.);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:14]);
+ XCTAssertTrue([dict getDouble:&value forKey:14]);
XCTAssertEqual(value, 603.);
- [dict setValue:603. forKey:11];
+ [dict setDouble:603. forKey:11];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:11]);
+ XCTAssertTrue([dict getDouble:&value forKey:11]);
XCTAssertEqual(value, 603.);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:12]);
+ XCTAssertTrue([dict getDouble:&value forKey:12]);
XCTAssertEqual(value, 601.);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:13]);
+ XCTAssertTrue([dict getDouble:&value forKey:13]);
XCTAssertEqual(value, 602.);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:14]);
+ XCTAssertTrue([dict getDouble:&value forKey:14]);
XCTAssertEqual(value, 603.);
- [dict setValue:601. forKey:14];
+ [dict setDouble:601. forKey:14];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:11]);
+ XCTAssertTrue([dict getDouble:&value forKey:11]);
XCTAssertEqual(value, 603.);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:12]);
+ XCTAssertTrue([dict getDouble:&value forKey:12]);
XCTAssertEqual(value, 601.);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:13]);
+ XCTAssertTrue([dict getDouble:&value forKey:13]);
XCTAssertEqual(value, 602.);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:14]);
+ XCTAssertTrue([dict getDouble:&value forKey:14]);
XCTAssertEqual(value, 601.);
const int32_t kKeys2[] = { 12, 13 };
const double kValues2[] = { 602., 600. };
GPBInt32DoubleDictionary *dict2 =
- [[GPBInt32DoubleDictionary alloc] initWithValues:kValues2
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBInt32DoubleDictionary alloc] initWithDoubles:kValues2
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:11]);
+ XCTAssertTrue([dict getDouble:&value forKey:11]);
XCTAssertEqual(value, 603.);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:12]);
+ XCTAssertTrue([dict getDouble:&value forKey:12]);
XCTAssertEqual(value, 602.);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:13]);
+ XCTAssertTrue([dict getDouble:&value forKey:13]);
XCTAssertEqual(value, 600.);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:14]);
+ XCTAssertTrue([dict getDouble:&value forKey:14]);
XCTAssertEqual(value, 601.);
[dict2 release];
@@ -2593,8 +2593,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
GPBInt32EnumDictionary *dict = [[GPBInt32EnumDictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:11 value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(int32_t aKey, int32_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getEnum:NULL forKey:11]);
+ [dict enumerateKeysAndEnumsUsingBlock:^(int32_t aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -2602,15 +2602,15 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testOne {
- GPBInt32EnumDictionary *dict = [GPBInt32EnumDictionary dictionaryWithValue:700 forKey:11];
+ GPBInt32EnumDictionary *dict = [GPBInt32EnumDictionary dictionaryWithEnum:700 forKey:11];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
int32_t value;
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:11]);
+ XCTAssertTrue([dict getEnum:&value forKey:11]);
XCTAssertEqual(value, 700);
- XCTAssertFalse([dict valueForKey:12 value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(int32_t aKey, int32_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getEnum:NULL forKey:12]);
+ [dict enumerateKeysAndEnumsUsingBlock:^(int32_t aKey, int32_t aValue, BOOL *stop) {
XCTAssertEqual(aKey, 11);
XCTAssertEqual(aValue, 700);
XCTAssertNotEqual(stop, NULL);
@@ -2621,27 +2621,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kKeys[] = { 11, 12, 13 };
const int32_t kValues[] = { 700, 701, 702 };
GPBInt32EnumDictionary *dict =
- [[GPBInt32EnumDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt32EnumDictionary alloc] initWithEnums:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 3U);
int32_t value;
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:11]);
+ XCTAssertTrue([dict getEnum:&value forKey:11]);
XCTAssertEqual(value, 700);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:12]);
+ XCTAssertTrue([dict getEnum:&value forKey:12]);
XCTAssertEqual(value, 701);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:13]);
+ XCTAssertTrue([dict getEnum:&value forKey:13]);
XCTAssertEqual(value, 702);
- XCTAssertFalse([dict valueForKey:14 value:NULL]);
+ XCTAssertFalse([dict getEnum:NULL forKey:14]);
__block NSUInteger idx = 0;
int32_t *seenKeys = malloc(3 * sizeof(int32_t));
int32_t *seenValues = malloc(3 * sizeof(int32_t));
- [dict enumerateKeysAndValuesUsingBlock:^(int32_t aKey, int32_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndEnumsUsingBlock:^(int32_t aKey, int32_t aValue, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -2663,7 +2663,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(int32_t aKey, int32_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndEnumsUsingBlock:^(int32_t aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -2679,29 +2679,29 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kValues2[] = { 700, 703, 702 };
const int32_t kValues3[] = { 700, 701, 702, 703 };
GPBInt32EnumDictionary *dict1 =
- [[GPBInt32EnumDictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBInt32EnumDictionary alloc] initWithEnums:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBInt32EnumDictionary *dict1prime =
- [[GPBInt32EnumDictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBInt32EnumDictionary alloc] initWithEnums:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBInt32EnumDictionary *dict2 =
- [[GPBInt32EnumDictionary alloc] initWithValues:kValues2
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBInt32EnumDictionary alloc] initWithEnums:kValues2
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBInt32EnumDictionary *dict3 =
- [[GPBInt32EnumDictionary alloc] initWithValues:kValues1
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBInt32EnumDictionary alloc] initWithEnums:kValues1
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBInt32EnumDictionary *dict4 =
- [[GPBInt32EnumDictionary alloc] initWithValues:kValues3
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues3)];
+ [[GPBInt32EnumDictionary alloc] initWithEnums:kValues3
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
// 1/1Prime should be different objects, but equal.
@@ -2730,9 +2730,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kKeys[] = { 11, 12, 13, 14 };
const int32_t kValues[] = { 700, 701, 702, 703 };
GPBInt32EnumDictionary *dict =
- [[GPBInt32EnumDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt32EnumDictionary alloc] initWithEnums:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBInt32EnumDictionary *dict2 = [dict copy];
@@ -2751,9 +2751,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kKeys[] = { 11, 12, 13, 14 };
const int32_t kValues[] = { 700, 701, 702, 703 };
GPBInt32EnumDictionary *dict =
- [[GPBInt32EnumDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt32EnumDictionary alloc] initWithEnums:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBInt32EnumDictionary *dict2 =
@@ -2771,31 +2771,31 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:700 forKey:11];
+ [dict setEnum:700 forKey:11];
XCTAssertEqual(dict.count, 1U);
const int32_t kKeys[] = { 12, 13, 14 };
const int32_t kValues[] = { 701, 702, 703 };
GPBInt32EnumDictionary *dict2 =
- [[GPBInt32EnumDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt32EnumDictionary alloc] initWithEnums:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
[dict addRawEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
int32_t value;
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:11]);
+ XCTAssertTrue([dict getEnum:&value forKey:11]);
XCTAssertEqual(value, 700);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:12]);
+ XCTAssertTrue([dict getEnum:&value forKey:12]);
XCTAssertEqual(value, 701);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:13]);
+ XCTAssertTrue([dict getEnum:&value forKey:13]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:14]);
+ XCTAssertTrue([dict getEnum:&value forKey:14]);
XCTAssertEqual(value, 703);
[dict2 release];
}
@@ -2804,57 +2804,57 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kKeys[] = { 11, 12, 13, 14 };
const int32_t kValues[] = { 700, 701, 702, 703 };
GPBInt32EnumDictionary *dict =
- [[GPBInt32EnumDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt32EnumDictionary alloc] initWithEnums:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
- [dict removeValueForKey:12];
+ [dict removeEnumForKey:12];
XCTAssertEqual(dict.count, 3U);
int32_t value;
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:11]);
+ XCTAssertTrue([dict getEnum:&value forKey:11]);
XCTAssertEqual(value, 700);
- XCTAssertFalse([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertFalse([dict getEnum:NULL forKey:12]);
+ XCTAssertTrue([dict getEnum:NULL forKey:13]);
+ XCTAssertTrue([dict getEnum:&value forKey:13]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:14]);
+ XCTAssertTrue([dict getEnum:&value forKey:14]);
XCTAssertEqual(value, 703);
// Remove again does nothing.
- [dict removeValueForKey:12];
+ [dict removeEnumForKey:12];
XCTAssertEqual(dict.count, 3U);
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:11]);
+ XCTAssertTrue([dict getEnum:&value forKey:11]);
XCTAssertEqual(value, 700);
- XCTAssertFalse([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertFalse([dict getEnum:NULL forKey:12]);
+ XCTAssertTrue([dict getEnum:NULL forKey:13]);
+ XCTAssertTrue([dict getEnum:&value forKey:13]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:14]);
+ XCTAssertTrue([dict getEnum:&value forKey:14]);
XCTAssertEqual(value, 703);
- [dict removeValueForKey:14];
+ [dict removeEnumForKey:14];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:11]);
+ XCTAssertTrue([dict getEnum:&value forKey:11]);
XCTAssertEqual(value, 700);
- XCTAssertFalse([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertFalse([dict getEnum:NULL forKey:12]);
+ XCTAssertTrue([dict getEnum:NULL forKey:13]);
+ XCTAssertTrue([dict getEnum:&value forKey:13]);
XCTAssertEqual(value, 702);
- XCTAssertFalse([dict valueForKey:14 value:NULL]);
+ XCTAssertFalse([dict getEnum:NULL forKey:14]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:11 value:NULL]);
- XCTAssertFalse([dict valueForKey:12 value:NULL]);
- XCTAssertFalse([dict valueForKey:13 value:NULL]);
- XCTAssertFalse([dict valueForKey:14 value:NULL]);
+ XCTAssertFalse([dict getEnum:NULL forKey:11]);
+ XCTAssertFalse([dict getEnum:NULL forKey:12]);
+ XCTAssertFalse([dict getEnum:NULL forKey:13]);
+ XCTAssertFalse([dict getEnum:NULL forKey:14]);
[dict release];
}
@@ -2862,75 +2862,75 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kKeys[] = { 11, 12, 13, 14 };
const int32_t kValues[] = { 700, 701, 702, 703 };
GPBInt32EnumDictionary *dict =
- [[GPBInt32EnumDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt32EnumDictionary alloc] initWithEnums:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
int32_t value;
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:11]);
+ XCTAssertTrue([dict getEnum:&value forKey:11]);
XCTAssertEqual(value, 700);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:12]);
+ XCTAssertTrue([dict getEnum:&value forKey:12]);
XCTAssertEqual(value, 701);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:13]);
+ XCTAssertTrue([dict getEnum:&value forKey:13]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:14]);
+ XCTAssertTrue([dict getEnum:&value forKey:14]);
XCTAssertEqual(value, 703);
- [dict setValue:703 forKey:11];
+ [dict setEnum:703 forKey:11];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:11]);
+ XCTAssertTrue([dict getEnum:&value forKey:11]);
XCTAssertEqual(value, 703);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:12]);
+ XCTAssertTrue([dict getEnum:&value forKey:12]);
XCTAssertEqual(value, 701);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:13]);
+ XCTAssertTrue([dict getEnum:&value forKey:13]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:14]);
+ XCTAssertTrue([dict getEnum:&value forKey:14]);
XCTAssertEqual(value, 703);
- [dict setValue:701 forKey:14];
+ [dict setEnum:701 forKey:14];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:11]);
+ XCTAssertTrue([dict getEnum:&value forKey:11]);
XCTAssertEqual(value, 703);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:12]);
+ XCTAssertTrue([dict getEnum:&value forKey:12]);
XCTAssertEqual(value, 701);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:13]);
+ XCTAssertTrue([dict getEnum:&value forKey:13]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:14]);
+ XCTAssertTrue([dict getEnum:&value forKey:14]);
XCTAssertEqual(value, 701);
const int32_t kKeys2[] = { 12, 13 };
const int32_t kValues2[] = { 702, 700 };
GPBInt32EnumDictionary *dict2 =
- [[GPBInt32EnumDictionary alloc] initWithValues:kValues2
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBInt32EnumDictionary alloc] initWithEnums:kValues2
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addRawEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:11]);
+ XCTAssertTrue([dict getEnum:&value forKey:11]);
XCTAssertEqual(value, 703);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:12]);
+ XCTAssertTrue([dict getEnum:&value forKey:12]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:13]);
+ XCTAssertTrue([dict getEnum:&value forKey:13]);
XCTAssertEqual(value, 700);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:14]);
+ XCTAssertTrue([dict getEnum:&value forKey:14]);
XCTAssertEqual(value, 701);
[dict2 release];
@@ -2958,24 +2958,24 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertEqual(dict.count, 3U);
XCTAssertTrue(dict.validationFunc == TestingEnum_IsValidValue); // Pointer comparison
int32_t value;
- XCTAssertTrue([dict valueForKey:11 rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:11 rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:11]);
+ XCTAssertTrue([dict getRawValue:&value forKey:11]);
XCTAssertEqual(value, 700);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:12]);
+ XCTAssertTrue([dict getEnum:&value forKey:12]);
XCTAssertEqual(value, kGPBUnrecognizedEnumeratorValue);
- XCTAssertTrue([dict valueForKey:12 rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:12 rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:12]);
+ XCTAssertTrue([dict getRawValue:&value forKey:12]);
XCTAssertEqual(value, 801);
- XCTAssertTrue([dict valueForKey:13 rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:13 rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:13]);
+ XCTAssertTrue([dict getRawValue:&value forKey:13]);
XCTAssertEqual(value, 702);
- XCTAssertFalse([dict valueForKey:14 rawValue:NULL]);
+ XCTAssertFalse([dict getRawValue:NULL forKey:14]);
__block NSUInteger idx = 0;
int32_t *seenKeys = malloc(3 * sizeof(int32_t));
int32_t *seenValues = malloc(3 * sizeof(int32_t));
- [dict enumerateKeysAndValuesUsingBlock:^(int32_t aKey, int32_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndEnumsUsingBlock:^(int32_t aKey, int32_t aValue, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -3136,7 +3136,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertThrowsSpecificNamed([dict setValue:801 forKey:12], // Unknown
+ XCTAssertThrowsSpecificNamed([dict setEnum:801 forKey:12], // Unknown
NSException, NSInvalidArgumentException);
XCTAssertEqual(dict.count, 0U);
[dict setRawValue:801 forKey:12]; // Unknown
@@ -3145,31 +3145,31 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kKeys[] = { 11, 13, 14 };
const int32_t kValues[] = { 700, 702, 803 }; // Unknown
GPBInt32EnumDictionary *dict2 =
- [[GPBInt32EnumDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt32EnumDictionary alloc] initWithEnums:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
[dict addRawEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
int32_t value;
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:11]);
+ XCTAssertTrue([dict getEnum:&value forKey:11]);
XCTAssertEqual(value, 700);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:12]);
+ XCTAssertTrue([dict getEnum:&value forKey:12]);
XCTAssertEqual(value, kGPBUnrecognizedEnumeratorValue);
- XCTAssertTrue([dict valueForKey:12 rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:12 rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:12]);
+ XCTAssertTrue([dict getRawValue:&value forKey:12]);
XCTAssertEqual(value, 801);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:13]);
+ XCTAssertTrue([dict getEnum:&value forKey:13]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:14]);
+ XCTAssertTrue([dict getEnum:&value forKey:14]);
XCTAssertEqual(value, kGPBUnrecognizedEnumeratorValue);
- XCTAssertTrue([dict valueForKey:14 rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:14 rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:14]);
+ XCTAssertTrue([dict getRawValue:&value forKey:14]);
XCTAssertEqual(value, 803);
[dict2 release];
}
@@ -3185,51 +3185,51 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
- [dict removeValueForKey:12];
+ [dict removeEnumForKey:12];
XCTAssertEqual(dict.count, 3U);
int32_t value;
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:11]);
+ XCTAssertTrue([dict getEnum:&value forKey:11]);
XCTAssertEqual(value, 700);
- XCTAssertFalse([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertFalse([dict getEnum:NULL forKey:12]);
+ XCTAssertTrue([dict getEnum:NULL forKey:13]);
+ XCTAssertTrue([dict getEnum:&value forKey:13]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:14 rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:14 rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:14]);
+ XCTAssertTrue([dict getRawValue:&value forKey:14]);
XCTAssertEqual(value, 803);
// Remove again does nothing.
- [dict removeValueForKey:12];
+ [dict removeEnumForKey:12];
XCTAssertEqual(dict.count, 3U);
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:11]);
+ XCTAssertTrue([dict getEnum:&value forKey:11]);
XCTAssertEqual(value, 700);
- XCTAssertFalse([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertFalse([dict getEnum:NULL forKey:12]);
+ XCTAssertTrue([dict getEnum:NULL forKey:13]);
+ XCTAssertTrue([dict getEnum:&value forKey:13]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:14 rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:14 rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:14]);
+ XCTAssertTrue([dict getRawValue:&value forKey:14]);
XCTAssertEqual(value, 803);
- [dict removeValueForKey:14];
+ [dict removeEnumForKey:14];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:11]);
+ XCTAssertTrue([dict getEnum:&value forKey:11]);
XCTAssertEqual(value, 700);
- XCTAssertFalse([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertFalse([dict getEnum:NULL forKey:12]);
+ XCTAssertTrue([dict getEnum:NULL forKey:13]);
+ XCTAssertTrue([dict getEnum:&value forKey:13]);
XCTAssertEqual(value, 702);
- XCTAssertFalse([dict valueForKey:14 value:NULL]);
+ XCTAssertFalse([dict getEnum:NULL forKey:14]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:11 value:NULL]);
- XCTAssertFalse([dict valueForKey:12 value:NULL]);
- XCTAssertFalse([dict valueForKey:13 value:NULL]);
- XCTAssertFalse([dict valueForKey:14 value:NULL]);
+ XCTAssertFalse([dict getEnum:NULL forKey:11]);
+ XCTAssertFalse([dict getEnum:NULL forKey:12]);
+ XCTAssertFalse([dict getEnum:NULL forKey:13]);
+ XCTAssertFalse([dict getEnum:NULL forKey:14]);
[dict release];
}
@@ -3244,63 +3244,63 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
int32_t value;
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:11]);
+ XCTAssertTrue([dict getEnum:&value forKey:11]);
XCTAssertEqual(value, 700);
- XCTAssertTrue([dict valueForKey:12 rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:12 rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:12]);
+ XCTAssertTrue([dict getRawValue:&value forKey:12]);
XCTAssertEqual(value, 801);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:13]);
+ XCTAssertTrue([dict getEnum:&value forKey:13]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:14 rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:14 rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:14]);
+ XCTAssertTrue([dict getRawValue:&value forKey:14]);
XCTAssertEqual(value, 803);
- XCTAssertThrowsSpecificNamed([dict setValue:803 forKey:11], // Unknown
+ XCTAssertThrowsSpecificNamed([dict setEnum:803 forKey:11], // Unknown
NSException, NSInvalidArgumentException);
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:11 value:NULL]);
- XCTAssertTrue([dict valueForKey:11 value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:11]);
+ XCTAssertTrue([dict getEnum:&value forKey:11]);
XCTAssertEqual(value, 700);
- XCTAssertTrue([dict valueForKey:12 rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:12 rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:12]);
+ XCTAssertTrue([dict getRawValue:&value forKey:12]);
XCTAssertEqual(value, 801);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:13]);
+ XCTAssertTrue([dict getEnum:&value forKey:13]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:14 rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:14 rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:14]);
+ XCTAssertTrue([dict getRawValue:&value forKey:14]);
XCTAssertEqual(value, 803);
[dict setRawValue:803 forKey:11]; // Unknown
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:11 rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:11 rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:11]);
+ XCTAssertTrue([dict getRawValue:&value forKey:11]);
XCTAssertEqual(value, 803);
- XCTAssertTrue([dict valueForKey:12 rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:12 rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:12]);
+ XCTAssertTrue([dict getRawValue:&value forKey:12]);
XCTAssertEqual(value, 801);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:13]);
+ XCTAssertTrue([dict getEnum:&value forKey:13]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:14 rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:14 rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:14]);
+ XCTAssertTrue([dict getRawValue:&value forKey:14]);
XCTAssertEqual(value, 803);
[dict setRawValue:700 forKey:14];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:11 rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:11 rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:11]);
+ XCTAssertTrue([dict getRawValue:&value forKey:11]);
XCTAssertEqual(value, 803);
- XCTAssertTrue([dict valueForKey:12 rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:12 rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:12]);
+ XCTAssertTrue([dict getRawValue:&value forKey:12]);
XCTAssertEqual(value, 801);
- XCTAssertTrue([dict valueForKey:13 value:NULL]);
- XCTAssertTrue([dict valueForKey:13 value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:13]);
+ XCTAssertTrue([dict getEnum:&value forKey:13]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:14]);
+ XCTAssertTrue([dict getEnum:&value forKey:14]);
XCTAssertEqual(value, 700);
const int32_t kKeys2[] = { 12, 13 };
@@ -3313,17 +3313,17 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict2);
[dict addRawEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:11 rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:11 rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:11]);
+ XCTAssertTrue([dict getRawValue:&value forKey:11]);
XCTAssertEqual(value, 803);
- XCTAssertTrue([dict valueForKey:12 value:NULL]);
- XCTAssertTrue([dict valueForKey:12 value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:12]);
+ XCTAssertTrue([dict getEnum:&value forKey:12]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:13 rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:13 rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:13]);
+ XCTAssertTrue([dict getRawValue:&value forKey:13]);
XCTAssertEqual(value, 801);
- XCTAssertTrue([dict valueForKey:14 value:NULL]);
- XCTAssertTrue([dict valueForKey:14 value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:14]);
+ XCTAssertTrue([dict getEnum:&value forKey:14]);
XCTAssertEqual(value, 700);
[dict2 release];
@@ -3363,11 +3363,11 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
@implementation GPBInt32ObjectDictionaryTests
- (void)testEmpty {
- GPBInt32ObjectDictionary *dict = [[GPBInt32ObjectDictionary alloc] init];
+ GPBInt32ObjectDictionary<NSString*> *dict = [[GPBInt32ObjectDictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertNil([dict objectForKey:11]);
- [dict enumerateKeysAndObjectsUsingBlock:^(int32_t aKey, id aObject, BOOL *stop) {
+ [dict enumerateKeysAndObjectsUsingBlock:^(int32_t aKey, NSString* aObject, BOOL *stop) {
#pragma unused(aKey, aObject, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -3375,12 +3375,12 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testOne {
- GPBInt32ObjectDictionary *dict = [GPBInt32ObjectDictionary dictionaryWithObject:@"abc" forKey:11];
+ GPBInt32ObjectDictionary<NSString*> *dict = [GPBInt32ObjectDictionary dictionaryWithObject:@"abc" forKey:11];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
XCTAssertEqualObjects([dict objectForKey:11], @"abc");
XCTAssertNil([dict objectForKey:12]);
- [dict enumerateKeysAndObjectsUsingBlock:^(int32_t aKey, id aObject, BOOL *stop) {
+ [dict enumerateKeysAndObjectsUsingBlock:^(int32_t aKey, NSString* aObject, BOOL *stop) {
XCTAssertEqual(aKey, 11);
XCTAssertEqualObjects(aObject, @"abc");
XCTAssertNotEqual(stop, NULL);
@@ -3389,8 +3389,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
- (void)testBasics {
const int32_t kKeys[] = { 11, 12, 13 };
- const id kObjects[] = { @"abc", @"def", @"ghi" };
- GPBInt32ObjectDictionary *dict =
+ const NSString* kObjects[] = { @"abc", @"def", @"ghi" };
+ GPBInt32ObjectDictionary<NSString*> *dict =
[[GPBInt32ObjectDictionary alloc] initWithObjects:kObjects
forKeys:kKeys
count:GPBARRAYSIZE(kObjects)];
@@ -3403,8 +3403,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
__block NSUInteger idx = 0;
int32_t *seenKeys = malloc(3 * sizeof(int32_t));
- id *seenObjects = malloc(3 * sizeof(id));
- [dict enumerateKeysAndObjectsUsingBlock:^(int32_t aKey, id aObject, BOOL *stop) {
+ NSString* *seenObjects = malloc(3 * sizeof(NSString*));
+ [dict enumerateKeysAndObjectsUsingBlock:^(int32_t aKey, NSString* aObject, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenObjects[idx] = aObject;
@@ -3426,7 +3426,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndObjectsUsingBlock:^(int32_t aKey, id aObject, BOOL *stop) {
+ [dict enumerateKeysAndObjectsUsingBlock:^(int32_t aKey, NSString* aObject, BOOL *stop) {
#pragma unused(aKey, aObject)
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -3438,30 +3438,30 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
- (void)testEquality {
const int32_t kKeys1[] = { 11, 12, 13, 14 };
const int32_t kKeys2[] = { 12, 11, 14 };
- const id kObjects1[] = { @"abc", @"def", @"ghi" };
- const id kObjects2[] = { @"abc", @"jkl", @"ghi" };
- const id kObjects3[] = { @"abc", @"def", @"ghi", @"jkl" };
- GPBInt32ObjectDictionary *dict1 =
+ const NSString* kObjects1[] = { @"abc", @"def", @"ghi" };
+ const NSString* kObjects2[] = { @"abc", @"jkl", @"ghi" };
+ const NSString* kObjects3[] = { @"abc", @"def", @"ghi", @"jkl" };
+ GPBInt32ObjectDictionary<NSString*> *dict1 =
[[GPBInt32ObjectDictionary alloc] initWithObjects:kObjects1
forKeys:kKeys1
count:GPBARRAYSIZE(kObjects1)];
XCTAssertNotNil(dict1);
- GPBInt32ObjectDictionary *dict1prime =
+ GPBInt32ObjectDictionary<NSString*> *dict1prime =
[[GPBInt32ObjectDictionary alloc] initWithObjects:kObjects1
forKeys:kKeys1
count:GPBARRAYSIZE(kObjects1)];
XCTAssertNotNil(dict1prime);
- GPBInt32ObjectDictionary *dict2 =
+ GPBInt32ObjectDictionary<NSString*> *dict2 =
[[GPBInt32ObjectDictionary alloc] initWithObjects:kObjects2
forKeys:kKeys1
count:GPBARRAYSIZE(kObjects2)];
XCTAssertNotNil(dict2);
- GPBInt32ObjectDictionary *dict3 =
+ GPBInt32ObjectDictionary<NSString*> *dict3 =
[[GPBInt32ObjectDictionary alloc] initWithObjects:kObjects1
forKeys:kKeys2
count:GPBARRAYSIZE(kObjects1)];
XCTAssertNotNil(dict3);
- GPBInt32ObjectDictionary *dict4 =
+ GPBInt32ObjectDictionary<NSString*> *dict4 =
[[GPBInt32ObjectDictionary alloc] initWithObjects:kObjects3
forKeys:kKeys1
count:GPBARRAYSIZE(kObjects3)];
@@ -3491,14 +3491,14 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
- (void)testCopy {
const int32_t kKeys[] = { 11, 12, 13, 14 };
- const id kObjects[] = { @"abc", @"def", @"ghi", @"jkl" };
- GPBInt32ObjectDictionary *dict =
+ const NSString* kObjects[] = { @"abc", @"def", @"ghi", @"jkl" };
+ GPBInt32ObjectDictionary<NSString*> *dict =
[[GPBInt32ObjectDictionary alloc] initWithObjects:kObjects
forKeys:kKeys
count:GPBARRAYSIZE(kObjects)];
XCTAssertNotNil(dict);
- GPBInt32ObjectDictionary *dict2 = [dict copy];
+ GPBInt32ObjectDictionary<NSString*> *dict2 = [dict copy];
XCTAssertNotNil(dict2);
// Should be new object but equal.
@@ -3512,14 +3512,14 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
- (void)testDictionaryFromDictionary {
const int32_t kKeys[] = { 11, 12, 13, 14 };
- const id kObjects[] = { @"abc", @"def", @"ghi", @"jkl" };
- GPBInt32ObjectDictionary *dict =
+ const NSString* kObjects[] = { @"abc", @"def", @"ghi", @"jkl" };
+ GPBInt32ObjectDictionary<NSString*> *dict =
[[GPBInt32ObjectDictionary alloc] initWithObjects:kObjects
forKeys:kKeys
count:GPBARRAYSIZE(kObjects)];
XCTAssertNotNil(dict);
- GPBInt32ObjectDictionary *dict2 =
+ GPBInt32ObjectDictionary<NSString*> *dict2 =
[GPBInt32ObjectDictionary dictionaryWithDictionary:dict];
XCTAssertNotNil(dict2);
@@ -3530,7 +3530,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testAdds {
- GPBInt32ObjectDictionary *dict = [GPBInt32ObjectDictionary dictionary];
+ GPBInt32ObjectDictionary<NSString*> *dict = [GPBInt32ObjectDictionary dictionary];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
@@ -3538,8 +3538,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertEqual(dict.count, 1U);
const int32_t kKeys[] = { 12, 13, 14 };
- const id kObjects[] = { @"def", @"ghi", @"jkl" };
- GPBInt32ObjectDictionary *dict2 =
+ const NSString* kObjects[] = { @"def", @"ghi", @"jkl" };
+ GPBInt32ObjectDictionary<NSString*> *dict2 =
[[GPBInt32ObjectDictionary alloc] initWithObjects:kObjects
forKeys:kKeys
count:GPBARRAYSIZE(kObjects)];
@@ -3556,11 +3556,11 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
- (void)testRemove {
const int32_t kKeys[] = { 11, 12, 13, 14 };
- const id kObjects[] = { @"abc", @"def", @"ghi", @"jkl" };
- GPBInt32ObjectDictionary *dict =
+ const NSString* kObjects[] = { @"abc", @"def", @"ghi", @"jkl" };
+ GPBInt32ObjectDictionary<NSString*> *dict =
[[GPBInt32ObjectDictionary alloc] initWithObjects:kObjects
- forKeys:kKeys
- count:GPBARRAYSIZE(kObjects)];
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kObjects)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
@@ -3597,11 +3597,11 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
- (void)testInplaceMutation {
const int32_t kKeys[] = { 11, 12, 13, 14 };
- const id kObjects[] = { @"abc", @"def", @"ghi", @"jkl" };
- GPBInt32ObjectDictionary *dict =
+ const NSString* kObjects[] = { @"abc", @"def", @"ghi", @"jkl" };
+ GPBInt32ObjectDictionary<NSString*> *dict =
[[GPBInt32ObjectDictionary alloc] initWithObjects:kObjects
- forKeys:kKeys
- count:GPBARRAYSIZE(kObjects)];
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kObjects)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
XCTAssertEqualObjects([dict objectForKey:11], @"abc");
@@ -3624,8 +3624,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertEqualObjects([dict objectForKey:14], @"def");
const int32_t kKeys2[] = { 12, 13 };
- const id kObjects2[] = { @"ghi", @"abc" };
- GPBInt32ObjectDictionary *dict2 =
+ const NSString* kObjects2[] = { @"ghi", @"abc" };
+ GPBInt32ObjectDictionary<NSString*> *dict2 =
[[GPBInt32ObjectDictionary alloc] initWithObjects:kObjects2
forKeys:kKeys2
count:GPBARRAYSIZE(kObjects2)];
diff --git a/objectivec/Tests/GPBDictionaryTests+Int64.m b/objectivec/Tests/GPBDictionaryTests+Int64.m
index 27f77f28..b90cdf8c 100644
--- a/objectivec/Tests/GPBDictionaryTests+Int64.m
+++ b/objectivec/Tests/GPBDictionaryTests+Int64.m
@@ -45,10 +45,10 @@
// To let the testing macros work, add some extra methods to simplify things.
@interface GPBInt64EnumDictionary (TestingTweak)
-+ (instancetype)dictionaryWithValue:(int32_t)value forKey:(int64_t)key;
-- (instancetype)initWithValues:(const int32_t [])values
- forKeys:(const int64_t [])keys
- count:(NSUInteger)count;
++ (instancetype)dictionaryWithEnum:(int32_t)value forKey:(int64_t)key;
+- (instancetype)initWithEnums:(const int32_t [])values
+ forKeys:(const int64_t [])keys
+ count:(NSUInteger)count;
@end
static BOOL TestingEnum_IsValidValue(int32_t value) {
@@ -64,7 +64,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
@implementation GPBInt64EnumDictionary (TestingTweak)
-+ (instancetype)dictionaryWithValue:(int32_t)value forKey:(int64_t)key {
++ (instancetype)dictionaryWithEnum:(int32_t)value forKey:(int64_t)key {
// Cast is needed to compiler knows what class we are invoking initWithValues: on to get the
// type correct.
return [[(GPBInt64EnumDictionary*)[self alloc] initWithValidationFunction:TestingEnum_IsValidValue
@@ -72,9 +72,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
forKeys:&key
count:1] autorelease];
}
-- (instancetype)initWithValues:(const int32_t [])values
- forKeys:(const int64_t [])keys
- count:(NSUInteger)count {
+- (instancetype)initWithEnums:(const int32_t [])values
+ forKeys:(const int64_t [])keys
+ count:(NSUInteger)count {
return [self initWithValidationFunction:TestingEnum_IsValidValue
rawValues:values
forKeys:keys
@@ -94,8 +94,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
GPBInt64UInt32Dictionary *dict = [[GPBInt64UInt32Dictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:21LL value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, uint32_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getUInt32:NULL forKey:21LL]);
+ [dict enumerateKeysAndUInt32sUsingBlock:^(int64_t aKey, uint32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -103,15 +103,15 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testOne {
- GPBInt64UInt32Dictionary *dict = [GPBInt64UInt32Dictionary dictionaryWithValue:100U forKey:21LL];
+ GPBInt64UInt32Dictionary *dict = [GPBInt64UInt32Dictionary dictionaryWithUInt32:100U forKey:21LL];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
uint32_t value;
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:21LL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:21LL]);
XCTAssertEqual(value, 100U);
- XCTAssertFalse([dict valueForKey:22LL value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, uint32_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getUInt32:NULL forKey:22LL]);
+ [dict enumerateKeysAndUInt32sUsingBlock:^(int64_t aKey, uint32_t aValue, BOOL *stop) {
XCTAssertEqual(aKey, 21LL);
XCTAssertEqual(aValue, 100U);
XCTAssertNotEqual(stop, NULL);
@@ -122,27 +122,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int64_t kKeys[] = { 21LL, 22LL, 23LL };
const uint32_t kValues[] = { 100U, 101U, 102U };
GPBInt64UInt32Dictionary *dict =
- [[GPBInt64UInt32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt64UInt32Dictionary alloc] initWithUInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 3U);
uint32_t value;
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:21LL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:21LL]);
XCTAssertEqual(value, 100U);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:22LL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:22LL]);
XCTAssertEqual(value, 101U);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:23LL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:23LL]);
XCTAssertEqual(value, 102U);
- XCTAssertFalse([dict valueForKey:24LL value:NULL]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:24LL]);
__block NSUInteger idx = 0;
int64_t *seenKeys = malloc(3 * sizeof(int64_t));
uint32_t *seenValues = malloc(3 * sizeof(uint32_t));
- [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, uint32_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndUInt32sUsingBlock:^(int64_t aKey, uint32_t aValue, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -164,7 +164,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, uint32_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndUInt32sUsingBlock:^(int64_t aKey, uint32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -180,29 +180,29 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint32_t kValues2[] = { 100U, 103U, 102U };
const uint32_t kValues3[] = { 100U, 101U, 102U, 103U };
GPBInt64UInt32Dictionary *dict1 =
- [[GPBInt64UInt32Dictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBInt64UInt32Dictionary alloc] initWithUInt32s:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBInt64UInt32Dictionary *dict1prime =
- [[GPBInt64UInt32Dictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBInt64UInt32Dictionary alloc] initWithUInt32s:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBInt64UInt32Dictionary *dict2 =
- [[GPBInt64UInt32Dictionary alloc] initWithValues:kValues2
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBInt64UInt32Dictionary alloc] initWithUInt32s:kValues2
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBInt64UInt32Dictionary *dict3 =
- [[GPBInt64UInt32Dictionary alloc] initWithValues:kValues1
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBInt64UInt32Dictionary alloc] initWithUInt32s:kValues1
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBInt64UInt32Dictionary *dict4 =
- [[GPBInt64UInt32Dictionary alloc] initWithValues:kValues3
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues3)];
+ [[GPBInt64UInt32Dictionary alloc] initWithUInt32s:kValues3
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
// 1/1Prime should be different objects, but equal.
@@ -231,9 +231,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
const uint32_t kValues[] = { 100U, 101U, 102U, 103U };
GPBInt64UInt32Dictionary *dict =
- [[GPBInt64UInt32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt64UInt32Dictionary alloc] initWithUInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBInt64UInt32Dictionary *dict2 = [dict copy];
@@ -252,9 +252,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
const uint32_t kValues[] = { 100U, 101U, 102U, 103U };
GPBInt64UInt32Dictionary *dict =
- [[GPBInt64UInt32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt64UInt32Dictionary alloc] initWithUInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBInt64UInt32Dictionary *dict2 =
@@ -272,31 +272,31 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:100U forKey:21LL];
+ [dict setUInt32:100U forKey:21LL];
XCTAssertEqual(dict.count, 1U);
const int64_t kKeys[] = { 22LL, 23LL, 24LL };
const uint32_t kValues[] = { 101U, 102U, 103U };
GPBInt64UInt32Dictionary *dict2 =
- [[GPBInt64UInt32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt64UInt32Dictionary alloc] initWithUInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
uint32_t value;
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:21LL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:21LL]);
XCTAssertEqual(value, 100U);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:22LL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:22LL]);
XCTAssertEqual(value, 101U);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:23LL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:23LL]);
XCTAssertEqual(value, 102U);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:24LL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:24LL]);
XCTAssertEqual(value, 103U);
[dict2 release];
}
@@ -305,57 +305,57 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
const uint32_t kValues[] = { 100U, 101U, 102U, 103U };
GPBInt64UInt32Dictionary *dict =
- [[GPBInt64UInt32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt64UInt32Dictionary alloc] initWithUInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
- [dict removeValueForKey:22LL];
+ [dict removeUInt32ForKey:22LL];
XCTAssertEqual(dict.count, 3U);
uint32_t value;
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:21LL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:21LL]);
XCTAssertEqual(value, 100U);
- XCTAssertFalse([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:22LL]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:23LL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:23LL]);
XCTAssertEqual(value, 102U);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:24LL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:24LL]);
XCTAssertEqual(value, 103U);
// Remove again does nothing.
- [dict removeValueForKey:22LL];
+ [dict removeUInt32ForKey:22LL];
XCTAssertEqual(dict.count, 3U);
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:21LL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:21LL]);
XCTAssertEqual(value, 100U);
- XCTAssertFalse([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:22LL]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:23LL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:23LL]);
XCTAssertEqual(value, 102U);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:24LL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:24LL]);
XCTAssertEqual(value, 103U);
- [dict removeValueForKey:24LL];
+ [dict removeUInt32ForKey:24LL];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:21LL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:21LL]);
XCTAssertEqual(value, 100U);
- XCTAssertFalse([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:22LL]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:23LL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:23LL]);
XCTAssertEqual(value, 102U);
- XCTAssertFalse([dict valueForKey:24LL value:NULL]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:24LL]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:21LL value:NULL]);
- XCTAssertFalse([dict valueForKey:22LL value:NULL]);
- XCTAssertFalse([dict valueForKey:23LL value:NULL]);
- XCTAssertFalse([dict valueForKey:24LL value:NULL]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:21LL]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:22LL]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:23LL]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:24LL]);
[dict release];
}
@@ -363,75 +363,75 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
const uint32_t kValues[] = { 100U, 101U, 102U, 103U };
GPBInt64UInt32Dictionary *dict =
- [[GPBInt64UInt32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt64UInt32Dictionary alloc] initWithUInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
uint32_t value;
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:21LL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:21LL]);
XCTAssertEqual(value, 100U);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:22LL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:22LL]);
XCTAssertEqual(value, 101U);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:23LL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:23LL]);
XCTAssertEqual(value, 102U);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:24LL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:24LL]);
XCTAssertEqual(value, 103U);
- [dict setValue:103U forKey:21LL];
+ [dict setUInt32:103U forKey:21LL];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:21LL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:21LL]);
XCTAssertEqual(value, 103U);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:22LL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:22LL]);
XCTAssertEqual(value, 101U);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:23LL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:23LL]);
XCTAssertEqual(value, 102U);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:24LL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:24LL]);
XCTAssertEqual(value, 103U);
- [dict setValue:101U forKey:24LL];
+ [dict setUInt32:101U forKey:24LL];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:21LL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:21LL]);
XCTAssertEqual(value, 103U);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:22LL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:22LL]);
XCTAssertEqual(value, 101U);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:23LL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:23LL]);
XCTAssertEqual(value, 102U);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:24LL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:24LL]);
XCTAssertEqual(value, 101U);
const int64_t kKeys2[] = { 22LL, 23LL };
const uint32_t kValues2[] = { 102U, 100U };
GPBInt64UInt32Dictionary *dict2 =
- [[GPBInt64UInt32Dictionary alloc] initWithValues:kValues2
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBInt64UInt32Dictionary alloc] initWithUInt32s:kValues2
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:21LL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:21LL]);
XCTAssertEqual(value, 103U);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:22LL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:22LL]);
XCTAssertEqual(value, 102U);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:23LL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:23LL]);
XCTAssertEqual(value, 100U);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:24LL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:24LL]);
XCTAssertEqual(value, 101U);
[dict2 release];
@@ -451,8 +451,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
GPBInt64Int32Dictionary *dict = [[GPBInt64Int32Dictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:21LL value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, int32_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getInt32:NULL forKey:21LL]);
+ [dict enumerateKeysAndInt32sUsingBlock:^(int64_t aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -460,15 +460,15 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testOne {
- GPBInt64Int32Dictionary *dict = [GPBInt64Int32Dictionary dictionaryWithValue:200 forKey:21LL];
+ GPBInt64Int32Dictionary *dict = [GPBInt64Int32Dictionary dictionaryWithInt32:200 forKey:21LL];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
int32_t value;
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:21LL]);
+ XCTAssertTrue([dict getInt32:&value forKey:21LL]);
XCTAssertEqual(value, 200);
- XCTAssertFalse([dict valueForKey:22LL value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, int32_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getInt32:NULL forKey:22LL]);
+ [dict enumerateKeysAndInt32sUsingBlock:^(int64_t aKey, int32_t aValue, BOOL *stop) {
XCTAssertEqual(aKey, 21LL);
XCTAssertEqual(aValue, 200);
XCTAssertNotEqual(stop, NULL);
@@ -479,27 +479,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int64_t kKeys[] = { 21LL, 22LL, 23LL };
const int32_t kValues[] = { 200, 201, 202 };
GPBInt64Int32Dictionary *dict =
- [[GPBInt64Int32Dictionary alloc] initWithValues:kValues
+ [[GPBInt64Int32Dictionary alloc] initWithInt32s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 3U);
int32_t value;
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:21LL]);
+ XCTAssertTrue([dict getInt32:&value forKey:21LL]);
XCTAssertEqual(value, 200);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:22LL]);
+ XCTAssertTrue([dict getInt32:&value forKey:22LL]);
XCTAssertEqual(value, 201);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:23LL]);
+ XCTAssertTrue([dict getInt32:&value forKey:23LL]);
XCTAssertEqual(value, 202);
- XCTAssertFalse([dict valueForKey:24LL value:NULL]);
+ XCTAssertFalse([dict getInt32:NULL forKey:24LL]);
__block NSUInteger idx = 0;
int64_t *seenKeys = malloc(3 * sizeof(int64_t));
int32_t *seenValues = malloc(3 * sizeof(int32_t));
- [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, int32_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndInt32sUsingBlock:^(int64_t aKey, int32_t aValue, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -521,7 +521,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, int32_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndInt32sUsingBlock:^(int64_t aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -537,27 +537,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kValues2[] = { 200, 203, 202 };
const int32_t kValues3[] = { 200, 201, 202, 203 };
GPBInt64Int32Dictionary *dict1 =
- [[GPBInt64Int32Dictionary alloc] initWithValues:kValues1
+ [[GPBInt64Int32Dictionary alloc] initWithInt32s:kValues1
forKeys:kKeys1
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBInt64Int32Dictionary *dict1prime =
- [[GPBInt64Int32Dictionary alloc] initWithValues:kValues1
+ [[GPBInt64Int32Dictionary alloc] initWithInt32s:kValues1
forKeys:kKeys1
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBInt64Int32Dictionary *dict2 =
- [[GPBInt64Int32Dictionary alloc] initWithValues:kValues2
+ [[GPBInt64Int32Dictionary alloc] initWithInt32s:kValues2
forKeys:kKeys1
count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBInt64Int32Dictionary *dict3 =
- [[GPBInt64Int32Dictionary alloc] initWithValues:kValues1
+ [[GPBInt64Int32Dictionary alloc] initWithInt32s:kValues1
forKeys:kKeys2
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBInt64Int32Dictionary *dict4 =
- [[GPBInt64Int32Dictionary alloc] initWithValues:kValues3
+ [[GPBInt64Int32Dictionary alloc] initWithInt32s:kValues3
forKeys:kKeys1
count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
@@ -588,7 +588,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
const int32_t kValues[] = { 200, 201, 202, 203 };
GPBInt64Int32Dictionary *dict =
- [[GPBInt64Int32Dictionary alloc] initWithValues:kValues
+ [[GPBInt64Int32Dictionary alloc] initWithInt32s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
@@ -609,7 +609,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
const int32_t kValues[] = { 200, 201, 202, 203 };
GPBInt64Int32Dictionary *dict =
- [[GPBInt64Int32Dictionary alloc] initWithValues:kValues
+ [[GPBInt64Int32Dictionary alloc] initWithInt32s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
@@ -629,13 +629,13 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:200 forKey:21LL];
+ [dict setInt32:200 forKey:21LL];
XCTAssertEqual(dict.count, 1U);
const int64_t kKeys[] = { 22LL, 23LL, 24LL };
const int32_t kValues[] = { 201, 202, 203 };
GPBInt64Int32Dictionary *dict2 =
- [[GPBInt64Int32Dictionary alloc] initWithValues:kValues
+ [[GPBInt64Int32Dictionary alloc] initWithInt32s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
@@ -643,17 +643,17 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertEqual(dict.count, 4U);
int32_t value;
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:21LL]);
+ XCTAssertTrue([dict getInt32:&value forKey:21LL]);
XCTAssertEqual(value, 200);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:22LL]);
+ XCTAssertTrue([dict getInt32:&value forKey:22LL]);
XCTAssertEqual(value, 201);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:23LL]);
+ XCTAssertTrue([dict getInt32:&value forKey:23LL]);
XCTAssertEqual(value, 202);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:24LL]);
+ XCTAssertTrue([dict getInt32:&value forKey:24LL]);
XCTAssertEqual(value, 203);
[dict2 release];
}
@@ -662,57 +662,57 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
const int32_t kValues[] = { 200, 201, 202, 203 };
GPBInt64Int32Dictionary *dict =
- [[GPBInt64Int32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt64Int32Dictionary alloc] initWithInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
- [dict removeValueForKey:22LL];
+ [dict removeInt32ForKey:22LL];
XCTAssertEqual(dict.count, 3U);
int32_t value;
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:21LL]);
+ XCTAssertTrue([dict getInt32:&value forKey:21LL]);
XCTAssertEqual(value, 200);
- XCTAssertFalse([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertFalse([dict getInt32:NULL forKey:22LL]);
+ XCTAssertTrue([dict getInt32:NULL forKey:23LL]);
+ XCTAssertTrue([dict getInt32:&value forKey:23LL]);
XCTAssertEqual(value, 202);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:24LL]);
+ XCTAssertTrue([dict getInt32:&value forKey:24LL]);
XCTAssertEqual(value, 203);
// Remove again does nothing.
- [dict removeValueForKey:22LL];
+ [dict removeInt32ForKey:22LL];
XCTAssertEqual(dict.count, 3U);
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:21LL]);
+ XCTAssertTrue([dict getInt32:&value forKey:21LL]);
XCTAssertEqual(value, 200);
- XCTAssertFalse([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertFalse([dict getInt32:NULL forKey:22LL]);
+ XCTAssertTrue([dict getInt32:NULL forKey:23LL]);
+ XCTAssertTrue([dict getInt32:&value forKey:23LL]);
XCTAssertEqual(value, 202);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:24LL]);
+ XCTAssertTrue([dict getInt32:&value forKey:24LL]);
XCTAssertEqual(value, 203);
- [dict removeValueForKey:24LL];
+ [dict removeInt32ForKey:24LL];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:21LL]);
+ XCTAssertTrue([dict getInt32:&value forKey:21LL]);
XCTAssertEqual(value, 200);
- XCTAssertFalse([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertFalse([dict getInt32:NULL forKey:22LL]);
+ XCTAssertTrue([dict getInt32:NULL forKey:23LL]);
+ XCTAssertTrue([dict getInt32:&value forKey:23LL]);
XCTAssertEqual(value, 202);
- XCTAssertFalse([dict valueForKey:24LL value:NULL]);
+ XCTAssertFalse([dict getInt32:NULL forKey:24LL]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:21LL value:NULL]);
- XCTAssertFalse([dict valueForKey:22LL value:NULL]);
- XCTAssertFalse([dict valueForKey:23LL value:NULL]);
- XCTAssertFalse([dict valueForKey:24LL value:NULL]);
+ XCTAssertFalse([dict getInt32:NULL forKey:21LL]);
+ XCTAssertFalse([dict getInt32:NULL forKey:22LL]);
+ XCTAssertFalse([dict getInt32:NULL forKey:23LL]);
+ XCTAssertFalse([dict getInt32:NULL forKey:24LL]);
[dict release];
}
@@ -720,75 +720,75 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
const int32_t kValues[] = { 200, 201, 202, 203 };
GPBInt64Int32Dictionary *dict =
- [[GPBInt64Int32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt64Int32Dictionary alloc] initWithInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
int32_t value;
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:21LL]);
+ XCTAssertTrue([dict getInt32:&value forKey:21LL]);
XCTAssertEqual(value, 200);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:22LL]);
+ XCTAssertTrue([dict getInt32:&value forKey:22LL]);
XCTAssertEqual(value, 201);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:23LL]);
+ XCTAssertTrue([dict getInt32:&value forKey:23LL]);
XCTAssertEqual(value, 202);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:24LL]);
+ XCTAssertTrue([dict getInt32:&value forKey:24LL]);
XCTAssertEqual(value, 203);
- [dict setValue:203 forKey:21LL];
+ [dict setInt32:203 forKey:21LL];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:21LL]);
+ XCTAssertTrue([dict getInt32:&value forKey:21LL]);
XCTAssertEqual(value, 203);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:22LL]);
+ XCTAssertTrue([dict getInt32:&value forKey:22LL]);
XCTAssertEqual(value, 201);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:23LL]);
+ XCTAssertTrue([dict getInt32:&value forKey:23LL]);
XCTAssertEqual(value, 202);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:24LL]);
+ XCTAssertTrue([dict getInt32:&value forKey:24LL]);
XCTAssertEqual(value, 203);
- [dict setValue:201 forKey:24LL];
+ [dict setInt32:201 forKey:24LL];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:21LL]);
+ XCTAssertTrue([dict getInt32:&value forKey:21LL]);
XCTAssertEqual(value, 203);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:22LL]);
+ XCTAssertTrue([dict getInt32:&value forKey:22LL]);
XCTAssertEqual(value, 201);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:23LL]);
+ XCTAssertTrue([dict getInt32:&value forKey:23LL]);
XCTAssertEqual(value, 202);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:24LL]);
+ XCTAssertTrue([dict getInt32:&value forKey:24LL]);
XCTAssertEqual(value, 201);
const int64_t kKeys2[] = { 22LL, 23LL };
const int32_t kValues2[] = { 202, 200 };
GPBInt64Int32Dictionary *dict2 =
- [[GPBInt64Int32Dictionary alloc] initWithValues:kValues2
+ [[GPBInt64Int32Dictionary alloc] initWithInt32s:kValues2
forKeys:kKeys2
count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:21LL]);
+ XCTAssertTrue([dict getInt32:&value forKey:21LL]);
XCTAssertEqual(value, 203);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:22LL]);
+ XCTAssertTrue([dict getInt32:&value forKey:22LL]);
XCTAssertEqual(value, 202);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:23LL]);
+ XCTAssertTrue([dict getInt32:&value forKey:23LL]);
XCTAssertEqual(value, 200);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:24LL]);
+ XCTAssertTrue([dict getInt32:&value forKey:24LL]);
XCTAssertEqual(value, 201);
[dict2 release];
@@ -808,8 +808,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
GPBInt64UInt64Dictionary *dict = [[GPBInt64UInt64Dictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:21LL value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, uint64_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getUInt64:NULL forKey:21LL]);
+ [dict enumerateKeysAndUInt64sUsingBlock:^(int64_t aKey, uint64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -817,15 +817,15 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testOne {
- GPBInt64UInt64Dictionary *dict = [GPBInt64UInt64Dictionary dictionaryWithValue:300U forKey:21LL];
+ GPBInt64UInt64Dictionary *dict = [GPBInt64UInt64Dictionary dictionaryWithUInt64:300U forKey:21LL];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
uint64_t value;
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:21LL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:21LL]);
XCTAssertEqual(value, 300U);
- XCTAssertFalse([dict valueForKey:22LL value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, uint64_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getUInt64:NULL forKey:22LL]);
+ [dict enumerateKeysAndUInt64sUsingBlock:^(int64_t aKey, uint64_t aValue, BOOL *stop) {
XCTAssertEqual(aKey, 21LL);
XCTAssertEqual(aValue, 300U);
XCTAssertNotEqual(stop, NULL);
@@ -836,27 +836,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int64_t kKeys[] = { 21LL, 22LL, 23LL };
const uint64_t kValues[] = { 300U, 301U, 302U };
GPBInt64UInt64Dictionary *dict =
- [[GPBInt64UInt64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt64UInt64Dictionary alloc] initWithUInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 3U);
uint64_t value;
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:21LL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:21LL]);
XCTAssertEqual(value, 300U);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:22LL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:22LL]);
XCTAssertEqual(value, 301U);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:23LL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:23LL]);
XCTAssertEqual(value, 302U);
- XCTAssertFalse([dict valueForKey:24LL value:NULL]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:24LL]);
__block NSUInteger idx = 0;
int64_t *seenKeys = malloc(3 * sizeof(int64_t));
uint64_t *seenValues = malloc(3 * sizeof(uint64_t));
- [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, uint64_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndUInt64sUsingBlock:^(int64_t aKey, uint64_t aValue, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -878,7 +878,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, uint64_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndUInt64sUsingBlock:^(int64_t aKey, uint64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -894,29 +894,29 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint64_t kValues2[] = { 300U, 303U, 302U };
const uint64_t kValues3[] = { 300U, 301U, 302U, 303U };
GPBInt64UInt64Dictionary *dict1 =
- [[GPBInt64UInt64Dictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBInt64UInt64Dictionary alloc] initWithUInt64s:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBInt64UInt64Dictionary *dict1prime =
- [[GPBInt64UInt64Dictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBInt64UInt64Dictionary alloc] initWithUInt64s:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBInt64UInt64Dictionary *dict2 =
- [[GPBInt64UInt64Dictionary alloc] initWithValues:kValues2
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBInt64UInt64Dictionary alloc] initWithUInt64s:kValues2
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBInt64UInt64Dictionary *dict3 =
- [[GPBInt64UInt64Dictionary alloc] initWithValues:kValues1
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBInt64UInt64Dictionary alloc] initWithUInt64s:kValues1
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBInt64UInt64Dictionary *dict4 =
- [[GPBInt64UInt64Dictionary alloc] initWithValues:kValues3
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues3)];
+ [[GPBInt64UInt64Dictionary alloc] initWithUInt64s:kValues3
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
// 1/1Prime should be different objects, but equal.
@@ -945,9 +945,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
const uint64_t kValues[] = { 300U, 301U, 302U, 303U };
GPBInt64UInt64Dictionary *dict =
- [[GPBInt64UInt64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt64UInt64Dictionary alloc] initWithUInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBInt64UInt64Dictionary *dict2 = [dict copy];
@@ -966,9 +966,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
const uint64_t kValues[] = { 300U, 301U, 302U, 303U };
GPBInt64UInt64Dictionary *dict =
- [[GPBInt64UInt64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt64UInt64Dictionary alloc] initWithUInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBInt64UInt64Dictionary *dict2 =
@@ -986,31 +986,31 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:300U forKey:21LL];
+ [dict setUInt64:300U forKey:21LL];
XCTAssertEqual(dict.count, 1U);
const int64_t kKeys[] = { 22LL, 23LL, 24LL };
const uint64_t kValues[] = { 301U, 302U, 303U };
GPBInt64UInt64Dictionary *dict2 =
- [[GPBInt64UInt64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt64UInt64Dictionary alloc] initWithUInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
uint64_t value;
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:21LL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:21LL]);
XCTAssertEqual(value, 300U);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:22LL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:22LL]);
XCTAssertEqual(value, 301U);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:23LL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:23LL]);
XCTAssertEqual(value, 302U);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:24LL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:24LL]);
XCTAssertEqual(value, 303U);
[dict2 release];
}
@@ -1019,57 +1019,57 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
const uint64_t kValues[] = { 300U, 301U, 302U, 303U };
GPBInt64UInt64Dictionary *dict =
- [[GPBInt64UInt64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt64UInt64Dictionary alloc] initWithUInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
- [dict removeValueForKey:22LL];
+ [dict removeUInt64ForKey:22LL];
XCTAssertEqual(dict.count, 3U);
uint64_t value;
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:21LL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:21LL]);
XCTAssertEqual(value, 300U);
- XCTAssertFalse([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:22LL]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:23LL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:23LL]);
XCTAssertEqual(value, 302U);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:24LL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:24LL]);
XCTAssertEqual(value, 303U);
// Remove again does nothing.
- [dict removeValueForKey:22LL];
+ [dict removeUInt64ForKey:22LL];
XCTAssertEqual(dict.count, 3U);
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:21LL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:21LL]);
XCTAssertEqual(value, 300U);
- XCTAssertFalse([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:22LL]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:23LL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:23LL]);
XCTAssertEqual(value, 302U);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:24LL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:24LL]);
XCTAssertEqual(value, 303U);
- [dict removeValueForKey:24LL];
+ [dict removeUInt64ForKey:24LL];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:21LL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:21LL]);
XCTAssertEqual(value, 300U);
- XCTAssertFalse([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:22LL]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:23LL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:23LL]);
XCTAssertEqual(value, 302U);
- XCTAssertFalse([dict valueForKey:24LL value:NULL]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:24LL]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:21LL value:NULL]);
- XCTAssertFalse([dict valueForKey:22LL value:NULL]);
- XCTAssertFalse([dict valueForKey:23LL value:NULL]);
- XCTAssertFalse([dict valueForKey:24LL value:NULL]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:21LL]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:22LL]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:23LL]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:24LL]);
[dict release];
}
@@ -1077,75 +1077,75 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
const uint64_t kValues[] = { 300U, 301U, 302U, 303U };
GPBInt64UInt64Dictionary *dict =
- [[GPBInt64UInt64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt64UInt64Dictionary alloc] initWithUInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
uint64_t value;
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:21LL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:21LL]);
XCTAssertEqual(value, 300U);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:22LL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:22LL]);
XCTAssertEqual(value, 301U);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:23LL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:23LL]);
XCTAssertEqual(value, 302U);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:24LL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:24LL]);
XCTAssertEqual(value, 303U);
- [dict setValue:303U forKey:21LL];
+ [dict setUInt64:303U forKey:21LL];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:21LL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:21LL]);
XCTAssertEqual(value, 303U);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:22LL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:22LL]);
XCTAssertEqual(value, 301U);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:23LL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:23LL]);
XCTAssertEqual(value, 302U);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:24LL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:24LL]);
XCTAssertEqual(value, 303U);
- [dict setValue:301U forKey:24LL];
+ [dict setUInt64:301U forKey:24LL];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:21LL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:21LL]);
XCTAssertEqual(value, 303U);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:22LL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:22LL]);
XCTAssertEqual(value, 301U);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:23LL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:23LL]);
XCTAssertEqual(value, 302U);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:24LL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:24LL]);
XCTAssertEqual(value, 301U);
const int64_t kKeys2[] = { 22LL, 23LL };
const uint64_t kValues2[] = { 302U, 300U };
GPBInt64UInt64Dictionary *dict2 =
- [[GPBInt64UInt64Dictionary alloc] initWithValues:kValues2
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBInt64UInt64Dictionary alloc] initWithUInt64s:kValues2
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:21LL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:21LL]);
XCTAssertEqual(value, 303U);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:22LL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:22LL]);
XCTAssertEqual(value, 302U);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:23LL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:23LL]);
XCTAssertEqual(value, 300U);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:24LL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:24LL]);
XCTAssertEqual(value, 301U);
[dict2 release];
@@ -1165,8 +1165,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
GPBInt64Int64Dictionary *dict = [[GPBInt64Int64Dictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:21LL value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, int64_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getInt64:NULL forKey:21LL]);
+ [dict enumerateKeysAndInt64sUsingBlock:^(int64_t aKey, int64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -1174,15 +1174,15 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testOne {
- GPBInt64Int64Dictionary *dict = [GPBInt64Int64Dictionary dictionaryWithValue:400 forKey:21LL];
+ GPBInt64Int64Dictionary *dict = [GPBInt64Int64Dictionary dictionaryWithInt64:400 forKey:21LL];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
int64_t value;
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:21LL]);
+ XCTAssertTrue([dict getInt64:&value forKey:21LL]);
XCTAssertEqual(value, 400);
- XCTAssertFalse([dict valueForKey:22LL value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, int64_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getInt64:NULL forKey:22LL]);
+ [dict enumerateKeysAndInt64sUsingBlock:^(int64_t aKey, int64_t aValue, BOOL *stop) {
XCTAssertEqual(aKey, 21LL);
XCTAssertEqual(aValue, 400);
XCTAssertNotEqual(stop, NULL);
@@ -1193,27 +1193,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int64_t kKeys[] = { 21LL, 22LL, 23LL };
const int64_t kValues[] = { 400, 401, 402 };
GPBInt64Int64Dictionary *dict =
- [[GPBInt64Int64Dictionary alloc] initWithValues:kValues
+ [[GPBInt64Int64Dictionary alloc] initWithInt64s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 3U);
int64_t value;
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:21LL]);
+ XCTAssertTrue([dict getInt64:&value forKey:21LL]);
XCTAssertEqual(value, 400);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:22LL]);
+ XCTAssertTrue([dict getInt64:&value forKey:22LL]);
XCTAssertEqual(value, 401);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:23LL]);
+ XCTAssertTrue([dict getInt64:&value forKey:23LL]);
XCTAssertEqual(value, 402);
- XCTAssertFalse([dict valueForKey:24LL value:NULL]);
+ XCTAssertFalse([dict getInt64:NULL forKey:24LL]);
__block NSUInteger idx = 0;
int64_t *seenKeys = malloc(3 * sizeof(int64_t));
int64_t *seenValues = malloc(3 * sizeof(int64_t));
- [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, int64_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndInt64sUsingBlock:^(int64_t aKey, int64_t aValue, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -1235,7 +1235,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, int64_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndInt64sUsingBlock:^(int64_t aKey, int64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -1251,27 +1251,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int64_t kValues2[] = { 400, 403, 402 };
const int64_t kValues3[] = { 400, 401, 402, 403 };
GPBInt64Int64Dictionary *dict1 =
- [[GPBInt64Int64Dictionary alloc] initWithValues:kValues1
+ [[GPBInt64Int64Dictionary alloc] initWithInt64s:kValues1
forKeys:kKeys1
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBInt64Int64Dictionary *dict1prime =
- [[GPBInt64Int64Dictionary alloc] initWithValues:kValues1
+ [[GPBInt64Int64Dictionary alloc] initWithInt64s:kValues1
forKeys:kKeys1
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBInt64Int64Dictionary *dict2 =
- [[GPBInt64Int64Dictionary alloc] initWithValues:kValues2
+ [[GPBInt64Int64Dictionary alloc] initWithInt64s:kValues2
forKeys:kKeys1
count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBInt64Int64Dictionary *dict3 =
- [[GPBInt64Int64Dictionary alloc] initWithValues:kValues1
+ [[GPBInt64Int64Dictionary alloc] initWithInt64s:kValues1
forKeys:kKeys2
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBInt64Int64Dictionary *dict4 =
- [[GPBInt64Int64Dictionary alloc] initWithValues:kValues3
+ [[GPBInt64Int64Dictionary alloc] initWithInt64s:kValues3
forKeys:kKeys1
count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
@@ -1302,7 +1302,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
const int64_t kValues[] = { 400, 401, 402, 403 };
GPBInt64Int64Dictionary *dict =
- [[GPBInt64Int64Dictionary alloc] initWithValues:kValues
+ [[GPBInt64Int64Dictionary alloc] initWithInt64s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
@@ -1323,7 +1323,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
const int64_t kValues[] = { 400, 401, 402, 403 };
GPBInt64Int64Dictionary *dict =
- [[GPBInt64Int64Dictionary alloc] initWithValues:kValues
+ [[GPBInt64Int64Dictionary alloc] initWithInt64s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
@@ -1343,13 +1343,13 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:400 forKey:21LL];
+ [dict setInt64:400 forKey:21LL];
XCTAssertEqual(dict.count, 1U);
const int64_t kKeys[] = { 22LL, 23LL, 24LL };
const int64_t kValues[] = { 401, 402, 403 };
GPBInt64Int64Dictionary *dict2 =
- [[GPBInt64Int64Dictionary alloc] initWithValues:kValues
+ [[GPBInt64Int64Dictionary alloc] initWithInt64s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
@@ -1357,17 +1357,17 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertEqual(dict.count, 4U);
int64_t value;
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:21LL]);
+ XCTAssertTrue([dict getInt64:&value forKey:21LL]);
XCTAssertEqual(value, 400);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:22LL]);
+ XCTAssertTrue([dict getInt64:&value forKey:22LL]);
XCTAssertEqual(value, 401);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:23LL]);
+ XCTAssertTrue([dict getInt64:&value forKey:23LL]);
XCTAssertEqual(value, 402);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:24LL]);
+ XCTAssertTrue([dict getInt64:&value forKey:24LL]);
XCTAssertEqual(value, 403);
[dict2 release];
}
@@ -1376,57 +1376,57 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
const int64_t kValues[] = { 400, 401, 402, 403 };
GPBInt64Int64Dictionary *dict =
- [[GPBInt64Int64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt64Int64Dictionary alloc] initWithInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
- [dict removeValueForKey:22LL];
+ [dict removeInt64ForKey:22LL];
XCTAssertEqual(dict.count, 3U);
int64_t value;
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:21LL]);
+ XCTAssertTrue([dict getInt64:&value forKey:21LL]);
XCTAssertEqual(value, 400);
- XCTAssertFalse([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertFalse([dict getInt64:NULL forKey:22LL]);
+ XCTAssertTrue([dict getInt64:NULL forKey:23LL]);
+ XCTAssertTrue([dict getInt64:&value forKey:23LL]);
XCTAssertEqual(value, 402);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:24LL]);
+ XCTAssertTrue([dict getInt64:&value forKey:24LL]);
XCTAssertEqual(value, 403);
// Remove again does nothing.
- [dict removeValueForKey:22LL];
+ [dict removeInt64ForKey:22LL];
XCTAssertEqual(dict.count, 3U);
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:21LL]);
+ XCTAssertTrue([dict getInt64:&value forKey:21LL]);
XCTAssertEqual(value, 400);
- XCTAssertFalse([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertFalse([dict getInt64:NULL forKey:22LL]);
+ XCTAssertTrue([dict getInt64:NULL forKey:23LL]);
+ XCTAssertTrue([dict getInt64:&value forKey:23LL]);
XCTAssertEqual(value, 402);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:24LL]);
+ XCTAssertTrue([dict getInt64:&value forKey:24LL]);
XCTAssertEqual(value, 403);
- [dict removeValueForKey:24LL];
+ [dict removeInt64ForKey:24LL];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:21LL]);
+ XCTAssertTrue([dict getInt64:&value forKey:21LL]);
XCTAssertEqual(value, 400);
- XCTAssertFalse([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertFalse([dict getInt64:NULL forKey:22LL]);
+ XCTAssertTrue([dict getInt64:NULL forKey:23LL]);
+ XCTAssertTrue([dict getInt64:&value forKey:23LL]);
XCTAssertEqual(value, 402);
- XCTAssertFalse([dict valueForKey:24LL value:NULL]);
+ XCTAssertFalse([dict getInt64:NULL forKey:24LL]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:21LL value:NULL]);
- XCTAssertFalse([dict valueForKey:22LL value:NULL]);
- XCTAssertFalse([dict valueForKey:23LL value:NULL]);
- XCTAssertFalse([dict valueForKey:24LL value:NULL]);
+ XCTAssertFalse([dict getInt64:NULL forKey:21LL]);
+ XCTAssertFalse([dict getInt64:NULL forKey:22LL]);
+ XCTAssertFalse([dict getInt64:NULL forKey:23LL]);
+ XCTAssertFalse([dict getInt64:NULL forKey:24LL]);
[dict release];
}
@@ -1434,75 +1434,75 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
const int64_t kValues[] = { 400, 401, 402, 403 };
GPBInt64Int64Dictionary *dict =
- [[GPBInt64Int64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt64Int64Dictionary alloc] initWithInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
int64_t value;
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:21LL]);
+ XCTAssertTrue([dict getInt64:&value forKey:21LL]);
XCTAssertEqual(value, 400);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:22LL]);
+ XCTAssertTrue([dict getInt64:&value forKey:22LL]);
XCTAssertEqual(value, 401);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:23LL]);
+ XCTAssertTrue([dict getInt64:&value forKey:23LL]);
XCTAssertEqual(value, 402);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:24LL]);
+ XCTAssertTrue([dict getInt64:&value forKey:24LL]);
XCTAssertEqual(value, 403);
- [dict setValue:403 forKey:21LL];
+ [dict setInt64:403 forKey:21LL];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:21LL]);
+ XCTAssertTrue([dict getInt64:&value forKey:21LL]);
XCTAssertEqual(value, 403);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:22LL]);
+ XCTAssertTrue([dict getInt64:&value forKey:22LL]);
XCTAssertEqual(value, 401);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:23LL]);
+ XCTAssertTrue([dict getInt64:&value forKey:23LL]);
XCTAssertEqual(value, 402);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:24LL]);
+ XCTAssertTrue([dict getInt64:&value forKey:24LL]);
XCTAssertEqual(value, 403);
- [dict setValue:401 forKey:24LL];
+ [dict setInt64:401 forKey:24LL];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:21LL]);
+ XCTAssertTrue([dict getInt64:&value forKey:21LL]);
XCTAssertEqual(value, 403);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:22LL]);
+ XCTAssertTrue([dict getInt64:&value forKey:22LL]);
XCTAssertEqual(value, 401);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:23LL]);
+ XCTAssertTrue([dict getInt64:&value forKey:23LL]);
XCTAssertEqual(value, 402);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:24LL]);
+ XCTAssertTrue([dict getInt64:&value forKey:24LL]);
XCTAssertEqual(value, 401);
const int64_t kKeys2[] = { 22LL, 23LL };
const int64_t kValues2[] = { 402, 400 };
GPBInt64Int64Dictionary *dict2 =
- [[GPBInt64Int64Dictionary alloc] initWithValues:kValues2
+ [[GPBInt64Int64Dictionary alloc] initWithInt64s:kValues2
forKeys:kKeys2
count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:21LL]);
+ XCTAssertTrue([dict getInt64:&value forKey:21LL]);
XCTAssertEqual(value, 403);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:22LL]);
+ XCTAssertTrue([dict getInt64:&value forKey:22LL]);
XCTAssertEqual(value, 402);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:23LL]);
+ XCTAssertTrue([dict getInt64:&value forKey:23LL]);
XCTAssertEqual(value, 400);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:24LL]);
+ XCTAssertTrue([dict getInt64:&value forKey:24LL]);
XCTAssertEqual(value, 401);
[dict2 release];
@@ -1522,8 +1522,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
GPBInt64BoolDictionary *dict = [[GPBInt64BoolDictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:21LL value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, BOOL aValue, BOOL *stop) {
+ XCTAssertFalse([dict getBool:NULL forKey:21LL]);
+ [dict enumerateKeysAndBoolsUsingBlock:^(int64_t aKey, BOOL aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -1531,15 +1531,15 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testOne {
- GPBInt64BoolDictionary *dict = [GPBInt64BoolDictionary dictionaryWithValue:YES forKey:21LL];
+ GPBInt64BoolDictionary *dict = [GPBInt64BoolDictionary dictionaryWithBool:YES forKey:21LL];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
BOOL value;
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:21LL]);
+ XCTAssertTrue([dict getBool:&value forKey:21LL]);
XCTAssertEqual(value, YES);
- XCTAssertFalse([dict valueForKey:22LL value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, BOOL aValue, BOOL *stop) {
+ XCTAssertFalse([dict getBool:NULL forKey:22LL]);
+ [dict enumerateKeysAndBoolsUsingBlock:^(int64_t aKey, BOOL aValue, BOOL *stop) {
XCTAssertEqual(aKey, 21LL);
XCTAssertEqual(aValue, YES);
XCTAssertNotEqual(stop, NULL);
@@ -1550,27 +1550,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int64_t kKeys[] = { 21LL, 22LL, 23LL };
const BOOL kValues[] = { YES, YES, NO };
GPBInt64BoolDictionary *dict =
- [[GPBInt64BoolDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt64BoolDictionary alloc] initWithBools:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 3U);
BOOL value;
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:21LL]);
+ XCTAssertTrue([dict getBool:&value forKey:21LL]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:22LL]);
+ XCTAssertTrue([dict getBool:&value forKey:22LL]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:23LL]);
+ XCTAssertTrue([dict getBool:&value forKey:23LL]);
XCTAssertEqual(value, NO);
- XCTAssertFalse([dict valueForKey:24LL value:NULL]);
+ XCTAssertFalse([dict getBool:NULL forKey:24LL]);
__block NSUInteger idx = 0;
int64_t *seenKeys = malloc(3 * sizeof(int64_t));
BOOL *seenValues = malloc(3 * sizeof(BOOL));
- [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, BOOL aValue, BOOL *stop) {
+ [dict enumerateKeysAndBoolsUsingBlock:^(int64_t aKey, BOOL aValue, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -1592,7 +1592,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, BOOL aValue, BOOL *stop) {
+ [dict enumerateKeysAndBoolsUsingBlock:^(int64_t aKey, BOOL aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -1608,29 +1608,29 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const BOOL kValues2[] = { YES, NO, NO };
const BOOL kValues3[] = { YES, YES, NO, NO };
GPBInt64BoolDictionary *dict1 =
- [[GPBInt64BoolDictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBInt64BoolDictionary alloc] initWithBools:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBInt64BoolDictionary *dict1prime =
- [[GPBInt64BoolDictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBInt64BoolDictionary alloc] initWithBools:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBInt64BoolDictionary *dict2 =
- [[GPBInt64BoolDictionary alloc] initWithValues:kValues2
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBInt64BoolDictionary alloc] initWithBools:kValues2
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBInt64BoolDictionary *dict3 =
- [[GPBInt64BoolDictionary alloc] initWithValues:kValues1
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBInt64BoolDictionary alloc] initWithBools:kValues1
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBInt64BoolDictionary *dict4 =
- [[GPBInt64BoolDictionary alloc] initWithValues:kValues3
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues3)];
+ [[GPBInt64BoolDictionary alloc] initWithBools:kValues3
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
// 1/1Prime should be different objects, but equal.
@@ -1659,9 +1659,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
const BOOL kValues[] = { YES, YES, NO, NO };
GPBInt64BoolDictionary *dict =
- [[GPBInt64BoolDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt64BoolDictionary alloc] initWithBools:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBInt64BoolDictionary *dict2 = [dict copy];
@@ -1680,9 +1680,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
const BOOL kValues[] = { YES, YES, NO, NO };
GPBInt64BoolDictionary *dict =
- [[GPBInt64BoolDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt64BoolDictionary alloc] initWithBools:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBInt64BoolDictionary *dict2 =
@@ -1700,31 +1700,31 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:YES forKey:21LL];
+ [dict setBool:YES forKey:21LL];
XCTAssertEqual(dict.count, 1U);
const int64_t kKeys[] = { 22LL, 23LL, 24LL };
const BOOL kValues[] = { YES, NO, NO };
GPBInt64BoolDictionary *dict2 =
- [[GPBInt64BoolDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt64BoolDictionary alloc] initWithBools:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
BOOL value;
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:21LL]);
+ XCTAssertTrue([dict getBool:&value forKey:21LL]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:22LL]);
+ XCTAssertTrue([dict getBool:&value forKey:22LL]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:23LL]);
+ XCTAssertTrue([dict getBool:&value forKey:23LL]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:24LL]);
+ XCTAssertTrue([dict getBool:&value forKey:24LL]);
XCTAssertEqual(value, NO);
[dict2 release];
}
@@ -1733,57 +1733,57 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
const BOOL kValues[] = { YES, YES, NO, NO };
GPBInt64BoolDictionary *dict =
- [[GPBInt64BoolDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt64BoolDictionary alloc] initWithBools:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
- [dict removeValueForKey:22LL];
+ [dict removeBoolForKey:22LL];
XCTAssertEqual(dict.count, 3U);
BOOL value;
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:21LL]);
+ XCTAssertTrue([dict getBool:&value forKey:21LL]);
XCTAssertEqual(value, YES);
- XCTAssertFalse([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertFalse([dict getBool:NULL forKey:22LL]);
+ XCTAssertTrue([dict getBool:NULL forKey:23LL]);
+ XCTAssertTrue([dict getBool:&value forKey:23LL]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:24LL]);
+ XCTAssertTrue([dict getBool:&value forKey:24LL]);
XCTAssertEqual(value, NO);
// Remove again does nothing.
- [dict removeValueForKey:22LL];
+ [dict removeBoolForKey:22LL];
XCTAssertEqual(dict.count, 3U);
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:21LL]);
+ XCTAssertTrue([dict getBool:&value forKey:21LL]);
XCTAssertEqual(value, YES);
- XCTAssertFalse([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertFalse([dict getBool:NULL forKey:22LL]);
+ XCTAssertTrue([dict getBool:NULL forKey:23LL]);
+ XCTAssertTrue([dict getBool:&value forKey:23LL]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:24LL]);
+ XCTAssertTrue([dict getBool:&value forKey:24LL]);
XCTAssertEqual(value, NO);
- [dict removeValueForKey:24LL];
+ [dict removeBoolForKey:24LL];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:21LL]);
+ XCTAssertTrue([dict getBool:&value forKey:21LL]);
XCTAssertEqual(value, YES);
- XCTAssertFalse([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertFalse([dict getBool:NULL forKey:22LL]);
+ XCTAssertTrue([dict getBool:NULL forKey:23LL]);
+ XCTAssertTrue([dict getBool:&value forKey:23LL]);
XCTAssertEqual(value, NO);
- XCTAssertFalse([dict valueForKey:24LL value:NULL]);
+ XCTAssertFalse([dict getBool:NULL forKey:24LL]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:21LL value:NULL]);
- XCTAssertFalse([dict valueForKey:22LL value:NULL]);
- XCTAssertFalse([dict valueForKey:23LL value:NULL]);
- XCTAssertFalse([dict valueForKey:24LL value:NULL]);
+ XCTAssertFalse([dict getBool:NULL forKey:21LL]);
+ XCTAssertFalse([dict getBool:NULL forKey:22LL]);
+ XCTAssertFalse([dict getBool:NULL forKey:23LL]);
+ XCTAssertFalse([dict getBool:NULL forKey:24LL]);
[dict release];
}
@@ -1791,75 +1791,75 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
const BOOL kValues[] = { YES, YES, NO, NO };
GPBInt64BoolDictionary *dict =
- [[GPBInt64BoolDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt64BoolDictionary alloc] initWithBools:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
BOOL value;
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:21LL]);
+ XCTAssertTrue([dict getBool:&value forKey:21LL]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:22LL]);
+ XCTAssertTrue([dict getBool:&value forKey:22LL]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:23LL]);
+ XCTAssertTrue([dict getBool:&value forKey:23LL]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:24LL]);
+ XCTAssertTrue([dict getBool:&value forKey:24LL]);
XCTAssertEqual(value, NO);
- [dict setValue:NO forKey:21LL];
+ [dict setBool:NO forKey:21LL];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:21LL]);
+ XCTAssertTrue([dict getBool:&value forKey:21LL]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:22LL]);
+ XCTAssertTrue([dict getBool:&value forKey:22LL]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:23LL]);
+ XCTAssertTrue([dict getBool:&value forKey:23LL]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:24LL]);
+ XCTAssertTrue([dict getBool:&value forKey:24LL]);
XCTAssertEqual(value, NO);
- [dict setValue:YES forKey:24LL];
+ [dict setBool:YES forKey:24LL];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:21LL]);
+ XCTAssertTrue([dict getBool:&value forKey:21LL]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:22LL]);
+ XCTAssertTrue([dict getBool:&value forKey:22LL]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:23LL]);
+ XCTAssertTrue([dict getBool:&value forKey:23LL]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:24LL]);
+ XCTAssertTrue([dict getBool:&value forKey:24LL]);
XCTAssertEqual(value, YES);
const int64_t kKeys2[] = { 22LL, 23LL };
const BOOL kValues2[] = { NO, YES };
GPBInt64BoolDictionary *dict2 =
- [[GPBInt64BoolDictionary alloc] initWithValues:kValues2
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBInt64BoolDictionary alloc] initWithBools:kValues2
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:21LL]);
+ XCTAssertTrue([dict getBool:&value forKey:21LL]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:22LL]);
+ XCTAssertTrue([dict getBool:&value forKey:22LL]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:23LL]);
+ XCTAssertTrue([dict getBool:&value forKey:23LL]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:24LL]);
+ XCTAssertTrue([dict getBool:&value forKey:24LL]);
XCTAssertEqual(value, YES);
[dict2 release];
@@ -1879,8 +1879,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
GPBInt64FloatDictionary *dict = [[GPBInt64FloatDictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:21LL value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, float aValue, BOOL *stop) {
+ XCTAssertFalse([dict getFloat:NULL forKey:21LL]);
+ [dict enumerateKeysAndFloatsUsingBlock:^(int64_t aKey, float aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -1888,15 +1888,15 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testOne {
- GPBInt64FloatDictionary *dict = [GPBInt64FloatDictionary dictionaryWithValue:500.f forKey:21LL];
+ GPBInt64FloatDictionary *dict = [GPBInt64FloatDictionary dictionaryWithFloat:500.f forKey:21LL];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
float value;
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:21LL]);
+ XCTAssertTrue([dict getFloat:&value forKey:21LL]);
XCTAssertEqual(value, 500.f);
- XCTAssertFalse([dict valueForKey:22LL value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, float aValue, BOOL *stop) {
+ XCTAssertFalse([dict getFloat:NULL forKey:22LL]);
+ [dict enumerateKeysAndFloatsUsingBlock:^(int64_t aKey, float aValue, BOOL *stop) {
XCTAssertEqual(aKey, 21LL);
XCTAssertEqual(aValue, 500.f);
XCTAssertNotEqual(stop, NULL);
@@ -1907,27 +1907,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int64_t kKeys[] = { 21LL, 22LL, 23LL };
const float kValues[] = { 500.f, 501.f, 502.f };
GPBInt64FloatDictionary *dict =
- [[GPBInt64FloatDictionary alloc] initWithValues:kValues
+ [[GPBInt64FloatDictionary alloc] initWithFloats:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 3U);
float value;
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:21LL]);
+ XCTAssertTrue([dict getFloat:&value forKey:21LL]);
XCTAssertEqual(value, 500.f);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:22LL]);
+ XCTAssertTrue([dict getFloat:&value forKey:22LL]);
XCTAssertEqual(value, 501.f);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:23LL]);
+ XCTAssertTrue([dict getFloat:&value forKey:23LL]);
XCTAssertEqual(value, 502.f);
- XCTAssertFalse([dict valueForKey:24LL value:NULL]);
+ XCTAssertFalse([dict getFloat:NULL forKey:24LL]);
__block NSUInteger idx = 0;
int64_t *seenKeys = malloc(3 * sizeof(int64_t));
float *seenValues = malloc(3 * sizeof(float));
- [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, float aValue, BOOL *stop) {
+ [dict enumerateKeysAndFloatsUsingBlock:^(int64_t aKey, float aValue, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -1949,7 +1949,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, float aValue, BOOL *stop) {
+ [dict enumerateKeysAndFloatsUsingBlock:^(int64_t aKey, float aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -1965,27 +1965,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const float kValues2[] = { 500.f, 503.f, 502.f };
const float kValues3[] = { 500.f, 501.f, 502.f, 503.f };
GPBInt64FloatDictionary *dict1 =
- [[GPBInt64FloatDictionary alloc] initWithValues:kValues1
+ [[GPBInt64FloatDictionary alloc] initWithFloats:kValues1
forKeys:kKeys1
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBInt64FloatDictionary *dict1prime =
- [[GPBInt64FloatDictionary alloc] initWithValues:kValues1
+ [[GPBInt64FloatDictionary alloc] initWithFloats:kValues1
forKeys:kKeys1
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBInt64FloatDictionary *dict2 =
- [[GPBInt64FloatDictionary alloc] initWithValues:kValues2
+ [[GPBInt64FloatDictionary alloc] initWithFloats:kValues2
forKeys:kKeys1
count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBInt64FloatDictionary *dict3 =
- [[GPBInt64FloatDictionary alloc] initWithValues:kValues1
+ [[GPBInt64FloatDictionary alloc] initWithFloats:kValues1
forKeys:kKeys2
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBInt64FloatDictionary *dict4 =
- [[GPBInt64FloatDictionary alloc] initWithValues:kValues3
+ [[GPBInt64FloatDictionary alloc] initWithFloats:kValues3
forKeys:kKeys1
count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
@@ -2016,7 +2016,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
const float kValues[] = { 500.f, 501.f, 502.f, 503.f };
GPBInt64FloatDictionary *dict =
- [[GPBInt64FloatDictionary alloc] initWithValues:kValues
+ [[GPBInt64FloatDictionary alloc] initWithFloats:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
@@ -2037,7 +2037,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
const float kValues[] = { 500.f, 501.f, 502.f, 503.f };
GPBInt64FloatDictionary *dict =
- [[GPBInt64FloatDictionary alloc] initWithValues:kValues
+ [[GPBInt64FloatDictionary alloc] initWithFloats:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
@@ -2057,13 +2057,13 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:500.f forKey:21LL];
+ [dict setFloat:500.f forKey:21LL];
XCTAssertEqual(dict.count, 1U);
const int64_t kKeys[] = { 22LL, 23LL, 24LL };
const float kValues[] = { 501.f, 502.f, 503.f };
GPBInt64FloatDictionary *dict2 =
- [[GPBInt64FloatDictionary alloc] initWithValues:kValues
+ [[GPBInt64FloatDictionary alloc] initWithFloats:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
@@ -2071,17 +2071,17 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertEqual(dict.count, 4U);
float value;
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:21LL]);
+ XCTAssertTrue([dict getFloat:&value forKey:21LL]);
XCTAssertEqual(value, 500.f);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:22LL]);
+ XCTAssertTrue([dict getFloat:&value forKey:22LL]);
XCTAssertEqual(value, 501.f);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:23LL]);
+ XCTAssertTrue([dict getFloat:&value forKey:23LL]);
XCTAssertEqual(value, 502.f);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:24LL]);
+ XCTAssertTrue([dict getFloat:&value forKey:24LL]);
XCTAssertEqual(value, 503.f);
[dict2 release];
}
@@ -2090,57 +2090,57 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
const float kValues[] = { 500.f, 501.f, 502.f, 503.f };
GPBInt64FloatDictionary *dict =
- [[GPBInt64FloatDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt64FloatDictionary alloc] initWithFloats:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
- [dict removeValueForKey:22LL];
+ [dict removeFloatForKey:22LL];
XCTAssertEqual(dict.count, 3U);
float value;
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:21LL]);
+ XCTAssertTrue([dict getFloat:&value forKey:21LL]);
XCTAssertEqual(value, 500.f);
- XCTAssertFalse([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertFalse([dict getFloat:NULL forKey:22LL]);
+ XCTAssertTrue([dict getFloat:NULL forKey:23LL]);
+ XCTAssertTrue([dict getFloat:&value forKey:23LL]);
XCTAssertEqual(value, 502.f);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:24LL]);
+ XCTAssertTrue([dict getFloat:&value forKey:24LL]);
XCTAssertEqual(value, 503.f);
// Remove again does nothing.
- [dict removeValueForKey:22LL];
+ [dict removeFloatForKey:22LL];
XCTAssertEqual(dict.count, 3U);
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:21LL]);
+ XCTAssertTrue([dict getFloat:&value forKey:21LL]);
XCTAssertEqual(value, 500.f);
- XCTAssertFalse([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertFalse([dict getFloat:NULL forKey:22LL]);
+ XCTAssertTrue([dict getFloat:NULL forKey:23LL]);
+ XCTAssertTrue([dict getFloat:&value forKey:23LL]);
XCTAssertEqual(value, 502.f);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:24LL]);
+ XCTAssertTrue([dict getFloat:&value forKey:24LL]);
XCTAssertEqual(value, 503.f);
- [dict removeValueForKey:24LL];
+ [dict removeFloatForKey:24LL];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:21LL]);
+ XCTAssertTrue([dict getFloat:&value forKey:21LL]);
XCTAssertEqual(value, 500.f);
- XCTAssertFalse([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertFalse([dict getFloat:NULL forKey:22LL]);
+ XCTAssertTrue([dict getFloat:NULL forKey:23LL]);
+ XCTAssertTrue([dict getFloat:&value forKey:23LL]);
XCTAssertEqual(value, 502.f);
- XCTAssertFalse([dict valueForKey:24LL value:NULL]);
+ XCTAssertFalse([dict getFloat:NULL forKey:24LL]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:21LL value:NULL]);
- XCTAssertFalse([dict valueForKey:22LL value:NULL]);
- XCTAssertFalse([dict valueForKey:23LL value:NULL]);
- XCTAssertFalse([dict valueForKey:24LL value:NULL]);
+ XCTAssertFalse([dict getFloat:NULL forKey:21LL]);
+ XCTAssertFalse([dict getFloat:NULL forKey:22LL]);
+ XCTAssertFalse([dict getFloat:NULL forKey:23LL]);
+ XCTAssertFalse([dict getFloat:NULL forKey:24LL]);
[dict release];
}
@@ -2148,75 +2148,75 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
const float kValues[] = { 500.f, 501.f, 502.f, 503.f };
GPBInt64FloatDictionary *dict =
- [[GPBInt64FloatDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt64FloatDictionary alloc] initWithFloats:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
float value;
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:21LL]);
+ XCTAssertTrue([dict getFloat:&value forKey:21LL]);
XCTAssertEqual(value, 500.f);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:22LL]);
+ XCTAssertTrue([dict getFloat:&value forKey:22LL]);
XCTAssertEqual(value, 501.f);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:23LL]);
+ XCTAssertTrue([dict getFloat:&value forKey:23LL]);
XCTAssertEqual(value, 502.f);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:24LL]);
+ XCTAssertTrue([dict getFloat:&value forKey:24LL]);
XCTAssertEqual(value, 503.f);
- [dict setValue:503.f forKey:21LL];
+ [dict setFloat:503.f forKey:21LL];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:21LL]);
+ XCTAssertTrue([dict getFloat:&value forKey:21LL]);
XCTAssertEqual(value, 503.f);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:22LL]);
+ XCTAssertTrue([dict getFloat:&value forKey:22LL]);
XCTAssertEqual(value, 501.f);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:23LL]);
+ XCTAssertTrue([dict getFloat:&value forKey:23LL]);
XCTAssertEqual(value, 502.f);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:24LL]);
+ XCTAssertTrue([dict getFloat:&value forKey:24LL]);
XCTAssertEqual(value, 503.f);
- [dict setValue:501.f forKey:24LL];
+ [dict setFloat:501.f forKey:24LL];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:21LL]);
+ XCTAssertTrue([dict getFloat:&value forKey:21LL]);
XCTAssertEqual(value, 503.f);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:22LL]);
+ XCTAssertTrue([dict getFloat:&value forKey:22LL]);
XCTAssertEqual(value, 501.f);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:23LL]);
+ XCTAssertTrue([dict getFloat:&value forKey:23LL]);
XCTAssertEqual(value, 502.f);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:24LL]);
+ XCTAssertTrue([dict getFloat:&value forKey:24LL]);
XCTAssertEqual(value, 501.f);
const int64_t kKeys2[] = { 22LL, 23LL };
const float kValues2[] = { 502.f, 500.f };
GPBInt64FloatDictionary *dict2 =
- [[GPBInt64FloatDictionary alloc] initWithValues:kValues2
+ [[GPBInt64FloatDictionary alloc] initWithFloats:kValues2
forKeys:kKeys2
count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:21LL]);
+ XCTAssertTrue([dict getFloat:&value forKey:21LL]);
XCTAssertEqual(value, 503.f);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:22LL]);
+ XCTAssertTrue([dict getFloat:&value forKey:22LL]);
XCTAssertEqual(value, 502.f);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:23LL]);
+ XCTAssertTrue([dict getFloat:&value forKey:23LL]);
XCTAssertEqual(value, 500.f);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:24LL]);
+ XCTAssertTrue([dict getFloat:&value forKey:24LL]);
XCTAssertEqual(value, 501.f);
[dict2 release];
@@ -2236,8 +2236,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
GPBInt64DoubleDictionary *dict = [[GPBInt64DoubleDictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:21LL value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, double aValue, BOOL *stop) {
+ XCTAssertFalse([dict getDouble:NULL forKey:21LL]);
+ [dict enumerateKeysAndDoublesUsingBlock:^(int64_t aKey, double aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -2245,15 +2245,15 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testOne {
- GPBInt64DoubleDictionary *dict = [GPBInt64DoubleDictionary dictionaryWithValue:600. forKey:21LL];
+ GPBInt64DoubleDictionary *dict = [GPBInt64DoubleDictionary dictionaryWithDouble:600. forKey:21LL];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
double value;
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:21LL]);
+ XCTAssertTrue([dict getDouble:&value forKey:21LL]);
XCTAssertEqual(value, 600.);
- XCTAssertFalse([dict valueForKey:22LL value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, double aValue, BOOL *stop) {
+ XCTAssertFalse([dict getDouble:NULL forKey:22LL]);
+ [dict enumerateKeysAndDoublesUsingBlock:^(int64_t aKey, double aValue, BOOL *stop) {
XCTAssertEqual(aKey, 21LL);
XCTAssertEqual(aValue, 600.);
XCTAssertNotEqual(stop, NULL);
@@ -2264,27 +2264,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int64_t kKeys[] = { 21LL, 22LL, 23LL };
const double kValues[] = { 600., 601., 602. };
GPBInt64DoubleDictionary *dict =
- [[GPBInt64DoubleDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt64DoubleDictionary alloc] initWithDoubles:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 3U);
double value;
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:21LL]);
+ XCTAssertTrue([dict getDouble:&value forKey:21LL]);
XCTAssertEqual(value, 600.);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:22LL]);
+ XCTAssertTrue([dict getDouble:&value forKey:22LL]);
XCTAssertEqual(value, 601.);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:23LL]);
+ XCTAssertTrue([dict getDouble:&value forKey:23LL]);
XCTAssertEqual(value, 602.);
- XCTAssertFalse([dict valueForKey:24LL value:NULL]);
+ XCTAssertFalse([dict getDouble:NULL forKey:24LL]);
__block NSUInteger idx = 0;
int64_t *seenKeys = malloc(3 * sizeof(int64_t));
double *seenValues = malloc(3 * sizeof(double));
- [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, double aValue, BOOL *stop) {
+ [dict enumerateKeysAndDoublesUsingBlock:^(int64_t aKey, double aValue, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -2306,7 +2306,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, double aValue, BOOL *stop) {
+ [dict enumerateKeysAndDoublesUsingBlock:^(int64_t aKey, double aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -2322,29 +2322,29 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const double kValues2[] = { 600., 603., 602. };
const double kValues3[] = { 600., 601., 602., 603. };
GPBInt64DoubleDictionary *dict1 =
- [[GPBInt64DoubleDictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBInt64DoubleDictionary alloc] initWithDoubles:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBInt64DoubleDictionary *dict1prime =
- [[GPBInt64DoubleDictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBInt64DoubleDictionary alloc] initWithDoubles:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBInt64DoubleDictionary *dict2 =
- [[GPBInt64DoubleDictionary alloc] initWithValues:kValues2
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBInt64DoubleDictionary alloc] initWithDoubles:kValues2
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBInt64DoubleDictionary *dict3 =
- [[GPBInt64DoubleDictionary alloc] initWithValues:kValues1
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBInt64DoubleDictionary alloc] initWithDoubles:kValues1
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBInt64DoubleDictionary *dict4 =
- [[GPBInt64DoubleDictionary alloc] initWithValues:kValues3
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues3)];
+ [[GPBInt64DoubleDictionary alloc] initWithDoubles:kValues3
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
// 1/1Prime should be different objects, but equal.
@@ -2373,9 +2373,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
const double kValues[] = { 600., 601., 602., 603. };
GPBInt64DoubleDictionary *dict =
- [[GPBInt64DoubleDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt64DoubleDictionary alloc] initWithDoubles:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBInt64DoubleDictionary *dict2 = [dict copy];
@@ -2394,9 +2394,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
const double kValues[] = { 600., 601., 602., 603. };
GPBInt64DoubleDictionary *dict =
- [[GPBInt64DoubleDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt64DoubleDictionary alloc] initWithDoubles:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBInt64DoubleDictionary *dict2 =
@@ -2414,31 +2414,31 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:600. forKey:21LL];
+ [dict setDouble:600. forKey:21LL];
XCTAssertEqual(dict.count, 1U);
const int64_t kKeys[] = { 22LL, 23LL, 24LL };
const double kValues[] = { 601., 602., 603. };
GPBInt64DoubleDictionary *dict2 =
- [[GPBInt64DoubleDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt64DoubleDictionary alloc] initWithDoubles:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
double value;
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:21LL]);
+ XCTAssertTrue([dict getDouble:&value forKey:21LL]);
XCTAssertEqual(value, 600.);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:22LL]);
+ XCTAssertTrue([dict getDouble:&value forKey:22LL]);
XCTAssertEqual(value, 601.);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:23LL]);
+ XCTAssertTrue([dict getDouble:&value forKey:23LL]);
XCTAssertEqual(value, 602.);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:24LL]);
+ XCTAssertTrue([dict getDouble:&value forKey:24LL]);
XCTAssertEqual(value, 603.);
[dict2 release];
}
@@ -2447,57 +2447,57 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
const double kValues[] = { 600., 601., 602., 603. };
GPBInt64DoubleDictionary *dict =
- [[GPBInt64DoubleDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt64DoubleDictionary alloc] initWithDoubles:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
- [dict removeValueForKey:22LL];
+ [dict removeDoubleForKey:22LL];
XCTAssertEqual(dict.count, 3U);
double value;
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:21LL]);
+ XCTAssertTrue([dict getDouble:&value forKey:21LL]);
XCTAssertEqual(value, 600.);
- XCTAssertFalse([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertFalse([dict getDouble:NULL forKey:22LL]);
+ XCTAssertTrue([dict getDouble:NULL forKey:23LL]);
+ XCTAssertTrue([dict getDouble:&value forKey:23LL]);
XCTAssertEqual(value, 602.);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:24LL]);
+ XCTAssertTrue([dict getDouble:&value forKey:24LL]);
XCTAssertEqual(value, 603.);
// Remove again does nothing.
- [dict removeValueForKey:22LL];
+ [dict removeDoubleForKey:22LL];
XCTAssertEqual(dict.count, 3U);
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:21LL]);
+ XCTAssertTrue([dict getDouble:&value forKey:21LL]);
XCTAssertEqual(value, 600.);
- XCTAssertFalse([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertFalse([dict getDouble:NULL forKey:22LL]);
+ XCTAssertTrue([dict getDouble:NULL forKey:23LL]);
+ XCTAssertTrue([dict getDouble:&value forKey:23LL]);
XCTAssertEqual(value, 602.);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:24LL]);
+ XCTAssertTrue([dict getDouble:&value forKey:24LL]);
XCTAssertEqual(value, 603.);
- [dict removeValueForKey:24LL];
+ [dict removeDoubleForKey:24LL];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:21LL]);
+ XCTAssertTrue([dict getDouble:&value forKey:21LL]);
XCTAssertEqual(value, 600.);
- XCTAssertFalse([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertFalse([dict getDouble:NULL forKey:22LL]);
+ XCTAssertTrue([dict getDouble:NULL forKey:23LL]);
+ XCTAssertTrue([dict getDouble:&value forKey:23LL]);
XCTAssertEqual(value, 602.);
- XCTAssertFalse([dict valueForKey:24LL value:NULL]);
+ XCTAssertFalse([dict getDouble:NULL forKey:24LL]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:21LL value:NULL]);
- XCTAssertFalse([dict valueForKey:22LL value:NULL]);
- XCTAssertFalse([dict valueForKey:23LL value:NULL]);
- XCTAssertFalse([dict valueForKey:24LL value:NULL]);
+ XCTAssertFalse([dict getDouble:NULL forKey:21LL]);
+ XCTAssertFalse([dict getDouble:NULL forKey:22LL]);
+ XCTAssertFalse([dict getDouble:NULL forKey:23LL]);
+ XCTAssertFalse([dict getDouble:NULL forKey:24LL]);
[dict release];
}
@@ -2505,75 +2505,75 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
const double kValues[] = { 600., 601., 602., 603. };
GPBInt64DoubleDictionary *dict =
- [[GPBInt64DoubleDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt64DoubleDictionary alloc] initWithDoubles:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
double value;
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:21LL]);
+ XCTAssertTrue([dict getDouble:&value forKey:21LL]);
XCTAssertEqual(value, 600.);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:22LL]);
+ XCTAssertTrue([dict getDouble:&value forKey:22LL]);
XCTAssertEqual(value, 601.);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:23LL]);
+ XCTAssertTrue([dict getDouble:&value forKey:23LL]);
XCTAssertEqual(value, 602.);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:24LL]);
+ XCTAssertTrue([dict getDouble:&value forKey:24LL]);
XCTAssertEqual(value, 603.);
- [dict setValue:603. forKey:21LL];
+ [dict setDouble:603. forKey:21LL];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:21LL]);
+ XCTAssertTrue([dict getDouble:&value forKey:21LL]);
XCTAssertEqual(value, 603.);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:22LL]);
+ XCTAssertTrue([dict getDouble:&value forKey:22LL]);
XCTAssertEqual(value, 601.);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:23LL]);
+ XCTAssertTrue([dict getDouble:&value forKey:23LL]);
XCTAssertEqual(value, 602.);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:24LL]);
+ XCTAssertTrue([dict getDouble:&value forKey:24LL]);
XCTAssertEqual(value, 603.);
- [dict setValue:601. forKey:24LL];
+ [dict setDouble:601. forKey:24LL];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:21LL]);
+ XCTAssertTrue([dict getDouble:&value forKey:21LL]);
XCTAssertEqual(value, 603.);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:22LL]);
+ XCTAssertTrue([dict getDouble:&value forKey:22LL]);
XCTAssertEqual(value, 601.);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:23LL]);
+ XCTAssertTrue([dict getDouble:&value forKey:23LL]);
XCTAssertEqual(value, 602.);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:24LL]);
+ XCTAssertTrue([dict getDouble:&value forKey:24LL]);
XCTAssertEqual(value, 601.);
const int64_t kKeys2[] = { 22LL, 23LL };
const double kValues2[] = { 602., 600. };
GPBInt64DoubleDictionary *dict2 =
- [[GPBInt64DoubleDictionary alloc] initWithValues:kValues2
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBInt64DoubleDictionary alloc] initWithDoubles:kValues2
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:21LL]);
+ XCTAssertTrue([dict getDouble:&value forKey:21LL]);
XCTAssertEqual(value, 603.);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:22LL]);
+ XCTAssertTrue([dict getDouble:&value forKey:22LL]);
XCTAssertEqual(value, 602.);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:23LL]);
+ XCTAssertTrue([dict getDouble:&value forKey:23LL]);
XCTAssertEqual(value, 600.);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:24LL]);
+ XCTAssertTrue([dict getDouble:&value forKey:24LL]);
XCTAssertEqual(value, 601.);
[dict2 release];
@@ -2593,8 +2593,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
GPBInt64EnumDictionary *dict = [[GPBInt64EnumDictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:21LL value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, int32_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getEnum:NULL forKey:21LL]);
+ [dict enumerateKeysAndEnumsUsingBlock:^(int64_t aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -2602,15 +2602,15 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testOne {
- GPBInt64EnumDictionary *dict = [GPBInt64EnumDictionary dictionaryWithValue:700 forKey:21LL];
+ GPBInt64EnumDictionary *dict = [GPBInt64EnumDictionary dictionaryWithEnum:700 forKey:21LL];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
int32_t value;
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:21LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:21LL]);
XCTAssertEqual(value, 700);
- XCTAssertFalse([dict valueForKey:22LL value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, int32_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getEnum:NULL forKey:22LL]);
+ [dict enumerateKeysAndEnumsUsingBlock:^(int64_t aKey, int32_t aValue, BOOL *stop) {
XCTAssertEqual(aKey, 21LL);
XCTAssertEqual(aValue, 700);
XCTAssertNotEqual(stop, NULL);
@@ -2621,27 +2621,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int64_t kKeys[] = { 21LL, 22LL, 23LL };
const int32_t kValues[] = { 700, 701, 702 };
GPBInt64EnumDictionary *dict =
- [[GPBInt64EnumDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt64EnumDictionary alloc] initWithEnums:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 3U);
int32_t value;
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:21LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:21LL]);
XCTAssertEqual(value, 700);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:22LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:22LL]);
XCTAssertEqual(value, 701);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:23LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:23LL]);
XCTAssertEqual(value, 702);
- XCTAssertFalse([dict valueForKey:24LL value:NULL]);
+ XCTAssertFalse([dict getEnum:NULL forKey:24LL]);
__block NSUInteger idx = 0;
int64_t *seenKeys = malloc(3 * sizeof(int64_t));
int32_t *seenValues = malloc(3 * sizeof(int32_t));
- [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, int32_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndEnumsUsingBlock:^(int64_t aKey, int32_t aValue, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -2663,7 +2663,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, int32_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndEnumsUsingBlock:^(int64_t aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -2679,29 +2679,29 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kValues2[] = { 700, 703, 702 };
const int32_t kValues3[] = { 700, 701, 702, 703 };
GPBInt64EnumDictionary *dict1 =
- [[GPBInt64EnumDictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBInt64EnumDictionary alloc] initWithEnums:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBInt64EnumDictionary *dict1prime =
- [[GPBInt64EnumDictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBInt64EnumDictionary alloc] initWithEnums:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBInt64EnumDictionary *dict2 =
- [[GPBInt64EnumDictionary alloc] initWithValues:kValues2
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBInt64EnumDictionary alloc] initWithEnums:kValues2
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBInt64EnumDictionary *dict3 =
- [[GPBInt64EnumDictionary alloc] initWithValues:kValues1
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBInt64EnumDictionary alloc] initWithEnums:kValues1
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBInt64EnumDictionary *dict4 =
- [[GPBInt64EnumDictionary alloc] initWithValues:kValues3
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues3)];
+ [[GPBInt64EnumDictionary alloc] initWithEnums:kValues3
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
// 1/1Prime should be different objects, but equal.
@@ -2730,9 +2730,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
const int32_t kValues[] = { 700, 701, 702, 703 };
GPBInt64EnumDictionary *dict =
- [[GPBInt64EnumDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt64EnumDictionary alloc] initWithEnums:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBInt64EnumDictionary *dict2 = [dict copy];
@@ -2751,9 +2751,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
const int32_t kValues[] = { 700, 701, 702, 703 };
GPBInt64EnumDictionary *dict =
- [[GPBInt64EnumDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt64EnumDictionary alloc] initWithEnums:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBInt64EnumDictionary *dict2 =
@@ -2771,31 +2771,31 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:700 forKey:21LL];
+ [dict setEnum:700 forKey:21LL];
XCTAssertEqual(dict.count, 1U);
const int64_t kKeys[] = { 22LL, 23LL, 24LL };
const int32_t kValues[] = { 701, 702, 703 };
GPBInt64EnumDictionary *dict2 =
- [[GPBInt64EnumDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt64EnumDictionary alloc] initWithEnums:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
[dict addRawEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
int32_t value;
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:21LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:21LL]);
XCTAssertEqual(value, 700);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:22LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:22LL]);
XCTAssertEqual(value, 701);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:23LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:23LL]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:24LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:24LL]);
XCTAssertEqual(value, 703);
[dict2 release];
}
@@ -2804,57 +2804,57 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
const int32_t kValues[] = { 700, 701, 702, 703 };
GPBInt64EnumDictionary *dict =
- [[GPBInt64EnumDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt64EnumDictionary alloc] initWithEnums:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
- [dict removeValueForKey:22LL];
+ [dict removeEnumForKey:22LL];
XCTAssertEqual(dict.count, 3U);
int32_t value;
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:21LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:21LL]);
XCTAssertEqual(value, 700);
- XCTAssertFalse([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertFalse([dict getEnum:NULL forKey:22LL]);
+ XCTAssertTrue([dict getEnum:NULL forKey:23LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:23LL]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:24LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:24LL]);
XCTAssertEqual(value, 703);
// Remove again does nothing.
- [dict removeValueForKey:22LL];
+ [dict removeEnumForKey:22LL];
XCTAssertEqual(dict.count, 3U);
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:21LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:21LL]);
XCTAssertEqual(value, 700);
- XCTAssertFalse([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertFalse([dict getEnum:NULL forKey:22LL]);
+ XCTAssertTrue([dict getEnum:NULL forKey:23LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:23LL]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:24LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:24LL]);
XCTAssertEqual(value, 703);
- [dict removeValueForKey:24LL];
+ [dict removeEnumForKey:24LL];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:21LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:21LL]);
XCTAssertEqual(value, 700);
- XCTAssertFalse([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertFalse([dict getEnum:NULL forKey:22LL]);
+ XCTAssertTrue([dict getEnum:NULL forKey:23LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:23LL]);
XCTAssertEqual(value, 702);
- XCTAssertFalse([dict valueForKey:24LL value:NULL]);
+ XCTAssertFalse([dict getEnum:NULL forKey:24LL]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:21LL value:NULL]);
- XCTAssertFalse([dict valueForKey:22LL value:NULL]);
- XCTAssertFalse([dict valueForKey:23LL value:NULL]);
- XCTAssertFalse([dict valueForKey:24LL value:NULL]);
+ XCTAssertFalse([dict getEnum:NULL forKey:21LL]);
+ XCTAssertFalse([dict getEnum:NULL forKey:22LL]);
+ XCTAssertFalse([dict getEnum:NULL forKey:23LL]);
+ XCTAssertFalse([dict getEnum:NULL forKey:24LL]);
[dict release];
}
@@ -2862,75 +2862,75 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
const int32_t kValues[] = { 700, 701, 702, 703 };
GPBInt64EnumDictionary *dict =
- [[GPBInt64EnumDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt64EnumDictionary alloc] initWithEnums:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
int32_t value;
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:21LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:21LL]);
XCTAssertEqual(value, 700);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:22LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:22LL]);
XCTAssertEqual(value, 701);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:23LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:23LL]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:24LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:24LL]);
XCTAssertEqual(value, 703);
- [dict setValue:703 forKey:21LL];
+ [dict setEnum:703 forKey:21LL];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:21LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:21LL]);
XCTAssertEqual(value, 703);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:22LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:22LL]);
XCTAssertEqual(value, 701);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:23LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:23LL]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:24LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:24LL]);
XCTAssertEqual(value, 703);
- [dict setValue:701 forKey:24LL];
+ [dict setEnum:701 forKey:24LL];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:21LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:21LL]);
XCTAssertEqual(value, 703);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:22LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:22LL]);
XCTAssertEqual(value, 701);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:23LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:23LL]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:24LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:24LL]);
XCTAssertEqual(value, 701);
const int64_t kKeys2[] = { 22LL, 23LL };
const int32_t kValues2[] = { 702, 700 };
GPBInt64EnumDictionary *dict2 =
- [[GPBInt64EnumDictionary alloc] initWithValues:kValues2
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBInt64EnumDictionary alloc] initWithEnums:kValues2
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addRawEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:21LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:21LL]);
XCTAssertEqual(value, 703);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:22LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:22LL]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:23LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:23LL]);
XCTAssertEqual(value, 700);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:24LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:24LL]);
XCTAssertEqual(value, 701);
[dict2 release];
@@ -2958,24 +2958,24 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertEqual(dict.count, 3U);
XCTAssertTrue(dict.validationFunc == TestingEnum_IsValidValue); // Pointer comparison
int32_t value;
- XCTAssertTrue([dict valueForKey:21LL rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:21LL rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:21LL]);
+ XCTAssertTrue([dict getRawValue:&value forKey:21LL]);
XCTAssertEqual(value, 700);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:22LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:22LL]);
XCTAssertEqual(value, kGPBUnrecognizedEnumeratorValue);
- XCTAssertTrue([dict valueForKey:22LL rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:22LL rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:22LL]);
+ XCTAssertTrue([dict getRawValue:&value forKey:22LL]);
XCTAssertEqual(value, 801);
- XCTAssertTrue([dict valueForKey:23LL rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:23LL rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:23LL]);
+ XCTAssertTrue([dict getRawValue:&value forKey:23LL]);
XCTAssertEqual(value, 702);
- XCTAssertFalse([dict valueForKey:24LL rawValue:NULL]);
+ XCTAssertFalse([dict getRawValue:NULL forKey:24LL]);
__block NSUInteger idx = 0;
int64_t *seenKeys = malloc(3 * sizeof(int64_t));
int32_t *seenValues = malloc(3 * sizeof(int32_t));
- [dict enumerateKeysAndValuesUsingBlock:^(int64_t aKey, int32_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndEnumsUsingBlock:^(int64_t aKey, int32_t aValue, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -3136,7 +3136,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertThrowsSpecificNamed([dict setValue:801 forKey:22LL], // Unknown
+ XCTAssertThrowsSpecificNamed([dict setEnum:801 forKey:22LL], // Unknown
NSException, NSInvalidArgumentException);
XCTAssertEqual(dict.count, 0U);
[dict setRawValue:801 forKey:22LL]; // Unknown
@@ -3145,31 +3145,31 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int64_t kKeys[] = { 21LL, 23LL, 24LL };
const int32_t kValues[] = { 700, 702, 803 }; // Unknown
GPBInt64EnumDictionary *dict2 =
- [[GPBInt64EnumDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBInt64EnumDictionary alloc] initWithEnums:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
[dict addRawEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
int32_t value;
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:21LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:21LL]);
XCTAssertEqual(value, 700);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:22LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:22LL]);
XCTAssertEqual(value, kGPBUnrecognizedEnumeratorValue);
- XCTAssertTrue([dict valueForKey:22LL rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:22LL rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:22LL]);
+ XCTAssertTrue([dict getRawValue:&value forKey:22LL]);
XCTAssertEqual(value, 801);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:23LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:23LL]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:24LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:24LL]);
XCTAssertEqual(value, kGPBUnrecognizedEnumeratorValue);
- XCTAssertTrue([dict valueForKey:24LL rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:24LL rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:24LL]);
+ XCTAssertTrue([dict getRawValue:&value forKey:24LL]);
XCTAssertEqual(value, 803);
[dict2 release];
}
@@ -3185,51 +3185,51 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
- [dict removeValueForKey:22LL];
+ [dict removeEnumForKey:22LL];
XCTAssertEqual(dict.count, 3U);
int32_t value;
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:21LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:21LL]);
XCTAssertEqual(value, 700);
- XCTAssertFalse([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertFalse([dict getEnum:NULL forKey:22LL]);
+ XCTAssertTrue([dict getEnum:NULL forKey:23LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:23LL]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:24LL rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:24LL rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:24LL]);
+ XCTAssertTrue([dict getRawValue:&value forKey:24LL]);
XCTAssertEqual(value, 803);
// Remove again does nothing.
- [dict removeValueForKey:22LL];
+ [dict removeEnumForKey:22LL];
XCTAssertEqual(dict.count, 3U);
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:21LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:21LL]);
XCTAssertEqual(value, 700);
- XCTAssertFalse([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertFalse([dict getEnum:NULL forKey:22LL]);
+ XCTAssertTrue([dict getEnum:NULL forKey:23LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:23LL]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:24LL rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:24LL rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:24LL]);
+ XCTAssertTrue([dict getRawValue:&value forKey:24LL]);
XCTAssertEqual(value, 803);
- [dict removeValueForKey:24LL];
+ [dict removeEnumForKey:24LL];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:21LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:21LL]);
XCTAssertEqual(value, 700);
- XCTAssertFalse([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertFalse([dict getEnum:NULL forKey:22LL]);
+ XCTAssertTrue([dict getEnum:NULL forKey:23LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:23LL]);
XCTAssertEqual(value, 702);
- XCTAssertFalse([dict valueForKey:24LL value:NULL]);
+ XCTAssertFalse([dict getEnum:NULL forKey:24LL]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:21LL value:NULL]);
- XCTAssertFalse([dict valueForKey:22LL value:NULL]);
- XCTAssertFalse([dict valueForKey:23LL value:NULL]);
- XCTAssertFalse([dict valueForKey:24LL value:NULL]);
+ XCTAssertFalse([dict getEnum:NULL forKey:21LL]);
+ XCTAssertFalse([dict getEnum:NULL forKey:22LL]);
+ XCTAssertFalse([dict getEnum:NULL forKey:23LL]);
+ XCTAssertFalse([dict getEnum:NULL forKey:24LL]);
[dict release];
}
@@ -3244,63 +3244,63 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
int32_t value;
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:21LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:21LL]);
XCTAssertEqual(value, 700);
- XCTAssertTrue([dict valueForKey:22LL rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:22LL rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:22LL]);
+ XCTAssertTrue([dict getRawValue:&value forKey:22LL]);
XCTAssertEqual(value, 801);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:23LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:23LL]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:24LL rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:24LL rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:24LL]);
+ XCTAssertTrue([dict getRawValue:&value forKey:24LL]);
XCTAssertEqual(value, 803);
- XCTAssertThrowsSpecificNamed([dict setValue:803 forKey:21LL], // Unknown
+ XCTAssertThrowsSpecificNamed([dict setEnum:803 forKey:21LL], // Unknown
NSException, NSInvalidArgumentException);
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:21LL value:NULL]);
- XCTAssertTrue([dict valueForKey:21LL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:21LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:21LL]);
XCTAssertEqual(value, 700);
- XCTAssertTrue([dict valueForKey:22LL rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:22LL rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:22LL]);
+ XCTAssertTrue([dict getRawValue:&value forKey:22LL]);
XCTAssertEqual(value, 801);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:23LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:23LL]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:24LL rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:24LL rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:24LL]);
+ XCTAssertTrue([dict getRawValue:&value forKey:24LL]);
XCTAssertEqual(value, 803);
[dict setRawValue:803 forKey:21LL]; // Unknown
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:21LL rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:21LL rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:21LL]);
+ XCTAssertTrue([dict getRawValue:&value forKey:21LL]);
XCTAssertEqual(value, 803);
- XCTAssertTrue([dict valueForKey:22LL rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:22LL rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:22LL]);
+ XCTAssertTrue([dict getRawValue:&value forKey:22LL]);
XCTAssertEqual(value, 801);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:23LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:23LL]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:24LL rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:24LL rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:24LL]);
+ XCTAssertTrue([dict getRawValue:&value forKey:24LL]);
XCTAssertEqual(value, 803);
[dict setRawValue:700 forKey:24LL];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:21LL rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:21LL rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:21LL]);
+ XCTAssertTrue([dict getRawValue:&value forKey:21LL]);
XCTAssertEqual(value, 803);
- XCTAssertTrue([dict valueForKey:22LL rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:22LL rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:22LL]);
+ XCTAssertTrue([dict getRawValue:&value forKey:22LL]);
XCTAssertEqual(value, 801);
- XCTAssertTrue([dict valueForKey:23LL value:NULL]);
- XCTAssertTrue([dict valueForKey:23LL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:23LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:23LL]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:24LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:24LL]);
XCTAssertEqual(value, 700);
const int64_t kKeys2[] = { 22LL, 23LL };
@@ -3313,17 +3313,17 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict2);
[dict addRawEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:21LL rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:21LL rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:21LL]);
+ XCTAssertTrue([dict getRawValue:&value forKey:21LL]);
XCTAssertEqual(value, 803);
- XCTAssertTrue([dict valueForKey:22LL value:NULL]);
- XCTAssertTrue([dict valueForKey:22LL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:22LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:22LL]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:23LL rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:23LL rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:23LL]);
+ XCTAssertTrue([dict getRawValue:&value forKey:23LL]);
XCTAssertEqual(value, 801);
- XCTAssertTrue([dict valueForKey:24LL value:NULL]);
- XCTAssertTrue([dict valueForKey:24LL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:24LL]);
+ XCTAssertTrue([dict getEnum:&value forKey:24LL]);
XCTAssertEqual(value, 700);
[dict2 release];
@@ -3363,11 +3363,11 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
@implementation GPBInt64ObjectDictionaryTests
- (void)testEmpty {
- GPBInt64ObjectDictionary *dict = [[GPBInt64ObjectDictionary alloc] init];
+ GPBInt64ObjectDictionary<NSString*> *dict = [[GPBInt64ObjectDictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertNil([dict objectForKey:21LL]);
- [dict enumerateKeysAndObjectsUsingBlock:^(int64_t aKey, id aObject, BOOL *stop) {
+ [dict enumerateKeysAndObjectsUsingBlock:^(int64_t aKey, NSString* aObject, BOOL *stop) {
#pragma unused(aKey, aObject, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -3375,12 +3375,12 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testOne {
- GPBInt64ObjectDictionary *dict = [GPBInt64ObjectDictionary dictionaryWithObject:@"abc" forKey:21LL];
+ GPBInt64ObjectDictionary<NSString*> *dict = [GPBInt64ObjectDictionary dictionaryWithObject:@"abc" forKey:21LL];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
XCTAssertEqualObjects([dict objectForKey:21LL], @"abc");
XCTAssertNil([dict objectForKey:22LL]);
- [dict enumerateKeysAndObjectsUsingBlock:^(int64_t aKey, id aObject, BOOL *stop) {
+ [dict enumerateKeysAndObjectsUsingBlock:^(int64_t aKey, NSString* aObject, BOOL *stop) {
XCTAssertEqual(aKey, 21LL);
XCTAssertEqualObjects(aObject, @"abc");
XCTAssertNotEqual(stop, NULL);
@@ -3389,8 +3389,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
- (void)testBasics {
const int64_t kKeys[] = { 21LL, 22LL, 23LL };
- const id kObjects[] = { @"abc", @"def", @"ghi" };
- GPBInt64ObjectDictionary *dict =
+ const NSString* kObjects[] = { @"abc", @"def", @"ghi" };
+ GPBInt64ObjectDictionary<NSString*> *dict =
[[GPBInt64ObjectDictionary alloc] initWithObjects:kObjects
forKeys:kKeys
count:GPBARRAYSIZE(kObjects)];
@@ -3403,8 +3403,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
__block NSUInteger idx = 0;
int64_t *seenKeys = malloc(3 * sizeof(int64_t));
- id *seenObjects = malloc(3 * sizeof(id));
- [dict enumerateKeysAndObjectsUsingBlock:^(int64_t aKey, id aObject, BOOL *stop) {
+ NSString* *seenObjects = malloc(3 * sizeof(NSString*));
+ [dict enumerateKeysAndObjectsUsingBlock:^(int64_t aKey, NSString* aObject, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenObjects[idx] = aObject;
@@ -3426,7 +3426,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndObjectsUsingBlock:^(int64_t aKey, id aObject, BOOL *stop) {
+ [dict enumerateKeysAndObjectsUsingBlock:^(int64_t aKey, NSString* aObject, BOOL *stop) {
#pragma unused(aKey, aObject)
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -3438,30 +3438,30 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
- (void)testEquality {
const int64_t kKeys1[] = { 21LL, 22LL, 23LL, 24LL };
const int64_t kKeys2[] = { 22LL, 21LL, 24LL };
- const id kObjects1[] = { @"abc", @"def", @"ghi" };
- const id kObjects2[] = { @"abc", @"jkl", @"ghi" };
- const id kObjects3[] = { @"abc", @"def", @"ghi", @"jkl" };
- GPBInt64ObjectDictionary *dict1 =
+ const NSString* kObjects1[] = { @"abc", @"def", @"ghi" };
+ const NSString* kObjects2[] = { @"abc", @"jkl", @"ghi" };
+ const NSString* kObjects3[] = { @"abc", @"def", @"ghi", @"jkl" };
+ GPBInt64ObjectDictionary<NSString*> *dict1 =
[[GPBInt64ObjectDictionary alloc] initWithObjects:kObjects1
forKeys:kKeys1
count:GPBARRAYSIZE(kObjects1)];
XCTAssertNotNil(dict1);
- GPBInt64ObjectDictionary *dict1prime =
+ GPBInt64ObjectDictionary<NSString*> *dict1prime =
[[GPBInt64ObjectDictionary alloc] initWithObjects:kObjects1
forKeys:kKeys1
count:GPBARRAYSIZE(kObjects1)];
XCTAssertNotNil(dict1prime);
- GPBInt64ObjectDictionary *dict2 =
+ GPBInt64ObjectDictionary<NSString*> *dict2 =
[[GPBInt64ObjectDictionary alloc] initWithObjects:kObjects2
forKeys:kKeys1
count:GPBARRAYSIZE(kObjects2)];
XCTAssertNotNil(dict2);
- GPBInt64ObjectDictionary *dict3 =
+ GPBInt64ObjectDictionary<NSString*> *dict3 =
[[GPBInt64ObjectDictionary alloc] initWithObjects:kObjects1
forKeys:kKeys2
count:GPBARRAYSIZE(kObjects1)];
XCTAssertNotNil(dict3);
- GPBInt64ObjectDictionary *dict4 =
+ GPBInt64ObjectDictionary<NSString*> *dict4 =
[[GPBInt64ObjectDictionary alloc] initWithObjects:kObjects3
forKeys:kKeys1
count:GPBARRAYSIZE(kObjects3)];
@@ -3491,14 +3491,14 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
- (void)testCopy {
const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
- const id kObjects[] = { @"abc", @"def", @"ghi", @"jkl" };
- GPBInt64ObjectDictionary *dict =
+ const NSString* kObjects[] = { @"abc", @"def", @"ghi", @"jkl" };
+ GPBInt64ObjectDictionary<NSString*> *dict =
[[GPBInt64ObjectDictionary alloc] initWithObjects:kObjects
forKeys:kKeys
count:GPBARRAYSIZE(kObjects)];
XCTAssertNotNil(dict);
- GPBInt64ObjectDictionary *dict2 = [dict copy];
+ GPBInt64ObjectDictionary<NSString*> *dict2 = [dict copy];
XCTAssertNotNil(dict2);
// Should be new object but equal.
@@ -3512,14 +3512,14 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
- (void)testDictionaryFromDictionary {
const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
- const id kObjects[] = { @"abc", @"def", @"ghi", @"jkl" };
- GPBInt64ObjectDictionary *dict =
+ const NSString* kObjects[] = { @"abc", @"def", @"ghi", @"jkl" };
+ GPBInt64ObjectDictionary<NSString*> *dict =
[[GPBInt64ObjectDictionary alloc] initWithObjects:kObjects
forKeys:kKeys
count:GPBARRAYSIZE(kObjects)];
XCTAssertNotNil(dict);
- GPBInt64ObjectDictionary *dict2 =
+ GPBInt64ObjectDictionary<NSString*> *dict2 =
[GPBInt64ObjectDictionary dictionaryWithDictionary:dict];
XCTAssertNotNil(dict2);
@@ -3530,7 +3530,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testAdds {
- GPBInt64ObjectDictionary *dict = [GPBInt64ObjectDictionary dictionary];
+ GPBInt64ObjectDictionary<NSString*> *dict = [GPBInt64ObjectDictionary dictionary];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
@@ -3538,8 +3538,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertEqual(dict.count, 1U);
const int64_t kKeys[] = { 22LL, 23LL, 24LL };
- const id kObjects[] = { @"def", @"ghi", @"jkl" };
- GPBInt64ObjectDictionary *dict2 =
+ const NSString* kObjects[] = { @"def", @"ghi", @"jkl" };
+ GPBInt64ObjectDictionary<NSString*> *dict2 =
[[GPBInt64ObjectDictionary alloc] initWithObjects:kObjects
forKeys:kKeys
count:GPBARRAYSIZE(kObjects)];
@@ -3556,11 +3556,11 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
- (void)testRemove {
const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
- const id kObjects[] = { @"abc", @"def", @"ghi", @"jkl" };
- GPBInt64ObjectDictionary *dict =
+ const NSString* kObjects[] = { @"abc", @"def", @"ghi", @"jkl" };
+ GPBInt64ObjectDictionary<NSString*> *dict =
[[GPBInt64ObjectDictionary alloc] initWithObjects:kObjects
- forKeys:kKeys
- count:GPBARRAYSIZE(kObjects)];
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kObjects)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
@@ -3597,11 +3597,11 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
- (void)testInplaceMutation {
const int64_t kKeys[] = { 21LL, 22LL, 23LL, 24LL };
- const id kObjects[] = { @"abc", @"def", @"ghi", @"jkl" };
- GPBInt64ObjectDictionary *dict =
+ const NSString* kObjects[] = { @"abc", @"def", @"ghi", @"jkl" };
+ GPBInt64ObjectDictionary<NSString*> *dict =
[[GPBInt64ObjectDictionary alloc] initWithObjects:kObjects
- forKeys:kKeys
- count:GPBARRAYSIZE(kObjects)];
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kObjects)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
XCTAssertEqualObjects([dict objectForKey:21LL], @"abc");
@@ -3624,8 +3624,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertEqualObjects([dict objectForKey:24LL], @"def");
const int64_t kKeys2[] = { 22LL, 23LL };
- const id kObjects2[] = { @"ghi", @"abc" };
- GPBInt64ObjectDictionary *dict2 =
+ const NSString* kObjects2[] = { @"ghi", @"abc" };
+ GPBInt64ObjectDictionary<NSString*> *dict2 =
[[GPBInt64ObjectDictionary alloc] initWithObjects:kObjects2
forKeys:kKeys2
count:GPBARRAYSIZE(kObjects2)];
diff --git a/objectivec/Tests/GPBDictionaryTests+String.m b/objectivec/Tests/GPBDictionaryTests+String.m
index bfa10b19..5df1d51d 100644
--- a/objectivec/Tests/GPBDictionaryTests+String.m
+++ b/objectivec/Tests/GPBDictionaryTests+String.m
@@ -45,10 +45,10 @@
// To let the testing macros work, add some extra methods to simplify things.
@interface GPBStringEnumDictionary (TestingTweak)
-+ (instancetype)dictionaryWithValue:(int32_t)value forKey:(NSString *)key;
-- (instancetype)initWithValues:(const int32_t [])values
- forKeys:(const NSString * [])keys
- count:(NSUInteger)count;
++ (instancetype)dictionaryWithEnum:(int32_t)value forKey:(NSString *)key;
+- (instancetype)initWithEnums:(const int32_t [])values
+ forKeys:(const NSString * [])keys
+ count:(NSUInteger)count;
@end
static BOOL TestingEnum_IsValidValue(int32_t value) {
@@ -64,7 +64,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
@implementation GPBStringEnumDictionary (TestingTweak)
-+ (instancetype)dictionaryWithValue:(int32_t)value forKey:(NSString *)key {
++ (instancetype)dictionaryWithEnum:(int32_t)value forKey:(NSString *)key {
// Cast is needed to compiler knows what class we are invoking initWithValues: on to get the
// type correct.
return [[(GPBStringEnumDictionary*)[self alloc] initWithValidationFunction:TestingEnum_IsValidValue
@@ -72,9 +72,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
forKeys:&key
count:1] autorelease];
}
-- (instancetype)initWithValues:(const int32_t [])values
- forKeys:(const NSString * [])keys
- count:(NSUInteger)count {
+- (instancetype)initWithEnums:(const int32_t [])values
+ forKeys:(const NSString * [])keys
+ count:(NSUInteger)count {
return [self initWithValidationFunction:TestingEnum_IsValidValue
rawValues:values
forKeys:keys
@@ -94,8 +94,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
GPBStringUInt32Dictionary *dict = [[GPBStringUInt32Dictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:@"foo" value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(NSString *aKey, uint32_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getUInt32:NULL forKey:@"foo"]);
+ [dict enumerateKeysAndUInt32sUsingBlock:^(NSString *aKey, uint32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -103,15 +103,15 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testOne {
- GPBStringUInt32Dictionary *dict = [GPBStringUInt32Dictionary dictionaryWithValue:100U forKey:@"foo"];
+ GPBStringUInt32Dictionary *dict = [GPBStringUInt32Dictionary dictionaryWithUInt32:100U forKey:@"foo"];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
uint32_t value;
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getUInt32:&value forKey:@"foo"]);
XCTAssertEqual(value, 100U);
- XCTAssertFalse([dict valueForKey:@"bar" value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(NSString *aKey, uint32_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getUInt32:NULL forKey:@"bar"]);
+ [dict enumerateKeysAndUInt32sUsingBlock:^(NSString *aKey, uint32_t aValue, BOOL *stop) {
XCTAssertEqualObjects(aKey, @"foo");
XCTAssertEqual(aValue, 100U);
XCTAssertNotEqual(stop, NULL);
@@ -122,27 +122,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const NSString *kKeys[] = { @"foo", @"bar", @"baz" };
const uint32_t kValues[] = { 100U, 101U, 102U };
GPBStringUInt32Dictionary *dict =
- [[GPBStringUInt32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 3U);
uint32_t value;
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getUInt32:&value forKey:@"foo"]);
XCTAssertEqual(value, 100U);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getUInt32:&value forKey:@"bar"]);
XCTAssertEqual(value, 101U);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getUInt32:&value forKey:@"baz"]);
XCTAssertEqual(value, 102U);
- XCTAssertFalse([dict valueForKey:@"mumble" value:NULL]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:@"mumble"]);
__block NSUInteger idx = 0;
NSString **seenKeys = malloc(3 * sizeof(NSString*));
uint32_t *seenValues = malloc(3 * sizeof(uint32_t));
- [dict enumerateKeysAndValuesUsingBlock:^(NSString *aKey, uint32_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndUInt32sUsingBlock:^(NSString *aKey, uint32_t aValue, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -164,7 +164,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(NSString *aKey, uint32_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndUInt32sUsingBlock:^(NSString *aKey, uint32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -180,29 +180,29 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint32_t kValues2[] = { 100U, 103U, 102U };
const uint32_t kValues3[] = { 100U, 101U, 102U, 103U };
GPBStringUInt32Dictionary *dict1 =
- [[GPBStringUInt32Dictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBStringUInt32Dictionary *dict1prime =
- [[GPBStringUInt32Dictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBStringUInt32Dictionary *dict2 =
- [[GPBStringUInt32Dictionary alloc] initWithValues:kValues2
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues2
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBStringUInt32Dictionary *dict3 =
- [[GPBStringUInt32Dictionary alloc] initWithValues:kValues1
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues1
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBStringUInt32Dictionary *dict4 =
- [[GPBStringUInt32Dictionary alloc] initWithValues:kValues3
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues3)];
+ [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues3
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
// 1/1Prime should be different objects, but equal.
@@ -231,9 +231,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
const uint32_t kValues[] = { 100U, 101U, 102U, 103U };
GPBStringUInt32Dictionary *dict =
- [[GPBStringUInt32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBStringUInt32Dictionary *dict2 = [dict copy];
@@ -252,9 +252,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
const uint32_t kValues[] = { 100U, 101U, 102U, 103U };
GPBStringUInt32Dictionary *dict =
- [[GPBStringUInt32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBStringUInt32Dictionary *dict2 =
@@ -272,31 +272,31 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:100U forKey:@"foo"];
+ [dict setUInt32:100U forKey:@"foo"];
XCTAssertEqual(dict.count, 1U);
const NSString *kKeys[] = { @"bar", @"baz", @"mumble" };
const uint32_t kValues[] = { 101U, 102U, 103U };
GPBStringUInt32Dictionary *dict2 =
- [[GPBStringUInt32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
uint32_t value;
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getUInt32:&value forKey:@"foo"]);
XCTAssertEqual(value, 100U);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getUInt32:&value forKey:@"bar"]);
XCTAssertEqual(value, 101U);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getUInt32:&value forKey:@"baz"]);
XCTAssertEqual(value, 102U);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getUInt32:&value forKey:@"mumble"]);
XCTAssertEqual(value, 103U);
[dict2 release];
}
@@ -305,57 +305,57 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
const uint32_t kValues[] = { 100U, 101U, 102U, 103U };
GPBStringUInt32Dictionary *dict =
- [[GPBStringUInt32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
- [dict removeValueForKey:@"bar"];
+ [dict removeUInt32ForKey:@"bar"];
XCTAssertEqual(dict.count, 3U);
uint32_t value;
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getUInt32:&value forKey:@"foo"]);
XCTAssertEqual(value, 100U);
- XCTAssertFalse([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getUInt32:&value forKey:@"baz"]);
XCTAssertEqual(value, 102U);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getUInt32:&value forKey:@"mumble"]);
XCTAssertEqual(value, 103U);
// Remove again does nothing.
- [dict removeValueForKey:@"bar"];
+ [dict removeUInt32ForKey:@"bar"];
XCTAssertEqual(dict.count, 3U);
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getUInt32:&value forKey:@"foo"]);
XCTAssertEqual(value, 100U);
- XCTAssertFalse([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getUInt32:&value forKey:@"baz"]);
XCTAssertEqual(value, 102U);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getUInt32:&value forKey:@"mumble"]);
XCTAssertEqual(value, 103U);
- [dict removeValueForKey:@"mumble"];
+ [dict removeUInt32ForKey:@"mumble"];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getUInt32:&value forKey:@"foo"]);
XCTAssertEqual(value, 100U);
- XCTAssertFalse([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getUInt32:&value forKey:@"baz"]);
XCTAssertEqual(value, 102U);
- XCTAssertFalse([dict valueForKey:@"mumble" value:NULL]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:@"mumble"]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:@"foo" value:NULL]);
- XCTAssertFalse([dict valueForKey:@"bar" value:NULL]);
- XCTAssertFalse([dict valueForKey:@"baz" value:NULL]);
- XCTAssertFalse([dict valueForKey:@"mumble" value:NULL]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:@"foo"]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:@"bar"]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:@"baz"]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:@"mumble"]);
[dict release];
}
@@ -363,75 +363,75 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
const uint32_t kValues[] = { 100U, 101U, 102U, 103U };
GPBStringUInt32Dictionary *dict =
- [[GPBStringUInt32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
uint32_t value;
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getUInt32:&value forKey:@"foo"]);
XCTAssertEqual(value, 100U);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getUInt32:&value forKey:@"bar"]);
XCTAssertEqual(value, 101U);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getUInt32:&value forKey:@"baz"]);
XCTAssertEqual(value, 102U);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getUInt32:&value forKey:@"mumble"]);
XCTAssertEqual(value, 103U);
- [dict setValue:103U forKey:@"foo"];
+ [dict setUInt32:103U forKey:@"foo"];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getUInt32:&value forKey:@"foo"]);
XCTAssertEqual(value, 103U);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getUInt32:&value forKey:@"bar"]);
XCTAssertEqual(value, 101U);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getUInt32:&value forKey:@"baz"]);
XCTAssertEqual(value, 102U);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getUInt32:&value forKey:@"mumble"]);
XCTAssertEqual(value, 103U);
- [dict setValue:101U forKey:@"mumble"];
+ [dict setUInt32:101U forKey:@"mumble"];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getUInt32:&value forKey:@"foo"]);
XCTAssertEqual(value, 103U);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getUInt32:&value forKey:@"bar"]);
XCTAssertEqual(value, 101U);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getUInt32:&value forKey:@"baz"]);
XCTAssertEqual(value, 102U);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getUInt32:&value forKey:@"mumble"]);
XCTAssertEqual(value, 101U);
const NSString *kKeys2[] = { @"bar", @"baz" };
const uint32_t kValues2[] = { 102U, 100U };
GPBStringUInt32Dictionary *dict2 =
- [[GPBStringUInt32Dictionary alloc] initWithValues:kValues2
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues2
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getUInt32:&value forKey:@"foo"]);
XCTAssertEqual(value, 103U);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getUInt32:&value forKey:@"bar"]);
XCTAssertEqual(value, 102U);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getUInt32:&value forKey:@"baz"]);
XCTAssertEqual(value, 100U);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getUInt32:&value forKey:@"mumble"]);
XCTAssertEqual(value, 101U);
[dict2 release];
@@ -451,8 +451,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
GPBStringInt32Dictionary *dict = [[GPBStringInt32Dictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:@"foo" value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getInt32:NULL forKey:@"foo"]);
+ [dict enumerateKeysAndInt32sUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -460,15 +460,15 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testOne {
- GPBStringInt32Dictionary *dict = [GPBStringInt32Dictionary dictionaryWithValue:200 forKey:@"foo"];
+ GPBStringInt32Dictionary *dict = [GPBStringInt32Dictionary dictionaryWithInt32:200 forKey:@"foo"];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
int32_t value;
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getInt32:&value forKey:@"foo"]);
XCTAssertEqual(value, 200);
- XCTAssertFalse([dict valueForKey:@"bar" value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getInt32:NULL forKey:@"bar"]);
+ [dict enumerateKeysAndInt32sUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) {
XCTAssertEqualObjects(aKey, @"foo");
XCTAssertEqual(aValue, 200);
XCTAssertNotEqual(stop, NULL);
@@ -479,27 +479,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const NSString *kKeys[] = { @"foo", @"bar", @"baz" };
const int32_t kValues[] = { 200, 201, 202 };
GPBStringInt32Dictionary *dict =
- [[GPBStringInt32Dictionary alloc] initWithValues:kValues
+ [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 3U);
int32_t value;
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getInt32:&value forKey:@"foo"]);
XCTAssertEqual(value, 200);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getInt32:&value forKey:@"bar"]);
XCTAssertEqual(value, 201);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getInt32:&value forKey:@"baz"]);
XCTAssertEqual(value, 202);
- XCTAssertFalse([dict valueForKey:@"mumble" value:NULL]);
+ XCTAssertFalse([dict getInt32:NULL forKey:@"mumble"]);
__block NSUInteger idx = 0;
NSString **seenKeys = malloc(3 * sizeof(NSString*));
int32_t *seenValues = malloc(3 * sizeof(int32_t));
- [dict enumerateKeysAndValuesUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndInt32sUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -521,7 +521,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndInt32sUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -537,27 +537,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kValues2[] = { 200, 203, 202 };
const int32_t kValues3[] = { 200, 201, 202, 203 };
GPBStringInt32Dictionary *dict1 =
- [[GPBStringInt32Dictionary alloc] initWithValues:kValues1
+ [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues1
forKeys:kKeys1
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBStringInt32Dictionary *dict1prime =
- [[GPBStringInt32Dictionary alloc] initWithValues:kValues1
+ [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues1
forKeys:kKeys1
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBStringInt32Dictionary *dict2 =
- [[GPBStringInt32Dictionary alloc] initWithValues:kValues2
+ [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues2
forKeys:kKeys1
count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBStringInt32Dictionary *dict3 =
- [[GPBStringInt32Dictionary alloc] initWithValues:kValues1
+ [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues1
forKeys:kKeys2
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBStringInt32Dictionary *dict4 =
- [[GPBStringInt32Dictionary alloc] initWithValues:kValues3
+ [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues3
forKeys:kKeys1
count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
@@ -588,7 +588,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
const int32_t kValues[] = { 200, 201, 202, 203 };
GPBStringInt32Dictionary *dict =
- [[GPBStringInt32Dictionary alloc] initWithValues:kValues
+ [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
@@ -609,7 +609,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
const int32_t kValues[] = { 200, 201, 202, 203 };
GPBStringInt32Dictionary *dict =
- [[GPBStringInt32Dictionary alloc] initWithValues:kValues
+ [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
@@ -629,13 +629,13 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:200 forKey:@"foo"];
+ [dict setInt32:200 forKey:@"foo"];
XCTAssertEqual(dict.count, 1U);
const NSString *kKeys[] = { @"bar", @"baz", @"mumble" };
const int32_t kValues[] = { 201, 202, 203 };
GPBStringInt32Dictionary *dict2 =
- [[GPBStringInt32Dictionary alloc] initWithValues:kValues
+ [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
@@ -643,17 +643,17 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertEqual(dict.count, 4U);
int32_t value;
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getInt32:&value forKey:@"foo"]);
XCTAssertEqual(value, 200);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getInt32:&value forKey:@"bar"]);
XCTAssertEqual(value, 201);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getInt32:&value forKey:@"baz"]);
XCTAssertEqual(value, 202);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getInt32:&value forKey:@"mumble"]);
XCTAssertEqual(value, 203);
[dict2 release];
}
@@ -662,57 +662,57 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
const int32_t kValues[] = { 200, 201, 202, 203 };
GPBStringInt32Dictionary *dict =
- [[GPBStringInt32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
- [dict removeValueForKey:@"bar"];
+ [dict removeInt32ForKey:@"bar"];
XCTAssertEqual(dict.count, 3U);
int32_t value;
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getInt32:&value forKey:@"foo"]);
XCTAssertEqual(value, 200);
- XCTAssertFalse([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertFalse([dict getInt32:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getInt32:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getInt32:&value forKey:@"baz"]);
XCTAssertEqual(value, 202);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getInt32:&value forKey:@"mumble"]);
XCTAssertEqual(value, 203);
// Remove again does nothing.
- [dict removeValueForKey:@"bar"];
+ [dict removeInt32ForKey:@"bar"];
XCTAssertEqual(dict.count, 3U);
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getInt32:&value forKey:@"foo"]);
XCTAssertEqual(value, 200);
- XCTAssertFalse([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertFalse([dict getInt32:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getInt32:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getInt32:&value forKey:@"baz"]);
XCTAssertEqual(value, 202);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getInt32:&value forKey:@"mumble"]);
XCTAssertEqual(value, 203);
- [dict removeValueForKey:@"mumble"];
+ [dict removeInt32ForKey:@"mumble"];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getInt32:&value forKey:@"foo"]);
XCTAssertEqual(value, 200);
- XCTAssertFalse([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertFalse([dict getInt32:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getInt32:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getInt32:&value forKey:@"baz"]);
XCTAssertEqual(value, 202);
- XCTAssertFalse([dict valueForKey:@"mumble" value:NULL]);
+ XCTAssertFalse([dict getInt32:NULL forKey:@"mumble"]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:@"foo" value:NULL]);
- XCTAssertFalse([dict valueForKey:@"bar" value:NULL]);
- XCTAssertFalse([dict valueForKey:@"baz" value:NULL]);
- XCTAssertFalse([dict valueForKey:@"mumble" value:NULL]);
+ XCTAssertFalse([dict getInt32:NULL forKey:@"foo"]);
+ XCTAssertFalse([dict getInt32:NULL forKey:@"bar"]);
+ XCTAssertFalse([dict getInt32:NULL forKey:@"baz"]);
+ XCTAssertFalse([dict getInt32:NULL forKey:@"mumble"]);
[dict release];
}
@@ -720,75 +720,75 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
const int32_t kValues[] = { 200, 201, 202, 203 };
GPBStringInt32Dictionary *dict =
- [[GPBStringInt32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
int32_t value;
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getInt32:&value forKey:@"foo"]);
XCTAssertEqual(value, 200);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getInt32:&value forKey:@"bar"]);
XCTAssertEqual(value, 201);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getInt32:&value forKey:@"baz"]);
XCTAssertEqual(value, 202);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getInt32:&value forKey:@"mumble"]);
XCTAssertEqual(value, 203);
- [dict setValue:203 forKey:@"foo"];
+ [dict setInt32:203 forKey:@"foo"];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getInt32:&value forKey:@"foo"]);
XCTAssertEqual(value, 203);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getInt32:&value forKey:@"bar"]);
XCTAssertEqual(value, 201);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getInt32:&value forKey:@"baz"]);
XCTAssertEqual(value, 202);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getInt32:&value forKey:@"mumble"]);
XCTAssertEqual(value, 203);
- [dict setValue:201 forKey:@"mumble"];
+ [dict setInt32:201 forKey:@"mumble"];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getInt32:&value forKey:@"foo"]);
XCTAssertEqual(value, 203);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getInt32:&value forKey:@"bar"]);
XCTAssertEqual(value, 201);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getInt32:&value forKey:@"baz"]);
XCTAssertEqual(value, 202);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getInt32:&value forKey:@"mumble"]);
XCTAssertEqual(value, 201);
const NSString *kKeys2[] = { @"bar", @"baz" };
const int32_t kValues2[] = { 202, 200 };
GPBStringInt32Dictionary *dict2 =
- [[GPBStringInt32Dictionary alloc] initWithValues:kValues2
+ [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues2
forKeys:kKeys2
count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getInt32:&value forKey:@"foo"]);
XCTAssertEqual(value, 203);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getInt32:&value forKey:@"bar"]);
XCTAssertEqual(value, 202);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getInt32:&value forKey:@"baz"]);
XCTAssertEqual(value, 200);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getInt32:&value forKey:@"mumble"]);
XCTAssertEqual(value, 201);
[dict2 release];
@@ -808,8 +808,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
GPBStringUInt64Dictionary *dict = [[GPBStringUInt64Dictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:@"foo" value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(NSString *aKey, uint64_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getUInt64:NULL forKey:@"foo"]);
+ [dict enumerateKeysAndUInt64sUsingBlock:^(NSString *aKey, uint64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -817,15 +817,15 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testOne {
- GPBStringUInt64Dictionary *dict = [GPBStringUInt64Dictionary dictionaryWithValue:300U forKey:@"foo"];
+ GPBStringUInt64Dictionary *dict = [GPBStringUInt64Dictionary dictionaryWithUInt64:300U forKey:@"foo"];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
uint64_t value;
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getUInt64:&value forKey:@"foo"]);
XCTAssertEqual(value, 300U);
- XCTAssertFalse([dict valueForKey:@"bar" value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(NSString *aKey, uint64_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getUInt64:NULL forKey:@"bar"]);
+ [dict enumerateKeysAndUInt64sUsingBlock:^(NSString *aKey, uint64_t aValue, BOOL *stop) {
XCTAssertEqualObjects(aKey, @"foo");
XCTAssertEqual(aValue, 300U);
XCTAssertNotEqual(stop, NULL);
@@ -836,27 +836,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const NSString *kKeys[] = { @"foo", @"bar", @"baz" };
const uint64_t kValues[] = { 300U, 301U, 302U };
GPBStringUInt64Dictionary *dict =
- [[GPBStringUInt64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 3U);
uint64_t value;
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getUInt64:&value forKey:@"foo"]);
XCTAssertEqual(value, 300U);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getUInt64:&value forKey:@"bar"]);
XCTAssertEqual(value, 301U);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getUInt64:&value forKey:@"baz"]);
XCTAssertEqual(value, 302U);
- XCTAssertFalse([dict valueForKey:@"mumble" value:NULL]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:@"mumble"]);
__block NSUInteger idx = 0;
NSString **seenKeys = malloc(3 * sizeof(NSString*));
uint64_t *seenValues = malloc(3 * sizeof(uint64_t));
- [dict enumerateKeysAndValuesUsingBlock:^(NSString *aKey, uint64_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndUInt64sUsingBlock:^(NSString *aKey, uint64_t aValue, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -878,7 +878,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(NSString *aKey, uint64_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndUInt64sUsingBlock:^(NSString *aKey, uint64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -894,29 +894,29 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint64_t kValues2[] = { 300U, 303U, 302U };
const uint64_t kValues3[] = { 300U, 301U, 302U, 303U };
GPBStringUInt64Dictionary *dict1 =
- [[GPBStringUInt64Dictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBStringUInt64Dictionary *dict1prime =
- [[GPBStringUInt64Dictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBStringUInt64Dictionary *dict2 =
- [[GPBStringUInt64Dictionary alloc] initWithValues:kValues2
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues2
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBStringUInt64Dictionary *dict3 =
- [[GPBStringUInt64Dictionary alloc] initWithValues:kValues1
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues1
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBStringUInt64Dictionary *dict4 =
- [[GPBStringUInt64Dictionary alloc] initWithValues:kValues3
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues3)];
+ [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues3
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
// 1/1Prime should be different objects, but equal.
@@ -945,9 +945,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
const uint64_t kValues[] = { 300U, 301U, 302U, 303U };
GPBStringUInt64Dictionary *dict =
- [[GPBStringUInt64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBStringUInt64Dictionary *dict2 = [dict copy];
@@ -966,9 +966,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
const uint64_t kValues[] = { 300U, 301U, 302U, 303U };
GPBStringUInt64Dictionary *dict =
- [[GPBStringUInt64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBStringUInt64Dictionary *dict2 =
@@ -986,31 +986,31 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:300U forKey:@"foo"];
+ [dict setUInt64:300U forKey:@"foo"];
XCTAssertEqual(dict.count, 1U);
const NSString *kKeys[] = { @"bar", @"baz", @"mumble" };
const uint64_t kValues[] = { 301U, 302U, 303U };
GPBStringUInt64Dictionary *dict2 =
- [[GPBStringUInt64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
uint64_t value;
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getUInt64:&value forKey:@"foo"]);
XCTAssertEqual(value, 300U);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getUInt64:&value forKey:@"bar"]);
XCTAssertEqual(value, 301U);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getUInt64:&value forKey:@"baz"]);
XCTAssertEqual(value, 302U);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getUInt64:&value forKey:@"mumble"]);
XCTAssertEqual(value, 303U);
[dict2 release];
}
@@ -1019,57 +1019,57 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
const uint64_t kValues[] = { 300U, 301U, 302U, 303U };
GPBStringUInt64Dictionary *dict =
- [[GPBStringUInt64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
- [dict removeValueForKey:@"bar"];
+ [dict removeUInt64ForKey:@"bar"];
XCTAssertEqual(dict.count, 3U);
uint64_t value;
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getUInt64:&value forKey:@"foo"]);
XCTAssertEqual(value, 300U);
- XCTAssertFalse([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getUInt64:&value forKey:@"baz"]);
XCTAssertEqual(value, 302U);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getUInt64:&value forKey:@"mumble"]);
XCTAssertEqual(value, 303U);
// Remove again does nothing.
- [dict removeValueForKey:@"bar"];
+ [dict removeUInt64ForKey:@"bar"];
XCTAssertEqual(dict.count, 3U);
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getUInt64:&value forKey:@"foo"]);
XCTAssertEqual(value, 300U);
- XCTAssertFalse([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getUInt64:&value forKey:@"baz"]);
XCTAssertEqual(value, 302U);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getUInt64:&value forKey:@"mumble"]);
XCTAssertEqual(value, 303U);
- [dict removeValueForKey:@"mumble"];
+ [dict removeUInt64ForKey:@"mumble"];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getUInt64:&value forKey:@"foo"]);
XCTAssertEqual(value, 300U);
- XCTAssertFalse([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getUInt64:&value forKey:@"baz"]);
XCTAssertEqual(value, 302U);
- XCTAssertFalse([dict valueForKey:@"mumble" value:NULL]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:@"mumble"]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:@"foo" value:NULL]);
- XCTAssertFalse([dict valueForKey:@"bar" value:NULL]);
- XCTAssertFalse([dict valueForKey:@"baz" value:NULL]);
- XCTAssertFalse([dict valueForKey:@"mumble" value:NULL]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:@"foo"]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:@"bar"]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:@"baz"]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:@"mumble"]);
[dict release];
}
@@ -1077,75 +1077,75 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
const uint64_t kValues[] = { 300U, 301U, 302U, 303U };
GPBStringUInt64Dictionary *dict =
- [[GPBStringUInt64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
uint64_t value;
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getUInt64:&value forKey:@"foo"]);
XCTAssertEqual(value, 300U);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getUInt64:&value forKey:@"bar"]);
XCTAssertEqual(value, 301U);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getUInt64:&value forKey:@"baz"]);
XCTAssertEqual(value, 302U);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getUInt64:&value forKey:@"mumble"]);
XCTAssertEqual(value, 303U);
- [dict setValue:303U forKey:@"foo"];
+ [dict setUInt64:303U forKey:@"foo"];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getUInt64:&value forKey:@"foo"]);
XCTAssertEqual(value, 303U);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getUInt64:&value forKey:@"bar"]);
XCTAssertEqual(value, 301U);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getUInt64:&value forKey:@"baz"]);
XCTAssertEqual(value, 302U);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getUInt64:&value forKey:@"mumble"]);
XCTAssertEqual(value, 303U);
- [dict setValue:301U forKey:@"mumble"];
+ [dict setUInt64:301U forKey:@"mumble"];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getUInt64:&value forKey:@"foo"]);
XCTAssertEqual(value, 303U);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getUInt64:&value forKey:@"bar"]);
XCTAssertEqual(value, 301U);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getUInt64:&value forKey:@"baz"]);
XCTAssertEqual(value, 302U);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getUInt64:&value forKey:@"mumble"]);
XCTAssertEqual(value, 301U);
const NSString *kKeys2[] = { @"bar", @"baz" };
const uint64_t kValues2[] = { 302U, 300U };
GPBStringUInt64Dictionary *dict2 =
- [[GPBStringUInt64Dictionary alloc] initWithValues:kValues2
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues2
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getUInt64:&value forKey:@"foo"]);
XCTAssertEqual(value, 303U);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getUInt64:&value forKey:@"bar"]);
XCTAssertEqual(value, 302U);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getUInt64:&value forKey:@"baz"]);
XCTAssertEqual(value, 300U);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getUInt64:&value forKey:@"mumble"]);
XCTAssertEqual(value, 301U);
[dict2 release];
@@ -1165,8 +1165,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
GPBStringInt64Dictionary *dict = [[GPBStringInt64Dictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:@"foo" value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(NSString *aKey, int64_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getInt64:NULL forKey:@"foo"]);
+ [dict enumerateKeysAndInt64sUsingBlock:^(NSString *aKey, int64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -1174,15 +1174,15 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testOne {
- GPBStringInt64Dictionary *dict = [GPBStringInt64Dictionary dictionaryWithValue:400 forKey:@"foo"];
+ GPBStringInt64Dictionary *dict = [GPBStringInt64Dictionary dictionaryWithInt64:400 forKey:@"foo"];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
int64_t value;
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getInt64:&value forKey:@"foo"]);
XCTAssertEqual(value, 400);
- XCTAssertFalse([dict valueForKey:@"bar" value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(NSString *aKey, int64_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getInt64:NULL forKey:@"bar"]);
+ [dict enumerateKeysAndInt64sUsingBlock:^(NSString *aKey, int64_t aValue, BOOL *stop) {
XCTAssertEqualObjects(aKey, @"foo");
XCTAssertEqual(aValue, 400);
XCTAssertNotEqual(stop, NULL);
@@ -1193,27 +1193,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const NSString *kKeys[] = { @"foo", @"bar", @"baz" };
const int64_t kValues[] = { 400, 401, 402 };
GPBStringInt64Dictionary *dict =
- [[GPBStringInt64Dictionary alloc] initWithValues:kValues
+ [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 3U);
int64_t value;
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getInt64:&value forKey:@"foo"]);
XCTAssertEqual(value, 400);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getInt64:&value forKey:@"bar"]);
XCTAssertEqual(value, 401);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getInt64:&value forKey:@"baz"]);
XCTAssertEqual(value, 402);
- XCTAssertFalse([dict valueForKey:@"mumble" value:NULL]);
+ XCTAssertFalse([dict getInt64:NULL forKey:@"mumble"]);
__block NSUInteger idx = 0;
NSString **seenKeys = malloc(3 * sizeof(NSString*));
int64_t *seenValues = malloc(3 * sizeof(int64_t));
- [dict enumerateKeysAndValuesUsingBlock:^(NSString *aKey, int64_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndInt64sUsingBlock:^(NSString *aKey, int64_t aValue, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -1235,7 +1235,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(NSString *aKey, int64_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndInt64sUsingBlock:^(NSString *aKey, int64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -1251,27 +1251,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int64_t kValues2[] = { 400, 403, 402 };
const int64_t kValues3[] = { 400, 401, 402, 403 };
GPBStringInt64Dictionary *dict1 =
- [[GPBStringInt64Dictionary alloc] initWithValues:kValues1
+ [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues1
forKeys:kKeys1
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBStringInt64Dictionary *dict1prime =
- [[GPBStringInt64Dictionary alloc] initWithValues:kValues1
+ [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues1
forKeys:kKeys1
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBStringInt64Dictionary *dict2 =
- [[GPBStringInt64Dictionary alloc] initWithValues:kValues2
+ [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues2
forKeys:kKeys1
count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBStringInt64Dictionary *dict3 =
- [[GPBStringInt64Dictionary alloc] initWithValues:kValues1
+ [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues1
forKeys:kKeys2
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBStringInt64Dictionary *dict4 =
- [[GPBStringInt64Dictionary alloc] initWithValues:kValues3
+ [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues3
forKeys:kKeys1
count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
@@ -1302,7 +1302,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
const int64_t kValues[] = { 400, 401, 402, 403 };
GPBStringInt64Dictionary *dict =
- [[GPBStringInt64Dictionary alloc] initWithValues:kValues
+ [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
@@ -1323,7 +1323,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
const int64_t kValues[] = { 400, 401, 402, 403 };
GPBStringInt64Dictionary *dict =
- [[GPBStringInt64Dictionary alloc] initWithValues:kValues
+ [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
@@ -1343,13 +1343,13 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:400 forKey:@"foo"];
+ [dict setInt64:400 forKey:@"foo"];
XCTAssertEqual(dict.count, 1U);
const NSString *kKeys[] = { @"bar", @"baz", @"mumble" };
const int64_t kValues[] = { 401, 402, 403 };
GPBStringInt64Dictionary *dict2 =
- [[GPBStringInt64Dictionary alloc] initWithValues:kValues
+ [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
@@ -1357,17 +1357,17 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertEqual(dict.count, 4U);
int64_t value;
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getInt64:&value forKey:@"foo"]);
XCTAssertEqual(value, 400);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getInt64:&value forKey:@"bar"]);
XCTAssertEqual(value, 401);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getInt64:&value forKey:@"baz"]);
XCTAssertEqual(value, 402);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getInt64:&value forKey:@"mumble"]);
XCTAssertEqual(value, 403);
[dict2 release];
}
@@ -1376,57 +1376,57 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
const int64_t kValues[] = { 400, 401, 402, 403 };
GPBStringInt64Dictionary *dict =
- [[GPBStringInt64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
- [dict removeValueForKey:@"bar"];
+ [dict removeInt64ForKey:@"bar"];
XCTAssertEqual(dict.count, 3U);
int64_t value;
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getInt64:&value forKey:@"foo"]);
XCTAssertEqual(value, 400);
- XCTAssertFalse([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertFalse([dict getInt64:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getInt64:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getInt64:&value forKey:@"baz"]);
XCTAssertEqual(value, 402);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getInt64:&value forKey:@"mumble"]);
XCTAssertEqual(value, 403);
// Remove again does nothing.
- [dict removeValueForKey:@"bar"];
+ [dict removeInt64ForKey:@"bar"];
XCTAssertEqual(dict.count, 3U);
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getInt64:&value forKey:@"foo"]);
XCTAssertEqual(value, 400);
- XCTAssertFalse([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertFalse([dict getInt64:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getInt64:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getInt64:&value forKey:@"baz"]);
XCTAssertEqual(value, 402);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getInt64:&value forKey:@"mumble"]);
XCTAssertEqual(value, 403);
- [dict removeValueForKey:@"mumble"];
+ [dict removeInt64ForKey:@"mumble"];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getInt64:&value forKey:@"foo"]);
XCTAssertEqual(value, 400);
- XCTAssertFalse([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertFalse([dict getInt64:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getInt64:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getInt64:&value forKey:@"baz"]);
XCTAssertEqual(value, 402);
- XCTAssertFalse([dict valueForKey:@"mumble" value:NULL]);
+ XCTAssertFalse([dict getInt64:NULL forKey:@"mumble"]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:@"foo" value:NULL]);
- XCTAssertFalse([dict valueForKey:@"bar" value:NULL]);
- XCTAssertFalse([dict valueForKey:@"baz" value:NULL]);
- XCTAssertFalse([dict valueForKey:@"mumble" value:NULL]);
+ XCTAssertFalse([dict getInt64:NULL forKey:@"foo"]);
+ XCTAssertFalse([dict getInt64:NULL forKey:@"bar"]);
+ XCTAssertFalse([dict getInt64:NULL forKey:@"baz"]);
+ XCTAssertFalse([dict getInt64:NULL forKey:@"mumble"]);
[dict release];
}
@@ -1434,75 +1434,75 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
const int64_t kValues[] = { 400, 401, 402, 403 };
GPBStringInt64Dictionary *dict =
- [[GPBStringInt64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
int64_t value;
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getInt64:&value forKey:@"foo"]);
XCTAssertEqual(value, 400);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getInt64:&value forKey:@"bar"]);
XCTAssertEqual(value, 401);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getInt64:&value forKey:@"baz"]);
XCTAssertEqual(value, 402);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getInt64:&value forKey:@"mumble"]);
XCTAssertEqual(value, 403);
- [dict setValue:403 forKey:@"foo"];
+ [dict setInt64:403 forKey:@"foo"];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getInt64:&value forKey:@"foo"]);
XCTAssertEqual(value, 403);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getInt64:&value forKey:@"bar"]);
XCTAssertEqual(value, 401);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getInt64:&value forKey:@"baz"]);
XCTAssertEqual(value, 402);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getInt64:&value forKey:@"mumble"]);
XCTAssertEqual(value, 403);
- [dict setValue:401 forKey:@"mumble"];
+ [dict setInt64:401 forKey:@"mumble"];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getInt64:&value forKey:@"foo"]);
XCTAssertEqual(value, 403);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getInt64:&value forKey:@"bar"]);
XCTAssertEqual(value, 401);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getInt64:&value forKey:@"baz"]);
XCTAssertEqual(value, 402);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getInt64:&value forKey:@"mumble"]);
XCTAssertEqual(value, 401);
const NSString *kKeys2[] = { @"bar", @"baz" };
const int64_t kValues2[] = { 402, 400 };
GPBStringInt64Dictionary *dict2 =
- [[GPBStringInt64Dictionary alloc] initWithValues:kValues2
+ [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues2
forKeys:kKeys2
count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getInt64:&value forKey:@"foo"]);
XCTAssertEqual(value, 403);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getInt64:&value forKey:@"bar"]);
XCTAssertEqual(value, 402);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getInt64:&value forKey:@"baz"]);
XCTAssertEqual(value, 400);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getInt64:&value forKey:@"mumble"]);
XCTAssertEqual(value, 401);
[dict2 release];
@@ -1522,8 +1522,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
GPBStringBoolDictionary *dict = [[GPBStringBoolDictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:@"foo" value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(NSString *aKey, BOOL aValue, BOOL *stop) {
+ XCTAssertFalse([dict getBool:NULL forKey:@"foo"]);
+ [dict enumerateKeysAndBoolsUsingBlock:^(NSString *aKey, BOOL aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -1531,15 +1531,15 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testOne {
- GPBStringBoolDictionary *dict = [GPBStringBoolDictionary dictionaryWithValue:YES forKey:@"foo"];
+ GPBStringBoolDictionary *dict = [GPBStringBoolDictionary dictionaryWithBool:YES forKey:@"foo"];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
BOOL value;
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getBool:&value forKey:@"foo"]);
XCTAssertEqual(value, YES);
- XCTAssertFalse([dict valueForKey:@"bar" value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(NSString *aKey, BOOL aValue, BOOL *stop) {
+ XCTAssertFalse([dict getBool:NULL forKey:@"bar"]);
+ [dict enumerateKeysAndBoolsUsingBlock:^(NSString *aKey, BOOL aValue, BOOL *stop) {
XCTAssertEqualObjects(aKey, @"foo");
XCTAssertEqual(aValue, YES);
XCTAssertNotEqual(stop, NULL);
@@ -1550,27 +1550,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const NSString *kKeys[] = { @"foo", @"bar", @"baz" };
const BOOL kValues[] = { YES, YES, NO };
GPBStringBoolDictionary *dict =
- [[GPBStringBoolDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBStringBoolDictionary alloc] initWithBools:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 3U);
BOOL value;
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getBool:&value forKey:@"foo"]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getBool:&value forKey:@"bar"]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getBool:&value forKey:@"baz"]);
XCTAssertEqual(value, NO);
- XCTAssertFalse([dict valueForKey:@"mumble" value:NULL]);
+ XCTAssertFalse([dict getBool:NULL forKey:@"mumble"]);
__block NSUInteger idx = 0;
NSString **seenKeys = malloc(3 * sizeof(NSString*));
BOOL *seenValues = malloc(3 * sizeof(BOOL));
- [dict enumerateKeysAndValuesUsingBlock:^(NSString *aKey, BOOL aValue, BOOL *stop) {
+ [dict enumerateKeysAndBoolsUsingBlock:^(NSString *aKey, BOOL aValue, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -1592,7 +1592,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(NSString *aKey, BOOL aValue, BOOL *stop) {
+ [dict enumerateKeysAndBoolsUsingBlock:^(NSString *aKey, BOOL aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -1608,29 +1608,29 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const BOOL kValues2[] = { YES, NO, NO };
const BOOL kValues3[] = { YES, YES, NO, NO };
GPBStringBoolDictionary *dict1 =
- [[GPBStringBoolDictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBStringBoolDictionary alloc] initWithBools:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBStringBoolDictionary *dict1prime =
- [[GPBStringBoolDictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBStringBoolDictionary alloc] initWithBools:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBStringBoolDictionary *dict2 =
- [[GPBStringBoolDictionary alloc] initWithValues:kValues2
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBStringBoolDictionary alloc] initWithBools:kValues2
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBStringBoolDictionary *dict3 =
- [[GPBStringBoolDictionary alloc] initWithValues:kValues1
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBStringBoolDictionary alloc] initWithBools:kValues1
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBStringBoolDictionary *dict4 =
- [[GPBStringBoolDictionary alloc] initWithValues:kValues3
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues3)];
+ [[GPBStringBoolDictionary alloc] initWithBools:kValues3
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
// 1/1Prime should be different objects, but equal.
@@ -1659,9 +1659,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
const BOOL kValues[] = { YES, YES, NO, NO };
GPBStringBoolDictionary *dict =
- [[GPBStringBoolDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBStringBoolDictionary alloc] initWithBools:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBStringBoolDictionary *dict2 = [dict copy];
@@ -1680,9 +1680,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
const BOOL kValues[] = { YES, YES, NO, NO };
GPBStringBoolDictionary *dict =
- [[GPBStringBoolDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBStringBoolDictionary alloc] initWithBools:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBStringBoolDictionary *dict2 =
@@ -1700,31 +1700,31 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:YES forKey:@"foo"];
+ [dict setBool:YES forKey:@"foo"];
XCTAssertEqual(dict.count, 1U);
const NSString *kKeys[] = { @"bar", @"baz", @"mumble" };
const BOOL kValues[] = { YES, NO, NO };
GPBStringBoolDictionary *dict2 =
- [[GPBStringBoolDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBStringBoolDictionary alloc] initWithBools:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
BOOL value;
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getBool:&value forKey:@"foo"]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getBool:&value forKey:@"bar"]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getBool:&value forKey:@"baz"]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getBool:&value forKey:@"mumble"]);
XCTAssertEqual(value, NO);
[dict2 release];
}
@@ -1733,57 +1733,57 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
const BOOL kValues[] = { YES, YES, NO, NO };
GPBStringBoolDictionary *dict =
- [[GPBStringBoolDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBStringBoolDictionary alloc] initWithBools:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
- [dict removeValueForKey:@"bar"];
+ [dict removeBoolForKey:@"bar"];
XCTAssertEqual(dict.count, 3U);
BOOL value;
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getBool:&value forKey:@"foo"]);
XCTAssertEqual(value, YES);
- XCTAssertFalse([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertFalse([dict getBool:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getBool:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getBool:&value forKey:@"baz"]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getBool:&value forKey:@"mumble"]);
XCTAssertEqual(value, NO);
// Remove again does nothing.
- [dict removeValueForKey:@"bar"];
+ [dict removeBoolForKey:@"bar"];
XCTAssertEqual(dict.count, 3U);
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getBool:&value forKey:@"foo"]);
XCTAssertEqual(value, YES);
- XCTAssertFalse([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertFalse([dict getBool:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getBool:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getBool:&value forKey:@"baz"]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getBool:&value forKey:@"mumble"]);
XCTAssertEqual(value, NO);
- [dict removeValueForKey:@"mumble"];
+ [dict removeBoolForKey:@"mumble"];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getBool:&value forKey:@"foo"]);
XCTAssertEqual(value, YES);
- XCTAssertFalse([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertFalse([dict getBool:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getBool:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getBool:&value forKey:@"baz"]);
XCTAssertEqual(value, NO);
- XCTAssertFalse([dict valueForKey:@"mumble" value:NULL]);
+ XCTAssertFalse([dict getBool:NULL forKey:@"mumble"]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:@"foo" value:NULL]);
- XCTAssertFalse([dict valueForKey:@"bar" value:NULL]);
- XCTAssertFalse([dict valueForKey:@"baz" value:NULL]);
- XCTAssertFalse([dict valueForKey:@"mumble" value:NULL]);
+ XCTAssertFalse([dict getBool:NULL forKey:@"foo"]);
+ XCTAssertFalse([dict getBool:NULL forKey:@"bar"]);
+ XCTAssertFalse([dict getBool:NULL forKey:@"baz"]);
+ XCTAssertFalse([dict getBool:NULL forKey:@"mumble"]);
[dict release];
}
@@ -1791,75 +1791,75 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
const BOOL kValues[] = { YES, YES, NO, NO };
GPBStringBoolDictionary *dict =
- [[GPBStringBoolDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBStringBoolDictionary alloc] initWithBools:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
BOOL value;
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getBool:&value forKey:@"foo"]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getBool:&value forKey:@"bar"]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getBool:&value forKey:@"baz"]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getBool:&value forKey:@"mumble"]);
XCTAssertEqual(value, NO);
- [dict setValue:NO forKey:@"foo"];
+ [dict setBool:NO forKey:@"foo"];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getBool:&value forKey:@"foo"]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getBool:&value forKey:@"bar"]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getBool:&value forKey:@"baz"]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getBool:&value forKey:@"mumble"]);
XCTAssertEqual(value, NO);
- [dict setValue:YES forKey:@"mumble"];
+ [dict setBool:YES forKey:@"mumble"];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getBool:&value forKey:@"foo"]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getBool:&value forKey:@"bar"]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getBool:&value forKey:@"baz"]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getBool:&value forKey:@"mumble"]);
XCTAssertEqual(value, YES);
const NSString *kKeys2[] = { @"bar", @"baz" };
const BOOL kValues2[] = { NO, YES };
GPBStringBoolDictionary *dict2 =
- [[GPBStringBoolDictionary alloc] initWithValues:kValues2
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBStringBoolDictionary alloc] initWithBools:kValues2
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getBool:&value forKey:@"foo"]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getBool:&value forKey:@"bar"]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getBool:&value forKey:@"baz"]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getBool:&value forKey:@"mumble"]);
XCTAssertEqual(value, YES);
[dict2 release];
@@ -1879,8 +1879,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
GPBStringFloatDictionary *dict = [[GPBStringFloatDictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:@"foo" value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(NSString *aKey, float aValue, BOOL *stop) {
+ XCTAssertFalse([dict getFloat:NULL forKey:@"foo"]);
+ [dict enumerateKeysAndFloatsUsingBlock:^(NSString *aKey, float aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -1888,15 +1888,15 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testOne {
- GPBStringFloatDictionary *dict = [GPBStringFloatDictionary dictionaryWithValue:500.f forKey:@"foo"];
+ GPBStringFloatDictionary *dict = [GPBStringFloatDictionary dictionaryWithFloat:500.f forKey:@"foo"];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
float value;
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getFloat:&value forKey:@"foo"]);
XCTAssertEqual(value, 500.f);
- XCTAssertFalse([dict valueForKey:@"bar" value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(NSString *aKey, float aValue, BOOL *stop) {
+ XCTAssertFalse([dict getFloat:NULL forKey:@"bar"]);
+ [dict enumerateKeysAndFloatsUsingBlock:^(NSString *aKey, float aValue, BOOL *stop) {
XCTAssertEqualObjects(aKey, @"foo");
XCTAssertEqual(aValue, 500.f);
XCTAssertNotEqual(stop, NULL);
@@ -1907,27 +1907,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const NSString *kKeys[] = { @"foo", @"bar", @"baz" };
const float kValues[] = { 500.f, 501.f, 502.f };
GPBStringFloatDictionary *dict =
- [[GPBStringFloatDictionary alloc] initWithValues:kValues
+ [[GPBStringFloatDictionary alloc] initWithFloats:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 3U);
float value;
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getFloat:&value forKey:@"foo"]);
XCTAssertEqual(value, 500.f);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getFloat:&value forKey:@"bar"]);
XCTAssertEqual(value, 501.f);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getFloat:&value forKey:@"baz"]);
XCTAssertEqual(value, 502.f);
- XCTAssertFalse([dict valueForKey:@"mumble" value:NULL]);
+ XCTAssertFalse([dict getFloat:NULL forKey:@"mumble"]);
__block NSUInteger idx = 0;
NSString **seenKeys = malloc(3 * sizeof(NSString*));
float *seenValues = malloc(3 * sizeof(float));
- [dict enumerateKeysAndValuesUsingBlock:^(NSString *aKey, float aValue, BOOL *stop) {
+ [dict enumerateKeysAndFloatsUsingBlock:^(NSString *aKey, float aValue, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -1949,7 +1949,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(NSString *aKey, float aValue, BOOL *stop) {
+ [dict enumerateKeysAndFloatsUsingBlock:^(NSString *aKey, float aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -1965,27 +1965,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const float kValues2[] = { 500.f, 503.f, 502.f };
const float kValues3[] = { 500.f, 501.f, 502.f, 503.f };
GPBStringFloatDictionary *dict1 =
- [[GPBStringFloatDictionary alloc] initWithValues:kValues1
+ [[GPBStringFloatDictionary alloc] initWithFloats:kValues1
forKeys:kKeys1
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBStringFloatDictionary *dict1prime =
- [[GPBStringFloatDictionary alloc] initWithValues:kValues1
+ [[GPBStringFloatDictionary alloc] initWithFloats:kValues1
forKeys:kKeys1
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBStringFloatDictionary *dict2 =
- [[GPBStringFloatDictionary alloc] initWithValues:kValues2
+ [[GPBStringFloatDictionary alloc] initWithFloats:kValues2
forKeys:kKeys1
count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBStringFloatDictionary *dict3 =
- [[GPBStringFloatDictionary alloc] initWithValues:kValues1
+ [[GPBStringFloatDictionary alloc] initWithFloats:kValues1
forKeys:kKeys2
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBStringFloatDictionary *dict4 =
- [[GPBStringFloatDictionary alloc] initWithValues:kValues3
+ [[GPBStringFloatDictionary alloc] initWithFloats:kValues3
forKeys:kKeys1
count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
@@ -2016,7 +2016,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
const float kValues[] = { 500.f, 501.f, 502.f, 503.f };
GPBStringFloatDictionary *dict =
- [[GPBStringFloatDictionary alloc] initWithValues:kValues
+ [[GPBStringFloatDictionary alloc] initWithFloats:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
@@ -2037,7 +2037,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
const float kValues[] = { 500.f, 501.f, 502.f, 503.f };
GPBStringFloatDictionary *dict =
- [[GPBStringFloatDictionary alloc] initWithValues:kValues
+ [[GPBStringFloatDictionary alloc] initWithFloats:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
@@ -2057,13 +2057,13 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:500.f forKey:@"foo"];
+ [dict setFloat:500.f forKey:@"foo"];
XCTAssertEqual(dict.count, 1U);
const NSString *kKeys[] = { @"bar", @"baz", @"mumble" };
const float kValues[] = { 501.f, 502.f, 503.f };
GPBStringFloatDictionary *dict2 =
- [[GPBStringFloatDictionary alloc] initWithValues:kValues
+ [[GPBStringFloatDictionary alloc] initWithFloats:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
@@ -2071,17 +2071,17 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertEqual(dict.count, 4U);
float value;
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getFloat:&value forKey:@"foo"]);
XCTAssertEqual(value, 500.f);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getFloat:&value forKey:@"bar"]);
XCTAssertEqual(value, 501.f);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getFloat:&value forKey:@"baz"]);
XCTAssertEqual(value, 502.f);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getFloat:&value forKey:@"mumble"]);
XCTAssertEqual(value, 503.f);
[dict2 release];
}
@@ -2090,57 +2090,57 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
const float kValues[] = { 500.f, 501.f, 502.f, 503.f };
GPBStringFloatDictionary *dict =
- [[GPBStringFloatDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBStringFloatDictionary alloc] initWithFloats:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
- [dict removeValueForKey:@"bar"];
+ [dict removeFloatForKey:@"bar"];
XCTAssertEqual(dict.count, 3U);
float value;
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getFloat:&value forKey:@"foo"]);
XCTAssertEqual(value, 500.f);
- XCTAssertFalse([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertFalse([dict getFloat:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getFloat:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getFloat:&value forKey:@"baz"]);
XCTAssertEqual(value, 502.f);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getFloat:&value forKey:@"mumble"]);
XCTAssertEqual(value, 503.f);
// Remove again does nothing.
- [dict removeValueForKey:@"bar"];
+ [dict removeFloatForKey:@"bar"];
XCTAssertEqual(dict.count, 3U);
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getFloat:&value forKey:@"foo"]);
XCTAssertEqual(value, 500.f);
- XCTAssertFalse([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertFalse([dict getFloat:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getFloat:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getFloat:&value forKey:@"baz"]);
XCTAssertEqual(value, 502.f);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getFloat:&value forKey:@"mumble"]);
XCTAssertEqual(value, 503.f);
- [dict removeValueForKey:@"mumble"];
+ [dict removeFloatForKey:@"mumble"];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getFloat:&value forKey:@"foo"]);
XCTAssertEqual(value, 500.f);
- XCTAssertFalse([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertFalse([dict getFloat:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getFloat:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getFloat:&value forKey:@"baz"]);
XCTAssertEqual(value, 502.f);
- XCTAssertFalse([dict valueForKey:@"mumble" value:NULL]);
+ XCTAssertFalse([dict getFloat:NULL forKey:@"mumble"]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:@"foo" value:NULL]);
- XCTAssertFalse([dict valueForKey:@"bar" value:NULL]);
- XCTAssertFalse([dict valueForKey:@"baz" value:NULL]);
- XCTAssertFalse([dict valueForKey:@"mumble" value:NULL]);
+ XCTAssertFalse([dict getFloat:NULL forKey:@"foo"]);
+ XCTAssertFalse([dict getFloat:NULL forKey:@"bar"]);
+ XCTAssertFalse([dict getFloat:NULL forKey:@"baz"]);
+ XCTAssertFalse([dict getFloat:NULL forKey:@"mumble"]);
[dict release];
}
@@ -2148,75 +2148,75 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
const float kValues[] = { 500.f, 501.f, 502.f, 503.f };
GPBStringFloatDictionary *dict =
- [[GPBStringFloatDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBStringFloatDictionary alloc] initWithFloats:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
float value;
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getFloat:&value forKey:@"foo"]);
XCTAssertEqual(value, 500.f);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getFloat:&value forKey:@"bar"]);
XCTAssertEqual(value, 501.f);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getFloat:&value forKey:@"baz"]);
XCTAssertEqual(value, 502.f);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getFloat:&value forKey:@"mumble"]);
XCTAssertEqual(value, 503.f);
- [dict setValue:503.f forKey:@"foo"];
+ [dict setFloat:503.f forKey:@"foo"];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getFloat:&value forKey:@"foo"]);
XCTAssertEqual(value, 503.f);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getFloat:&value forKey:@"bar"]);
XCTAssertEqual(value, 501.f);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getFloat:&value forKey:@"baz"]);
XCTAssertEqual(value, 502.f);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getFloat:&value forKey:@"mumble"]);
XCTAssertEqual(value, 503.f);
- [dict setValue:501.f forKey:@"mumble"];
+ [dict setFloat:501.f forKey:@"mumble"];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getFloat:&value forKey:@"foo"]);
XCTAssertEqual(value, 503.f);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getFloat:&value forKey:@"bar"]);
XCTAssertEqual(value, 501.f);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getFloat:&value forKey:@"baz"]);
XCTAssertEqual(value, 502.f);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getFloat:&value forKey:@"mumble"]);
XCTAssertEqual(value, 501.f);
const NSString *kKeys2[] = { @"bar", @"baz" };
const float kValues2[] = { 502.f, 500.f };
GPBStringFloatDictionary *dict2 =
- [[GPBStringFloatDictionary alloc] initWithValues:kValues2
+ [[GPBStringFloatDictionary alloc] initWithFloats:kValues2
forKeys:kKeys2
count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getFloat:&value forKey:@"foo"]);
XCTAssertEqual(value, 503.f);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getFloat:&value forKey:@"bar"]);
XCTAssertEqual(value, 502.f);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getFloat:&value forKey:@"baz"]);
XCTAssertEqual(value, 500.f);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getFloat:&value forKey:@"mumble"]);
XCTAssertEqual(value, 501.f);
[dict2 release];
@@ -2236,8 +2236,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
GPBStringDoubleDictionary *dict = [[GPBStringDoubleDictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:@"foo" value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(NSString *aKey, double aValue, BOOL *stop) {
+ XCTAssertFalse([dict getDouble:NULL forKey:@"foo"]);
+ [dict enumerateKeysAndDoublesUsingBlock:^(NSString *aKey, double aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -2245,15 +2245,15 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testOne {
- GPBStringDoubleDictionary *dict = [GPBStringDoubleDictionary dictionaryWithValue:600. forKey:@"foo"];
+ GPBStringDoubleDictionary *dict = [GPBStringDoubleDictionary dictionaryWithDouble:600. forKey:@"foo"];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
double value;
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getDouble:&value forKey:@"foo"]);
XCTAssertEqual(value, 600.);
- XCTAssertFalse([dict valueForKey:@"bar" value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(NSString *aKey, double aValue, BOOL *stop) {
+ XCTAssertFalse([dict getDouble:NULL forKey:@"bar"]);
+ [dict enumerateKeysAndDoublesUsingBlock:^(NSString *aKey, double aValue, BOOL *stop) {
XCTAssertEqualObjects(aKey, @"foo");
XCTAssertEqual(aValue, 600.);
XCTAssertNotEqual(stop, NULL);
@@ -2264,27 +2264,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const NSString *kKeys[] = { @"foo", @"bar", @"baz" };
const double kValues[] = { 600., 601., 602. };
GPBStringDoubleDictionary *dict =
- [[GPBStringDoubleDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 3U);
double value;
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getDouble:&value forKey:@"foo"]);
XCTAssertEqual(value, 600.);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getDouble:&value forKey:@"bar"]);
XCTAssertEqual(value, 601.);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getDouble:&value forKey:@"baz"]);
XCTAssertEqual(value, 602.);
- XCTAssertFalse([dict valueForKey:@"mumble" value:NULL]);
+ XCTAssertFalse([dict getDouble:NULL forKey:@"mumble"]);
__block NSUInteger idx = 0;
NSString **seenKeys = malloc(3 * sizeof(NSString*));
double *seenValues = malloc(3 * sizeof(double));
- [dict enumerateKeysAndValuesUsingBlock:^(NSString *aKey, double aValue, BOOL *stop) {
+ [dict enumerateKeysAndDoublesUsingBlock:^(NSString *aKey, double aValue, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -2306,7 +2306,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(NSString *aKey, double aValue, BOOL *stop) {
+ [dict enumerateKeysAndDoublesUsingBlock:^(NSString *aKey, double aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -2322,29 +2322,29 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const double kValues2[] = { 600., 603., 602. };
const double kValues3[] = { 600., 601., 602., 603. };
GPBStringDoubleDictionary *dict1 =
- [[GPBStringDoubleDictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBStringDoubleDictionary *dict1prime =
- [[GPBStringDoubleDictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBStringDoubleDictionary *dict2 =
- [[GPBStringDoubleDictionary alloc] initWithValues:kValues2
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues2
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBStringDoubleDictionary *dict3 =
- [[GPBStringDoubleDictionary alloc] initWithValues:kValues1
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues1
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBStringDoubleDictionary *dict4 =
- [[GPBStringDoubleDictionary alloc] initWithValues:kValues3
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues3)];
+ [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues3
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
// 1/1Prime should be different objects, but equal.
@@ -2373,9 +2373,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
const double kValues[] = { 600., 601., 602., 603. };
GPBStringDoubleDictionary *dict =
- [[GPBStringDoubleDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBStringDoubleDictionary *dict2 = [dict copy];
@@ -2394,9 +2394,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
const double kValues[] = { 600., 601., 602., 603. };
GPBStringDoubleDictionary *dict =
- [[GPBStringDoubleDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBStringDoubleDictionary *dict2 =
@@ -2414,31 +2414,31 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:600. forKey:@"foo"];
+ [dict setDouble:600. forKey:@"foo"];
XCTAssertEqual(dict.count, 1U);
const NSString *kKeys[] = { @"bar", @"baz", @"mumble" };
const double kValues[] = { 601., 602., 603. };
GPBStringDoubleDictionary *dict2 =
- [[GPBStringDoubleDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
double value;
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getDouble:&value forKey:@"foo"]);
XCTAssertEqual(value, 600.);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getDouble:&value forKey:@"bar"]);
XCTAssertEqual(value, 601.);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getDouble:&value forKey:@"baz"]);
XCTAssertEqual(value, 602.);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getDouble:&value forKey:@"mumble"]);
XCTAssertEqual(value, 603.);
[dict2 release];
}
@@ -2447,57 +2447,57 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
const double kValues[] = { 600., 601., 602., 603. };
GPBStringDoubleDictionary *dict =
- [[GPBStringDoubleDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
- [dict removeValueForKey:@"bar"];
+ [dict removeDoubleForKey:@"bar"];
XCTAssertEqual(dict.count, 3U);
double value;
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getDouble:&value forKey:@"foo"]);
XCTAssertEqual(value, 600.);
- XCTAssertFalse([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertFalse([dict getDouble:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getDouble:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getDouble:&value forKey:@"baz"]);
XCTAssertEqual(value, 602.);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getDouble:&value forKey:@"mumble"]);
XCTAssertEqual(value, 603.);
// Remove again does nothing.
- [dict removeValueForKey:@"bar"];
+ [dict removeDoubleForKey:@"bar"];
XCTAssertEqual(dict.count, 3U);
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getDouble:&value forKey:@"foo"]);
XCTAssertEqual(value, 600.);
- XCTAssertFalse([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertFalse([dict getDouble:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getDouble:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getDouble:&value forKey:@"baz"]);
XCTAssertEqual(value, 602.);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getDouble:&value forKey:@"mumble"]);
XCTAssertEqual(value, 603.);
- [dict removeValueForKey:@"mumble"];
+ [dict removeDoubleForKey:@"mumble"];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getDouble:&value forKey:@"foo"]);
XCTAssertEqual(value, 600.);
- XCTAssertFalse([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertFalse([dict getDouble:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getDouble:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getDouble:&value forKey:@"baz"]);
XCTAssertEqual(value, 602.);
- XCTAssertFalse([dict valueForKey:@"mumble" value:NULL]);
+ XCTAssertFalse([dict getDouble:NULL forKey:@"mumble"]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:@"foo" value:NULL]);
- XCTAssertFalse([dict valueForKey:@"bar" value:NULL]);
- XCTAssertFalse([dict valueForKey:@"baz" value:NULL]);
- XCTAssertFalse([dict valueForKey:@"mumble" value:NULL]);
+ XCTAssertFalse([dict getDouble:NULL forKey:@"foo"]);
+ XCTAssertFalse([dict getDouble:NULL forKey:@"bar"]);
+ XCTAssertFalse([dict getDouble:NULL forKey:@"baz"]);
+ XCTAssertFalse([dict getDouble:NULL forKey:@"mumble"]);
[dict release];
}
@@ -2505,75 +2505,75 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
const double kValues[] = { 600., 601., 602., 603. };
GPBStringDoubleDictionary *dict =
- [[GPBStringDoubleDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
double value;
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getDouble:&value forKey:@"foo"]);
XCTAssertEqual(value, 600.);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getDouble:&value forKey:@"bar"]);
XCTAssertEqual(value, 601.);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getDouble:&value forKey:@"baz"]);
XCTAssertEqual(value, 602.);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getDouble:&value forKey:@"mumble"]);
XCTAssertEqual(value, 603.);
- [dict setValue:603. forKey:@"foo"];
+ [dict setDouble:603. forKey:@"foo"];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getDouble:&value forKey:@"foo"]);
XCTAssertEqual(value, 603.);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getDouble:&value forKey:@"bar"]);
XCTAssertEqual(value, 601.);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getDouble:&value forKey:@"baz"]);
XCTAssertEqual(value, 602.);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getDouble:&value forKey:@"mumble"]);
XCTAssertEqual(value, 603.);
- [dict setValue:601. forKey:@"mumble"];
+ [dict setDouble:601. forKey:@"mumble"];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getDouble:&value forKey:@"foo"]);
XCTAssertEqual(value, 603.);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getDouble:&value forKey:@"bar"]);
XCTAssertEqual(value, 601.);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getDouble:&value forKey:@"baz"]);
XCTAssertEqual(value, 602.);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getDouble:&value forKey:@"mumble"]);
XCTAssertEqual(value, 601.);
const NSString *kKeys2[] = { @"bar", @"baz" };
const double kValues2[] = { 602., 600. };
GPBStringDoubleDictionary *dict2 =
- [[GPBStringDoubleDictionary alloc] initWithValues:kValues2
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues2
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getDouble:&value forKey:@"foo"]);
XCTAssertEqual(value, 603.);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getDouble:&value forKey:@"bar"]);
XCTAssertEqual(value, 602.);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getDouble:&value forKey:@"baz"]);
XCTAssertEqual(value, 600.);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getDouble:&value forKey:@"mumble"]);
XCTAssertEqual(value, 601.);
[dict2 release];
@@ -2593,8 +2593,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
GPBStringEnumDictionary *dict = [[GPBStringEnumDictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:@"foo" value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getEnum:NULL forKey:@"foo"]);
+ [dict enumerateKeysAndEnumsUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -2602,15 +2602,15 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testOne {
- GPBStringEnumDictionary *dict = [GPBStringEnumDictionary dictionaryWithValue:700 forKey:@"foo"];
+ GPBStringEnumDictionary *dict = [GPBStringEnumDictionary dictionaryWithEnum:700 forKey:@"foo"];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
int32_t value;
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
XCTAssertEqual(value, 700);
- XCTAssertFalse([dict valueForKey:@"bar" value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getEnum:NULL forKey:@"bar"]);
+ [dict enumerateKeysAndEnumsUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) {
XCTAssertEqualObjects(aKey, @"foo");
XCTAssertEqual(aValue, 700);
XCTAssertNotEqual(stop, NULL);
@@ -2621,27 +2621,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const NSString *kKeys[] = { @"foo", @"bar", @"baz" };
const int32_t kValues[] = { 700, 701, 702 };
GPBStringEnumDictionary *dict =
- [[GPBStringEnumDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBStringEnumDictionary alloc] initWithEnums:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 3U);
int32_t value;
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
XCTAssertEqual(value, 700);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"bar"]);
XCTAssertEqual(value, 701);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
XCTAssertEqual(value, 702);
- XCTAssertFalse([dict valueForKey:@"mumble" value:NULL]);
+ XCTAssertFalse([dict getEnum:NULL forKey:@"mumble"]);
__block NSUInteger idx = 0;
NSString **seenKeys = malloc(3 * sizeof(NSString*));
int32_t *seenValues = malloc(3 * sizeof(int32_t));
- [dict enumerateKeysAndValuesUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndEnumsUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -2663,7 +2663,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndEnumsUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -2679,29 +2679,29 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kValues2[] = { 700, 703, 702 };
const int32_t kValues3[] = { 700, 701, 702, 703 };
GPBStringEnumDictionary *dict1 =
- [[GPBStringEnumDictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBStringEnumDictionary alloc] initWithEnums:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBStringEnumDictionary *dict1prime =
- [[GPBStringEnumDictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBStringEnumDictionary alloc] initWithEnums:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBStringEnumDictionary *dict2 =
- [[GPBStringEnumDictionary alloc] initWithValues:kValues2
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBStringEnumDictionary alloc] initWithEnums:kValues2
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBStringEnumDictionary *dict3 =
- [[GPBStringEnumDictionary alloc] initWithValues:kValues1
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBStringEnumDictionary alloc] initWithEnums:kValues1
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBStringEnumDictionary *dict4 =
- [[GPBStringEnumDictionary alloc] initWithValues:kValues3
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues3)];
+ [[GPBStringEnumDictionary alloc] initWithEnums:kValues3
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
// 1/1Prime should be different objects, but equal.
@@ -2730,9 +2730,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
const int32_t kValues[] = { 700, 701, 702, 703 };
GPBStringEnumDictionary *dict =
- [[GPBStringEnumDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBStringEnumDictionary alloc] initWithEnums:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBStringEnumDictionary *dict2 = [dict copy];
@@ -2751,9 +2751,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
const int32_t kValues[] = { 700, 701, 702, 703 };
GPBStringEnumDictionary *dict =
- [[GPBStringEnumDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBStringEnumDictionary alloc] initWithEnums:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBStringEnumDictionary *dict2 =
@@ -2771,31 +2771,31 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:700 forKey:@"foo"];
+ [dict setEnum:700 forKey:@"foo"];
XCTAssertEqual(dict.count, 1U);
const NSString *kKeys[] = { @"bar", @"baz", @"mumble" };
const int32_t kValues[] = { 701, 702, 703 };
GPBStringEnumDictionary *dict2 =
- [[GPBStringEnumDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBStringEnumDictionary alloc] initWithEnums:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
[dict addRawEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
int32_t value;
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
XCTAssertEqual(value, 700);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"bar"]);
XCTAssertEqual(value, 701);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"mumble"]);
XCTAssertEqual(value, 703);
[dict2 release];
}
@@ -2804,57 +2804,57 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
const int32_t kValues[] = { 700, 701, 702, 703 };
GPBStringEnumDictionary *dict =
- [[GPBStringEnumDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBStringEnumDictionary alloc] initWithEnums:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
- [dict removeValueForKey:@"bar"];
+ [dict removeEnumForKey:@"bar"];
XCTAssertEqual(dict.count, 3U);
int32_t value;
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
XCTAssertEqual(value, 700);
- XCTAssertFalse([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertFalse([dict getEnum:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"mumble"]);
XCTAssertEqual(value, 703);
// Remove again does nothing.
- [dict removeValueForKey:@"bar"];
+ [dict removeEnumForKey:@"bar"];
XCTAssertEqual(dict.count, 3U);
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
XCTAssertEqual(value, 700);
- XCTAssertFalse([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertFalse([dict getEnum:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"mumble"]);
XCTAssertEqual(value, 703);
- [dict removeValueForKey:@"mumble"];
+ [dict removeEnumForKey:@"mumble"];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
XCTAssertEqual(value, 700);
- XCTAssertFalse([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertFalse([dict getEnum:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
XCTAssertEqual(value, 702);
- XCTAssertFalse([dict valueForKey:@"mumble" value:NULL]);
+ XCTAssertFalse([dict getEnum:NULL forKey:@"mumble"]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:@"foo" value:NULL]);
- XCTAssertFalse([dict valueForKey:@"bar" value:NULL]);
- XCTAssertFalse([dict valueForKey:@"baz" value:NULL]);
- XCTAssertFalse([dict valueForKey:@"mumble" value:NULL]);
+ XCTAssertFalse([dict getEnum:NULL forKey:@"foo"]);
+ XCTAssertFalse([dict getEnum:NULL forKey:@"bar"]);
+ XCTAssertFalse([dict getEnum:NULL forKey:@"baz"]);
+ XCTAssertFalse([dict getEnum:NULL forKey:@"mumble"]);
[dict release];
}
@@ -2862,75 +2862,75 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
const int32_t kValues[] = { 700, 701, 702, 703 };
GPBStringEnumDictionary *dict =
- [[GPBStringEnumDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBStringEnumDictionary alloc] initWithEnums:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
int32_t value;
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
XCTAssertEqual(value, 700);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"bar"]);
XCTAssertEqual(value, 701);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"mumble"]);
XCTAssertEqual(value, 703);
- [dict setValue:703 forKey:@"foo"];
+ [dict setEnum:703 forKey:@"foo"];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
XCTAssertEqual(value, 703);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"bar"]);
XCTAssertEqual(value, 701);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"mumble"]);
XCTAssertEqual(value, 703);
- [dict setValue:701 forKey:@"mumble"];
+ [dict setEnum:701 forKey:@"mumble"];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
XCTAssertEqual(value, 703);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"bar"]);
XCTAssertEqual(value, 701);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"mumble"]);
XCTAssertEqual(value, 701);
const NSString *kKeys2[] = { @"bar", @"baz" };
const int32_t kValues2[] = { 702, 700 };
GPBStringEnumDictionary *dict2 =
- [[GPBStringEnumDictionary alloc] initWithValues:kValues2
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBStringEnumDictionary alloc] initWithEnums:kValues2
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addRawEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
XCTAssertEqual(value, 703);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"bar"]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
XCTAssertEqual(value, 700);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"mumble"]);
XCTAssertEqual(value, 701);
[dict2 release];
@@ -2958,24 +2958,24 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertEqual(dict.count, 3U);
XCTAssertTrue(dict.validationFunc == TestingEnum_IsValidValue); // Pointer comparison
int32_t value;
- XCTAssertTrue([dict valueForKey:@"foo" rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getRawValue:&value forKey:@"foo"]);
XCTAssertEqual(value, 700);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"bar"]);
XCTAssertEqual(value, kGPBUnrecognizedEnumeratorValue);
- XCTAssertTrue([dict valueForKey:@"bar" rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getRawValue:&value forKey:@"bar"]);
XCTAssertEqual(value, 801);
- XCTAssertTrue([dict valueForKey:@"baz" rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getRawValue:&value forKey:@"baz"]);
XCTAssertEqual(value, 702);
- XCTAssertFalse([dict valueForKey:@"mumble" rawValue:NULL]);
+ XCTAssertFalse([dict getRawValue:NULL forKey:@"mumble"]);
__block NSUInteger idx = 0;
NSString **seenKeys = malloc(3 * sizeof(NSString*));
int32_t *seenValues = malloc(3 * sizeof(int32_t));
- [dict enumerateKeysAndValuesUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndEnumsUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -3136,7 +3136,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertThrowsSpecificNamed([dict setValue:801 forKey:@"bar"], // Unknown
+ XCTAssertThrowsSpecificNamed([dict setEnum:801 forKey:@"bar"], // Unknown
NSException, NSInvalidArgumentException);
XCTAssertEqual(dict.count, 0U);
[dict setRawValue:801 forKey:@"bar"]; // Unknown
@@ -3145,31 +3145,31 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const NSString *kKeys[] = { @"foo", @"baz", @"mumble" };
const int32_t kValues[] = { 700, 702, 803 }; // Unknown
GPBStringEnumDictionary *dict2 =
- [[GPBStringEnumDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBStringEnumDictionary alloc] initWithEnums:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
[dict addRawEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
int32_t value;
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
XCTAssertEqual(value, 700);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"bar"]);
XCTAssertEqual(value, kGPBUnrecognizedEnumeratorValue);
- XCTAssertTrue([dict valueForKey:@"bar" rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getRawValue:&value forKey:@"bar"]);
XCTAssertEqual(value, 801);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"mumble"]);
XCTAssertEqual(value, kGPBUnrecognizedEnumeratorValue);
- XCTAssertTrue([dict valueForKey:@"mumble" rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getRawValue:&value forKey:@"mumble"]);
XCTAssertEqual(value, 803);
[dict2 release];
}
@@ -3185,51 +3185,51 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
- [dict removeValueForKey:@"bar"];
+ [dict removeEnumForKey:@"bar"];
XCTAssertEqual(dict.count, 3U);
int32_t value;
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
XCTAssertEqual(value, 700);
- XCTAssertFalse([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertFalse([dict getEnum:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:@"mumble" rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getRawValue:&value forKey:@"mumble"]);
XCTAssertEqual(value, 803);
// Remove again does nothing.
- [dict removeValueForKey:@"bar"];
+ [dict removeEnumForKey:@"bar"];
XCTAssertEqual(dict.count, 3U);
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
XCTAssertEqual(value, 700);
- XCTAssertFalse([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertFalse([dict getEnum:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:@"mumble" rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getRawValue:&value forKey:@"mumble"]);
XCTAssertEqual(value, 803);
- [dict removeValueForKey:@"mumble"];
+ [dict removeEnumForKey:@"mumble"];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
XCTAssertEqual(value, 700);
- XCTAssertFalse([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertFalse([dict getEnum:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
XCTAssertEqual(value, 702);
- XCTAssertFalse([dict valueForKey:@"mumble" value:NULL]);
+ XCTAssertFalse([dict getEnum:NULL forKey:@"mumble"]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:@"foo" value:NULL]);
- XCTAssertFalse([dict valueForKey:@"bar" value:NULL]);
- XCTAssertFalse([dict valueForKey:@"baz" value:NULL]);
- XCTAssertFalse([dict valueForKey:@"mumble" value:NULL]);
+ XCTAssertFalse([dict getEnum:NULL forKey:@"foo"]);
+ XCTAssertFalse([dict getEnum:NULL forKey:@"bar"]);
+ XCTAssertFalse([dict getEnum:NULL forKey:@"baz"]);
+ XCTAssertFalse([dict getEnum:NULL forKey:@"mumble"]);
[dict release];
}
@@ -3244,63 +3244,63 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
int32_t value;
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
XCTAssertEqual(value, 700);
- XCTAssertTrue([dict valueForKey:@"bar" rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getRawValue:&value forKey:@"bar"]);
XCTAssertEqual(value, 801);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:@"mumble" rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getRawValue:&value forKey:@"mumble"]);
XCTAssertEqual(value, 803);
- XCTAssertThrowsSpecificNamed([dict setValue:803 forKey:@"foo"], // Unknown
+ XCTAssertThrowsSpecificNamed([dict setEnum:803 forKey:@"foo"], // Unknown
NSException, NSInvalidArgumentException);
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:@"foo" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
XCTAssertEqual(value, 700);
- XCTAssertTrue([dict valueForKey:@"bar" rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getRawValue:&value forKey:@"bar"]);
XCTAssertEqual(value, 801);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:@"mumble" rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getRawValue:&value forKey:@"mumble"]);
XCTAssertEqual(value, 803);
[dict setRawValue:803 forKey:@"foo"]; // Unknown
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:@"foo" rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getRawValue:&value forKey:@"foo"]);
XCTAssertEqual(value, 803);
- XCTAssertTrue([dict valueForKey:@"bar" rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getRawValue:&value forKey:@"bar"]);
XCTAssertEqual(value, 801);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:@"mumble" rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getRawValue:&value forKey:@"mumble"]);
XCTAssertEqual(value, 803);
[dict setRawValue:700 forKey:@"mumble"];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:@"foo" rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getRawValue:&value forKey:@"foo"]);
XCTAssertEqual(value, 803);
- XCTAssertTrue([dict valueForKey:@"bar" rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getRawValue:&value forKey:@"bar"]);
XCTAssertEqual(value, 801);
- XCTAssertTrue([dict valueForKey:@"baz" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"mumble"]);
XCTAssertEqual(value, 700);
const NSString *kKeys2[] = { @"bar", @"baz" };
@@ -3313,17 +3313,17 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict2);
[dict addRawEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:@"foo" rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:@"foo" rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:@"foo"]);
+ XCTAssertTrue([dict getRawValue:&value forKey:@"foo"]);
XCTAssertEqual(value, 803);
- XCTAssertTrue([dict valueForKey:@"bar" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"bar" value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"bar"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"bar"]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:@"baz" rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:@"baz" rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:@"baz"]);
+ XCTAssertTrue([dict getRawValue:&value forKey:@"baz"]);
XCTAssertEqual(value, 801);
- XCTAssertTrue([dict valueForKey:@"mumble" value:NULL]);
- XCTAssertTrue([dict valueForKey:@"mumble" value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:@"mumble"]);
+ XCTAssertTrue([dict getEnum:&value forKey:@"mumble"]);
XCTAssertEqual(value, 700);
[dict2 release];
diff --git a/objectivec/Tests/GPBDictionaryTests+UInt32.m b/objectivec/Tests/GPBDictionaryTests+UInt32.m
index c7c57652..1d3f6f78 100644
--- a/objectivec/Tests/GPBDictionaryTests+UInt32.m
+++ b/objectivec/Tests/GPBDictionaryTests+UInt32.m
@@ -45,10 +45,10 @@
// To let the testing macros work, add some extra methods to simplify things.
@interface GPBUInt32EnumDictionary (TestingTweak)
-+ (instancetype)dictionaryWithValue:(int32_t)value forKey:(uint32_t)key;
-- (instancetype)initWithValues:(const int32_t [])values
- forKeys:(const uint32_t [])keys
- count:(NSUInteger)count;
++ (instancetype)dictionaryWithEnum:(int32_t)value forKey:(uint32_t)key;
+- (instancetype)initWithEnums:(const int32_t [])values
+ forKeys:(const uint32_t [])keys
+ count:(NSUInteger)count;
@end
static BOOL TestingEnum_IsValidValue(int32_t value) {
@@ -64,7 +64,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
@implementation GPBUInt32EnumDictionary (TestingTweak)
-+ (instancetype)dictionaryWithValue:(int32_t)value forKey:(uint32_t)key {
++ (instancetype)dictionaryWithEnum:(int32_t)value forKey:(uint32_t)key {
// Cast is needed to compiler knows what class we are invoking initWithValues: on to get the
// type correct.
return [[(GPBUInt32EnumDictionary*)[self alloc] initWithValidationFunction:TestingEnum_IsValidValue
@@ -72,9 +72,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
forKeys:&key
count:1] autorelease];
}
-- (instancetype)initWithValues:(const int32_t [])values
- forKeys:(const uint32_t [])keys
- count:(NSUInteger)count {
+- (instancetype)initWithEnums:(const int32_t [])values
+ forKeys:(const uint32_t [])keys
+ count:(NSUInteger)count {
return [self initWithValidationFunction:TestingEnum_IsValidValue
rawValues:values
forKeys:keys
@@ -94,8 +94,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
GPBUInt32UInt32Dictionary *dict = [[GPBUInt32UInt32Dictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:1U value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(uint32_t aKey, uint32_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getUInt32:NULL forKey:1U]);
+ [dict enumerateKeysAndUInt32sUsingBlock:^(uint32_t aKey, uint32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -103,15 +103,15 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testOne {
- GPBUInt32UInt32Dictionary *dict = [GPBUInt32UInt32Dictionary dictionaryWithValue:100U forKey:1U];
+ GPBUInt32UInt32Dictionary *dict = [GPBUInt32UInt32Dictionary dictionaryWithUInt32:100U forKey:1U];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
uint32_t value;
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:1U]);
+ XCTAssertTrue([dict getUInt32:&value forKey:1U]);
XCTAssertEqual(value, 100U);
- XCTAssertFalse([dict valueForKey:2U value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(uint32_t aKey, uint32_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getUInt32:NULL forKey:2U]);
+ [dict enumerateKeysAndUInt32sUsingBlock:^(uint32_t aKey, uint32_t aValue, BOOL *stop) {
XCTAssertEqual(aKey, 1U);
XCTAssertEqual(aValue, 100U);
XCTAssertNotEqual(stop, NULL);
@@ -122,27 +122,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint32_t kKeys[] = { 1U, 2U, 3U };
const uint32_t kValues[] = { 100U, 101U, 102U };
GPBUInt32UInt32Dictionary *dict =
- [[GPBUInt32UInt32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt32UInt32Dictionary alloc] initWithUInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 3U);
uint32_t value;
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:1U]);
+ XCTAssertTrue([dict getUInt32:&value forKey:1U]);
XCTAssertEqual(value, 100U);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:2U]);
+ XCTAssertTrue([dict getUInt32:&value forKey:2U]);
XCTAssertEqual(value, 101U);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:3U]);
+ XCTAssertTrue([dict getUInt32:&value forKey:3U]);
XCTAssertEqual(value, 102U);
- XCTAssertFalse([dict valueForKey:4U value:NULL]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:4U]);
__block NSUInteger idx = 0;
uint32_t *seenKeys = malloc(3 * sizeof(uint32_t));
uint32_t *seenValues = malloc(3 * sizeof(uint32_t));
- [dict enumerateKeysAndValuesUsingBlock:^(uint32_t aKey, uint32_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndUInt32sUsingBlock:^(uint32_t aKey, uint32_t aValue, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -164,7 +164,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(uint32_t aKey, uint32_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndUInt32sUsingBlock:^(uint32_t aKey, uint32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -180,29 +180,29 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint32_t kValues2[] = { 100U, 103U, 102U };
const uint32_t kValues3[] = { 100U, 101U, 102U, 103U };
GPBUInt32UInt32Dictionary *dict1 =
- [[GPBUInt32UInt32Dictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBUInt32UInt32Dictionary alloc] initWithUInt32s:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBUInt32UInt32Dictionary *dict1prime =
- [[GPBUInt32UInt32Dictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBUInt32UInt32Dictionary alloc] initWithUInt32s:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBUInt32UInt32Dictionary *dict2 =
- [[GPBUInt32UInt32Dictionary alloc] initWithValues:kValues2
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBUInt32UInt32Dictionary alloc] initWithUInt32s:kValues2
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBUInt32UInt32Dictionary *dict3 =
- [[GPBUInt32UInt32Dictionary alloc] initWithValues:kValues1
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBUInt32UInt32Dictionary alloc] initWithUInt32s:kValues1
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBUInt32UInt32Dictionary *dict4 =
- [[GPBUInt32UInt32Dictionary alloc] initWithValues:kValues3
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues3)];
+ [[GPBUInt32UInt32Dictionary alloc] initWithUInt32s:kValues3
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
// 1/1Prime should be different objects, but equal.
@@ -231,9 +231,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint32_t kKeys[] = { 1U, 2U, 3U, 4U };
const uint32_t kValues[] = { 100U, 101U, 102U, 103U };
GPBUInt32UInt32Dictionary *dict =
- [[GPBUInt32UInt32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt32UInt32Dictionary alloc] initWithUInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBUInt32UInt32Dictionary *dict2 = [dict copy];
@@ -252,9 +252,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint32_t kKeys[] = { 1U, 2U, 3U, 4U };
const uint32_t kValues[] = { 100U, 101U, 102U, 103U };
GPBUInt32UInt32Dictionary *dict =
- [[GPBUInt32UInt32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt32UInt32Dictionary alloc] initWithUInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBUInt32UInt32Dictionary *dict2 =
@@ -272,31 +272,31 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:100U forKey:1U];
+ [dict setUInt32:100U forKey:1U];
XCTAssertEqual(dict.count, 1U);
const uint32_t kKeys[] = { 2U, 3U, 4U };
const uint32_t kValues[] = { 101U, 102U, 103U };
GPBUInt32UInt32Dictionary *dict2 =
- [[GPBUInt32UInt32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt32UInt32Dictionary alloc] initWithUInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
uint32_t value;
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:1U]);
+ XCTAssertTrue([dict getUInt32:&value forKey:1U]);
XCTAssertEqual(value, 100U);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:2U]);
+ XCTAssertTrue([dict getUInt32:&value forKey:2U]);
XCTAssertEqual(value, 101U);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:3U]);
+ XCTAssertTrue([dict getUInt32:&value forKey:3U]);
XCTAssertEqual(value, 102U);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:4U]);
+ XCTAssertTrue([dict getUInt32:&value forKey:4U]);
XCTAssertEqual(value, 103U);
[dict2 release];
}
@@ -305,57 +305,57 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint32_t kKeys[] = { 1U, 2U, 3U, 4U };
const uint32_t kValues[] = { 100U, 101U, 102U, 103U };
GPBUInt32UInt32Dictionary *dict =
- [[GPBUInt32UInt32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt32UInt32Dictionary alloc] initWithUInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
- [dict removeValueForKey:2U];
+ [dict removeUInt32ForKey:2U];
XCTAssertEqual(dict.count, 3U);
uint32_t value;
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:1U]);
+ XCTAssertTrue([dict getUInt32:&value forKey:1U]);
XCTAssertEqual(value, 100U);
- XCTAssertFalse([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:2U]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:3U]);
+ XCTAssertTrue([dict getUInt32:&value forKey:3U]);
XCTAssertEqual(value, 102U);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:4U]);
+ XCTAssertTrue([dict getUInt32:&value forKey:4U]);
XCTAssertEqual(value, 103U);
// Remove again does nothing.
- [dict removeValueForKey:2U];
+ [dict removeUInt32ForKey:2U];
XCTAssertEqual(dict.count, 3U);
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:1U]);
+ XCTAssertTrue([dict getUInt32:&value forKey:1U]);
XCTAssertEqual(value, 100U);
- XCTAssertFalse([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:2U]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:3U]);
+ XCTAssertTrue([dict getUInt32:&value forKey:3U]);
XCTAssertEqual(value, 102U);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:4U]);
+ XCTAssertTrue([dict getUInt32:&value forKey:4U]);
XCTAssertEqual(value, 103U);
- [dict removeValueForKey:4U];
+ [dict removeUInt32ForKey:4U];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:1U]);
+ XCTAssertTrue([dict getUInt32:&value forKey:1U]);
XCTAssertEqual(value, 100U);
- XCTAssertFalse([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:2U]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:3U]);
+ XCTAssertTrue([dict getUInt32:&value forKey:3U]);
XCTAssertEqual(value, 102U);
- XCTAssertFalse([dict valueForKey:4U value:NULL]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:4U]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:1U value:NULL]);
- XCTAssertFalse([dict valueForKey:2U value:NULL]);
- XCTAssertFalse([dict valueForKey:3U value:NULL]);
- XCTAssertFalse([dict valueForKey:4U value:NULL]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:1U]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:2U]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:3U]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:4U]);
[dict release];
}
@@ -363,75 +363,75 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint32_t kKeys[] = { 1U, 2U, 3U, 4U };
const uint32_t kValues[] = { 100U, 101U, 102U, 103U };
GPBUInt32UInt32Dictionary *dict =
- [[GPBUInt32UInt32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt32UInt32Dictionary alloc] initWithUInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
uint32_t value;
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:1U]);
+ XCTAssertTrue([dict getUInt32:&value forKey:1U]);
XCTAssertEqual(value, 100U);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:2U]);
+ XCTAssertTrue([dict getUInt32:&value forKey:2U]);
XCTAssertEqual(value, 101U);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:3U]);
+ XCTAssertTrue([dict getUInt32:&value forKey:3U]);
XCTAssertEqual(value, 102U);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:4U]);
+ XCTAssertTrue([dict getUInt32:&value forKey:4U]);
XCTAssertEqual(value, 103U);
- [dict setValue:103U forKey:1U];
+ [dict setUInt32:103U forKey:1U];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:1U]);
+ XCTAssertTrue([dict getUInt32:&value forKey:1U]);
XCTAssertEqual(value, 103U);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:2U]);
+ XCTAssertTrue([dict getUInt32:&value forKey:2U]);
XCTAssertEqual(value, 101U);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:3U]);
+ XCTAssertTrue([dict getUInt32:&value forKey:3U]);
XCTAssertEqual(value, 102U);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:4U]);
+ XCTAssertTrue([dict getUInt32:&value forKey:4U]);
XCTAssertEqual(value, 103U);
- [dict setValue:101U forKey:4U];
+ [dict setUInt32:101U forKey:4U];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:1U]);
+ XCTAssertTrue([dict getUInt32:&value forKey:1U]);
XCTAssertEqual(value, 103U);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:2U]);
+ XCTAssertTrue([dict getUInt32:&value forKey:2U]);
XCTAssertEqual(value, 101U);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:3U]);
+ XCTAssertTrue([dict getUInt32:&value forKey:3U]);
XCTAssertEqual(value, 102U);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:4U]);
+ XCTAssertTrue([dict getUInt32:&value forKey:4U]);
XCTAssertEqual(value, 101U);
const uint32_t kKeys2[] = { 2U, 3U };
const uint32_t kValues2[] = { 102U, 100U };
GPBUInt32UInt32Dictionary *dict2 =
- [[GPBUInt32UInt32Dictionary alloc] initWithValues:kValues2
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBUInt32UInt32Dictionary alloc] initWithUInt32s:kValues2
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:1U]);
+ XCTAssertTrue([dict getUInt32:&value forKey:1U]);
XCTAssertEqual(value, 103U);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:2U]);
+ XCTAssertTrue([dict getUInt32:&value forKey:2U]);
XCTAssertEqual(value, 102U);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:3U]);
+ XCTAssertTrue([dict getUInt32:&value forKey:3U]);
XCTAssertEqual(value, 100U);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:4U]);
+ XCTAssertTrue([dict getUInt32:&value forKey:4U]);
XCTAssertEqual(value, 101U);
[dict2 release];
@@ -451,8 +451,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
GPBUInt32Int32Dictionary *dict = [[GPBUInt32Int32Dictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:1U value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(uint32_t aKey, int32_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getInt32:NULL forKey:1U]);
+ [dict enumerateKeysAndInt32sUsingBlock:^(uint32_t aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -460,15 +460,15 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testOne {
- GPBUInt32Int32Dictionary *dict = [GPBUInt32Int32Dictionary dictionaryWithValue:200 forKey:1U];
+ GPBUInt32Int32Dictionary *dict = [GPBUInt32Int32Dictionary dictionaryWithInt32:200 forKey:1U];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
int32_t value;
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:1U]);
+ XCTAssertTrue([dict getInt32:&value forKey:1U]);
XCTAssertEqual(value, 200);
- XCTAssertFalse([dict valueForKey:2U value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(uint32_t aKey, int32_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getInt32:NULL forKey:2U]);
+ [dict enumerateKeysAndInt32sUsingBlock:^(uint32_t aKey, int32_t aValue, BOOL *stop) {
XCTAssertEqual(aKey, 1U);
XCTAssertEqual(aValue, 200);
XCTAssertNotEqual(stop, NULL);
@@ -479,27 +479,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint32_t kKeys[] = { 1U, 2U, 3U };
const int32_t kValues[] = { 200, 201, 202 };
GPBUInt32Int32Dictionary *dict =
- [[GPBUInt32Int32Dictionary alloc] initWithValues:kValues
+ [[GPBUInt32Int32Dictionary alloc] initWithInt32s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 3U);
int32_t value;
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:1U]);
+ XCTAssertTrue([dict getInt32:&value forKey:1U]);
XCTAssertEqual(value, 200);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:2U]);
+ XCTAssertTrue([dict getInt32:&value forKey:2U]);
XCTAssertEqual(value, 201);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:3U]);
+ XCTAssertTrue([dict getInt32:&value forKey:3U]);
XCTAssertEqual(value, 202);
- XCTAssertFalse([dict valueForKey:4U value:NULL]);
+ XCTAssertFalse([dict getInt32:NULL forKey:4U]);
__block NSUInteger idx = 0;
uint32_t *seenKeys = malloc(3 * sizeof(uint32_t));
int32_t *seenValues = malloc(3 * sizeof(int32_t));
- [dict enumerateKeysAndValuesUsingBlock:^(uint32_t aKey, int32_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndInt32sUsingBlock:^(uint32_t aKey, int32_t aValue, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -521,7 +521,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(uint32_t aKey, int32_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndInt32sUsingBlock:^(uint32_t aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -537,27 +537,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kValues2[] = { 200, 203, 202 };
const int32_t kValues3[] = { 200, 201, 202, 203 };
GPBUInt32Int32Dictionary *dict1 =
- [[GPBUInt32Int32Dictionary alloc] initWithValues:kValues1
+ [[GPBUInt32Int32Dictionary alloc] initWithInt32s:kValues1
forKeys:kKeys1
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBUInt32Int32Dictionary *dict1prime =
- [[GPBUInt32Int32Dictionary alloc] initWithValues:kValues1
+ [[GPBUInt32Int32Dictionary alloc] initWithInt32s:kValues1
forKeys:kKeys1
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBUInt32Int32Dictionary *dict2 =
- [[GPBUInt32Int32Dictionary alloc] initWithValues:kValues2
+ [[GPBUInt32Int32Dictionary alloc] initWithInt32s:kValues2
forKeys:kKeys1
count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBUInt32Int32Dictionary *dict3 =
- [[GPBUInt32Int32Dictionary alloc] initWithValues:kValues1
+ [[GPBUInt32Int32Dictionary alloc] initWithInt32s:kValues1
forKeys:kKeys2
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBUInt32Int32Dictionary *dict4 =
- [[GPBUInt32Int32Dictionary alloc] initWithValues:kValues3
+ [[GPBUInt32Int32Dictionary alloc] initWithInt32s:kValues3
forKeys:kKeys1
count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
@@ -588,7 +588,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint32_t kKeys[] = { 1U, 2U, 3U, 4U };
const int32_t kValues[] = { 200, 201, 202, 203 };
GPBUInt32Int32Dictionary *dict =
- [[GPBUInt32Int32Dictionary alloc] initWithValues:kValues
+ [[GPBUInt32Int32Dictionary alloc] initWithInt32s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
@@ -609,7 +609,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint32_t kKeys[] = { 1U, 2U, 3U, 4U };
const int32_t kValues[] = { 200, 201, 202, 203 };
GPBUInt32Int32Dictionary *dict =
- [[GPBUInt32Int32Dictionary alloc] initWithValues:kValues
+ [[GPBUInt32Int32Dictionary alloc] initWithInt32s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
@@ -629,13 +629,13 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:200 forKey:1U];
+ [dict setInt32:200 forKey:1U];
XCTAssertEqual(dict.count, 1U);
const uint32_t kKeys[] = { 2U, 3U, 4U };
const int32_t kValues[] = { 201, 202, 203 };
GPBUInt32Int32Dictionary *dict2 =
- [[GPBUInt32Int32Dictionary alloc] initWithValues:kValues
+ [[GPBUInt32Int32Dictionary alloc] initWithInt32s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
@@ -643,17 +643,17 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertEqual(dict.count, 4U);
int32_t value;
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:1U]);
+ XCTAssertTrue([dict getInt32:&value forKey:1U]);
XCTAssertEqual(value, 200);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:2U]);
+ XCTAssertTrue([dict getInt32:&value forKey:2U]);
XCTAssertEqual(value, 201);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:3U]);
+ XCTAssertTrue([dict getInt32:&value forKey:3U]);
XCTAssertEqual(value, 202);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:4U]);
+ XCTAssertTrue([dict getInt32:&value forKey:4U]);
XCTAssertEqual(value, 203);
[dict2 release];
}
@@ -662,57 +662,57 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint32_t kKeys[] = { 1U, 2U, 3U, 4U };
const int32_t kValues[] = { 200, 201, 202, 203 };
GPBUInt32Int32Dictionary *dict =
- [[GPBUInt32Int32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt32Int32Dictionary alloc] initWithInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
- [dict removeValueForKey:2U];
+ [dict removeInt32ForKey:2U];
XCTAssertEqual(dict.count, 3U);
int32_t value;
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:1U]);
+ XCTAssertTrue([dict getInt32:&value forKey:1U]);
XCTAssertEqual(value, 200);
- XCTAssertFalse([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertFalse([dict getInt32:NULL forKey:2U]);
+ XCTAssertTrue([dict getInt32:NULL forKey:3U]);
+ XCTAssertTrue([dict getInt32:&value forKey:3U]);
XCTAssertEqual(value, 202);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:4U]);
+ XCTAssertTrue([dict getInt32:&value forKey:4U]);
XCTAssertEqual(value, 203);
// Remove again does nothing.
- [dict removeValueForKey:2U];
+ [dict removeInt32ForKey:2U];
XCTAssertEqual(dict.count, 3U);
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:1U]);
+ XCTAssertTrue([dict getInt32:&value forKey:1U]);
XCTAssertEqual(value, 200);
- XCTAssertFalse([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertFalse([dict getInt32:NULL forKey:2U]);
+ XCTAssertTrue([dict getInt32:NULL forKey:3U]);
+ XCTAssertTrue([dict getInt32:&value forKey:3U]);
XCTAssertEqual(value, 202);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:4U]);
+ XCTAssertTrue([dict getInt32:&value forKey:4U]);
XCTAssertEqual(value, 203);
- [dict removeValueForKey:4U];
+ [dict removeInt32ForKey:4U];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:1U]);
+ XCTAssertTrue([dict getInt32:&value forKey:1U]);
XCTAssertEqual(value, 200);
- XCTAssertFalse([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertFalse([dict getInt32:NULL forKey:2U]);
+ XCTAssertTrue([dict getInt32:NULL forKey:3U]);
+ XCTAssertTrue([dict getInt32:&value forKey:3U]);
XCTAssertEqual(value, 202);
- XCTAssertFalse([dict valueForKey:4U value:NULL]);
+ XCTAssertFalse([dict getInt32:NULL forKey:4U]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:1U value:NULL]);
- XCTAssertFalse([dict valueForKey:2U value:NULL]);
- XCTAssertFalse([dict valueForKey:3U value:NULL]);
- XCTAssertFalse([dict valueForKey:4U value:NULL]);
+ XCTAssertFalse([dict getInt32:NULL forKey:1U]);
+ XCTAssertFalse([dict getInt32:NULL forKey:2U]);
+ XCTAssertFalse([dict getInt32:NULL forKey:3U]);
+ XCTAssertFalse([dict getInt32:NULL forKey:4U]);
[dict release];
}
@@ -720,75 +720,75 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint32_t kKeys[] = { 1U, 2U, 3U, 4U };
const int32_t kValues[] = { 200, 201, 202, 203 };
GPBUInt32Int32Dictionary *dict =
- [[GPBUInt32Int32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt32Int32Dictionary alloc] initWithInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
int32_t value;
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:1U]);
+ XCTAssertTrue([dict getInt32:&value forKey:1U]);
XCTAssertEqual(value, 200);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:2U]);
+ XCTAssertTrue([dict getInt32:&value forKey:2U]);
XCTAssertEqual(value, 201);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:3U]);
+ XCTAssertTrue([dict getInt32:&value forKey:3U]);
XCTAssertEqual(value, 202);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:4U]);
+ XCTAssertTrue([dict getInt32:&value forKey:4U]);
XCTAssertEqual(value, 203);
- [dict setValue:203 forKey:1U];
+ [dict setInt32:203 forKey:1U];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:1U]);
+ XCTAssertTrue([dict getInt32:&value forKey:1U]);
XCTAssertEqual(value, 203);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:2U]);
+ XCTAssertTrue([dict getInt32:&value forKey:2U]);
XCTAssertEqual(value, 201);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:3U]);
+ XCTAssertTrue([dict getInt32:&value forKey:3U]);
XCTAssertEqual(value, 202);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:4U]);
+ XCTAssertTrue([dict getInt32:&value forKey:4U]);
XCTAssertEqual(value, 203);
- [dict setValue:201 forKey:4U];
+ [dict setInt32:201 forKey:4U];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:1U]);
+ XCTAssertTrue([dict getInt32:&value forKey:1U]);
XCTAssertEqual(value, 203);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:2U]);
+ XCTAssertTrue([dict getInt32:&value forKey:2U]);
XCTAssertEqual(value, 201);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:3U]);
+ XCTAssertTrue([dict getInt32:&value forKey:3U]);
XCTAssertEqual(value, 202);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:4U]);
+ XCTAssertTrue([dict getInt32:&value forKey:4U]);
XCTAssertEqual(value, 201);
const uint32_t kKeys2[] = { 2U, 3U };
const int32_t kValues2[] = { 202, 200 };
GPBUInt32Int32Dictionary *dict2 =
- [[GPBUInt32Int32Dictionary alloc] initWithValues:kValues2
+ [[GPBUInt32Int32Dictionary alloc] initWithInt32s:kValues2
forKeys:kKeys2
count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:1U]);
+ XCTAssertTrue([dict getInt32:&value forKey:1U]);
XCTAssertEqual(value, 203);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:2U]);
+ XCTAssertTrue([dict getInt32:&value forKey:2U]);
XCTAssertEqual(value, 202);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:3U]);
+ XCTAssertTrue([dict getInt32:&value forKey:3U]);
XCTAssertEqual(value, 200);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:4U]);
+ XCTAssertTrue([dict getInt32:&value forKey:4U]);
XCTAssertEqual(value, 201);
[dict2 release];
@@ -808,8 +808,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
GPBUInt32UInt64Dictionary *dict = [[GPBUInt32UInt64Dictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:1U value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(uint32_t aKey, uint64_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getUInt64:NULL forKey:1U]);
+ [dict enumerateKeysAndUInt64sUsingBlock:^(uint32_t aKey, uint64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -817,15 +817,15 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testOne {
- GPBUInt32UInt64Dictionary *dict = [GPBUInt32UInt64Dictionary dictionaryWithValue:300U forKey:1U];
+ GPBUInt32UInt64Dictionary *dict = [GPBUInt32UInt64Dictionary dictionaryWithUInt64:300U forKey:1U];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
uint64_t value;
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:1U]);
+ XCTAssertTrue([dict getUInt64:&value forKey:1U]);
XCTAssertEqual(value, 300U);
- XCTAssertFalse([dict valueForKey:2U value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(uint32_t aKey, uint64_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getUInt64:NULL forKey:2U]);
+ [dict enumerateKeysAndUInt64sUsingBlock:^(uint32_t aKey, uint64_t aValue, BOOL *stop) {
XCTAssertEqual(aKey, 1U);
XCTAssertEqual(aValue, 300U);
XCTAssertNotEqual(stop, NULL);
@@ -836,27 +836,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint32_t kKeys[] = { 1U, 2U, 3U };
const uint64_t kValues[] = { 300U, 301U, 302U };
GPBUInt32UInt64Dictionary *dict =
- [[GPBUInt32UInt64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt32UInt64Dictionary alloc] initWithUInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 3U);
uint64_t value;
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:1U]);
+ XCTAssertTrue([dict getUInt64:&value forKey:1U]);
XCTAssertEqual(value, 300U);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:2U]);
+ XCTAssertTrue([dict getUInt64:&value forKey:2U]);
XCTAssertEqual(value, 301U);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:3U]);
+ XCTAssertTrue([dict getUInt64:&value forKey:3U]);
XCTAssertEqual(value, 302U);
- XCTAssertFalse([dict valueForKey:4U value:NULL]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:4U]);
__block NSUInteger idx = 0;
uint32_t *seenKeys = malloc(3 * sizeof(uint32_t));
uint64_t *seenValues = malloc(3 * sizeof(uint64_t));
- [dict enumerateKeysAndValuesUsingBlock:^(uint32_t aKey, uint64_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndUInt64sUsingBlock:^(uint32_t aKey, uint64_t aValue, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -878,7 +878,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(uint32_t aKey, uint64_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndUInt64sUsingBlock:^(uint32_t aKey, uint64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -894,29 +894,29 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint64_t kValues2[] = { 300U, 303U, 302U };
const uint64_t kValues3[] = { 300U, 301U, 302U, 303U };
GPBUInt32UInt64Dictionary *dict1 =
- [[GPBUInt32UInt64Dictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBUInt32UInt64Dictionary alloc] initWithUInt64s:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBUInt32UInt64Dictionary *dict1prime =
- [[GPBUInt32UInt64Dictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBUInt32UInt64Dictionary alloc] initWithUInt64s:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBUInt32UInt64Dictionary *dict2 =
- [[GPBUInt32UInt64Dictionary alloc] initWithValues:kValues2
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBUInt32UInt64Dictionary alloc] initWithUInt64s:kValues2
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBUInt32UInt64Dictionary *dict3 =
- [[GPBUInt32UInt64Dictionary alloc] initWithValues:kValues1
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBUInt32UInt64Dictionary alloc] initWithUInt64s:kValues1
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBUInt32UInt64Dictionary *dict4 =
- [[GPBUInt32UInt64Dictionary alloc] initWithValues:kValues3
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues3)];
+ [[GPBUInt32UInt64Dictionary alloc] initWithUInt64s:kValues3
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
// 1/1Prime should be different objects, but equal.
@@ -945,9 +945,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint32_t kKeys[] = { 1U, 2U, 3U, 4U };
const uint64_t kValues[] = { 300U, 301U, 302U, 303U };
GPBUInt32UInt64Dictionary *dict =
- [[GPBUInt32UInt64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt32UInt64Dictionary alloc] initWithUInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBUInt32UInt64Dictionary *dict2 = [dict copy];
@@ -966,9 +966,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint32_t kKeys[] = { 1U, 2U, 3U, 4U };
const uint64_t kValues[] = { 300U, 301U, 302U, 303U };
GPBUInt32UInt64Dictionary *dict =
- [[GPBUInt32UInt64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt32UInt64Dictionary alloc] initWithUInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBUInt32UInt64Dictionary *dict2 =
@@ -986,31 +986,31 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:300U forKey:1U];
+ [dict setUInt64:300U forKey:1U];
XCTAssertEqual(dict.count, 1U);
const uint32_t kKeys[] = { 2U, 3U, 4U };
const uint64_t kValues[] = { 301U, 302U, 303U };
GPBUInt32UInt64Dictionary *dict2 =
- [[GPBUInt32UInt64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt32UInt64Dictionary alloc] initWithUInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
uint64_t value;
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:1U]);
+ XCTAssertTrue([dict getUInt64:&value forKey:1U]);
XCTAssertEqual(value, 300U);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:2U]);
+ XCTAssertTrue([dict getUInt64:&value forKey:2U]);
XCTAssertEqual(value, 301U);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:3U]);
+ XCTAssertTrue([dict getUInt64:&value forKey:3U]);
XCTAssertEqual(value, 302U);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:4U]);
+ XCTAssertTrue([dict getUInt64:&value forKey:4U]);
XCTAssertEqual(value, 303U);
[dict2 release];
}
@@ -1019,57 +1019,57 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint32_t kKeys[] = { 1U, 2U, 3U, 4U };
const uint64_t kValues[] = { 300U, 301U, 302U, 303U };
GPBUInt32UInt64Dictionary *dict =
- [[GPBUInt32UInt64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt32UInt64Dictionary alloc] initWithUInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
- [dict removeValueForKey:2U];
+ [dict removeUInt64ForKey:2U];
XCTAssertEqual(dict.count, 3U);
uint64_t value;
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:1U]);
+ XCTAssertTrue([dict getUInt64:&value forKey:1U]);
XCTAssertEqual(value, 300U);
- XCTAssertFalse([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:2U]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:3U]);
+ XCTAssertTrue([dict getUInt64:&value forKey:3U]);
XCTAssertEqual(value, 302U);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:4U]);
+ XCTAssertTrue([dict getUInt64:&value forKey:4U]);
XCTAssertEqual(value, 303U);
// Remove again does nothing.
- [dict removeValueForKey:2U];
+ [dict removeUInt64ForKey:2U];
XCTAssertEqual(dict.count, 3U);
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:1U]);
+ XCTAssertTrue([dict getUInt64:&value forKey:1U]);
XCTAssertEqual(value, 300U);
- XCTAssertFalse([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:2U]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:3U]);
+ XCTAssertTrue([dict getUInt64:&value forKey:3U]);
XCTAssertEqual(value, 302U);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:4U]);
+ XCTAssertTrue([dict getUInt64:&value forKey:4U]);
XCTAssertEqual(value, 303U);
- [dict removeValueForKey:4U];
+ [dict removeUInt64ForKey:4U];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:1U]);
+ XCTAssertTrue([dict getUInt64:&value forKey:1U]);
XCTAssertEqual(value, 300U);
- XCTAssertFalse([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:2U]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:3U]);
+ XCTAssertTrue([dict getUInt64:&value forKey:3U]);
XCTAssertEqual(value, 302U);
- XCTAssertFalse([dict valueForKey:4U value:NULL]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:4U]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:1U value:NULL]);
- XCTAssertFalse([dict valueForKey:2U value:NULL]);
- XCTAssertFalse([dict valueForKey:3U value:NULL]);
- XCTAssertFalse([dict valueForKey:4U value:NULL]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:1U]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:2U]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:3U]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:4U]);
[dict release];
}
@@ -1077,75 +1077,75 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint32_t kKeys[] = { 1U, 2U, 3U, 4U };
const uint64_t kValues[] = { 300U, 301U, 302U, 303U };
GPBUInt32UInt64Dictionary *dict =
- [[GPBUInt32UInt64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt32UInt64Dictionary alloc] initWithUInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
uint64_t value;
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:1U]);
+ XCTAssertTrue([dict getUInt64:&value forKey:1U]);
XCTAssertEqual(value, 300U);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:2U]);
+ XCTAssertTrue([dict getUInt64:&value forKey:2U]);
XCTAssertEqual(value, 301U);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:3U]);
+ XCTAssertTrue([dict getUInt64:&value forKey:3U]);
XCTAssertEqual(value, 302U);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:4U]);
+ XCTAssertTrue([dict getUInt64:&value forKey:4U]);
XCTAssertEqual(value, 303U);
- [dict setValue:303U forKey:1U];
+ [dict setUInt64:303U forKey:1U];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:1U]);
+ XCTAssertTrue([dict getUInt64:&value forKey:1U]);
XCTAssertEqual(value, 303U);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:2U]);
+ XCTAssertTrue([dict getUInt64:&value forKey:2U]);
XCTAssertEqual(value, 301U);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:3U]);
+ XCTAssertTrue([dict getUInt64:&value forKey:3U]);
XCTAssertEqual(value, 302U);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:4U]);
+ XCTAssertTrue([dict getUInt64:&value forKey:4U]);
XCTAssertEqual(value, 303U);
- [dict setValue:301U forKey:4U];
+ [dict setUInt64:301U forKey:4U];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:1U]);
+ XCTAssertTrue([dict getUInt64:&value forKey:1U]);
XCTAssertEqual(value, 303U);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:2U]);
+ XCTAssertTrue([dict getUInt64:&value forKey:2U]);
XCTAssertEqual(value, 301U);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:3U]);
+ XCTAssertTrue([dict getUInt64:&value forKey:3U]);
XCTAssertEqual(value, 302U);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:4U]);
+ XCTAssertTrue([dict getUInt64:&value forKey:4U]);
XCTAssertEqual(value, 301U);
const uint32_t kKeys2[] = { 2U, 3U };
const uint64_t kValues2[] = { 302U, 300U };
GPBUInt32UInt64Dictionary *dict2 =
- [[GPBUInt32UInt64Dictionary alloc] initWithValues:kValues2
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBUInt32UInt64Dictionary alloc] initWithUInt64s:kValues2
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:1U]);
+ XCTAssertTrue([dict getUInt64:&value forKey:1U]);
XCTAssertEqual(value, 303U);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:2U]);
+ XCTAssertTrue([dict getUInt64:&value forKey:2U]);
XCTAssertEqual(value, 302U);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:3U]);
+ XCTAssertTrue([dict getUInt64:&value forKey:3U]);
XCTAssertEqual(value, 300U);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:4U]);
+ XCTAssertTrue([dict getUInt64:&value forKey:4U]);
XCTAssertEqual(value, 301U);
[dict2 release];
@@ -1165,8 +1165,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
GPBUInt32Int64Dictionary *dict = [[GPBUInt32Int64Dictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:1U value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(uint32_t aKey, int64_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getInt64:NULL forKey:1U]);
+ [dict enumerateKeysAndInt64sUsingBlock:^(uint32_t aKey, int64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -1174,15 +1174,15 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testOne {
- GPBUInt32Int64Dictionary *dict = [GPBUInt32Int64Dictionary dictionaryWithValue:400 forKey:1U];
+ GPBUInt32Int64Dictionary *dict = [GPBUInt32Int64Dictionary dictionaryWithInt64:400 forKey:1U];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
int64_t value;
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:1U]);
+ XCTAssertTrue([dict getInt64:&value forKey:1U]);
XCTAssertEqual(value, 400);
- XCTAssertFalse([dict valueForKey:2U value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(uint32_t aKey, int64_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getInt64:NULL forKey:2U]);
+ [dict enumerateKeysAndInt64sUsingBlock:^(uint32_t aKey, int64_t aValue, BOOL *stop) {
XCTAssertEqual(aKey, 1U);
XCTAssertEqual(aValue, 400);
XCTAssertNotEqual(stop, NULL);
@@ -1193,27 +1193,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint32_t kKeys[] = { 1U, 2U, 3U };
const int64_t kValues[] = { 400, 401, 402 };
GPBUInt32Int64Dictionary *dict =
- [[GPBUInt32Int64Dictionary alloc] initWithValues:kValues
+ [[GPBUInt32Int64Dictionary alloc] initWithInt64s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 3U);
int64_t value;
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:1U]);
+ XCTAssertTrue([dict getInt64:&value forKey:1U]);
XCTAssertEqual(value, 400);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:2U]);
+ XCTAssertTrue([dict getInt64:&value forKey:2U]);
XCTAssertEqual(value, 401);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:3U]);
+ XCTAssertTrue([dict getInt64:&value forKey:3U]);
XCTAssertEqual(value, 402);
- XCTAssertFalse([dict valueForKey:4U value:NULL]);
+ XCTAssertFalse([dict getInt64:NULL forKey:4U]);
__block NSUInteger idx = 0;
uint32_t *seenKeys = malloc(3 * sizeof(uint32_t));
int64_t *seenValues = malloc(3 * sizeof(int64_t));
- [dict enumerateKeysAndValuesUsingBlock:^(uint32_t aKey, int64_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndInt64sUsingBlock:^(uint32_t aKey, int64_t aValue, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -1235,7 +1235,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(uint32_t aKey, int64_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndInt64sUsingBlock:^(uint32_t aKey, int64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -1251,27 +1251,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int64_t kValues2[] = { 400, 403, 402 };
const int64_t kValues3[] = { 400, 401, 402, 403 };
GPBUInt32Int64Dictionary *dict1 =
- [[GPBUInt32Int64Dictionary alloc] initWithValues:kValues1
+ [[GPBUInt32Int64Dictionary alloc] initWithInt64s:kValues1
forKeys:kKeys1
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBUInt32Int64Dictionary *dict1prime =
- [[GPBUInt32Int64Dictionary alloc] initWithValues:kValues1
+ [[GPBUInt32Int64Dictionary alloc] initWithInt64s:kValues1
forKeys:kKeys1
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBUInt32Int64Dictionary *dict2 =
- [[GPBUInt32Int64Dictionary alloc] initWithValues:kValues2
+ [[GPBUInt32Int64Dictionary alloc] initWithInt64s:kValues2
forKeys:kKeys1
count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBUInt32Int64Dictionary *dict3 =
- [[GPBUInt32Int64Dictionary alloc] initWithValues:kValues1
+ [[GPBUInt32Int64Dictionary alloc] initWithInt64s:kValues1
forKeys:kKeys2
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBUInt32Int64Dictionary *dict4 =
- [[GPBUInt32Int64Dictionary alloc] initWithValues:kValues3
+ [[GPBUInt32Int64Dictionary alloc] initWithInt64s:kValues3
forKeys:kKeys1
count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
@@ -1302,7 +1302,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint32_t kKeys[] = { 1U, 2U, 3U, 4U };
const int64_t kValues[] = { 400, 401, 402, 403 };
GPBUInt32Int64Dictionary *dict =
- [[GPBUInt32Int64Dictionary alloc] initWithValues:kValues
+ [[GPBUInt32Int64Dictionary alloc] initWithInt64s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
@@ -1323,7 +1323,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint32_t kKeys[] = { 1U, 2U, 3U, 4U };
const int64_t kValues[] = { 400, 401, 402, 403 };
GPBUInt32Int64Dictionary *dict =
- [[GPBUInt32Int64Dictionary alloc] initWithValues:kValues
+ [[GPBUInt32Int64Dictionary alloc] initWithInt64s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
@@ -1343,13 +1343,13 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:400 forKey:1U];
+ [dict setInt64:400 forKey:1U];
XCTAssertEqual(dict.count, 1U);
const uint32_t kKeys[] = { 2U, 3U, 4U };
const int64_t kValues[] = { 401, 402, 403 };
GPBUInt32Int64Dictionary *dict2 =
- [[GPBUInt32Int64Dictionary alloc] initWithValues:kValues
+ [[GPBUInt32Int64Dictionary alloc] initWithInt64s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
@@ -1357,17 +1357,17 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertEqual(dict.count, 4U);
int64_t value;
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:1U]);
+ XCTAssertTrue([dict getInt64:&value forKey:1U]);
XCTAssertEqual(value, 400);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:2U]);
+ XCTAssertTrue([dict getInt64:&value forKey:2U]);
XCTAssertEqual(value, 401);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:3U]);
+ XCTAssertTrue([dict getInt64:&value forKey:3U]);
XCTAssertEqual(value, 402);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:4U]);
+ XCTAssertTrue([dict getInt64:&value forKey:4U]);
XCTAssertEqual(value, 403);
[dict2 release];
}
@@ -1376,57 +1376,57 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint32_t kKeys[] = { 1U, 2U, 3U, 4U };
const int64_t kValues[] = { 400, 401, 402, 403 };
GPBUInt32Int64Dictionary *dict =
- [[GPBUInt32Int64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt32Int64Dictionary alloc] initWithInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
- [dict removeValueForKey:2U];
+ [dict removeInt64ForKey:2U];
XCTAssertEqual(dict.count, 3U);
int64_t value;
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:1U]);
+ XCTAssertTrue([dict getInt64:&value forKey:1U]);
XCTAssertEqual(value, 400);
- XCTAssertFalse([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertFalse([dict getInt64:NULL forKey:2U]);
+ XCTAssertTrue([dict getInt64:NULL forKey:3U]);
+ XCTAssertTrue([dict getInt64:&value forKey:3U]);
XCTAssertEqual(value, 402);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:4U]);
+ XCTAssertTrue([dict getInt64:&value forKey:4U]);
XCTAssertEqual(value, 403);
// Remove again does nothing.
- [dict removeValueForKey:2U];
+ [dict removeInt64ForKey:2U];
XCTAssertEqual(dict.count, 3U);
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:1U]);
+ XCTAssertTrue([dict getInt64:&value forKey:1U]);
XCTAssertEqual(value, 400);
- XCTAssertFalse([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertFalse([dict getInt64:NULL forKey:2U]);
+ XCTAssertTrue([dict getInt64:NULL forKey:3U]);
+ XCTAssertTrue([dict getInt64:&value forKey:3U]);
XCTAssertEqual(value, 402);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:4U]);
+ XCTAssertTrue([dict getInt64:&value forKey:4U]);
XCTAssertEqual(value, 403);
- [dict removeValueForKey:4U];
+ [dict removeInt64ForKey:4U];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:1U]);
+ XCTAssertTrue([dict getInt64:&value forKey:1U]);
XCTAssertEqual(value, 400);
- XCTAssertFalse([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertFalse([dict getInt64:NULL forKey:2U]);
+ XCTAssertTrue([dict getInt64:NULL forKey:3U]);
+ XCTAssertTrue([dict getInt64:&value forKey:3U]);
XCTAssertEqual(value, 402);
- XCTAssertFalse([dict valueForKey:4U value:NULL]);
+ XCTAssertFalse([dict getInt64:NULL forKey:4U]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:1U value:NULL]);
- XCTAssertFalse([dict valueForKey:2U value:NULL]);
- XCTAssertFalse([dict valueForKey:3U value:NULL]);
- XCTAssertFalse([dict valueForKey:4U value:NULL]);
+ XCTAssertFalse([dict getInt64:NULL forKey:1U]);
+ XCTAssertFalse([dict getInt64:NULL forKey:2U]);
+ XCTAssertFalse([dict getInt64:NULL forKey:3U]);
+ XCTAssertFalse([dict getInt64:NULL forKey:4U]);
[dict release];
}
@@ -1434,75 +1434,75 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint32_t kKeys[] = { 1U, 2U, 3U, 4U };
const int64_t kValues[] = { 400, 401, 402, 403 };
GPBUInt32Int64Dictionary *dict =
- [[GPBUInt32Int64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt32Int64Dictionary alloc] initWithInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
int64_t value;
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:1U]);
+ XCTAssertTrue([dict getInt64:&value forKey:1U]);
XCTAssertEqual(value, 400);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:2U]);
+ XCTAssertTrue([dict getInt64:&value forKey:2U]);
XCTAssertEqual(value, 401);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:3U]);
+ XCTAssertTrue([dict getInt64:&value forKey:3U]);
XCTAssertEqual(value, 402);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:4U]);
+ XCTAssertTrue([dict getInt64:&value forKey:4U]);
XCTAssertEqual(value, 403);
- [dict setValue:403 forKey:1U];
+ [dict setInt64:403 forKey:1U];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:1U]);
+ XCTAssertTrue([dict getInt64:&value forKey:1U]);
XCTAssertEqual(value, 403);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:2U]);
+ XCTAssertTrue([dict getInt64:&value forKey:2U]);
XCTAssertEqual(value, 401);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:3U]);
+ XCTAssertTrue([dict getInt64:&value forKey:3U]);
XCTAssertEqual(value, 402);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:4U]);
+ XCTAssertTrue([dict getInt64:&value forKey:4U]);
XCTAssertEqual(value, 403);
- [dict setValue:401 forKey:4U];
+ [dict setInt64:401 forKey:4U];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:1U]);
+ XCTAssertTrue([dict getInt64:&value forKey:1U]);
XCTAssertEqual(value, 403);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:2U]);
+ XCTAssertTrue([dict getInt64:&value forKey:2U]);
XCTAssertEqual(value, 401);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:3U]);
+ XCTAssertTrue([dict getInt64:&value forKey:3U]);
XCTAssertEqual(value, 402);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:4U]);
+ XCTAssertTrue([dict getInt64:&value forKey:4U]);
XCTAssertEqual(value, 401);
const uint32_t kKeys2[] = { 2U, 3U };
const int64_t kValues2[] = { 402, 400 };
GPBUInt32Int64Dictionary *dict2 =
- [[GPBUInt32Int64Dictionary alloc] initWithValues:kValues2
+ [[GPBUInt32Int64Dictionary alloc] initWithInt64s:kValues2
forKeys:kKeys2
count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:1U]);
+ XCTAssertTrue([dict getInt64:&value forKey:1U]);
XCTAssertEqual(value, 403);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:2U]);
+ XCTAssertTrue([dict getInt64:&value forKey:2U]);
XCTAssertEqual(value, 402);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:3U]);
+ XCTAssertTrue([dict getInt64:&value forKey:3U]);
XCTAssertEqual(value, 400);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:4U]);
+ XCTAssertTrue([dict getInt64:&value forKey:4U]);
XCTAssertEqual(value, 401);
[dict2 release];
@@ -1522,8 +1522,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
GPBUInt32BoolDictionary *dict = [[GPBUInt32BoolDictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:1U value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(uint32_t aKey, BOOL aValue, BOOL *stop) {
+ XCTAssertFalse([dict getBool:NULL forKey:1U]);
+ [dict enumerateKeysAndBoolsUsingBlock:^(uint32_t aKey, BOOL aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -1531,15 +1531,15 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testOne {
- GPBUInt32BoolDictionary *dict = [GPBUInt32BoolDictionary dictionaryWithValue:YES forKey:1U];
+ GPBUInt32BoolDictionary *dict = [GPBUInt32BoolDictionary dictionaryWithBool:YES forKey:1U];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
BOOL value;
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:1U]);
+ XCTAssertTrue([dict getBool:&value forKey:1U]);
XCTAssertEqual(value, YES);
- XCTAssertFalse([dict valueForKey:2U value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(uint32_t aKey, BOOL aValue, BOOL *stop) {
+ XCTAssertFalse([dict getBool:NULL forKey:2U]);
+ [dict enumerateKeysAndBoolsUsingBlock:^(uint32_t aKey, BOOL aValue, BOOL *stop) {
XCTAssertEqual(aKey, 1U);
XCTAssertEqual(aValue, YES);
XCTAssertNotEqual(stop, NULL);
@@ -1550,27 +1550,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint32_t kKeys[] = { 1U, 2U, 3U };
const BOOL kValues[] = { YES, YES, NO };
GPBUInt32BoolDictionary *dict =
- [[GPBUInt32BoolDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt32BoolDictionary alloc] initWithBools:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 3U);
BOOL value;
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:1U]);
+ XCTAssertTrue([dict getBool:&value forKey:1U]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:2U]);
+ XCTAssertTrue([dict getBool:&value forKey:2U]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:3U]);
+ XCTAssertTrue([dict getBool:&value forKey:3U]);
XCTAssertEqual(value, NO);
- XCTAssertFalse([dict valueForKey:4U value:NULL]);
+ XCTAssertFalse([dict getBool:NULL forKey:4U]);
__block NSUInteger idx = 0;
uint32_t *seenKeys = malloc(3 * sizeof(uint32_t));
BOOL *seenValues = malloc(3 * sizeof(BOOL));
- [dict enumerateKeysAndValuesUsingBlock:^(uint32_t aKey, BOOL aValue, BOOL *stop) {
+ [dict enumerateKeysAndBoolsUsingBlock:^(uint32_t aKey, BOOL aValue, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -1592,7 +1592,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(uint32_t aKey, BOOL aValue, BOOL *stop) {
+ [dict enumerateKeysAndBoolsUsingBlock:^(uint32_t aKey, BOOL aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -1608,29 +1608,29 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const BOOL kValues2[] = { YES, NO, NO };
const BOOL kValues3[] = { YES, YES, NO, NO };
GPBUInt32BoolDictionary *dict1 =
- [[GPBUInt32BoolDictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBUInt32BoolDictionary alloc] initWithBools:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBUInt32BoolDictionary *dict1prime =
- [[GPBUInt32BoolDictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBUInt32BoolDictionary alloc] initWithBools:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBUInt32BoolDictionary *dict2 =
- [[GPBUInt32BoolDictionary alloc] initWithValues:kValues2
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBUInt32BoolDictionary alloc] initWithBools:kValues2
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBUInt32BoolDictionary *dict3 =
- [[GPBUInt32BoolDictionary alloc] initWithValues:kValues1
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBUInt32BoolDictionary alloc] initWithBools:kValues1
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBUInt32BoolDictionary *dict4 =
- [[GPBUInt32BoolDictionary alloc] initWithValues:kValues3
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues3)];
+ [[GPBUInt32BoolDictionary alloc] initWithBools:kValues3
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
// 1/1Prime should be different objects, but equal.
@@ -1659,9 +1659,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint32_t kKeys[] = { 1U, 2U, 3U, 4U };
const BOOL kValues[] = { YES, YES, NO, NO };
GPBUInt32BoolDictionary *dict =
- [[GPBUInt32BoolDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt32BoolDictionary alloc] initWithBools:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBUInt32BoolDictionary *dict2 = [dict copy];
@@ -1680,9 +1680,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint32_t kKeys[] = { 1U, 2U, 3U, 4U };
const BOOL kValues[] = { YES, YES, NO, NO };
GPBUInt32BoolDictionary *dict =
- [[GPBUInt32BoolDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt32BoolDictionary alloc] initWithBools:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBUInt32BoolDictionary *dict2 =
@@ -1700,31 +1700,31 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:YES forKey:1U];
+ [dict setBool:YES forKey:1U];
XCTAssertEqual(dict.count, 1U);
const uint32_t kKeys[] = { 2U, 3U, 4U };
const BOOL kValues[] = { YES, NO, NO };
GPBUInt32BoolDictionary *dict2 =
- [[GPBUInt32BoolDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt32BoolDictionary alloc] initWithBools:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
BOOL value;
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:1U]);
+ XCTAssertTrue([dict getBool:&value forKey:1U]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:2U]);
+ XCTAssertTrue([dict getBool:&value forKey:2U]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:3U]);
+ XCTAssertTrue([dict getBool:&value forKey:3U]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:4U]);
+ XCTAssertTrue([dict getBool:&value forKey:4U]);
XCTAssertEqual(value, NO);
[dict2 release];
}
@@ -1733,57 +1733,57 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint32_t kKeys[] = { 1U, 2U, 3U, 4U };
const BOOL kValues[] = { YES, YES, NO, NO };
GPBUInt32BoolDictionary *dict =
- [[GPBUInt32BoolDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt32BoolDictionary alloc] initWithBools:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
- [dict removeValueForKey:2U];
+ [dict removeBoolForKey:2U];
XCTAssertEqual(dict.count, 3U);
BOOL value;
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:1U]);
+ XCTAssertTrue([dict getBool:&value forKey:1U]);
XCTAssertEqual(value, YES);
- XCTAssertFalse([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertFalse([dict getBool:NULL forKey:2U]);
+ XCTAssertTrue([dict getBool:NULL forKey:3U]);
+ XCTAssertTrue([dict getBool:&value forKey:3U]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:4U]);
+ XCTAssertTrue([dict getBool:&value forKey:4U]);
XCTAssertEqual(value, NO);
// Remove again does nothing.
- [dict removeValueForKey:2U];
+ [dict removeBoolForKey:2U];
XCTAssertEqual(dict.count, 3U);
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:1U]);
+ XCTAssertTrue([dict getBool:&value forKey:1U]);
XCTAssertEqual(value, YES);
- XCTAssertFalse([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertFalse([dict getBool:NULL forKey:2U]);
+ XCTAssertTrue([dict getBool:NULL forKey:3U]);
+ XCTAssertTrue([dict getBool:&value forKey:3U]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:4U]);
+ XCTAssertTrue([dict getBool:&value forKey:4U]);
XCTAssertEqual(value, NO);
- [dict removeValueForKey:4U];
+ [dict removeBoolForKey:4U];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:1U]);
+ XCTAssertTrue([dict getBool:&value forKey:1U]);
XCTAssertEqual(value, YES);
- XCTAssertFalse([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertFalse([dict getBool:NULL forKey:2U]);
+ XCTAssertTrue([dict getBool:NULL forKey:3U]);
+ XCTAssertTrue([dict getBool:&value forKey:3U]);
XCTAssertEqual(value, NO);
- XCTAssertFalse([dict valueForKey:4U value:NULL]);
+ XCTAssertFalse([dict getBool:NULL forKey:4U]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:1U value:NULL]);
- XCTAssertFalse([dict valueForKey:2U value:NULL]);
- XCTAssertFalse([dict valueForKey:3U value:NULL]);
- XCTAssertFalse([dict valueForKey:4U value:NULL]);
+ XCTAssertFalse([dict getBool:NULL forKey:1U]);
+ XCTAssertFalse([dict getBool:NULL forKey:2U]);
+ XCTAssertFalse([dict getBool:NULL forKey:3U]);
+ XCTAssertFalse([dict getBool:NULL forKey:4U]);
[dict release];
}
@@ -1791,75 +1791,75 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint32_t kKeys[] = { 1U, 2U, 3U, 4U };
const BOOL kValues[] = { YES, YES, NO, NO };
GPBUInt32BoolDictionary *dict =
- [[GPBUInt32BoolDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt32BoolDictionary alloc] initWithBools:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
BOOL value;
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:1U]);
+ XCTAssertTrue([dict getBool:&value forKey:1U]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:2U]);
+ XCTAssertTrue([dict getBool:&value forKey:2U]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:3U]);
+ XCTAssertTrue([dict getBool:&value forKey:3U]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:4U]);
+ XCTAssertTrue([dict getBool:&value forKey:4U]);
XCTAssertEqual(value, NO);
- [dict setValue:NO forKey:1U];
+ [dict setBool:NO forKey:1U];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:1U]);
+ XCTAssertTrue([dict getBool:&value forKey:1U]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:2U]);
+ XCTAssertTrue([dict getBool:&value forKey:2U]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:3U]);
+ XCTAssertTrue([dict getBool:&value forKey:3U]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:4U]);
+ XCTAssertTrue([dict getBool:&value forKey:4U]);
XCTAssertEqual(value, NO);
- [dict setValue:YES forKey:4U];
+ [dict setBool:YES forKey:4U];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:1U]);
+ XCTAssertTrue([dict getBool:&value forKey:1U]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:2U]);
+ XCTAssertTrue([dict getBool:&value forKey:2U]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:3U]);
+ XCTAssertTrue([dict getBool:&value forKey:3U]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:4U]);
+ XCTAssertTrue([dict getBool:&value forKey:4U]);
XCTAssertEqual(value, YES);
const uint32_t kKeys2[] = { 2U, 3U };
const BOOL kValues2[] = { NO, YES };
GPBUInt32BoolDictionary *dict2 =
- [[GPBUInt32BoolDictionary alloc] initWithValues:kValues2
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBUInt32BoolDictionary alloc] initWithBools:kValues2
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:1U]);
+ XCTAssertTrue([dict getBool:&value forKey:1U]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:2U]);
+ XCTAssertTrue([dict getBool:&value forKey:2U]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:3U]);
+ XCTAssertTrue([dict getBool:&value forKey:3U]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:4U]);
+ XCTAssertTrue([dict getBool:&value forKey:4U]);
XCTAssertEqual(value, YES);
[dict2 release];
@@ -1879,8 +1879,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
GPBUInt32FloatDictionary *dict = [[GPBUInt32FloatDictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:1U value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(uint32_t aKey, float aValue, BOOL *stop) {
+ XCTAssertFalse([dict getFloat:NULL forKey:1U]);
+ [dict enumerateKeysAndFloatsUsingBlock:^(uint32_t aKey, float aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -1888,15 +1888,15 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testOne {
- GPBUInt32FloatDictionary *dict = [GPBUInt32FloatDictionary dictionaryWithValue:500.f forKey:1U];
+ GPBUInt32FloatDictionary *dict = [GPBUInt32FloatDictionary dictionaryWithFloat:500.f forKey:1U];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
float value;
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:1U]);
+ XCTAssertTrue([dict getFloat:&value forKey:1U]);
XCTAssertEqual(value, 500.f);
- XCTAssertFalse([dict valueForKey:2U value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(uint32_t aKey, float aValue, BOOL *stop) {
+ XCTAssertFalse([dict getFloat:NULL forKey:2U]);
+ [dict enumerateKeysAndFloatsUsingBlock:^(uint32_t aKey, float aValue, BOOL *stop) {
XCTAssertEqual(aKey, 1U);
XCTAssertEqual(aValue, 500.f);
XCTAssertNotEqual(stop, NULL);
@@ -1907,27 +1907,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint32_t kKeys[] = { 1U, 2U, 3U };
const float kValues[] = { 500.f, 501.f, 502.f };
GPBUInt32FloatDictionary *dict =
- [[GPBUInt32FloatDictionary alloc] initWithValues:kValues
+ [[GPBUInt32FloatDictionary alloc] initWithFloats:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 3U);
float value;
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:1U]);
+ XCTAssertTrue([dict getFloat:&value forKey:1U]);
XCTAssertEqual(value, 500.f);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:2U]);
+ XCTAssertTrue([dict getFloat:&value forKey:2U]);
XCTAssertEqual(value, 501.f);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:3U]);
+ XCTAssertTrue([dict getFloat:&value forKey:3U]);
XCTAssertEqual(value, 502.f);
- XCTAssertFalse([dict valueForKey:4U value:NULL]);
+ XCTAssertFalse([dict getFloat:NULL forKey:4U]);
__block NSUInteger idx = 0;
uint32_t *seenKeys = malloc(3 * sizeof(uint32_t));
float *seenValues = malloc(3 * sizeof(float));
- [dict enumerateKeysAndValuesUsingBlock:^(uint32_t aKey, float aValue, BOOL *stop) {
+ [dict enumerateKeysAndFloatsUsingBlock:^(uint32_t aKey, float aValue, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -1949,7 +1949,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(uint32_t aKey, float aValue, BOOL *stop) {
+ [dict enumerateKeysAndFloatsUsingBlock:^(uint32_t aKey, float aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -1965,27 +1965,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const float kValues2[] = { 500.f, 503.f, 502.f };
const float kValues3[] = { 500.f, 501.f, 502.f, 503.f };
GPBUInt32FloatDictionary *dict1 =
- [[GPBUInt32FloatDictionary alloc] initWithValues:kValues1
+ [[GPBUInt32FloatDictionary alloc] initWithFloats:kValues1
forKeys:kKeys1
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBUInt32FloatDictionary *dict1prime =
- [[GPBUInt32FloatDictionary alloc] initWithValues:kValues1
+ [[GPBUInt32FloatDictionary alloc] initWithFloats:kValues1
forKeys:kKeys1
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBUInt32FloatDictionary *dict2 =
- [[GPBUInt32FloatDictionary alloc] initWithValues:kValues2
+ [[GPBUInt32FloatDictionary alloc] initWithFloats:kValues2
forKeys:kKeys1
count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBUInt32FloatDictionary *dict3 =
- [[GPBUInt32FloatDictionary alloc] initWithValues:kValues1
+ [[GPBUInt32FloatDictionary alloc] initWithFloats:kValues1
forKeys:kKeys2
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBUInt32FloatDictionary *dict4 =
- [[GPBUInt32FloatDictionary alloc] initWithValues:kValues3
+ [[GPBUInt32FloatDictionary alloc] initWithFloats:kValues3
forKeys:kKeys1
count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
@@ -2016,7 +2016,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint32_t kKeys[] = { 1U, 2U, 3U, 4U };
const float kValues[] = { 500.f, 501.f, 502.f, 503.f };
GPBUInt32FloatDictionary *dict =
- [[GPBUInt32FloatDictionary alloc] initWithValues:kValues
+ [[GPBUInt32FloatDictionary alloc] initWithFloats:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
@@ -2037,7 +2037,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint32_t kKeys[] = { 1U, 2U, 3U, 4U };
const float kValues[] = { 500.f, 501.f, 502.f, 503.f };
GPBUInt32FloatDictionary *dict =
- [[GPBUInt32FloatDictionary alloc] initWithValues:kValues
+ [[GPBUInt32FloatDictionary alloc] initWithFloats:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
@@ -2057,13 +2057,13 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:500.f forKey:1U];
+ [dict setFloat:500.f forKey:1U];
XCTAssertEqual(dict.count, 1U);
const uint32_t kKeys[] = { 2U, 3U, 4U };
const float kValues[] = { 501.f, 502.f, 503.f };
GPBUInt32FloatDictionary *dict2 =
- [[GPBUInt32FloatDictionary alloc] initWithValues:kValues
+ [[GPBUInt32FloatDictionary alloc] initWithFloats:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
@@ -2071,17 +2071,17 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertEqual(dict.count, 4U);
float value;
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:1U]);
+ XCTAssertTrue([dict getFloat:&value forKey:1U]);
XCTAssertEqual(value, 500.f);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:2U]);
+ XCTAssertTrue([dict getFloat:&value forKey:2U]);
XCTAssertEqual(value, 501.f);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:3U]);
+ XCTAssertTrue([dict getFloat:&value forKey:3U]);
XCTAssertEqual(value, 502.f);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:4U]);
+ XCTAssertTrue([dict getFloat:&value forKey:4U]);
XCTAssertEqual(value, 503.f);
[dict2 release];
}
@@ -2090,57 +2090,57 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint32_t kKeys[] = { 1U, 2U, 3U, 4U };
const float kValues[] = { 500.f, 501.f, 502.f, 503.f };
GPBUInt32FloatDictionary *dict =
- [[GPBUInt32FloatDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt32FloatDictionary alloc] initWithFloats:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
- [dict removeValueForKey:2U];
+ [dict removeFloatForKey:2U];
XCTAssertEqual(dict.count, 3U);
float value;
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:1U]);
+ XCTAssertTrue([dict getFloat:&value forKey:1U]);
XCTAssertEqual(value, 500.f);
- XCTAssertFalse([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertFalse([dict getFloat:NULL forKey:2U]);
+ XCTAssertTrue([dict getFloat:NULL forKey:3U]);
+ XCTAssertTrue([dict getFloat:&value forKey:3U]);
XCTAssertEqual(value, 502.f);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:4U]);
+ XCTAssertTrue([dict getFloat:&value forKey:4U]);
XCTAssertEqual(value, 503.f);
// Remove again does nothing.
- [dict removeValueForKey:2U];
+ [dict removeFloatForKey:2U];
XCTAssertEqual(dict.count, 3U);
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:1U]);
+ XCTAssertTrue([dict getFloat:&value forKey:1U]);
XCTAssertEqual(value, 500.f);
- XCTAssertFalse([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertFalse([dict getFloat:NULL forKey:2U]);
+ XCTAssertTrue([dict getFloat:NULL forKey:3U]);
+ XCTAssertTrue([dict getFloat:&value forKey:3U]);
XCTAssertEqual(value, 502.f);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:4U]);
+ XCTAssertTrue([dict getFloat:&value forKey:4U]);
XCTAssertEqual(value, 503.f);
- [dict removeValueForKey:4U];
+ [dict removeFloatForKey:4U];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:1U]);
+ XCTAssertTrue([dict getFloat:&value forKey:1U]);
XCTAssertEqual(value, 500.f);
- XCTAssertFalse([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertFalse([dict getFloat:NULL forKey:2U]);
+ XCTAssertTrue([dict getFloat:NULL forKey:3U]);
+ XCTAssertTrue([dict getFloat:&value forKey:3U]);
XCTAssertEqual(value, 502.f);
- XCTAssertFalse([dict valueForKey:4U value:NULL]);
+ XCTAssertFalse([dict getFloat:NULL forKey:4U]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:1U value:NULL]);
- XCTAssertFalse([dict valueForKey:2U value:NULL]);
- XCTAssertFalse([dict valueForKey:3U value:NULL]);
- XCTAssertFalse([dict valueForKey:4U value:NULL]);
+ XCTAssertFalse([dict getFloat:NULL forKey:1U]);
+ XCTAssertFalse([dict getFloat:NULL forKey:2U]);
+ XCTAssertFalse([dict getFloat:NULL forKey:3U]);
+ XCTAssertFalse([dict getFloat:NULL forKey:4U]);
[dict release];
}
@@ -2148,75 +2148,75 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint32_t kKeys[] = { 1U, 2U, 3U, 4U };
const float kValues[] = { 500.f, 501.f, 502.f, 503.f };
GPBUInt32FloatDictionary *dict =
- [[GPBUInt32FloatDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt32FloatDictionary alloc] initWithFloats:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
float value;
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:1U]);
+ XCTAssertTrue([dict getFloat:&value forKey:1U]);
XCTAssertEqual(value, 500.f);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:2U]);
+ XCTAssertTrue([dict getFloat:&value forKey:2U]);
XCTAssertEqual(value, 501.f);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:3U]);
+ XCTAssertTrue([dict getFloat:&value forKey:3U]);
XCTAssertEqual(value, 502.f);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:4U]);
+ XCTAssertTrue([dict getFloat:&value forKey:4U]);
XCTAssertEqual(value, 503.f);
- [dict setValue:503.f forKey:1U];
+ [dict setFloat:503.f forKey:1U];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:1U]);
+ XCTAssertTrue([dict getFloat:&value forKey:1U]);
XCTAssertEqual(value, 503.f);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:2U]);
+ XCTAssertTrue([dict getFloat:&value forKey:2U]);
XCTAssertEqual(value, 501.f);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:3U]);
+ XCTAssertTrue([dict getFloat:&value forKey:3U]);
XCTAssertEqual(value, 502.f);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:4U]);
+ XCTAssertTrue([dict getFloat:&value forKey:4U]);
XCTAssertEqual(value, 503.f);
- [dict setValue:501.f forKey:4U];
+ [dict setFloat:501.f forKey:4U];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:1U]);
+ XCTAssertTrue([dict getFloat:&value forKey:1U]);
XCTAssertEqual(value, 503.f);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:2U]);
+ XCTAssertTrue([dict getFloat:&value forKey:2U]);
XCTAssertEqual(value, 501.f);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:3U]);
+ XCTAssertTrue([dict getFloat:&value forKey:3U]);
XCTAssertEqual(value, 502.f);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:4U]);
+ XCTAssertTrue([dict getFloat:&value forKey:4U]);
XCTAssertEqual(value, 501.f);
const uint32_t kKeys2[] = { 2U, 3U };
const float kValues2[] = { 502.f, 500.f };
GPBUInt32FloatDictionary *dict2 =
- [[GPBUInt32FloatDictionary alloc] initWithValues:kValues2
+ [[GPBUInt32FloatDictionary alloc] initWithFloats:kValues2
forKeys:kKeys2
count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:1U]);
+ XCTAssertTrue([dict getFloat:&value forKey:1U]);
XCTAssertEqual(value, 503.f);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:2U]);
+ XCTAssertTrue([dict getFloat:&value forKey:2U]);
XCTAssertEqual(value, 502.f);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:3U]);
+ XCTAssertTrue([dict getFloat:&value forKey:3U]);
XCTAssertEqual(value, 500.f);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:4U]);
+ XCTAssertTrue([dict getFloat:&value forKey:4U]);
XCTAssertEqual(value, 501.f);
[dict2 release];
@@ -2236,8 +2236,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
GPBUInt32DoubleDictionary *dict = [[GPBUInt32DoubleDictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:1U value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(uint32_t aKey, double aValue, BOOL *stop) {
+ XCTAssertFalse([dict getDouble:NULL forKey:1U]);
+ [dict enumerateKeysAndDoublesUsingBlock:^(uint32_t aKey, double aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -2245,15 +2245,15 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testOne {
- GPBUInt32DoubleDictionary *dict = [GPBUInt32DoubleDictionary dictionaryWithValue:600. forKey:1U];
+ GPBUInt32DoubleDictionary *dict = [GPBUInt32DoubleDictionary dictionaryWithDouble:600. forKey:1U];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
double value;
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:1U]);
+ XCTAssertTrue([dict getDouble:&value forKey:1U]);
XCTAssertEqual(value, 600.);
- XCTAssertFalse([dict valueForKey:2U value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(uint32_t aKey, double aValue, BOOL *stop) {
+ XCTAssertFalse([dict getDouble:NULL forKey:2U]);
+ [dict enumerateKeysAndDoublesUsingBlock:^(uint32_t aKey, double aValue, BOOL *stop) {
XCTAssertEqual(aKey, 1U);
XCTAssertEqual(aValue, 600.);
XCTAssertNotEqual(stop, NULL);
@@ -2264,27 +2264,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint32_t kKeys[] = { 1U, 2U, 3U };
const double kValues[] = { 600., 601., 602. };
GPBUInt32DoubleDictionary *dict =
- [[GPBUInt32DoubleDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt32DoubleDictionary alloc] initWithDoubles:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 3U);
double value;
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:1U]);
+ XCTAssertTrue([dict getDouble:&value forKey:1U]);
XCTAssertEqual(value, 600.);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:2U]);
+ XCTAssertTrue([dict getDouble:&value forKey:2U]);
XCTAssertEqual(value, 601.);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:3U]);
+ XCTAssertTrue([dict getDouble:&value forKey:3U]);
XCTAssertEqual(value, 602.);
- XCTAssertFalse([dict valueForKey:4U value:NULL]);
+ XCTAssertFalse([dict getDouble:NULL forKey:4U]);
__block NSUInteger idx = 0;
uint32_t *seenKeys = malloc(3 * sizeof(uint32_t));
double *seenValues = malloc(3 * sizeof(double));
- [dict enumerateKeysAndValuesUsingBlock:^(uint32_t aKey, double aValue, BOOL *stop) {
+ [dict enumerateKeysAndDoublesUsingBlock:^(uint32_t aKey, double aValue, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -2306,7 +2306,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(uint32_t aKey, double aValue, BOOL *stop) {
+ [dict enumerateKeysAndDoublesUsingBlock:^(uint32_t aKey, double aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -2322,29 +2322,29 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const double kValues2[] = { 600., 603., 602. };
const double kValues3[] = { 600., 601., 602., 603. };
GPBUInt32DoubleDictionary *dict1 =
- [[GPBUInt32DoubleDictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBUInt32DoubleDictionary alloc] initWithDoubles:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBUInt32DoubleDictionary *dict1prime =
- [[GPBUInt32DoubleDictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBUInt32DoubleDictionary alloc] initWithDoubles:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBUInt32DoubleDictionary *dict2 =
- [[GPBUInt32DoubleDictionary alloc] initWithValues:kValues2
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBUInt32DoubleDictionary alloc] initWithDoubles:kValues2
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBUInt32DoubleDictionary *dict3 =
- [[GPBUInt32DoubleDictionary alloc] initWithValues:kValues1
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBUInt32DoubleDictionary alloc] initWithDoubles:kValues1
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBUInt32DoubleDictionary *dict4 =
- [[GPBUInt32DoubleDictionary alloc] initWithValues:kValues3
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues3)];
+ [[GPBUInt32DoubleDictionary alloc] initWithDoubles:kValues3
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
// 1/1Prime should be different objects, but equal.
@@ -2373,9 +2373,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint32_t kKeys[] = { 1U, 2U, 3U, 4U };
const double kValues[] = { 600., 601., 602., 603. };
GPBUInt32DoubleDictionary *dict =
- [[GPBUInt32DoubleDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt32DoubleDictionary alloc] initWithDoubles:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBUInt32DoubleDictionary *dict2 = [dict copy];
@@ -2394,9 +2394,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint32_t kKeys[] = { 1U, 2U, 3U, 4U };
const double kValues[] = { 600., 601., 602., 603. };
GPBUInt32DoubleDictionary *dict =
- [[GPBUInt32DoubleDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt32DoubleDictionary alloc] initWithDoubles:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBUInt32DoubleDictionary *dict2 =
@@ -2414,31 +2414,31 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:600. forKey:1U];
+ [dict setDouble:600. forKey:1U];
XCTAssertEqual(dict.count, 1U);
const uint32_t kKeys[] = { 2U, 3U, 4U };
const double kValues[] = { 601., 602., 603. };
GPBUInt32DoubleDictionary *dict2 =
- [[GPBUInt32DoubleDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt32DoubleDictionary alloc] initWithDoubles:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
double value;
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:1U]);
+ XCTAssertTrue([dict getDouble:&value forKey:1U]);
XCTAssertEqual(value, 600.);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:2U]);
+ XCTAssertTrue([dict getDouble:&value forKey:2U]);
XCTAssertEqual(value, 601.);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:3U]);
+ XCTAssertTrue([dict getDouble:&value forKey:3U]);
XCTAssertEqual(value, 602.);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:4U]);
+ XCTAssertTrue([dict getDouble:&value forKey:4U]);
XCTAssertEqual(value, 603.);
[dict2 release];
}
@@ -2447,57 +2447,57 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint32_t kKeys[] = { 1U, 2U, 3U, 4U };
const double kValues[] = { 600., 601., 602., 603. };
GPBUInt32DoubleDictionary *dict =
- [[GPBUInt32DoubleDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt32DoubleDictionary alloc] initWithDoubles:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
- [dict removeValueForKey:2U];
+ [dict removeDoubleForKey:2U];
XCTAssertEqual(dict.count, 3U);
double value;
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:1U]);
+ XCTAssertTrue([dict getDouble:&value forKey:1U]);
XCTAssertEqual(value, 600.);
- XCTAssertFalse([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertFalse([dict getDouble:NULL forKey:2U]);
+ XCTAssertTrue([dict getDouble:NULL forKey:3U]);
+ XCTAssertTrue([dict getDouble:&value forKey:3U]);
XCTAssertEqual(value, 602.);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:4U]);
+ XCTAssertTrue([dict getDouble:&value forKey:4U]);
XCTAssertEqual(value, 603.);
// Remove again does nothing.
- [dict removeValueForKey:2U];
+ [dict removeDoubleForKey:2U];
XCTAssertEqual(dict.count, 3U);
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:1U]);
+ XCTAssertTrue([dict getDouble:&value forKey:1U]);
XCTAssertEqual(value, 600.);
- XCTAssertFalse([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertFalse([dict getDouble:NULL forKey:2U]);
+ XCTAssertTrue([dict getDouble:NULL forKey:3U]);
+ XCTAssertTrue([dict getDouble:&value forKey:3U]);
XCTAssertEqual(value, 602.);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:4U]);
+ XCTAssertTrue([dict getDouble:&value forKey:4U]);
XCTAssertEqual(value, 603.);
- [dict removeValueForKey:4U];
+ [dict removeDoubleForKey:4U];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:1U]);
+ XCTAssertTrue([dict getDouble:&value forKey:1U]);
XCTAssertEqual(value, 600.);
- XCTAssertFalse([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertFalse([dict getDouble:NULL forKey:2U]);
+ XCTAssertTrue([dict getDouble:NULL forKey:3U]);
+ XCTAssertTrue([dict getDouble:&value forKey:3U]);
XCTAssertEqual(value, 602.);
- XCTAssertFalse([dict valueForKey:4U value:NULL]);
+ XCTAssertFalse([dict getDouble:NULL forKey:4U]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:1U value:NULL]);
- XCTAssertFalse([dict valueForKey:2U value:NULL]);
- XCTAssertFalse([dict valueForKey:3U value:NULL]);
- XCTAssertFalse([dict valueForKey:4U value:NULL]);
+ XCTAssertFalse([dict getDouble:NULL forKey:1U]);
+ XCTAssertFalse([dict getDouble:NULL forKey:2U]);
+ XCTAssertFalse([dict getDouble:NULL forKey:3U]);
+ XCTAssertFalse([dict getDouble:NULL forKey:4U]);
[dict release];
}
@@ -2505,75 +2505,75 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint32_t kKeys[] = { 1U, 2U, 3U, 4U };
const double kValues[] = { 600., 601., 602., 603. };
GPBUInt32DoubleDictionary *dict =
- [[GPBUInt32DoubleDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt32DoubleDictionary alloc] initWithDoubles:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
double value;
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:1U]);
+ XCTAssertTrue([dict getDouble:&value forKey:1U]);
XCTAssertEqual(value, 600.);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:2U]);
+ XCTAssertTrue([dict getDouble:&value forKey:2U]);
XCTAssertEqual(value, 601.);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:3U]);
+ XCTAssertTrue([dict getDouble:&value forKey:3U]);
XCTAssertEqual(value, 602.);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:4U]);
+ XCTAssertTrue([dict getDouble:&value forKey:4U]);
XCTAssertEqual(value, 603.);
- [dict setValue:603. forKey:1U];
+ [dict setDouble:603. forKey:1U];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:1U]);
+ XCTAssertTrue([dict getDouble:&value forKey:1U]);
XCTAssertEqual(value, 603.);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:2U]);
+ XCTAssertTrue([dict getDouble:&value forKey:2U]);
XCTAssertEqual(value, 601.);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:3U]);
+ XCTAssertTrue([dict getDouble:&value forKey:3U]);
XCTAssertEqual(value, 602.);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:4U]);
+ XCTAssertTrue([dict getDouble:&value forKey:4U]);
XCTAssertEqual(value, 603.);
- [dict setValue:601. forKey:4U];
+ [dict setDouble:601. forKey:4U];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:1U]);
+ XCTAssertTrue([dict getDouble:&value forKey:1U]);
XCTAssertEqual(value, 603.);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:2U]);
+ XCTAssertTrue([dict getDouble:&value forKey:2U]);
XCTAssertEqual(value, 601.);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:3U]);
+ XCTAssertTrue([dict getDouble:&value forKey:3U]);
XCTAssertEqual(value, 602.);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:4U]);
+ XCTAssertTrue([dict getDouble:&value forKey:4U]);
XCTAssertEqual(value, 601.);
const uint32_t kKeys2[] = { 2U, 3U };
const double kValues2[] = { 602., 600. };
GPBUInt32DoubleDictionary *dict2 =
- [[GPBUInt32DoubleDictionary alloc] initWithValues:kValues2
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBUInt32DoubleDictionary alloc] initWithDoubles:kValues2
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:1U]);
+ XCTAssertTrue([dict getDouble:&value forKey:1U]);
XCTAssertEqual(value, 603.);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:2U]);
+ XCTAssertTrue([dict getDouble:&value forKey:2U]);
XCTAssertEqual(value, 602.);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:3U]);
+ XCTAssertTrue([dict getDouble:&value forKey:3U]);
XCTAssertEqual(value, 600.);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:4U]);
+ XCTAssertTrue([dict getDouble:&value forKey:4U]);
XCTAssertEqual(value, 601.);
[dict2 release];
@@ -2593,8 +2593,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
GPBUInt32EnumDictionary *dict = [[GPBUInt32EnumDictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:1U value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(uint32_t aKey, int32_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getEnum:NULL forKey:1U]);
+ [dict enumerateKeysAndEnumsUsingBlock:^(uint32_t aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -2602,15 +2602,15 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testOne {
- GPBUInt32EnumDictionary *dict = [GPBUInt32EnumDictionary dictionaryWithValue:700 forKey:1U];
+ GPBUInt32EnumDictionary *dict = [GPBUInt32EnumDictionary dictionaryWithEnum:700 forKey:1U];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
int32_t value;
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:1U]);
+ XCTAssertTrue([dict getEnum:&value forKey:1U]);
XCTAssertEqual(value, 700);
- XCTAssertFalse([dict valueForKey:2U value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(uint32_t aKey, int32_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getEnum:NULL forKey:2U]);
+ [dict enumerateKeysAndEnumsUsingBlock:^(uint32_t aKey, int32_t aValue, BOOL *stop) {
XCTAssertEqual(aKey, 1U);
XCTAssertEqual(aValue, 700);
XCTAssertNotEqual(stop, NULL);
@@ -2621,27 +2621,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint32_t kKeys[] = { 1U, 2U, 3U };
const int32_t kValues[] = { 700, 701, 702 };
GPBUInt32EnumDictionary *dict =
- [[GPBUInt32EnumDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt32EnumDictionary alloc] initWithEnums:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 3U);
int32_t value;
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:1U]);
+ XCTAssertTrue([dict getEnum:&value forKey:1U]);
XCTAssertEqual(value, 700);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:2U]);
+ XCTAssertTrue([dict getEnum:&value forKey:2U]);
XCTAssertEqual(value, 701);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:3U]);
+ XCTAssertTrue([dict getEnum:&value forKey:3U]);
XCTAssertEqual(value, 702);
- XCTAssertFalse([dict valueForKey:4U value:NULL]);
+ XCTAssertFalse([dict getEnum:NULL forKey:4U]);
__block NSUInteger idx = 0;
uint32_t *seenKeys = malloc(3 * sizeof(uint32_t));
int32_t *seenValues = malloc(3 * sizeof(int32_t));
- [dict enumerateKeysAndValuesUsingBlock:^(uint32_t aKey, int32_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndEnumsUsingBlock:^(uint32_t aKey, int32_t aValue, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -2663,7 +2663,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(uint32_t aKey, int32_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndEnumsUsingBlock:^(uint32_t aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -2679,29 +2679,29 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kValues2[] = { 700, 703, 702 };
const int32_t kValues3[] = { 700, 701, 702, 703 };
GPBUInt32EnumDictionary *dict1 =
- [[GPBUInt32EnumDictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBUInt32EnumDictionary alloc] initWithEnums:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBUInt32EnumDictionary *dict1prime =
- [[GPBUInt32EnumDictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBUInt32EnumDictionary alloc] initWithEnums:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBUInt32EnumDictionary *dict2 =
- [[GPBUInt32EnumDictionary alloc] initWithValues:kValues2
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBUInt32EnumDictionary alloc] initWithEnums:kValues2
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBUInt32EnumDictionary *dict3 =
- [[GPBUInt32EnumDictionary alloc] initWithValues:kValues1
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBUInt32EnumDictionary alloc] initWithEnums:kValues1
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBUInt32EnumDictionary *dict4 =
- [[GPBUInt32EnumDictionary alloc] initWithValues:kValues3
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues3)];
+ [[GPBUInt32EnumDictionary alloc] initWithEnums:kValues3
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
// 1/1Prime should be different objects, but equal.
@@ -2730,9 +2730,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint32_t kKeys[] = { 1U, 2U, 3U, 4U };
const int32_t kValues[] = { 700, 701, 702, 703 };
GPBUInt32EnumDictionary *dict =
- [[GPBUInt32EnumDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt32EnumDictionary alloc] initWithEnums:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBUInt32EnumDictionary *dict2 = [dict copy];
@@ -2751,9 +2751,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint32_t kKeys[] = { 1U, 2U, 3U, 4U };
const int32_t kValues[] = { 700, 701, 702, 703 };
GPBUInt32EnumDictionary *dict =
- [[GPBUInt32EnumDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt32EnumDictionary alloc] initWithEnums:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBUInt32EnumDictionary *dict2 =
@@ -2771,31 +2771,31 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:700 forKey:1U];
+ [dict setEnum:700 forKey:1U];
XCTAssertEqual(dict.count, 1U);
const uint32_t kKeys[] = { 2U, 3U, 4U };
const int32_t kValues[] = { 701, 702, 703 };
GPBUInt32EnumDictionary *dict2 =
- [[GPBUInt32EnumDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt32EnumDictionary alloc] initWithEnums:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
[dict addRawEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
int32_t value;
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:1U]);
+ XCTAssertTrue([dict getEnum:&value forKey:1U]);
XCTAssertEqual(value, 700);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:2U]);
+ XCTAssertTrue([dict getEnum:&value forKey:2U]);
XCTAssertEqual(value, 701);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:3U]);
+ XCTAssertTrue([dict getEnum:&value forKey:3U]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:4U]);
+ XCTAssertTrue([dict getEnum:&value forKey:4U]);
XCTAssertEqual(value, 703);
[dict2 release];
}
@@ -2804,57 +2804,57 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint32_t kKeys[] = { 1U, 2U, 3U, 4U };
const int32_t kValues[] = { 700, 701, 702, 703 };
GPBUInt32EnumDictionary *dict =
- [[GPBUInt32EnumDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt32EnumDictionary alloc] initWithEnums:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
- [dict removeValueForKey:2U];
+ [dict removeEnumForKey:2U];
XCTAssertEqual(dict.count, 3U);
int32_t value;
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:1U]);
+ XCTAssertTrue([dict getEnum:&value forKey:1U]);
XCTAssertEqual(value, 700);
- XCTAssertFalse([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertFalse([dict getEnum:NULL forKey:2U]);
+ XCTAssertTrue([dict getEnum:NULL forKey:3U]);
+ XCTAssertTrue([dict getEnum:&value forKey:3U]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:4U]);
+ XCTAssertTrue([dict getEnum:&value forKey:4U]);
XCTAssertEqual(value, 703);
// Remove again does nothing.
- [dict removeValueForKey:2U];
+ [dict removeEnumForKey:2U];
XCTAssertEqual(dict.count, 3U);
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:1U]);
+ XCTAssertTrue([dict getEnum:&value forKey:1U]);
XCTAssertEqual(value, 700);
- XCTAssertFalse([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertFalse([dict getEnum:NULL forKey:2U]);
+ XCTAssertTrue([dict getEnum:NULL forKey:3U]);
+ XCTAssertTrue([dict getEnum:&value forKey:3U]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:4U]);
+ XCTAssertTrue([dict getEnum:&value forKey:4U]);
XCTAssertEqual(value, 703);
- [dict removeValueForKey:4U];
+ [dict removeEnumForKey:4U];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:1U]);
+ XCTAssertTrue([dict getEnum:&value forKey:1U]);
XCTAssertEqual(value, 700);
- XCTAssertFalse([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertFalse([dict getEnum:NULL forKey:2U]);
+ XCTAssertTrue([dict getEnum:NULL forKey:3U]);
+ XCTAssertTrue([dict getEnum:&value forKey:3U]);
XCTAssertEqual(value, 702);
- XCTAssertFalse([dict valueForKey:4U value:NULL]);
+ XCTAssertFalse([dict getEnum:NULL forKey:4U]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:1U value:NULL]);
- XCTAssertFalse([dict valueForKey:2U value:NULL]);
- XCTAssertFalse([dict valueForKey:3U value:NULL]);
- XCTAssertFalse([dict valueForKey:4U value:NULL]);
+ XCTAssertFalse([dict getEnum:NULL forKey:1U]);
+ XCTAssertFalse([dict getEnum:NULL forKey:2U]);
+ XCTAssertFalse([dict getEnum:NULL forKey:3U]);
+ XCTAssertFalse([dict getEnum:NULL forKey:4U]);
[dict release];
}
@@ -2862,75 +2862,75 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint32_t kKeys[] = { 1U, 2U, 3U, 4U };
const int32_t kValues[] = { 700, 701, 702, 703 };
GPBUInt32EnumDictionary *dict =
- [[GPBUInt32EnumDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt32EnumDictionary alloc] initWithEnums:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
int32_t value;
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:1U]);
+ XCTAssertTrue([dict getEnum:&value forKey:1U]);
XCTAssertEqual(value, 700);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:2U]);
+ XCTAssertTrue([dict getEnum:&value forKey:2U]);
XCTAssertEqual(value, 701);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:3U]);
+ XCTAssertTrue([dict getEnum:&value forKey:3U]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:4U]);
+ XCTAssertTrue([dict getEnum:&value forKey:4U]);
XCTAssertEqual(value, 703);
- [dict setValue:703 forKey:1U];
+ [dict setEnum:703 forKey:1U];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:1U]);
+ XCTAssertTrue([dict getEnum:&value forKey:1U]);
XCTAssertEqual(value, 703);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:2U]);
+ XCTAssertTrue([dict getEnum:&value forKey:2U]);
XCTAssertEqual(value, 701);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:3U]);
+ XCTAssertTrue([dict getEnum:&value forKey:3U]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:4U]);
+ XCTAssertTrue([dict getEnum:&value forKey:4U]);
XCTAssertEqual(value, 703);
- [dict setValue:701 forKey:4U];
+ [dict setEnum:701 forKey:4U];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:1U]);
+ XCTAssertTrue([dict getEnum:&value forKey:1U]);
XCTAssertEqual(value, 703);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:2U]);
+ XCTAssertTrue([dict getEnum:&value forKey:2U]);
XCTAssertEqual(value, 701);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:3U]);
+ XCTAssertTrue([dict getEnum:&value forKey:3U]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:4U]);
+ XCTAssertTrue([dict getEnum:&value forKey:4U]);
XCTAssertEqual(value, 701);
const uint32_t kKeys2[] = { 2U, 3U };
const int32_t kValues2[] = { 702, 700 };
GPBUInt32EnumDictionary *dict2 =
- [[GPBUInt32EnumDictionary alloc] initWithValues:kValues2
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBUInt32EnumDictionary alloc] initWithEnums:kValues2
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addRawEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:1U]);
+ XCTAssertTrue([dict getEnum:&value forKey:1U]);
XCTAssertEqual(value, 703);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:2U]);
+ XCTAssertTrue([dict getEnum:&value forKey:2U]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:3U]);
+ XCTAssertTrue([dict getEnum:&value forKey:3U]);
XCTAssertEqual(value, 700);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:4U]);
+ XCTAssertTrue([dict getEnum:&value forKey:4U]);
XCTAssertEqual(value, 701);
[dict2 release];
@@ -2958,24 +2958,24 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertEqual(dict.count, 3U);
XCTAssertTrue(dict.validationFunc == TestingEnum_IsValidValue); // Pointer comparison
int32_t value;
- XCTAssertTrue([dict valueForKey:1U rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:1U rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:1U]);
+ XCTAssertTrue([dict getRawValue:&value forKey:1U]);
XCTAssertEqual(value, 700);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:2U]);
+ XCTAssertTrue([dict getEnum:&value forKey:2U]);
XCTAssertEqual(value, kGPBUnrecognizedEnumeratorValue);
- XCTAssertTrue([dict valueForKey:2U rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:2U rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:2U]);
+ XCTAssertTrue([dict getRawValue:&value forKey:2U]);
XCTAssertEqual(value, 801);
- XCTAssertTrue([dict valueForKey:3U rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:3U rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:3U]);
+ XCTAssertTrue([dict getRawValue:&value forKey:3U]);
XCTAssertEqual(value, 702);
- XCTAssertFalse([dict valueForKey:4U rawValue:NULL]);
+ XCTAssertFalse([dict getRawValue:NULL forKey:4U]);
__block NSUInteger idx = 0;
uint32_t *seenKeys = malloc(3 * sizeof(uint32_t));
int32_t *seenValues = malloc(3 * sizeof(int32_t));
- [dict enumerateKeysAndValuesUsingBlock:^(uint32_t aKey, int32_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndEnumsUsingBlock:^(uint32_t aKey, int32_t aValue, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -3136,7 +3136,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertThrowsSpecificNamed([dict setValue:801 forKey:2U], // Unknown
+ XCTAssertThrowsSpecificNamed([dict setEnum:801 forKey:2U], // Unknown
NSException, NSInvalidArgumentException);
XCTAssertEqual(dict.count, 0U);
[dict setRawValue:801 forKey:2U]; // Unknown
@@ -3145,31 +3145,31 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint32_t kKeys[] = { 1U, 3U, 4U };
const int32_t kValues[] = { 700, 702, 803 }; // Unknown
GPBUInt32EnumDictionary *dict2 =
- [[GPBUInt32EnumDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt32EnumDictionary alloc] initWithEnums:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
[dict addRawEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
int32_t value;
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:1U]);
+ XCTAssertTrue([dict getEnum:&value forKey:1U]);
XCTAssertEqual(value, 700);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:2U]);
+ XCTAssertTrue([dict getEnum:&value forKey:2U]);
XCTAssertEqual(value, kGPBUnrecognizedEnumeratorValue);
- XCTAssertTrue([dict valueForKey:2U rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:2U rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:2U]);
+ XCTAssertTrue([dict getRawValue:&value forKey:2U]);
XCTAssertEqual(value, 801);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:3U]);
+ XCTAssertTrue([dict getEnum:&value forKey:3U]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:4U]);
+ XCTAssertTrue([dict getEnum:&value forKey:4U]);
XCTAssertEqual(value, kGPBUnrecognizedEnumeratorValue);
- XCTAssertTrue([dict valueForKey:4U rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:4U rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:4U]);
+ XCTAssertTrue([dict getRawValue:&value forKey:4U]);
XCTAssertEqual(value, 803);
[dict2 release];
}
@@ -3185,51 +3185,51 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
- [dict removeValueForKey:2U];
+ [dict removeEnumForKey:2U];
XCTAssertEqual(dict.count, 3U);
int32_t value;
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:1U]);
+ XCTAssertTrue([dict getEnum:&value forKey:1U]);
XCTAssertEqual(value, 700);
- XCTAssertFalse([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertFalse([dict getEnum:NULL forKey:2U]);
+ XCTAssertTrue([dict getEnum:NULL forKey:3U]);
+ XCTAssertTrue([dict getEnum:&value forKey:3U]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:4U rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:4U rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:4U]);
+ XCTAssertTrue([dict getRawValue:&value forKey:4U]);
XCTAssertEqual(value, 803);
// Remove again does nothing.
- [dict removeValueForKey:2U];
+ [dict removeEnumForKey:2U];
XCTAssertEqual(dict.count, 3U);
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:1U]);
+ XCTAssertTrue([dict getEnum:&value forKey:1U]);
XCTAssertEqual(value, 700);
- XCTAssertFalse([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertFalse([dict getEnum:NULL forKey:2U]);
+ XCTAssertTrue([dict getEnum:NULL forKey:3U]);
+ XCTAssertTrue([dict getEnum:&value forKey:3U]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:4U rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:4U rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:4U]);
+ XCTAssertTrue([dict getRawValue:&value forKey:4U]);
XCTAssertEqual(value, 803);
- [dict removeValueForKey:4U];
+ [dict removeEnumForKey:4U];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:1U]);
+ XCTAssertTrue([dict getEnum:&value forKey:1U]);
XCTAssertEqual(value, 700);
- XCTAssertFalse([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertFalse([dict getEnum:NULL forKey:2U]);
+ XCTAssertTrue([dict getEnum:NULL forKey:3U]);
+ XCTAssertTrue([dict getEnum:&value forKey:3U]);
XCTAssertEqual(value, 702);
- XCTAssertFalse([dict valueForKey:4U value:NULL]);
+ XCTAssertFalse([dict getEnum:NULL forKey:4U]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:1U value:NULL]);
- XCTAssertFalse([dict valueForKey:2U value:NULL]);
- XCTAssertFalse([dict valueForKey:3U value:NULL]);
- XCTAssertFalse([dict valueForKey:4U value:NULL]);
+ XCTAssertFalse([dict getEnum:NULL forKey:1U]);
+ XCTAssertFalse([dict getEnum:NULL forKey:2U]);
+ XCTAssertFalse([dict getEnum:NULL forKey:3U]);
+ XCTAssertFalse([dict getEnum:NULL forKey:4U]);
[dict release];
}
@@ -3244,63 +3244,63 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
int32_t value;
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:1U]);
+ XCTAssertTrue([dict getEnum:&value forKey:1U]);
XCTAssertEqual(value, 700);
- XCTAssertTrue([dict valueForKey:2U rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:2U rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:2U]);
+ XCTAssertTrue([dict getRawValue:&value forKey:2U]);
XCTAssertEqual(value, 801);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:3U]);
+ XCTAssertTrue([dict getEnum:&value forKey:3U]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:4U rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:4U rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:4U]);
+ XCTAssertTrue([dict getRawValue:&value forKey:4U]);
XCTAssertEqual(value, 803);
- XCTAssertThrowsSpecificNamed([dict setValue:803 forKey:1U], // Unknown
+ XCTAssertThrowsSpecificNamed([dict setEnum:803 forKey:1U], // Unknown
NSException, NSInvalidArgumentException);
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:1U value:NULL]);
- XCTAssertTrue([dict valueForKey:1U value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:1U]);
+ XCTAssertTrue([dict getEnum:&value forKey:1U]);
XCTAssertEqual(value, 700);
- XCTAssertTrue([dict valueForKey:2U rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:2U rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:2U]);
+ XCTAssertTrue([dict getRawValue:&value forKey:2U]);
XCTAssertEqual(value, 801);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:3U]);
+ XCTAssertTrue([dict getEnum:&value forKey:3U]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:4U rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:4U rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:4U]);
+ XCTAssertTrue([dict getRawValue:&value forKey:4U]);
XCTAssertEqual(value, 803);
[dict setRawValue:803 forKey:1U]; // Unknown
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:1U rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:1U rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:1U]);
+ XCTAssertTrue([dict getRawValue:&value forKey:1U]);
XCTAssertEqual(value, 803);
- XCTAssertTrue([dict valueForKey:2U rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:2U rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:2U]);
+ XCTAssertTrue([dict getRawValue:&value forKey:2U]);
XCTAssertEqual(value, 801);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:3U]);
+ XCTAssertTrue([dict getEnum:&value forKey:3U]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:4U rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:4U rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:4U]);
+ XCTAssertTrue([dict getRawValue:&value forKey:4U]);
XCTAssertEqual(value, 803);
[dict setRawValue:700 forKey:4U];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:1U rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:1U rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:1U]);
+ XCTAssertTrue([dict getRawValue:&value forKey:1U]);
XCTAssertEqual(value, 803);
- XCTAssertTrue([dict valueForKey:2U rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:2U rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:2U]);
+ XCTAssertTrue([dict getRawValue:&value forKey:2U]);
XCTAssertEqual(value, 801);
- XCTAssertTrue([dict valueForKey:3U value:NULL]);
- XCTAssertTrue([dict valueForKey:3U value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:3U]);
+ XCTAssertTrue([dict getEnum:&value forKey:3U]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:4U]);
+ XCTAssertTrue([dict getEnum:&value forKey:4U]);
XCTAssertEqual(value, 700);
const uint32_t kKeys2[] = { 2U, 3U };
@@ -3313,17 +3313,17 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict2);
[dict addRawEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:1U rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:1U rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:1U]);
+ XCTAssertTrue([dict getRawValue:&value forKey:1U]);
XCTAssertEqual(value, 803);
- XCTAssertTrue([dict valueForKey:2U value:NULL]);
- XCTAssertTrue([dict valueForKey:2U value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:2U]);
+ XCTAssertTrue([dict getEnum:&value forKey:2U]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:3U rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:3U rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:3U]);
+ XCTAssertTrue([dict getRawValue:&value forKey:3U]);
XCTAssertEqual(value, 801);
- XCTAssertTrue([dict valueForKey:4U value:NULL]);
- XCTAssertTrue([dict valueForKey:4U value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:4U]);
+ XCTAssertTrue([dict getEnum:&value forKey:4U]);
XCTAssertEqual(value, 700);
[dict2 release];
@@ -3363,11 +3363,11 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
@implementation GPBUInt32ObjectDictionaryTests
- (void)testEmpty {
- GPBUInt32ObjectDictionary *dict = [[GPBUInt32ObjectDictionary alloc] init];
+ GPBUInt32ObjectDictionary<NSString*> *dict = [[GPBUInt32ObjectDictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertNil([dict objectForKey:1U]);
- [dict enumerateKeysAndObjectsUsingBlock:^(uint32_t aKey, id aObject, BOOL *stop) {
+ [dict enumerateKeysAndObjectsUsingBlock:^(uint32_t aKey, NSString* aObject, BOOL *stop) {
#pragma unused(aKey, aObject, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -3375,12 +3375,12 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testOne {
- GPBUInt32ObjectDictionary *dict = [GPBUInt32ObjectDictionary dictionaryWithObject:@"abc" forKey:1U];
+ GPBUInt32ObjectDictionary<NSString*> *dict = [GPBUInt32ObjectDictionary dictionaryWithObject:@"abc" forKey:1U];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
XCTAssertEqualObjects([dict objectForKey:1U], @"abc");
XCTAssertNil([dict objectForKey:2U]);
- [dict enumerateKeysAndObjectsUsingBlock:^(uint32_t aKey, id aObject, BOOL *stop) {
+ [dict enumerateKeysAndObjectsUsingBlock:^(uint32_t aKey, NSString* aObject, BOOL *stop) {
XCTAssertEqual(aKey, 1U);
XCTAssertEqualObjects(aObject, @"abc");
XCTAssertNotEqual(stop, NULL);
@@ -3389,8 +3389,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
- (void)testBasics {
const uint32_t kKeys[] = { 1U, 2U, 3U };
- const id kObjects[] = { @"abc", @"def", @"ghi" };
- GPBUInt32ObjectDictionary *dict =
+ const NSString* kObjects[] = { @"abc", @"def", @"ghi" };
+ GPBUInt32ObjectDictionary<NSString*> *dict =
[[GPBUInt32ObjectDictionary alloc] initWithObjects:kObjects
forKeys:kKeys
count:GPBARRAYSIZE(kObjects)];
@@ -3403,8 +3403,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
__block NSUInteger idx = 0;
uint32_t *seenKeys = malloc(3 * sizeof(uint32_t));
- id *seenObjects = malloc(3 * sizeof(id));
- [dict enumerateKeysAndObjectsUsingBlock:^(uint32_t aKey, id aObject, BOOL *stop) {
+ NSString* *seenObjects = malloc(3 * sizeof(NSString*));
+ [dict enumerateKeysAndObjectsUsingBlock:^(uint32_t aKey, NSString* aObject, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenObjects[idx] = aObject;
@@ -3426,7 +3426,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndObjectsUsingBlock:^(uint32_t aKey, id aObject, BOOL *stop) {
+ [dict enumerateKeysAndObjectsUsingBlock:^(uint32_t aKey, NSString* aObject, BOOL *stop) {
#pragma unused(aKey, aObject)
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -3438,30 +3438,30 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
- (void)testEquality {
const uint32_t kKeys1[] = { 1U, 2U, 3U, 4U };
const uint32_t kKeys2[] = { 2U, 1U, 4U };
- const id kObjects1[] = { @"abc", @"def", @"ghi" };
- const id kObjects2[] = { @"abc", @"jkl", @"ghi" };
- const id kObjects3[] = { @"abc", @"def", @"ghi", @"jkl" };
- GPBUInt32ObjectDictionary *dict1 =
+ const NSString* kObjects1[] = { @"abc", @"def", @"ghi" };
+ const NSString* kObjects2[] = { @"abc", @"jkl", @"ghi" };
+ const NSString* kObjects3[] = { @"abc", @"def", @"ghi", @"jkl" };
+ GPBUInt32ObjectDictionary<NSString*> *dict1 =
[[GPBUInt32ObjectDictionary alloc] initWithObjects:kObjects1
forKeys:kKeys1
count:GPBARRAYSIZE(kObjects1)];
XCTAssertNotNil(dict1);
- GPBUInt32ObjectDictionary *dict1prime =
+ GPBUInt32ObjectDictionary<NSString*> *dict1prime =
[[GPBUInt32ObjectDictionary alloc] initWithObjects:kObjects1
forKeys:kKeys1
count:GPBARRAYSIZE(kObjects1)];
XCTAssertNotNil(dict1prime);
- GPBUInt32ObjectDictionary *dict2 =
+ GPBUInt32ObjectDictionary<NSString*> *dict2 =
[[GPBUInt32ObjectDictionary alloc] initWithObjects:kObjects2
forKeys:kKeys1
count:GPBARRAYSIZE(kObjects2)];
XCTAssertNotNil(dict2);
- GPBUInt32ObjectDictionary *dict3 =
+ GPBUInt32ObjectDictionary<NSString*> *dict3 =
[[GPBUInt32ObjectDictionary alloc] initWithObjects:kObjects1
forKeys:kKeys2
count:GPBARRAYSIZE(kObjects1)];
XCTAssertNotNil(dict3);
- GPBUInt32ObjectDictionary *dict4 =
+ GPBUInt32ObjectDictionary<NSString*> *dict4 =
[[GPBUInt32ObjectDictionary alloc] initWithObjects:kObjects3
forKeys:kKeys1
count:GPBARRAYSIZE(kObjects3)];
@@ -3491,14 +3491,14 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
- (void)testCopy {
const uint32_t kKeys[] = { 1U, 2U, 3U, 4U };
- const id kObjects[] = { @"abc", @"def", @"ghi", @"jkl" };
- GPBUInt32ObjectDictionary *dict =
+ const NSString* kObjects[] = { @"abc", @"def", @"ghi", @"jkl" };
+ GPBUInt32ObjectDictionary<NSString*> *dict =
[[GPBUInt32ObjectDictionary alloc] initWithObjects:kObjects
forKeys:kKeys
count:GPBARRAYSIZE(kObjects)];
XCTAssertNotNil(dict);
- GPBUInt32ObjectDictionary *dict2 = [dict copy];
+ GPBUInt32ObjectDictionary<NSString*> *dict2 = [dict copy];
XCTAssertNotNil(dict2);
// Should be new object but equal.
@@ -3512,14 +3512,14 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
- (void)testDictionaryFromDictionary {
const uint32_t kKeys[] = { 1U, 2U, 3U, 4U };
- const id kObjects[] = { @"abc", @"def", @"ghi", @"jkl" };
- GPBUInt32ObjectDictionary *dict =
+ const NSString* kObjects[] = { @"abc", @"def", @"ghi", @"jkl" };
+ GPBUInt32ObjectDictionary<NSString*> *dict =
[[GPBUInt32ObjectDictionary alloc] initWithObjects:kObjects
forKeys:kKeys
count:GPBARRAYSIZE(kObjects)];
XCTAssertNotNil(dict);
- GPBUInt32ObjectDictionary *dict2 =
+ GPBUInt32ObjectDictionary<NSString*> *dict2 =
[GPBUInt32ObjectDictionary dictionaryWithDictionary:dict];
XCTAssertNotNil(dict2);
@@ -3530,7 +3530,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testAdds {
- GPBUInt32ObjectDictionary *dict = [GPBUInt32ObjectDictionary dictionary];
+ GPBUInt32ObjectDictionary<NSString*> *dict = [GPBUInt32ObjectDictionary dictionary];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
@@ -3538,8 +3538,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertEqual(dict.count, 1U);
const uint32_t kKeys[] = { 2U, 3U, 4U };
- const id kObjects[] = { @"def", @"ghi", @"jkl" };
- GPBUInt32ObjectDictionary *dict2 =
+ const NSString* kObjects[] = { @"def", @"ghi", @"jkl" };
+ GPBUInt32ObjectDictionary<NSString*> *dict2 =
[[GPBUInt32ObjectDictionary alloc] initWithObjects:kObjects
forKeys:kKeys
count:GPBARRAYSIZE(kObjects)];
@@ -3556,11 +3556,11 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
- (void)testRemove {
const uint32_t kKeys[] = { 1U, 2U, 3U, 4U };
- const id kObjects[] = { @"abc", @"def", @"ghi", @"jkl" };
- GPBUInt32ObjectDictionary *dict =
+ const NSString* kObjects[] = { @"abc", @"def", @"ghi", @"jkl" };
+ GPBUInt32ObjectDictionary<NSString*> *dict =
[[GPBUInt32ObjectDictionary alloc] initWithObjects:kObjects
- forKeys:kKeys
- count:GPBARRAYSIZE(kObjects)];
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kObjects)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
@@ -3597,11 +3597,11 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
- (void)testInplaceMutation {
const uint32_t kKeys[] = { 1U, 2U, 3U, 4U };
- const id kObjects[] = { @"abc", @"def", @"ghi", @"jkl" };
- GPBUInt32ObjectDictionary *dict =
+ const NSString* kObjects[] = { @"abc", @"def", @"ghi", @"jkl" };
+ GPBUInt32ObjectDictionary<NSString*> *dict =
[[GPBUInt32ObjectDictionary alloc] initWithObjects:kObjects
- forKeys:kKeys
- count:GPBARRAYSIZE(kObjects)];
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kObjects)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
XCTAssertEqualObjects([dict objectForKey:1U], @"abc");
@@ -3624,8 +3624,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertEqualObjects([dict objectForKey:4U], @"def");
const uint32_t kKeys2[] = { 2U, 3U };
- const id kObjects2[] = { @"ghi", @"abc" };
- GPBUInt32ObjectDictionary *dict2 =
+ const NSString* kObjects2[] = { @"ghi", @"abc" };
+ GPBUInt32ObjectDictionary<NSString*> *dict2 =
[[GPBUInt32ObjectDictionary alloc] initWithObjects:kObjects2
forKeys:kKeys2
count:GPBARRAYSIZE(kObjects2)];
diff --git a/objectivec/Tests/GPBDictionaryTests+UInt64.m b/objectivec/Tests/GPBDictionaryTests+UInt64.m
index b64d3a96..94c116f6 100644
--- a/objectivec/Tests/GPBDictionaryTests+UInt64.m
+++ b/objectivec/Tests/GPBDictionaryTests+UInt64.m
@@ -45,10 +45,10 @@
// To let the testing macros work, add some extra methods to simplify things.
@interface GPBUInt64EnumDictionary (TestingTweak)
-+ (instancetype)dictionaryWithValue:(int32_t)value forKey:(uint64_t)key;
-- (instancetype)initWithValues:(const int32_t [])values
- forKeys:(const uint64_t [])keys
- count:(NSUInteger)count;
++ (instancetype)dictionaryWithEnum:(int32_t)value forKey:(uint64_t)key;
+- (instancetype)initWithEnums:(const int32_t [])values
+ forKeys:(const uint64_t [])keys
+ count:(NSUInteger)count;
@end
static BOOL TestingEnum_IsValidValue(int32_t value) {
@@ -64,7 +64,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
@implementation GPBUInt64EnumDictionary (TestingTweak)
-+ (instancetype)dictionaryWithValue:(int32_t)value forKey:(uint64_t)key {
++ (instancetype)dictionaryWithEnum:(int32_t)value forKey:(uint64_t)key {
// Cast is needed to compiler knows what class we are invoking initWithValues: on to get the
// type correct.
return [[(GPBUInt64EnumDictionary*)[self alloc] initWithValidationFunction:TestingEnum_IsValidValue
@@ -72,9 +72,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
forKeys:&key
count:1] autorelease];
}
-- (instancetype)initWithValues:(const int32_t [])values
- forKeys:(const uint64_t [])keys
- count:(NSUInteger)count {
+- (instancetype)initWithEnums:(const int32_t [])values
+ forKeys:(const uint64_t [])keys
+ count:(NSUInteger)count {
return [self initWithValidationFunction:TestingEnum_IsValidValue
rawValues:values
forKeys:keys
@@ -94,8 +94,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
GPBUInt64UInt32Dictionary *dict = [[GPBUInt64UInt32Dictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:31ULL value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(uint64_t aKey, uint32_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getUInt32:NULL forKey:31ULL]);
+ [dict enumerateKeysAndUInt32sUsingBlock:^(uint64_t aKey, uint32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -103,15 +103,15 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testOne {
- GPBUInt64UInt32Dictionary *dict = [GPBUInt64UInt32Dictionary dictionaryWithValue:100U forKey:31ULL];
+ GPBUInt64UInt32Dictionary *dict = [GPBUInt64UInt32Dictionary dictionaryWithUInt32:100U forKey:31ULL];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
uint32_t value;
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:31ULL]);
XCTAssertEqual(value, 100U);
- XCTAssertFalse([dict valueForKey:32ULL value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(uint64_t aKey, uint32_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getUInt32:NULL forKey:32ULL]);
+ [dict enumerateKeysAndUInt32sUsingBlock:^(uint64_t aKey, uint32_t aValue, BOOL *stop) {
XCTAssertEqual(aKey, 31ULL);
XCTAssertEqual(aValue, 100U);
XCTAssertNotEqual(stop, NULL);
@@ -122,27 +122,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL };
const uint32_t kValues[] = { 100U, 101U, 102U };
GPBUInt64UInt32Dictionary *dict =
- [[GPBUInt64UInt32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt64UInt32Dictionary alloc] initWithUInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 3U);
uint32_t value;
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:31ULL]);
XCTAssertEqual(value, 100U);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:32ULL]);
XCTAssertEqual(value, 101U);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:33ULL]);
XCTAssertEqual(value, 102U);
- XCTAssertFalse([dict valueForKey:34ULL value:NULL]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:34ULL]);
__block NSUInteger idx = 0;
uint64_t *seenKeys = malloc(3 * sizeof(uint64_t));
uint32_t *seenValues = malloc(3 * sizeof(uint32_t));
- [dict enumerateKeysAndValuesUsingBlock:^(uint64_t aKey, uint32_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndUInt32sUsingBlock:^(uint64_t aKey, uint32_t aValue, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -164,7 +164,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(uint64_t aKey, uint32_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndUInt32sUsingBlock:^(uint64_t aKey, uint32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -180,29 +180,29 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint32_t kValues2[] = { 100U, 103U, 102U };
const uint32_t kValues3[] = { 100U, 101U, 102U, 103U };
GPBUInt64UInt32Dictionary *dict1 =
- [[GPBUInt64UInt32Dictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBUInt64UInt32Dictionary alloc] initWithUInt32s:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBUInt64UInt32Dictionary *dict1prime =
- [[GPBUInt64UInt32Dictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBUInt64UInt32Dictionary alloc] initWithUInt32s:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBUInt64UInt32Dictionary *dict2 =
- [[GPBUInt64UInt32Dictionary alloc] initWithValues:kValues2
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBUInt64UInt32Dictionary alloc] initWithUInt32s:kValues2
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBUInt64UInt32Dictionary *dict3 =
- [[GPBUInt64UInt32Dictionary alloc] initWithValues:kValues1
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBUInt64UInt32Dictionary alloc] initWithUInt32s:kValues1
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBUInt64UInt32Dictionary *dict4 =
- [[GPBUInt64UInt32Dictionary alloc] initWithValues:kValues3
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues3)];
+ [[GPBUInt64UInt32Dictionary alloc] initWithUInt32s:kValues3
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
// 1/1Prime should be different objects, but equal.
@@ -231,9 +231,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
const uint32_t kValues[] = { 100U, 101U, 102U, 103U };
GPBUInt64UInt32Dictionary *dict =
- [[GPBUInt64UInt32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt64UInt32Dictionary alloc] initWithUInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBUInt64UInt32Dictionary *dict2 = [dict copy];
@@ -252,9 +252,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
const uint32_t kValues[] = { 100U, 101U, 102U, 103U };
GPBUInt64UInt32Dictionary *dict =
- [[GPBUInt64UInt32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt64UInt32Dictionary alloc] initWithUInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBUInt64UInt32Dictionary *dict2 =
@@ -272,31 +272,31 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:100U forKey:31ULL];
+ [dict setUInt32:100U forKey:31ULL];
XCTAssertEqual(dict.count, 1U);
const uint64_t kKeys[] = { 32ULL, 33ULL, 34ULL };
const uint32_t kValues[] = { 101U, 102U, 103U };
GPBUInt64UInt32Dictionary *dict2 =
- [[GPBUInt64UInt32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt64UInt32Dictionary alloc] initWithUInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
uint32_t value;
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:31ULL]);
XCTAssertEqual(value, 100U);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:32ULL]);
XCTAssertEqual(value, 101U);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:33ULL]);
XCTAssertEqual(value, 102U);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:34ULL]);
XCTAssertEqual(value, 103U);
[dict2 release];
}
@@ -305,57 +305,57 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
const uint32_t kValues[] = { 100U, 101U, 102U, 103U };
GPBUInt64UInt32Dictionary *dict =
- [[GPBUInt64UInt32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt64UInt32Dictionary alloc] initWithUInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
- [dict removeValueForKey:32ULL];
+ [dict removeUInt32ForKey:32ULL];
XCTAssertEqual(dict.count, 3U);
uint32_t value;
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:31ULL]);
XCTAssertEqual(value, 100U);
- XCTAssertFalse([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:33ULL]);
XCTAssertEqual(value, 102U);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:34ULL]);
XCTAssertEqual(value, 103U);
// Remove again does nothing.
- [dict removeValueForKey:32ULL];
+ [dict removeUInt32ForKey:32ULL];
XCTAssertEqual(dict.count, 3U);
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:31ULL]);
XCTAssertEqual(value, 100U);
- XCTAssertFalse([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:33ULL]);
XCTAssertEqual(value, 102U);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:34ULL]);
XCTAssertEqual(value, 103U);
- [dict removeValueForKey:34ULL];
+ [dict removeUInt32ForKey:34ULL];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:31ULL]);
XCTAssertEqual(value, 100U);
- XCTAssertFalse([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:33ULL]);
XCTAssertEqual(value, 102U);
- XCTAssertFalse([dict valueForKey:34ULL value:NULL]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:34ULL]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:31ULL value:NULL]);
- XCTAssertFalse([dict valueForKey:32ULL value:NULL]);
- XCTAssertFalse([dict valueForKey:33ULL value:NULL]);
- XCTAssertFalse([dict valueForKey:34ULL value:NULL]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:31ULL]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:32ULL]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:33ULL]);
+ XCTAssertFalse([dict getUInt32:NULL forKey:34ULL]);
[dict release];
}
@@ -363,75 +363,75 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
const uint32_t kValues[] = { 100U, 101U, 102U, 103U };
GPBUInt64UInt32Dictionary *dict =
- [[GPBUInt64UInt32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt64UInt32Dictionary alloc] initWithUInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
uint32_t value;
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:31ULL]);
XCTAssertEqual(value, 100U);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:32ULL]);
XCTAssertEqual(value, 101U);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:33ULL]);
XCTAssertEqual(value, 102U);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:34ULL]);
XCTAssertEqual(value, 103U);
- [dict setValue:103U forKey:31ULL];
+ [dict setUInt32:103U forKey:31ULL];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:31ULL]);
XCTAssertEqual(value, 103U);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:32ULL]);
XCTAssertEqual(value, 101U);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:33ULL]);
XCTAssertEqual(value, 102U);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:34ULL]);
XCTAssertEqual(value, 103U);
- [dict setValue:101U forKey:34ULL];
+ [dict setUInt32:101U forKey:34ULL];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:31ULL]);
XCTAssertEqual(value, 103U);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:32ULL]);
XCTAssertEqual(value, 101U);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:33ULL]);
XCTAssertEqual(value, 102U);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:34ULL]);
XCTAssertEqual(value, 101U);
const uint64_t kKeys2[] = { 32ULL, 33ULL };
const uint32_t kValues2[] = { 102U, 100U };
GPBUInt64UInt32Dictionary *dict2 =
- [[GPBUInt64UInt32Dictionary alloc] initWithValues:kValues2
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBUInt64UInt32Dictionary alloc] initWithUInt32s:kValues2
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:31ULL]);
XCTAssertEqual(value, 103U);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:32ULL]);
XCTAssertEqual(value, 102U);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:33ULL]);
XCTAssertEqual(value, 100U);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getUInt32:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getUInt32:&value forKey:34ULL]);
XCTAssertEqual(value, 101U);
[dict2 release];
@@ -451,8 +451,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
GPBUInt64Int32Dictionary *dict = [[GPBUInt64Int32Dictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:31ULL value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(uint64_t aKey, int32_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getInt32:NULL forKey:31ULL]);
+ [dict enumerateKeysAndInt32sUsingBlock:^(uint64_t aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -460,15 +460,15 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testOne {
- GPBUInt64Int32Dictionary *dict = [GPBUInt64Int32Dictionary dictionaryWithValue:200 forKey:31ULL];
+ GPBUInt64Int32Dictionary *dict = [GPBUInt64Int32Dictionary dictionaryWithInt32:200 forKey:31ULL];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
int32_t value;
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getInt32:&value forKey:31ULL]);
XCTAssertEqual(value, 200);
- XCTAssertFalse([dict valueForKey:32ULL value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(uint64_t aKey, int32_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getInt32:NULL forKey:32ULL]);
+ [dict enumerateKeysAndInt32sUsingBlock:^(uint64_t aKey, int32_t aValue, BOOL *stop) {
XCTAssertEqual(aKey, 31ULL);
XCTAssertEqual(aValue, 200);
XCTAssertNotEqual(stop, NULL);
@@ -479,27 +479,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL };
const int32_t kValues[] = { 200, 201, 202 };
GPBUInt64Int32Dictionary *dict =
- [[GPBUInt64Int32Dictionary alloc] initWithValues:kValues
+ [[GPBUInt64Int32Dictionary alloc] initWithInt32s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 3U);
int32_t value;
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getInt32:&value forKey:31ULL]);
XCTAssertEqual(value, 200);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getInt32:&value forKey:32ULL]);
XCTAssertEqual(value, 201);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getInt32:&value forKey:33ULL]);
XCTAssertEqual(value, 202);
- XCTAssertFalse([dict valueForKey:34ULL value:NULL]);
+ XCTAssertFalse([dict getInt32:NULL forKey:34ULL]);
__block NSUInteger idx = 0;
uint64_t *seenKeys = malloc(3 * sizeof(uint64_t));
int32_t *seenValues = malloc(3 * sizeof(int32_t));
- [dict enumerateKeysAndValuesUsingBlock:^(uint64_t aKey, int32_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndInt32sUsingBlock:^(uint64_t aKey, int32_t aValue, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -521,7 +521,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(uint64_t aKey, int32_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndInt32sUsingBlock:^(uint64_t aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -537,27 +537,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kValues2[] = { 200, 203, 202 };
const int32_t kValues3[] = { 200, 201, 202, 203 };
GPBUInt64Int32Dictionary *dict1 =
- [[GPBUInt64Int32Dictionary alloc] initWithValues:kValues1
+ [[GPBUInt64Int32Dictionary alloc] initWithInt32s:kValues1
forKeys:kKeys1
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBUInt64Int32Dictionary *dict1prime =
- [[GPBUInt64Int32Dictionary alloc] initWithValues:kValues1
+ [[GPBUInt64Int32Dictionary alloc] initWithInt32s:kValues1
forKeys:kKeys1
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBUInt64Int32Dictionary *dict2 =
- [[GPBUInt64Int32Dictionary alloc] initWithValues:kValues2
+ [[GPBUInt64Int32Dictionary alloc] initWithInt32s:kValues2
forKeys:kKeys1
count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBUInt64Int32Dictionary *dict3 =
- [[GPBUInt64Int32Dictionary alloc] initWithValues:kValues1
+ [[GPBUInt64Int32Dictionary alloc] initWithInt32s:kValues1
forKeys:kKeys2
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBUInt64Int32Dictionary *dict4 =
- [[GPBUInt64Int32Dictionary alloc] initWithValues:kValues3
+ [[GPBUInt64Int32Dictionary alloc] initWithInt32s:kValues3
forKeys:kKeys1
count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
@@ -588,7 +588,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
const int32_t kValues[] = { 200, 201, 202, 203 };
GPBUInt64Int32Dictionary *dict =
- [[GPBUInt64Int32Dictionary alloc] initWithValues:kValues
+ [[GPBUInt64Int32Dictionary alloc] initWithInt32s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
@@ -609,7 +609,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
const int32_t kValues[] = { 200, 201, 202, 203 };
GPBUInt64Int32Dictionary *dict =
- [[GPBUInt64Int32Dictionary alloc] initWithValues:kValues
+ [[GPBUInt64Int32Dictionary alloc] initWithInt32s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
@@ -629,13 +629,13 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:200 forKey:31ULL];
+ [dict setInt32:200 forKey:31ULL];
XCTAssertEqual(dict.count, 1U);
const uint64_t kKeys[] = { 32ULL, 33ULL, 34ULL };
const int32_t kValues[] = { 201, 202, 203 };
GPBUInt64Int32Dictionary *dict2 =
- [[GPBUInt64Int32Dictionary alloc] initWithValues:kValues
+ [[GPBUInt64Int32Dictionary alloc] initWithInt32s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
@@ -643,17 +643,17 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertEqual(dict.count, 4U);
int32_t value;
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getInt32:&value forKey:31ULL]);
XCTAssertEqual(value, 200);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getInt32:&value forKey:32ULL]);
XCTAssertEqual(value, 201);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getInt32:&value forKey:33ULL]);
XCTAssertEqual(value, 202);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getInt32:&value forKey:34ULL]);
XCTAssertEqual(value, 203);
[dict2 release];
}
@@ -662,57 +662,57 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
const int32_t kValues[] = { 200, 201, 202, 203 };
GPBUInt64Int32Dictionary *dict =
- [[GPBUInt64Int32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt64Int32Dictionary alloc] initWithInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
- [dict removeValueForKey:32ULL];
+ [dict removeInt32ForKey:32ULL];
XCTAssertEqual(dict.count, 3U);
int32_t value;
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getInt32:&value forKey:31ULL]);
XCTAssertEqual(value, 200);
- XCTAssertFalse([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertFalse([dict getInt32:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getInt32:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getInt32:&value forKey:33ULL]);
XCTAssertEqual(value, 202);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getInt32:&value forKey:34ULL]);
XCTAssertEqual(value, 203);
// Remove again does nothing.
- [dict removeValueForKey:32ULL];
+ [dict removeInt32ForKey:32ULL];
XCTAssertEqual(dict.count, 3U);
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getInt32:&value forKey:31ULL]);
XCTAssertEqual(value, 200);
- XCTAssertFalse([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertFalse([dict getInt32:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getInt32:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getInt32:&value forKey:33ULL]);
XCTAssertEqual(value, 202);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getInt32:&value forKey:34ULL]);
XCTAssertEqual(value, 203);
- [dict removeValueForKey:34ULL];
+ [dict removeInt32ForKey:34ULL];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getInt32:&value forKey:31ULL]);
XCTAssertEqual(value, 200);
- XCTAssertFalse([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertFalse([dict getInt32:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getInt32:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getInt32:&value forKey:33ULL]);
XCTAssertEqual(value, 202);
- XCTAssertFalse([dict valueForKey:34ULL value:NULL]);
+ XCTAssertFalse([dict getInt32:NULL forKey:34ULL]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:31ULL value:NULL]);
- XCTAssertFalse([dict valueForKey:32ULL value:NULL]);
- XCTAssertFalse([dict valueForKey:33ULL value:NULL]);
- XCTAssertFalse([dict valueForKey:34ULL value:NULL]);
+ XCTAssertFalse([dict getInt32:NULL forKey:31ULL]);
+ XCTAssertFalse([dict getInt32:NULL forKey:32ULL]);
+ XCTAssertFalse([dict getInt32:NULL forKey:33ULL]);
+ XCTAssertFalse([dict getInt32:NULL forKey:34ULL]);
[dict release];
}
@@ -720,75 +720,75 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
const int32_t kValues[] = { 200, 201, 202, 203 };
GPBUInt64Int32Dictionary *dict =
- [[GPBUInt64Int32Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt64Int32Dictionary alloc] initWithInt32s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
int32_t value;
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getInt32:&value forKey:31ULL]);
XCTAssertEqual(value, 200);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getInt32:&value forKey:32ULL]);
XCTAssertEqual(value, 201);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getInt32:&value forKey:33ULL]);
XCTAssertEqual(value, 202);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getInt32:&value forKey:34ULL]);
XCTAssertEqual(value, 203);
- [dict setValue:203 forKey:31ULL];
+ [dict setInt32:203 forKey:31ULL];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getInt32:&value forKey:31ULL]);
XCTAssertEqual(value, 203);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getInt32:&value forKey:32ULL]);
XCTAssertEqual(value, 201);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getInt32:&value forKey:33ULL]);
XCTAssertEqual(value, 202);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getInt32:&value forKey:34ULL]);
XCTAssertEqual(value, 203);
- [dict setValue:201 forKey:34ULL];
+ [dict setInt32:201 forKey:34ULL];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getInt32:&value forKey:31ULL]);
XCTAssertEqual(value, 203);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getInt32:&value forKey:32ULL]);
XCTAssertEqual(value, 201);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getInt32:&value forKey:33ULL]);
XCTAssertEqual(value, 202);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getInt32:&value forKey:34ULL]);
XCTAssertEqual(value, 201);
const uint64_t kKeys2[] = { 32ULL, 33ULL };
const int32_t kValues2[] = { 202, 200 };
GPBUInt64Int32Dictionary *dict2 =
- [[GPBUInt64Int32Dictionary alloc] initWithValues:kValues2
+ [[GPBUInt64Int32Dictionary alloc] initWithInt32s:kValues2
forKeys:kKeys2
count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getInt32:&value forKey:31ULL]);
XCTAssertEqual(value, 203);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getInt32:&value forKey:32ULL]);
XCTAssertEqual(value, 202);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getInt32:&value forKey:33ULL]);
XCTAssertEqual(value, 200);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getInt32:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getInt32:&value forKey:34ULL]);
XCTAssertEqual(value, 201);
[dict2 release];
@@ -808,8 +808,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
GPBUInt64UInt64Dictionary *dict = [[GPBUInt64UInt64Dictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:31ULL value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(uint64_t aKey, uint64_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getUInt64:NULL forKey:31ULL]);
+ [dict enumerateKeysAndUInt64sUsingBlock:^(uint64_t aKey, uint64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -817,15 +817,15 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testOne {
- GPBUInt64UInt64Dictionary *dict = [GPBUInt64UInt64Dictionary dictionaryWithValue:300U forKey:31ULL];
+ GPBUInt64UInt64Dictionary *dict = [GPBUInt64UInt64Dictionary dictionaryWithUInt64:300U forKey:31ULL];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
uint64_t value;
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:31ULL]);
XCTAssertEqual(value, 300U);
- XCTAssertFalse([dict valueForKey:32ULL value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(uint64_t aKey, uint64_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getUInt64:NULL forKey:32ULL]);
+ [dict enumerateKeysAndUInt64sUsingBlock:^(uint64_t aKey, uint64_t aValue, BOOL *stop) {
XCTAssertEqual(aKey, 31ULL);
XCTAssertEqual(aValue, 300U);
XCTAssertNotEqual(stop, NULL);
@@ -836,27 +836,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL };
const uint64_t kValues[] = { 300U, 301U, 302U };
GPBUInt64UInt64Dictionary *dict =
- [[GPBUInt64UInt64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt64UInt64Dictionary alloc] initWithUInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 3U);
uint64_t value;
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:31ULL]);
XCTAssertEqual(value, 300U);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:32ULL]);
XCTAssertEqual(value, 301U);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:33ULL]);
XCTAssertEqual(value, 302U);
- XCTAssertFalse([dict valueForKey:34ULL value:NULL]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:34ULL]);
__block NSUInteger idx = 0;
uint64_t *seenKeys = malloc(3 * sizeof(uint64_t));
uint64_t *seenValues = malloc(3 * sizeof(uint64_t));
- [dict enumerateKeysAndValuesUsingBlock:^(uint64_t aKey, uint64_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndUInt64sUsingBlock:^(uint64_t aKey, uint64_t aValue, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -878,7 +878,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(uint64_t aKey, uint64_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndUInt64sUsingBlock:^(uint64_t aKey, uint64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -894,29 +894,29 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint64_t kValues2[] = { 300U, 303U, 302U };
const uint64_t kValues3[] = { 300U, 301U, 302U, 303U };
GPBUInt64UInt64Dictionary *dict1 =
- [[GPBUInt64UInt64Dictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBUInt64UInt64Dictionary alloc] initWithUInt64s:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBUInt64UInt64Dictionary *dict1prime =
- [[GPBUInt64UInt64Dictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBUInt64UInt64Dictionary alloc] initWithUInt64s:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBUInt64UInt64Dictionary *dict2 =
- [[GPBUInt64UInt64Dictionary alloc] initWithValues:kValues2
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBUInt64UInt64Dictionary alloc] initWithUInt64s:kValues2
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBUInt64UInt64Dictionary *dict3 =
- [[GPBUInt64UInt64Dictionary alloc] initWithValues:kValues1
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBUInt64UInt64Dictionary alloc] initWithUInt64s:kValues1
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBUInt64UInt64Dictionary *dict4 =
- [[GPBUInt64UInt64Dictionary alloc] initWithValues:kValues3
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues3)];
+ [[GPBUInt64UInt64Dictionary alloc] initWithUInt64s:kValues3
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
// 1/1Prime should be different objects, but equal.
@@ -945,9 +945,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
const uint64_t kValues[] = { 300U, 301U, 302U, 303U };
GPBUInt64UInt64Dictionary *dict =
- [[GPBUInt64UInt64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt64UInt64Dictionary alloc] initWithUInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBUInt64UInt64Dictionary *dict2 = [dict copy];
@@ -966,9 +966,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
const uint64_t kValues[] = { 300U, 301U, 302U, 303U };
GPBUInt64UInt64Dictionary *dict =
- [[GPBUInt64UInt64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt64UInt64Dictionary alloc] initWithUInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBUInt64UInt64Dictionary *dict2 =
@@ -986,31 +986,31 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:300U forKey:31ULL];
+ [dict setUInt64:300U forKey:31ULL];
XCTAssertEqual(dict.count, 1U);
const uint64_t kKeys[] = { 32ULL, 33ULL, 34ULL };
const uint64_t kValues[] = { 301U, 302U, 303U };
GPBUInt64UInt64Dictionary *dict2 =
- [[GPBUInt64UInt64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt64UInt64Dictionary alloc] initWithUInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
uint64_t value;
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:31ULL]);
XCTAssertEqual(value, 300U);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:32ULL]);
XCTAssertEqual(value, 301U);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:33ULL]);
XCTAssertEqual(value, 302U);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:34ULL]);
XCTAssertEqual(value, 303U);
[dict2 release];
}
@@ -1019,57 +1019,57 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
const uint64_t kValues[] = { 300U, 301U, 302U, 303U };
GPBUInt64UInt64Dictionary *dict =
- [[GPBUInt64UInt64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt64UInt64Dictionary alloc] initWithUInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
- [dict removeValueForKey:32ULL];
+ [dict removeUInt64ForKey:32ULL];
XCTAssertEqual(dict.count, 3U);
uint64_t value;
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:31ULL]);
XCTAssertEqual(value, 300U);
- XCTAssertFalse([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:33ULL]);
XCTAssertEqual(value, 302U);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:34ULL]);
XCTAssertEqual(value, 303U);
// Remove again does nothing.
- [dict removeValueForKey:32ULL];
+ [dict removeUInt64ForKey:32ULL];
XCTAssertEqual(dict.count, 3U);
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:31ULL]);
XCTAssertEqual(value, 300U);
- XCTAssertFalse([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:33ULL]);
XCTAssertEqual(value, 302U);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:34ULL]);
XCTAssertEqual(value, 303U);
- [dict removeValueForKey:34ULL];
+ [dict removeUInt64ForKey:34ULL];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:31ULL]);
XCTAssertEqual(value, 300U);
- XCTAssertFalse([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:33ULL]);
XCTAssertEqual(value, 302U);
- XCTAssertFalse([dict valueForKey:34ULL value:NULL]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:34ULL]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:31ULL value:NULL]);
- XCTAssertFalse([dict valueForKey:32ULL value:NULL]);
- XCTAssertFalse([dict valueForKey:33ULL value:NULL]);
- XCTAssertFalse([dict valueForKey:34ULL value:NULL]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:31ULL]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:32ULL]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:33ULL]);
+ XCTAssertFalse([dict getUInt64:NULL forKey:34ULL]);
[dict release];
}
@@ -1077,75 +1077,75 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
const uint64_t kValues[] = { 300U, 301U, 302U, 303U };
GPBUInt64UInt64Dictionary *dict =
- [[GPBUInt64UInt64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt64UInt64Dictionary alloc] initWithUInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
uint64_t value;
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:31ULL]);
XCTAssertEqual(value, 300U);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:32ULL]);
XCTAssertEqual(value, 301U);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:33ULL]);
XCTAssertEqual(value, 302U);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:34ULL]);
XCTAssertEqual(value, 303U);
- [dict setValue:303U forKey:31ULL];
+ [dict setUInt64:303U forKey:31ULL];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:31ULL]);
XCTAssertEqual(value, 303U);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:32ULL]);
XCTAssertEqual(value, 301U);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:33ULL]);
XCTAssertEqual(value, 302U);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:34ULL]);
XCTAssertEqual(value, 303U);
- [dict setValue:301U forKey:34ULL];
+ [dict setUInt64:301U forKey:34ULL];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:31ULL]);
XCTAssertEqual(value, 303U);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:32ULL]);
XCTAssertEqual(value, 301U);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:33ULL]);
XCTAssertEqual(value, 302U);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:34ULL]);
XCTAssertEqual(value, 301U);
const uint64_t kKeys2[] = { 32ULL, 33ULL };
const uint64_t kValues2[] = { 302U, 300U };
GPBUInt64UInt64Dictionary *dict2 =
- [[GPBUInt64UInt64Dictionary alloc] initWithValues:kValues2
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBUInt64UInt64Dictionary alloc] initWithUInt64s:kValues2
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:31ULL]);
XCTAssertEqual(value, 303U);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:32ULL]);
XCTAssertEqual(value, 302U);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:33ULL]);
XCTAssertEqual(value, 300U);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getUInt64:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getUInt64:&value forKey:34ULL]);
XCTAssertEqual(value, 301U);
[dict2 release];
@@ -1165,8 +1165,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
GPBUInt64Int64Dictionary *dict = [[GPBUInt64Int64Dictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:31ULL value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(uint64_t aKey, int64_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getInt64:NULL forKey:31ULL]);
+ [dict enumerateKeysAndInt64sUsingBlock:^(uint64_t aKey, int64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -1174,15 +1174,15 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testOne {
- GPBUInt64Int64Dictionary *dict = [GPBUInt64Int64Dictionary dictionaryWithValue:400 forKey:31ULL];
+ GPBUInt64Int64Dictionary *dict = [GPBUInt64Int64Dictionary dictionaryWithInt64:400 forKey:31ULL];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
int64_t value;
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getInt64:&value forKey:31ULL]);
XCTAssertEqual(value, 400);
- XCTAssertFalse([dict valueForKey:32ULL value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(uint64_t aKey, int64_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getInt64:NULL forKey:32ULL]);
+ [dict enumerateKeysAndInt64sUsingBlock:^(uint64_t aKey, int64_t aValue, BOOL *stop) {
XCTAssertEqual(aKey, 31ULL);
XCTAssertEqual(aValue, 400);
XCTAssertNotEqual(stop, NULL);
@@ -1193,27 +1193,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL };
const int64_t kValues[] = { 400, 401, 402 };
GPBUInt64Int64Dictionary *dict =
- [[GPBUInt64Int64Dictionary alloc] initWithValues:kValues
+ [[GPBUInt64Int64Dictionary alloc] initWithInt64s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 3U);
int64_t value;
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getInt64:&value forKey:31ULL]);
XCTAssertEqual(value, 400);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getInt64:&value forKey:32ULL]);
XCTAssertEqual(value, 401);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getInt64:&value forKey:33ULL]);
XCTAssertEqual(value, 402);
- XCTAssertFalse([dict valueForKey:34ULL value:NULL]);
+ XCTAssertFalse([dict getInt64:NULL forKey:34ULL]);
__block NSUInteger idx = 0;
uint64_t *seenKeys = malloc(3 * sizeof(uint64_t));
int64_t *seenValues = malloc(3 * sizeof(int64_t));
- [dict enumerateKeysAndValuesUsingBlock:^(uint64_t aKey, int64_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndInt64sUsingBlock:^(uint64_t aKey, int64_t aValue, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -1235,7 +1235,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(uint64_t aKey, int64_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndInt64sUsingBlock:^(uint64_t aKey, int64_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -1251,27 +1251,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int64_t kValues2[] = { 400, 403, 402 };
const int64_t kValues3[] = { 400, 401, 402, 403 };
GPBUInt64Int64Dictionary *dict1 =
- [[GPBUInt64Int64Dictionary alloc] initWithValues:kValues1
+ [[GPBUInt64Int64Dictionary alloc] initWithInt64s:kValues1
forKeys:kKeys1
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBUInt64Int64Dictionary *dict1prime =
- [[GPBUInt64Int64Dictionary alloc] initWithValues:kValues1
+ [[GPBUInt64Int64Dictionary alloc] initWithInt64s:kValues1
forKeys:kKeys1
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBUInt64Int64Dictionary *dict2 =
- [[GPBUInt64Int64Dictionary alloc] initWithValues:kValues2
+ [[GPBUInt64Int64Dictionary alloc] initWithInt64s:kValues2
forKeys:kKeys1
count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBUInt64Int64Dictionary *dict3 =
- [[GPBUInt64Int64Dictionary alloc] initWithValues:kValues1
+ [[GPBUInt64Int64Dictionary alloc] initWithInt64s:kValues1
forKeys:kKeys2
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBUInt64Int64Dictionary *dict4 =
- [[GPBUInt64Int64Dictionary alloc] initWithValues:kValues3
+ [[GPBUInt64Int64Dictionary alloc] initWithInt64s:kValues3
forKeys:kKeys1
count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
@@ -1302,7 +1302,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
const int64_t kValues[] = { 400, 401, 402, 403 };
GPBUInt64Int64Dictionary *dict =
- [[GPBUInt64Int64Dictionary alloc] initWithValues:kValues
+ [[GPBUInt64Int64Dictionary alloc] initWithInt64s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
@@ -1323,7 +1323,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
const int64_t kValues[] = { 400, 401, 402, 403 };
GPBUInt64Int64Dictionary *dict =
- [[GPBUInt64Int64Dictionary alloc] initWithValues:kValues
+ [[GPBUInt64Int64Dictionary alloc] initWithInt64s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
@@ -1343,13 +1343,13 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:400 forKey:31ULL];
+ [dict setInt64:400 forKey:31ULL];
XCTAssertEqual(dict.count, 1U);
const uint64_t kKeys[] = { 32ULL, 33ULL, 34ULL };
const int64_t kValues[] = { 401, 402, 403 };
GPBUInt64Int64Dictionary *dict2 =
- [[GPBUInt64Int64Dictionary alloc] initWithValues:kValues
+ [[GPBUInt64Int64Dictionary alloc] initWithInt64s:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
@@ -1357,17 +1357,17 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertEqual(dict.count, 4U);
int64_t value;
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getInt64:&value forKey:31ULL]);
XCTAssertEqual(value, 400);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getInt64:&value forKey:32ULL]);
XCTAssertEqual(value, 401);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getInt64:&value forKey:33ULL]);
XCTAssertEqual(value, 402);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getInt64:&value forKey:34ULL]);
XCTAssertEqual(value, 403);
[dict2 release];
}
@@ -1376,57 +1376,57 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
const int64_t kValues[] = { 400, 401, 402, 403 };
GPBUInt64Int64Dictionary *dict =
- [[GPBUInt64Int64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt64Int64Dictionary alloc] initWithInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
- [dict removeValueForKey:32ULL];
+ [dict removeInt64ForKey:32ULL];
XCTAssertEqual(dict.count, 3U);
int64_t value;
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getInt64:&value forKey:31ULL]);
XCTAssertEqual(value, 400);
- XCTAssertFalse([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertFalse([dict getInt64:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getInt64:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getInt64:&value forKey:33ULL]);
XCTAssertEqual(value, 402);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getInt64:&value forKey:34ULL]);
XCTAssertEqual(value, 403);
// Remove again does nothing.
- [dict removeValueForKey:32ULL];
+ [dict removeInt64ForKey:32ULL];
XCTAssertEqual(dict.count, 3U);
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getInt64:&value forKey:31ULL]);
XCTAssertEqual(value, 400);
- XCTAssertFalse([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertFalse([dict getInt64:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getInt64:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getInt64:&value forKey:33ULL]);
XCTAssertEqual(value, 402);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getInt64:&value forKey:34ULL]);
XCTAssertEqual(value, 403);
- [dict removeValueForKey:34ULL];
+ [dict removeInt64ForKey:34ULL];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getInt64:&value forKey:31ULL]);
XCTAssertEqual(value, 400);
- XCTAssertFalse([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertFalse([dict getInt64:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getInt64:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getInt64:&value forKey:33ULL]);
XCTAssertEqual(value, 402);
- XCTAssertFalse([dict valueForKey:34ULL value:NULL]);
+ XCTAssertFalse([dict getInt64:NULL forKey:34ULL]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:31ULL value:NULL]);
- XCTAssertFalse([dict valueForKey:32ULL value:NULL]);
- XCTAssertFalse([dict valueForKey:33ULL value:NULL]);
- XCTAssertFalse([dict valueForKey:34ULL value:NULL]);
+ XCTAssertFalse([dict getInt64:NULL forKey:31ULL]);
+ XCTAssertFalse([dict getInt64:NULL forKey:32ULL]);
+ XCTAssertFalse([dict getInt64:NULL forKey:33ULL]);
+ XCTAssertFalse([dict getInt64:NULL forKey:34ULL]);
[dict release];
}
@@ -1434,75 +1434,75 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
const int64_t kValues[] = { 400, 401, 402, 403 };
GPBUInt64Int64Dictionary *dict =
- [[GPBUInt64Int64Dictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt64Int64Dictionary alloc] initWithInt64s:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
int64_t value;
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getInt64:&value forKey:31ULL]);
XCTAssertEqual(value, 400);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getInt64:&value forKey:32ULL]);
XCTAssertEqual(value, 401);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getInt64:&value forKey:33ULL]);
XCTAssertEqual(value, 402);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getInt64:&value forKey:34ULL]);
XCTAssertEqual(value, 403);
- [dict setValue:403 forKey:31ULL];
+ [dict setInt64:403 forKey:31ULL];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getInt64:&value forKey:31ULL]);
XCTAssertEqual(value, 403);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getInt64:&value forKey:32ULL]);
XCTAssertEqual(value, 401);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getInt64:&value forKey:33ULL]);
XCTAssertEqual(value, 402);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getInt64:&value forKey:34ULL]);
XCTAssertEqual(value, 403);
- [dict setValue:401 forKey:34ULL];
+ [dict setInt64:401 forKey:34ULL];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getInt64:&value forKey:31ULL]);
XCTAssertEqual(value, 403);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getInt64:&value forKey:32ULL]);
XCTAssertEqual(value, 401);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getInt64:&value forKey:33ULL]);
XCTAssertEqual(value, 402);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getInt64:&value forKey:34ULL]);
XCTAssertEqual(value, 401);
const uint64_t kKeys2[] = { 32ULL, 33ULL };
const int64_t kValues2[] = { 402, 400 };
GPBUInt64Int64Dictionary *dict2 =
- [[GPBUInt64Int64Dictionary alloc] initWithValues:kValues2
+ [[GPBUInt64Int64Dictionary alloc] initWithInt64s:kValues2
forKeys:kKeys2
count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getInt64:&value forKey:31ULL]);
XCTAssertEqual(value, 403);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getInt64:&value forKey:32ULL]);
XCTAssertEqual(value, 402);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getInt64:&value forKey:33ULL]);
XCTAssertEqual(value, 400);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getInt64:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getInt64:&value forKey:34ULL]);
XCTAssertEqual(value, 401);
[dict2 release];
@@ -1522,8 +1522,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
GPBUInt64BoolDictionary *dict = [[GPBUInt64BoolDictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:31ULL value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(uint64_t aKey, BOOL aValue, BOOL *stop) {
+ XCTAssertFalse([dict getBool:NULL forKey:31ULL]);
+ [dict enumerateKeysAndBoolsUsingBlock:^(uint64_t aKey, BOOL aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -1531,15 +1531,15 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testOne {
- GPBUInt64BoolDictionary *dict = [GPBUInt64BoolDictionary dictionaryWithValue:YES forKey:31ULL];
+ GPBUInt64BoolDictionary *dict = [GPBUInt64BoolDictionary dictionaryWithBool:YES forKey:31ULL];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
BOOL value;
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getBool:&value forKey:31ULL]);
XCTAssertEqual(value, YES);
- XCTAssertFalse([dict valueForKey:32ULL value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(uint64_t aKey, BOOL aValue, BOOL *stop) {
+ XCTAssertFalse([dict getBool:NULL forKey:32ULL]);
+ [dict enumerateKeysAndBoolsUsingBlock:^(uint64_t aKey, BOOL aValue, BOOL *stop) {
XCTAssertEqual(aKey, 31ULL);
XCTAssertEqual(aValue, YES);
XCTAssertNotEqual(stop, NULL);
@@ -1550,27 +1550,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL };
const BOOL kValues[] = { YES, YES, NO };
GPBUInt64BoolDictionary *dict =
- [[GPBUInt64BoolDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt64BoolDictionary alloc] initWithBools:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 3U);
BOOL value;
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getBool:&value forKey:31ULL]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getBool:&value forKey:32ULL]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getBool:&value forKey:33ULL]);
XCTAssertEqual(value, NO);
- XCTAssertFalse([dict valueForKey:34ULL value:NULL]);
+ XCTAssertFalse([dict getBool:NULL forKey:34ULL]);
__block NSUInteger idx = 0;
uint64_t *seenKeys = malloc(3 * sizeof(uint64_t));
BOOL *seenValues = malloc(3 * sizeof(BOOL));
- [dict enumerateKeysAndValuesUsingBlock:^(uint64_t aKey, BOOL aValue, BOOL *stop) {
+ [dict enumerateKeysAndBoolsUsingBlock:^(uint64_t aKey, BOOL aValue, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -1592,7 +1592,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(uint64_t aKey, BOOL aValue, BOOL *stop) {
+ [dict enumerateKeysAndBoolsUsingBlock:^(uint64_t aKey, BOOL aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -1608,29 +1608,29 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const BOOL kValues2[] = { YES, NO, NO };
const BOOL kValues3[] = { YES, YES, NO, NO };
GPBUInt64BoolDictionary *dict1 =
- [[GPBUInt64BoolDictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBUInt64BoolDictionary alloc] initWithBools:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBUInt64BoolDictionary *dict1prime =
- [[GPBUInt64BoolDictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBUInt64BoolDictionary alloc] initWithBools:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBUInt64BoolDictionary *dict2 =
- [[GPBUInt64BoolDictionary alloc] initWithValues:kValues2
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBUInt64BoolDictionary alloc] initWithBools:kValues2
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBUInt64BoolDictionary *dict3 =
- [[GPBUInt64BoolDictionary alloc] initWithValues:kValues1
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBUInt64BoolDictionary alloc] initWithBools:kValues1
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBUInt64BoolDictionary *dict4 =
- [[GPBUInt64BoolDictionary alloc] initWithValues:kValues3
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues3)];
+ [[GPBUInt64BoolDictionary alloc] initWithBools:kValues3
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
// 1/1Prime should be different objects, but equal.
@@ -1659,9 +1659,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
const BOOL kValues[] = { YES, YES, NO, NO };
GPBUInt64BoolDictionary *dict =
- [[GPBUInt64BoolDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt64BoolDictionary alloc] initWithBools:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBUInt64BoolDictionary *dict2 = [dict copy];
@@ -1680,9 +1680,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
const BOOL kValues[] = { YES, YES, NO, NO };
GPBUInt64BoolDictionary *dict =
- [[GPBUInt64BoolDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt64BoolDictionary alloc] initWithBools:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBUInt64BoolDictionary *dict2 =
@@ -1700,31 +1700,31 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:YES forKey:31ULL];
+ [dict setBool:YES forKey:31ULL];
XCTAssertEqual(dict.count, 1U);
const uint64_t kKeys[] = { 32ULL, 33ULL, 34ULL };
const BOOL kValues[] = { YES, NO, NO };
GPBUInt64BoolDictionary *dict2 =
- [[GPBUInt64BoolDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt64BoolDictionary alloc] initWithBools:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
BOOL value;
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getBool:&value forKey:31ULL]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getBool:&value forKey:32ULL]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getBool:&value forKey:33ULL]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getBool:&value forKey:34ULL]);
XCTAssertEqual(value, NO);
[dict2 release];
}
@@ -1733,57 +1733,57 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
const BOOL kValues[] = { YES, YES, NO, NO };
GPBUInt64BoolDictionary *dict =
- [[GPBUInt64BoolDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt64BoolDictionary alloc] initWithBools:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
- [dict removeValueForKey:32ULL];
+ [dict removeBoolForKey:32ULL];
XCTAssertEqual(dict.count, 3U);
BOOL value;
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getBool:&value forKey:31ULL]);
XCTAssertEqual(value, YES);
- XCTAssertFalse([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertFalse([dict getBool:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getBool:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getBool:&value forKey:33ULL]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getBool:&value forKey:34ULL]);
XCTAssertEqual(value, NO);
// Remove again does nothing.
- [dict removeValueForKey:32ULL];
+ [dict removeBoolForKey:32ULL];
XCTAssertEqual(dict.count, 3U);
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getBool:&value forKey:31ULL]);
XCTAssertEqual(value, YES);
- XCTAssertFalse([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertFalse([dict getBool:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getBool:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getBool:&value forKey:33ULL]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getBool:&value forKey:34ULL]);
XCTAssertEqual(value, NO);
- [dict removeValueForKey:34ULL];
+ [dict removeBoolForKey:34ULL];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getBool:&value forKey:31ULL]);
XCTAssertEqual(value, YES);
- XCTAssertFalse([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertFalse([dict getBool:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getBool:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getBool:&value forKey:33ULL]);
XCTAssertEqual(value, NO);
- XCTAssertFalse([dict valueForKey:34ULL value:NULL]);
+ XCTAssertFalse([dict getBool:NULL forKey:34ULL]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:31ULL value:NULL]);
- XCTAssertFalse([dict valueForKey:32ULL value:NULL]);
- XCTAssertFalse([dict valueForKey:33ULL value:NULL]);
- XCTAssertFalse([dict valueForKey:34ULL value:NULL]);
+ XCTAssertFalse([dict getBool:NULL forKey:31ULL]);
+ XCTAssertFalse([dict getBool:NULL forKey:32ULL]);
+ XCTAssertFalse([dict getBool:NULL forKey:33ULL]);
+ XCTAssertFalse([dict getBool:NULL forKey:34ULL]);
[dict release];
}
@@ -1791,75 +1791,75 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
const BOOL kValues[] = { YES, YES, NO, NO };
GPBUInt64BoolDictionary *dict =
- [[GPBUInt64BoolDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt64BoolDictionary alloc] initWithBools:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
BOOL value;
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getBool:&value forKey:31ULL]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getBool:&value forKey:32ULL]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getBool:&value forKey:33ULL]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getBool:&value forKey:34ULL]);
XCTAssertEqual(value, NO);
- [dict setValue:NO forKey:31ULL];
+ [dict setBool:NO forKey:31ULL];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getBool:&value forKey:31ULL]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getBool:&value forKey:32ULL]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getBool:&value forKey:33ULL]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getBool:&value forKey:34ULL]);
XCTAssertEqual(value, NO);
- [dict setValue:YES forKey:34ULL];
+ [dict setBool:YES forKey:34ULL];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getBool:&value forKey:31ULL]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getBool:&value forKey:32ULL]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getBool:&value forKey:33ULL]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getBool:&value forKey:34ULL]);
XCTAssertEqual(value, YES);
const uint64_t kKeys2[] = { 32ULL, 33ULL };
const BOOL kValues2[] = { NO, YES };
GPBUInt64BoolDictionary *dict2 =
- [[GPBUInt64BoolDictionary alloc] initWithValues:kValues2
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBUInt64BoolDictionary alloc] initWithBools:kValues2
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getBool:&value forKey:31ULL]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getBool:&value forKey:32ULL]);
XCTAssertEqual(value, NO);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getBool:&value forKey:33ULL]);
XCTAssertEqual(value, YES);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getBool:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getBool:&value forKey:34ULL]);
XCTAssertEqual(value, YES);
[dict2 release];
@@ -1879,8 +1879,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
GPBUInt64FloatDictionary *dict = [[GPBUInt64FloatDictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:31ULL value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(uint64_t aKey, float aValue, BOOL *stop) {
+ XCTAssertFalse([dict getFloat:NULL forKey:31ULL]);
+ [dict enumerateKeysAndFloatsUsingBlock:^(uint64_t aKey, float aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -1888,15 +1888,15 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testOne {
- GPBUInt64FloatDictionary *dict = [GPBUInt64FloatDictionary dictionaryWithValue:500.f forKey:31ULL];
+ GPBUInt64FloatDictionary *dict = [GPBUInt64FloatDictionary dictionaryWithFloat:500.f forKey:31ULL];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
float value;
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getFloat:&value forKey:31ULL]);
XCTAssertEqual(value, 500.f);
- XCTAssertFalse([dict valueForKey:32ULL value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(uint64_t aKey, float aValue, BOOL *stop) {
+ XCTAssertFalse([dict getFloat:NULL forKey:32ULL]);
+ [dict enumerateKeysAndFloatsUsingBlock:^(uint64_t aKey, float aValue, BOOL *stop) {
XCTAssertEqual(aKey, 31ULL);
XCTAssertEqual(aValue, 500.f);
XCTAssertNotEqual(stop, NULL);
@@ -1907,27 +1907,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL };
const float kValues[] = { 500.f, 501.f, 502.f };
GPBUInt64FloatDictionary *dict =
- [[GPBUInt64FloatDictionary alloc] initWithValues:kValues
+ [[GPBUInt64FloatDictionary alloc] initWithFloats:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 3U);
float value;
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getFloat:&value forKey:31ULL]);
XCTAssertEqual(value, 500.f);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getFloat:&value forKey:32ULL]);
XCTAssertEqual(value, 501.f);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getFloat:&value forKey:33ULL]);
XCTAssertEqual(value, 502.f);
- XCTAssertFalse([dict valueForKey:34ULL value:NULL]);
+ XCTAssertFalse([dict getFloat:NULL forKey:34ULL]);
__block NSUInteger idx = 0;
uint64_t *seenKeys = malloc(3 * sizeof(uint64_t));
float *seenValues = malloc(3 * sizeof(float));
- [dict enumerateKeysAndValuesUsingBlock:^(uint64_t aKey, float aValue, BOOL *stop) {
+ [dict enumerateKeysAndFloatsUsingBlock:^(uint64_t aKey, float aValue, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -1949,7 +1949,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(uint64_t aKey, float aValue, BOOL *stop) {
+ [dict enumerateKeysAndFloatsUsingBlock:^(uint64_t aKey, float aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -1965,27 +1965,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const float kValues2[] = { 500.f, 503.f, 502.f };
const float kValues3[] = { 500.f, 501.f, 502.f, 503.f };
GPBUInt64FloatDictionary *dict1 =
- [[GPBUInt64FloatDictionary alloc] initWithValues:kValues1
+ [[GPBUInt64FloatDictionary alloc] initWithFloats:kValues1
forKeys:kKeys1
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBUInt64FloatDictionary *dict1prime =
- [[GPBUInt64FloatDictionary alloc] initWithValues:kValues1
+ [[GPBUInt64FloatDictionary alloc] initWithFloats:kValues1
forKeys:kKeys1
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBUInt64FloatDictionary *dict2 =
- [[GPBUInt64FloatDictionary alloc] initWithValues:kValues2
+ [[GPBUInt64FloatDictionary alloc] initWithFloats:kValues2
forKeys:kKeys1
count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBUInt64FloatDictionary *dict3 =
- [[GPBUInt64FloatDictionary alloc] initWithValues:kValues1
+ [[GPBUInt64FloatDictionary alloc] initWithFloats:kValues1
forKeys:kKeys2
count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBUInt64FloatDictionary *dict4 =
- [[GPBUInt64FloatDictionary alloc] initWithValues:kValues3
+ [[GPBUInt64FloatDictionary alloc] initWithFloats:kValues3
forKeys:kKeys1
count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
@@ -2016,7 +2016,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
const float kValues[] = { 500.f, 501.f, 502.f, 503.f };
GPBUInt64FloatDictionary *dict =
- [[GPBUInt64FloatDictionary alloc] initWithValues:kValues
+ [[GPBUInt64FloatDictionary alloc] initWithFloats:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
@@ -2037,7 +2037,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
const float kValues[] = { 500.f, 501.f, 502.f, 503.f };
GPBUInt64FloatDictionary *dict =
- [[GPBUInt64FloatDictionary alloc] initWithValues:kValues
+ [[GPBUInt64FloatDictionary alloc] initWithFloats:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
@@ -2057,13 +2057,13 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:500.f forKey:31ULL];
+ [dict setFloat:500.f forKey:31ULL];
XCTAssertEqual(dict.count, 1U);
const uint64_t kKeys[] = { 32ULL, 33ULL, 34ULL };
const float kValues[] = { 501.f, 502.f, 503.f };
GPBUInt64FloatDictionary *dict2 =
- [[GPBUInt64FloatDictionary alloc] initWithValues:kValues
+ [[GPBUInt64FloatDictionary alloc] initWithFloats:kValues
forKeys:kKeys
count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
@@ -2071,17 +2071,17 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertEqual(dict.count, 4U);
float value;
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getFloat:&value forKey:31ULL]);
XCTAssertEqual(value, 500.f);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getFloat:&value forKey:32ULL]);
XCTAssertEqual(value, 501.f);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getFloat:&value forKey:33ULL]);
XCTAssertEqual(value, 502.f);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getFloat:&value forKey:34ULL]);
XCTAssertEqual(value, 503.f);
[dict2 release];
}
@@ -2090,57 +2090,57 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
const float kValues[] = { 500.f, 501.f, 502.f, 503.f };
GPBUInt64FloatDictionary *dict =
- [[GPBUInt64FloatDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt64FloatDictionary alloc] initWithFloats:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
- [dict removeValueForKey:32ULL];
+ [dict removeFloatForKey:32ULL];
XCTAssertEqual(dict.count, 3U);
float value;
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getFloat:&value forKey:31ULL]);
XCTAssertEqual(value, 500.f);
- XCTAssertFalse([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertFalse([dict getFloat:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getFloat:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getFloat:&value forKey:33ULL]);
XCTAssertEqual(value, 502.f);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getFloat:&value forKey:34ULL]);
XCTAssertEqual(value, 503.f);
// Remove again does nothing.
- [dict removeValueForKey:32ULL];
+ [dict removeFloatForKey:32ULL];
XCTAssertEqual(dict.count, 3U);
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getFloat:&value forKey:31ULL]);
XCTAssertEqual(value, 500.f);
- XCTAssertFalse([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertFalse([dict getFloat:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getFloat:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getFloat:&value forKey:33ULL]);
XCTAssertEqual(value, 502.f);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getFloat:&value forKey:34ULL]);
XCTAssertEqual(value, 503.f);
- [dict removeValueForKey:34ULL];
+ [dict removeFloatForKey:34ULL];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getFloat:&value forKey:31ULL]);
XCTAssertEqual(value, 500.f);
- XCTAssertFalse([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertFalse([dict getFloat:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getFloat:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getFloat:&value forKey:33ULL]);
XCTAssertEqual(value, 502.f);
- XCTAssertFalse([dict valueForKey:34ULL value:NULL]);
+ XCTAssertFalse([dict getFloat:NULL forKey:34ULL]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:31ULL value:NULL]);
- XCTAssertFalse([dict valueForKey:32ULL value:NULL]);
- XCTAssertFalse([dict valueForKey:33ULL value:NULL]);
- XCTAssertFalse([dict valueForKey:34ULL value:NULL]);
+ XCTAssertFalse([dict getFloat:NULL forKey:31ULL]);
+ XCTAssertFalse([dict getFloat:NULL forKey:32ULL]);
+ XCTAssertFalse([dict getFloat:NULL forKey:33ULL]);
+ XCTAssertFalse([dict getFloat:NULL forKey:34ULL]);
[dict release];
}
@@ -2148,75 +2148,75 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
const float kValues[] = { 500.f, 501.f, 502.f, 503.f };
GPBUInt64FloatDictionary *dict =
- [[GPBUInt64FloatDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt64FloatDictionary alloc] initWithFloats:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
float value;
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getFloat:&value forKey:31ULL]);
XCTAssertEqual(value, 500.f);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getFloat:&value forKey:32ULL]);
XCTAssertEqual(value, 501.f);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getFloat:&value forKey:33ULL]);
XCTAssertEqual(value, 502.f);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getFloat:&value forKey:34ULL]);
XCTAssertEqual(value, 503.f);
- [dict setValue:503.f forKey:31ULL];
+ [dict setFloat:503.f forKey:31ULL];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getFloat:&value forKey:31ULL]);
XCTAssertEqual(value, 503.f);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getFloat:&value forKey:32ULL]);
XCTAssertEqual(value, 501.f);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getFloat:&value forKey:33ULL]);
XCTAssertEqual(value, 502.f);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getFloat:&value forKey:34ULL]);
XCTAssertEqual(value, 503.f);
- [dict setValue:501.f forKey:34ULL];
+ [dict setFloat:501.f forKey:34ULL];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getFloat:&value forKey:31ULL]);
XCTAssertEqual(value, 503.f);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getFloat:&value forKey:32ULL]);
XCTAssertEqual(value, 501.f);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getFloat:&value forKey:33ULL]);
XCTAssertEqual(value, 502.f);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getFloat:&value forKey:34ULL]);
XCTAssertEqual(value, 501.f);
const uint64_t kKeys2[] = { 32ULL, 33ULL };
const float kValues2[] = { 502.f, 500.f };
GPBUInt64FloatDictionary *dict2 =
- [[GPBUInt64FloatDictionary alloc] initWithValues:kValues2
+ [[GPBUInt64FloatDictionary alloc] initWithFloats:kValues2
forKeys:kKeys2
count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getFloat:&value forKey:31ULL]);
XCTAssertEqual(value, 503.f);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getFloat:&value forKey:32ULL]);
XCTAssertEqual(value, 502.f);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getFloat:&value forKey:33ULL]);
XCTAssertEqual(value, 500.f);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getFloat:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getFloat:&value forKey:34ULL]);
XCTAssertEqual(value, 501.f);
[dict2 release];
@@ -2236,8 +2236,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
GPBUInt64DoubleDictionary *dict = [[GPBUInt64DoubleDictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:31ULL value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(uint64_t aKey, double aValue, BOOL *stop) {
+ XCTAssertFalse([dict getDouble:NULL forKey:31ULL]);
+ [dict enumerateKeysAndDoublesUsingBlock:^(uint64_t aKey, double aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -2245,15 +2245,15 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testOne {
- GPBUInt64DoubleDictionary *dict = [GPBUInt64DoubleDictionary dictionaryWithValue:600. forKey:31ULL];
+ GPBUInt64DoubleDictionary *dict = [GPBUInt64DoubleDictionary dictionaryWithDouble:600. forKey:31ULL];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
double value;
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getDouble:&value forKey:31ULL]);
XCTAssertEqual(value, 600.);
- XCTAssertFalse([dict valueForKey:32ULL value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(uint64_t aKey, double aValue, BOOL *stop) {
+ XCTAssertFalse([dict getDouble:NULL forKey:32ULL]);
+ [dict enumerateKeysAndDoublesUsingBlock:^(uint64_t aKey, double aValue, BOOL *stop) {
XCTAssertEqual(aKey, 31ULL);
XCTAssertEqual(aValue, 600.);
XCTAssertNotEqual(stop, NULL);
@@ -2264,27 +2264,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL };
const double kValues[] = { 600., 601., 602. };
GPBUInt64DoubleDictionary *dict =
- [[GPBUInt64DoubleDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt64DoubleDictionary alloc] initWithDoubles:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 3U);
double value;
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getDouble:&value forKey:31ULL]);
XCTAssertEqual(value, 600.);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getDouble:&value forKey:32ULL]);
XCTAssertEqual(value, 601.);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getDouble:&value forKey:33ULL]);
XCTAssertEqual(value, 602.);
- XCTAssertFalse([dict valueForKey:34ULL value:NULL]);
+ XCTAssertFalse([dict getDouble:NULL forKey:34ULL]);
__block NSUInteger idx = 0;
uint64_t *seenKeys = malloc(3 * sizeof(uint64_t));
double *seenValues = malloc(3 * sizeof(double));
- [dict enumerateKeysAndValuesUsingBlock:^(uint64_t aKey, double aValue, BOOL *stop) {
+ [dict enumerateKeysAndDoublesUsingBlock:^(uint64_t aKey, double aValue, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -2306,7 +2306,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(uint64_t aKey, double aValue, BOOL *stop) {
+ [dict enumerateKeysAndDoublesUsingBlock:^(uint64_t aKey, double aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -2322,29 +2322,29 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const double kValues2[] = { 600., 603., 602. };
const double kValues3[] = { 600., 601., 602., 603. };
GPBUInt64DoubleDictionary *dict1 =
- [[GPBUInt64DoubleDictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBUInt64DoubleDictionary alloc] initWithDoubles:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBUInt64DoubleDictionary *dict1prime =
- [[GPBUInt64DoubleDictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBUInt64DoubleDictionary alloc] initWithDoubles:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBUInt64DoubleDictionary *dict2 =
- [[GPBUInt64DoubleDictionary alloc] initWithValues:kValues2
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBUInt64DoubleDictionary alloc] initWithDoubles:kValues2
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBUInt64DoubleDictionary *dict3 =
- [[GPBUInt64DoubleDictionary alloc] initWithValues:kValues1
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBUInt64DoubleDictionary alloc] initWithDoubles:kValues1
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBUInt64DoubleDictionary *dict4 =
- [[GPBUInt64DoubleDictionary alloc] initWithValues:kValues3
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues3)];
+ [[GPBUInt64DoubleDictionary alloc] initWithDoubles:kValues3
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
// 1/1Prime should be different objects, but equal.
@@ -2373,9 +2373,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
const double kValues[] = { 600., 601., 602., 603. };
GPBUInt64DoubleDictionary *dict =
- [[GPBUInt64DoubleDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt64DoubleDictionary alloc] initWithDoubles:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBUInt64DoubleDictionary *dict2 = [dict copy];
@@ -2394,9 +2394,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
const double kValues[] = { 600., 601., 602., 603. };
GPBUInt64DoubleDictionary *dict =
- [[GPBUInt64DoubleDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt64DoubleDictionary alloc] initWithDoubles:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBUInt64DoubleDictionary *dict2 =
@@ -2414,31 +2414,31 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:600. forKey:31ULL];
+ [dict setDouble:600. forKey:31ULL];
XCTAssertEqual(dict.count, 1U);
const uint64_t kKeys[] = { 32ULL, 33ULL, 34ULL };
const double kValues[] = { 601., 602., 603. };
GPBUInt64DoubleDictionary *dict2 =
- [[GPBUInt64DoubleDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt64DoubleDictionary alloc] initWithDoubles:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
double value;
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getDouble:&value forKey:31ULL]);
XCTAssertEqual(value, 600.);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getDouble:&value forKey:32ULL]);
XCTAssertEqual(value, 601.);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getDouble:&value forKey:33ULL]);
XCTAssertEqual(value, 602.);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getDouble:&value forKey:34ULL]);
XCTAssertEqual(value, 603.);
[dict2 release];
}
@@ -2447,57 +2447,57 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
const double kValues[] = { 600., 601., 602., 603. };
GPBUInt64DoubleDictionary *dict =
- [[GPBUInt64DoubleDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt64DoubleDictionary alloc] initWithDoubles:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
- [dict removeValueForKey:32ULL];
+ [dict removeDoubleForKey:32ULL];
XCTAssertEqual(dict.count, 3U);
double value;
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getDouble:&value forKey:31ULL]);
XCTAssertEqual(value, 600.);
- XCTAssertFalse([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertFalse([dict getDouble:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getDouble:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getDouble:&value forKey:33ULL]);
XCTAssertEqual(value, 602.);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getDouble:&value forKey:34ULL]);
XCTAssertEqual(value, 603.);
// Remove again does nothing.
- [dict removeValueForKey:32ULL];
+ [dict removeDoubleForKey:32ULL];
XCTAssertEqual(dict.count, 3U);
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getDouble:&value forKey:31ULL]);
XCTAssertEqual(value, 600.);
- XCTAssertFalse([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertFalse([dict getDouble:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getDouble:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getDouble:&value forKey:33ULL]);
XCTAssertEqual(value, 602.);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getDouble:&value forKey:34ULL]);
XCTAssertEqual(value, 603.);
- [dict removeValueForKey:34ULL];
+ [dict removeDoubleForKey:34ULL];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getDouble:&value forKey:31ULL]);
XCTAssertEqual(value, 600.);
- XCTAssertFalse([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertFalse([dict getDouble:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getDouble:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getDouble:&value forKey:33ULL]);
XCTAssertEqual(value, 602.);
- XCTAssertFalse([dict valueForKey:34ULL value:NULL]);
+ XCTAssertFalse([dict getDouble:NULL forKey:34ULL]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:31ULL value:NULL]);
- XCTAssertFalse([dict valueForKey:32ULL value:NULL]);
- XCTAssertFalse([dict valueForKey:33ULL value:NULL]);
- XCTAssertFalse([dict valueForKey:34ULL value:NULL]);
+ XCTAssertFalse([dict getDouble:NULL forKey:31ULL]);
+ XCTAssertFalse([dict getDouble:NULL forKey:32ULL]);
+ XCTAssertFalse([dict getDouble:NULL forKey:33ULL]);
+ XCTAssertFalse([dict getDouble:NULL forKey:34ULL]);
[dict release];
}
@@ -2505,75 +2505,75 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
const double kValues[] = { 600., 601., 602., 603. };
GPBUInt64DoubleDictionary *dict =
- [[GPBUInt64DoubleDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt64DoubleDictionary alloc] initWithDoubles:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
double value;
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getDouble:&value forKey:31ULL]);
XCTAssertEqual(value, 600.);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getDouble:&value forKey:32ULL]);
XCTAssertEqual(value, 601.);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getDouble:&value forKey:33ULL]);
XCTAssertEqual(value, 602.);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getDouble:&value forKey:34ULL]);
XCTAssertEqual(value, 603.);
- [dict setValue:603. forKey:31ULL];
+ [dict setDouble:603. forKey:31ULL];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getDouble:&value forKey:31ULL]);
XCTAssertEqual(value, 603.);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getDouble:&value forKey:32ULL]);
XCTAssertEqual(value, 601.);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getDouble:&value forKey:33ULL]);
XCTAssertEqual(value, 602.);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getDouble:&value forKey:34ULL]);
XCTAssertEqual(value, 603.);
- [dict setValue:601. forKey:34ULL];
+ [dict setDouble:601. forKey:34ULL];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getDouble:&value forKey:31ULL]);
XCTAssertEqual(value, 603.);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getDouble:&value forKey:32ULL]);
XCTAssertEqual(value, 601.);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getDouble:&value forKey:33ULL]);
XCTAssertEqual(value, 602.);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getDouble:&value forKey:34ULL]);
XCTAssertEqual(value, 601.);
const uint64_t kKeys2[] = { 32ULL, 33ULL };
const double kValues2[] = { 602., 600. };
GPBUInt64DoubleDictionary *dict2 =
- [[GPBUInt64DoubleDictionary alloc] initWithValues:kValues2
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBUInt64DoubleDictionary alloc] initWithDoubles:kValues2
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getDouble:&value forKey:31ULL]);
XCTAssertEqual(value, 603.);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getDouble:&value forKey:32ULL]);
XCTAssertEqual(value, 602.);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getDouble:&value forKey:33ULL]);
XCTAssertEqual(value, 600.);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getDouble:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getDouble:&value forKey:34ULL]);
XCTAssertEqual(value, 601.);
[dict2 release];
@@ -2593,8 +2593,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
GPBUInt64EnumDictionary *dict = [[GPBUInt64EnumDictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:31ULL value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(uint64_t aKey, int32_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getEnum:NULL forKey:31ULL]);
+ [dict enumerateKeysAndEnumsUsingBlock:^(uint64_t aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -2602,15 +2602,15 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testOne {
- GPBUInt64EnumDictionary *dict = [GPBUInt64EnumDictionary dictionaryWithValue:700 forKey:31ULL];
+ GPBUInt64EnumDictionary *dict = [GPBUInt64EnumDictionary dictionaryWithEnum:700 forKey:31ULL];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
int32_t value;
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:31ULL]);
XCTAssertEqual(value, 700);
- XCTAssertFalse([dict valueForKey:32ULL value:NULL]);
- [dict enumerateKeysAndValuesUsingBlock:^(uint64_t aKey, int32_t aValue, BOOL *stop) {
+ XCTAssertFalse([dict getEnum:NULL forKey:32ULL]);
+ [dict enumerateKeysAndEnumsUsingBlock:^(uint64_t aKey, int32_t aValue, BOOL *stop) {
XCTAssertEqual(aKey, 31ULL);
XCTAssertEqual(aValue, 700);
XCTAssertNotEqual(stop, NULL);
@@ -2621,27 +2621,27 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL };
const int32_t kValues[] = { 700, 701, 702 };
GPBUInt64EnumDictionary *dict =
- [[GPBUInt64EnumDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt64EnumDictionary alloc] initWithEnums:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 3U);
int32_t value;
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:31ULL]);
XCTAssertEqual(value, 700);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:32ULL]);
XCTAssertEqual(value, 701);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:33ULL]);
XCTAssertEqual(value, 702);
- XCTAssertFalse([dict valueForKey:34ULL value:NULL]);
+ XCTAssertFalse([dict getEnum:NULL forKey:34ULL]);
__block NSUInteger idx = 0;
uint64_t *seenKeys = malloc(3 * sizeof(uint64_t));
int32_t *seenValues = malloc(3 * sizeof(int32_t));
- [dict enumerateKeysAndValuesUsingBlock:^(uint64_t aKey, int32_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndEnumsUsingBlock:^(uint64_t aKey, int32_t aValue, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -2663,7 +2663,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndValuesUsingBlock:^(uint64_t aKey, int32_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndEnumsUsingBlock:^(uint64_t aKey, int32_t aValue, BOOL *stop) {
#pragma unused(aKey, aValue)
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -2679,29 +2679,29 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const int32_t kValues2[] = { 700, 703, 702 };
const int32_t kValues3[] = { 700, 701, 702, 703 };
GPBUInt64EnumDictionary *dict1 =
- [[GPBUInt64EnumDictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBUInt64EnumDictionary alloc] initWithEnums:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1);
GPBUInt64EnumDictionary *dict1prime =
- [[GPBUInt64EnumDictionary alloc] initWithValues:kValues1
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBUInt64EnumDictionary alloc] initWithEnums:kValues1
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict1prime);
GPBUInt64EnumDictionary *dict2 =
- [[GPBUInt64EnumDictionary alloc] initWithValues:kValues2
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBUInt64EnumDictionary alloc] initWithEnums:kValues2
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
GPBUInt64EnumDictionary *dict3 =
- [[GPBUInt64EnumDictionary alloc] initWithValues:kValues1
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues1)];
+ [[GPBUInt64EnumDictionary alloc] initWithEnums:kValues1
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues1)];
XCTAssertNotNil(dict3);
GPBUInt64EnumDictionary *dict4 =
- [[GPBUInt64EnumDictionary alloc] initWithValues:kValues3
- forKeys:kKeys1
- count:GPBARRAYSIZE(kValues3)];
+ [[GPBUInt64EnumDictionary alloc] initWithEnums:kValues3
+ forKeys:kKeys1
+ count:GPBARRAYSIZE(kValues3)];
XCTAssertNotNil(dict4);
// 1/1Prime should be different objects, but equal.
@@ -2730,9 +2730,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
const int32_t kValues[] = { 700, 701, 702, 703 };
GPBUInt64EnumDictionary *dict =
- [[GPBUInt64EnumDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt64EnumDictionary alloc] initWithEnums:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBUInt64EnumDictionary *dict2 = [dict copy];
@@ -2751,9 +2751,9 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
const int32_t kValues[] = { 700, 701, 702, 703 };
GPBUInt64EnumDictionary *dict =
- [[GPBUInt64EnumDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt64EnumDictionary alloc] initWithEnums:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
GPBUInt64EnumDictionary *dict2 =
@@ -2771,31 +2771,31 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- [dict setValue:700 forKey:31ULL];
+ [dict setEnum:700 forKey:31ULL];
XCTAssertEqual(dict.count, 1U);
const uint64_t kKeys[] = { 32ULL, 33ULL, 34ULL };
const int32_t kValues[] = { 701, 702, 703 };
GPBUInt64EnumDictionary *dict2 =
- [[GPBUInt64EnumDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt64EnumDictionary alloc] initWithEnums:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
[dict addRawEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
int32_t value;
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:31ULL]);
XCTAssertEqual(value, 700);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:32ULL]);
XCTAssertEqual(value, 701);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:33ULL]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:34ULL]);
XCTAssertEqual(value, 703);
[dict2 release];
}
@@ -2804,57 +2804,57 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
const int32_t kValues[] = { 700, 701, 702, 703 };
GPBUInt64EnumDictionary *dict =
- [[GPBUInt64EnumDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt64EnumDictionary alloc] initWithEnums:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
- [dict removeValueForKey:32ULL];
+ [dict removeEnumForKey:32ULL];
XCTAssertEqual(dict.count, 3U);
int32_t value;
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:31ULL]);
XCTAssertEqual(value, 700);
- XCTAssertFalse([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertFalse([dict getEnum:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getEnum:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:33ULL]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:34ULL]);
XCTAssertEqual(value, 703);
// Remove again does nothing.
- [dict removeValueForKey:32ULL];
+ [dict removeEnumForKey:32ULL];
XCTAssertEqual(dict.count, 3U);
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:31ULL]);
XCTAssertEqual(value, 700);
- XCTAssertFalse([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertFalse([dict getEnum:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getEnum:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:33ULL]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:34ULL]);
XCTAssertEqual(value, 703);
- [dict removeValueForKey:34ULL];
+ [dict removeEnumForKey:34ULL];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:31ULL]);
XCTAssertEqual(value, 700);
- XCTAssertFalse([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertFalse([dict getEnum:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getEnum:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:33ULL]);
XCTAssertEqual(value, 702);
- XCTAssertFalse([dict valueForKey:34ULL value:NULL]);
+ XCTAssertFalse([dict getEnum:NULL forKey:34ULL]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:31ULL value:NULL]);
- XCTAssertFalse([dict valueForKey:32ULL value:NULL]);
- XCTAssertFalse([dict valueForKey:33ULL value:NULL]);
- XCTAssertFalse([dict valueForKey:34ULL value:NULL]);
+ XCTAssertFalse([dict getEnum:NULL forKey:31ULL]);
+ XCTAssertFalse([dict getEnum:NULL forKey:32ULL]);
+ XCTAssertFalse([dict getEnum:NULL forKey:33ULL]);
+ XCTAssertFalse([dict getEnum:NULL forKey:34ULL]);
[dict release];
}
@@ -2862,75 +2862,75 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
const int32_t kValues[] = { 700, 701, 702, 703 };
GPBUInt64EnumDictionary *dict =
- [[GPBUInt64EnumDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt64EnumDictionary alloc] initWithEnums:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
int32_t value;
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:31ULL]);
XCTAssertEqual(value, 700);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:32ULL]);
XCTAssertEqual(value, 701);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:33ULL]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:34ULL]);
XCTAssertEqual(value, 703);
- [dict setValue:703 forKey:31ULL];
+ [dict setEnum:703 forKey:31ULL];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:31ULL]);
XCTAssertEqual(value, 703);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:32ULL]);
XCTAssertEqual(value, 701);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:33ULL]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:34ULL]);
XCTAssertEqual(value, 703);
- [dict setValue:701 forKey:34ULL];
+ [dict setEnum:701 forKey:34ULL];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:31ULL]);
XCTAssertEqual(value, 703);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:32ULL]);
XCTAssertEqual(value, 701);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:33ULL]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:34ULL]);
XCTAssertEqual(value, 701);
const uint64_t kKeys2[] = { 32ULL, 33ULL };
const int32_t kValues2[] = { 702, 700 };
GPBUInt64EnumDictionary *dict2 =
- [[GPBUInt64EnumDictionary alloc] initWithValues:kValues2
- forKeys:kKeys2
- count:GPBARRAYSIZE(kValues2)];
+ [[GPBUInt64EnumDictionary alloc] initWithEnums:kValues2
+ forKeys:kKeys2
+ count:GPBARRAYSIZE(kValues2)];
XCTAssertNotNil(dict2);
[dict addRawEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:31ULL]);
XCTAssertEqual(value, 703);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:32ULL]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:33ULL]);
XCTAssertEqual(value, 700);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:34ULL]);
XCTAssertEqual(value, 701);
[dict2 release];
@@ -2958,24 +2958,24 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertEqual(dict.count, 3U);
XCTAssertTrue(dict.validationFunc == TestingEnum_IsValidValue); // Pointer comparison
int32_t value;
- XCTAssertTrue([dict valueForKey:31ULL rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getRawValue:&value forKey:31ULL]);
XCTAssertEqual(value, 700);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:32ULL]);
XCTAssertEqual(value, kGPBUnrecognizedEnumeratorValue);
- XCTAssertTrue([dict valueForKey:32ULL rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getRawValue:&value forKey:32ULL]);
XCTAssertEqual(value, 801);
- XCTAssertTrue([dict valueForKey:33ULL rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getRawValue:&value forKey:33ULL]);
XCTAssertEqual(value, 702);
- XCTAssertFalse([dict valueForKey:34ULL rawValue:NULL]);
+ XCTAssertFalse([dict getRawValue:NULL forKey:34ULL]);
__block NSUInteger idx = 0;
uint64_t *seenKeys = malloc(3 * sizeof(uint64_t));
int32_t *seenValues = malloc(3 * sizeof(int32_t));
- [dict enumerateKeysAndValuesUsingBlock:^(uint64_t aKey, int32_t aValue, BOOL *stop) {
+ [dict enumerateKeysAndEnumsUsingBlock:^(uint64_t aKey, int32_t aValue, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenValues[idx] = aValue;
@@ -3136,7 +3136,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
- XCTAssertThrowsSpecificNamed([dict setValue:801 forKey:32ULL], // Unknown
+ XCTAssertThrowsSpecificNamed([dict setEnum:801 forKey:32ULL], // Unknown
NSException, NSInvalidArgumentException);
XCTAssertEqual(dict.count, 0U);
[dict setRawValue:801 forKey:32ULL]; // Unknown
@@ -3145,31 +3145,31 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
const uint64_t kKeys[] = { 31ULL, 33ULL, 34ULL };
const int32_t kValues[] = { 700, 702, 803 }; // Unknown
GPBUInt64EnumDictionary *dict2 =
- [[GPBUInt64EnumDictionary alloc] initWithValues:kValues
- forKeys:kKeys
- count:GPBARRAYSIZE(kValues)];
+ [[GPBUInt64EnumDictionary alloc] initWithEnums:kValues
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kValues)];
XCTAssertNotNil(dict2);
[dict addRawEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
int32_t value;
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:31ULL]);
XCTAssertEqual(value, 700);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:32ULL]);
XCTAssertEqual(value, kGPBUnrecognizedEnumeratorValue);
- XCTAssertTrue([dict valueForKey:32ULL rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getRawValue:&value forKey:32ULL]);
XCTAssertEqual(value, 801);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:33ULL]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:34ULL]);
XCTAssertEqual(value, kGPBUnrecognizedEnumeratorValue);
- XCTAssertTrue([dict valueForKey:34ULL rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getRawValue:&value forKey:34ULL]);
XCTAssertEqual(value, 803);
[dict2 release];
}
@@ -3185,51 +3185,51 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
- [dict removeValueForKey:32ULL];
+ [dict removeEnumForKey:32ULL];
XCTAssertEqual(dict.count, 3U);
int32_t value;
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:31ULL]);
XCTAssertEqual(value, 700);
- XCTAssertFalse([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertFalse([dict getEnum:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getEnum:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:33ULL]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:34ULL rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getRawValue:&value forKey:34ULL]);
XCTAssertEqual(value, 803);
// Remove again does nothing.
- [dict removeValueForKey:32ULL];
+ [dict removeEnumForKey:32ULL];
XCTAssertEqual(dict.count, 3U);
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:31ULL]);
XCTAssertEqual(value, 700);
- XCTAssertFalse([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertFalse([dict getEnum:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getEnum:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:33ULL]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:34ULL rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getRawValue:&value forKey:34ULL]);
XCTAssertEqual(value, 803);
- [dict removeValueForKey:34ULL];
+ [dict removeEnumForKey:34ULL];
XCTAssertEqual(dict.count, 2U);
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:31ULL]);
XCTAssertEqual(value, 700);
- XCTAssertFalse([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertFalse([dict getEnum:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getEnum:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:33ULL]);
XCTAssertEqual(value, 702);
- XCTAssertFalse([dict valueForKey:34ULL value:NULL]);
+ XCTAssertFalse([dict getEnum:NULL forKey:34ULL]);
[dict removeAll];
XCTAssertEqual(dict.count, 0U);
- XCTAssertFalse([dict valueForKey:31ULL value:NULL]);
- XCTAssertFalse([dict valueForKey:32ULL value:NULL]);
- XCTAssertFalse([dict valueForKey:33ULL value:NULL]);
- XCTAssertFalse([dict valueForKey:34ULL value:NULL]);
+ XCTAssertFalse([dict getEnum:NULL forKey:31ULL]);
+ XCTAssertFalse([dict getEnum:NULL forKey:32ULL]);
+ XCTAssertFalse([dict getEnum:NULL forKey:33ULL]);
+ XCTAssertFalse([dict getEnum:NULL forKey:34ULL]);
[dict release];
}
@@ -3244,63 +3244,63 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
int32_t value;
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:31ULL]);
XCTAssertEqual(value, 700);
- XCTAssertTrue([dict valueForKey:32ULL rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getRawValue:&value forKey:32ULL]);
XCTAssertEqual(value, 801);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:33ULL]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:34ULL rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getRawValue:&value forKey:34ULL]);
XCTAssertEqual(value, 803);
- XCTAssertThrowsSpecificNamed([dict setValue:803 forKey:31ULL], // Unknown
+ XCTAssertThrowsSpecificNamed([dict setEnum:803 forKey:31ULL], // Unknown
NSException, NSInvalidArgumentException);
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:31ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:31ULL]);
XCTAssertEqual(value, 700);
- XCTAssertTrue([dict valueForKey:32ULL rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getRawValue:&value forKey:32ULL]);
XCTAssertEqual(value, 801);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:33ULL]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:34ULL rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getRawValue:&value forKey:34ULL]);
XCTAssertEqual(value, 803);
[dict setRawValue:803 forKey:31ULL]; // Unknown
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:31ULL rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getRawValue:&value forKey:31ULL]);
XCTAssertEqual(value, 803);
- XCTAssertTrue([dict valueForKey:32ULL rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getRawValue:&value forKey:32ULL]);
XCTAssertEqual(value, 801);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:33ULL]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:34ULL rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getRawValue:&value forKey:34ULL]);
XCTAssertEqual(value, 803);
[dict setRawValue:700 forKey:34ULL];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:31ULL rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getRawValue:&value forKey:31ULL]);
XCTAssertEqual(value, 803);
- XCTAssertTrue([dict valueForKey:32ULL rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getRawValue:&value forKey:32ULL]);
XCTAssertEqual(value, 801);
- XCTAssertTrue([dict valueForKey:33ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:33ULL]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:34ULL]);
XCTAssertEqual(value, 700);
const uint64_t kKeys2[] = { 32ULL, 33ULL };
@@ -3313,17 +3313,17 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertNotNil(dict2);
[dict addRawEntriesFromDictionary:dict2];
XCTAssertEqual(dict.count, 4U);
- XCTAssertTrue([dict valueForKey:31ULL rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:31ULL rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:31ULL]);
+ XCTAssertTrue([dict getRawValue:&value forKey:31ULL]);
XCTAssertEqual(value, 803);
- XCTAssertTrue([dict valueForKey:32ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:32ULL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:32ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:32ULL]);
XCTAssertEqual(value, 702);
- XCTAssertTrue([dict valueForKey:33ULL rawValue:NULL]);
- XCTAssertTrue([dict valueForKey:33ULL rawValue:&value]);
+ XCTAssertTrue([dict getRawValue:NULL forKey:33ULL]);
+ XCTAssertTrue([dict getRawValue:&value forKey:33ULL]);
XCTAssertEqual(value, 801);
- XCTAssertTrue([dict valueForKey:34ULL value:NULL]);
- XCTAssertTrue([dict valueForKey:34ULL value:&value]);
+ XCTAssertTrue([dict getEnum:NULL forKey:34ULL]);
+ XCTAssertTrue([dict getEnum:&value forKey:34ULL]);
XCTAssertEqual(value, 700);
[dict2 release];
@@ -3363,11 +3363,11 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
@implementation GPBUInt64ObjectDictionaryTests
- (void)testEmpty {
- GPBUInt64ObjectDictionary *dict = [[GPBUInt64ObjectDictionary alloc] init];
+ GPBUInt64ObjectDictionary<NSString*> *dict = [[GPBUInt64ObjectDictionary alloc] init];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
XCTAssertNil([dict objectForKey:31ULL]);
- [dict enumerateKeysAndObjectsUsingBlock:^(uint64_t aKey, id aObject, BOOL *stop) {
+ [dict enumerateKeysAndObjectsUsingBlock:^(uint64_t aKey, NSString* aObject, BOOL *stop) {
#pragma unused(aKey, aObject, stop)
XCTFail(@"Shouldn't get here!");
}];
@@ -3375,12 +3375,12 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testOne {
- GPBUInt64ObjectDictionary *dict = [GPBUInt64ObjectDictionary dictionaryWithObject:@"abc" forKey:31ULL];
+ GPBUInt64ObjectDictionary<NSString*> *dict = [GPBUInt64ObjectDictionary dictionaryWithObject:@"abc" forKey:31ULL];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 1U);
XCTAssertEqualObjects([dict objectForKey:31ULL], @"abc");
XCTAssertNil([dict objectForKey:32ULL]);
- [dict enumerateKeysAndObjectsUsingBlock:^(uint64_t aKey, id aObject, BOOL *stop) {
+ [dict enumerateKeysAndObjectsUsingBlock:^(uint64_t aKey, NSString* aObject, BOOL *stop) {
XCTAssertEqual(aKey, 31ULL);
XCTAssertEqualObjects(aObject, @"abc");
XCTAssertNotEqual(stop, NULL);
@@ -3389,8 +3389,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
- (void)testBasics {
const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL };
- const id kObjects[] = { @"abc", @"def", @"ghi" };
- GPBUInt64ObjectDictionary *dict =
+ const NSString* kObjects[] = { @"abc", @"def", @"ghi" };
+ GPBUInt64ObjectDictionary<NSString*> *dict =
[[GPBUInt64ObjectDictionary alloc] initWithObjects:kObjects
forKeys:kKeys
count:GPBARRAYSIZE(kObjects)];
@@ -3403,8 +3403,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
__block NSUInteger idx = 0;
uint64_t *seenKeys = malloc(3 * sizeof(uint64_t));
- id *seenObjects = malloc(3 * sizeof(id));
- [dict enumerateKeysAndObjectsUsingBlock:^(uint64_t aKey, id aObject, BOOL *stop) {
+ NSString* *seenObjects = malloc(3 * sizeof(NSString*));
+ [dict enumerateKeysAndObjectsUsingBlock:^(uint64_t aKey, NSString* aObject, BOOL *stop) {
XCTAssertLessThan(idx, 3U);
seenKeys[idx] = aKey;
seenObjects[idx] = aObject;
@@ -3426,7 +3426,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
// Stopping the enumeration.
idx = 0;
- [dict enumerateKeysAndObjectsUsingBlock:^(uint64_t aKey, id aObject, BOOL *stop) {
+ [dict enumerateKeysAndObjectsUsingBlock:^(uint64_t aKey, NSString* aObject, BOOL *stop) {
#pragma unused(aKey, aObject)
if (idx == 1) *stop = YES;
XCTAssertNotEqual(idx, 2U);
@@ -3438,30 +3438,30 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
- (void)testEquality {
const uint64_t kKeys1[] = { 31ULL, 32ULL, 33ULL, 34ULL };
const uint64_t kKeys2[] = { 32ULL, 31ULL, 34ULL };
- const id kObjects1[] = { @"abc", @"def", @"ghi" };
- const id kObjects2[] = { @"abc", @"jkl", @"ghi" };
- const id kObjects3[] = { @"abc", @"def", @"ghi", @"jkl" };
- GPBUInt64ObjectDictionary *dict1 =
+ const NSString* kObjects1[] = { @"abc", @"def", @"ghi" };
+ const NSString* kObjects2[] = { @"abc", @"jkl", @"ghi" };
+ const NSString* kObjects3[] = { @"abc", @"def", @"ghi", @"jkl" };
+ GPBUInt64ObjectDictionary<NSString*> *dict1 =
[[GPBUInt64ObjectDictionary alloc] initWithObjects:kObjects1
forKeys:kKeys1
count:GPBARRAYSIZE(kObjects1)];
XCTAssertNotNil(dict1);
- GPBUInt64ObjectDictionary *dict1prime =
+ GPBUInt64ObjectDictionary<NSString*> *dict1prime =
[[GPBUInt64ObjectDictionary alloc] initWithObjects:kObjects1
forKeys:kKeys1
count:GPBARRAYSIZE(kObjects1)];
XCTAssertNotNil(dict1prime);
- GPBUInt64ObjectDictionary *dict2 =
+ GPBUInt64ObjectDictionary<NSString*> *dict2 =
[[GPBUInt64ObjectDictionary alloc] initWithObjects:kObjects2
forKeys:kKeys1
count:GPBARRAYSIZE(kObjects2)];
XCTAssertNotNil(dict2);
- GPBUInt64ObjectDictionary *dict3 =
+ GPBUInt64ObjectDictionary<NSString*> *dict3 =
[[GPBUInt64ObjectDictionary alloc] initWithObjects:kObjects1
forKeys:kKeys2
count:GPBARRAYSIZE(kObjects1)];
XCTAssertNotNil(dict3);
- GPBUInt64ObjectDictionary *dict4 =
+ GPBUInt64ObjectDictionary<NSString*> *dict4 =
[[GPBUInt64ObjectDictionary alloc] initWithObjects:kObjects3
forKeys:kKeys1
count:GPBARRAYSIZE(kObjects3)];
@@ -3491,14 +3491,14 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
- (void)testCopy {
const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
- const id kObjects[] = { @"abc", @"def", @"ghi", @"jkl" };
- GPBUInt64ObjectDictionary *dict =
+ const NSString* kObjects[] = { @"abc", @"def", @"ghi", @"jkl" };
+ GPBUInt64ObjectDictionary<NSString*> *dict =
[[GPBUInt64ObjectDictionary alloc] initWithObjects:kObjects
forKeys:kKeys
count:GPBARRAYSIZE(kObjects)];
XCTAssertNotNil(dict);
- GPBUInt64ObjectDictionary *dict2 = [dict copy];
+ GPBUInt64ObjectDictionary<NSString*> *dict2 = [dict copy];
XCTAssertNotNil(dict2);
// Should be new object but equal.
@@ -3512,14 +3512,14 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
- (void)testDictionaryFromDictionary {
const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
- const id kObjects[] = { @"abc", @"def", @"ghi", @"jkl" };
- GPBUInt64ObjectDictionary *dict =
+ const NSString* kObjects[] = { @"abc", @"def", @"ghi", @"jkl" };
+ GPBUInt64ObjectDictionary<NSString*> *dict =
[[GPBUInt64ObjectDictionary alloc] initWithObjects:kObjects
forKeys:kKeys
count:GPBARRAYSIZE(kObjects)];
XCTAssertNotNil(dict);
- GPBUInt64ObjectDictionary *dict2 =
+ GPBUInt64ObjectDictionary<NSString*> *dict2 =
[GPBUInt64ObjectDictionary dictionaryWithDictionary:dict];
XCTAssertNotNil(dict2);
@@ -3530,7 +3530,7 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
}
- (void)testAdds {
- GPBUInt64ObjectDictionary *dict = [GPBUInt64ObjectDictionary dictionary];
+ GPBUInt64ObjectDictionary<NSString*> *dict = [GPBUInt64ObjectDictionary dictionary];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 0U);
@@ -3538,8 +3538,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertEqual(dict.count, 1U);
const uint64_t kKeys[] = { 32ULL, 33ULL, 34ULL };
- const id kObjects[] = { @"def", @"ghi", @"jkl" };
- GPBUInt64ObjectDictionary *dict2 =
+ const NSString* kObjects[] = { @"def", @"ghi", @"jkl" };
+ GPBUInt64ObjectDictionary<NSString*> *dict2 =
[[GPBUInt64ObjectDictionary alloc] initWithObjects:kObjects
forKeys:kKeys
count:GPBARRAYSIZE(kObjects)];
@@ -3556,11 +3556,11 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
- (void)testRemove {
const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
- const id kObjects[] = { @"abc", @"def", @"ghi", @"jkl" };
- GPBUInt64ObjectDictionary *dict =
+ const NSString* kObjects[] = { @"abc", @"def", @"ghi", @"jkl" };
+ GPBUInt64ObjectDictionary<NSString*> *dict =
[[GPBUInt64ObjectDictionary alloc] initWithObjects:kObjects
- forKeys:kKeys
- count:GPBARRAYSIZE(kObjects)];
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kObjects)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
@@ -3597,11 +3597,11 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
- (void)testInplaceMutation {
const uint64_t kKeys[] = { 31ULL, 32ULL, 33ULL, 34ULL };
- const id kObjects[] = { @"abc", @"def", @"ghi", @"jkl" };
- GPBUInt64ObjectDictionary *dict =
+ const NSString* kObjects[] = { @"abc", @"def", @"ghi", @"jkl" };
+ GPBUInt64ObjectDictionary<NSString*> *dict =
[[GPBUInt64ObjectDictionary alloc] initWithObjects:kObjects
- forKeys:kKeys
- count:GPBARRAYSIZE(kObjects)];
+ forKeys:kKeys
+ count:GPBARRAYSIZE(kObjects)];
XCTAssertNotNil(dict);
XCTAssertEqual(dict.count, 4U);
XCTAssertEqualObjects([dict objectForKey:31ULL], @"abc");
@@ -3624,8 +3624,8 @@ static BOOL TestingEnum_IsValidValue(int32_t value) {
XCTAssertEqualObjects([dict objectForKey:34ULL], @"def");
const uint64_t kKeys2[] = { 32ULL, 33ULL };
- const id kObjects2[] = { @"ghi", @"abc" };
- GPBUInt64ObjectDictionary *dict2 =
+ const NSString* kObjects2[] = { @"ghi", @"abc" };
+ GPBUInt64ObjectDictionary<NSString*> *dict2 =
[[GPBUInt64ObjectDictionary alloc] initWithObjects:kObjects2
forKeys:kKeys2
count:GPBARRAYSIZE(kObjects2)];
diff --git a/objectivec/Tests/GPBDictionaryTests.pddm b/objectivec/Tests/GPBDictionaryTests.pddm
index ada93c64..d6aa7211 100644
--- a/objectivec/Tests/GPBDictionaryTests.pddm
+++ b/objectivec/Tests/GPBDictionaryTests.pddm
@@ -30,7 +30,7 @@
//%PDDM-DEFINE TEST_FOR_POD_KEY(KEY_NAME, KEY_TYPE, KEY1, KEY2, KEY3, KEY4)
//%TESTS_FOR_POD_VALUES(KEY_NAME, KEY_TYPE, , , KEY1, KEY2, KEY3, KEY4)
-//%TESTS_FOR_POD_KEY_OBJECT_VALUE(KEY_NAME, KEY_TYPE, KEY1, KEY2, KEY3, KEY4, Object, id, @"abc", @"def", @"ghi", @"jkl")
+//%TESTS_FOR_POD_KEY_OBJECT_VALUE(KEY_NAME, KEY_TYPE, KEY1, KEY2, KEY3, KEY4, Object, NSString*, @"abc", @"def", @"ghi", @"jkl")
//%PDDM-DEFINE TESTS_FOR_POD_VALUES(KEY_NAME, KEY_TYPE, KisP, KSUFFIX, KEY1, KEY2, KEY3, KEY4)
//%TEST_HELPERS(KEY_NAME, KEY_TYPE, KisP)
@@ -50,6 +50,13 @@
//%PDDM-DEFINE TESTS_FOR_POD_KEY_OBJECT_VALUE(KEY_NAME, KEY_TYPE, KEY1, KEY2, KEY3, KEY4, VALUE_NAME, VALUE_TYPE, VAL1, VAL2, VAL3, VAL4)
//%TESTS_COMMON(KEY_NAME, KEY_TYPE, , , KEY1, KEY2, KEY3, KEY4, VALUE_NAME, VALUE_TYPE, Objects, object, OBJECT, , VAL1, VAL2, VAL3, VAL4)
+//%PDDM-DEFINE DICTIONARY_CLASS_DECLPOD(KEY_NAME, VALUE_NAME, VALUE_TYPE)
+//%GPB##KEY_NAME##VALUE_NAME##Dictionary
+//%PDDM-DEFINE DICTIONARY_CLASS_DECLEnum(KEY_NAME, VALUE_NAME, VALUE_TYPE)
+//%GPB##KEY_NAME##VALUE_NAME##Dictionary
+//%PDDM-DEFINE DICTIONARY_CLASS_DECLOBJECT(KEY_NAME, VALUE_NAME, VALUE_TYPE)
+//%GPB##KEY_NAME##VALUE_NAME##Dictionary<VALUE_TYPE>
+
//%PDDM-DEFINE TESTS_COMMON(KEY_NAME, KEY_TYPE, KisP, KSUFFIX, KEY1, KEY2, KEY3, KEY4, VALUE_NAME, VALUE_TYPE, VSUFFIX, VNAME, VHELPER, VACCESSOR, VAL1, VAL2, VAL3, VAL4)
//%#pragma mark - KEY_NAME -> VALUE_NAME
//%
@@ -59,11 +66,11 @@
//%@implementation GPB##KEY_NAME##VALUE_NAME##DictionaryTests
//%
//%- (void)testEmpty {
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict = [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] init];
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict = [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] init];
//% XCTAssertNotNil(dict);
//% XCTAssertEqual(dict.count, 0U);
-//%VALUE_NOT_FOUND##VHELPER(dict, KEY1)
-//% [dict enumerateKeysAnd##VNAME$u##sUsingBlock:^(KEY_TYPE KisP##aKey, VALUE_TYPE a##VNAME$u, BOOL *stop) {
+//%VALUE_NOT_FOUND##VHELPER(VALUE_NAME, dict, KEY1)
+//% [dict enumerateKeysAnd##VALUE_NAME$u##sUsingBlock:^(KEY_TYPE KisP##aKey, VALUE_TYPE a##VNAME$u, BOOL *stop) {
//% #pragma unused(aKey, a##VNAME$u, stop)
//% XCTFail(@"Shouldn't get here!");
//% }];
@@ -71,12 +78,12 @@
//%}
//%
//%- (void)testOne {
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict = [GPB##KEY_NAME##VALUE_NAME##Dictionary dictionaryWith##VNAME$u##:VAL1 forKey:KEY1];
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict = [GPB##KEY_NAME##VALUE_NAME##Dictionary dictionaryWith##VALUE_NAME$u##:VAL1 forKey:KEY1];
//% XCTAssertNotNil(dict);
//% XCTAssertEqual(dict.count, 1U);
-//%DECLARE_VALUE_STORAGE##VHELPER(VALUE_TYPE, VNAME)TEST_VALUE##VHELPER(dict, VNAME, KEY1, VAL1)
-//%VALUE_NOT_FOUND##VHELPER(dict, KEY2)
-//% [dict enumerateKeysAnd##VNAME$u##sUsingBlock:^(KEY_TYPE KisP##aKey, VALUE_TYPE a##VNAME$u, BOOL *stop) {
+//%DECLARE_VALUE_STORAGE##VHELPER(VALUE_TYPE, VNAME)TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY1, VAL1)
+//%VALUE_NOT_FOUND##VHELPER(VALUE_NAME, dict, KEY2)
+//% [dict enumerateKeysAnd##VALUE_NAME$u##sUsingBlock:^(KEY_TYPE KisP##aKey, VALUE_TYPE a##VNAME$u, BOOL *stop) {
//% XCTAssertEqual##KSUFFIX(aKey, KEY1);
//% XCTAssertEqual##VSUFFIX(a##VNAME$u, VAL1);
//% XCTAssertNotEqual(stop, NULL);
@@ -86,21 +93,21 @@
//%- (void)testBasics {
//% const KEY_TYPE KisP##kKeys[] = { KEY1, KEY2, KEY3 };
//% const VALUE_TYPE k##VNAME$u##s[] = { VAL1, VAL2, VAL3 };
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict =
-//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## forKeys:kKeys
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## count:GPBARRAYSIZE(k##VNAME$u##s)];
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict =
+//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VALUE_NAME$u##s:k##VNAME$u##s
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## forKeys:kKeys
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## count:GPBARRAYSIZE(k##VNAME$u##s)];
//% XCTAssertNotNil(dict);
//% XCTAssertEqual(dict.count, 3U);
-//%DECLARE_VALUE_STORAGE##VHELPER(VALUE_TYPE, VNAME)TEST_VALUE##VHELPER(dict, VNAME, KEY1, VAL1)
-//%TEST_VALUE##VHELPER(dict, VNAME, KEY2, VAL2)
-//%TEST_VALUE##VHELPER(dict, VNAME, KEY3, VAL3)
-//%VALUE_NOT_FOUND##VHELPER(dict, KEY4)
+//%DECLARE_VALUE_STORAGE##VHELPER(VALUE_TYPE, VNAME)TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY1, VAL1)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY2, VAL2)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY3, VAL3)
+//%VALUE_NOT_FOUND##VHELPER(VALUE_NAME, dict, KEY4)
//%
//% __block NSUInteger idx = 0;
//% KEY_TYPE KisP##*seenKeys = malloc(3 * sizeof(KEY_TYPE##KisP));
//% VALUE_TYPE *seen##VNAME$u##s = malloc(3 * sizeof(VALUE_TYPE));
-//% [dict enumerateKeysAnd##VNAME$u##sUsingBlock:^(KEY_TYPE KisP##aKey, VALUE_TYPE a##VNAME$u, BOOL *stop) {
+//% [dict enumerateKeysAnd##VALUE_NAME$u##sUsingBlock:^(KEY_TYPE KisP##aKey, VALUE_TYPE a##VNAME$u, BOOL *stop) {
//% XCTAssertLessThan(idx, 3U);
//% seenKeys[idx] = aKey;
//% seen##VNAME$u##s[idx] = a##VNAME$u##;
@@ -122,7 +129,7 @@
//%
//% // Stopping the enumeration.
//% idx = 0;
-//% [dict enumerateKeysAnd##VNAME$u##sUsingBlock:^(KEY_TYPE KisP##aKey, VALUE_TYPE a##VNAME$u, BOOL *stop) {
+//% [dict enumerateKeysAnd##VALUE_NAME$u##sUsingBlock:^(KEY_TYPE KisP##aKey, VALUE_TYPE a##VNAME$u, BOOL *stop) {
//% #pragma unused(aKey, a##VNAME$u)
//% if (idx == 1) *stop = YES;
//% XCTAssertNotEqual(idx, 2U);
@@ -137,30 +144,30 @@
//% const VALUE_TYPE k##VNAME$u##s1[] = { VAL1, VAL2, VAL3 };
//% const VALUE_TYPE k##VNAME$u##s2[] = { VAL1, VAL4, VAL3 };
//% const VALUE_TYPE k##VNAME$u##s3[] = { VAL1, VAL2, VAL3, VAL4 };
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict1 =
-//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s1
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## forKeys:kKeys1
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## count:GPBARRAYSIZE(k##VNAME$u##s1)];
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict1 =
+//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VALUE_NAME##s:k##VNAME$u##s1
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## forKeys:kKeys1
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## count:GPBARRAYSIZE(k##VNAME$u##s1)];
//% XCTAssertNotNil(dict1);
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict1prime =
-//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s1
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## forKeys:kKeys1
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## count:GPBARRAYSIZE(k##VNAME$u##s1)];
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict1prime =
+//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VALUE_NAME##s:k##VNAME$u##s1
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## forKeys:kKeys1
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## count:GPBARRAYSIZE(k##VNAME$u##s1)];
//% XCTAssertNotNil(dict1prime);
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict2 =
-//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s2
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## forKeys:kKeys1
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## count:GPBARRAYSIZE(k##VNAME$u##s2)];
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict2 =
+//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VALUE_NAME##s:k##VNAME$u##s2
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## forKeys:kKeys1
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## count:GPBARRAYSIZE(k##VNAME$u##s2)];
//% XCTAssertNotNil(dict2);
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict3 =
-//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s1
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## forKeys:kKeys2
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## count:GPBARRAYSIZE(k##VNAME$u##s1)];
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict3 =
+//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VALUE_NAME##s:k##VNAME$u##s1
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## forKeys:kKeys2
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## count:GPBARRAYSIZE(k##VNAME$u##s1)];
//% XCTAssertNotNil(dict3);
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict4 =
-//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s3
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## forKeys:kKeys1
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## count:GPBARRAYSIZE(k##VNAME$u##s3)];
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict4 =
+//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VALUE_NAME##s:k##VNAME$u##s3
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## forKeys:kKeys1
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## count:GPBARRAYSIZE(k##VNAME$u##s3)];
//% XCTAssertNotNil(dict4);
//%
//% // 1/1Prime should be different objects, but equal.
@@ -188,13 +195,13 @@
//%- (void)testCopy {
//% const KEY_TYPE KisP##kKeys[] = { KEY1, KEY2, KEY3, KEY4 };
//% const VALUE_TYPE k##VNAME$u##s[] = { VAL1, VAL2, VAL3, VAL4 };
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict =
-//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## forKeys:kKeys
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## count:GPBARRAYSIZE(k##VNAME$u##s)];
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict =
+//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VALUE_NAME##s:k##VNAME$u##s
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## forKeys:kKeys
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## count:GPBARRAYSIZE(k##VNAME$u##s)];
//% XCTAssertNotNil(dict);
//%
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict2 = [dict copy];
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict2 = [dict copy];
//% XCTAssertNotNil(dict2);
//%
//% // Should be new object but equal.
@@ -209,13 +216,13 @@
//%- (void)testDictionaryFromDictionary {
//% const KEY_TYPE KisP##kKeys[] = { KEY1, KEY2, KEY3, KEY4 };
//% const VALUE_TYPE k##VNAME$u##s[] = { VAL1, VAL2, VAL3, VAL4 };
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict =
-//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## forKeys:kKeys
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## count:GPBARRAYSIZE(k##VNAME$u##s)];
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict =
+//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VALUE_NAME##s:k##VNAME$u##s
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## forKeys:kKeys
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## count:GPBARRAYSIZE(k##VNAME$u##s)];
//% XCTAssertNotNil(dict);
//%
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict2 =
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict2 =
//% [GPB##KEY_NAME##VALUE_NAME##Dictionary dictionaryWithDictionary:dict];
//% XCTAssertNotNil(dict2);
//%
@@ -226,112 +233,112 @@
//%}
//%
//%- (void)testAdds {
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict = [GPB##KEY_NAME##VALUE_NAME##Dictionary dictionary];
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict = [GPB##KEY_NAME##VALUE_NAME##Dictionary dictionary];
//% XCTAssertNotNil(dict);
//%
//% XCTAssertEqual(dict.count, 0U);
-//% [dict set##VNAME$u##:VAL1 forKey:KEY1];
+//% [dict set##VALUE_NAME##:VAL1 forKey:KEY1];
//% XCTAssertEqual(dict.count, 1U);
//%
//% const KEY_TYPE KisP##kKeys[] = { KEY2, KEY3, KEY4 };
//% const VALUE_TYPE k##VNAME$u##s[] = { VAL2, VAL3, VAL4 };
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict2 =
-//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## forKeys:kKeys
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## count:GPBARRAYSIZE(k##VNAME$u##s)];
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict2 =
+//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VALUE_NAME##s:k##VNAME$u##s
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## forKeys:kKeys
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## count:GPBARRAYSIZE(k##VNAME$u##s)];
//% XCTAssertNotNil(dict2);
//% [dict add##VACCESSOR##EntriesFromDictionary:dict2];
//% XCTAssertEqual(dict.count, 4U);
//%
-//%DECLARE_VALUE_STORAGE##VHELPER(VALUE_TYPE, VNAME)TEST_VALUE##VHELPER(dict, VNAME, KEY1, VAL1)
-//%TEST_VALUE##VHELPER(dict, VNAME, KEY2, VAL2)
-//%TEST_VALUE##VHELPER(dict, VNAME, KEY3, VAL3)
-//%TEST_VALUE##VHELPER(dict, VNAME, KEY4, VAL4)
+//%DECLARE_VALUE_STORAGE##VHELPER(VALUE_TYPE, VNAME)TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY1, VAL1)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY2, VAL2)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY3, VAL3)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY4, VAL4)
//% [dict2 release];
//%}
//%
//%- (void)testRemove {
//% const KEY_TYPE KisP##kKeys[] = { KEY1, KEY2, KEY3, KEY4 };
//% const VALUE_TYPE k##VNAME$u##s[] = { VAL1, VAL2, VAL3, VAL4 };
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict =
-//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## forKeys:kKeys
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## count:GPBARRAYSIZE(k##VNAME$u##s)];
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict =
+//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VALUE_NAME##s:k##VNAME$u##s
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## forKeys:kKeys
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## count:GPBARRAYSIZE(k##VNAME$u##s)];
//% XCTAssertNotNil(dict);
//% XCTAssertEqual(dict.count, 4U);
//%
-//% [dict remove##VNAME$u##ForKey:KEY2];
+//% [dict remove##VALUE_NAME##ForKey:KEY2];
//% XCTAssertEqual(dict.count, 3U);
-//%DECLARE_VALUE_STORAGE##VHELPER(VALUE_TYPE, VNAME)TEST_VALUE##VHELPER(dict, VNAME, KEY1, VAL1)
-//%VALUE_NOT_FOUND##VHELPER(dict, KEY2)
-//%TEST_VALUE##VHELPER(dict, VNAME, KEY3, VAL3)
-//%TEST_VALUE##VHELPER(dict, VNAME, KEY4, VAL4)
+//%DECLARE_VALUE_STORAGE##VHELPER(VALUE_TYPE, VNAME)TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY1, VAL1)
+//%VALUE_NOT_FOUND##VHELPER(VALUE_NAME, dict, KEY2)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY3, VAL3)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY4, VAL4)
//%
//% // Remove again does nothing.
-//% [dict remove##VNAME$u##ForKey:KEY2];
+//% [dict remove##VALUE_NAME##ForKey:KEY2];
//% XCTAssertEqual(dict.count, 3U);
-//%TEST_VALUE##VHELPER(dict, VNAME, KEY1, VAL1)
-//%VALUE_NOT_FOUND##VHELPER(dict, KEY2)
-//%TEST_VALUE##VHELPER(dict, VNAME, KEY3, VAL3)
-//%TEST_VALUE##VHELPER(dict, VNAME, KEY4, VAL4)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY1, VAL1)
+//%VALUE_NOT_FOUND##VHELPER(VALUE_NAME, dict, KEY2)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY3, VAL3)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY4, VAL4)
//%
-//% [dict remove##VNAME$u##ForKey:KEY4];
+//% [dict remove##VALUE_NAME##ForKey:KEY4];
//% XCTAssertEqual(dict.count, 2U);
-//%TEST_VALUE##VHELPER(dict, VNAME, KEY1, VAL1)
-//%VALUE_NOT_FOUND##VHELPER(dict, KEY2)
-//%TEST_VALUE##VHELPER(dict, VNAME, KEY3, VAL3)
-//%VALUE_NOT_FOUND##VHELPER(dict, KEY4)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY1, VAL1)
+//%VALUE_NOT_FOUND##VHELPER(VALUE_NAME, dict, KEY2)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY3, VAL3)
+//%VALUE_NOT_FOUND##VHELPER(VALUE_NAME, dict, KEY4)
//%
//% [dict removeAll];
//% XCTAssertEqual(dict.count, 0U);
-//%VALUE_NOT_FOUND##VHELPER(dict, KEY1)
-//%VALUE_NOT_FOUND##VHELPER(dict, KEY2)
-//%VALUE_NOT_FOUND##VHELPER(dict, KEY3)
-//%VALUE_NOT_FOUND##VHELPER(dict, KEY4)
+//%VALUE_NOT_FOUND##VHELPER(VALUE_NAME, dict, KEY1)
+//%VALUE_NOT_FOUND##VHELPER(VALUE_NAME, dict, KEY2)
+//%VALUE_NOT_FOUND##VHELPER(VALUE_NAME, dict, KEY3)
+//%VALUE_NOT_FOUND##VHELPER(VALUE_NAME, dict, KEY4)
//% [dict release];
//%}
//%
//%- (void)testInplaceMutation {
//% const KEY_TYPE KisP##kKeys[] = { KEY1, KEY2, KEY3, KEY4 };
//% const VALUE_TYPE k##VNAME$u##s[] = { VAL1, VAL2, VAL3, VAL4 };
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict =
-//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## forKeys:kKeys
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## count:GPBARRAYSIZE(k##VNAME$u##s)];
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict =
+//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VALUE_NAME##s:k##VNAME$u##s
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## forKeys:kKeys
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## count:GPBARRAYSIZE(k##VNAME$u##s)];
//% XCTAssertNotNil(dict);
//% XCTAssertEqual(dict.count, 4U);
-//%DECLARE_VALUE_STORAGE##VHELPER(VALUE_TYPE, VNAME)TEST_VALUE##VHELPER(dict, VNAME, KEY1, VAL1)
-//%TEST_VALUE##VHELPER(dict, VNAME, KEY2, VAL2)
-//%TEST_VALUE##VHELPER(dict, VNAME, KEY3, VAL3)
-//%TEST_VALUE##VHELPER(dict, VNAME, KEY4, VAL4)
+//%DECLARE_VALUE_STORAGE##VHELPER(VALUE_TYPE, VNAME)TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY1, VAL1)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY2, VAL2)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY3, VAL3)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY4, VAL4)
//%
-//% [dict set##VNAME$u##:VAL4 forKey:KEY1];
+//% [dict set##VALUE_NAME##:VAL4 forKey:KEY1];
//% XCTAssertEqual(dict.count, 4U);
-//%TEST_VALUE##VHELPER(dict, VNAME, KEY1, VAL4)
-//%TEST_VALUE##VHELPER(dict, VNAME, KEY2, VAL2)
-//%TEST_VALUE##VHELPER(dict, VNAME, KEY3, VAL3)
-//%TEST_VALUE##VHELPER(dict, VNAME, KEY4, VAL4)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY1, VAL4)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY2, VAL2)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY3, VAL3)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY4, VAL4)
//%
-//% [dict set##VNAME$u##:VAL2 forKey:KEY4];
+//% [dict set##VALUE_NAME##:VAL2 forKey:KEY4];
//% XCTAssertEqual(dict.count, 4U);
-//%TEST_VALUE##VHELPER(dict, VNAME, KEY1, VAL4)
-//%TEST_VALUE##VHELPER(dict, VNAME, KEY2, VAL2)
-//%TEST_VALUE##VHELPER(dict, VNAME, KEY3, VAL3)
-//%TEST_VALUE##VHELPER(dict, VNAME, KEY4, VAL2)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY1, VAL4)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY2, VAL2)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY3, VAL3)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY4, VAL2)
//%
//% const KEY_TYPE KisP##kKeys2[] = { KEY2, KEY3 };
//% const VALUE_TYPE k##VNAME$u##s2[] = { VAL3, VAL1 };
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict2 =
-//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s2
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## forKeys:kKeys2
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## count:GPBARRAYSIZE(k##VNAME$u##s2)];
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict2 =
+//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VALUE_NAME##s:k##VNAME$u##s2
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## forKeys:kKeys2
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## count:GPBARRAYSIZE(k##VNAME$u##s2)];
//% XCTAssertNotNil(dict2);
//% [dict add##VACCESSOR##EntriesFromDictionary:dict2];
//% XCTAssertEqual(dict.count, 4U);
-//%TEST_VALUE##VHELPER(dict, VNAME, KEY1, VAL4)
-//%TEST_VALUE##VHELPER(dict, VNAME, KEY2, VAL3)
-//%TEST_VALUE##VHELPER(dict, VNAME, KEY3, VAL1)
-//%TEST_VALUE##VHELPER(dict, VNAME, KEY4, VAL2)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY1, VAL4)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY2, VAL3)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY3, VAL1)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY4, VAL2)
//%
//% [dict2 release];
//% [dict release];
@@ -353,7 +360,7 @@
//%- (void)testRawBasics {
//% const KEY_TYPE KisP##kKeys[] = { KEY1, KEY2, KEY3 };
//% const VALUE_TYPE kValues[] = { VAL1, VAL2, VAL3 };
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict =
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict =
//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
//% KEY_NAME$S VALUE_NAME$S rawValues:kValues
//% KEY_NAME$S VALUE_NAME$S forKeys:kKeys
@@ -362,15 +369,15 @@
//% XCTAssertEqual(dict.count, 3U);
//% XCTAssertTrue(dict.validationFunc == TestingEnum_IsValidValue); // Pointer comparison
//%DECLARE_VALUE_STORAGE##VHELPER(VALUE_TYPE, value)TEST_RAW_VALUE##VHELPER(dict, value, KEY1, VAL1)
-//%TEST_VALUE##VHELPER(dict, value, KEY2, kGPBUnrecognizedEnumeratorValue)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, value, KEY2, kGPBUnrecognizedEnumeratorValue)
//%TEST_RAW_VALUE##VHELPER(dict, value, KEY2, VAL2)
//%TEST_RAW_VALUE##VHELPER(dict, value, KEY3, VAL3)
-//%RAW_VALUE_NOT_FOUND##VHELPER(dict, KEY4)
+//%RAW_VALUE_NOT_FOUND##VHELPER(VALUE_NAME, dict, KEY4)
//%
//% __block NSUInteger idx = 0;
//% KEY_TYPE KisP##*seenKeys = malloc(3 * sizeof(KEY_TYPE##KisP));
//% VALUE_TYPE *seenValues = malloc(3 * sizeof(VALUE_TYPE));
-//% [dict enumerateKeysAndValuesUsingBlock:^(KEY_TYPE KisP##aKey, VALUE_TYPE aValue, BOOL *stop) {
+//% [dict enumerateKeysAndEnumsUsingBlock:^(KEY_TYPE KisP##aKey, VALUE_TYPE aValue, BOOL *stop) {
//% XCTAssertLessThan(idx, 3U);
//% seenKeys[idx] = aKey;
//% seenValues[idx] = aValue;
@@ -429,31 +436,31 @@
//% const VALUE_TYPE kValues1[] = { VAL1, VAL2, VAL3 }; // Unknown
//% const VALUE_TYPE kValues2[] = { VAL1, VAL4, VAL3 }; // Unknown
//% const VALUE_TYPE kValues3[] = { VAL1, VAL2, VAL3, VAL4 }; // Unknowns
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict1 =
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict1 =
//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
//% KEY_NAME$S VALUE_NAME$S rawValues:kValues1
//% KEY_NAME$S VALUE_NAME$S forKeys:kKeys1
//% KEY_NAME$S VALUE_NAME$S count:GPBARRAYSIZE(kValues1)];
//% XCTAssertNotNil(dict1);
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict1prime =
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict1prime =
//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
//% KEY_NAME$S VALUE_NAME$S rawValues:kValues1
//% KEY_NAME$S VALUE_NAME$S forKeys:kKeys1
//% KEY_NAME$S VALUE_NAME$S count:GPBARRAYSIZE(kValues1)];
//% XCTAssertNotNil(dict1prime);
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict2 =
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict2 =
//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
//% KEY_NAME$S VALUE_NAME$S rawValues:kValues2
//% KEY_NAME$S VALUE_NAME$S forKeys:kKeys1
//% KEY_NAME$S VALUE_NAME$S count:GPBARRAYSIZE(kValues2)];
//% XCTAssertNotNil(dict2);
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict3 =
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict3 =
//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
//% KEY_NAME$S VALUE_NAME$S rawValues:kValues1
//% KEY_NAME$S VALUE_NAME$S forKeys:kKeys2
//% KEY_NAME$S VALUE_NAME$S count:GPBARRAYSIZE(kValues1)];
//% XCTAssertNotNil(dict3);
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict4 =
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict4 =
//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
//% KEY_NAME$S VALUE_NAME$S rawValues:kValues3
//% KEY_NAME$S VALUE_NAME$S forKeys:kKeys1
@@ -485,14 +492,14 @@
//%- (void)testCopyWithUnknowns {
//% const KEY_TYPE KisP##kKeys[] = { KEY1, KEY2, KEY3, KEY4 };
//% const VALUE_TYPE kValues[] = { VAL1, VAL2, VAL3, VAL4 }; // Unknown
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict =
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict =
//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
//% KEY_NAME$S VALUE_NAME$S rawValues:kValues
//% KEY_NAME$S VALUE_NAME$S forKeys:kKeys
//% KEY_NAME$S VALUE_NAME$S count:GPBARRAYSIZE(kValues)];
//% XCTAssertNotNil(dict);
//%
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict2 = [dict copy];
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict2 = [dict copy];
//% XCTAssertNotNil(dict2);
//%
//% // Should be new pointer, but equal objects.
@@ -507,14 +514,14 @@
//%- (void)testDictionaryFromDictionary {
//% const KEY_TYPE KisP##kKeys[] = { KEY1, KEY2, KEY3, KEY4 };
//% const VALUE_TYPE kValues[] = { VAL1, VAL2, VAL3, VAL4 }; // Unknowns
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict =
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict =
//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
//% KEY_NAME$S VALUE_NAME$S rawValues:kValues
//% KEY_NAME$S VALUE_NAME$S forKeys:kKeys
//% KEY_NAME$S VALUE_NAME$S count:GPBARRAYSIZE(kValues)];
//% XCTAssertNotNil(dict);
//%
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict2 =
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict2 =
//% [GPB##KEY_NAME##VALUE_NAME##Dictionary dictionaryWithDictionary:dict];
//% XCTAssertNotNil(dict2);
//%
@@ -526,12 +533,12 @@
//%}
//%
//%- (void)testUnknownAdds {
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict =
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict =
//% [GPB##KEY_NAME##VALUE_NAME##Dictionary dictionaryWithValidationFunction:TestingEnum_IsValidValue];
//% XCTAssertNotNil(dict);
//%
//% XCTAssertEqual(dict.count, 0U);
-//% XCTAssertThrowsSpecificNamed([dict setValue:VAL2 forKey:KEY2], // Unknown
+//% XCTAssertThrowsSpecificNamed([dict setEnum:VAL2 forKey:KEY2], // Unknown
//% NSException, NSInvalidArgumentException);
//% XCTAssertEqual(dict.count, 0U);
//% [dict setRawValue:VAL2 forKey:KEY2]; // Unknown
@@ -539,19 +546,19 @@
//%
//% const KEY_TYPE KisP##kKeys[] = { KEY1, KEY3, KEY4 };
//% const VALUE_TYPE kValues[] = { VAL1, VAL3, VAL4 }; // Unknown
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict2 =
-//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWithValues:kValues
-//% KEY_NAME$S VALUE_NAME$S forKeys:kKeys
-//% KEY_NAME$S VALUE_NAME$S count:GPBARRAYSIZE(kValues)];
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict2 =
+//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWithEnums:kValues
+//% KEY_NAME$S VALUE_NAME$S forKeys:kKeys
+//% KEY_NAME$S VALUE_NAME$S count:GPBARRAYSIZE(kValues)];
//% XCTAssertNotNil(dict2);
//% [dict addRawEntriesFromDictionary:dict2];
//% XCTAssertEqual(dict.count, 4U);
//%
-//%DECLARE_VALUE_STORAGE##VHELPER(VALUE_TYPE, value)TEST_VALUE##VHELPER(dict, value, KEY1, VAL1)
-//%TEST_VALUE##VHELPER(dict, value, KEY2, kGPBUnrecognizedEnumeratorValue)
+//%DECLARE_VALUE_STORAGE##VHELPER(VALUE_TYPE, value)TEST_VALUE##VHELPER(VALUE_NAME, dict, value, KEY1, VAL1)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, value, KEY2, kGPBUnrecognizedEnumeratorValue)
//%TEST_RAW_VALUE##VHELPER(dict, value, KEY2, VAL2)
-//%TEST_VALUE##VHELPER(dict, value, KEY3, VAL3)
-//%TEST_VALUE##VHELPER(dict, value, KEY4, kGPBUnrecognizedEnumeratorValue)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, value, KEY3, VAL3)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, value, KEY4, kGPBUnrecognizedEnumeratorValue)
//%TEST_RAW_VALUE##VHELPER(dict, value, KEY4, VAL4)
//% [dict2 release];
//%}
@@ -559,7 +566,7 @@
//%- (void)testUnknownRemove {
//% const KEY_TYPE KisP##kKeys[] = { KEY1, KEY2, KEY3, KEY4 };
//% const VALUE_TYPE kValues[] = { VAL1, VAL2, VAL3, VAL4 }; // Unknowns
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict =
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict =
//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
//% KEY_NAME$S VALUE_NAME$S rawValues:kValues
//% KEY_NAME$S VALUE_NAME$S forKeys:kKeys
@@ -567,77 +574,77 @@
//% XCTAssertNotNil(dict);
//% XCTAssertEqual(dict.count, 4U);
//%
-//% [dict removeValueForKey:KEY2];
+//% [dict removeEnumForKey:KEY2];
//% XCTAssertEqual(dict.count, 3U);
-//%DECLARE_VALUE_STORAGE##VHELPER(VALUE_TYPE, value)TEST_VALUE##VHELPER(dict, value, KEY1, VAL1)
-//%VALUE_NOT_FOUND##VHELPER(dict, KEY2)
-//%TEST_VALUE##VHELPER(dict, value, KEY3, VAL3)
+//%DECLARE_VALUE_STORAGE##VHELPER(VALUE_TYPE, value)TEST_VALUE##VHELPER(VALUE_NAME, dict, value, KEY1, VAL1)
+//%VALUE_NOT_FOUND##VHELPER(VALUE_NAME, dict, KEY2)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, value, KEY3, VAL3)
//%TEST_RAW_VALUE##VHELPER(dict, value, KEY4, VAL4)
//%
//% // Remove again does nothing.
-//% [dict removeValueForKey:KEY2];
+//% [dict removeEnumForKey:KEY2];
//% XCTAssertEqual(dict.count, 3U);
-//%TEST_VALUE##VHELPER(dict, value, KEY1, VAL1)
-//%VALUE_NOT_FOUND##VHELPER(dict, KEY2)
-//%TEST_VALUE##VHELPER(dict, value, KEY3, VAL3)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, value, KEY1, VAL1)
+//%VALUE_NOT_FOUND##VHELPER(VALUE_NAME, dict, KEY2)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, value, KEY3, VAL3)
//%TEST_RAW_VALUE##VHELPER(dict, value, KEY4, VAL4)
//%
-//% [dict removeValueForKey:KEY4];
+//% [dict removeEnumForKey:KEY4];
//% XCTAssertEqual(dict.count, 2U);
-//%TEST_VALUE##VHELPER(dict, value, KEY1, VAL1)
-//%VALUE_NOT_FOUND##VHELPER(dict, KEY2)
-//%TEST_VALUE##VHELPER(dict, value, KEY3, VAL3)
-//%VALUE_NOT_FOUND##VHELPER(dict, KEY4)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, value, KEY1, VAL1)
+//%VALUE_NOT_FOUND##VHELPER(VALUE_NAME, dict, KEY2)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, value, KEY3, VAL3)
+//%VALUE_NOT_FOUND##VHELPER(VALUE_NAME, dict, KEY4)
//%
//% [dict removeAll];
//% XCTAssertEqual(dict.count, 0U);
-//%VALUE_NOT_FOUND##VHELPER(dict, KEY1)
-//%VALUE_NOT_FOUND##VHELPER(dict, KEY2)
-//%VALUE_NOT_FOUND##VHELPER(dict, KEY3)
-//%VALUE_NOT_FOUND##VHELPER(dict, KEY4)
+//%VALUE_NOT_FOUND##VHELPER(VALUE_NAME, dict, KEY1)
+//%VALUE_NOT_FOUND##VHELPER(VALUE_NAME, dict, KEY2)
+//%VALUE_NOT_FOUND##VHELPER(VALUE_NAME, dict, KEY3)
+//%VALUE_NOT_FOUND##VHELPER(VALUE_NAME, dict, KEY4)
//% [dict release];
//%}
//%
//%- (void)testInplaceMutationUnknowns {
//% const KEY_TYPE KisP##kKeys[] = { KEY1, KEY2, KEY3, KEY4 };
//% const VALUE_TYPE kValues[] = { VAL1, VAL2, VAL3, VAL4 }; // Unknowns
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict =
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict =
//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
//% KEY_NAME$S VALUE_NAME$S rawValues:kValues
//% KEY_NAME$S VALUE_NAME$S forKeys:kKeys
//% KEY_NAME$S VALUE_NAME$S count:GPBARRAYSIZE(kValues)];
//% XCTAssertNotNil(dict);
//% XCTAssertEqual(dict.count, 4U);
-//%DECLARE_VALUE_STORAGE##VHELPER(VALUE_TYPE, value)TEST_VALUE##VHELPER(dict, value, KEY1, VAL1)
+//%DECLARE_VALUE_STORAGE##VHELPER(VALUE_TYPE, value)TEST_VALUE##VHELPER(VALUE_NAME, dict, value, KEY1, VAL1)
//%TEST_RAW_VALUE##VHELPER(dict, value, KEY2, VAL2)
-//%TEST_VALUE##VHELPER(dict, value, KEY3, VAL3)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, value, KEY3, VAL3)
//%TEST_RAW_VALUE##VHELPER(dict, value, KEY4, VAL4)
//%
-//% XCTAssertThrowsSpecificNamed([dict setValue:VAL4 forKey:KEY1], // Unknown
+//% XCTAssertThrowsSpecificNamed([dict setEnum:VAL4 forKey:KEY1], // Unknown
//% NSException, NSInvalidArgumentException);
//% XCTAssertEqual(dict.count, 4U);
-//%TEST_VALUE##VHELPER(dict, value, KEY1, VAL1)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, value, KEY1, VAL1)
//%TEST_RAW_VALUE##VHELPER(dict, value, KEY2, VAL2)
-//%TEST_VALUE##VHELPER(dict, value, KEY3, VAL3)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, value, KEY3, VAL3)
//%TEST_RAW_VALUE##VHELPER(dict, value, KEY4, VAL4)
//%
//% [dict setRawValue:VAL4 forKey:KEY1]; // Unknown
//% XCTAssertEqual(dict.count, 4U);
//%TEST_RAW_VALUE##VHELPER(dict, value, KEY1, VAL4)
//%TEST_RAW_VALUE##VHELPER(dict, value, KEY2, VAL2)
-//%TEST_VALUE##VHELPER(dict, value, KEY3, VAL3)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, value, KEY3, VAL3)
//%TEST_RAW_VALUE##VHELPER(dict, value, KEY4, VAL4)
//%
//% [dict setRawValue:VAL1 forKey:KEY4];
//% XCTAssertEqual(dict.count, 4U);
//%TEST_RAW_VALUE##VHELPER(dict, value, KEY1, VAL4)
//%TEST_RAW_VALUE##VHELPER(dict, value, KEY2, VAL2)
-//%TEST_VALUE##VHELPER(dict, value, KEY3, VAL3)
-//%TEST_VALUE##VHELPER(dict, value, KEY4, VAL1)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, value, KEY3, VAL3)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, value, KEY4, VAL1)
//%
//% const KEY_TYPE KisP##kKeys2[] = { KEY2, KEY3 };
//% const VALUE_TYPE kValues2[] = { VAL3, VAL2 }; // Unknown
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict2 =
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict2 =
//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
//% KEY_NAME$S VALUE_NAME$S rawValues:kValues2
//% KEY_NAME$S VALUE_NAME$S forKeys:kKeys2
@@ -646,9 +653,9 @@
//% [dict addRawEntriesFromDictionary:dict2];
//% XCTAssertEqual(dict.count, 4U);
//%TEST_RAW_VALUE##VHELPER(dict, value, KEY1, VAL4)
-//%TEST_VALUE##VHELPER(dict, value, KEY2, VAL3)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, value, KEY2, VAL3)
//%TEST_RAW_VALUE##VHELPER(dict, value, KEY3, VAL2)
-//%TEST_VALUE##VHELPER(dict, value, KEY4, VAL1)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, value, KEY4, VAL1)
//%
//% [dict2 release];
//% [dict release];
@@ -657,14 +664,14 @@
//%- (void)testCopyUnknowns {
//% const KEY_TYPE KisP##kKeys[] = { KEY1, KEY2, KEY3, KEY4 };
//% const VALUE_TYPE kValues[] = { VAL1, VAL2, VAL3, VAL4 };
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict =
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict =
//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
//% KEY_NAME$S VALUE_NAME$S rawValues:kValues
//% KEY_NAME$S VALUE_NAME$S forKeys:kKeys
//% KEY_NAME$S VALUE_NAME$S count:GPBARRAYSIZE(kValues)];
//% XCTAssertNotNil(dict);
//%
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict2 = [dict copy];
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict2 = [dict copy];
//% XCTAssertNotNil(dict2);
//%
//% // Should be new pointer, but equal objects.
@@ -687,19 +694,19 @@
//%PDDM-DEFINE DECLARE_VALUE_STORAGEPOD(VALUE_TYPE, NAME)
//% VALUE_TYPE NAME;
//%
-//%PDDM-DEFINE VALUE_NOT_FOUNDPOD(DICT, KEY)
-//% XCTAssertFalse([DICT valueForKey:KEY value:NULL]);
-//%PDDM-DEFINE TEST_VALUEPOD(DICT, STORAGE, KEY, VALUE)
-//% XCTAssertTrue([DICT valueForKey:KEY value:NULL]);
-//% XCTAssertTrue([DICT valueForKey:KEY value:&STORAGE]);
+//%PDDM-DEFINE VALUE_NOT_FOUNDPOD(VALUE_NAME, DICT, KEY)
+//% XCTAssertFalse([DICT get##VALUE_NAME##:NULL forKey:KEY]);
+//%PDDM-DEFINE TEST_VALUEPOD(VALUE_NAME, DICT, STORAGE, KEY, VALUE)
+//% XCTAssertTrue([DICT get##VALUE_NAME##:NULL forKey:KEY]);
+//% XCTAssertTrue([DICT get##VALUE_NAME##:&STORAGE forKey:KEY]);
//% XCTAssertEqual(STORAGE, VALUE);
//%PDDM-DEFINE COMPARE_KEYS(KEY1, KEY2)
//%KEY1 == KEY2
-//%PDDM-DEFINE RAW_VALUE_NOT_FOUNDPOD(DICT, KEY)
-//% XCTAssertFalse([DICT valueForKey:KEY rawValue:NULL]);
+//%PDDM-DEFINE RAW_VALUE_NOT_FOUNDPOD(VALUE_NAME, DICT, KEY)
+//% XCTAssertFalse([DICT getRawValue:NULL forKey:KEY]);
//%PDDM-DEFINE TEST_RAW_VALUEPOD(DICT, STORAGE, KEY, VALUE)
-//% XCTAssertTrue([DICT valueForKey:KEY rawValue:NULL]);
-//% XCTAssertTrue([DICT valueForKey:KEY rawValue:&STORAGE]);
+//% XCTAssertTrue([DICT getRawValue:NULL forKey:KEY]);
+//% XCTAssertTrue([DICT getRawValue:&STORAGE forKey:KEY]);
//% XCTAssertEqual(STORAGE, VALUE);
//
@@ -708,9 +715,9 @@
//%PDDM-DEFINE DECLARE_VALUE_STORAGEOBJECT(VALUE_TYPE, NAME)
// Empty
-//%PDDM-DEFINE VALUE_NOT_FOUNDOBJECT(DICT, KEY)
+//%PDDM-DEFINE VALUE_NOT_FOUNDOBJECT(VALUE_NAME, DICT, KEY)
//% XCTAssertNil([DICT objectForKey:KEY]);
-//%PDDM-DEFINE TEST_VALUEOBJECT(DICT, STORAGE, KEY, VALUE)
+//%PDDM-DEFINE TEST_VALUEOBJECT(VALUE_NAME, DICT, STORAGE, KEY, VALUE)
//% XCTAssertEqualObjects([DICT objectForKey:KEY], VALUE);
//%PDDM-DEFINE COMPARE_KEYSObjects(KEY1, KEY2)
//%[KEY1 isEqual:KEY2]
@@ -722,10 +729,10 @@
//%PDDM-DEFINE TEST_HELPERS(KEY_NAME, KEY_TYPE, KisP)
//%// To let the testing macros work, add some extra methods to simplify things.
//%@interface GPB##KEY_NAME##EnumDictionary (TestingTweak)
-//%+ (instancetype)dictionaryWithValue:(int32_t)value forKey:(KEY_TYPE##KisP$S##KisP)key;
-//%- (instancetype)initWithValues:(const int32_t [])values
-//% forKeys:(const KEY_TYPE##KisP$S##KisP [])keys
-//% count:(NSUInteger)count;
+//%+ (instancetype)dictionaryWithEnum:(int32_t)value forKey:(KEY_TYPE##KisP$S##KisP)key;
+//%- (instancetype)initWithEnums:(const int32_t [])values
+//% forKeys:(const KEY_TYPE##KisP$S##KisP [])keys
+//% count:(NSUInteger)count;
//%@end
//%
//%static BOOL TestingEnum_IsValidValue(int32_t value) {
@@ -741,7 +748,7 @@
//%}
//%
//%@implementation GPB##KEY_NAME##EnumDictionary (TestingTweak)
-//%+ (instancetype)dictionaryWithValue:(int32_t)value forKey:(KEY_TYPE##KisP$S##KisP)key {
+//%+ (instancetype)dictionaryWithEnum:(int32_t)value forKey:(KEY_TYPE##KisP$S##KisP)key {
//% // Cast is needed to compiler knows what class we are invoking initWithValues: on to get the
//% // type correct.
//% return [[(GPB##KEY_NAME##EnumDictionary*)[self alloc] initWithValidationFunction:TestingEnum_IsValidValue
@@ -749,9 +756,9 @@
//% KEY_NAME$S forKeys:&key
//% KEY_NAME$S count:1] autorelease];
//%}
-//%- (instancetype)initWithValues:(const int32_t [])values
-//% forKeys:(const KEY_TYPE##KisP$S##KisP [])keys
-//% count:(NSUInteger)count {
+//%- (instancetype)initWithEnums:(const int32_t [])values
+//% forKeys:(const KEY_TYPE##KisP$S##KisP [])keys
+//% count:(NSUInteger)count {
//% return [self initWithValidationFunction:TestingEnum_IsValidValue
//% rawValues:values
//% forKeys:keys
@@ -782,11 +789,11 @@
//%@implementation GPB##KEY_NAME##VALUE_NAME##DictionaryTests
//%
//%- (void)testEmpty {
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict = [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] init];
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict = [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] init];
//% XCTAssertNotNil(dict);
//% XCTAssertEqual(dict.count, 0U);
-//%VALUE_NOT_FOUND##VHELPER(dict, KEY1)
-//% [dict enumerateKeysAnd##VNAME$u##sUsingBlock:^(KEY_TYPE KisP##aKey, VALUE_TYPE a##VNAME$u##, BOOL *stop) {
+//%VALUE_NOT_FOUND##VHELPER(VALUE_NAME, dict, KEY1)
+//% [dict enumerateKeysAnd##VALUE_NAME##sUsingBlock:^(KEY_TYPE KisP##aKey, VALUE_TYPE a##VNAME$u##, BOOL *stop) {
//% #pragma unused(aKey, a##VNAME$u##, stop)
//% XCTFail(@"Shouldn't get here!");
//% }];
@@ -794,12 +801,12 @@
//%}
//%
//%- (void)testOne {
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict = [GPB##KEY_NAME##VALUE_NAME##Dictionary dictionaryWith##VNAME$u##:VAL1 forKey:KEY1];
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict = [GPB##KEY_NAME##VALUE_NAME##Dictionary dictionaryWith##VALUE_NAME$u##:VAL1 forKey:KEY1];
//% XCTAssertNotNil(dict);
//% XCTAssertEqual(dict.count, 1U);
-//%DECLARE_VALUE_STORAGE##VHELPER(VALUE_TYPE, VNAME)TEST_VALUE##VHELPER(dict, VNAME, KEY1, VAL1)
-//%VALUE_NOT_FOUND##VHELPER(dict, KEY2)
-//% [dict enumerateKeysAnd##VNAME$u##sUsingBlock:^(KEY_TYPE KisP##aKey, VALUE_TYPE a##VNAME$u, BOOL *stop) {
+//%DECLARE_VALUE_STORAGE##VHELPER(VALUE_TYPE, VNAME)TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY1, VAL1)
+//%VALUE_NOT_FOUND##VHELPER(VALUE_NAME, dict, KEY2)
+//% [dict enumerateKeysAnd##VALUE_NAME$u##sUsingBlock:^(KEY_TYPE KisP##aKey, VALUE_TYPE a##VNAME$u, BOOL *stop) {
//% XCTAssertEqual##KSUFFIX(aKey, KEY1);
//% XCTAssertEqual##VSUFFIX(a##VNAME$u, VAL1);
//% XCTAssertNotEqual(stop, NULL);
@@ -809,19 +816,19 @@
//%- (void)testBasics {
//% const KEY_TYPE KisP##kKeys[] = { KEY1, KEY2 };
//% const VALUE_TYPE k##VNAME$u##s[] = { VAL1, VAL2 };
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict =
-//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## forKeys:kKeys
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## count:GPBARRAYSIZE(k##VNAME$u##s)];
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict =
+//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VALUE_NAME##s:k##VNAME$u##s
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## forKeys:kKeys
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## count:GPBARRAYSIZE(k##VNAME$u##s)];
//% XCTAssertNotNil(dict);
//% XCTAssertEqual(dict.count, 2U);
-//%DECLARE_VALUE_STORAGE##VHELPER(VALUE_TYPE, VNAME)TEST_VALUE##VHELPER(dict, VNAME, KEY1, VAL1)
-//%TEST_VALUE##VHELPER(dict, VNAME, KEY2, VAL2)
+//%DECLARE_VALUE_STORAGE##VHELPER(VALUE_TYPE, VNAME)TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY1, VAL1)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY2, VAL2)
//%
//% __block NSUInteger idx = 0;
//% KEY_TYPE KisP##*seenKeys = malloc(2 * sizeof(KEY_TYPE##KisP));
//% VALUE_TYPE *seen##VNAME$u##s = malloc(2 * sizeof(VALUE_TYPE));
-//% [dict enumerateKeysAnd##VNAME$u##sUsingBlock:^(KEY_TYPE KisP##aKey, VALUE_TYPE a##VNAME$u##, BOOL *stop) {
+//% [dict enumerateKeysAnd##VALUE_NAME$u##sUsingBlock:^(KEY_TYPE KisP##aKey, VALUE_TYPE a##VNAME$u##, BOOL *stop) {
//% XCTAssertLessThan(idx, 2U);
//% seenKeys[idx] = aKey;
//% seen##VNAME$u##s[idx] = a##VNAME$u;
@@ -843,7 +850,7 @@
//%
//% // Stopping the enumeration.
//% idx = 0;
-//% [dict enumerateKeysAnd##VNAME$u##sUsingBlock:^(KEY_TYPE KisP##aKey, VALUE_TYPE a##VNAME$u##, BOOL *stop) {
+//% [dict enumerateKeysAnd##VALUE_NAME$u##sUsingBlock:^(KEY_TYPE KisP##aKey, VALUE_TYPE a##VNAME$u##, BOOL *stop) {
//% #pragma unused(aKey, a##VNAME$u)
//% if (idx == 0) *stop = YES;
//% XCTAssertNotEqual(idx, 2U);
@@ -858,30 +865,30 @@
//% const VALUE_TYPE k##VNAME$u##s1[] = { VAL1, VAL2 };
//% const VALUE_TYPE k##VNAME$u##s2[] = { VAL2, VAL1 };
//% const VALUE_TYPE k##VNAME$u##s3[] = { VAL2 };
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict1 =
-//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s1
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## forKeys:kKeys1
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## count:GPBARRAYSIZE(k##VNAME$u##s1)];
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict1 =
+//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VALUE_NAME##s:k##VNAME$u##s1
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## forKeys:kKeys1
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## count:GPBARRAYSIZE(k##VNAME$u##s1)];
//% XCTAssertNotNil(dict1);
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict1prime =
-//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s1
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## forKeys:kKeys1
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## count:GPBARRAYSIZE(k##VNAME$u##s1)];
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict1prime =
+//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VALUE_NAME##s:k##VNAME$u##s1
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## forKeys:kKeys1
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## count:GPBARRAYSIZE(k##VNAME$u##s1)];
//% XCTAssertNotNil(dict1prime);
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict2 =
-//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s2
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## forKeys:kKeys1
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## count:GPBARRAYSIZE(k##VNAME$u##s2)];
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict2 =
+//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VALUE_NAME##s:k##VNAME$u##s2
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## forKeys:kKeys1
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## count:GPBARRAYSIZE(k##VNAME$u##s2)];
//% XCTAssertNotNil(dict2);
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict3 =
-//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s1
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## forKeys:kKeys2
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## count:GPBARRAYSIZE(k##VNAME$u##s1)];
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict3 =
+//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VALUE_NAME##s:k##VNAME$u##s1
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## forKeys:kKeys2
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## count:GPBARRAYSIZE(k##VNAME$u##s1)];
//% XCTAssertNotNil(dict3);
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict4 =
-//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s3
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## forKeys:kKeys1
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## count:GPBARRAYSIZE(k##VNAME$u##s3)];
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict4 =
+//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VALUE_NAME##s:k##VNAME$u##s3
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## forKeys:kKeys1
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## count:GPBARRAYSIZE(k##VNAME$u##s3)];
//% XCTAssertNotNil(dict4);
//%
//% // 1/1Prime should be different objects, but equal.
@@ -909,13 +916,13 @@
//%- (void)testCopy {
//% const KEY_TYPE KisP##kKeys[] = { KEY1, KEY2 };
//% const VALUE_TYPE k##VNAME$u##s[] = { VAL1, VAL2 };
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict =
-//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## forKeys:kKeys
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## count:GPBARRAYSIZE(k##VNAME$u##s)];
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict =
+//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VALUE_NAME##s:k##VNAME$u##s
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## forKeys:kKeys
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## count:GPBARRAYSIZE(k##VNAME$u##s)];
//% XCTAssertNotNil(dict);
//%
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict2 = [dict copy];
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict2 = [dict copy];
//% XCTAssertNotNil(dict2);
//%
//% // Should be new object but equal.
@@ -930,13 +937,13 @@
//%- (void)testDictionaryFromDictionary {
//% const KEY_TYPE KisP##kKeys[] = { KEY1, KEY2 };
//% const VALUE_TYPE k##VNAME$u##s[] = { VAL1, VAL2 };
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict =
-//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## forKeys:kKeys
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## count:GPBARRAYSIZE(k##VNAME$u##s)];
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict =
+//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VALUE_NAME##s:k##VNAME$u##s
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## forKeys:kKeys
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## count:GPBARRAYSIZE(k##VNAME$u##s)];
//% XCTAssertNotNil(dict);
//%
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict2 =
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict2 =
//% [GPB##KEY_NAME##VALUE_NAME##Dictionary dictionaryWithDictionary:dict];
//% XCTAssertNotNil(dict2);
//%
@@ -947,89 +954,89 @@
//%}
//%
//%- (void)testAdds {
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict = [GPB##KEY_NAME##VALUE_NAME##Dictionary dictionary];
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict = [GPB##KEY_NAME##VALUE_NAME##Dictionary dictionary];
//% XCTAssertNotNil(dict);
//%
//% XCTAssertEqual(dict.count, 0U);
-//% [dict set##VNAME$u:VAL1 forKey:KEY1];
+//% [dict set##VALUE_NAME:VAL1 forKey:KEY1];
//% XCTAssertEqual(dict.count, 1U);
//%
//% const KEY_TYPE KisP##kKeys[] = { KEY2 };
//% const VALUE_TYPE k##VNAME$u##s[] = { VAL2 };
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict2 =
-//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## forKeys:kKeys
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## count:GPBARRAYSIZE(k##VNAME$u##s)];
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict2 =
+//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VALUE_NAME##s:k##VNAME$u##s
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## forKeys:kKeys
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## count:GPBARRAYSIZE(k##VNAME$u##s)];
//% XCTAssertNotNil(dict2);
//% [dict addEntriesFromDictionary:dict2];
//% XCTAssertEqual(dict.count, 2U);
//%
-//%DECLARE_VALUE_STORAGE##VHELPER(VALUE_TYPE, VNAME)TEST_VALUE##VHELPER(dict, VNAME, KEY1, VAL1)
-//%TEST_VALUE##VHELPER(dict, VNAME, KEY2, VAL2)
+//%DECLARE_VALUE_STORAGE##VHELPER(VALUE_TYPE, VNAME)TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY1, VAL1)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY2, VAL2)
//% [dict2 release];
//%}
//%
//%- (void)testRemove {
//% const KEY_TYPE KisP##kKeys[] = { KEY1, KEY2};
//% const VALUE_TYPE k##VNAME$u##s[] = { VAL1, VAL2 };
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict =
-//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## forKeys:kKeys
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## count:GPBARRAYSIZE(k##VNAME$u##s)];
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict =
+//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VALUE_NAME##s:k##VNAME$u##s
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## forKeys:kKeys
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## count:GPBARRAYSIZE(k##VNAME$u##s)];
//% XCTAssertNotNil(dict);
//% XCTAssertEqual(dict.count, 2U);
//%
-//% [dict remove##VNAME$u##ForKey:KEY2];
+//% [dict remove##VALUE_NAME##ForKey:KEY2];
//% XCTAssertEqual(dict.count, 1U);
-//%DECLARE_VALUE_STORAGE##VHELPER(VALUE_TYPE, VNAME)TEST_VALUE##VHELPER(dict, VNAME, KEY1, VAL1)
-//%VALUE_NOT_FOUND##VHELPER(dict, KEY2)
+//%DECLARE_VALUE_STORAGE##VHELPER(VALUE_TYPE, VNAME)TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY1, VAL1)
+//%VALUE_NOT_FOUND##VHELPER(VALUE_NAME, dict, KEY2)
//%
//% // Remove again does nothing.
-//% [dict remove##VNAME$u##ForKey:KEY2];
+//% [dict remove##VALUE_NAME##ForKey:KEY2];
//% XCTAssertEqual(dict.count, 1U);
-//%TEST_VALUE##VHELPER(dict, VNAME, KEY1, VAL1)
-//%VALUE_NOT_FOUND##VHELPER(dict, KEY2)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY1, VAL1)
+//%VALUE_NOT_FOUND##VHELPER(VALUE_NAME, dict, KEY2)
//%
//% [dict removeAll];
//% XCTAssertEqual(dict.count, 0U);
-//%VALUE_NOT_FOUND##VHELPER(dict, KEY1)
-//%VALUE_NOT_FOUND##VHELPER(dict, KEY2)
+//%VALUE_NOT_FOUND##VHELPER(VALUE_NAME, dict, KEY1)
+//%VALUE_NOT_FOUND##VHELPER(VALUE_NAME, dict, KEY2)
//% [dict release];
//%}
//%
//%- (void)testInplaceMutation {
//% const KEY_TYPE KisP##kKeys[] = { KEY1, KEY2 };
//% const VALUE_TYPE k##VNAME$u##s[] = { VAL1, VAL2 };
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict =
-//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## forKeys:kKeys
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## count:GPBARRAYSIZE(k##VNAME$u##s)];
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict =
+//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VALUE_NAME##s:k##VNAME$u##s
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## forKeys:kKeys
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## count:GPBARRAYSIZE(k##VNAME$u##s)];
//% XCTAssertNotNil(dict);
//% XCTAssertEqual(dict.count, 2U);
-//%DECLARE_VALUE_STORAGE##VHELPER(VALUE_TYPE, VNAME)TEST_VALUE##VHELPER(dict, VNAME, KEY1, VAL1)
-//%TEST_VALUE##VHELPER(dict, VNAME, KEY2, VAL2)
+//%DECLARE_VALUE_STORAGE##VHELPER(VALUE_TYPE, VNAME)TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY1, VAL1)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY2, VAL2)
//%
-//% [dict set##VNAME$u##:VAL2 forKey:KEY1];
+//% [dict set##VALUE_NAME##:VAL2 forKey:KEY1];
//% XCTAssertEqual(dict.count, 2U);
-//%TEST_VALUE##VHELPER(dict, VNAME, KEY1, VAL2)
-//%TEST_VALUE##VHELPER(dict, VNAME, KEY2, VAL2)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY1, VAL2)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY2, VAL2)
//%
-//% [dict set##VNAME$u##:VAL1 forKey:KEY2];
+//% [dict set##VALUE_NAME##:VAL1 forKey:KEY2];
//% XCTAssertEqual(dict.count, 2U);
-//%TEST_VALUE##VHELPER(dict, VNAME, KEY1, VAL2)
-//%TEST_VALUE##VHELPER(dict, VNAME, KEY2, VAL1)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY1, VAL2)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY2, VAL1)
//%
//% const KEY_TYPE KisP##kKeys2[] = { KEY2, KEY1 };
//% const VALUE_TYPE k##VNAME$u##s2[] = { VAL2, VAL1 };
-//% GPB##KEY_NAME##VALUE_NAME##Dictionary *dict2 =
-//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s2
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## forKeys:kKeys2
-//% KEY_NAME$S VALUE_NAME$S ##VNAME$S## count:GPBARRAYSIZE(k##VNAME$u##s2)];
+//% DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict2 =
+//% [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VALUE_NAME##s:k##VNAME$u##s2
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## forKeys:kKeys2
+//% KEY_NAME$S VALUE_NAME$S ##VALUE_NAME$S## count:GPBARRAYSIZE(k##VNAME$u##s2)];
//% XCTAssertNotNil(dict2);
//% [dict addEntriesFromDictionary:dict2];
//% XCTAssertEqual(dict.count, 2U);
-//%TEST_VALUE##VHELPER(dict, VNAME, KEY1, VAL1)
-//%TEST_VALUE##VHELPER(dict, VNAME, KEY2, VAL2)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY1, VAL1)
+//%TEST_VALUE##VHELPER(VALUE_NAME, dict, VNAME, KEY2, VAL2)
//%
//% [dict2 release];
//% [dict release];
diff --git a/objectivec/Tests/GPBMessageTests+Merge.m b/objectivec/Tests/GPBMessageTests+Merge.m
index a3908aab..c0bd5897 100644
--- a/objectivec/Tests/GPBMessageTests+Merge.m
+++ b/objectivec/Tests/GPBMessageTests+Merge.m
@@ -675,14 +675,12 @@
TestAllTypes *subMsg = [TestAllTypes message];
subMsg.repeatedInt32Array = [GPBInt32Array arrayWithValue:100];
- msg1.mapInt32Message = [GPBInt32ObjectDictionary dictionary];
[msg1.mapInt32Message setObject:subMsg forKey:0];
subMsg = nil;
subMsg = [TestAllTypes message];
subMsg.repeatedInt32Array = [GPBInt32Array arrayWithValue:101];
- msg2.mapInt32Message = [GPBInt32ObjectDictionary dictionary];
-
+
[msg2.mapInt32Message setObject:subMsg forKey:0];
subMsg = nil;
diff --git a/objectivec/Tests/GPBMessageTests+Runtime.m b/objectivec/Tests/GPBMessageTests+Runtime.m
index e536bfec..1520381b 100644
--- a/objectivec/Tests/GPBMessageTests+Runtime.m
+++ b/objectivec/Tests/GPBMessageTests+Runtime.m
@@ -2066,6 +2066,46 @@
}];
}
+- (void)test_GPBGetMessageRepeatedField {
+ TestAllTypes *message = [TestAllTypes message];
+ GPBFieldDescriptor *fieldDescriptor = [[message descriptor] fieldWithName:@"repeatedStringArray"];
+ XCTAssertNotNil(fieldDescriptor);
+ NSMutableArray *fieldArray = GPBGetMessageRepeatedField(message, fieldDescriptor);
+ XCTAssertNotNil(fieldArray); // Should have autocreated.
+ XCTAssertTrue(fieldArray == message.repeatedStringArray); // Same pointer
+}
+
+- (void)test_GPBSetMessageRepeatedField {
+ TestAllTypes *message = [TestAllTypes message];
+ GPBFieldDescriptor *fieldDescriptor = [[message descriptor] fieldWithName:@"repeatedStringArray"];
+ XCTAssertNotNil(fieldDescriptor);
+
+ NSMutableArray *fieldArray = [NSMutableArray arrayWithObject:@"foo"];
+ GPBSetMessageRepeatedField(message, fieldDescriptor, fieldArray);
+ XCTAssertTrue(fieldArray == message.repeatedStringArray); // Same pointer
+ XCTAssertEqualObjects(@"foo", message.repeatedStringArray.firstObject);
+}
+
+- (void)test_GPBGetMessageMapField {
+ TestMap *message = [TestMap message];
+ GPBFieldDescriptor *fieldDescriptor = [[message descriptor] fieldWithName:@"mapStringString"];
+ XCTAssertNotNil(fieldDescriptor);
+ NSMutableDictionary *fieldMap = GPBGetMessageMapField(message, fieldDescriptor);
+ XCTAssertNotNil(fieldMap); // Should have autocreated.
+ XCTAssertTrue(fieldMap == message.mapStringString); // Same pointer
+}
+
+- (void)test_GPBSetMessageMapField {
+ TestMap *message = [TestMap message];
+ GPBFieldDescriptor *fieldDescriptor = [[message descriptor] fieldWithName:@"mapStringString"];
+ XCTAssertNotNil(fieldDescriptor);
+
+ NSMutableDictionary *fieldMap = [NSMutableDictionary dictionaryWithObject:@"bar" forKey:@"foo"];
+ GPBSetMessageMapField(message, fieldDescriptor, fieldMap);
+ XCTAssertTrue(fieldMap == message.mapStringString); // Same pointer
+ XCTAssertEqualObjects(@"bar", message.mapStringString[@"foo"]);
+}
+
#pragma mark - Subset from from map_tests.cc
// TEST(GeneratedMapFieldTest, IsInitialized)
@@ -2074,7 +2114,6 @@
// Add an uninitialized message.
TestRequired *subMsg = [[TestRequired alloc] init];
- msg.mapField = [GPBInt32ObjectDictionary dictionary];
[msg.mapField setObject:subMsg forKey:0];
XCTAssertFalse(msg.initialized);
diff --git a/objectivec/Tests/GPBMessageTests+Serialization.m b/objectivec/Tests/GPBMessageTests+Serialization.m
index 0d811a96..763af2b0 100644
--- a/objectivec/Tests/GPBMessageTests+Serialization.m
+++ b/objectivec/Tests/GPBMessageTests+Serialization.m
@@ -881,6 +881,103 @@ static NSData *DataFromCStr(const char *str) {
XCTAssertEqualObjects(extsParse, extsOrig);
}
+- (void)testErrorSubsectionInvalidLimit {
+ NSData *data = DataFromCStr(
+ "\x0A\x08\x0A\x07\x12\x04\x72\x02\x4B\x50\x12\x04\x72\x02\x4B\x50");
+ NSError *error = nil;
+ NestedTestAllTypes *msg = [NestedTestAllTypes parseFromData:data
+ error:&error];
+ XCTAssertNil(msg);
+ XCTAssertNotNil(error);
+ XCTAssertEqualObjects(error.domain, GPBCodedInputStreamErrorDomain);
+ XCTAssertEqual(error.code, GPBCodedInputStreamErrorInvalidSubsectionLimit);
+}
+
+- (void)testErrorSubsectionLimitReached {
+ NSData *data = DataFromCStr("\x0A\x06\x12\x03\x72\x02\x4B\x50");
+ NSError *error = nil;
+ NestedTestAllTypes *msg = [NestedTestAllTypes parseFromData:data
+ error:&error];
+ XCTAssertNil(msg);
+ XCTAssertNotNil(error);
+ XCTAssertEqualObjects(error.domain, GPBCodedInputStreamErrorDomain);
+ XCTAssertEqual(error.code, GPBCodedInputStreamErrorSubsectionLimitReached);
+}
+
+- (void)testErrorInvalidVarint {
+ NSData *data = DataFromCStr("\x72\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF");
+ NSError *error = nil;
+ TestAllTypes *msg = [TestAllTypes parseFromData:data error:&error];
+ XCTAssertNil(msg);
+ XCTAssertNotNil(error);
+ XCTAssertEqualObjects(error.domain, GPBCodedInputStreamErrorDomain);
+ XCTAssertEqual(error.code, GPBCodedInputStreamErrorInvalidVarInt);
+}
+
+- (void)testErrorInvalidUTF8 {
+ NSData *data = DataFromCStr("\x72\x04\xF4\xFF\xFF\xFF");
+ NSError *error = nil;
+ TestAllTypes *msg = [TestAllTypes parseFromData:data error:&error];
+ XCTAssertNil(msg);
+ XCTAssertNotNil(error);
+ XCTAssertEqualObjects(error.domain, GPBCodedInputStreamErrorDomain);
+ XCTAssertEqual(error.code, GPBCodedInputStreamErrorInvalidUTF8);
+}
+
+- (void)testErrorInvalidSize {
+ NSData *data = DataFromCStr("\x72\x03\x4B\x50");
+ NSError *error = nil;
+ NestedTestAllTypes *msg = [NestedTestAllTypes parseFromData:data
+ error:&error];
+ XCTAssertNil(msg);
+ XCTAssertNotNil(error);
+ XCTAssertEqualObjects(error.domain, GPBCodedInputStreamErrorDomain);
+ XCTAssertEqual(error.code, GPBCodedInputStreamErrorInvalidSize);
+}
+
+- (void)testErrorInvalidTag {
+ NSData *data = DataFromCStr("\x0F");
+ NSError *error = nil;
+ NestedTestAllTypes *msg = [NestedTestAllTypes parseFromData:data
+ error:&error];
+ XCTAssertNil(msg);
+ XCTAssertNotNil(error);
+ XCTAssertEqualObjects(error.domain, GPBCodedInputStreamErrorDomain);
+ XCTAssertEqual(error.code, GPBCodedInputStreamErrorInvalidTag);
+}
+
+- (void)testErrorRecursionDepthReached {
+ NSData *data = DataFromCStr(
+ "\x0A\x86\x01\x0A\x83\x01\x0A\x80\x01\x0A\x7E\x0A\x7C\x0A\x7A\x0A\x78"
+ "\x0A\x76\x0A\x74\x0A\x72\x0A\x70\x0A\x6E\x0A\x6C\x0A\x6A\x0A\x68"
+ "\x0A\x66\x0A\x64\x0A\x62\x0A\x60\x0A\x5E\x0A\x5C\x0A\x5A\x0A\x58"
+ "\x0A\x56\x0A\x54\x0A\x52\x0A\x50\x0A\x4E\x0A\x4C\x0A\x4A\x0A\x48"
+ "\x0A\x46\x0A\x44\x0A\x42\x0A\x40\x0A\x3E\x0A\x3C\x0A\x3A\x0A\x38"
+ "\x0A\x36\x0A\x34\x0A\x32\x0A\x30\x0A\x2E\x0A\x2C\x0A\x2A\x0A\x28"
+ "\x0A\x26\x0A\x24\x0A\x22\x0A\x20\x0A\x1E\x0A\x1C\x0A\x1A\x0A\x18"
+ "\x0A\x16\x0A\x14\x0A\x12\x0A\x10\x0A\x0E\x0A\x0C\x0A\x0A\x0A\x08"
+ "\x0A\x06\x12\x04\x72\x02\x4B\x50");
+ NSError *error = nil;
+ NestedTestAllTypes *msg = [NestedTestAllTypes parseFromData:data
+ error:&error];
+ XCTAssertNil(msg);
+ XCTAssertNotNil(error);
+ XCTAssertEqualObjects(error.domain, GPBCodedInputStreamErrorDomain);
+ XCTAssertEqual(error.code, GPBCodedInputStreamErrorRecursionDepthExceeded);
+}
+
+#ifdef DEBUG
+- (void)testErrorMissingRequiredField {
+ NSData *data = DataFromCStr("");
+ NSError *error = nil;
+ TestRequired *msg = [TestRequired parseFromData:data error:&error];
+ XCTAssertNil(msg);
+ XCTAssertNotNil(error);
+ XCTAssertEqualObjects(error.domain, GPBMessageErrorDomain);
+ XCTAssertEqual(error.code, GPBMessageErrorCodeMissingRequiredField);
+}
+#endif
+
#pragma mark - Subset from from map_tests.cc
// TEST(GeneratedMapFieldTest, StandardWireFormat)
@@ -890,7 +987,7 @@ static NSData *DataFromCStr(const char *str) {
TestMap *msg = [[TestMap alloc] initWithData:data error:NULL];
XCTAssertEqual(msg.mapInt32Int32.count, 1U);
int32_t val = 666;
- XCTAssertTrue([msg.mapInt32Int32 valueForKey:1 value:&val]);
+ XCTAssertTrue([msg.mapInt32Int32 getInt32:&val forKey:1]);
XCTAssertEqual(val, 1);
[msg release];
@@ -904,7 +1001,7 @@ static NSData *DataFromCStr(const char *str) {
TestMap *msg = [[TestMap alloc] initWithData:data error:NULL];
XCTAssertEqual(msg.mapInt32Int32.count, 1U);
int32_t val = 666;
- XCTAssertTrue([msg.mapInt32Int32 valueForKey:2 value:&val]);
+ XCTAssertTrue([msg.mapInt32Int32 getInt32:&val forKey:2]);
XCTAssertEqual(val, 1);
[msg release];
@@ -918,7 +1015,7 @@ static NSData *DataFromCStr(const char *str) {
TestMap *msg = [[TestMap alloc] initWithData:data error:NULL];
XCTAssertEqual(msg.mapInt32Int32.count, 1U);
int32_t val = 666;
- XCTAssertTrue([msg.mapInt32Int32 valueForKey:2 value:&val]);
+ XCTAssertTrue([msg.mapInt32Int32 getInt32:&val forKey:2]);
XCTAssertEqual(val, 1);
[msg release];
@@ -932,7 +1029,7 @@ static NSData *DataFromCStr(const char *str) {
TestMap *msg = [[TestMap alloc] initWithData:data error:NULL];
XCTAssertEqual(msg.mapInt32Int32.count, 1U);
int32_t val = 666;
- XCTAssertTrue([msg.mapInt32Int32 valueForKey:1 value:&val]);
+ XCTAssertTrue([msg.mapInt32Int32 getInt32:&val forKey:1]);
XCTAssertEqual(val, 2);
[msg release];
@@ -946,7 +1043,7 @@ static NSData *DataFromCStr(const char *str) {
TestMap *msg = [[TestMap alloc] initWithData:data error:NULL];
XCTAssertEqual(msg.mapInt32Int32.count, 1U);
int32_t val = 666;
- XCTAssertTrue([msg.mapInt32Int32 valueForKey:0 value:&val]);
+ XCTAssertTrue([msg.mapInt32Int32 getInt32:&val forKey:0]);
XCTAssertEqual(val, 1);
[msg release];
@@ -960,7 +1057,7 @@ static NSData *DataFromCStr(const char *str) {
TestMap *msg = [[TestMap alloc] initWithData:data error:NULL];
XCTAssertEqual(msg.mapInt32Int32.count, 1U);
int32_t val = 666;
- XCTAssertTrue([msg.mapInt32Int32 valueForKey:1 value:&val]);
+ XCTAssertTrue([msg.mapInt32Int32 getInt32:&val forKey:1]);
XCTAssertEqual(val, 0);
[msg release];
@@ -974,7 +1071,7 @@ static NSData *DataFromCStr(const char *str) {
TestMap *msg = [[TestMap alloc] initWithData:data error:NULL];
XCTAssertEqual(msg.mapInt32Int32.count, 1U);
int32_t val = 666;
- XCTAssertTrue([msg.mapInt32Int32 valueForKey:2 value:&val]);
+ XCTAssertTrue([msg.mapInt32Int32 getInt32:&val forKey:2]);
XCTAssertEqual(val, 3);
[msg release];
@@ -989,8 +1086,8 @@ static NSData *DataFromCStr(const char *str) {
TestMap *msg = [TestMap parseFromData:data error:&error];
XCTAssertNil(msg);
XCTAssertNotNil(error);
- XCTAssertEqualObjects(error.domain, GPBMessageErrorDomain);
- XCTAssertEqual(error.code, GPBMessageErrorCodeMalformedData);
+ XCTAssertEqualObjects(error.domain, GPBCodedInputStreamErrorDomain);
+ XCTAssertEqual(error.code, GPBCodedInputStreamErrorInvalidSubsectionLimit);
}
// TEST(GeneratedMapFieldTest, Proto2UnknownEnum)
@@ -1001,17 +1098,17 @@ static NSData *DataFromCStr(const char *str) {
dictionaryWithValidationFunction:Proto2MapEnumPlusExtra_IsValidValue];
orig.unknownMapField = [GPBInt32EnumDictionary
dictionaryWithValidationFunction:Proto2MapEnumPlusExtra_IsValidValue];
- [orig.knownMapField setValue:Proto2MapEnumPlusExtra_EProto2MapEnumFoo
- forKey:0];
- [orig.unknownMapField setValue:Proto2MapEnumPlusExtra_EProto2MapEnumExtra
- forKey:0];
+ [orig.knownMapField setEnum:Proto2MapEnumPlusExtra_EProto2MapEnumFoo
+ forKey:0];
+ [orig.unknownMapField setEnum:Proto2MapEnumPlusExtra_EProto2MapEnumExtra
+ forKey:0];
NSData *data = [orig data];
XCTAssertNotNil(data);
TestEnumMap *msg1 = [TestEnumMap parseFromData:data error:NULL];
XCTAssertEqual(msg1.knownMapField.count, 1U);
int32_t val = -1;
- XCTAssertTrue([msg1.knownMapField valueForKey:0 value:&val]);
+ XCTAssertTrue([msg1.knownMapField getEnum:&val forKey:0]);
XCTAssertEqual(val, Proto2MapEnum_Proto2MapEnumFoo);
XCTAssertEqual(msg1.unknownFields.countOfFields, 1U);
@@ -1020,11 +1117,11 @@ static NSData *DataFromCStr(const char *str) {
[TestEnumMapPlusExtra parseFromData:data error:NULL];
val = -1;
XCTAssertEqual(msg2.knownMapField.count, 1U);
- XCTAssertTrue([msg2.knownMapField valueForKey:0 value:&val]);
+ XCTAssertTrue([msg2.knownMapField getEnum:&val forKey:0]);
XCTAssertEqual(val, Proto2MapEnumPlusExtra_EProto2MapEnumFoo);
val = -1;
XCTAssertEqual(msg2.unknownMapField.count, 1U);
- XCTAssertTrue([msg2.unknownMapField valueForKey:0 value:&val]);
+ XCTAssertTrue([msg2.unknownMapField getEnum:&val forKey:0]);
XCTAssertEqual(val, Proto2MapEnumPlusExtra_EProto2MapEnumExtra);
XCTAssertEqual(msg2.unknownFields.countOfFields, 0U);
@@ -1040,32 +1137,32 @@ static NSData *DataFromCStr(const char *str) {
// Key/Value data should result in different byte lengths on wire to ensure
// everything is right.
- [msg.mapInt32Int32 setValue:1000 forKey:200];
- [msg.mapInt32Int32 setValue:101 forKey:2001];
- [msg.mapInt64Int64 setValue:1002 forKey:202];
- [msg.mapInt64Int64 setValue:103 forKey:2003];
- [msg.mapUint32Uint32 setValue:1004 forKey:204];
- [msg.mapUint32Uint32 setValue:105 forKey:2005];
- [msg.mapUint64Uint64 setValue:1006 forKey:206];
- [msg.mapUint64Uint64 setValue:107 forKey:2007];
- [msg.mapSint32Sint32 setValue:1008 forKey:208];
- [msg.mapSint32Sint32 setValue:109 forKey:2009];
- [msg.mapSint64Sint64 setValue:1010 forKey:210];
- [msg.mapSint64Sint64 setValue:111 forKey:2011];
- [msg.mapFixed32Fixed32 setValue:1012 forKey:212];
- [msg.mapFixed32Fixed32 setValue:113 forKey:2013];
- [msg.mapFixed64Fixed64 setValue:1014 forKey:214];
- [msg.mapFixed64Fixed64 setValue:115 forKey:2015];
- [msg.mapSfixed32Sfixed32 setValue:1016 forKey:216];
- [msg.mapSfixed32Sfixed32 setValue:117 forKey:2017];
- [msg.mapSfixed64Sfixed64 setValue:1018 forKey:218];
- [msg.mapSfixed64Sfixed64 setValue:119 forKey:2019];
- [msg.mapInt32Float setValue:1020.f forKey:220];
- [msg.mapInt32Float setValue:121.f forKey:2021];
- [msg.mapInt32Double setValue:1022. forKey:222];
- [msg.mapInt32Double setValue:123. forKey:2023];
- [msg.mapBoolBool setValue:false forKey:true];
- [msg.mapBoolBool setValue:true forKey:false];
+ [msg.mapInt32Int32 setInt32:1000 forKey:200];
+ [msg.mapInt32Int32 setInt32:101 forKey:2001];
+ [msg.mapInt64Int64 setInt64:1002 forKey:202];
+ [msg.mapInt64Int64 setInt64:103 forKey:2003];
+ [msg.mapUint32Uint32 setUInt32:1004 forKey:204];
+ [msg.mapUint32Uint32 setUInt32:105 forKey:2005];
+ [msg.mapUint64Uint64 setUInt64:1006 forKey:206];
+ [msg.mapUint64Uint64 setUInt64:107 forKey:2007];
+ [msg.mapSint32Sint32 setInt32:1008 forKey:208];
+ [msg.mapSint32Sint32 setInt32:109 forKey:2009];
+ [msg.mapSint64Sint64 setInt64:1010 forKey:210];
+ [msg.mapSint64Sint64 setInt64:111 forKey:2011];
+ [msg.mapFixed32Fixed32 setUInt32:1012 forKey:212];
+ [msg.mapFixed32Fixed32 setUInt32:113 forKey:2013];
+ [msg.mapFixed64Fixed64 setUInt64:1014 forKey:214];
+ [msg.mapFixed64Fixed64 setUInt64:115 forKey:2015];
+ [msg.mapSfixed32Sfixed32 setInt32:1016 forKey:216];
+ [msg.mapSfixed32Sfixed32 setInt32:117 forKey:2017];
+ [msg.mapSfixed64Sfixed64 setInt64:1018 forKey:218];
+ [msg.mapSfixed64Sfixed64 setInt64:119 forKey:2019];
+ [msg.mapInt32Float setFloat:1020.f forKey:220];
+ [msg.mapInt32Float setFloat:121.f forKey:2021];
+ [msg.mapInt32Double setDouble:1022. forKey:222];
+ [msg.mapInt32Double setDouble:123. forKey:2023];
+ [msg.mapBoolBool setBool:false forKey:true];
+ [msg.mapBoolBool setBool:true forKey:false];
msg.mapStringString[@"224"] = @"1024";
msg.mapStringString[@"2025"] = @"125";
msg.mapStringBytes[@"226"] = DataFromCStr("1026");
@@ -1074,12 +1171,12 @@ static NSData *DataFromCStr(const char *str) {
val1.optionalInt32 = 1028;
Message2 *val2 = [[Message2 alloc] init];
val2.optionalInt32 = 129;
- [msg.mapStringMessage setValue:val1 forKey:@"228"];
- [msg.mapStringMessage setValue:val2 forKey:@"2029"];
+ [msg.mapStringMessage setObject:val1 forKey:@"228"];
+ [msg.mapStringMessage setObject:val2 forKey:@"2029"];
[msg.mapInt32Bytes setObject:DataFromCStr("1030 bytes") forKey:230];
[msg.mapInt32Bytes setObject:DataFromCStr("131") forKey:2031];
- [msg.mapInt32Enum setValue:Message2_Enum_Bar forKey:232];
- [msg.mapInt32Enum setValue:Message2_Enum_Baz forKey:2033];
+ [msg.mapInt32Enum setEnum:Message2_Enum_Bar forKey:232];
+ [msg.mapInt32Enum setEnum:Message2_Enum_Baz forKey:2033];
Message2 *val3 = [[Message2 alloc] init];
val3.optionalInt32 = 1034;
Message2 *val4 = [[Message2 alloc] init];
diff --git a/objectivec/Tests/GPBMessageTests.m b/objectivec/Tests/GPBMessageTests.m
index f79b8128..a3c5a6b4 100644
--- a/objectivec/Tests/GPBMessageTests.m
+++ b/objectivec/Tests/GPBMessageTests.m
@@ -55,7 +55,6 @@
[message setOptionalInt32:1];
[message setOptionalString:@"foo"];
[message setOptionalForeignMessage:[ForeignMessage message]];
- message.repeatedStringArray = [NSMutableArray array];
[message.repeatedStringArray addObject:@"bar"];
return message;
}
@@ -67,7 +66,6 @@
ForeignMessage *foreignMessage = [ForeignMessage message];
[foreignMessage setC:3];
[message setOptionalForeignMessage:foreignMessage];
- message.repeatedStringArray = [NSMutableArray array];
[message.repeatedStringArray addObject:@"qux"];
return message;
}
@@ -76,7 +74,6 @@
TestAllTypes *message = [TestAllTypes message];
[message setOptionalInt64:2];
[message setOptionalString:@"baz"];
- message.repeatedStringArray = [NSMutableArray array];
[message.repeatedStringArray addObject:@"qux"];
return message;
}
@@ -89,7 +86,6 @@
ForeignMessage *foreignMessage = [ForeignMessage message];
[foreignMessage setC:3];
[message setOptionalForeignMessage:foreignMessage];
- message.repeatedStringArray = [NSMutableArray array];
[message.repeatedStringArray addObject:@"qux"];
[message.repeatedStringArray addObject:@"bar"];
return message;
@@ -102,7 +98,6 @@
[message setOptionalString:@"foo"];
ForeignMessage *foreignMessage = [ForeignMessage message];
[message setOptionalForeignMessage:foreignMessage];
- message.repeatedStringArray = [NSMutableArray array];
[message.repeatedStringArray addObject:@"qux"];
[message.repeatedStringArray addObject:@"bar"];
return message;
@@ -248,7 +243,6 @@
[message setOptionalMessage:self.testRequiredInitialized];
XCTAssertTrue(message.initialized);
- message.repeatedMessageArray = [NSMutableArray array];
[message.repeatedMessageArray addObject:[TestRequired message]];
XCTAssertFalse(message.initialized);
@@ -300,7 +294,6 @@
- (void)testDataFromNestedUninitialized {
TestRequiredForeign *message = [TestRequiredForeign message];
[message setOptionalMessage:[TestRequired message]];
- message.repeatedMessageArray = [NSMutableArray array];
[message.repeatedMessageArray addObject:[TestRequired message]];
[message.repeatedMessageArray addObject:[TestRequired message]];
NSData *data = [message data];
@@ -319,7 +312,6 @@
TestRequiredForeign *message = [TestRequiredForeign message];
[message setOptionalMessage:[TestRequired message]];
- message.repeatedMessageArray = [NSMutableArray array];
[message.repeatedMessageArray addObject:[TestRequired message]];
[message.repeatedMessageArray addObject:[TestRequired message]];
@@ -1179,7 +1171,7 @@
XCTAssertFalse([message2.a hasA]);
// But adding an element to the map should.
- [message.a.a.iToI setValue:100 forKey:200];
+ [message.a.a.iToI setInt32:100 forKey:200];
XCTAssertTrue([message hasA]);
XCTAssertTrue([message.a hasA]);
XCTAssertEqual([message.a.a.iToI count], (NSUInteger)1);
@@ -1198,7 +1190,7 @@
message1a.a.iToI = message1b.a.iToI;
XCTAssertTrue([message1a hasA]);
XCTAssertFalse([message1b hasA]);
- [message1a.a.iToI setValue:1 forKey:2];
+ [message1a.a.iToI setInt32:1 forKey:2];
XCTAssertTrue([message1a hasA]);
XCTAssertTrue([message1b hasA]);
XCTAssertEqual(message1a.a.iToI, message1b.a.iToI);
@@ -1232,7 +1224,7 @@
// with different objects that are equal).
TestRecursiveMessageWithRepeatedField *message3 =
[TestRecursiveMessageWithRepeatedField message];
- message3.iToI = [GPBInt32Int32Dictionary dictionaryWithValue:10 forKey:20];
+ message3.iToI = [GPBInt32Int32Dictionary dictionaryWithInt32:10 forKey:20];
message3.strToStr =
[NSMutableDictionary dictionaryWithObject:@"abc" forKey:@"123"];
XCTAssertNotNil(message.iToI);
@@ -1300,7 +1292,7 @@
XCTAssertFalse([message hasA]);
GPBInt32Int32Dictionary *iToI = [message.a.iToI retain];
XCTAssertEqual(iToI->_autocreator, message.a); // Pointer comparision
- message.a.iToI = [GPBInt32Int32Dictionary dictionaryWithValue:6 forKey:7];
+ message.a.iToI = [GPBInt32Int32Dictionary dictionaryWithInt32:6 forKey:7];
XCTAssertTrue([message hasA]);
XCTAssertNotEqual(message.a.iToI, iToI); // Pointer comparision
XCTAssertNil(iToI->_autocreator);
@@ -1828,6 +1820,24 @@
XCTAssertEqualObjects(enumDescriptor, expectedDescriptor);
}
+- (void)testPropertyNaming {
+ // objectivec_helpers.cc has some special handing to get proper all caps
+ // for a few cases to meet objc developer expectations.
+ //
+ // This "test" confirms that the expected names are generated, otherwise the
+ // test itself will fail to compile.
+ ObjCPropertyNaming *msg = [ObjCPropertyNaming message];
+ // On their own, at the end, in the middle.
+ msg.URL = @"good";
+ msg.thumbnailURL = @"good";
+ msg.URLFoo = @"good";
+ msg.someURLBlah = @"good";
+ msg.HTTP = @"good";
+ msg.HTTPS = @"good";
+ // No caps since it was "urls".
+ [msg.urlsArray addObject:@"good"];
+}
+
- (void)testEnumNaming {
// objectivec_helpers.cc has some interesting cases to deal with in
// EnumValueName/EnumValueShortName. Confirm that things generated as
@@ -1937,4 +1947,76 @@
EnumTestMsg_MyEnum_NegTwo);
}
+- (void)testOneBasedEnumHolder {
+ // Test case for https://github.com/google/protobuf/issues/1453
+ // Message with no explicit defaults, but a non zero default for an enum.
+ MessageWithOneBasedEnum *enumMsg = [MessageWithOneBasedEnum message];
+ XCTAssertEqual(enumMsg.enumField, MessageWithOneBasedEnum_OneBasedEnum_One);
+}
+
+- (void)testBoolOffsetUsage {
+ // Bools use storage within has_bits; this test ensures that this is honored
+ // in all places where things should crash or fail based on reading out of
+ // field storage instead.
+ BoolOnlyMessage *msg1 = [BoolOnlyMessage message];
+ BoolOnlyMessage *msg2 = [BoolOnlyMessage message];
+
+ msg1.boolField1 = YES;
+ msg2.boolField1 = YES;
+ msg1.boolField3 = YES;
+ msg2.boolField3 = YES;
+ msg1.boolField5 = YES;
+ msg2.boolField5 = YES;
+ msg1.boolField7 = YES;
+ msg2.boolField7 = YES;
+ msg1.boolField9 = YES;
+ msg2.boolField9 = YES;
+ msg1.boolField11 = YES;
+ msg2.boolField11 = YES;
+ msg1.boolField13 = YES;
+ msg2.boolField13 = YES;
+ msg1.boolField15 = YES;
+ msg2.boolField15 = YES;
+ msg1.boolField17 = YES;
+ msg2.boolField17 = YES;
+ msg1.boolField19 = YES;
+ msg2.boolField19 = YES;
+ msg1.boolField21 = YES;
+ msg2.boolField21 = YES;
+ msg1.boolField23 = YES;
+ msg2.boolField23 = YES;
+ msg1.boolField25 = YES;
+ msg2.boolField25 = YES;
+ msg1.boolField27 = YES;
+ msg2.boolField27 = YES;
+ msg1.boolField29 = YES;
+ msg2.boolField29 = YES;
+ msg1.boolField31 = YES;
+ msg2.boolField31 = YES;
+
+ msg1.boolField32 = YES;
+ msg2.boolField32 = YES;
+
+ XCTAssertTrue(msg1 != msg2); // Different pointers.
+ XCTAssertEqual([msg1 hash], [msg2 hash]);
+ XCTAssertEqualObjects(msg1, msg2);
+
+ BoolOnlyMessage *msg1Prime = [[msg1 copy] autorelease];
+ XCTAssertTrue(msg1Prime != msg1); // Different pointers.
+ XCTAssertEqual([msg1 hash], [msg1Prime hash]);
+ XCTAssertEqualObjects(msg1, msg1Prime);
+
+ // Field set in one, but not the other means they don't match (even if
+ // set to default value).
+ msg1Prime.boolField2 = NO;
+ XCTAssertNotEqualObjects(msg1Prime, msg1);
+ // And when set to different values.
+ msg1.boolField2 = YES;
+ XCTAssertNotEqualObjects(msg1Prime, msg1);
+ // And then they match again.
+ msg1.boolField2 = NO;
+ XCTAssertEqualObjects(msg1Prime, msg1);
+ XCTAssertEqual([msg1 hash], [msg1Prime hash]);
+}
+
@end
diff --git a/objectivec/Tests/GPBStringTests.m b/objectivec/Tests/GPBStringTests.m
deleted file mode 100644
index 802afa7d..00000000
--- a/objectivec/Tests/GPBStringTests.m
+++ /dev/null
@@ -1,513 +0,0 @@
-// 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.
-
-#import <XCTest/XCTest.h>
-
-#import "GPBCodedInputStream_PackagePrivate.h"
-#import "GPBTestUtilities.h"
-
-@interface TestClass : NSObject
-@property(nonatomic, retain) NSString *foo;
-@end
-
-@implementation TestClass
-@synthesize foo;
-@end
-
-@interface GPBStringTests : XCTestCase {
- NSMutableArray *nsStrings_;
- NSMutableArray *gpbStrings_;
-}
-
-@end
-
-@implementation GPBStringTests
-
-- (void)setUp {
- [super setUp];
- const char *strings[] = {
- "ascii string",
- "non-ascii string \xc3\xa9", // e with acute accent
- "\xe2\x99\xa1", // White Heart
- "mix \xe2\x99\xa4 string", // White Spade
-
- // Decomposed forms from http://www.unicode.org/reports/tr15/
- // 1.2 Singletons
- "\xe2\x84\xa8 = A\xcc\x8a = \xc3\x85", "\xe2\x84\xa6 = \xce\xa9",
-
- // 1.2 Canonical Composites
- "A\xcc\x8a = \xc3\x85",
- "o\xcc\x82 = \xc3\xb4",
-
- // 1.2 Multiple Combining Marks
- "s\xcc\xa3\xcc\x87 = \xe1\xb9\xa9",
- "\xe1\xb8\x8b\xcc\xa3 = d\xcc\xa3\xcc\x87 = \xe1\xb8\x8d \xcc\x87",
- "q\xcc\x87\xcc\xa3 = q\xcc\xa3\xcc\x87",
-
- // BOM
- "\xEF\xBB\xBF String with BOM",
- "String with \xEF\xBB\xBF in middle",
- "String with end bom \xEF\xBB\xBF",
- "\xEF\xBB\xBF\xe2\x99\xa1", // BOM White Heart
- "\xEF\xBB\xBF\xEF\xBB\xBF String with Two BOM",
-
- // Supplementary Plane
- "\xf0\x9d\x84\x9e", // MUSICAL SYMBOL G CLEF
-
- // Tags
- "\xf3\xa0\x80\x81", // Language Tag
-
- // Variation Selectors
- "\xf3\xa0\x84\x80", // VARIATION SELECTOR-17
-
- // Specials
- "\xef\xbb\xbf\xef\xbf\xbd\xef\xbf\xbf",
-
- // Left To Right/Right To Left
- // http://unicode.org/reports/tr9/
-
- // Hello! <RTL marker>!Merhaba<LTR marker>
- "Hello! \xE2\x80\x8F!\xd9\x85\xd8\xb1\xd8\xad\xd8\xa8\xd8\xa7\xE2\x80\x8E",
-
- "\xE2\x80\x8E LTR At Start",
- "LTR At End\xE2\x80\x8E",
- "\xE2\x80\x8F RTL At Start",
- "RTL At End\xE2\x80\x8F",
- "\xE2\x80\x8E\xE2\x80\x8E Double LTR \xE2\x80\x8E\xE2\x80\x8E",
- "\xE2\x80\x8F\xE2\x80\x8F Double RTL \xE2\x80\x8F\xE2\x80\x8F",
- "\xE2\x80\x8F\xE2\x80\x8E LTR-RTL LTR-RTL \xE2\x80\x8E\xE2\x80\x8F",
- };
- size_t stringsSize = GPBARRAYSIZE(strings);
- size_t numberUnicodeStrings = 17375;
- nsStrings_ = [[NSMutableArray alloc]
- initWithCapacity:stringsSize + numberUnicodeStrings];
- gpbStrings_ = [[NSMutableArray alloc]
- initWithCapacity:stringsSize + numberUnicodeStrings];
- for (size_t i = 0; i < stringsSize; ++i) {
- size_t length = strlen(strings[i]);
- NSString *nsString = [[NSString alloc] initWithBytes:strings[i]
- length:length
- encoding:NSUTF8StringEncoding];
- [nsStrings_ addObject:nsString];
- [nsString release];
- GPBString *gpbString = GPBCreateGPBStringWithUTF8(strings[i], length);
- [gpbStrings_ addObject:gpbString];
- [gpbString release];
- }
-
- // Generate all UTF8 characters in a variety of strings
- // UTF8-1 - 1 Byte UTF 8 chars
- int length = 0x7F + 1;
- char *buffer = (char *)calloc(length, 1);
- for (int i = 0; i < length; ++i) {
- buffer[i] = (char)i;
- }
- NSString *nsString = [[NSString alloc] initWithBytes:buffer
- length:length
- encoding:NSUTF8StringEncoding];
- [nsStrings_ addObject:nsString];
- [nsString release];
- GPBString *gpbString = GPBCreateGPBStringWithUTF8(buffer, length);
- [gpbStrings_ addObject:gpbString];
- [gpbString release];
-
- // UTF8-2 - 2 Byte UTF 8 chars
- int pointLength = 0xbf - 0x80 + 1;
- length = pointLength * 2;
- buffer = (char *)calloc(length, 1);
- for (int i = 0xc2; i <= 0xdf; ++i) {
- char *bufferPtr = buffer;
- for (int j = 0x80; j <= 0xbf; ++j) {
- (*bufferPtr++) = (char)i;
- (*bufferPtr++) = (char)j;
- }
- nsString = [[NSString alloc] initWithBytes:buffer
- length:length
- encoding:NSUTF8StringEncoding];
- [nsStrings_ addObject:nsString];
- [nsString release];
- gpbString = GPBCreateGPBStringWithUTF8(buffer, length);
- [gpbStrings_ addObject:gpbString];
- [gpbString release];
- }
- free(buffer);
-
- // UTF8-3 - 3 Byte UTF 8 chars
- length = pointLength * 3;
- buffer = (char *)calloc(length, 1);
- for (int i = 0xa0; i <= 0xbf; ++i) {
- char *bufferPtr = buffer;
- for (int j = 0x80; j <= 0xbf; ++j) {
- (*bufferPtr++) = (char)0xE0;
- (*bufferPtr++) = (char)i;
- (*bufferPtr++) = (char)j;
- }
- nsString = [[NSString alloc] initWithBytes:buffer
- length:length
- encoding:NSUTF8StringEncoding];
- [nsStrings_ addObject:nsString];
- [nsString release];
- gpbString = GPBCreateGPBStringWithUTF8(buffer, length);
- [gpbStrings_ addObject:gpbString];
- [gpbString release];
- }
- for (int i = 0xe1; i <= 0xec; ++i) {
- for (int j = 0x80; j <= 0xbf; ++j) {
- char *bufferPtr = buffer;
- for (int k = 0x80; k <= 0xbf; ++k) {
- (*bufferPtr++) = (char)i;
- (*bufferPtr++) = (char)j;
- (*bufferPtr++) = (char)k;
- }
- nsString = [[NSString alloc] initWithBytes:buffer
- length:length
- encoding:NSUTF8StringEncoding];
- [nsStrings_ addObject:nsString];
- [nsString release];
- gpbString = GPBCreateGPBStringWithUTF8(buffer, length);
- [gpbStrings_ addObject:gpbString];
- [gpbString release];
- }
- }
- for (int i = 0x80; i <= 0x9f; ++i) {
- char *bufferPtr = buffer;
- for (int j = 0x80; j <= 0xbf; ++j) {
- (*bufferPtr++) = (char)0xED;
- (*bufferPtr++) = (char)i;
- (*bufferPtr++) = (char)j;
- }
- nsString = [[NSString alloc] initWithBytes:buffer
- length:length
- encoding:NSUTF8StringEncoding];
- [nsStrings_ addObject:nsString];
- [nsString release];
- gpbString = GPBCreateGPBStringWithUTF8(buffer, length);
- [gpbStrings_ addObject:gpbString];
- [gpbString release];
- }
- for (int i = 0xee; i <= 0xef; ++i) {
- for (int j = 0x80; j <= 0xbf; ++j) {
- char *bufferPtr = buffer;
- for (int k = 0x80; k <= 0xbf; ++k) {
- (*bufferPtr++) = (char)i;
- (*bufferPtr++) = (char)j;
- (*bufferPtr++) = (char)k;
- }
- nsString = [[NSString alloc] initWithBytes:buffer
- length:length
- encoding:NSUTF8StringEncoding];
- [nsStrings_ addObject:nsString];
- [nsString release];
- gpbString = GPBCreateGPBStringWithUTF8(buffer, length);
- [gpbStrings_ addObject:gpbString];
- [gpbString release];
- }
- }
- free(buffer);
-
- // UTF8-4 - 4 Byte UTF 8 chars
- length = pointLength * 4;
- buffer = (char *)calloc(length, 1);
- for (int i = 0x90; i <= 0xbf; ++i) {
- for (int j = 0x80; j <= 0xbf; ++j) {
- char *bufferPtr = buffer;
- for (int k = 0x80; k <= 0xbf; ++k) {
- (*bufferPtr++) = (char)0xF0;
- (*bufferPtr++) = (char)i;
- (*bufferPtr++) = (char)j;
- (*bufferPtr++) = (char)k;
- }
- nsString = [[NSString alloc] initWithBytes:buffer
- length:length
- encoding:NSUTF8StringEncoding];
- [nsStrings_ addObject:nsString];
- [nsString release];
- gpbString = GPBCreateGPBStringWithUTF8(buffer, length);
- [gpbStrings_ addObject:gpbString];
- [gpbString release];
- }
- }
- for (int i = 0xf1; i <= 0xf3; ++i) {
- for (int j = 0x80; j <= 0xbf; ++j) {
- for (int k = 0x80; k <= 0xbf; ++k) {
- char *bufferPtr = buffer;
- for (int m = 0x80; m <= 0xbf; ++m) {
- (*bufferPtr++) = (char)i;
- (*bufferPtr++) = (char)j;
- (*bufferPtr++) = (char)k;
- (*bufferPtr++) = (char)m;
- }
- nsString = [[NSString alloc] initWithBytes:buffer
- length:length
- encoding:NSUTF8StringEncoding];
- [nsStrings_ addObject:nsString];
- [nsString release];
- gpbString = GPBCreateGPBStringWithUTF8(buffer, length);
- [gpbStrings_ addObject:gpbString];
- [gpbString release];
- }
- }
- }
- for (int i = 0x80; i <= 0x8f; ++i) {
- for (int j = 0x80; j <= 0xbf; ++j) {
- char *bufferPtr = buffer;
- for (int k = 0x80; k <= 0xbf; ++k) {
- (*bufferPtr++) = (char)0xF4;
- (*bufferPtr++) = (char)i;
- (*bufferPtr++) = (char)j;
- (*bufferPtr++) = (char)k;
- }
- nsString = [[NSString alloc] initWithBytes:buffer
- length:length
- encoding:NSUTF8StringEncoding];
- [nsStrings_ addObject:nsString];
- [nsString release];
- gpbString = GPBCreateGPBStringWithUTF8(buffer, length);
- [gpbStrings_ addObject:gpbString];
- [gpbString release];
- }
- }
- free(buffer);
-}
-
-- (void)tearDown {
- [nsStrings_ release];
- [gpbStrings_ release];
- [super tearDown];
-}
-
-- (void)testLength {
- size_t i = 0;
- for (NSString *nsString in nsStrings_) {
- GPBString *gpbString = gpbStrings_[i];
- XCTAssertEqual([nsString length], [gpbString length], @"%@ %@", nsString,
- gpbString);
- ++i;
- }
-}
-
-- (void)testLengthOfBytesUsingEncoding {
- NSStringEncoding encodings[] = {
- NSUTF8StringEncoding,
- NSASCIIStringEncoding,
- NSISOLatin1StringEncoding,
- NSMacOSRomanStringEncoding,
- NSUTF16StringEncoding,
- NSUTF32StringEncoding,
- };
-
- for (size_t j = 0; j < GPBARRAYSIZE(encodings); ++j) {
- NSStringEncoding testEncoding = encodings[j];
- size_t i = 0;
- for (NSString *nsString in nsStrings_) {
- GPBString *gpbString = gpbStrings_[i];
- XCTAssertEqual([nsString lengthOfBytesUsingEncoding:testEncoding],
- [gpbString lengthOfBytesUsingEncoding:testEncoding],
- @"%@ %@", nsString, gpbString);
- ++i;
- }
- }
-}
-
-- (void)testHash {
- size_t i = 0;
- for (NSString *nsString in nsStrings_) {
- GPBString *gpbString = gpbStrings_[i];
- XCTAssertEqual([nsString hash], [gpbString hash], @"%@ %@", nsString,
- gpbString);
- ++i;
- }
-}
-
-- (void)testEquality {
- size_t i = 0;
- for (NSString *nsString in nsStrings_) {
- GPBString *gpbString = gpbStrings_[i];
- XCTAssertEqualObjects(nsString, gpbString);
- ++i;
- }
-}
-
-- (void)testCharacterAtIndex {
- size_t i = 0;
- for (NSString *nsString in nsStrings_) {
- GPBString *gpbString = gpbStrings_[i];
- NSUInteger length = [nsString length];
- for (size_t j = 0; j < length; ++j) {
- unichar nsChar = [nsString characterAtIndex:j];
- unichar pbChar = [gpbString characterAtIndex:j];
- XCTAssertEqual(nsChar, pbChar, @"%@ %@ %zu", nsString, gpbString, j);
- }
- ++i;
- }
-}
-
-- (void)testCopy {
- size_t i = 0;
- for (NSString *nsString in nsStrings_) {
- GPBString *gpbString = [[gpbStrings_[i] copy] autorelease];
- XCTAssertEqualObjects(nsString, gpbString);
- ++i;
- }
-}
-
-- (void)testMutableCopy {
- size_t i = 0;
- for (NSString *nsString in nsStrings_) {
- GPBString *gpbString = [[gpbStrings_[i] mutableCopy] autorelease];
- XCTAssertEqualObjects(nsString, gpbString);
- ++i;
- }
-}
-
-- (void)testGetBytes {
- // Do an attempt at a reasonably exhaustive test of get bytes.
- // Get bytes with options other than 0 should always fall through to Apple
- // code so we don't bother testing that path.
- size_t i = 0;
- char pbBuffer[256];
- char nsBuffer[256];
- int count = 0;
- for (NSString *nsString in nsStrings_) {
- GPBString *gpbString = gpbStrings_[i];
- for (int j = 0; j < 100; ++j) {
- // [NSString getBytes:maxLength:usedLength:encoding:options:range:remainingRange]
- // does not return reliable results if the maxLength argument is 0,
- // or range is 0,0.
- // Radar 16385183
- NSUInteger length = [nsString length];
- NSUInteger maxBufferCount = (arc4random() % (length + 3)) + 1;
- NSUInteger rangeStart = arc4random() % length;
- NSUInteger rangeLength = arc4random() % (length - rangeStart);
-
- NSRange range = NSMakeRange(rangeStart, rangeLength);
-
- NSStringEncoding encodings[] = {
- NSASCIIStringEncoding,
- NSUTF8StringEncoding,
- NSUTF16StringEncoding,
- };
-
- for (size_t k = 0; k < GPBARRAYSIZE(encodings); ++k) {
- NSStringEncoding encoding = encodings[k];
- NSUInteger pbUsedBufferCount = 0;
- NSUInteger nsUsedBufferCount = 0;
- NSRange pbLeftOver = NSMakeRange(0, 0);
- NSRange nsLeftOver = NSMakeRange(0, 0);
-
- BOOL pbGotBytes = [gpbString getBytes:pbBuffer
- maxLength:maxBufferCount
- usedLength:&pbUsedBufferCount
- encoding:encoding
- options:0
- range:range
- remainingRange:&pbLeftOver];
- BOOL nsGotBytes = [nsString getBytes:nsBuffer
- maxLength:maxBufferCount
- usedLength:&nsUsedBufferCount
- encoding:encoding
- options:0
- range:range
- remainingRange:&nsLeftOver];
- XCTAssertEqual(
- (bool)pbGotBytes, (bool)nsGotBytes,
- @"PB %d '%@' vs '%@' Encoding:%tu MaxLength: %tu Range: %@ "
- @"Used: %tu, %tu LeftOver %@, %@)",
- count, gpbString, nsString, encoding, maxBufferCount,
- NSStringFromRange(range), pbUsedBufferCount, nsUsedBufferCount,
- NSStringFromRange(pbLeftOver), NSStringFromRange(nsLeftOver));
- XCTAssertEqual(
- pbUsedBufferCount, nsUsedBufferCount,
- @"PB %d '%@' vs '%@' Encoding:%tu MaxLength: %tu Range: %@ "
- @"Used: %tu, %tu LeftOver %@, %@)",
- count, gpbString, nsString, encoding, maxBufferCount,
- NSStringFromRange(range), pbUsedBufferCount, nsUsedBufferCount,
- NSStringFromRange(pbLeftOver), NSStringFromRange(nsLeftOver));
- XCTAssertEqual(
- pbLeftOver.location, nsLeftOver.location,
- @"PB %d '%@' vs '%@' Encoding:%tu MaxLength: %tu Range: %@ "
- @"Used: %tu, %tu LeftOver %@, %@)",
- count, gpbString, nsString, encoding, maxBufferCount,
- NSStringFromRange(range), pbUsedBufferCount, nsUsedBufferCount,
- NSStringFromRange(pbLeftOver), NSStringFromRange(nsLeftOver));
- XCTAssertEqual(
- pbLeftOver.length, nsLeftOver.length,
- @"PB %d '%@' vs '%@' Encoding:%tu MaxLength: %tu Range: %@ "
- @"Used: %tu, %tu LeftOver %@, %@)",
- count, gpbString, nsString, encoding, maxBufferCount,
- NSStringFromRange(range), pbUsedBufferCount, nsUsedBufferCount,
- NSStringFromRange(pbLeftOver), NSStringFromRange(nsLeftOver));
- ++count;
- }
- }
- ++i;
- }
-}
-
-- (void)testLengthAndGetBytes {
- // This test exists as an attempt to ferret out a bug.
- // http://b/13516532
- size_t i = 0;
- char pbBuffer[256];
- char nsBuffer[256];
- for (NSString *nsString in nsStrings_) {
- GPBString *gpbString = gpbStrings_[i++];
- NSUInteger nsLength =
- [nsString lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
- NSUInteger pbLength =
- [gpbString lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
- XCTAssertEqual(nsLength, pbLength, @"%@ %@", nsString, gpbString);
- NSUInteger pbUsedBufferCount = 0;
- NSUInteger nsUsedBufferCount = 0;
- NSRange pbLeftOver = NSMakeRange(0, 0);
- NSRange nsLeftOver = NSMakeRange(0, 0);
- NSRange range = NSMakeRange(0, [gpbString length]);
- BOOL pbGotBytes = [gpbString getBytes:pbBuffer
- maxLength:sizeof(pbBuffer)
- usedLength:&pbUsedBufferCount
- encoding:NSUTF8StringEncoding
- options:0
- range:range
- remainingRange:&pbLeftOver];
- BOOL nsGotBytes = [nsString getBytes:nsBuffer
- maxLength:sizeof(nsBuffer)
- usedLength:&nsUsedBufferCount
- encoding:NSUTF8StringEncoding
- options:0
- range:range
- remainingRange:&nsLeftOver];
- XCTAssertTrue(pbGotBytes, @"%@", gpbString);
- XCTAssertTrue(nsGotBytes, @"%@", nsString);
- XCTAssertEqual(pbUsedBufferCount, pbLength, @"%@", gpbString);
- XCTAssertEqual(nsUsedBufferCount, nsLength, @"%@", nsString);
- }
-}
-
-@end
diff --git a/objectivec/Tests/GPBSwiftTests.swift b/objectivec/Tests/GPBSwiftTests.swift
index 36ed2a62..b5999c21 100644
--- a/objectivec/Tests/GPBSwiftTests.swift
+++ b/objectivec/Tests/GPBSwiftTests.swift
@@ -53,12 +53,12 @@ class GPBBridgeTests: XCTestCase {
msg.repeatedStringArray.addObject("pqr")
msg.repeatedEnumArray.addValue(Message2_Enum.Bar.rawValue)
msg.repeatedEnumArray.addValue(Message2_Enum.Baz.rawValue)
- msg.mapInt32Int32.setValue(400, forKey:500)
- msg.mapInt32Int32.setValue(401, forKey:501)
+ msg.mapInt32Int32.setInt32(400, forKey:500)
+ msg.mapInt32Int32.setInt32(401, forKey:501)
msg.mapStringString.setObject("foo", forKey:"bar")
msg.mapStringString.setObject("abc", forKey:"xyz")
- msg.mapInt32Enum.setValue(Message2_Enum.Bar.rawValue, forKey:600)
- msg.mapInt32Enum.setValue(Message2_Enum.Baz.rawValue, forKey:601)
+ msg.mapInt32Enum.setEnum(Message2_Enum.Bar.rawValue, forKey:600)
+ msg.mapInt32Enum.setEnum(Message2_Enum.Baz.rawValue, forKey:601)
// Check has*.
XCTAssertTrue(msg.hasOptionalInt32)
@@ -90,18 +90,18 @@ class GPBBridgeTests: XCTestCase {
XCTAssertEqual(msg.repeatedEnumArray.valueAtIndex(1), Message2_Enum.Baz.rawValue)
XCTAssertEqual(msg.repeatedInt64Array.count, UInt(0))
XCTAssertEqual(msg.mapInt32Int32.count, UInt(2))
- var intValue: Int32 = 0;
- XCTAssertTrue(msg.mapInt32Int32.valueForKey(500, value:&intValue))
+ var intValue: Int32 = 0
+ XCTAssertTrue(msg.mapInt32Int32.getInt32(&intValue, forKey: 500))
XCTAssertEqual(intValue, Int32(400))
- XCTAssertTrue(msg.mapInt32Int32.valueForKey(501, value:&intValue))
+ XCTAssertTrue(msg.mapInt32Int32.getInt32(&intValue, forKey: 501))
XCTAssertEqual(intValue, Int32(401))
XCTAssertEqual(msg.mapStringString.count, Int(2))
XCTAssertEqual(msg.mapStringString.objectForKey("bar") as? String, "foo")
XCTAssertEqual(msg.mapStringString.objectForKey("xyz") as? String, "abc")
XCTAssertEqual(msg.mapInt32Enum.count, UInt(2))
- XCTAssertTrue(msg.mapInt32Enum.valueForKey(600, value:&intValue))
+ XCTAssertTrue(msg.mapInt32Enum.getEnum(&intValue, forKey:600))
XCTAssertEqual(intValue, Message2_Enum.Bar.rawValue)
- XCTAssertTrue(msg.mapInt32Enum.valueForKey(601, value:&intValue))
+ XCTAssertTrue(msg.mapInt32Enum.getEnum(&intValue, forKey:601))
XCTAssertEqual(intValue, Message2_Enum.Baz.rawValue)
// Clearing a string with nil.
@@ -151,11 +151,11 @@ class GPBBridgeTests: XCTestCase {
msg.repeatedEnumArray.addValue(Message3_Enum.Bar.rawValue)
msg.repeatedEnumArray.addRawValue(666)
SetMessage3_OptionalEnum_RawValue(msg2, 666)
- msg.mapInt32Int32.setValue(400, forKey:500)
- msg.mapInt32Int32.setValue(401, forKey:501)
+ msg.mapInt32Int32.setInt32(400, forKey:500)
+ msg.mapInt32Int32.setInt32(401, forKey:501)
msg.mapStringString.setObject("foo", forKey:"bar")
msg.mapStringString.setObject("abc", forKey:"xyz")
- msg.mapInt32Enum.setValue(Message2_Enum.Bar.rawValue, forKey:600)
+ msg.mapInt32Enum.setEnum(Message2_Enum.Bar.rawValue, forKey:600)
// "proto3" syntax lets enum get unknown values.
msg.mapInt32Enum.setRawValue(666, forKey:601)
@@ -183,20 +183,20 @@ class GPBBridgeTests: XCTestCase {
XCTAssertEqual(msg2.optionalEnum, Message3_Enum.GPBUnrecognizedEnumeratorValue)
XCTAssertEqual(Message3_OptionalEnum_RawValue(msg2), Int32(666))
XCTAssertEqual(msg.mapInt32Int32.count, UInt(2))
- var intValue: Int32 = 0;
- XCTAssertTrue(msg.mapInt32Int32.valueForKey(500, value:&intValue))
+ var intValue: Int32 = 0
+ XCTAssertTrue(msg.mapInt32Int32.getInt32(&intValue, forKey:500))
XCTAssertEqual(intValue, Int32(400))
- XCTAssertTrue(msg.mapInt32Int32.valueForKey(501, value:&intValue))
+ XCTAssertTrue(msg.mapInt32Int32.getInt32(&intValue, forKey:501))
XCTAssertEqual(intValue, Int32(401))
XCTAssertEqual(msg.mapStringString.count, Int(2))
XCTAssertEqual(msg.mapStringString.objectForKey("bar") as? String, "foo")
XCTAssertEqual(msg.mapStringString.objectForKey("xyz") as? String, "abc")
XCTAssertEqual(msg.mapInt32Enum.count, UInt(2))
- XCTAssertTrue(msg.mapInt32Enum.valueForKey(600, value:&intValue))
+ XCTAssertTrue(msg.mapInt32Enum.getEnum(&intValue, forKey:600))
XCTAssertEqual(intValue, Message2_Enum.Bar.rawValue)
- XCTAssertTrue(msg.mapInt32Enum.valueForKey(601, value:&intValue))
+ XCTAssertTrue(msg.mapInt32Enum.getEnum(&intValue, forKey:601))
XCTAssertEqual(intValue, Message3_Enum.GPBUnrecognizedEnumeratorValue.rawValue)
- XCTAssertTrue(msg.mapInt32Enum.valueForKey(601, rawValue:&intValue))
+ XCTAssertTrue(msg.mapInt32Enum.getRawValue(&intValue, forKey:601))
XCTAssertEqual(intValue, 666)
// Clearing a string with nil.
@@ -439,14 +439,14 @@ class GPBBridgeTests: XCTestCase {
msg.optionalGroup.a = 102
msg.repeatedStringArray.addObject("abc")
msg.repeatedStringArray.addObject("def")
- msg.mapInt32Int32.setValue(200, forKey:300)
- msg.mapInt32Int32.setValue(201, forKey:201)
+ msg.mapInt32Int32.setInt32(200, forKey:300)
+ msg.mapInt32Int32.setInt32(201, forKey:201)
msg.mapStringString.setObject("foo", forKey:"bar")
msg.mapStringString.setObject("abc", forKey:"xyz")
let data = msg.data()
- let msg2 = Message2(data: data!, error:nil)
+ let msg2 = try! Message2(data: data!)
XCTAssertTrue(msg2 !== msg) // New instance
XCTAssertEqual(msg.optionalInt32, Int32(100))
XCTAssertEqual(msg.optionalInt64, Int64(101))
diff --git a/objectivec/Tests/GPBTestUtilities.m b/objectivec/Tests/GPBTestUtilities.m
index 726761a7..ebccaac9 100644
--- a/objectivec/Tests/GPBTestUtilities.m
+++ b/objectivec/Tests/GPBTestUtilities.m
@@ -1089,19 +1089,19 @@ const uint32_t kGPBDefaultRepeatCount = 2;
- (void)setAllMapFields:(TestMap *)message numEntries:(uint32_t)count {
for (uint32_t i = 0; i < count; i++) {
- [message.mapInt32Int32 setValue:(i + 1) forKey:100 + i * 100];
- [message.mapInt64Int64 setValue:(i + 1) forKey:101 + i * 100];
- [message.mapUint32Uint32 setValue:(i + 1) forKey:102 + i * 100];
- [message.mapUint64Uint64 setValue:(i + 1) forKey:103 + i * 100];
- [message.mapSint32Sint32 setValue:(i + 1) forKey:104 + i * 100];
- [message.mapSint64Sint64 setValue:(i + 1) forKey:105 + i * 100];
- [message.mapFixed32Fixed32 setValue:(i + 1) forKey:106 + i * 100];
- [message.mapFixed64Fixed64 setValue:(i + 1) forKey:107 + i * 100];
- [message.mapSfixed32Sfixed32 setValue:(i + 1) forKey:108 + i * 100];
- [message.mapSfixed64Sfixed64 setValue:(i + 1) forKey:109 + i * 100];
- [message.mapInt32Float setValue:(i + 1) forKey:110 + i * 100];
- [message.mapInt32Double setValue:(i + 1) forKey:111 + i * 100];
- [message.mapBoolBool setValue:((i % 2) == 1) forKey:((i % 2) == 0)];
+ [message.mapInt32Int32 setInt32:(i + 1) forKey:100 + i * 100];
+ [message.mapInt64Int64 setInt64:(i + 1) forKey:101 + i * 100];
+ [message.mapUint32Uint32 setUInt32:(i + 1) forKey:102 + i * 100];
+ [message.mapUint64Uint64 setUInt64:(i + 1) forKey:103 + i * 100];
+ [message.mapSint32Sint32 setInt32:(i + 1) forKey:104 + i * 100];
+ [message.mapSint64Sint64 setInt64:(i + 1) forKey:105 + i * 100];
+ [message.mapFixed32Fixed32 setUInt32:(i + 1) forKey:106 + i * 100];
+ [message.mapFixed64Fixed64 setUInt64:(i + 1) forKey:107 + i * 100];
+ [message.mapSfixed32Sfixed32 setInt32:(i + 1) forKey:108 + i * 100];
+ [message.mapSfixed64Sfixed64 setInt64:(i + 1) forKey:109 + i * 100];
+ [message.mapInt32Float setFloat:(i + 1) forKey:110 + i * 100];
+ [message.mapInt32Double setDouble:(i + 1) forKey:111 + i * 100];
+ [message.mapBoolBool setBool:((i % 2) == 1) forKey:((i % 2) == 0)];
NSString *keyStr = [[NSString alloc] initWithFormat:@"%d", 112 + i * 100];
NSString *dataStr = [[NSString alloc] initWithFormat:@"%d", i + 1];
@@ -1114,8 +1114,8 @@ const uint32_t kGPBDefaultRepeatCount = 2;
[data release];
[message.mapInt32Enum
- setValue:(i % 2) ? MapEnum_MapEnumBar : MapEnum_MapEnumBaz
- forKey:114 + i * 100];
+ setEnum:(i % 2) ? MapEnum_MapEnumBar : MapEnum_MapEnumBaz
+ forKey:114 + i * 100];
ForeignMessage *subMsg = [[ForeignMessage alloc] init];
subMsg.c = i + 1;
diff --git a/objectivec/Tests/GPBUnittestProtos.m b/objectivec/Tests/GPBUnittestProtos.m
index 50c4dfa9..d19beee9 100644
--- a/objectivec/Tests/GPBUnittestProtos.m
+++ b/objectivec/Tests/GPBUnittestProtos.m
@@ -31,6 +31,11 @@
// Collects all the compiled protos into one file and compiles them to make sure
// the compiler is generating valid code.
+// The unittest_custom_options.proto extends the messages in descriptor.proto
+// so we build it in to test extending in general. The library doesn't provide
+// a descriptor as it doesn't use the classes/enums.
+#import "google/protobuf/Descriptor.pbobjc.m"
+
#import "google/protobuf/MapProto2Unittest.pbobjc.m"
#import "google/protobuf/MapUnittest.pbobjc.m"
#import "google/protobuf/Unittest.pbobjc.m"
diff --git a/objectivec/Tests/GPBUnknownFieldSetTest.m b/objectivec/Tests/GPBUnknownFieldSetTest.m
index 01217ca6..b2b5b21e 100644
--- a/objectivec/Tests/GPBUnknownFieldSetTest.m
+++ b/objectivec/Tests/GPBUnknownFieldSetTest.m
@@ -60,10 +60,6 @@
unknownFields_ = emptyMessage_.unknownFields;
}
-- (GPBUnknownField *)getField:(int32_t)number {
- return [unknownFields_ getField:number];
-}
-
// Constructs a protocol buffer which contains fields with all the same
// numbers as allFieldsData except that each field is some other wire
// type.
diff --git a/objectivec/Tests/GPBUtilitiesTests.m b/objectivec/Tests/GPBUtilitiesTests.m
index ba1fc270..dfaca660 100644
--- a/objectivec/Tests/GPBUtilitiesTests.m
+++ b/objectivec/Tests/GPBUtilitiesTests.m
@@ -170,4 +170,31 @@
// TODO(thomasvl): add test with extensions once those format with correct names.
+- (void)testSetRepeatedFields {
+ TestAllTypes *message = [TestAllTypes message];
+
+ NSDictionary *repeatedFieldValues = @{
+ @"repeatedStringArray" : [@[@"foo", @"bar"] mutableCopy],
+ @"repeatedBoolArray" : [GPBBoolArray arrayWithValue:YES],
+ @"repeatedInt32Array" : [GPBInt32Array arrayWithValue:14],
+ @"repeatedInt64Array" : [GPBInt64Array arrayWithValue:15],
+ @"repeatedUint32Array" : [GPBUInt32Array arrayWithValue:16],
+ @"repeatedUint64Array" : [GPBUInt64Array arrayWithValue:16],
+ @"repeatedFloatArray" : [GPBFloatArray arrayWithValue:16],
+ @"repeatedDoubleArray" : [GPBDoubleArray arrayWithValue:16],
+ @"repeatedNestedEnumArray" :
+ [GPBEnumArray arrayWithValidationFunction:TestAllTypes_NestedEnum_IsValidValue
+ rawValue:TestAllTypes_NestedEnum_Foo],
+ };
+ for (NSString *fieldName in repeatedFieldValues) {
+ GPBFieldDescriptor *field =
+ [message.descriptor fieldWithName:fieldName];
+ XCTAssertNotNil(field, @"No field with name: %@", fieldName);
+ id expectedValues = repeatedFieldValues[fieldName];
+ GPBSetMessageRepeatedField(message, field, expectedValues);
+ XCTAssertEqualObjects(expectedValues,
+ [message valueForKeyPath:fieldName]);
+ }
+}
+
@end
diff --git a/objectivec/Tests/GPBWireFormatTests.m b/objectivec/Tests/GPBWireFormatTests.m
index 3fab20b7..dbeab215 100644
--- a/objectivec/Tests/GPBWireFormatTests.m
+++ b/objectivec/Tests/GPBWireFormatTests.m
@@ -46,6 +46,7 @@
TestAllTypes* message = [self allSetRepeatedCount:kGPBDefaultRepeatCount];
NSData* rawBytes = message.data;
+ [self assertFieldsInOrder:rawBytes];
XCTAssertEqual(message.serializedSize, (size_t)rawBytes.length);
TestAllTypes* message2 = [TestAllTypes parseFromData:rawBytes error:NULL];
@@ -58,6 +59,7 @@
[self packedSetRepeatedCount:kGPBDefaultRepeatCount];
NSData* rawBytes = message.data;
+ [self assertFieldsInOrder:rawBytes];
XCTAssertEqual(message.serializedSize, (size_t)rawBytes.length);
TestPackedTypes* message2 =
@@ -74,6 +76,7 @@
TestAllExtensions* message =
[self allExtensionsSetRepeatedCount:kGPBDefaultRepeatCount];
NSData* rawBytes = message.data;
+ [self assertFieldsInOrder:rawBytes];
XCTAssertEqual(message.serializedSize, (size_t)rawBytes.length);
TestAllTypes* message2 = [TestAllTypes parseFromData:rawBytes error:NULL];
@@ -87,6 +90,7 @@
TestPackedExtensions* message =
[self packedExtensionsSetRepeatedCount:kGPBDefaultRepeatCount];
NSData* rawBytes = message.data;
+ [self assertFieldsInOrder:rawBytes];
TestPackedTypes* message2 =
[self packedSetRepeatedCount:kGPBDefaultRepeatCount];
@@ -102,6 +106,7 @@
TestAllTypes* message = [self allSetRepeatedCount:kGPBDefaultRepeatCount];
NSData* rawBytes = message.data;
+ [self assertFieldsInOrder:rawBytes];
GPBExtensionRegistry* registry = [self extensionRegistry];
@@ -113,7 +118,7 @@
}
-- (void) testExtensionsSerializedSize {
+- (void)testExtensionsSerializedSize {
size_t allSet = [self allSetRepeatedCount:kGPBDefaultRepeatCount].serializedSize;
size_t extensionSet = [self allExtensionsSetRepeatedCount:kGPBDefaultRepeatCount].serializedSize;
XCTAssertEqual(allSet, extensionSet);
@@ -124,6 +129,7 @@
TestPackedExtensions* message =
[self packedExtensionsSetRepeatedCount:kGPBDefaultRepeatCount];
NSData* rawBytes = message.data;
+ [self assertFieldsInOrder:rawBytes];
GPBExtensionRegistry* registry = [self extensionRegistry];
@@ -190,7 +196,6 @@ const int kUnknownTypeId = 1550055;
TestMessageSetExtension1* message = [TestMessageSetExtension1 message];
message.i = 123;
item.message = [message data];
- raw.itemArray = [NSMutableArray array];
[raw.itemArray addObject:item];
}
diff --git a/objectivec/Tests/unittest_objc.proto b/objectivec/Tests/unittest_objc.proto
index 3bb92761..914945eb 100644
--- a/objectivec/Tests/unittest_objc.proto
+++ b/objectivec/Tests/unittest_objc.proto
@@ -29,6 +29,7 @@
syntax = "proto2";
+import "google/protobuf/any.proto";
import "google/protobuf/unittest.proto";
package protobuf_unittest;
@@ -112,6 +113,18 @@ enum retain {
serializedSize = 6;
}
+message ObjCPropertyNaming {
+ // Test that the properties properly get things all caps.
+ optional string url = 1;
+ optional string thumbnail_url = 2;
+ optional string url_foo = 3;
+ optional string some_url_blah = 4;
+ optional string http = 5;
+ optional string https = 6;
+ // This one doesn't.
+ repeated string urls = 7;
+}
+
// EnumValueShortName: The short names shouldn't get suffixes/prefixes.
enum Foo {
SERIALIZED_SIZE = 1;
@@ -389,3 +402,57 @@ message EnumTestMsg {
repeated MyEnum mumble = 4;
}
+
+// Test case for https://github.com/google/protobuf/issues/1453
+// Message with no explicit defaults, but a non zero default for an enum.
+message MessageWithOneBasedEnum {
+ enum OneBasedEnum {
+ ONE = 1;
+ TWO = 2;
+ }
+ optional OneBasedEnum enum_field = 1;
+}
+
+// Message with all bools for testing things related to bool storage.
+message BoolOnlyMessage {
+ optional bool bool_field_1 = 1;
+ optional bool bool_field_2 = 2;
+ optional bool bool_field_3 = 3;
+ optional bool bool_field_4 = 4;
+ optional bool bool_field_5 = 5;
+ optional bool bool_field_6 = 6;
+ optional bool bool_field_7 = 7;
+ optional bool bool_field_8 = 8;
+ optional bool bool_field_9 = 9;
+ optional bool bool_field_10 = 10;
+ optional bool bool_field_11 = 11;
+ optional bool bool_field_12 = 12;
+ optional bool bool_field_13 = 13;
+ optional bool bool_field_14 = 14;
+ optional bool bool_field_15 = 15;
+ optional bool bool_field_16 = 16;
+ optional bool bool_field_17 = 17;
+ optional bool bool_field_18 = 18;
+ optional bool bool_field_19 = 19;
+ optional bool bool_field_20 = 20;
+ optional bool bool_field_21 = 21;
+ optional bool bool_field_22 = 22;
+ optional bool bool_field_23 = 23;
+ optional bool bool_field_24 = 24;
+ optional bool bool_field_25 = 25;
+ optional bool bool_field_26 = 26;
+ optional bool bool_field_27 = 27;
+ optional bool bool_field_28 = 28;
+ optional bool bool_field_29 = 29;
+ optional bool bool_field_30 = 30;
+ optional bool bool_field_31 = 31;
+ optional bool bool_field_32 = 32;
+}
+
+// Reference to a WKT to test (via generated code inspection), the handling
+// of #imports. Within the WKTs, references to each other are just path
+// based imports, but when reference from another proto file, they should be
+// conditional to support the framework import style.
+message WKTRefereceMessage {
+ optional google.protobuf.Any an_any = 1;
+}
diff --git a/objectivec/generate_descriptors_proto.sh b/objectivec/generate_well_known_types.sh
index 84ba0738..36c34603 100755
--- a/objectivec/generate_descriptors_proto.sh
+++ b/objectivec/generate_well_known_types.sh
@@ -1,9 +1,9 @@
#!/bin/bash
-# Run this script to regenerate descriptor.pbobjc.{h,m} after the protocol
-# compiler changes.
+# Run this script to regenerate *.pbobjc.{h,m} for the well known types after
+# the protocol compiler changes.
-# HINT: Flags passed to generate_descriptor_proto.sh will be passed directly
+# HINT: Flags passed to generate_well_known_types.sh will be passed directly
# to make when building protoc. This is particularly useful for passing
# -j4 to run 4 jobs simultaneously.
@@ -12,6 +12,13 @@ set -eu
readonly ScriptDir=$(dirname "$(echo $0 | sed -e "s,^\([^/]\),$(pwd)/\1,")")
readonly ProtoRootDir="${ScriptDir}/.."
+# Flag for continuous integration to check that everything is current.
+CHECK_ONLY=0
+if [[ $# -ge 1 && ( "$1" == "--check-only" ) ]] ; then
+ CHECK_ONLY=1
+ shift
+fi
+
pushd "${ProtoRootDir}" > /dev/null
if test ! -e src/google/protobuf/stubs/common.h; then
@@ -37,7 +44,6 @@ make $@ protoc
declare -a RUNTIME_PROTO_FILES=( \
google/protobuf/any.proto \
google/protobuf/api.proto \
- google/protobuf/descriptor.proto \
google/protobuf/duration.proto \
google/protobuf/empty.proto \
google/protobuf/field_mask.proto \
@@ -47,4 +53,24 @@ declare -a RUNTIME_PROTO_FILES=( \
google/protobuf/type.proto \
google/protobuf/wrappers.proto)
-./protoc --objc_out="${ProtoRootDir}/objectivec" ${RUNTIME_PROTO_FILES[@]}
+# Generate to a temp directory to see if they match.
+TMP_DIR=$(mktemp -d)
+trap "rm -rf ${TMP_DIR}" EXIT
+./protoc --objc_out="${TMP_DIR}" ${RUNTIME_PROTO_FILES[@]}
+set +e
+diff -r "${TMP_DIR}/google" "${ProtoRootDir}/objectivec/google" > /dev/null
+if [[ $? -eq 0 ]] ; then
+ echo "Generated source for WellKnownTypes is current."
+ exit 0
+fi
+set -e
+
+# If check only mode, error out.
+if [[ "${CHECK_ONLY}" == 1 ]] ; then
+ echo "ERROR: The WKTs need to be regenerated! Run $0"
+ exit 1
+fi
+
+# Copy them over.
+echo "Copying over updated WellKnownType sources."
+cp -r "${TMP_DIR}/google/." "${ProtoRootDir}/objectivec/google/"
diff --git a/objectivec/google/protobuf/Any.pbobjc.h b/objectivec/google/protobuf/Any.pbobjc.h
index d2261ee4..4253b604 100644
--- a/objectivec/google/protobuf/Any.pbobjc.h
+++ b/objectivec/google/protobuf/Any.pbobjc.h
@@ -1,27 +1,42 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: google/protobuf/any.proto
-#import "GPBProtocolBuffers.h"
+// This CPP symbol can be defined to use imports that match up to the framework
+// imports needed when using CocoaPods.
+#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS)
+ #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0
+#endif
+
+#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS
+ #import <Protobuf/GPBProtocolBuffers.h>
+#else
+ #import "GPBProtocolBuffers.h"
+#endif
-#if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30000
+#if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30001
#error This file was generated by a different version of protoc which is incompatible with your Protocol Buffer library sources.
#endif
// @@protoc_insertion_point(imports)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
CF_EXTERN_C_BEGIN
NS_ASSUME_NONNULL_BEGIN
#pragma mark - GPBAnyRoot
+/// Exposes the extension registry for this file.
+///
+/// The base class provides:
+/// @code
+/// + (GPBExtensionRegistry *)extensionRegistry;
+/// @endcode
+/// which is a @c GPBExtensionRegistry that includes all the extensions defined by
+/// this file and all files that it depends on.
@interface GPBAnyRoot : GPBRootObject
-
-// The base class provides:
-// + (GPBExtensionRegistry *)extensionRegistry;
-// which is an GPBExtensionRegistry that includes all the extensions defined by
-// this file and all files that it depends on.
-
@end
#pragma mark - GPBAny
@@ -31,60 +46,101 @@ typedef GPB_ENUM(GPBAny_FieldNumber) {
GPBAny_FieldNumber_Value = 2,
};
-// `Any` contains an arbitrary serialized message along with a URL
-// that describes the type of the serialized message.
-//
-// JSON
-// ====
-// The JSON representation of an `Any` value uses the regular
-// representation of the deserialized, embedded message, with an
-// additional field `@type` which contains the type URL. Example:
-//
-// package google.profile;
-// message Person {
-// string first_name = 1;
-// string last_name = 2;
-// }
-//
-// {
-// "@type": "type.googleapis.com/google.profile.Person",
-// "firstName": <string>,
-// "lastName": <string>
-// }
-//
-// If the embedded message type is well-known and has a custom JSON
-// representation, that representation will be embedded adding a field
-// `value` which holds the custom JSON in addition to the the `@type`
-// field. Example (for message [google.protobuf.Duration][google.protobuf.Duration]):
-//
-// {
-// "@type": "type.googleapis.com/google.protobuf.Duration",
-// "value": "1.212s"
-// }
+/// `Any` contains an arbitrary serialized protocol buffer message along with a
+/// URL that describes the type of the serialized message.
+///
+/// Protobuf library provides support to pack/unpack Any values in the form
+/// of utility functions or additional generated methods of the Any type.
+///
+/// Example 1: Pack and unpack a message in C++.
+///
+/// Foo foo = ...;
+/// Any any;
+/// any.PackFrom(foo);
+/// ...
+/// if (any.UnpackTo(&foo)) {
+/// ...
+/// }
+///
+/// Example 2: Pack and unpack a message in Java.
+///
+/// Foo foo = ...;
+/// Any any = Any.pack(foo);
+/// ...
+/// if (any.is(Foo.class)) {
+/// foo = any.unpack(Foo.class);
+/// }
+///
+/// Example 3: Pack and unpack a message in Python.
+///
+/// foo = Foo(...)
+/// any = Any()
+/// any.Pack(foo)
+/// ...
+/// if any.Is(Foo.DESCRIPTOR):
+/// any.Unpack(foo)
+/// ...
+///
+/// The pack methods provided by protobuf library will by default use
+/// 'type.googleapis.com/full.type.name' as the type URL and the unpack
+/// methods only use the fully qualified type name after the last '/'
+/// in the type URL, for example "foo.bar.com/x/y.z" will yield type
+/// name "y.z".
+///
+///
+/// JSON
+/// ====
+/// The JSON representation of an `Any` value uses the regular
+/// representation of the deserialized, embedded message, with an
+/// additional field `\@type` which contains the type URL. Example:
+///
+/// package google.profile;
+/// message Person {
+/// string first_name = 1;
+/// string last_name = 2;
+/// }
+///
+/// {
+/// "\@type": "type.googleapis.com/google.profile.Person",
+/// "firstName": <string>,
+/// "lastName": <string>
+/// }
+///
+/// If the embedded message type is well-known and has a custom JSON
+/// representation, that representation will be embedded adding a field
+/// `value` which holds the custom JSON in addition to the `\@type`
+/// field. Example (for message [google.protobuf.Duration][]):
+///
+/// {
+/// "\@type": "type.googleapis.com/google.protobuf.Duration",
+/// "value": "1.212s"
+/// }
@interface GPBAny : GPBMessage
-// A URL/resource name whose content describes the type of the
-// serialized message.
-//
-// For URLs which use the schema `http`, `https`, or no schema, the
-// following restrictions and interpretations apply:
-//
-// * If no schema is provided, `https` is assumed.
-// * The last segment of the URL's path must represent the fully
-// qualified name of the type (as in `path/google.protobuf.Duration`).
-// * An HTTP GET on the URL must yield a [google.protobuf.Type][google.protobuf.Type]
-// value in binary format, or produce an error.
-// * Applications are allowed to cache lookup results based on the
-// URL, or have them precompiled into a binary to avoid any
-// lookup. Therefore, binary compatibility needs to be preserved
-// on changes to types. (Use versioned type names to manage
-// breaking changes.)
-//
-// Schemas other than `http`, `https` (or the empty schema) might be
-// used with implementation specific semantics.
+/// A URL/resource name whose content describes the type of the
+/// serialized protocol buffer message.
+///
+/// For URLs which use the scheme `http`, `https`, or no scheme, the
+/// following restrictions and interpretations apply:
+///
+/// * If no scheme is provided, `https` is assumed.
+/// * The last segment of the URL's path must represent the fully
+/// qualified name of the type (as in `path/google.protobuf.Duration`).
+/// The name should be in a canonical form (e.g., leading "." is
+/// not accepted).
+/// * An HTTP GET on the URL must yield a [google.protobuf.Type][]
+/// value in binary format, or produce an error.
+/// * Applications are allowed to cache lookup results based on the
+/// URL, or have them precompiled into a binary to avoid any
+/// lookup. Therefore, binary compatibility needs to be preserved
+/// on changes to types. (Use versioned type names to manage
+/// breaking changes.)
+///
+/// Schemes other than `http`, `https` (or the empty scheme) might be
+/// used with implementation specific semantics.
@property(nonatomic, readwrite, copy, null_resettable) NSString *typeURL;
-// Must be valid serialized data of the above specified type.
+/// Must be a valid serialized protocol buffer of the above specified type.
@property(nonatomic, readwrite, copy, null_resettable) NSData *value;
@end
@@ -93,4 +149,6 @@ NS_ASSUME_NONNULL_END
CF_EXTERN_C_END
+#pragma clang diagnostic pop
+
// @@protoc_insertion_point(global_scope)
diff --git a/objectivec/google/protobuf/Any.pbobjc.m b/objectivec/google/protobuf/Any.pbobjc.m
index b41102a4..25e5b4c4 100644
--- a/objectivec/google/protobuf/Any.pbobjc.m
+++ b/objectivec/google/protobuf/Any.pbobjc.m
@@ -1,10 +1,28 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: google/protobuf/any.proto
-#import "GPBProtocolBuffers_RuntimeSupport.h"
-#import "google/protobuf/Any.pbobjc.h"
+// This CPP symbol can be defined to use imports that match up to the framework
+// imports needed when using CocoaPods.
+#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS)
+ #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0
+#endif
+
+#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS
+ #import <Protobuf/GPBProtocolBuffers_RuntimeSupport.h>
+#else
+ #import "GPBProtocolBuffers_RuntimeSupport.h"
+#endif
+
+#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS
+ #import <Protobuf/Any.pbobjc.h>
+#else
+ #import "google/protobuf/Any.pbobjc.h"
+#endif
// @@protoc_insertion_point(imports)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
#pragma mark - GPBAnyRoot
@implementation GPBAnyRoot
@@ -46,47 +64,36 @@ typedef struct GPBAny__storage_ {
static GPBMessageFieldDescription fields[] = {
{
.name = "typeURL",
+ .dataTypeSpecific.className = NULL,
.number = GPBAny_FieldNumber_TypeURL,
.hasIndex = 0,
+ .offset = (uint32_t)offsetof(GPBAny__storage_, typeURL),
.flags = GPBFieldOptional | GPBFieldTextFormatNameCustom,
.dataType = GPBDataTypeString,
- .offset = offsetof(GPBAny__storage_, typeURL),
- .defaultValue.valueString = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
},
{
.name = "value",
+ .dataTypeSpecific.className = NULL,
.number = GPBAny_FieldNumber_Value,
.hasIndex = 1,
+ .offset = (uint32_t)offsetof(GPBAny__storage_, value),
.flags = GPBFieldOptional,
.dataType = GPBDataTypeBytes,
- .offset = offsetof(GPBAny__storage_, value),
- .defaultValue.valueData = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
},
};
-#if GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS
- const char *extraTextFormatInfo = NULL;
-#else
- static const char *extraTextFormatInfo = "\001\001\004\241!!\000";
-#endif // GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS
GPBDescriptor *localDescriptor =
[GPBDescriptor allocDescriptorForClass:[GPBAny class]
rootClass:[GPBAnyRoot class]
file:GPBAnyRoot_FileDescriptor()
fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:NULL
- oneofCount:0
- enums:NULL
- enumCount:0
- ranges:NULL
- rangeCount:0
+ fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBAny__storage_)
- wireFormat:NO
- extraTextFormatInfo:extraTextFormatInfo];
+ flags:0];
+#if !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS
+ static const char *extraTextFormatInfo =
+ "\001\001\004\241!!\000";
+ [localDescriptor setupExtraTextInfo:extraTextFormatInfo];
+#endif // !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS
NSAssert(descriptor == nil, @"Startup recursed!");
descriptor = localDescriptor;
}
@@ -96,4 +103,6 @@ typedef struct GPBAny__storage_ {
@end
+#pragma clang diagnostic pop
+
// @@protoc_insertion_point(global_scope)
diff --git a/objectivec/google/protobuf/Api.pbobjc.h b/objectivec/google/protobuf/Api.pbobjc.h
index c9dacfee..04341f47 100644
--- a/objectivec/google/protobuf/Api.pbobjc.h
+++ b/objectivec/google/protobuf/Api.pbobjc.h
@@ -1,16 +1,32 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: google/protobuf/api.proto
-#import "GPBProtocolBuffers.h"
+// This CPP symbol can be defined to use imports that match up to the framework
+// imports needed when using CocoaPods.
+#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS)
+ #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0
+#endif
+
+#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS
+ #import <Protobuf/GPBProtocolBuffers.h>
+#else
+ #import "GPBProtocolBuffers.h"
+#endif
-#if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30000
+#if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30001
#error This file was generated by a different version of protoc which is incompatible with your Protocol Buffer library sources.
#endif
// @@protoc_insertion_point(imports)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
CF_EXTERN_C_BEGIN
+@class GPBMethod;
+@class GPBMixin;
+@class GPBOption;
@class GPBSourceContext;
GPB_ENUM_FWD_DECLARE(GPBSyntax);
@@ -18,13 +34,15 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - GPBApiRoot
+/// Exposes the extension registry for this file.
+///
+/// The base class provides:
+/// @code
+/// + (GPBExtensionRegistry *)extensionRegistry;
+/// @endcode
+/// which is a @c GPBExtensionRegistry that includes all the extensions defined by
+/// this file and all files that it depends on.
@interface GPBApiRoot : GPBRootObject
-
-// The base class provides:
-// + (GPBExtensionRegistry *)extensionRegistry;
-// which is an GPBExtensionRegistry that includes all the extensions defined by
-// this file and all files that it depends on.
-
@end
#pragma mark - GPBApi
@@ -39,61 +57,67 @@ typedef GPB_ENUM(GPBApi_FieldNumber) {
GPBApi_FieldNumber_Syntax = 7,
};
-// Api is a light-weight descriptor for a protocol buffer service.
+/// Api is a light-weight descriptor for a protocol buffer service.
@interface GPBApi : GPBMessage
-// The fully qualified name of this api, including package name
-// followed by the api's simple name.
+/// The fully qualified name of this api, including package name
+/// followed by the api's simple name.
@property(nonatomic, readwrite, copy, null_resettable) NSString *name;
-// The methods of this api, in unspecified order.
-// |methodsArray| contains |GPBMethod|
-@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *methodsArray;
+/// The methods of this api, in unspecified order.
+@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBMethod*> *methodsArray;
+/// The number of items in @c methodsArray without causing the array to be created.
@property(nonatomic, readonly) NSUInteger methodsArray_Count;
-// Any metadata attached to the API.
-// |optionsArray| contains |GPBOption|
-@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *optionsArray;
+/// Any metadata attached to the API.
+@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBOption*> *optionsArray;
+/// The number of items in @c optionsArray without causing the array to be created.
@property(nonatomic, readonly) NSUInteger optionsArray_Count;
-// A version string for this api. If specified, must have the form
-// `major-version.minor-version`, as in `1.10`. If the minor version
-// is omitted, it defaults to zero. If the entire version field is
-// empty, the major version is derived from the package name, as
-// outlined below. If the field is not empty, the version in the
-// package name will be verified to be consistent with what is
-// provided here.
-//
-// The versioning schema uses [semantic
-// versioning](http://semver.org) where the major version number
-// indicates a breaking change and the minor version an additive,
-// non-breaking change. Both version numbers are signals to users
-// what to expect from different versions, and should be carefully
-// chosen based on the product plan.
-//
-// The major version is also reflected in the package name of the
-// API, which must end in `v<major-version>`, as in
-// `google.feature.v1`. For major versions 0 and 1, the suffix can
-// be omitted. Zero major versions must only be used for
-// experimental, none-GA apis.
+/// A version string for this api. If specified, must have the form
+/// `major-version.minor-version`, as in `1.10`. If the minor version
+/// is omitted, it defaults to zero. If the entire version field is
+/// empty, the major version is derived from the package name, as
+/// outlined below. If the field is not empty, the version in the
+/// package name will be verified to be consistent with what is
+/// provided here.
+///
+/// The versioning schema uses [semantic
+/// versioning](http://semver.org) where the major version number
+/// indicates a breaking change and the minor version an additive,
+/// non-breaking change. Both version numbers are signals to users
+/// what to expect from different versions, and should be carefully
+/// chosen based on the product plan.
+///
+/// The major version is also reflected in the package name of the
+/// API, which must end in `v<major-version>`, as in
+/// `google.feature.v1`. For major versions 0 and 1, the suffix can
+/// be omitted. Zero major versions must only be used for
+/// experimental, none-GA apis.
@property(nonatomic, readwrite, copy, null_resettable) NSString *version;
-// Source context for the protocol buffer service represented by this
-// message.
-@property(nonatomic, readwrite) BOOL hasSourceContext;
+/// Source context for the protocol buffer service represented by this
+/// message.
@property(nonatomic, readwrite, strong, null_resettable) GPBSourceContext *sourceContext;
+/// Test to see if @c sourceContext has been set.
+@property(nonatomic, readwrite) BOOL hasSourceContext;
-// Included APIs. See [Mixin][].
-// |mixinsArray| contains |GPBMixin|
-@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *mixinsArray;
+/// Included APIs. See [Mixin][].
+@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBMixin*> *mixinsArray;
+/// The number of items in @c mixinsArray without causing the array to be created.
@property(nonatomic, readonly) NSUInteger mixinsArray_Count;
-// The source syntax of the service.
+/// The source syntax of the service.
@property(nonatomic, readwrite) enum GPBSyntax syntax;
@end
+/// Fetches the raw value of a @c GPBApi's @c syntax property, even
+/// if the value was not defined by the enum at the time the code was generated.
int32_t GPBApi_Syntax_RawValue(GPBApi *message);
+/// Sets the raw value of an @c GPBApi's @c syntax property, allowing
+/// it to be set to a value that was not defined by the enum at the time the code
+/// was generated.
void SetGPBApi_Syntax_RawValue(GPBApi *message, int32_t value);
#pragma mark - GPBMethod
@@ -108,35 +132,40 @@ typedef GPB_ENUM(GPBMethod_FieldNumber) {
GPBMethod_FieldNumber_Syntax = 7,
};
-// Method represents a method of an api.
+/// Method represents a method of an api.
@interface GPBMethod : GPBMessage
-// The simple name of this method.
+/// The simple name of this method.
@property(nonatomic, readwrite, copy, null_resettable) NSString *name;
-// A URL of the input message type.
+/// A URL of the input message type.
@property(nonatomic, readwrite, copy, null_resettable) NSString *requestTypeURL;
-// If true, the request is streamed.
+/// If true, the request is streamed.
@property(nonatomic, readwrite) BOOL requestStreaming;
-// The URL of the output message type.
+/// The URL of the output message type.
@property(nonatomic, readwrite, copy, null_resettable) NSString *responseTypeURL;
-// If true, the response is streamed.
+/// If true, the response is streamed.
@property(nonatomic, readwrite) BOOL responseStreaming;
-// Any metadata attached to the method.
-// |optionsArray| contains |GPBOption|
-@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *optionsArray;
+/// Any metadata attached to the method.
+@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBOption*> *optionsArray;
+/// The number of items in @c optionsArray without causing the array to be created.
@property(nonatomic, readonly) NSUInteger optionsArray_Count;
-// The source syntax of this method.
+/// The source syntax of this method.
@property(nonatomic, readwrite) enum GPBSyntax syntax;
@end
+/// Fetches the raw value of a @c GPBMethod's @c syntax property, even
+/// if the value was not defined by the enum at the time the code was generated.
int32_t GPBMethod_Syntax_RawValue(GPBMethod *message);
+/// Sets the raw value of an @c GPBMethod's @c syntax property, allowing
+/// it to be set to a value that was not defined by the enum at the time the code
+/// was generated.
void SetGPBMethod_Syntax_RawValue(GPBMethod *message, int32_t value);
#pragma mark - GPBMixin
@@ -146,91 +175,90 @@ typedef GPB_ENUM(GPBMixin_FieldNumber) {
GPBMixin_FieldNumber_Root = 2,
};
-// Declares an API to be included in this API. The including API must
-// redeclare all the methods from the included API, but documentation
-// and options are inherited as follows:
-//
-// - If after comment and whitespace stripping, the documentation
-// string of the redeclared method is empty, it will be inherited
-// from the original method.
-//
-// - Each annotation belonging to the service config (http,
-// visibility) which is not set in the redeclared method will be
-// inherited.
-//
-// - If an http annotation is inherited, the path pattern will be
-// modified as follows. Any version prefix will be replaced by the
-// version of the including API plus the [root][] path if specified.
-//
-// Example of a simple mixin:
-//
-// package google.acl.v1;
-// service AccessControl {
-// // Get the underlying ACL object.
-// rpc GetAcl(GetAclRequest) returns (Acl) {
-// option (google.api.http).get = "/v1/{resource=**}:getAcl";
-// }
-// }
-//
-// package google.storage.v2;
-// service Storage {
-// // (-- see AccessControl.GetAcl --)
-// rpc GetAcl(GetAclRequest) returns (Acl);
-//
-// // Get a data record.
-// rpc GetData(GetDataRequest) returns (Data) {
-// option (google.api.http).get = "/v2/{resource=**}";
-// }
-// }
-//
-// Example of a mixin configuration:
-//
-// apis:
-// - name: google.storage.v2.Storage
-// mixins:
-// - name: google.acl.v1.AccessControl
-//
-// 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
-// documentation and annotations as follows:
-//
-// service Storage {
-// // Get the underlying ACL object.
-// rpc GetAcl(GetAclRequest) returns (Acl) {
-// option (google.api.http).get = "/v2/{resource=**}:getAcl";
-// }
-// ...
-// }
-//
-// Note how the version in the path pattern changed from `v1` to `v2`.
-//
-// If the `root` field in the mixin is specified, it should be a
-// relative path under which inherited HTTP paths are placed. Example:
-//
-// apis:
-// - name: google.storage.v2.Storage
-// mixins:
-// - name: google.acl.v1.AccessControl
-// root: acls
-//
-// This implies the following inherited HTTP annotation:
-//
-// service Storage {
-// // Get the underlying ACL object.
-// rpc GetAcl(GetAclRequest) returns (Acl) {
-// option (google.api.http).get = "/v2/acls/{resource=**}:getAcl";
-// }
-// ...
-// }
+/// Declares an API to be included in this API. The including API must
+/// redeclare all the methods from the included API, but documentation
+/// and options are inherited as follows:
+///
+/// - If after comment and whitespace stripping, the documentation
+/// string of the redeclared method is empty, it will be inherited
+/// from the original method.
+///
+/// - Each annotation belonging to the service config (http,
+/// visibility) which is not set in the redeclared method will be
+/// inherited.
+///
+/// - If an http annotation is inherited, the path pattern will be
+/// modified as follows. Any version prefix will be replaced by the
+/// version of the including API plus the [root][] path if specified.
+///
+/// Example of a simple mixin:
+///
+/// package google.acl.v1;
+/// service AccessControl {
+/// // Get the underlying ACL object.
+/// rpc GetAcl(GetAclRequest) returns (Acl) {
+/// option (google.api.http).get = "/v1/{resource=**}:getAcl";
+/// }
+/// }
+///
+/// package google.storage.v2;
+/// service Storage {
+/// rpc GetAcl(GetAclRequest) returns (Acl);
+///
+/// // Get a data record.
+/// rpc GetData(GetDataRequest) returns (Data) {
+/// option (google.api.http).get = "/v2/{resource=**}";
+/// }
+/// }
+///
+/// Example of a mixin configuration:
+///
+/// apis:
+/// - name: google.storage.v2.Storage
+/// mixins:
+/// - name: google.acl.v1.AccessControl
+///
+/// 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
+/// documentation and annotations as follows:
+///
+/// service Storage {
+/// // Get the underlying ACL object.
+/// rpc GetAcl(GetAclRequest) returns (Acl) {
+/// option (google.api.http).get = "/v2/{resource=**}:getAcl";
+/// }
+/// ...
+/// }
+///
+/// Note how the version in the path pattern changed from `v1` to `v2`.
+///
+/// If the `root` field in the mixin is specified, it should be a
+/// relative path under which inherited HTTP paths are placed. Example:
+///
+/// apis:
+/// - name: google.storage.v2.Storage
+/// mixins:
+/// - name: google.acl.v1.AccessControl
+/// root: acls
+///
+/// This implies the following inherited HTTP annotation:
+///
+/// service Storage {
+/// // Get the underlying ACL object.
+/// rpc GetAcl(GetAclRequest) returns (Acl) {
+/// option (google.api.http).get = "/v2/acls/{resource=**}:getAcl";
+/// }
+/// ...
+/// }
@interface GPBMixin : GPBMessage
-// The fully qualified name of the API which is included.
+/// The fully qualified name of the API which is included.
@property(nonatomic, readwrite, copy, null_resettable) NSString *name;
-// If non-empty specifies a path under which inherited HTTP paths
-// are rooted.
+/// If non-empty specifies a path under which inherited HTTP paths
+/// are rooted.
@property(nonatomic, readwrite, copy, null_resettable) NSString *root;
@end
@@ -239,4 +267,6 @@ NS_ASSUME_NONNULL_END
CF_EXTERN_C_END
+#pragma clang diagnostic pop
+
// @@protoc_insertion_point(global_scope)
diff --git a/objectivec/google/protobuf/Api.pbobjc.m b/objectivec/google/protobuf/Api.pbobjc.m
index d964ff41..cd37edaa 100644
--- a/objectivec/google/protobuf/Api.pbobjc.m
+++ b/objectivec/google/protobuf/Api.pbobjc.m
@@ -1,12 +1,32 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: google/protobuf/api.proto
-#import "GPBProtocolBuffers_RuntimeSupport.h"
-#import "google/protobuf/Api.pbobjc.h"
-#import "google/protobuf/SourceContext.pbobjc.h"
-#import "google/protobuf/Type.pbobjc.h"
+// This CPP symbol can be defined to use imports that match up to the framework
+// imports needed when using CocoaPods.
+#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS)
+ #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0
+#endif
+
+#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS
+ #import <Protobuf/GPBProtocolBuffers_RuntimeSupport.h>
+#else
+ #import "GPBProtocolBuffers_RuntimeSupport.h"
+#endif
+
+#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS
+ #import <Protobuf/Api.pbobjc.h>
+ #import <Protobuf/SourceContext.pbobjc.h>
+ #import <Protobuf/Type.pbobjc.h>
+#else
+ #import "google/protobuf/Api.pbobjc.h"
+ #import "google/protobuf/SourceContext.pbobjc.h"
+ #import "google/protobuf/Type.pbobjc.h"
+#endif
// @@protoc_insertion_point(imports)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
#pragma mark - GPBApiRoot
@implementation GPBApiRoot
@@ -71,80 +91,66 @@ typedef struct GPBApi__storage_ {
static GPBMessageFieldDescription fields[] = {
{
.name = "name",
+ .dataTypeSpecific.className = NULL,
.number = GPBApi_FieldNumber_Name,
.hasIndex = 0,
+ .offset = (uint32_t)offsetof(GPBApi__storage_, name),
.flags = GPBFieldOptional,
.dataType = GPBDataTypeString,
- .offset = offsetof(GPBApi__storage_, name),
- .defaultValue.valueString = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
},
{
.name = "methodsArray",
+ .dataTypeSpecific.className = GPBStringifySymbol(GPBMethod),
.number = GPBApi_FieldNumber_MethodsArray,
.hasIndex = GPBNoHasBit,
+ .offset = (uint32_t)offsetof(GPBApi__storage_, methodsArray),
.flags = GPBFieldRepeated,
.dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBApi__storage_, methodsArray),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBMethod),
- .fieldOptions = NULL,
},
{
.name = "optionsArray",
+ .dataTypeSpecific.className = GPBStringifySymbol(GPBOption),
.number = GPBApi_FieldNumber_OptionsArray,
.hasIndex = GPBNoHasBit,
+ .offset = (uint32_t)offsetof(GPBApi__storage_, optionsArray),
.flags = GPBFieldRepeated,
.dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBApi__storage_, optionsArray),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBOption),
- .fieldOptions = NULL,
},
{
.name = "version",
+ .dataTypeSpecific.className = NULL,
.number = GPBApi_FieldNumber_Version,
- .hasIndex = 3,
+ .hasIndex = 1,
+ .offset = (uint32_t)offsetof(GPBApi__storage_, version),
.flags = GPBFieldOptional,
.dataType = GPBDataTypeString,
- .offset = offsetof(GPBApi__storage_, version),
- .defaultValue.valueString = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
},
{
.name = "sourceContext",
+ .dataTypeSpecific.className = GPBStringifySymbol(GPBSourceContext),
.number = GPBApi_FieldNumber_SourceContext,
- .hasIndex = 4,
+ .hasIndex = 2,
+ .offset = (uint32_t)offsetof(GPBApi__storage_, sourceContext),
.flags = GPBFieldOptional,
.dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBApi__storage_, sourceContext),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBSourceContext),
- .fieldOptions = NULL,
},
{
.name = "mixinsArray",
+ .dataTypeSpecific.className = GPBStringifySymbol(GPBMixin),
.number = GPBApi_FieldNumber_MixinsArray,
.hasIndex = GPBNoHasBit,
+ .offset = (uint32_t)offsetof(GPBApi__storage_, mixinsArray),
.flags = GPBFieldRepeated,
.dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBApi__storage_, mixinsArray),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBMixin),
- .fieldOptions = NULL,
},
{
.name = "syntax",
+ .dataTypeSpecific.enumDescFunc = GPBSyntax_EnumDescriptor,
.number = GPBApi_FieldNumber_Syntax,
- .hasIndex = 6,
+ .hasIndex = 3,
+ .offset = (uint32_t)offsetof(GPBApi__storage_, syntax),
.flags = GPBFieldOptional | GPBFieldHasEnumDescriptor,
.dataType = GPBDataTypeEnum,
- .offset = offsetof(GPBApi__storage_, syntax),
- .defaultValue.valueEnum = GPBSyntax_SyntaxProto2,
- .dataTypeSpecific.enumDescFunc = GPBSyntax_EnumDescriptor,
- .fieldOptions = NULL,
},
};
GPBDescriptor *localDescriptor =
@@ -152,15 +158,9 @@ typedef struct GPBApi__storage_ {
rootClass:[GPBApiRoot class]
file:GPBApiRoot_FileDescriptor()
fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:NULL
- oneofCount:0
- enums:NULL
- enumCount:0
- ranges:NULL
- rangeCount:0
+ fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBApi__storage_)
- wireFormat:NO];
+ flags:0];
NSAssert(descriptor == nil, @"Startup recursed!");
descriptor = localDescriptor;
}
@@ -195,8 +195,6 @@ void SetGPBApi_Syntax_RawValue(GPBApi *message, int32_t value) {
typedef struct GPBMethod__storage_ {
uint32_t _has_storage_[1];
- BOOL requestStreaming;
- BOOL responseStreaming;
GPBSyntax syntax;
NSString *name;
NSString *requestTypeURL;
@@ -212,102 +210,81 @@ typedef struct GPBMethod__storage_ {
static GPBMessageFieldDescription fields[] = {
{
.name = "name",
+ .dataTypeSpecific.className = NULL,
.number = GPBMethod_FieldNumber_Name,
.hasIndex = 0,
+ .offset = (uint32_t)offsetof(GPBMethod__storage_, name),
.flags = GPBFieldOptional,
.dataType = GPBDataTypeString,
- .offset = offsetof(GPBMethod__storage_, name),
- .defaultValue.valueString = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
},
{
.name = "requestTypeURL",
+ .dataTypeSpecific.className = NULL,
.number = GPBMethod_FieldNumber_RequestTypeURL,
.hasIndex = 1,
+ .offset = (uint32_t)offsetof(GPBMethod__storage_, requestTypeURL),
.flags = GPBFieldOptional | GPBFieldTextFormatNameCustom,
.dataType = GPBDataTypeString,
- .offset = offsetof(GPBMethod__storage_, requestTypeURL),
- .defaultValue.valueString = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
},
{
.name = "requestStreaming",
+ .dataTypeSpecific.className = NULL,
.number = GPBMethod_FieldNumber_RequestStreaming,
.hasIndex = 2,
+ .offset = 3, // Stored in _has_storage_ to save space.
.flags = GPBFieldOptional,
.dataType = GPBDataTypeBool,
- .offset = offsetof(GPBMethod__storage_, requestStreaming),
- .defaultValue.valueBool = NO,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
},
{
.name = "responseTypeURL",
+ .dataTypeSpecific.className = NULL,
.number = GPBMethod_FieldNumber_ResponseTypeURL,
- .hasIndex = 3,
+ .hasIndex = 4,
+ .offset = (uint32_t)offsetof(GPBMethod__storage_, responseTypeURL),
.flags = GPBFieldOptional | GPBFieldTextFormatNameCustom,
.dataType = GPBDataTypeString,
- .offset = offsetof(GPBMethod__storage_, responseTypeURL),
- .defaultValue.valueString = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
},
{
.name = "responseStreaming",
+ .dataTypeSpecific.className = NULL,
.number = GPBMethod_FieldNumber_ResponseStreaming,
- .hasIndex = 4,
+ .hasIndex = 5,
+ .offset = 6, // Stored in _has_storage_ to save space.
.flags = GPBFieldOptional,
.dataType = GPBDataTypeBool,
- .offset = offsetof(GPBMethod__storage_, responseStreaming),
- .defaultValue.valueBool = NO,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
},
{
.name = "optionsArray",
+ .dataTypeSpecific.className = GPBStringifySymbol(GPBOption),
.number = GPBMethod_FieldNumber_OptionsArray,
.hasIndex = GPBNoHasBit,
+ .offset = (uint32_t)offsetof(GPBMethod__storage_, optionsArray),
.flags = GPBFieldRepeated,
.dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBMethod__storage_, optionsArray),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBOption),
- .fieldOptions = NULL,
},
{
.name = "syntax",
+ .dataTypeSpecific.enumDescFunc = GPBSyntax_EnumDescriptor,
.number = GPBMethod_FieldNumber_Syntax,
- .hasIndex = 6,
+ .hasIndex = 7,
+ .offset = (uint32_t)offsetof(GPBMethod__storage_, syntax),
.flags = GPBFieldOptional | GPBFieldHasEnumDescriptor,
.dataType = GPBDataTypeEnum,
- .offset = offsetof(GPBMethod__storage_, syntax),
- .defaultValue.valueEnum = GPBSyntax_SyntaxProto2,
- .dataTypeSpecific.enumDescFunc = GPBSyntax_EnumDescriptor,
- .fieldOptions = NULL,
},
};
-#if GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS
- const char *extraTextFormatInfo = NULL;
-#else
- static const char *extraTextFormatInfo = "\002\002\007\244\241!!\000\004\010\244\241!!\000";
-#endif // GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS
GPBDescriptor *localDescriptor =
[GPBDescriptor allocDescriptorForClass:[GPBMethod class]
rootClass:[GPBApiRoot class]
file:GPBApiRoot_FileDescriptor()
fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:NULL
- oneofCount:0
- enums:NULL
- enumCount:0
- ranges:NULL
- rangeCount:0
+ fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBMethod__storage_)
- wireFormat:NO
- extraTextFormatInfo:extraTextFormatInfo];
+ flags:0];
+#if !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS
+ static const char *extraTextFormatInfo =
+ "\002\002\007\244\241!!\000\004\010\244\241!!\000";
+ [localDescriptor setupExtraTextInfo:extraTextFormatInfo];
+#endif // !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS
NSAssert(descriptor == nil, @"Startup recursed!");
descriptor = localDescriptor;
}
@@ -349,25 +326,21 @@ typedef struct GPBMixin__storage_ {
static GPBMessageFieldDescription fields[] = {
{
.name = "name",
+ .dataTypeSpecific.className = NULL,
.number = GPBMixin_FieldNumber_Name,
.hasIndex = 0,
+ .offset = (uint32_t)offsetof(GPBMixin__storage_, name),
.flags = GPBFieldOptional,
.dataType = GPBDataTypeString,
- .offset = offsetof(GPBMixin__storage_, name),
- .defaultValue.valueString = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
},
{
.name = "root",
+ .dataTypeSpecific.className = NULL,
.number = GPBMixin_FieldNumber_Root,
.hasIndex = 1,
+ .offset = (uint32_t)offsetof(GPBMixin__storage_, root),
.flags = GPBFieldOptional,
.dataType = GPBDataTypeString,
- .offset = offsetof(GPBMixin__storage_, root),
- .defaultValue.valueString = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
},
};
GPBDescriptor *localDescriptor =
@@ -375,15 +348,9 @@ typedef struct GPBMixin__storage_ {
rootClass:[GPBApiRoot class]
file:GPBApiRoot_FileDescriptor()
fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:NULL
- oneofCount:0
- enums:NULL
- enumCount:0
- ranges:NULL
- rangeCount:0
+ fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBMixin__storage_)
- wireFormat:NO];
+ flags:0];
NSAssert(descriptor == nil, @"Startup recursed!");
descriptor = localDescriptor;
}
@@ -393,4 +360,6 @@ typedef struct GPBMixin__storage_ {
@end
+#pragma clang diagnostic pop
+
// @@protoc_insertion_point(global_scope)
diff --git a/objectivec/google/protobuf/Descriptor.pbobjc.h b/objectivec/google/protobuf/Descriptor.pbobjc.h
deleted file mode 100644
index f04616c3..00000000
--- a/objectivec/google/protobuf/Descriptor.pbobjc.h
+++ /dev/null
@@ -1,1160 +0,0 @@
-// Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: google/protobuf/descriptor.proto
-
-#import "GPBProtocolBuffers.h"
-
-#if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30000
-#error This file was generated by a different version of protoc which is incompatible with your Protocol Buffer library sources.
-#endif
-
-// @@protoc_insertion_point(imports)
-
-CF_EXTERN_C_BEGIN
-
-@class GPBEnumOptions;
-@class GPBEnumValueOptions;
-@class GPBFieldOptions;
-@class GPBFileOptions;
-@class GPBMessageOptions;
-@class GPBMethodOptions;
-@class GPBServiceOptions;
-@class GPBSourceCodeInfo;
-
-NS_ASSUME_NONNULL_BEGIN
-
-#pragma mark - Enum GPBFieldDescriptorProto_Type
-
-typedef GPB_ENUM(GPBFieldDescriptorProto_Type) {
- // 0 is reserved for errors.
- // Order is weird for historical reasons.
- GPBFieldDescriptorProto_Type_TypeDouble = 1,
- GPBFieldDescriptorProto_Type_TypeFloat = 2,
-
- // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT64 if
- // negative values are likely.
- GPBFieldDescriptorProto_Type_TypeInt64 = 3,
- GPBFieldDescriptorProto_Type_TypeUint64 = 4,
-
- // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT32 if
- // negative values are likely.
- GPBFieldDescriptorProto_Type_TypeInt32 = 5,
- GPBFieldDescriptorProto_Type_TypeFixed64 = 6,
- GPBFieldDescriptorProto_Type_TypeFixed32 = 7,
- GPBFieldDescriptorProto_Type_TypeBool = 8,
- GPBFieldDescriptorProto_Type_TypeString = 9,
-
- // Tag-delimited aggregate.
- GPBFieldDescriptorProto_Type_TypeGroup = 10,
-
- // Length-delimited aggregate.
- GPBFieldDescriptorProto_Type_TypeMessage = 11,
-
- // New in version 2.
- GPBFieldDescriptorProto_Type_TypeBytes = 12,
- GPBFieldDescriptorProto_Type_TypeUint32 = 13,
- GPBFieldDescriptorProto_Type_TypeEnum = 14,
- GPBFieldDescriptorProto_Type_TypeSfixed32 = 15,
- GPBFieldDescriptorProto_Type_TypeSfixed64 = 16,
-
- // Uses ZigZag encoding.
- GPBFieldDescriptorProto_Type_TypeSint32 = 17,
-
- // Uses ZigZag encoding.
- GPBFieldDescriptorProto_Type_TypeSint64 = 18,
-};
-
-GPBEnumDescriptor *GPBFieldDescriptorProto_Type_EnumDescriptor(void);
-
-BOOL GPBFieldDescriptorProto_Type_IsValidValue(int32_t value);
-
-#pragma mark - Enum GPBFieldDescriptorProto_Label
-
-typedef GPB_ENUM(GPBFieldDescriptorProto_Label) {
- // 0 is reserved for errors
- GPBFieldDescriptorProto_Label_LabelOptional = 1,
- GPBFieldDescriptorProto_Label_LabelRequired = 2,
-
- // TODO(sanjay): Should we add LABEL_MAP?
- GPBFieldDescriptorProto_Label_LabelRepeated = 3,
-};
-
-GPBEnumDescriptor *GPBFieldDescriptorProto_Label_EnumDescriptor(void);
-
-BOOL GPBFieldDescriptorProto_Label_IsValidValue(int32_t value);
-
-#pragma mark - Enum GPBFileOptions_OptimizeMode
-
-// Generated classes can be optimized for speed or code size.
-typedef GPB_ENUM(GPBFileOptions_OptimizeMode) {
- // Generate complete code for parsing, serialization,
- GPBFileOptions_OptimizeMode_Speed = 1,
-
- // etc.
- GPBFileOptions_OptimizeMode_CodeSize = 2,
-
- // Generate code using MessageLite and the lite runtime.
- GPBFileOptions_OptimizeMode_LiteRuntime = 3,
-};
-
-GPBEnumDescriptor *GPBFileOptions_OptimizeMode_EnumDescriptor(void);
-
-BOOL GPBFileOptions_OptimizeMode_IsValidValue(int32_t value);
-
-#pragma mark - Enum GPBFieldOptions_CType
-
-typedef GPB_ENUM(GPBFieldOptions_CType) {
- // Default mode.
- GPBFieldOptions_CType_String = 0,
- GPBFieldOptions_CType_Cord = 1,
- GPBFieldOptions_CType_StringPiece = 2,
-};
-
-GPBEnumDescriptor *GPBFieldOptions_CType_EnumDescriptor(void);
-
-BOOL GPBFieldOptions_CType_IsValidValue(int32_t value);
-
-#pragma mark - Enum GPBFieldOptions_JSType
-
-typedef GPB_ENUM(GPBFieldOptions_JSType) {
- // Use the default type.
- GPBFieldOptions_JSType_JsNormal = 0,
-
- // Use JavaScript strings.
- GPBFieldOptions_JSType_JsString = 1,
-
- // Use JavaScript numbers.
- GPBFieldOptions_JSType_JsNumber = 2,
-};
-
-GPBEnumDescriptor *GPBFieldOptions_JSType_EnumDescriptor(void);
-
-BOOL GPBFieldOptions_JSType_IsValidValue(int32_t value);
-
-#pragma mark - GPBDescriptorRoot
-
-@interface GPBDescriptorRoot : GPBRootObject
-
-// The base class provides:
-// + (GPBExtensionRegistry *)extensionRegistry;
-// which is an GPBExtensionRegistry that includes all the extensions defined by
-// this file and all files that it depends on.
-
-@end
-
-#pragma mark - GPBFileDescriptorSet
-
-typedef GPB_ENUM(GPBFileDescriptorSet_FieldNumber) {
- GPBFileDescriptorSet_FieldNumber_FileArray = 1,
-};
-
-// The protocol compiler can output a FileDescriptorSet containing the .proto
-// files it parses.
-@interface GPBFileDescriptorSet : GPBMessage
-
-// |fileArray| contains |GPBFileDescriptorProto|
-@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *fileArray;
-@property(nonatomic, readonly) NSUInteger fileArray_Count;
-
-@end
-
-#pragma mark - GPBFileDescriptorProto
-
-typedef GPB_ENUM(GPBFileDescriptorProto_FieldNumber) {
- GPBFileDescriptorProto_FieldNumber_Name = 1,
- GPBFileDescriptorProto_FieldNumber_Package = 2,
- GPBFileDescriptorProto_FieldNumber_DependencyArray = 3,
- GPBFileDescriptorProto_FieldNumber_MessageTypeArray = 4,
- GPBFileDescriptorProto_FieldNumber_EnumTypeArray = 5,
- GPBFileDescriptorProto_FieldNumber_ServiceArray = 6,
- GPBFileDescriptorProto_FieldNumber_ExtensionArray = 7,
- GPBFileDescriptorProto_FieldNumber_Options = 8,
- GPBFileDescriptorProto_FieldNumber_SourceCodeInfo = 9,
- GPBFileDescriptorProto_FieldNumber_PublicDependencyArray = 10,
- GPBFileDescriptorProto_FieldNumber_WeakDependencyArray = 11,
- GPBFileDescriptorProto_FieldNumber_Syntax = 12,
-};
-
-// Describes a complete .proto file.
-@interface GPBFileDescriptorProto : GPBMessage
-
-// file name, relative to root of source tree
-@property(nonatomic, readwrite) BOOL hasName;
-@property(nonatomic, readwrite, copy, null_resettable) NSString *name;
-
-// e.g. "foo", "foo.bar", etc.
-@property(nonatomic, readwrite) BOOL hasPackage;
-@property(nonatomic, readwrite, copy, null_resettable) NSString *package;
-
-// Names of files imported by this file.
-// |dependencyArray| contains |NSString|
-@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *dependencyArray;
-@property(nonatomic, readonly) NSUInteger dependencyArray_Count;
-
-// Indexes of the public imported files in the dependency list above.
-@property(nonatomic, readwrite, strong, null_resettable) GPBInt32Array *publicDependencyArray;
-@property(nonatomic, readonly) NSUInteger publicDependencyArray_Count;
-
-// Indexes of the weak imported files in the dependency list.
-// For Google-internal migration only. Do not use.
-@property(nonatomic, readwrite, strong, null_resettable) GPBInt32Array *weakDependencyArray;
-@property(nonatomic, readonly) NSUInteger weakDependencyArray_Count;
-
-// All top-level definitions in this file.
-// |messageTypeArray| contains |GPBDescriptorProto|
-@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *messageTypeArray;
-@property(nonatomic, readonly) NSUInteger messageTypeArray_Count;
-
-// |enumTypeArray| contains |GPBEnumDescriptorProto|
-@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *enumTypeArray;
-@property(nonatomic, readonly) NSUInteger enumTypeArray_Count;
-
-// |serviceArray| contains |GPBServiceDescriptorProto|
-@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *serviceArray;
-@property(nonatomic, readonly) NSUInteger serviceArray_Count;
-
-// |extensionArray| contains |GPBFieldDescriptorProto|
-@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *extensionArray;
-@property(nonatomic, readonly) NSUInteger extensionArray_Count;
-
-@property(nonatomic, readwrite) BOOL hasOptions;
-@property(nonatomic, readwrite, strong, null_resettable) GPBFileOptions *options;
-
-// This field contains optional information about the original source code.
-// You may safely remove this entire field without harming runtime
-// functionality of the descriptors -- the information is needed only by
-// development tools.
-@property(nonatomic, readwrite) BOOL hasSourceCodeInfo;
-@property(nonatomic, readwrite, strong, null_resettable) GPBSourceCodeInfo *sourceCodeInfo;
-
-// The syntax of the proto file.
-// The supported values are "proto2" and "proto3".
-@property(nonatomic, readwrite) BOOL hasSyntax;
-@property(nonatomic, readwrite, copy, null_resettable) NSString *syntax;
-
-@end
-
-#pragma mark - GPBDescriptorProto
-
-typedef GPB_ENUM(GPBDescriptorProto_FieldNumber) {
- GPBDescriptorProto_FieldNumber_Name = 1,
- GPBDescriptorProto_FieldNumber_FieldArray = 2,
- GPBDescriptorProto_FieldNumber_NestedTypeArray = 3,
- GPBDescriptorProto_FieldNumber_EnumTypeArray = 4,
- GPBDescriptorProto_FieldNumber_ExtensionRangeArray = 5,
- GPBDescriptorProto_FieldNumber_ExtensionArray = 6,
- GPBDescriptorProto_FieldNumber_Options = 7,
- GPBDescriptorProto_FieldNumber_OneofDeclArray = 8,
- GPBDescriptorProto_FieldNumber_ReservedRangeArray = 9,
- GPBDescriptorProto_FieldNumber_ReservedNameArray = 10,
-};
-
-// Describes a message type.
-@interface GPBDescriptorProto : GPBMessage
-
-@property(nonatomic, readwrite) BOOL hasName;
-@property(nonatomic, readwrite, copy, null_resettable) NSString *name;
-
-// |fieldArray| contains |GPBFieldDescriptorProto|
-@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *fieldArray;
-@property(nonatomic, readonly) NSUInteger fieldArray_Count;
-
-// |extensionArray| contains |GPBFieldDescriptorProto|
-@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *extensionArray;
-@property(nonatomic, readonly) NSUInteger extensionArray_Count;
-
-// |nestedTypeArray| contains |GPBDescriptorProto|
-@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *nestedTypeArray;
-@property(nonatomic, readonly) NSUInteger nestedTypeArray_Count;
-
-// |enumTypeArray| contains |GPBEnumDescriptorProto|
-@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *enumTypeArray;
-@property(nonatomic, readonly) NSUInteger enumTypeArray_Count;
-
-// |extensionRangeArray| contains |GPBDescriptorProto_ExtensionRange|
-@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *extensionRangeArray;
-@property(nonatomic, readonly) NSUInteger extensionRangeArray_Count;
-
-// |oneofDeclArray| contains |GPBOneofDescriptorProto|
-@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *oneofDeclArray;
-@property(nonatomic, readonly) NSUInteger oneofDeclArray_Count;
-
-@property(nonatomic, readwrite) BOOL hasOptions;
-@property(nonatomic, readwrite, strong, null_resettable) GPBMessageOptions *options;
-
-// |reservedRangeArray| contains |GPBDescriptorProto_ReservedRange|
-@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *reservedRangeArray;
-@property(nonatomic, readonly) NSUInteger reservedRangeArray_Count;
-
-// Reserved field names, which may not be used by fields in the same message.
-// A given name may only be reserved once.
-// |reservedNameArray| contains |NSString|
-@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *reservedNameArray;
-@property(nonatomic, readonly) NSUInteger reservedNameArray_Count;
-
-@end
-
-#pragma mark - GPBDescriptorProto_ExtensionRange
-
-typedef GPB_ENUM(GPBDescriptorProto_ExtensionRange_FieldNumber) {
- GPBDescriptorProto_ExtensionRange_FieldNumber_Start = 1,
- GPBDescriptorProto_ExtensionRange_FieldNumber_End = 2,
-};
-
-@interface GPBDescriptorProto_ExtensionRange : GPBMessage
-
-@property(nonatomic, readwrite) BOOL hasStart;
-@property(nonatomic, readwrite) int32_t start;
-
-@property(nonatomic, readwrite) BOOL hasEnd;
-@property(nonatomic, readwrite) int32_t end;
-
-@end
-
-#pragma mark - GPBDescriptorProto_ReservedRange
-
-typedef GPB_ENUM(GPBDescriptorProto_ReservedRange_FieldNumber) {
- GPBDescriptorProto_ReservedRange_FieldNumber_Start = 1,
- GPBDescriptorProto_ReservedRange_FieldNumber_End = 2,
-};
-
-// Range of reserved tag numbers. Reserved tag numbers may not be used by
-// fields or extension ranges in the same message. Reserved ranges may
-// not overlap.
-@interface GPBDescriptorProto_ReservedRange : GPBMessage
-
-// Inclusive.
-@property(nonatomic, readwrite) BOOL hasStart;
-@property(nonatomic, readwrite) int32_t start;
-
-// Exclusive.
-@property(nonatomic, readwrite) BOOL hasEnd;
-@property(nonatomic, readwrite) int32_t end;
-
-@end
-
-#pragma mark - GPBFieldDescriptorProto
-
-typedef GPB_ENUM(GPBFieldDescriptorProto_FieldNumber) {
- GPBFieldDescriptorProto_FieldNumber_Name = 1,
- GPBFieldDescriptorProto_FieldNumber_Extendee = 2,
- GPBFieldDescriptorProto_FieldNumber_Number = 3,
- GPBFieldDescriptorProto_FieldNumber_Label = 4,
- GPBFieldDescriptorProto_FieldNumber_Type = 5,
- GPBFieldDescriptorProto_FieldNumber_TypeName = 6,
- GPBFieldDescriptorProto_FieldNumber_DefaultValue = 7,
- GPBFieldDescriptorProto_FieldNumber_Options = 8,
- GPBFieldDescriptorProto_FieldNumber_OneofIndex = 9,
- GPBFieldDescriptorProto_FieldNumber_JsonName = 10,
-};
-
-// Describes a field within a message.
-@interface GPBFieldDescriptorProto : GPBMessage
-
-@property(nonatomic, readwrite) BOOL hasName;
-@property(nonatomic, readwrite, copy, null_resettable) NSString *name;
-
-@property(nonatomic, readwrite) BOOL hasNumber;
-@property(nonatomic, readwrite) int32_t number;
-
-@property(nonatomic, readwrite) BOOL hasLabel;
-@property(nonatomic, readwrite) GPBFieldDescriptorProto_Label 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.
-@property(nonatomic, readwrite) BOOL hasType;
-@property(nonatomic, readwrite) GPBFieldDescriptorProto_Type 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
-// rules are used to find the type (i.e. first the nested types within this
-// message are searched, then within the parent, on up to the root
-// namespace).
-@property(nonatomic, readwrite) BOOL hasTypeName;
-@property(nonatomic, readwrite, copy, null_resettable) NSString *typeName;
-
-// For extensions, this is the name of the type being extended. It is
-// resolved in the same manner as type_name.
-@property(nonatomic, readwrite) BOOL hasExtendee;
-@property(nonatomic, readwrite, copy, null_resettable) NSString *extendee;
-
-// For numeric types, contains the original text representation of the value.
-// For booleans, "true" or "false".
-// For strings, contains the default text contents (not escaped in any way).
-// For bytes, contains the C escaped value. All bytes >= 128 are escaped.
-// TODO(kenton): Base-64 encode?
-@property(nonatomic, readwrite) BOOL hasDefaultValue;
-@property(nonatomic, readwrite, copy, null_resettable) NSString *defaultValue;
-
-// If set, gives the index of a oneof in the containing type's oneof_decl
-// list. This field is a member of that oneof.
-@property(nonatomic, readwrite) BOOL hasOneofIndex;
-@property(nonatomic, readwrite) int32_t oneofIndex;
-
-// 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
-// will be used. Otherwise, it's deduced from the field's name by converting
-// it to camelCase.
-@property(nonatomic, readwrite) BOOL hasJsonName;
-@property(nonatomic, readwrite, copy, null_resettable) NSString *jsonName;
-
-@property(nonatomic, readwrite) BOOL hasOptions;
-@property(nonatomic, readwrite, strong, null_resettable) GPBFieldOptions *options;
-
-@end
-
-#pragma mark - GPBOneofDescriptorProto
-
-typedef GPB_ENUM(GPBOneofDescriptorProto_FieldNumber) {
- GPBOneofDescriptorProto_FieldNumber_Name = 1,
-};
-
-// Describes a oneof.
-@interface GPBOneofDescriptorProto : GPBMessage
-
-@property(nonatomic, readwrite) BOOL hasName;
-@property(nonatomic, readwrite, copy, null_resettable) NSString *name;
-
-@end
-
-#pragma mark - GPBEnumDescriptorProto
-
-typedef GPB_ENUM(GPBEnumDescriptorProto_FieldNumber) {
- GPBEnumDescriptorProto_FieldNumber_Name = 1,
- GPBEnumDescriptorProto_FieldNumber_ValueArray = 2,
- GPBEnumDescriptorProto_FieldNumber_Options = 3,
-};
-
-// Describes an enum type.
-@interface GPBEnumDescriptorProto : GPBMessage
-
-@property(nonatomic, readwrite) BOOL hasName;
-@property(nonatomic, readwrite, copy, null_resettable) NSString *name;
-
-// |valueArray| contains |GPBEnumValueDescriptorProto|
-@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *valueArray;
-@property(nonatomic, readonly) NSUInteger valueArray_Count;
-
-@property(nonatomic, readwrite) BOOL hasOptions;
-@property(nonatomic, readwrite, strong, null_resettable) GPBEnumOptions *options;
-
-@end
-
-#pragma mark - GPBEnumValueDescriptorProto
-
-typedef GPB_ENUM(GPBEnumValueDescriptorProto_FieldNumber) {
- GPBEnumValueDescriptorProto_FieldNumber_Name = 1,
- GPBEnumValueDescriptorProto_FieldNumber_Number = 2,
- GPBEnumValueDescriptorProto_FieldNumber_Options = 3,
-};
-
-// Describes a value within an enum.
-@interface GPBEnumValueDescriptorProto : GPBMessage
-
-@property(nonatomic, readwrite) BOOL hasName;
-@property(nonatomic, readwrite, copy, null_resettable) NSString *name;
-
-@property(nonatomic, readwrite) BOOL hasNumber;
-@property(nonatomic, readwrite) int32_t number;
-
-@property(nonatomic, readwrite) BOOL hasOptions;
-@property(nonatomic, readwrite, strong, null_resettable) GPBEnumValueOptions *options;
-
-@end
-
-#pragma mark - GPBServiceDescriptorProto
-
-typedef GPB_ENUM(GPBServiceDescriptorProto_FieldNumber) {
- GPBServiceDescriptorProto_FieldNumber_Name = 1,
- GPBServiceDescriptorProto_FieldNumber_MethodArray = 2,
- GPBServiceDescriptorProto_FieldNumber_Options = 3,
-};
-
-// Describes a service.
-@interface GPBServiceDescriptorProto : GPBMessage
-
-@property(nonatomic, readwrite) BOOL hasName;
-@property(nonatomic, readwrite, copy, null_resettable) NSString *name;
-
-// |methodArray| contains |GPBMethodDescriptorProto|
-@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *methodArray;
-@property(nonatomic, readonly) NSUInteger methodArray_Count;
-
-@property(nonatomic, readwrite) BOOL hasOptions;
-@property(nonatomic, readwrite, strong, null_resettable) GPBServiceOptions *options;
-
-@end
-
-#pragma mark - GPBMethodDescriptorProto
-
-typedef GPB_ENUM(GPBMethodDescriptorProto_FieldNumber) {
- GPBMethodDescriptorProto_FieldNumber_Name = 1,
- GPBMethodDescriptorProto_FieldNumber_InputType = 2,
- GPBMethodDescriptorProto_FieldNumber_OutputType = 3,
- GPBMethodDescriptorProto_FieldNumber_Options = 4,
- GPBMethodDescriptorProto_FieldNumber_ClientStreaming = 5,
- GPBMethodDescriptorProto_FieldNumber_ServerStreaming = 6,
-};
-
-// Describes a method of a service.
-@interface GPBMethodDescriptorProto : GPBMessage
-
-@property(nonatomic, readwrite) BOOL hasName;
-@property(nonatomic, readwrite, copy, null_resettable) NSString *name;
-
-// Input and output type names. These are resolved in the same way as
-// FieldDescriptorProto.type_name, but must refer to a message type.
-@property(nonatomic, readwrite) BOOL hasInputType;
-@property(nonatomic, readwrite, copy, null_resettable) NSString *inputType;
-
-@property(nonatomic, readwrite) BOOL hasOutputType;
-@property(nonatomic, readwrite, copy, null_resettable) NSString *outputType;
-
-@property(nonatomic, readwrite) BOOL hasOptions;
-@property(nonatomic, readwrite, strong, null_resettable) GPBMethodOptions *options;
-
-// Identifies if client streams multiple client messages
-@property(nonatomic, readwrite) BOOL hasClientStreaming;
-@property(nonatomic, readwrite) BOOL clientStreaming;
-
-// Identifies if server streams multiple server messages
-@property(nonatomic, readwrite) BOOL hasServerStreaming;
-@property(nonatomic, readwrite) BOOL serverStreaming;
-
-@end
-
-#pragma mark - GPBFileOptions
-
-typedef GPB_ENUM(GPBFileOptions_FieldNumber) {
- GPBFileOptions_FieldNumber_JavaPackage = 1,
- GPBFileOptions_FieldNumber_JavaOuterClassname = 8,
- GPBFileOptions_FieldNumber_OptimizeFor = 9,
- GPBFileOptions_FieldNumber_JavaMultipleFiles = 10,
- GPBFileOptions_FieldNumber_GoPackage = 11,
- GPBFileOptions_FieldNumber_CcGenericServices = 16,
- GPBFileOptions_FieldNumber_JavaGenericServices = 17,
- GPBFileOptions_FieldNumber_PyGenericServices = 18,
- GPBFileOptions_FieldNumber_JavaGenerateEqualsAndHash = 20,
- GPBFileOptions_FieldNumber_Deprecated = 23,
- GPBFileOptions_FieldNumber_JavaStringCheckUtf8 = 27,
- GPBFileOptions_FieldNumber_CcEnableArenas = 31,
- GPBFileOptions_FieldNumber_ObjcClassPrefix = 36,
- GPBFileOptions_FieldNumber_CsharpNamespace = 37,
- GPBFileOptions_FieldNumber_JavananoUseDeprecatedPackage = 38,
- GPBFileOptions_FieldNumber_UninterpretedOptionArray = 999,
-};
-
-@interface GPBFileOptions : GPBMessage
-
-// Sets the Java package where classes generated from this .proto will be
-// placed. By default, the proto package is used, but this is often
-// inappropriate because proto packages do not normally start with backwards
-// domain names.
-@property(nonatomic, readwrite) BOOL hasJavaPackage;
-@property(nonatomic, readwrite, copy, null_resettable) NSString *javaPackage;
-
-// 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
-// (equivalent to the old "--one_java_file" option) and Proto2 (where
-// a .proto always translates to a single class, but you may want to
-// explicitly choose the class name).
-@property(nonatomic, readwrite) BOOL hasJavaOuterClassname;
-@property(nonatomic, readwrite, copy, null_resettable) NSString *javaOuterClassname;
-
-// 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
-// file. Thus, these types will *not* be nested inside the outer class
-// named by java_outer_classname. However, the outer class will still be
-// generated to contain the file's getDescriptor() method as well as any
-// top-level extensions defined in the file.
-@property(nonatomic, readwrite) BOOL hasJavaMultipleFiles;
-@property(nonatomic, readwrite) BOOL javaMultipleFiles;
-
-// If set true, then the Java code generator will generate equals() and
-// hashCode() methods for all messages defined in the .proto file.
-// This increases generated code size, potentially substantially for large
-// protos, which may harm a memory-constrained application.
-// - In the full runtime this is a speed optimization, as the
-// AbstractMessage base class includes reflection-based implementations of
-// these methods.
-// - In the lite runtime, setting this option changes the semantics of
-// equals() and hashCode() to more closely match those of the full runtime;
-// the generated methods compute their results based on field values rather
-// than object identity. (Implementations should not assume that hashcodes
-// will be consistent across runtimes or versions of the protocol compiler.)
-@property(nonatomic, readwrite) BOOL hasJavaGenerateEqualsAndHash;
-@property(nonatomic, readwrite) BOOL javaGenerateEqualsAndHash;
-
-// 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
-// byte sequence to a string field.
-// Message reflection will do the same.
-// However, an extension field still accepts non-UTF-8 byte sequences.
-// This option has no effect on when used with the lite runtime.
-@property(nonatomic, readwrite) BOOL hasJavaStringCheckUtf8;
-@property(nonatomic, readwrite) BOOL javaStringCheckUtf8;
-
-@property(nonatomic, readwrite) BOOL hasOptimizeFor;
-@property(nonatomic, readwrite) GPBFileOptions_OptimizeMode optimizeFor;
-
-// Sets the Go package where structs generated from this .proto will be
-// placed. If omitted, the Go package will be derived from the following:
-// - The basename of the package import path, if provided.
-// - Otherwise, the package statement in the .proto file, if present.
-// - Otherwise, the basename of the .proto file, without extension.
-@property(nonatomic, readwrite) BOOL hasGoPackage;
-@property(nonatomic, readwrite, copy, null_resettable) NSString *goPackage;
-
-// Should generic services be generated in each language? "Generic" services
-// are not specific to any particular RPC system. They are generated by the
-// main code generators in each language (without additional plugins).
-// Generic services were the only kind of service generation supported by
-// early versions of google.protobuf.
-//
-// Generic services are now considered deprecated in favor of using plugins
-// that generate code specific to your particular RPC system. Therefore,
-// these default to false. Old code which depends on generic services should
-// explicitly set them to true.
-@property(nonatomic, readwrite) BOOL hasCcGenericServices;
-@property(nonatomic, readwrite) BOOL ccGenericServices;
-
-@property(nonatomic, readwrite) BOOL hasJavaGenericServices;
-@property(nonatomic, readwrite) BOOL javaGenericServices;
-
-@property(nonatomic, readwrite) BOOL hasPyGenericServices;
-@property(nonatomic, readwrite) BOOL pyGenericServices;
-
-// Is this file deprecated?
-// Depending on the target platform, this can emit Deprecated annotations
-// for everything in the file, or it will be completely ignored; in the very
-// least, this is a formalization for deprecating files.
-@property(nonatomic, readwrite) BOOL hasDeprecated;
-@property(nonatomic, readwrite) BOOL deprecated;
-
-// Enables the use of arenas for the proto messages in this file. This applies
-// only to generated classes for C++.
-@property(nonatomic, readwrite) BOOL hasCcEnableArenas;
-@property(nonatomic, readwrite) BOOL ccEnableArenas;
-
-// Sets the objective c class prefix which is prepended to all objective c
-// generated classes from this .proto. There is no default.
-@property(nonatomic, readwrite) BOOL hasObjcClassPrefix;
-@property(nonatomic, readwrite, copy, null_resettable) NSString *objcClassPrefix;
-
-// Namespace for generated classes; defaults to the package.
-@property(nonatomic, readwrite) BOOL hasCsharpNamespace;
-@property(nonatomic, readwrite, copy, null_resettable) NSString *csharpNamespace;
-
-// Whether the nano proto compiler should generate in the deprecated non-nano
-// suffixed package.
-@property(nonatomic, readwrite) BOOL hasJavananoUseDeprecatedPackage;
-@property(nonatomic, readwrite) BOOL javananoUseDeprecatedPackage;
-
-// The parser stores options it doesn't recognize here. See above.
-// |uninterpretedOptionArray| contains |GPBUninterpretedOption|
-@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *uninterpretedOptionArray;
-@property(nonatomic, readonly) NSUInteger uninterpretedOptionArray_Count;
-
-@end
-
-#pragma mark - GPBMessageOptions
-
-typedef GPB_ENUM(GPBMessageOptions_FieldNumber) {
- GPBMessageOptions_FieldNumber_MessageSetWireFormat = 1,
- GPBMessageOptions_FieldNumber_NoStandardDescriptorAccessor = 2,
- GPBMessageOptions_FieldNumber_Deprecated = 3,
- GPBMessageOptions_FieldNumber_MapEntry = 7,
- GPBMessageOptions_FieldNumber_UninterpretedOptionArray = 999,
-};
-
-@interface GPBMessageOptions : GPBMessage
-
-// Set true to use the old proto1 MessageSet wire format for extensions.
-// This is provided for backwards-compatibility with the MessageSet wire
-// format. You should not use this for any other reason: It's less
-// efficient, has fewer features, and is more complicated.
-//
-// The message must be defined exactly as follows:
-// message Foo {
-// option message_set_wire_format = true;
-// extensions 4 to max;
-// }
-// Note that the message cannot have any defined fields; MessageSets only
-// have extensions.
-//
-// All extensions of your type must be singular messages; e.g. they cannot
-// be int32s, enums, or repeated messages.
-//
-// Because this is an option, the above two restrictions are not enforced by
-// the protocol compiler.
-@property(nonatomic, readwrite) BOOL hasMessageSetWireFormat;
-@property(nonatomic, readwrite) BOOL messageSetWireFormat;
-
-// Disables the generation of the standard "descriptor()" accessor, which can
-// conflict with a field of the same name. This is meant to make migration
-// from proto1 easier; new code should avoid fields named "descriptor".
-@property(nonatomic, readwrite) BOOL hasNoStandardDescriptorAccessor;
-@property(nonatomic, readwrite) BOOL noStandardDescriptorAccessor;
-
-// Is this message deprecated?
-// Depending on the target platform, this can emit Deprecated annotations
-// for the message, or it will be completely ignored; in the very least,
-// this is a formalization for deprecating messages.
-@property(nonatomic, readwrite) BOOL hasDeprecated;
-@property(nonatomic, readwrite) BOOL deprecated;
-
-// Whether the message is an automatically generated map entry type for the
-// maps field.
-//
-// For maps fields:
-// map<KeyType, ValueType> map_field = 1;
-// The parsed descriptor looks like:
-// message MapFieldEntry {
-// option map_entry = true;
-// optional KeyType key = 1;
-// optional ValueType value = 2;
-// }
-// repeated MapFieldEntry map_field = 1;
-//
-// Implementations may choose not to generate the map_entry=true message, but
-// use a native map in the target language to hold the keys and values.
-// The reflection APIs in such implementions still need to work as
-// if the field is a repeated message field.
-//
-// NOTE: Do not set the option in .proto files. Always use the maps syntax
-// instead. The option should only be implicitly set by the proto compiler
-// parser.
-@property(nonatomic, readwrite) BOOL hasMapEntry;
-@property(nonatomic, readwrite) BOOL mapEntry;
-
-// The parser stores options it doesn't recognize here. See above.
-// |uninterpretedOptionArray| contains |GPBUninterpretedOption|
-@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *uninterpretedOptionArray;
-@property(nonatomic, readonly) NSUInteger uninterpretedOptionArray_Count;
-
-@end
-
-#pragma mark - GPBFieldOptions
-
-typedef GPB_ENUM(GPBFieldOptions_FieldNumber) {
- GPBFieldOptions_FieldNumber_Ctype = 1,
- GPBFieldOptions_FieldNumber_Packed = 2,
- GPBFieldOptions_FieldNumber_Deprecated = 3,
- GPBFieldOptions_FieldNumber_Lazy = 5,
- GPBFieldOptions_FieldNumber_Jstype = 6,
- GPBFieldOptions_FieldNumber_Weak = 10,
- GPBFieldOptions_FieldNumber_UninterpretedOptionArray = 999,
-};
-
-@interface GPBFieldOptions : GPBMessage
-
-// The ctype option instructs the C++ code generator to use a different
-// representation of the field than it normally would. See the specific
-// options below. This option is not yet implemented in the open source
-// release -- sorry, we'll try to include it in a future version!
-@property(nonatomic, readwrite) BOOL hasCtype;
-@property(nonatomic, readwrite) GPBFieldOptions_CType ctype;
-
-// The packed option can be enabled for repeated primitive fields to enable
-// a more efficient representation on the wire. Rather than repeatedly
-// writing the tag and type for each element, the entire array is encoded as
-// a single length-delimited blob. In proto3, only explicit setting it to
-// false will avoid using packed encoding.
-@property(nonatomic, readwrite) BOOL hasPacked;
-@property(nonatomic, readwrite) BOOL 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
-// (int64, uint64, sint64, fixed64, sfixed64). By default these types are
-// represented as JavaScript strings. This avoids loss of precision that can
-// happen when a large value is converted to a floating point JavaScript
-// numbers. Specifying JS_NUMBER for the jstype causes the generated
-// JavaScript code to use the JavaScript "number" type instead of strings.
-// This option is an enum to permit additional types to be added,
-// e.g. goog.math.Integer.
-@property(nonatomic, readwrite) BOOL hasJstype;
-@property(nonatomic, readwrite) GPBFieldOptions_JSType 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
-// inner message's contents will not be parsed but instead stored in encoded
-// form. The inner message will actually be parsed when it is first accessed.
-//
-// This is only a hint. Implementations are free to choose whether to use
-// eager or lazy parsing regardless of the value of this option. However,
-// setting this option true suggests that the protocol author believes that
-// using lazy parsing on this field is worth the additional bookkeeping
-// overhead typically needed to implement it.
-//
-// This option does not affect the public interface of any generated code;
-// all method signatures remain the same. Furthermore, thread-safety of the
-// interface is not affected by this option; const methods remain safe to
-// call from multiple threads concurrently, while non-const methods continue
-// to require exclusive access.
-//
-//
-// Note that implementations may choose not to check required fields within
-// a lazy sub-message. That is, calling IsInitialized() on the outher message
-// may return true even if the inner message has missing required fields.
-// This is necessary because otherwise the inner message would have to be
-// parsed in order to perform the check, defeating the purpose of lazy
-// parsing. An implementation which chooses not to check required fields
-// must be consistent about it. That is, for any particular sub-message, the
-// implementation must either *always* check its required fields, or *never*
-// check its required fields, regardless of whether or not the message has
-// been parsed.
-@property(nonatomic, readwrite) BOOL hasLazy;
-@property(nonatomic, readwrite) BOOL lazy;
-
-// Is this field deprecated?
-// Depending on the target platform, this can emit Deprecated annotations
-// for accessors, or it will be completely ignored; in the very least, this
-// is a formalization for deprecating fields.
-@property(nonatomic, readwrite) BOOL hasDeprecated;
-@property(nonatomic, readwrite) BOOL deprecated;
-
-// For Google-internal migration only. Do not use.
-@property(nonatomic, readwrite) BOOL hasWeak;
-@property(nonatomic, readwrite) BOOL weak;
-
-// The parser stores options it doesn't recognize here. See above.
-// |uninterpretedOptionArray| contains |GPBUninterpretedOption|
-@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *uninterpretedOptionArray;
-@property(nonatomic, readonly) NSUInteger uninterpretedOptionArray_Count;
-
-@end
-
-#pragma mark - GPBEnumOptions
-
-typedef GPB_ENUM(GPBEnumOptions_FieldNumber) {
- GPBEnumOptions_FieldNumber_AllowAlias = 2,
- GPBEnumOptions_FieldNumber_Deprecated = 3,
- GPBEnumOptions_FieldNumber_UninterpretedOptionArray = 999,
-};
-
-@interface GPBEnumOptions : GPBMessage
-
-// Set this option to true to allow mapping different tag names to the same
-// value.
-@property(nonatomic, readwrite) BOOL hasAllowAlias;
-@property(nonatomic, readwrite) BOOL allowAlias;
-
-// Is this enum deprecated?
-// Depending on the target platform, this can emit Deprecated annotations
-// for the enum, or it will be completely ignored; in the very least, this
-// is a formalization for deprecating enums.
-@property(nonatomic, readwrite) BOOL hasDeprecated;
-@property(nonatomic, readwrite) BOOL deprecated;
-
-// The parser stores options it doesn't recognize here. See above.
-// |uninterpretedOptionArray| contains |GPBUninterpretedOption|
-@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *uninterpretedOptionArray;
-@property(nonatomic, readonly) NSUInteger uninterpretedOptionArray_Count;
-
-@end
-
-#pragma mark - GPBEnumValueOptions
-
-typedef GPB_ENUM(GPBEnumValueOptions_FieldNumber) {
- GPBEnumValueOptions_FieldNumber_Deprecated = 1,
- GPBEnumValueOptions_FieldNumber_UninterpretedOptionArray = 999,
-};
-
-@interface GPBEnumValueOptions : GPBMessage
-
-// Is this enum value deprecated?
-// Depending on the target platform, this can emit Deprecated annotations
-// for the enum value, or it will be completely ignored; in the very least,
-// this is a formalization for deprecating enum values.
-@property(nonatomic, readwrite) BOOL hasDeprecated;
-@property(nonatomic, readwrite) BOOL deprecated;
-
-// The parser stores options it doesn't recognize here. See above.
-// |uninterpretedOptionArray| contains |GPBUninterpretedOption|
-@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *uninterpretedOptionArray;
-@property(nonatomic, readonly) NSUInteger uninterpretedOptionArray_Count;
-
-@end
-
-#pragma mark - GPBServiceOptions
-
-typedef GPB_ENUM(GPBServiceOptions_FieldNumber) {
- GPBServiceOptions_FieldNumber_Deprecated = 33,
- GPBServiceOptions_FieldNumber_UninterpretedOptionArray = 999,
-};
-
-@interface GPBServiceOptions : GPBMessage
-
-// Is this service deprecated?
-// Depending on the target platform, this can emit Deprecated annotations
-// for the service, or it will be completely ignored; in the very least,
-// this is a formalization for deprecating services.
-@property(nonatomic, readwrite) BOOL hasDeprecated;
-@property(nonatomic, readwrite) BOOL deprecated;
-
-// The parser stores options it doesn't recognize here. See above.
-// |uninterpretedOptionArray| contains |GPBUninterpretedOption|
-@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *uninterpretedOptionArray;
-@property(nonatomic, readonly) NSUInteger uninterpretedOptionArray_Count;
-
-@end
-
-#pragma mark - GPBMethodOptions
-
-typedef GPB_ENUM(GPBMethodOptions_FieldNumber) {
- GPBMethodOptions_FieldNumber_Deprecated = 33,
- GPBMethodOptions_FieldNumber_UninterpretedOptionArray = 999,
-};
-
-@interface GPBMethodOptions : GPBMessage
-
-// Is this method deprecated?
-// Depending on the target platform, this can emit Deprecated annotations
-// for the method, or it will be completely ignored; in the very least,
-// this is a formalization for deprecating methods.
-@property(nonatomic, readwrite) BOOL hasDeprecated;
-@property(nonatomic, readwrite) BOOL deprecated;
-
-// The parser stores options it doesn't recognize here. See above.
-// |uninterpretedOptionArray| contains |GPBUninterpretedOption|
-@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *uninterpretedOptionArray;
-@property(nonatomic, readonly) NSUInteger uninterpretedOptionArray_Count;
-
-@end
-
-#pragma mark - GPBUninterpretedOption
-
-typedef GPB_ENUM(GPBUninterpretedOption_FieldNumber) {
- GPBUninterpretedOption_FieldNumber_NameArray = 2,
- GPBUninterpretedOption_FieldNumber_IdentifierValue = 3,
- GPBUninterpretedOption_FieldNumber_PositiveIntValue = 4,
- GPBUninterpretedOption_FieldNumber_NegativeIntValue = 5,
- GPBUninterpretedOption_FieldNumber_DoubleValue = 6,
- GPBUninterpretedOption_FieldNumber_StringValue = 7,
- GPBUninterpretedOption_FieldNumber_AggregateValue = 8,
-};
-
-// A message representing a option the parser does not recognize. This only
-// appears in options protos created by the compiler::Parser class.
-// DescriptorPool resolves these when building Descriptor objects. Therefore,
-// options protos in descriptor objects (e.g. returned by Descriptor::options(),
-// or produced by Descriptor::CopyTo()) will never have UninterpretedOptions
-// in them.
-@interface GPBUninterpretedOption : GPBMessage
-
-// |nameArray| contains |GPBUninterpretedOption_NamePart|
-@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *nameArray;
-@property(nonatomic, readonly) NSUInteger nameArray_Count;
-
-// The value of the uninterpreted option, in whatever type the tokenizer
-// identified it as during parsing. Exactly one of these should be set.
-@property(nonatomic, readwrite) BOOL hasIdentifierValue;
-@property(nonatomic, readwrite, copy, null_resettable) NSString *identifierValue;
-
-@property(nonatomic, readwrite) BOOL hasPositiveIntValue;
-@property(nonatomic, readwrite) uint64_t positiveIntValue;
-
-@property(nonatomic, readwrite) BOOL hasNegativeIntValue;
-@property(nonatomic, readwrite) int64_t negativeIntValue;
-
-@property(nonatomic, readwrite) BOOL hasDoubleValue;
-@property(nonatomic, readwrite) double doubleValue;
-
-@property(nonatomic, readwrite) BOOL hasStringValue;
-@property(nonatomic, readwrite, copy, null_resettable) NSData *stringValue;
-
-@property(nonatomic, readwrite) BOOL hasAggregateValue;
-@property(nonatomic, readwrite, copy, null_resettable) NSString *aggregateValue;
-
-@end
-
-#pragma mark - GPBUninterpretedOption_NamePart
-
-typedef GPB_ENUM(GPBUninterpretedOption_NamePart_FieldNumber) {
- GPBUninterpretedOption_NamePart_FieldNumber_NamePart = 1,
- GPBUninterpretedOption_NamePart_FieldNumber_IsExtension = 2,
-};
-
-// The name of the uninterpreted option. Each string represents a segment in
-// a dot-separated name. is_extension is true iff a segment represents an
-// extension (denoted with parentheses in options specs in .proto files).
-// E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents
-// "foo.(bar.baz).qux".
-@interface GPBUninterpretedOption_NamePart : GPBMessage
-
-@property(nonatomic, readwrite) BOOL hasNamePart;
-@property(nonatomic, readwrite, copy, null_resettable) NSString *namePart;
-
-@property(nonatomic, readwrite) BOOL hasIsExtension;
-@property(nonatomic, readwrite) BOOL isExtension;
-
-@end
-
-#pragma mark - GPBSourceCodeInfo
-
-typedef GPB_ENUM(GPBSourceCodeInfo_FieldNumber) {
- GPBSourceCodeInfo_FieldNumber_LocationArray = 1,
-};
-
-// Encapsulates information about the original source file from which a
-// FileDescriptorProto was generated.
-@interface GPBSourceCodeInfo : GPBMessage
-
-// A Location identifies a piece of source code in a .proto file which
-// corresponds to a particular definition. This information is intended
-// to be useful to IDEs, code indexers, documentation generators, and similar
-// tools.
-//
-// For example, say we have a file like:
-// message Foo {
-// optional string foo = 1;
-// }
-// Let's look at just the field definition:
-// optional string foo = 1;
-// ^ ^^ ^^ ^ ^^^
-// a bc de f ghi
-// We have the following locations:
-// span path represents
-// [a,i) [ 4, 0, 2, 0 ] The whole field definition.
-// [a,b) [ 4, 0, 2, 0, 4 ] The label (optional).
-// [c,d) [ 4, 0, 2, 0, 5 ] The type (string).
-// [e,f) [ 4, 0, 2, 0, 1 ] The name (foo).
-// [g,h) [ 4, 0, 2, 0, 3 ] The number (1).
-//
-// Notes:
-// - A location may refer to a repeated field itself (i.e. not to any
-// particular index within it). This is used whenever a set of elements are
-// logically enclosed in a single code segment. For example, an entire
-// extend block (possibly containing multiple extension definitions) will
-// have an outer location whose path refers to the "extensions" repeated
-// field without an index.
-// - Multiple locations may have the same path. This happens when a single
-// logical declaration is spread out across multiple places. The most
-// obvious example is the "extend" block again -- there may be multiple
-// extend blocks in the same scope, each of which will have the same path.
-// - A location's span is not always a subset of its parent's span. For
-// example, the "extendee" of an extension declaration appears at the
-// beginning of the "extend" block and is shared by all extensions within
-// the block.
-// - Just because a location's span is a subset of some other location's span
-// does not mean that it is a descendent. For example, a "group" defines
-// both a type and a field in a single declaration. Thus, the locations
-// corresponding to the type and field and their components will overlap.
-// - Code which tries to interpret locations should probably be designed to
-// ignore those that it doesn't understand, as more types of locations could
-// be recorded in the future.
-// |locationArray| contains |GPBSourceCodeInfo_Location|
-@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *locationArray;
-@property(nonatomic, readonly) NSUInteger locationArray_Count;
-
-@end
-
-#pragma mark - GPBSourceCodeInfo_Location
-
-typedef GPB_ENUM(GPBSourceCodeInfo_Location_FieldNumber) {
- GPBSourceCodeInfo_Location_FieldNumber_PathArray = 1,
- GPBSourceCodeInfo_Location_FieldNumber_SpanArray = 2,
- GPBSourceCodeInfo_Location_FieldNumber_LeadingComments = 3,
- GPBSourceCodeInfo_Location_FieldNumber_TrailingComments = 4,
- GPBSourceCodeInfo_Location_FieldNumber_LeadingDetachedCommentsArray = 6,
-};
-
-@interface GPBSourceCodeInfo_Location : GPBMessage
-
-// Identifies which part of the FileDescriptorProto was defined at this
-// location.
-//
-// Each element is a field number or an index. They form a path from
-// the root FileDescriptorProto to the place where the definition. For
-// example, this path:
-// [ 4, 3, 2, 7, 1 ]
-// refers to:
-// file.message_type(3) // 4, 3
-// .field(7) // 2, 7
-// .name() // 1
-// This is because FileDescriptorProto.message_type has field number 4:
-// repeated DescriptorProto message_type = 4;
-// and DescriptorProto.field has field number 2:
-// repeated FieldDescriptorProto field = 2;
-// and FieldDescriptorProto.name has field number 1:
-// optional string name = 1;
-//
-// Thus, the above path gives the location of a field name. If we removed
-// the last element:
-// [ 4, 3, 2, 7 ]
-// this path refers to the whole field declaration (from the beginning
-// of the label to the terminating semicolon).
-@property(nonatomic, readwrite, strong, null_resettable) GPBInt32Array *pathArray;
-@property(nonatomic, readonly) NSUInteger pathArray_Count;
-
-// Always has exactly three or four elements: start line, start column,
-// end line (optional, otherwise assumed same as start line), end column.
-// These are packed into a single field for efficiency. Note that line
-// and column numbers are zero-based -- typically you will want to add
-// 1 to each before displaying to a user.
-@property(nonatomic, readwrite, strong, null_resettable) GPBInt32Array *spanArray;
-@property(nonatomic, readonly) NSUInteger spanArray_Count;
-
-// If this SourceCodeInfo represents a complete declaration, these are any
-// comments appearing before and after the declaration which appear to be
-// attached to the declaration.
-//
-// A series of line comments appearing on consecutive lines, with no other
-// tokens appearing on those lines, will be treated as a single comment.
-//
-// leading_detached_comments will keep paragraphs of comments that appear
-// before (but not connected to) the current element. Each paragraph,
-// separated by empty lines, will be one comment element in the repeated
-// field.
-//
-// Only the comment content is provided; comment markers (e.g. //) are
-// stripped out. For block comments, leading whitespace and an asterisk
-// will be stripped from the beginning of each line other than the first.
-// Newlines are included in the output.
-//
-// Examples:
-//
-// optional int32 foo = 1; // Comment attached to foo.
-// // Comment attached to bar.
-// optional int32 bar = 2;
-//
-// optional string baz = 3;
-// // Comment attached to baz.
-// // Another line attached to baz.
-//
-// // Comment attached to qux.
-// //
-// // Another line attached to qux.
-// optional double qux = 4;
-//
-// // Detached comment for corge. This is not leading or trailing comments
-// // to qux or corge because there are blank lines separating it from
-// // both.
-//
-// // Detached comment for corge paragraph 2.
-//
-// optional string corge = 5;
-// /* Block comment attached
-// * to corge. Leading asterisks
-// * will be removed. */
-// /* Block comment attached to
-// * grault. */
-// optional int32 grault = 6;
-//
-// // ignored detached comments.
-@property(nonatomic, readwrite) BOOL hasLeadingComments;
-@property(nonatomic, readwrite, copy, null_resettable) NSString *leadingComments;
-
-@property(nonatomic, readwrite) BOOL hasTrailingComments;
-@property(nonatomic, readwrite, copy, null_resettable) NSString *trailingComments;
-
-// |leadingDetachedCommentsArray| contains |NSString|
-@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *leadingDetachedCommentsArray;
-@property(nonatomic, readonly) NSUInteger leadingDetachedCommentsArray_Count;
-
-@end
-
-NS_ASSUME_NONNULL_END
-
-CF_EXTERN_C_END
-
-// @@protoc_insertion_point(global_scope)
diff --git a/objectivec/google/protobuf/Descriptor.pbobjc.m b/objectivec/google/protobuf/Descriptor.pbobjc.m
deleted file mode 100644
index e3e44c48..00000000
--- a/objectivec/google/protobuf/Descriptor.pbobjc.m
+++ /dev/null
@@ -1,2445 +0,0 @@
-// Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: google/protobuf/descriptor.proto
-
-#import "GPBProtocolBuffers_RuntimeSupport.h"
-#import "google/protobuf/Descriptor.pbobjc.h"
-// @@protoc_insertion_point(imports)
-
-#pragma mark - GPBDescriptorRoot
-
-@implementation GPBDescriptorRoot
-
-@end
-
-#pragma mark - GPBDescriptorRoot_FileDescriptor
-
-static GPBFileDescriptor *GPBDescriptorRoot_FileDescriptor(void) {
- // This is called by +initialize so there is no need to worry
- // about thread safety of the singleton.
- static GPBFileDescriptor *descriptor = NULL;
- if (!descriptor) {
- GPBDebugCheckRuntimeVersion();
- descriptor = [[GPBFileDescriptor alloc] initWithPackage:@"google.protobuf"
- syntax:GPBFileSyntaxProto2];
- }
- return descriptor;
-}
-
-#pragma mark - GPBFileDescriptorSet
-
-@implementation GPBFileDescriptorSet
-
-@dynamic fileArray, fileArray_Count;
-
-typedef struct GPBFileDescriptorSet__storage_ {
- uint32_t _has_storage_[1];
- NSMutableArray *fileArray;
-} GPBFileDescriptorSet__storage_;
-
-// This method is threadsafe because it is initially called
-// in +initialize for each subclass.
-+ (GPBDescriptor *)descriptor {
- static GPBDescriptor *descriptor = nil;
- if (!descriptor) {
- static GPBMessageFieldDescription fields[] = {
- {
- .name = "fileArray",
- .number = GPBFileDescriptorSet_FieldNumber_FileArray,
- .hasIndex = GPBNoHasBit,
- .flags = GPBFieldRepeated,
- .dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBFileDescriptorSet__storage_, fileArray),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBFileDescriptorProto),
- .fieldOptions = NULL,
- },
- };
- GPBDescriptor *localDescriptor =
- [GPBDescriptor allocDescriptorForClass:[GPBFileDescriptorSet class]
- rootClass:[GPBDescriptorRoot class]
- file:GPBDescriptorRoot_FileDescriptor()
- fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:NULL
- oneofCount:0
- enums:NULL
- enumCount:0
- ranges:NULL
- rangeCount:0
- storageSize:sizeof(GPBFileDescriptorSet__storage_)
- wireFormat:NO];
- NSAssert(descriptor == nil, @"Startup recursed!");
- descriptor = localDescriptor;
- }
- return descriptor;
-}
-
-@end
-
-#pragma mark - GPBFileDescriptorProto
-
-@implementation GPBFileDescriptorProto
-
-@dynamic hasName, name;
-@dynamic hasPackage, package;
-@dynamic dependencyArray, dependencyArray_Count;
-@dynamic publicDependencyArray, publicDependencyArray_Count;
-@dynamic weakDependencyArray, weakDependencyArray_Count;
-@dynamic messageTypeArray, messageTypeArray_Count;
-@dynamic enumTypeArray, enumTypeArray_Count;
-@dynamic serviceArray, serviceArray_Count;
-@dynamic extensionArray, extensionArray_Count;
-@dynamic hasOptions, options;
-@dynamic hasSourceCodeInfo, sourceCodeInfo;
-@dynamic hasSyntax, syntax;
-
-typedef struct GPBFileDescriptorProto__storage_ {
- uint32_t _has_storage_[1];
- NSString *name;
- NSString *package;
- NSMutableArray *dependencyArray;
- NSMutableArray *messageTypeArray;
- NSMutableArray *enumTypeArray;
- NSMutableArray *serviceArray;
- NSMutableArray *extensionArray;
- GPBFileOptions *options;
- GPBSourceCodeInfo *sourceCodeInfo;
- GPBInt32Array *publicDependencyArray;
- GPBInt32Array *weakDependencyArray;
- NSString *syntax;
-} GPBFileDescriptorProto__storage_;
-
-// This method is threadsafe because it is initially called
-// in +initialize for each subclass.
-+ (GPBDescriptor *)descriptor {
- static GPBDescriptor *descriptor = nil;
- if (!descriptor) {
- static GPBMessageFieldDescription fields[] = {
- {
- .name = "name",
- .number = GPBFileDescriptorProto_FieldNumber_Name,
- .hasIndex = 0,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeString,
- .offset = offsetof(GPBFileDescriptorProto__storage_, name),
- .defaultValue.valueString = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "package",
- .number = GPBFileDescriptorProto_FieldNumber_Package,
- .hasIndex = 1,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeString,
- .offset = offsetof(GPBFileDescriptorProto__storage_, package),
- .defaultValue.valueString = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "dependencyArray",
- .number = GPBFileDescriptorProto_FieldNumber_DependencyArray,
- .hasIndex = GPBNoHasBit,
- .flags = GPBFieldRepeated,
- .dataType = GPBDataTypeString,
- .offset = offsetof(GPBFileDescriptorProto__storage_, dependencyArray),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "messageTypeArray",
- .number = GPBFileDescriptorProto_FieldNumber_MessageTypeArray,
- .hasIndex = GPBNoHasBit,
- .flags = GPBFieldRepeated,
- .dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBFileDescriptorProto__storage_, messageTypeArray),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBDescriptorProto),
- .fieldOptions = NULL,
- },
- {
- .name = "enumTypeArray",
- .number = GPBFileDescriptorProto_FieldNumber_EnumTypeArray,
- .hasIndex = GPBNoHasBit,
- .flags = GPBFieldRepeated,
- .dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBFileDescriptorProto__storage_, enumTypeArray),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBEnumDescriptorProto),
- .fieldOptions = NULL,
- },
- {
- .name = "serviceArray",
- .number = GPBFileDescriptorProto_FieldNumber_ServiceArray,
- .hasIndex = GPBNoHasBit,
- .flags = GPBFieldRepeated,
- .dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBFileDescriptorProto__storage_, serviceArray),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBServiceDescriptorProto),
- .fieldOptions = NULL,
- },
- {
- .name = "extensionArray",
- .number = GPBFileDescriptorProto_FieldNumber_ExtensionArray,
- .hasIndex = GPBNoHasBit,
- .flags = GPBFieldRepeated,
- .dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBFileDescriptorProto__storage_, extensionArray),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBFieldDescriptorProto),
- .fieldOptions = NULL,
- },
- {
- .name = "options",
- .number = GPBFileDescriptorProto_FieldNumber_Options,
- .hasIndex = 9,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBFileDescriptorProto__storage_, options),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBFileOptions),
- .fieldOptions = NULL,
- },
- {
- .name = "sourceCodeInfo",
- .number = GPBFileDescriptorProto_FieldNumber_SourceCodeInfo,
- .hasIndex = 10,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBFileDescriptorProto__storage_, sourceCodeInfo),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBSourceCodeInfo),
- .fieldOptions = NULL,
- },
- {
- .name = "publicDependencyArray",
- .number = GPBFileDescriptorProto_FieldNumber_PublicDependencyArray,
- .hasIndex = GPBNoHasBit,
- .flags = GPBFieldRepeated,
- .dataType = GPBDataTypeInt32,
- .offset = offsetof(GPBFileDescriptorProto__storage_, publicDependencyArray),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "weakDependencyArray",
- .number = GPBFileDescriptorProto_FieldNumber_WeakDependencyArray,
- .hasIndex = GPBNoHasBit,
- .flags = GPBFieldRepeated,
- .dataType = GPBDataTypeInt32,
- .offset = offsetof(GPBFileDescriptorProto__storage_, weakDependencyArray),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "syntax",
- .number = GPBFileDescriptorProto_FieldNumber_Syntax,
- .hasIndex = 11,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeString,
- .offset = offsetof(GPBFileDescriptorProto__storage_, syntax),
- .defaultValue.valueString = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- };
- GPBDescriptor *localDescriptor =
- [GPBDescriptor allocDescriptorForClass:[GPBFileDescriptorProto class]
- rootClass:[GPBDescriptorRoot class]
- file:GPBDescriptorRoot_FileDescriptor()
- fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:NULL
- oneofCount:0
- enums:NULL
- enumCount:0
- ranges:NULL
- rangeCount:0
- storageSize:sizeof(GPBFileDescriptorProto__storage_)
- wireFormat:NO];
- NSAssert(descriptor == nil, @"Startup recursed!");
- descriptor = localDescriptor;
- }
- return descriptor;
-}
-
-@end
-
-#pragma mark - GPBDescriptorProto
-
-@implementation GPBDescriptorProto
-
-@dynamic hasName, name;
-@dynamic fieldArray, fieldArray_Count;
-@dynamic extensionArray, extensionArray_Count;
-@dynamic nestedTypeArray, nestedTypeArray_Count;
-@dynamic enumTypeArray, enumTypeArray_Count;
-@dynamic extensionRangeArray, extensionRangeArray_Count;
-@dynamic oneofDeclArray, oneofDeclArray_Count;
-@dynamic hasOptions, options;
-@dynamic reservedRangeArray, reservedRangeArray_Count;
-@dynamic reservedNameArray, reservedNameArray_Count;
-
-typedef struct GPBDescriptorProto__storage_ {
- uint32_t _has_storage_[1];
- NSString *name;
- NSMutableArray *fieldArray;
- NSMutableArray *nestedTypeArray;
- NSMutableArray *enumTypeArray;
- NSMutableArray *extensionRangeArray;
- NSMutableArray *extensionArray;
- GPBMessageOptions *options;
- NSMutableArray *oneofDeclArray;
- NSMutableArray *reservedRangeArray;
- NSMutableArray *reservedNameArray;
-} GPBDescriptorProto__storage_;
-
-// This method is threadsafe because it is initially called
-// in +initialize for each subclass.
-+ (GPBDescriptor *)descriptor {
- static GPBDescriptor *descriptor = nil;
- if (!descriptor) {
- static GPBMessageFieldDescription fields[] = {
- {
- .name = "name",
- .number = GPBDescriptorProto_FieldNumber_Name,
- .hasIndex = 0,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeString,
- .offset = offsetof(GPBDescriptorProto__storage_, name),
- .defaultValue.valueString = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "fieldArray",
- .number = GPBDescriptorProto_FieldNumber_FieldArray,
- .hasIndex = GPBNoHasBit,
- .flags = GPBFieldRepeated,
- .dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBDescriptorProto__storage_, fieldArray),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBFieldDescriptorProto),
- .fieldOptions = NULL,
- },
- {
- .name = "nestedTypeArray",
- .number = GPBDescriptorProto_FieldNumber_NestedTypeArray,
- .hasIndex = GPBNoHasBit,
- .flags = GPBFieldRepeated,
- .dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBDescriptorProto__storage_, nestedTypeArray),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBDescriptorProto),
- .fieldOptions = NULL,
- },
- {
- .name = "enumTypeArray",
- .number = GPBDescriptorProto_FieldNumber_EnumTypeArray,
- .hasIndex = GPBNoHasBit,
- .flags = GPBFieldRepeated,
- .dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBDescriptorProto__storage_, enumTypeArray),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBEnumDescriptorProto),
- .fieldOptions = NULL,
- },
- {
- .name = "extensionRangeArray",
- .number = GPBDescriptorProto_FieldNumber_ExtensionRangeArray,
- .hasIndex = GPBNoHasBit,
- .flags = GPBFieldRepeated,
- .dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBDescriptorProto__storage_, extensionRangeArray),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBDescriptorProto_ExtensionRange),
- .fieldOptions = NULL,
- },
- {
- .name = "extensionArray",
- .number = GPBDescriptorProto_FieldNumber_ExtensionArray,
- .hasIndex = GPBNoHasBit,
- .flags = GPBFieldRepeated,
- .dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBDescriptorProto__storage_, extensionArray),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBFieldDescriptorProto),
- .fieldOptions = NULL,
- },
- {
- .name = "options",
- .number = GPBDescriptorProto_FieldNumber_Options,
- .hasIndex = 7,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBDescriptorProto__storage_, options),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBMessageOptions),
- .fieldOptions = NULL,
- },
- {
- .name = "oneofDeclArray",
- .number = GPBDescriptorProto_FieldNumber_OneofDeclArray,
- .hasIndex = GPBNoHasBit,
- .flags = GPBFieldRepeated,
- .dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBDescriptorProto__storage_, oneofDeclArray),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBOneofDescriptorProto),
- .fieldOptions = NULL,
- },
- {
- .name = "reservedRangeArray",
- .number = GPBDescriptorProto_FieldNumber_ReservedRangeArray,
- .hasIndex = GPBNoHasBit,
- .flags = GPBFieldRepeated,
- .dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBDescriptorProto__storage_, reservedRangeArray),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBDescriptorProto_ReservedRange),
- .fieldOptions = NULL,
- },
- {
- .name = "reservedNameArray",
- .number = GPBDescriptorProto_FieldNumber_ReservedNameArray,
- .hasIndex = GPBNoHasBit,
- .flags = GPBFieldRepeated,
- .dataType = GPBDataTypeString,
- .offset = offsetof(GPBDescriptorProto__storage_, reservedNameArray),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- };
- GPBDescriptor *localDescriptor =
- [GPBDescriptor allocDescriptorForClass:[GPBDescriptorProto class]
- rootClass:[GPBDescriptorRoot class]
- file:GPBDescriptorRoot_FileDescriptor()
- fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:NULL
- oneofCount:0
- enums:NULL
- enumCount:0
- ranges:NULL
- rangeCount:0
- storageSize:sizeof(GPBDescriptorProto__storage_)
- wireFormat:NO];
- NSAssert(descriptor == nil, @"Startup recursed!");
- descriptor = localDescriptor;
- }
- return descriptor;
-}
-
-@end
-
-#pragma mark - GPBDescriptorProto_ExtensionRange
-
-@implementation GPBDescriptorProto_ExtensionRange
-
-@dynamic hasStart, start;
-@dynamic hasEnd, end;
-
-typedef struct GPBDescriptorProto_ExtensionRange__storage_ {
- uint32_t _has_storage_[1];
- int32_t start;
- int32_t end;
-} GPBDescriptorProto_ExtensionRange__storage_;
-
-// This method is threadsafe because it is initially called
-// in +initialize for each subclass.
-+ (GPBDescriptor *)descriptor {
- static GPBDescriptor *descriptor = nil;
- if (!descriptor) {
- static GPBMessageFieldDescription fields[] = {
- {
- .name = "start",
- .number = GPBDescriptorProto_ExtensionRange_FieldNumber_Start,
- .hasIndex = 0,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeInt32,
- .offset = offsetof(GPBDescriptorProto_ExtensionRange__storage_, start),
- .defaultValue.valueInt32 = 0,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "end",
- .number = GPBDescriptorProto_ExtensionRange_FieldNumber_End,
- .hasIndex = 1,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeInt32,
- .offset = offsetof(GPBDescriptorProto_ExtensionRange__storage_, end),
- .defaultValue.valueInt32 = 0,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- };
- GPBDescriptor *localDescriptor =
- [GPBDescriptor allocDescriptorForClass:[GPBDescriptorProto_ExtensionRange class]
- rootClass:[GPBDescriptorRoot class]
- file:GPBDescriptorRoot_FileDescriptor()
- fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:NULL
- oneofCount:0
- enums:NULL
- enumCount:0
- ranges:NULL
- rangeCount:0
- storageSize:sizeof(GPBDescriptorProto_ExtensionRange__storage_)
- wireFormat:NO];
- NSAssert(descriptor == nil, @"Startup recursed!");
- descriptor = localDescriptor;
- }
- return descriptor;
-}
-
-@end
-
-#pragma mark - GPBDescriptorProto_ReservedRange
-
-@implementation GPBDescriptorProto_ReservedRange
-
-@dynamic hasStart, start;
-@dynamic hasEnd, end;
-
-typedef struct GPBDescriptorProto_ReservedRange__storage_ {
- uint32_t _has_storage_[1];
- int32_t start;
- int32_t end;
-} GPBDescriptorProto_ReservedRange__storage_;
-
-// This method is threadsafe because it is initially called
-// in +initialize for each subclass.
-+ (GPBDescriptor *)descriptor {
- static GPBDescriptor *descriptor = nil;
- if (!descriptor) {
- static GPBMessageFieldDescription fields[] = {
- {
- .name = "start",
- .number = GPBDescriptorProto_ReservedRange_FieldNumber_Start,
- .hasIndex = 0,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeInt32,
- .offset = offsetof(GPBDescriptorProto_ReservedRange__storage_, start),
- .defaultValue.valueInt32 = 0,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "end",
- .number = GPBDescriptorProto_ReservedRange_FieldNumber_End,
- .hasIndex = 1,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeInt32,
- .offset = offsetof(GPBDescriptorProto_ReservedRange__storage_, end),
- .defaultValue.valueInt32 = 0,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- };
- GPBDescriptor *localDescriptor =
- [GPBDescriptor allocDescriptorForClass:[GPBDescriptorProto_ReservedRange class]
- rootClass:[GPBDescriptorRoot class]
- file:GPBDescriptorRoot_FileDescriptor()
- fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:NULL
- oneofCount:0
- enums:NULL
- enumCount:0
- ranges:NULL
- rangeCount:0
- storageSize:sizeof(GPBDescriptorProto_ReservedRange__storage_)
- wireFormat:NO];
- NSAssert(descriptor == nil, @"Startup recursed!");
- descriptor = localDescriptor;
- }
- return descriptor;
-}
-
-@end
-
-#pragma mark - GPBFieldDescriptorProto
-
-@implementation GPBFieldDescriptorProto
-
-@dynamic hasName, name;
-@dynamic hasNumber, number;
-@dynamic hasLabel, label;
-@dynamic hasType, type;
-@dynamic hasTypeName, typeName;
-@dynamic hasExtendee, extendee;
-@dynamic hasDefaultValue, defaultValue;
-@dynamic hasOneofIndex, oneofIndex;
-@dynamic hasJsonName, jsonName;
-@dynamic hasOptions, options;
-
-typedef struct GPBFieldDescriptorProto__storage_ {
- uint32_t _has_storage_[1];
- int32_t number;
- GPBFieldDescriptorProto_Label label;
- GPBFieldDescriptorProto_Type type;
- int32_t oneofIndex;
- NSString *name;
- NSString *extendee;
- NSString *typeName;
- NSString *defaultValue;
- GPBFieldOptions *options;
- NSString *jsonName;
-} GPBFieldDescriptorProto__storage_;
-
-// This method is threadsafe because it is initially called
-// in +initialize for each subclass.
-+ (GPBDescriptor *)descriptor {
- static GPBDescriptor *descriptor = nil;
- if (!descriptor) {
- static GPBMessageFieldDescription fields[] = {
- {
- .name = "name",
- .number = GPBFieldDescriptorProto_FieldNumber_Name,
- .hasIndex = 0,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeString,
- .offset = offsetof(GPBFieldDescriptorProto__storage_, name),
- .defaultValue.valueString = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "extendee",
- .number = GPBFieldDescriptorProto_FieldNumber_Extendee,
- .hasIndex = 5,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeString,
- .offset = offsetof(GPBFieldDescriptorProto__storage_, extendee),
- .defaultValue.valueString = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "number",
- .number = GPBFieldDescriptorProto_FieldNumber_Number,
- .hasIndex = 1,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeInt32,
- .offset = offsetof(GPBFieldDescriptorProto__storage_, number),
- .defaultValue.valueInt32 = 0,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "label",
- .number = GPBFieldDescriptorProto_FieldNumber_Label,
- .hasIndex = 2,
- .flags = GPBFieldOptional | GPBFieldHasEnumDescriptor,
- .dataType = GPBDataTypeEnum,
- .offset = offsetof(GPBFieldDescriptorProto__storage_, label),
- .defaultValue.valueEnum = GPBFieldDescriptorProto_Label_LabelOptional,
- .dataTypeSpecific.enumDescFunc = GPBFieldDescriptorProto_Label_EnumDescriptor,
- .fieldOptions = NULL,
- },
- {
- .name = "type",
- .number = GPBFieldDescriptorProto_FieldNumber_Type,
- .hasIndex = 3,
- .flags = GPBFieldOptional | GPBFieldHasEnumDescriptor,
- .dataType = GPBDataTypeEnum,
- .offset = offsetof(GPBFieldDescriptorProto__storage_, type),
- .defaultValue.valueEnum = GPBFieldDescriptorProto_Type_TypeDouble,
- .dataTypeSpecific.enumDescFunc = GPBFieldDescriptorProto_Type_EnumDescriptor,
- .fieldOptions = NULL,
- },
- {
- .name = "typeName",
- .number = GPBFieldDescriptorProto_FieldNumber_TypeName,
- .hasIndex = 4,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeString,
- .offset = offsetof(GPBFieldDescriptorProto__storage_, typeName),
- .defaultValue.valueString = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "defaultValue",
- .number = GPBFieldDescriptorProto_FieldNumber_DefaultValue,
- .hasIndex = 6,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeString,
- .offset = offsetof(GPBFieldDescriptorProto__storage_, defaultValue),
- .defaultValue.valueString = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "options",
- .number = GPBFieldDescriptorProto_FieldNumber_Options,
- .hasIndex = 9,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBFieldDescriptorProto__storage_, options),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBFieldOptions),
- .fieldOptions = NULL,
- },
- {
- .name = "oneofIndex",
- .number = GPBFieldDescriptorProto_FieldNumber_OneofIndex,
- .hasIndex = 7,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeInt32,
- .offset = offsetof(GPBFieldDescriptorProto__storage_, oneofIndex),
- .defaultValue.valueInt32 = 0,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "jsonName",
- .number = GPBFieldDescriptorProto_FieldNumber_JsonName,
- .hasIndex = 8,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeString,
- .offset = offsetof(GPBFieldDescriptorProto__storage_, jsonName),
- .defaultValue.valueString = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- };
- static GPBMessageEnumDescription enums[] = {
- { .enumDescriptorFunc = GPBFieldDescriptorProto_Type_EnumDescriptor },
- { .enumDescriptorFunc = GPBFieldDescriptorProto_Label_EnumDescriptor },
- };
- GPBDescriptor *localDescriptor =
- [GPBDescriptor allocDescriptorForClass:[GPBFieldDescriptorProto class]
- rootClass:[GPBDescriptorRoot class]
- file:GPBDescriptorRoot_FileDescriptor()
- fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:NULL
- oneofCount:0
- enums:enums
- enumCount:sizeof(enums) / sizeof(GPBMessageEnumDescription)
- ranges:NULL
- rangeCount:0
- storageSize:sizeof(GPBFieldDescriptorProto__storage_)
- wireFormat:NO];
- NSAssert(descriptor == nil, @"Startup recursed!");
- descriptor = localDescriptor;
- }
- return descriptor;
-}
-
-@end
-
-#pragma mark - Enum GPBFieldDescriptorProto_Type
-
-GPBEnumDescriptor *GPBFieldDescriptorProto_Type_EnumDescriptor(void) {
- static GPBEnumDescriptor *descriptor = NULL;
- if (!descriptor) {
- static GPBMessageEnumValueDescription values[] = {
- { .name = "TypeDouble", .number = GPBFieldDescriptorProto_Type_TypeDouble },
- { .name = "TypeFloat", .number = GPBFieldDescriptorProto_Type_TypeFloat },
- { .name = "TypeInt64", .number = GPBFieldDescriptorProto_Type_TypeInt64 },
- { .name = "TypeUint64", .number = GPBFieldDescriptorProto_Type_TypeUint64 },
- { .name = "TypeInt32", .number = GPBFieldDescriptorProto_Type_TypeInt32 },
- { .name = "TypeFixed64", .number = GPBFieldDescriptorProto_Type_TypeFixed64 },
- { .name = "TypeFixed32", .number = GPBFieldDescriptorProto_Type_TypeFixed32 },
- { .name = "TypeBool", .number = GPBFieldDescriptorProto_Type_TypeBool },
- { .name = "TypeString", .number = GPBFieldDescriptorProto_Type_TypeString },
- { .name = "TypeGroup", .number = GPBFieldDescriptorProto_Type_TypeGroup },
- { .name = "TypeMessage", .number = GPBFieldDescriptorProto_Type_TypeMessage },
- { .name = "TypeBytes", .number = GPBFieldDescriptorProto_Type_TypeBytes },
- { .name = "TypeUint32", .number = GPBFieldDescriptorProto_Type_TypeUint32 },
- { .name = "TypeEnum", .number = GPBFieldDescriptorProto_Type_TypeEnum },
- { .name = "TypeSfixed32", .number = GPBFieldDescriptorProto_Type_TypeSfixed32 },
- { .name = "TypeSfixed64", .number = GPBFieldDescriptorProto_Type_TypeSfixed64 },
- { .name = "TypeSint32", .number = GPBFieldDescriptorProto_Type_TypeSint32 },
- { .name = "TypeSint64", .number = GPBFieldDescriptorProto_Type_TypeSint64 },
- };
- descriptor = [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GPBFieldDescriptorProto_Type)
- values:values
- valueCount:sizeof(values) / sizeof(GPBMessageEnumValueDescription)
- enumVerifier:GPBFieldDescriptorProto_Type_IsValidValue];
- }
- return descriptor;
-}
-
-BOOL GPBFieldDescriptorProto_Type_IsValidValue(int32_t value__) {
- switch (value__) {
- case GPBFieldDescriptorProto_Type_TypeDouble:
- case GPBFieldDescriptorProto_Type_TypeFloat:
- case GPBFieldDescriptorProto_Type_TypeInt64:
- case GPBFieldDescriptorProto_Type_TypeUint64:
- case GPBFieldDescriptorProto_Type_TypeInt32:
- case GPBFieldDescriptorProto_Type_TypeFixed64:
- case GPBFieldDescriptorProto_Type_TypeFixed32:
- case GPBFieldDescriptorProto_Type_TypeBool:
- case GPBFieldDescriptorProto_Type_TypeString:
- case GPBFieldDescriptorProto_Type_TypeGroup:
- case GPBFieldDescriptorProto_Type_TypeMessage:
- case GPBFieldDescriptorProto_Type_TypeBytes:
- case GPBFieldDescriptorProto_Type_TypeUint32:
- case GPBFieldDescriptorProto_Type_TypeEnum:
- case GPBFieldDescriptorProto_Type_TypeSfixed32:
- case GPBFieldDescriptorProto_Type_TypeSfixed64:
- case GPBFieldDescriptorProto_Type_TypeSint32:
- case GPBFieldDescriptorProto_Type_TypeSint64:
- return YES;
- default:
- return NO;
- }
-}
-
-#pragma mark - Enum GPBFieldDescriptorProto_Label
-
-GPBEnumDescriptor *GPBFieldDescriptorProto_Label_EnumDescriptor(void) {
- static GPBEnumDescriptor *descriptor = NULL;
- if (!descriptor) {
- static GPBMessageEnumValueDescription values[] = {
- { .name = "LabelOptional", .number = GPBFieldDescriptorProto_Label_LabelOptional },
- { .name = "LabelRequired", .number = GPBFieldDescriptorProto_Label_LabelRequired },
- { .name = "LabelRepeated", .number = GPBFieldDescriptorProto_Label_LabelRepeated },
- };
- descriptor = [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GPBFieldDescriptorProto_Label)
- values:values
- valueCount:sizeof(values) / sizeof(GPBMessageEnumValueDescription)
- enumVerifier:GPBFieldDescriptorProto_Label_IsValidValue];
- }
- return descriptor;
-}
-
-BOOL GPBFieldDescriptorProto_Label_IsValidValue(int32_t value__) {
- switch (value__) {
- case GPBFieldDescriptorProto_Label_LabelOptional:
- case GPBFieldDescriptorProto_Label_LabelRequired:
- case GPBFieldDescriptorProto_Label_LabelRepeated:
- return YES;
- default:
- return NO;
- }
-}
-
-#pragma mark - GPBOneofDescriptorProto
-
-@implementation GPBOneofDescriptorProto
-
-@dynamic hasName, name;
-
-typedef struct GPBOneofDescriptorProto__storage_ {
- uint32_t _has_storage_[1];
- NSString *name;
-} GPBOneofDescriptorProto__storage_;
-
-// This method is threadsafe because it is initially called
-// in +initialize for each subclass.
-+ (GPBDescriptor *)descriptor {
- static GPBDescriptor *descriptor = nil;
- if (!descriptor) {
- static GPBMessageFieldDescription fields[] = {
- {
- .name = "name",
- .number = GPBOneofDescriptorProto_FieldNumber_Name,
- .hasIndex = 0,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeString,
- .offset = offsetof(GPBOneofDescriptorProto__storage_, name),
- .defaultValue.valueString = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- };
- GPBDescriptor *localDescriptor =
- [GPBDescriptor allocDescriptorForClass:[GPBOneofDescriptorProto class]
- rootClass:[GPBDescriptorRoot class]
- file:GPBDescriptorRoot_FileDescriptor()
- fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:NULL
- oneofCount:0
- enums:NULL
- enumCount:0
- ranges:NULL
- rangeCount:0
- storageSize:sizeof(GPBOneofDescriptorProto__storage_)
- wireFormat:NO];
- NSAssert(descriptor == nil, @"Startup recursed!");
- descriptor = localDescriptor;
- }
- return descriptor;
-}
-
-@end
-
-#pragma mark - GPBEnumDescriptorProto
-
-@implementation GPBEnumDescriptorProto
-
-@dynamic hasName, name;
-@dynamic valueArray, valueArray_Count;
-@dynamic hasOptions, options;
-
-typedef struct GPBEnumDescriptorProto__storage_ {
- uint32_t _has_storage_[1];
- NSString *name;
- NSMutableArray *valueArray;
- GPBEnumOptions *options;
-} GPBEnumDescriptorProto__storage_;
-
-// This method is threadsafe because it is initially called
-// in +initialize for each subclass.
-+ (GPBDescriptor *)descriptor {
- static GPBDescriptor *descriptor = nil;
- if (!descriptor) {
- static GPBMessageFieldDescription fields[] = {
- {
- .name = "name",
- .number = GPBEnumDescriptorProto_FieldNumber_Name,
- .hasIndex = 0,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeString,
- .offset = offsetof(GPBEnumDescriptorProto__storage_, name),
- .defaultValue.valueString = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "valueArray",
- .number = GPBEnumDescriptorProto_FieldNumber_ValueArray,
- .hasIndex = GPBNoHasBit,
- .flags = GPBFieldRepeated,
- .dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBEnumDescriptorProto__storage_, valueArray),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBEnumValueDescriptorProto),
- .fieldOptions = NULL,
- },
- {
- .name = "options",
- .number = GPBEnumDescriptorProto_FieldNumber_Options,
- .hasIndex = 2,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBEnumDescriptorProto__storage_, options),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBEnumOptions),
- .fieldOptions = NULL,
- },
- };
- GPBDescriptor *localDescriptor =
- [GPBDescriptor allocDescriptorForClass:[GPBEnumDescriptorProto class]
- rootClass:[GPBDescriptorRoot class]
- file:GPBDescriptorRoot_FileDescriptor()
- fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:NULL
- oneofCount:0
- enums:NULL
- enumCount:0
- ranges:NULL
- rangeCount:0
- storageSize:sizeof(GPBEnumDescriptorProto__storage_)
- wireFormat:NO];
- NSAssert(descriptor == nil, @"Startup recursed!");
- descriptor = localDescriptor;
- }
- return descriptor;
-}
-
-@end
-
-#pragma mark - GPBEnumValueDescriptorProto
-
-@implementation GPBEnumValueDescriptorProto
-
-@dynamic hasName, name;
-@dynamic hasNumber, number;
-@dynamic hasOptions, options;
-
-typedef struct GPBEnumValueDescriptorProto__storage_ {
- uint32_t _has_storage_[1];
- int32_t number;
- NSString *name;
- GPBEnumValueOptions *options;
-} GPBEnumValueDescriptorProto__storage_;
-
-// This method is threadsafe because it is initially called
-// in +initialize for each subclass.
-+ (GPBDescriptor *)descriptor {
- static GPBDescriptor *descriptor = nil;
- if (!descriptor) {
- static GPBMessageFieldDescription fields[] = {
- {
- .name = "name",
- .number = GPBEnumValueDescriptorProto_FieldNumber_Name,
- .hasIndex = 0,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeString,
- .offset = offsetof(GPBEnumValueDescriptorProto__storage_, name),
- .defaultValue.valueString = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "number",
- .number = GPBEnumValueDescriptorProto_FieldNumber_Number,
- .hasIndex = 1,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeInt32,
- .offset = offsetof(GPBEnumValueDescriptorProto__storage_, number),
- .defaultValue.valueInt32 = 0,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "options",
- .number = GPBEnumValueDescriptorProto_FieldNumber_Options,
- .hasIndex = 2,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBEnumValueDescriptorProto__storage_, options),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBEnumValueOptions),
- .fieldOptions = NULL,
- },
- };
- GPBDescriptor *localDescriptor =
- [GPBDescriptor allocDescriptorForClass:[GPBEnumValueDescriptorProto class]
- rootClass:[GPBDescriptorRoot class]
- file:GPBDescriptorRoot_FileDescriptor()
- fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:NULL
- oneofCount:0
- enums:NULL
- enumCount:0
- ranges:NULL
- rangeCount:0
- storageSize:sizeof(GPBEnumValueDescriptorProto__storage_)
- wireFormat:NO];
- NSAssert(descriptor == nil, @"Startup recursed!");
- descriptor = localDescriptor;
- }
- return descriptor;
-}
-
-@end
-
-#pragma mark - GPBServiceDescriptorProto
-
-@implementation GPBServiceDescriptorProto
-
-@dynamic hasName, name;
-@dynamic methodArray, methodArray_Count;
-@dynamic hasOptions, options;
-
-typedef struct GPBServiceDescriptorProto__storage_ {
- uint32_t _has_storage_[1];
- NSString *name;
- NSMutableArray *methodArray;
- GPBServiceOptions *options;
-} GPBServiceDescriptorProto__storage_;
-
-// This method is threadsafe because it is initially called
-// in +initialize for each subclass.
-+ (GPBDescriptor *)descriptor {
- static GPBDescriptor *descriptor = nil;
- if (!descriptor) {
- static GPBMessageFieldDescription fields[] = {
- {
- .name = "name",
- .number = GPBServiceDescriptorProto_FieldNumber_Name,
- .hasIndex = 0,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeString,
- .offset = offsetof(GPBServiceDescriptorProto__storage_, name),
- .defaultValue.valueString = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "methodArray",
- .number = GPBServiceDescriptorProto_FieldNumber_MethodArray,
- .hasIndex = GPBNoHasBit,
- .flags = GPBFieldRepeated,
- .dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBServiceDescriptorProto__storage_, methodArray),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBMethodDescriptorProto),
- .fieldOptions = NULL,
- },
- {
- .name = "options",
- .number = GPBServiceDescriptorProto_FieldNumber_Options,
- .hasIndex = 2,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBServiceDescriptorProto__storage_, options),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBServiceOptions),
- .fieldOptions = NULL,
- },
- };
- GPBDescriptor *localDescriptor =
- [GPBDescriptor allocDescriptorForClass:[GPBServiceDescriptorProto class]
- rootClass:[GPBDescriptorRoot class]
- file:GPBDescriptorRoot_FileDescriptor()
- fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:NULL
- oneofCount:0
- enums:NULL
- enumCount:0
- ranges:NULL
- rangeCount:0
- storageSize:sizeof(GPBServiceDescriptorProto__storage_)
- wireFormat:NO];
- NSAssert(descriptor == nil, @"Startup recursed!");
- descriptor = localDescriptor;
- }
- return descriptor;
-}
-
-@end
-
-#pragma mark - GPBMethodDescriptorProto
-
-@implementation GPBMethodDescriptorProto
-
-@dynamic hasName, name;
-@dynamic hasInputType, inputType;
-@dynamic hasOutputType, outputType;
-@dynamic hasOptions, options;
-@dynamic hasClientStreaming, clientStreaming;
-@dynamic hasServerStreaming, serverStreaming;
-
-typedef struct GPBMethodDescriptorProto__storage_ {
- uint32_t _has_storage_[1];
- BOOL clientStreaming;
- BOOL serverStreaming;
- NSString *name;
- NSString *inputType;
- NSString *outputType;
- GPBMethodOptions *options;
-} GPBMethodDescriptorProto__storage_;
-
-// This method is threadsafe because it is initially called
-// in +initialize for each subclass.
-+ (GPBDescriptor *)descriptor {
- static GPBDescriptor *descriptor = nil;
- if (!descriptor) {
- static GPBMessageFieldDescription fields[] = {
- {
- .name = "name",
- .number = GPBMethodDescriptorProto_FieldNumber_Name,
- .hasIndex = 0,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeString,
- .offset = offsetof(GPBMethodDescriptorProto__storage_, name),
- .defaultValue.valueString = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "inputType",
- .number = GPBMethodDescriptorProto_FieldNumber_InputType,
- .hasIndex = 1,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeString,
- .offset = offsetof(GPBMethodDescriptorProto__storage_, inputType),
- .defaultValue.valueString = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "outputType",
- .number = GPBMethodDescriptorProto_FieldNumber_OutputType,
- .hasIndex = 2,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeString,
- .offset = offsetof(GPBMethodDescriptorProto__storage_, outputType),
- .defaultValue.valueString = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "options",
- .number = GPBMethodDescriptorProto_FieldNumber_Options,
- .hasIndex = 3,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBMethodDescriptorProto__storage_, options),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBMethodOptions),
- .fieldOptions = NULL,
- },
- {
- .name = "clientStreaming",
- .number = GPBMethodDescriptorProto_FieldNumber_ClientStreaming,
- .hasIndex = 4,
- .flags = GPBFieldOptional | GPBFieldHasDefaultValue,
- .dataType = GPBDataTypeBool,
- .offset = offsetof(GPBMethodDescriptorProto__storage_, clientStreaming),
- .defaultValue.valueBool = NO,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "serverStreaming",
- .number = GPBMethodDescriptorProto_FieldNumber_ServerStreaming,
- .hasIndex = 5,
- .flags = GPBFieldOptional | GPBFieldHasDefaultValue,
- .dataType = GPBDataTypeBool,
- .offset = offsetof(GPBMethodDescriptorProto__storage_, serverStreaming),
- .defaultValue.valueBool = NO,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- };
- GPBDescriptor *localDescriptor =
- [GPBDescriptor allocDescriptorForClass:[GPBMethodDescriptorProto class]
- rootClass:[GPBDescriptorRoot class]
- file:GPBDescriptorRoot_FileDescriptor()
- fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:NULL
- oneofCount:0
- enums:NULL
- enumCount:0
- ranges:NULL
- rangeCount:0
- storageSize:sizeof(GPBMethodDescriptorProto__storage_)
- wireFormat:NO];
- NSAssert(descriptor == nil, @"Startup recursed!");
- descriptor = localDescriptor;
- }
- return descriptor;
-}
-
-@end
-
-#pragma mark - GPBFileOptions
-
-@implementation GPBFileOptions
-
-@dynamic hasJavaPackage, javaPackage;
-@dynamic hasJavaOuterClassname, javaOuterClassname;
-@dynamic hasJavaMultipleFiles, javaMultipleFiles;
-@dynamic hasJavaGenerateEqualsAndHash, javaGenerateEqualsAndHash;
-@dynamic hasJavaStringCheckUtf8, javaStringCheckUtf8;
-@dynamic hasOptimizeFor, optimizeFor;
-@dynamic hasGoPackage, goPackage;
-@dynamic hasCcGenericServices, ccGenericServices;
-@dynamic hasJavaGenericServices, javaGenericServices;
-@dynamic hasPyGenericServices, pyGenericServices;
-@dynamic hasDeprecated, deprecated;
-@dynamic hasCcEnableArenas, ccEnableArenas;
-@dynamic hasObjcClassPrefix, objcClassPrefix;
-@dynamic hasCsharpNamespace, csharpNamespace;
-@dynamic hasJavananoUseDeprecatedPackage, javananoUseDeprecatedPackage;
-@dynamic uninterpretedOptionArray, uninterpretedOptionArray_Count;
-
-typedef struct GPBFileOptions__storage_ {
- uint32_t _has_storage_[1];
- BOOL javaMultipleFiles;
- BOOL ccGenericServices;
- BOOL javaGenericServices;
- BOOL pyGenericServices;
- BOOL javaGenerateEqualsAndHash;
- BOOL deprecated;
- BOOL javaStringCheckUtf8;
- BOOL ccEnableArenas;
- BOOL javananoUseDeprecatedPackage;
- GPBFileOptions_OptimizeMode optimizeFor;
- NSString *javaPackage;
- NSString *javaOuterClassname;
- NSString *goPackage;
- NSString *objcClassPrefix;
- NSString *csharpNamespace;
- NSMutableArray *uninterpretedOptionArray;
-} GPBFileOptions__storage_;
-
-// This method is threadsafe because it is initially called
-// in +initialize for each subclass.
-+ (GPBDescriptor *)descriptor {
- static GPBDescriptor *descriptor = nil;
- if (!descriptor) {
- static GPBMessageFieldDescription fields[] = {
- {
- .name = "javaPackage",
- .number = GPBFileOptions_FieldNumber_JavaPackage,
- .hasIndex = 0,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeString,
- .offset = offsetof(GPBFileOptions__storage_, javaPackage),
- .defaultValue.valueString = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "javaOuterClassname",
- .number = GPBFileOptions_FieldNumber_JavaOuterClassname,
- .hasIndex = 1,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeString,
- .offset = offsetof(GPBFileOptions__storage_, javaOuterClassname),
- .defaultValue.valueString = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "optimizeFor",
- .number = GPBFileOptions_FieldNumber_OptimizeFor,
- .hasIndex = 5,
- .flags = GPBFieldOptional | GPBFieldHasDefaultValue | GPBFieldHasEnumDescriptor,
- .dataType = GPBDataTypeEnum,
- .offset = offsetof(GPBFileOptions__storage_, optimizeFor),
- .defaultValue.valueEnum = GPBFileOptions_OptimizeMode_Speed,
- .dataTypeSpecific.enumDescFunc = GPBFileOptions_OptimizeMode_EnumDescriptor,
- .fieldOptions = NULL,
- },
- {
- .name = "javaMultipleFiles",
- .number = GPBFileOptions_FieldNumber_JavaMultipleFiles,
- .hasIndex = 2,
- .flags = GPBFieldOptional | GPBFieldHasDefaultValue,
- .dataType = GPBDataTypeBool,
- .offset = offsetof(GPBFileOptions__storage_, javaMultipleFiles),
- .defaultValue.valueBool = NO,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "goPackage",
- .number = GPBFileOptions_FieldNumber_GoPackage,
- .hasIndex = 6,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeString,
- .offset = offsetof(GPBFileOptions__storage_, goPackage),
- .defaultValue.valueString = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "ccGenericServices",
- .number = GPBFileOptions_FieldNumber_CcGenericServices,
- .hasIndex = 7,
- .flags = GPBFieldOptional | GPBFieldHasDefaultValue,
- .dataType = GPBDataTypeBool,
- .offset = offsetof(GPBFileOptions__storage_, ccGenericServices),
- .defaultValue.valueBool = NO,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "javaGenericServices",
- .number = GPBFileOptions_FieldNumber_JavaGenericServices,
- .hasIndex = 8,
- .flags = GPBFieldOptional | GPBFieldHasDefaultValue,
- .dataType = GPBDataTypeBool,
- .offset = offsetof(GPBFileOptions__storage_, javaGenericServices),
- .defaultValue.valueBool = NO,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "pyGenericServices",
- .number = GPBFileOptions_FieldNumber_PyGenericServices,
- .hasIndex = 9,
- .flags = GPBFieldOptional | GPBFieldHasDefaultValue,
- .dataType = GPBDataTypeBool,
- .offset = offsetof(GPBFileOptions__storage_, pyGenericServices),
- .defaultValue.valueBool = NO,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "javaGenerateEqualsAndHash",
- .number = GPBFileOptions_FieldNumber_JavaGenerateEqualsAndHash,
- .hasIndex = 3,
- .flags = GPBFieldOptional | GPBFieldHasDefaultValue,
- .dataType = GPBDataTypeBool,
- .offset = offsetof(GPBFileOptions__storage_, javaGenerateEqualsAndHash),
- .defaultValue.valueBool = NO,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "deprecated",
- .number = GPBFileOptions_FieldNumber_Deprecated,
- .hasIndex = 10,
- .flags = GPBFieldOptional | GPBFieldHasDefaultValue,
- .dataType = GPBDataTypeBool,
- .offset = offsetof(GPBFileOptions__storage_, deprecated),
- .defaultValue.valueBool = NO,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "javaStringCheckUtf8",
- .number = GPBFileOptions_FieldNumber_JavaStringCheckUtf8,
- .hasIndex = 4,
- .flags = GPBFieldOptional | GPBFieldHasDefaultValue,
- .dataType = GPBDataTypeBool,
- .offset = offsetof(GPBFileOptions__storage_, javaStringCheckUtf8),
- .defaultValue.valueBool = NO,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "ccEnableArenas",
- .number = GPBFileOptions_FieldNumber_CcEnableArenas,
- .hasIndex = 11,
- .flags = GPBFieldOptional | GPBFieldHasDefaultValue,
- .dataType = GPBDataTypeBool,
- .offset = offsetof(GPBFileOptions__storage_, ccEnableArenas),
- .defaultValue.valueBool = NO,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "objcClassPrefix",
- .number = GPBFileOptions_FieldNumber_ObjcClassPrefix,
- .hasIndex = 12,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeString,
- .offset = offsetof(GPBFileOptions__storage_, objcClassPrefix),
- .defaultValue.valueString = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "csharpNamespace",
- .number = GPBFileOptions_FieldNumber_CsharpNamespace,
- .hasIndex = 13,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeString,
- .offset = offsetof(GPBFileOptions__storage_, csharpNamespace),
- .defaultValue.valueString = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "javananoUseDeprecatedPackage",
- .number = GPBFileOptions_FieldNumber_JavananoUseDeprecatedPackage,
- .hasIndex = 14,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeBool,
- .offset = offsetof(GPBFileOptions__storage_, javananoUseDeprecatedPackage),
- .defaultValue.valueBool = NO,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "uninterpretedOptionArray",
- .number = GPBFileOptions_FieldNumber_UninterpretedOptionArray,
- .hasIndex = GPBNoHasBit,
- .flags = GPBFieldRepeated,
- .dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBFileOptions__storage_, uninterpretedOptionArray),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBUninterpretedOption),
- .fieldOptions = NULL,
- },
- };
- static GPBMessageEnumDescription enums[] = {
- { .enumDescriptorFunc = GPBFileOptions_OptimizeMode_EnumDescriptor },
- };
- static GPBExtensionRange ranges[] = {
- { .start = 1000, .end = 536870912 },
- };
- GPBDescriptor *localDescriptor =
- [GPBDescriptor allocDescriptorForClass:[GPBFileOptions class]
- rootClass:[GPBDescriptorRoot class]
- file:GPBDescriptorRoot_FileDescriptor()
- fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:NULL
- oneofCount:0
- enums:enums
- enumCount:sizeof(enums) / sizeof(GPBMessageEnumDescription)
- ranges:ranges
- rangeCount:sizeof(ranges) / sizeof(GPBExtensionRange)
- storageSize:sizeof(GPBFileOptions__storage_)
- wireFormat:NO];
- NSAssert(descriptor == nil, @"Startup recursed!");
- descriptor = localDescriptor;
- }
- return descriptor;
-}
-
-@end
-
-#pragma mark - Enum GPBFileOptions_OptimizeMode
-
-GPBEnumDescriptor *GPBFileOptions_OptimizeMode_EnumDescriptor(void) {
- static GPBEnumDescriptor *descriptor = NULL;
- if (!descriptor) {
- static GPBMessageEnumValueDescription values[] = {
- { .name = "Speed", .number = GPBFileOptions_OptimizeMode_Speed },
- { .name = "CodeSize", .number = GPBFileOptions_OptimizeMode_CodeSize },
- { .name = "LiteRuntime", .number = GPBFileOptions_OptimizeMode_LiteRuntime },
- };
- descriptor = [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GPBFileOptions_OptimizeMode)
- values:values
- valueCount:sizeof(values) / sizeof(GPBMessageEnumValueDescription)
- enumVerifier:GPBFileOptions_OptimizeMode_IsValidValue];
- }
- return descriptor;
-}
-
-BOOL GPBFileOptions_OptimizeMode_IsValidValue(int32_t value__) {
- switch (value__) {
- case GPBFileOptions_OptimizeMode_Speed:
- case GPBFileOptions_OptimizeMode_CodeSize:
- case GPBFileOptions_OptimizeMode_LiteRuntime:
- return YES;
- default:
- return NO;
- }
-}
-
-#pragma mark - GPBMessageOptions
-
-@implementation GPBMessageOptions
-
-@dynamic hasMessageSetWireFormat, messageSetWireFormat;
-@dynamic hasNoStandardDescriptorAccessor, noStandardDescriptorAccessor;
-@dynamic hasDeprecated, deprecated;
-@dynamic hasMapEntry, mapEntry;
-@dynamic uninterpretedOptionArray, uninterpretedOptionArray_Count;
-
-typedef struct GPBMessageOptions__storage_ {
- uint32_t _has_storage_[1];
- BOOL messageSetWireFormat;
- BOOL noStandardDescriptorAccessor;
- BOOL deprecated;
- BOOL mapEntry;
- NSMutableArray *uninterpretedOptionArray;
-} GPBMessageOptions__storage_;
-
-// This method is threadsafe because it is initially called
-// in +initialize for each subclass.
-+ (GPBDescriptor *)descriptor {
- static GPBDescriptor *descriptor = nil;
- if (!descriptor) {
- static GPBMessageFieldDescription fields[] = {
- {
- .name = "messageSetWireFormat",
- .number = GPBMessageOptions_FieldNumber_MessageSetWireFormat,
- .hasIndex = 0,
- .flags = GPBFieldOptional | GPBFieldHasDefaultValue,
- .dataType = GPBDataTypeBool,
- .offset = offsetof(GPBMessageOptions__storage_, messageSetWireFormat),
- .defaultValue.valueBool = NO,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "noStandardDescriptorAccessor",
- .number = GPBMessageOptions_FieldNumber_NoStandardDescriptorAccessor,
- .hasIndex = 1,
- .flags = GPBFieldOptional | GPBFieldHasDefaultValue,
- .dataType = GPBDataTypeBool,
- .offset = offsetof(GPBMessageOptions__storage_, noStandardDescriptorAccessor),
- .defaultValue.valueBool = NO,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "deprecated",
- .number = GPBMessageOptions_FieldNumber_Deprecated,
- .hasIndex = 2,
- .flags = GPBFieldOptional | GPBFieldHasDefaultValue,
- .dataType = GPBDataTypeBool,
- .offset = offsetof(GPBMessageOptions__storage_, deprecated),
- .defaultValue.valueBool = NO,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "mapEntry",
- .number = GPBMessageOptions_FieldNumber_MapEntry,
- .hasIndex = 3,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeBool,
- .offset = offsetof(GPBMessageOptions__storage_, mapEntry),
- .defaultValue.valueBool = NO,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "uninterpretedOptionArray",
- .number = GPBMessageOptions_FieldNumber_UninterpretedOptionArray,
- .hasIndex = GPBNoHasBit,
- .flags = GPBFieldRepeated,
- .dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBMessageOptions__storage_, uninterpretedOptionArray),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBUninterpretedOption),
- .fieldOptions = NULL,
- },
- };
- static GPBExtensionRange ranges[] = {
- { .start = 1000, .end = 536870912 },
- };
- GPBDescriptor *localDescriptor =
- [GPBDescriptor allocDescriptorForClass:[GPBMessageOptions class]
- rootClass:[GPBDescriptorRoot class]
- file:GPBDescriptorRoot_FileDescriptor()
- fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:NULL
- oneofCount:0
- enums:NULL
- enumCount:0
- ranges:ranges
- rangeCount:sizeof(ranges) / sizeof(GPBExtensionRange)
- storageSize:sizeof(GPBMessageOptions__storage_)
- wireFormat:NO];
- NSAssert(descriptor == nil, @"Startup recursed!");
- descriptor = localDescriptor;
- }
- return descriptor;
-}
-
-@end
-
-#pragma mark - GPBFieldOptions
-
-@implementation GPBFieldOptions
-
-@dynamic hasCtype, ctype;
-@dynamic hasPacked, packed;
-@dynamic hasJstype, jstype;
-@dynamic hasLazy, lazy;
-@dynamic hasDeprecated, deprecated;
-@dynamic hasWeak, weak;
-@dynamic uninterpretedOptionArray, uninterpretedOptionArray_Count;
-
-typedef struct GPBFieldOptions__storage_ {
- uint32_t _has_storage_[1];
- BOOL packed;
- BOOL deprecated;
- BOOL lazy;
- BOOL weak;
- GPBFieldOptions_CType ctype;
- GPBFieldOptions_JSType jstype;
- NSMutableArray *uninterpretedOptionArray;
-} GPBFieldOptions__storage_;
-
-// This method is threadsafe because it is initially called
-// in +initialize for each subclass.
-+ (GPBDescriptor *)descriptor {
- static GPBDescriptor *descriptor = nil;
- if (!descriptor) {
- static GPBMessageFieldDescription fields[] = {
- {
- .name = "ctype",
- .number = GPBFieldOptions_FieldNumber_Ctype,
- .hasIndex = 0,
- .flags = GPBFieldOptional | GPBFieldHasDefaultValue | GPBFieldHasEnumDescriptor,
- .dataType = GPBDataTypeEnum,
- .offset = offsetof(GPBFieldOptions__storage_, ctype),
- .defaultValue.valueEnum = GPBFieldOptions_CType_String,
- .dataTypeSpecific.enumDescFunc = GPBFieldOptions_CType_EnumDescriptor,
- .fieldOptions = NULL,
- },
- {
- .name = "packed",
- .number = GPBFieldOptions_FieldNumber_Packed,
- .hasIndex = 1,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeBool,
- .offset = offsetof(GPBFieldOptions__storage_, packed),
- .defaultValue.valueBool = NO,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "deprecated",
- .number = GPBFieldOptions_FieldNumber_Deprecated,
- .hasIndex = 4,
- .flags = GPBFieldOptional | GPBFieldHasDefaultValue,
- .dataType = GPBDataTypeBool,
- .offset = offsetof(GPBFieldOptions__storage_, deprecated),
- .defaultValue.valueBool = NO,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "lazy",
- .number = GPBFieldOptions_FieldNumber_Lazy,
- .hasIndex = 3,
- .flags = GPBFieldOptional | GPBFieldHasDefaultValue,
- .dataType = GPBDataTypeBool,
- .offset = offsetof(GPBFieldOptions__storage_, lazy),
- .defaultValue.valueBool = NO,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "jstype",
- .number = GPBFieldOptions_FieldNumber_Jstype,
- .hasIndex = 2,
- .flags = GPBFieldOptional | GPBFieldHasDefaultValue | GPBFieldHasEnumDescriptor,
- .dataType = GPBDataTypeEnum,
- .offset = offsetof(GPBFieldOptions__storage_, jstype),
- .defaultValue.valueEnum = GPBFieldOptions_JSType_JsNormal,
- .dataTypeSpecific.enumDescFunc = GPBFieldOptions_JSType_EnumDescriptor,
- .fieldOptions = NULL,
- },
- {
- .name = "weak",
- .number = GPBFieldOptions_FieldNumber_Weak,
- .hasIndex = 5,
- .flags = GPBFieldOptional | GPBFieldHasDefaultValue,
- .dataType = GPBDataTypeBool,
- .offset = offsetof(GPBFieldOptions__storage_, weak),
- .defaultValue.valueBool = NO,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "uninterpretedOptionArray",
- .number = GPBFieldOptions_FieldNumber_UninterpretedOptionArray,
- .hasIndex = GPBNoHasBit,
- .flags = GPBFieldRepeated,
- .dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBFieldOptions__storage_, uninterpretedOptionArray),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBUninterpretedOption),
- .fieldOptions = NULL,
- },
- };
- static GPBMessageEnumDescription enums[] = {
- { .enumDescriptorFunc = GPBFieldOptions_CType_EnumDescriptor },
- { .enumDescriptorFunc = GPBFieldOptions_JSType_EnumDescriptor },
- };
- static GPBExtensionRange ranges[] = {
- { .start = 1000, .end = 536870912 },
- };
- GPBDescriptor *localDescriptor =
- [GPBDescriptor allocDescriptorForClass:[GPBFieldOptions class]
- rootClass:[GPBDescriptorRoot class]
- file:GPBDescriptorRoot_FileDescriptor()
- fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:NULL
- oneofCount:0
- enums:enums
- enumCount:sizeof(enums) / sizeof(GPBMessageEnumDescription)
- ranges:ranges
- rangeCount:sizeof(ranges) / sizeof(GPBExtensionRange)
- storageSize:sizeof(GPBFieldOptions__storage_)
- wireFormat:NO];
- NSAssert(descriptor == nil, @"Startup recursed!");
- descriptor = localDescriptor;
- }
- return descriptor;
-}
-
-@end
-
-#pragma mark - Enum GPBFieldOptions_CType
-
-GPBEnumDescriptor *GPBFieldOptions_CType_EnumDescriptor(void) {
- static GPBEnumDescriptor *descriptor = NULL;
- if (!descriptor) {
- static GPBMessageEnumValueDescription values[] = {
- { .name = "String", .number = GPBFieldOptions_CType_String },
- { .name = "Cord", .number = GPBFieldOptions_CType_Cord },
- { .name = "StringPiece", .number = GPBFieldOptions_CType_StringPiece },
- };
- descriptor = [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GPBFieldOptions_CType)
- values:values
- valueCount:sizeof(values) / sizeof(GPBMessageEnumValueDescription)
- enumVerifier:GPBFieldOptions_CType_IsValidValue];
- }
- return descriptor;
-}
-
-BOOL GPBFieldOptions_CType_IsValidValue(int32_t value__) {
- switch (value__) {
- case GPBFieldOptions_CType_String:
- case GPBFieldOptions_CType_Cord:
- case GPBFieldOptions_CType_StringPiece:
- return YES;
- default:
- return NO;
- }
-}
-
-#pragma mark - Enum GPBFieldOptions_JSType
-
-GPBEnumDescriptor *GPBFieldOptions_JSType_EnumDescriptor(void) {
- static GPBEnumDescriptor *descriptor = NULL;
- if (!descriptor) {
- static GPBMessageEnumValueDescription values[] = {
- { .name = "JsNormal", .number = GPBFieldOptions_JSType_JsNormal },
- { .name = "JsString", .number = GPBFieldOptions_JSType_JsString },
- { .name = "JsNumber", .number = GPBFieldOptions_JSType_JsNumber },
- };
- descriptor = [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GPBFieldOptions_JSType)
- values:values
- valueCount:sizeof(values) / sizeof(GPBMessageEnumValueDescription)
- enumVerifier:GPBFieldOptions_JSType_IsValidValue];
- }
- return descriptor;
-}
-
-BOOL GPBFieldOptions_JSType_IsValidValue(int32_t value__) {
- switch (value__) {
- case GPBFieldOptions_JSType_JsNormal:
- case GPBFieldOptions_JSType_JsString:
- case GPBFieldOptions_JSType_JsNumber:
- return YES;
- default:
- return NO;
- }
-}
-
-#pragma mark - GPBEnumOptions
-
-@implementation GPBEnumOptions
-
-@dynamic hasAllowAlias, allowAlias;
-@dynamic hasDeprecated, deprecated;
-@dynamic uninterpretedOptionArray, uninterpretedOptionArray_Count;
-
-typedef struct GPBEnumOptions__storage_ {
- uint32_t _has_storage_[1];
- BOOL allowAlias;
- BOOL deprecated;
- NSMutableArray *uninterpretedOptionArray;
-} GPBEnumOptions__storage_;
-
-// This method is threadsafe because it is initially called
-// in +initialize for each subclass.
-+ (GPBDescriptor *)descriptor {
- static GPBDescriptor *descriptor = nil;
- if (!descriptor) {
- static GPBMessageFieldDescription fields[] = {
- {
- .name = "allowAlias",
- .number = GPBEnumOptions_FieldNumber_AllowAlias,
- .hasIndex = 0,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeBool,
- .offset = offsetof(GPBEnumOptions__storage_, allowAlias),
- .defaultValue.valueBool = NO,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "deprecated",
- .number = GPBEnumOptions_FieldNumber_Deprecated,
- .hasIndex = 1,
- .flags = GPBFieldOptional | GPBFieldHasDefaultValue,
- .dataType = GPBDataTypeBool,
- .offset = offsetof(GPBEnumOptions__storage_, deprecated),
- .defaultValue.valueBool = NO,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "uninterpretedOptionArray",
- .number = GPBEnumOptions_FieldNumber_UninterpretedOptionArray,
- .hasIndex = GPBNoHasBit,
- .flags = GPBFieldRepeated,
- .dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBEnumOptions__storage_, uninterpretedOptionArray),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBUninterpretedOption),
- .fieldOptions = NULL,
- },
- };
- static GPBExtensionRange ranges[] = {
- { .start = 1000, .end = 536870912 },
- };
- GPBDescriptor *localDescriptor =
- [GPBDescriptor allocDescriptorForClass:[GPBEnumOptions class]
- rootClass:[GPBDescriptorRoot class]
- file:GPBDescriptorRoot_FileDescriptor()
- fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:NULL
- oneofCount:0
- enums:NULL
- enumCount:0
- ranges:ranges
- rangeCount:sizeof(ranges) / sizeof(GPBExtensionRange)
- storageSize:sizeof(GPBEnumOptions__storage_)
- wireFormat:NO];
- NSAssert(descriptor == nil, @"Startup recursed!");
- descriptor = localDescriptor;
- }
- return descriptor;
-}
-
-@end
-
-#pragma mark - GPBEnumValueOptions
-
-@implementation GPBEnumValueOptions
-
-@dynamic hasDeprecated, deprecated;
-@dynamic uninterpretedOptionArray, uninterpretedOptionArray_Count;
-
-typedef struct GPBEnumValueOptions__storage_ {
- uint32_t _has_storage_[1];
- BOOL deprecated;
- NSMutableArray *uninterpretedOptionArray;
-} GPBEnumValueOptions__storage_;
-
-// This method is threadsafe because it is initially called
-// in +initialize for each subclass.
-+ (GPBDescriptor *)descriptor {
- static GPBDescriptor *descriptor = nil;
- if (!descriptor) {
- static GPBMessageFieldDescription fields[] = {
- {
- .name = "deprecated",
- .number = GPBEnumValueOptions_FieldNumber_Deprecated,
- .hasIndex = 0,
- .flags = GPBFieldOptional | GPBFieldHasDefaultValue,
- .dataType = GPBDataTypeBool,
- .offset = offsetof(GPBEnumValueOptions__storage_, deprecated),
- .defaultValue.valueBool = NO,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "uninterpretedOptionArray",
- .number = GPBEnumValueOptions_FieldNumber_UninterpretedOptionArray,
- .hasIndex = GPBNoHasBit,
- .flags = GPBFieldRepeated,
- .dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBEnumValueOptions__storage_, uninterpretedOptionArray),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBUninterpretedOption),
- .fieldOptions = NULL,
- },
- };
- static GPBExtensionRange ranges[] = {
- { .start = 1000, .end = 536870912 },
- };
- GPBDescriptor *localDescriptor =
- [GPBDescriptor allocDescriptorForClass:[GPBEnumValueOptions class]
- rootClass:[GPBDescriptorRoot class]
- file:GPBDescriptorRoot_FileDescriptor()
- fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:NULL
- oneofCount:0
- enums:NULL
- enumCount:0
- ranges:ranges
- rangeCount:sizeof(ranges) / sizeof(GPBExtensionRange)
- storageSize:sizeof(GPBEnumValueOptions__storage_)
- wireFormat:NO];
- NSAssert(descriptor == nil, @"Startup recursed!");
- descriptor = localDescriptor;
- }
- return descriptor;
-}
-
-@end
-
-#pragma mark - GPBServiceOptions
-
-@implementation GPBServiceOptions
-
-@dynamic hasDeprecated, deprecated;
-@dynamic uninterpretedOptionArray, uninterpretedOptionArray_Count;
-
-typedef struct GPBServiceOptions__storage_ {
- uint32_t _has_storage_[1];
- BOOL deprecated;
- NSMutableArray *uninterpretedOptionArray;
-} GPBServiceOptions__storage_;
-
-// This method is threadsafe because it is initially called
-// in +initialize for each subclass.
-+ (GPBDescriptor *)descriptor {
- static GPBDescriptor *descriptor = nil;
- if (!descriptor) {
- static GPBMessageFieldDescription fields[] = {
- {
- .name = "deprecated",
- .number = GPBServiceOptions_FieldNumber_Deprecated,
- .hasIndex = 0,
- .flags = GPBFieldOptional | GPBFieldHasDefaultValue,
- .dataType = GPBDataTypeBool,
- .offset = offsetof(GPBServiceOptions__storage_, deprecated),
- .defaultValue.valueBool = NO,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "uninterpretedOptionArray",
- .number = GPBServiceOptions_FieldNumber_UninterpretedOptionArray,
- .hasIndex = GPBNoHasBit,
- .flags = GPBFieldRepeated,
- .dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBServiceOptions__storage_, uninterpretedOptionArray),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBUninterpretedOption),
- .fieldOptions = NULL,
- },
- };
- static GPBExtensionRange ranges[] = {
- { .start = 1000, .end = 536870912 },
- };
- GPBDescriptor *localDescriptor =
- [GPBDescriptor allocDescriptorForClass:[GPBServiceOptions class]
- rootClass:[GPBDescriptorRoot class]
- file:GPBDescriptorRoot_FileDescriptor()
- fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:NULL
- oneofCount:0
- enums:NULL
- enumCount:0
- ranges:ranges
- rangeCount:sizeof(ranges) / sizeof(GPBExtensionRange)
- storageSize:sizeof(GPBServiceOptions__storage_)
- wireFormat:NO];
- NSAssert(descriptor == nil, @"Startup recursed!");
- descriptor = localDescriptor;
- }
- return descriptor;
-}
-
-@end
-
-#pragma mark - GPBMethodOptions
-
-@implementation GPBMethodOptions
-
-@dynamic hasDeprecated, deprecated;
-@dynamic uninterpretedOptionArray, uninterpretedOptionArray_Count;
-
-typedef struct GPBMethodOptions__storage_ {
- uint32_t _has_storage_[1];
- BOOL deprecated;
- NSMutableArray *uninterpretedOptionArray;
-} GPBMethodOptions__storage_;
-
-// This method is threadsafe because it is initially called
-// in +initialize for each subclass.
-+ (GPBDescriptor *)descriptor {
- static GPBDescriptor *descriptor = nil;
- if (!descriptor) {
- static GPBMessageFieldDescription fields[] = {
- {
- .name = "deprecated",
- .number = GPBMethodOptions_FieldNumber_Deprecated,
- .hasIndex = 0,
- .flags = GPBFieldOptional | GPBFieldHasDefaultValue,
- .dataType = GPBDataTypeBool,
- .offset = offsetof(GPBMethodOptions__storage_, deprecated),
- .defaultValue.valueBool = NO,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "uninterpretedOptionArray",
- .number = GPBMethodOptions_FieldNumber_UninterpretedOptionArray,
- .hasIndex = GPBNoHasBit,
- .flags = GPBFieldRepeated,
- .dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBMethodOptions__storage_, uninterpretedOptionArray),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBUninterpretedOption),
- .fieldOptions = NULL,
- },
- };
- static GPBExtensionRange ranges[] = {
- { .start = 1000, .end = 536870912 },
- };
- GPBDescriptor *localDescriptor =
- [GPBDescriptor allocDescriptorForClass:[GPBMethodOptions class]
- rootClass:[GPBDescriptorRoot class]
- file:GPBDescriptorRoot_FileDescriptor()
- fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:NULL
- oneofCount:0
- enums:NULL
- enumCount:0
- ranges:ranges
- rangeCount:sizeof(ranges) / sizeof(GPBExtensionRange)
- storageSize:sizeof(GPBMethodOptions__storage_)
- wireFormat:NO];
- NSAssert(descriptor == nil, @"Startup recursed!");
- descriptor = localDescriptor;
- }
- return descriptor;
-}
-
-@end
-
-#pragma mark - GPBUninterpretedOption
-
-@implementation GPBUninterpretedOption
-
-@dynamic nameArray, nameArray_Count;
-@dynamic hasIdentifierValue, identifierValue;
-@dynamic hasPositiveIntValue, positiveIntValue;
-@dynamic hasNegativeIntValue, negativeIntValue;
-@dynamic hasDoubleValue, doubleValue;
-@dynamic hasStringValue, stringValue;
-@dynamic hasAggregateValue, aggregateValue;
-
-typedef struct GPBUninterpretedOption__storage_ {
- uint32_t _has_storage_[1];
- NSMutableArray *nameArray;
- NSString *identifierValue;
- NSData *stringValue;
- NSString *aggregateValue;
- uint64_t positiveIntValue;
- int64_t negativeIntValue;
- double doubleValue;
-} GPBUninterpretedOption__storage_;
-
-// This method is threadsafe because it is initially called
-// in +initialize for each subclass.
-+ (GPBDescriptor *)descriptor {
- static GPBDescriptor *descriptor = nil;
- if (!descriptor) {
- static GPBMessageFieldDescription fields[] = {
- {
- .name = "nameArray",
- .number = GPBUninterpretedOption_FieldNumber_NameArray,
- .hasIndex = GPBNoHasBit,
- .flags = GPBFieldRepeated,
- .dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBUninterpretedOption__storage_, nameArray),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBUninterpretedOption_NamePart),
- .fieldOptions = NULL,
- },
- {
- .name = "identifierValue",
- .number = GPBUninterpretedOption_FieldNumber_IdentifierValue,
- .hasIndex = 1,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeString,
- .offset = offsetof(GPBUninterpretedOption__storage_, identifierValue),
- .defaultValue.valueString = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "positiveIntValue",
- .number = GPBUninterpretedOption_FieldNumber_PositiveIntValue,
- .hasIndex = 2,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeUInt64,
- .offset = offsetof(GPBUninterpretedOption__storage_, positiveIntValue),
- .defaultValue.valueUInt64 = 0ULL,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "negativeIntValue",
- .number = GPBUninterpretedOption_FieldNumber_NegativeIntValue,
- .hasIndex = 3,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeInt64,
- .offset = offsetof(GPBUninterpretedOption__storage_, negativeIntValue),
- .defaultValue.valueInt64 = 0LL,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "doubleValue",
- .number = GPBUninterpretedOption_FieldNumber_DoubleValue,
- .hasIndex = 4,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeDouble,
- .offset = offsetof(GPBUninterpretedOption__storage_, doubleValue),
- .defaultValue.valueDouble = 0,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "stringValue",
- .number = GPBUninterpretedOption_FieldNumber_StringValue,
- .hasIndex = 5,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeBytes,
- .offset = offsetof(GPBUninterpretedOption__storage_, stringValue),
- .defaultValue.valueData = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "aggregateValue",
- .number = GPBUninterpretedOption_FieldNumber_AggregateValue,
- .hasIndex = 6,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeString,
- .offset = offsetof(GPBUninterpretedOption__storage_, aggregateValue),
- .defaultValue.valueString = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- };
- GPBDescriptor *localDescriptor =
- [GPBDescriptor allocDescriptorForClass:[GPBUninterpretedOption class]
- rootClass:[GPBDescriptorRoot class]
- file:GPBDescriptorRoot_FileDescriptor()
- fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:NULL
- oneofCount:0
- enums:NULL
- enumCount:0
- ranges:NULL
- rangeCount:0
- storageSize:sizeof(GPBUninterpretedOption__storage_)
- wireFormat:NO];
- NSAssert(descriptor == nil, @"Startup recursed!");
- descriptor = localDescriptor;
- }
- return descriptor;
-}
-
-@end
-
-#pragma mark - GPBUninterpretedOption_NamePart
-
-@implementation GPBUninterpretedOption_NamePart
-
-@dynamic hasNamePart, namePart;
-@dynamic hasIsExtension, isExtension;
-
-typedef struct GPBUninterpretedOption_NamePart__storage_ {
- uint32_t _has_storage_[1];
- BOOL isExtension;
- NSString *namePart;
-} GPBUninterpretedOption_NamePart__storage_;
-
-// This method is threadsafe because it is initially called
-// in +initialize for each subclass.
-+ (GPBDescriptor *)descriptor {
- static GPBDescriptor *descriptor = nil;
- if (!descriptor) {
- static GPBMessageFieldDescription fields[] = {
- {
- .name = "namePart",
- .number = GPBUninterpretedOption_NamePart_FieldNumber_NamePart,
- .hasIndex = 0,
- .flags = GPBFieldRequired,
- .dataType = GPBDataTypeString,
- .offset = offsetof(GPBUninterpretedOption_NamePart__storage_, namePart),
- .defaultValue.valueString = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "isExtension",
- .number = GPBUninterpretedOption_NamePart_FieldNumber_IsExtension,
- .hasIndex = 1,
- .flags = GPBFieldRequired,
- .dataType = GPBDataTypeBool,
- .offset = offsetof(GPBUninterpretedOption_NamePart__storage_, isExtension),
- .defaultValue.valueBool = NO,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- };
- GPBDescriptor *localDescriptor =
- [GPBDescriptor allocDescriptorForClass:[GPBUninterpretedOption_NamePart class]
- rootClass:[GPBDescriptorRoot class]
- file:GPBDescriptorRoot_FileDescriptor()
- fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:NULL
- oneofCount:0
- enums:NULL
- enumCount:0
- ranges:NULL
- rangeCount:0
- storageSize:sizeof(GPBUninterpretedOption_NamePart__storage_)
- wireFormat:NO];
- NSAssert(descriptor == nil, @"Startup recursed!");
- descriptor = localDescriptor;
- }
- return descriptor;
-}
-
-@end
-
-#pragma mark - GPBSourceCodeInfo
-
-@implementation GPBSourceCodeInfo
-
-@dynamic locationArray, locationArray_Count;
-
-typedef struct GPBSourceCodeInfo__storage_ {
- uint32_t _has_storage_[1];
- NSMutableArray *locationArray;
-} GPBSourceCodeInfo__storage_;
-
-// This method is threadsafe because it is initially called
-// in +initialize for each subclass.
-+ (GPBDescriptor *)descriptor {
- static GPBDescriptor *descriptor = nil;
- if (!descriptor) {
- static GPBMessageFieldDescription fields[] = {
- {
- .name = "locationArray",
- .number = GPBSourceCodeInfo_FieldNumber_LocationArray,
- .hasIndex = GPBNoHasBit,
- .flags = GPBFieldRepeated,
- .dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBSourceCodeInfo__storage_, locationArray),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBSourceCodeInfo_Location),
- .fieldOptions = NULL,
- },
- };
- GPBDescriptor *localDescriptor =
- [GPBDescriptor allocDescriptorForClass:[GPBSourceCodeInfo class]
- rootClass:[GPBDescriptorRoot class]
- file:GPBDescriptorRoot_FileDescriptor()
- fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:NULL
- oneofCount:0
- enums:NULL
- enumCount:0
- ranges:NULL
- rangeCount:0
- storageSize:sizeof(GPBSourceCodeInfo__storage_)
- wireFormat:NO];
- NSAssert(descriptor == nil, @"Startup recursed!");
- descriptor = localDescriptor;
- }
- return descriptor;
-}
-
-@end
-
-#pragma mark - GPBSourceCodeInfo_Location
-
-@implementation GPBSourceCodeInfo_Location
-
-@dynamic pathArray, pathArray_Count;
-@dynamic spanArray, spanArray_Count;
-@dynamic hasLeadingComments, leadingComments;
-@dynamic hasTrailingComments, trailingComments;
-@dynamic leadingDetachedCommentsArray, leadingDetachedCommentsArray_Count;
-
-typedef struct GPBSourceCodeInfo_Location__storage_ {
- uint32_t _has_storage_[1];
- GPBInt32Array *pathArray;
- GPBInt32Array *spanArray;
- NSString *leadingComments;
- NSString *trailingComments;
- NSMutableArray *leadingDetachedCommentsArray;
-} GPBSourceCodeInfo_Location__storage_;
-
-// This method is threadsafe because it is initially called
-// in +initialize for each subclass.
-+ (GPBDescriptor *)descriptor {
- static GPBDescriptor *descriptor = nil;
- if (!descriptor) {
- static GPBMessageFieldDescription fields[] = {
- {
- .name = "pathArray",
- .number = GPBSourceCodeInfo_Location_FieldNumber_PathArray,
- .hasIndex = GPBNoHasBit,
- .flags = GPBFieldRepeated | GPBFieldPacked,
- .dataType = GPBDataTypeInt32,
- .offset = offsetof(GPBSourceCodeInfo_Location__storage_, pathArray),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = NULL,
- #if GPBOBJC_INCLUDE_FIELD_OPTIONS
- .fieldOptions = "\000\000\000\002\020\001",
- #else
- .fieldOptions = NULL,
- #endif // GPBOBJC_INCLUDE_FIELD_OPTIONS
- },
- {
- .name = "spanArray",
- .number = GPBSourceCodeInfo_Location_FieldNumber_SpanArray,
- .hasIndex = GPBNoHasBit,
- .flags = GPBFieldRepeated | GPBFieldPacked,
- .dataType = GPBDataTypeInt32,
- .offset = offsetof(GPBSourceCodeInfo_Location__storage_, spanArray),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = NULL,
- #if GPBOBJC_INCLUDE_FIELD_OPTIONS
- .fieldOptions = "\000\000\000\002\020\001",
- #else
- .fieldOptions = NULL,
- #endif // GPBOBJC_INCLUDE_FIELD_OPTIONS
- },
- {
- .name = "leadingComments",
- .number = GPBSourceCodeInfo_Location_FieldNumber_LeadingComments,
- .hasIndex = 2,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeString,
- .offset = offsetof(GPBSourceCodeInfo_Location__storage_, leadingComments),
- .defaultValue.valueString = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "trailingComments",
- .number = GPBSourceCodeInfo_Location_FieldNumber_TrailingComments,
- .hasIndex = 3,
- .flags = GPBFieldOptional,
- .dataType = GPBDataTypeString,
- .offset = offsetof(GPBSourceCodeInfo_Location__storage_, trailingComments),
- .defaultValue.valueString = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- {
- .name = "leadingDetachedCommentsArray",
- .number = GPBSourceCodeInfo_Location_FieldNumber_LeadingDetachedCommentsArray,
- .hasIndex = GPBNoHasBit,
- .flags = GPBFieldRepeated,
- .dataType = GPBDataTypeString,
- .offset = offsetof(GPBSourceCodeInfo_Location__storage_, leadingDetachedCommentsArray),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
- },
- };
- GPBDescriptor *localDescriptor =
- [GPBDescriptor allocDescriptorForClass:[GPBSourceCodeInfo_Location class]
- rootClass:[GPBDescriptorRoot class]
- file:GPBDescriptorRoot_FileDescriptor()
- fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:NULL
- oneofCount:0
- enums:NULL
- enumCount:0
- ranges:NULL
- rangeCount:0
- storageSize:sizeof(GPBSourceCodeInfo_Location__storage_)
- wireFormat:NO];
- NSAssert(descriptor == nil, @"Startup recursed!");
- descriptor = localDescriptor;
- }
- return descriptor;
-}
-
-@end
-
-
-// @@protoc_insertion_point(global_scope)
diff --git a/objectivec/google/protobuf/Duration.pbobjc.h b/objectivec/google/protobuf/Duration.pbobjc.h
index b592640b..4c3173d3 100644
--- a/objectivec/google/protobuf/Duration.pbobjc.h
+++ b/objectivec/google/protobuf/Duration.pbobjc.h
@@ -1,27 +1,42 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: google/protobuf/duration.proto
-#import "GPBProtocolBuffers.h"
+// This CPP symbol can be defined to use imports that match up to the framework
+// imports needed when using CocoaPods.
+#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS)
+ #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0
+#endif
+
+#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS
+ #import <Protobuf/GPBProtocolBuffers.h>
+#else
+ #import "GPBProtocolBuffers.h"
+#endif
-#if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30000
+#if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30001
#error This file was generated by a different version of protoc which is incompatible with your Protocol Buffer library sources.
#endif
// @@protoc_insertion_point(imports)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
CF_EXTERN_C_BEGIN
NS_ASSUME_NONNULL_BEGIN
#pragma mark - GPBDurationRoot
+/// Exposes the extension registry for this file.
+///
+/// The base class provides:
+/// @code
+/// + (GPBExtensionRegistry *)extensionRegistry;
+/// @endcode
+/// which is a @c GPBExtensionRegistry that includes all the extensions defined by
+/// this file and all files that it depends on.
@interface GPBDurationRoot : GPBRootObject
-
-// The base class provides:
-// + (GPBExtensionRegistry *)extensionRegistry;
-// which is an GPBExtensionRegistry that includes all the extensions defined by
-// this file and all files that it depends on.
-
@end
#pragma mark - GPBDuration
@@ -31,58 +46,58 @@ typedef GPB_ENUM(GPBDuration_FieldNumber) {
GPBDuration_FieldNumber_Nanos = 2,
};
-// A Duration represents a signed, fixed-length span of time represented
-// as a count of seconds and fractions of seconds at nanosecond
-// resolution. It is independent of any calendar and concepts like "day"
-// or "month". It is related to Timestamp in that the difference between
-// two Timestamp values is a Duration and it can be added or subtracted
-// from a Timestamp. Range is approximately +-10,000 years.
-//
-// Example 1: Compute Duration from two Timestamps in pseudo code.
-//
-// Timestamp start = ...;
-// Timestamp end = ...;
-// Duration duration = ...;
-//
-// duration.seconds = end.seconds - start.seconds;
-// duration.nanos = end.nanos - start.nanos;
-//
-// if (duration.seconds < 0 && duration.nanos > 0) {
-// duration.seconds += 1;
-// duration.nanos -= 1000000000;
-// } else if (durations.seconds > 0 && duration.nanos < 0) {
-// duration.seconds -= 1;
-// duration.nanos += 1000000000;
-// }
-//
-// Example 2: Compute Timestamp from Timestamp + Duration in pseudo code.
-//
-// Timestamp start = ...;
-// Duration duration = ...;
-// Timestamp end = ...;
-//
-// end.seconds = start.seconds + duration.seconds;
-// end.nanos = start.nanos + duration.nanos;
-//
-// if (end.nanos < 0) {
-// end.seconds -= 1;
-// end.nanos += 1000000000;
-// } else if (end.nanos >= 1000000000) {
-// end.seconds += 1;
-// end.nanos -= 1000000000;
-// }
+/// A Duration represents a signed, fixed-length span of time represented
+/// as a count of seconds and fractions of seconds at nanosecond
+/// resolution. It is independent of any calendar and concepts like "day"
+/// or "month". It is related to Timestamp in that the difference between
+/// two Timestamp values is a Duration and it can be added or subtracted
+/// from a Timestamp. Range is approximately +-10,000 years.
+///
+/// Example 1: Compute Duration from two Timestamps in pseudo code.
+///
+/// Timestamp start = ...;
+/// Timestamp end = ...;
+/// Duration duration = ...;
+///
+/// duration.seconds = end.seconds - start.seconds;
+/// duration.nanos = end.nanos - start.nanos;
+///
+/// if (duration.seconds < 0 && duration.nanos > 0) {
+/// duration.seconds += 1;
+/// duration.nanos -= 1000000000;
+/// } else if (durations.seconds > 0 && duration.nanos < 0) {
+/// duration.seconds -= 1;
+/// duration.nanos += 1000000000;
+/// }
+///
+/// Example 2: Compute Timestamp from Timestamp + Duration in pseudo code.
+///
+/// Timestamp start = ...;
+/// Duration duration = ...;
+/// Timestamp end = ...;
+///
+/// end.seconds = start.seconds + duration.seconds;
+/// end.nanos = start.nanos + duration.nanos;
+///
+/// if (end.nanos < 0) {
+/// end.seconds -= 1;
+/// end.nanos += 1000000000;
+/// } else if (end.nanos >= 1000000000) {
+/// end.seconds += 1;
+/// end.nanos -= 1000000000;
+/// }
@interface GPBDuration : GPBMessage
-// Signed seconds of the span of time. Must be from -315,576,000,000
-// to +315,576,000,000 inclusive.
+/// Signed seconds of the span of time. Must be from -315,576,000,000
+/// to +315,576,000,000 inclusive.
@property(nonatomic, readwrite) int64_t seconds;
-// Signed fractions of a second at nanosecond resolution of the span
-// of time. Durations less than one second are represented with a 0
-// `seconds` field and a positive or negative `nanos` field. For durations
-// of one second or more, a non-zero value for the `nanos` field must be
-// of the same sign as the `seconds` field. Must be from -999,999,999
-// to +999,999,999 inclusive.
+/// Signed fractions of a second at nanosecond resolution of the span
+/// of time. Durations less than one second are represented with a 0
+/// `seconds` field and a positive or negative `nanos` field. For durations
+/// of one second or more, a non-zero value for the `nanos` field must be
+/// of the same sign as the `seconds` field. Must be from -999,999,999
+/// to +999,999,999 inclusive.
@property(nonatomic, readwrite) int32_t nanos;
@end
@@ -91,4 +106,6 @@ NS_ASSUME_NONNULL_END
CF_EXTERN_C_END
+#pragma clang diagnostic pop
+
// @@protoc_insertion_point(global_scope)
diff --git a/objectivec/google/protobuf/Duration.pbobjc.m b/objectivec/google/protobuf/Duration.pbobjc.m
index e4fd4951..35daa3df 100644
--- a/objectivec/google/protobuf/Duration.pbobjc.m
+++ b/objectivec/google/protobuf/Duration.pbobjc.m
@@ -1,10 +1,28 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: google/protobuf/duration.proto
-#import "GPBProtocolBuffers_RuntimeSupport.h"
-#import "google/protobuf/Duration.pbobjc.h"
+// This CPP symbol can be defined to use imports that match up to the framework
+// imports needed when using CocoaPods.
+#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS)
+ #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0
+#endif
+
+#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS
+ #import <Protobuf/GPBProtocolBuffers_RuntimeSupport.h>
+#else
+ #import "GPBProtocolBuffers_RuntimeSupport.h"
+#endif
+
+#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS
+ #import <Protobuf/Duration.pbobjc.h>
+#else
+ #import "google/protobuf/Duration.pbobjc.h"
+#endif
// @@protoc_insertion_point(imports)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
#pragma mark - GPBDurationRoot
@implementation GPBDurationRoot
@@ -46,25 +64,21 @@ typedef struct GPBDuration__storage_ {
static GPBMessageFieldDescription fields[] = {
{
.name = "seconds",
+ .dataTypeSpecific.className = NULL,
.number = GPBDuration_FieldNumber_Seconds,
.hasIndex = 0,
+ .offset = (uint32_t)offsetof(GPBDuration__storage_, seconds),
.flags = GPBFieldOptional,
.dataType = GPBDataTypeInt64,
- .offset = offsetof(GPBDuration__storage_, seconds),
- .defaultValue.valueInt64 = 0LL,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
},
{
.name = "nanos",
+ .dataTypeSpecific.className = NULL,
.number = GPBDuration_FieldNumber_Nanos,
.hasIndex = 1,
+ .offset = (uint32_t)offsetof(GPBDuration__storage_, nanos),
.flags = GPBFieldOptional,
.dataType = GPBDataTypeInt32,
- .offset = offsetof(GPBDuration__storage_, nanos),
- .defaultValue.valueInt32 = 0,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
},
};
GPBDescriptor *localDescriptor =
@@ -72,15 +86,9 @@ typedef struct GPBDuration__storage_ {
rootClass:[GPBDurationRoot class]
file:GPBDurationRoot_FileDescriptor()
fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:NULL
- oneofCount:0
- enums:NULL
- enumCount:0
- ranges:NULL
- rangeCount:0
+ fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBDuration__storage_)
- wireFormat:NO];
+ flags:0];
NSAssert(descriptor == nil, @"Startup recursed!");
descriptor = localDescriptor;
}
@@ -90,4 +98,6 @@ typedef struct GPBDuration__storage_ {
@end
+#pragma clang diagnostic pop
+
// @@protoc_insertion_point(global_scope)
diff --git a/objectivec/google/protobuf/Empty.pbobjc.h b/objectivec/google/protobuf/Empty.pbobjc.h
index bace614d..2d2a86bc 100644
--- a/objectivec/google/protobuf/Empty.pbobjc.h
+++ b/objectivec/google/protobuf/Empty.pbobjc.h
@@ -1,40 +1,55 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: google/protobuf/empty.proto
-#import "GPBProtocolBuffers.h"
+// This CPP symbol can be defined to use imports that match up to the framework
+// imports needed when using CocoaPods.
+#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS)
+ #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0
+#endif
+
+#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS
+ #import <Protobuf/GPBProtocolBuffers.h>
+#else
+ #import "GPBProtocolBuffers.h"
+#endif
-#if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30000
+#if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30001
#error This file was generated by a different version of protoc which is incompatible with your Protocol Buffer library sources.
#endif
// @@protoc_insertion_point(imports)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
CF_EXTERN_C_BEGIN
NS_ASSUME_NONNULL_BEGIN
#pragma mark - GPBEmptyRoot
+/// Exposes the extension registry for this file.
+///
+/// The base class provides:
+/// @code
+/// + (GPBExtensionRegistry *)extensionRegistry;
+/// @endcode
+/// which is a @c GPBExtensionRegistry that includes all the extensions defined by
+/// this file and all files that it depends on.
@interface GPBEmptyRoot : GPBRootObject
-
-// The base class provides:
-// + (GPBExtensionRegistry *)extensionRegistry;
-// which is an GPBExtensionRegistry that includes all the extensions defined by
-// this file and all files that it depends on.
-
@end
#pragma mark - GPBEmpty
-// A generic empty message that you can re-use to avoid defining duplicated
-// empty messages in your APIs. A typical example is to use it as the request
-// or the response type of an API method. For instance:
-//
-// service Foo {
-// rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty);
-// }
-//
-// The JSON representation for `Empty` is empty JSON object `{}`.
+/// A generic empty message that you can re-use to avoid defining duplicated
+/// empty messages in your APIs. A typical example is to use it as the request
+/// or the response type of an API method. For instance:
+///
+/// service Foo {
+/// rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty);
+/// }
+///
+/// The JSON representation for `Empty` is empty JSON object `{}`.
@interface GPBEmpty : GPBMessage
@end
@@ -43,4 +58,6 @@ NS_ASSUME_NONNULL_END
CF_EXTERN_C_END
+#pragma clang diagnostic pop
+
// @@protoc_insertion_point(global_scope)
diff --git a/objectivec/google/protobuf/Empty.pbobjc.m b/objectivec/google/protobuf/Empty.pbobjc.m
index 17f0c1ac..1bdd4949 100644
--- a/objectivec/google/protobuf/Empty.pbobjc.m
+++ b/objectivec/google/protobuf/Empty.pbobjc.m
@@ -1,10 +1,28 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: google/protobuf/empty.proto
-#import "GPBProtocolBuffers_RuntimeSupport.h"
-#import "google/protobuf/Empty.pbobjc.h"
+// This CPP symbol can be defined to use imports that match up to the framework
+// imports needed when using CocoaPods.
+#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS)
+ #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0
+#endif
+
+#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS
+ #import <Protobuf/GPBProtocolBuffers_RuntimeSupport.h>
+#else
+ #import "GPBProtocolBuffers_RuntimeSupport.h"
+#endif
+
+#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS
+ #import <Protobuf/Empty.pbobjc.h>
+#else
+ #import "google/protobuf/Empty.pbobjc.h"
+#endif
// @@protoc_insertion_point(imports)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
#pragma mark - GPBEmptyRoot
@implementation GPBEmptyRoot
@@ -31,7 +49,7 @@ static GPBFileDescriptor *GPBEmptyRoot_FileDescriptor(void) {
typedef struct GPBEmpty__storage_ {
- uint32_t _has_storage_[0];
+ uint32_t _has_storage_[1];
} GPBEmpty__storage_;
// This method is threadsafe because it is initially called
@@ -45,14 +63,8 @@ typedef struct GPBEmpty__storage_ {
file:GPBEmptyRoot_FileDescriptor()
fields:NULL
fieldCount:0
- oneofs:NULL
- oneofCount:0
- enums:NULL
- enumCount:0
- ranges:NULL
- rangeCount:0
storageSize:sizeof(GPBEmpty__storage_)
- wireFormat:NO];
+ flags:0];
NSAssert(descriptor == nil, @"Startup recursed!");
descriptor = localDescriptor;
}
@@ -62,4 +74,6 @@ typedef struct GPBEmpty__storage_ {
@end
+#pragma clang diagnostic pop
+
// @@protoc_insertion_point(global_scope)
diff --git a/objectivec/google/protobuf/FieldMask.pbobjc.h b/objectivec/google/protobuf/FieldMask.pbobjc.h
index 67cea4d6..06053f1a 100644
--- a/objectivec/google/protobuf/FieldMask.pbobjc.h
+++ b/objectivec/google/protobuf/FieldMask.pbobjc.h
@@ -1,27 +1,42 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: google/protobuf/field_mask.proto
-#import "GPBProtocolBuffers.h"
+// This CPP symbol can be defined to use imports that match up to the framework
+// imports needed when using CocoaPods.
+#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS)
+ #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0
+#endif
+
+#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS
+ #import <Protobuf/GPBProtocolBuffers.h>
+#else
+ #import "GPBProtocolBuffers.h"
+#endif
-#if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30000
+#if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30001
#error This file was generated by a different version of protoc which is incompatible with your Protocol Buffer library sources.
#endif
// @@protoc_insertion_point(imports)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
CF_EXTERN_C_BEGIN
NS_ASSUME_NONNULL_BEGIN
#pragma mark - GPBFieldMaskRoot
+/// Exposes the extension registry for this file.
+///
+/// The base class provides:
+/// @code
+/// + (GPBExtensionRegistry *)extensionRegistry;
+/// @endcode
+/// which is a @c GPBExtensionRegistry that includes all the extensions defined by
+/// this file and all files that it depends on.
@interface GPBFieldMaskRoot : GPBRootObject
-
-// The base class provides:
-// + (GPBExtensionRegistry *)extensionRegistry;
-// which is an GPBExtensionRegistry that includes all the extensions defined by
-// this file and all files that it depends on.
-
@end
#pragma mark - GPBFieldMask
@@ -30,133 +45,212 @@ typedef GPB_ENUM(GPBFieldMask_FieldNumber) {
GPBFieldMask_FieldNumber_PathsArray = 1,
};
-// `FieldMask` represents a set of symbolic field paths, for example:
-//
-// paths: "f.a"
-// paths: "f.b.d"
-//
-// Here `f` represents a field in some root message, `a` and `b`
-// fields in the message found in `f`, and `d` a field found in the
-// message in `f.b`.
-//
-// Field masks are used to specify a subset of fields that should be
-// returned by a get operation or modified by an update operation.
-// Field masks also have a custom JSON encoding (see below).
-//
-// # Field Masks in Projections
-//
-// When used in the context of a projection, a response message or
-// sub-message is filtered by the API to only contain those fields as
-// specified in the mask. For example, if the mask in the previous
-// example is applied to a response message as follows:
-//
-// f {
-// a : 22
-// b {
-// d : 1
-// x : 2
-// }
-// y : 13
-// }
-// z: 8
-//
-// The result will not contain specific values for fields x,y and z
-// (there value will be set to the default, and omitted in proto text
-// output):
-//
-//
-// f {
-// a : 22
-// b {
-// d : 1
-// }
-// }
-//
-// A repeated field is not allowed except at the last position of a
-// field mask.
-//
-// If a FieldMask object is not present in a get operation, the
-// operation applies to all fields (as if a FieldMask of all fields
-// had been specified).
-//
-// Note that a field mask does not necessarily applies to the
-// top-level response message. In case of a REST get operation, the
-// field mask applies directly to the response, but in case of a REST
-// list operation, the mask instead applies to each individual message
-// in the returned resource list. In case of a REST custom method,
-// other definitions may be used. Where the mask applies will be
-// clearly documented together with its declaration in the API. In
-// any case, the effect on the returned resource/resources is required
-// behavior for APIs.
-//
-// # Field Masks in Update Operations
-//
-// A field mask in update operations specifies which fields of the
-// targeted resource are going to be updated. The API is required
-// to only change the values of the fields as specified in the mask
-// and leave the others untouched. If a resource is passed in to
-// describe the updated values, the API ignores the values of all
-// fields not covered by the mask.
-//
-// In order to reset a field's value to the default, the field must
-// be in the mask and set to the default value in the provided resource.
-// Hence, in order to reset all fields of a resource, provide a default
-// instance of the resource and set all fields in the mask, or do
-// not provide a mask as described below.
-//
-// If a field mask is not present on update, the operation applies to
-// all fields (as if a field mask of all fields has been specified).
-// Note that in the presence of schema evolution, this may mean that
-// fields the client does not know and has therefore not filled into
-// the request will be reset to their default. If this is unwanted
-// behavior, a specific service may require a client to always specify
-// a field mask, producing an error if not.
-//
-// As with get operations, the location of the resource which
-// describes the updated values in the request message depends on the
-// operation kind. In any case, the effect of the field mask is
-// required to be honored by the API.
-//
-// ## Considerations for HTTP REST
-//
-// The HTTP kind of an update operation which uses a field mask must
-// be set to PATCH instead of PUT in order to satisfy HTTP semantics
-// (PUT must only be used for full updates).
-//
-// # JSON Encoding of Field Masks
-//
-// In JSON, a field mask is encoded as a single string where paths are
-// separated by a comma. Fields name in each path are converted
-// to/from lower-camel naming conventions.
-//
-// As an example, consider the following message declarations:
-//
-// message Profile {
-// User user = 1;
-// Photo photo = 2;
-// }
-// message User {
-// string display_name = 1;
-// string address = 2;
-// }
-//
-// In proto a field mask for `Profile` may look as such:
-//
-// mask {
-// paths: "user.display_name"
-// paths: "photo"
-// }
-//
-// In JSON, the same mask is represented as below:
-//
-// {
-// mask: "user.displayName,photo"
-// }
+/// `FieldMask` represents a set of symbolic field paths, for example:
+///
+/// paths: "f.a"
+/// paths: "f.b.d"
+///
+/// Here `f` represents a field in some root message, `a` and `b`
+/// fields in the message found in `f`, and `d` a field found in the
+/// message in `f.b`.
+///
+/// Field masks are used to specify a subset of fields that should be
+/// returned by a get operation or modified by an update operation.
+/// Field masks also have a custom JSON encoding (see below).
+///
+/// # Field Masks in Projections
+///
+/// When used in the context of a projection, a response message or
+/// sub-message is filtered by the API to only contain those fields as
+/// specified in the mask. For example, if the mask in the previous
+/// example is applied to a response message as follows:
+///
+/// f {
+/// a : 22
+/// b {
+/// d : 1
+/// x : 2
+/// }
+/// y : 13
+/// }
+/// z: 8
+///
+/// The result will not contain specific values for fields x,y and z
+/// (their value will be set to the default, and omitted in proto text
+/// output):
+///
+///
+/// f {
+/// a : 22
+/// b {
+/// d : 1
+/// }
+/// }
+///
+/// A repeated field is not allowed except at the last position of a
+/// field mask.
+///
+/// If a FieldMask object is not present in a get operation, the
+/// operation applies to all fields (as if a FieldMask of all fields
+/// had been specified).
+///
+/// Note that a field mask does not necessarily apply to the
+/// top-level response message. In case of a REST get operation, the
+/// field mask applies directly to the response, but in case of a REST
+/// list operation, the mask instead applies to each individual message
+/// in the returned resource list. In case of a REST custom method,
+/// other definitions may be used. Where the mask applies will be
+/// clearly documented together with its declaration in the API. In
+/// any case, the effect on the returned resource/resources is required
+/// behavior for APIs.
+///
+/// # Field Masks in Update Operations
+///
+/// A field mask in update operations specifies which fields of the
+/// targeted resource are going to be updated. The API is required
+/// to only change the values of the fields as specified in the mask
+/// and leave the others untouched. If a resource is passed in to
+/// describe the updated values, the API ignores the values of all
+/// fields not covered by the mask.
+///
+/// If a repeated field is specified for an update operation, the existing
+/// repeated values in the target resource will be overwritten by the new values.
+/// Note that a repeated field is only allowed in the last position of a field
+/// mask.
+///
+/// If a sub-message is specified in the last position of the field mask for an
+/// update operation, then the existing sub-message in the target resource is
+/// overwritten. Given the target message:
+///
+/// f {
+/// b {
+/// d : 1
+/// x : 2
+/// }
+/// c : 1
+/// }
+///
+/// And an update message:
+///
+/// f {
+/// b {
+/// d : 10
+/// }
+/// }
+///
+/// then if the field mask is:
+///
+/// paths: "f.b"
+///
+/// then the result will be:
+///
+/// f {
+/// b {
+/// d : 10
+/// }
+/// c : 1
+/// }
+///
+/// However, if the update mask was:
+///
+/// paths: "f.b.d"
+///
+/// then the result would be:
+///
+/// f {
+/// b {
+/// d : 10
+/// x : 2
+/// }
+/// c : 1
+/// }
+///
+/// In order to reset a field's value to the default, the field must
+/// be in the mask and set to the default value in the provided resource.
+/// Hence, in order to reset all fields of a resource, provide a default
+/// instance of the resource and set all fields in the mask, or do
+/// not provide a mask as described below.
+///
+/// If a field mask is not present on update, the operation applies to
+/// all fields (as if a field mask of all fields has been specified).
+/// Note that in the presence of schema evolution, this may mean that
+/// fields the client does not know and has therefore not filled into
+/// the request will be reset to their default. If this is unwanted
+/// behavior, a specific service may require a client to always specify
+/// a field mask, producing an error if not.
+///
+/// As with get operations, the location of the resource which
+/// describes the updated values in the request message depends on the
+/// operation kind. In any case, the effect of the field mask is
+/// required to be honored by the API.
+///
+/// ## Considerations for HTTP REST
+///
+/// The HTTP kind of an update operation which uses a field mask must
+/// be set to PATCH instead of PUT in order to satisfy HTTP semantics
+/// (PUT must only be used for full updates).
+///
+/// # JSON Encoding of Field Masks
+///
+/// In JSON, a field mask is encoded as a single string where paths are
+/// separated by a comma. Fields name in each path are converted
+/// to/from lower-camel naming conventions.
+///
+/// As an example, consider the following message declarations:
+///
+/// message Profile {
+/// User user = 1;
+/// Photo photo = 2;
+/// }
+/// message User {
+/// string display_name = 1;
+/// string address = 2;
+/// }
+///
+/// In proto a field mask for `Profile` may look as such:
+///
+/// mask {
+/// paths: "user.display_name"
+/// paths: "photo"
+/// }
+///
+/// In JSON, the same mask is represented as below:
+///
+/// {
+/// mask: "user.displayName,photo"
+/// }
+///
+/// # Field Masks and Oneof Fields
+///
+/// Field masks treat fields in oneofs just as regular fields. Consider the
+/// following message:
+///
+/// message SampleMessage {
+/// oneof test_oneof {
+/// string name = 4;
+/// SubMessage sub_message = 9;
+/// }
+/// }
+///
+/// The field mask can be:
+///
+/// mask {
+/// paths: "name"
+/// }
+///
+/// Or:
+///
+/// mask {
+/// paths: "sub_message"
+/// }
+///
+/// Note that oneof type names ("test_oneof" in this case) cannot be used in
+/// paths.
@interface GPBFieldMask : GPBMessage
-// The set of field mask paths.
-// |pathsArray| contains |NSString|
-@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *pathsArray;
+/// The set of field mask paths.
+@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<NSString*> *pathsArray;
+/// The number of items in @c pathsArray without causing the array to be created.
@property(nonatomic, readonly) NSUInteger pathsArray_Count;
@end
@@ -165,4 +259,6 @@ NS_ASSUME_NONNULL_END
CF_EXTERN_C_END
+#pragma clang diagnostic pop
+
// @@protoc_insertion_point(global_scope)
diff --git a/objectivec/google/protobuf/FieldMask.pbobjc.m b/objectivec/google/protobuf/FieldMask.pbobjc.m
index f9684f51..2721fdfa 100644
--- a/objectivec/google/protobuf/FieldMask.pbobjc.m
+++ b/objectivec/google/protobuf/FieldMask.pbobjc.m
@@ -1,10 +1,28 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: google/protobuf/field_mask.proto
-#import "GPBProtocolBuffers_RuntimeSupport.h"
-#import "google/protobuf/FieldMask.pbobjc.h"
+// This CPP symbol can be defined to use imports that match up to the framework
+// imports needed when using CocoaPods.
+#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS)
+ #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0
+#endif
+
+#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS
+ #import <Protobuf/GPBProtocolBuffers_RuntimeSupport.h>
+#else
+ #import "GPBProtocolBuffers_RuntimeSupport.h"
+#endif
+
+#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS
+ #import <Protobuf/FieldMask.pbobjc.h>
+#else
+ #import "google/protobuf/FieldMask.pbobjc.h"
+#endif
// @@protoc_insertion_point(imports)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
#pragma mark - GPBFieldMaskRoot
@implementation GPBFieldMaskRoot
@@ -44,14 +62,12 @@ typedef struct GPBFieldMask__storage_ {
static GPBMessageFieldDescription fields[] = {
{
.name = "pathsArray",
+ .dataTypeSpecific.className = NULL,
.number = GPBFieldMask_FieldNumber_PathsArray,
.hasIndex = GPBNoHasBit,
+ .offset = (uint32_t)offsetof(GPBFieldMask__storage_, pathsArray),
.flags = GPBFieldRepeated,
.dataType = GPBDataTypeString,
- .offset = offsetof(GPBFieldMask__storage_, pathsArray),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
},
};
GPBDescriptor *localDescriptor =
@@ -59,15 +75,9 @@ typedef struct GPBFieldMask__storage_ {
rootClass:[GPBFieldMaskRoot class]
file:GPBFieldMaskRoot_FileDescriptor()
fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:NULL
- oneofCount:0
- enums:NULL
- enumCount:0
- ranges:NULL
- rangeCount:0
+ fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBFieldMask__storage_)
- wireFormat:NO];
+ flags:0];
NSAssert(descriptor == nil, @"Startup recursed!");
descriptor = localDescriptor;
}
@@ -77,4 +87,6 @@ typedef struct GPBFieldMask__storage_ {
@end
+#pragma clang diagnostic pop
+
// @@protoc_insertion_point(global_scope)
diff --git a/objectivec/google/protobuf/SourceContext.pbobjc.h b/objectivec/google/protobuf/SourceContext.pbobjc.h
index 8480db1d..4514fa9f 100644
--- a/objectivec/google/protobuf/SourceContext.pbobjc.h
+++ b/objectivec/google/protobuf/SourceContext.pbobjc.h
@@ -1,27 +1,42 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: google/protobuf/source_context.proto
-#import "GPBProtocolBuffers.h"
+// This CPP symbol can be defined to use imports that match up to the framework
+// imports needed when using CocoaPods.
+#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS)
+ #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0
+#endif
+
+#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS
+ #import <Protobuf/GPBProtocolBuffers.h>
+#else
+ #import "GPBProtocolBuffers.h"
+#endif
-#if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30000
+#if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30001
#error This file was generated by a different version of protoc which is incompatible with your Protocol Buffer library sources.
#endif
// @@protoc_insertion_point(imports)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
CF_EXTERN_C_BEGIN
NS_ASSUME_NONNULL_BEGIN
#pragma mark - GPBSourceContextRoot
+/// Exposes the extension registry for this file.
+///
+/// The base class provides:
+/// @code
+/// + (GPBExtensionRegistry *)extensionRegistry;
+/// @endcode
+/// which is a @c GPBExtensionRegistry that includes all the extensions defined by
+/// this file and all files that it depends on.
@interface GPBSourceContextRoot : GPBRootObject
-
-// The base class provides:
-// + (GPBExtensionRegistry *)extensionRegistry;
-// which is an GPBExtensionRegistry that includes all the extensions defined by
-// this file and all files that it depends on.
-
@end
#pragma mark - GPBSourceContext
@@ -30,12 +45,12 @@ typedef GPB_ENUM(GPBSourceContext_FieldNumber) {
GPBSourceContext_FieldNumber_FileName = 1,
};
-// `SourceContext` represents information about the source of a
-// protobuf element, like the file in which it is defined.
+/// `SourceContext` represents information about the source of a
+/// protobuf element, like the file in which it is defined.
@interface GPBSourceContext : GPBMessage
-// The path-qualified name of the .proto file that contained the associated
-// protobuf element. For example: `"google/protobuf/source.proto"`.
+/// The path-qualified name of the .proto file that contained the associated
+/// protobuf element. For example: `"google/protobuf/source_context.proto"`.
@property(nonatomic, readwrite, copy, null_resettable) NSString *fileName;
@end
@@ -44,4 +59,6 @@ NS_ASSUME_NONNULL_END
CF_EXTERN_C_END
+#pragma clang diagnostic pop
+
// @@protoc_insertion_point(global_scope)
diff --git a/objectivec/google/protobuf/SourceContext.pbobjc.m b/objectivec/google/protobuf/SourceContext.pbobjc.m
index ac1827fc..6e3c9c07 100644
--- a/objectivec/google/protobuf/SourceContext.pbobjc.m
+++ b/objectivec/google/protobuf/SourceContext.pbobjc.m
@@ -1,10 +1,28 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: google/protobuf/source_context.proto
-#import "GPBProtocolBuffers_RuntimeSupport.h"
-#import "google/protobuf/SourceContext.pbobjc.h"
+// This CPP symbol can be defined to use imports that match up to the framework
+// imports needed when using CocoaPods.
+#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS)
+ #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0
+#endif
+
+#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS
+ #import <Protobuf/GPBProtocolBuffers_RuntimeSupport.h>
+#else
+ #import "GPBProtocolBuffers_RuntimeSupport.h"
+#endif
+
+#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS
+ #import <Protobuf/SourceContext.pbobjc.h>
+#else
+ #import "google/protobuf/SourceContext.pbobjc.h"
+#endif
// @@protoc_insertion_point(imports)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
#pragma mark - GPBSourceContextRoot
@implementation GPBSourceContextRoot
@@ -44,14 +62,12 @@ typedef struct GPBSourceContext__storage_ {
static GPBMessageFieldDescription fields[] = {
{
.name = "fileName",
+ .dataTypeSpecific.className = NULL,
.number = GPBSourceContext_FieldNumber_FileName,
.hasIndex = 0,
+ .offset = (uint32_t)offsetof(GPBSourceContext__storage_, fileName),
.flags = GPBFieldOptional,
.dataType = GPBDataTypeString,
- .offset = offsetof(GPBSourceContext__storage_, fileName),
- .defaultValue.valueString = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
},
};
GPBDescriptor *localDescriptor =
@@ -59,15 +75,9 @@ typedef struct GPBSourceContext__storage_ {
rootClass:[GPBSourceContextRoot class]
file:GPBSourceContextRoot_FileDescriptor()
fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:NULL
- oneofCount:0
- enums:NULL
- enumCount:0
- ranges:NULL
- rangeCount:0
+ fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBSourceContext__storage_)
- wireFormat:NO];
+ flags:0];
NSAssert(descriptor == nil, @"Startup recursed!");
descriptor = localDescriptor;
}
@@ -77,4 +87,6 @@ typedef struct GPBSourceContext__storage_ {
@end
+#pragma clang diagnostic pop
+
// @@protoc_insertion_point(global_scope)
diff --git a/objectivec/google/protobuf/Struct.pbobjc.h b/objectivec/google/protobuf/Struct.pbobjc.h
index f40414fa..3e2d55fd 100644
--- a/objectivec/google/protobuf/Struct.pbobjc.h
+++ b/objectivec/google/protobuf/Struct.pbobjc.h
@@ -1,46 +1,67 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: google/protobuf/struct.proto
-#import "GPBProtocolBuffers.h"
+// This CPP symbol can be defined to use imports that match up to the framework
+// imports needed when using CocoaPods.
+#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS)
+ #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0
+#endif
+
+#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS
+ #import <Protobuf/GPBProtocolBuffers.h>
+#else
+ #import "GPBProtocolBuffers.h"
+#endif
-#if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30000
+#if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30001
#error This file was generated by a different version of protoc which is incompatible with your Protocol Buffer library sources.
#endif
// @@protoc_insertion_point(imports)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
CF_EXTERN_C_BEGIN
@class GPBListValue;
@class GPBStruct;
+@class GPBValue;
NS_ASSUME_NONNULL_BEGIN
#pragma mark - Enum GPBNullValue
-// `NullValue` is a singleton enumeration to represent the null value for the
-// `Value` type union.
-//
-// The JSON representation for `NullValue` is JSON `null`.
+/// `NullValue` is a singleton enumeration to represent the null value for the
+/// `Value` type union.
+///
+/// The JSON representation for `NullValue` is JSON `null`.
typedef GPB_ENUM(GPBNullValue) {
+ /// Value used if any message's field encounters a value that is not defined
+ /// by this enum. The message will also have C functions to get/set the rawValue
+ /// of the field.
GPBNullValue_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue,
- // Null value.
+ /// Null value.
GPBNullValue_NullValue = 0,
};
GPBEnumDescriptor *GPBNullValue_EnumDescriptor(void);
+/// Checks to see if the given value is defined by the enum or was not known at
+/// the time this source was generated.
BOOL GPBNullValue_IsValidValue(int32_t value);
#pragma mark - GPBStructRoot
+/// Exposes the extension registry for this file.
+///
+/// The base class provides:
+/// @code
+/// + (GPBExtensionRegistry *)extensionRegistry;
+/// @endcode
+/// which is a @c GPBExtensionRegistry that includes all the extensions defined by
+/// this file and all files that it depends on.
@interface GPBStructRoot : GPBRootObject
-
-// The base class provides:
-// + (GPBExtensionRegistry *)extensionRegistry;
-// which is an GPBExtensionRegistry that includes all the extensions defined by
-// this file and all files that it depends on.
-
@end
#pragma mark - GPBStruct
@@ -49,19 +70,19 @@ typedef GPB_ENUM(GPBStruct_FieldNumber) {
GPBStruct_FieldNumber_Fields = 1,
};
-// `Struct` represents a structured data value, consisting of fields
-// which map to dynamically typed values. In some languages, `Struct`
-// might be supported by a native representation. For example, in
-// scripting languages like JS a struct is represented as an
-// object. The details of that representation are described together
-// with the proto support for the language.
-//
-// The JSON representation for `Struct` is JSON object.
+/// `Struct` represents a structured data value, consisting of fields
+/// which map to dynamically typed values. In some languages, `Struct`
+/// might be supported by a native representation. For example, in
+/// scripting languages like JS a struct is represented as an
+/// object. The details of that representation are described together
+/// with the proto support for the language.
+///
+/// The JSON representation for `Struct` is JSON object.
@interface GPBStruct : GPBMessage
-// Map of dynamically typed values.
-// |fields| values are |GPBValue|
-@property(nonatomic, readwrite, strong, null_resettable) NSMutableDictionary *fields;
+/// Unordered map of dynamically typed values.
+@property(nonatomic, readwrite, strong, null_resettable) NSMutableDictionary<NSString*, GPBValue*> *fields;
+/// The number of items in @c fields without causing the array to be created.
@property(nonatomic, readonly) NSUInteger fields_Count;
@end
@@ -87,40 +108,46 @@ typedef GPB_ENUM(GPBValue_Kind_OneOfCase) {
GPBValue_Kind_OneOfCase_ListValue = 6,
};
-// `Value` represents a dynamically typed value which can be either
-// null, a number, a string, a boolean, a recursive struct value, or a
-// list of values. A producer of value is expected to set one of that
-// variants, absence of any variant indicates an error.
-//
-// The JSON representation for `Value` is JSON value.
+/// `Value` represents a dynamically typed value which can be either
+/// null, a number, a string, a boolean, a recursive struct value, or a
+/// list of values. A producer of value is expected to set one of that
+/// variants, absence of any variant indicates an error.
+///
+/// The JSON representation for `Value` is JSON value.
@interface GPBValue : GPBMessage
-// The kind of value.
+/// The kind of value.
@property(nonatomic, readonly) GPBValue_Kind_OneOfCase kindOneOfCase;
-// Represents a null value.
+/// Represents a null value.
@property(nonatomic, readwrite) GPBNullValue nullValue;
-// Represents a double value.
+/// Represents a double value.
@property(nonatomic, readwrite) double numberValue;
-// Represents a string value.
+/// Represents a string value.
@property(nonatomic, readwrite, copy, null_resettable) NSString *stringValue;
-// Represents a boolean value.
+/// Represents a boolean value.
@property(nonatomic, readwrite) BOOL boolValue;
-// Represents a structured value.
+/// Represents a structured value.
@property(nonatomic, readwrite, strong, null_resettable) GPBStruct *structValue;
-// Represents a repeated `Value`.
+/// Represents a repeated `Value`.
@property(nonatomic, readwrite, strong, null_resettable) GPBListValue *listValue;
@end
+/// Fetches the raw value of a @c GPBValue's @c nullValue property, even
+/// if the value was not defined by the enum at the time the code was generated.
int32_t GPBValue_NullValue_RawValue(GPBValue *message);
+/// Sets the raw value of an @c GPBValue's @c nullValue property, allowing
+/// it to be set to a value that was not defined by the enum at the time the code
+/// was generated.
void SetGPBValue_NullValue_RawValue(GPBValue *message, int32_t value);
+/// Clears whatever value was set for the oneof 'kind'.
void GPBValue_ClearKindOneOfCase(GPBValue *message);
#pragma mark - GPBListValue
@@ -129,14 +156,14 @@ typedef GPB_ENUM(GPBListValue_FieldNumber) {
GPBListValue_FieldNumber_ValuesArray = 1,
};
-// `ListValue` is a wrapper around a repeated field of values.
-//
-// The JSON representation for `ListValue` is JSON array.
+/// `ListValue` is a wrapper around a repeated field of values.
+///
+/// The JSON representation for `ListValue` is JSON array.
@interface GPBListValue : GPBMessage
-// Repeated field of dynamically typed values.
-// |valuesArray| contains |GPBValue|
-@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *valuesArray;
+/// Repeated field of dynamically typed values.
+@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBValue*> *valuesArray;
+/// The number of items in @c valuesArray without causing the array to be created.
@property(nonatomic, readonly) NSUInteger valuesArray_Count;
@end
@@ -145,4 +172,6 @@ NS_ASSUME_NONNULL_END
CF_EXTERN_C_END
+#pragma clang diagnostic pop
+
// @@protoc_insertion_point(global_scope)
diff --git a/objectivec/google/protobuf/Struct.pbobjc.m b/objectivec/google/protobuf/Struct.pbobjc.m
index 14b8f271..8ea1f124 100644
--- a/objectivec/google/protobuf/Struct.pbobjc.m
+++ b/objectivec/google/protobuf/Struct.pbobjc.m
@@ -1,10 +1,29 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: google/protobuf/struct.proto
-#import "GPBProtocolBuffers_RuntimeSupport.h"
-#import "google/protobuf/Struct.pbobjc.h"
+// This CPP symbol can be defined to use imports that match up to the framework
+// imports needed when using CocoaPods.
+#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS)
+ #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0
+#endif
+
+#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS
+ #import <Protobuf/GPBProtocolBuffers_RuntimeSupport.h>
+#else
+ #import "GPBProtocolBuffers_RuntimeSupport.h"
+#endif
+
+#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS
+ #import <Protobuf/Struct.pbobjc.h>
+#else
+ #import "google/protobuf/Struct.pbobjc.h"
+#endif
// @@protoc_insertion_point(imports)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+#pragma clang diagnostic ignored "-Wdirect-ivar-access"
+
#pragma mark - GPBStructRoot
@implementation GPBStructRoot
@@ -30,13 +49,20 @@ static GPBFileDescriptor *GPBStructRoot_FileDescriptor(void) {
GPBEnumDescriptor *GPBNullValue_EnumDescriptor(void) {
static GPBEnumDescriptor *descriptor = NULL;
if (!descriptor) {
- static GPBMessageEnumValueDescription values[] = {
- { .name = "NullValue", .number = GPBNullValue_NullValue },
+ static const char *valueNames =
+ "NullValue\000";
+ static const int32_t values[] = {
+ GPBNullValue_NullValue,
};
- descriptor = [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GPBNullValue)
- values:values
- valueCount:sizeof(values) / sizeof(GPBMessageEnumValueDescription)
- enumVerifier:GPBNullValue_IsValidValue];
+ GPBEnumDescriptor *worker =
+ [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GPBNullValue)
+ valueNames:valueNames
+ values:values
+ count:(uint32_t)(sizeof(values) / sizeof(int32_t))
+ enumVerifier:GPBNullValue_IsValidValue];
+ if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) {
+ [worker release];
+ }
}
return descriptor;
}
@@ -69,14 +95,12 @@ typedef struct GPBStruct__storage_ {
static GPBMessageFieldDescription fields[] = {
{
.name = "fields",
+ .dataTypeSpecific.className = GPBStringifySymbol(GPBValue),
.number = GPBStruct_FieldNumber_Fields,
.hasIndex = GPBNoHasBit,
+ .offset = (uint32_t)offsetof(GPBStruct__storage_, fields),
.flags = GPBFieldMapKeyString,
.dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBStruct__storage_, fields),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBValue),
- .fieldOptions = NULL,
},
};
GPBDescriptor *localDescriptor =
@@ -84,15 +108,9 @@ typedef struct GPBStruct__storage_ {
rootClass:[GPBStructRoot class]
file:GPBStructRoot_FileDescriptor()
fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:NULL
- oneofCount:0
- enums:NULL
- enumCount:0
- ranges:NULL
- rangeCount:0
+ fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBStruct__storage_)
- wireFormat:NO];
+ flags:0];
NSAssert(descriptor == nil, @"Startup recursed!");
descriptor = localDescriptor;
}
@@ -115,7 +133,6 @@ typedef struct GPBStruct__storage_ {
typedef struct GPBValue__storage_ {
uint32_t _has_storage_[2];
- BOOL boolValue;
GPBNullValue nullValue;
NSString *stringValue;
GPBStruct *structValue;
@@ -128,78 +145,60 @@ typedef struct GPBValue__storage_ {
+ (GPBDescriptor *)descriptor {
static GPBDescriptor *descriptor = nil;
if (!descriptor) {
- static GPBMessageOneofDescription oneofs[] = {
- {
- .name = "kind",
- .index = -1,
- },
- };
static GPBMessageFieldDescription fields[] = {
{
.name = "nullValue",
+ .dataTypeSpecific.enumDescFunc = GPBNullValue_EnumDescriptor,
.number = GPBValue_FieldNumber_NullValue,
.hasIndex = -1,
+ .offset = (uint32_t)offsetof(GPBValue__storage_, nullValue),
.flags = GPBFieldOptional | GPBFieldHasEnumDescriptor,
.dataType = GPBDataTypeEnum,
- .offset = offsetof(GPBValue__storage_, nullValue),
- .defaultValue.valueEnum = GPBNullValue_NullValue,
- .dataTypeSpecific.enumDescFunc = GPBNullValue_EnumDescriptor,
- .fieldOptions = NULL,
},
{
.name = "numberValue",
+ .dataTypeSpecific.className = NULL,
.number = GPBValue_FieldNumber_NumberValue,
.hasIndex = -1,
+ .offset = (uint32_t)offsetof(GPBValue__storage_, numberValue),
.flags = GPBFieldOptional,
.dataType = GPBDataTypeDouble,
- .offset = offsetof(GPBValue__storage_, numberValue),
- .defaultValue.valueDouble = 0,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
},
{
.name = "stringValue",
+ .dataTypeSpecific.className = NULL,
.number = GPBValue_FieldNumber_StringValue,
.hasIndex = -1,
+ .offset = (uint32_t)offsetof(GPBValue__storage_, stringValue),
.flags = GPBFieldOptional,
.dataType = GPBDataTypeString,
- .offset = offsetof(GPBValue__storage_, stringValue),
- .defaultValue.valueString = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
},
{
.name = "boolValue",
+ .dataTypeSpecific.className = NULL,
.number = GPBValue_FieldNumber_BoolValue,
.hasIndex = -1,
+ .offset = 0, // Stored in _has_storage_ to save space.
.flags = GPBFieldOptional,
.dataType = GPBDataTypeBool,
- .offset = offsetof(GPBValue__storage_, boolValue),
- .defaultValue.valueBool = NO,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
},
{
.name = "structValue",
+ .dataTypeSpecific.className = GPBStringifySymbol(GPBStruct),
.number = GPBValue_FieldNumber_StructValue,
.hasIndex = -1,
+ .offset = (uint32_t)offsetof(GPBValue__storage_, structValue),
.flags = GPBFieldOptional,
.dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBValue__storage_, structValue),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBStruct),
- .fieldOptions = NULL,
},
{
.name = "listValue",
+ .dataTypeSpecific.className = GPBStringifySymbol(GPBListValue),
.number = GPBValue_FieldNumber_ListValue,
.hasIndex = -1,
+ .offset = (uint32_t)offsetof(GPBValue__storage_, listValue),
.flags = GPBFieldOptional,
.dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBValue__storage_, listValue),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBListValue),
- .fieldOptions = NULL,
},
};
GPBDescriptor *localDescriptor =
@@ -207,15 +206,15 @@ typedef struct GPBValue__storage_ {
rootClass:[GPBStructRoot class]
file:GPBStructRoot_FileDescriptor()
fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:oneofs
- oneofCount:sizeof(oneofs) / sizeof(GPBMessageOneofDescription)
- enums:NULL
- enumCount:0
- ranges:NULL
- rangeCount:0
+ fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBValue__storage_)
- wireFormat:NO];
+ flags:0];
+ static const char *oneofs[] = {
+ "kind",
+ };
+ [localDescriptor setupOneofs:oneofs
+ count:(uint32_t)(sizeof(oneofs) / sizeof(char*))
+ firstHasIndex:-1];
NSAssert(descriptor == nil, @"Startup recursed!");
descriptor = localDescriptor;
}
@@ -238,8 +237,8 @@ void SetGPBValue_NullValue_RawValue(GPBValue *message, int32_t value) {
void GPBValue_ClearKindOneOfCase(GPBValue *message) {
GPBDescriptor *descriptor = [message descriptor];
- GPBOneofDescriptor *oneof = descriptor->oneofs_[0];
- GPBMaybeClearOneof(message, oneof, 0);
+ GPBOneofDescriptor *oneof = [descriptor.oneofs objectAtIndex:0];
+ GPBMaybeClearOneof(message, oneof, -1, 0);
}
#pragma mark - GPBListValue
@@ -260,14 +259,12 @@ typedef struct GPBListValue__storage_ {
static GPBMessageFieldDescription fields[] = {
{
.name = "valuesArray",
+ .dataTypeSpecific.className = GPBStringifySymbol(GPBValue),
.number = GPBListValue_FieldNumber_ValuesArray,
.hasIndex = GPBNoHasBit,
+ .offset = (uint32_t)offsetof(GPBListValue__storage_, valuesArray),
.flags = GPBFieldRepeated,
.dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBListValue__storage_, valuesArray),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBValue),
- .fieldOptions = NULL,
},
};
GPBDescriptor *localDescriptor =
@@ -275,15 +272,9 @@ typedef struct GPBListValue__storage_ {
rootClass:[GPBStructRoot class]
file:GPBStructRoot_FileDescriptor()
fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:NULL
- oneofCount:0
- enums:NULL
- enumCount:0
- ranges:NULL
- rangeCount:0
+ fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBListValue__storage_)
- wireFormat:NO];
+ flags:0];
NSAssert(descriptor == nil, @"Startup recursed!");
descriptor = localDescriptor;
}
@@ -293,4 +284,6 @@ typedef struct GPBListValue__storage_ {
@end
+#pragma clang diagnostic pop
+
// @@protoc_insertion_point(global_scope)
diff --git a/objectivec/google/protobuf/Timestamp.pbobjc.h b/objectivec/google/protobuf/Timestamp.pbobjc.h
index 79b24ec6..d15de7c7 100644
--- a/objectivec/google/protobuf/Timestamp.pbobjc.h
+++ b/objectivec/google/protobuf/Timestamp.pbobjc.h
@@ -1,27 +1,42 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: google/protobuf/timestamp.proto
-#import "GPBProtocolBuffers.h"
+// This CPP symbol can be defined to use imports that match up to the framework
+// imports needed when using CocoaPods.
+#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS)
+ #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0
+#endif
+
+#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS
+ #import <Protobuf/GPBProtocolBuffers.h>
+#else
+ #import "GPBProtocolBuffers.h"
+#endif
-#if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30000
+#if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30001
#error This file was generated by a different version of protoc which is incompatible with your Protocol Buffer library sources.
#endif
// @@protoc_insertion_point(imports)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
CF_EXTERN_C_BEGIN
NS_ASSUME_NONNULL_BEGIN
#pragma mark - GPBTimestampRoot
+/// Exposes the extension registry for this file.
+///
+/// The base class provides:
+/// @code
+/// + (GPBExtensionRegistry *)extensionRegistry;
+/// @endcode
+/// which is a @c GPBExtensionRegistry that includes all the extensions defined by
+/// this file and all files that it depends on.
@interface GPBTimestampRoot : GPBRootObject
-
-// The base class provides:
-// + (GPBExtensionRegistry *)extensionRegistry;
-// which is an GPBExtensionRegistry that includes all the extensions defined by
-// this file and all files that it depends on.
-
@end
#pragma mark - GPBTimestamp
@@ -31,70 +46,70 @@ typedef GPB_ENUM(GPBTimestamp_FieldNumber) {
GPBTimestamp_FieldNumber_Nanos = 2,
};
-// A Timestamp represents a point in time independent of any time zone
-// or calendar, represented as seconds and fractions of seconds at
-// nanosecond resolution in UTC Epoch time. It is encoded using the
-// Proleptic Gregorian Calendar which extends the Gregorian calendar
-// backwards to year one. It is encoded assuming all minutes are 60
-// seconds long, i.e. leap seconds are "smeared" so that no leap second
-// table is needed for interpretation. Range is from
-// 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z.
-// By restricting to that range, we ensure that we can convert to
-// and from RFC 3339 date strings.
-// See [https://www.ietf.org/rfc/rfc3339.txt](https://www.ietf.org/rfc/rfc3339.txt).
-//
-// Example 1: Compute Timestamp from POSIX `time()`.
-//
-// Timestamp timestamp;
-// timestamp.set_seconds(time(NULL));
-// timestamp.set_nanos(0);
-//
-// Example 2: Compute Timestamp from POSIX `gettimeofday()`.
-//
-// struct timeval tv;
-// gettimeofday(&tv, NULL);
-//
-// Timestamp timestamp;
-// timestamp.set_seconds(tv.tv_sec);
-// timestamp.set_nanos(tv.tv_usec * 1000);
-//
-// Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`.
-//
-// FILETIME ft;
-// GetSystemTimeAsFileTime(&ft);
-// UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
-//
-// // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z
-// // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z.
-// Timestamp timestamp;
-// timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL));
-// timestamp.set_nanos((INT32) ((ticks % 10000000) * 100));
-//
-// Example 4: Compute Timestamp from Java `System.currentTimeMillis()`.
-//
-// long millis = System.currentTimeMillis();
-//
-// Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000)
-// .setNanos((int) ((millis % 1000) * 1000000)).build();
-//
-//
-// Example 5: Compute Timestamp from current time in Python.
-//
-// now = time.time()
-// seconds = int(now)
-// nanos = int((now - seconds) * 10**9)
-// timestamp = Timestamp(seconds=seconds, nanos=nanos)
+/// A Timestamp represents a point in time independent of any time zone
+/// or calendar, represented as seconds and fractions of seconds at
+/// nanosecond resolution in UTC Epoch time. It is encoded using the
+/// Proleptic Gregorian Calendar which extends the Gregorian calendar
+/// backwards to year one. It is encoded assuming all minutes are 60
+/// seconds long, i.e. leap seconds are "smeared" so that no leap second
+/// table is needed for interpretation. Range is from
+/// 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z.
+/// By restricting to that range, we ensure that we can convert to
+/// and from RFC 3339 date strings.
+/// See [https://www.ietf.org/rfc/rfc3339.txt](https://www.ietf.org/rfc/rfc3339.txt).
+///
+/// Example 1: Compute Timestamp from POSIX `time()`.
+///
+/// Timestamp timestamp;
+/// timestamp.set_seconds(time(NULL));
+/// timestamp.set_nanos(0);
+///
+/// Example 2: Compute Timestamp from POSIX `gettimeofday()`.
+///
+/// struct timeval tv;
+/// gettimeofday(&tv, NULL);
+///
+/// Timestamp timestamp;
+/// timestamp.set_seconds(tv.tv_sec);
+/// timestamp.set_nanos(tv.tv_usec * 1000);
+///
+/// Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`.
+///
+/// FILETIME ft;
+/// GetSystemTimeAsFileTime(&ft);
+/// UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
+///
+/// // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z
+/// // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z.
+/// Timestamp timestamp;
+/// timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL));
+/// timestamp.set_nanos((INT32) ((ticks % 10000000) * 100));
+///
+/// Example 4: Compute Timestamp from Java `System.currentTimeMillis()`.
+///
+/// long millis = System.currentTimeMillis();
+///
+/// Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000)
+/// .setNanos((int) ((millis % 1000) * 1000000)).build();
+///
+///
+/// Example 5: Compute Timestamp from current time in Python.
+///
+/// now = time.time()
+/// seconds = int(now)
+/// nanos = int((now - seconds) * 10**9)
+/// timestamp = Timestamp(seconds=seconds, nanos=nanos)
@interface GPBTimestamp : GPBMessage
-// Represents seconds of UTC time since Unix epoch
-// 1970-01-01T00:00:00Z. Must be from from 0001-01-01T00:00:00Z to
-// 9999-12-31T23:59:59Z inclusive.
+/// Represents seconds of UTC time since Unix epoch
+/// 1970-01-01T00:00:00Z. Must be from from 0001-01-01T00:00:00Z to
+/// 9999-12-31T23:59:59Z inclusive.
@property(nonatomic, readwrite) int64_t seconds;
-// Non-negative fractions of a second at nanosecond resolution. Negative
-// second values with fractions must still have non-negative nanos values
-// that count forward in time. Must be from 0 to 999,999,999
-// inclusive.
+/// Non-negative fractions of a second at nanosecond resolution. Negative
+/// second values with fractions must still have non-negative nanos values
+/// that count forward in time. Must be from 0 to 999,999,999
+/// inclusive.
@property(nonatomic, readwrite) int32_t nanos;
@end
@@ -103,4 +118,6 @@ NS_ASSUME_NONNULL_END
CF_EXTERN_C_END
+#pragma clang diagnostic pop
+
// @@protoc_insertion_point(global_scope)
diff --git a/objectivec/google/protobuf/Timestamp.pbobjc.m b/objectivec/google/protobuf/Timestamp.pbobjc.m
index a206f159..06e3ef94 100644
--- a/objectivec/google/protobuf/Timestamp.pbobjc.m
+++ b/objectivec/google/protobuf/Timestamp.pbobjc.m
@@ -1,10 +1,28 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: google/protobuf/timestamp.proto
-#import "GPBProtocolBuffers_RuntimeSupport.h"
-#import "google/protobuf/Timestamp.pbobjc.h"
+// This CPP symbol can be defined to use imports that match up to the framework
+// imports needed when using CocoaPods.
+#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS)
+ #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0
+#endif
+
+#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS
+ #import <Protobuf/GPBProtocolBuffers_RuntimeSupport.h>
+#else
+ #import "GPBProtocolBuffers_RuntimeSupport.h"
+#endif
+
+#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS
+ #import <Protobuf/Timestamp.pbobjc.h>
+#else
+ #import "google/protobuf/Timestamp.pbobjc.h"
+#endif
// @@protoc_insertion_point(imports)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
#pragma mark - GPBTimestampRoot
@implementation GPBTimestampRoot
@@ -46,25 +64,21 @@ typedef struct GPBTimestamp__storage_ {
static GPBMessageFieldDescription fields[] = {
{
.name = "seconds",
+ .dataTypeSpecific.className = NULL,
.number = GPBTimestamp_FieldNumber_Seconds,
.hasIndex = 0,
+ .offset = (uint32_t)offsetof(GPBTimestamp__storage_, seconds),
.flags = GPBFieldOptional,
.dataType = GPBDataTypeInt64,
- .offset = offsetof(GPBTimestamp__storage_, seconds),
- .defaultValue.valueInt64 = 0LL,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
},
{
.name = "nanos",
+ .dataTypeSpecific.className = NULL,
.number = GPBTimestamp_FieldNumber_Nanos,
.hasIndex = 1,
+ .offset = (uint32_t)offsetof(GPBTimestamp__storage_, nanos),
.flags = GPBFieldOptional,
.dataType = GPBDataTypeInt32,
- .offset = offsetof(GPBTimestamp__storage_, nanos),
- .defaultValue.valueInt32 = 0,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
},
};
GPBDescriptor *localDescriptor =
@@ -72,15 +86,9 @@ typedef struct GPBTimestamp__storage_ {
rootClass:[GPBTimestampRoot class]
file:GPBTimestampRoot_FileDescriptor()
fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:NULL
- oneofCount:0
- enums:NULL
- enumCount:0
- ranges:NULL
- rangeCount:0
+ fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBTimestamp__storage_)
- wireFormat:NO];
+ flags:0];
NSAssert(descriptor == nil, @"Startup recursed!");
descriptor = localDescriptor;
}
@@ -90,4 +98,6 @@ typedef struct GPBTimestamp__storage_ {
@end
+#pragma clang diagnostic pop
+
// @@protoc_insertion_point(global_scope)
diff --git a/objectivec/google/protobuf/Type.pbobjc.h b/objectivec/google/protobuf/Type.pbobjc.h
index 65f1da46..93ee3cec 100644
--- a/objectivec/google/protobuf/Type.pbobjc.h
+++ b/objectivec/google/protobuf/Type.pbobjc.h
@@ -1,136 +1,168 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: google/protobuf/type.proto
-#import "GPBProtocolBuffers.h"
+// This CPP symbol can be defined to use imports that match up to the framework
+// imports needed when using CocoaPods.
+#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS)
+ #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0
+#endif
+
+#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS
+ #import <Protobuf/GPBProtocolBuffers.h>
+#else
+ #import "GPBProtocolBuffers.h"
+#endif
-#if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30000
+#if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30001
#error This file was generated by a different version of protoc which is incompatible with your Protocol Buffer library sources.
#endif
// @@protoc_insertion_point(imports)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
CF_EXTERN_C_BEGIN
@class GPBAny;
+@class GPBEnumValue;
+@class GPBField;
+@class GPBOption;
@class GPBSourceContext;
NS_ASSUME_NONNULL_BEGIN
#pragma mark - Enum GPBSyntax
-// Syntax specifies the syntax in which a service element was defined.
+/// The syntax in which a protocol buffer element is defined.
typedef GPB_ENUM(GPBSyntax) {
+ /// Value used if any message's field encounters a value that is not defined
+ /// by this enum. The message will also have C functions to get/set the rawValue
+ /// of the field.
GPBSyntax_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue,
- // Syntax "proto2"
+ /// Syntax `proto2`.
GPBSyntax_SyntaxProto2 = 0,
- // Syntax "proto3"
+ /// Syntax `proto3`.
GPBSyntax_SyntaxProto3 = 1,
};
GPBEnumDescriptor *GPBSyntax_EnumDescriptor(void);
+/// Checks to see if the given value is defined by the enum or was not known at
+/// the time this source was generated.
BOOL GPBSyntax_IsValidValue(int32_t value);
#pragma mark - Enum GPBField_Kind
-// Kind represents a basic field type.
+/// Basic field types.
typedef GPB_ENUM(GPBField_Kind) {
+ /// Value used if any message's field encounters a value that is not defined
+ /// by this enum. The message will also have C functions to get/set the rawValue
+ /// of the field.
GPBField_Kind_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue,
- // Field type unknown.
+ /// Field type unknown.
GPBField_Kind_TypeUnknown = 0,
- // Field type double.
+ /// Field type double.
GPBField_Kind_TypeDouble = 1,
- // Field type float.
+ /// Field type float.
GPBField_Kind_TypeFloat = 2,
- // Field type int64.
+ /// Field type int64.
GPBField_Kind_TypeInt64 = 3,
- // Field type uint64.
+ /// Field type uint64.
GPBField_Kind_TypeUint64 = 4,
- // Field type int32.
+ /// Field type int32.
GPBField_Kind_TypeInt32 = 5,
- // Field type fixed64.
+ /// Field type fixed64.
GPBField_Kind_TypeFixed64 = 6,
- // Field type fixed32.
+ /// Field type fixed32.
GPBField_Kind_TypeFixed32 = 7,
- // Field type bool.
+ /// Field type bool.
GPBField_Kind_TypeBool = 8,
- // Field type string.
+ /// Field type string.
GPBField_Kind_TypeString = 9,
- // Field type group (deprecated proto2 type)
+ /// Field type group. Proto2 syntax only, and deprecated.
GPBField_Kind_TypeGroup = 10,
- // Field type message.
+ /// Field type message.
GPBField_Kind_TypeMessage = 11,
- // Field type bytes.
+ /// Field type bytes.
GPBField_Kind_TypeBytes = 12,
- // Field type uint32.
+ /// Field type uint32.
GPBField_Kind_TypeUint32 = 13,
- // Field type enum.
+ /// Field type enum.
GPBField_Kind_TypeEnum = 14,
- // Field type sfixed32.
+ /// Field type sfixed32.
GPBField_Kind_TypeSfixed32 = 15,
- // Field type sfixed64.
+ /// Field type sfixed64.
GPBField_Kind_TypeSfixed64 = 16,
- // Field type sint32.
+ /// Field type sint32.
GPBField_Kind_TypeSint32 = 17,
- // Field type sint64.
+ /// Field type sint64.
GPBField_Kind_TypeSint64 = 18,
};
GPBEnumDescriptor *GPBField_Kind_EnumDescriptor(void);
+/// Checks to see if the given value is defined by the enum or was not known at
+/// the time this source was generated.
BOOL GPBField_Kind_IsValidValue(int32_t value);
#pragma mark - Enum GPBField_Cardinality
-// Cardinality represents whether a field is optional, required, or
-// repeated.
+/// Whether a field is optional, required, or repeated.
typedef GPB_ENUM(GPBField_Cardinality) {
+ /// Value used if any message's field encounters a value that is not defined
+ /// by this enum. The message will also have C functions to get/set the rawValue
+ /// of the field.
GPBField_Cardinality_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue,
- // The field cardinality is unknown. Typically an error condition.
+ /// For fields with unknown cardinality.
GPBField_Cardinality_CardinalityUnknown = 0,
- // For optional fields.
+ /// For optional fields.
GPBField_Cardinality_CardinalityOptional = 1,
- // For required fields. Not used for proto3.
+ /// For required fields. Proto2 syntax only.
GPBField_Cardinality_CardinalityRequired = 2,
- // For repeated fields.
+ /// For repeated fields.
GPBField_Cardinality_CardinalityRepeated = 3,
};
GPBEnumDescriptor *GPBField_Cardinality_EnumDescriptor(void);
+/// Checks to see if the given value is defined by the enum or was not known at
+/// the time this source was generated.
BOOL GPBField_Cardinality_IsValidValue(int32_t value);
#pragma mark - GPBTypeRoot
+/// Exposes the extension registry for this file.
+///
+/// The base class provides:
+/// @code
+/// + (GPBExtensionRegistry *)extensionRegistry;
+/// @endcode
+/// which is a @c GPBExtensionRegistry that includes all the extensions defined by
+/// this file and all files that it depends on.
@interface GPBTypeRoot : GPBRootObject
-
-// The base class provides:
-// + (GPBExtensionRegistry *)extensionRegistry;
-// which is an GPBExtensionRegistry that includes all the extensions defined by
-// this file and all files that it depends on.
-
@end
#pragma mark - GPBType
@@ -144,37 +176,43 @@ typedef GPB_ENUM(GPBType_FieldNumber) {
GPBType_FieldNumber_Syntax = 6,
};
-// A light-weight descriptor for a proto message type.
+/// A protocol buffer message type.
@interface GPBType : GPBMessage
-// The fully qualified message name.
+/// The fully qualified message name.
@property(nonatomic, readwrite, copy, null_resettable) NSString *name;
-// The list of fields.
-// |fieldsArray| contains |GPBField|
-@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *fieldsArray;
+/// The list of fields.
+@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBField*> *fieldsArray;
+/// The number of items in @c fieldsArray without causing the array to be created.
@property(nonatomic, readonly) NSUInteger fieldsArray_Count;
-// The list of oneof definitions.
-// |oneofsArray| contains |NSString|
-@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *oneofsArray;
+/// The list of types appearing in `oneof` definitions in this type.
+@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<NSString*> *oneofsArray;
+/// The number of items in @c oneofsArray without causing the array to be created.
@property(nonatomic, readonly) NSUInteger oneofsArray_Count;
-// The proto options.
-// |optionsArray| contains |GPBOption|
-@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *optionsArray;
+/// The protocol buffer options.
+@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBOption*> *optionsArray;
+/// The number of items in @c optionsArray without causing the array to be created.
@property(nonatomic, readonly) NSUInteger optionsArray_Count;
-// The source context.
-@property(nonatomic, readwrite) BOOL hasSourceContext;
+/// The source context.
@property(nonatomic, readwrite, strong, null_resettable) GPBSourceContext *sourceContext;
+/// Test to see if @c sourceContext has been set.
+@property(nonatomic, readwrite) BOOL hasSourceContext;
-// The source syntax.
+/// The source syntax.
@property(nonatomic, readwrite) GPBSyntax syntax;
@end
+/// Fetches the raw value of a @c GPBType's @c syntax property, even
+/// if the value was not defined by the enum at the time the code was generated.
int32_t GPBType_Syntax_RawValue(GPBType *message);
+/// Sets the raw value of an @c GPBType's @c syntax property, allowing
+/// it to be set to a value that was not defined by the enum at the time the code
+/// was generated.
void SetGPBType_Syntax_RawValue(GPBType *message, int32_t value);
#pragma mark - GPBField
@@ -189,47 +227,62 @@ typedef GPB_ENUM(GPBField_FieldNumber) {
GPBField_FieldNumber_Packed = 8,
GPBField_FieldNumber_OptionsArray = 9,
GPBField_FieldNumber_JsonName = 10,
+ GPBField_FieldNumber_DefaultValue = 11,
};
-// Field represents a single field of a message type.
+/// A single field of a message type.
@interface GPBField : GPBMessage
-// The field kind.
+/// The field type.
@property(nonatomic, readwrite) GPBField_Kind kind;
-// The field cardinality, i.e. optional/required/repeated.
+/// The field cardinality.
@property(nonatomic, readwrite) GPBField_Cardinality cardinality;
-// The proto field number.
+/// The field number.
@property(nonatomic, readwrite) int32_t number;
-// The field name.
+/// The field name.
@property(nonatomic, readwrite, copy, null_resettable) NSString *name;
-// The type URL (without the scheme) when the type is MESSAGE or ENUM,
-// such as `type.googleapis.com/google.protobuf.Empty`.
+/// The field type URL, without the scheme, for message or enumeration
+/// types. Example: `"type.googleapis.com/google.protobuf.Timestamp"`.
@property(nonatomic, readwrite, copy, null_resettable) NSString *typeURL;
-// Index in Type.oneofs. Starts at 1. Zero means no oneof mapping.
+/// The index of the field type in `Type.oneofs`, for message or enumeration
+/// types. The first type has index 1; zero means the type is not in the list.
@property(nonatomic, readwrite) int32_t oneofIndex;
-// Whether to use alternative packed wire representation.
+/// Whether to use alternative packed wire representation.
@property(nonatomic, readwrite) BOOL packed;
-// The proto options.
-// |optionsArray| contains |GPBOption|
-@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *optionsArray;
+/// The protocol buffer options.
+@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBOption*> *optionsArray;
+/// The number of items in @c optionsArray without causing the array to be created.
@property(nonatomic, readonly) NSUInteger optionsArray_Count;
-// The JSON name for this field.
+/// The field JSON name.
@property(nonatomic, readwrite, copy, null_resettable) NSString *jsonName;
+/// The string value of the default value of this field. Proto2 syntax only.
+@property(nonatomic, readwrite, copy, null_resettable) NSString *defaultValue;
+
@end
+/// Fetches the raw value of a @c GPBField's @c kind property, even
+/// if the value was not defined by the enum at the time the code was generated.
int32_t GPBField_Kind_RawValue(GPBField *message);
+/// Sets the raw value of an @c GPBField's @c kind property, allowing
+/// it to be set to a value that was not defined by the enum at the time the code
+/// was generated.
void SetGPBField_Kind_RawValue(GPBField *message, int32_t value);
+/// Fetches the raw value of a @c GPBField's @c cardinality property, even
+/// if the value was not defined by the enum at the time the code was generated.
int32_t GPBField_Cardinality_RawValue(GPBField *message);
+/// Sets the raw value of an @c GPBField's @c cardinality property, allowing
+/// it to be set to a value that was not defined by the enum at the time the code
+/// was generated.
void SetGPBField_Cardinality_RawValue(GPBField *message, int32_t value);
#pragma mark - GPBEnum
@@ -242,32 +295,38 @@ typedef GPB_ENUM(GPBEnum_FieldNumber) {
GPBEnum_FieldNumber_Syntax = 5,
};
-// Enum type definition.
+/// Enum type definition.
@interface GPBEnum : GPBMessage
-// Enum type name.
+/// Enum type name.
@property(nonatomic, readwrite, copy, null_resettable) NSString *name;
-// Enum value definitions.
-// |enumvalueArray| contains |GPBEnumValue|
-@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *enumvalueArray;
+/// Enum value definitions.
+@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBEnumValue*> *enumvalueArray;
+/// The number of items in @c enumvalueArray without causing the array to be created.
@property(nonatomic, readonly) NSUInteger enumvalueArray_Count;
-// Proto options for the enum type.
-// |optionsArray| contains |GPBOption|
-@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *optionsArray;
+/// Protocol buffer options.
+@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBOption*> *optionsArray;
+/// The number of items in @c optionsArray without causing the array to be created.
@property(nonatomic, readonly) NSUInteger optionsArray_Count;
-// The source context.
-@property(nonatomic, readwrite) BOOL hasSourceContext;
+/// The source context.
@property(nonatomic, readwrite, strong, null_resettable) GPBSourceContext *sourceContext;
+/// Test to see if @c sourceContext has been set.
+@property(nonatomic, readwrite) BOOL hasSourceContext;
-// The source syntax.
+/// The source syntax.
@property(nonatomic, readwrite) GPBSyntax syntax;
@end
+/// Fetches the raw value of a @c GPBEnum's @c syntax property, even
+/// if the value was not defined by the enum at the time the code was generated.
int32_t GPBEnum_Syntax_RawValue(GPBEnum *message);
+/// Sets the raw value of an @c GPBEnum's @c syntax property, allowing
+/// it to be set to a value that was not defined by the enum at the time the code
+/// was generated.
void SetGPBEnum_Syntax_RawValue(GPBEnum *message, int32_t value);
#pragma mark - GPBEnumValue
@@ -278,18 +337,18 @@ typedef GPB_ENUM(GPBEnumValue_FieldNumber) {
GPBEnumValue_FieldNumber_OptionsArray = 3,
};
-// Enum value definition.
+/// Enum value definition.
@interface GPBEnumValue : GPBMessage
-// Enum value name.
+/// Enum value name.
@property(nonatomic, readwrite, copy, null_resettable) NSString *name;
-// Enum value number.
+/// Enum value number.
@property(nonatomic, readwrite) int32_t number;
-// Proto options for the enum value.
-// |optionsArray| contains |GPBOption|
-@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *optionsArray;
+/// Protocol buffer options.
+@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBOption*> *optionsArray;
+/// The number of items in @c optionsArray without causing the array to be created.
@property(nonatomic, readonly) NSUInteger optionsArray_Count;
@end
@@ -301,15 +360,17 @@ typedef GPB_ENUM(GPBOption_FieldNumber) {
GPBOption_FieldNumber_Value = 2,
};
-// Proto option attached to messages/fields/enums etc.
+/// A protocol buffer option, which can be attached to a message, field,
+/// enumeration, etc.
@interface GPBOption : GPBMessage
-// Proto option name.
+/// The option's name. For example, `"java_package"`.
@property(nonatomic, readwrite, copy, null_resettable) NSString *name;
-// Proto option value.
-@property(nonatomic, readwrite) BOOL hasValue;
+/// The option's value. For example, `"com.google.protobuf"`.
@property(nonatomic, readwrite, strong, null_resettable) GPBAny *value;
+/// Test to see if @c value has been set.
+@property(nonatomic, readwrite) BOOL hasValue;
@end
@@ -317,4 +378,6 @@ NS_ASSUME_NONNULL_END
CF_EXTERN_C_END
+#pragma clang diagnostic pop
+
// @@protoc_insertion_point(global_scope)
diff --git a/objectivec/google/protobuf/Type.pbobjc.m b/objectivec/google/protobuf/Type.pbobjc.m
index 4485e904..6c7b4efd 100644
--- a/objectivec/google/protobuf/Type.pbobjc.m
+++ b/objectivec/google/protobuf/Type.pbobjc.m
@@ -1,12 +1,32 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: google/protobuf/type.proto
-#import "GPBProtocolBuffers_RuntimeSupport.h"
-#import "google/protobuf/Type.pbobjc.h"
-#import "google/protobuf/Any.pbobjc.h"
-#import "google/protobuf/SourceContext.pbobjc.h"
+// This CPP symbol can be defined to use imports that match up to the framework
+// imports needed when using CocoaPods.
+#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS)
+ #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0
+#endif
+
+#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS
+ #import <Protobuf/GPBProtocolBuffers_RuntimeSupport.h>
+#else
+ #import "GPBProtocolBuffers_RuntimeSupport.h"
+#endif
+
+#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS
+ #import <Protobuf/Type.pbobjc.h>
+ #import <Protobuf/Any.pbobjc.h>
+ #import <Protobuf/SourceContext.pbobjc.h>
+#else
+ #import "google/protobuf/Type.pbobjc.h"
+ #import "google/protobuf/Any.pbobjc.h"
+ #import "google/protobuf/SourceContext.pbobjc.h"
+#endif
// @@protoc_insertion_point(imports)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
#pragma mark - GPBTypeRoot
@implementation GPBTypeRoot
@@ -45,14 +65,21 @@ static GPBFileDescriptor *GPBTypeRoot_FileDescriptor(void) {
GPBEnumDescriptor *GPBSyntax_EnumDescriptor(void) {
static GPBEnumDescriptor *descriptor = NULL;
if (!descriptor) {
- static GPBMessageEnumValueDescription values[] = {
- { .name = "SyntaxProto2", .number = GPBSyntax_SyntaxProto2 },
- { .name = "SyntaxProto3", .number = GPBSyntax_SyntaxProto3 },
+ static const char *valueNames =
+ "SyntaxProto2\000SyntaxProto3\000";
+ static const int32_t values[] = {
+ GPBSyntax_SyntaxProto2,
+ GPBSyntax_SyntaxProto3,
};
- descriptor = [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GPBSyntax)
- values:values
- valueCount:sizeof(values) / sizeof(GPBMessageEnumValueDescription)
- enumVerifier:GPBSyntax_IsValidValue];
+ GPBEnumDescriptor *worker =
+ [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GPBSyntax)
+ valueNames:valueNames
+ values:values
+ count:(uint32_t)(sizeof(values) / sizeof(int32_t))
+ enumVerifier:GPBSyntax_IsValidValue];
+ if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) {
+ [worker release];
+ }
}
return descriptor;
}
@@ -96,69 +123,57 @@ typedef struct GPBType__storage_ {
static GPBMessageFieldDescription fields[] = {
{
.name = "name",
+ .dataTypeSpecific.className = NULL,
.number = GPBType_FieldNumber_Name,
.hasIndex = 0,
+ .offset = (uint32_t)offsetof(GPBType__storage_, name),
.flags = GPBFieldOptional,
.dataType = GPBDataTypeString,
- .offset = offsetof(GPBType__storage_, name),
- .defaultValue.valueString = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
},
{
.name = "fieldsArray",
+ .dataTypeSpecific.className = GPBStringifySymbol(GPBField),
.number = GPBType_FieldNumber_FieldsArray,
.hasIndex = GPBNoHasBit,
+ .offset = (uint32_t)offsetof(GPBType__storage_, fieldsArray),
.flags = GPBFieldRepeated,
.dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBType__storage_, fieldsArray),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBField),
- .fieldOptions = NULL,
},
{
.name = "oneofsArray",
+ .dataTypeSpecific.className = NULL,
.number = GPBType_FieldNumber_OneofsArray,
.hasIndex = GPBNoHasBit,
+ .offset = (uint32_t)offsetof(GPBType__storage_, oneofsArray),
.flags = GPBFieldRepeated,
.dataType = GPBDataTypeString,
- .offset = offsetof(GPBType__storage_, oneofsArray),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
},
{
.name = "optionsArray",
+ .dataTypeSpecific.className = GPBStringifySymbol(GPBOption),
.number = GPBType_FieldNumber_OptionsArray,
.hasIndex = GPBNoHasBit,
+ .offset = (uint32_t)offsetof(GPBType__storage_, optionsArray),
.flags = GPBFieldRepeated,
.dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBType__storage_, optionsArray),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBOption),
- .fieldOptions = NULL,
},
{
.name = "sourceContext",
+ .dataTypeSpecific.className = GPBStringifySymbol(GPBSourceContext),
.number = GPBType_FieldNumber_SourceContext,
- .hasIndex = 4,
+ .hasIndex = 1,
+ .offset = (uint32_t)offsetof(GPBType__storage_, sourceContext),
.flags = GPBFieldOptional,
.dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBType__storage_, sourceContext),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBSourceContext),
- .fieldOptions = NULL,
},
{
.name = "syntax",
+ .dataTypeSpecific.enumDescFunc = GPBSyntax_EnumDescriptor,
.number = GPBType_FieldNumber_Syntax,
- .hasIndex = 5,
+ .hasIndex = 2,
+ .offset = (uint32_t)offsetof(GPBType__storage_, syntax),
.flags = GPBFieldOptional | GPBFieldHasEnumDescriptor,
.dataType = GPBDataTypeEnum,
- .offset = offsetof(GPBType__storage_, syntax),
- .defaultValue.valueEnum = GPBSyntax_SyntaxProto2,
- .dataTypeSpecific.enumDescFunc = GPBSyntax_EnumDescriptor,
- .fieldOptions = NULL,
},
};
GPBDescriptor *localDescriptor =
@@ -166,15 +181,9 @@ typedef struct GPBType__storage_ {
rootClass:[GPBTypeRoot class]
file:GPBTypeRoot_FileDescriptor()
fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:NULL
- oneofCount:0
- enums:NULL
- enumCount:0
- ranges:NULL
- rangeCount:0
+ fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBType__storage_)
- wireFormat:NO];
+ flags:0];
NSAssert(descriptor == nil, @"Startup recursed!");
descriptor = localDescriptor;
}
@@ -208,10 +217,10 @@ void SetGPBType_Syntax_RawValue(GPBType *message, int32_t value) {
@dynamic packed;
@dynamic optionsArray, optionsArray_Count;
@dynamic jsonName;
+@dynamic defaultValue;
typedef struct GPBField__storage_ {
uint32_t _has_storage_[1];
- BOOL packed;
GPBField_Kind kind;
GPBField_Cardinality cardinality;
int32_t number;
@@ -220,6 +229,7 @@ typedef struct GPBField__storage_ {
NSString *typeURL;
NSMutableArray *optionsArray;
NSString *jsonName;
+ NSString *defaultValue;
} GPBField__storage_;
// This method is threadsafe because it is initially called
@@ -230,128 +240,108 @@ typedef struct GPBField__storage_ {
static GPBMessageFieldDescription fields[] = {
{
.name = "kind",
+ .dataTypeSpecific.enumDescFunc = GPBField_Kind_EnumDescriptor,
.number = GPBField_FieldNumber_Kind,
.hasIndex = 0,
+ .offset = (uint32_t)offsetof(GPBField__storage_, kind),
.flags = GPBFieldOptional | GPBFieldHasEnumDescriptor,
.dataType = GPBDataTypeEnum,
- .offset = offsetof(GPBField__storage_, kind),
- .defaultValue.valueEnum = GPBField_Kind_TypeUnknown,
- .dataTypeSpecific.enumDescFunc = GPBField_Kind_EnumDescriptor,
- .fieldOptions = NULL,
},
{
.name = "cardinality",
+ .dataTypeSpecific.enumDescFunc = GPBField_Cardinality_EnumDescriptor,
.number = GPBField_FieldNumber_Cardinality,
.hasIndex = 1,
+ .offset = (uint32_t)offsetof(GPBField__storage_, cardinality),
.flags = GPBFieldOptional | GPBFieldHasEnumDescriptor,
.dataType = GPBDataTypeEnum,
- .offset = offsetof(GPBField__storage_, cardinality),
- .defaultValue.valueEnum = GPBField_Cardinality_CardinalityUnknown,
- .dataTypeSpecific.enumDescFunc = GPBField_Cardinality_EnumDescriptor,
- .fieldOptions = NULL,
},
{
.name = "number",
+ .dataTypeSpecific.className = NULL,
.number = GPBField_FieldNumber_Number,
.hasIndex = 2,
+ .offset = (uint32_t)offsetof(GPBField__storage_, number),
.flags = GPBFieldOptional,
.dataType = GPBDataTypeInt32,
- .offset = offsetof(GPBField__storage_, number),
- .defaultValue.valueInt32 = 0,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
},
{
.name = "name",
+ .dataTypeSpecific.className = NULL,
.number = GPBField_FieldNumber_Name,
.hasIndex = 3,
+ .offset = (uint32_t)offsetof(GPBField__storage_, name),
.flags = GPBFieldOptional,
.dataType = GPBDataTypeString,
- .offset = offsetof(GPBField__storage_, name),
- .defaultValue.valueString = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
},
{
.name = "typeURL",
+ .dataTypeSpecific.className = NULL,
.number = GPBField_FieldNumber_TypeURL,
.hasIndex = 4,
+ .offset = (uint32_t)offsetof(GPBField__storage_, typeURL),
.flags = GPBFieldOptional | GPBFieldTextFormatNameCustom,
.dataType = GPBDataTypeString,
- .offset = offsetof(GPBField__storage_, typeURL),
- .defaultValue.valueString = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
},
{
.name = "oneofIndex",
+ .dataTypeSpecific.className = NULL,
.number = GPBField_FieldNumber_OneofIndex,
.hasIndex = 5,
+ .offset = (uint32_t)offsetof(GPBField__storage_, oneofIndex),
.flags = GPBFieldOptional,
.dataType = GPBDataTypeInt32,
- .offset = offsetof(GPBField__storage_, oneofIndex),
- .defaultValue.valueInt32 = 0,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
},
{
.name = "packed",
+ .dataTypeSpecific.className = NULL,
.number = GPBField_FieldNumber_Packed,
.hasIndex = 6,
+ .offset = 7, // Stored in _has_storage_ to save space.
.flags = GPBFieldOptional,
.dataType = GPBDataTypeBool,
- .offset = offsetof(GPBField__storage_, packed),
- .defaultValue.valueBool = NO,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
},
{
.name = "optionsArray",
+ .dataTypeSpecific.className = GPBStringifySymbol(GPBOption),
.number = GPBField_FieldNumber_OptionsArray,
.hasIndex = GPBNoHasBit,
+ .offset = (uint32_t)offsetof(GPBField__storage_, optionsArray),
.flags = GPBFieldRepeated,
.dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBField__storage_, optionsArray),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBOption),
- .fieldOptions = NULL,
},
{
.name = "jsonName",
+ .dataTypeSpecific.className = NULL,
.number = GPBField_FieldNumber_JsonName,
.hasIndex = 8,
+ .offset = (uint32_t)offsetof(GPBField__storage_, jsonName),
.flags = GPBFieldOptional,
.dataType = GPBDataTypeString,
- .offset = offsetof(GPBField__storage_, jsonName),
- .defaultValue.valueString = nil,
+ },
+ {
+ .name = "defaultValue",
.dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
+ .number = GPBField_FieldNumber_DefaultValue,
+ .hasIndex = 9,
+ .offset = (uint32_t)offsetof(GPBField__storage_, defaultValue),
+ .flags = GPBFieldOptional,
+ .dataType = GPBDataTypeString,
},
};
- static GPBMessageEnumDescription enums[] = {
- { .enumDescriptorFunc = GPBField_Kind_EnumDescriptor },
- { .enumDescriptorFunc = GPBField_Cardinality_EnumDescriptor },
- };
-#if GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS
- const char *extraTextFormatInfo = NULL;
-#else
- static const char *extraTextFormatInfo = "\001\006\004\241!!\000";
-#endif // GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS
GPBDescriptor *localDescriptor =
[GPBDescriptor allocDescriptorForClass:[GPBField class]
rootClass:[GPBTypeRoot class]
file:GPBTypeRoot_FileDescriptor()
fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:NULL
- oneofCount:0
- enums:enums
- enumCount:sizeof(enums) / sizeof(GPBMessageEnumDescription)
- ranges:NULL
- rangeCount:0
+ fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBField__storage_)
- wireFormat:NO
- extraTextFormatInfo:extraTextFormatInfo];
+ flags:0];
+#if !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS
+ static const char *extraTextFormatInfo =
+ "\001\006\004\241!!\000";
+ [localDescriptor setupExtraTextInfo:extraTextFormatInfo];
+#endif // !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS
NSAssert(descriptor == nil, @"Startup recursed!");
descriptor = localDescriptor;
}
@@ -389,31 +379,43 @@ void SetGPBField_Cardinality_RawValue(GPBField *message, int32_t value) {
GPBEnumDescriptor *GPBField_Kind_EnumDescriptor(void) {
static GPBEnumDescriptor *descriptor = NULL;
if (!descriptor) {
- static GPBMessageEnumValueDescription values[] = {
- { .name = "TypeUnknown", .number = GPBField_Kind_TypeUnknown },
- { .name = "TypeDouble", .number = GPBField_Kind_TypeDouble },
- { .name = "TypeFloat", .number = GPBField_Kind_TypeFloat },
- { .name = "TypeInt64", .number = GPBField_Kind_TypeInt64 },
- { .name = "TypeUint64", .number = GPBField_Kind_TypeUint64 },
- { .name = "TypeInt32", .number = GPBField_Kind_TypeInt32 },
- { .name = "TypeFixed64", .number = GPBField_Kind_TypeFixed64 },
- { .name = "TypeFixed32", .number = GPBField_Kind_TypeFixed32 },
- { .name = "TypeBool", .number = GPBField_Kind_TypeBool },
- { .name = "TypeString", .number = GPBField_Kind_TypeString },
- { .name = "TypeGroup", .number = GPBField_Kind_TypeGroup },
- { .name = "TypeMessage", .number = GPBField_Kind_TypeMessage },
- { .name = "TypeBytes", .number = GPBField_Kind_TypeBytes },
- { .name = "TypeUint32", .number = GPBField_Kind_TypeUint32 },
- { .name = "TypeEnum", .number = GPBField_Kind_TypeEnum },
- { .name = "TypeSfixed32", .number = GPBField_Kind_TypeSfixed32 },
- { .name = "TypeSfixed64", .number = GPBField_Kind_TypeSfixed64 },
- { .name = "TypeSint32", .number = GPBField_Kind_TypeSint32 },
- { .name = "TypeSint64", .number = GPBField_Kind_TypeSint64 },
+ static const char *valueNames =
+ "TypeUnknown\000TypeDouble\000TypeFloat\000TypeInt"
+ "64\000TypeUint64\000TypeInt32\000TypeFixed64\000Type"
+ "Fixed32\000TypeBool\000TypeString\000TypeGroup\000Ty"
+ "peMessage\000TypeBytes\000TypeUint32\000TypeEnum\000"
+ "TypeSfixed32\000TypeSfixed64\000TypeSint32\000Typ"
+ "eSint64\000";
+ static const int32_t values[] = {
+ GPBField_Kind_TypeUnknown,
+ GPBField_Kind_TypeDouble,
+ GPBField_Kind_TypeFloat,
+ GPBField_Kind_TypeInt64,
+ GPBField_Kind_TypeUint64,
+ GPBField_Kind_TypeInt32,
+ GPBField_Kind_TypeFixed64,
+ GPBField_Kind_TypeFixed32,
+ GPBField_Kind_TypeBool,
+ GPBField_Kind_TypeString,
+ GPBField_Kind_TypeGroup,
+ GPBField_Kind_TypeMessage,
+ GPBField_Kind_TypeBytes,
+ GPBField_Kind_TypeUint32,
+ GPBField_Kind_TypeEnum,
+ GPBField_Kind_TypeSfixed32,
+ GPBField_Kind_TypeSfixed64,
+ GPBField_Kind_TypeSint32,
+ GPBField_Kind_TypeSint64,
};
- descriptor = [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GPBField_Kind)
- values:values
- valueCount:sizeof(values) / sizeof(GPBMessageEnumValueDescription)
- enumVerifier:GPBField_Kind_IsValidValue];
+ GPBEnumDescriptor *worker =
+ [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GPBField_Kind)
+ valueNames:valueNames
+ values:values
+ count:(uint32_t)(sizeof(values) / sizeof(int32_t))
+ enumVerifier:GPBField_Kind_IsValidValue];
+ if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) {
+ [worker release];
+ }
}
return descriptor;
}
@@ -450,16 +452,24 @@ BOOL GPBField_Kind_IsValidValue(int32_t value__) {
GPBEnumDescriptor *GPBField_Cardinality_EnumDescriptor(void) {
static GPBEnumDescriptor *descriptor = NULL;
if (!descriptor) {
- static GPBMessageEnumValueDescription values[] = {
- { .name = "CardinalityUnknown", .number = GPBField_Cardinality_CardinalityUnknown },
- { .name = "CardinalityOptional", .number = GPBField_Cardinality_CardinalityOptional },
- { .name = "CardinalityRequired", .number = GPBField_Cardinality_CardinalityRequired },
- { .name = "CardinalityRepeated", .number = GPBField_Cardinality_CardinalityRepeated },
+ static const char *valueNames =
+ "CardinalityUnknown\000CardinalityOptional\000C"
+ "ardinalityRequired\000CardinalityRepeated\000";
+ static const int32_t values[] = {
+ GPBField_Cardinality_CardinalityUnknown,
+ GPBField_Cardinality_CardinalityOptional,
+ GPBField_Cardinality_CardinalityRequired,
+ GPBField_Cardinality_CardinalityRepeated,
};
- descriptor = [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GPBField_Cardinality)
- values:values
- valueCount:sizeof(values) / sizeof(GPBMessageEnumValueDescription)
- enumVerifier:GPBField_Cardinality_IsValidValue];
+ GPBEnumDescriptor *worker =
+ [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GPBField_Cardinality)
+ valueNames:valueNames
+ values:values
+ count:(uint32_t)(sizeof(values) / sizeof(int32_t))
+ enumVerifier:GPBField_Cardinality_IsValidValue];
+ if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) {
+ [worker release];
+ }
}
return descriptor;
}
@@ -503,58 +513,48 @@ typedef struct GPBEnum__storage_ {
static GPBMessageFieldDescription fields[] = {
{
.name = "name",
+ .dataTypeSpecific.className = NULL,
.number = GPBEnum_FieldNumber_Name,
.hasIndex = 0,
+ .offset = (uint32_t)offsetof(GPBEnum__storage_, name),
.flags = GPBFieldOptional,
.dataType = GPBDataTypeString,
- .offset = offsetof(GPBEnum__storage_, name),
- .defaultValue.valueString = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
},
{
.name = "enumvalueArray",
+ .dataTypeSpecific.className = GPBStringifySymbol(GPBEnumValue),
.number = GPBEnum_FieldNumber_EnumvalueArray,
.hasIndex = GPBNoHasBit,
+ .offset = (uint32_t)offsetof(GPBEnum__storage_, enumvalueArray),
.flags = GPBFieldRepeated,
.dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBEnum__storage_, enumvalueArray),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBEnumValue),
- .fieldOptions = NULL,
},
{
.name = "optionsArray",
+ .dataTypeSpecific.className = GPBStringifySymbol(GPBOption),
.number = GPBEnum_FieldNumber_OptionsArray,
.hasIndex = GPBNoHasBit,
+ .offset = (uint32_t)offsetof(GPBEnum__storage_, optionsArray),
.flags = GPBFieldRepeated,
.dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBEnum__storage_, optionsArray),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBOption),
- .fieldOptions = NULL,
},
{
.name = "sourceContext",
+ .dataTypeSpecific.className = GPBStringifySymbol(GPBSourceContext),
.number = GPBEnum_FieldNumber_SourceContext,
- .hasIndex = 3,
+ .hasIndex = 1,
+ .offset = (uint32_t)offsetof(GPBEnum__storage_, sourceContext),
.flags = GPBFieldOptional,
.dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBEnum__storage_, sourceContext),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBSourceContext),
- .fieldOptions = NULL,
},
{
.name = "syntax",
+ .dataTypeSpecific.enumDescFunc = GPBSyntax_EnumDescriptor,
.number = GPBEnum_FieldNumber_Syntax,
- .hasIndex = 4,
+ .hasIndex = 2,
+ .offset = (uint32_t)offsetof(GPBEnum__storage_, syntax),
.flags = GPBFieldOptional | GPBFieldHasEnumDescriptor,
.dataType = GPBDataTypeEnum,
- .offset = offsetof(GPBEnum__storage_, syntax),
- .defaultValue.valueEnum = GPBSyntax_SyntaxProto2,
- .dataTypeSpecific.enumDescFunc = GPBSyntax_EnumDescriptor,
- .fieldOptions = NULL,
},
};
GPBDescriptor *localDescriptor =
@@ -562,15 +562,9 @@ typedef struct GPBEnum__storage_ {
rootClass:[GPBTypeRoot class]
file:GPBTypeRoot_FileDescriptor()
fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:NULL
- oneofCount:0
- enums:NULL
- enumCount:0
- ranges:NULL
- rangeCount:0
+ fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBEnum__storage_)
- wireFormat:NO];
+ flags:0];
NSAssert(descriptor == nil, @"Startup recursed!");
descriptor = localDescriptor;
}
@@ -614,36 +608,30 @@ typedef struct GPBEnumValue__storage_ {
static GPBMessageFieldDescription fields[] = {
{
.name = "name",
+ .dataTypeSpecific.className = NULL,
.number = GPBEnumValue_FieldNumber_Name,
.hasIndex = 0,
+ .offset = (uint32_t)offsetof(GPBEnumValue__storage_, name),
.flags = GPBFieldOptional,
.dataType = GPBDataTypeString,
- .offset = offsetof(GPBEnumValue__storage_, name),
- .defaultValue.valueString = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
},
{
.name = "number",
+ .dataTypeSpecific.className = NULL,
.number = GPBEnumValue_FieldNumber_Number,
.hasIndex = 1,
+ .offset = (uint32_t)offsetof(GPBEnumValue__storage_, number),
.flags = GPBFieldOptional,
.dataType = GPBDataTypeInt32,
- .offset = offsetof(GPBEnumValue__storage_, number),
- .defaultValue.valueInt32 = 0,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
},
{
.name = "optionsArray",
+ .dataTypeSpecific.className = GPBStringifySymbol(GPBOption),
.number = GPBEnumValue_FieldNumber_OptionsArray,
.hasIndex = GPBNoHasBit,
+ .offset = (uint32_t)offsetof(GPBEnumValue__storage_, optionsArray),
.flags = GPBFieldRepeated,
.dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBEnumValue__storage_, optionsArray),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBOption),
- .fieldOptions = NULL,
},
};
GPBDescriptor *localDescriptor =
@@ -651,15 +639,9 @@ typedef struct GPBEnumValue__storage_ {
rootClass:[GPBTypeRoot class]
file:GPBTypeRoot_FileDescriptor()
fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:NULL
- oneofCount:0
- enums:NULL
- enumCount:0
- ranges:NULL
- rangeCount:0
+ fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBEnumValue__storage_)
- wireFormat:NO];
+ flags:0];
NSAssert(descriptor == nil, @"Startup recursed!");
descriptor = localDescriptor;
}
@@ -689,25 +671,21 @@ typedef struct GPBOption__storage_ {
static GPBMessageFieldDescription fields[] = {
{
.name = "name",
+ .dataTypeSpecific.className = NULL,
.number = GPBOption_FieldNumber_Name,
.hasIndex = 0,
+ .offset = (uint32_t)offsetof(GPBOption__storage_, name),
.flags = GPBFieldOptional,
.dataType = GPBDataTypeString,
- .offset = offsetof(GPBOption__storage_, name),
- .defaultValue.valueString = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
},
{
.name = "value",
+ .dataTypeSpecific.className = GPBStringifySymbol(GPBAny),
.number = GPBOption_FieldNumber_Value,
.hasIndex = 1,
+ .offset = (uint32_t)offsetof(GPBOption__storage_, value),
.flags = GPBFieldOptional,
.dataType = GPBDataTypeMessage,
- .offset = offsetof(GPBOption__storage_, value),
- .defaultValue.valueMessage = nil,
- .dataTypeSpecific.className = GPBStringifySymbol(GPBAny),
- .fieldOptions = NULL,
},
};
GPBDescriptor *localDescriptor =
@@ -715,15 +693,9 @@ typedef struct GPBOption__storage_ {
rootClass:[GPBTypeRoot class]
file:GPBTypeRoot_FileDescriptor()
fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:NULL
- oneofCount:0
- enums:NULL
- enumCount:0
- ranges:NULL
- rangeCount:0
+ fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBOption__storage_)
- wireFormat:NO];
+ flags:0];
NSAssert(descriptor == nil, @"Startup recursed!");
descriptor = localDescriptor;
}
@@ -733,4 +705,6 @@ typedef struct GPBOption__storage_ {
@end
+#pragma clang diagnostic pop
+
// @@protoc_insertion_point(global_scope)
diff --git a/objectivec/google/protobuf/Wrappers.pbobjc.h b/objectivec/google/protobuf/Wrappers.pbobjc.h
index 580945c4..5593d348 100644
--- a/objectivec/google/protobuf/Wrappers.pbobjc.h
+++ b/objectivec/google/protobuf/Wrappers.pbobjc.h
@@ -1,27 +1,42 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: google/protobuf/wrappers.proto
-#import "GPBProtocolBuffers.h"
+// This CPP symbol can be defined to use imports that match up to the framework
+// imports needed when using CocoaPods.
+#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS)
+ #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0
+#endif
+
+#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS
+ #import <Protobuf/GPBProtocolBuffers.h>
+#else
+ #import "GPBProtocolBuffers.h"
+#endif
-#if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30000
+#if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30001
#error This file was generated by a different version of protoc which is incompatible with your Protocol Buffer library sources.
#endif
// @@protoc_insertion_point(imports)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
CF_EXTERN_C_BEGIN
NS_ASSUME_NONNULL_BEGIN
#pragma mark - GPBWrappersRoot
+/// Exposes the extension registry for this file.
+///
+/// The base class provides:
+/// @code
+/// + (GPBExtensionRegistry *)extensionRegistry;
+/// @endcode
+/// which is a @c GPBExtensionRegistry that includes all the extensions defined by
+/// this file and all files that it depends on.
@interface GPBWrappersRoot : GPBRootObject
-
-// The base class provides:
-// + (GPBExtensionRegistry *)extensionRegistry;
-// which is an GPBExtensionRegistry that includes all the extensions defined by
-// this file and all files that it depends on.
-
@end
#pragma mark - GPBDoubleValue
@@ -30,12 +45,12 @@ typedef GPB_ENUM(GPBDoubleValue_FieldNumber) {
GPBDoubleValue_FieldNumber_Value = 1,
};
-// Wrapper message for `double`.
-//
-// The JSON representation for `DoubleValue` is JSON number.
+/// Wrapper message for `double`.
+///
+/// The JSON representation for `DoubleValue` is JSON number.
@interface GPBDoubleValue : GPBMessage
-// The double value.
+/// The double value.
@property(nonatomic, readwrite) double value;
@end
@@ -46,12 +61,12 @@ typedef GPB_ENUM(GPBFloatValue_FieldNumber) {
GPBFloatValue_FieldNumber_Value = 1,
};
-// Wrapper message for `float`.
-//
-// The JSON representation for `FloatValue` is JSON number.
+/// Wrapper message for `float`.
+///
+/// The JSON representation for `FloatValue` is JSON number.
@interface GPBFloatValue : GPBMessage
-// The float value.
+/// The float value.
@property(nonatomic, readwrite) float value;
@end
@@ -62,12 +77,12 @@ typedef GPB_ENUM(GPBInt64Value_FieldNumber) {
GPBInt64Value_FieldNumber_Value = 1,
};
-// Wrapper message for `int64`.
-//
-// The JSON representation for `Int64Value` is JSON string.
+/// Wrapper message for `int64`.
+///
+/// The JSON representation for `Int64Value` is JSON string.
@interface GPBInt64Value : GPBMessage
-// The int64 value.
+/// The int64 value.
@property(nonatomic, readwrite) int64_t value;
@end
@@ -78,12 +93,12 @@ typedef GPB_ENUM(GPBUInt64Value_FieldNumber) {
GPBUInt64Value_FieldNumber_Value = 1,
};
-// Wrapper message for `uint64`.
-//
-// The JSON representation for `UInt64Value` is JSON string.
+/// Wrapper message for `uint64`.
+///
+/// The JSON representation for `UInt64Value` is JSON string.
@interface GPBUInt64Value : GPBMessage
-// The uint64 value.
+/// The uint64 value.
@property(nonatomic, readwrite) uint64_t value;
@end
@@ -94,12 +109,12 @@ typedef GPB_ENUM(GPBInt32Value_FieldNumber) {
GPBInt32Value_FieldNumber_Value = 1,
};
-// Wrapper message for `int32`.
-//
-// The JSON representation for `Int32Value` is JSON number.
+/// Wrapper message for `int32`.
+///
+/// The JSON representation for `Int32Value` is JSON number.
@interface GPBInt32Value : GPBMessage
-// The int32 value.
+/// The int32 value.
@property(nonatomic, readwrite) int32_t value;
@end
@@ -110,12 +125,12 @@ typedef GPB_ENUM(GPBUInt32Value_FieldNumber) {
GPBUInt32Value_FieldNumber_Value = 1,
};
-// Wrapper message for `uint32`.
-//
-// The JSON representation for `UInt32Value` is JSON number.
+/// Wrapper message for `uint32`.
+///
+/// The JSON representation for `UInt32Value` is JSON number.
@interface GPBUInt32Value : GPBMessage
-// The uint32 value.
+/// The uint32 value.
@property(nonatomic, readwrite) uint32_t value;
@end
@@ -126,12 +141,12 @@ typedef GPB_ENUM(GPBBoolValue_FieldNumber) {
GPBBoolValue_FieldNumber_Value = 1,
};
-// Wrapper message for `bool`.
-//
-// The JSON representation for `BoolValue` is JSON `true` and `false`.
+/// Wrapper message for `bool`.
+///
+/// The JSON representation for `BoolValue` is JSON `true` and `false`.
@interface GPBBoolValue : GPBMessage
-// The bool value.
+/// The bool value.
@property(nonatomic, readwrite) BOOL value;
@end
@@ -142,12 +157,12 @@ typedef GPB_ENUM(GPBStringValue_FieldNumber) {
GPBStringValue_FieldNumber_Value = 1,
};
-// Wrapper message for `string`.
-//
-// The JSON representation for `StringValue` is JSON string.
+/// Wrapper message for `string`.
+///
+/// The JSON representation for `StringValue` is JSON string.
@interface GPBStringValue : GPBMessage
-// The string value.
+/// The string value.
@property(nonatomic, readwrite, copy, null_resettable) NSString *value;
@end
@@ -158,12 +173,12 @@ typedef GPB_ENUM(GPBBytesValue_FieldNumber) {
GPBBytesValue_FieldNumber_Value = 1,
};
-// Wrapper message for `bytes`.
-//
-// The JSON representation for `BytesValue` is JSON string.
+/// Wrapper message for `bytes`.
+///
+/// The JSON representation for `BytesValue` is JSON string.
@interface GPBBytesValue : GPBMessage
-// The bytes value.
+/// The bytes value.
@property(nonatomic, readwrite, copy, null_resettable) NSData *value;
@end
@@ -172,4 +187,6 @@ NS_ASSUME_NONNULL_END
CF_EXTERN_C_END
+#pragma clang diagnostic pop
+
// @@protoc_insertion_point(global_scope)
diff --git a/objectivec/google/protobuf/Wrappers.pbobjc.m b/objectivec/google/protobuf/Wrappers.pbobjc.m
index 0403b464..b5405a7d 100644
--- a/objectivec/google/protobuf/Wrappers.pbobjc.m
+++ b/objectivec/google/protobuf/Wrappers.pbobjc.m
@@ -1,10 +1,28 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: google/protobuf/wrappers.proto
-#import "GPBProtocolBuffers_RuntimeSupport.h"
-#import "google/protobuf/Wrappers.pbobjc.h"
+// This CPP symbol can be defined to use imports that match up to the framework
+// imports needed when using CocoaPods.
+#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS)
+ #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0
+#endif
+
+#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS
+ #import <Protobuf/GPBProtocolBuffers_RuntimeSupport.h>
+#else
+ #import "GPBProtocolBuffers_RuntimeSupport.h"
+#endif
+
+#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS
+ #import <Protobuf/Wrappers.pbobjc.h>
+#else
+ #import "google/protobuf/Wrappers.pbobjc.h"
+#endif
// @@protoc_insertion_point(imports)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+
#pragma mark - GPBWrappersRoot
@implementation GPBWrappersRoot
@@ -44,14 +62,12 @@ typedef struct GPBDoubleValue__storage_ {
static GPBMessageFieldDescription fields[] = {
{
.name = "value",
+ .dataTypeSpecific.className = NULL,
.number = GPBDoubleValue_FieldNumber_Value,
.hasIndex = 0,
+ .offset = (uint32_t)offsetof(GPBDoubleValue__storage_, value),
.flags = GPBFieldOptional,
.dataType = GPBDataTypeDouble,
- .offset = offsetof(GPBDoubleValue__storage_, value),
- .defaultValue.valueDouble = 0,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
},
};
GPBDescriptor *localDescriptor =
@@ -59,15 +75,9 @@ typedef struct GPBDoubleValue__storage_ {
rootClass:[GPBWrappersRoot class]
file:GPBWrappersRoot_FileDescriptor()
fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:NULL
- oneofCount:0
- enums:NULL
- enumCount:0
- ranges:NULL
- rangeCount:0
+ fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBDoubleValue__storage_)
- wireFormat:NO];
+ flags:0];
NSAssert(descriptor == nil, @"Startup recursed!");
descriptor = localDescriptor;
}
@@ -95,14 +105,12 @@ typedef struct GPBFloatValue__storage_ {
static GPBMessageFieldDescription fields[] = {
{
.name = "value",
+ .dataTypeSpecific.className = NULL,
.number = GPBFloatValue_FieldNumber_Value,
.hasIndex = 0,
+ .offset = (uint32_t)offsetof(GPBFloatValue__storage_, value),
.flags = GPBFieldOptional,
.dataType = GPBDataTypeFloat,
- .offset = offsetof(GPBFloatValue__storage_, value),
- .defaultValue.valueFloat = 0,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
},
};
GPBDescriptor *localDescriptor =
@@ -110,15 +118,9 @@ typedef struct GPBFloatValue__storage_ {
rootClass:[GPBWrappersRoot class]
file:GPBWrappersRoot_FileDescriptor()
fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:NULL
- oneofCount:0
- enums:NULL
- enumCount:0
- ranges:NULL
- rangeCount:0
+ fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBFloatValue__storage_)
- wireFormat:NO];
+ flags:0];
NSAssert(descriptor == nil, @"Startup recursed!");
descriptor = localDescriptor;
}
@@ -146,14 +148,12 @@ typedef struct GPBInt64Value__storage_ {
static GPBMessageFieldDescription fields[] = {
{
.name = "value",
+ .dataTypeSpecific.className = NULL,
.number = GPBInt64Value_FieldNumber_Value,
.hasIndex = 0,
+ .offset = (uint32_t)offsetof(GPBInt64Value__storage_, value),
.flags = GPBFieldOptional,
.dataType = GPBDataTypeInt64,
- .offset = offsetof(GPBInt64Value__storage_, value),
- .defaultValue.valueInt64 = 0LL,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
},
};
GPBDescriptor *localDescriptor =
@@ -161,15 +161,9 @@ typedef struct GPBInt64Value__storage_ {
rootClass:[GPBWrappersRoot class]
file:GPBWrappersRoot_FileDescriptor()
fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:NULL
- oneofCount:0
- enums:NULL
- enumCount:0
- ranges:NULL
- rangeCount:0
+ fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBInt64Value__storage_)
- wireFormat:NO];
+ flags:0];
NSAssert(descriptor == nil, @"Startup recursed!");
descriptor = localDescriptor;
}
@@ -197,14 +191,12 @@ typedef struct GPBUInt64Value__storage_ {
static GPBMessageFieldDescription fields[] = {
{
.name = "value",
+ .dataTypeSpecific.className = NULL,
.number = GPBUInt64Value_FieldNumber_Value,
.hasIndex = 0,
+ .offset = (uint32_t)offsetof(GPBUInt64Value__storage_, value),
.flags = GPBFieldOptional,
.dataType = GPBDataTypeUInt64,
- .offset = offsetof(GPBUInt64Value__storage_, value),
- .defaultValue.valueUInt64 = 0ULL,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
},
};
GPBDescriptor *localDescriptor =
@@ -212,15 +204,9 @@ typedef struct GPBUInt64Value__storage_ {
rootClass:[GPBWrappersRoot class]
file:GPBWrappersRoot_FileDescriptor()
fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:NULL
- oneofCount:0
- enums:NULL
- enumCount:0
- ranges:NULL
- rangeCount:0
+ fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBUInt64Value__storage_)
- wireFormat:NO];
+ flags:0];
NSAssert(descriptor == nil, @"Startup recursed!");
descriptor = localDescriptor;
}
@@ -248,14 +234,12 @@ typedef struct GPBInt32Value__storage_ {
static GPBMessageFieldDescription fields[] = {
{
.name = "value",
+ .dataTypeSpecific.className = NULL,
.number = GPBInt32Value_FieldNumber_Value,
.hasIndex = 0,
+ .offset = (uint32_t)offsetof(GPBInt32Value__storage_, value),
.flags = GPBFieldOptional,
.dataType = GPBDataTypeInt32,
- .offset = offsetof(GPBInt32Value__storage_, value),
- .defaultValue.valueInt32 = 0,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
},
};
GPBDescriptor *localDescriptor =
@@ -263,15 +247,9 @@ typedef struct GPBInt32Value__storage_ {
rootClass:[GPBWrappersRoot class]
file:GPBWrappersRoot_FileDescriptor()
fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:NULL
- oneofCount:0
- enums:NULL
- enumCount:0
- ranges:NULL
- rangeCount:0
+ fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBInt32Value__storage_)
- wireFormat:NO];
+ flags:0];
NSAssert(descriptor == nil, @"Startup recursed!");
descriptor = localDescriptor;
}
@@ -299,14 +277,12 @@ typedef struct GPBUInt32Value__storage_ {
static GPBMessageFieldDescription fields[] = {
{
.name = "value",
+ .dataTypeSpecific.className = NULL,
.number = GPBUInt32Value_FieldNumber_Value,
.hasIndex = 0,
+ .offset = (uint32_t)offsetof(GPBUInt32Value__storage_, value),
.flags = GPBFieldOptional,
.dataType = GPBDataTypeUInt32,
- .offset = offsetof(GPBUInt32Value__storage_, value),
- .defaultValue.valueUInt32 = 0U,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
},
};
GPBDescriptor *localDescriptor =
@@ -314,15 +290,9 @@ typedef struct GPBUInt32Value__storage_ {
rootClass:[GPBWrappersRoot class]
file:GPBWrappersRoot_FileDescriptor()
fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:NULL
- oneofCount:0
- enums:NULL
- enumCount:0
- ranges:NULL
- rangeCount:0
+ fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBUInt32Value__storage_)
- wireFormat:NO];
+ flags:0];
NSAssert(descriptor == nil, @"Startup recursed!");
descriptor = localDescriptor;
}
@@ -339,7 +309,6 @@ typedef struct GPBUInt32Value__storage_ {
typedef struct GPBBoolValue__storage_ {
uint32_t _has_storage_[1];
- BOOL value;
} GPBBoolValue__storage_;
// This method is threadsafe because it is initially called
@@ -350,14 +319,12 @@ typedef struct GPBBoolValue__storage_ {
static GPBMessageFieldDescription fields[] = {
{
.name = "value",
+ .dataTypeSpecific.className = NULL,
.number = GPBBoolValue_FieldNumber_Value,
.hasIndex = 0,
+ .offset = 1, // Stored in _has_storage_ to save space.
.flags = GPBFieldOptional,
.dataType = GPBDataTypeBool,
- .offset = offsetof(GPBBoolValue__storage_, value),
- .defaultValue.valueBool = NO,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
},
};
GPBDescriptor *localDescriptor =
@@ -365,15 +332,9 @@ typedef struct GPBBoolValue__storage_ {
rootClass:[GPBWrappersRoot class]
file:GPBWrappersRoot_FileDescriptor()
fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:NULL
- oneofCount:0
- enums:NULL
- enumCount:0
- ranges:NULL
- rangeCount:0
+ fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBBoolValue__storage_)
- wireFormat:NO];
+ flags:0];
NSAssert(descriptor == nil, @"Startup recursed!");
descriptor = localDescriptor;
}
@@ -401,14 +362,12 @@ typedef struct GPBStringValue__storage_ {
static GPBMessageFieldDescription fields[] = {
{
.name = "value",
+ .dataTypeSpecific.className = NULL,
.number = GPBStringValue_FieldNumber_Value,
.hasIndex = 0,
+ .offset = (uint32_t)offsetof(GPBStringValue__storage_, value),
.flags = GPBFieldOptional,
.dataType = GPBDataTypeString,
- .offset = offsetof(GPBStringValue__storage_, value),
- .defaultValue.valueString = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
},
};
GPBDescriptor *localDescriptor =
@@ -416,15 +375,9 @@ typedef struct GPBStringValue__storage_ {
rootClass:[GPBWrappersRoot class]
file:GPBWrappersRoot_FileDescriptor()
fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:NULL
- oneofCount:0
- enums:NULL
- enumCount:0
- ranges:NULL
- rangeCount:0
+ fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBStringValue__storage_)
- wireFormat:NO];
+ flags:0];
NSAssert(descriptor == nil, @"Startup recursed!");
descriptor = localDescriptor;
}
@@ -452,14 +405,12 @@ typedef struct GPBBytesValue__storage_ {
static GPBMessageFieldDescription fields[] = {
{
.name = "value",
+ .dataTypeSpecific.className = NULL,
.number = GPBBytesValue_FieldNumber_Value,
.hasIndex = 0,
+ .offset = (uint32_t)offsetof(GPBBytesValue__storage_, value),
.flags = GPBFieldOptional,
.dataType = GPBDataTypeBytes,
- .offset = offsetof(GPBBytesValue__storage_, value),
- .defaultValue.valueData = nil,
- .dataTypeSpecific.className = NULL,
- .fieldOptions = NULL,
},
};
GPBDescriptor *localDescriptor =
@@ -467,15 +418,9 @@ typedef struct GPBBytesValue__storage_ {
rootClass:[GPBWrappersRoot class]
file:GPBWrappersRoot_FileDescriptor()
fields:fields
- fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
- oneofs:NULL
- oneofCount:0
- enums:NULL
- enumCount:0
- ranges:NULL
- rangeCount:0
+ fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(GPBBytesValue__storage_)
- wireFormat:NO];
+ flags:0];
NSAssert(descriptor == nil, @"Startup recursed!");
descriptor = localDescriptor;
}
@@ -485,4 +430,6 @@ typedef struct GPBBytesValue__storage_ {
@end
+#pragma clang diagnostic pop
+
// @@protoc_insertion_point(global_scope)
diff --git a/php/ext/google/protobuf/config.m4 b/php/ext/google/protobuf/config.m4
new file mode 100644
index 00000000..b5946f74
--- /dev/null
+++ b/php/ext/google/protobuf/config.m4
@@ -0,0 +1,10 @@
+dnl lines starting with "dnl" are comments
+
+PHP_ARG_ENABLE(protobuf, whether to enable Protobuf extension, [ --enable-protobuf Enable Protobuf extension])
+
+if test "$PHP_PROTOBUF" != "no"; then
+
+ dnl this defines the extension
+ PHP_NEW_EXTENSION(protobuf, upb.c protobuf.c def.c message.c storage.c, $ext_shared)
+
+fi
diff --git a/php/ext/google/protobuf/def.c b/php/ext/google/protobuf/def.c
new file mode 100644
index 00000000..fc188069
--- /dev/null
+++ b/php/ext/google/protobuf/def.c
@@ -0,0 +1,381 @@
+#include "protobuf.h"
+
+// -----------------------------------------------------------------------------
+// Common Utilities
+// -----------------------------------------------------------------------------
+
+void check_upb_status(const upb_status* status, const char* msg) {
+ if (!upb_ok(status)) {
+ zend_error("%s: %s\n", msg, upb_status_errmsg(status));
+ }
+}
+
+
+static upb_def *check_notfrozen(const upb_def *def) {
+ if (upb_def_isfrozen(def)) {
+ zend_error(E_ERROR,
+ "Attempt to modify a frozen descriptor. Once descriptors are "
+ "added to the descriptor pool, they may not be modified.");
+ }
+ return (upb_def *)def;
+}
+
+static upb_msgdef *check_msgdef_notfrozen(const upb_msgdef *def) {
+ return upb_downcast_msgdef_mutable(check_notfrozen((const upb_def *)def));
+}
+
+static upb_fielddef *check_fielddef_notfrozen(const upb_fielddef *def) {
+ return upb_downcast_fielddef_mutable(check_notfrozen((const upb_def *)def));
+}
+
+#define PROTOBUF_WRAP_INTERN(wrapper, intern, intern_dtor) \
+ Z_TYPE_P(wrapper) = IS_OBJECT; \
+ Z_OBJVAL_P(wrapper) \
+ .handle = zend_objects_store_put( \
+ intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, \
+ intern_dtor, NULL TSRMLS_CC); \
+ Z_OBJVAL_P(wrapper).handlers = zend_get_std_object_handlers();
+
+#define PROTOBUF_SETUP_ZEND_WRAPPER(class_name, class_name_lower, wrapper, \
+ intern) \
+ Z_TYPE_P(wrapper) = IS_OBJECT; \
+ class_name *intern = ALLOC(class_name); \
+ memset(intern, 0, sizeof(class_name)); \
+ class_name_lower##_init_c_instance(intern TSRMLS_CC); \
+ Z_OBJVAL_P(wrapper) \
+ .handle = zend_objects_store_put(intern, NULL, class_name_lower##_free, \
+ NULL TSRMLS_CC); \
+ Z_OBJVAL_P(wrapper).handlers = zend_get_std_object_handlers();
+
+#define PROTOBUF_CREATE_ZEND_WRAPPER(class_name, class_name_lower, wrapper, \
+ intern) \
+ MAKE_STD_ZVAL(wrapper); \
+ PROTOBUF_SETUP_ZEND_WRAPPER(class_name, class_name_lower, wrapper, intern);
+
+#define DEFINE_CLASS(name, name_lower, string_name) \
+ zend_class_entry *name_lower##_type; \
+ void name_lower##_init(TSRMLS_D) { \
+ zend_class_entry class_type; \
+ INIT_CLASS_ENTRY(class_type, string_name, name_lower##_methods); \
+ name_lower##_type = zend_register_internal_class(&class_type TSRMLS_CC); \
+ name_lower##_type->create_object = name_lower##_create; \
+ } \
+ name *php_to_##name_lower(zval *val TSRMLS_DC) { \
+ return (name *)zend_object_store_get_object(val TSRMLS_CC); \
+ } \
+ void name_lower##_free(void *object TSRMLS_DC) { \
+ name *intern = (name *)object; \
+ name_lower##_free_c(intern TSRMLS_CC); \
+ efree(object); \
+ } \
+ zend_object_value name_lower##_create(zend_class_entry *ce TSRMLS_DC) { \
+ zend_object_value return_value; \
+ name *intern = (name *)emalloc(sizeof(name)); \
+ memset(intern, 0, sizeof(name)); \
+ name_lower##_init_c_instance(intern TSRMLS_CC); \
+ return_value.handle = zend_objects_store_put( \
+ intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, \
+ name_lower##_free, NULL TSRMLS_CC); \
+ return_value.handlers = zend_get_std_object_handlers(); \
+ return return_value; \
+ }
+
+// -----------------------------------------------------------------------------
+// DescriptorPool
+// -----------------------------------------------------------------------------
+
+static zend_function_entry descriptor_pool_methods[] = {
+ PHP_ME(DescriptorPool, addMessage, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(DescriptorPool, finalize, NULL, ZEND_ACC_PUBLIC)
+ ZEND_FE_END
+};
+
+DEFINE_CLASS(DescriptorPool, descriptor_pool,
+ "Google\\Protobuf\\DescriptorPool");
+
+DescriptorPool *generated_pool; // The actual generated pool
+
+ZEND_FUNCTION(get_generated_pool) {
+ if (PROTOBUF_G(generated_pool) == NULL) {
+ MAKE_STD_ZVAL(PROTOBUF_G(generated_pool));
+ Z_TYPE_P(PROTOBUF_G(generated_pool)) = IS_OBJECT;
+ generated_pool = ALLOC(DescriptorPool);
+ descriptor_pool_init_c_instance(generated_pool TSRMLS_CC);
+ Z_OBJ_HANDLE_P(PROTOBUF_G(generated_pool)) = zend_objects_store_put(
+ generated_pool, NULL,
+ (zend_objects_free_object_storage_t)descriptor_pool_free, NULL TSRMLS_CC);
+ Z_OBJ_HT_P(PROTOBUF_G(generated_pool)) = zend_get_std_object_handlers();
+ }
+ RETURN_ZVAL(PROTOBUF_G(generated_pool), 1, 0);
+}
+
+void descriptor_pool_init_c_instance(DescriptorPool* pool TSRMLS_DC) {
+ zend_object_std_init(&pool->std, descriptor_pool_type TSRMLS_CC);
+ pool->symtab = upb_symtab_new(&pool->symtab);
+
+ ALLOC_HASHTABLE(pool->pending_list);
+ zend_hash_init(pool->pending_list, 1, NULL, ZVAL_PTR_DTOR, 0);
+}
+
+void descriptor_pool_free_c(DescriptorPool *pool TSRMLS_DC) {
+ upb_symtab_unref(pool->symtab, &pool->symtab);
+ zend_hash_destroy(pool->pending_list);
+ FREE_HASHTABLE(pool->pending_list);
+}
+
+PHP_METHOD(DescriptorPool, addMessage) {
+ char *name = NULL;
+ int str_len;
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &str_len) ==
+ FAILURE) {
+ return;
+ }
+
+ zval* retval = NULL;
+ PROTOBUF_CREATE_ZEND_WRAPPER(MessageBuilderContext, message_builder_context,
+ retval, context);
+
+ MAKE_STD_ZVAL(context->pool);
+ ZVAL_ZVAL(context->pool, getThis(), 1, 0);
+
+ Descriptor *desc = php_to_descriptor(context->descriptor TSRMLS_CC);
+ Descriptor_name_set(desc, name);
+
+ RETURN_ZVAL(retval, 0, 1);
+}
+
+static void validate_msgdef(const upb_msgdef* msgdef) {
+ // Verify that no required fields exist. proto3 does not support these.
+ upb_msg_field_iter it;
+ for (upb_msg_field_begin(&it, msgdef);
+ !upb_msg_field_done(&it);
+ upb_msg_field_next(&it)) {
+ const upb_fielddef* field = upb_msg_iter_field(&it);
+ if (upb_fielddef_label(field) == UPB_LABEL_REQUIRED) {
+ zend_error(E_ERROR, "Required fields are unsupported in proto3.");
+ }
+ }
+}
+
+PHP_METHOD(DescriptorPool, finalize) {
+ DescriptorPool *self = php_to_descriptor_pool(getThis() TSRMLS_CC);
+ Bucket *temp;
+ int i, num;
+
+ num = zend_hash_num_elements(self->pending_list);
+ upb_def **defs = emalloc(sizeof(upb_def *) * num);
+
+ for (i = 0, temp = self->pending_list->pListHead; temp != NULL;
+ temp = temp->pListNext) {
+ zval *def_php = *(zval **)temp->pData;
+ Descriptor* desc = php_to_descriptor(def_php TSRMLS_CC);
+ defs[i] = (upb_def *)desc->msgdef;
+ validate_msgdef((const upb_msgdef *)defs[i++]);
+ }
+
+ CHECK_UPB(upb_symtab_add(self->symtab, (upb_def **)defs, num, NULL, &status),
+ "Unable to add defs to DescriptorPool");
+
+ for (temp = self->pending_list->pListHead; temp != NULL;
+ temp = temp->pListNext) {
+ // zval *def_php = *(zval **)temp->pData;
+ // Descriptor* desc = php_to_descriptor(def_php TSRMLS_CC);
+ build_class_from_descriptor((zval *)temp->pDataPtr TSRMLS_CC);
+ }
+
+ FREE(defs);
+ zend_hash_destroy(self->pending_list);
+ zend_hash_init(self->pending_list, 1, NULL, ZVAL_PTR_DTOR, 0);
+}
+
+// -----------------------------------------------------------------------------
+// Descriptor
+// -----------------------------------------------------------------------------
+
+static zend_function_entry descriptor_methods[] = {
+ ZEND_FE_END
+};
+
+DEFINE_CLASS(Descriptor, descriptor, "Google\\Protobuf\\Descriptor");
+
+void descriptor_free_c(Descriptor *self TSRMLS_DC) {
+ upb_msg_field_iter iter;
+ upb_msg_field_begin(&iter, self->msgdef);
+ while (!upb_msg_field_done(&iter)) {
+ upb_fielddef *fielddef = upb_msg_iter_field(&iter);
+ upb_fielddef_unref(fielddef, &fielddef);
+ upb_msg_field_next(&iter);
+ }
+ upb_msgdef_unref(self->msgdef, &self->msgdef);
+ if (self->layout) {
+ free_layout(self->layout);
+ }
+}
+
+static void descriptor_add_field(Descriptor *desc,
+ const upb_fielddef *fielddef) {
+ upb_msgdef *mut_def = check_msgdef_notfrozen(desc->msgdef);
+ upb_fielddef *mut_field_def = check_fielddef_notfrozen(fielddef);
+ CHECK_UPB(upb_msgdef_addfield(mut_def, mut_field_def, NULL, &status),
+ "Adding field to Descriptor failed");
+ // add_def_obj(fielddef, obj);
+}
+
+void descriptor_init_c_instance(Descriptor* desc TSRMLS_DC) {
+ zend_object_std_init(&desc->std, descriptor_type TSRMLS_CC);
+ desc->msgdef = upb_msgdef_new(&desc->msgdef);
+ desc->layout = NULL;
+ // MAKE_STD_ZVAL(intern->klass);
+ // ZVAL_NULL(intern->klass);
+ desc->pb_serialize_handlers = NULL;
+}
+
+void Descriptor_name_set(Descriptor *desc, const char *name) {
+ upb_msgdef *mut_def = check_msgdef_notfrozen(desc->msgdef);
+ CHECK_UPB(upb_msgdef_setfullname(mut_def, name, &status),
+ "Error setting Descriptor name");
+}
+
+// -----------------------------------------------------------------------------
+// FieldDescriptor
+// -----------------------------------------------------------------------------
+
+static void field_descriptor_name_set(const upb_fielddef* fielddef,
+ const char *name) {
+ upb_fielddef *mut_def = check_fielddef_notfrozen(fielddef);
+ CHECK_UPB(upb_fielddef_setname(mut_def, name, &status),
+ "Error setting FieldDescriptor name");
+}
+
+static void field_descriptor_label_set(const upb_fielddef* fielddef,
+ upb_label_t upb_label) {
+ upb_fielddef *mut_def = check_fielddef_notfrozen(fielddef);
+ upb_fielddef_setlabel(mut_def, upb_label);
+}
+
+upb_fieldtype_t string_to_descriptortype(const char *type) {
+#define CONVERT(upb, str) \
+ if (!strcmp(type, str)) { \
+ return UPB_DESCRIPTOR_TYPE_##upb; \
+ }
+
+ CONVERT(FLOAT, "float");
+ CONVERT(DOUBLE, "double");
+ CONVERT(BOOL, "bool");
+ CONVERT(STRING, "string");
+ CONVERT(BYTES, "bytes");
+ CONVERT(MESSAGE, "message");
+ CONVERT(GROUP, "group");
+ CONVERT(ENUM, "enum");
+ CONVERT(INT32, "int32");
+ CONVERT(INT64, "int64");
+ CONVERT(UINT32, "uint32");
+ CONVERT(UINT64, "uint64");
+ CONVERT(SINT32, "sint32");
+ CONVERT(SINT64, "sint64");
+ CONVERT(FIXED32, "fixed32");
+ CONVERT(FIXED64, "fixed64");
+ CONVERT(SFIXED32, "sfixed32");
+ CONVERT(SFIXED64, "sfixed64");
+
+#undef CONVERT
+
+ zend_error(E_ERROR, "Unknown field type.");
+ return 0;
+}
+
+static void field_descriptor_type_set(const upb_fielddef* fielddef,
+ const char *type) {
+ upb_fielddef *mut_def = check_fielddef_notfrozen(fielddef);
+ upb_fielddef_setdescriptortype(mut_def, string_to_descriptortype(type));
+}
+
+static void field_descriptor_number_set(const upb_fielddef* fielddef,
+ int number) {
+ upb_fielddef *mut_def = check_fielddef_notfrozen(fielddef);
+ CHECK_UPB(upb_fielddef_setnumber(mut_def, number, &status),
+ "Error setting field number");
+}
+
+// -----------------------------------------------------------------------------
+// MessageBuilderContext
+// -----------------------------------------------------------------------------
+
+static zend_function_entry message_builder_context_methods[] = {
+ PHP_ME(MessageBuilderContext, finalizeToPool, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(MessageBuilderContext, optional, NULL, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+
+DEFINE_CLASS(MessageBuilderContext, message_builder_context,
+ "Google\\Protobuf\\Internal\\MessageBuilderContext");
+
+void message_builder_context_free_c(MessageBuilderContext *context TSRMLS_DC) {
+ zval_ptr_dtor(&context->descriptor);
+ zval_ptr_dtor(&context->pool);
+}
+
+void message_builder_context_init_c_instance(
+ MessageBuilderContext *context TSRMLS_DC) {
+ zend_object_std_init(&context->std, message_builder_context_type TSRMLS_CC);
+ PROTOBUF_CREATE_ZEND_WRAPPER(Descriptor, descriptor, context->descriptor,
+ desc);
+}
+
+static void msgdef_add_field(Descriptor *desc, upb_label_t upb_label,
+ const char *name, const char *type, int number,
+ const char *type_class) {
+ upb_fielddef *fielddef = upb_fielddef_new(&fielddef);
+ upb_fielddef_setpacked(fielddef, false);
+
+ field_descriptor_label_set(fielddef, upb_label);
+ field_descriptor_name_set(fielddef, name);
+ field_descriptor_type_set(fielddef, type);
+ field_descriptor_number_set(fielddef, number);
+
+// // if (type_class != Qnil) {
+// // if (TYPE(type_class) != T_STRING) {
+// // rb_raise(rb_eArgError, "Expected string for type class");
+// // }
+// // // Make it an absolute type name by prepending a dot.
+// // type_class = rb_str_append(rb_str_new2("."), type_class);
+// // rb_funcall(fielddef, rb_intern("submsg_name="), 1, type_class);
+// // }
+ descriptor_add_field(desc, fielddef);
+}
+
+PHP_METHOD(MessageBuilderContext, optional) {
+ MessageBuilderContext *self = php_to_message_builder_context(getThis() TSRMLS_CC);
+ Descriptor *desc = php_to_descriptor(self->descriptor TSRMLS_CC);
+ // VALUE name, type, number, type_class;
+ const char *name, *type, *type_class;
+ int number, name_str_len, type_str_len, type_class_str_len;
+ if (ZEND_NUM_ARGS() == 3) {
+ if (zend_parse_parameters(3 TSRMLS_CC, "ssl", &name,
+ &name_str_len, &type, &type_str_len, &number) == FAILURE) {
+ return;
+ }
+ } else {
+ if (zend_parse_parameters(4 TSRMLS_CC, "ssls", &name,
+ &name_str_len, &type, &type_str_len, &number, &type_class,
+ &type_class_str_len) == FAILURE) {
+ return;
+ }
+ }
+
+ msgdef_add_field(desc, UPB_LABEL_OPTIONAL, name, type, number, type_class);
+
+ zval_copy_ctor(getThis());
+ RETURN_ZVAL(getThis(), 1, 0);
+}
+
+PHP_METHOD(MessageBuilderContext, finalizeToPool) {
+ MessageBuilderContext *self = php_to_message_builder_context(getThis() TSRMLS_CC);
+ DescriptorPool *pool = php_to_descriptor_pool(self->pool TSRMLS_CC);
+ Descriptor* desc = php_to_descriptor(self->descriptor TSRMLS_CC);
+
+ Z_ADDREF_P(self->descriptor);
+ zend_hash_next_index_insert(pool->pending_list, &self->descriptor,
+ sizeof(zval *), NULL);
+ RETURN_ZVAL(self->pool, 1, 0);
+}
diff --git a/php/ext/google/protobuf/message.c b/php/ext/google/protobuf/message.c
new file mode 100644
index 00000000..c062d665
--- /dev/null
+++ b/php/ext/google/protobuf/message.c
@@ -0,0 +1,273 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2014 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 <php.h>
+
+#include "protobuf.h"
+
+// -----------------------------------------------------------------------------
+// Class/module creation from msgdefs and enumdefs, respectively.
+// -----------------------------------------------------------------------------
+
+void* message_data(void* msg) {
+ return ((uint8_t *)msg) + sizeof(MessageHeader);
+}
+
+void message_set_property(zval* object, zval* field_name, zval* value,
+ const zend_literal* key TSRMLS_DC) {
+ const upb_fielddef* field;
+
+ MessageHeader* self = zend_object_store_get_object(object TSRMLS_CC);
+
+ CHECK_TYPE(field_name, IS_STRING);
+ field = upb_msgdef_ntofz(self->descriptor->msgdef, Z_STRVAL_P(field_name));
+ if (field == NULL) {
+ zend_error(E_ERROR, "Unknown field: %s", Z_STRVAL_P(field_name));
+ }
+ layout_set(self->descriptor->layout, message_data(self), field, value);
+}
+
+zval* message_get_property(zval* object, zval* member, int type,
+ const zend_literal* key TSRMLS_DC) {
+ MessageHeader* self =
+ (MessageHeader*)zend_object_store_get_object(object TSRMLS_CC);
+ CHECK_TYPE(member, IS_STRING);
+
+ const upb_fielddef* field;
+ field = upb_msgdef_ntofz(self->descriptor->msgdef, Z_STRVAL_P(member));
+ if (field == NULL) {
+ return EG(uninitialized_zval_ptr);
+ }
+ zval* retval = layout_get(self->descriptor->layout, message_data(self), field TSRMLS_CC);
+ return retval;
+}
+
+static zend_function_entry message_methods[] = {
+ PHP_ME(Message, encode, NULL, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+
+/* stringsink *****************************************************************/
+
+// This should probably be factored into a common upb component.
+
+typedef struct {
+ upb_byteshandler handler;
+ upb_bytessink sink;
+ char *ptr;
+ size_t len, size;
+} stringsink;
+
+static void *stringsink_start(void *_sink, const void *hd, size_t size_hint) {
+ stringsink *sink = _sink;
+ sink->len = 0;
+ return sink;
+}
+
+static size_t stringsink_string(void *_sink, const void *hd, const char *ptr,
+ size_t len, const upb_bufhandle *handle) {
+ stringsink *sink = _sink;
+ size_t new_size = sink->size;
+
+ UPB_UNUSED(hd);
+ UPB_UNUSED(handle);
+
+ while (sink->len + len > new_size) {
+ new_size *= 2;
+ }
+
+ if (new_size != sink->size) {
+ sink->ptr = realloc(sink->ptr, new_size);
+ sink->size = new_size;
+ }
+
+ memcpy(sink->ptr + sink->len, ptr, len);
+ sink->len += len;
+
+ return len;
+}
+
+void stringsink_init(stringsink *sink) {
+ upb_byteshandler_init(&sink->handler);
+ upb_byteshandler_setstartstr(&sink->handler, stringsink_start, NULL);
+ upb_byteshandler_setstring(&sink->handler, stringsink_string, NULL);
+
+ upb_bytessink_reset(&sink->sink, &sink->handler, sink);
+
+ sink->size = 32;
+ sink->ptr = malloc(sink->size);
+ sink->len = 0;
+}
+
+void stringsink_uninit(stringsink *sink) { free(sink->ptr); }
+
+// Stack-allocated context during an encode/decode operation. Contains the upb
+// environment and its stack-based allocator, an initial buffer for allocations
+// to avoid malloc() when possible, and a template for PHP exception messages
+// if any error occurs.
+#define STACK_ENV_STACKBYTES 4096
+typedef struct {
+ upb_env env;
+ upb_seededalloc alloc;
+ const char *php_error_template;
+ char allocbuf[STACK_ENV_STACKBYTES];
+} stackenv;
+
+static void stackenv_init(stackenv* se, const char* errmsg);
+static void stackenv_uninit(stackenv* se);
+
+// Callback invoked by upb if any error occurs during parsing or serialization.
+static bool env_error_func(void* ud, const upb_status* status) {
+ stackenv* se = ud;
+ // Free the env -- rb_raise will longjmp up the stack past the encode/decode
+ // function so it would not otherwise have been freed.
+ stackenv_uninit(se);
+
+ // TODO(teboring): have a way to verify that this is actually a parse error,
+ // instead of just throwing "parse error" unconditionally.
+ zend_error(E_ERROR, se->php_error_template);
+ // Never reached.
+ return false;
+}
+
+static void stackenv_init(stackenv* se, const char* errmsg) {
+ se->php_error_template = errmsg;
+ upb_env_init(&se->env);
+ upb_seededalloc_init(&se->alloc, &se->allocbuf, STACK_ENV_STACKBYTES);
+ upb_env_setallocfunc(&se->env, upb_seededalloc_getallocfunc(&se->alloc),
+ &se->alloc);
+ upb_env_seterrorfunc(&se->env, env_error_func, se);
+}
+
+static void stackenv_uninit(stackenv* se) {
+ upb_env_uninit(&se->env);
+ upb_seededalloc_uninit(&se->alloc);
+}
+
+// -----------------------------------------------------------------------------
+// Message
+// -----------------------------------------------------------------------------
+
+static const upb_handlers* msgdef_pb_serialize_handlers(Descriptor* desc) {
+ if (desc->pb_serialize_handlers == NULL) {
+ desc->pb_serialize_handlers =
+ upb_pb_encoder_newhandlers(desc->msgdef, &desc->pb_serialize_handlers);
+ }
+ return desc->pb_serialize_handlers;
+}
+
+PHP_METHOD(Message, encode) {
+ Descriptor* desc = (Descriptor*)zend_object_store_get_object(
+ CE_STATIC_MEMBERS(Z_OBJCE_P(getThis()))[0] TSRMLS_CC);
+
+ stringsink sink;
+ stringsink_init(&sink);
+
+ {
+ const upb_handlers* serialize_handlers = msgdef_pb_serialize_handlers(desc);
+
+ stackenv se;
+ upb_pb_encoder* encoder;
+
+ stackenv_init(&se, "Error occurred during encoding: %s");
+ encoder = upb_pb_encoder_create(&se.env, serialize_handlers, &sink.sink);
+
+ putmsg(getThis(), desc, upb_pb_encoder_input(encoder), 0);
+
+ RETVAL_STRINGL(sink.ptr, sink.len, 1);
+
+ stackenv_uninit(&se);
+ stringsink_uninit(&sink);
+ }
+}
+
+void message_free(void * object TSRMLS_DC) {
+ FREE(object);
+}
+
+zend_object_value message_create(zend_class_entry* ce TSRMLS_DC) {
+ zend_object_value return_value;
+
+ zval* php_descriptor = get_def_obj(ce);
+
+ Descriptor* desc = zend_object_store_get_object(php_descriptor TSRMLS_CC);
+ MessageHeader* msg = (MessageHeader*)ALLOC_N(
+ uint8_t, sizeof(MessageHeader) + desc->layout->size);
+ memset(message_data(msg), 0, desc->layout->size);
+
+ // We wrap first so that everything in the message object is GC-rooted in case
+ // a collection happens during object creation in layout_init().
+ msg->descriptor = desc;
+
+ layout_init(desc->layout, message_data(msg));
+ zend_object_std_init(&msg->std, ce TSRMLS_CC);
+
+ return_value.handle = zend_objects_store_put(
+ msg, (zend_objects_store_dtor_t)zend_objects_destroy_object,
+ message_free, NULL TSRMLS_CC);
+
+ return_value.handlers = PROTOBUF_G(message_handlers);
+ return return_value;
+}
+
+const zend_class_entry* build_class_from_descriptor(
+ zval* php_descriptor TSRMLS_DC) {
+ Descriptor* desc = php_to_descriptor(php_descriptor);
+ if (desc->layout == NULL) {
+ MessageLayout* layout = create_layout(desc->msgdef);
+ desc->layout = layout;
+ }
+ // TODO(teboring): Add it back.
+ // if (desc->fill_method == NULL) {
+ // desc->fill_method = new_fillmsg_decodermethod(desc, &desc->fill_method);
+ // }
+
+ const char* name = upb_msgdef_fullname(desc->msgdef);
+ if (name == NULL) {
+ zend_error(E_ERROR, "Descriptor does not have assigned name.");
+ }
+
+ zend_class_entry class_entry;
+ INIT_CLASS_ENTRY_EX(class_entry, name, strlen(name), message_methods);
+ zend_class_entry* registered_ce =
+ zend_register_internal_class(&class_entry TSRMLS_CC);
+
+ add_def_obj(registered_ce, php_descriptor);
+
+ if (PROTOBUF_G(message_handlers) == NULL) {
+ PROTOBUF_G(message_handlers) = ALLOC(zend_object_handlers);
+ memcpy(PROTOBUF_G(message_handlers), zend_get_std_object_handlers(),
+ sizeof(zend_object_handlers));
+ PROTOBUF_G(message_handlers)->write_property = message_set_property;
+ PROTOBUF_G(message_handlers)->read_property = message_get_property;
+ }
+
+ registered_ce->create_object = message_create;
+}
diff --git a/php/ext/google/protobuf/protobuf.c b/php/ext/google/protobuf/protobuf.c
new file mode 100644
index 00000000..b1ace8b0
--- /dev/null
+++ b/php/ext/google/protobuf/protobuf.c
@@ -0,0 +1,89 @@
+#include "protobuf.h"
+
+#include <zend_hash.h>
+
+ZEND_DECLARE_MODULE_GLOBALS(protobuf)
+static PHP_GINIT_FUNCTION(protobuf);
+static PHP_GSHUTDOWN_FUNCTION(protobuf);
+
+// -----------------------------------------------------------------------------
+// Global map from upb {msg,enum}defs to wrapper Descriptor/EnumDescriptor
+// instances.
+// -----------------------------------------------------------------------------
+
+void add_def_obj(const void* def, zval* value) {
+ uint nIndex = (ulong)def & PROTOBUF_G(upb_def_to_php_obj_map).nTableMask;
+
+ zval* pDest = NULL;
+ Z_ADDREF_P(value);
+ zend_hash_index_update(&PROTOBUF_G(upb_def_to_php_obj_map), (zend_ulong)def,
+ &value, sizeof(zval*), &pDest);
+}
+
+zval* get_def_obj(const void* def) {
+ zval** value;
+ if (zend_hash_index_find(&PROTOBUF_G(upb_def_to_php_obj_map), (zend_ulong)def,
+ &value) == FAILURE) {
+ zend_error(E_ERROR, "PHP object not found for given definition.\n");
+ return NULL;
+ }
+ return *value;
+}
+
+// -----------------------------------------------------------------------------
+// Utilities.
+// -----------------------------------------------------------------------------
+
+// define the function(s) we want to add
+zend_function_entry protobuf_functions[] = {
+ ZEND_FE(get_generated_pool, NULL)
+ ZEND_FE_END
+};
+
+// "protobuf_functions" refers to the struct defined above
+// we'll be filling in more of this later: you can use this to specify
+// globals, php.ini info, startup and teardown functions, etc.
+zend_module_entry protobuf_module_entry = {
+ STANDARD_MODULE_HEADER,
+ PHP_PROTOBUF_EXTNAME, // extension name
+ protobuf_functions, // function list
+ PHP_MINIT(protobuf), // process startup
+ NULL, // process shutdown
+ NULL, // request startup
+ NULL, // request shutdown
+ NULL, // extension info
+ PHP_PROTOBUF_VERSION, // extension version
+ PHP_MODULE_GLOBALS(protobuf), // globals descriptor
+ PHP_GINIT(protobuf), // globals ctor
+ PHP_GSHUTDOWN(protobuf), // globals dtor
+ NULL, // post deactivate
+ STANDARD_MODULE_PROPERTIES_EX
+};
+
+// install module
+ZEND_GET_MODULE(protobuf)
+
+// global variables
+static PHP_GINIT_FUNCTION(protobuf) {
+ protobuf_globals->generated_pool = NULL;
+ generated_pool = NULL;
+ protobuf_globals->message_handlers = NULL;
+ zend_hash_init(&protobuf_globals->upb_def_to_php_obj_map, 16, NULL,
+ ZVAL_PTR_DTOR, 0);
+}
+
+static PHP_GSHUTDOWN_FUNCTION(protobuf) {
+ if (protobuf_globals->generated_pool != NULL) {
+ FREE_ZVAL(protobuf_globals->generated_pool);
+ }
+ if (protobuf_globals->message_handlers != NULL) {
+ FREE(protobuf_globals->message_handlers);
+ }
+ zend_hash_destroy(&protobuf_globals->upb_def_to_php_obj_map);
+}
+
+PHP_MINIT_FUNCTION(protobuf) {
+ descriptor_pool_init(TSRMLS_C);
+ descriptor_init(TSRMLS_C);
+ message_builder_context_init(TSRMLS_C);
+}
diff --git a/php/ext/google/protobuf/protobuf.h b/php/ext/google/protobuf/protobuf.h
new file mode 100644
index 00000000..f9038550
--- /dev/null
+++ b/php/ext/google/protobuf/protobuf.h
@@ -0,0 +1,281 @@
+#ifndef __GOOGLE_PROTOBUF_PHP_PROTOBUF_H__
+#define __GOOGLE_PROTOBUF_PHP_PROTOBUF_H__
+
+#include <php.h>
+
+#include "upb.h"
+
+#define PHP_PROTOBUF_EXTNAME "protobuf"
+#define PHP_PROTOBUF_VERSION "0.01"
+
+// Forward decls.
+struct DescriptorPool;
+struct Descriptor;
+struct FieldDescriptor;
+struct EnumDescriptor;
+struct MessageLayout;
+struct MessageField;
+struct MessageHeader;
+struct MessageBuilderContext;
+struct EnumBuilderContext;
+
+typedef struct DescriptorPool DescriptorPool;
+typedef struct Descriptor Descriptor;
+typedef struct FieldDescriptor FieldDescriptor;
+typedef struct OneofDescriptor OneofDescriptor;
+typedef struct EnumDescriptor EnumDescriptor;
+typedef struct MessageLayout MessageLayout;
+typedef struct MessageField MessageField;
+typedef struct MessageHeader MessageHeader;
+typedef struct MessageBuilderContext MessageBuilderContext;
+typedef struct OneofBuilderContext OneofBuilderContext;
+typedef struct EnumBuilderContext EnumBuilderContext;
+
+extern zend_class_entry* builder_type;
+extern zend_class_entry* descriptor_type;
+extern zend_class_entry* message_builder_context_type;
+
+extern DescriptorPool* generated_pool; // The actual generated pool
+
+ZEND_BEGIN_MODULE_GLOBALS(protobuf)
+ zval* generated_pool;
+ zend_object_handlers* message_handlers;
+ HashTable upb_def_to_php_obj_map;
+ZEND_END_MODULE_GLOBALS(protobuf)
+
+ZEND_DECLARE_MODULE_GLOBALS(protobuf)
+
+#ifdef ZTS
+#define PROTOBUF_G(v) TSRMG(protobuf_globals_id, zend_protobuf_globals*, v)
+#else
+#define PROTOBUF_G(v) (protobuf_globals.v)
+#endif
+
+// -----------------------------------------------------------------------------
+// PHP functions and global variables.
+// -----------------------------------------------------------------------------
+
+PHP_MINIT_FUNCTION(protobuf);
+
+// -----------------------------------------------------------------------------
+// PHP class structure.
+// -----------------------------------------------------------------------------
+
+struct DescriptorPool {
+ zend_object std;
+ upb_symtab* symtab;
+ HashTable* pending_list;
+};
+
+struct Descriptor {
+ zend_object std;
+ const upb_msgdef* msgdef;
+ MessageLayout* layout;
+ // zval* klass; // begins as NULL
+ // const upb_handlers* fill_handlers;
+ // const upb_pbdecodermethod* fill_method;
+ const upb_handlers* pb_serialize_handlers;
+ // const upb_handlers* json_serialize_handlers;
+ // Handlers hold type class references for sub-message fields directly in some
+ // cases. We need to keep these rooted because they might otherwise be
+ // collected.
+ // zval_array typeclass_references;
+};
+
+struct FieldDescriptor {
+ zend_object std;
+ const upb_fielddef* fielddef;
+};
+
+struct OneofDescriptor {
+ zend_object std;
+ const upb_oneofdef* oneofdef;
+};
+
+struct EnumDescriptor {
+ zend_object std;
+ const upb_enumdef* enumdef;
+ // zval* module; // begins as NULL
+};
+
+// -----------------------------------------------------------------------------
+// Native slot storage abstraction.
+// -----------------------------------------------------------------------------
+
+#define NATIVE_SLOT_MAX_SIZE sizeof(uint64_t)
+
+size_t native_slot_size(upb_fieldtype_t type);
+
+#define MAP_KEY_FIELD 1
+#define MAP_VALUE_FIELD 2
+
+// Oneof case slot value to indicate that no oneof case is set. The value `0` is
+// safe because field numbers are used as case identifiers, and no field can
+// have a number of 0.
+#define ONEOF_CASE_NONE 0
+
+// These operate on a map field (i.e., a repeated field of submessages whose
+// submessage type is a map-entry msgdef).
+bool is_map_field(const upb_fielddef* field);
+const upb_fielddef* map_field_key(const upb_fielddef* field);
+const upb_fielddef* map_field_value(const upb_fielddef* field);
+
+// These operate on a map-entry msgdef.
+const upb_fielddef* map_entry_key(const upb_msgdef* msgdef);
+const upb_fielddef* map_entry_value(const upb_msgdef* msgdef);
+
+// -----------------------------------------------------------------------------
+// Message layout / storage.
+// -----------------------------------------------------------------------------
+
+#define MESSAGE_FIELD_NO_CASE ((size_t)-1)
+
+struct MessageField {
+ size_t offset;
+ size_t case_offset; // for oneofs, a uint32. Else, MESSAGE_FIELD_NO_CASE.
+};
+
+struct MessageLayout {
+ const upb_msgdef* msgdef;
+ MessageField* fields;
+ size_t size;
+};
+
+void layout_init(MessageLayout* layout, void* storage);
+zval* layout_get(MessageLayout* layout, const void* storage,
+ const upb_fielddef* field TSRMLS_DC);
+MessageLayout* create_layout(const upb_msgdef* msgdef);
+void free_layout(MessageLayout* layout);
+zval* native_slot_get(upb_fieldtype_t type, /*VALUE type_class,*/
+ const void* memory TSRMLS_DC);
+
+// -----------------------------------------------------------------------------
+// Message class creation.
+// -----------------------------------------------------------------------------
+
+struct MessageHeader {
+ zend_object std;
+ Descriptor* descriptor; // kept alive by self.class.descriptor reference.
+ // Data comes after this.
+};
+
+struct MessageBuilderContext {
+ zend_object std;
+ zval* descriptor;
+ zval* pool;
+};
+
+struct OneofBuilderContext {
+ zend_object std;
+ // VALUE descriptor;
+ // VALUE builder;
+};
+
+struct EnumBuilderContext {
+ zend_object std;
+ // VALUE enumdesc;
+};
+
+// Forward-declare all of the PHP method implementations.
+
+DescriptorPool* php_to_descriptor_pool(zval* value TSRMLS_DC);
+zend_object_value descriptor_pool_create(zend_class_entry *ce TSRMLS_DC);
+void descriptor_pool_free_c(DescriptorPool* object TSRMLS_DC);
+void descriptor_pool_free(void* object TSRMLS_DC);
+void descriptor_pool_init_c_instance(DescriptorPool* pool TSRMLS_DC);
+PHP_METHOD(DescriptorPool, addMessage);
+PHP_METHOD(DescriptorPool, finalize);
+
+Descriptor* php_to_descriptor(zval* value TSRMLS_DC);
+zend_object_value descriptor_create(zend_class_entry *ce TSRMLS_DC);
+void descriptor_init_c_instance(Descriptor* intern TSRMLS_DC);
+void descriptor_free_c(Descriptor* object TSRMLS_DC);
+void descriptor_free(void* object TSRMLS_DC);
+void descriptor_name_set(Descriptor *desc, const char *name);
+
+MessageBuilderContext* php_to_message_builder_context(zval* value TSRMLS_DC);
+zend_object_value message_builder_context_create(
+ zend_class_entry* ce TSRMLS_DC);
+void message_builder_context_init_c_instance(
+ MessageBuilderContext* intern TSRMLS_DC);
+void message_builder_context_free_c(MessageBuilderContext* object TSRMLS_DC);
+void message_builder_context_free(void* object TSRMLS_DC);
+PHP_METHOD(MessageBuilderContext, optional);
+PHP_METHOD(MessageBuilderContext, finalizeToPool);
+
+PHP_METHOD(Message, encode);
+const zend_class_entry* build_class_from_descriptor(
+ zval* php_descriptor TSRMLS_DC);
+
+PHP_FUNCTION(get_generated_pool);
+
+// -----------------------------------------------------------------------------
+// Global map from upb {msg,enum}defs to wrapper Descriptor/EnumDescriptor
+// instances.
+// ----------------------------------------------------------------------------
+
+void add_def_obj(const void* def, zval* value);
+zval* get_def_obj(const void* def);
+
+// -----------------------------------------------------------------------------
+// Utilities.
+// -----------------------------------------------------------------------------
+
+// PHP Array utils.
+#define Z_ARRVAL_SIZE_P(zval_p) zend_hash_num_elements(Z_ARRVAL_P(zval_p))
+#define Z_ARRVAL_BEGIN_P(zval_p) Z_ARRVAL_P(zval_p)->pListHead
+#define Z_BUCKET_NEXT_PP(bucket_pp) *bucket_pp = (*bucket_pp)->pListNext
+
+#define DEFINE_PHP_OBJECT(class_name, class_name_lower, name) \
+ do { \
+ zval* name; \
+ MAKE_STD_ZVAL(name); \
+ object_init_ex(name, class_name_lower##_type); \
+ } while (0)
+
+#define DEFINE_PHP_WRAPPER(class_name, class_name_lower, name, intern) \
+ zval* name; \
+ MAKE_STD_ZVAL(name); \
+ object_init_ex(name, class_name_lower##_type); \
+ Z_OBJVAL_P(name) \
+ .handle = zend_objects_store_put( \
+ intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, \
+ class_name_lower##_free, NULL TSRMLS_CC);
+
+#define DEFINE_PHP_ZVAL(name) \
+ do { \
+ zval* name; \
+ MAKE_STD_ZVAL(name); \
+ } while (0)
+
+#define DEFINE_PHP_STRING(name, value) \
+ do { \
+ zval* name; \
+ MAKE_STD_ZVAL(name); \
+ ZVAL_STRING(name, value, 1); \
+ } while (0)
+
+// Upb Utilities
+
+void check_upb_status(const upb_status* status, const char* msg);
+
+#define CHECK_UPB(code, msg) \
+ do { \
+ upb_status status = UPB_STATUS_INIT; \
+ code; \
+ check_upb_status(&status, msg); \
+ } while (0)
+
+// Memory management
+
+#define ALLOC(class_name) (class_name*) emalloc(sizeof(class_name))
+#define ALLOC_N(class_name, n) (class_name*) emalloc(sizeof(class_name) * n)
+#define FREE(object) efree(object)
+
+// Type Checking
+#define CHECK_TYPE(field, type) \
+ if (Z_TYPE_P(field) != type) { \
+ zend_error(E_ERROR, "Unexpected type"); \
+ }
+
+#endif // __GOOGLE_PROTOBUF_PHP_PROTOBUF_H__
diff --git a/php/ext/google/protobuf/storage.c b/php/ext/google/protobuf/storage.c
new file mode 100644
index 00000000..e5a09c17
--- /dev/null
+++ b/php/ext/google/protobuf/storage.c
@@ -0,0 +1,539 @@
+#include <stdint.h>
+#include <protobuf.h>
+
+// -----------------------------------------------------------------------------
+// PHP <-> native slot management.
+// -----------------------------------------------------------------------------
+
+static zval* int32_to_zval(int32_t value) {
+ zval* tmp;
+ MAKE_STD_ZVAL(tmp);
+ ZVAL_LONG(tmp, value);
+ php_printf("int32 to zval\n");
+ // ZVAL_LONG(tmp, 1);
+ return tmp;
+}
+
+#define DEREF(memory, type) *(type*)(memory)
+
+size_t native_slot_size(upb_fieldtype_t type) {
+ switch (type) {
+ case UPB_TYPE_FLOAT: return 4;
+ case UPB_TYPE_DOUBLE: return 8;
+ case UPB_TYPE_BOOL: return 1;
+ case UPB_TYPE_STRING: return sizeof(zval*);
+ case UPB_TYPE_BYTES: return sizeof(zval*);
+ case UPB_TYPE_MESSAGE: return sizeof(zval*);
+ case UPB_TYPE_ENUM: return 4;
+ case UPB_TYPE_INT32: return 4;
+ case UPB_TYPE_INT64: return 8;
+ case UPB_TYPE_UINT32: return 4;
+ case UPB_TYPE_UINT64: return 8;
+ default: return 0;
+ }
+}
+
+static bool is_php_num(zval* value) {
+ // Is numerial string also valid?
+ return (Z_TYPE_P(value) == IS_LONG ||
+ Z_TYPE_P(value) == IS_DOUBLE);
+}
+
+void native_slot_check_int_range_precision(upb_fieldtype_t type, zval* val) {
+ // TODO(teboring): Add it back.
+ // if (!is_php_num(val)) {
+ // zend_error(E_ERROR, "Expected number type for integral field.");
+ // }
+
+ // if (Z_TYPE_P(val) == IS_DOUBLE) {
+ // double dbl_val = NUM2DBL(val);
+ // if (floor(dbl_val) != dbl_val) {
+ // zend_error(E_ERROR,
+ // "Non-integral floating point value assigned to integer field.");
+ // }
+ // }
+ // if (type == UPB_TYPE_UINT32 || type == UPB_TYPE_UINT64) {
+ // if (NUM2DBL(val) < 0) {
+ // zend_error(E_ERROR,
+ // "Assigning negative value to unsigned integer field.");
+ // }
+ // }
+}
+
+zval* native_slot_get(upb_fieldtype_t type, /*VALUE type_class,*/
+ const void* memory TSRMLS_DC) {
+ zval* retval = NULL;
+ switch (type) {
+ // TODO(teboring): Add it back.
+ // case UPB_TYPE_FLOAT:
+ // return DBL2NUM(DEREF(memory, float));
+ // case UPB_TYPE_DOUBLE:
+ // return DBL2NUM(DEREF(memory, double));
+ // case UPB_TYPE_BOOL:
+ // return DEREF(memory, int8_t) ? Qtrue : Qfalse;
+ // case UPB_TYPE_STRING:
+ // case UPB_TYPE_BYTES:
+ // case UPB_TYPE_MESSAGE:
+ // return DEREF(memory, VALUE);
+ // case UPB_TYPE_ENUM: {
+ // int32_t val = DEREF(memory, int32_t);
+ // VALUE symbol = enum_lookup(type_class, INT2NUM(val));
+ // if (symbol == Qnil) {
+ // return INT2NUM(val);
+ // } else {
+ // return symbol;
+ // }
+ // }
+ case UPB_TYPE_INT32:
+ return int32_to_zval(DEREF(memory, int32_t));
+ // TODO(teboring): Add it back.
+ // case UPB_TYPE_INT64:
+ // return LL2NUM(DEREF(memory, int64_t));
+ // case UPB_TYPE_UINT32:
+ // return UINT2NUM(DEREF(memory, uint32_t));
+ // case UPB_TYPE_UINT64:
+ // return ULL2NUM(DEREF(memory, uint64_t));
+ default:
+ return EG(uninitialized_zval_ptr);
+ }
+}
+
+void native_slot_init(upb_fieldtype_t type, void* memory) {
+ switch (type) {
+ case UPB_TYPE_FLOAT:
+ DEREF(memory, float) = 0.0;
+ break;
+ case UPB_TYPE_DOUBLE:
+ DEREF(memory, double) = 0.0;
+ break;
+ case UPB_TYPE_BOOL:
+ DEREF(memory, int8_t) = 0;
+ break;
+ // TODO(teboring): Add it back.
+ // case UPB_TYPE_STRING:
+ // case UPB_TYPE_BYTES:
+ // DEREF(memory, VALUE) = php_str_new2("");
+ // php_enc_associate(DEREF(memory, VALUE), (type == UPB_TYPE_BYTES)
+ // ? kRubyString8bitEncoding
+ // : kRubyStringUtf8Encoding);
+ // break;
+ // case UPB_TYPE_MESSAGE:
+ // DEREF(memory, VALUE) = Qnil;
+ // break;
+ case UPB_TYPE_ENUM:
+ case UPB_TYPE_INT32:
+ DEREF(memory, int32_t) = 0;
+ break;
+ case UPB_TYPE_INT64:
+ DEREF(memory, int64_t) = 0;
+ break;
+ case UPB_TYPE_UINT32:
+ DEREF(memory, uint32_t) = 0;
+ break;
+ case UPB_TYPE_UINT64:
+ DEREF(memory, uint64_t) = 0;
+ break;
+ default:
+ break;
+ }
+}
+
+void native_slot_set(upb_fieldtype_t type, /*VALUE type_class,*/ void* memory,
+ zval* value) {
+ native_slot_set_value_and_case(type, /*type_class,*/ memory, value, NULL, 0);
+}
+
+void native_slot_set_value_and_case(upb_fieldtype_t type, /*VALUE type_class,*/
+ void* memory, zval* value,
+ uint32_t* case_memory,
+ uint32_t case_number) {
+ switch (type) {
+ case UPB_TYPE_FLOAT:
+ if (!Z_TYPE_P(value) == IS_LONG) {
+ zend_error(E_ERROR, "Expected number type for float field.");
+ }
+ DEREF(memory, float) = Z_DVAL_P(value);
+ break;
+ case UPB_TYPE_DOUBLE:
+ // TODO(teboring): Add it back.
+ // if (!is_php_num(value)) {
+ // zend_error(E_ERROR, "Expected number type for double field.");
+ // }
+ // DEREF(memory, double) = Z_DVAL_P(value);
+ break;
+ case UPB_TYPE_BOOL: {
+ int8_t val = -1;
+ if (zval_is_true(value)) {
+ val = 1;
+ } else {
+ val = 0;
+ }
+ // TODO(teboring): Add it back.
+ // else if (value == Qfalse) {
+ // val = 0;
+ // }
+ // else {
+ // php_raise(php_eTypeError, "Invalid argument for boolean field.");
+ // }
+ DEREF(memory, int8_t) = val;
+ break;
+ }
+ case UPB_TYPE_STRING:
+ case UPB_TYPE_BYTES: {
+ // TODO(teboring): Add it back.
+ // if (Z_TYPE_P(value) != IS_STRING) {
+ // zend_error(E_ERROR, "Invalid argument for string field.");
+ // }
+ // native_slot_validate_string_encoding(type, value);
+ // DEREF(memory, zval*) = value;
+ break;
+ }
+ case UPB_TYPE_MESSAGE: {
+ // TODO(teboring): Add it back.
+ // if (CLASS_OF(value) == CLASS_OF(Qnil)) {
+ // value = Qnil;
+ // } else if (CLASS_OF(value) != type_class) {
+ // php_raise(php_eTypeError,
+ // "Invalid type %s to assign to submessage field.",
+ // php_class2name(CLASS_OF(value)));
+ // }
+ // DEREF(memory, VALUE) = value;
+ break;
+ }
+ case UPB_TYPE_ENUM: {
+ // TODO(teboring): Add it back.
+ // int32_t int_val = 0;
+ // if (!is_php_num(value) && TYPE(value) != T_SYMBOL) {
+ // php_raise(php_eTypeError,
+ // "Expected number or symbol type for enum field.");
+ // }
+ // if (TYPE(value) == T_SYMBOL) {
+ // // Ensure that the given symbol exists in the enum module.
+ // VALUE lookup = php_funcall(type_class, php_intern("resolve"), 1, value);
+ // if (lookup == Qnil) {
+ // php_raise(php_eRangeError, "Unknown symbol value for enum field.");
+ // } else {
+ // int_val = NUM2INT(lookup);
+ // }
+ // } else {
+ // native_slot_check_int_range_precision(UPB_TYPE_INT32, value);
+ // int_val = NUM2INT(value);
+ // }
+ // DEREF(memory, int32_t) = int_val;
+ // break;
+ }
+ case UPB_TYPE_INT32:
+ case UPB_TYPE_INT64:
+ case UPB_TYPE_UINT32:
+ case UPB_TYPE_UINT64:
+ native_slot_check_int_range_precision(type, value);
+ switch (type) {
+ case UPB_TYPE_INT32:
+ php_printf("Setting INT32 field\n");
+ DEREF(memory, int32_t) = Z_LVAL_P(value);
+ break;
+ case UPB_TYPE_INT64:
+ // TODO(teboring): Add it back.
+ // DEREF(memory, int64_t) = NUM2LL(value);
+ break;
+ case UPB_TYPE_UINT32:
+ // TODO(teboring): Add it back.
+ // DEREF(memory, uint32_t) = NUM2UINT(value);
+ break;
+ case UPB_TYPE_UINT64:
+ // TODO(teboring): Add it back.
+ // DEREF(memory, uint64_t) = NUM2ULL(value);
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (case_memory != NULL) {
+ *case_memory = case_number;
+ }
+}
+
+// -----------------------------------------------------------------------------
+// Map field utilities.
+// ----------------------------------------------------------------------------
+
+const upb_msgdef* tryget_map_entry_msgdef(const upb_fielddef* field) {
+ const upb_msgdef* subdef;
+ if (upb_fielddef_label(field) != UPB_LABEL_REPEATED ||
+ upb_fielddef_type(field) != UPB_TYPE_MESSAGE) {
+ return NULL;
+ }
+ subdef = upb_fielddef_msgsubdef(field);
+ return upb_msgdef_mapentry(subdef) ? subdef : NULL;
+}
+
+const upb_msgdef* map_entry_msgdef(const upb_fielddef* field) {
+ const upb_msgdef* subdef = tryget_map_entry_msgdef(field);
+ assert(subdef);
+ return subdef;
+}
+
+bool is_map_field(const upb_fielddef* field) {
+ return tryget_map_entry_msgdef(field) != NULL;
+}
+
+// -----------------------------------------------------------------------------
+// Memory layout management.
+// -----------------------------------------------------------------------------
+
+static size_t align_up_to(size_t offset, size_t granularity) {
+ // Granularity must be a power of two.
+ return (offset + granularity - 1) & ~(granularity - 1);
+}
+
+MessageLayout* create_layout(const upb_msgdef* msgdef) {
+ MessageLayout* layout = ALLOC(MessageLayout);
+ int nfields = upb_msgdef_numfields(msgdef);
+ upb_msg_field_iter it;
+ upb_msg_oneof_iter oit;
+ size_t off = 0;
+
+ layout->fields = ALLOC_N(MessageField, nfields);
+
+ for (upb_msg_field_begin(&it, msgdef); !upb_msg_field_done(&it);
+ upb_msg_field_next(&it)) {
+ const upb_fielddef* field = upb_msg_iter_field(&it);
+ size_t field_size;
+
+ if (upb_fielddef_containingoneof(field)) {
+ // Oneofs are handled separately below.
+ continue;
+ }
+
+ // Allocate |field_size| bytes for this field in the layout.
+ field_size = 0;
+ if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
+ field_size = sizeof(zval*);
+ } else {
+ field_size = native_slot_size(upb_fielddef_type(field));
+ }
+
+ // Align current offset up to | size | granularity.
+ off = align_up_to(off, field_size);
+ layout->fields[upb_fielddef_index(field)].offset = off;
+ layout->fields[upb_fielddef_index(field)].case_offset =
+ MESSAGE_FIELD_NO_CASE;
+ off += field_size;
+ }
+
+ // Handle oneofs now -- we iterate over oneofs specifically and allocate only
+ // one slot per oneof.
+ //
+ // We assign all value slots first, then pack the 'case' fields at the end,
+ // since in the common case (modern 64-bit platform) these are 8 bytes and 4
+ // bytes respectively and we want to avoid alignment overhead.
+ //
+ // Note that we reserve 4 bytes (a uint32) per 'case' slot because the value
+ // space for oneof cases is conceptually as wide as field tag numbers. In
+ // practice, it's unlikely that a oneof would have more than e.g. 256 or 64K
+ // members (8 or 16 bits respectively), so conceivably we could assign
+ // consecutive case numbers and then pick a smaller oneof case slot size, but
+ // the complexity to implement this indirection is probably not worthwhile.
+ for (upb_msg_oneof_begin(&oit, msgdef); !upb_msg_oneof_done(&oit);
+ upb_msg_oneof_next(&oit)) {
+ const upb_oneofdef* oneof = upb_msg_iter_oneof(&oit);
+ upb_oneof_iter fit;
+
+ // Always allocate NATIVE_SLOT_MAX_SIZE bytes, but share the slot between
+ // all fields.
+ size_t field_size = NATIVE_SLOT_MAX_SIZE;
+ // Align the offset .
+ off = align_up_to( off, field_size);
+ // Assign all fields in the oneof this same offset.
+ for (upb_oneof_begin(&fit, oneof); !upb_oneof_done(&fit);
+ upb_oneof_next(&fit)) {
+ const upb_fielddef* field = upb_oneof_iter_field(&fit);
+ layout->fields[upb_fielddef_index(field)].offset = off;
+ }
+ off += field_size;
+ }
+
+ // Now the case fields.
+ for (upb_msg_oneof_begin(&oit, msgdef); !upb_msg_oneof_done(&oit);
+ upb_msg_oneof_next(&oit)) {
+ const upb_oneofdef* oneof = upb_msg_iter_oneof(&oit);
+ upb_oneof_iter fit;
+
+ size_t field_size = sizeof(uint32_t);
+ // Align the offset .
+ off = (off + field_size - 1) & ~(field_size - 1);
+ // Assign all fields in the oneof this same offset.
+ for (upb_oneof_begin(&fit, oneof); !upb_oneof_done(&fit);
+ upb_oneof_next(&fit)) {
+ const upb_fielddef* field = upb_oneof_iter_field(&fit);
+ layout->fields[upb_fielddef_index(field)].case_offset = off;
+ }
+ off += field_size;
+ }
+
+ layout->size = off;
+
+ layout->msgdef = msgdef;
+ upb_msgdef_ref(layout->msgdef, &layout->msgdef);
+
+ return layout;
+}
+
+void free_layout(MessageLayout* layout) {
+ FREE(layout->fields);
+ upb_msgdef_unref(layout->msgdef, &layout->msgdef);
+ FREE(layout);
+}
+
+// TODO(teboring): Add it back.
+// VALUE field_type_class(const upb_fielddef* field) {
+// VALUE type_class = Qnil;
+// if (upb_fielddef_type(field) == UPB_TYPE_MESSAGE) {
+// VALUE submsgdesc = get_def_obj(upb_fielddef_subdef(field));
+// type_class = Descriptor_msgclass(submsgdesc);
+// } else if (upb_fielddef_type(field) == UPB_TYPE_ENUM) {
+// VALUE subenumdesc = get_def_obj(upb_fielddef_subdef(field));
+// type_class = EnumDescriptor_enummodule(subenumdesc);
+// }
+// return type_class;
+// }
+
+static void* slot_memory(MessageLayout* layout, const void* storage,
+ const upb_fielddef* field) {
+ return ((uint8_t*)storage) + layout->fields[upb_fielddef_index(field)].offset;
+}
+
+static uint32_t* slot_oneof_case(MessageLayout* layout, const void* storage,
+ const upb_fielddef* field) {
+ return (uint32_t*)(((uint8_t*)storage) +
+ layout->fields[upb_fielddef_index(field)].case_offset);
+}
+
+void layout_set(MessageLayout* layout, void* storage, const upb_fielddef* field,
+ zval* val) {
+ void* memory = slot_memory(layout, storage, field);
+ uint32_t* oneof_case = slot_oneof_case(layout, storage, field);
+
+ if (upb_fielddef_containingoneof(field)) {
+ if (Z_TYPE_P(val) == IS_NULL) {
+ // Assigning nil to a oneof field clears the oneof completely.
+ *oneof_case = ONEOF_CASE_NONE;
+ memset(memory, 0, NATIVE_SLOT_MAX_SIZE);
+ } else {
+ // The transition between field types for a single oneof (union) slot is
+ // somewhat complex because we need to ensure that a GC triggered at any
+ // point by a call into the Ruby VM sees a valid state for this field and
+ // does not either go off into the weeds (following what it thinks is a
+ // VALUE but is actually a different field type) or miss an object (seeing
+ // what it thinks is a primitive field but is actually a VALUE for the new
+ // field type).
+ //
+ // In order for the transition to be safe, the oneof case slot must be in
+ // sync with the value slot whenever the Ruby VM has been called. Thus, we
+ // use native_slot_set_value_and_case(), which ensures that both the value
+ // and case number are altered atomically (w.r.t. the Ruby VM).
+ native_slot_set_value_and_case(upb_fielddef_type(field),
+ /*field_type_class(field),*/ memory, val,
+ oneof_case, upb_fielddef_number(field));
+ }
+ } else if (is_map_field(field)) {
+ // TODO(teboring): Add it back.
+ // check_map_field_type(val, field);
+ // DEREF(memory, zval*) = val;
+ } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
+ // TODO(teboring): Add it back.
+ // check_repeated_field_type(val, field);
+ // DEREF(memory, zval*) = val;
+ } else {
+ native_slot_set(upb_fielddef_type(field), /*field_type_class(field),*/ memory,
+ val);
+ }
+}
+
+void layout_init(MessageLayout* layout, void* storage) {
+ upb_msg_field_iter it;
+ for (upb_msg_field_begin(&it, layout->msgdef); !upb_msg_field_done(&it);
+ upb_msg_field_next(&it)) {
+ const upb_fielddef* field = upb_msg_iter_field(&it);
+ void* memory = slot_memory(layout, storage, field);
+ uint32_t* oneof_case = slot_oneof_case(layout, storage, field);
+
+ if (upb_fielddef_containingoneof(field)) {
+ // TODO(teboring): Add it back.
+ // memset(memory, 0, NATIVE_SLOT_MAX_SIZE);
+ // *oneof_case = ONEOF_CASE_NONE;
+ } else if (is_map_field(field)) {
+ // TODO(teboring): Add it back.
+ // VALUE map = Qnil;
+
+ // const upb_fielddef* key_field = map_field_key(field);
+ // const upb_fielddef* value_field = map_field_value(field);
+ // VALUE type_class = field_type_class(value_field);
+
+ // if (type_class != Qnil) {
+ // VALUE args[3] = {
+ // fieldtype_to_php(upb_fielddef_type(key_field)),
+ // fieldtype_to_php(upb_fielddef_type(value_field)), type_class,
+ // };
+ // map = php_class_new_instance(3, args, cMap);
+ // } else {
+ // VALUE args[2] = {
+ // fieldtype_to_php(upb_fielddef_type(key_field)),
+ // fieldtype_to_php(upb_fielddef_type(value_field)),
+ // };
+ // map = php_class_new_instance(2, args, cMap);
+ // }
+
+ // DEREF(memory, VALUE) = map;
+ } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
+ // TODO(teboring): Add it back.
+ // VALUE ary = Qnil;
+
+ // VALUE type_class = field_type_class(field);
+
+ // if (type_class != Qnil) {
+ // VALUE args[2] = {
+ // fieldtype_to_php(upb_fielddef_type(field)), type_class,
+ // };
+ // ary = php_class_new_instance(2, args, cRepeatedField);
+ // } else {
+ // VALUE args[1] = {fieldtype_to_php(upb_fielddef_type(field))};
+ // ary = php_class_new_instance(1, args, cRepeatedField);
+ // }
+
+ // DEREF(memory, VALUE) = ary;
+ } else {
+ native_slot_init(upb_fielddef_type(field), memory);
+ }
+ }
+}
+
+zval* layout_get(MessageLayout* layout, const void* storage,
+ const upb_fielddef* field TSRMLS_DC) {
+ void* memory = slot_memory(layout, storage, field);
+ uint32_t* oneof_case = slot_oneof_case(layout, storage, field);
+
+ if (upb_fielddef_containingoneof(field)) {
+ if (*oneof_case != upb_fielddef_number(field)) {
+ return NULL;
+ // TODO(teboring): Add it back.
+ // return Qnil;
+ }
+ return NULL;
+ // TODO(teboring): Add it back.
+ // return native_slot_get(upb_fielddef_type(field), field_type_class(field),
+ // memory);
+ } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
+ return NULL;
+ // TODO(teboring): Add it back.
+ // return *((VALUE*)memory);
+ } else {
+ return native_slot_get(
+ upb_fielddef_type(field), /*field_type_class(field), */
+ memory TSRMLS_CC);
+ }
+}
diff --git a/php/ext/google/protobuf/test.php b/php/ext/google/protobuf/test.php
new file mode 100644
index 00000000..6bbadd48
--- /dev/null
+++ b/php/ext/google/protobuf/test.php
@@ -0,0 +1,15 @@
+<?php
+
+
+namespace Google\Protobuf;
+
+$pool = get_generated_pool();
+$pool->addMessage("TestMessage")
+ ->optional("optional_int32_a", "int32", 1)
+ ->optional("optional_int32_b", "int32", 2)
+ ->finalizeToPool()
+ ->finalize();
+
+$test_message = new \TestMessage();
+
+?>
diff --git a/php/ext/google/protobuf/upb.c b/php/ext/google/protobuf/upb.c
new file mode 100644
index 00000000..048a163a
--- /dev/null
+++ b/php/ext/google/protobuf/upb.c
@@ -0,0 +1,11990 @@
+// Amalgamated source file
+#include "upb.h"
+
+
+#include <stdlib.h>
+#include <string.h>
+
+typedef struct {
+ size_t len;
+ char str[1]; /* Null-terminated string data follows. */
+} str_t;
+
+static str_t *newstr(const char *data, size_t len) {
+ str_t *ret = malloc(sizeof(*ret) + len);
+ if (!ret) return NULL;
+ ret->len = len;
+ memcpy(ret->str, data, len);
+ ret->str[len] = '\0';
+ return ret;
+}
+
+static void freestr(str_t *s) { free(s); }
+
+/* isalpha() etc. from <ctype.h> are locale-dependent, which we don't want. */
+static bool upb_isbetween(char c, char low, char high) {
+ return c >= low && c <= high;
+}
+
+static bool upb_isletter(char c) {
+ return upb_isbetween(c, 'A', 'Z') || upb_isbetween(c, 'a', 'z') || c == '_';
+}
+
+static bool upb_isalphanum(char c) {
+ return upb_isletter(c) || upb_isbetween(c, '0', '9');
+}
+
+static bool upb_isident(const char *str, size_t len, bool full, upb_status *s) {
+ bool start = true;
+ size_t i;
+ for (i = 0; i < len; i++) {
+ char c = str[i];
+ if (c == '.') {
+ if (start || !full) {
+ upb_status_seterrf(s, "invalid name: unexpected '.' (%s)", str);
+ return false;
+ }
+ start = true;
+ } else if (start) {
+ if (!upb_isletter(c)) {
+ upb_status_seterrf(
+ s, "invalid name: path components must start with a letter (%s)",
+ str);
+ return false;
+ }
+ start = false;
+ } else {
+ if (!upb_isalphanum(c)) {
+ upb_status_seterrf(s, "invalid name: non-alphanumeric character (%s)",
+ str);
+ return false;
+ }
+ }
+ }
+ return !start;
+}
+
+
+/* upb_def ********************************************************************/
+
+upb_deftype_t upb_def_type(const upb_def *d) { return d->type; }
+
+const char *upb_def_fullname(const upb_def *d) { return d->fullname; }
+
+bool upb_def_setfullname(upb_def *def, const char *fullname, upb_status *s) {
+ assert(!upb_def_isfrozen(def));
+ if (!upb_isident(fullname, strlen(fullname), true, s)) return false;
+ free((void*)def->fullname);
+ def->fullname = upb_strdup(fullname);
+ return true;
+}
+
+upb_def *upb_def_dup(const upb_def *def, const void *o) {
+ switch (def->type) {
+ case UPB_DEF_MSG:
+ return upb_msgdef_upcast_mutable(
+ upb_msgdef_dup(upb_downcast_msgdef(def), o));
+ case UPB_DEF_FIELD:
+ return upb_fielddef_upcast_mutable(
+ upb_fielddef_dup(upb_downcast_fielddef(def), o));
+ case UPB_DEF_ENUM:
+ return upb_enumdef_upcast_mutable(
+ upb_enumdef_dup(upb_downcast_enumdef(def), o));
+ default: assert(false); return NULL;
+ }
+}
+
+static bool upb_def_init(upb_def *def, upb_deftype_t type,
+ const struct upb_refcounted_vtbl *vtbl,
+ const void *owner) {
+ if (!upb_refcounted_init(upb_def_upcast_mutable(def), vtbl, owner)) return false;
+ def->type = type;
+ def->fullname = NULL;
+ def->came_from_user = false;
+ return true;
+}
+
+static void upb_def_uninit(upb_def *def) {
+ free((void*)def->fullname);
+}
+
+static const char *msgdef_name(const upb_msgdef *m) {
+ const char *name = upb_def_fullname(upb_msgdef_upcast(m));
+ return name ? name : "(anonymous)";
+}
+
+static bool upb_validate_field(upb_fielddef *f, upb_status *s) {
+ if (upb_fielddef_name(f) == NULL || upb_fielddef_number(f) == 0) {
+ upb_status_seterrmsg(s, "fielddef must have name and number set");
+ return false;
+ }
+
+ if (!f->type_is_set_) {
+ upb_status_seterrmsg(s, "fielddef type was not initialized");
+ return false;
+ }
+
+ if (upb_fielddef_lazy(f) &&
+ upb_fielddef_descriptortype(f) != UPB_DESCRIPTOR_TYPE_MESSAGE) {
+ upb_status_seterrmsg(s,
+ "only length-delimited submessage fields may be lazy");
+ return false;
+ }
+
+ if (upb_fielddef_hassubdef(f)) {
+ const upb_def *subdef;
+
+ if (f->subdef_is_symbolic) {
+ upb_status_seterrf(s, "field '%s.%s' has not been resolved",
+ msgdef_name(f->msg.def), upb_fielddef_name(f));
+ return false;
+ }
+
+ subdef = upb_fielddef_subdef(f);
+ if (subdef == NULL) {
+ upb_status_seterrf(s, "field %s.%s is missing required subdef",
+ msgdef_name(f->msg.def), upb_fielddef_name(f));
+ return false;
+ }
+
+ if (!upb_def_isfrozen(subdef) && !subdef->came_from_user) {
+ upb_status_seterrf(s,
+ "subdef of field %s.%s is not frozen or being frozen",
+ msgdef_name(f->msg.def), upb_fielddef_name(f));
+ return false;
+ }
+ }
+
+ if (upb_fielddef_type(f) == UPB_TYPE_ENUM) {
+ bool has_default_name = upb_fielddef_enumhasdefaultstr(f);
+ bool has_default_number = upb_fielddef_enumhasdefaultint32(f);
+
+ /* Previously verified by upb_validate_enumdef(). */
+ assert(upb_enumdef_numvals(upb_fielddef_enumsubdef(f)) > 0);
+
+ /* We've already validated that we have an associated enumdef and that it
+ * has at least one member, so at least one of these should be true.
+ * Because if the user didn't set anything, we'll pick up the enum's
+ * default, but if the user *did* set something we should at least pick up
+ * the one they set (int32 or string). */
+ assert(has_default_name || has_default_number);
+
+ if (!has_default_name) {
+ upb_status_seterrf(s,
+ "enum default for field %s.%s (%d) is not in the enum",
+ msgdef_name(f->msg.def), upb_fielddef_name(f),
+ upb_fielddef_defaultint32(f));
+ return false;
+ }
+
+ if (!has_default_number) {
+ upb_status_seterrf(s,
+ "enum default for field %s.%s (%s) is not in the enum",
+ msgdef_name(f->msg.def), upb_fielddef_name(f),
+ upb_fielddef_defaultstr(f, NULL));
+ return false;
+ }
+
+ /* Lift the effective numeric default into the field's default slot, in case
+ * we were only getting it "by reference" from the enumdef. */
+ upb_fielddef_setdefaultint32(f, upb_fielddef_defaultint32(f));
+ }
+
+ /* Ensure that MapEntry submessages only appear as repeated fields, not
+ * optional/required (singular) fields. */
+ if (upb_fielddef_type(f) == UPB_TYPE_MESSAGE &&
+ upb_fielddef_msgsubdef(f) != NULL) {
+ const upb_msgdef *subdef = upb_fielddef_msgsubdef(f);
+ if (upb_msgdef_mapentry(subdef) && !upb_fielddef_isseq(f)) {
+ upb_status_seterrf(s,
+ "Field %s refers to mapentry message but is not "
+ "a repeated field",
+ upb_fielddef_name(f) ? upb_fielddef_name(f) :
+ "(unnamed)");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static bool upb_validate_enumdef(const upb_enumdef *e, upb_status *s) {
+ if (upb_enumdef_numvals(e) == 0) {
+ upb_status_seterrf(s, "enum %s has no members (must have at least one)",
+ upb_enumdef_fullname(e));
+ return false;
+ }
+
+ return true;
+}
+
+/* All submessage fields are lower than all other fields.
+ * Secondly, fields are increasing in order. */
+uint32_t field_rank(const upb_fielddef *f) {
+ uint32_t ret = upb_fielddef_number(f);
+ const uint32_t high_bit = 1 << 30;
+ assert(ret < high_bit);
+ if (!upb_fielddef_issubmsg(f))
+ ret |= high_bit;
+ return ret;
+}
+
+int cmp_fields(const void *p1, const void *p2) {
+ const upb_fielddef *f1 = *(upb_fielddef*const*)p1;
+ const upb_fielddef *f2 = *(upb_fielddef*const*)p2;
+ return field_rank(f1) - field_rank(f2);
+}
+
+static bool assign_msg_indices(upb_msgdef *m, upb_status *s) {
+ /* Sort fields. upb internally relies on UPB_TYPE_MESSAGE fields having the
+ * lowest indexes, but we do not publicly guarantee this. */
+ upb_msg_field_iter j;
+ int i;
+ uint32_t selector;
+ int n = upb_msgdef_numfields(m);
+ upb_fielddef **fields = malloc(n * sizeof(*fields));
+ if (!fields) return false;
+
+ m->submsg_field_count = 0;
+ for(i = 0, upb_msg_field_begin(&j, m);
+ !upb_msg_field_done(&j);
+ upb_msg_field_next(&j), i++) {
+ upb_fielddef *f = upb_msg_iter_field(&j);
+ assert(f->msg.def == m);
+ if (!upb_validate_field(f, s)) {
+ free(fields);
+ return false;
+ }
+ if (upb_fielddef_issubmsg(f)) {
+ m->submsg_field_count++;
+ }
+ fields[i] = f;
+ }
+
+ qsort(fields, n, sizeof(*fields), cmp_fields);
+
+ selector = UPB_STATIC_SELECTOR_COUNT + m->submsg_field_count;
+ for (i = 0; i < n; i++) {
+ upb_fielddef *f = fields[i];
+ f->index_ = i;
+ f->selector_base = selector + upb_handlers_selectorbaseoffset(f);
+ selector += upb_handlers_selectorcount(f);
+ }
+ m->selector_count = selector;
+
+#ifndef NDEBUG
+ {
+ /* Verify that all selectors for the message are distinct. */
+#define TRY(type) \
+ if (upb_handlers_getselector(f, type, &sel)) upb_inttable_insert(&t, sel, v);
+
+ upb_inttable t;
+ upb_value v;
+ upb_selector_t sel;
+
+ upb_inttable_init(&t, UPB_CTYPE_BOOL);
+ v = upb_value_bool(true);
+ upb_inttable_insert(&t, UPB_STARTMSG_SELECTOR, v);
+ upb_inttable_insert(&t, UPB_ENDMSG_SELECTOR, v);
+ for(upb_msg_field_begin(&j, m);
+ !upb_msg_field_done(&j);
+ upb_msg_field_next(&j)) {
+ upb_fielddef *f = upb_msg_iter_field(&j);
+ /* These calls will assert-fail in upb_table if the value already
+ * exists. */
+ TRY(UPB_HANDLER_INT32);
+ TRY(UPB_HANDLER_INT64)
+ TRY(UPB_HANDLER_UINT32)
+ TRY(UPB_HANDLER_UINT64)
+ TRY(UPB_HANDLER_FLOAT)
+ TRY(UPB_HANDLER_DOUBLE)
+ TRY(UPB_HANDLER_BOOL)
+ TRY(UPB_HANDLER_STARTSTR)
+ TRY(UPB_HANDLER_STRING)
+ TRY(UPB_HANDLER_ENDSTR)
+ TRY(UPB_HANDLER_STARTSUBMSG)
+ TRY(UPB_HANDLER_ENDSUBMSG)
+ TRY(UPB_HANDLER_STARTSEQ)
+ TRY(UPB_HANDLER_ENDSEQ)
+ }
+ upb_inttable_uninit(&t);
+ }
+#undef TRY
+#endif
+
+ free(fields);
+ return true;
+}
+
+bool upb_def_freeze(upb_def *const* defs, int n, upb_status *s) {
+ int i;
+ int maxdepth;
+ bool ret;
+ upb_status_clear(s);
+
+ /* First perform validation, in two passes so we can check that we have a
+ * transitive closure without needing to search. */
+ for (i = 0; i < n; i++) {
+ upb_def *def = defs[i];
+ if (upb_def_isfrozen(def)) {
+ /* Could relax this requirement if it's annoying. */
+ upb_status_seterrmsg(s, "def is already frozen");
+ goto err;
+ } else if (def->type == UPB_DEF_FIELD) {
+ upb_status_seterrmsg(s, "standalone fielddefs can not be frozen");
+ goto err;
+ } else if (def->type == UPB_DEF_ENUM) {
+ if (!upb_validate_enumdef(upb_dyncast_enumdef(def), s)) {
+ goto err;
+ }
+ } else {
+ /* Set now to detect transitive closure in the second pass. */
+ def->came_from_user = true;
+ }
+ }
+
+ /* Second pass of validation. Also assign selector bases and indexes, and
+ * compact tables. */
+ for (i = 0; i < n; i++) {
+ upb_msgdef *m = upb_dyncast_msgdef_mutable(defs[i]);
+ upb_enumdef *e = upb_dyncast_enumdef_mutable(defs[i]);
+ if (m) {
+ upb_inttable_compact(&m->itof);
+ if (!assign_msg_indices(m, s)) {
+ goto err;
+ }
+ } else if (e) {
+ upb_inttable_compact(&e->iton);
+ }
+ }
+
+ /* Def graph contains FieldDefs between each MessageDef, so double the
+ * limit. */
+ maxdepth = UPB_MAX_MESSAGE_DEPTH * 2;
+
+ /* Validation all passed; freeze the defs. */
+ ret = upb_refcounted_freeze((upb_refcounted * const *)defs, n, s, maxdepth);
+ assert(!(s && ret != upb_ok(s)));
+ return ret;
+
+err:
+ for (i = 0; i < n; i++) {
+ defs[i]->came_from_user = false;
+ }
+ assert(!(s && upb_ok(s)));
+ return false;
+}
+
+
+/* upb_enumdef ****************************************************************/
+
+static void upb_enumdef_free(upb_refcounted *r) {
+ upb_enumdef *e = (upb_enumdef*)r;
+ upb_inttable_iter i;
+ upb_inttable_begin(&i, &e->iton);
+ for( ; !upb_inttable_done(&i); upb_inttable_next(&i)) {
+ /* To clean up the upb_strdup() from upb_enumdef_addval(). */
+ free(upb_value_getcstr(upb_inttable_iter_value(&i)));
+ }
+ upb_strtable_uninit(&e->ntoi);
+ upb_inttable_uninit(&e->iton);
+ upb_def_uninit(upb_enumdef_upcast_mutable(e));
+ free(e);
+}
+
+upb_enumdef *upb_enumdef_new(const void *owner) {
+ static const struct upb_refcounted_vtbl vtbl = {NULL, &upb_enumdef_free};
+ upb_enumdef *e = malloc(sizeof(*e));
+ if (!e) return NULL;
+ if (!upb_def_init(upb_enumdef_upcast_mutable(e), UPB_DEF_ENUM, &vtbl, owner))
+ goto err2;
+ if (!upb_strtable_init(&e->ntoi, UPB_CTYPE_INT32)) goto err2;
+ if (!upb_inttable_init(&e->iton, UPB_CTYPE_CSTR)) goto err1;
+ return e;
+
+err1:
+ upb_strtable_uninit(&e->ntoi);
+err2:
+ free(e);
+ return NULL;
+}
+
+upb_enumdef *upb_enumdef_dup(const upb_enumdef *e, const void *owner) {
+ upb_enum_iter i;
+ upb_enumdef *new_e = upb_enumdef_new(owner);
+ if (!new_e) return NULL;
+ for(upb_enum_begin(&i, e); !upb_enum_done(&i); upb_enum_next(&i)) {
+ bool success = upb_enumdef_addval(
+ new_e, upb_enum_iter_name(&i),upb_enum_iter_number(&i), NULL);
+ if (!success) {
+ upb_enumdef_unref(new_e, owner);
+ return NULL;
+ }
+ }
+ return new_e;
+}
+
+bool upb_enumdef_freeze(upb_enumdef *e, upb_status *status) {
+ upb_def *d = upb_enumdef_upcast_mutable(e);
+ return upb_def_freeze(&d, 1, status);
+}
+
+const char *upb_enumdef_fullname(const upb_enumdef *e) {
+ return upb_def_fullname(upb_enumdef_upcast(e));
+}
+
+bool upb_enumdef_setfullname(upb_enumdef *e, const char *fullname,
+ upb_status *s) {
+ return upb_def_setfullname(upb_enumdef_upcast_mutable(e), fullname, s);
+}
+
+bool upb_enumdef_addval(upb_enumdef *e, const char *name, int32_t num,
+ upb_status *status) {
+ if (!upb_isident(name, strlen(name), false, status)) {
+ return false;
+ }
+ if (upb_enumdef_ntoiz(e, name, NULL)) {
+ upb_status_seterrf(status, "name '%s' is already defined", name);
+ return false;
+ }
+ if (!upb_strtable_insert(&e->ntoi, name, upb_value_int32(num))) {
+ upb_status_seterrmsg(status, "out of memory");
+ return false;
+ }
+ if (!upb_inttable_lookup(&e->iton, num, NULL) &&
+ !upb_inttable_insert(&e->iton, num, upb_value_cstr(upb_strdup(name)))) {
+ upb_status_seterrmsg(status, "out of memory");
+ upb_strtable_remove(&e->ntoi, name, NULL);
+ return false;
+ }
+ if (upb_enumdef_numvals(e) == 1) {
+ bool ok = upb_enumdef_setdefault(e, num, NULL);
+ UPB_ASSERT_VAR(ok, ok);
+ }
+ return true;
+}
+
+int32_t upb_enumdef_default(const upb_enumdef *e) {
+ assert(upb_enumdef_iton(e, e->defaultval));
+ return e->defaultval;
+}
+
+bool upb_enumdef_setdefault(upb_enumdef *e, int32_t val, upb_status *s) {
+ assert(!upb_enumdef_isfrozen(e));
+ if (!upb_enumdef_iton(e, val)) {
+ upb_status_seterrf(s, "number '%d' is not in the enum.", val);
+ return false;
+ }
+ e->defaultval = val;
+ return true;
+}
+
+int upb_enumdef_numvals(const upb_enumdef *e) {
+ return upb_strtable_count(&e->ntoi);
+}
+
+void upb_enum_begin(upb_enum_iter *i, const upb_enumdef *e) {
+ /* We iterate over the ntoi table, to account for duplicate numbers. */
+ upb_strtable_begin(i, &e->ntoi);
+}
+
+void upb_enum_next(upb_enum_iter *iter) { upb_strtable_next(iter); }
+bool upb_enum_done(upb_enum_iter *iter) { return upb_strtable_done(iter); }
+
+bool upb_enumdef_ntoi(const upb_enumdef *def, const char *name,
+ size_t len, int32_t *num) {
+ upb_value v;
+ if (!upb_strtable_lookup2(&def->ntoi, name, len, &v)) {
+ return false;
+ }
+ if (num) *num = upb_value_getint32(v);
+ return true;
+}
+
+const char *upb_enumdef_iton(const upb_enumdef *def, int32_t num) {
+ upb_value v;
+ return upb_inttable_lookup32(&def->iton, num, &v) ?
+ upb_value_getcstr(v) : NULL;
+}
+
+const char *upb_enum_iter_name(upb_enum_iter *iter) {
+ return upb_strtable_iter_key(iter);
+}
+
+int32_t upb_enum_iter_number(upb_enum_iter *iter) {
+ return upb_value_getint32(upb_strtable_iter_value(iter));
+}
+
+
+/* upb_fielddef ***************************************************************/
+
+static void upb_fielddef_init_default(upb_fielddef *f);
+
+static void upb_fielddef_uninit_default(upb_fielddef *f) {
+ if (f->type_is_set_ && f->default_is_string && f->defaultval.bytes)
+ freestr(f->defaultval.bytes);
+}
+
+static void visitfield(const upb_refcounted *r, upb_refcounted_visit *visit,
+ void *closure) {
+ const upb_fielddef *f = (const upb_fielddef*)r;
+ if (upb_fielddef_containingtype(f)) {
+ visit(r, upb_msgdef_upcast2(upb_fielddef_containingtype(f)), closure);
+ }
+ if (upb_fielddef_containingoneof(f)) {
+ visit(r, upb_oneofdef_upcast2(upb_fielddef_containingoneof(f)), closure);
+ }
+ if (upb_fielddef_subdef(f)) {
+ visit(r, upb_def_upcast(upb_fielddef_subdef(f)), closure);
+ }
+}
+
+static void freefield(upb_refcounted *r) {
+ upb_fielddef *f = (upb_fielddef*)r;
+ upb_fielddef_uninit_default(f);
+ if (f->subdef_is_symbolic)
+ free(f->sub.name);
+ upb_def_uninit(upb_fielddef_upcast_mutable(f));
+ free(f);
+}
+
+static const char *enumdefaultstr(const upb_fielddef *f) {
+ const upb_enumdef *e;
+ assert(f->type_is_set_ && f->type_ == UPB_TYPE_ENUM);
+ e = upb_fielddef_enumsubdef(f);
+ if (f->default_is_string && f->defaultval.bytes) {
+ /* Default was explicitly set as a string. */
+ str_t *s = f->defaultval.bytes;
+ return s->str;
+ } else if (e) {
+ if (!f->default_is_string) {
+ /* Default was explicitly set as an integer; look it up in enumdef. */
+ const char *name = upb_enumdef_iton(e, f->defaultval.sint);
+ if (name) {
+ return name;
+ }
+ } else {
+ /* Default is completely unset; pull enumdef default. */
+ if (upb_enumdef_numvals(e) > 0) {
+ const char *name = upb_enumdef_iton(e, upb_enumdef_default(e));
+ assert(name);
+ return name;
+ }
+ }
+ }
+ return NULL;
+}
+
+static bool enumdefaultint32(const upb_fielddef *f, int32_t *val) {
+ const upb_enumdef *e;
+ assert(f->type_is_set_ && f->type_ == UPB_TYPE_ENUM);
+ e = upb_fielddef_enumsubdef(f);
+ if (!f->default_is_string) {
+ /* Default was explicitly set as an integer. */
+ *val = f->defaultval.sint;
+ return true;
+ } else if (e) {
+ if (f->defaultval.bytes) {
+ /* Default was explicitly set as a str; try to lookup corresponding int. */
+ str_t *s = f->defaultval.bytes;
+ if (upb_enumdef_ntoiz(e, s->str, val)) {
+ return true;
+ }
+ } else {
+ /* Default is unset; try to pull in enumdef default. */
+ if (upb_enumdef_numvals(e) > 0) {
+ *val = upb_enumdef_default(e);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+upb_fielddef *upb_fielddef_new(const void *o) {
+ static const struct upb_refcounted_vtbl vtbl = {visitfield, freefield};
+ upb_fielddef *f = malloc(sizeof(*f));
+ if (!f) return NULL;
+ if (!upb_def_init(upb_fielddef_upcast_mutable(f), UPB_DEF_FIELD, &vtbl, o)) {
+ free(f);
+ return NULL;
+ }
+ f->msg.def = NULL;
+ f->sub.def = NULL;
+ f->oneof = NULL;
+ f->subdef_is_symbolic = false;
+ f->msg_is_symbolic = false;
+ f->label_ = UPB_LABEL_OPTIONAL;
+ f->type_ = UPB_TYPE_INT32;
+ f->number_ = 0;
+ f->type_is_set_ = false;
+ f->tagdelim = false;
+ f->is_extension_ = false;
+ f->lazy_ = false;
+ f->packed_ = true;
+
+ /* For the moment we default this to UPB_INTFMT_VARIABLE, since it will work
+ * with all integer types and is in some since more "default" since the most
+ * normal-looking proto2 types int32/int64/uint32/uint64 use variable.
+ *
+ * Other options to consider:
+ * - there is no default; users must set this manually (like type).
+ * - default signed integers to UPB_INTFMT_ZIGZAG, since it's more likely to
+ * be an optimal default for signed integers. */
+ f->intfmt = UPB_INTFMT_VARIABLE;
+ return f;
+}
+
+upb_fielddef *upb_fielddef_dup(const upb_fielddef *f, const void *owner) {
+ const char *srcname;
+ upb_fielddef *newf = upb_fielddef_new(owner);
+ if (!newf) return NULL;
+ upb_fielddef_settype(newf, upb_fielddef_type(f));
+ upb_fielddef_setlabel(newf, upb_fielddef_label(f));
+ upb_fielddef_setnumber(newf, upb_fielddef_number(f), NULL);
+ upb_fielddef_setname(newf, upb_fielddef_name(f), NULL);
+ if (f->default_is_string && f->defaultval.bytes) {
+ str_t *s = f->defaultval.bytes;
+ upb_fielddef_setdefaultstr(newf, s->str, s->len, NULL);
+ } else {
+ newf->default_is_string = f->default_is_string;
+ newf->defaultval = f->defaultval;
+ }
+
+ if (f->subdef_is_symbolic) {
+ srcname = f->sub.name; /* Might be NULL. */
+ } else {
+ srcname = f->sub.def ? upb_def_fullname(f->sub.def) : NULL;
+ }
+ if (srcname) {
+ char *newname = malloc(strlen(f->sub.def->fullname) + 2);
+ if (!newname) {
+ upb_fielddef_unref(newf, owner);
+ return NULL;
+ }
+ strcpy(newname, ".");
+ strcat(newname, f->sub.def->fullname);
+ upb_fielddef_setsubdefname(newf, newname, NULL);
+ free(newname);
+ }
+
+ return newf;
+}
+
+bool upb_fielddef_typeisset(const upb_fielddef *f) {
+ return f->type_is_set_;
+}
+
+upb_fieldtype_t upb_fielddef_type(const upb_fielddef *f) {
+ assert(f->type_is_set_);
+ return f->type_;
+}
+
+uint32_t upb_fielddef_index(const upb_fielddef *f) {
+ return f->index_;
+}
+
+upb_label_t upb_fielddef_label(const upb_fielddef *f) {
+ return f->label_;
+}
+
+upb_intfmt_t upb_fielddef_intfmt(const upb_fielddef *f) {
+ return f->intfmt;
+}
+
+bool upb_fielddef_istagdelim(const upb_fielddef *f) {
+ return f->tagdelim;
+}
+
+uint32_t upb_fielddef_number(const upb_fielddef *f) {
+ return f->number_;
+}
+
+bool upb_fielddef_isextension(const upb_fielddef *f) {
+ return f->is_extension_;
+}
+
+bool upb_fielddef_lazy(const upb_fielddef *f) {
+ return f->lazy_;
+}
+
+bool upb_fielddef_packed(const upb_fielddef *f) {
+ return f->packed_;
+}
+
+const char *upb_fielddef_name(const upb_fielddef *f) {
+ return upb_def_fullname(upb_fielddef_upcast(f));
+}
+
+const upb_msgdef *upb_fielddef_containingtype(const upb_fielddef *f) {
+ return f->msg_is_symbolic ? NULL : f->msg.def;
+}
+
+const upb_oneofdef *upb_fielddef_containingoneof(const upb_fielddef *f) {
+ return f->oneof;
+}
+
+upb_msgdef *upb_fielddef_containingtype_mutable(upb_fielddef *f) {
+ return (upb_msgdef*)upb_fielddef_containingtype(f);
+}
+
+const char *upb_fielddef_containingtypename(upb_fielddef *f) {
+ return f->msg_is_symbolic ? f->msg.name : NULL;
+}
+
+static void release_containingtype(upb_fielddef *f) {
+ if (f->msg_is_symbolic) free(f->msg.name);
+}
+
+bool upb_fielddef_setcontainingtypename(upb_fielddef *f, const char *name,
+ upb_status *s) {
+ assert(!upb_fielddef_isfrozen(f));
+ if (upb_fielddef_containingtype(f)) {
+ upb_status_seterrmsg(s, "field has already been added to a message.");
+ return false;
+ }
+ /* TODO: validate name (upb_isident() doesn't quite work atm because this name
+ * may have a leading "."). */
+ release_containingtype(f);
+ f->msg.name = upb_strdup(name);
+ f->msg_is_symbolic = true;
+ return true;
+}
+
+bool upb_fielddef_setname(upb_fielddef *f, const char *name, upb_status *s) {
+ if (upb_fielddef_containingtype(f) || upb_fielddef_containingoneof(f)) {
+ upb_status_seterrmsg(s, "Already added to message or oneof");
+ return false;
+ }
+ return upb_def_setfullname(upb_fielddef_upcast_mutable(f), name, s);
+}
+
+static void chkdefaulttype(const upb_fielddef *f, upb_fieldtype_t type) {
+ UPB_UNUSED(f);
+ UPB_UNUSED(type);
+ assert(f->type_is_set_ && upb_fielddef_type(f) == type);
+}
+
+int64_t upb_fielddef_defaultint64(const upb_fielddef *f) {
+ chkdefaulttype(f, UPB_TYPE_INT64);
+ return f->defaultval.sint;
+}
+
+int32_t upb_fielddef_defaultint32(const upb_fielddef *f) {
+ if (f->type_is_set_ && upb_fielddef_type(f) == UPB_TYPE_ENUM) {
+ int32_t val;
+ bool ok = enumdefaultint32(f, &val);
+ UPB_ASSERT_VAR(ok, ok);
+ return val;
+ } else {
+ chkdefaulttype(f, UPB_TYPE_INT32);
+ return f->defaultval.sint;
+ }
+}
+
+uint64_t upb_fielddef_defaultuint64(const upb_fielddef *f) {
+ chkdefaulttype(f, UPB_TYPE_UINT64);
+ return f->defaultval.uint;
+}
+
+uint32_t upb_fielddef_defaultuint32(const upb_fielddef *f) {
+ chkdefaulttype(f, UPB_TYPE_UINT32);
+ return f->defaultval.uint;
+}
+
+bool upb_fielddef_defaultbool(const upb_fielddef *f) {
+ chkdefaulttype(f, UPB_TYPE_BOOL);
+ return f->defaultval.uint;
+}
+
+float upb_fielddef_defaultfloat(const upb_fielddef *f) {
+ chkdefaulttype(f, UPB_TYPE_FLOAT);
+ return f->defaultval.flt;
+}
+
+double upb_fielddef_defaultdouble(const upb_fielddef *f) {
+ chkdefaulttype(f, UPB_TYPE_DOUBLE);
+ return f->defaultval.dbl;
+}
+
+const char *upb_fielddef_defaultstr(const upb_fielddef *f, size_t *len) {
+ assert(f->type_is_set_);
+ assert(upb_fielddef_type(f) == UPB_TYPE_STRING ||
+ upb_fielddef_type(f) == UPB_TYPE_BYTES ||
+ upb_fielddef_type(f) == UPB_TYPE_ENUM);
+
+ if (upb_fielddef_type(f) == UPB_TYPE_ENUM) {
+ const char *ret = enumdefaultstr(f);
+ assert(ret);
+ /* Enum defaults can't have embedded NULLs. */
+ if (len) *len = strlen(ret);
+ return ret;
+ }
+
+ if (f->default_is_string) {
+ str_t *str = f->defaultval.bytes;
+ if (len) *len = str->len;
+ return str->str;
+ }
+
+ return NULL;
+}
+
+static void upb_fielddef_init_default(upb_fielddef *f) {
+ f->default_is_string = false;
+ switch (upb_fielddef_type(f)) {
+ case UPB_TYPE_DOUBLE: f->defaultval.dbl = 0; break;
+ case UPB_TYPE_FLOAT: f->defaultval.flt = 0; break;
+ case UPB_TYPE_INT32:
+ case UPB_TYPE_INT64: f->defaultval.sint = 0; break;
+ case UPB_TYPE_UINT64:
+ case UPB_TYPE_UINT32:
+ case UPB_TYPE_BOOL: f->defaultval.uint = 0; break;
+ case UPB_TYPE_STRING:
+ case UPB_TYPE_BYTES:
+ f->defaultval.bytes = newstr("", 0);
+ f->default_is_string = true;
+ break;
+ case UPB_TYPE_MESSAGE: break;
+ case UPB_TYPE_ENUM:
+ /* This is our special sentinel that indicates "not set" for an enum. */
+ f->default_is_string = true;
+ f->defaultval.bytes = NULL;
+ break;
+ }
+}
+
+const upb_def *upb_fielddef_subdef(const upb_fielddef *f) {
+ return f->subdef_is_symbolic ? NULL : f->sub.def;
+}
+
+const upb_msgdef *upb_fielddef_msgsubdef(const upb_fielddef *f) {
+ const upb_def *def = upb_fielddef_subdef(f);
+ return def ? upb_dyncast_msgdef(def) : NULL;
+}
+
+const upb_enumdef *upb_fielddef_enumsubdef(const upb_fielddef *f) {
+ const upb_def *def = upb_fielddef_subdef(f);
+ return def ? upb_dyncast_enumdef(def) : NULL;
+}
+
+upb_def *upb_fielddef_subdef_mutable(upb_fielddef *f) {
+ return (upb_def*)upb_fielddef_subdef(f);
+}
+
+const char *upb_fielddef_subdefname(const upb_fielddef *f) {
+ if (f->subdef_is_symbolic) {
+ return f->sub.name;
+ } else if (f->sub.def) {
+ return upb_def_fullname(f->sub.def);
+ } else {
+ return NULL;
+ }
+}
+
+bool upb_fielddef_setnumber(upb_fielddef *f, uint32_t number, upb_status *s) {
+ if (upb_fielddef_containingtype(f)) {
+ upb_status_seterrmsg(
+ s, "cannot change field number after adding to a message");
+ return false;
+ }
+ if (number == 0 || number > UPB_MAX_FIELDNUMBER) {
+ upb_status_seterrf(s, "invalid field number (%u)", number);
+ return false;
+ }
+ f->number_ = number;
+ return true;
+}
+
+void upb_fielddef_settype(upb_fielddef *f, upb_fieldtype_t type) {
+ assert(!upb_fielddef_isfrozen(f));
+ assert(upb_fielddef_checktype(type));
+ upb_fielddef_uninit_default(f);
+ f->type_ = type;
+ f->type_is_set_ = true;
+ upb_fielddef_init_default(f);
+}
+
+void upb_fielddef_setdescriptortype(upb_fielddef *f, int type) {
+ assert(!upb_fielddef_isfrozen(f));
+ switch (type) {
+ case UPB_DESCRIPTOR_TYPE_DOUBLE:
+ upb_fielddef_settype(f, UPB_TYPE_DOUBLE);
+ break;
+ case UPB_DESCRIPTOR_TYPE_FLOAT:
+ upb_fielddef_settype(f, UPB_TYPE_FLOAT);
+ break;
+ case UPB_DESCRIPTOR_TYPE_INT64:
+ case UPB_DESCRIPTOR_TYPE_SFIXED64:
+ case UPB_DESCRIPTOR_TYPE_SINT64:
+ upb_fielddef_settype(f, UPB_TYPE_INT64);
+ break;
+ case UPB_DESCRIPTOR_TYPE_UINT64:
+ case UPB_DESCRIPTOR_TYPE_FIXED64:
+ upb_fielddef_settype(f, UPB_TYPE_UINT64);
+ break;
+ case UPB_DESCRIPTOR_TYPE_INT32:
+ case UPB_DESCRIPTOR_TYPE_SFIXED32:
+ case UPB_DESCRIPTOR_TYPE_SINT32:
+ upb_fielddef_settype(f, UPB_TYPE_INT32);
+ break;
+ case UPB_DESCRIPTOR_TYPE_UINT32:
+ case UPB_DESCRIPTOR_TYPE_FIXED32:
+ upb_fielddef_settype(f, UPB_TYPE_UINT32);
+ break;
+ case UPB_DESCRIPTOR_TYPE_BOOL:
+ upb_fielddef_settype(f, UPB_TYPE_BOOL);
+ break;
+ case UPB_DESCRIPTOR_TYPE_STRING:
+ upb_fielddef_settype(f, UPB_TYPE_STRING);
+ break;
+ case UPB_DESCRIPTOR_TYPE_BYTES:
+ upb_fielddef_settype(f, UPB_TYPE_BYTES);
+ break;
+ case UPB_DESCRIPTOR_TYPE_GROUP:
+ case UPB_DESCRIPTOR_TYPE_MESSAGE:
+ upb_fielddef_settype(f, UPB_TYPE_MESSAGE);
+ break;
+ case UPB_DESCRIPTOR_TYPE_ENUM:
+ upb_fielddef_settype(f, UPB_TYPE_ENUM);
+ break;
+ default: assert(false);
+ }
+
+ if (type == UPB_DESCRIPTOR_TYPE_FIXED64 ||
+ type == UPB_DESCRIPTOR_TYPE_FIXED32 ||
+ type == UPB_DESCRIPTOR_TYPE_SFIXED64 ||
+ type == UPB_DESCRIPTOR_TYPE_SFIXED32) {
+ upb_fielddef_setintfmt(f, UPB_INTFMT_FIXED);
+ } else if (type == UPB_DESCRIPTOR_TYPE_SINT64 ||
+ type == UPB_DESCRIPTOR_TYPE_SINT32) {
+ upb_fielddef_setintfmt(f, UPB_INTFMT_ZIGZAG);
+ } else {
+ upb_fielddef_setintfmt(f, UPB_INTFMT_VARIABLE);
+ }
+
+ upb_fielddef_settagdelim(f, type == UPB_DESCRIPTOR_TYPE_GROUP);
+}
+
+upb_descriptortype_t upb_fielddef_descriptortype(const upb_fielddef *f) {
+ switch (upb_fielddef_type(f)) {
+ case UPB_TYPE_FLOAT: return UPB_DESCRIPTOR_TYPE_FLOAT;
+ case UPB_TYPE_DOUBLE: return UPB_DESCRIPTOR_TYPE_DOUBLE;
+ case UPB_TYPE_BOOL: return UPB_DESCRIPTOR_TYPE_BOOL;
+ case UPB_TYPE_STRING: return UPB_DESCRIPTOR_TYPE_STRING;
+ case UPB_TYPE_BYTES: return UPB_DESCRIPTOR_TYPE_BYTES;
+ case UPB_TYPE_ENUM: return UPB_DESCRIPTOR_TYPE_ENUM;
+ case UPB_TYPE_INT32:
+ switch (upb_fielddef_intfmt(f)) {
+ case UPB_INTFMT_VARIABLE: return UPB_DESCRIPTOR_TYPE_INT32;
+ case UPB_INTFMT_FIXED: return UPB_DESCRIPTOR_TYPE_SFIXED32;
+ case UPB_INTFMT_ZIGZAG: return UPB_DESCRIPTOR_TYPE_SINT32;
+ }
+ case UPB_TYPE_INT64:
+ switch (upb_fielddef_intfmt(f)) {
+ case UPB_INTFMT_VARIABLE: return UPB_DESCRIPTOR_TYPE_INT64;
+ case UPB_INTFMT_FIXED: return UPB_DESCRIPTOR_TYPE_SFIXED64;
+ case UPB_INTFMT_ZIGZAG: return UPB_DESCRIPTOR_TYPE_SINT64;
+ }
+ case UPB_TYPE_UINT32:
+ switch (upb_fielddef_intfmt(f)) {
+ case UPB_INTFMT_VARIABLE: return UPB_DESCRIPTOR_TYPE_UINT32;
+ case UPB_INTFMT_FIXED: return UPB_DESCRIPTOR_TYPE_FIXED32;
+ case UPB_INTFMT_ZIGZAG: return -1;
+ }
+ case UPB_TYPE_UINT64:
+ switch (upb_fielddef_intfmt(f)) {
+ case UPB_INTFMT_VARIABLE: return UPB_DESCRIPTOR_TYPE_UINT64;
+ case UPB_INTFMT_FIXED: return UPB_DESCRIPTOR_TYPE_FIXED64;
+ case UPB_INTFMT_ZIGZAG: return -1;
+ }
+ case UPB_TYPE_MESSAGE:
+ return upb_fielddef_istagdelim(f) ?
+ UPB_DESCRIPTOR_TYPE_GROUP : UPB_DESCRIPTOR_TYPE_MESSAGE;
+ }
+ return 0;
+}
+
+void upb_fielddef_setisextension(upb_fielddef *f, bool is_extension) {
+ assert(!upb_fielddef_isfrozen(f));
+ f->is_extension_ = is_extension;
+}
+
+void upb_fielddef_setlazy(upb_fielddef *f, bool lazy) {
+ assert(!upb_fielddef_isfrozen(f));
+ f->lazy_ = lazy;
+}
+
+void upb_fielddef_setpacked(upb_fielddef *f, bool packed) {
+ assert(!upb_fielddef_isfrozen(f));
+ f->packed_ = packed;
+}
+
+void upb_fielddef_setlabel(upb_fielddef *f, upb_label_t label) {
+ assert(!upb_fielddef_isfrozen(f));
+ assert(upb_fielddef_checklabel(label));
+ f->label_ = label;
+}
+
+void upb_fielddef_setintfmt(upb_fielddef *f, upb_intfmt_t fmt) {
+ assert(!upb_fielddef_isfrozen(f));
+ assert(upb_fielddef_checkintfmt(fmt));
+ f->intfmt = fmt;
+}
+
+void upb_fielddef_settagdelim(upb_fielddef *f, bool tag_delim) {
+ assert(!upb_fielddef_isfrozen(f));
+ f->tagdelim = tag_delim;
+ f->tagdelim = tag_delim;
+}
+
+static bool checksetdefault(upb_fielddef *f, upb_fieldtype_t type) {
+ if (!f->type_is_set_ || upb_fielddef_isfrozen(f) ||
+ upb_fielddef_type(f) != type) {
+ assert(false);
+ return false;
+ }
+ if (f->default_is_string) {
+ str_t *s = f->defaultval.bytes;
+ assert(s || type == UPB_TYPE_ENUM);
+ if (s) freestr(s);
+ }
+ f->default_is_string = false;
+ return true;
+}
+
+void upb_fielddef_setdefaultint64(upb_fielddef *f, int64_t value) {
+ if (checksetdefault(f, UPB_TYPE_INT64))
+ f->defaultval.sint = value;
+}
+
+void upb_fielddef_setdefaultint32(upb_fielddef *f, int32_t value) {
+ if ((upb_fielddef_type(f) == UPB_TYPE_ENUM &&
+ checksetdefault(f, UPB_TYPE_ENUM)) ||
+ checksetdefault(f, UPB_TYPE_INT32)) {
+ f->defaultval.sint = value;
+ }
+}
+
+void upb_fielddef_setdefaultuint64(upb_fielddef *f, uint64_t value) {
+ if (checksetdefault(f, UPB_TYPE_UINT64))
+ f->defaultval.uint = value;
+}
+
+void upb_fielddef_setdefaultuint32(upb_fielddef *f, uint32_t value) {
+ if (checksetdefault(f, UPB_TYPE_UINT32))
+ f->defaultval.uint = value;
+}
+
+void upb_fielddef_setdefaultbool(upb_fielddef *f, bool value) {
+ if (checksetdefault(f, UPB_TYPE_BOOL))
+ f->defaultval.uint = value;
+}
+
+void upb_fielddef_setdefaultfloat(upb_fielddef *f, float value) {
+ if (checksetdefault(f, UPB_TYPE_FLOAT))
+ f->defaultval.flt = value;
+}
+
+void upb_fielddef_setdefaultdouble(upb_fielddef *f, double value) {
+ if (checksetdefault(f, UPB_TYPE_DOUBLE))
+ f->defaultval.dbl = value;
+}
+
+bool upb_fielddef_setdefaultstr(upb_fielddef *f, const void *str, size_t len,
+ upb_status *s) {
+ str_t *str2;
+ assert(upb_fielddef_isstring(f) || f->type_ == UPB_TYPE_ENUM);
+ if (f->type_ == UPB_TYPE_ENUM && !upb_isident(str, len, false, s))
+ return false;
+
+ if (f->default_is_string) {
+ str_t *s = f->defaultval.bytes;
+ assert(s || f->type_ == UPB_TYPE_ENUM);
+ if (s) freestr(s);
+ } else {
+ assert(f->type_ == UPB_TYPE_ENUM);
+ }
+
+ str2 = newstr(str, len);
+ f->defaultval.bytes = str2;
+ f->default_is_string = true;
+ return true;
+}
+
+void upb_fielddef_setdefaultcstr(upb_fielddef *f, const char *str,
+ upb_status *s) {
+ assert(f->type_is_set_);
+ upb_fielddef_setdefaultstr(f, str, str ? strlen(str) : 0, s);
+}
+
+bool upb_fielddef_enumhasdefaultint32(const upb_fielddef *f) {
+ int32_t val;
+ assert(f->type_is_set_ && f->type_ == UPB_TYPE_ENUM);
+ return enumdefaultint32(f, &val);
+}
+
+bool upb_fielddef_enumhasdefaultstr(const upb_fielddef *f) {
+ assert(f->type_is_set_ && f->type_ == UPB_TYPE_ENUM);
+ return enumdefaultstr(f) != NULL;
+}
+
+static bool upb_subdef_typecheck(upb_fielddef *f, const upb_def *subdef,
+ upb_status *s) {
+ if (f->type_ == UPB_TYPE_MESSAGE) {
+ if (upb_dyncast_msgdef(subdef)) return true;
+ upb_status_seterrmsg(s, "invalid subdef type for this submessage field");
+ return false;
+ } else if (f->type_ == UPB_TYPE_ENUM) {
+ if (upb_dyncast_enumdef(subdef)) return true;
+ upb_status_seterrmsg(s, "invalid subdef type for this enum field");
+ return false;
+ } else {
+ upb_status_seterrmsg(s, "only message and enum fields can have a subdef");
+ return false;
+ }
+}
+
+static void release_subdef(upb_fielddef *f) {
+ if (f->subdef_is_symbolic) {
+ free(f->sub.name);
+ } else if (f->sub.def) {
+ upb_unref2(f->sub.def, f);
+ }
+}
+
+bool upb_fielddef_setsubdef(upb_fielddef *f, const upb_def *subdef,
+ upb_status *s) {
+ assert(!upb_fielddef_isfrozen(f));
+ assert(upb_fielddef_hassubdef(f));
+ if (subdef && !upb_subdef_typecheck(f, subdef, s)) return false;
+ release_subdef(f);
+ f->sub.def = subdef;
+ f->subdef_is_symbolic = false;
+ if (f->sub.def) upb_ref2(f->sub.def, f);
+ return true;
+}
+
+bool upb_fielddef_setmsgsubdef(upb_fielddef *f, const upb_msgdef *subdef,
+ upb_status *s) {
+ return upb_fielddef_setsubdef(f, upb_msgdef_upcast(subdef), s);
+}
+
+bool upb_fielddef_setenumsubdef(upb_fielddef *f, const upb_enumdef *subdef,
+ upb_status *s) {
+ return upb_fielddef_setsubdef(f, upb_enumdef_upcast(subdef), s);
+}
+
+bool upb_fielddef_setsubdefname(upb_fielddef *f, const char *name,
+ upb_status *s) {
+ assert(!upb_fielddef_isfrozen(f));
+ if (!upb_fielddef_hassubdef(f)) {
+ upb_status_seterrmsg(s, "field type does not accept a subdef");
+ return false;
+ }
+ /* TODO: validate name (upb_isident() doesn't quite work atm because this name
+ * may have a leading "."). */
+ release_subdef(f);
+ f->sub.name = upb_strdup(name);
+ f->subdef_is_symbolic = true;
+ return true;
+}
+
+bool upb_fielddef_issubmsg(const upb_fielddef *f) {
+ return upb_fielddef_type(f) == UPB_TYPE_MESSAGE;
+}
+
+bool upb_fielddef_isstring(const upb_fielddef *f) {
+ return upb_fielddef_type(f) == UPB_TYPE_STRING ||
+ upb_fielddef_type(f) == UPB_TYPE_BYTES;
+}
+
+bool upb_fielddef_isseq(const upb_fielddef *f) {
+ return upb_fielddef_label(f) == UPB_LABEL_REPEATED;
+}
+
+bool upb_fielddef_isprimitive(const upb_fielddef *f) {
+ return !upb_fielddef_isstring(f) && !upb_fielddef_issubmsg(f);
+}
+
+bool upb_fielddef_ismap(const upb_fielddef *f) {
+ return upb_fielddef_isseq(f) && upb_fielddef_issubmsg(f) &&
+ upb_msgdef_mapentry(upb_fielddef_msgsubdef(f));
+}
+
+bool upb_fielddef_hassubdef(const upb_fielddef *f) {
+ return upb_fielddef_issubmsg(f) || upb_fielddef_type(f) == UPB_TYPE_ENUM;
+}
+
+static bool between(int32_t x, int32_t low, int32_t high) {
+ return x >= low && x <= high;
+}
+
+bool upb_fielddef_checklabel(int32_t label) { return between(label, 1, 3); }
+bool upb_fielddef_checktype(int32_t type) { return between(type, 1, 11); }
+bool upb_fielddef_checkintfmt(int32_t fmt) { return between(fmt, 1, 3); }
+
+bool upb_fielddef_checkdescriptortype(int32_t type) {
+ return between(type, 1, 18);
+}
+
+/* upb_msgdef *****************************************************************/
+
+static void visitmsg(const upb_refcounted *r, upb_refcounted_visit *visit,
+ void *closure) {
+ upb_msg_oneof_iter o;
+ const upb_msgdef *m = (const upb_msgdef*)r;
+ upb_msg_field_iter i;
+ for(upb_msg_field_begin(&i, m);
+ !upb_msg_field_done(&i);
+ upb_msg_field_next(&i)) {
+ upb_fielddef *f = upb_msg_iter_field(&i);
+ visit(r, upb_fielddef_upcast2(f), closure);
+ }
+ for(upb_msg_oneof_begin(&o, m);
+ !upb_msg_oneof_done(&o);
+ upb_msg_oneof_next(&o)) {
+ upb_oneofdef *f = upb_msg_iter_oneof(&o);
+ visit(r, upb_oneofdef_upcast2(f), closure);
+ }
+}
+
+static void freemsg(upb_refcounted *r) {
+ upb_msgdef *m = (upb_msgdef*)r;
+ upb_strtable_uninit(&m->ntoo);
+ upb_strtable_uninit(&m->ntof);
+ upb_inttable_uninit(&m->itof);
+ upb_def_uninit(upb_msgdef_upcast_mutable(m));
+ free(m);
+}
+
+upb_msgdef *upb_msgdef_new(const void *owner) {
+ static const struct upb_refcounted_vtbl vtbl = {visitmsg, freemsg};
+ upb_msgdef *m = malloc(sizeof(*m));
+ if (!m) return NULL;
+ if (!upb_def_init(upb_msgdef_upcast_mutable(m), UPB_DEF_MSG, &vtbl, owner))
+ goto err2;
+ if (!upb_inttable_init(&m->itof, UPB_CTYPE_PTR)) goto err3;
+ if (!upb_strtable_init(&m->ntof, UPB_CTYPE_PTR)) goto err2;
+ if (!upb_strtable_init(&m->ntoo, UPB_CTYPE_PTR)) goto err1;
+ m->map_entry = false;
+ return m;
+
+err1:
+ upb_strtable_uninit(&m->ntof);
+err2:
+ upb_inttable_uninit(&m->itof);
+err3:
+ free(m);
+ return NULL;
+}
+
+upb_msgdef *upb_msgdef_dup(const upb_msgdef *m, const void *owner) {
+ bool ok;
+ upb_msg_field_iter i;
+ upb_msg_oneof_iter o;
+
+ upb_msgdef *newm = upb_msgdef_new(owner);
+ if (!newm) return NULL;
+ ok = upb_def_setfullname(upb_msgdef_upcast_mutable(newm),
+ upb_def_fullname(upb_msgdef_upcast(m)),
+ NULL);
+ newm->map_entry = m->map_entry;
+ UPB_ASSERT_VAR(ok, ok);
+ for(upb_msg_field_begin(&i, m);
+ !upb_msg_field_done(&i);
+ upb_msg_field_next(&i)) {
+ upb_fielddef *f = upb_fielddef_dup(upb_msg_iter_field(&i), &f);
+ /* Fields in oneofs are dup'd below. */
+ if (upb_fielddef_containingoneof(f)) continue;
+ if (!f || !upb_msgdef_addfield(newm, f, &f, NULL)) {
+ upb_msgdef_unref(newm, owner);
+ return NULL;
+ }
+ }
+ for(upb_msg_oneof_begin(&o, m);
+ !upb_msg_oneof_done(&o);
+ upb_msg_oneof_next(&o)) {
+ upb_oneofdef *f = upb_oneofdef_dup(upb_msg_iter_oneof(&o), &f);
+ if (!f || !upb_msgdef_addoneof(newm, f, &f, NULL)) {
+ upb_msgdef_unref(newm, owner);
+ return NULL;
+ }
+ }
+ return newm;
+}
+
+bool upb_msgdef_freeze(upb_msgdef *m, upb_status *status) {
+ upb_def *d = upb_msgdef_upcast_mutable(m);
+ return upb_def_freeze(&d, 1, status);
+}
+
+const char *upb_msgdef_fullname(const upb_msgdef *m) {
+ return upb_def_fullname(upb_msgdef_upcast(m));
+}
+
+bool upb_msgdef_setfullname(upb_msgdef *m, const char *fullname,
+ upb_status *s) {
+ return upb_def_setfullname(upb_msgdef_upcast_mutable(m), fullname, s);
+}
+
+/* Helper: check that the field |f| is safe to add to msgdef |m|. Set an error
+ * on status |s| and return false if not. */
+static bool check_field_add(const upb_msgdef *m, const upb_fielddef *f,
+ upb_status *s) {
+ if (upb_fielddef_containingtype(f) != NULL) {
+ upb_status_seterrmsg(s, "fielddef already belongs to a message");
+ return false;
+ } else if (upb_fielddef_name(f) == NULL || upb_fielddef_number(f) == 0) {
+ upb_status_seterrmsg(s, "field name or number were not set");
+ return false;
+ } else if (upb_msgdef_ntofz(m, upb_fielddef_name(f)) ||
+ upb_msgdef_itof(m, upb_fielddef_number(f))) {
+ upb_status_seterrmsg(s, "duplicate field name or number for field");
+ return false;
+ }
+ return true;
+}
+
+static void add_field(upb_msgdef *m, upb_fielddef *f, const void *ref_donor) {
+ release_containingtype(f);
+ f->msg.def = m;
+ f->msg_is_symbolic = false;
+ upb_inttable_insert(&m->itof, upb_fielddef_number(f), upb_value_ptr(f));
+ upb_strtable_insert(&m->ntof, upb_fielddef_name(f), upb_value_ptr(f));
+ upb_ref2(f, m);
+ upb_ref2(m, f);
+ if (ref_donor) upb_fielddef_unref(f, ref_donor);
+}
+
+bool upb_msgdef_addfield(upb_msgdef *m, upb_fielddef *f, const void *ref_donor,
+ upb_status *s) {
+ /* TODO: extensions need to have a separate namespace, because proto2 allows a
+ * top-level extension (ie. one not in any package) to have the same name as a
+ * field from the message.
+ *
+ * This also implies that there needs to be a separate lookup-by-name method
+ * for extensions. It seems desirable for iteration to return both extensions
+ * and non-extensions though.
+ *
+ * We also need to validate that the field number is in an extension range iff
+ * it is an extension.
+ *
+ * This method is idempotent. Check if |f| is already part of this msgdef and
+ * return immediately if so. */
+ if (upb_fielddef_containingtype(f) == m) {
+ return true;
+ }
+
+ /* Check constraints for all fields before performing any action. */
+ if (!check_field_add(m, f, s)) {
+ return false;
+ } else if (upb_fielddef_containingoneof(f) != NULL) {
+ /* Fields in a oneof can only be added by adding the oneof to the msgdef. */
+ upb_status_seterrmsg(s, "fielddef is part of a oneof");
+ return false;
+ }
+
+ /* Constraint checks ok, perform the action. */
+ add_field(m, f, ref_donor);
+ return true;
+}
+
+bool upb_msgdef_addoneof(upb_msgdef *m, upb_oneofdef *o, const void *ref_donor,
+ upb_status *s) {
+ upb_oneof_iter it;
+
+ /* Check various conditions that would prevent this oneof from being added. */
+ if (upb_oneofdef_containingtype(o)) {
+ upb_status_seterrmsg(s, "oneofdef already belongs to a message");
+ return false;
+ } else if (upb_oneofdef_name(o) == NULL) {
+ upb_status_seterrmsg(s, "oneofdef name was not set");
+ return false;
+ } else if (upb_msgdef_ntooz(m, upb_oneofdef_name(o))) {
+ upb_status_seterrmsg(s, "duplicate oneof name");
+ return false;
+ }
+
+ /* Check that all of the oneof's fields do not conflict with names or numbers
+ * of fields already in the message. */
+ for (upb_oneof_begin(&it, o); !upb_oneof_done(&it); upb_oneof_next(&it)) {
+ const upb_fielddef *f = upb_oneof_iter_field(&it);
+ if (!check_field_add(m, f, s)) {
+ return false;
+ }
+ }
+
+ /* Everything checks out -- commit now. */
+
+ /* Add oneof itself first. */
+ o->parent = m;
+ upb_strtable_insert(&m->ntoo, upb_oneofdef_name(o), upb_value_ptr(o));
+ upb_ref2(o, m);
+ upb_ref2(m, o);
+
+ /* Add each field of the oneof directly to the msgdef. */
+ for (upb_oneof_begin(&it, o); !upb_oneof_done(&it); upb_oneof_next(&it)) {
+ upb_fielddef *f = upb_oneof_iter_field(&it);
+ add_field(m, f, NULL);
+ }
+
+ if (ref_donor) upb_oneofdef_unref(o, ref_donor);
+
+ return true;
+}
+
+const upb_fielddef *upb_msgdef_itof(const upb_msgdef *m, uint32_t i) {
+ upb_value val;
+ return upb_inttable_lookup32(&m->itof, i, &val) ?
+ upb_value_getptr(val) : NULL;
+}
+
+const upb_fielddef *upb_msgdef_ntof(const upb_msgdef *m, const char *name,
+ size_t len) {
+ upb_value val;
+ return upb_strtable_lookup2(&m->ntof, name, len, &val) ?
+ upb_value_getptr(val) : NULL;
+}
+
+const upb_oneofdef *upb_msgdef_ntoo(const upb_msgdef *m, const char *name,
+ size_t len) {
+ upb_value val;
+ return upb_strtable_lookup2(&m->ntoo, name, len, &val) ?
+ upb_value_getptr(val) : NULL;
+}
+
+int upb_msgdef_numfields(const upb_msgdef *m) {
+ return upb_strtable_count(&m->ntof);
+}
+
+int upb_msgdef_numoneofs(const upb_msgdef *m) {
+ return upb_strtable_count(&m->ntoo);
+}
+
+void upb_msgdef_setmapentry(upb_msgdef *m, bool map_entry) {
+ assert(!upb_msgdef_isfrozen(m));
+ m->map_entry = map_entry;
+}
+
+bool upb_msgdef_mapentry(const upb_msgdef *m) {
+ return m->map_entry;
+}
+
+void upb_msg_field_begin(upb_msg_field_iter *iter, const upb_msgdef *m) {
+ upb_inttable_begin(iter, &m->itof);
+}
+
+void upb_msg_field_next(upb_msg_field_iter *iter) { upb_inttable_next(iter); }
+
+bool upb_msg_field_done(const upb_msg_field_iter *iter) {
+ return upb_inttable_done(iter);
+}
+
+upb_fielddef *upb_msg_iter_field(const upb_msg_field_iter *iter) {
+ return (upb_fielddef*)upb_value_getptr(upb_inttable_iter_value(iter));
+}
+
+void upb_msg_field_iter_setdone(upb_msg_field_iter *iter) {
+ upb_inttable_iter_setdone(iter);
+}
+
+void upb_msg_oneof_begin(upb_msg_oneof_iter *iter, const upb_msgdef *m) {
+ upb_strtable_begin(iter, &m->ntoo);
+}
+
+void upb_msg_oneof_next(upb_msg_oneof_iter *iter) { upb_strtable_next(iter); }
+
+bool upb_msg_oneof_done(const upb_msg_oneof_iter *iter) {
+ return upb_strtable_done(iter);
+}
+
+upb_oneofdef *upb_msg_iter_oneof(const upb_msg_oneof_iter *iter) {
+ return (upb_oneofdef*)upb_value_getptr(upb_strtable_iter_value(iter));
+}
+
+void upb_msg_oneof_iter_setdone(upb_msg_oneof_iter *iter) {
+ upb_strtable_iter_setdone(iter);
+}
+
+/* upb_oneofdef ***************************************************************/
+
+static void visitoneof(const upb_refcounted *r, upb_refcounted_visit *visit,
+ void *closure) {
+ const upb_oneofdef *o = (const upb_oneofdef*)r;
+ upb_oneof_iter i;
+ for (upb_oneof_begin(&i, o); !upb_oneof_done(&i); upb_oneof_next(&i)) {
+ const upb_fielddef *f = upb_oneof_iter_field(&i);
+ visit(r, upb_fielddef_upcast2(f), closure);
+ }
+ if (o->parent) {
+ visit(r, upb_msgdef_upcast2(o->parent), closure);
+ }
+}
+
+static void freeoneof(upb_refcounted *r) {
+ upb_oneofdef *o = (upb_oneofdef*)r;
+ upb_strtable_uninit(&o->ntof);
+ upb_inttable_uninit(&o->itof);
+ upb_def_uninit(upb_oneofdef_upcast_mutable(o));
+ free(o);
+}
+
+upb_oneofdef *upb_oneofdef_new(const void *owner) {
+ static const struct upb_refcounted_vtbl vtbl = {visitoneof, freeoneof};
+ upb_oneofdef *o = malloc(sizeof(*o));
+ o->parent = NULL;
+ if (!o) return NULL;
+ if (!upb_def_init(upb_oneofdef_upcast_mutable(o), UPB_DEF_ONEOF, &vtbl,
+ owner))
+ goto err2;
+ if (!upb_inttable_init(&o->itof, UPB_CTYPE_PTR)) goto err2;
+ if (!upb_strtable_init(&o->ntof, UPB_CTYPE_PTR)) goto err1;
+ return o;
+
+err1:
+ upb_inttable_uninit(&o->itof);
+err2:
+ free(o);
+ return NULL;
+}
+
+upb_oneofdef *upb_oneofdef_dup(const upb_oneofdef *o, const void *owner) {
+ bool ok;
+ upb_oneof_iter i;
+ upb_oneofdef *newo = upb_oneofdef_new(owner);
+ if (!newo) return NULL;
+ ok = upb_def_setfullname(upb_oneofdef_upcast_mutable(newo),
+ upb_def_fullname(upb_oneofdef_upcast(o)), NULL);
+ UPB_ASSERT_VAR(ok, ok);
+ for (upb_oneof_begin(&i, o); !upb_oneof_done(&i); upb_oneof_next(&i)) {
+ upb_fielddef *f = upb_fielddef_dup(upb_oneof_iter_field(&i), &f);
+ if (!f || !upb_oneofdef_addfield(newo, f, &f, NULL)) {
+ upb_oneofdef_unref(newo, owner);
+ return NULL;
+ }
+ }
+ return newo;
+}
+
+const char *upb_oneofdef_name(const upb_oneofdef *o) {
+ return upb_def_fullname(upb_oneofdef_upcast(o));
+}
+
+bool upb_oneofdef_setname(upb_oneofdef *o, const char *fullname,
+ upb_status *s) {
+ if (upb_oneofdef_containingtype(o)) {
+ upb_status_seterrmsg(s, "oneof already added to a message");
+ return false;
+ }
+ return upb_def_setfullname(upb_oneofdef_upcast_mutable(o), fullname, s);
+}
+
+const upb_msgdef *upb_oneofdef_containingtype(const upb_oneofdef *o) {
+ return o->parent;
+}
+
+int upb_oneofdef_numfields(const upb_oneofdef *o) {
+ return upb_strtable_count(&o->ntof);
+}
+
+bool upb_oneofdef_addfield(upb_oneofdef *o, upb_fielddef *f,
+ const void *ref_donor,
+ upb_status *s) {
+ assert(!upb_oneofdef_isfrozen(o));
+ assert(!o->parent || !upb_msgdef_isfrozen(o->parent));
+
+ /* This method is idempotent. Check if |f| is already part of this oneofdef
+ * and return immediately if so. */
+ if (upb_fielddef_containingoneof(f) == o) {
+ return true;
+ }
+
+ /* The field must have an OPTIONAL label. */
+ if (upb_fielddef_label(f) != UPB_LABEL_OPTIONAL) {
+ upb_status_seterrmsg(s, "fields in oneof must have OPTIONAL label");
+ return false;
+ }
+
+ /* Check that no field with this name or number exists already in the oneof.
+ * Also check that the field is not already part of a oneof. */
+ if (upb_fielddef_name(f) == NULL || upb_fielddef_number(f) == 0) {
+ upb_status_seterrmsg(s, "field name or number were not set");
+ return false;
+ } else if (upb_oneofdef_itof(o, upb_fielddef_number(f)) ||
+ upb_oneofdef_ntofz(o, upb_fielddef_name(f))) {
+ upb_status_seterrmsg(s, "duplicate field name or number");
+ return false;
+ } else if (upb_fielddef_containingoneof(f) != NULL) {
+ upb_status_seterrmsg(s, "fielddef already belongs to a oneof");
+ return false;
+ }
+
+ /* We allow adding a field to the oneof either if the field is not part of a
+ * msgdef, or if it is and we are also part of the same msgdef. */
+ if (o->parent == NULL) {
+ /* If we're not in a msgdef, the field cannot be either. Otherwise we would
+ * need to magically add this oneof to a msgdef to remain consistent, which
+ * is surprising behavior. */
+ if (upb_fielddef_containingtype(f) != NULL) {
+ upb_status_seterrmsg(s, "fielddef already belongs to a message, but "
+ "oneof does not");
+ return false;
+ }
+ } else {
+ /* If we're in a msgdef, the user can add fields that either aren't in any
+ * msgdef (in which case they're added to our msgdef) or already a part of
+ * our msgdef. */
+ if (upb_fielddef_containingtype(f) != NULL &&
+ upb_fielddef_containingtype(f) != o->parent) {
+ upb_status_seterrmsg(s, "fielddef belongs to a different message "
+ "than oneof");
+ return false;
+ }
+ }
+
+ /* Commit phase. First add the field to our parent msgdef, if any, because
+ * that may fail; then add the field to our own tables. */
+
+ if (o->parent != NULL && upb_fielddef_containingtype(f) == NULL) {
+ if (!upb_msgdef_addfield((upb_msgdef*)o->parent, f, NULL, s)) {
+ return false;
+ }
+ }
+
+ release_containingtype(f);
+ f->oneof = o;
+ upb_inttable_insert(&o->itof, upb_fielddef_number(f), upb_value_ptr(f));
+ upb_strtable_insert(&o->ntof, upb_fielddef_name(f), upb_value_ptr(f));
+ upb_ref2(f, o);
+ upb_ref2(o, f);
+ if (ref_donor) upb_fielddef_unref(f, ref_donor);
+
+ return true;
+}
+
+const upb_fielddef *upb_oneofdef_ntof(const upb_oneofdef *o,
+ const char *name, size_t length) {
+ upb_value val;
+ return upb_strtable_lookup2(&o->ntof, name, length, &val) ?
+ upb_value_getptr(val) : NULL;
+}
+
+const upb_fielddef *upb_oneofdef_itof(const upb_oneofdef *o, uint32_t num) {
+ upb_value val;
+ return upb_inttable_lookup32(&o->itof, num, &val) ?
+ upb_value_getptr(val) : NULL;
+}
+
+void upb_oneof_begin(upb_oneof_iter *iter, const upb_oneofdef *o) {
+ upb_inttable_begin(iter, &o->itof);
+}
+
+void upb_oneof_next(upb_oneof_iter *iter) {
+ upb_inttable_next(iter);
+}
+
+bool upb_oneof_done(upb_oneof_iter *iter) {
+ return upb_inttable_done(iter);
+}
+
+upb_fielddef *upb_oneof_iter_field(const upb_oneof_iter *iter) {
+ return (upb_fielddef*)upb_value_getptr(upb_inttable_iter_value(iter));
+}
+
+void upb_oneof_iter_setdone(upb_oneof_iter *iter) {
+ upb_inttable_iter_setdone(iter);
+}
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+typedef struct cleanup_ent {
+ upb_cleanup_func *cleanup;
+ void *ud;
+ struct cleanup_ent *next;
+} cleanup_ent;
+
+static void *seeded_alloc(void *ud, void *ptr, size_t oldsize, size_t size);
+
+/* Default allocator **********************************************************/
+
+/* Just use realloc, keeping all allocated blocks in a linked list to destroy at
+ * the end. */
+
+typedef struct mem_block {
+ /* List is doubly-linked, because in cases where realloc() moves an existing
+ * block, we need to be able to remove the old pointer from the list
+ * efficiently. */
+ struct mem_block *prev, *next;
+#ifndef NDEBUG
+ size_t size; /* Doesn't include mem_block structure. */
+#endif
+} mem_block;
+
+typedef struct {
+ mem_block *head;
+} default_alloc_ud;
+
+static void *default_alloc(void *_ud, void *ptr, size_t oldsize, size_t size) {
+ default_alloc_ud *ud = _ud;
+ mem_block *from, *block;
+ void *ret;
+ UPB_UNUSED(oldsize);
+
+ from = ptr ? (void*)((char*)ptr - sizeof(mem_block)) : NULL;
+
+#ifndef NDEBUG
+ if (from) {
+ assert(oldsize <= from->size);
+ }
+#endif
+
+ /* TODO(haberman): we probably need to provide even better alignment here,
+ * like 16-byte alignment of the returned data pointer. */
+ block = realloc(from, size + sizeof(mem_block));
+ if (!block) return NULL;
+ ret = (char*)block + sizeof(*block);
+
+#ifndef NDEBUG
+ block->size = size;
+#endif
+
+ if (from) {
+ if (block != from) {
+ /* The block was moved, so pointers in next and prev blocks must be
+ * updated to its new location. */
+ if (block->next) block->next->prev = block;
+ if (block->prev) block->prev->next = block;
+ if (ud->head == from) ud->head = block;
+ }
+ } else {
+ /* Insert at head of linked list. */
+ block->prev = NULL;
+ block->next = ud->head;
+ if (block->next) block->next->prev = block;
+ ud->head = block;
+ }
+
+ return ret;
+}
+
+static void default_alloc_cleanup(void *_ud) {
+ default_alloc_ud *ud = _ud;
+ mem_block *block = ud->head;
+
+ while (block) {
+ void *to_free = block;
+ block = block->next;
+ free(to_free);
+ }
+}
+
+
+/* Standard error functions ***************************************************/
+
+static bool default_err(void *ud, const upb_status *status) {
+ UPB_UNUSED(ud);
+ UPB_UNUSED(status);
+ return false;
+}
+
+static bool write_err_to(void *ud, const upb_status *status) {
+ upb_status *copy_to = ud;
+ upb_status_copy(copy_to, status);
+ return false;
+}
+
+
+/* upb_env ********************************************************************/
+
+void upb_env_init(upb_env *e) {
+ default_alloc_ud *ud = (default_alloc_ud*)&e->default_alloc_ud;
+ e->ok_ = true;
+ e->bytes_allocated = 0;
+ e->cleanup_head = NULL;
+
+ ud->head = NULL;
+
+ /* Set default functions. */
+ upb_env_setallocfunc(e, default_alloc, ud);
+ upb_env_seterrorfunc(e, default_err, NULL);
+}
+
+void upb_env_uninit(upb_env *e) {
+ cleanup_ent *ent = e->cleanup_head;
+
+ while (ent) {
+ ent->cleanup(ent->ud);
+ ent = ent->next;
+ }
+
+ /* Must do this after running cleanup functions, because this will delete
+ the memory we store our cleanup entries in! */
+ if (e->alloc == default_alloc) {
+ default_alloc_cleanup(e->alloc_ud);
+ }
+}
+
+UPB_FORCEINLINE void upb_env_setallocfunc(upb_env *e, upb_alloc_func *alloc,
+ void *ud) {
+ e->alloc = alloc;
+ e->alloc_ud = ud;
+}
+
+UPB_FORCEINLINE void upb_env_seterrorfunc(upb_env *e, upb_error_func *func,
+ void *ud) {
+ e->err = func;
+ e->err_ud = ud;
+}
+
+void upb_env_reporterrorsto(upb_env *e, upb_status *status) {
+ e->err = write_err_to;
+ e->err_ud = status;
+}
+
+bool upb_env_ok(const upb_env *e) {
+ return e->ok_;
+}
+
+bool upb_env_reporterror(upb_env *e, const upb_status *status) {
+ e->ok_ = false;
+ return e->err(e->err_ud, status);
+}
+
+bool upb_env_addcleanup(upb_env *e, upb_cleanup_func *func, void *ud) {
+ cleanup_ent *ent = upb_env_malloc(e, sizeof(cleanup_ent));
+ if (!ent) return false;
+
+ ent->cleanup = func;
+ ent->ud = ud;
+ ent->next = e->cleanup_head;
+ e->cleanup_head = ent;
+
+ return true;
+}
+
+void *upb_env_malloc(upb_env *e, size_t size) {
+ e->bytes_allocated += size;
+ if (e->alloc == seeded_alloc) {
+ /* This is equivalent to the next branch, but allows inlining for a
+ * measurable perf benefit. */
+ return seeded_alloc(e->alloc_ud, NULL, 0, size);
+ } else {
+ return e->alloc(e->alloc_ud, NULL, 0, size);
+ }
+}
+
+void *upb_env_realloc(upb_env *e, void *ptr, size_t oldsize, size_t size) {
+ char *ret;
+ assert(oldsize <= size);
+ ret = e->alloc(e->alloc_ud, ptr, oldsize, size);
+
+#ifndef NDEBUG
+ /* Overwrite non-preserved memory to ensure callers are passing the oldsize
+ * that they truly require. */
+ memset(ret + oldsize, 0xff, size - oldsize);
+#endif
+
+ return ret;
+}
+
+size_t upb_env_bytesallocated(const upb_env *e) {
+ return e->bytes_allocated;
+}
+
+
+/* upb_seededalloc ************************************************************/
+
+/* Be conservative and choose 16 in case anyone is using SSE. */
+static const size_t maxalign = 16;
+
+static size_t align_up(size_t size) {
+ return ((size + maxalign - 1) / maxalign) * maxalign;
+}
+
+UPB_FORCEINLINE static void *seeded_alloc(void *ud, void *ptr, size_t oldsize,
+ size_t size) {
+ upb_seededalloc *a = ud;
+
+ size = align_up(size);
+
+ assert(a->mem_limit >= a->mem_ptr);
+
+ if (oldsize == 0 && size <= (size_t)(a->mem_limit - a->mem_ptr)) {
+ /* Fast path: we can satisfy from the initial allocation. */
+ void *ret = a->mem_ptr;
+ a->mem_ptr += size;
+ return ret;
+ } else {
+ char *chptr = ptr;
+ /* Slow path: fallback to other allocator. */
+ a->need_cleanup = true;
+ /* Is `ptr` part of the user-provided initial block? Don't pass it to the
+ * default allocator if so; otherwise, it may try to realloc() the block. */
+ if (chptr >= a->mem_base && chptr < a->mem_limit) {
+ void *ret;
+ assert(chptr + oldsize <= a->mem_limit);
+ ret = a->alloc(a->alloc_ud, NULL, 0, size);
+ if (ret) memcpy(ret, ptr, oldsize);
+ return ret;
+ } else {
+ return a->alloc(a->alloc_ud, ptr, oldsize, size);
+ }
+ }
+}
+
+void upb_seededalloc_init(upb_seededalloc *a, void *mem, size_t len) {
+ default_alloc_ud *ud = (default_alloc_ud*)&a->default_alloc_ud;
+ a->mem_base = mem;
+ a->mem_ptr = mem;
+ a->mem_limit = (char*)mem + len;
+ a->need_cleanup = false;
+ a->returned_allocfunc = false;
+
+ ud->head = NULL;
+
+ upb_seededalloc_setfallbackalloc(a, default_alloc, ud);
+}
+
+void upb_seededalloc_uninit(upb_seededalloc *a) {
+ if (a->alloc == default_alloc && a->need_cleanup) {
+ default_alloc_cleanup(a->alloc_ud);
+ }
+}
+
+UPB_FORCEINLINE void upb_seededalloc_setfallbackalloc(upb_seededalloc *a,
+ upb_alloc_func *alloc,
+ void *ud) {
+ assert(!a->returned_allocfunc);
+ a->alloc = alloc;
+ a->alloc_ud = ud;
+}
+
+upb_alloc_func *upb_seededalloc_getallocfunc(upb_seededalloc *a) {
+ a->returned_allocfunc = true;
+ return seeded_alloc;
+}
+/*
+** TODO(haberman): it's unclear whether a lot of the consistency checks should
+** assert() or return false.
+*/
+
+
+#include <stdlib.h>
+#include <string.h>
+
+
+
+/* Defined for the sole purpose of having a unique pointer value for
+ * UPB_NO_CLOSURE. */
+char _upb_noclosure;
+
+static void freehandlers(upb_refcounted *r) {
+ upb_handlers *h = (upb_handlers*)r;
+
+ upb_inttable_iter i;
+ upb_inttable_begin(&i, &h->cleanup_);
+ for(; !upb_inttable_done(&i); upb_inttable_next(&i)) {
+ void *val = (void*)upb_inttable_iter_key(&i);
+ upb_value func_val = upb_inttable_iter_value(&i);
+ upb_handlerfree *func = upb_value_getfptr(func_val);
+ func(val);
+ }
+
+ upb_inttable_uninit(&h->cleanup_);
+ upb_msgdef_unref(h->msg, h);
+ free(h->sub);
+ free(h);
+}
+
+static void visithandlers(const upb_refcounted *r, upb_refcounted_visit *visit,
+ void *closure) {
+ const upb_handlers *h = (const upb_handlers*)r;
+ upb_msg_field_iter i;
+ for(upb_msg_field_begin(&i, h->msg);
+ !upb_msg_field_done(&i);
+ upb_msg_field_next(&i)) {
+ upb_fielddef *f = upb_msg_iter_field(&i);
+ const upb_handlers *sub;
+ if (!upb_fielddef_issubmsg(f)) continue;
+ sub = upb_handlers_getsubhandlers(h, f);
+ if (sub) visit(r, upb_handlers_upcast(sub), closure);
+ }
+}
+
+static const struct upb_refcounted_vtbl vtbl = {visithandlers, freehandlers};
+
+typedef struct {
+ upb_inttable tab; /* maps upb_msgdef* -> upb_handlers*. */
+ upb_handlers_callback *callback;
+ const void *closure;
+} dfs_state;
+
+/* TODO(haberman): discard upb_handlers* objects that do not actually have any
+ * handlers set and cannot reach any upb_handlers* object that does. This is
+ * slightly tricky to do correctly. */
+static upb_handlers *newformsg(const upb_msgdef *m, const void *owner,
+ dfs_state *s) {
+ upb_msg_field_iter i;
+ upb_handlers *h = upb_handlers_new(m, owner);
+ if (!h) return NULL;
+ if (!upb_inttable_insertptr(&s->tab, m, upb_value_ptr(h))) goto oom;
+
+ s->callback(s->closure, h);
+
+ /* For each submessage field, get or create a handlers object and set it as
+ * the subhandlers. */
+ for(upb_msg_field_begin(&i, m);
+ !upb_msg_field_done(&i);
+ upb_msg_field_next(&i)) {
+ upb_fielddef *f = upb_msg_iter_field(&i);
+ const upb_msgdef *subdef;
+ upb_value subm_ent;
+
+ if (!upb_fielddef_issubmsg(f)) continue;
+
+ subdef = upb_downcast_msgdef(upb_fielddef_subdef(f));
+ if (upb_inttable_lookupptr(&s->tab, subdef, &subm_ent)) {
+ upb_handlers_setsubhandlers(h, f, upb_value_getptr(subm_ent));
+ } else {
+ upb_handlers *sub_mh = newformsg(subdef, &sub_mh, s);
+ if (!sub_mh) goto oom;
+ upb_handlers_setsubhandlers(h, f, sub_mh);
+ upb_handlers_unref(sub_mh, &sub_mh);
+ }
+ }
+ return h;
+
+oom:
+ upb_handlers_unref(h, owner);
+ return NULL;
+}
+
+/* Given a selector for a STARTSUBMSG handler, resolves to a pointer to the
+ * subhandlers for this submessage field. */
+#define SUBH(h, selector) (h->sub[selector])
+
+/* The selector for a submessage field is the field index. */
+#define SUBH_F(h, f) SUBH(h, f->index_)
+
+static int32_t trygetsel(upb_handlers *h, const upb_fielddef *f,
+ upb_handlertype_t type) {
+ upb_selector_t sel;
+ assert(!upb_handlers_isfrozen(h));
+ if (upb_handlers_msgdef(h) != upb_fielddef_containingtype(f)) {
+ upb_status_seterrf(
+ &h->status_, "type mismatch: field %s does not belong to message %s",
+ upb_fielddef_name(f), upb_msgdef_fullname(upb_handlers_msgdef(h)));
+ return -1;
+ }
+ if (!upb_handlers_getselector(f, type, &sel)) {
+ upb_status_seterrf(
+ &h->status_,
+ "type mismatch: cannot register handler type %d for field %s",
+ type, upb_fielddef_name(f));
+ return -1;
+ }
+ return sel;
+}
+
+static upb_selector_t handlers_getsel(upb_handlers *h, const upb_fielddef *f,
+ upb_handlertype_t type) {
+ int32_t sel = trygetsel(h, f, type);
+ assert(sel >= 0);
+ return sel;
+}
+
+static const void **returntype(upb_handlers *h, const upb_fielddef *f,
+ upb_handlertype_t type) {
+ return &h->table[handlers_getsel(h, f, type)].attr.return_closure_type_;
+}
+
+static bool doset(upb_handlers *h, int32_t sel, const upb_fielddef *f,
+ upb_handlertype_t type, upb_func *func,
+ upb_handlerattr *attr) {
+ upb_handlerattr set_attr = UPB_HANDLERATTR_INITIALIZER;
+ const void *closure_type;
+ const void **context_closure_type;
+
+ assert(!upb_handlers_isfrozen(h));
+
+ if (sel < 0) {
+ upb_status_seterrmsg(&h->status_,
+ "incorrect handler type for this field.");
+ return false;
+ }
+
+ if (h->table[sel].func) {
+ upb_status_seterrmsg(&h->status_,
+ "cannot change handler once it has been set.");
+ return false;
+ }
+
+ if (attr) {
+ set_attr = *attr;
+ }
+
+ /* Check that the given closure type matches the closure type that has been
+ * established for this context (if any). */
+ closure_type = upb_handlerattr_closuretype(&set_attr);
+
+ if (type == UPB_HANDLER_STRING) {
+ context_closure_type = returntype(h, f, UPB_HANDLER_STARTSTR);
+ } else if (f && upb_fielddef_isseq(f) &&
+ type != UPB_HANDLER_STARTSEQ &&
+ type != UPB_HANDLER_ENDSEQ) {
+ context_closure_type = returntype(h, f, UPB_HANDLER_STARTSEQ);
+ } else {
+ context_closure_type = &h->top_closure_type;
+ }
+
+ if (closure_type && *context_closure_type &&
+ closure_type != *context_closure_type) {
+ /* TODO(haberman): better message for debugging. */
+ if (f) {
+ upb_status_seterrf(&h->status_,
+ "closure type does not match for field %s",
+ upb_fielddef_name(f));
+ } else {
+ upb_status_seterrmsg(
+ &h->status_, "closure type does not match for message-level handler");
+ }
+ return false;
+ }
+
+ if (closure_type)
+ *context_closure_type = closure_type;
+
+ /* If this is a STARTSEQ or STARTSTR handler, check that the returned pointer
+ * matches any pre-existing expectations about what type is expected. */
+ if (type == UPB_HANDLER_STARTSEQ || type == UPB_HANDLER_STARTSTR) {
+ const void *return_type = upb_handlerattr_returnclosuretype(&set_attr);
+ const void *table_return_type =
+ upb_handlerattr_returnclosuretype(&h->table[sel].attr);
+ if (return_type && table_return_type && return_type != table_return_type) {
+ upb_status_seterrmsg(&h->status_, "closure return type does not match");
+ return false;
+ }
+
+ if (table_return_type && !return_type)
+ upb_handlerattr_setreturnclosuretype(&set_attr, table_return_type);
+ }
+
+ h->table[sel].func = (upb_func*)func;
+ h->table[sel].attr = set_attr;
+ return true;
+}
+
+/* Returns the effective closure type for this handler (which will propagate
+ * from outer frames if this frame has no START* handler). Not implemented for
+ * UPB_HANDLER_STRING at the moment since this is not needed. Returns NULL is
+ * the effective closure type is unspecified (either no handler was registered
+ * to specify it or the handler that was registered did not specify the closure
+ * type). */
+const void *effective_closure_type(upb_handlers *h, const upb_fielddef *f,
+ upb_handlertype_t type) {
+ const void *ret;
+ upb_selector_t sel;
+
+ assert(type != UPB_HANDLER_STRING);
+ ret = h->top_closure_type;
+
+ if (upb_fielddef_isseq(f) &&
+ type != UPB_HANDLER_STARTSEQ &&
+ type != UPB_HANDLER_ENDSEQ &&
+ h->table[sel = handlers_getsel(h, f, UPB_HANDLER_STARTSEQ)].func) {
+ ret = upb_handlerattr_returnclosuretype(&h->table[sel].attr);
+ }
+
+ if (type == UPB_HANDLER_STRING &&
+ h->table[sel = handlers_getsel(h, f, UPB_HANDLER_STARTSTR)].func) {
+ ret = upb_handlerattr_returnclosuretype(&h->table[sel].attr);
+ }
+
+ /* The effective type of the submessage; not used yet.
+ * if (type == SUBMESSAGE &&
+ * h->table[sel = handlers_getsel(h, f, UPB_HANDLER_STARTSUBMSG)].func) {
+ * ret = upb_handlerattr_returnclosuretype(&h->table[sel].attr);
+ * } */
+
+ return ret;
+}
+
+/* Checks whether the START* handler specified by f & type is missing even
+ * though it is required to convert the established type of an outer frame
+ * ("closure_type") into the established type of an inner frame (represented in
+ * the return closure type of this handler's attr. */
+bool checkstart(upb_handlers *h, const upb_fielddef *f, upb_handlertype_t type,
+ upb_status *status) {
+ const void *closure_type;
+ const upb_handlerattr *attr;
+ const void *return_closure_type;
+
+ upb_selector_t sel = handlers_getsel(h, f, type);
+ if (h->table[sel].func) return true;
+ closure_type = effective_closure_type(h, f, type);
+ attr = &h->table[sel].attr;
+ return_closure_type = upb_handlerattr_returnclosuretype(attr);
+ if (closure_type && return_closure_type &&
+ closure_type != return_closure_type) {
+ upb_status_seterrf(status,
+ "expected start handler to return sub type for field %f",
+ upb_fielddef_name(f));
+ return false;
+ }
+ return true;
+}
+
+/* Public interface ***********************************************************/
+
+upb_handlers *upb_handlers_new(const upb_msgdef *md, const void *owner) {
+ int extra;
+ upb_handlers *h;
+
+ assert(upb_msgdef_isfrozen(md));
+
+ extra = sizeof(upb_handlers_tabent) * (md->selector_count - 1);
+ h = calloc(sizeof(*h) + extra, 1);
+ if (!h) return NULL;
+
+ h->msg = md;
+ upb_msgdef_ref(h->msg, h);
+ upb_status_clear(&h->status_);
+ h->sub = calloc(md->submsg_field_count, sizeof(*h->sub));
+ if (!h->sub) goto oom;
+ if (!upb_refcounted_init(upb_handlers_upcast_mutable(h), &vtbl, owner))
+ goto oom;
+ if (!upb_inttable_init(&h->cleanup_, UPB_CTYPE_FPTR)) goto oom;
+
+ /* calloc() above initialized all handlers to NULL. */
+ return h;
+
+oom:
+ freehandlers(upb_handlers_upcast_mutable(h));
+ return NULL;
+}
+
+const upb_handlers *upb_handlers_newfrozen(const upb_msgdef *m,
+ const void *owner,
+ upb_handlers_callback *callback,
+ const void *closure) {
+ dfs_state state;
+ upb_handlers *ret;
+ bool ok;
+ upb_refcounted *r;
+
+ state.callback = callback;
+ state.closure = closure;
+ if (!upb_inttable_init(&state.tab, UPB_CTYPE_PTR)) return NULL;
+
+ ret = newformsg(m, owner, &state);
+
+ upb_inttable_uninit(&state.tab);
+ if (!ret) return NULL;
+
+ r = upb_handlers_upcast_mutable(ret);
+ ok = upb_refcounted_freeze(&r, 1, NULL, UPB_MAX_HANDLER_DEPTH);
+ UPB_ASSERT_VAR(ok, ok);
+
+ return ret;
+}
+
+const upb_status *upb_handlers_status(upb_handlers *h) {
+ assert(!upb_handlers_isfrozen(h));
+ return &h->status_;
+}
+
+void upb_handlers_clearerr(upb_handlers *h) {
+ assert(!upb_handlers_isfrozen(h));
+ upb_status_clear(&h->status_);
+}
+
+#define SETTER(name, handlerctype, handlertype) \
+ bool upb_handlers_set ## name(upb_handlers *h, const upb_fielddef *f, \
+ handlerctype func, upb_handlerattr *attr) { \
+ int32_t sel = trygetsel(h, f, handlertype); \
+ return doset(h, sel, f, handlertype, (upb_func*)func, attr); \
+ }
+
+SETTER(int32, upb_int32_handlerfunc*, UPB_HANDLER_INT32)
+SETTER(int64, upb_int64_handlerfunc*, UPB_HANDLER_INT64)
+SETTER(uint32, upb_uint32_handlerfunc*, UPB_HANDLER_UINT32)
+SETTER(uint64, upb_uint64_handlerfunc*, UPB_HANDLER_UINT64)
+SETTER(float, upb_float_handlerfunc*, UPB_HANDLER_FLOAT)
+SETTER(double, upb_double_handlerfunc*, UPB_HANDLER_DOUBLE)
+SETTER(bool, upb_bool_handlerfunc*, UPB_HANDLER_BOOL)
+SETTER(startstr, upb_startstr_handlerfunc*, UPB_HANDLER_STARTSTR)
+SETTER(string, upb_string_handlerfunc*, UPB_HANDLER_STRING)
+SETTER(endstr, upb_endfield_handlerfunc*, UPB_HANDLER_ENDSTR)
+SETTER(startseq, upb_startfield_handlerfunc*, UPB_HANDLER_STARTSEQ)
+SETTER(startsubmsg, upb_startfield_handlerfunc*, UPB_HANDLER_STARTSUBMSG)
+SETTER(endsubmsg, upb_endfield_handlerfunc*, UPB_HANDLER_ENDSUBMSG)
+SETTER(endseq, upb_endfield_handlerfunc*, UPB_HANDLER_ENDSEQ)
+
+#undef SETTER
+
+bool upb_handlers_setstartmsg(upb_handlers *h, upb_startmsg_handlerfunc *func,
+ upb_handlerattr *attr) {
+ return doset(h, UPB_STARTMSG_SELECTOR, NULL, UPB_HANDLER_INT32,
+ (upb_func *)func, attr);
+}
+
+bool upb_handlers_setendmsg(upb_handlers *h, upb_endmsg_handlerfunc *func,
+ upb_handlerattr *attr) {
+ assert(!upb_handlers_isfrozen(h));
+ return doset(h, UPB_ENDMSG_SELECTOR, NULL, UPB_HANDLER_INT32,
+ (upb_func *)func, attr);
+}
+
+bool upb_handlers_setsubhandlers(upb_handlers *h, const upb_fielddef *f,
+ const upb_handlers *sub) {
+ assert(sub);
+ assert(!upb_handlers_isfrozen(h));
+ assert(upb_fielddef_issubmsg(f));
+ if (SUBH_F(h, f)) return false; /* Can't reset. */
+ if (upb_msgdef_upcast(upb_handlers_msgdef(sub)) != upb_fielddef_subdef(f)) {
+ return false;
+ }
+ SUBH_F(h, f) = sub;
+ upb_ref2(sub, h);
+ return true;
+}
+
+const upb_handlers *upb_handlers_getsubhandlers(const upb_handlers *h,
+ const upb_fielddef *f) {
+ assert(upb_fielddef_issubmsg(f));
+ return SUBH_F(h, f);
+}
+
+bool upb_handlers_getattr(const upb_handlers *h, upb_selector_t sel,
+ upb_handlerattr *attr) {
+ if (!upb_handlers_gethandler(h, sel))
+ return false;
+ *attr = h->table[sel].attr;
+ return true;
+}
+
+const upb_handlers *upb_handlers_getsubhandlers_sel(const upb_handlers *h,
+ upb_selector_t sel) {
+ /* STARTSUBMSG selector in sel is the field's selector base. */
+ return SUBH(h, sel - UPB_STATIC_SELECTOR_COUNT);
+}
+
+const upb_msgdef *upb_handlers_msgdef(const upb_handlers *h) { return h->msg; }
+
+bool upb_handlers_addcleanup(upb_handlers *h, void *p, upb_handlerfree *func) {
+ bool ok;
+ if (upb_inttable_lookupptr(&h->cleanup_, p, NULL)) {
+ return false;
+ }
+ ok = upb_inttable_insertptr(&h->cleanup_, p, upb_value_fptr(func));
+ UPB_ASSERT_VAR(ok, ok);
+ return true;
+}
+
+
+/* "Static" methods ***********************************************************/
+
+bool upb_handlers_freeze(upb_handlers *const*handlers, int n, upb_status *s) {
+ /* TODO: verify we have a transitive closure. */
+ int i;
+ for (i = 0; i < n; i++) {
+ upb_msg_field_iter j;
+ upb_handlers *h = handlers[i];
+
+ if (!upb_ok(&h->status_)) {
+ upb_status_seterrf(s, "handlers for message %s had error status: %s",
+ upb_msgdef_fullname(upb_handlers_msgdef(h)),
+ upb_status_errmsg(&h->status_));
+ return false;
+ }
+
+ /* Check that there are no closure mismatches due to missing Start* handlers
+ * or subhandlers with different type-level types. */
+ for(upb_msg_field_begin(&j, h->msg);
+ !upb_msg_field_done(&j);
+ upb_msg_field_next(&j)) {
+
+ const upb_fielddef *f = upb_msg_iter_field(&j);
+ if (upb_fielddef_isseq(f)) {
+ if (!checkstart(h, f, UPB_HANDLER_STARTSEQ, s))
+ return false;
+ }
+
+ if (upb_fielddef_isstring(f)) {
+ if (!checkstart(h, f, UPB_HANDLER_STARTSTR, s))
+ return false;
+ }
+
+ if (upb_fielddef_issubmsg(f)) {
+ bool hashandler = false;
+ if (upb_handlers_gethandler(
+ h, handlers_getsel(h, f, UPB_HANDLER_STARTSUBMSG)) ||
+ upb_handlers_gethandler(
+ h, handlers_getsel(h, f, UPB_HANDLER_ENDSUBMSG))) {
+ hashandler = true;
+ }
+
+ if (upb_fielddef_isseq(f) &&
+ (upb_handlers_gethandler(
+ h, handlers_getsel(h, f, UPB_HANDLER_STARTSEQ)) ||
+ upb_handlers_gethandler(
+ h, handlers_getsel(h, f, UPB_HANDLER_ENDSEQ)))) {
+ hashandler = true;
+ }
+
+ if (hashandler && !upb_handlers_getsubhandlers(h, f)) {
+ /* For now we add an empty subhandlers in this case. It makes the
+ * decoder code generator simpler, because it only has to handle two
+ * cases (submessage has handlers or not) as opposed to three
+ * (submessage has handlers in enclosing message but no subhandlers).
+ *
+ * This makes parsing less efficient in the case that we want to
+ * notice a submessage but skip its contents (like if we're testing
+ * for submessage presence or counting the number of repeated
+ * submessages). In this case we will end up parsing the submessage
+ * field by field and throwing away the results for each, instead of
+ * skipping the whole delimited thing at once. If this is an issue we
+ * can revisit it, but do remember that this only arises when you have
+ * handlers (startseq/startsubmsg/endsubmsg/endseq) set for the
+ * submessage but no subhandlers. The uses cases for this are
+ * limited. */
+ upb_handlers *sub = upb_handlers_new(upb_fielddef_msgsubdef(f), &sub);
+ upb_handlers_setsubhandlers(h, f, sub);
+ upb_handlers_unref(sub, &sub);
+ }
+
+ /* TODO(haberman): check type of submessage.
+ * This is slightly tricky; also consider whether we should check that
+ * they match at setsubhandlers time. */
+ }
+ }
+ }
+
+ if (!upb_refcounted_freeze((upb_refcounted*const*)handlers, n, s,
+ UPB_MAX_HANDLER_DEPTH)) {
+ return false;
+ }
+
+ return true;
+}
+
+upb_handlertype_t upb_handlers_getprimitivehandlertype(const upb_fielddef *f) {
+ switch (upb_fielddef_type(f)) {
+ case UPB_TYPE_INT32:
+ case UPB_TYPE_ENUM: return UPB_HANDLER_INT32;
+ case UPB_TYPE_INT64: return UPB_HANDLER_INT64;
+ case UPB_TYPE_UINT32: return UPB_HANDLER_UINT32;
+ case UPB_TYPE_UINT64: return UPB_HANDLER_UINT64;
+ case UPB_TYPE_FLOAT: return UPB_HANDLER_FLOAT;
+ case UPB_TYPE_DOUBLE: return UPB_HANDLER_DOUBLE;
+ case UPB_TYPE_BOOL: return UPB_HANDLER_BOOL;
+ default: assert(false); return -1; /* Invalid input. */
+ }
+}
+
+bool upb_handlers_getselector(const upb_fielddef *f, upb_handlertype_t type,
+ upb_selector_t *s) {
+ switch (type) {
+ case UPB_HANDLER_INT32:
+ case UPB_HANDLER_INT64:
+ case UPB_HANDLER_UINT32:
+ case UPB_HANDLER_UINT64:
+ case UPB_HANDLER_FLOAT:
+ case UPB_HANDLER_DOUBLE:
+ case UPB_HANDLER_BOOL:
+ if (!upb_fielddef_isprimitive(f) ||
+ upb_handlers_getprimitivehandlertype(f) != type)
+ return false;
+ *s = f->selector_base;
+ break;
+ case UPB_HANDLER_STRING:
+ if (upb_fielddef_isstring(f)) {
+ *s = f->selector_base;
+ } else if (upb_fielddef_lazy(f)) {
+ *s = f->selector_base + 3;
+ } else {
+ return false;
+ }
+ break;
+ case UPB_HANDLER_STARTSTR:
+ if (upb_fielddef_isstring(f) || upb_fielddef_lazy(f)) {
+ *s = f->selector_base + 1;
+ } else {
+ return false;
+ }
+ break;
+ case UPB_HANDLER_ENDSTR:
+ if (upb_fielddef_isstring(f) || upb_fielddef_lazy(f)) {
+ *s = f->selector_base + 2;
+ } else {
+ return false;
+ }
+ break;
+ case UPB_HANDLER_STARTSEQ:
+ if (!upb_fielddef_isseq(f)) return false;
+ *s = f->selector_base - 2;
+ break;
+ case UPB_HANDLER_ENDSEQ:
+ if (!upb_fielddef_isseq(f)) return false;
+ *s = f->selector_base - 1;
+ break;
+ case UPB_HANDLER_STARTSUBMSG:
+ if (!upb_fielddef_issubmsg(f)) return false;
+ /* Selectors for STARTSUBMSG are at the beginning of the table so that the
+ * selector can also be used as an index into the "sub" array of
+ * subhandlers. The indexes for the two into these two tables are the
+ * same, except that in the handler table the static selectors come first. */
+ *s = f->index_ + UPB_STATIC_SELECTOR_COUNT;
+ break;
+ case UPB_HANDLER_ENDSUBMSG:
+ if (!upb_fielddef_issubmsg(f)) return false;
+ *s = f->selector_base;
+ break;
+ }
+ assert((size_t)*s < upb_fielddef_containingtype(f)->selector_count);
+ return true;
+}
+
+uint32_t upb_handlers_selectorbaseoffset(const upb_fielddef *f) {
+ return upb_fielddef_isseq(f) ? 2 : 0;
+}
+
+uint32_t upb_handlers_selectorcount(const upb_fielddef *f) {
+ uint32_t ret = 1;
+ if (upb_fielddef_isseq(f)) ret += 2; /* STARTSEQ/ENDSEQ */
+ if (upb_fielddef_isstring(f)) ret += 2; /* [STRING]/STARTSTR/ENDSTR */
+ if (upb_fielddef_issubmsg(f)) {
+ /* ENDSUBMSG (STARTSUBMSG is at table beginning) */
+ ret += 0;
+ if (upb_fielddef_lazy(f)) {
+ /* STARTSTR/ENDSTR/STRING (for lazy) */
+ ret += 3;
+ }
+ }
+ return ret;
+}
+
+
+/* upb_handlerattr ************************************************************/
+
+void upb_handlerattr_init(upb_handlerattr *attr) {
+ upb_handlerattr from = UPB_HANDLERATTR_INITIALIZER;
+ memcpy(attr, &from, sizeof(*attr));
+}
+
+void upb_handlerattr_uninit(upb_handlerattr *attr) {
+ UPB_UNUSED(attr);
+}
+
+bool upb_handlerattr_sethandlerdata(upb_handlerattr *attr, const void *hd) {
+ attr->handler_data_ = hd;
+ return true;
+}
+
+bool upb_handlerattr_setclosuretype(upb_handlerattr *attr, const void *type) {
+ attr->closure_type_ = type;
+ return true;
+}
+
+const void *upb_handlerattr_closuretype(const upb_handlerattr *attr) {
+ return attr->closure_type_;
+}
+
+bool upb_handlerattr_setreturnclosuretype(upb_handlerattr *attr,
+ const void *type) {
+ attr->return_closure_type_ = type;
+ return true;
+}
+
+const void *upb_handlerattr_returnclosuretype(const upb_handlerattr *attr) {
+ return attr->return_closure_type_;
+}
+
+bool upb_handlerattr_setalwaysok(upb_handlerattr *attr, bool alwaysok) {
+ attr->alwaysok_ = alwaysok;
+ return true;
+}
+
+bool upb_handlerattr_alwaysok(const upb_handlerattr *attr) {
+ return attr->alwaysok_;
+}
+
+/* upb_bufhandle **************************************************************/
+
+size_t upb_bufhandle_objofs(const upb_bufhandle *h) {
+ return h->objofs_;
+}
+
+/* upb_byteshandler ***********************************************************/
+
+void upb_byteshandler_init(upb_byteshandler* h) {
+ memset(h, 0, sizeof(*h));
+}
+
+/* For when we support handlerfree callbacks. */
+void upb_byteshandler_uninit(upb_byteshandler* h) {
+ UPB_UNUSED(h);
+}
+
+bool upb_byteshandler_setstartstr(upb_byteshandler *h,
+ upb_startstr_handlerfunc *func, void *d) {
+ h->table[UPB_STARTSTR_SELECTOR].func = (upb_func*)func;
+ h->table[UPB_STARTSTR_SELECTOR].attr.handler_data_ = d;
+ return true;
+}
+
+bool upb_byteshandler_setstring(upb_byteshandler *h,
+ upb_string_handlerfunc *func, void *d) {
+ h->table[UPB_STRING_SELECTOR].func = (upb_func*)func;
+ h->table[UPB_STRING_SELECTOR].attr.handler_data_ = d;
+ return true;
+}
+
+bool upb_byteshandler_setendstr(upb_byteshandler *h,
+ upb_endfield_handlerfunc *func, void *d) {
+ h->table[UPB_ENDSTR_SELECTOR].func = (upb_func*)func;
+ h->table[UPB_ENDSTR_SELECTOR].attr.handler_data_ = d;
+ return true;
+}
+/*
+** upb::RefCounted Implementation
+**
+** Our key invariants are:
+** 1. reference cycles never span groups
+** 2. for ref2(to, from), we increment to's count iff group(from) != group(to)
+**
+** The previous two are how we avoid leaking cycles. Other important
+** invariants are:
+** 3. for mutable objects "from" and "to", if there exists a ref2(to, from)
+** this implies group(from) == group(to). (In practice, what we implement
+** is even stronger; "from" and "to" will share a group if there has *ever*
+** been a ref2(to, from), but all that is necessary for correctness is the
+** weaker one).
+** 4. mutable and immutable objects are never in the same group.
+*/
+
+
+#include <setjmp.h>
+#include <stdlib.h>
+
+static void freeobj(upb_refcounted *o);
+
+const char untracked_val;
+const void *UPB_UNTRACKED_REF = &untracked_val;
+
+/* arch-specific atomic primitives *******************************************/
+
+#ifdef UPB_THREAD_UNSAFE /*---------------------------------------------------*/
+
+static void atomic_inc(uint32_t *a) { (*a)++; }
+static bool atomic_dec(uint32_t *a) { return --(*a) == 0; }
+
+#elif defined(__GNUC__) || defined(__clang__) /*------------------------------*/
+
+static void atomic_inc(uint32_t *a) { __sync_fetch_and_add(a, 1); }
+static bool atomic_dec(uint32_t *a) { return __sync_sub_and_fetch(a, 1) == 0; }
+
+#elif defined(WIN32) /*-------------------------------------------------------*/
+
+#include <Windows.h>
+
+static void atomic_inc(upb_atomic_t *a) { InterlockedIncrement(&a->val); }
+static bool atomic_dec(upb_atomic_t *a) {
+ return InterlockedDecrement(&a->val) == 0;
+}
+
+#else
+#error Atomic primitives not defined for your platform/CPU. \
+ Implement them or compile with UPB_THREAD_UNSAFE.
+#endif
+
+/* All static objects point to this refcount.
+ * It is special-cased in ref/unref below. */
+uint32_t static_refcount = -1;
+
+/* We can avoid atomic ops for statically-declared objects.
+ * This is a minor optimization but nice since we can avoid degrading under
+ * contention in this case. */
+
+static void refgroup(uint32_t *group) {
+ if (group != &static_refcount)
+ atomic_inc(group);
+}
+
+static bool unrefgroup(uint32_t *group) {
+ if (group == &static_refcount) {
+ return false;
+ } else {
+ return atomic_dec(group);
+ }
+}
+
+
+/* Reference tracking (debug only) ********************************************/
+
+#ifdef UPB_DEBUG_REFS
+
+#ifdef UPB_THREAD_UNSAFE
+
+static void upb_lock() {}
+static void upb_unlock() {}
+
+#else
+
+/* User must define functions that lock/unlock a global mutex and link this
+ * file against them. */
+void upb_lock();
+void upb_unlock();
+
+#endif
+
+/* UPB_DEBUG_REFS mode counts on being able to malloc() memory in some
+ * code-paths that can normally never fail, like upb_refcounted_ref(). Since
+ * we have no way to propagage out-of-memory errors back to the user, and since
+ * these errors can only occur in UPB_DEBUG_REFS mode, we immediately fail. */
+#define CHECK_OOM(predicate) if (!(predicate)) { assert(predicate); exit(1); }
+
+typedef struct {
+ int count; /* How many refs there are (duplicates only allowed for ref2). */
+ bool is_ref2;
+} trackedref;
+
+static trackedref *trackedref_new(bool is_ref2) {
+ trackedref *ret = malloc(sizeof(*ret));
+ CHECK_OOM(ret);
+ ret->count = 1;
+ ret->is_ref2 = is_ref2;
+ return ret;
+}
+
+static void track(const upb_refcounted *r, const void *owner, bool ref2) {
+ upb_value v;
+
+ assert(owner);
+ if (owner == UPB_UNTRACKED_REF) return;
+
+ upb_lock();
+ if (upb_inttable_lookupptr(r->refs, owner, &v)) {
+ trackedref *ref = upb_value_getptr(v);
+ /* Since we allow multiple ref2's for the same to/from pair without
+ * allocating separate memory for each one, we lose the fine-grained
+ * tracking behavior we get with regular refs. Since ref2s only happen
+ * inside upb, we'll accept this limitation until/unless there is a really
+ * difficult upb-internal bug that can't be figured out without it. */
+ assert(ref2);
+ assert(ref->is_ref2);
+ ref->count++;
+ } else {
+ trackedref *ref = trackedref_new(ref2);
+ bool ok = upb_inttable_insertptr(r->refs, owner, upb_value_ptr(ref));
+ CHECK_OOM(ok);
+ if (ref2) {
+ /* We know this cast is safe when it is a ref2, because it's coming from
+ * another refcounted object. */
+ const upb_refcounted *from = owner;
+ assert(!upb_inttable_lookupptr(from->ref2s, r, NULL));
+ ok = upb_inttable_insertptr(from->ref2s, r, upb_value_ptr(NULL));
+ CHECK_OOM(ok);
+ }
+ }
+ upb_unlock();
+}
+
+static void untrack(const upb_refcounted *r, const void *owner, bool ref2) {
+ upb_value v;
+ bool found;
+ trackedref *ref;
+
+ assert(owner);
+ if (owner == UPB_UNTRACKED_REF) return;
+
+ upb_lock();
+ found = upb_inttable_lookupptr(r->refs, owner, &v);
+ /* This assert will fail if an owner attempts to release a ref it didn't have. */
+ UPB_ASSERT_VAR(found, found);
+ ref = upb_value_getptr(v);
+ assert(ref->is_ref2 == ref2);
+ if (--ref->count == 0) {
+ free(ref);
+ upb_inttable_removeptr(r->refs, owner, NULL);
+ if (ref2) {
+ /* We know this cast is safe when it is a ref2, because it's coming from
+ * another refcounted object. */
+ const upb_refcounted *from = owner;
+ bool removed = upb_inttable_removeptr(from->ref2s, r, NULL);
+ assert(removed);
+ }
+ }
+ upb_unlock();
+}
+
+static void checkref(const upb_refcounted *r, const void *owner, bool ref2) {
+ upb_value v;
+ bool found;
+ trackedref *ref;
+
+ upb_lock();
+ found = upb_inttable_lookupptr(r->refs, owner, &v);
+ UPB_ASSERT_VAR(found, found);
+ ref = upb_value_getptr(v);
+ assert(ref->is_ref2 == ref2);
+ upb_unlock();
+}
+
+/* Populates the given UPB_CTYPE_INT32 inttable with counts of ref2's that
+ * originate from the given owner. */
+static void getref2s(const upb_refcounted *owner, upb_inttable *tab) {
+ upb_inttable_iter i;
+
+ upb_lock();
+ upb_inttable_begin(&i, owner->ref2s);
+ for(; !upb_inttable_done(&i); upb_inttable_next(&i)) {
+ upb_value v;
+ upb_value count;
+ trackedref *ref;
+ bool ok;
+ bool found;
+
+ upb_refcounted *to = (upb_refcounted*)upb_inttable_iter_key(&i);
+
+ /* To get the count we need to look in the target's table. */
+ found = upb_inttable_lookupptr(to->refs, owner, &v);
+ assert(found);
+ ref = upb_value_getptr(v);
+ count = upb_value_int32(ref->count);
+
+ ok = upb_inttable_insertptr(tab, to, count);
+ CHECK_OOM(ok);
+ }
+ upb_unlock();
+}
+
+typedef struct {
+ upb_inttable ref2;
+ const upb_refcounted *obj;
+} check_state;
+
+static void visit_check(const upb_refcounted *obj, const upb_refcounted *subobj,
+ void *closure) {
+ check_state *s = closure;
+ upb_inttable *ref2 = &s->ref2;
+ upb_value v;
+ bool removed;
+ int32_t newcount;
+
+ assert(obj == s->obj);
+ assert(subobj);
+ removed = upb_inttable_removeptr(ref2, subobj, &v);
+ /* The following assertion will fail if the visit() function visits a subobj
+ * that it did not have a ref2 on, or visits the same subobj too many times. */
+ assert(removed);
+ newcount = upb_value_getint32(v) - 1;
+ if (newcount > 0) {
+ upb_inttable_insert(ref2, (uintptr_t)subobj, upb_value_int32(newcount));
+ }
+}
+
+static void visit(const upb_refcounted *r, upb_refcounted_visit *v,
+ void *closure) {
+ bool ok;
+
+ /* In DEBUG_REFS mode we know what existing ref2 refs there are, so we know
+ * exactly the set of nodes that visit() should visit. So we verify visit()'s
+ * correctness here. */
+ check_state state;
+ state.obj = r;
+ ok = upb_inttable_init(&state.ref2, UPB_CTYPE_INT32);
+ CHECK_OOM(ok);
+ getref2s(r, &state.ref2);
+
+ /* This should visit any children in the ref2 table. */
+ if (r->vtbl->visit) r->vtbl->visit(r, visit_check, &state);
+
+ /* This assertion will fail if the visit() function missed any children. */
+ assert(upb_inttable_count(&state.ref2) == 0);
+ upb_inttable_uninit(&state.ref2);
+ if (r->vtbl->visit) r->vtbl->visit(r, v, closure);
+}
+
+static bool trackinit(upb_refcounted *r) {
+ r->refs = malloc(sizeof(*r->refs));
+ r->ref2s = malloc(sizeof(*r->ref2s));
+ if (!r->refs || !r->ref2s) goto err1;
+
+ if (!upb_inttable_init(r->refs, UPB_CTYPE_PTR)) goto err1;
+ if (!upb_inttable_init(r->ref2s, UPB_CTYPE_PTR)) goto err2;
+ return true;
+
+err2:
+ upb_inttable_uninit(r->refs);
+err1:
+ free(r->refs);
+ free(r->ref2s);
+ return false;
+}
+
+static void trackfree(const upb_refcounted *r) {
+ upb_inttable_uninit(r->refs);
+ upb_inttable_uninit(r->ref2s);
+ free(r->refs);
+ free(r->ref2s);
+}
+
+#else
+
+static void track(const upb_refcounted *r, const void *owner, bool ref2) {
+ UPB_UNUSED(r);
+ UPB_UNUSED(owner);
+ UPB_UNUSED(ref2);
+}
+
+static void untrack(const upb_refcounted *r, const void *owner, bool ref2) {
+ UPB_UNUSED(r);
+ UPB_UNUSED(owner);
+ UPB_UNUSED(ref2);
+}
+
+static void checkref(const upb_refcounted *r, const void *owner, bool ref2) {
+ UPB_UNUSED(r);
+ UPB_UNUSED(owner);
+ UPB_UNUSED(ref2);
+}
+
+static bool trackinit(upb_refcounted *r) {
+ UPB_UNUSED(r);
+ return true;
+}
+
+static void trackfree(const upb_refcounted *r) {
+ UPB_UNUSED(r);
+}
+
+static void visit(const upb_refcounted *r, upb_refcounted_visit *v,
+ void *closure) {
+ if (r->vtbl->visit) r->vtbl->visit(r, v, closure);
+}
+
+#endif /* UPB_DEBUG_REFS */
+
+
+/* freeze() *******************************************************************/
+
+/* The freeze() operation is by far the most complicated part of this scheme.
+ * We compute strongly-connected components and then mutate the graph such that
+ * we preserve the invariants documented at the top of this file. And we must
+ * handle out-of-memory errors gracefully (without leaving the graph
+ * inconsistent), which adds to the fun. */
+
+/* The state used by the freeze operation (shared across many functions). */
+typedef struct {
+ int depth;
+ int maxdepth;
+ uint64_t index;
+ /* Maps upb_refcounted* -> attributes (color, etc). attr layout varies by
+ * color. */
+ upb_inttable objattr;
+ upb_inttable stack; /* stack of upb_refcounted* for Tarjan's algorithm. */
+ upb_inttable groups; /* array of uint32_t*, malloc'd refcounts for new groups */
+ upb_status *status;
+ jmp_buf err;
+} tarjan;
+
+static void release_ref2(const upb_refcounted *obj,
+ const upb_refcounted *subobj,
+ void *closure);
+
+/* Node attributes -----------------------------------------------------------*/
+
+/* After our analysis phase all nodes will be either GRAY or WHITE. */
+
+typedef enum {
+ BLACK = 0, /* Object has not been seen. */
+ GRAY, /* Object has been found via a refgroup but may not be reachable. */
+ GREEN, /* Object is reachable and is currently on the Tarjan stack. */
+ WHITE /* Object is reachable and has been assigned a group (SCC). */
+} color_t;
+
+UPB_NORETURN static void err(tarjan *t) { longjmp(t->err, 1); }
+UPB_NORETURN static void oom(tarjan *t) {
+ upb_status_seterrmsg(t->status, "out of memory");
+ err(t);
+}
+
+static uint64_t trygetattr(const tarjan *t, const upb_refcounted *r) {
+ upb_value v;
+ return upb_inttable_lookupptr(&t->objattr, r, &v) ?
+ upb_value_getuint64(v) : 0;
+}
+
+static uint64_t getattr(const tarjan *t, const upb_refcounted *r) {
+ upb_value v;
+ bool found = upb_inttable_lookupptr(&t->objattr, r, &v);
+ UPB_ASSERT_VAR(found, found);
+ return upb_value_getuint64(v);
+}
+
+static void setattr(tarjan *t, const upb_refcounted *r, uint64_t attr) {
+ upb_inttable_removeptr(&t->objattr, r, NULL);
+ upb_inttable_insertptr(&t->objattr, r, upb_value_uint64(attr));
+}
+
+static color_t color(tarjan *t, const upb_refcounted *r) {
+ return trygetattr(t, r) & 0x3; /* Color is always stored in the low 2 bits. */
+}
+
+static void set_gray(tarjan *t, const upb_refcounted *r) {
+ assert(color(t, r) == BLACK);
+ setattr(t, r, GRAY);
+}
+
+/* Pushes an obj onto the Tarjan stack and sets it to GREEN. */
+static void push(tarjan *t, const upb_refcounted *r) {
+ assert(color(t, r) == BLACK || color(t, r) == GRAY);
+ /* This defines the attr layout for the GREEN state. "index" and "lowlink"
+ * get 31 bits, which is plenty (limit of 2B objects frozen at a time). */
+ setattr(t, r, GREEN | (t->index << 2) | (t->index << 33));
+ if (++t->index == 0x80000000) {
+ upb_status_seterrmsg(t->status, "too many objects to freeze");
+ err(t);
+ }
+ upb_inttable_push(&t->stack, upb_value_ptr((void*)r));
+}
+
+/* Pops an obj from the Tarjan stack and sets it to WHITE, with a ptr to its
+ * SCC group. */
+static upb_refcounted *pop(tarjan *t) {
+ upb_refcounted *r = upb_value_getptr(upb_inttable_pop(&t->stack));
+ assert(color(t, r) == GREEN);
+ /* This defines the attr layout for nodes in the WHITE state.
+ * Top of group stack is [group, NULL]; we point at group. */
+ setattr(t, r, WHITE | (upb_inttable_count(&t->groups) - 2) << 8);
+ return r;
+}
+
+static void tarjan_newgroup(tarjan *t) {
+ uint32_t *group = malloc(sizeof(*group));
+ if (!group) oom(t);
+ /* Push group and empty group leader (we'll fill in leader later). */
+ if (!upb_inttable_push(&t->groups, upb_value_ptr(group)) ||
+ !upb_inttable_push(&t->groups, upb_value_ptr(NULL))) {
+ free(group);
+ oom(t);
+ }
+ *group = 0;
+}
+
+static uint32_t idx(tarjan *t, const upb_refcounted *r) {
+ assert(color(t, r) == GREEN);
+ return (getattr(t, r) >> 2) & 0x7FFFFFFF;
+}
+
+static uint32_t lowlink(tarjan *t, const upb_refcounted *r) {
+ if (color(t, r) == GREEN) {
+ return getattr(t, r) >> 33;
+ } else {
+ return UINT32_MAX;
+ }
+}
+
+static void set_lowlink(tarjan *t, const upb_refcounted *r, uint32_t lowlink) {
+ assert(color(t, r) == GREEN);
+ setattr(t, r, ((uint64_t)lowlink << 33) | (getattr(t, r) & 0x1FFFFFFFF));
+}
+
+static uint32_t *group(tarjan *t, upb_refcounted *r) {
+ uint64_t groupnum;
+ upb_value v;
+ bool found;
+
+ assert(color(t, r) == WHITE);
+ groupnum = getattr(t, r) >> 8;
+ found = upb_inttable_lookup(&t->groups, groupnum, &v);
+ UPB_ASSERT_VAR(found, found);
+ return upb_value_getptr(v);
+}
+
+/* If the group leader for this object's group has not previously been set,
+ * the given object is assigned to be its leader. */
+static upb_refcounted *groupleader(tarjan *t, upb_refcounted *r) {
+ uint64_t leader_slot;
+ upb_value v;
+ bool found;
+
+ assert(color(t, r) == WHITE);
+ leader_slot = (getattr(t, r) >> 8) + 1;
+ found = upb_inttable_lookup(&t->groups, leader_slot, &v);
+ UPB_ASSERT_VAR(found, found);
+ if (upb_value_getptr(v)) {
+ return upb_value_getptr(v);
+ } else {
+ upb_inttable_remove(&t->groups, leader_slot, NULL);
+ upb_inttable_insert(&t->groups, leader_slot, upb_value_ptr(r));
+ return r;
+ }
+}
+
+
+/* Tarjan's algorithm --------------------------------------------------------*/
+
+/* See:
+ * http://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm */
+static void do_tarjan(const upb_refcounted *obj, tarjan *t);
+
+static void tarjan_visit(const upb_refcounted *obj,
+ const upb_refcounted *subobj,
+ void *closure) {
+ tarjan *t = closure;
+ if (++t->depth > t->maxdepth) {
+ upb_status_seterrf(t->status, "graph too deep to freeze (%d)", t->maxdepth);
+ err(t);
+ } else if (subobj->is_frozen || color(t, subobj) == WHITE) {
+ /* Do nothing: we don't want to visit or color already-frozen nodes,
+ * and WHITE nodes have already been assigned a SCC. */
+ } else if (color(t, subobj) < GREEN) {
+ /* Subdef has not yet been visited; recurse on it. */
+ do_tarjan(subobj, t);
+ set_lowlink(t, obj, UPB_MIN(lowlink(t, obj), lowlink(t, subobj)));
+ } else if (color(t, subobj) == GREEN) {
+ /* Subdef is in the stack and hence in the current SCC. */
+ set_lowlink(t, obj, UPB_MIN(lowlink(t, obj), idx(t, subobj)));
+ }
+ --t->depth;
+}
+
+static void do_tarjan(const upb_refcounted *obj, tarjan *t) {
+ if (color(t, obj) == BLACK) {
+ /* We haven't seen this object's group; mark the whole group GRAY. */
+ const upb_refcounted *o = obj;
+ do { set_gray(t, o); } while ((o = o->next) != obj);
+ }
+
+ push(t, obj);
+ visit(obj, tarjan_visit, t);
+ if (lowlink(t, obj) == idx(t, obj)) {
+ tarjan_newgroup(t);
+ while (pop(t) != obj)
+ ;
+ }
+}
+
+
+/* freeze() ------------------------------------------------------------------*/
+
+static void crossref(const upb_refcounted *r, const upb_refcounted *subobj,
+ void *_t) {
+ tarjan *t = _t;
+ assert(color(t, r) > BLACK);
+ if (color(t, subobj) > BLACK && r->group != subobj->group) {
+ /* Previously this ref was not reflected in subobj->group because they
+ * were in the same group; now that they are split a ref must be taken. */
+ refgroup(subobj->group);
+ }
+}
+
+static bool freeze(upb_refcounted *const*roots, int n, upb_status *s,
+ int maxdepth) {
+ volatile bool ret = false;
+ int i;
+ upb_inttable_iter iter;
+
+ /* We run in two passes so that we can allocate all memory before performing
+ * any mutation of the input -- this allows us to leave the input unchanged
+ * in the case of memory allocation failure. */
+ tarjan t;
+ t.index = 0;
+ t.depth = 0;
+ t.maxdepth = maxdepth;
+ t.status = s;
+ if (!upb_inttable_init(&t.objattr, UPB_CTYPE_UINT64)) goto err1;
+ if (!upb_inttable_init(&t.stack, UPB_CTYPE_PTR)) goto err2;
+ if (!upb_inttable_init(&t.groups, UPB_CTYPE_PTR)) goto err3;
+ if (setjmp(t.err) != 0) goto err4;
+
+
+ for (i = 0; i < n; i++) {
+ if (color(&t, roots[i]) < GREEN) {
+ do_tarjan(roots[i], &t);
+ }
+ }
+
+ /* If we've made it this far, no further errors are possible so it's safe to
+ * mutate the objects without risk of leaving them in an inconsistent state. */
+ ret = true;
+
+ /* The transformation that follows requires care. The preconditions are:
+ * - all objects in attr map are WHITE or GRAY, and are in mutable groups
+ * (groups of all mutable objs)
+ * - no ref2(to, from) refs have incremented count(to) if both "to" and
+ * "from" are in our attr map (this follows from invariants (2) and (3)) */
+
+ /* Pass 1: we remove WHITE objects from their mutable groups, and add them to
+ * new groups according to the SCC's we computed. These new groups will
+ * consist of only frozen objects. None will be immediately collectible,
+ * because WHITE objects are by definition reachable from one of "roots",
+ * which the caller must own refs on. */
+ upb_inttable_begin(&iter, &t.objattr);
+ for(; !upb_inttable_done(&iter); upb_inttable_next(&iter)) {
+ upb_refcounted *obj = (upb_refcounted*)upb_inttable_iter_key(&iter);
+ /* Since removal from a singly-linked list requires access to the object's
+ * predecessor, we consider obj->next instead of obj for moving. With the
+ * while() loop we guarantee that we will visit every node's predecessor.
+ * Proof:
+ * 1. every node's predecessor is in our attr map.
+ * 2. though the loop body may change a node's predecessor, it will only
+ * change it to be the node we are currently operating on, so with a
+ * while() loop we guarantee ourselves the chance to remove each node. */
+ while (color(&t, obj->next) == WHITE &&
+ group(&t, obj->next) != obj->next->group) {
+ upb_refcounted *leader;
+
+ /* Remove from old group. */
+ upb_refcounted *move = obj->next;
+ if (obj == move) {
+ /* Removing the last object from a group. */
+ assert(*obj->group == obj->individual_count);
+ free(obj->group);
+ } else {
+ obj->next = move->next;
+ /* This may decrease to zero; we'll collect GRAY objects (if any) that
+ * remain in the group in the third pass. */
+ assert(*move->group >= move->individual_count);
+ *move->group -= move->individual_count;
+ }
+
+ /* Add to new group. */
+ leader = groupleader(&t, move);
+ if (move == leader) {
+ /* First object added to new group is its leader. */
+ move->group = group(&t, move);
+ move->next = move;
+ *move->group = move->individual_count;
+ } else {
+ /* Group already has at least one object in it. */
+ assert(leader->group == group(&t, move));
+ move->group = group(&t, move);
+ move->next = leader->next;
+ leader->next = move;
+ *move->group += move->individual_count;
+ }
+
+ move->is_frozen = true;
+ }
+ }
+
+ /* Pass 2: GRAY and WHITE objects "obj" with ref2(to, obj) references must
+ * increment count(to) if group(obj) != group(to) (which could now be the
+ * case if "to" was just frozen). */
+ upb_inttable_begin(&iter, &t.objattr);
+ for(; !upb_inttable_done(&iter); upb_inttable_next(&iter)) {
+ upb_refcounted *obj = (upb_refcounted*)upb_inttable_iter_key(&iter);
+ visit(obj, crossref, &t);
+ }
+
+ /* Pass 3: GRAY objects are collected if their group's refcount dropped to
+ * zero when we removed its white nodes. This can happen if they had only
+ * been kept alive by virtue of sharing a group with an object that was just
+ * frozen.
+ *
+ * It is important that we do this last, since the GRAY object's free()
+ * function could call unref2() on just-frozen objects, which will decrement
+ * refs that were added in pass 2. */
+ upb_inttable_begin(&iter, &t.objattr);
+ for(; !upb_inttable_done(&iter); upb_inttable_next(&iter)) {
+ upb_refcounted *obj = (upb_refcounted*)upb_inttable_iter_key(&iter);
+ if (obj->group == NULL || *obj->group == 0) {
+ if (obj->group) {
+ upb_refcounted *o;
+
+ /* We eagerly free() the group's count (since we can't easily determine
+ * the group's remaining size it's the easiest way to ensure it gets
+ * done). */
+ free(obj->group);
+
+ /* Visit to release ref2's (done in a separate pass since release_ref2
+ * depends on o->group being unmodified so it can test merged()). */
+ o = obj;
+ do { visit(o, release_ref2, NULL); } while ((o = o->next) != obj);
+
+ /* Mark "group" fields as NULL so we know to free the objects later in
+ * this loop, but also don't try to delete the group twice. */
+ o = obj;
+ do { o->group = NULL; } while ((o = o->next) != obj);
+ }
+ freeobj(obj);
+ }
+ }
+
+err4:
+ if (!ret) {
+ upb_inttable_begin(&iter, &t.groups);
+ for(; !upb_inttable_done(&iter); upb_inttable_next(&iter))
+ free(upb_value_getptr(upb_inttable_iter_value(&iter)));
+ }
+ upb_inttable_uninit(&t.groups);
+err3:
+ upb_inttable_uninit(&t.stack);
+err2:
+ upb_inttable_uninit(&t.objattr);
+err1:
+ return ret;
+}
+
+
+/* Misc internal functions ***************************************************/
+
+static bool merged(const upb_refcounted *r, const upb_refcounted *r2) {
+ return r->group == r2->group;
+}
+
+static void merge(upb_refcounted *r, upb_refcounted *from) {
+ upb_refcounted *base;
+ upb_refcounted *tmp;
+
+ if (merged(r, from)) return;
+ *r->group += *from->group;
+ free(from->group);
+ base = from;
+
+ /* Set all refcount pointers in the "from" chain to the merged refcount.
+ *
+ * TODO(haberman): this linear algorithm can result in an overall O(n^2) bound
+ * if the user continuously extends a group by one object. Prevent this by
+ * using one of the techniques in this paper:
+ * ftp://www.ncedc.org/outgoing/geomorph/dino/orals/p245-tarjan.pdf */
+ do { from->group = r->group; } while ((from = from->next) != base);
+
+ /* Merge the two circularly linked lists by swapping their next pointers. */
+ tmp = r->next;
+ r->next = base->next;
+ base->next = tmp;
+}
+
+static void unref(const upb_refcounted *r);
+
+static void release_ref2(const upb_refcounted *obj,
+ const upb_refcounted *subobj,
+ void *closure) {
+ UPB_UNUSED(closure);
+ untrack(subobj, obj, true);
+ if (!merged(obj, subobj)) {
+ assert(subobj->is_frozen);
+ unref(subobj);
+ }
+}
+
+static void unref(const upb_refcounted *r) {
+ if (unrefgroup(r->group)) {
+ const upb_refcounted *o;
+
+ free(r->group);
+
+ /* In two passes, since release_ref2 needs a guarantee that any subobjs
+ * are alive. */
+ o = r;
+ do { visit(o, release_ref2, NULL); } while((o = o->next) != r);
+
+ o = r;
+ do {
+ const upb_refcounted *next = o->next;
+ assert(o->is_frozen || o->individual_count == 0);
+ freeobj((upb_refcounted*)o);
+ o = next;
+ } while(o != r);
+ }
+}
+
+static void freeobj(upb_refcounted *o) {
+ trackfree(o);
+ o->vtbl->free((upb_refcounted*)o);
+}
+
+
+/* Public interface ***********************************************************/
+
+bool upb_refcounted_init(upb_refcounted *r,
+ const struct upb_refcounted_vtbl *vtbl,
+ const void *owner) {
+#ifndef NDEBUG
+ /* Endianness check. This is unrelated to upb_refcounted, it's just a
+ * convenient place to put the check that we can be assured will run for
+ * basically every program using upb. */
+ const int x = 1;
+#ifdef UPB_BIG_ENDIAN
+ assert(*(char*)&x != 1);
+#else
+ assert(*(char*)&x == 1);
+#endif
+#endif
+
+ r->next = r;
+ r->vtbl = vtbl;
+ r->individual_count = 0;
+ r->is_frozen = false;
+ r->group = malloc(sizeof(*r->group));
+ if (!r->group) return false;
+ *r->group = 0;
+ if (!trackinit(r)) {
+ free(r->group);
+ return false;
+ }
+ upb_refcounted_ref(r, owner);
+ return true;
+}
+
+bool upb_refcounted_isfrozen(const upb_refcounted *r) {
+ return r->is_frozen;
+}
+
+void upb_refcounted_ref(const upb_refcounted *r, const void *owner) {
+ track(r, owner, false);
+ if (!r->is_frozen)
+ ((upb_refcounted*)r)->individual_count++;
+ refgroup(r->group);
+}
+
+void upb_refcounted_unref(const upb_refcounted *r, const void *owner) {
+ untrack(r, owner, false);
+ if (!r->is_frozen)
+ ((upb_refcounted*)r)->individual_count--;
+ unref(r);
+}
+
+void upb_refcounted_ref2(const upb_refcounted *r, upb_refcounted *from) {
+ assert(!from->is_frozen); /* Non-const pointer implies this. */
+ track(r, from, true);
+ if (r->is_frozen) {
+ refgroup(r->group);
+ } else {
+ merge((upb_refcounted*)r, from);
+ }
+}
+
+void upb_refcounted_unref2(const upb_refcounted *r, upb_refcounted *from) {
+ assert(!from->is_frozen); /* Non-const pointer implies this. */
+ untrack(r, from, true);
+ if (r->is_frozen) {
+ unref(r);
+ } else {
+ assert(merged(r, from));
+ }
+}
+
+void upb_refcounted_donateref(
+ const upb_refcounted *r, const void *from, const void *to) {
+ assert(from != to);
+ if (to != NULL)
+ upb_refcounted_ref(r, to);
+ if (from != NULL)
+ upb_refcounted_unref(r, from);
+}
+
+void upb_refcounted_checkref(const upb_refcounted *r, const void *owner) {
+ checkref(r, owner, false);
+}
+
+bool upb_refcounted_freeze(upb_refcounted *const*roots, int n, upb_status *s,
+ int maxdepth) {
+ int i;
+ for (i = 0; i < n; i++) {
+ assert(!roots[i]->is_frozen);
+ }
+ return freeze(roots, n, s, maxdepth);
+}
+
+
+#include <stdlib.h>
+
+/* Fallback implementation if the shim is not specialized by the JIT. */
+#define SHIM_WRITER(type, ctype) \
+ bool upb_shim_set ## type (void *c, const void *hd, ctype val) { \
+ uint8_t *m = c; \
+ const upb_shim_data *d = hd; \
+ if (d->hasbit > 0) \
+ *(uint8_t*)&m[d->hasbit / 8] |= 1 << (d->hasbit % 8); \
+ *(ctype*)&m[d->offset] = val; \
+ return true; \
+ } \
+
+SHIM_WRITER(double, double)
+SHIM_WRITER(float, float)
+SHIM_WRITER(int32, int32_t)
+SHIM_WRITER(int64, int64_t)
+SHIM_WRITER(uint32, uint32_t)
+SHIM_WRITER(uint64, uint64_t)
+SHIM_WRITER(bool, bool)
+#undef SHIM_WRITER
+
+bool upb_shim_set(upb_handlers *h, const upb_fielddef *f, size_t offset,
+ int32_t hasbit) {
+ upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
+ bool ok;
+
+ upb_shim_data *d = malloc(sizeof(*d));
+ if (!d) return false;
+ d->offset = offset;
+ d->hasbit = hasbit;
+
+ upb_handlerattr_sethandlerdata(&attr, d);
+ upb_handlerattr_setalwaysok(&attr, true);
+ upb_handlers_addcleanup(h, d, free);
+
+#define TYPE(u, l) \
+ case UPB_TYPE_##u: \
+ ok = upb_handlers_set##l(h, f, upb_shim_set##l, &attr); break;
+
+ ok = false;
+
+ switch (upb_fielddef_type(f)) {
+ TYPE(INT64, int64);
+ TYPE(INT32, int32);
+ TYPE(ENUM, int32);
+ TYPE(UINT64, uint64);
+ TYPE(UINT32, uint32);
+ TYPE(DOUBLE, double);
+ TYPE(FLOAT, float);
+ TYPE(BOOL, bool);
+ default: assert(false); break;
+ }
+#undef TYPE
+
+ upb_handlerattr_uninit(&attr);
+ return ok;
+}
+
+const upb_shim_data *upb_shim_getdata(const upb_handlers *h, upb_selector_t s,
+ upb_fieldtype_t *type) {
+ upb_func *f = upb_handlers_gethandler(h, s);
+
+ if ((upb_int64_handlerfunc*)f == upb_shim_setint64) {
+ *type = UPB_TYPE_INT64;
+ } else if ((upb_int32_handlerfunc*)f == upb_shim_setint32) {
+ *type = UPB_TYPE_INT32;
+ } else if ((upb_uint64_handlerfunc*)f == upb_shim_setuint64) {
+ *type = UPB_TYPE_UINT64;
+ } else if ((upb_uint32_handlerfunc*)f == upb_shim_setuint32) {
+ *type = UPB_TYPE_UINT32;
+ } else if ((upb_double_handlerfunc*)f == upb_shim_setdouble) {
+ *type = UPB_TYPE_DOUBLE;
+ } else if ((upb_float_handlerfunc*)f == upb_shim_setfloat) {
+ *type = UPB_TYPE_FLOAT;
+ } else if ((upb_bool_handlerfunc*)f == upb_shim_setbool) {
+ *type = UPB_TYPE_BOOL;
+ } else {
+ return NULL;
+ }
+
+ return (const upb_shim_data*)upb_handlers_gethandlerdata(h, s);
+}
+
+
+#include <stdlib.h>
+#include <string.h>
+
+static void upb_symtab_free(upb_refcounted *r) {
+ upb_symtab *s = (upb_symtab*)r;
+ upb_strtable_iter i;
+ upb_strtable_begin(&i, &s->symtab);
+ for (; !upb_strtable_done(&i); upb_strtable_next(&i)) {
+ const upb_def *def = upb_value_getptr(upb_strtable_iter_value(&i));
+ upb_def_unref(def, s);
+ }
+ upb_strtable_uninit(&s->symtab);
+ free(s);
+}
+
+
+upb_symtab *upb_symtab_new(const void *owner) {
+ static const struct upb_refcounted_vtbl vtbl = {NULL, &upb_symtab_free};
+ upb_symtab *s = malloc(sizeof(*s));
+ upb_refcounted_init(upb_symtab_upcast_mutable(s), &vtbl, owner);
+ upb_strtable_init(&s->symtab, UPB_CTYPE_PTR);
+ return s;
+}
+
+void upb_symtab_freeze(upb_symtab *s) {
+ upb_refcounted *r;
+ bool ok;
+
+ assert(!upb_symtab_isfrozen(s));
+ r = upb_symtab_upcast_mutable(s);
+ /* The symtab does not take ref2's (see refcounted.h) on the defs, because
+ * defs cannot refer back to the table and therefore cannot create cycles. So
+ * 0 will suffice for maxdepth here. */
+ ok = upb_refcounted_freeze(&r, 1, NULL, 0);
+ UPB_ASSERT_VAR(ok, ok);
+}
+
+const upb_def *upb_symtab_lookup(const upb_symtab *s, const char *sym) {
+ upb_value v;
+ upb_def *ret = upb_strtable_lookup(&s->symtab, sym, &v) ?
+ upb_value_getptr(v) : NULL;
+ return ret;
+}
+
+const upb_msgdef *upb_symtab_lookupmsg(const upb_symtab *s, const char *sym) {
+ upb_value v;
+ upb_def *def = upb_strtable_lookup(&s->symtab, sym, &v) ?
+ upb_value_getptr(v) : NULL;
+ return def ? upb_dyncast_msgdef(def) : NULL;
+}
+
+const upb_enumdef *upb_symtab_lookupenum(const upb_symtab *s, const char *sym) {
+ upb_value v;
+ upb_def *def = upb_strtable_lookup(&s->symtab, sym, &v) ?
+ upb_value_getptr(v) : NULL;
+ return def ? upb_dyncast_enumdef(def) : NULL;
+}
+
+/* Given a symbol and the base symbol inside which it is defined, find the
+ * symbol's definition in t. */
+static upb_def *upb_resolvename(const upb_strtable *t,
+ const char *base, const char *sym) {
+ if(strlen(sym) == 0) return NULL;
+ if(sym[0] == '.') {
+ /* Symbols starting with '.' are absolute, so we do a single lookup.
+ * Slice to omit the leading '.' */
+ upb_value v;
+ return upb_strtable_lookup(t, sym + 1, &v) ? upb_value_getptr(v) : NULL;
+ } else {
+ /* Remove components from base until we find an entry or run out.
+ * TODO: This branch is totally broken, but currently not used. */
+ (void)base;
+ assert(false);
+ return NULL;
+ }
+}
+
+const upb_def *upb_symtab_resolve(const upb_symtab *s, const char *base,
+ const char *sym) {
+ upb_def *ret = upb_resolvename(&s->symtab, base, sym);
+ return ret;
+}
+
+/* Starts a depth-first traversal at "def", recursing into any subdefs
+ * (ie. submessage types). Adds duplicates of existing defs to addtab
+ * wherever necessary, so that the resulting symtab will be consistent once
+ * addtab is added.
+ *
+ * More specifically, if any def D is found in the DFS that:
+ *
+ * 1. can reach a def that is being replaced by something in addtab, AND
+ *
+ * 2. is not itself being replaced already (ie. this name doesn't already
+ * exist in addtab)
+ *
+ * ...then a duplicate (new copy) of D will be added to addtab.
+ *
+ * Returns true if this happened for any def reachable from "def."
+ *
+ * It is slightly tricky to do this correctly in the presence of cycles. If we
+ * detect that our DFS has hit a cycle, we might not yet know if any SCCs on
+ * our stack can reach a def in addtab or not. Once we figure this out, that
+ * answer needs to apply to *all* defs in these SCCs, even if we visited them
+ * already. So a straight up one-pass cycle-detecting DFS won't work.
+ *
+ * To work around this problem, we traverse each SCC (which we already
+ * computed, since these defs are frozen) as a single node. We first compute
+ * whether the SCC as a whole can reach any def in addtab, then we dup (or not)
+ * the entire SCC. This requires breaking the encapsulation of upb_refcounted,
+ * since that is where we get the data about what SCC we are in. */
+static bool upb_resolve_dfs(const upb_def *def, upb_strtable *addtab,
+ const void *new_owner, upb_inttable *seen,
+ upb_status *s) {
+ upb_value v;
+ bool need_dup;
+ const upb_def *base;
+ const void* memoize_key;
+
+ /* Memoize results of this function for efficiency (since we're traversing a
+ * DAG this is not needed to limit the depth of the search).
+ *
+ * We memoize by SCC instead of by individual def. */
+ memoize_key = def->base.group;
+
+ if (upb_inttable_lookupptr(seen, memoize_key, &v))
+ return upb_value_getbool(v);
+
+ /* Visit submessages for all messages in the SCC. */
+ need_dup = false;
+ base = def;
+ do {
+ upb_value v;
+ const upb_msgdef *m;
+
+ assert(upb_def_isfrozen(def));
+ if (def->type == UPB_DEF_FIELD) continue;
+ if (upb_strtable_lookup(addtab, upb_def_fullname(def), &v)) {
+ need_dup = true;
+ }
+
+ /* For messages, continue the recursion by visiting all subdefs, but only
+ * ones in different SCCs. */
+ m = upb_dyncast_msgdef(def);
+ if (m) {
+ upb_msg_field_iter i;
+ for(upb_msg_field_begin(&i, m);
+ !upb_msg_field_done(&i);
+ upb_msg_field_next(&i)) {
+ upb_fielddef *f = upb_msg_iter_field(&i);
+ const upb_def *subdef;
+
+ if (!upb_fielddef_hassubdef(f)) continue;
+ subdef = upb_fielddef_subdef(f);
+
+ /* Skip subdefs in this SCC. */
+ if (def->base.group == subdef->base.group) continue;
+
+ /* |= to avoid short-circuit; we need its side-effects. */
+ need_dup |= upb_resolve_dfs(subdef, addtab, new_owner, seen, s);
+ if (!upb_ok(s)) return false;
+ }
+ }
+ } while ((def = (upb_def*)def->base.next) != base);
+
+ if (need_dup) {
+ /* Dup all defs in this SCC that don't already have entries in addtab. */
+ def = base;
+ do {
+ const char *name;
+
+ if (def->type == UPB_DEF_FIELD) continue;
+ name = upb_def_fullname(def);
+ if (!upb_strtable_lookup(addtab, name, NULL)) {
+ upb_def *newdef = upb_def_dup(def, new_owner);
+ if (!newdef) goto oom;
+ newdef->came_from_user = false;
+ if (!upb_strtable_insert(addtab, name, upb_value_ptr(newdef)))
+ goto oom;
+ }
+ } while ((def = (upb_def*)def->base.next) != base);
+ }
+
+ upb_inttable_insertptr(seen, memoize_key, upb_value_bool(need_dup));
+ return need_dup;
+
+oom:
+ upb_status_seterrmsg(s, "out of memory");
+ return false;
+}
+
+/* TODO(haberman): we need a lot more testing of error conditions.
+ * The came_from_user stuff in particular is not tested. */
+bool upb_symtab_add(upb_symtab *s, upb_def *const*defs, int n, void *ref_donor,
+ upb_status *status) {
+ int i;
+ upb_strtable_iter iter;
+ upb_def **add_defs = NULL;
+ upb_strtable addtab;
+ upb_inttable seen;
+
+ assert(!upb_symtab_isfrozen(s));
+ if (!upb_strtable_init(&addtab, UPB_CTYPE_PTR)) {
+ upb_status_seterrmsg(status, "out of memory");
+ return false;
+ }
+
+ /* Add new defs to our "add" set. */
+ for (i = 0; i < n; i++) {
+ upb_def *def = defs[i];
+ const char *fullname;
+ upb_fielddef *f;
+
+ if (upb_def_isfrozen(def)) {
+ upb_status_seterrmsg(status, "added defs must be mutable");
+ goto err;
+ }
+ assert(!upb_def_isfrozen(def));
+ fullname = upb_def_fullname(def);
+ if (!fullname) {
+ upb_status_seterrmsg(
+ status, "Anonymous defs cannot be added to a symtab");
+ goto err;
+ }
+
+ f = upb_dyncast_fielddef_mutable(def);
+
+ if (f) {
+ if (!upb_fielddef_containingtypename(f)) {
+ upb_status_seterrmsg(status,
+ "Standalone fielddefs must have a containing type "
+ "(extendee) name set");
+ goto err;
+ }
+ } else {
+ if (upb_strtable_lookup(&addtab, fullname, NULL)) {
+ upb_status_seterrf(status, "Conflicting defs named '%s'", fullname);
+ goto err;
+ }
+ /* We need this to back out properly, because if there is a failure we
+ * need to donate the ref back to the caller. */
+ def->came_from_user = true;
+ upb_def_donateref(def, ref_donor, s);
+ if (!upb_strtable_insert(&addtab, fullname, upb_value_ptr(def)))
+ goto oom_err;
+ }
+ }
+
+ /* Add standalone fielddefs (ie. extensions) to the appropriate messages.
+ * If the appropriate message only exists in the existing symtab, duplicate
+ * it so we have a mutable copy we can add the fields to. */
+ for (i = 0; i < n; i++) {
+ upb_def *def = defs[i];
+ upb_fielddef *f = upb_dyncast_fielddef_mutable(def);
+ const char *msgname;
+ upb_value v;
+ upb_msgdef *m;
+
+ if (!f) continue;
+ msgname = upb_fielddef_containingtypename(f);
+ /* We validated this earlier in this function. */
+ assert(msgname);
+
+ /* If the extendee name is absolutely qualified, move past the initial ".".
+ * TODO(haberman): it is not obvious what it would mean if this was not
+ * absolutely qualified. */
+ if (msgname[0] == '.') {
+ msgname++;
+ }
+
+ if (upb_strtable_lookup(&addtab, msgname, &v)) {
+ /* Extendee is in the set of defs the user asked us to add. */
+ m = upb_value_getptr(v);
+ } else {
+ /* Need to find and dup the extendee from the existing symtab. */
+ const upb_msgdef *frozen_m = upb_symtab_lookupmsg(s, msgname);
+ if (!frozen_m) {
+ upb_status_seterrf(status,
+ "Tried to extend message %s that does not exist "
+ "in this SymbolTable.",
+ msgname);
+ goto err;
+ }
+ m = upb_msgdef_dup(frozen_m, s);
+ if (!m) goto oom_err;
+ if (!upb_strtable_insert(&addtab, msgname, upb_value_ptr(m))) {
+ upb_msgdef_unref(m, s);
+ goto oom_err;
+ }
+ }
+
+ if (!upb_msgdef_addfield(m, f, ref_donor, status)) {
+ goto err;
+ }
+ }
+
+ /* Add dups of any existing def that can reach a def with the same name as
+ * anything in our "add" set. */
+ if (!upb_inttable_init(&seen, UPB_CTYPE_BOOL)) goto oom_err;
+ upb_strtable_begin(&iter, &s->symtab);
+ for (; !upb_strtable_done(&iter); upb_strtable_next(&iter)) {
+ upb_def *def = upb_value_getptr(upb_strtable_iter_value(&iter));
+ upb_resolve_dfs(def, &addtab, s, &seen, status);
+ if (!upb_ok(status)) goto err;
+ }
+ upb_inttable_uninit(&seen);
+
+ /* Now using the table, resolve symbolic references for subdefs. */
+ upb_strtable_begin(&iter, &addtab);
+ for (; !upb_strtable_done(&iter); upb_strtable_next(&iter)) {
+ const char *base;
+ upb_def *def = upb_value_getptr(upb_strtable_iter_value(&iter));
+ upb_msgdef *m = upb_dyncast_msgdef_mutable(def);
+ upb_msg_field_iter j;
+
+ if (!m) continue;
+ /* Type names are resolved relative to the message in which they appear. */
+ base = upb_msgdef_fullname(m);
+
+ for(upb_msg_field_begin(&j, m);
+ !upb_msg_field_done(&j);
+ upb_msg_field_next(&j)) {
+ upb_fielddef *f = upb_msg_iter_field(&j);
+ const char *name = upb_fielddef_subdefname(f);
+ if (name && !upb_fielddef_subdef(f)) {
+ /* Try the lookup in the current set of to-be-added defs first. If not
+ * there, try existing defs. */
+ upb_def *subdef = upb_resolvename(&addtab, base, name);
+ if (subdef == NULL) {
+ subdef = upb_resolvename(&s->symtab, base, name);
+ }
+ if (subdef == NULL) {
+ upb_status_seterrf(
+ status, "couldn't resolve name '%s' in message '%s'", name, base);
+ goto err;
+ } else if (!upb_fielddef_setsubdef(f, subdef, status)) {
+ goto err;
+ }
+ }
+ }
+ }
+
+ /* We need an array of the defs in addtab, for passing to upb_def_freeze. */
+ add_defs = malloc(sizeof(void*) * upb_strtable_count(&addtab));
+ if (add_defs == NULL) goto oom_err;
+ upb_strtable_begin(&iter, &addtab);
+ for (n = 0; !upb_strtable_done(&iter); upb_strtable_next(&iter)) {
+ add_defs[n++] = upb_value_getptr(upb_strtable_iter_value(&iter));
+ }
+
+ if (!upb_def_freeze(add_defs, n, status)) goto err;
+
+ /* This must be delayed until all errors have been detected, since error
+ * recovery code uses this table to cleanup defs. */
+ upb_strtable_uninit(&addtab);
+
+ /* TODO(haberman) we don't properly handle errors after this point (like
+ * OOM in upb_strtable_insert() below). */
+ for (i = 0; i < n; i++) {
+ upb_def *def = add_defs[i];
+ const char *name = upb_def_fullname(def);
+ upb_value v;
+ bool success;
+
+ if (upb_strtable_remove(&s->symtab, name, &v)) {
+ const upb_def *def = upb_value_getptr(v);
+ upb_def_unref(def, s);
+ }
+ success = upb_strtable_insert(&s->symtab, name, upb_value_ptr(def));
+ UPB_ASSERT_VAR(success, success == true);
+ }
+ free(add_defs);
+ return true;
+
+oom_err:
+ upb_status_seterrmsg(status, "out of memory");
+err: {
+ /* For defs the user passed in, we need to donate the refs back. For defs
+ * we dup'd, we need to just unref them. */
+ upb_strtable_begin(&iter, &addtab);
+ for (; !upb_strtable_done(&iter); upb_strtable_next(&iter)) {
+ upb_def *def = upb_value_getptr(upb_strtable_iter_value(&iter));
+ bool came_from_user = def->came_from_user;
+ def->came_from_user = false;
+ if (came_from_user) {
+ upb_def_donateref(def, s, ref_donor);
+ } else {
+ upb_def_unref(def, s);
+ }
+ }
+ }
+ upb_strtable_uninit(&addtab);
+ free(add_defs);
+ assert(!upb_ok(status));
+ return false;
+}
+
+/* Iteration. */
+
+static void advance_to_matching(upb_symtab_iter *iter) {
+ if (iter->type == UPB_DEF_ANY)
+ return;
+
+ while (!upb_strtable_done(&iter->iter) &&
+ iter->type != upb_symtab_iter_def(iter)->type) {
+ upb_strtable_next(&iter->iter);
+ }
+}
+
+void upb_symtab_begin(upb_symtab_iter *iter, const upb_symtab *s,
+ upb_deftype_t type) {
+ upb_strtable_begin(&iter->iter, &s->symtab);
+ iter->type = type;
+ advance_to_matching(iter);
+}
+
+void upb_symtab_next(upb_symtab_iter *iter) {
+ upb_strtable_next(&iter->iter);
+ advance_to_matching(iter);
+}
+
+bool upb_symtab_done(const upb_symtab_iter *iter) {
+ return upb_strtable_done(&iter->iter);
+}
+
+const upb_def *upb_symtab_iter_def(const upb_symtab_iter *iter) {
+ return upb_value_getptr(upb_strtable_iter_value(&iter->iter));
+}
+/*
+** upb_table Implementation
+**
+** Implementation is heavily inspired by Lua's ltable.c.
+*/
+
+
+#include <stdlib.h>
+#include <string.h>
+
+#define UPB_MAXARRSIZE 16 /* 64k. */
+
+/* From Chromium. */
+#define ARRAY_SIZE(x) \
+ ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
+
+static const double MAX_LOAD = 0.85;
+
+/* The minimum utilization of the array part of a mixed hash/array table. This
+ * is a speed/memory-usage tradeoff (though it's not straightforward because of
+ * cache effects). The lower this is, the more memory we'll use. */
+static const double MIN_DENSITY = 0.1;
+
+bool is_pow2(uint64_t v) { return v == 0 || (v & (v - 1)) == 0; }
+
+int log2ceil(uint64_t v) {
+ int ret = 0;
+ bool pow2 = is_pow2(v);
+ while (v >>= 1) ret++;
+ ret = pow2 ? ret : ret + 1; /* Ceiling. */
+ return UPB_MIN(UPB_MAXARRSIZE, ret);
+}
+
+char *upb_strdup(const char *s) {
+ return upb_strdup2(s, strlen(s));
+}
+
+char *upb_strdup2(const char *s, size_t len) {
+ size_t n;
+ char *p;
+
+ /* Prevent overflow errors. */
+ if (len == SIZE_MAX) return NULL;
+ /* Always null-terminate, even if binary data; but don't rely on the input to
+ * have a null-terminating byte since it may be a raw binary buffer. */
+ n = len + 1;
+ p = malloc(n);
+ if (p) {
+ memcpy(p, s, len);
+ p[len] = 0;
+ }
+ return p;
+}
+
+/* A type to represent the lookup key of either a strtable or an inttable. */
+typedef union {
+ uintptr_t num;
+ struct {
+ const char *str;
+ size_t len;
+ } str;
+} lookupkey_t;
+
+static lookupkey_t strkey2(const char *str, size_t len) {
+ lookupkey_t k;
+ k.str.str = str;
+ k.str.len = len;
+ return k;
+}
+
+static lookupkey_t intkey(uintptr_t key) {
+ lookupkey_t k;
+ k.num = key;
+ return k;
+}
+
+typedef uint32_t hashfunc_t(upb_tabkey key);
+typedef bool eqlfunc_t(upb_tabkey k1, lookupkey_t k2);
+
+/* Base table (shared code) ***************************************************/
+
+/* For when we need to cast away const. */
+static upb_tabent *mutable_entries(upb_table *t) {
+ return (upb_tabent*)t->entries;
+}
+
+static bool isfull(upb_table *t) {
+ return (double)(t->count + 1) / upb_table_size(t) > MAX_LOAD;
+}
+
+static bool init(upb_table *t, upb_ctype_t ctype, uint8_t size_lg2) {
+ size_t bytes;
+
+ t->count = 0;
+ t->ctype = ctype;
+ t->size_lg2 = size_lg2;
+ t->mask = upb_table_size(t) ? upb_table_size(t) - 1 : 0;
+ bytes = upb_table_size(t) * sizeof(upb_tabent);
+ if (bytes > 0) {
+ t->entries = malloc(bytes);
+ if (!t->entries) return false;
+ memset(mutable_entries(t), 0, bytes);
+ } else {
+ t->entries = NULL;
+ }
+ return true;
+}
+
+static void uninit(upb_table *t) { free(mutable_entries(t)); }
+
+static upb_tabent *emptyent(upb_table *t) {
+ upb_tabent *e = mutable_entries(t) + upb_table_size(t);
+ while (1) { if (upb_tabent_isempty(--e)) return e; assert(e > t->entries); }
+}
+
+static upb_tabent *getentry_mutable(upb_table *t, uint32_t hash) {
+ return (upb_tabent*)upb_getentry(t, hash);
+}
+
+static const upb_tabent *findentry(const upb_table *t, lookupkey_t key,
+ uint32_t hash, eqlfunc_t *eql) {
+ const upb_tabent *e;
+
+ if (t->size_lg2 == 0) return NULL;
+ e = upb_getentry(t, hash);
+ if (upb_tabent_isempty(e)) return NULL;
+ while (1) {
+ if (eql(e->key, key)) return e;
+ if ((e = e->next) == NULL) return NULL;
+ }
+}
+
+static upb_tabent *findentry_mutable(upb_table *t, lookupkey_t key,
+ uint32_t hash, eqlfunc_t *eql) {
+ return (upb_tabent*)findentry(t, key, hash, eql);
+}
+
+static bool lookup(const upb_table *t, lookupkey_t key, upb_value *v,
+ uint32_t hash, eqlfunc_t *eql) {
+ const upb_tabent *e = findentry(t, key, hash, eql);
+ if (e) {
+ if (v) {
+ _upb_value_setval(v, e->val.val, t->ctype);
+ }
+ return true;
+ } else {
+ return false;
+ }
+}
+
+/* The given key must not already exist in the table. */
+static void insert(upb_table *t, lookupkey_t key, upb_tabkey tabkey,
+ upb_value val, uint32_t hash,
+ hashfunc_t *hashfunc, eqlfunc_t *eql) {
+ upb_tabent *mainpos_e;
+ upb_tabent *our_e;
+
+ UPB_UNUSED(eql);
+ UPB_UNUSED(key);
+ assert(findentry(t, key, hash, eql) == NULL);
+ assert(val.ctype == t->ctype);
+
+ t->count++;
+ mainpos_e = getentry_mutable(t, hash);
+ our_e = mainpos_e;
+
+ if (upb_tabent_isempty(mainpos_e)) {
+ /* Our main position is empty; use it. */
+ our_e->next = NULL;
+ } else {
+ /* Collision. */
+ upb_tabent *new_e = emptyent(t);
+ /* Head of collider's chain. */
+ upb_tabent *chain = getentry_mutable(t, hashfunc(mainpos_e->key));
+ if (chain == mainpos_e) {
+ /* Existing ent is in its main posisiton (it has the same hash as us, and
+ * is the head of our chain). Insert to new ent and append to this chain. */
+ new_e->next = mainpos_e->next;
+ mainpos_e->next = new_e;
+ our_e = new_e;
+ } else {
+ /* Existing ent is not in its main position (it is a node in some other
+ * chain). This implies that no existing ent in the table has our hash.
+ * Evict it (updating its chain) and use its ent for head of our chain. */
+ *new_e = *mainpos_e; /* copies next. */
+ while (chain->next != mainpos_e) {
+ chain = (upb_tabent*)chain->next;
+ assert(chain);
+ }
+ chain->next = new_e;
+ our_e = mainpos_e;
+ our_e->next = NULL;
+ }
+ }
+ our_e->key = tabkey;
+ our_e->val.val = val.val;
+ assert(findentry(t, key, hash, eql) == our_e);
+}
+
+static bool rm(upb_table *t, lookupkey_t key, upb_value *val,
+ upb_tabkey *removed, uint32_t hash, eqlfunc_t *eql) {
+ upb_tabent *chain = getentry_mutable(t, hash);
+ if (upb_tabent_isempty(chain)) return false;
+ if (eql(chain->key, key)) {
+ /* Element to remove is at the head of its chain. */
+ t->count--;
+ if (val) {
+ _upb_value_setval(val, chain->val.val, t->ctype);
+ }
+ if (chain->next) {
+ upb_tabent *move = (upb_tabent*)chain->next;
+ *chain = *move;
+ if (removed) *removed = move->key;
+ move->key = 0; /* Make the slot empty. */
+ } else {
+ if (removed) *removed = chain->key;
+ chain->key = 0; /* Make the slot empty. */
+ }
+ return true;
+ } else {
+ /* Element to remove is either in a non-head position or not in the
+ * table. */
+ while (chain->next && !eql(chain->next->key, key))
+ chain = (upb_tabent*)chain->next;
+ if (chain->next) {
+ /* Found element to remove. */
+ upb_tabent *rm;
+
+ if (val) {
+ _upb_value_setval(val, chain->next->val.val, t->ctype);
+ }
+ rm = (upb_tabent*)chain->next;
+ if (removed) *removed = rm->key;
+ rm->key = 0;
+ chain->next = rm->next;
+ t->count--;
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
+
+static size_t next(const upb_table *t, size_t i) {
+ do {
+ if (++i >= upb_table_size(t))
+ return SIZE_MAX;
+ } while(upb_tabent_isempty(&t->entries[i]));
+
+ return i;
+}
+
+static size_t begin(const upb_table *t) {
+ return next(t, -1);
+}
+
+
+/* upb_strtable ***************************************************************/
+
+/* A simple "subclass" of upb_table that only adds a hash function for strings. */
+
+static upb_tabkey strcopy(lookupkey_t k2) {
+ char *str = malloc(k2.str.len + sizeof(uint32_t) + 1);
+ if (str == NULL) return 0;
+ memcpy(str, &k2.str.len, sizeof(uint32_t));
+ memcpy(str + sizeof(uint32_t), k2.str.str, k2.str.len + 1);
+ return (uintptr_t)str;
+}
+
+static uint32_t strhash(upb_tabkey key) {
+ uint32_t len;
+ char *str = upb_tabstr(key, &len);
+ return MurmurHash2(str, len, 0);
+}
+
+static bool streql(upb_tabkey k1, lookupkey_t k2) {
+ uint32_t len;
+ char *str = upb_tabstr(k1, &len);
+ return len == k2.str.len && memcmp(str, k2.str.str, len) == 0;
+}
+
+bool upb_strtable_init(upb_strtable *t, upb_ctype_t ctype) {
+ return init(&t->t, ctype, 2);
+}
+
+void upb_strtable_uninit(upb_strtable *t) {
+ size_t i;
+ for (i = 0; i < upb_table_size(&t->t); i++)
+ free((void*)t->t.entries[i].key);
+ uninit(&t->t);
+}
+
+bool upb_strtable_resize(upb_strtable *t, size_t size_lg2) {
+ upb_strtable new_table;
+ upb_strtable_iter i;
+
+ if (!init(&new_table.t, t->t.ctype, size_lg2))
+ return false;
+ upb_strtable_begin(&i, t);
+ for ( ; !upb_strtable_done(&i); upb_strtable_next(&i)) {
+ upb_strtable_insert2(
+ &new_table,
+ upb_strtable_iter_key(&i),
+ upb_strtable_iter_keylength(&i),
+ upb_strtable_iter_value(&i));
+ }
+ upb_strtable_uninit(t);
+ *t = new_table;
+ return true;
+}
+
+bool upb_strtable_insert2(upb_strtable *t, const char *k, size_t len,
+ upb_value v) {
+ lookupkey_t key;
+ upb_tabkey tabkey;
+ uint32_t hash;
+
+ if (isfull(&t->t)) {
+ /* Need to resize. New table of double the size, add old elements to it. */
+ if (!upb_strtable_resize(t, t->t.size_lg2 + 1)) {
+ return false;
+ }
+ }
+
+ key = strkey2(k, len);
+ tabkey = strcopy(key);
+ if (tabkey == 0) return false;
+
+ hash = MurmurHash2(key.str.str, key.str.len, 0);
+ insert(&t->t, key, tabkey, v, hash, &strhash, &streql);
+ return true;
+}
+
+bool upb_strtable_lookup2(const upb_strtable *t, const char *key, size_t len,
+ upb_value *v) {
+ uint32_t hash = MurmurHash2(key, len, 0);
+ return lookup(&t->t, strkey2(key, len), v, hash, &streql);
+}
+
+bool upb_strtable_remove2(upb_strtable *t, const char *key, size_t len,
+ upb_value *val) {
+ uint32_t hash = MurmurHash2(key, strlen(key), 0);
+ upb_tabkey tabkey;
+ if (rm(&t->t, strkey2(key, len), val, &tabkey, hash, &streql)) {
+ free((void*)tabkey);
+ return true;
+ } else {
+ return false;
+ }
+}
+
+/* Iteration */
+
+static const upb_tabent *str_tabent(const upb_strtable_iter *i) {
+ return &i->t->t.entries[i->index];
+}
+
+void upb_strtable_begin(upb_strtable_iter *i, const upb_strtable *t) {
+ i->t = t;
+ i->index = begin(&t->t);
+}
+
+void upb_strtable_next(upb_strtable_iter *i) {
+ i->index = next(&i->t->t, i->index);
+}
+
+bool upb_strtable_done(const upb_strtable_iter *i) {
+ return i->index >= upb_table_size(&i->t->t) ||
+ upb_tabent_isempty(str_tabent(i));
+}
+
+const char *upb_strtable_iter_key(upb_strtable_iter *i) {
+ assert(!upb_strtable_done(i));
+ return upb_tabstr(str_tabent(i)->key, NULL);
+}
+
+size_t upb_strtable_iter_keylength(upb_strtable_iter *i) {
+ uint32_t len;
+ assert(!upb_strtable_done(i));
+ upb_tabstr(str_tabent(i)->key, &len);
+ return len;
+}
+
+upb_value upb_strtable_iter_value(const upb_strtable_iter *i) {
+ assert(!upb_strtable_done(i));
+ return _upb_value_val(str_tabent(i)->val.val, i->t->t.ctype);
+}
+
+void upb_strtable_iter_setdone(upb_strtable_iter *i) {
+ i->index = SIZE_MAX;
+}
+
+bool upb_strtable_iter_isequal(const upb_strtable_iter *i1,
+ const upb_strtable_iter *i2) {
+ if (upb_strtable_done(i1) && upb_strtable_done(i2))
+ return true;
+ return i1->t == i2->t && i1->index == i2->index;
+}
+
+
+/* upb_inttable ***************************************************************/
+
+/* For inttables we use a hybrid structure where small keys are kept in an
+ * array and large keys are put in the hash table. */
+
+static uint32_t inthash(upb_tabkey key) { return upb_inthash(key); }
+
+static bool inteql(upb_tabkey k1, lookupkey_t k2) {
+ return k1 == k2.num;
+}
+
+static upb_tabval *mutable_array(upb_inttable *t) {
+ return (upb_tabval*)t->array;
+}
+
+static upb_tabval *inttable_val(upb_inttable *t, uintptr_t key) {
+ if (key < t->array_size) {
+ return upb_arrhas(t->array[key]) ? &(mutable_array(t)[key]) : NULL;
+ } else {
+ upb_tabent *e =
+ findentry_mutable(&t->t, intkey(key), upb_inthash(key), &inteql);
+ return e ? &e->val : NULL;
+ }
+}
+
+static const upb_tabval *inttable_val_const(const upb_inttable *t,
+ uintptr_t key) {
+ return inttable_val((upb_inttable*)t, key);
+}
+
+size_t upb_inttable_count(const upb_inttable *t) {
+ return t->t.count + t->array_count;
+}
+
+static void check(upb_inttable *t) {
+ UPB_UNUSED(t);
+#if defined(UPB_DEBUG_TABLE) && !defined(NDEBUG)
+ {
+ /* This check is very expensive (makes inserts/deletes O(N)). */
+ size_t count = 0;
+ upb_inttable_iter i;
+ upb_inttable_begin(&i, t);
+ for(; !upb_inttable_done(&i); upb_inttable_next(&i), count++) {
+ assert(upb_inttable_lookup(t, upb_inttable_iter_key(&i), NULL));
+ }
+ assert(count == upb_inttable_count(t));
+ }
+#endif
+}
+
+bool upb_inttable_sizedinit(upb_inttable *t, upb_ctype_t ctype,
+ size_t asize, int hsize_lg2) {
+ size_t array_bytes;
+
+ if (!init(&t->t, ctype, hsize_lg2)) return false;
+ /* Always make the array part at least 1 long, so that we know key 0
+ * won't be in the hash part, which simplifies things. */
+ t->array_size = UPB_MAX(1, asize);
+ t->array_count = 0;
+ array_bytes = t->array_size * sizeof(upb_value);
+ t->array = malloc(array_bytes);
+ if (!t->array) {
+ uninit(&t->t);
+ return false;
+ }
+ memset(mutable_array(t), 0xff, array_bytes);
+ check(t);
+ return true;
+}
+
+bool upb_inttable_init(upb_inttable *t, upb_ctype_t ctype) {
+ return upb_inttable_sizedinit(t, ctype, 0, 4);
+}
+
+void upb_inttable_uninit(upb_inttable *t) {
+ uninit(&t->t);
+ free(mutable_array(t));
+}
+
+bool upb_inttable_insert(upb_inttable *t, uintptr_t key, upb_value val) {
+ /* XXX: Table can't store value (uint64_t)-1. Need to somehow statically
+ * guarantee that this is not necessary, or fix the limitation. */
+ upb_tabval tabval;
+ tabval.val = val.val;
+ UPB_UNUSED(tabval);
+ assert(upb_arrhas(tabval));
+
+ if (key < t->array_size) {
+ assert(!upb_arrhas(t->array[key]));
+ t->array_count++;
+ mutable_array(t)[key].val = val.val;
+ } else {
+ if (isfull(&t->t)) {
+ /* Need to resize the hash part, but we re-use the array part. */
+ size_t i;
+ upb_table new_table;
+ if (!init(&new_table, t->t.ctype, t->t.size_lg2 + 1))
+ return false;
+ for (i = begin(&t->t); i < upb_table_size(&t->t); i = next(&t->t, i)) {
+ const upb_tabent *e = &t->t.entries[i];
+ uint32_t hash;
+ upb_value v;
+
+ _upb_value_setval(&v, e->val.val, t->t.ctype);
+ hash = upb_inthash(e->key);
+ insert(&new_table, intkey(e->key), e->key, v, hash, &inthash, &inteql);
+ }
+
+ assert(t->t.count == new_table.count);
+
+ uninit(&t->t);
+ t->t = new_table;
+ }
+ insert(&t->t, intkey(key), key, val, upb_inthash(key), &inthash, &inteql);
+ }
+ check(t);
+ return true;
+}
+
+bool upb_inttable_lookup(const upb_inttable *t, uintptr_t key, upb_value *v) {
+ const upb_tabval *table_v = inttable_val_const(t, key);
+ if (!table_v) return false;
+ if (v) _upb_value_setval(v, table_v->val, t->t.ctype);
+ return true;
+}
+
+bool upb_inttable_replace(upb_inttable *t, uintptr_t key, upb_value val) {
+ upb_tabval *table_v = inttable_val(t, key);
+ if (!table_v) return false;
+ table_v->val = val.val;
+ return true;
+}
+
+bool upb_inttable_remove(upb_inttable *t, uintptr_t key, upb_value *val) {
+ bool success;
+ if (key < t->array_size) {
+ if (upb_arrhas(t->array[key])) {
+ upb_tabval empty = UPB_TABVALUE_EMPTY_INIT;
+ t->array_count--;
+ if (val) {
+ _upb_value_setval(val, t->array[key].val, t->t.ctype);
+ }
+ mutable_array(t)[key] = empty;
+ success = true;
+ } else {
+ success = false;
+ }
+ } else {
+ upb_tabkey removed;
+ uint32_t hash = upb_inthash(key);
+ success = rm(&t->t, intkey(key), val, &removed, hash, &inteql);
+ }
+ check(t);
+ return success;
+}
+
+bool upb_inttable_push(upb_inttable *t, upb_value val) {
+ return upb_inttable_insert(t, upb_inttable_count(t), val);
+}
+
+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_VAR(ok, ok);
+ return val;
+}
+
+bool upb_inttable_insertptr(upb_inttable *t, const void *key, upb_value val) {
+ return upb_inttable_insert(t, (uintptr_t)key, val);
+}
+
+bool upb_inttable_lookupptr(const upb_inttable *t, const void *key,
+ upb_value *v) {
+ return upb_inttable_lookup(t, (uintptr_t)key, v);
+}
+
+bool upb_inttable_removeptr(upb_inttable *t, const void *key, upb_value *val) {
+ return upb_inttable_remove(t, (uintptr_t)key, val);
+}
+
+void upb_inttable_compact(upb_inttable *t) {
+ /* Create a power-of-two histogram of the table keys. */
+ int counts[UPB_MAXARRSIZE + 1] = {0};
+ uintptr_t max_key = 0;
+ upb_inttable_iter i;
+ size_t arr_size;
+ int arr_count;
+ upb_inttable new_t;
+
+ upb_inttable_begin(&i, t);
+ for (; !upb_inttable_done(&i); upb_inttable_next(&i)) {
+ uintptr_t key = upb_inttable_iter_key(&i);
+ if (key > max_key) {
+ max_key = key;
+ }
+ counts[log2ceil(key)]++;
+ }
+
+ arr_size = 1;
+ arr_count = upb_inttable_count(t);
+
+ if (upb_inttable_count(t) >= max_key * MIN_DENSITY) {
+ /* We can put 100% of the entries in the array part. */
+ arr_size = max_key + 1;
+ } else {
+ /* Find the largest power of two that satisfies the MIN_DENSITY
+ * definition. */
+ int size_lg2;
+ for (size_lg2 = ARRAY_SIZE(counts) - 1; size_lg2 > 1; size_lg2--) {
+ arr_size = 1 << size_lg2;
+ arr_count -= counts[size_lg2];
+ if (arr_count >= arr_size * MIN_DENSITY) {
+ break;
+ }
+ }
+ }
+
+ /* Array part must always be at least 1 entry large to catch lookups of key
+ * 0. Key 0 must always be in the array part because "0" in the hash part
+ * denotes an empty entry. */
+ arr_size = UPB_MAX(arr_size, 1);
+
+ {
+ /* Insert all elements into new, perfectly-sized table. */
+ int hash_count = upb_inttable_count(t) - arr_count;
+ int hash_size = hash_count ? (hash_count / MAX_LOAD) + 1 : 0;
+ int hashsize_lg2 = log2ceil(hash_size);
+
+ assert(hash_count >= 0);
+ upb_inttable_sizedinit(&new_t, t->t.ctype, arr_size, hashsize_lg2);
+ upb_inttable_begin(&i, t);
+ for (; !upb_inttable_done(&i); upb_inttable_next(&i)) {
+ uintptr_t k = upb_inttable_iter_key(&i);
+ upb_inttable_insert(&new_t, k, upb_inttable_iter_value(&i));
+ }
+ assert(new_t.array_size == arr_size);
+ assert(new_t.t.size_lg2 == hashsize_lg2);
+ }
+ upb_inttable_uninit(t);
+ *t = new_t;
+}
+
+/* Iteration. */
+
+static const upb_tabent *int_tabent(const upb_inttable_iter *i) {
+ assert(!i->array_part);
+ return &i->t->t.entries[i->index];
+}
+
+static upb_tabval int_arrent(const upb_inttable_iter *i) {
+ assert(i->array_part);
+ return i->t->array[i->index];
+}
+
+void upb_inttable_begin(upb_inttable_iter *i, const upb_inttable *t) {
+ i->t = t;
+ i->index = -1;
+ i->array_part = true;
+ upb_inttable_next(i);
+}
+
+void upb_inttable_next(upb_inttable_iter *iter) {
+ const upb_inttable *t = iter->t;
+ if (iter->array_part) {
+ while (++iter->index < t->array_size) {
+ if (upb_arrhas(int_arrent(iter))) {
+ return;
+ }
+ }
+ iter->array_part = false;
+ iter->index = begin(&t->t);
+ } else {
+ iter->index = next(&t->t, iter->index);
+ }
+}
+
+bool upb_inttable_done(const upb_inttable_iter *i) {
+ if (i->array_part) {
+ return i->index >= i->t->array_size ||
+ !upb_arrhas(int_arrent(i));
+ } else {
+ return i->index >= upb_table_size(&i->t->t) ||
+ upb_tabent_isempty(int_tabent(i));
+ }
+}
+
+uintptr_t upb_inttable_iter_key(const upb_inttable_iter *i) {
+ assert(!upb_inttable_done(i));
+ return i->array_part ? i->index : int_tabent(i)->key;
+}
+
+upb_value upb_inttable_iter_value(const upb_inttable_iter *i) {
+ assert(!upb_inttable_done(i));
+ return _upb_value_val(
+ i->array_part ? i->t->array[i->index].val : int_tabent(i)->val.val,
+ i->t->t.ctype);
+}
+
+void upb_inttable_iter_setdone(upb_inttable_iter *i) {
+ i->index = SIZE_MAX;
+ i->array_part = false;
+}
+
+bool upb_inttable_iter_isequal(const upb_inttable_iter *i1,
+ const upb_inttable_iter *i2) {
+ if (upb_inttable_done(i1) && upb_inttable_done(i2))
+ return true;
+ return i1->t == i2->t && i1->index == i2->index &&
+ i1->array_part == i2->array_part;
+}
+
+#ifdef UPB_UNALIGNED_READS_OK
+/* -----------------------------------------------------------------------------
+ * MurmurHash2, by Austin Appleby (released as public domain).
+ * Reformatted and C99-ified by Joshua Haberman.
+ * Note - This code makes a few assumptions about how your machine behaves -
+ * 1. We can read a 4-byte value from any address without crashing
+ * 2. sizeof(int) == 4 (in upb this limitation is removed by using uint32_t
+ * And it has a few limitations -
+ * 1. It will not work incrementally.
+ * 2. It will not produce the same results on little-endian and big-endian
+ * machines. */
+uint32_t MurmurHash2(const void *key, size_t len, uint32_t seed) {
+ /* 'm' and 'r' are mixing constants generated offline.
+ * They're not really 'magic', they just happen to work well. */
+ const uint32_t m = 0x5bd1e995;
+ const int32_t r = 24;
+
+ /* Initialize the hash to a 'random' value */
+ uint32_t h = seed ^ len;
+
+ /* Mix 4 bytes at a time into the hash */
+ const uint8_t * data = (const uint8_t *)key;
+ while(len >= 4) {
+ uint32_t k = *(uint32_t *)data;
+
+ k *= m;
+ k ^= k >> r;
+ k *= m;
+
+ h *= m;
+ h ^= k;
+
+ data += 4;
+ len -= 4;
+ }
+
+ /* Handle the last few bytes of the input array */
+ switch(len) {
+ case 3: h ^= data[2] << 16;
+ case 2: h ^= data[1] << 8;
+ case 1: h ^= data[0]; h *= m;
+ };
+
+ /* Do a few final mixes of the hash to ensure the last few
+ * bytes are well-incorporated. */
+ h ^= h >> 13;
+ h *= m;
+ h ^= h >> 15;
+
+ return h;
+}
+
+#else /* !UPB_UNALIGNED_READS_OK */
+
+/* -----------------------------------------------------------------------------
+ * MurmurHashAligned2, by Austin Appleby
+ * Same algorithm as MurmurHash2, but only does aligned reads - should be safer
+ * on certain platforms.
+ * Performance will be lower than MurmurHash2 */
+
+#define MIX(h,k,m) { k *= m; k ^= k >> r; k *= m; h *= m; h ^= k; }
+
+uint32_t MurmurHash2(const void * key, size_t len, uint32_t seed) {
+ const uint32_t m = 0x5bd1e995;
+ const int32_t r = 24;
+ const uint8_t * data = (const uint8_t *)key;
+ uint32_t h = seed ^ len;
+ uint8_t align = (uintptr_t)data & 3;
+
+ if(align && (len >= 4)) {
+ /* Pre-load the temp registers */
+ uint32_t t = 0, d = 0;
+ int32_t sl;
+ int32_t sr;
+
+ switch(align) {
+ case 1: t |= data[2] << 16;
+ case 2: t |= data[1] << 8;
+ case 3: t |= data[0];
+ }
+
+ t <<= (8 * align);
+
+ data += 4-align;
+ len -= 4-align;
+
+ sl = 8 * (4-align);
+ sr = 8 * align;
+
+ /* Mix */
+
+ while(len >= 4) {
+ uint32_t k;
+
+ d = *(uint32_t *)data;
+ t = (t >> sr) | (d << sl);
+
+ k = t;
+
+ MIX(h,k,m);
+
+ t = d;
+
+ data += 4;
+ len -= 4;
+ }
+
+ /* Handle leftover data in temp registers */
+
+ d = 0;
+
+ if(len >= align) {
+ uint32_t k;
+
+ switch(align) {
+ case 3: d |= data[2] << 16;
+ case 2: d |= data[1] << 8;
+ case 1: d |= data[0];
+ }
+
+ k = (t >> sr) | (d << sl);
+ MIX(h,k,m);
+
+ data += align;
+ len -= align;
+
+ /* ----------
+ * Handle tail bytes */
+
+ switch(len) {
+ case 3: h ^= data[2] << 16;
+ case 2: h ^= data[1] << 8;
+ case 1: h ^= data[0]; h *= m;
+ };
+ } else {
+ switch(len) {
+ case 3: d |= data[2] << 16;
+ case 2: d |= data[1] << 8;
+ case 1: d |= data[0];
+ case 0: h ^= (t >> sr) | (d << sl); h *= m;
+ }
+ }
+
+ h ^= h >> 13;
+ h *= m;
+ h ^= h >> 15;
+
+ return h;
+ } else {
+ while(len >= 4) {
+ uint32_t k = *(uint32_t *)data;
+
+ MIX(h,k,m);
+
+ data += 4;
+ len -= 4;
+ }
+
+ /* ----------
+ * Handle tail bytes */
+
+ switch(len) {
+ case 3: h ^= data[2] << 16;
+ case 2: h ^= data[1] << 8;
+ case 1: h ^= data[0]; h *= m;
+ };
+
+ h ^= h >> 13;
+ h *= m;
+ h ^= h >> 15;
+
+ return h;
+ }
+}
+#undef MIX
+
+#endif /* UPB_UNALIGNED_READS_OK */
+
+#include <errno.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+bool upb_dumptostderr(void *closure, const upb_status* status) {
+ UPB_UNUSED(closure);
+ fprintf(stderr, "%s\n", upb_status_errmsg(status));
+ return false;
+}
+
+/* Guarantee null-termination and provide ellipsis truncation.
+ * It may be tempting to "optimize" this by initializing these final
+ * four bytes up-front and then being careful never to overwrite them,
+ * this is safer and simpler. */
+static void nullz(upb_status *status) {
+ const char *ellipsis = "...";
+ size_t len = strlen(ellipsis);
+ assert(sizeof(status->msg) > len);
+ memcpy(status->msg + sizeof(status->msg) - len, ellipsis, len);
+}
+
+void upb_status_clear(upb_status *status) {
+ if (!status) return;
+ status->ok_ = true;
+ status->code_ = 0;
+ status->msg[0] = '\0';
+}
+
+bool upb_ok(const upb_status *status) { return status->ok_; }
+
+upb_errorspace *upb_status_errspace(const upb_status *status) {
+ return status->error_space_;
+}
+
+int upb_status_errcode(const upb_status *status) { return status->code_; }
+
+const char *upb_status_errmsg(const upb_status *status) { return status->msg; }
+
+void upb_status_seterrmsg(upb_status *status, const char *msg) {
+ if (!status) return;
+ status->ok_ = false;
+ strncpy(status->msg, msg, sizeof(status->msg));
+ nullz(status);
+}
+
+void upb_status_seterrf(upb_status *status, const char *fmt, ...) {
+ va_list args;
+ va_start(args, fmt);
+ upb_status_vseterrf(status, fmt, args);
+ va_end(args);
+}
+
+void upb_status_vseterrf(upb_status *status, const char *fmt, va_list args) {
+ if (!status) return;
+ status->ok_ = false;
+ _upb_vsnprintf(status->msg, sizeof(status->msg), fmt, args);
+ nullz(status);
+}
+
+void upb_status_seterrcode(upb_status *status, upb_errorspace *space,
+ int code) {
+ if (!status) return;
+ status->ok_ = false;
+ status->error_space_ = space;
+ status->code_ = code;
+ space->set_message(status, code);
+}
+
+void upb_status_copy(upb_status *to, const upb_status *from) {
+ if (!to) return;
+ *to = *from;
+}
+/* This file was generated by upbc (the upb compiler).
+ * Do not edit -- your changes will be discarded when the file is
+ * regenerated. */
+
+
+static const upb_msgdef msgs[20];
+static const upb_fielddef fields[81];
+static const upb_enumdef enums[4];
+static const upb_tabent strentries[236];
+static const upb_tabent intentries[14];
+static const upb_tabval arrays[232];
+
+#ifdef UPB_DEBUG_REFS
+static upb_inttable reftables[212];
+#endif
+
+static const upb_msgdef msgs[20] = {
+ UPB_MSGDEF_INIT("google.protobuf.DescriptorProto", 27, 6, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[0], 8, 7), UPB_STRTABLE_INIT(7, 15, UPB_CTYPE_PTR, 4, &strentries[0]),&reftables[0], &reftables[1]),
+ UPB_MSGDEF_INIT("google.protobuf.DescriptorProto.ExtensionRange", 4, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[8], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[16]),&reftables[2], &reftables[3]),
+ UPB_MSGDEF_INIT("google.protobuf.EnumDescriptorProto", 11, 2, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[11], 4, 3), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[20]),&reftables[4], &reftables[5]),
+ UPB_MSGDEF_INIT("google.protobuf.EnumOptions", 7, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[0], &arrays[15], 8, 1), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[24]),&reftables[6], &reftables[7]),
+ UPB_MSGDEF_INIT("google.protobuf.EnumValueDescriptorProto", 8, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[23], 4, 3), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[28]),&reftables[8], &reftables[9]),
+ UPB_MSGDEF_INIT("google.protobuf.EnumValueOptions", 6, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[2], &arrays[27], 4, 0), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[32]),&reftables[10], &reftables[11]),
+ UPB_MSGDEF_INIT("google.protobuf.FieldDescriptorProto", 19, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[31], 9, 8), UPB_STRTABLE_INIT(8, 15, UPB_CTYPE_PTR, 4, &strentries[36]),&reftables[12], &reftables[13]),
+ UPB_MSGDEF_INIT("google.protobuf.FieldOptions", 14, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[4], &arrays[40], 32, 6), UPB_STRTABLE_INIT(7, 15, UPB_CTYPE_PTR, 4, &strentries[52]),&reftables[14], &reftables[15]),
+ UPB_MSGDEF_INIT("google.protobuf.FileDescriptorProto", 39, 6, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[72], 12, 11), UPB_STRTABLE_INIT(11, 15, UPB_CTYPE_PTR, 4, &strentries[68]),&reftables[16], &reftables[17]),
+ UPB_MSGDEF_INIT("google.protobuf.FileDescriptorSet", 6, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[84], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[84]),&reftables[18], &reftables[19]),
+ UPB_MSGDEF_INIT("google.protobuf.FileOptions", 21, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[6], &arrays[86], 64, 9), UPB_STRTABLE_INIT(10, 15, UPB_CTYPE_PTR, 4, &strentries[88]),&reftables[20], &reftables[21]),
+ UPB_MSGDEF_INIT("google.protobuf.MessageOptions", 8, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[8], &arrays[150], 16, 2), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[104]),&reftables[22], &reftables[23]),
+ UPB_MSGDEF_INIT("google.protobuf.MethodDescriptorProto", 13, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[166], 5, 4), UPB_STRTABLE_INIT(4, 7, UPB_CTYPE_PTR, 3, &strentries[108]),&reftables[24], &reftables[25]),
+ UPB_MSGDEF_INIT("google.protobuf.MethodOptions", 6, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[10], &arrays[171], 4, 0), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[116]),&reftables[26], &reftables[27]),
+ UPB_MSGDEF_INIT("google.protobuf.ServiceDescriptorProto", 11, 2, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[175], 4, 3), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[120]),&reftables[28], &reftables[29]),
+ UPB_MSGDEF_INIT("google.protobuf.ServiceOptions", 6, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[12], &arrays[179], 4, 0), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[124]),&reftables[30], &reftables[31]),
+ UPB_MSGDEF_INIT("google.protobuf.SourceCodeInfo", 6, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[183], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[128]),&reftables[32], &reftables[33]),
+ UPB_MSGDEF_INIT("google.protobuf.SourceCodeInfo.Location", 14, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[185], 5, 4), UPB_STRTABLE_INIT(4, 7, UPB_CTYPE_PTR, 3, &strentries[132]),&reftables[34], &reftables[35]),
+ UPB_MSGDEF_INIT("google.protobuf.UninterpretedOption", 18, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[190], 9, 7), UPB_STRTABLE_INIT(7, 15, UPB_CTYPE_PTR, 4, &strentries[140]),&reftables[36], &reftables[37]),
+ UPB_MSGDEF_INIT("google.protobuf.UninterpretedOption.NamePart", 6, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[199], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[156]),&reftables[38], &reftables[39]),
+};
+
+static const upb_fielddef fields[81] = {
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "aggregate_value", 8, &msgs[18], NULL, 15, 6, {0},&reftables[40], &reftables[41]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "allow_alias", 2, &msgs[3], NULL, 6, 1, {0},&reftables[42], &reftables[43]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "cc_generic_services", 16, &msgs[10], NULL, 17, 6, {0},&reftables[44], &reftables[45]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "ctype", 1, &msgs[7], (const upb_def*)(&enums[2]), 6, 1, {0},&reftables[46], &reftables[47]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "default_value", 7, &msgs[6], NULL, 16, 7, {0},&reftables[48], &reftables[49]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_STRING, 0, false, false, false, false, "dependency", 3, &msgs[8], NULL, 30, 8, {0},&reftables[50], &reftables[51]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 3, &msgs[7], NULL, 8, 3, {0},&reftables[52], &reftables[53]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_DOUBLE, 0, false, false, false, false, "double_value", 6, &msgs[18], NULL, 11, 4, {0},&reftables[54], &reftables[55]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "end", 2, &msgs[1], NULL, 3, 1, {0},&reftables[56], &reftables[57]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "enum_type", 4, &msgs[0], (const upb_def*)(&msgs[2]), 16, 2, {0},&reftables[58], &reftables[59]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "enum_type", 5, &msgs[8], (const upb_def*)(&msgs[2]), 13, 1, {0},&reftables[60], &reftables[61]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "experimental_map_key", 9, &msgs[7], NULL, 10, 5, {0},&reftables[62], &reftables[63]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "extendee", 2, &msgs[6], NULL, 7, 2, {0},&reftables[64], &reftables[65]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "extension", 7, &msgs[8], (const upb_def*)(&msgs[6]), 19, 3, {0},&reftables[66], &reftables[67]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "extension", 6, &msgs[0], (const upb_def*)(&msgs[6]), 22, 4, {0},&reftables[68], &reftables[69]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "extension_range", 5, &msgs[0], (const upb_def*)(&msgs[1]), 19, 3, {0},&reftables[70], &reftables[71]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "field", 2, &msgs[0], (const upb_def*)(&msgs[6]), 10, 0, {0},&reftables[72], &reftables[73]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "file", 1, &msgs[9], (const upb_def*)(&msgs[8]), 5, 0, {0},&reftables[74], &reftables[75]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "go_package", 11, &msgs[10], NULL, 14, 5, {0},&reftables[76], &reftables[77]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "identifier_value", 3, &msgs[18], NULL, 6, 1, {0},&reftables[78], &reftables[79]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "input_type", 2, &msgs[12], NULL, 7, 2, {0},&reftables[80], &reftables[81]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REQUIRED, UPB_TYPE_BOOL, 0, false, false, false, false, "is_extension", 2, &msgs[19], NULL, 5, 1, {0},&reftables[82], &reftables[83]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "java_generate_equals_and_hash", 20, &msgs[10], NULL, 20, 9, {0},&reftables[84], &reftables[85]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "java_generic_services", 17, &msgs[10], NULL, 18, 7, {0},&reftables[86], &reftables[87]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "java_multiple_files", 10, &msgs[10], NULL, 13, 4, {0},&reftables[88], &reftables[89]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "java_outer_classname", 8, &msgs[10], NULL, 9, 2, {0},&reftables[90], &reftables[91]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "java_package", 1, &msgs[10], NULL, 6, 1, {0},&reftables[92], &reftables[93]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "label", 4, &msgs[6], (const upb_def*)(&enums[0]), 11, 4, {0},&reftables[94], &reftables[95]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "lazy", 5, &msgs[7], NULL, 9, 4, {0},&reftables[96], &reftables[97]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "leading_comments", 3, &msgs[17], NULL, 8, 2, {0},&reftables[98], &reftables[99]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "location", 1, &msgs[16], (const upb_def*)(&msgs[17]), 5, 0, {0},&reftables[100], &reftables[101]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "message_set_wire_format", 1, &msgs[11], NULL, 6, 1, {0},&reftables[102], &reftables[103]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "message_type", 4, &msgs[8], (const upb_def*)(&msgs[0]), 10, 0, {0},&reftables[104], &reftables[105]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "method", 2, &msgs[14], (const upb_def*)(&msgs[12]), 6, 0, {0},&reftables[106], &reftables[107]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[8], NULL, 22, 6, {0},&reftables[108], &reftables[109]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[14], NULL, 8, 2, {0},&reftables[110], &reftables[111]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "name", 2, &msgs[18], (const upb_def*)(&msgs[19]), 5, 0, {0},&reftables[112], &reftables[113]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[4], NULL, 4, 1, {0},&reftables[114], &reftables[115]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[0], NULL, 24, 6, {0},&reftables[116], &reftables[117]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[12], NULL, 4, 1, {0},&reftables[118], &reftables[119]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[2], NULL, 8, 2, {0},&reftables[120], &reftables[121]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[6], NULL, 4, 1, {0},&reftables[122], &reftables[123]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REQUIRED, UPB_TYPE_STRING, 0, false, false, false, false, "name_part", 1, &msgs[19], NULL, 2, 0, {0},&reftables[124], &reftables[125]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT64, UPB_INTFMT_VARIABLE, false, false, false, false, "negative_int_value", 5, &msgs[18], NULL, 10, 3, {0},&reftables[126], &reftables[127]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "nested_type", 3, &msgs[0], (const upb_def*)(&msgs[0]), 13, 1, {0},&reftables[128], &reftables[129]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "no_standard_descriptor_accessor", 2, &msgs[11], NULL, 7, 2, {0},&reftables[130], &reftables[131]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "number", 3, &msgs[6], NULL, 10, 3, {0},&reftables[132], &reftables[133]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "number", 2, &msgs[4], NULL, 7, 2, {0},&reftables[134], &reftables[135]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "optimize_for", 9, &msgs[10], (const upb_def*)(&enums[3]), 12, 3, {0},&reftables[136], &reftables[137]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 7, &msgs[0], (const upb_def*)(&msgs[11]), 23, 5, {0},&reftables[138], &reftables[139]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 3, &msgs[2], (const upb_def*)(&msgs[3]), 7, 1, {0},&reftables[140], &reftables[141]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 8, &msgs[6], (const upb_def*)(&msgs[7]), 3, 0, {0},&reftables[142], &reftables[143]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 3, &msgs[4], (const upb_def*)(&msgs[5]), 3, 0, {0},&reftables[144], &reftables[145]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 8, &msgs[8], (const upb_def*)(&msgs[10]), 20, 4, {0},&reftables[146], &reftables[147]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 3, &msgs[14], (const upb_def*)(&msgs[15]), 7, 1, {0},&reftables[148], &reftables[149]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 4, &msgs[12], (const upb_def*)(&msgs[13]), 3, 0, {0},&reftables[150], &reftables[151]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "output_type", 3, &msgs[12], NULL, 10, 3, {0},&reftables[152], &reftables[153]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "package", 2, &msgs[8], NULL, 25, 7, {0},&reftables[154], &reftables[155]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "packed", 2, &msgs[7], NULL, 7, 2, {0},&reftables[156], &reftables[157]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, true, "path", 1, &msgs[17], NULL, 4, 0, {0},&reftables[158], &reftables[159]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_UINT64, UPB_INTFMT_VARIABLE, false, false, false, false, "positive_int_value", 4, &msgs[18], NULL, 9, 2, {0},&reftables[160], &reftables[161]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "public_dependency", 10, &msgs[8], NULL, 35, 9, {0},&reftables[162], &reftables[163]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "py_generic_services", 18, &msgs[10], NULL, 19, 8, {0},&reftables[164], &reftables[165]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "service", 6, &msgs[8], (const upb_def*)(&msgs[14]), 16, 2, {0},&reftables[166], &reftables[167]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "source_code_info", 9, &msgs[8], (const upb_def*)(&msgs[16]), 21, 5, {0},&reftables[168], &reftables[169]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, true, "span", 2, &msgs[17], NULL, 7, 1, {0},&reftables[170], &reftables[171]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "start", 1, &msgs[1], NULL, 2, 0, {0},&reftables[172], &reftables[173]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BYTES, 0, false, false, false, false, "string_value", 7, &msgs[18], NULL, 12, 5, {0},&reftables[174], &reftables[175]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "trailing_comments", 4, &msgs[17], NULL, 11, 3, {0},&reftables[176], &reftables[177]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "type", 5, &msgs[6], (const upb_def*)(&enums[1]), 12, 5, {0},&reftables[178], &reftables[179]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "type_name", 6, &msgs[6], NULL, 13, 6, {0},&reftables[180], &reftables[181]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[5], (const upb_def*)(&msgs[18]), 5, 0, {0},&reftables[182], &reftables[183]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[15], (const upb_def*)(&msgs[18]), 5, 0, {0},&reftables[184], &reftables[185]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[3], (const upb_def*)(&msgs[18]), 5, 0, {0},&reftables[186], &reftables[187]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[13], (const upb_def*)(&msgs[18]), 5, 0, {0},&reftables[188], &reftables[189]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[10], (const upb_def*)(&msgs[18]), 5, 0, {0},&reftables[190], &reftables[191]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[11], (const upb_def*)(&msgs[18]), 5, 0, {0},&reftables[192], &reftables[193]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[7], (const upb_def*)(&msgs[18]), 5, 0, {0},&reftables[194], &reftables[195]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "value", 2, &msgs[2], (const upb_def*)(&msgs[4]), 6, 0, {0},&reftables[196], &reftables[197]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "weak", 10, &msgs[7], NULL, 13, 6, {0},&reftables[198], &reftables[199]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "weak_dependency", 11, &msgs[8], NULL, 38, 10, {0},&reftables[200], &reftables[201]),
+};
+
+static const upb_enumdef enums[4] = {
+ UPB_ENUMDEF_INIT("google.protobuf.FieldDescriptorProto.Label", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &strentries[160]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[202], 4, 3), 0, &reftables[202], &reftables[203]),
+ UPB_ENUMDEF_INIT("google.protobuf.FieldDescriptorProto.Type", UPB_STRTABLE_INIT(18, 31, UPB_CTYPE_INT32, 5, &strentries[164]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[206], 19, 18), 0, &reftables[204], &reftables[205]),
+ UPB_ENUMDEF_INIT("google.protobuf.FieldOptions.CType", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &strentries[196]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[225], 3, 3), 0, &reftables[206], &reftables[207]),
+ UPB_ENUMDEF_INIT("google.protobuf.FileOptions.OptimizeMode", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &strentries[200]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[228], 4, 3), 0, &reftables[208], &reftables[209]),
+};
+
+static const upb_tabent strentries[236] = {
+ {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "extension"), UPB_TABVALUE_PTR_INIT(&fields[14]), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[38]), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "field"), UPB_TABVALUE_PTR_INIT(&fields[16]), NULL},
+ {UPB_TABKEY_STR("\017", "\000", "\000", "\000", "extension_range"), UPB_TABVALUE_PTR_INIT(&fields[15]), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "nested_type"), UPB_TABVALUE_PTR_INIT(&fields[44]), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[49]), NULL},
+ {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "enum_type"), UPB_TABVALUE_PTR_INIT(&fields[9]), &strentries[14]},
+ {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "start"), UPB_TABVALUE_PTR_INIT(&fields[66]), NULL},
+ {UPB_TABKEY_STR("\003", "\000", "\000", "\000", "end"), UPB_TABVALUE_PTR_INIT(&fields[8]), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "value"), UPB_TABVALUE_PTR_INIT(&fields[78]), NULL},
+ {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[50]), NULL},
+ {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[40]), &strentries[22]},
+ {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[73]), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "allow_alias"), UPB_TABVALUE_PTR_INIT(&fields[1]), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "number"), UPB_TABVALUE_PTR_INIT(&fields[47]), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[52]), NULL},
+ {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[37]), &strentries[30]},
+ {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[71]), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "label"), UPB_TABVALUE_PTR_INIT(&fields[27]), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[41]), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "number"), UPB_TABVALUE_PTR_INIT(&fields[46]), &strentries[49]},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "type_name"), UPB_TABVALUE_PTR_INIT(&fields[70]), NULL},
+ {UPB_TABKEY_STR("\010", "\000", "\000", "\000", "extendee"), UPB_TABVALUE_PTR_INIT(&fields[12]), NULL},
+ {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "type"), UPB_TABVALUE_PTR_INIT(&fields[69]), &strentries[48]},
+ {UPB_TABKEY_STR("\015", "\000", "\000", "\000", "default_value"), UPB_TABVALUE_PTR_INIT(&fields[4]), NULL},
+ {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[51]), NULL},
+ {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "experimental_map_key"), UPB_TABVALUE_PTR_INIT(&fields[11]), &strentries[67]},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "weak"), UPB_TABVALUE_PTR_INIT(&fields[79]), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "packed"), UPB_TABVALUE_PTR_INIT(&fields[58]), NULL},
+ {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "lazy"), UPB_TABVALUE_PTR_INIT(&fields[28]), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "ctype"), UPB_TABVALUE_PTR_INIT(&fields[3]), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[6]), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[77]), NULL},
+ {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "extension"), UPB_TABVALUE_PTR_INIT(&fields[13]), NULL},
+ {UPB_TABKEY_STR("\017", "\000", "\000", "\000", "weak_dependency"), UPB_TABVALUE_PTR_INIT(&fields[80]), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[34]), NULL},
+ {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "service"), UPB_TABVALUE_PTR_INIT(&fields[63]), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "source_code_info"), UPB_TABVALUE_PTR_INIT(&fields[64]), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "dependency"), UPB_TABVALUE_PTR_INIT(&fields[5]), NULL},
+ {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "message_type"), UPB_TABVALUE_PTR_INIT(&fields[32]), NULL},
+ {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "package"), UPB_TABVALUE_PTR_INIT(&fields[57]), NULL},
+ {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[53]), &strentries[82]},
+ {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "enum_type"), UPB_TABVALUE_PTR_INIT(&fields[10]), NULL},
+ {UPB_TABKEY_STR("\021", "\000", "\000", "\000", "public_dependency"), UPB_TABVALUE_PTR_INIT(&fields[61]), &strentries[81]},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "file"), UPB_TABVALUE_PTR_INIT(&fields[17]), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[75]), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\023", "\000", "\000", "\000", "cc_generic_services"), UPB_TABVALUE_PTR_INIT(&fields[2]), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\023", "\000", "\000", "\000", "java_multiple_files"), UPB_TABVALUE_PTR_INIT(&fields[24]), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\025", "\000", "\000", "\000", "java_generic_services"), UPB_TABVALUE_PTR_INIT(&fields[23]), &strentries[102]},
+ {UPB_TABKEY_STR("\035", "\000", "\000", "\000", "java_generate_equals_and_hash"), UPB_TABVALUE_PTR_INIT(&fields[22]), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "go_package"), UPB_TABVALUE_PTR_INIT(&fields[18]), NULL},
+ {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "java_package"), UPB_TABVALUE_PTR_INIT(&fields[26]), NULL},
+ {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "optimize_for"), UPB_TABVALUE_PTR_INIT(&fields[48]), NULL},
+ {UPB_TABKEY_STR("\023", "\000", "\000", "\000", "py_generic_services"), UPB_TABVALUE_PTR_INIT(&fields[62]), NULL},
+ {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "java_outer_classname"), UPB_TABVALUE_PTR_INIT(&fields[25]), NULL},
+ {UPB_TABKEY_STR("\027", "\000", "\000", "\000", "message_set_wire_format"), UPB_TABVALUE_PTR_INIT(&fields[31]), &strentries[106]},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[76]), NULL},
+ {UPB_TABKEY_STR("\037", "\000", "\000", "\000", "no_standard_descriptor_accessor"), UPB_TABVALUE_PTR_INIT(&fields[45]), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[39]), NULL},
+ {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "input_type"), UPB_TABVALUE_PTR_INIT(&fields[20]), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "output_type"), UPB_TABVALUE_PTR_INIT(&fields[56]), NULL},
+ {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[55]), NULL},
+ {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[74]), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[54]), &strentries[122]},
+ {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "method"), UPB_TABVALUE_PTR_INIT(&fields[33]), NULL},
+ {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[35]), &strentries[121]},
+ {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[72]), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\010", "\000", "\000", "\000", "location"), UPB_TABVALUE_PTR_INIT(&fields[30]), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "span"), UPB_TABVALUE_PTR_INIT(&fields[65]), &strentries[139]},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\021", "\000", "\000", "\000", "trailing_comments"), UPB_TABVALUE_PTR_INIT(&fields[68]), NULL},
+ {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "leading_comments"), UPB_TABVALUE_PTR_INIT(&fields[29]), &strentries[137]},
+ {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "path"), UPB_TABVALUE_PTR_INIT(&fields[59]), NULL},
+ {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "double_value"), UPB_TABVALUE_PTR_INIT(&fields[7]), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[36]), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\022", "\000", "\000", "\000", "negative_int_value"), UPB_TABVALUE_PTR_INIT(&fields[43]), NULL},
+ {UPB_TABKEY_STR("\017", "\000", "\000", "\000", "aggregate_value"), UPB_TABVALUE_PTR_INIT(&fields[0]), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\022", "\000", "\000", "\000", "positive_int_value"), UPB_TABVALUE_PTR_INIT(&fields[60]), NULL},
+ {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "identifier_value"), UPB_TABVALUE_PTR_INIT(&fields[19]), NULL},
+ {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "string_value"), UPB_TABVALUE_PTR_INIT(&fields[67]), &strentries[154]},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "is_extension"), UPB_TABVALUE_PTR_INIT(&fields[21]), NULL},
+ {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "name_part"), UPB_TABVALUE_PTR_INIT(&fields[42]), NULL},
+ {UPB_TABKEY_STR("\016", "\000", "\000", "\000", "LABEL_REQUIRED"), UPB_TABVALUE_INT_INIT(2), &strentries[162]},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\016", "\000", "\000", "\000", "LABEL_REPEATED"), UPB_TABVALUE_INT_INIT(3), NULL},
+ {UPB_TABKEY_STR("\016", "\000", "\000", "\000", "LABEL_OPTIONAL"), UPB_TABVALUE_INT_INIT(1), NULL},
+ {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "TYPE_FIXED64"), UPB_TABVALUE_INT_INIT(6), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "TYPE_STRING"), UPB_TABVALUE_INT_INIT(9), NULL},
+ {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "TYPE_FLOAT"), UPB_TABVALUE_INT_INIT(2), &strentries[193]},
+ {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "TYPE_DOUBLE"), UPB_TABVALUE_INT_INIT(1), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "TYPE_INT32"), UPB_TABVALUE_INT_INIT(5), NULL},
+ {UPB_TABKEY_STR("\015", "\000", "\000", "\000", "TYPE_SFIXED32"), UPB_TABVALUE_INT_INIT(15), NULL},
+ {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "TYPE_FIXED32"), UPB_TABVALUE_INT_INIT(7), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "TYPE_MESSAGE"), UPB_TABVALUE_INT_INIT(11), &strentries[194]},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "TYPE_INT64"), UPB_TABVALUE_INT_INIT(3), &strentries[191]},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "TYPE_ENUM"), UPB_TABVALUE_INT_INIT(14), NULL},
+ {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "TYPE_UINT32"), UPB_TABVALUE_INT_INIT(13), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "TYPE_UINT64"), UPB_TABVALUE_INT_INIT(4), &strentries[190]},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\015", "\000", "\000", "\000", "TYPE_SFIXED64"), UPB_TABVALUE_INT_INIT(16), NULL},
+ {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "TYPE_BYTES"), UPB_TABVALUE_INT_INIT(12), NULL},
+ {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "TYPE_SINT64"), UPB_TABVALUE_INT_INIT(18), NULL},
+ {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "TYPE_BOOL"), UPB_TABVALUE_INT_INIT(8), NULL},
+ {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "TYPE_GROUP"), UPB_TABVALUE_INT_INIT(10), NULL},
+ {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "TYPE_SINT32"), UPB_TABVALUE_INT_INIT(17), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "CORD"), UPB_TABVALUE_INT_INIT(1), NULL},
+ {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "STRING"), UPB_TABVALUE_INT_INIT(0), &strentries[197]},
+ {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "STRING_PIECE"), UPB_TABVALUE_INT_INIT(2), NULL},
+ {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "CODE_SIZE"), UPB_TABVALUE_INT_INIT(2), NULL},
+ {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "SPEED"), UPB_TABVALUE_INT_INIT(1), &strentries[203]},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "LITE_RUNTIME"), UPB_TABVALUE_INT_INIT(3), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\047", "\000", "\000", "\000", "google.protobuf.SourceCodeInfo.Location"), UPB_TABVALUE_PTR_INIT(&msgs[17]), NULL},
+ {UPB_TABKEY_STR("\043", "\000", "\000", "\000", "google.protobuf.UninterpretedOption"), UPB_TABVALUE_PTR_INIT(&msgs[18]), NULL},
+ {UPB_TABKEY_STR("\043", "\000", "\000", "\000", "google.protobuf.FileDescriptorProto"), UPB_TABVALUE_PTR_INIT(&msgs[8]), NULL},
+ {UPB_TABKEY_STR("\045", "\000", "\000", "\000", "google.protobuf.MethodDescriptorProto"), UPB_TABVALUE_PTR_INIT(&msgs[12]), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\040", "\000", "\000", "\000", "google.protobuf.EnumValueOptions"), UPB_TABVALUE_PTR_INIT(&msgs[5]), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\037", "\000", "\000", "\000", "google.protobuf.DescriptorProto"), UPB_TABVALUE_PTR_INIT(&msgs[0]), &strentries[228]},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\036", "\000", "\000", "\000", "google.protobuf.SourceCodeInfo"), UPB_TABVALUE_PTR_INIT(&msgs[16]), NULL},
+ {UPB_TABKEY_STR("\051", "\000", "\000", "\000", "google.protobuf.FieldDescriptorProto.Type"), UPB_TABVALUE_PTR_INIT(&enums[1]), NULL},
+ {UPB_TABKEY_STR("\056", "\000", "\000", "\000", "google.protobuf.DescriptorProto.ExtensionRange"), UPB_TABVALUE_PTR_INIT(&msgs[1]), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\050", "\000", "\000", "\000", "google.protobuf.EnumValueDescriptorProto"), UPB_TABVALUE_PTR_INIT(&msgs[4]), NULL},
+ {UPB_TABKEY_STR("\034", "\000", "\000", "\000", "google.protobuf.FieldOptions"), UPB_TABVALUE_PTR_INIT(&msgs[7]), NULL},
+ {UPB_TABKEY_STR("\033", "\000", "\000", "\000", "google.protobuf.FileOptions"), UPB_TABVALUE_PTR_INIT(&msgs[10]), NULL},
+ {UPB_TABKEY_STR("\043", "\000", "\000", "\000", "google.protobuf.EnumDescriptorProto"), UPB_TABVALUE_PTR_INIT(&msgs[2]), &strentries[233]},
+ {UPB_TABKEY_STR("\052", "\000", "\000", "\000", "google.protobuf.FieldDescriptorProto.Label"), UPB_TABVALUE_PTR_INIT(&enums[0]), NULL},
+ {UPB_TABKEY_STR("\046", "\000", "\000", "\000", "google.protobuf.ServiceDescriptorProto"), UPB_TABVALUE_PTR_INIT(&msgs[14]), NULL},
+ {UPB_TABKEY_STR("\042", "\000", "\000", "\000", "google.protobuf.FieldOptions.CType"), UPB_TABVALUE_PTR_INIT(&enums[2]), &strentries[229]},
+ {UPB_TABKEY_STR("\041", "\000", "\000", "\000", "google.protobuf.FileDescriptorSet"), UPB_TABVALUE_PTR_INIT(&msgs[9]), &strentries[235]},
+ {UPB_TABKEY_STR("\033", "\000", "\000", "\000", "google.protobuf.EnumOptions"), UPB_TABVALUE_PTR_INIT(&msgs[3]), NULL},
+ {UPB_TABKEY_STR("\044", "\000", "\000", "\000", "google.protobuf.FieldDescriptorProto"), UPB_TABVALUE_PTR_INIT(&msgs[6]), NULL},
+ {UPB_TABKEY_STR("\050", "\000", "\000", "\000", "google.protobuf.FileOptions.OptimizeMode"), UPB_TABVALUE_PTR_INIT(&enums[3]), &strentries[221]},
+ {UPB_TABKEY_STR("\036", "\000", "\000", "\000", "google.protobuf.ServiceOptions"), UPB_TABVALUE_PTR_INIT(&msgs[15]), NULL},
+ {UPB_TABKEY_STR("\036", "\000", "\000", "\000", "google.protobuf.MessageOptions"), UPB_TABVALUE_PTR_INIT(&msgs[11]), NULL},
+ {UPB_TABKEY_STR("\035", "\000", "\000", "\000", "google.protobuf.MethodOptions"), UPB_TABVALUE_PTR_INIT(&msgs[13]), &strentries[226]},
+ {UPB_TABKEY_STR("\054", "\000", "\000", "\000", "google.protobuf.UninterpretedOption.NamePart"), UPB_TABVALUE_PTR_INIT(&msgs[19]), NULL},
+};
+
+static const upb_tabent intentries[14] = {
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[73]), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[71]), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[77]), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[75]), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[76]), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[74]), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[72]), NULL},
+};
+
+static const upb_tabval arrays[232] = {
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[38]),
+ UPB_TABVALUE_PTR_INIT(&fields[16]),
+ UPB_TABVALUE_PTR_INIT(&fields[44]),
+ UPB_TABVALUE_PTR_INIT(&fields[9]),
+ UPB_TABVALUE_PTR_INIT(&fields[15]),
+ UPB_TABVALUE_PTR_INIT(&fields[14]),
+ UPB_TABVALUE_PTR_INIT(&fields[49]),
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[66]),
+ UPB_TABVALUE_PTR_INIT(&fields[8]),
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[40]),
+ UPB_TABVALUE_PTR_INIT(&fields[78]),
+ UPB_TABVALUE_PTR_INIT(&fields[50]),
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[1]),
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[37]),
+ UPB_TABVALUE_PTR_INIT(&fields[47]),
+ UPB_TABVALUE_PTR_INIT(&fields[52]),
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[41]),
+ UPB_TABVALUE_PTR_INIT(&fields[12]),
+ UPB_TABVALUE_PTR_INIT(&fields[46]),
+ UPB_TABVALUE_PTR_INIT(&fields[27]),
+ UPB_TABVALUE_PTR_INIT(&fields[69]),
+ UPB_TABVALUE_PTR_INIT(&fields[70]),
+ UPB_TABVALUE_PTR_INIT(&fields[4]),
+ UPB_TABVALUE_PTR_INIT(&fields[51]),
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[3]),
+ UPB_TABVALUE_PTR_INIT(&fields[58]),
+ UPB_TABVALUE_PTR_INIT(&fields[6]),
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[28]),
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[11]),
+ UPB_TABVALUE_PTR_INIT(&fields[79]),
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[34]),
+ UPB_TABVALUE_PTR_INIT(&fields[57]),
+ UPB_TABVALUE_PTR_INIT(&fields[5]),
+ UPB_TABVALUE_PTR_INIT(&fields[32]),
+ UPB_TABVALUE_PTR_INIT(&fields[10]),
+ UPB_TABVALUE_PTR_INIT(&fields[63]),
+ UPB_TABVALUE_PTR_INIT(&fields[13]),
+ UPB_TABVALUE_PTR_INIT(&fields[53]),
+ UPB_TABVALUE_PTR_INIT(&fields[64]),
+ UPB_TABVALUE_PTR_INIT(&fields[61]),
+ UPB_TABVALUE_PTR_INIT(&fields[80]),
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[17]),
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[26]),
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[25]),
+ UPB_TABVALUE_PTR_INIT(&fields[48]),
+ UPB_TABVALUE_PTR_INIT(&fields[24]),
+ UPB_TABVALUE_PTR_INIT(&fields[18]),
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[2]),
+ UPB_TABVALUE_PTR_INIT(&fields[23]),
+ UPB_TABVALUE_PTR_INIT(&fields[62]),
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[22]),
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[31]),
+ UPB_TABVALUE_PTR_INIT(&fields[45]),
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[39]),
+ UPB_TABVALUE_PTR_INIT(&fields[20]),
+ UPB_TABVALUE_PTR_INIT(&fields[56]),
+ UPB_TABVALUE_PTR_INIT(&fields[55]),
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[35]),
+ UPB_TABVALUE_PTR_INIT(&fields[33]),
+ UPB_TABVALUE_PTR_INIT(&fields[54]),
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[30]),
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[59]),
+ UPB_TABVALUE_PTR_INIT(&fields[65]),
+ UPB_TABVALUE_PTR_INIT(&fields[29]),
+ UPB_TABVALUE_PTR_INIT(&fields[68]),
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[36]),
+ UPB_TABVALUE_PTR_INIT(&fields[19]),
+ UPB_TABVALUE_PTR_INIT(&fields[60]),
+ UPB_TABVALUE_PTR_INIT(&fields[43]),
+ UPB_TABVALUE_PTR_INIT(&fields[7]),
+ UPB_TABVALUE_PTR_INIT(&fields[67]),
+ UPB_TABVALUE_PTR_INIT(&fields[0]),
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[42]),
+ UPB_TABVALUE_PTR_INIT(&fields[21]),
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT("LABEL_OPTIONAL"),
+ UPB_TABVALUE_PTR_INIT("LABEL_REQUIRED"),
+ UPB_TABVALUE_PTR_INIT("LABEL_REPEATED"),
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT("TYPE_DOUBLE"),
+ UPB_TABVALUE_PTR_INIT("TYPE_FLOAT"),
+ UPB_TABVALUE_PTR_INIT("TYPE_INT64"),
+ UPB_TABVALUE_PTR_INIT("TYPE_UINT64"),
+ UPB_TABVALUE_PTR_INIT("TYPE_INT32"),
+ UPB_TABVALUE_PTR_INIT("TYPE_FIXED64"),
+ UPB_TABVALUE_PTR_INIT("TYPE_FIXED32"),
+ UPB_TABVALUE_PTR_INIT("TYPE_BOOL"),
+ UPB_TABVALUE_PTR_INIT("TYPE_STRING"),
+ UPB_TABVALUE_PTR_INIT("TYPE_GROUP"),
+ UPB_TABVALUE_PTR_INIT("TYPE_MESSAGE"),
+ UPB_TABVALUE_PTR_INIT("TYPE_BYTES"),
+ UPB_TABVALUE_PTR_INIT("TYPE_UINT32"),
+ UPB_TABVALUE_PTR_INIT("TYPE_ENUM"),
+ UPB_TABVALUE_PTR_INIT("TYPE_SFIXED32"),
+ UPB_TABVALUE_PTR_INIT("TYPE_SFIXED64"),
+ UPB_TABVALUE_PTR_INIT("TYPE_SINT32"),
+ UPB_TABVALUE_PTR_INIT("TYPE_SINT64"),
+ UPB_TABVALUE_PTR_INIT("STRING"),
+ UPB_TABVALUE_PTR_INIT("CORD"),
+ UPB_TABVALUE_PTR_INIT("STRING_PIECE"),
+ UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT("SPEED"),
+ UPB_TABVALUE_PTR_INIT("CODE_SIZE"),
+ UPB_TABVALUE_PTR_INIT("LITE_RUNTIME"),
+};
+
+static const upb_symtab symtab = UPB_SYMTAB_INIT(UPB_STRTABLE_INIT(24, 31, UPB_CTYPE_PTR, 5, &strentries[204]), &reftables[210], &reftables[211]);
+
+const upb_symtab *upbdefs_google_protobuf_descriptor(const void *owner) {
+ upb_symtab_ref(&symtab, owner);
+ return &symtab;
+}
+
+#ifdef UPB_DEBUG_REFS
+static upb_inttable reftables[212] = {
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+};
+#endif
+
+/*
+** XXX: The routines in this file that consume a string do not currently
+** support having the string span buffers. In the future, as upb_sink and
+** its buffering/sharing functionality evolve there should be an easy and
+** idiomatic way of correctly handling this case. For now, we accept this
+** limitation since we currently only parse descriptors from single strings.
+*/
+
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* upb_deflist is an internal-only dynamic array for storing a growing list of
+ * upb_defs. */
+typedef struct {
+ upb_def **defs;
+ size_t len;
+ size_t size;
+ bool owned;
+} upb_deflist;
+
+/* We keep a stack of all the messages scopes we are currently in, as well as
+ * the top-level file scope. This is necessary to correctly qualify the
+ * definitions that are contained inside. "name" tracks the name of the
+ * message or package (a bare name -- not qualified by any enclosing scopes). */
+typedef struct {
+ char *name;
+ /* Index of the first def that is under this scope. For msgdefs, the
+ * msgdef itself is at start-1. */
+ int start;
+} upb_descreader_frame;
+
+/* The maximum number of nested declarations that are allowed, ie.
+ * message Foo {
+ * message Bar {
+ * message Baz {
+ * }
+ * }
+ * }
+ *
+ * This is a resource limit that affects how big our runtime stack can grow.
+ * TODO: make this a runtime-settable property of the Reader instance. */
+#define UPB_MAX_MESSAGE_NESTING 64
+
+struct upb_descreader {
+ upb_sink sink;
+ upb_deflist defs;
+ upb_descreader_frame stack[UPB_MAX_MESSAGE_NESTING];
+ int stack_len;
+
+ uint32_t number;
+ char *name;
+ bool saw_number;
+ bool saw_name;
+
+ char *default_string;
+
+ upb_fielddef *f;
+};
+
+static char *upb_strndup(const char *buf, size_t n) {
+ char *ret = malloc(n + 1);
+ if (!ret) return NULL;
+ memcpy(ret, buf, n);
+ ret[n] = '\0';
+ return ret;
+}
+
+/* Returns a newly allocated string that joins input strings together, for
+ * example:
+ * join("Foo.Bar", "Baz") -> "Foo.Bar.Baz"
+ * join("", "Baz") -> "Baz"
+ * Caller owns a ref on the returned string. */
+static char *upb_join(const char *base, const char *name) {
+ if (!base || strlen(base) == 0) {
+ return upb_strdup(name);
+ } else {
+ char *ret = malloc(strlen(base) + strlen(name) + 2);
+ ret[0] = '\0';
+ strcat(ret, base);
+ strcat(ret, ".");
+ strcat(ret, name);
+ return ret;
+ }
+}
+
+
+/* upb_deflist ****************************************************************/
+
+void upb_deflist_init(upb_deflist *l) {
+ l->size = 0;
+ l->defs = NULL;
+ l->len = 0;
+ l->owned = true;
+}
+
+void upb_deflist_uninit(upb_deflist *l) {
+ size_t i;
+ if (l->owned)
+ for(i = 0; i < l->len; i++)
+ upb_def_unref(l->defs[i], l);
+ free(l->defs);
+}
+
+bool upb_deflist_push(upb_deflist *l, upb_def *d) {
+ if(++l->len >= l->size) {
+ size_t new_size = UPB_MAX(l->size, 4);
+ new_size *= 2;
+ l->defs = realloc(l->defs, new_size * sizeof(void *));
+ if (!l->defs) return false;
+ l->size = new_size;
+ }
+ l->defs[l->len - 1] = d;
+ return true;
+}
+
+void upb_deflist_donaterefs(upb_deflist *l, void *owner) {
+ size_t i;
+ assert(l->owned);
+ for (i = 0; i < l->len; i++)
+ upb_def_donateref(l->defs[i], l, owner);
+ l->owned = false;
+}
+
+static upb_def *upb_deflist_last(upb_deflist *l) {
+ return l->defs[l->len-1];
+}
+
+/* Qualify the defname for all defs starting with offset "start" with "str". */
+static void upb_deflist_qualify(upb_deflist *l, char *str, int32_t start) {
+ uint32_t i;
+ for (i = start; i < l->len; i++) {
+ upb_def *def = l->defs[i];
+ char *name = upb_join(str, upb_def_fullname(def));
+ upb_def_setfullname(def, name, NULL);
+ free(name);
+ }
+}
+
+
+/* upb_descreader ************************************************************/
+
+static upb_msgdef *upb_descreader_top(upb_descreader *r) {
+ int index;
+ assert(r->stack_len > 1);
+ index = r->stack[r->stack_len-1].start - 1;
+ assert(index >= 0);
+ return upb_downcast_msgdef_mutable(r->defs.defs[index]);
+}
+
+static upb_def *upb_descreader_last(upb_descreader *r) {
+ return upb_deflist_last(&r->defs);
+}
+
+/* Start/end handlers for FileDescriptorProto and DescriptorProto (the two
+ * entities that have names and can contain sub-definitions. */
+void upb_descreader_startcontainer(upb_descreader *r) {
+ upb_descreader_frame *f = &r->stack[r->stack_len++];
+ f->start = r->defs.len;
+ f->name = NULL;
+}
+
+void upb_descreader_endcontainer(upb_descreader *r) {
+ upb_descreader_frame *f = &r->stack[--r->stack_len];
+ upb_deflist_qualify(&r->defs, f->name, f->start);
+ free(f->name);
+ f->name = NULL;
+}
+
+void upb_descreader_setscopename(upb_descreader *r, char *str) {
+ upb_descreader_frame *f = &r->stack[r->stack_len-1];
+ free(f->name);
+ f->name = str;
+}
+
+/* Handlers for google.protobuf.FileDescriptorProto. */
+static bool file_startmsg(void *r, const void *hd) {
+ UPB_UNUSED(hd);
+ upb_descreader_startcontainer(r);
+ return true;
+}
+
+static bool file_endmsg(void *closure, const void *hd, upb_status *status) {
+ upb_descreader *r = closure;
+ UPB_UNUSED(hd);
+ UPB_UNUSED(status);
+ upb_descreader_endcontainer(r);
+ return true;
+}
+
+static size_t file_onpackage(void *closure, const void *hd, const char *buf,
+ size_t n, const upb_bufhandle *handle) {
+ upb_descreader *r = closure;
+ UPB_UNUSED(hd);
+ UPB_UNUSED(handle);
+ /* XXX: see comment at the top of the file. */
+ upb_descreader_setscopename(r, upb_strndup(buf, n));
+ return n;
+}
+
+/* Handlers for google.protobuf.EnumValueDescriptorProto. */
+static bool enumval_startmsg(void *closure, const void *hd) {
+ upb_descreader *r = closure;
+ UPB_UNUSED(hd);
+ r->saw_number = false;
+ r->saw_name = false;
+ return true;
+}
+
+static size_t enumval_onname(void *closure, const void *hd, const char *buf,
+ size_t n, const upb_bufhandle *handle) {
+ upb_descreader *r = closure;
+ UPB_UNUSED(hd);
+ UPB_UNUSED(handle);
+ /* XXX: see comment at the top of the file. */
+ free(r->name);
+ r->name = upb_strndup(buf, n);
+ r->saw_name = true;
+ return n;
+}
+
+static bool enumval_onnumber(void *closure, const void *hd, int32_t val) {
+ upb_descreader *r = closure;
+ UPB_UNUSED(hd);
+ r->number = val;
+ r->saw_number = true;
+ return true;
+}
+
+static bool enumval_endmsg(void *closure, const void *hd, upb_status *status) {
+ upb_descreader *r = closure;
+ upb_enumdef *e;
+ UPB_UNUSED(hd);
+
+ if(!r->saw_number || !r->saw_name) {
+ upb_status_seterrmsg(status, "Enum value missing name or number.");
+ return false;
+ }
+ e = upb_downcast_enumdef_mutable(upb_descreader_last(r));
+ upb_enumdef_addval(e, r->name, r->number, status);
+ free(r->name);
+ r->name = NULL;
+ return true;
+}
+
+
+/* Handlers for google.protobuf.EnumDescriptorProto. */
+static bool enum_startmsg(void *closure, const void *hd) {
+ upb_descreader *r = closure;
+ UPB_UNUSED(hd);
+ upb_deflist_push(&r->defs,
+ upb_enumdef_upcast_mutable(upb_enumdef_new(&r->defs)));
+ return true;
+}
+
+static bool enum_endmsg(void *closure, const void *hd, upb_status *status) {
+ upb_descreader *r = closure;
+ upb_enumdef *e;
+ UPB_UNUSED(hd);
+
+ e = upb_downcast_enumdef_mutable(upb_descreader_last(r));
+ if (upb_def_fullname(upb_descreader_last(r)) == NULL) {
+ upb_status_seterrmsg(status, "Enum had no name.");
+ return false;
+ }
+ if (upb_enumdef_numvals(e) == 0) {
+ upb_status_seterrmsg(status, "Enum had no values.");
+ return false;
+ }
+ return true;
+}
+
+static size_t enum_onname(void *closure, const void *hd, const char *buf,
+ size_t n, const upb_bufhandle *handle) {
+ upb_descreader *r = closure;
+ char *fullname = upb_strndup(buf, n);
+ UPB_UNUSED(hd);
+ UPB_UNUSED(handle);
+ /* XXX: see comment at the top of the file. */
+ upb_def_setfullname(upb_descreader_last(r), fullname, NULL);
+ free(fullname);
+ return n;
+}
+
+/* Handlers for google.protobuf.FieldDescriptorProto */
+static bool field_startmsg(void *closure, const void *hd) {
+ upb_descreader *r = closure;
+ UPB_UNUSED(hd);
+ r->f = upb_fielddef_new(&r->defs);
+ free(r->default_string);
+ r->default_string = NULL;
+
+ /* fielddefs default to packed, but descriptors default to non-packed. */
+ upb_fielddef_setpacked(r->f, false);
+ return true;
+}
+
+/* Converts the default value in string "str" into "d". Passes a ref on str.
+ * Returns true on success. */
+static bool parse_default(char *str, upb_fielddef *f) {
+ bool success = true;
+ char *end;
+ switch (upb_fielddef_type(f)) {
+ case UPB_TYPE_INT32: {
+ long val = strtol(str, &end, 0);
+ if (val > INT32_MAX || val < INT32_MIN || errno == ERANGE || *end)
+ success = false;
+ else
+ upb_fielddef_setdefaultint32(f, val);
+ break;
+ }
+ case UPB_TYPE_INT64: {
+ /* XXX: Need to write our own strtoll, since it's not available in c89. */
+ long long val = strtol(str, &end, 0);
+ if (val > INT64_MAX || val < INT64_MIN || errno == ERANGE || *end)
+ success = false;
+ else
+ upb_fielddef_setdefaultint64(f, val);
+ break;
+ }
+ case UPB_TYPE_UINT32: {
+ unsigned long val = strtoul(str, &end, 0);
+ if (val > UINT32_MAX || errno == ERANGE || *end)
+ success = false;
+ else
+ upb_fielddef_setdefaultuint32(f, val);
+ break;
+ }
+ case UPB_TYPE_UINT64: {
+ /* XXX: Need to write our own strtoull, since it's not available in c89. */
+ unsigned long long val = strtoul(str, &end, 0);
+ if (val > UINT64_MAX || errno == ERANGE || *end)
+ success = false;
+ else
+ upb_fielddef_setdefaultuint64(f, val);
+ break;
+ }
+ case UPB_TYPE_DOUBLE: {
+ double val = strtod(str, &end);
+ if (errno == ERANGE || *end)
+ success = false;
+ else
+ upb_fielddef_setdefaultdouble(f, val);
+ break;
+ }
+ case UPB_TYPE_FLOAT: {
+ /* XXX: Need to write our own strtof, since it's not available in c89. */
+ float val = strtod(str, &end);
+ if (errno == ERANGE || *end)
+ success = false;
+ else
+ upb_fielddef_setdefaultfloat(f, val);
+ break;
+ }
+ case UPB_TYPE_BOOL: {
+ if (strcmp(str, "false") == 0)
+ upb_fielddef_setdefaultbool(f, false);
+ else if (strcmp(str, "true") == 0)
+ upb_fielddef_setdefaultbool(f, true);
+ else
+ success = false;
+ break;
+ }
+ default: abort();
+ }
+ return success;
+}
+
+static bool field_endmsg(void *closure, const void *hd, upb_status *status) {
+ upb_descreader *r = closure;
+ upb_fielddef *f = r->f;
+ UPB_UNUSED(hd);
+
+ /* TODO: verify that all required fields were present. */
+ assert(upb_fielddef_number(f) != 0);
+ assert(upb_fielddef_name(f) != NULL);
+ assert((upb_fielddef_subdefname(f) != NULL) == upb_fielddef_hassubdef(f));
+
+ if (r->default_string) {
+ if (upb_fielddef_issubmsg(f)) {
+ upb_status_seterrmsg(status, "Submessages cannot have defaults.");
+ return false;
+ }
+ if (upb_fielddef_isstring(f) || upb_fielddef_type(f) == UPB_TYPE_ENUM) {
+ upb_fielddef_setdefaultcstr(f, r->default_string, NULL);
+ } else {
+ if (r->default_string && !parse_default(r->default_string, f)) {
+ /* We don't worry too much about giving a great error message since the
+ * compiler should have ensured this was correct. */
+ upb_status_seterrmsg(status, "Error converting default value.");
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+static bool field_onlazy(void *closure, const void *hd, bool val) {
+ upb_descreader *r = closure;
+ UPB_UNUSED(hd);
+
+ upb_fielddef_setlazy(r->f, val);
+ return true;
+}
+
+static bool field_onpacked(void *closure, const void *hd, bool val) {
+ upb_descreader *r = closure;
+ UPB_UNUSED(hd);
+
+ upb_fielddef_setpacked(r->f, val);
+ return true;
+}
+
+static bool field_ontype(void *closure, const void *hd, int32_t val) {
+ upb_descreader *r = closure;
+ UPB_UNUSED(hd);
+
+ upb_fielddef_setdescriptortype(r->f, val);
+ return true;
+}
+
+static bool field_onlabel(void *closure, const void *hd, int32_t val) {
+ upb_descreader *r = closure;
+ UPB_UNUSED(hd);
+
+ upb_fielddef_setlabel(r->f, val);
+ return true;
+}
+
+static bool field_onnumber(void *closure, const void *hd, int32_t val) {
+ upb_descreader *r = closure;
+ bool ok = upb_fielddef_setnumber(r->f, val, NULL);
+ UPB_UNUSED(hd);
+
+ UPB_ASSERT_VAR(ok, ok);
+ return true;
+}
+
+static size_t field_onname(void *closure, const void *hd, const char *buf,
+ size_t n, const upb_bufhandle *handle) {
+ upb_descreader *r = closure;
+ char *name = upb_strndup(buf, n);
+ UPB_UNUSED(hd);
+ UPB_UNUSED(handle);
+
+ /* XXX: see comment at the top of the file. */
+ upb_fielddef_setname(r->f, name, NULL);
+ free(name);
+ return n;
+}
+
+static size_t field_ontypename(void *closure, const void *hd, const char *buf,
+ size_t n, const upb_bufhandle *handle) {
+ upb_descreader *r = closure;
+ char *name = upb_strndup(buf, n);
+ UPB_UNUSED(hd);
+ UPB_UNUSED(handle);
+
+ /* XXX: see comment at the top of the file. */
+ upb_fielddef_setsubdefname(r->f, name, NULL);
+ free(name);
+ return n;
+}
+
+static size_t field_onextendee(void *closure, const void *hd, const char *buf,
+ size_t n, const upb_bufhandle *handle) {
+ upb_descreader *r = closure;
+ char *name = upb_strndup(buf, n);
+ UPB_UNUSED(hd);
+ UPB_UNUSED(handle);
+
+ /* XXX: see comment at the top of the file. */
+ upb_fielddef_setcontainingtypename(r->f, name, NULL);
+ free(name);
+ return n;
+}
+
+static size_t field_ondefaultval(void *closure, const void *hd, const char *buf,
+ size_t n, const upb_bufhandle *handle) {
+ upb_descreader *r = closure;
+ UPB_UNUSED(hd);
+ UPB_UNUSED(handle);
+
+ /* Have to convert from string to the correct type, but we might not know the
+ * type yet, so we save it as a string until the end of the field.
+ * XXX: see comment at the top of the file. */
+ free(r->default_string);
+ r->default_string = upb_strndup(buf, n);
+ return n;
+}
+
+/* Handlers for google.protobuf.DescriptorProto (representing a message). */
+static bool msg_startmsg(void *closure, const void *hd) {
+ upb_descreader *r = closure;
+ UPB_UNUSED(hd);
+
+ upb_deflist_push(&r->defs,
+ upb_msgdef_upcast_mutable(upb_msgdef_new(&r->defs)));
+ upb_descreader_startcontainer(r);
+ return true;
+}
+
+static bool msg_endmsg(void *closure, const void *hd, upb_status *status) {
+ upb_descreader *r = closure;
+ upb_msgdef *m = upb_descreader_top(r);
+ UPB_UNUSED(hd);
+
+ if(!upb_def_fullname(upb_msgdef_upcast_mutable(m))) {
+ upb_status_seterrmsg(status, "Encountered message with no name.");
+ return false;
+ }
+ upb_descreader_endcontainer(r);
+ return true;
+}
+
+static size_t msg_onname(void *closure, const void *hd, const char *buf,
+ size_t n, const upb_bufhandle *handle) {
+ upb_descreader *r = closure;
+ upb_msgdef *m = upb_descreader_top(r);
+ /* XXX: see comment at the top of the file. */
+ char *name = upb_strndup(buf, n);
+ UPB_UNUSED(hd);
+ UPB_UNUSED(handle);
+
+ upb_def_setfullname(upb_msgdef_upcast_mutable(m), name, NULL);
+ upb_descreader_setscopename(r, name); /* Passes ownership of name. */
+ return n;
+}
+
+static bool msg_onendfield(void *closure, const void *hd) {
+ upb_descreader *r = closure;
+ upb_msgdef *m = upb_descreader_top(r);
+ UPB_UNUSED(hd);
+
+ upb_msgdef_addfield(m, r->f, &r->defs, NULL);
+ r->f = NULL;
+ return true;
+}
+
+static bool pushextension(void *closure, const void *hd) {
+ upb_descreader *r = closure;
+ UPB_UNUSED(hd);
+
+ assert(upb_fielddef_containingtypename(r->f));
+ upb_fielddef_setisextension(r->f, true);
+ upb_deflist_push(&r->defs, upb_fielddef_upcast_mutable(r->f));
+ r->f = NULL;
+ return true;
+}
+
+#define D(name) upbdefs_google_protobuf_ ## name(s)
+
+static void reghandlers(const void *closure, upb_handlers *h) {
+ const upb_symtab *s = closure;
+ const upb_msgdef *m = upb_handlers_msgdef(h);
+
+ if (m == D(DescriptorProto)) {
+ upb_handlers_setstartmsg(h, &msg_startmsg, NULL);
+ upb_handlers_setendmsg(h, &msg_endmsg, NULL);
+ upb_handlers_setstring(h, D(DescriptorProto_name), &msg_onname, NULL);
+ upb_handlers_setendsubmsg(h, D(DescriptorProto_field), &msg_onendfield,
+ NULL);
+ upb_handlers_setendsubmsg(h, D(DescriptorProto_extension), &pushextension,
+ NULL);
+ } else if (m == D(FileDescriptorProto)) {
+ upb_handlers_setstartmsg(h, &file_startmsg, NULL);
+ upb_handlers_setendmsg(h, &file_endmsg, NULL);
+ upb_handlers_setstring(h, D(FileDescriptorProto_package), &file_onpackage,
+ NULL);
+ upb_handlers_setendsubmsg(h, D(FileDescriptorProto_extension), &pushextension,
+ NULL);
+ } else if (m == D(EnumValueDescriptorProto)) {
+ upb_handlers_setstartmsg(h, &enumval_startmsg, NULL);
+ upb_handlers_setendmsg(h, &enumval_endmsg, NULL);
+ upb_handlers_setstring(h, D(EnumValueDescriptorProto_name), &enumval_onname, NULL);
+ upb_handlers_setint32(h, D(EnumValueDescriptorProto_number), &enumval_onnumber,
+ NULL);
+ } else if (m == D(EnumDescriptorProto)) {
+ upb_handlers_setstartmsg(h, &enum_startmsg, NULL);
+ upb_handlers_setendmsg(h, &enum_endmsg, NULL);
+ upb_handlers_setstring(h, D(EnumDescriptorProto_name), &enum_onname, NULL);
+ } else if (m == D(FieldDescriptorProto)) {
+ upb_handlers_setstartmsg(h, &field_startmsg, NULL);
+ upb_handlers_setendmsg(h, &field_endmsg, NULL);
+ upb_handlers_setint32(h, D(FieldDescriptorProto_type), &field_ontype,
+ NULL);
+ upb_handlers_setint32(h, D(FieldDescriptorProto_label), &field_onlabel,
+ NULL);
+ upb_handlers_setint32(h, D(FieldDescriptorProto_number), &field_onnumber,
+ NULL);
+ upb_handlers_setstring(h, D(FieldDescriptorProto_name), &field_onname,
+ NULL);
+ upb_handlers_setstring(h, D(FieldDescriptorProto_type_name),
+ &field_ontypename, NULL);
+ upb_handlers_setstring(h, D(FieldDescriptorProto_extendee),
+ &field_onextendee, NULL);
+ upb_handlers_setstring(h, D(FieldDescriptorProto_default_value),
+ &field_ondefaultval, NULL);
+ } else if (m == D(FieldOptions)) {
+ upb_handlers_setbool(h, D(FieldOptions_lazy), &field_onlazy, NULL);
+ upb_handlers_setbool(h, D(FieldOptions_packed), &field_onpacked, NULL);
+ }
+}
+
+#undef D
+
+void descreader_cleanup(void *_r) {
+ upb_descreader *r = _r;
+ free(r->name);
+ upb_deflist_uninit(&r->defs);
+ free(r->default_string);
+ while (r->stack_len > 0) {
+ upb_descreader_frame *f = &r->stack[--r->stack_len];
+ free(f->name);
+ }
+}
+
+
+/* Public API ****************************************************************/
+
+upb_descreader *upb_descreader_create(upb_env *e, const upb_handlers *h) {
+ upb_descreader *r = upb_env_malloc(e, sizeof(upb_descreader));
+ if (!r || !upb_env_addcleanup(e, descreader_cleanup, r)) {
+ return NULL;
+ }
+
+ upb_deflist_init(&r->defs);
+ upb_sink_reset(upb_descreader_input(r), h, r);
+ r->stack_len = 0;
+ r->name = NULL;
+ r->default_string = NULL;
+
+ return r;
+}
+
+upb_def **upb_descreader_getdefs(upb_descreader *r, void *owner, int *n) {
+ *n = r->defs.len;
+ upb_deflist_donaterefs(&r->defs, owner);
+ return r->defs.defs;
+}
+
+upb_sink *upb_descreader_input(upb_descreader *r) {
+ return &r->sink;
+}
+
+const upb_handlers *upb_descreader_newhandlers(const void *owner) {
+ const upb_symtab *s = upbdefs_google_protobuf_descriptor(&s);
+ const upb_handlers *h = upb_handlers_newfrozen(
+ upbdefs_google_protobuf_FileDescriptorSet(s), owner, reghandlers, s);
+ upb_symtab_unref(s, &s);
+ return h;
+}
+/*
+** protobuf decoder bytecode compiler
+**
+** Code to compile a upb::Handlers into bytecode for decoding a protobuf
+** according to that specific schema and destination handlers.
+**
+** Compiling to bytecode is always the first step. If we are using the
+** interpreted decoder we leave it as bytecode and interpret that. If we are
+** using a JIT decoder we use a code generator to turn the bytecode into native
+** code, LLVM IR, etc.
+**
+** Bytecode definition is in decoder.int.h.
+*/
+
+#include <stdarg.h>
+
+#ifdef UPB_DUMP_BYTECODE
+#include <stdio.h>
+#endif
+
+#define MAXLABEL 5
+#define EMPTYLABEL -1
+
+/* mgroup *********************************************************************/
+
+static void freegroup(upb_refcounted *r) {
+ mgroup *g = (mgroup*)r;
+ upb_inttable_uninit(&g->methods);
+#ifdef UPB_USE_JIT_X64
+ upb_pbdecoder_freejit(g);
+#endif
+ free(g->bytecode);
+ free(g);
+}
+
+static void visitgroup(const upb_refcounted *r, upb_refcounted_visit *visit,
+ void *closure) {
+ const mgroup *g = (const mgroup*)r;
+ upb_inttable_iter i;
+ upb_inttable_begin(&i, &g->methods);
+ for(; !upb_inttable_done(&i); upb_inttable_next(&i)) {
+ upb_pbdecodermethod *method = upb_value_getptr(upb_inttable_iter_value(&i));
+ visit(r, upb_pbdecodermethod_upcast(method), closure);
+ }
+}
+
+mgroup *newgroup(const void *owner) {
+ mgroup *g = malloc(sizeof(*g));
+ static const struct upb_refcounted_vtbl vtbl = {visitgroup, freegroup};
+ upb_refcounted_init(mgroup_upcast_mutable(g), &vtbl, owner);
+ upb_inttable_init(&g->methods, UPB_CTYPE_PTR);
+ g->bytecode = NULL;
+ g->bytecode_end = NULL;
+ return g;
+}
+
+
+/* upb_pbdecodermethod ********************************************************/
+
+static void freemethod(upb_refcounted *r) {
+ upb_pbdecodermethod *method = (upb_pbdecodermethod*)r;
+
+ if (method->dest_handlers_) {
+ upb_handlers_unref(method->dest_handlers_, method);
+ }
+
+ upb_inttable_uninit(&method->dispatch);
+ free(method);
+}
+
+static void visitmethod(const upb_refcounted *r, upb_refcounted_visit *visit,
+ void *closure) {
+ const upb_pbdecodermethod *m = (const upb_pbdecodermethod*)r;
+ visit(r, m->group, closure);
+}
+
+static upb_pbdecodermethod *newmethod(const upb_handlers *dest_handlers,
+ mgroup *group) {
+ static const struct upb_refcounted_vtbl vtbl = {visitmethod, freemethod};
+ upb_pbdecodermethod *ret = malloc(sizeof(*ret));
+ upb_refcounted_init(upb_pbdecodermethod_upcast_mutable(ret), &vtbl, &ret);
+ upb_byteshandler_init(&ret->input_handler_);
+
+ /* The method references the group and vice-versa, in a circular reference. */
+ upb_ref2(ret, group);
+ upb_ref2(group, ret);
+ upb_inttable_insertptr(&group->methods, dest_handlers, upb_value_ptr(ret));
+ upb_pbdecodermethod_unref(ret, &ret);
+
+ ret->group = mgroup_upcast_mutable(group);
+ ret->dest_handlers_ = dest_handlers;
+ ret->is_native_ = false; /* If we JIT, it will update this later. */
+ upb_inttable_init(&ret->dispatch, UPB_CTYPE_UINT64);
+
+ if (ret->dest_handlers_) {
+ upb_handlers_ref(ret->dest_handlers_, ret);
+ }
+ return ret;
+}
+
+const upb_handlers *upb_pbdecodermethod_desthandlers(
+ const upb_pbdecodermethod *m) {
+ return m->dest_handlers_;
+}
+
+const upb_byteshandler *upb_pbdecodermethod_inputhandler(
+ const upb_pbdecodermethod *m) {
+ return &m->input_handler_;
+}
+
+bool upb_pbdecodermethod_isnative(const upb_pbdecodermethod *m) {
+ return m->is_native_;
+}
+
+const upb_pbdecodermethod *upb_pbdecodermethod_new(
+ const upb_pbdecodermethodopts *opts, const void *owner) {
+ const upb_pbdecodermethod *ret;
+ upb_pbcodecache cache;
+
+ upb_pbcodecache_init(&cache);
+ ret = upb_pbcodecache_getdecodermethod(&cache, opts);
+ upb_pbdecodermethod_ref(ret, owner);
+ upb_pbcodecache_uninit(&cache);
+ return ret;
+}
+
+
+/* bytecode compiler **********************************************************/
+
+/* Data used only at compilation time. */
+typedef struct {
+ mgroup *group;
+
+ uint32_t *pc;
+ int fwd_labels[MAXLABEL];
+ int back_labels[MAXLABEL];
+
+ /* For fields marked "lazy", parse them lazily or eagerly? */
+ bool lazy;
+} compiler;
+
+static compiler *newcompiler(mgroup *group, bool lazy) {
+ compiler *ret = malloc(sizeof(*ret));
+ int i;
+
+ ret->group = group;
+ ret->lazy = lazy;
+ for (i = 0; i < MAXLABEL; i++) {
+ ret->fwd_labels[i] = EMPTYLABEL;
+ ret->back_labels[i] = EMPTYLABEL;
+ }
+ return ret;
+}
+
+static void freecompiler(compiler *c) {
+ free(c);
+}
+
+const size_t ptr_words = sizeof(void*) / sizeof(uint32_t);
+
+/* How many words an instruction is. */
+static int instruction_len(uint32_t instr) {
+ switch (getop(instr)) {
+ case OP_SETDISPATCH: return 1 + ptr_words;
+ case OP_TAGN: return 3;
+ case OP_SETBIGGROUPNUM: return 2;
+ default: return 1;
+ }
+}
+
+bool op_has_longofs(int32_t instruction) {
+ switch (getop(instruction)) {
+ case OP_CALL:
+ case OP_BRANCH:
+ case OP_CHECKDELIM:
+ return true;
+ /* The "tag" instructions only have 8 bytes available for the jump target,
+ * but that is ok because these opcodes only require short jumps. */
+ case OP_TAG1:
+ case OP_TAG2:
+ case OP_TAGN:
+ return false;
+ default:
+ assert(false);
+ return false;
+ }
+}
+
+static int32_t getofs(uint32_t instruction) {
+ if (op_has_longofs(instruction)) {
+ return (int32_t)instruction >> 8;
+ } else {
+ return (int8_t)(instruction >> 8);
+ }
+}
+
+static void setofs(uint32_t *instruction, int32_t ofs) {
+ if (op_has_longofs(*instruction)) {
+ *instruction = getop(*instruction) | ofs << 8;
+ } else {
+ *instruction = (*instruction & ~0xff00) | ((ofs & 0xff) << 8);
+ }
+ assert(getofs(*instruction) == ofs); /* Would fail in cases of overflow. */
+}
+
+static uint32_t pcofs(compiler *c) { return c->pc - c->group->bytecode; }
+
+/* Defines a local label at the current PC location. All previous forward
+ * references are updated to point to this location. The location is noted
+ * for any future backward references. */
+static void label(compiler *c, unsigned int label) {
+ int val;
+ uint32_t *codep;
+
+ assert(label < MAXLABEL);
+ val = c->fwd_labels[label];
+ codep = (val == EMPTYLABEL) ? NULL : c->group->bytecode + val;
+ while (codep) {
+ int ofs = getofs(*codep);
+ setofs(codep, c->pc - codep - instruction_len(*codep));
+ codep = ofs ? codep + ofs : NULL;
+ }
+ c->fwd_labels[label] = EMPTYLABEL;
+ c->back_labels[label] = pcofs(c);
+}
+
+/* Creates a reference to a numbered label; either a forward reference
+ * (positive arg) or backward reference (negative arg). For forward references
+ * the value returned now is actually a "next" pointer into a linked list of all
+ * instructions that use this label and will be patched later when the label is
+ * defined with label().
+ *
+ * The returned value is the offset that should be written into the instruction.
+ */
+static int32_t labelref(compiler *c, int label) {
+ assert(label < MAXLABEL);
+ if (label == LABEL_DISPATCH) {
+ /* No resolving required. */
+ return 0;
+ } else if (label < 0) {
+ /* Backward local label. Relative to the next instruction. */
+ uint32_t from = (c->pc + 1) - c->group->bytecode;
+ return c->back_labels[-label] - from;
+ } else {
+ /* Forward local label: prepend to (possibly-empty) linked list. */
+ int *lptr = &c->fwd_labels[label];
+ int32_t ret = (*lptr == EMPTYLABEL) ? 0 : *lptr - pcofs(c);
+ *lptr = pcofs(c);
+ return ret;
+ }
+}
+
+static void put32(compiler *c, uint32_t v) {
+ mgroup *g = c->group;
+ if (c->pc == g->bytecode_end) {
+ int ofs = pcofs(c);
+ size_t oldsize = g->bytecode_end - g->bytecode;
+ size_t newsize = UPB_MAX(oldsize * 2, 64);
+ /* TODO(haberman): handle OOM. */
+ g->bytecode = realloc(g->bytecode, newsize * sizeof(uint32_t));
+ g->bytecode_end = g->bytecode + newsize;
+ c->pc = g->bytecode + ofs;
+ }
+ *c->pc++ = v;
+}
+
+static void putop(compiler *c, opcode op, ...) {
+ va_list ap;
+ va_start(ap, op);
+
+ switch (op) {
+ case OP_SETDISPATCH: {
+ uintptr_t ptr = (uintptr_t)va_arg(ap, void*);
+ put32(c, OP_SETDISPATCH);
+ put32(c, ptr);
+ if (sizeof(uintptr_t) > sizeof(uint32_t))
+ put32(c, (uint64_t)ptr >> 32);
+ break;
+ }
+ case OP_STARTMSG:
+ case OP_ENDMSG:
+ case OP_PUSHLENDELIM:
+ case OP_POP:
+ case OP_SETDELIM:
+ case OP_HALT:
+ case OP_RET:
+ case OP_DISPATCH:
+ put32(c, op);
+ break;
+ case OP_PARSE_DOUBLE:
+ case OP_PARSE_FLOAT:
+ case OP_PARSE_INT64:
+ case OP_PARSE_UINT64:
+ case OP_PARSE_INT32:
+ case OP_PARSE_FIXED64:
+ case OP_PARSE_FIXED32:
+ case OP_PARSE_BOOL:
+ case OP_PARSE_UINT32:
+ case OP_PARSE_SFIXED32:
+ case OP_PARSE_SFIXED64:
+ case OP_PARSE_SINT32:
+ case OP_PARSE_SINT64:
+ case OP_STARTSEQ:
+ case OP_ENDSEQ:
+ case OP_STARTSUBMSG:
+ case OP_ENDSUBMSG:
+ case OP_STARTSTR:
+ case OP_STRING:
+ case OP_ENDSTR:
+ case OP_PUSHTAGDELIM:
+ put32(c, op | va_arg(ap, upb_selector_t) << 8);
+ break;
+ case OP_SETBIGGROUPNUM:
+ put32(c, op);
+ put32(c, va_arg(ap, int));
+ break;
+ case OP_CALL: {
+ const upb_pbdecodermethod *method = va_arg(ap, upb_pbdecodermethod *);
+ put32(c, op | (method->code_base.ofs - (pcofs(c) + 1)) << 8);
+ break;
+ }
+ case OP_CHECKDELIM:
+ case OP_BRANCH: {
+ uint32_t instruction = op;
+ int label = va_arg(ap, int);
+ setofs(&instruction, labelref(c, label));
+ put32(c, instruction);
+ break;
+ }
+ case OP_TAG1:
+ case OP_TAG2: {
+ int label = va_arg(ap, int);
+ uint64_t tag = va_arg(ap, uint64_t);
+ uint32_t instruction = op | (tag << 16);
+ assert(tag <= 0xffff);
+ setofs(&instruction, labelref(c, label));
+ put32(c, instruction);
+ break;
+ }
+ case OP_TAGN: {
+ int label = va_arg(ap, int);
+ uint64_t tag = va_arg(ap, uint64_t);
+ uint32_t instruction = op | (upb_value_size(tag) << 16);
+ setofs(&instruction, labelref(c, label));
+ put32(c, instruction);
+ put32(c, tag);
+ put32(c, tag >> 32);
+ break;
+ }
+ }
+
+ va_end(ap);
+}
+
+#if defined(UPB_USE_JIT_X64) || defined(UPB_DUMP_BYTECODE)
+
+const char *upb_pbdecoder_getopname(unsigned int op) {
+#define QUOTE(x) #x
+#define EXPAND_AND_QUOTE(x) QUOTE(x)
+#define OPNAME(x) OP_##x
+#define OP(x) case OPNAME(x): return EXPAND_AND_QUOTE(OPNAME(x));
+#define T(x) OP(PARSE_##x)
+ /* Keep in sync with list in decoder.int.h. */
+ switch ((opcode)op) {
+ T(DOUBLE) T(FLOAT) T(INT64) T(UINT64) T(INT32) T(FIXED64) T(FIXED32)
+ T(BOOL) T(UINT32) T(SFIXED32) T(SFIXED64) T(SINT32) T(SINT64)
+ OP(STARTMSG) OP(ENDMSG) OP(STARTSEQ) OP(ENDSEQ) OP(STARTSUBMSG)
+ OP(ENDSUBMSG) OP(STARTSTR) OP(STRING) OP(ENDSTR) OP(CALL) OP(RET)
+ OP(PUSHLENDELIM) OP(PUSHTAGDELIM) OP(SETDELIM) OP(CHECKDELIM)
+ OP(BRANCH) OP(TAG1) OP(TAG2) OP(TAGN) OP(SETDISPATCH) OP(POP)
+ OP(SETBIGGROUPNUM) OP(DISPATCH) OP(HALT)
+ }
+ return "<unknown op>";
+#undef OP
+#undef T
+}
+
+#endif
+
+#ifdef UPB_DUMP_BYTECODE
+
+static void dumpbc(uint32_t *p, uint32_t *end, FILE *f) {
+
+ uint32_t *begin = p;
+
+ while (p < end) {
+ fprintf(f, "%p %8tx", p, p - begin);
+ uint32_t instr = *p++;
+ uint8_t op = getop(instr);
+ fprintf(f, " %s", upb_pbdecoder_getopname(op));
+ switch ((opcode)op) {
+ case OP_SETDISPATCH: {
+ const upb_inttable *dispatch;
+ memcpy(&dispatch, p, sizeof(void*));
+ p += ptr_words;
+ const upb_pbdecodermethod *method =
+ (void *)((char *)dispatch -
+ offsetof(upb_pbdecodermethod, dispatch));
+ fprintf(f, " %s", upb_msgdef_fullname(
+ upb_handlers_msgdef(method->dest_handlers_)));
+ break;
+ }
+ case OP_DISPATCH:
+ case OP_STARTMSG:
+ case OP_ENDMSG:
+ case OP_PUSHLENDELIM:
+ case OP_POP:
+ case OP_SETDELIM:
+ case OP_HALT:
+ case OP_RET:
+ break;
+ case OP_PARSE_DOUBLE:
+ case OP_PARSE_FLOAT:
+ case OP_PARSE_INT64:
+ case OP_PARSE_UINT64:
+ case OP_PARSE_INT32:
+ case OP_PARSE_FIXED64:
+ case OP_PARSE_FIXED32:
+ case OP_PARSE_BOOL:
+ case OP_PARSE_UINT32:
+ case OP_PARSE_SFIXED32:
+ case OP_PARSE_SFIXED64:
+ case OP_PARSE_SINT32:
+ case OP_PARSE_SINT64:
+ case OP_STARTSEQ:
+ case OP_ENDSEQ:
+ case OP_STARTSUBMSG:
+ case OP_ENDSUBMSG:
+ case OP_STARTSTR:
+ case OP_STRING:
+ case OP_ENDSTR:
+ case OP_PUSHTAGDELIM:
+ fprintf(f, " %d", instr >> 8);
+ break;
+ case OP_SETBIGGROUPNUM:
+ fprintf(f, " %d", *p++);
+ break;
+ case OP_CHECKDELIM:
+ case OP_CALL:
+ case OP_BRANCH:
+ fprintf(f, " =>0x%tx", p + getofs(instr) - begin);
+ break;
+ case OP_TAG1:
+ case OP_TAG2: {
+ fprintf(f, " tag:0x%x", instr >> 16);
+ if (getofs(instr)) {
+ fprintf(f, " =>0x%tx", p + getofs(instr) - begin);
+ }
+ break;
+ }
+ case OP_TAGN: {
+ uint64_t tag = *p++;
+ tag |= (uint64_t)*p++ << 32;
+ fprintf(f, " tag:0x%llx", (long long)tag);
+ fprintf(f, " n:%d", instr >> 16);
+ if (getofs(instr)) {
+ fprintf(f, " =>0x%tx", p + getofs(instr) - begin);
+ }
+ break;
+ }
+ }
+ fputs("\n", f);
+ }
+}
+
+#endif
+
+static uint64_t get_encoded_tag(const upb_fielddef *f, int wire_type) {
+ uint32_t tag = (upb_fielddef_number(f) << 3) | wire_type;
+ uint64_t encoded_tag = upb_vencode32(tag);
+ /* No tag should be greater than 5 bytes. */
+ assert(encoded_tag <= 0xffffffffff);
+ return encoded_tag;
+}
+
+static void putchecktag(compiler *c, const upb_fielddef *f,
+ int wire_type, int dest) {
+ uint64_t tag = get_encoded_tag(f, wire_type);
+ switch (upb_value_size(tag)) {
+ case 1:
+ putop(c, OP_TAG1, dest, tag);
+ break;
+ case 2:
+ putop(c, OP_TAG2, dest, tag);
+ break;
+ default:
+ putop(c, OP_TAGN, dest, tag);
+ break;
+ }
+}
+
+static upb_selector_t getsel(const upb_fielddef *f, upb_handlertype_t type) {
+ upb_selector_t selector;
+ bool ok = upb_handlers_getselector(f, type, &selector);
+ UPB_ASSERT_VAR(ok, ok);
+ return selector;
+}
+
+/* Takes an existing, primary dispatch table entry and repacks it with a
+ * different alternate wire type. Called when we are inserting a secondary
+ * dispatch table entry for an alternate wire type. */
+static uint64_t repack(uint64_t dispatch, int new_wt2) {
+ uint64_t ofs;
+ uint8_t wt1;
+ uint8_t old_wt2;
+ upb_pbdecoder_unpackdispatch(dispatch, &ofs, &wt1, &old_wt2);
+ assert(old_wt2 == NO_WIRE_TYPE); /* wt2 should not be set yet. */
+ return upb_pbdecoder_packdispatch(ofs, wt1, new_wt2);
+}
+
+/* Marks the current bytecode position as the dispatch target for this message,
+ * field, and wire type. */
+static void dispatchtarget(compiler *c, upb_pbdecodermethod *method,
+ const upb_fielddef *f, int wire_type) {
+ /* Offset is relative to msg base. */
+ uint64_t ofs = pcofs(c) - method->code_base.ofs;
+ uint32_t fn = upb_fielddef_number(f);
+ upb_inttable *d = &method->dispatch;
+ upb_value v;
+ if (upb_inttable_remove(d, fn, &v)) {
+ /* TODO: prioritize based on packed setting in .proto file. */
+ uint64_t repacked = repack(upb_value_getuint64(v), wire_type);
+ upb_inttable_insert(d, fn, upb_value_uint64(repacked));
+ upb_inttable_insert(d, fn + UPB_MAX_FIELDNUMBER, upb_value_uint64(ofs));
+ } else {
+ uint64_t val = upb_pbdecoder_packdispatch(ofs, wire_type, NO_WIRE_TYPE);
+ upb_inttable_insert(d, fn, upb_value_uint64(val));
+ }
+}
+
+static void putpush(compiler *c, const upb_fielddef *f) {
+ if (upb_fielddef_descriptortype(f) == UPB_DESCRIPTOR_TYPE_MESSAGE) {
+ putop(c, OP_PUSHLENDELIM);
+ } else {
+ uint32_t fn = upb_fielddef_number(f);
+ if (fn >= 1 << 24) {
+ putop(c, OP_PUSHTAGDELIM, 0);
+ putop(c, OP_SETBIGGROUPNUM, fn);
+ } else {
+ putop(c, OP_PUSHTAGDELIM, fn);
+ }
+ }
+}
+
+static upb_pbdecodermethod *find_submethod(const compiler *c,
+ const upb_pbdecodermethod *method,
+ const upb_fielddef *f) {
+ const upb_handlers *sub =
+ upb_handlers_getsubhandlers(method->dest_handlers_, f);
+ upb_value v;
+ return upb_inttable_lookupptr(&c->group->methods, sub, &v)
+ ? upb_value_getptr(v)
+ : NULL;
+}
+
+static void putsel(compiler *c, opcode op, upb_selector_t sel,
+ const upb_handlers *h) {
+ if (upb_handlers_gethandler(h, sel)) {
+ putop(c, op, sel);
+ }
+}
+
+/* Puts an opcode to call a callback, but only if a callback actually exists for
+ * this field and handler type. */
+static void maybeput(compiler *c, opcode op, const upb_handlers *h,
+ const upb_fielddef *f, upb_handlertype_t type) {
+ putsel(c, op, getsel(f, type), h);
+}
+
+static bool haslazyhandlers(const upb_handlers *h, const upb_fielddef *f) {
+ if (!upb_fielddef_lazy(f))
+ return false;
+
+ return upb_handlers_gethandler(h, getsel(f, UPB_HANDLER_STARTSTR)) ||
+ upb_handlers_gethandler(h, getsel(f, UPB_HANDLER_STRING)) ||
+ upb_handlers_gethandler(h, getsel(f, UPB_HANDLER_ENDSTR));
+}
+
+
+/* bytecode compiler code generation ******************************************/
+
+/* Symbolic names for our local labels. */
+#define LABEL_LOOPSTART 1 /* Top of a repeated field loop. */
+#define LABEL_LOOPBREAK 2 /* To jump out of a repeated loop */
+#define LABEL_FIELD 3 /* Jump backward to find the most recent field. */
+#define LABEL_ENDMSG 4 /* To reach the OP_ENDMSG instr for this msg. */
+
+/* Generates bytecode to parse a single non-lazy message field. */
+static void generate_msgfield(compiler *c, const upb_fielddef *f,
+ upb_pbdecodermethod *method) {
+ const upb_handlers *h = upb_pbdecodermethod_desthandlers(method);
+ const upb_pbdecodermethod *sub_m = find_submethod(c, method, f);
+ int wire_type;
+
+ if (!sub_m) {
+ /* Don't emit any code for this field at all; it will be parsed as an
+ * unknown field. */
+ return;
+ }
+
+ label(c, LABEL_FIELD);
+
+ wire_type =
+ (upb_fielddef_descriptortype(f) == UPB_DESCRIPTOR_TYPE_MESSAGE)
+ ? UPB_WIRE_TYPE_DELIMITED
+ : UPB_WIRE_TYPE_START_GROUP;
+
+ if (upb_fielddef_isseq(f)) {
+ putop(c, OP_CHECKDELIM, LABEL_ENDMSG);
+ putchecktag(c, f, wire_type, LABEL_DISPATCH);
+ dispatchtarget(c, method, f, wire_type);
+ putop(c, OP_PUSHTAGDELIM, 0);
+ putop(c, OP_STARTSEQ, getsel(f, UPB_HANDLER_STARTSEQ));
+ label(c, LABEL_LOOPSTART);
+ putpush(c, f);
+ putop(c, OP_STARTSUBMSG, getsel(f, UPB_HANDLER_STARTSUBMSG));
+ putop(c, OP_CALL, sub_m);
+ putop(c, OP_POP);
+ maybeput(c, OP_ENDSUBMSG, h, f, UPB_HANDLER_ENDSUBMSG);
+ if (wire_type == UPB_WIRE_TYPE_DELIMITED) {
+ putop(c, OP_SETDELIM);
+ }
+ putop(c, OP_CHECKDELIM, LABEL_LOOPBREAK);
+ putchecktag(c, f, wire_type, LABEL_LOOPBREAK);
+ putop(c, OP_BRANCH, -LABEL_LOOPSTART);
+ label(c, LABEL_LOOPBREAK);
+ putop(c, OP_POP);
+ maybeput(c, OP_ENDSEQ, h, f, UPB_HANDLER_ENDSEQ);
+ } else {
+ putop(c, OP_CHECKDELIM, LABEL_ENDMSG);
+ putchecktag(c, f, wire_type, LABEL_DISPATCH);
+ dispatchtarget(c, method, f, wire_type);
+ putpush(c, f);
+ putop(c, OP_STARTSUBMSG, getsel(f, UPB_HANDLER_STARTSUBMSG));
+ putop(c, OP_CALL, sub_m);
+ putop(c, OP_POP);
+ maybeput(c, OP_ENDSUBMSG, h, f, UPB_HANDLER_ENDSUBMSG);
+ if (wire_type == UPB_WIRE_TYPE_DELIMITED) {
+ putop(c, OP_SETDELIM);
+ }
+ }
+}
+
+/* Generates bytecode to parse a single string or lazy submessage field. */
+static void generate_delimfield(compiler *c, const upb_fielddef *f,
+ upb_pbdecodermethod *method) {
+ const upb_handlers *h = upb_pbdecodermethod_desthandlers(method);
+
+ label(c, LABEL_FIELD);
+ if (upb_fielddef_isseq(f)) {
+ putop(c, OP_CHECKDELIM, LABEL_ENDMSG);
+ putchecktag(c, f, UPB_WIRE_TYPE_DELIMITED, LABEL_DISPATCH);
+ dispatchtarget(c, method, f, UPB_WIRE_TYPE_DELIMITED);
+ putop(c, OP_PUSHTAGDELIM, 0);
+ putop(c, OP_STARTSEQ, getsel(f, UPB_HANDLER_STARTSEQ));
+ label(c, LABEL_LOOPSTART);
+ putop(c, OP_PUSHLENDELIM);
+ putop(c, OP_STARTSTR, getsel(f, UPB_HANDLER_STARTSTR));
+ /* Need to emit even if no handler to skip past the string. */
+ putop(c, OP_STRING, getsel(f, UPB_HANDLER_STRING));
+ putop(c, OP_POP);
+ maybeput(c, OP_ENDSTR, h, f, UPB_HANDLER_ENDSTR);
+ putop(c, OP_SETDELIM);
+ putop(c, OP_CHECKDELIM, LABEL_LOOPBREAK);
+ putchecktag(c, f, UPB_WIRE_TYPE_DELIMITED, LABEL_LOOPBREAK);
+ putop(c, OP_BRANCH, -LABEL_LOOPSTART);
+ label(c, LABEL_LOOPBREAK);
+ putop(c, OP_POP);
+ maybeput(c, OP_ENDSEQ, h, f, UPB_HANDLER_ENDSEQ);
+ } else {
+ putop(c, OP_CHECKDELIM, LABEL_ENDMSG);
+ putchecktag(c, f, UPB_WIRE_TYPE_DELIMITED, LABEL_DISPATCH);
+ dispatchtarget(c, method, f, UPB_WIRE_TYPE_DELIMITED);
+ putop(c, OP_PUSHLENDELIM);
+ putop(c, OP_STARTSTR, getsel(f, UPB_HANDLER_STARTSTR));
+ putop(c, OP_STRING, getsel(f, UPB_HANDLER_STRING));
+ putop(c, OP_POP);
+ maybeput(c, OP_ENDSTR, h, f, UPB_HANDLER_ENDSTR);
+ putop(c, OP_SETDELIM);
+ }
+}
+
+/* Generates bytecode to parse a single primitive field. */
+static void generate_primitivefield(compiler *c, const upb_fielddef *f,
+ upb_pbdecodermethod *method) {
+ const upb_handlers *h = upb_pbdecodermethod_desthandlers(method);
+ upb_descriptortype_t descriptor_type = upb_fielddef_descriptortype(f);
+ opcode parse_type;
+ upb_selector_t sel;
+ int wire_type;
+
+ label(c, LABEL_FIELD);
+
+ /* From a decoding perspective, ENUM is the same as INT32. */
+ if (descriptor_type == UPB_DESCRIPTOR_TYPE_ENUM)
+ descriptor_type = UPB_DESCRIPTOR_TYPE_INT32;
+
+ parse_type = (opcode)descriptor_type;
+
+ /* TODO(haberman): generate packed or non-packed first depending on "packed"
+ * setting in the fielddef. This will favor (in speed) whichever was
+ * specified. */
+
+ assert((int)parse_type >= 0 && parse_type <= OP_MAX);
+ sel = getsel(f, upb_handlers_getprimitivehandlertype(f));
+ wire_type = upb_pb_native_wire_types[upb_fielddef_descriptortype(f)];
+ if (upb_fielddef_isseq(f)) {
+ putop(c, OP_CHECKDELIM, LABEL_ENDMSG);
+ putchecktag(c, f, UPB_WIRE_TYPE_DELIMITED, LABEL_DISPATCH);
+ dispatchtarget(c, method, f, UPB_WIRE_TYPE_DELIMITED);
+ putop(c, OP_PUSHLENDELIM);
+ putop(c, OP_STARTSEQ, getsel(f, UPB_HANDLER_STARTSEQ)); /* Packed */
+ label(c, LABEL_LOOPSTART);
+ putop(c, parse_type, sel);
+ putop(c, OP_CHECKDELIM, LABEL_LOOPBREAK);
+ putop(c, OP_BRANCH, -LABEL_LOOPSTART);
+ dispatchtarget(c, method, f, wire_type);
+ putop(c, OP_PUSHTAGDELIM, 0);
+ putop(c, OP_STARTSEQ, getsel(f, UPB_HANDLER_STARTSEQ)); /* Non-packed */
+ label(c, LABEL_LOOPSTART);
+ putop(c, parse_type, sel);
+ putop(c, OP_CHECKDELIM, LABEL_LOOPBREAK);
+ putchecktag(c, f, wire_type, LABEL_LOOPBREAK);
+ putop(c, OP_BRANCH, -LABEL_LOOPSTART);
+ label(c, LABEL_LOOPBREAK);
+ putop(c, OP_POP); /* Packed and non-packed join. */
+ maybeput(c, OP_ENDSEQ, h, f, UPB_HANDLER_ENDSEQ);
+ putop(c, OP_SETDELIM); /* Could remove for non-packed by dup ENDSEQ. */
+ } else {
+ putop(c, OP_CHECKDELIM, LABEL_ENDMSG);
+ putchecktag(c, f, wire_type, LABEL_DISPATCH);
+ dispatchtarget(c, method, f, wire_type);
+ putop(c, parse_type, sel);
+ }
+}
+
+/* Adds bytecode for parsing the given message to the given decoderplan,
+ * while adding all dispatch targets to this message's dispatch table. */
+static void compile_method(compiler *c, upb_pbdecodermethod *method) {
+ const upb_handlers *h;
+ const upb_msgdef *md;
+ uint32_t* start_pc;
+ upb_msg_field_iter i;
+ upb_value val;
+
+ assert(method);
+
+ /* Clear all entries in the dispatch table. */
+ upb_inttable_uninit(&method->dispatch);
+ upb_inttable_init(&method->dispatch, UPB_CTYPE_UINT64);
+
+ h = upb_pbdecodermethod_desthandlers(method);
+ md = upb_handlers_msgdef(h);
+
+ method->code_base.ofs = pcofs(c);
+ putop(c, OP_SETDISPATCH, &method->dispatch);
+ putsel(c, OP_STARTMSG, UPB_STARTMSG_SELECTOR, h);
+ label(c, LABEL_FIELD);
+ start_pc = c->pc;
+ for(upb_msg_field_begin(&i, md);
+ !upb_msg_field_done(&i);
+ upb_msg_field_next(&i)) {
+ const upb_fielddef *f = upb_msg_iter_field(&i);
+ upb_fieldtype_t type = upb_fielddef_type(f);
+
+ if (type == UPB_TYPE_MESSAGE && !(haslazyhandlers(h, f) && c->lazy)) {
+ generate_msgfield(c, f, method);
+ } else if (type == UPB_TYPE_STRING || type == UPB_TYPE_BYTES ||
+ type == UPB_TYPE_MESSAGE) {
+ generate_delimfield(c, f, method);
+ } else {
+ generate_primitivefield(c, f, method);
+ }
+ }
+
+ /* If there were no fields, or if no handlers were defined, we need to
+ * generate a non-empty loop body so that we can at least dispatch for unknown
+ * fields and check for the end of the message. */
+ if (c->pc == start_pc) {
+ /* Check for end-of-message. */
+ putop(c, OP_CHECKDELIM, LABEL_ENDMSG);
+ /* Unconditionally dispatch. */
+ putop(c, OP_DISPATCH, 0);
+ }
+
+ /* For now we just loop back to the last field of the message (or if none,
+ * the DISPATCH opcode for the message). */
+ putop(c, OP_BRANCH, -LABEL_FIELD);
+
+ /* Insert both a label and a dispatch table entry for this end-of-msg. */
+ label(c, LABEL_ENDMSG);
+ val = upb_value_uint64(pcofs(c) - method->code_base.ofs);
+ upb_inttable_insert(&method->dispatch, DISPATCH_ENDMSG, val);
+
+ putsel(c, OP_ENDMSG, UPB_ENDMSG_SELECTOR, h);
+ putop(c, OP_RET);
+
+ upb_inttable_compact(&method->dispatch);
+}
+
+/* Populate "methods" with new upb_pbdecodermethod objects reachable from "h".
+ * Returns the method for these handlers.
+ *
+ * Generates a new method for every destination handlers reachable from "h". */
+static void find_methods(compiler *c, const upb_handlers *h) {
+ upb_value v;
+ upb_msg_field_iter i;
+ const upb_msgdef *md;
+
+ if (upb_inttable_lookupptr(&c->group->methods, h, &v))
+ return;
+ newmethod(h, c->group);
+
+ /* Find submethods. */
+ md = upb_handlers_msgdef(h);
+ for(upb_msg_field_begin(&i, md);
+ !upb_msg_field_done(&i);
+ upb_msg_field_next(&i)) {
+ const upb_fielddef *f = upb_msg_iter_field(&i);
+ const upb_handlers *sub_h;
+ if (upb_fielddef_type(f) == UPB_TYPE_MESSAGE &&
+ (sub_h = upb_handlers_getsubhandlers(h, f)) != NULL) {
+ /* We only generate a decoder method for submessages with handlers.
+ * Others will be parsed as unknown fields. */
+ find_methods(c, sub_h);
+ }
+ }
+}
+
+/* (Re-)compile bytecode for all messages in "msgs."
+ * Overwrites any existing bytecode in "c". */
+static void compile_methods(compiler *c) {
+ upb_inttable_iter i;
+
+ /* Start over at the beginning of the bytecode. */
+ c->pc = c->group->bytecode;
+
+ upb_inttable_begin(&i, &c->group->methods);
+ for(; !upb_inttable_done(&i); upb_inttable_next(&i)) {
+ upb_pbdecodermethod *method = upb_value_getptr(upb_inttable_iter_value(&i));
+ compile_method(c, method);
+ }
+}
+
+static void set_bytecode_handlers(mgroup *g) {
+ upb_inttable_iter i;
+ upb_inttable_begin(&i, &g->methods);
+ for(; !upb_inttable_done(&i); upb_inttable_next(&i)) {
+ upb_pbdecodermethod *m = upb_value_getptr(upb_inttable_iter_value(&i));
+ upb_byteshandler *h = &m->input_handler_;
+
+ m->code_base.ptr = g->bytecode + m->code_base.ofs;
+
+ upb_byteshandler_setstartstr(h, upb_pbdecoder_startbc, m->code_base.ptr);
+ upb_byteshandler_setstring(h, upb_pbdecoder_decode, g);
+ upb_byteshandler_setendstr(h, upb_pbdecoder_end, m);
+ }
+}
+
+
+/* JIT setup. *****************************************************************/
+
+#ifdef UPB_USE_JIT_X64
+
+static void sethandlers(mgroup *g, bool allowjit) {
+ g->jit_code = NULL;
+ if (allowjit) {
+ /* Compile byte-code into machine code, create handlers. */
+ upb_pbdecoder_jit(g);
+ } else {
+ set_bytecode_handlers(g);
+ }
+}
+
+#else /* UPB_USE_JIT_X64 */
+
+static void sethandlers(mgroup *g, bool allowjit) {
+ /* No JIT compiled in; use bytecode handlers unconditionally. */
+ UPB_UNUSED(allowjit);
+ set_bytecode_handlers(g);
+}
+
+#endif /* UPB_USE_JIT_X64 */
+
+
+/* TODO(haberman): allow this to be constructed for an arbitrary set of dest
+ * handlers and other mgroups (but verify we have a transitive closure). */
+const mgroup *mgroup_new(const upb_handlers *dest, bool allowjit, bool lazy,
+ const void *owner) {
+ mgroup *g;
+ compiler *c;
+
+ UPB_UNUSED(allowjit);
+ assert(upb_handlers_isfrozen(dest));
+
+ g = newgroup(owner);
+ c = newcompiler(g, lazy);
+ find_methods(c, dest);
+
+ /* We compile in two passes:
+ * 1. all messages are assigned relative offsets from the beginning of the
+ * bytecode (saved in method->code_base).
+ * 2. forwards OP_CALL instructions can be correctly linked since message
+ * offsets have been previously assigned.
+ *
+ * Could avoid the second pass by linking OP_CALL instructions somehow. */
+ compile_methods(c);
+ compile_methods(c);
+ g->bytecode_end = c->pc;
+ freecompiler(c);
+
+#ifdef UPB_DUMP_BYTECODE
+ {
+ FILE *f = fopen("/tmp/upb-bytecode", "wb");
+ assert(f);
+ dumpbc(g->bytecode, g->bytecode_end, stderr);
+ dumpbc(g->bytecode, g->bytecode_end, f);
+ fclose(f);
+ }
+#endif
+
+ sethandlers(g, allowjit);
+ return g;
+}
+
+
+/* upb_pbcodecache ************************************************************/
+
+void upb_pbcodecache_init(upb_pbcodecache *c) {
+ upb_inttable_init(&c->groups, UPB_CTYPE_CONSTPTR);
+ c->allow_jit_ = true;
+}
+
+void upb_pbcodecache_uninit(upb_pbcodecache *c) {
+ upb_inttable_iter i;
+ upb_inttable_begin(&i, &c->groups);
+ for(; !upb_inttable_done(&i); upb_inttable_next(&i)) {
+ const mgroup *group = upb_value_getconstptr(upb_inttable_iter_value(&i));
+ mgroup_unref(group, c);
+ }
+ upb_inttable_uninit(&c->groups);
+}
+
+bool upb_pbcodecache_allowjit(const upb_pbcodecache *c) {
+ return c->allow_jit_;
+}
+
+bool upb_pbcodecache_setallowjit(upb_pbcodecache *c, bool allow) {
+ if (upb_inttable_count(&c->groups) > 0)
+ return false;
+ c->allow_jit_ = allow;
+ return true;
+}
+
+const upb_pbdecodermethod *upb_pbcodecache_getdecodermethod(
+ upb_pbcodecache *c, const upb_pbdecodermethodopts *opts) {
+ upb_value v;
+ bool ok;
+
+ /* Right now we build a new DecoderMethod every time.
+ * TODO(haberman): properly cache methods by their true key. */
+ const mgroup *g = mgroup_new(opts->handlers, c->allow_jit_, opts->lazy, c);
+ upb_inttable_push(&c->groups, upb_value_constptr(g));
+
+ ok = upb_inttable_lookupptr(&g->methods, opts->handlers, &v);
+ UPB_ASSERT_VAR(ok, ok);
+ return upb_value_getptr(v);
+}
+
+
+/* upb_pbdecodermethodopts ****************************************************/
+
+void upb_pbdecodermethodopts_init(upb_pbdecodermethodopts *opts,
+ const upb_handlers *h) {
+ opts->handlers = h;
+ opts->lazy = false;
+}
+
+void upb_pbdecodermethodopts_setlazy(upb_pbdecodermethodopts *opts, bool lazy) {
+ opts->lazy = lazy;
+}
+/*
+** upb::Decoder (Bytecode Decoder VM)
+**
+** Bytecode must previously have been generated using the bytecode compiler in
+** compile_decoder.c. This decoder then walks through the bytecode op-by-op to
+** parse the input.
+**
+** Decoding is fully resumable; we just keep a pointer to the current bytecode
+** instruction and resume from there. A fair amount of the logic here is to
+** handle the fact that values can span buffer seams and we have to be able to
+** be capable of suspending/resuming from any byte in the stream. This
+** sometimes requires keeping a few trailing bytes from the last buffer around
+** in the "residual" buffer.
+*/
+
+#include <inttypes.h>
+#include <stddef.h>
+
+#ifdef UPB_DUMP_BYTECODE
+#include <stdio.h>
+#endif
+
+#define CHECK_SUSPEND(x) if (!(x)) return upb_pbdecoder_suspend(d);
+
+/* Error messages that are shared between the bytecode and JIT decoders. */
+const char *kPbDecoderStackOverflow = "Nesting too deep.";
+const char *kPbDecoderSubmessageTooLong =
+ "Submessage end extends past enclosing submessage.";
+
+/* Error messages shared within this file. */
+static const char *kUnterminatedVarint = "Unterminated varint.";
+
+/* upb_pbdecoder **************************************************************/
+
+static opcode halt = OP_HALT;
+
+/* Whether an op consumes any of the input buffer. */
+static bool consumes_input(opcode op) {
+ switch (op) {
+ case OP_SETDISPATCH:
+ case OP_STARTMSG:
+ case OP_ENDMSG:
+ case OP_STARTSEQ:
+ case OP_ENDSEQ:
+ case OP_STARTSUBMSG:
+ case OP_ENDSUBMSG:
+ case OP_STARTSTR:
+ case OP_ENDSTR:
+ case OP_PUSHTAGDELIM:
+ case OP_POP:
+ case OP_SETDELIM:
+ case OP_SETBIGGROUPNUM:
+ case OP_CHECKDELIM:
+ case OP_CALL:
+ case OP_RET:
+ case OP_BRANCH:
+ return false;
+ default:
+ return true;
+ }
+}
+
+static size_t stacksize(upb_pbdecoder *d, size_t entries) {
+ UPB_UNUSED(d);
+ return entries * sizeof(upb_pbdecoder_frame);
+}
+
+static size_t callstacksize(upb_pbdecoder *d, size_t entries) {
+ UPB_UNUSED(d);
+
+#ifdef UPB_USE_JIT_X64
+ if (d->method_->is_native_) {
+ /* Each native stack frame needs two pointers, plus we need a few frames for
+ * the enter/exit trampolines. */
+ size_t ret = entries * sizeof(void*) * 2;
+ ret += sizeof(void*) * 10;
+ return ret;
+ }
+#endif
+
+ return entries * sizeof(uint32_t*);
+}
+
+
+static bool in_residual_buf(const upb_pbdecoder *d, const char *p);
+
+/* It's unfortunate that we have to micro-manage the compiler with
+ * UPB_FORCEINLINE and UPB_NOINLINE, especially since this tuning is necessarily
+ * specific to one hardware configuration. But empirically on a Core i7,
+ * performance increases 30-50% with these annotations. Every instance where
+ * these appear, gcc 4.2.1 made the wrong decision and degraded performance in
+ * benchmarks. */
+
+static void seterr(upb_pbdecoder *d, const char *msg) {
+ upb_status status = UPB_STATUS_INIT;
+ upb_status_seterrmsg(&status, msg);
+ upb_env_reporterror(d->env, &status);
+}
+
+void upb_pbdecoder_seterr(upb_pbdecoder *d, const char *msg) {
+ seterr(d, msg);
+}
+
+
+/* Buffering ******************************************************************/
+
+/* We operate on one buffer at a time, which is either the user's buffer passed
+ * to our "decode" callback or some residual bytes from the previous buffer. */
+
+/* How many bytes can be safely read from d->ptr without reading past end-of-buf
+ * or past the current delimited end. */
+static size_t curbufleft(const upb_pbdecoder *d) {
+ assert(d->data_end >= d->ptr);
+ return d->data_end - d->ptr;
+}
+
+/* How many bytes are available before end-of-buffer. */
+static size_t bufleft(const upb_pbdecoder *d) {
+ return d->end - d->ptr;
+}
+
+/* Overall stream offset of d->ptr. */
+uint64_t offset(const upb_pbdecoder *d) {
+ return d->bufstart_ofs + (d->ptr - d->buf);
+}
+
+/* How many bytes are available before the end of this delimited region. */
+size_t delim_remaining(const upb_pbdecoder *d) {
+ return d->top->end_ofs - offset(d);
+}
+
+/* Advances d->ptr. */
+static void advance(upb_pbdecoder *d, size_t len) {
+ assert(curbufleft(d) >= len);
+ d->ptr += len;
+}
+
+static bool in_buf(const char *p, const char *buf, const char *end) {
+ return p >= buf && p <= end;
+}
+
+static bool in_residual_buf(const upb_pbdecoder *d, const char *p) {
+ return in_buf(p, d->residual, d->residual_end);
+}
+
+/* Calculates the delim_end value, which is affected by both the current buffer
+ * and the parsing stack, so must be called whenever either is updated. */
+static void set_delim_end(upb_pbdecoder *d) {
+ size_t delim_ofs = d->top->end_ofs - d->bufstart_ofs;
+ if (delim_ofs <= (size_t)(d->end - d->buf)) {
+ d->delim_end = d->buf + delim_ofs;
+ d->data_end = d->delim_end;
+ } else {
+ d->data_end = d->end;
+ d->delim_end = NULL;
+ }
+}
+
+static void switchtobuf(upb_pbdecoder *d, const char *buf, const char *end) {
+ d->ptr = buf;
+ d->buf = buf;
+ d->end = end;
+ set_delim_end(d);
+}
+
+static void advancetobuf(upb_pbdecoder *d, const char *buf, size_t len) {
+ assert(curbufleft(d) == 0);
+ d->bufstart_ofs += (d->end - d->buf);
+ switchtobuf(d, buf, buf + len);
+}
+
+static void checkpoint(upb_pbdecoder *d) {
+ /* The assertion here is in the interests of efficiency, not correctness.
+ * We are trying to ensure that we don't checkpoint() more often than
+ * necessary. */
+ assert(d->checkpoint != d->ptr);
+ d->checkpoint = d->ptr;
+}
+
+/* Skips "bytes" bytes in the stream, which may be more than available. If we
+ * skip more bytes than are available, we return a long read count to the caller
+ * indicating how many bytes can be skipped over before passing actual data
+ * again. Skipped bytes can pass a NULL buffer and the decoder guarantees they
+ * won't actually be read.
+ */
+static int32_t skip(upb_pbdecoder *d, size_t bytes) {
+ assert(!in_residual_buf(d, d->ptr) || d->size_param == 0);
+ assert(d->skip == 0);
+ if (bytes > delim_remaining(d)) {
+ seterr(d, "Skipped value extended beyond enclosing submessage.");
+ return upb_pbdecoder_suspend(d);
+ } else if (bufleft(d) > bytes) {
+ /* Skipped data is all in current buffer, and more is still available. */
+ advance(d, bytes);
+ d->skip = 0;
+ return DECODE_OK;
+ } else {
+ /* Skipped data extends beyond currently available buffers. */
+ d->pc = d->last;
+ d->skip = bytes - curbufleft(d);
+ d->bufstart_ofs += (d->end - d->buf);
+ d->residual_end = d->residual;
+ switchtobuf(d, d->residual, d->residual_end);
+ return d->size_param + d->skip;
+ }
+}
+
+
+/* Resumes the decoder from an initial state or from a previous suspend. */
+int32_t upb_pbdecoder_resume(upb_pbdecoder *d, void *p, const char *buf,
+ size_t size, const upb_bufhandle *handle) {
+ UPB_UNUSED(p); /* Useless; just for the benefit of the JIT. */
+
+ d->buf_param = buf;
+ d->size_param = size;
+ d->handle = handle;
+
+ if (d->residual_end > d->residual) {
+ /* We have residual bytes from the last buffer. */
+ assert(d->ptr == d->residual);
+ } else {
+ switchtobuf(d, buf, buf + size);
+ }
+
+ d->checkpoint = d->ptr;
+
+ if (d->skip) {
+ size_t skip_bytes = d->skip;
+ d->skip = 0;
+ CHECK_RETURN(skip(d, skip_bytes));
+ d->checkpoint = d->ptr;
+ }
+
+ if (!buf) {
+ /* NULL buf is ok if its entire span is covered by the "skip" above, but
+ * by this point we know that "skip" doesn't cover the buffer. */
+ seterr(d, "Passed NULL buffer over non-skippable region.");
+ return upb_pbdecoder_suspend(d);
+ }
+
+ if (d->top->groupnum < 0) {
+ CHECK_RETURN(upb_pbdecoder_skipunknown(d, -1, 0));
+ d->checkpoint = d->ptr;
+ }
+
+ return DECODE_OK;
+}
+
+/* Suspends the decoder at the last checkpoint, without saving any residual
+ * bytes. If there are any unconsumed bytes, returns a short byte count. */
+size_t upb_pbdecoder_suspend(upb_pbdecoder *d) {
+ d->pc = d->last;
+ if (d->checkpoint == d->residual) {
+ /* Checkpoint was in residual buf; no user bytes were consumed. */
+ d->ptr = d->residual;
+ return 0;
+ } else {
+ size_t consumed;
+ assert(!in_residual_buf(d, d->checkpoint));
+ assert(d->buf == d->buf_param);
+
+ consumed = d->checkpoint - d->buf;
+ d->bufstart_ofs += consumed;
+ d->residual_end = d->residual;
+ switchtobuf(d, d->residual, d->residual_end);
+ return consumed;
+ }
+}
+
+/* Suspends the decoder at the last checkpoint, and saves any unconsumed
+ * bytes in our residual buffer. This is necessary if we need more user
+ * bytes to form a complete value, which might not be contiguous in the
+ * user's buffers. Always consumes all user bytes. */
+static size_t suspend_save(upb_pbdecoder *d) {
+ /* We hit end-of-buffer before we could parse a full value.
+ * Save any unconsumed bytes (if any) to the residual buffer. */
+ d->pc = d->last;
+
+ if (d->checkpoint == d->residual) {
+ /* Checkpoint was in residual buf; append user byte(s) to residual buf. */
+ assert((d->residual_end - d->residual) + d->size_param <=
+ sizeof(d->residual));
+ if (!in_residual_buf(d, d->ptr)) {
+ d->bufstart_ofs -= (d->residual_end - d->residual);
+ }
+ memcpy(d->residual_end, d->buf_param, d->size_param);
+ d->residual_end += d->size_param;
+ } else {
+ /* Checkpoint was in user buf; old residual bytes not needed. */
+ size_t save;
+ assert(!in_residual_buf(d, d->checkpoint));
+
+ d->ptr = d->checkpoint;
+ save = curbufleft(d);
+ assert(save <= sizeof(d->residual));
+ memcpy(d->residual, d->ptr, save);
+ d->residual_end = d->residual + save;
+ d->bufstart_ofs = offset(d);
+ }
+
+ switchtobuf(d, d->residual, d->residual_end);
+ return d->size_param;
+}
+
+/* Copies the next "bytes" bytes into "buf" and advances the stream.
+ * Requires that this many bytes are available in the current buffer. */
+UPB_FORCEINLINE static void consumebytes(upb_pbdecoder *d, void *buf,
+ size_t bytes) {
+ assert(bytes <= curbufleft(d));
+ memcpy(buf, d->ptr, bytes);
+ advance(d, bytes);
+}
+
+/* Slow path for getting the next "bytes" bytes, regardless of whether they are
+ * available in the current buffer or not. Returns a status code as described
+ * in decoder.int.h. */
+UPB_NOINLINE static int32_t getbytes_slow(upb_pbdecoder *d, void *buf,
+ size_t bytes) {
+ const size_t avail = curbufleft(d);
+ consumebytes(d, buf, avail);
+ bytes -= avail;
+ assert(bytes > 0);
+ if (in_residual_buf(d, d->ptr)) {
+ advancetobuf(d, d->buf_param, d->size_param);
+ }
+ if (curbufleft(d) >= bytes) {
+ consumebytes(d, (char *)buf + avail, bytes);
+ return DECODE_OK;
+ } else if (d->data_end == d->delim_end) {
+ seterr(d, "Submessage ended in the middle of a value or group");
+ return upb_pbdecoder_suspend(d);
+ } else {
+ return suspend_save(d);
+ }
+}
+
+/* Gets the next "bytes" bytes, regardless of whether they are available in the
+ * current buffer or not. Returns a status code as described in decoder.int.h.
+ */
+UPB_FORCEINLINE static int32_t getbytes(upb_pbdecoder *d, void *buf,
+ size_t bytes) {
+ if (curbufleft(d) >= bytes) {
+ /* Buffer has enough data to satisfy. */
+ consumebytes(d, buf, bytes);
+ return DECODE_OK;
+ } else {
+ return getbytes_slow(d, buf, bytes);
+ }
+}
+
+UPB_NOINLINE static size_t peekbytes_slow(upb_pbdecoder *d, void *buf,
+ size_t bytes) {
+ size_t ret = curbufleft(d);
+ memcpy(buf, d->ptr, ret);
+ if (in_residual_buf(d, d->ptr)) {
+ size_t copy = UPB_MIN(bytes - ret, d->size_param);
+ memcpy((char *)buf + ret, d->buf_param, copy);
+ ret += copy;
+ }
+ return ret;
+}
+
+UPB_FORCEINLINE static size_t peekbytes(upb_pbdecoder *d, void *buf,
+ size_t bytes) {
+ if (curbufleft(d) >= bytes) {
+ memcpy(buf, d->ptr, bytes);
+ return bytes;
+ } else {
+ return peekbytes_slow(d, buf, bytes);
+ }
+}
+
+
+/* Decoding of wire types *****************************************************/
+
+/* Slow path for decoding a varint from the current buffer position.
+ * Returns a status code as described in decoder.int.h. */
+UPB_NOINLINE int32_t upb_pbdecoder_decode_varint_slow(upb_pbdecoder *d,
+ uint64_t *u64) {
+ uint8_t byte = 0x80;
+ int bitpos;
+ *u64 = 0;
+ for(bitpos = 0; bitpos < 70 && (byte & 0x80); bitpos += 7) {
+ int32_t ret = getbytes(d, &byte, 1);
+ if (ret >= 0) return ret;
+ *u64 |= (uint64_t)(byte & 0x7F) << bitpos;
+ }
+ if(bitpos == 70 && (byte & 0x80)) {
+ seterr(d, kUnterminatedVarint);
+ return upb_pbdecoder_suspend(d);
+ }
+ return DECODE_OK;
+}
+
+/* Decodes a varint from the current buffer position.
+ * Returns a status code as described in decoder.int.h. */
+UPB_FORCEINLINE static int32_t decode_varint(upb_pbdecoder *d, uint64_t *u64) {
+ if (curbufleft(d) > 0 && !(*d->ptr & 0x80)) {
+ *u64 = *d->ptr;
+ advance(d, 1);
+ return DECODE_OK;
+ } else if (curbufleft(d) >= 10) {
+ /* Fast case. */
+ upb_decoderet r = upb_vdecode_fast(d->ptr);
+ if (r.p == NULL) {
+ seterr(d, kUnterminatedVarint);
+ return upb_pbdecoder_suspend(d);
+ }
+ advance(d, r.p - d->ptr);
+ *u64 = r.val;
+ return DECODE_OK;
+ } else {
+ /* Slow case -- varint spans buffer seam. */
+ return upb_pbdecoder_decode_varint_slow(d, u64);
+ }
+}
+
+/* Decodes a 32-bit varint from the current buffer position.
+ * Returns a status code as described in decoder.int.h. */
+UPB_FORCEINLINE static int32_t decode_v32(upb_pbdecoder *d, uint32_t *u32) {
+ uint64_t u64;
+ int32_t ret = decode_varint(d, &u64);
+ if (ret >= 0) return ret;
+ if (u64 > UINT32_MAX) {
+ seterr(d, "Unterminated 32-bit varint");
+ /* TODO(haberman) guarantee that this function return is >= 0 somehow,
+ * so we know this path will always be treated as error by our caller.
+ * Right now the size_t -> int32_t can overflow and produce negative values.
+ */
+ *u32 = 0;
+ return upb_pbdecoder_suspend(d);
+ }
+ *u32 = u64;
+ return DECODE_OK;
+}
+
+/* Decodes a fixed32 from the current buffer position.
+ * Returns a status code as described in decoder.int.h.
+ * TODO: proper byte swapping for big-endian machines. */
+UPB_FORCEINLINE static int32_t decode_fixed32(upb_pbdecoder *d, uint32_t *u32) {
+ return getbytes(d, u32, 4);
+}
+
+/* Decodes a fixed64 from the current buffer position.
+ * Returns a status code as described in decoder.int.h.
+ * TODO: proper byte swapping for big-endian machines. */
+UPB_FORCEINLINE static int32_t decode_fixed64(upb_pbdecoder *d, uint64_t *u64) {
+ return getbytes(d, u64, 8);
+}
+
+/* Non-static versions of the above functions.
+ * These are called by the JIT for fallback paths. */
+int32_t upb_pbdecoder_decode_f32(upb_pbdecoder *d, uint32_t *u32) {
+ return decode_fixed32(d, u32);
+}
+
+int32_t upb_pbdecoder_decode_f64(upb_pbdecoder *d, uint64_t *u64) {
+ return decode_fixed64(d, u64);
+}
+
+static double as_double(uint64_t n) { double d; memcpy(&d, &n, 8); return d; }
+static float as_float(uint32_t n) { float f; memcpy(&f, &n, 4); return f; }
+
+/* Pushes a frame onto the decoder stack. */
+static bool decoder_push(upb_pbdecoder *d, uint64_t end) {
+ upb_pbdecoder_frame *fr = d->top;
+
+ if (end > fr->end_ofs) {
+ seterr(d, kPbDecoderSubmessageTooLong);
+ return false;
+ } else if (fr == d->limit) {
+ seterr(d, kPbDecoderStackOverflow);
+ return false;
+ }
+
+ fr++;
+ fr->end_ofs = end;
+ fr->dispatch = NULL;
+ fr->groupnum = 0;
+ d->top = fr;
+ return true;
+}
+
+static bool pushtagdelim(upb_pbdecoder *d, uint32_t arg) {
+ /* While we expect to see an "end" tag (either ENDGROUP or a non-sequence
+ * field number) prior to hitting any enclosing submessage end, pushing our
+ * existing delim end prevents us from continuing to parse values from a
+ * corrupt proto that doesn't give us an END tag in time. */
+ if (!decoder_push(d, d->top->end_ofs))
+ return false;
+ d->top->groupnum = arg;
+ return true;
+}
+
+/* Pops a frame from the decoder stack. */
+static void decoder_pop(upb_pbdecoder *d) { d->top--; }
+
+UPB_NOINLINE int32_t upb_pbdecoder_checktag_slow(upb_pbdecoder *d,
+ uint64_t expected) {
+ uint64_t data = 0;
+ size_t bytes = upb_value_size(expected);
+ size_t read = peekbytes(d, &data, bytes);
+ if (read == bytes && data == expected) {
+ /* Advance past matched bytes. */
+ int32_t ok = getbytes(d, &data, read);
+ UPB_ASSERT_VAR(ok, ok < 0);
+ return DECODE_OK;
+ } else if (read < bytes && memcmp(&data, &expected, read) == 0) {
+ return suspend_save(d);
+ } else {
+ return DECODE_MISMATCH;
+ }
+}
+
+int32_t upb_pbdecoder_skipunknown(upb_pbdecoder *d, int32_t fieldnum,
+ uint8_t wire_type) {
+ if (fieldnum >= 0)
+ goto have_tag;
+
+ while (true) {
+ uint32_t tag;
+ CHECK_RETURN(decode_v32(d, &tag));
+ wire_type = tag & 0x7;
+ fieldnum = tag >> 3;
+
+have_tag:
+ if (fieldnum == 0) {
+ seterr(d, "Saw invalid field number (0)");
+ return upb_pbdecoder_suspend(d);
+ }
+
+ /* TODO: deliver to unknown field callback. */
+ switch (wire_type) {
+ case UPB_WIRE_TYPE_32BIT:
+ CHECK_RETURN(skip(d, 4));
+ break;
+ case UPB_WIRE_TYPE_64BIT:
+ CHECK_RETURN(skip(d, 8));
+ break;
+ case UPB_WIRE_TYPE_VARINT: {
+ uint64_t u64;
+ CHECK_RETURN(decode_varint(d, &u64));
+ break;
+ }
+ case UPB_WIRE_TYPE_DELIMITED: {
+ uint32_t len;
+ CHECK_RETURN(decode_v32(d, &len));
+ CHECK_RETURN(skip(d, len));
+ break;
+ }
+ case UPB_WIRE_TYPE_START_GROUP:
+ CHECK_SUSPEND(pushtagdelim(d, -fieldnum));
+ break;
+ case UPB_WIRE_TYPE_END_GROUP:
+ if (fieldnum == -d->top->groupnum) {
+ decoder_pop(d);
+ } else if (fieldnum == d->top->groupnum) {
+ return DECODE_ENDGROUP;
+ } else {
+ seterr(d, "Unmatched ENDGROUP tag.");
+ return upb_pbdecoder_suspend(d);
+ }
+ break;
+ default:
+ seterr(d, "Invalid wire type");
+ return upb_pbdecoder_suspend(d);
+ }
+
+ if (d->top->groupnum >= 0) {
+ return DECODE_OK;
+ }
+
+ /* Unknown group -- continue looping over unknown fields. */
+ checkpoint(d);
+ }
+}
+
+static void goto_endmsg(upb_pbdecoder *d) {
+ upb_value v;
+ bool found = upb_inttable_lookup32(d->top->dispatch, DISPATCH_ENDMSG, &v);
+ UPB_ASSERT_VAR(found, found);
+ d->pc = d->top->base + upb_value_getuint64(v);
+}
+
+/* Parses a tag and jumps to the corresponding bytecode instruction for this
+ * field.
+ *
+ * If the tag is unknown (or the wire type doesn't match), parses the field as
+ * unknown. If the tag is a valid ENDGROUP tag, jumps to the bytecode
+ * instruction for the end of message. */
+static int32_t dispatch(upb_pbdecoder *d) {
+ upb_inttable *dispatch = d->top->dispatch;
+ uint32_t tag;
+ uint8_t wire_type;
+ uint32_t fieldnum;
+ upb_value val;
+ int32_t retval;
+
+ /* Decode tag. */
+ CHECK_RETURN(decode_v32(d, &tag));
+ wire_type = tag & 0x7;
+ fieldnum = tag >> 3;
+
+ /* Lookup tag. Because of packed/non-packed compatibility, we have to
+ * check the wire type against two possibilities. */
+ if (fieldnum != DISPATCH_ENDMSG &&
+ upb_inttable_lookup32(dispatch, fieldnum, &val)) {
+ uint64_t v = upb_value_getuint64(val);
+ if (wire_type == (v & 0xff)) {
+ d->pc = d->top->base + (v >> 16);
+ return DECODE_OK;
+ } else if (wire_type == ((v >> 8) & 0xff)) {
+ bool found =
+ upb_inttable_lookup(dispatch, fieldnum + UPB_MAX_FIELDNUMBER, &val);
+ UPB_ASSERT_VAR(found, found);
+ d->pc = d->top->base + upb_value_getuint64(val);
+ return DECODE_OK;
+ }
+ }
+
+ /* We have some unknown fields (or ENDGROUP) to parse. The DISPATCH or TAG
+ * bytecode that triggered this is preceded by a CHECKDELIM bytecode which
+ * we need to back up to, so that when we're done skipping unknown data we
+ * can re-check the delimited end. */
+ d->last--; /* Necessary if we get suspended */
+ d->pc = d->last;
+ assert(getop(*d->last) == OP_CHECKDELIM);
+
+ /* Unknown field or ENDGROUP. */
+ retval = upb_pbdecoder_skipunknown(d, fieldnum, wire_type);
+
+ CHECK_RETURN(retval);
+
+ if (retval == DECODE_ENDGROUP) {
+ goto_endmsg(d);
+ return DECODE_OK;
+ }
+
+ return DECODE_OK;
+}
+
+/* Callers know that the stack is more than one deep because the opcodes that
+ * call this only occur after PUSH operations. */
+upb_pbdecoder_frame *outer_frame(upb_pbdecoder *d) {
+ assert(d->top != d->stack);
+ return d->top - 1;
+}
+
+
+/* The main decoding loop *****************************************************/
+
+/* The main decoder VM function. Uses traditional bytecode dispatch loop with a
+ * switch() statement. */
+size_t run_decoder_vm(upb_pbdecoder *d, const mgroup *group,
+ const upb_bufhandle* handle) {
+
+#define VMCASE(op, code) \
+ case op: { code; if (consumes_input(op)) checkpoint(d); break; }
+#define PRIMITIVE_OP(type, wt, name, convfunc, ctype) \
+ VMCASE(OP_PARSE_ ## type, { \
+ ctype val; \
+ CHECK_RETURN(decode_ ## wt(d, &val)); \
+ upb_sink_put ## name(&d->top->sink, arg, (convfunc)(val)); \
+ })
+
+ while(1) {
+ int32_t instruction;
+ opcode op;
+ uint32_t arg;
+ int32_t longofs;
+
+ d->last = d->pc;
+ instruction = *d->pc++;
+ op = getop(instruction);
+ arg = instruction >> 8;
+ longofs = arg;
+ assert(d->ptr != d->residual_end);
+ UPB_UNUSED(group);
+#ifdef UPB_DUMP_BYTECODE
+ fprintf(stderr, "s_ofs=%d buf_ofs=%d data_rem=%d buf_rem=%d delim_rem=%d "
+ "%x %s (%d)\n",
+ (int)offset(d),
+ (int)(d->ptr - d->buf),
+ (int)(d->data_end - d->ptr),
+ (int)(d->end - d->ptr),
+ (int)((d->top->end_ofs - d->bufstart_ofs) - (d->ptr - d->buf)),
+ (int)(d->pc - 1 - group->bytecode),
+ upb_pbdecoder_getopname(op),
+ arg);
+#endif
+ switch (op) {
+ /* Technically, we are losing data if we see a 32-bit varint that is not
+ * properly sign-extended. We could detect this and error about the data
+ * loss, but proto2 does not do this, so we pass. */
+ PRIMITIVE_OP(INT32, varint, int32, int32_t, uint64_t)
+ PRIMITIVE_OP(INT64, varint, int64, int64_t, uint64_t)
+ PRIMITIVE_OP(UINT32, varint, uint32, uint32_t, uint64_t)
+ PRIMITIVE_OP(UINT64, varint, uint64, uint64_t, uint64_t)
+ PRIMITIVE_OP(FIXED32, fixed32, uint32, uint32_t, uint32_t)
+ PRIMITIVE_OP(FIXED64, fixed64, uint64, uint64_t, uint64_t)
+ PRIMITIVE_OP(SFIXED32, fixed32, int32, int32_t, uint32_t)
+ PRIMITIVE_OP(SFIXED64, fixed64, int64, int64_t, uint64_t)
+ PRIMITIVE_OP(BOOL, varint, bool, bool, uint64_t)
+ PRIMITIVE_OP(DOUBLE, fixed64, double, as_double, uint64_t)
+ PRIMITIVE_OP(FLOAT, fixed32, float, as_float, uint32_t)
+ PRIMITIVE_OP(SINT32, varint, int32, upb_zzdec_32, uint64_t)
+ PRIMITIVE_OP(SINT64, varint, int64, upb_zzdec_64, uint64_t)
+
+ VMCASE(OP_SETDISPATCH,
+ d->top->base = d->pc - 1;
+ memcpy(&d->top->dispatch, d->pc, sizeof(void*));
+ d->pc += sizeof(void*) / sizeof(uint32_t);
+ )
+ VMCASE(OP_STARTMSG,
+ CHECK_SUSPEND(upb_sink_startmsg(&d->top->sink));
+ )
+ VMCASE(OP_ENDMSG,
+ CHECK_SUSPEND(upb_sink_endmsg(&d->top->sink, d->status));
+ )
+ VMCASE(OP_STARTSEQ,
+ upb_pbdecoder_frame *outer = outer_frame(d);
+ CHECK_SUSPEND(upb_sink_startseq(&outer->sink, arg, &d->top->sink));
+ )
+ VMCASE(OP_ENDSEQ,
+ CHECK_SUSPEND(upb_sink_endseq(&d->top->sink, arg));
+ )
+ VMCASE(OP_STARTSUBMSG,
+ upb_pbdecoder_frame *outer = outer_frame(d);
+ CHECK_SUSPEND(upb_sink_startsubmsg(&outer->sink, arg, &d->top->sink));
+ )
+ VMCASE(OP_ENDSUBMSG,
+ CHECK_SUSPEND(upb_sink_endsubmsg(&d->top->sink, arg));
+ )
+ VMCASE(OP_STARTSTR,
+ uint32_t len = delim_remaining(d);
+ upb_pbdecoder_frame *outer = outer_frame(d);
+ CHECK_SUSPEND(upb_sink_startstr(&outer->sink, arg, len, &d->top->sink));
+ if (len == 0) {
+ d->pc++; /* Skip OP_STRING. */
+ }
+ )
+ VMCASE(OP_STRING,
+ uint32_t len = curbufleft(d);
+ size_t n = upb_sink_putstring(&d->top->sink, arg, d->ptr, len, handle);
+ if (n > len) {
+ if (n > delim_remaining(d)) {
+ seterr(d, "Tried to skip past end of string.");
+ return upb_pbdecoder_suspend(d);
+ } else {
+ int32_t ret = skip(d, n);
+ /* This shouldn't return DECODE_OK, because n > len. */
+ assert(ret >= 0);
+ return ret;
+ }
+ }
+ advance(d, n);
+ if (n < len || d->delim_end == NULL) {
+ /* We aren't finished with this string yet. */
+ d->pc--; /* Repeat OP_STRING. */
+ if (n > 0) checkpoint(d);
+ return upb_pbdecoder_suspend(d);
+ }
+ )
+ VMCASE(OP_ENDSTR,
+ CHECK_SUSPEND(upb_sink_endstr(&d->top->sink, arg));
+ )
+ VMCASE(OP_PUSHTAGDELIM,
+ CHECK_SUSPEND(pushtagdelim(d, arg));
+ )
+ VMCASE(OP_SETBIGGROUPNUM,
+ d->top->groupnum = *d->pc++;
+ )
+ VMCASE(OP_POP,
+ assert(d->top > d->stack);
+ decoder_pop(d);
+ )
+ VMCASE(OP_PUSHLENDELIM,
+ uint32_t len;
+ CHECK_RETURN(decode_v32(d, &len));
+ CHECK_SUSPEND(decoder_push(d, offset(d) + len));
+ set_delim_end(d);
+ )
+ VMCASE(OP_SETDELIM,
+ set_delim_end(d);
+ )
+ VMCASE(OP_CHECKDELIM,
+ /* We are guaranteed of this assert because we never allow ourselves to
+ * consume bytes beyond data_end, which covers delim_end when non-NULL.
+ */
+ assert(!(d->delim_end && d->ptr > d->delim_end));
+ if (d->ptr == d->delim_end)
+ d->pc += longofs;
+ )
+ VMCASE(OP_CALL,
+ d->callstack[d->call_len++] = d->pc;
+ d->pc += longofs;
+ )
+ VMCASE(OP_RET,
+ assert(d->call_len > 0);
+ d->pc = d->callstack[--d->call_len];
+ )
+ VMCASE(OP_BRANCH,
+ d->pc += longofs;
+ )
+ VMCASE(OP_TAG1,
+ uint8_t expected;
+ CHECK_SUSPEND(curbufleft(d) > 0);
+ expected = (arg >> 8) & 0xff;
+ if (*d->ptr == expected) {
+ advance(d, 1);
+ } else {
+ int8_t shortofs;
+ badtag:
+ shortofs = arg;
+ if (shortofs == LABEL_DISPATCH) {
+ CHECK_RETURN(dispatch(d));
+ } else {
+ d->pc += shortofs;
+ break; /* Avoid checkpoint(). */
+ }
+ }
+ )
+ VMCASE(OP_TAG2,
+ uint16_t expected;
+ CHECK_SUSPEND(curbufleft(d) > 0);
+ expected = (arg >> 8) & 0xffff;
+ if (curbufleft(d) >= 2) {
+ uint16_t actual;
+ memcpy(&actual, d->ptr, 2);
+ if (expected == actual) {
+ advance(d, 2);
+ } else {
+ goto badtag;
+ }
+ } else {
+ int32_t result = upb_pbdecoder_checktag_slow(d, expected);
+ if (result == DECODE_MISMATCH) goto badtag;
+ if (result >= 0) return result;
+ }
+ )
+ VMCASE(OP_TAGN, {
+ uint64_t expected;
+ int32_t result;
+ memcpy(&expected, d->pc, 8);
+ d->pc += 2;
+ result = upb_pbdecoder_checktag_slow(d, expected);
+ if (result == DECODE_MISMATCH) goto badtag;
+ if (result >= 0) return result;
+ })
+ VMCASE(OP_DISPATCH, {
+ CHECK_RETURN(dispatch(d));
+ })
+ VMCASE(OP_HALT, {
+ return d->size_param;
+ })
+ }
+ }
+}
+
+
+/* BytesHandler handlers ******************************************************/
+
+void *upb_pbdecoder_startbc(void *closure, const void *pc, size_t size_hint) {
+ upb_pbdecoder *d = closure;
+ UPB_UNUSED(size_hint);
+ d->top->end_ofs = UINT64_MAX;
+ d->bufstart_ofs = 0;
+ d->call_len = 1;
+ d->callstack[0] = &halt;
+ d->pc = pc;
+ d->skip = 0;
+ return d;
+}
+
+void *upb_pbdecoder_startjit(void *closure, const void *hd, size_t size_hint) {
+ upb_pbdecoder *d = closure;
+ UPB_UNUSED(hd);
+ UPB_UNUSED(size_hint);
+ d->top->end_ofs = UINT64_MAX;
+ d->bufstart_ofs = 0;
+ d->call_len = 0;
+ d->skip = 0;
+ return d;
+}
+
+bool upb_pbdecoder_end(void *closure, const void *handler_data) {
+ upb_pbdecoder *d = closure;
+ const upb_pbdecodermethod *method = handler_data;
+ uint64_t end;
+ char dummy;
+
+ if (d->residual_end > d->residual) {
+ seterr(d, "Unexpected EOF: decoder still has buffered unparsed data");
+ return false;
+ }
+
+ if (d->skip) {
+ seterr(d, "Unexpected EOF inside skipped data");
+ return false;
+ }
+
+ if (d->top->end_ofs != UINT64_MAX) {
+ seterr(d, "Unexpected EOF inside delimited string");
+ return false;
+ }
+
+ /* The user's end() call indicates that the message ends here. */
+ end = offset(d);
+ d->top->end_ofs = end;
+
+#ifdef UPB_USE_JIT_X64
+ if (method->is_native_) {
+ const mgroup *group = (const mgroup*)method->group;
+ if (d->top != d->stack)
+ d->stack->end_ofs = 0;
+ group->jit_code(closure, method->code_base.ptr, &dummy, 0, NULL);
+ } else
+#endif
+ {
+ const uint32_t *p = d->pc;
+ d->stack->end_ofs = end;
+ /* Check the previous bytecode, but guard against beginning. */
+ if (p != method->code_base.ptr) p--;
+ if (getop(*p) == OP_CHECKDELIM) {
+ /* Rewind from OP_TAG* to OP_CHECKDELIM. */
+ assert(getop(*d->pc) == OP_TAG1 ||
+ getop(*d->pc) == OP_TAG2 ||
+ getop(*d->pc) == OP_TAGN ||
+ getop(*d->pc) == OP_DISPATCH);
+ d->pc = p;
+ }
+ upb_pbdecoder_decode(closure, handler_data, &dummy, 0, NULL);
+ }
+
+ if (d->call_len != 0) {
+ seterr(d, "Unexpected EOF inside submessage or group");
+ return false;
+ }
+
+ return true;
+}
+
+size_t upb_pbdecoder_decode(void *decoder, const void *group, const char *buf,
+ size_t size, const upb_bufhandle *handle) {
+ int32_t result = upb_pbdecoder_resume(decoder, NULL, buf, size, handle);
+
+ if (result == DECODE_ENDGROUP) goto_endmsg(decoder);
+ CHECK_RETURN(result);
+
+ return run_decoder_vm(decoder, group, handle);
+}
+
+
+/* Public API *****************************************************************/
+
+void upb_pbdecoder_reset(upb_pbdecoder *d) {
+ d->top = d->stack;
+ d->top->groupnum = 0;
+ d->ptr = d->residual;
+ d->buf = d->residual;
+ d->end = d->residual;
+ d->residual_end = d->residual;
+}
+
+upb_pbdecoder *upb_pbdecoder_create(upb_env *e, const upb_pbdecodermethod *m,
+ upb_sink *sink) {
+ const size_t default_max_nesting = 64;
+#ifndef NDEBUG
+ size_t size_before = upb_env_bytesallocated(e);
+#endif
+
+ upb_pbdecoder *d = upb_env_malloc(e, sizeof(upb_pbdecoder));
+ if (!d) return NULL;
+
+ d->method_ = m;
+ d->callstack = upb_env_malloc(e, callstacksize(d, default_max_nesting));
+ d->stack = upb_env_malloc(e, stacksize(d, default_max_nesting));
+ if (!d->stack || !d->callstack) {
+ return NULL;
+ }
+
+ d->env = e;
+ d->limit = d->stack + default_max_nesting - 1;
+ d->stack_size = default_max_nesting;
+
+ upb_pbdecoder_reset(d);
+ upb_bytessink_reset(&d->input_, &m->input_handler_, d);
+
+ assert(sink);
+ if (d->method_->dest_handlers_) {
+ if (sink->handlers != d->method_->dest_handlers_)
+ return NULL;
+ }
+ upb_sink_reset(&d->top->sink, sink->handlers, sink->closure);
+
+ /* If this fails, increase the value in decoder.h. */
+ assert(upb_env_bytesallocated(e) - size_before <= UPB_PB_DECODER_SIZE);
+ return d;
+}
+
+uint64_t upb_pbdecoder_bytesparsed(const upb_pbdecoder *d) {
+ return offset(d);
+}
+
+const upb_pbdecodermethod *upb_pbdecoder_method(const upb_pbdecoder *d) {
+ return d->method_;
+}
+
+upb_bytessink *upb_pbdecoder_input(upb_pbdecoder *d) {
+ return &d->input_;
+}
+
+size_t upb_pbdecoder_maxnesting(const upb_pbdecoder *d) {
+ return d->stack_size;
+}
+
+bool upb_pbdecoder_setmaxnesting(upb_pbdecoder *d, size_t max) {
+ assert(d->top >= d->stack);
+
+ if (max < (size_t)(d->top - d->stack)) {
+ /* Can't set a limit smaller than what we are currently at. */
+ return false;
+ }
+
+ if (max > d->stack_size) {
+ /* Need to reallocate stack and callstack to accommodate. */
+ size_t old_size = stacksize(d, d->stack_size);
+ size_t new_size = stacksize(d, max);
+ void *p = upb_env_realloc(d->env, d->stack, old_size, new_size);
+ if (!p) {
+ return false;
+ }
+ d->stack = p;
+
+ old_size = callstacksize(d, d->stack_size);
+ new_size = callstacksize(d, max);
+ p = upb_env_realloc(d->env, d->callstack, old_size, new_size);
+ if (!p) {
+ return false;
+ }
+ d->callstack = p;
+
+ d->stack_size = max;
+ }
+
+ d->limit = d->stack + max - 1;
+ return true;
+}
+/*
+** upb::Encoder
+**
+** Since we are implementing pure handlers (ie. without any out-of-band access
+** to pre-computed lengths), we have to buffer all submessages before we can
+** emit even their first byte.
+**
+** Not knowing the size of submessages also means we can't write a perfect
+** zero-copy implementation, even with buffering. Lengths are stored as
+** varints, which means that we don't know how many bytes to reserve for the
+** length until we know what the length is.
+**
+** This leaves us with three main choices:
+**
+** 1. buffer all submessage data in a temporary buffer, then copy it exactly
+** once into the output buffer.
+**
+** 2. attempt to buffer data directly into the output buffer, estimating how
+** many bytes each length will take. When our guesses are wrong, use
+** memmove() to grow or shrink the allotted space.
+**
+** 3. buffer directly into the output buffer, allocating a max length
+** ahead-of-time for each submessage length. If we overallocated, we waste
+** space, but no memcpy() or memmove() is required. This approach requires
+** defining a maximum size for submessages and rejecting submessages that
+** exceed that size.
+**
+** (2) and (3) have the potential to have better performance, but they are more
+** complicated and subtle to implement:
+**
+** (3) requires making an arbitrary choice of the maximum message size; it
+** wastes space when submessages are shorter than this and fails
+** completely when they are longer. This makes it more finicky and
+** requires configuration based on the input. It also makes it impossible
+** to perfectly match the output of reference encoders that always use the
+** optimal amount of space for each length.
+**
+** (2) requires guessing the the size upfront, and if multiple lengths are
+** guessed wrong the minimum required number of memmove() operations may
+** be complicated to compute correctly. Implemented properly, it may have
+** a useful amortized or average cost, but more investigation is required
+** to determine this and what the optimal algorithm is to achieve it.
+**
+** (1) makes you always pay for exactly one copy, but its implementation is
+** the simplest and its performance is predictable.
+**
+** So for now, we implement (1) only. If we wish to optimize later, we should
+** be able to do it without affecting users.
+**
+** The strategy is to buffer the segments of data that do *not* depend on
+** unknown lengths in one buffer, and keep a separate buffer of segment pointers
+** and lengths. When the top-level submessage ends, we can go beginning to end,
+** alternating the writing of lengths with memcpy() of the rest of the data.
+** At the top level though, no buffering is required.
+*/
+
+
+#include <stdlib.h>
+
+/* The output buffer is divided into segments; a segment is a string of data
+ * that is "ready to go" -- it does not need any varint lengths inserted into
+ * the middle. The seams between segments are where varints will be inserted
+ * once they are known.
+ *
+ * We also use the concept of a "run", which is a range of encoded bytes that
+ * occur at a single submessage level. Every segment contains one or more runs.
+ *
+ * A segment can span messages. Consider:
+ *
+ * .--Submessage lengths---------.
+ * | | |
+ * | V V
+ * V | |--------------- | |-----------------
+ * Submessages: | |-----------------------------------------------
+ * Top-level msg: ------------------------------------------------------------
+ *
+ * Segments: ----- ------------------- -----------------
+ * Runs: *---- *--------------*--- *----------------
+ * (* marks the start)
+ *
+ * Note that the top-level menssage is not in any segment because it does not
+ * have any length preceding it.
+ *
+ * A segment is only interrupted when another length needs to be inserted. So
+ * observe how the second segment spans both the inner submessage and part of
+ * the next enclosing message. */
+typedef struct {
+ uint32_t msglen; /* The length to varint-encode before this segment. */
+ uint32_t seglen; /* Length of the segment. */
+} upb_pb_encoder_segment;
+
+struct upb_pb_encoder {
+ upb_env *env;
+
+ /* Our input and output. */
+ upb_sink input_;
+ upb_bytessink *output_;
+
+ /* The "subclosure" -- used as the inner closure as part of the bytessink
+ * protocol. */
+ void *subc;
+
+ /* The output buffer and limit, and our current write position. "buf"
+ * initially points to "initbuf", but is dynamically allocated if we need to
+ * grow beyond the initial size. */
+ char *buf, *ptr, *limit;
+
+ /* The beginning of the current run, or undefined if we are at the top
+ * level. */
+ char *runbegin;
+
+ /* The list of segments we are accumulating. */
+ upb_pb_encoder_segment *segbuf, *segptr, *seglimit;
+
+ /* The stack of enclosing submessages. Each entry in the stack points to the
+ * segment where this submessage's length is being accumulated. */
+ int *stack, *top, *stacklimit;
+
+ /* Depth of startmsg/endmsg calls. */
+ int depth;
+};
+
+/* low-level buffering ********************************************************/
+
+/* Low-level functions for interacting with the output buffer. */
+
+/* TODO(haberman): handle pushback */
+static void putbuf(upb_pb_encoder *e, const char *buf, size_t len) {
+ size_t n = upb_bytessink_putbuf(e->output_, e->subc, buf, len, NULL);
+ UPB_ASSERT_VAR(n, n == len);
+}
+
+static upb_pb_encoder_segment *top(upb_pb_encoder *e) {
+ return &e->segbuf[*e->top];
+}
+
+/* Call to ensure that at least "bytes" bytes are available for writing at
+ * e->ptr. Returns false if the bytes could not be allocated. */
+static bool reserve(upb_pb_encoder *e, size_t bytes) {
+ if ((size_t)(e->limit - e->ptr) < bytes) {
+ /* Grow buffer. */
+ char *new_buf;
+ size_t needed = bytes + (e->ptr - e->buf);
+ size_t old_size = e->limit - e->buf;
+
+ size_t new_size = old_size;
+
+ while (new_size < needed) {
+ new_size *= 2;
+ }
+
+ new_buf = upb_env_realloc(e->env, e->buf, old_size, new_size);
+
+ if (new_buf == NULL) {
+ return false;
+ }
+
+ e->ptr = new_buf + (e->ptr - e->buf);
+ e->runbegin = new_buf + (e->runbegin - e->buf);
+ e->limit = new_buf + new_size;
+ e->buf = new_buf;
+ }
+
+ return true;
+}
+
+/* Call when "bytes" bytes have been writte at e->ptr. The caller *must* have
+ * previously called reserve() with at least this many bytes. */
+static void encoder_advance(upb_pb_encoder *e, size_t bytes) {
+ assert((size_t)(e->limit - e->ptr) >= bytes);
+ e->ptr += bytes;
+}
+
+/* Call when all of the bytes for a handler have been written. Flushes the
+ * bytes if possible and necessary, returning false if this failed. */
+static bool commit(upb_pb_encoder *e) {
+ if (!e->top) {
+ /* We aren't inside a delimited region. Flush our accumulated bytes to
+ * the output.
+ *
+ * TODO(haberman): in the future we may want to delay flushing for
+ * efficiency reasons. */
+ putbuf(e, e->buf, e->ptr - e->buf);
+ e->ptr = e->buf;
+ }
+
+ return true;
+}
+
+/* Writes the given bytes to the buffer, handling reserve/advance. */
+static bool encode_bytes(upb_pb_encoder *e, const void *data, size_t len) {
+ if (!reserve(e, len)) {
+ return false;
+ }
+
+ memcpy(e->ptr, data, len);
+ encoder_advance(e, len);
+ return true;
+}
+
+/* Finish the current run by adding the run totals to the segment and message
+ * length. */
+static void accumulate(upb_pb_encoder *e) {
+ size_t run_len;
+ assert(e->ptr >= e->runbegin);
+ run_len = e->ptr - e->runbegin;
+ e->segptr->seglen += run_len;
+ top(e)->msglen += run_len;
+ e->runbegin = e->ptr;
+}
+
+/* Call to indicate the start of delimited region for which the full length is
+ * not yet known. All data will be buffered until the length is known.
+ * Delimited regions may be nested; their lengths will all be tracked properly. */
+static bool start_delim(upb_pb_encoder *e) {
+ if (e->top) {
+ /* We are already buffering, advance to the next segment and push it on the
+ * stack. */
+ accumulate(e);
+
+ if (++e->top == e->stacklimit) {
+ /* TODO(haberman): grow stack? */
+ return false;
+ }
+
+ if (++e->segptr == e->seglimit) {
+ /* Grow segment buffer. */
+ size_t old_size =
+ (e->seglimit - e->segbuf) * sizeof(upb_pb_encoder_segment);
+ size_t new_size = old_size * 2;
+ upb_pb_encoder_segment *new_buf =
+ upb_env_realloc(e->env, e->segbuf, old_size, new_size);
+
+ if (new_buf == NULL) {
+ return false;
+ }
+
+ e->segptr = new_buf + (e->segptr - e->segbuf);
+ e->seglimit = new_buf + (new_size / sizeof(upb_pb_encoder_segment));
+ e->segbuf = new_buf;
+ }
+ } else {
+ /* We were previously at the top level, start buffering. */
+ e->segptr = e->segbuf;
+ e->top = e->stack;
+ e->runbegin = e->ptr;
+ }
+
+ *e->top = e->segptr - e->segbuf;
+ e->segptr->seglen = 0;
+ e->segptr->msglen = 0;
+
+ return true;
+}
+
+/* Call to indicate the end of a delimited region. We now know the length of
+ * the delimited region. If we are not nested inside any other delimited
+ * regions, we can now emit all of the buffered data we accumulated. */
+static bool end_delim(upb_pb_encoder *e) {
+ size_t msglen;
+ accumulate(e);
+ msglen = top(e)->msglen;
+
+ if (e->top == e->stack) {
+ /* All lengths are now available, emit all buffered data. */
+ char buf[UPB_PB_VARINT_MAX_LEN];
+ upb_pb_encoder_segment *s;
+ const char *ptr = e->buf;
+ for (s = e->segbuf; s <= e->segptr; s++) {
+ size_t lenbytes = upb_vencode64(s->msglen, buf);
+ putbuf(e, buf, lenbytes);
+ putbuf(e, ptr, s->seglen);
+ ptr += s->seglen;
+ }
+
+ e->ptr = e->buf;
+ e->top = NULL;
+ } else {
+ /* Need to keep buffering; propagate length info into enclosing
+ * submessages. */
+ --e->top;
+ top(e)->msglen += msglen + upb_varint_size(msglen);
+ }
+
+ return true;
+}
+
+
+/* tag_t **********************************************************************/
+
+/* A precomputed (pre-encoded) tag and length. */
+
+typedef struct {
+ uint8_t bytes;
+ char tag[7];
+} tag_t;
+
+/* Allocates a new tag for this field, and sets it in these handlerattr. */
+static void new_tag(upb_handlers *h, const upb_fielddef *f, upb_wiretype_t wt,
+ upb_handlerattr *attr) {
+ uint32_t n = upb_fielddef_number(f);
+
+ tag_t *tag = malloc(sizeof(tag_t));
+ tag->bytes = upb_vencode64((n << 3) | wt, tag->tag);
+
+ upb_handlerattr_init(attr);
+ upb_handlerattr_sethandlerdata(attr, tag);
+ upb_handlers_addcleanup(h, tag, free);
+}
+
+static bool encode_tag(upb_pb_encoder *e, const tag_t *tag) {
+ return encode_bytes(e, tag->tag, tag->bytes);
+}
+
+
+/* encoding of wire types *****************************************************/
+
+static bool encode_fixed64(upb_pb_encoder *e, uint64_t val) {
+ /* TODO(haberman): byte-swap for big endian. */
+ return encode_bytes(e, &val, sizeof(uint64_t));
+}
+
+static bool encode_fixed32(upb_pb_encoder *e, uint32_t val) {
+ /* TODO(haberman): byte-swap for big endian. */
+ return encode_bytes(e, &val, sizeof(uint32_t));
+}
+
+static bool encode_varint(upb_pb_encoder *e, uint64_t val) {
+ if (!reserve(e, UPB_PB_VARINT_MAX_LEN)) {
+ return false;
+ }
+
+ encoder_advance(e, upb_vencode64(val, e->ptr));
+ return true;
+}
+
+static uint64_t dbl2uint64(double d) {
+ uint64_t ret;
+ memcpy(&ret, &d, sizeof(uint64_t));
+ return ret;
+}
+
+static uint32_t flt2uint32(float d) {
+ uint32_t ret;
+ memcpy(&ret, &d, sizeof(uint32_t));
+ return ret;
+}
+
+
+/* encoding of proto types ****************************************************/
+
+static bool startmsg(void *c, const void *hd) {
+ upb_pb_encoder *e = c;
+ UPB_UNUSED(hd);
+ if (e->depth++ == 0) {
+ upb_bytessink_start(e->output_, 0, &e->subc);
+ }
+ return true;
+}
+
+static bool endmsg(void *c, const void *hd, upb_status *status) {
+ upb_pb_encoder *e = c;
+ UPB_UNUSED(hd);
+ UPB_UNUSED(status);
+ if (--e->depth == 0) {
+ upb_bytessink_end(e->output_);
+ }
+ return true;
+}
+
+static void *encode_startdelimfield(void *c, const void *hd) {
+ bool ok = encode_tag(c, hd) && commit(c) && start_delim(c);
+ return ok ? c : UPB_BREAK;
+}
+
+static bool encode_enddelimfield(void *c, const void *hd) {
+ UPB_UNUSED(hd);
+ return end_delim(c);
+}
+
+static void *encode_startgroup(void *c, const void *hd) {
+ return (encode_tag(c, hd) && commit(c)) ? c : UPB_BREAK;
+}
+
+static bool encode_endgroup(void *c, const void *hd) {
+ return encode_tag(c, hd) && commit(c);
+}
+
+static void *encode_startstr(void *c, const void *hd, size_t size_hint) {
+ UPB_UNUSED(size_hint);
+ return encode_startdelimfield(c, hd);
+}
+
+static size_t encode_strbuf(void *c, const void *hd, const char *buf,
+ size_t len, const upb_bufhandle *h) {
+ UPB_UNUSED(hd);
+ UPB_UNUSED(h);
+ return encode_bytes(c, buf, len) ? len : 0;
+}
+
+#define T(type, ctype, convert, encode) \
+ static bool encode_scalar_##type(void *e, const void *hd, ctype val) { \
+ return encode_tag(e, hd) && encode(e, (convert)(val)) && commit(e); \
+ } \
+ static bool encode_packed_##type(void *e, const void *hd, ctype val) { \
+ UPB_UNUSED(hd); \
+ return encode(e, (convert)(val)); \
+ }
+
+T(double, double, dbl2uint64, encode_fixed64)
+T(float, float, flt2uint32, encode_fixed32)
+T(int64, int64_t, uint64_t, encode_varint)
+T(int32, int32_t, uint32_t, encode_varint)
+T(fixed64, uint64_t, uint64_t, encode_fixed64)
+T(fixed32, uint32_t, uint32_t, encode_fixed32)
+T(bool, bool, bool, encode_varint)
+T(uint32, uint32_t, uint32_t, encode_varint)
+T(uint64, uint64_t, uint64_t, encode_varint)
+T(enum, int32_t, uint32_t, encode_varint)
+T(sfixed32, int32_t, uint32_t, encode_fixed32)
+T(sfixed64, int64_t, uint64_t, encode_fixed64)
+T(sint32, int32_t, upb_zzenc_32, encode_varint)
+T(sint64, int64_t, upb_zzenc_64, encode_varint)
+
+#undef T
+
+
+/* code to build the handlers *************************************************/
+
+static void newhandlers_callback(const void *closure, upb_handlers *h) {
+ const upb_msgdef *m;
+ upb_msg_field_iter i;
+
+ UPB_UNUSED(closure);
+
+ upb_handlers_setstartmsg(h, startmsg, NULL);
+ upb_handlers_setendmsg(h, endmsg, NULL);
+
+ m = upb_handlers_msgdef(h);
+ for(upb_msg_field_begin(&i, m);
+ !upb_msg_field_done(&i);
+ upb_msg_field_next(&i)) {
+ const upb_fielddef *f = upb_msg_iter_field(&i);
+ bool packed = upb_fielddef_isseq(f) && upb_fielddef_isprimitive(f) &&
+ upb_fielddef_packed(f);
+ upb_handlerattr attr;
+ upb_wiretype_t wt =
+ packed ? UPB_WIRE_TYPE_DELIMITED
+ : upb_pb_native_wire_types[upb_fielddef_descriptortype(f)];
+
+ /* Pre-encode the tag for this field. */
+ new_tag(h, f, wt, &attr);
+
+ if (packed) {
+ upb_handlers_setstartseq(h, f, encode_startdelimfield, &attr);
+ upb_handlers_setendseq(h, f, encode_enddelimfield, &attr);
+ }
+
+#define T(upper, lower, upbtype) \
+ case UPB_DESCRIPTOR_TYPE_##upper: \
+ if (packed) { \
+ upb_handlers_set##upbtype(h, f, encode_packed_##lower, &attr); \
+ } else { \
+ upb_handlers_set##upbtype(h, f, encode_scalar_##lower, &attr); \
+ } \
+ break;
+
+ switch (upb_fielddef_descriptortype(f)) {
+ T(DOUBLE, double, double);
+ T(FLOAT, float, float);
+ T(INT64, int64, int64);
+ T(INT32, int32, int32);
+ T(FIXED64, fixed64, uint64);
+ T(FIXED32, fixed32, uint32);
+ T(BOOL, bool, bool);
+ T(UINT32, uint32, uint32);
+ T(UINT64, uint64, uint64);
+ T(ENUM, enum, int32);
+ T(SFIXED32, sfixed32, int32);
+ T(SFIXED64, sfixed64, int64);
+ T(SINT32, sint32, int32);
+ T(SINT64, sint64, int64);
+ case UPB_DESCRIPTOR_TYPE_STRING:
+ case UPB_DESCRIPTOR_TYPE_BYTES:
+ upb_handlers_setstartstr(h, f, encode_startstr, &attr);
+ upb_handlers_setendstr(h, f, encode_enddelimfield, &attr);
+ upb_handlers_setstring(h, f, encode_strbuf, &attr);
+ break;
+ case UPB_DESCRIPTOR_TYPE_MESSAGE:
+ upb_handlers_setstartsubmsg(h, f, encode_startdelimfield, &attr);
+ upb_handlers_setendsubmsg(h, f, encode_enddelimfield, &attr);
+ break;
+ case UPB_DESCRIPTOR_TYPE_GROUP: {
+ /* Endgroup takes a different tag (wire_type = END_GROUP). */
+ upb_handlerattr attr2;
+ new_tag(h, f, UPB_WIRE_TYPE_END_GROUP, &attr2);
+
+ upb_handlers_setstartsubmsg(h, f, encode_startgroup, &attr);
+ upb_handlers_setendsubmsg(h, f, encode_endgroup, &attr2);
+
+ upb_handlerattr_uninit(&attr2);
+ break;
+ }
+ }
+
+#undef T
+
+ upb_handlerattr_uninit(&attr);
+ }
+}
+
+void upb_pb_encoder_reset(upb_pb_encoder *e) {
+ e->segptr = NULL;
+ e->top = NULL;
+ e->depth = 0;
+}
+
+
+/* public API *****************************************************************/
+
+const upb_handlers *upb_pb_encoder_newhandlers(const upb_msgdef *m,
+ const void *owner) {
+ return upb_handlers_newfrozen(m, owner, newhandlers_callback, NULL);
+}
+
+upb_pb_encoder *upb_pb_encoder_create(upb_env *env, const upb_handlers *h,
+ upb_bytessink *output) {
+ const size_t initial_bufsize = 256;
+ const size_t initial_segbufsize = 16;
+ /* TODO(haberman): make this configurable. */
+ const size_t stack_size = 64;
+#ifndef NDEBUG
+ const size_t size_before = upb_env_bytesallocated(env);
+#endif
+
+ upb_pb_encoder *e = upb_env_malloc(env, sizeof(upb_pb_encoder));
+ if (!e) return NULL;
+
+ e->buf = upb_env_malloc(env, initial_bufsize);
+ e->segbuf = upb_env_malloc(env, initial_segbufsize * sizeof(*e->segbuf));
+ e->stack = upb_env_malloc(env, stack_size * sizeof(*e->stack));
+
+ if (!e->buf || !e->segbuf || !e->stack) {
+ return NULL;
+ }
+
+ e->limit = e->buf + initial_bufsize;
+ e->seglimit = e->segbuf + initial_segbufsize;
+ e->stacklimit = e->stack + stack_size;
+
+ upb_pb_encoder_reset(e);
+ upb_sink_reset(&e->input_, h, e);
+
+ e->env = env;
+ e->output_ = output;
+ e->subc = output->closure;
+ e->ptr = e->buf;
+
+ /* If this fails, increase the value in encoder.h. */
+ assert(upb_env_bytesallocated(env) - size_before <= UPB_PB_ENCODER_SIZE);
+ return e;
+}
+
+upb_sink *upb_pb_encoder_input(upb_pb_encoder *e) { return &e->input_; }
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+upb_def **upb_load_defs_from_descriptor(const char *str, size_t len, int *n,
+ void *owner, upb_status *status) {
+ /* Create handlers. */
+ const upb_pbdecodermethod *decoder_m;
+ const upb_handlers *reader_h = upb_descreader_newhandlers(&reader_h);
+ upb_env env;
+ upb_pbdecodermethodopts opts;
+ upb_pbdecoder *decoder;
+ upb_descreader *reader;
+ bool ok;
+ upb_def **ret = NULL;
+ upb_def **defs;
+
+ upb_pbdecodermethodopts_init(&opts, reader_h);
+ decoder_m = upb_pbdecodermethod_new(&opts, &decoder_m);
+
+ upb_env_init(&env);
+ upb_env_reporterrorsto(&env, status);
+
+ reader = upb_descreader_create(&env, reader_h);
+ decoder = upb_pbdecoder_create(&env, decoder_m, upb_descreader_input(reader));
+
+ /* Push input data. */
+ ok = upb_bufsrc_putbuf(str, len, upb_pbdecoder_input(decoder));
+
+ if (!ok) goto cleanup;
+ defs = upb_descreader_getdefs(reader, owner, n);
+ ret = malloc(sizeof(upb_def*) * (*n));
+ memcpy(ret, defs, sizeof(upb_def*) * (*n));
+
+cleanup:
+ upb_env_uninit(&env);
+ upb_handlers_unref(reader_h, &reader_h);
+ upb_pbdecodermethod_unref(decoder_m, &decoder_m);
+ return ret;
+}
+
+bool upb_load_descriptor_into_symtab(upb_symtab *s, const char *str, size_t len,
+ upb_status *status) {
+ int n;
+ bool success;
+ upb_def **defs = upb_load_defs_from_descriptor(str, len, &n, &defs, status);
+ if (!defs) return false;
+ success = upb_symtab_add(s, defs, n, &defs, status);
+ free(defs);
+ return success;
+}
+
+char *upb_readfile(const char *filename, size_t *len) {
+ long size;
+ char *buf;
+ FILE *f = fopen(filename, "rb");
+ if(!f) return NULL;
+ if(fseek(f, 0, SEEK_END) != 0) goto error;
+ size = ftell(f);
+ if(size < 0) goto error;
+ if(fseek(f, 0, SEEK_SET) != 0) goto error;
+ buf = malloc(size + 1);
+ if(size && fread(buf, size, 1, f) != 1) goto error;
+ fclose(f);
+ if (len) *len = size;
+ return buf;
+
+error:
+ fclose(f);
+ return NULL;
+}
+
+bool upb_load_descriptor_file_into_symtab(upb_symtab *symtab, const char *fname,
+ upb_status *status) {
+ size_t len;
+ bool success;
+ char *data = upb_readfile(fname, &len);
+ if (!data) {
+ if (status) upb_status_seterrf(status, "Couldn't read file: %s", fname);
+ return false;
+ }
+ success = upb_load_descriptor_into_symtab(symtab, data, len, status);
+ free(data);
+ return success;
+}
+/*
+ * upb::pb::TextPrinter
+ *
+ * OPT: This is not optimized at all. It uses printf() which parses the format
+ * string every time, and it allocates memory for every put.
+ */
+
+
+#include <ctype.h>
+#include <float.h>
+#include <inttypes.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+struct upb_textprinter {
+ upb_sink input_;
+ upb_bytessink *output_;
+ int indent_depth_;
+ bool single_line_;
+ void *subc;
+};
+
+#define CHECK(x) if ((x) < 0) goto err;
+
+static const char *shortname(const char *longname) {
+ const char *last = strrchr(longname, '.');
+ return last ? last + 1 : longname;
+}
+
+static int indent(upb_textprinter *p) {
+ int i;
+ if (!p->single_line_)
+ for (i = 0; i < p->indent_depth_; i++)
+ upb_bytessink_putbuf(p->output_, p->subc, " ", 2, NULL);
+ return 0;
+}
+
+static int endfield(upb_textprinter *p) {
+ const char ch = (p->single_line_ ? ' ' : '\n');
+ upb_bytessink_putbuf(p->output_, p->subc, &ch, 1, NULL);
+ return 0;
+}
+
+static int putescaped(upb_textprinter *p, const char *buf, size_t len,
+ bool preserve_utf8) {
+ /* Based on CEscapeInternal() from Google's protobuf release. */
+ char dstbuf[4096], *dst = dstbuf, *dstend = dstbuf + sizeof(dstbuf);
+ const char *end = buf + len;
+
+ /* I think hex is prettier and more useful, but proto2 uses octal; should
+ * investigate whether it can parse hex also. */
+ const bool use_hex = false;
+ bool last_hex_escape = false; /* true if last output char was \xNN */
+
+ for (; buf < end; buf++) {
+ bool is_hex_escape;
+
+ if (dstend - dst < 4) {
+ upb_bytessink_putbuf(p->output_, p->subc, dstbuf, dst - dstbuf, NULL);
+ dst = dstbuf;
+ }
+
+ is_hex_escape = false;
+ switch (*buf) {
+ case '\n': *(dst++) = '\\'; *(dst++) = 'n'; break;
+ case '\r': *(dst++) = '\\'; *(dst++) = 'r'; break;
+ case '\t': *(dst++) = '\\'; *(dst++) = 't'; break;
+ case '\"': *(dst++) = '\\'; *(dst++) = '\"'; break;
+ case '\'': *(dst++) = '\\'; *(dst++) = '\''; break;
+ case '\\': *(dst++) = '\\'; *(dst++) = '\\'; break;
+ default:
+ /* Note that if we emit \xNN and the buf character after that is a hex
+ * digit then that digit must be escaped too to prevent it being
+ * interpreted as part of the character code by C. */
+ if ((!preserve_utf8 || (uint8_t)*buf < 0x80) &&
+ (!isprint(*buf) || (last_hex_escape && isxdigit(*buf)))) {
+ sprintf(dst, (use_hex ? "\\x%02x" : "\\%03o"), (uint8_t)*buf);
+ is_hex_escape = use_hex;
+ dst += 4;
+ } else {
+ *(dst++) = *buf; break;
+ }
+ }
+ last_hex_escape = is_hex_escape;
+ }
+ /* Flush remaining data. */
+ upb_bytessink_putbuf(p->output_, p->subc, dstbuf, dst - dstbuf, NULL);
+ return 0;
+}
+
+bool putf(upb_textprinter *p, const char *fmt, ...) {
+ va_list args;
+ va_list args_copy;
+ char *str;
+ int written;
+ int len;
+ bool ok;
+
+ va_start(args, fmt);
+
+ /* Run once to get the length of the string. */
+ _upb_va_copy(args_copy, args);
+ len = _upb_vsnprintf(NULL, 0, fmt, args_copy);
+ va_end(args_copy);
+
+ /* + 1 for NULL terminator (vsprintf() requires it even if we don't). */
+ str = malloc(len + 1);
+ if (!str) return false;
+ written = vsprintf(str, fmt, args);
+ va_end(args);
+ UPB_ASSERT_VAR(written, written == len);
+
+ ok = upb_bytessink_putbuf(p->output_, p->subc, str, len, NULL);
+ free(str);
+ return ok;
+}
+
+
+/* handlers *******************************************************************/
+
+static bool textprinter_startmsg(void *c, const void *hd) {
+ upb_textprinter *p = c;
+ UPB_UNUSED(hd);
+ if (p->indent_depth_ == 0) {
+ upb_bytessink_start(p->output_, 0, &p->subc);
+ }
+ return true;
+}
+
+static bool textprinter_endmsg(void *c, const void *hd, upb_status *s) {
+ upb_textprinter *p = c;
+ UPB_UNUSED(hd);
+ UPB_UNUSED(s);
+ if (p->indent_depth_ == 0) {
+ upb_bytessink_end(p->output_);
+ }
+ return true;
+}
+
+#define TYPE(name, ctype, fmt) \
+ static bool textprinter_put ## name(void *closure, const void *handler_data, \
+ ctype val) { \
+ upb_textprinter *p = closure; \
+ const upb_fielddef *f = handler_data; \
+ CHECK(indent(p)); \
+ putf(p, "%s: " fmt, upb_fielddef_name(f), val); \
+ CHECK(endfield(p)); \
+ return true; \
+ err: \
+ return false; \
+}
+
+static bool textprinter_putbool(void *closure, const void *handler_data,
+ bool val) {
+ upb_textprinter *p = closure;
+ const upb_fielddef *f = handler_data;
+ CHECK(indent(p));
+ putf(p, "%s: %s", upb_fielddef_name(f), val ? "true" : "false");
+ CHECK(endfield(p));
+ return true;
+err:
+ return false;
+}
+
+#define STRINGIFY_HELPER(x) #x
+#define STRINGIFY_MACROVAL(x) STRINGIFY_HELPER(x)
+
+TYPE(int32, int32_t, "%" PRId32)
+TYPE(int64, int64_t, "%" PRId64)
+TYPE(uint32, uint32_t, "%" PRIu32)
+TYPE(uint64, uint64_t, "%" PRIu64)
+TYPE(float, float, "%." STRINGIFY_MACROVAL(FLT_DIG) "g")
+TYPE(double, double, "%." STRINGIFY_MACROVAL(DBL_DIG) "g")
+
+#undef TYPE
+
+/* Output a symbolic value from the enum if found, else just print as int32. */
+static bool textprinter_putenum(void *closure, const void *handler_data,
+ int32_t val) {
+ upb_textprinter *p = closure;
+ const upb_fielddef *f = handler_data;
+ const upb_enumdef *enum_def = upb_downcast_enumdef(upb_fielddef_subdef(f));
+ const char *label = upb_enumdef_iton(enum_def, val);
+ if (label) {
+ indent(p);
+ putf(p, "%s: %s", upb_fielddef_name(f), label);
+ endfield(p);
+ } else {
+ if (!textprinter_putint32(closure, handler_data, val))
+ return false;
+ }
+ return true;
+}
+
+static void *textprinter_startstr(void *closure, const void *handler_data,
+ size_t size_hint) {
+ upb_textprinter *p = closure;
+ const upb_fielddef *f = handler_data;
+ UPB_UNUSED(size_hint);
+ indent(p);
+ putf(p, "%s: \"", upb_fielddef_name(f));
+ return p;
+}
+
+static bool textprinter_endstr(void *closure, const void *handler_data) {
+ upb_textprinter *p = closure;
+ UPB_UNUSED(handler_data);
+ putf(p, "\"");
+ endfield(p);
+ return true;
+}
+
+static size_t textprinter_putstr(void *closure, const void *hd, const char *buf,
+ size_t len, const upb_bufhandle *handle) {
+ upb_textprinter *p = closure;
+ const upb_fielddef *f = hd;
+ UPB_UNUSED(handle);
+ CHECK(putescaped(p, buf, len, upb_fielddef_type(f) == UPB_TYPE_STRING));
+ return len;
+err:
+ return 0;
+}
+
+static void *textprinter_startsubmsg(void *closure, const void *handler_data) {
+ upb_textprinter *p = closure;
+ const char *name = handler_data;
+ CHECK(indent(p));
+ putf(p, "%s {%c", name, p->single_line_ ? ' ' : '\n');
+ p->indent_depth_++;
+ return p;
+err:
+ return UPB_BREAK;
+}
+
+static bool textprinter_endsubmsg(void *closure, const void *handler_data) {
+ upb_textprinter *p = closure;
+ UPB_UNUSED(handler_data);
+ p->indent_depth_--;
+ CHECK(indent(p));
+ upb_bytessink_putbuf(p->output_, p->subc, "}", 1, NULL);
+ CHECK(endfield(p));
+ return true;
+err:
+ return false;
+}
+
+static void onmreg(const void *c, upb_handlers *h) {
+ const upb_msgdef *m = upb_handlers_msgdef(h);
+ upb_msg_field_iter i;
+ UPB_UNUSED(c);
+
+ upb_handlers_setstartmsg(h, textprinter_startmsg, NULL);
+ upb_handlers_setendmsg(h, textprinter_endmsg, NULL);
+
+ for(upb_msg_field_begin(&i, m);
+ !upb_msg_field_done(&i);
+ upb_msg_field_next(&i)) {
+ upb_fielddef *f = upb_msg_iter_field(&i);
+ upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
+ upb_handlerattr_sethandlerdata(&attr, f);
+ switch (upb_fielddef_type(f)) {
+ case UPB_TYPE_INT32:
+ upb_handlers_setint32(h, f, textprinter_putint32, &attr);
+ break;
+ case UPB_TYPE_INT64:
+ upb_handlers_setint64(h, f, textprinter_putint64, &attr);
+ break;
+ case UPB_TYPE_UINT32:
+ upb_handlers_setuint32(h, f, textprinter_putuint32, &attr);
+ break;
+ case UPB_TYPE_UINT64:
+ upb_handlers_setuint64(h, f, textprinter_putuint64, &attr);
+ break;
+ case UPB_TYPE_FLOAT:
+ upb_handlers_setfloat(h, f, textprinter_putfloat, &attr);
+ break;
+ case UPB_TYPE_DOUBLE:
+ upb_handlers_setdouble(h, f, textprinter_putdouble, &attr);
+ break;
+ case UPB_TYPE_BOOL:
+ upb_handlers_setbool(h, f, textprinter_putbool, &attr);
+ break;
+ case UPB_TYPE_STRING:
+ case UPB_TYPE_BYTES:
+ upb_handlers_setstartstr(h, f, textprinter_startstr, &attr);
+ upb_handlers_setstring(h, f, textprinter_putstr, &attr);
+ upb_handlers_setendstr(h, f, textprinter_endstr, &attr);
+ break;
+ case UPB_TYPE_MESSAGE: {
+ const char *name =
+ upb_fielddef_istagdelim(f)
+ ? shortname(upb_msgdef_fullname(upb_fielddef_msgsubdef(f)))
+ : upb_fielddef_name(f);
+ upb_handlerattr_sethandlerdata(&attr, name);
+ upb_handlers_setstartsubmsg(h, f, textprinter_startsubmsg, &attr);
+ upb_handlers_setendsubmsg(h, f, textprinter_endsubmsg, &attr);
+ break;
+ }
+ case UPB_TYPE_ENUM:
+ upb_handlers_setint32(h, f, textprinter_putenum, &attr);
+ break;
+ }
+ }
+}
+
+static void textprinter_reset(upb_textprinter *p, bool single_line) {
+ p->single_line_ = single_line;
+ p->indent_depth_ = 0;
+}
+
+
+/* Public API *****************************************************************/
+
+upb_textprinter *upb_textprinter_create(upb_env *env, const upb_handlers *h,
+ upb_bytessink *output) {
+ upb_textprinter *p = upb_env_malloc(env, sizeof(upb_textprinter));
+ if (!p) return NULL;
+
+ p->output_ = output;
+ upb_sink_reset(&p->input_, h, p);
+ textprinter_reset(p, false);
+
+ return p;
+}
+
+const upb_handlers *upb_textprinter_newhandlers(const upb_msgdef *m,
+ const void *owner) {
+ return upb_handlers_newfrozen(m, owner, &onmreg, NULL);
+}
+
+upb_sink *upb_textprinter_input(upb_textprinter *p) { return &p->input_; }
+
+void upb_textprinter_setsingleline(upb_textprinter *p, bool single_line) {
+ p->single_line_ = single_line;
+}
+
+
+/* Index is descriptor type. */
+const uint8_t upb_pb_native_wire_types[] = {
+ UPB_WIRE_TYPE_END_GROUP, /* ENDGROUP */
+ UPB_WIRE_TYPE_64BIT, /* DOUBLE */
+ UPB_WIRE_TYPE_32BIT, /* FLOAT */
+ UPB_WIRE_TYPE_VARINT, /* INT64 */
+ UPB_WIRE_TYPE_VARINT, /* UINT64 */
+ UPB_WIRE_TYPE_VARINT, /* INT32 */
+ UPB_WIRE_TYPE_64BIT, /* FIXED64 */
+ UPB_WIRE_TYPE_32BIT, /* FIXED32 */
+ UPB_WIRE_TYPE_VARINT, /* BOOL */
+ UPB_WIRE_TYPE_DELIMITED, /* STRING */
+ UPB_WIRE_TYPE_START_GROUP, /* GROUP */
+ UPB_WIRE_TYPE_DELIMITED, /* MESSAGE */
+ UPB_WIRE_TYPE_DELIMITED, /* BYTES */
+ UPB_WIRE_TYPE_VARINT, /* UINT32 */
+ UPB_WIRE_TYPE_VARINT, /* ENUM */
+ UPB_WIRE_TYPE_32BIT, /* SFIXED32 */
+ UPB_WIRE_TYPE_64BIT, /* SFIXED64 */
+ UPB_WIRE_TYPE_VARINT, /* SINT32 */
+ UPB_WIRE_TYPE_VARINT, /* SINT64 */
+};
+
+/* A basic branch-based decoder, uses 32-bit values to get good performance
+ * on 32-bit architectures (but performs well on 64-bits also).
+ * This scheme comes from the original Google Protobuf implementation
+ * (proto2). */
+upb_decoderet upb_vdecode_max8_branch32(upb_decoderet r) {
+ upb_decoderet err = {NULL, 0};
+ const char *p = r.p;
+ uint32_t low = (uint32_t)r.val;
+ uint32_t high = 0;
+ uint32_t b;
+ b = *(p++); low |= (b & 0x7fU) << 14; if (!(b & 0x80)) goto done;
+ b = *(p++); low |= (b & 0x7fU) << 21; if (!(b & 0x80)) goto done;
+ b = *(p++); low |= (b & 0x7fU) << 28;
+ high = (b & 0x7fU) >> 4; if (!(b & 0x80)) goto done;
+ b = *(p++); high |= (b & 0x7fU) << 3; if (!(b & 0x80)) goto done;
+ b = *(p++); high |= (b & 0x7fU) << 10; if (!(b & 0x80)) goto done;
+ b = *(p++); high |= (b & 0x7fU) << 17; if (!(b & 0x80)) goto done;
+ b = *(p++); high |= (b & 0x7fU) << 24; if (!(b & 0x80)) goto done;
+ b = *(p++); high |= (b & 0x7fU) << 31; if (!(b & 0x80)) goto done;
+ return err;
+
+done:
+ r.val = ((uint64_t)high << 32) | low;
+ r.p = p;
+ return r;
+}
+
+/* Like the previous, but uses 64-bit values. */
+upb_decoderet upb_vdecode_max8_branch64(upb_decoderet r) {
+ const char *p = r.p;
+ uint64_t val = r.val;
+ uint64_t b;
+ upb_decoderet err = {NULL, 0};
+ b = *(p++); val |= (b & 0x7fU) << 14; if (!(b & 0x80)) goto done;
+ b = *(p++); val |= (b & 0x7fU) << 21; if (!(b & 0x80)) goto done;
+ b = *(p++); val |= (b & 0x7fU) << 28; if (!(b & 0x80)) goto done;
+ b = *(p++); val |= (b & 0x7fU) << 35; if (!(b & 0x80)) goto done;
+ b = *(p++); val |= (b & 0x7fU) << 42; if (!(b & 0x80)) goto done;
+ b = *(p++); val |= (b & 0x7fU) << 49; if (!(b & 0x80)) goto done;
+ b = *(p++); val |= (b & 0x7fU) << 56; if (!(b & 0x80)) goto done;
+ b = *(p++); val |= (b & 0x7fU) << 63; if (!(b & 0x80)) goto done;
+ return err;
+
+done:
+ r.val = val;
+ r.p = p;
+ return r;
+}
+
+/* Given an encoded varint v, returns an integer with a single bit set that
+ * indicates the end of the varint. Subtracting one from this value will
+ * yield a mask that leaves only bits that are part of the varint. Returns
+ * 0 if the varint is unterminated. */
+static uint64_t upb_get_vstopbit(uint64_t v) {
+ uint64_t cbits = v | 0x7f7f7f7f7f7f7f7fULL;
+ return ~cbits & (cbits+1);
+}
+
+/* A branchless decoder. Credit to Pascal Massimino for the bit-twiddling. */
+upb_decoderet upb_vdecode_max8_massimino(upb_decoderet r) {
+ uint64_t b;
+ uint64_t stop_bit;
+ upb_decoderet my_r;
+ memcpy(&b, r.p, sizeof(b));
+ stop_bit = upb_get_vstopbit(b);
+ b = (b & 0x7f7f7f7f7f7f7f7fULL) & (stop_bit - 1);
+ b += b & 0x007f007f007f007fULL;
+ b += 3 * (b & 0x0000ffff0000ffffULL);
+ b += 15 * (b & 0x00000000ffffffffULL);
+ if (stop_bit == 0) {
+ /* Error: unterminated varint. */
+ upb_decoderet err_r = {(void*)0, 0};
+ return err_r;
+ }
+ my_r = upb_decoderet_make(r.p + ((__builtin_ctzll(stop_bit) + 1) / 8),
+ r.val | (b << 7));
+ return my_r;
+}
+
+/* A branchless decoder. Credit to Daniel Wright for the bit-twiddling. */
+upb_decoderet upb_vdecode_max8_wright(upb_decoderet r) {
+ uint64_t b;
+ uint64_t stop_bit;
+ upb_decoderet my_r;
+ memcpy(&b, r.p, sizeof(b));
+ stop_bit = upb_get_vstopbit(b);
+ b &= (stop_bit - 1);
+ b = ((b & 0x7f007f007f007f00ULL) >> 1) | (b & 0x007f007f007f007fULL);
+ b = ((b & 0xffff0000ffff0000ULL) >> 2) | (b & 0x0000ffff0000ffffULL);
+ b = ((b & 0xffffffff00000000ULL) >> 4) | (b & 0x00000000ffffffffULL);
+ if (stop_bit == 0) {
+ /* Error: unterminated varint. */
+ upb_decoderet err_r = {(void*)0, 0};
+ return err_r;
+ }
+ my_r = upb_decoderet_make(r.p + ((__builtin_ctzll(stop_bit) + 1) / 8),
+ r.val | (b << 14));
+ return my_r;
+}
+
+#line 1 "upb/json/parser.rl"
+/*
+** upb::json::Parser (upb_json_parser)
+**
+** A parser that uses the Ragel State Machine Compiler to generate
+** the finite automata.
+**
+** Ragel only natively handles regular languages, but we can manually
+** program it a bit to handle context-free languages like JSON, by using
+** the "fcall" and "fret" constructs.
+**
+** This parser can handle the basics, but needs several things to be fleshed
+** out:
+**
+** - handling of unicode escape sequences (including high surrogate pairs).
+** - properly check and report errors for unknown fields, stack overflow,
+** improper array nesting (or lack of nesting).
+** - handling of base64 sequences with padding characters.
+** - handling of push-back (non-success returns from sink functions).
+** - handling of keys/escape-sequences/etc that span input buffers.
+*/
+
+#include <stdio.h>
+#include <stdint.h>
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+
+
+#define UPB_JSON_MAX_DEPTH 64
+
+typedef struct {
+ upb_sink sink;
+
+ /* The current message in which we're parsing, and the field whose value we're
+ * expecting next. */
+ const upb_msgdef *m;
+ const upb_fielddef *f;
+
+ /* We are in a repeated-field context, ready to emit mapentries as
+ * submessages. This flag alters the start-of-object (open-brace) behavior to
+ * begin a sequence of mapentry messages rather than a single submessage. */
+ bool is_map;
+
+ /* We are in a map-entry message context. This flag is set when parsing the
+ * value field of a single map entry and indicates to all value-field parsers
+ * (subobjects, strings, numbers, and bools) that the map-entry submessage
+ * should end as soon as the value is parsed. */
+ bool is_mapentry;
+
+ /* If |is_map| or |is_mapentry| is true, |mapfield| refers to the parent
+ * message's map field that we're currently parsing. This differs from |f|
+ * because |f| is the field in the *current* message (i.e., the map-entry
+ * message itself), not the parent's field that leads to this map. */
+ const upb_fielddef *mapfield;
+} upb_jsonparser_frame;
+
+struct upb_json_parser {
+ upb_env *env;
+ upb_byteshandler input_handler_;
+ upb_bytessink input_;
+
+ /* Stack to track the JSON scopes we are in. */
+ upb_jsonparser_frame stack[UPB_JSON_MAX_DEPTH];
+ upb_jsonparser_frame *top;
+ upb_jsonparser_frame *limit;
+
+ upb_status status;
+
+ /* Ragel's internal parsing stack for the parsing state machine. */
+ int current_state;
+ int parser_stack[UPB_JSON_MAX_DEPTH];
+ int parser_top;
+
+ /* The handle for the current buffer. */
+ const upb_bufhandle *handle;
+
+ /* Accumulate buffer. See details in parser.rl. */
+ const char *accumulated;
+ size_t accumulated_len;
+ char *accumulate_buf;
+ size_t accumulate_buf_size;
+
+ /* Multi-part text data. See details in parser.rl. */
+ int multipart_state;
+ upb_selector_t string_selector;
+
+ /* Input capture. See details in parser.rl. */
+ const char *capture;
+
+ /* Intermediate result of parsing a unicode escape sequence. */
+ uint32_t digit;
+};
+
+#define PARSER_CHECK_RETURN(x) if (!(x)) return false
+
+/* Used to signal that a capture has been suspended. */
+static char suspend_capture;
+
+static upb_selector_t getsel_for_handlertype(upb_json_parser *p,
+ upb_handlertype_t type) {
+ upb_selector_t sel;
+ bool ok = upb_handlers_getselector(p->top->f, type, &sel);
+ UPB_ASSERT_VAR(ok, ok);
+ return sel;
+}
+
+static upb_selector_t parser_getsel(upb_json_parser *p) {
+ return getsel_for_handlertype(
+ p, upb_handlers_getprimitivehandlertype(p->top->f));
+}
+
+static bool check_stack(upb_json_parser *p) {
+ if ((p->top + 1) == p->limit) {
+ upb_status_seterrmsg(&p->status, "Nesting too deep");
+ upb_env_reporterror(p->env, &p->status);
+ return false;
+ }
+
+ return true;
+}
+
+/* There are GCC/Clang built-ins for overflow checking which we could start
+ * using if there was any performance benefit to it. */
+
+static bool checked_add(size_t a, size_t b, size_t *c) {
+ if (SIZE_MAX - a < b) return false;
+ *c = a + b;
+ return true;
+}
+
+static size_t saturating_multiply(size_t a, size_t b) {
+ /* size_t is unsigned, so this is defined behavior even on overflow. */
+ size_t ret = a * b;
+ if (b != 0 && ret / b != a) {
+ ret = SIZE_MAX;
+ }
+ return ret;
+}
+
+
+/* Base64 decoding ************************************************************/
+
+/* TODO(haberman): make this streaming. */
+
+static const signed char b64table[] = {
+ -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, 62/*+*/, -1, -1, -1, 63/*/ */,
+ 52/*0*/, 53/*1*/, 54/*2*/, 55/*3*/, 56/*4*/, 57/*5*/, 58/*6*/, 59/*7*/,
+ 60/*8*/, 61/*9*/, -1, -1, -1, -1, -1, -1,
+ -1, 0/*A*/, 1/*B*/, 2/*C*/, 3/*D*/, 4/*E*/, 5/*F*/, 6/*G*/,
+ 07/*H*/, 8/*I*/, 9/*J*/, 10/*K*/, 11/*L*/, 12/*M*/, 13/*N*/, 14/*O*/,
+ 15/*P*/, 16/*Q*/, 17/*R*/, 18/*S*/, 19/*T*/, 20/*U*/, 21/*V*/, 22/*W*/,
+ 23/*X*/, 24/*Y*/, 25/*Z*/, -1, -1, -1, -1, -1,
+ -1, 26/*a*/, 27/*b*/, 28/*c*/, 29/*d*/, 30/*e*/, 31/*f*/, 32/*g*/,
+ 33/*h*/, 34/*i*/, 35/*j*/, 36/*k*/, 37/*l*/, 38/*m*/, 39/*n*/, 40/*o*/,
+ 41/*p*/, 42/*q*/, 43/*r*/, 44/*s*/, 45/*t*/, 46/*u*/, 47/*v*/, 48/*w*/,
+ 49/*x*/, 50/*y*/, 51/*z*/, -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, -1, -1, -1, -1, -1
+};
+
+/* Returns the table value sign-extended to 32 bits. Knowing that the upper
+ * bits will be 1 for unrecognized characters makes it easier to check for
+ * this error condition later (see below). */
+int32_t b64lookup(unsigned char ch) { return b64table[ch]; }
+
+/* Returns true if the given character is not a valid base64 character or
+ * padding. */
+bool nonbase64(unsigned char ch) { return b64lookup(ch) == -1 && ch != '='; }
+
+static bool base64_push(upb_json_parser *p, upb_selector_t sel, const char *ptr,
+ size_t len) {
+ const char *limit = ptr + len;
+ for (; ptr < limit; ptr += 4) {
+ uint32_t val;
+ char output[3];
+
+ if (limit - ptr < 4) {
+ upb_status_seterrf(&p->status,
+ "Base64 input for bytes field not a multiple of 4: %s",
+ upb_fielddef_name(p->top->f));
+ upb_env_reporterror(p->env, &p->status);
+ return false;
+ }
+
+ val = b64lookup(ptr[0]) << 18 |
+ b64lookup(ptr[1]) << 12 |
+ b64lookup(ptr[2]) << 6 |
+ b64lookup(ptr[3]);
+
+ /* Test the upper bit; returns true if any of the characters returned -1. */
+ if (val & 0x80000000) {
+ goto otherchar;
+ }
+
+ output[0] = val >> 16;
+ output[1] = (val >> 8) & 0xff;
+ output[2] = val & 0xff;
+ upb_sink_putstring(&p->top->sink, sel, output, 3, NULL);
+ }
+ return true;
+
+otherchar:
+ if (nonbase64(ptr[0]) || nonbase64(ptr[1]) || nonbase64(ptr[2]) ||
+ nonbase64(ptr[3]) ) {
+ upb_status_seterrf(&p->status,
+ "Non-base64 characters in bytes field: %s",
+ upb_fielddef_name(p->top->f));
+ upb_env_reporterror(p->env, &p->status);
+ return false;
+ } if (ptr[2] == '=') {
+ uint32_t val;
+ char output;
+
+ /* Last group contains only two input bytes, one output byte. */
+ if (ptr[0] == '=' || ptr[1] == '=' || ptr[3] != '=') {
+ goto badpadding;
+ }
+
+ val = b64lookup(ptr[0]) << 18 |
+ b64lookup(ptr[1]) << 12;
+
+ assert(!(val & 0x80000000));
+ output = val >> 16;
+ upb_sink_putstring(&p->top->sink, sel, &output, 1, NULL);
+ return true;
+ } else {
+ uint32_t val;
+ char output[2];
+
+ /* Last group contains only three input bytes, two output bytes. */
+ if (ptr[0] == '=' || ptr[1] == '=' || ptr[2] == '=') {
+ goto badpadding;
+ }
+
+ val = b64lookup(ptr[0]) << 18 |
+ b64lookup(ptr[1]) << 12 |
+ b64lookup(ptr[2]) << 6;
+
+ output[0] = val >> 16;
+ output[1] = (val >> 8) & 0xff;
+ upb_sink_putstring(&p->top->sink, sel, output, 2, NULL);
+ return true;
+ }
+
+badpadding:
+ upb_status_seterrf(&p->status,
+ "Incorrect base64 padding for field: %s (%.*s)",
+ upb_fielddef_name(p->top->f),
+ 4, ptr);
+ upb_env_reporterror(p->env, &p->status);
+ return false;
+}
+
+
+/* Accumulate buffer **********************************************************/
+
+/* Functionality for accumulating a buffer.
+ *
+ * Some parts of the parser need an entire value as a contiguous string. For
+ * example, to look up a member name in a hash table, or to turn a string into
+ * a number, the relevant library routines need the input string to be in
+ * contiguous memory, even if the value spanned two or more buffers in the
+ * input. These routines handle that.
+ *
+ * In the common case we can just point to the input buffer to get this
+ * contiguous string and avoid any actual copy. So we optimistically begin
+ * this way. But there are a few cases where we must instead copy into a
+ * separate buffer:
+ *
+ * 1. The string was not contiguous in the input (it spanned buffers).
+ *
+ * 2. The string included escape sequences that need to be interpreted to get
+ * the true value in a contiguous buffer. */
+
+static void assert_accumulate_empty(upb_json_parser *p) {
+ UPB_UNUSED(p);
+ assert(p->accumulated == NULL);
+ assert(p->accumulated_len == 0);
+}
+
+static void accumulate_clear(upb_json_parser *p) {
+ p->accumulated = NULL;
+ p->accumulated_len = 0;
+}
+
+/* Used internally by accumulate_append(). */
+static bool accumulate_realloc(upb_json_parser *p, size_t need) {
+ void *mem;
+ size_t old_size = p->accumulate_buf_size;
+ size_t new_size = UPB_MAX(old_size, 128);
+ while (new_size < need) {
+ new_size = saturating_multiply(new_size, 2);
+ }
+
+ mem = upb_env_realloc(p->env, p->accumulate_buf, old_size, new_size);
+ if (!mem) {
+ upb_status_seterrmsg(&p->status, "Out of memory allocating buffer.");
+ upb_env_reporterror(p->env, &p->status);
+ return false;
+ }
+
+ p->accumulate_buf = mem;
+ p->accumulate_buf_size = new_size;
+ return true;
+}
+
+/* Logically appends the given data to the append buffer.
+ * If "can_alias" is true, we will try to avoid actually copying, but the buffer
+ * must be valid until the next accumulate_append() call (if any). */
+static bool accumulate_append(upb_json_parser *p, const char *buf, size_t len,
+ bool can_alias) {
+ size_t need;
+
+ if (!p->accumulated && can_alias) {
+ p->accumulated = buf;
+ p->accumulated_len = len;
+ return true;
+ }
+
+ if (!checked_add(p->accumulated_len, len, &need)) {
+ upb_status_seterrmsg(&p->status, "Integer overflow.");
+ upb_env_reporterror(p->env, &p->status);
+ return false;
+ }
+
+ if (need > p->accumulate_buf_size && !accumulate_realloc(p, need)) {
+ return false;
+ }
+
+ if (p->accumulated != p->accumulate_buf) {
+ memcpy(p->accumulate_buf, p->accumulated, p->accumulated_len);
+ p->accumulated = p->accumulate_buf;
+ }
+
+ memcpy(p->accumulate_buf + p->accumulated_len, buf, len);
+ p->accumulated_len += len;
+ return true;
+}
+
+/* Returns a pointer to the data accumulated since the last accumulate_clear()
+ * call, and writes the length to *len. This with point either to the input
+ * buffer or a temporary accumulate buffer. */
+static const char *accumulate_getptr(upb_json_parser *p, size_t *len) {
+ assert(p->accumulated);
+ *len = p->accumulated_len;
+ return p->accumulated;
+}
+
+
+/* Mult-part text data ********************************************************/
+
+/* When we have text data in the input, it can often come in multiple segments.
+ * For example, there may be some raw string data followed by an escape
+ * sequence. The two segments are processed with different logic. Also buffer
+ * seams in the input can cause multiple segments.
+ *
+ * As we see segments, there are two main cases for how we want to process them:
+ *
+ * 1. we want to push the captured input directly to string handlers.
+ *
+ * 2. we need to accumulate all the parts into a contiguous buffer for further
+ * processing (field name lookup, string->number conversion, etc). */
+
+/* This is the set of states for p->multipart_state. */
+enum {
+ /* We are not currently processing multipart data. */
+ MULTIPART_INACTIVE = 0,
+
+ /* We are processing multipart data by accumulating it into a contiguous
+ * buffer. */
+ MULTIPART_ACCUMULATE = 1,
+
+ /* We are processing multipart data by pushing each part directly to the
+ * current string handlers. */
+ MULTIPART_PUSHEAGERLY = 2
+};
+
+/* Start a multi-part text value where we accumulate the data for processing at
+ * the end. */
+static void multipart_startaccum(upb_json_parser *p) {
+ assert_accumulate_empty(p);
+ assert(p->multipart_state == MULTIPART_INACTIVE);
+ p->multipart_state = MULTIPART_ACCUMULATE;
+}
+
+/* Start a multi-part text value where we immediately push text data to a string
+ * value with the given selector. */
+static void multipart_start(upb_json_parser *p, upb_selector_t sel) {
+ assert_accumulate_empty(p);
+ assert(p->multipart_state == MULTIPART_INACTIVE);
+ p->multipart_state = MULTIPART_PUSHEAGERLY;
+ p->string_selector = sel;
+}
+
+static bool multipart_text(upb_json_parser *p, const char *buf, size_t len,
+ bool can_alias) {
+ switch (p->multipart_state) {
+ case MULTIPART_INACTIVE:
+ upb_status_seterrmsg(
+ &p->status, "Internal error: unexpected state MULTIPART_INACTIVE");
+ upb_env_reporterror(p->env, &p->status);
+ return false;
+
+ case MULTIPART_ACCUMULATE:
+ if (!accumulate_append(p, buf, len, can_alias)) {
+ return false;
+ }
+ break;
+
+ case MULTIPART_PUSHEAGERLY: {
+ const upb_bufhandle *handle = can_alias ? p->handle : NULL;
+ upb_sink_putstring(&p->top->sink, p->string_selector, buf, len, handle);
+ break;
+ }
+ }
+
+ return true;
+}
+
+/* Note: this invalidates the accumulate buffer! Call only after reading its
+ * contents. */
+static void multipart_end(upb_json_parser *p) {
+ assert(p->multipart_state != MULTIPART_INACTIVE);
+ p->multipart_state = MULTIPART_INACTIVE;
+ accumulate_clear(p);
+}
+
+
+/* Input capture **************************************************************/
+
+/* Functionality for capturing a region of the input as text. Gracefully
+ * handles the case where a buffer seam occurs in the middle of the captured
+ * region. */
+
+static void capture_begin(upb_json_parser *p, const char *ptr) {
+ assert(p->multipart_state != MULTIPART_INACTIVE);
+ assert(p->capture == NULL);
+ p->capture = ptr;
+}
+
+static bool capture_end(upb_json_parser *p, const char *ptr) {
+ assert(p->capture);
+ if (multipart_text(p, p->capture, ptr - p->capture, true)) {
+ p->capture = NULL;
+ return true;
+ } else {
+ return false;
+ }
+}
+
+/* This is called at the end of each input buffer (ie. when we have hit a
+ * buffer seam). If we are in the middle of capturing the input, this
+ * processes the unprocessed capture region. */
+static void capture_suspend(upb_json_parser *p, const char **ptr) {
+ if (!p->capture) return;
+
+ if (multipart_text(p, p->capture, *ptr - p->capture, false)) {
+ /* We use this as a signal that we were in the middle of capturing, and
+ * that capturing should resume at the beginning of the next buffer.
+ *
+ * We can't use *ptr here, because we have no guarantee that this pointer
+ * will be valid when we resume (if the underlying memory is freed, then
+ * using the pointer at all, even to compare to NULL, is likely undefined
+ * behavior). */
+ p->capture = &suspend_capture;
+ } else {
+ /* Need to back up the pointer to the beginning of the capture, since
+ * we were not able to actually preserve it. */
+ *ptr = p->capture;
+ }
+}
+
+static void capture_resume(upb_json_parser *p, const char *ptr) {
+ if (p->capture) {
+ assert(p->capture == &suspend_capture);
+ p->capture = ptr;
+ }
+}
+
+
+/* Callbacks from the parser **************************************************/
+
+/* These are the functions called directly from the parser itself.
+ * We define these in the same order as their declarations in the parser. */
+
+static char escape_char(char in) {
+ switch (in) {
+ case 'r': return '\r';
+ case 't': return '\t';
+ case 'n': return '\n';
+ case 'f': return '\f';
+ case 'b': return '\b';
+ case '/': return '/';
+ case '"': return '"';
+ case '\\': return '\\';
+ default:
+ assert(0);
+ return 'x';
+ }
+}
+
+static bool escape(upb_json_parser *p, const char *ptr) {
+ char ch = escape_char(*ptr);
+ return multipart_text(p, &ch, 1, false);
+}
+
+static void start_hex(upb_json_parser *p) {
+ p->digit = 0;
+}
+
+static void hexdigit(upb_json_parser *p, const char *ptr) {
+ char ch = *ptr;
+
+ p->digit <<= 4;
+
+ if (ch >= '0' && ch <= '9') {
+ p->digit += (ch - '0');
+ } else if (ch >= 'a' && ch <= 'f') {
+ p->digit += ((ch - 'a') + 10);
+ } else {
+ assert(ch >= 'A' && ch <= 'F');
+ p->digit += ((ch - 'A') + 10);
+ }
+}
+
+static bool end_hex(upb_json_parser *p) {
+ uint32_t codepoint = p->digit;
+
+ /* emit the codepoint as UTF-8. */
+ char utf8[3]; /* support \u0000 -- \uFFFF -- need only three bytes. */
+ int length = 0;
+ if (codepoint <= 0x7F) {
+ utf8[0] = codepoint;
+ length = 1;
+ } else if (codepoint <= 0x07FF) {
+ utf8[1] = (codepoint & 0x3F) | 0x80;
+ codepoint >>= 6;
+ utf8[0] = (codepoint & 0x1F) | 0xC0;
+ length = 2;
+ } else /* codepoint <= 0xFFFF */ {
+ utf8[2] = (codepoint & 0x3F) | 0x80;
+ codepoint >>= 6;
+ utf8[1] = (codepoint & 0x3F) | 0x80;
+ codepoint >>= 6;
+ utf8[0] = (codepoint & 0x0F) | 0xE0;
+ length = 3;
+ }
+ /* TODO(haberman): Handle high surrogates: if codepoint is a high surrogate
+ * we have to wait for the next escape to get the full code point). */
+
+ return multipart_text(p, utf8, length, false);
+}
+
+static void start_text(upb_json_parser *p, const char *ptr) {
+ capture_begin(p, ptr);
+}
+
+static bool end_text(upb_json_parser *p, const char *ptr) {
+ return capture_end(p, ptr);
+}
+
+static void start_number(upb_json_parser *p, const char *ptr) {
+ multipart_startaccum(p);
+ capture_begin(p, ptr);
+}
+
+static bool parse_number(upb_json_parser *p);
+
+static bool end_number(upb_json_parser *p, const char *ptr) {
+ if (!capture_end(p, ptr)) {
+ return false;
+ }
+
+ return parse_number(p);
+}
+
+static bool parse_number(upb_json_parser *p) {
+ size_t len;
+ const char *buf;
+ const char *myend;
+ char *end;
+
+ /* strtol() and friends unfortunately do not support specifying the length of
+ * the input string, so we need to force a copy into a NULL-terminated buffer. */
+ if (!multipart_text(p, "\0", 1, false)) {
+ return false;
+ }
+
+ buf = accumulate_getptr(p, &len);
+ myend = buf + len - 1; /* One for NULL. */
+
+ /* XXX: We are using strtol to parse integers, but this is wrong as even
+ * integers can be represented as 1e6 (for example), which strtol can't
+ * handle correctly.
+ *
+ * XXX: Also, we can't handle large integers properly because strto[u]ll
+ * isn't in C89.
+ *
+ * XXX: Also, we don't properly check floats for overflow, since strtof
+ * isn't in C89. */
+ switch (upb_fielddef_type(p->top->f)) {
+ case UPB_TYPE_ENUM:
+ case UPB_TYPE_INT32: {
+ long val = strtol(p->accumulated, &end, 0);
+ if (val > INT32_MAX || val < INT32_MIN || errno == ERANGE || end != myend)
+ goto err;
+ else
+ upb_sink_putint32(&p->top->sink, parser_getsel(p), val);
+ break;
+ }
+ case UPB_TYPE_INT64: {
+ long long val = strtol(p->accumulated, &end, 0);
+ if (val > INT64_MAX || val < INT64_MIN || errno == ERANGE || end != myend)
+ goto err;
+ else
+ upb_sink_putint64(&p->top->sink, parser_getsel(p), val);
+ break;
+ }
+ case UPB_TYPE_UINT32: {
+ unsigned long val = strtoul(p->accumulated, &end, 0);
+ if (val > UINT32_MAX || errno == ERANGE || end != myend)
+ goto err;
+ else
+ upb_sink_putuint32(&p->top->sink, parser_getsel(p), val);
+ break;
+ }
+ case UPB_TYPE_UINT64: {
+ unsigned long long val = strtoul(p->accumulated, &end, 0);
+ if (val > UINT64_MAX || errno == ERANGE || end != myend)
+ goto err;
+ else
+ upb_sink_putuint64(&p->top->sink, parser_getsel(p), val);
+ break;
+ }
+ case UPB_TYPE_DOUBLE: {
+ double val = strtod(p->accumulated, &end);
+ if (errno == ERANGE || end != myend)
+ goto err;
+ else
+ upb_sink_putdouble(&p->top->sink, parser_getsel(p), val);
+ break;
+ }
+ case UPB_TYPE_FLOAT: {
+ float val = strtod(p->accumulated, &end);
+ if (errno == ERANGE || end != myend)
+ goto err;
+ else
+ upb_sink_putfloat(&p->top->sink, parser_getsel(p), val);
+ break;
+ }
+ default:
+ assert(false);
+ }
+
+ multipart_end(p);
+
+ return true;
+
+err:
+ upb_status_seterrf(&p->status, "error parsing number: %s", buf);
+ upb_env_reporterror(p->env, &p->status);
+ multipart_end(p);
+ return false;
+}
+
+static bool parser_putbool(upb_json_parser *p, bool val) {
+ bool ok;
+
+ if (upb_fielddef_type(p->top->f) != UPB_TYPE_BOOL) {
+ upb_status_seterrf(&p->status,
+ "Boolean value specified for non-bool field: %s",
+ upb_fielddef_name(p->top->f));
+ upb_env_reporterror(p->env, &p->status);
+ return false;
+ }
+
+ ok = upb_sink_putbool(&p->top->sink, parser_getsel(p), val);
+ UPB_ASSERT_VAR(ok, ok);
+
+ return true;
+}
+
+static bool start_stringval(upb_json_parser *p) {
+ assert(p->top->f);
+
+ if (upb_fielddef_isstring(p->top->f)) {
+ upb_jsonparser_frame *inner;
+ upb_selector_t sel;
+
+ if (!check_stack(p)) return false;
+
+ /* Start a new parser frame: parser frames correspond one-to-one with
+ * handler frames, and string events occur in a sub-frame. */
+ inner = p->top + 1;
+ sel = getsel_for_handlertype(p, UPB_HANDLER_STARTSTR);
+ upb_sink_startstr(&p->top->sink, sel, 0, &inner->sink);
+ inner->m = p->top->m;
+ inner->f = p->top->f;
+ inner->is_map = false;
+ inner->is_mapentry = false;
+ p->top = inner;
+
+ if (upb_fielddef_type(p->top->f) == UPB_TYPE_STRING) {
+ /* For STRING fields we push data directly to the handlers as it is
+ * parsed. We don't do this yet for BYTES fields, because our base64
+ * decoder is not streaming.
+ *
+ * TODO(haberman): make base64 decoding streaming also. */
+ multipart_start(p, getsel_for_handlertype(p, UPB_HANDLER_STRING));
+ return true;
+ } else {
+ multipart_startaccum(p);
+ return true;
+ }
+ } else if (upb_fielddef_type(p->top->f) == UPB_TYPE_ENUM) {
+ /* No need to push a frame -- symbolic enum names in quotes remain in the
+ * current parser frame.
+ *
+ * Enum string values must accumulate so we can look up the value in a table
+ * once it is complete. */
+ multipart_startaccum(p);
+ return true;
+ } else {
+ upb_status_seterrf(&p->status,
+ "String specified for non-string/non-enum field: %s",
+ upb_fielddef_name(p->top->f));
+ upb_env_reporterror(p->env, &p->status);
+ return false;
+ }
+}
+
+static bool end_stringval(upb_json_parser *p) {
+ bool ok = true;
+
+ switch (upb_fielddef_type(p->top->f)) {
+ case UPB_TYPE_BYTES:
+ if (!base64_push(p, getsel_for_handlertype(p, UPB_HANDLER_STRING),
+ p->accumulated, p->accumulated_len)) {
+ return false;
+ }
+ /* Fall through. */
+
+ case UPB_TYPE_STRING: {
+ upb_selector_t sel = getsel_for_handlertype(p, UPB_HANDLER_ENDSTR);
+ upb_sink_endstr(&p->top->sink, sel);
+ p->top--;
+ break;
+ }
+
+ case UPB_TYPE_ENUM: {
+ /* Resolve enum symbolic name to integer value. */
+ const upb_enumdef *enumdef =
+ (const upb_enumdef*)upb_fielddef_subdef(p->top->f);
+
+ size_t len;
+ const char *buf = accumulate_getptr(p, &len);
+
+ int32_t int_val = 0;
+ ok = upb_enumdef_ntoi(enumdef, buf, len, &int_val);
+
+ if (ok) {
+ upb_selector_t sel = parser_getsel(p);
+ upb_sink_putint32(&p->top->sink, sel, int_val);
+ } else {
+ upb_status_seterrf(&p->status, "Enum value unknown: '%.*s'", len, buf);
+ upb_env_reporterror(p->env, &p->status);
+ }
+
+ break;
+ }
+
+ default:
+ assert(false);
+ upb_status_seterrmsg(&p->status, "Internal error in JSON decoder");
+ upb_env_reporterror(p->env, &p->status);
+ ok = false;
+ break;
+ }
+
+ multipart_end(p);
+
+ return ok;
+}
+
+static void start_member(upb_json_parser *p) {
+ assert(!p->top->f);
+ multipart_startaccum(p);
+}
+
+/* Helper: invoked during parse_mapentry() to emit the mapentry message's key
+ * field based on the current contents of the accumulate buffer. */
+static bool parse_mapentry_key(upb_json_parser *p) {
+
+ size_t len;
+ const char *buf = accumulate_getptr(p, &len);
+
+ /* Emit the key field. We do a bit of ad-hoc parsing here because the
+ * parser state machine has already decided that this is a string field
+ * name, and we are reinterpreting it as some arbitrary key type. In
+ * particular, integer and bool keys are quoted, so we need to parse the
+ * quoted string contents here. */
+
+ p->top->f = upb_msgdef_itof(p->top->m, UPB_MAPENTRY_KEY);
+ if (p->top->f == NULL) {
+ upb_status_seterrmsg(&p->status, "mapentry message has no key");
+ upb_env_reporterror(p->env, &p->status);
+ return false;
+ }
+ switch (upb_fielddef_type(p->top->f)) {
+ case UPB_TYPE_INT32:
+ case UPB_TYPE_INT64:
+ case UPB_TYPE_UINT32:
+ case UPB_TYPE_UINT64:
+ /* Invoke end_number. The accum buffer has the number's text already. */
+ if (!parse_number(p)) {
+ return false;
+ }
+ break;
+ case UPB_TYPE_BOOL:
+ if (len == 4 && !strncmp(buf, "true", 4)) {
+ if (!parser_putbool(p, true)) {
+ return false;
+ }
+ } else if (len == 5 && !strncmp(buf, "false", 5)) {
+ if (!parser_putbool(p, false)) {
+ return false;
+ }
+ } else {
+ upb_status_seterrmsg(&p->status,
+ "Map bool key not 'true' or 'false'");
+ upb_env_reporterror(p->env, &p->status);
+ return false;
+ }
+ multipart_end(p);
+ break;
+ case UPB_TYPE_STRING:
+ case UPB_TYPE_BYTES: {
+ upb_sink subsink;
+ upb_selector_t sel = getsel_for_handlertype(p, UPB_HANDLER_STARTSTR);
+ upb_sink_startstr(&p->top->sink, sel, len, &subsink);
+ sel = getsel_for_handlertype(p, UPB_HANDLER_STRING);
+ upb_sink_putstring(&subsink, sel, buf, len, NULL);
+ sel = getsel_for_handlertype(p, UPB_HANDLER_ENDSTR);
+ upb_sink_endstr(&subsink, sel);
+ multipart_end(p);
+ break;
+ }
+ default:
+ upb_status_seterrmsg(&p->status, "Invalid field type for map key");
+ upb_env_reporterror(p->env, &p->status);
+ return false;
+ }
+
+ return true;
+}
+
+/* Helper: emit one map entry (as a submessage in the map field sequence). This
+ * is invoked from end_membername(), at the end of the map entry's key string,
+ * with the map key in the accumulate buffer. It parses the key from that
+ * buffer, emits the handler calls to start the mapentry submessage (setting up
+ * its subframe in the process), and sets up state in the subframe so that the
+ * value parser (invoked next) will emit the mapentry's value field and then
+ * end the mapentry message. */
+
+static bool handle_mapentry(upb_json_parser *p) {
+ const upb_fielddef *mapfield;
+ const upb_msgdef *mapentrymsg;
+ upb_jsonparser_frame *inner;
+ upb_selector_t sel;
+
+ /* Map entry: p->top->sink is the seq frame, so we need to start a frame
+ * for the mapentry itself, and then set |f| in that frame so that the map
+ * value field is parsed, and also set a flag to end the frame after the
+ * map-entry value is parsed. */
+ if (!check_stack(p)) return false;
+
+ mapfield = p->top->mapfield;
+ mapentrymsg = upb_fielddef_msgsubdef(mapfield);
+
+ inner = p->top + 1;
+ p->top->f = mapfield;
+ sel = getsel_for_handlertype(p, UPB_HANDLER_STARTSUBMSG);
+ upb_sink_startsubmsg(&p->top->sink, sel, &inner->sink);
+ inner->m = mapentrymsg;
+ inner->mapfield = mapfield;
+ inner->is_map = false;
+
+ /* Don't set this to true *yet* -- we reuse parsing handlers below to push
+ * the key field value to the sink, and these handlers will pop the frame
+ * if they see is_mapentry (when invoked by the parser state machine, they
+ * would have just seen the map-entry value, not key). */
+ inner->is_mapentry = false;
+ p->top = inner;
+
+ /* send STARTMSG in submsg frame. */
+ upb_sink_startmsg(&p->top->sink);
+
+ parse_mapentry_key(p);
+
+ /* Set up the value field to receive the map-entry value. */
+ p->top->f = upb_msgdef_itof(p->top->m, UPB_MAPENTRY_VALUE);
+ p->top->is_mapentry = true; /* set up to pop frame after value is parsed. */
+ p->top->mapfield = mapfield;
+ if (p->top->f == NULL) {
+ upb_status_seterrmsg(&p->status, "mapentry message has no value");
+ upb_env_reporterror(p->env, &p->status);
+ return false;
+ }
+
+ return true;
+}
+
+static bool end_membername(upb_json_parser *p) {
+ assert(!p->top->f);
+
+ if (p->top->is_map) {
+ return handle_mapentry(p);
+ } else {
+ size_t len;
+ const char *buf = accumulate_getptr(p, &len);
+ const upb_fielddef *f = upb_msgdef_ntof(p->top->m, buf, len);
+
+ if (!f) {
+ /* TODO(haberman): Ignore unknown fields if requested/configured to do
+ * so. */
+ upb_status_seterrf(&p->status, "No such field: %.*s\n", (int)len, buf);
+ upb_env_reporterror(p->env, &p->status);
+ return false;
+ }
+
+ p->top->f = f;
+ multipart_end(p);
+
+ return true;
+ }
+}
+
+static void end_member(upb_json_parser *p) {
+ /* If we just parsed a map-entry value, end that frame too. */
+ if (p->top->is_mapentry) {
+ upb_status s = UPB_STATUS_INIT;
+ upb_selector_t sel;
+ bool ok;
+ const upb_fielddef *mapfield;
+
+ assert(p->top > p->stack);
+ /* send ENDMSG on submsg. */
+ upb_sink_endmsg(&p->top->sink, &s);
+ mapfield = p->top->mapfield;
+
+ /* send ENDSUBMSG in repeated-field-of-mapentries frame. */
+ p->top--;
+ ok = upb_handlers_getselector(mapfield, UPB_HANDLER_ENDSUBMSG, &sel);
+ UPB_ASSERT_VAR(ok, ok);
+ upb_sink_endsubmsg(&p->top->sink, sel);
+ }
+
+ p->top->f = NULL;
+}
+
+static bool start_subobject(upb_json_parser *p) {
+ assert(p->top->f);
+
+ if (upb_fielddef_ismap(p->top->f)) {
+ upb_jsonparser_frame *inner;
+ upb_selector_t sel;
+
+ /* Beginning of a map. Start a new parser frame in a repeated-field
+ * context. */
+ if (!check_stack(p)) return false;
+
+ inner = p->top + 1;
+ sel = getsel_for_handlertype(p, UPB_HANDLER_STARTSEQ);
+ upb_sink_startseq(&p->top->sink, sel, &inner->sink);
+ inner->m = upb_fielddef_msgsubdef(p->top->f);
+ inner->mapfield = p->top->f;
+ inner->f = NULL;
+ inner->is_map = true;
+ inner->is_mapentry = false;
+ p->top = inner;
+
+ return true;
+ } else if (upb_fielddef_issubmsg(p->top->f)) {
+ upb_jsonparser_frame *inner;
+ upb_selector_t sel;
+
+ /* Beginning of a subobject. Start a new parser frame in the submsg
+ * context. */
+ if (!check_stack(p)) return false;
+
+ inner = p->top + 1;
+
+ sel = getsel_for_handlertype(p, UPB_HANDLER_STARTSUBMSG);
+ upb_sink_startsubmsg(&p->top->sink, sel, &inner->sink);
+ inner->m = upb_fielddef_msgsubdef(p->top->f);
+ inner->f = NULL;
+ inner->is_map = false;
+ inner->is_mapentry = false;
+ p->top = inner;
+
+ return true;
+ } else {
+ upb_status_seterrf(&p->status,
+ "Object specified for non-message/group field: %s",
+ upb_fielddef_name(p->top->f));
+ upb_env_reporterror(p->env, &p->status);
+ return false;
+ }
+}
+
+static void end_subobject(upb_json_parser *p) {
+ if (p->top->is_map) {
+ upb_selector_t sel;
+ p->top--;
+ sel = getsel_for_handlertype(p, UPB_HANDLER_ENDSEQ);
+ upb_sink_endseq(&p->top->sink, sel);
+ } else {
+ upb_selector_t sel;
+ p->top--;
+ sel = getsel_for_handlertype(p, UPB_HANDLER_ENDSUBMSG);
+ upb_sink_endsubmsg(&p->top->sink, sel);
+ }
+}
+
+static bool start_array(upb_json_parser *p) {
+ upb_jsonparser_frame *inner;
+ upb_selector_t sel;
+
+ assert(p->top->f);
+
+ if (!upb_fielddef_isseq(p->top->f)) {
+ upb_status_seterrf(&p->status,
+ "Array specified for non-repeated field: %s",
+ upb_fielddef_name(p->top->f));
+ upb_env_reporterror(p->env, &p->status);
+ return false;
+ }
+
+ if (!check_stack(p)) return false;
+
+ inner = p->top + 1;
+ sel = getsel_for_handlertype(p, UPB_HANDLER_STARTSEQ);
+ upb_sink_startseq(&p->top->sink, sel, &inner->sink);
+ inner->m = p->top->m;
+ inner->f = p->top->f;
+ inner->is_map = false;
+ inner->is_mapentry = false;
+ p->top = inner;
+
+ return true;
+}
+
+static void end_array(upb_json_parser *p) {
+ upb_selector_t sel;
+
+ assert(p->top > p->stack);
+
+ p->top--;
+ sel = getsel_for_handlertype(p, UPB_HANDLER_ENDSEQ);
+ upb_sink_endseq(&p->top->sink, sel);
+}
+
+static void start_object(upb_json_parser *p) {
+ if (!p->top->is_map) {
+ upb_sink_startmsg(&p->top->sink);
+ }
+}
+
+static void end_object(upb_json_parser *p) {
+ if (!p->top->is_map) {
+ upb_status status;
+ upb_status_clear(&status);
+ upb_sink_endmsg(&p->top->sink, &status);
+ if (!upb_ok(&status)) {
+ upb_env_reporterror(p->env, &status);
+ }
+ }
+}
+
+
+#define CHECK_RETURN_TOP(x) if (!(x)) goto error
+
+
+/* The actual parser **********************************************************/
+
+/* What follows is the Ragel parser itself. The language is specified in Ragel
+ * and the actions call our C functions above.
+ *
+ * Ragel has an extensive set of functionality, and we use only a small part of
+ * it. There are many action types but we only use a few:
+ *
+ * ">" -- transition into a machine
+ * "%" -- transition out of a machine
+ * "@" -- transition into a final state of a machine.
+ *
+ * "@" transitions are tricky because a machine can transition into a final
+ * state repeatedly. But in some cases we know this can't happen, for example
+ * a string which is delimited by a final '"' can only transition into its
+ * final state once, when the closing '"' is seen. */
+
+
+#line 1218 "upb/json/parser.rl"
+
+
+
+#line 1130 "upb/json/parser.c"
+static const char _json_actions[] = {
+ 0, 1, 0, 1, 2, 1, 3, 1,
+ 5, 1, 6, 1, 7, 1, 8, 1,
+ 10, 1, 12, 1, 13, 1, 14, 1,
+ 15, 1, 16, 1, 17, 1, 21, 1,
+ 25, 1, 27, 2, 3, 8, 2, 4,
+ 5, 2, 6, 2, 2, 6, 8, 2,
+ 11, 9, 2, 13, 15, 2, 14, 15,
+ 2, 18, 1, 2, 19, 27, 2, 20,
+ 9, 2, 22, 27, 2, 23, 27, 2,
+ 24, 27, 2, 26, 27, 3, 14, 11,
+ 9
+};
+
+static const unsigned char _json_key_offsets[] = {
+ 0, 0, 4, 9, 14, 15, 19, 24,
+ 29, 34, 38, 42, 45, 48, 50, 54,
+ 58, 60, 62, 67, 69, 71, 80, 86,
+ 92, 98, 104, 106, 115, 116, 116, 116,
+ 121, 126, 131, 132, 133, 134, 135, 135,
+ 136, 137, 138, 138, 139, 140, 141, 141,
+ 146, 151, 152, 156, 161, 166, 171, 175,
+ 175, 178, 178, 178
+};
+
+static const char _json_trans_keys[] = {
+ 32, 123, 9, 13, 32, 34, 125, 9,
+ 13, 32, 34, 125, 9, 13, 34, 32,
+ 58, 9, 13, 32, 93, 125, 9, 13,
+ 32, 44, 125, 9, 13, 32, 44, 125,
+ 9, 13, 32, 34, 9, 13, 45, 48,
+ 49, 57, 48, 49, 57, 46, 69, 101,
+ 48, 57, 69, 101, 48, 57, 43, 45,
+ 48, 57, 48, 57, 48, 57, 46, 69,
+ 101, 48, 57, 34, 92, 34, 92, 34,
+ 47, 92, 98, 102, 110, 114, 116, 117,
+ 48, 57, 65, 70, 97, 102, 48, 57,
+ 65, 70, 97, 102, 48, 57, 65, 70,
+ 97, 102, 48, 57, 65, 70, 97, 102,
+ 34, 92, 34, 45, 91, 102, 110, 116,
+ 123, 48, 57, 34, 32, 93, 125, 9,
+ 13, 32, 44, 93, 9, 13, 32, 93,
+ 125, 9, 13, 97, 108, 115, 101, 117,
+ 108, 108, 114, 117, 101, 32, 34, 125,
+ 9, 13, 32, 34, 125, 9, 13, 34,
+ 32, 58, 9, 13, 32, 93, 125, 9,
+ 13, 32, 44, 125, 9, 13, 32, 44,
+ 125, 9, 13, 32, 34, 9, 13, 32,
+ 9, 13, 0
+};
+
+static const char _json_single_lengths[] = {
+ 0, 2, 3, 3, 1, 2, 3, 3,
+ 3, 2, 2, 1, 3, 0, 2, 2,
+ 0, 0, 3, 2, 2, 9, 0, 0,
+ 0, 0, 2, 7, 1, 0, 0, 3,
+ 3, 3, 1, 1, 1, 1, 0, 1,
+ 1, 1, 0, 1, 1, 1, 0, 3,
+ 3, 1, 2, 3, 3, 3, 2, 0,
+ 1, 0, 0, 0
+};
+
+static const char _json_range_lengths[] = {
+ 0, 1, 1, 1, 0, 1, 1, 1,
+ 1, 1, 1, 1, 0, 1, 1, 1,
+ 1, 1, 1, 0, 0, 0, 3, 3,
+ 3, 3, 0, 1, 0, 0, 0, 1,
+ 1, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1,
+ 1, 0, 1, 1, 1, 1, 1, 0,
+ 1, 0, 0, 0
+};
+
+static const short _json_index_offsets[] = {
+ 0, 0, 4, 9, 14, 16, 20, 25,
+ 30, 35, 39, 43, 46, 50, 52, 56,
+ 60, 62, 64, 69, 72, 75, 85, 89,
+ 93, 97, 101, 104, 113, 115, 116, 117,
+ 122, 127, 132, 134, 136, 138, 140, 141,
+ 143, 145, 147, 148, 150, 152, 154, 155,
+ 160, 165, 167, 171, 176, 181, 186, 190,
+ 191, 194, 195, 196
+};
+
+static const char _json_indicies[] = {
+ 0, 2, 0, 1, 3, 4, 5, 3,
+ 1, 6, 7, 8, 6, 1, 9, 1,
+ 10, 11, 10, 1, 11, 1, 1, 11,
+ 12, 13, 14, 15, 13, 1, 16, 17,
+ 8, 16, 1, 17, 7, 17, 1, 18,
+ 19, 20, 1, 19, 20, 1, 22, 23,
+ 23, 21, 24, 1, 23, 23, 24, 21,
+ 25, 25, 26, 1, 26, 1, 26, 21,
+ 22, 23, 23, 20, 21, 28, 29, 27,
+ 31, 32, 30, 33, 33, 33, 33, 33,
+ 33, 33, 33, 34, 1, 35, 35, 35,
+ 1, 36, 36, 36, 1, 37, 37, 37,
+ 1, 38, 38, 38, 1, 40, 41, 39,
+ 42, 43, 44, 45, 46, 47, 48, 43,
+ 1, 49, 1, 50, 51, 53, 54, 1,
+ 53, 52, 55, 56, 54, 55, 1, 56,
+ 1, 1, 56, 52, 57, 1, 58, 1,
+ 59, 1, 60, 1, 61, 62, 1, 63,
+ 1, 64, 1, 65, 66, 1, 67, 1,
+ 68, 1, 69, 70, 71, 72, 70, 1,
+ 73, 74, 75, 73, 1, 76, 1, 77,
+ 78, 77, 1, 78, 1, 1, 78, 79,
+ 80, 81, 82, 80, 1, 83, 84, 75,
+ 83, 1, 84, 74, 84, 1, 85, 86,
+ 86, 1, 1, 1, 1, 0
+};
+
+static const char _json_trans_targs[] = {
+ 1, 0, 2, 3, 4, 56, 3, 4,
+ 56, 5, 5, 6, 7, 8, 9, 56,
+ 8, 9, 11, 12, 18, 57, 13, 15,
+ 14, 16, 17, 20, 58, 21, 20, 58,
+ 21, 19, 22, 23, 24, 25, 26, 20,
+ 58, 21, 28, 30, 31, 34, 39, 43,
+ 47, 29, 59, 59, 32, 31, 29, 32,
+ 33, 35, 36, 37, 38, 59, 40, 41,
+ 42, 59, 44, 45, 46, 59, 48, 49,
+ 55, 48, 49, 55, 50, 50, 51, 52,
+ 53, 54, 55, 53, 54, 59, 56
+};
+
+static const char _json_trans_actions[] = {
+ 0, 0, 0, 21, 77, 53, 0, 47,
+ 23, 17, 0, 0, 15, 19, 19, 50,
+ 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 0, 0, 3, 13, 0, 0, 35,
+ 5, 11, 0, 38, 7, 7, 7, 41,
+ 44, 9, 62, 56, 25, 0, 0, 0,
+ 31, 29, 33, 59, 15, 0, 27, 0,
+ 0, 0, 0, 0, 0, 68, 0, 0,
+ 0, 71, 0, 0, 0, 65, 21, 77,
+ 53, 0, 47, 23, 17, 0, 0, 15,
+ 19, 19, 50, 0, 0, 74, 0
+};
+
+static const int json_start = 1;
+
+static const int json_en_number_machine = 10;
+static const int json_en_string_machine = 19;
+static const int json_en_value_machine = 27;
+static const int json_en_main = 1;
+
+
+#line 1221 "upb/json/parser.rl"
+
+size_t parse(void *closure, const void *hd, const char *buf, size_t size,
+ const upb_bufhandle *handle) {
+ upb_json_parser *parser = closure;
+
+ /* Variables used by Ragel's generated code. */
+ int cs = parser->current_state;
+ int *stack = parser->parser_stack;
+ int top = parser->parser_top;
+
+ const char *p = buf;
+ const char *pe = buf + size;
+
+ parser->handle = handle;
+
+ UPB_UNUSED(hd);
+ UPB_UNUSED(handle);
+
+ capture_resume(parser, buf);
+
+
+#line 1301 "upb/json/parser.c"
+ {
+ int _klen;
+ unsigned int _trans;
+ const char *_acts;
+ unsigned int _nacts;
+ const char *_keys;
+
+ if ( p == pe )
+ goto _test_eof;
+ if ( cs == 0 )
+ goto _out;
+_resume:
+ _keys = _json_trans_keys + _json_key_offsets[cs];
+ _trans = _json_index_offsets[cs];
+
+ _klen = _json_single_lengths[cs];
+ if ( _klen > 0 ) {
+ const char *_lower = _keys;
+ const char *_mid;
+ const char *_upper = _keys + _klen - 1;
+ while (1) {
+ if ( _upper < _lower )
+ break;
+
+ _mid = _lower + ((_upper-_lower) >> 1);
+ if ( (*p) < *_mid )
+ _upper = _mid - 1;
+ else if ( (*p) > *_mid )
+ _lower = _mid + 1;
+ else {
+ _trans += (unsigned int)(_mid - _keys);
+ goto _match;
+ }
+ }
+ _keys += _klen;
+ _trans += _klen;
+ }
+
+ _klen = _json_range_lengths[cs];
+ if ( _klen > 0 ) {
+ const char *_lower = _keys;
+ const char *_mid;
+ const char *_upper = _keys + (_klen<<1) - 2;
+ while (1) {
+ if ( _upper < _lower )
+ break;
+
+ _mid = _lower + (((_upper-_lower) >> 1) & ~1);
+ if ( (*p) < _mid[0] )
+ _upper = _mid - 2;
+ else if ( (*p) > _mid[1] )
+ _lower = _mid + 2;
+ else {
+ _trans += (unsigned int)((_mid - _keys)>>1);
+ goto _match;
+ }
+ }
+ _trans += _klen;
+ }
+
+_match:
+ _trans = _json_indicies[_trans];
+ cs = _json_trans_targs[_trans];
+
+ if ( _json_trans_actions[_trans] == 0 )
+ goto _again;
+
+ _acts = _json_actions + _json_trans_actions[_trans];
+ _nacts = (unsigned int) *_acts++;
+ while ( _nacts-- > 0 )
+ {
+ switch ( *_acts++ )
+ {
+ case 0:
+#line 1133 "upb/json/parser.rl"
+ { p--; {cs = stack[--top]; goto _again;} }
+ break;
+ case 1:
+#line 1134 "upb/json/parser.rl"
+ { p--; {stack[top++] = cs; cs = 10; goto _again;} }
+ break;
+ case 2:
+#line 1138 "upb/json/parser.rl"
+ { start_text(parser, p); }
+ break;
+ case 3:
+#line 1139 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(end_text(parser, p)); }
+ break;
+ case 4:
+#line 1145 "upb/json/parser.rl"
+ { start_hex(parser); }
+ break;
+ case 5:
+#line 1146 "upb/json/parser.rl"
+ { hexdigit(parser, p); }
+ break;
+ case 6:
+#line 1147 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(end_hex(parser)); }
+ break;
+ case 7:
+#line 1153 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(escape(parser, p)); }
+ break;
+ case 8:
+#line 1159 "upb/json/parser.rl"
+ { p--; {cs = stack[--top]; goto _again;} }
+ break;
+ case 9:
+#line 1162 "upb/json/parser.rl"
+ { {stack[top++] = cs; cs = 19; goto _again;} }
+ break;
+ case 10:
+#line 1164 "upb/json/parser.rl"
+ { p--; {stack[top++] = cs; cs = 27; goto _again;} }
+ break;
+ case 11:
+#line 1169 "upb/json/parser.rl"
+ { start_member(parser); }
+ break;
+ case 12:
+#line 1170 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(end_membername(parser)); }
+ break;
+ case 13:
+#line 1173 "upb/json/parser.rl"
+ { end_member(parser); }
+ break;
+ case 14:
+#line 1179 "upb/json/parser.rl"
+ { start_object(parser); }
+ break;
+ case 15:
+#line 1182 "upb/json/parser.rl"
+ { end_object(parser); }
+ break;
+ case 16:
+#line 1188 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(start_array(parser)); }
+ break;
+ case 17:
+#line 1192 "upb/json/parser.rl"
+ { end_array(parser); }
+ break;
+ case 18:
+#line 1197 "upb/json/parser.rl"
+ { start_number(parser, p); }
+ break;
+ case 19:
+#line 1198 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(end_number(parser, p)); }
+ break;
+ case 20:
+#line 1200 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(start_stringval(parser)); }
+ break;
+ case 21:
+#line 1201 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(end_stringval(parser)); }
+ break;
+ case 22:
+#line 1203 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(parser_putbool(parser, true)); }
+ break;
+ case 23:
+#line 1205 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(parser_putbool(parser, false)); }
+ break;
+ case 24:
+#line 1207 "upb/json/parser.rl"
+ { /* null value */ }
+ break;
+ case 25:
+#line 1209 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(start_subobject(parser)); }
+ break;
+ case 26:
+#line 1210 "upb/json/parser.rl"
+ { end_subobject(parser); }
+ break;
+ case 27:
+#line 1215 "upb/json/parser.rl"
+ { p--; {cs = stack[--top]; goto _again;} }
+ break;
+#line 1487 "upb/json/parser.c"
+ }
+ }
+
+_again:
+ if ( cs == 0 )
+ goto _out;
+ if ( ++p != pe )
+ goto _resume;
+ _test_eof: {}
+ _out: {}
+ }
+
+#line 1242 "upb/json/parser.rl"
+
+ if (p != pe) {
+ upb_status_seterrf(&parser->status, "Parse error at %s\n", p);
+ upb_env_reporterror(parser->env, &parser->status);
+ } else {
+ capture_suspend(parser, &p);
+ }
+
+error:
+ /* Save parsing state back to parser. */
+ parser->current_state = cs;
+ parser->parser_top = top;
+
+ return p - buf;
+}
+
+bool end(void *closure, const void *hd) {
+ UPB_UNUSED(closure);
+ UPB_UNUSED(hd);
+
+ /* Prevent compile warning on unused static constants. */
+ UPB_UNUSED(json_start);
+ UPB_UNUSED(json_en_number_machine);
+ UPB_UNUSED(json_en_string_machine);
+ UPB_UNUSED(json_en_value_machine);
+ UPB_UNUSED(json_en_main);
+ return true;
+}
+
+static void json_parser_reset(upb_json_parser *p) {
+ int cs;
+ int top;
+
+ p->top = p->stack;
+ p->top->f = NULL;
+ p->top->is_map = false;
+ p->top->is_mapentry = false;
+
+ /* Emit Ragel initialization of the parser. */
+
+#line 1541 "upb/json/parser.c"
+ {
+ cs = json_start;
+ top = 0;
+ }
+
+#line 1282 "upb/json/parser.rl"
+ p->current_state = cs;
+ p->parser_top = top;
+ accumulate_clear(p);
+ p->multipart_state = MULTIPART_INACTIVE;
+ p->capture = NULL;
+ p->accumulated = NULL;
+ upb_status_clear(&p->status);
+}
+
+
+/* Public API *****************************************************************/
+
+upb_json_parser *upb_json_parser_create(upb_env *env, upb_sink *output) {
+#ifndef NDEBUG
+ const size_t size_before = upb_env_bytesallocated(env);
+#endif
+ upb_json_parser *p = upb_env_malloc(env, sizeof(upb_json_parser));
+ if (!p) return false;
+
+ p->env = env;
+ p->limit = p->stack + UPB_JSON_MAX_DEPTH;
+ p->accumulate_buf = NULL;
+ p->accumulate_buf_size = 0;
+ upb_byteshandler_init(&p->input_handler_);
+ upb_byteshandler_setstring(&p->input_handler_, parse, NULL);
+ upb_byteshandler_setendstr(&p->input_handler_, end, NULL);
+ upb_bytessink_reset(&p->input_, &p->input_handler_, p);
+
+ json_parser_reset(p);
+ upb_sink_reset(&p->top->sink, output->handlers, output->closure);
+ p->top->m = upb_handlers_msgdef(output->handlers);
+
+ /* If this fails, uncomment and increase the value in parser.h. */
+ /* fprintf(stderr, "%zd\n", upb_env_bytesallocated(env) - size_before); */
+ assert(upb_env_bytesallocated(env) - size_before <= UPB_JSON_PARSER_SIZE);
+ return p;
+}
+
+upb_bytessink *upb_json_parser_input(upb_json_parser *p) {
+ return &p->input_;
+}
+/*
+** This currently uses snprintf() to format primitives, and could be optimized
+** further.
+*/
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+
+struct upb_json_printer {
+ upb_sink input_;
+ /* BytesSink closure. */
+ void *subc_;
+ upb_bytessink *output_;
+
+ /* We track the depth so that we know when to emit startstr/endstr on the
+ * output. */
+ int depth_;
+
+ /* Have we emitted the first element? This state is necessary to emit commas
+ * without leaving a trailing comma in arrays/maps. We keep this state per
+ * frame depth.
+ *
+ * Why max_depth * 2? UPB_MAX_HANDLER_DEPTH counts depth as nested messages.
+ * We count frames (contexts in which we separate elements by commas) as both
+ * repeated fields and messages (maps), and the worst case is a
+ * message->repeated field->submessage->repeated field->... nesting. */
+ bool first_elem_[UPB_MAX_HANDLER_DEPTH * 2];
+};
+
+/* StringPiece; a pointer plus a length. */
+typedef struct {
+ const char *ptr;
+ size_t len;
+} strpc;
+
+strpc *newstrpc(upb_handlers *h, const upb_fielddef *f) {
+ strpc *ret = malloc(sizeof(*ret));
+ ret->ptr = upb_fielddef_name(f);
+ ret->len = strlen(ret->ptr);
+ upb_handlers_addcleanup(h, ret, free);
+ return ret;
+}
+
+/* ------------ JSON string printing: values, maps, arrays ------------------ */
+
+static void print_data(
+ upb_json_printer *p, const char *buf, unsigned int len) {
+ /* TODO: Will need to change if we support pushback from the sink. */
+ size_t n = upb_bytessink_putbuf(p->output_, p->subc_, buf, len, NULL);
+ UPB_ASSERT_VAR(n, n == len);
+}
+
+static void print_comma(upb_json_printer *p) {
+ if (!p->first_elem_[p->depth_]) {
+ print_data(p, ",", 1);
+ }
+ p->first_elem_[p->depth_] = false;
+}
+
+/* Helpers that print properly formatted elements to the JSON output stream. */
+
+/* Used for escaping control chars in strings. */
+static const char kControlCharLimit = 0x20;
+
+UPB_INLINE bool is_json_escaped(char c) {
+ /* See RFC 4627. */
+ unsigned char uc = (unsigned char)c;
+ return uc < kControlCharLimit || uc == '"' || uc == '\\';
+}
+
+UPB_INLINE char* json_nice_escape(char c) {
+ switch (c) {
+ case '"': return "\\\"";
+ case '\\': return "\\\\";
+ case '\b': return "\\b";
+ case '\f': return "\\f";
+ case '\n': return "\\n";
+ case '\r': return "\\r";
+ case '\t': return "\\t";
+ default: return NULL;
+ }
+}
+
+/* Write a properly escaped string chunk. The surrounding quotes are *not*
+ * printed; this is so that the caller has the option of emitting the string
+ * content in chunks. */
+static void putstring(upb_json_printer *p, const char *buf, unsigned int len) {
+ const char* unescaped_run = NULL;
+ unsigned int i;
+ for (i = 0; i < len; i++) {
+ char c = buf[i];
+ /* Handle escaping. */
+ if (is_json_escaped(c)) {
+ /* Use a "nice" escape, like \n, if one exists for this character. */
+ const char* escape = json_nice_escape(c);
+ /* If we don't have a specific 'nice' escape code, use a \uXXXX-style
+ * escape. */
+ char escape_buf[8];
+ if (!escape) {
+ unsigned char byte = (unsigned char)c;
+ _upb_snprintf(escape_buf, sizeof(escape_buf), "\\u%04x", (int)byte);
+ escape = escape_buf;
+ }
+
+ /* N.B. that we assume that the input encoding is equal to the output
+ * encoding (both UTF-8 for now), so for chars >= 0x20 and != \, ", we
+ * can simply pass the bytes through. */
+
+ /* If there's a current run of unescaped chars, print that run first. */
+ if (unescaped_run) {
+ print_data(p, unescaped_run, &buf[i] - unescaped_run);
+ unescaped_run = NULL;
+ }
+ /* Then print the escape code. */
+ print_data(p, escape, strlen(escape));
+ } else {
+ /* Add to the current unescaped run of characters. */
+ if (unescaped_run == NULL) {
+ unescaped_run = &buf[i];
+ }
+ }
+ }
+
+ /* If the string ended in a run of unescaped characters, print that last run. */
+ if (unescaped_run) {
+ print_data(p, unescaped_run, &buf[len] - unescaped_run);
+ }
+}
+
+#define CHKLENGTH(x) if (!(x)) return -1;
+
+/* Helpers that format floating point values according to our custom formats.
+ * Right now we use %.8g and %.17g for float/double, respectively, to match
+ * proto2::util::JsonFormat's defaults. May want to change this later. */
+
+static size_t fmt_double(double val, char* buf, size_t length) {
+ size_t n = _upb_snprintf(buf, length, "%.17g", val);
+ CHKLENGTH(n > 0 && n < length);
+ return n;
+}
+
+static size_t fmt_float(float val, char* buf, size_t length) {
+ size_t n = _upb_snprintf(buf, length, "%.8g", val);
+ CHKLENGTH(n > 0 && n < length);
+ return n;
+}
+
+static size_t fmt_bool(bool val, char* buf, size_t length) {
+ size_t n = _upb_snprintf(buf, length, "%s", (val ? "true" : "false"));
+ CHKLENGTH(n > 0 && n < length);
+ return n;
+}
+
+static size_t fmt_int64(long val, char* buf, size_t length) {
+ size_t n = _upb_snprintf(buf, length, "%ld", val);
+ CHKLENGTH(n > 0 && n < length);
+ return n;
+}
+
+static size_t fmt_uint64(unsigned long long val, char* buf, size_t length) {
+ size_t n = _upb_snprintf(buf, length, "%llu", val);
+ CHKLENGTH(n > 0 && n < length);
+ return n;
+}
+
+/* Print a map key given a field name. Called by scalar field handlers and by
+ * startseq for repeated fields. */
+static bool putkey(void *closure, const void *handler_data) {
+ upb_json_printer *p = closure;
+ const strpc *key = handler_data;
+ print_comma(p);
+ print_data(p, "\"", 1);
+ putstring(p, key->ptr, key->len);
+ print_data(p, "\":", 2);
+ return true;
+}
+
+#define CHKFMT(val) if ((val) == (size_t)-1) return false;
+#define CHK(val) if (!(val)) return false;
+
+#define TYPE_HANDLERS(type, fmt_func) \
+ static bool put##type(void *closure, const void *handler_data, type val) { \
+ upb_json_printer *p = closure; \
+ char data[64]; \
+ size_t length = fmt_func(val, data, sizeof(data)); \
+ UPB_UNUSED(handler_data); \
+ CHKFMT(length); \
+ print_data(p, data, length); \
+ return true; \
+ } \
+ static bool scalar_##type(void *closure, const void *handler_data, \
+ type val) { \
+ CHK(putkey(closure, handler_data)); \
+ CHK(put##type(closure, handler_data, val)); \
+ return true; \
+ } \
+ static bool repeated_##type(void *closure, const void *handler_data, \
+ type val) { \
+ upb_json_printer *p = closure; \
+ print_comma(p); \
+ CHK(put##type(closure, handler_data, val)); \
+ return true; \
+ }
+
+#define TYPE_HANDLERS_MAPKEY(type, fmt_func) \
+ static bool putmapkey_##type(void *closure, const void *handler_data, \
+ type val) { \
+ upb_json_printer *p = closure; \
+ print_data(p, "\"", 1); \
+ CHK(put##type(closure, handler_data, val)); \
+ print_data(p, "\":", 2); \
+ return true; \
+ }
+
+TYPE_HANDLERS(double, fmt_double)
+TYPE_HANDLERS(float, fmt_float)
+TYPE_HANDLERS(bool, fmt_bool)
+TYPE_HANDLERS(int32_t, fmt_int64)
+TYPE_HANDLERS(uint32_t, fmt_int64)
+TYPE_HANDLERS(int64_t, fmt_int64)
+TYPE_HANDLERS(uint64_t, fmt_uint64)
+
+/* double and float are not allowed to be map keys. */
+TYPE_HANDLERS_MAPKEY(bool, fmt_bool)
+TYPE_HANDLERS_MAPKEY(int32_t, fmt_int64)
+TYPE_HANDLERS_MAPKEY(uint32_t, fmt_int64)
+TYPE_HANDLERS_MAPKEY(int64_t, fmt_int64)
+TYPE_HANDLERS_MAPKEY(uint64_t, fmt_uint64)
+
+#undef TYPE_HANDLERS
+#undef TYPE_HANDLERS_MAPKEY
+
+typedef struct {
+ void *keyname;
+ const upb_enumdef *enumdef;
+} EnumHandlerData;
+
+static bool scalar_enum(void *closure, const void *handler_data,
+ int32_t val) {
+ const EnumHandlerData *hd = handler_data;
+ upb_json_printer *p = closure;
+ const char *symbolic_name;
+
+ CHK(putkey(closure, hd->keyname));
+
+ symbolic_name = upb_enumdef_iton(hd->enumdef, val);
+ if (symbolic_name) {
+ print_data(p, "\"", 1);
+ putstring(p, symbolic_name, strlen(symbolic_name));
+ print_data(p, "\"", 1);
+ } else {
+ putint32_t(closure, NULL, val);
+ }
+
+ return true;
+}
+
+static void print_enum_symbolic_name(upb_json_printer *p,
+ const upb_enumdef *def,
+ int32_t val) {
+ const char *symbolic_name = upb_enumdef_iton(def, val);
+ if (symbolic_name) {
+ print_data(p, "\"", 1);
+ putstring(p, symbolic_name, strlen(symbolic_name));
+ print_data(p, "\"", 1);
+ } else {
+ putint32_t(p, NULL, val);
+ }
+}
+
+static bool repeated_enum(void *closure, const void *handler_data,
+ int32_t val) {
+ const EnumHandlerData *hd = handler_data;
+ upb_json_printer *p = closure;
+ print_comma(p);
+
+ print_enum_symbolic_name(p, hd->enumdef, val);
+
+ return true;
+}
+
+static bool mapvalue_enum(void *closure, const void *handler_data,
+ int32_t val) {
+ const EnumHandlerData *hd = handler_data;
+ upb_json_printer *p = closure;
+
+ print_enum_symbolic_name(p, hd->enumdef, val);
+
+ return true;
+}
+
+static void *scalar_startsubmsg(void *closure, const void *handler_data) {
+ return putkey(closure, handler_data) ? closure : UPB_BREAK;
+}
+
+static void *repeated_startsubmsg(void *closure, const void *handler_data) {
+ upb_json_printer *p = closure;
+ UPB_UNUSED(handler_data);
+ print_comma(p);
+ return closure;
+}
+
+static void start_frame(upb_json_printer *p) {
+ p->depth_++;
+ p->first_elem_[p->depth_] = true;
+ print_data(p, "{", 1);
+}
+
+static void end_frame(upb_json_printer *p) {
+ print_data(p, "}", 1);
+ p->depth_--;
+}
+
+static bool printer_startmsg(void *closure, const void *handler_data) {
+ upb_json_printer *p = closure;
+ UPB_UNUSED(handler_data);
+ if (p->depth_ == 0) {
+ upb_bytessink_start(p->output_, 0, &p->subc_);
+ }
+ start_frame(p);
+ return true;
+}
+
+static bool printer_endmsg(void *closure, const void *handler_data, upb_status *s) {
+ upb_json_printer *p = closure;
+ UPB_UNUSED(handler_data);
+ UPB_UNUSED(s);
+ end_frame(p);
+ if (p->depth_ == 0) {
+ upb_bytessink_end(p->output_);
+ }
+ return true;
+}
+
+static void *startseq(void *closure, const void *handler_data) {
+ upb_json_printer *p = closure;
+ CHK(putkey(closure, handler_data));
+ p->depth_++;
+ p->first_elem_[p->depth_] = true;
+ print_data(p, "[", 1);
+ return closure;
+}
+
+static bool endseq(void *closure, const void *handler_data) {
+ upb_json_printer *p = closure;
+ UPB_UNUSED(handler_data);
+ print_data(p, "]", 1);
+ p->depth_--;
+ return true;
+}
+
+static void *startmap(void *closure, const void *handler_data) {
+ upb_json_printer *p = closure;
+ CHK(putkey(closure, handler_data));
+ p->depth_++;
+ p->first_elem_[p->depth_] = true;
+ print_data(p, "{", 1);
+ return closure;
+}
+
+static bool endmap(void *closure, const void *handler_data) {
+ upb_json_printer *p = closure;
+ UPB_UNUSED(handler_data);
+ print_data(p, "}", 1);
+ p->depth_--;
+ return true;
+}
+
+static size_t putstr(void *closure, const void *handler_data, const char *str,
+ size_t len, const upb_bufhandle *handle) {
+ upb_json_printer *p = closure;
+ UPB_UNUSED(handler_data);
+ UPB_UNUSED(handle);
+ putstring(p, str, len);
+ return len;
+}
+
+/* This has to Base64 encode the bytes, because JSON has no "bytes" type. */
+static size_t putbytes(void *closure, const void *handler_data, const char *str,
+ size_t len, const upb_bufhandle *handle) {
+ upb_json_printer *p = closure;
+
+ /* This is the regular base64, not the "web-safe" version. */
+ static const char base64[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+ /* Base64-encode. */
+ char data[16000];
+ const char *limit = data + sizeof(data);
+ const unsigned char *from = (const unsigned char*)str;
+ char *to = data;
+ size_t remaining = len;
+ size_t bytes;
+
+ UPB_UNUSED(handler_data);
+ UPB_UNUSED(handle);
+
+ while (remaining > 2) {
+ /* TODO(haberman): handle encoded lengths > sizeof(data) */
+ UPB_ASSERT_VAR(limit, (limit - to) >= 4);
+
+ to[0] = base64[from[0] >> 2];
+ to[1] = base64[((from[0] & 0x3) << 4) | (from[1] >> 4)];
+ to[2] = base64[((from[1] & 0xf) << 2) | (from[2] >> 6)];
+ to[3] = base64[from[2] & 0x3f];
+
+ remaining -= 3;
+ to += 4;
+ from += 3;
+ }
+
+ switch (remaining) {
+ case 2:
+ to[0] = base64[from[0] >> 2];
+ to[1] = base64[((from[0] & 0x3) << 4) | (from[1] >> 4)];
+ to[2] = base64[(from[1] & 0xf) << 2];
+ to[3] = '=';
+ to += 4;
+ from += 2;
+ break;
+ case 1:
+ to[0] = base64[from[0] >> 2];
+ to[1] = base64[((from[0] & 0x3) << 4)];
+ to[2] = '=';
+ to[3] = '=';
+ to += 4;
+ from += 1;
+ break;
+ }
+
+ bytes = to - data;
+ print_data(p, "\"", 1);
+ putstring(p, data, bytes);
+ print_data(p, "\"", 1);
+ return len;
+}
+
+static void *scalar_startstr(void *closure, const void *handler_data,
+ size_t size_hint) {
+ upb_json_printer *p = closure;
+ UPB_UNUSED(handler_data);
+ UPB_UNUSED(size_hint);
+ CHK(putkey(closure, handler_data));
+ print_data(p, "\"", 1);
+ return p;
+}
+
+static size_t scalar_str(void *closure, const void *handler_data,
+ const char *str, size_t len,
+ const upb_bufhandle *handle) {
+ CHK(putstr(closure, handler_data, str, len, handle));
+ return len;
+}
+
+static bool scalar_endstr(void *closure, const void *handler_data) {
+ upb_json_printer *p = closure;
+ UPB_UNUSED(handler_data);
+ print_data(p, "\"", 1);
+ return true;
+}
+
+static void *repeated_startstr(void *closure, const void *handler_data,
+ size_t size_hint) {
+ upb_json_printer *p = closure;
+ UPB_UNUSED(handler_data);
+ UPB_UNUSED(size_hint);
+ print_comma(p);
+ print_data(p, "\"", 1);
+ return p;
+}
+
+static size_t repeated_str(void *closure, const void *handler_data,
+ const char *str, size_t len,
+ const upb_bufhandle *handle) {
+ CHK(putstr(closure, handler_data, str, len, handle));
+ return len;
+}
+
+static bool repeated_endstr(void *closure, const void *handler_data) {
+ upb_json_printer *p = closure;
+ UPB_UNUSED(handler_data);
+ print_data(p, "\"", 1);
+ return true;
+}
+
+static void *mapkeyval_startstr(void *closure, const void *handler_data,
+ size_t size_hint) {
+ upb_json_printer *p = closure;
+ UPB_UNUSED(handler_data);
+ UPB_UNUSED(size_hint);
+ print_data(p, "\"", 1);
+ return p;
+}
+
+static size_t mapkey_str(void *closure, const void *handler_data,
+ const char *str, size_t len,
+ const upb_bufhandle *handle) {
+ CHK(putstr(closure, handler_data, str, len, handle));
+ return len;
+}
+
+static bool mapkey_endstr(void *closure, const void *handler_data) {
+ upb_json_printer *p = closure;
+ UPB_UNUSED(handler_data);
+ print_data(p, "\":", 2);
+ return true;
+}
+
+static bool mapvalue_endstr(void *closure, const void *handler_data) {
+ upb_json_printer *p = closure;
+ UPB_UNUSED(handler_data);
+ print_data(p, "\"", 1);
+ return true;
+}
+
+static size_t scalar_bytes(void *closure, const void *handler_data,
+ const char *str, size_t len,
+ const upb_bufhandle *handle) {
+ CHK(putkey(closure, handler_data));
+ CHK(putbytes(closure, handler_data, str, len, handle));
+ return len;
+}
+
+static size_t repeated_bytes(void *closure, const void *handler_data,
+ const char *str, size_t len,
+ const upb_bufhandle *handle) {
+ upb_json_printer *p = closure;
+ print_comma(p);
+ CHK(putbytes(closure, handler_data, str, len, handle));
+ return len;
+}
+
+static size_t mapkey_bytes(void *closure, const void *handler_data,
+ const char *str, size_t len,
+ const upb_bufhandle *handle) {
+ upb_json_printer *p = closure;
+ CHK(putbytes(closure, handler_data, str, len, handle));
+ print_data(p, ":", 1);
+ return len;
+}
+
+static void set_enum_hd(upb_handlers *h,
+ const upb_fielddef *f,
+ upb_handlerattr *attr) {
+ EnumHandlerData *hd = malloc(sizeof(EnumHandlerData));
+ hd->enumdef = (const upb_enumdef *)upb_fielddef_subdef(f);
+ hd->keyname = newstrpc(h, f);
+ upb_handlers_addcleanup(h, hd, free);
+ upb_handlerattr_sethandlerdata(attr, hd);
+}
+
+/* Set up handlers for a mapentry submessage (i.e., an individual key/value pair
+ * in a map).
+ *
+ * TODO: Handle missing key, missing value, out-of-order key/value, or repeated
+ * key or value cases properly. The right way to do this is to allocate a
+ * temporary structure at the start of a mapentry submessage, store key and
+ * value data in it as key and value handlers are called, and then print the
+ * key/value pair once at the end of the submessage. If we don't do this, we
+ * should at least detect the case and throw an error. However, so far all of
+ * our sources that emit mapentry messages do so canonically (with one key
+ * field, and then one value field), so this is not a pressing concern at the
+ * moment. */
+void printer_sethandlers_mapentry(const void *closure, upb_handlers *h) {
+ const upb_msgdef *md = upb_handlers_msgdef(h);
+
+ /* A mapentry message is printed simply as '"key": value'. Rather than
+ * special-case key and value for every type below, we just handle both
+ * fields explicitly here. */
+ const upb_fielddef* key_field = upb_msgdef_itof(md, UPB_MAPENTRY_KEY);
+ const upb_fielddef* value_field = upb_msgdef_itof(md, UPB_MAPENTRY_VALUE);
+
+ upb_handlerattr empty_attr = UPB_HANDLERATTR_INITIALIZER;
+
+ UPB_UNUSED(closure);
+
+ switch (upb_fielddef_type(key_field)) {
+ case UPB_TYPE_INT32:
+ upb_handlers_setint32(h, key_field, putmapkey_int32_t, &empty_attr);
+ break;
+ case UPB_TYPE_INT64:
+ upb_handlers_setint64(h, key_field, putmapkey_int64_t, &empty_attr);
+ break;
+ case UPB_TYPE_UINT32:
+ upb_handlers_setuint32(h, key_field, putmapkey_uint32_t, &empty_attr);
+ break;
+ case UPB_TYPE_UINT64:
+ upb_handlers_setuint64(h, key_field, putmapkey_uint64_t, &empty_attr);
+ break;
+ case UPB_TYPE_BOOL:
+ upb_handlers_setbool(h, key_field, putmapkey_bool, &empty_attr);
+ break;
+ case UPB_TYPE_STRING:
+ upb_handlers_setstartstr(h, key_field, mapkeyval_startstr, &empty_attr);
+ upb_handlers_setstring(h, key_field, mapkey_str, &empty_attr);
+ upb_handlers_setendstr(h, key_field, mapkey_endstr, &empty_attr);
+ break;
+ case UPB_TYPE_BYTES:
+ upb_handlers_setstring(h, key_field, mapkey_bytes, &empty_attr);
+ break;
+ default:
+ assert(false);
+ break;
+ }
+
+ switch (upb_fielddef_type(value_field)) {
+ case UPB_TYPE_INT32:
+ upb_handlers_setint32(h, value_field, putint32_t, &empty_attr);
+ break;
+ case UPB_TYPE_INT64:
+ upb_handlers_setint64(h, value_field, putint64_t, &empty_attr);
+ break;
+ case UPB_TYPE_UINT32:
+ upb_handlers_setuint32(h, value_field, putuint32_t, &empty_attr);
+ break;
+ case UPB_TYPE_UINT64:
+ upb_handlers_setuint64(h, value_field, putuint64_t, &empty_attr);
+ break;
+ case UPB_TYPE_BOOL:
+ upb_handlers_setbool(h, value_field, putbool, &empty_attr);
+ break;
+ case UPB_TYPE_FLOAT:
+ upb_handlers_setfloat(h, value_field, putfloat, &empty_attr);
+ break;
+ case UPB_TYPE_DOUBLE:
+ upb_handlers_setdouble(h, value_field, putdouble, &empty_attr);
+ break;
+ case UPB_TYPE_STRING:
+ upb_handlers_setstartstr(h, value_field, mapkeyval_startstr, &empty_attr);
+ upb_handlers_setstring(h, value_field, putstr, &empty_attr);
+ upb_handlers_setendstr(h, value_field, mapvalue_endstr, &empty_attr);
+ break;
+ case UPB_TYPE_BYTES:
+ upb_handlers_setstring(h, value_field, putbytes, &empty_attr);
+ break;
+ case UPB_TYPE_ENUM: {
+ upb_handlerattr enum_attr = UPB_HANDLERATTR_INITIALIZER;
+ set_enum_hd(h, value_field, &enum_attr);
+ upb_handlers_setint32(h, value_field, mapvalue_enum, &enum_attr);
+ upb_handlerattr_uninit(&enum_attr);
+ break;
+ }
+ case UPB_TYPE_MESSAGE:
+ /* No handler necessary -- the submsg handlers will print the message
+ * as appropriate. */
+ break;
+ }
+
+ upb_handlerattr_uninit(&empty_attr);
+}
+
+void printer_sethandlers(const void *closure, upb_handlers *h) {
+ const upb_msgdef *md = upb_handlers_msgdef(h);
+ bool is_mapentry = upb_msgdef_mapentry(md);
+ upb_handlerattr empty_attr = UPB_HANDLERATTR_INITIALIZER;
+ upb_msg_field_iter i;
+
+ UPB_UNUSED(closure);
+
+ if (is_mapentry) {
+ /* mapentry messages are sufficiently different that we handle them
+ * separately. */
+ printer_sethandlers_mapentry(closure, h);
+ return;
+ }
+
+ upb_handlers_setstartmsg(h, printer_startmsg, &empty_attr);
+ upb_handlers_setendmsg(h, printer_endmsg, &empty_attr);
+
+#define TYPE(type, name, ctype) \
+ case type: \
+ if (upb_fielddef_isseq(f)) { \
+ upb_handlers_set##name(h, f, repeated_##ctype, &empty_attr); \
+ } else { \
+ upb_handlers_set##name(h, f, scalar_##ctype, &name_attr); \
+ } \
+ break;
+
+ upb_msg_field_begin(&i, md);
+ for(; !upb_msg_field_done(&i); upb_msg_field_next(&i)) {
+ const upb_fielddef *f = upb_msg_iter_field(&i);
+
+ upb_handlerattr name_attr = UPB_HANDLERATTR_INITIALIZER;
+ upb_handlerattr_sethandlerdata(&name_attr, newstrpc(h, f));
+
+ if (upb_fielddef_ismap(f)) {
+ upb_handlers_setstartseq(h, f, startmap, &name_attr);
+ upb_handlers_setendseq(h, f, endmap, &name_attr);
+ } else if (upb_fielddef_isseq(f)) {
+ upb_handlers_setstartseq(h, f, startseq, &name_attr);
+ upb_handlers_setendseq(h, f, endseq, &empty_attr);
+ }
+
+ switch (upb_fielddef_type(f)) {
+ TYPE(UPB_TYPE_FLOAT, float, float);
+ TYPE(UPB_TYPE_DOUBLE, double, double);
+ TYPE(UPB_TYPE_BOOL, bool, bool);
+ TYPE(UPB_TYPE_INT32, int32, int32_t);
+ TYPE(UPB_TYPE_UINT32, uint32, uint32_t);
+ TYPE(UPB_TYPE_INT64, int64, int64_t);
+ TYPE(UPB_TYPE_UINT64, uint64, uint64_t);
+ case UPB_TYPE_ENUM: {
+ /* For now, we always emit symbolic names for enums. We may want an
+ * option later to control this behavior, but we will wait for a real
+ * need first. */
+ upb_handlerattr enum_attr = UPB_HANDLERATTR_INITIALIZER;
+ set_enum_hd(h, f, &enum_attr);
+
+ if (upb_fielddef_isseq(f)) {
+ upb_handlers_setint32(h, f, repeated_enum, &enum_attr);
+ } else {
+ upb_handlers_setint32(h, f, scalar_enum, &enum_attr);
+ }
+
+ upb_handlerattr_uninit(&enum_attr);
+ break;
+ }
+ case UPB_TYPE_STRING:
+ if (upb_fielddef_isseq(f)) {
+ upb_handlers_setstartstr(h, f, repeated_startstr, &empty_attr);
+ upb_handlers_setstring(h, f, repeated_str, &empty_attr);
+ upb_handlers_setendstr(h, f, repeated_endstr, &empty_attr);
+ } else {
+ upb_handlers_setstartstr(h, f, scalar_startstr, &name_attr);
+ upb_handlers_setstring(h, f, scalar_str, &empty_attr);
+ upb_handlers_setendstr(h, f, scalar_endstr, &empty_attr);
+ }
+ break;
+ case UPB_TYPE_BYTES:
+ /* XXX: this doesn't support strings that span buffers yet. The base64
+ * encoder will need to be made resumable for this to work properly. */
+ if (upb_fielddef_isseq(f)) {
+ upb_handlers_setstring(h, f, repeated_bytes, &empty_attr);
+ } else {
+ upb_handlers_setstring(h, f, scalar_bytes, &name_attr);
+ }
+ break;
+ case UPB_TYPE_MESSAGE:
+ if (upb_fielddef_isseq(f)) {
+ upb_handlers_setstartsubmsg(h, f, repeated_startsubmsg, &name_attr);
+ } else {
+ upb_handlers_setstartsubmsg(h, f, scalar_startsubmsg, &name_attr);
+ }
+ break;
+ }
+
+ upb_handlerattr_uninit(&name_attr);
+ }
+
+ upb_handlerattr_uninit(&empty_attr);
+#undef TYPE
+}
+
+static void json_printer_reset(upb_json_printer *p) {
+ p->depth_ = 0;
+}
+
+
+/* Public API *****************************************************************/
+
+upb_json_printer *upb_json_printer_create(upb_env *e, const upb_handlers *h,
+ upb_bytessink *output) {
+#ifndef NDEBUG
+ size_t size_before = upb_env_bytesallocated(e);
+#endif
+
+ upb_json_printer *p = upb_env_malloc(e, sizeof(upb_json_printer));
+ if (!p) return NULL;
+
+ p->output_ = output;
+ json_printer_reset(p);
+ upb_sink_reset(&p->input_, h, p);
+
+ /* If this fails, increase the value in printer.h. */
+ assert(upb_env_bytesallocated(e) - size_before <= UPB_JSON_PRINTER_SIZE);
+ return p;
+}
+
+upb_sink *upb_json_printer_input(upb_json_printer *p) {
+ return &p->input_;
+}
+
+const upb_handlers *upb_json_printer_newhandlers(const upb_msgdef *md,
+ const void *owner) {
+ return upb_handlers_newfrozen(md, owner, printer_sethandlers, NULL);
+}
diff --git a/php/ext/google/protobuf/upb.h b/php/ext/google/protobuf/upb.h
new file mode 100644
index 00000000..073faf41
--- /dev/null
+++ b/php/ext/google/protobuf/upb.h
@@ -0,0 +1,8217 @@
+// Amalgamated source file
+/*
+** Defs are upb's internal representation of the constructs that can appear
+** in a .proto file:
+**
+** - upb::MessageDef (upb_msgdef): describes a "message" construct.
+** - upb::FieldDef (upb_fielddef): describes a message field.
+** - upb::EnumDef (upb_enumdef): describes an enum.
+** - upb::OneofDef (upb_oneofdef): describes a oneof.
+** - upb::Def (upb_def): base class of all the others.
+**
+** TODO: definitions of services.
+**
+** Like upb_refcounted objects, defs are mutable only until frozen, and are
+** only thread-safe once frozen.
+**
+** This is a mixed C/C++ interface that offers a full API to both languages.
+** See the top-level README for more information.
+*/
+
+#ifndef UPB_DEF_H_
+#define UPB_DEF_H_
+
+/*
+** upb::RefCounted (upb_refcounted)
+**
+** A refcounting scheme that supports circular refs. It accomplishes this by
+** partitioning the set of objects into groups such that no cycle spans groups;
+** we can then reference-count the group as a whole and ignore refs within the
+** group. When objects are mutable, these groups are computed very
+** conservatively; we group any objects that have ever had a link between them.
+** When objects are frozen, we compute strongly-connected components which
+** allows us to be precise and only group objects that are actually cyclic.
+**
+** This is a mixed C/C++ interface that offers a full API to both languages.
+** See the top-level README for more information.
+*/
+
+#ifndef UPB_REFCOUNTED_H_
+#define UPB_REFCOUNTED_H_
+
+/*
+** upb_table
+**
+** This header is INTERNAL-ONLY! Its interfaces are not public or stable!
+** This file defines very fast int->upb_value (inttable) and string->upb_value
+** (strtable) hash tables.
+**
+** The table uses chained scatter with Brent's variation (inspired by the Lua
+** implementation of hash tables). The hash function for strings is Austin
+** Appleby's "MurmurHash."
+**
+** The inttable uses uintptr_t as its key, which guarantees it can be used to
+** store pointers or integers of at least 32 bits (upb isn't really useful on
+** systems where sizeof(void*) < 4).
+**
+** The table must be homogeneous (all values of the same type). In debug
+** mode, we check this on insert and lookup.
+*/
+
+#ifndef UPB_TABLE_H_
+#define UPB_TABLE_H_
+
+#include <assert.h>
+#include <stdint.h>
+#include <string.h>
+/*
+** This file contains shared definitions that are widely used across upb.
+**
+** This is a mixed C/C++ interface that offers a full API to both languages.
+** See the top-level README for more information.
+*/
+
+#ifndef UPB_H_
+#define UPB_H_
+
+#include <assert.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stddef.h>
+
+/* UPB_INLINE: inline if possible, emit standalone code if required. */
+#ifdef __cplusplus
+#define UPB_INLINE inline
+#elif defined (__GNUC__)
+#define UPB_INLINE static __inline__
+#else
+#define UPB_INLINE static
+#endif
+
+/* Define UPB_BIG_ENDIAN manually if you're on big endian and your compiler
+ * doesn't provide these preprocessor symbols. */
+#if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
+#define UPB_BIG_ENDIAN
+#endif
+
+/* Macros for function attributes on compilers that support them. */
+#ifdef __GNUC__
+#define UPB_FORCEINLINE __inline__ __attribute__((always_inline))
+#define UPB_NOINLINE __attribute__((noinline))
+#define UPB_NORETURN __attribute__((__noreturn__))
+#else /* !defined(__GNUC__) */
+#define UPB_FORCEINLINE
+#define UPB_NOINLINE
+#define UPB_NORETURN
+#endif
+
+/* A few hacky workarounds for functions not in C89.
+ * For internal use only!
+ * TODO(haberman): fix these by including our own implementations, or finding
+ * another workaround.
+ */
+#ifdef __GNUC__
+#define _upb_snprintf __builtin_snprintf
+#define _upb_vsnprintf __builtin_vsnprintf
+#define _upb_va_copy(a, b) __va_copy(a, b)
+#elif __STDC_VERSION__ >= 199901L
+/* C99 versions. */
+#define _upb_snprintf snprintf
+#define _upb_vsnprintf vsnprintf
+#define _upb_va_copy(a, b) va_copy(a, b)
+#else
+#error Need implementations of [v]snprintf and va_copy
+#endif
+
+
+#if ((defined(__cplusplus) && __cplusplus >= 201103L) || \
+ defined(__GXX_EXPERIMENTAL_CXX0X__)) && !defined(UPB_NO_CXX11)
+#define UPB_CXX11
+#endif
+
+/* UPB_DISALLOW_COPY_AND_ASSIGN()
+ * UPB_DISALLOW_POD_OPS()
+ *
+ * Declare these in the "private" section of a C++ class to forbid copy/assign
+ * or all POD ops (construct, destruct, copy, assign) on that class. */
+#ifdef UPB_CXX11
+#include <type_traits>
+#define UPB_DISALLOW_COPY_AND_ASSIGN(class_name) \
+ class_name(const class_name&) = delete; \
+ void operator=(const class_name&) = delete;
+#define UPB_DISALLOW_POD_OPS(class_name, full_class_name) \
+ class_name() = delete; \
+ ~class_name() = delete; \
+ UPB_DISALLOW_COPY_AND_ASSIGN(class_name)
+#define UPB_ASSERT_STDLAYOUT(type) \
+ static_assert(std::is_standard_layout<type>::value, \
+ #type " must be standard layout");
+#else /* !defined(UPB_CXX11) */
+#define UPB_DISALLOW_COPY_AND_ASSIGN(class_name) \
+ class_name(const class_name&); \
+ void operator=(const class_name&);
+#define UPB_DISALLOW_POD_OPS(class_name, full_class_name) \
+ class_name(); \
+ ~class_name(); \
+ UPB_DISALLOW_COPY_AND_ASSIGN(class_name)
+#define UPB_ASSERT_STDLAYOUT(type)
+#endif
+
+/* UPB_DECLARE_TYPE()
+ * UPB_DECLARE_DERIVED_TYPE()
+ * UPB_DECLARE_DERIVED_TYPE2()
+ *
+ * Macros for declaring C and C++ types both, including inheritance.
+ * The inheritance doesn't use real C++ inheritance, to stay compatible with C.
+ *
+ * These macros also provide upcasts:
+ * - in C: types-specific functions (ie. upb_foo_upcast(foo))
+ * - in C++: upb::upcast(foo) along with implicit conversions
+ *
+ * Downcasts are not provided, but upb/def.h defines downcasts for upb::Def. */
+
+#define UPB_C_UPCASTS(ty, base) \
+ UPB_INLINE base *ty ## _upcast_mutable(ty *p) { return (base*)p; } \
+ UPB_INLINE const base *ty ## _upcast(const ty *p) { return (const base*)p; }
+
+#define UPB_C_UPCASTS2(ty, base, base2) \
+ UPB_C_UPCASTS(ty, base) \
+ UPB_INLINE base2 *ty ## _upcast2_mutable(ty *p) { return (base2*)p; } \
+ UPB_INLINE const base2 *ty ## _upcast2(const ty *p) { return (const base2*)p; }
+
+#ifdef __cplusplus
+
+#define UPB_BEGIN_EXTERN_C extern "C" {
+#define UPB_END_EXTERN_C }
+#define UPB_PRIVATE_FOR_CPP private:
+#define UPB_DECLARE_TYPE(cppname, cname) typedef cppname cname;
+
+#define UPB_DECLARE_DERIVED_TYPE(cppname, cppbase, cname, cbase) \
+ UPB_DECLARE_TYPE(cppname, cname) \
+ UPB_C_UPCASTS(cname, cbase) \
+ namespace upb { \
+ template <> \
+ class Pointer<cppname> : public PointerBase<cppname, cppbase> { \
+ public: \
+ explicit Pointer(cppname* ptr) : PointerBase(ptr) {} \
+ }; \
+ template <> \
+ class Pointer<const cppname> \
+ : public PointerBase<const cppname, const cppbase> { \
+ public: \
+ explicit Pointer(const cppname* ptr) : PointerBase(ptr) {} \
+ }; \
+ }
+
+#define UPB_DECLARE_DERIVED_TYPE2(cppname, cppbase, cppbase2, cname, cbase, \
+ cbase2) \
+ UPB_DECLARE_TYPE(cppname, cname) \
+ UPB_C_UPCASTS2(cname, cbase, cbase2) \
+ namespace upb { \
+ template <> \
+ class Pointer<cppname> : public PointerBase2<cppname, cppbase, cppbase2> { \
+ public: \
+ explicit Pointer(cppname* ptr) : PointerBase2(ptr) {} \
+ }; \
+ template <> \
+ class Pointer<const cppname> \
+ : public PointerBase2<const cppname, const cppbase, const cppbase2> { \
+ public: \
+ explicit Pointer(const cppname* ptr) : PointerBase2(ptr) {} \
+ }; \
+ }
+
+#else /* !defined(__cplusplus) */
+
+#define UPB_BEGIN_EXTERN_C
+#define UPB_END_EXTERN_C
+#define UPB_PRIVATE_FOR_CPP
+#define UPB_DECLARE_TYPE(cppname, cname) \
+ struct cname; \
+ typedef struct cname cname;
+#define UPB_DECLARE_DERIVED_TYPE(cppname, cppbase, cname, cbase) \
+ UPB_DECLARE_TYPE(cppname, cname) \
+ UPB_C_UPCASTS(cname, cbase)
+#define UPB_DECLARE_DERIVED_TYPE2(cppname, cppbase, cppbase2, \
+ cname, cbase, cbase2) \
+ UPB_DECLARE_TYPE(cppname, cname) \
+ UPB_C_UPCASTS2(cname, cbase, cbase2)
+
+#endif /* defined(__cplusplus) */
+
+#define UPB_MAX(x, y) ((x) > (y) ? (x) : (y))
+#define UPB_MIN(x, y) ((x) < (y) ? (x) : (y))
+
+#define UPB_UNUSED(var) (void)var
+
+/* For asserting something about a variable when the variable is not used for
+ * anything else. This prevents "unused variable" warnings when compiling in
+ * debug mode. */
+#define UPB_ASSERT_VAR(var, predicate) UPB_UNUSED(var); assert(predicate)
+
+/* Generic function type. */
+typedef void upb_func();
+
+/* C++ Casts ******************************************************************/
+
+#ifdef __cplusplus
+
+namespace upb {
+
+template <class T> class Pointer;
+
+/* Casts to a subclass. The caller must know that cast is correct; an
+ * incorrect cast will throw an assertion failure in debug mode.
+ *
+ * Example:
+ * upb::Def* def = GetDef();
+ * // Assert-fails if this was not actually a MessageDef.
+ * upb::MessgeDef* md = upb::down_cast<upb::MessageDef>(def);
+ *
+ * Note that downcasts are only defined for some types (at the moment you can
+ * only downcast from a upb::Def to a specific Def type). */
+template<class To, class From> To down_cast(From* f);
+
+/* Casts to a subclass. If the class does not actually match the given To type,
+ * returns NULL.
+ *
+ * Example:
+ * upb::Def* def = GetDef();
+ * // md will be NULL if this was not actually a MessageDef.
+ * upb::MessgeDef* md = upb::down_cast<upb::MessageDef>(def);
+ *
+ * Note that dynamic casts are only defined for some types (at the moment you
+ * can only downcast from a upb::Def to a specific Def type).. */
+template<class To, class From> To dyn_cast(From* f);
+
+/* Casts to any base class, or the type itself (ie. can be a no-op).
+ *
+ * Example:
+ * upb::MessageDef* md = GetDef();
+ * // This will fail to compile if this wasn't actually a base class.
+ * upb::Def* def = upb::upcast(md);
+ */
+template <class T> inline Pointer<T> upcast(T *f) { return Pointer<T>(f); }
+
+/* Attempt upcast to specific base class.
+ *
+ * Example:
+ * upb::MessageDef* md = GetDef();
+ * upb::upcast_to<upb::Def>(md)->MethodOnDef();
+ */
+template <class T, class F> inline T* upcast_to(F *f) {
+ return static_cast<T*>(upcast(f));
+}
+
+/* PointerBase<T>: implementation detail of upb::upcast().
+ * It is implicitly convertable to pointers to the Base class(es).
+ */
+template <class T, class Base>
+class PointerBase {
+ public:
+ explicit PointerBase(T* ptr) : ptr_(ptr) {}
+ operator T*() { return ptr_; }
+ operator Base*() { return (Base*)ptr_; }
+
+ private:
+ T* ptr_;
+};
+
+template <class T, class Base, class Base2>
+class PointerBase2 : public PointerBase<T, Base> {
+ public:
+ explicit PointerBase2(T* ptr) : PointerBase<T, Base>(ptr) {}
+ operator Base2*() { return Pointer<Base>(*this); }
+};
+
+}
+
+#endif
+
+
+/* upb::reffed_ptr ************************************************************/
+
+#ifdef __cplusplus
+
+#include <algorithm> /* For std::swap(). */
+
+namespace upb {
+
+/* Provides RAII semantics for upb refcounted objects. Each reffed_ptr owns a
+ * ref on whatever object it points to (if any). */
+template <class T> class reffed_ptr {
+ public:
+ reffed_ptr() : ptr_(NULL) {}
+
+ /* If ref_donor is NULL, takes a new ref, otherwise adopts from ref_donor. */
+ template <class U>
+ reffed_ptr(U* val, const void* ref_donor = NULL)
+ : ptr_(upb::upcast(val)) {
+ if (ref_donor) {
+ assert(ptr_);
+ ptr_->DonateRef(ref_donor, this);
+ } else if (ptr_) {
+ ptr_->Ref(this);
+ }
+ }
+
+ template <class U>
+ reffed_ptr(const reffed_ptr<U>& other)
+ : ptr_(upb::upcast(other.get())) {
+ if (ptr_) ptr_->Ref(this);
+ }
+
+ ~reffed_ptr() { if (ptr_) ptr_->Unref(this); }
+
+ template <class U>
+ reffed_ptr& operator=(const reffed_ptr<U>& other) {
+ reset(other.get());
+ return *this;
+ }
+
+ reffed_ptr& operator=(const reffed_ptr& other) {
+ reset(other.get());
+ return *this;
+ }
+
+ /* TODO(haberman): add C++11 move construction/assignment for greater
+ * efficiency. */
+
+ void swap(reffed_ptr& other) {
+ if (ptr_ == other.ptr_) {
+ return;
+ }
+
+ if (ptr_) ptr_->DonateRef(this, &other);
+ if (other.ptr_) other.ptr_->DonateRef(&other, this);
+ std::swap(ptr_, other.ptr_);
+ }
+
+ T& operator*() const {
+ assert(ptr_);
+ return *ptr_;
+ }
+
+ T* operator->() const {
+ assert(ptr_);
+ return ptr_;
+ }
+
+ T* get() const { return ptr_; }
+
+ /* If ref_donor is NULL, takes a new ref, otherwise adopts from ref_donor. */
+ template <class U>
+ void reset(U* ptr = NULL, const void* ref_donor = NULL) {
+ reffed_ptr(ptr, ref_donor).swap(*this);
+ }
+
+ template <class U>
+ reffed_ptr<U> down_cast() {
+ return reffed_ptr<U>(upb::down_cast<U*>(get()));
+ }
+
+ template <class U>
+ reffed_ptr<U> dyn_cast() {
+ return reffed_ptr<U>(upb::dyn_cast<U*>(get()));
+ }
+
+ /* Plain release() is unsafe; if we were the only owner, it would leak the
+ * object. Instead we provide this: */
+ T* ReleaseTo(const void* new_owner) {
+ T* ret = NULL;
+ ptr_->DonateRef(this, new_owner);
+ std::swap(ret, ptr_);
+ return ret;
+ }
+
+ private:
+ T* ptr_;
+};
+
+} /* namespace upb */
+
+#endif /* __cplusplus */
+
+
+/* upb::Status ****************************************************************/
+
+#ifdef __cplusplus
+namespace upb {
+class ErrorSpace;
+class Status;
+}
+#endif
+
+UPB_DECLARE_TYPE(upb::ErrorSpace, upb_errorspace)
+UPB_DECLARE_TYPE(upb::Status, upb_status)
+
+/* The maximum length of an error message before it will get truncated. */
+#define UPB_STATUS_MAX_MESSAGE 128
+
+/* An error callback function is used to report errors from some component.
+ * The function can return "true" to indicate that the component should try
+ * to recover and proceed, but this is not always possible. */
+typedef bool upb_errcb_t(void *closure, const upb_status* status);
+
+#ifdef __cplusplus
+class upb::ErrorSpace {
+#else
+struct upb_errorspace {
+#endif
+ const char *name;
+ /* Should the error message in the status object according to this code. */
+ void (*set_message)(upb_status* status, int code);
+};
+
+#ifdef __cplusplus
+
+/* Object representing a success or failure status.
+ * It owns no resources and allocates no memory, so it should work
+ * even in OOM situations. */
+
+class upb::Status {
+ public:
+ Status();
+
+ /* Returns true if there is no error. */
+ bool ok() const;
+
+ /* Optional error space and code, useful if the caller wants to
+ * programmatically check the specific kind of error. */
+ ErrorSpace* error_space();
+ int code() const;
+
+ const char *error_message() const;
+
+ /* The error message will be truncated if it is longer than
+ * UPB_STATUS_MAX_MESSAGE-4. */
+ void SetErrorMessage(const char* msg);
+ void SetFormattedErrorMessage(const char* fmt, ...);
+
+ /* If there is no error message already, this will use the ErrorSpace to
+ * populate the error message for this code. The caller can still call
+ * SetErrorMessage() to give a more specific message. */
+ void SetErrorCode(ErrorSpace* space, int code);
+
+ /* Resets the status to a successful state with no message. */
+ void Clear();
+
+ void CopyFrom(const Status& other);
+
+ private:
+ UPB_DISALLOW_COPY_AND_ASSIGN(Status)
+#else
+struct upb_status {
+#endif
+ bool ok_;
+
+ /* Specific status code defined by some error space (optional). */
+ int code_;
+ upb_errorspace *error_space_;
+
+ /* Error message; NULL-terminated. */
+ char msg[UPB_STATUS_MAX_MESSAGE];
+};
+
+#define UPB_STATUS_INIT {true, 0, NULL, {0}}
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* The returned string is invalidated by any other call into the status. */
+const char *upb_status_errmsg(const upb_status *status);
+bool upb_ok(const upb_status *status);
+upb_errorspace *upb_status_errspace(const upb_status *status);
+int upb_status_errcode(const upb_status *status);
+
+/* Any of the functions that write to a status object allow status to be NULL,
+ * to support use cases where the function's caller does not care about the
+ * status message. */
+void upb_status_clear(upb_status *status);
+void upb_status_seterrmsg(upb_status *status, const char *msg);
+void upb_status_seterrf(upb_status *status, const char *fmt, ...);
+void upb_status_vseterrf(upb_status *status, const char *fmt, va_list args);
+void upb_status_seterrcode(upb_status *status, upb_errorspace *space, int code);
+void upb_status_copy(upb_status *to, const upb_status *from);
+
+#ifdef __cplusplus
+} /* extern "C" */
+
+namespace upb {
+
+/* C++ Wrappers */
+inline Status::Status() { Clear(); }
+inline bool Status::ok() const { return upb_ok(this); }
+inline const char* Status::error_message() const {
+ return upb_status_errmsg(this);
+}
+inline void Status::SetErrorMessage(const char* msg) {
+ upb_status_seterrmsg(this, msg);
+}
+inline void Status::SetFormattedErrorMessage(const char* fmt, ...) {
+ va_list args;
+ va_start(args, fmt);
+ upb_status_vseterrf(this, fmt, args);
+ va_end(args);
+}
+inline void Status::SetErrorCode(ErrorSpace* space, int code) {
+ upb_status_seterrcode(this, space, code);
+}
+inline void Status::Clear() { upb_status_clear(this); }
+inline void Status::CopyFrom(const Status& other) {
+ upb_status_copy(this, &other);
+}
+
+} /* namespace upb */
+
+#endif
+
+#endif /* UPB_H_ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* upb_value ******************************************************************/
+
+/* A tagged union (stored untagged inside the table) so that we can check that
+ * clients calling table accessors are correctly typed without having to have
+ * an explosion of accessors. */
+typedef enum {
+ UPB_CTYPE_INT32 = 1,
+ UPB_CTYPE_INT64 = 2,
+ UPB_CTYPE_UINT32 = 3,
+ UPB_CTYPE_UINT64 = 4,
+ UPB_CTYPE_BOOL = 5,
+ UPB_CTYPE_CSTR = 6,
+ UPB_CTYPE_PTR = 7,
+ UPB_CTYPE_CONSTPTR = 8,
+ UPB_CTYPE_FPTR = 9
+} upb_ctype_t;
+
+typedef struct {
+ uint64_t val;
+#ifndef NDEBUG
+ /* In debug mode we carry the value type around also so we can check accesses
+ * to be sure the right member is being read. */
+ upb_ctype_t ctype;
+#endif
+} upb_value;
+
+#ifdef NDEBUG
+#define SET_TYPE(dest, val) UPB_UNUSED(val)
+#else
+#define SET_TYPE(dest, val) dest = val
+#endif
+
+/* Like strdup(), which isn't always available since it's not ANSI C. */
+char *upb_strdup(const char *s);
+/* Variant that works with a length-delimited rather than NULL-delimited string,
+ * as supported by strtable. */
+char *upb_strdup2(const char *s, size_t len);
+
+UPB_INLINE void _upb_value_setval(upb_value *v, uint64_t val,
+ upb_ctype_t ctype) {
+ v->val = val;
+ SET_TYPE(v->ctype, ctype);
+}
+
+UPB_INLINE upb_value _upb_value_val(uint64_t val, upb_ctype_t ctype) {
+ upb_value ret;
+ _upb_value_setval(&ret, val, ctype);
+ return ret;
+}
+
+/* For each value ctype, define the following set of functions:
+ *
+ * // Get/set an int32 from a upb_value.
+ * int32_t upb_value_getint32(upb_value val);
+ * void upb_value_setint32(upb_value *val, int32_t cval);
+ *
+ * // Construct a new upb_value from an int32.
+ * upb_value upb_value_int32(int32_t val); */
+#define FUNCS(name, membername, type_t, converter, proto_type) \
+ UPB_INLINE void upb_value_set ## name(upb_value *val, type_t cval) { \
+ val->val = (converter)cval; \
+ SET_TYPE(val->ctype, proto_type); \
+ } \
+ UPB_INLINE upb_value upb_value_ ## name(type_t val) { \
+ upb_value ret; \
+ upb_value_set ## name(&ret, val); \
+ return ret; \
+ } \
+ UPB_INLINE type_t upb_value_get ## name(upb_value val) { \
+ assert(val.ctype == proto_type); \
+ return (type_t)(converter)val.val; \
+ }
+
+FUNCS(int32, int32, int32_t, int32_t, UPB_CTYPE_INT32)
+FUNCS(int64, int64, int64_t, int64_t, UPB_CTYPE_INT64)
+FUNCS(uint32, uint32, uint32_t, uint32_t, UPB_CTYPE_UINT32)
+FUNCS(uint64, uint64, uint64_t, uint64_t, UPB_CTYPE_UINT64)
+FUNCS(bool, _bool, bool, bool, UPB_CTYPE_BOOL)
+FUNCS(cstr, cstr, char*, uintptr_t, UPB_CTYPE_CSTR)
+FUNCS(ptr, ptr, void*, uintptr_t, UPB_CTYPE_PTR)
+FUNCS(constptr, constptr, const void*, uintptr_t, UPB_CTYPE_CONSTPTR)
+FUNCS(fptr, fptr, upb_func*, uintptr_t, UPB_CTYPE_FPTR)
+
+#undef FUNCS
+#undef SET_TYPE
+
+
+/* upb_tabkey *****************************************************************/
+
+/* Either:
+ * 1. an actual integer key, or
+ * 2. a pointer to a string prefixed by its uint32_t length, owned by us.
+ *
+ * ...depending on whether this is a string table or an int table. We would
+ * make this a union of those two types, but C89 doesn't support statically
+ * initializing a non-first union member. */
+typedef uintptr_t upb_tabkey;
+
+#define UPB_TABKEY_NUM(n) n
+#define UPB_TABKEY_NONE 0
+/* The preprocessor isn't quite powerful enough to turn the compile-time string
+ * length into a byte-wise string representation, so code generation needs to
+ * help it along.
+ *
+ * "len1" is the low byte and len4 is the high byte. */
+#ifdef UPB_BIG_ENDIAN
+#define UPB_TABKEY_STR(len1, len2, len3, len4, strval) \
+ (uintptr_t)(len4 len3 len2 len1 strval)
+#else
+#define UPB_TABKEY_STR(len1, len2, len3, len4, strval) \
+ (uintptr_t)(len1 len2 len3 len4 strval)
+#endif
+
+UPB_INLINE char *upb_tabstr(upb_tabkey key, uint32_t *len) {
+ char* mem = (char*)key;
+ if (len) memcpy(len, mem, sizeof(*len));
+ return mem + sizeof(*len);
+}
+
+
+/* upb_tabval *****************************************************************/
+
+#ifdef __cplusplus
+
+/* Status initialization not supported.
+ *
+ * This separate definition is necessary because in C++, UINTPTR_MAX isn't
+ * reliably available. */
+typedef struct {
+ uint64_t val;
+} upb_tabval;
+
+#else
+
+/* C -- supports static initialization, but to support static initialization of
+ * both integers and points for both 32 and 64 bit targets, it takes a little
+ * bit of doing. */
+
+#if UINTPTR_MAX == 0xffffffffffffffffULL
+#define UPB_PTR_IS_64BITS
+#elif UINTPTR_MAX != 0xffffffff
+#error Could not determine how many bits pointers are.
+#endif
+
+typedef union {
+ /* For static initialization.
+ *
+ * Unfortunately this ugliness is necessary -- it is the only way that we can,
+ * with -std=c89 -pedantic, statically initialize this to either a pointer or
+ * an integer on 32-bit platforms. */
+ struct {
+#ifdef UPB_PTR_IS_64BITS
+ uintptr_t val;
+#else
+ uintptr_t val1;
+ uintptr_t val2;
+#endif
+ } staticinit;
+
+ /* The normal accessor that we use for everything at runtime. */
+ uint64_t val;
+} upb_tabval;
+
+#ifdef UPB_PTR_IS_64BITS
+#define UPB_TABVALUE_INT_INIT(v) {{v}}
+#define UPB_TABVALUE_EMPTY_INIT {{-1}}
+#else
+
+/* 32-bit pointers */
+
+#ifdef UPB_BIG_ENDIAN
+#define UPB_TABVALUE_INT_INIT(v) {{0, v}}
+#define UPB_TABVALUE_EMPTY_INIT {{-1, -1}}
+#else
+#define UPB_TABVALUE_INT_INIT(v) {{v, 0}}
+#define UPB_TABVALUE_EMPTY_INIT {{-1, -1}}
+#endif
+
+#endif
+
+#define UPB_TABVALUE_PTR_INIT(v) UPB_TABVALUE_INT_INIT((uintptr_t)v)
+
+#undef UPB_PTR_IS_64BITS
+
+#endif /* __cplusplus */
+
+
+/* upb_table ******************************************************************/
+
+typedef struct _upb_tabent {
+ upb_tabkey key;
+ upb_tabval val;
+
+ /* Internal chaining. This is const so we can create static initializers for
+ * tables. We cast away const sometimes, but *only* when the containing
+ * upb_table is known to be non-const. This requires a bit of care, but
+ * the subtlety is confined to table.c. */
+ const struct _upb_tabent *next;
+} upb_tabent;
+
+typedef struct {
+ size_t count; /* Number of entries in the hash part. */
+ size_t mask; /* Mask to turn hash value -> bucket. */
+ upb_ctype_t ctype; /* Type of all values. */
+ uint8_t size_lg2; /* Size of the hashtable part is 2^size_lg2 entries. */
+
+ /* Hash table entries.
+ * Making this const isn't entirely accurate; what we really want is for it to
+ * have the same const-ness as the table it's inside. But there's no way to
+ * declare that in C. So we have to make it const so that we can statically
+ * initialize const hash tables. Then we cast away const when we have to.
+ */
+ const upb_tabent *entries;
+} upb_table;
+
+typedef struct {
+ upb_table t;
+} upb_strtable;
+
+#define UPB_STRTABLE_INIT(count, mask, ctype, size_lg2, entries) \
+ {{count, mask, ctype, size_lg2, entries}}
+
+#define UPB_EMPTY_STRTABLE_INIT(ctype) \
+ UPB_STRTABLE_INIT(0, 0, ctype, 0, NULL)
+
+typedef struct {
+ upb_table t; /* For entries that don't fit in the array part. */
+ const upb_tabval *array; /* Array part of the table. See const note above. */
+ size_t array_size; /* Array part size. */
+ size_t array_count; /* Array part number of elements. */
+} upb_inttable;
+
+#define UPB_INTTABLE_INIT(count, mask, ctype, size_lg2, ent, a, asize, acount) \
+ {{count, mask, ctype, size_lg2, ent}, a, asize, acount}
+
+#define UPB_EMPTY_INTTABLE_INIT(ctype) \
+ UPB_INTTABLE_INIT(0, 0, ctype, 0, NULL, NULL, 0, 0)
+
+#define UPB_ARRAY_EMPTYENT -1
+
+UPB_INLINE size_t upb_table_size(const upb_table *t) {
+ if (t->size_lg2 == 0)
+ return 0;
+ else
+ return 1 << t->size_lg2;
+}
+
+/* Internal-only functions, in .h file only out of necessity. */
+UPB_INLINE bool upb_tabent_isempty(const upb_tabent *e) {
+ return e->key == 0;
+}
+
+/* Used by some of the unit tests for generic hashing functionality. */
+uint32_t MurmurHash2(const void * key, size_t len, uint32_t seed);
+
+UPB_INLINE uintptr_t upb_intkey(uintptr_t key) {
+ return key;
+}
+
+UPB_INLINE uint32_t upb_inthash(uintptr_t key) {
+ return (uint32_t)key;
+}
+
+static const upb_tabent *upb_getentry(const upb_table *t, uint32_t hash) {
+ return t->entries + (hash & t->mask);
+}
+
+UPB_INLINE bool upb_arrhas(upb_tabval key) {
+ return key.val != (uint64_t)-1;
+}
+
+/* Initialize and uninitialize a table, respectively. If memory allocation
+ * failed, false is returned that the table is uninitialized. */
+bool upb_inttable_init(upb_inttable *table, upb_ctype_t ctype);
+bool upb_strtable_init(upb_strtable *table, upb_ctype_t ctype);
+void upb_inttable_uninit(upb_inttable *table);
+void upb_strtable_uninit(upb_strtable *table);
+
+/* Returns the number of values in the table. */
+size_t upb_inttable_count(const upb_inttable *t);
+UPB_INLINE size_t upb_strtable_count(const upb_strtable *t) {
+ return t->t.count;
+}
+
+/* Inserts the given key into the hashtable with the given value. The key must
+ * not already exist in the hash table. For string tables, the key must be
+ * NULL-terminated, and the table will make an internal copy of the key.
+ * Inttables must not insert a value of UINTPTR_MAX.
+ *
+ * If a table resize was required but memory allocation failed, false is
+ * returned and the table is unchanged. */
+bool upb_inttable_insert(upb_inttable *t, uintptr_t key, upb_value val);
+bool upb_strtable_insert2(upb_strtable *t, const char *key, size_t len,
+ upb_value val);
+
+/* For NULL-terminated strings. */
+UPB_INLINE bool upb_strtable_insert(upb_strtable *t, const char *key,
+ upb_value val) {
+ return upb_strtable_insert2(t, key, strlen(key), val);
+}
+
+/* Looks up key in this table, returning "true" if the key was found.
+ * If v is non-NULL, copies the value for this key into *v. */
+bool upb_inttable_lookup(const upb_inttable *t, uintptr_t key, upb_value *v);
+bool upb_strtable_lookup2(const upb_strtable *t, const char *key, size_t len,
+ upb_value *v);
+
+/* For NULL-terminated strings. */
+UPB_INLINE bool upb_strtable_lookup(const upb_strtable *t, const char *key,
+ upb_value *v) {
+ return upb_strtable_lookup2(t, key, strlen(key), v);
+}
+
+/* Removes an item from the table. Returns true if the remove was successful,
+ * and stores the removed item in *val if non-NULL. */
+bool upb_inttable_remove(upb_inttable *t, uintptr_t key, upb_value *val);
+bool upb_strtable_remove2(upb_strtable *t, const char *key, size_t len,
+ upb_value *val);
+
+/* For NULL-terminated strings. */
+UPB_INLINE bool upb_strtable_remove(upb_strtable *t, const char *key,
+ upb_value *v) {
+ return upb_strtable_remove2(t, key, strlen(key), v);
+}
+
+/* Updates an existing entry in an inttable. If the entry does not exist,
+ * returns false and does nothing. Unlike insert/remove, this does not
+ * 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_push(upb_inttable *t, upb_value val);
+upb_value upb_inttable_pop(upb_inttable *t);
+
+/* Convenience routines for inttables with pointer keys. */
+bool upb_inttable_insertptr(upb_inttable *t, const void *key, upb_value val);
+bool upb_inttable_removeptr(upb_inttable *t, const void *key, upb_value *val);
+bool upb_inttable_lookupptr(
+ const upb_inttable *t, const void *key, upb_value *val);
+
+/* Optimizes the table for the current set of entries, for both memory use and
+ * lookup time. Client should call this after all entries have been inserted;
+ * inserting more entries is legal, but will likely require a table resize. */
+void upb_inttable_compact(upb_inttable *t);
+
+/* A special-case inlinable version of the lookup routine for 32-bit
+ * integers. */
+UPB_INLINE bool upb_inttable_lookup32(const upb_inttable *t, uint32_t key,
+ upb_value *v) {
+ *v = upb_value_int32(0); /* Silence compiler warnings. */
+ if (key < t->array_size) {
+ upb_tabval arrval = t->array[key];
+ if (upb_arrhas(arrval)) {
+ _upb_value_setval(v, arrval.val, t->t.ctype);
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ const upb_tabent *e;
+ if (t->t.entries == NULL) return false;
+ for (e = upb_getentry(&t->t, upb_inthash(key)); true; e = e->next) {
+ if ((uint32_t)e->key == key) {
+ _upb_value_setval(v, e->val.val, t->t.ctype);
+ return true;
+ }
+ if (e->next == NULL) return false;
+ }
+ }
+}
+
+/* Exposed for testing only. */
+bool upb_strtable_resize(upb_strtable *t, size_t size_lg2);
+
+/* Iterators ******************************************************************/
+
+/* Iterators for int and string tables. We are subject to some kind of unusual
+ * design constraints:
+ *
+ * For high-level languages:
+ * - we must be able to guarantee that we don't crash or corrupt memory even if
+ * the program accesses an invalidated iterator.
+ *
+ * For C++11 range-based for:
+ * - iterators must be copyable
+ * - iterators must be comparable
+ * - it must be possible to construct an "end" value.
+ *
+ * Iteration order is undefined.
+ *
+ * Modifying the table invalidates iterators. upb_{str,int}table_done() is
+ * guaranteed to work even on an invalidated iterator, as long as the table it
+ * is iterating over has not been freed. Calling next() or accessing data from
+ * an invalidated iterator yields unspecified elements from the table, but it is
+ * guaranteed not to crash and to return real table elements (except when done()
+ * is true). */
+
+
+/* upb_strtable_iter **********************************************************/
+
+/* upb_strtable_iter i;
+ * upb_strtable_begin(&i, t);
+ * for(; !upb_strtable_done(&i); upb_strtable_next(&i)) {
+ * const char *key = upb_strtable_iter_key(&i);
+ * const upb_value val = upb_strtable_iter_value(&i);
+ * // ...
+ * }
+ */
+
+typedef struct {
+ const upb_strtable *t;
+ size_t index;
+} upb_strtable_iter;
+
+void upb_strtable_begin(upb_strtable_iter *i, const upb_strtable *t);
+void upb_strtable_next(upb_strtable_iter *i);
+bool upb_strtable_done(const upb_strtable_iter *i);
+const char *upb_strtable_iter_key(upb_strtable_iter *i);
+size_t upb_strtable_iter_keylength(upb_strtable_iter *i);
+upb_value upb_strtable_iter_value(const upb_strtable_iter *i);
+void upb_strtable_iter_setdone(upb_strtable_iter *i);
+bool upb_strtable_iter_isequal(const upb_strtable_iter *i1,
+ const upb_strtable_iter *i2);
+
+
+/* upb_inttable_iter **********************************************************/
+
+/* upb_inttable_iter i;
+ * upb_inttable_begin(&i, t);
+ * for(; !upb_inttable_done(&i); upb_inttable_next(&i)) {
+ * uintptr_t key = upb_inttable_iter_key(&i);
+ * upb_value val = upb_inttable_iter_value(&i);
+ * // ...
+ * }
+ */
+
+typedef struct {
+ const upb_inttable *t;
+ size_t index;
+ bool array_part;
+} upb_inttable_iter;
+
+void upb_inttable_begin(upb_inttable_iter *i, const upb_inttable *t);
+void upb_inttable_next(upb_inttable_iter *i);
+bool upb_inttable_done(const upb_inttable_iter *i);
+uintptr_t upb_inttable_iter_key(const upb_inttable_iter *i);
+upb_value upb_inttable_iter_value(const upb_inttable_iter *i);
+void upb_inttable_iter_setdone(upb_inttable_iter *i);
+bool upb_inttable_iter_isequal(const upb_inttable_iter *i1,
+ const upb_inttable_iter *i2);
+
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* UPB_TABLE_H_ */
+
+/* Reference tracking will check ref()/unref() operations to make sure the
+ * ref ownership is correct. Where possible it will also make tools like
+ * Valgrind attribute ref leaks to the code that took the leaked ref, not
+ * the code that originally created the object.
+ *
+ * Enabling this requires the application to define upb_lock()/upb_unlock()
+ * functions that acquire/release a global mutex (or #define UPB_THREAD_UNSAFE).
+ * For this reason we don't enable it by default, even in debug builds.
+ */
+
+/* #define UPB_DEBUG_REFS */
+
+#ifdef __cplusplus
+namespace upb { class RefCounted; }
+#endif
+
+UPB_DECLARE_TYPE(upb::RefCounted, upb_refcounted)
+
+struct upb_refcounted_vtbl;
+
+#ifdef __cplusplus
+
+class upb::RefCounted {
+ public:
+ /* Returns true if the given object is frozen. */
+ bool IsFrozen() const;
+
+ /* Increases the ref count, the new ref is owned by "owner" which must not
+ * already own a ref (and should not itself be a refcounted object if the ref
+ * could possibly be circular; see below).
+ * Thread-safe iff "this" is frozen. */
+ void Ref(const void *owner) const;
+
+ /* Release a ref that was acquired from upb_refcounted_ref() and collects any
+ * objects it can. */
+ void Unref(const void *owner) const;
+
+ /* Moves an existing ref from "from" to "to", without changing the overall
+ * ref count. DonateRef(foo, NULL, owner) is the same as Ref(foo, owner),
+ * but "to" may not be NULL. */
+ void DonateRef(const void *from, const void *to) const;
+
+ /* Verifies that a ref to the given object is currently held by the given
+ * owner. Only effective in UPB_DEBUG_REFS builds. */
+ void CheckRef(const void *owner) const;
+
+ private:
+ UPB_DISALLOW_POD_OPS(RefCounted, upb::RefCounted)
+#else
+struct upb_refcounted {
+#endif
+ /* TODO(haberman): move the actual structure definition to structdefs.int.h.
+ * The only reason they are here is because inline functions need to see the
+ * definition of upb_handlers, which needs to see this definition. But we
+ * can change the upb_handlers inline functions to deal in raw offsets
+ * instead.
+ */
+
+ /* A single reference count shared by all objects in the group. */
+ uint32_t *group;
+
+ /* A singly-linked list of all objects in the group. */
+ upb_refcounted *next;
+
+ /* Table of function pointers for this type. */
+ const struct upb_refcounted_vtbl *vtbl;
+
+ /* Maintained only when mutable, this tracks the number of refs (but not
+ * ref2's) to this object. *group should be the sum of all individual_count
+ * in the group. */
+ uint32_t individual_count;
+
+ bool is_frozen;
+
+#ifdef UPB_DEBUG_REFS
+ upb_inttable *refs; /* Maps owner -> trackedref for incoming refs. */
+ upb_inttable *ref2s; /* Set of targets for outgoing ref2s. */
+#endif
+};
+
+#ifdef UPB_DEBUG_REFS
+#define UPB_REFCOUNT_INIT(refs, ref2s) \
+ {&static_refcount, NULL, NULL, 0, true, refs, ref2s}
+#else
+#define UPB_REFCOUNT_INIT(refs, ref2s) {&static_refcount, NULL, NULL, 0, true}
+#endif
+
+UPB_BEGIN_EXTERN_C
+
+/* It is better to use tracked refs when possible, for the extra debugging
+ * capability. But if this is not possible (because you don't have easy access
+ * to a stable pointer value that is associated with the ref), you can pass
+ * UPB_UNTRACKED_REF instead. */
+extern const void *UPB_UNTRACKED_REF;
+
+/* Native C API. */
+bool upb_refcounted_isfrozen(const upb_refcounted *r);
+void upb_refcounted_ref(const upb_refcounted *r, const void *owner);
+void upb_refcounted_unref(const upb_refcounted *r, const void *owner);
+void upb_refcounted_donateref(
+ const upb_refcounted *r, const void *from, const void *to);
+void upb_refcounted_checkref(const upb_refcounted *r, const void *owner);
+
+#define UPB_REFCOUNTED_CMETHODS(type, upcastfunc) \
+ UPB_INLINE bool type ## _isfrozen(const type *v) { \
+ return upb_refcounted_isfrozen(upcastfunc(v)); \
+ } \
+ UPB_INLINE void type ## _ref(const type *v, const void *owner) { \
+ upb_refcounted_ref(upcastfunc(v), owner); \
+ } \
+ UPB_INLINE void type ## _unref(const type *v, const void *owner) { \
+ upb_refcounted_unref(upcastfunc(v), owner); \
+ } \
+ UPB_INLINE void type ## _donateref(const type *v, const void *from, const void *to) { \
+ upb_refcounted_donateref(upcastfunc(v), from, to); \
+ } \
+ UPB_INLINE void type ## _checkref(const type *v, const void *owner) { \
+ upb_refcounted_checkref(upcastfunc(v), owner); \
+ }
+
+#define UPB_REFCOUNTED_CPPMETHODS \
+ bool IsFrozen() const { \
+ return upb::upcast_to<const upb::RefCounted>(this)->IsFrozen(); \
+ } \
+ void Ref(const void *owner) const { \
+ return upb::upcast_to<const upb::RefCounted>(this)->Ref(owner); \
+ } \
+ void Unref(const void *owner) const { \
+ return upb::upcast_to<const upb::RefCounted>(this)->Unref(owner); \
+ } \
+ void DonateRef(const void *from, const void *to) const { \
+ return upb::upcast_to<const upb::RefCounted>(this)->DonateRef(from, to); \
+ } \
+ void CheckRef(const void *owner) const { \
+ return upb::upcast_to<const upb::RefCounted>(this)->CheckRef(owner); \
+ }
+
+/* Internal-to-upb Interface **************************************************/
+
+typedef void upb_refcounted_visit(const upb_refcounted *r,
+ const upb_refcounted *subobj,
+ void *closure);
+
+struct upb_refcounted_vtbl {
+ /* Must visit all subobjects that are currently ref'd via upb_refcounted_ref2.
+ * Must be longjmp()-safe. */
+ void (*visit)(const upb_refcounted *r, upb_refcounted_visit *visit, void *c);
+
+ /* Must free the object and release all references to other objects. */
+ void (*free)(upb_refcounted *r);
+};
+
+/* Initializes the refcounted with a single ref for the given owner. Returns
+ * false if memory could not be allocated. */
+bool upb_refcounted_init(upb_refcounted *r,
+ const struct upb_refcounted_vtbl *vtbl,
+ const void *owner);
+
+/* Adds a ref from one refcounted object to another ("from" must not already
+ * own a ref). These refs may be circular; cycles will be collected correctly
+ * (if conservatively). These refs do not need to be freed in from's free()
+ * function. */
+void upb_refcounted_ref2(const upb_refcounted *r, upb_refcounted *from);
+
+/* Removes a ref that was acquired from upb_refcounted_ref2(), and collects any
+ * object it can. This is only necessary when "from" no longer points to "r",
+ * and not from from's "free" function. */
+void upb_refcounted_unref2(const upb_refcounted *r, upb_refcounted *from);
+
+#define upb_ref2(r, from) \
+ upb_refcounted_ref2((const upb_refcounted*)r, (upb_refcounted*)from)
+#define upb_unref2(r, from) \
+ upb_refcounted_unref2((const upb_refcounted*)r, (upb_refcounted*)from)
+
+/* Freezes all mutable object reachable by ref2() refs from the given roots.
+ * This will split refcounting groups into precise SCC groups, so that
+ * refcounting of frozen objects can be more aggressive. If memory allocation
+ * fails, or if more than 2**31 mutable objects are reachable from "roots", or
+ * if the maximum depth of the graph exceeds "maxdepth", false is returned and
+ * the objects are unchanged.
+ *
+ * After this operation succeeds, the objects are frozen/const, and may not be
+ * used through non-const pointers. In particular, they may not be passed as
+ * the second parameter of upb_refcounted_{ref,unref}2(). On the upside, all
+ * operations on frozen refcounteds are threadsafe, and objects will be freed
+ * at the precise moment that they become unreachable.
+ *
+ * Caller must own refs on each object in the "roots" list. */
+bool upb_refcounted_freeze(upb_refcounted *const*roots, int n, upb_status *s,
+ int maxdepth);
+
+/* Shared by all compiled-in refcounted objects. */
+extern uint32_t static_refcount;
+
+UPB_END_EXTERN_C
+
+#ifdef __cplusplus
+/* C++ Wrappers. */
+namespace upb {
+inline bool RefCounted::IsFrozen() const {
+ return upb_refcounted_isfrozen(this);
+}
+inline void RefCounted::Ref(const void *owner) const {
+ upb_refcounted_ref(this, owner);
+}
+inline void RefCounted::Unref(const void *owner) const {
+ upb_refcounted_unref(this, owner);
+}
+inline void RefCounted::DonateRef(const void *from, const void *to) const {
+ upb_refcounted_donateref(this, from, to);
+}
+inline void RefCounted::CheckRef(const void *owner) const {
+ upb_refcounted_checkref(this, owner);
+}
+} /* namespace upb */
+#endif
+
+#endif /* UPB_REFCOUNT_H_ */
+
+#ifdef __cplusplus
+#include <cstring>
+#include <string>
+#include <vector>
+
+namespace upb {
+class Def;
+class EnumDef;
+class FieldDef;
+class MessageDef;
+class OneofDef;
+}
+#endif
+
+UPB_DECLARE_DERIVED_TYPE(upb::Def, upb::RefCounted, upb_def, upb_refcounted)
+
+/* The maximum message depth that the type graph can have. This is a resource
+ * limit for the C stack since we sometimes need to recursively traverse the
+ * graph. Cycles are ok; the traversal will stop when it detects a cycle, but
+ * we must hit the cycle before the maximum depth is reached.
+ *
+ * If having a single static limit is too inflexible, we can add another variant
+ * of Def::Freeze that allows specifying this as a parameter. */
+#define UPB_MAX_MESSAGE_DEPTH 64
+
+
+/* upb::Def: base class for defs *********************************************/
+
+/* All the different kind of defs we support. These correspond 1:1 with
+ * declarations in a .proto file. */
+typedef enum {
+ UPB_DEF_MSG,
+ UPB_DEF_FIELD,
+ UPB_DEF_ENUM,
+ UPB_DEF_ONEOF,
+ UPB_DEF_SERVICE, /* Not yet implemented. */
+ UPB_DEF_ANY = -1 /* Wildcard for upb_symtab_get*() */
+} upb_deftype_t;
+
+#ifdef __cplusplus
+
+/* The base class of all defs. Its base is upb::RefCounted (use upb::upcast()
+ * to convert). */
+class upb::Def {
+ public:
+ typedef upb_deftype_t Type;
+
+ Def* Dup(const void *owner) const;
+
+ /* upb::RefCounted methods like Ref()/Unref(). */
+ UPB_REFCOUNTED_CPPMETHODS
+
+ Type def_type() const;
+
+ /* "fullname" is the def's fully-qualified name (eg. foo.bar.Message). */
+ const char *full_name() const;
+
+ /* The def must be mutable. Caller retains ownership of fullname. Defs are
+ * not required to have a name; if a def has no name when it is frozen, it
+ * will remain an anonymous def. On failure, returns false and details in "s"
+ * if non-NULL. */
+ bool set_full_name(const char* fullname, upb::Status* s);
+ bool set_full_name(const std::string &fullname, upb::Status* s);
+
+ /* Freezes the given defs; this validates all constraints and marks the defs
+ * as frozen (read-only). "defs" may not contain any fielddefs, but fields
+ * of any msgdefs will be frozen.
+ *
+ * Symbolic references to sub-types and enum defaults must have already been
+ * resolved. Any mutable defs reachable from any of "defs" must also be in
+ * the list; more formally, "defs" must be a transitive closure of mutable
+ * defs.
+ *
+ * After this operation succeeds, the finalized defs must only be accessed
+ * through a const pointer! */
+ static bool Freeze(Def* const* defs, int n, Status* status);
+ static bool Freeze(const std::vector<Def*>& defs, Status* status);
+
+ private:
+ UPB_DISALLOW_POD_OPS(Def, upb::Def)
+};
+
+#endif /* __cplusplus */
+
+UPB_BEGIN_EXTERN_C
+
+/* Native C API. */
+upb_def *upb_def_dup(const upb_def *def, const void *owner);
+
+/* Include upb_refcounted methods like upb_def_ref()/upb_def_unref(). */
+UPB_REFCOUNTED_CMETHODS(upb_def, upb_def_upcast)
+
+upb_deftype_t upb_def_type(const upb_def *d);
+const char *upb_def_fullname(const upb_def *d);
+bool upb_def_setfullname(upb_def *def, const char *fullname, upb_status *s);
+bool upb_def_freeze(upb_def *const *defs, int n, upb_status *s);
+
+UPB_END_EXTERN_C
+
+
+/* upb::Def casts *************************************************************/
+
+#ifdef __cplusplus
+#define UPB_CPP_CASTS(cname, cpptype) \
+ namespace upb { \
+ template <> \
+ inline cpptype *down_cast<cpptype *, Def>(Def * def) { \
+ return upb_downcast_##cname##_mutable(def); \
+ } \
+ template <> \
+ inline cpptype *dyn_cast<cpptype *, Def>(Def * def) { \
+ return upb_dyncast_##cname##_mutable(def); \
+ } \
+ template <> \
+ inline const cpptype *down_cast<const cpptype *, const Def>( \
+ const Def *def) { \
+ return upb_downcast_##cname(def); \
+ } \
+ template <> \
+ inline const cpptype *dyn_cast<const cpptype *, const Def>(const Def *def) { \
+ return upb_dyncast_##cname(def); \
+ } \
+ template <> \
+ inline const cpptype *down_cast<const cpptype *, Def>(Def * def) { \
+ return upb_downcast_##cname(def); \
+ } \
+ template <> \
+ inline const cpptype *dyn_cast<const cpptype *, Def>(Def * def) { \
+ return upb_dyncast_##cname(def); \
+ } \
+ } /* namespace upb */
+#else
+#define UPB_CPP_CASTS(cname, cpptype)
+#endif /* __cplusplus */
+
+/* Dynamic casts, for determining if a def is of a particular type at runtime.
+ * Downcasts, for when some wants to assert that a def is of a particular type.
+ * These are only checked if we are building debug. */
+#define UPB_DEF_CASTS(lower, upper, cpptype) \
+ UPB_INLINE const upb_##lower *upb_dyncast_##lower(const upb_def *def) { \
+ if (upb_def_type(def) != UPB_DEF_##upper) return NULL; \
+ return (upb_##lower *)def; \
+ } \
+ UPB_INLINE const upb_##lower *upb_downcast_##lower(const upb_def *def) { \
+ assert(upb_def_type(def) == UPB_DEF_##upper); \
+ return (const upb_##lower *)def; \
+ } \
+ UPB_INLINE upb_##lower *upb_dyncast_##lower##_mutable(upb_def *def) { \
+ return (upb_##lower *)upb_dyncast_##lower(def); \
+ } \
+ UPB_INLINE upb_##lower *upb_downcast_##lower##_mutable(upb_def *def) { \
+ return (upb_##lower *)upb_downcast_##lower(def); \
+ } \
+ UPB_CPP_CASTS(lower, cpptype)
+
+#define UPB_DEFINE_DEF(cppname, lower, upper, cppmethods, members) \
+ UPB_DEFINE_CLASS2(cppname, upb::Def, upb::RefCounted, cppmethods, \
+ members) \
+ UPB_DEF_CASTS(lower, upper, cppname)
+
+#define UPB_DECLARE_DEF_TYPE(cppname, lower, upper) \
+ UPB_DECLARE_DERIVED_TYPE2(cppname, upb::Def, upb::RefCounted, \
+ upb_ ## lower, upb_def, upb_refcounted) \
+ UPB_DEF_CASTS(lower, upper, cppname)
+
+UPB_DECLARE_DEF_TYPE(upb::FieldDef, fielddef, FIELD)
+UPB_DECLARE_DEF_TYPE(upb::MessageDef, msgdef, MSG)
+UPB_DECLARE_DEF_TYPE(upb::EnumDef, enumdef, ENUM)
+UPB_DECLARE_DEF_TYPE(upb::OneofDef, oneofdef, ONEOF)
+
+#undef UPB_DECLARE_DEF_TYPE
+#undef UPB_DEF_CASTS
+#undef UPB_CPP_CASTS
+
+
+/* upb::FieldDef **************************************************************/
+
+/* The types a field can have. Note that this list is not identical to the
+ * types defined in descriptor.proto, which gives INT32 and SINT32 separate
+ * types (we distinguish the two with the "integer encoding" enum below). */
+typedef enum {
+ UPB_TYPE_FLOAT = 1,
+ UPB_TYPE_DOUBLE = 2,
+ UPB_TYPE_BOOL = 3,
+ UPB_TYPE_STRING = 4,
+ UPB_TYPE_BYTES = 5,
+ UPB_TYPE_MESSAGE = 6,
+ UPB_TYPE_ENUM = 7, /* Enum values are int32. */
+ UPB_TYPE_INT32 = 8,
+ UPB_TYPE_UINT32 = 9,
+ UPB_TYPE_INT64 = 10,
+ UPB_TYPE_UINT64 = 11
+} upb_fieldtype_t;
+
+/* The repeated-ness of each field; this matches descriptor.proto. */
+typedef enum {
+ UPB_LABEL_OPTIONAL = 1,
+ UPB_LABEL_REQUIRED = 2,
+ UPB_LABEL_REPEATED = 3
+} upb_label_t;
+
+/* How integers should be encoded in serializations that offer multiple
+ * integer encoding methods. */
+typedef enum {
+ UPB_INTFMT_VARIABLE = 1,
+ UPB_INTFMT_FIXED = 2,
+ UPB_INTFMT_ZIGZAG = 3 /* Only for signed types (INT32/INT64). */
+} upb_intfmt_t;
+
+/* Descriptor types, as defined in descriptor.proto. */
+typedef enum {
+ UPB_DESCRIPTOR_TYPE_DOUBLE = 1,
+ UPB_DESCRIPTOR_TYPE_FLOAT = 2,
+ UPB_DESCRIPTOR_TYPE_INT64 = 3,
+ UPB_DESCRIPTOR_TYPE_UINT64 = 4,
+ UPB_DESCRIPTOR_TYPE_INT32 = 5,
+ UPB_DESCRIPTOR_TYPE_FIXED64 = 6,
+ UPB_DESCRIPTOR_TYPE_FIXED32 = 7,
+ UPB_DESCRIPTOR_TYPE_BOOL = 8,
+ UPB_DESCRIPTOR_TYPE_STRING = 9,
+ UPB_DESCRIPTOR_TYPE_GROUP = 10,
+ UPB_DESCRIPTOR_TYPE_MESSAGE = 11,
+ UPB_DESCRIPTOR_TYPE_BYTES = 12,
+ UPB_DESCRIPTOR_TYPE_UINT32 = 13,
+ UPB_DESCRIPTOR_TYPE_ENUM = 14,
+ UPB_DESCRIPTOR_TYPE_SFIXED32 = 15,
+ UPB_DESCRIPTOR_TYPE_SFIXED64 = 16,
+ UPB_DESCRIPTOR_TYPE_SINT32 = 17,
+ UPB_DESCRIPTOR_TYPE_SINT64 = 18
+} upb_descriptortype_t;
+
+/* Maximum field number allowed for FieldDefs. This is an inherent limit of the
+ * protobuf wire format. */
+#define UPB_MAX_FIELDNUMBER ((1 << 29) - 1)
+
+#ifdef __cplusplus
+
+/* A upb_fielddef describes a single field in a message. It is most often
+ * found as a part of a upb_msgdef, but can also stand alone to represent
+ * an extension.
+ *
+ * Its base class is upb::Def (use upb::upcast() to convert). */
+class upb::FieldDef {
+ public:
+ typedef upb_fieldtype_t Type;
+ typedef upb_label_t Label;
+ typedef upb_intfmt_t IntegerFormat;
+ typedef upb_descriptortype_t DescriptorType;
+
+ /* These return true if the given value is a valid member of the enumeration. */
+ static bool CheckType(int32_t val);
+ static bool CheckLabel(int32_t val);
+ static bool CheckDescriptorType(int32_t val);
+ static bool CheckIntegerFormat(int32_t val);
+
+ /* These convert to the given enumeration; they require that the value is
+ * valid. */
+ static Type ConvertType(int32_t val);
+ static Label ConvertLabel(int32_t val);
+ static DescriptorType ConvertDescriptorType(int32_t val);
+ static IntegerFormat ConvertIntegerFormat(int32_t val);
+
+ /* Returns NULL if memory allocation failed. */
+ static reffed_ptr<FieldDef> New();
+
+ /* Duplicates the given field, returning NULL if memory allocation failed.
+ * When a fielddef is duplicated, the subdef (if any) is made symbolic if it
+ * wasn't already. If the subdef is set but has no name (which is possible
+ * since msgdefs are not required to have a name) the new fielddef's subdef
+ * will be unset. */
+ FieldDef* Dup(const void* owner) const;
+
+ /* upb::RefCounted methods like Ref()/Unref(). */
+ UPB_REFCOUNTED_CPPMETHODS
+
+ /* Functionality from upb::Def. */
+ const char* full_name() const;
+
+ bool type_is_set() const; /* set_[descriptor_]type() has been called? */
+ Type type() const; /* Requires that type_is_set() == true. */
+ Label label() const; /* Defaults to UPB_LABEL_OPTIONAL. */
+ const char* name() const; /* NULL if uninitialized. */
+ uint32_t number() const; /* Returns 0 if uninitialized. */
+ bool is_extension() const;
+
+ /* For UPB_TYPE_MESSAGE fields only where is_tag_delimited() == false,
+ * indicates whether this field should have lazy parsing handlers that yield
+ * the unparsed string for the submessage.
+ *
+ * TODO(haberman): I think we want to move this into a FieldOptions container
+ * when we add support for custom options (the FieldOptions struct will
+ * contain both regular FieldOptions like "lazy" *and* custom options). */
+ bool lazy() const;
+
+ /* For non-string, non-submessage fields, this indicates whether binary
+ * protobufs are encoded in packed or non-packed format.
+ *
+ * TODO(haberman): see note above about putting options like this into a
+ * FieldOptions container. */
+ bool packed() const;
+
+ /* An integer that can be used as an index into an array of fields for
+ * whatever message this field belongs to. Guaranteed to be less than
+ * f->containing_type()->field_count(). May only be accessed once the def has
+ * been finalized. */
+ int index() const;
+
+ /* The MessageDef to which this field belongs.
+ *
+ * If this field has been added to a MessageDef, that message can be retrieved
+ * directly (this is always the case for frozen FieldDefs).
+ *
+ * If the field has not yet been added to a MessageDef, you can set the name
+ * of the containing type symbolically instead. This is mostly useful for
+ * extensions, where the extension is declared separately from the message. */
+ const MessageDef* containing_type() const;
+ const char* containing_type_name();
+
+ /* The OneofDef to which this field belongs, or NULL if this field is not part
+ * of a oneof. */
+ const OneofDef* containing_oneof() const;
+
+ /* The field's type according to the enum in descriptor.proto. This is not
+ * the same as UPB_TYPE_*, because it distinguishes between (for example)
+ * INT32 and SINT32, whereas our "type" enum does not. This return of
+ * descriptor_type() is a function of type(), integer_format(), and
+ * is_tag_delimited(). Likewise set_descriptor_type() sets all three
+ * appropriately. */
+ DescriptorType descriptor_type() const;
+
+ /* Convenient field type tests. */
+ bool IsSubMessage() const;
+ bool IsString() const;
+ bool IsSequence() const;
+ bool IsPrimitive() const;
+ bool IsMap() const;
+
+ /* How integers are encoded. Only meaningful for integer types.
+ * Defaults to UPB_INTFMT_VARIABLE, and is reset when "type" changes. */
+ IntegerFormat integer_format() const;
+
+ /* Whether a submessage field is tag-delimited or not (if false, then
+ * length-delimited). May only be set when type() == UPB_TYPE_MESSAGE. */
+ bool is_tag_delimited() const;
+
+ /* Returns the non-string default value for this fielddef, which may either
+ * be something the client set explicitly or the "default default" (0 for
+ * numbers, empty for strings). The field's type indicates the type of the
+ * returned value, except for enum fields that are still mutable.
+ *
+ * Requires that the given function matches the field's current type. */
+ int64_t default_int64() const;
+ int32_t default_int32() const;
+ uint64_t default_uint64() const;
+ uint32_t default_uint32() const;
+ bool default_bool() const;
+ float default_float() const;
+ double default_double() const;
+
+ /* The resulting string is always NULL-terminated. If non-NULL, the length
+ * will be stored in *len. */
+ const char *default_string(size_t* len) const;
+
+ /* For frozen UPB_TYPE_ENUM fields, enum defaults can always be read as either
+ * string or int32, and both of these methods will always return true.
+ *
+ * For mutable UPB_TYPE_ENUM fields, the story is a bit more complicated.
+ * Enum defaults are unusual. They can be specified either as string or int32,
+ * but to be valid the enum must have that value as a member. And if no
+ * default is specified, the "default default" comes from the EnumDef.
+ *
+ * We allow reading the default as either an int32 or a string, but only if
+ * we have a meaningful value to report. We have a meaningful value if it was
+ * set explicitly, or if we could get the "default default" from the EnumDef.
+ * Also if you explicitly set the name and we find the number in the EnumDef */
+ bool EnumHasStringDefault() const;
+ bool EnumHasInt32Default() const;
+
+ /* Submessage and enum fields must reference a "subdef", which is the
+ * upb::MessageDef or upb::EnumDef that defines their type. Note that when
+ * the FieldDef is mutable it may not have a subdef *yet*, but this function
+ * still returns true to indicate that the field's type requires a subdef. */
+ bool HasSubDef() const;
+
+ /* Returns the enum or submessage def for this field, if any. The field's
+ * type must match (ie. you may only call enum_subdef() for fields where
+ * type() == UPB_TYPE_ENUM). Returns NULL if the subdef has not been set or
+ * is currently set symbolically. */
+ const EnumDef* enum_subdef() const;
+ const MessageDef* message_subdef() const;
+
+ /* Returns the generic subdef for this field. Requires that HasSubDef() (ie.
+ * only works for UPB_TYPE_ENUM and UPB_TYPE_MESSAGE fields). */
+ const Def* subdef() const;
+
+ /* Returns the symbolic name of the subdef. If the subdef is currently set
+ * unresolved (ie. set symbolically) returns the symbolic name. If it has
+ * been resolved to a specific subdef, returns the name from that subdef. */
+ const char* subdef_name() const;
+
+ /* Setters (non-const methods), only valid for mutable FieldDefs! ***********/
+
+ bool set_full_name(const char* fullname, upb::Status* s);
+ bool set_full_name(const std::string& fullname, upb::Status* s);
+
+ /* This may only be called if containing_type() == NULL (ie. the field has not
+ * been added to a message yet). */
+ bool set_containing_type_name(const char *name, Status* status);
+ bool set_containing_type_name(const std::string& name, Status* status);
+
+ /* Defaults to false. When we freeze, we ensure that this can only be true
+ * for length-delimited message fields. Prior to freezing this can be true or
+ * false with no restrictions. */
+ void set_lazy(bool lazy);
+
+ /* Defaults to true. Sets whether this field is encoded in packed format. */
+ void set_packed(bool packed);
+
+ /* "type" or "descriptor_type" MUST be set explicitly before the fielddef is
+ * finalized. These setters require that the enum value is valid; if the
+ * value did not come directly from an enum constant, the caller should
+ * validate it first with the functions above (CheckFieldType(), etc). */
+ void set_type(Type type);
+ void set_label(Label label);
+ void set_descriptor_type(DescriptorType type);
+ void set_is_extension(bool is_extension);
+
+ /* "number" and "name" must be set before the FieldDef is added to a
+ * MessageDef, and may not be set after that.
+ *
+ * "name" is the same as full_name()/set_full_name(), but since fielddefs
+ * most often use simple, non-qualified names, we provide this accessor
+ * also. Generally only extensions will want to think of this name as
+ * fully-qualified. */
+ bool set_number(uint32_t number, upb::Status* s);
+ bool set_name(const char* name, upb::Status* s);
+ bool set_name(const std::string& name, upb::Status* s);
+
+ void set_integer_format(IntegerFormat format);
+ bool set_tag_delimited(bool tag_delimited, upb::Status* s);
+
+ /* Sets default value for the field. The call must exactly match the type
+ * of the field. Enum fields may use either setint32 or setstring to set
+ * the default numerically or symbolically, respectively, but symbolic
+ * defaults must be resolved before finalizing (see ResolveEnumDefault()).
+ *
+ * Changing the type of a field will reset its default. */
+ void set_default_int64(int64_t val);
+ void set_default_int32(int32_t val);
+ void set_default_uint64(uint64_t val);
+ void set_default_uint32(uint32_t val);
+ void set_default_bool(bool val);
+ void set_default_float(float val);
+ void set_default_double(double val);
+ bool set_default_string(const void *str, size_t len, Status *s);
+ bool set_default_string(const std::string &str, Status *s);
+ void set_default_cstr(const char *str, Status *s);
+
+ /* Before a fielddef is frozen, its subdef may be set either directly (with a
+ * upb::Def*) or symbolically. Symbolic refs must be resolved before the
+ * containing msgdef can be frozen (see upb_resolve() above). upb always
+ * guarantees that any def reachable from a live def will also be kept alive.
+ *
+ * Both methods require that upb_hassubdef(f) (so the type must be set prior
+ * to calling these methods). Returns false if this is not the case, or if
+ * the given subdef is not of the correct type. The subdef is reset if the
+ * field's type is changed. The subdef can be set to NULL to clear it. */
+ bool set_subdef(const Def* subdef, Status* s);
+ bool set_enum_subdef(const EnumDef* subdef, Status* s);
+ bool set_message_subdef(const MessageDef* subdef, Status* s);
+ bool set_subdef_name(const char* name, Status* s);
+ bool set_subdef_name(const std::string &name, Status* s);
+
+ private:
+ UPB_DISALLOW_POD_OPS(FieldDef, upb::FieldDef)
+};
+
+# endif /* defined(__cplusplus) */
+
+UPB_BEGIN_EXTERN_C
+
+/* Native C API. */
+upb_fielddef *upb_fielddef_new(const void *owner);
+upb_fielddef *upb_fielddef_dup(const upb_fielddef *f, const void *owner);
+
+/* Include upb_refcounted methods like upb_fielddef_ref(). */
+UPB_REFCOUNTED_CMETHODS(upb_fielddef, upb_fielddef_upcast2)
+
+/* Methods from upb_def. */
+const char *upb_fielddef_fullname(const upb_fielddef *f);
+bool upb_fielddef_setfullname(upb_fielddef *f, const char *fullname,
+ upb_status *s);
+
+bool upb_fielddef_typeisset(const upb_fielddef *f);
+upb_fieldtype_t upb_fielddef_type(const upb_fielddef *f);
+upb_descriptortype_t upb_fielddef_descriptortype(const upb_fielddef *f);
+upb_label_t upb_fielddef_label(const upb_fielddef *f);
+uint32_t upb_fielddef_number(const upb_fielddef *f);
+const char *upb_fielddef_name(const upb_fielddef *f);
+bool upb_fielddef_isextension(const upb_fielddef *f);
+bool upb_fielddef_lazy(const upb_fielddef *f);
+bool upb_fielddef_packed(const upb_fielddef *f);
+const upb_msgdef *upb_fielddef_containingtype(const upb_fielddef *f);
+const upb_oneofdef *upb_fielddef_containingoneof(const upb_fielddef *f);
+upb_msgdef *upb_fielddef_containingtype_mutable(upb_fielddef *f);
+const char *upb_fielddef_containingtypename(upb_fielddef *f);
+upb_intfmt_t upb_fielddef_intfmt(const upb_fielddef *f);
+uint32_t upb_fielddef_index(const upb_fielddef *f);
+bool upb_fielddef_istagdelim(const upb_fielddef *f);
+bool upb_fielddef_issubmsg(const upb_fielddef *f);
+bool upb_fielddef_isstring(const upb_fielddef *f);
+bool upb_fielddef_isseq(const upb_fielddef *f);
+bool upb_fielddef_isprimitive(const upb_fielddef *f);
+bool upb_fielddef_ismap(const upb_fielddef *f);
+int64_t upb_fielddef_defaultint64(const upb_fielddef *f);
+int32_t upb_fielddef_defaultint32(const upb_fielddef *f);
+uint64_t upb_fielddef_defaultuint64(const upb_fielddef *f);
+uint32_t upb_fielddef_defaultuint32(const upb_fielddef *f);
+bool upb_fielddef_defaultbool(const upb_fielddef *f);
+float upb_fielddef_defaultfloat(const upb_fielddef *f);
+double upb_fielddef_defaultdouble(const upb_fielddef *f);
+const char *upb_fielddef_defaultstr(const upb_fielddef *f, size_t *len);
+bool upb_fielddef_enumhasdefaultint32(const upb_fielddef *f);
+bool upb_fielddef_enumhasdefaultstr(const upb_fielddef *f);
+bool upb_fielddef_hassubdef(const upb_fielddef *f);
+const upb_def *upb_fielddef_subdef(const upb_fielddef *f);
+const upb_msgdef *upb_fielddef_msgsubdef(const upb_fielddef *f);
+const upb_enumdef *upb_fielddef_enumsubdef(const upb_fielddef *f);
+const char *upb_fielddef_subdefname(const upb_fielddef *f);
+
+void upb_fielddef_settype(upb_fielddef *f, upb_fieldtype_t type);
+void upb_fielddef_setdescriptortype(upb_fielddef *f, int type);
+void upb_fielddef_setlabel(upb_fielddef *f, upb_label_t label);
+bool upb_fielddef_setnumber(upb_fielddef *f, uint32_t number, upb_status *s);
+bool upb_fielddef_setname(upb_fielddef *f, const char *name, upb_status *s);
+bool upb_fielddef_setcontainingtypename(upb_fielddef *f, const char *name,
+ upb_status *s);
+void upb_fielddef_setisextension(upb_fielddef *f, bool is_extension);
+void upb_fielddef_setlazy(upb_fielddef *f, bool lazy);
+void upb_fielddef_setpacked(upb_fielddef *f, bool packed);
+void upb_fielddef_setintfmt(upb_fielddef *f, upb_intfmt_t fmt);
+void upb_fielddef_settagdelim(upb_fielddef *f, bool tag_delim);
+void upb_fielddef_setdefaultint64(upb_fielddef *f, int64_t val);
+void upb_fielddef_setdefaultint32(upb_fielddef *f, int32_t val);
+void upb_fielddef_setdefaultuint64(upb_fielddef *f, uint64_t val);
+void upb_fielddef_setdefaultuint32(upb_fielddef *f, uint32_t val);
+void upb_fielddef_setdefaultbool(upb_fielddef *f, bool val);
+void upb_fielddef_setdefaultfloat(upb_fielddef *f, float val);
+void upb_fielddef_setdefaultdouble(upb_fielddef *f, double val);
+bool upb_fielddef_setdefaultstr(upb_fielddef *f, const void *str, size_t len,
+ upb_status *s);
+void upb_fielddef_setdefaultcstr(upb_fielddef *f, const char *str,
+ upb_status *s);
+bool upb_fielddef_setsubdef(upb_fielddef *f, const upb_def *subdef,
+ upb_status *s);
+bool upb_fielddef_setmsgsubdef(upb_fielddef *f, const upb_msgdef *subdef,
+ upb_status *s);
+bool upb_fielddef_setenumsubdef(upb_fielddef *f, const upb_enumdef *subdef,
+ upb_status *s);
+bool upb_fielddef_setsubdefname(upb_fielddef *f, const char *name,
+ upb_status *s);
+
+bool upb_fielddef_checklabel(int32_t label);
+bool upb_fielddef_checktype(int32_t type);
+bool upb_fielddef_checkdescriptortype(int32_t type);
+bool upb_fielddef_checkintfmt(int32_t fmt);
+
+UPB_END_EXTERN_C
+
+
+/* upb::MessageDef ************************************************************/
+
+typedef upb_inttable_iter upb_msg_field_iter;
+typedef upb_strtable_iter upb_msg_oneof_iter;
+
+#ifdef __cplusplus
+
+/* Structure that describes a single .proto message type.
+ *
+ * Its base class is upb::Def (use upb::upcast() to convert). */
+class upb::MessageDef {
+ public:
+ /* Returns NULL if memory allocation failed. */
+ static reffed_ptr<MessageDef> New();
+
+ /* upb::RefCounted methods like Ref()/Unref(). */
+ UPB_REFCOUNTED_CPPMETHODS
+
+ /* Functionality from upb::Def. */
+ const char* full_name() const;
+ bool set_full_name(const char* fullname, Status* s);
+ bool set_full_name(const std::string& fullname, Status* s);
+
+ /* Call to freeze this MessageDef.
+ * WARNING: this will fail if this message has any unfrozen submessages!
+ * Messages with cycles must be frozen as a batch using upb::Def::Freeze(). */
+ bool Freeze(Status* s);
+
+ /* The number of fields that belong to the MessageDef. */
+ int field_count() const;
+
+ /* The number of oneofs that belong to the MessageDef. */
+ int oneof_count() const;
+
+ /* Adds a field (upb_fielddef object) to a msgdef. Requires that the msgdef
+ * and the fielddefs are mutable. The fielddef's name and number must be
+ * set, and the message may not already contain any field with this name or
+ * number, and this fielddef may not be part of another message. In error
+ * cases false is returned and the msgdef is unchanged.
+ *
+ * If the given field is part of a oneof, this call succeeds if and only if
+ * that oneof is already part of this msgdef. (Note that adding a oneof to a
+ * msgdef automatically adds all of its fields to the msgdef at the time that
+ * the oneof is added, so it is usually more idiomatic to add the oneof's
+ * fields first then add the oneof to the msgdef. This case is supported for
+ * convenience.)
+ *
+ * If |f| is already part of this MessageDef, this method performs no action
+ * and returns true (success). Thus, this method is idempotent. */
+ bool AddField(FieldDef* f, Status* s);
+ bool AddField(const reffed_ptr<FieldDef>& f, Status* s);
+
+ /* Adds a oneof (upb_oneofdef object) to a msgdef. Requires that the msgdef,
+ * oneof, and any fielddefs are mutable, that the fielddefs contained in the
+ * oneof do not have any name or number conflicts with existing fields in the
+ * msgdef, and that the oneof's name is unique among all oneofs in the msgdef.
+ * If the oneof is added successfully, all of its fields will be added
+ * directly to the msgdef as well. In error cases, false is returned and the
+ * msgdef is unchanged. */
+ bool AddOneof(OneofDef* o, Status* s);
+ bool AddOneof(const reffed_ptr<OneofDef>& o, Status* s);
+
+ /* These return NULL if the field is not found. */
+ FieldDef* FindFieldByNumber(uint32_t number);
+ FieldDef* FindFieldByName(const char *name, size_t len);
+ const FieldDef* FindFieldByNumber(uint32_t number) const;
+ const FieldDef* FindFieldByName(const char* name, size_t len) const;
+
+
+ FieldDef* FindFieldByName(const char *name) {
+ return FindFieldByName(name, strlen(name));
+ }
+ const FieldDef* FindFieldByName(const char *name) const {
+ return FindFieldByName(name, strlen(name));
+ }
+
+ template <class T>
+ FieldDef* FindFieldByName(const T& str) {
+ return FindFieldByName(str.c_str(), str.size());
+ }
+ template <class T>
+ const FieldDef* FindFieldByName(const T& str) const {
+ return FindFieldByName(str.c_str(), str.size());
+ }
+
+ OneofDef* FindOneofByName(const char* name, size_t len);
+ const OneofDef* FindOneofByName(const char* name, size_t len) const;
+
+ OneofDef* FindOneofByName(const char* name) {
+ return FindOneofByName(name, strlen(name));
+ }
+ const OneofDef* FindOneofByName(const char* name) const {
+ return FindOneofByName(name, strlen(name));
+ }
+
+ template<class T>
+ OneofDef* FindOneofByName(const T& str) {
+ return FindOneofByName(str.c_str(), str.size());
+ }
+ template<class T>
+ const OneofDef* FindOneofByName(const T& str) const {
+ return FindOneofByName(str.c_str(), str.size());
+ }
+
+ /* Returns a new msgdef that is a copy of the given msgdef (and a copy of all
+ * the fields) but with any references to submessages broken and replaced
+ * with just the name of the submessage. Returns NULL if memory allocation
+ * failed.
+ *
+ * TODO(haberman): which is more useful, keeping fields resolved or
+ * unresolving them? If there's no obvious answer, Should this functionality
+ * just be moved into symtab.c? */
+ MessageDef* Dup(const void* owner) const;
+
+ /* Is this message a map entry? */
+ void setmapentry(bool map_entry);
+ bool mapentry() const;
+
+ /* Iteration over fields. The order is undefined. */
+ class field_iterator
+ : public std::iterator<std::forward_iterator_tag, FieldDef*> {
+ public:
+ explicit field_iterator(MessageDef* md);
+ static field_iterator end(MessageDef* md);
+
+ void operator++();
+ FieldDef* operator*() const;
+ bool operator!=(const field_iterator& other) const;
+ bool operator==(const field_iterator& other) const;
+
+ private:
+ upb_msg_field_iter iter_;
+ };
+
+ class const_field_iterator
+ : public std::iterator<std::forward_iterator_tag, const FieldDef*> {
+ public:
+ explicit const_field_iterator(const MessageDef* md);
+ static const_field_iterator end(const MessageDef* md);
+
+ void operator++();
+ const FieldDef* operator*() const;
+ bool operator!=(const const_field_iterator& other) const;
+ bool operator==(const const_field_iterator& other) const;
+
+ private:
+ upb_msg_field_iter iter_;
+ };
+
+ /* Iteration over oneofs. The order is undefined. */
+ class oneof_iterator
+ : public std::iterator<std::forward_iterator_tag, FieldDef*> {
+ public:
+ explicit oneof_iterator(MessageDef* md);
+ static oneof_iterator end(MessageDef* md);
+
+ void operator++();
+ OneofDef* operator*() const;
+ bool operator!=(const oneof_iterator& other) const;
+ bool operator==(const oneof_iterator& other) const;
+
+ private:
+ upb_msg_oneof_iter iter_;
+ };
+
+ class const_oneof_iterator
+ : public std::iterator<std::forward_iterator_tag, const FieldDef*> {
+ public:
+ explicit const_oneof_iterator(const MessageDef* md);
+ static const_oneof_iterator end(const MessageDef* md);
+
+ void operator++();
+ const OneofDef* operator*() const;
+ bool operator!=(const const_oneof_iterator& other) const;
+ bool operator==(const const_oneof_iterator& other) const;
+
+ private:
+ upb_msg_oneof_iter iter_;
+ };
+
+ class FieldAccessor {
+ public:
+ explicit FieldAccessor(MessageDef* msg) : msg_(msg) {}
+ field_iterator begin() { return msg_->field_begin(); }
+ field_iterator end() { return msg_->field_end(); }
+ private:
+ MessageDef* msg_;
+ };
+
+ class ConstFieldAccessor {
+ public:
+ explicit ConstFieldAccessor(const MessageDef* msg) : msg_(msg) {}
+ const_field_iterator begin() { return msg_->field_begin(); }
+ const_field_iterator end() { return msg_->field_end(); }
+ private:
+ const MessageDef* msg_;
+ };
+
+ class OneofAccessor {
+ public:
+ explicit OneofAccessor(MessageDef* msg) : msg_(msg) {}
+ oneof_iterator begin() { return msg_->oneof_begin(); }
+ oneof_iterator end() { return msg_->oneof_end(); }
+ private:
+ MessageDef* msg_;
+ };
+
+ class ConstOneofAccessor {
+ public:
+ explicit ConstOneofAccessor(const MessageDef* msg) : msg_(msg) {}
+ const_oneof_iterator begin() { return msg_->oneof_begin(); }
+ const_oneof_iterator end() { return msg_->oneof_end(); }
+ private:
+ const MessageDef* msg_;
+ };
+
+ field_iterator field_begin();
+ field_iterator field_end();
+ const_field_iterator field_begin() const;
+ const_field_iterator field_end() const;
+
+ oneof_iterator oneof_begin();
+ oneof_iterator oneof_end();
+ const_oneof_iterator oneof_begin() const;
+ const_oneof_iterator oneof_end() const;
+
+ FieldAccessor fields() { return FieldAccessor(this); }
+ ConstFieldAccessor fields() const { return ConstFieldAccessor(this); }
+ OneofAccessor oneofs() { return OneofAccessor(this); }
+ ConstOneofAccessor oneofs() const { return ConstOneofAccessor(this); }
+
+ private:
+ UPB_DISALLOW_POD_OPS(MessageDef, upb::MessageDef)
+};
+
+#endif /* __cplusplus */
+
+UPB_BEGIN_EXTERN_C
+
+/* Returns NULL if memory allocation failed. */
+upb_msgdef *upb_msgdef_new(const void *owner);
+
+/* Include upb_refcounted methods like upb_msgdef_ref(). */
+UPB_REFCOUNTED_CMETHODS(upb_msgdef, upb_msgdef_upcast2)
+
+bool upb_msgdef_freeze(upb_msgdef *m, upb_status *status);
+
+const char *upb_msgdef_fullname(const upb_msgdef *m);
+bool upb_msgdef_setfullname(upb_msgdef *m, const char *fullname, upb_status *s);
+
+upb_msgdef *upb_msgdef_dup(const upb_msgdef *m, const void *owner);
+bool upb_msgdef_addfield(upb_msgdef *m, upb_fielddef *f, const void *ref_donor,
+ upb_status *s);
+bool upb_msgdef_addoneof(upb_msgdef *m, upb_oneofdef *o, const void *ref_donor,
+ upb_status *s);
+
+/* Field lookup in a couple of different variations:
+ * - itof = int to field
+ * - ntof = name to field
+ * - ntofz = name to field, null-terminated string. */
+const upb_fielddef *upb_msgdef_itof(const upb_msgdef *m, uint32_t i);
+const upb_fielddef *upb_msgdef_ntof(const upb_msgdef *m, const char *name,
+ size_t len);
+int upb_msgdef_numfields(const upb_msgdef *m);
+
+UPB_INLINE const upb_fielddef *upb_msgdef_ntofz(const upb_msgdef *m,
+ const char *name) {
+ return upb_msgdef_ntof(m, name, strlen(name));
+}
+
+UPB_INLINE upb_fielddef *upb_msgdef_itof_mutable(upb_msgdef *m, uint32_t i) {
+ return (upb_fielddef*)upb_msgdef_itof(m, i);
+}
+
+UPB_INLINE upb_fielddef *upb_msgdef_ntof_mutable(upb_msgdef *m,
+ const char *name, size_t len) {
+ return (upb_fielddef *)upb_msgdef_ntof(m, name, len);
+}
+
+/* Oneof lookup:
+ * - ntoo = name to oneof
+ * - ntooz = name to oneof, null-terminated string. */
+const upb_oneofdef *upb_msgdef_ntoo(const upb_msgdef *m, const char *name,
+ size_t len);
+int upb_msgdef_numoneofs(const upb_msgdef *m);
+
+UPB_INLINE const upb_oneofdef *upb_msgdef_ntooz(const upb_msgdef *m,
+ const char *name) {
+ return upb_msgdef_ntoo(m, name, strlen(name));
+}
+
+UPB_INLINE upb_oneofdef *upb_msgdef_ntoo_mutable(upb_msgdef *m,
+ const char *name, size_t len) {
+ return (upb_oneofdef *)upb_msgdef_ntoo(m, name, len);
+}
+
+void upb_msgdef_setmapentry(upb_msgdef *m, bool map_entry);
+bool upb_msgdef_mapentry(const upb_msgdef *m);
+
+/* Well-known field tag numbers for map-entry messages. */
+#define UPB_MAPENTRY_KEY 1
+#define UPB_MAPENTRY_VALUE 2
+
+const upb_oneofdef *upb_msgdef_findoneof(const upb_msgdef *m,
+ const char *name);
+int upb_msgdef_numoneofs(const upb_msgdef *m);
+
+/* upb_msg_field_iter i;
+ * for(upb_msg_field_begin(&i, m);
+ * !upb_msg_field_done(&i);
+ * upb_msg_field_next(&i)) {
+ * upb_fielddef *f = upb_msg_iter_field(&i);
+ * // ...
+ * }
+ *
+ * For C we don't have separate iterators for const and non-const.
+ * It is the caller's responsibility to cast the upb_fielddef* to
+ * const if the upb_msgdef* is const. */
+void upb_msg_field_begin(upb_msg_field_iter *iter, const upb_msgdef *m);
+void upb_msg_field_next(upb_msg_field_iter *iter);
+bool upb_msg_field_done(const upb_msg_field_iter *iter);
+upb_fielddef *upb_msg_iter_field(const upb_msg_field_iter *iter);
+void upb_msg_field_iter_setdone(upb_msg_field_iter *iter);
+
+/* Similar to above, we also support iterating through the oneofs in a
+ * msgdef. */
+void upb_msg_oneof_begin(upb_msg_oneof_iter *iter, const upb_msgdef *m);
+void upb_msg_oneof_next(upb_msg_oneof_iter *iter);
+bool upb_msg_oneof_done(const upb_msg_oneof_iter *iter);
+upb_oneofdef *upb_msg_iter_oneof(const upb_msg_oneof_iter *iter);
+void upb_msg_oneof_iter_setdone(upb_msg_oneof_iter *iter);
+
+UPB_END_EXTERN_C
+
+
+/* upb::EnumDef ***************************************************************/
+
+typedef upb_strtable_iter upb_enum_iter;
+
+#ifdef __cplusplus
+
+/* Class that represents an enum. Its base class is upb::Def (convert with
+ * upb::upcast()). */
+class upb::EnumDef {
+ public:
+ /* Returns NULL if memory allocation failed. */
+ static reffed_ptr<EnumDef> New();
+
+ /* upb::RefCounted methods like Ref()/Unref(). */
+ UPB_REFCOUNTED_CPPMETHODS
+
+ /* Functionality from upb::Def. */
+ const char* full_name() const;
+ bool set_full_name(const char* fullname, Status* s);
+ bool set_full_name(const std::string& fullname, Status* s);
+
+ /* Call to freeze this EnumDef. */
+ bool Freeze(Status* s);
+
+ /* The value that is used as the default when no field default is specified.
+ * If not set explicitly, the first value that was added will be used.
+ * The default value must be a member of the enum.
+ * Requires that value_count() > 0. */
+ int32_t default_value() const;
+
+ /* Sets the default value. If this value is not valid, returns false and an
+ * error message in status. */
+ bool set_default_value(int32_t val, Status* status);
+
+ /* Returns the number of values currently defined in the enum. Note that
+ * multiple names can refer to the same number, so this may be greater than
+ * the total number of unique numbers. */
+ int value_count() const;
+
+ /* Adds a single name/number pair to the enum. Fails if this name has
+ * already been used by another value. */
+ bool AddValue(const char* name, int32_t num, Status* status);
+ bool AddValue(const std::string& name, int32_t num, Status* status);
+
+ /* Lookups from name to integer, returning true if found. */
+ bool FindValueByName(const char* name, int32_t* num) const;
+
+ /* Finds the name corresponding to the given number, or NULL if none was
+ * found. If more than one name corresponds to this number, returns the
+ * first one that was added. */
+ const char* FindValueByNumber(int32_t num) const;
+
+ /* Returns a new EnumDef with all the same values. The new EnumDef will be
+ * owned by the given owner. */
+ EnumDef* Dup(const void* owner) const;
+
+ /* Iteration over name/value pairs. The order is undefined.
+ * Adding an enum val invalidates any iterators.
+ *
+ * TODO: make compatible with range-for, with elements as pairs? */
+ class Iterator {
+ public:
+ explicit Iterator(const EnumDef*);
+
+ int32_t number();
+ const char *name();
+ bool Done();
+ void Next();
+
+ private:
+ upb_enum_iter iter_;
+ };
+
+ private:
+ UPB_DISALLOW_POD_OPS(EnumDef, upb::EnumDef)
+};
+
+#endif /* __cplusplus */
+
+UPB_BEGIN_EXTERN_C
+
+/* Native C API. */
+upb_enumdef *upb_enumdef_new(const void *owner);
+upb_enumdef *upb_enumdef_dup(const upb_enumdef *e, const void *owner);
+
+/* Include upb_refcounted methods like upb_enumdef_ref(). */
+UPB_REFCOUNTED_CMETHODS(upb_enumdef, upb_enumdef_upcast2)
+
+bool upb_enumdef_freeze(upb_enumdef *e, upb_status *status);
+
+/* From upb_def. */
+const char *upb_enumdef_fullname(const upb_enumdef *e);
+bool upb_enumdef_setfullname(upb_enumdef *e, const char *fullname,
+ upb_status *s);
+
+int32_t upb_enumdef_default(const upb_enumdef *e);
+bool upb_enumdef_setdefault(upb_enumdef *e, int32_t val, upb_status *s);
+int upb_enumdef_numvals(const upb_enumdef *e);
+bool upb_enumdef_addval(upb_enumdef *e, const char *name, int32_t num,
+ upb_status *status);
+
+/* Enum lookups:
+ * - ntoi: look up a name with specified length.
+ * - ntoiz: look up a name provided as a null-terminated string.
+ * - iton: look up an integer, returning the name as a null-terminated
+ * string. */
+bool upb_enumdef_ntoi(const upb_enumdef *e, const char *name, size_t len,
+ int32_t *num);
+UPB_INLINE bool upb_enumdef_ntoiz(const upb_enumdef *e,
+ const char *name, int32_t *num) {
+ return upb_enumdef_ntoi(e, name, strlen(name), num);
+}
+const char *upb_enumdef_iton(const upb_enumdef *e, int32_t num);
+
+/* upb_enum_iter i;
+ * for(upb_enum_begin(&i, e); !upb_enum_done(&i); upb_enum_next(&i)) {
+ * // ...
+ * }
+ */
+void upb_enum_begin(upb_enum_iter *iter, const upb_enumdef *e);
+void upb_enum_next(upb_enum_iter *iter);
+bool upb_enum_done(upb_enum_iter *iter);
+const char *upb_enum_iter_name(upb_enum_iter *iter);
+int32_t upb_enum_iter_number(upb_enum_iter *iter);
+
+UPB_END_EXTERN_C
+
+/* upb::OneofDef **************************************************************/
+
+typedef upb_inttable_iter upb_oneof_iter;
+
+#ifdef __cplusplus
+
+/* Class that represents a oneof. Its base class is upb::Def (convert with
+ * upb::upcast()). */
+class upb::OneofDef {
+ public:
+ /* Returns NULL if memory allocation failed. */
+ static reffed_ptr<OneofDef> New();
+
+ /* upb::RefCounted methods like Ref()/Unref(). */
+ UPB_REFCOUNTED_CPPMETHODS
+
+ /* Functionality from upb::Def. */
+ const char* full_name() const;
+
+ /* Returns the MessageDef that owns this OneofDef. */
+ const MessageDef* containing_type() const;
+
+ /* Returns the name of this oneof. This is the name used to look up the oneof
+ * by name once added to a message def. */
+ const char* name() const;
+ bool set_name(const char* name, Status* s);
+
+ /* Returns the number of fields currently defined in the oneof. */
+ int field_count() const;
+
+ /* Adds a field to the oneof. The field must not have been added to any other
+ * oneof or msgdef. If the oneof is not yet part of a msgdef, then when the
+ * oneof is eventually added to a msgdef, all fields added to the oneof will
+ * also be added to the msgdef at that time. If the oneof is already part of a
+ * msgdef, the field must either be a part of that msgdef already, or must not
+ * be a part of any msgdef; in the latter case, the field is added to the
+ * msgdef as a part of this operation.
+ *
+ * The field may only have an OPTIONAL label, never REQUIRED or REPEATED.
+ *
+ * If |f| is already part of this MessageDef, this method performs no action
+ * and returns true (success). Thus, this method is idempotent. */
+ bool AddField(FieldDef* field, Status* s);
+ bool AddField(const reffed_ptr<FieldDef>& field, Status* s);
+
+ /* Looks up by name. */
+ const FieldDef* FindFieldByName(const char* name, size_t len) const;
+ FieldDef* FindFieldByName(const char* name, size_t len);
+ const FieldDef* FindFieldByName(const char* name) const {
+ return FindFieldByName(name, strlen(name));
+ }
+ FieldDef* FindFieldByName(const char* name) {
+ return FindFieldByName(name, strlen(name));
+ }
+
+ template <class T>
+ FieldDef* FindFieldByName(const T& str) {
+ return FindFieldByName(str.c_str(), str.size());
+ }
+ template <class T>
+ const FieldDef* FindFieldByName(const T& str) const {
+ return FindFieldByName(str.c_str(), str.size());
+ }
+
+ /* Looks up by tag number. */
+ const FieldDef* FindFieldByNumber(uint32_t num) const;
+
+ /* Returns a new OneofDef with all the same fields. The OneofDef will be owned
+ * by the given owner. */
+ OneofDef* Dup(const void* owner) const;
+
+ /* Iteration over fields. The order is undefined. */
+ class iterator : public std::iterator<std::forward_iterator_tag, FieldDef*> {
+ public:
+ explicit iterator(OneofDef* md);
+ static iterator end(OneofDef* md);
+
+ void operator++();
+ FieldDef* operator*() const;
+ bool operator!=(const iterator& other) const;
+ bool operator==(const iterator& other) const;
+
+ private:
+ upb_oneof_iter iter_;
+ };
+
+ class const_iterator
+ : public std::iterator<std::forward_iterator_tag, const FieldDef*> {
+ public:
+ explicit const_iterator(const OneofDef* md);
+ static const_iterator end(const OneofDef* md);
+
+ void operator++();
+ const FieldDef* operator*() const;
+ bool operator!=(const const_iterator& other) const;
+ bool operator==(const const_iterator& other) const;
+
+ private:
+ upb_oneof_iter iter_;
+ };
+
+ iterator begin();
+ iterator end();
+ const_iterator begin() const;
+ const_iterator end() const;
+
+ private:
+ UPB_DISALLOW_POD_OPS(OneofDef, upb::OneofDef)
+};
+
+#endif /* __cplusplus */
+
+UPB_BEGIN_EXTERN_C
+
+/* Native C API. */
+upb_oneofdef *upb_oneofdef_new(const void *owner);
+upb_oneofdef *upb_oneofdef_dup(const upb_oneofdef *o, const void *owner);
+
+/* Include upb_refcounted methods like upb_oneofdef_ref(). */
+UPB_REFCOUNTED_CMETHODS(upb_oneofdef, upb_oneofdef_upcast2)
+
+const char *upb_oneofdef_name(const upb_oneofdef *o);
+bool upb_oneofdef_setname(upb_oneofdef *o, const char *name, upb_status *s);
+
+const upb_msgdef *upb_oneofdef_containingtype(const upb_oneofdef *o);
+int upb_oneofdef_numfields(const upb_oneofdef *o);
+bool upb_oneofdef_addfield(upb_oneofdef *o, upb_fielddef *f,
+ const void *ref_donor,
+ upb_status *s);
+
+/* Oneof lookups:
+ * - ntof: look up a field by name.
+ * - ntofz: look up a field by name (as a null-terminated string).
+ * - itof: look up a field by number. */
+const upb_fielddef *upb_oneofdef_ntof(const upb_oneofdef *o,
+ const char *name, size_t length);
+UPB_INLINE const upb_fielddef *upb_oneofdef_ntofz(const upb_oneofdef *o,
+ const char *name) {
+ return upb_oneofdef_ntof(o, name, strlen(name));
+}
+const upb_fielddef *upb_oneofdef_itof(const upb_oneofdef *o, uint32_t num);
+
+/* upb_oneof_iter i;
+ * for(upb_oneof_begin(&i, e); !upb_oneof_done(&i); upb_oneof_next(&i)) {
+ * // ...
+ * }
+ */
+void upb_oneof_begin(upb_oneof_iter *iter, const upb_oneofdef *o);
+void upb_oneof_next(upb_oneof_iter *iter);
+bool upb_oneof_done(upb_oneof_iter *iter);
+upb_fielddef *upb_oneof_iter_field(const upb_oneof_iter *iter);
+void upb_oneof_iter_setdone(upb_oneof_iter *iter);
+
+UPB_END_EXTERN_C
+
+#ifdef __cplusplus
+
+UPB_INLINE const char* upb_safecstr(const std::string& str) {
+ assert(str.size() == std::strlen(str.c_str()));
+ return str.c_str();
+}
+
+/* Inline C++ wrappers. */
+namespace upb {
+
+inline Def* Def::Dup(const void* owner) const {
+ return upb_def_dup(this, owner);
+}
+inline Def::Type Def::def_type() const { return upb_def_type(this); }
+inline const char* Def::full_name() const { return upb_def_fullname(this); }
+inline bool Def::set_full_name(const char* fullname, Status* s) {
+ return upb_def_setfullname(this, fullname, s);
+}
+inline bool Def::set_full_name(const std::string& fullname, Status* s) {
+ return upb_def_setfullname(this, upb_safecstr(fullname), s);
+}
+inline bool Def::Freeze(Def* const* defs, int n, Status* status) {
+ return upb_def_freeze(defs, n, status);
+}
+inline bool Def::Freeze(const std::vector<Def*>& defs, Status* status) {
+ return upb_def_freeze((Def* const*)&defs[0], defs.size(), status);
+}
+
+inline bool FieldDef::CheckType(int32_t val) {
+ return upb_fielddef_checktype(val);
+}
+inline bool FieldDef::CheckLabel(int32_t val) {
+ return upb_fielddef_checklabel(val);
+}
+inline bool FieldDef::CheckDescriptorType(int32_t val) {
+ return upb_fielddef_checkdescriptortype(val);
+}
+inline bool FieldDef::CheckIntegerFormat(int32_t val) {
+ return upb_fielddef_checkintfmt(val);
+}
+inline FieldDef::Type FieldDef::ConvertType(int32_t val) {
+ assert(CheckType(val));
+ return static_cast<FieldDef::Type>(val);
+}
+inline FieldDef::Label FieldDef::ConvertLabel(int32_t val) {
+ assert(CheckLabel(val));
+ return static_cast<FieldDef::Label>(val);
+}
+inline FieldDef::DescriptorType FieldDef::ConvertDescriptorType(int32_t val) {
+ assert(CheckDescriptorType(val));
+ return static_cast<FieldDef::DescriptorType>(val);
+}
+inline FieldDef::IntegerFormat FieldDef::ConvertIntegerFormat(int32_t val) {
+ assert(CheckIntegerFormat(val));
+ return static_cast<FieldDef::IntegerFormat>(val);
+}
+
+inline reffed_ptr<FieldDef> FieldDef::New() {
+ upb_fielddef *f = upb_fielddef_new(&f);
+ return reffed_ptr<FieldDef>(f, &f);
+}
+inline FieldDef* FieldDef::Dup(const void* owner) const {
+ return upb_fielddef_dup(this, owner);
+}
+inline const char* FieldDef::full_name() const {
+ return upb_fielddef_fullname(this);
+}
+inline bool FieldDef::set_full_name(const char* fullname, Status* s) {
+ return upb_fielddef_setfullname(this, fullname, s);
+}
+inline bool FieldDef::set_full_name(const std::string& fullname, Status* s) {
+ return upb_fielddef_setfullname(this, upb_safecstr(fullname), s);
+}
+inline bool FieldDef::type_is_set() const {
+ return upb_fielddef_typeisset(this);
+}
+inline FieldDef::Type FieldDef::type() const { return upb_fielddef_type(this); }
+inline FieldDef::DescriptorType FieldDef::descriptor_type() const {
+ return upb_fielddef_descriptortype(this);
+}
+inline FieldDef::Label FieldDef::label() const {
+ return upb_fielddef_label(this);
+}
+inline uint32_t FieldDef::number() const { return upb_fielddef_number(this); }
+inline const char* FieldDef::name() const { return upb_fielddef_name(this); }
+inline bool FieldDef::is_extension() const {
+ return upb_fielddef_isextension(this);
+}
+inline bool FieldDef::lazy() const {
+ return upb_fielddef_lazy(this);
+}
+inline void FieldDef::set_lazy(bool lazy) {
+ upb_fielddef_setlazy(this, lazy);
+}
+inline bool FieldDef::packed() const {
+ return upb_fielddef_packed(this);
+}
+inline void FieldDef::set_packed(bool packed) {
+ upb_fielddef_setpacked(this, packed);
+}
+inline const MessageDef* FieldDef::containing_type() const {
+ return upb_fielddef_containingtype(this);
+}
+inline const OneofDef* FieldDef::containing_oneof() const {
+ return upb_fielddef_containingoneof(this);
+}
+inline const char* FieldDef::containing_type_name() {
+ return upb_fielddef_containingtypename(this);
+}
+inline bool FieldDef::set_number(uint32_t number, Status* s) {
+ return upb_fielddef_setnumber(this, number, s);
+}
+inline bool FieldDef::set_name(const char *name, Status* s) {
+ return upb_fielddef_setname(this, name, s);
+}
+inline bool FieldDef::set_name(const std::string& name, Status* s) {
+ return upb_fielddef_setname(this, upb_safecstr(name), s);
+}
+inline bool FieldDef::set_containing_type_name(const char *name, Status* s) {
+ return upb_fielddef_setcontainingtypename(this, name, s);
+}
+inline bool FieldDef::set_containing_type_name(const std::string &name,
+ Status *s) {
+ return upb_fielddef_setcontainingtypename(this, upb_safecstr(name), s);
+}
+inline void FieldDef::set_type(upb_fieldtype_t type) {
+ upb_fielddef_settype(this, type);
+}
+inline void FieldDef::set_is_extension(bool is_extension) {
+ upb_fielddef_setisextension(this, is_extension);
+}
+inline void FieldDef::set_descriptor_type(FieldDef::DescriptorType type) {
+ upb_fielddef_setdescriptortype(this, type);
+}
+inline void FieldDef::set_label(upb_label_t label) {
+ upb_fielddef_setlabel(this, label);
+}
+inline bool FieldDef::IsSubMessage() const {
+ return upb_fielddef_issubmsg(this);
+}
+inline bool FieldDef::IsString() const { return upb_fielddef_isstring(this); }
+inline bool FieldDef::IsSequence() const { return upb_fielddef_isseq(this); }
+inline bool FieldDef::IsMap() const { return upb_fielddef_ismap(this); }
+inline int64_t FieldDef::default_int64() const {
+ return upb_fielddef_defaultint64(this);
+}
+inline int32_t FieldDef::default_int32() const {
+ return upb_fielddef_defaultint32(this);
+}
+inline uint64_t FieldDef::default_uint64() const {
+ return upb_fielddef_defaultuint64(this);
+}
+inline uint32_t FieldDef::default_uint32() const {
+ return upb_fielddef_defaultuint32(this);
+}
+inline bool FieldDef::default_bool() const {
+ return upb_fielddef_defaultbool(this);
+}
+inline float FieldDef::default_float() const {
+ return upb_fielddef_defaultfloat(this);
+}
+inline double FieldDef::default_double() const {
+ return upb_fielddef_defaultdouble(this);
+}
+inline const char* FieldDef::default_string(size_t* len) const {
+ return upb_fielddef_defaultstr(this, len);
+}
+inline void FieldDef::set_default_int64(int64_t value) {
+ upb_fielddef_setdefaultint64(this, value);
+}
+inline void FieldDef::set_default_int32(int32_t value) {
+ upb_fielddef_setdefaultint32(this, value);
+}
+inline void FieldDef::set_default_uint64(uint64_t value) {
+ upb_fielddef_setdefaultuint64(this, value);
+}
+inline void FieldDef::set_default_uint32(uint32_t value) {
+ upb_fielddef_setdefaultuint32(this, value);
+}
+inline void FieldDef::set_default_bool(bool value) {
+ upb_fielddef_setdefaultbool(this, value);
+}
+inline void FieldDef::set_default_float(float value) {
+ upb_fielddef_setdefaultfloat(this, value);
+}
+inline void FieldDef::set_default_double(double value) {
+ upb_fielddef_setdefaultdouble(this, value);
+}
+inline bool FieldDef::set_default_string(const void *str, size_t len,
+ Status *s) {
+ return upb_fielddef_setdefaultstr(this, str, len, s);
+}
+inline bool FieldDef::set_default_string(const std::string& str, Status* s) {
+ return upb_fielddef_setdefaultstr(this, str.c_str(), str.size(), s);
+}
+inline void FieldDef::set_default_cstr(const char* str, Status* s) {
+ return upb_fielddef_setdefaultcstr(this, str, s);
+}
+inline bool FieldDef::HasSubDef() const { return upb_fielddef_hassubdef(this); }
+inline const Def* FieldDef::subdef() const { return upb_fielddef_subdef(this); }
+inline const MessageDef *FieldDef::message_subdef() const {
+ return upb_fielddef_msgsubdef(this);
+}
+inline const EnumDef *FieldDef::enum_subdef() const {
+ return upb_fielddef_enumsubdef(this);
+}
+inline const char* FieldDef::subdef_name() const {
+ return upb_fielddef_subdefname(this);
+}
+inline bool FieldDef::set_subdef(const Def* subdef, Status* s) {
+ return upb_fielddef_setsubdef(this, subdef, s);
+}
+inline bool FieldDef::set_enum_subdef(const EnumDef* subdef, Status* s) {
+ return upb_fielddef_setenumsubdef(this, subdef, s);
+}
+inline bool FieldDef::set_message_subdef(const MessageDef* subdef, Status* s) {
+ return upb_fielddef_setmsgsubdef(this, subdef, s);
+}
+inline bool FieldDef::set_subdef_name(const char* name, Status* s) {
+ return upb_fielddef_setsubdefname(this, name, s);
+}
+inline bool FieldDef::set_subdef_name(const std::string& name, Status* s) {
+ return upb_fielddef_setsubdefname(this, upb_safecstr(name), s);
+}
+
+inline reffed_ptr<MessageDef> MessageDef::New() {
+ upb_msgdef *m = upb_msgdef_new(&m);
+ return reffed_ptr<MessageDef>(m, &m);
+}
+inline const char *MessageDef::full_name() const {
+ return upb_msgdef_fullname(this);
+}
+inline bool MessageDef::set_full_name(const char* fullname, Status* s) {
+ return upb_msgdef_setfullname(this, fullname, s);
+}
+inline bool MessageDef::set_full_name(const std::string& fullname, Status* s) {
+ return upb_msgdef_setfullname(this, upb_safecstr(fullname), s);
+}
+inline bool MessageDef::Freeze(Status* status) {
+ return upb_msgdef_freeze(this, status);
+}
+inline int MessageDef::field_count() const {
+ return upb_msgdef_numfields(this);
+}
+inline int MessageDef::oneof_count() const {
+ return upb_msgdef_numoneofs(this);
+}
+inline bool MessageDef::AddField(upb_fielddef* f, Status* s) {
+ return upb_msgdef_addfield(this, f, NULL, s);
+}
+inline bool MessageDef::AddField(const reffed_ptr<FieldDef>& f, Status* s) {
+ return upb_msgdef_addfield(this, f.get(), NULL, s);
+}
+inline bool MessageDef::AddOneof(upb_oneofdef* o, Status* s) {
+ return upb_msgdef_addoneof(this, o, NULL, s);
+}
+inline bool MessageDef::AddOneof(const reffed_ptr<OneofDef>& o, Status* s) {
+ return upb_msgdef_addoneof(this, o.get(), NULL, s);
+}
+inline FieldDef* MessageDef::FindFieldByNumber(uint32_t number) {
+ return upb_msgdef_itof_mutable(this, number);
+}
+inline FieldDef* MessageDef::FindFieldByName(const char* name, size_t len) {
+ return upb_msgdef_ntof_mutable(this, name, len);
+}
+inline const FieldDef* MessageDef::FindFieldByNumber(uint32_t number) const {
+ return upb_msgdef_itof(this, number);
+}
+inline const FieldDef *MessageDef::FindFieldByName(const char *name,
+ size_t len) const {
+ return upb_msgdef_ntof(this, name, len);
+}
+inline OneofDef* MessageDef::FindOneofByName(const char* name, size_t len) {
+ return upb_msgdef_ntoo_mutable(this, name, len);
+}
+inline const OneofDef* MessageDef::FindOneofByName(const char* name,
+ size_t len) const {
+ return upb_msgdef_ntoo(this, name, len);
+}
+inline MessageDef* MessageDef::Dup(const void *owner) const {
+ return upb_msgdef_dup(this, owner);
+}
+inline void MessageDef::setmapentry(bool map_entry) {
+ upb_msgdef_setmapentry(this, map_entry);
+}
+inline bool MessageDef::mapentry() const {
+ return upb_msgdef_mapentry(this);
+}
+inline MessageDef::field_iterator MessageDef::field_begin() {
+ return field_iterator(this);
+}
+inline MessageDef::field_iterator MessageDef::field_end() {
+ return field_iterator::end(this);
+}
+inline MessageDef::const_field_iterator MessageDef::field_begin() const {
+ return const_field_iterator(this);
+}
+inline MessageDef::const_field_iterator MessageDef::field_end() const {
+ return const_field_iterator::end(this);
+}
+
+inline MessageDef::oneof_iterator MessageDef::oneof_begin() {
+ return oneof_iterator(this);
+}
+inline MessageDef::oneof_iterator MessageDef::oneof_end() {
+ return oneof_iterator::end(this);
+}
+inline MessageDef::const_oneof_iterator MessageDef::oneof_begin() const {
+ return const_oneof_iterator(this);
+}
+inline MessageDef::const_oneof_iterator MessageDef::oneof_end() const {
+ return const_oneof_iterator::end(this);
+}
+
+inline MessageDef::field_iterator::field_iterator(MessageDef* md) {
+ upb_msg_field_begin(&iter_, md);
+}
+inline MessageDef::field_iterator MessageDef::field_iterator::end(
+ MessageDef* md) {
+ MessageDef::field_iterator iter(md);
+ upb_msg_field_iter_setdone(&iter.iter_);
+ return iter;
+}
+inline FieldDef* MessageDef::field_iterator::operator*() const {
+ return upb_msg_iter_field(&iter_);
+}
+inline void MessageDef::field_iterator::operator++() {
+ return upb_msg_field_next(&iter_);
+}
+inline bool MessageDef::field_iterator::operator==(
+ const field_iterator &other) const {
+ return upb_inttable_iter_isequal(&iter_, &other.iter_);
+}
+inline bool MessageDef::field_iterator::operator!=(
+ const field_iterator &other) const {
+ return !(*this == other);
+}
+
+inline MessageDef::const_field_iterator::const_field_iterator(
+ const MessageDef* md) {
+ upb_msg_field_begin(&iter_, md);
+}
+inline MessageDef::const_field_iterator MessageDef::const_field_iterator::end(
+ const MessageDef *md) {
+ MessageDef::const_field_iterator iter(md);
+ upb_msg_field_iter_setdone(&iter.iter_);
+ return iter;
+}
+inline const FieldDef* MessageDef::const_field_iterator::operator*() const {
+ return upb_msg_iter_field(&iter_);
+}
+inline void MessageDef::const_field_iterator::operator++() {
+ return upb_msg_field_next(&iter_);
+}
+inline bool MessageDef::const_field_iterator::operator==(
+ const const_field_iterator &other) const {
+ return upb_inttable_iter_isequal(&iter_, &other.iter_);
+}
+inline bool MessageDef::const_field_iterator::operator!=(
+ const const_field_iterator &other) const {
+ return !(*this == other);
+}
+
+inline MessageDef::oneof_iterator::oneof_iterator(MessageDef* md) {
+ upb_msg_oneof_begin(&iter_, md);
+}
+inline MessageDef::oneof_iterator MessageDef::oneof_iterator::end(
+ MessageDef* md) {
+ MessageDef::oneof_iterator iter(md);
+ upb_msg_oneof_iter_setdone(&iter.iter_);
+ return iter;
+}
+inline OneofDef* MessageDef::oneof_iterator::operator*() const {
+ return upb_msg_iter_oneof(&iter_);
+}
+inline void MessageDef::oneof_iterator::operator++() {
+ return upb_msg_oneof_next(&iter_);
+}
+inline bool MessageDef::oneof_iterator::operator==(
+ const oneof_iterator &other) const {
+ return upb_strtable_iter_isequal(&iter_, &other.iter_);
+}
+inline bool MessageDef::oneof_iterator::operator!=(
+ const oneof_iterator &other) const {
+ return !(*this == other);
+}
+
+inline MessageDef::const_oneof_iterator::const_oneof_iterator(
+ const MessageDef* md) {
+ upb_msg_oneof_begin(&iter_, md);
+}
+inline MessageDef::const_oneof_iterator MessageDef::const_oneof_iterator::end(
+ const MessageDef *md) {
+ MessageDef::const_oneof_iterator iter(md);
+ upb_msg_oneof_iter_setdone(&iter.iter_);
+ return iter;
+}
+inline const OneofDef* MessageDef::const_oneof_iterator::operator*() const {
+ return upb_msg_iter_oneof(&iter_);
+}
+inline void MessageDef::const_oneof_iterator::operator++() {
+ return upb_msg_oneof_next(&iter_);
+}
+inline bool MessageDef::const_oneof_iterator::operator==(
+ const const_oneof_iterator &other) const {
+ return upb_strtable_iter_isequal(&iter_, &other.iter_);
+}
+inline bool MessageDef::const_oneof_iterator::operator!=(
+ const const_oneof_iterator &other) const {
+ return !(*this == other);
+}
+
+inline reffed_ptr<EnumDef> EnumDef::New() {
+ upb_enumdef *e = upb_enumdef_new(&e);
+ return reffed_ptr<EnumDef>(e, &e);
+}
+inline const char* EnumDef::full_name() const {
+ return upb_enumdef_fullname(this);
+}
+inline bool EnumDef::set_full_name(const char* fullname, Status* s) {
+ return upb_enumdef_setfullname(this, fullname, s);
+}
+inline bool EnumDef::set_full_name(const std::string& fullname, Status* s) {
+ return upb_enumdef_setfullname(this, upb_safecstr(fullname), s);
+}
+inline bool EnumDef::Freeze(Status* status) {
+ return upb_enumdef_freeze(this, status);
+}
+inline int32_t EnumDef::default_value() const {
+ return upb_enumdef_default(this);
+}
+inline bool EnumDef::set_default_value(int32_t val, Status* status) {
+ return upb_enumdef_setdefault(this, val, status);
+}
+inline int EnumDef::value_count() const { return upb_enumdef_numvals(this); }
+inline bool EnumDef::AddValue(const char* name, int32_t num, Status* status) {
+ return upb_enumdef_addval(this, name, num, status);
+}
+inline bool EnumDef::AddValue(const std::string& name, int32_t num,
+ Status* status) {
+ return upb_enumdef_addval(this, upb_safecstr(name), num, status);
+}
+inline bool EnumDef::FindValueByName(const char* name, int32_t *num) const {
+ return upb_enumdef_ntoiz(this, name, num);
+}
+inline const char* EnumDef::FindValueByNumber(int32_t num) const {
+ return upb_enumdef_iton(this, num);
+}
+inline EnumDef* EnumDef::Dup(const void* owner) const {
+ return upb_enumdef_dup(this, owner);
+}
+
+inline EnumDef::Iterator::Iterator(const EnumDef* e) {
+ upb_enum_begin(&iter_, e);
+}
+inline int32_t EnumDef::Iterator::number() {
+ return upb_enum_iter_number(&iter_);
+}
+inline const char* EnumDef::Iterator::name() {
+ return upb_enum_iter_name(&iter_);
+}
+inline bool EnumDef::Iterator::Done() { return upb_enum_done(&iter_); }
+inline void EnumDef::Iterator::Next() { return upb_enum_next(&iter_); }
+
+inline reffed_ptr<OneofDef> OneofDef::New() {
+ upb_oneofdef *o = upb_oneofdef_new(&o);
+ return reffed_ptr<OneofDef>(o, &o);
+}
+inline const char* OneofDef::full_name() const {
+ return upb_oneofdef_name(this);
+}
+
+inline const MessageDef* OneofDef::containing_type() const {
+ return upb_oneofdef_containingtype(this);
+}
+inline const char* OneofDef::name() const {
+ return upb_oneofdef_name(this);
+}
+inline bool OneofDef::set_name(const char* name, Status* s) {
+ return upb_oneofdef_setname(this, name, s);
+}
+inline int OneofDef::field_count() const {
+ return upb_oneofdef_numfields(this);
+}
+inline bool OneofDef::AddField(FieldDef* field, Status* s) {
+ return upb_oneofdef_addfield(this, field, NULL, s);
+}
+inline bool OneofDef::AddField(const reffed_ptr<FieldDef>& field, Status* s) {
+ return upb_oneofdef_addfield(this, field.get(), NULL, s);
+}
+inline const FieldDef* OneofDef::FindFieldByName(const char* name,
+ size_t len) const {
+ return upb_oneofdef_ntof(this, name, len);
+}
+inline const FieldDef* OneofDef::FindFieldByNumber(uint32_t num) const {
+ return upb_oneofdef_itof(this, num);
+}
+inline OneofDef::iterator OneofDef::begin() { return iterator(this); }
+inline OneofDef::iterator OneofDef::end() { return iterator::end(this); }
+inline OneofDef::const_iterator OneofDef::begin() const {
+ return const_iterator(this);
+}
+inline OneofDef::const_iterator OneofDef::end() const {
+ return const_iterator::end(this);
+}
+
+inline OneofDef::iterator::iterator(OneofDef* o) {
+ upb_oneof_begin(&iter_, o);
+}
+inline OneofDef::iterator OneofDef::iterator::end(OneofDef* o) {
+ OneofDef::iterator iter(o);
+ upb_oneof_iter_setdone(&iter.iter_);
+ return iter;
+}
+inline FieldDef* OneofDef::iterator::operator*() const {
+ return upb_oneof_iter_field(&iter_);
+}
+inline void OneofDef::iterator::operator++() { return upb_oneof_next(&iter_); }
+inline bool OneofDef::iterator::operator==(const iterator &other) const {
+ return upb_inttable_iter_isequal(&iter_, &other.iter_);
+}
+inline bool OneofDef::iterator::operator!=(const iterator &other) const {
+ return !(*this == other);
+}
+
+inline OneofDef::const_iterator::const_iterator(const OneofDef* md) {
+ upb_oneof_begin(&iter_, md);
+}
+inline OneofDef::const_iterator OneofDef::const_iterator::end(
+ const OneofDef *md) {
+ OneofDef::const_iterator iter(md);
+ upb_oneof_iter_setdone(&iter.iter_);
+ return iter;
+}
+inline const FieldDef* OneofDef::const_iterator::operator*() const {
+ return upb_msg_iter_field(&iter_);
+}
+inline void OneofDef::const_iterator::operator++() {
+ return upb_oneof_next(&iter_);
+}
+inline bool OneofDef::const_iterator::operator==(
+ const const_iterator &other) const {
+ return upb_inttable_iter_isequal(&iter_, &other.iter_);
+}
+inline bool OneofDef::const_iterator::operator!=(
+ const const_iterator &other) const {
+ return !(*this == other);
+}
+
+} /* namespace upb */
+#endif
+
+#endif /* UPB_DEF_H_ */
+/*
+** This file contains definitions of structs that should be considered private
+** and NOT stable across versions of upb.
+**
+** The only reason they are declared here and not in .c files is to allow upb
+** and the application (if desired) to embed statically-initialized instances
+** of structures like defs.
+**
+** If you include this file, all guarantees of ABI compatibility go out the
+** window! Any code that includes this file needs to recompile against the
+** exact same version of upb that they are linking against.
+**
+** You also need to recompile if you change the value of the UPB_DEBUG_REFS
+** flag.
+*/
+
+
+#ifndef UPB_STATICINIT_H_
+#define UPB_STATICINIT_H_
+
+#ifdef __cplusplus
+/* Because of how we do our typedefs, this header can't be included from C++. */
+#error This file cannot be included from C++
+#endif
+
+/* upb_refcounted *************************************************************/
+
+
+/* upb_def ********************************************************************/
+
+struct upb_def {
+ upb_refcounted base;
+
+ const char *fullname;
+ char type; /* A upb_deftype_t (char to save space) */
+
+ /* Used as a flag during the def's mutable stage. Must be false unless
+ * it is currently being used by a function on the stack. This allows
+ * us to easily determine which defs were passed into the function's
+ * current invocation. */
+ bool came_from_user;
+};
+
+#define UPB_DEF_INIT(name, type, refs, ref2s) \
+ { UPB_REFCOUNT_INIT(refs, ref2s), name, type, false }
+
+
+/* upb_fielddef ***************************************************************/
+
+struct upb_fielddef {
+ upb_def base;
+
+ union {
+ int64_t sint;
+ uint64_t uint;
+ double dbl;
+ float flt;
+ void *bytes;
+ } defaultval;
+ union {
+ const upb_msgdef *def; /* If !msg_is_symbolic. */
+ char *name; /* If msg_is_symbolic. */
+ } msg;
+ union {
+ const upb_def *def; /* If !subdef_is_symbolic. */
+ char *name; /* If subdef_is_symbolic. */
+ } sub; /* The msgdef or enumdef for this field, if upb_hassubdef(f). */
+ bool subdef_is_symbolic;
+ bool msg_is_symbolic;
+ const upb_oneofdef *oneof;
+ bool default_is_string;
+ bool type_is_set_; /* False until type is explicitly set. */
+ bool is_extension_;
+ bool lazy_;
+ bool packed_;
+ upb_intfmt_t intfmt;
+ bool tagdelim;
+ upb_fieldtype_t type_;
+ upb_label_t label_;
+ uint32_t number_;
+ uint32_t selector_base; /* Used to index into a upb::Handlers table. */
+ uint32_t index_;
+};
+
+#define UPB_FIELDDEF_INIT(label, type, intfmt, tagdelim, is_extension, lazy, \
+ packed, name, num, msgdef, subdef, selector_base, \
+ index, defaultval, refs, ref2s) \
+ { \
+ UPB_DEF_INIT(name, UPB_DEF_FIELD, refs, ref2s), defaultval, {msgdef}, \
+ {subdef}, NULL, false, false, \
+ type == UPB_TYPE_STRING || type == UPB_TYPE_BYTES, true, is_extension, \
+ lazy, packed, intfmt, tagdelim, type, label, num, selector_base, index \
+ }
+
+
+/* upb_msgdef *****************************************************************/
+
+struct upb_msgdef {
+ upb_def base;
+
+ size_t selector_count;
+ uint32_t submsg_field_count;
+
+ /* Tables for looking up fields by number and name. */
+ upb_inttable itof; /* int to field */
+ upb_strtable ntof; /* name to field */
+
+ /* Tables for looking up oneofs by name. */
+ upb_strtable ntoo; /* name to oneof */
+
+ /* Is this a map-entry message?
+ * TODO: set this flag properly for static descriptors; regenerate
+ * descriptor.upb.c. */
+ bool map_entry;
+
+ /* TODO(haberman): proper extension ranges (there can be multiple). */
+};
+
+/* TODO: also support static initialization of the oneofs table. This will be
+ * needed if we compile in descriptors that contain oneofs. */
+#define UPB_MSGDEF_INIT(name, selector_count, submsg_field_count, itof, ntof, \
+ refs, ref2s) \
+ { \
+ UPB_DEF_INIT(name, UPB_DEF_MSG, refs, ref2s), selector_count, \
+ submsg_field_count, itof, ntof, \
+ UPB_EMPTY_STRTABLE_INIT(UPB_CTYPE_PTR), false \
+ }
+
+
+/* upb_enumdef ****************************************************************/
+
+struct upb_enumdef {
+ upb_def base;
+
+ upb_strtable ntoi;
+ upb_inttable iton;
+ int32_t defaultval;
+};
+
+#define UPB_ENUMDEF_INIT(name, ntoi, iton, defaultval, refs, ref2s) \
+ { UPB_DEF_INIT(name, UPB_DEF_ENUM, refs, ref2s), ntoi, iton, defaultval }
+
+
+/* upb_oneofdef ***************************************************************/
+
+struct upb_oneofdef {
+ upb_def base;
+
+ upb_strtable ntof;
+ upb_inttable itof;
+ const upb_msgdef *parent;
+};
+
+#define UPB_ONEOFDEF_INIT(name, ntof, itof, refs, ref2s) \
+ { UPB_DEF_INIT(name, UPB_DEF_ENUM, refs, ref2s), ntof, itof }
+
+
+/* upb_symtab *****************************************************************/
+
+struct upb_symtab {
+ upb_refcounted base;
+
+ upb_strtable symtab;
+};
+
+#define UPB_SYMTAB_INIT(symtab, refs, ref2s) \
+ { UPB_REFCOUNT_INIT(refs, ref2s), symtab }
+
+
+#endif /* UPB_STATICINIT_H_ */
+/*
+** upb::Handlers (upb_handlers)
+**
+** A upb_handlers is like a virtual table for a upb_msgdef. Each field of the
+** message can have associated functions that will be called when we are
+** parsing or visiting a stream of data. This is similar to how handlers work
+** in SAX (the Simple API for XML).
+**
+** The handlers have no idea where the data is coming from, so a single set of
+** handlers could be used with two completely different data sources (for
+** example, a parser and a visitor over in-memory objects). This decoupling is
+** the most important feature of upb, because it allows parsers and serializers
+** to be highly reusable.
+**
+** This is a mixed C/C++ interface that offers a full API to both languages.
+** See the top-level README for more information.
+*/
+
+#ifndef UPB_HANDLERS_H
+#define UPB_HANDLERS_H
+
+
+#ifdef __cplusplus
+namespace upb {
+class BufferHandle;
+class BytesHandler;
+class HandlerAttributes;
+class Handlers;
+template <class T> class Handler;
+template <class T> struct CanonicalType;
+} /* namespace upb */
+#endif
+
+UPB_DECLARE_TYPE(upb::BufferHandle, upb_bufhandle)
+UPB_DECLARE_TYPE(upb::BytesHandler, upb_byteshandler)
+UPB_DECLARE_TYPE(upb::HandlerAttributes, upb_handlerattr)
+UPB_DECLARE_DERIVED_TYPE(upb::Handlers, upb::RefCounted,
+ upb_handlers, upb_refcounted)
+
+/* The maximum depth that the handler graph can have. This is a resource limit
+ * for the C stack since we sometimes need to recursively traverse the graph.
+ * Cycles are ok; the traversal will stop when it detects a cycle, but we must
+ * hit the cycle before the maximum depth is reached.
+ *
+ * If having a single static limit is too inflexible, we can add another variant
+ * of Handlers::Freeze that allows specifying this as a parameter. */
+#define UPB_MAX_HANDLER_DEPTH 64
+
+/* All the different types of handlers that can be registered.
+ * Only needed for the advanced functions in upb::Handlers. */
+typedef enum {
+ UPB_HANDLER_INT32,
+ UPB_HANDLER_INT64,
+ UPB_HANDLER_UINT32,
+ UPB_HANDLER_UINT64,
+ UPB_HANDLER_FLOAT,
+ UPB_HANDLER_DOUBLE,
+ UPB_HANDLER_BOOL,
+ UPB_HANDLER_STARTSTR,
+ UPB_HANDLER_STRING,
+ UPB_HANDLER_ENDSTR,
+ UPB_HANDLER_STARTSUBMSG,
+ UPB_HANDLER_ENDSUBMSG,
+ UPB_HANDLER_STARTSEQ,
+ UPB_HANDLER_ENDSEQ
+} upb_handlertype_t;
+
+#define UPB_HANDLER_MAX (UPB_HANDLER_ENDSEQ+1)
+
+#define UPB_BREAK NULL
+
+/* A convenient definition for when no closure is needed. */
+extern char _upb_noclosure;
+#define UPB_NO_CLOSURE &_upb_noclosure
+
+/* A selector refers to a specific field handler in the Handlers object
+ * (for example: the STARTSUBMSG handler for field "field15"). */
+typedef int32_t upb_selector_t;
+
+UPB_BEGIN_EXTERN_C
+
+/* Forward-declares for C inline accessors. We need to declare these here
+ * so we can "friend" them in the class declarations in C++. */
+UPB_INLINE upb_func *upb_handlers_gethandler(const upb_handlers *h,
+ upb_selector_t s);
+UPB_INLINE const void *upb_handlerattr_handlerdata(const upb_handlerattr *attr);
+UPB_INLINE const void *upb_handlers_gethandlerdata(const upb_handlers *h,
+ upb_selector_t s);
+
+UPB_INLINE void upb_bufhandle_init(upb_bufhandle *h);
+UPB_INLINE void upb_bufhandle_setobj(upb_bufhandle *h, const void *obj,
+ const void *type);
+UPB_INLINE void upb_bufhandle_setbuf(upb_bufhandle *h, const char *buf,
+ size_t ofs);
+UPB_INLINE const void *upb_bufhandle_obj(const upb_bufhandle *h);
+UPB_INLINE const void *upb_bufhandle_objtype(const upb_bufhandle *h);
+UPB_INLINE const char *upb_bufhandle_buf(const upb_bufhandle *h);
+
+UPB_END_EXTERN_C
+
+
+/* Static selectors for upb::Handlers. */
+#define UPB_STARTMSG_SELECTOR 0
+#define UPB_ENDMSG_SELECTOR 1
+#define UPB_STATIC_SELECTOR_COUNT 2
+
+/* Static selectors for upb::BytesHandler. */
+#define UPB_STARTSTR_SELECTOR 0
+#define UPB_STRING_SELECTOR 1
+#define UPB_ENDSTR_SELECTOR 2
+
+typedef void upb_handlerfree(void *d);
+
+#ifdef __cplusplus
+
+/* A set of attributes that accompanies a handler's function pointer. */
+class upb::HandlerAttributes {
+ public:
+ HandlerAttributes();
+ ~HandlerAttributes();
+
+ /* Sets the handler data that will be passed as the second parameter of the
+ * handler. To free this pointer when the handlers are freed, call
+ * Handlers::AddCleanup(). */
+ bool SetHandlerData(const void *handler_data);
+ const void* handler_data() const;
+
+ /* Use this to specify the type of the closure. This will be checked against
+ * all other closure types for handler that use the same closure.
+ * Registration will fail if this does not match all other non-NULL closure
+ * types. */
+ bool SetClosureType(const void *closure_type);
+ const void* closure_type() const;
+
+ /* Use this to specify the type of the returned closure. Only used for
+ * Start*{String,SubMessage,Sequence} handlers. This must match the closure
+ * type of any handlers that use it (for example, the StringBuf handler must
+ * match the closure returned from StartString). */
+ bool SetReturnClosureType(const void *return_closure_type);
+ const void* return_closure_type() const;
+
+ /* Set to indicate that the handler always returns "ok" (either "true" or a
+ * non-NULL closure). This is a hint that can allow code generators to
+ * generate more efficient code. */
+ bool SetAlwaysOk(bool always_ok);
+ bool always_ok() const;
+
+ private:
+ friend UPB_INLINE const void * ::upb_handlerattr_handlerdata(
+ const upb_handlerattr *attr);
+#else
+struct upb_handlerattr {
+#endif
+ const void *handler_data_;
+ const void *closure_type_;
+ const void *return_closure_type_;
+ bool alwaysok_;
+};
+
+#define UPB_HANDLERATTR_INITIALIZER {NULL, NULL, NULL, false}
+
+typedef struct {
+ upb_func *func;
+
+ /* It is wasteful to include the entire attributes here:
+ *
+ * * Some of the information is redundant (like storing the closure type
+ * separately for each handler that must match).
+ * * Some of the info is only needed prior to freeze() (like closure types).
+ * * alignment padding wastes a lot of space for alwaysok_.
+ *
+ * If/when the size and locality of handlers is an issue, we can optimize this
+ * not to store the entire attr like this. We do not expose the table's
+ * layout to allow this optimization in the future. */
+ upb_handlerattr attr;
+} upb_handlers_tabent;
+
+#ifdef __cplusplus
+
+/* Extra information about a buffer that is passed to a StringBuf handler.
+ * TODO(haberman): allow the handle to be pinned so that it will outlive
+ * the handler invocation. */
+class upb::BufferHandle {
+ public:
+ BufferHandle();
+ ~BufferHandle();
+
+ /* The beginning of the buffer. This may be different than the pointer
+ * passed to a StringBuf handler because the handler may receive data
+ * that is from the middle or end of a larger buffer. */
+ const char* buffer() const;
+
+ /* The offset within the attached object where this buffer begins. Only
+ * meaningful if there is an attached object. */
+ size_t object_offset() const;
+
+ /* Note that object_offset is the offset of "buf" within the attached
+ * object. */
+ void SetBuffer(const char* buf, size_t object_offset);
+
+ /* The BufferHandle can have an "attached object", which can be used to
+ * tunnel through a pointer to the buffer's underlying representation. */
+ template <class T>
+ void SetAttachedObject(const T* obj);
+
+ /* Returns NULL if the attached object is not of this type. */
+ template <class T>
+ const T* GetAttachedObject() const;
+
+ private:
+ friend UPB_INLINE void ::upb_bufhandle_init(upb_bufhandle *h);
+ friend UPB_INLINE void ::upb_bufhandle_setobj(upb_bufhandle *h,
+ const void *obj,
+ const void *type);
+ friend UPB_INLINE void ::upb_bufhandle_setbuf(upb_bufhandle *h,
+ const char *buf, size_t ofs);
+ friend UPB_INLINE const void* ::upb_bufhandle_obj(const upb_bufhandle *h);
+ friend UPB_INLINE const void* ::upb_bufhandle_objtype(
+ const upb_bufhandle *h);
+ friend UPB_INLINE const char* ::upb_bufhandle_buf(const upb_bufhandle *h);
+#else
+struct upb_bufhandle {
+#endif
+ const char *buf_;
+ const void *obj_;
+ const void *objtype_;
+ size_t objofs_;
+};
+
+#ifdef __cplusplus
+
+/* A upb::Handlers object represents the set of handlers associated with a
+ * message in the graph of messages. You can think of it as a big virtual
+ * table with functions corresponding to all the events that can fire while
+ * parsing or visiting a message of a specific type.
+ *
+ * Any handlers that are not set behave as if they had successfully consumed
+ * the value. Any unset Start* handlers will propagate their closure to the
+ * inner frame.
+ *
+ * The easiest way to create the *Handler objects needed by the Set* methods is
+ * with the UpbBind() and UpbMakeHandler() macros; see below. */
+class upb::Handlers {
+ public:
+ typedef upb_selector_t Selector;
+ typedef upb_handlertype_t Type;
+
+ typedef Handler<void *(*)(void *, const void *)> StartFieldHandler;
+ typedef Handler<bool (*)(void *, const void *)> EndFieldHandler;
+ typedef Handler<bool (*)(void *, const void *)> StartMessageHandler;
+ typedef Handler<bool (*)(void *, const void *, Status*)> EndMessageHandler;
+ typedef Handler<void *(*)(void *, const void *, size_t)> StartStringHandler;
+ typedef Handler<size_t (*)(void *, const void *, const char *, size_t,
+ const BufferHandle *)> StringHandler;
+
+ template <class T> struct ValueHandler {
+ typedef Handler<bool(*)(void *, const void *, T)> H;
+ };
+
+ typedef ValueHandler<int32_t>::H Int32Handler;
+ typedef ValueHandler<int64_t>::H Int64Handler;
+ typedef ValueHandler<uint32_t>::H UInt32Handler;
+ typedef ValueHandler<uint64_t>::H UInt64Handler;
+ typedef ValueHandler<float>::H FloatHandler;
+ typedef ValueHandler<double>::H DoubleHandler;
+ typedef ValueHandler<bool>::H BoolHandler;
+
+ /* Any function pointer can be converted to this and converted back to its
+ * correct type. */
+ typedef void GenericFunction();
+
+ typedef void HandlersCallback(const void *closure, upb_handlers *h);
+
+ /* Returns a new handlers object for the given frozen msgdef.
+ * Returns NULL if memory allocation failed. */
+ static reffed_ptr<Handlers> New(const MessageDef *m);
+
+ /* Convenience function for registering a graph of handlers that mirrors the
+ * graph of msgdefs for some message. For "m" and all its children a new set
+ * of handlers will be created and the given callback will be invoked,
+ * allowing the client to register handlers for this message. Note that any
+ * subhandlers set by the callback will be overwritten. */
+ static reffed_ptr<const Handlers> NewFrozen(const MessageDef *m,
+ HandlersCallback *callback,
+ const void *closure);
+
+ /* Functionality from upb::RefCounted. */
+ UPB_REFCOUNTED_CPPMETHODS
+
+ /* All handler registration functions return bool to indicate success or
+ * failure; details about failures are stored in this status object. If a
+ * failure does occur, it must be cleared before the Handlers are frozen,
+ * otherwise the freeze() operation will fail. The functions may *only* be
+ * used while the Handlers are mutable. */
+ const Status* status();
+ void ClearError();
+
+ /* Call to freeze these Handlers. Requires that any SubHandlers are already
+ * frozen. For cycles, you must use the static version below and freeze the
+ * whole graph at once. */
+ bool Freeze(Status* s);
+
+ /* Freezes the given set of handlers. You may not freeze a handler without
+ * also freezing any handlers they point to. */
+ static bool Freeze(Handlers*const* handlers, int n, Status* s);
+ static bool Freeze(const std::vector<Handlers*>& handlers, Status* s);
+
+ /* Returns the msgdef associated with this handlers object. */
+ const MessageDef* message_def() const;
+
+ /* Adds the given pointer and function to the list of cleanup functions that
+ * will be run when these handlers are freed. If this pointer has previously
+ * been registered, the function returns false and does nothing. */
+ bool AddCleanup(void *ptr, upb_handlerfree *cleanup);
+
+ /* Sets the startmsg handler for the message, which is defined as follows:
+ *
+ * bool startmsg(MyType* closure) {
+ * // Called when the message begins. Returns true if processing should
+ * // continue.
+ * return true;
+ * }
+ */
+ bool SetStartMessageHandler(const StartMessageHandler& handler);
+
+ /* Sets the endmsg handler for the message, which is defined as follows:
+ *
+ * bool endmsg(MyType* closure, upb_status *status) {
+ * // Called when processing of this message ends, whether in success or
+ * // failure. "status" indicates the final status of processing, and
+ * // can also be modified in-place to update the final status.
+ * }
+ */
+ bool SetEndMessageHandler(const EndMessageHandler& handler);
+
+ /* Sets the value handler for the given field, which is defined as follows
+ * (this is for an int32 field; other field types will pass their native
+ * C/C++ type for "val"):
+ *
+ * bool OnValue(MyClosure* c, const MyHandlerData* d, int32_t val) {
+ * // Called when the field's value is encountered. "d" contains
+ * // whatever data was bound to this field when it was registered.
+ * // Returns true if processing should continue.
+ * return true;
+ * }
+ *
+ * handers->SetInt32Handler(f, UpbBind(OnValue, new MyHandlerData(...)));
+ *
+ * The value type must exactly match f->type().
+ * For example, a handler that takes an int32_t parameter may only be used for
+ * fields of type UPB_TYPE_INT32 and UPB_TYPE_ENUM.
+ *
+ * Returns false if the handler failed to register; in this case the cleanup
+ * handler (if any) will be called immediately.
+ */
+ bool SetInt32Handler (const FieldDef* f, const Int32Handler& h);
+ bool SetInt64Handler (const FieldDef* f, const Int64Handler& h);
+ bool SetUInt32Handler(const FieldDef* f, const UInt32Handler& h);
+ bool SetUInt64Handler(const FieldDef* f, const UInt64Handler& h);
+ bool SetFloatHandler (const FieldDef* f, const FloatHandler& h);
+ bool SetDoubleHandler(const FieldDef* f, const DoubleHandler& h);
+ bool SetBoolHandler (const FieldDef* f, const BoolHandler& h);
+
+ /* Like the previous, but templated on the type on the value (ie. int32).
+ * This is mostly useful to call from other templates. To call this you must
+ * specify the template parameter explicitly, ie:
+ * h->SetValueHandler<T>(f, UpbBind(MyHandler<T>, MyData)); */
+ template <class T>
+ bool SetValueHandler(
+ const FieldDef *f,
+ const typename ValueHandler<typename CanonicalType<T>::Type>::H& handler);
+
+ /* Sets handlers for a string field, which are defined as follows:
+ *
+ * MySubClosure* startstr(MyClosure* c, const MyHandlerData* d,
+ * size_t size_hint) {
+ * // Called when a string value begins. The return value indicates the
+ * // closure for the string. "size_hint" indicates the size of the
+ * // string if it is known, however if the string is length-delimited
+ * // and the end-of-string is not available size_hint will be zero.
+ * // This case is indistinguishable from the case where the size is
+ * // known to be zero.
+ * //
+ * // TODO(haberman): is it important to distinguish these cases?
+ * // If we had ssize_t as a type we could make -1 "unknown", but
+ * // ssize_t is POSIX (not ANSI) and therefore less portable.
+ * // In practice I suspect it won't be important to distinguish.
+ * return closure;
+ * }
+ *
+ * size_t str(MyClosure* closure, const MyHandlerData* d,
+ * const char *str, size_t len) {
+ * // Called for each buffer of string data; the multiple physical buffers
+ * // are all part of the same logical string. The return value indicates
+ * // how many bytes were consumed. If this number is less than "len",
+ * // this will also indicate that processing should be halted for now,
+ * // like returning false or UPB_BREAK from any other callback. If
+ * // number is greater than "len", the excess bytes will be skipped over
+ * // and not passed to the callback.
+ * return len;
+ * }
+ *
+ * bool endstr(MyClosure* c, const MyHandlerData* d) {
+ * // Called when a string value ends. Return value indicates whether
+ * // processing should continue.
+ * return true;
+ * }
+ */
+ bool SetStartStringHandler(const FieldDef* f, const StartStringHandler& h);
+ bool SetStringHandler(const FieldDef* f, const StringHandler& h);
+ bool SetEndStringHandler(const FieldDef* f, const EndFieldHandler& h);
+
+ /* Sets the startseq handler, which is defined as follows:
+ *
+ * MySubClosure *startseq(MyClosure* c, const MyHandlerData* d) {
+ * // Called when a sequence (repeated field) begins. The returned
+ * // pointer indicates the closure for the sequence (or UPB_BREAK
+ * // to interrupt processing).
+ * return closure;
+ * }
+ *
+ * h->SetStartSequenceHandler(f, UpbBind(startseq, new MyHandlerData(...)));
+ *
+ * Returns "false" if "f" does not belong to this message or is not a
+ * repeated field.
+ */
+ bool SetStartSequenceHandler(const FieldDef* f, const StartFieldHandler& h);
+
+ /* Sets the startsubmsg handler for the given field, which is defined as
+ * follows:
+ *
+ * MySubClosure* startsubmsg(MyClosure* c, const MyHandlerData* d) {
+ * // Called when a submessage begins. The returned pointer indicates the
+ * // closure for the sequence (or UPB_BREAK to interrupt processing).
+ * return closure;
+ * }
+ *
+ * h->SetStartSubMessageHandler(f, UpbBind(startsubmsg,
+ * new MyHandlerData(...)));
+ *
+ * Returns "false" if "f" does not belong to this message or is not a
+ * submessage/group field.
+ */
+ bool SetStartSubMessageHandler(const FieldDef* f, const StartFieldHandler& h);
+
+ /* Sets the endsubmsg handler for the given field, which is defined as
+ * follows:
+ *
+ * bool endsubmsg(MyClosure* c, const MyHandlerData* d) {
+ * // Called when a submessage ends. Returns true to continue processing.
+ * return true;
+ * }
+ *
+ * Returns "false" if "f" does not belong to this message or is not a
+ * submessage/group field.
+ */
+ bool SetEndSubMessageHandler(const FieldDef *f, const EndFieldHandler &h);
+
+ /* Starts the endsubseq handler for the given field, which is defined as
+ * follows:
+ *
+ * bool endseq(MyClosure* c, const MyHandlerData* d) {
+ * // Called when a sequence ends. Returns true continue processing.
+ * return true;
+ * }
+ *
+ * Returns "false" if "f" does not belong to this message or is not a
+ * repeated field.
+ */
+ bool SetEndSequenceHandler(const FieldDef* f, const EndFieldHandler& h);
+
+ /* Sets or gets the object that specifies handlers for the given field, which
+ * must be a submessage or group. Returns NULL if no handlers are set. */
+ bool SetSubHandlers(const FieldDef* f, const Handlers* sub);
+ const Handlers* GetSubHandlers(const FieldDef* f) const;
+
+ /* Equivalent to GetSubHandlers, but takes the STARTSUBMSG selector for the
+ * field. */
+ const Handlers* GetSubHandlers(Selector startsubmsg) const;
+
+ /* A selector refers to a specific field handler in the Handlers object
+ * (for example: the STARTSUBMSG handler for field "field15").
+ * On success, returns true and stores the selector in "s".
+ * If the FieldDef or Type are invalid, returns false.
+ * The returned selector is ONLY valid for Handlers whose MessageDef
+ * contains this FieldDef. */
+ static bool GetSelector(const FieldDef* f, Type type, Selector* s);
+
+ /* Given a START selector of any kind, returns the corresponding END selector. */
+ static Selector GetEndSelector(Selector start_selector);
+
+ /* Returns the function pointer for this handler. It is the client's
+ * responsibility to cast to the correct function type before calling it. */
+ GenericFunction* GetHandler(Selector selector);
+
+ /* Sets the given attributes to the attributes for this selector. */
+ bool GetAttributes(Selector selector, HandlerAttributes* attr);
+
+ /* Returns the handler data that was registered with this handler. */
+ const void* GetHandlerData(Selector selector);
+
+ /* Could add any of the following functions as-needed, with some minor
+ * implementation changes:
+ *
+ * const FieldDef* GetFieldDef(Selector selector);
+ * static bool IsSequence(Selector selector); */
+
+ private:
+ UPB_DISALLOW_POD_OPS(Handlers, upb::Handlers)
+
+ friend UPB_INLINE GenericFunction *::upb_handlers_gethandler(
+ const upb_handlers *h, upb_selector_t s);
+ friend UPB_INLINE const void *::upb_handlers_gethandlerdata(
+ const upb_handlers *h, upb_selector_t s);
+#else
+struct upb_handlers {
+#endif
+ upb_refcounted base;
+
+ const upb_msgdef *msg;
+ const upb_handlers **sub;
+ const void *top_closure_type;
+ upb_inttable cleanup_;
+ upb_status status_; /* Used only when mutable. */
+ upb_handlers_tabent table[1]; /* Dynamically-sized field handler array. */
+};
+
+#ifdef __cplusplus
+
+namespace upb {
+
+/* Convenience macros for creating a Handler object that is wrapped with a
+ * type-safe wrapper function that converts the "void*" parameters/returns
+ * of the underlying C API into nice C++ function.
+ *
+ * Sample usage:
+ * void OnValue1(MyClosure* c, const MyHandlerData* d, int32_t val) {
+ * // do stuff ...
+ * }
+ *
+ * // Handler that doesn't need any data bound to it.
+ * void OnValue2(MyClosure* c, int32_t val) {
+ * // do stuff ...
+ * }
+ *
+ * // Handler that returns bool so it can return failure if necessary.
+ * bool OnValue3(MyClosure* c, int32_t val) {
+ * // do stuff ...
+ * return ok;
+ * }
+ *
+ * // Member function handler.
+ * class MyClosure {
+ * public:
+ * void OnValue(int32_t val) {
+ * // do stuff ...
+ * }
+ * };
+ *
+ * // Takes ownership of the MyHandlerData.
+ * handlers->SetInt32Handler(f1, UpbBind(OnValue1, new MyHandlerData(...)));
+ * handlers->SetInt32Handler(f2, UpbMakeHandler(OnValue2));
+ * handlers->SetInt32Handler(f1, UpbMakeHandler(OnValue3));
+ * handlers->SetInt32Handler(f2, UpbMakeHandler(&MyClosure::OnValue));
+ */
+
+#ifdef UPB_CXX11
+
+/* In C++11, the "template" disambiguator can appear even outside templates,
+ * so all calls can safely use this pair of macros. */
+
+#define UpbMakeHandler(f) upb::MatchFunc(f).template GetFunc<f>()
+
+/* We have to be careful to only evaluate "d" once. */
+#define UpbBind(f, d) upb::MatchFunc(f).template GetFunc<f>((d))
+
+#else
+
+/* Prior to C++11, the "template" disambiguator may only appear inside a
+ * template, so the regular macro must not use "template" */
+
+#define UpbMakeHandler(f) upb::MatchFunc(f).GetFunc<f>()
+
+#define UpbBind(f, d) upb::MatchFunc(f).GetFunc<f>((d))
+
+#endif /* UPB_CXX11 */
+
+/* This macro must be used in C++98 for calls from inside a template. But we
+ * define this variant in all cases; code that wants to be compatible with both
+ * C++98 and C++11 should always use this macro when calling from a template. */
+#define UpbMakeHandlerT(f) upb::MatchFunc(f).template GetFunc<f>()
+
+/* We have to be careful to only evaluate "d" once. */
+#define UpbBindT(f, d) upb::MatchFunc(f).template GetFunc<f>((d))
+
+/* Handler: a struct that contains the (handler, data, deleter) tuple that is
+ * used to register all handlers. Users can Make() these directly but it's
+ * more convenient to use the UpbMakeHandler/UpbBind macros above. */
+template <class T> class Handler {
+ public:
+ /* The underlying, handler function signature that upb uses internally. */
+ typedef T FuncPtr;
+
+ /* Intentionally implicit. */
+ template <class F> Handler(F func);
+ ~Handler();
+
+ private:
+ void AddCleanup(Handlers* h) const {
+ if (cleanup_func_) {
+ bool ok = h->AddCleanup(cleanup_data_, cleanup_func_);
+ UPB_ASSERT_VAR(ok, ok);
+ }
+ }
+
+ UPB_DISALLOW_COPY_AND_ASSIGN(Handler)
+ friend class Handlers;
+ FuncPtr handler_;
+ mutable HandlerAttributes attr_;
+ mutable bool registered_;
+ void *cleanup_data_;
+ upb_handlerfree *cleanup_func_;
+};
+
+} /* namespace upb */
+
+#endif /* __cplusplus */
+
+UPB_BEGIN_EXTERN_C
+
+/* Native C API. */
+
+/* Handler function typedefs. */
+typedef bool upb_startmsg_handlerfunc(void *c, const void*);
+typedef bool upb_endmsg_handlerfunc(void *c, const void *, upb_status *status);
+typedef void* upb_startfield_handlerfunc(void *c, const void *hd);
+typedef bool upb_endfield_handlerfunc(void *c, const void *hd);
+typedef bool upb_int32_handlerfunc(void *c, const void *hd, int32_t val);
+typedef bool upb_int64_handlerfunc(void *c, const void *hd, int64_t val);
+typedef bool upb_uint32_handlerfunc(void *c, const void *hd, uint32_t val);
+typedef bool upb_uint64_handlerfunc(void *c, const void *hd, uint64_t val);
+typedef bool upb_float_handlerfunc(void *c, const void *hd, float val);
+typedef bool upb_double_handlerfunc(void *c, const void *hd, double val);
+typedef bool upb_bool_handlerfunc(void *c, const void *hd, bool val);
+typedef void *upb_startstr_handlerfunc(void *c, const void *hd,
+ size_t size_hint);
+typedef size_t upb_string_handlerfunc(void *c, const void *hd, const char *buf,
+ size_t n, const upb_bufhandle* handle);
+
+/* upb_bufhandle */
+size_t upb_bufhandle_objofs(const upb_bufhandle *h);
+
+/* upb_handlerattr */
+void upb_handlerattr_init(upb_handlerattr *attr);
+void upb_handlerattr_uninit(upb_handlerattr *attr);
+
+bool upb_handlerattr_sethandlerdata(upb_handlerattr *attr, const void *hd);
+bool upb_handlerattr_setclosuretype(upb_handlerattr *attr, const void *type);
+const void *upb_handlerattr_closuretype(const upb_handlerattr *attr);
+bool upb_handlerattr_setreturnclosuretype(upb_handlerattr *attr,
+ const void *type);
+const void *upb_handlerattr_returnclosuretype(const upb_handlerattr *attr);
+bool upb_handlerattr_setalwaysok(upb_handlerattr *attr, bool alwaysok);
+bool upb_handlerattr_alwaysok(const upb_handlerattr *attr);
+
+UPB_INLINE const void *upb_handlerattr_handlerdata(
+ const upb_handlerattr *attr) {
+ return attr->handler_data_;
+}
+
+/* upb_handlers */
+typedef void upb_handlers_callback(const void *closure, upb_handlers *h);
+upb_handlers *upb_handlers_new(const upb_msgdef *m,
+ const void *owner);
+const upb_handlers *upb_handlers_newfrozen(const upb_msgdef *m,
+ const void *owner,
+ upb_handlers_callback *callback,
+ const void *closure);
+
+/* Include refcounted methods like upb_handlers_ref(). */
+UPB_REFCOUNTED_CMETHODS(upb_handlers, upb_handlers_upcast)
+
+const upb_status *upb_handlers_status(upb_handlers *h);
+void upb_handlers_clearerr(upb_handlers *h);
+const upb_msgdef *upb_handlers_msgdef(const upb_handlers *h);
+bool upb_handlers_addcleanup(upb_handlers *h, void *p, upb_handlerfree *hfree);
+
+bool upb_handlers_setstartmsg(upb_handlers *h, upb_startmsg_handlerfunc *func,
+ upb_handlerattr *attr);
+bool upb_handlers_setendmsg(upb_handlers *h, upb_endmsg_handlerfunc *func,
+ upb_handlerattr *attr);
+bool upb_handlers_setint32(upb_handlers *h, const upb_fielddef *f,
+ upb_int32_handlerfunc *func, upb_handlerattr *attr);
+bool upb_handlers_setint64(upb_handlers *h, const upb_fielddef *f,
+ upb_int64_handlerfunc *func, upb_handlerattr *attr);
+bool upb_handlers_setuint32(upb_handlers *h, const upb_fielddef *f,
+ upb_uint32_handlerfunc *func,
+ upb_handlerattr *attr);
+bool upb_handlers_setuint64(upb_handlers *h, const upb_fielddef *f,
+ upb_uint64_handlerfunc *func,
+ upb_handlerattr *attr);
+bool upb_handlers_setfloat(upb_handlers *h, const upb_fielddef *f,
+ upb_float_handlerfunc *func, upb_handlerattr *attr);
+bool upb_handlers_setdouble(upb_handlers *h, const upb_fielddef *f,
+ upb_double_handlerfunc *func,
+ upb_handlerattr *attr);
+bool upb_handlers_setbool(upb_handlers *h, const upb_fielddef *f,
+ upb_bool_handlerfunc *func,
+ upb_handlerattr *attr);
+bool upb_handlers_setstartstr(upb_handlers *h, const upb_fielddef *f,
+ upb_startstr_handlerfunc *func,
+ upb_handlerattr *attr);
+bool upb_handlers_setstring(upb_handlers *h, const upb_fielddef *f,
+ upb_string_handlerfunc *func,
+ upb_handlerattr *attr);
+bool upb_handlers_setendstr(upb_handlers *h, const upb_fielddef *f,
+ upb_endfield_handlerfunc *func,
+ upb_handlerattr *attr);
+bool upb_handlers_setstartseq(upb_handlers *h, const upb_fielddef *f,
+ upb_startfield_handlerfunc *func,
+ upb_handlerattr *attr);
+bool upb_handlers_setstartsubmsg(upb_handlers *h, const upb_fielddef *f,
+ upb_startfield_handlerfunc *func,
+ upb_handlerattr *attr);
+bool upb_handlers_setendsubmsg(upb_handlers *h, const upb_fielddef *f,
+ upb_endfield_handlerfunc *func,
+ upb_handlerattr *attr);
+bool upb_handlers_setendseq(upb_handlers *h, const upb_fielddef *f,
+ upb_endfield_handlerfunc *func,
+ upb_handlerattr *attr);
+
+bool upb_handlers_setsubhandlers(upb_handlers *h, const upb_fielddef *f,
+ const upb_handlers *sub);
+const upb_handlers *upb_handlers_getsubhandlers(const upb_handlers *h,
+ const upb_fielddef *f);
+const upb_handlers *upb_handlers_getsubhandlers_sel(const upb_handlers *h,
+ upb_selector_t sel);
+
+UPB_INLINE upb_func *upb_handlers_gethandler(const upb_handlers *h,
+ upb_selector_t s) {
+ return (upb_func *)h->table[s].func;
+}
+
+bool upb_handlers_getattr(const upb_handlers *h, upb_selector_t s,
+ upb_handlerattr *attr);
+
+UPB_INLINE const void *upb_handlers_gethandlerdata(const upb_handlers *h,
+ upb_selector_t s) {
+ return upb_handlerattr_handlerdata(&h->table[s].attr);
+}
+
+#ifdef __cplusplus
+
+/* Handler types for single fields.
+ * Right now we only have one for TYPE_BYTES but ones for other types
+ * should follow.
+ *
+ * These follow the same handlers protocol for fields of a message. */
+class upb::BytesHandler {
+ public:
+ BytesHandler();
+ ~BytesHandler();
+#else
+struct upb_byteshandler {
+#endif
+ upb_handlers_tabent table[3];
+};
+
+void upb_byteshandler_init(upb_byteshandler *h);
+
+/* Caller must ensure that "d" outlives the handlers.
+ * TODO(haberman): should this have a "freeze" operation? It's not necessary
+ * for memory management, but could be useful to force immutability and provide
+ * a convenient moment to verify that all registration succeeded. */
+bool upb_byteshandler_setstartstr(upb_byteshandler *h,
+ upb_startstr_handlerfunc *func, void *d);
+bool upb_byteshandler_setstring(upb_byteshandler *h,
+ upb_string_handlerfunc *func, void *d);
+bool upb_byteshandler_setendstr(upb_byteshandler *h,
+ upb_endfield_handlerfunc *func, void *d);
+
+/* "Static" methods */
+bool upb_handlers_freeze(upb_handlers *const *handlers, int n, upb_status *s);
+upb_handlertype_t upb_handlers_getprimitivehandlertype(const upb_fielddef *f);
+bool upb_handlers_getselector(const upb_fielddef *f, upb_handlertype_t type,
+ upb_selector_t *s);
+UPB_INLINE upb_selector_t upb_handlers_getendselector(upb_selector_t start) {
+ return start + 1;
+}
+
+/* Internal-only. */
+uint32_t upb_handlers_selectorbaseoffset(const upb_fielddef *f);
+uint32_t upb_handlers_selectorcount(const upb_fielddef *f);
+
+UPB_END_EXTERN_C
+
+/*
+** Inline definitions for handlers.h, which are particularly long and a bit
+** tricky.
+*/
+
+#ifndef UPB_HANDLERS_INL_H_
+#define UPB_HANDLERS_INL_H_
+
+#include <limits.h>
+
+/* C inline methods. */
+
+/* upb_bufhandle */
+UPB_INLINE void upb_bufhandle_init(upb_bufhandle *h) {
+ h->obj_ = NULL;
+ h->objtype_ = NULL;
+ h->buf_ = NULL;
+ h->objofs_ = 0;
+}
+UPB_INLINE void upb_bufhandle_uninit(upb_bufhandle *h) {
+ UPB_UNUSED(h);
+}
+UPB_INLINE void upb_bufhandle_setobj(upb_bufhandle *h, const void *obj,
+ const void *type) {
+ h->obj_ = obj;
+ h->objtype_ = type;
+}
+UPB_INLINE void upb_bufhandle_setbuf(upb_bufhandle *h, const char *buf,
+ size_t ofs) {
+ h->buf_ = buf;
+ h->objofs_ = ofs;
+}
+UPB_INLINE const void *upb_bufhandle_obj(const upb_bufhandle *h) {
+ return h->obj_;
+}
+UPB_INLINE const void *upb_bufhandle_objtype(const upb_bufhandle *h) {
+ return h->objtype_;
+}
+UPB_INLINE const char *upb_bufhandle_buf(const upb_bufhandle *h) {
+ return h->buf_;
+}
+
+
+#ifdef __cplusplus
+
+/* Type detection and typedefs for integer types.
+ * For platforms where there are multiple 32-bit or 64-bit types, we need to be
+ * able to enumerate them so we can properly create overloads for all variants.
+ *
+ * If any platform existed where there were three integer types with the same
+ * size, this would have to become more complicated. For example, short, int,
+ * and long could all be 32-bits. Even more diabolically, short, int, long,
+ * and long long could all be 64 bits and still be standard-compliant.
+ * However, few platforms are this strange, and it's unlikely that upb will be
+ * used on the strangest ones. */
+
+/* Can't count on stdint.h limits like INT32_MAX, because in C++ these are
+ * only defined when __STDC_LIMIT_MACROS are defined before the *first* include
+ * of stdint.h. We can't guarantee that someone else didn't include these first
+ * without defining __STDC_LIMIT_MACROS. */
+#define UPB_INT32_MAX 0x7fffffffLL
+#define UPB_INT32_MIN (-UPB_INT32_MAX - 1)
+#define UPB_INT64_MAX 0x7fffffffffffffffLL
+#define UPB_INT64_MIN (-UPB_INT64_MAX - 1)
+
+#if INT_MAX == UPB_INT32_MAX && INT_MIN == UPB_INT32_MIN
+#define UPB_INT_IS_32BITS 1
+#endif
+
+#if LONG_MAX == UPB_INT32_MAX && LONG_MIN == UPB_INT32_MIN
+#define UPB_LONG_IS_32BITS 1
+#endif
+
+#if LONG_MAX == UPB_INT64_MAX && LONG_MIN == UPB_INT64_MIN
+#define UPB_LONG_IS_64BITS 1
+#endif
+
+#if LLONG_MAX == UPB_INT64_MAX && LLONG_MIN == UPB_INT64_MIN
+#define UPB_LLONG_IS_64BITS 1
+#endif
+
+/* We use macros instead of typedefs so we can undefine them later and avoid
+ * leaking them outside this header file. */
+#if UPB_INT_IS_32BITS
+#define UPB_INT32_T int
+#define UPB_UINT32_T unsigned int
+
+#if UPB_LONG_IS_32BITS
+#define UPB_TWO_32BIT_TYPES 1
+#define UPB_INT32ALT_T long
+#define UPB_UINT32ALT_T unsigned long
+#endif /* UPB_LONG_IS_32BITS */
+
+#elif UPB_LONG_IS_32BITS /* && !UPB_INT_IS_32BITS */
+#define UPB_INT32_T long
+#define UPB_UINT32_T unsigned long
+#endif /* UPB_INT_IS_32BITS */
+
+
+#if UPB_LONG_IS_64BITS
+#define UPB_INT64_T long
+#define UPB_UINT64_T unsigned long
+
+#if UPB_LLONG_IS_64BITS
+#define UPB_TWO_64BIT_TYPES 1
+#define UPB_INT64ALT_T long long
+#define UPB_UINT64ALT_T unsigned long long
+#endif /* UPB_LLONG_IS_64BITS */
+
+#elif UPB_LLONG_IS_64BITS /* && !UPB_LONG_IS_64BITS */
+#define UPB_INT64_T long long
+#define UPB_UINT64_T unsigned long long
+#endif /* UPB_LONG_IS_64BITS */
+
+#undef UPB_INT32_MAX
+#undef UPB_INT32_MIN
+#undef UPB_INT64_MAX
+#undef UPB_INT64_MIN
+#undef UPB_INT_IS_32BITS
+#undef UPB_LONG_IS_32BITS
+#undef UPB_LONG_IS_64BITS
+#undef UPB_LLONG_IS_64BITS
+
+
+namespace upb {
+
+typedef void CleanupFunc(void *ptr);
+
+/* Template to remove "const" from "const T*" and just return "T*".
+ *
+ * We define a nonsense default because otherwise it will fail to instantiate as
+ * a function parameter type even in cases where we don't expect any caller to
+ * actually match the overload. */
+class CouldntRemoveConst {};
+template <class T> struct remove_constptr { typedef CouldntRemoveConst type; };
+template <class T> struct remove_constptr<const T *> { typedef T *type; };
+
+/* Template that we use below to remove a template specialization from
+ * consideration if it matches a specific type. */
+template <class T, class U> struct disable_if_same { typedef void Type; };
+template <class T> struct disable_if_same<T, T> {};
+
+template <class T> void DeletePointer(void *p) { delete static_cast<T>(p); }
+
+template <class T1, class T2>
+struct FirstUnlessVoidOrBool {
+ typedef T1 value;
+};
+
+template <class T2>
+struct FirstUnlessVoidOrBool<void, T2> {
+ typedef T2 value;
+};
+
+template <class T2>
+struct FirstUnlessVoidOrBool<bool, T2> {
+ typedef T2 value;
+};
+
+template<class T, class U>
+struct is_same {
+ static bool value;
+};
+
+template<class T>
+struct is_same<T, T> {
+ static bool value;
+};
+
+template<class T, class U>
+bool is_same<T, U>::value = false;
+
+template<class T>
+bool is_same<T, T>::value = true;
+
+/* FuncInfo *******************************************************************/
+
+/* Info about the user's original, pre-wrapped function. */
+template <class C, class R = void>
+struct FuncInfo {
+ /* The type of the closure that the function takes (its first param). */
+ typedef C Closure;
+
+ /* The return type. */
+ typedef R Return;
+};
+
+/* Func ***********************************************************************/
+
+/* Func1, Func2, Func3: Template classes representing a function and its
+ * signature.
+ *
+ * Since the function is a template parameter, calling the function can be
+ * inlined at compile-time and does not require a function pointer at runtime.
+ * These functions are not bound to a handler data so have no data or cleanup
+ * handler. */
+struct UnboundFunc {
+ CleanupFunc *GetCleanup() { return NULL; }
+ void *GetData() { return NULL; }
+};
+
+template <class R, class P1, R F(P1), class I>
+struct Func1 : public UnboundFunc {
+ typedef R Return;
+ typedef I FuncInfo;
+ static R Call(P1 p1) { return F(p1); }
+};
+
+template <class R, class P1, class P2, R F(P1, P2), class I>
+struct Func2 : public UnboundFunc {
+ typedef R Return;
+ typedef I FuncInfo;
+ static R Call(P1 p1, P2 p2) { return F(p1, p2); }
+};
+
+template <class R, class P1, class P2, class P3, R F(P1, P2, P3), class I>
+struct Func3 : public UnboundFunc {
+ typedef R Return;
+ typedef I FuncInfo;
+ static R Call(P1 p1, P2 p2, P3 p3) { return F(p1, p2, p3); }
+};
+
+template <class R, class P1, class P2, class P3, class P4, R F(P1, P2, P3, P4),
+ class I>
+struct Func4 : public UnboundFunc {
+ typedef R Return;
+ typedef I FuncInfo;
+ static R Call(P1 p1, P2 p2, P3 p3, P4 p4) { return F(p1, p2, p3, p4); }
+};
+
+template <class R, class P1, class P2, class P3, class P4, class P5,
+ R F(P1, P2, P3, P4, P5), class I>
+struct Func5 : public UnboundFunc {
+ typedef R Return;
+ typedef I FuncInfo;
+ static R Call(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {
+ return F(p1, p2, p3, p4, p5);
+ }
+};
+
+/* BoundFunc ******************************************************************/
+
+/* BoundFunc2, BoundFunc3: Like Func2/Func3 except also contains a value that
+ * shall be bound to the function's second parameter.
+ *
+ * Note that the second parameter is a const pointer, but our stored bound value
+ * is non-const so we can free it when the handlers are destroyed. */
+template <class T>
+struct BoundFunc {
+ typedef typename remove_constptr<T>::type MutableP2;
+ explicit BoundFunc(MutableP2 data_) : data(data_) {}
+ CleanupFunc *GetCleanup() { return &DeletePointer<MutableP2>; }
+ MutableP2 GetData() { return data; }
+ MutableP2 data;
+};
+
+template <class R, class P1, class P2, R F(P1, P2), class I>
+struct BoundFunc2 : public BoundFunc<P2> {
+ typedef BoundFunc<P2> Base;
+ typedef I FuncInfo;
+ explicit BoundFunc2(typename Base::MutableP2 arg) : Base(arg) {}
+};
+
+template <class R, class P1, class P2, class P3, R F(P1, P2, P3), class I>
+struct BoundFunc3 : public BoundFunc<P2> {
+ typedef BoundFunc<P2> Base;
+ typedef I FuncInfo;
+ explicit BoundFunc3(typename Base::MutableP2 arg) : Base(arg) {}
+};
+
+template <class R, class P1, class P2, class P3, class P4, R F(P1, P2, P3, P4),
+ class I>
+struct BoundFunc4 : public BoundFunc<P2> {
+ typedef BoundFunc<P2> Base;
+ typedef I FuncInfo;
+ explicit BoundFunc4(typename Base::MutableP2 arg) : Base(arg) {}
+};
+
+template <class R, class P1, class P2, class P3, class P4, class P5,
+ R F(P1, P2, P3, P4, P5), class I>
+struct BoundFunc5 : public BoundFunc<P2> {
+ typedef BoundFunc<P2> Base;
+ typedef I FuncInfo;
+ explicit BoundFunc5(typename Base::MutableP2 arg) : Base(arg) {}
+};
+
+/* FuncSig ********************************************************************/
+
+/* FuncSig1, FuncSig2, FuncSig3: template classes reflecting a function
+ * *signature*, but without a specific function attached.
+ *
+ * These classes contain member functions that can be invoked with a
+ * specific function to return a Func/BoundFunc class. */
+template <class R, class P1>
+struct FuncSig1 {
+ template <R F(P1)>
+ Func1<R, P1, F, FuncInfo<P1, R> > GetFunc() {
+ return Func1<R, P1, F, FuncInfo<P1, R> >();
+ }
+};
+
+template <class R, class P1, class P2>
+struct FuncSig2 {
+ template <R F(P1, P2)>
+ Func2<R, P1, P2, F, FuncInfo<P1, R> > GetFunc() {
+ return Func2<R, P1, P2, F, FuncInfo<P1, R> >();
+ }
+
+ template <R F(P1, P2)>
+ BoundFunc2<R, P1, P2, F, FuncInfo<P1, R> > GetFunc(
+ typename remove_constptr<P2>::type param2) {
+ return BoundFunc2<R, P1, P2, F, FuncInfo<P1, R> >(param2);
+ }
+};
+
+template <class R, class P1, class P2, class P3>
+struct FuncSig3 {
+ template <R F(P1, P2, P3)>
+ Func3<R, P1, P2, P3, F, FuncInfo<P1, R> > GetFunc() {
+ return Func3<R, P1, P2, P3, F, FuncInfo<P1, R> >();
+ }
+
+ template <R F(P1, P2, P3)>
+ BoundFunc3<R, P1, P2, P3, F, FuncInfo<P1, R> > GetFunc(
+ typename remove_constptr<P2>::type param2) {
+ return BoundFunc3<R, P1, P2, P3, F, FuncInfo<P1, R> >(param2);
+ }
+};
+
+template <class R, class P1, class P2, class P3, class P4>
+struct FuncSig4 {
+ template <R F(P1, P2, P3, P4)>
+ Func4<R, P1, P2, P3, P4, F, FuncInfo<P1, R> > GetFunc() {
+ return Func4<R, P1, P2, P3, P4, F, FuncInfo<P1, R> >();
+ }
+
+ template <R F(P1, P2, P3, P4)>
+ BoundFunc4<R, P1, P2, P3, P4, F, FuncInfo<P1, R> > GetFunc(
+ typename remove_constptr<P2>::type param2) {
+ return BoundFunc4<R, P1, P2, P3, P4, F, FuncInfo<P1, R> >(param2);
+ }
+};
+
+template <class R, class P1, class P2, class P3, class P4, class P5>
+struct FuncSig5 {
+ template <R F(P1, P2, P3, P4, P5)>
+ Func5<R, P1, P2, P3, P4, P5, F, FuncInfo<P1, R> > GetFunc() {
+ return Func5<R, P1, P2, P3, P4, P5, F, FuncInfo<P1, R> >();
+ }
+
+ template <R F(P1, P2, P3, P4, P5)>
+ BoundFunc5<R, P1, P2, P3, P4, P5, F, FuncInfo<P1, R> > GetFunc(
+ typename remove_constptr<P2>::type param2) {
+ return BoundFunc5<R, P1, P2, P3, P4, P5, F, FuncInfo<P1, R> >(param2);
+ }
+};
+
+/* Overloaded template function that can construct the appropriate FuncSig*
+ * class given a function pointer by deducing the template parameters. */
+template <class R, class P1>
+inline FuncSig1<R, P1> MatchFunc(R (*f)(P1)) {
+ UPB_UNUSED(f); /* Only used for template parameter deduction. */
+ return FuncSig1<R, P1>();
+}
+
+template <class R, class P1, class P2>
+inline FuncSig2<R, P1, P2> MatchFunc(R (*f)(P1, P2)) {
+ UPB_UNUSED(f); /* Only used for template parameter deduction. */
+ return FuncSig2<R, P1, P2>();
+}
+
+template <class R, class P1, class P2, class P3>
+inline FuncSig3<R, P1, P2, P3> MatchFunc(R (*f)(P1, P2, P3)) {
+ UPB_UNUSED(f); /* Only used for template parameter deduction. */
+ return FuncSig3<R, P1, P2, P3>();
+}
+
+template <class R, class P1, class P2, class P3, class P4>
+inline FuncSig4<R, P1, P2, P3, P4> MatchFunc(R (*f)(P1, P2, P3, P4)) {
+ UPB_UNUSED(f); /* Only used for template parameter deduction. */
+ return FuncSig4<R, P1, P2, P3, P4>();
+}
+
+template <class R, class P1, class P2, class P3, class P4, class P5>
+inline FuncSig5<R, P1, P2, P3, P4, P5> MatchFunc(R (*f)(P1, P2, P3, P4, P5)) {
+ UPB_UNUSED(f); /* Only used for template parameter deduction. */
+ return FuncSig5<R, P1, P2, P3, P4, P5>();
+}
+
+/* MethodSig ******************************************************************/
+
+/* CallMethod*: a function template that calls a given method. */
+template <class R, class C, R (C::*F)()>
+R CallMethod0(C *obj) {
+ return ((*obj).*F)();
+}
+
+template <class R, class C, class P1, R (C::*F)(P1)>
+R CallMethod1(C *obj, P1 arg1) {
+ return ((*obj).*F)(arg1);
+}
+
+template <class R, class C, class P1, class P2, R (C::*F)(P1, P2)>
+R CallMethod2(C *obj, P1 arg1, P2 arg2) {
+ return ((*obj).*F)(arg1, arg2);
+}
+
+template <class R, class C, class P1, class P2, class P3, R (C::*F)(P1, P2, P3)>
+R CallMethod3(C *obj, P1 arg1, P2 arg2, P3 arg3) {
+ return ((*obj).*F)(arg1, arg2, arg3);
+}
+
+template <class R, class C, class P1, class P2, class P3, class P4,
+ R (C::*F)(P1, P2, P3, P4)>
+R CallMethod4(C *obj, P1 arg1, P2 arg2, P3 arg3, P4 arg4) {
+ return ((*obj).*F)(arg1, arg2, arg3, arg4);
+}
+
+/* MethodSig: like FuncSig, but for member functions.
+ *
+ * GetFunc() returns a normal FuncN object, so after calling GetFunc() no
+ * more logic is required to special-case methods. */
+template <class R, class C>
+struct MethodSig0 {
+ template <R (C::*F)()>
+ Func1<R, C *, CallMethod0<R, C, F>, FuncInfo<C *, R> > GetFunc() {
+ return Func1<R, C *, CallMethod0<R, C, F>, FuncInfo<C *, R> >();
+ }
+};
+
+template <class R, class C, class P1>
+struct MethodSig1 {
+ template <R (C::*F)(P1)>
+ Func2<R, C *, P1, CallMethod1<R, C, P1, F>, FuncInfo<C *, R> > GetFunc() {
+ return Func2<R, C *, P1, CallMethod1<R, C, P1, F>, FuncInfo<C *, R> >();
+ }
+
+ template <R (C::*F)(P1)>
+ BoundFunc2<R, C *, P1, CallMethod1<R, C, P1, F>, FuncInfo<C *, R> > GetFunc(
+ typename remove_constptr<P1>::type param1) {
+ return BoundFunc2<R, C *, P1, CallMethod1<R, C, P1, F>, FuncInfo<C *, R> >(
+ param1);
+ }
+};
+
+template <class R, class C, class P1, class P2>
+struct MethodSig2 {
+ template <R (C::*F)(P1, P2)>
+ Func3<R, C *, P1, P2, CallMethod2<R, C, P1, P2, F>, FuncInfo<C *, R> >
+ GetFunc() {
+ return Func3<R, C *, P1, P2, CallMethod2<R, C, P1, P2, F>,
+ FuncInfo<C *, R> >();
+ }
+
+ template <R (C::*F)(P1, P2)>
+ BoundFunc3<R, C *, P1, P2, CallMethod2<R, C, P1, P2, F>, FuncInfo<C *, R> >
+ GetFunc(typename remove_constptr<P1>::type param1) {
+ return BoundFunc3<R, C *, P1, P2, CallMethod2<R, C, P1, P2, F>,
+ FuncInfo<C *, R> >(param1);
+ }
+};
+
+template <class R, class C, class P1, class P2, class P3>
+struct MethodSig3 {
+ template <R (C::*F)(P1, P2, P3)>
+ Func4<R, C *, P1, P2, P3, CallMethod3<R, C, P1, P2, P3, F>, FuncInfo<C *, R> >
+ GetFunc() {
+ return Func4<R, C *, P1, P2, P3, CallMethod3<R, C, P1, P2, P3, F>,
+ FuncInfo<C *, R> >();
+ }
+
+ template <R (C::*F)(P1, P2, P3)>
+ BoundFunc4<R, C *, P1, P2, P3, CallMethod3<R, C, P1, P2, P3, F>,
+ FuncInfo<C *, R> >
+ GetFunc(typename remove_constptr<P1>::type param1) {
+ return BoundFunc4<R, C *, P1, P2, P3, CallMethod3<R, C, P1, P2, P3, F>,
+ FuncInfo<C *, R> >(param1);
+ }
+};
+
+template <class R, class C, class P1, class P2, class P3, class P4>
+struct MethodSig4 {
+ template <R (C::*F)(P1, P2, P3, P4)>
+ Func5<R, C *, P1, P2, P3, P4, CallMethod4<R, C, P1, P2, P3, P4, F>,
+ FuncInfo<C *, R> >
+ GetFunc() {
+ return Func5<R, C *, P1, P2, P3, P4, CallMethod4<R, C, P1, P2, P3, P4, F>,
+ FuncInfo<C *, R> >();
+ }
+
+ template <R (C::*F)(P1, P2, P3, P4)>
+ BoundFunc5<R, C *, P1, P2, P3, P4, CallMethod4<R, C, P1, P2, P3, P4, F>,
+ FuncInfo<C *, R> >
+ GetFunc(typename remove_constptr<P1>::type param1) {
+ return BoundFunc5<R, C *, P1, P2, P3, P4,
+ CallMethod4<R, C, P1, P2, P3, P4, F>, FuncInfo<C *, R> >(
+ param1);
+ }
+};
+
+template <class R, class C>
+inline MethodSig0<R, C> MatchFunc(R (C::*f)()) {
+ UPB_UNUSED(f); /* Only used for template parameter deduction. */
+ return MethodSig0<R, C>();
+}
+
+template <class R, class C, class P1>
+inline MethodSig1<R, C, P1> MatchFunc(R (C::*f)(P1)) {
+ UPB_UNUSED(f); /* Only used for template parameter deduction. */
+ return MethodSig1<R, C, P1>();
+}
+
+template <class R, class C, class P1, class P2>
+inline MethodSig2<R, C, P1, P2> MatchFunc(R (C::*f)(P1, P2)) {
+ UPB_UNUSED(f); /* Only used for template parameter deduction. */
+ return MethodSig2<R, C, P1, P2>();
+}
+
+template <class R, class C, class P1, class P2, class P3>
+inline MethodSig3<R, C, P1, P2, P3> MatchFunc(R (C::*f)(P1, P2, P3)) {
+ UPB_UNUSED(f); /* Only used for template parameter deduction. */
+ return MethodSig3<R, C, P1, P2, P3>();
+}
+
+template <class R, class C, class P1, class P2, class P3, class P4>
+inline MethodSig4<R, C, P1, P2, P3, P4> MatchFunc(R (C::*f)(P1, P2, P3, P4)) {
+ UPB_UNUSED(f); /* Only used for template parameter deduction. */
+ return MethodSig4<R, C, P1, P2, P3, P4>();
+}
+
+/* MaybeWrapReturn ************************************************************/
+
+/* Template class that attempts to wrap the return value of the function so it
+ * matches the expected type. There are two main adjustments it may make:
+ *
+ * 1. If the function returns void, make it return the expected type and with
+ * a value that always indicates success.
+ * 2. If the function returns bool, make it return the expected type with a
+ * value that indicates success or failure.
+ *
+ * The "expected type" for return is:
+ * 1. void* for start handlers. If the closure parameter has a different type
+ * we will cast it to void* for the return in the success case.
+ * 2. size_t for string buffer handlers.
+ * 3. bool for everything else. */
+
+/* Template parameters are FuncN type and desired return type. */
+template <class F, class R, class Enable = void>
+struct MaybeWrapReturn;
+
+/* If the return type matches, return the given function unwrapped. */
+template <class F>
+struct MaybeWrapReturn<F, typename F::Return> {
+ typedef F Func;
+};
+
+/* Function wrapper that munges the return value from void to (bool)true. */
+template <class P1, class P2, void F(P1, P2)>
+bool ReturnTrue2(P1 p1, P2 p2) {
+ F(p1, p2);
+ return true;
+}
+
+template <class P1, class P2, class P3, void F(P1, P2, P3)>
+bool ReturnTrue3(P1 p1, P2 p2, P3 p3) {
+ F(p1, p2, p3);
+ return true;
+}
+
+/* Function wrapper that munges the return value from void to (void*)arg1 */
+template <class P1, class P2, void F(P1, P2)>
+void *ReturnClosure2(P1 p1, P2 p2) {
+ F(p1, p2);
+ return p1;
+}
+
+template <class P1, class P2, class P3, void F(P1, P2, P3)>
+void *ReturnClosure3(P1 p1, P2 p2, P3 p3) {
+ F(p1, p2, p3);
+ return p1;
+}
+
+/* Function wrapper that munges the return value from R to void*. */
+template <class R, class P1, class P2, R F(P1, P2)>
+void *CastReturnToVoidPtr2(P1 p1, P2 p2) {
+ return F(p1, p2);
+}
+
+template <class R, class P1, class P2, class P3, R F(P1, P2, P3)>
+void *CastReturnToVoidPtr3(P1 p1, P2 p2, P3 p3) {
+ return F(p1, p2, p3);
+}
+
+/* Function wrapper that munges the return value from bool to void*. */
+template <class P1, class P2, bool F(P1, P2)>
+void *ReturnClosureOrBreak2(P1 p1, P2 p2) {
+ return F(p1, p2) ? p1 : UPB_BREAK;
+}
+
+template <class P1, class P2, class P3, bool F(P1, P2, P3)>
+void *ReturnClosureOrBreak3(P1 p1, P2 p2, P3 p3) {
+ return F(p1, p2, p3) ? p1 : UPB_BREAK;
+}
+
+/* For the string callback, which takes five params, returns the size param. */
+template <class P1, class P2,
+ void F(P1, P2, const char *, size_t, const BufferHandle *)>
+size_t ReturnStringLen(P1 p1, P2 p2, const char *p3, size_t p4,
+ const BufferHandle *p5) {
+ F(p1, p2, p3, p4, p5);
+ return p4;
+}
+
+/* For the string callback, which takes five params, returns the size param or
+ * zero. */
+template <class P1, class P2,
+ bool F(P1, P2, const char *, size_t, const BufferHandle *)>
+size_t ReturnNOr0(P1 p1, P2 p2, const char *p3, size_t p4,
+ const BufferHandle *p5) {
+ return F(p1, p2, p3, p4, p5) ? p4 : 0;
+}
+
+/* If we have a function returning void but want a function returning bool, wrap
+ * it in a function that returns true. */
+template <class P1, class P2, void F(P1, P2), class I>
+struct MaybeWrapReturn<Func2<void, P1, P2, F, I>, bool> {
+ typedef Func2<bool, P1, P2, ReturnTrue2<P1, P2, F>, I> Func;
+};
+
+template <class P1, class P2, class P3, void F(P1, P2, P3), class I>
+struct MaybeWrapReturn<Func3<void, P1, P2, P3, F, I>, bool> {
+ typedef Func3<bool, P1, P2, P3, ReturnTrue3<P1, P2, P3, F>, I> Func;
+};
+
+/* If our function returns void but we want one returning void*, wrap it in a
+ * function that returns the first argument. */
+template <class P1, class P2, void F(P1, P2), class I>
+struct MaybeWrapReturn<Func2<void, P1, P2, F, I>, void *> {
+ typedef Func2<void *, P1, P2, ReturnClosure2<P1, P2, F>, I> Func;
+};
+
+template <class P1, class P2, class P3, void F(P1, P2, P3), class I>
+struct MaybeWrapReturn<Func3<void, P1, P2, P3, F, I>, void *> {
+ typedef Func3<void *, P1, P2, P3, ReturnClosure3<P1, P2, P3, F>, I> Func;
+};
+
+/* If our function returns R* but we want one returning void*, wrap it in a
+ * function that casts to void*. */
+template <class R, class P1, class P2, R *F(P1, P2), class I>
+struct MaybeWrapReturn<Func2<R *, P1, P2, F, I>, void *,
+ typename disable_if_same<R *, void *>::Type> {
+ typedef Func2<void *, P1, P2, CastReturnToVoidPtr2<R *, P1, P2, F>, I> Func;
+};
+
+template <class R, class P1, class P2, class P3, R *F(P1, P2, P3), class I>
+struct MaybeWrapReturn<Func3<R *, P1, P2, P3, F, I>, void *,
+ typename disable_if_same<R *, void *>::Type> {
+ typedef Func3<void *, P1, P2, P3, CastReturnToVoidPtr3<R *, P1, P2, P3, F>, I>
+ Func;
+};
+
+/* If our function returns bool but we want one returning void*, wrap it in a
+ * function that returns either the first param or UPB_BREAK. */
+template <class P1, class P2, bool F(P1, P2), class I>
+struct MaybeWrapReturn<Func2<bool, P1, P2, F, I>, void *> {
+ typedef Func2<void *, P1, P2, ReturnClosureOrBreak2<P1, P2, F>, I> Func;
+};
+
+template <class P1, class P2, class P3, bool F(P1, P2, P3), class I>
+struct MaybeWrapReturn<Func3<bool, P1, P2, P3, F, I>, void *> {
+ typedef Func3<void *, P1, P2, P3, ReturnClosureOrBreak3<P1, P2, P3, F>, I>
+ Func;
+};
+
+/* If our function returns void but we want one returning size_t, wrap it in a
+ * function that returns the size argument. */
+template <class P1, class P2,
+ void F(P1, P2, const char *, size_t, const BufferHandle *), class I>
+struct MaybeWrapReturn<
+ Func5<void, P1, P2, const char *, size_t, const BufferHandle *, F, I>,
+ size_t> {
+ typedef Func5<size_t, P1, P2, const char *, size_t, const BufferHandle *,
+ ReturnStringLen<P1, P2, F>, I> Func;
+};
+
+/* If our function returns bool but we want one returning size_t, wrap it in a
+ * function that returns either 0 or the buf size. */
+template <class P1, class P2,
+ bool F(P1, P2, const char *, size_t, const BufferHandle *), class I>
+struct MaybeWrapReturn<
+ Func5<bool, P1, P2, const char *, size_t, const BufferHandle *, F, I>,
+ size_t> {
+ typedef Func5<size_t, P1, P2, const char *, size_t, const BufferHandle *,
+ ReturnNOr0<P1, P2, F>, I> Func;
+};
+
+/* ConvertParams **************************************************************/
+
+/* Template class that converts the function parameters if necessary, and
+ * ignores the HandlerData parameter if appropriate.
+ *
+ * Template parameter is the are FuncN function type. */
+template <class F, class T>
+struct ConvertParams;
+
+/* Function that discards the handler data parameter. */
+template <class R, class P1, R F(P1)>
+R IgnoreHandlerData2(void *p1, const void *hd) {
+ UPB_UNUSED(hd);
+ return F(static_cast<P1>(p1));
+}
+
+template <class R, class P1, class P2Wrapper, class P2Wrapped,
+ R F(P1, P2Wrapped)>
+R IgnoreHandlerData3(void *p1, const void *hd, P2Wrapper p2) {
+ UPB_UNUSED(hd);
+ return F(static_cast<P1>(p1), p2);
+}
+
+template <class R, class P1, class P2, class P3, R F(P1, P2, P3)>
+R IgnoreHandlerData4(void *p1, const void *hd, P2 p2, P3 p3) {
+ UPB_UNUSED(hd);
+ return F(static_cast<P1>(p1), p2, p3);
+}
+
+template <class R, class P1, class P2, class P3, class P4, R F(P1, P2, P3, P4)>
+R IgnoreHandlerData5(void *p1, const void *hd, P2 p2, P3 p3, P4 p4) {
+ UPB_UNUSED(hd);
+ return F(static_cast<P1>(p1), p2, p3, p4);
+}
+
+template <class R, class P1, R F(P1, const char*, size_t)>
+R IgnoreHandlerDataIgnoreHandle(void *p1, const void *hd, const char *p2,
+ size_t p3, const BufferHandle *handle) {
+ UPB_UNUSED(hd);
+ UPB_UNUSED(handle);
+ return F(static_cast<P1>(p1), p2, p3);
+}
+
+/* Function that casts the handler data parameter. */
+template <class R, class P1, class P2, R F(P1, P2)>
+R CastHandlerData2(void *c, const void *hd) {
+ return F(static_cast<P1>(c), static_cast<P2>(hd));
+}
+
+template <class R, class P1, class P2, class P3Wrapper, class P3Wrapped,
+ R F(P1, P2, P3Wrapped)>
+R CastHandlerData3(void *c, const void *hd, P3Wrapper p3) {
+ return F(static_cast<P1>(c), static_cast<P2>(hd), p3);
+}
+
+template <class R, class P1, class P2, class P3, class P4, class P5,
+ R F(P1, P2, P3, P4, P5)>
+R CastHandlerData5(void *c, const void *hd, P3 p3, P4 p4, P5 p5) {
+ return F(static_cast<P1>(c), static_cast<P2>(hd), p3, p4, p5);
+}
+
+template <class R, class P1, class P2, R F(P1, P2, const char *, size_t)>
+R CastHandlerDataIgnoreHandle(void *c, const void *hd, const char *p3,
+ size_t p4, const BufferHandle *handle) {
+ UPB_UNUSED(handle);
+ return F(static_cast<P1>(c), static_cast<P2>(hd), p3, p4);
+}
+
+/* For unbound functions, ignore the handler data. */
+template <class R, class P1, R F(P1), class I, class T>
+struct ConvertParams<Func1<R, P1, F, I>, T> {
+ typedef Func2<R, void *, const void *, IgnoreHandlerData2<R, P1, F>, I> Func;
+};
+
+template <class R, class P1, class P2, R F(P1, P2), class I,
+ class R2, class P1_2, class P2_2, class P3_2>
+struct ConvertParams<Func2<R, P1, P2, F, I>,
+ R2 (*)(P1_2, P2_2, P3_2)> {
+ typedef Func3<R, void *, const void *, P3_2,
+ IgnoreHandlerData3<R, P1, P3_2, P2, F>, I> Func;
+};
+
+/* For StringBuffer only; this ignores both the handler data and the
+ * BufferHandle. */
+template <class R, class P1, R F(P1, const char *, size_t), class I, class T>
+struct ConvertParams<Func3<R, P1, const char *, size_t, F, I>, T> {
+ typedef Func5<R, void *, const void *, const char *, size_t,
+ const BufferHandle *, IgnoreHandlerDataIgnoreHandle<R, P1, F>,
+ I> Func;
+};
+
+template <class R, class P1, class P2, class P3, class P4, R F(P1, P2, P3, P4),
+ class I, class T>
+struct ConvertParams<Func4<R, P1, P2, P3, P4, F, I>, T> {
+ typedef Func5<R, void *, const void *, P2, P3, P4,
+ IgnoreHandlerData5<R, P1, P2, P3, P4, F>, I> Func;
+};
+
+/* For bound functions, cast the handler data. */
+template <class R, class P1, class P2, R F(P1, P2), class I, class T>
+struct ConvertParams<BoundFunc2<R, P1, P2, F, I>, T> {
+ typedef Func2<R, void *, const void *, CastHandlerData2<R, P1, P2, F>, I>
+ Func;
+};
+
+template <class R, class P1, class P2, class P3, R F(P1, P2, P3), class I,
+ class R2, class P1_2, class P2_2, class P3_2>
+struct ConvertParams<BoundFunc3<R, P1, P2, P3, F, I>,
+ R2 (*)(P1_2, P2_2, P3_2)> {
+ typedef Func3<R, void *, const void *, P3_2,
+ CastHandlerData3<R, P1, P2, P3_2, P3, F>, I> Func;
+};
+
+/* For StringBuffer only; this ignores the BufferHandle. */
+template <class R, class P1, class P2, R F(P1, P2, const char *, size_t),
+ class I, class T>
+struct ConvertParams<BoundFunc4<R, P1, P2, const char *, size_t, F, I>, T> {
+ typedef Func5<R, void *, const void *, const char *, size_t,
+ const BufferHandle *, CastHandlerDataIgnoreHandle<R, P1, P2, F>,
+ I> Func;
+};
+
+template <class R, class P1, class P2, class P3, class P4, class P5,
+ R F(P1, P2, P3, P4, P5), class I, class T>
+struct ConvertParams<BoundFunc5<R, P1, P2, P3, P4, P5, F, I>, T> {
+ typedef Func5<R, void *, const void *, P3, P4, P5,
+ CastHandlerData5<R, P1, P2, P3, P4, P5, F>, I> Func;
+};
+
+/* utype/ltype are upper/lower-case, ctype is canonical C type, vtype is
+ * variant C type. */
+#define TYPE_METHODS(utype, ltype, ctype, vtype) \
+ template <> struct CanonicalType<vtype> { \
+ typedef ctype Type; \
+ }; \
+ template <> \
+ inline bool Handlers::SetValueHandler<vtype>( \
+ const FieldDef *f, \
+ const Handlers::utype ## Handler& handler) { \
+ assert(!handler.registered_); \
+ handler.AddCleanup(this); \
+ handler.registered_ = true; \
+ return upb_handlers_set##ltype(this, f, handler.handler_, &handler.attr_); \
+ } \
+
+TYPE_METHODS(Double, double, double, double)
+TYPE_METHODS(Float, float, float, float)
+TYPE_METHODS(UInt64, uint64, uint64_t, UPB_UINT64_T)
+TYPE_METHODS(UInt32, uint32, uint32_t, UPB_UINT32_T)
+TYPE_METHODS(Int64, int64, int64_t, UPB_INT64_T)
+TYPE_METHODS(Int32, int32, int32_t, UPB_INT32_T)
+TYPE_METHODS(Bool, bool, bool, bool)
+
+#ifdef UPB_TWO_32BIT_TYPES
+TYPE_METHODS(Int32, int32, int32_t, UPB_INT32ALT_T)
+TYPE_METHODS(UInt32, uint32, uint32_t, UPB_UINT32ALT_T)
+#endif
+
+#ifdef UPB_TWO_64BIT_TYPES
+TYPE_METHODS(Int64, int64, int64_t, UPB_INT64ALT_T)
+TYPE_METHODS(UInt64, uint64, uint64_t, UPB_UINT64ALT_T)
+#endif
+#undef TYPE_METHODS
+
+template <> struct CanonicalType<Status*> {
+ typedef Status* Type;
+};
+
+/* Type methods that are only one-per-canonical-type and not
+ * one-per-cvariant. */
+
+#define TYPE_METHODS(utype, ctype) \
+ inline bool Handlers::Set##utype##Handler(const FieldDef *f, \
+ const utype##Handler &h) { \
+ return SetValueHandler<ctype>(f, h); \
+ } \
+
+TYPE_METHODS(Double, double)
+TYPE_METHODS(Float, float)
+TYPE_METHODS(UInt64, uint64_t)
+TYPE_METHODS(UInt32, uint32_t)
+TYPE_METHODS(Int64, int64_t)
+TYPE_METHODS(Int32, int32_t)
+TYPE_METHODS(Bool, bool)
+#undef TYPE_METHODS
+
+template <class F> struct ReturnOf;
+
+template <class R, class P1, class P2>
+struct ReturnOf<R (*)(P1, P2)> {
+ typedef R Return;
+};
+
+template <class R, class P1, class P2, class P3>
+struct ReturnOf<R (*)(P1, P2, P3)> {
+ typedef R Return;
+};
+
+template <class R, class P1, class P2, class P3, class P4>
+struct ReturnOf<R (*)(P1, P2, P3, P4)> {
+ typedef R Return;
+};
+
+template <class R, class P1, class P2, class P3, class P4, class P5>
+struct ReturnOf<R (*)(P1, P2, P3, P4, P5)> {
+ typedef R Return;
+};
+
+template<class T> const void *UniquePtrForType() {
+ static const char ch = 0;
+ return &ch;
+}
+
+template <class T>
+template <class F>
+inline Handler<T>::Handler(F func)
+ : registered_(false),
+ cleanup_data_(func.GetData()),
+ cleanup_func_(func.GetCleanup()) {
+ upb_handlerattr_sethandlerdata(&attr_, func.GetData());
+ typedef typename ReturnOf<T>::Return Return;
+ typedef typename ConvertParams<F, T>::Func ConvertedParamsFunc;
+ typedef typename MaybeWrapReturn<ConvertedParamsFunc, Return>::Func
+ ReturnWrappedFunc;
+ handler_ = ReturnWrappedFunc().Call;
+
+ /* Set attributes based on what templates can statically tell us about the
+ * user's function. */
+
+ /* If the original function returns void, then we know that we wrapped it to
+ * always return ok. */
+ bool always_ok = is_same<typename F::FuncInfo::Return, void>::value;
+ attr_.SetAlwaysOk(always_ok);
+
+ /* Closure parameter and return type. */
+ attr_.SetClosureType(UniquePtrForType<typename F::FuncInfo::Closure>());
+
+ /* We use the closure type (from the first parameter) if the return type is
+ * void or bool, since these are the two cases we wrap to return the closure's
+ * type anyway.
+ *
+ * This is all nonsense for non START* handlers, but it doesn't matter because
+ * in that case the value will be ignored. */
+ typedef typename FirstUnlessVoidOrBool<typename F::FuncInfo::Return,
+ typename F::FuncInfo::Closure>::value
+ EffectiveReturn;
+ attr_.SetReturnClosureType(UniquePtrForType<EffectiveReturn>());
+}
+
+template <class T>
+inline Handler<T>::~Handler() {
+ assert(registered_);
+}
+
+inline HandlerAttributes::HandlerAttributes() { upb_handlerattr_init(this); }
+inline HandlerAttributes::~HandlerAttributes() { upb_handlerattr_uninit(this); }
+inline bool HandlerAttributes::SetHandlerData(const void *hd) {
+ return upb_handlerattr_sethandlerdata(this, hd);
+}
+inline const void* HandlerAttributes::handler_data() const {
+ return upb_handlerattr_handlerdata(this);
+}
+inline bool HandlerAttributes::SetClosureType(const void *type) {
+ return upb_handlerattr_setclosuretype(this, type);
+}
+inline const void* HandlerAttributes::closure_type() const {
+ return upb_handlerattr_closuretype(this);
+}
+inline bool HandlerAttributes::SetReturnClosureType(const void *type) {
+ return upb_handlerattr_setreturnclosuretype(this, type);
+}
+inline const void* HandlerAttributes::return_closure_type() const {
+ return upb_handlerattr_returnclosuretype(this);
+}
+inline bool HandlerAttributes::SetAlwaysOk(bool always_ok) {
+ return upb_handlerattr_setalwaysok(this, always_ok);
+}
+inline bool HandlerAttributes::always_ok() const {
+ return upb_handlerattr_alwaysok(this);
+}
+
+inline BufferHandle::BufferHandle() { upb_bufhandle_init(this); }
+inline BufferHandle::~BufferHandle() { upb_bufhandle_uninit(this); }
+inline const char* BufferHandle::buffer() const {
+ return upb_bufhandle_buf(this);
+}
+inline size_t BufferHandle::object_offset() const {
+ return upb_bufhandle_objofs(this);
+}
+inline void BufferHandle::SetBuffer(const char* buf, size_t ofs) {
+ upb_bufhandle_setbuf(this, buf, ofs);
+}
+template <class T>
+void BufferHandle::SetAttachedObject(const T* obj) {
+ upb_bufhandle_setobj(this, obj, UniquePtrForType<T>());
+}
+template <class T>
+const T* BufferHandle::GetAttachedObject() const {
+ return upb_bufhandle_objtype(this) == UniquePtrForType<T>()
+ ? static_cast<const T *>(upb_bufhandle_obj(this))
+ : NULL;
+}
+
+inline reffed_ptr<Handlers> Handlers::New(const MessageDef *m) {
+ upb_handlers *h = upb_handlers_new(m, &h);
+ return reffed_ptr<Handlers>(h, &h);
+}
+inline reffed_ptr<const Handlers> Handlers::NewFrozen(
+ const MessageDef *m, upb_handlers_callback *callback,
+ const void *closure) {
+ const upb_handlers *h = upb_handlers_newfrozen(m, &h, callback, closure);
+ return reffed_ptr<const Handlers>(h, &h);
+}
+inline const Status* Handlers::status() {
+ return upb_handlers_status(this);
+}
+inline void Handlers::ClearError() {
+ return upb_handlers_clearerr(this);
+}
+inline bool Handlers::Freeze(Status *s) {
+ upb::Handlers* h = this;
+ return upb_handlers_freeze(&h, 1, s);
+}
+inline bool Handlers::Freeze(Handlers *const *handlers, int n, Status *s) {
+ return upb_handlers_freeze(handlers, n, s);
+}
+inline bool Handlers::Freeze(const std::vector<Handlers*>& h, Status* status) {
+ return upb_handlers_freeze((Handlers* const*)&h[0], h.size(), status);
+}
+inline const MessageDef *Handlers::message_def() const {
+ return upb_handlers_msgdef(this);
+}
+inline bool Handlers::AddCleanup(void *p, upb_handlerfree *func) {
+ return upb_handlers_addcleanup(this, p, func);
+}
+inline bool Handlers::SetStartMessageHandler(
+ const Handlers::StartMessageHandler &handler) {
+ assert(!handler.registered_);
+ handler.registered_ = true;
+ handler.AddCleanup(this);
+ return upb_handlers_setstartmsg(this, handler.handler_, &handler.attr_);
+}
+inline bool Handlers::SetEndMessageHandler(
+ const Handlers::EndMessageHandler &handler) {
+ assert(!handler.registered_);
+ handler.registered_ = true;
+ handler.AddCleanup(this);
+ return upb_handlers_setendmsg(this, handler.handler_, &handler.attr_);
+}
+inline bool Handlers::SetStartStringHandler(const FieldDef *f,
+ const StartStringHandler &handler) {
+ assert(!handler.registered_);
+ handler.registered_ = true;
+ handler.AddCleanup(this);
+ return upb_handlers_setstartstr(this, f, handler.handler_, &handler.attr_);
+}
+inline bool Handlers::SetEndStringHandler(const FieldDef *f,
+ const EndFieldHandler &handler) {
+ assert(!handler.registered_);
+ handler.registered_ = true;
+ handler.AddCleanup(this);
+ return upb_handlers_setendstr(this, f, handler.handler_, &handler.attr_);
+}
+inline bool Handlers::SetStringHandler(const FieldDef *f,
+ const StringHandler& handler) {
+ assert(!handler.registered_);
+ handler.registered_ = true;
+ handler.AddCleanup(this);
+ return upb_handlers_setstring(this, f, handler.handler_, &handler.attr_);
+}
+inline bool Handlers::SetStartSequenceHandler(
+ const FieldDef *f, const StartFieldHandler &handler) {
+ assert(!handler.registered_);
+ handler.registered_ = true;
+ handler.AddCleanup(this);
+ return upb_handlers_setstartseq(this, f, handler.handler_, &handler.attr_);
+}
+inline bool Handlers::SetStartSubMessageHandler(
+ const FieldDef *f, const StartFieldHandler &handler) {
+ assert(!handler.registered_);
+ handler.registered_ = true;
+ handler.AddCleanup(this);
+ return upb_handlers_setstartsubmsg(this, f, handler.handler_, &handler.attr_);
+}
+inline bool Handlers::SetEndSubMessageHandler(const FieldDef *f,
+ const EndFieldHandler &handler) {
+ assert(!handler.registered_);
+ handler.registered_ = true;
+ handler.AddCleanup(this);
+ return upb_handlers_setendsubmsg(this, f, handler.handler_, &handler.attr_);
+}
+inline bool Handlers::SetEndSequenceHandler(const FieldDef *f,
+ const EndFieldHandler &handler) {
+ assert(!handler.registered_);
+ handler.registered_ = true;
+ handler.AddCleanup(this);
+ return upb_handlers_setendseq(this, f, handler.handler_, &handler.attr_);
+}
+inline bool Handlers::SetSubHandlers(const FieldDef *f, const Handlers *sub) {
+ return upb_handlers_setsubhandlers(this, f, sub);
+}
+inline const Handlers *Handlers::GetSubHandlers(const FieldDef *f) const {
+ return upb_handlers_getsubhandlers(this, f);
+}
+inline const Handlers *Handlers::GetSubHandlers(Handlers::Selector sel) const {
+ return upb_handlers_getsubhandlers_sel(this, sel);
+}
+inline bool Handlers::GetSelector(const FieldDef *f, Handlers::Type type,
+ Handlers::Selector *s) {
+ return upb_handlers_getselector(f, type, s);
+}
+inline Handlers::Selector Handlers::GetEndSelector(Handlers::Selector start) {
+ return upb_handlers_getendselector(start);
+}
+inline Handlers::GenericFunction *Handlers::GetHandler(
+ Handlers::Selector selector) {
+ return upb_handlers_gethandler(this, selector);
+}
+inline const void *Handlers::GetHandlerData(Handlers::Selector selector) {
+ return upb_handlers_gethandlerdata(this, selector);
+}
+
+inline BytesHandler::BytesHandler() {
+ upb_byteshandler_init(this);
+}
+
+inline BytesHandler::~BytesHandler() {}
+
+} /* namespace upb */
+
+#endif /* __cplusplus */
+
+
+#undef UPB_TWO_32BIT_TYPES
+#undef UPB_TWO_64BIT_TYPES
+#undef UPB_INT32_T
+#undef UPB_UINT32_T
+#undef UPB_INT32ALT_T
+#undef UPB_UINT32ALT_T
+#undef UPB_INT64_T
+#undef UPB_UINT64_T
+#undef UPB_INT64ALT_T
+#undef UPB_UINT64ALT_T
+
+#endif /* UPB_HANDLERS_INL_H_ */
+
+#endif /* UPB_HANDLERS_H */
+/*
+** upb::Environment (upb_env)
+**
+** A upb::Environment provides a means for injecting malloc and an
+** error-reporting callback into encoders/decoders. This allows them to be
+** independent of nearly all assumptions about their actual environment.
+**
+** It is also a container for allocating the encoders/decoders themselves that
+** insulates clients from knowing their actual size. This provides ABI
+** compatibility even if the size of the objects change. And this allows the
+** structure definitions to be in the .c files instead of the .h files, making
+** the .h files smaller and more readable.
+*/
+
+
+#ifndef UPB_ENV_H_
+#define UPB_ENV_H_
+
+#ifdef __cplusplus
+namespace upb {
+class Environment;
+class SeededAllocator;
+}
+#endif
+
+UPB_DECLARE_TYPE(upb::Environment, upb_env)
+UPB_DECLARE_TYPE(upb::SeededAllocator, upb_seededalloc)
+
+typedef void *upb_alloc_func(void *ud, void *ptr, size_t oldsize, size_t size);
+typedef void upb_cleanup_func(void *ud);
+typedef bool upb_error_func(void *ud, const upb_status *status);
+
+#ifdef __cplusplus
+
+/* An environment is *not* thread-safe. */
+class upb::Environment {
+ public:
+ Environment();
+ ~Environment();
+
+ /* Set a custom memory allocation function for the environment. May ONLY
+ * be called before any calls to Malloc()/Realloc()/AddCleanup() below.
+ * If this is not called, the system realloc() function will be used.
+ * The given user pointer "ud" will be passed to the allocation function.
+ *
+ * The allocation function will not receive corresponding "free" calls. it
+ * must ensure that the memory is valid for the lifetime of the Environment,
+ * but it may be reclaimed any time thereafter. The likely usage is that
+ * "ud" points to a stateful allocator, and that the allocator frees all
+ * memory, arena-style, when it is destroyed. In this case the allocator must
+ * outlive the Environment. Another possibility is that the allocation
+ * function returns GC-able memory that is guaranteed to be GC-rooted for the
+ * life of the Environment. */
+ void SetAllocationFunction(upb_alloc_func* alloc, void* ud);
+
+ template<class T>
+ void SetAllocator(T* allocator) {
+ SetAllocationFunction(allocator->GetAllocationFunction(), allocator);
+ }
+
+ /* Set a custom error reporting function. */
+ void SetErrorFunction(upb_error_func* func, void* ud);
+
+ /* Set the error reporting function to simply copy the status to the given
+ * status and abort. */
+ void ReportErrorsTo(Status* status);
+
+ /* Returns true if all allocations and AddCleanup() calls have succeeded,
+ * and no errors were reported with ReportError() (except ones that recovered
+ * successfully). */
+ bool ok() const;
+
+ /* Functions for use by encoders/decoders. **********************************/
+
+ /* Reports an error to this environment's callback, returning true if
+ * the caller should try to recover. */
+ bool ReportError(const Status* status);
+
+ /* Allocate memory. Uses the environment's allocation function.
+ *
+ * There is no need to free(). All memory will be freed automatically, but is
+ * guaranteed to outlive the Environment. */
+ void* Malloc(size_t size);
+
+ /* Reallocate memory. Preserves "oldsize" bytes from the existing buffer
+ * Requires: oldsize <= existing_size.
+ *
+ * TODO(haberman): should we also enforce that oldsize <= size? */
+ void* Realloc(void* ptr, size_t oldsize, size_t size);
+
+ /* Add a cleanup function to run when the environment is destroyed.
+ * Returns false on out-of-memory.
+ *
+ * The first call to AddCleanup() after SetAllocationFunction() is guaranteed
+ * to return true -- this makes it possible to robustly set a cleanup handler
+ * for a custom allocation function. */
+ bool AddCleanup(upb_cleanup_func* func, void* ud);
+
+ /* Total number of bytes that have been allocated. It is undefined what
+ * Realloc() does to this counter. */
+ size_t BytesAllocated() const;
+
+ private:
+ UPB_DISALLOW_COPY_AND_ASSIGN(Environment)
+
+#else
+struct upb_env {
+#endif /* __cplusplus */
+
+ bool ok_;
+ size_t bytes_allocated;
+
+ /* Alloc function. */
+ upb_alloc_func *alloc;
+ void *alloc_ud;
+
+ /* Error-reporting function. */
+ upb_error_func *err;
+ void *err_ud;
+
+ /* Userdata for default alloc func. */
+ void *default_alloc_ud;
+
+ /* Cleanup entries. Pointer to a cleanup_ent, defined in env.c */
+ void *cleanup_head;
+
+ /* For future expansion, since the size of this struct is exposed to users. */
+ void *future1;
+ void *future2;
+};
+
+UPB_BEGIN_EXTERN_C
+
+void upb_env_init(upb_env *e);
+void upb_env_uninit(upb_env *e);
+void upb_env_setallocfunc(upb_env *e, upb_alloc_func *func, void *ud);
+void upb_env_seterrorfunc(upb_env *e, upb_error_func *func, void *ud);
+void upb_env_reporterrorsto(upb_env *e, upb_status *status);
+bool upb_env_ok(const upb_env *e);
+bool upb_env_reporterror(upb_env *e, const upb_status *status);
+void *upb_env_malloc(upb_env *e, size_t size);
+void *upb_env_realloc(upb_env *e, void *ptr, size_t oldsize, size_t size);
+bool upb_env_addcleanup(upb_env *e, upb_cleanup_func *func, void *ud);
+size_t upb_env_bytesallocated(const upb_env *e);
+
+UPB_END_EXTERN_C
+
+#ifdef __cplusplus
+
+/* An allocator that allocates from an initial memory region (likely the stack)
+ * before falling back to another allocator. */
+class upb::SeededAllocator {
+ public:
+ SeededAllocator(void *mem, size_t len);
+ ~SeededAllocator();
+
+ /* Set a custom fallback memory allocation function for the allocator, to use
+ * once the initial region runs out.
+ *
+ * May ONLY be called before GetAllocationFunction(). If this is not
+ * called, the system realloc() will be the fallback allocator. */
+ void SetFallbackAllocator(upb_alloc_func *alloc, void *ud);
+
+ /* Gets the allocation function for this allocator. */
+ upb_alloc_func* GetAllocationFunction();
+
+ private:
+ UPB_DISALLOW_COPY_AND_ASSIGN(SeededAllocator)
+
+#else
+struct upb_seededalloc {
+#endif /* __cplusplus */
+
+ /* Fallback alloc function. */
+ upb_alloc_func *alloc;
+ upb_cleanup_func *alloc_cleanup;
+ void *alloc_ud;
+ bool need_cleanup;
+ bool returned_allocfunc;
+
+ /* Userdata for default alloc func. */
+ void *default_alloc_ud;
+
+ /* Pointers for the initial memory region. */
+ char *mem_base;
+ char *mem_ptr;
+ char *mem_limit;
+
+ /* For future expansion, since the size of this struct is exposed to users. */
+ void *future1;
+ void *future2;
+};
+
+UPB_BEGIN_EXTERN_C
+
+void upb_seededalloc_init(upb_seededalloc *a, void *mem, size_t len);
+void upb_seededalloc_uninit(upb_seededalloc *a);
+void upb_seededalloc_setfallbackalloc(upb_seededalloc *a, upb_alloc_func *func,
+ void *ud);
+upb_alloc_func *upb_seededalloc_getallocfunc(upb_seededalloc *a);
+
+UPB_END_EXTERN_C
+
+#ifdef __cplusplus
+
+namespace upb {
+
+inline Environment::Environment() {
+ upb_env_init(this);
+}
+inline Environment::~Environment() {
+ upb_env_uninit(this);
+}
+inline void Environment::SetAllocationFunction(upb_alloc_func *alloc,
+ void *ud) {
+ upb_env_setallocfunc(this, alloc, ud);
+}
+inline void Environment::SetErrorFunction(upb_error_func *func, void *ud) {
+ upb_env_seterrorfunc(this, func, ud);
+}
+inline void Environment::ReportErrorsTo(Status* status) {
+ upb_env_reporterrorsto(this, status);
+}
+inline bool Environment::ok() const {
+ return upb_env_ok(this);
+}
+inline bool Environment::ReportError(const Status* status) {
+ return upb_env_reporterror(this, status);
+}
+inline void *Environment::Malloc(size_t size) {
+ return upb_env_malloc(this, size);
+}
+inline void *Environment::Realloc(void *ptr, size_t oldsize, size_t size) {
+ return upb_env_realloc(this, ptr, oldsize, size);
+}
+inline bool Environment::AddCleanup(upb_cleanup_func *func, void *ud) {
+ return upb_env_addcleanup(this, func, ud);
+}
+inline size_t Environment::BytesAllocated() const {
+ return upb_env_bytesallocated(this);
+}
+
+inline SeededAllocator::SeededAllocator(void *mem, size_t len) {
+ upb_seededalloc_init(this, mem, len);
+}
+inline SeededAllocator::~SeededAllocator() {
+ upb_seededalloc_uninit(this);
+}
+inline void SeededAllocator::SetFallbackAllocator(upb_alloc_func *alloc,
+ void *ud) {
+ upb_seededalloc_setfallbackalloc(this, alloc, ud);
+}
+inline upb_alloc_func *SeededAllocator::GetAllocationFunction() {
+ return upb_seededalloc_getallocfunc(this);
+}
+
+} /* namespace upb */
+
+#endif /* __cplusplus */
+
+#endif /* UPB_ENV_H_ */
+/*
+** upb::Sink (upb_sink)
+** upb::BytesSink (upb_bytessink)
+**
+** A upb_sink is an object that binds a upb_handlers object to some runtime
+** state. It is the object that can actually receive data via the upb_handlers
+** interface.
+**
+** Unlike upb_def and upb_handlers, upb_sink is never frozen, immutable, or
+** thread-safe. You can create as many of them as you want, but each one may
+** only be used in a single thread at a time.
+**
+** If we compare with class-based OOP, a you can think of a upb_def as an
+** abstract base class, a upb_handlers as a concrete derived class, and a
+** upb_sink as an object (class instance).
+*/
+
+#ifndef UPB_SINK_H
+#define UPB_SINK_H
+
+
+#ifdef __cplusplus
+namespace upb {
+class BufferSource;
+class BytesSink;
+class Sink;
+}
+#endif
+
+UPB_DECLARE_TYPE(upb::BufferSource, upb_bufsrc)
+UPB_DECLARE_TYPE(upb::BytesSink, upb_bytessink)
+UPB_DECLARE_TYPE(upb::Sink, upb_sink)
+
+#ifdef __cplusplus
+
+/* A upb::Sink is an object that binds a upb::Handlers object to some runtime
+ * state. It represents an endpoint to which data can be sent.
+ *
+ * TODO(haberman): right now all of these functions take selectors. Should they
+ * take selectorbase instead?
+ *
+ * ie. instead of calling:
+ * sink->StartString(FOO_FIELD_START_STRING, ...)
+ * a selector base would let you say:
+ * sink->StartString(FOO_FIELD, ...)
+ *
+ * This would make call sites a little nicer and require emitting fewer selector
+ * definitions in .h files.
+ *
+ * But the current scheme has the benefit that you can retrieve a function
+ * pointer for any handler with handlers->GetHandler(selector), without having
+ * to have a separate GetHandler() function for each handler type. The JIT
+ * compiler uses this. To accommodate we'd have to expose a separate
+ * GetHandler() for every handler type.
+ *
+ * Also to ponder: selectors right now are independent of a specific Handlers
+ * instance. In other words, they allocate a number to every possible handler
+ * that *could* be registered, without knowing anything about what handlers
+ * *are* registered. That means that using selectors as table offsets prohibits
+ * us from compacting the handler table at Freeze() time. If the table is very
+ * sparse, this could be wasteful.
+ *
+ * Having another selector-like thing that is specific to a Handlers instance
+ * would allow this compacting, but then it would be impossible to write code
+ * ahead-of-time that can be bound to any Handlers instance at runtime. For
+ * example, a .proto file parser written as straight C will not know what
+ * Handlers it will be bound to, so when it calls sink->StartString() what
+ * selector will it pass? It needs a selector like we have today, that is
+ * independent of any particular upb::Handlers.
+ *
+ * Is there a way then to allow Handlers table compaction? */
+class upb::Sink {
+ public:
+ /* Constructor with no initialization; must be Reset() before use. */
+ Sink() {}
+
+ /* Constructs a new sink for the given frozen handlers and closure.
+ *
+ * TODO: once the Handlers know the expected closure type, verify that T
+ * matches it. */
+ template <class T> Sink(const Handlers* handlers, T* closure);
+
+ /* Resets the value of the sink. */
+ template <class T> void Reset(const Handlers* handlers, T* closure);
+
+ /* Returns the top-level object that is bound to this sink.
+ *
+ * TODO: once the Handlers know the expected closure type, verify that T
+ * matches it. */
+ template <class T> T* GetObject() const;
+
+ /* Functions for pushing data into the sink.
+ *
+ * These return false if processing should stop (either due to error or just
+ * to suspend).
+ *
+ * These may not be called from within one of the same sink's handlers (in
+ * other words, handlers are not re-entrant). */
+
+ /* Should be called at the start and end of every message; both the top-level
+ * message and submessages. This means that submessages should use the
+ * following sequence:
+ * sink->StartSubMessage(startsubmsg_selector);
+ * sink->StartMessage();
+ * // ...
+ * sink->EndMessage(&status);
+ * sink->EndSubMessage(endsubmsg_selector); */
+ bool StartMessage();
+ bool EndMessage(Status* status);
+
+ /* Putting of individual values. These work for both repeated and
+ * non-repeated fields, but for repeated fields you must wrap them in
+ * calls to StartSequence()/EndSequence(). */
+ bool PutInt32(Handlers::Selector s, int32_t val);
+ bool PutInt64(Handlers::Selector s, int64_t val);
+ bool PutUInt32(Handlers::Selector s, uint32_t val);
+ bool PutUInt64(Handlers::Selector s, uint64_t val);
+ bool PutFloat(Handlers::Selector s, float val);
+ bool PutDouble(Handlers::Selector s, double val);
+ bool PutBool(Handlers::Selector s, bool val);
+
+ /* Putting of string/bytes values. Each string can consist of zero or more
+ * non-contiguous buffers of data.
+ *
+ * For StartString(), the function will write a sink for the string to "sub."
+ * The sub-sink must be used for any/all PutStringBuffer() calls. */
+ bool StartString(Handlers::Selector s, size_t size_hint, Sink* sub);
+ size_t PutStringBuffer(Handlers::Selector s, const char *buf, size_t len,
+ const BufferHandle *handle);
+ bool EndString(Handlers::Selector s);
+
+ /* For submessage fields.
+ *
+ * For StartSubMessage(), the function will write a sink for the string to
+ * "sub." The sub-sink must be used for any/all handlers called within the
+ * submessage. */
+ bool StartSubMessage(Handlers::Selector s, Sink* sub);
+ bool EndSubMessage(Handlers::Selector s);
+
+ /* For repeated fields of any type, the sequence of values must be wrapped in
+ * these calls.
+ *
+ * For StartSequence(), the function will write a sink for the string to
+ * "sub." The sub-sink must be used for any/all handlers called within the
+ * sequence. */
+ bool StartSequence(Handlers::Selector s, Sink* sub);
+ bool EndSequence(Handlers::Selector s);
+
+ /* Copy and assign specifically allowed.
+ * We don't even bother making these members private because so many
+ * functions need them and this is mainly just a dumb data container anyway.
+ */
+#else
+struct upb_sink {
+#endif
+ const upb_handlers *handlers;
+ void *closure;
+};
+
+#ifdef __cplusplus
+class upb::BytesSink {
+ public:
+ BytesSink() {}
+
+ /* Constructs a new sink for the given frozen handlers and closure.
+ *
+ * TODO(haberman): once the Handlers know the expected closure type, verify
+ * that T matches it. */
+ template <class T> BytesSink(const BytesHandler* handler, T* closure);
+
+ /* Resets the value of the sink. */
+ template <class T> void Reset(const BytesHandler* handler, T* closure);
+
+ bool Start(size_t size_hint, void **subc);
+ size_t PutBuffer(void *subc, const char *buf, size_t len,
+ const BufferHandle *handle);
+ bool End();
+#else
+struct upb_bytessink {
+#endif
+ const upb_byteshandler *handler;
+ void *closure;
+};
+
+#ifdef __cplusplus
+
+/* A class for pushing a flat buffer of data to a BytesSink.
+ * You can construct an instance of this to get a resumable source,
+ * or just call the static PutBuffer() to do a non-resumable push all in one
+ * go. */
+class upb::BufferSource {
+ public:
+ BufferSource();
+ BufferSource(const char* buf, size_t len, BytesSink* sink);
+
+ /* Returns true if the entire buffer was pushed successfully. Otherwise the
+ * next call to PutNext() will resume where the previous one left off.
+ * TODO(haberman): implement this. */
+ bool PutNext();
+
+ /* A static version; with this version is it not possible to resume in the
+ * case of failure or a partially-consumed buffer. */
+ static bool PutBuffer(const char* buf, size_t len, BytesSink* sink);
+
+ template <class T> static bool PutBuffer(const T& str, BytesSink* sink) {
+ return PutBuffer(str.c_str(), str.size(), sink);
+ }
+#else
+struct upb_bufsrc {
+ char dummy;
+#endif
+};
+
+UPB_BEGIN_EXTERN_C
+
+/* Inline definitions. */
+
+UPB_INLINE void upb_bytessink_reset(upb_bytessink *s, const upb_byteshandler *h,
+ void *closure) {
+ s->handler = h;
+ s->closure = closure;
+}
+
+UPB_INLINE bool upb_bytessink_start(upb_bytessink *s, size_t size_hint,
+ void **subc) {
+ typedef upb_startstr_handlerfunc func;
+ func *start;
+ *subc = s->closure;
+ if (!s->handler) return true;
+ start = (func *)s->handler->table[UPB_STARTSTR_SELECTOR].func;
+
+ if (!start) return true;
+ *subc = start(s->closure, upb_handlerattr_handlerdata(
+ &s->handler->table[UPB_STARTSTR_SELECTOR].attr),
+ size_hint);
+ return *subc != NULL;
+}
+
+UPB_INLINE size_t upb_bytessink_putbuf(upb_bytessink *s, void *subc,
+ const char *buf, size_t size,
+ const upb_bufhandle* handle) {
+ typedef upb_string_handlerfunc func;
+ func *putbuf;
+ if (!s->handler) return true;
+ putbuf = (func *)s->handler->table[UPB_STRING_SELECTOR].func;
+
+ if (!putbuf) return true;
+ return putbuf(subc, upb_handlerattr_handlerdata(
+ &s->handler->table[UPB_STRING_SELECTOR].attr),
+ buf, size, handle);
+}
+
+UPB_INLINE bool upb_bytessink_end(upb_bytessink *s) {
+ typedef upb_endfield_handlerfunc func;
+ func *end;
+ if (!s->handler) return true;
+ end = (func *)s->handler->table[UPB_ENDSTR_SELECTOR].func;
+
+ if (!end) return true;
+ return end(s->closure,
+ upb_handlerattr_handlerdata(
+ &s->handler->table[UPB_ENDSTR_SELECTOR].attr));
+}
+
+UPB_INLINE bool upb_bufsrc_putbuf(const char *buf, size_t len,
+ upb_bytessink *sink) {
+ void *subc;
+ bool ret;
+ upb_bufhandle handle;
+ upb_bufhandle_init(&handle);
+ upb_bufhandle_setbuf(&handle, buf, 0);
+ ret = upb_bytessink_start(sink, len, &subc);
+ if (ret && len != 0) {
+ ret = (upb_bytessink_putbuf(sink, subc, buf, len, &handle) >= len);
+ }
+ if (ret) {
+ ret = upb_bytessink_end(sink);
+ }
+ upb_bufhandle_uninit(&handle);
+ return ret;
+}
+
+#define PUTVAL(type, ctype) \
+ UPB_INLINE bool upb_sink_put##type(upb_sink *s, upb_selector_t sel, \
+ ctype val) { \
+ typedef upb_##type##_handlerfunc functype; \
+ functype *func; \
+ const void *hd; \
+ if (!s->handlers) return true; \
+ func = (functype *)upb_handlers_gethandler(s->handlers, sel); \
+ if (!func) return true; \
+ hd = upb_handlers_gethandlerdata(s->handlers, sel); \
+ return func(s->closure, hd, val); \
+ }
+
+PUTVAL(int32, int32_t)
+PUTVAL(int64, int64_t)
+PUTVAL(uint32, uint32_t)
+PUTVAL(uint64, uint64_t)
+PUTVAL(float, float)
+PUTVAL(double, double)
+PUTVAL(bool, bool)
+#undef PUTVAL
+
+UPB_INLINE void upb_sink_reset(upb_sink *s, const upb_handlers *h, void *c) {
+ s->handlers = h;
+ s->closure = c;
+}
+
+UPB_INLINE size_t upb_sink_putstring(upb_sink *s, upb_selector_t sel,
+ const char *buf, size_t n,
+ const upb_bufhandle *handle) {
+ typedef upb_string_handlerfunc func;
+ func *handler;
+ const void *hd;
+ if (!s->handlers) return n;
+ handler = (func *)upb_handlers_gethandler(s->handlers, sel);
+
+ if (!handler) return n;
+ hd = upb_handlers_gethandlerdata(s->handlers, sel);
+ return handler(s->closure, hd, buf, n, handle);
+}
+
+UPB_INLINE bool upb_sink_startmsg(upb_sink *s) {
+ typedef upb_startmsg_handlerfunc func;
+ func *startmsg;
+ const void *hd;
+ if (!s->handlers) return true;
+ startmsg = (func*)upb_handlers_gethandler(s->handlers, UPB_STARTMSG_SELECTOR);
+
+ if (!startmsg) return true;
+ hd = upb_handlers_gethandlerdata(s->handlers, UPB_STARTMSG_SELECTOR);
+ return startmsg(s->closure, hd);
+}
+
+UPB_INLINE bool upb_sink_endmsg(upb_sink *s, upb_status *status) {
+ typedef upb_endmsg_handlerfunc func;
+ func *endmsg;
+ const void *hd;
+ if (!s->handlers) return true;
+ endmsg = (func *)upb_handlers_gethandler(s->handlers, UPB_ENDMSG_SELECTOR);
+
+ if (!endmsg) return true;
+ hd = upb_handlers_gethandlerdata(s->handlers, UPB_ENDMSG_SELECTOR);
+ return endmsg(s->closure, hd, status);
+}
+
+UPB_INLINE bool upb_sink_startseq(upb_sink *s, upb_selector_t sel,
+ upb_sink *sub) {
+ typedef upb_startfield_handlerfunc func;
+ func *startseq;
+ const void *hd;
+ sub->closure = s->closure;
+ sub->handlers = s->handlers;
+ if (!s->handlers) return true;
+ startseq = (func*)upb_handlers_gethandler(s->handlers, sel);
+
+ if (!startseq) return true;
+ hd = upb_handlers_gethandlerdata(s->handlers, sel);
+ sub->closure = startseq(s->closure, hd);
+ return sub->closure ? true : false;
+}
+
+UPB_INLINE bool upb_sink_endseq(upb_sink *s, upb_selector_t sel) {
+ typedef upb_endfield_handlerfunc func;
+ func *endseq;
+ const void *hd;
+ if (!s->handlers) return true;
+ endseq = (func*)upb_handlers_gethandler(s->handlers, sel);
+
+ if (!endseq) return true;
+ hd = upb_handlers_gethandlerdata(s->handlers, sel);
+ return endseq(s->closure, hd);
+}
+
+UPB_INLINE bool upb_sink_startstr(upb_sink *s, upb_selector_t sel,
+ size_t size_hint, upb_sink *sub) {
+ typedef upb_startstr_handlerfunc func;
+ func *startstr;
+ const void *hd;
+ sub->closure = s->closure;
+ sub->handlers = s->handlers;
+ if (!s->handlers) return true;
+ startstr = (func*)upb_handlers_gethandler(s->handlers, sel);
+
+ if (!startstr) return true;
+ hd = upb_handlers_gethandlerdata(s->handlers, sel);
+ sub->closure = startstr(s->closure, hd, size_hint);
+ return sub->closure ? true : false;
+}
+
+UPB_INLINE bool upb_sink_endstr(upb_sink *s, upb_selector_t sel) {
+ typedef upb_endfield_handlerfunc func;
+ func *endstr;
+ const void *hd;
+ if (!s->handlers) return true;
+ endstr = (func*)upb_handlers_gethandler(s->handlers, sel);
+
+ if (!endstr) return true;
+ hd = upb_handlers_gethandlerdata(s->handlers, sel);
+ return endstr(s->closure, hd);
+}
+
+UPB_INLINE bool upb_sink_startsubmsg(upb_sink *s, upb_selector_t sel,
+ upb_sink *sub) {
+ typedef upb_startfield_handlerfunc func;
+ func *startsubmsg;
+ const void *hd;
+ sub->closure = s->closure;
+ if (!s->handlers) {
+ sub->handlers = NULL;
+ return true;
+ }
+ sub->handlers = upb_handlers_getsubhandlers_sel(s->handlers, sel);
+ startsubmsg = (func*)upb_handlers_gethandler(s->handlers, sel);
+
+ if (!startsubmsg) return true;
+ hd = upb_handlers_gethandlerdata(s->handlers, sel);
+ sub->closure = startsubmsg(s->closure, hd);
+ return sub->closure ? true : false;
+}
+
+UPB_INLINE bool upb_sink_endsubmsg(upb_sink *s, upb_selector_t sel) {
+ typedef upb_endfield_handlerfunc func;
+ func *endsubmsg;
+ const void *hd;
+ if (!s->handlers) return true;
+ endsubmsg = (func*)upb_handlers_gethandler(s->handlers, sel);
+
+ if (!endsubmsg) return s->closure;
+ hd = upb_handlers_gethandlerdata(s->handlers, sel);
+ return endsubmsg(s->closure, hd);
+}
+
+UPB_END_EXTERN_C
+
+#ifdef __cplusplus
+
+namespace upb {
+
+template <class T> Sink::Sink(const Handlers* handlers, T* closure) {
+ upb_sink_reset(this, handlers, closure);
+}
+template <class T>
+inline void Sink::Reset(const Handlers* handlers, T* closure) {
+ upb_sink_reset(this, handlers, closure);
+}
+inline bool Sink::StartMessage() {
+ return upb_sink_startmsg(this);
+}
+inline bool Sink::EndMessage(Status* status) {
+ return upb_sink_endmsg(this, status);
+}
+inline bool Sink::PutInt32(Handlers::Selector sel, int32_t val) {
+ return upb_sink_putint32(this, sel, val);
+}
+inline bool Sink::PutInt64(Handlers::Selector sel, int64_t val) {
+ return upb_sink_putint64(this, sel, val);
+}
+inline bool Sink::PutUInt32(Handlers::Selector sel, uint32_t val) {
+ return upb_sink_putuint32(this, sel, val);
+}
+inline bool Sink::PutUInt64(Handlers::Selector sel, uint64_t val) {
+ return upb_sink_putuint64(this, sel, val);
+}
+inline bool Sink::PutFloat(Handlers::Selector sel, float val) {
+ return upb_sink_putfloat(this, sel, val);
+}
+inline bool Sink::PutDouble(Handlers::Selector sel, double val) {
+ return upb_sink_putdouble(this, sel, val);
+}
+inline bool Sink::PutBool(Handlers::Selector sel, bool val) {
+ return upb_sink_putbool(this, sel, val);
+}
+inline bool Sink::StartString(Handlers::Selector sel, size_t size_hint,
+ Sink *sub) {
+ return upb_sink_startstr(this, sel, size_hint, sub);
+}
+inline size_t Sink::PutStringBuffer(Handlers::Selector sel, const char *buf,
+ size_t len, const BufferHandle* handle) {
+ return upb_sink_putstring(this, sel, buf, len, handle);
+}
+inline bool Sink::EndString(Handlers::Selector sel) {
+ return upb_sink_endstr(this, sel);
+}
+inline bool Sink::StartSubMessage(Handlers::Selector sel, Sink* sub) {
+ return upb_sink_startsubmsg(this, sel, sub);
+}
+inline bool Sink::EndSubMessage(Handlers::Selector sel) {
+ return upb_sink_endsubmsg(this, sel);
+}
+inline bool Sink::StartSequence(Handlers::Selector sel, Sink* sub) {
+ return upb_sink_startseq(this, sel, sub);
+}
+inline bool Sink::EndSequence(Handlers::Selector sel) {
+ return upb_sink_endseq(this, sel);
+}
+
+template <class T>
+BytesSink::BytesSink(const BytesHandler* handler, T* closure) {
+ Reset(handler, closure);
+}
+
+template <class T>
+void BytesSink::Reset(const BytesHandler *handler, T *closure) {
+ upb_bytessink_reset(this, handler, closure);
+}
+inline bool BytesSink::Start(size_t size_hint, void **subc) {
+ return upb_bytessink_start(this, size_hint, subc);
+}
+inline size_t BytesSink::PutBuffer(void *subc, const char *buf, size_t len,
+ const BufferHandle *handle) {
+ return upb_bytessink_putbuf(this, subc, buf, len, handle);
+}
+inline bool BytesSink::End() {
+ return upb_bytessink_end(this);
+}
+
+inline bool BufferSource::PutBuffer(const char *buf, size_t len,
+ BytesSink *sink) {
+ return upb_bufsrc_putbuf(buf, len, sink);
+}
+
+} /* namespace upb */
+#endif
+
+#endif
+/*
+** For handlers that do very tiny, very simple operations, the function call
+** overhead of calling a handler can be significant. This file allows the
+** user to define handlers that do something very simple like store the value
+** to memory and/or set a hasbit. JIT compilers can then special-case these
+** handlers and emit specialized code for them instead of actually calling the
+** handler.
+**
+** The functionality is very simple/limited right now but may expand to be able
+** to call another function.
+*/
+
+#ifndef UPB_SHIM_H
+#define UPB_SHIM_H
+
+
+typedef struct {
+ size_t offset;
+ int32_t hasbit;
+} upb_shim_data;
+
+#ifdef __cplusplus
+
+namespace upb {
+
+struct Shim {
+ typedef upb_shim_data Data;
+
+ /* Sets a handler for the given field that writes the value to the given
+ * offset and, if hasbit >= 0, sets a bit at the given bit offset. Returns
+ * true if the handler was set successfully. */
+ static bool Set(Handlers *h, const FieldDef *f, size_t ofs, int32_t hasbit);
+
+ /* If this handler is a shim, returns the corresponding upb::Shim::Data and
+ * stores the type in "type". Otherwise returns NULL. */
+ static const Data* GetData(const Handlers* h, Handlers::Selector s,
+ FieldDef::Type* type);
+};
+
+} /* namespace upb */
+
+#endif
+
+UPB_BEGIN_EXTERN_C
+
+/* C API. */
+bool upb_shim_set(upb_handlers *h, const upb_fielddef *f, size_t offset,
+ int32_t hasbit);
+const upb_shim_data *upb_shim_getdata(const upb_handlers *h, upb_selector_t s,
+ upb_fieldtype_t *type);
+
+UPB_END_EXTERN_C
+
+#ifdef __cplusplus
+/* C++ Wrappers. */
+namespace upb {
+inline bool Shim::Set(Handlers* h, const FieldDef* f, size_t ofs,
+ int32_t hasbit) {
+ return upb_shim_set(h, f, ofs, hasbit);
+}
+inline const Shim::Data* Shim::GetData(const Handlers* h, Handlers::Selector s,
+ FieldDef::Type* type) {
+ return upb_shim_getdata(h, s, type);
+}
+} /* namespace upb */
+#endif
+
+#endif /* UPB_SHIM_H */
+/*
+** upb::SymbolTable (upb_symtab)
+**
+** A symtab (symbol table) stores a name->def map of upb_defs. Clients could
+** always create such tables themselves, but upb_symtab has logic for resolving
+** symbolic references, and in particular, for keeping a whole set of consistent
+** defs when replacing some subset of those defs. This logic is nontrivial.
+**
+** This is a mixed C/C++ interface that offers a full API to both languages.
+** See the top-level README for more information.
+*/
+
+#ifndef UPB_SYMTAB_H_
+#define UPB_SYMTAB_H_
+
+
+#ifdef __cplusplus
+#include <vector>
+namespace upb { class SymbolTable; }
+#endif
+
+UPB_DECLARE_DERIVED_TYPE(upb::SymbolTable, upb::RefCounted,
+ upb_symtab, upb_refcounted)
+
+typedef struct {
+ UPB_PRIVATE_FOR_CPP
+ upb_strtable_iter iter;
+ upb_deftype_t type;
+} upb_symtab_iter;
+
+#ifdef __cplusplus
+
+/* Non-const methods in upb::SymbolTable are NOT thread-safe. */
+class upb::SymbolTable {
+ public:
+ /* Returns a new symbol table with a single ref owned by "owner."
+ * Returns NULL if memory allocation failed. */
+ static reffed_ptr<SymbolTable> New();
+
+ /* Include RefCounted base methods. */
+ UPB_REFCOUNTED_CPPMETHODS
+
+ /* For all lookup functions, the returned pointer is not owned by the
+ * caller; it may be invalidated by any non-const call or unref of the
+ * SymbolTable! To protect against this, take a ref if desired. */
+
+ /* Freezes the symbol table: prevents further modification of it.
+ * After the Freeze() operation is successful, the SymbolTable must only be
+ * accessed via a const pointer.
+ *
+ * Unlike with upb::MessageDef/upb::EnumDef/etc, freezing a SymbolTable is not
+ * a necessary step in using a SymbolTable. If you have no need for it to be
+ * immutable, there is no need to freeze it ever. However sometimes it is
+ * useful, and SymbolTables that are statically compiled into the binary are
+ * always frozen by nature. */
+ void Freeze();
+
+ /* Resolves the given symbol using the rules described in descriptor.proto,
+ * namely:
+ *
+ * If the name starts with a '.', it is fully-qualified. Otherwise,
+ * C++-like scoping rules are used to find the type (i.e. first the nested
+ * types within this message are searched, then within the parent, on up
+ * to the root namespace).
+ *
+ * If not found, returns NULL. */
+ const Def* Resolve(const char* base, const char* sym) const;
+
+ /* Finds an entry in the symbol table with this exact name. If not found,
+ * returns NULL. */
+ const Def* Lookup(const char *sym) const;
+ const MessageDef* LookupMessage(const char *sym) const;
+ const EnumDef* LookupEnum(const char *sym) const;
+
+ /* TODO: introduce a C++ iterator, but make it nice and templated so that if
+ * you ask for an iterator of MessageDef the iterated elements are strongly
+ * typed as MessageDef*. */
+
+ /* Adds the given mutable defs to the symtab, resolving all symbols
+ * (including enum default values) and finalizing the defs. Only one def per
+ * name may be in the list, but defs can replace existing defs in the symtab.
+ * All defs must have a name -- anonymous defs are not allowed. Anonymous
+ * defs can still be frozen by calling upb_def_freeze() directly.
+ *
+ * Any existing defs that can reach defs that are being replaced will
+ * themselves be replaced also, so that the resulting set of defs is fully
+ * consistent.
+ *
+ * This logic implemented in this method is a convenience; ultimately it
+ * calls some combination of upb_fielddef_setsubdef(), upb_def_dup(), and
+ * upb_freeze(), any of which the client could call themself. However, since
+ * the logic for doing so is nontrivial, we provide it here.
+ *
+ * The entire operation either succeeds or fails. If the operation fails,
+ * the symtab is unchanged, false is returned, and status indicates the
+ * error. The caller passes a ref on all defs to the symtab (even if the
+ * operation fails).
+ *
+ * TODO(haberman): currently failure will leave the symtab unchanged, but may
+ * leave the defs themselves partially resolved. Does this matter? If so we
+ * could do a prepass that ensures that all symbols are resolvable and bail
+ * if not, so we don't mutate anything until we know the operation will
+ * succeed.
+ *
+ * TODO(haberman): since the defs must be mutable, refining a frozen def
+ * requires making mutable copies of the entire tree. This is wasteful if
+ * only a few messages are changing. We may want to add a way of adding a
+ * tree of frozen defs to the symtab (perhaps an alternate constructor where
+ * you pass the root of the tree?) */
+ bool Add(Def*const* defs, int n, void* ref_donor, upb_status* status);
+
+ bool Add(const std::vector<Def*>& defs, void *owner, Status* status) {
+ return Add((Def*const*)&defs[0], defs.size(), owner, status);
+ }
+
+ private:
+ UPB_DISALLOW_POD_OPS(SymbolTable, upb::SymbolTable)
+};
+
+#endif /* __cplusplus */
+
+UPB_BEGIN_EXTERN_C
+
+/* Native C API. */
+
+/* Include refcounted methods like upb_symtab_ref(). */
+UPB_REFCOUNTED_CMETHODS(upb_symtab, upb_symtab_upcast)
+
+upb_symtab *upb_symtab_new(const void *owner);
+void upb_symtab_freeze(upb_symtab *s);
+const upb_def *upb_symtab_resolve(const upb_symtab *s, const char *base,
+ const char *sym);
+const upb_def *upb_symtab_lookup(const upb_symtab *s, const char *sym);
+const upb_msgdef *upb_symtab_lookupmsg(const upb_symtab *s, const char *sym);
+const upb_enumdef *upb_symtab_lookupenum(const upb_symtab *s, const char *sym);
+bool upb_symtab_add(upb_symtab *s, upb_def *const*defs, int n, void *ref_donor,
+ upb_status *status);
+
+/* upb_symtab_iter i;
+ * for(upb_symtab_begin(&i, s, type); !upb_symtab_done(&i);
+ * upb_symtab_next(&i)) {
+ * const upb_def *def = upb_symtab_iter_def(&i);
+ * // ...
+ * }
+ *
+ * For C we don't have separate iterators for const and non-const.
+ * It is the caller's responsibility to cast the upb_fielddef* to
+ * const if the upb_msgdef* is const. */
+void upb_symtab_begin(upb_symtab_iter *iter, const upb_symtab *s,
+ upb_deftype_t type);
+void upb_symtab_next(upb_symtab_iter *iter);
+bool upb_symtab_done(const upb_symtab_iter *iter);
+const upb_def *upb_symtab_iter_def(const upb_symtab_iter *iter);
+
+UPB_END_EXTERN_C
+
+#ifdef __cplusplus
+/* C++ inline wrappers. */
+namespace upb {
+inline reffed_ptr<SymbolTable> SymbolTable::New() {
+ upb_symtab *s = upb_symtab_new(&s);
+ return reffed_ptr<SymbolTable>(s, &s);
+}
+
+inline void SymbolTable::Freeze() {
+ return upb_symtab_freeze(this);
+}
+inline const Def *SymbolTable::Resolve(const char *base,
+ const char *sym) const {
+ return upb_symtab_resolve(this, base, sym);
+}
+inline const Def* SymbolTable::Lookup(const char *sym) const {
+ return upb_symtab_lookup(this, sym);
+}
+inline const MessageDef *SymbolTable::LookupMessage(const char *sym) const {
+ return upb_symtab_lookupmsg(this, sym);
+}
+inline bool SymbolTable::Add(
+ Def*const* defs, int n, void* ref_donor, upb_status* status) {
+ return upb_symtab_add(this, (upb_def*const*)defs, n, ref_donor, status);
+}
+} /* namespace upb */
+#endif
+
+#endif /* UPB_SYMTAB_H_ */
+/*
+** upb::descriptor::Reader (upb_descreader)
+**
+** Provides a way of building upb::Defs from data in descriptor.proto format.
+*/
+
+#ifndef UPB_DESCRIPTOR_H
+#define UPB_DESCRIPTOR_H
+
+
+#ifdef __cplusplus
+namespace upb {
+namespace descriptor {
+class Reader;
+} /* namespace descriptor */
+} /* namespace upb */
+#endif
+
+UPB_DECLARE_TYPE(upb::descriptor::Reader, upb_descreader)
+
+#ifdef __cplusplus
+
+/* Class that receives descriptor data according to the descriptor.proto schema
+ * and use it to build upb::Defs corresponding to that schema. */
+class upb::descriptor::Reader {
+ public:
+ /* These handlers must have come from NewHandlers() and must outlive the
+ * Reader.
+ *
+ * TODO: generate the handlers statically (like we do with the
+ * descriptor.proto defs) so that there is no need to pass this parameter (or
+ * to build/memory-manage the handlers at runtime at all). Unfortunately this
+ * is a bit tricky to implement for Handlers, but necessary to simplify this
+ * interface. */
+ static Reader* Create(Environment* env, const Handlers* handlers);
+
+ /* The reader's input; this is where descriptor.proto data should be sent. */
+ Sink* input();
+
+ /* Returns an array of all defs that have been parsed, and transfers ownership
+ * of them to "owner". The number of defs is stored in *n. Ownership of the
+ * returned array is retained and is invalidated by any other call into
+ * Reader.
+ *
+ * These defs are not frozen or resolved; they are ready to be added to a
+ * symtab. */
+ upb::Def** GetDefs(void* owner, int* n);
+
+ /* Builds and returns handlers for the reader, owned by "owner." */
+ static Handlers* NewHandlers(const void* owner);
+
+ private:
+ UPB_DISALLOW_POD_OPS(Reader, upb::descriptor::Reader)
+};
+
+#endif
+
+UPB_BEGIN_EXTERN_C
+
+/* C API. */
+upb_descreader *upb_descreader_create(upb_env *e, const upb_handlers *h);
+upb_sink *upb_descreader_input(upb_descreader *r);
+upb_def **upb_descreader_getdefs(upb_descreader *r, void *owner, int *n);
+const upb_handlers *upb_descreader_newhandlers(const void *owner);
+
+UPB_END_EXTERN_C
+
+#ifdef __cplusplus
+/* C++ implementation details. ************************************************/
+namespace upb {
+namespace descriptor {
+inline Reader* Reader::Create(Environment* e, const Handlers *h) {
+ return upb_descreader_create(e, h);
+}
+inline Sink* Reader::input() { return upb_descreader_input(this); }
+inline upb::Def** Reader::GetDefs(void* owner, int* n) {
+ return upb_descreader_getdefs(this, owner, n);
+}
+} /* namespace descriptor */
+} /* namespace upb */
+#endif
+
+#endif /* UPB_DESCRIPTOR_H */
+/* This file contains accessors for a set of compiled-in defs.
+ * Note that unlike Google's protobuf, it does *not* define
+ * generated classes or any other kind of data structure for
+ * actually storing protobufs. It only contains *defs* which
+ * let you reflect over a protobuf *schema*.
+ */
+/* This file was generated by upbc (the upb compiler).
+ * Do not edit -- your changes will be discarded when the file is
+ * regenerated. */
+
+#ifndef GOOGLE_PROTOBUF_DESCRIPTOR_UPB_H_
+#define GOOGLE_PROTOBUF_DESCRIPTOR_UPB_H_
+
+
+#ifdef __cplusplus
+UPB_BEGIN_EXTERN_C
+#endif
+
+/* Enums */
+
+typedef enum {
+ GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_LABEL_OPTIONAL = 1,
+ GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_LABEL_REQUIRED = 2,
+ GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_LABEL_REPEATED = 3
+} google_protobuf_FieldDescriptorProto_Label;
+
+typedef enum {
+ GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_DOUBLE = 1,
+ GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_FLOAT = 2,
+ GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_INT64 = 3,
+ GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_UINT64 = 4,
+ GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_INT32 = 5,
+ GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_FIXED64 = 6,
+ GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_FIXED32 = 7,
+ GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_BOOL = 8,
+ GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_STRING = 9,
+ GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_GROUP = 10,
+ GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_MESSAGE = 11,
+ GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_BYTES = 12,
+ GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_UINT32 = 13,
+ GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_ENUM = 14,
+ GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_SFIXED32 = 15,
+ GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_SFIXED64 = 16,
+ GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_SINT32 = 17,
+ GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_SINT64 = 18
+} google_protobuf_FieldDescriptorProto_Type;
+
+typedef enum {
+ GOOGLE_PROTOBUF_FIELDOPTIONS_STRING = 0,
+ GOOGLE_PROTOBUF_FIELDOPTIONS_CORD = 1,
+ GOOGLE_PROTOBUF_FIELDOPTIONS_STRING_PIECE = 2
+} google_protobuf_FieldOptions_CType;
+
+typedef enum {
+ GOOGLE_PROTOBUF_FILEOPTIONS_SPEED = 1,
+ GOOGLE_PROTOBUF_FILEOPTIONS_CODE_SIZE = 2,
+ GOOGLE_PROTOBUF_FILEOPTIONS_LITE_RUNTIME = 3
+} google_protobuf_FileOptions_OptimizeMode;
+
+/* Selectors */
+
+/* google.protobuf.DescriptorProto */
+#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_FIELD_STARTSUBMSG 2
+#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_NESTED_TYPE_STARTSUBMSG 3
+#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_ENUM_TYPE_STARTSUBMSG 4
+#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSION_RANGE_STARTSUBMSG 5
+#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSION_STARTSUBMSG 6
+#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_OPTIONS_STARTSUBMSG 7
+#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_FIELD_STARTSEQ 8
+#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_FIELD_ENDSEQ 9
+#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_FIELD_ENDSUBMSG 10
+#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_NESTED_TYPE_STARTSEQ 11
+#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_NESTED_TYPE_ENDSEQ 12
+#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_NESTED_TYPE_ENDSUBMSG 13
+#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_ENUM_TYPE_STARTSEQ 14
+#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_ENUM_TYPE_ENDSEQ 15
+#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_ENUM_TYPE_ENDSUBMSG 16
+#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSION_RANGE_STARTSEQ 17
+#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSION_RANGE_ENDSEQ 18
+#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSION_RANGE_ENDSUBMSG 19
+#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSION_STARTSEQ 20
+#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSION_ENDSEQ 21
+#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSION_ENDSUBMSG 22
+#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_OPTIONS_ENDSUBMSG 23
+#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_NAME_STRING 24
+#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_NAME_STARTSTR 25
+#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_NAME_ENDSTR 26
+
+/* google.protobuf.DescriptorProto.ExtensionRange */
+#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSIONRANGE_START_INT32 2
+#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSIONRANGE_END_INT32 3
+
+/* google.protobuf.EnumDescriptorProto */
+#define SEL_GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_VALUE_STARTSUBMSG 2
+#define SEL_GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_OPTIONS_STARTSUBMSG 3
+#define SEL_GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_VALUE_STARTSEQ 4
+#define SEL_GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_VALUE_ENDSEQ 5
+#define SEL_GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_VALUE_ENDSUBMSG 6
+#define SEL_GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_OPTIONS_ENDSUBMSG 7
+#define SEL_GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_NAME_STRING 8
+#define SEL_GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_NAME_STARTSTR 9
+#define SEL_GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_NAME_ENDSTR 10
+
+/* google.protobuf.EnumOptions */
+#define SEL_GOOGLE_PROTOBUF_ENUMOPTIONS_UNINTERPRETED_OPTION_STARTSUBMSG 2
+#define SEL_GOOGLE_PROTOBUF_ENUMOPTIONS_UNINTERPRETED_OPTION_STARTSEQ 3
+#define SEL_GOOGLE_PROTOBUF_ENUMOPTIONS_UNINTERPRETED_OPTION_ENDSEQ 4
+#define SEL_GOOGLE_PROTOBUF_ENUMOPTIONS_UNINTERPRETED_OPTION_ENDSUBMSG 5
+#define SEL_GOOGLE_PROTOBUF_ENUMOPTIONS_ALLOW_ALIAS_BOOL 6
+
+/* google.protobuf.EnumValueDescriptorProto */
+#define SEL_GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO_OPTIONS_STARTSUBMSG 2
+#define SEL_GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO_OPTIONS_ENDSUBMSG 3
+#define SEL_GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO_NAME_STRING 4
+#define SEL_GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO_NAME_STARTSTR 5
+#define SEL_GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO_NAME_ENDSTR 6
+#define SEL_GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO_NUMBER_INT32 7
+
+/* google.protobuf.EnumValueOptions */
+#define SEL_GOOGLE_PROTOBUF_ENUMVALUEOPTIONS_UNINTERPRETED_OPTION_STARTSUBMSG 2
+#define SEL_GOOGLE_PROTOBUF_ENUMVALUEOPTIONS_UNINTERPRETED_OPTION_STARTSEQ 3
+#define SEL_GOOGLE_PROTOBUF_ENUMVALUEOPTIONS_UNINTERPRETED_OPTION_ENDSEQ 4
+#define SEL_GOOGLE_PROTOBUF_ENUMVALUEOPTIONS_UNINTERPRETED_OPTION_ENDSUBMSG 5
+
+/* google.protobuf.FieldDescriptorProto */
+#define SEL_GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_OPTIONS_STARTSUBMSG 2
+#define SEL_GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_OPTIONS_ENDSUBMSG 3
+#define SEL_GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_NAME_STRING 4
+#define SEL_GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_NAME_STARTSTR 5
+#define SEL_GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_NAME_ENDSTR 6
+#define SEL_GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_EXTENDEE_STRING 7
+#define SEL_GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_EXTENDEE_STARTSTR 8
+#define SEL_GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_EXTENDEE_ENDSTR 9
+#define SEL_GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_NUMBER_INT32 10
+#define SEL_GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_LABEL_INT32 11
+#define SEL_GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_INT32 12
+#define SEL_GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_NAME_STRING 13
+#define SEL_GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_NAME_STARTSTR 14
+#define SEL_GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_NAME_ENDSTR 15
+#define SEL_GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_DEFAULT_VALUE_STRING 16
+#define SEL_GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_DEFAULT_VALUE_STARTSTR 17
+#define SEL_GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_DEFAULT_VALUE_ENDSTR 18
+
+/* google.protobuf.FieldOptions */
+#define SEL_GOOGLE_PROTOBUF_FIELDOPTIONS_UNINTERPRETED_OPTION_STARTSUBMSG 2
+#define SEL_GOOGLE_PROTOBUF_FIELDOPTIONS_UNINTERPRETED_OPTION_STARTSEQ 3
+#define SEL_GOOGLE_PROTOBUF_FIELDOPTIONS_UNINTERPRETED_OPTION_ENDSEQ 4
+#define SEL_GOOGLE_PROTOBUF_FIELDOPTIONS_UNINTERPRETED_OPTION_ENDSUBMSG 5
+#define SEL_GOOGLE_PROTOBUF_FIELDOPTIONS_CTYPE_INT32 6
+#define SEL_GOOGLE_PROTOBUF_FIELDOPTIONS_PACKED_BOOL 7
+#define SEL_GOOGLE_PROTOBUF_FIELDOPTIONS_DEPRECATED_BOOL 8
+#define SEL_GOOGLE_PROTOBUF_FIELDOPTIONS_LAZY_BOOL 9
+#define SEL_GOOGLE_PROTOBUF_FIELDOPTIONS_EXPERIMENTAL_MAP_KEY_STRING 10
+#define SEL_GOOGLE_PROTOBUF_FIELDOPTIONS_EXPERIMENTAL_MAP_KEY_STARTSTR 11
+#define SEL_GOOGLE_PROTOBUF_FIELDOPTIONS_EXPERIMENTAL_MAP_KEY_ENDSTR 12
+#define SEL_GOOGLE_PROTOBUF_FIELDOPTIONS_WEAK_BOOL 13
+
+/* google.protobuf.FileDescriptorProto */
+#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_MESSAGE_TYPE_STARTSUBMSG 2
+#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_ENUM_TYPE_STARTSUBMSG 3
+#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_SERVICE_STARTSUBMSG 4
+#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_EXTENSION_STARTSUBMSG 5
+#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_OPTIONS_STARTSUBMSG 6
+#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_SOURCE_CODE_INFO_STARTSUBMSG 7
+#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_MESSAGE_TYPE_STARTSEQ 8
+#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_MESSAGE_TYPE_ENDSEQ 9
+#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_MESSAGE_TYPE_ENDSUBMSG 10
+#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_ENUM_TYPE_STARTSEQ 11
+#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_ENUM_TYPE_ENDSEQ 12
+#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_ENUM_TYPE_ENDSUBMSG 13
+#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_SERVICE_STARTSEQ 14
+#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_SERVICE_ENDSEQ 15
+#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_SERVICE_ENDSUBMSG 16
+#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_EXTENSION_STARTSEQ 17
+#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_EXTENSION_ENDSEQ 18
+#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_EXTENSION_ENDSUBMSG 19
+#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_OPTIONS_ENDSUBMSG 20
+#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_SOURCE_CODE_INFO_ENDSUBMSG 21
+#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_NAME_STRING 22
+#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_NAME_STARTSTR 23
+#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_NAME_ENDSTR 24
+#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_PACKAGE_STRING 25
+#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_PACKAGE_STARTSTR 26
+#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_PACKAGE_ENDSTR 27
+#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_DEPENDENCY_STARTSEQ 28
+#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_DEPENDENCY_ENDSEQ 29
+#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_DEPENDENCY_STRING 30
+#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_DEPENDENCY_STARTSTR 31
+#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_DEPENDENCY_ENDSTR 32
+#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_PUBLIC_DEPENDENCY_STARTSEQ 33
+#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_PUBLIC_DEPENDENCY_ENDSEQ 34
+#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_PUBLIC_DEPENDENCY_INT32 35
+#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_WEAK_DEPENDENCY_STARTSEQ 36
+#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_WEAK_DEPENDENCY_ENDSEQ 37
+#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_WEAK_DEPENDENCY_INT32 38
+
+/* google.protobuf.FileDescriptorSet */
+#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORSET_FILE_STARTSUBMSG 2
+#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORSET_FILE_STARTSEQ 3
+#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORSET_FILE_ENDSEQ 4
+#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORSET_FILE_ENDSUBMSG 5
+
+/* google.protobuf.FileOptions */
+#define SEL_GOOGLE_PROTOBUF_FILEOPTIONS_UNINTERPRETED_OPTION_STARTSUBMSG 2
+#define SEL_GOOGLE_PROTOBUF_FILEOPTIONS_UNINTERPRETED_OPTION_STARTSEQ 3
+#define SEL_GOOGLE_PROTOBUF_FILEOPTIONS_UNINTERPRETED_OPTION_ENDSEQ 4
+#define SEL_GOOGLE_PROTOBUF_FILEOPTIONS_UNINTERPRETED_OPTION_ENDSUBMSG 5
+#define SEL_GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_PACKAGE_STRING 6
+#define SEL_GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_PACKAGE_STARTSTR 7
+#define SEL_GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_PACKAGE_ENDSTR 8
+#define SEL_GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_OUTER_CLASSNAME_STRING 9
+#define SEL_GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_OUTER_CLASSNAME_STARTSTR 10
+#define SEL_GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_OUTER_CLASSNAME_ENDSTR 11
+#define SEL_GOOGLE_PROTOBUF_FILEOPTIONS_OPTIMIZE_FOR_INT32 12
+#define SEL_GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_MULTIPLE_FILES_BOOL 13
+#define SEL_GOOGLE_PROTOBUF_FILEOPTIONS_GO_PACKAGE_STRING 14
+#define SEL_GOOGLE_PROTOBUF_FILEOPTIONS_GO_PACKAGE_STARTSTR 15
+#define SEL_GOOGLE_PROTOBUF_FILEOPTIONS_GO_PACKAGE_ENDSTR 16
+#define SEL_GOOGLE_PROTOBUF_FILEOPTIONS_CC_GENERIC_SERVICES_BOOL 17
+#define SEL_GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_GENERIC_SERVICES_BOOL 18
+#define SEL_GOOGLE_PROTOBUF_FILEOPTIONS_PY_GENERIC_SERVICES_BOOL 19
+#define SEL_GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_GENERATE_EQUALS_AND_HASH_BOOL 20
+
+/* google.protobuf.MessageOptions */
+#define SEL_GOOGLE_PROTOBUF_MESSAGEOPTIONS_UNINTERPRETED_OPTION_STARTSUBMSG 2
+#define SEL_GOOGLE_PROTOBUF_MESSAGEOPTIONS_UNINTERPRETED_OPTION_STARTSEQ 3
+#define SEL_GOOGLE_PROTOBUF_MESSAGEOPTIONS_UNINTERPRETED_OPTION_ENDSEQ 4
+#define SEL_GOOGLE_PROTOBUF_MESSAGEOPTIONS_UNINTERPRETED_OPTION_ENDSUBMSG 5
+#define SEL_GOOGLE_PROTOBUF_MESSAGEOPTIONS_MESSAGE_SET_WIRE_FORMAT_BOOL 6
+#define SEL_GOOGLE_PROTOBUF_MESSAGEOPTIONS_NO_STANDARD_DESCRIPTOR_ACCESSOR_BOOL 7
+
+/* google.protobuf.MethodDescriptorProto */
+#define SEL_GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_OPTIONS_STARTSUBMSG 2
+#define SEL_GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_OPTIONS_ENDSUBMSG 3
+#define SEL_GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_NAME_STRING 4
+#define SEL_GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_NAME_STARTSTR 5
+#define SEL_GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_NAME_ENDSTR 6
+#define SEL_GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_INPUT_TYPE_STRING 7
+#define SEL_GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_INPUT_TYPE_STARTSTR 8
+#define SEL_GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_INPUT_TYPE_ENDSTR 9
+#define SEL_GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_OUTPUT_TYPE_STRING 10
+#define SEL_GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_OUTPUT_TYPE_STARTSTR 11
+#define SEL_GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_OUTPUT_TYPE_ENDSTR 12
+
+/* google.protobuf.MethodOptions */
+#define SEL_GOOGLE_PROTOBUF_METHODOPTIONS_UNINTERPRETED_OPTION_STARTSUBMSG 2
+#define SEL_GOOGLE_PROTOBUF_METHODOPTIONS_UNINTERPRETED_OPTION_STARTSEQ 3
+#define SEL_GOOGLE_PROTOBUF_METHODOPTIONS_UNINTERPRETED_OPTION_ENDSEQ 4
+#define SEL_GOOGLE_PROTOBUF_METHODOPTIONS_UNINTERPRETED_OPTION_ENDSUBMSG 5
+
+/* google.protobuf.ServiceDescriptorProto */
+#define SEL_GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_METHOD_STARTSUBMSG 2
+#define SEL_GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_OPTIONS_STARTSUBMSG 3
+#define SEL_GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_METHOD_STARTSEQ 4
+#define SEL_GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_METHOD_ENDSEQ 5
+#define SEL_GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_METHOD_ENDSUBMSG 6
+#define SEL_GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_OPTIONS_ENDSUBMSG 7
+#define SEL_GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_NAME_STRING 8
+#define SEL_GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_NAME_STARTSTR 9
+#define SEL_GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_NAME_ENDSTR 10
+
+/* google.protobuf.ServiceOptions */
+#define SEL_GOOGLE_PROTOBUF_SERVICEOPTIONS_UNINTERPRETED_OPTION_STARTSUBMSG 2
+#define SEL_GOOGLE_PROTOBUF_SERVICEOPTIONS_UNINTERPRETED_OPTION_STARTSEQ 3
+#define SEL_GOOGLE_PROTOBUF_SERVICEOPTIONS_UNINTERPRETED_OPTION_ENDSEQ 4
+#define SEL_GOOGLE_PROTOBUF_SERVICEOPTIONS_UNINTERPRETED_OPTION_ENDSUBMSG 5
+
+/* google.protobuf.SourceCodeInfo */
+#define SEL_GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_STARTSUBMSG 2
+#define SEL_GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_STARTSEQ 3
+#define SEL_GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_ENDSEQ 4
+#define SEL_GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_ENDSUBMSG 5
+
+/* google.protobuf.SourceCodeInfo.Location */
+#define SEL_GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_PATH_STARTSEQ 2
+#define SEL_GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_PATH_ENDSEQ 3
+#define SEL_GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_PATH_INT32 4
+#define SEL_GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_SPAN_STARTSEQ 5
+#define SEL_GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_SPAN_ENDSEQ 6
+#define SEL_GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_SPAN_INT32 7
+#define SEL_GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_LEADING_COMMENTS_STRING 8
+#define SEL_GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_LEADING_COMMENTS_STARTSTR 9
+#define SEL_GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_LEADING_COMMENTS_ENDSTR 10
+#define SEL_GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_TRAILING_COMMENTS_STRING 11
+#define SEL_GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_TRAILING_COMMENTS_STARTSTR 12
+#define SEL_GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_TRAILING_COMMENTS_ENDSTR 13
+
+/* google.protobuf.UninterpretedOption */
+#define SEL_GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAME_STARTSUBMSG 2
+#define SEL_GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAME_STARTSEQ 3
+#define SEL_GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAME_ENDSEQ 4
+#define SEL_GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAME_ENDSUBMSG 5
+#define SEL_GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_IDENTIFIER_VALUE_STRING 6
+#define SEL_GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_IDENTIFIER_VALUE_STARTSTR 7
+#define SEL_GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_IDENTIFIER_VALUE_ENDSTR 8
+#define SEL_GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_POSITIVE_INT_VALUE_UINT64 9
+#define SEL_GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NEGATIVE_INT_VALUE_INT64 10
+#define SEL_GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_DOUBLE_VALUE_DOUBLE 11
+#define SEL_GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_STRING_VALUE_STRING 12
+#define SEL_GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_STRING_VALUE_STARTSTR 13
+#define SEL_GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_STRING_VALUE_ENDSTR 14
+#define SEL_GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_AGGREGATE_VALUE_STRING 15
+#define SEL_GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_AGGREGATE_VALUE_STARTSTR 16
+#define SEL_GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_AGGREGATE_VALUE_ENDSTR 17
+
+/* google.protobuf.UninterpretedOption.NamePart */
+#define SEL_GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAMEPART_NAME_PART_STRING 2
+#define SEL_GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAMEPART_NAME_PART_STARTSTR 3
+#define SEL_GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAMEPART_NAME_PART_ENDSTR 4
+#define SEL_GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAMEPART_IS_EXTENSION_BOOL 5
+
+const upb_symtab *upbdefs_google_protobuf_descriptor(const void *owner);
+
+/* MessageDefs */
+UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_DescriptorProto(const upb_symtab *s) {
+ const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.DescriptorProto");
+ assert(m);
+ return m;
+}
+UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_DescriptorProto_ExtensionRange(const upb_symtab *s) {
+ const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.DescriptorProto.ExtensionRange");
+ assert(m);
+ return m;
+}
+UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_EnumDescriptorProto(const upb_symtab *s) {
+ const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.EnumDescriptorProto");
+ assert(m);
+ return m;
+}
+UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_EnumOptions(const upb_symtab *s) {
+ const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.EnumOptions");
+ assert(m);
+ return m;
+}
+UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_EnumValueDescriptorProto(const upb_symtab *s) {
+ const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.EnumValueDescriptorProto");
+ assert(m);
+ return m;
+}
+UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_EnumValueOptions(const upb_symtab *s) {
+ const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.EnumValueOptions");
+ assert(m);
+ return m;
+}
+UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_FieldDescriptorProto(const upb_symtab *s) {
+ const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.FieldDescriptorProto");
+ assert(m);
+ return m;
+}
+UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_FieldOptions(const upb_symtab *s) {
+ const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.FieldOptions");
+ assert(m);
+ return m;
+}
+UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_FileDescriptorProto(const upb_symtab *s) {
+ const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.FileDescriptorProto");
+ assert(m);
+ return m;
+}
+UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_FileDescriptorSet(const upb_symtab *s) {
+ const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.FileDescriptorSet");
+ assert(m);
+ return m;
+}
+UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_FileOptions(const upb_symtab *s) {
+ const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.FileOptions");
+ assert(m);
+ return m;
+}
+UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_MessageOptions(const upb_symtab *s) {
+ const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.MessageOptions");
+ assert(m);
+ return m;
+}
+UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_MethodDescriptorProto(const upb_symtab *s) {
+ const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.MethodDescriptorProto");
+ assert(m);
+ return m;
+}
+UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_MethodOptions(const upb_symtab *s) {
+ const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.MethodOptions");
+ assert(m);
+ return m;
+}
+UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_ServiceDescriptorProto(const upb_symtab *s) {
+ const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.ServiceDescriptorProto");
+ assert(m);
+ return m;
+}
+UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_ServiceOptions(const upb_symtab *s) {
+ const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.ServiceOptions");
+ assert(m);
+ return m;
+}
+UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_SourceCodeInfo(const upb_symtab *s) {
+ const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.SourceCodeInfo");
+ assert(m);
+ return m;
+}
+UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_SourceCodeInfo_Location(const upb_symtab *s) {
+ const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.SourceCodeInfo.Location");
+ assert(m);
+ return m;
+}
+UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_UninterpretedOption(const upb_symtab *s) {
+ const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.UninterpretedOption");
+ assert(m);
+ return m;
+}
+UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_UninterpretedOption_NamePart(const upb_symtab *s) {
+ const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.UninterpretedOption.NamePart");
+ assert(m);
+ return m;
+}
+
+
+/* EnumDefs */
+UPB_INLINE const upb_enumdef *upbdefs_google_protobuf_FieldDescriptorProto_Label(const upb_symtab *s) {
+ const upb_enumdef *e = upb_symtab_lookupenum(s, "google.protobuf.FieldDescriptorProto.Label");
+ assert(e);
+ return e;
+}
+UPB_INLINE const upb_enumdef *upbdefs_google_protobuf_FieldDescriptorProto_Type(const upb_symtab *s) {
+ const upb_enumdef *e = upb_symtab_lookupenum(s, "google.protobuf.FieldDescriptorProto.Type");
+ assert(e);
+ return e;
+}
+UPB_INLINE const upb_enumdef *upbdefs_google_protobuf_FieldOptions_CType(const upb_symtab *s) {
+ const upb_enumdef *e = upb_symtab_lookupenum(s, "google.protobuf.FieldOptions.CType");
+ assert(e);
+ return e;
+}
+UPB_INLINE const upb_enumdef *upbdefs_google_protobuf_FileOptions_OptimizeMode(const upb_symtab *s) {
+ const upb_enumdef *e = upb_symtab_lookupenum(s, "google.protobuf.FileOptions.OptimizeMode");
+ assert(e);
+ return e;
+}
+
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_DescriptorProto_ExtensionRange_end(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_DescriptorProto_ExtensionRange(s), 2); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_DescriptorProto_ExtensionRange_start(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_DescriptorProto_ExtensionRange(s), 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_DescriptorProto_enum_type(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_DescriptorProto(s), 4); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_DescriptorProto_extension(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_DescriptorProto(s), 6); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_DescriptorProto_extension_range(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_DescriptorProto(s), 5); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_DescriptorProto_field(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_DescriptorProto(s), 2); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_DescriptorProto_name(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_DescriptorProto(s), 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_DescriptorProto_nested_type(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_DescriptorProto(s), 3); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_DescriptorProto_options(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_DescriptorProto(s), 7); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_EnumDescriptorProto_name(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_EnumDescriptorProto(s), 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_EnumDescriptorProto_options(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_EnumDescriptorProto(s), 3); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_EnumDescriptorProto_value(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_EnumDescriptorProto(s), 2); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_EnumOptions_allow_alias(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_EnumOptions(s), 2); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_EnumOptions_uninterpreted_option(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_EnumOptions(s), 999); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_EnumValueDescriptorProto_name(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_EnumValueDescriptorProto(s), 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_EnumValueDescriptorProto_number(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_EnumValueDescriptorProto(s), 2); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_EnumValueDescriptorProto_options(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_EnumValueDescriptorProto(s), 3); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_EnumValueOptions_uninterpreted_option(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_EnumValueOptions(s), 999); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldDescriptorProto_default_value(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FieldDescriptorProto(s), 7); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldDescriptorProto_extendee(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FieldDescriptorProto(s), 2); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldDescriptorProto_label(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FieldDescriptorProto(s), 4); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldDescriptorProto_name(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FieldDescriptorProto(s), 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldDescriptorProto_number(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FieldDescriptorProto(s), 3); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldDescriptorProto_options(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FieldDescriptorProto(s), 8); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldDescriptorProto_type(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FieldDescriptorProto(s), 5); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldDescriptorProto_type_name(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FieldDescriptorProto(s), 6); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldOptions_ctype(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FieldOptions(s), 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldOptions_deprecated(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FieldOptions(s), 3); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldOptions_experimental_map_key(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FieldOptions(s), 9); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldOptions_lazy(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FieldOptions(s), 5); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldOptions_packed(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FieldOptions(s), 2); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldOptions_uninterpreted_option(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FieldOptions(s), 999); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldOptions_weak(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FieldOptions(s), 10); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorProto_dependency(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileDescriptorProto(s), 3); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorProto_enum_type(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileDescriptorProto(s), 5); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorProto_extension(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileDescriptorProto(s), 7); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorProto_message_type(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileDescriptorProto(s), 4); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorProto_name(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileDescriptorProto(s), 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorProto_options(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileDescriptorProto(s), 8); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorProto_package(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileDescriptorProto(s), 2); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorProto_public_dependency(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileDescriptorProto(s), 10); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorProto_service(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileDescriptorProto(s), 6); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorProto_source_code_info(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileDescriptorProto(s), 9); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorProto_weak_dependency(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileDescriptorProto(s), 11); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorSet_file(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileDescriptorSet(s), 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_cc_generic_services(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileOptions(s), 16); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_go_package(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileOptions(s), 11); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_java_generate_equals_and_hash(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileOptions(s), 20); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_java_generic_services(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileOptions(s), 17); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_java_multiple_files(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileOptions(s), 10); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_java_outer_classname(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileOptions(s), 8); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_java_package(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileOptions(s), 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_optimize_for(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileOptions(s), 9); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_py_generic_services(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileOptions(s), 18); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_uninterpreted_option(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileOptions(s), 999); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_MessageOptions_message_set_wire_format(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_MessageOptions(s), 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_MessageOptions_no_standard_descriptor_accessor(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_MessageOptions(s), 2); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_MessageOptions_uninterpreted_option(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_MessageOptions(s), 999); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_MethodDescriptorProto_input_type(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_MethodDescriptorProto(s), 2); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_MethodDescriptorProto_name(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_MethodDescriptorProto(s), 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_MethodDescriptorProto_options(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_MethodDescriptorProto(s), 4); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_MethodDescriptorProto_output_type(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_MethodDescriptorProto(s), 3); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_MethodOptions_uninterpreted_option(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_MethodOptions(s), 999); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_ServiceDescriptorProto_method(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_ServiceDescriptorProto(s), 2); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_ServiceDescriptorProto_name(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_ServiceDescriptorProto(s), 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_ServiceDescriptorProto_options(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_ServiceDescriptorProto(s), 3); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_ServiceOptions_uninterpreted_option(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_ServiceOptions(s), 999); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_SourceCodeInfo_Location_leading_comments(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_SourceCodeInfo_Location(s), 3); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_SourceCodeInfo_Location_path(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_SourceCodeInfo_Location(s), 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_SourceCodeInfo_Location_span(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_SourceCodeInfo_Location(s), 2); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_SourceCodeInfo_Location_trailing_comments(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_SourceCodeInfo_Location(s), 4); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_SourceCodeInfo_location(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_SourceCodeInfo(s), 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_UninterpretedOption_NamePart_is_extension(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_UninterpretedOption_NamePart(s), 2); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_UninterpretedOption_NamePart_name_part(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_UninterpretedOption_NamePart(s), 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_UninterpretedOption_aggregate_value(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_UninterpretedOption(s), 8); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_UninterpretedOption_double_value(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_UninterpretedOption(s), 6); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_UninterpretedOption_identifier_value(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_UninterpretedOption(s), 3); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_UninterpretedOption_name(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_UninterpretedOption(s), 2); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_UninterpretedOption_negative_int_value(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_UninterpretedOption(s), 5); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_UninterpretedOption_positive_int_value(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_UninterpretedOption(s), 4); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_UninterpretedOption_string_value(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_UninterpretedOption(s), 7); }
+
+UPB_END_EXTERN_C
+
+#ifdef __cplusplus
+
+namespace upbdefs {
+namespace google {
+namespace protobuf {
+namespace descriptor {
+inline upb::reffed_ptr<const upb::SymbolTable> SymbolTable() {
+ const upb::SymbolTable* s = upbdefs_google_protobuf_descriptor(&s);
+ return upb::reffed_ptr<const upb::SymbolTable>(s, &s);
+}
+} /* namespace descriptor */
+} /* namespace protobuf */
+} /* namespace google */
+
+#define RETURN_REFFED(type, func) \
+ const type* obj = func(upbdefs::google::protobuf::descriptor::SymbolTable().get()); \
+ return upb::reffed_ptr<const type>(obj);
+
+namespace google {
+namespace protobuf {
+namespace DescriptorProto {
+inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_DescriptorProto) }
+inline upb::reffed_ptr<const upb::FieldDef> enum_type() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_DescriptorProto_enum_type) }
+inline upb::reffed_ptr<const upb::FieldDef> extension() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_DescriptorProto_extension) }
+inline upb::reffed_ptr<const upb::FieldDef> extension_range() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_DescriptorProto_extension_range) }
+inline upb::reffed_ptr<const upb::FieldDef> field() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_DescriptorProto_field) }
+inline upb::reffed_ptr<const upb::FieldDef> name() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_DescriptorProto_name) }
+inline upb::reffed_ptr<const upb::FieldDef> nested_type() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_DescriptorProto_nested_type) }
+inline upb::reffed_ptr<const upb::FieldDef> options() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_DescriptorProto_options) }
+} /* namespace DescriptorProto */
+} /* namespace protobuf */
+} /* namespace google */
+
+namespace google {
+namespace protobuf {
+namespace DescriptorProto {
+namespace ExtensionRange {
+inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_DescriptorProto_ExtensionRange) }
+inline upb::reffed_ptr<const upb::FieldDef> end() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_DescriptorProto_ExtensionRange_end) }
+inline upb::reffed_ptr<const upb::FieldDef> start() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_DescriptorProto_ExtensionRange_start) }
+} /* namespace ExtensionRange */
+} /* namespace DescriptorProto */
+} /* namespace protobuf */
+} /* namespace google */
+
+namespace google {
+namespace protobuf {
+namespace EnumDescriptorProto {
+inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_EnumDescriptorProto) }
+inline upb::reffed_ptr<const upb::FieldDef> name() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_EnumDescriptorProto_name) }
+inline upb::reffed_ptr<const upb::FieldDef> options() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_EnumDescriptorProto_options) }
+inline upb::reffed_ptr<const upb::FieldDef> value() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_EnumDescriptorProto_value) }
+} /* namespace EnumDescriptorProto */
+} /* namespace protobuf */
+} /* namespace google */
+
+namespace google {
+namespace protobuf {
+namespace EnumOptions {
+inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_EnumOptions) }
+inline upb::reffed_ptr<const upb::FieldDef> allow_alias() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_EnumOptions_allow_alias) }
+inline upb::reffed_ptr<const upb::FieldDef> uninterpreted_option() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_EnumOptions_uninterpreted_option) }
+} /* namespace EnumOptions */
+} /* namespace protobuf */
+} /* namespace google */
+
+namespace google {
+namespace protobuf {
+namespace EnumValueDescriptorProto {
+inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_EnumValueDescriptorProto) }
+inline upb::reffed_ptr<const upb::FieldDef> name() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_EnumValueDescriptorProto_name) }
+inline upb::reffed_ptr<const upb::FieldDef> number() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_EnumValueDescriptorProto_number) }
+inline upb::reffed_ptr<const upb::FieldDef> options() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_EnumValueDescriptorProto_options) }
+} /* namespace EnumValueDescriptorProto */
+} /* namespace protobuf */
+} /* namespace google */
+
+namespace google {
+namespace protobuf {
+namespace EnumValueOptions {
+inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_EnumValueOptions) }
+inline upb::reffed_ptr<const upb::FieldDef> uninterpreted_option() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_EnumValueOptions_uninterpreted_option) }
+} /* namespace EnumValueOptions */
+} /* namespace protobuf */
+} /* namespace google */
+
+namespace google {
+namespace protobuf {
+namespace FieldDescriptorProto {
+inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_FieldDescriptorProto) }
+inline upb::reffed_ptr<const upb::FieldDef> default_value() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FieldDescriptorProto_default_value) }
+inline upb::reffed_ptr<const upb::FieldDef> extendee() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FieldDescriptorProto_extendee) }
+inline upb::reffed_ptr<const upb::FieldDef> label() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FieldDescriptorProto_label) }
+inline upb::reffed_ptr<const upb::FieldDef> name() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FieldDescriptorProto_name) }
+inline upb::reffed_ptr<const upb::FieldDef> number() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FieldDescriptorProto_number) }
+inline upb::reffed_ptr<const upb::FieldDef> options() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FieldDescriptorProto_options) }
+inline upb::reffed_ptr<const upb::FieldDef> type() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FieldDescriptorProto_type) }
+inline upb::reffed_ptr<const upb::FieldDef> type_name() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FieldDescriptorProto_type_name) }
+inline upb::reffed_ptr<const upb::EnumDef> Label() { RETURN_REFFED(upb::EnumDef, upbdefs_google_protobuf_FieldDescriptorProto_Label) }
+inline upb::reffed_ptr<const upb::EnumDef> Type() { RETURN_REFFED(upb::EnumDef, upbdefs_google_protobuf_FieldDescriptorProto_Type) }
+} /* namespace FieldDescriptorProto */
+} /* namespace protobuf */
+} /* namespace google */
+
+namespace google {
+namespace protobuf {
+namespace FieldOptions {
+inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_FieldOptions) }
+inline upb::reffed_ptr<const upb::FieldDef> ctype() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FieldOptions_ctype) }
+inline upb::reffed_ptr<const upb::FieldDef> deprecated() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FieldOptions_deprecated) }
+inline upb::reffed_ptr<const upb::FieldDef> experimental_map_key() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FieldOptions_experimental_map_key) }
+inline upb::reffed_ptr<const upb::FieldDef> lazy() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FieldOptions_lazy) }
+inline upb::reffed_ptr<const upb::FieldDef> packed() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FieldOptions_packed) }
+inline upb::reffed_ptr<const upb::FieldDef> uninterpreted_option() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FieldOptions_uninterpreted_option) }
+inline upb::reffed_ptr<const upb::FieldDef> weak() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FieldOptions_weak) }
+inline upb::reffed_ptr<const upb::EnumDef> CType() { RETURN_REFFED(upb::EnumDef, upbdefs_google_protobuf_FieldOptions_CType) }
+} /* namespace FieldOptions */
+} /* namespace protobuf */
+} /* namespace google */
+
+namespace google {
+namespace protobuf {
+namespace FileDescriptorProto {
+inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_FileDescriptorProto) }
+inline upb::reffed_ptr<const upb::FieldDef> dependency() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileDescriptorProto_dependency) }
+inline upb::reffed_ptr<const upb::FieldDef> enum_type() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileDescriptorProto_enum_type) }
+inline upb::reffed_ptr<const upb::FieldDef> extension() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileDescriptorProto_extension) }
+inline upb::reffed_ptr<const upb::FieldDef> message_type() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileDescriptorProto_message_type) }
+inline upb::reffed_ptr<const upb::FieldDef> name() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileDescriptorProto_name) }
+inline upb::reffed_ptr<const upb::FieldDef> options() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileDescriptorProto_options) }
+inline upb::reffed_ptr<const upb::FieldDef> package() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileDescriptorProto_package) }
+inline upb::reffed_ptr<const upb::FieldDef> public_dependency() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileDescriptorProto_public_dependency) }
+inline upb::reffed_ptr<const upb::FieldDef> service() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileDescriptorProto_service) }
+inline upb::reffed_ptr<const upb::FieldDef> source_code_info() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileDescriptorProto_source_code_info) }
+inline upb::reffed_ptr<const upb::FieldDef> weak_dependency() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileDescriptorProto_weak_dependency) }
+} /* namespace FileDescriptorProto */
+} /* namespace protobuf */
+} /* namespace google */
+
+namespace google {
+namespace protobuf {
+namespace FileDescriptorSet {
+inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_FileDescriptorSet) }
+inline upb::reffed_ptr<const upb::FieldDef> file() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileDescriptorSet_file) }
+} /* namespace FileDescriptorSet */
+} /* namespace protobuf */
+} /* namespace google */
+
+namespace google {
+namespace protobuf {
+namespace FileOptions {
+inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_FileOptions) }
+inline upb::reffed_ptr<const upb::FieldDef> cc_generic_services() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileOptions_cc_generic_services) }
+inline upb::reffed_ptr<const upb::FieldDef> go_package() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileOptions_go_package) }
+inline upb::reffed_ptr<const upb::FieldDef> java_generate_equals_and_hash() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileOptions_java_generate_equals_and_hash) }
+inline upb::reffed_ptr<const upb::FieldDef> java_generic_services() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileOptions_java_generic_services) }
+inline upb::reffed_ptr<const upb::FieldDef> java_multiple_files() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileOptions_java_multiple_files) }
+inline upb::reffed_ptr<const upb::FieldDef> java_outer_classname() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileOptions_java_outer_classname) }
+inline upb::reffed_ptr<const upb::FieldDef> java_package() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileOptions_java_package) }
+inline upb::reffed_ptr<const upb::FieldDef> optimize_for() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileOptions_optimize_for) }
+inline upb::reffed_ptr<const upb::FieldDef> py_generic_services() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileOptions_py_generic_services) }
+inline upb::reffed_ptr<const upb::FieldDef> uninterpreted_option() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileOptions_uninterpreted_option) }
+inline upb::reffed_ptr<const upb::EnumDef> OptimizeMode() { RETURN_REFFED(upb::EnumDef, upbdefs_google_protobuf_FileOptions_OptimizeMode) }
+} /* namespace FileOptions */
+} /* namespace protobuf */
+} /* namespace google */
+
+namespace google {
+namespace protobuf {
+namespace MessageOptions {
+inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_MessageOptions) }
+inline upb::reffed_ptr<const upb::FieldDef> message_set_wire_format() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_MessageOptions_message_set_wire_format) }
+inline upb::reffed_ptr<const upb::FieldDef> no_standard_descriptor_accessor() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_MessageOptions_no_standard_descriptor_accessor) }
+inline upb::reffed_ptr<const upb::FieldDef> uninterpreted_option() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_MessageOptions_uninterpreted_option) }
+} /* namespace MessageOptions */
+} /* namespace protobuf */
+} /* namespace google */
+
+namespace google {
+namespace protobuf {
+namespace MethodDescriptorProto {
+inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_MethodDescriptorProto) }
+inline upb::reffed_ptr<const upb::FieldDef> input_type() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_MethodDescriptorProto_input_type) }
+inline upb::reffed_ptr<const upb::FieldDef> name() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_MethodDescriptorProto_name) }
+inline upb::reffed_ptr<const upb::FieldDef> options() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_MethodDescriptorProto_options) }
+inline upb::reffed_ptr<const upb::FieldDef> output_type() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_MethodDescriptorProto_output_type) }
+} /* namespace MethodDescriptorProto */
+} /* namespace protobuf */
+} /* namespace google */
+
+namespace google {
+namespace protobuf {
+namespace MethodOptions {
+inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_MethodOptions) }
+inline upb::reffed_ptr<const upb::FieldDef> uninterpreted_option() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_MethodOptions_uninterpreted_option) }
+} /* namespace MethodOptions */
+} /* namespace protobuf */
+} /* namespace google */
+
+namespace google {
+namespace protobuf {
+namespace ServiceDescriptorProto {
+inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_ServiceDescriptorProto) }
+inline upb::reffed_ptr<const upb::FieldDef> method() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_ServiceDescriptorProto_method) }
+inline upb::reffed_ptr<const upb::FieldDef> name() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_ServiceDescriptorProto_name) }
+inline upb::reffed_ptr<const upb::FieldDef> options() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_ServiceDescriptorProto_options) }
+} /* namespace ServiceDescriptorProto */
+} /* namespace protobuf */
+} /* namespace google */
+
+namespace google {
+namespace protobuf {
+namespace ServiceOptions {
+inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_ServiceOptions) }
+inline upb::reffed_ptr<const upb::FieldDef> uninterpreted_option() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_ServiceOptions_uninterpreted_option) }
+} /* namespace ServiceOptions */
+} /* namespace protobuf */
+} /* namespace google */
+
+namespace google {
+namespace protobuf {
+namespace SourceCodeInfo {
+inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_SourceCodeInfo) }
+inline upb::reffed_ptr<const upb::FieldDef> location() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_SourceCodeInfo_location) }
+} /* namespace SourceCodeInfo */
+} /* namespace protobuf */
+} /* namespace google */
+
+namespace google {
+namespace protobuf {
+namespace SourceCodeInfo {
+namespace Location {
+inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_SourceCodeInfo_Location) }
+inline upb::reffed_ptr<const upb::FieldDef> leading_comments() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_SourceCodeInfo_Location_leading_comments) }
+inline upb::reffed_ptr<const upb::FieldDef> path() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_SourceCodeInfo_Location_path) }
+inline upb::reffed_ptr<const upb::FieldDef> span() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_SourceCodeInfo_Location_span) }
+inline upb::reffed_ptr<const upb::FieldDef> trailing_comments() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_SourceCodeInfo_Location_trailing_comments) }
+} /* namespace Location */
+} /* namespace SourceCodeInfo */
+} /* namespace protobuf */
+} /* namespace google */
+
+namespace google {
+namespace protobuf {
+namespace UninterpretedOption {
+inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_UninterpretedOption) }
+inline upb::reffed_ptr<const upb::FieldDef> aggregate_value() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_UninterpretedOption_aggregate_value) }
+inline upb::reffed_ptr<const upb::FieldDef> double_value() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_UninterpretedOption_double_value) }
+inline upb::reffed_ptr<const upb::FieldDef> identifier_value() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_UninterpretedOption_identifier_value) }
+inline upb::reffed_ptr<const upb::FieldDef> name() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_UninterpretedOption_name) }
+inline upb::reffed_ptr<const upb::FieldDef> negative_int_value() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_UninterpretedOption_negative_int_value) }
+inline upb::reffed_ptr<const upb::FieldDef> positive_int_value() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_UninterpretedOption_positive_int_value) }
+inline upb::reffed_ptr<const upb::FieldDef> string_value() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_UninterpretedOption_string_value) }
+} /* namespace UninterpretedOption */
+} /* namespace protobuf */
+} /* namespace google */
+
+namespace google {
+namespace protobuf {
+namespace UninterpretedOption {
+namespace NamePart {
+inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_UninterpretedOption_NamePart) }
+inline upb::reffed_ptr<const upb::FieldDef> is_extension() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_UninterpretedOption_NamePart_is_extension) }
+inline upb::reffed_ptr<const upb::FieldDef> name_part() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_UninterpretedOption_NamePart_name_part) }
+} /* namespace NamePart */
+} /* namespace UninterpretedOption */
+} /* namespace protobuf */
+} /* namespace google */
+
+} /* namespace upbdefs */
+
+
+#undef RETURN_REFFED
+#endif /* __cplusplus */
+
+#endif /* GOOGLE_PROTOBUF_DESCRIPTOR_UPB_H_ */
+/*
+** Internal-only definitions for the decoder.
+*/
+
+#ifndef UPB_DECODER_INT_H_
+#define UPB_DECODER_INT_H_
+
+#include <stdlib.h>
+/*
+** upb::pb::Decoder
+**
+** A high performance, streaming, resumable decoder for the binary protobuf
+** format.
+**
+** This interface works the same regardless of what decoder backend is being
+** used. A client of this class does not need to know whether decoding is using
+** a JITted decoder (DynASM, LLVM, etc) or an interpreted decoder. By default,
+** it will always use the fastest available decoder. However, you can call
+** set_allow_jit(false) to disable any JIT decoder that might be available.
+** This is primarily useful for testing purposes.
+*/
+
+#ifndef UPB_DECODER_H_
+#define UPB_DECODER_H_
+
+
+#ifdef __cplusplus
+namespace upb {
+namespace pb {
+class CodeCache;
+class Decoder;
+class DecoderMethod;
+class DecoderMethodOptions;
+} /* namespace pb */
+} /* namespace upb */
+#endif
+
+UPB_DECLARE_TYPE(upb::pb::CodeCache, upb_pbcodecache)
+UPB_DECLARE_TYPE(upb::pb::Decoder, upb_pbdecoder)
+UPB_DECLARE_TYPE(upb::pb::DecoderMethodOptions, upb_pbdecodermethodopts)
+
+UPB_DECLARE_DERIVED_TYPE(upb::pb::DecoderMethod, upb::RefCounted,
+ upb_pbdecodermethod, upb_refcounted)
+
+#ifdef __cplusplus
+
+/* The parameters one uses to construct a DecoderMethod.
+ * TODO(haberman): move allowjit here? Seems more convenient for users.
+ * TODO(haberman): move this to be heap allocated for ABI stability. */
+class upb::pb::DecoderMethodOptions {
+ public:
+ /* Parameter represents the destination handlers that this method will push
+ * to. */
+ explicit DecoderMethodOptions(const Handlers* dest_handlers);
+
+ /* Should the decoder push submessages to lazy handlers for fields that have
+ * them? The caller should set this iff the lazy handlers expect data that is
+ * in protobuf binary format and the caller wishes to lazy parse it. */
+ void set_lazy(bool lazy);
+#else
+struct upb_pbdecodermethodopts {
+#endif
+ const upb_handlers *handlers;
+ bool lazy;
+};
+
+#ifdef __cplusplus
+
+/* Represents the code to parse a protobuf according to a destination
+ * Handlers. */
+class upb::pb::DecoderMethod {
+ public:
+ /* Include base methods from upb::ReferenceCounted. */
+ UPB_REFCOUNTED_CPPMETHODS
+
+ /* The destination handlers that are statically bound to this method.
+ * This method is only capable of outputting to a sink that uses these
+ * handlers. */
+ const Handlers* dest_handlers() const;
+
+ /* The input handlers for this decoder method. */
+ const BytesHandler* input_handler() const;
+
+ /* Whether this method is native. */
+ bool is_native() const;
+
+ /* Convenience method for generating a DecoderMethod without explicitly
+ * creating a CodeCache. */
+ static reffed_ptr<const DecoderMethod> New(const DecoderMethodOptions& opts);
+
+ private:
+ UPB_DISALLOW_POD_OPS(DecoderMethod, upb::pb::DecoderMethod)
+};
+
+#endif
+
+/* Preallocation hint: decoder won't allocate more bytes than this when first
+ * constructed. This hint may be an overestimate for some build configurations.
+ * But if the decoder library is upgraded without recompiling the application,
+ * it may be an underestimate. */
+#define UPB_PB_DECODER_SIZE 4408
+
+#ifdef __cplusplus
+
+/* A Decoder receives binary protobuf data on its input sink and pushes the
+ * decoded data to its output sink. */
+class upb::pb::Decoder {
+ public:
+ /* Constructs a decoder instance for the given method, which must outlive this
+ * decoder. Any errors during parsing will be set on the given status, which
+ * must also outlive this decoder.
+ *
+ * The sink must match the given method. */
+ static Decoder* Create(Environment* env, const DecoderMethod* method,
+ Sink* output);
+
+ /* Returns the DecoderMethod this decoder is parsing from. */
+ const DecoderMethod* method() const;
+
+ /* The sink on which this decoder receives input. */
+ BytesSink* input();
+
+ /* Returns number of bytes successfully parsed.
+ *
+ * This can be useful for determining the stream position where an error
+ * occurred.
+ *
+ * This value may not be up-to-date when called from inside a parsing
+ * callback. */
+ uint64_t BytesParsed() const;
+
+ /* Gets/sets the parsing nexting limit. If the total number of nested
+ * submessages and repeated fields hits this limit, parsing will fail. This
+ * is a resource limit that controls the amount of memory used by the parsing
+ * stack.
+ *
+ * Setting the limit will fail if the parser is currently suspended at a depth
+ * greater than this, or if memory allocation of the stack fails. */
+ size_t max_nesting() const;
+ bool set_max_nesting(size_t max);
+
+ void Reset();
+
+ static const size_t kSize = UPB_PB_DECODER_SIZE;
+
+ private:
+ UPB_DISALLOW_POD_OPS(Decoder, upb::pb::Decoder)
+};
+
+#endif /* __cplusplus */
+
+#ifdef __cplusplus
+
+/* A class for caching protobuf processing code, whether bytecode for the
+ * interpreted decoder or machine code for the JIT.
+ *
+ * This class is not thread-safe.
+ *
+ * TODO(haberman): move this to be heap allocated for ABI stability. */
+class upb::pb::CodeCache {
+ public:
+ CodeCache();
+ ~CodeCache();
+
+ /* Whether the cache is allowed to generate machine code. Defaults to true.
+ * There is no real reason to turn it off except for testing or if you are
+ * having a specific problem with the JIT.
+ *
+ * Note that allow_jit = true does not *guarantee* that the code will be JIT
+ * compiled. If this platform is not supported or the JIT was not compiled
+ * in, the code may still be interpreted. */
+ bool allow_jit() const;
+
+ /* This may only be called when the object is first constructed, and prior to
+ * any code generation, otherwise returns false and does nothing. */
+ bool set_allow_jit(bool allow);
+
+ /* Returns a DecoderMethod that can push data to the given handlers.
+ * If a suitable method already exists, it will be returned from the cache.
+ *
+ * Specifying the destination handlers here allows the DecoderMethod to be
+ * statically bound to the destination handlers if possible, which can allow
+ * more efficient decoding. However the returned method may or may not
+ * actually be statically bound. But in all cases, the returned method can
+ * push data to the given handlers. */
+ const DecoderMethod *GetDecoderMethod(const DecoderMethodOptions& opts);
+
+ /* If/when someone needs to explicitly create a dynamically-bound
+ * DecoderMethod*, we can add a method to get it here. */
+
+ private:
+ UPB_DISALLOW_COPY_AND_ASSIGN(CodeCache)
+#else
+struct upb_pbcodecache {
+#endif
+ bool allow_jit_;
+
+ /* Array of mgroups. */
+ upb_inttable groups;
+};
+
+UPB_BEGIN_EXTERN_C
+
+upb_pbdecoder *upb_pbdecoder_create(upb_env *e,
+ const upb_pbdecodermethod *method,
+ upb_sink *output);
+const upb_pbdecodermethod *upb_pbdecoder_method(const upb_pbdecoder *d);
+upb_bytessink *upb_pbdecoder_input(upb_pbdecoder *d);
+uint64_t upb_pbdecoder_bytesparsed(const upb_pbdecoder *d);
+size_t upb_pbdecoder_maxnesting(const upb_pbdecoder *d);
+bool upb_pbdecoder_setmaxnesting(upb_pbdecoder *d, size_t max);
+void upb_pbdecoder_reset(upb_pbdecoder *d);
+
+void upb_pbdecodermethodopts_init(upb_pbdecodermethodopts *opts,
+ const upb_handlers *h);
+void upb_pbdecodermethodopts_setlazy(upb_pbdecodermethodopts *opts, bool lazy);
+
+
+/* Include refcounted methods like upb_pbdecodermethod_ref(). */
+UPB_REFCOUNTED_CMETHODS(upb_pbdecodermethod, upb_pbdecodermethod_upcast)
+
+const upb_handlers *upb_pbdecodermethod_desthandlers(
+ const upb_pbdecodermethod *m);
+const upb_byteshandler *upb_pbdecodermethod_inputhandler(
+ const upb_pbdecodermethod *m);
+bool upb_pbdecodermethod_isnative(const upb_pbdecodermethod *m);
+const upb_pbdecodermethod *upb_pbdecodermethod_new(
+ const upb_pbdecodermethodopts *opts, const void *owner);
+
+void upb_pbcodecache_init(upb_pbcodecache *c);
+void upb_pbcodecache_uninit(upb_pbcodecache *c);
+bool upb_pbcodecache_allowjit(const upb_pbcodecache *c);
+bool upb_pbcodecache_setallowjit(upb_pbcodecache *c, bool allow);
+const upb_pbdecodermethod *upb_pbcodecache_getdecodermethod(
+ upb_pbcodecache *c, const upb_pbdecodermethodopts *opts);
+
+UPB_END_EXTERN_C
+
+#ifdef __cplusplus
+
+namespace upb {
+
+namespace pb {
+
+/* static */
+inline Decoder* Decoder::Create(Environment* env, const DecoderMethod* m,
+ Sink* sink) {
+ return upb_pbdecoder_create(env, m, sink);
+}
+inline const DecoderMethod* Decoder::method() const {
+ return upb_pbdecoder_method(this);
+}
+inline BytesSink* Decoder::input() {
+ return upb_pbdecoder_input(this);
+}
+inline uint64_t Decoder::BytesParsed() const {
+ return upb_pbdecoder_bytesparsed(this);
+}
+inline size_t Decoder::max_nesting() const {
+ return upb_pbdecoder_maxnesting(this);
+}
+inline bool Decoder::set_max_nesting(size_t max) {
+ return upb_pbdecoder_setmaxnesting(this, max);
+}
+inline void Decoder::Reset() { upb_pbdecoder_reset(this); }
+
+inline DecoderMethodOptions::DecoderMethodOptions(const Handlers* h) {
+ upb_pbdecodermethodopts_init(this, h);
+}
+inline void DecoderMethodOptions::set_lazy(bool lazy) {
+ upb_pbdecodermethodopts_setlazy(this, lazy);
+}
+
+inline const Handlers* DecoderMethod::dest_handlers() const {
+ return upb_pbdecodermethod_desthandlers(this);
+}
+inline const BytesHandler* DecoderMethod::input_handler() const {
+ return upb_pbdecodermethod_inputhandler(this);
+}
+inline bool DecoderMethod::is_native() const {
+ return upb_pbdecodermethod_isnative(this);
+}
+/* static */
+inline reffed_ptr<const DecoderMethod> DecoderMethod::New(
+ const DecoderMethodOptions &opts) {
+ const upb_pbdecodermethod *m = upb_pbdecodermethod_new(&opts, &m);
+ return reffed_ptr<const DecoderMethod>(m, &m);
+}
+
+inline CodeCache::CodeCache() {
+ upb_pbcodecache_init(this);
+}
+inline CodeCache::~CodeCache() {
+ upb_pbcodecache_uninit(this);
+}
+inline bool CodeCache::allow_jit() const {
+ return upb_pbcodecache_allowjit(this);
+}
+inline bool CodeCache::set_allow_jit(bool allow) {
+ return upb_pbcodecache_setallowjit(this, allow);
+}
+inline const DecoderMethod *CodeCache::GetDecoderMethod(
+ const DecoderMethodOptions& opts) {
+ return upb_pbcodecache_getdecodermethod(this, &opts);
+}
+
+} /* namespace pb */
+} /* namespace upb */
+
+#endif /* __cplusplus */
+
+#endif /* UPB_DECODER_H_ */
+
+/* C++ names are not actually used since this type isn't exposed to users. */
+#ifdef __cplusplus
+namespace upb {
+namespace pb {
+class MessageGroup;
+} /* namespace pb */
+} /* namespace upb */
+#endif
+UPB_DECLARE_DERIVED_TYPE(upb::pb::MessageGroup, upb::RefCounted,
+ mgroup, upb_refcounted)
+
+/* Opcode definitions. The canonical meaning of each opcode is its
+ * implementation in the interpreter (the JIT is written to match this).
+ *
+ * All instructions have the opcode in the low byte.
+ * Instruction format for most instructions is:
+ *
+ * +-------------------+--------+
+ * | arg (24) | op (8) |
+ * +-------------------+--------+
+ *
+ * Exceptions are indicated below. A few opcodes are multi-word. */
+typedef enum {
+ /* Opcodes 1-8, 13, 15-18 parse their respective descriptor types.
+ * Arg for all of these is the upb selector for this field. */
+#define T(type) OP_PARSE_ ## type = UPB_DESCRIPTOR_TYPE_ ## type
+ T(DOUBLE), T(FLOAT), T(INT64), T(UINT64), T(INT32), T(FIXED64), T(FIXED32),
+ T(BOOL), T(UINT32), T(SFIXED32), T(SFIXED64), T(SINT32), T(SINT64),
+#undef T
+ OP_STARTMSG = 9, /* No arg. */
+ OP_ENDMSG = 10, /* No arg. */
+ OP_STARTSEQ = 11,
+ OP_ENDSEQ = 12,
+ OP_STARTSUBMSG = 14,
+ OP_ENDSUBMSG = 19,
+ OP_STARTSTR = 20,
+ OP_STRING = 21,
+ OP_ENDSTR = 22,
+
+ OP_PUSHTAGDELIM = 23, /* No arg. */
+ OP_PUSHLENDELIM = 24, /* No arg. */
+ OP_POP = 25, /* No arg. */
+ OP_SETDELIM = 26, /* No arg. */
+ OP_SETBIGGROUPNUM = 27, /* two words:
+ * | unused (24) | opc (8) |
+ * | groupnum (32) | */
+ OP_CHECKDELIM = 28,
+ OP_CALL = 29,
+ OP_RET = 30,
+ OP_BRANCH = 31,
+
+ /* Different opcodes depending on how many bytes expected. */
+ OP_TAG1 = 32, /* | match tag (16) | jump target (8) | opc (8) | */
+ OP_TAG2 = 33, /* | match tag (16) | jump target (8) | opc (8) | */
+ OP_TAGN = 34, /* three words: */
+ /* | unused (16) | jump target(8) | opc (8) | */
+ /* | match tag 1 (32) | */
+ /* | match tag 2 (32) | */
+
+ OP_SETDISPATCH = 35, /* N words: */
+ /* | unused (24) | opc | */
+ /* | upb_inttable* (32 or 64) | */
+
+ OP_DISPATCH = 36, /* No arg. */
+
+ OP_HALT = 37 /* No arg. */
+} opcode;
+
+#define OP_MAX OP_HALT
+
+UPB_INLINE opcode getop(uint32_t instr) { return instr & 0xff; }
+
+/* Method group; represents a set of decoder methods that had their code
+ * emitted together, and must therefore be freed together. Immutable once
+ * created. It is possible we may want to expose this to users at some point.
+ *
+ * Overall ownership of Decoder objects looks like this:
+ *
+ * +----------+
+ * | | <---> DecoderMethod
+ * | method |
+ * CodeCache ---> | group | <---> DecoderMethod
+ * | |
+ * | (mgroup) | <---> DecoderMethod
+ * +----------+
+ */
+struct mgroup {
+ upb_refcounted base;
+
+ /* Maps upb_msgdef/upb_handlers -> upb_pbdecodermethod. We own refs on the
+ * methods. */
+ upb_inttable methods;
+
+ /* When we add the ability to link to previously existing mgroups, we'll
+ * need an array of mgroups we reference here, and own refs on them. */
+
+ /* The bytecode for our methods, if any exists. Owned by us. */
+ uint32_t *bytecode;
+ uint32_t *bytecode_end;
+
+#ifdef UPB_USE_JIT_X64
+ /* JIT-generated machine code, if any. */
+ upb_string_handlerfunc *jit_code;
+ /* The size of the jit_code (required to munmap()). */
+ size_t jit_size;
+ char *debug_info;
+ void *dl;
+#endif
+};
+
+/* The maximum that any submessages can be nested. Matches proto2's limit.
+ * This specifies the size of the decoder's statically-sized array and therefore
+ * setting it high will cause the upb::pb::Decoder object to be larger.
+ *
+ * If necessary we can add a runtime-settable property to Decoder that allow
+ * this to be larger than the compile-time setting, but this would add
+ * complexity, particularly since we would have to decide how/if to give users
+ * the ability to set a custom memory allocation function. */
+#define UPB_DECODER_MAX_NESTING 64
+
+/* Internal-only struct used by the decoder. */
+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
+ * 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;
+
+ /* The absolute stream offset of the end-of-frame delimiter.
+ * Non-delimited frames (groups and non-packed repeated fields) reuse the
+ * delimiter of their parent, even though the frame may not end there.
+ *
+ * NOTE: the JIT stores a slightly different value here for non-top frames.
+ * It stores the value relative to the end of the enclosed message. But the
+ * top frame is still stored the same way, which is important for ensuring
+ * that calls from the JIT into C work correctly. */
+ uint64_t end_ofs;
+ const uint32_t *base;
+
+ /* 0 indicates a length-delimited field.
+ * A positive number indicates a known group.
+ * A negative number indicates an unknown group. */
+ int32_t groupnum;
+ upb_inttable *dispatch; /* Not used by the JIT. */
+} upb_pbdecoder_frame;
+
+struct upb_pbdecodermethod {
+ upb_refcounted base;
+
+ /* While compiling, the base is relative in "ofs", after compiling it is
+ * absolute in "ptr". */
+ union {
+ uint32_t ofs; /* PC offset of method. */
+ void *ptr; /* Pointer to bytecode or machine code for this method. */
+ } code_base;
+
+ /* The decoder method group to which this method belongs. We own a ref.
+ * Owning a ref on the entire group is more coarse-grained than is strictly
+ * necessary; all we truly require is that methods we directly reference
+ * outlive us, while the group could contain many other messages we don't
+ * require. But the group represents the messages that were
+ * allocated+compiled together, so it makes the most sense to free them
+ * together also. */
+ const upb_refcounted *group;
+
+ /* Whether this method is native code or bytecode. */
+ bool is_native_;
+
+ /* The handler one calls to invoke this method. */
+ upb_byteshandler input_handler_;
+
+ /* The destination handlers this method is bound to. We own a ref. */
+ const upb_handlers *dest_handlers_;
+
+ /* Dispatch table -- used by both bytecode decoder and JIT when encountering a
+ * field number that wasn't the one we were expecting to see. See
+ * decoder.int.h for the layout of this table. */
+ upb_inttable dispatch;
+};
+
+struct upb_pbdecoder {
+ upb_env *env;
+
+ /* Our input sink. */
+ upb_bytessink input_;
+
+ /* The decoder method we are parsing with (owned). */
+ const upb_pbdecodermethod *method_;
+
+ size_t call_len;
+ const uint32_t *pc, *last;
+
+ /* Current input buffer and its stream offset. */
+ const char *buf, *ptr, *end, *checkpoint;
+
+ /* End of the delimited region, relative to ptr, NULL if not in this buf. */
+ const char *delim_end;
+
+ /* End of the delimited region, relative to ptr, end if not in this buf. */
+ const char *data_end;
+
+ /* Overall stream offset of "buf." */
+ uint64_t bufstart_ofs;
+
+ /* Buffer for residual bytes not parsed from the previous buffer.
+ * The maximum number of residual bytes we require is 12; a five-byte
+ * unknown tag plus an eight-byte value, less one because the value
+ * is only a partial value. */
+ char residual[12];
+ char *residual_end;
+
+ /* Bytes of data that should be discarded from the input beore we start
+ * parsing again. We set this when we internally determine that we can
+ * safely skip the next N bytes, but this region extends past the current
+ * user buffer. */
+ size_t skip;
+
+ /* Stores the user buffer passed to our decode function. */
+ const char *buf_param;
+ size_t size_param;
+ const upb_bufhandle *handle;
+
+ /* Our internal stack. */
+ upb_pbdecoder_frame *stack, *top, *limit;
+ const uint32_t **callstack;
+ size_t stack_size;
+
+ upb_status *status;
+
+#ifdef UPB_USE_JIT_X64
+ /* Used momentarily by the generated code to store a value while a user
+ * function is called. */
+ uint32_t tmp_len;
+
+ const void *saved_rsp;
+#endif
+};
+
+/* Decoder entry points; used as handlers. */
+void *upb_pbdecoder_startbc(void *closure, const void *pc, size_t size_hint);
+void *upb_pbdecoder_startjit(void *closure, const void *hd, size_t size_hint);
+size_t upb_pbdecoder_decode(void *closure, const void *hd, const char *buf,
+ size_t size, const upb_bufhandle *handle);
+bool upb_pbdecoder_end(void *closure, const void *handler_data);
+
+/* Decoder-internal functions that the JIT calls to handle fallback paths. */
+int32_t upb_pbdecoder_resume(upb_pbdecoder *d, void *p, const char *buf,
+ size_t size, const upb_bufhandle *handle);
+size_t upb_pbdecoder_suspend(upb_pbdecoder *d);
+int32_t upb_pbdecoder_skipunknown(upb_pbdecoder *d, int32_t fieldnum,
+ uint8_t wire_type);
+int32_t upb_pbdecoder_checktag_slow(upb_pbdecoder *d, uint64_t expected);
+int32_t upb_pbdecoder_decode_varint_slow(upb_pbdecoder *d, uint64_t *u64);
+int32_t upb_pbdecoder_decode_f32(upb_pbdecoder *d, uint32_t *u32);
+int32_t upb_pbdecoder_decode_f64(upb_pbdecoder *d, uint64_t *u64);
+void upb_pbdecoder_seterr(upb_pbdecoder *d, const char *msg);
+
+/* Error messages that are shared between the bytecode and JIT decoders. */
+extern const char *kPbDecoderStackOverflow;
+extern const char *kPbDecoderSubmessageTooLong;
+
+/* Access to decoderplan members needed by the decoder. */
+const char *upb_pbdecoder_getopname(unsigned int op);
+
+/* JIT codegen entry point. */
+void upb_pbdecoder_jit(mgroup *group);
+void upb_pbdecoder_freejit(mgroup *group);
+UPB_REFCOUNTED_CMETHODS(mgroup, mgroup_upcast)
+
+/* A special label that means "do field dispatch for this message and branch to
+ * wherever that takes you." */
+#define LABEL_DISPATCH 0
+
+/* A special slot in the dispatch table that stores the epilogue (ENDMSG and/or
+ * RET) for branching to when we find an appropriate ENDGROUP tag. */
+#define DISPATCH_ENDMSG 0
+
+/* It's important to use this invalid wire type instead of 0 (which is a valid
+ * wire type). */
+#define NO_WIRE_TYPE 0xff
+
+/* The dispatch table layout is:
+ * [field number] -> [ 48-bit offset ][ 8-bit wt2 ][ 8-bit wt1 ]
+ *
+ * If wt1 matches, jump to the 48-bit offset. If wt2 matches, lookup
+ * (UPB_MAX_FIELDNUMBER + fieldnum) and jump there.
+ *
+ * We need two wire types because of packed/non-packed compatibility. A
+ * primitive repeated field can use either wire type and be valid. While we
+ * could key the table on fieldnum+wiretype, the table would be 8x sparser.
+ *
+ * Storing two wire types in the primary value allows us to quickly rule out
+ * the second wire type without needing to do a separate lookup (this case is
+ * less common than an unknown field). */
+UPB_INLINE uint64_t upb_pbdecoder_packdispatch(uint64_t ofs, uint8_t wt1,
+ uint8_t wt2) {
+ return (ofs << 16) | (wt2 << 8) | wt1;
+}
+
+UPB_INLINE void upb_pbdecoder_unpackdispatch(uint64_t dispatch, uint64_t *ofs,
+ uint8_t *wt1, uint8_t *wt2) {
+ *wt1 = (uint8_t)dispatch;
+ *wt2 = (uint8_t)(dispatch >> 8);
+ *ofs = dispatch >> 16;
+}
+
+/* All of the functions in decoder.c that return int32_t return values according
+ * to the following scheme:
+ * 1. negative values indicate a return code from the following list.
+ * 2. positive values indicate that error or end of buffer was hit, and
+ * that the decode function should immediately return the given value
+ * (the decoder state has already been suspended and is ready to be
+ * resumed). */
+#define DECODE_OK -1
+#define DECODE_MISMATCH -2 /* Used only from checktag_slow(). */
+#define DECODE_ENDGROUP -3 /* Used only from checkunknown(). */
+
+#define CHECK_RETURN(x) { int32_t ret = x; if (ret >= 0) return ret; }
+
+#endif /* UPB_DECODER_INT_H_ */
+/*
+** A number of routines for varint manipulation (we keep them all around to
+** have multiple approaches available for benchmarking).
+*/
+
+#ifndef UPB_VARINT_DECODER_H_
+#define UPB_VARINT_DECODER_H_
+
+#include <assert.h>
+#include <stdint.h>
+#include <string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* A list of types as they are encoded on-the-wire. */
+typedef enum {
+ UPB_WIRE_TYPE_VARINT = 0,
+ UPB_WIRE_TYPE_64BIT = 1,
+ UPB_WIRE_TYPE_DELIMITED = 2,
+ UPB_WIRE_TYPE_START_GROUP = 3,
+ UPB_WIRE_TYPE_END_GROUP = 4,
+ UPB_WIRE_TYPE_32BIT = 5
+} upb_wiretype_t;
+
+#define UPB_MAX_WIRE_TYPE 5
+
+/* The maximum number of bytes that it takes to encode a 64-bit varint.
+ * Note that with a better encoding this could be 9 (TODO: write up a
+ * wiki document about this). */
+#define UPB_PB_VARINT_MAX_LEN 10
+
+/* Array of the "native" (ie. non-packed-repeated) wire type for the given a
+ * descriptor type (upb_descriptortype_t). */
+extern const uint8_t upb_pb_native_wire_types[];
+
+/* Zig-zag encoding/decoding **************************************************/
+
+UPB_INLINE int32_t upb_zzdec_32(uint32_t n) {
+ return (n >> 1) ^ -(int32_t)(n & 1);
+}
+UPB_INLINE int64_t upb_zzdec_64(uint64_t n) {
+ return (n >> 1) ^ -(int64_t)(n & 1);
+}
+UPB_INLINE uint32_t upb_zzenc_32(int32_t n) { return (n << 1) ^ (n >> 31); }
+UPB_INLINE uint64_t upb_zzenc_64(int64_t n) { return (n << 1) ^ (n >> 63); }
+
+/* Decoding *******************************************************************/
+
+/* All decoding functions return this struct by value. */
+typedef struct {
+ const char *p; /* NULL if the varint was unterminated. */
+ uint64_t val;
+} upb_decoderet;
+
+UPB_INLINE upb_decoderet upb_decoderet_make(const char *p, uint64_t val) {
+ upb_decoderet ret;
+ ret.p = p;
+ ret.val = val;
+ return ret;
+}
+
+/* Four functions for decoding a varint of at most eight bytes. They are all
+ * functionally identical, but are implemented in different ways and likely have
+ * different performance profiles. We keep them around for performance testing.
+ *
+ * Note that these functions may not read byte-by-byte, so they must not be used
+ * unless there are at least eight bytes left in the buffer! */
+upb_decoderet upb_vdecode_max8_branch32(upb_decoderet r);
+upb_decoderet upb_vdecode_max8_branch64(upb_decoderet r);
+upb_decoderet upb_vdecode_max8_wright(upb_decoderet r);
+upb_decoderet upb_vdecode_max8_massimino(upb_decoderet r);
+
+/* Template for a function that checks the first two bytes with branching
+ * and dispatches 2-10 bytes with a separate function. Note that this may read
+ * up to 10 bytes, so it must not be used unless there are at least ten bytes
+ * left in the buffer! */
+#define UPB_VARINT_DECODER_CHECK2(name, decode_max8_function) \
+UPB_INLINE upb_decoderet upb_vdecode_check2_ ## name(const char *_p) { \
+ uint8_t *p = (uint8_t*)_p; \
+ upb_decoderet r; \
+ if ((*p & 0x80) == 0) { \
+ /* Common case: one-byte varint. */ \
+ return upb_decoderet_make(_p + 1, *p & 0x7fU); \
+ } \
+ r = upb_decoderet_make(_p + 2, (*p & 0x7fU) | ((*(p + 1) & 0x7fU) << 7)); \
+ if ((*(p + 1) & 0x80) == 0) { \
+ /* Two-byte varint. */ \
+ return r; \
+ } \
+ /* Longer varint, fallback to out-of-line function. */ \
+ return decode_max8_function(r); \
+}
+
+UPB_VARINT_DECODER_CHECK2(branch32, upb_vdecode_max8_branch32)
+UPB_VARINT_DECODER_CHECK2(branch64, upb_vdecode_max8_branch64)
+UPB_VARINT_DECODER_CHECK2(wright, upb_vdecode_max8_wright)
+UPB_VARINT_DECODER_CHECK2(massimino, upb_vdecode_max8_massimino)
+#undef UPB_VARINT_DECODER_CHECK2
+
+/* Our canonical functions for decoding varints, based on the currently
+ * favored best-performing implementations. */
+UPB_INLINE upb_decoderet upb_vdecode_fast(const char *p) {
+ if (sizeof(long) == 8)
+ return upb_vdecode_check2_branch64(p);
+ else
+ return upb_vdecode_check2_branch32(p);
+}
+
+UPB_INLINE upb_decoderet upb_vdecode_max8_fast(upb_decoderet r) {
+ return upb_vdecode_max8_massimino(r);
+}
+
+
+/* Encoding *******************************************************************/
+
+UPB_INLINE int upb_value_size(uint64_t val) {
+#ifdef __GNUC__
+ int high_bit = 63 - __builtin_clzll(val); /* 0-based, undef if val == 0. */
+#else
+ int high_bit = 0;
+ uint64_t tmp = val;
+ while(tmp >>= 1) high_bit++;
+#endif
+ return val == 0 ? 1 : high_bit / 8 + 1;
+}
+
+/* Encodes a 64-bit varint into buf (which must be >=UPB_PB_VARINT_MAX_LEN
+ * bytes long), returning how many bytes were used.
+ *
+ * TODO: benchmark and optimize if necessary. */
+UPB_INLINE size_t upb_vencode64(uint64_t val, char *buf) {
+ size_t i;
+ if (val == 0) { buf[0] = 0; return 1; }
+ i = 0;
+ while (val) {
+ uint8_t byte = val & 0x7fU;
+ val >>= 7;
+ if (val) byte |= 0x80U;
+ buf[i++] = byte;
+ }
+ return i;
+}
+
+UPB_INLINE size_t upb_varint_size(uint64_t val) {
+ char buf[UPB_PB_VARINT_MAX_LEN];
+ return upb_vencode64(val, buf);
+}
+
+/* Encodes a 32-bit varint, *not* sign-extended. */
+UPB_INLINE uint64_t upb_vencode32(uint32_t val) {
+ char buf[UPB_PB_VARINT_MAX_LEN];
+ size_t bytes = upb_vencode64(val, buf);
+ uint64_t ret = 0;
+ assert(bytes <= 5);
+ memcpy(&ret, buf, bytes);
+ assert(ret <= 0xffffffffffU);
+ return ret;
+}
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* UPB_VARINT_DECODER_H_ */
+/*
+** upb::pb::Encoder (upb_pb_encoder)
+**
+** Implements a set of upb_handlers that write protobuf data to the binary wire
+** format.
+**
+** This encoder implementation does not have any access to any out-of-band or
+** precomputed lengths for submessages, so it must buffer submessages internally
+** before it can emit the first byte.
+*/
+
+#ifndef UPB_ENCODER_H_
+#define UPB_ENCODER_H_
+
+
+#ifdef __cplusplus
+namespace upb {
+namespace pb {
+class Encoder;
+} /* namespace pb */
+} /* namespace upb */
+#endif
+
+UPB_DECLARE_TYPE(upb::pb::Encoder, upb_pb_encoder)
+
+#define UPB_PBENCODER_MAX_NESTING 100
+
+/* upb::pb::Encoder ***********************************************************/
+
+/* Preallocation hint: decoder won't allocate more bytes than this when first
+ * constructed. This hint may be an overestimate for some build configurations.
+ * But if the decoder library is upgraded without recompiling the application,
+ * it may be an underestimate. */
+#define UPB_PB_ENCODER_SIZE 768
+
+#ifdef __cplusplus
+
+class upb::pb::Encoder {
+ public:
+ /* Creates a new encoder in the given environment. The Handlers must have
+ * come from NewHandlers() below. */
+ static Encoder* Create(Environment* env, const Handlers* handlers,
+ BytesSink* output);
+
+ /* The input to the encoder. */
+ Sink* input();
+
+ /* Creates a new set of handlers for this MessageDef. */
+ static reffed_ptr<const Handlers> NewHandlers(const MessageDef* msg);
+
+ static const size_t kSize = UPB_PB_ENCODER_SIZE;
+
+ private:
+ UPB_DISALLOW_POD_OPS(Encoder, upb::pb::Encoder)
+};
+
+#endif
+
+UPB_BEGIN_EXTERN_C
+
+const upb_handlers *upb_pb_encoder_newhandlers(const upb_msgdef *m,
+ const void *owner);
+upb_sink *upb_pb_encoder_input(upb_pb_encoder *p);
+upb_pb_encoder* upb_pb_encoder_create(upb_env* e, const upb_handlers* h,
+ upb_bytessink* output);
+
+UPB_END_EXTERN_C
+
+#ifdef __cplusplus
+
+namespace upb {
+namespace pb {
+inline Encoder* Encoder::Create(Environment* env, const Handlers* handlers,
+ BytesSink* output) {
+ return upb_pb_encoder_create(env, handlers, output);
+}
+inline Sink* Encoder::input() {
+ return upb_pb_encoder_input(this);
+}
+inline reffed_ptr<const Handlers> Encoder::NewHandlers(
+ const upb::MessageDef *md) {
+ const Handlers* h = upb_pb_encoder_newhandlers(md, &h);
+ return reffed_ptr<const Handlers>(h, &h);
+}
+} /* namespace pb */
+} /* namespace upb */
+
+#endif
+
+#endif /* UPB_ENCODER_H_ */
+/*
+** upb's core components like upb_decoder and upb_msg are carefully designed to
+** avoid depending on each other for maximum orthogonality. In other words,
+** you can use a upb_decoder to decode into *any* kind of structure; upb_msg is
+** just one such structure. A upb_msg can be serialized/deserialized into any
+** format, protobuf binary format is just one such format.
+**
+** However, for convenience we provide functions here for doing common
+** operations like deserializing protobuf binary format into a upb_msg. The
+** compromise is that this file drags in almost all of upb as a dependency,
+** which could be undesirable if you're trying to use a trimmed-down build of
+** upb.
+**
+** While these routines are convenient, they do not reuse any encoding/decoding
+** state. For example, if a decoder is JIT-based, it will be re-JITted every
+** time these functions are called. For this reason, if you are parsing lots
+** of data and efficiency is an issue, these may not be the best functions to
+** use (though they are useful for prototyping, before optimizing).
+*/
+
+#ifndef UPB_GLUE_H
+#define UPB_GLUE_H
+
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Loads all defs from the given protobuf binary descriptor, setting default
+ * accessors and a default layout on all messages. The caller owns the
+ * returned array of defs, which will be of length *n. On error NULL is
+ * returned and status is set (if non-NULL). */
+upb_def **upb_load_defs_from_descriptor(const char *str, size_t len, int *n,
+ void *owner, upb_status *status);
+
+/* Like the previous but also adds the loaded defs to the given symtab. */
+bool upb_load_descriptor_into_symtab(upb_symtab *symtab, const char *str,
+ size_t len, upb_status *status);
+
+/* Like the previous but also reads the descriptor from the given filename. */
+bool upb_load_descriptor_file_into_symtab(upb_symtab *symtab, const char *fname,
+ upb_status *status);
+
+/* Reads the given filename into a character string, returning NULL if there
+ * was an error. */
+char *upb_readfile(const char *filename, size_t *len);
+
+#ifdef __cplusplus
+} /* extern "C" */
+
+namespace upb {
+
+/* All routines that load descriptors expect the descriptor to be a
+ * FileDescriptorSet. */
+inline bool LoadDescriptorFileIntoSymtab(SymbolTable* s, const char *fname,
+ Status* status) {
+ return upb_load_descriptor_file_into_symtab(s, fname, status);
+}
+
+inline bool LoadDescriptorIntoSymtab(SymbolTable* s, const char* str,
+ size_t len, Status* status) {
+ return upb_load_descriptor_into_symtab(s, str, len, status);
+}
+
+/* Templated so it can accept both string and std::string. */
+template <typename T>
+bool LoadDescriptorIntoSymtab(SymbolTable* s, const T& desc, Status* status) {
+ return upb_load_descriptor_into_symtab(s, desc.c_str(), desc.size(), status);
+}
+
+} /* namespace upb */
+
+#endif
+
+#endif /* UPB_GLUE_H */
+/*
+** upb::pb::TextPrinter (upb_textprinter)
+**
+** Handlers for writing to protobuf text format.
+*/
+
+#ifndef UPB_TEXT_H_
+#define UPB_TEXT_H_
+
+
+#ifdef __cplusplus
+namespace upb {
+namespace pb {
+class TextPrinter;
+} /* namespace pb */
+} /* namespace upb */
+#endif
+
+UPB_DECLARE_TYPE(upb::pb::TextPrinter, upb_textprinter)
+
+#ifdef __cplusplus
+
+class upb::pb::TextPrinter {
+ public:
+ /* The given handlers must have come from NewHandlers(). It must outlive the
+ * TextPrinter. */
+ static TextPrinter *Create(Environment *env, const upb::Handlers *handlers,
+ BytesSink *output);
+
+ void SetSingleLineMode(bool single_line);
+
+ Sink* input();
+
+ /* If handler caching becomes a requirement we can add a code cache as in
+ * decoder.h */
+ static reffed_ptr<const Handlers> NewHandlers(const MessageDef* md);
+};
+
+#endif
+
+UPB_BEGIN_EXTERN_C
+
+/* C API. */
+upb_textprinter *upb_textprinter_create(upb_env *env, const upb_handlers *h,
+ upb_bytessink *output);
+void upb_textprinter_setsingleline(upb_textprinter *p, bool single_line);
+upb_sink *upb_textprinter_input(upb_textprinter *p);
+
+const upb_handlers *upb_textprinter_newhandlers(const upb_msgdef *m,
+ const void *owner);
+
+UPB_END_EXTERN_C
+
+#ifdef __cplusplus
+
+namespace upb {
+namespace pb {
+inline TextPrinter *TextPrinter::Create(Environment *env,
+ const upb::Handlers *handlers,
+ BytesSink *output) {
+ return upb_textprinter_create(env, handlers, output);
+}
+inline void TextPrinter::SetSingleLineMode(bool single_line) {
+ upb_textprinter_setsingleline(this, single_line);
+}
+inline Sink* TextPrinter::input() {
+ return upb_textprinter_input(this);
+}
+inline reffed_ptr<const Handlers> TextPrinter::NewHandlers(
+ const MessageDef *md) {
+ const Handlers* h = upb_textprinter_newhandlers(md, &h);
+ return reffed_ptr<const Handlers>(h, &h);
+}
+} /* namespace pb */
+} /* namespace upb */
+
+#endif
+
+#endif /* UPB_TEXT_H_ */
+/*
+** upb::json::Parser (upb_json_parser)
+**
+** Parses JSON according to a specific schema.
+** Support for parsing arbitrary JSON (schema-less) will be added later.
+*/
+
+#ifndef UPB_JSON_PARSER_H_
+#define UPB_JSON_PARSER_H_
+
+
+#ifdef __cplusplus
+namespace upb {
+namespace json {
+class Parser;
+} /* namespace json */
+} /* namespace upb */
+#endif
+
+UPB_DECLARE_TYPE(upb::json::Parser, upb_json_parser)
+
+/* upb::json::Parser **********************************************************/
+
+/* Preallocation hint: parser won't allocate more bytes than this when first
+ * constructed. This hint may be an overestimate for some build configurations.
+ * But if the parser library is upgraded without recompiling the application,
+ * it may be an underestimate. */
+#define UPB_JSON_PARSER_SIZE 3704
+
+#ifdef __cplusplus
+
+/* Parses an incoming BytesStream, pushing the results to the destination
+ * sink. */
+class upb::json::Parser {
+ public:
+ static Parser* Create(Environment* env, Sink* output);
+
+ BytesSink* input();
+
+ private:
+ UPB_DISALLOW_POD_OPS(Parser, upb::json::Parser)
+};
+
+#endif
+
+UPB_BEGIN_EXTERN_C
+
+upb_json_parser *upb_json_parser_create(upb_env *e, upb_sink *output);
+upb_bytessink *upb_json_parser_input(upb_json_parser *p);
+
+UPB_END_EXTERN_C
+
+#ifdef __cplusplus
+
+namespace upb {
+namespace json {
+inline Parser* Parser::Create(Environment* env, Sink* output) {
+ return upb_json_parser_create(env, output);
+}
+inline BytesSink* Parser::input() {
+ return upb_json_parser_input(this);
+}
+} /* namespace json */
+} /* namespace upb */
+
+#endif
+
+
+#endif /* UPB_JSON_PARSER_H_ */
+/*
+** upb::json::Printer
+**
+** Handlers that emit JSON according to a specific protobuf schema.
+*/
+
+#ifndef UPB_JSON_TYPED_PRINTER_H_
+#define UPB_JSON_TYPED_PRINTER_H_
+
+
+#ifdef __cplusplus
+namespace upb {
+namespace json {
+class Printer;
+} /* namespace json */
+} /* namespace upb */
+#endif
+
+UPB_DECLARE_TYPE(upb::json::Printer, upb_json_printer)
+
+
+/* upb::json::Printer *********************************************************/
+
+#define UPB_JSON_PRINTER_SIZE 168
+
+#ifdef __cplusplus
+
+/* Prints an incoming stream of data to a BytesSink in JSON format. */
+class upb::json::Printer {
+ public:
+ static Printer* Create(Environment* env, const upb::Handlers* handlers,
+ BytesSink* output);
+
+ /* The input to the printer. */
+ Sink* input();
+
+ /* Returns handlers for printing according to the specified schema. */
+ static reffed_ptr<const Handlers> NewHandlers(const upb::MessageDef* md);
+
+ static const size_t kSize = UPB_JSON_PRINTER_SIZE;
+
+ private:
+ UPB_DISALLOW_POD_OPS(Printer, upb::json::Printer)
+};
+
+#endif
+
+UPB_BEGIN_EXTERN_C
+
+/* Native C API. */
+upb_json_printer *upb_json_printer_create(upb_env *e, const upb_handlers *h,
+ upb_bytessink *output);
+upb_sink *upb_json_printer_input(upb_json_printer *p);
+const upb_handlers *upb_json_printer_newhandlers(const upb_msgdef *md,
+ const void *owner);
+
+UPB_END_EXTERN_C
+
+#ifdef __cplusplus
+
+namespace upb {
+namespace json {
+inline Printer* Printer::Create(Environment* env, const upb::Handlers* handlers,
+ BytesSink* output) {
+ return upb_json_printer_create(env, handlers, output);
+}
+inline Sink* Printer::input() { return upb_json_printer_input(this); }
+inline reffed_ptr<const Handlers> Printer::NewHandlers(
+ const upb::MessageDef *md) {
+ const Handlers* h = upb_json_printer_newhandlers(md, &h);
+ return reffed_ptr<const Handlers>(h, &h);
+}
+} /* namespace json */
+} /* namespace upb */
+
+#endif
+
+#endif /* UPB_JSON_TYPED_PRINTER_H_ */
diff --git a/php/tests/autoload.php b/php/tests/autoload.php
new file mode 100644
index 00000000..af88ba01
--- /dev/null
+++ b/php/tests/autoload.php
@@ -0,0 +1,4 @@
+<?php
+
+require_once('test.pb.php');
+require_once('test_util.php');
diff --git a/post_process_dist.sh b/post_process_dist.sh
index 6d5b85d3..82736bd0 100755
--- a/post_process_dist.sh
+++ b/post_process_dist.sh
@@ -27,7 +27,7 @@ fi
set -ex
-LANGUAGES="cpp csharp java javanano objectivec python ruby"
+LANGUAGES="cpp csharp java javanano js objectivec python ruby"
BASENAME=`basename $1 .tar.gz`
VERSION=${BASENAME:9}
diff --git a/protobuf.bzl b/protobuf.bzl
index bf748db6..c5555fde 100644
--- a/protobuf.bzl
+++ b/protobuf.bzl
@@ -1,22 +1,32 @@
# -*- mode: python; -*- PYTHON-PREPROCESSING-REQUIRED
+def _GetPath(ctx, path):
+ if ctx.label.workspace_root:
+ return ctx.label.workspace_root + '/' + path
+ else:
+ return path
+
def _GenDir(ctx):
if not ctx.attr.includes:
- return ""
+ return ctx.label.workspace_root
if not ctx.attr.includes[0]:
- return ctx.label.package
+ return _GetPath(ctx, ctx.label.package)
if not ctx.label.package:
- return ctx.attr.includes[0]
- return ctx.label.package + '/' + ctx.attr.includes[0]
+ return _GetPath(ctx, ctx.attr.includes[0])
+ return _GetPath(ctx, ctx.label.package + '/' + ctx.attr.includes[0])
-def _CcOuts(srcs):
- return [s[:-len(".proto")] + ".pb.h" for s in srcs] + \
- [s[:-len(".proto")] + ".pb.cc" for s in srcs]
+def _CcOuts(srcs, use_grpc_plugin=False):
+ ret = [s[:-len(".proto")] + ".pb.h" for s in srcs] + \
+ [s[:-len(".proto")] + ".pb.cc" for s in srcs]
+ if use_grpc_plugin:
+ ret += [s[:-len(".proto")] + ".grpc.pb.h" for s in srcs] + \
+ [s[:-len(".proto")] + ".grpc.pb.cc" for s in srcs]
+ return ret
def _PyOuts(srcs):
return [s[:-len(".proto")] + "_pb2.py" for s in srcs]
-def _RelativeOutputPath(path, include):
+def _RelativeOutputPath(path, include, dest=""):
if include == None:
return path
@@ -25,18 +35,11 @@ def _RelativeOutputPath(path, include):
if include and include[-1] != '/':
include = include + '/'
+ if dest and dest[-1] != '/':
+ dest = dest + '/'
path = path[len(include):]
-
- if not path.startswith(PACKAGE_NAME):
- fail("The package %s is not within the path %s" % (PACKAGE_NAME, path))
-
- if not PACKAGE_NAME:
- return path
-
- return path[len(PACKAGE_NAME)+1:]
-
-
+ return dest + path
def _proto_gen_impl(ctx):
"""General implementation for generating protos"""
@@ -45,7 +48,7 @@ def _proto_gen_impl(ctx):
deps += ctx.files.srcs
gen_dir = _GenDir(ctx)
if gen_dir:
- import_flags = ["-I" + gen_dir]
+ import_flags = ["-I" + gen_dir, "-I" + ctx.var["GENDIR"] + "/" + gen_dir]
else:
import_flags = ["-I."]
@@ -59,6 +62,10 @@ def _proto_gen_impl(ctx):
if ctx.attr.gen_py:
args += ["--python_out=" + ctx.var["GENDIR"] + "/" + gen_dir]
+ if ctx.executable.grpc_cpp_plugin:
+ args += ["--plugin=protoc-gen-grpc=" + ctx.executable.grpc_cpp_plugin.path]
+ args += ["--grpc_out=" + ctx.var["GENDIR"] + "/" + gen_dir]
+
if args:
ctx.action(
inputs=srcs + deps,
@@ -86,6 +93,11 @@ _proto_gen = rule(
single_file = True,
mandatory = True,
),
+ "grpc_cpp_plugin": attr.label(
+ cfg = HOST_CFG,
+ executable = True,
+ single_file = True,
+ ),
"gen_cc": attr.bool(),
"gen_py": attr.bool(),
"outs": attr.output_list(),
@@ -100,9 +112,10 @@ def cc_proto_library(
deps=[],
cc_libs=[],
include=None,
- protoc="//google/protobuf:protoc",
+ protoc="//:protoc",
internal_bootstrap_hack=False,
- default_runtime="//google/protobuf:protobuf",
+ use_grpc_plugin=False,
+ default_runtime="//:protobuf",
**kargs):
"""Bazel rule to create a C++ protobuf library from proto source files
@@ -122,6 +135,8 @@ def cc_proto_library(
for bootstraping. When it is set to True, no files will be generated.
The rule will simply be a provider for .proto files, so that other
cc_proto_library can depend on it.
+ use_grpc_plugin: a flag to indicate whether to call the grpc C++ plugin
+ when processing the proto files.
default_runtime: the implicitly default runtime which will be depended on by
the generated cc_library target.
**kargs: other keyword arguments that are passed to cc_library.
@@ -149,13 +164,19 @@ def cc_proto_library(
**kargs)
return
- outs = _CcOuts(srcs)
+ grpc_cpp_plugin = None
+ if use_grpc_plugin:
+ grpc_cpp_plugin = "//external:grpc_cpp_plugin"
+
+ outs = _CcOuts(srcs, use_grpc_plugin)
+
_proto_gen(
name=name + "_genproto",
srcs=srcs,
deps=[s + "_genproto" for s in deps],
includes=includes,
protoc=protoc,
+ grpc_cpp_plugin=grpc_cpp_plugin,
gen_cc=1,
outs=outs,
visibility=["//visibility:public"],
@@ -163,6 +184,8 @@ def cc_proto_library(
if default_runtime and not default_runtime in cc_libs:
cc_libs += [default_runtime]
+ if use_grpc_plugin:
+ cc_libs += ["//external:grpc_lib"]
native.cc_library(
name=name,
@@ -172,34 +195,58 @@ def cc_proto_library(
**kargs)
-def internal_copied_filegroup(
- name,
- srcs,
- include,
- **kargs):
- """Bazel rule to fix sources file to workaround with python path issues.
+def internal_gen_well_known_protos_java(srcs):
+ """Bazel rule to generate the gen_well_known_protos_java genrule
Args:
- name: the name of the internal_copied_filegroup rule, which will be the
- name of the generated filegroup.
- srcs: the source files to be copied.
- include: the expected import root of the source.
- **kargs: extra arguments that will be passed into the filegroup.
+ srcs: the well known protos
"""
- outs = [_RelativeOutputPath(s, include) for s in srcs]
+ root = Label("%s//protobuf_java" % (REPOSITORY_NAME)).workspace_root
+ if root == "":
+ include = " -Isrc "
+ else:
+ include = " -I%s/src " % root
+ native.genrule(
+ name = "gen_well_known_protos_java",
+ srcs = srcs,
+ outs = [
+ "wellknown.srcjar",
+ ],
+ cmd = "$(location :protoc) --java_out=$(@D)/wellknown.jar" +
+ " %s $(SRCS) " % include +
+ " && mv $(@D)/wellknown.jar $(@D)/wellknown.srcjar",
+ tools = [":protoc"],
+ )
+
+
+def internal_copied_filegroup(name, srcs, strip_prefix, dest, **kwargs):
+ """Macro to copy files to a different directory and then create a filegroup.
+
+ This is used by the //:protobuf_python py_proto_library target to work around
+ an issue caused by Python source files that are part of the same Python
+ package being in separate directories.
+
+ Args:
+ srcs: The source files to copy and add to the filegroup.
+ strip_prefix: Path to the root of the files to copy.
+ dest: The directory to copy the source files into.
+ **kwargs: extra arguments that will be passesd to the filegroup.
+ """
+ outs = [_RelativeOutputPath(s, strip_prefix, dest) for s in srcs]
native.genrule(
- name=name+"_genrule",
- srcs=srcs,
- outs=outs,
- cmd=" && ".join(["cp $(location %s) $(location %s)" %
- (s, _RelativeOutputPath(s, include))
- for s in srcs]))
+ name = name + "_genrule",
+ srcs = srcs,
+ outs = outs,
+ cmd = " && ".join(
+ ["cp $(location %s) $(location %s)" %
+ (s, _RelativeOutputPath(s, strip_prefix, dest)) for s in srcs]),
+ )
native.filegroup(
- name=name,
- srcs=outs,
- **kargs)
+ name = name,
+ srcs = outs,
+ **kwargs)
def py_proto_library(
@@ -209,8 +256,8 @@ def py_proto_library(
py_libs=[],
py_extra_srcs=[],
include=None,
- default_runtime="//google/protobuf:protobuf_python",
- protoc="//google/protobuf:protoc",
+ default_runtime="//:protobuf_python",
+ protoc="//:protoc",
**kargs):
"""Bazel rule to create a Python protobuf library from proto source files
@@ -250,15 +297,6 @@ def py_proto_library(
visibility=["//visibility:public"],
)
- if include != None:
- # Copy the output files to the desired location to make the import work.
- internal_copied_filegroup_name=name + "_internal_copied_filegroup"
- internal_copied_filegroup(
- name=internal_copied_filegroup_name,
- srcs=outs,
- include=include)
- outs=[internal_copied_filegroup_name]
-
if default_runtime and not default_runtime in py_libs + deps:
py_libs += [default_runtime]
@@ -266,6 +304,7 @@ def py_proto_library(
name=name,
srcs=outs+py_extra_srcs,
deps=py_libs+deps,
+ imports=includes,
**kargs)
def internal_protobuf_py_tests(
@@ -282,8 +321,7 @@ def internal_protobuf_py_tests(
"""
for m in modules:
- s = _RelativeOutputPath(
- "python/google/protobuf/internal/%s.py" % m, "python")
+ s = "python/google/protobuf/internal/%s.py" % m
native.py_test(
name="py_%s" % m,
srcs=[s],
diff --git a/protoc-artifacts/Dockerfile b/protoc-artifacts/Dockerfile
index fd35b89f..5143b028 100644
--- a/protoc-artifacts/Dockerfile
+++ b/protoc-artifacts/Dockerfile
@@ -21,9 +21,9 @@ ENV JAVA_HOME /var/local/jdk1.8.0_45
ENV PATH $JAVA_HOME/bin:$PATH
# Install Maven
-RUN wget -q http://apache.cs.utah.edu/maven/maven-3/3.3.3/binaries/apache-maven-3.3.3-bin.tar.gz -O - | \
+RUN wget -q http://apache.cs.utah.edu/maven/maven-3/3.3.9/binaries/apache-maven-3.3.9-bin.tar.gz -O - | \
tar xz -C /var/local
-ENV PATH /var/local/apache-maven-3.3.3/bin:$PATH
+ENV PATH /var/local/apache-maven-3.3.9/bin:$PATH
# Install GCC 4.7 to support -static-libstdc++
RUN wget http://people.centos.org/tru/devtools-1.1/devtools-1.1.repo -P /etc/yum.repos.d
diff --git a/protoc-artifacts/README.md b/protoc-artifacts/README.md
index 06091cfe..50629209 100644
--- a/protoc-artifacts/README.md
+++ b/protoc-artifacts/README.md
@@ -22,6 +22,17 @@ The scripts only work under Unix-like environments, e.g., Linux, MacOSX, and
Cygwin or MinGW for Windows. Please see ``README.md`` of the Protobuf project
for how to set up the build environment.
+## Building from a freshly checked-out source
+
+If you just checked out the Protobuf source from github, you need to
+generate the configure script.
+
+Under the protobuf project directory:
+
+```
+$ ./autogen.sh && ./configure && make
+```
+
## To install artifacts locally
The following command will install the ``protoc`` artifact to your local Maven repository.
```
@@ -43,7 +54,7 @@ Frequently used values are:
- ``os.detected.name``: ``linux``, ``osx``, ``windows``.
- ``os.detected.arch``: ``x86_32``, ``x86_64``
-For example, MingGW32 only ships with 32-bit compilers, but you can still build
+For example, MinGW32 only ships with 32-bit compilers, but you can still build
32-bit protoc under 64-bit Windows, with the following command:
```
$ mvn install -Dos.detected.arch=x86_32
@@ -55,14 +66,18 @@ read [this page](http://central.sonatype.org/pages/apache-maven.html) on how to
configure GPG and Sonatype account.
You need to perform the deployment for every platform that you want to
-suppport. DO NOT close the staging repository until you have done the
+support. DO NOT close the staging repository until you have done the
deployment for all platforms. Currently the following platforms are supported:
- Linux (x86_32 and x86_64)
- Windows (x86_32 and x86_64) with
- - Cygwin with MinGW compilers (both x86_32 and x86_64)
- - MSYS with MinGW32 (x86_32 only)
+ - Cygwin64 with MinGW compilers (x86_64)
+ - MSYS with MinGW32 (x86_32)
- MacOSX (x86_32 and x86_64)
+As for MSYS2/MinGW64 for Windows: protoc will build, but it insists on
+adding a dependency of `libwinpthread-1.dll`, which isn't shipped with
+Windows.
+
Use the following command to deploy artifacts for the host platform to a
staging repository.
```
@@ -87,6 +102,25 @@ When you have done deployment for all platforms, go to
https://oss.sonatype.org/#stagingRepositories, verify that the staging
repository has all the binaries, close and release this repository.
+## Upload zip packages to github release page.
+After uploading protoc artifacts to Maven Central repository, run the
+build-zip.sh script to bulid zip packages for these protoc binaries
+and upload these zip packages to the download section of the github
+release. For example:
+```
+$ ./build-zip.sh 3.0.0-beta-4
+```
+The above command will create 5 zip files:
+```
+dist/protoc-3.0.0-beta-4-win32.zip
+dist/protoc-3.0.0-beta-4-osx-x86_32.zip
+dist/protoc-3.0.0-beta-4-osx-x86_64.zip
+dist/protoc-3.0.0-beta-4-linux-x86_32.zip
+dist/protoc-3.0.0-beta-4-linux-x86_64.zip
+```
+Before running the script, make sure the artifacts are accessible from:
+http://repo1.maven.org/maven2/com/google/protobuf/protoc/
+
### Tips for deploying on Linux
We build on Centos 6.6 to provide a good compatibility for not very new
systems. We have provided a ``Dockerfile`` under this directory to build the
@@ -113,7 +147,7 @@ stored:
<settings>
<servers>
<server>
- <id>ossrh</id>
+ <id>sonatype-nexus-staging</id>
<username>[username]</username>
<password>[password]</password>
</server>
@@ -134,7 +168,7 @@ stored:
```
### Tested build environments
-We have succesfully built artifacts on the following environments:
+We have successfully built artifacts on the following environments:
- Linux x86_32 and x86_64:
- Centos 6.6 (within Docker 1.6.1)
- Ubuntu 14.04.2 64-bit
diff --git a/protoc-artifacts/build-protoc.sh b/protoc-artifacts/build-protoc.sh
index 2f67c508..e31948e9 100755
--- a/protoc-artifacts/build-protoc.sh
+++ b/protoc-artifacts/build-protoc.sh
@@ -1,17 +1,30 @@
#!/bin/bash
-# Builds protoc executable into target/protoc.exe
+# Builds protoc executable into target/protoc.exe; optionally build protoc
+# plugins into target/protoc-gen-*.exe
# To be run from Maven.
-# Usage: build-protoc.sh <OS> <ARCH>
+# Usage: build-protoc.sh <OS> <ARCH> <TARGET>
# <OS> and <ARCH> are ${os.detected.name} and ${os.detected.arch} from os-maven-plugin
+# <TARGET> can be "protoc" or "protoc-gen-javalite"
OS=$1
ARCH=$2
+MAKE_TARGET=$3
-if [[ $# < 2 ]]; then
+if [[ $# < 3 ]]; then
echo "No arguments provided. This script is intended to be run from Maven."
exit 1
fi
+case $MAKE_TARGET in
+ protoc-gen-javalite)
+ ;;
+ protoc)
+ ;;
+ *)
+ echo "Target ""$TARGET"" invalid."
+ exit 1
+esac
+
# Under Cygwin, bash doesn't have these in PATH when called from Maven which
# runs in Windows version of Java.
export PATH="/bin:/usr/bin:$PATH"
@@ -126,7 +139,7 @@ checkDependencies ()
}
############################################################################
-echo "Building protoc, OS=$OS ARCH=$ARCH"
+echo "Building protoc, OS=$OS ARCH=$ARCH TARGET=$TARGET"
# Nested double quotes are unintuitive, but it works.
cd "$(dirname "$0")"
@@ -134,7 +147,7 @@ cd "$(dirname "$0")"
WORKING_DIR=$(pwd)
CONFIGURE_ARGS="--disable-shared"
-MAKE_TARGET="protoc"
+TARGET_FILE=target/$MAKE_TARGET.exe
if [[ "$OS" == windows ]]; then
MAKE_TARGET="${MAKE_TARGET}.exe"
fi
@@ -209,12 +222,10 @@ fi
export CXXFLAGS LDFLAGS
-TARGET_FILE=target/protoc.exe
-
cd "$WORKING_DIR"/.. && ./configure $CONFIGURE_ARGS &&
- cd src && make clean && make google/protobuf/stubs/pbconfig.h $MAKE_TARGET &&
+ cd src && make clean && make $MAKE_TARGET &&
cd "$WORKING_DIR" && mkdir -p target &&
- (cp ../src/protoc $TARGET_FILE || cp ../src/protoc.exe $TARGET_FILE) ||
+ cp ../src/$MAKE_TARGET $TARGET_FILE ||
exit 1
if [[ "$OS" == osx ]]; then
diff --git a/protoc-artifacts/build-zip.sh b/protoc-artifacts/build-zip.sh
new file mode 100755
index 00000000..3c5e887b
--- /dev/null
+++ b/protoc-artifacts/build-zip.sh
@@ -0,0 +1,108 @@
+#!/bin/bash
+
+if [ $# -ne 2 ]; then
+ cat <<EOF
+Usage: $0 <TARGET> <VERSION_NUMBER>
+
+TARGET: protoc | protoc-gen-javalite
+
+Example:
+ $ $0 protoc 3.0.0
+ $ $0 protoc-gen-javalite 3.0.0
+
+This script will download pre-built protoc or protoc plugin binaries from maven
+repository and create .zip packages suitable to be included in the github
+release page. If the target is protoc, well-known type .proto files will also be
+included. Each invocation will create 5 zip packages:
+ dist/<TARGET>-<VERSION_NUMBER>-win32.zip
+ dist/<TARGET>-<VERSION_NUMBER>-osx-x86_32.zip
+ dist/<TARGET>-<VERSION_NUMBER>-osx-x86_64.zip
+ dist/<TARGET>-<VERSION_NUMBER>-linux-x86_32.zip
+ dist/<TARGET>-<VERSION_NUMBER>-linux-x86_64.zip
+EOF
+ exit 1
+fi
+
+TARGET=$1
+VERSION_NUMBER=$2
+
+# <zip file name> <binary file name> pairs.
+declare -a FILE_NAMES=( \
+ win32.zip windows-x86_32.exe \
+ osx-x86_32.zip osx-x86_32.exe \
+ osx-x86_64.zip osx-x86_64.exe \
+ linux-x86_32.zip linux-x86_32.exe \
+ linux-x86_64.zip linux-x86_64.exe \
+)
+
+# List of all well-known types to be included.
+declare -a WELL_KNOWN_TYPES=( \
+ google/protobuf/descriptor.proto \
+ 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 \
+ google/protobuf/struct.proto \
+ google/protobuf/timestamp.proto \
+ google/protobuf/type.proto \
+ google/protobuf/wrappers.proto \
+ google/protobuf/compiler/plugin.proto \
+)
+
+set -e
+
+# A temporary working directory to put all files.
+DIR=$(mktemp -d)
+
+# Copy over well-known types.
+mkdir -p ${DIR}/include/google/protobuf/compiler
+for PROTO in ${WELL_KNOWN_TYPES[@]}; do
+ cp -f ../src/${PROTO} ${DIR}/include/${PROTO}
+done
+
+# Create a readme file.
+cat <<EOF > ${DIR}/readme.txt
+Protocol Buffers - Google's data interchange format
+Copyright 2008 Google Inc.
+https://developers.google.com/protocol-buffers/
+
+This package contains a precompiled binary version of the protocol buffer
+compiler (protoc). This binary is intended for users who want to use Protocol
+Buffers in languages other than C++ but do not want to compile protoc
+themselves. To install, simply place this binary somewhere in your PATH.
+
+Please refer to our official github site for more installation instructions:
+ https://github.com/google/protobuf
+EOF
+
+mkdir -p dist
+mkdir -p ${DIR}/bin
+# Create a zip file for each binary.
+for((i=0;i<${#FILE_NAMES[@]};i+=2));do
+ ZIP_NAME=${FILE_NAMES[$i]}
+ if [ ${ZIP_NAME:0:3} = "win" ]; then
+ BINARY="$TARGET.exe"
+ else
+ BINARY="$TARGET"
+ fi
+ BINARY_NAME=${FILE_NAMES[$(($i+1))]}
+ BINARY_URL=http://repo1.maven.org/maven2/com/google/protobuf/$TARGET/${VERSION_NUMBER}/$TARGET-${VERSION_NUMBER}-${BINARY_NAME}
+ if ! wget ${BINARY_URL} -O ${DIR}/bin/$BINARY &> /dev/null; then
+ echo "[ERROR] Failed to download ${BINARY_URL}" >&2
+ echo "[ERROR] Skipped $TARGET-${VERSION_NAME}-${ZIP_NAME}" >&2
+ continue
+ fi
+ TARGET_ZIP_FILE=`pwd`/dist/$TARGET-${VERSION_NUMBER}-${ZIP_NAME}
+ pushd $DIR &> /dev/null
+ chmod +x bin/$BINARY
+ if [ "$TARGET" = "protoc" ]; then
+ zip -r ${TARGET_ZIP_FILE} include bin readme.txt &> /dev/null
+ else
+ zip -r ${TARGET_ZIP_FILE} bin &> /dev/null
+ fi
+ rm bin/$BINARY
+ popd &> /dev/null
+ echo "[INFO] Successfully created ${TARGET_ZIP_FILE}"
+done
diff --git a/protoc-artifacts/pom.xml b/protoc-artifacts/pom.xml
index cdf17707..840bc60a 100644
--- a/protoc-artifacts/pom.xml
+++ b/protoc-artifacts/pom.xml
@@ -10,7 +10,7 @@
</parent>
<groupId>com.google.protobuf</groupId>
<artifactId>protoc</artifactId>
- <version>3.0.0-beta-1</version>
+ <version>3.0.0</version>
<packaging>pom</packaging>
<name>Protobuf Compiler</name>
<description>
@@ -59,6 +59,7 @@
<argument>build-protoc.sh</argument>
<argument>${os.detected.name}</argument>
<argument>${os.detected.arch}</argument>
+ <argument>protoc</argument>
</arguments>
</configuration>
</plugin>
diff --git a/python/README.md b/python/README.md
index 1b5b9dff..57acfd94 100644
--- a/python/README.md
+++ b/python/README.md
@@ -123,13 +123,5 @@ C++ Implementation
The C++ implementation for Python messages is built as a Python extension to
improve the overall protobuf Python performance.
-To use the C++ implementation, you need to:
-1) Install the C++ protobuf runtime library, please see instructions in the
- parent directory.
-2) Export an environment variable:
-
- $ export PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=cpp
-
-You must set this variable at runtime, before running your program, otherwise
-the pure-Python implementation will be used. In a future release, we will
-change the default so that C++ implementation is used whenever it is available.
+To use the C++ implementation, you need to install the C++ protobuf runtime
+library, please see instructions in the parent directory.
diff --git a/python/google/__init__.py b/python/google/__init__.py
index de40ea7c..55856141 100755
--- a/python/google/__init__.py
+++ b/python/google/__init__.py
@@ -1 +1,4 @@
-__import__('pkg_resources').declare_namespace(__name__)
+try:
+ __import__('pkg_resources').declare_namespace(__name__)
+except ImportError:
+ __path__ = __import__('pkgutil').extend_path(__path__, __name__)
diff --git a/python/google/protobuf/__init__.py b/python/google/protobuf/__init__.py
index ed88480f..6210a404 100755
--- a/python/google/protobuf/__init__.py
+++ b/python/google/protobuf/__init__.py
@@ -30,4 +30,10 @@
# Copyright 2007 Google Inc. All Rights Reserved.
-__version__ = '3.0.0a4'
+__version__ = '3.0.0'
+
+if __name__ != '__main__':
+ try:
+ __import__('pkg_resources').declare_namespace(__name__)
+ except ImportError:
+ __path__ = __import__('pkgutil').extend_path(__path__, __name__)
diff --git a/python/google/protobuf/descriptor.py b/python/google/protobuf/descriptor.py
index 2bf36532..873af306 100755
--- a/python/google/protobuf/descriptor.py
+++ b/python/google/protobuf/descriptor.py
@@ -258,7 +258,7 @@ class Descriptor(_NestedDescriptorBase):
def __new__(cls, name, full_name, filename, containing_type, fields,
nested_types, enum_types, extensions, options=None,
is_extendable=True, extension_ranges=None, oneofs=None,
- file=None, serialized_start=None, serialized_end=None,
+ file=None, serialized_start=None, serialized_end=None, # pylint: disable=redefined-builtin
syntax=None):
_message.Message._CheckCalledFromGeneratedFile()
return _message.default_pool.FindMessageTypeByName(full_name)
@@ -269,8 +269,8 @@ class Descriptor(_NestedDescriptorBase):
def __init__(self, name, full_name, filename, containing_type, fields,
nested_types, enum_types, extensions, options=None,
is_extendable=True, extension_ranges=None, oneofs=None,
- file=None, serialized_start=None, serialized_end=None,
- syntax=None): # pylint:disable=redefined-builtin
+ file=None, serialized_start=None, serialized_end=None, # pylint: disable=redefined-builtin
+ syntax=None):
"""Arguments to __init__() are as described in the description
of Descriptor fields above.
@@ -349,7 +349,7 @@ class Descriptor(_NestedDescriptorBase):
Args:
proto: An empty descriptor_pb2.DescriptorProto.
"""
- # This function is overriden to give a better doc comment.
+ # This function is overridden to give a better doc comment.
super(Descriptor, self).CopyToProto(proto)
@@ -626,7 +626,7 @@ class EnumDescriptor(_NestedDescriptorBase):
Args:
proto: An empty descriptor_pb2.EnumDescriptorProto.
"""
- # This function is overriden to give a better doc comment.
+ # This function is overridden to give a better doc comment.
super(EnumDescriptor, self).CopyToProto(proto)
@@ -665,7 +665,7 @@ class EnumValueDescriptor(DescriptorBase):
self.type = type
-class OneofDescriptor(object):
+class OneofDescriptor(DescriptorBase):
"""Descriptor for a oneof field.
name: (str) Name of the oneof field.
@@ -682,12 +682,15 @@ class OneofDescriptor(object):
if _USE_C_DESCRIPTORS:
_C_DESCRIPTOR_CLASS = _message.OneofDescriptor
- def __new__(cls, name, full_name, index, containing_type, fields):
+ def __new__(
+ cls, name, full_name, index, containing_type, fields, options=None):
_message.Message._CheckCalledFromGeneratedFile()
return _message.default_pool.FindOneofByName(full_name)
- def __init__(self, name, full_name, index, containing_type, fields):
+ def __init__(
+ self, name, full_name, index, containing_type, fields, options=None):
"""Arguments are as described in the attribute description above."""
+ super(OneofDescriptor, self).__init__(options, 'OneofOptions')
self.name = name
self.full_name = full_name
self.index = index
@@ -705,11 +708,22 @@ class ServiceDescriptor(_NestedDescriptorBase):
definition appears withing the .proto file.
methods: (list of MethodDescriptor) List of methods provided by this
service.
+ methods_by_name: (dict str -> MethodDescriptor) Same MethodDescriptor
+ objects as in |methods_by_name|, but indexed by "name" attribute in each
+ MethodDescriptor.
options: (descriptor_pb2.ServiceOptions) Service options message or
None to use default service options.
file: (FileDescriptor) Reference to file info.
"""
+ if _USE_C_DESCRIPTORS:
+ _C_DESCRIPTOR_CLASS = _message.ServiceDescriptor
+
+ def __new__(cls, name, full_name, index, methods, options=None, file=None, # pylint: disable=redefined-builtin
+ serialized_start=None, serialized_end=None):
+ _message.Message._CheckCalledFromGeneratedFile() # pylint: disable=protected-access
+ return _message.default_pool.FindServiceByName(full_name)
+
def __init__(self, name, full_name, index, methods, options=None, file=None,
serialized_start=None, serialized_end=None):
super(ServiceDescriptor, self).__init__(
@@ -718,16 +732,14 @@ class ServiceDescriptor(_NestedDescriptorBase):
serialized_end=serialized_end)
self.index = index
self.methods = methods
+ self.methods_by_name = dict((m.name, m) for m in methods)
# Set the containing service for each method in this service.
for method in self.methods:
method.containing_service = self
def FindMethodByName(self, name):
"""Searches for the specified method, and returns its descriptor."""
- for method in self.methods:
- if name == method.name:
- return method
- return None
+ return self.methods_by_name.get(name, None)
def CopyToProto(self, proto):
"""Copies this to a descriptor_pb2.ServiceDescriptorProto.
@@ -735,7 +747,7 @@ class ServiceDescriptor(_NestedDescriptorBase):
Args:
proto: An empty descriptor_pb2.ServiceDescriptorProto.
"""
- # This function is overriden to give a better doc comment.
+ # This function is overridden to give a better doc comment.
super(ServiceDescriptor, self).CopyToProto(proto)
@@ -754,6 +766,14 @@ class MethodDescriptor(DescriptorBase):
None to use default method options.
"""
+ if _USE_C_DESCRIPTORS:
+ _C_DESCRIPTOR_CLASS = _message.MethodDescriptor
+
+ def __new__(cls, name, full_name, index, containing_service,
+ input_type, output_type, options=None):
+ _message.Message._CheckCalledFromGeneratedFile() # pylint: disable=protected-access
+ return _message.default_pool.FindMethodByName(full_name)
+
def __init__(self, name, full_name, index, containing_service,
input_type, output_type, options=None):
"""The arguments are as described in the description of MethodDescriptor
@@ -783,28 +803,41 @@ class FileDescriptor(DescriptorBase):
serialized_pb: (str) Byte string of serialized
descriptor_pb2.FileDescriptorProto.
dependencies: List of other FileDescriptors this FileDescriptor depends on.
+ public_dependencies: A list of FileDescriptors, subset of the dependencies
+ above, which were declared as "public".
message_types_by_name: Dict of message names of their descriptors.
enum_types_by_name: Dict of enum names and their descriptors.
extensions_by_name: Dict of extension names and their descriptors.
+ services_by_name: Dict of services names and their descriptors.
+ pool: the DescriptorPool this descriptor belongs to. When not passed to the
+ constructor, the global default pool is used.
"""
if _USE_C_DESCRIPTORS:
_C_DESCRIPTOR_CLASS = _message.FileDescriptor
def __new__(cls, name, package, options=None, serialized_pb=None,
- dependencies=None, syntax=None):
+ dependencies=None, public_dependencies=None,
+ syntax=None, pool=None):
# FileDescriptor() is called from various places, not only from generated
# files, to register dynamic proto files and messages.
if serialized_pb:
+ # TODO(amauryfa): use the pool passed as argument. This will work only
+ # for C++-implemented DescriptorPools.
return _message.default_pool.AddSerializedFile(serialized_pb)
else:
return super(FileDescriptor, cls).__new__(cls)
def __init__(self, name, package, options=None, serialized_pb=None,
- dependencies=None, syntax=None):
+ dependencies=None, public_dependencies=None,
+ syntax=None, pool=None):
"""Constructor."""
super(FileDescriptor, self).__init__(options, 'FileOptions')
+ if pool is None:
+ from google.protobuf import descriptor_pool
+ pool = descriptor_pool.Default()
+ self.pool = pool
self.message_types_by_name = {}
self.name = name
self.package = package
@@ -813,7 +846,9 @@ class FileDescriptor(DescriptorBase):
self.enum_types_by_name = {}
self.extensions_by_name = {}
+ self.services_by_name = {}
self.dependencies = (dependencies or [])
+ self.public_dependencies = (public_dependencies or [])
if (api_implementation.Type() == 'cpp' and
self.serialized_pb is not None):
diff --git a/python/google/protobuf/descriptor_database.py b/python/google/protobuf/descriptor_database.py
index b10021e9..1333f996 100644
--- a/python/google/protobuf/descriptor_database.py
+++ b/python/google/protobuf/descriptor_database.py
@@ -65,6 +65,7 @@ class DescriptorDatabase(object):
raise DescriptorDatabaseConflictingDefinitionError(
'%s already added, but with different descriptor.' % proto_name)
+ # Add the top-level Message, Enum and Extension descriptors to the index.
package = file_desc_proto.package
for message in file_desc_proto.message_type:
self._file_desc_protos_by_symbol.update(
@@ -72,6 +73,9 @@ class DescriptorDatabase(object):
for enum in file_desc_proto.enum_type:
self._file_desc_protos_by_symbol[
'.'.join((package, enum.name))] = file_desc_proto
+ for extension in file_desc_proto.extension:
+ self._file_desc_protos_by_symbol[
+ '.'.join((package, extension.name))] = file_desc_proto
def FindFileByName(self, name):
"""Finds the file descriptor proto by file name.
diff --git a/python/google/protobuf/descriptor_pool.py b/python/google/protobuf/descriptor_pool.py
index 6a1b4b5e..5c055ab9 100644
--- a/python/google/protobuf/descriptor_pool.py
+++ b/python/google/protobuf/descriptor_pool.py
@@ -83,6 +83,12 @@ def _NormalizeFullyQualifiedName(name):
class DescriptorPool(object):
"""A collection of protobufs dynamically constructed by descriptor protos."""
+ if _USE_C_DESCRIPTORS:
+
+ def __new__(cls, descriptor_db=None):
+ # pylint: disable=protected-access
+ return descriptor._message.DescriptorPool(descriptor_db)
+
def __init__(self, descriptor_db=None):
"""Initializes a Pool of proto buffs.
@@ -264,6 +270,39 @@ class DescriptorPool(object):
self.FindFileContainingSymbol(full_name)
return self._enum_descriptors[full_name]
+ def FindFieldByName(self, full_name):
+ """Loads the named field descriptor from the pool.
+
+ Args:
+ full_name: The full name of the field descriptor to load.
+
+ Returns:
+ The field descriptor for the named field.
+ """
+ full_name = _NormalizeFullyQualifiedName(full_name)
+ message_name, _, field_name = full_name.rpartition('.')
+ message_descriptor = self.FindMessageTypeByName(message_name)
+ return message_descriptor.fields_by_name[field_name]
+
+ def FindExtensionByName(self, full_name):
+ """Loads the named extension descriptor from the pool.
+
+ Args:
+ full_name: The full name of the extension descriptor to load.
+
+ Returns:
+ A FieldDescriptor, describing the named extension.
+ """
+ full_name = _NormalizeFullyQualifiedName(full_name)
+ message_name, _, extension_name = full_name.rpartition('.')
+ try:
+ # Most extensions are nested inside a message.
+ scope = self.FindMessageTypeByName(message_name)
+ except KeyError:
+ # Some extensions are defined at file scope.
+ scope = self.FindFileContainingSymbol(full_name)
+ return scope.extensions_by_name[extension_name]
+
def _ConvertFileProtoToFileDescriptor(self, file_proto):
"""Creates a FileDescriptor from a proto or returns a cached copy.
@@ -280,14 +319,17 @@ class DescriptorPool(object):
if file_proto.name not in self._file_descriptors:
built_deps = list(self._GetDeps(file_proto.dependency))
direct_deps = [self.FindFileByName(n) for n in file_proto.dependency]
+ public_deps = [direct_deps[i] for i in file_proto.public_dependency]
file_descriptor = descriptor.FileDescriptor(
+ pool=self,
name=file_proto.name,
package=file_proto.package,
syntax=file_proto.syntax,
options=file_proto.options,
serialized_pb=file_proto.SerializeToString(),
- dependencies=direct_deps)
+ dependencies=direct_deps,
+ public_dependencies=public_deps)
if _USE_C_DESCRIPTORS:
# When using C++ descriptors, all objects defined in the file were added
# to the C++ database when the FileDescriptor was built above.
@@ -352,6 +394,11 @@ class DescriptorPool(object):
desc_proto_prefix, desc_proto.name, scope)
file_descriptor.message_types_by_name[desc_proto.name] = desc
+ for index, service_proto in enumerate(file_proto.service):
+ file_descriptor.services_by_name[service_proto.name] = (
+ self._MakeServiceDescriptor(service_proto, index, scope,
+ file_proto.package, file_descriptor))
+
self.Add(file_proto)
self._file_descriptors[file_proto.name] = file_descriptor
@@ -399,7 +446,7 @@ class DescriptorPool(object):
for index, extension in enumerate(desc_proto.extension)]
oneofs = [
descriptor.OneofDescriptor(desc.name, '.'.join((desc_name, desc.name)),
- index, None, [])
+ index, None, [], desc.options)
for index, desc in enumerate(desc_proto.oneof_decl)]
extension_ranges = [(r.start, r.end) for r in desc_proto.extension_range]
if extension_ranges:
@@ -598,10 +645,24 @@ class DescriptorPool(object):
field_desc.default_value = text_encoding.CUnescape(
field_proto.default_value)
else:
+ # All other types are of the "int" type.
field_desc.default_value = int(field_proto.default_value)
else:
field_desc.has_default_value = False
- field_desc.default_value = None
+ if (field_proto.type == descriptor.FieldDescriptor.TYPE_DOUBLE or
+ field_proto.type == descriptor.FieldDescriptor.TYPE_FLOAT):
+ field_desc.default_value = 0.0
+ elif field_proto.type == descriptor.FieldDescriptor.TYPE_STRING:
+ field_desc.default_value = u''
+ elif field_proto.type == descriptor.FieldDescriptor.TYPE_BOOL:
+ field_desc.default_value = False
+ elif field_proto.type == descriptor.FieldDescriptor.TYPE_ENUM:
+ field_desc.default_value = field_desc.enum_type.values[0].number
+ elif field_proto.type == descriptor.FieldDescriptor.TYPE_BYTES:
+ field_desc.default_value = b''
+ else:
+ # All other types are of the "int" type.
+ field_desc.default_value = 0
field_desc.type = field_proto.type
@@ -623,6 +684,64 @@ class DescriptorPool(object):
options=value_proto.options,
type=None)
+ def _MakeServiceDescriptor(self, service_proto, service_index, scope,
+ package, file_desc):
+ """Make a protobuf ServiceDescriptor given a ServiceDescriptorProto.
+
+ Args:
+ service_proto: The descriptor_pb2.ServiceDescriptorProto protobuf message.
+ service_index: The index of the service in the File.
+ scope: Dict mapping short and full symbols to message and enum types.
+ package: Optional package name for the new message EnumDescriptor.
+ file_desc: The file containing the service descriptor.
+
+ Returns:
+ The added descriptor.
+ """
+
+ if package:
+ service_name = '.'.join((package, service_proto.name))
+ else:
+ service_name = service_proto.name
+
+ methods = [self._MakeMethodDescriptor(method_proto, service_name, package,
+ scope, index)
+ for index, method_proto in enumerate(service_proto.method)]
+ desc = descriptor.ServiceDescriptor(name=service_proto.name,
+ full_name=service_name,
+ index=service_index,
+ methods=methods,
+ options=service_proto.options,
+ file=file_desc)
+ return desc
+
+ def _MakeMethodDescriptor(self, method_proto, service_name, package, scope,
+ index):
+ """Creates a method descriptor from a MethodDescriptorProto.
+
+ Args:
+ method_proto: The proto describing the method.
+ service_name: The name of the containing service.
+ package: Optional package name to look up for types.
+ scope: Scope containing available types.
+ index: Index of the method in the service.
+
+ Returns:
+ An initialized MethodDescriptor object.
+ """
+ full_name = '.'.join((service_name, method_proto.name))
+ input_type = self._GetTypeFromScope(
+ package, method_proto.input_type, scope)
+ output_type = self._GetTypeFromScope(
+ package, method_proto.output_type, scope)
+ return descriptor.MethodDescriptor(name=method_proto.name,
+ full_name=full_name,
+ index=index,
+ containing_service=None,
+ input_type=input_type,
+ output_type=output_type,
+ options=method_proto.options)
+
def _ExtractSymbols(self, descriptors):
"""Pulls out all the symbols from descriptor protos.
@@ -680,3 +799,16 @@ class DescriptorPool(object):
def _PrefixWithDot(name):
return name if name.startswith('.') else '.%s' % name
+
+
+if _USE_C_DESCRIPTORS:
+ # TODO(amauryfa): This pool could be constructed from Python code, when we
+ # support a flag like 'use_cpp_generated_pool=True'.
+ # pylint: disable=protected-access
+ _DEFAULT = descriptor._message.default_pool
+else:
+ _DEFAULT = DescriptorPool()
+
+
+def Default():
+ return _DEFAULT
diff --git a/python/google/protobuf/internal/_parameterized.py b/python/google/protobuf/internal/_parameterized.py
index dea3f199..23a78f03 100755
--- a/python/google/protobuf/internal/_parameterized.py
+++ b/python/google/protobuf/internal/_parameterized.py
@@ -347,7 +347,7 @@ class TestGeneratorMetaclass(type):
iterable conforms to the test pattern, the injected methods will be picked
up as tests by the unittest framework.
- In general, it is supposed to be used in conjuction with the
+ In general, it is supposed to be used in conjunction with the
Parameters decorator.
"""
diff --git a/python/google/protobuf/internal/any_test.proto b/python/google/protobuf/internal/any_test.proto
new file mode 100644
index 00000000..cd641ca0
--- /dev/null
+++ b/python/google/protobuf/internal/any_test.proto
@@ -0,0 +1,42 @@
+// 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.
+
+// Author: jieluo@google.com (Jie Luo)
+
+syntax = "proto3";
+
+package google.protobuf.internal;
+
+import "google/protobuf/any.proto";
+
+message TestAny {
+ google.protobuf.Any value = 1;
+ int32 int_value = 2;
+}
diff --git a/python/google/protobuf/internal/api_implementation.py b/python/google/protobuf/internal/api_implementation.py
index ffcf7511..460a4a6c 100755
--- a/python/google/protobuf/internal/api_implementation.py
+++ b/python/google/protobuf/internal/api_implementation.py
@@ -32,6 +32,7 @@
"""
import os
+import warnings
import sys
try:
@@ -78,6 +79,11 @@ _implementation_type = os.getenv('PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION',
if _implementation_type != 'python':
_implementation_type = 'cpp'
+if 'PyPy' in sys.version and _implementation_type == 'cpp':
+ warnings.warn('PyPy does not work yet with cpp protocol buffers. '
+ 'Falling back to the python implementation.')
+ _implementation_type = 'python'
+
# This environment variable can be used to switch between the two
# 'cpp' implementations, overriding the compile-time constants in the
# _api_implementation module. Right now only '2' is supported. Any other
diff --git a/python/google/protobuf/internal/containers.py b/python/google/protobuf/internal/containers.py
index 9c8275eb..ce46d08c 100755
--- a/python/google/protobuf/internal/containers.py
+++ b/python/google/protobuf/internal/containers.py
@@ -464,6 +464,9 @@ class ScalarMap(MutableMapping):
return val
def __contains__(self, item):
+ # We check the key's type to match the strong-typing flavor of the API.
+ # Also this makes it easier to match the behavior of the C++ implementation.
+ self._key_checker.CheckValue(item)
return item in self._values
# We need to override this explicitly, because our defaultdict-like behavior
@@ -491,10 +494,20 @@ class ScalarMap(MutableMapping):
def __iter__(self):
return iter(self._values)
+ def __repr__(self):
+ return repr(self._values)
+
def MergeFrom(self, other):
self._values.update(other._values)
self._message_listener.Modified()
+ def InvalidateIterators(self):
+ # It appears that the only way to reliably invalidate iterators to
+ # self._values is to ensure that its size changes.
+ original = self._values
+ self._values = original.copy()
+ original[None] = None
+
# This is defined in the abstract base, but we can do it much more cheaply.
def clear(self):
self._values.clear()
@@ -576,12 +589,26 @@ class MessageMap(MutableMapping):
def __iter__(self):
return iter(self._values)
+ def __repr__(self):
+ return repr(self._values)
+
def MergeFrom(self, other):
for key in other:
- self[key].MergeFrom(other[key])
+ # According to documentation: "When parsing from the wire or when merging,
+ # if there are duplicate map keys the last key seen is used".
+ if key in self:
+ del self[key]
+ self[key].CopyFrom(other[key])
# self._message_listener.Modified() not required here, because
# mutations to submessages already propagate.
+ def InvalidateIterators(self):
+ # It appears that the only way to reliably invalidate iterators to
+ # self._values is to ensure that its size changes.
+ original = self._values
+ self._values = original.copy()
+ original[None] = None
+
# This is defined in the abstract base, but we can do it much more cheaply.
def clear(self):
self._values.clear()
diff --git a/python/google/protobuf/internal/descriptor_database_test.py b/python/google/protobuf/internal/descriptor_database_test.py
index 1baff7d1..5225a458 100644
--- a/python/google/protobuf/internal/descriptor_database_test.py
+++ b/python/google/protobuf/internal/descriptor_database_test.py
@@ -35,9 +35,10 @@
__author__ = 'matthewtoia@google.com (Matt Toia)'
try:
- import unittest2 as unittest
+ import unittest2 as unittest #PY26
except ImportError:
import unittest
+
from google.protobuf import descriptor_pb2
from google.protobuf.internal import factory_test2_pb2
from google.protobuf import descriptor_database
diff --git a/python/google/protobuf/internal/descriptor_pool_test.py b/python/google/protobuf/internal/descriptor_pool_test.py
index da9a78db..3c8c7935 100644
--- a/python/google/protobuf/internal/descriptor_pool_test.py
+++ b/python/google/protobuf/internal/descriptor_pool_test.py
@@ -35,11 +35,15 @@
__author__ = 'matthewtoia@google.com (Matt Toia)'
import os
+import sys
try:
- import unittest2 as unittest
+ import unittest2 as unittest #PY26
except ImportError:
import unittest
+
+from google.protobuf import unittest_import_pb2
+from google.protobuf import unittest_import_public_pb2
from google.protobuf import unittest_pb2
from google.protobuf import descriptor_pb2
from google.protobuf.internal import api_implementation
@@ -47,10 +51,12 @@ from google.protobuf.internal import descriptor_pool_test1_pb2
from google.protobuf.internal import descriptor_pool_test2_pb2
from google.protobuf.internal import factory_test1_pb2
from google.protobuf.internal import factory_test2_pb2
-from google.protobuf.internal import test_util
+from google.protobuf.internal import file_options_test_pb2
+from google.protobuf.internal import more_messages_pb2
from google.protobuf import descriptor
from google.protobuf import descriptor_database
from google.protobuf import descriptor_pool
+from google.protobuf import message_factory
from google.protobuf import symbol_database
@@ -89,7 +95,7 @@ class DescriptorPoolTest(unittest.TestCase):
'google.protobuf.python.internal.Factory1Message')
self.assertIsInstance(file_desc1, descriptor.FileDescriptor)
self.assertEqual('google/protobuf/internal/factory_test1.proto',
- file_desc1.name)
+ file_desc1.name)
self.assertEqual('google.protobuf.python.internal', file_desc1.package)
self.assertIn('Factory1Message', file_desc1.message_types_by_name)
@@ -97,7 +103,7 @@ class DescriptorPoolTest(unittest.TestCase):
'google.protobuf.python.internal.Factory2Message')
self.assertIsInstance(file_desc2, descriptor.FileDescriptor)
self.assertEqual('google/protobuf/internal/factory_test2.proto',
- file_desc2.name)
+ file_desc2.name)
self.assertEqual('google.protobuf.python.internal', file_desc2.package)
self.assertIn('Factory2Message', file_desc2.message_types_by_name)
@@ -111,7 +117,7 @@ class DescriptorPoolTest(unittest.TestCase):
self.assertIsInstance(msg1, descriptor.Descriptor)
self.assertEqual('Factory1Message', msg1.name)
self.assertEqual('google.protobuf.python.internal.Factory1Message',
- msg1.full_name)
+ msg1.full_name)
self.assertEqual(None, msg1.containing_type)
nested_msg1 = msg1.nested_types[0]
@@ -132,7 +138,7 @@ class DescriptorPoolTest(unittest.TestCase):
self.assertIsInstance(msg2, descriptor.Descriptor)
self.assertEqual('Factory2Message', msg2.name)
self.assertEqual('google.protobuf.python.internal.Factory2Message',
- msg2.full_name)
+ msg2.full_name)
self.assertIsNone(msg2.containing_type)
nested_msg2 = msg2.nested_types[0]
@@ -223,6 +229,37 @@ class DescriptorPoolTest(unittest.TestCase):
with self.assertRaises(KeyError):
self.pool.FindEnumTypeByName('Does not exist')
+ def testFindFieldByName(self):
+ field = self.pool.FindFieldByName(
+ 'google.protobuf.python.internal.Factory1Message.list_value')
+ self.assertEqual(field.name, 'list_value')
+ self.assertEqual(field.label, field.LABEL_REPEATED)
+ with self.assertRaises(KeyError):
+ self.pool.FindFieldByName('Does not exist')
+
+ def testFindExtensionByName(self):
+ # An extension defined in a message.
+ extension = self.pool.FindExtensionByName(
+ 'google.protobuf.python.internal.Factory2Message.one_more_field')
+ self.assertEqual(extension.name, 'one_more_field')
+ # An extension defined at file scope.
+ extension = self.pool.FindExtensionByName(
+ 'google.protobuf.python.internal.another_field')
+ self.assertEqual(extension.name, 'another_field')
+ self.assertEqual(extension.number, 1002)
+ with self.assertRaises(KeyError):
+ self.pool.FindFieldByName('Does not exist')
+
+ def testExtensionsAreNotFields(self):
+ with self.assertRaises(KeyError):
+ self.pool.FindFieldByName('google.protobuf.python.internal.another_field')
+ with self.assertRaises(KeyError):
+ self.pool.FindFieldByName(
+ 'google.protobuf.python.internal.Factory2Message.one_more_field')
+ with self.assertRaises(KeyError):
+ self.pool.FindExtensionByName(
+ 'google.protobuf.python.internal.Factory1Message.list_value')
+
def testUserDefinedDB(self):
db = descriptor_database.DescriptorDatabase()
self.pool = descriptor_pool.DescriptorPool(db)
@@ -231,17 +268,19 @@ class DescriptorPoolTest(unittest.TestCase):
self.testFindMessageTypeByName()
def testAddSerializedFile(self):
- db = descriptor_database.DescriptorDatabase()
- self.pool = descriptor_pool.DescriptorPool(db)
+ self.pool = descriptor_pool.DescriptorPool()
self.pool.AddSerializedFile(self.factory_test1_fd.SerializeToString())
self.pool.AddSerializedFile(self.factory_test2_fd.SerializeToString())
self.testFindMessageTypeByName()
def testComplexNesting(self):
+ more_messages_desc = descriptor_pb2.FileDescriptorProto.FromString(
+ more_messages_pb2.DESCRIPTOR.serialized_pb)
test1_desc = descriptor_pb2.FileDescriptorProto.FromString(
descriptor_pool_test1_pb2.DESCRIPTOR.serialized_pb)
test2_desc = descriptor_pb2.FileDescriptorProto.FromString(
descriptor_pool_test2_pb2.DESCRIPTOR.serialized_pb)
+ self.pool.Add(more_messages_desc)
self.pool.Add(test1_desc)
self.pool.Add(test2_desc)
TEST1_FILE.CheckFile(self, self.pool)
@@ -274,14 +313,54 @@ class DescriptorPoolTest(unittest.TestCase):
'google/protobuf/internal/descriptor_pool_test1.proto')
_CheckDefaultValue(file_descriptor)
+ def testDefaultValueForCustomMessages(self):
+ """Check the value returned by non-existent fields."""
+ def _CheckValueAndType(value, expected_value, expected_type):
+ self.assertEqual(value, expected_value)
+ self.assertIsInstance(value, expected_type)
+
+ def _CheckDefaultValues(msg):
+ try:
+ int64 = long
+ except NameError: # Python3
+ int64 = int
+ try:
+ unicode_type = unicode
+ except NameError: # Python3
+ unicode_type = str
+ _CheckValueAndType(msg.optional_int32, 0, int)
+ _CheckValueAndType(msg.optional_uint64, 0, (int64, int))
+ _CheckValueAndType(msg.optional_float, 0, (float, int))
+ _CheckValueAndType(msg.optional_double, 0, (float, int))
+ _CheckValueAndType(msg.optional_bool, False, bool)
+ _CheckValueAndType(msg.optional_string, u'', unicode_type)
+ _CheckValueAndType(msg.optional_bytes, b'', bytes)
+ _CheckValueAndType(msg.optional_nested_enum, msg.FOO, int)
+ # First for the generated message
+ _CheckDefaultValues(unittest_pb2.TestAllTypes())
+ # Then for a message built with from the DescriptorPool.
+ pool = descriptor_pool.DescriptorPool()
+ pool.Add(descriptor_pb2.FileDescriptorProto.FromString(
+ unittest_import_public_pb2.DESCRIPTOR.serialized_pb))
+ pool.Add(descriptor_pb2.FileDescriptorProto.FromString(
+ unittest_import_pb2.DESCRIPTOR.serialized_pb))
+ pool.Add(descriptor_pb2.FileDescriptorProto.FromString(
+ unittest_pb2.DESCRIPTOR.serialized_pb))
+ message_class = message_factory.MessageFactory(pool).GetPrototype(
+ pool.FindMessageTypeByName(
+ unittest_pb2.TestAllTypes.DESCRIPTOR.full_name))
+ _CheckDefaultValues(message_class())
+
class ProtoFile(object):
- def __init__(self, name, package, messages, dependencies=None):
+ def __init__(self, name, package, messages, dependencies=None,
+ public_dependencies=None):
self.name = name
self.package = package
self.messages = messages
self.dependencies = dependencies or []
+ self.public_dependencies = public_dependencies or []
def CheckFile(self, test, pool):
file_desc = pool.FindFileByName(self.name)
@@ -289,6 +368,8 @@ class ProtoFile(object):
test.assertEqual(self.package, file_desc.package)
dependencies_names = [f.name for f in file_desc.dependencies]
test.assertEqual(self.dependencies, dependencies_names)
+ public_dependencies_names = [f.name for f in file_desc.public_dependencies]
+ test.assertEqual(self.public_dependencies, public_dependencies_names)
for name, msg_type in self.messages.items():
msg_type.CheckType(test, None, name, file_desc)
@@ -468,6 +549,8 @@ class AddDescriptorTest(unittest.TestCase):
pool.FindFileContainingSymbol(
prefix + 'protobuf_unittest.TestAllTypes.NestedMessage').name)
+ @unittest.skipIf(api_implementation.Type() == 'cpp',
+ 'With the cpp implementation, Add() must be called first')
def testMessage(self):
self._TestMessage('')
self._TestMessage('.')
@@ -502,10 +585,14 @@ class AddDescriptorTest(unittest.TestCase):
pool.FindFileContainingSymbol(
prefix + 'protobuf_unittest.TestAllTypes.NestedEnum').name)
+ @unittest.skipIf(api_implementation.Type() == 'cpp',
+ 'With the cpp implementation, Add() must be called first')
def testEnum(self):
self._TestEnum('')
self._TestEnum('.')
+ @unittest.skipIf(api_implementation.Type() == 'cpp',
+ 'With the cpp implementation, Add() must be called first')
def testFile(self):
pool = descriptor_pool.DescriptorPool()
pool.AddFileDescriptor(unittest_pb2.DESCRIPTOR)
@@ -520,6 +607,84 @@ class AddDescriptorTest(unittest.TestCase):
pool.FindFileContainingSymbol(
'protobuf_unittest.TestAllTypes')
+ def testEmptyDescriptorPool(self):
+ # Check that an empty DescriptorPool() contains no messages.
+ pool = descriptor_pool.DescriptorPool()
+ proto_file_name = descriptor_pb2.DESCRIPTOR.name
+ self.assertRaises(KeyError, pool.FindFileByName, proto_file_name)
+ # Add the above file to the pool
+ file_descriptor = descriptor_pb2.FileDescriptorProto()
+ descriptor_pb2.DESCRIPTOR.CopyToProto(file_descriptor)
+ pool.Add(file_descriptor)
+ # Now it exists.
+ self.assertTrue(pool.FindFileByName(proto_file_name))
+
+ def testCustomDescriptorPool(self):
+ # Create a new pool, and add a file descriptor.
+ pool = descriptor_pool.DescriptorPool()
+ file_desc = descriptor_pb2.FileDescriptorProto(
+ name='some/file.proto', package='package')
+ file_desc.message_type.add(name='Message')
+ pool.Add(file_desc)
+ self.assertEqual(pool.FindFileByName('some/file.proto').name,
+ 'some/file.proto')
+ self.assertEqual(pool.FindMessageTypeByName('package.Message').name,
+ 'Message')
+
+ def testFileDescriptorOptionsWithCustomDescriptorPool(self):
+ # Create a descriptor pool, and add a new FileDescriptorProto to it.
+ pool = descriptor_pool.DescriptorPool()
+ file_name = 'file_descriptor_options_with_custom_descriptor_pool.proto'
+ file_descriptor_proto = descriptor_pb2.FileDescriptorProto(name=file_name)
+ extension_id = file_options_test_pb2.foo_options
+ file_descriptor_proto.options.Extensions[extension_id].foo_name = 'foo'
+ pool.Add(file_descriptor_proto)
+ # The options set on the FileDescriptorProto should be available in the
+ # descriptor even if they contain extensions that cannot be deserialized
+ # using the pool.
+ file_descriptor = pool.FindFileByName(file_name)
+ options = file_descriptor.GetOptions()
+ self.assertEqual('foo', options.Extensions[extension_id].foo_name)
+ # The object returned by GetOptions() is cached.
+ self.assertIs(options, file_descriptor.GetOptions())
+
+
+@unittest.skipIf(
+ api_implementation.Type() != 'cpp',
+ 'default_pool is only supported by the C++ implementation')
+class DefaultPoolTest(unittest.TestCase):
+
+ def testFindMethods(self):
+ # pylint: disable=g-import-not-at-top
+ from google.protobuf.pyext import _message
+ pool = _message.default_pool
+ self.assertIs(
+ pool.FindFileByName('google/protobuf/unittest.proto'),
+ unittest_pb2.DESCRIPTOR)
+ self.assertIs(
+ pool.FindMessageTypeByName('protobuf_unittest.TestAllTypes'),
+ unittest_pb2.TestAllTypes.DESCRIPTOR)
+ self.assertIs(
+ pool.FindFieldByName('protobuf_unittest.TestAllTypes.optional_int32'),
+ unittest_pb2.TestAllTypes.DESCRIPTOR.fields_by_name['optional_int32'])
+ self.assertIs(
+ pool.FindExtensionByName('protobuf_unittest.optional_int32_extension'),
+ unittest_pb2.DESCRIPTOR.extensions_by_name['optional_int32_extension'])
+ self.assertIs(
+ pool.FindEnumTypeByName('protobuf_unittest.ForeignEnum'),
+ unittest_pb2.ForeignEnum.DESCRIPTOR)
+ self.assertIs(
+ pool.FindOneofByName('protobuf_unittest.TestAllTypes.oneof_field'),
+ unittest_pb2.TestAllTypes.DESCRIPTOR.oneofs_by_name['oneof_field'])
+
+ def testAddFileDescriptor(self):
+ # pylint: disable=g-import-not-at-top
+ from google.protobuf.pyext import _message
+ pool = _message.default_pool
+ file_desc = descriptor_pb2.FileDescriptorProto(name='some/file.proto')
+ pool.Add(file_desc)
+ pool.AddSerializedFile(file_desc.SerializeToString())
+
TEST1_FILE = ProtoFile(
'google/protobuf/internal/descriptor_pool_test1.proto',
@@ -594,7 +759,9 @@ TEST2_FILE = ProtoFile(
ExtensionField(1001, 'DescriptorPoolTest1')),
]),
},
- dependencies=['google/protobuf/internal/descriptor_pool_test1.proto'])
+ dependencies=['google/protobuf/internal/descriptor_pool_test1.proto',
+ 'google/protobuf/internal/more_messages.proto'],
+ public_dependencies=['google/protobuf/internal/more_messages.proto'])
if __name__ == '__main__':
diff --git a/python/google/protobuf/internal/descriptor_pool_test2.proto b/python/google/protobuf/internal/descriptor_pool_test2.proto
index e3fa660c..a218eccb 100644
--- a/python/google/protobuf/internal/descriptor_pool_test2.proto
+++ b/python/google/protobuf/internal/descriptor_pool_test2.proto
@@ -33,6 +33,7 @@ syntax = "proto2";
package google.protobuf.python.internal;
import "google/protobuf/internal/descriptor_pool_test1.proto";
+import public "google/protobuf/internal/more_messages.proto";
message DescriptorPoolTest3 {
diff --git a/python/google/protobuf/internal/descriptor_test.py b/python/google/protobuf/internal/descriptor_test.py
index 99afee63..623198c8 100755
--- a/python/google/protobuf/internal/descriptor_test.py
+++ b/python/google/protobuf/internal/descriptor_test.py
@@ -37,9 +37,10 @@ __author__ = 'robinson@google.com (Will Robinson)'
import sys
try:
- import unittest2 as unittest
+ import unittest2 as unittest #PY26
except ImportError:
import unittest
+
from google.protobuf import unittest_custom_options_pb2
from google.protobuf import unittest_import_pb2
from google.protobuf import unittest_pb2
@@ -47,6 +48,7 @@ from google.protobuf import descriptor_pb2
from google.protobuf.internal import api_implementation
from google.protobuf.internal import test_util
from google.protobuf import descriptor
+from google.protobuf import descriptor_pool
from google.protobuf import symbol_database
from google.protobuf import text_format
@@ -75,27 +77,27 @@ class DescriptorTest(unittest.TestCase):
enum_proto.value.add(name='FOREIGN_BAR', number=5)
enum_proto.value.add(name='FOREIGN_BAZ', number=6)
- descriptor_pool = symbol_database.Default().pool
- descriptor_pool.Add(file_proto)
- self.my_file = descriptor_pool.FindFileByName(file_proto.name)
+ file_proto.message_type.add(name='ResponseMessage')
+ service_proto = file_proto.service.add(
+ name='Service')
+ method_proto = service_proto.method.add(
+ name='CallMethod',
+ input_type='.protobuf_unittest.NestedMessage',
+ output_type='.protobuf_unittest.ResponseMessage')
+
+ # Note: Calling DescriptorPool.Add() multiple times with the same file only
+ # works if the input is canonical; in particular, all type names must be
+ # fully qualified.
+ self.pool = self.GetDescriptorPool()
+ self.pool.Add(file_proto)
+ self.my_file = self.pool.FindFileByName(file_proto.name)
self.my_message = self.my_file.message_types_by_name[message_proto.name]
self.my_enum = self.my_message.enum_types_by_name[enum_proto.name]
+ self.my_service = self.my_file.services_by_name[service_proto.name]
+ self.my_method = self.my_service.methods_by_name[method_proto.name]
- self.my_method = descriptor.MethodDescriptor(
- name='Bar',
- full_name='protobuf_unittest.TestService.Bar',
- index=0,
- containing_service=None,
- input_type=None,
- output_type=None)
- self.my_service = descriptor.ServiceDescriptor(
- name='TestServiceWithOptions',
- full_name='protobuf_unittest.TestServiceWithOptions',
- file=self.my_file,
- index=0,
- methods=[
- self.my_method
- ])
+ def GetDescriptorPool(self):
+ return symbol_database.Default().pool
def testEnumValueName(self):
self.assertEqual(self.my_message.EnumValueName('ForeignEnum', 4),
@@ -134,13 +136,14 @@ class DescriptorTest(unittest.TestCase):
file_descriptor = unittest_custom_options_pb2.DESCRIPTOR
message_descriptor =\
unittest_custom_options_pb2.TestMessageWithCustomOptions.DESCRIPTOR
- field_descriptor = message_descriptor.fields_by_name["field1"]
- enum_descriptor = message_descriptor.enum_types_by_name["AnEnum"]
+ field_descriptor = message_descriptor.fields_by_name['field1']
+ oneof_descriptor = message_descriptor.oneofs_by_name['AnOneof']
+ enum_descriptor = message_descriptor.enum_types_by_name['AnEnum']
enum_value_descriptor =\
- message_descriptor.enum_values_by_name["ANENUM_VAL2"]
+ message_descriptor.enum_values_by_name['ANENUM_VAL2']
service_descriptor =\
unittest_custom_options_pb2.TestServiceWithCustomOptions.DESCRIPTOR
- method_descriptor = service_descriptor.FindMethodByName("Foo")
+ method_descriptor = service_descriptor.FindMethodByName('Foo')
file_options = file_descriptor.GetOptions()
file_opt1 = unittest_custom_options_pb2.file_opt1
@@ -153,6 +156,9 @@ class DescriptorTest(unittest.TestCase):
self.assertEqual(8765432109, field_options.Extensions[field_opt1])
field_opt2 = unittest_custom_options_pb2.field_opt2
self.assertEqual(42, field_options.Extensions[field_opt2])
+ oneof_options = oneof_descriptor.GetOptions()
+ oneof_opt1 = unittest_custom_options_pb2.oneof_opt1
+ self.assertEqual(-99, oneof_options.Extensions[oneof_opt1])
enum_options = enum_descriptor.GetOptions()
enum_opt1 = unittest_custom_options_pb2.enum_opt1
self.assertEqual(-789, enum_options.Extensions[enum_opt1])
@@ -393,6 +399,9 @@ class DescriptorTest(unittest.TestCase):
def testFileDescriptor(self):
self.assertEqual(self.my_file.name, 'some/filename/some.proto')
self.assertEqual(self.my_file.package, 'protobuf_unittest')
+ self.assertEqual(self.my_file.pool, self.pool)
+ # Generated modules also belong to the default pool.
+ self.assertEqual(unittest_pb2.DESCRIPTOR.pool, descriptor_pool.Default())
@unittest.skipIf(
api_implementation.Type() != 'cpp' or api_implementation.Version() != 2,
@@ -407,6 +416,13 @@ class DescriptorTest(unittest.TestCase):
message_descriptor.fields.append(None)
+class NewDescriptorTest(DescriptorTest):
+ """Redo the same tests as above, but with a separate DescriptorPool."""
+
+ def GetDescriptorPool(self):
+ return descriptor_pool.DescriptorPool()
+
+
class GeneratedDescriptorTest(unittest.TestCase):
"""Tests for the properties of descriptors in generated code."""
@@ -582,7 +598,7 @@ class DescriptorCopyToProtoTest(unittest.TestCase):
"""
self._InternalTestCopyToProto(
- unittest_pb2._FOREIGNENUM,
+ unittest_pb2.ForeignEnum.DESCRIPTOR,
descriptor_pb2.EnumDescriptorProto,
TEST_FOREIGN_ENUM_ASCII)
diff --git a/python/google/protobuf/internal/file_options_test.proto b/python/google/protobuf/internal/file_options_test.proto
new file mode 100644
index 00000000..4eceeb07
--- /dev/null
+++ b/python/google/protobuf/internal/file_options_test.proto
@@ -0,0 +1,43 @@
+// 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.
+
+syntax = "proto2";
+
+import "google/protobuf/descriptor.proto";
+
+package google.protobuf.python.internal;
+
+message FooOptions {
+ optional string foo_name = 1;
+}
+
+extend .google.protobuf.FileOptions {
+ optional FooOptions foo_options = 120436268;
+}
diff --git a/python/google/protobuf/internal/generator_test.py b/python/google/protobuf/internal/generator_test.py
index 9956da59..83ea5f50 100755
--- a/python/google/protobuf/internal/generator_test.py
+++ b/python/google/protobuf/internal/generator_test.py
@@ -42,9 +42,10 @@ further ensures that we can use Python protocol message objects as we expect.
__author__ = 'robinson@google.com (Will Robinson)'
try:
- import unittest2 as unittest
+ import unittest2 as unittest #PY26
except ImportError:
import unittest
+
from google.protobuf.internal import test_bad_identifiers_pb2
from google.protobuf import unittest_custom_options_pb2
from google.protobuf import unittest_import_pb2
diff --git a/python/google/protobuf/internal/json_format_test.py b/python/google/protobuf/internal/json_format_test.py
index 69197865..a5ee8ace 100644
--- a/python/google/protobuf/internal/json_format_test.py
+++ b/python/google/protobuf/internal/json_format_test.py
@@ -39,9 +39,17 @@ import math
import sys
try:
- import unittest2 as unittest
+ import unittest2 as unittest #PY26
except ImportError:
import unittest
+
+from google.protobuf import any_pb2
+from google.protobuf import duration_pb2
+from google.protobuf import field_mask_pb2
+from google.protobuf import struct_pb2
+from google.protobuf import timestamp_pb2
+from google.protobuf import wrappers_pb2
+from google.protobuf.internal import well_known_types
from google.protobuf import json_format
from google.protobuf.util import json_format_proto3_pb2
@@ -239,6 +247,23 @@ class JsonFormatTest(JsonFormatBase):
parsed_message = json_format_proto3_pb2.TestOneof()
self.CheckParseBack(message, parsed_message)
+ def testSurrogates(self):
+ # Test correct surrogate handling.
+ message = json_format_proto3_pb2.TestMessage()
+ json_format.Parse('{"stringValue": "\\uD83D\\uDE01"}', message)
+ self.assertEqual(message.string_value,
+ b'\xF0\x9F\x98\x81'.decode('utf-8', 'strict'))
+
+ # Error case: unpaired high surrogate.
+ self.CheckError(
+ '{"stringValue": "\\uD83D"}',
+ r'Invalid \\uXXXX escape|Unpaired.*surrogate')
+
+ # Unpaired low surrogate.
+ self.CheckError(
+ '{"stringValue": "\\uDE01"}',
+ r'Invalid \\uXXXX escape|Unpaired.*surrogate')
+
def testTimestampMessage(self):
message = json_format_proto3_pb2.TestTimestamp()
message.value.seconds = 0
@@ -269,15 +294,15 @@ class JsonFormatTest(JsonFormatBase):
'}'))
parsed_message = json_format_proto3_pb2.TestTimestamp()
self.CheckParseBack(message, parsed_message)
- text = (r'{"value": "1972-01-01T01:00:00.01+08:00",'
+ text = (r'{"value": "1970-01-01T00:00:00.01+08:00",'
r'"repeatedValue":['
- r' "1972-01-01T01:00:00.01+08:30",'
- r' "1972-01-01T01:00:00.01-01:23"]}')
+ r' "1970-01-01T00:00:00.01+08:30",'
+ r' "1970-01-01T00:00:00.01-01:23"]}')
json_format.Parse(text, parsed_message)
- self.assertEqual(parsed_message.value.seconds, 63104400)
+ self.assertEqual(parsed_message.value.seconds, -8 * 3600)
self.assertEqual(parsed_message.value.nanos, 10000000)
- self.assertEqual(parsed_message.repeated_value[0].seconds, 63106200)
- self.assertEqual(parsed_message.repeated_value[1].seconds, 63070620)
+ self.assertEqual(parsed_message.repeated_value[0].seconds, -8.5 * 3600)
+ self.assertEqual(parsed_message.repeated_value[1].seconds, 3600 + 23 * 60)
def testDurationMessage(self):
message = json_format_proto3_pb2.TestDuration()
@@ -325,6 +350,7 @@ class JsonFormatTest(JsonFormatBase):
message.bytes_value.value = b''
message.repeated_bool_value.add().value = True
message.repeated_bool_value.add().value = False
+ message.repeated_int32_value.add()
self.assertEqual(
json.loads(json_format.MessageToJson(message, True)),
json.loads('{\n'
@@ -333,7 +359,7 @@ class JsonFormatTest(JsonFormatBase):
' "stringValue": "",'
' "bytesValue": "",'
' "repeatedBoolValue": [true, false],'
- ' "repeatedInt32Value": [],'
+ ' "repeatedInt32Value": [0],'
' "repeatedUint32Value": [],'
' "repeatedFloatValue": [],'
' "repeatedDoubleValue": [],'
@@ -345,11 +371,208 @@ class JsonFormatTest(JsonFormatBase):
parsed_message = json_format_proto3_pb2.TestWrapper()
self.CheckParseBack(message, parsed_message)
+ def testStructMessage(self):
+ message = json_format_proto3_pb2.TestStruct()
+ message.value['name'] = 'Jim'
+ message.value['age'] = 10
+ message.value['attend'] = True
+ message.value['email'] = None
+ message.value.get_or_create_struct('address')['city'] = 'SFO'
+ message.value['address']['house_number'] = 1024
+ struct_list = message.value.get_or_create_list('list')
+ struct_list.extend([6, 'seven', True, False, None])
+ struct_list.add_struct()['subkey2'] = 9
+ message.repeated_value.add()['age'] = 11
+ message.repeated_value.add()
+ self.assertEqual(
+ json.loads(json_format.MessageToJson(message, False)),
+ json.loads(
+ '{'
+ ' "value": {'
+ ' "address": {'
+ ' "city": "SFO", '
+ ' "house_number": 1024'
+ ' }, '
+ ' "age": 10, '
+ ' "name": "Jim", '
+ ' "attend": true, '
+ ' "email": null, '
+ ' "list": [6, "seven", true, false, null, {"subkey2": 9}]'
+ ' },'
+ ' "repeatedValue": [{"age": 11}, {}]'
+ '}'))
+ parsed_message = json_format_proto3_pb2.TestStruct()
+ self.CheckParseBack(message, parsed_message)
+
+ def testValueMessage(self):
+ message = json_format_proto3_pb2.TestValue()
+ message.value.string_value = 'hello'
+ message.repeated_value.add().number_value = 11.1
+ message.repeated_value.add().bool_value = False
+ message.repeated_value.add().null_value = 0
+ self.assertEqual(
+ json.loads(json_format.MessageToJson(message, False)),
+ json.loads(
+ '{'
+ ' "value": "hello",'
+ ' "repeatedValue": [11.1, false, null]'
+ '}'))
+ parsed_message = json_format_proto3_pb2.TestValue()
+ self.CheckParseBack(message, parsed_message)
+ # Can't parse back if the Value message is not set.
+ message.repeated_value.add()
+ self.assertEqual(
+ json.loads(json_format.MessageToJson(message, False)),
+ json.loads(
+ '{'
+ ' "value": "hello",'
+ ' "repeatedValue": [11.1, false, null, null]'
+ '}'))
+
+ def testListValueMessage(self):
+ message = json_format_proto3_pb2.TestListValue()
+ message.value.values.add().number_value = 11.1
+ message.value.values.add().null_value = 0
+ message.value.values.add().bool_value = True
+ message.value.values.add().string_value = 'hello'
+ message.value.values.add().struct_value['name'] = 'Jim'
+ message.repeated_value.add().values.add().number_value = 1
+ message.repeated_value.add()
+ self.assertEqual(
+ json.loads(json_format.MessageToJson(message, False)),
+ json.loads(
+ '{"value": [11.1, null, true, "hello", {"name": "Jim"}]\n,'
+ '"repeatedValue": [[1], []]}'))
+ parsed_message = json_format_proto3_pb2.TestListValue()
+ self.CheckParseBack(message, parsed_message)
+
+ def testAnyMessage(self):
+ message = json_format_proto3_pb2.TestAny()
+ value1 = json_format_proto3_pb2.MessageType()
+ value2 = json_format_proto3_pb2.MessageType()
+ value1.value = 1234
+ value2.value = 5678
+ message.value.Pack(value1)
+ message.repeated_value.add().Pack(value1)
+ message.repeated_value.add().Pack(value2)
+ message.repeated_value.add()
+ self.assertEqual(
+ json.loads(json_format.MessageToJson(message, True)),
+ json.loads(
+ '{\n'
+ ' "repeatedValue": [ {\n'
+ ' "@type": "type.googleapis.com/proto3.MessageType",\n'
+ ' "value": 1234\n'
+ ' }, {\n'
+ ' "@type": "type.googleapis.com/proto3.MessageType",\n'
+ ' "value": 5678\n'
+ ' },\n'
+ ' {}],\n'
+ ' "value": {\n'
+ ' "@type": "type.googleapis.com/proto3.MessageType",\n'
+ ' "value": 1234\n'
+ ' }\n'
+ '}\n'))
+ parsed_message = json_format_proto3_pb2.TestAny()
+ self.CheckParseBack(message, parsed_message)
+ # Must print @type first
+ test_message = json_format_proto3_pb2.TestMessage(
+ bool_value=True,
+ int32_value=20,
+ int64_value=-20,
+ uint32_value=20,
+ uint64_value=20,
+ double_value=3.14,
+ string_value='foo')
+ message.Clear()
+ message.value.Pack(test_message)
+ self.assertEqual(
+ json_format.MessageToJson(message, False)[0:68],
+ '{\n'
+ ' "value": {\n'
+ ' "@type": "type.googleapis.com/proto3.TestMessage"')
+
+ def testWellKnownInAnyMessage(self):
+ message = any_pb2.Any()
+ int32_value = wrappers_pb2.Int32Value()
+ int32_value.value = 1234
+ message.Pack(int32_value)
+ self.assertEqual(
+ json.loads(json_format.MessageToJson(message, True)),
+ json.loads(
+ '{\n'
+ ' "@type": \"type.googleapis.com/google.protobuf.Int32Value\",\n'
+ ' "value": 1234\n'
+ '}\n'))
+ parsed_message = any_pb2.Any()
+ self.CheckParseBack(message, parsed_message)
+
+ timestamp = timestamp_pb2.Timestamp()
+ message.Pack(timestamp)
+ self.assertEqual(
+ json.loads(json_format.MessageToJson(message, True)),
+ json.loads(
+ '{\n'
+ ' "@type": "type.googleapis.com/google.protobuf.Timestamp",\n'
+ ' "value": "1970-01-01T00:00:00Z"\n'
+ '}\n'))
+ self.CheckParseBack(message, parsed_message)
+
+ duration = duration_pb2.Duration()
+ duration.seconds = 1
+ message.Pack(duration)
+ self.assertEqual(
+ json.loads(json_format.MessageToJson(message, True)),
+ json.loads(
+ '{\n'
+ ' "@type": "type.googleapis.com/google.protobuf.Duration",\n'
+ ' "value": "1s"\n'
+ '}\n'))
+ self.CheckParseBack(message, parsed_message)
+
+ field_mask = field_mask_pb2.FieldMask()
+ field_mask.paths.append('foo.bar')
+ field_mask.paths.append('bar')
+ message.Pack(field_mask)
+ self.assertEqual(
+ json.loads(json_format.MessageToJson(message, True)),
+ json.loads(
+ '{\n'
+ ' "@type": "type.googleapis.com/google.protobuf.FieldMask",\n'
+ ' "value": "foo.bar,bar"\n'
+ '}\n'))
+ self.CheckParseBack(message, parsed_message)
+
+ struct_message = struct_pb2.Struct()
+ struct_message['name'] = 'Jim'
+ message.Pack(struct_message)
+ self.assertEqual(
+ json.loads(json_format.MessageToJson(message, True)),
+ json.loads(
+ '{\n'
+ ' "@type": "type.googleapis.com/google.protobuf.Struct",\n'
+ ' "value": {"name": "Jim"}\n'
+ '}\n'))
+ self.CheckParseBack(message, parsed_message)
+
+ nested_any = any_pb2.Any()
+ int32_value.value = 5678
+ nested_any.Pack(int32_value)
+ message.Pack(nested_any)
+ self.assertEqual(
+ json.loads(json_format.MessageToJson(message, True)),
+ json.loads(
+ '{\n'
+ ' "@type": "type.googleapis.com/google.protobuf.Any",\n'
+ ' "value": {\n'
+ ' "@type": "type.googleapis.com/google.protobuf.Int32Value",\n'
+ ' "value": 5678\n'
+ ' }\n'
+ '}\n'))
+ self.CheckParseBack(message, parsed_message)
+
def testParseNull(self):
message = json_format_proto3_pb2.TestMessage()
- message.repeated_int32_value.append(1)
- message.repeated_int32_value.append(2)
- message.repeated_int32_value.append(3)
parsed_message = json_format_proto3_pb2.TestMessage()
self.FillAllFields(parsed_message)
json_format.Parse('{"int32Value": null, '
@@ -363,7 +586,7 @@ class JsonFormatTest(JsonFormatBase):
'"bytesValue": null,'
'"messageValue": null,'
'"enumValue": null,'
- '"repeatedInt32Value": [1, 2, null, 3],'
+ '"repeatedInt32Value": null,'
'"repeatedInt64Value": null,'
'"repeatedUint32Value": null,'
'"repeatedUint64Value": null,'
@@ -377,6 +600,13 @@ class JsonFormatTest(JsonFormatBase):
'}',
parsed_message)
self.assertEqual(message, parsed_message)
+ self.assertRaisesRegexp(
+ json_format.ParseError,
+ 'Failed to parse repeatedInt32Value field: '
+ 'null is not allowed to be used as an element in a repeated field.',
+ json_format.Parse,
+ '{"repeatedInt32Value":[1, null]}',
+ parsed_message)
def testNanFloat(self):
message = json_format_proto3_pb2.TestMessage()
@@ -389,7 +619,7 @@ class JsonFormatTest(JsonFormatBase):
def testParseEmptyText(self):
self.CheckError('',
- r'Failed to load JSON: (Expecting value)|(No JSON)')
+ r'Failed to load JSON: (Expecting value)|(No JSON).')
def testParseBadEnumValue(self):
self.CheckError(
@@ -409,12 +639,25 @@ class JsonFormatTest(JsonFormatBase):
'Message type "proto3.TestMessage" has no field named '
'"unknownName".')
+ def testIgnoreUnknownField(self):
+ text = '{"unknownName": 1}'
+ parsed_message = json_format_proto3_pb2.TestMessage()
+ json_format.Parse(text, parsed_message, ignore_unknown_fields=True)
+ text = ('{\n'
+ ' "repeatedValue": [ {\n'
+ ' "@type": "type.googleapis.com/proto3.MessageType",\n'
+ ' "unknownName": 1\n'
+ ' }]\n'
+ '}\n')
+ parsed_message = json_format_proto3_pb2.TestAny()
+ json_format.Parse(text, parsed_message, ignore_unknown_fields=True)
+
def testDuplicateField(self):
# Duplicate key check is not supported for python2.6
if sys.version_info < (2, 7):
return
self.CheckError('{"int32Value": 1,\n"int32Value":2}',
- 'Failed to load JSON: duplicate key int32Value')
+ 'Failed to load JSON: duplicate key int32Value.')
def testInvalidBoolValue(self):
self.CheckError('{"boolValue": 1}',
@@ -431,39 +674,43 @@ class JsonFormatTest(JsonFormatBase):
json_format.Parse, text, message)
self.CheckError('{"int32Value": 012345}',
(r'Failed to load JSON: Expecting \'?,\'? delimiter: '
- r'line 1'))
+ r'line 1.'))
self.CheckError('{"int32Value": 1.0}',
'Failed to parse int32Value field: '
- 'Couldn\'t parse integer: 1.0')
+ 'Couldn\'t parse integer: 1.0.')
self.CheckError('{"int32Value": " 1 "}',
'Failed to parse int32Value field: '
- 'Couldn\'t parse integer: " 1 "')
+ 'Couldn\'t parse integer: " 1 ".')
+ self.CheckError('{"int32Value": "1 "}',
+ 'Failed to parse int32Value field: '
+ 'Couldn\'t parse integer: "1 ".')
self.CheckError('{"int32Value": 12345678901234567890}',
'Failed to parse int32Value field: Value out of range: '
- '12345678901234567890')
+ '12345678901234567890.')
self.CheckError('{"int32Value": 1e5}',
'Failed to parse int32Value field: '
- 'Couldn\'t parse integer: 100000.0')
+ 'Couldn\'t parse integer: 100000.0.')
self.CheckError('{"uint32Value": -1}',
- 'Failed to parse uint32Value field: Value out of range: -1')
+ 'Failed to parse uint32Value field: '
+ 'Value out of range: -1.')
def testInvalidFloatValue(self):
self.CheckError('{"floatValue": "nan"}',
'Failed to parse floatValue field: Couldn\'t '
- 'parse float "nan", use "NaN" instead')
+ 'parse float "nan", use "NaN" instead.')
def testInvalidBytesValue(self):
self.CheckError('{"bytesValue": "AQI"}',
- 'Failed to parse bytesValue field: Incorrect padding')
+ 'Failed to parse bytesValue field: Incorrect padding.')
self.CheckError('{"bytesValue": "AQI*"}',
- 'Failed to parse bytesValue field: Incorrect padding')
+ 'Failed to parse bytesValue field: Incorrect padding.')
def testInvalidMap(self):
message = json_format_proto3_pb2.TestMap()
text = '{"int32Map": {"null": 2, "2": 3}}'
self.assertRaisesRegexp(
json_format.ParseError,
- 'Failed to parse int32Map field: Couldn\'t parse integer: "null"',
+ 'Failed to parse int32Map field: invalid literal',
json_format.Parse, text, message)
text = '{"int32Map": {1: 2, "2": 3}}'
self.assertRaisesRegexp(
@@ -474,7 +721,7 @@ class JsonFormatTest(JsonFormatBase):
text = '{"boolMap": {"null": 1}}'
self.assertRaisesRegexp(
json_format.ParseError,
- 'Failed to parse boolMap field: Expect "true" or "false", not null.',
+ 'Failed to parse boolMap field: Expected "true" or "false", not null.',
json_format.Parse, text, message)
if sys.version_info < (2, 7):
return
@@ -490,30 +737,29 @@ class JsonFormatTest(JsonFormatBase):
self.assertRaisesRegexp(
json_format.ParseError,
'time data \'10000-01-01T00:00:00\' does not match'
- ' format \'%Y-%m-%dT%H:%M:%S\'',
+ ' format \'%Y-%m-%dT%H:%M:%S\'.',
json_format.Parse, text, message)
text = '{"value": "1970-01-01T00:00:00.0123456789012Z"}'
self.assertRaisesRegexp(
- json_format.ParseError,
- 'Failed to parse value field: Failed to parse Timestamp: '
+ well_known_types.ParseError,
'nanos 0123456789012 more than 9 fractional digits.',
json_format.Parse, text, message)
text = '{"value": "1972-01-01T01:00:00.01+08"}'
self.assertRaisesRegexp(
- json_format.ParseError,
- (r'Failed to parse value field: Invalid timezone offset value: \+08'),
+ well_known_types.ParseError,
+ (r'Invalid timezone offset value: \+08.'),
json_format.Parse, text, message)
# Time smaller than minimum time.
text = '{"value": "0000-01-01T00:00:00Z"}'
self.assertRaisesRegexp(
json_format.ParseError,
- 'Failed to parse value field: year is out of range',
+ 'Failed to parse value field: year is out of range.',
json_format.Parse, text, message)
# Time bigger than maxinum time.
message.value.seconds = 253402300800
self.assertRaisesRegexp(
- json_format.SerializeToJsonError,
- 'Failed to serialize value field: year is out of range',
+ OverflowError,
+ 'date value out of range',
json_format.MessageToJson, message)
def testInvalidOneof(self):
@@ -525,6 +771,45 @@ class JsonFormatTest(JsonFormatBase):
' should not have multiple "oneof_value" oneof fields.',
json_format.Parse, text, message)
+ def testInvalidListValue(self):
+ message = json_format_proto3_pb2.TestListValue()
+ text = '{"value": 1234}'
+ self.assertRaisesRegexp(
+ json_format.ParseError,
+ r'Failed to parse value field: ListValue must be in \[\] which is 1234',
+ json_format.Parse, text, message)
+
+ def testInvalidStruct(self):
+ message = json_format_proto3_pb2.TestStruct()
+ text = '{"value": 1234}'
+ self.assertRaisesRegexp(
+ json_format.ParseError,
+ 'Failed to parse value field: Struct must be in a dict which is 1234',
+ json_format.Parse, text, message)
+
+ def testInvalidAny(self):
+ message = any_pb2.Any()
+ text = '{"@type": "type.googleapis.com/google.protobuf.Int32Value"}'
+ self.assertRaisesRegexp(
+ KeyError,
+ 'value',
+ json_format.Parse, text, message)
+ text = '{"value": 1234}'
+ self.assertRaisesRegexp(
+ json_format.ParseError,
+ '@type is missing when parsing any message.',
+ json_format.Parse, text, message)
+ text = '{"@type": "type.googleapis.com/MessageNotExist", "value": 1234}'
+ self.assertRaisesRegexp(
+ TypeError,
+ 'Can not find message descriptor by type_url: '
+ 'type.googleapis.com/MessageNotExist.',
+ json_format.Parse, text, message)
+ # Only last part is to be used: b/25630112
+ text = (r'{"@type": "incorrect.googleapis.com/google.protobuf.Int32Value",'
+ r'"value": 1234}')
+ json_format.Parse(text, message)
+
if __name__ == '__main__':
unittest.main()
diff --git a/python/google/protobuf/internal/message_factory_test.py b/python/google/protobuf/internal/message_factory_test.py
index d760b898..7bb7d1ac 100644
--- a/python/google/protobuf/internal/message_factory_test.py
+++ b/python/google/protobuf/internal/message_factory_test.py
@@ -35,9 +35,10 @@
__author__ = 'matthewtoia@google.com (Matt Toia)'
try:
- import unittest2 as unittest
+ import unittest2 as unittest #PY26
except ImportError:
import unittest
+
from google.protobuf import descriptor_pb2
from google.protobuf.internal import factory_test1_pb2
from google.protobuf.internal import factory_test2_pb2
@@ -45,6 +46,7 @@ from google.protobuf import descriptor_database
from google.protobuf import descriptor_pool
from google.protobuf import message_factory
+
class MessageFactoryTest(unittest.TestCase):
def setUp(self):
@@ -104,8 +106,8 @@ class MessageFactoryTest(unittest.TestCase):
def testGetMessages(self):
# performed twice because multiple calls with the same input must be allowed
for _ in range(2):
- messages = message_factory.GetMessages([self.factory_test2_fd,
- self.factory_test1_fd])
+ messages = message_factory.GetMessages([self.factory_test1_fd,
+ self.factory_test2_fd])
self.assertTrue(
set(['google.protobuf.python.internal.Factory2Message',
'google.protobuf.python.internal.Factory1Message'],
@@ -116,7 +118,7 @@ class MessageFactoryTest(unittest.TestCase):
set(['google.protobuf.python.internal.Factory2Message.one_more_field',
'google.protobuf.python.internal.another_field'],
).issubset(
- set(messages['google.protobuf.python.internal.Factory1Message']
+ set(messages['google.protobuf.python.internal.Factory1Message']
._extensions_by_name.keys())))
factory_msg1 = messages['google.protobuf.python.internal.Factory1Message']
msg1 = messages['google.protobuf.python.internal.Factory1Message']()
@@ -129,6 +131,60 @@ class MessageFactoryTest(unittest.TestCase):
self.assertEqual('test1', msg1.Extensions[ext1])
self.assertEqual('test2', msg1.Extensions[ext2])
+ def testDuplicateExtensionNumber(self):
+ pool = descriptor_pool.DescriptorPool()
+ factory = message_factory.MessageFactory(pool=pool)
+
+ # Add Container message.
+ f = descriptor_pb2.FileDescriptorProto()
+ f.name = 'google/protobuf/internal/container.proto'
+ f.package = 'google.protobuf.python.internal'
+ msg = f.message_type.add()
+ msg.name = 'Container'
+ rng = msg.extension_range.add()
+ rng.start = 1
+ rng.end = 10
+ pool.Add(f)
+ msgs = factory.GetMessages([f.name])
+ self.assertIn('google.protobuf.python.internal.Container', msgs)
+
+ # Extend container.
+ f = descriptor_pb2.FileDescriptorProto()
+ f.name = 'google/protobuf/internal/extension.proto'
+ f.package = 'google.protobuf.python.internal'
+ f.dependency.append('google/protobuf/internal/container.proto')
+ msg = f.message_type.add()
+ msg.name = 'Extension'
+ ext = msg.extension.add()
+ ext.name = 'extension_field'
+ ext.number = 2
+ ext.label = descriptor_pb2.FieldDescriptorProto.LABEL_OPTIONAL
+ ext.type_name = 'Extension'
+ ext.extendee = 'Container'
+ pool.Add(f)
+ msgs = factory.GetMessages([f.name])
+ self.assertIn('google.protobuf.python.internal.Extension', msgs)
+
+ # Add Duplicate extending the same field number.
+ f = descriptor_pb2.FileDescriptorProto()
+ f.name = 'google/protobuf/internal/duplicate.proto'
+ f.package = 'google.protobuf.python.internal'
+ f.dependency.append('google/protobuf/internal/container.proto')
+ msg = f.message_type.add()
+ msg.name = 'Duplicate'
+ ext = msg.extension.add()
+ ext.name = 'extension_field'
+ ext.number = 2
+ ext.label = descriptor_pb2.FieldDescriptorProto.LABEL_OPTIONAL
+ ext.type_name = 'Duplicate'
+ ext.extendee = 'Container'
+ pool.Add(f)
+
+ with self.assertRaises(Exception) as cm:
+ factory.GetMessages([f.name])
+
+ self.assertIsInstance(cm.exception, (AssertionError, ValueError))
+
if __name__ == '__main__':
unittest.main()
diff --git a/python/google/protobuf/internal/message_set_extensions.proto b/python/google/protobuf/internal/message_set_extensions.proto
index 702c8d07..14e5f193 100644
--- a/python/google/protobuf/internal/message_set_extensions.proto
+++ b/python/google/protobuf/internal/message_set_extensions.proto
@@ -54,6 +54,14 @@ message TestMessageSetExtension2 {
optional string str = 25;
}
+message TestMessageSetExtension3 {
+ optional string text = 35;
+}
+
+extend TestMessageSet {
+ optional TestMessageSetExtension3 message_set_extension3 = 98418655;
+}
+
// This message was used to generate
// //net/proto2/python/internal/testdata/message_set_message, but is commented
// out since it must not actually exist in code, to simulate an "unknown"
diff --git a/python/google/protobuf/internal/message_test.py b/python/google/protobuf/internal/message_test.py
index 13c3caa6..1e95adf9 100755
--- a/python/google/protobuf/internal/message_test.py
+++ b/python/google/protobuf/internal/message_test.py
@@ -53,21 +53,27 @@ import six
import sys
try:
- import unittest2 as unittest
+ import unittest2 as unittest #PY26
except ImportError:
import unittest
-from google.protobuf.internal import _parameterized
+
from google.protobuf import map_unittest_pb2
from google.protobuf import unittest_pb2
from google.protobuf import unittest_proto3_arena_pb2
+from google.protobuf import descriptor_pb2
+from google.protobuf import descriptor_pool
+from google.protobuf import message_factory
+from google.protobuf import text_format
from google.protobuf.internal import api_implementation
from google.protobuf.internal import packed_field_test_pb2
from google.protobuf.internal import test_util
from google.protobuf import message
+from google.protobuf.internal import _parameterized
if six.PY3:
long = int
+
# Python pre-2.6 does not have isinf() or isnan() functions, so we have
# to provide our own.
def isnan(val):
@@ -1156,6 +1162,7 @@ class Proto2Test(unittest.TestCase):
unittest_pb2.TestAllTypes(repeated_nested_enum='FOO')
+
# Class to test proto3-only features/behavior (updated field presence & enums)
class Proto3Test(unittest.TestCase):
@@ -1258,7 +1265,10 @@ class Proto3Test(unittest.TestCase):
self.assertFalse(-2**33 in msg.map_int64_int64)
self.assertFalse(123 in msg.map_uint32_uint32)
self.assertFalse(2**33 in msg.map_uint64_uint64)
+ self.assertFalse(123 in msg.map_int32_double)
+ self.assertFalse(False in msg.map_bool_bool)
self.assertFalse('abc' in msg.map_string_string)
+ self.assertFalse(111 in msg.map_int32_bytes)
self.assertFalse(888 in msg.map_int32_enum)
# Accessing an unset key returns the default.
@@ -1266,7 +1276,12 @@ class Proto3Test(unittest.TestCase):
self.assertEqual(0, msg.map_int64_int64[-2**33])
self.assertEqual(0, msg.map_uint32_uint32[123])
self.assertEqual(0, msg.map_uint64_uint64[2**33])
+ self.assertEqual(0.0, msg.map_int32_double[123])
+ self.assertTrue(isinstance(msg.map_int32_double[123], float))
+ self.assertEqual(False, msg.map_bool_bool[False])
+ self.assertTrue(isinstance(msg.map_bool_bool[False], bool))
self.assertEqual('', msg.map_string_string['abc'])
+ self.assertEqual(b'', msg.map_int32_bytes[111])
self.assertEqual(0, msg.map_int32_enum[888])
# It also sets the value in the map
@@ -1274,17 +1289,21 @@ class Proto3Test(unittest.TestCase):
self.assertTrue(-2**33 in msg.map_int64_int64)
self.assertTrue(123 in msg.map_uint32_uint32)
self.assertTrue(2**33 in msg.map_uint64_uint64)
+ self.assertTrue(123 in msg.map_int32_double)
+ self.assertTrue(False in msg.map_bool_bool)
self.assertTrue('abc' in msg.map_string_string)
+ self.assertTrue(111 in msg.map_int32_bytes)
self.assertTrue(888 in msg.map_int32_enum)
self.assertIsInstance(msg.map_string_string['abc'], six.text_type)
- # Accessing an unset key still throws TypeError of the type of the key
+ # Accessing an unset key still throws TypeError if the type of the key
# is incorrect.
with self.assertRaises(TypeError):
msg.map_string_string[123]
- self.assertFalse(123 in msg.map_string_string)
+ with self.assertRaises(TypeError):
+ 123 in msg.map_string_string
def testMapGet(self):
# Need to test that get() properly returns the default, even though the dict
@@ -1416,6 +1435,8 @@ class Proto3Test(unittest.TestCase):
msg2.map_int32_int32[12] = 55
msg2.map_int64_int64[88] = 99
msg2.map_int32_foreign_message[222].c = 15
+ msg2.map_int32_foreign_message[222].d = 20
+ old_map_value = msg2.map_int32_foreign_message[222]
msg2.MergeFrom(msg)
@@ -1425,6 +1446,8 @@ class Proto3Test(unittest.TestCase):
self.assertEqual(99, msg2.map_int64_int64[88])
self.assertEqual(5, msg2.map_int32_foreign_message[111].c)
self.assertEqual(10, msg2.map_int32_foreign_message[222].c)
+ self.assertFalse(msg2.map_int32_foreign_message[222].HasField('d'))
+ self.assertEqual(15, old_map_value.c)
# Verify that there is only one entry per key, even though the MergeFrom
# may have internally created multiple entries for a single key in the
@@ -1446,6 +1469,22 @@ class Proto3Test(unittest.TestCase):
del msg2.map_int32_foreign_message[222]
self.assertFalse(222 in msg2.map_int32_foreign_message)
+ def testMergeFromBadType(self):
+ msg = map_unittest_pb2.TestMap()
+ with self.assertRaisesRegexp(
+ TypeError,
+ r'Parameter to MergeFrom\(\) must be instance of same class: expected '
+ r'.*TestMap got int\.'):
+ msg.MergeFrom(1)
+
+ def testCopyFromBadType(self):
+ msg = map_unittest_pb2.TestMap()
+ with self.assertRaisesRegexp(
+ TypeError,
+ r'Parameter to [A-Za-z]*From\(\) must be instance of same class: '
+ r'expected .*TestMap got int\.'):
+ msg.CopyFrom(1)
+
def testIntegerMapWithLongs(self):
msg = map_unittest_pb2.TestMap()
msg.map_int32_int32[long(-123)] = long(-456)
@@ -1563,6 +1602,21 @@ class Proto3Test(unittest.TestCase):
matching_dict = {2: 4, 3: 6, 4: 8}
self.assertMapIterEquals(msg.map_int32_int32.items(), matching_dict)
+ def testMapItems(self):
+ # Map items used to have strange behaviors when use c extension. Because
+ # [] may reorder the map and invalidate any exsting iterators.
+ # TODO(jieluo): Check if [] reordering the map is a bug or intended
+ # behavior.
+ msg = map_unittest_pb2.TestMap()
+ msg.map_string_string['local_init_op'] = ''
+ msg.map_string_string['trainable_variables'] = ''
+ msg.map_string_string['variables'] = ''
+ msg.map_string_string['init_op'] = ''
+ msg.map_string_string['summaries'] = ''
+ items1 = msg.map_string_string.items()
+ items2 = msg.map_string_string.items()
+ self.assertEqual(items1, items2)
+
def testMapIterationClearMessage(self):
# Iterator needs to work even if message and map are deleted.
msg = map_unittest_pb2.TestMap()
@@ -1591,31 +1645,49 @@ class Proto3Test(unittest.TestCase):
# For the C++ implementation this tests the correctness of
# ScalarMapContainer::Release()
msg = map_unittest_pb2.TestMap()
- map = msg.map_int32_int32
+ int32_map = msg.map_int32_int32
- map[2] = 4
- map[3] = 6
- map[4] = 8
+ int32_map[2] = 4
+ int32_map[3] = 6
+ int32_map[4] = 8
msg.ClearField('map_int32_int32')
+ self.assertEqual(b'', msg.SerializeToString())
matching_dict = {2: 4, 3: 6, 4: 8}
- self.assertMapIterEquals(map.items(), matching_dict)
+ self.assertMapIterEquals(int32_map.items(), matching_dict)
- def testMapIterValidAfterFieldCleared(self):
- # Map iterator needs to work even if field is cleared.
+ def testMessageMapValidAfterFieldCleared(self):
+ # Map needs to work even if field is cleared.
# For the C++ implementation this tests the correctness of
# ScalarMapContainer::Release()
msg = map_unittest_pb2.TestMap()
+ int32_foreign_message = msg.map_int32_foreign_message
- msg.map_int32_int32[2] = 4
- msg.map_int32_int32[3] = 6
- msg.map_int32_int32[4] = 8
+ int32_foreign_message[2].c = 5
- it = msg.map_int32_int32.items()
+ msg.ClearField('map_int32_foreign_message')
+ self.assertEqual(b'', msg.SerializeToString())
+ self.assertTrue(2 in int32_foreign_message.keys())
+
+ def testMapIterInvalidatedByClearField(self):
+ # Map iterator is invalidated when field is cleared.
+ # But this case does need to not crash the interpreter.
+ # For the C++ implementation this tests the correctness of
+ # ScalarMapContainer::Release()
+ msg = map_unittest_pb2.TestMap()
+
+ it = iter(msg.map_int32_int32)
msg.ClearField('map_int32_int32')
- matching_dict = {2: 4, 3: 6, 4: 8}
- self.assertMapIterEquals(it, matching_dict)
+ with self.assertRaises(RuntimeError):
+ for _ in it:
+ pass
+
+ it = iter(msg.map_int32_foreign_message)
+ msg.ClearField('map_int32_foreign_message')
+ with self.assertRaises(RuntimeError):
+ for _ in it:
+ pass
def testMapDelete(self):
msg = map_unittest_pb2.TestMap()
@@ -1725,5 +1797,60 @@ class PackedFieldTest(unittest.TestCase):
b'\x70\x01')
self.assertEqual(golden_data, message.SerializeToString())
+
+@unittest.skipIf(api_implementation.Type() != 'cpp',
+ 'explicit tests of the C++ implementation')
+class OversizeProtosTest(unittest.TestCase):
+
+ def setUp(self):
+ self.file_desc = """
+ name: "f/f.msg2"
+ package: "f"
+ message_type {
+ name: "msg1"
+ field {
+ name: "payload"
+ number: 1
+ label: LABEL_OPTIONAL
+ type: TYPE_STRING
+ }
+ }
+ message_type {
+ name: "msg2"
+ field {
+ name: "field"
+ number: 1
+ label: LABEL_OPTIONAL
+ type: TYPE_MESSAGE
+ type_name: "msg1"
+ }
+ }
+ """
+ pool = descriptor_pool.DescriptorPool()
+ desc = descriptor_pb2.FileDescriptorProto()
+ text_format.Parse(self.file_desc, desc)
+ pool.Add(desc)
+ self.proto_cls = message_factory.MessageFactory(pool).GetPrototype(
+ pool.FindMessageTypeByName('f.msg2'))
+ self.p = self.proto_cls()
+ self.p.field.payload = 'c' * (1024 * 1024 * 64 + 1)
+ self.p_serialized = self.p.SerializeToString()
+
+ def testAssertOversizeProto(self):
+ from google.protobuf.pyext._message import SetAllowOversizeProtos
+ SetAllowOversizeProtos(False)
+ q = self.proto_cls()
+ try:
+ q.ParseFromString(self.p_serialized)
+ except message.DecodeError as e:
+ self.assertEqual(str(e), 'Error parsing message')
+
+ def testSucceedOversizeProto(self):
+ from google.protobuf.pyext._message import SetAllowOversizeProtos
+ SetAllowOversizeProtos(True)
+ q = self.proto_cls()
+ q.ParseFromString(self.p_serialized)
+ self.assertEqual(self.p.field.payload, q.field.payload)
+
if __name__ == '__main__':
unittest.main()
diff --git a/python/google/protobuf/internal/proto_builder_test.py b/python/google/protobuf/internal/proto_builder_test.py
index 822ad895..36dfbfde 100644
--- a/python/google/protobuf/internal/proto_builder_test.py
+++ b/python/google/protobuf/internal/proto_builder_test.py
@@ -40,6 +40,7 @@ try:
import unittest2 as unittest
except ImportError:
import unittest
+
from google.protobuf import descriptor_pb2
from google.protobuf import descriptor_pool
from google.protobuf import proto_builder
diff --git a/python/google/protobuf/internal/python_message.py b/python/google/protobuf/internal/python_message.py
index 2b87f704..c0d0ad45 100755
--- a/python/google/protobuf/internal/python_message.py
+++ b/python/google/protobuf/internal/python_message.py
@@ -56,7 +56,14 @@ import struct
import weakref
import six
-import six.moves.copyreg as copyreg
+try:
+ import six.moves.copyreg as copyreg
+except ImportError:
+ # On some platforms, for example gMac, we run native Python because there is
+ # nothing like hermetic Python. This means lesser control on the system and
+ # the six.moves package may be missing (is missing on 20150321 on gMac). Be
+ # extra conservative and try to load the old replacement if it fails.
+ import copy_reg as copyreg
# We use "as" to avoid name collisions with variables.
from google.protobuf.internal import containers
@@ -65,13 +72,14 @@ from google.protobuf.internal import encoder
from google.protobuf.internal import enum_type_wrapper
from google.protobuf.internal import message_listener as message_listener_mod
from google.protobuf.internal import type_checkers
+from google.protobuf.internal import well_known_types
from google.protobuf.internal import wire_format
from google.protobuf import descriptor as descriptor_mod
from google.protobuf import message as message_mod
-from google.protobuf import symbol_database
from google.protobuf import text_format
_FieldDescriptor = descriptor_mod.FieldDescriptor
+_AnyFullTypeName = 'google.protobuf.Any'
class GeneratedProtocolMessageType(type):
@@ -89,16 +97,12 @@ class GeneratedProtocolMessageType(type):
classes at runtime, as in this example:
mydescriptor = Descriptor(.....)
- class MyProtoClass(Message):
- __metaclass__ = GeneratedProtocolMessageType
- DESCRIPTOR = mydescriptor
+ factory = symbol_database.Default()
+ factory.pool.AddDescriptor(mydescriptor)
+ MyProtoClass = factory.GetPrototype(mydescriptor)
myproto_instance = MyProtoClass()
myproto.foo_field = 23
...
-
- The above example will not work for nested types. If you wish to include them,
- use reflection.MakeClass() instead of manually instantiating the class in
- order to create the appropriate class structure.
"""
# Must be consistent with the protocol-compiler code in
@@ -127,6 +131,8 @@ class GeneratedProtocolMessageType(type):
Newly-allocated class.
"""
descriptor = dictionary[GeneratedProtocolMessageType._DESCRIPTOR_KEY]
+ if descriptor.full_name in well_known_types.WKTBASES:
+ bases += (well_known_types.WKTBASES[descriptor.full_name],)
_AddClassAttributesForNestedExtensions(descriptor, dictionary)
_AddSlots(descriptor, dictionary)
@@ -261,7 +267,6 @@ def _IsMessageSetExtension(field):
field.containing_type.has_options and
field.containing_type.GetOptions().message_set_wire_format and
field.type == _FieldDescriptor.TYPE_MESSAGE and
- field.message_type == field.extension_scope and
field.label == _FieldDescriptor.LABEL_OPTIONAL)
@@ -487,6 +492,9 @@ def _AddInitMethod(message_descriptor, cls):
if field is None:
raise TypeError("%s() got an unexpected keyword argument '%s'" %
(message_descriptor.name, field_name))
+ if field_value is None:
+ # field=None is the same as no field at all.
+ continue
if field.label == _FieldDescriptor.LABEL_REPEATED:
copy = field._default_constructor(self)
if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: # Composite
@@ -543,7 +551,8 @@ def _GetFieldByName(message_descriptor, field_name):
try:
return message_descriptor.fields_by_name[field_name]
except KeyError:
- raise ValueError('Protocol message has no "%s" field.' % field_name)
+ raise ValueError('Protocol message %s has no "%s" field.' %
+ (message_descriptor.name, field_name))
def _AddPropertiesForFields(descriptor, cls):
@@ -848,9 +857,15 @@ def _AddClearFieldMethod(message_descriptor, cls):
else:
return
except KeyError:
- raise ValueError('Protocol message has no "%s" field.' % field_name)
+ raise ValueError('Protocol message %s() has no "%s" field.' %
+ (message_descriptor.name, field_name))
if field in self._fields:
+ # To match the C++ implementation, we need to invalidate iterators
+ # for map fields when ClearField() happens.
+ if hasattr(self._fields[field], 'InvalidateIterators'):
+ self._fields[field].InvalidateIterators()
+
# Note: If the field is a sub-message, its listener will still point
# at us. That's fine, because the worst than can happen is that it
# will call _Modified() and invalidate our byte size. Big deal.
@@ -879,17 +894,6 @@ def _AddClearExtensionMethod(cls):
cls.ClearExtension = ClearExtension
-def _AddClearMethod(message_descriptor, cls):
- """Helper for _AddMessageMethods()."""
- def Clear(self):
- # Clear fields.
- self._fields = {}
- self._unknown_fields = ()
- self._oneofs = {}
- self._Modified()
- cls.Clear = Clear
-
-
def _AddHasExtensionMethod(cls):
"""Helper for _AddMessageMethods()."""
def HasExtension(self, extension_handle):
@@ -904,27 +908,46 @@ def _AddHasExtensionMethod(cls):
return extension_handle in self._fields
cls.HasExtension = HasExtension
-def _UnpackAny(msg):
+def _InternalUnpackAny(msg):
+ """Unpacks Any message and returns the unpacked message.
+
+ This internal method is differnt from public Any Unpack method which takes
+ the target message as argument. _InternalUnpackAny method does not have
+ target message type and need to find the message type in descriptor pool.
+
+ Args:
+ msg: An Any message to be unpacked.
+
+ Returns:
+ The unpacked message.
+ """
+ # TODO(amauryfa): Don't use the factory of generated messages.
+ # To make Any work with custom factories, use the message factory of the
+ # parent message.
+ # pylint: disable=g-import-not-at-top
+ from google.protobuf import symbol_database
+ factory = symbol_database.Default()
+
type_url = msg.type_url
- db = symbol_database.Default()
if not type_url:
return None
# TODO(haberman): For now we just strip the hostname. Better logic will be
# required.
- type_name = type_url.split("/")[-1]
- descriptor = db.pool.FindMessageTypeByName(type_name)
+ type_name = type_url.split('/')[-1]
+ descriptor = factory.pool.FindMessageTypeByName(type_name)
if descriptor is None:
return None
- message_class = db.GetPrototype(descriptor)
+ message_class = factory.GetPrototype(descriptor)
message = message_class()
message.ParseFromString(msg.value)
return message
+
def _AddEqualsMethod(message_descriptor, cls):
"""Helper for _AddMessageMethods()."""
def __eq__(self, other):
@@ -935,9 +958,9 @@ def _AddEqualsMethod(message_descriptor, cls):
if self is other:
return True
- if self.DESCRIPTOR.full_name == "google.protobuf.Any":
- any_a = _UnpackAny(self)
- any_b = _UnpackAny(other)
+ if self.DESCRIPTOR.full_name == _AnyFullTypeName:
+ any_a = _InternalUnpackAny(self)
+ any_b = _InternalUnpackAny(other)
if any_a and any_b:
return any_a == any_b
@@ -962,6 +985,13 @@ def _AddStrMethod(message_descriptor, cls):
cls.__str__ = __str__
+def _AddReprMethod(message_descriptor, cls):
+ """Helper for _AddMessageMethods()."""
+ def __repr__(self):
+ return text_format.MessageToString(self)
+ cls.__repr__ = __repr__
+
+
def _AddUnicodeMethod(unused_message_descriptor, cls):
"""Helper for _AddMessageMethods()."""
@@ -970,16 +1000,6 @@ def _AddUnicodeMethod(unused_message_descriptor, cls):
cls.__unicode__ = __unicode__
-def _AddSetListenerMethod(cls):
- """Helper for _AddMessageMethods()."""
- def SetListener(self, listener):
- if listener is None:
- self._listener = message_listener_mod.NullMessageListener()
- else:
- self._listener = listener
- cls._SetListener = SetListener
-
-
def _BytesForNonRepeatedElement(value, field_number, field_type):
"""Returns the number of bytes needed to serialize a non-repeated element.
The returned byte count includes space for tag information and any
@@ -1259,6 +1279,32 @@ def _AddWhichOneofMethod(message_descriptor, cls):
cls.WhichOneof = WhichOneof
+def _Clear(self):
+ # Clear fields.
+ self._fields = {}
+ self._unknown_fields = ()
+ self._oneofs = {}
+ self._Modified()
+
+
+def _DiscardUnknownFields(self):
+ self._unknown_fields = []
+ for field, value in self.ListFields():
+ if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
+ if field.label == _FieldDescriptor.LABEL_REPEATED:
+ for sub_message in value:
+ sub_message.DiscardUnknownFields()
+ else:
+ value.DiscardUnknownFields()
+
+
+def _SetListener(self, listener):
+ if listener is None:
+ self._listener = message_listener_mod.NullMessageListener()
+ else:
+ self._listener = listener
+
+
def _AddMessageMethods(message_descriptor, cls):
"""Adds implementations of all Message methods to cls."""
_AddListFieldsMethod(message_descriptor, cls)
@@ -1267,11 +1313,10 @@ def _AddMessageMethods(message_descriptor, cls):
if message_descriptor.is_extendable:
_AddClearExtensionMethod(cls)
_AddHasExtensionMethod(cls)
- _AddClearMethod(message_descriptor, cls)
_AddEqualsMethod(message_descriptor, cls)
_AddStrMethod(message_descriptor, cls)
+ _AddReprMethod(message_descriptor, cls)
_AddUnicodeMethod(message_descriptor, cls)
- _AddSetListenerMethod(cls)
_AddByteSizeMethod(message_descriptor, cls)
_AddSerializeToStringMethod(message_descriptor, cls)
_AddSerializePartialToStringMethod(message_descriptor, cls)
@@ -1279,6 +1324,11 @@ def _AddMessageMethods(message_descriptor, cls):
_AddIsInitializedMethod(message_descriptor, cls)
_AddMergeFromMethod(cls)
_AddWhichOneofMethod(message_descriptor, cls)
+ # Adds methods which do not depend on cls.
+ cls.Clear = _Clear
+ cls.DiscardUnknownFields = _DiscardUnknownFields
+ cls._SetListener = _SetListener
+
def _AddPrivateHelperMethods(message_descriptor, cls):
"""Adds implementation of private helper methods to cls."""
@@ -1487,3 +1537,14 @@ class _ExtensionDict(object):
Extension field descriptor.
"""
return self._extended_message._extensions_by_name.get(name, None)
+
+ def _FindExtensionByNumber(self, number):
+ """Tries to find a known extension with the field number.
+
+ Args:
+ number: Extension field number.
+
+ Returns:
+ Extension field descriptor.
+ """
+ return self._extended_message._extensions_by_number.get(number, None)
diff --git a/python/google/protobuf/internal/reflection_test.py b/python/google/protobuf/internal/reflection_test.py
index 8621d61e..20e5d245 100755
--- a/python/google/protobuf/internal/reflection_test.py
+++ b/python/google/protobuf/internal/reflection_test.py
@@ -42,9 +42,10 @@ import six
import struct
try:
- import unittest2 as unittest
+ import unittest2 as unittest #PY26
except ImportError:
import unittest
+
from google.protobuf import unittest_import_pb2
from google.protobuf import unittest_mset_pb2
from google.protobuf import unittest_pb2
@@ -119,11 +120,13 @@ class ReflectionTest(unittest.TestCase):
proto = unittest_pb2.TestAllTypes(
optional_int32=24,
optional_double=54.321,
- optional_string='optional_string')
+ optional_string='optional_string',
+ optional_float=None)
self.assertEqual(24, proto.optional_int32)
self.assertEqual(54.321, proto.optional_double)
self.assertEqual('optional_string', proto.optional_string)
+ self.assertFalse(proto.HasField("optional_float"))
def testRepeatedScalarConstructor(self):
# Constructor with only repeated scalar types should succeed.
@@ -131,12 +134,14 @@ class ReflectionTest(unittest.TestCase):
repeated_int32=[1, 2, 3, 4],
repeated_double=[1.23, 54.321],
repeated_bool=[True, False, False],
- repeated_string=["optional_string"])
+ repeated_string=["optional_string"],
+ repeated_float=None)
self.assertEqual([1, 2, 3, 4], list(proto.repeated_int32))
self.assertEqual([1.23, 54.321], list(proto.repeated_double))
self.assertEqual([True, False, False], list(proto.repeated_bool))
self.assertEqual(["optional_string"], list(proto.repeated_string))
+ self.assertEqual([], list(proto.repeated_float))
def testRepeatedCompositeConstructor(self):
# Constructor with only repeated composite types should succeed.
@@ -187,7 +192,8 @@ class ReflectionTest(unittest.TestCase):
repeated_foreign_message=[
unittest_pb2.ForeignMessage(c=-43),
unittest_pb2.ForeignMessage(c=45324),
- unittest_pb2.ForeignMessage(c=12)])
+ unittest_pb2.ForeignMessage(c=12)],
+ optional_nested_message=None)
self.assertEqual(24, proto.optional_int32)
self.assertEqual('optional_string', proto.optional_string)
@@ -204,6 +210,7 @@ class ReflectionTest(unittest.TestCase):
unittest_pb2.ForeignMessage(c=45324),
unittest_pb2.ForeignMessage(c=12)],
list(proto.repeated_foreign_message))
+ self.assertFalse(proto.HasField("optional_nested_message"))
def testConstructorTypeError(self):
self.assertRaises(
@@ -965,6 +972,7 @@ class ReflectionTest(unittest.TestCase):
proto.repeated_nested_message.add(bb=23)
self.assertEqual(1, len(proto.repeated_nested_message))
self.assertEqual(23, proto.repeated_nested_message[0].bb)
+ self.assertRaises(TypeError, proto.repeated_nested_message.add, 23)
def testRepeatedCompositeRemove(self):
proto = unittest_pb2.TestAllTypes()
@@ -2394,8 +2402,10 @@ class SerializationTest(unittest.TestCase):
extension_message2 = message_set_extensions_pb2.TestMessageSetExtension2
extension1 = extension_message1.message_set_extension
extension2 = extension_message2.message_set_extension
+ extension3 = message_set_extensions_pb2.message_set_extension3
proto.Extensions[extension1].i = 123
proto.Extensions[extension2].str = 'foo'
+ proto.Extensions[extension3].text = 'bar'
# Serialize using the MessageSet wire format (this is specified in the
# .proto file).
@@ -2407,7 +2417,7 @@ class SerializationTest(unittest.TestCase):
self.assertEqual(
len(serialized),
raw.MergeFromString(serialized))
- self.assertEqual(2, len(raw.item))
+ self.assertEqual(3, len(raw.item))
message1 = message_set_extensions_pb2.TestMessageSetExtension1()
self.assertEqual(
@@ -2421,6 +2431,12 @@ class SerializationTest(unittest.TestCase):
message2.MergeFromString(raw.item[1].message))
self.assertEqual('foo', message2.str)
+ message3 = message_set_extensions_pb2.TestMessageSetExtension3()
+ self.assertEqual(
+ len(raw.item[2].message),
+ message3.MergeFromString(raw.item[2].message))
+ self.assertEqual('bar', message3.text)
+
# Deserialize using the MessageSet wire format.
proto2 = message_set_extensions_pb2.TestMessageSet()
self.assertEqual(
@@ -2428,6 +2444,7 @@ class SerializationTest(unittest.TestCase):
proto2.MergeFromString(serialized))
self.assertEqual(123, proto2.Extensions[extension1].i)
self.assertEqual('foo', proto2.Extensions[extension2].str)
+ self.assertEqual('bar', proto2.Extensions[extension3].text)
# Check byte size.
self.assertEqual(proto2.ByteSize(), len(serialized))
@@ -2757,9 +2774,10 @@ class SerializationTest(unittest.TestCase):
def testInitArgsUnknownFieldName(self):
def InitalizeEmptyMessageWithExtraKeywordArg():
unused_proto = unittest_pb2.TestEmptyMessage(unknown='unknown')
- self._CheckRaises(ValueError,
- InitalizeEmptyMessageWithExtraKeywordArg,
- 'Protocol message has no "unknown" field.')
+ self._CheckRaises(
+ ValueError,
+ InitalizeEmptyMessageWithExtraKeywordArg,
+ 'Protocol message TestEmptyMessage has no "unknown" field.')
def testInitRequiredKwargs(self):
proto = unittest_pb2.TestRequired(a=1, b=1, c=1)
diff --git a/python/google/protobuf/internal/service_reflection_test.py b/python/google/protobuf/internal/service_reflection_test.py
index 98614b77..62900b1d 100755
--- a/python/google/protobuf/internal/service_reflection_test.py
+++ b/python/google/protobuf/internal/service_reflection_test.py
@@ -34,10 +34,12 @@
__author__ = 'petar@google.com (Petar Petrov)'
+
try:
- import unittest2 as unittest
+ import unittest2 as unittest #PY26
except ImportError:
import unittest
+
from google.protobuf import unittest_pb2
from google.protobuf import service_reflection
from google.protobuf import service
diff --git a/python/google/protobuf/internal/symbol_database_test.py b/python/google/protobuf/internal/symbol_database_test.py
index 0cb935a8..4f5173b2 100644
--- a/python/google/protobuf/internal/symbol_database_test.py
+++ b/python/google/protobuf/internal/symbol_database_test.py
@@ -33,31 +33,34 @@
"""Tests for google.protobuf.symbol_database."""
try:
- import unittest2 as unittest
+ import unittest2 as unittest #PY26
except ImportError:
import unittest
+
from google.protobuf import unittest_pb2
from google.protobuf import descriptor
+from google.protobuf import descriptor_pool
from google.protobuf import symbol_database
+
class SymbolDatabaseTest(unittest.TestCase):
def _Database(self):
- # TODO(b/17734095): Remove this difference when the C++ implementation
- # supports multiple databases.
if descriptor._USE_C_DESCRIPTORS:
- return symbol_database.Default()
+ # The C++ implementation does not allow mixing descriptors from
+ # different pools.
+ db = symbol_database.SymbolDatabase(pool=descriptor_pool.Default())
else:
db = symbol_database.SymbolDatabase()
- # Register representative types from unittest_pb2.
- db.RegisterFileDescriptor(unittest_pb2.DESCRIPTOR)
- db.RegisterMessage(unittest_pb2.TestAllTypes)
- db.RegisterMessage(unittest_pb2.TestAllTypes.NestedMessage)
- db.RegisterMessage(unittest_pb2.TestAllTypes.OptionalGroup)
- db.RegisterMessage(unittest_pb2.TestAllTypes.RepeatedGroup)
- db.RegisterEnumDescriptor(unittest_pb2.ForeignEnum.DESCRIPTOR)
- db.RegisterEnumDescriptor(unittest_pb2.TestAllTypes.NestedEnum.DESCRIPTOR)
- return db
+ # Register representative types from unittest_pb2.
+ db.RegisterFileDescriptor(unittest_pb2.DESCRIPTOR)
+ db.RegisterMessage(unittest_pb2.TestAllTypes)
+ db.RegisterMessage(unittest_pb2.TestAllTypes.NestedMessage)
+ db.RegisterMessage(unittest_pb2.TestAllTypes.OptionalGroup)
+ db.RegisterMessage(unittest_pb2.TestAllTypes.RepeatedGroup)
+ db.RegisterEnumDescriptor(unittest_pb2.ForeignEnum.DESCRIPTOR)
+ db.RegisterEnumDescriptor(unittest_pb2.TestAllTypes.NestedEnum.DESCRIPTOR)
+ return db
def testGetPrototype(self):
instance = self._Database().GetPrototype(
diff --git a/python/google/protobuf/internal/test_util.py b/python/google/protobuf/internal/test_util.py
index ac88fa81..2c805599 100755
--- a/python/google/protobuf/internal/test_util.py
+++ b/python/google/protobuf/internal/test_util.py
@@ -38,6 +38,8 @@ __author__ = 'robinson@google.com (Will Robinson)'
import os.path
+import sys
+
from google.protobuf import unittest_import_pb2
from google.protobuf import unittest_pb2
from google.protobuf import descriptor_pb2
diff --git a/python/google/protobuf/internal/text_encoding_test.py b/python/google/protobuf/internal/text_encoding_test.py
index 338a287b..c7d182c4 100755
--- a/python/google/protobuf/internal/text_encoding_test.py
+++ b/python/google/protobuf/internal/text_encoding_test.py
@@ -33,9 +33,10 @@
"""Tests for google.protobuf.text_encoding."""
try:
- import unittest2 as unittest
+ import unittest2 as unittest #PY26
except ImportError:
import unittest
+
from google.protobuf import text_encoding
TEST_VALUES = [
diff --git a/python/google/protobuf/internal/text_format_test.py b/python/google/protobuf/internal/text_format_test.py
index cca0ee63..0e38e0e9 100755
--- a/python/google/protobuf/internal/text_format_test.py
+++ b/python/google/protobuf/internal/text_format_test.py
@@ -40,19 +40,36 @@ import six
import string
try:
- import unittest2 as unittest
+ import unittest2 as unittest # PY26, pylint: disable=g-import-not-at-top
except ImportError:
- import unittest
+ import unittest # pylint: disable=g-import-not-at-top
+
from google.protobuf.internal import _parameterized
+from google.protobuf import any_test_pb2
from google.protobuf import map_unittest_pb2
from google.protobuf import unittest_mset_pb2
from google.protobuf import unittest_pb2
from google.protobuf import unittest_proto3_arena_pb2
from google.protobuf.internal import api_implementation
from google.protobuf.internal import test_util
+from google.protobuf.internal import message_set_extensions_pb2
+from google.protobuf import descriptor_pool
from google.protobuf import text_format
+
+# Low-level nuts-n-bolts tests.
+class SimpleTextFormatTests(unittest.TestCase):
+
+ # The members of _QUOTES are formatted into a regexp template that
+ # expects single characters. Therefore it's an error (in addition to being
+ # non-sensical in the first place) to try to specify a "quote mark" that is
+ # more than one character.
+ def testQuoteMarksAreSingleChars(self):
+ for quote in text_format._QUOTES:
+ self.assertEqual(1, len(quote))
+
+
# Base class with some common functionality.
class TextFormatBase(unittest.TestCase):
@@ -75,13 +92,11 @@ class TextFormatBase(unittest.TestCase):
.replace('e-0','e-').replace('e-0','e-')
# Floating point fields are printed with .0 suffix even if they are
# actualy integer numbers.
- text = re.compile('\.0$', re.MULTILINE).sub('', text)
+ text = re.compile(r'\.0$', re.MULTILINE).sub('', text)
return text
-@_parameterized.Parameters(
- (unittest_pb2),
- (unittest_proto3_arena_pb2))
+@_parameterized.Parameters((unittest_pb2), (unittest_proto3_arena_pb2))
class TextFormatTest(TextFormatBase):
def testPrintExotic(self, message_module):
@@ -105,8 +120,10 @@ class TextFormatTest(TextFormatBase):
'repeated_string: "\\303\\274\\352\\234\\237"\n')
def testPrintExoticUnicodeSubclass(self, message_module):
+
class UnicodeSub(six.text_type):
pass
+
message = message_module.TestAllTypes()
message.repeated_string.append(UnicodeSub(u'\u00fc\ua71f'))
self.CompareToGoldenText(
@@ -150,8 +167,8 @@ class TextFormatTest(TextFormatBase):
message.repeated_string.append('\000\001\a\b\f\n\r\t\v\\\'"')
message.repeated_string.append(u'\u00fc\ua71f')
self.CompareToGoldenText(
- self.RemoveRedundantZeros(
- text_format.MessageToString(message, as_one_line=True)),
+ self.RemoveRedundantZeros(text_format.MessageToString(
+ message, as_one_line=True)),
'repeated_int64: -9223372036854775808'
' repeated_uint64: 18446744073709551615'
' repeated_double: 123.456'
@@ -172,21 +189,23 @@ class TextFormatTest(TextFormatBase):
message.repeated_string.append(u'\u00fc\ua71f')
# Test as_utf8 = False.
- wire_text = text_format.MessageToString(
- message, as_one_line=True, as_utf8=False)
+ wire_text = text_format.MessageToString(message,
+ as_one_line=True,
+ as_utf8=False)
parsed_message = message_module.TestAllTypes()
r = text_format.Parse(wire_text, parsed_message)
self.assertIs(r, parsed_message)
self.assertEqual(message, parsed_message)
# Test as_utf8 = True.
- wire_text = text_format.MessageToString(
- message, as_one_line=True, as_utf8=True)
+ wire_text = text_format.MessageToString(message,
+ as_one_line=True,
+ as_utf8=True)
parsed_message = message_module.TestAllTypes()
r = text_format.Parse(wire_text, parsed_message)
self.assertIs(r, parsed_message)
self.assertEqual(message, parsed_message,
- '\n%s != %s' % (message, parsed_message))
+ '\n%s != %s' % (message, parsed_message))
def testPrintRawUtf8String(self, message_module):
message = message_module.TestAllTypes()
@@ -196,7 +215,7 @@ class TextFormatTest(TextFormatBase):
parsed_message = message_module.TestAllTypes()
text_format.Parse(text, parsed_message)
self.assertEqual(message, parsed_message,
- '\n%s != %s' % (message, parsed_message))
+ '\n%s != %s' % (message, parsed_message))
def testPrintFloatFormat(self, message_module):
# Check that float_format argument is passed to sub-message formatting.
@@ -217,14 +236,15 @@ class TextFormatTest(TextFormatBase):
message.payload.repeated_double.append(.000078900)
formatted_fields = ['optional_float: 1.25',
'optional_double: -3.45678901234568e-6',
- 'repeated_float: -5642',
- 'repeated_double: 7.89e-5']
+ 'repeated_float: -5642', 'repeated_double: 7.89e-5']
text_message = text_format.MessageToString(message, float_format='.15g')
self.CompareToGoldenText(
self.RemoveRedundantZeros(text_message),
- 'payload {{\n {0}\n {1}\n {2}\n {3}\n}}\n'.format(*formatted_fields))
+ 'payload {{\n {0}\n {1}\n {2}\n {3}\n}}\n'.format(
+ *formatted_fields))
# as_one_line=True is a separate code branch where float_format is passed.
- text_message = text_format.MessageToString(message, as_one_line=True,
+ text_message = text_format.MessageToString(message,
+ as_one_line=True,
float_format='.15g')
self.CompareToGoldenText(
self.RemoveRedundantZeros(text_message),
@@ -235,6 +255,36 @@ class TextFormatTest(TextFormatBase):
message.c = 123
self.assertEqual('c: 123\n', str(message))
+ def testPrintField(self, message_module):
+ message = message_module.TestAllTypes()
+ field = message.DESCRIPTOR.fields_by_name['optional_float']
+ value = message.optional_float
+ out = text_format.TextWriter(False)
+ text_format.PrintField(field, value, out)
+ self.assertEqual('optional_float: 0.0\n', out.getvalue())
+ out.close()
+ # Test Printer
+ out = text_format.TextWriter(False)
+ printer = text_format._Printer(out)
+ printer.PrintField(field, value)
+ self.assertEqual('optional_float: 0.0\n', out.getvalue())
+ out.close()
+
+ def testPrintFieldValue(self, message_module):
+ message = message_module.TestAllTypes()
+ field = message.DESCRIPTOR.fields_by_name['optional_float']
+ value = message.optional_float
+ out = text_format.TextWriter(False)
+ text_format.PrintFieldValue(field, value, out)
+ self.assertEqual('0.0', out.getvalue())
+ out.close()
+ # Test Printer
+ out = text_format.TextWriter(False)
+ printer = text_format._Printer(out)
+ printer.PrintFieldValue(field, value)
+ self.assertEqual('0.0', out.getvalue())
+ out.close()
+
def testParseAllFields(self, message_module):
message = message_module.TestAllTypes()
test_util.SetAllFields(message)
@@ -266,8 +316,7 @@ class TextFormatTest(TextFormatBase):
self.assertEqual(123.456, message.repeated_double[0])
self.assertEqual(1.23e22, message.repeated_double[1])
self.assertEqual(1.23e-18, message.repeated_double[2])
- self.assertEqual(
- '\000\001\a\b\f\n\r\t\v\\\'"', message.repeated_string[0])
+ self.assertEqual('\000\001\a\b\f\n\r\t\v\\\'"', message.repeated_string[0])
self.assertEqual('foocorgegrault', message.repeated_string[1])
self.assertEqual(u'\u00fc\ua71f', message.repeated_string[2])
self.assertEqual(u'\u00fc', message.repeated_string[3])
@@ -287,6 +336,31 @@ class TextFormatTest(TextFormatBase):
self.assertEqual(u'one', message.repeated_string[0])
self.assertEqual(u'two', message.repeated_string[1])
+ def testParseRepeatedScalarShortFormat(self, message_module):
+ message = message_module.TestAllTypes()
+ text = ('repeated_int64: [100, 200];\n'
+ 'repeated_int64: 300,\n'
+ 'repeated_string: ["one", "two"];\n')
+ text_format.Parse(text, message)
+
+ self.assertEqual(100, message.repeated_int64[0])
+ self.assertEqual(200, message.repeated_int64[1])
+ self.assertEqual(300, message.repeated_int64[2])
+ self.assertEqual(u'one', message.repeated_string[0])
+ self.assertEqual(u'two', message.repeated_string[1])
+
+ def testParseRepeatedMessageShortFormat(self, message_module):
+ message = message_module.TestAllTypes()
+ text = ('repeated_nested_message: [{bb: 100}, {bb: 200}],\n'
+ 'repeated_nested_message: {bb: 300}\n'
+ 'repeated_nested_message [{bb: 400}];\n')
+ text_format.Parse(text, message)
+
+ self.assertEqual(100, message.repeated_nested_message[0].bb)
+ self.assertEqual(200, message.repeated_nested_message[1].bb)
+ self.assertEqual(300, message.repeated_nested_message[2].bb)
+ self.assertEqual(400, message.repeated_nested_message[3].bb)
+
def testParseEmptyText(self, message_module):
message = message_module.TestAllTypes()
text = ''
@@ -301,45 +375,38 @@ class TextFormatTest(TextFormatBase):
def testParseSingleWord(self, message_module):
message = message_module.TestAllTypes()
text = 'foo'
- six.assertRaisesRegex(self,
- text_format.ParseError,
- (r'1:1 : Message type "\w+.TestAllTypes" has no field named '
- r'"foo".'),
- text_format.Parse, text, message)
+ six.assertRaisesRegex(self, text_format.ParseError, (
+ r'1:1 : Message type "\w+.TestAllTypes" has no field named '
+ r'"foo".'), text_format.Parse, text, message)
def testParseUnknownField(self, message_module):
message = message_module.TestAllTypes()
text = 'unknown_field: 8\n'
- six.assertRaisesRegex(self,
- text_format.ParseError,
- (r'1:1 : Message type "\w+.TestAllTypes" has no field named '
- r'"unknown_field".'),
- text_format.Parse, text, message)
+ six.assertRaisesRegex(self, text_format.ParseError, (
+ r'1:1 : Message type "\w+.TestAllTypes" has no field named '
+ r'"unknown_field".'), text_format.Parse, text, message)
def testParseBadEnumValue(self, message_module):
message = message_module.TestAllTypes()
text = 'optional_nested_enum: BARR'
- six.assertRaisesRegex(self,
- text_format.ParseError,
- (r'1:23 : Enum type "\w+.TestAllTypes.NestedEnum" '
- r'has no value named BARR.'),
- text_format.Parse, text, message)
+ six.assertRaisesRegex(self, text_format.ParseError,
+ (r'1:23 : Enum type "\w+.TestAllTypes.NestedEnum" '
+ r'has no value named BARR.'), text_format.Parse,
+ text, message)
message = message_module.TestAllTypes()
text = 'optional_nested_enum: 100'
- six.assertRaisesRegex(self,
- text_format.ParseError,
- (r'1:23 : Enum type "\w+.TestAllTypes.NestedEnum" '
- r'has no value with number 100.'),
- text_format.Parse, text, message)
+ six.assertRaisesRegex(self, text_format.ParseError,
+ (r'1:23 : Enum type "\w+.TestAllTypes.NestedEnum" '
+ r'has no value with number 100.'), text_format.Parse,
+ text, message)
def testParseBadIntValue(self, message_module):
message = message_module.TestAllTypes()
text = 'optional_int32: bork'
- six.assertRaisesRegex(self,
- text_format.ParseError,
- ('1:17 : Couldn\'t parse integer: bork'),
- text_format.Parse, text, message)
+ six.assertRaisesRegex(self, text_format.ParseError,
+ ('1:17 : Couldn\'t parse integer: bork'),
+ text_format.Parse, text, message)
def testParseStringFieldUnescape(self, message_module):
message = message_module.TestAllTypes()
@@ -349,6 +416,7 @@ class TextFormatTest(TextFormatBase):
repeated_string: "\\\\xf\\\\x62"
repeated_string: "\\\\\xf\\\\\x62"
repeated_string: "\x5cx20"'''
+
text_format.Parse(text, message)
SLASH = '\\'
@@ -363,8 +431,7 @@ class TextFormatTest(TextFormatBase):
def testMergeDuplicateScalars(self, message_module):
message = message_module.TestAllTypes()
- text = ('optional_int32: 42 '
- 'optional_int32: 67')
+ text = ('optional_int32: 42 ' 'optional_int32: 67')
r = text_format.Merge(text, message)
self.assertIs(r, message)
self.assertEqual(67, message.optional_int32)
@@ -384,6 +451,17 @@ class TextFormatTest(TextFormatBase):
text_format.Parse(text_format.MessageToString(m), m2)
self.assertEqual('oneof_uint32', m2.WhichOneof('oneof_field'))
+ def testParseMultipleOneof(self, message_module):
+ m_string = '\n'.join(['oneof_uint32: 11', 'oneof_string: "foo"'])
+ m2 = message_module.TestAllTypes()
+ if message_module is unittest_pb2:
+ with self.assertRaisesRegexp(text_format.ParseError,
+ ' is specified along with field '):
+ text_format.Parse(m_string, m2)
+ else:
+ text_format.Parse(m_string, m2)
+ self.assertEqual('oneof_string', m2.WhichOneof('oneof_field'))
+
# These are tests that aren't fundamentally specific to proto2, but are at
# the moment because of differences between the proto2 and proto3 test schemas.
@@ -394,12 +472,13 @@ class OnlyWorksWithProto2RightNowTests(TextFormatBase):
message = unittest_pb2.TestAllTypes()
test_util.SetAllFields(message)
self.CompareToGoldenFile(
- self.RemoveRedundantZeros(
- text_format.MessageToString(message, pointy_brackets=True)),
+ self.RemoveRedundantZeros(text_format.MessageToString(
+ message, pointy_brackets=True)),
'text_format_unittest_data_pointy_oneof.txt')
def testParseGolden(self):
- golden_text = '\n'.join(self.ReadGolden('text_format_unittest_data.txt'))
+ golden_text = '\n'.join(self.ReadGolden(
+ 'text_format_unittest_data_oneof_implemented.txt'))
parsed_message = unittest_pb2.TestAllTypes()
r = text_format.Parse(golden_text, parsed_message)
self.assertIs(r, parsed_message)
@@ -415,14 +494,6 @@ class OnlyWorksWithProto2RightNowTests(TextFormatBase):
self.RemoveRedundantZeros(text_format.MessageToString(message)),
'text_format_unittest_data_oneof_implemented.txt')
- def testPrintAllFieldsPointy(self):
- message = unittest_pb2.TestAllTypes()
- test_util.SetAllFields(message)
- self.CompareToGoldenFile(
- self.RemoveRedundantZeros(
- text_format.MessageToString(message, pointy_brackets=True)),
- 'text_format_unittest_data_pointy_oneof.txt')
-
def testPrintInIndexOrder(self):
message = unittest_pb2.TestFieldOrderings()
message.my_string = '115'
@@ -436,13 +507,12 @@ class OnlyWorksWithProto2RightNowTests(TextFormatBase):
'my_string: \"115\"\nmy_int: 101\nmy_float: 111\n'
'optional_nested_message {\n oo: 0\n bb: 1\n}\n')
self.CompareToGoldenText(
- self.RemoveRedundantZeros(text_format.MessageToString(
- message)),
+ self.RemoveRedundantZeros(text_format.MessageToString(message)),
'my_int: 101\nmy_string: \"115\"\nmy_float: 111\n'
'optional_nested_message {\n bb: 1\n oo: 0\n}\n')
def testMergeLinesGolden(self):
- opened = self.ReadGolden('text_format_unittest_data.txt')
+ opened = self.ReadGolden('text_format_unittest_data_oneof_implemented.txt')
parsed_message = unittest_pb2.TestAllTypes()
r = text_format.MergeLines(opened, parsed_message)
self.assertIs(r, parsed_message)
@@ -452,7 +522,7 @@ class OnlyWorksWithProto2RightNowTests(TextFormatBase):
self.assertEqual(message, parsed_message)
def testParseLinesGolden(self):
- opened = self.ReadGolden('text_format_unittest_data.txt')
+ opened = self.ReadGolden('text_format_unittest_data_oneof_implemented.txt')
parsed_message = unittest_pb2.TestAllTypes()
r = text_format.ParseLines(opened, parsed_message)
self.assertIs(r, parsed_message)
@@ -468,14 +538,13 @@ class OnlyWorksWithProto2RightNowTests(TextFormatBase):
message.map_int64_int64[-2**33] = -2**34
message.map_uint32_uint32[123] = 456
message.map_uint64_uint64[2**33] = 2**34
- message.map_string_string["abc"] = "123"
+ message.map_string_string['abc'] = '123'
message.map_int32_foreign_message[111].c = 5
# Maps are serialized to text format using their underlying repeated
# representation.
self.CompareToGoldenText(
- text_format.MessageToString(message),
- 'map_int32_int32 {\n'
+ text_format.MessageToString(message), 'map_int32_int32 {\n'
' key: -123\n'
' value: -456\n'
'}\n'
@@ -508,9 +577,8 @@ class OnlyWorksWithProto2RightNowTests(TextFormatBase):
message.map_string_string[letter] = 'dummy'
for letter in reversed(string.ascii_uppercase[0:13]):
message.map_string_string[letter] = 'dummy'
- golden = ''.join((
- 'map_string_string {\n key: "%c"\n value: "dummy"\n}\n' % (letter,)
- for letter in string.ascii_uppercase))
+ golden = ''.join(('map_string_string {\n key: "%c"\n value: "dummy"\n}\n'
+ % (letter,) for letter in string.ascii_uppercase))
self.CompareToGoldenText(text_format.MessageToString(message), golden)
def testMapOrderSemantics(self):
@@ -518,9 +586,7 @@ class OnlyWorksWithProto2RightNowTests(TextFormatBase):
# The C++ implementation emits defaulted-value fields, while the Python
# implementation does not. Adjusting for this is awkward, but it is
# valuable to test against a common golden file.
- line_blacklist = (' key: 0\n',
- ' value: 0\n',
- ' key: false\n',
+ line_blacklist = (' key: 0\n', ' value: 0\n', ' key: false\n',
' value: false\n')
golden_lines = [line for line in golden_lines if line not in line_blacklist]
@@ -543,8 +609,7 @@ class Proto2Tests(TextFormatBase):
message.message_set.Extensions[ext1].i = 23
message.message_set.Extensions[ext2].str = 'foo'
self.CompareToGoldenText(
- text_format.MessageToString(message),
- 'message_set {\n'
+ text_format.MessageToString(message), 'message_set {\n'
' [protobuf_unittest.TestMessageSetExtension1] {\n'
' i: 23\n'
' }\n'
@@ -553,6 +618,33 @@ class Proto2Tests(TextFormatBase):
' }\n'
'}\n')
+ message = message_set_extensions_pb2.TestMessageSet()
+ ext = message_set_extensions_pb2.message_set_extension3
+ message.Extensions[ext].text = 'bar'
+ self.CompareToGoldenText(
+ text_format.MessageToString(message),
+ '[google.protobuf.internal.TestMessageSetExtension3] {\n'
+ ' text: \"bar\"\n'
+ '}\n')
+
+ def testPrintMessageSetByFieldNumber(self):
+ out = text_format.TextWriter(False)
+ message = unittest_mset_pb2.TestMessageSetContainer()
+ ext1 = unittest_mset_pb2.TestMessageSetExtension1.message_set_extension
+ ext2 = unittest_mset_pb2.TestMessageSetExtension2.message_set_extension
+ message.message_set.Extensions[ext1].i = 23
+ message.message_set.Extensions[ext2].str = 'foo'
+ text_format.PrintMessage(message, out, use_field_number=True)
+ self.CompareToGoldenText(out.getvalue(), '1 {\n'
+ ' 1545008 {\n'
+ ' 15: 23\n'
+ ' }\n'
+ ' 1547769 {\n'
+ ' 25: \"foo\"\n'
+ ' }\n'
+ '}\n')
+ out.close()
+
def testPrintMessageSetAsOneLine(self):
message = unittest_mset_pb2.TestMessageSetContainer()
ext1 = unittest_mset_pb2.TestMessageSetExtension1.message_set_extension
@@ -572,8 +664,7 @@ class Proto2Tests(TextFormatBase):
def testParseMessageSet(self):
message = unittest_pb2.TestAllTypes()
- text = ('repeated_uint64: 1\n'
- 'repeated_uint64: 2\n')
+ text = ('repeated_uint64: 1\n' 'repeated_uint64: 2\n')
text_format.Parse(text, message)
self.assertEqual(1, message.repeated_uint64[0])
self.assertEqual(2, message.repeated_uint64[1])
@@ -593,6 +684,47 @@ class Proto2Tests(TextFormatBase):
self.assertEqual(23, message.message_set.Extensions[ext1].i)
self.assertEqual('foo', message.message_set.Extensions[ext2].str)
+ def testParseMessageByFieldNumber(self):
+ message = unittest_pb2.TestAllTypes()
+ text = ('34: 1\n' 'repeated_uint64: 2\n')
+ text_format.Parse(text, message, allow_field_number=True)
+ self.assertEqual(1, message.repeated_uint64[0])
+ self.assertEqual(2, message.repeated_uint64[1])
+
+ message = unittest_mset_pb2.TestMessageSetContainer()
+ text = ('1 {\n'
+ ' 1545008 {\n'
+ ' 15: 23\n'
+ ' }\n'
+ ' 1547769 {\n'
+ ' 25: \"foo\"\n'
+ ' }\n'
+ '}\n')
+ text_format.Parse(text, message, allow_field_number=True)
+ ext1 = unittest_mset_pb2.TestMessageSetExtension1.message_set_extension
+ ext2 = unittest_mset_pb2.TestMessageSetExtension2.message_set_extension
+ self.assertEqual(23, message.message_set.Extensions[ext1].i)
+ self.assertEqual('foo', message.message_set.Extensions[ext2].str)
+
+ # Can't parse field number without set allow_field_number=True.
+ message = unittest_pb2.TestAllTypes()
+ text = '34:1\n'
+ six.assertRaisesRegex(self, text_format.ParseError, (
+ r'1:1 : Message type "\w+.TestAllTypes" has no field named '
+ r'"34".'), text_format.Parse, text, message)
+
+ # Can't parse if field number is not found.
+ text = '1234:1\n'
+ six.assertRaisesRegex(
+ self,
+ text_format.ParseError,
+ (r'1:1 : Message type "\w+.TestAllTypes" has no field named '
+ r'"1234".'),
+ text_format.Parse,
+ text,
+ message,
+ allow_field_number=True)
+
def testPrintAllExtensions(self):
message = unittest_pb2.TestAllExtensions()
test_util.SetAllExtensions(message)
@@ -627,70 +759,181 @@ class Proto2Tests(TextFormatBase):
text_format.Parse(ascii_text, parsed_message)
self.assertEqual(message, parsed_message)
+ def testParseAllowedUnknownExtension(self):
+ # Skip over unknown extension correctly.
+ message = unittest_mset_pb2.TestMessageSetContainer()
+ text = ('message_set {\n'
+ ' [unknown_extension] {\n'
+ ' i: 23\n'
+ ' bin: "\xe0"'
+ ' [nested_unknown_ext]: {\n'
+ ' i: 23\n'
+ ' test: "test_string"\n'
+ ' floaty_float: -0.315\n'
+ ' num: -inf\n'
+ ' multiline_str: "abc"\n'
+ ' "def"\n'
+ ' "xyz."\n'
+ ' [nested_unknown_ext]: <\n'
+ ' i: 23\n'
+ ' i: 24\n'
+ ' pointfloat: .3\n'
+ ' test: "test_string"\n'
+ ' floaty_float: -0.315\n'
+ ' num: -inf\n'
+ ' long_string: "test" "test2" \n'
+ ' >\n'
+ ' }\n'
+ ' }\n'
+ ' [unknown_extension]: 5\n'
+ '}\n')
+ text_format.Parse(text, message, allow_unknown_extension=True)
+ golden = 'message_set {\n}\n'
+ self.CompareToGoldenText(text_format.MessageToString(message), golden)
+
+ # Catch parse errors in unknown extension.
+ message = unittest_mset_pb2.TestMessageSetContainer()
+ malformed = ('message_set {\n'
+ ' [unknown_extension] {\n'
+ ' i:\n' # Missing value.
+ ' }\n'
+ '}\n')
+ six.assertRaisesRegex(self,
+ text_format.ParseError,
+ 'Invalid field value: }',
+ text_format.Parse,
+ malformed,
+ message,
+ allow_unknown_extension=True)
+
+ message = unittest_mset_pb2.TestMessageSetContainer()
+ malformed = ('message_set {\n'
+ ' [unknown_extension] {\n'
+ ' str: "malformed string\n' # Missing closing quote.
+ ' }\n'
+ '}\n')
+ six.assertRaisesRegex(self,
+ text_format.ParseError,
+ 'Invalid field value: "',
+ text_format.Parse,
+ malformed,
+ message,
+ allow_unknown_extension=True)
+
+ message = unittest_mset_pb2.TestMessageSetContainer()
+ malformed = ('message_set {\n'
+ ' [unknown_extension] {\n'
+ ' str: "malformed\n multiline\n string\n'
+ ' }\n'
+ '}\n')
+ six.assertRaisesRegex(self,
+ text_format.ParseError,
+ 'Invalid field value: "',
+ text_format.Parse,
+ malformed,
+ message,
+ allow_unknown_extension=True)
+
+ message = unittest_mset_pb2.TestMessageSetContainer()
+ malformed = ('message_set {\n'
+ ' [malformed_extension] <\n'
+ ' i: -5\n'
+ ' \n' # Missing '>' here.
+ '}\n')
+ six.assertRaisesRegex(self,
+ text_format.ParseError,
+ '5:1 : Expected ">".',
+ text_format.Parse,
+ malformed,
+ message,
+ allow_unknown_extension=True)
+
+ # Don't allow unknown fields with allow_unknown_extension=True.
+ message = unittest_mset_pb2.TestMessageSetContainer()
+ malformed = ('message_set {\n'
+ ' unknown_field: true\n'
+ ' \n' # Missing '>' here.
+ '}\n')
+ six.assertRaisesRegex(self,
+ text_format.ParseError,
+ ('2:3 : Message type '
+ '"proto2_wireformat_unittest.TestMessageSet" has no'
+ ' field named "unknown_field".'),
+ text_format.Parse,
+ malformed,
+ message,
+ allow_unknown_extension=True)
+
+ # Parse known extension correcty.
+ message = unittest_mset_pb2.TestMessageSetContainer()
+ text = ('message_set {\n'
+ ' [protobuf_unittest.TestMessageSetExtension1] {\n'
+ ' i: 23\n'
+ ' }\n'
+ ' [protobuf_unittest.TestMessageSetExtension2] {\n'
+ ' str: \"foo\"\n'
+ ' }\n'
+ '}\n')
+ text_format.Parse(text, message, allow_unknown_extension=True)
+ ext1 = unittest_mset_pb2.TestMessageSetExtension1.message_set_extension
+ ext2 = unittest_mset_pb2.TestMessageSetExtension2.message_set_extension
+ self.assertEqual(23, message.message_set.Extensions[ext1].i)
+ self.assertEqual('foo', message.message_set.Extensions[ext2].str)
+
def testParseBadExtension(self):
message = unittest_pb2.TestAllExtensions()
text = '[unknown_extension]: 8\n'
- six.assertRaisesRegex(self,
- text_format.ParseError,
- '1:2 : Extension "unknown_extension" not registered.',
- text_format.Parse, text, message)
+ six.assertRaisesRegex(self, text_format.ParseError,
+ '1:2 : Extension "unknown_extension" not registered.',
+ text_format.Parse, text, message)
message = unittest_pb2.TestAllTypes()
- six.assertRaisesRegex(self,
- text_format.ParseError,
- ('1:2 : Message type "protobuf_unittest.TestAllTypes" does not have '
- 'extensions.'),
- text_format.Parse, text, message)
+ six.assertRaisesRegex(self, text_format.ParseError, (
+ '1:2 : Message type "protobuf_unittest.TestAllTypes" does not have '
+ 'extensions.'), text_format.Parse, text, message)
def testMergeDuplicateExtensionScalars(self):
message = unittest_pb2.TestAllExtensions()
text = ('[protobuf_unittest.optional_int32_extension]: 42 '
'[protobuf_unittest.optional_int32_extension]: 67')
text_format.Merge(text, message)
- self.assertEqual(
- 67,
- message.Extensions[unittest_pb2.optional_int32_extension])
+ self.assertEqual(67,
+ message.Extensions[unittest_pb2.optional_int32_extension])
def testParseDuplicateExtensionScalars(self):
message = unittest_pb2.TestAllExtensions()
text = ('[protobuf_unittest.optional_int32_extension]: 42 '
'[protobuf_unittest.optional_int32_extension]: 67')
- six.assertRaisesRegex(self,
- text_format.ParseError,
- ('1:96 : Message type "protobuf_unittest.TestAllExtensions" '
- 'should not have multiple '
- '"protobuf_unittest.optional_int32_extension" extensions.'),
- text_format.Parse, text, message)
+ six.assertRaisesRegex(self, text_format.ParseError, (
+ '1:96 : Message type "protobuf_unittest.TestAllExtensions" '
+ 'should not have multiple '
+ '"protobuf_unittest.optional_int32_extension" extensions.'),
+ text_format.Parse, text, message)
def testParseDuplicateNestedMessageScalars(self):
message = unittest_pb2.TestAllTypes()
text = ('optional_nested_message { bb: 1 } '
'optional_nested_message { bb: 2 }')
- six.assertRaisesRegex(self,
- text_format.ParseError,
- ('1:65 : Message type "protobuf_unittest.TestAllTypes.NestedMessage" '
- 'should not have multiple "bb" fields.'),
- text_format.Parse, text, message)
+ six.assertRaisesRegex(self, text_format.ParseError, (
+ '1:65 : Message type "protobuf_unittest.TestAllTypes.NestedMessage" '
+ 'should not have multiple "bb" fields.'), text_format.Parse, text,
+ message)
def testParseDuplicateScalars(self):
message = unittest_pb2.TestAllTypes()
- text = ('optional_int32: 42 '
- 'optional_int32: 67')
- six.assertRaisesRegex(self,
- text_format.ParseError,
- ('1:36 : Message type "protobuf_unittest.TestAllTypes" should not '
- 'have multiple "optional_int32" fields.'),
- text_format.Parse, text, message)
+ text = ('optional_int32: 42 ' 'optional_int32: 67')
+ six.assertRaisesRegex(self, text_format.ParseError, (
+ '1:36 : Message type "protobuf_unittest.TestAllTypes" should not '
+ 'have multiple "optional_int32" fields.'), text_format.Parse, text,
+ message)
def testParseGroupNotClosed(self):
message = unittest_pb2.TestAllTypes()
text = 'RepeatedGroup: <'
- six.assertRaisesRegex(self,
- text_format.ParseError, '1:16 : Expected ">".',
- text_format.Parse, text, message)
+ six.assertRaisesRegex(self, text_format.ParseError, '1:16 : Expected ">".',
+ text_format.Parse, text, message)
text = 'RepeatedGroup: {'
- six.assertRaisesRegex(self,
- text_format.ParseError, '1:16 : Expected "}".',
- text_format.Parse, text, message)
+ six.assertRaisesRegex(self, text_format.ParseError, '1:16 : Expected "}".',
+ text_format.Parse, text, message)
def testParseEmptyGroup(self):
message = unittest_pb2.TestAllTypes()
@@ -741,10 +984,197 @@ class Proto2Tests(TextFormatBase):
self.assertEqual(-2**34, message.map_int64_int64[-2**33])
self.assertEqual(456, message.map_uint32_uint32[123])
self.assertEqual(2**34, message.map_uint64_uint64[2**33])
- self.assertEqual("123", message.map_string_string["abc"])
+ self.assertEqual('123', message.map_string_string['abc'])
self.assertEqual(5, message.map_int32_foreign_message[111].c)
+class Proto3Tests(unittest.TestCase):
+
+ def testPrintMessageExpandAny(self):
+ packed_message = unittest_pb2.OneString()
+ packed_message.data = 'string'
+ message = any_test_pb2.TestAny()
+ message.any_value.Pack(packed_message)
+ self.assertEqual(
+ text_format.MessageToString(message,
+ descriptor_pool=descriptor_pool.Default()),
+ 'any_value {\n'
+ ' [type.googleapis.com/protobuf_unittest.OneString] {\n'
+ ' data: "string"\n'
+ ' }\n'
+ '}\n')
+
+ def testPrintMessageExpandAnyRepeated(self):
+ packed_message = unittest_pb2.OneString()
+ message = any_test_pb2.TestAny()
+ packed_message.data = 'string0'
+ message.repeated_any_value.add().Pack(packed_message)
+ packed_message.data = 'string1'
+ message.repeated_any_value.add().Pack(packed_message)
+ self.assertEqual(
+ text_format.MessageToString(message,
+ descriptor_pool=descriptor_pool.Default()),
+ 'repeated_any_value {\n'
+ ' [type.googleapis.com/protobuf_unittest.OneString] {\n'
+ ' data: "string0"\n'
+ ' }\n'
+ '}\n'
+ 'repeated_any_value {\n'
+ ' [type.googleapis.com/protobuf_unittest.OneString] {\n'
+ ' data: "string1"\n'
+ ' }\n'
+ '}\n')
+
+ def testPrintMessageExpandAnyNoDescriptorPool(self):
+ packed_message = unittest_pb2.OneString()
+ packed_message.data = 'string'
+ message = any_test_pb2.TestAny()
+ message.any_value.Pack(packed_message)
+ self.assertEqual(
+ text_format.MessageToString(message, descriptor_pool=None),
+ 'any_value {\n'
+ ' type_url: "type.googleapis.com/protobuf_unittest.OneString"\n'
+ ' value: "\\n\\006string"\n'
+ '}\n')
+
+ def testPrintMessageExpandAnyDescriptorPoolMissingType(self):
+ packed_message = unittest_pb2.OneString()
+ packed_message.data = 'string'
+ message = any_test_pb2.TestAny()
+ message.any_value.Pack(packed_message)
+ empty_pool = descriptor_pool.DescriptorPool()
+ self.assertEqual(
+ text_format.MessageToString(message, descriptor_pool=empty_pool),
+ 'any_value {\n'
+ ' type_url: "type.googleapis.com/protobuf_unittest.OneString"\n'
+ ' value: "\\n\\006string"\n'
+ '}\n')
+
+ def testPrintMessageExpandAnyPointyBrackets(self):
+ packed_message = unittest_pb2.OneString()
+ packed_message.data = 'string'
+ message = any_test_pb2.TestAny()
+ message.any_value.Pack(packed_message)
+ self.assertEqual(
+ text_format.MessageToString(message,
+ pointy_brackets=True,
+ descriptor_pool=descriptor_pool.Default()),
+ 'any_value <\n'
+ ' [type.googleapis.com/protobuf_unittest.OneString] <\n'
+ ' data: "string"\n'
+ ' >\n'
+ '>\n')
+
+ def testPrintMessageExpandAnyAsOneLine(self):
+ packed_message = unittest_pb2.OneString()
+ packed_message.data = 'string'
+ message = any_test_pb2.TestAny()
+ message.any_value.Pack(packed_message)
+ self.assertEqual(
+ text_format.MessageToString(message,
+ as_one_line=True,
+ descriptor_pool=descriptor_pool.Default()),
+ 'any_value {'
+ ' [type.googleapis.com/protobuf_unittest.OneString]'
+ ' { data: "string" } '
+ '}')
+
+ def testPrintMessageExpandAnyAsOneLinePointyBrackets(self):
+ packed_message = unittest_pb2.OneString()
+ packed_message.data = 'string'
+ message = any_test_pb2.TestAny()
+ message.any_value.Pack(packed_message)
+ self.assertEqual(
+ text_format.MessageToString(message,
+ as_one_line=True,
+ pointy_brackets=True,
+ descriptor_pool=descriptor_pool.Default()),
+ 'any_value <'
+ ' [type.googleapis.com/protobuf_unittest.OneString]'
+ ' < data: "string" > '
+ '>')
+
+ def testMergeExpandedAny(self):
+ message = any_test_pb2.TestAny()
+ text = ('any_value {\n'
+ ' [type.googleapis.com/protobuf_unittest.OneString] {\n'
+ ' data: "string"\n'
+ ' }\n'
+ '}\n')
+ text_format.Merge(text, message, descriptor_pool=descriptor_pool.Default())
+ packed_message = unittest_pb2.OneString()
+ message.any_value.Unpack(packed_message)
+ self.assertEqual('string', packed_message.data)
+
+ def testMergeExpandedAnyRepeated(self):
+ message = any_test_pb2.TestAny()
+ text = ('repeated_any_value {\n'
+ ' [type.googleapis.com/protobuf_unittest.OneString] {\n'
+ ' data: "string0"\n'
+ ' }\n'
+ '}\n'
+ 'repeated_any_value {\n'
+ ' [type.googleapis.com/protobuf_unittest.OneString] {\n'
+ ' data: "string1"\n'
+ ' }\n'
+ '}\n')
+ text_format.Merge(text, message, descriptor_pool=descriptor_pool.Default())
+ packed_message = unittest_pb2.OneString()
+ message.repeated_any_value[0].Unpack(packed_message)
+ self.assertEqual('string0', packed_message.data)
+ message.repeated_any_value[1].Unpack(packed_message)
+ self.assertEqual('string1', packed_message.data)
+
+ def testMergeExpandedAnyPointyBrackets(self):
+ message = any_test_pb2.TestAny()
+ text = ('any_value {\n'
+ ' [type.googleapis.com/protobuf_unittest.OneString] <\n'
+ ' data: "string"\n'
+ ' >\n'
+ '}\n')
+ text_format.Merge(text, message, descriptor_pool=descriptor_pool.Default())
+ packed_message = unittest_pb2.OneString()
+ message.any_value.Unpack(packed_message)
+ self.assertEqual('string', packed_message.data)
+
+ def testMergeExpandedAnyNoDescriptorPool(self):
+ message = any_test_pb2.TestAny()
+ text = ('any_value {\n'
+ ' [type.googleapis.com/protobuf_unittest.OneString] {\n'
+ ' data: "string"\n'
+ ' }\n'
+ '}\n')
+ with self.assertRaises(text_format.ParseError) as e:
+ text_format.Merge(text, message, descriptor_pool=None)
+ self.assertEqual(str(e.exception),
+ 'Descriptor pool required to parse expanded Any field')
+
+ def testMergeExpandedAnyDescriptorPoolMissingType(self):
+ message = any_test_pb2.TestAny()
+ text = ('any_value {\n'
+ ' [type.googleapis.com/protobuf_unittest.OneString] {\n'
+ ' data: "string"\n'
+ ' }\n'
+ '}\n')
+ with self.assertRaises(text_format.ParseError) as e:
+ empty_pool = descriptor_pool.DescriptorPool()
+ text_format.Merge(text, message, descriptor_pool=empty_pool)
+ self.assertEqual(
+ str(e.exception),
+ 'Type protobuf_unittest.OneString not found in descriptor pool')
+
+ def testMergeUnexpandedAny(self):
+ text = ('any_value {\n'
+ ' type_url: "type.googleapis.com/protobuf_unittest.OneString"\n'
+ ' value: "\\n\\006string"\n'
+ '}\n')
+ message = any_test_pb2.TestAny()
+ text_format.Merge(text, message)
+ packed_message = unittest_pb2.OneString()
+ message.any_value.Unpack(packed_message)
+ self.assertEqual('string', packed_message.data)
+
+
class TokenizerTest(unittest.TestCase):
def testSimpleTokenCases(self):
@@ -755,79 +1185,55 @@ class TokenizerTest(unittest.TestCase):
'ID9: 22 ID10: -111111111111111111 ID11: -22\n'
'ID12: 2222222222222222222 ID13: 1.23456f ID14: 1.2e+2f '
'false_bool: 0 true_BOOL:t \n true_bool1: 1 false_BOOL1:f ')
- tokenizer = text_format._Tokenizer(text.splitlines())
- methods = [(tokenizer.ConsumeIdentifier, 'identifier1'),
- ':',
+ tokenizer = text_format.Tokenizer(text.splitlines())
+ methods = [(tokenizer.ConsumeIdentifier, 'identifier1'), ':',
(tokenizer.ConsumeString, 'string1'),
- (tokenizer.ConsumeIdentifier, 'identifier2'),
- ':',
- (tokenizer.ConsumeInt32, 123),
- (tokenizer.ConsumeIdentifier, 'identifier3'),
- ':',
+ (tokenizer.ConsumeIdentifier, 'identifier2'), ':',
+ (tokenizer.ConsumeInteger, 123),
+ (tokenizer.ConsumeIdentifier, 'identifier3'), ':',
(tokenizer.ConsumeString, 'string'),
- (tokenizer.ConsumeIdentifier, 'identifiER_4'),
- ':',
+ (tokenizer.ConsumeIdentifier, 'identifiER_4'), ':',
(tokenizer.ConsumeFloat, 1.1e+2),
- (tokenizer.ConsumeIdentifier, 'ID5'),
- ':',
+ (tokenizer.ConsumeIdentifier, 'ID5'), ':',
(tokenizer.ConsumeFloat, -0.23),
- (tokenizer.ConsumeIdentifier, 'ID6'),
- ':',
+ (tokenizer.ConsumeIdentifier, 'ID6'), ':',
(tokenizer.ConsumeString, 'aaaa\'bbbb'),
- (tokenizer.ConsumeIdentifier, 'ID7'),
- ':',
+ (tokenizer.ConsumeIdentifier, 'ID7'), ':',
(tokenizer.ConsumeString, 'aa\"bb'),
- (tokenizer.ConsumeIdentifier, 'ID8'),
- ':',
- '{',
- (tokenizer.ConsumeIdentifier, 'A'),
- ':',
+ (tokenizer.ConsumeIdentifier, 'ID8'), ':', '{',
+ (tokenizer.ConsumeIdentifier, 'A'), ':',
(tokenizer.ConsumeFloat, float('inf')),
- (tokenizer.ConsumeIdentifier, 'B'),
- ':',
+ (tokenizer.ConsumeIdentifier, 'B'), ':',
(tokenizer.ConsumeFloat, -float('inf')),
- (tokenizer.ConsumeIdentifier, 'C'),
- ':',
+ (tokenizer.ConsumeIdentifier, 'C'), ':',
(tokenizer.ConsumeBool, True),
- (tokenizer.ConsumeIdentifier, 'D'),
- ':',
- (tokenizer.ConsumeBool, False),
- '}',
- (tokenizer.ConsumeIdentifier, 'ID9'),
- ':',
- (tokenizer.ConsumeUint32, 22),
- (tokenizer.ConsumeIdentifier, 'ID10'),
- ':',
- (tokenizer.ConsumeInt64, -111111111111111111),
- (tokenizer.ConsumeIdentifier, 'ID11'),
- ':',
- (tokenizer.ConsumeInt32, -22),
- (tokenizer.ConsumeIdentifier, 'ID12'),
- ':',
- (tokenizer.ConsumeUint64, 2222222222222222222),
- (tokenizer.ConsumeIdentifier, 'ID13'),
- ':',
+ (tokenizer.ConsumeIdentifier, 'D'), ':',
+ (tokenizer.ConsumeBool, False), '}',
+ (tokenizer.ConsumeIdentifier, 'ID9'), ':',
+ (tokenizer.ConsumeInteger, 22),
+ (tokenizer.ConsumeIdentifier, 'ID10'), ':',
+ (tokenizer.ConsumeInteger, -111111111111111111),
+ (tokenizer.ConsumeIdentifier, 'ID11'), ':',
+ (tokenizer.ConsumeInteger, -22),
+ (tokenizer.ConsumeIdentifier, 'ID12'), ':',
+ (tokenizer.ConsumeInteger, 2222222222222222222),
+ (tokenizer.ConsumeIdentifier, 'ID13'), ':',
(tokenizer.ConsumeFloat, 1.23456),
- (tokenizer.ConsumeIdentifier, 'ID14'),
- ':',
+ (tokenizer.ConsumeIdentifier, 'ID14'), ':',
(tokenizer.ConsumeFloat, 1.2e+2),
- (tokenizer.ConsumeIdentifier, 'false_bool'),
- ':',
+ (tokenizer.ConsumeIdentifier, 'false_bool'), ':',
(tokenizer.ConsumeBool, False),
- (tokenizer.ConsumeIdentifier, 'true_BOOL'),
- ':',
+ (tokenizer.ConsumeIdentifier, 'true_BOOL'), ':',
(tokenizer.ConsumeBool, True),
- (tokenizer.ConsumeIdentifier, 'true_bool1'),
- ':',
+ (tokenizer.ConsumeIdentifier, 'true_bool1'), ':',
(tokenizer.ConsumeBool, True),
- (tokenizer.ConsumeIdentifier, 'false_BOOL1'),
- ':',
+ (tokenizer.ConsumeIdentifier, 'false_BOOL1'), ':',
(tokenizer.ConsumeBool, False)]
i = 0
while not tokenizer.AtEnd():
m = methods[i]
- if type(m) == str:
+ if isinstance(m, str):
token = tokenizer.token
self.assertEqual(token, m)
tokenizer.NextToken()
@@ -835,59 +1241,119 @@ class TokenizerTest(unittest.TestCase):
self.assertEqual(m[1], m[0]())
i += 1
- def testConsumeIntegers(self):
+ def testConsumeAbstractIntegers(self):
# This test only tests the failures in the integer parsing methods as well
# as the '0' special cases.
int64_max = (1 << 63) - 1
uint32_max = (1 << 32) - 1
text = '-1 %d %d' % (uint32_max + 1, int64_max + 1)
- tokenizer = text_format._Tokenizer(text.splitlines())
- self.assertRaises(text_format.ParseError, tokenizer.ConsumeUint32)
- self.assertRaises(text_format.ParseError, tokenizer.ConsumeUint64)
- self.assertEqual(-1, tokenizer.ConsumeInt32())
+ tokenizer = text_format.Tokenizer(text.splitlines())
+ self.assertEqual(-1, tokenizer.ConsumeInteger())
+
+ self.assertEqual(uint32_max + 1, tokenizer.ConsumeInteger())
+
+ self.assertEqual(int64_max + 1, tokenizer.ConsumeInteger())
+ self.assertTrue(tokenizer.AtEnd())
- self.assertRaises(text_format.ParseError, tokenizer.ConsumeUint32)
- self.assertRaises(text_format.ParseError, tokenizer.ConsumeInt32)
- self.assertEqual(uint32_max + 1, tokenizer.ConsumeInt64())
+ text = '-0 0'
+ tokenizer = text_format.Tokenizer(text.splitlines())
+ self.assertEqual(0, tokenizer.ConsumeInteger())
+ self.assertEqual(0, tokenizer.ConsumeInteger())
+ self.assertTrue(tokenizer.AtEnd())
- self.assertRaises(text_format.ParseError, tokenizer.ConsumeInt64)
- self.assertEqual(int64_max + 1, tokenizer.ConsumeUint64())
+ def testConsumeIntegers(self):
+ # This test only tests the failures in the integer parsing methods as well
+ # as the '0' special cases.
+ int64_max = (1 << 63) - 1
+ uint32_max = (1 << 32) - 1
+ text = '-1 %d %d' % (uint32_max + 1, int64_max + 1)
+ tokenizer = text_format.Tokenizer(text.splitlines())
+ self.assertRaises(text_format.ParseError,
+ text_format._ConsumeUint32, tokenizer)
+ self.assertRaises(text_format.ParseError,
+ text_format._ConsumeUint64, tokenizer)
+ self.assertEqual(-1, text_format._ConsumeInt32(tokenizer))
+
+ self.assertRaises(text_format.ParseError,
+ text_format._ConsumeUint32, tokenizer)
+ self.assertRaises(text_format.ParseError,
+ text_format._ConsumeInt32, tokenizer)
+ self.assertEqual(uint32_max + 1, text_format._ConsumeInt64(tokenizer))
+
+ self.assertRaises(text_format.ParseError,
+ text_format._ConsumeInt64, tokenizer)
+ self.assertEqual(int64_max + 1, text_format._ConsumeUint64(tokenizer))
self.assertTrue(tokenizer.AtEnd())
text = '-0 -0 0 0'
- tokenizer = text_format._Tokenizer(text.splitlines())
- self.assertEqual(0, tokenizer.ConsumeUint32())
- self.assertEqual(0, tokenizer.ConsumeUint64())
- self.assertEqual(0, tokenizer.ConsumeUint32())
- self.assertEqual(0, tokenizer.ConsumeUint64())
+ tokenizer = text_format.Tokenizer(text.splitlines())
+ self.assertEqual(0, text_format._ConsumeUint32(tokenizer))
+ self.assertEqual(0, text_format._ConsumeUint64(tokenizer))
+ self.assertEqual(0, text_format._ConsumeUint32(tokenizer))
+ self.assertEqual(0, text_format._ConsumeUint64(tokenizer))
self.assertTrue(tokenizer.AtEnd())
def testConsumeByteString(self):
text = '"string1\''
- tokenizer = text_format._Tokenizer(text.splitlines())
+ tokenizer = text_format.Tokenizer(text.splitlines())
self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString)
text = 'string1"'
- tokenizer = text_format._Tokenizer(text.splitlines())
+ tokenizer = text_format.Tokenizer(text.splitlines())
self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString)
text = '\n"\\xt"'
- tokenizer = text_format._Tokenizer(text.splitlines())
+ tokenizer = text_format.Tokenizer(text.splitlines())
self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString)
text = '\n"\\"'
- tokenizer = text_format._Tokenizer(text.splitlines())
+ tokenizer = text_format.Tokenizer(text.splitlines())
self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString)
text = '\n"\\x"'
- tokenizer = text_format._Tokenizer(text.splitlines())
+ tokenizer = text_format.Tokenizer(text.splitlines())
self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString)
def testConsumeBool(self):
text = 'not-a-bool'
- tokenizer = text_format._Tokenizer(text.splitlines())
+ tokenizer = text_format.Tokenizer(text.splitlines())
self.assertRaises(text_format.ParseError, tokenizer.ConsumeBool)
+ def testSkipComment(self):
+ tokenizer = text_format.Tokenizer('# some comment'.splitlines())
+ self.assertTrue(tokenizer.AtEnd())
+ self.assertRaises(text_format.ParseError, tokenizer.ConsumeComment)
+
+ def testConsumeComment(self):
+ tokenizer = text_format.Tokenizer('# some comment'.splitlines(),
+ skip_comments=False)
+ self.assertFalse(tokenizer.AtEnd())
+ self.assertEqual('# some comment', tokenizer.ConsumeComment())
+ self.assertTrue(tokenizer.AtEnd())
+
+ def testConsumeTwoComments(self):
+ text = '# some comment\n# another comment'
+ tokenizer = text_format.Tokenizer(text.splitlines(), skip_comments=False)
+ self.assertEqual('# some comment', tokenizer.ConsumeComment())
+ self.assertFalse(tokenizer.AtEnd())
+ self.assertEqual('# another comment', tokenizer.ConsumeComment())
+ self.assertTrue(tokenizer.AtEnd())
+
+ def testConsumeTrailingComment(self):
+ text = 'some_number: 4\n# some comment'
+ tokenizer = text_format.Tokenizer(text.splitlines(), skip_comments=False)
+ self.assertRaises(text_format.ParseError, tokenizer.ConsumeComment)
+
+ self.assertEqual('some_number', tokenizer.ConsumeIdentifier())
+ self.assertEqual(tokenizer.token, ':')
+ tokenizer.NextToken()
+ self.assertRaises(text_format.ParseError, tokenizer.ConsumeComment)
+ self.assertEqual(4, tokenizer.ConsumeInteger())
+ self.assertFalse(tokenizer.AtEnd())
+
+ self.assertEqual('# some comment', tokenizer.ConsumeComment())
+ self.assertTrue(tokenizer.AtEnd())
+
if __name__ == '__main__':
unittest.main()
diff --git a/python/google/protobuf/internal/type_checkers.py b/python/google/protobuf/internal/type_checkers.py
index f30ca6a8..1be3ad9a 100755
--- a/python/google/protobuf/internal/type_checkers.py
+++ b/python/google/protobuf/internal/type_checkers.py
@@ -109,6 +109,16 @@ class TypeChecker(object):
return proposed_value
+class TypeCheckerWithDefault(TypeChecker):
+
+ def __init__(self, default_value, *acceptable_types):
+ TypeChecker.__init__(self, acceptable_types)
+ self._default_value = default_value
+
+ def DefaultValue(self):
+ return self._default_value
+
+
# IntValueChecker and its subclasses perform integer type-checks
# and bounds-checks.
class IntValueChecker(object):
@@ -212,12 +222,13 @@ _VALUE_CHECKERS = {
_FieldDescriptor.CPPTYPE_INT64: Int64ValueChecker(),
_FieldDescriptor.CPPTYPE_UINT32: Uint32ValueChecker(),
_FieldDescriptor.CPPTYPE_UINT64: Uint64ValueChecker(),
- _FieldDescriptor.CPPTYPE_DOUBLE: TypeChecker(
- float, int, long),
- _FieldDescriptor.CPPTYPE_FLOAT: TypeChecker(
- float, int, long),
- _FieldDescriptor.CPPTYPE_BOOL: TypeChecker(bool, int),
- _FieldDescriptor.CPPTYPE_STRING: TypeChecker(bytes),
+ _FieldDescriptor.CPPTYPE_DOUBLE: TypeCheckerWithDefault(
+ 0.0, float, int, long),
+ _FieldDescriptor.CPPTYPE_FLOAT: TypeCheckerWithDefault(
+ 0.0, float, int, long),
+ _FieldDescriptor.CPPTYPE_BOOL: TypeCheckerWithDefault(
+ False, bool, int),
+ _FieldDescriptor.CPPTYPE_STRING: TypeCheckerWithDefault(b'', bytes),
}
diff --git a/python/google/protobuf/internal/unknown_fields_test.py b/python/google/protobuf/internal/unknown_fields_test.py
index 9685b8b4..84073f1c 100755
--- a/python/google/protobuf/internal/unknown_fields_test.py
+++ b/python/google/protobuf/internal/unknown_fields_test.py
@@ -36,7 +36,7 @@
__author__ = 'bohdank@google.com (Bohdan Koval)'
try:
- import unittest2 as unittest
+ import unittest2 as unittest #PY26
except ImportError:
import unittest
from google.protobuf import unittest_mset_pb2
@@ -119,6 +119,26 @@ class UnknownFieldsTest(unittest.TestCase):
message.ParseFromString(self.all_fields.SerializeToString())
self.assertNotEqual(self.empty_message, message)
+ def testDiscardUnknownFields(self):
+ self.empty_message.DiscardUnknownFields()
+ self.assertEqual(b'', self.empty_message.SerializeToString())
+ # Test message field and repeated message field.
+ message = unittest_pb2.TestAllTypes()
+ other_message = unittest_pb2.TestAllTypes()
+ other_message.optional_string = 'discard'
+ message.optional_nested_message.ParseFromString(
+ other_message.SerializeToString())
+ message.repeated_nested_message.add().ParseFromString(
+ other_message.SerializeToString())
+ self.assertNotEqual(
+ b'', message.optional_nested_message.SerializeToString())
+ self.assertNotEqual(
+ b'', message.repeated_nested_message[0].SerializeToString())
+ message.DiscardUnknownFields()
+ self.assertEqual(b'', message.optional_nested_message.SerializeToString())
+ self.assertEqual(
+ b'', message.repeated_nested_message[0].SerializeToString())
+
class UnknownFieldsAccessorsTest(unittest.TestCase):
diff --git a/python/google/protobuf/internal/well_known_types.py b/python/google/protobuf/internal/well_known_types.py
new file mode 100644
index 00000000..7c5dffd0
--- /dev/null
+++ b/python/google/protobuf/internal/well_known_types.py
@@ -0,0 +1,724 @@
+# 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.
+
+"""Contains well known classes.
+
+This files defines well known classes which need extra maintenance including:
+ - Any
+ - Duration
+ - FieldMask
+ - Struct
+ - Timestamp
+"""
+
+__author__ = 'jieluo@google.com (Jie Luo)'
+
+from datetime import datetime
+from datetime import timedelta
+import six
+
+from google.protobuf.descriptor import FieldDescriptor
+
+_TIMESTAMPFOMAT = '%Y-%m-%dT%H:%M:%S'
+_NANOS_PER_SECOND = 1000000000
+_NANOS_PER_MILLISECOND = 1000000
+_NANOS_PER_MICROSECOND = 1000
+_MILLIS_PER_SECOND = 1000
+_MICROS_PER_SECOND = 1000000
+_SECONDS_PER_DAY = 24 * 3600
+
+
+class Error(Exception):
+ """Top-level module error."""
+
+
+class ParseError(Error):
+ """Thrown in case of parsing error."""
+
+
+class Any(object):
+ """Class for Any Message type."""
+
+ def Pack(self, msg, type_url_prefix='type.googleapis.com/'):
+ """Packs the specified message into current Any message."""
+ if len(type_url_prefix) < 1 or type_url_prefix[-1] != '/':
+ self.type_url = '%s/%s' % (type_url_prefix, msg.DESCRIPTOR.full_name)
+ else:
+ self.type_url = '%s%s' % (type_url_prefix, msg.DESCRIPTOR.full_name)
+ self.value = msg.SerializeToString()
+
+ def Unpack(self, msg):
+ """Unpacks the current Any message into specified message."""
+ descriptor = msg.DESCRIPTOR
+ if not self.Is(descriptor):
+ return False
+ msg.ParseFromString(self.value)
+ return True
+
+ def TypeName(self):
+ """Returns the protobuf type name of the inner message."""
+ # Only last part is to be used: b/25630112
+ return self.type_url.split('/')[-1]
+
+ def Is(self, descriptor):
+ """Checks if this Any represents the given protobuf type."""
+ return self.TypeName() == descriptor.full_name
+
+
+class Timestamp(object):
+ """Class for Timestamp message type."""
+
+ def ToJsonString(self):
+ """Converts Timestamp to RFC 3339 date string format.
+
+ Returns:
+ A string converted from timestamp. The string is always Z-normalized
+ and uses 3, 6 or 9 fractional digits as required to represent the
+ exact time. Example of the return format: '1972-01-01T10:00:20.021Z'
+ """
+ nanos = self.nanos % _NANOS_PER_SECOND
+ total_sec = self.seconds + (self.nanos - nanos) // _NANOS_PER_SECOND
+ seconds = total_sec % _SECONDS_PER_DAY
+ days = (total_sec - seconds) // _SECONDS_PER_DAY
+ dt = datetime(1970, 1, 1) + timedelta(days, seconds)
+
+ result = dt.isoformat()
+ if (nanos % 1e9) == 0:
+ # If there are 0 fractional digits, the fractional
+ # point '.' should be omitted when serializing.
+ return result + 'Z'
+ if (nanos % 1e6) == 0:
+ # Serialize 3 fractional digits.
+ return result + '.%03dZ' % (nanos / 1e6)
+ if (nanos % 1e3) == 0:
+ # Serialize 6 fractional digits.
+ return result + '.%06dZ' % (nanos / 1e3)
+ # Serialize 9 fractional digits.
+ return result + '.%09dZ' % nanos
+
+ def FromJsonString(self, value):
+ """Parse a RFC 3339 date string format to Timestamp.
+
+ Args:
+ value: A date string. Any fractional digits (or none) and any offset are
+ accepted as long as they fit into nano-seconds precision.
+ Example of accepted format: '1972-01-01T10:00:20.021-05:00'
+
+ Raises:
+ ParseError: On parsing problems.
+ """
+ timezone_offset = value.find('Z')
+ if timezone_offset == -1:
+ timezone_offset = value.find('+')
+ if timezone_offset == -1:
+ timezone_offset = value.rfind('-')
+ if timezone_offset == -1:
+ raise ParseError(
+ 'Failed to parse timestamp: missing valid timezone offset.')
+ time_value = value[0:timezone_offset]
+ # Parse datetime and nanos.
+ point_position = time_value.find('.')
+ if point_position == -1:
+ second_value = time_value
+ nano_value = ''
+ else:
+ second_value = time_value[:point_position]
+ nano_value = time_value[point_position + 1:]
+ date_object = datetime.strptime(second_value, _TIMESTAMPFOMAT)
+ td = date_object - datetime(1970, 1, 1)
+ seconds = td.seconds + td.days * _SECONDS_PER_DAY
+ if len(nano_value) > 9:
+ raise ParseError(
+ 'Failed to parse Timestamp: nanos {0} more than '
+ '9 fractional digits.'.format(nano_value))
+ if nano_value:
+ nanos = round(float('0.' + nano_value) * 1e9)
+ else:
+ nanos = 0
+ # Parse timezone offsets.
+ if value[timezone_offset] == 'Z':
+ if len(value) != timezone_offset + 1:
+ raise ParseError('Failed to parse timestamp: invalid trailing'
+ ' data {0}.'.format(value))
+ else:
+ timezone = value[timezone_offset:]
+ pos = timezone.find(':')
+ if pos == -1:
+ raise ParseError(
+ 'Invalid timezone offset value: {0}.'.format(timezone))
+ if timezone[0] == '+':
+ seconds -= (int(timezone[1:pos])*60+int(timezone[pos+1:]))*60
+ else:
+ seconds += (int(timezone[1:pos])*60+int(timezone[pos+1:]))*60
+ # Set seconds and nanos
+ self.seconds = int(seconds)
+ self.nanos = int(nanos)
+
+ def GetCurrentTime(self):
+ """Get the current UTC into Timestamp."""
+ self.FromDatetime(datetime.utcnow())
+
+ def ToNanoseconds(self):
+ """Converts Timestamp to nanoseconds since epoch."""
+ return self.seconds * _NANOS_PER_SECOND + self.nanos
+
+ def ToMicroseconds(self):
+ """Converts Timestamp to microseconds since epoch."""
+ return (self.seconds * _MICROS_PER_SECOND +
+ self.nanos // _NANOS_PER_MICROSECOND)
+
+ def ToMilliseconds(self):
+ """Converts Timestamp to milliseconds since epoch."""
+ return (self.seconds * _MILLIS_PER_SECOND +
+ self.nanos // _NANOS_PER_MILLISECOND)
+
+ def ToSeconds(self):
+ """Converts Timestamp to seconds since epoch."""
+ return self.seconds
+
+ def FromNanoseconds(self, nanos):
+ """Converts nanoseconds since epoch to Timestamp."""
+ self.seconds = nanos // _NANOS_PER_SECOND
+ self.nanos = nanos % _NANOS_PER_SECOND
+
+ def FromMicroseconds(self, micros):
+ """Converts microseconds since epoch to Timestamp."""
+ self.seconds = micros // _MICROS_PER_SECOND
+ self.nanos = (micros % _MICROS_PER_SECOND) * _NANOS_PER_MICROSECOND
+
+ def FromMilliseconds(self, millis):
+ """Converts milliseconds since epoch to Timestamp."""
+ self.seconds = millis // _MILLIS_PER_SECOND
+ self.nanos = (millis % _MILLIS_PER_SECOND) * _NANOS_PER_MILLISECOND
+
+ def FromSeconds(self, seconds):
+ """Converts seconds since epoch to Timestamp."""
+ self.seconds = seconds
+ self.nanos = 0
+
+ def ToDatetime(self):
+ """Converts Timestamp to datetime."""
+ return datetime.utcfromtimestamp(
+ self.seconds + self.nanos / float(_NANOS_PER_SECOND))
+
+ def FromDatetime(self, dt):
+ """Converts datetime to Timestamp."""
+ td = dt - datetime(1970, 1, 1)
+ self.seconds = td.seconds + td.days * _SECONDS_PER_DAY
+ self.nanos = td.microseconds * _NANOS_PER_MICROSECOND
+
+
+class Duration(object):
+ """Class for Duration message type."""
+
+ def ToJsonString(self):
+ """Converts Duration to string format.
+
+ Returns:
+ A string converted from self. The string format will contains
+ 3, 6, or 9 fractional digits depending on the precision required to
+ represent the exact Duration value. For example: "1s", "1.010s",
+ "1.000000100s", "-3.100s"
+ """
+ if self.seconds < 0 or self.nanos < 0:
+ result = '-'
+ seconds = - self.seconds + int((0 - self.nanos) // 1e9)
+ nanos = (0 - self.nanos) % 1e9
+ else:
+ result = ''
+ seconds = self.seconds + int(self.nanos // 1e9)
+ nanos = self.nanos % 1e9
+ result += '%d' % seconds
+ if (nanos % 1e9) == 0:
+ # If there are 0 fractional digits, the fractional
+ # point '.' should be omitted when serializing.
+ return result + 's'
+ if (nanos % 1e6) == 0:
+ # Serialize 3 fractional digits.
+ return result + '.%03ds' % (nanos / 1e6)
+ if (nanos % 1e3) == 0:
+ # Serialize 6 fractional digits.
+ return result + '.%06ds' % (nanos / 1e3)
+ # Serialize 9 fractional digits.
+ return result + '.%09ds' % nanos
+
+ def FromJsonString(self, value):
+ """Converts a string to Duration.
+
+ Args:
+ value: A string to be converted. The string must end with 's'. Any
+ fractional digits (or none) are accepted as long as they fit into
+ precision. For example: "1s", "1.01s", "1.0000001s", "-3.100s
+
+ Raises:
+ ParseError: On parsing problems.
+ """
+ if len(value) < 1 or value[-1] != 's':
+ raise ParseError(
+ 'Duration must end with letter "s": {0}.'.format(value))
+ try:
+ pos = value.find('.')
+ if pos == -1:
+ self.seconds = int(value[:-1])
+ self.nanos = 0
+ else:
+ self.seconds = int(value[:pos])
+ if value[0] == '-':
+ self.nanos = int(round(float('-0{0}'.format(value[pos: -1])) *1e9))
+ else:
+ self.nanos = int(round(float('0{0}'.format(value[pos: -1])) *1e9))
+ except ValueError:
+ raise ParseError(
+ 'Couldn\'t parse duration: {0}.'.format(value))
+
+ def ToNanoseconds(self):
+ """Converts a Duration to nanoseconds."""
+ return self.seconds * _NANOS_PER_SECOND + self.nanos
+
+ def ToMicroseconds(self):
+ """Converts a Duration to microseconds."""
+ micros = _RoundTowardZero(self.nanos, _NANOS_PER_MICROSECOND)
+ return self.seconds * _MICROS_PER_SECOND + micros
+
+ def ToMilliseconds(self):
+ """Converts a Duration to milliseconds."""
+ millis = _RoundTowardZero(self.nanos, _NANOS_PER_MILLISECOND)
+ return self.seconds * _MILLIS_PER_SECOND + millis
+
+ def ToSeconds(self):
+ """Converts a Duration to seconds."""
+ return self.seconds
+
+ def FromNanoseconds(self, nanos):
+ """Converts nanoseconds to Duration."""
+ self._NormalizeDuration(nanos // _NANOS_PER_SECOND,
+ nanos % _NANOS_PER_SECOND)
+
+ def FromMicroseconds(self, micros):
+ """Converts microseconds to Duration."""
+ self._NormalizeDuration(
+ micros // _MICROS_PER_SECOND,
+ (micros % _MICROS_PER_SECOND) * _NANOS_PER_MICROSECOND)
+
+ def FromMilliseconds(self, millis):
+ """Converts milliseconds to Duration."""
+ self._NormalizeDuration(
+ millis // _MILLIS_PER_SECOND,
+ (millis % _MILLIS_PER_SECOND) * _NANOS_PER_MILLISECOND)
+
+ def FromSeconds(self, seconds):
+ """Converts seconds to Duration."""
+ self.seconds = seconds
+ self.nanos = 0
+
+ def ToTimedelta(self):
+ """Converts Duration to timedelta."""
+ return timedelta(
+ seconds=self.seconds, microseconds=_RoundTowardZero(
+ self.nanos, _NANOS_PER_MICROSECOND))
+
+ def FromTimedelta(self, td):
+ """Convertd timedelta to Duration."""
+ self._NormalizeDuration(td.seconds + td.days * _SECONDS_PER_DAY,
+ td.microseconds * _NANOS_PER_MICROSECOND)
+
+ def _NormalizeDuration(self, seconds, nanos):
+ """Set Duration by seconds and nonas."""
+ # Force nanos to be negative if the duration is negative.
+ if seconds < 0 and nanos > 0:
+ seconds += 1
+ nanos -= _NANOS_PER_SECOND
+ self.seconds = seconds
+ self.nanos = nanos
+
+
+def _RoundTowardZero(value, divider):
+ """Truncates the remainder part after division."""
+ # For some languanges, the sign of the remainder is implementation
+ # dependent if any of the operands is negative. Here we enforce
+ # "rounded toward zero" semantics. For example, for (-5) / 2 an
+ # implementation may give -3 as the result with the remainder being
+ # 1. This function ensures we always return -2 (closer to zero).
+ result = value // divider
+ remainder = value % divider
+ if result < 0 and remainder > 0:
+ return result + 1
+ else:
+ return result
+
+
+class FieldMask(object):
+ """Class for FieldMask message type."""
+
+ def ToJsonString(self):
+ """Converts FieldMask to string according to proto3 JSON spec."""
+ return ','.join(self.paths)
+
+ def FromJsonString(self, value):
+ """Converts string to FieldMask according to proto3 JSON spec."""
+ self.Clear()
+ for path in value.split(','):
+ self.paths.append(path)
+
+ def IsValidForDescriptor(self, message_descriptor):
+ """Checks whether the FieldMask is valid for Message Descriptor."""
+ for path in self.paths:
+ if not _IsValidPath(message_descriptor, path):
+ return False
+ return True
+
+ def AllFieldsFromDescriptor(self, message_descriptor):
+ """Gets all direct fields of Message Descriptor to FieldMask."""
+ self.Clear()
+ for field in message_descriptor.fields:
+ self.paths.append(field.name)
+
+ def CanonicalFormFromMask(self, mask):
+ """Converts a FieldMask to the canonical form.
+
+ Removes paths that are covered by another path. For example,
+ "foo.bar" is covered by "foo" and will be removed if "foo"
+ is also in the FieldMask. Then sorts all paths in alphabetical order.
+
+ Args:
+ mask: The original FieldMask to be converted.
+ """
+ tree = _FieldMaskTree(mask)
+ tree.ToFieldMask(self)
+
+ def Union(self, mask1, mask2):
+ """Merges mask1 and mask2 into this FieldMask."""
+ _CheckFieldMaskMessage(mask1)
+ _CheckFieldMaskMessage(mask2)
+ tree = _FieldMaskTree(mask1)
+ tree.MergeFromFieldMask(mask2)
+ tree.ToFieldMask(self)
+
+ def Intersect(self, mask1, mask2):
+ """Intersects mask1 and mask2 into this FieldMask."""
+ _CheckFieldMaskMessage(mask1)
+ _CheckFieldMaskMessage(mask2)
+ tree = _FieldMaskTree(mask1)
+ intersection = _FieldMaskTree()
+ for path in mask2.paths:
+ tree.IntersectPath(path, intersection)
+ intersection.ToFieldMask(self)
+
+ def MergeMessage(
+ self, source, destination,
+ replace_message_field=False, replace_repeated_field=False):
+ """Merges fields specified in FieldMask from source to destination.
+
+ Args:
+ source: Source message.
+ destination: The destination message to be merged into.
+ replace_message_field: Replace message field if True. Merge message
+ field if False.
+ replace_repeated_field: Replace repeated field if True. Append
+ elements of repeated field if False.
+ """
+ tree = _FieldMaskTree(self)
+ tree.MergeMessage(
+ source, destination, replace_message_field, replace_repeated_field)
+
+
+def _IsValidPath(message_descriptor, path):
+ """Checks whether the path is valid for Message Descriptor."""
+ parts = path.split('.')
+ last = parts.pop()
+ for name in parts:
+ field = message_descriptor.fields_by_name[name]
+ if (field is None or
+ field.label == FieldDescriptor.LABEL_REPEATED or
+ field.type != FieldDescriptor.TYPE_MESSAGE):
+ return False
+ message_descriptor = field.message_type
+ return last in message_descriptor.fields_by_name
+
+
+def _CheckFieldMaskMessage(message):
+ """Raises ValueError if message is not a FieldMask."""
+ message_descriptor = message.DESCRIPTOR
+ if (message_descriptor.name != 'FieldMask' or
+ message_descriptor.file.name != 'google/protobuf/field_mask.proto'):
+ raise ValueError('Message {0} is not a FieldMask.'.format(
+ message_descriptor.full_name))
+
+
+class _FieldMaskTree(object):
+ """Represents a FieldMask in a tree structure.
+
+ For example, given a FieldMask "foo.bar,foo.baz,bar.baz",
+ the FieldMaskTree will be:
+ [_root] -+- foo -+- bar
+ | |
+ | +- baz
+ |
+ +- bar --- baz
+ In the tree, each leaf node represents a field path.
+ """
+
+ def __init__(self, field_mask=None):
+ """Initializes the tree by FieldMask."""
+ self._root = {}
+ if field_mask:
+ self.MergeFromFieldMask(field_mask)
+
+ def MergeFromFieldMask(self, field_mask):
+ """Merges a FieldMask to the tree."""
+ for path in field_mask.paths:
+ self.AddPath(path)
+
+ def AddPath(self, path):
+ """Adds a field path into the tree.
+
+ If the field path to add is a sub-path of an existing field path
+ in the tree (i.e., a leaf node), it means the tree already matches
+ the given path so nothing will be added to the tree. If the path
+ matches an existing non-leaf node in the tree, that non-leaf node
+ will be turned into a leaf node with all its children removed because
+ the path matches all the node's children. Otherwise, a new path will
+ be added.
+
+ Args:
+ path: The field path to add.
+ """
+ node = self._root
+ for name in path.split('.'):
+ if name not in node:
+ node[name] = {}
+ elif not node[name]:
+ # Pre-existing empty node implies we already have this entire tree.
+ return
+ node = node[name]
+ # Remove any sub-trees we might have had.
+ node.clear()
+
+ def ToFieldMask(self, field_mask):
+ """Converts the tree to a FieldMask."""
+ field_mask.Clear()
+ _AddFieldPaths(self._root, '', field_mask)
+
+ def IntersectPath(self, path, intersection):
+ """Calculates the intersection part of a field path with this tree.
+
+ Args:
+ path: The field path to calculates.
+ intersection: The out tree to record the intersection part.
+ """
+ node = self._root
+ for name in path.split('.'):
+ if name not in node:
+ return
+ elif not node[name]:
+ intersection.AddPath(path)
+ return
+ node = node[name]
+ intersection.AddLeafNodes(path, node)
+
+ def AddLeafNodes(self, prefix, node):
+ """Adds leaf nodes begin with prefix to this tree."""
+ if not node:
+ self.AddPath(prefix)
+ for name in node:
+ child_path = prefix + '.' + name
+ self.AddLeafNodes(child_path, node[name])
+
+ def MergeMessage(
+ self, source, destination,
+ replace_message, replace_repeated):
+ """Merge all fields specified by this tree from source to destination."""
+ _MergeMessage(
+ self._root, source, destination, replace_message, replace_repeated)
+
+
+def _StrConvert(value):
+ """Converts value to str if it is not."""
+ # This file is imported by c extension and some methods like ClearField
+ # requires string for the field name. py2/py3 has different text
+ # type and may use unicode.
+ if not isinstance(value, str):
+ return value.encode('utf-8')
+ return value
+
+
+def _MergeMessage(
+ node, source, destination, replace_message, replace_repeated):
+ """Merge all fields specified by a sub-tree from source to destination."""
+ source_descriptor = source.DESCRIPTOR
+ for name in node:
+ child = node[name]
+ field = source_descriptor.fields_by_name[name]
+ if field is None:
+ raise ValueError('Error: Can\'t find field {0} in message {1}.'.format(
+ name, source_descriptor.full_name))
+ if child:
+ # Sub-paths are only allowed for singular message fields.
+ if (field.label == FieldDescriptor.LABEL_REPEATED or
+ field.cpp_type != FieldDescriptor.CPPTYPE_MESSAGE):
+ raise ValueError('Error: Field {0} in message {1} is not a singular '
+ 'message field and cannot have sub-fields.'.format(
+ name, source_descriptor.full_name))
+ _MergeMessage(
+ child, getattr(source, name), getattr(destination, name),
+ replace_message, replace_repeated)
+ continue
+ if field.label == FieldDescriptor.LABEL_REPEATED:
+ if replace_repeated:
+ destination.ClearField(_StrConvert(name))
+ repeated_source = getattr(source, name)
+ repeated_destination = getattr(destination, name)
+ if field.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE:
+ for item in repeated_source:
+ repeated_destination.add().MergeFrom(item)
+ else:
+ repeated_destination.extend(repeated_source)
+ else:
+ if field.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE:
+ if replace_message:
+ destination.ClearField(_StrConvert(name))
+ if source.HasField(name):
+ getattr(destination, name).MergeFrom(getattr(source, name))
+ else:
+ setattr(destination, name, getattr(source, name))
+
+
+def _AddFieldPaths(node, prefix, field_mask):
+ """Adds the field paths descended from node to field_mask."""
+ if not node:
+ field_mask.paths.append(prefix)
+ return
+ for name in sorted(node):
+ if prefix:
+ child_path = prefix + '.' + name
+ else:
+ child_path = name
+ _AddFieldPaths(node[name], child_path, field_mask)
+
+
+_INT_OR_FLOAT = six.integer_types + (float,)
+
+
+def _SetStructValue(struct_value, value):
+ if value is None:
+ struct_value.null_value = 0
+ elif isinstance(value, bool):
+ # Note: this check must come before the number check because in Python
+ # True and False are also considered numbers.
+ struct_value.bool_value = value
+ elif isinstance(value, six.string_types):
+ struct_value.string_value = value
+ elif isinstance(value, _INT_OR_FLOAT):
+ struct_value.number_value = value
+ else:
+ raise ValueError('Unexpected type')
+
+
+def _GetStructValue(struct_value):
+ which = struct_value.WhichOneof('kind')
+ if which == 'struct_value':
+ return struct_value.struct_value
+ elif which == 'null_value':
+ return None
+ elif which == 'number_value':
+ return struct_value.number_value
+ elif which == 'string_value':
+ return struct_value.string_value
+ elif which == 'bool_value':
+ return struct_value.bool_value
+ elif which == 'list_value':
+ return struct_value.list_value
+ elif which is None:
+ raise ValueError('Value not set')
+
+
+class Struct(object):
+ """Class for Struct message type."""
+
+ __slots__ = []
+
+ def __getitem__(self, key):
+ return _GetStructValue(self.fields[key])
+
+ def __setitem__(self, key, value):
+ _SetStructValue(self.fields[key], value)
+
+ def get_or_create_list(self, key):
+ """Returns a list for this key, creating if it didn't exist already."""
+ return self.fields[key].list_value
+
+ def get_or_create_struct(self, key):
+ """Returns a struct for this key, creating if it didn't exist already."""
+ return self.fields[key].struct_value
+
+ # TODO(haberman): allow constructing/merging from dict.
+
+
+class ListValue(object):
+ """Class for ListValue message type."""
+
+ def __len__(self):
+ return len(self.values)
+
+ def append(self, value):
+ _SetStructValue(self.values.add(), value)
+
+ def extend(self, elem_seq):
+ for value in elem_seq:
+ self.append(value)
+
+ def __getitem__(self, index):
+ """Retrieves item by the specified index."""
+ return _GetStructValue(self.values.__getitem__(index))
+
+ def __setitem__(self, index, value):
+ _SetStructValue(self.values.__getitem__(index), value)
+
+ def items(self):
+ for i in range(len(self)):
+ yield self[i]
+
+ def add_struct(self):
+ """Appends and returns a struct value as the next value in the list."""
+ return self.values.add().struct_value
+
+ def add_list(self):
+ """Appends and returns a list value as the next value in the list."""
+ return self.values.add().list_value
+
+
+WKTBASES = {
+ 'google.protobuf.Any': Any,
+ 'google.protobuf.Duration': Duration,
+ 'google.protobuf.FieldMask': FieldMask,
+ 'google.protobuf.ListValue': ListValue,
+ 'google.protobuf.Struct': Struct,
+ 'google.protobuf.Timestamp': Timestamp,
+}
diff --git a/python/google/protobuf/internal/well_known_types_test.py b/python/google/protobuf/internal/well_known_types_test.py
new file mode 100644
index 00000000..2f32ac99
--- /dev/null
+++ b/python/google/protobuf/internal/well_known_types_test.py
@@ -0,0 +1,644 @@
+#! /usr/bin/env python
+#
+# 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.
+
+"""Test for google.protobuf.internal.well_known_types."""
+
+__author__ = 'jieluo@google.com (Jie Luo)'
+
+from datetime import datetime
+
+try:
+ import unittest2 as unittest #PY26
+except ImportError:
+ import unittest
+
+from google.protobuf import any_pb2
+from google.protobuf import duration_pb2
+from google.protobuf import field_mask_pb2
+from google.protobuf import struct_pb2
+from google.protobuf import timestamp_pb2
+from google.protobuf import unittest_pb2
+from google.protobuf.internal import any_test_pb2
+from google.protobuf.internal import test_util
+from google.protobuf.internal import well_known_types
+from google.protobuf import descriptor
+from google.protobuf import text_format
+
+
+class TimeUtilTestBase(unittest.TestCase):
+
+ def CheckTimestampConversion(self, message, text):
+ self.assertEqual(text, message.ToJsonString())
+ parsed_message = timestamp_pb2.Timestamp()
+ parsed_message.FromJsonString(text)
+ self.assertEqual(message, parsed_message)
+
+ def CheckDurationConversion(self, message, text):
+ self.assertEqual(text, message.ToJsonString())
+ parsed_message = duration_pb2.Duration()
+ parsed_message.FromJsonString(text)
+ self.assertEqual(message, parsed_message)
+
+
+class TimeUtilTest(TimeUtilTestBase):
+
+ def testTimestampSerializeAndParse(self):
+ message = timestamp_pb2.Timestamp()
+ # Generated output should contain 3, 6, or 9 fractional digits.
+ message.seconds = 0
+ message.nanos = 0
+ self.CheckTimestampConversion(message, '1970-01-01T00:00:00Z')
+ message.nanos = 10000000
+ self.CheckTimestampConversion(message, '1970-01-01T00:00:00.010Z')
+ message.nanos = 10000
+ self.CheckTimestampConversion(message, '1970-01-01T00:00:00.000010Z')
+ message.nanos = 10
+ self.CheckTimestampConversion(message, '1970-01-01T00:00:00.000000010Z')
+ # Test min timestamps.
+ message.seconds = -62135596800
+ message.nanos = 0
+ self.CheckTimestampConversion(message, '0001-01-01T00:00:00Z')
+ # Test max timestamps.
+ message.seconds = 253402300799
+ message.nanos = 999999999
+ self.CheckTimestampConversion(message, '9999-12-31T23:59:59.999999999Z')
+ # Test negative timestamps.
+ message.seconds = -1
+ self.CheckTimestampConversion(message, '1969-12-31T23:59:59.999999999Z')
+
+ # Parsing accepts an fractional digits as long as they fit into nano
+ # precision.
+ message.FromJsonString('1970-01-01T00:00:00.1Z')
+ self.assertEqual(0, message.seconds)
+ self.assertEqual(100000000, message.nanos)
+ # Parsing accpets offsets.
+ message.FromJsonString('1970-01-01T00:00:00-08:00')
+ self.assertEqual(8 * 3600, message.seconds)
+ self.assertEqual(0, message.nanos)
+
+ def testDurationSerializeAndParse(self):
+ message = duration_pb2.Duration()
+ # Generated output should contain 3, 6, or 9 fractional digits.
+ message.seconds = 0
+ message.nanos = 0
+ self.CheckDurationConversion(message, '0s')
+ message.nanos = 10000000
+ self.CheckDurationConversion(message, '0.010s')
+ message.nanos = 10000
+ self.CheckDurationConversion(message, '0.000010s')
+ message.nanos = 10
+ self.CheckDurationConversion(message, '0.000000010s')
+
+ # Test min and max
+ message.seconds = 315576000000
+ message.nanos = 999999999
+ self.CheckDurationConversion(message, '315576000000.999999999s')
+ message.seconds = -315576000000
+ message.nanos = -999999999
+ self.CheckDurationConversion(message, '-315576000000.999999999s')
+
+ # Parsing accepts an fractional digits as long as they fit into nano
+ # precision.
+ message.FromJsonString('0.1s')
+ self.assertEqual(100000000, message.nanos)
+ message.FromJsonString('0.0000001s')
+ self.assertEqual(100, message.nanos)
+
+ def testTimestampIntegerConversion(self):
+ message = timestamp_pb2.Timestamp()
+ message.FromNanoseconds(1)
+ self.assertEqual('1970-01-01T00:00:00.000000001Z',
+ message.ToJsonString())
+ self.assertEqual(1, message.ToNanoseconds())
+
+ message.FromNanoseconds(-1)
+ self.assertEqual('1969-12-31T23:59:59.999999999Z',
+ message.ToJsonString())
+ self.assertEqual(-1, message.ToNanoseconds())
+
+ message.FromMicroseconds(1)
+ self.assertEqual('1970-01-01T00:00:00.000001Z',
+ message.ToJsonString())
+ self.assertEqual(1, message.ToMicroseconds())
+
+ message.FromMicroseconds(-1)
+ self.assertEqual('1969-12-31T23:59:59.999999Z',
+ message.ToJsonString())
+ self.assertEqual(-1, message.ToMicroseconds())
+
+ message.FromMilliseconds(1)
+ self.assertEqual('1970-01-01T00:00:00.001Z',
+ message.ToJsonString())
+ self.assertEqual(1, message.ToMilliseconds())
+
+ message.FromMilliseconds(-1)
+ self.assertEqual('1969-12-31T23:59:59.999Z',
+ message.ToJsonString())
+ self.assertEqual(-1, message.ToMilliseconds())
+
+ message.FromSeconds(1)
+ self.assertEqual('1970-01-01T00:00:01Z',
+ message.ToJsonString())
+ self.assertEqual(1, message.ToSeconds())
+
+ message.FromSeconds(-1)
+ self.assertEqual('1969-12-31T23:59:59Z',
+ message.ToJsonString())
+ self.assertEqual(-1, message.ToSeconds())
+
+ message.FromNanoseconds(1999)
+ self.assertEqual(1, message.ToMicroseconds())
+ # For negative values, Timestamp will be rounded down.
+ # For example, "1969-12-31T23:59:59.5Z" (i.e., -0.5s) rounded to seconds
+ # will be "1969-12-31T23:59:59Z" (i.e., -1s) rather than
+ # "1970-01-01T00:00:00Z" (i.e., 0s).
+ message.FromNanoseconds(-1999)
+ self.assertEqual(-2, message.ToMicroseconds())
+
+ def testDurationIntegerConversion(self):
+ message = duration_pb2.Duration()
+ message.FromNanoseconds(1)
+ self.assertEqual('0.000000001s',
+ message.ToJsonString())
+ self.assertEqual(1, message.ToNanoseconds())
+
+ message.FromNanoseconds(-1)
+ self.assertEqual('-0.000000001s',
+ message.ToJsonString())
+ self.assertEqual(-1, message.ToNanoseconds())
+
+ message.FromMicroseconds(1)
+ self.assertEqual('0.000001s',
+ message.ToJsonString())
+ self.assertEqual(1, message.ToMicroseconds())
+
+ message.FromMicroseconds(-1)
+ self.assertEqual('-0.000001s',
+ message.ToJsonString())
+ self.assertEqual(-1, message.ToMicroseconds())
+
+ message.FromMilliseconds(1)
+ self.assertEqual('0.001s',
+ message.ToJsonString())
+ self.assertEqual(1, message.ToMilliseconds())
+
+ message.FromMilliseconds(-1)
+ self.assertEqual('-0.001s',
+ message.ToJsonString())
+ self.assertEqual(-1, message.ToMilliseconds())
+
+ message.FromSeconds(1)
+ self.assertEqual('1s', message.ToJsonString())
+ self.assertEqual(1, message.ToSeconds())
+
+ message.FromSeconds(-1)
+ self.assertEqual('-1s',
+ message.ToJsonString())
+ self.assertEqual(-1, message.ToSeconds())
+
+ # Test truncation behavior.
+ message.FromNanoseconds(1999)
+ self.assertEqual(1, message.ToMicroseconds())
+
+ # For negative values, Duration will be rounded towards 0.
+ message.FromNanoseconds(-1999)
+ self.assertEqual(-1, message.ToMicroseconds())
+
+ def testDatetimeConverison(self):
+ message = timestamp_pb2.Timestamp()
+ dt = datetime(1970, 1, 1)
+ message.FromDatetime(dt)
+ self.assertEqual(dt, message.ToDatetime())
+
+ message.FromMilliseconds(1999)
+ self.assertEqual(datetime(1970, 1, 1, 0, 0, 1, 999000),
+ message.ToDatetime())
+
+ def testTimedeltaConversion(self):
+ message = duration_pb2.Duration()
+ message.FromNanoseconds(1999999999)
+ td = message.ToTimedelta()
+ self.assertEqual(1, td.seconds)
+ self.assertEqual(999999, td.microseconds)
+
+ message.FromNanoseconds(-1999999999)
+ td = message.ToTimedelta()
+ self.assertEqual(-1, td.days)
+ self.assertEqual(86398, td.seconds)
+ self.assertEqual(1, td.microseconds)
+
+ message.FromMicroseconds(-1)
+ td = message.ToTimedelta()
+ self.assertEqual(-1, td.days)
+ self.assertEqual(86399, td.seconds)
+ self.assertEqual(999999, td.microseconds)
+ converted_message = duration_pb2.Duration()
+ converted_message.FromTimedelta(td)
+ self.assertEqual(message, converted_message)
+
+ def testInvalidTimestamp(self):
+ message = timestamp_pb2.Timestamp()
+ self.assertRaisesRegexp(
+ ValueError,
+ 'time data \'10000-01-01T00:00:00\' does not match'
+ ' format \'%Y-%m-%dT%H:%M:%S\'',
+ message.FromJsonString, '10000-01-01T00:00:00.00Z')
+ self.assertRaisesRegexp(
+ well_known_types.ParseError,
+ 'nanos 0123456789012 more than 9 fractional digits.',
+ message.FromJsonString,
+ '1970-01-01T00:00:00.0123456789012Z')
+ self.assertRaisesRegexp(
+ well_known_types.ParseError,
+ (r'Invalid timezone offset value: \+08.'),
+ message.FromJsonString,
+ '1972-01-01T01:00:00.01+08',)
+ self.assertRaisesRegexp(
+ ValueError,
+ 'year is out of range',
+ message.FromJsonString,
+ '0000-01-01T00:00:00Z')
+ message.seconds = 253402300800
+ self.assertRaisesRegexp(
+ OverflowError,
+ 'date value out of range',
+ message.ToJsonString)
+
+ def testInvalidDuration(self):
+ message = duration_pb2.Duration()
+ self.assertRaisesRegexp(
+ well_known_types.ParseError,
+ 'Duration must end with letter "s": 1.',
+ message.FromJsonString, '1')
+ self.assertRaisesRegexp(
+ well_known_types.ParseError,
+ 'Couldn\'t parse duration: 1...2s.',
+ message.FromJsonString, '1...2s')
+
+
+class FieldMaskTest(unittest.TestCase):
+
+ def testStringFormat(self):
+ mask = field_mask_pb2.FieldMask()
+ self.assertEqual('', mask.ToJsonString())
+ mask.paths.append('foo')
+ self.assertEqual('foo', mask.ToJsonString())
+ mask.paths.append('bar')
+ self.assertEqual('foo,bar', mask.ToJsonString())
+
+ mask.FromJsonString('')
+ self.assertEqual('', mask.ToJsonString())
+ mask.FromJsonString('foo')
+ self.assertEqual(['foo'], mask.paths)
+ mask.FromJsonString('foo,bar')
+ self.assertEqual(['foo', 'bar'], mask.paths)
+
+ def testDescriptorToFieldMask(self):
+ mask = field_mask_pb2.FieldMask()
+ msg_descriptor = unittest_pb2.TestAllTypes.DESCRIPTOR
+ mask.AllFieldsFromDescriptor(msg_descriptor)
+ self.assertEqual(75, len(mask.paths))
+ self.assertTrue(mask.IsValidForDescriptor(msg_descriptor))
+ for field in msg_descriptor.fields:
+ self.assertTrue(field.name in mask.paths)
+ mask.paths.append('optional_nested_message.bb')
+ self.assertTrue(mask.IsValidForDescriptor(msg_descriptor))
+ mask.paths.append('repeated_nested_message.bb')
+ self.assertFalse(mask.IsValidForDescriptor(msg_descriptor))
+
+ def testCanonicalFrom(self):
+ mask = field_mask_pb2.FieldMask()
+ out_mask = field_mask_pb2.FieldMask()
+ # Paths will be sorted.
+ mask.FromJsonString('baz.quz,bar,foo')
+ out_mask.CanonicalFormFromMask(mask)
+ self.assertEqual('bar,baz.quz,foo', out_mask.ToJsonString())
+ # Duplicated paths will be removed.
+ mask.FromJsonString('foo,bar,foo')
+ out_mask.CanonicalFormFromMask(mask)
+ self.assertEqual('bar,foo', out_mask.ToJsonString())
+ # Sub-paths of other paths will be removed.
+ mask.FromJsonString('foo.b1,bar.b1,foo.b2,bar')
+ out_mask.CanonicalFormFromMask(mask)
+ self.assertEqual('bar,foo.b1,foo.b2', out_mask.ToJsonString())
+
+ # Test more deeply nested cases.
+ mask.FromJsonString(
+ 'foo.bar.baz1,foo.bar.baz2.quz,foo.bar.baz2')
+ out_mask.CanonicalFormFromMask(mask)
+ self.assertEqual('foo.bar.baz1,foo.bar.baz2',
+ out_mask.ToJsonString())
+ mask.FromJsonString(
+ 'foo.bar.baz1,foo.bar.baz2,foo.bar.baz2.quz')
+ out_mask.CanonicalFormFromMask(mask)
+ self.assertEqual('foo.bar.baz1,foo.bar.baz2',
+ out_mask.ToJsonString())
+ mask.FromJsonString(
+ 'foo.bar.baz1,foo.bar.baz2,foo.bar.baz2.quz,foo.bar')
+ out_mask.CanonicalFormFromMask(mask)
+ self.assertEqual('foo.bar', out_mask.ToJsonString())
+ mask.FromJsonString(
+ 'foo.bar.baz1,foo.bar.baz2,foo.bar.baz2.quz,foo')
+ out_mask.CanonicalFormFromMask(mask)
+ self.assertEqual('foo', out_mask.ToJsonString())
+
+ def testUnion(self):
+ mask1 = field_mask_pb2.FieldMask()
+ mask2 = field_mask_pb2.FieldMask()
+ out_mask = field_mask_pb2.FieldMask()
+ mask1.FromJsonString('foo,baz')
+ mask2.FromJsonString('bar,quz')
+ out_mask.Union(mask1, mask2)
+ self.assertEqual('bar,baz,foo,quz', out_mask.ToJsonString())
+ # Overlap with duplicated paths.
+ mask1.FromJsonString('foo,baz.bb')
+ mask2.FromJsonString('baz.bb,quz')
+ out_mask.Union(mask1, mask2)
+ self.assertEqual('baz.bb,foo,quz', out_mask.ToJsonString())
+ # Overlap with paths covering some other paths.
+ mask1.FromJsonString('foo.bar.baz,quz')
+ mask2.FromJsonString('foo.bar,bar')
+ out_mask.Union(mask1, mask2)
+ self.assertEqual('bar,foo.bar,quz', out_mask.ToJsonString())
+
+ def testIntersect(self):
+ mask1 = field_mask_pb2.FieldMask()
+ mask2 = field_mask_pb2.FieldMask()
+ out_mask = field_mask_pb2.FieldMask()
+ # Test cases without overlapping.
+ mask1.FromJsonString('foo,baz')
+ mask2.FromJsonString('bar,quz')
+ out_mask.Intersect(mask1, mask2)
+ self.assertEqual('', out_mask.ToJsonString())
+ # Overlap with duplicated paths.
+ mask1.FromJsonString('foo,baz.bb')
+ mask2.FromJsonString('baz.bb,quz')
+ out_mask.Intersect(mask1, mask2)
+ self.assertEqual('baz.bb', out_mask.ToJsonString())
+ # Overlap with paths covering some other paths.
+ mask1.FromJsonString('foo.bar.baz,quz')
+ mask2.FromJsonString('foo.bar,bar')
+ out_mask.Intersect(mask1, mask2)
+ self.assertEqual('foo.bar.baz', out_mask.ToJsonString())
+ mask1.FromJsonString('foo.bar,bar')
+ mask2.FromJsonString('foo.bar.baz,quz')
+ out_mask.Intersect(mask1, mask2)
+ self.assertEqual('foo.bar.baz', out_mask.ToJsonString())
+
+ def testMergeMessage(self):
+ # Test merge one field.
+ src = unittest_pb2.TestAllTypes()
+ test_util.SetAllFields(src)
+ for field in src.DESCRIPTOR.fields:
+ if field.containing_oneof:
+ continue
+ field_name = field.name
+ dst = unittest_pb2.TestAllTypes()
+ # Only set one path to mask.
+ mask = field_mask_pb2.FieldMask()
+ mask.paths.append(field_name)
+ mask.MergeMessage(src, dst)
+ # The expected result message.
+ msg = unittest_pb2.TestAllTypes()
+ if field.label == descriptor.FieldDescriptor.LABEL_REPEATED:
+ repeated_src = getattr(src, field_name)
+ repeated_msg = getattr(msg, field_name)
+ if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE:
+ for item in repeated_src:
+ repeated_msg.add().CopyFrom(item)
+ else:
+ repeated_msg.extend(repeated_src)
+ elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE:
+ getattr(msg, field_name).CopyFrom(getattr(src, field_name))
+ else:
+ setattr(msg, field_name, getattr(src, field_name))
+ # Only field specified in mask is merged.
+ self.assertEqual(msg, dst)
+
+ # Test merge nested fields.
+ nested_src = unittest_pb2.NestedTestAllTypes()
+ nested_dst = unittest_pb2.NestedTestAllTypes()
+ nested_src.child.payload.optional_int32 = 1234
+ nested_src.child.child.payload.optional_int32 = 5678
+ mask = field_mask_pb2.FieldMask()
+ mask.FromJsonString('child.payload')
+ mask.MergeMessage(nested_src, nested_dst)
+ self.assertEqual(1234, nested_dst.child.payload.optional_int32)
+ self.assertEqual(0, nested_dst.child.child.payload.optional_int32)
+
+ mask.FromJsonString('child.child.payload')
+ mask.MergeMessage(nested_src, nested_dst)
+ self.assertEqual(1234, nested_dst.child.payload.optional_int32)
+ self.assertEqual(5678, nested_dst.child.child.payload.optional_int32)
+
+ nested_dst.Clear()
+ mask.FromJsonString('child.child.payload')
+ mask.MergeMessage(nested_src, nested_dst)
+ self.assertEqual(0, nested_dst.child.payload.optional_int32)
+ self.assertEqual(5678, nested_dst.child.child.payload.optional_int32)
+
+ nested_dst.Clear()
+ mask.FromJsonString('child')
+ mask.MergeMessage(nested_src, nested_dst)
+ self.assertEqual(1234, nested_dst.child.payload.optional_int32)
+ self.assertEqual(5678, nested_dst.child.child.payload.optional_int32)
+
+ # Test MergeOptions.
+ nested_dst.Clear()
+ nested_dst.child.payload.optional_int64 = 4321
+ # Message fields will be merged by default.
+ mask.FromJsonString('child.payload')
+ mask.MergeMessage(nested_src, nested_dst)
+ self.assertEqual(1234, nested_dst.child.payload.optional_int32)
+ self.assertEqual(4321, nested_dst.child.payload.optional_int64)
+ # Change the behavior to replace message fields.
+ mask.FromJsonString('child.payload')
+ mask.MergeMessage(nested_src, nested_dst, True, False)
+ self.assertEqual(1234, nested_dst.child.payload.optional_int32)
+ self.assertEqual(0, nested_dst.child.payload.optional_int64)
+
+ # By default, fields missing in source are not cleared in destination.
+ nested_dst.payload.optional_int32 = 1234
+ self.assertTrue(nested_dst.HasField('payload'))
+ mask.FromJsonString('payload')
+ mask.MergeMessage(nested_src, nested_dst)
+ self.assertTrue(nested_dst.HasField('payload'))
+ # But they are cleared when replacing message fields.
+ nested_dst.Clear()
+ nested_dst.payload.optional_int32 = 1234
+ mask.FromJsonString('payload')
+ mask.MergeMessage(nested_src, nested_dst, True, False)
+ self.assertFalse(nested_dst.HasField('payload'))
+
+ nested_src.payload.repeated_int32.append(1234)
+ nested_dst.payload.repeated_int32.append(5678)
+ # Repeated fields will be appended by default.
+ mask.FromJsonString('payload.repeated_int32')
+ mask.MergeMessage(nested_src, nested_dst)
+ self.assertEqual(2, len(nested_dst.payload.repeated_int32))
+ self.assertEqual(5678, nested_dst.payload.repeated_int32[0])
+ self.assertEqual(1234, nested_dst.payload.repeated_int32[1])
+ # Change the behavior to replace repeated fields.
+ mask.FromJsonString('payload.repeated_int32')
+ mask.MergeMessage(nested_src, nested_dst, False, True)
+ self.assertEqual(1, len(nested_dst.payload.repeated_int32))
+ self.assertEqual(1234, nested_dst.payload.repeated_int32[0])
+
+
+class StructTest(unittest.TestCase):
+
+ def testStruct(self):
+ struct = struct_pb2.Struct()
+ struct_class = struct.__class__
+
+ struct['key1'] = 5
+ struct['key2'] = 'abc'
+ struct['key3'] = True
+ struct.get_or_create_struct('key4')['subkey'] = 11.0
+ struct_list = struct.get_or_create_list('key5')
+ struct_list.extend([6, 'seven', True, False, None])
+ struct_list.add_struct()['subkey2'] = 9
+
+ self.assertTrue(isinstance(struct, well_known_types.Struct))
+ self.assertEquals(5, struct['key1'])
+ self.assertEquals('abc', struct['key2'])
+ self.assertIs(True, struct['key3'])
+ self.assertEquals(11, struct['key4']['subkey'])
+ inner_struct = struct_class()
+ inner_struct['subkey2'] = 9
+ self.assertEquals([6, 'seven', True, False, None, inner_struct],
+ list(struct['key5'].items()))
+
+ serialized = struct.SerializeToString()
+
+ struct2 = struct_pb2.Struct()
+ struct2.ParseFromString(serialized)
+
+ self.assertEquals(struct, struct2)
+
+ self.assertTrue(isinstance(struct2, well_known_types.Struct))
+ self.assertEquals(5, struct2['key1'])
+ self.assertEquals('abc', struct2['key2'])
+ self.assertIs(True, struct2['key3'])
+ self.assertEquals(11, struct2['key4']['subkey'])
+ self.assertEquals([6, 'seven', True, False, None, inner_struct],
+ list(struct2['key5'].items()))
+
+ struct_list = struct2['key5']
+ self.assertEquals(6, struct_list[0])
+ self.assertEquals('seven', struct_list[1])
+ self.assertEquals(True, struct_list[2])
+ self.assertEquals(False, struct_list[3])
+ self.assertEquals(None, struct_list[4])
+ self.assertEquals(inner_struct, struct_list[5])
+
+ struct_list[1] = 7
+ self.assertEquals(7, struct_list[1])
+
+ struct_list.add_list().extend([1, 'two', True, False, None])
+ self.assertEquals([1, 'two', True, False, None],
+ list(struct_list[6].items()))
+
+ text_serialized = str(struct)
+ struct3 = struct_pb2.Struct()
+ text_format.Merge(text_serialized, struct3)
+ self.assertEquals(struct, struct3)
+
+ struct.get_or_create_struct('key3')['replace'] = 12
+ self.assertEquals(12, struct['key3']['replace'])
+
+
+class AnyTest(unittest.TestCase):
+
+ def testAnyMessage(self):
+ # Creates and sets message.
+ msg = any_test_pb2.TestAny()
+ msg_descriptor = msg.DESCRIPTOR
+ all_types = unittest_pb2.TestAllTypes()
+ all_descriptor = all_types.DESCRIPTOR
+ all_types.repeated_string.append(u'\u00fc\ua71f')
+ # Packs to Any.
+ msg.value.Pack(all_types)
+ self.assertEqual(msg.value.type_url,
+ 'type.googleapis.com/%s' % all_descriptor.full_name)
+ self.assertEqual(msg.value.value,
+ all_types.SerializeToString())
+ # Tests Is() method.
+ self.assertTrue(msg.value.Is(all_descriptor))
+ self.assertFalse(msg.value.Is(msg_descriptor))
+ # Unpacks Any.
+ unpacked_message = unittest_pb2.TestAllTypes()
+ self.assertTrue(msg.value.Unpack(unpacked_message))
+ self.assertEqual(all_types, unpacked_message)
+ # Unpacks to different type.
+ self.assertFalse(msg.value.Unpack(msg))
+ # Only Any messages have Pack method.
+ try:
+ msg.Pack(all_types)
+ except AttributeError:
+ pass
+ else:
+ raise AttributeError('%s should not have Pack method.' %
+ msg_descriptor.full_name)
+
+ def testMessageName(self):
+ # Creates and sets message.
+ submessage = any_test_pb2.TestAny()
+ submessage.int_value = 12345
+ msg = any_pb2.Any()
+ msg.Pack(submessage)
+ self.assertEqual(msg.TypeName(), 'google.protobuf.internal.TestAny')
+
+ def testPackWithCustomTypeUrl(self):
+ submessage = any_test_pb2.TestAny()
+ submessage.int_value = 12345
+ msg = any_pb2.Any()
+ # Pack with a custom type URL prefix.
+ msg.Pack(submessage, 'type.myservice.com')
+ self.assertEqual(msg.type_url,
+ 'type.myservice.com/%s' % submessage.DESCRIPTOR.full_name)
+ # Pack with a custom type URL prefix ending with '/'.
+ msg.Pack(submessage, 'type.myservice.com/')
+ self.assertEqual(msg.type_url,
+ 'type.myservice.com/%s' % submessage.DESCRIPTOR.full_name)
+ # Pack with an empty type URL prefix.
+ msg.Pack(submessage, '')
+ self.assertEqual(msg.type_url,
+ '/%s' % submessage.DESCRIPTOR.full_name)
+ # Test unpacking the type.
+ unpacked_message = any_test_pb2.TestAny()
+ self.assertTrue(msg.Unpack(unpacked_message))
+ self.assertEqual(submessage, unpacked_message)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/python/google/protobuf/internal/wire_format_test.py b/python/google/protobuf/internal/wire_format_test.py
index f659d18e..da120f33 100755
--- a/python/google/protobuf/internal/wire_format_test.py
+++ b/python/google/protobuf/internal/wire_format_test.py
@@ -35,9 +35,10 @@
__author__ = 'robinson@google.com (Will Robinson)'
try:
- import unittest2 as unittest
+ import unittest2 as unittest #PY26
except ImportError:
import unittest
+
from google.protobuf import message
from google.protobuf.internal import wire_format
diff --git a/python/google/protobuf/json_format.py b/python/google/protobuf/json_format.py
index d95557d7..edc0cb50 100644
--- a/python/google/protobuf/json_format.py
+++ b/python/google/protobuf/json_format.py
@@ -28,22 +28,36 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-"""Contains routines for printing protocol messages in JSON format."""
+"""Contains routines for printing protocol messages in JSON format.
+
+Simple usage example:
+
+ # Create a proto object and serialize it to a json format string.
+ message = my_proto_pb2.MyMessage(foo='bar')
+ json_string = json_format.MessageToJson(message)
+
+ # Parse a json format string to proto object.
+ message = json_format.Parse(json_string, my_proto_pb2.MyMessage())
+"""
__author__ = 'jieluo@google.com (Jie Luo)'
+try:
+ from collections import OrderedDict
+except ImportError:
+ from ordereddict import OrderedDict #PY26
import base64
-from datetime import datetime
import json
import math
import re
+import six
import sys
+from operator import methodcaller
from google.protobuf import descriptor
+from google.protobuf import symbol_database
_TIMESTAMPFOMAT = '%Y-%m-%dT%H:%M:%S'
-_NUMBER = re.compile(u'[0-9+-][0-9e.+-]*')
-_INTEGER = re.compile(u'[0-9+-]')
_INT_TYPES = frozenset([descriptor.FieldDescriptor.CPPTYPE_INT32,
descriptor.FieldDescriptor.CPPTYPE_UINT32,
descriptor.FieldDescriptor.CPPTYPE_INT64,
@@ -52,17 +66,23 @@ _INT64_TYPES = frozenset([descriptor.FieldDescriptor.CPPTYPE_INT64,
descriptor.FieldDescriptor.CPPTYPE_UINT64])
_FLOAT_TYPES = frozenset([descriptor.FieldDescriptor.CPPTYPE_FLOAT,
descriptor.FieldDescriptor.CPPTYPE_DOUBLE])
-if str is bytes:
- _UNICODETYPE = unicode
-else:
- _UNICODETYPE = str
+_INFINITY = 'Infinity'
+_NEG_INFINITY = '-Infinity'
+_NAN = 'NaN'
+_UNPAIRED_SURROGATE_PATTERN = re.compile(six.u(
+ r'[\ud800-\udbff](?![\udc00-\udfff])|(?<![\ud800-\udbff])[\udc00-\udfff]'
+))
-class SerializeToJsonError(Exception):
+class Error(Exception):
+ """Top-level module error for json_format."""
+
+
+class SerializeToJsonError(Error):
"""Thrown if serialization to JSON fails."""
-class ParseError(Exception):
+class ParseError(Error):
"""Thrown in case of parsing error."""
@@ -79,22 +99,8 @@ def MessageToJson(message, including_default_value_fields=False):
Returns:
A string containing the JSON formatted protocol buffer message.
"""
- js = _MessageToJsonObject(message, including_default_value_fields)
- return json.dumps(js, indent=2)
-
-
-def _MessageToJsonObject(message, including_default_value_fields):
- """Converts message to an object according to Proto3 JSON Specification."""
- message_descriptor = message.DESCRIPTOR
- if _IsTimestampMessage(message_descriptor):
- return _TimestampMessageToJsonObject(message)
- if _IsDurationMessage(message_descriptor):
- return _DurationMessageToJsonObject(message)
- if _IsFieldMaskMessage(message_descriptor):
- return _FieldMaskMessageToJsonObject(message)
- if _IsWrapperMessage(message_descriptor):
- return _WrapperMessageToJsonObject(message)
- return _RegularMessageToJsonObject(message, including_default_value_fields)
+ printer = _Printer(including_default_value_fields)
+ return printer.ToJsonString(message)
def _IsMapEntry(field):
@@ -103,199 +109,209 @@ def _IsMapEntry(field):
field.message_type.GetOptions().map_entry)
-def _RegularMessageToJsonObject(message, including_default_value_fields):
- """Converts normal message according to Proto3 JSON Specification."""
- js = {}
- fields = message.ListFields()
+class _Printer(object):
+ """JSON format printer for protocol message."""
- try:
- for field, value in fields:
- name = field.camelcase_name
- if _IsMapEntry(field):
- # Convert a map field.
- js_map = {}
- for key in value:
- if isinstance(key, bool):
- if key:
- recorded_key = 'true'
- else:
- recorded_key = 'false'
- else:
- recorded_key = key
- js_map[recorded_key] = _ConvertFieldToJsonObject(
- field.message_type.fields_by_name['value'],
- value[key], including_default_value_fields)
- js[name] = js_map
- elif field.label == descriptor.FieldDescriptor.LABEL_REPEATED:
- # Convert a repeated field.
- repeated = []
- for element in value:
- repeated.append(_ConvertFieldToJsonObject(
- field, element, including_default_value_fields))
- js[name] = repeated
- else:
- js[name] = _ConvertFieldToJsonObject(
- field, value, including_default_value_fields)
-
- # Serialize default value if including_default_value_fields is True.
- if including_default_value_fields:
- message_descriptor = message.DESCRIPTOR
- for field in message_descriptor.fields:
- # Singular message fields and oneof fields will not be affected.
- if ((field.label != descriptor.FieldDescriptor.LABEL_REPEATED and
- field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE) or
- field.containing_oneof):
- continue
+ def __init__(self,
+ including_default_value_fields=False):
+ self.including_default_value_fields = including_default_value_fields
+
+ def ToJsonString(self, message):
+ js = self._MessageToJsonObject(message)
+ return json.dumps(js, indent=2)
+
+ def _MessageToJsonObject(self, message):
+ """Converts message to an object according to Proto3 JSON Specification."""
+ message_descriptor = message.DESCRIPTOR
+ full_name = message_descriptor.full_name
+ if _IsWrapperMessage(message_descriptor):
+ return self._WrapperMessageToJsonObject(message)
+ if full_name in _WKTJSONMETHODS:
+ return methodcaller(_WKTJSONMETHODS[full_name][0], message)(self)
+ js = {}
+ return self._RegularMessageToJsonObject(message, js)
+
+ def _RegularMessageToJsonObject(self, message, js):
+ """Converts normal message according to Proto3 JSON Specification."""
+ fields = message.ListFields()
+
+ try:
+ for field, value in fields:
name = field.camelcase_name
- if name in js:
- # Skip the field which has been serailized already.
- continue
if _IsMapEntry(field):
- js[name] = {}
+ # Convert a map field.
+ v_field = field.message_type.fields_by_name['value']
+ js_map = {}
+ for key in value:
+ if isinstance(key, bool):
+ if key:
+ recorded_key = 'true'
+ else:
+ recorded_key = 'false'
+ else:
+ recorded_key = key
+ js_map[recorded_key] = self._FieldToJsonObject(
+ v_field, value[key])
+ js[name] = js_map
elif field.label == descriptor.FieldDescriptor.LABEL_REPEATED:
- js[name] = []
+ # Convert a repeated field.
+ js[name] = [self._FieldToJsonObject(field, k)
+ for k in value]
else:
- js[name] = _ConvertFieldToJsonObject(field, field.default_value)
-
- except ValueError as e:
- raise SerializeToJsonError(
- 'Failed to serialize {0} field: {1}'.format(field.name, e))
-
- return js
-
+ js[name] = self._FieldToJsonObject(field, value)
+
+ # Serialize default value if including_default_value_fields is True.
+ if self.including_default_value_fields:
+ message_descriptor = message.DESCRIPTOR
+ for field in message_descriptor.fields:
+ # Singular message fields and oneof fields will not be affected.
+ if ((field.label != descriptor.FieldDescriptor.LABEL_REPEATED and
+ field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE) or
+ field.containing_oneof):
+ continue
+ name = field.camelcase_name
+ if name in js:
+ # Skip the field which has been serailized already.
+ continue
+ if _IsMapEntry(field):
+ js[name] = {}
+ elif field.label == descriptor.FieldDescriptor.LABEL_REPEATED:
+ js[name] = []
+ else:
+ js[name] = self._FieldToJsonObject(field, field.default_value)
-def _ConvertFieldToJsonObject(
- field, value, including_default_value_fields=False):
- """Converts field value according to Proto3 JSON Specification."""
- if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE:
- return _MessageToJsonObject(value, including_default_value_fields)
- elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_ENUM:
- enum_value = field.enum_type.values_by_number.get(value, None)
- if enum_value is not None:
- return enum_value.name
- else:
- raise SerializeToJsonError('Enum field contains an integer value '
- 'which can not mapped to an enum value.')
- elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_STRING:
- if field.type == descriptor.FieldDescriptor.TYPE_BYTES:
- # Use base64 Data encoding for bytes
- return base64.b64encode(value).decode('utf-8')
- else:
- return value
- elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_BOOL:
- if value:
- return True
- else:
- return False
- elif field.cpp_type in _INT64_TYPES:
- return str(value)
- elif field.cpp_type in _FLOAT_TYPES:
- if math.isinf(value):
- if value < 0.0:
- return '-Infinity'
+ except ValueError as e:
+ raise SerializeToJsonError(
+ 'Failed to serialize {0} field: {1}.'.format(field.name, e))
+
+ return js
+
+ def _FieldToJsonObject(self, field, value):
+ """Converts field value according to Proto3 JSON Specification."""
+ if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE:
+ return self._MessageToJsonObject(value)
+ elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_ENUM:
+ enum_value = field.enum_type.values_by_number.get(value, None)
+ if enum_value is not None:
+ return enum_value.name
else:
- return 'Infinity'
- if math.isnan(value):
- return 'NaN'
- return value
+ raise SerializeToJsonError('Enum field contains an integer value '
+ 'which can not mapped to an enum value.')
+ elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_STRING:
+ if field.type == descriptor.FieldDescriptor.TYPE_BYTES:
+ # Use base64 Data encoding for bytes
+ return base64.b64encode(value).decode('utf-8')
+ else:
+ return value
+ elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_BOOL:
+ return bool(value)
+ elif field.cpp_type in _INT64_TYPES:
+ return str(value)
+ elif field.cpp_type in _FLOAT_TYPES:
+ if math.isinf(value):
+ if value < 0.0:
+ return _NEG_INFINITY
+ else:
+ return _INFINITY
+ if math.isnan(value):
+ return _NAN
+ return value
+
+ def _AnyMessageToJsonObject(self, message):
+ """Converts Any message according to Proto3 JSON Specification."""
+ if not message.ListFields():
+ return {}
+ # Must print @type first, use OrderedDict instead of {}
+ js = OrderedDict()
+ type_url = message.type_url
+ js['@type'] = type_url
+ sub_message = _CreateMessageFromTypeUrl(type_url)
+ sub_message.ParseFromString(message.value)
+ message_descriptor = sub_message.DESCRIPTOR
+ full_name = message_descriptor.full_name
+ if _IsWrapperMessage(message_descriptor):
+ js['value'] = self._WrapperMessageToJsonObject(sub_message)
+ return js
+ if full_name in _WKTJSONMETHODS:
+ js['value'] = methodcaller(_WKTJSONMETHODS[full_name][0],
+ sub_message)(self)
+ return js
+ return self._RegularMessageToJsonObject(sub_message, js)
+
+ def _GenericMessageToJsonObject(self, message):
+ """Converts message according to Proto3 JSON Specification."""
+ # Duration, Timestamp and FieldMask have ToJsonString method to do the
+ # convert. Users can also call the method directly.
+ return message.ToJsonString()
+
+ def _ValueMessageToJsonObject(self, message):
+ """Converts Value message according to Proto3 JSON Specification."""
+ which = message.WhichOneof('kind')
+ # If the Value message is not set treat as null_value when serialize
+ # to JSON. The parse back result will be different from original message.
+ if which is None or which == 'null_value':
+ return None
+ if which == 'list_value':
+ return self._ListValueMessageToJsonObject(message.list_value)
+ if which == 'struct_value':
+ value = message.struct_value
+ else:
+ value = getattr(message, which)
+ oneof_descriptor = message.DESCRIPTOR.fields_by_name[which]
+ return self._FieldToJsonObject(oneof_descriptor, value)
+ def _ListValueMessageToJsonObject(self, message):
+ """Converts ListValue message according to Proto3 JSON Specification."""
+ return [self._ValueMessageToJsonObject(value)
+ for value in message.values]
-def _IsTimestampMessage(message_descriptor):
- return (message_descriptor.name == 'Timestamp' and
- message_descriptor.file.name == 'google/protobuf/timestamp.proto')
-
-
-def _TimestampMessageToJsonObject(message):
- """Converts Timestamp message according to Proto3 JSON Specification."""
- nanos = message.nanos % 1e9
- dt = datetime.utcfromtimestamp(
- message.seconds + (message.nanos - nanos) / 1e9)
- result = dt.isoformat()
- if (nanos % 1e9) == 0:
- # If there are 0 fractional digits, the fractional
- # point '.' should be omitted when serializing.
- return result + 'Z'
- if (nanos % 1e6) == 0:
- # Serialize 3 fractional digits.
- return result + '.%03dZ' % (nanos / 1e6)
- if (nanos % 1e3) == 0:
- # Serialize 6 fractional digits.
- return result + '.%06dZ' % (nanos / 1e3)
- # Serialize 9 fractional digits.
- return result + '.%09dZ' % nanos
-
-
-def _IsDurationMessage(message_descriptor):
- return (message_descriptor.name == 'Duration' and
- message_descriptor.file.name == 'google/protobuf/duration.proto')
-
-
-def _DurationMessageToJsonObject(message):
- """Converts Duration message according to Proto3 JSON Specification."""
- if message.seconds < 0 or message.nanos < 0:
- result = '-'
- seconds = - message.seconds + int((0 - message.nanos) / 1e9)
- nanos = (0 - message.nanos) % 1e9
- else:
- result = ''
- seconds = message.seconds + int(message.nanos / 1e9)
- nanos = message.nanos % 1e9
- result += '%d' % seconds
- if (nanos % 1e9) == 0:
- # If there are 0 fractional digits, the fractional
- # point '.' should be omitted when serializing.
- return result + 's'
- if (nanos % 1e6) == 0:
- # Serialize 3 fractional digits.
- return result + '.%03ds' % (nanos / 1e6)
- if (nanos % 1e3) == 0:
- # Serialize 6 fractional digits.
- return result + '.%06ds' % (nanos / 1e3)
- # Serialize 9 fractional digits.
- return result + '.%09ds' % nanos
-
-
-def _IsFieldMaskMessage(message_descriptor):
- return (message_descriptor.name == 'FieldMask' and
- message_descriptor.file.name == 'google/protobuf/field_mask.proto')
-
-
-def _FieldMaskMessageToJsonObject(message):
- """Converts FieldMask message according to Proto3 JSON Specification."""
- result = ''
- first = True
- for path in message.paths:
- if not first:
- result += ','
- result += path
- first = False
- return result
+ def _StructMessageToJsonObject(self, message):
+ """Converts Struct message according to Proto3 JSON Specification."""
+ fields = message.fields
+ ret = {}
+ for key in fields:
+ ret[key] = self._ValueMessageToJsonObject(fields[key])
+ return ret
+
+ def _WrapperMessageToJsonObject(self, message):
+ return self._FieldToJsonObject(
+ message.DESCRIPTOR.fields_by_name['value'], message.value)
def _IsWrapperMessage(message_descriptor):
return message_descriptor.file.name == 'google/protobuf/wrappers.proto'
-def _WrapperMessageToJsonObject(message):
- return _ConvertFieldToJsonObject(
- message.DESCRIPTOR.fields_by_name['value'], message.value)
-
-
def _DuplicateChecker(js):
result = {}
for name, value in js:
if name in result:
- raise ParseError('Failed to load JSON: duplicate key ' + name)
+ raise ParseError('Failed to load JSON: duplicate key {0}.'.format(name))
result[name] = value
return result
-def Parse(text, message):
+def _CreateMessageFromTypeUrl(type_url):
+ # TODO(jieluo): Should add a way that users can register the type resolver
+ # instead of the default one.
+ db = symbol_database.Default()
+ type_name = type_url.split('/')[-1]
+ try:
+ message_descriptor = db.pool.FindMessageTypeByName(type_name)
+ except KeyError:
+ raise TypeError(
+ 'Can not find message descriptor by type_url: {0}.'.format(type_url))
+ message_class = db.GetPrototype(message_descriptor)
+ return message_class()
+
+
+def Parse(text, message, ignore_unknown_fields=False):
"""Parses a JSON representation of a protocol message into a message.
Args:
text: Message JSON representation.
- message: A protocol beffer message to merge into.
+ message: A protocol buffer message to merge into.
+ ignore_unknown_fields: If True, do not raise errors for unknown fields.
Returns:
The same message passed as argument.
@@ -303,7 +319,7 @@ def Parse(text, message):
Raises::
ParseError: On JSON parsing problems.
"""
- if not isinstance(text, _UNICODETYPE): text = text.decode('utf-8')
+ if not isinstance(text, six.text_type): text = text.decode('utf-8')
try:
if sys.version_info < (2, 7):
# object_pair_hook is not supported before python2.7
@@ -311,214 +327,227 @@ def Parse(text, message):
else:
js = json.loads(text, object_pairs_hook=_DuplicateChecker)
except ValueError as e:
- raise ParseError('Failed to load JSON: ' + str(e))
- _ConvertFieldValuePair(js, message)
+ raise ParseError('Failed to load JSON: {0}.'.format(str(e)))
+ parser = _Parser(ignore_unknown_fields)
+ parser.ConvertMessage(js, message)
return message
-def _ConvertFieldValuePair(js, message):
- """Convert field value pairs into regular message.
+_INT_OR_FLOAT = six.integer_types + (float,)
- Args:
- js: A JSON object to convert the field value pairs.
- message: A regular protocol message to record the data.
- Raises:
- ParseError: In case of problems converting.
- """
- names = []
- message_descriptor = message.DESCRIPTOR
- for name in js:
- try:
- field = message_descriptor.fields_by_camelcase_name.get(name, None)
- if not field:
- raise ParseError(
- 'Message type "{0}" has no field named "{1}".'.format(
- message_descriptor.full_name, name))
- if name in names:
- raise ParseError(
- 'Message type "{0}" should not have multiple "{1}" fields.'.format(
- message.DESCRIPTOR.full_name, name))
- names.append(name)
- # Check no other oneof field is parsed.
- if field.containing_oneof is not None:
- oneof_name = field.containing_oneof.name
- if oneof_name in names:
- raise ParseError('Message type "{0}" should not have multiple "{1}" '
- 'oneof fields.'.format(
- message.DESCRIPTOR.full_name, oneof_name))
- names.append(oneof_name)
-
- value = js[name]
- if value is None:
- message.ClearField(field.name)
- continue
-
- # Parse field value.
- if _IsMapEntry(field):
- message.ClearField(field.name)
- _ConvertMapFieldValue(value, message, field)
- elif field.label == descriptor.FieldDescriptor.LABEL_REPEATED:
- message.ClearField(field.name)
- if not isinstance(value, list):
- raise ParseError('repeated field {0} must be in [] which is '
- '{1}'.format(name, value))
- for item in value:
- if item is None:
- continue
- if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE:
- sub_message = getattr(message, field.name).add()
- _ConvertMessage(item, sub_message)
- else:
- getattr(message, field.name).append(
- _ConvertScalarFieldValue(item, field))
- elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE:
- sub_message = getattr(message, field.name)
- _ConvertMessage(value, sub_message)
- else:
- setattr(message, field.name, _ConvertScalarFieldValue(value, field))
- except ParseError as e:
- if field and field.containing_oneof is None:
- raise ParseError('Failed to parse {0} field: {1}'.format(name, e))
- else:
- raise ParseError(str(e))
- except ValueError as e:
- raise ParseError('Failed to parse {0} field: {1}'.format(name, e))
- except TypeError as e:
- raise ParseError('Failed to parse {0} field: {1}'.format(name, e))
+class _Parser(object):
+ """JSON format parser for protocol message."""
+ def __init__(self,
+ ignore_unknown_fields):
+ self.ignore_unknown_fields = ignore_unknown_fields
-def _ConvertMessage(value, message):
- """Convert a JSON object into a message.
+ def ConvertMessage(self, value, message):
+ """Convert a JSON object into a message.
- Args:
- value: A JSON object.
- message: A WKT or regular protocol message to record the data.
+ Args:
+ value: A JSON object.
+ message: A WKT or regular protocol message to record the data.
- Raises:
- ParseError: In case of convert problems.
- """
- message_descriptor = message.DESCRIPTOR
- if _IsTimestampMessage(message_descriptor):
- _ConvertTimestampMessage(value, message)
- elif _IsDurationMessage(message_descriptor):
- _ConvertDurationMessage(value, message)
- elif _IsFieldMaskMessage(message_descriptor):
- _ConvertFieldMaskMessage(value, message)
- elif _IsWrapperMessage(message_descriptor):
- _ConvertWrapperMessage(value, message)
- else:
- _ConvertFieldValuePair(value, message)
-
-
-def _ConvertTimestampMessage(value, message):
- """Convert a JSON representation into Timestamp message."""
- timezone_offset = value.find('Z')
- if timezone_offset == -1:
- timezone_offset = value.find('+')
- if timezone_offset == -1:
- timezone_offset = value.rfind('-')
- if timezone_offset == -1:
- raise ParseError(
- 'Failed to parse timestamp: missing valid timezone offset.')
- time_value = value[0:timezone_offset]
- # Parse datetime and nanos
- point_position = time_value.find('.')
- if point_position == -1:
- second_value = time_value
- nano_value = ''
- else:
- second_value = time_value[:point_position]
- nano_value = time_value[point_position + 1:]
- date_object = datetime.strptime(second_value, _TIMESTAMPFOMAT)
- td = date_object - datetime(1970, 1, 1)
- seconds = td.seconds + td.days * 24 * 3600
- if len(nano_value) > 9:
- raise ParseError(
- 'Failed to parse Timestamp: nanos {0} more than '
- '9 fractional digits.'.format(nano_value))
- if nano_value:
- nanos = round(float('0.' + nano_value) * 1e9)
- else:
- nanos = 0
- # Parse timezone offsets
- if value[timezone_offset] == 'Z':
- if len(value) != timezone_offset + 1:
- raise ParseError(
- 'Failed to parse timestamp: invalid trailing data {0}.'.format(value))
- else:
- timezone = value[timezone_offset:]
- pos = timezone.find(':')
- if pos == -1:
- raise ParseError(
- 'Invalid timezone offset value: ' + timezone)
- if timezone[0] == '+':
- seconds += (int(timezone[1:pos])*60+int(timezone[pos+1:]))*60
+ Raises:
+ ParseError: In case of convert problems.
+ """
+ message_descriptor = message.DESCRIPTOR
+ full_name = message_descriptor.full_name
+ if _IsWrapperMessage(message_descriptor):
+ self._ConvertWrapperMessage(value, message)
+ elif full_name in _WKTJSONMETHODS:
+ methodcaller(_WKTJSONMETHODS[full_name][1], value, message)(self)
else:
- seconds -= (int(timezone[1:pos])*60+int(timezone[pos+1:]))*60
- # Set seconds and nanos
- message.seconds = int(seconds)
- message.nanos = int(nanos)
-
-
-def _ConvertDurationMessage(value, message):
- """Convert a JSON representation into Duration message."""
- if value[-1] != 's':
- raise ParseError(
- 'Duration must end with letter "s": ' + value)
- try:
- duration = float(value[:-1])
- except ValueError:
- raise ParseError(
- 'Couldn\'t parse duration: ' + value)
- message.seconds = int(duration)
- message.nanos = int(round((duration - message.seconds) * 1e9))
-
-
-def _ConvertFieldMaskMessage(value, message):
- """Convert a JSON representation into FieldMask message."""
- for path in value.split(','):
- message.paths.append(path)
-
-
-def _ConvertWrapperMessage(value, message):
- """Convert a JSON representation into Wrapper message."""
- field = message.DESCRIPTOR.fields_by_name['value']
- setattr(message, 'value', _ConvertScalarFieldValue(value, field))
-
-
-def _ConvertMapFieldValue(value, message, field):
- """Convert map field value for a message map field.
-
- Args:
- value: A JSON object to convert the map field value.
- message: A protocol message to record the converted data.
- field: The descriptor of the map field to be converted.
+ self._ConvertFieldValuePair(value, message)
+
+ def _ConvertFieldValuePair(self, js, message):
+ """Convert field value pairs into regular message.
+
+ Args:
+ js: A JSON object to convert the field value pairs.
+ message: A regular protocol message to record the data.
+
+ Raises:
+ ParseError: In case of problems converting.
+ """
+ names = []
+ message_descriptor = message.DESCRIPTOR
+ for name in js:
+ try:
+ field = message_descriptor.fields_by_camelcase_name.get(name, None)
+ if not field:
+ if self.ignore_unknown_fields:
+ continue
+ raise ParseError(
+ 'Message type "{0}" has no field named "{1}".'.format(
+ message_descriptor.full_name, name))
+ if name in names:
+ raise ParseError('Message type "{0}" should not have multiple '
+ '"{1}" fields.'.format(
+ message.DESCRIPTOR.full_name, name))
+ names.append(name)
+ # Check no other oneof field is parsed.
+ if field.containing_oneof is not None:
+ oneof_name = field.containing_oneof.name
+ if oneof_name in names:
+ raise ParseError('Message type "{0}" should not have multiple '
+ '"{1}" oneof fields.'.format(
+ message.DESCRIPTOR.full_name, oneof_name))
+ names.append(oneof_name)
+
+ value = js[name]
+ if value is None:
+ message.ClearField(field.name)
+ continue
- Raises:
- ParseError: In case of convert problems.
- """
- if not isinstance(value, dict):
- raise ParseError(
- 'Map fieled {0} must be in {} which is {1}.'.format(field.name, value))
- key_field = field.message_type.fields_by_name['key']
- value_field = field.message_type.fields_by_name['value']
- for key in value:
- key_value = _ConvertScalarFieldValue(key, key_field, True)
- if value_field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE:
- _ConvertMessage(value[key], getattr(message, field.name)[key_value])
+ # Parse field value.
+ if _IsMapEntry(field):
+ message.ClearField(field.name)
+ self._ConvertMapFieldValue(value, message, field)
+ elif field.label == descriptor.FieldDescriptor.LABEL_REPEATED:
+ message.ClearField(field.name)
+ if not isinstance(value, list):
+ raise ParseError('repeated field {0} must be in [] which is '
+ '{1}.'.format(name, value))
+ if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE:
+ # Repeated message field.
+ for item in value:
+ sub_message = getattr(message, field.name).add()
+ # None is a null_value in Value.
+ if (item is None and
+ sub_message.DESCRIPTOR.full_name != 'google.protobuf.Value'):
+ raise ParseError('null is not allowed to be used as an element'
+ ' in a repeated field.')
+ self.ConvertMessage(item, sub_message)
+ else:
+ # Repeated scalar field.
+ for item in value:
+ if item is None:
+ raise ParseError('null is not allowed to be used as an element'
+ ' in a repeated field.')
+ getattr(message, field.name).append(
+ _ConvertScalarFieldValue(item, field))
+ elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE:
+ sub_message = getattr(message, field.name)
+ self.ConvertMessage(value, sub_message)
+ else:
+ setattr(message, field.name, _ConvertScalarFieldValue(value, field))
+ except ParseError as e:
+ if field and field.containing_oneof is None:
+ raise ParseError('Failed to parse {0} field: {1}'.format(name, e))
+ else:
+ raise ParseError(str(e))
+ except ValueError as e:
+ raise ParseError('Failed to parse {0} field: {1}.'.format(name, e))
+ except TypeError as e:
+ raise ParseError('Failed to parse {0} field: {1}.'.format(name, e))
+
+ def _ConvertAnyMessage(self, value, message):
+ """Convert a JSON representation into Any message."""
+ if isinstance(value, dict) and not value:
+ return
+ try:
+ type_url = value['@type']
+ except KeyError:
+ raise ParseError('@type is missing when parsing any message.')
+
+ sub_message = _CreateMessageFromTypeUrl(type_url)
+ message_descriptor = sub_message.DESCRIPTOR
+ full_name = message_descriptor.full_name
+ if _IsWrapperMessage(message_descriptor):
+ self._ConvertWrapperMessage(value['value'], sub_message)
+ elif full_name in _WKTJSONMETHODS:
+ methodcaller(
+ _WKTJSONMETHODS[full_name][1], value['value'], sub_message)(self)
+ else:
+ del value['@type']
+ self._ConvertFieldValuePair(value, sub_message)
+ # Sets Any message
+ message.value = sub_message.SerializeToString()
+ message.type_url = type_url
+
+ def _ConvertGenericMessage(self, value, message):
+ """Convert a JSON representation into message with FromJsonString."""
+ # Durantion, Timestamp, FieldMask have FromJsonString method to do the
+ # convert. Users can also call the method directly.
+ message.FromJsonString(value)
+
+ def _ConvertValueMessage(self, value, message):
+ """Convert a JSON representation into Value message."""
+ if isinstance(value, dict):
+ self._ConvertStructMessage(value, message.struct_value)
+ elif isinstance(value, list):
+ self. _ConvertListValueMessage(value, message.list_value)
+ elif value is None:
+ message.null_value = 0
+ elif isinstance(value, bool):
+ message.bool_value = value
+ elif isinstance(value, six.string_types):
+ message.string_value = value
+ elif isinstance(value, _INT_OR_FLOAT):
+ message.number_value = value
else:
- getattr(message, field.name)[key_value] = _ConvertScalarFieldValue(
- value[key], value_field)
+ raise ParseError('Unexpected type for Value message.')
+
+ def _ConvertListValueMessage(self, value, message):
+ """Convert a JSON representation into ListValue message."""
+ if not isinstance(value, list):
+ raise ParseError(
+ 'ListValue must be in [] which is {0}.'.format(value))
+ message.ClearField('values')
+ for item in value:
+ self._ConvertValueMessage(item, message.values.add())
+
+ def _ConvertStructMessage(self, value, message):
+ """Convert a JSON representation into Struct message."""
+ if not isinstance(value, dict):
+ raise ParseError(
+ 'Struct must be in a dict which is {0}.'.format(value))
+ for key in value:
+ self._ConvertValueMessage(value[key], message.fields[key])
+ return
+
+ def _ConvertWrapperMessage(self, value, message):
+ """Convert a JSON representation into Wrapper message."""
+ field = message.DESCRIPTOR.fields_by_name['value']
+ setattr(message, 'value', _ConvertScalarFieldValue(value, field))
+
+ def _ConvertMapFieldValue(self, value, message, field):
+ """Convert map field value for a message map field.
+
+ Args:
+ value: A JSON object to convert the map field value.
+ message: A protocol message to record the converted data.
+ field: The descriptor of the map field to be converted.
+
+ Raises:
+ ParseError: In case of convert problems.
+ """
+ if not isinstance(value, dict):
+ raise ParseError(
+ 'Map field {0} must be in a dict which is {1}.'.format(
+ field.name, value))
+ key_field = field.message_type.fields_by_name['key']
+ value_field = field.message_type.fields_by_name['value']
+ for key in value:
+ key_value = _ConvertScalarFieldValue(key, key_field, True)
+ if value_field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE:
+ self.ConvertMessage(value[key], getattr(
+ message, field.name)[key_value])
+ else:
+ getattr(message, field.name)[key_value] = _ConvertScalarFieldValue(
+ value[key], value_field)
-def _ConvertScalarFieldValue(value, field, require_quote=False):
+def _ConvertScalarFieldValue(value, field, require_str=False):
"""Convert a single scalar field value.
Args:
value: A scalar value to convert the scalar field value.
field: The descriptor of the field to convert.
- require_quote: If True, '"' is required for the field value.
+ require_str: If True, the field value must be a str.
Returns:
The converted scalar field value
@@ -531,11 +560,15 @@ def _ConvertScalarFieldValue(value, field, require_quote=False):
elif field.cpp_type in _FLOAT_TYPES:
return _ConvertFloat(value)
elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_BOOL:
- return _ConvertBool(value, require_quote)
+ return _ConvertBool(value, require_str)
elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_STRING:
if field.type == descriptor.FieldDescriptor.TYPE_BYTES:
return base64.b64decode(value)
else:
+ # Checking for unpaired surrogates appears to be unreliable,
+ # depending on the specific Python version, so we check manually.
+ if _UNPAIRED_SURROGATE_PATTERN.search(value):
+ raise ParseError('Unpaired surrogate')
return value
elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_ENUM:
# Convert an enum value.
@@ -561,10 +594,10 @@ def _ConvertInteger(value):
ParseError: If an integer couldn't be consumed.
"""
if isinstance(value, float):
- raise ParseError('Couldn\'t parse integer: {0}'.format(value))
+ raise ParseError('Couldn\'t parse integer: {0}.'.format(value))
- if isinstance(value, _UNICODETYPE) and not _INTEGER.match(value):
- raise ParseError('Couldn\'t parse integer: "{0}"'.format(value))
+ if isinstance(value, six.text_type) and value.find(' ') != -1:
+ raise ParseError('Couldn\'t parse integer: "{0}".'.format(value))
return int(value)
@@ -572,28 +605,28 @@ def _ConvertInteger(value):
def _ConvertFloat(value):
"""Convert an floating point number."""
if value == 'nan':
- raise ParseError('Couldn\'t parse float "nan", use "NaN" instead')
+ raise ParseError('Couldn\'t parse float "nan", use "NaN" instead.')
try:
# Assume Python compatible syntax.
return float(value)
except ValueError:
# Check alternative spellings.
- if value == '-Infinity':
+ if value == _NEG_INFINITY:
return float('-inf')
- elif value == 'Infinity':
+ elif value == _INFINITY:
return float('inf')
- elif value == 'NaN':
+ elif value == _NAN:
return float('nan')
else:
- raise ParseError('Couldn\'t parse float: {0}'.format(value))
+ raise ParseError('Couldn\'t parse float: {0}.'.format(value))
-def _ConvertBool(value, require_quote):
+def _ConvertBool(value, require_str):
"""Convert a boolean value.
Args:
value: A scalar value to convert.
- require_quote: If True, '"' is required for the boolean value.
+ require_str: If True, value must be a str.
Returns:
The bool parsed.
@@ -601,14 +634,31 @@ def _ConvertBool(value, require_quote):
Raises:
ParseError: If a boolean value couldn't be consumed.
"""
- if require_quote:
+ if require_str:
if value == 'true':
return True
elif value == 'false':
return False
else:
- raise ParseError('Expect "true" or "false", not {0}.'.format(value))
+ raise ParseError('Expected "true" or "false", not {0}.'.format(value))
if not isinstance(value, bool):
raise ParseError('Expected true or false without quotes.')
return value
+
+_WKTJSONMETHODS = {
+ 'google.protobuf.Any': ['_AnyMessageToJsonObject',
+ '_ConvertAnyMessage'],
+ 'google.protobuf.Duration': ['_GenericMessageToJsonObject',
+ '_ConvertGenericMessage'],
+ 'google.protobuf.FieldMask': ['_GenericMessageToJsonObject',
+ '_ConvertGenericMessage'],
+ 'google.protobuf.ListValue': ['_ListValueMessageToJsonObject',
+ '_ConvertListValueMessage'],
+ 'google.protobuf.Struct': ['_StructMessageToJsonObject',
+ '_ConvertStructMessage'],
+ 'google.protobuf.Timestamp': ['_GenericMessageToJsonObject',
+ '_ConvertGenericMessage'],
+ 'google.protobuf.Value': ['_ValueMessageToJsonObject',
+ '_ConvertValueMessage']
+}
diff --git a/python/google/protobuf/message.py b/python/google/protobuf/message.py
index de2f5697..606f735f 100755
--- a/python/google/protobuf/message.py
+++ b/python/google/protobuf/message.py
@@ -255,6 +255,9 @@ class Message(object):
def ClearExtension(self, extension_handle):
raise NotImplementedError
+ def DiscardUnknownFields(self):
+ raise NotImplementedError
+
def ByteSize(self):
"""Returns the serialized size of this message.
Recursively calls ByteSize() on all contained messages.
diff --git a/python/google/protobuf/message_factory.py b/python/google/protobuf/message_factory.py
index 9cd9c2a8..1b059d13 100644
--- a/python/google/protobuf/message_factory.py
+++ b/python/google/protobuf/message_factory.py
@@ -39,7 +39,6 @@ my_proto_instance = message_classes['some.proto.package.MessageName']()
__author__ = 'matthewtoia@google.com (Matt Toia)'
-from google.protobuf import descriptor_database
from google.protobuf import descriptor_pool
from google.protobuf import message
from google.protobuf import reflection
@@ -50,8 +49,7 @@ class MessageFactory(object):
def __init__(self, pool=None):
"""Initializes a new factory."""
- self.pool = (pool or descriptor_pool.DescriptorPool(
- descriptor_database.DescriptorDatabase()))
+ self.pool = pool or descriptor_pool.DescriptorPool()
# local cache of all classes built from protobuf descriptors
self._classes = {}
diff --git a/python/google/protobuf/pyext/__init__.py b/python/google/protobuf/pyext/__init__.py
index e69de29b..55856141 100644
--- a/python/google/protobuf/pyext/__init__.py
+++ b/python/google/protobuf/pyext/__init__.py
@@ -0,0 +1,4 @@
+try:
+ __import__('pkg_resources').declare_namespace(__name__)
+except ImportError:
+ __path__ = __import__('pkgutil').extend_path(__path__, __name__)
diff --git a/python/google/protobuf/pyext/cpp_message.py b/python/google/protobuf/pyext/cpp_message.py
index b215211e..fc8eb32d 100644
--- a/python/google/protobuf/pyext/cpp_message.py
+++ b/python/google/protobuf/pyext/cpp_message.py
@@ -48,9 +48,9 @@ class GeneratedProtocolMessageType(_message.MessageMeta):
classes at runtime, as in this example:
mydescriptor = Descriptor(.....)
- class MyProtoClass(Message):
- __metaclass__ = GeneratedProtocolMessageType
- DESCRIPTOR = mydescriptor
+ factory = symbol_database.Default()
+ factory.pool.AddDescriptor(mydescriptor)
+ MyProtoClass = factory.GetPrototype(mydescriptor)
myproto_instance = MyProtoClass()
myproto.foo_field = 23
...
diff --git a/python/google/protobuf/pyext/descriptor.cc b/python/google/protobuf/pyext/descriptor.cc
index 61a3d237..e6ef5ef5 100644
--- a/python/google/protobuf/pyext/descriptor.cc
+++ b/python/google/protobuf/pyext/descriptor.cc
@@ -92,11 +92,10 @@ PyObject* PyString_FromCppString(const string& str) {
// TODO(amauryfa): Change the proto2 compiler to remove the assignments, and
// remove this hack.
bool _CalledFromGeneratedFile(int stacklevel) {
- PyThreadState *state = PyThreadState_GET();
- if (state == NULL) {
- return false;
- }
- PyFrameObject* frame = state->frame;
+#ifndef PYPY_VERSION
+ // This check is not critical and is somewhat difficult to implement correctly
+ // in PyPy.
+ PyFrameObject* frame = PyEval_GetFrame();
if (frame == NULL) {
return false;
}
@@ -130,6 +129,7 @@ bool _CalledFromGeneratedFile(int stacklevel) {
// Filename is not ending with _pb2.
return false;
}
+#endif
return true;
}
@@ -172,12 +172,16 @@ template<>
const FileDescriptor* GetFileDescriptor(const OneofDescriptor* descriptor) {
return descriptor->containing_type()->file();
}
+template<>
+const FileDescriptor* GetFileDescriptor(const MethodDescriptor* descriptor) {
+ return descriptor->service()->file();
+}
// Converts options into a Python protobuf, and cache the result.
//
// This is a bit tricky because options can contain extension fields defined in
// the same proto file. In this case the options parsed from the serialized_pb
-// have unkown fields, and we need to parse them again.
+// have unknown fields, and we need to parse them again.
//
// Always returns a new reference.
template<class DescriptorClass>
@@ -200,17 +204,33 @@ static PyObject* GetOrBuildOptions(const DescriptorClass *descriptor) {
// read-only instance.
const Message& options(descriptor->options());
const Descriptor *message_type = options.GetDescriptor();
- PyObject* message_class(cdescriptor_pool::GetMessageClass(
- pool, message_type));
+ CMessageClass* message_class(
+ cdescriptor_pool::GetMessageClass(pool, message_type));
+ if (message_class == NULL) {
+ // The Options message was not found in the current DescriptorPool.
+ // This means that the pool cannot contain any extensions to the Options
+ // message either, so falling back to the basic pool we can only increase
+ // the chances of successfully parsing the options.
+ PyErr_Clear();
+ pool = GetDefaultDescriptorPool();
+ message_class = cdescriptor_pool::GetMessageClass(pool, message_type);
+ }
if (message_class == NULL) {
PyErr_Format(PyExc_TypeError, "Could not retrieve class for Options: %s",
message_type->full_name().c_str());
return NULL;
}
- ScopedPyObjectPtr value(PyEval_CallObject(message_class, NULL));
+ ScopedPyObjectPtr value(
+ PyEval_CallObject(message_class->AsPyObject(), NULL));
if (value == NULL) {
return NULL;
}
+ if (!PyObject_TypeCheck(value.get(), &CMessage_Type)) {
+ PyErr_Format(PyExc_TypeError, "Invalid class for %s: %s",
+ message_type->full_name().c_str(),
+ Py_TYPE(value.get())->tp_name);
+ return NULL;
+ }
CMessage* cmsg = reinterpret_cast<CMessage*>(value.get());
const Reflection* reflection = options.GetReflection();
@@ -233,7 +253,7 @@ static PyObject* GetOrBuildOptions(const DescriptorClass *descriptor) {
// Cache the result.
Py_INCREF(value.get());
- (*pool->descriptor_options)[descriptor] = value.get();
+ (*descriptor_options)[descriptor] = value.get();
return value.release();
}
@@ -327,7 +347,8 @@ PyObject* NewInternedDescriptor(PyTypeObject* type,
PyDescriptorPool* pool = GetDescriptorPool_FromPool(
GetFileDescriptor(descriptor)->pool());
if (pool == NULL) {
- Py_DECREF(py_descriptor);
+ // Don't DECREF, the object is not fully initialized.
+ PyObject_Del(py_descriptor);
return NULL;
}
Py_INCREF(pool);
@@ -418,11 +439,11 @@ static PyObject* GetConcreteClass(PyBaseDescriptor* self, void *closure) {
// which contains this descriptor.
// This might not be the one you expect! For example the returned object does
// not know about extensions defined in a custom pool.
- PyObject* concrete_class(cdescriptor_pool::GetMessageClass(
+ CMessageClass* concrete_class(cdescriptor_pool::GetMessageClass(
GetDescriptorPool_FromPool(_GetDescriptor(self)->file()->pool()),
_GetDescriptor(self)));
Py_XINCREF(concrete_class);
- return concrete_class;
+ return concrete_class->AsPyObject();
}
static PyObject* GetFieldsByName(PyBaseDescriptor* self, void *closure) {
@@ -1075,7 +1096,7 @@ PyTypeObject PyEnumDescriptor_Type = {
0, // tp_weaklistoffset
0, // tp_iter
0, // tp_iternext
- enum_descriptor::Methods, // tp_getset
+ enum_descriptor::Methods, // tp_methods
0, // tp_members
enum_descriptor::Getters, // tp_getset
&descriptor::PyBaseDescriptor_Type, // tp_base
@@ -1213,6 +1234,13 @@ static void Dealloc(PyFileDescriptor* self) {
descriptor::Dealloc(&self->base);
}
+static PyObject* GetPool(PyFileDescriptor *self, void *closure) {
+ PyObject* pool = reinterpret_cast<PyObject*>(
+ GetDescriptorPool_FromPool(_GetDescriptor(self)->pool()));
+ Py_XINCREF(pool);
+ return pool;
+}
+
static PyObject* GetName(PyFileDescriptor *self, void *closure) {
return PyString_FromCppString(_GetDescriptor(self)->name());
}
@@ -1252,6 +1280,10 @@ static PyObject* GetExtensionsByName(PyFileDescriptor* self, void *closure) {
return NewFileExtensionsByName(_GetDescriptor(self));
}
+static PyObject* GetServicesByName(PyFileDescriptor* self, void *closure) {
+ return NewFileServicesByName(_GetDescriptor(self));
+}
+
static PyObject* GetDependencies(PyFileDescriptor* self, void *closure) {
return NewFileDependencies(_GetDescriptor(self));
}
@@ -1292,6 +1324,7 @@ static PyObject* CopyToProto(PyFileDescriptor *self, PyObject *target) {
}
static PyGetSetDef Getters[] = {
+ { "pool", (getter)GetPool, NULL, "pool"},
{ "name", (getter)GetName, NULL, "name"},
{ "package", (getter)GetPackage, NULL, "package"},
{ "serialized_pb", (getter)GetSerializedPb},
@@ -1300,6 +1333,7 @@ static PyGetSetDef Getters[] = {
{ "enum_types_by_name", (getter)GetEnumTypesByName, NULL, "Enums by name"},
{ "extensions_by_name", (getter)GetExtensionsByName, NULL,
"Extensions by name"},
+ { "services_by_name", (getter)GetServicesByName, NULL, "Services by name"},
{ "dependencies", (getter)GetDependencies, NULL, "Dependencies"},
{ "public_dependencies", (getter)GetPublicDependencies, NULL, "Dependencies"},
@@ -1354,8 +1388,8 @@ PyTypeObject PyFileDescriptor_Type = {
0, // tp_descr_set
0, // tp_dictoffset
0, // tp_init
- PyType_GenericAlloc, // tp_alloc
- PyType_GenericNew, // tp_new
+ 0, // tp_alloc
+ 0, // tp_new
PyObject_Del, // tp_free
};
@@ -1428,16 +1462,45 @@ static PyObject* GetContainingType(PyBaseDescriptor *self, void *closure) {
}
}
+static PyObject* GetHasOptions(PyBaseDescriptor *self, void *closure) {
+ const OneofOptions& options(_GetDescriptor(self)->options());
+ if (&options != &OneofOptions::default_instance()) {
+ Py_RETURN_TRUE;
+ } else {
+ Py_RETURN_FALSE;
+ }
+}
+static int SetHasOptions(PyBaseDescriptor *self, PyObject *value,
+ void *closure) {
+ return CheckCalledFromGeneratedFile("has_options");
+}
+
+static PyObject* GetOptions(PyBaseDescriptor *self) {
+ return GetOrBuildOptions(_GetDescriptor(self));
+}
+
+static int SetOptions(PyBaseDescriptor *self, PyObject *value,
+ void *closure) {
+ return CheckCalledFromGeneratedFile("_options");
+}
+
static PyGetSetDef Getters[] = {
{ "name", (getter)GetName, NULL, "Name"},
{ "full_name", (getter)GetFullName, NULL, "Full name"},
{ "index", (getter)GetIndex, NULL, "Index"},
{ "containing_type", (getter)GetContainingType, NULL, "Containing type"},
+ { "has_options", (getter)GetHasOptions, (setter)SetHasOptions, "Has Options"},
+ { "_options", (getter)NULL, (setter)SetOptions, "Options"},
{ "fields", (getter)GetFields, NULL, "Fields"},
{NULL}
};
+static PyMethodDef Methods[] = {
+ { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS },
+ {NULL}
+};
+
} // namespace oneof_descriptor
PyTypeObject PyOneofDescriptor_Type = {
@@ -1468,7 +1531,7 @@ PyTypeObject PyOneofDescriptor_Type = {
0, // tp_weaklistoffset
0, // tp_iter
0, // tp_iternext
- 0, // tp_methods
+ oneof_descriptor::Methods, // tp_methods
0, // tp_members
oneof_descriptor::Getters, // tp_getset
&descriptor::PyBaseDescriptor_Type, // tp_base
@@ -1480,6 +1543,222 @@ PyObject* PyOneofDescriptor_FromDescriptor(
&PyOneofDescriptor_Type, oneof_descriptor, NULL);
}
+namespace service_descriptor {
+
+// Unchecked accessor to the C++ pointer.
+static const ServiceDescriptor* _GetDescriptor(
+ PyBaseDescriptor *self) {
+ return reinterpret_cast<const ServiceDescriptor*>(self->descriptor);
+}
+
+static PyObject* GetName(PyBaseDescriptor* self, void *closure) {
+ return PyString_FromCppString(_GetDescriptor(self)->name());
+}
+
+static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) {
+ return PyString_FromCppString(_GetDescriptor(self)->full_name());
+}
+
+static PyObject* GetIndex(PyBaseDescriptor *self, void *closure) {
+ return PyInt_FromLong(_GetDescriptor(self)->index());
+}
+
+static PyObject* GetMethods(PyBaseDescriptor* self, void *closure) {
+ return NewServiceMethodsSeq(_GetDescriptor(self));
+}
+
+static PyObject* GetMethodsByName(PyBaseDescriptor* self, void *closure) {
+ return NewServiceMethodsByName(_GetDescriptor(self));
+}
+
+static PyObject* FindMethodByName(PyBaseDescriptor *self, PyObject* arg) {
+ Py_ssize_t name_size;
+ char* name;
+ if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) {
+ return NULL;
+ }
+
+ const MethodDescriptor* method_descriptor =
+ _GetDescriptor(self)->FindMethodByName(string(name, name_size));
+ if (method_descriptor == NULL) {
+ PyErr_Format(PyExc_KeyError, "Couldn't find method %.200s", name);
+ return NULL;
+ }
+
+ return PyMethodDescriptor_FromDescriptor(method_descriptor);
+}
+
+static PyObject* GetOptions(PyBaseDescriptor *self) {
+ return GetOrBuildOptions(_GetDescriptor(self));
+}
+
+static PyObject* CopyToProto(PyBaseDescriptor *self, PyObject *target) {
+ return CopyToPythonProto<ServiceDescriptorProto>(_GetDescriptor(self),
+ target);
+}
+
+static PyGetSetDef Getters[] = {
+ { "name", (getter)GetName, NULL, "Name", NULL},
+ { "full_name", (getter)GetFullName, NULL, "Full name", NULL},
+ { "index", (getter)GetIndex, NULL, "Index", NULL},
+
+ { "methods", (getter)GetMethods, NULL, "Methods", NULL},
+ { "methods_by_name", (getter)GetMethodsByName, NULL, "Methods by name", NULL},
+ {NULL}
+};
+
+static PyMethodDef Methods[] = {
+ { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS },
+ { "CopyToProto", (PyCFunction)CopyToProto, METH_O, },
+ { "FindMethodByName", (PyCFunction)FindMethodByName, METH_O },
+ {NULL}
+};
+
+} // namespace service_descriptor
+
+PyTypeObject PyServiceDescriptor_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ FULL_MODULE_NAME ".ServiceDescriptor", // tp_name
+ sizeof(PyBaseDescriptor), // tp_basicsize
+ 0, // tp_itemsize
+ 0, // tp_dealloc
+ 0, // tp_print
+ 0, // tp_getattr
+ 0, // tp_setattr
+ 0, // tp_compare
+ 0, // tp_repr
+ 0, // tp_as_number
+ 0, // tp_as_sequence
+ 0, // tp_as_mapping
+ 0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ 0, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ Py_TPFLAGS_DEFAULT, // tp_flags
+ "A Service Descriptor", // tp_doc
+ 0, // tp_traverse
+ 0, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ service_descriptor::Methods, // tp_methods
+ 0, // tp_members
+ service_descriptor::Getters, // tp_getset
+ &descriptor::PyBaseDescriptor_Type, // tp_base
+};
+
+PyObject* PyServiceDescriptor_FromDescriptor(
+ const ServiceDescriptor* service_descriptor) {
+ return descriptor::NewInternedDescriptor(
+ &PyServiceDescriptor_Type, service_descriptor, NULL);
+}
+
+namespace method_descriptor {
+
+// Unchecked accessor to the C++ pointer.
+static const MethodDescriptor* _GetDescriptor(
+ PyBaseDescriptor *self) {
+ return reinterpret_cast<const MethodDescriptor*>(self->descriptor);
+}
+
+static PyObject* GetName(PyBaseDescriptor* self, void *closure) {
+ return PyString_FromCppString(_GetDescriptor(self)->name());
+}
+
+static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) {
+ return PyString_FromCppString(_GetDescriptor(self)->full_name());
+}
+
+static PyObject* GetIndex(PyBaseDescriptor *self, void *closure) {
+ return PyInt_FromLong(_GetDescriptor(self)->index());
+}
+
+static PyObject* GetContainingService(PyBaseDescriptor *self, void *closure) {
+ const ServiceDescriptor* containing_service =
+ _GetDescriptor(self)->service();
+ return PyServiceDescriptor_FromDescriptor(containing_service);
+}
+
+static PyObject* GetInputType(PyBaseDescriptor *self, void *closure) {
+ const Descriptor* input_type = _GetDescriptor(self)->input_type();
+ return PyMessageDescriptor_FromDescriptor(input_type);
+}
+
+static PyObject* GetOutputType(PyBaseDescriptor *self, void *closure) {
+ const Descriptor* output_type = _GetDescriptor(self)->output_type();
+ return PyMessageDescriptor_FromDescriptor(output_type);
+}
+
+static PyObject* GetOptions(PyBaseDescriptor *self) {
+ return GetOrBuildOptions(_GetDescriptor(self));
+}
+
+static PyObject* CopyToProto(PyBaseDescriptor *self, PyObject *target) {
+ return CopyToPythonProto<MethodDescriptorProto>(_GetDescriptor(self), target);
+}
+
+static PyGetSetDef Getters[] = {
+ { "name", (getter)GetName, NULL, "Name", NULL},
+ { "full_name", (getter)GetFullName, NULL, "Full name", NULL},
+ { "index", (getter)GetIndex, NULL, "Index", NULL},
+ { "containing_service", (getter)GetContainingService, NULL,
+ "Containing service", NULL},
+ { "input_type", (getter)GetInputType, NULL, "Input type", NULL},
+ { "output_type", (getter)GetOutputType, NULL, "Output type", NULL},
+ {NULL}
+};
+
+static PyMethodDef Methods[] = {
+ { "GetOptions", (PyCFunction)GetOptions, METH_NOARGS, },
+ { "CopyToProto", (PyCFunction)CopyToProto, METH_O, },
+ {NULL}
+};
+
+} // namespace method_descriptor
+
+PyTypeObject PyMethodDescriptor_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ FULL_MODULE_NAME ".MethodDescriptor", // tp_name
+ sizeof(PyBaseDescriptor), // tp_basicsize
+ 0, // tp_itemsize
+ 0, // tp_dealloc
+ 0, // tp_print
+ 0, // tp_getattr
+ 0, // tp_setattr
+ 0, // tp_compare
+ 0, // tp_repr
+ 0, // tp_as_number
+ 0, // tp_as_sequence
+ 0, // tp_as_mapping
+ 0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ 0, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ Py_TPFLAGS_DEFAULT, // tp_flags
+ "A Method Descriptor", // tp_doc
+ 0, // tp_traverse
+ 0, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ method_descriptor::Methods, // tp_methods
+ 0, // tp_members
+ method_descriptor::Getters, // tp_getset
+ &descriptor::PyBaseDescriptor_Type, // tp_base
+};
+
+PyObject* PyMethodDescriptor_FromDescriptor(
+ const MethodDescriptor* method_descriptor) {
+ return descriptor::NewInternedDescriptor(
+ &PyMethodDescriptor_Type, method_descriptor, NULL);
+}
+
// Add a enum values to a type dictionary.
static bool AddEnumValues(PyTypeObject *type,
const EnumDescriptor* enum_descriptor) {
@@ -1549,6 +1828,12 @@ bool InitDescriptor() {
if (PyType_Ready(&PyOneofDescriptor_Type) < 0)
return false;
+ if (PyType_Ready(&PyServiceDescriptor_Type) < 0)
+ return false;
+
+ if (PyType_Ready(&PyMethodDescriptor_Type) < 0)
+ return false;
+
if (!InitDescriptorMappingTypes())
return false;
diff --git a/python/google/protobuf/pyext/descriptor.h b/python/google/protobuf/pyext/descriptor.h
index eb99df18..1ae0e672 100644
--- a/python/google/protobuf/pyext/descriptor.h
+++ b/python/google/protobuf/pyext/descriptor.h
@@ -47,6 +47,8 @@ extern PyTypeObject PyEnumDescriptor_Type;
extern PyTypeObject PyEnumValueDescriptor_Type;
extern PyTypeObject PyFileDescriptor_Type;
extern PyTypeObject PyOneofDescriptor_Type;
+extern PyTypeObject PyServiceDescriptor_Type;
+extern PyTypeObject PyMethodDescriptor_Type;
// Wraps a Descriptor in a Python object.
// The C++ pointer is usually borrowed from the global DescriptorPool.
@@ -60,6 +62,10 @@ PyObject* PyEnumValueDescriptor_FromDescriptor(
PyObject* PyOneofDescriptor_FromDescriptor(const OneofDescriptor* descriptor);
PyObject* PyFileDescriptor_FromDescriptor(
const FileDescriptor* file_descriptor);
+PyObject* PyServiceDescriptor_FromDescriptor(
+ const ServiceDescriptor* descriptor);
+PyObject* PyMethodDescriptor_FromDescriptor(
+ const MethodDescriptor* descriptor);
// Alternate constructor of PyFileDescriptor, used when we already have a
// serialized FileDescriptorProto that can be cached.
diff --git a/python/google/protobuf/pyext/descriptor_containers.cc b/python/google/protobuf/pyext/descriptor_containers.cc
index e505d812..d0aae9c9 100644
--- a/python/google/protobuf/pyext/descriptor_containers.cc
+++ b/python/google/protobuf/pyext/descriptor_containers.cc
@@ -608,6 +608,24 @@ static PyObject* GetItem(PyContainer* self, Py_ssize_t index) {
return _NewObj_ByIndex(self, index);
}
+static PyObject *
+SeqSubscript(PyContainer* self, PyObject* item) {
+ if (PyIndex_Check(item)) {
+ Py_ssize_t index;
+ index = PyNumber_AsSsize_t(item, PyExc_IndexError);
+ if (index == -1 && PyErr_Occurred())
+ return NULL;
+ return GetItem(self, index);
+ }
+ // Materialize the list and delegate the operation to it.
+ ScopedPyObjectPtr list(PyObject_CallFunctionObjArgs(
+ reinterpret_cast<PyObject*>(&PyList_Type), self, NULL));
+ if (list == NULL) {
+ return NULL;
+ }
+ return Py_TYPE(list.get())->tp_as_mapping->mp_subscript(list.get(), item);
+}
+
// Returns the position of the item in the sequence, of -1 if not found.
// This function never fails.
int Find(PyContainer* self, PyObject* item) {
@@ -703,14 +721,20 @@ static PyMethodDef SeqMethods[] = {
};
static PySequenceMethods SeqSequenceMethods = {
- (lenfunc)Length, // sq_length
- 0, // sq_concat
- 0, // sq_repeat
- (ssizeargfunc)GetItem, // sq_item
- 0, // sq_slice
- 0, // sq_ass_item
- 0, // sq_ass_slice
- (objobjproc)SeqContains, // sq_contains
+ (lenfunc)Length, // sq_length
+ 0, // sq_concat
+ 0, // sq_repeat
+ (ssizeargfunc)GetItem, // sq_item
+ 0, // sq_slice
+ 0, // sq_ass_item
+ 0, // sq_ass_slice
+ (objobjproc)SeqContains, // sq_contains
+};
+
+static PyMappingMethods SeqMappingMethods = {
+ (lenfunc)Length, // mp_length
+ (binaryfunc)SeqSubscript, // mp_subscript
+ 0, // mp_ass_subscript
};
PyTypeObject DescriptorSequence_Type = {
@@ -726,7 +750,7 @@ PyTypeObject DescriptorSequence_Type = {
(reprfunc)ContainerRepr, // tp_repr
0, // tp_as_number
&SeqSequenceMethods, // tp_as_sequence
- 0, // tp_as_mapping
+ &SeqMappingMethods, // tp_as_mapping
0, // tp_hash
0, // tp_call
0, // tp_str
@@ -1407,6 +1431,68 @@ PyObject* NewOneofFieldsSeq(ParentDescriptor descriptor) {
} // namespace oneof_descriptor
+namespace service_descriptor {
+
+typedef const ServiceDescriptor* ParentDescriptor;
+
+static ParentDescriptor GetDescriptor(PyContainer* self) {
+ return reinterpret_cast<ParentDescriptor>(self->descriptor);
+}
+
+namespace methods {
+
+typedef const MethodDescriptor* ItemDescriptor;
+
+static int Count(PyContainer* self) {
+ return GetDescriptor(self)->method_count();
+}
+
+static ItemDescriptor GetByName(PyContainer* self, const string& name) {
+ return GetDescriptor(self)->FindMethodByName(name);
+}
+
+static ItemDescriptor GetByIndex(PyContainer* self, int index) {
+ return GetDescriptor(self)->method(index);
+}
+
+static PyObject* NewObjectFromItem(ItemDescriptor item) {
+ return PyMethodDescriptor_FromDescriptor(item);
+}
+
+static const string& GetItemName(ItemDescriptor item) {
+ return item->name();
+}
+
+static int GetItemIndex(ItemDescriptor item) {
+ return item->index();
+}
+
+static DescriptorContainerDef ContainerDef = {
+ "ServiceMethods",
+ (CountMethod)Count,
+ (GetByIndexMethod)GetByIndex,
+ (GetByNameMethod)GetByName,
+ (GetByCamelcaseNameMethod)NULL,
+ (GetByNumberMethod)NULL,
+ (NewObjectFromItemMethod)NewObjectFromItem,
+ (GetItemNameMethod)GetItemName,
+ (GetItemCamelcaseNameMethod)NULL,
+ (GetItemNumberMethod)NULL,
+ (GetItemIndexMethod)GetItemIndex,
+};
+
+} // namespace methods
+
+PyObject* NewServiceMethodsSeq(ParentDescriptor descriptor) {
+ return descriptor::NewSequence(&methods::ContainerDef, descriptor);
+}
+
+PyObject* NewServiceMethodsByName(ParentDescriptor descriptor) {
+ return descriptor::NewMappingByName(&methods::ContainerDef, descriptor);
+}
+
+} // namespace service_descriptor
+
namespace file_descriptor {
typedef const FileDescriptor* ParentDescriptor;
@@ -1459,7 +1545,7 @@ static DescriptorContainerDef ContainerDef = {
} // namespace messages
-PyObject* NewFileMessageTypesByName(const FileDescriptor* descriptor) {
+PyObject* NewFileMessageTypesByName(ParentDescriptor descriptor) {
return descriptor::NewMappingByName(&messages::ContainerDef, descriptor);
}
@@ -1507,7 +1593,7 @@ static DescriptorContainerDef ContainerDef = {
} // namespace enums
-PyObject* NewFileEnumTypesByName(const FileDescriptor* descriptor) {
+PyObject* NewFileEnumTypesByName(ParentDescriptor descriptor) {
return descriptor::NewMappingByName(&enums::ContainerDef, descriptor);
}
@@ -1555,10 +1641,58 @@ static DescriptorContainerDef ContainerDef = {
} // namespace extensions
-PyObject* NewFileExtensionsByName(const FileDescriptor* descriptor) {
+PyObject* NewFileExtensionsByName(ParentDescriptor descriptor) {
return descriptor::NewMappingByName(&extensions::ContainerDef, descriptor);
}
+namespace services {
+
+typedef const ServiceDescriptor* ItemDescriptor;
+
+static int Count(PyContainer* self) {
+ return GetDescriptor(self)->service_count();
+}
+
+static ItemDescriptor GetByName(PyContainer* self, const string& name) {
+ return GetDescriptor(self)->FindServiceByName(name);
+}
+
+static ItemDescriptor GetByIndex(PyContainer* self, int index) {
+ return GetDescriptor(self)->service(index);
+}
+
+static PyObject* NewObjectFromItem(ItemDescriptor item) {
+ return PyServiceDescriptor_FromDescriptor(item);
+}
+
+static const string& GetItemName(ItemDescriptor item) {
+ return item->name();
+}
+
+static int GetItemIndex(ItemDescriptor item) {
+ return item->index();
+}
+
+static DescriptorContainerDef ContainerDef = {
+ "FileServices",
+ (CountMethod)Count,
+ (GetByIndexMethod)GetByIndex,
+ (GetByNameMethod)GetByName,
+ (GetByCamelcaseNameMethod)NULL,
+ (GetByNumberMethod)NULL,
+ (NewObjectFromItemMethod)NewObjectFromItem,
+ (GetItemNameMethod)GetItemName,
+ (GetItemCamelcaseNameMethod)NULL,
+ (GetItemNumberMethod)NULL,
+ (GetItemIndexMethod)GetItemIndex,
+};
+
+} // namespace services
+
+PyObject* NewFileServicesByName(const FileDescriptor* descriptor) {
+ return descriptor::NewMappingByName(&services::ContainerDef, descriptor);
+}
+
namespace dependencies {
typedef const FileDescriptor* ItemDescriptor;
diff --git a/python/google/protobuf/pyext/descriptor_containers.h b/python/google/protobuf/pyext/descriptor_containers.h
index ce40747d..83de07b6 100644
--- a/python/google/protobuf/pyext/descriptor_containers.h
+++ b/python/google/protobuf/pyext/descriptor_containers.h
@@ -43,6 +43,7 @@ class Descriptor;
class FileDescriptor;
class EnumDescriptor;
class OneofDescriptor;
+class ServiceDescriptor;
namespace python {
@@ -89,10 +90,17 @@ PyObject* NewFileEnumTypesByName(const FileDescriptor* descriptor);
PyObject* NewFileExtensionsByName(const FileDescriptor* descriptor);
+PyObject* NewFileServicesByName(const FileDescriptor* descriptor);
+
PyObject* NewFileDependencies(const FileDescriptor* descriptor);
PyObject* NewFilePublicDependencies(const FileDescriptor* descriptor);
} // namespace file_descriptor
+namespace service_descriptor {
+PyObject* NewServiceMethodsSeq(const ServiceDescriptor* descriptor);
+PyObject* NewServiceMethodsByName(const ServiceDescriptor* descriptor);
+} // namespace service_descriptor
+
} // namespace python
} // namespace protobuf
diff --git a/python/google/protobuf/pyext/descriptor_database.cc b/python/google/protobuf/pyext/descriptor_database.cc
new file mode 100644
index 00000000..daa40cc7
--- /dev/null
+++ b/python/google/protobuf/pyext/descriptor_database.cc
@@ -0,0 +1,148 @@
+// 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.
+
+// This file defines a C++ DescriptorDatabase, which wraps a Python Database
+// and delegate all its operations to Python methods.
+
+#include <google/protobuf/pyext/descriptor_database.h>
+
+#include <google/protobuf/stubs/logging.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/pyext/message.h>
+#include <google/protobuf/pyext/scoped_pyobject_ptr.h>
+
+namespace google {
+namespace protobuf {
+namespace python {
+
+PyDescriptorDatabase::PyDescriptorDatabase(PyObject* py_database)
+ : py_database_(py_database) {
+ Py_INCREF(py_database_);
+}
+
+PyDescriptorDatabase::~PyDescriptorDatabase() { Py_DECREF(py_database_); }
+
+// Convert a Python object to a FileDescriptorProto pointer.
+// Handles all kinds of Python errors, which are simply logged.
+static bool GetFileDescriptorProto(PyObject* py_descriptor,
+ FileDescriptorProto* output) {
+ if (py_descriptor == NULL) {
+ if (PyErr_ExceptionMatches(PyExc_KeyError)) {
+ // Expected error: item was simply not found.
+ PyErr_Clear();
+ } else {
+ GOOGLE_LOG(ERROR) << "DescriptorDatabase method raised an error";
+ PyErr_Print();
+ }
+ return false;
+ }
+ if (py_descriptor == Py_None) {
+ return false;
+ }
+ const Descriptor* filedescriptor_descriptor =
+ FileDescriptorProto::default_instance().GetDescriptor();
+ CMessage* message = reinterpret_cast<CMessage*>(py_descriptor);
+ if (PyObject_TypeCheck(py_descriptor, &CMessage_Type) &&
+ message->message->GetDescriptor() == filedescriptor_descriptor) {
+ // Fast path: Just use the pointer.
+ FileDescriptorProto* file_proto =
+ static_cast<FileDescriptorProto*>(message->message);
+ *output = *file_proto;
+ return true;
+ } else {
+ // Slow path: serialize the message. This allows to use databases which
+ // use a different implementation of FileDescriptorProto.
+ ScopedPyObjectPtr serialized_pb(
+ PyObject_CallMethod(py_descriptor, "SerializeToString", NULL));
+ if (serialized_pb == NULL) {
+ GOOGLE_LOG(ERROR)
+ << "DescriptorDatabase method did not return a FileDescriptorProto";
+ PyErr_Print();
+ return false;
+ }
+ char* str;
+ Py_ssize_t len;
+ if (PyBytes_AsStringAndSize(serialized_pb.get(), &str, &len) < 0) {
+ GOOGLE_LOG(ERROR)
+ << "DescriptorDatabase method did not return a FileDescriptorProto";
+ PyErr_Print();
+ return false;
+ }
+ FileDescriptorProto file_proto;
+ if (!file_proto.ParseFromArray(str, len)) {
+ GOOGLE_LOG(ERROR)
+ << "DescriptorDatabase method did not return a FileDescriptorProto";
+ return false;
+ }
+ *output = file_proto;
+ return true;
+ }
+}
+
+// Find a file by file name.
+bool PyDescriptorDatabase::FindFileByName(const string& filename,
+ FileDescriptorProto* output) {
+ ScopedPyObjectPtr py_descriptor(PyObject_CallMethod(
+ py_database_, "FindFileByName", "s#", filename.c_str(), filename.size()));
+ return GetFileDescriptorProto(py_descriptor.get(), output);
+}
+
+// Find the file that declares the given fully-qualified symbol name.
+bool PyDescriptorDatabase::FindFileContainingSymbol(
+ const string& symbol_name, FileDescriptorProto* output) {
+ ScopedPyObjectPtr py_descriptor(
+ PyObject_CallMethod(py_database_, "FindFileContainingSymbol", "s#",
+ symbol_name.c_str(), symbol_name.size()));
+ return GetFileDescriptorProto(py_descriptor.get(), output);
+}
+
+// Find the file which defines an extension extending the given message type
+// with the given field number.
+// Python DescriptorDatabases are not required to implement this method.
+bool PyDescriptorDatabase::FindFileContainingExtension(
+ const string& containing_type, int field_number,
+ FileDescriptorProto* output) {
+ ScopedPyObjectPtr py_method(
+ PyObject_GetAttrString(py_database_, "FindFileContainingExtension"));
+ if (py_method == NULL) {
+ // This method is not implemented, returns without error.
+ PyErr_Clear();
+ return false;
+ }
+ ScopedPyObjectPtr py_descriptor(
+ PyObject_CallFunction(py_method.get(), "s#i", containing_type.c_str(),
+ containing_type.size(), field_number));
+ return GetFileDescriptorProto(py_descriptor.get(), output);
+}
+
+} // namespace python
+} // namespace protobuf
+} // namespace google
diff --git a/python/google/protobuf/pyext/descriptor_database.h b/python/google/protobuf/pyext/descriptor_database.h
new file mode 100644
index 00000000..fc71c4bc
--- /dev/null
+++ b/python/google/protobuf/pyext/descriptor_database.h
@@ -0,0 +1,75 @@
+// 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.
+
+#ifndef GOOGLE_PROTOBUF_PYTHON_CPP_DESCRIPTOR_DATABASE_H__
+#define GOOGLE_PROTOBUF_PYTHON_CPP_DESCRIPTOR_DATABASE_H__
+
+#include <Python.h>
+
+#include <google/protobuf/descriptor_database.h>
+
+namespace google {
+namespace protobuf {
+namespace python {
+
+class PyDescriptorDatabase : public DescriptorDatabase {
+ public:
+ explicit PyDescriptorDatabase(PyObject* py_database);
+ ~PyDescriptorDatabase();
+
+ // Implement the abstract interface. All these functions fill the output
+ // with a copy of FileDescriptorProto.
+
+ // Find a file by file name.
+ bool FindFileByName(const string& filename,
+ FileDescriptorProto* output);
+
+ // Find the file that declares the given fully-qualified symbol name.
+ bool FindFileContainingSymbol(const string& symbol_name,
+ FileDescriptorProto* output);
+
+ // Find the file which defines an extension extending the given message type
+ // with the given field number.
+ // Containing_type must be a fully-qualified type name.
+ // Python objects are not required to implement this method.
+ bool FindFileContainingExtension(const string& containing_type,
+ int field_number,
+ FileDescriptorProto* output);
+
+ private:
+ // The python object that implements the database. The reference is owned.
+ PyObject* py_database_;
+};
+
+} // namespace python
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_PYTHON_CPP_DESCRIPTOR_DATABASE_H__
diff --git a/python/google/protobuf/pyext/descriptor_pool.cc b/python/google/protobuf/pyext/descriptor_pool.cc
index 0f7487fa..cfd98690 100644
--- a/python/google/protobuf/pyext/descriptor_pool.cc
+++ b/python/google/protobuf/pyext/descriptor_pool.cc
@@ -34,8 +34,9 @@
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/dynamic_message.h>
-#include <google/protobuf/pyext/descriptor_pool.h>
#include <google/protobuf/pyext/descriptor.h>
+#include <google/protobuf/pyext/descriptor_database.h>
+#include <google/protobuf/pyext/descriptor_pool.h>
#include <google/protobuf/pyext/message.h>
#include <google/protobuf/pyext/scoped_pyobject_ptr.h>
@@ -60,38 +61,93 @@ static hash_map<const DescriptorPool*, PyDescriptorPool*> descriptor_pool_map;
namespace cdescriptor_pool {
-static PyDescriptorPool* NewDescriptorPool() {
- PyDescriptorPool* cdescriptor_pool = PyObject_New(
+// Create a Python DescriptorPool object, but does not fill the "pool"
+// attribute.
+static PyDescriptorPool* _CreateDescriptorPool() {
+ PyDescriptorPool* cpool = PyObject_New(
PyDescriptorPool, &PyDescriptorPool_Type);
- if (cdescriptor_pool == NULL) {
+ if (cpool == NULL) {
return NULL;
}
- // Build a DescriptorPool for messages only declared in Python libraries.
- // generated_pool() contains all messages linked in C++ libraries, and is used
- // as underlay.
- cdescriptor_pool->pool = new DescriptorPool(DescriptorPool::generated_pool());
+ cpool->underlay = NULL;
+ cpool->database = NULL;
DynamicMessageFactory* message_factory = new DynamicMessageFactory();
// This option might be the default some day.
message_factory->SetDelegateToGeneratedFactory(true);
- cdescriptor_pool->message_factory = message_factory;
+ cpool->message_factory = message_factory;
// TODO(amauryfa): Rewrite the SymbolDatabase in C so that it uses the same
// storage.
- cdescriptor_pool->classes_by_descriptor =
+ cpool->classes_by_descriptor =
new PyDescriptorPool::ClassesByMessageMap();
- cdescriptor_pool->descriptor_options =
+ cpool->descriptor_options =
new hash_map<const void*, PyObject *>();
+ return cpool;
+}
+
+// Create a Python DescriptorPool, using the given pool as an underlay:
+// new messages will be added to a custom pool, not to the underlay.
+//
+// Ownership of the underlay is not transferred, its pointer should
+// stay alive.
+static PyDescriptorPool* PyDescriptorPool_NewWithUnderlay(
+ const DescriptorPool* underlay) {
+ PyDescriptorPool* cpool = _CreateDescriptorPool();
+ if (cpool == NULL) {
+ return NULL;
+ }
+ cpool->pool = new DescriptorPool(underlay);
+ cpool->underlay = underlay;
+
if (!descriptor_pool_map.insert(
- std::make_pair(cdescriptor_pool->pool, cdescriptor_pool)).second) {
+ std::make_pair(cpool->pool, cpool)).second) {
// Should never happen -- would indicate an internal error / bug.
PyErr_SetString(PyExc_ValueError, "DescriptorPool already registered");
return NULL;
}
- return cdescriptor_pool;
+ return cpool;
+}
+
+static PyDescriptorPool* PyDescriptorPool_NewWithDatabase(
+ DescriptorDatabase* database) {
+ PyDescriptorPool* cpool = _CreateDescriptorPool();
+ if (cpool == NULL) {
+ return NULL;
+ }
+ if (database != NULL) {
+ cpool->pool = new DescriptorPool(database);
+ cpool->database = database;
+ } else {
+ cpool->pool = new DescriptorPool();
+ }
+
+ if (!descriptor_pool_map.insert(std::make_pair(cpool->pool, cpool)).second) {
+ // Should never happen -- would indicate an internal error / bug.
+ PyErr_SetString(PyExc_ValueError, "DescriptorPool already registered");
+ return NULL;
+ }
+
+ return cpool;
+}
+
+// The public DescriptorPool constructor.
+static PyObject* New(PyTypeObject* type,
+ PyObject* args, PyObject* kwargs) {
+ static char* kwlist[] = {"descriptor_db", 0};
+ PyObject* py_database = NULL;
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", kwlist, &py_database)) {
+ return NULL;
+ }
+ DescriptorDatabase* database = NULL;
+ if (py_database && py_database != Py_None) {
+ database = new PyDescriptorDatabase(py_database);
+ }
+ return reinterpret_cast<PyObject*>(
+ PyDescriptorPool_NewWithDatabase(database));
}
static void Dealloc(PyDescriptorPool* self) {
@@ -108,8 +164,9 @@ static void Dealloc(PyDescriptorPool* self) {
Py_DECREF(it->second);
}
delete self->descriptor_options;
- delete self->pool;
delete self->message_factory;
+ delete self->database;
+ delete self->pool;
Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
}
@@ -133,8 +190,8 @@ PyObject* FindMessageByName(PyDescriptorPool* self, PyObject* arg) {
// Add a message class to our database.
int RegisterMessageClass(PyDescriptorPool* self,
- const Descriptor *message_descriptor,
- PyObject *message_class) {
+ const Descriptor* message_descriptor,
+ CMessageClass* message_class) {
Py_INCREF(message_class);
typedef PyDescriptorPool::ClassesByMessageMap::iterator iterator;
std::pair<iterator, bool> ret = self->classes_by_descriptor->insert(
@@ -148,8 +205,8 @@ int RegisterMessageClass(PyDescriptorPool* self,
}
// Retrieve the message class added to our database.
-PyObject *GetMessageClass(PyDescriptorPool* self,
- const Descriptor *message_descriptor) {
+CMessageClass* GetMessageClass(PyDescriptorPool* self,
+ const Descriptor* message_descriptor) {
typedef PyDescriptorPool::ClassesByMessageMap::iterator iterator;
iterator ret = self->classes_by_descriptor->find(message_descriptor);
if (ret == self->classes_by_descriptor->end()) {
@@ -248,6 +305,40 @@ PyObject* FindOneofByName(PyDescriptorPool* self, PyObject* arg) {
return PyOneofDescriptor_FromDescriptor(oneof_descriptor);
}
+PyObject* FindServiceByName(PyDescriptorPool* self, PyObject* arg) {
+ Py_ssize_t name_size;
+ char* name;
+ if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) {
+ return NULL;
+ }
+
+ const ServiceDescriptor* service_descriptor =
+ self->pool->FindServiceByName(string(name, name_size));
+ if (service_descriptor == NULL) {
+ PyErr_Format(PyExc_KeyError, "Couldn't find service %.200s", name);
+ return NULL;
+ }
+
+ return PyServiceDescriptor_FromDescriptor(service_descriptor);
+}
+
+PyObject* FindMethodByName(PyDescriptorPool* self, PyObject* arg) {
+ Py_ssize_t name_size;
+ char* name;
+ if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) {
+ return NULL;
+ }
+
+ const MethodDescriptor* method_descriptor =
+ self->pool->FindMethodByName(string(name, name_size));
+ if (method_descriptor == NULL) {
+ PyErr_Format(PyExc_KeyError, "Couldn't find method %.200s", name);
+ return NULL;
+ }
+
+ return PyMethodDescriptor_FromDescriptor(method_descriptor);
+}
+
PyObject* FindFileContainingSymbol(PyDescriptorPool* self, PyObject* arg) {
Py_ssize_t name_size;
char* name;
@@ -354,6 +445,14 @@ PyObject* AddSerializedFile(PyDescriptorPool* self, PyObject* serialized_pb) {
char* message_type;
Py_ssize_t message_len;
+ if (self->database != NULL) {
+ PyErr_SetString(
+ PyExc_ValueError,
+ "Cannot call Add on a DescriptorPool that uses a DescriptorDatabase. "
+ "Add your file to the underlying database.");
+ return NULL;
+ }
+
if (PyBytes_AsStringAndSize(serialized_pb, &message_type, &message_len) < 0) {
return NULL;
}
@@ -366,8 +465,10 @@ PyObject* AddSerializedFile(PyDescriptorPool* self, PyObject* serialized_pb) {
// If the file was already part of a C++ library, all its descriptors are in
// the underlying pool. No need to do anything else.
- const FileDescriptor* generated_file =
- DescriptorPool::generated_pool()->FindFileByName(file_proto.name());
+ const FileDescriptor* generated_file = NULL;
+ if (self->underlay) {
+ generated_file = self->underlay->FindFileByName(file_proto.name());
+ }
if (generated_file != NULL) {
return PyFileDescriptor_FromDescriptorWithSerializedPb(
generated_file, serialized_pb);
@@ -424,6 +525,10 @@ static PyMethodDef Methods[] = {
"Searches for enum type descriptor by full name." },
{ "FindOneofByName", (PyCFunction)FindOneofByName, METH_O,
"Searches for oneof descriptor by full name." },
+ { "FindServiceByName", (PyCFunction)FindServiceByName, METH_O,
+ "Searches for service descriptor by full name." },
+ { "FindMethodByName", (PyCFunction)FindMethodByName, METH_O,
+ "Searches for method descriptor by full name." },
{ "FindFileContainingSymbol", (PyCFunction)FindFileContainingSymbol, METH_O,
"Gets the FileDescriptor containing the specified symbol." },
@@ -470,7 +575,7 @@ PyTypeObject PyDescriptorPool_Type = {
0, // tp_dictoffset
0, // tp_init
0, // tp_alloc
- 0, // tp_new
+ cdescriptor_pool::New, // tp_new
PyObject_Del, // tp_free
};
@@ -482,7 +587,11 @@ bool InitDescriptorPool() {
if (PyType_Ready(&PyDescriptorPool_Type) < 0)
return false;
- python_generated_pool = cdescriptor_pool::NewDescriptorPool();
+ // The Pool of messages declared in Python libraries.
+ // generated_pool() contains all messages already linked in C++ libraries, and
+ // is used as underlay.
+ python_generated_pool = cdescriptor_pool::PyDescriptorPool_NewWithUnderlay(
+ DescriptorPool::generated_pool());
if (python_generated_pool == NULL) {
return false;
}
@@ -494,6 +603,10 @@ bool InitDescriptorPool() {
return true;
}
+// The default DescriptorPool used everywhere in this module.
+// Today it's the python_generated_pool.
+// TODO(amauryfa): Remove all usages of this function: the pool should be
+// derived from the context.
PyDescriptorPool* GetDefaultDescriptorPool() {
return python_generated_pool;
}
diff --git a/python/google/protobuf/pyext/descriptor_pool.h b/python/google/protobuf/pyext/descriptor_pool.h
index eda73d38..2a42c112 100644
--- a/python/google/protobuf/pyext/descriptor_pool.h
+++ b/python/google/protobuf/pyext/descriptor_pool.h
@@ -42,6 +42,9 @@ class MessageFactory;
namespace python {
+// The (meta) type of all Messages classes.
+struct CMessageClass;
+
// Wraps operations to the global DescriptorPool which contains information
// about all messages and fields.
//
@@ -55,8 +58,17 @@ namespace python {
typedef struct PyDescriptorPool {
PyObject_HEAD
+ // The C++ pool containing Descriptors.
DescriptorPool* pool;
+ // The C++ pool acting as an underlay. Can be NULL.
+ // This pointer is not owned and must stay alive.
+ const DescriptorPool* underlay;
+
+ // The C++ descriptor database used to fetch unknown protos. Can be NULL.
+ // This pointer is owned.
+ const DescriptorDatabase* database;
+
// DynamicMessageFactory used to create C++ instances of messages.
// This object cache the descriptors that were used, so the DescriptorPool
// needs to get rid of it before it can delete itself.
@@ -69,7 +81,7 @@ typedef struct PyDescriptorPool {
//
// Descriptor pointers stored here are owned by the DescriptorPool above.
// Python references to classes are owned by this PyDescriptorPool.
- typedef hash_map<const Descriptor*, PyObject*> ClassesByMessageMap;
+ typedef hash_map<const Descriptor*, CMessageClass*> ClassesByMessageMap;
ClassesByMessageMap* classes_by_descriptor;
// Cache the options for any kind of descriptor.
@@ -92,14 +104,14 @@ const Descriptor* FindMessageTypeByName(PyDescriptorPool* self,
// On error, returns -1 with a Python exception set.
int RegisterMessageClass(PyDescriptorPool* self,
const Descriptor* message_descriptor,
- PyObject* message_class);
+ CMessageClass* message_class);
// Retrieves the Python class registered with the given message descriptor.
//
// Returns a *borrowed* reference if found, otherwise returns NULL with an
// exception set.
-PyObject* GetMessageClass(PyDescriptorPool* self,
- const Descriptor* message_descriptor);
+CMessageClass* GetMessageClass(PyDescriptorPool* self,
+ const Descriptor* message_descriptor);
// The functions below are also exposed as methods of the DescriptorPool type.
@@ -138,6 +150,7 @@ PyObject* FindOneofByName(PyDescriptorPool* self, PyObject* arg);
// Retrieve the global descriptor pool owned by the _message module.
// This is the one used by pb2.py generated modules.
// Returns a *borrowed* reference.
+// "Default" pool used to register messages from _pb2.py modules.
PyDescriptorPool* GetDefaultDescriptorPool();
// Retrieve the python descriptor pool owning a C++ descriptor pool.
diff --git a/python/google/protobuf/pyext/extension_dict.cc b/python/google/protobuf/pyext/extension_dict.cc
index b361b342..21bbb8c2 100644
--- a/python/google/protobuf/pyext/extension_dict.cc
+++ b/python/google/protobuf/pyext/extension_dict.cc
@@ -94,13 +94,13 @@ PyObject* subscript(ExtensionDict* self, PyObject* key) {
if (descriptor == NULL) {
return NULL;
}
- if (!CheckFieldBelongsToMessage(descriptor, self->parent->message)) {
+ if (!CheckFieldBelongsToMessage(descriptor, self->message)) {
return NULL;
}
if (descriptor->label() != FieldDescriptor::LABEL_REPEATED &&
descriptor->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
- return cmessage::InternalGetScalar(self->parent->message, descriptor);
+ return cmessage::InternalGetScalar(self->message, descriptor);
}
PyObject* value = PyDict_GetItem(self->values, key);
@@ -109,6 +109,14 @@ PyObject* subscript(ExtensionDict* self, PyObject* key) {
return value;
}
+ if (self->parent == NULL) {
+ // We are in "detached" state. Don't allow further modifications.
+ // TODO(amauryfa): Support adding non-scalars to a detached extension dict.
+ // This probably requires to store the type of the main message.
+ PyErr_SetObject(PyExc_KeyError, key);
+ return NULL;
+ }
+
if (descriptor->label() != FieldDescriptor::LABEL_REPEATED &&
descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
PyObject* sub_message = cmessage::InternalGetSubMessage(
@@ -122,7 +130,7 @@ PyObject* subscript(ExtensionDict* self, PyObject* key) {
if (descriptor->label() == FieldDescriptor::LABEL_REPEATED) {
if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
- PyObject *message_class = cdescriptor_pool::GetMessageClass(
+ CMessageClass* message_class = cdescriptor_pool::GetMessageClass(
cmessage::GetDescriptorPoolForMessage(self->parent),
descriptor->message_type());
if (message_class == NULL) {
@@ -154,7 +162,7 @@ int ass_subscript(ExtensionDict* self, PyObject* key, PyObject* value) {
if (descriptor == NULL) {
return -1;
}
- if (!CheckFieldBelongsToMessage(descriptor, self->parent->message)) {
+ if (!CheckFieldBelongsToMessage(descriptor, self->message)) {
return -1;
}
@@ -164,9 +172,11 @@ int ass_subscript(ExtensionDict* self, PyObject* key, PyObject* value) {
"type");
return -1;
}
- cmessage::AssureWritable(self->parent);
- if (cmessage::InternalSetScalar(self->parent, descriptor, value) < 0) {
- return -1;
+ if (self->parent) {
+ cmessage::AssureWritable(self->parent);
+ if (cmessage::InternalSetScalar(self->parent, descriptor, value) < 0) {
+ return -1;
+ }
}
// TODO(tibell): We shouldn't write scalars to the cache.
PyDict_SetItem(self->values, key, value);
@@ -180,15 +190,17 @@ PyObject* ClearExtension(ExtensionDict* self, PyObject* extension) {
return NULL;
}
PyObject* value = PyDict_GetItem(self->values, extension);
- if (value != NULL) {
- if (ReleaseExtension(self, value, descriptor) < 0) {
+ if (self->parent) {
+ if (value != NULL) {
+ if (ReleaseExtension(self, value, descriptor) < 0) {
+ return NULL;
+ }
+ }
+ if (ScopedPyObjectPtr(cmessage::ClearFieldByDescriptor(
+ self->parent, descriptor)) == NULL) {
return NULL;
}
}
- if (ScopedPyObjectPtr(cmessage::ClearFieldByDescriptor(
- self->parent, descriptor)) == NULL) {
- return NULL;
- }
if (PyDict_DelItem(self->values, extension) < 0) {
PyErr_Clear();
}
@@ -201,8 +213,15 @@ PyObject* HasExtension(ExtensionDict* self, PyObject* extension) {
if (descriptor == NULL) {
return NULL;
}
- PyObject* result = cmessage::HasFieldByDescriptor(self->parent, descriptor);
- return result;
+ if (self->parent) {
+ return cmessage::HasFieldByDescriptor(self->parent, descriptor);
+ } else {
+ int exists = PyDict_Contains(self->values, extension);
+ if (exists < 0) {
+ return NULL;
+ }
+ return PyBool_FromLong(exists);
+ }
}
PyObject* _FindExtensionByName(ExtensionDict* self, PyObject* name) {
@@ -220,6 +239,21 @@ PyObject* _FindExtensionByName(ExtensionDict* self, PyObject* name) {
}
}
+PyObject* _FindExtensionByNumber(ExtensionDict* self, PyObject* number) {
+ ScopedPyObjectPtr extensions_by_number(PyObject_GetAttrString(
+ reinterpret_cast<PyObject*>(self->parent), "_extensions_by_number"));
+ if (extensions_by_number == NULL) {
+ return NULL;
+ }
+ PyObject* result = PyDict_GetItem(extensions_by_number.get(), number);
+ if (result == NULL) {
+ Py_RETURN_NONE;
+ } else {
+ Py_INCREF(result);
+ return result;
+ }
+}
+
ExtensionDict* NewExtensionDict(CMessage *parent) {
ExtensionDict* self = reinterpret_cast<ExtensionDict*>(
PyType_GenericAlloc(&ExtensionDict_Type, 0));
@@ -252,6 +286,8 @@ static PyMethodDef Methods[] = {
EDMETHOD(HasExtension, METH_O, "Checks if the object has an extension."),
EDMETHOD(_FindExtensionByName, METH_O,
"Finds an extension by name."),
+ EDMETHOD(_FindExtensionByNumber, METH_O,
+ "Finds an extension by field number."),
{ NULL, NULL }
};
diff --git a/python/google/protobuf/pyext/extension_dict.h b/python/google/protobuf/pyext/extension_dict.h
index 7a66cb23..2456eda1 100644
--- a/python/google/protobuf/pyext/extension_dict.h
+++ b/python/google/protobuf/pyext/extension_dict.h
@@ -117,17 +117,18 @@ int ass_subscript(ExtensionDict* self, PyObject* key, PyObject* value);
PyObject* ClearExtension(ExtensionDict* self,
PyObject* extension);
-// Checks if the dict has an extension.
-//
-// Returns a new python boolean reference.
-PyObject* HasExtension(ExtensionDict* self, PyObject* extension);
-
// Gets an extension from the dict given the extension name as opposed to
// descriptor.
//
// Returns a new reference.
PyObject* _FindExtensionByName(ExtensionDict* self, PyObject* name);
+// Gets an extension from the dict given the extension field number as
+// opposed to descriptor.
+//
+// Returns a new reference.
+PyObject* _FindExtensionByNumber(ExtensionDict* self, PyObject* number);
+
} // namespace extension_dict
} // namespace python
} // namespace protobuf
diff --git a/python/google/protobuf/pyext/map_container.cc b/python/google/protobuf/pyext/map_container.cc
new file mode 100644
index 00000000..0987b898
--- /dev/null
+++ b/python/google/protobuf/pyext/map_container.cc
@@ -0,0 +1,970 @@
+// 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.
+
+// Author: haberman@google.com (Josh Haberman)
+
+#include <google/protobuf/pyext/map_container.h>
+
+#include <memory>
+#ifndef _SHARED_PTR_H
+#include <google/protobuf/stubs/shared_ptr.h>
+#endif
+
+#include <google/protobuf/stubs/logging.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/map_field.h>
+#include <google/protobuf/map.h>
+#include <google/protobuf/message.h>
+#include <google/protobuf/pyext/message.h>
+#include <google/protobuf/pyext/scoped_pyobject_ptr.h>
+
+#if PY_MAJOR_VERSION >= 3
+ #define PyInt_FromLong PyLong_FromLong
+ #define PyInt_FromSize_t PyLong_FromSize_t
+#endif
+
+namespace google {
+namespace protobuf {
+namespace python {
+
+// Functions that need access to map reflection functionality.
+// They need to be contained in this class because it is friended.
+class MapReflectionFriend {
+ public:
+ // Methods that are in common between the map types.
+ static PyObject* Contains(PyObject* _self, PyObject* key);
+ static Py_ssize_t Length(PyObject* _self);
+ static PyObject* GetIterator(PyObject *_self);
+ static PyObject* IterNext(PyObject* _self);
+
+ // Methods that differ between the map types.
+ static PyObject* ScalarMapGetItem(PyObject* _self, PyObject* key);
+ static PyObject* MessageMapGetItem(PyObject* _self, PyObject* key);
+ static int ScalarMapSetItem(PyObject* _self, PyObject* key, PyObject* v);
+ static int MessageMapSetItem(PyObject* _self, PyObject* key, PyObject* v);
+};
+
+struct MapIterator {
+ PyObject_HEAD;
+
+ google::protobuf::scoped_ptr< ::google::protobuf::MapIterator> iter;
+
+ // A pointer back to the container, so we can notice changes to the version.
+ // We own a ref on this.
+ MapContainer* container;
+
+ // We need to keep a ref on the Message* too, because
+ // MapIterator::~MapIterator() accesses it. Normally this would be ok because
+ // the ref on container (above) would guarantee outlive semantics. However in
+ // the case of ClearField(), InitializeAndCopyToParentContainer() resets the
+ // message pointer (and the owner) to a different message, a copy of the
+ // original. But our iterator still points to the original, which could now
+ // get deleted before us.
+ //
+ // To prevent this, we ensure that the Message will always stay alive as long
+ // as this iterator does. This is solely for the benefit of the MapIterator
+ // destructor -- we should never actually access the iterator in this state
+ // except to delete it.
+ shared_ptr<Message> owner;
+
+ // The version of the map when we took the iterator to it.
+ //
+ // We store this so that if the map is modified during iteration we can throw
+ // an error.
+ uint64 version;
+
+ // True if the container is empty. We signal this separately to avoid calling
+ // any of the iteration methods, which are non-const.
+ bool empty;
+};
+
+Message* MapContainer::GetMutableMessage() {
+ cmessage::AssureWritable(parent);
+ return const_cast<Message*>(message);
+}
+
+// Consumes a reference on the Python string object.
+static bool PyStringToSTL(PyObject* py_string, string* stl_string) {
+ char *value;
+ Py_ssize_t value_len;
+
+ if (!py_string) {
+ return false;
+ }
+ if (PyBytes_AsStringAndSize(py_string, &value, &value_len) < 0) {
+ Py_DECREF(py_string);
+ return false;
+ } else {
+ stl_string->assign(value, value_len);
+ Py_DECREF(py_string);
+ return true;
+ }
+}
+
+static bool PythonToMapKey(PyObject* obj,
+ const FieldDescriptor* field_descriptor,
+ MapKey* key) {
+ switch (field_descriptor->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32: {
+ GOOGLE_CHECK_GET_INT32(obj, value, false);
+ key->SetInt32Value(value);
+ break;
+ }
+ case FieldDescriptor::CPPTYPE_INT64: {
+ GOOGLE_CHECK_GET_INT64(obj, value, false);
+ key->SetInt64Value(value);
+ break;
+ }
+ case FieldDescriptor::CPPTYPE_UINT32: {
+ GOOGLE_CHECK_GET_UINT32(obj, value, false);
+ key->SetUInt32Value(value);
+ break;
+ }
+ case FieldDescriptor::CPPTYPE_UINT64: {
+ GOOGLE_CHECK_GET_UINT64(obj, value, false);
+ key->SetUInt64Value(value);
+ break;
+ }
+ case FieldDescriptor::CPPTYPE_BOOL: {
+ GOOGLE_CHECK_GET_BOOL(obj, value, false);
+ key->SetBoolValue(value);
+ break;
+ }
+ case FieldDescriptor::CPPTYPE_STRING: {
+ string str;
+ if (!PyStringToSTL(CheckString(obj, field_descriptor), &str)) {
+ return false;
+ }
+ key->SetStringValue(str);
+ break;
+ }
+ default:
+ PyErr_Format(
+ PyExc_SystemError, "Type %d cannot be a map key",
+ field_descriptor->cpp_type());
+ return false;
+ }
+ return true;
+}
+
+static PyObject* MapKeyToPython(const FieldDescriptor* field_descriptor,
+ const MapKey& key) {
+ switch (field_descriptor->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ return PyInt_FromLong(key.GetInt32Value());
+ case FieldDescriptor::CPPTYPE_INT64:
+ return PyLong_FromLongLong(key.GetInt64Value());
+ case FieldDescriptor::CPPTYPE_UINT32:
+ return PyInt_FromSize_t(key.GetUInt32Value());
+ case FieldDescriptor::CPPTYPE_UINT64:
+ return PyLong_FromUnsignedLongLong(key.GetUInt64Value());
+ case FieldDescriptor::CPPTYPE_BOOL:
+ return PyBool_FromLong(key.GetBoolValue());
+ case FieldDescriptor::CPPTYPE_STRING:
+ return ToStringObject(field_descriptor, key.GetStringValue());
+ default:
+ PyErr_Format(
+ PyExc_SystemError, "Couldn't convert type %d to value",
+ field_descriptor->cpp_type());
+ return NULL;
+ }
+}
+
+// This is only used for ScalarMap, so we don't need to handle the
+// CPPTYPE_MESSAGE case.
+PyObject* MapValueRefToPython(const FieldDescriptor* field_descriptor,
+ MapValueRef* value) {
+ switch (field_descriptor->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ return PyInt_FromLong(value->GetInt32Value());
+ case FieldDescriptor::CPPTYPE_INT64:
+ return PyLong_FromLongLong(value->GetInt64Value());
+ case FieldDescriptor::CPPTYPE_UINT32:
+ return PyInt_FromSize_t(value->GetUInt32Value());
+ case FieldDescriptor::CPPTYPE_UINT64:
+ return PyLong_FromUnsignedLongLong(value->GetUInt64Value());
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ return PyFloat_FromDouble(value->GetFloatValue());
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ return PyFloat_FromDouble(value->GetDoubleValue());
+ case FieldDescriptor::CPPTYPE_BOOL:
+ return PyBool_FromLong(value->GetBoolValue());
+ case FieldDescriptor::CPPTYPE_STRING:
+ return ToStringObject(field_descriptor, value->GetStringValue());
+ case FieldDescriptor::CPPTYPE_ENUM:
+ return PyInt_FromLong(value->GetEnumValue());
+ default:
+ PyErr_Format(
+ PyExc_SystemError, "Couldn't convert type %d to value",
+ field_descriptor->cpp_type());
+ return NULL;
+ }
+}
+
+// This is only used for ScalarMap, so we don't need to handle the
+// CPPTYPE_MESSAGE case.
+static bool PythonToMapValueRef(PyObject* obj,
+ const FieldDescriptor* field_descriptor,
+ bool allow_unknown_enum_values,
+ MapValueRef* value_ref) {
+ switch (field_descriptor->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32: {
+ GOOGLE_CHECK_GET_INT32(obj, value, false);
+ value_ref->SetInt32Value(value);
+ return true;
+ }
+ case FieldDescriptor::CPPTYPE_INT64: {
+ GOOGLE_CHECK_GET_INT64(obj, value, false);
+ value_ref->SetInt64Value(value);
+ return true;
+ }
+ case FieldDescriptor::CPPTYPE_UINT32: {
+ GOOGLE_CHECK_GET_UINT32(obj, value, false);
+ value_ref->SetUInt32Value(value);
+ return true;
+ }
+ case FieldDescriptor::CPPTYPE_UINT64: {
+ GOOGLE_CHECK_GET_UINT64(obj, value, false);
+ value_ref->SetUInt64Value(value);
+ return true;
+ }
+ case FieldDescriptor::CPPTYPE_FLOAT: {
+ GOOGLE_CHECK_GET_FLOAT(obj, value, false);
+ value_ref->SetFloatValue(value);
+ return true;
+ }
+ case FieldDescriptor::CPPTYPE_DOUBLE: {
+ GOOGLE_CHECK_GET_DOUBLE(obj, value, false);
+ value_ref->SetDoubleValue(value);
+ return true;
+ }
+ case FieldDescriptor::CPPTYPE_BOOL: {
+ GOOGLE_CHECK_GET_BOOL(obj, value, false);
+ value_ref->SetBoolValue(value);
+ return true;;
+ }
+ case FieldDescriptor::CPPTYPE_STRING: {
+ string str;
+ if (!PyStringToSTL(CheckString(obj, field_descriptor), &str)) {
+ return false;
+ }
+ value_ref->SetStringValue(str);
+ return true;
+ }
+ case FieldDescriptor::CPPTYPE_ENUM: {
+ GOOGLE_CHECK_GET_INT32(obj, value, false);
+ if (allow_unknown_enum_values) {
+ value_ref->SetEnumValue(value);
+ return true;
+ } else {
+ const EnumDescriptor* enum_descriptor = field_descriptor->enum_type();
+ const EnumValueDescriptor* enum_value =
+ enum_descriptor->FindValueByNumber(value);
+ if (enum_value != NULL) {
+ value_ref->SetEnumValue(value);
+ return true;
+ } else {
+ PyErr_Format(PyExc_ValueError, "Unknown enum value: %d", value);
+ return false;
+ }
+ }
+ break;
+ }
+ default:
+ PyErr_Format(
+ PyExc_SystemError, "Setting value to a field of unknown type %d",
+ field_descriptor->cpp_type());
+ return false;
+ }
+}
+
+// Map methods common to ScalarMap and MessageMap //////////////////////////////
+
+static MapContainer* GetMap(PyObject* obj) {
+ return reinterpret_cast<MapContainer*>(obj);
+}
+
+Py_ssize_t MapReflectionFriend::Length(PyObject* _self) {
+ MapContainer* self = GetMap(_self);
+ const google::protobuf::Message* message = self->message;
+ return message->GetReflection()->MapSize(*message,
+ self->parent_field_descriptor);
+}
+
+PyObject* Clear(PyObject* _self) {
+ MapContainer* self = GetMap(_self);
+ Message* message = self->GetMutableMessage();
+ const Reflection* reflection = message->GetReflection();
+
+ reflection->ClearField(message, self->parent_field_descriptor);
+
+ Py_RETURN_NONE;
+}
+
+PyObject* MapReflectionFriend::Contains(PyObject* _self, PyObject* key) {
+ MapContainer* self = GetMap(_self);
+
+ const Message* message = self->message;
+ const Reflection* reflection = message->GetReflection();
+ MapKey map_key;
+
+ if (!PythonToMapKey(key, self->key_field_descriptor, &map_key)) {
+ return NULL;
+ }
+
+ if (reflection->ContainsMapKey(*message, self->parent_field_descriptor,
+ map_key)) {
+ Py_RETURN_TRUE;
+ } else {
+ Py_RETURN_FALSE;
+ }
+}
+
+// Initializes the underlying Message object of "to" so it becomes a new parent
+// map container, and copies all the values from "from" to it. A child map
+// container can be released by passing it as both from and to (e.g. making it
+// the recipient of the new parent message and copying the values from itself).
+// In fact, this is the only supported use at the moment.
+static int InitializeAndCopyToParentContainer(MapContainer* from,
+ MapContainer* to) {
+ // For now we require from == to, re-evaluate if we want to support deep copy
+ // as in repeated_scalar_container.cc.
+ GOOGLE_DCHECK(from == to);
+ Message* new_message = from->message->New();
+
+ if (MapReflectionFriend::Length(reinterpret_cast<PyObject*>(from)) > 0) {
+ // A somewhat roundabout way of copying just one field from old_message to
+ // new_message. This is the best we can do with what Reflection gives us.
+ Message* mutable_old = from->GetMutableMessage();
+ vector<const FieldDescriptor*> fields;
+ fields.push_back(from->parent_field_descriptor);
+
+ // Move the map field into the new message.
+ mutable_old->GetReflection()->SwapFields(mutable_old, new_message, fields);
+
+ // If/when we support from != to, this will be required also to copy the
+ // map field back into the existing message:
+ // mutable_old->MergeFrom(*new_message);
+ }
+
+ // If from == to this could delete old_message.
+ to->owner.reset(new_message);
+
+ to->parent = NULL;
+ to->parent_field_descriptor = from->parent_field_descriptor;
+ to->message = new_message;
+
+ // Invalidate iterators, since they point to the old copy of the field.
+ to->version++;
+
+ return 0;
+}
+
+int MapContainer::Release() {
+ return InitializeAndCopyToParentContainer(this, this);
+}
+
+
+// ScalarMap ///////////////////////////////////////////////////////////////////
+
+PyObject *NewScalarMapContainer(
+ CMessage* parent, const google::protobuf::FieldDescriptor* parent_field_descriptor) {
+ if (!CheckFieldBelongsToMessage(parent_field_descriptor, parent->message)) {
+ return NULL;
+ }
+
+#if PY_MAJOR_VERSION >= 3
+ ScopedPyObjectPtr obj(PyType_GenericAlloc(
+ reinterpret_cast<PyTypeObject *>(ScalarMapContainer_Type), 0));
+#else
+ ScopedPyObjectPtr obj(PyType_GenericAlloc(&ScalarMapContainer_Type, 0));
+#endif
+ if (obj.get() == NULL) {
+ return PyErr_Format(PyExc_RuntimeError,
+ "Could not allocate new container.");
+ }
+
+ MapContainer* self = GetMap(obj.get());
+
+ self->message = parent->message;
+ self->parent = parent;
+ self->parent_field_descriptor = parent_field_descriptor;
+ self->owner = parent->owner;
+ self->version = 0;
+
+ self->key_field_descriptor =
+ parent_field_descriptor->message_type()->FindFieldByName("key");
+ self->value_field_descriptor =
+ parent_field_descriptor->message_type()->FindFieldByName("value");
+
+ if (self->key_field_descriptor == NULL ||
+ self->value_field_descriptor == NULL) {
+ return PyErr_Format(PyExc_KeyError,
+ "Map entry descriptor did not have key/value fields");
+ }
+
+ return obj.release();
+}
+
+PyObject* MapReflectionFriend::ScalarMapGetItem(PyObject* _self,
+ PyObject* key) {
+ MapContainer* self = GetMap(_self);
+
+ Message* message = self->GetMutableMessage();
+ const Reflection* reflection = message->GetReflection();
+ MapKey map_key;
+ MapValueRef value;
+
+ if (!PythonToMapKey(key, self->key_field_descriptor, &map_key)) {
+ return NULL;
+ }
+
+ if (reflection->InsertOrLookupMapValue(message, self->parent_field_descriptor,
+ map_key, &value)) {
+ self->version++;
+ }
+
+ return MapValueRefToPython(self->value_field_descriptor, &value);
+}
+
+int MapReflectionFriend::ScalarMapSetItem(PyObject* _self, PyObject* key,
+ PyObject* v) {
+ MapContainer* self = GetMap(_self);
+
+ Message* message = self->GetMutableMessage();
+ const Reflection* reflection = message->GetReflection();
+ MapKey map_key;
+ MapValueRef value;
+
+ if (!PythonToMapKey(key, self->key_field_descriptor, &map_key)) {
+ return -1;
+ }
+
+ self->version++;
+
+ if (v) {
+ // Set item to v.
+ reflection->InsertOrLookupMapValue(message, self->parent_field_descriptor,
+ map_key, &value);
+
+ return PythonToMapValueRef(v, self->value_field_descriptor,
+ reflection->SupportsUnknownEnumValues(), &value)
+ ? 0
+ : -1;
+ } else {
+ // Delete key from map.
+ if (reflection->DeleteMapValue(message, self->parent_field_descriptor,
+ map_key)) {
+ return 0;
+ } else {
+ PyErr_Format(PyExc_KeyError, "Key not present in map");
+ return -1;
+ }
+ }
+}
+
+static PyObject* ScalarMapGet(PyObject* self, PyObject* args) {
+ PyObject* key;
+ PyObject* default_value = NULL;
+ if (PyArg_ParseTuple(args, "O|O", &key, &default_value) < 0) {
+ return NULL;
+ }
+
+ ScopedPyObjectPtr is_present(MapReflectionFriend::Contains(self, key));
+ if (is_present.get() == NULL) {
+ return NULL;
+ }
+
+ if (PyObject_IsTrue(is_present.get())) {
+ return MapReflectionFriend::ScalarMapGetItem(self, key);
+ } else {
+ if (default_value != NULL) {
+ Py_INCREF(default_value);
+ return default_value;
+ } else {
+ Py_RETURN_NONE;
+ }
+ }
+}
+
+static void ScalarMapDealloc(PyObject* _self) {
+ MapContainer* self = GetMap(_self);
+ self->owner.reset();
+ Py_TYPE(_self)->tp_free(_self);
+}
+
+static PyMethodDef ScalarMapMethods[] = {
+ { "__contains__", MapReflectionFriend::Contains, METH_O,
+ "Tests whether a key is a member of the map." },
+ { "clear", (PyCFunction)Clear, METH_NOARGS,
+ "Removes all elements from the map." },
+ { "get", ScalarMapGet, METH_VARARGS,
+ "Gets the value for the given key if present, or otherwise a default" },
+ /*
+ { "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS,
+ "Makes a deep copy of the class." },
+ { "__reduce__", (PyCFunction)Reduce, METH_NOARGS,
+ "Outputs picklable representation of the repeated field." },
+ */
+ {NULL, NULL},
+};
+
+#if PY_MAJOR_VERSION >= 3
+ static PyType_Slot ScalarMapContainer_Type_slots[] = {
+ {Py_tp_dealloc, (void *)ScalarMapDealloc},
+ {Py_mp_length, (void *)MapReflectionFriend::Length},
+ {Py_mp_subscript, (void *)MapReflectionFriend::ScalarMapGetItem},
+ {Py_mp_ass_subscript, (void *)MapReflectionFriend::ScalarMapSetItem},
+ {Py_tp_methods, (void *)ScalarMapMethods},
+ {Py_tp_iter, (void *)MapReflectionFriend::GetIterator},
+ {0, 0},
+ };
+
+ PyType_Spec ScalarMapContainer_Type_spec = {
+ FULL_MODULE_NAME ".ScalarMapContainer",
+ sizeof(MapContainer),
+ 0,
+ Py_TPFLAGS_DEFAULT,
+ ScalarMapContainer_Type_slots
+ };
+ PyObject *ScalarMapContainer_Type;
+#else
+ static PyMappingMethods ScalarMapMappingMethods = {
+ MapReflectionFriend::Length, // mp_length
+ MapReflectionFriend::ScalarMapGetItem, // mp_subscript
+ MapReflectionFriend::ScalarMapSetItem, // mp_ass_subscript
+ };
+
+ PyTypeObject ScalarMapContainer_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ FULL_MODULE_NAME ".ScalarMapContainer", // tp_name
+ sizeof(MapContainer), // tp_basicsize
+ 0, // tp_itemsize
+ ScalarMapDealloc, // tp_dealloc
+ 0, // tp_print
+ 0, // tp_getattr
+ 0, // tp_setattr
+ 0, // tp_compare
+ 0, // tp_repr
+ 0, // tp_as_number
+ 0, // tp_as_sequence
+ &ScalarMapMappingMethods, // tp_as_mapping
+ 0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ 0, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ Py_TPFLAGS_DEFAULT, // tp_flags
+ "A scalar map container", // tp_doc
+ 0, // tp_traverse
+ 0, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ MapReflectionFriend::GetIterator, // tp_iter
+ 0, // tp_iternext
+ ScalarMapMethods, // tp_methods
+ 0, // tp_members
+ 0, // tp_getset
+ 0, // tp_base
+ 0, // tp_dict
+ 0, // tp_descr_get
+ 0, // tp_descr_set
+ 0, // tp_dictoffset
+ 0, // tp_init
+ };
+#endif
+
+
+// MessageMap //////////////////////////////////////////////////////////////////
+
+static MessageMapContainer* GetMessageMap(PyObject* obj) {
+ return reinterpret_cast<MessageMapContainer*>(obj);
+}
+
+static PyObject* GetCMessage(MessageMapContainer* self, Message* message) {
+ // Get or create the CMessage object corresponding to this message.
+ ScopedPyObjectPtr key(PyLong_FromVoidPtr(message));
+ PyObject* ret = PyDict_GetItem(self->message_dict, key.get());
+
+ if (ret == NULL) {
+ CMessage* cmsg = cmessage::NewEmptyMessage(self->message_class);
+ ret = reinterpret_cast<PyObject*>(cmsg);
+
+ if (cmsg == NULL) {
+ return NULL;
+ }
+ cmsg->owner = self->owner;
+ cmsg->message = message;
+ cmsg->parent = self->parent;
+
+ if (PyDict_SetItem(self->message_dict, key.get(), ret) < 0) {
+ Py_DECREF(ret);
+ return NULL;
+ }
+ } else {
+ Py_INCREF(ret);
+ }
+
+ return ret;
+}
+
+PyObject* NewMessageMapContainer(
+ CMessage* parent, const google::protobuf::FieldDescriptor* parent_field_descriptor,
+ CMessageClass* message_class) {
+ if (!CheckFieldBelongsToMessage(parent_field_descriptor, parent->message)) {
+ return NULL;
+ }
+
+#if PY_MAJOR_VERSION >= 3
+ PyObject* obj = PyType_GenericAlloc(
+ reinterpret_cast<PyTypeObject *>(MessageMapContainer_Type), 0);
+#else
+ PyObject* obj = PyType_GenericAlloc(&MessageMapContainer_Type, 0);
+#endif
+ if (obj == NULL) {
+ return PyErr_Format(PyExc_RuntimeError,
+ "Could not allocate new container.");
+ }
+
+ MessageMapContainer* self = GetMessageMap(obj);
+
+ self->message = parent->message;
+ self->parent = parent;
+ self->parent_field_descriptor = parent_field_descriptor;
+ self->owner = parent->owner;
+ self->version = 0;
+
+ self->key_field_descriptor =
+ parent_field_descriptor->message_type()->FindFieldByName("key");
+ self->value_field_descriptor =
+ parent_field_descriptor->message_type()->FindFieldByName("value");
+
+ self->message_dict = PyDict_New();
+ if (self->message_dict == NULL) {
+ return PyErr_Format(PyExc_RuntimeError,
+ "Could not allocate message dict.");
+ }
+
+ Py_INCREF(message_class);
+ self->message_class = message_class;
+
+ if (self->key_field_descriptor == NULL ||
+ self->value_field_descriptor == NULL) {
+ Py_DECREF(obj);
+ return PyErr_Format(PyExc_KeyError,
+ "Map entry descriptor did not have key/value fields");
+ }
+
+ return obj;
+}
+
+int MapReflectionFriend::MessageMapSetItem(PyObject* _self, PyObject* key,
+ PyObject* v) {
+ if (v) {
+ PyErr_Format(PyExc_ValueError,
+ "Direct assignment of submessage not allowed");
+ return -1;
+ }
+
+ // Now we know that this is a delete, not a set.
+
+ MessageMapContainer* self = GetMessageMap(_self);
+ Message* message = self->GetMutableMessage();
+ const Reflection* reflection = message->GetReflection();
+ MapKey map_key;
+ MapValueRef value;
+
+ self->version++;
+
+ if (!PythonToMapKey(key, self->key_field_descriptor, &map_key)) {
+ return -1;
+ }
+
+ // Delete key from map.
+ if (reflection->DeleteMapValue(message, self->parent_field_descriptor,
+ map_key)) {
+ return 0;
+ } else {
+ PyErr_Format(PyExc_KeyError, "Key not present in map");
+ return -1;
+ }
+}
+
+PyObject* MapReflectionFriend::MessageMapGetItem(PyObject* _self,
+ PyObject* key) {
+ MessageMapContainer* self = GetMessageMap(_self);
+
+ Message* message = self->GetMutableMessage();
+ const Reflection* reflection = message->GetReflection();
+ MapKey map_key;
+ MapValueRef value;
+
+ if (!PythonToMapKey(key, self->key_field_descriptor, &map_key)) {
+ return NULL;
+ }
+
+ if (reflection->InsertOrLookupMapValue(message, self->parent_field_descriptor,
+ map_key, &value)) {
+ self->version++;
+ }
+
+ return GetCMessage(self, value.MutableMessageValue());
+}
+
+PyObject* MessageMapGet(PyObject* self, PyObject* args) {
+ PyObject* key;
+ PyObject* default_value = NULL;
+ if (PyArg_ParseTuple(args, "O|O", &key, &default_value) < 0) {
+ return NULL;
+ }
+
+ ScopedPyObjectPtr is_present(MapReflectionFriend::Contains(self, key));
+ if (is_present.get() == NULL) {
+ return NULL;
+ }
+
+ if (PyObject_IsTrue(is_present.get())) {
+ return MapReflectionFriend::MessageMapGetItem(self, key);
+ } else {
+ if (default_value != NULL) {
+ Py_INCREF(default_value);
+ return default_value;
+ } else {
+ Py_RETURN_NONE;
+ }
+ }
+}
+
+static void MessageMapDealloc(PyObject* _self) {
+ MessageMapContainer* self = GetMessageMap(_self);
+ self->owner.reset();
+ Py_DECREF(self->message_dict);
+ Py_DECREF(self->message_class);
+ Py_TYPE(_self)->tp_free(_self);
+}
+
+static PyMethodDef MessageMapMethods[] = {
+ { "__contains__", (PyCFunction)MapReflectionFriend::Contains, METH_O,
+ "Tests whether the map contains this element."},
+ { "clear", (PyCFunction)Clear, METH_NOARGS,
+ "Removes all elements from the map."},
+ { "get", MessageMapGet, METH_VARARGS,
+ "Gets the value for the given key if present, or otherwise a default" },
+ { "get_or_create", MapReflectionFriend::MessageMapGetItem, METH_O,
+ "Alias for getitem, useful to make explicit that the map is mutated." },
+ /*
+ { "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS,
+ "Makes a deep copy of the class." },
+ { "__reduce__", (PyCFunction)Reduce, METH_NOARGS,
+ "Outputs picklable representation of the repeated field." },
+ */
+ {NULL, NULL},
+};
+
+#if PY_MAJOR_VERSION >= 3
+ static PyType_Slot MessageMapContainer_Type_slots[] = {
+ {Py_tp_dealloc, (void *)MessageMapDealloc},
+ {Py_mp_length, (void *)MapReflectionFriend::Length},
+ {Py_mp_subscript, (void *)MapReflectionFriend::MessageMapGetItem},
+ {Py_mp_ass_subscript, (void *)MapReflectionFriend::MessageMapSetItem},
+ {Py_tp_methods, (void *)MessageMapMethods},
+ {Py_tp_iter, (void *)MapReflectionFriend::GetIterator},
+ {0, 0}
+ };
+
+ PyType_Spec MessageMapContainer_Type_spec = {
+ FULL_MODULE_NAME ".MessageMapContainer",
+ sizeof(MessageMapContainer),
+ 0,
+ Py_TPFLAGS_DEFAULT,
+ MessageMapContainer_Type_slots
+ };
+
+ PyObject *MessageMapContainer_Type;
+#else
+ static PyMappingMethods MessageMapMappingMethods = {
+ MapReflectionFriend::Length, // mp_length
+ MapReflectionFriend::MessageMapGetItem, // mp_subscript
+ MapReflectionFriend::MessageMapSetItem, // mp_ass_subscript
+ };
+
+ PyTypeObject MessageMapContainer_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ FULL_MODULE_NAME ".MessageMapContainer", // tp_name
+ sizeof(MessageMapContainer), // tp_basicsize
+ 0, // tp_itemsize
+ MessageMapDealloc, // tp_dealloc
+ 0, // tp_print
+ 0, // tp_getattr
+ 0, // tp_setattr
+ 0, // tp_compare
+ 0, // tp_repr
+ 0, // tp_as_number
+ 0, // tp_as_sequence
+ &MessageMapMappingMethods, // tp_as_mapping
+ 0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ 0, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ Py_TPFLAGS_DEFAULT, // tp_flags
+ "A map container for message", // tp_doc
+ 0, // tp_traverse
+ 0, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ MapReflectionFriend::GetIterator, // tp_iter
+ 0, // tp_iternext
+ MessageMapMethods, // tp_methods
+ 0, // tp_members
+ 0, // tp_getset
+ 0, // tp_base
+ 0, // tp_dict
+ 0, // tp_descr_get
+ 0, // tp_descr_set
+ 0, // tp_dictoffset
+ 0, // tp_init
+ };
+#endif
+
+// MapIterator /////////////////////////////////////////////////////////////////
+
+static MapIterator* GetIter(PyObject* obj) {
+ return reinterpret_cast<MapIterator*>(obj);
+}
+
+PyObject* MapReflectionFriend::GetIterator(PyObject *_self) {
+ MapContainer* self = GetMap(_self);
+
+ ScopedPyObjectPtr obj(PyType_GenericAlloc(&MapIterator_Type, 0));
+ if (obj == NULL) {
+ return PyErr_Format(PyExc_KeyError, "Could not allocate iterator");
+ }
+
+ MapIterator* iter = GetIter(obj.get());
+
+ Py_INCREF(self);
+ iter->container = self;
+ iter->version = self->version;
+ iter->owner = self->owner;
+
+ if (MapReflectionFriend::Length(_self) > 0) {
+ Message* message = self->GetMutableMessage();
+ const Reflection* reflection = message->GetReflection();
+
+ iter->iter.reset(new ::google::protobuf::MapIterator(
+ reflection->MapBegin(message, self->parent_field_descriptor)));
+ }
+
+ return obj.release();
+}
+
+PyObject* MapReflectionFriend::IterNext(PyObject* _self) {
+ MapIterator* self = GetIter(_self);
+
+ // This won't catch mutations to the map performed by MergeFrom(); no easy way
+ // to address that.
+ if (self->version != self->container->version) {
+ return PyErr_Format(PyExc_RuntimeError,
+ "Map modified during iteration.");
+ }
+
+ if (self->iter.get() == NULL) {
+ return NULL;
+ }
+
+ Message* message = self->container->GetMutableMessage();
+ const Reflection* reflection = message->GetReflection();
+
+ if (*self->iter ==
+ reflection->MapEnd(message, self->container->parent_field_descriptor)) {
+ return NULL;
+ }
+
+ PyObject* ret = MapKeyToPython(self->container->key_field_descriptor,
+ self->iter->GetKey());
+
+ ++(*self->iter);
+
+ return ret;
+}
+
+static void DeallocMapIterator(PyObject* _self) {
+ MapIterator* self = GetIter(_self);
+ self->iter.reset();
+ self->owner.reset();
+ Py_XDECREF(self->container);
+ Py_TYPE(_self)->tp_free(_self);
+}
+
+PyTypeObject MapIterator_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ FULL_MODULE_NAME ".MapIterator", // tp_name
+ sizeof(MapIterator), // tp_basicsize
+ 0, // tp_itemsize
+ DeallocMapIterator, // tp_dealloc
+ 0, // tp_print
+ 0, // tp_getattr
+ 0, // tp_setattr
+ 0, // tp_compare
+ 0, // tp_repr
+ 0, // tp_as_number
+ 0, // tp_as_sequence
+ 0, // tp_as_mapping
+ 0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ 0, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ Py_TPFLAGS_DEFAULT, // tp_flags
+ "A scalar map iterator", // tp_doc
+ 0, // tp_traverse
+ 0, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ PyObject_SelfIter, // tp_iter
+ MapReflectionFriend::IterNext, // tp_iternext
+ 0, // tp_methods
+ 0, // tp_members
+ 0, // tp_getset
+ 0, // tp_base
+ 0, // tp_dict
+ 0, // tp_descr_get
+ 0, // tp_descr_set
+ 0, // tp_dictoffset
+ 0, // tp_init
+};
+
+} // namespace python
+} // namespace protobuf
+} // namespace google
diff --git a/python/google/protobuf/pyext/message_map_container.h b/python/google/protobuf/pyext/map_container.h
index 4f6cb26a..fbd6713f 100644
--- a/python/google/protobuf/pyext/message_map_container.h
+++ b/python/google/protobuf/pyext/map_container.h
@@ -28,8 +28,8 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#ifndef GOOGLE_PROTOBUF_PYTHON_CPP_MESSAGE_MAP_CONTAINER_H__
-#define GOOGLE_PROTOBUF_PYTHON_CPP_MESSAGE_MAP_CONTAINER_H__
+#ifndef GOOGLE_PROTOBUF_PYTHON_CPP_MAP_CONTAINER_H__
+#define GOOGLE_PROTOBUF_PYTHON_CPP_MAP_CONTAINER_H__
#include <Python.h>
@@ -39,6 +39,7 @@
#endif
#include <google/protobuf/descriptor.h>
+#include <google/protobuf/message.h>
namespace google {
namespace protobuf {
@@ -54,19 +55,25 @@ using internal::shared_ptr;
namespace python {
struct CMessage;
+struct CMessageClass;
-struct MessageMapContainer {
+// This struct is used directly for ScalarMap, and is the base class of
+// MessageMapContainer, which is used for MessageMap.
+struct MapContainer {
PyObject_HEAD;
// This is the top-level C++ Message object that owns the whole
- // proto tree. Every Python MessageMapContainer holds a
+ // proto tree. Every Python MapContainer holds a
// reference to it in order to keep it alive as long as there's a
// Python object that references any part of the tree.
shared_ptr<Message> owner;
// Pointer to the C++ Message that contains this container. The
- // MessageMapContainer does not own this pointer.
- Message* message;
+ // MapContainer does not own this pointer.
+ const Message* message;
+
+ // Use to get a mutable message when necessary.
+ Message* GetMutableMessage();
// Weak reference to a parent CMessage object (i.e. may be NULL.)
//
@@ -82,45 +89,54 @@ struct MessageMapContainer {
const FieldDescriptor* key_field_descriptor;
const FieldDescriptor* value_field_descriptor;
- // A callable that is used to create new child messages.
- PyObject* subclass_init;
-
- // A dict mapping Message* -> CMessage.
- PyObject* message_dict;
-
// We bump this whenever we perform a mutation, to invalidate existing
// iterators.
uint64 version;
+
+ // Releases the messages in the container to a new message.
+ //
+ // Returns 0 on success, -1 on failure.
+ int Release();
+
+ // Set the owner field of self and any children of self.
+ void SetOwner(const shared_ptr<Message>& new_owner) {
+ owner = new_owner;
+ }
+};
+
+struct MessageMapContainer : public MapContainer {
+ // The type used to create new child messages.
+ CMessageClass* message_class;
+
+ // A dict mapping Message* -> CMessage.
+ PyObject* message_dict;
};
#if PY_MAJOR_VERSION >= 3
extern PyObject *MessageMapContainer_Type;
extern PyType_Spec MessageMapContainer_Type_spec;
+ extern PyObject *ScalarMapContainer_Type;
+ extern PyType_Spec ScalarMapContainer_Type_spec;
#else
extern PyTypeObject MessageMapContainer_Type;
+ extern PyTypeObject ScalarMapContainer_Type;
#endif
-extern PyTypeObject MessageMapIterator_Type;
-namespace message_map_container {
+extern PyTypeObject MapIterator_Type; // Both map types use the same iterator.
-// Builds a MessageMapContainer object, from a parent message and a
+// Builds a MapContainer object, from a parent message and a
// field descriptor.
-extern PyObject* NewContainer(CMessage* parent,
- const FieldDescriptor* parent_field_descriptor,
- PyObject* concrete_class);
-
-// Releases the messages in the container to a new message.
-//
-// Returns 0 on success, -1 on failure.
-int Release(MessageMapContainer* self);
+extern PyObject* NewScalarMapContainer(
+ CMessage* parent, const FieldDescriptor* parent_field_descriptor);
-// Set the owner field of self and any children of self.
-void SetOwner(MessageMapContainer* self,
- const shared_ptr<Message>& new_owner);
+// Builds a MessageMap object, from a parent message and a
+// field descriptor.
+extern PyObject* NewMessageMapContainer(
+ CMessage* parent, const FieldDescriptor* parent_field_descriptor,
+ CMessageClass* message_class);
-} // namespace message_map_container
} // namespace python
} // namespace protobuf
} // namespace google
-#endif // GOOGLE_PROTOBUF_PYTHON_CPP_MESSAGE_MAP_CONTAINER_H__
+#endif // GOOGLE_PROTOBUF_PYTHON_CPP_MAP_CONTAINER_H__
diff --git a/python/google/protobuf/pyext/message.cc b/python/google/protobuf/pyext/message.cc
index 72f51ec1..5535338d 100644
--- a/python/google/protobuf/pyext/message.cc
+++ b/python/google/protobuf/pyext/message.cc
@@ -33,6 +33,7 @@
#include <google/protobuf/pyext/message.h>
+#include <map>
#include <memory>
#ifndef _SHARED_PTR_H
#include <google/protobuf/stubs/shared_ptr.h>
@@ -61,8 +62,7 @@
#include <google/protobuf/pyext/extension_dict.h>
#include <google/protobuf/pyext/repeated_composite_container.h>
#include <google/protobuf/pyext/repeated_scalar_container.h>
-#include <google/protobuf/pyext/message_map_container.h>
-#include <google/protobuf/pyext/scalar_map_container.h>
+#include <google/protobuf/pyext/map_container.h>
#include <google/protobuf/pyext/scoped_pyobject_ptr.h>
#include <google/protobuf/stubs/strutil.h>
@@ -96,31 +96,7 @@ static PyObject* k_extensions_by_number;
PyObject* EnumTypeWrapper_class;
static PyObject* PythonMessage_class;
static PyObject* kEmptyWeakref;
-
-// Defines the Metaclass of all Message classes.
-// It allows us to cache some C++ pointers in the class object itself, they are
-// faster to extract than from the type's dictionary.
-
-struct PyMessageMeta {
- // This is how CPython subclasses C structures: the base structure must be
- // the first member of the object.
- PyHeapTypeObject super;
-
- // C++ descriptor of this message.
- const Descriptor* message_descriptor;
-
- // Owned reference, used to keep the pointer above alive.
- PyObject* py_message_descriptor;
-
- // The Python DescriptorPool used to create the class. It is needed to resolve
- // fields descriptors, including extensions fields; its C++ MessageFactory is
- // used to instantiate submessages.
- // This can be different from DESCRIPTOR.file.pool, in the case of a custom
- // DescriptorPool which defines new extensions.
- // We own the reference, because it's important to keep the descriptors and
- // factory alive.
- PyDescriptorPool* py_descriptor_pool;
-};
+static PyObject* WKT_classes = NULL;
namespace message_meta {
@@ -172,10 +148,6 @@ static int AddDescriptors(PyObject* cls, const Descriptor* descriptor) {
}
// For each enum set cls.<enum name> = EnumTypeWrapper(<enum descriptor>).
- //
- // The enum descriptor we get from
- // <messagedescriptor>.enum_types_by_name[name]
- // which was built previously.
for (int i = 0; i < descriptor->enum_type_count(); ++i) {
const EnumDescriptor* enum_descriptor = descriptor->enum_type(i);
ScopedPyObjectPtr enum_type(
@@ -274,8 +246,32 @@ static PyObject* New(PyTypeObject* type,
// Build the arguments to the base metaclass.
// We change the __bases__ classes.
- ScopedPyObjectPtr new_args(Py_BuildValue(
- "s(OO)O", name, &CMessage_Type, PythonMessage_class, dict));
+ ScopedPyObjectPtr new_args;
+ const Descriptor* message_descriptor =
+ PyMessageDescriptor_AsDescriptor(py_descriptor);
+ if (message_descriptor == NULL) {
+ return NULL;
+ }
+
+ if (WKT_classes == NULL) {
+ ScopedPyObjectPtr well_known_types(PyImport_ImportModule(
+ "google.protobuf.internal.well_known_types"));
+ GOOGLE_DCHECK(well_known_types != NULL);
+
+ WKT_classes = PyObject_GetAttrString(well_known_types.get(), "WKTBASES");
+ GOOGLE_DCHECK(WKT_classes != NULL);
+ }
+
+ PyObject* well_known_class = PyDict_GetItemString(
+ WKT_classes, message_descriptor->full_name().c_str());
+ if (well_known_class == NULL) {
+ new_args.reset(Py_BuildValue("s(OO)O", name, &CMessage_Type,
+ PythonMessage_class, dict));
+ } else {
+ new_args.reset(Py_BuildValue("s(OOO)O", name, &CMessage_Type,
+ PythonMessage_class, well_known_class, dict));
+ }
+
if (new_args == NULL) {
return NULL;
}
@@ -284,7 +280,7 @@ static PyObject* New(PyTypeObject* type,
if (result == NULL) {
return NULL;
}
- PyMessageMeta* newtype = reinterpret_cast<PyMessageMeta*>(result.get());
+ CMessageClass* newtype = reinterpret_cast<CMessageClass*>(result.get());
// Insert the empty weakref into the base classes.
if (InsertEmptyWeakref(
@@ -313,7 +309,7 @@ static PyObject* New(PyTypeObject* type,
// Add the message to the DescriptorPool.
if (cdescriptor_pool::RegisterMessageClass(newtype->py_descriptor_pool,
- descriptor, result.get()) < 0) {
+ descriptor, newtype) < 0) {
return NULL;
}
@@ -324,7 +320,7 @@ static PyObject* New(PyTypeObject* type,
return result.release();
}
-static void Dealloc(PyMessageMeta *self) {
+static void Dealloc(CMessageClass *self) {
Py_DECREF(self->py_message_descriptor);
Py_DECREF(self->py_descriptor_pool);
Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
@@ -353,10 +349,10 @@ static int InsertEmptyWeakref(PyTypeObject *base_type) {
} // namespace message_meta
-PyTypeObject PyMessageMeta_Type = {
+PyTypeObject CMessageClass_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
FULL_MODULE_NAME ".MessageMeta", // tp_name
- sizeof(PyMessageMeta), // tp_basicsize
+ sizeof(CMessageClass), // tp_basicsize
0, // tp_itemsize
(destructor)message_meta::Dealloc, // tp_dealloc
0, // tp_print
@@ -394,16 +390,16 @@ PyTypeObject PyMessageMeta_Type = {
message_meta::New, // tp_new
};
-static PyMessageMeta* CheckMessageClass(PyTypeObject* cls) {
- if (!PyObject_TypeCheck(cls, &PyMessageMeta_Type)) {
+static CMessageClass* CheckMessageClass(PyTypeObject* cls) {
+ if (!PyObject_TypeCheck(cls, &CMessageClass_Type)) {
PyErr_Format(PyExc_TypeError, "Class %s is not a Message", cls->tp_name);
return NULL;
}
- return reinterpret_cast<PyMessageMeta*>(cls);
+ return reinterpret_cast<CMessageClass*>(cls);
}
static const Descriptor* GetMessageDescriptor(PyTypeObject* cls) {
- PyMessageMeta* type = CheckMessageClass(cls);
+ CMessageClass* type = CheckMessageClass(cls);
if (type == NULL) {
return NULL;
}
@@ -448,21 +444,9 @@ static int VisitCompositeField(const FieldDescriptor* descriptor,
if (descriptor->label() == FieldDescriptor::LABEL_REPEATED) {
if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
if (descriptor->is_map()) {
- const Descriptor* entry_type = descriptor->message_type();
- const FieldDescriptor* value_type =
- entry_type->FindFieldByName("value");
- if (value_type->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
- MessageMapContainer* container =
- reinterpret_cast<MessageMapContainer*>(child);
- if (visitor.VisitMessageMapContainer(container) == -1) {
- return -1;
- }
- } else {
- ScalarMapContainer* container =
- reinterpret_cast<ScalarMapContainer*>(child);
- if (visitor.VisitScalarMapContainer(container) == -1) {
- return -1;
- }
+ MapContainer* container = reinterpret_cast<MapContainer*>(child);
+ if (visitor.VisitMapContainer(container) == -1) {
+ return -1;
}
} else {
RepeatedCompositeContainer* container =
@@ -579,12 +563,14 @@ bool CheckAndGetInteger(
if (PyObject_RichCompareBool(min, arg, Py_LE) != 1 ||
PyObject_RichCompareBool(max, arg, Py_GE) != 1) {
#endif
- PyObject *s = PyObject_Str(arg);
- if (s) {
- PyErr_Format(PyExc_ValueError,
- "Value out of range: %s",
- PyString_AsString(s));
- Py_DECREF(s);
+ if (!PyErr_Occurred()) {
+ PyObject *s = PyObject_Str(arg);
+ if (s) {
+ PyErr_Format(PyExc_ValueError,
+ "Value out of range: %s",
+ PyString_AsString(s));
+ Py_DECREF(s);
+ }
}
return false;
}
@@ -642,38 +628,51 @@ bool CheckAndGetBool(PyObject* arg, bool* value) {
return true;
}
-bool CheckAndSetString(
- PyObject* arg, Message* message,
- const FieldDescriptor* descriptor,
- const Reflection* reflection,
- bool append,
- int index) {
+// Checks whether the given object (which must be "bytes" or "unicode") contains
+// valid UTF-8.
+bool IsValidUTF8(PyObject* obj) {
+ if (PyBytes_Check(obj)) {
+ PyObject* unicode = PyUnicode_FromEncodedObject(obj, "utf-8", NULL);
+
+ // Clear the error indicator; we report our own error when desired.
+ PyErr_Clear();
+
+ if (unicode) {
+ Py_DECREF(unicode);
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ // Unicode object, known to be valid UTF-8.
+ return true;
+ }
+}
+
+bool AllowInvalidUTF8(const FieldDescriptor* field) { return false; }
+
+PyObject* CheckString(PyObject* arg, const FieldDescriptor* descriptor) {
GOOGLE_DCHECK(descriptor->type() == FieldDescriptor::TYPE_STRING ||
descriptor->type() == FieldDescriptor::TYPE_BYTES);
if (descriptor->type() == FieldDescriptor::TYPE_STRING) {
if (!PyBytes_Check(arg) && !PyUnicode_Check(arg)) {
FormatTypeError(arg, "bytes, unicode");
- return false;
+ return NULL;
}
- if (PyBytes_Check(arg)) {
- PyObject* unicode = PyUnicode_FromEncodedObject(arg, "utf-8", NULL);
- if (unicode == NULL) {
- PyObject* repr = PyObject_Repr(arg);
- PyErr_Format(PyExc_ValueError,
- "%s has type str, but isn't valid UTF-8 "
- "encoding. Non-UTF-8 strings must be converted to "
- "unicode objects before being added.",
- PyString_AsString(repr));
- Py_DECREF(repr);
- return false;
- } else {
- Py_DECREF(unicode);
- }
+ if (!IsValidUTF8(arg) && !AllowInvalidUTF8(descriptor)) {
+ PyObject* repr = PyObject_Repr(arg);
+ PyErr_Format(PyExc_ValueError,
+ "%s has type str, but isn't valid UTF-8 "
+ "encoding. Non-UTF-8 strings must be converted to "
+ "unicode objects before being added.",
+ PyString_AsString(repr));
+ Py_DECREF(repr);
+ return NULL;
}
} else if (!PyBytes_Check(arg)) {
FormatTypeError(arg, "bytes");
- return false;
+ return NULL;
}
PyObject* encoded_string = NULL;
@@ -691,14 +690,24 @@ bool CheckAndSetString(
Py_INCREF(encoded_string);
}
- if (encoded_string == NULL) {
+ return encoded_string;
+}
+
+bool CheckAndSetString(
+ PyObject* arg, Message* message,
+ const FieldDescriptor* descriptor,
+ const Reflection* reflection,
+ bool append,
+ int index) {
+ ScopedPyObjectPtr encoded_string(CheckString(arg, descriptor));
+
+ if (encoded_string.get() == NULL) {
return false;
}
char* value;
Py_ssize_t value_len;
- if (PyBytes_AsStringAndSize(encoded_string, &value, &value_len) < 0) {
- Py_DECREF(encoded_string);
+ if (PyBytes_AsStringAndSize(encoded_string.get(), &value, &value_len) < 0) {
return false;
}
@@ -710,7 +719,6 @@ bool CheckAndSetString(
} else {
reflection->SetRepeatedString(message, descriptor, index, value_string);
}
- Py_DECREF(encoded_string);
return true;
}
@@ -746,9 +754,9 @@ namespace cmessage {
PyDescriptorPool* GetDescriptorPoolForMessage(CMessage* message) {
// No need to check the type: the type of instances of CMessage is always
- // an instance of PyMessageMeta. Let's prove it with a debug-only check.
+ // an instance of CMessageClass. Let's prove it with a debug-only check.
GOOGLE_DCHECK(PyObject_TypeCheck(message, &CMessage_Type));
- return reinterpret_cast<PyMessageMeta*>(Py_TYPE(message))->py_descriptor_pool;
+ return reinterpret_cast<CMessageClass*>(Py_TYPE(message))->py_descriptor_pool;
}
MessageFactory* GetFactoryForMessage(CMessage* message) {
@@ -823,12 +831,7 @@ struct FixupMessageReference : public ChildVisitor {
return 0;
}
- int VisitScalarMapContainer(ScalarMapContainer* container) {
- container->message = message_;
- return 0;
- }
-
- int VisitMessageMapContainer(MessageMapContainer* container) {
+ int VisitMapContainer(MapContainer* container) {
container->message = message_;
return 0;
}
@@ -870,9 +873,8 @@ int AssureWritable(CMessage* self) {
// When a CMessage is made writable its Message pointer is updated
// to point to a new mutable Message. When that happens we need to
// update any references to the old, read-only CMessage. There are
- // five places such references occur: RepeatedScalarContainer,
- // RepeatedCompositeContainer, ScalarMapContainer, MessageMapContainer,
- // and ExtensionDict.
+ // four places such references occur: RepeatedScalarContainer,
+ // RepeatedCompositeContainer, MapContainer, and ExtensionDict.
if (self->extensions != NULL)
self->extensions->message = self->message;
if (ForEachCompositeField(self, FixupMessageReference(self->message)) == -1)
@@ -1039,7 +1041,12 @@ int InternalDeleteRepeatedField(
}
// Initializes fields of a message. Used in constructors.
-int InitAttributes(CMessage* self, PyObject* kwargs) {
+int InitAttributes(CMessage* self, PyObject* args, PyObject* kwargs) {
+ if (args != NULL && PyTuple_Size(args) != 0) {
+ PyErr_SetString(PyExc_TypeError, "No positional arguments allowed");
+ return -1;
+ }
+
if (kwargs == NULL) {
return 0;
}
@@ -1054,10 +1061,15 @@ int InitAttributes(CMessage* self, PyObject* kwargs) {
}
const FieldDescriptor* descriptor = GetFieldDescriptor(self, name);
if (descriptor == NULL) {
- PyErr_Format(PyExc_ValueError, "Protocol message has no \"%s\" field.",
+ PyErr_Format(PyExc_ValueError, "Protocol message %s has no \"%s\" field.",
+ self->message->GetDescriptor()->name().c_str(),
PyString_AsString(name));
return -1;
}
+ if (value == Py_None) {
+ // field=None is the same as no field at all.
+ continue;
+ }
if (descriptor->is_map()) {
ScopedPyObjectPtr map(GetAttr(self, name));
const FieldDescriptor* value_descriptor =
@@ -1160,7 +1172,7 @@ int InitAttributes(CMessage* self, PyObject* kwargs) {
}
CMessage* cmessage = reinterpret_cast<CMessage*>(message.get());
if (PyDict_Check(value)) {
- if (InitAttributes(cmessage, value) < 0) {
+ if (InitAttributes(cmessage, NULL, value) < 0) {
return -1;
}
} else {
@@ -1188,9 +1200,9 @@ int InitAttributes(CMessage* self, PyObject* kwargs) {
// Allocates an incomplete Python Message: the caller must fill self->message,
// self->owner and eventually self->parent.
-CMessage* NewEmptyMessage(PyObject* type, const Descriptor *descriptor) {
+CMessage* NewEmptyMessage(CMessageClass* type) {
CMessage* self = reinterpret_cast<CMessage*>(
- PyType_GenericAlloc(reinterpret_cast<PyTypeObject*>(type), 0));
+ PyType_GenericAlloc(&type->super.ht_type, 0));
if (self == NULL) {
return NULL;
}
@@ -1203,18 +1215,6 @@ CMessage* NewEmptyMessage(PyObject* type, const Descriptor *descriptor) {
self->composite_fields = NULL;
- // If there are extension_ranges, the message is "extendable". Allocate a
- // dictionary to store the extension fields.
- if (descriptor->extension_range_count() > 0) {
- // TODO(amauryfa): Delay the construction of this dict until extensions are
- // really used on the object.
- ExtensionDict* extension_dict = extension_dict::NewExtensionDict(self);
- if (extension_dict == NULL) {
- return NULL;
- }
- self->extensions = extension_dict;
- }
-
return self;
}
@@ -1222,7 +1222,7 @@ CMessage* NewEmptyMessage(PyObject* type, const Descriptor *descriptor) {
// Creates a new C++ message and takes ownership.
static PyObject* New(PyTypeObject* cls,
PyObject* unused_args, PyObject* unused_kwargs) {
- PyMessageMeta* type = CheckMessageClass(cls);
+ CMessageClass* type = CheckMessageClass(cls);
if (type == NULL) {
return NULL;
}
@@ -1238,8 +1238,7 @@ static PyObject* New(PyTypeObject* cls,
return NULL;
}
- CMessage* self = NewEmptyMessage(reinterpret_cast<PyObject*>(type),
- message_descriptor);
+ CMessage* self = NewEmptyMessage(type);
if (self == NULL) {
return NULL;
}
@@ -1251,12 +1250,7 @@ static PyObject* New(PyTypeObject* cls,
// The __init__ method of Message classes.
// It initializes fields from keywords passed to the constructor.
static int Init(CMessage* self, PyObject* args, PyObject* kwargs) {
- if (PyTuple_Size(args) != 0) {
- PyErr_SetString(PyExc_TypeError, "No positional arguments allowed");
- return -1;
- }
-
- return InitAttributes(self, kwargs);
+ return InitAttributes(self, args, kwargs);
}
// ---------------------------------------------------------------------
@@ -1285,12 +1279,7 @@ struct ClearWeakReferences : public ChildVisitor {
return 0;
}
- int VisitScalarMapContainer(ScalarMapContainer* container) {
- container->parent = NULL;
- return 0;
- }
-
- int VisitMessageMapContainer(MessageMapContainer* container) {
+ int VisitMapContainer(MapContainer* container) {
container->parent = NULL;
return 0;
}
@@ -1305,6 +1294,9 @@ struct ClearWeakReferences : public ChildVisitor {
static void Dealloc(CMessage* self) {
// Null out all weak references from children to this message.
GOOGLE_CHECK_EQ(0, ForEachCompositeField(self, ClearWeakReferences()));
+ if (self->extensions) {
+ self->extensions->parent = NULL;
+ }
Py_CLEAR(self->extensions);
Py_CLEAR(self->composite_fields);
@@ -1466,20 +1458,27 @@ PyObject* HasField(CMessage* self, PyObject* arg) {
Py_RETURN_FALSE;
}
-PyObject* ClearExtension(CMessage* self, PyObject* arg) {
+PyObject* ClearExtension(CMessage* self, PyObject* extension) {
if (self->extensions != NULL) {
- return extension_dict::ClearExtension(self->extensions, arg);
+ return extension_dict::ClearExtension(self->extensions, extension);
+ } else {
+ const FieldDescriptor* descriptor = GetExtensionDescriptor(extension);
+ if (descriptor == NULL) {
+ return NULL;
+ }
+ if (ScopedPyObjectPtr(ClearFieldByDescriptor(self, descriptor)) == NULL) {
+ return NULL;
+ }
}
- PyErr_SetString(PyExc_TypeError, "Message is not extendable");
- return NULL;
+ Py_RETURN_NONE;
}
-PyObject* HasExtension(CMessage* self, PyObject* arg) {
- if (self->extensions != NULL) {
- return extension_dict::HasExtension(self->extensions, arg);
+PyObject* HasExtension(CMessage* self, PyObject* extension) {
+ const FieldDescriptor* descriptor = GetExtensionDescriptor(extension);
+ if (descriptor == NULL) {
+ return NULL;
}
- PyErr_SetString(PyExc_TypeError, "Message is not extendable");
- return NULL;
+ return HasFieldByDescriptor(self, descriptor);
}
// ---------------------------------------------------------------------
@@ -1529,13 +1528,8 @@ struct SetOwnerVisitor : public ChildVisitor {
return 0;
}
- int VisitScalarMapContainer(ScalarMapContainer* container) {
- scalar_map_container::SetOwner(container, new_owner_);
- return 0;
- }
-
- int VisitMessageMapContainer(MessageMapContainer* container) {
- message_map_container::SetOwner(container, new_owner_);
+ int VisitMapContainer(MapContainer* container) {
+ container->SetOwner(new_owner_);
return 0;
}
@@ -1599,29 +1593,20 @@ struct ReleaseChild : public ChildVisitor {
parent_(parent) {}
int VisitRepeatedCompositeContainer(RepeatedCompositeContainer* container) {
- return repeated_composite_container::Release(
- reinterpret_cast<RepeatedCompositeContainer*>(container));
+ return repeated_composite_container::Release(container);
}
int VisitRepeatedScalarContainer(RepeatedScalarContainer* container) {
- return repeated_scalar_container::Release(
- reinterpret_cast<RepeatedScalarContainer*>(container));
- }
-
- int VisitScalarMapContainer(ScalarMapContainer* container) {
- return scalar_map_container::Release(
- reinterpret_cast<ScalarMapContainer*>(container));
+ return repeated_scalar_container::Release(container);
}
- int VisitMessageMapContainer(MessageMapContainer* container) {
- return message_map_container::Release(
- reinterpret_cast<MessageMapContainer*>(container));
+ int VisitMapContainer(MapContainer* container) {
+ return container->Release();
}
int VisitCMessage(CMessage* cmessage,
const FieldDescriptor* field_descriptor) {
- return ReleaseSubMessage(parent_, field_descriptor,
- reinterpret_cast<CMessage*>(cmessage));
+ return ReleaseSubMessage(parent_, field_descriptor, cmessage);
}
CMessage* parent_;
@@ -1707,17 +1692,7 @@ PyObject* Clear(CMessage* self) {
AssureWritable(self);
if (ForEachCompositeField(self, ReleaseChild(self)) == -1)
return NULL;
-
- // The old ExtensionDict still aliases this CMessage, but all its
- // fields have been released.
- if (self->extensions != NULL) {
- Py_CLEAR(self->extensions);
- ExtensionDict* extension_dict = extension_dict::NewExtensionDict(self);
- if (extension_dict == NULL) {
- return NULL;
- }
- self->extensions = extension_dict;
- }
+ Py_CLEAR(self->extensions);
if (self->composite_fields) {
PyDict_Clear(self->composite_fields);
}
@@ -1847,8 +1822,12 @@ static PyObject* ToStr(CMessage* self) {
PyObject* MergeFrom(CMessage* self, PyObject* arg) {
CMessage* other_message;
- if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg), &CMessage_Type)) {
- PyErr_SetString(PyExc_TypeError, "Must be a message");
+ if (!PyObject_TypeCheck(arg, &CMessage_Type)) {
+ PyErr_Format(PyExc_TypeError,
+ "Parameter to MergeFrom() must be instance of same class: "
+ "expected %s got %s.",
+ self->message->GetDescriptor()->full_name().c_str(),
+ Py_TYPE(arg)->tp_name);
return NULL;
}
@@ -1856,8 +1835,8 @@ PyObject* MergeFrom(CMessage* self, PyObject* arg) {
if (other_message->message->GetDescriptor() !=
self->message->GetDescriptor()) {
PyErr_Format(PyExc_TypeError,
- "Tried to merge from a message with a different type. "
- "to: %s, from: %s",
+ "Parameter to MergeFrom() must be instance of same class: "
+ "expected %s got %s.",
self->message->GetDescriptor()->full_name().c_str(),
other_message->message->GetDescriptor()->full_name().c_str());
return NULL;
@@ -1875,8 +1854,12 @@ PyObject* MergeFrom(CMessage* self, PyObject* arg) {
static PyObject* CopyFrom(CMessage* self, PyObject* arg) {
CMessage* other_message;
- if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg), &CMessage_Type)) {
- PyErr_SetString(PyExc_TypeError, "Must be a message");
+ if (!PyObject_TypeCheck(arg, &CMessage_Type)) {
+ PyErr_Format(PyExc_TypeError,
+ "Parameter to CopyFrom() must be instance of same class: "
+ "expected %s got %s.",
+ self->message->GetDescriptor()->full_name().c_str(),
+ Py_TYPE(arg)->tp_name);
return NULL;
}
@@ -1889,8 +1872,8 @@ static PyObject* CopyFrom(CMessage* self, PyObject* arg) {
if (other_message->message->GetDescriptor() !=
self->message->GetDescriptor()) {
PyErr_Format(PyExc_TypeError,
- "Tried to copy from a message with a different type. "
- "to: %s, from: %s",
+ "Parameter to CopyFrom() must be instance of same class: "
+ "expected %s got %s.",
self->message->GetDescriptor()->full_name().c_str(),
other_message->message->GetDescriptor()->full_name().c_str());
return NULL;
@@ -1907,6 +1890,30 @@ static PyObject* CopyFrom(CMessage* self, PyObject* arg) {
Py_RETURN_NONE;
}
+// Protobuf has a 64MB limit built in, this variable will override this. Please
+// do not enable this unless you fully understand the implications: protobufs
+// must all be kept in memory at the same time, so if they grow too big you may
+// get OOM errors. The protobuf APIs do not provide any tools for processing
+// protobufs in chunks. If you have protos this big you should break them up if
+// it is at all convenient to do so.
+static bool allow_oversize_protos = false;
+
+// Provide a method in the module to set allow_oversize_protos to a boolean
+// value. This method returns the newly value of allow_oversize_protos.
+PyObject* SetAllowOversizeProtos(PyObject* m, PyObject* arg) {
+ if (!arg || !PyBool_Check(arg)) {
+ PyErr_SetString(PyExc_TypeError,
+ "Argument to SetAllowOversizeProtos must be boolean");
+ return NULL;
+ }
+ allow_oversize_protos = PyObject_IsTrue(arg);
+ if (allow_oversize_protos) {
+ Py_RETURN_TRUE;
+ } else {
+ Py_RETURN_FALSE;
+ }
+}
+
static PyObject* MergeFromString(CMessage* self, PyObject* arg) {
const void* data;
Py_ssize_t data_length;
@@ -1917,6 +1924,9 @@ static PyObject* MergeFromString(CMessage* self, PyObject* arg) {
AssureWritable(self);
io::CodedInputStream input(
reinterpret_cast<const uint8*>(data), data_length);
+ if (allow_oversize_protos) {
+ input.SetTotalBytesLimit(INT_MAX, INT_MAX);
+ }
PyDescriptorPool* pool = GetDescriptorPoolForMessage(self);
input.SetExtensionRegistry(pool->pool, pool->message_factory);
bool success = self->message->MergePartialFromCodedStream(&input);
@@ -1984,10 +1994,34 @@ static PyObject* RegisterExtension(PyObject* cls,
PyErr_SetString(PyExc_TypeError, "no extensions_by_number on class");
return NULL;
}
+
ScopedPyObjectPtr number(PyObject_GetAttrString(extension_handle, "number"));
if (number == NULL) {
return NULL;
}
+
+ // If the extension was already registered by number, check that it is the
+ // same.
+ existing_extension = PyDict_GetItem(extensions_by_number.get(), number.get());
+ if (existing_extension != NULL) {
+ const FieldDescriptor* existing_extension_descriptor =
+ GetExtensionDescriptor(existing_extension);
+ if (existing_extension_descriptor != descriptor) {
+ const Descriptor* msg_desc = GetMessageDescriptor(
+ reinterpret_cast<PyTypeObject*>(cls));
+ PyErr_Format(
+ PyExc_ValueError,
+ "Extensions \"%s\" and \"%s\" both try to extend message type "
+ "\"%s\" with field number %ld.",
+ existing_extension_descriptor->full_name().c_str(),
+ descriptor->full_name().c_str(),
+ msg_desc->full_name().c_str(),
+ PyInt_AsLong(number.get()));
+ return NULL;
+ }
+ // Nothing else to do.
+ Py_RETURN_NONE;
+ }
if (PyDict_SetItem(extensions_by_number.get(), number.get(),
extension_handle) < 0) {
return NULL;
@@ -1997,7 +2031,6 @@ static PyObject* RegisterExtension(PyObject* cls,
if (descriptor->is_extension() &&
descriptor->containing_type()->options().message_set_wire_format() &&
descriptor->type() == FieldDescriptor::TYPE_MESSAGE &&
- descriptor->message_type() == descriptor->extension_scope() &&
descriptor->label() == FieldDescriptor::LABEL_OPTIONAL) {
ScopedPyObjectPtr message_name(PyString_FromStringAndSize(
descriptor->message_type()->full_name().c_str(),
@@ -2042,6 +2075,8 @@ static PyObject* WhichOneof(CMessage* self, PyObject* arg) {
}
}
+static PyObject* GetExtensionDict(CMessage* self, void *closure);
+
static PyObject* ListFields(CMessage* self) {
vector<const FieldDescriptor*> fields;
self->message->GetReflection()->ListFields(*self->message, &fields);
@@ -2079,12 +2114,13 @@ static PyObject* ListFields(CMessage* self) {
PyErr_Clear();
continue;
}
- PyObject* extensions = reinterpret_cast<PyObject*>(self->extensions);
+ ScopedPyObjectPtr extensions(GetExtensionDict(self, NULL));
if (extensions == NULL) {
return NULL;
}
// 'extension' reference later stolen by PyTuple_SET_ITEM.
- PyObject* extension = PyObject_GetItem(extensions, extension_field.get());
+ PyObject* extension = PyObject_GetItem(
+ extensions.get(), extension_field.get());
if (extension == NULL) {
return NULL;
}
@@ -2117,10 +2153,20 @@ static PyObject* ListFields(CMessage* self) {
PyList_SET_ITEM(all_fields.get(), actual_size, t.release());
++actual_size;
}
- Py_SIZE(all_fields.get()) = actual_size;
+ if (static_cast<size_t>(actual_size) != fields.size() &&
+ (PyList_SetSlice(all_fields.get(), actual_size, fields.size(), NULL) <
+ 0)) {
+ return NULL;
+ }
return all_fields.release();
}
+static PyObject* DiscardUnknownFields(CMessage* self) {
+ AssureWritable(self);
+ self->message->DiscardUnknownFields();
+ Py_RETURN_NONE;
+}
+
PyObject* FindInitializationErrors(CMessage* self) {
Message* message = self->message;
vector<string> errors;
@@ -2264,14 +2310,13 @@ PyObject* InternalGetSubMessage(
const Message& sub_message = reflection->GetMessage(
*self->message, field_descriptor, pool->message_factory);
- PyObject *message_class = cdescriptor_pool::GetMessageClass(
+ CMessageClass* message_class = cdescriptor_pool::GetMessageClass(
pool, field_descriptor->message_type());
if (message_class == NULL) {
return NULL;
}
- CMessage* cmsg = cmessage::NewEmptyMessage(message_class,
- sub_message.GetDescriptor());
+ CMessage* cmsg = cmessage::NewEmptyMessage(message_class);
if (cmsg == NULL) {
return NULL;
}
@@ -2493,9 +2538,31 @@ PyObject* _CheckCalledFromGeneratedFile(PyObject* unused,
Py_RETURN_NONE;
}
-static PyMemberDef Members[] = {
- {"Extensions", T_OBJECT_EX, offsetof(CMessage, extensions), 0,
- "Extension dict"},
+static PyObject* GetExtensionDict(CMessage* self, void *closure) {
+ if (self->extensions) {
+ Py_INCREF(self->extensions);
+ return reinterpret_cast<PyObject*>(self->extensions);
+ }
+
+ // If there are extension_ranges, the message is "extendable". Allocate a
+ // dictionary to store the extension fields.
+ const Descriptor* descriptor = GetMessageDescriptor(Py_TYPE(self));
+ if (descriptor->extension_range_count() > 0) {
+ ExtensionDict* extension_dict = extension_dict::NewExtensionDict(self);
+ if (extension_dict == NULL) {
+ return NULL;
+ }
+ self->extensions = extension_dict;
+ Py_INCREF(self->extensions);
+ return reinterpret_cast<PyObject*>(self->extensions);
+ }
+
+ PyErr_SetNone(PyExc_AttributeError);
+ return NULL;
+}
+
+static PyGetSetDef Getters[] = {
+ {"Extensions", (getter)GetExtensionDict, NULL, "Extension dict"},
{NULL}
};
@@ -2518,6 +2585,8 @@ static PyMethodDef Methods[] = {
"Clears a message field." },
{ "CopyFrom", (PyCFunction)CopyFrom, METH_O,
"Copies a protocol message into the current message." },
+ { "DiscardUnknownFields", (PyCFunction)DiscardUnknownFields, METH_NOARGS,
+ "Discards the unknown fields." },
{ "FindInitializationErrors", (PyCFunction)FindInitializationErrors,
METH_NOARGS,
"Finds unset required fields." },
@@ -2587,15 +2656,15 @@ PyObject* GetAttr(CMessage* self, PyObject* name) {
const Descriptor* entry_type = field_descriptor->message_type();
const FieldDescriptor* value_type = entry_type->FindFieldByName("value");
if (value_type->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
- PyObject* value_class = cdescriptor_pool::GetMessageClass(
+ CMessageClass* value_class = cdescriptor_pool::GetMessageClass(
GetDescriptorPoolForMessage(self), value_type->message_type());
if (value_class == NULL) {
return NULL;
}
- py_container = message_map_container::NewContainer(self, field_descriptor,
- value_class);
+ py_container =
+ NewMessageMapContainer(self, field_descriptor, value_class);
} else {
- py_container = scalar_map_container::NewContainer(self, field_descriptor);
+ py_container = NewScalarMapContainer(self, field_descriptor);
}
if (py_container == NULL) {
return NULL;
@@ -2610,7 +2679,7 @@ PyObject* GetAttr(CMessage* self, PyObject* name) {
if (field_descriptor->label() == FieldDescriptor::LABEL_REPEATED) {
PyObject* py_container = NULL;
if (field_descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
- PyObject *message_class = cdescriptor_pool::GetMessageClass(
+ CMessageClass* message_class = cdescriptor_pool::GetMessageClass(
GetDescriptorPoolForMessage(self), field_descriptor->message_type());
if (message_class == NULL) {
return NULL;
@@ -2672,14 +2741,17 @@ int SetAttr(CMessage* self, PyObject* name, PyObject* value) {
}
}
- PyErr_Format(PyExc_AttributeError, "Assignment not allowed");
+ PyErr_Format(PyExc_AttributeError,
+ "Assignment not allowed "
+ "(no field \"%s\" in protocol message object).",
+ PyString_AsString(name));
return -1;
}
} // namespace cmessage
PyTypeObject CMessage_Type = {
- PyVarObject_HEAD_INIT(&PyMessageMeta_Type, 0)
+ PyVarObject_HEAD_INIT(&CMessageClass_Type, 0)
FULL_MODULE_NAME ".CMessage", // tp_name
sizeof(CMessage), // tp_basicsize
0, // tp_itemsize
@@ -2688,7 +2760,7 @@ PyTypeObject CMessage_Type = {
0, // tp_getattr
0, // tp_setattr
0, // tp_compare
- 0, // tp_repr
+ (reprfunc)cmessage::ToStr, // tp_repr
0, // tp_as_number
0, // tp_as_sequence
0, // tp_as_mapping
@@ -2707,8 +2779,8 @@ PyTypeObject CMessage_Type = {
0, // tp_iter
0, // tp_iternext
cmessage::Methods, // tp_methods
- cmessage::Members, // tp_members
- 0, // tp_getset
+ 0, // tp_members
+ cmessage::Getters, // tp_getset
0, // tp_base
0, // tp_dict
0, // tp_descr_get
@@ -2794,12 +2866,12 @@ bool InitProto2MessageModule(PyObject *m) {
// Initialize constants defined in this file.
InitGlobals();
- PyMessageMeta_Type.tp_base = &PyType_Type;
- if (PyType_Ready(&PyMessageMeta_Type) < 0) {
+ CMessageClass_Type.tp_base = &PyType_Type;
+ if (PyType_Ready(&CMessageClass_Type) < 0) {
return false;
}
PyModule_AddObject(m, "MessageMeta",
- reinterpret_cast<PyObject*>(&PyMessageMeta_Type));
+ reinterpret_cast<PyObject*>(&CMessageClass_Type));
if (PyType_Ready(&CMessage_Type) < 0) {
return false;
@@ -2910,12 +2982,12 @@ bool InitProto2MessageModule(PyObject *m) {
reinterpret_cast<PyObject*>(&ScalarMapContainer_Type));
#endif
- if (PyType_Ready(&ScalarMapIterator_Type) < 0) {
+ if (PyType_Ready(&MapIterator_Type) < 0) {
return false;
}
- PyModule_AddObject(m, "ScalarMapIterator",
- reinterpret_cast<PyObject*>(&ScalarMapIterator_Type));
+ PyModule_AddObject(m, "MapIterator",
+ reinterpret_cast<PyObject*>(&MapIterator_Type));
#if PY_MAJOR_VERSION >= 3
@@ -2934,13 +3006,6 @@ bool InitProto2MessageModule(PyObject *m) {
PyModule_AddObject(m, "MessageMapContainer",
reinterpret_cast<PyObject*>(&MessageMapContainer_Type));
#endif
-
- if (PyType_Ready(&MessageMapIterator_Type) < 0) {
- return false;
- }
-
- PyModule_AddObject(m, "MessageMapIterator",
- reinterpret_cast<PyObject*>(&MessageMapIterator_Type));
}
if (PyType_Ready(&ExtensionDict_Type) < 0) {
@@ -2957,6 +3022,9 @@ bool InitProto2MessageModule(PyObject *m) {
PyModule_AddObject(m, "default_pool",
reinterpret_cast<PyObject*>(GetDefaultDescriptorPool()));
+ PyModule_AddObject(m, "DescriptorPool", reinterpret_cast<PyObject*>(
+ &PyDescriptorPool_Type));
+
// This implementation provides full Descriptor types, we advertise it so that
// descriptor.py can use them in replacement of the Python classes.
PyModule_AddIntConstant(m, "_USE_C_DESCRIPTORS", 1);
@@ -2973,6 +3041,10 @@ bool InitProto2MessageModule(PyObject *m) {
&PyFileDescriptor_Type));
PyModule_AddObject(m, "OneofDescriptor", reinterpret_cast<PyObject*>(
&PyOneofDescriptor_Type));
+ PyModule_AddObject(m, "ServiceDescriptor", reinterpret_cast<PyObject*>(
+ &PyServiceDescriptor_Type));
+ PyModule_AddObject(m, "MethodDescriptor", reinterpret_cast<PyObject*>(
+ &PyMethodDescriptor_Type));
PyObject* enum_type_wrapper = PyImport_ImportModule(
"google.protobuf.internal.enum_type_wrapper");
@@ -3010,46 +3082,4 @@ bool InitProto2MessageModule(PyObject *m) {
} // namespace python
} // namespace protobuf
-
-#if PY_MAJOR_VERSION >= 3
-static struct PyModuleDef _module = {
- PyModuleDef_HEAD_INIT,
- "_message",
- google::protobuf::python::module_docstring,
- -1,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL
-};
-#define INITFUNC PyInit__message
-#define INITFUNC_ERRORVAL NULL
-#else // Python 2
-#define INITFUNC init_message
-#define INITFUNC_ERRORVAL
-#endif
-
-extern "C" {
- PyMODINIT_FUNC INITFUNC(void) {
- PyObject* m;
-#if PY_MAJOR_VERSION >= 3
- m = PyModule_Create(&_module);
-#else
- m = Py_InitModule3("_message", NULL, google::protobuf::python::module_docstring);
-#endif
- if (m == NULL) {
- return INITFUNC_ERRORVAL;
- }
-
- if (!google::protobuf::python::InitProto2MessageModule(m)) {
- Py_DECREF(m);
- return INITFUNC_ERRORVAL;
- }
-
-#if PY_MAJOR_VERSION >= 3
- return m;
-#endif
- }
-}
} // namespace google
diff --git a/python/google/protobuf/pyext/message.h b/python/google/protobuf/pyext/message.h
index 94de4551..c44a2ae2 100644
--- a/python/google/protobuf/pyext/message.h
+++ b/python/google/protobuf/pyext/message.h
@@ -116,12 +116,43 @@ typedef struct CMessage {
extern PyTypeObject CMessage_Type;
+
+// The (meta) type of all Messages classes.
+// It allows us to cache some C++ pointers in the class object itself, they are
+// faster to extract than from the type's dictionary.
+
+struct CMessageClass {
+ // This is how CPython subclasses C structures: the base structure must be
+ // the first member of the object.
+ PyHeapTypeObject super;
+
+ // C++ descriptor of this message.
+ const Descriptor* message_descriptor;
+
+ // Owned reference, used to keep the pointer above alive.
+ PyObject* py_message_descriptor;
+
+ // The Python DescriptorPool used to create the class. It is needed to resolve
+ // fields descriptors, including extensions fields; its C++ MessageFactory is
+ // used to instantiate submessages.
+ // This can be different from DESCRIPTOR.file.pool, in the case of a custom
+ // DescriptorPool which defines new extensions.
+ // We own the reference, because it's important to keep the descriptors and
+ // factory alive.
+ PyDescriptorPool* py_descriptor_pool;
+
+ PyObject* AsPyObject() {
+ return reinterpret_cast<PyObject*>(this);
+ }
+};
+
+
namespace cmessage {
// Internal function to create a new empty Message Python object, but with empty
// pointers to the C++ objects.
// The caller must fill self->message, self->owner and eventually self->parent.
-CMessage* NewEmptyMessage(PyObject* type, const Descriptor* descriptor);
+CMessage* NewEmptyMessage(CMessageClass* type);
// Release a submessage from its proto tree, making it a new top-level messgae.
// A new message will be created if this is a read-only default instance.
@@ -206,7 +237,9 @@ PyObject* HasFieldByDescriptor(
PyObject* HasField(CMessage* self, PyObject* arg);
// Initializes values of fields on a newly constructed message.
-int InitAttributes(CMessage* self, PyObject* kwargs);
+// Note that positional arguments are disallowed: 'args' must be NULL or the
+// empty tuple.
+int InitAttributes(CMessage* self, PyObject* args, PyObject* kwargs);
PyObject* MergeFrom(CMessage* self, PyObject* arg);
@@ -238,6 +271,8 @@ int AssureWritable(CMessage* self);
// even in the case of extensions.
PyDescriptorPool* GetDescriptorPoolForMessage(CMessage* message);
+PyObject* SetAllowOversizeProtos(PyObject* m, PyObject* arg);
+
} // namespace cmessage
@@ -307,6 +342,7 @@ bool CheckAndGetInteger(
bool CheckAndGetDouble(PyObject* arg, double* value);
bool CheckAndGetFloat(PyObject* arg, float* value);
bool CheckAndGetBool(PyObject* arg, bool* value);
+PyObject* CheckString(PyObject* arg, const FieldDescriptor* descriptor);
bool CheckAndSetString(
PyObject* arg, Message* message,
const FieldDescriptor* descriptor,
@@ -322,6 +358,8 @@ bool CheckFieldBelongsToMessage(const FieldDescriptor* field_descriptor,
extern PyObject* PickleError_class;
+bool InitProto2MessageModule(PyObject *m);
+
} // namespace python
} // namespace protobuf
diff --git a/python/google/protobuf/pyext/message_map_container.cc b/python/google/protobuf/pyext/message_map_container.cc
deleted file mode 100644
index 8902fa00..00000000
--- a/python/google/protobuf/pyext/message_map_container.cc
+++ /dev/null
@@ -1,569 +0,0 @@
-// 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.
-
-// Author: haberman@google.com (Josh Haberman)
-
-#include <google/protobuf/pyext/message_map_container.h>
-
-#include <google/protobuf/stubs/logging.h>
-#include <google/protobuf/stubs/common.h>
-#include <google/protobuf/message.h>
-#include <google/protobuf/pyext/message.h>
-#include <google/protobuf/pyext/scoped_pyobject_ptr.h>
-
-namespace google {
-namespace protobuf {
-namespace python {
-
-struct MessageMapIterator {
- PyObject_HEAD;
-
- // This dict contains the full contents of what we want to iterate over.
- // There's no way to avoid building this, because the list representation
- // (which is canonical) can contain duplicate keys. So at the very least we
- // need a set that lets us skip duplicate keys. And at the point that we're
- // doing that, we might as well just build the actual dict we're iterating
- // over and use dict's built-in iterator.
- PyObject* dict;
-
- // An iterator on dict.
- PyObject* iter;
-
- // A pointer back to the container, so we can notice changes to the version.
- MessageMapContainer* container;
-
- // The version of the map when we took the iterator to it.
- //
- // We store this so that if the map is modified during iteration we can throw
- // an error.
- uint64 version;
-};
-
-static MessageMapIterator* GetIter(PyObject* obj) {
- return reinterpret_cast<MessageMapIterator*>(obj);
-}
-
-namespace message_map_container {
-
-static MessageMapContainer* GetMap(PyObject* obj) {
- return reinterpret_cast<MessageMapContainer*>(obj);
-}
-
-// The private constructor of MessageMapContainer objects.
-PyObject* NewContainer(CMessage* parent,
- const google::protobuf::FieldDescriptor* parent_field_descriptor,
- PyObject* concrete_class) {
- if (!CheckFieldBelongsToMessage(parent_field_descriptor, parent->message)) {
- return NULL;
- }
-
-#if PY_MAJOR_VERSION >= 3
- PyObject* obj = PyType_GenericAlloc(
- reinterpret_cast<PyTypeObject *>(MessageMapContainer_Type), 0);
-#else
- PyObject* obj = PyType_GenericAlloc(&MessageMapContainer_Type, 0);
-#endif
- if (obj == NULL) {
- return PyErr_Format(PyExc_RuntimeError,
- "Could not allocate new container.");
- }
-
- MessageMapContainer* self = GetMap(obj);
-
- self->message = parent->message;
- self->parent = parent;
- self->parent_field_descriptor = parent_field_descriptor;
- self->owner = parent->owner;
- self->version = 0;
-
- self->key_field_descriptor =
- parent_field_descriptor->message_type()->FindFieldByName("key");
- self->value_field_descriptor =
- parent_field_descriptor->message_type()->FindFieldByName("value");
-
- self->message_dict = PyDict_New();
- if (self->message_dict == NULL) {
- return PyErr_Format(PyExc_RuntimeError,
- "Could not allocate message dict.");
- }
-
- Py_INCREF(concrete_class);
- self->subclass_init = concrete_class;
-
- if (self->key_field_descriptor == NULL ||
- self->value_field_descriptor == NULL) {
- Py_DECREF(obj);
- return PyErr_Format(PyExc_KeyError,
- "Map entry descriptor did not have key/value fields");
- }
-
- return obj;
-}
-
-// Initializes the underlying Message object of "to" so it becomes a new parent
-// repeated scalar, and copies all the values from "from" to it. A child scalar
-// container can be released by passing it as both from and to (e.g. making it
-// the recipient of the new parent message and copying the values from itself).
-static int InitializeAndCopyToParentContainer(
- MessageMapContainer* from,
- MessageMapContainer* to) {
- // For now we require from == to, re-evaluate if we want to support deep copy
- // as in repeated_composite_container.cc.
- GOOGLE_DCHECK(from == to);
- Message* old_message = from->message;
- Message* new_message = old_message->New();
- to->parent = NULL;
- to->parent_field_descriptor = from->parent_field_descriptor;
- to->message = new_message;
- to->owner.reset(new_message);
-
- vector<const FieldDescriptor*> fields;
- fields.push_back(from->parent_field_descriptor);
- old_message->GetReflection()->SwapFields(old_message, new_message, fields);
- return 0;
-}
-
-static PyObject* GetCMessage(MessageMapContainer* self, Message* entry) {
- // Get or create the CMessage object corresponding to this message.
- Message* message = entry->GetReflection()->MutableMessage(
- entry, self->value_field_descriptor);
- ScopedPyObjectPtr key(PyLong_FromVoidPtr(message));
- PyObject* ret = PyDict_GetItem(self->message_dict, key.get());
-
- if (ret == NULL) {
- CMessage* cmsg = cmessage::NewEmptyMessage(self->subclass_init,
- message->GetDescriptor());
- ret = reinterpret_cast<PyObject*>(cmsg);
-
- if (cmsg == NULL) {
- return NULL;
- }
- cmsg->owner = self->owner;
- cmsg->message = message;
- cmsg->parent = self->parent;
-
- if (PyDict_SetItem(self->message_dict, key.get(), ret) < 0) {
- Py_DECREF(ret);
- return NULL;
- }
- } else {
- Py_INCREF(ret);
- }
-
- return ret;
-}
-
-int Release(MessageMapContainer* self) {
- InitializeAndCopyToParentContainer(self, self);
- return 0;
-}
-
-void SetOwner(MessageMapContainer* self,
- const shared_ptr<Message>& new_owner) {
- self->owner = new_owner;
-}
-
-Py_ssize_t Length(PyObject* _self) {
- MessageMapContainer* self = GetMap(_self);
- google::protobuf::Message* message = self->message;
- return message->GetReflection()->FieldSize(*message,
- self->parent_field_descriptor);
-}
-
-int MapKeyMatches(MessageMapContainer* self, const Message* entry,
- PyObject* key) {
- // TODO(haberman): do we need more strict type checking?
- ScopedPyObjectPtr entry_key(
- cmessage::InternalGetScalar(entry, self->key_field_descriptor));
- int ret = PyObject_RichCompareBool(key, entry_key.get(), Py_EQ);
- return ret;
-}
-
-int SetItem(PyObject *_self, PyObject *key, PyObject *v) {
- if (v) {
- PyErr_Format(PyExc_ValueError,
- "Direct assignment of submessage not allowed");
- return -1;
- }
-
- // Now we know that this is a delete, not a set.
-
- MessageMapContainer* self = GetMap(_self);
- cmessage::AssureWritable(self->parent);
-
- Message* message = self->message;
- const Reflection* reflection = message->GetReflection();
- size_t size =
- reflection->FieldSize(*message, self->parent_field_descriptor);
-
- // Right now the Reflection API doesn't support map lookup, so we implement it
- // via linear search. We need to search from the end because the underlying
- // representation can have duplicates if a user calls MergeFrom(); the last
- // one needs to win.
- //
- // TODO(haberman): add lookup API to Reflection API.
- bool found = false;
- for (int i = size - 1; i >= 0; i--) {
- Message* entry = reflection->MutableRepeatedMessage(
- message, self->parent_field_descriptor, i);
- int matches = MapKeyMatches(self, entry, key);
- if (matches < 0) return -1;
- if (matches) {
- found = true;
- if (i != (int)size - 1) {
- reflection->SwapElements(message, self->parent_field_descriptor, i,
- size - 1);
- }
- reflection->RemoveLast(message, self->parent_field_descriptor);
-
- // Can't exit now, the repeated field representation of maps allows
- // duplicate keys, and we have to be sure to remove all of them.
- }
- }
-
- if (!found) {
- PyErr_Format(PyExc_KeyError, "Key not present in map");
- return -1;
- }
-
- self->version++;
-
- return 0;
-}
-
-PyObject* GetIterator(PyObject *_self) {
- MessageMapContainer* self = GetMap(_self);
-
- ScopedPyObjectPtr obj(PyType_GenericAlloc(&MessageMapIterator_Type, 0));
- if (obj == NULL) {
- return PyErr_Format(PyExc_KeyError, "Could not allocate iterator");
- }
-
- MessageMapIterator* iter = GetIter(obj.get());
-
- Py_INCREF(self);
- iter->container = self;
- iter->version = self->version;
- iter->dict = PyDict_New();
- if (iter->dict == NULL) {
- return PyErr_Format(PyExc_RuntimeError,
- "Could not allocate dict for iterator.");
- }
-
- // Build the entire map into a dict right now. Start from the beginning so
- // that later entries win in the case of duplicates.
- Message* message = self->message;
- const Reflection* reflection = message->GetReflection();
-
- // Right now the Reflection API doesn't support map lookup, so we implement it
- // via linear search. We need to search from the end because the underlying
- // representation can have duplicates if a user calls MergeFrom(); the last
- // one needs to win.
- //
- // TODO(haberman): add lookup API to Reflection API.
- size_t size =
- reflection->FieldSize(*message, self->parent_field_descriptor);
- for (int i = size - 1; i >= 0; i--) {
- Message* entry = reflection->MutableRepeatedMessage(
- message, self->parent_field_descriptor, i);
- ScopedPyObjectPtr key(
- cmessage::InternalGetScalar(entry, self->key_field_descriptor));
- if (PyDict_SetItem(iter->dict, key.get(), GetCMessage(self, entry)) < 0) {
- return PyErr_Format(PyExc_RuntimeError,
- "SetItem failed in iterator construction.");
- }
- }
-
- iter->iter = PyObject_GetIter(iter->dict);
-
- return obj.release();
-}
-
-PyObject* GetItem(PyObject* _self, PyObject* key) {
- MessageMapContainer* self = GetMap(_self);
- cmessage::AssureWritable(self->parent);
- Message* message = self->message;
- const Reflection* reflection = message->GetReflection();
-
- // Right now the Reflection API doesn't support map lookup, so we implement it
- // via linear search. We need to search from the end because the underlying
- // representation can have duplicates if a user calls MergeFrom(); the last
- // one needs to win.
- //
- // TODO(haberman): add lookup API to Reflection API.
- size_t size =
- reflection->FieldSize(*message, self->parent_field_descriptor);
- for (int i = size - 1; i >= 0; i--) {
- Message* entry = reflection->MutableRepeatedMessage(
- message, self->parent_field_descriptor, i);
- int matches = MapKeyMatches(self, entry, key);
- if (matches < 0) return NULL;
- if (matches) {
- return GetCMessage(self, entry);
- }
- }
-
- // Key is not already present; insert a new entry.
- Message* entry =
- reflection->AddMessage(message, self->parent_field_descriptor);
-
- self->version++;
-
- if (cmessage::InternalSetNonOneofScalar(entry, self->key_field_descriptor,
- key) < 0) {
- reflection->RemoveLast(message, self->parent_field_descriptor);
- return NULL;
- }
-
- return GetCMessage(self, entry);
-}
-
-PyObject* Contains(PyObject* _self, PyObject* key) {
- MessageMapContainer* self = GetMap(_self);
- Message* message = self->message;
- const Reflection* reflection = message->GetReflection();
-
- // Right now the Reflection API doesn't support map lookup, so we implement it
- // via linear search.
- //
- // TODO(haberman): add lookup API to Reflection API.
- int size =
- reflection->FieldSize(*message, self->parent_field_descriptor);
- for (int i = 0; i < size; i++) {
- Message* entry = reflection->MutableRepeatedMessage(
- message, self->parent_field_descriptor, i);
- int matches = MapKeyMatches(self, entry, key);
- if (matches < 0) return NULL;
- if (matches) {
- Py_RETURN_TRUE;
- }
- }
-
- Py_RETURN_FALSE;
-}
-
-PyObject* Clear(PyObject* _self) {
- MessageMapContainer* self = GetMap(_self);
- cmessage::AssureWritable(self->parent);
- Message* message = self->message;
- const Reflection* reflection = message->GetReflection();
-
- self->version++;
- reflection->ClearField(message, self->parent_field_descriptor);
-
- Py_RETURN_NONE;
-}
-
-PyObject* Get(PyObject* self, PyObject* args) {
- PyObject* key;
- PyObject* default_value = NULL;
- if (PyArg_ParseTuple(args, "O|O", &key, &default_value) < 0) {
- return NULL;
- }
-
- ScopedPyObjectPtr is_present(Contains(self, key));
- if (is_present.get() == NULL) {
- return NULL;
- }
-
- if (PyObject_IsTrue(is_present.get())) {
- return GetItem(self, key);
- } else {
- if (default_value != NULL) {
- Py_INCREF(default_value);
- return default_value;
- } else {
- Py_RETURN_NONE;
- }
- }
-}
-
-static void Dealloc(PyObject* _self) {
- MessageMapContainer* self = GetMap(_self);
- self->owner.reset();
- Py_DECREF(self->message_dict);
- Py_TYPE(_self)->tp_free(_self);
-}
-
-static PyMethodDef Methods[] = {
- { "__contains__", (PyCFunction)Contains, METH_O,
- "Tests whether the map contains this element."},
- { "clear", (PyCFunction)Clear, METH_NOARGS,
- "Removes all elements from the map."},
- { "get", Get, METH_VARARGS,
- "Gets the value for the given key if present, or otherwise a default" },
- { "get_or_create", GetItem, METH_O,
- "Alias for getitem, useful to make explicit that the map is mutated." },
- /*
- { "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS,
- "Makes a deep copy of the class." },
- { "__reduce__", (PyCFunction)Reduce, METH_NOARGS,
- "Outputs picklable representation of the repeated field." },
- */
- {NULL, NULL},
-};
-
-} // namespace message_map_container
-
-namespace message_map_iterator {
-
-static void Dealloc(PyObject* _self) {
- MessageMapIterator* self = GetIter(_self);
- Py_DECREF(self->dict);
- Py_DECREF(self->iter);
- Py_DECREF(self->container);
- Py_TYPE(_self)->tp_free(_self);
-}
-
-PyObject* IterNext(PyObject* _self) {
- MessageMapIterator* self = GetIter(_self);
-
- // This won't catch mutations to the map performed by MergeFrom(); no easy way
- // to address that.
- if (self->version != self->container->version) {
- return PyErr_Format(PyExc_RuntimeError,
- "Map modified during iteration.");
- }
-
- return PyIter_Next(self->iter);
-}
-
-} // namespace message_map_iterator
-
-#if PY_MAJOR_VERSION >= 3
- static PyType_Slot MessageMapContainer_Type_slots[] = {
- {Py_tp_dealloc, (void *)message_map_container::Dealloc},
- {Py_mp_length, (void *)message_map_container::Length},
- {Py_mp_subscript, (void *)message_map_container::GetItem},
- {Py_mp_ass_subscript, (void *)message_map_container::SetItem},
- {Py_tp_methods, (void *)message_map_container::Methods},
- {Py_tp_iter, (void *)message_map_container::GetIterator},
- {0, 0}
- };
-
- PyType_Spec MessageMapContainer_Type_spec = {
- FULL_MODULE_NAME ".MessageMapContainer",
- sizeof(MessageMapContainer),
- 0,
- Py_TPFLAGS_DEFAULT,
- MessageMapContainer_Type_slots
- };
-
- PyObject *MessageMapContainer_Type;
-
-#else
- static PyMappingMethods MpMethods = {
- message_map_container::Length, // mp_length
- message_map_container::GetItem, // mp_subscript
- message_map_container::SetItem, // mp_ass_subscript
- };
-
- PyTypeObject MessageMapContainer_Type = {
- PyVarObject_HEAD_INIT(&PyType_Type, 0)
- FULL_MODULE_NAME ".MessageMapContainer", // tp_name
- sizeof(MessageMapContainer), // tp_basicsize
- 0, // tp_itemsize
- message_map_container::Dealloc, // tp_dealloc
- 0, // tp_print
- 0, // tp_getattr
- 0, // tp_setattr
- 0, // tp_compare
- 0, // tp_repr
- 0, // tp_as_number
- 0, // tp_as_sequence
- &MpMethods, // tp_as_mapping
- 0, // tp_hash
- 0, // tp_call
- 0, // tp_str
- 0, // tp_getattro
- 0, // tp_setattro
- 0, // tp_as_buffer
- Py_TPFLAGS_DEFAULT, // tp_flags
- "A map container for message", // tp_doc
- 0, // tp_traverse
- 0, // tp_clear
- 0, // tp_richcompare
- 0, // tp_weaklistoffset
- message_map_container::GetIterator, // tp_iter
- 0, // tp_iternext
- message_map_container::Methods, // tp_methods
- 0, // tp_members
- 0, // tp_getset
- 0, // tp_base
- 0, // tp_dict
- 0, // tp_descr_get
- 0, // tp_descr_set
- 0, // tp_dictoffset
- 0, // tp_init
- };
-#endif
-
-PyTypeObject MessageMapIterator_Type = {
- PyVarObject_HEAD_INIT(&PyType_Type, 0)
- FULL_MODULE_NAME ".MessageMapIterator", // tp_name
- sizeof(MessageMapIterator), // tp_basicsize
- 0, // tp_itemsize
- message_map_iterator::Dealloc, // tp_dealloc
- 0, // tp_print
- 0, // tp_getattr
- 0, // tp_setattr
- 0, // tp_compare
- 0, // tp_repr
- 0, // tp_as_number
- 0, // tp_as_sequence
- 0, // tp_as_mapping
- 0, // tp_hash
- 0, // tp_call
- 0, // tp_str
- 0, // tp_getattro
- 0, // tp_setattro
- 0, // tp_as_buffer
- Py_TPFLAGS_DEFAULT, // tp_flags
- "A scalar map iterator", // tp_doc
- 0, // tp_traverse
- 0, // tp_clear
- 0, // tp_richcompare
- 0, // tp_weaklistoffset
- PyObject_SelfIter, // tp_iter
- message_map_iterator::IterNext, // tp_iternext
- 0, // tp_methods
- 0, // tp_members
- 0, // tp_getset
- 0, // tp_base
- 0, // tp_dict
- 0, // tp_descr_get
- 0, // tp_descr_set
- 0, // tp_dictoffset
- 0, // tp_init
-};
-
-} // namespace python
-} // namespace protobuf
-} // namespace google
diff --git a/python/google/protobuf/pyext/message_module.cc b/python/google/protobuf/pyext/message_module.cc
new file mode 100644
index 00000000..d90d9de3
--- /dev/null
+++ b/python/google/protobuf/pyext/message_module.cc
@@ -0,0 +1,88 @@
+// 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 <google/protobuf/pyext/message.h>
+
+static const char module_docstring[] =
+"python-proto2 is a module that can be used to enhance proto2 Python API\n"
+"performance.\n"
+"\n"
+"It provides access to the protocol buffers C++ reflection API that\n"
+"implements the basic protocol buffer functions.";
+
+static PyMethodDef ModuleMethods[] = {
+ {"SetAllowOversizeProtos",
+ (PyCFunction)google::protobuf::python::cmessage::SetAllowOversizeProtos,
+ METH_O, "Enable/disable oversize proto parsing."},
+ { NULL, NULL}
+};
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef _module = {
+ PyModuleDef_HEAD_INIT,
+ "_message",
+ module_docstring,
+ -1,
+ ModuleMethods, /* m_methods */
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+#define INITFUNC PyInit__message
+#define INITFUNC_ERRORVAL NULL
+#else // Python 2
+#define INITFUNC init_message
+#define INITFUNC_ERRORVAL
+#endif
+
+extern "C" {
+ PyMODINIT_FUNC INITFUNC(void) {
+ PyObject* m;
+#if PY_MAJOR_VERSION >= 3
+ m = PyModule_Create(&_module);
+#else
+ m = Py_InitModule3("_message", ModuleMethods,
+ module_docstring);
+#endif
+ if (m == NULL) {
+ return INITFUNC_ERRORVAL;
+ }
+
+ if (!google::protobuf::python::InitProto2MessageModule(m)) {
+ Py_DECREF(m);
+ return INITFUNC_ERRORVAL;
+ }
+
+#if PY_MAJOR_VERSION >= 3
+ return m;
+#endif
+ }
+}
diff --git a/python/google/protobuf/pyext/repeated_composite_container.cc b/python/google/protobuf/pyext/repeated_composite_container.cc
index b01123b4..bb2f6db2 100644
--- a/python/google/protobuf/pyext/repeated_composite_container.cc
+++ b/python/google/protobuf/pyext/repeated_composite_container.cc
@@ -107,8 +107,7 @@ static int UpdateChildMessages(RepeatedCompositeContainer* self) {
for (Py_ssize_t i = child_length; i < message_length; ++i) {
const Message& sub_message = reflection->GetRepeatedMessage(
*(self->message), self->parent_field_descriptor, i);
- CMessage* cmsg = cmessage::NewEmptyMessage(self->subclass_init,
- sub_message.GetDescriptor());
+ CMessage* cmsg = cmessage::NewEmptyMessage(self->child_message_class);
ScopedPyObjectPtr py_cmsg(reinterpret_cast<PyObject*>(cmsg));
if (cmsg == NULL) {
return -1;
@@ -140,15 +139,14 @@ static PyObject* AddToAttached(RepeatedCompositeContainer* self,
Message* sub_message =
message->GetReflection()->AddMessage(message,
self->parent_field_descriptor);
- CMessage* cmsg = cmessage::NewEmptyMessage(self->subclass_init,
- sub_message->GetDescriptor());
+ CMessage* cmsg = cmessage::NewEmptyMessage(self->child_message_class);
if (cmsg == NULL)
return NULL;
cmsg->owner = self->owner;
cmsg->message = sub_message;
cmsg->parent = self->parent;
- if (cmessage::InitAttributes(cmsg, kwargs) < 0) {
+ if (cmessage::InitAttributes(cmsg, args, kwargs) < 0) {
Py_DECREF(cmsg);
return NULL;
}
@@ -168,7 +166,7 @@ static PyObject* AddToReleased(RepeatedCompositeContainer* self,
// Create a new Message detached from the rest.
PyObject* py_cmsg = PyEval_CallObjectWithKeywords(
- self->subclass_init, NULL, kwargs);
+ self->child_message_class->AsPyObject(), args, kwargs);
if (py_cmsg == NULL)
return NULL;
@@ -506,7 +504,7 @@ int SetOwner(RepeatedCompositeContainer* self,
PyObject *NewContainer(
CMessage* parent,
const FieldDescriptor* parent_field_descriptor,
- PyObject *concrete_class) {
+ CMessageClass* concrete_class) {
if (!CheckFieldBelongsToMessage(parent_field_descriptor, parent->message)) {
return NULL;
}
@@ -523,7 +521,7 @@ PyObject *NewContainer(
self->parent_field_descriptor = parent_field_descriptor;
self->owner = parent->owner;
Py_INCREF(concrete_class);
- self->subclass_init = concrete_class;
+ self->child_message_class = concrete_class;
self->child_messages = PyList_New(0);
return reinterpret_cast<PyObject*>(self);
@@ -531,7 +529,7 @@ PyObject *NewContainer(
static void Dealloc(RepeatedCompositeContainer* self) {
Py_CLEAR(self->child_messages);
- Py_CLEAR(self->subclass_init);
+ Py_CLEAR(self->child_message_class);
// TODO(tibell): Do we need to call delete on these objects to make
// sure their destructors are called?
self->owner.reset();
diff --git a/python/google/protobuf/pyext/repeated_composite_container.h b/python/google/protobuf/pyext/repeated_composite_container.h
index 58d37b02..a7b56b61 100644
--- a/python/google/protobuf/pyext/repeated_composite_container.h
+++ b/python/google/protobuf/pyext/repeated_composite_container.h
@@ -58,6 +58,7 @@ using internal::shared_ptr;
namespace python {
struct CMessage;
+struct CMessageClass;
// A RepeatedCompositeContainer can be in one of two states: attached
// or released.
@@ -94,8 +95,8 @@ typedef struct RepeatedCompositeContainer {
// calling Clear() or ClearField() on the parent.
Message* message;
- // A callable that is used to create new child messages.
- PyObject* subclass_init;
+ // The type used to create new child messages.
+ CMessageClass* child_message_class;
// A list of child messages.
PyObject* child_messages;
@@ -110,7 +111,7 @@ namespace repeated_composite_container {
PyObject *NewContainer(
CMessage* parent,
const FieldDescriptor* parent_field_descriptor,
- PyObject *concrete_class);
+ CMessageClass *child_message_class);
// Appends a new CMessage to the container and returns it. The
// CMessage is initialized using the content of kwargs.
diff --git a/python/google/protobuf/pyext/scalar_map_container.cc b/python/google/protobuf/pyext/scalar_map_container.cc
deleted file mode 100644
index 0b0d5a3d..00000000
--- a/python/google/protobuf/pyext/scalar_map_container.cc
+++ /dev/null
@@ -1,542 +0,0 @@
-// 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.
-
-// Author: haberman@google.com (Josh Haberman)
-
-#include <google/protobuf/pyext/scalar_map_container.h>
-
-#include <google/protobuf/stubs/logging.h>
-#include <google/protobuf/stubs/common.h>
-#include <google/protobuf/message.h>
-#include <google/protobuf/pyext/message.h>
-#include <google/protobuf/pyext/scoped_pyobject_ptr.h>
-
-namespace google {
-namespace protobuf {
-namespace python {
-
-struct ScalarMapIterator {
- PyObject_HEAD;
-
- // This dict contains the full contents of what we want to iterate over.
- // There's no way to avoid building this, because the list representation
- // (which is canonical) can contain duplicate keys. So at the very least we
- // need a set that lets us skip duplicate keys. And at the point that we're
- // doing that, we might as well just build the actual dict we're iterating
- // over and use dict's built-in iterator.
- PyObject* dict;
-
- // An iterator on dict.
- PyObject* iter;
-
- // A pointer back to the container, so we can notice changes to the version.
- ScalarMapContainer* container;
-
- // The version of the map when we took the iterator to it.
- //
- // We store this so that if the map is modified during iteration we can throw
- // an error.
- uint64 version;
-};
-
-static ScalarMapIterator* GetIter(PyObject* obj) {
- return reinterpret_cast<ScalarMapIterator*>(obj);
-}
-
-namespace scalar_map_container {
-
-static ScalarMapContainer* GetMap(PyObject* obj) {
- return reinterpret_cast<ScalarMapContainer*>(obj);
-}
-
-// The private constructor of ScalarMapContainer objects.
-PyObject *NewContainer(
- CMessage* parent, const google::protobuf::FieldDescriptor* parent_field_descriptor) {
- if (!CheckFieldBelongsToMessage(parent_field_descriptor, parent->message)) {
- return NULL;
- }
-
-#if PY_MAJOR_VERSION >= 3
- ScopedPyObjectPtr obj(PyType_GenericAlloc(
- reinterpret_cast<PyTypeObject *>(ScalarMapContainer_Type), 0));
-#else
- ScopedPyObjectPtr obj(PyType_GenericAlloc(&ScalarMapContainer_Type, 0));
-#endif
- if (obj.get() == NULL) {
- return PyErr_Format(PyExc_RuntimeError,
- "Could not allocate new container.");
- }
-
- ScalarMapContainer* self = GetMap(obj.get());
-
- self->message = parent->message;
- self->parent = parent;
- self->parent_field_descriptor = parent_field_descriptor;
- self->owner = parent->owner;
- self->version = 0;
-
- self->key_field_descriptor =
- parent_field_descriptor->message_type()->FindFieldByName("key");
- self->value_field_descriptor =
- parent_field_descriptor->message_type()->FindFieldByName("value");
-
- if (self->key_field_descriptor == NULL ||
- self->value_field_descriptor == NULL) {
- return PyErr_Format(PyExc_KeyError,
- "Map entry descriptor did not have key/value fields");
- }
-
- return obj.release();
-}
-
-// Initializes the underlying Message object of "to" so it becomes a new parent
-// repeated scalar, and copies all the values from "from" to it. A child scalar
-// container can be released by passing it as both from and to (e.g. making it
-// the recipient of the new parent message and copying the values from itself).
-static int InitializeAndCopyToParentContainer(
- ScalarMapContainer* from,
- ScalarMapContainer* to) {
- // For now we require from == to, re-evaluate if we want to support deep copy
- // as in repeated_scalar_container.cc.
- GOOGLE_DCHECK(from == to);
- Message* old_message = from->message;
- Message* new_message = old_message->New();
- to->parent = NULL;
- to->parent_field_descriptor = from->parent_field_descriptor;
- to->message = new_message;
- to->owner.reset(new_message);
-
- vector<const FieldDescriptor*> fields;
- fields.push_back(from->parent_field_descriptor);
- old_message->GetReflection()->SwapFields(old_message, new_message, fields);
- return 0;
-}
-
-int Release(ScalarMapContainer* self) {
- return InitializeAndCopyToParentContainer(self, self);
-}
-
-void SetOwner(ScalarMapContainer* self,
- const shared_ptr<Message>& new_owner) {
- self->owner = new_owner;
-}
-
-Py_ssize_t Length(PyObject* _self) {
- ScalarMapContainer* self = GetMap(_self);
- google::protobuf::Message* message = self->message;
- return message->GetReflection()->FieldSize(*message,
- self->parent_field_descriptor);
-}
-
-int MapKeyMatches(ScalarMapContainer* self, const Message* entry,
- PyObject* key) {
- // TODO(haberman): do we need more strict type checking?
- ScopedPyObjectPtr entry_key(
- cmessage::InternalGetScalar(entry, self->key_field_descriptor));
- int ret = PyObject_RichCompareBool(key, entry_key.get(), Py_EQ);
- return ret;
-}
-
-PyObject* GetItem(PyObject* _self, PyObject* key) {
- ScalarMapContainer* self = GetMap(_self);
-
- Message* message = self->message;
- const Reflection* reflection = message->GetReflection();
-
- // Right now the Reflection API doesn't support map lookup, so we implement it
- // via linear search.
- //
- // TODO(haberman): add lookup API to Reflection API.
- size_t size = reflection->FieldSize(*message, self->parent_field_descriptor);
- for (int i = size - 1; i >= 0; i--) {
- const Message& entry = reflection->GetRepeatedMessage(
- *message, self->parent_field_descriptor, i);
- int matches = MapKeyMatches(self, &entry, key);
- if (matches < 0) return NULL;
- if (matches) {
- return cmessage::InternalGetScalar(&entry, self->value_field_descriptor);
- }
- }
-
- // Need to add a new entry.
- Message* entry =
- reflection->AddMessage(message, self->parent_field_descriptor);
- PyObject* ret = NULL;
-
- if (cmessage::InternalSetNonOneofScalar(entry, self->key_field_descriptor,
- key) >= 0) {
- ret = cmessage::InternalGetScalar(entry, self->value_field_descriptor);
- }
-
- self->version++;
-
- // If there was a type error above, it set the Python exception.
- return ret;
-}
-
-int SetItem(PyObject *_self, PyObject *key, PyObject *v) {
- ScalarMapContainer* self = GetMap(_self);
- cmessage::AssureWritable(self->parent);
-
- Message* message = self->message;
- const Reflection* reflection = message->GetReflection();
- size_t size =
- reflection->FieldSize(*message, self->parent_field_descriptor);
- self->version++;
-
- if (v) {
- // Set item.
- //
- // Right now the Reflection API doesn't support map lookup, so we implement
- // it via linear search.
- //
- // TODO(haberman): add lookup API to Reflection API.
- for (int i = size - 1; i >= 0; i--) {
- Message* entry = reflection->MutableRepeatedMessage(
- message, self->parent_field_descriptor, i);
- int matches = MapKeyMatches(self, entry, key);
- if (matches < 0) return -1;
- if (matches) {
- return cmessage::InternalSetNonOneofScalar(
- entry, self->value_field_descriptor, v);
- }
- }
-
- // Key is not already present; insert a new entry.
- Message* entry =
- reflection->AddMessage(message, self->parent_field_descriptor);
-
- if (cmessage::InternalSetNonOneofScalar(entry, self->key_field_descriptor,
- key) < 0 ||
- cmessage::InternalSetNonOneofScalar(entry, self->value_field_descriptor,
- v) < 0) {
- reflection->RemoveLast(message, self->parent_field_descriptor);
- return -1;
- }
-
- return 0;
- } else {
- bool found = false;
- for (int i = size - 1; i >= 0; i--) {
- Message* entry = reflection->MutableRepeatedMessage(
- message, self->parent_field_descriptor, i);
- int matches = MapKeyMatches(self, entry, key);
- if (matches < 0) return -1;
- if (matches) {
- found = true;
- if (i != (int)size - 1) {
- reflection->SwapElements(message, self->parent_field_descriptor, i,
- size - 1);
- }
- reflection->RemoveLast(message, self->parent_field_descriptor);
-
- // Can't exit now, the repeated field representation of maps allows
- // duplicate keys, and we have to be sure to remove all of them.
- }
- }
-
- if (found) {
- return 0;
- } else {
- PyErr_Format(PyExc_KeyError, "Key not present in map");
- return -1;
- }
- }
-}
-
-PyObject* GetIterator(PyObject *_self) {
- ScalarMapContainer* self = GetMap(_self);
-
- ScopedPyObjectPtr obj(PyType_GenericAlloc(&ScalarMapIterator_Type, 0));
- if (obj == NULL) {
- return PyErr_Format(PyExc_KeyError, "Could not allocate iterator");
- }
-
- ScalarMapIterator* iter = GetIter(obj.get());
-
- Py_INCREF(self);
- iter->container = self;
- iter->version = self->version;
- iter->dict = PyDict_New();
- if (iter->dict == NULL) {
- return PyErr_Format(PyExc_RuntimeError,
- "Could not allocate dict for iterator.");
- }
-
- // Build the entire map into a dict right now. Start from the beginning so
- // that later entries win in the case of duplicates.
- Message* message = self->message;
- const Reflection* reflection = message->GetReflection();
-
- // Right now the Reflection API doesn't support map lookup, so we implement it
- // via linear search. We need to search from the end because the underlying
- // representation can have duplicates if a user calls MergeFrom(); the last
- // one needs to win.
- //
- // TODO(haberman): add lookup API to Reflection API.
- size_t size =
- reflection->FieldSize(*message, self->parent_field_descriptor);
- for (size_t i = 0; i < size; i++) {
- Message* entry = reflection->MutableRepeatedMessage(
- message, self->parent_field_descriptor, i);
- ScopedPyObjectPtr key(
- cmessage::InternalGetScalar(entry, self->key_field_descriptor));
- ScopedPyObjectPtr val(
- cmessage::InternalGetScalar(entry, self->value_field_descriptor));
- if (PyDict_SetItem(iter->dict, key.get(), val.get()) < 0) {
- return PyErr_Format(PyExc_RuntimeError,
- "SetItem failed in iterator construction.");
- }
- }
-
-
- iter->iter = PyObject_GetIter(iter->dict);
-
-
- return obj.release();
-}
-
-PyObject* Clear(PyObject* _self) {
- ScalarMapContainer* self = GetMap(_self);
- cmessage::AssureWritable(self->parent);
- Message* message = self->message;
- const Reflection* reflection = message->GetReflection();
-
- reflection->ClearField(message, self->parent_field_descriptor);
-
- Py_RETURN_NONE;
-}
-
-PyObject* Contains(PyObject* _self, PyObject* key) {
- ScalarMapContainer* self = GetMap(_self);
-
- Message* message = self->message;
- const Reflection* reflection = message->GetReflection();
-
- // Right now the Reflection API doesn't support map lookup, so we implement it
- // via linear search.
- //
- // TODO(haberman): add lookup API to Reflection API.
- size_t size = reflection->FieldSize(*message, self->parent_field_descriptor);
- for (int i = size - 1; i >= 0; i--) {
- const Message& entry = reflection->GetRepeatedMessage(
- *message, self->parent_field_descriptor, i);
- int matches = MapKeyMatches(self, &entry, key);
- if (matches < 0) return NULL;
- if (matches) {
- Py_RETURN_TRUE;
- }
- }
-
- Py_RETURN_FALSE;
-}
-
-PyObject* Get(PyObject* self, PyObject* args) {
- PyObject* key;
- PyObject* default_value = NULL;
- if (PyArg_ParseTuple(args, "O|O", &key, &default_value) < 0) {
- return NULL;
- }
-
- ScopedPyObjectPtr is_present(Contains(self, key));
- if (is_present.get() == NULL) {
- return NULL;
- }
-
- if (PyObject_IsTrue(is_present.get())) {
- return GetItem(self, key);
- } else {
- if (default_value != NULL) {
- Py_INCREF(default_value);
- return default_value;
- } else {
- Py_RETURN_NONE;
- }
- }
-}
-
-static void Dealloc(PyObject* _self) {
- ScalarMapContainer* self = GetMap(_self);
- self->owner.reset();
- Py_TYPE(_self)->tp_free(_self);
-}
-
-static PyMethodDef Methods[] = {
- { "__contains__", Contains, METH_O,
- "Tests whether a key is a member of the map." },
- { "clear", (PyCFunction)Clear, METH_NOARGS,
- "Removes all elements from the map." },
- { "get", Get, METH_VARARGS,
- "Gets the value for the given key if present, or otherwise a default" },
- /*
- { "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS,
- "Makes a deep copy of the class." },
- { "__reduce__", (PyCFunction)Reduce, METH_NOARGS,
- "Outputs picklable representation of the repeated field." },
- */
- {NULL, NULL},
-};
-
-} // namespace scalar_map_container
-
-namespace scalar_map_iterator {
-
-static void Dealloc(PyObject* _self) {
- ScalarMapIterator* self = GetIter(_self);
- Py_DECREF(self->dict);
- Py_DECREF(self->iter);
- Py_DECREF(self->container);
- Py_TYPE(_self)->tp_free(_self);
-}
-
-PyObject* IterNext(PyObject* _self) {
- ScalarMapIterator* self = GetIter(_self);
-
- // This won't catch mutations to the map performed by MergeFrom(); no easy way
- // to address that.
- if (self->version != self->container->version) {
- return PyErr_Format(PyExc_RuntimeError,
- "Map modified during iteration.");
- }
-
- return PyIter_Next(self->iter);
-}
-
-} // namespace scalar_map_iterator
-
-
-#if PY_MAJOR_VERSION >= 3
- static PyType_Slot ScalarMapContainer_Type_slots[] = {
- {Py_tp_dealloc, (void *)scalar_map_container::Dealloc},
- {Py_mp_length, (void *)scalar_map_container::Length},
- {Py_mp_subscript, (void *)scalar_map_container::GetItem},
- {Py_mp_ass_subscript, (void *)scalar_map_container::SetItem},
- {Py_tp_methods, (void *)scalar_map_container::Methods},
- {Py_tp_iter, (void *)scalar_map_container::GetIterator},
- {0, 0},
- };
-
- PyType_Spec ScalarMapContainer_Type_spec = {
- FULL_MODULE_NAME ".ScalarMapContainer",
- sizeof(ScalarMapContainer),
- 0,
- Py_TPFLAGS_DEFAULT,
- ScalarMapContainer_Type_slots
- };
- PyObject *ScalarMapContainer_Type;
-#else
- static PyMappingMethods MpMethods = {
- scalar_map_container::Length, // mp_length
- scalar_map_container::GetItem, // mp_subscript
- scalar_map_container::SetItem, // mp_ass_subscript
- };
-
- PyTypeObject ScalarMapContainer_Type = {
- PyVarObject_HEAD_INIT(&PyType_Type, 0)
- FULL_MODULE_NAME ".ScalarMapContainer", // tp_name
- sizeof(ScalarMapContainer), // tp_basicsize
- 0, // tp_itemsize
- scalar_map_container::Dealloc, // tp_dealloc
- 0, // tp_print
- 0, // tp_getattr
- 0, // tp_setattr
- 0, // tp_compare
- 0, // tp_repr
- 0, // tp_as_number
- 0, // tp_as_sequence
- &MpMethods, // tp_as_mapping
- 0, // tp_hash
- 0, // tp_call
- 0, // tp_str
- 0, // tp_getattro
- 0, // tp_setattro
- 0, // tp_as_buffer
- Py_TPFLAGS_DEFAULT, // tp_flags
- "A scalar map container", // tp_doc
- 0, // tp_traverse
- 0, // tp_clear
- 0, // tp_richcompare
- 0, // tp_weaklistoffset
- scalar_map_container::GetIterator, // tp_iter
- 0, // tp_iternext
- scalar_map_container::Methods, // tp_methods
- 0, // tp_members
- 0, // tp_getset
- 0, // tp_base
- 0, // tp_dict
- 0, // tp_descr_get
- 0, // tp_descr_set
- 0, // tp_dictoffset
- 0, // tp_init
- };
-#endif
-
-PyTypeObject ScalarMapIterator_Type = {
- PyVarObject_HEAD_INIT(&PyType_Type, 0)
- FULL_MODULE_NAME ".ScalarMapIterator", // tp_name
- sizeof(ScalarMapIterator), // tp_basicsize
- 0, // tp_itemsize
- scalar_map_iterator::Dealloc, // tp_dealloc
- 0, // tp_print
- 0, // tp_getattr
- 0, // tp_setattr
- 0, // tp_compare
- 0, // tp_repr
- 0, // tp_as_number
- 0, // tp_as_sequence
- 0, // tp_as_mapping
- 0, // tp_hash
- 0, // tp_call
- 0, // tp_str
- 0, // tp_getattro
- 0, // tp_setattro
- 0, // tp_as_buffer
- Py_TPFLAGS_DEFAULT, // tp_flags
- "A scalar map iterator", // tp_doc
- 0, // tp_traverse
- 0, // tp_clear
- 0, // tp_richcompare
- 0, // tp_weaklistoffset
- PyObject_SelfIter, // tp_iter
- scalar_map_iterator::IterNext, // tp_iternext
- 0, // tp_methods
- 0, // tp_members
- 0, // tp_getset
- 0, // tp_base
- 0, // tp_dict
- 0, // tp_descr_get
- 0, // tp_descr_set
- 0, // tp_dictoffset
- 0, // tp_init
-};
-
-} // namespace python
-} // namespace protobuf
-} // namespace google
diff --git a/python/google/protobuf/pyext/scalar_map_container.h b/python/google/protobuf/pyext/scalar_map_container.h
deleted file mode 100644
index 4d663b88..00000000
--- a/python/google/protobuf/pyext/scalar_map_container.h
+++ /dev/null
@@ -1,119 +0,0 @@
-// 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.
-
-#ifndef GOOGLE_PROTOBUF_PYTHON_CPP_SCALAR_MAP_CONTAINER_H__
-#define GOOGLE_PROTOBUF_PYTHON_CPP_SCALAR_MAP_CONTAINER_H__
-
-#include <Python.h>
-
-#include <memory>
-#ifndef _SHARED_PTR_H
-#include <google/protobuf/stubs/shared_ptr.h>
-#endif
-
-#include <google/protobuf/descriptor.h>
-
-namespace google {
-namespace protobuf {
-
-class Message;
-
-#ifdef _SHARED_PTR_H
-using std::shared_ptr;
-#else
-using internal::shared_ptr;
-#endif
-
-namespace python {
-
-struct CMessage;
-
-struct ScalarMapContainer {
- PyObject_HEAD;
-
- // This is the top-level C++ Message object that owns the whole
- // proto tree. Every Python ScalarMapContainer holds a
- // reference to it in order to keep it alive as long as there's a
- // Python object that references any part of the tree.
- shared_ptr<Message> owner;
-
- // Pointer to the C++ Message that contains this container. The
- // ScalarMapContainer does not own this pointer.
- Message* message;
-
- // Weak reference to a parent CMessage object (i.e. may be NULL.)
- //
- // Used to make sure all ancestors are also mutable when first
- // modifying the container.
- CMessage* parent;
-
- // Pointer to the parent's descriptor that describes this
- // field. Used together with the parent's message when making a
- // default message instance mutable.
- // The pointer is owned by the global DescriptorPool.
- const FieldDescriptor* parent_field_descriptor;
- const FieldDescriptor* key_field_descriptor;
- const FieldDescriptor* value_field_descriptor;
-
- // We bump this whenever we perform a mutation, to invalidate existing
- // iterators.
- uint64 version;
-};
-
-#if PY_MAJOR_VERSION >= 3
- extern PyObject *ScalarMapContainer_Type;
- extern PyType_Spec ScalarMapContainer_Type_spec;
-#else
- extern PyTypeObject ScalarMapContainer_Type;
-#endif
-extern PyTypeObject ScalarMapIterator_Type;
-
-namespace scalar_map_container {
-
-// Builds a ScalarMapContainer object, from a parent message and a
-// field descriptor.
-extern PyObject *NewContainer(
- CMessage* parent, const FieldDescriptor* parent_field_descriptor);
-
-// Releases the messages in the container to a new message.
-//
-// Returns 0 on success, -1 on failure.
-int Release(ScalarMapContainer* self);
-
-// Set the owner field of self and any children of self.
-void SetOwner(ScalarMapContainer* self,
- const shared_ptr<Message>& new_owner);
-
-} // namespace scalar_map_container
-} // namespace python
-} // namespace protobuf
-
-} // namespace google
-#endif // GOOGLE_PROTOBUF_PYTHON_CPP_SCALAR_MAP_CONTAINER_H__
diff --git a/python/google/protobuf/reflection.py b/python/google/protobuf/reflection.py
index 0c757264..51c83321 100755
--- a/python/google/protobuf/reflection.py
+++ b/python/google/protobuf/reflection.py
@@ -58,13 +58,7 @@ else:
from google.protobuf.internal import python_message as message_impl
# The type of all Message classes.
-# Part of the public interface.
-#
-# Used by generated files, but clients can also use it at runtime:
-# mydescriptor = pool.FindDescriptor(.....)
-# class MyProtoClass(Message):
-# __metaclass__ = GeneratedProtocolMessageType
-# DESCRIPTOR = mydescriptor
+# Part of the public interface, but normally only used by message factories.
GeneratedProtocolMessageType = message_impl.GeneratedProtocolMessageType
diff --git a/python/google/protobuf/symbol_database.py b/python/google/protobuf/symbol_database.py
index b81ef4d7..aa466abd 100644
--- a/python/google/protobuf/symbol_database.py
+++ b/python/google/protobuf/symbol_database.py
@@ -30,11 +30,9 @@
"""A database of Python protocol buffer generated symbols.
-SymbolDatabase makes it easy to create new instances of a registered type, given
-only the type's protocol buffer symbol name. Once all symbols are registered,
-they can be accessed using either the MessageFactory interface which
-SymbolDatabase exposes, or the DescriptorPool interface of the underlying
-pool.
+SymbolDatabase is the MessageFactory for messages generated at compile time,
+and makes it easy to create new instances of a registered type, given only the
+type's protocol buffer symbol name.
Example usage:
@@ -60,54 +58,18 @@ Example usage:
"""
-from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool
+from google.protobuf import message_factory
-class SymbolDatabase(object):
- """A database of Python generated symbols.
-
- SymbolDatabase also models message_factory.MessageFactory.
-
- The symbol database can be used to keep a global registry of all protocol
- buffer types used within a program.
- """
-
- # pylint: disable=protected-access
- if _descriptor._USE_C_DESCRIPTORS:
-
- def __new__(cls):
- raise TypeError("Instances of SymbolDatabase cannot be created")
-
- @classmethod
- def _CreateDefaultDatabase(cls):
- self = object.__new__(cls) # Bypass the __new__ above.
- # Don't call __init__() and initialize here.
- self._symbols = {}
- self._symbols_by_file = {}
- # As of today all descriptors are registered and retrieved from
- # _message.default_pool (see FileDescriptor.__new__), so it's not
- # necessary to use another pool.
- self.pool = _descriptor._message.default_pool
- return self
- # pylint: enable=protected-access
-
- else:
-
- @classmethod
- def _CreateDefaultDatabase(cls):
- return cls()
-
- def __init__(self):
- """Constructor."""
-
- self._symbols = {}
- self._symbols_by_file = {}
- self.pool = descriptor_pool.DescriptorPool()
+class SymbolDatabase(message_factory.MessageFactory):
+ """A database of Python generated symbols."""
def RegisterMessage(self, message):
"""Registers the given message type in the local database.
+ Calls to GetSymbol() and GetMessages() will return messages registered here.
+
Args:
message: a message.Message, to be registered.
@@ -116,10 +78,7 @@ class SymbolDatabase(object):
"""
desc = message.DESCRIPTOR
- self._symbols[desc.full_name] = message
- if desc.file.name not in self._symbols_by_file:
- self._symbols_by_file[desc.file.name] = {}
- self._symbols_by_file[desc.file.name][desc.full_name] = message
+ self._classes[desc.full_name] = message
self.pool.AddDescriptor(desc)
return message
@@ -162,48 +121,47 @@ class SymbolDatabase(object):
KeyError: if the symbol could not be found.
"""
- return self._symbols[symbol]
-
- def GetPrototype(self, descriptor):
- """Builds a proto2 message class based on the passed in descriptor.
-
- Passing a descriptor with a fully qualified name matching a previous
- invocation will cause the same class to be returned.
-
- Args:
- descriptor: The descriptor to build from.
-
- Returns:
- A class describing the passed in descriptor.
- """
-
- return self.GetSymbol(descriptor.full_name)
+ return self._classes[symbol]
def GetMessages(self, files):
- """Gets all the messages from a specified file.
-
- This will find and resolve dependencies, failing if they are not registered
- in the symbol database.
+ # TODO(amauryfa): Fix the differences with MessageFactory.
+ """Gets all registered messages from a specified file.
+ Only messages already created and registered will be returned; (this is the
+ case for imported _pb2 modules)
+ But unlike MessageFactory, this version also returns nested messages.
Args:
files: The file names to extract messages from.
Returns:
- A dictionary mapping proto names to the message classes. This will include
- any dependent messages as well as any messages defined in the same file as
- a specified message.
+ A dictionary mapping proto names to the message classes.
Raises:
KeyError: if a file could not be found.
"""
+ def _GetAllMessageNames(desc):
+ """Walk a message Descriptor and recursively yields all message names."""
+ yield desc.full_name
+ for msg_desc in desc.nested_types:
+ for full_name in _GetAllMessageNames(msg_desc):
+ yield full_name
+
result = {}
- for f in files:
- result.update(self._symbols_by_file[f])
+ for file_name in files:
+ file_desc = self.pool.FindFileByName(file_name)
+ for msg_desc in file_desc.message_types_by_name.values():
+ for full_name in _GetAllMessageNames(msg_desc):
+ try:
+ result[full_name] = self._classes[full_name]
+ except KeyError:
+ # This descriptor has no registered class, skip it.
+ pass
return result
-_DEFAULT = SymbolDatabase._CreateDefaultDatabase()
+
+_DEFAULT = SymbolDatabase(pool=descriptor_pool.Default())
def Default():
diff --git a/python/google/protobuf/text_format.py b/python/google/protobuf/text_format.py
index e4fadf09..06b79d77 100755
--- a/python/google/protobuf/text_format.py
+++ b/python/google/protobuf/text_format.py
@@ -48,15 +48,15 @@ import re
import six
if six.PY3:
- long = int
+ long = int # pylint: disable=redefined-builtin,invalid-name
+# pylint: disable=g-import-not-at-top
from google.protobuf.internal import type_checkers
from google.protobuf import descriptor
from google.protobuf import text_encoding
-__all__ = ['MessageToString', 'PrintMessage', 'PrintField',
- 'PrintFieldValue', 'Merge']
-
+__all__ = ['MessageToString', 'PrintMessage', 'PrintField', 'PrintFieldValue',
+ 'Merge']
_INTEGER_CHECKERS = (type_checkers.Uint32ValueChecker(),
type_checkers.Int32ValueChecker(),
@@ -66,6 +66,8 @@ _FLOAT_INFINITY = re.compile('-?inf(?:inity)?f?', re.IGNORECASE)
_FLOAT_NAN = re.compile('nanf?', re.IGNORECASE)
_FLOAT_TYPES = frozenset([descriptor.FieldDescriptor.CPPTYPE_FLOAT,
descriptor.FieldDescriptor.CPPTYPE_DOUBLE])
+_QUOTES = frozenset(("'", '"'))
+_ANY_FULL_TYPE_NAME = 'google.protobuf.Any'
class Error(Exception):
@@ -73,9 +75,30 @@ class Error(Exception):
class ParseError(Error):
- """Thrown in case of ASCII parsing error."""
+ """Thrown in case of text parsing or tokenizing error."""
+
+ def __init__(self, message=None, line=None, column=None):
+ if message is not None and line is not None:
+ loc = str(line)
+ if column is not None:
+ loc += ':{0}'.format(column)
+ message = '{0} : {1}'.format(loc, message)
+ if message is not None:
+ super(ParseError, self).__init__(message)
+ else:
+ super(ParseError, self).__init__()
+ self._line = line
+ self._column = column
+
+ def GetLine(self):
+ return self._line
+
+ def GetColumn(self):
+ return self._column
+
class TextWriter(object):
+
def __init__(self, as_utf8):
if six.PY2:
self._writer = io.BytesIO()
@@ -95,14 +118,21 @@ class TextWriter(object):
return self._writer.getvalue()
-def MessageToString(message, as_utf8=False, as_one_line=False,
- pointy_brackets=False, use_index_order=False,
- float_format=None):
+def MessageToString(message,
+ as_utf8=False,
+ as_one_line=False,
+ pointy_brackets=False,
+ use_index_order=False,
+ float_format=None,
+ use_field_number=False,
+ descriptor_pool=None,
+ indent=0):
"""Convert protobuf message to text format.
Floating point values can be formatted compactly with 15 digits of
precision (which is the most that IEEE 754 "double" can guarantee)
- using float_format='.15g'.
+ using float_format='.15g'. To ensure that converting to text and back to a
+ proto will result in an identical value, float_format='.17g' should be used.
Args:
message: The protocol buffers message.
@@ -115,305 +145,572 @@ def MessageToString(message, as_utf8=False, as_one_line=False,
field number order.
float_format: If set, use this to specify floating point number formatting
(per the "Format Specification Mini-Language"); otherwise, str() is used.
+ use_field_number: If True, print field numbers instead of names.
+ descriptor_pool: A DescriptorPool used to resolve Any types.
+ indent: The indent level, in terms of spaces, for pretty print.
Returns:
A string of the text formatted protocol buffer message.
"""
out = TextWriter(as_utf8)
- PrintMessage(message, out, as_utf8=as_utf8, as_one_line=as_one_line,
- pointy_brackets=pointy_brackets,
- use_index_order=use_index_order,
- float_format=float_format)
+ printer = _Printer(out, indent, as_utf8, as_one_line, pointy_brackets,
+ use_index_order, float_format, use_field_number,
+ descriptor_pool)
+ printer.PrintMessage(message)
result = out.getvalue()
out.close()
if as_one_line:
return result.rstrip()
return result
+
def _IsMapEntry(field):
return (field.type == descriptor.FieldDescriptor.TYPE_MESSAGE and
field.message_type.has_options and
field.message_type.GetOptions().map_entry)
-def PrintMessage(message, out, indent=0, as_utf8=False, as_one_line=False,
- pointy_brackets=False, use_index_order=False,
- float_format=None):
- fields = message.ListFields()
- if use_index_order:
- fields.sort(key=lambda x: x[0].index)
- for field, value in fields:
- if _IsMapEntry(field):
- for key in sorted(value):
- # This is slow for maps with submessage entires because it copies the
- # entire tree. Unfortunately this would take significant refactoring
- # of this file to work around.
- #
- # TODO(haberman): refactor and optimize if this becomes an issue.
- entry_submsg = field.message_type._concrete_class(
- key=key, value=value[key])
- PrintField(field, entry_submsg, out, indent, as_utf8, as_one_line,
- pointy_brackets=pointy_brackets,
- use_index_order=use_index_order, float_format=float_format)
- elif field.label == descriptor.FieldDescriptor.LABEL_REPEATED:
- for element in value:
- PrintField(field, element, out, indent, as_utf8, as_one_line,
- pointy_brackets=pointy_brackets,
- use_index_order=use_index_order,
- float_format=float_format)
- else:
- PrintField(field, value, out, indent, as_utf8, as_one_line,
- pointy_brackets=pointy_brackets,
- use_index_order=use_index_order,
- float_format=float_format)
-
-def PrintField(field, value, out, indent=0, as_utf8=False, as_one_line=False,
- pointy_brackets=False, use_index_order=False, float_format=None):
- """Print a single field name/value pair. For repeated fields, the value
- should be a single element."""
-
- out.write(' ' * indent)
- if field.is_extension:
- out.write('[')
- if (field.containing_type.GetOptions().message_set_wire_format and
- field.type == descriptor.FieldDescriptor.TYPE_MESSAGE and
- field.message_type == field.extension_scope and
- field.label == descriptor.FieldDescriptor.LABEL_OPTIONAL):
- out.write(field.message_type.full_name)
- else:
- out.write(field.full_name)
- out.write(']')
- elif field.type == descriptor.FieldDescriptor.TYPE_GROUP:
- # For groups, use the capitalized name.
- out.write(field.message_type.name)
- else:
- out.write(field.name)
- if field.cpp_type != descriptor.FieldDescriptor.CPPTYPE_MESSAGE:
- # The colon is optional in this case, but our cross-language golden files
- # don't include it.
- out.write(': ')
+def PrintMessage(message,
+ out,
+ indent=0,
+ as_utf8=False,
+ as_one_line=False,
+ pointy_brackets=False,
+ use_index_order=False,
+ float_format=None,
+ use_field_number=False,
+ descriptor_pool=None):
+ printer = _Printer(out, indent, as_utf8, as_one_line, pointy_brackets,
+ use_index_order, float_format, use_field_number,
+ descriptor_pool)
+ printer.PrintMessage(message)
+
+
+def PrintField(field,
+ value,
+ out,
+ indent=0,
+ as_utf8=False,
+ as_one_line=False,
+ pointy_brackets=False,
+ use_index_order=False,
+ float_format=None):
+ """Print a single field name/value pair."""
+ printer = _Printer(out, indent, as_utf8, as_one_line, pointy_brackets,
+ use_index_order, float_format)
+ printer.PrintField(field, value)
+
+
+def PrintFieldValue(field,
+ value,
+ out,
+ indent=0,
+ as_utf8=False,
+ as_one_line=False,
+ pointy_brackets=False,
+ use_index_order=False,
+ float_format=None):
+ """Print a single field value (not including name)."""
+ printer = _Printer(out, indent, as_utf8, as_one_line, pointy_brackets,
+ use_index_order, float_format)
+ printer.PrintFieldValue(field, value)
- PrintFieldValue(field, value, out, indent, as_utf8, as_one_line,
- pointy_brackets=pointy_brackets,
- use_index_order=use_index_order,
- float_format=float_format)
- if as_one_line:
- out.write(' ')
- else:
- out.write('\n')
+def _BuildMessageFromTypeName(type_name, descriptor_pool):
+ """Returns a protobuf message instance.
-def PrintFieldValue(field, value, out, indent=0, as_utf8=False,
- as_one_line=False, pointy_brackets=False,
- use_index_order=False,
- float_format=None):
- """Print a single field value (not including name). For repeated fields,
- the value should be a single element."""
+ Args:
+ type_name: Fully-qualified protobuf message type name string.
+ descriptor_pool: DescriptorPool instance.
- if pointy_brackets:
- openb = '<'
- closeb = '>'
- else:
- openb = '{'
- closeb = '}'
-
- if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE:
- if as_one_line:
- out.write(' %s ' % openb)
- PrintMessage(value, out, indent, as_utf8, as_one_line,
- pointy_brackets=pointy_brackets,
- use_index_order=use_index_order,
- float_format=float_format)
- out.write(closeb)
+ Returns:
+ A Message instance of type matching type_name, or None if the a Descriptor
+ wasn't found matching type_name.
+ """
+ # pylint: disable=g-import-not-at-top
+ from google.protobuf import message_factory
+ factory = message_factory.MessageFactory(descriptor_pool)
+ try:
+ message_descriptor = descriptor_pool.FindMessageTypeByName(type_name)
+ except KeyError:
+ return None
+ message_type = factory.GetPrototype(message_descriptor)
+ return message_type()
+
+
+class _Printer(object):
+ """Text format printer for protocol message."""
+
+ def __init__(self,
+ out,
+ indent=0,
+ as_utf8=False,
+ as_one_line=False,
+ pointy_brackets=False,
+ use_index_order=False,
+ float_format=None,
+ use_field_number=False,
+ descriptor_pool=None):
+ """Initialize the Printer.
+
+ Floating point values can be formatted compactly with 15 digits of
+ precision (which is the most that IEEE 754 "double" can guarantee)
+ using float_format='.15g'. To ensure that converting to text and back to a
+ proto will result in an identical value, float_format='.17g' should be used.
+
+ Args:
+ out: To record the text format result.
+ indent: The indent level for pretty print.
+ as_utf8: Produce text output in UTF8 format.
+ as_one_line: Don't introduce newlines between fields.
+ pointy_brackets: If True, use angle brackets instead of curly braces for
+ nesting.
+ use_index_order: If True, print fields of a proto message using the order
+ defined in source code instead of the field number. By default, use the
+ field number order.
+ float_format: If set, use this to specify floating point number formatting
+ (per the "Format Specification Mini-Language"); otherwise, str() is
+ used.
+ use_field_number: If True, print field numbers instead of names.
+ descriptor_pool: A DescriptorPool used to resolve Any types.
+ """
+ self.out = out
+ self.indent = indent
+ self.as_utf8 = as_utf8
+ self.as_one_line = as_one_line
+ self.pointy_brackets = pointy_brackets
+ self.use_index_order = use_index_order
+ self.float_format = float_format
+ self.use_field_number = use_field_number
+ self.descriptor_pool = descriptor_pool
+
+ def _TryPrintAsAnyMessage(self, message):
+ """Serializes if message is a google.protobuf.Any field."""
+ packed_message = _BuildMessageFromTypeName(message.TypeName(),
+ self.descriptor_pool)
+ if packed_message:
+ packed_message.MergeFromString(message.value)
+ self.out.write('%s[%s]' % (self.indent * ' ', message.type_url))
+ self._PrintMessageFieldValue(packed_message)
+ self.out.write(' ' if self.as_one_line else '\n')
+ return True
+ else:
+ return False
+
+ def PrintMessage(self, message):
+ """Convert protobuf message to text format.
+
+ Args:
+ message: The protocol buffers message.
+ """
+ if (message.DESCRIPTOR.full_name == _ANY_FULL_TYPE_NAME and
+ self.descriptor_pool and self._TryPrintAsAnyMessage(message)):
+ return
+ fields = message.ListFields()
+ if self.use_index_order:
+ fields.sort(key=lambda x: x[0].index)
+ for field, value in fields:
+ if _IsMapEntry(field):
+ for key in sorted(value):
+ # This is slow for maps with submessage entires because it copies the
+ # entire tree. Unfortunately this would take significant refactoring
+ # of this file to work around.
+ #
+ # TODO(haberman): refactor and optimize if this becomes an issue.
+ entry_submsg = field.message_type._concrete_class(key=key,
+ value=value[key])
+ self.PrintField(field, entry_submsg)
+ elif field.label == descriptor.FieldDescriptor.LABEL_REPEATED:
+ for element in value:
+ self.PrintField(field, element)
+ else:
+ self.PrintField(field, value)
+
+ def PrintField(self, field, value):
+ """Print a single field name/value pair."""
+ out = self.out
+ out.write(' ' * self.indent)
+ if self.use_field_number:
+ out.write(str(field.number))
else:
- out.write(' %s\n' % openb)
- PrintMessage(value, out, indent + 2, as_utf8, as_one_line,
- pointy_brackets=pointy_brackets,
- use_index_order=use_index_order,
- float_format=float_format)
- out.write(' ' * indent + closeb)
- elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_ENUM:
- enum_value = field.enum_type.values_by_number.get(value, None)
- if enum_value is not None:
- out.write(enum_value.name)
+ if field.is_extension:
+ out.write('[')
+ if (field.containing_type.GetOptions().message_set_wire_format and
+ field.type == descriptor.FieldDescriptor.TYPE_MESSAGE and
+ field.label == descriptor.FieldDescriptor.LABEL_OPTIONAL):
+ out.write(field.message_type.full_name)
+ else:
+ out.write(field.full_name)
+ out.write(']')
+ elif field.type == descriptor.FieldDescriptor.TYPE_GROUP:
+ # For groups, use the capitalized name.
+ out.write(field.message_type.name)
+ else:
+ out.write(field.name)
+
+ if field.cpp_type != descriptor.FieldDescriptor.CPPTYPE_MESSAGE:
+ # The colon is optional in this case, but our cross-language golden files
+ # don't include it.
+ out.write(': ')
+
+ self.PrintFieldValue(field, value)
+ if self.as_one_line:
+ out.write(' ')
else:
- out.write(str(value))
- elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_STRING:
- out.write('\"')
- if isinstance(value, six.text_type):
- out_value = value.encode('utf-8')
+ out.write('\n')
+
+ def _PrintMessageFieldValue(self, value):
+ if self.pointy_brackets:
+ openb = '<'
+ closeb = '>'
else:
- out_value = value
- if field.type == descriptor.FieldDescriptor.TYPE_BYTES:
- # We need to escape non-UTF8 chars in TYPE_BYTES field.
- out_as_utf8 = False
+ openb = '{'
+ closeb = '}'
+
+ if self.as_one_line:
+ self.out.write(' %s ' % openb)
+ self.PrintMessage(value)
+ self.out.write(closeb)
else:
- out_as_utf8 = as_utf8
- out.write(text_encoding.CEscape(out_value, out_as_utf8))
- out.write('\"')
- elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_BOOL:
- if value:
- out.write('true')
+ self.out.write(' %s\n' % openb)
+ self.indent += 2
+ self.PrintMessage(value)
+ self.indent -= 2
+ self.out.write(' ' * self.indent + closeb)
+
+ def PrintFieldValue(self, field, value):
+ """Print a single field value (not including name).
+
+ For repeated fields, the value should be a single element.
+
+ Args:
+ field: The descriptor of the field to be printed.
+ value: The value of the field.
+ """
+ out = self.out
+ if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE:
+ self._PrintMessageFieldValue(value)
+ elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_ENUM:
+ enum_value = field.enum_type.values_by_number.get(value, None)
+ if enum_value is not None:
+ out.write(enum_value.name)
+ else:
+ out.write(str(value))
+ elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_STRING:
+ out.write('\"')
+ if isinstance(value, six.text_type):
+ out_value = value.encode('utf-8')
+ else:
+ out_value = value
+ if field.type == descriptor.FieldDescriptor.TYPE_BYTES:
+ # We need to escape non-UTF8 chars in TYPE_BYTES field.
+ out_as_utf8 = False
+ else:
+ out_as_utf8 = self.as_utf8
+ out.write(text_encoding.CEscape(out_value, out_as_utf8))
+ out.write('\"')
+ elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_BOOL:
+ if value:
+ out.write('true')
+ else:
+ out.write('false')
+ elif field.cpp_type in _FLOAT_TYPES and self.float_format is not None:
+ out.write('{1:{0}}'.format(self.float_format, value))
else:
- out.write('false')
- elif field.cpp_type in _FLOAT_TYPES and float_format is not None:
- out.write('{1:{0}}'.format(float_format, value))
- else:
- out.write(str(value))
+ out.write(str(value))
-def Parse(text, message):
- """Parses an ASCII representation of a protocol message into a message.
+def Parse(text,
+ message,
+ allow_unknown_extension=False,
+ allow_field_number=False):
+ """Parses a text representation of a protocol message into a message.
Args:
- text: Message ASCII representation.
+ text: Message text representation.
message: A protocol buffer message to merge into.
+ allow_unknown_extension: if True, skip over missing extensions and keep
+ parsing
+ allow_field_number: if True, both field number and field name are allowed.
Returns:
The same message passed as argument.
Raises:
- ParseError: On ASCII parsing problems.
+ ParseError: On text parsing problems.
"""
- if not isinstance(text, str): text = text.decode('utf-8')
- return ParseLines(text.split('\n'), message)
+ if not isinstance(text, str):
+ text = text.decode('utf-8')
+ return ParseLines(
+ text.split('\n'), message, allow_unknown_extension, allow_field_number)
-def Merge(text, message):
- """Parses an ASCII representation of a protocol message into a message.
+def Merge(text,
+ message,
+ allow_unknown_extension=False,
+ allow_field_number=False,
+ descriptor_pool=None):
+ """Parses a text representation of a protocol message into a message.
Like Parse(), but allows repeated values for a non-repeated field, and uses
the last one.
Args:
- text: Message ASCII representation.
+ text: Message text representation.
message: A protocol buffer message to merge into.
+ allow_unknown_extension: if True, skip over missing extensions and keep
+ parsing
+ allow_field_number: if True, both field number and field name are allowed.
+ descriptor_pool: A DescriptorPool used to resolve Any types.
Returns:
The same message passed as argument.
Raises:
- ParseError: On ASCII parsing problems.
+ ParseError: On text parsing problems.
"""
- return MergeLines(text.split('\n'), message)
+ return MergeLines(
+ text.split('\n'),
+ message,
+ allow_unknown_extension,
+ allow_field_number,
+ descriptor_pool=descriptor_pool)
-def ParseLines(lines, message):
- """Parses an ASCII representation of a protocol message into a message.
+def ParseLines(lines,
+ message,
+ allow_unknown_extension=False,
+ allow_field_number=False):
+ """Parses a text representation of a protocol message into a message.
Args:
- lines: An iterable of lines of a message's ASCII representation.
+ lines: An iterable of lines of a message's text representation.
message: A protocol buffer message to merge into.
+ allow_unknown_extension: if True, skip over missing extensions and keep
+ parsing
+ allow_field_number: if True, both field number and field name are allowed.
+ descriptor_pool: A DescriptorPool used to resolve Any types.
Returns:
The same message passed as argument.
Raises:
- ParseError: On ASCII parsing problems.
+ ParseError: On text parsing problems.
"""
- _ParseOrMerge(lines, message, False)
- return message
+ parser = _Parser(allow_unknown_extension, allow_field_number)
+ return parser.ParseLines(lines, message)
-def MergeLines(lines, message):
- """Parses an ASCII representation of a protocol message into a message.
+def MergeLines(lines,
+ message,
+ allow_unknown_extension=False,
+ allow_field_number=False,
+ descriptor_pool=None):
+ """Parses a text representation of a protocol message into a message.
Args:
- lines: An iterable of lines of a message's ASCII representation.
+ lines: An iterable of lines of a message's text representation.
message: A protocol buffer message to merge into.
+ allow_unknown_extension: if True, skip over missing extensions and keep
+ parsing
+ allow_field_number: if True, both field number and field name are allowed.
Returns:
The same message passed as argument.
Raises:
- ParseError: On ASCII parsing problems.
+ ParseError: On text parsing problems.
"""
- _ParseOrMerge(lines, message, True)
- return message
+ parser = _Parser(allow_unknown_extension,
+ allow_field_number,
+ descriptor_pool=descriptor_pool)
+ return parser.MergeLines(lines, message)
+
+
+class _Parser(object):
+ """Text format parser for protocol message."""
+
+ def __init__(self,
+ allow_unknown_extension=False,
+ allow_field_number=False,
+ descriptor_pool=None):
+ self.allow_unknown_extension = allow_unknown_extension
+ self.allow_field_number = allow_field_number
+ self.descriptor_pool = descriptor_pool
+
+ def ParseFromString(self, text, message):
+ """Parses a text representation of a protocol message into a message."""
+ if not isinstance(text, str):
+ text = text.decode('utf-8')
+ return self.ParseLines(text.split('\n'), message)
+
+ def ParseLines(self, lines, message):
+ """Parses a text representation of a protocol message into a message."""
+ self._allow_multiple_scalars = False
+ self._ParseOrMerge(lines, message)
+ return message
+
+ def MergeFromString(self, text, message):
+ """Merges a text representation of a protocol message into a message."""
+ return self._MergeLines(text.split('\n'), message)
+
+ def MergeLines(self, lines, message):
+ """Merges a text representation of a protocol message into a message."""
+ self._allow_multiple_scalars = True
+ self._ParseOrMerge(lines, message)
+ return message
+
+ def _ParseOrMerge(self, lines, message):
+ """Converts a text representation of a protocol message into a message.
+ Args:
+ lines: Lines of a message's text representation.
+ message: A protocol buffer message to merge into.
-def _ParseOrMerge(lines, message, allow_multiple_scalars):
- """Converts an ASCII representation of a protocol message into a message.
+ Raises:
+ ParseError: On text parsing problems.
+ """
+ tokenizer = Tokenizer(lines)
+ while not tokenizer.AtEnd():
+ self._MergeField(tokenizer, message)
- Args:
- lines: Lines of a message's ASCII representation.
- message: A protocol buffer message to merge into.
- allow_multiple_scalars: Determines if repeated values for a non-repeated
- field are permitted, e.g., the string "foo: 1 foo: 2" for a
- required/optional field named "foo".
+ def _MergeField(self, tokenizer, message):
+ """Merges a single protocol message field into a message.
- Raises:
- ParseError: On ASCII parsing problems.
- """
- tokenizer = _Tokenizer(lines)
- while not tokenizer.AtEnd():
- _MergeField(tokenizer, message, allow_multiple_scalars)
+ Args:
+ tokenizer: A tokenizer to parse the field name and values.
+ message: A protocol message to record the data.
+ Raises:
+ ParseError: In case of text parsing problems.
+ """
+ message_descriptor = message.DESCRIPTOR
+ if (hasattr(message_descriptor, 'syntax') and
+ message_descriptor.syntax == 'proto3'):
+ # Proto3 doesn't represent presence so we can't test if multiple
+ # scalars have occurred. We have to allow them.
+ self._allow_multiple_scalars = True
+ if tokenizer.TryConsume('['):
+ name = [tokenizer.ConsumeIdentifier()]
+ while tokenizer.TryConsume('.'):
+ name.append(tokenizer.ConsumeIdentifier())
+ name = '.'.join(name)
+
+ if not message_descriptor.is_extendable:
+ raise tokenizer.ParseErrorPreviousToken(
+ 'Message type "%s" does not have extensions.' %
+ message_descriptor.full_name)
+ # pylint: disable=protected-access
+ field = message.Extensions._FindExtensionByName(name)
+ # pylint: enable=protected-access
+ if not field:
+ if self.allow_unknown_extension:
+ field = None
+ else:
+ raise tokenizer.ParseErrorPreviousToken(
+ 'Extension "%s" not registered.' % name)
+ elif message_descriptor != field.containing_type:
+ raise tokenizer.ParseErrorPreviousToken(
+ 'Extension "%s" does not extend message type "%s".' %
+ (name, message_descriptor.full_name))
-def _MergeField(tokenizer, message, allow_multiple_scalars):
- """Merges a single protocol message field into a message.
+ tokenizer.Consume(']')
- Args:
- tokenizer: A tokenizer to parse the field name and values.
- message: A protocol message to record the data.
- allow_multiple_scalars: Determines if repeated values for a non-repeated
- field are permitted, e.g., the string "foo: 1 foo: 2" for a
- required/optional field named "foo".
+ else:
+ name = tokenizer.ConsumeIdentifierOrNumber()
+ if self.allow_field_number and name.isdigit():
+ number = ParseInteger(name, True, True)
+ field = message_descriptor.fields_by_number.get(number, None)
+ if not field and message_descriptor.is_extendable:
+ field = message.Extensions._FindExtensionByNumber(number)
+ else:
+ field = message_descriptor.fields_by_name.get(name, None)
- Raises:
- ParseError: In case of ASCII parsing problems.
- """
- message_descriptor = message.DESCRIPTOR
- if (hasattr(message_descriptor, 'syntax') and
- message_descriptor.syntax == 'proto3'):
- # Proto3 doesn't represent presence so we can't test if multiple
- # scalars have occurred. We have to allow them.
- allow_multiple_scalars = True
- if tokenizer.TryConsume('['):
+ # Group names are expected to be capitalized as they appear in the
+ # .proto file, which actually matches their type names, not their field
+ # names.
+ if not field:
+ field = message_descriptor.fields_by_name.get(name.lower(), None)
+ if field and field.type != descriptor.FieldDescriptor.TYPE_GROUP:
+ field = None
+
+ if (field and field.type == descriptor.FieldDescriptor.TYPE_GROUP and
+ field.message_type.name != name):
+ field = None
+
+ if not field:
+ raise tokenizer.ParseErrorPreviousToken(
+ 'Message type "%s" has no field named "%s".' %
+ (message_descriptor.full_name, name))
+
+ if field:
+ if not self._allow_multiple_scalars and field.containing_oneof:
+ # Check if there's a different field set in this oneof.
+ # Note that we ignore the case if the same field was set before, and we
+ # apply _allow_multiple_scalars to non-scalar fields as well.
+ which_oneof = message.WhichOneof(field.containing_oneof.name)
+ if which_oneof is not None and which_oneof != field.name:
+ raise tokenizer.ParseErrorPreviousToken(
+ 'Field "%s" is specified along with field "%s", another member '
+ 'of oneof "%s" for message type "%s".' %
+ (field.name, which_oneof, field.containing_oneof.name,
+ message_descriptor.full_name))
+
+ if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE:
+ tokenizer.TryConsume(':')
+ merger = self._MergeMessageField
+ else:
+ tokenizer.Consume(':')
+ merger = self._MergeScalarField
+
+ if (field.label == descriptor.FieldDescriptor.LABEL_REPEATED and
+ tokenizer.TryConsume('[')):
+ # Short repeated format, e.g. "foo: [1, 2, 3]"
+ while True:
+ merger(tokenizer, message, field)
+ if tokenizer.TryConsume(']'):
+ break
+ tokenizer.Consume(',')
+
+ else:
+ merger(tokenizer, message, field)
+
+ else: # Proto field is unknown.
+ assert self.allow_unknown_extension
+ _SkipFieldContents(tokenizer)
+
+ # For historical reasons, fields may optionally be separated by commas or
+ # semicolons.
+ if not tokenizer.TryConsume(','):
+ tokenizer.TryConsume(';')
+
+ def _ConsumeAnyTypeUrl(self, tokenizer):
+ """Consumes a google.protobuf.Any type URL and returns the type name."""
+ # Consume "type.googleapis.com/".
+ tokenizer.ConsumeIdentifier()
+ tokenizer.Consume('.')
+ tokenizer.ConsumeIdentifier()
+ tokenizer.Consume('.')
+ tokenizer.ConsumeIdentifier()
+ tokenizer.Consume('/')
+ # Consume the fully-qualified type name.
name = [tokenizer.ConsumeIdentifier()]
while tokenizer.TryConsume('.'):
name.append(tokenizer.ConsumeIdentifier())
- name = '.'.join(name)
-
- if not message_descriptor.is_extendable:
- raise tokenizer.ParseErrorPreviousToken(
- 'Message type "%s" does not have extensions.' %
- message_descriptor.full_name)
- # pylint: disable=protected-access
- field = message.Extensions._FindExtensionByName(name)
- # pylint: enable=protected-access
- if not field:
- raise tokenizer.ParseErrorPreviousToken(
- 'Extension "%s" not registered.' % name)
- elif message_descriptor != field.containing_type:
- raise tokenizer.ParseErrorPreviousToken(
- 'Extension "%s" does not extend message type "%s".' % (
- name, message_descriptor.full_name))
- tokenizer.Consume(']')
- else:
- name = tokenizer.ConsumeIdentifier()
- field = message_descriptor.fields_by_name.get(name, None)
-
- # Group names are expected to be capitalized as they appear in the
- # .proto file, which actually matches their type names, not their field
- # names.
- if not field:
- field = message_descriptor.fields_by_name.get(name.lower(), None)
- if field and field.type != descriptor.FieldDescriptor.TYPE_GROUP:
- field = None
-
- if (field and field.type == descriptor.FieldDescriptor.TYPE_GROUP and
- field.message_type.name != name):
- field = None
-
- if not field:
- raise tokenizer.ParseErrorPreviousToken(
- 'Message type "%s" has no field named "%s".' % (
- message_descriptor.full_name, name))
-
- if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE:
+ return '.'.join(name)
+
+ def _MergeMessageField(self, tokenizer, message, field):
+ """Merges a single scalar field into a message.
+
+ Args:
+ tokenizer: A tokenizer to parse the field value.
+ message: The message of which field is a member.
+ field: The descriptor of the field to be merged.
+
+ Raises:
+ ParseError: In case of text parsing problems.
+ """
is_map_entry = _IsMapEntry(field)
- tokenizer.TryConsume(':')
if tokenizer.TryConsume('<'):
end_token = '>'
@@ -421,10 +718,38 @@ def _MergeField(tokenizer, message, allow_multiple_scalars):
tokenizer.Consume('{')
end_token = '}'
- if field.label == descriptor.FieldDescriptor.LABEL_REPEATED:
+ if (field.message_type.full_name == _ANY_FULL_TYPE_NAME and
+ tokenizer.TryConsume('[')):
+ packed_type_name = self._ConsumeAnyTypeUrl(tokenizer)
+ tokenizer.Consume(']')
+ tokenizer.TryConsume(':')
+ if tokenizer.TryConsume('<'):
+ expanded_any_end_token = '>'
+ else:
+ tokenizer.Consume('{')
+ expanded_any_end_token = '}'
+ if not self.descriptor_pool:
+ raise ParseError('Descriptor pool required to parse expanded Any field')
+ expanded_any_sub_message = _BuildMessageFromTypeName(packed_type_name,
+ self.descriptor_pool)
+ if not expanded_any_sub_message:
+ raise ParseError('Type %s not found in descriptor pool' %
+ packed_type_name)
+ while not tokenizer.TryConsume(expanded_any_end_token):
+ if tokenizer.AtEnd():
+ raise tokenizer.ParseErrorPreviousToken('Expected "%s".' %
+ (expanded_any_end_token,))
+ self._MergeField(tokenizer, expanded_any_sub_message)
+ if field.label == descriptor.FieldDescriptor.LABEL_REPEATED:
+ any_message = getattr(message, field.name).add()
+ else:
+ any_message = getattr(message, field.name)
+ any_message.Pack(expanded_any_sub_message)
+ elif field.label == descriptor.FieldDescriptor.LABEL_REPEATED:
if field.is_extension:
sub_message = message.Extensions[field].add()
elif is_map_entry:
+ # pylint: disable=protected-access
sub_message = field.message_type._concrete_class()
else:
sub_message = getattr(message, field.name).add()
@@ -437,8 +762,8 @@ def _MergeField(tokenizer, message, allow_multiple_scalars):
while not tokenizer.TryConsume(end_token):
if tokenizer.AtEnd():
- raise tokenizer.ParseErrorPreviousToken('Expected "%s".' % (end_token))
- _MergeField(tokenizer, sub_message, allow_multiple_scalars)
+ raise tokenizer.ParseErrorPreviousToken('Expected "%s".' % (end_token,))
+ self._MergeField(tokenizer, sub_message)
if is_map_entry:
value_cpptype = field.message_type.fields_by_name['value'].cpp_type
@@ -447,8 +772,107 @@ def _MergeField(tokenizer, message, allow_multiple_scalars):
value.MergeFrom(sub_message.value)
else:
getattr(message, field.name)[sub_message.key] = sub_message.value
+
+ def _MergeScalarField(self, tokenizer, message, field):
+ """Merges a single scalar field into a message.
+
+ Args:
+ tokenizer: A tokenizer to parse the field value.
+ message: A protocol message to record the data.
+ field: The descriptor of the field to be merged.
+
+ Raises:
+ ParseError: In case of text parsing problems.
+ RuntimeError: On runtime errors.
+ """
+ _ = self.allow_unknown_extension
+ value = None
+
+ if field.type in (descriptor.FieldDescriptor.TYPE_INT32,
+ descriptor.FieldDescriptor.TYPE_SINT32,
+ descriptor.FieldDescriptor.TYPE_SFIXED32):
+ value = _ConsumeInt32(tokenizer)
+ elif field.type in (descriptor.FieldDescriptor.TYPE_INT64,
+ descriptor.FieldDescriptor.TYPE_SINT64,
+ descriptor.FieldDescriptor.TYPE_SFIXED64):
+ value = _ConsumeInt64(tokenizer)
+ elif field.type in (descriptor.FieldDescriptor.TYPE_UINT32,
+ descriptor.FieldDescriptor.TYPE_FIXED32):
+ value = _ConsumeUint32(tokenizer)
+ elif field.type in (descriptor.FieldDescriptor.TYPE_UINT64,
+ descriptor.FieldDescriptor.TYPE_FIXED64):
+ value = _ConsumeUint64(tokenizer)
+ elif field.type in (descriptor.FieldDescriptor.TYPE_FLOAT,
+ descriptor.FieldDescriptor.TYPE_DOUBLE):
+ value = tokenizer.ConsumeFloat()
+ elif field.type == descriptor.FieldDescriptor.TYPE_BOOL:
+ value = tokenizer.ConsumeBool()
+ elif field.type == descriptor.FieldDescriptor.TYPE_STRING:
+ value = tokenizer.ConsumeString()
+ elif field.type == descriptor.FieldDescriptor.TYPE_BYTES:
+ value = tokenizer.ConsumeByteString()
+ elif field.type == descriptor.FieldDescriptor.TYPE_ENUM:
+ value = tokenizer.ConsumeEnum(field)
+ else:
+ raise RuntimeError('Unknown field type %d' % field.type)
+
+ if field.label == descriptor.FieldDescriptor.LABEL_REPEATED:
+ if field.is_extension:
+ message.Extensions[field].append(value)
+ else:
+ getattr(message, field.name).append(value)
+ else:
+ if field.is_extension:
+ if not self._allow_multiple_scalars and message.HasExtension(field):
+ raise tokenizer.ParseErrorPreviousToken(
+ 'Message type "%s" should not have multiple "%s" extensions.' %
+ (message.DESCRIPTOR.full_name, field.full_name))
+ else:
+ message.Extensions[field] = value
+ else:
+ if not self._allow_multiple_scalars and message.HasField(field.name):
+ raise tokenizer.ParseErrorPreviousToken(
+ 'Message type "%s" should not have multiple "%s" fields.' %
+ (message.DESCRIPTOR.full_name, field.name))
+ else:
+ setattr(message, field.name, value)
+
+
+def _SkipFieldContents(tokenizer):
+ """Skips over contents (value or message) of a field.
+
+ Args:
+ tokenizer: A tokenizer to parse the field name and values.
+ """
+ # Try to guess the type of this field.
+ # If this field is not a message, there should be a ":" between the
+ # field name and the field value and also the field value should not
+ # start with "{" or "<" which indicates the beginning of a message body.
+ # If there is no ":" or there is a "{" or "<" after ":", this field has
+ # to be a message or the input is ill-formed.
+ if tokenizer.TryConsume(':') and not tokenizer.LookingAt(
+ '{') and not tokenizer.LookingAt('<'):
+ _SkipFieldValue(tokenizer)
+ else:
+ _SkipFieldMessage(tokenizer)
+
+
+def _SkipField(tokenizer):
+ """Skips over a complete field (name and value/message).
+
+ Args:
+ tokenizer: A tokenizer to parse the field name and values.
+ """
+ if tokenizer.TryConsume('['):
+ # Consume extension name.
+ tokenizer.ConsumeIdentifier()
+ while tokenizer.TryConsume('.'):
+ tokenizer.ConsumeIdentifier()
+ tokenizer.Consume(']')
else:
- _MergeScalarField(tokenizer, message, field, allow_multiple_scalars)
+ tokenizer.ConsumeIdentifier()
+
+ _SkipFieldContents(tokenizer)
# For historical reasons, fields may optionally be separated by commas or
# semicolons.
@@ -456,76 +880,49 @@ def _MergeField(tokenizer, message, allow_multiple_scalars):
tokenizer.TryConsume(';')
-def _MergeScalarField(tokenizer, message, field, allow_multiple_scalars):
- """Merges a single protocol message scalar field into a message.
+def _SkipFieldMessage(tokenizer):
+ """Skips over a field message.
Args:
- tokenizer: A tokenizer to parse the field value.
- message: A protocol message to record the data.
- field: The descriptor of the field to be merged.
- allow_multiple_scalars: Determines if repeated values for a non-repeated
- field are permitted, e.g., the string "foo: 1 foo: 2" for a
- required/optional field named "foo".
+ tokenizer: A tokenizer to parse the field name and values.
+ """
+
+ if tokenizer.TryConsume('<'):
+ delimiter = '>'
+ else:
+ tokenizer.Consume('{')
+ delimiter = '}'
+
+ while not tokenizer.LookingAt('>') and not tokenizer.LookingAt('}'):
+ _SkipField(tokenizer)
+
+ tokenizer.Consume(delimiter)
+
+
+def _SkipFieldValue(tokenizer):
+ """Skips over a field value.
+
+ Args:
+ tokenizer: A tokenizer to parse the field name and values.
Raises:
- ParseError: In case of ASCII parsing problems.
- RuntimeError: On runtime errors.
+ ParseError: In case an invalid field value is found.
"""
- tokenizer.Consume(':')
- value = None
-
- if field.type in (descriptor.FieldDescriptor.TYPE_INT32,
- descriptor.FieldDescriptor.TYPE_SINT32,
- descriptor.FieldDescriptor.TYPE_SFIXED32):
- value = tokenizer.ConsumeInt32()
- elif field.type in (descriptor.FieldDescriptor.TYPE_INT64,
- descriptor.FieldDescriptor.TYPE_SINT64,
- descriptor.FieldDescriptor.TYPE_SFIXED64):
- value = tokenizer.ConsumeInt64()
- elif field.type in (descriptor.FieldDescriptor.TYPE_UINT32,
- descriptor.FieldDescriptor.TYPE_FIXED32):
- value = tokenizer.ConsumeUint32()
- elif field.type in (descriptor.FieldDescriptor.TYPE_UINT64,
- descriptor.FieldDescriptor.TYPE_FIXED64):
- value = tokenizer.ConsumeUint64()
- elif field.type in (descriptor.FieldDescriptor.TYPE_FLOAT,
- descriptor.FieldDescriptor.TYPE_DOUBLE):
- value = tokenizer.ConsumeFloat()
- elif field.type == descriptor.FieldDescriptor.TYPE_BOOL:
- value = tokenizer.ConsumeBool()
- elif field.type == descriptor.FieldDescriptor.TYPE_STRING:
- value = tokenizer.ConsumeString()
- elif field.type == descriptor.FieldDescriptor.TYPE_BYTES:
- value = tokenizer.ConsumeByteString()
- elif field.type == descriptor.FieldDescriptor.TYPE_ENUM:
- value = tokenizer.ConsumeEnum(field)
- else:
- raise RuntimeError('Unknown field type %d' % field.type)
+ # String/bytes tokens can come in multiple adjacent string literals.
+ # If we can consume one, consume as many as we can.
+ if tokenizer.TryConsumeByteString():
+ while tokenizer.TryConsumeByteString():
+ pass
+ return
- if field.label == descriptor.FieldDescriptor.LABEL_REPEATED:
- if field.is_extension:
- message.Extensions[field].append(value)
- else:
- getattr(message, field.name).append(value)
- else:
- if field.is_extension:
- if not allow_multiple_scalars and message.HasExtension(field):
- raise tokenizer.ParseErrorPreviousToken(
- 'Message type "%s" should not have multiple "%s" extensions.' %
- (message.DESCRIPTOR.full_name, field.full_name))
- else:
- message.Extensions[field] = value
- else:
- if not allow_multiple_scalars and message.HasField(field.name):
- raise tokenizer.ParseErrorPreviousToken(
- 'Message type "%s" should not have multiple "%s" fields.' %
- (message.DESCRIPTOR.full_name, field.name))
- else:
- setattr(message, field.name, value)
+ if (not tokenizer.TryConsumeIdentifier() and
+ not _TryConsumeInt64(tokenizer) and not _TryConsumeUint64(tokenizer) and
+ not tokenizer.TryConsumeFloat()):
+ raise ParseError('Invalid field value: ' + tokenizer.token)
-class _Tokenizer(object):
- """Protocol buffer ASCII representation tokenizer.
+class Tokenizer(object):
+ """Protocol buffer text representation tokenizer.
This class handles the lower level string parsing by splitting it into
meaningful tokens.
@@ -533,15 +930,20 @@ class _Tokenizer(object):
It was directly ported from the Java protocol buffer API.
"""
- _WHITESPACE = re.compile('(\\s|(#.*$))+', re.MULTILINE)
- _TOKEN = re.compile(
- '[a-zA-Z_][0-9a-zA-Z_+-]*|' # an identifier
- '[0-9+-][0-9a-zA-Z_.+-]*|' # a number
- '\"([^\"\n\\\\]|\\\\.)*(\"|\\\\?$)|' # a double-quoted string
- '\'([^\'\n\\\\]|\\\\.)*(\'|\\\\?$)') # a single-quoted string
- _IDENTIFIER = re.compile(r'\w+')
+ _WHITESPACE = re.compile(r'\s+')
+ _COMMENT = re.compile(r'(\s*#.*$)', re.MULTILINE)
+ _WHITESPACE_OR_COMMENT = re.compile(r'(\s|(#.*$))+', re.MULTILINE)
+ _TOKEN = re.compile('|'.join([
+ r'[a-zA-Z_][0-9a-zA-Z_+-]*', # an identifier
+ r'([0-9+-]|(\.[0-9]))[0-9a-zA-Z_.+-]*', # a number
+ ] + [ # quoted str for each quote mark
+ r'{qt}([^{qt}\n\\]|\\.)*({qt}|\\?$)'.format(qt=mark) for mark in _QUOTES
+ ]))
+
+ _IDENTIFIER = re.compile(r'[^\d\W]\w*')
+ _IDENTIFIER_OR_NUMBER = re.compile(r'\w+')
- def __init__(self, lines):
+ def __init__(self, lines, skip_comments=True):
self._position = 0
self._line = -1
self._column = 0
@@ -552,9 +954,15 @@ class _Tokenizer(object):
self._previous_line = 0
self._previous_column = 0
self._more_lines = True
+ self._skip_comments = skip_comments
+ self._whitespace_pattern = (skip_comments and self._WHITESPACE_OR_COMMENT
+ or self._WHITESPACE)
self._SkipWhitespace()
self.NextToken()
+ def LookingAt(self, token):
+ return self.token == token
+
def AtEnd(self):
"""Checks the end of the text was reached.
@@ -578,7 +986,7 @@ class _Tokenizer(object):
def _SkipWhitespace(self):
while True:
self._PopLine()
- match = self._WHITESPACE.match(self._current_line, self._column)
+ match = self._whitespace_pattern.match(self._current_line, self._column)
if not match:
break
length = len(match.group(0))
@@ -608,7 +1016,21 @@ class _Tokenizer(object):
ParseError: If the text couldn't be consumed.
"""
if not self.TryConsume(token):
- raise self._ParseError('Expected "%s".' % token)
+ raise self.ParseError('Expected "%s".' % token)
+
+ def ConsumeComment(self):
+ result = self.token
+ if not self._COMMENT.match(result):
+ raise self.ParseError('Expected comment.')
+ self.NextToken()
+ return result
+
+ def TryConsumeIdentifier(self):
+ try:
+ self.ConsumeIdentifier()
+ return True
+ except ParseError:
+ return False
def ConsumeIdentifier(self):
"""Consumes protocol message field identifier.
@@ -621,74 +1043,65 @@ class _Tokenizer(object):
"""
result = self.token
if not self._IDENTIFIER.match(result):
- raise self._ParseError('Expected identifier.')
+ raise self.ParseError('Expected identifier.')
self.NextToken()
return result
- def ConsumeInt32(self):
- """Consumes a signed 32bit integer number.
-
- Returns:
- The integer parsed.
-
- Raises:
- ParseError: If a signed 32bit integer couldn't be consumed.
- """
+ def TryConsumeIdentifierOrNumber(self):
try:
- result = ParseInteger(self.token, is_signed=True, is_long=False)
- except ValueError as e:
- raise self._ParseError(str(e))
- self.NextToken()
- return result
+ self.ConsumeIdentifierOrNumber()
+ return True
+ except ParseError:
+ return False
- def ConsumeUint32(self):
- """Consumes an unsigned 32bit integer number.
+ def ConsumeIdentifierOrNumber(self):
+ """Consumes protocol message field identifier.
Returns:
- The integer parsed.
+ Identifier string.
Raises:
- ParseError: If an unsigned 32bit integer couldn't be consumed.
+ ParseError: If an identifier couldn't be consumed.
"""
- try:
- result = ParseInteger(self.token, is_signed=False, is_long=False)
- except ValueError as e:
- raise self._ParseError(str(e))
+ result = self.token
+ if not self._IDENTIFIER_OR_NUMBER.match(result):
+ raise self.ParseError('Expected identifier or number.')
self.NextToken()
return result
- def ConsumeInt64(self):
- """Consumes a signed 64bit integer number.
-
- Returns:
- The integer parsed.
-
- Raises:
- ParseError: If a signed 64bit integer couldn't be consumed.
- """
+ def TryConsumeInteger(self):
try:
- result = ParseInteger(self.token, is_signed=True, is_long=True)
- except ValueError as e:
- raise self._ParseError(str(e))
- self.NextToken()
- return result
+ # Note: is_long only affects value type, not whether an error is raised.
+ self.ConsumeInteger()
+ return True
+ except ParseError:
+ return False
- def ConsumeUint64(self):
- """Consumes an unsigned 64bit integer number.
+ def ConsumeInteger(self, is_long=False):
+ """Consumes an integer number.
+ Args:
+ is_long: True if the value should be returned as a long integer.
Returns:
The integer parsed.
Raises:
- ParseError: If an unsigned 64bit integer couldn't be consumed.
+ ParseError: If an integer couldn't be consumed.
"""
try:
- result = ParseInteger(self.token, is_signed=False, is_long=True)
+ result = _ParseAbstractInteger(self.token, is_long=is_long)
except ValueError as e:
- raise self._ParseError(str(e))
+ raise self.ParseError(str(e))
self.NextToken()
return result
+ def TryConsumeFloat(self):
+ try:
+ self.ConsumeFloat()
+ return True
+ except ParseError:
+ return False
+
def ConsumeFloat(self):
"""Consumes an floating point number.
@@ -701,7 +1114,7 @@ class _Tokenizer(object):
try:
result = ParseFloat(self.token)
except ValueError as e:
- raise self._ParseError(str(e))
+ raise self.ParseError(str(e))
self.NextToken()
return result
@@ -717,10 +1130,17 @@ class _Tokenizer(object):
try:
result = ParseBool(self.token)
except ValueError as e:
- raise self._ParseError(str(e))
+ raise self.ParseError(str(e))
self.NextToken()
return result
+ def TryConsumeByteString(self):
+ try:
+ self.ConsumeByteString()
+ return True
+ except ParseError:
+ return False
+
def ConsumeString(self):
"""Consumes a string value.
@@ -746,7 +1166,7 @@ class _Tokenizer(object):
ParseError: If a byte array value couldn't be consumed.
"""
the_list = [self._ConsumeSingleByteString()]
- while self.token and self.token[0] in ('\'', '"'):
+ while self.token and self.token[0] in _QUOTES:
the_list.append(self._ConsumeSingleByteString())
return b''.join(the_list)
@@ -757,20 +1177,22 @@ class _Tokenizer(object):
tokens which are automatically concatenated, like in C or Python. This
method only consumes one token.
+ Returns:
+ The token parsed.
Raises:
ParseError: When the wrong format data is found.
"""
text = self.token
- if len(text) < 1 or text[0] not in ('\'', '"'):
- raise self._ParseError('Expected string but found: %r' % (text,))
+ if len(text) < 1 or text[0] not in _QUOTES:
+ raise self.ParseError('Expected string but found: %r' % (text,))
if len(text) < 2 or text[-1] != text[0]:
- raise self._ParseError('String missing ending quote: %r' % (text,))
+ raise self.ParseError('String missing ending quote: %r' % (text,))
try:
result = text_encoding.CUnescape(text[1:-1])
except ValueError as e:
- raise self._ParseError(str(e))
+ raise self.ParseError(str(e))
self.NextToken()
return result
@@ -778,7 +1200,7 @@ class _Tokenizer(object):
try:
result = ParseEnum(field, self.token)
except ValueError as e:
- raise self._ParseError(str(e))
+ raise self.ParseError(str(e))
self.NextToken()
return result
@@ -791,16 +1213,15 @@ class _Tokenizer(object):
Returns:
A ParseError instance.
"""
- return ParseError('%d:%d : %s' % (
- self._previous_line + 1, self._previous_column + 1, message))
+ return ParseError(message, self._previous_line + 1,
+ self._previous_column + 1)
- def _ParseError(self, message):
+ def ParseError(self, message):
"""Creates and *returns* a ParseError for the current token."""
- return ParseError('%d:%d : %s' % (
- self._line + 1, self._column + 1, message))
+ return ParseError(message, self._line + 1, self._column + 1)
def _StringParseError(self, e):
- return self._ParseError('Couldn\'t parse string: ' + str(e))
+ return self.ParseError('Couldn\'t parse string: ' + str(e))
def NextToken(self):
"""Reads the next meaningful token."""
@@ -815,12 +1236,124 @@ class _Tokenizer(object):
return
match = self._TOKEN.match(self._current_line, self._column)
+ if not match and not self._skip_comments:
+ match = self._COMMENT.match(self._current_line, self._column)
if match:
token = match.group(0)
self.token = token
else:
self.token = self._current_line[self._column]
+# Aliased so it can still be accessed by current visibility violators.
+# TODO(dbarnett): Migrate violators to textformat_tokenizer.
+_Tokenizer = Tokenizer # pylint: disable=invalid-name
+
+
+def _ConsumeInt32(tokenizer):
+ """Consumes a signed 32bit integer number from tokenizer.
+
+ Args:
+ tokenizer: A tokenizer used to parse the number.
+
+ Returns:
+ The integer parsed.
+
+ Raises:
+ ParseError: If a signed 32bit integer couldn't be consumed.
+ """
+ return _ConsumeInteger(tokenizer, is_signed=True, is_long=False)
+
+
+def _ConsumeUint32(tokenizer):
+ """Consumes an unsigned 32bit integer number from tokenizer.
+
+ Args:
+ tokenizer: A tokenizer used to parse the number.
+
+ Returns:
+ The integer parsed.
+
+ Raises:
+ ParseError: If an unsigned 32bit integer couldn't be consumed.
+ """
+ return _ConsumeInteger(tokenizer, is_signed=False, is_long=False)
+
+
+def _TryConsumeInt64(tokenizer):
+ try:
+ _ConsumeInt64(tokenizer)
+ return True
+ except ParseError:
+ return False
+
+
+def _ConsumeInt64(tokenizer):
+ """Consumes a signed 32bit integer number from tokenizer.
+
+ Args:
+ tokenizer: A tokenizer used to parse the number.
+
+ Returns:
+ The integer parsed.
+
+ Raises:
+ ParseError: If a signed 32bit integer couldn't be consumed.
+ """
+ return _ConsumeInteger(tokenizer, is_signed=True, is_long=True)
+
+
+def _TryConsumeUint64(tokenizer):
+ try:
+ _ConsumeUint64(tokenizer)
+ return True
+ except ParseError:
+ return False
+
+
+def _ConsumeUint64(tokenizer):
+ """Consumes an unsigned 64bit integer number from tokenizer.
+
+ Args:
+ tokenizer: A tokenizer used to parse the number.
+
+ Returns:
+ The integer parsed.
+
+ Raises:
+ ParseError: If an unsigned 64bit integer couldn't be consumed.
+ """
+ return _ConsumeInteger(tokenizer, is_signed=False, is_long=True)
+
+
+def _TryConsumeInteger(tokenizer, is_signed=False, is_long=False):
+ try:
+ _ConsumeInteger(tokenizer, is_signed=is_signed, is_long=is_long)
+ return True
+ except ParseError:
+ return False
+
+
+def _ConsumeInteger(tokenizer, is_signed=False, is_long=False):
+ """Consumes an integer number from tokenizer.
+
+ Args:
+ tokenizer: A tokenizer used to parse the number.
+ is_signed: True if a signed integer must be parsed.
+ is_long: True if a long integer must be parsed.
+
+ Returns:
+ The integer parsed.
+
+ Raises:
+ ParseError: If an integer with given characteristics couldn't be consumed.
+ """
+ try:
+ result = ParseInteger(tokenizer.token, is_signed=is_signed, is_long=is_long)
+ except ValueError as e:
+ raise tokenizer.ParseError(str(e))
+ tokenizer.NextToken()
+ return result
+
def ParseInteger(text, is_signed=False, is_long=False):
"""Parses an integer.
@@ -837,22 +1370,39 @@ def ParseInteger(text, is_signed=False, is_long=False):
ValueError: Thrown Iff the text is not a valid integer.
"""
# Do the actual parsing. Exception handling is propagated to caller.
+ result = _ParseAbstractInteger(text, is_long=is_long)
+
+ # Check if the integer is sane. Exceptions handled by callers.
+ checker = _INTEGER_CHECKERS[2 * int(is_long) + int(is_signed)]
+ checker.CheckValue(result)
+ return result
+
+
+def _ParseAbstractInteger(text, is_long=False):
+ """Parses an integer without checking size/signedness.
+
+ Args:
+ text: The text to parse.
+ is_long: True if the value should be returned as a long integer.
+
+ Returns:
+ The integer value.
+
+ Raises:
+ ValueError: Thrown Iff the text is not a valid integer.
+ """
+ # Do the actual parsing. Exception handling is propagated to caller.
try:
# We force 32-bit values to int and 64-bit values to long to make
# alternate implementations where the distinction is more significant
# (e.g. the C++ implementation) simpler.
if is_long:
- result = long(text, 0)
+ return long(text, 0)
else:
- result = int(text, 0)
+ return int(text, 0)
except ValueError:
raise ValueError('Couldn\'t parse integer: %s' % text)
- # Check if the integer is sane. Exceptions handled by callers.
- checker = _INTEGER_CHECKERS[2 * int(is_long) + int(is_signed)]
- checker.CheckValue(result)
- return result
-
def ParseFloat(text):
"""Parse a floating point number.
@@ -929,14 +1479,12 @@ def ParseEnum(field, value):
# Identifier.
enum_value = enum_descriptor.values_by_name.get(value, None)
if enum_value is None:
- raise ValueError(
- 'Enum type "%s" has no value named %s.' % (
- enum_descriptor.full_name, value))
+ raise ValueError('Enum type "%s" has no value named %s.' %
+ (enum_descriptor.full_name, value))
else:
# Numeric value.
enum_value = enum_descriptor.values_by_number.get(number, None)
if enum_value is None:
- raise ValueError(
- 'Enum type "%s" has no value with number %d.' % (
- enum_descriptor.full_name, number))
+ raise ValueError('Enum type "%s" has no value with number %d.' %
+ (enum_descriptor.full_name, number))
return enum_value.number
diff --git a/python/google/protobuf/util/__init__.py b/python/google/protobuf/util/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/python/google/protobuf/util/__init__.py
+++ /dev/null
diff --git a/python/setup.cfg b/python/setup.cfg
new file mode 100644
index 00000000..2a9acf13
--- /dev/null
+++ b/python/setup.cfg
@@ -0,0 +1,2 @@
+[bdist_wheel]
+universal = 1
diff --git a/python/setup.py b/python/setup.py
index 18865e03..524a312f 100755
--- a/python/setup.py
+++ b/python/setup.py
@@ -76,6 +76,7 @@ def generate_proto(source, require = True):
sys.exit(-1)
def GenerateUnittestProtos():
+ generate_proto("../src/google/protobuf/any_test.proto", False)
generate_proto("../src/google/protobuf/map_unittest.proto", False)
generate_proto("../src/google/protobuf/unittest_arena.proto", False)
generate_proto("../src/google/protobuf/unittest_no_arena.proto", False)
@@ -89,10 +90,12 @@ def GenerateUnittestProtos():
generate_proto("../src/google/protobuf/unittest_no_generic_services.proto", False)
generate_proto("../src/google/protobuf/unittest_proto3_arena.proto", False)
generate_proto("../src/google/protobuf/util/json_format_proto3.proto", False)
+ generate_proto("google/protobuf/internal/any_test.proto", False)
generate_proto("google/protobuf/internal/descriptor_pool_test1.proto", False)
generate_proto("google/protobuf/internal/descriptor_pool_test2.proto", False)
generate_proto("google/protobuf/internal/factory_test1.proto", False)
generate_proto("google/protobuf/internal/factory_test2.proto", False)
+ generate_proto("google/protobuf/internal/file_options_test.proto", False)
generate_proto("google/protobuf/internal/import_test_package/inner.proto", False)
generate_proto("google/protobuf/internal/import_test_package/outer.proto", False)
generate_proto("google/protobuf/internal/missing_enum_values.proto", False)
@@ -113,7 +116,8 @@ class clean(_clean):
filepath = os.path.join(dirpath, filename)
if filepath.endswith("_pb2.py") or filepath.endswith(".pyc") or \
filepath.endswith(".so") or filepath.endswith(".o") or \
- filepath.endswith('google/protobuf/compiler/__init__.py'):
+ filepath.endswith('google/protobuf/compiler/__init__.py') or \
+ filepath.endswith('google/protobuf/util/__init__.py'):
os.remove(filepath)
# _clean is an old-style class, so super() doesn't work.
_clean.run(self)
@@ -136,7 +140,7 @@ class build_py(_build_py):
GenerateUnittestProtos()
# Make sure google.protobuf/** are valid packages.
- for path in ['', 'internal/', 'compiler/', 'pyext/']:
+ for path in ['', 'internal/', 'compiler/', 'pyext/', 'util/']:
try:
open('google/protobuf/%s__init__.py' % path, 'a').close()
except EnvironmentError:
@@ -147,20 +151,41 @@ class build_py(_build_py):
class test_conformance(_build_py):
target = 'test_python'
def run(self):
+ if sys.version_info >= (2, 7):
+ # Python 2.6 dodges these extra failures.
+ os.environ["CONFORMANCE_PYTHON_EXTRA_FAILURES"] = (
+ "--failure_list failure_list_python-post26.txt")
cmd = 'cd ../conformance && make %s' % (test_conformance.target)
status = subprocess.check_call(cmd, shell=True)
+def get_option_from_sys_argv(option_str):
+ if option_str in sys.argv:
+ sys.argv.remove(option_str)
+ return True
+ return False
+
+
if __name__ == '__main__':
ext_module_list = []
- cpp_impl = '--cpp_implementation'
warnings_as_errors = '--warnings_as_errors'
- if cpp_impl in sys.argv:
- sys.argv.remove(cpp_impl)
- extra_compile_args = ['-Wno-write-strings', '-Wno-invalid-offsetof']
+ if get_option_from_sys_argv('--cpp_implementation'):
+ # Link libprotobuf.a and libprotobuf-lite.a statically with the
+ # extension. Note that those libraries have to be compiled with
+ # -fPIC for this to work.
+ compile_static_ext = get_option_from_sys_argv('--compile_static_extension')
+ extra_compile_args = ['-Wno-write-strings',
+ '-Wno-invalid-offsetof',
+ '-Wno-sign-compare']
+ libraries = ['protobuf']
+ extra_objects = None
+ if compile_static_ext:
+ libraries = None
+ extra_objects = ['../src/.libs/libprotobuf.a',
+ '../src/.libs/libprotobuf-lite.a']
test_conformance.target = 'test_python_cpp'
- if "clang" in os.popen('$CC --version').read():
+ if "clang" in os.popen('$CC --version 2> /dev/null').read():
extra_compile_args.append('-Wno-shorten-64-to-32')
if warnings_as_errors in sys.argv:
@@ -168,20 +193,26 @@ if __name__ == '__main__':
sys.argv.remove(warnings_as_errors)
# C++ implementation extension
- ext_module_list.append(
+ ext_module_list.extend([
Extension(
"google.protobuf.pyext._message",
glob.glob('google/protobuf/pyext/*.cc'),
include_dirs=[".", "../src"],
- libraries=['protobuf'],
+ libraries=libraries,
+ extra_objects=extra_objects,
library_dirs=['../src/.libs'],
extra_compile_args=extra_compile_args,
- )
- )
+ ),
+ Extension(
+ "google.protobuf.internal._api_implementation",
+ glob.glob('google/protobuf/internal/api_implementation.cc'),
+ extra_compile_args=['-DPYTHON_PROTO2_CPP_IMPL_V2'],
+ ),
+ ])
os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION'] = 'cpp'
# Keep this list of dependencies in sync with tox.ini.
- install_requires = ['six', 'setuptools']
+ install_requires = ['six>=1.9', 'setuptools']
if sys.version_info <= (2,7):
install_requires.append('ordereddict')
install_requires.append('unittest2')
@@ -190,6 +221,7 @@ if __name__ == '__main__':
name='protobuf',
version=GetVersion(),
description='Protocol Buffers',
+ download_url='https://github.com/google/protobuf/releases',
long_description="Protocol Buffers are Google's data interchange format",
url='https://developers.google.com/protocol-buffers/',
maintainer='protobuf@googlegroups.com',
diff --git a/python/tox.ini b/python/tox.ini
index 683d82dc..cf8d5401 100644
--- a/python/tox.ini
+++ b/python/tox.ini
@@ -19,6 +19,6 @@ commands =
cpp: python setup.py -q test_conformance --cpp_implementation
deps =
# Keep this list of dependencies in sync with setup.py.
- six
+ six>=1.9
py26: ordereddict
py26: unittest2
diff --git a/ruby/Gemfile.lock b/ruby/Gemfile.lock
index 8599da75..d0eb9cc4 100644
--- a/ruby/Gemfile.lock
+++ b/ruby/Gemfile.lock
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
- google-protobuf (3.0.0.alpha.4.0)
+ google-protobuf (3.0.0.alpha.5.0.5)
GEM
remote: https://rubygems.org/
@@ -10,6 +10,7 @@ GEM
rake (10.4.2)
rake-compiler (0.9.5)
rake
+ rake-compiler-dock (0.5.1)
rubygems-tasks (0.2.4)
test-unit (3.0.9)
power_assert
@@ -21,8 +22,9 @@ PLATFORMS
DEPENDENCIES
google-protobuf!
rake-compiler
+ rake-compiler-dock
rubygems-tasks
test-unit
BUNDLED WITH
- 1.10.6
+ 1.11.2
diff --git a/ruby/README.md b/ruby/README.md
index 16474322..f28e05a7 100644
--- a/ruby/README.md
+++ b/ruby/README.md
@@ -32,23 +32,25 @@ documentation may be found in the RubyDoc comments (`call-seq` tags) in the
source, and we plan to release separate, more detailed, documentation at a
later date.
- require 'google/protobuf'
+```ruby
+require 'google/protobuf'
- # generated from my_proto_types.proto with protoc:
- # $ protoc --ruby_out=. my_proto_types.proto
- require 'my_proto_types'
+# generated from my_proto_types.proto with protoc:
+# $ protoc --ruby_out=. my_proto_types.proto
+require 'my_proto_types'
- mymessage = MyTestMessage.new(:field1 => 42, :field2 => ["a", "b", "c"])
- mymessage.field1 = 43
- mymessage.field2.push("d")
- mymessage.field3 = SubMessage.new(:foo => 100)
+mymessage = MyTestMessage.new(:field1 => 42, :field2 => ["a", "b", "c"])
+mymessage.field1 = 43
+mymessage.field2.push("d")
+mymessage.field3 = SubMessage.new(:foo => 100)
- encoded_data = MyTestMessage.encode(mymessage)
- decoded = MyTestMessage.decode(encoded_data)
- assert decoded == mymessage
+encoded_data = MyTestMessage.encode(mymessage)
+decoded = MyTestMessage.decode(encoded_data)
+assert decoded == mymessage
- puts "JSON:"
- puts MyTestMessage.encode_json(mymessage)
+puts "JSON:"
+puts MyTestMessage.encode_json(mymessage)
+```
Installation from Source (Building Gem)
---------------------------------------
diff --git a/ruby/Rakefile b/ruby/Rakefile
index c25103d8..ba1cf4cf 100644
--- a/ruby/Rakefile
+++ b/ruby/Rakefile
@@ -5,6 +5,40 @@ require "rake/testtask"
spec = Gem::Specification.load("google-protobuf.gemspec")
+well_known_protos = %w[
+ 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
+ google/protobuf/struct.proto
+ google/protobuf/timestamp.proto
+ google/protobuf/type.proto
+ google/protobuf/wrappers.proto
+]
+
+# These are omitted for now because we don't support proto2.
+proto2_protos = %w[
+ google/protobuf/descriptor.proto
+ google/protobuf/compiler/plugin.proto
+]
+
+genproto_output = []
+
+# We won't have access to .. from within docker, but the proto files
+# will be there, thanks to the :genproto rule dependency for gem:native.
+unless ENV['IN_DOCKER'] == 'true'
+ well_known_protos.each do |proto_file|
+ input_file = "../src/" + proto_file
+ output_file = "lib/" + proto_file.sub(/\.proto$/, "_pb.rb")
+ genproto_output << output_file
+ file output_file => input_file do |file_task|
+ sh "../src/protoc -I../src --ruby_out=lib #{input_file}"
+ end
+ end
+end
+
if RUBY_PLATFORM == "java"
if `which mvn` == ''
raise ArgumentError, "maven needs to be installed"
@@ -20,9 +54,47 @@ else
Rake::ExtensionTask.new("protobuf_c", spec) do |ext|
ext.ext_dir = "ext/google/protobuf_c"
ext.lib_dir = "lib/google"
+ ext.cross_compile = true
+ ext.cross_platform = [
+ 'x86-mingw32', 'x64-mingw32',
+ 'x86_64-linux', 'x86-linux',
+ 'universal-darwin'
+ ]
+ end
+
+ task 'gem:windows' do
+ require 'rake_compiler_dock'
+ RakeCompilerDock.sh "bundle && IN_DOCKER=true rake cross native gem RUBY_CC_VERSION=2.3.0:2.2.2:2.1.5:2.0.0"
+ end
+
+ if RUBY_PLATFORM =~ /darwin/
+ task 'gem:native' do
+ system "rake genproto"
+ system "rake cross native gem RUBY_CC_VERSION=2.3.0:2.2.2:2.1.5:2.0.0"
+ end
+ else
+ task 'gem:native' => [:genproto, 'gem:windows']
end
end
+
+# Proto for tests.
+genproto_output << "tests/generated_code.rb"
+genproto_output << "tests/test_import.rb"
+file "tests/generated_code.rb" => "tests/generated_code.proto" do |file_task|
+ sh "../src/protoc --ruby_out=. tests/generated_code.proto"
+end
+
+file "tests/test_import.rb" => "tests/test_import.proto" do |file_task|
+ sh "../src/protoc --ruby_out=. tests/test_import.proto"
+end
+
+task :genproto => genproto_output
+
+task :clean do
+ sh "rm -f #{genproto_output.join(' ')}"
+end
+
Gem::PackageTask.new(spec) do |pkg|
end
@@ -30,7 +102,7 @@ Rake::TestTask.new(:test => :build) do |t|
t.test_files = FileList["tests/*.rb"]
end
-task :build => [:clean, :compile]
+task :build => [:clean, :compile, :genproto]
task :default => [:build]
# vim:sw=2:et
diff --git a/ruby/ext/google/protobuf_c/defs.c b/ruby/ext/google/protobuf_c/defs.c
index 7e0cd14c..7e93bafb 100644
--- a/ruby/ext/google/protobuf_c/defs.c
+++ b/ruby/ext/google/protobuf_c/defs.c
@@ -243,6 +243,10 @@ void Descriptor_free(void* _self) {
if (self->fill_method) {
upb_pbdecodermethod_unref(self->fill_method, &self->fill_method);
}
+ if (self->json_fill_method) {
+ upb_json_parsermethod_unref(self->json_fill_method,
+ &self->json_fill_method);
+ }
if (self->pb_serialize_handlers) {
upb_handlers_unref(self->pb_serialize_handlers,
&self->pb_serialize_handlers);
@@ -251,6 +255,10 @@ void Descriptor_free(void* _self) {
upb_handlers_unref(self->json_serialize_handlers,
&self->json_serialize_handlers);
}
+ if (self->json_serialize_handlers_preserve) {
+ upb_handlers_unref(self->json_serialize_handlers_preserve,
+ &self->json_serialize_handlers_preserve);
+ }
xfree(self);
}
@@ -271,8 +279,10 @@ VALUE Descriptor_alloc(VALUE klass) {
self->layout = NULL;
self->fill_handlers = NULL;
self->fill_method = NULL;
+ self->json_fill_method = NULL;
self->pb_serialize_handlers = NULL;
self->json_serialize_handlers = NULL;
+ self->json_serialize_handlers_preserve = NULL;
self->typeclass_references = rb_ary_new();
return ret;
}
diff --git a/ruby/ext/google/protobuf_c/encode_decode.c b/ruby/ext/google/protobuf_c/encode_decode.c
index 1c48281f..dd21a046 100644
--- a/ruby/ext/google/protobuf_c/encode_decode.c
+++ b/ruby/ext/google/protobuf_c/encode_decode.c
@@ -54,7 +54,7 @@ VALUE noleak_rb_str_cat(VALUE rb_str, const char *str, long len) {
static const void* newhandlerdata(upb_handlers* h, uint32_t ofs) {
size_t* hd_ofs = ALLOC(size_t);
*hd_ofs = ofs;
- upb_handlers_addcleanup(h, hd_ofs, free);
+ upb_handlers_addcleanup(h, hd_ofs, xfree);
return hd_ofs;
}
@@ -69,7 +69,7 @@ static const void *newsubmsghandlerdata(upb_handlers* h, uint32_t ofs,
submsg_handlerdata_t *hd = ALLOC(submsg_handlerdata_t);
hd->ofs = ofs;
hd->md = upb_fielddef_msgsubdef(f);
- upb_handlers_addcleanup(h, hd, free);
+ upb_handlers_addcleanup(h, hd, xfree);
return hd;
}
@@ -99,7 +99,7 @@ static const void *newoneofhandlerdata(upb_handlers *h,
} else {
hd->md = NULL;
}
- upb_handlers_addcleanup(h, hd, free);
+ upb_handlers_addcleanup(h, hd, xfree);
return hd;
}
@@ -135,7 +135,7 @@ static void* appendstr_handler(void *closure,
VALUE ary = (VALUE)closure;
VALUE str = rb_str_new2("");
rb_enc_associate(str, kRubyStringUtf8Encoding);
- RepeatedField_push(ary, str);
+ RepeatedField_push_native(ary, &str);
return (void*)str;
}
@@ -146,7 +146,7 @@ static void* appendbytes_handler(void *closure,
VALUE ary = (VALUE)closure;
VALUE str = rb_str_new2("");
rb_enc_associate(str, kRubyString8bitEncoding);
- RepeatedField_push(ary, str);
+ RepeatedField_push_native(ary, &str);
return (void*)str;
}
@@ -182,6 +182,23 @@ static size_t stringdata_handler(void* closure, const void* hd,
return len;
}
+static bool stringdata_end_handler(void* closure, const void* hd) {
+ MessageHeader* msg = closure;
+ const size_t *ofs = hd;
+ VALUE rb_str = DEREF(msg, *ofs, VALUE);
+ rb_obj_freeze(rb_str);
+ return true;
+}
+
+static bool appendstring_end_handler(void* closure, const void* hd) {
+ VALUE ary = (VALUE)closure;
+ int size = RepeatedField_size(ary);
+ VALUE* last = RepeatedField_index_native(ary, size - 1);
+ VALUE rb_str = *last;
+ rb_obj_freeze(rb_str);
+ return true;
+}
+
// Appends a submessage to a repeated field (a regular Ruby array for now).
static void *appendsubmsg_handler(void *closure, const void *hd) {
VALUE ary = (VALUE)closure;
@@ -281,7 +298,7 @@ static bool endmap_handler(void *closure, const void *hd, upb_status* s) {
&frame->value_storage);
Map_index_set(frame->map, key, value);
- free(frame);
+ xfree(frame);
return true;
}
@@ -360,6 +377,13 @@ static void *oneofbytes_handler(void *closure,
return (void*)str;
}
+static bool oneofstring_end_handler(void* closure, const void* hd) {
+ MessageHeader* msg = closure;
+ const oneof_handlerdata_t *oneofdata = hd;
+ rb_obj_freeze(DEREF(msg, oneofdata->ofs, VALUE));
+ return true;
+}
+
// Handler for a submessage field in a oneof.
static void *oneofsubmsg_handler(void *closure,
const void *hd) {
@@ -426,6 +450,7 @@ static void add_handlers_for_repeated_field(upb_handlers *h,
appendbytes_handler : appendstr_handler,
NULL);
upb_handlers_setstring(h, f, stringdata_handler, NULL);
+ upb_handlers_setendstr(h, f, appendstring_end_handler, NULL);
break;
}
case UPB_TYPE_MESSAGE: {
@@ -462,6 +487,7 @@ static void add_handlers_for_singular_field(upb_handlers *h,
is_bytes ? bytes_handler : str_handler,
&attr);
upb_handlers_setstring(h, f, stringdata_handler, &attr);
+ upb_handlers_setendstr(h, f, stringdata_end_handler, &attr);
upb_handlerattr_uninit(&attr);
break;
}
@@ -484,7 +510,7 @@ static void add_handlers_for_mapfield(upb_handlers* h,
map_handlerdata_t* hd = new_map_handlerdata(offset, map_msgdef, desc);
upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
- upb_handlers_addcleanup(h, hd, free);
+ upb_handlers_addcleanup(h, hd, xfree);
upb_handlerattr_sethandlerdata(&attr, hd);
upb_handlers_setstartsubmsg(h, fielddef, startmapentry_handler, &attr);
upb_handlerattr_uninit(&attr);
@@ -499,7 +525,7 @@ static void add_handlers_for_mapentry(const upb_msgdef* msgdef,
map_handlerdata_t* hd = new_map_handlerdata(0, msgdef, desc);
upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
- upb_handlers_addcleanup(h, hd, free);
+ upb_handlers_addcleanup(h, hd, xfree);
upb_handlerattr_sethandlerdata(&attr, hd);
upb_handlers_setendmsg(h, endmap_handler, &attr);
@@ -546,6 +572,7 @@ static void add_handlers_for_oneof_field(upb_handlers *h,
oneofbytes_handler : oneofstr_handler,
&attr);
upb_handlers_setstring(h, f, stringdata_handler, NULL);
+ upb_handlers_setendstr(h, f, oneofstring_end_handler, &attr);
break;
}
case UPB_TYPE_MESSAGE: {
@@ -640,6 +667,14 @@ static const upb_pbdecodermethod *msgdef_decodermethod(Descriptor* desc) {
return desc->fill_method;
}
+static const upb_json_parsermethod *msgdef_jsonparsermethod(Descriptor* desc) {
+ if (desc->json_fill_method == NULL) {
+ desc->json_fill_method =
+ upb_json_parsermethod_new(desc->msgdef, &desc->json_fill_method);
+ }
+ return desc->json_fill_method;
+}
+
// Stack-allocated context during an encode/decode operation. Contains the upb
// environment and its stack-based allocator, an initial buffer for allocations
@@ -648,7 +683,6 @@ static const upb_pbdecodermethod *msgdef_decodermethod(Descriptor* desc) {
#define STACK_ENV_STACKBYTES 4096
typedef struct {
upb_env env;
- upb_seededalloc alloc;
const char* ruby_error_template;
char allocbuf[STACK_ENV_STACKBYTES];
} stackenv;
@@ -673,16 +707,12 @@ static bool env_error_func(void* ud, const upb_status* status) {
static void stackenv_init(stackenv* se, const char* errmsg) {
se->ruby_error_template = errmsg;
- upb_env_init(&se->env);
- upb_seededalloc_init(&se->alloc, &se->allocbuf, STACK_ENV_STACKBYTES);
- upb_env_setallocfunc(
- &se->env, upb_seededalloc_getallocfunc(&se->alloc), &se->alloc);
+ upb_env_init2(&se->env, se->allocbuf, sizeof(se->allocbuf), NULL);
upb_env_seterrorfunc(&se->env, env_error_func, se);
}
static void stackenv_uninit(stackenv* se) {
upb_env_uninit(&se->env);
- upb_seededalloc_uninit(&se->alloc);
}
/*
@@ -752,13 +782,14 @@ VALUE Message_decode_json(VALUE klass, VALUE data) {
TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
{
+ const upb_json_parsermethod* method = msgdef_jsonparsermethod(desc);
stackenv se;
upb_sink sink;
upb_json_parser* parser;
stackenv_init(&se, "Error occurred during parsing: %s");
upb_sink_reset(&sink, get_fill_handlers(desc), msg);
- parser = upb_json_parser_create(&se.env, &sink);
+ parser = upb_json_parser_create(&se.env, method, &sink);
upb_bufsrc_putbuf(RSTRING_PTR(data), RSTRING_LEN(data),
upb_json_parser_input(parser));
@@ -859,9 +890,13 @@ static void putstr(VALUE str, const upb_fielddef *f, upb_sink *sink) {
assert(BUILTIN_TYPE(str) == RUBY_T_STRING);
- // Ensure that the string has the correct encoding. We also check at field-set
- // time, but the user may have mutated the string object since then.
- native_slot_validate_string_encoding(upb_fielddef_type(f), str);
+ // We should be guaranteed that the string has the correct encoding because
+ // we ensured this at assignment time and then froze the string.
+ if (upb_fielddef_type(f) == UPB_TYPE_STRING) {
+ assert(rb_enc_from_index(ENCODING_GET(value)) == kRubyStringUtf8Encoding);
+ } else {
+ assert(rb_enc_from_index(ENCODING_GET(value)) == kRubyString8bitEncoding);
+ }
upb_sink_startstr(sink, getsel(f, UPB_HANDLER_STARTSTR), RSTRING_LEN(str),
&subsink);
@@ -1041,6 +1076,7 @@ static void putmsg(VALUE msg_rb, const Descriptor* desc,
!upb_msg_field_done(&i);
upb_msg_field_next(&i)) {
upb_fielddef *f = upb_msg_iter_field(&i);
+ bool is_matching_oneof = false;
uint32_t offset =
desc->layout->fields[upb_fielddef_index(f)].offset +
sizeof(MessageHeader);
@@ -1057,6 +1093,7 @@ static void putmsg(VALUE msg_rb, const Descriptor* desc,
}
// Otherwise, fall through to the appropriate singular-field handler
// below.
+ is_matching_oneof = true;
}
if (is_map_field(f)) {
@@ -1071,7 +1108,7 @@ static void putmsg(VALUE msg_rb, const Descriptor* desc,
}
} else if (upb_fielddef_isstring(f)) {
VALUE str = DEREF(msg, offset, VALUE);
- if (RSTRING_LEN(str) > 0) {
+ if (is_matching_oneof || RSTRING_LEN(str) > 0) {
putstr(str, f, sink);
}
} else if (upb_fielddef_issubmsg(f)) {
@@ -1082,7 +1119,7 @@ static void putmsg(VALUE msg_rb, const Descriptor* desc,
#define T(upbtypeconst, upbtype, ctype, default_value) \
case upbtypeconst: { \
ctype value = DEREF(msg, offset, ctype); \
- if (value != default_value) { \
+ if (is_matching_oneof || value != default_value) { \
upb_sink_put##upbtype(sink, sel, value); \
} \
} \
@@ -1119,13 +1156,23 @@ static const upb_handlers* msgdef_pb_serialize_handlers(Descriptor* desc) {
return desc->pb_serialize_handlers;
}
-static const upb_handlers* msgdef_json_serialize_handlers(Descriptor* desc) {
- if (desc->json_serialize_handlers == NULL) {
- desc->json_serialize_handlers =
- upb_json_printer_newhandlers(
- desc->msgdef, &desc->json_serialize_handlers);
+static const upb_handlers* msgdef_json_serialize_handlers(
+ Descriptor* desc, bool preserve_proto_fieldnames) {
+ if (preserve_proto_fieldnames) {
+ if (desc->json_serialize_handlers == NULL) {
+ desc->json_serialize_handlers =
+ upb_json_printer_newhandlers(
+ desc->msgdef, true, &desc->json_serialize_handlers);
+ }
+ return desc->json_serialize_handlers;
+ } else {
+ if (desc->json_serialize_handlers_preserve == NULL) {
+ desc->json_serialize_handlers_preserve =
+ upb_json_printer_newhandlers(
+ desc->msgdef, false, &desc->json_serialize_handlers_preserve);
+ }
+ return desc->json_serialize_handlers_preserve;
}
- return desc->json_serialize_handlers;
}
/*
@@ -1170,16 +1217,33 @@ VALUE Message_encode(VALUE klass, VALUE msg_rb) {
*
* Encodes the given message object into its serialized JSON representation.
*/
-VALUE Message_encode_json(VALUE klass, VALUE msg_rb) {
+VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass) {
VALUE descriptor = rb_ivar_get(klass, descriptor_instancevar_interned);
Descriptor* desc = ruby_to_Descriptor(descriptor);
-
+ VALUE msg_rb;
+ VALUE preserve_proto_fieldnames = Qfalse;
stringsink sink;
+
+ if (argc < 1 || argc > 2) {
+ rb_raise(rb_eArgError, "Expected 1 or 2 arguments.");
+ }
+
+ msg_rb = argv[0];
+
+ if (argc == 2) {
+ VALUE hash_args = argv[1];
+ if (TYPE(hash_args) != T_HASH) {
+ rb_raise(rb_eArgError, "Expected hash arguments.");
+ }
+ preserve_proto_fieldnames = rb_hash_lookup2(
+ hash_args, ID2SYM(rb_intern("preserve_proto_fieldnames")), Qfalse);
+ }
+
stringsink_init(&sink);
{
const upb_handlers* serialize_handlers =
- msgdef_json_serialize_handlers(desc);
+ msgdef_json_serialize_handlers(desc, RTEST(preserve_proto_fieldnames));
upb_json_printer* printer;
stackenv se;
VALUE ret;
@@ -1189,7 +1253,7 @@ VALUE Message_encode_json(VALUE klass, VALUE msg_rb) {
putmsg(msg_rb, desc, upb_json_printer_input(printer), 0);
- ret = rb_str_new(sink.ptr, sink.len);
+ ret = rb_enc_str_new(sink.ptr, sink.len, rb_utf8_encoding());
stackenv_uninit(&se);
stringsink_uninit(&sink);
diff --git a/ruby/ext/google/protobuf_c/map.c b/ruby/ext/google/protobuf_c/map.c
index 92fc7286..12f1f9dd 100644
--- a/ruby/ext/google/protobuf_c/map.c
+++ b/ruby/ext/google/protobuf_c/map.c
@@ -63,16 +63,16 @@
// construct a key byte sequence if needed. |out_key| and |out_length| provide
// the resulting key data/length.
#define TABLE_KEY_BUF_LENGTH 8 // sizeof(uint64_t)
-static void table_key(Map* self, VALUE key,
- char* buf,
- const char** out_key,
- size_t* out_length) {
+static VALUE table_key(Map* self, VALUE key,
+ char* buf,
+ const char** out_key,
+ size_t* out_length) {
switch (self->key_type) {
case UPB_TYPE_BYTES:
case UPB_TYPE_STRING:
// Strings: use string content directly.
Check_Type(key, T_STRING);
- native_slot_validate_string_encoding(self->key_type, key);
+ key = native_slot_encode_and_freeze_string(self->key_type, key);
*out_key = RSTRING_PTR(key);
*out_length = RSTRING_LEN(key);
break;
@@ -93,6 +93,8 @@ static void table_key(Map* self, VALUE key,
assert(false);
break;
}
+
+ return key;
}
static VALUE table_key_to_ruby(Map* self, const char* buf, size_t length) {
@@ -357,7 +359,7 @@ VALUE Map_index(VALUE _self, VALUE key) {
const char* keyval = NULL;
size_t length = 0;
upb_value v;
- table_key(self, key, keybuf, &keyval, &length);
+ key = table_key(self, key, keybuf, &keyval, &length);
if (upb_strtable_lookup2(&self->table, keyval, length, &v)) {
void* mem = value_memory(&v);
@@ -383,7 +385,7 @@ VALUE Map_index_set(VALUE _self, VALUE key, VALUE value) {
size_t length = 0;
upb_value v;
void* mem;
- table_key(self, key, keybuf, &keyval, &length);
+ key = table_key(self, key, keybuf, &keyval, &length);
mem = value_memory(&v);
native_slot_set(self->value_type, self->value_type_class, mem, value);
@@ -411,7 +413,7 @@ VALUE Map_has_key(VALUE _self, VALUE key) {
char keybuf[TABLE_KEY_BUF_LENGTH];
const char* keyval = NULL;
size_t length = 0;
- table_key(self, key, keybuf, &keyval, &length);
+ key = table_key(self, key, keybuf, &keyval, &length);
if (upb_strtable_lookup2(&self->table, keyval, length, NULL)) {
return Qtrue;
@@ -434,7 +436,7 @@ VALUE Map_delete(VALUE _self, VALUE key) {
const char* keyval = NULL;
size_t length = 0;
upb_value v;
- table_key(self, key, keybuf, &keyval, &length);
+ key = table_key(self, key, keybuf, &keyval, &length);
if (upb_strtable_remove2(&self->table, keyval, length, &v)) {
void* mem = value_memory(&v);
diff --git a/ruby/ext/google/protobuf_c/message.c b/ruby/ext/google/protobuf_c/message.c
index ebe2f1ab..e16250f3 100644
--- a/ruby/ext/google/protobuf_c/message.c
+++ b/ruby/ext/google/protobuf_c/message.c
@@ -151,32 +151,30 @@ VALUE Message_method_missing(int argc, VALUE* argv, VALUE _self) {
name_len--;
}
- // Check for a oneof name first.
- o = upb_msgdef_ntoo(self->descriptor->msgdef,
- name, name_len);
+ // See if this name corresponds to either a oneof or field in this message.
+ if (!upb_msgdef_lookupname(self->descriptor->msgdef, name, name_len, &f,
+ &o)) {
+ return rb_call_super(argc, argv);
+ }
+
if (o != NULL) {
+ // This is a oneof -- return which field inside the oneof is set.
if (setter) {
rb_raise(rb_eRuntimeError, "Oneof accessors are read-only.");
}
return which_oneof_field(self, o);
- }
-
- // Otherwise, check for a field with that name.
- f = upb_msgdef_ntof(self->descriptor->msgdef,
- name, name_len);
-
- if (f == NULL) {
- rb_raise(rb_eArgError, "Unknown field");
- }
-
- if (setter) {
- if (argc < 2) {
- rb_raise(rb_eArgError, "No value provided to setter.");
- }
- layout_set(self->descriptor->layout, Message_data(self), f, argv[1]);
- return Qnil;
} else {
- return layout_get(self->descriptor->layout, Message_data(self), f);
+ // This is a field -- get or set the field's value.
+ assert(f);
+ if (setter) {
+ if (argc < 2) {
+ rb_raise(rb_eArgError, "No value provided to setter.");
+ }
+ layout_set(self->descriptor->layout, Message_data(self), f, argv[1]);
+ return Qnil;
+ } else {
+ return layout_get(self->descriptor->layout, Message_data(self), f);
+ }
}
}
@@ -197,7 +195,7 @@ int Message_initialize_kwarg(VALUE key, VALUE val, VALUE _self) {
f = upb_msgdef_ntofz(self->descriptor->msgdef, name);
if (f == NULL) {
rb_raise(rb_eArgError,
- "Unknown field name in initialization map entry.");
+ "Unknown field name '%s' in initialization map entry.", name);
}
if (is_map_field(f)) {
@@ -205,7 +203,7 @@ int Message_initialize_kwarg(VALUE key, VALUE val, VALUE _self) {
if (TYPE(val) != T_HASH) {
rb_raise(rb_eArgError,
- "Expected Hash object as initializer value for map field.");
+ "Expected Hash object as initializer value for map field '%s'.", name);
}
map = layout_get(self->descriptor->layout, Message_data(self), f);
Map_merge_into_self(map, val);
@@ -214,7 +212,7 @@ int Message_initialize_kwarg(VALUE key, VALUE val, VALUE _self) {
if (TYPE(val) != T_ARRAY) {
rb_raise(rb_eArgError,
- "Expected array as initializer value for repeated field.");
+ "Expected array as initializer value for repeated field '%s'.", name);
}
ary = layout_get(self->descriptor->layout, Message_data(self), f);
for (int i = 0; i < RARRAY_LEN(val); i++) {
@@ -475,7 +473,7 @@ VALUE build_class_from_descriptor(Descriptor* desc) {
rb_define_singleton_method(klass, "decode", Message_decode, 1);
rb_define_singleton_method(klass, "encode", Message_encode, 1);
rb_define_singleton_method(klass, "decode_json", Message_decode_json, 1);
- rb_define_singleton_method(klass, "encode_json", Message_encode_json, 1);
+ rb_define_singleton_method(klass, "encode_json", Message_encode_json, -1);
rb_define_singleton_method(klass, "descriptor", Message_descriptor, 0);
return klass;
diff --git a/ruby/ext/google/protobuf_c/protobuf.h b/ruby/ext/google/protobuf_c/protobuf.h
index 8750c93d..08b8d516 100644
--- a/ruby/ext/google/protobuf_c/protobuf.h
+++ b/ruby/ext/google/protobuf_c/protobuf.h
@@ -112,8 +112,10 @@ struct Descriptor {
VALUE klass; // begins as nil
const upb_handlers* fill_handlers;
const upb_pbdecodermethod* fill_method;
+ const upb_json_parsermethod* json_fill_method;
const upb_handlers* pb_serialize_handlers;
const upb_handlers* json_serialize_handlers;
+ const upb_handlers* json_serialize_handlers_preserve;
// Handlers hold type class references for sub-message fields directly in some
// cases. We need to keep these rooted because they might otherwise be
// collected.
@@ -311,7 +313,7 @@ void native_slot_dup(upb_fieldtype_t type, void* to, void* from);
void native_slot_deep_copy(upb_fieldtype_t type, void* to, void* from);
bool native_slot_eq(upb_fieldtype_t type, void* mem1, void* mem2);
-void native_slot_validate_string_encoding(upb_fieldtype_t type, VALUE value);
+VALUE native_slot_encode_and_freeze_string(upb_fieldtype_t type, VALUE value);
void native_slot_check_int_range_precision(upb_fieldtype_t type, VALUE value);
extern rb_encoding* kRubyStringUtf8Encoding;
@@ -364,6 +366,7 @@ RepeatedField* ruby_to_RepeatedField(VALUE value);
VALUE RepeatedField_each(VALUE _self);
VALUE RepeatedField_index(int argc, VALUE* argv, VALUE _self);
void* RepeatedField_index_native(VALUE _self, int index);
+int RepeatedField_size(VALUE _self);
VALUE RepeatedField_index_set(VALUE _self, VALUE _index, VALUE val);
void RepeatedField_reserve(RepeatedField* self, int new_size);
VALUE RepeatedField_push(VALUE _self, VALUE val);
@@ -497,7 +500,7 @@ VALUE Message_descriptor(VALUE klass);
VALUE Message_decode(VALUE klass, VALUE data);
VALUE Message_encode(VALUE klass, VALUE msg_rb);
VALUE Message_decode_json(VALUE klass, VALUE data);
-VALUE Message_encode_json(VALUE klass, VALUE msg_rb);
+VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass);
VALUE Google_Protobuf_deep_copy(VALUE self, VALUE obj);
diff --git a/ruby/ext/google/protobuf_c/repeated_field.c b/ruby/ext/google/protobuf_c/repeated_field.c
index 83afbc91..47c207a5 100644
--- a/ruby/ext/google/protobuf_c/repeated_field.c
+++ b/ruby/ext/google/protobuf_c/repeated_field.c
@@ -244,6 +244,11 @@ void* RepeatedField_index_native(VALUE _self, int index) {
return RepeatedField_memoryat(self, index, element_size);
}
+int RepeatedField_size(VALUE _self) {
+ RepeatedField* self = ruby_to_RepeatedField(_self);
+ return self->size;
+}
+
/*
* Private ruby method, used by RepeatedField.pop
*/
diff --git a/ruby/ext/google/protobuf_c/storage.c b/ruby/ext/google/protobuf_c/storage.c
index b1f65f41..3ff2bda6 100644
--- a/ruby/ext/google/protobuf_c/storage.c
+++ b/ruby/ext/google/protobuf_c/storage.c
@@ -57,6 +57,37 @@ size_t native_slot_size(upb_fieldtype_t type) {
}
}
+static VALUE value_from_default(const upb_fielddef *field) {
+ switch (upb_fielddef_type(field)) {
+ case UPB_TYPE_FLOAT: return DBL2NUM(upb_fielddef_defaultfloat(field));
+ case UPB_TYPE_DOUBLE: return DBL2NUM(upb_fielddef_defaultdouble(field));
+ case UPB_TYPE_BOOL:
+ return upb_fielddef_defaultbool(field) ? Qtrue : Qfalse;
+ case UPB_TYPE_MESSAGE: return Qnil;
+ case UPB_TYPE_ENUM: {
+ const upb_enumdef *enumdef = upb_fielddef_enumsubdef(field);
+ int32_t num = upb_fielddef_defaultint32(field);
+ const char *label = upb_enumdef_iton(enumdef, num);
+ if (label) {
+ return ID2SYM(rb_intern(label));
+ } else {
+ return INT2NUM(num);
+ }
+ }
+ case UPB_TYPE_INT32: return INT2NUM(upb_fielddef_defaultint32(field));
+ case UPB_TYPE_INT64: return LL2NUM(upb_fielddef_defaultint64(field));;
+ case UPB_TYPE_UINT32: return UINT2NUM(upb_fielddef_defaultuint32(field));
+ case UPB_TYPE_UINT64: return ULL2NUM(upb_fielddef_defaultuint64(field));
+ case UPB_TYPE_STRING:
+ case UPB_TYPE_BYTES: {
+ size_t size;
+ const char *str = upb_fielddef_defaultstr(field, &size);
+ return rb_str_new(str, size);
+ }
+ default: return Qnil;
+ }
+}
+
static bool is_ruby_num(VALUE value) {
return (TYPE(value) == T_FLOAT ||
TYPE(value) == T_FIXNUM ||
@@ -86,25 +117,24 @@ void native_slot_check_int_range_precision(upb_fieldtype_t type, VALUE val) {
}
}
-void native_slot_validate_string_encoding(upb_fieldtype_t type, VALUE value) {
- bool bad_encoding = false;
- rb_encoding* string_encoding = rb_enc_from_index(ENCODING_GET(value));
- if (type == UPB_TYPE_STRING) {
- bad_encoding =
- string_encoding != kRubyStringUtf8Encoding &&
- string_encoding != kRubyStringASCIIEncoding;
- } else {
- bad_encoding =
- string_encoding != kRubyString8bitEncoding;
- }
- // Check that encoding is UTF-8 or ASCII (for string fields) or ASCII-8BIT
- // (for bytes fields).
- if (bad_encoding) {
- rb_raise(rb_eTypeError, "Encoding for '%s' fields must be %s (was %s)",
- (type == UPB_TYPE_STRING) ? "string" : "bytes",
- (type == UPB_TYPE_STRING) ? "UTF-8 or ASCII" : "ASCII-8BIT",
- rb_enc_name(string_encoding));
+VALUE native_slot_encode_and_freeze_string(upb_fieldtype_t type, VALUE value) {
+ rb_encoding* desired_encoding = (type == UPB_TYPE_STRING) ?
+ kRubyStringUtf8Encoding : kRubyString8bitEncoding;
+ VALUE desired_encoding_value = rb_enc_from_encoding(desired_encoding);
+
+ // Note: this will not duplicate underlying string data unless necessary.
+ value = rb_str_encode(value, desired_encoding_value, 0, Qnil);
+
+ if (type == UPB_TYPE_STRING &&
+ rb_enc_str_coderange(value) == ENC_CODERANGE_BROKEN) {
+ rb_raise(rb_eEncodingError, "String is invalid UTF-8");
}
+
+ // Ensure the data remains valid. Since we called #encode a moment ago,
+ // this does not freeze the string the user assigned.
+ rb_obj_freeze(value);
+
+ return value;
}
void native_slot_set(upb_fieldtype_t type, VALUE type_class,
@@ -150,8 +180,8 @@ void native_slot_set_value_and_case(upb_fieldtype_t type, VALUE type_class,
if (CLASS_OF(value) != rb_cString) {
rb_raise(rb_eTypeError, "Invalid argument for string field.");
}
- native_slot_validate_string_encoding(type, value);
- DEREF(memory, VALUE) = value;
+
+ DEREF(memory, VALUE) = native_slot_encode_and_freeze_string(type, value);
break;
}
case UPB_TYPE_MESSAGE: {
@@ -537,7 +567,7 @@ VALUE layout_get(MessageLayout* layout,
if (upb_fielddef_containingoneof(field)) {
if (*oneof_case != upb_fielddef_number(field)) {
- return Qnil;
+ return value_from_default(field);
}
return native_slot_get(upb_fielddef_type(field),
field_type_class(field),
diff --git a/ruby/ext/google/protobuf_c/upb.c b/ruby/ext/google/protobuf_c/upb.c
index 048a163a..976a3934 100644
--- a/ruby/ext/google/protobuf_c/upb.c
+++ b/ruby/ext/google/protobuf_c/upb.c
@@ -2,6 +2,7 @@
#include "upb.h"
+#include <ctype.h>
#include <stdlib.h>
#include <string.h>
@@ -11,7 +12,7 @@ typedef struct {
} str_t;
static str_t *newstr(const char *data, size_t len) {
- str_t *ret = malloc(sizeof(*ret) + len);
+ str_t *ret = upb_gmalloc(sizeof(*ret) + len);
if (!ret) return NULL;
ret->len = len;
memcpy(ret->str, data, len);
@@ -19,7 +20,7 @@ static str_t *newstr(const char *data, size_t len) {
return ret;
}
-static void freestr(str_t *s) { free(s); }
+static void freestr(str_t *s) { upb_gfree(s); }
/* isalpha() etc. from <ctype.h> are locale-dependent, which we don't want. */
static bool upb_isbetween(char c, char low, char high) {
@@ -64,6 +65,22 @@ static bool upb_isident(const char *str, size_t len, bool full, upb_status *s) {
return !start;
}
+static bool upb_isoneof(const upb_refcounted *def) {
+ return def->vtbl == &upb_oneofdef_vtbl;
+}
+
+static bool upb_isfield(const upb_refcounted *def) {
+ return def->vtbl == &upb_fielddef_vtbl;
+}
+
+static const upb_oneofdef *upb_trygetoneof(const upb_refcounted *def) {
+ return upb_isoneof(def) ? (const upb_oneofdef*)def : NULL;
+}
+
+static const upb_fielddef *upb_trygetfield(const upb_refcounted *def) {
+ return upb_isfield(def) ? (const upb_fielddef*)def : NULL;
+}
+
/* upb_def ********************************************************************/
@@ -71,14 +88,39 @@ upb_deftype_t upb_def_type(const upb_def *d) { return d->type; }
const char *upb_def_fullname(const upb_def *d) { return d->fullname; }
+const char *upb_def_name(const upb_def *d) {
+ const char *p;
+
+ if (d->fullname == NULL) {
+ return NULL;
+ } else if ((p = strrchr(d->fullname, '.')) == NULL) {
+ /* No '.' in the name, return the full string. */
+ return d->fullname;
+ } else {
+ /* Return one past the last '.'. */
+ return p + 1;
+ }
+}
+
bool upb_def_setfullname(upb_def *def, const char *fullname, upb_status *s) {
assert(!upb_def_isfrozen(def));
- if (!upb_isident(fullname, strlen(fullname), true, s)) return false;
- free((void*)def->fullname);
- def->fullname = upb_strdup(fullname);
+ if (!upb_isident(fullname, strlen(fullname), true, s)) {
+ return false;
+ }
+
+ fullname = upb_gstrdup(fullname);
+ if (!fullname) {
+ upb_upberr_setoom(s);
+ return false;
+ }
+
+ upb_gfree((void*)def->fullname);
+ def->fullname = fullname;
return true;
}
+const upb_filedef *upb_def_file(const upb_def *d) { return d->file; }
+
upb_def *upb_def_dup(const upb_def *def, const void *o) {
switch (def->type) {
case UPB_DEF_MSG:
@@ -101,11 +143,12 @@ static bool upb_def_init(upb_def *def, upb_deftype_t type,
def->type = type;
def->fullname = NULL;
def->came_from_user = false;
+ def->file = NULL;
return true;
}
static void upb_def_uninit(upb_def *def) {
- free((void*)def->fullname);
+ upb_gfree((void*)def->fullname);
}
static const char *msgdef_name(const upb_msgdef *m) {
@@ -242,8 +285,19 @@ static bool assign_msg_indices(upb_msgdef *m, upb_status *s) {
int i;
uint32_t selector;
int n = upb_msgdef_numfields(m);
- upb_fielddef **fields = malloc(n * sizeof(*fields));
- if (!fields) return false;
+ upb_fielddef **fields;
+
+ if (n == 0) {
+ m->selector_count = UPB_STATIC_SELECTOR_COUNT;
+ m->submsg_field_count = 0;
+ return true;
+ }
+
+ fields = upb_gmalloc(n * sizeof(*fields));
+ if (!fields) {
+ upb_upberr_setoom(s);
+ return false;
+ }
m->submsg_field_count = 0;
for(i = 0, upb_msg_field_begin(&j, m);
@@ -252,7 +306,7 @@ static bool assign_msg_indices(upb_msgdef *m, upb_status *s) {
upb_fielddef *f = upb_msg_iter_field(&j);
assert(f->msg.def == m);
if (!upb_validate_field(f, s)) {
- free(fields);
+ upb_gfree(fields);
return false;
}
if (upb_fielddef_issubmsg(f)) {
@@ -312,15 +366,12 @@ static bool assign_msg_indices(upb_msgdef *m, upb_status *s) {
#undef TRY
#endif
- free(fields);
+ upb_gfree(fields);
return true;
}
-bool upb_def_freeze(upb_def *const* defs, int n, upb_status *s) {
- int i;
- int maxdepth;
- bool ret;
- upb_status_clear(s);
+bool _upb_def_validate(upb_def *const*defs, size_t n, upb_status *s) {
+ size_t i;
/* First perform validation, in two passes so we can check that we have a
* transitive closure without needing to search. */
@@ -346,8 +397,9 @@ bool upb_def_freeze(upb_def *const* defs, int n, upb_status *s) {
/* Second pass of validation. Also assign selector bases and indexes, and
* compact tables. */
for (i = 0; i < n; i++) {
- upb_msgdef *m = upb_dyncast_msgdef_mutable(defs[i]);
- upb_enumdef *e = upb_dyncast_enumdef_mutable(defs[i]);
+ upb_def *def = defs[i];
+ upb_msgdef *m = upb_dyncast_msgdef_mutable(def);
+ upb_enumdef *e = upb_dyncast_enumdef_mutable(def);
if (m) {
upb_inttable_compact(&m->itof);
if (!assign_msg_indices(m, s)) {
@@ -358,23 +410,31 @@ bool upb_def_freeze(upb_def *const* defs, int n, upb_status *s) {
}
}
- /* Def graph contains FieldDefs between each MessageDef, so double the
- * limit. */
- maxdepth = UPB_MAX_MESSAGE_DEPTH * 2;
-
- /* Validation all passed; freeze the defs. */
- ret = upb_refcounted_freeze((upb_refcounted * const *)defs, n, s, maxdepth);
- assert(!(s && ret != upb_ok(s)));
- return ret;
+ return true;
err:
for (i = 0; i < n; i++) {
- defs[i]->came_from_user = false;
+ upb_def *def = defs[i];
+ def->came_from_user = false;
}
assert(!(s && upb_ok(s)));
return false;
}
+bool upb_def_freeze(upb_def *const* defs, size_t n, upb_status *s) {
+ /* Def graph contains FieldDefs between each MessageDef, so double the
+ * limit. */
+ const size_t maxdepth = UPB_MAX_MESSAGE_DEPTH * 2;
+
+ if (!_upb_def_validate(defs, n, s)) {
+ return false;
+ }
+
+
+ /* Validation all passed; freeze the objects. */
+ return upb_refcounted_freeze((upb_refcounted *const*)defs, n, s, maxdepth);
+}
+
/* upb_enumdef ****************************************************************/
@@ -383,21 +443,26 @@ static void upb_enumdef_free(upb_refcounted *r) {
upb_inttable_iter i;
upb_inttable_begin(&i, &e->iton);
for( ; !upb_inttable_done(&i); upb_inttable_next(&i)) {
- /* To clean up the upb_strdup() from upb_enumdef_addval(). */
- free(upb_value_getcstr(upb_inttable_iter_value(&i)));
+ /* To clean up the upb_gstrdup() from upb_enumdef_addval(). */
+ upb_gfree(upb_value_getcstr(upb_inttable_iter_value(&i)));
}
upb_strtable_uninit(&e->ntoi);
upb_inttable_uninit(&e->iton);
upb_def_uninit(upb_enumdef_upcast_mutable(e));
- free(e);
+ upb_gfree(e);
}
+const struct upb_refcounted_vtbl upb_enumdef_vtbl = {NULL, &upb_enumdef_free};
+
upb_enumdef *upb_enumdef_new(const void *owner) {
- static const struct upb_refcounted_vtbl vtbl = {NULL, &upb_enumdef_free};
- upb_enumdef *e = malloc(sizeof(*e));
+ upb_enumdef *e = upb_gmalloc(sizeof(*e));
if (!e) return NULL;
- if (!upb_def_init(upb_enumdef_upcast_mutable(e), UPB_DEF_ENUM, &vtbl, owner))
+
+ if (!upb_def_init(upb_enumdef_upcast_mutable(e), UPB_DEF_ENUM,
+ &upb_enumdef_vtbl, owner)) {
goto err2;
+ }
+
if (!upb_strtable_init(&e->ntoi, UPB_CTYPE_INT32)) goto err2;
if (!upb_inttable_init(&e->iton, UPB_CTYPE_CSTR)) goto err1;
return e;
@@ -405,7 +470,7 @@ upb_enumdef *upb_enumdef_new(const void *owner) {
err1:
upb_strtable_uninit(&e->ntoi);
err2:
- free(e);
+ upb_gfree(e);
return NULL;
}
@@ -433,6 +498,10 @@ const char *upb_enumdef_fullname(const upb_enumdef *e) {
return upb_def_fullname(upb_enumdef_upcast(e));
}
+const char *upb_enumdef_name(const upb_enumdef *e) {
+ return upb_def_name(upb_enumdef_upcast(e));
+}
+
bool upb_enumdef_setfullname(upb_enumdef *e, const char *fullname,
upb_status *s) {
return upb_def_setfullname(upb_enumdef_upcast_mutable(e), fullname, s);
@@ -440,27 +509,36 @@ bool upb_enumdef_setfullname(upb_enumdef *e, const char *fullname,
bool upb_enumdef_addval(upb_enumdef *e, const char *name, int32_t num,
upb_status *status) {
+ char *name2;
+
if (!upb_isident(name, strlen(name), false, status)) {
return false;
}
+
if (upb_enumdef_ntoiz(e, name, NULL)) {
upb_status_seterrf(status, "name '%s' is already defined", name);
return false;
}
+
if (!upb_strtable_insert(&e->ntoi, name, upb_value_int32(num))) {
upb_status_seterrmsg(status, "out of memory");
return false;
}
- if (!upb_inttable_lookup(&e->iton, num, NULL) &&
- !upb_inttable_insert(&e->iton, num, upb_value_cstr(upb_strdup(name)))) {
- upb_status_seterrmsg(status, "out of memory");
- upb_strtable_remove(&e->ntoi, name, NULL);
- return false;
+
+ if (!upb_inttable_lookup(&e->iton, num, NULL)) {
+ name2 = upb_gstrdup(name);
+ if (!name2 || !upb_inttable_insert(&e->iton, num, upb_value_cstr(name2))) {
+ upb_status_seterrmsg(status, "out of memory");
+ upb_strtable_remove(&e->ntoi, name, NULL);
+ return false;
+ }
}
+
if (upb_enumdef_numvals(e) == 1) {
bool ok = upb_enumdef_setdefault(e, num, NULL);
UPB_ASSERT_VAR(ok, ok);
}
+
return true;
}
@@ -525,6 +603,10 @@ static void upb_fielddef_uninit_default(upb_fielddef *f) {
freestr(f->defaultval.bytes);
}
+const char *upb_fielddef_fullname(const upb_fielddef *e) {
+ return upb_def_fullname(upb_fielddef_upcast(e));
+}
+
static void visitfield(const upb_refcounted *r, upb_refcounted_visit *visit,
void *closure) {
const upb_fielddef *f = (const upb_fielddef*)r;
@@ -532,7 +614,7 @@ static void visitfield(const upb_refcounted *r, upb_refcounted_visit *visit,
visit(r, upb_msgdef_upcast2(upb_fielddef_containingtype(f)), closure);
}
if (upb_fielddef_containingoneof(f)) {
- visit(r, upb_oneofdef_upcast2(upb_fielddef_containingoneof(f)), closure);
+ visit(r, upb_oneofdef_upcast(upb_fielddef_containingoneof(f)), closure);
}
if (upb_fielddef_subdef(f)) {
visit(r, upb_def_upcast(upb_fielddef_subdef(f)), closure);
@@ -543,9 +625,9 @@ static void freefield(upb_refcounted *r) {
upb_fielddef *f = (upb_fielddef*)r;
upb_fielddef_uninit_default(f);
if (f->subdef_is_symbolic)
- free(f->sub.name);
+ upb_gfree(f->sub.name);
upb_def_uninit(upb_fielddef_upcast_mutable(f));
- free(f);
+ upb_gfree(f);
}
static const char *enumdefaultstr(const upb_fielddef *f) {
@@ -601,12 +683,14 @@ static bool enumdefaultint32(const upb_fielddef *f, int32_t *val) {
return false;
}
+const struct upb_refcounted_vtbl upb_fielddef_vtbl = {visitfield, freefield};
+
upb_fielddef *upb_fielddef_new(const void *o) {
- static const struct upb_refcounted_vtbl vtbl = {visitfield, freefield};
- upb_fielddef *f = malloc(sizeof(*f));
+ upb_fielddef *f = upb_gmalloc(sizeof(*f));
if (!f) return NULL;
- if (!upb_def_init(upb_fielddef_upcast_mutable(f), UPB_DEF_FIELD, &vtbl, o)) {
- free(f);
+ if (!upb_def_init(upb_fielddef_upcast_mutable(f), UPB_DEF_FIELD,
+ &upb_fielddef_vtbl, o)) {
+ upb_gfree(f);
return NULL;
}
f->msg.def = NULL;
@@ -657,7 +741,7 @@ upb_fielddef *upb_fielddef_dup(const upb_fielddef *f, const void *owner) {
srcname = f->sub.def ? upb_def_fullname(f->sub.def) : NULL;
}
if (srcname) {
- char *newname = malloc(strlen(f->sub.def->fullname) + 2);
+ char *newname = upb_gmalloc(strlen(f->sub.def->fullname) + 2);
if (!newname) {
upb_fielddef_unref(newf, owner);
return NULL;
@@ -665,7 +749,7 @@ upb_fielddef *upb_fielddef_dup(const upb_fielddef *f, const void *owner) {
strcpy(newname, ".");
strcat(newname, f->sub.def->fullname);
upb_fielddef_setsubdefname(newf, newname, NULL);
- free(newname);
+ upb_gfree(newname);
}
return newf;
@@ -716,6 +800,45 @@ const char *upb_fielddef_name(const upb_fielddef *f) {
return upb_def_fullname(upb_fielddef_upcast(f));
}
+size_t upb_fielddef_getjsonname(const upb_fielddef *f, char *buf, size_t len) {
+ const char *name = upb_fielddef_name(f);
+ size_t src, dst = 0;
+ bool ucase_next = false;
+
+#define WRITE(byte) \
+ ++dst; \
+ if (dst < len) buf[dst - 1] = byte; \
+ else if (dst == len) buf[dst - 1] = '\0'
+
+ if (!name) {
+ WRITE('\0');
+ return 0;
+ }
+
+ /* Implement the transformation as described in the spec:
+ * 1. upper case all letters after an underscore.
+ * 2. remove all underscores.
+ */
+ for (src = 0; name[src]; src++) {
+ if (name[src] == '_') {
+ ucase_next = true;
+ continue;
+ }
+
+ if (ucase_next) {
+ WRITE(toupper(name[src]));
+ ucase_next = false;
+ } else {
+ WRITE(name[src]);
+ }
+ }
+
+ WRITE('\0');
+ return dst;
+
+#undef WRITE
+}
+
const upb_msgdef *upb_fielddef_containingtype(const upb_fielddef *f) {
return f->msg_is_symbolic ? NULL : f->msg.def;
}
@@ -733,11 +856,12 @@ const char *upb_fielddef_containingtypename(upb_fielddef *f) {
}
static void release_containingtype(upb_fielddef *f) {
- if (f->msg_is_symbolic) free(f->msg.name);
+ if (f->msg_is_symbolic) upb_gfree(f->msg.name);
}
bool upb_fielddef_setcontainingtypename(upb_fielddef *f, const char *name,
upb_status *s) {
+ char *name_copy;
assert(!upb_fielddef_isfrozen(f));
if (upb_fielddef_containingtype(f)) {
upb_status_seterrmsg(s, "field has already been added to a message.");
@@ -745,8 +869,15 @@ bool upb_fielddef_setcontainingtypename(upb_fielddef *f, const char *name,
}
/* TODO: validate name (upb_isident() doesn't quite work atm because this name
* may have a leading "."). */
+
+ name_copy = upb_gstrdup(name);
+ if (!name_copy) {
+ upb_upberr_setoom(s);
+ return false;
+ }
+
release_containingtype(f);
- f->msg.name = upb_strdup(name);
+ f->msg.name = name_copy;
f->msg_is_symbolic = true;
return true;
}
@@ -1147,7 +1278,7 @@ static bool upb_subdef_typecheck(upb_fielddef *f, const upb_def *subdef,
static void release_subdef(upb_fielddef *f) {
if (f->subdef_is_symbolic) {
- free(f->sub.name);
+ upb_gfree(f->sub.name);
} else if (f->sub.def) {
upb_unref2(f->sub.def, f);
}
@@ -1177,15 +1308,23 @@ bool upb_fielddef_setenumsubdef(upb_fielddef *f, const upb_enumdef *subdef,
bool upb_fielddef_setsubdefname(upb_fielddef *f, const char *name,
upb_status *s) {
+ char *name_copy;
assert(!upb_fielddef_isfrozen(f));
if (!upb_fielddef_hassubdef(f)) {
upb_status_seterrmsg(s, "field type does not accept a subdef");
return false;
}
+
+ name_copy = upb_gstrdup(name);
+ if (!name_copy) {
+ upb_upberr_setoom(s);
+ return false;
+ }
+
/* TODO: validate name (upb_isident() doesn't quite work atm because this name
* may have a leading "."). */
release_subdef(f);
- f->sub.name = upb_strdup(name);
+ f->sub.name = name_copy;
f->subdef_is_symbolic = true;
return true;
}
@@ -1212,6 +1351,16 @@ bool upb_fielddef_ismap(const upb_fielddef *f) {
upb_msgdef_mapentry(upb_fielddef_msgsubdef(f));
}
+bool upb_fielddef_haspresence(const upb_fielddef *f) {
+ if (upb_fielddef_isseq(f)) return false;
+ if (upb_fielddef_issubmsg(f)) return true;
+
+ /* Primitive field: return true unless there is a message that specifies
+ * presence should not exist. */
+ if (f->msg_is_symbolic || !f->msg.def) return true;
+ return f->msg.def->syntax == UPB_SYNTAX_PROTO2;
+}
+
bool upb_fielddef_hassubdef(const upb_fielddef *f) {
return upb_fielddef_issubmsg(f) || upb_fielddef_type(f) == UPB_TYPE_ENUM;
}
@@ -1245,37 +1394,39 @@ static void visitmsg(const upb_refcounted *r, upb_refcounted_visit *visit,
!upb_msg_oneof_done(&o);
upb_msg_oneof_next(&o)) {
upb_oneofdef *f = upb_msg_iter_oneof(&o);
- visit(r, upb_oneofdef_upcast2(f), closure);
+ visit(r, upb_oneofdef_upcast(f), closure);
}
}
static void freemsg(upb_refcounted *r) {
upb_msgdef *m = (upb_msgdef*)r;
- upb_strtable_uninit(&m->ntoo);
upb_strtable_uninit(&m->ntof);
upb_inttable_uninit(&m->itof);
upb_def_uninit(upb_msgdef_upcast_mutable(m));
- free(m);
+ upb_gfree(m);
}
+const struct upb_refcounted_vtbl upb_msgdef_vtbl = {visitmsg, freemsg};
+
upb_msgdef *upb_msgdef_new(const void *owner) {
- static const struct upb_refcounted_vtbl vtbl = {visitmsg, freemsg};
- upb_msgdef *m = malloc(sizeof(*m));
+ upb_msgdef *m = upb_gmalloc(sizeof(*m));
if (!m) return NULL;
- if (!upb_def_init(upb_msgdef_upcast_mutable(m), UPB_DEF_MSG, &vtbl, owner))
+
+ if (!upb_def_init(upb_msgdef_upcast_mutable(m), UPB_DEF_MSG, &upb_msgdef_vtbl,
+ owner)) {
goto err2;
- if (!upb_inttable_init(&m->itof, UPB_CTYPE_PTR)) goto err3;
- if (!upb_strtable_init(&m->ntof, UPB_CTYPE_PTR)) goto err2;
- if (!upb_strtable_init(&m->ntoo, UPB_CTYPE_PTR)) goto err1;
+ }
+
+ if (!upb_inttable_init(&m->itof, UPB_CTYPE_PTR)) goto err2;
+ if (!upb_strtable_init(&m->ntof, UPB_CTYPE_PTR)) goto err1;
m->map_entry = false;
+ m->syntax = UPB_SYNTAX_PROTO2;
return m;
err1:
- upb_strtable_uninit(&m->ntof);
-err2:
upb_inttable_uninit(&m->itof);
-err3:
- free(m);
+err2:
+ upb_gfree(m);
return NULL;
}
@@ -1290,6 +1441,7 @@ upb_msgdef *upb_msgdef_dup(const upb_msgdef *m, const void *owner) {
upb_def_fullname(upb_msgdef_upcast(m)),
NULL);
newm->map_entry = m->map_entry;
+ newm->syntax = m->syntax;
UPB_ASSERT_VAR(ok, ok);
for(upb_msg_field_begin(&i, m);
!upb_msg_field_done(&i);
@@ -1323,11 +1475,28 @@ const char *upb_msgdef_fullname(const upb_msgdef *m) {
return upb_def_fullname(upb_msgdef_upcast(m));
}
+const char *upb_msgdef_name(const upb_msgdef *m) {
+ return upb_def_name(upb_msgdef_upcast(m));
+}
+
bool upb_msgdef_setfullname(upb_msgdef *m, const char *fullname,
upb_status *s) {
return upb_def_setfullname(upb_msgdef_upcast_mutable(m), fullname, s);
}
+bool upb_msgdef_setsyntax(upb_msgdef *m, upb_syntax_t syntax) {
+ if (syntax != UPB_SYNTAX_PROTO2 && syntax != UPB_SYNTAX_PROTO3) {
+ return false;
+ }
+
+ m->syntax = syntax;
+ return true;
+}
+
+upb_syntax_t upb_msgdef_syntax(const upb_msgdef *m) {
+ return m->syntax;
+}
+
/* Helper: check that the field |f| is safe to add to msgdef |m|. Set an error
* on status |s| and return false if not. */
static bool check_field_add(const upb_msgdef *m, const upb_fielddef *f,
@@ -1338,9 +1507,11 @@ static bool check_field_add(const upb_msgdef *m, const upb_fielddef *f,
} else if (upb_fielddef_name(f) == NULL || upb_fielddef_number(f) == 0) {
upb_status_seterrmsg(s, "field name or number were not set");
return false;
- } else if (upb_msgdef_ntofz(m, upb_fielddef_name(f)) ||
- upb_msgdef_itof(m, upb_fielddef_number(f))) {
- upb_status_seterrmsg(s, "duplicate field name or number for field");
+ } else if (upb_msgdef_itof(m, upb_fielddef_number(f))) {
+ upb_status_seterrmsg(s, "duplicate field number");
+ return false;
+ } else if (upb_strtable_lookup(&m->ntof, upb_fielddef_name(f), NULL)) {
+ upb_status_seterrmsg(s, "name conflicts with existing field or oneof");
return false;
}
return true;
@@ -1401,8 +1572,8 @@ bool upb_msgdef_addoneof(upb_msgdef *m, upb_oneofdef *o, const void *ref_donor,
} else if (upb_oneofdef_name(o) == NULL) {
upb_status_seterrmsg(s, "oneofdef name was not set");
return false;
- } else if (upb_msgdef_ntooz(m, upb_oneofdef_name(o))) {
- upb_status_seterrmsg(s, "duplicate oneof name");
+ } else if (upb_strtable_lookup(&m->ntof, upb_oneofdef_name(o), NULL)) {
+ upb_status_seterrmsg(s, "name conflicts with existing field or oneof");
return false;
}
@@ -1419,7 +1590,7 @@ bool upb_msgdef_addoneof(upb_msgdef *m, upb_oneofdef *o, const void *ref_donor,
/* Add oneof itself first. */
o->parent = m;
- upb_strtable_insert(&m->ntoo, upb_oneofdef_name(o), upb_value_ptr(o));
+ upb_strtable_insert(&m->ntof, upb_oneofdef_name(o), upb_value_ptr(o));
upb_ref2(o, m);
upb_ref2(m, o);
@@ -1443,23 +1614,47 @@ const upb_fielddef *upb_msgdef_itof(const upb_msgdef *m, uint32_t i) {
const upb_fielddef *upb_msgdef_ntof(const upb_msgdef *m, const char *name,
size_t len) {
upb_value val;
- return upb_strtable_lookup2(&m->ntof, name, len, &val) ?
- upb_value_getptr(val) : NULL;
+
+ if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) {
+ return NULL;
+ }
+
+ return upb_trygetfield(upb_value_getptr(val));
}
const upb_oneofdef *upb_msgdef_ntoo(const upb_msgdef *m, const char *name,
size_t len) {
upb_value val;
- return upb_strtable_lookup2(&m->ntoo, name, len, &val) ?
- upb_value_getptr(val) : NULL;
+
+ if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) {
+ return NULL;
+ }
+
+ return upb_trygetoneof(upb_value_getptr(val));
+}
+
+bool upb_msgdef_lookupname(const upb_msgdef *m, const char *name, size_t len,
+ const upb_fielddef **f, const upb_oneofdef **o) {
+ upb_value val;
+
+ if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) {
+ return false;
+ }
+
+ *o = upb_trygetoneof(upb_value_getptr(val));
+ *f = upb_trygetfield(upb_value_getptr(val));
+ assert((*o != NULL) ^ (*f != NULL)); /* Exactly one of the two should be set. */
+ return true;
}
int upb_msgdef_numfields(const upb_msgdef *m) {
- return upb_strtable_count(&m->ntof);
+ /* The number table contains only fields. */
+ return upb_inttable_count(&m->itof);
}
int upb_msgdef_numoneofs(const upb_msgdef *m) {
- return upb_strtable_count(&m->ntoo);
+ /* The name table includes oneofs, and the number table does not. */
+ return upb_strtable_count(&m->ntof) - upb_inttable_count(&m->itof);
}
void upb_msgdef_setmapentry(upb_msgdef *m, bool map_entry) {
@@ -1490,10 +1685,21 @@ void upb_msg_field_iter_setdone(upb_msg_field_iter *iter) {
}
void upb_msg_oneof_begin(upb_msg_oneof_iter *iter, const upb_msgdef *m) {
- upb_strtable_begin(iter, &m->ntoo);
+ upb_strtable_begin(iter, &m->ntof);
+ /* We need to skip past any initial fields. */
+ while (!upb_strtable_done(iter) &&
+ !upb_isoneof(upb_value_getptr(upb_strtable_iter_value(iter)))) {
+ upb_strtable_next(iter);
+ }
}
-void upb_msg_oneof_next(upb_msg_oneof_iter *iter) { upb_strtable_next(iter); }
+void upb_msg_oneof_next(upb_msg_oneof_iter *iter) {
+ /* We need to skip past fields to return only oneofs. */
+ do {
+ upb_strtable_next(iter);
+ } while (!upb_strtable_done(iter) &&
+ !upb_isoneof(upb_value_getptr(upb_strtable_iter_value(iter))));
+}
bool upb_msg_oneof_done(const upb_msg_oneof_iter *iter) {
return upb_strtable_done(iter);
@@ -1526,26 +1732,36 @@ static void freeoneof(upb_refcounted *r) {
upb_oneofdef *o = (upb_oneofdef*)r;
upb_strtable_uninit(&o->ntof);
upb_inttable_uninit(&o->itof);
- upb_def_uninit(upb_oneofdef_upcast_mutable(o));
- free(o);
+ upb_gfree((void*)o->name);
+ upb_gfree(o);
}
+const struct upb_refcounted_vtbl upb_oneofdef_vtbl = {visitoneof, freeoneof};
+
upb_oneofdef *upb_oneofdef_new(const void *owner) {
- static const struct upb_refcounted_vtbl vtbl = {visitoneof, freeoneof};
- upb_oneofdef *o = malloc(sizeof(*o));
+ upb_oneofdef *o = upb_gmalloc(sizeof(*o));
+
+ if (!o) {
+ return NULL;
+ }
+
o->parent = NULL;
- if (!o) return NULL;
- if (!upb_def_init(upb_oneofdef_upcast_mutable(o), UPB_DEF_ONEOF, &vtbl,
- owner))
+ o->name = NULL;
+
+ if (!upb_refcounted_init(upb_oneofdef_upcast_mutable(o), &upb_oneofdef_vtbl,
+ owner)) {
goto err2;
+ }
+
if (!upb_inttable_init(&o->itof, UPB_CTYPE_PTR)) goto err2;
if (!upb_strtable_init(&o->ntof, UPB_CTYPE_PTR)) goto err1;
+
return o;
err1:
upb_inttable_uninit(&o->itof);
err2:
- free(o);
+ upb_gfree(o);
return NULL;
}
@@ -1554,8 +1770,7 @@ upb_oneofdef *upb_oneofdef_dup(const upb_oneofdef *o, const void *owner) {
upb_oneof_iter i;
upb_oneofdef *newo = upb_oneofdef_new(owner);
if (!newo) return NULL;
- ok = upb_def_setfullname(upb_oneofdef_upcast_mutable(newo),
- upb_def_fullname(upb_oneofdef_upcast(o)), NULL);
+ ok = upb_oneofdef_setname(newo, upb_oneofdef_name(o), NULL);
UPB_ASSERT_VAR(ok, ok);
for (upb_oneof_begin(&i, o); !upb_oneof_done(&i); upb_oneof_next(&i)) {
upb_fielddef *f = upb_fielddef_dup(upb_oneof_iter_field(&i), &f);
@@ -1567,17 +1782,28 @@ upb_oneofdef *upb_oneofdef_dup(const upb_oneofdef *o, const void *owner) {
return newo;
}
-const char *upb_oneofdef_name(const upb_oneofdef *o) {
- return upb_def_fullname(upb_oneofdef_upcast(o));
-}
+const char *upb_oneofdef_name(const upb_oneofdef *o) { return o->name; }
-bool upb_oneofdef_setname(upb_oneofdef *o, const char *fullname,
- upb_status *s) {
+bool upb_oneofdef_setname(upb_oneofdef *o, const char *name, upb_status *s) {
+ assert(!upb_oneofdef_isfrozen(o));
if (upb_oneofdef_containingtype(o)) {
upb_status_seterrmsg(s, "oneof already added to a message");
return false;
}
- return upb_def_setfullname(upb_oneofdef_upcast_mutable(o), fullname, s);
+
+ if (!upb_isident(name, strlen(name), true, s)) {
+ return false;
+ }
+
+ name = upb_gstrdup(name);
+ if (!name) {
+ upb_status_seterrmsg(s, "One of memory");
+ return false;
+ }
+
+ upb_gfree((void*)o->name);
+ o->name = name;
+ return true;
}
const upb_msgdef *upb_oneofdef_containingtype(const upb_oneofdef *o) {
@@ -1696,276 +1922,191 @@ void upb_oneof_iter_setdone(upb_oneof_iter *iter) {
upb_inttable_iter_setdone(iter);
}
+/* upb_filedef ****************************************************************/
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-typedef struct cleanup_ent {
- upb_cleanup_func *cleanup;
- void *ud;
- struct cleanup_ent *next;
-} cleanup_ent;
-
-static void *seeded_alloc(void *ud, void *ptr, size_t oldsize, size_t size);
-
-/* Default allocator **********************************************************/
-
-/* Just use realloc, keeping all allocated blocks in a linked list to destroy at
- * the end. */
-
-typedef struct mem_block {
- /* List is doubly-linked, because in cases where realloc() moves an existing
- * block, we need to be able to remove the old pointer from the list
- * efficiently. */
- struct mem_block *prev, *next;
-#ifndef NDEBUG
- size_t size; /* Doesn't include mem_block structure. */
-#endif
-} mem_block;
-
-typedef struct {
- mem_block *head;
-} default_alloc_ud;
-
-static void *default_alloc(void *_ud, void *ptr, size_t oldsize, size_t size) {
- default_alloc_ud *ud = _ud;
- mem_block *from, *block;
- void *ret;
- UPB_UNUSED(oldsize);
-
- from = ptr ? (void*)((char*)ptr - sizeof(mem_block)) : NULL;
-
-#ifndef NDEBUG
- if (from) {
- assert(oldsize <= from->size);
- }
-#endif
-
- /* TODO(haberman): we probably need to provide even better alignment here,
- * like 16-byte alignment of the returned data pointer. */
- block = realloc(from, size + sizeof(mem_block));
- if (!block) return NULL;
- ret = (char*)block + sizeof(*block);
-
-#ifndef NDEBUG
- block->size = size;
-#endif
+static void visitfiledef(const upb_refcounted *r, upb_refcounted_visit *visit,
+ void *closure) {
+ const upb_filedef *f = (const upb_filedef*)r;
+ size_t i;
- if (from) {
- if (block != from) {
- /* The block was moved, so pointers in next and prev blocks must be
- * updated to its new location. */
- if (block->next) block->next->prev = block;
- if (block->prev) block->prev->next = block;
- if (ud->head == from) ud->head = block;
- }
- } else {
- /* Insert at head of linked list. */
- block->prev = NULL;
- block->next = ud->head;
- if (block->next) block->next->prev = block;
- ud->head = block;
+ for(i = 0; i < upb_filedef_defcount(f); i++) {
+ visit(r, upb_def_upcast(upb_filedef_def(f, i)), closure);
}
-
- return ret;
}
-static void default_alloc_cleanup(void *_ud) {
- default_alloc_ud *ud = _ud;
- mem_block *block = ud->head;
+static void freefiledef(upb_refcounted *r) {
+ upb_filedef *f = (upb_filedef*)r;
+ size_t i;
- while (block) {
- void *to_free = block;
- block = block->next;
- free(to_free);
+ for(i = 0; i < upb_filedef_depcount(f); i++) {
+ upb_filedef_unref(upb_filedef_dep(f, i), f);
}
+
+ upb_inttable_uninit(&f->defs);
+ upb_inttable_uninit(&f->deps);
+ upb_gfree((void*)f->name);
+ upb_gfree((void*)f->package);
+ upb_gfree(f);
}
+const struct upb_refcounted_vtbl upb_filedef_vtbl = {visitfiledef, freefiledef};
-/* Standard error functions ***************************************************/
-
-static bool default_err(void *ud, const upb_status *status) {
- UPB_UNUSED(ud);
- UPB_UNUSED(status);
- return false;
-}
+upb_filedef *upb_filedef_new(const void *owner) {
+ upb_filedef *f = upb_gmalloc(sizeof(*f));
-static bool write_err_to(void *ud, const upb_status *status) {
- upb_status *copy_to = ud;
- upb_status_copy(copy_to, status);
- return false;
-}
+ if (!f) {
+ return NULL;
+ }
+ f->package = NULL;
+ f->name = NULL;
+ f->syntax = UPB_SYNTAX_PROTO2;
-/* upb_env ********************************************************************/
+ if (!upb_refcounted_init(upb_filedef_upcast_mutable(f), &upb_filedef_vtbl,
+ owner)) {
+ goto err;
+ }
-void upb_env_init(upb_env *e) {
- default_alloc_ud *ud = (default_alloc_ud*)&e->default_alloc_ud;
- e->ok_ = true;
- e->bytes_allocated = 0;
- e->cleanup_head = NULL;
+ if (!upb_inttable_init(&f->defs, UPB_CTYPE_CONSTPTR)) {
+ goto err;
+ }
- ud->head = NULL;
+ if (!upb_inttable_init(&f->deps, UPB_CTYPE_CONSTPTR)) {
+ goto err2;
+ }
- /* Set default functions. */
- upb_env_setallocfunc(e, default_alloc, ud);
- upb_env_seterrorfunc(e, default_err, NULL);
-}
+ return f;
-void upb_env_uninit(upb_env *e) {
- cleanup_ent *ent = e->cleanup_head;
- while (ent) {
- ent->cleanup(ent->ud);
- ent = ent->next;
- }
+err2:
+ upb_inttable_uninit(&f->defs);
- /* Must do this after running cleanup functions, because this will delete
- the memory we store our cleanup entries in! */
- if (e->alloc == default_alloc) {
- default_alloc_cleanup(e->alloc_ud);
- }
+err:
+ upb_gfree(f);
+ return NULL;
}
-UPB_FORCEINLINE void upb_env_setallocfunc(upb_env *e, upb_alloc_func *alloc,
- void *ud) {
- e->alloc = alloc;
- e->alloc_ud = ud;
+const char *upb_filedef_name(const upb_filedef *f) {
+ return f->name;
}
-UPB_FORCEINLINE void upb_env_seterrorfunc(upb_env *e, upb_error_func *func,
- void *ud) {
- e->err = func;
- e->err_ud = ud;
+const char *upb_filedef_package(const upb_filedef *f) {
+ return f->package;
}
-void upb_env_reporterrorsto(upb_env *e, upb_status *status) {
- e->err = write_err_to;
- e->err_ud = status;
+upb_syntax_t upb_filedef_syntax(const upb_filedef *f) {
+ return f->syntax;
}
-bool upb_env_ok(const upb_env *e) {
- return e->ok_;
+size_t upb_filedef_defcount(const upb_filedef *f) {
+ return upb_inttable_count(&f->defs);
}
-bool upb_env_reporterror(upb_env *e, const upb_status *status) {
- e->ok_ = false;
- return e->err(e->err_ud, status);
+size_t upb_filedef_depcount(const upb_filedef *f) {
+ return upb_inttable_count(&f->deps);
}
-bool upb_env_addcleanup(upb_env *e, upb_cleanup_func *func, void *ud) {
- cleanup_ent *ent = upb_env_malloc(e, sizeof(cleanup_ent));
- if (!ent) return false;
-
- ent->cleanup = func;
- ent->ud = ud;
- ent->next = e->cleanup_head;
- e->cleanup_head = ent;
-
- return true;
-}
+const upb_def *upb_filedef_def(const upb_filedef *f, size_t i) {
+ upb_value v;
-void *upb_env_malloc(upb_env *e, size_t size) {
- e->bytes_allocated += size;
- if (e->alloc == seeded_alloc) {
- /* This is equivalent to the next branch, but allows inlining for a
- * measurable perf benefit. */
- return seeded_alloc(e->alloc_ud, NULL, 0, size);
+ if (upb_inttable_lookup32(&f->defs, i, &v)) {
+ return upb_value_getconstptr(v);
} else {
- return e->alloc(e->alloc_ud, NULL, 0, size);
+ return NULL;
}
}
-void *upb_env_realloc(upb_env *e, void *ptr, size_t oldsize, size_t size) {
- char *ret;
- assert(oldsize <= size);
- ret = e->alloc(e->alloc_ud, ptr, oldsize, size);
-
-#ifndef NDEBUG
- /* Overwrite non-preserved memory to ensure callers are passing the oldsize
- * that they truly require. */
- memset(ret + oldsize, 0xff, size - oldsize);
-#endif
+const upb_filedef *upb_filedef_dep(const upb_filedef *f, size_t i) {
+ upb_value v;
- return ret;
+ if (upb_inttable_lookup32(&f->deps, i, &v)) {
+ return upb_value_getconstptr(v);
+ } else {
+ return NULL;
+ }
}
-size_t upb_env_bytesallocated(const upb_env *e) {
- return e->bytes_allocated;
+bool upb_filedef_setname(upb_filedef *f, const char *name, upb_status *s) {
+ name = upb_gstrdup(name);
+ if (!name) {
+ upb_upberr_setoom(s);
+ return false;
+ }
+ upb_gfree((void*)f->name);
+ f->name = name;
+ return true;
}
-
-/* upb_seededalloc ************************************************************/
-
-/* Be conservative and choose 16 in case anyone is using SSE. */
-static const size_t maxalign = 16;
-
-static size_t align_up(size_t size) {
- return ((size + maxalign - 1) / maxalign) * maxalign;
+bool upb_filedef_setpackage(upb_filedef *f, const char *package,
+ upb_status *s) {
+ if (!upb_isident(package, strlen(package), true, s)) return false;
+ package = upb_gstrdup(package);
+ if (!package) {
+ upb_upberr_setoom(s);
+ return false;
+ }
+ upb_gfree((void*)f->package);
+ f->package = package;
+ return true;
}
-UPB_FORCEINLINE static void *seeded_alloc(void *ud, void *ptr, size_t oldsize,
- size_t size) {
- upb_seededalloc *a = ud;
-
- size = align_up(size);
-
- assert(a->mem_limit >= a->mem_ptr);
+bool upb_filedef_setsyntax(upb_filedef *f, upb_syntax_t syntax,
+ upb_status *s) {
+ UPB_UNUSED(s);
+ if (syntax != UPB_SYNTAX_PROTO2 &&
+ syntax != UPB_SYNTAX_PROTO3) {
+ upb_status_seterrmsg(s, "Unknown syntax value.");
+ return false;
+ }
+ f->syntax = syntax;
- if (oldsize == 0 && size <= (size_t)(a->mem_limit - a->mem_ptr)) {
- /* Fast path: we can satisfy from the initial allocation. */
- void *ret = a->mem_ptr;
- a->mem_ptr += size;
- return ret;
- } else {
- char *chptr = ptr;
- /* Slow path: fallback to other allocator. */
- a->need_cleanup = true;
- /* Is `ptr` part of the user-provided initial block? Don't pass it to the
- * default allocator if so; otherwise, it may try to realloc() the block. */
- if (chptr >= a->mem_base && chptr < a->mem_limit) {
- void *ret;
- assert(chptr + oldsize <= a->mem_limit);
- ret = a->alloc(a->alloc_ud, NULL, 0, size);
- if (ret) memcpy(ret, ptr, oldsize);
- return ret;
- } else {
- return a->alloc(a->alloc_ud, ptr, oldsize, size);
+ {
+ /* Set all messages in this file to match. */
+ size_t i;
+ for (i = 0; i < upb_filedef_defcount(f); i++) {
+ /* Casting const away is safe since all defs in mutable filedef must
+ * also be mutable. */
+ upb_def *def = (upb_def*)upb_filedef_def(f, i);
+
+ upb_msgdef *m = upb_dyncast_msgdef_mutable(def);
+ if (m) {
+ m->syntax = syntax;
+ }
}
}
-}
-
-void upb_seededalloc_init(upb_seededalloc *a, void *mem, size_t len) {
- default_alloc_ud *ud = (default_alloc_ud*)&a->default_alloc_ud;
- a->mem_base = mem;
- a->mem_ptr = mem;
- a->mem_limit = (char*)mem + len;
- a->need_cleanup = false;
- a->returned_allocfunc = false;
-
- ud->head = NULL;
- upb_seededalloc_setfallbackalloc(a, default_alloc, ud);
+ return true;
}
-void upb_seededalloc_uninit(upb_seededalloc *a) {
- if (a->alloc == default_alloc && a->need_cleanup) {
- default_alloc_cleanup(a->alloc_ud);
+bool upb_filedef_adddef(upb_filedef *f, upb_def *def, const void *ref_donor,
+ upb_status *s) {
+ if (def->file) {
+ upb_status_seterrmsg(s, "Def is already part of another filedef.");
+ return false;
}
-}
-UPB_FORCEINLINE void upb_seededalloc_setfallbackalloc(upb_seededalloc *a,
- upb_alloc_func *alloc,
- void *ud) {
- assert(!a->returned_allocfunc);
- a->alloc = alloc;
- a->alloc_ud = ud;
+ if (upb_inttable_push(&f->defs, upb_value_constptr(def))) {
+ def->file = f;
+ upb_ref2(def, f);
+ if (ref_donor) upb_def_unref(def, ref_donor);
+ if (def->type == UPB_DEF_MSG) {
+ upb_downcast_msgdef_mutable(def)->syntax = f->syntax;
+ }
+ return true;
+ } else {
+ upb_upberr_setoom(s);
+ return false;
+ }
}
-upb_alloc_func *upb_seededalloc_getallocfunc(upb_seededalloc *a) {
- a->returned_allocfunc = true;
- return seeded_alloc;
+bool upb_filedef_adddep(upb_filedef *f, const upb_filedef *dep) {
+ if (upb_inttable_push(&f->deps, upb_value_constptr(dep))) {
+ /* Regular ref instead of ref2 because files can't form cycles. */
+ upb_filedef_ref(dep, f);
+ return true;
+ } else {
+ return false;
+ }
}
/*
** TODO(haberman): it's unclear whether a lot of the consistency checks should
@@ -1973,10 +2114,16 @@ upb_alloc_func *upb_seededalloc_getallocfunc(upb_seededalloc *a) {
*/
-#include <stdlib.h>
#include <string.h>
+static void *upb_calloc(size_t size) {
+ void *mem = upb_gmalloc(size);
+ if (mem) {
+ memset(mem, 0, size);
+ }
+ return mem;
+}
/* Defined for the sole purpose of having a unique pointer value for
* UPB_NO_CLOSURE. */
@@ -1996,8 +2143,8 @@ static void freehandlers(upb_refcounted *r) {
upb_inttable_uninit(&h->cleanup_);
upb_msgdef_unref(h->msg, h);
- free(h->sub);
- free(h);
+ upb_gfree(h->sub);
+ upb_gfree(h);
}
static void visithandlers(const upb_refcounted *r, upb_refcounted_visit *visit,
@@ -2247,14 +2394,20 @@ upb_handlers *upb_handlers_new(const upb_msgdef *md, const void *owner) {
assert(upb_msgdef_isfrozen(md));
extra = sizeof(upb_handlers_tabent) * (md->selector_count - 1);
- h = calloc(sizeof(*h) + extra, 1);
+ h = upb_calloc(sizeof(*h) + extra);
if (!h) return NULL;
h->msg = md;
upb_msgdef_ref(h->msg, h);
upb_status_clear(&h->status_);
- h->sub = calloc(md->submsg_field_count, sizeof(*h->sub));
- if (!h->sub) goto oom;
+
+ if (md->submsg_field_count > 0) {
+ h->sub = upb_calloc(md->submsg_field_count * sizeof(*h->sub));
+ if (!h->sub) goto oom;
+ } else {
+ h->sub = 0;
+ }
+
if (!upb_refcounted_init(upb_handlers_upcast_mutable(h), &vtbl, owner))
goto oom;
if (!upb_inttable_init(&h->cleanup_, UPB_CTYPE_FPTR)) goto oom;
@@ -2669,7 +2822,6 @@ bool upb_byteshandler_setendstr(upb_byteshandler *h,
#include <setjmp.h>
-#include <stdlib.h>
static void freeobj(upb_refcounted *o);
@@ -2745,8 +2897,31 @@ void upb_unlock();
/* UPB_DEBUG_REFS mode counts on being able to malloc() memory in some
* code-paths that can normally never fail, like upb_refcounted_ref(). Since
* we have no way to propagage out-of-memory errors back to the user, and since
- * these errors can only occur in UPB_DEBUG_REFS mode, we immediately fail. */
-#define CHECK_OOM(predicate) if (!(predicate)) { assert(predicate); exit(1); }
+ * these errors can only occur in UPB_DEBUG_REFS mode, we use an allocator that
+ * immediately aborts on failure (avoiding the global allocator, which might
+ * inject failures). */
+
+#include <stdlib.h>
+
+static void *upb_debugrefs_allocfunc(upb_alloc *alloc, void *ptr,
+ size_t oldsize, size_t size) {
+ UPB_UNUSED(alloc);
+ UPB_UNUSED(oldsize);
+ if (size == 0) {
+ free(ptr);
+ return NULL;
+ } else {
+ void *ret = realloc(ptr, size);
+
+ if (!ret) {
+ abort();
+ }
+
+ return ret;
+ }
+}
+
+upb_alloc upb_alloc_debugrefs = {&upb_debugrefs_allocfunc};
typedef struct {
int count; /* How many refs there are (duplicates only allowed for ref2). */
@@ -2754,8 +2929,7 @@ typedef struct {
} trackedref;
static trackedref *trackedref_new(bool is_ref2) {
- trackedref *ret = malloc(sizeof(*ret));
- CHECK_OOM(ret);
+ trackedref *ret = upb_malloc(&upb_alloc_debugrefs, sizeof(*ret));
ret->count = 1;
ret->is_ref2 = is_ref2;
return ret;
@@ -2780,15 +2954,15 @@ static void track(const upb_refcounted *r, const void *owner, bool ref2) {
ref->count++;
} else {
trackedref *ref = trackedref_new(ref2);
- bool ok = upb_inttable_insertptr(r->refs, owner, upb_value_ptr(ref));
- CHECK_OOM(ok);
+ upb_inttable_insertptr2(r->refs, owner, upb_value_ptr(ref),
+ &upb_alloc_debugrefs);
if (ref2) {
/* We know this cast is safe when it is a ref2, because it's coming from
* another refcounted object. */
const upb_refcounted *from = owner;
assert(!upb_inttable_lookupptr(from->ref2s, r, NULL));
- ok = upb_inttable_insertptr(from->ref2s, r, upb_value_ptr(NULL));
- CHECK_OOM(ok);
+ upb_inttable_insertptr2(from->ref2s, r, upb_value_ptr(NULL),
+ &upb_alloc_debugrefs);
}
}
upb_unlock();
@@ -2846,7 +3020,6 @@ static void getref2s(const upb_refcounted *owner, upb_inttable *tab) {
upb_value v;
upb_value count;
trackedref *ref;
- bool ok;
bool found;
upb_refcounted *to = (upb_refcounted*)upb_inttable_iter_key(&i);
@@ -2857,8 +3030,7 @@ static void getref2s(const upb_refcounted *owner, upb_inttable *tab) {
ref = upb_value_getptr(v);
count = upb_value_int32(ref->count);
- ok = upb_inttable_insertptr(tab, to, count);
- CHECK_OOM(ok);
+ upb_inttable_insertptr2(tab, to, count, &upb_alloc_debugrefs);
}
upb_unlock();
}
@@ -2884,21 +3056,19 @@ static void visit_check(const upb_refcounted *obj, const upb_refcounted *subobj,
assert(removed);
newcount = upb_value_getint32(v) - 1;
if (newcount > 0) {
- upb_inttable_insert(ref2, (uintptr_t)subobj, upb_value_int32(newcount));
+ upb_inttable_insert2(ref2, (uintptr_t)subobj, upb_value_int32(newcount),
+ &upb_alloc_debugrefs);
}
}
static void visit(const upb_refcounted *r, upb_refcounted_visit *v,
void *closure) {
- bool ok;
-
/* In DEBUG_REFS mode we know what existing ref2 refs there are, so we know
* exactly the set of nodes that visit() should visit. So we verify visit()'s
* correctness here. */
check_state state;
state.obj = r;
- ok = upb_inttable_init(&state.ref2, UPB_CTYPE_INT32);
- CHECK_OOM(ok);
+ upb_inttable_init2(&state.ref2, UPB_CTYPE_INT32, &upb_alloc_debugrefs);
getref2s(r, &state.ref2);
/* This should visit any children in the ref2 table. */
@@ -2906,32 +3076,22 @@ static void visit(const upb_refcounted *r, upb_refcounted_visit *v,
/* This assertion will fail if the visit() function missed any children. */
assert(upb_inttable_count(&state.ref2) == 0);
- upb_inttable_uninit(&state.ref2);
+ upb_inttable_uninit2(&state.ref2, &upb_alloc_debugrefs);
if (r->vtbl->visit) r->vtbl->visit(r, v, closure);
}
-static bool trackinit(upb_refcounted *r) {
- r->refs = malloc(sizeof(*r->refs));
- r->ref2s = malloc(sizeof(*r->ref2s));
- if (!r->refs || !r->ref2s) goto err1;
-
- if (!upb_inttable_init(r->refs, UPB_CTYPE_PTR)) goto err1;
- if (!upb_inttable_init(r->ref2s, UPB_CTYPE_PTR)) goto err2;
- return true;
-
-err2:
- upb_inttable_uninit(r->refs);
-err1:
- free(r->refs);
- free(r->ref2s);
- return false;
+static void trackinit(upb_refcounted *r) {
+ r->refs = upb_malloc(&upb_alloc_debugrefs, sizeof(*r->refs));
+ r->ref2s = upb_malloc(&upb_alloc_debugrefs, sizeof(*r->ref2s));
+ upb_inttable_init2(r->refs, UPB_CTYPE_PTR, &upb_alloc_debugrefs);
+ upb_inttable_init2(r->ref2s, UPB_CTYPE_PTR, &upb_alloc_debugrefs);
}
static void trackfree(const upb_refcounted *r) {
- upb_inttable_uninit(r->refs);
- upb_inttable_uninit(r->ref2s);
- free(r->refs);
- free(r->ref2s);
+ upb_inttable_uninit2(r->refs, &upb_alloc_debugrefs);
+ upb_inttable_uninit2(r->ref2s, &upb_alloc_debugrefs);
+ upb_free(&upb_alloc_debugrefs, r->refs);
+ upb_free(&upb_alloc_debugrefs, r->ref2s);
}
#else
@@ -2954,9 +3114,8 @@ static void checkref(const upb_refcounted *r, const void *owner, bool ref2) {
UPB_UNUSED(ref2);
}
-static bool trackinit(upb_refcounted *r) {
+static void trackinit(upb_refcounted *r) {
UPB_UNUSED(r);
- return true;
}
static void trackfree(const upb_refcounted *r) {
@@ -3066,12 +3225,12 @@ static upb_refcounted *pop(tarjan *t) {
}
static void tarjan_newgroup(tarjan *t) {
- uint32_t *group = malloc(sizeof(*group));
+ uint32_t *group = upb_gmalloc(sizeof(*group));
if (!group) oom(t);
/* Push group and empty group leader (we'll fill in leader later). */
if (!upb_inttable_push(&t->groups, upb_value_ptr(group)) ||
!upb_inttable_push(&t->groups, upb_value_ptr(NULL))) {
- free(group);
+ upb_gfree(group);
oom(t);
}
*group = 0;
@@ -3246,7 +3405,7 @@ static bool freeze(upb_refcounted *const*roots, int n, upb_status *s,
if (obj == move) {
/* Removing the last object from a group. */
assert(*obj->group == obj->individual_count);
- free(obj->group);
+ upb_gfree(obj->group);
} else {
obj->next = move->next;
/* This may decrease to zero; we'll collect GRAY objects (if any) that
@@ -3302,7 +3461,7 @@ static bool freeze(upb_refcounted *const*roots, int n, upb_status *s,
/* We eagerly free() the group's count (since we can't easily determine
* the group's remaining size it's the easiest way to ensure it gets
* done). */
- free(obj->group);
+ upb_gfree(obj->group);
/* Visit to release ref2's (done in a separate pass since release_ref2
* depends on o->group being unmodified so it can test merged()). */
@@ -3322,7 +3481,7 @@ err4:
if (!ret) {
upb_inttable_begin(&iter, &t.groups);
for(; !upb_inttable_done(&iter); upb_inttable_next(&iter))
- free(upb_value_getptr(upb_inttable_iter_value(&iter)));
+ upb_gfree(upb_value_getptr(upb_inttable_iter_value(&iter)));
}
upb_inttable_uninit(&t.groups);
err3:
@@ -3346,7 +3505,7 @@ static void merge(upb_refcounted *r, upb_refcounted *from) {
if (merged(r, from)) return;
*r->group += *from->group;
- free(from->group);
+ upb_gfree(from->group);
base = from;
/* Set all refcount pointers in the "from" chain to the merged refcount.
@@ -3380,7 +3539,7 @@ static void unref(const upb_refcounted *r) {
if (unrefgroup(r->group)) {
const upb_refcounted *o;
- free(r->group);
+ upb_gfree(r->group);
/* In two passes, since release_ref2 needs a guarantee that any subobjs
* are alive. */
@@ -3424,13 +3583,10 @@ bool upb_refcounted_init(upb_refcounted *r,
r->vtbl = vtbl;
r->individual_count = 0;
r->is_frozen = false;
- r->group = malloc(sizeof(*r->group));
+ r->group = upb_gmalloc(sizeof(*r->group));
if (!r->group) return false;
*r->group = 0;
- if (!trackinit(r)) {
- free(r->group);
- return false;
- }
+ trackinit(r);
upb_refcounted_ref(r, owner);
return true;
}
@@ -3489,15 +3645,16 @@ void upb_refcounted_checkref(const upb_refcounted *r, const void *owner) {
bool upb_refcounted_freeze(upb_refcounted *const*roots, int n, upb_status *s,
int maxdepth) {
int i;
+ bool ret;
for (i = 0; i < n; i++) {
assert(!roots[i]->is_frozen);
}
- return freeze(roots, n, s, maxdepth);
+ ret = freeze(roots, n, s, maxdepth);
+ assert(!s || ret == upb_ok(s));
+ return ret;
}
-#include <stdlib.h>
-
/* Fallback implementation if the shim is not specialized by the JIT. */
#define SHIM_WRITER(type, ctype) \
bool upb_shim_set ## type (void *c, const void *hd, ctype val) { \
@@ -3523,14 +3680,14 @@ bool upb_shim_set(upb_handlers *h, const upb_fielddef *f, size_t offset,
upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
bool ok;
- upb_shim_data *d = malloc(sizeof(*d));
+ upb_shim_data *d = upb_gmalloc(sizeof(*d));
if (!d) return false;
d->offset = offset;
d->hasbit = hasbit;
upb_handlerattr_sethandlerdata(&attr, d);
upb_handlerattr_setalwaysok(&attr, true);
- upb_handlers_addcleanup(h, d, free);
+ upb_handlers_addcleanup(h, d, upb_gfree);
#define TYPE(u, l) \
case UPB_TYPE_##u: \
@@ -3581,7 +3738,6 @@ const upb_shim_data *upb_shim_getdata(const upb_handlers *h, upb_selector_t s,
}
-#include <stdlib.h>
#include <string.h>
static void upb_symtab_free(upb_refcounted *r) {
@@ -3593,13 +3749,17 @@ static void upb_symtab_free(upb_refcounted *r) {
upb_def_unref(def, s);
}
upb_strtable_uninit(&s->symtab);
- free(s);
+ upb_gfree(s);
}
-
upb_symtab *upb_symtab_new(const void *owner) {
static const struct upb_refcounted_vtbl vtbl = {NULL, &upb_symtab_free};
- upb_symtab *s = malloc(sizeof(*s));
+
+ upb_symtab *s = upb_gmalloc(sizeof(*s));
+ if (!s) {
+ return NULL;
+ }
+
upb_refcounted_init(upb_symtab_upcast_mutable(s), &vtbl, owner);
upb_strtable_init(&s->symtab, UPB_CTYPE_PTR);
return s;
@@ -3773,14 +3933,23 @@ oom:
/* TODO(haberman): we need a lot more testing of error conditions.
* The came_from_user stuff in particular is not tested. */
-bool upb_symtab_add(upb_symtab *s, upb_def *const*defs, int n, void *ref_donor,
- upb_status *status) {
- int i;
+static bool symtab_add(upb_symtab *s, upb_def *const*defs, size_t n,
+ void *ref_donor, upb_refcounted *freeze_also,
+ upb_status *status) {
+ size_t i;
+ size_t add_n;
+ size_t freeze_n;
upb_strtable_iter iter;
+ upb_refcounted **add_objs = NULL;
upb_def **add_defs = NULL;
+ size_t add_objs_size;
upb_strtable addtab;
upb_inttable seen;
+ if (n == 0 && !freeze_also) {
+ return true;
+ }
+
assert(!upb_symtab_isfrozen(s));
if (!upb_strtable_init(&addtab, UPB_CTYPE_PTR)) {
upb_status_seterrmsg(status, "out of memory");
@@ -3922,15 +4091,38 @@ bool upb_symtab_add(upb_symtab *s, upb_def *const*defs, int n, void *ref_donor,
}
}
- /* We need an array of the defs in addtab, for passing to upb_def_freeze. */
- add_defs = malloc(sizeof(void*) * upb_strtable_count(&addtab));
+ /* We need an array of the defs in addtab, for passing to
+ * upb_refcounted_freeze(). */
+ add_objs_size = upb_strtable_count(&addtab);
+ if (freeze_also) {
+ add_objs_size++;
+ }
+
+ add_defs = upb_gmalloc(sizeof(void*) * add_objs_size);
if (add_defs == NULL) goto oom_err;
upb_strtable_begin(&iter, &addtab);
- for (n = 0; !upb_strtable_done(&iter); upb_strtable_next(&iter)) {
- add_defs[n++] = upb_value_getptr(upb_strtable_iter_value(&iter));
+ for (add_n = 0; !upb_strtable_done(&iter); upb_strtable_next(&iter)) {
+ add_defs[add_n++] = upb_value_getptr(upb_strtable_iter_value(&iter));
}
- if (!upb_def_freeze(add_defs, n, status)) goto err;
+ /* Validate defs. */
+ if (!_upb_def_validate(add_defs, add_n, status)) {
+ goto err;
+ }
+
+ /* Cheat a little and give the array a new type.
+ * This is probably undefined behavior, but this code will be deleted soon. */
+ add_objs = (upb_refcounted**)add_defs;
+
+ freeze_n = add_n;
+ if (freeze_also) {
+ add_objs[freeze_n++] = freeze_also;
+ }
+
+ if (!upb_refcounted_freeze(add_objs, freeze_n, status,
+ UPB_MAX_MESSAGE_DEPTH * 2)) {
+ goto err;
+ }
/* This must be delayed until all errors have been detected, since error
* recovery code uses this table to cleanup defs. */
@@ -3938,8 +4130,8 @@ bool upb_symtab_add(upb_symtab *s, upb_def *const*defs, int n, void *ref_donor,
/* TODO(haberman) we don't properly handle errors after this point (like
* OOM in upb_strtable_insert() below). */
- for (i = 0; i < n; i++) {
- upb_def *def = add_defs[i];
+ for (i = 0; i < add_n; i++) {
+ upb_def *def = (upb_def*)add_objs[i];
const char *name = upb_def_fullname(def);
upb_value v;
bool success;
@@ -3951,7 +4143,7 @@ bool upb_symtab_add(upb_symtab *s, upb_def *const*defs, int n, void *ref_donor,
success = upb_strtable_insert(&s->symtab, name, upb_value_ptr(def));
UPB_ASSERT_VAR(success, success == true);
}
- free(add_defs);
+ upb_gfree(add_defs);
return true;
oom_err:
@@ -3972,11 +4164,40 @@ err: {
}
}
upb_strtable_uninit(&addtab);
- free(add_defs);
+ upb_gfree(add_defs);
assert(!upb_ok(status));
return false;
}
+bool upb_symtab_add(upb_symtab *s, upb_def *const*defs, size_t n,
+ void *ref_donor, upb_status *status) {
+ return symtab_add(s, defs, n, ref_donor, NULL, status);
+}
+
+bool upb_symtab_addfile(upb_symtab *s, upb_filedef *file, upb_status *status) {
+ size_t n;
+ size_t i;
+ upb_def **defs;
+ bool ret;
+
+ n = upb_filedef_defcount(file);
+ defs = upb_gmalloc(sizeof(*defs) * n);
+
+ if (defs == NULL) {
+ upb_status_seterrmsg(status, "Out of memory");
+ return false;
+ }
+
+ for (i = 0; i < n; i++) {
+ defs[i] = upb_filedef_mutabledef(file, i);
+ }
+
+ ret = symtab_add(s, defs, n, NULL, upb_filedef_upcast_mutable(file), status);
+
+ upb_gfree(defs);
+ return ret;
+}
+
/* Iteration. */
static void advance_to_matching(upb_symtab_iter *iter) {
@@ -4015,7 +4236,6 @@ const upb_def *upb_symtab_iter_def(const upb_symtab_iter *iter) {
*/
-#include <stdlib.h>
#include <string.h>
#define UPB_MAXARRSIZE 16 /* 64k. */
@@ -4024,6 +4244,17 @@ const upb_def *upb_symtab_iter_def(const upb_symtab_iter *iter) {
#define ARRAY_SIZE(x) \
((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
+#ifdef NDEBUG
+static void upb_check_alloc(upb_table *t, upb_alloc *a) {
+ UPB_UNUSED(t);
+ UPB_UNUSED(a);
+}
+#else
+static void upb_check_alloc(upb_table *t, upb_alloc *a) {
+ assert(t->alloc == a);
+}
+#endif
+
static const double MAX_LOAD = 0.85;
/* The minimum utilization of the array part of a mixed hash/array table. This
@@ -4041,11 +4272,11 @@ int log2ceil(uint64_t v) {
return UPB_MIN(UPB_MAXARRSIZE, ret);
}
-char *upb_strdup(const char *s) {
- return upb_strdup2(s, strlen(s));
+char *upb_strdup(const char *s, upb_alloc *a) {
+ return upb_strdup2(s, strlen(s), a);
}
-char *upb_strdup2(const char *s, size_t len) {
+char *upb_strdup2(const char *s, size_t len, upb_alloc *a) {
size_t n;
char *p;
@@ -4054,7 +4285,7 @@ char *upb_strdup2(const char *s, size_t len) {
/* Always null-terminate, even if binary data; but don't rely on the input to
* have a null-terminating byte since it may be a raw binary buffer. */
n = len + 1;
- p = malloc(n);
+ p = upb_malloc(a, n);
if (p) {
memcpy(p, s, len);
p[len] = 0;
@@ -4095,19 +4326,27 @@ static upb_tabent *mutable_entries(upb_table *t) {
}
static bool isfull(upb_table *t) {
- return (double)(t->count + 1) / upb_table_size(t) > MAX_LOAD;
+ if (upb_table_size(t) == 0) {
+ return true;
+ } else {
+ return ((double)(t->count + 1) / upb_table_size(t)) > MAX_LOAD;
+ }
}
-static bool init(upb_table *t, upb_ctype_t ctype, uint8_t size_lg2) {
+static bool init(upb_table *t, upb_ctype_t ctype, uint8_t size_lg2,
+ upb_alloc *a) {
size_t bytes;
t->count = 0;
t->ctype = ctype;
t->size_lg2 = size_lg2;
t->mask = upb_table_size(t) ? upb_table_size(t) - 1 : 0;
+#ifndef NDEBUG
+ t->alloc = a;
+#endif
bytes = upb_table_size(t) * sizeof(upb_tabent);
if (bytes > 0) {
- t->entries = malloc(bytes);
+ t->entries = upb_malloc(a, bytes);
if (!t->entries) return false;
memset(mutable_entries(t), 0, bytes);
} else {
@@ -4116,7 +4355,10 @@ static bool init(upb_table *t, upb_ctype_t ctype, uint8_t size_lg2) {
return true;
}
-static void uninit(upb_table *t) { free(mutable_entries(t)); }
+static void uninit(upb_table *t, upb_alloc *a) {
+ upb_check_alloc(t, a);
+ upb_free(a, mutable_entries(t));
+}
static upb_tabent *emptyent(upb_table *t) {
upb_tabent *e = mutable_entries(t) + upb_table_size(t);
@@ -4269,8 +4511,8 @@ static size_t begin(const upb_table *t) {
/* A simple "subclass" of upb_table that only adds a hash function for strings. */
-static upb_tabkey strcopy(lookupkey_t k2) {
- char *str = malloc(k2.str.len + sizeof(uint32_t) + 1);
+static upb_tabkey strcopy(lookupkey_t k2, upb_alloc *a) {
+ char *str = upb_malloc(a, k2.str.len + sizeof(uint32_t) + 1);
if (str == NULL) return 0;
memcpy(str, &k2.str.len, sizeof(uint32_t));
memcpy(str + sizeof(uint32_t), k2.str.str, k2.str.len + 1);
@@ -4289,51 +4531,56 @@ static bool streql(upb_tabkey k1, lookupkey_t k2) {
return len == k2.str.len && memcmp(str, k2.str.str, len) == 0;
}
-bool upb_strtable_init(upb_strtable *t, upb_ctype_t ctype) {
- return init(&t->t, ctype, 2);
+bool upb_strtable_init2(upb_strtable *t, upb_ctype_t ctype, upb_alloc *a) {
+ return init(&t->t, ctype, 2, a);
}
-void upb_strtable_uninit(upb_strtable *t) {
+void upb_strtable_uninit2(upb_strtable *t, upb_alloc *a) {
size_t i;
for (i = 0; i < upb_table_size(&t->t); i++)
- free((void*)t->t.entries[i].key);
- uninit(&t->t);
+ upb_free(a, (void*)t->t.entries[i].key);
+ uninit(&t->t, a);
}
-bool upb_strtable_resize(upb_strtable *t, size_t size_lg2) {
+bool upb_strtable_resize(upb_strtable *t, size_t size_lg2, upb_alloc *a) {
upb_strtable new_table;
upb_strtable_iter i;
- if (!init(&new_table.t, t->t.ctype, size_lg2))
+ upb_check_alloc(&t->t, a);
+
+ if (!init(&new_table.t, t->t.ctype, size_lg2, a))
return false;
upb_strtable_begin(&i, t);
for ( ; !upb_strtable_done(&i); upb_strtable_next(&i)) {
- upb_strtable_insert2(
+ upb_strtable_insert3(
&new_table,
upb_strtable_iter_key(&i),
upb_strtable_iter_keylength(&i),
- upb_strtable_iter_value(&i));
+ upb_strtable_iter_value(&i),
+ a);
}
- upb_strtable_uninit(t);
+ upb_strtable_uninit2(t, a);
*t = new_table;
return true;
}
-bool upb_strtable_insert2(upb_strtable *t, const char *k, size_t len,
- upb_value v) {
+bool upb_strtable_insert3(upb_strtable *t, const char *k, size_t len,
+ upb_value v, upb_alloc *a) {
lookupkey_t key;
upb_tabkey tabkey;
uint32_t hash;
+ upb_check_alloc(&t->t, a);
+
if (isfull(&t->t)) {
/* Need to resize. New table of double the size, add old elements to it. */
- if (!upb_strtable_resize(t, t->t.size_lg2 + 1)) {
+ if (!upb_strtable_resize(t, t->t.size_lg2 + 1, a)) {
return false;
}
}
key = strkey2(k, len);
- tabkey = strcopy(key);
+ tabkey = strcopy(key, a);
if (tabkey == 0) return false;
hash = MurmurHash2(key.str.str, key.str.len, 0);
@@ -4347,12 +4594,12 @@ bool upb_strtable_lookup2(const upb_strtable *t, const char *key, size_t len,
return lookup(&t->t, strkey2(key, len), v, hash, &streql);
}
-bool upb_strtable_remove2(upb_strtable *t, const char *key, size_t len,
- upb_value *val) {
+bool upb_strtable_remove3(upb_strtable *t, const char *key, size_t len,
+ upb_value *val, upb_alloc *alloc) {
uint32_t hash = MurmurHash2(key, strlen(key), 0);
upb_tabkey tabkey;
if (rm(&t->t, strkey2(key, len), val, &tabkey, hash, &streql)) {
- free((void*)tabkey);
+ upb_free(alloc, (void*)tabkey);
return true;
} else {
return false;
@@ -4379,12 +4626,12 @@ bool upb_strtable_done(const upb_strtable_iter *i) {
upb_tabent_isempty(str_tabent(i));
}
-const char *upb_strtable_iter_key(upb_strtable_iter *i) {
+const char *upb_strtable_iter_key(const upb_strtable_iter *i) {
assert(!upb_strtable_done(i));
return upb_tabstr(str_tabent(i)->key, NULL);
}
-size_t upb_strtable_iter_keylength(upb_strtable_iter *i) {
+size_t upb_strtable_iter_keylength(const upb_strtable_iter *i) {
uint32_t len;
assert(!upb_strtable_done(i));
upb_tabstr(str_tabent(i)->key, &len);
@@ -4459,18 +4706,18 @@ static void check(upb_inttable *t) {
}
bool upb_inttable_sizedinit(upb_inttable *t, upb_ctype_t ctype,
- size_t asize, int hsize_lg2) {
+ size_t asize, int hsize_lg2, upb_alloc *a) {
size_t array_bytes;
- if (!init(&t->t, ctype, hsize_lg2)) return false;
+ if (!init(&t->t, ctype, hsize_lg2, a)) return false;
/* Always make the array part at least 1 long, so that we know key 0
* won't be in the hash part, which simplifies things. */
t->array_size = UPB_MAX(1, asize);
t->array_count = 0;
array_bytes = t->array_size * sizeof(upb_value);
- t->array = malloc(array_bytes);
+ t->array = upb_malloc(a, array_bytes);
if (!t->array) {
- uninit(&t->t);
+ uninit(&t->t, a);
return false;
}
memset(mutable_array(t), 0xff, array_bytes);
@@ -4478,22 +4725,23 @@ bool upb_inttable_sizedinit(upb_inttable *t, upb_ctype_t ctype,
return true;
}
-bool upb_inttable_init(upb_inttable *t, upb_ctype_t ctype) {
- return upb_inttable_sizedinit(t, ctype, 0, 4);
+bool upb_inttable_init2(upb_inttable *t, upb_ctype_t ctype, upb_alloc *a) {
+ return upb_inttable_sizedinit(t, ctype, 0, 4, a);
}
-void upb_inttable_uninit(upb_inttable *t) {
- uninit(&t->t);
- free(mutable_array(t));
+void upb_inttable_uninit2(upb_inttable *t, upb_alloc *a) {
+ uninit(&t->t, a);
+ upb_free(a, mutable_array(t));
}
-bool upb_inttable_insert(upb_inttable *t, uintptr_t key, upb_value val) {
- /* XXX: Table can't store value (uint64_t)-1. Need to somehow statically
- * guarantee that this is not necessary, or fix the limitation. */
+bool upb_inttable_insert2(upb_inttable *t, uintptr_t key, upb_value val,
+ upb_alloc *a) {
upb_tabval tabval;
tabval.val = val.val;
UPB_UNUSED(tabval);
- assert(upb_arrhas(tabval));
+ assert(upb_arrhas(tabval)); /* This will reject (uint64_t)-1. Fix this. */
+
+ upb_check_alloc(&t->t, a);
if (key < t->array_size) {
assert(!upb_arrhas(t->array[key]));
@@ -4504,8 +4752,11 @@ bool upb_inttable_insert(upb_inttable *t, uintptr_t key, upb_value val) {
/* Need to resize the hash part, but we re-use the array part. */
size_t i;
upb_table new_table;
- if (!init(&new_table, t->t.ctype, t->t.size_lg2 + 1))
+
+ if (!init(&new_table, t->t.ctype, t->t.size_lg2 + 1, a)) {
return false;
+ }
+
for (i = begin(&t->t); i < upb_table_size(&t->t); i = next(&t->t, i)) {
const upb_tabent *e = &t->t.entries[i];
uint32_t hash;
@@ -4518,7 +4769,7 @@ bool upb_inttable_insert(upb_inttable *t, uintptr_t key, upb_value val) {
assert(t->t.count == new_table.count);
- uninit(&t->t);
+ uninit(&t->t, a);
t->t = new_table;
}
insert(&t->t, intkey(key), key, val, upb_inthash(key), &inthash, &inteql);
@@ -4564,8 +4815,9 @@ bool upb_inttable_remove(upb_inttable *t, uintptr_t key, upb_value *val) {
return success;
}
-bool upb_inttable_push(upb_inttable *t, upb_value val) {
- return upb_inttable_insert(t, upb_inttable_count(t), val);
+bool upb_inttable_push2(upb_inttable *t, upb_value val, upb_alloc *a) {
+ upb_check_alloc(&t->t, a);
+ return upb_inttable_insert2(t, upb_inttable_count(t), val, a);
}
upb_value upb_inttable_pop(upb_inttable *t) {
@@ -4575,8 +4827,10 @@ upb_value upb_inttable_pop(upb_inttable *t) {
return val;
}
-bool upb_inttable_insertptr(upb_inttable *t, const void *key, upb_value val) {
- return upb_inttable_insert(t, (uintptr_t)key, val);
+bool upb_inttable_insertptr2(upb_inttable *t, const void *key, upb_value val,
+ upb_alloc *a) {
+ upb_check_alloc(&t->t, a);
+ return upb_inttable_insert2(t, (uintptr_t)key, val, a);
}
bool upb_inttable_lookupptr(const upb_inttable *t, const void *key,
@@ -4588,65 +4842,62 @@ bool upb_inttable_removeptr(upb_inttable *t, const void *key, upb_value *val) {
return upb_inttable_remove(t, (uintptr_t)key, val);
}
-void upb_inttable_compact(upb_inttable *t) {
- /* Create a power-of-two histogram of the table keys. */
- int counts[UPB_MAXARRSIZE + 1] = {0};
- uintptr_t max_key = 0;
+void upb_inttable_compact2(upb_inttable *t, upb_alloc *a) {
+ /* A power-of-two histogram of the table keys. */
+ size_t counts[UPB_MAXARRSIZE + 1] = {0};
+
+ /* The max key in each bucket. */
+ uintptr_t max[UPB_MAXARRSIZE + 1] = {0};
+
upb_inttable_iter i;
- size_t arr_size;
- int arr_count;
+ size_t arr_count;
+ int size_lg2;
upb_inttable new_t;
+ upb_check_alloc(&t->t, a);
+
upb_inttable_begin(&i, t);
for (; !upb_inttable_done(&i); upb_inttable_next(&i)) {
uintptr_t key = upb_inttable_iter_key(&i);
- if (key > max_key) {
- max_key = key;
- }
- counts[log2ceil(key)]++;
+ int bucket = log2ceil(key);
+ max[bucket] = UPB_MAX(max[bucket], key);
+ counts[bucket]++;
}
- arr_size = 1;
+ /* Find the largest power of two that satisfies the MIN_DENSITY
+ * definition (while actually having some keys). */
arr_count = upb_inttable_count(t);
- if (upb_inttable_count(t) >= max_key * MIN_DENSITY) {
- /* We can put 100% of the entries in the array part. */
- arr_size = max_key + 1;
- } else {
- /* Find the largest power of two that satisfies the MIN_DENSITY
- * definition. */
- int size_lg2;
- for (size_lg2 = ARRAY_SIZE(counts) - 1; size_lg2 > 1; size_lg2--) {
- arr_size = 1 << size_lg2;
- arr_count -= counts[size_lg2];
- if (arr_count >= arr_size * MIN_DENSITY) {
- break;
- }
+ for (size_lg2 = ARRAY_SIZE(counts) - 1; size_lg2 > 0; size_lg2--) {
+ if (counts[size_lg2] == 0) {
+ /* We can halve again without losing any entries. */
+ continue;
+ } else if (arr_count >= (1 << size_lg2) * MIN_DENSITY) {
+ break;
}
+
+ arr_count -= counts[size_lg2];
}
- /* Array part must always be at least 1 entry large to catch lookups of key
- * 0. Key 0 must always be in the array part because "0" in the hash part
- * denotes an empty entry. */
- arr_size = UPB_MAX(arr_size, 1);
+ assert(arr_count <= upb_inttable_count(t));
{
/* Insert all elements into new, perfectly-sized table. */
- int hash_count = upb_inttable_count(t) - arr_count;
- int hash_size = hash_count ? (hash_count / MAX_LOAD) + 1 : 0;
- int hashsize_lg2 = log2ceil(hash_size);
+ size_t arr_size = max[size_lg2] + 1; /* +1 so arr[max] will fit. */
+ size_t hash_count = upb_inttable_count(t) - arr_count;
+ size_t hash_size = hash_count ? (hash_count / MAX_LOAD) + 1 : 0;
+ size_t hashsize_lg2 = log2ceil(hash_size);
- assert(hash_count >= 0);
- upb_inttable_sizedinit(&new_t, t->t.ctype, arr_size, hashsize_lg2);
+ upb_inttable_sizedinit(&new_t, t->t.ctype, arr_size, hashsize_lg2, a);
upb_inttable_begin(&i, t);
for (; !upb_inttable_done(&i); upb_inttable_next(&i)) {
uintptr_t k = upb_inttable_iter_key(&i);
- upb_inttable_insert(&new_t, k, upb_inttable_iter_value(&i));
+ upb_inttable_insert2(&new_t, k, upb_inttable_iter_value(&i), a);
}
assert(new_t.array_size == arr_size);
assert(new_t.t.size_lg2 == hashsize_lg2);
}
- upb_inttable_uninit(t);
+ upb_inttable_uninit2(t, a);
*t = new_t;
}
@@ -4922,6 +5173,19 @@ static void nullz(upb_status *status) {
memcpy(status->msg + sizeof(status->msg) - len, ellipsis, len);
}
+
+/* upb_upberr *****************************************************************/
+
+upb_errorspace upb_upberr = {"upb error"};
+
+void upb_upberr_setoom(upb_status *status) {
+ status->error_space_ = &upb_upberr;
+ upb_status_seterrmsg(status, "Out of memory");
+}
+
+
+/* upb_status *****************************************************************/
+
void upb_status_clear(upb_status *status) {
if (!status) return;
status->ok_ = true;
@@ -4960,311 +5224,606 @@ void upb_status_vseterrf(upb_status *status, const char *fmt, va_list args) {
nullz(status);
}
-void upb_status_seterrcode(upb_status *status, upb_errorspace *space,
- int code) {
- if (!status) return;
- status->ok_ = false;
- status->error_space_ = space;
- status->code_ = code;
- space->set_message(status, code);
-}
-
void upb_status_copy(upb_status *to, const upb_status *from) {
if (!to) return;
*to = *from;
}
-/* This file was generated by upbc (the upb compiler).
+
+
+/* upb_alloc ******************************************************************/
+
+static void *upb_global_allocfunc(upb_alloc *alloc, void *ptr, size_t oldsize,
+ size_t size) {
+ UPB_UNUSED(alloc);
+ UPB_UNUSED(oldsize);
+ if (size == 0) {
+ free(ptr);
+ return NULL;
+ } else {
+ return realloc(ptr, size);
+ }
+}
+
+upb_alloc upb_alloc_global = {&upb_global_allocfunc};
+
+
+/* upb_arena ******************************************************************/
+
+/* Be conservative and choose 16 in case anyone is using SSE. */
+static const size_t maxalign = 16;
+
+static size_t align_up(size_t size) {
+ return ((size + maxalign - 1) / maxalign) * maxalign;
+}
+
+typedef struct mem_block {
+ struct mem_block *next;
+ size_t size;
+ size_t used;
+ bool owned;
+ /* Data follows. */
+} mem_block;
+
+typedef struct cleanup_ent {
+ struct cleanup_ent *next;
+ upb_cleanup_func *cleanup;
+ void *ud;
+} cleanup_ent;
+
+static void upb_arena_addblock(upb_arena *a, void *ptr, size_t size,
+ bool owned) {
+ mem_block *block = ptr;
+
+ block->next = a->block_head;
+ block->size = size;
+ block->used = align_up(sizeof(mem_block));
+ block->owned = owned;
+
+ a->block_head = block;
+
+ /* TODO(haberman): ASAN poison. */
+}
+
+
+static mem_block *upb_arena_allocblock(upb_arena *a, size_t size) {
+ size_t block_size = UPB_MAX(size, a->next_block_size) + sizeof(mem_block);
+ mem_block *block = upb_malloc(a->block_alloc, block_size);
+
+ if (!block) {
+ return NULL;
+ }
+
+ upb_arena_addblock(a, block, block_size, true);
+ a->next_block_size = UPB_MIN(block_size * 2, a->max_block_size);
+
+ return block;
+}
+
+static void *upb_arena_doalloc(upb_alloc *alloc, void *ptr, size_t oldsize,
+ size_t size) {
+ upb_arena *a = (upb_arena*)alloc; /* upb_alloc is initial member. */
+ mem_block *block = a->block_head;
+ void *ret;
+
+ if (size == 0) {
+ return NULL; /* We are an arena, don't need individual frees. */
+ }
+
+ size = align_up(size);
+
+ /* TODO(haberman): special-case if this is a realloc of the last alloc? */
+
+ if (!block || block->size - block->used < size) {
+ /* Slow path: have to allocate a new block. */
+ block = upb_arena_allocblock(a, size);
+
+ if (!block) {
+ return NULL; /* Out of memory. */
+ }
+ }
+
+ ret = (char*)block + block->used;
+ block->used += size;
+
+ if (oldsize > 0) {
+ memcpy(ret, ptr, oldsize); /* Preserve existing data. */
+ }
+
+ /* TODO(haberman): ASAN unpoison. */
+
+ a->bytes_allocated += size;
+ return ret;
+}
+
+/* Public Arena API ***********************************************************/
+
+void upb_arena_init(upb_arena *a) {
+ a->alloc.func = &upb_arena_doalloc;
+ a->block_alloc = &upb_alloc_global;
+ a->bytes_allocated = 0;
+ a->next_block_size = 256;
+ a->max_block_size = 16384;
+ a->cleanup_head = NULL;
+ a->block_head = NULL;
+}
+
+void upb_arena_init2(upb_arena *a, void *mem, size_t size, upb_alloc *alloc) {
+ upb_arena_init(a);
+
+ if (size > sizeof(mem_block)) {
+ upb_arena_addblock(a, mem, size, false);
+ }
+
+ if (alloc) {
+ a->block_alloc = alloc;
+ }
+}
+
+void upb_arena_uninit(upb_arena *a) {
+ cleanup_ent *ent = a->cleanup_head;
+ mem_block *block = a->block_head;
+
+ while (ent) {
+ ent->cleanup(ent->ud);
+ ent = ent->next;
+ }
+
+ /* Must do this after running cleanup functions, because this will delete
+ * the memory we store our cleanup entries in! */
+ while (block) {
+ mem_block *next = block->next;
+
+ if (block->owned) {
+ upb_free(a->block_alloc, block);
+ }
+
+ block = next;
+ }
+}
+
+bool upb_arena_addcleanup(upb_arena *a, upb_cleanup_func *func, void *ud) {
+ cleanup_ent *ent = upb_malloc(&a->alloc, sizeof(cleanup_ent));
+ if (!ent) {
+ return false; /* Out of memory. */
+ }
+
+ ent->cleanup = func;
+ ent->ud = ud;
+ ent->next = a->cleanup_head;
+ a->cleanup_head = ent;
+
+ return true;
+}
+
+size_t upb_arena_bytesallocated(const upb_arena *a) {
+ return a->bytes_allocated;
+}
+
+
+/* Standard error functions ***************************************************/
+
+static bool default_err(void *ud, const upb_status *status) {
+ UPB_UNUSED(ud);
+ UPB_UNUSED(status);
+ return false;
+}
+
+static bool write_err_to(void *ud, const upb_status *status) {
+ upb_status *copy_to = ud;
+ upb_status_copy(copy_to, status);
+ return false;
+}
+
+
+/* upb_env ********************************************************************/
+
+void upb_env_initonly(upb_env *e) {
+ e->ok_ = true;
+ e->error_func_ = &default_err;
+ e->error_ud_ = NULL;
+}
+
+void upb_env_init(upb_env *e) {
+ upb_arena_init(&e->arena_);
+ upb_env_initonly(e);
+}
+
+void upb_env_init2(upb_env *e, void *mem, size_t n, upb_alloc *alloc) {
+ upb_arena_init2(&e->arena_, mem, n, alloc);
+ upb_env_initonly(e);
+}
+
+void upb_env_uninit(upb_env *e) {
+ upb_arena_uninit(&e->arena_);
+}
+
+void upb_env_seterrorfunc(upb_env *e, upb_error_func *func, void *ud) {
+ e->error_func_ = func;
+ e->error_ud_ = ud;
+}
+
+void upb_env_reporterrorsto(upb_env *e, upb_status *s) {
+ e->error_func_ = &write_err_to;
+ e->error_ud_ = s;
+}
+
+bool upb_env_reporterror(upb_env *e, const upb_status *status) {
+ e->ok_ = false;
+ return e->error_func_(e->error_ud_, status);
+}
+
+void *upb_env_malloc(upb_env *e, size_t size) {
+ return upb_malloc(&e->arena_.alloc, size);
+}
+
+void *upb_env_realloc(upb_env *e, void *ptr, size_t oldsize, size_t size) {
+ return upb_realloc(&e->arena_.alloc, ptr, oldsize, size);
+}
+
+void upb_env_free(upb_env *e, void *ptr) {
+ upb_free(&e->arena_.alloc, ptr);
+}
+
+bool upb_env_addcleanup(upb_env *e, upb_cleanup_func *func, void *ud) {
+ return upb_arena_addcleanup(&e->arena_, func, ud);
+}
+
+size_t upb_env_bytesallocated(const upb_env *e) {
+ return upb_arena_bytesallocated(&e->arena_);
+}
+/* This file was generated by upbc (the upb compiler) from the input
+ * file:
+ *
+ * upb/descriptor/descriptor.proto
+ *
* Do not edit -- your changes will be discarded when the file is
* regenerated. */
+#include <assert.h>
+
-static const upb_msgdef msgs[20];
-static const upb_fielddef fields[81];
-static const upb_enumdef enums[4];
+static const upb_msgdef msgs[22];
+static const upb_fielddef fields[105];
+static const upb_enumdef enums[5];
static const upb_tabent strentries[236];
-static const upb_tabent intentries[14];
-static const upb_tabval arrays[232];
+static const upb_tabent intentries[18];
+static const upb_tabval arrays[184];
#ifdef UPB_DEBUG_REFS
-static upb_inttable reftables[212];
+static upb_inttable reftables[264];
#endif
-static const upb_msgdef msgs[20] = {
- UPB_MSGDEF_INIT("google.protobuf.DescriptorProto", 27, 6, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[0], 8, 7), UPB_STRTABLE_INIT(7, 15, UPB_CTYPE_PTR, 4, &strentries[0]),&reftables[0], &reftables[1]),
- UPB_MSGDEF_INIT("google.protobuf.DescriptorProto.ExtensionRange", 4, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[8], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[16]),&reftables[2], &reftables[3]),
- UPB_MSGDEF_INIT("google.protobuf.EnumDescriptorProto", 11, 2, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[11], 4, 3), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[20]),&reftables[4], &reftables[5]),
- UPB_MSGDEF_INIT("google.protobuf.EnumOptions", 7, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[0], &arrays[15], 8, 1), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[24]),&reftables[6], &reftables[7]),
- UPB_MSGDEF_INIT("google.protobuf.EnumValueDescriptorProto", 8, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[23], 4, 3), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[28]),&reftables[8], &reftables[9]),
- UPB_MSGDEF_INIT("google.protobuf.EnumValueOptions", 6, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[2], &arrays[27], 4, 0), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[32]),&reftables[10], &reftables[11]),
- UPB_MSGDEF_INIT("google.protobuf.FieldDescriptorProto", 19, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[31], 9, 8), UPB_STRTABLE_INIT(8, 15, UPB_CTYPE_PTR, 4, &strentries[36]),&reftables[12], &reftables[13]),
- UPB_MSGDEF_INIT("google.protobuf.FieldOptions", 14, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[4], &arrays[40], 32, 6), UPB_STRTABLE_INIT(7, 15, UPB_CTYPE_PTR, 4, &strentries[52]),&reftables[14], &reftables[15]),
- UPB_MSGDEF_INIT("google.protobuf.FileDescriptorProto", 39, 6, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[72], 12, 11), UPB_STRTABLE_INIT(11, 15, UPB_CTYPE_PTR, 4, &strentries[68]),&reftables[16], &reftables[17]),
- UPB_MSGDEF_INIT("google.protobuf.FileDescriptorSet", 6, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[84], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[84]),&reftables[18], &reftables[19]),
- UPB_MSGDEF_INIT("google.protobuf.FileOptions", 21, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[6], &arrays[86], 64, 9), UPB_STRTABLE_INIT(10, 15, UPB_CTYPE_PTR, 4, &strentries[88]),&reftables[20], &reftables[21]),
- UPB_MSGDEF_INIT("google.protobuf.MessageOptions", 8, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[8], &arrays[150], 16, 2), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[104]),&reftables[22], &reftables[23]),
- UPB_MSGDEF_INIT("google.protobuf.MethodDescriptorProto", 13, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[166], 5, 4), UPB_STRTABLE_INIT(4, 7, UPB_CTYPE_PTR, 3, &strentries[108]),&reftables[24], &reftables[25]),
- UPB_MSGDEF_INIT("google.protobuf.MethodOptions", 6, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[10], &arrays[171], 4, 0), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[116]),&reftables[26], &reftables[27]),
- UPB_MSGDEF_INIT("google.protobuf.ServiceDescriptorProto", 11, 2, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[175], 4, 3), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[120]),&reftables[28], &reftables[29]),
- UPB_MSGDEF_INIT("google.protobuf.ServiceOptions", 6, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[12], &arrays[179], 4, 0), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[124]),&reftables[30], &reftables[31]),
- UPB_MSGDEF_INIT("google.protobuf.SourceCodeInfo", 6, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[183], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[128]),&reftables[32], &reftables[33]),
- UPB_MSGDEF_INIT("google.protobuf.SourceCodeInfo.Location", 14, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[185], 5, 4), UPB_STRTABLE_INIT(4, 7, UPB_CTYPE_PTR, 3, &strentries[132]),&reftables[34], &reftables[35]),
- UPB_MSGDEF_INIT("google.protobuf.UninterpretedOption", 18, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[190], 9, 7), UPB_STRTABLE_INIT(7, 15, UPB_CTYPE_PTR, 4, &strentries[140]),&reftables[36], &reftables[37]),
- UPB_MSGDEF_INIT("google.protobuf.UninterpretedOption.NamePart", 6, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[199], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[156]),&reftables[38], &reftables[39]),
+static const upb_msgdef msgs[22] = {
+ UPB_MSGDEF_INIT("google.protobuf.DescriptorProto", 40, 8, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[0], 11, 10), UPB_STRTABLE_INIT(10, 15, UPB_CTYPE_PTR, 4, &strentries[0]), false, UPB_SYNTAX_PROTO2, &reftables[0], &reftables[1]),
+ UPB_MSGDEF_INIT("google.protobuf.DescriptorProto.ExtensionRange", 4, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[11], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[16]), false, UPB_SYNTAX_PROTO2, &reftables[2], &reftables[3]),
+ UPB_MSGDEF_INIT("google.protobuf.DescriptorProto.ReservedRange", 4, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[14], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[20]), false, UPB_SYNTAX_PROTO2, &reftables[4], &reftables[5]),
+ UPB_MSGDEF_INIT("google.protobuf.EnumDescriptorProto", 11, 2, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[17], 4, 3), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[24]), false, UPB_SYNTAX_PROTO2, &reftables[6], &reftables[7]),
+ UPB_MSGDEF_INIT("google.protobuf.EnumOptions", 8, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[0], &arrays[21], 4, 2), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[28]), false, UPB_SYNTAX_PROTO2, &reftables[8], &reftables[9]),
+ UPB_MSGDEF_INIT("google.protobuf.EnumValueDescriptorProto", 8, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[25], 4, 3), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[32]), false, UPB_SYNTAX_PROTO2, &reftables[10], &reftables[11]),
+ UPB_MSGDEF_INIT("google.protobuf.EnumValueOptions", 7, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[2], &arrays[29], 2, 1), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[36]), false, UPB_SYNTAX_PROTO2, &reftables[12], &reftables[13]),
+ UPB_MSGDEF_INIT("google.protobuf.FieldDescriptorProto", 23, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[31], 11, 10), UPB_STRTABLE_INIT(10, 15, UPB_CTYPE_PTR, 4, &strentries[40]), false, UPB_SYNTAX_PROTO2, &reftables[14], &reftables[15]),
+ UPB_MSGDEF_INIT("google.protobuf.FieldOptions", 12, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[4], &arrays[42], 11, 6), UPB_STRTABLE_INIT(7, 15, UPB_CTYPE_PTR, 4, &strentries[56]), false, UPB_SYNTAX_PROTO2, &reftables[16], &reftables[17]),
+ UPB_MSGDEF_INIT("google.protobuf.FileDescriptorProto", 42, 6, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[53], 13, 12), UPB_STRTABLE_INIT(12, 15, UPB_CTYPE_PTR, 4, &strentries[72]), false, UPB_SYNTAX_PROTO2, &reftables[18], &reftables[19]),
+ UPB_MSGDEF_INIT("google.protobuf.FileDescriptorSet", 6, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[66], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[88]), false, UPB_SYNTAX_PROTO2, &reftables[20], &reftables[21]),
+ UPB_MSGDEF_INIT("google.protobuf.FileOptions", 31, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[6], &arrays[68], 39, 15), UPB_STRTABLE_INIT(16, 31, UPB_CTYPE_PTR, 5, &strentries[92]), false, UPB_SYNTAX_PROTO2, &reftables[22], &reftables[23]),
+ UPB_MSGDEF_INIT("google.protobuf.MessageOptions", 10, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[8], &arrays[107], 8, 4), UPB_STRTABLE_INIT(5, 7, UPB_CTYPE_PTR, 3, &strentries[124]), false, UPB_SYNTAX_PROTO2, &reftables[24], &reftables[25]),
+ UPB_MSGDEF_INIT("google.protobuf.MethodDescriptorProto", 15, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[115], 7, 6), UPB_STRTABLE_INIT(6, 7, UPB_CTYPE_PTR, 3, &strentries[132]), false, UPB_SYNTAX_PROTO2, &reftables[26], &reftables[27]),
+ UPB_MSGDEF_INIT("google.protobuf.MethodOptions", 7, 1, UPB_INTTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &intentries[10], &arrays[122], 1, 0), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[140]), false, UPB_SYNTAX_PROTO2, &reftables[28], &reftables[29]),
+ UPB_MSGDEF_INIT("google.protobuf.OneofDescriptorProto", 5, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[123], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[144]), false, UPB_SYNTAX_PROTO2, &reftables[30], &reftables[31]),
+ UPB_MSGDEF_INIT("google.protobuf.ServiceDescriptorProto", 11, 2, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[125], 4, 3), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[148]), false, UPB_SYNTAX_PROTO2, &reftables[32], &reftables[33]),
+ UPB_MSGDEF_INIT("google.protobuf.ServiceOptions", 7, 1, UPB_INTTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &intentries[14], &arrays[129], 1, 0), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[152]), false, UPB_SYNTAX_PROTO2, &reftables[34], &reftables[35]),
+ UPB_MSGDEF_INIT("google.protobuf.SourceCodeInfo", 6, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[130], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[156]), false, UPB_SYNTAX_PROTO2, &reftables[36], &reftables[37]),
+ UPB_MSGDEF_INIT("google.protobuf.SourceCodeInfo.Location", 19, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[132], 7, 5), UPB_STRTABLE_INIT(5, 7, UPB_CTYPE_PTR, 3, &strentries[160]), false, UPB_SYNTAX_PROTO2, &reftables[38], &reftables[39]),
+ UPB_MSGDEF_INIT("google.protobuf.UninterpretedOption", 18, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[139], 9, 7), UPB_STRTABLE_INIT(7, 15, UPB_CTYPE_PTR, 4, &strentries[168]), false, UPB_SYNTAX_PROTO2, &reftables[40], &reftables[41]),
+ UPB_MSGDEF_INIT("google.protobuf.UninterpretedOption.NamePart", 6, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[148], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[184]), false, UPB_SYNTAX_PROTO2, &reftables[42], &reftables[43]),
};
-static const upb_fielddef fields[81] = {
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "aggregate_value", 8, &msgs[18], NULL, 15, 6, {0},&reftables[40], &reftables[41]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "allow_alias", 2, &msgs[3], NULL, 6, 1, {0},&reftables[42], &reftables[43]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "cc_generic_services", 16, &msgs[10], NULL, 17, 6, {0},&reftables[44], &reftables[45]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "ctype", 1, &msgs[7], (const upb_def*)(&enums[2]), 6, 1, {0},&reftables[46], &reftables[47]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "default_value", 7, &msgs[6], NULL, 16, 7, {0},&reftables[48], &reftables[49]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_STRING, 0, false, false, false, false, "dependency", 3, &msgs[8], NULL, 30, 8, {0},&reftables[50], &reftables[51]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 3, &msgs[7], NULL, 8, 3, {0},&reftables[52], &reftables[53]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_DOUBLE, 0, false, false, false, false, "double_value", 6, &msgs[18], NULL, 11, 4, {0},&reftables[54], &reftables[55]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "end", 2, &msgs[1], NULL, 3, 1, {0},&reftables[56], &reftables[57]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "enum_type", 4, &msgs[0], (const upb_def*)(&msgs[2]), 16, 2, {0},&reftables[58], &reftables[59]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "enum_type", 5, &msgs[8], (const upb_def*)(&msgs[2]), 13, 1, {0},&reftables[60], &reftables[61]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "experimental_map_key", 9, &msgs[7], NULL, 10, 5, {0},&reftables[62], &reftables[63]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "extendee", 2, &msgs[6], NULL, 7, 2, {0},&reftables[64], &reftables[65]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "extension", 7, &msgs[8], (const upb_def*)(&msgs[6]), 19, 3, {0},&reftables[66], &reftables[67]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "extension", 6, &msgs[0], (const upb_def*)(&msgs[6]), 22, 4, {0},&reftables[68], &reftables[69]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "extension_range", 5, &msgs[0], (const upb_def*)(&msgs[1]), 19, 3, {0},&reftables[70], &reftables[71]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "field", 2, &msgs[0], (const upb_def*)(&msgs[6]), 10, 0, {0},&reftables[72], &reftables[73]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "file", 1, &msgs[9], (const upb_def*)(&msgs[8]), 5, 0, {0},&reftables[74], &reftables[75]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "go_package", 11, &msgs[10], NULL, 14, 5, {0},&reftables[76], &reftables[77]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "identifier_value", 3, &msgs[18], NULL, 6, 1, {0},&reftables[78], &reftables[79]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "input_type", 2, &msgs[12], NULL, 7, 2, {0},&reftables[80], &reftables[81]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REQUIRED, UPB_TYPE_BOOL, 0, false, false, false, false, "is_extension", 2, &msgs[19], NULL, 5, 1, {0},&reftables[82], &reftables[83]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "java_generate_equals_and_hash", 20, &msgs[10], NULL, 20, 9, {0},&reftables[84], &reftables[85]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "java_generic_services", 17, &msgs[10], NULL, 18, 7, {0},&reftables[86], &reftables[87]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "java_multiple_files", 10, &msgs[10], NULL, 13, 4, {0},&reftables[88], &reftables[89]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "java_outer_classname", 8, &msgs[10], NULL, 9, 2, {0},&reftables[90], &reftables[91]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "java_package", 1, &msgs[10], NULL, 6, 1, {0},&reftables[92], &reftables[93]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "label", 4, &msgs[6], (const upb_def*)(&enums[0]), 11, 4, {0},&reftables[94], &reftables[95]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "lazy", 5, &msgs[7], NULL, 9, 4, {0},&reftables[96], &reftables[97]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "leading_comments", 3, &msgs[17], NULL, 8, 2, {0},&reftables[98], &reftables[99]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "location", 1, &msgs[16], (const upb_def*)(&msgs[17]), 5, 0, {0},&reftables[100], &reftables[101]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "message_set_wire_format", 1, &msgs[11], NULL, 6, 1, {0},&reftables[102], &reftables[103]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "message_type", 4, &msgs[8], (const upb_def*)(&msgs[0]), 10, 0, {0},&reftables[104], &reftables[105]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "method", 2, &msgs[14], (const upb_def*)(&msgs[12]), 6, 0, {0},&reftables[106], &reftables[107]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[8], NULL, 22, 6, {0},&reftables[108], &reftables[109]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[14], NULL, 8, 2, {0},&reftables[110], &reftables[111]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "name", 2, &msgs[18], (const upb_def*)(&msgs[19]), 5, 0, {0},&reftables[112], &reftables[113]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[4], NULL, 4, 1, {0},&reftables[114], &reftables[115]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[0], NULL, 24, 6, {0},&reftables[116], &reftables[117]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[12], NULL, 4, 1, {0},&reftables[118], &reftables[119]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[2], NULL, 8, 2, {0},&reftables[120], &reftables[121]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[6], NULL, 4, 1, {0},&reftables[122], &reftables[123]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REQUIRED, UPB_TYPE_STRING, 0, false, false, false, false, "name_part", 1, &msgs[19], NULL, 2, 0, {0},&reftables[124], &reftables[125]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT64, UPB_INTFMT_VARIABLE, false, false, false, false, "negative_int_value", 5, &msgs[18], NULL, 10, 3, {0},&reftables[126], &reftables[127]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "nested_type", 3, &msgs[0], (const upb_def*)(&msgs[0]), 13, 1, {0},&reftables[128], &reftables[129]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "no_standard_descriptor_accessor", 2, &msgs[11], NULL, 7, 2, {0},&reftables[130], &reftables[131]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "number", 3, &msgs[6], NULL, 10, 3, {0},&reftables[132], &reftables[133]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "number", 2, &msgs[4], NULL, 7, 2, {0},&reftables[134], &reftables[135]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "optimize_for", 9, &msgs[10], (const upb_def*)(&enums[3]), 12, 3, {0},&reftables[136], &reftables[137]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 7, &msgs[0], (const upb_def*)(&msgs[11]), 23, 5, {0},&reftables[138], &reftables[139]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 3, &msgs[2], (const upb_def*)(&msgs[3]), 7, 1, {0},&reftables[140], &reftables[141]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 8, &msgs[6], (const upb_def*)(&msgs[7]), 3, 0, {0},&reftables[142], &reftables[143]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 3, &msgs[4], (const upb_def*)(&msgs[5]), 3, 0, {0},&reftables[144], &reftables[145]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 8, &msgs[8], (const upb_def*)(&msgs[10]), 20, 4, {0},&reftables[146], &reftables[147]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 3, &msgs[14], (const upb_def*)(&msgs[15]), 7, 1, {0},&reftables[148], &reftables[149]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 4, &msgs[12], (const upb_def*)(&msgs[13]), 3, 0, {0},&reftables[150], &reftables[151]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "output_type", 3, &msgs[12], NULL, 10, 3, {0},&reftables[152], &reftables[153]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "package", 2, &msgs[8], NULL, 25, 7, {0},&reftables[154], &reftables[155]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "packed", 2, &msgs[7], NULL, 7, 2, {0},&reftables[156], &reftables[157]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, true, "path", 1, &msgs[17], NULL, 4, 0, {0},&reftables[158], &reftables[159]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_UINT64, UPB_INTFMT_VARIABLE, false, false, false, false, "positive_int_value", 4, &msgs[18], NULL, 9, 2, {0},&reftables[160], &reftables[161]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "public_dependency", 10, &msgs[8], NULL, 35, 9, {0},&reftables[162], &reftables[163]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "py_generic_services", 18, &msgs[10], NULL, 19, 8, {0},&reftables[164], &reftables[165]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "service", 6, &msgs[8], (const upb_def*)(&msgs[14]), 16, 2, {0},&reftables[166], &reftables[167]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "source_code_info", 9, &msgs[8], (const upb_def*)(&msgs[16]), 21, 5, {0},&reftables[168], &reftables[169]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, true, "span", 2, &msgs[17], NULL, 7, 1, {0},&reftables[170], &reftables[171]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "start", 1, &msgs[1], NULL, 2, 0, {0},&reftables[172], &reftables[173]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BYTES, 0, false, false, false, false, "string_value", 7, &msgs[18], NULL, 12, 5, {0},&reftables[174], &reftables[175]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "trailing_comments", 4, &msgs[17], NULL, 11, 3, {0},&reftables[176], &reftables[177]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "type", 5, &msgs[6], (const upb_def*)(&enums[1]), 12, 5, {0},&reftables[178], &reftables[179]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "type_name", 6, &msgs[6], NULL, 13, 6, {0},&reftables[180], &reftables[181]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[5], (const upb_def*)(&msgs[18]), 5, 0, {0},&reftables[182], &reftables[183]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[15], (const upb_def*)(&msgs[18]), 5, 0, {0},&reftables[184], &reftables[185]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[3], (const upb_def*)(&msgs[18]), 5, 0, {0},&reftables[186], &reftables[187]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[13], (const upb_def*)(&msgs[18]), 5, 0, {0},&reftables[188], &reftables[189]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[10], (const upb_def*)(&msgs[18]), 5, 0, {0},&reftables[190], &reftables[191]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[11], (const upb_def*)(&msgs[18]), 5, 0, {0},&reftables[192], &reftables[193]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[7], (const upb_def*)(&msgs[18]), 5, 0, {0},&reftables[194], &reftables[195]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "value", 2, &msgs[2], (const upb_def*)(&msgs[4]), 6, 0, {0},&reftables[196], &reftables[197]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "weak", 10, &msgs[7], NULL, 13, 6, {0},&reftables[198], &reftables[199]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "weak_dependency", 11, &msgs[8], NULL, 38, 10, {0},&reftables[200], &reftables[201]),
+static const upb_fielddef fields[105] = {
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "aggregate_value", 8, &msgs[20], NULL, 15, 6, {0},&reftables[44], &reftables[45]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "allow_alias", 2, &msgs[4], NULL, 6, 1, {0},&reftables[46], &reftables[47]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "cc_enable_arenas", 31, &msgs[11], NULL, 23, 12, {0},&reftables[48], &reftables[49]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "cc_generic_services", 16, &msgs[11], NULL, 17, 6, {0},&reftables[50], &reftables[51]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "client_streaming", 5, &msgs[13], NULL, 13, 4, {0},&reftables[52], &reftables[53]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "csharp_namespace", 37, &msgs[11], NULL, 27, 14, {0},&reftables[54], &reftables[55]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "ctype", 1, &msgs[8], (const upb_def*)(&enums[2]), 6, 1, {0},&reftables[56], &reftables[57]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "default_value", 7, &msgs[7], NULL, 16, 7, {0},&reftables[58], &reftables[59]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_STRING, 0, false, false, false, false, "dependency", 3, &msgs[9], NULL, 30, 8, {0},&reftables[60], &reftables[61]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 3, &msgs[12], NULL, 8, 3, {0},&reftables[62], &reftables[63]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 3, &msgs[8], NULL, 8, 3, {0},&reftables[64], &reftables[65]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 33, &msgs[14], NULL, 6, 1, {0},&reftables[66], &reftables[67]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 23, &msgs[11], NULL, 21, 10, {0},&reftables[68], &reftables[69]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 3, &msgs[4], NULL, 7, 2, {0},&reftables[70], &reftables[71]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 33, &msgs[17], NULL, 6, 1, {0},&reftables[72], &reftables[73]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 1, &msgs[6], NULL, 6, 1, {0},&reftables[74], &reftables[75]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_DOUBLE, 0, false, false, false, false, "double_value", 6, &msgs[20], NULL, 11, 4, {0},&reftables[76], &reftables[77]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "end", 2, &msgs[2], NULL, 3, 1, {0},&reftables[78], &reftables[79]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "end", 2, &msgs[1], NULL, 3, 1, {0},&reftables[80], &reftables[81]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "enum_type", 4, &msgs[0], (const upb_def*)(&msgs[3]), 18, 2, {0},&reftables[82], &reftables[83]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "enum_type", 5, &msgs[9], (const upb_def*)(&msgs[3]), 13, 1, {0},&reftables[84], &reftables[85]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "extendee", 2, &msgs[7], NULL, 7, 2, {0},&reftables[86], &reftables[87]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "extension", 6, &msgs[0], (const upb_def*)(&msgs[7]), 24, 4, {0},&reftables[88], &reftables[89]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "extension", 7, &msgs[9], (const upb_def*)(&msgs[7]), 19, 3, {0},&reftables[90], &reftables[91]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "extension_range", 5, &msgs[0], (const upb_def*)(&msgs[1]), 21, 3, {0},&reftables[92], &reftables[93]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "field", 2, &msgs[0], (const upb_def*)(&msgs[7]), 12, 0, {0},&reftables[94], &reftables[95]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "file", 1, &msgs[10], (const upb_def*)(&msgs[9]), 5, 0, {0},&reftables[96], &reftables[97]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "go_package", 11, &msgs[11], NULL, 14, 5, {0},&reftables[98], &reftables[99]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "identifier_value", 3, &msgs[20], NULL, 6, 1, {0},&reftables[100], &reftables[101]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "input_type", 2, &msgs[13], NULL, 7, 2, {0},&reftables[102], &reftables[103]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REQUIRED, UPB_TYPE_BOOL, 0, false, false, false, false, "is_extension", 2, &msgs[21], NULL, 5, 1, {0},&reftables[104], &reftables[105]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "java_generate_equals_and_hash", 20, &msgs[11], NULL, 20, 9, {0},&reftables[106], &reftables[107]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "java_generic_services", 17, &msgs[11], NULL, 18, 7, {0},&reftables[108], &reftables[109]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "java_multiple_files", 10, &msgs[11], NULL, 13, 4, {0},&reftables[110], &reftables[111]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "java_outer_classname", 8, &msgs[11], NULL, 9, 2, {0},&reftables[112], &reftables[113]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "java_package", 1, &msgs[11], NULL, 6, 1, {0},&reftables[114], &reftables[115]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "java_string_check_utf8", 27, &msgs[11], NULL, 22, 11, {0},&reftables[116], &reftables[117]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "javanano_use_deprecated_package", 38, &msgs[11], NULL, 30, 15, {0},&reftables[118], &reftables[119]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "json_name", 10, &msgs[7], NULL, 20, 9, {0},&reftables[120], &reftables[121]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "jstype", 6, &msgs[8], (const upb_def*)(&enums[3]), 10, 5, {0},&reftables[122], &reftables[123]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "label", 4, &msgs[7], (const upb_def*)(&enums[0]), 11, 4, {0},&reftables[124], &reftables[125]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "lazy", 5, &msgs[8], NULL, 9, 4, {0},&reftables[126], &reftables[127]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "leading_comments", 3, &msgs[19], NULL, 8, 2, {0},&reftables[128], &reftables[129]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_STRING, 0, false, false, false, false, "leading_detached_comments", 6, &msgs[19], NULL, 16, 4, {0},&reftables[130], &reftables[131]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "location", 1, &msgs[18], (const upb_def*)(&msgs[19]), 5, 0, {0},&reftables[132], &reftables[133]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "map_entry", 7, &msgs[12], NULL, 9, 4, {0},&reftables[134], &reftables[135]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "message_set_wire_format", 1, &msgs[12], NULL, 6, 1, {0},&reftables[136], &reftables[137]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "message_type", 4, &msgs[9], (const upb_def*)(&msgs[0]), 10, 0, {0},&reftables[138], &reftables[139]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "method", 2, &msgs[16], (const upb_def*)(&msgs[13]), 6, 0, {0},&reftables[140], &reftables[141]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[3], NULL, 8, 2, {0},&reftables[142], &reftables[143]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[15], NULL, 2, 0, {0},&reftables[144], &reftables[145]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "name", 2, &msgs[20], (const upb_def*)(&msgs[21]), 5, 0, {0},&reftables[146], &reftables[147]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[0], NULL, 32, 8, {0},&reftables[148], &reftables[149]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[5], NULL, 4, 1, {0},&reftables[150], &reftables[151]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[9], NULL, 22, 6, {0},&reftables[152], &reftables[153]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[7], NULL, 4, 1, {0},&reftables[154], &reftables[155]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[13], NULL, 4, 1, {0},&reftables[156], &reftables[157]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[16], NULL, 8, 2, {0},&reftables[158], &reftables[159]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REQUIRED, UPB_TYPE_STRING, 0, false, false, false, false, "name_part", 1, &msgs[21], NULL, 2, 0, {0},&reftables[160], &reftables[161]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT64, UPB_INTFMT_VARIABLE, false, false, false, false, "negative_int_value", 5, &msgs[20], NULL, 10, 3, {0},&reftables[162], &reftables[163]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "nested_type", 3, &msgs[0], (const upb_def*)(&msgs[0]), 15, 1, {0},&reftables[164], &reftables[165]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "no_standard_descriptor_accessor", 2, &msgs[12], NULL, 7, 2, {0},&reftables[166], &reftables[167]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "number", 2, &msgs[5], NULL, 7, 2, {0},&reftables[168], &reftables[169]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "number", 3, &msgs[7], NULL, 10, 3, {0},&reftables[170], &reftables[171]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "objc_class_prefix", 36, &msgs[11], NULL, 24, 13, {0},&reftables[172], &reftables[173]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "oneof_decl", 8, &msgs[0], (const upb_def*)(&msgs[15]), 28, 6, {0},&reftables[174], &reftables[175]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "oneof_index", 9, &msgs[7], NULL, 19, 8, {0},&reftables[176], &reftables[177]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "optimize_for", 9, &msgs[11], (const upb_def*)(&enums[4]), 12, 3, {0},&reftables[178], &reftables[179]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 7, &msgs[0], (const upb_def*)(&msgs[12]), 25, 5, {0},&reftables[180], &reftables[181]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 8, &msgs[9], (const upb_def*)(&msgs[11]), 20, 4, {0},&reftables[182], &reftables[183]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 4, &msgs[13], (const upb_def*)(&msgs[14]), 3, 0, {0},&reftables[184], &reftables[185]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 8, &msgs[7], (const upb_def*)(&msgs[8]), 3, 0, {0},&reftables[186], &reftables[187]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 3, &msgs[16], (const upb_def*)(&msgs[17]), 7, 1, {0},&reftables[188], &reftables[189]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 3, &msgs[5], (const upb_def*)(&msgs[6]), 3, 0, {0},&reftables[190], &reftables[191]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 3, &msgs[3], (const upb_def*)(&msgs[4]), 7, 1, {0},&reftables[192], &reftables[193]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "output_type", 3, &msgs[13], NULL, 10, 3, {0},&reftables[194], &reftables[195]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "package", 2, &msgs[9], NULL, 25, 7, {0},&reftables[196], &reftables[197]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "packed", 2, &msgs[8], NULL, 7, 2, {0},&reftables[198], &reftables[199]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, true, "path", 1, &msgs[19], NULL, 4, 0, {0},&reftables[200], &reftables[201]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_UINT64, UPB_INTFMT_VARIABLE, false, false, false, false, "positive_int_value", 4, &msgs[20], NULL, 9, 2, {0},&reftables[202], &reftables[203]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "public_dependency", 10, &msgs[9], NULL, 35, 9, {0},&reftables[204], &reftables[205]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "py_generic_services", 18, &msgs[11], NULL, 19, 8, {0},&reftables[206], &reftables[207]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_STRING, 0, false, false, false, false, "reserved_name", 10, &msgs[0], NULL, 37, 9, {0},&reftables[208], &reftables[209]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "reserved_range", 9, &msgs[0], (const upb_def*)(&msgs[2]), 31, 7, {0},&reftables[210], &reftables[211]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "server_streaming", 6, &msgs[13], NULL, 14, 5, {0},&reftables[212], &reftables[213]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "service", 6, &msgs[9], (const upb_def*)(&msgs[16]), 16, 2, {0},&reftables[214], &reftables[215]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "source_code_info", 9, &msgs[9], (const upb_def*)(&msgs[18]), 21, 5, {0},&reftables[216], &reftables[217]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, true, "span", 2, &msgs[19], NULL, 7, 1, {0},&reftables[218], &reftables[219]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "start", 1, &msgs[2], NULL, 2, 0, {0},&reftables[220], &reftables[221]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "start", 1, &msgs[1], NULL, 2, 0, {0},&reftables[222], &reftables[223]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BYTES, 0, false, false, false, false, "string_value", 7, &msgs[20], NULL, 12, 5, {0},&reftables[224], &reftables[225]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "syntax", 12, &msgs[9], NULL, 39, 11, {0},&reftables[226], &reftables[227]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "trailing_comments", 4, &msgs[19], NULL, 11, 3, {0},&reftables[228], &reftables[229]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "type", 5, &msgs[7], (const upb_def*)(&enums[1]), 12, 5, {0},&reftables[230], &reftables[231]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "type_name", 6, &msgs[7], NULL, 13, 6, {0},&reftables[232], &reftables[233]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[11], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[234], &reftables[235]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[12], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[236], &reftables[237]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[6], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[238], &reftables[239]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[4], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[240], &reftables[241]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[8], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[242], &reftables[243]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[14], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[244], &reftables[245]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[17], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[246], &reftables[247]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "value", 2, &msgs[3], (const upb_def*)(&msgs[5]), 6, 0, {0},&reftables[248], &reftables[249]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "weak", 10, &msgs[8], NULL, 11, 6, {0},&reftables[250], &reftables[251]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "weak_dependency", 11, &msgs[9], NULL, 38, 10, {0},&reftables[252], &reftables[253]),
};
-static const upb_enumdef enums[4] = {
- UPB_ENUMDEF_INIT("google.protobuf.FieldDescriptorProto.Label", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &strentries[160]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[202], 4, 3), 0, &reftables[202], &reftables[203]),
- UPB_ENUMDEF_INIT("google.protobuf.FieldDescriptorProto.Type", UPB_STRTABLE_INIT(18, 31, UPB_CTYPE_INT32, 5, &strentries[164]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[206], 19, 18), 0, &reftables[204], &reftables[205]),
- UPB_ENUMDEF_INIT("google.protobuf.FieldOptions.CType", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &strentries[196]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[225], 3, 3), 0, &reftables[206], &reftables[207]),
- UPB_ENUMDEF_INIT("google.protobuf.FileOptions.OptimizeMode", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &strentries[200]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[228], 4, 3), 0, &reftables[208], &reftables[209]),
+static const upb_enumdef enums[5] = {
+ UPB_ENUMDEF_INIT("google.protobuf.FieldDescriptorProto.Label", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &strentries[188]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[151], 4, 3), 0, &reftables[254], &reftables[255]),
+ UPB_ENUMDEF_INIT("google.protobuf.FieldDescriptorProto.Type", UPB_STRTABLE_INIT(18, 31, UPB_CTYPE_INT32, 5, &strentries[192]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[155], 19, 18), 0, &reftables[256], &reftables[257]),
+ UPB_ENUMDEF_INIT("google.protobuf.FieldOptions.CType", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &strentries[224]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[174], 3, 3), 0, &reftables[258], &reftables[259]),
+ UPB_ENUMDEF_INIT("google.protobuf.FieldOptions.JSType", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &strentries[228]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[177], 3, 3), 0, &reftables[260], &reftables[261]),
+ UPB_ENUMDEF_INIT("google.protobuf.FileOptions.OptimizeMode", UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_INT32, 2, &strentries[232]), UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_CSTR, 0, NULL, &arrays[180], 4, 3), 0, &reftables[262], &reftables[263]),
};
static const upb_tabent strentries[236] = {
- {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "extension"), UPB_TABVALUE_PTR_INIT(&fields[14]), NULL},
+ {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "extension"), UPB_TABVALUE_PTR_INIT(&fields[22]), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\015", "\000", "\000", "\000", "reserved_name"), UPB_TABVALUE_PTR_INIT(&fields[82]), NULL},
+ {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[52]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[38]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "field"), UPB_TABVALUE_PTR_INIT(&fields[25]), &strentries[12]},
+ {UPB_TABKEY_STR("\017", "\000", "\000", "\000", "extension_range"), UPB_TABVALUE_PTR_INIT(&fields[24]), &strentries[14]},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "nested_type"), UPB_TABVALUE_PTR_INIT(&fields[60]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "field"), UPB_TABVALUE_PTR_INIT(&fields[16]), NULL},
- {UPB_TABKEY_STR("\017", "\000", "\000", "\000", "extension_range"), UPB_TABVALUE_PTR_INIT(&fields[15]), NULL},
+ {UPB_TABKEY_STR("\016", "\000", "\000", "\000", "reserved_range"), UPB_TABVALUE_PTR_INIT(&fields[83]), NULL},
+ {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[68]), NULL},
+ {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "oneof_decl"), UPB_TABVALUE_PTR_INIT(&fields[65]), NULL},
+ {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "enum_type"), UPB_TABVALUE_PTR_INIT(&fields[19]), &strentries[13]},
+ {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "start"), UPB_TABVALUE_PTR_INIT(&fields[89]), NULL},
+ {UPB_TABKEY_STR("\003", "\000", "\000", "\000", "end"), UPB_TABVALUE_PTR_INIT(&fields[18]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "nested_type"), UPB_TABVALUE_PTR_INIT(&fields[44]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "start"), UPB_TABVALUE_PTR_INIT(&fields[88]), NULL},
+ {UPB_TABKEY_STR("\003", "\000", "\000", "\000", "end"), UPB_TABVALUE_PTR_INIT(&fields[17]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[49]), NULL},
- {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "enum_type"), UPB_TABVALUE_PTR_INIT(&fields[9]), &strentries[14]},
- {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "start"), UPB_TABVALUE_PTR_INIT(&fields[66]), NULL},
- {UPB_TABKEY_STR("\003", "\000", "\000", "\000", "end"), UPB_TABVALUE_PTR_INIT(&fields[8]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "value"), UPB_TABVALUE_PTR_INIT(&fields[102]), NULL},
+ {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[74]), NULL},
+ {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[49]), &strentries[26]},
+ {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[98]), NULL},
+ {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[13]), NULL},
+ {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "allow_alias"), UPB_TABVALUE_PTR_INIT(&fields[1]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "number"), UPB_TABVALUE_PTR_INIT(&fields[62]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "value"), UPB_TABVALUE_PTR_INIT(&fields[78]), NULL},
- {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[50]), NULL},
- {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[40]), &strentries[22]},
- {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[73]), NULL},
+ {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[73]), NULL},
+ {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[53]), &strentries[34]},
+ {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[97]), NULL},
+ {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[15]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "allow_alias"), UPB_TABVALUE_PTR_INIT(&fields[1]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "number"), UPB_TABVALUE_PTR_INIT(&fields[47]), NULL},
+ {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "oneof_index"), UPB_TABVALUE_PTR_INIT(&fields[66]), NULL},
+ {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "label"), UPB_TABVALUE_PTR_INIT(&fields[40]), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[55]), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[52]), NULL},
- {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[37]), &strentries[30]},
- {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[71]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "number"), UPB_TABVALUE_PTR_INIT(&fields[63]), &strentries[53]},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\010", "\000", "\000", "\000", "extendee"), UPB_TABVALUE_PTR_INIT(&fields[21]), NULL},
+ {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "type_name"), UPB_TABVALUE_PTR_INIT(&fields[94]), NULL},
+ {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "json_name"), UPB_TABVALUE_PTR_INIT(&fields[38]), NULL},
+ {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "type"), UPB_TABVALUE_PTR_INIT(&fields[93]), &strentries[50]},
+ {UPB_TABKEY_STR("\015", "\000", "\000", "\000", "default_value"), UPB_TABVALUE_PTR_INIT(&fields[7]), NULL},
+ {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[71]), NULL},
+ {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[99]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "label"), UPB_TABVALUE_PTR_INIT(&fields[27]), NULL},
+ {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "weak"), UPB_TABVALUE_PTR_INIT(&fields[103]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[41]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "packed"), UPB_TABVALUE_PTR_INIT(&fields[77]), NULL},
+ {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "lazy"), UPB_TABVALUE_PTR_INIT(&fields[41]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "number"), UPB_TABVALUE_PTR_INIT(&fields[46]), &strentries[49]},
+ {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "ctype"), UPB_TABVALUE_PTR_INIT(&fields[6]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "jstype"), UPB_TABVALUE_PTR_INIT(&fields[39]), NULL},
+ {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[10]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "type_name"), UPB_TABVALUE_PTR_INIT(&fields[70]), NULL},
- {UPB_TABKEY_STR("\010", "\000", "\000", "\000", "extendee"), UPB_TABVALUE_PTR_INIT(&fields[12]), NULL},
- {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "type"), UPB_TABVALUE_PTR_INIT(&fields[69]), &strentries[48]},
- {UPB_TABKEY_STR("\015", "\000", "\000", "\000", "default_value"), UPB_TABVALUE_PTR_INIT(&fields[4]), NULL},
- {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[51]), NULL},
- {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "experimental_map_key"), UPB_TABVALUE_PTR_INIT(&fields[11]), &strentries[67]},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "weak"), UPB_TABVALUE_PTR_INIT(&fields[79]), NULL},
+ {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "extension"), UPB_TABVALUE_PTR_INIT(&fields[23]), NULL},
+ {UPB_TABKEY_STR("\017", "\000", "\000", "\000", "weak_dependency"), UPB_TABVALUE_PTR_INIT(&fields[104]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[54]), NULL},
+ {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "service"), UPB_TABVALUE_PTR_INIT(&fields[85]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "source_code_info"), UPB_TABVALUE_PTR_INIT(&fields[86]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "packed"), UPB_TABVALUE_PTR_INIT(&fields[58]), NULL},
- {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "lazy"), UPB_TABVALUE_PTR_INIT(&fields[28]), NULL},
+ {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "syntax"), UPB_TABVALUE_PTR_INIT(&fields[91]), NULL},
+ {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "dependency"), UPB_TABVALUE_PTR_INIT(&fields[8]), NULL},
+ {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "message_type"), UPB_TABVALUE_PTR_INIT(&fields[47]), NULL},
+ {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "package"), UPB_TABVALUE_PTR_INIT(&fields[76]), NULL},
+ {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[69]), &strentries[86]},
+ {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "enum_type"), UPB_TABVALUE_PTR_INIT(&fields[20]), NULL},
+ {UPB_TABKEY_STR("\021", "\000", "\000", "\000", "public_dependency"), UPB_TABVALUE_PTR_INIT(&fields[80]), &strentries[85]},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "ctype"), UPB_TABVALUE_PTR_INIT(&fields[3]), NULL},
+ {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "file"), UPB_TABVALUE_PTR_INIT(&fields[26]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[6]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[77]), NULL},
- {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "extension"), UPB_TABVALUE_PTR_INIT(&fields[13]), NULL},
- {UPB_TABKEY_STR("\017", "\000", "\000", "\000", "weak_dependency"), UPB_TABVALUE_PTR_INIT(&fields[80]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[34]), NULL},
- {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "service"), UPB_TABVALUE_PTR_INIT(&fields[63]), NULL},
+ {UPB_TABKEY_STR("\023", "\000", "\000", "\000", "cc_generic_services"), UPB_TABVALUE_PTR_INIT(&fields[3]), NULL},
+ {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "csharp_namespace"), UPB_TABVALUE_PTR_INIT(&fields[5]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "source_code_info"), UPB_TABVALUE_PTR_INIT(&fields[64]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "dependency"), UPB_TABVALUE_PTR_INIT(&fields[5]), NULL},
- {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "message_type"), UPB_TABVALUE_PTR_INIT(&fields[32]), NULL},
- {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "package"), UPB_TABVALUE_PTR_INIT(&fields[57]), NULL},
- {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[53]), &strentries[82]},
- {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "enum_type"), UPB_TABVALUE_PTR_INIT(&fields[10]), NULL},
- {UPB_TABKEY_STR("\021", "\000", "\000", "\000", "public_dependency"), UPB_TABVALUE_PTR_INIT(&fields[61]), &strentries[81]},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "file"), UPB_TABVALUE_PTR_INIT(&fields[17]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[75]), NULL},
+ {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "go_package"), UPB_TABVALUE_PTR_INIT(&fields[27]), NULL},
+ {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "java_package"), UPB_TABVALUE_PTR_INIT(&fields[35]), &strentries[120]},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_STR("\023", "\000", "\000", "\000", "cc_generic_services"), UPB_TABVALUE_PTR_INIT(&fields[2]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_STR("\023", "\000", "\000", "\000", "java_multiple_files"), UPB_TABVALUE_PTR_INIT(&fields[24]), NULL},
+ {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "java_outer_classname"), UPB_TABVALUE_PTR_INIT(&fields[34]), NULL},
+ {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[95]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_STR("\025", "\000", "\000", "\000", "java_generic_services"), UPB_TABVALUE_PTR_INIT(&fields[23]), &strentries[102]},
- {UPB_TABKEY_STR("\035", "\000", "\000", "\000", "java_generate_equals_and_hash"), UPB_TABVALUE_PTR_INIT(&fields[22]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\023", "\000", "\000", "\000", "java_multiple_files"), UPB_TABVALUE_PTR_INIT(&fields[33]), &strentries[117]},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "go_package"), UPB_TABVALUE_PTR_INIT(&fields[18]), NULL},
- {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "java_package"), UPB_TABVALUE_PTR_INIT(&fields[26]), NULL},
- {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "optimize_for"), UPB_TABVALUE_PTR_INIT(&fields[48]), NULL},
- {UPB_TABKEY_STR("\023", "\000", "\000", "\000", "py_generic_services"), UPB_TABVALUE_PTR_INIT(&fields[62]), NULL},
- {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "java_outer_classname"), UPB_TABVALUE_PTR_INIT(&fields[25]), NULL},
- {UPB_TABKEY_STR("\027", "\000", "\000", "\000", "message_set_wire_format"), UPB_TABVALUE_PTR_INIT(&fields[31]), &strentries[106]},
+ {UPB_TABKEY_STR("\025", "\000", "\000", "\000", "java_generic_services"), UPB_TABVALUE_PTR_INIT(&fields[32]), &strentries[118]},
+ {UPB_TABKEY_STR("\035", "\000", "\000", "\000", "java_generate_equals_and_hash"), UPB_TABVALUE_PTR_INIT(&fields[31]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[76]), NULL},
- {UPB_TABKEY_STR("\037", "\000", "\000", "\000", "no_standard_descriptor_accessor"), UPB_TABVALUE_PTR_INIT(&fields[45]), NULL},
+ {UPB_TABKEY_STR("\037", "\000", "\000", "\000", "javanano_use_deprecated_package"), UPB_TABVALUE_PTR_INIT(&fields[37]), &strentries[123]},
+ {UPB_TABKEY_STR("\023", "\000", "\000", "\000", "py_generic_services"), UPB_TABVALUE_PTR_INIT(&fields[81]), NULL},
+ {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "optimize_for"), UPB_TABVALUE_PTR_INIT(&fields[67]), NULL},
+ {UPB_TABKEY_STR("\026", "\000", "\000", "\000", "java_string_check_utf8"), UPB_TABVALUE_PTR_INIT(&fields[36]), NULL},
+ {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[12]), &strentries[119]},
+ {UPB_TABKEY_STR("\021", "\000", "\000", "\000", "objc_class_prefix"), UPB_TABVALUE_PTR_INIT(&fields[64]), NULL},
+ {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "cc_enable_arenas"), UPB_TABVALUE_PTR_INIT(&fields[2]), NULL},
+ {UPB_TABKEY_STR("\027", "\000", "\000", "\000", "message_set_wire_format"), UPB_TABVALUE_PTR_INIT(&fields[46]), &strentries[128]},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[39]), NULL},
- {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "input_type"), UPB_TABVALUE_PTR_INIT(&fields[20]), NULL},
+ {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[96]), NULL},
+ {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[9]), NULL},
+ {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "map_entry"), UPB_TABVALUE_PTR_INIT(&fields[45]), NULL},
+ {UPB_TABKEY_STR("\037", "\000", "\000", "\000", "no_standard_descriptor_accessor"), UPB_TABVALUE_PTR_INIT(&fields[61]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "output_type"), UPB_TABVALUE_PTR_INIT(&fields[56]), NULL},
- {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[55]), NULL},
- {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[74]), NULL},
+ {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "client_streaming"), UPB_TABVALUE_PTR_INIT(&fields[4]), NULL},
+ {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "server_streaming"), UPB_TABVALUE_PTR_INIT(&fields[84]), NULL},
+ {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[56]), NULL},
+ {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "input_type"), UPB_TABVALUE_PTR_INIT(&fields[29]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "output_type"), UPB_TABVALUE_PTR_INIT(&fields[75]), NULL},
+ {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[70]), NULL},
+ {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[100]), NULL},
+ {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[11]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[54]), &strentries[122]},
- {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "method"), UPB_TABVALUE_PTR_INIT(&fields[33]), NULL},
- {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[35]), &strentries[121]},
- {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[72]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[50]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\007", "\000", "\000", "\000", "options"), UPB_TABVALUE_PTR_INIT(&fields[72]), &strentries[150]},
+ {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "method"), UPB_TABVALUE_PTR_INIT(&fields[48]), NULL},
+ {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[57]), &strentries[149]},
+ {UPB_TABKEY_STR("\024", "\000", "\000", "\000", "uninterpreted_option"), UPB_TABVALUE_PTR_INIT(&fields[101]), NULL},
+ {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "deprecated"), UPB_TABVALUE_PTR_INIT(&fields[14]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_STR("\010", "\000", "\000", "\000", "location"), UPB_TABVALUE_PTR_INIT(&fields[30]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\010", "\000", "\000", "\000", "location"), UPB_TABVALUE_PTR_INIT(&fields[44]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "span"), UPB_TABVALUE_PTR_INIT(&fields[65]), &strentries[139]},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_STR("\021", "\000", "\000", "\000", "trailing_comments"), UPB_TABVALUE_PTR_INIT(&fields[68]), NULL},
- {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "leading_comments"), UPB_TABVALUE_PTR_INIT(&fields[29]), &strentries[137]},
- {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "path"), UPB_TABVALUE_PTR_INIT(&fields[59]), NULL},
- {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "double_value"), UPB_TABVALUE_PTR_INIT(&fields[7]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "span"), UPB_TABVALUE_PTR_INIT(&fields[87]), &strentries[167]},
+ {UPB_TABKEY_STR("\031", "\000", "\000", "\000", "leading_detached_comments"), UPB_TABVALUE_PTR_INIT(&fields[43]), &strentries[165]},
+ {UPB_TABKEY_STR("\021", "\000", "\000", "\000", "trailing_comments"), UPB_TABVALUE_PTR_INIT(&fields[92]), NULL},
+ {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "leading_comments"), UPB_TABVALUE_PTR_INIT(&fields[42]), &strentries[164]},
+ {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "path"), UPB_TABVALUE_PTR_INIT(&fields[78]), NULL},
+ {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "double_value"), UPB_TABVALUE_PTR_INIT(&fields[16]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[36]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\004", "\000", "\000", "\000", "name"), UPB_TABVALUE_PTR_INIT(&fields[51]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_STR("\022", "\000", "\000", "\000", "negative_int_value"), UPB_TABVALUE_PTR_INIT(&fields[43]), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\022", "\000", "\000", "\000", "negative_int_value"), UPB_TABVALUE_PTR_INIT(&fields[59]), NULL},
{UPB_TABKEY_STR("\017", "\000", "\000", "\000", "aggregate_value"), UPB_TABVALUE_PTR_INIT(&fields[0]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_STR("\022", "\000", "\000", "\000", "positive_int_value"), UPB_TABVALUE_PTR_INIT(&fields[60]), NULL},
- {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "identifier_value"), UPB_TABVALUE_PTR_INIT(&fields[19]), NULL},
- {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "string_value"), UPB_TABVALUE_PTR_INIT(&fields[67]), &strentries[154]},
+ {UPB_TABKEY_STR("\022", "\000", "\000", "\000", "positive_int_value"), UPB_TABVALUE_PTR_INIT(&fields[79]), NULL},
+ {UPB_TABKEY_STR("\020", "\000", "\000", "\000", "identifier_value"), UPB_TABVALUE_PTR_INIT(&fields[28]), NULL},
+ {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "string_value"), UPB_TABVALUE_PTR_INIT(&fields[90]), &strentries[182]},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "is_extension"), UPB_TABVALUE_PTR_INIT(&fields[21]), NULL},
- {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "name_part"), UPB_TABVALUE_PTR_INIT(&fields[42]), NULL},
- {UPB_TABKEY_STR("\016", "\000", "\000", "\000", "LABEL_REQUIRED"), UPB_TABVALUE_INT_INIT(2), &strentries[162]},
+ {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "is_extension"), UPB_TABVALUE_PTR_INIT(&fields[30]), NULL},
+ {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "name_part"), UPB_TABVALUE_PTR_INIT(&fields[58]), NULL},
+ {UPB_TABKEY_STR("\016", "\000", "\000", "\000", "LABEL_REQUIRED"), UPB_TABVALUE_INT_INIT(2), &strentries[190]},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
{UPB_TABKEY_STR("\016", "\000", "\000", "\000", "LABEL_REPEATED"), UPB_TABVALUE_INT_INIT(3), NULL},
{UPB_TABKEY_STR("\016", "\000", "\000", "\000", "LABEL_OPTIONAL"), UPB_TABVALUE_INT_INIT(1), NULL},
@@ -5274,17 +5833,17 @@ static const upb_tabent strentries[236] = {
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
{UPB_TABKEY_STR("\013", "\000", "\000", "\000", "TYPE_STRING"), UPB_TABVALUE_INT_INIT(9), NULL},
- {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "TYPE_FLOAT"), UPB_TABVALUE_INT_INIT(2), &strentries[193]},
+ {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "TYPE_FLOAT"), UPB_TABVALUE_INT_INIT(2), &strentries[221]},
{UPB_TABKEY_STR("\013", "\000", "\000", "\000", "TYPE_DOUBLE"), UPB_TABVALUE_INT_INIT(1), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
{UPB_TABKEY_STR("\012", "\000", "\000", "\000", "TYPE_INT32"), UPB_TABVALUE_INT_INIT(5), NULL},
{UPB_TABKEY_STR("\015", "\000", "\000", "\000", "TYPE_SFIXED32"), UPB_TABVALUE_INT_INIT(15), NULL},
{UPB_TABKEY_STR("\014", "\000", "\000", "\000", "TYPE_FIXED32"), UPB_TABVALUE_INT_INIT(7), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "TYPE_MESSAGE"), UPB_TABVALUE_INT_INIT(11), &strentries[194]},
+ {UPB_TABKEY_STR("\014", "\000", "\000", "\000", "TYPE_MESSAGE"), UPB_TABVALUE_INT_INIT(11), &strentries[222]},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "TYPE_INT64"), UPB_TABVALUE_INT_INIT(3), &strentries[191]},
+ {UPB_TABKEY_STR("\012", "\000", "\000", "\000", "TYPE_INT64"), UPB_TABVALUE_INT_INIT(3), &strentries[219]},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
@@ -5292,7 +5851,7 @@ static const upb_tabent strentries[236] = {
{UPB_TABKEY_STR("\011", "\000", "\000", "\000", "TYPE_ENUM"), UPB_TABVALUE_INT_INIT(14), NULL},
{UPB_TABKEY_STR("\013", "\000", "\000", "\000", "TYPE_UINT32"), UPB_TABVALUE_INT_INIT(13), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "TYPE_UINT64"), UPB_TABVALUE_INT_INIT(4), &strentries[190]},
+ {UPB_TABKEY_STR("\013", "\000", "\000", "\000", "TYPE_UINT64"), UPB_TABVALUE_INT_INIT(4), &strentries[218]},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
{UPB_TABKEY_STR("\015", "\000", "\000", "\000", "TYPE_SFIXED64"), UPB_TABVALUE_INT_INIT(16), NULL},
{UPB_TABKEY_STR("\012", "\000", "\000", "\000", "TYPE_BYTES"), UPB_TABVALUE_INT_INIT(12), NULL},
@@ -5302,266 +5861,191 @@ static const upb_tabent strentries[236] = {
{UPB_TABKEY_STR("\013", "\000", "\000", "\000", "TYPE_SINT32"), UPB_TABVALUE_INT_INIT(17), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
{UPB_TABKEY_STR("\004", "\000", "\000", "\000", "CORD"), UPB_TABVALUE_INT_INIT(1), NULL},
- {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "STRING"), UPB_TABVALUE_INT_INIT(0), &strentries[197]},
+ {UPB_TABKEY_STR("\006", "\000", "\000", "\000", "STRING"), UPB_TABVALUE_INT_INIT(0), &strentries[225]},
{UPB_TABKEY_STR("\014", "\000", "\000", "\000", "STRING_PIECE"), UPB_TABVALUE_INT_INIT(2), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "JS_NORMAL"), UPB_TABVALUE_INT_INIT(0), NULL},
+ {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "JS_NUMBER"), UPB_TABVALUE_INT_INIT(2), NULL},
+ {UPB_TABKEY_STR("\011", "\000", "\000", "\000", "JS_STRING"), UPB_TABVALUE_INT_INIT(1), NULL},
{UPB_TABKEY_STR("\011", "\000", "\000", "\000", "CODE_SIZE"), UPB_TABVALUE_INT_INIT(2), NULL},
- {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "SPEED"), UPB_TABVALUE_INT_INIT(1), &strentries[203]},
+ {UPB_TABKEY_STR("\005", "\000", "\000", "\000", "SPEED"), UPB_TABVALUE_INT_INIT(1), &strentries[235]},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
{UPB_TABKEY_STR("\014", "\000", "\000", "\000", "LITE_RUNTIME"), UPB_TABVALUE_INT_INIT(3), NULL},
- {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_STR("\047", "\000", "\000", "\000", "google.protobuf.SourceCodeInfo.Location"), UPB_TABVALUE_PTR_INIT(&msgs[17]), NULL},
- {UPB_TABKEY_STR("\043", "\000", "\000", "\000", "google.protobuf.UninterpretedOption"), UPB_TABVALUE_PTR_INIT(&msgs[18]), NULL},
- {UPB_TABKEY_STR("\043", "\000", "\000", "\000", "google.protobuf.FileDescriptorProto"), UPB_TABVALUE_PTR_INIT(&msgs[8]), NULL},
- {UPB_TABKEY_STR("\045", "\000", "\000", "\000", "google.protobuf.MethodDescriptorProto"), UPB_TABVALUE_PTR_INIT(&msgs[12]), NULL},
- {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_STR("\040", "\000", "\000", "\000", "google.protobuf.EnumValueOptions"), UPB_TABVALUE_PTR_INIT(&msgs[5]), NULL},
- {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_STR("\037", "\000", "\000", "\000", "google.protobuf.DescriptorProto"), UPB_TABVALUE_PTR_INIT(&msgs[0]), &strentries[228]},
- {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_STR("\036", "\000", "\000", "\000", "google.protobuf.SourceCodeInfo"), UPB_TABVALUE_PTR_INIT(&msgs[16]), NULL},
- {UPB_TABKEY_STR("\051", "\000", "\000", "\000", "google.protobuf.FieldDescriptorProto.Type"), UPB_TABVALUE_PTR_INIT(&enums[1]), NULL},
- {UPB_TABKEY_STR("\056", "\000", "\000", "\000", "google.protobuf.DescriptorProto.ExtensionRange"), UPB_TABVALUE_PTR_INIT(&msgs[1]), NULL},
- {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_STR("\050", "\000", "\000", "\000", "google.protobuf.EnumValueDescriptorProto"), UPB_TABVALUE_PTR_INIT(&msgs[4]), NULL},
- {UPB_TABKEY_STR("\034", "\000", "\000", "\000", "google.protobuf.FieldOptions"), UPB_TABVALUE_PTR_INIT(&msgs[7]), NULL},
- {UPB_TABKEY_STR("\033", "\000", "\000", "\000", "google.protobuf.FileOptions"), UPB_TABVALUE_PTR_INIT(&msgs[10]), NULL},
- {UPB_TABKEY_STR("\043", "\000", "\000", "\000", "google.protobuf.EnumDescriptorProto"), UPB_TABVALUE_PTR_INIT(&msgs[2]), &strentries[233]},
- {UPB_TABKEY_STR("\052", "\000", "\000", "\000", "google.protobuf.FieldDescriptorProto.Label"), UPB_TABVALUE_PTR_INIT(&enums[0]), NULL},
- {UPB_TABKEY_STR("\046", "\000", "\000", "\000", "google.protobuf.ServiceDescriptorProto"), UPB_TABVALUE_PTR_INIT(&msgs[14]), NULL},
- {UPB_TABKEY_STR("\042", "\000", "\000", "\000", "google.protobuf.FieldOptions.CType"), UPB_TABVALUE_PTR_INIT(&enums[2]), &strentries[229]},
- {UPB_TABKEY_STR("\041", "\000", "\000", "\000", "google.protobuf.FileDescriptorSet"), UPB_TABVALUE_PTR_INIT(&msgs[9]), &strentries[235]},
- {UPB_TABKEY_STR("\033", "\000", "\000", "\000", "google.protobuf.EnumOptions"), UPB_TABVALUE_PTR_INIT(&msgs[3]), NULL},
- {UPB_TABKEY_STR("\044", "\000", "\000", "\000", "google.protobuf.FieldDescriptorProto"), UPB_TABVALUE_PTR_INIT(&msgs[6]), NULL},
- {UPB_TABKEY_STR("\050", "\000", "\000", "\000", "google.protobuf.FileOptions.OptimizeMode"), UPB_TABVALUE_PTR_INIT(&enums[3]), &strentries[221]},
- {UPB_TABKEY_STR("\036", "\000", "\000", "\000", "google.protobuf.ServiceOptions"), UPB_TABVALUE_PTR_INIT(&msgs[15]), NULL},
- {UPB_TABKEY_STR("\036", "\000", "\000", "\000", "google.protobuf.MessageOptions"), UPB_TABVALUE_PTR_INIT(&msgs[11]), NULL},
- {UPB_TABKEY_STR("\035", "\000", "\000", "\000", "google.protobuf.MethodOptions"), UPB_TABVALUE_PTR_INIT(&msgs[13]), &strentries[226]},
- {UPB_TABKEY_STR("\054", "\000", "\000", "\000", "google.protobuf.UninterpretedOption.NamePart"), UPB_TABVALUE_PTR_INIT(&msgs[19]), NULL},
};
-static const upb_tabent intentries[14] = {
+static const upb_tabent intentries[18] = {
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[98]), NULL},
+ {UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
+ {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[97]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[73]), NULL},
+ {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[99]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[71]), NULL},
+ {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[95]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[77]), NULL},
+ {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[96]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[75]), NULL},
+ {UPB_TABKEY_NUM(33), UPB_TABVALUE_PTR_INIT(&fields[11]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[76]), NULL},
+ {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[100]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[74]), NULL},
+ {UPB_TABKEY_NUM(33), UPB_TABVALUE_PTR_INIT(&fields[14]), NULL},
{UPB_TABKEY_NONE, UPB_TABVALUE_EMPTY_INIT, NULL},
- {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[72]), NULL},
+ {UPB_TABKEY_NUM(999), UPB_TABVALUE_PTR_INIT(&fields[101]), NULL},
};
-static const upb_tabval arrays[232] = {
+static const upb_tabval arrays[184] = {
UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_PTR_INIT(&fields[38]),
- UPB_TABVALUE_PTR_INIT(&fields[16]),
- UPB_TABVALUE_PTR_INIT(&fields[44]),
- UPB_TABVALUE_PTR_INIT(&fields[9]),
- UPB_TABVALUE_PTR_INIT(&fields[15]),
- UPB_TABVALUE_PTR_INIT(&fields[14]),
- UPB_TABVALUE_PTR_INIT(&fields[49]),
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_PTR_INIT(&fields[66]),
- UPB_TABVALUE_PTR_INIT(&fields[8]),
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_PTR_INIT(&fields[40]),
- UPB_TABVALUE_PTR_INIT(&fields[78]),
- UPB_TABVALUE_PTR_INIT(&fields[50]),
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_PTR_INIT(&fields[1]),
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_PTR_INIT(&fields[37]),
- UPB_TABVALUE_PTR_INIT(&fields[47]),
UPB_TABVALUE_PTR_INIT(&fields[52]),
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_PTR_INIT(&fields[41]),
- UPB_TABVALUE_PTR_INIT(&fields[12]),
- UPB_TABVALUE_PTR_INIT(&fields[46]),
- UPB_TABVALUE_PTR_INIT(&fields[27]),
- UPB_TABVALUE_PTR_INIT(&fields[69]),
- UPB_TABVALUE_PTR_INIT(&fields[70]),
- UPB_TABVALUE_PTR_INIT(&fields[4]),
- UPB_TABVALUE_PTR_INIT(&fields[51]),
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_PTR_INIT(&fields[3]),
- UPB_TABVALUE_PTR_INIT(&fields[58]),
- UPB_TABVALUE_PTR_INIT(&fields[6]),
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_PTR_INIT(&fields[28]),
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_PTR_INIT(&fields[11]),
- UPB_TABVALUE_PTR_INIT(&fields[79]),
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_PTR_INIT(&fields[34]),
- UPB_TABVALUE_PTR_INIT(&fields[57]),
- UPB_TABVALUE_PTR_INIT(&fields[5]),
- UPB_TABVALUE_PTR_INIT(&fields[32]),
- UPB_TABVALUE_PTR_INIT(&fields[10]),
- UPB_TABVALUE_PTR_INIT(&fields[63]),
- UPB_TABVALUE_PTR_INIT(&fields[13]),
- UPB_TABVALUE_PTR_INIT(&fields[53]),
- UPB_TABVALUE_PTR_INIT(&fields[64]),
- UPB_TABVALUE_PTR_INIT(&fields[61]),
- UPB_TABVALUE_PTR_INIT(&fields[80]),
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_PTR_INIT(&fields[17]),
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_PTR_INIT(&fields[26]),
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
UPB_TABVALUE_PTR_INIT(&fields[25]),
- UPB_TABVALUE_PTR_INIT(&fields[48]),
+ UPB_TABVALUE_PTR_INIT(&fields[60]),
+ UPB_TABVALUE_PTR_INIT(&fields[19]),
UPB_TABVALUE_PTR_INIT(&fields[24]),
- UPB_TABVALUE_PTR_INIT(&fields[18]),
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_PTR_INIT(&fields[2]),
- UPB_TABVALUE_PTR_INIT(&fields[23]),
- UPB_TABVALUE_PTR_INIT(&fields[62]),
- UPB_TABVALUE_EMPTY_INIT,
UPB_TABVALUE_PTR_INIT(&fields[22]),
+ UPB_TABVALUE_PTR_INIT(&fields[68]),
+ UPB_TABVALUE_PTR_INIT(&fields[65]),
+ UPB_TABVALUE_PTR_INIT(&fields[83]),
+ UPB_TABVALUE_PTR_INIT(&fields[82]),
UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[89]),
+ UPB_TABVALUE_PTR_INIT(&fields[18]),
UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[88]),
+ UPB_TABVALUE_PTR_INIT(&fields[17]),
UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[49]),
+ UPB_TABVALUE_PTR_INIT(&fields[102]),
+ UPB_TABVALUE_PTR_INIT(&fields[74]),
UPB_TABVALUE_EMPTY_INIT,
UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[1]),
+ UPB_TABVALUE_PTR_INIT(&fields[13]),
UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[53]),
+ UPB_TABVALUE_PTR_INIT(&fields[62]),
+ UPB_TABVALUE_PTR_INIT(&fields[73]),
UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[15]),
UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[55]),
+ UPB_TABVALUE_PTR_INIT(&fields[21]),
+ UPB_TABVALUE_PTR_INIT(&fields[63]),
+ UPB_TABVALUE_PTR_INIT(&fields[40]),
+ UPB_TABVALUE_PTR_INIT(&fields[93]),
+ UPB_TABVALUE_PTR_INIT(&fields[94]),
+ UPB_TABVALUE_PTR_INIT(&fields[7]),
+ UPB_TABVALUE_PTR_INIT(&fields[71]),
+ UPB_TABVALUE_PTR_INIT(&fields[66]),
+ UPB_TABVALUE_PTR_INIT(&fields[38]),
UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[6]),
+ UPB_TABVALUE_PTR_INIT(&fields[77]),
+ UPB_TABVALUE_PTR_INIT(&fields[10]),
UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[41]),
+ UPB_TABVALUE_PTR_INIT(&fields[39]),
UPB_TABVALUE_EMPTY_INIT,
UPB_TABVALUE_EMPTY_INIT,
UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[103]),
UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[54]),
+ UPB_TABVALUE_PTR_INIT(&fields[76]),
+ UPB_TABVALUE_PTR_INIT(&fields[8]),
+ UPB_TABVALUE_PTR_INIT(&fields[47]),
+ UPB_TABVALUE_PTR_INIT(&fields[20]),
+ UPB_TABVALUE_PTR_INIT(&fields[85]),
+ UPB_TABVALUE_PTR_INIT(&fields[23]),
+ UPB_TABVALUE_PTR_INIT(&fields[69]),
+ UPB_TABVALUE_PTR_INIT(&fields[86]),
+ UPB_TABVALUE_PTR_INIT(&fields[80]),
+ UPB_TABVALUE_PTR_INIT(&fields[104]),
+ UPB_TABVALUE_PTR_INIT(&fields[91]),
UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[26]),
UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[35]),
UPB_TABVALUE_EMPTY_INIT,
UPB_TABVALUE_EMPTY_INIT,
UPB_TABVALUE_EMPTY_INIT,
UPB_TABVALUE_EMPTY_INIT,
UPB_TABVALUE_EMPTY_INIT,
UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[34]),
+ UPB_TABVALUE_PTR_INIT(&fields[67]),
+ UPB_TABVALUE_PTR_INIT(&fields[33]),
+ UPB_TABVALUE_PTR_INIT(&fields[27]),
UPB_TABVALUE_EMPTY_INIT,
UPB_TABVALUE_EMPTY_INIT,
UPB_TABVALUE_EMPTY_INIT,
UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[3]),
+ UPB_TABVALUE_PTR_INIT(&fields[32]),
+ UPB_TABVALUE_PTR_INIT(&fields[81]),
UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[31]),
UPB_TABVALUE_EMPTY_INIT,
UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[12]),
UPB_TABVALUE_EMPTY_INIT,
UPB_TABVALUE_EMPTY_INIT,
UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[36]),
UPB_TABVALUE_EMPTY_INIT,
UPB_TABVALUE_EMPTY_INIT,
UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[2]),
UPB_TABVALUE_EMPTY_INIT,
UPB_TABVALUE_EMPTY_INIT,
UPB_TABVALUE_EMPTY_INIT,
UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[64]),
+ UPB_TABVALUE_PTR_INIT(&fields[5]),
+ UPB_TABVALUE_PTR_INIT(&fields[37]),
UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[46]),
+ UPB_TABVALUE_PTR_INIT(&fields[61]),
+ UPB_TABVALUE_PTR_INIT(&fields[9]),
UPB_TABVALUE_EMPTY_INIT,
UPB_TABVALUE_EMPTY_INIT,
UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_PTR_INIT(&fields[31]),
UPB_TABVALUE_PTR_INIT(&fields[45]),
UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_PTR_INIT(&fields[39]),
- UPB_TABVALUE_PTR_INIT(&fields[20]),
UPB_TABVALUE_PTR_INIT(&fields[56]),
- UPB_TABVALUE_PTR_INIT(&fields[55]),
- UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[29]),
+ UPB_TABVALUE_PTR_INIT(&fields[75]),
+ UPB_TABVALUE_PTR_INIT(&fields[70]),
+ UPB_TABVALUE_PTR_INIT(&fields[4]),
+ UPB_TABVALUE_PTR_INIT(&fields[84]),
UPB_TABVALUE_EMPTY_INIT,
UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[50]),
UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[57]),
+ UPB_TABVALUE_PTR_INIT(&fields[48]),
+ UPB_TABVALUE_PTR_INIT(&fields[72]),
UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_PTR_INIT(&fields[35]),
- UPB_TABVALUE_PTR_INIT(&fields[33]),
- UPB_TABVALUE_PTR_INIT(&fields[54]),
UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[44]),
UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[78]),
+ UPB_TABVALUE_PTR_INIT(&fields[87]),
+ UPB_TABVALUE_PTR_INIT(&fields[42]),
+ UPB_TABVALUE_PTR_INIT(&fields[92]),
UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[43]),
UPB_TABVALUE_EMPTY_INIT,
UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_PTR_INIT(&fields[30]),
- UPB_TABVALUE_EMPTY_INIT,
+ UPB_TABVALUE_PTR_INIT(&fields[51]),
+ UPB_TABVALUE_PTR_INIT(&fields[28]),
+ UPB_TABVALUE_PTR_INIT(&fields[79]),
UPB_TABVALUE_PTR_INIT(&fields[59]),
- UPB_TABVALUE_PTR_INIT(&fields[65]),
- UPB_TABVALUE_PTR_INIT(&fields[29]),
- UPB_TABVALUE_PTR_INIT(&fields[68]),
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_PTR_INIT(&fields[36]),
- UPB_TABVALUE_PTR_INIT(&fields[19]),
- UPB_TABVALUE_PTR_INIT(&fields[60]),
- UPB_TABVALUE_PTR_INIT(&fields[43]),
- UPB_TABVALUE_PTR_INIT(&fields[7]),
- UPB_TABVALUE_PTR_INIT(&fields[67]),
+ UPB_TABVALUE_PTR_INIT(&fields[16]),
+ UPB_TABVALUE_PTR_INIT(&fields[90]),
UPB_TABVALUE_PTR_INIT(&fields[0]),
UPB_TABVALUE_EMPTY_INIT,
- UPB_TABVALUE_PTR_INIT(&fields[42]),
- UPB_TABVALUE_PTR_INIT(&fields[21]),
+ UPB_TABVALUE_PTR_INIT(&fields[58]),
+ UPB_TABVALUE_PTR_INIT(&fields[30]),
UPB_TABVALUE_EMPTY_INIT,
UPB_TABVALUE_PTR_INIT("LABEL_OPTIONAL"),
UPB_TABVALUE_PTR_INIT("LABEL_REQUIRED"),
@@ -5588,21 +6072,69 @@ static const upb_tabval arrays[232] = {
UPB_TABVALUE_PTR_INIT("STRING"),
UPB_TABVALUE_PTR_INIT("CORD"),
UPB_TABVALUE_PTR_INIT("STRING_PIECE"),
+ UPB_TABVALUE_PTR_INIT("JS_NORMAL"),
+ UPB_TABVALUE_PTR_INIT("JS_STRING"),
+ UPB_TABVALUE_PTR_INIT("JS_NUMBER"),
UPB_TABVALUE_EMPTY_INIT,
UPB_TABVALUE_PTR_INIT("SPEED"),
UPB_TABVALUE_PTR_INIT("CODE_SIZE"),
UPB_TABVALUE_PTR_INIT("LITE_RUNTIME"),
};
-static const upb_symtab symtab = UPB_SYMTAB_INIT(UPB_STRTABLE_INIT(24, 31, UPB_CTYPE_PTR, 5, &strentries[204]), &reftables[210], &reftables[211]);
-
-const upb_symtab *upbdefs_google_protobuf_descriptor(const void *owner) {
- upb_symtab_ref(&symtab, owner);
- return &symtab;
-}
-
#ifdef UPB_DEBUG_REFS
-static upb_inttable reftables[212] = {
+static upb_inttable reftables[264] = {
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
+ UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
UPB_EMPTY_INTTABLE_INIT(UPB_CTYPE_PTR),
@@ -5818,6 +6350,45 @@ static upb_inttable reftables[212] = {
};
#endif
+static const upb_msgdef *refm(const upb_msgdef *m, const void *owner) {
+ upb_msgdef_ref(m, owner);
+ return m;
+}
+
+static const upb_enumdef *refe(const upb_enumdef *e, const void *owner) {
+ upb_enumdef_ref(e, owner);
+ return e;
+}
+
+/* Public API. */
+const upb_msgdef *upbdefs_google_protobuf_DescriptorProto_get(const void *owner) { return refm(&msgs[0], owner); }
+const upb_msgdef *upbdefs_google_protobuf_DescriptorProto_ExtensionRange_get(const void *owner) { return refm(&msgs[1], owner); }
+const upb_msgdef *upbdefs_google_protobuf_DescriptorProto_ReservedRange_get(const void *owner) { return refm(&msgs[2], owner); }
+const upb_msgdef *upbdefs_google_protobuf_EnumDescriptorProto_get(const void *owner) { return refm(&msgs[3], owner); }
+const upb_msgdef *upbdefs_google_protobuf_EnumOptions_get(const void *owner) { return refm(&msgs[4], owner); }
+const upb_msgdef *upbdefs_google_protobuf_EnumValueDescriptorProto_get(const void *owner) { return refm(&msgs[5], owner); }
+const upb_msgdef *upbdefs_google_protobuf_EnumValueOptions_get(const void *owner) { return refm(&msgs[6], owner); }
+const upb_msgdef *upbdefs_google_protobuf_FieldDescriptorProto_get(const void *owner) { return refm(&msgs[7], owner); }
+const upb_msgdef *upbdefs_google_protobuf_FieldOptions_get(const void *owner) { return refm(&msgs[8], owner); }
+const upb_msgdef *upbdefs_google_protobuf_FileDescriptorProto_get(const void *owner) { return refm(&msgs[9], owner); }
+const upb_msgdef *upbdefs_google_protobuf_FileDescriptorSet_get(const void *owner) { return refm(&msgs[10], owner); }
+const upb_msgdef *upbdefs_google_protobuf_FileOptions_get(const void *owner) { return refm(&msgs[11], owner); }
+const upb_msgdef *upbdefs_google_protobuf_MessageOptions_get(const void *owner) { return refm(&msgs[12], owner); }
+const upb_msgdef *upbdefs_google_protobuf_MethodDescriptorProto_get(const void *owner) { return refm(&msgs[13], owner); }
+const upb_msgdef *upbdefs_google_protobuf_MethodOptions_get(const void *owner) { return refm(&msgs[14], owner); }
+const upb_msgdef *upbdefs_google_protobuf_OneofDescriptorProto_get(const void *owner) { return refm(&msgs[15], owner); }
+const upb_msgdef *upbdefs_google_protobuf_ServiceDescriptorProto_get(const void *owner) { return refm(&msgs[16], owner); }
+const upb_msgdef *upbdefs_google_protobuf_ServiceOptions_get(const void *owner) { return refm(&msgs[17], owner); }
+const upb_msgdef *upbdefs_google_protobuf_SourceCodeInfo_get(const void *owner) { return refm(&msgs[18], owner); }
+const upb_msgdef *upbdefs_google_protobuf_SourceCodeInfo_Location_get(const void *owner) { return refm(&msgs[19], owner); }
+const upb_msgdef *upbdefs_google_protobuf_UninterpretedOption_get(const void *owner) { return refm(&msgs[20], owner); }
+const upb_msgdef *upbdefs_google_protobuf_UninterpretedOption_NamePart_get(const void *owner) { return refm(&msgs[21], owner); }
+
+const upb_enumdef *upbdefs_google_protobuf_FieldDescriptorProto_Label_get(const void *owner) { return refe(&enums[0], owner); }
+const upb_enumdef *upbdefs_google_protobuf_FieldDescriptorProto_Type_get(const void *owner) { return refe(&enums[1], owner); }
+const upb_enumdef *upbdefs_google_protobuf_FieldOptions_CType_get(const void *owner) { return refe(&enums[2], owner); }
+const upb_enumdef *upbdefs_google_protobuf_FieldOptions_JSType_get(const void *owner) { return refe(&enums[3], owner); }
+const upb_enumdef *upbdefs_google_protobuf_FileOptions_OptimizeMode_get(const void *owner) { return refe(&enums[4], owner); }
/*
** XXX: The routines in this file that consume a string do not currently
** support having the string span buffers. In the future, as upb_sink and
@@ -5831,14 +6402,10 @@ static upb_inttable reftables[212] = {
#include <stdlib.h>
#include <string.h>
-/* upb_deflist is an internal-only dynamic array for storing a growing list of
- * upb_defs. */
-typedef struct {
- upb_def **defs;
- size_t len;
- size_t size;
- bool owned;
-} upb_deflist;
+/* Compares a NULL-terminated string with a non-NULL-terminated string. */
+static bool upb_streq(const char *str, const char *buf, size_t n) {
+ return strlen(str) == n && memcmp(str, buf, n) == 0;
+}
/* We keep a stack of all the messages scopes we are currently in, as well as
* the top-level file scope. This is necessary to correctly qualify the
@@ -5865,7 +6432,8 @@ typedef struct {
struct upb_descreader {
upb_sink sink;
- upb_deflist defs;
+ upb_inttable files;
+ upb_filedef *file; /* The last file in files. */
upb_descreader_frame stack[UPB_MAX_MESSAGE_NESTING];
int stack_len;
@@ -5880,7 +6448,7 @@ struct upb_descreader {
};
static char *upb_strndup(const char *buf, size_t n) {
- char *ret = malloc(n + 1);
+ char *ret = upb_gmalloc(n + 1);
if (!ret) return NULL;
memcpy(ret, buf, n);
ret[n] = '\0';
@@ -5894,9 +6462,12 @@ static char *upb_strndup(const char *buf, size_t n) {
* Caller owns a ref on the returned string. */
static char *upb_join(const char *base, const char *name) {
if (!base || strlen(base) == 0) {
- return upb_strdup(name);
+ return upb_gstrdup(name);
} else {
- char *ret = malloc(strlen(base) + strlen(name) + 2);
+ char *ret = upb_gmalloc(strlen(base) + strlen(name) + 2);
+ if (!ret) {
+ return NULL;
+ }
ret[0] = '\0';
strcat(ret, base);
strcat(ret, ".");
@@ -5905,57 +6476,21 @@ static char *upb_join(const char *base, const char *name) {
}
}
-
-/* upb_deflist ****************************************************************/
-
-void upb_deflist_init(upb_deflist *l) {
- l->size = 0;
- l->defs = NULL;
- l->len = 0;
- l->owned = true;
-}
-
-void upb_deflist_uninit(upb_deflist *l) {
- size_t i;
- if (l->owned)
- for(i = 0; i < l->len; i++)
- upb_def_unref(l->defs[i], l);
- free(l->defs);
-}
-
-bool upb_deflist_push(upb_deflist *l, upb_def *d) {
- if(++l->len >= l->size) {
- size_t new_size = UPB_MAX(l->size, 4);
- new_size *= 2;
- l->defs = realloc(l->defs, new_size * sizeof(void *));
- if (!l->defs) return false;
- l->size = new_size;
- }
- l->defs[l->len - 1] = d;
- return true;
-}
-
-void upb_deflist_donaterefs(upb_deflist *l, void *owner) {
- size_t i;
- assert(l->owned);
- for (i = 0; i < l->len; i++)
- upb_def_donateref(l->defs[i], l, owner);
- l->owned = false;
-}
-
-static upb_def *upb_deflist_last(upb_deflist *l) {
- return l->defs[l->len-1];
-}
-
/* Qualify the defname for all defs starting with offset "start" with "str". */
-static void upb_deflist_qualify(upb_deflist *l, char *str, int32_t start) {
- uint32_t i;
- for (i = start; i < l->len; i++) {
- upb_def *def = l->defs[i];
+static bool upb_descreader_qualify(upb_filedef *f, char *str, int32_t start) {
+ size_t i;
+ for (i = start; i < upb_filedef_defcount(f); i++) {
+ upb_def *def = upb_filedef_mutabledef(f, i);
char *name = upb_join(str, upb_def_fullname(def));
+ if (!name) {
+ /* Need better logic here; at this point we've qualified some names but
+ * not others. */
+ return false;
+ }
upb_def_setfullname(def, name, NULL);
- free(name);
+ upb_gfree(name);
}
+ return true;
}
@@ -5966,60 +6501,144 @@ static upb_msgdef *upb_descreader_top(upb_descreader *r) {
assert(r->stack_len > 1);
index = r->stack[r->stack_len-1].start - 1;
assert(index >= 0);
- return upb_downcast_msgdef_mutable(r->defs.defs[index]);
+ return upb_downcast_msgdef_mutable(upb_filedef_mutabledef(r->file, index));
}
static upb_def *upb_descreader_last(upb_descreader *r) {
- return upb_deflist_last(&r->defs);
+ return upb_filedef_mutabledef(r->file, upb_filedef_defcount(r->file) - 1);
}
/* Start/end handlers for FileDescriptorProto and DescriptorProto (the two
* entities that have names and can contain sub-definitions. */
void upb_descreader_startcontainer(upb_descreader *r) {
upb_descreader_frame *f = &r->stack[r->stack_len++];
- f->start = r->defs.len;
+ f->start = upb_filedef_defcount(r->file);
f->name = NULL;
}
-void upb_descreader_endcontainer(upb_descreader *r) {
+bool upb_descreader_endcontainer(upb_descreader *r) {
upb_descreader_frame *f = &r->stack[--r->stack_len];
- upb_deflist_qualify(&r->defs, f->name, f->start);
- free(f->name);
+ if (!upb_descreader_qualify(r->file, f->name, f->start)) {
+ return false;
+ }
+ upb_gfree(f->name);
f->name = NULL;
+ return true;
}
void upb_descreader_setscopename(upb_descreader *r, char *str) {
upb_descreader_frame *f = &r->stack[r->stack_len-1];
- free(f->name);
+ upb_gfree(f->name);
f->name = str;
}
-/* Handlers for google.protobuf.FileDescriptorProto. */
-static bool file_startmsg(void *r, const void *hd) {
+/** Handlers for google.protobuf.FileDescriptorSet. ***************************/
+
+static void *fileset_startfile(void *closure, const void *hd) {
+ upb_descreader *r = closure;
+ UPB_UNUSED(hd);
+ r->file = upb_filedef_new(&r->files);
+ upb_inttable_push(&r->files, upb_value_ptr(r->file));
+ return r;
+}
+
+/** Handlers for google.protobuf.FileDescriptorProto. *************************/
+
+static bool file_start(void *closure, const void *hd) {
+ upb_descreader *r = closure;
UPB_UNUSED(hd);
upb_descreader_startcontainer(r);
return true;
}
-static bool file_endmsg(void *closure, const void *hd, upb_status *status) {
+static bool file_end(void *closure, const void *hd, upb_status *status) {
upb_descreader *r = closure;
UPB_UNUSED(hd);
UPB_UNUSED(status);
- upb_descreader_endcontainer(r);
- return true;
+ return upb_descreader_endcontainer(r);
+}
+
+static size_t file_onname(void *closure, const void *hd, const char *buf,
+ size_t n, const upb_bufhandle *handle) {
+ upb_descreader *r = closure;
+ char *name;
+ bool ok;
+ UPB_UNUSED(hd);
+ UPB_UNUSED(handle);
+
+ name = upb_strndup(buf, n);
+ /* XXX: see comment at the top of the file. */
+ ok = upb_filedef_setname(r->file, name, NULL);
+ upb_gfree(name);
+ UPB_ASSERT_VAR(ok, ok);
+ return n;
}
static size_t file_onpackage(void *closure, const void *hd, const char *buf,
size_t n, const upb_bufhandle *handle) {
upb_descreader *r = closure;
+ char *package;
+ bool ok;
UPB_UNUSED(hd);
UPB_UNUSED(handle);
+
+ package = upb_strndup(buf, n);
/* XXX: see comment at the top of the file. */
- upb_descreader_setscopename(r, upb_strndup(buf, n));
+ upb_descreader_setscopename(r, package);
+ ok = upb_filedef_setpackage(r->file, package, NULL);
+ UPB_ASSERT_VAR(ok, ok);
return n;
}
-/* Handlers for google.protobuf.EnumValueDescriptorProto. */
+static size_t file_onsyntax(void *closure, const void *hd, const char *buf,
+ size_t n, const upb_bufhandle *handle) {
+ upb_descreader *r = closure;
+ bool ok;
+ UPB_UNUSED(hd);
+ UPB_UNUSED(handle);
+ /* XXX: see comment at the top of the file. */
+ if (upb_streq("proto2", buf, n)) {
+ ok = upb_filedef_setsyntax(r->file, UPB_SYNTAX_PROTO2, NULL);
+ } else if (upb_streq("proto3", buf, n)) {
+ ok = upb_filedef_setsyntax(r->file, UPB_SYNTAX_PROTO3, NULL);
+ } else {
+ ok = false;
+ }
+
+ UPB_ASSERT_VAR(ok, ok);
+ return n;
+}
+
+static void *file_startmsg(void *closure, const void *hd) {
+ upb_descreader *r = closure;
+ upb_msgdef *m = upb_msgdef_new(&m);
+ bool ok = upb_filedef_addmsg(r->file, m, &m, NULL);
+ UPB_UNUSED(hd);
+ UPB_ASSERT_VAR(ok, ok);
+ return r;
+}
+
+static void *file_startenum(void *closure, const void *hd) {
+ upb_descreader *r = closure;
+ upb_enumdef *e = upb_enumdef_new(&e);
+ bool ok = upb_filedef_addenum(r->file, e, &e, NULL);
+ UPB_UNUSED(hd);
+ UPB_ASSERT_VAR(ok, ok);
+ return r;
+}
+
+static void *file_startext(void *closure, const void *hd) {
+ upb_descreader *r = closure;
+ bool ok;
+ r->f = upb_fielddef_new(r);
+ ok = upb_filedef_addext(r->file, r->f, r, NULL);
+ UPB_UNUSED(hd);
+ UPB_ASSERT_VAR(ok, ok);
+ return r;
+}
+
+/** Handlers for google.protobuf.EnumValueDescriptorProto. *********************/
+
static bool enumval_startmsg(void *closure, const void *hd) {
upb_descreader *r = closure;
UPB_UNUSED(hd);
@@ -6034,7 +6653,7 @@ static size_t enumval_onname(void *closure, const void *hd, const char *buf,
UPB_UNUSED(hd);
UPB_UNUSED(handle);
/* XXX: see comment at the top of the file. */
- free(r->name);
+ upb_gfree(r->name);
r->name = upb_strndup(buf, n);
r->saw_name = true;
return n;
@@ -6059,20 +6678,12 @@ static bool enumval_endmsg(void *closure, const void *hd, upb_status *status) {
}
e = upb_downcast_enumdef_mutable(upb_descreader_last(r));
upb_enumdef_addval(e, r->name, r->number, status);
- free(r->name);
+ upb_gfree(r->name);
r->name = NULL;
return true;
}
-
-/* Handlers for google.protobuf.EnumDescriptorProto. */
-static bool enum_startmsg(void *closure, const void *hd) {
- upb_descreader *r = closure;
- UPB_UNUSED(hd);
- upb_deflist_push(&r->defs,
- upb_enumdef_upcast_mutable(upb_enumdef_new(&r->defs)));
- return true;
-}
+/** Handlers for google.protobuf.EnumDescriptorProto. *************************/
static bool enum_endmsg(void *closure, const void *hd, upb_status *status) {
upb_descreader *r = closure;
@@ -6099,16 +6710,17 @@ static size_t enum_onname(void *closure, const void *hd, const char *buf,
UPB_UNUSED(handle);
/* XXX: see comment at the top of the file. */
upb_def_setfullname(upb_descreader_last(r), fullname, NULL);
- free(fullname);
+ upb_gfree(fullname);
return n;
}
-/* Handlers for google.protobuf.FieldDescriptorProto */
+/** Handlers for google.protobuf.FieldDescriptorProto *************************/
+
static bool field_startmsg(void *closure, const void *hd) {
upb_descreader *r = closure;
UPB_UNUSED(hd);
- r->f = upb_fielddef_new(&r->defs);
- free(r->default_string);
+ assert(r->f);
+ upb_gfree(r->default_string);
r->default_string = NULL;
/* fielddefs default to packed, but descriptors default to non-packed. */
@@ -6250,9 +6862,10 @@ static bool field_onlabel(void *closure, const void *hd, int32_t val) {
static bool field_onnumber(void *closure, const void *hd, int32_t val) {
upb_descreader *r = closure;
- bool ok = upb_fielddef_setnumber(r->f, val, NULL);
+ bool ok;
UPB_UNUSED(hd);
+ ok = upb_fielddef_setnumber(r->f, val, NULL);
UPB_ASSERT_VAR(ok, ok);
return true;
}
@@ -6266,7 +6879,7 @@ static size_t field_onname(void *closure, const void *hd, const char *buf,
/* XXX: see comment at the top of the file. */
upb_fielddef_setname(r->f, name, NULL);
- free(name);
+ upb_gfree(name);
return n;
}
@@ -6279,7 +6892,7 @@ static size_t field_ontypename(void *closure, const void *hd, const char *buf,
/* XXX: see comment at the top of the file. */
upb_fielddef_setsubdefname(r->f, name, NULL);
- free(name);
+ upb_gfree(name);
return n;
}
@@ -6292,7 +6905,7 @@ static size_t field_onextendee(void *closure, const void *hd, const char *buf,
/* XXX: see comment at the top of the file. */
upb_fielddef_setcontainingtypename(r->f, name, NULL);
- free(name);
+ upb_gfree(name);
return n;
}
@@ -6305,23 +6918,22 @@ static size_t field_ondefaultval(void *closure, const void *hd, const char *buf,
/* Have to convert from string to the correct type, but we might not know the
* type yet, so we save it as a string until the end of the field.
* XXX: see comment at the top of the file. */
- free(r->default_string);
+ upb_gfree(r->default_string);
r->default_string = upb_strndup(buf, n);
return n;
}
-/* Handlers for google.protobuf.DescriptorProto (representing a message). */
-static bool msg_startmsg(void *closure, const void *hd) {
+/** Handlers for google.protobuf.DescriptorProto ******************************/
+
+static bool msg_start(void *closure, const void *hd) {
upb_descreader *r = closure;
UPB_UNUSED(hd);
- upb_deflist_push(&r->defs,
- upb_msgdef_upcast_mutable(upb_msgdef_new(&r->defs)));
upb_descreader_startcontainer(r);
return true;
}
-static bool msg_endmsg(void *closure, const void *hd, upb_status *status) {
+static bool msg_end(void *closure, const void *hd, upb_status *status) {
upb_descreader *r = closure;
upb_msgdef *m = upb_descreader_top(r);
UPB_UNUSED(hd);
@@ -6330,12 +6942,11 @@ static bool msg_endmsg(void *closure, const void *hd, upb_status *status) {
upb_status_seterrmsg(status, "Encountered message with no name.");
return false;
}
- upb_descreader_endcontainer(r);
- return true;
+ return upb_descreader_endcontainer(r);
}
-static size_t msg_onname(void *closure, const void *hd, const char *buf,
- size_t n, const upb_bufhandle *handle) {
+static size_t msg_name(void *closure, const void *hd, const char *buf,
+ size_t n, const upb_bufhandle *handle) {
upb_descreader *r = closure;
upb_msgdef *m = upb_descreader_top(r);
/* XXX: see comment at the top of the file. */
@@ -6348,91 +6959,147 @@ static size_t msg_onname(void *closure, const void *hd, const char *buf,
return n;
}
-static bool msg_onendfield(void *closure, const void *hd) {
+static void *msg_startmsg(void *closure, const void *hd) {
+ upb_descreader *r = closure;
+ upb_msgdef *m = upb_msgdef_new(&m);
+ bool ok = upb_filedef_addmsg(r->file, m, &m, NULL);
+ UPB_UNUSED(hd);
+ UPB_ASSERT_VAR(ok, ok);
+ return r;
+}
+
+static void *msg_startext(void *closure, const void *hd) {
+ upb_descreader *r = closure;
+ upb_fielddef *f = upb_fielddef_new(&f);
+ bool ok = upb_filedef_addext(r->file, f, &f, NULL);
+ UPB_UNUSED(hd);
+ UPB_ASSERT_VAR(ok, ok);
+ return r;
+}
+
+static void *msg_startfield(void *closure, const void *hd) {
+ upb_descreader *r = closure;
+ r->f = upb_fielddef_new(&r->f);
+ /* We can't add the new field to the message until its name/number are
+ * filled in. */
+ UPB_UNUSED(hd);
+ return r;
+}
+
+static bool msg_endfield(void *closure, const void *hd) {
upb_descreader *r = closure;
upb_msgdef *m = upb_descreader_top(r);
UPB_UNUSED(hd);
- upb_msgdef_addfield(m, r->f, &r->defs, NULL);
+ upb_msgdef_addfield(m, r->f, &r->f, NULL);
r->f = NULL;
return true;
}
-static bool pushextension(void *closure, const void *hd) {
+static bool msg_onmapentry(void *closure, const void *hd, bool mapentry) {
upb_descreader *r = closure;
+ upb_msgdef *m = upb_descreader_top(r);
UPB_UNUSED(hd);
- assert(upb_fielddef_containingtypename(r->f));
- upb_fielddef_setisextension(r->f, true);
- upb_deflist_push(&r->defs, upb_fielddef_upcast_mutable(r->f));
+ upb_msgdef_setmapentry(m, mapentry);
r->f = NULL;
return true;
}
-#define D(name) upbdefs_google_protobuf_ ## name(s)
+
+
+/** Code to register handlers *************************************************/
+
+#define F(msg, field) upbdefs_google_protobuf_ ## msg ## _f_ ## field(m)
static void reghandlers(const void *closure, upb_handlers *h) {
- const upb_symtab *s = closure;
const upb_msgdef *m = upb_handlers_msgdef(h);
+ UPB_UNUSED(closure);
- if (m == D(DescriptorProto)) {
- upb_handlers_setstartmsg(h, &msg_startmsg, NULL);
- upb_handlers_setendmsg(h, &msg_endmsg, NULL);
- upb_handlers_setstring(h, D(DescriptorProto_name), &msg_onname, NULL);
- upb_handlers_setendsubmsg(h, D(DescriptorProto_field), &msg_onendfield,
- NULL);
- upb_handlers_setendsubmsg(h, D(DescriptorProto_extension), &pushextension,
- NULL);
- } else if (m == D(FileDescriptorProto)) {
- upb_handlers_setstartmsg(h, &file_startmsg, NULL);
- upb_handlers_setendmsg(h, &file_endmsg, NULL);
- upb_handlers_setstring(h, D(FileDescriptorProto_package), &file_onpackage,
+ if (upbdefs_google_protobuf_FileDescriptorSet_is(m)) {
+ upb_handlers_setstartsubmsg(h, F(FileDescriptorSet, file),
+ &fileset_startfile, NULL);
+ } else if (upbdefs_google_protobuf_DescriptorProto_is(m)) {
+ upb_handlers_setstartmsg(h, &msg_start, NULL);
+ upb_handlers_setendmsg(h, &msg_end, NULL);
+ upb_handlers_setstring(h, F(DescriptorProto, name), &msg_name, NULL);
+ upb_handlers_setstartsubmsg(h, F(DescriptorProto, extension), &msg_startext,
+ NULL);
+ upb_handlers_setstartsubmsg(h, F(DescriptorProto, nested_type),
+ &msg_startmsg, NULL);
+ upb_handlers_setstartsubmsg(h, F(DescriptorProto, field),
+ &msg_startfield, NULL);
+ upb_handlers_setendsubmsg(h, F(DescriptorProto, field),
+ &msg_endfield, NULL);
+ upb_handlers_setstartsubmsg(h, F(DescriptorProto, enum_type),
+ &file_startenum, NULL);
+ } else if (upbdefs_google_protobuf_FileDescriptorProto_is(m)) {
+ upb_handlers_setstartmsg(h, &file_start, NULL);
+ upb_handlers_setendmsg(h, &file_end, NULL);
+ upb_handlers_setstring(h, F(FileDescriptorProto, name), &file_onname,
+ NULL);
+ upb_handlers_setstring(h, F(FileDescriptorProto, package), &file_onpackage,
+ NULL);
+ upb_handlers_setstring(h, F(FileDescriptorProto, syntax), &file_onsyntax,
NULL);
- upb_handlers_setendsubmsg(h, D(FileDescriptorProto_extension), &pushextension,
- NULL);
- } else if (m == D(EnumValueDescriptorProto)) {
+ upb_handlers_setstartsubmsg(h, F(FileDescriptorProto, message_type),
+ &file_startmsg, NULL);
+ upb_handlers_setstartsubmsg(h, F(FileDescriptorProto, enum_type),
+ &file_startenum, NULL);
+ upb_handlers_setstartsubmsg(h, F(FileDescriptorProto, extension),
+ &file_startext, NULL);
+ } else if (upbdefs_google_protobuf_EnumValueDescriptorProto_is(m)) {
upb_handlers_setstartmsg(h, &enumval_startmsg, NULL);
upb_handlers_setendmsg(h, &enumval_endmsg, NULL);
- upb_handlers_setstring(h, D(EnumValueDescriptorProto_name), &enumval_onname, NULL);
- upb_handlers_setint32(h, D(EnumValueDescriptorProto_number), &enumval_onnumber,
+ upb_handlers_setstring(h, F(EnumValueDescriptorProto, name), &enumval_onname, NULL);
+ upb_handlers_setint32(h, F(EnumValueDescriptorProto, number), &enumval_onnumber,
NULL);
- } else if (m == D(EnumDescriptorProto)) {
- upb_handlers_setstartmsg(h, &enum_startmsg, NULL);
+ } else if (upbdefs_google_protobuf_EnumDescriptorProto_is(m)) {
upb_handlers_setendmsg(h, &enum_endmsg, NULL);
- upb_handlers_setstring(h, D(EnumDescriptorProto_name), &enum_onname, NULL);
- } else if (m == D(FieldDescriptorProto)) {
+ upb_handlers_setstring(h, F(EnumDescriptorProto, name), &enum_onname, NULL);
+ } else if (upbdefs_google_protobuf_FieldDescriptorProto_is(m)) {
upb_handlers_setstartmsg(h, &field_startmsg, NULL);
upb_handlers_setendmsg(h, &field_endmsg, NULL);
- upb_handlers_setint32(h, D(FieldDescriptorProto_type), &field_ontype,
+ upb_handlers_setint32(h, F(FieldDescriptorProto, type), &field_ontype,
NULL);
- upb_handlers_setint32(h, D(FieldDescriptorProto_label), &field_onlabel,
+ upb_handlers_setint32(h, F(FieldDescriptorProto, label), &field_onlabel,
NULL);
- upb_handlers_setint32(h, D(FieldDescriptorProto_number), &field_onnumber,
+ upb_handlers_setint32(h, F(FieldDescriptorProto, number), &field_onnumber,
NULL);
- upb_handlers_setstring(h, D(FieldDescriptorProto_name), &field_onname,
+ upb_handlers_setstring(h, F(FieldDescriptorProto, name), &field_onname,
NULL);
- upb_handlers_setstring(h, D(FieldDescriptorProto_type_name),
+ upb_handlers_setstring(h, F(FieldDescriptorProto, type_name),
&field_ontypename, NULL);
- upb_handlers_setstring(h, D(FieldDescriptorProto_extendee),
+ upb_handlers_setstring(h, F(FieldDescriptorProto, extendee),
&field_onextendee, NULL);
- upb_handlers_setstring(h, D(FieldDescriptorProto_default_value),
+ upb_handlers_setstring(h, F(FieldDescriptorProto, default_value),
&field_ondefaultval, NULL);
- } else if (m == D(FieldOptions)) {
- upb_handlers_setbool(h, D(FieldOptions_lazy), &field_onlazy, NULL);
- upb_handlers_setbool(h, D(FieldOptions_packed), &field_onpacked, NULL);
+ } else if (upbdefs_google_protobuf_FieldOptions_is(m)) {
+ upb_handlers_setbool(h, F(FieldOptions, lazy), &field_onlazy, NULL);
+ upb_handlers_setbool(h, F(FieldOptions, packed), &field_onpacked, NULL);
+ } else if (upbdefs_google_protobuf_MessageOptions_is(m)) {
+ upb_handlers_setbool(h, F(MessageOptions, map_entry), &msg_onmapentry, NULL);
}
+
+ assert(upb_ok(upb_handlers_status(h)));
}
-#undef D
+#undef F
void descreader_cleanup(void *_r) {
upb_descreader *r = _r;
- free(r->name);
- upb_deflist_uninit(&r->defs);
- free(r->default_string);
+ size_t i;
+
+ for (i = 0; i < upb_descreader_filecount(r); i++) {
+ upb_filedef_unref(upb_descreader_file(r, i), &r->files);
+ }
+
+ upb_gfree(r->name);
+ upb_inttable_uninit(&r->files);
+ upb_gfree(r->default_string);
while (r->stack_len > 0) {
upb_descreader_frame *f = &r->stack[--r->stack_len];
- free(f->name);
+ upb_gfree(f->name);
}
}
@@ -6445,7 +7112,7 @@ upb_descreader *upb_descreader_create(upb_env *e, const upb_handlers *h) {
return NULL;
}
- upb_deflist_init(&r->defs);
+ upb_inttable_init(&r->files, UPB_CTYPE_PTR);
upb_sink_reset(upb_descreader_input(r), h, r);
r->stack_len = 0;
r->name = NULL;
@@ -6454,10 +7121,17 @@ upb_descreader *upb_descreader_create(upb_env *e, const upb_handlers *h) {
return r;
}
-upb_def **upb_descreader_getdefs(upb_descreader *r, void *owner, int *n) {
- *n = r->defs.len;
- upb_deflist_donaterefs(&r->defs, owner);
- return r->defs.defs;
+size_t upb_descreader_filecount(const upb_descreader *r) {
+ return upb_inttable_count(&r->files);
+}
+
+upb_filedef *upb_descreader_file(const upb_descreader *r, size_t i) {
+ upb_value v;
+ if (upb_inttable_lookup(&r->files, i, &v)) {
+ return upb_value_getptr(v);
+ } else {
+ return NULL;
+ }
}
upb_sink *upb_descreader_input(upb_descreader *r) {
@@ -6465,10 +7139,9 @@ upb_sink *upb_descreader_input(upb_descreader *r) {
}
const upb_handlers *upb_descreader_newhandlers(const void *owner) {
- const upb_symtab *s = upbdefs_google_protobuf_descriptor(&s);
- const upb_handlers *h = upb_handlers_newfrozen(
- upbdefs_google_protobuf_FileDescriptorSet(s), owner, reghandlers, s);
- upb_symtab_unref(s, &s);
+ const upb_msgdef *m = upbdefs_google_protobuf_FileDescriptorSet_get(&m);
+ const upb_handlers *h = upb_handlers_newfrozen(m, owner, reghandlers, NULL);
+ upb_msgdef_unref(m, &m);
return h;
}
/*
@@ -6502,8 +7175,8 @@ static void freegroup(upb_refcounted *r) {
#ifdef UPB_USE_JIT_X64
upb_pbdecoder_freejit(g);
#endif
- free(g->bytecode);
- free(g);
+ upb_gfree(g->bytecode);
+ upb_gfree(g);
}
static void visitgroup(const upb_refcounted *r, upb_refcounted_visit *visit,
@@ -6518,7 +7191,7 @@ static void visitgroup(const upb_refcounted *r, upb_refcounted_visit *visit,
}
mgroup *newgroup(const void *owner) {
- mgroup *g = malloc(sizeof(*g));
+ mgroup *g = upb_gmalloc(sizeof(*g));
static const struct upb_refcounted_vtbl vtbl = {visitgroup, freegroup};
upb_refcounted_init(mgroup_upcast_mutable(g), &vtbl, owner);
upb_inttable_init(&g->methods, UPB_CTYPE_PTR);
@@ -6538,7 +7211,7 @@ static void freemethod(upb_refcounted *r) {
}
upb_inttable_uninit(&method->dispatch);
- free(method);
+ upb_gfree(method);
}
static void visitmethod(const upb_refcounted *r, upb_refcounted_visit *visit,
@@ -6550,7 +7223,7 @@ static void visitmethod(const upb_refcounted *r, upb_refcounted_visit *visit,
static upb_pbdecodermethod *newmethod(const upb_handlers *dest_handlers,
mgroup *group) {
static const struct upb_refcounted_vtbl vtbl = {visitmethod, freemethod};
- upb_pbdecodermethod *ret = malloc(sizeof(*ret));
+ upb_pbdecodermethod *ret = upb_gmalloc(sizeof(*ret));
upb_refcounted_init(upb_pbdecodermethod_upcast_mutable(ret), &vtbl, &ret);
upb_byteshandler_init(&ret->input_handler_);
@@ -6613,7 +7286,7 @@ typedef struct {
} compiler;
static compiler *newcompiler(mgroup *group, bool lazy) {
- compiler *ret = malloc(sizeof(*ret));
+ compiler *ret = upb_gmalloc(sizeof(*ret));
int i;
ret->group = group;
@@ -6626,7 +7299,7 @@ static compiler *newcompiler(mgroup *group, bool lazy) {
}
static void freecompiler(compiler *c) {
- free(c);
+ upb_gfree(c);
}
const size_t ptr_words = sizeof(void*) / sizeof(uint32_t);
@@ -6730,7 +7403,8 @@ static void put32(compiler *c, uint32_t v) {
size_t oldsize = g->bytecode_end - g->bytecode;
size_t newsize = UPB_MAX(oldsize * 2, 64);
/* TODO(haberman): handle OOM. */
- g->bytecode = realloc(g->bytecode, newsize * sizeof(uint32_t));
+ g->bytecode = upb_grealloc(g->bytecode, oldsize * sizeof(uint32_t),
+ newsize * sizeof(uint32_t));
g->bytecode_end = g->bytecode + newsize;
c->pc = g->bytecode + ofs;
}
@@ -7067,7 +7741,12 @@ static void generate_msgfield(compiler *c, const upb_fielddef *f,
if (!sub_m) {
/* Don't emit any code for this field at all; it will be parsed as an
- * unknown field. */
+ * unknown field.
+ *
+ * TODO(haberman): we should change this to parse it as a string field
+ * instead. It will probably be faster, but more importantly, once we
+ * start vending unknown fields, a field shouldn't be treated as unknown
+ * just because it doesn't have subhandlers registered. */
return;
}
@@ -7384,11 +8063,16 @@ const mgroup *mgroup_new(const upb_handlers *dest, bool allowjit, bool lazy,
#ifdef UPB_DUMP_BYTECODE
{
- FILE *f = fopen("/tmp/upb-bytecode", "wb");
+ FILE *f = fopen("/tmp/upb-bytecode", "w");
assert(f);
dumpbc(g->bytecode, g->bytecode_end, stderr);
dumpbc(g->bytecode, g->bytecode_end, f);
fclose(f);
+
+ f = fopen("/tmp/upb-bytecode.bin", "wb");
+ assert(f);
+ fwrite(g->bytecode, 1, g->bytecode_end - g->bytecode, f);
+ fclose(f);
}
#endif
@@ -7488,6 +8172,11 @@ static const char *kUnterminatedVarint = "Unterminated varint.";
static opcode halt = OP_HALT;
+/* A dummy character we can point to when the user passes us a NULL buffer.
+ * We need this because in C (NULL + 0) and (NULL - NULL) are undefined
+ * behavior, which would invalidate functions like curbufleft(). */
+static const char dummy_char;
+
/* Whether an op consumes any of the input buffer. */
static bool consumes_input(opcode op) {
switch (op) {
@@ -7643,7 +8332,7 @@ static int32_t skip(upb_pbdecoder *d, size_t bytes) {
if (bytes > delim_remaining(d)) {
seterr(d, "Skipped value extended beyond enclosing submessage.");
return upb_pbdecoder_suspend(d);
- } else if (bufleft(d) > bytes) {
+ } else if (bufleft(d) >= bytes) {
/* Skipped data is all in current buffer, and more is still available. */
advance(d, bytes);
d->skip = 0;
@@ -7665,10 +8354,39 @@ int32_t upb_pbdecoder_resume(upb_pbdecoder *d, void *p, const char *buf,
size_t size, const upb_bufhandle *handle) {
UPB_UNUSED(p); /* Useless; just for the benefit of the JIT. */
- d->buf_param = buf;
+ /* d->skip and d->residual_end could probably elegantly be represented
+ * as a single variable, to more easily represent this invariant. */
+ assert(!(d->skip && d->residual_end > d->residual));
+
+ /* We need to remember the original size_param, so that the value we return
+ * is relative to it, even if we do some skipping first. */
d->size_param = size;
d->handle = handle;
+ /* Have to handle this case specially (ie. not with skip()) because the user
+ * is allowed to pass a NULL buffer here, which won't allow us to safely
+ * calculate a d->end or use our normal functions like curbufleft(). */
+ if (d->skip && d->skip >= size) {
+ d->skip -= size;
+ d->bufstart_ofs += size;
+ buf = &dummy_char;
+ size = 0;
+
+ /* We can't just return now, because we might need to execute some ops
+ * like CHECKDELIM, which could call some callbacks and pop the stack. */
+ }
+
+ /* We need to pretend that this was the actual buffer param, since some of the
+ * calculations assume that d->ptr/d->buf is relative to this. */
+ d->buf_param = buf;
+
+ if (!buf) {
+ /* NULL buf is ok if its entire span is covered by the "skip" above, but
+ * by this point we know that "skip" doesn't cover the buffer. */
+ seterr(d, "Passed NULL buffer over non-skippable region.");
+ return upb_pbdecoder_suspend(d);
+ }
+
if (d->residual_end > d->residual) {
/* We have residual bytes from the last buffer. */
assert(d->ptr == d->residual);
@@ -7678,23 +8396,18 @@ int32_t upb_pbdecoder_resume(upb_pbdecoder *d, void *p, const char *buf,
d->checkpoint = d->ptr;
+ /* Handle skips that don't cover the whole buffer (as above). */
if (d->skip) {
size_t skip_bytes = d->skip;
d->skip = 0;
CHECK_RETURN(skip(d, skip_bytes));
- d->checkpoint = d->ptr;
- }
-
- if (!buf) {
- /* NULL buf is ok if its entire span is covered by the "skip" above, but
- * by this point we know that "skip" doesn't cover the buffer. */
- seterr(d, "Passed NULL buffer over non-skippable region.");
- return upb_pbdecoder_suspend(d);
+ checkpoint(d);
}
+ /* If we're inside an unknown group, continue to parse unknown values. */
if (d->top->groupnum < 0) {
CHECK_RETURN(upb_pbdecoder_skipunknown(d, -1, 0));
- d->checkpoint = d->ptr;
+ checkpoint(d);
}
return DECODE_OK;
@@ -7709,15 +8422,14 @@ size_t upb_pbdecoder_suspend(upb_pbdecoder *d) {
d->ptr = d->residual;
return 0;
} else {
- size_t consumed;
+ size_t ret = d->size_param - (d->end - d->checkpoint);
assert(!in_residual_buf(d, d->checkpoint));
- assert(d->buf == d->buf_param);
+ assert(d->buf == d->buf_param || d->buf == &dummy_char);
- consumed = d->checkpoint - d->buf;
- d->bufstart_ofs += consumed;
+ d->bufstart_ofs += (d->checkpoint - d->buf);
d->residual_end = d->residual;
switchtobuf(d, d->residual, d->residual_end);
- return consumed;
+ return ret;
}
}
@@ -7835,8 +8547,7 @@ UPB_NOINLINE int32_t upb_pbdecoder_decode_varint_slow(upb_pbdecoder *d,
int bitpos;
*u64 = 0;
for(bitpos = 0; bitpos < 70 && (byte & 0x80); bitpos += 7) {
- int32_t ret = getbytes(d, &byte, 1);
- if (ret >= 0) return ret;
+ CHECK_RETURN(getbytes(d, &byte, 1));
*u64 |= (uint64_t)(byte & 0x7F) << bitpos;
}
if(bitpos == 70 && (byte & 0x80)) {
@@ -8436,6 +9147,7 @@ upb_pbdecoder *upb_pbdecoder_create(upb_env *e, const upb_pbdecodermethod *m,
d->env = e;
d->limit = d->stack + default_max_nesting - 1;
d->stack_size = default_max_nesting;
+ d->status = NULL;
upb_pbdecoder_reset(d);
upb_bytessink_reset(&d->input_, &m->input_handler_, d);
@@ -8557,7 +9269,6 @@ bool upb_pbdecoder_setmaxnesting(upb_pbdecoder *d, size_t max) {
*/
-#include <stdlib.h>
/* The output buffer is divided into segments; a segment is a string of data
* that is "ready to go" -- it does not need any varint lengths inserted into
@@ -8802,12 +9513,12 @@ static void new_tag(upb_handlers *h, const upb_fielddef *f, upb_wiretype_t wt,
upb_handlerattr *attr) {
uint32_t n = upb_fielddef_number(f);
- tag_t *tag = malloc(sizeof(tag_t));
+ tag_t *tag = upb_gmalloc(sizeof(tag_t));
tag->bytes = upb_vencode64((n << 3) | wt, tag->tag);
upb_handlerattr_init(attr);
upb_handlerattr_sethandlerdata(attr, tag);
- upb_handlers_addcleanup(h, tag, free);
+ upb_handlers_addcleanup(h, tag, upb_gfree);
}
static bool encode_tag(upb_pb_encoder *e, const tag_t *tag) {
@@ -9066,12 +9777,9 @@ upb_pb_encoder *upb_pb_encoder_create(upb_env *env, const upb_handlers *h,
upb_sink *upb_pb_encoder_input(upb_pb_encoder *e) { return &e->input_; }
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-upb_def **upb_load_defs_from_descriptor(const char *str, size_t len, int *n,
- void *owner, upb_status *status) {
+upb_filedef **upb_loaddescriptor(const char *buf, size_t n, const void *owner,
+ upb_status *status) {
/* Create handlers. */
const upb_pbdecodermethod *decoder_m;
const upb_handlers *reader_h = upb_descreader_newhandlers(&reader_h);
@@ -9080,8 +9788,8 @@ upb_def **upb_load_defs_from_descriptor(const char *str, size_t len, int *n,
upb_pbdecoder *decoder;
upb_descreader *reader;
bool ok;
- upb_def **ret = NULL;
- upb_def **defs;
+ size_t i;
+ upb_filedef **ret = NULL;
upb_pbdecodermethodopts_init(&opts, reader_h);
decoder_m = upb_pbdecodermethod_new(&opts, &decoder_m);
@@ -9093,12 +9801,24 @@ upb_def **upb_load_defs_from_descriptor(const char *str, size_t len, int *n,
decoder = upb_pbdecoder_create(&env, decoder_m, upb_descreader_input(reader));
/* Push input data. */
- ok = upb_bufsrc_putbuf(str, len, upb_pbdecoder_input(decoder));
+ ok = upb_bufsrc_putbuf(buf, n, upb_pbdecoder_input(decoder));
+
+ if (!ok) {
+ goto cleanup;
+ }
- if (!ok) goto cleanup;
- defs = upb_descreader_getdefs(reader, owner, n);
- ret = malloc(sizeof(upb_def*) * (*n));
- memcpy(ret, defs, sizeof(upb_def*) * (*n));
+ ret = upb_gmalloc(sizeof (*ret) * (upb_descreader_filecount(reader) + 1));
+
+ if (!ret) {
+ goto cleanup;
+ }
+
+ for (i = 0; i < upb_descreader_filecount(reader); i++) {
+ ret[i] = upb_descreader_file(reader, i);
+ upb_filedef_ref(ret[i], owner);
+ }
+
+ ret[i] = NULL;
cleanup:
upb_env_uninit(&env);
@@ -9106,51 +9826,6 @@ cleanup:
upb_pbdecodermethod_unref(decoder_m, &decoder_m);
return ret;
}
-
-bool upb_load_descriptor_into_symtab(upb_symtab *s, const char *str, size_t len,
- upb_status *status) {
- int n;
- bool success;
- upb_def **defs = upb_load_defs_from_descriptor(str, len, &n, &defs, status);
- if (!defs) return false;
- success = upb_symtab_add(s, defs, n, &defs, status);
- free(defs);
- return success;
-}
-
-char *upb_readfile(const char *filename, size_t *len) {
- long size;
- char *buf;
- FILE *f = fopen(filename, "rb");
- if(!f) return NULL;
- if(fseek(f, 0, SEEK_END) != 0) goto error;
- size = ftell(f);
- if(size < 0) goto error;
- if(fseek(f, 0, SEEK_SET) != 0) goto error;
- buf = malloc(size + 1);
- if(size && fread(buf, size, 1, f) != 1) goto error;
- fclose(f);
- if (len) *len = size;
- return buf;
-
-error:
- fclose(f);
- return NULL;
-}
-
-bool upb_load_descriptor_file_into_symtab(upb_symtab *symtab, const char *fname,
- upb_status *status) {
- size_t len;
- bool success;
- char *data = upb_readfile(fname, &len);
- if (!data) {
- if (status) upb_status_seterrf(status, "Couldn't read file: %s", fname);
- return false;
- }
- success = upb_load_descriptor_into_symtab(symtab, data, len, status);
- free(data);
- return success;
-}
/*
* upb::pb::TextPrinter
*
@@ -9164,7 +9839,6 @@ bool upb_load_descriptor_file_into_symtab(upb_symtab *symtab, const char *fname,
#include <inttypes.h>
#include <stdarg.h>
#include <stdio.h>
-#include <stdlib.h>
#include <string.h>
@@ -9260,14 +9934,14 @@ bool putf(upb_textprinter *p, const char *fmt, ...) {
va_end(args_copy);
/* + 1 for NULL terminator (vsprintf() requires it even if we don't). */
- str = malloc(len + 1);
+ str = upb_gmalloc(len + 1);
if (!str) return false;
written = vsprintf(str, fmt, args);
va_end(args);
UPB_ASSERT_VAR(written, written == len);
ok = upb_bytessink_putbuf(p->output_, p->subc, str, len, NULL);
- free(str);
+ upb_gfree(str);
return ok;
}
@@ -9636,12 +10310,11 @@ upb_decoderet upb_vdecode_max8_wright(upb_decoderet r) {
** - handling of keys/escape-sequences/etc that span input buffers.
*/
-#include <stdio.h>
-#include <stdint.h>
#include <assert.h>
-#include <string.h>
-#include <stdlib.h>
#include <errno.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
#define UPB_JSON_MAX_DEPTH 64
@@ -9654,6 +10327,9 @@ typedef struct {
const upb_msgdef *m;
const upb_fielddef *f;
+ /* The table mapping json name to fielddef for this message. */
+ upb_strtable *name_table;
+
/* We are in a repeated-field context, ready to emit mapentries as
* submessages. This flag alters the start-of-object (open-brace) behavior to
* begin a sequence of mapentry messages rather than a single submessage. */
@@ -9674,7 +10350,7 @@ typedef struct {
struct upb_json_parser {
upb_env *env;
- upb_byteshandler input_handler_;
+ const upb_json_parsermethod *method;
upb_bytessink input_;
/* Stack to track the JSON scopes we are in. */
@@ -9709,6 +10385,19 @@ struct upb_json_parser {
uint32_t digit;
};
+struct upb_json_parsermethod {
+ upb_refcounted base;
+
+ upb_byteshandler input_handler_;
+
+ /* Mainly for the purposes of refcounting, so all the fielddefs we point
+ * to stay alive. */
+ const upb_msgdef *msg;
+
+ /* Keys are upb_msgdef*, values are upb_strtable (json_name -> fielddef) */
+ upb_inttable name_tables;
+};
+
#define PARSER_CHECK_RETURN(x) if (!(x)) return false
/* Used to signal that a capture has been suspended. */
@@ -9737,6 +10426,13 @@ static bool check_stack(upb_json_parser *p) {
return true;
}
+static void set_name_table(upb_json_parser *p, upb_jsonparser_frame *frame) {
+ upb_value v;
+ bool ok = upb_inttable_lookupptr(&p->method->name_tables, frame->m, &v);
+ UPB_ASSERT_VAR(ok, ok);
+ frame->name_table = upb_value_getptr(v);
+}
+
/* There are GCC/Clang built-ins for overflow checking which we could start
* using if there was any performance benefit to it. */
@@ -10333,6 +11029,7 @@ static bool start_stringval(upb_json_parser *p) {
upb_sink_startstr(&p->top->sink, sel, 0, &inner->sink);
inner->m = p->top->m;
inner->f = p->top->f;
+ inner->name_table = NULL;
inner->is_map = false;
inner->is_mapentry = false;
p->top = inner;
@@ -10379,8 +11076,8 @@ static bool end_stringval(upb_json_parser *p) {
case UPB_TYPE_STRING: {
upb_selector_t sel = getsel_for_handlertype(p, UPB_HANDLER_ENDSTR);
- upb_sink_endstr(&p->top->sink, sel);
p->top--;
+ upb_sink_endstr(&p->top->sink, sel);
break;
}
@@ -10519,6 +11216,7 @@ static bool handle_mapentry(upb_json_parser *p) {
sel = getsel_for_handlertype(p, UPB_HANDLER_STARTSUBMSG);
upb_sink_startsubmsg(&p->top->sink, sel, &inner->sink);
inner->m = mapentrymsg;
+ inner->name_table = NULL;
inner->mapfield = mapfield;
inner->is_map = false;
@@ -10555,20 +11253,20 @@ static bool end_membername(upb_json_parser *p) {
} else {
size_t len;
const char *buf = accumulate_getptr(p, &len);
- const upb_fielddef *f = upb_msgdef_ntof(p->top->m, buf, len);
+ upb_value v;
+
+ if (upb_strtable_lookup2(p->top->name_table, buf, len, &v)) {
+ p->top->f = upb_value_getconstptr(v);
+ multipart_end(p);
- if (!f) {
+ return true;
+ } else {
/* TODO(haberman): Ignore unknown fields if requested/configured to do
* so. */
upb_status_seterrf(&p->status, "No such field: %.*s\n", (int)len, buf);
upb_env_reporterror(p->env, &p->status);
return false;
}
-
- p->top->f = f;
- multipart_end(p);
-
- return true;
}
}
@@ -10610,6 +11308,7 @@ static bool start_subobject(upb_json_parser *p) {
sel = getsel_for_handlertype(p, UPB_HANDLER_STARTSEQ);
upb_sink_startseq(&p->top->sink, sel, &inner->sink);
inner->m = upb_fielddef_msgsubdef(p->top->f);
+ inner->name_table = NULL;
inner->mapfield = p->top->f;
inner->f = NULL;
inner->is_map = true;
@@ -10630,6 +11329,7 @@ static bool start_subobject(upb_json_parser *p) {
sel = getsel_for_handlertype(p, UPB_HANDLER_STARTSUBMSG);
upb_sink_startsubmsg(&p->top->sink, sel, &inner->sink);
inner->m = upb_fielddef_msgsubdef(p->top->f);
+ set_name_table(p, inner);
inner->f = NULL;
inner->is_map = false;
inner->is_mapentry = false;
@@ -10679,6 +11379,7 @@ static bool start_array(upb_json_parser *p) {
sel = getsel_for_handlertype(p, UPB_HANDLER_STARTSEQ);
upb_sink_startseq(&p->top->sink, sel, &inner->sink);
inner->m = p->top->m;
+ inner->name_table = NULL;
inner->f = p->top->f;
inner->is_map = false;
inner->is_mapentry = false;
@@ -10736,11 +11437,11 @@ static void end_object(upb_json_parser *p) {
* final state once, when the closing '"' is seen. */
-#line 1218 "upb/json/parser.rl"
+#line 1245 "upb/json/parser.rl"
-#line 1130 "upb/json/parser.c"
+#line 1157 "upb/json/parser.c"
static const char _json_actions[] = {
0, 1, 0, 1, 2, 1, 3, 1,
5, 1, 6, 1, 7, 1, 8, 1,
@@ -10889,7 +11590,7 @@ static const int json_en_value_machine = 27;
static const int json_en_main = 1;
-#line 1221 "upb/json/parser.rl"
+#line 1248 "upb/json/parser.rl"
size_t parse(void *closure, const void *hd, const char *buf, size_t size,
const upb_bufhandle *handle) {
@@ -10911,7 +11612,7 @@ size_t parse(void *closure, const void *hd, const char *buf, size_t size,
capture_resume(parser, buf);
-#line 1301 "upb/json/parser.c"
+#line 1328 "upb/json/parser.c"
{
int _klen;
unsigned int _trans;
@@ -10986,118 +11687,118 @@ _match:
switch ( *_acts++ )
{
case 0:
-#line 1133 "upb/json/parser.rl"
+#line 1160 "upb/json/parser.rl"
{ p--; {cs = stack[--top]; goto _again;} }
break;
case 1:
-#line 1134 "upb/json/parser.rl"
+#line 1161 "upb/json/parser.rl"
{ p--; {stack[top++] = cs; cs = 10; goto _again;} }
break;
case 2:
-#line 1138 "upb/json/parser.rl"
+#line 1165 "upb/json/parser.rl"
{ start_text(parser, p); }
break;
case 3:
-#line 1139 "upb/json/parser.rl"
+#line 1166 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(end_text(parser, p)); }
break;
case 4:
-#line 1145 "upb/json/parser.rl"
+#line 1172 "upb/json/parser.rl"
{ start_hex(parser); }
break;
case 5:
-#line 1146 "upb/json/parser.rl"
+#line 1173 "upb/json/parser.rl"
{ hexdigit(parser, p); }
break;
case 6:
-#line 1147 "upb/json/parser.rl"
+#line 1174 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(end_hex(parser)); }
break;
case 7:
-#line 1153 "upb/json/parser.rl"
+#line 1180 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(escape(parser, p)); }
break;
case 8:
-#line 1159 "upb/json/parser.rl"
+#line 1186 "upb/json/parser.rl"
{ p--; {cs = stack[--top]; goto _again;} }
break;
case 9:
-#line 1162 "upb/json/parser.rl"
+#line 1189 "upb/json/parser.rl"
{ {stack[top++] = cs; cs = 19; goto _again;} }
break;
case 10:
-#line 1164 "upb/json/parser.rl"
+#line 1191 "upb/json/parser.rl"
{ p--; {stack[top++] = cs; cs = 27; goto _again;} }
break;
case 11:
-#line 1169 "upb/json/parser.rl"
+#line 1196 "upb/json/parser.rl"
{ start_member(parser); }
break;
case 12:
-#line 1170 "upb/json/parser.rl"
+#line 1197 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(end_membername(parser)); }
break;
case 13:
-#line 1173 "upb/json/parser.rl"
+#line 1200 "upb/json/parser.rl"
{ end_member(parser); }
break;
case 14:
-#line 1179 "upb/json/parser.rl"
+#line 1206 "upb/json/parser.rl"
{ start_object(parser); }
break;
case 15:
-#line 1182 "upb/json/parser.rl"
+#line 1209 "upb/json/parser.rl"
{ end_object(parser); }
break;
case 16:
-#line 1188 "upb/json/parser.rl"
+#line 1215 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(start_array(parser)); }
break;
case 17:
-#line 1192 "upb/json/parser.rl"
+#line 1219 "upb/json/parser.rl"
{ end_array(parser); }
break;
case 18:
-#line 1197 "upb/json/parser.rl"
+#line 1224 "upb/json/parser.rl"
{ start_number(parser, p); }
break;
case 19:
-#line 1198 "upb/json/parser.rl"
+#line 1225 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(end_number(parser, p)); }
break;
case 20:
-#line 1200 "upb/json/parser.rl"
+#line 1227 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(start_stringval(parser)); }
break;
case 21:
-#line 1201 "upb/json/parser.rl"
+#line 1228 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(end_stringval(parser)); }
break;
case 22:
-#line 1203 "upb/json/parser.rl"
+#line 1230 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(parser_putbool(parser, true)); }
break;
case 23:
-#line 1205 "upb/json/parser.rl"
+#line 1232 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(parser_putbool(parser, false)); }
break;
case 24:
-#line 1207 "upb/json/parser.rl"
+#line 1234 "upb/json/parser.rl"
{ /* null value */ }
break;
case 25:
-#line 1209 "upb/json/parser.rl"
+#line 1236 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(start_subobject(parser)); }
break;
case 26:
-#line 1210 "upb/json/parser.rl"
+#line 1237 "upb/json/parser.rl"
{ end_subobject(parser); }
break;
case 27:
-#line 1215 "upb/json/parser.rl"
+#line 1242 "upb/json/parser.rl"
{ p--; {cs = stack[--top]; goto _again;} }
break;
-#line 1487 "upb/json/parser.c"
+#line 1514 "upb/json/parser.c"
}
}
@@ -11110,10 +11811,10 @@ _again:
_out: {}
}
-#line 1242 "upb/json/parser.rl"
+#line 1269 "upb/json/parser.rl"
if (p != pe) {
- upb_status_seterrf(&parser->status, "Parse error at %s\n", p);
+ upb_status_seterrf(&parser->status, "Parse error at '%.*s'\n", pe - p, p);
upb_env_reporterror(parser->env, &parser->status);
} else {
capture_suspend(parser, &p);
@@ -11151,13 +11852,13 @@ static void json_parser_reset(upb_json_parser *p) {
/* Emit Ragel initialization of the parser. */
-#line 1541 "upb/json/parser.c"
+#line 1568 "upb/json/parser.c"
{
cs = json_start;
top = 0;
}
-#line 1282 "upb/json/parser.rl"
+#line 1309 "upb/json/parser.rl"
p->current_state = cs;
p->parser_top = top;
accumulate_clear(p);
@@ -11167,10 +11868,84 @@ static void json_parser_reset(upb_json_parser *p) {
upb_status_clear(&p->status);
}
+static void visit_json_parsermethod(const upb_refcounted *r,
+ upb_refcounted_visit *visit,
+ void *closure) {
+ const upb_json_parsermethod *method = (upb_json_parsermethod*)r;
+ visit(r, upb_msgdef_upcast2(method->msg), closure);
+}
+
+static void free_json_parsermethod(upb_refcounted *r) {
+ upb_json_parsermethod *method = (upb_json_parsermethod*)r;
+
+ upb_inttable_iter i;
+ upb_inttable_begin(&i, &method->name_tables);
+ for(; !upb_inttable_done(&i); upb_inttable_next(&i)) {
+ upb_value val = upb_inttable_iter_value(&i);
+ upb_strtable *t = upb_value_getptr(val);
+ upb_strtable_uninit(t);
+ upb_gfree(t);
+ }
+
+ upb_inttable_uninit(&method->name_tables);
+
+ upb_gfree(r);
+}
+
+static void add_jsonname_table(upb_json_parsermethod *m, const upb_msgdef* md) {
+ upb_msg_field_iter i;
+ upb_strtable *t;
+
+ /* It would be nice to stack-allocate this, but protobufs do not limit the
+ * length of fields to any reasonable limit. */
+ char *buf = NULL;
+ size_t len = 0;
+
+ if (upb_inttable_lookupptr(&m->name_tables, md, NULL)) {
+ return;
+ }
+
+ /* TODO(haberman): handle malloc failure. */
+ t = upb_gmalloc(sizeof(*t));
+ upb_strtable_init(t, UPB_CTYPE_CONSTPTR);
+ upb_inttable_insertptr(&m->name_tables, md, upb_value_ptr(t));
+
+ for(upb_msg_field_begin(&i, md);
+ !upb_msg_field_done(&i);
+ upb_msg_field_next(&i)) {
+ const upb_fielddef *f = upb_msg_iter_field(&i);
+
+ /* Add an entry for the JSON name. */
+ size_t field_len = upb_fielddef_getjsonname(f, buf, len);
+ if (field_len > len) {
+ size_t len2;
+ buf = upb_grealloc(buf, 0, field_len);
+ len = field_len;
+ len2 = upb_fielddef_getjsonname(f, buf, len);
+ UPB_ASSERT_VAR(len2, len == len2);
+ }
+ upb_strtable_insert(t, buf, upb_value_constptr(f));
+
+ if (strcmp(buf, upb_fielddef_name(f)) != 0) {
+ /* Since the JSON name is different from the regular field name, add an
+ * entry for the raw name (compliant proto3 JSON parsers must accept
+ * both). */
+ upb_strtable_insert(t, upb_fielddef_name(f), upb_value_constptr(f));
+ }
+
+ if (upb_fielddef_issubmsg(f)) {
+ add_jsonname_table(m, upb_fielddef_msgsubdef(f));
+ }
+ }
+
+ upb_gfree(buf);
+}
/* Public API *****************************************************************/
-upb_json_parser *upb_json_parser_create(upb_env *env, upb_sink *output) {
+upb_json_parser *upb_json_parser_create(upb_env *env,
+ const upb_json_parsermethod *method,
+ upb_sink *output) {
#ifndef NDEBUG
const size_t size_before = upb_env_bytesallocated(env);
#endif
@@ -11178,17 +11953,16 @@ upb_json_parser *upb_json_parser_create(upb_env *env, upb_sink *output) {
if (!p) return false;
p->env = env;
+ p->method = method;
p->limit = p->stack + UPB_JSON_MAX_DEPTH;
p->accumulate_buf = NULL;
p->accumulate_buf_size = 0;
- upb_byteshandler_init(&p->input_handler_);
- upb_byteshandler_setstring(&p->input_handler_, parse, NULL);
- upb_byteshandler_setendstr(&p->input_handler_, end, NULL);
- upb_bytessink_reset(&p->input_, &p->input_handler_, p);
+ upb_bytessink_reset(&p->input_, &method->input_handler_, p);
json_parser_reset(p);
upb_sink_reset(&p->top->sink, output->handlers, output->closure);
p->top->m = upb_handlers_msgdef(output->handlers);
+ set_name_table(p, p->top);
/* If this fails, uncomment and increase the value in parser.h. */
/* fprintf(stderr, "%zd\n", upb_env_bytesallocated(env) - size_before); */
@@ -11199,14 +11973,38 @@ upb_json_parser *upb_json_parser_create(upb_env *env, upb_sink *output) {
upb_bytessink *upb_json_parser_input(upb_json_parser *p) {
return &p->input_;
}
+
+upb_json_parsermethod *upb_json_parsermethod_new(const upb_msgdef* md,
+ const void* owner) {
+ static const struct upb_refcounted_vtbl vtbl = {visit_json_parsermethod,
+ free_json_parsermethod};
+ upb_json_parsermethod *ret = upb_gmalloc(sizeof(*ret));
+ upb_refcounted_init(upb_json_parsermethod_upcast_mutable(ret), &vtbl, owner);
+
+ ret->msg = md;
+ upb_ref2(md, ret);
+
+ upb_byteshandler_init(&ret->input_handler_);
+ upb_byteshandler_setstring(&ret->input_handler_, parse, ret);
+ upb_byteshandler_setendstr(&ret->input_handler_, end, ret);
+
+ upb_inttable_init(&ret->name_tables, UPB_CTYPE_PTR);
+
+ add_jsonname_table(ret, md);
+
+ return ret;
+}
+
+const upb_byteshandler *upb_json_parsermethod_inputhandler(
+ const upb_json_parsermethod *m) {
+ return &m->input_handler_;
+}
/*
** This currently uses snprintf() to format primitives, and could be optimized
** further.
*/
-#include <stdlib.h>
-#include <stdio.h>
#include <string.h>
#include <stdint.h>
@@ -11233,15 +12031,34 @@ struct upb_json_printer {
/* StringPiece; a pointer plus a length. */
typedef struct {
- const char *ptr;
+ char *ptr;
size_t len;
} strpc;
-strpc *newstrpc(upb_handlers *h, const upb_fielddef *f) {
- strpc *ret = malloc(sizeof(*ret));
- ret->ptr = upb_fielddef_name(f);
- ret->len = strlen(ret->ptr);
- upb_handlers_addcleanup(h, ret, free);
+void freestrpc(void *ptr) {
+ strpc *pc = ptr;
+ upb_gfree(pc->ptr);
+ upb_gfree(pc);
+}
+
+/* Convert fielddef name to JSON name and return as a string piece. */
+strpc *newstrpc(upb_handlers *h, const upb_fielddef *f,
+ bool preserve_fieldnames) {
+ /* TODO(haberman): handle malloc failure. */
+ strpc *ret = upb_gmalloc(sizeof(*ret));
+ if (preserve_fieldnames) {
+ ret->ptr = upb_gstrdup(upb_fielddef_name(f));
+ ret->len = strlen(ret->ptr);
+ } else {
+ size_t len;
+ ret->len = upb_fielddef_getjsonname(f, NULL, 0);
+ ret->ptr = upb_gmalloc(ret->len);
+ len = upb_fielddef_getjsonname(f, ret->ptr, ret->len);
+ UPB_ASSERT_VAR(len, len == ret->len);
+ ret->len--; /* NULL */
+ }
+
+ upb_handlers_addcleanup(h, ret, freestrpc);
return ret;
}
@@ -11272,7 +12089,7 @@ UPB_INLINE bool is_json_escaped(char c) {
return uc < kControlCharLimit || uc == '"' || uc == '\\';
}
-UPB_INLINE char* json_nice_escape(char c) {
+UPB_INLINE const char* json_nice_escape(char c) {
switch (c) {
case '"': return "\\\"";
case '\\': return "\\\\";
@@ -11745,11 +12562,12 @@ static size_t mapkey_bytes(void *closure, const void *handler_data,
static void set_enum_hd(upb_handlers *h,
const upb_fielddef *f,
+ bool preserve_fieldnames,
upb_handlerattr *attr) {
- EnumHandlerData *hd = malloc(sizeof(EnumHandlerData));
+ EnumHandlerData *hd = upb_gmalloc(sizeof(EnumHandlerData));
hd->enumdef = (const upb_enumdef *)upb_fielddef_subdef(f);
- hd->keyname = newstrpc(h, f);
- upb_handlers_addcleanup(h, hd, free);
+ hd->keyname = newstrpc(h, f, preserve_fieldnames);
+ upb_handlers_addcleanup(h, hd, upb_gfree);
upb_handlerattr_sethandlerdata(attr, hd);
}
@@ -11765,7 +12583,8 @@ static void set_enum_hd(upb_handlers *h,
* our sources that emit mapentry messages do so canonically (with one key
* field, and then one value field), so this is not a pressing concern at the
* moment. */
-void printer_sethandlers_mapentry(const void *closure, upb_handlers *h) {
+void printer_sethandlers_mapentry(const void *closure, bool preserve_fieldnames,
+ upb_handlers *h) {
const upb_msgdef *md = upb_handlers_msgdef(h);
/* A mapentry message is printed simply as '"key": value'. Rather than
@@ -11839,7 +12658,7 @@ void printer_sethandlers_mapentry(const void *closure, upb_handlers *h) {
break;
case UPB_TYPE_ENUM: {
upb_handlerattr enum_attr = UPB_HANDLERATTR_INITIALIZER;
- set_enum_hd(h, value_field, &enum_attr);
+ set_enum_hd(h, value_field, preserve_fieldnames, &enum_attr);
upb_handlers_setint32(h, value_field, mapvalue_enum, &enum_attr);
upb_handlerattr_uninit(&enum_attr);
break;
@@ -11858,13 +12677,13 @@ void printer_sethandlers(const void *closure, upb_handlers *h) {
bool is_mapentry = upb_msgdef_mapentry(md);
upb_handlerattr empty_attr = UPB_HANDLERATTR_INITIALIZER;
upb_msg_field_iter i;
-
- UPB_UNUSED(closure);
+ const bool *preserve_fieldnames_ptr = closure;
+ const bool preserve_fieldnames = *preserve_fieldnames_ptr;
if (is_mapentry) {
/* mapentry messages are sufficiently different that we handle them
* separately. */
- printer_sethandlers_mapentry(closure, h);
+ printer_sethandlers_mapentry(closure, preserve_fieldnames, h);
return;
}
@@ -11885,7 +12704,8 @@ void printer_sethandlers(const void *closure, upb_handlers *h) {
const upb_fielddef *f = upb_msg_iter_field(&i);
upb_handlerattr name_attr = UPB_HANDLERATTR_INITIALIZER;
- upb_handlerattr_sethandlerdata(&name_attr, newstrpc(h, f));
+ upb_handlerattr_sethandlerdata(&name_attr,
+ newstrpc(h, f, preserve_fieldnames));
if (upb_fielddef_ismap(f)) {
upb_handlers_setstartseq(h, f, startmap, &name_attr);
@@ -11908,7 +12728,7 @@ void printer_sethandlers(const void *closure, upb_handlers *h) {
* option later to control this behavior, but we will wait for a real
* need first. */
upb_handlerattr enum_attr = UPB_HANDLERATTR_INITIALIZER;
- set_enum_hd(h, f, &enum_attr);
+ set_enum_hd(h, f, preserve_fieldnames, &enum_attr);
if (upb_fielddef_isseq(f)) {
upb_handlers_setint32(h, f, repeated_enum, &enum_attr);
@@ -11985,6 +12805,8 @@ upb_sink *upb_json_printer_input(upb_json_printer *p) {
}
const upb_handlers *upb_json_printer_newhandlers(const upb_msgdef *md,
+ bool preserve_fieldnames,
const void *owner) {
- return upb_handlers_newfrozen(md, owner, printer_sethandlers, NULL);
+ return upb_handlers_newfrozen(
+ md, owner, printer_sethandlers, &preserve_fieldnames);
}
diff --git a/ruby/ext/google/protobuf_c/upb.h b/ruby/ext/google/protobuf_c/upb.h
index 078e2a28..e8b683bd 100644
--- a/ruby/ext/google/protobuf_c/upb.h
+++ b/ruby/ext/google/protobuf_c/upb.h
@@ -5,6 +5,7 @@
**
** - upb::MessageDef (upb_msgdef): describes a "message" construct.
** - upb::FieldDef (upb_fielddef): describes a message field.
+** - upb::FileDef (upb_filedef): describes a .proto file and its defs.
** - upb::EnumDef (upb_enumdef): describes an enum.
** - upb::OneofDef (upb_oneofdef): describes a oneof.
** - upb::Def (upb_def): base class of all the others.
@@ -54,7 +55,7 @@
** 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.
*/
@@ -79,6 +80,18 @@
#include <stdbool.h>
#include <stddef.h>
+#ifdef __cplusplus
+namespace upb {
+class Allocator;
+class Arena;
+class Environment;
+class ErrorSpace;
+class Status;
+template <int N> class InlinedArena;
+template <int N> class InlinedEnvironment;
+}
+#endif
+
/* UPB_INLINE: inline if possible, emit standalone code if required. */
#ifdef __cplusplus
#define UPB_INLINE inline
@@ -146,6 +159,7 @@
#define UPB_ASSERT_STDLAYOUT(type) \
static_assert(std::is_standard_layout<type>::value, \
#type " must be standard layout");
+#define UPB_FINAL final
#else /* !defined(UPB_CXX11) */
#define UPB_DISALLOW_COPY_AND_ASSIGN(class_name) \
class_name(const class_name&); \
@@ -155,6 +169,7 @@
~class_name(); \
UPB_DISALLOW_COPY_AND_ASSIGN(class_name)
#define UPB_ASSERT_STDLAYOUT(type)
+#define UPB_FINAL
#endif
/* UPB_DECLARE_TYPE()
@@ -193,13 +208,15 @@
template <> \
class Pointer<cppname> : public PointerBase<cppname, cppbase> { \
public: \
- explicit Pointer(cppname* ptr) : PointerBase(ptr) {} \
+ explicit Pointer(cppname* ptr) \
+ : PointerBase<cppname, cppbase>(ptr) {} \
}; \
template <> \
class Pointer<const cppname> \
: public PointerBase<const cppname, const cppbase> { \
public: \
- explicit Pointer(const cppname* ptr) : PointerBase(ptr) {} \
+ explicit Pointer(const cppname* ptr) \
+ : PointerBase<const cppname, const cppbase>(ptr) {} \
}; \
}
@@ -211,13 +228,15 @@
template <> \
class Pointer<cppname> : public PointerBase2<cppname, cppbase, cppbase2> { \
public: \
- explicit Pointer(cppname* ptr) : PointerBase2(ptr) {} \
+ explicit Pointer(cppname* ptr) \
+ : PointerBase2<cppname, cppbase, cppbase2>(ptr) {} \
}; \
template <> \
class Pointer<const cppname> \
: public PointerBase2<const cppname, const cppbase, const cppbase2> { \
public: \
- explicit Pointer(const cppname* ptr) : PointerBase2(ptr) {} \
+ explicit Pointer(const cppname* ptr) \
+ : PointerBase2<const cppname, const cppbase, const cppbase2>(ptr) {} \
}; \
}
@@ -252,6 +271,7 @@
/* Generic function type. */
typedef void upb_func();
+
/* C++ Casts ******************************************************************/
#ifdef __cplusplus
@@ -329,243 +349,430 @@ class PointerBase2 : public PointerBase<T, Base> {
#endif
-/* upb::reffed_ptr ************************************************************/
+/* upb::ErrorSpace ************************************************************/
+
+/* A upb::ErrorSpace represents some domain of possible error values. This lets
+ * upb::Status attach specific error codes to operations, like POSIX/C errno,
+ * Win32 error codes, etc. Clients who want to know the very specific error
+ * code can check the error space and then know the type of the integer code.
+ *
+ * NOTE: upb::ErrorSpace is currently not used and should be considered
+ * experimental. It is important primarily in cases where upb is performing
+ * I/O, but upb doesn't currently have any components that do this. */
+
+UPB_DECLARE_TYPE(upb::ErrorSpace, upb_errorspace)
#ifdef __cplusplus
+class upb::ErrorSpace {
+#else
+struct upb_errorspace {
+#endif
+ const char *name;
+};
-#include <algorithm> /* For std::swap(). */
-namespace upb {
+/* upb::Status ****************************************************************/
-/* Provides RAII semantics for upb refcounted objects. Each reffed_ptr owns a
- * ref on whatever object it points to (if any). */
-template <class T> class reffed_ptr {
+/* upb::Status represents a success or failure status and error message.
+ * It owns no resources and allocates no memory, so it should work
+ * even in OOM situations. */
+UPB_DECLARE_TYPE(upb::Status, upb_status)
+
+/* The maximum length of an error message before it will get truncated. */
+#define UPB_STATUS_MAX_MESSAGE 128
+
+UPB_BEGIN_EXTERN_C
+
+const char *upb_status_errmsg(const upb_status *status);
+bool upb_ok(const upb_status *status);
+upb_errorspace *upb_status_errspace(const upb_status *status);
+int upb_status_errcode(const upb_status *status);
+
+/* Any of the functions that write to a status object allow status to be NULL,
+ * to support use cases where the function's caller does not care about the
+ * status message. */
+void upb_status_clear(upb_status *status);
+void upb_status_seterrmsg(upb_status *status, const char *msg);
+void upb_status_seterrf(upb_status *status, const char *fmt, ...);
+void upb_status_vseterrf(upb_status *status, const char *fmt, va_list args);
+void upb_status_copy(upb_status *to, const upb_status *from);
+
+UPB_END_EXTERN_C
+
+#ifdef __cplusplus
+
+class upb::Status {
public:
- reffed_ptr() : ptr_(NULL) {}
+ Status() { upb_status_clear(this); }
- /* If ref_donor is NULL, takes a new ref, otherwise adopts from ref_donor. */
- template <class U>
- reffed_ptr(U* val, const void* ref_donor = NULL)
- : ptr_(upb::upcast(val)) {
- if (ref_donor) {
- assert(ptr_);
- ptr_->DonateRef(ref_donor, this);
- } else if (ptr_) {
- ptr_->Ref(this);
- }
- }
+ /* Returns true if there is no error. */
+ bool ok() const { return upb_ok(this); }
- template <class U>
- reffed_ptr(const reffed_ptr<U>& other)
- : ptr_(upb::upcast(other.get())) {
- if (ptr_) ptr_->Ref(this);
- }
+ /* Optional error space and code, useful if the caller wants to
+ * programmatically check the specific kind of error. */
+ ErrorSpace* error_space() { return upb_status_errspace(this); }
+ int error_code() const { return upb_status_errcode(this); }
- ~reffed_ptr() { if (ptr_) ptr_->Unref(this); }
+ /* The returned string is invalidated by any other call into the status. */
+ const char *error_message() const { return upb_status_errmsg(this); }
- template <class U>
- reffed_ptr& operator=(const reffed_ptr<U>& other) {
- reset(other.get());
- return *this;
+ /* The error message will be truncated if it is longer than
+ * UPB_STATUS_MAX_MESSAGE-4. */
+ void SetErrorMessage(const char* msg) { upb_status_seterrmsg(this, msg); }
+ void SetFormattedErrorMessage(const char* fmt, ...) {
+ va_list args;
+ va_start(args, fmt);
+ upb_status_vseterrf(this, fmt, args);
+ va_end(args);
}
- reffed_ptr& operator=(const reffed_ptr& other) {
- reset(other.get());
- return *this;
- }
+ /* Resets the status to a successful state with no message. */
+ void Clear() { upb_status_clear(this); }
- /* TODO(haberman): add C++11 move construction/assignment for greater
- * efficiency. */
+ void CopyFrom(const Status& other) { upb_status_copy(this, &other); }
- void swap(reffed_ptr& other) {
- if (ptr_ == other.ptr_) {
- return;
- }
+ private:
+ UPB_DISALLOW_COPY_AND_ASSIGN(Status)
+#else
+struct upb_status {
+#endif
+ bool ok_;
- if (ptr_) ptr_->DonateRef(this, &other);
- if (other.ptr_) other.ptr_->DonateRef(&other, this);
- std::swap(ptr_, other.ptr_);
- }
+ /* Specific status code defined by some error space (optional). */
+ int code_;
+ upb_errorspace *error_space_;
- T& operator*() const {
- assert(ptr_);
- return *ptr_;
- }
+ /* TODO(haberman): add file/line of error? */
- T* operator->() const {
- assert(ptr_);
- return ptr_;
- }
+ /* Error message; NULL-terminated. */
+ char msg[UPB_STATUS_MAX_MESSAGE];
+};
- T* get() const { return ptr_; }
+#define UPB_STATUS_INIT {true, 0, NULL, {0}}
- /* If ref_donor is NULL, takes a new ref, otherwise adopts from ref_donor. */
- template <class U>
- void reset(U* ptr = NULL, const void* ref_donor = NULL) {
- reffed_ptr(ptr, ref_donor).swap(*this);
- }
- template <class U>
- reffed_ptr<U> down_cast() {
- return reffed_ptr<U>(upb::down_cast<U*>(get()));
- }
+/** Built-in error spaces. ****************************************************/
- template <class U>
- reffed_ptr<U> dyn_cast() {
- return reffed_ptr<U>(upb::dyn_cast<U*>(get()));
- }
+/* Errors raised by upb that we want to be able to detect programmatically. */
+typedef enum {
+ UPB_NOMEM /* Can't reuse ENOMEM because it is POSIX, not ISO C. */
+} upb_errcode_t;
- /* Plain release() is unsafe; if we were the only owner, it would leak the
- * object. Instead we provide this: */
- T* ReleaseTo(const void* new_owner) {
- T* ret = NULL;
- ptr_->DonateRef(this, new_owner);
- std::swap(ret, ptr_);
- return ret;
- }
+extern upb_errorspace upb_upberr;
+
+void upb_upberr_setoom(upb_status *s);
+
+/* Since errno is defined by standard C, we define an error space for it in
+ * core upb. Other error spaces should be defined in other, platform-specific
+ * modules. */
+
+extern upb_errorspace upb_errnoerr;
+
+
+/** upb::Allocator ************************************************************/
+
+/* A upb::Allocator is a possibly-stateful allocator object.
+ *
+ * It could either be an arena allocator (which doesn't require individual
+ * free() calls) or a regular malloc() (which does). The client must therefore
+ * free memory unless it knows that the allocator is an arena allocator. */
+UPB_DECLARE_TYPE(upb::Allocator, upb_alloc)
+
+/* A malloc()/free() function.
+ * If "size" is 0 then the function acts like free(), otherwise it acts like
+ * realloc(). Only "oldsize" bytes from a previous allocation are preserved. */
+typedef void *upb_alloc_func(upb_alloc *alloc, void *ptr, size_t oldsize,
+ size_t size);
+
+#ifdef __cplusplus
+
+class upb::Allocator UPB_FINAL {
+ public:
+ Allocator() {}
private:
- T* ptr_;
+ UPB_DISALLOW_COPY_AND_ASSIGN(Allocator)
+
+ public:
+#else
+struct upb_alloc {
+#endif /* __cplusplus */
+ upb_alloc_func *func;
};
-} /* namespace upb */
+UPB_INLINE void *upb_malloc(upb_alloc *alloc, size_t size) {
+ assert(size > 0);
+ return alloc->func(alloc, NULL, 0, size);
+}
-#endif /* __cplusplus */
+UPB_INLINE void *upb_realloc(upb_alloc *alloc, void *ptr, size_t oldsize,
+ size_t size) {
+ assert(size > 0);
+ return alloc->func(alloc, ptr, oldsize, size);
+}
+UPB_INLINE void upb_free(upb_alloc *alloc, void *ptr) {
+ alloc->func(alloc, ptr, 0, 0);
+}
-/* upb::Status ****************************************************************/
+/* The global allocator used by upb. Uses the standard malloc()/free(). */
-#ifdef __cplusplus
-namespace upb {
-class ErrorSpace;
-class Status;
+extern upb_alloc upb_alloc_global;
+
+/* Functions that hard-code the global malloc.
+ *
+ * We still get benefit because we can put custom logic into our global
+ * allocator, like injecting out-of-memory faults in debug/testing builds. */
+
+UPB_INLINE void *upb_gmalloc(size_t size) {
+ return upb_malloc(&upb_alloc_global, size);
}
-#endif
-UPB_DECLARE_TYPE(upb::ErrorSpace, upb_errorspace)
-UPB_DECLARE_TYPE(upb::Status, upb_status)
+UPB_INLINE void *upb_grealloc(void *ptr, size_t oldsize, size_t size) {
+ return upb_realloc(&upb_alloc_global, ptr, oldsize, size);
+}
-/* The maximum length of an error message before it will get truncated. */
-#define UPB_STATUS_MAX_MESSAGE 128
+UPB_INLINE void upb_gfree(void *ptr) {
+ upb_free(&upb_alloc_global, ptr);
+}
+
+/* upb::Arena *****************************************************************/
+
+/* upb::Arena is a specific allocator implementation that uses arena allocation.
+ * The user provides an allocator that will be used to allocate the underlying
+ * arena blocks. Arenas by nature do not require the individual allocations
+ * to be freed. However the Arena does allow users to register cleanup
+ * functions that will run when the arena is destroyed.
+ *
+ * A upb::Arena is *not* thread-safe.
+ *
+ * You could write a thread-safe arena allocator that satisfies the
+ * upb::Allocator interface, but it would not be as efficient for the
+ * single-threaded case. */
+UPB_DECLARE_TYPE(upb::Arena, upb_arena)
-/* An error callback function is used to report errors from some component.
- * The function can return "true" to indicate that the component should try
- * to recover and proceed, but this is not always possible. */
-typedef bool upb_errcb_t(void *closure, const upb_status* status);
+typedef void upb_cleanup_func(void *ud);
+
+#define UPB_ARENA_BLOCK_OVERHEAD (sizeof(size_t)*4)
+
+UPB_BEGIN_EXTERN_C
+
+void upb_arena_init(upb_arena *a);
+void upb_arena_init2(upb_arena *a, void *mem, size_t n, upb_alloc *alloc);
+void upb_arena_uninit(upb_arena *a);
+upb_alloc *upb_arena_alloc(upb_arena *a);
+bool upb_arena_addcleanup(upb_arena *a, upb_cleanup_func *func, void *ud);
+size_t upb_arena_bytesallocated(const upb_arena *a);
+void upb_arena_setnextblocksize(upb_arena *a, size_t size);
+void upb_arena_setmaxblocksize(upb_arena *a, size_t size);
+
+UPB_END_EXTERN_C
#ifdef __cplusplus
-class upb::ErrorSpace {
+
+class upb::Arena {
+ public:
+ /* A simple arena with no initial memory block and the default allocator. */
+ Arena() { upb_arena_init(this); }
+
+ /* Constructs an arena with the given initial block which allocates blocks
+ * with the given allocator. The given allocator must outlive the Arena.
+ *
+ * If you pass NULL for the allocator it will default to the global allocator
+ * upb_alloc_global, and NULL/0 for the initial block will cause there to be
+ * no initial block. */
+ Arena(void *mem, size_t len, Allocator* a) {
+ upb_arena_init2(this, mem, len, a);
+ }
+
+ ~Arena() { upb_arena_uninit(this); }
+
+ /* Sets the size of the next block the Arena will request (unless the
+ * requested allocation is larger). Each block will double in size until the
+ * max limit is reached. */
+ void SetNextBlockSize(size_t size) { upb_arena_setnextblocksize(this, size); }
+
+ /* Sets the maximum block size. No blocks larger than this will be requested
+ * from the underlying allocator unless individual arena allocations are
+ * larger. */
+ void SetMaxBlockSize(size_t size) { upb_arena_setmaxblocksize(this, size); }
+
+ /* Allows this arena to be used as a generic allocator.
+ *
+ * The arena does not need free() calls so when using Arena as an allocator
+ * it is safe to skip them. However they are no-ops so there is no harm in
+ * calling free() either. */
+ Allocator* allocator() { return upb_arena_alloc(this); }
+
+ /* Add a cleanup function to run when the arena is destroyed.
+ * Returns false on out-of-memory. */
+ bool AddCleanup(upb_cleanup_func* func, void* ud) {
+ return upb_arena_addcleanup(this, func, ud);
+ }
+
+ /* Total number of bytes that have been allocated. It is undefined what
+ * Realloc() does to this counter. */
+ size_t BytesAllocated() const {
+ return upb_arena_bytesallocated(this);
+ }
+
+ private:
+ UPB_DISALLOW_COPY_AND_ASSIGN(Arena)
+
#else
-struct upb_errorspace {
-#endif
- const char *name;
- /* Should the error message in the status object according to this code. */
- void (*set_message)(upb_status* status, int code);
+struct upb_arena {
+#endif /* __cplusplus */
+ /* We implement the allocator interface.
+ * This must be the first member of upb_arena! */
+ upb_alloc alloc;
+
+ /* Allocator to allocate arena blocks. We are responsible for freeing these
+ * when we are destroyed. */
+ upb_alloc *block_alloc;
+
+ size_t bytes_allocated;
+ size_t next_block_size;
+ size_t max_block_size;
+
+ /* Linked list of blocks. Points to an arena_block, defined in env.c */
+ void *block_head;
+
+ /* Cleanup entries. Pointer to a cleanup_ent, defined in env.c */
+ void *cleanup_head;
+
+ /* For future expansion, since the size of this struct is exposed to users. */
+ void *future1;
+ void *future2;
};
-#ifdef __cplusplus
-/* Object representing a success or failure status.
- * It owns no resources and allocates no memory, so it should work
- * even in OOM situations. */
+/* upb::Environment ***********************************************************/
-class upb::Status {
- public:
- Status();
+/* A upb::Environment provides a means for injecting malloc and an
+ * error-reporting callback into encoders/decoders. This allows them to be
+ * independent of nearly all assumptions about their actual environment.
+ *
+ * It is also a container for allocating the encoders/decoders themselves that
+ * insulates clients from knowing their actual size. This provides ABI
+ * compatibility even if the size of the objects change. And this allows the
+ * structure definitions to be in the .c files instead of the .h files, making
+ * the .h files smaller and more readable.
+ *
+ * We might want to consider renaming this to "Pipeline" if/when the concept of
+ * a pipeline element becomes more formalized. */
+UPB_DECLARE_TYPE(upb::Environment, upb_env)
- /* Returns true if there is no error. */
- bool ok() const;
+/* A function that receives an error report from an encoder or decoder. The
+ * callback can return true to request that the error should be recovered, but
+ * if the error is not recoverable this has no effect. */
+typedef bool upb_error_func(void *ud, const upb_status *status);
- /* Optional error space and code, useful if the caller wants to
- * programmatically check the specific kind of error. */
- ErrorSpace* error_space();
- int code() const;
+UPB_BEGIN_EXTERN_C
- const char *error_message() const;
+void upb_env_init(upb_env *e);
+void upb_env_init2(upb_env *e, void *mem, size_t n, upb_alloc *alloc);
+void upb_env_uninit(upb_env *e);
- /* The error message will be truncated if it is longer than
- * UPB_STATUS_MAX_MESSAGE-4. */
- void SetErrorMessage(const char* msg);
- void SetFormattedErrorMessage(const char* fmt, ...);
+void upb_env_initonly(upb_env *e);
- /* If there is no error message already, this will use the ErrorSpace to
- * populate the error message for this code. The caller can still call
- * SetErrorMessage() to give a more specific message. */
- void SetErrorCode(ErrorSpace* space, int code);
+upb_arena *upb_env_arena(upb_env *e);
+bool upb_env_ok(const upb_env *e);
+void upb_env_seterrorfunc(upb_env *e, upb_error_func *func, void *ud);
- /* Resets the status to a successful state with no message. */
- void Clear();
+/* Convenience wrappers around the methods of the contained arena. */
+void upb_env_reporterrorsto(upb_env *e, upb_status *s);
+bool upb_env_reporterror(upb_env *e, const upb_status *s);
+void *upb_env_malloc(upb_env *e, size_t size);
+void *upb_env_realloc(upb_env *e, void *ptr, size_t oldsize, size_t size);
+void upb_env_free(upb_env *e, void *ptr);
+bool upb_env_addcleanup(upb_env *e, upb_cleanup_func *func, void *ud);
+size_t upb_env_bytesallocated(const upb_env *e);
+
+UPB_END_EXTERN_C
+
+#ifdef __cplusplus
- void CopyFrom(const Status& other);
+class upb::Environment {
+ public:
+ /* The given Arena must outlive this environment. */
+ Environment() { upb_env_initonly(this); }
+
+ Environment(void *mem, size_t len, Allocator *a) : arena_(mem, len, a) {
+ upb_env_initonly(this);
+ }
+
+ Arena* arena() { return upb_env_arena(this); }
+
+ /* Set a custom error reporting function. */
+ void SetErrorFunction(upb_error_func* func, void* ud) {
+ upb_env_seterrorfunc(this, func, ud);
+ }
+
+ /* Set the error reporting function to simply copy the status to the given
+ * status and abort. */
+ void ReportErrorsTo(Status* status) { upb_env_reporterrorsto(this, status); }
+
+ /* Returns true if all allocations and AddCleanup() calls have succeeded,
+ * and no errors were reported with ReportError() (except ones that recovered
+ * successfully). */
+ bool ok() const { return upb_env_ok(this); }
+
+ /* Reports an error to this environment's callback, returning true if
+ * the caller should try to recover. */
+ bool ReportError(const Status* status) {
+ return upb_env_reporterror(this, status);
+ }
private:
- UPB_DISALLOW_COPY_AND_ASSIGN(Status)
+ UPB_DISALLOW_COPY_AND_ASSIGN(Environment)
+
#else
-struct upb_status {
-#endif
+struct upb_env {
+#endif /* __cplusplus */
+ upb_arena arena_;
+ upb_error_func *error_func_;
+ void *error_ud_;
bool ok_;
+};
- /* Specific status code defined by some error space (optional). */
- int code_;
- upb_errorspace *error_space_;
- /* Error message; NULL-terminated. */
- char msg[UPB_STATUS_MAX_MESSAGE];
-};
+/* upb::InlinedArena **********************************************************/
+/* upb::InlinedEnvironment ****************************************************/
-#define UPB_STATUS_INIT {true, 0, NULL, {0}}
+/* upb::InlinedArena and upb::InlinedEnvironment seed their arenas with a
+ * predefined amount of memory. No heap memory will be allocated until the
+ * initial block is exceeded.
+ *
+ * These types only exist in C++ */
#ifdef __cplusplus
-extern "C" {
-#endif
-/* The returned string is invalidated by any other call into the status. */
-const char *upb_status_errmsg(const upb_status *status);
-bool upb_ok(const upb_status *status);
-upb_errorspace *upb_status_errspace(const upb_status *status);
-int upb_status_errcode(const upb_status *status);
+template <int N> class upb::InlinedArena : public upb::Arena {
+ public:
+ InlinedArena() : Arena(initial_block_, N, NULL) {}
+ explicit InlinedArena(Allocator* a) : Arena(initial_block_, N, a) {}
-/* Any of the functions that write to a status object allow status to be NULL,
- * to support use cases where the function's caller does not care about the
- * status message. */
-void upb_status_clear(upb_status *status);
-void upb_status_seterrmsg(upb_status *status, const char *msg);
-void upb_status_seterrf(upb_status *status, const char *fmt, ...);
-void upb_status_vseterrf(upb_status *status, const char *fmt, va_list args);
-void upb_status_seterrcode(upb_status *status, upb_errorspace *space, int code);
-void upb_status_copy(upb_status *to, const upb_status *from);
+ private:
+ UPB_DISALLOW_COPY_AND_ASSIGN(InlinedArena)
-#ifdef __cplusplus
-} /* extern "C" */
+ char initial_block_[N + UPB_ARENA_BLOCK_OVERHEAD];
+};
-namespace upb {
+template <int N> class upb::InlinedEnvironment : public upb::Environment {
+ public:
+ InlinedEnvironment() : Environment(initial_block_, N, NULL) {}
+ explicit InlinedEnvironment(Allocator *a)
+ : Environment(initial_block_, N, a) {}
-/* C++ Wrappers */
-inline Status::Status() { Clear(); }
-inline bool Status::ok() const { return upb_ok(this); }
-inline const char* Status::error_message() const {
- return upb_status_errmsg(this);
-}
-inline void Status::SetErrorMessage(const char* msg) {
- upb_status_seterrmsg(this, msg);
-}
-inline void Status::SetFormattedErrorMessage(const char* fmt, ...) {
- va_list args;
- va_start(args, fmt);
- upb_status_vseterrf(this, fmt, args);
- va_end(args);
-}
-inline void Status::SetErrorCode(ErrorSpace* space, int code) {
- upb_status_seterrcode(this, space, code);
-}
-inline void Status::Clear() { upb_status_clear(this); }
-inline void Status::CopyFrom(const Status& other) {
- upb_status_copy(this, &other);
-}
+ private:
+ UPB_DISALLOW_COPY_AND_ASSIGN(InlinedEnvironment)
+
+ char initial_block_[N + UPB_ARENA_BLOCK_OVERHEAD];
+};
+
+#endif /* __cplusplus */
-} /* namespace upb */
-#endif
#endif /* UPB_H_ */
@@ -607,10 +814,14 @@ typedef struct {
#endif
/* Like strdup(), which isn't always available since it's not ANSI C. */
-char *upb_strdup(const char *s);
+char *upb_strdup(const char *s, upb_alloc *a);
/* Variant that works with a length-delimited rather than NULL-delimited string,
* as supported by strtable. */
-char *upb_strdup2(const char *s, size_t len);
+char *upb_strdup2(const char *s, size_t len, upb_alloc *a);
+
+UPB_INLINE char *upb_gstrdup(const char *s) {
+ return upb_strdup(s, &upb_alloc_global);
+}
UPB_INLINE void _upb_value_setval(upb_value *v, uint64_t val,
upb_ctype_t ctype) {
@@ -787,14 +998,40 @@ typedef struct {
* initialize const hash tables. Then we cast away const when we have to.
*/
const upb_tabent *entries;
+
+#ifndef NDEBUG
+ /* This table's allocator. We make the user pass it in to every relevant
+ * function and only use this to check it in debug mode. We do this solely
+ * to keep upb_table as small as possible. This might seem slightly paranoid
+ * but the plan is to use upb_table for all map fields and extension sets in
+ * a forthcoming message representation, so there could be a lot of these.
+ * If this turns out to be too annoying later, we can change it (since this
+ * is an internal-only header file). */
+ upb_alloc *alloc;
+#endif
} upb_table;
+#ifdef NDEBUG
+# define UPB_TABLE_INIT(count, mask, ctype, size_lg2, entries) \
+ {count, mask, ctype, size_lg2, entries}
+#else
+# ifdef UPB_DEBUG_REFS
+/* At the moment the only mutable tables we statically initialize are debug
+ * ref tables. */
+# define UPB_TABLE_INIT(count, mask, ctype, size_lg2, entries) \
+ {count, mask, ctype, size_lg2, entries, &upb_alloc_debugrefs}
+# else
+# define UPB_TABLE_INIT(count, mask, ctype, size_lg2, entries) \
+ {count, mask, ctype, size_lg2, entries, NULL}
+# endif
+#endif
+
typedef struct {
upb_table t;
} upb_strtable;
#define UPB_STRTABLE_INIT(count, mask, ctype, size_lg2, entries) \
- {{count, mask, ctype, size_lg2, entries}}
+ {UPB_TABLE_INIT(count, mask, ctype, size_lg2, entries)}
#define UPB_EMPTY_STRTABLE_INIT(ctype) \
UPB_STRTABLE_INIT(0, 0, ctype, 0, NULL)
@@ -807,7 +1044,7 @@ typedef struct {
} upb_inttable;
#define UPB_INTTABLE_INIT(count, mask, ctype, size_lg2, ent, a, asize, acount) \
- {{count, mask, ctype, size_lg2, ent}, a, asize, acount}
+ {UPB_TABLE_INIT(count, mask, ctype, size_lg2, ent), a, asize, acount}
#define UPB_EMPTY_INTTABLE_INIT(ctype) \
UPB_INTTABLE_INIT(0, 0, ctype, 0, NULL, NULL, 0, 0)
@@ -847,10 +1084,26 @@ UPB_INLINE bool upb_arrhas(upb_tabval key) {
/* Initialize and uninitialize a table, respectively. If memory allocation
* failed, false is returned that the table is uninitialized. */
-bool upb_inttable_init(upb_inttable *table, upb_ctype_t ctype);
-bool upb_strtable_init(upb_strtable *table, upb_ctype_t ctype);
-void upb_inttable_uninit(upb_inttable *table);
-void upb_strtable_uninit(upb_strtable *table);
+bool upb_inttable_init2(upb_inttable *table, upb_ctype_t ctype, upb_alloc *a);
+bool upb_strtable_init2(upb_strtable *table, upb_ctype_t ctype, upb_alloc *a);
+void upb_inttable_uninit2(upb_inttable *table, upb_alloc *a);
+void upb_strtable_uninit2(upb_strtable *table, upb_alloc *a);
+
+UPB_INLINE bool upb_inttable_init(upb_inttable *table, upb_ctype_t ctype) {
+ return upb_inttable_init2(table, ctype, &upb_alloc_global);
+}
+
+UPB_INLINE bool upb_strtable_init(upb_strtable *table, upb_ctype_t ctype) {
+ return upb_strtable_init2(table, ctype, &upb_alloc_global);
+}
+
+UPB_INLINE void upb_inttable_uninit(upb_inttable *table) {
+ upb_inttable_uninit2(table, &upb_alloc_global);
+}
+
+UPB_INLINE void upb_strtable_uninit(upb_strtable *table) {
+ upb_strtable_uninit2(table, &upb_alloc_global);
+}
/* Returns the number of values in the table. */
size_t upb_inttable_count(const upb_inttable *t);
@@ -865,9 +1118,20 @@ UPB_INLINE size_t upb_strtable_count(const upb_strtable *t) {
*
* If a table resize was required but memory allocation failed, false is
* returned and the table is unchanged. */
-bool upb_inttable_insert(upb_inttable *t, uintptr_t key, upb_value val);
-bool upb_strtable_insert2(upb_strtable *t, const char *key, size_t len,
- upb_value val);
+bool upb_inttable_insert2(upb_inttable *t, uintptr_t key, upb_value val,
+ upb_alloc *a);
+bool upb_strtable_insert3(upb_strtable *t, const char *key, size_t len,
+ upb_value val, upb_alloc *a);
+
+UPB_INLINE bool upb_inttable_insert(upb_inttable *t, uintptr_t key,
+ upb_value val) {
+ return upb_inttable_insert2(t, key, val, &upb_alloc_global);
+}
+
+UPB_INLINE bool upb_strtable_insert2(upb_strtable *t, const char *key,
+ size_t len, upb_value val) {
+ return upb_strtable_insert3(t, key, len, val, &upb_alloc_global);
+}
/* For NULL-terminated strings. */
UPB_INLINE bool upb_strtable_insert(upb_strtable *t, const char *key,
@@ -890,8 +1154,13 @@ UPB_INLINE bool upb_strtable_lookup(const upb_strtable *t, const char *key,
/* Removes an item from the table. Returns true if the remove was successful,
* and stores the removed item in *val if non-NULL. */
bool upb_inttable_remove(upb_inttable *t, uintptr_t key, upb_value *val);
-bool upb_strtable_remove2(upb_strtable *t, const char *key, size_t len,
- upb_value *val);
+bool upb_strtable_remove3(upb_strtable *t, const char *key, size_t len,
+ upb_value *val, upb_alloc *alloc);
+
+UPB_INLINE bool upb_strtable_remove2(upb_strtable *t, const char *key,
+ size_t len, upb_value *val) {
+ return upb_strtable_remove3(t, key, len, val, &upb_alloc_global);
+}
/* For NULL-terminated strings. */
UPB_INLINE bool upb_strtable_remove(upb_strtable *t, const char *key,
@@ -906,19 +1175,33 @@ 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_push(upb_inttable *t, upb_value val);
+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_insertptr(upb_inttable *t, const void *key, upb_value val);
+bool upb_inttable_insertptr2(upb_inttable *t, const void *key, upb_value val,
+ upb_alloc *a);
bool upb_inttable_removeptr(upb_inttable *t, const void *key, upb_value *val);
bool upb_inttable_lookupptr(
const upb_inttable *t, const void *key, upb_value *val);
+UPB_INLINE bool upb_inttable_insertptr(upb_inttable *t, const void *key,
+ upb_value val) {
+ return upb_inttable_insertptr2(t, key, val, &upb_alloc_global);
+}
+
/* Optimizes the table for the current set of entries, for both memory use and
* lookup time. Client should call this after all entries have been inserted;
* inserting more entries is legal, but will likely require a table resize. */
-void upb_inttable_compact(upb_inttable *t);
+void upb_inttable_compact2(upb_inttable *t, upb_alloc *a);
+
+UPB_INLINE void upb_inttable_compact(upb_inttable *t) {
+ upb_inttable_compact2(t, &upb_alloc_global);
+}
/* A special-case inlinable version of the lookup routine for 32-bit
* integers. */
@@ -947,7 +1230,7 @@ UPB_INLINE bool upb_inttable_lookup32(const upb_inttable *t, uint32_t key,
}
/* Exposed for testing only. */
-bool upb_strtable_resize(upb_strtable *t, size_t size_lg2);
+bool upb_strtable_resize(upb_strtable *t, size_t size_lg2, upb_alloc *a);
/* Iterators ******************************************************************/
@@ -992,8 +1275,8 @@ typedef struct {
void upb_strtable_begin(upb_strtable_iter *i, const upb_strtable *t);
void upb_strtable_next(upb_strtable_iter *i);
bool upb_strtable_done(const upb_strtable_iter *i);
-const char *upb_strtable_iter_key(upb_strtable_iter *i);
-size_t upb_strtable_iter_keylength(upb_strtable_iter *i);
+const char *upb_strtable_iter_key(const upb_strtable_iter *i);
+size_t upb_strtable_iter_keylength(const upb_strtable_iter *i);
upb_value upb_strtable_iter_value(const upb_strtable_iter *i);
void upb_strtable_iter_setdone(upb_strtable_iter *i);
bool upb_strtable_iter_isequal(const upb_strtable_iter *i1,
@@ -1046,7 +1329,10 @@ bool upb_inttable_iter_isequal(const upb_inttable_iter *i1,
/* #define UPB_DEBUG_REFS */
#ifdef __cplusplus
-namespace upb { class RefCounted; }
+namespace upb {
+class RefCounted;
+template <class T> class reffed_ptr;
+}
#endif
UPB_DECLARE_TYPE(upb::RefCounted, upb_refcounted)
@@ -1114,10 +1400,12 @@ struct upb_refcounted {
};
#ifdef UPB_DEBUG_REFS
-#define UPB_REFCOUNT_INIT(refs, ref2s) \
- {&static_refcount, NULL, NULL, 0, true, refs, ref2s}
+extern upb_alloc upb_alloc_debugrefs;
+#define UPB_REFCOUNT_INIT(vtbl, refs, ref2s) \
+ {&static_refcount, NULL, vtbl, 0, true, refs, ref2s}
#else
-#define UPB_REFCOUNT_INIT(refs, ref2s) {&static_refcount, NULL, NULL, 0, true}
+#define UPB_REFCOUNT_INIT(vtbl, refs, ref2s) \
+ {&static_refcount, NULL, vtbl, 0, true}
#endif
UPB_BEGIN_EXTERN_C
@@ -1250,6 +1538,111 @@ inline void RefCounted::CheckRef(const void *owner) const {
} /* namespace upb */
#endif
+
+/* upb::reffed_ptr ************************************************************/
+
+#ifdef __cplusplus
+
+#include <algorithm> /* For std::swap(). */
+
+/* Provides RAII semantics for upb refcounted objects. Each reffed_ptr owns a
+ * ref on whatever object it points to (if any). */
+template <class T> class upb::reffed_ptr {
+ public:
+ reffed_ptr() : ptr_(NULL) {}
+
+ /* If ref_donor is NULL, takes a new ref, otherwise adopts from ref_donor. */
+ template <class U>
+ reffed_ptr(U* val, const void* ref_donor = NULL)
+ : ptr_(upb::upcast(val)) {
+ if (ref_donor) {
+ assert(ptr_);
+ ptr_->DonateRef(ref_donor, this);
+ } else if (ptr_) {
+ ptr_->Ref(this);
+ }
+ }
+
+ template <class U>
+ reffed_ptr(const reffed_ptr<U>& other)
+ : ptr_(upb::upcast(other.get())) {
+ if (ptr_) ptr_->Ref(this);
+ }
+
+ reffed_ptr(const reffed_ptr& other)
+ : ptr_(upb::upcast(other.get())) {
+ if (ptr_) ptr_->Ref(this);
+ }
+
+ ~reffed_ptr() { if (ptr_) ptr_->Unref(this); }
+
+ template <class U>
+ reffed_ptr& operator=(const reffed_ptr<U>& other) {
+ reset(other.get());
+ return *this;
+ }
+
+ reffed_ptr& operator=(const reffed_ptr& other) {
+ reset(other.get());
+ return *this;
+ }
+
+ /* TODO(haberman): add C++11 move construction/assignment for greater
+ * efficiency. */
+
+ void swap(reffed_ptr& other) {
+ if (ptr_ == other.ptr_) {
+ return;
+ }
+
+ if (ptr_) ptr_->DonateRef(this, &other);
+ if (other.ptr_) other.ptr_->DonateRef(&other, this);
+ std::swap(ptr_, other.ptr_);
+ }
+
+ T& operator*() const {
+ assert(ptr_);
+ return *ptr_;
+ }
+
+ T* operator->() const {
+ assert(ptr_);
+ return ptr_;
+ }
+
+ T* get() const { return ptr_; }
+
+ /* If ref_donor is NULL, takes a new ref, otherwise adopts from ref_donor. */
+ template <class U>
+ void reset(U* ptr = NULL, const void* ref_donor = NULL) {
+ reffed_ptr(ptr, ref_donor).swap(*this);
+ }
+
+ template <class U>
+ reffed_ptr<U> down_cast() {
+ return reffed_ptr<U>(upb::down_cast<U*>(get()));
+ }
+
+ template <class U>
+ reffed_ptr<U> dyn_cast() {
+ return reffed_ptr<U>(upb::dyn_cast<U*>(get()));
+ }
+
+ /* Plain release() is unsafe; if we were the only owner, it would leak the
+ * object. Instead we provide this: */
+ T* ReleaseTo(const void* new_owner) {
+ T* ret = NULL;
+ ptr_->DonateRef(this, new_owner);
+ std::swap(ret, ptr_);
+ return ret;
+ }
+
+ private:
+ T* ptr_;
+};
+
+#endif /* __cplusplus */
+
#endif /* UPB_REFCOUNT_H_ */
#ifdef __cplusplus
@@ -1261,12 +1654,17 @@ namespace upb {
class Def;
class EnumDef;
class FieldDef;
+class FileDef;
class MessageDef;
class OneofDef;
}
#endif
UPB_DECLARE_DERIVED_TYPE(upb::Def, upb::RefCounted, upb_def, upb_refcounted)
+UPB_DECLARE_DERIVED_TYPE(upb::OneofDef, upb::RefCounted, upb_oneofdef,
+ upb_refcounted)
+UPB_DECLARE_DERIVED_TYPE(upb::FileDef, upb::RefCounted, upb_filedef,
+ upb_refcounted)
/* The maximum message depth that the type graph can have. This is a resource
* limit for the C stack since we sometimes need to recursively traverse the
@@ -1278,15 +1676,16 @@ UPB_DECLARE_DERIVED_TYPE(upb::Def, upb::RefCounted, upb_def, upb_refcounted)
#define UPB_MAX_MESSAGE_DEPTH 64
-/* upb::Def: base class for defs *********************************************/
+/* upb::Def: base class for top-level defs ***********************************/
-/* All the different kind of defs we support. These correspond 1:1 with
- * declarations in a .proto file. */
+/* All the different kind of defs that can be defined at the top-level and put
+ * in a SymbolTable or appear in a FileDef::defs() list. This excludes some
+ * defs (like oneofs and files). It only includes fields because they can be
+ * defined as extensions. */
typedef enum {
UPB_DEF_MSG,
UPB_DEF_FIELD,
UPB_DEF_ENUM,
- UPB_DEF_ONEOF,
UPB_DEF_SERVICE, /* Not yet implemented. */
UPB_DEF_ANY = -1 /* Wildcard for upb_symtab_get*() */
} upb_deftype_t;
@@ -1309,6 +1708,9 @@ class upb::Def {
/* "fullname" is the def's fully-qualified name (eg. foo.bar.Message). */
const char *full_name() const;
+ /* The final part of a def's name (eg. Message). */
+ const char *name() const;
+
/* The def must be mutable. Caller retains ownership of fullname. Defs are
* not required to have a name; if a def has no name when it is frozen, it
* will remain an anonymous def. On failure, returns false and details in "s"
@@ -1316,6 +1718,11 @@ class upb::Def {
bool set_full_name(const char* fullname, upb::Status* s);
bool set_full_name(const std::string &fullname, upb::Status* s);
+ /* The file in which this def appears. It is not necessary to add a def to a
+ * file (and consequently the accessor may return NULL). Set this by calling
+ * file->Add(def). */
+ FileDef* file() const;
+
/* Freezes the given defs; this validates all constraints and marks the defs
* as frozen (read-only). "defs" may not contain any fielddefs, but fields
* of any msgdefs will be frozen.
@@ -1327,7 +1734,7 @@ class upb::Def {
*
* After this operation succeeds, the finalized defs must only be accessed
* through a const pointer! */
- static bool Freeze(Def* const* defs, int n, Status* status);
+ static bool Freeze(Def* const* defs, size_t n, Status* status);
static bool Freeze(const std::vector<Def*>& defs, Status* status);
private:
@@ -1346,8 +1753,13 @@ UPB_REFCOUNTED_CMETHODS(upb_def, upb_def_upcast)
upb_deftype_t upb_def_type(const upb_def *d);
const char *upb_def_fullname(const upb_def *d);
+const char *upb_def_name(const upb_def *d);
+const upb_filedef *upb_def_file(const upb_def *d);
bool upb_def_setfullname(upb_def *def, const char *fullname, upb_status *s);
-bool upb_def_freeze(upb_def *const *defs, int n, upb_status *s);
+bool upb_def_freeze(upb_def *const *defs, size_t n, upb_status *s);
+
+/* Temporary API: for internal use only. */
+bool _upb_def_validate(upb_def *const*defs, size_t n, upb_status *s);
UPB_END_EXTERN_C
@@ -1420,7 +1832,6 @@ UPB_END_EXTERN_C
UPB_DECLARE_DEF_TYPE(upb::FieldDef, fielddef, FIELD)
UPB_DECLARE_DEF_TYPE(upb::MessageDef, msgdef, MSG)
UPB_DECLARE_DEF_TYPE(upb::EnumDef, enumdef, ENUM)
-UPB_DECLARE_DEF_TYPE(upb::OneofDef, oneofdef, ONEOF)
#undef UPB_DECLARE_DEF_TYPE
#undef UPB_DEF_CASTS
@@ -1483,6 +1894,11 @@ typedef enum {
UPB_DESCRIPTOR_TYPE_SINT64 = 18
} upb_descriptortype_t;
+typedef enum {
+ UPB_SYNTAX_PROTO2 = 2,
+ UPB_SYNTAX_PROTO3 = 3
+} upb_syntax_t;
+
/* Maximum field number allowed for FieldDefs. This is an inherent limit of the
* protobuf wire format. */
#define UPB_MAX_FIELDNUMBER ((1 << 29) - 1)
@@ -1537,6 +1953,27 @@ class upb::FieldDef {
uint32_t number() const; /* Returns 0 if uninitialized. */
bool is_extension() const;
+ /* Copies the JSON name for this field into the given buffer. Returns the
+ * actual size of the JSON name, including the NULL terminator. If the
+ * return value is 0, the JSON name is unset. If the return value is
+ * greater than len, the JSON name was truncated. The buffer is always
+ * NULL-terminated if len > 0.
+ *
+ * The JSON name always defaults to a camelCased version of the regular
+ * name. However if the regular name is unset, the JSON name will be unset
+ * also.
+ */
+ size_t GetJsonName(char* buf, size_t len) const;
+
+ /* Convenience version of the above function which copies the JSON name
+ * into the given string, returning false if the name is not set. */
+ template <class T>
+ bool GetJsonName(T* str) {
+ str->resize(GetJsonName(NULL, 0));
+ GetJsonName(&(*str)[0], str->size());
+ return str->size() > 0;
+ }
+
/* For UPB_TYPE_MESSAGE fields only where is_tag_delimited() == false,
* indicates whether this field should have lazy parsing handlers that yield
* the unparsed string for the submessage.
@@ -1557,7 +1994,7 @@ class upb::FieldDef {
* whatever message this field belongs to. Guaranteed to be less than
* f->containing_type()->field_count(). May only be accessed once the def has
* been finalized. */
- int index() const;
+ uint32_t index() const;
/* The MessageDef to which this field belongs.
*
@@ -1589,6 +2026,18 @@ class upb::FieldDef {
bool IsPrimitive() const;
bool IsMap() const;
+ /* Whether this field must be able to explicitly represent presence:
+ *
+ * * This is always false for repeated fields (an empty repeated field is
+ * equivalent to a repeated field with zero entries).
+ *
+ * * This is always true for submessages.
+ *
+ * * For other fields, it depends on the message (see
+ * MessageDef::SetPrimitivesHavePresence())
+ */
+ bool HasPresence() const;
+
/* How integers are encoded. Only meaningful for integer types.
* Defaults to UPB_INTFMT_VARIABLE, and is reset when "type" changes. */
IntegerFormat integer_format() const;
@@ -1690,6 +2139,16 @@ class upb::FieldDef {
bool set_name(const char* name, upb::Status* s);
bool set_name(const std::string& name, upb::Status* s);
+ /* Sets the JSON name to the given string. */
+ /* TODO(haberman): implement. Right now only default json_name (camelCase)
+ * is supported. */
+ bool set_json_name(const char* json_name, upb::Status* s);
+ bool set_json_name(const std::string& name, upb::Status* s);
+
+ /* Clears the JSON name. This will make it revert to its default, which is
+ * a camelCased version of the regular field name. */
+ void clear_json_name();
+
void set_integer_format(IntegerFormat format);
bool set_tag_delimited(bool tag_delimited, upb::Status* s);
@@ -1754,6 +2213,7 @@ const char *upb_fielddef_name(const upb_fielddef *f);
bool upb_fielddef_isextension(const upb_fielddef *f);
bool upb_fielddef_lazy(const upb_fielddef *f);
bool upb_fielddef_packed(const upb_fielddef *f);
+size_t upb_fielddef_getjsonname(const upb_fielddef *f, char *buf, size_t len);
const upb_msgdef *upb_fielddef_containingtype(const upb_fielddef *f);
const upb_oneofdef *upb_fielddef_containingoneof(const upb_fielddef *f);
upb_msgdef *upb_fielddef_containingtype_mutable(upb_fielddef *f);
@@ -1766,6 +2226,7 @@ bool upb_fielddef_isstring(const upb_fielddef *f);
bool upb_fielddef_isseq(const upb_fielddef *f);
bool upb_fielddef_isprimitive(const upb_fielddef *f);
bool upb_fielddef_ismap(const upb_fielddef *f);
+bool upb_fielddef_haspresence(const upb_fielddef *f);
int64_t upb_fielddef_defaultint64(const upb_fielddef *f);
int32_t upb_fielddef_defaultint32(const upb_fielddef *f);
uint64_t upb_fielddef_defaultuint64(const upb_fielddef *f);
@@ -1787,6 +2248,8 @@ void upb_fielddef_setdescriptortype(upb_fielddef *f, int type);
void upb_fielddef_setlabel(upb_fielddef *f, upb_label_t label);
bool upb_fielddef_setnumber(upb_fielddef *f, uint32_t number, upb_status *s);
bool upb_fielddef_setname(upb_fielddef *f, const char *name, upb_status *s);
+bool upb_fielddef_setjsonname(upb_fielddef *f, const char *name, upb_status *s);
+bool upb_fielddef_clearjsonname(upb_fielddef *f);
bool upb_fielddef_setcontainingtypename(upb_fielddef *f, const char *name,
upb_status *s);
void upb_fielddef_setisextension(upb_fielddef *f, bool is_extension);
@@ -1827,6 +2290,10 @@ UPB_END_EXTERN_C
typedef upb_inttable_iter upb_msg_field_iter;
typedef upb_strtable_iter upb_msg_oneof_iter;
+/* Well-known field tag numbers for map-entry messages. */
+#define UPB_MAPENTRY_KEY 1
+#define UPB_MAPENTRY_VALUE 2
+
#ifdef __cplusplus
/* Structure that describes a single .proto message type.
@@ -1842,6 +2309,7 @@ class upb::MessageDef {
/* Functionality from upb::Def. */
const char* full_name() const;
+ const char* name() const;
bool set_full_name(const char* fullname, Status* s);
bool set_full_name(const std::string& fullname, Status* s);
@@ -1884,6 +2352,16 @@ class upb::MessageDef {
bool AddOneof(OneofDef* o, Status* s);
bool AddOneof(const reffed_ptr<OneofDef>& o, Status* s);
+ upb_syntax_t syntax() const;
+
+ /* Returns false if we don't support this syntax value. */
+ bool set_syntax(upb_syntax_t syntax);
+
+ /* Set this to false to indicate that primitive fields should not have
+ * explicit presence information associated with them. This will affect all
+ * fields added to this message. Defaults to true. */
+ void SetPrimitivesHavePresence(bool have_presence);
+
/* These return NULL if the field is not found. */
FieldDef* FindFieldByNumber(uint32_t number);
FieldDef* FindFieldByName(const char *name, size_t len);
@@ -2069,14 +2547,20 @@ UPB_REFCOUNTED_CMETHODS(upb_msgdef, upb_msgdef_upcast2)
bool upb_msgdef_freeze(upb_msgdef *m, upb_status *status);
+upb_msgdef *upb_msgdef_dup(const upb_msgdef *m, const void *owner);
const char *upb_msgdef_fullname(const upb_msgdef *m);
-bool upb_msgdef_setfullname(upb_msgdef *m, const char *fullname, upb_status *s);
+const char *upb_msgdef_name(const upb_msgdef *m);
+int upb_msgdef_numoneofs(const upb_msgdef *m);
+upb_syntax_t upb_msgdef_syntax(const upb_msgdef *m);
-upb_msgdef *upb_msgdef_dup(const upb_msgdef *m, const void *owner);
bool upb_msgdef_addfield(upb_msgdef *m, upb_fielddef *f, const void *ref_donor,
upb_status *s);
bool upb_msgdef_addoneof(upb_msgdef *m, upb_oneofdef *o, const void *ref_donor,
upb_status *s);
+bool upb_msgdef_setfullname(upb_msgdef *m, const char *fullname, upb_status *s);
+void upb_msgdef_setmapentry(upb_msgdef *m, bool map_entry);
+bool upb_msgdef_mapentry(const upb_msgdef *m);
+bool upb_msgdef_setsyntax(upb_msgdef *m, upb_syntax_t syntax);
/* Field lookup in a couple of different variations:
* - itof = int to field
@@ -2118,18 +2602,21 @@ UPB_INLINE upb_oneofdef *upb_msgdef_ntoo_mutable(upb_msgdef *m,
return (upb_oneofdef *)upb_msgdef_ntoo(m, name, len);
}
-void upb_msgdef_setmapentry(upb_msgdef *m, bool map_entry);
-bool upb_msgdef_mapentry(const upb_msgdef *m);
-
-/* Well-known field tag numbers for map-entry messages. */
-#define UPB_MAPENTRY_KEY 1
-#define UPB_MAPENTRY_VALUE 2
+/* Lookup of either field or oneof by name. Returns whether either was found.
+ * If the return is true, then the found def will be set, and the non-found
+ * one set to NULL. */
+bool upb_msgdef_lookupname(const upb_msgdef *m, const char *name, size_t len,
+ const upb_fielddef **f, const upb_oneofdef **o);
-const upb_oneofdef *upb_msgdef_findoneof(const upb_msgdef *m,
- const char *name);
-int upb_msgdef_numoneofs(const upb_msgdef *m);
+UPB_INLINE bool upb_msgdef_lookupnamez(const upb_msgdef *m, const char *name,
+ const upb_fielddef **f,
+ const upb_oneofdef **o) {
+ return upb_msgdef_lookupname(m, name, strlen(name), f, o);
+}
-/* upb_msg_field_iter i;
+/* Iteration over fields and oneofs. For example:
+ *
+ * upb_msg_field_iter i;
* for(upb_msg_field_begin(&i, m);
* !upb_msg_field_done(&i);
* upb_msg_field_next(&i)) {
@@ -2175,6 +2662,7 @@ class upb::EnumDef {
/* Functionality from upb::Def. */
const char* full_name() const;
+ const char* name() const;
bool set_full_name(const char* fullname, Status* s);
bool set_full_name(const std::string& fullname, Status* s);
@@ -2249,6 +2737,7 @@ bool upb_enumdef_freeze(upb_enumdef *e, upb_status *status);
/* From upb_def. */
const char *upb_enumdef_fullname(const upb_enumdef *e);
+const char *upb_enumdef_name(const upb_enumdef *e);
bool upb_enumdef_setfullname(upb_enumdef *e, const char *fullname,
upb_status *s);
@@ -2290,8 +2779,7 @@ typedef upb_inttable_iter upb_oneof_iter;
#ifdef __cplusplus
-/* Class that represents a oneof. Its base class is upb::Def (convert with
- * upb::upcast()). */
+/* Class that represents a oneof. */
class upb::OneofDef {
public:
/* Returns NULL if memory allocation failed. */
@@ -2300,9 +2788,6 @@ class upb::OneofDef {
/* upb::RefCounted methods like Ref()/Unref(). */
UPB_REFCOUNTED_CPPMETHODS
- /* Functionality from upb::Def. */
- const char* full_name() const;
-
/* Returns the MessageDef that owns this OneofDef. */
const MessageDef* containing_type() const;
@@ -2310,6 +2795,7 @@ class upb::OneofDef {
* by name once added to a message def. */
const char* name() const;
bool set_name(const char* name, Status* s);
+ bool set_name(const std::string& name, Status* s);
/* Returns the number of fields currently defined in the oneof. */
int field_count() const;
@@ -2403,7 +2889,7 @@ upb_oneofdef *upb_oneofdef_new(const void *owner);
upb_oneofdef *upb_oneofdef_dup(const upb_oneofdef *o, const void *owner);
/* Include upb_refcounted methods like upb_oneofdef_ref(). */
-UPB_REFCOUNTED_CMETHODS(upb_oneofdef, upb_oneofdef_upcast2)
+UPB_REFCOUNTED_CMETHODS(upb_oneofdef, upb_oneofdef_upcast)
const char *upb_oneofdef_name(const upb_oneofdef *o);
bool upb_oneofdef_setname(upb_oneofdef *o, const char *name, upb_status *s);
@@ -2439,6 +2925,120 @@ void upb_oneof_iter_setdone(upb_oneof_iter *iter);
UPB_END_EXTERN_C
+
+/* upb::FileDef ***************************************************************/
+
+#ifdef __cplusplus
+
+/* Class that represents a .proto file with some things defined in it.
+ *
+ * Many users won't care about FileDefs, but they are necessary if you want to
+ * read the values of file-level options. */
+class upb::FileDef {
+ public:
+ /* Returns NULL if memory allocation failed. */
+ static reffed_ptr<FileDef> New();
+
+ /* upb::RefCounted methods like Ref()/Unref(). */
+ UPB_REFCOUNTED_CPPMETHODS
+
+ /* Get/set name of the file (eg. "foo/bar.proto"). */
+ const char* name() const;
+ bool set_name(const char* name, Status* s);
+ bool set_name(const std::string& name, Status* s);
+
+ /* Package name for definitions inside the file (eg. "foo.bar"). */
+ const char* package() const;
+ bool set_package(const char* package, Status* s);
+
+ /* Syntax for the file. Defaults to proto2. */
+ upb_syntax_t syntax() const;
+ void set_syntax(upb_syntax_t syntax);
+
+ /* Get the list of defs from the file. These are returned in the order that
+ * they were added to the FileDef. */
+ int def_count() const;
+ const Def* def(int index) const;
+ Def* def(int index);
+
+ /* Get the list of dependencies from the file. These are returned in the
+ * order that they were added to the FileDef. */
+ int dependency_count() const;
+ const FileDef* dependency(int index) const;
+
+ /* Adds defs to this file. The def must not already belong to another
+ * file.
+ *
+ * Note: this does *not* ensure that this def's name is unique in this file!
+ * Use a SymbolTable if you want to check this property. Especially since
+ * properly checking uniqueness would require a check across *all* files
+ * (including dependencies). */
+ bool AddDef(Def* def, Status* s);
+ bool AddMessage(MessageDef* m, Status* s);
+ bool AddEnum(EnumDef* e, Status* s);
+ bool AddExtension(FieldDef* f, Status* s);
+
+ /* Adds a dependency of this file. */
+ bool AddDependency(const FileDef* file);
+
+ /* Freezes this FileDef and all messages/enums under it. All subdefs must be
+ * resolved and all messages/enums must validate. Returns true if this
+ * succeeded.
+ *
+ * TODO(haberman): should we care whether the file's dependencies are frozen
+ * already? */
+ bool Freeze(Status* s);
+
+ private:
+ UPB_DISALLOW_POD_OPS(FileDef, upb::FileDef)
+};
+
+#endif
+
+UPB_BEGIN_EXTERN_C
+
+upb_filedef *upb_filedef_new(const void *owner);
+
+/* Include upb_refcounted methods like upb_msgdef_ref(). */
+UPB_REFCOUNTED_CMETHODS(upb_filedef, upb_filedef_upcast)
+
+const char *upb_filedef_name(const upb_filedef *f);
+const char *upb_filedef_package(const upb_filedef *f);
+upb_syntax_t upb_filedef_syntax(const upb_filedef *f);
+size_t upb_filedef_defcount(const upb_filedef *f);
+size_t upb_filedef_depcount(const upb_filedef *f);
+const upb_def *upb_filedef_def(const upb_filedef *f, size_t i);
+const upb_filedef *upb_filedef_dep(const upb_filedef *f, size_t i);
+
+bool upb_filedef_freeze(upb_filedef *f, upb_status *s);
+bool upb_filedef_setname(upb_filedef *f, const char *name, upb_status *s);
+bool upb_filedef_setpackage(upb_filedef *f, const char *package, upb_status *s);
+bool upb_filedef_setsyntax(upb_filedef *f, upb_syntax_t syntax, upb_status *s);
+
+bool upb_filedef_adddef(upb_filedef *f, upb_def *def, const void *ref_donor,
+ upb_status *s);
+bool upb_filedef_adddep(upb_filedef *f, const upb_filedef *dep);
+
+UPB_INLINE bool upb_filedef_addmsg(upb_filedef *f, upb_msgdef *m,
+ const void *ref_donor, upb_status *s) {
+ return upb_filedef_adddef(f, upb_msgdef_upcast_mutable(m), ref_donor, s);
+}
+
+UPB_INLINE bool upb_filedef_addenum(upb_filedef *f, upb_enumdef *e,
+ const void *ref_donor, upb_status *s) {
+ return upb_filedef_adddef(f, upb_enumdef_upcast_mutable(e), ref_donor, s);
+}
+
+UPB_INLINE bool upb_filedef_addext(upb_filedef *file, upb_fielddef *f,
+ const void *ref_donor, upb_status *s) {
+ return upb_filedef_adddef(file, upb_fielddef_upcast_mutable(f), ref_donor, s);
+}
+UPB_INLINE upb_def *upb_filedef_mutabledef(upb_filedef *f, int i) {
+ return (upb_def*)upb_filedef_def(f, i);
+}
+
+UPB_END_EXTERN_C
+
#ifdef __cplusplus
UPB_INLINE const char* upb_safecstr(const std::string& str) {
@@ -2454,13 +3054,14 @@ inline Def* Def::Dup(const void* owner) const {
}
inline Def::Type Def::def_type() const { return upb_def_type(this); }
inline const char* Def::full_name() const { return upb_def_fullname(this); }
+inline const char* Def::name() const { return upb_def_name(this); }
inline bool Def::set_full_name(const char* fullname, Status* s) {
return upb_def_setfullname(this, fullname, s);
}
inline bool Def::set_full_name(const std::string& fullname, Status* s) {
return upb_def_setfullname(this, upb_safecstr(fullname), s);
}
-inline bool Def::Freeze(Def* const* defs, int n, Status* status) {
+inline bool Def::Freeze(Def* const* defs, size_t n, Status* status) {
return upb_def_freeze(defs, n, status);
}
inline bool Def::Freeze(const std::vector<Def*>& defs, Status* status) {
@@ -2527,6 +3128,9 @@ inline const char* FieldDef::name() const { return upb_fielddef_name(this); }
inline bool FieldDef::is_extension() const {
return upb_fielddef_isextension(this);
}
+inline size_t FieldDef::GetJsonName(char* buf, size_t len) const {
+ return upb_fielddef_getjsonname(this, buf, len);
+}
inline bool FieldDef::lazy() const {
return upb_fielddef_lazy(this);
}
@@ -2536,6 +3140,9 @@ inline void FieldDef::set_lazy(bool lazy) {
inline bool FieldDef::packed() const {
return upb_fielddef_packed(this);
}
+inline uint32_t FieldDef::index() const {
+ return upb_fielddef_index(this);
+}
inline void FieldDef::set_packed(bool packed) {
upb_fielddef_setpacked(this, packed);
}
@@ -2557,6 +3164,15 @@ inline bool FieldDef::set_name(const char *name, Status* s) {
inline bool FieldDef::set_name(const std::string& name, Status* s) {
return upb_fielddef_setname(this, upb_safecstr(name), s);
}
+inline bool FieldDef::set_json_name(const char *name, Status* s) {
+ return upb_fielddef_setjsonname(this, name, s);
+}
+inline bool FieldDef::set_json_name(const std::string& name, Status* s) {
+ return upb_fielddef_setjsonname(this, upb_safecstr(name), s);
+}
+inline void FieldDef::clear_json_name() {
+ upb_fielddef_clearjsonname(this);
+}
inline bool FieldDef::set_containing_type_name(const char *name, Status* s) {
return upb_fielddef_setcontainingtypename(this, name, s);
}
@@ -2671,12 +3287,21 @@ inline reffed_ptr<MessageDef> MessageDef::New() {
inline const char *MessageDef::full_name() const {
return upb_msgdef_fullname(this);
}
+inline const char *MessageDef::name() const {
+ return upb_msgdef_name(this);
+}
+inline upb_syntax_t MessageDef::syntax() const {
+ return upb_msgdef_syntax(this);
+}
inline bool MessageDef::set_full_name(const char* fullname, Status* s) {
return upb_msgdef_setfullname(this, fullname, s);
}
inline bool MessageDef::set_full_name(const std::string& fullname, Status* s) {
return upb_msgdef_setfullname(this, upb_safecstr(fullname), s);
}
+inline bool MessageDef::set_syntax(upb_syntax_t syntax) {
+ return upb_msgdef_setsyntax(this, syntax);
+}
inline bool MessageDef::Freeze(Status* status) {
return upb_msgdef_freeze(this, status);
}
@@ -2858,6 +3483,9 @@ inline reffed_ptr<EnumDef> EnumDef::New() {
inline const char* EnumDef::full_name() const {
return upb_enumdef_fullname(this);
}
+inline const char* EnumDef::name() const {
+ return upb_enumdef_name(this);
+}
inline bool EnumDef::set_full_name(const char* fullname, Status* s) {
return upb_enumdef_setfullname(this, fullname, s);
}
@@ -2907,9 +3535,6 @@ inline reffed_ptr<OneofDef> OneofDef::New() {
upb_oneofdef *o = upb_oneofdef_new(&o);
return reffed_ptr<OneofDef>(o, &o);
}
-inline const char* OneofDef::full_name() const {
- return upb_oneofdef_name(this);
-}
inline const MessageDef* OneofDef::containing_type() const {
return upb_oneofdef_containingtype(this);
@@ -2920,6 +3545,9 @@ inline const char* OneofDef::name() const {
inline bool OneofDef::set_name(const char* name, Status* s) {
return upb_oneofdef_setname(this, name, s);
}
+inline bool OneofDef::set_name(const std::string& name, Status* s) {
+ return upb_oneofdef_setname(this, upb_safecstr(name), s);
+}
inline int OneofDef::field_count() const {
return upb_oneofdef_numfields(this);
}
@@ -2988,6 +3616,57 @@ inline bool OneofDef::const_iterator::operator!=(
return !(*this == other);
}
+inline reffed_ptr<FileDef> FileDef::New() {
+ upb_filedef *f = upb_filedef_new(&f);
+ return reffed_ptr<FileDef>(f, &f);
+}
+
+inline const char* FileDef::name() const {
+ return upb_filedef_name(this);
+}
+inline bool FileDef::set_name(const char* name, Status* s) {
+ return upb_filedef_setname(this, name, s);
+}
+inline bool FileDef::set_name(const std::string& name, Status* s) {
+ return upb_filedef_setname(this, upb_safecstr(name), s);
+}
+inline const char* FileDef::package() const {
+ return upb_filedef_package(this);
+}
+inline bool FileDef::set_package(const char* package, Status* s) {
+ return upb_filedef_setpackage(this, package, s);
+}
+inline int FileDef::def_count() const {
+ return upb_filedef_defcount(this);
+}
+inline const Def* FileDef::def(int index) const {
+ return upb_filedef_def(this, index);
+}
+inline Def* FileDef::def(int index) {
+ return const_cast<Def*>(upb_filedef_def(this, index));
+}
+inline int FileDef::dependency_count() const {
+ return upb_filedef_depcount(this);
+}
+inline const FileDef* FileDef::dependency(int index) const {
+ return upb_filedef_dep(this, index);
+}
+inline bool FileDef::AddDef(Def* def, Status* s) {
+ return upb_filedef_adddef(this, def, NULL, s);
+}
+inline bool FileDef::AddMessage(MessageDef* m, Status* s) {
+ return upb_filedef_addmsg(this, m, NULL, s);
+}
+inline bool FileDef::AddEnum(EnumDef* e, Status* s) {
+ return upb_filedef_addenum(this, e, NULL, s);
+}
+inline bool FileDef::AddExtension(FieldDef* f, Status* s) {
+ return upb_filedef_addext(this, f, NULL, s);
+}
+inline bool FileDef::AddDependency(const FileDef* file) {
+ return upb_filedef_adddep(this, file);
+}
+
} /* namespace upb */
#endif
@@ -3026,6 +3705,7 @@ struct upb_def {
upb_refcounted base;
const char *fullname;
+ const upb_filedef* file;
char type; /* A upb_deftype_t (char to save space) */
/* Used as a flag during the def's mutable stage. Must be false unless
@@ -3035,8 +3715,8 @@ struct upb_def {
bool came_from_user;
};
-#define UPB_DEF_INIT(name, type, refs, ref2s) \
- { UPB_REFCOUNT_INIT(refs, ref2s), name, type, false }
+#define UPB_DEF_INIT(name, type, vtbl, refs, ref2s) \
+ { UPB_REFCOUNT_INIT(vtbl, refs, ref2s), name, NULL, type, false }
/* upb_fielddef ***************************************************************/
@@ -3076,12 +3756,14 @@ struct upb_fielddef {
uint32_t index_;
};
+extern const struct upb_refcounted_vtbl upb_fielddef_vtbl;
+
#define UPB_FIELDDEF_INIT(label, type, intfmt, tagdelim, is_extension, lazy, \
packed, name, num, msgdef, subdef, selector_base, \
index, defaultval, refs, ref2s) \
{ \
- UPB_DEF_INIT(name, UPB_DEF_FIELD, refs, ref2s), defaultval, {msgdef}, \
- {subdef}, NULL, false, false, \
+ UPB_DEF_INIT(name, UPB_DEF_FIELD, &upb_fielddef_vtbl, refs, ref2s), \
+ defaultval, {msgdef}, {subdef}, NULL, false, false, \
type == UPB_TYPE_STRING || type == UPB_TYPE_BYTES, true, is_extension, \
lazy, packed, intfmt, tagdelim, type, label, num, selector_base, index \
}
@@ -3097,27 +3779,26 @@ struct upb_msgdef {
/* Tables for looking up fields by number and name. */
upb_inttable itof; /* int to field */
- upb_strtable ntof; /* name to field */
-
- /* Tables for looking up oneofs by name. */
- upb_strtable ntoo; /* name to oneof */
+ upb_strtable ntof; /* name to field/oneof */
- /* Is this a map-entry message?
- * TODO: set this flag properly for static descriptors; regenerate
- * descriptor.upb.c. */
+ /* Is this a map-entry message? */
bool map_entry;
+ /* Whether this message has proto2 or proto3 semantics. */
+ upb_syntax_t syntax;
+
/* TODO(haberman): proper extension ranges (there can be multiple). */
};
+extern const struct upb_refcounted_vtbl upb_msgdef_vtbl;
+
/* TODO: also support static initialization of the oneofs table. This will be
* needed if we compile in descriptors that contain oneofs. */
#define UPB_MSGDEF_INIT(name, selector_count, submsg_field_count, itof, ntof, \
- refs, ref2s) \
+ map_entry, syntax, refs, ref2s) \
{ \
- UPB_DEF_INIT(name, UPB_DEF_MSG, refs, ref2s), selector_count, \
- submsg_field_count, itof, ntof, \
- UPB_EMPTY_STRTABLE_INIT(UPB_CTYPE_PTR), false \
+ UPB_DEF_INIT(name, UPB_DEF_MSG, &upb_fielddef_vtbl, refs, ref2s), \
+ selector_count, submsg_field_count, itof, ntof, map_entry, syntax \
}
@@ -3131,22 +3812,28 @@ struct upb_enumdef {
int32_t defaultval;
};
+extern const struct upb_refcounted_vtbl upb_enumdef_vtbl;
+
#define UPB_ENUMDEF_INIT(name, ntoi, iton, defaultval, refs, ref2s) \
- { UPB_DEF_INIT(name, UPB_DEF_ENUM, refs, ref2s), ntoi, iton, defaultval }
+ { UPB_DEF_INIT(name, UPB_DEF_ENUM, &upb_enumdef_vtbl, refs, ref2s), ntoi, \
+ iton, defaultval }
/* upb_oneofdef ***************************************************************/
struct upb_oneofdef {
- upb_def base;
+ upb_refcounted base;
+ const char *name;
upb_strtable ntof;
upb_inttable itof;
const upb_msgdef *parent;
};
+extern const struct upb_refcounted_vtbl upb_oneofdef_vtbl;
+
#define UPB_ONEOFDEF_INIT(name, ntof, itof, refs, ref2s) \
- { UPB_DEF_INIT(name, UPB_DEF_ENUM, refs, ref2s), ntof, itof }
+ { UPB_REFCOUNT_INIT(&upb_oneofdef_vtbl, refs, ref2s), name, ntof, itof }
/* upb_symtab *****************************************************************/
@@ -3157,9 +3844,18 @@ struct upb_symtab {
upb_strtable symtab;
};
-#define UPB_SYMTAB_INIT(symtab, refs, ref2s) \
- { UPB_REFCOUNT_INIT(refs, ref2s), symtab }
+struct upb_filedef {
+ upb_refcounted base;
+ const char *name;
+ const char *package;
+ upb_syntax_t syntax;
+
+ upb_inttable defs;
+ upb_inttable deps;
+};
+
+extern const struct upb_refcounted_vtbl upb_filedef_vtbl;
#endif /* UPB_STATICINIT_H_ */
/*
@@ -5102,267 +5798,6 @@ inline BytesHandler::~BytesHandler() {}
#endif /* UPB_HANDLERS_H */
/*
-** upb::Environment (upb_env)
-**
-** A upb::Environment provides a means for injecting malloc and an
-** error-reporting callback into encoders/decoders. This allows them to be
-** independent of nearly all assumptions about their actual environment.
-**
-** It is also a container for allocating the encoders/decoders themselves that
-** insulates clients from knowing their actual size. This provides ABI
-** compatibility even if the size of the objects change. And this allows the
-** structure definitions to be in the .c files instead of the .h files, making
-** the .h files smaller and more readable.
-*/
-
-
-#ifndef UPB_ENV_H_
-#define UPB_ENV_H_
-
-#ifdef __cplusplus
-namespace upb {
-class Environment;
-class SeededAllocator;
-}
-#endif
-
-UPB_DECLARE_TYPE(upb::Environment, upb_env)
-UPB_DECLARE_TYPE(upb::SeededAllocator, upb_seededalloc)
-
-typedef void *upb_alloc_func(void *ud, void *ptr, size_t oldsize, size_t size);
-typedef void upb_cleanup_func(void *ud);
-typedef bool upb_error_func(void *ud, const upb_status *status);
-
-#ifdef __cplusplus
-
-/* An environment is *not* thread-safe. */
-class upb::Environment {
- public:
- Environment();
- ~Environment();
-
- /* Set a custom memory allocation function for the environment. May ONLY
- * be called before any calls to Malloc()/Realloc()/AddCleanup() below.
- * If this is not called, the system realloc() function will be used.
- * The given user pointer "ud" will be passed to the allocation function.
- *
- * The allocation function will not receive corresponding "free" calls. it
- * must ensure that the memory is valid for the lifetime of the Environment,
- * but it may be reclaimed any time thereafter. The likely usage is that
- * "ud" points to a stateful allocator, and that the allocator frees all
- * memory, arena-style, when it is destroyed. In this case the allocator must
- * outlive the Environment. Another possibility is that the allocation
- * function returns GC-able memory that is guaranteed to be GC-rooted for the
- * life of the Environment. */
- void SetAllocationFunction(upb_alloc_func* alloc, void* ud);
-
- template<class T>
- void SetAllocator(T* allocator) {
- SetAllocationFunction(allocator->GetAllocationFunction(), allocator);
- }
-
- /* Set a custom error reporting function. */
- void SetErrorFunction(upb_error_func* func, void* ud);
-
- /* Set the error reporting function to simply copy the status to the given
- * status and abort. */
- void ReportErrorsTo(Status* status);
-
- /* Returns true if all allocations and AddCleanup() calls have succeeded,
- * and no errors were reported with ReportError() (except ones that recovered
- * successfully). */
- bool ok() const;
-
- /* Functions for use by encoders/decoders. **********************************/
-
- /* Reports an error to this environment's callback, returning true if
- * the caller should try to recover. */
- bool ReportError(const Status* status);
-
- /* Allocate memory. Uses the environment's allocation function.
- *
- * There is no need to free(). All memory will be freed automatically, but is
- * guaranteed to outlive the Environment. */
- void* Malloc(size_t size);
-
- /* Reallocate memory. Preserves "oldsize" bytes from the existing buffer
- * Requires: oldsize <= existing_size.
- *
- * TODO(haberman): should we also enforce that oldsize <= size? */
- void* Realloc(void* ptr, size_t oldsize, size_t size);
-
- /* Add a cleanup function to run when the environment is destroyed.
- * Returns false on out-of-memory.
- *
- * The first call to AddCleanup() after SetAllocationFunction() is guaranteed
- * to return true -- this makes it possible to robustly set a cleanup handler
- * for a custom allocation function. */
- bool AddCleanup(upb_cleanup_func* func, void* ud);
-
- /* Total number of bytes that have been allocated. It is undefined what
- * Realloc() does to this counter. */
- size_t BytesAllocated() const;
-
- private:
- UPB_DISALLOW_COPY_AND_ASSIGN(Environment)
-
-#else
-struct upb_env {
-#endif /* __cplusplus */
-
- bool ok_;
- size_t bytes_allocated;
-
- /* Alloc function. */
- upb_alloc_func *alloc;
- void *alloc_ud;
-
- /* Error-reporting function. */
- upb_error_func *err;
- void *err_ud;
-
- /* Userdata for default alloc func. */
- void *default_alloc_ud;
-
- /* Cleanup entries. Pointer to a cleanup_ent, defined in env.c */
- void *cleanup_head;
-
- /* For future expansion, since the size of this struct is exposed to users. */
- void *future1;
- void *future2;
-};
-
-UPB_BEGIN_EXTERN_C
-
-void upb_env_init(upb_env *e);
-void upb_env_uninit(upb_env *e);
-void upb_env_setallocfunc(upb_env *e, upb_alloc_func *func, void *ud);
-void upb_env_seterrorfunc(upb_env *e, upb_error_func *func, void *ud);
-void upb_env_reporterrorsto(upb_env *e, upb_status *status);
-bool upb_env_ok(const upb_env *e);
-bool upb_env_reporterror(upb_env *e, const upb_status *status);
-void *upb_env_malloc(upb_env *e, size_t size);
-void *upb_env_realloc(upb_env *e, void *ptr, size_t oldsize, size_t size);
-bool upb_env_addcleanup(upb_env *e, upb_cleanup_func *func, void *ud);
-size_t upb_env_bytesallocated(const upb_env *e);
-
-UPB_END_EXTERN_C
-
-#ifdef __cplusplus
-
-/* An allocator that allocates from an initial memory region (likely the stack)
- * before falling back to another allocator. */
-class upb::SeededAllocator {
- public:
- SeededAllocator(void *mem, size_t len);
- ~SeededAllocator();
-
- /* Set a custom fallback memory allocation function for the allocator, to use
- * once the initial region runs out.
- *
- * May ONLY be called before GetAllocationFunction(). If this is not
- * called, the system realloc() will be the fallback allocator. */
- void SetFallbackAllocator(upb_alloc_func *alloc, void *ud);
-
- /* Gets the allocation function for this allocator. */
- upb_alloc_func* GetAllocationFunction();
-
- private:
- UPB_DISALLOW_COPY_AND_ASSIGN(SeededAllocator)
-
-#else
-struct upb_seededalloc {
-#endif /* __cplusplus */
-
- /* Fallback alloc function. */
- upb_alloc_func *alloc;
- upb_cleanup_func *alloc_cleanup;
- void *alloc_ud;
- bool need_cleanup;
- bool returned_allocfunc;
-
- /* Userdata for default alloc func. */
- void *default_alloc_ud;
-
- /* Pointers for the initial memory region. */
- char *mem_base;
- char *mem_ptr;
- char *mem_limit;
-
- /* For future expansion, since the size of this struct is exposed to users. */
- void *future1;
- void *future2;
-};
-
-UPB_BEGIN_EXTERN_C
-
-void upb_seededalloc_init(upb_seededalloc *a, void *mem, size_t len);
-void upb_seededalloc_uninit(upb_seededalloc *a);
-void upb_seededalloc_setfallbackalloc(upb_seededalloc *a, upb_alloc_func *func,
- void *ud);
-upb_alloc_func *upb_seededalloc_getallocfunc(upb_seededalloc *a);
-
-UPB_END_EXTERN_C
-
-#ifdef __cplusplus
-
-namespace upb {
-
-inline Environment::Environment() {
- upb_env_init(this);
-}
-inline Environment::~Environment() {
- upb_env_uninit(this);
-}
-inline void Environment::SetAllocationFunction(upb_alloc_func *alloc,
- void *ud) {
- upb_env_setallocfunc(this, alloc, ud);
-}
-inline void Environment::SetErrorFunction(upb_error_func *func, void *ud) {
- upb_env_seterrorfunc(this, func, ud);
-}
-inline void Environment::ReportErrorsTo(Status* status) {
- upb_env_reporterrorsto(this, status);
-}
-inline bool Environment::ok() const {
- return upb_env_ok(this);
-}
-inline bool Environment::ReportError(const Status* status) {
- return upb_env_reporterror(this, status);
-}
-inline void *Environment::Malloc(size_t size) {
- return upb_env_malloc(this, size);
-}
-inline void *Environment::Realloc(void *ptr, size_t oldsize, size_t size) {
- return upb_env_realloc(this, ptr, oldsize, size);
-}
-inline bool Environment::AddCleanup(upb_cleanup_func *func, void *ud) {
- return upb_env_addcleanup(this, func, ud);
-}
-inline size_t Environment::BytesAllocated() const {
- return upb_env_bytesallocated(this);
-}
-
-inline SeededAllocator::SeededAllocator(void *mem, size_t len) {
- upb_seededalloc_init(this, mem, len);
-}
-inline SeededAllocator::~SeededAllocator() {
- upb_seededalloc_uninit(this);
-}
-inline void SeededAllocator::SetFallbackAllocator(upb_alloc_func *alloc,
- void *ud) {
- upb_seededalloc_setfallbackalloc(this, alloc, ud);
-}
-inline upb_alloc_func *SeededAllocator::GetAllocationFunction() {
- return upb_seededalloc_getallocfunc(this);
-}
-
-} /* namespace upb */
-
-#endif /* __cplusplus */
-
-#endif /* UPB_ENV_H_ */
-/*
** upb::Sink (upb_sink)
** upb::BytesSink (upb_bytessink)
**
@@ -6066,12 +6501,17 @@ class upb::SymbolTable {
* only a few messages are changing. We may want to add a way of adding a
* tree of frozen defs to the symtab (perhaps an alternate constructor where
* you pass the root of the tree?) */
- bool Add(Def*const* defs, int n, void* ref_donor, upb_status* status);
+ bool Add(Def*const* defs, size_t n, void* ref_donor, Status* status);
bool Add(const std::vector<Def*>& defs, void *owner, Status* status) {
return Add((Def*const*)&defs[0], defs.size(), owner, status);
}
+ /* Resolves all subdefs for messages in this file and attempts to freeze the
+ * file. If this succeeds, adds all the symbols to this SymbolTable
+ * (replacing any existing ones with the same names). */
+ bool AddFile(FileDef* file, Status* s);
+
private:
UPB_DISALLOW_POD_OPS(SymbolTable, upb::SymbolTable)
};
@@ -6092,8 +6532,9 @@ const upb_def *upb_symtab_resolve(const upb_symtab *s, const char *base,
const upb_def *upb_symtab_lookup(const upb_symtab *s, const char *sym);
const upb_msgdef *upb_symtab_lookupmsg(const upb_symtab *s, const char *sym);
const upb_enumdef *upb_symtab_lookupenum(const upb_symtab *s, const char *sym);
-bool upb_symtab_add(upb_symtab *s, upb_def *const*defs, int n, void *ref_donor,
- upb_status *status);
+bool upb_symtab_add(upb_symtab *s, upb_def *const*defs, size_t n,
+ void *ref_donor, upb_status *status);
+bool upb_symtab_addfile(upb_symtab *s, upb_filedef *file, upb_status* status);
/* upb_symtab_iter i;
* for(upb_symtab_begin(&i, s, type); !upb_symtab_done(&i);
@@ -6135,9 +6576,12 @@ inline const MessageDef *SymbolTable::LookupMessage(const char *sym) const {
return upb_symtab_lookupmsg(this, sym);
}
inline bool SymbolTable::Add(
- Def*const* defs, int n, void* ref_donor, upb_status* status) {
+ Def*const* defs, size_t n, void* ref_donor, Status* status) {
return upb_symtab_add(this, (upb_def*const*)defs, n, ref_donor, status);
}
+inline bool SymbolTable::AddFile(FileDef* file, Status* s) {
+ return upb_symtab_addfile(this, file, s);
+}
} /* namespace upb */
#endif
@@ -6181,14 +6625,9 @@ class upb::descriptor::Reader {
/* The reader's input; this is where descriptor.proto data should be sent. */
Sink* input();
- /* Returns an array of all defs that have been parsed, and transfers ownership
- * of them to "owner". The number of defs is stored in *n. Ownership of the
- * returned array is retained and is invalidated by any other call into
- * Reader.
- *
- * These defs are not frozen or resolved; they are ready to be added to a
- * symtab. */
- upb::Def** GetDefs(void* owner, int* n);
+ /* Use to get the FileDefs that have been parsed. */
+ size_t file_count() const;
+ FileDef* file(size_t i) const;
/* Builds and returns handlers for the reader, owned by "owner." */
static Handlers* NewHandlers(const void* owner);
@@ -6204,7 +6643,8 @@ UPB_BEGIN_EXTERN_C
/* C API. */
upb_descreader *upb_descreader_create(upb_env *e, const upb_handlers *h);
upb_sink *upb_descreader_input(upb_descreader *r);
-upb_def **upb_descreader_getdefs(upb_descreader *r, void *owner, int *n);
+size_t upb_descreader_filecount(const upb_descreader *r);
+upb_filedef *upb_descreader_file(const upb_descreader *r, size_t i);
const upb_handlers *upb_descreader_newhandlers(const void *owner);
UPB_END_EXTERN_C
@@ -6217,8 +6657,11 @@ inline Reader* Reader::Create(Environment* e, const Handlers *h) {
return upb_descreader_create(e, h);
}
inline Sink* Reader::input() { return upb_descreader_input(this); }
-inline upb::Def** Reader::GetDefs(void* owner, int* n) {
- return upb_descreader_getdefs(this, owner, n);
+inline size_t Reader::file_count() const {
+ return upb_descreader_filecount(this);
+}
+inline FileDef* Reader::file(size_t i) const {
+ return upb_descreader_file(this, i);
}
} /* namespace descriptor */
} /* namespace upb */
@@ -6231,519 +6674,290 @@ inline upb::Def** Reader::GetDefs(void* owner, int* n) {
* actually storing protobufs. It only contains *defs* which
* let you reflect over a protobuf *schema*.
*/
-/* This file was generated by upbc (the upb compiler).
+/* This file was generated by upbc (the upb compiler) from the input
+ * file:
+ *
+ * upb/descriptor/descriptor.proto
+ *
* Do not edit -- your changes will be discarded when the file is
* regenerated. */
-#ifndef GOOGLE_PROTOBUF_DESCRIPTOR_UPB_H_
-#define GOOGLE_PROTOBUF_DESCRIPTOR_UPB_H_
+#ifndef UPB_DESCRIPTOR_DESCRIPTOR_PROTO_UPB_H_
+#define UPB_DESCRIPTOR_DESCRIPTOR_PROTO_UPB_H_
-#ifdef __cplusplus
UPB_BEGIN_EXTERN_C
-#endif
/* Enums */
typedef enum {
- GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_LABEL_OPTIONAL = 1,
- GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_LABEL_REQUIRED = 2,
- GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_LABEL_REPEATED = 3
+ google_protobuf_FieldDescriptorProto_LABEL_OPTIONAL = 1,
+ google_protobuf_FieldDescriptorProto_LABEL_REQUIRED = 2,
+ google_protobuf_FieldDescriptorProto_LABEL_REPEATED = 3
} google_protobuf_FieldDescriptorProto_Label;
typedef enum {
- GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_DOUBLE = 1,
- GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_FLOAT = 2,
- GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_INT64 = 3,
- GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_UINT64 = 4,
- GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_INT32 = 5,
- GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_FIXED64 = 6,
- GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_FIXED32 = 7,
- GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_BOOL = 8,
- GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_STRING = 9,
- GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_GROUP = 10,
- GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_MESSAGE = 11,
- GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_BYTES = 12,
- GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_UINT32 = 13,
- GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_ENUM = 14,
- GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_SFIXED32 = 15,
- GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_SFIXED64 = 16,
- GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_SINT32 = 17,
- GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_SINT64 = 18
+ google_protobuf_FieldDescriptorProto_TYPE_DOUBLE = 1,
+ google_protobuf_FieldDescriptorProto_TYPE_FLOAT = 2,
+ google_protobuf_FieldDescriptorProto_TYPE_INT64 = 3,
+ google_protobuf_FieldDescriptorProto_TYPE_UINT64 = 4,
+ google_protobuf_FieldDescriptorProto_TYPE_INT32 = 5,
+ google_protobuf_FieldDescriptorProto_TYPE_FIXED64 = 6,
+ google_protobuf_FieldDescriptorProto_TYPE_FIXED32 = 7,
+ google_protobuf_FieldDescriptorProto_TYPE_BOOL = 8,
+ google_protobuf_FieldDescriptorProto_TYPE_STRING = 9,
+ google_protobuf_FieldDescriptorProto_TYPE_GROUP = 10,
+ google_protobuf_FieldDescriptorProto_TYPE_MESSAGE = 11,
+ google_protobuf_FieldDescriptorProto_TYPE_BYTES = 12,
+ google_protobuf_FieldDescriptorProto_TYPE_UINT32 = 13,
+ google_protobuf_FieldDescriptorProto_TYPE_ENUM = 14,
+ google_protobuf_FieldDescriptorProto_TYPE_SFIXED32 = 15,
+ google_protobuf_FieldDescriptorProto_TYPE_SFIXED64 = 16,
+ google_protobuf_FieldDescriptorProto_TYPE_SINT32 = 17,
+ google_protobuf_FieldDescriptorProto_TYPE_SINT64 = 18
} google_protobuf_FieldDescriptorProto_Type;
typedef enum {
- GOOGLE_PROTOBUF_FIELDOPTIONS_STRING = 0,
- GOOGLE_PROTOBUF_FIELDOPTIONS_CORD = 1,
- GOOGLE_PROTOBUF_FIELDOPTIONS_STRING_PIECE = 2
+ google_protobuf_FieldOptions_STRING = 0,
+ google_protobuf_FieldOptions_CORD = 1,
+ google_protobuf_FieldOptions_STRING_PIECE = 2
} google_protobuf_FieldOptions_CType;
typedef enum {
- GOOGLE_PROTOBUF_FILEOPTIONS_SPEED = 1,
- GOOGLE_PROTOBUF_FILEOPTIONS_CODE_SIZE = 2,
- GOOGLE_PROTOBUF_FILEOPTIONS_LITE_RUNTIME = 3
+ google_protobuf_FieldOptions_JS_NORMAL = 0,
+ google_protobuf_FieldOptions_JS_STRING = 1,
+ google_protobuf_FieldOptions_JS_NUMBER = 2
+} google_protobuf_FieldOptions_JSType;
+
+typedef enum {
+ google_protobuf_FileOptions_SPEED = 1,
+ google_protobuf_FileOptions_CODE_SIZE = 2,
+ google_protobuf_FileOptions_LITE_RUNTIME = 3
} google_protobuf_FileOptions_OptimizeMode;
-/* Selectors */
-
-/* google.protobuf.DescriptorProto */
-#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_FIELD_STARTSUBMSG 2
-#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_NESTED_TYPE_STARTSUBMSG 3
-#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_ENUM_TYPE_STARTSUBMSG 4
-#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSION_RANGE_STARTSUBMSG 5
-#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSION_STARTSUBMSG 6
-#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_OPTIONS_STARTSUBMSG 7
-#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_FIELD_STARTSEQ 8
-#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_FIELD_ENDSEQ 9
-#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_FIELD_ENDSUBMSG 10
-#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_NESTED_TYPE_STARTSEQ 11
-#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_NESTED_TYPE_ENDSEQ 12
-#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_NESTED_TYPE_ENDSUBMSG 13
-#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_ENUM_TYPE_STARTSEQ 14
-#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_ENUM_TYPE_ENDSEQ 15
-#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_ENUM_TYPE_ENDSUBMSG 16
-#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSION_RANGE_STARTSEQ 17
-#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSION_RANGE_ENDSEQ 18
-#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSION_RANGE_ENDSUBMSG 19
-#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSION_STARTSEQ 20
-#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSION_ENDSEQ 21
-#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSION_ENDSUBMSG 22
-#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_OPTIONS_ENDSUBMSG 23
-#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_NAME_STRING 24
-#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_NAME_STARTSTR 25
-#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_NAME_ENDSTR 26
-
-/* google.protobuf.DescriptorProto.ExtensionRange */
-#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSIONRANGE_START_INT32 2
-#define SEL_GOOGLE_PROTOBUF_DESCRIPTORPROTO_EXTENSIONRANGE_END_INT32 3
-
-/* google.protobuf.EnumDescriptorProto */
-#define SEL_GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_VALUE_STARTSUBMSG 2
-#define SEL_GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_OPTIONS_STARTSUBMSG 3
-#define SEL_GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_VALUE_STARTSEQ 4
-#define SEL_GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_VALUE_ENDSEQ 5
-#define SEL_GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_VALUE_ENDSUBMSG 6
-#define SEL_GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_OPTIONS_ENDSUBMSG 7
-#define SEL_GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_NAME_STRING 8
-#define SEL_GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_NAME_STARTSTR 9
-#define SEL_GOOGLE_PROTOBUF_ENUMDESCRIPTORPROTO_NAME_ENDSTR 10
-
-/* google.protobuf.EnumOptions */
-#define SEL_GOOGLE_PROTOBUF_ENUMOPTIONS_UNINTERPRETED_OPTION_STARTSUBMSG 2
-#define SEL_GOOGLE_PROTOBUF_ENUMOPTIONS_UNINTERPRETED_OPTION_STARTSEQ 3
-#define SEL_GOOGLE_PROTOBUF_ENUMOPTIONS_UNINTERPRETED_OPTION_ENDSEQ 4
-#define SEL_GOOGLE_PROTOBUF_ENUMOPTIONS_UNINTERPRETED_OPTION_ENDSUBMSG 5
-#define SEL_GOOGLE_PROTOBUF_ENUMOPTIONS_ALLOW_ALIAS_BOOL 6
-
-/* google.protobuf.EnumValueDescriptorProto */
-#define SEL_GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO_OPTIONS_STARTSUBMSG 2
-#define SEL_GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO_OPTIONS_ENDSUBMSG 3
-#define SEL_GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO_NAME_STRING 4
-#define SEL_GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO_NAME_STARTSTR 5
-#define SEL_GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO_NAME_ENDSTR 6
-#define SEL_GOOGLE_PROTOBUF_ENUMVALUEDESCRIPTORPROTO_NUMBER_INT32 7
-
-/* google.protobuf.EnumValueOptions */
-#define SEL_GOOGLE_PROTOBUF_ENUMVALUEOPTIONS_UNINTERPRETED_OPTION_STARTSUBMSG 2
-#define SEL_GOOGLE_PROTOBUF_ENUMVALUEOPTIONS_UNINTERPRETED_OPTION_STARTSEQ 3
-#define SEL_GOOGLE_PROTOBUF_ENUMVALUEOPTIONS_UNINTERPRETED_OPTION_ENDSEQ 4
-#define SEL_GOOGLE_PROTOBUF_ENUMVALUEOPTIONS_UNINTERPRETED_OPTION_ENDSUBMSG 5
-
-/* google.protobuf.FieldDescriptorProto */
-#define SEL_GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_OPTIONS_STARTSUBMSG 2
-#define SEL_GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_OPTIONS_ENDSUBMSG 3
-#define SEL_GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_NAME_STRING 4
-#define SEL_GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_NAME_STARTSTR 5
-#define SEL_GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_NAME_ENDSTR 6
-#define SEL_GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_EXTENDEE_STRING 7
-#define SEL_GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_EXTENDEE_STARTSTR 8
-#define SEL_GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_EXTENDEE_ENDSTR 9
-#define SEL_GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_NUMBER_INT32 10
-#define SEL_GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_LABEL_INT32 11
-#define SEL_GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_INT32 12
-#define SEL_GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_NAME_STRING 13
-#define SEL_GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_NAME_STARTSTR 14
-#define SEL_GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_NAME_ENDSTR 15
-#define SEL_GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_DEFAULT_VALUE_STRING 16
-#define SEL_GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_DEFAULT_VALUE_STARTSTR 17
-#define SEL_GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_DEFAULT_VALUE_ENDSTR 18
-
-/* google.protobuf.FieldOptions */
-#define SEL_GOOGLE_PROTOBUF_FIELDOPTIONS_UNINTERPRETED_OPTION_STARTSUBMSG 2
-#define SEL_GOOGLE_PROTOBUF_FIELDOPTIONS_UNINTERPRETED_OPTION_STARTSEQ 3
-#define SEL_GOOGLE_PROTOBUF_FIELDOPTIONS_UNINTERPRETED_OPTION_ENDSEQ 4
-#define SEL_GOOGLE_PROTOBUF_FIELDOPTIONS_UNINTERPRETED_OPTION_ENDSUBMSG 5
-#define SEL_GOOGLE_PROTOBUF_FIELDOPTIONS_CTYPE_INT32 6
-#define SEL_GOOGLE_PROTOBUF_FIELDOPTIONS_PACKED_BOOL 7
-#define SEL_GOOGLE_PROTOBUF_FIELDOPTIONS_DEPRECATED_BOOL 8
-#define SEL_GOOGLE_PROTOBUF_FIELDOPTIONS_LAZY_BOOL 9
-#define SEL_GOOGLE_PROTOBUF_FIELDOPTIONS_EXPERIMENTAL_MAP_KEY_STRING 10
-#define SEL_GOOGLE_PROTOBUF_FIELDOPTIONS_EXPERIMENTAL_MAP_KEY_STARTSTR 11
-#define SEL_GOOGLE_PROTOBUF_FIELDOPTIONS_EXPERIMENTAL_MAP_KEY_ENDSTR 12
-#define SEL_GOOGLE_PROTOBUF_FIELDOPTIONS_WEAK_BOOL 13
-
-/* google.protobuf.FileDescriptorProto */
-#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_MESSAGE_TYPE_STARTSUBMSG 2
-#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_ENUM_TYPE_STARTSUBMSG 3
-#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_SERVICE_STARTSUBMSG 4
-#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_EXTENSION_STARTSUBMSG 5
-#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_OPTIONS_STARTSUBMSG 6
-#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_SOURCE_CODE_INFO_STARTSUBMSG 7
-#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_MESSAGE_TYPE_STARTSEQ 8
-#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_MESSAGE_TYPE_ENDSEQ 9
-#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_MESSAGE_TYPE_ENDSUBMSG 10
-#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_ENUM_TYPE_STARTSEQ 11
-#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_ENUM_TYPE_ENDSEQ 12
-#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_ENUM_TYPE_ENDSUBMSG 13
-#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_SERVICE_STARTSEQ 14
-#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_SERVICE_ENDSEQ 15
-#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_SERVICE_ENDSUBMSG 16
-#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_EXTENSION_STARTSEQ 17
-#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_EXTENSION_ENDSEQ 18
-#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_EXTENSION_ENDSUBMSG 19
-#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_OPTIONS_ENDSUBMSG 20
-#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_SOURCE_CODE_INFO_ENDSUBMSG 21
-#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_NAME_STRING 22
-#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_NAME_STARTSTR 23
-#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_NAME_ENDSTR 24
-#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_PACKAGE_STRING 25
-#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_PACKAGE_STARTSTR 26
-#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_PACKAGE_ENDSTR 27
-#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_DEPENDENCY_STARTSEQ 28
-#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_DEPENDENCY_ENDSEQ 29
-#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_DEPENDENCY_STRING 30
-#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_DEPENDENCY_STARTSTR 31
-#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_DEPENDENCY_ENDSTR 32
-#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_PUBLIC_DEPENDENCY_STARTSEQ 33
-#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_PUBLIC_DEPENDENCY_ENDSEQ 34
-#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_PUBLIC_DEPENDENCY_INT32 35
-#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_WEAK_DEPENDENCY_STARTSEQ 36
-#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_WEAK_DEPENDENCY_ENDSEQ 37
-#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORPROTO_WEAK_DEPENDENCY_INT32 38
-
-/* google.protobuf.FileDescriptorSet */
-#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORSET_FILE_STARTSUBMSG 2
-#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORSET_FILE_STARTSEQ 3
-#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORSET_FILE_ENDSEQ 4
-#define SEL_GOOGLE_PROTOBUF_FILEDESCRIPTORSET_FILE_ENDSUBMSG 5
-
-/* google.protobuf.FileOptions */
-#define SEL_GOOGLE_PROTOBUF_FILEOPTIONS_UNINTERPRETED_OPTION_STARTSUBMSG 2
-#define SEL_GOOGLE_PROTOBUF_FILEOPTIONS_UNINTERPRETED_OPTION_STARTSEQ 3
-#define SEL_GOOGLE_PROTOBUF_FILEOPTIONS_UNINTERPRETED_OPTION_ENDSEQ 4
-#define SEL_GOOGLE_PROTOBUF_FILEOPTIONS_UNINTERPRETED_OPTION_ENDSUBMSG 5
-#define SEL_GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_PACKAGE_STRING 6
-#define SEL_GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_PACKAGE_STARTSTR 7
-#define SEL_GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_PACKAGE_ENDSTR 8
-#define SEL_GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_OUTER_CLASSNAME_STRING 9
-#define SEL_GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_OUTER_CLASSNAME_STARTSTR 10
-#define SEL_GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_OUTER_CLASSNAME_ENDSTR 11
-#define SEL_GOOGLE_PROTOBUF_FILEOPTIONS_OPTIMIZE_FOR_INT32 12
-#define SEL_GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_MULTIPLE_FILES_BOOL 13
-#define SEL_GOOGLE_PROTOBUF_FILEOPTIONS_GO_PACKAGE_STRING 14
-#define SEL_GOOGLE_PROTOBUF_FILEOPTIONS_GO_PACKAGE_STARTSTR 15
-#define SEL_GOOGLE_PROTOBUF_FILEOPTIONS_GO_PACKAGE_ENDSTR 16
-#define SEL_GOOGLE_PROTOBUF_FILEOPTIONS_CC_GENERIC_SERVICES_BOOL 17
-#define SEL_GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_GENERIC_SERVICES_BOOL 18
-#define SEL_GOOGLE_PROTOBUF_FILEOPTIONS_PY_GENERIC_SERVICES_BOOL 19
-#define SEL_GOOGLE_PROTOBUF_FILEOPTIONS_JAVA_GENERATE_EQUALS_AND_HASH_BOOL 20
-
-/* google.protobuf.MessageOptions */
-#define SEL_GOOGLE_PROTOBUF_MESSAGEOPTIONS_UNINTERPRETED_OPTION_STARTSUBMSG 2
-#define SEL_GOOGLE_PROTOBUF_MESSAGEOPTIONS_UNINTERPRETED_OPTION_STARTSEQ 3
-#define SEL_GOOGLE_PROTOBUF_MESSAGEOPTIONS_UNINTERPRETED_OPTION_ENDSEQ 4
-#define SEL_GOOGLE_PROTOBUF_MESSAGEOPTIONS_UNINTERPRETED_OPTION_ENDSUBMSG 5
-#define SEL_GOOGLE_PROTOBUF_MESSAGEOPTIONS_MESSAGE_SET_WIRE_FORMAT_BOOL 6
-#define SEL_GOOGLE_PROTOBUF_MESSAGEOPTIONS_NO_STANDARD_DESCRIPTOR_ACCESSOR_BOOL 7
-
-/* google.protobuf.MethodDescriptorProto */
-#define SEL_GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_OPTIONS_STARTSUBMSG 2
-#define SEL_GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_OPTIONS_ENDSUBMSG 3
-#define SEL_GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_NAME_STRING 4
-#define SEL_GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_NAME_STARTSTR 5
-#define SEL_GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_NAME_ENDSTR 6
-#define SEL_GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_INPUT_TYPE_STRING 7
-#define SEL_GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_INPUT_TYPE_STARTSTR 8
-#define SEL_GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_INPUT_TYPE_ENDSTR 9
-#define SEL_GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_OUTPUT_TYPE_STRING 10
-#define SEL_GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_OUTPUT_TYPE_STARTSTR 11
-#define SEL_GOOGLE_PROTOBUF_METHODDESCRIPTORPROTO_OUTPUT_TYPE_ENDSTR 12
-
-/* google.protobuf.MethodOptions */
-#define SEL_GOOGLE_PROTOBUF_METHODOPTIONS_UNINTERPRETED_OPTION_STARTSUBMSG 2
-#define SEL_GOOGLE_PROTOBUF_METHODOPTIONS_UNINTERPRETED_OPTION_STARTSEQ 3
-#define SEL_GOOGLE_PROTOBUF_METHODOPTIONS_UNINTERPRETED_OPTION_ENDSEQ 4
-#define SEL_GOOGLE_PROTOBUF_METHODOPTIONS_UNINTERPRETED_OPTION_ENDSUBMSG 5
-
-/* google.protobuf.ServiceDescriptorProto */
-#define SEL_GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_METHOD_STARTSUBMSG 2
-#define SEL_GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_OPTIONS_STARTSUBMSG 3
-#define SEL_GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_METHOD_STARTSEQ 4
-#define SEL_GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_METHOD_ENDSEQ 5
-#define SEL_GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_METHOD_ENDSUBMSG 6
-#define SEL_GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_OPTIONS_ENDSUBMSG 7
-#define SEL_GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_NAME_STRING 8
-#define SEL_GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_NAME_STARTSTR 9
-#define SEL_GOOGLE_PROTOBUF_SERVICEDESCRIPTORPROTO_NAME_ENDSTR 10
-
-/* google.protobuf.ServiceOptions */
-#define SEL_GOOGLE_PROTOBUF_SERVICEOPTIONS_UNINTERPRETED_OPTION_STARTSUBMSG 2
-#define SEL_GOOGLE_PROTOBUF_SERVICEOPTIONS_UNINTERPRETED_OPTION_STARTSEQ 3
-#define SEL_GOOGLE_PROTOBUF_SERVICEOPTIONS_UNINTERPRETED_OPTION_ENDSEQ 4
-#define SEL_GOOGLE_PROTOBUF_SERVICEOPTIONS_UNINTERPRETED_OPTION_ENDSUBMSG 5
-
-/* google.protobuf.SourceCodeInfo */
-#define SEL_GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_STARTSUBMSG 2
-#define SEL_GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_STARTSEQ 3
-#define SEL_GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_ENDSEQ 4
-#define SEL_GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_ENDSUBMSG 5
-
-/* google.protobuf.SourceCodeInfo.Location */
-#define SEL_GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_PATH_STARTSEQ 2
-#define SEL_GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_PATH_ENDSEQ 3
-#define SEL_GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_PATH_INT32 4
-#define SEL_GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_SPAN_STARTSEQ 5
-#define SEL_GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_SPAN_ENDSEQ 6
-#define SEL_GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_SPAN_INT32 7
-#define SEL_GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_LEADING_COMMENTS_STRING 8
-#define SEL_GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_LEADING_COMMENTS_STARTSTR 9
-#define SEL_GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_LEADING_COMMENTS_ENDSTR 10
-#define SEL_GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_TRAILING_COMMENTS_STRING 11
-#define SEL_GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_TRAILING_COMMENTS_STARTSTR 12
-#define SEL_GOOGLE_PROTOBUF_SOURCECODEINFO_LOCATION_TRAILING_COMMENTS_ENDSTR 13
-
-/* google.protobuf.UninterpretedOption */
-#define SEL_GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAME_STARTSUBMSG 2
-#define SEL_GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAME_STARTSEQ 3
-#define SEL_GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAME_ENDSEQ 4
-#define SEL_GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAME_ENDSUBMSG 5
-#define SEL_GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_IDENTIFIER_VALUE_STRING 6
-#define SEL_GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_IDENTIFIER_VALUE_STARTSTR 7
-#define SEL_GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_IDENTIFIER_VALUE_ENDSTR 8
-#define SEL_GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_POSITIVE_INT_VALUE_UINT64 9
-#define SEL_GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NEGATIVE_INT_VALUE_INT64 10
-#define SEL_GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_DOUBLE_VALUE_DOUBLE 11
-#define SEL_GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_STRING_VALUE_STRING 12
-#define SEL_GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_STRING_VALUE_STARTSTR 13
-#define SEL_GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_STRING_VALUE_ENDSTR 14
-#define SEL_GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_AGGREGATE_VALUE_STRING 15
-#define SEL_GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_AGGREGATE_VALUE_STARTSTR 16
-#define SEL_GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_AGGREGATE_VALUE_ENDSTR 17
-
-/* google.protobuf.UninterpretedOption.NamePart */
-#define SEL_GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAMEPART_NAME_PART_STRING 2
-#define SEL_GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAMEPART_NAME_PART_STARTSTR 3
-#define SEL_GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAMEPART_NAME_PART_ENDSTR 4
-#define SEL_GOOGLE_PROTOBUF_UNINTERPRETEDOPTION_NAMEPART_IS_EXTENSION_BOOL 5
-
-const upb_symtab *upbdefs_google_protobuf_descriptor(const void *owner);
-
-/* MessageDefs */
-UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_DescriptorProto(const upb_symtab *s) {
- const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.DescriptorProto");
- assert(m);
- return m;
-}
-UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_DescriptorProto_ExtensionRange(const upb_symtab *s) {
- const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.DescriptorProto.ExtensionRange");
- assert(m);
- return m;
-}
-UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_EnumDescriptorProto(const upb_symtab *s) {
- const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.EnumDescriptorProto");
- assert(m);
- return m;
-}
-UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_EnumOptions(const upb_symtab *s) {
- const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.EnumOptions");
- assert(m);
- return m;
-}
-UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_EnumValueDescriptorProto(const upb_symtab *s) {
- const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.EnumValueDescriptorProto");
- assert(m);
- return m;
-}
-UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_EnumValueOptions(const upb_symtab *s) {
- const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.EnumValueOptions");
- assert(m);
- return m;
-}
-UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_FieldDescriptorProto(const upb_symtab *s) {
- const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.FieldDescriptorProto");
- assert(m);
- return m;
-}
-UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_FieldOptions(const upb_symtab *s) {
- const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.FieldOptions");
- assert(m);
- return m;
-}
-UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_FileDescriptorProto(const upb_symtab *s) {
- const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.FileDescriptorProto");
- assert(m);
- return m;
-}
-UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_FileDescriptorSet(const upb_symtab *s) {
- const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.FileDescriptorSet");
- assert(m);
- return m;
-}
-UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_FileOptions(const upb_symtab *s) {
- const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.FileOptions");
- assert(m);
- return m;
-}
-UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_MessageOptions(const upb_symtab *s) {
- const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.MessageOptions");
- assert(m);
- return m;
-}
-UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_MethodDescriptorProto(const upb_symtab *s) {
- const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.MethodDescriptorProto");
- assert(m);
- return m;
-}
-UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_MethodOptions(const upb_symtab *s) {
- const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.MethodOptions");
- assert(m);
- return m;
-}
-UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_ServiceDescriptorProto(const upb_symtab *s) {
- const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.ServiceDescriptorProto");
- assert(m);
- return m;
-}
-UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_ServiceOptions(const upb_symtab *s) {
- const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.ServiceOptions");
- assert(m);
- return m;
-}
-UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_SourceCodeInfo(const upb_symtab *s) {
- const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.SourceCodeInfo");
- assert(m);
- return m;
-}
-UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_SourceCodeInfo_Location(const upb_symtab *s) {
- const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.SourceCodeInfo.Location");
- assert(m);
- return m;
-}
-UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_UninterpretedOption(const upb_symtab *s) {
- const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.UninterpretedOption");
- assert(m);
- return m;
-}
-UPB_INLINE const upb_msgdef *upbdefs_google_protobuf_UninterpretedOption_NamePart(const upb_symtab *s) {
- const upb_msgdef *m = upb_symtab_lookupmsg(s, "google.protobuf.UninterpretedOption.NamePart");
- assert(m);
- return m;
-}
-
-
-/* EnumDefs */
-UPB_INLINE const upb_enumdef *upbdefs_google_protobuf_FieldDescriptorProto_Label(const upb_symtab *s) {
- const upb_enumdef *e = upb_symtab_lookupenum(s, "google.protobuf.FieldDescriptorProto.Label");
- assert(e);
- return e;
-}
-UPB_INLINE const upb_enumdef *upbdefs_google_protobuf_FieldDescriptorProto_Type(const upb_symtab *s) {
- const upb_enumdef *e = upb_symtab_lookupenum(s, "google.protobuf.FieldDescriptorProto.Type");
- assert(e);
- return e;
-}
-UPB_INLINE const upb_enumdef *upbdefs_google_protobuf_FieldOptions_CType(const upb_symtab *s) {
- const upb_enumdef *e = upb_symtab_lookupenum(s, "google.protobuf.FieldOptions.CType");
- assert(e);
- return e;
-}
-UPB_INLINE const upb_enumdef *upbdefs_google_protobuf_FileOptions_OptimizeMode(const upb_symtab *s) {
- const upb_enumdef *e = upb_symtab_lookupenum(s, "google.protobuf.FileOptions.OptimizeMode");
- assert(e);
- return e;
-}
-
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_DescriptorProto_ExtensionRange_end(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_DescriptorProto_ExtensionRange(s), 2); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_DescriptorProto_ExtensionRange_start(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_DescriptorProto_ExtensionRange(s), 1); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_DescriptorProto_enum_type(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_DescriptorProto(s), 4); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_DescriptorProto_extension(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_DescriptorProto(s), 6); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_DescriptorProto_extension_range(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_DescriptorProto(s), 5); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_DescriptorProto_field(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_DescriptorProto(s), 2); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_DescriptorProto_name(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_DescriptorProto(s), 1); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_DescriptorProto_nested_type(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_DescriptorProto(s), 3); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_DescriptorProto_options(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_DescriptorProto(s), 7); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_EnumDescriptorProto_name(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_EnumDescriptorProto(s), 1); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_EnumDescriptorProto_options(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_EnumDescriptorProto(s), 3); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_EnumDescriptorProto_value(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_EnumDescriptorProto(s), 2); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_EnumOptions_allow_alias(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_EnumOptions(s), 2); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_EnumOptions_uninterpreted_option(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_EnumOptions(s), 999); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_EnumValueDescriptorProto_name(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_EnumValueDescriptorProto(s), 1); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_EnumValueDescriptorProto_number(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_EnumValueDescriptorProto(s), 2); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_EnumValueDescriptorProto_options(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_EnumValueDescriptorProto(s), 3); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_EnumValueOptions_uninterpreted_option(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_EnumValueOptions(s), 999); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldDescriptorProto_default_value(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FieldDescriptorProto(s), 7); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldDescriptorProto_extendee(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FieldDescriptorProto(s), 2); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldDescriptorProto_label(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FieldDescriptorProto(s), 4); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldDescriptorProto_name(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FieldDescriptorProto(s), 1); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldDescriptorProto_number(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FieldDescriptorProto(s), 3); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldDescriptorProto_options(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FieldDescriptorProto(s), 8); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldDescriptorProto_type(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FieldDescriptorProto(s), 5); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldDescriptorProto_type_name(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FieldDescriptorProto(s), 6); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldOptions_ctype(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FieldOptions(s), 1); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldOptions_deprecated(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FieldOptions(s), 3); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldOptions_experimental_map_key(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FieldOptions(s), 9); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldOptions_lazy(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FieldOptions(s), 5); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldOptions_packed(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FieldOptions(s), 2); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldOptions_uninterpreted_option(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FieldOptions(s), 999); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldOptions_weak(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FieldOptions(s), 10); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorProto_dependency(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileDescriptorProto(s), 3); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorProto_enum_type(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileDescriptorProto(s), 5); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorProto_extension(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileDescriptorProto(s), 7); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorProto_message_type(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileDescriptorProto(s), 4); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorProto_name(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileDescriptorProto(s), 1); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorProto_options(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileDescriptorProto(s), 8); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorProto_package(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileDescriptorProto(s), 2); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorProto_public_dependency(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileDescriptorProto(s), 10); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorProto_service(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileDescriptorProto(s), 6); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorProto_source_code_info(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileDescriptorProto(s), 9); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorProto_weak_dependency(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileDescriptorProto(s), 11); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorSet_file(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileDescriptorSet(s), 1); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_cc_generic_services(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileOptions(s), 16); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_go_package(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileOptions(s), 11); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_java_generate_equals_and_hash(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileOptions(s), 20); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_java_generic_services(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileOptions(s), 17); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_java_multiple_files(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileOptions(s), 10); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_java_outer_classname(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileOptions(s), 8); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_java_package(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileOptions(s), 1); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_optimize_for(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileOptions(s), 9); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_py_generic_services(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileOptions(s), 18); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_uninterpreted_option(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_FileOptions(s), 999); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_MessageOptions_message_set_wire_format(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_MessageOptions(s), 1); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_MessageOptions_no_standard_descriptor_accessor(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_MessageOptions(s), 2); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_MessageOptions_uninterpreted_option(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_MessageOptions(s), 999); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_MethodDescriptorProto_input_type(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_MethodDescriptorProto(s), 2); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_MethodDescriptorProto_name(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_MethodDescriptorProto(s), 1); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_MethodDescriptorProto_options(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_MethodDescriptorProto(s), 4); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_MethodDescriptorProto_output_type(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_MethodDescriptorProto(s), 3); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_MethodOptions_uninterpreted_option(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_MethodOptions(s), 999); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_ServiceDescriptorProto_method(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_ServiceDescriptorProto(s), 2); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_ServiceDescriptorProto_name(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_ServiceDescriptorProto(s), 1); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_ServiceDescriptorProto_options(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_ServiceDescriptorProto(s), 3); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_ServiceOptions_uninterpreted_option(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_ServiceOptions(s), 999); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_SourceCodeInfo_Location_leading_comments(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_SourceCodeInfo_Location(s), 3); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_SourceCodeInfo_Location_path(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_SourceCodeInfo_Location(s), 1); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_SourceCodeInfo_Location_span(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_SourceCodeInfo_Location(s), 2); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_SourceCodeInfo_Location_trailing_comments(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_SourceCodeInfo_Location(s), 4); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_SourceCodeInfo_location(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_SourceCodeInfo(s), 1); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_UninterpretedOption_NamePart_is_extension(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_UninterpretedOption_NamePart(s), 2); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_UninterpretedOption_NamePart_name_part(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_UninterpretedOption_NamePart(s), 1); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_UninterpretedOption_aggregate_value(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_UninterpretedOption(s), 8); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_UninterpretedOption_double_value(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_UninterpretedOption(s), 6); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_UninterpretedOption_identifier_value(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_UninterpretedOption(s), 3); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_UninterpretedOption_name(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_UninterpretedOption(s), 2); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_UninterpretedOption_negative_int_value(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_UninterpretedOption(s), 5); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_UninterpretedOption_positive_int_value(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_UninterpretedOption(s), 4); }
-UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_UninterpretedOption_string_value(const upb_symtab *s) { return upb_msgdef_itof(upbdefs_google_protobuf_UninterpretedOption(s), 7); }
+/* MessageDefs: call these functions to get a ref to a msgdef. */
+const upb_msgdef *upbdefs_google_protobuf_DescriptorProto_get(const void *owner);
+const upb_msgdef *upbdefs_google_protobuf_DescriptorProto_ExtensionRange_get(const void *owner);
+const upb_msgdef *upbdefs_google_protobuf_DescriptorProto_ReservedRange_get(const void *owner);
+const upb_msgdef *upbdefs_google_protobuf_EnumDescriptorProto_get(const void *owner);
+const upb_msgdef *upbdefs_google_protobuf_EnumOptions_get(const void *owner);
+const upb_msgdef *upbdefs_google_protobuf_EnumValueDescriptorProto_get(const void *owner);
+const upb_msgdef *upbdefs_google_protobuf_EnumValueOptions_get(const void *owner);
+const upb_msgdef *upbdefs_google_protobuf_FieldDescriptorProto_get(const void *owner);
+const upb_msgdef *upbdefs_google_protobuf_FieldOptions_get(const void *owner);
+const upb_msgdef *upbdefs_google_protobuf_FileDescriptorProto_get(const void *owner);
+const upb_msgdef *upbdefs_google_protobuf_FileDescriptorSet_get(const void *owner);
+const upb_msgdef *upbdefs_google_protobuf_FileOptions_get(const void *owner);
+const upb_msgdef *upbdefs_google_protobuf_MessageOptions_get(const void *owner);
+const upb_msgdef *upbdefs_google_protobuf_MethodDescriptorProto_get(const void *owner);
+const upb_msgdef *upbdefs_google_protobuf_MethodOptions_get(const void *owner);
+const upb_msgdef *upbdefs_google_protobuf_OneofDescriptorProto_get(const void *owner);
+const upb_msgdef *upbdefs_google_protobuf_ServiceDescriptorProto_get(const void *owner);
+const upb_msgdef *upbdefs_google_protobuf_ServiceOptions_get(const void *owner);
+const upb_msgdef *upbdefs_google_protobuf_SourceCodeInfo_get(const void *owner);
+const upb_msgdef *upbdefs_google_protobuf_SourceCodeInfo_Location_get(const void *owner);
+const upb_msgdef *upbdefs_google_protobuf_UninterpretedOption_get(const void *owner);
+const upb_msgdef *upbdefs_google_protobuf_UninterpretedOption_NamePart_get(const void *owner);
+
+/* EnumDefs: call these functions to get a ref to an enumdef. */
+const upb_enumdef *upbdefs_google_protobuf_FieldDescriptorProto_Label_get(const void *owner);
+const upb_enumdef *upbdefs_google_protobuf_FieldDescriptorProto_Type_get(const void *owner);
+const upb_enumdef *upbdefs_google_protobuf_FieldOptions_CType_get(const void *owner);
+const upb_enumdef *upbdefs_google_protobuf_FieldOptions_JSType_get(const void *owner);
+const upb_enumdef *upbdefs_google_protobuf_FileOptions_OptimizeMode_get(const void *owner);
+
+/* Functions to test whether this message is of a certain type. */
+UPB_INLINE bool upbdefs_google_protobuf_DescriptorProto_is(const upb_msgdef *m) {
+ return strcmp(upb_msgdef_fullname(m), "google.protobuf.DescriptorProto") == 0;
+}
+UPB_INLINE bool upbdefs_google_protobuf_DescriptorProto_ExtensionRange_is(const upb_msgdef *m) {
+ return strcmp(upb_msgdef_fullname(m), "google.protobuf.DescriptorProto.ExtensionRange") == 0;
+}
+UPB_INLINE bool upbdefs_google_protobuf_DescriptorProto_ReservedRange_is(const upb_msgdef *m) {
+ return strcmp(upb_msgdef_fullname(m), "google.protobuf.DescriptorProto.ReservedRange") == 0;
+}
+UPB_INLINE bool upbdefs_google_protobuf_EnumDescriptorProto_is(const upb_msgdef *m) {
+ return strcmp(upb_msgdef_fullname(m), "google.protobuf.EnumDescriptorProto") == 0;
+}
+UPB_INLINE bool upbdefs_google_protobuf_EnumOptions_is(const upb_msgdef *m) {
+ return strcmp(upb_msgdef_fullname(m), "google.protobuf.EnumOptions") == 0;
+}
+UPB_INLINE bool upbdefs_google_protobuf_EnumValueDescriptorProto_is(const upb_msgdef *m) {
+ return strcmp(upb_msgdef_fullname(m), "google.protobuf.EnumValueDescriptorProto") == 0;
+}
+UPB_INLINE bool upbdefs_google_protobuf_EnumValueOptions_is(const upb_msgdef *m) {
+ return strcmp(upb_msgdef_fullname(m), "google.protobuf.EnumValueOptions") == 0;
+}
+UPB_INLINE bool upbdefs_google_protobuf_FieldDescriptorProto_is(const upb_msgdef *m) {
+ return strcmp(upb_msgdef_fullname(m), "google.protobuf.FieldDescriptorProto") == 0;
+}
+UPB_INLINE bool upbdefs_google_protobuf_FieldOptions_is(const upb_msgdef *m) {
+ return strcmp(upb_msgdef_fullname(m), "google.protobuf.FieldOptions") == 0;
+}
+UPB_INLINE bool upbdefs_google_protobuf_FileDescriptorProto_is(const upb_msgdef *m) {
+ return strcmp(upb_msgdef_fullname(m), "google.protobuf.FileDescriptorProto") == 0;
+}
+UPB_INLINE bool upbdefs_google_protobuf_FileDescriptorSet_is(const upb_msgdef *m) {
+ return strcmp(upb_msgdef_fullname(m), "google.protobuf.FileDescriptorSet") == 0;
+}
+UPB_INLINE bool upbdefs_google_protobuf_FileOptions_is(const upb_msgdef *m) {
+ return strcmp(upb_msgdef_fullname(m), "google.protobuf.FileOptions") == 0;
+}
+UPB_INLINE bool upbdefs_google_protobuf_MessageOptions_is(const upb_msgdef *m) {
+ return strcmp(upb_msgdef_fullname(m), "google.protobuf.MessageOptions") == 0;
+}
+UPB_INLINE bool upbdefs_google_protobuf_MethodDescriptorProto_is(const upb_msgdef *m) {
+ return strcmp(upb_msgdef_fullname(m), "google.protobuf.MethodDescriptorProto") == 0;
+}
+UPB_INLINE bool upbdefs_google_protobuf_MethodOptions_is(const upb_msgdef *m) {
+ return strcmp(upb_msgdef_fullname(m), "google.protobuf.MethodOptions") == 0;
+}
+UPB_INLINE bool upbdefs_google_protobuf_OneofDescriptorProto_is(const upb_msgdef *m) {
+ return strcmp(upb_msgdef_fullname(m), "google.protobuf.OneofDescriptorProto") == 0;
+}
+UPB_INLINE bool upbdefs_google_protobuf_ServiceDescriptorProto_is(const upb_msgdef *m) {
+ return strcmp(upb_msgdef_fullname(m), "google.protobuf.ServiceDescriptorProto") == 0;
+}
+UPB_INLINE bool upbdefs_google_protobuf_ServiceOptions_is(const upb_msgdef *m) {
+ return strcmp(upb_msgdef_fullname(m), "google.protobuf.ServiceOptions") == 0;
+}
+UPB_INLINE bool upbdefs_google_protobuf_SourceCodeInfo_is(const upb_msgdef *m) {
+ return strcmp(upb_msgdef_fullname(m), "google.protobuf.SourceCodeInfo") == 0;
+}
+UPB_INLINE bool upbdefs_google_protobuf_SourceCodeInfo_Location_is(const upb_msgdef *m) {
+ return strcmp(upb_msgdef_fullname(m), "google.protobuf.SourceCodeInfo.Location") == 0;
+}
+UPB_INLINE bool upbdefs_google_protobuf_UninterpretedOption_is(const upb_msgdef *m) {
+ return strcmp(upb_msgdef_fullname(m), "google.protobuf.UninterpretedOption") == 0;
+}
+UPB_INLINE bool upbdefs_google_protobuf_UninterpretedOption_NamePart_is(const upb_msgdef *m) {
+ return strcmp(upb_msgdef_fullname(m), "google.protobuf.UninterpretedOption.NamePart") == 0;
+}
+
+/* Functions to test whether this enum is of a certain type. */
+UPB_INLINE bool upbdefs_google_protobuf_FieldDescriptorProto_Label_is(const upb_enumdef *e) {
+ return strcmp(upb_enumdef_fullname(e), "google.protobuf.FieldDescriptorProto.Label") == 0;
+}
+UPB_INLINE bool upbdefs_google_protobuf_FieldDescriptorProto_Type_is(const upb_enumdef *e) {
+ return strcmp(upb_enumdef_fullname(e), "google.protobuf.FieldDescriptorProto.Type") == 0;
+}
+UPB_INLINE bool upbdefs_google_protobuf_FieldOptions_CType_is(const upb_enumdef *e) {
+ return strcmp(upb_enumdef_fullname(e), "google.protobuf.FieldOptions.CType") == 0;
+}
+UPB_INLINE bool upbdefs_google_protobuf_FieldOptions_JSType_is(const upb_enumdef *e) {
+ return strcmp(upb_enumdef_fullname(e), "google.protobuf.FieldOptions.JSType") == 0;
+}
+UPB_INLINE bool upbdefs_google_protobuf_FileOptions_OptimizeMode_is(const upb_enumdef *e) {
+ return strcmp(upb_enumdef_fullname(e), "google.protobuf.FileOptions.OptimizeMode") == 0;
+}
+
+
+/* Functions to get a fielddef from a msgdef reference. */
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_DescriptorProto_ExtensionRange_f_end(const upb_msgdef *m) { assert(upbdefs_google_protobuf_DescriptorProto_ExtensionRange_is(m)); return upb_msgdef_itof(m, 2); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_DescriptorProto_ExtensionRange_f_start(const upb_msgdef *m) { assert(upbdefs_google_protobuf_DescriptorProto_ExtensionRange_is(m)); return upb_msgdef_itof(m, 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_DescriptorProto_ReservedRange_f_end(const upb_msgdef *m) { assert(upbdefs_google_protobuf_DescriptorProto_ReservedRange_is(m)); return upb_msgdef_itof(m, 2); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_DescriptorProto_ReservedRange_f_start(const upb_msgdef *m) { assert(upbdefs_google_protobuf_DescriptorProto_ReservedRange_is(m)); return upb_msgdef_itof(m, 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_DescriptorProto_f_enum_type(const upb_msgdef *m) { assert(upbdefs_google_protobuf_DescriptorProto_is(m)); return upb_msgdef_itof(m, 4); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_DescriptorProto_f_extension(const upb_msgdef *m) { assert(upbdefs_google_protobuf_DescriptorProto_is(m)); return upb_msgdef_itof(m, 6); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_DescriptorProto_f_extension_range(const upb_msgdef *m) { assert(upbdefs_google_protobuf_DescriptorProto_is(m)); return upb_msgdef_itof(m, 5); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_DescriptorProto_f_field(const upb_msgdef *m) { assert(upbdefs_google_protobuf_DescriptorProto_is(m)); return upb_msgdef_itof(m, 2); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_DescriptorProto_f_name(const upb_msgdef *m) { assert(upbdefs_google_protobuf_DescriptorProto_is(m)); return upb_msgdef_itof(m, 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_DescriptorProto_f_nested_type(const upb_msgdef *m) { assert(upbdefs_google_protobuf_DescriptorProto_is(m)); return upb_msgdef_itof(m, 3); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_DescriptorProto_f_oneof_decl(const upb_msgdef *m) { assert(upbdefs_google_protobuf_DescriptorProto_is(m)); return upb_msgdef_itof(m, 8); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_DescriptorProto_f_options(const upb_msgdef *m) { assert(upbdefs_google_protobuf_DescriptorProto_is(m)); return upb_msgdef_itof(m, 7); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_DescriptorProto_f_reserved_name(const upb_msgdef *m) { assert(upbdefs_google_protobuf_DescriptorProto_is(m)); return upb_msgdef_itof(m, 10); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_DescriptorProto_f_reserved_range(const upb_msgdef *m) { assert(upbdefs_google_protobuf_DescriptorProto_is(m)); return upb_msgdef_itof(m, 9); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_EnumDescriptorProto_f_name(const upb_msgdef *m) { assert(upbdefs_google_protobuf_EnumDescriptorProto_is(m)); return upb_msgdef_itof(m, 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_EnumDescriptorProto_f_options(const upb_msgdef *m) { assert(upbdefs_google_protobuf_EnumDescriptorProto_is(m)); return upb_msgdef_itof(m, 3); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_EnumDescriptorProto_f_value(const upb_msgdef *m) { assert(upbdefs_google_protobuf_EnumDescriptorProto_is(m)); return upb_msgdef_itof(m, 2); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_EnumOptions_f_allow_alias(const upb_msgdef *m) { assert(upbdefs_google_protobuf_EnumOptions_is(m)); return upb_msgdef_itof(m, 2); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_EnumOptions_f_deprecated(const upb_msgdef *m) { assert(upbdefs_google_protobuf_EnumOptions_is(m)); return upb_msgdef_itof(m, 3); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_EnumOptions_f_uninterpreted_option(const upb_msgdef *m) { assert(upbdefs_google_protobuf_EnumOptions_is(m)); return upb_msgdef_itof(m, 999); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_EnumValueDescriptorProto_f_name(const upb_msgdef *m) { assert(upbdefs_google_protobuf_EnumValueDescriptorProto_is(m)); return upb_msgdef_itof(m, 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_EnumValueDescriptorProto_f_number(const upb_msgdef *m) { assert(upbdefs_google_protobuf_EnumValueDescriptorProto_is(m)); return upb_msgdef_itof(m, 2); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_EnumValueDescriptorProto_f_options(const upb_msgdef *m) { assert(upbdefs_google_protobuf_EnumValueDescriptorProto_is(m)); return upb_msgdef_itof(m, 3); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_EnumValueOptions_f_deprecated(const upb_msgdef *m) { assert(upbdefs_google_protobuf_EnumValueOptions_is(m)); return upb_msgdef_itof(m, 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_EnumValueOptions_f_uninterpreted_option(const upb_msgdef *m) { assert(upbdefs_google_protobuf_EnumValueOptions_is(m)); return upb_msgdef_itof(m, 999); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldDescriptorProto_f_default_value(const upb_msgdef *m) { assert(upbdefs_google_protobuf_FieldDescriptorProto_is(m)); return upb_msgdef_itof(m, 7); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldDescriptorProto_f_extendee(const upb_msgdef *m) { assert(upbdefs_google_protobuf_FieldDescriptorProto_is(m)); return upb_msgdef_itof(m, 2); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldDescriptorProto_f_json_name(const upb_msgdef *m) { assert(upbdefs_google_protobuf_FieldDescriptorProto_is(m)); return upb_msgdef_itof(m, 10); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldDescriptorProto_f_label(const upb_msgdef *m) { assert(upbdefs_google_protobuf_FieldDescriptorProto_is(m)); return upb_msgdef_itof(m, 4); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldDescriptorProto_f_name(const upb_msgdef *m) { assert(upbdefs_google_protobuf_FieldDescriptorProto_is(m)); return upb_msgdef_itof(m, 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldDescriptorProto_f_number(const upb_msgdef *m) { assert(upbdefs_google_protobuf_FieldDescriptorProto_is(m)); return upb_msgdef_itof(m, 3); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldDescriptorProto_f_oneof_index(const upb_msgdef *m) { assert(upbdefs_google_protobuf_FieldDescriptorProto_is(m)); return upb_msgdef_itof(m, 9); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldDescriptorProto_f_options(const upb_msgdef *m) { assert(upbdefs_google_protobuf_FieldDescriptorProto_is(m)); return upb_msgdef_itof(m, 8); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldDescriptorProto_f_type(const upb_msgdef *m) { assert(upbdefs_google_protobuf_FieldDescriptorProto_is(m)); return upb_msgdef_itof(m, 5); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldDescriptorProto_f_type_name(const upb_msgdef *m) { assert(upbdefs_google_protobuf_FieldDescriptorProto_is(m)); return upb_msgdef_itof(m, 6); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldOptions_f_ctype(const upb_msgdef *m) { assert(upbdefs_google_protobuf_FieldOptions_is(m)); return upb_msgdef_itof(m, 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldOptions_f_deprecated(const upb_msgdef *m) { assert(upbdefs_google_protobuf_FieldOptions_is(m)); return upb_msgdef_itof(m, 3); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldOptions_f_jstype(const upb_msgdef *m) { assert(upbdefs_google_protobuf_FieldOptions_is(m)); return upb_msgdef_itof(m, 6); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldOptions_f_lazy(const upb_msgdef *m) { assert(upbdefs_google_protobuf_FieldOptions_is(m)); return upb_msgdef_itof(m, 5); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldOptions_f_packed(const upb_msgdef *m) { assert(upbdefs_google_protobuf_FieldOptions_is(m)); return upb_msgdef_itof(m, 2); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldOptions_f_uninterpreted_option(const upb_msgdef *m) { assert(upbdefs_google_protobuf_FieldOptions_is(m)); return upb_msgdef_itof(m, 999); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FieldOptions_f_weak(const upb_msgdef *m) { assert(upbdefs_google_protobuf_FieldOptions_is(m)); return upb_msgdef_itof(m, 10); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorProto_f_dependency(const upb_msgdef *m) { assert(upbdefs_google_protobuf_FileDescriptorProto_is(m)); return upb_msgdef_itof(m, 3); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorProto_f_enum_type(const upb_msgdef *m) { assert(upbdefs_google_protobuf_FileDescriptorProto_is(m)); return upb_msgdef_itof(m, 5); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorProto_f_extension(const upb_msgdef *m) { assert(upbdefs_google_protobuf_FileDescriptorProto_is(m)); return upb_msgdef_itof(m, 7); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorProto_f_message_type(const upb_msgdef *m) { assert(upbdefs_google_protobuf_FileDescriptorProto_is(m)); return upb_msgdef_itof(m, 4); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorProto_f_name(const upb_msgdef *m) { assert(upbdefs_google_protobuf_FileDescriptorProto_is(m)); return upb_msgdef_itof(m, 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorProto_f_options(const upb_msgdef *m) { assert(upbdefs_google_protobuf_FileDescriptorProto_is(m)); return upb_msgdef_itof(m, 8); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorProto_f_package(const upb_msgdef *m) { assert(upbdefs_google_protobuf_FileDescriptorProto_is(m)); return upb_msgdef_itof(m, 2); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorProto_f_public_dependency(const upb_msgdef *m) { assert(upbdefs_google_protobuf_FileDescriptorProto_is(m)); return upb_msgdef_itof(m, 10); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorProto_f_service(const upb_msgdef *m) { assert(upbdefs_google_protobuf_FileDescriptorProto_is(m)); return upb_msgdef_itof(m, 6); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorProto_f_source_code_info(const upb_msgdef *m) { assert(upbdefs_google_protobuf_FileDescriptorProto_is(m)); return upb_msgdef_itof(m, 9); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorProto_f_syntax(const upb_msgdef *m) { assert(upbdefs_google_protobuf_FileDescriptorProto_is(m)); return upb_msgdef_itof(m, 12); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorProto_f_weak_dependency(const upb_msgdef *m) { assert(upbdefs_google_protobuf_FileDescriptorProto_is(m)); return upb_msgdef_itof(m, 11); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileDescriptorSet_f_file(const upb_msgdef *m) { assert(upbdefs_google_protobuf_FileDescriptorSet_is(m)); return upb_msgdef_itof(m, 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_f_cc_enable_arenas(const upb_msgdef *m) { assert(upbdefs_google_protobuf_FileOptions_is(m)); return upb_msgdef_itof(m, 31); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_f_cc_generic_services(const upb_msgdef *m) { assert(upbdefs_google_protobuf_FileOptions_is(m)); return upb_msgdef_itof(m, 16); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_f_csharp_namespace(const upb_msgdef *m) { assert(upbdefs_google_protobuf_FileOptions_is(m)); return upb_msgdef_itof(m, 37); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_f_deprecated(const upb_msgdef *m) { assert(upbdefs_google_protobuf_FileOptions_is(m)); return upb_msgdef_itof(m, 23); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_f_go_package(const upb_msgdef *m) { assert(upbdefs_google_protobuf_FileOptions_is(m)); return upb_msgdef_itof(m, 11); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_f_java_generate_equals_and_hash(const upb_msgdef *m) { assert(upbdefs_google_protobuf_FileOptions_is(m)); return upb_msgdef_itof(m, 20); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_f_java_generic_services(const upb_msgdef *m) { assert(upbdefs_google_protobuf_FileOptions_is(m)); return upb_msgdef_itof(m, 17); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_f_java_multiple_files(const upb_msgdef *m) { assert(upbdefs_google_protobuf_FileOptions_is(m)); return upb_msgdef_itof(m, 10); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_f_java_outer_classname(const upb_msgdef *m) { assert(upbdefs_google_protobuf_FileOptions_is(m)); return upb_msgdef_itof(m, 8); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_f_java_package(const upb_msgdef *m) { assert(upbdefs_google_protobuf_FileOptions_is(m)); return upb_msgdef_itof(m, 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_f_java_string_check_utf8(const upb_msgdef *m) { assert(upbdefs_google_protobuf_FileOptions_is(m)); return upb_msgdef_itof(m, 27); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_f_javanano_use_deprecated_package(const upb_msgdef *m) { assert(upbdefs_google_protobuf_FileOptions_is(m)); return upb_msgdef_itof(m, 38); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_f_objc_class_prefix(const upb_msgdef *m) { assert(upbdefs_google_protobuf_FileOptions_is(m)); return upb_msgdef_itof(m, 36); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_f_optimize_for(const upb_msgdef *m) { assert(upbdefs_google_protobuf_FileOptions_is(m)); return upb_msgdef_itof(m, 9); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_f_py_generic_services(const upb_msgdef *m) { assert(upbdefs_google_protobuf_FileOptions_is(m)); return upb_msgdef_itof(m, 18); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_FileOptions_f_uninterpreted_option(const upb_msgdef *m) { assert(upbdefs_google_protobuf_FileOptions_is(m)); return upb_msgdef_itof(m, 999); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_MessageOptions_f_deprecated(const upb_msgdef *m) { assert(upbdefs_google_protobuf_MessageOptions_is(m)); return upb_msgdef_itof(m, 3); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_MessageOptions_f_map_entry(const upb_msgdef *m) { assert(upbdefs_google_protobuf_MessageOptions_is(m)); return upb_msgdef_itof(m, 7); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_MessageOptions_f_message_set_wire_format(const upb_msgdef *m) { assert(upbdefs_google_protobuf_MessageOptions_is(m)); return upb_msgdef_itof(m, 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_MessageOptions_f_no_standard_descriptor_accessor(const upb_msgdef *m) { assert(upbdefs_google_protobuf_MessageOptions_is(m)); return upb_msgdef_itof(m, 2); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_MessageOptions_f_uninterpreted_option(const upb_msgdef *m) { assert(upbdefs_google_protobuf_MessageOptions_is(m)); return upb_msgdef_itof(m, 999); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_MethodDescriptorProto_f_client_streaming(const upb_msgdef *m) { assert(upbdefs_google_protobuf_MethodDescriptorProto_is(m)); return upb_msgdef_itof(m, 5); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_MethodDescriptorProto_f_input_type(const upb_msgdef *m) { assert(upbdefs_google_protobuf_MethodDescriptorProto_is(m)); return upb_msgdef_itof(m, 2); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_MethodDescriptorProto_f_name(const upb_msgdef *m) { assert(upbdefs_google_protobuf_MethodDescriptorProto_is(m)); return upb_msgdef_itof(m, 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_MethodDescriptorProto_f_options(const upb_msgdef *m) { assert(upbdefs_google_protobuf_MethodDescriptorProto_is(m)); return upb_msgdef_itof(m, 4); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_MethodDescriptorProto_f_output_type(const upb_msgdef *m) { assert(upbdefs_google_protobuf_MethodDescriptorProto_is(m)); return upb_msgdef_itof(m, 3); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_MethodDescriptorProto_f_server_streaming(const upb_msgdef *m) { assert(upbdefs_google_protobuf_MethodDescriptorProto_is(m)); return upb_msgdef_itof(m, 6); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_MethodOptions_f_deprecated(const upb_msgdef *m) { assert(upbdefs_google_protobuf_MethodOptions_is(m)); return upb_msgdef_itof(m, 33); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_MethodOptions_f_uninterpreted_option(const upb_msgdef *m) { assert(upbdefs_google_protobuf_MethodOptions_is(m)); return upb_msgdef_itof(m, 999); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_OneofDescriptorProto_f_name(const upb_msgdef *m) { assert(upbdefs_google_protobuf_OneofDescriptorProto_is(m)); return upb_msgdef_itof(m, 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_ServiceDescriptorProto_f_method(const upb_msgdef *m) { assert(upbdefs_google_protobuf_ServiceDescriptorProto_is(m)); return upb_msgdef_itof(m, 2); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_ServiceDescriptorProto_f_name(const upb_msgdef *m) { assert(upbdefs_google_protobuf_ServiceDescriptorProto_is(m)); return upb_msgdef_itof(m, 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_ServiceDescriptorProto_f_options(const upb_msgdef *m) { assert(upbdefs_google_protobuf_ServiceDescriptorProto_is(m)); return upb_msgdef_itof(m, 3); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_ServiceOptions_f_deprecated(const upb_msgdef *m) { assert(upbdefs_google_protobuf_ServiceOptions_is(m)); return upb_msgdef_itof(m, 33); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_ServiceOptions_f_uninterpreted_option(const upb_msgdef *m) { assert(upbdefs_google_protobuf_ServiceOptions_is(m)); return upb_msgdef_itof(m, 999); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_SourceCodeInfo_Location_f_leading_comments(const upb_msgdef *m) { assert(upbdefs_google_protobuf_SourceCodeInfo_Location_is(m)); return upb_msgdef_itof(m, 3); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_SourceCodeInfo_Location_f_leading_detached_comments(const upb_msgdef *m) { assert(upbdefs_google_protobuf_SourceCodeInfo_Location_is(m)); return upb_msgdef_itof(m, 6); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_SourceCodeInfo_Location_f_path(const upb_msgdef *m) { assert(upbdefs_google_protobuf_SourceCodeInfo_Location_is(m)); return upb_msgdef_itof(m, 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_SourceCodeInfo_Location_f_span(const upb_msgdef *m) { assert(upbdefs_google_protobuf_SourceCodeInfo_Location_is(m)); return upb_msgdef_itof(m, 2); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_SourceCodeInfo_Location_f_trailing_comments(const upb_msgdef *m) { assert(upbdefs_google_protobuf_SourceCodeInfo_Location_is(m)); return upb_msgdef_itof(m, 4); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_SourceCodeInfo_f_location(const upb_msgdef *m) { assert(upbdefs_google_protobuf_SourceCodeInfo_is(m)); return upb_msgdef_itof(m, 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_UninterpretedOption_NamePart_f_is_extension(const upb_msgdef *m) { assert(upbdefs_google_protobuf_UninterpretedOption_NamePart_is(m)); return upb_msgdef_itof(m, 2); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_UninterpretedOption_NamePart_f_name_part(const upb_msgdef *m) { assert(upbdefs_google_protobuf_UninterpretedOption_NamePart_is(m)); return upb_msgdef_itof(m, 1); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_UninterpretedOption_f_aggregate_value(const upb_msgdef *m) { assert(upbdefs_google_protobuf_UninterpretedOption_is(m)); return upb_msgdef_itof(m, 8); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_UninterpretedOption_f_double_value(const upb_msgdef *m) { assert(upbdefs_google_protobuf_UninterpretedOption_is(m)); return upb_msgdef_itof(m, 6); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_UninterpretedOption_f_identifier_value(const upb_msgdef *m) { assert(upbdefs_google_protobuf_UninterpretedOption_is(m)); return upb_msgdef_itof(m, 3); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_UninterpretedOption_f_name(const upb_msgdef *m) { assert(upbdefs_google_protobuf_UninterpretedOption_is(m)); return upb_msgdef_itof(m, 2); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_UninterpretedOption_f_negative_int_value(const upb_msgdef *m) { assert(upbdefs_google_protobuf_UninterpretedOption_is(m)); return upb_msgdef_itof(m, 5); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_UninterpretedOption_f_positive_int_value(const upb_msgdef *m) { assert(upbdefs_google_protobuf_UninterpretedOption_is(m)); return upb_msgdef_itof(m, 4); }
+UPB_INLINE const upb_fielddef *upbdefs_google_protobuf_UninterpretedOption_f_string_value(const upb_msgdef *m) { assert(upbdefs_google_protobuf_UninterpretedOption_is(m)); return upb_msgdef_itof(m, 7); }
UPB_END_EXTERN_C
@@ -6752,277 +6966,360 @@ UPB_END_EXTERN_C
namespace upbdefs {
namespace google {
namespace protobuf {
-namespace descriptor {
-inline upb::reffed_ptr<const upb::SymbolTable> SymbolTable() {
- const upb::SymbolTable* s = upbdefs_google_protobuf_descriptor(&s);
- return upb::reffed_ptr<const upb::SymbolTable>(s, &s);
-}
-} /* namespace descriptor */
-} /* namespace protobuf */
-} /* namespace google */
-#define RETURN_REFFED(type, func) \
- const type* obj = func(upbdefs::google::protobuf::descriptor::SymbolTable().get()); \
- return upb::reffed_ptr<const type>(obj);
+class DescriptorProto : public ::upb::reffed_ptr<const ::upb::MessageDef> {
+ public:
+ DescriptorProto(const ::upb::MessageDef* m, const void *ref_donor = NULL)
+ : reffed_ptr(m, ref_donor) {
+ assert(upbdefs_google_protobuf_DescriptorProto_is(m));
+ }
-namespace google {
-namespace protobuf {
-namespace DescriptorProto {
-inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_DescriptorProto) }
-inline upb::reffed_ptr<const upb::FieldDef> enum_type() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_DescriptorProto_enum_type) }
-inline upb::reffed_ptr<const upb::FieldDef> extension() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_DescriptorProto_extension) }
-inline upb::reffed_ptr<const upb::FieldDef> extension_range() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_DescriptorProto_extension_range) }
-inline upb::reffed_ptr<const upb::FieldDef> field() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_DescriptorProto_field) }
-inline upb::reffed_ptr<const upb::FieldDef> name() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_DescriptorProto_name) }
-inline upb::reffed_ptr<const upb::FieldDef> nested_type() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_DescriptorProto_nested_type) }
-inline upb::reffed_ptr<const upb::FieldDef> options() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_DescriptorProto_options) }
-} /* namespace DescriptorProto */
-} /* namespace protobuf */
-} /* namespace google */
+ static DescriptorProto get() {
+ const ::upb::MessageDef* m = upbdefs_google_protobuf_DescriptorProto_get(&m);
+ return DescriptorProto(m, &m);
+ }
-namespace google {
-namespace protobuf {
-namespace DescriptorProto {
-namespace ExtensionRange {
-inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_DescriptorProto_ExtensionRange) }
-inline upb::reffed_ptr<const upb::FieldDef> end() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_DescriptorProto_ExtensionRange_end) }
-inline upb::reffed_ptr<const upb::FieldDef> start() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_DescriptorProto_ExtensionRange_start) }
-} /* namespace ExtensionRange */
-} /* namespace DescriptorProto */
-} /* namespace protobuf */
-} /* namespace google */
+ class ExtensionRange : public ::upb::reffed_ptr<const ::upb::MessageDef> {
+ public:
+ ExtensionRange(const ::upb::MessageDef* m, const void *ref_donor = NULL)
+ : reffed_ptr(m, ref_donor) {
+ assert(upbdefs_google_protobuf_DescriptorProto_ExtensionRange_is(m));
+ }
-namespace google {
-namespace protobuf {
-namespace EnumDescriptorProto {
-inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_EnumDescriptorProto) }
-inline upb::reffed_ptr<const upb::FieldDef> name() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_EnumDescriptorProto_name) }
-inline upb::reffed_ptr<const upb::FieldDef> options() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_EnumDescriptorProto_options) }
-inline upb::reffed_ptr<const upb::FieldDef> value() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_EnumDescriptorProto_value) }
-} /* namespace EnumDescriptorProto */
-} /* namespace protobuf */
-} /* namespace google */
+ static ExtensionRange get() {
+ const ::upb::MessageDef* m = upbdefs_google_protobuf_DescriptorProto_ExtensionRange_get(&m);
+ return ExtensionRange(m, &m);
+ }
+ };
-namespace google {
-namespace protobuf {
-namespace EnumOptions {
-inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_EnumOptions) }
-inline upb::reffed_ptr<const upb::FieldDef> allow_alias() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_EnumOptions_allow_alias) }
-inline upb::reffed_ptr<const upb::FieldDef> uninterpreted_option() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_EnumOptions_uninterpreted_option) }
-} /* namespace EnumOptions */
-} /* namespace protobuf */
-} /* namespace google */
+ class ReservedRange : public ::upb::reffed_ptr<const ::upb::MessageDef> {
+ public:
+ ReservedRange(const ::upb::MessageDef* m, const void *ref_donor = NULL)
+ : reffed_ptr(m, ref_donor) {
+ assert(upbdefs_google_protobuf_DescriptorProto_ReservedRange_is(m));
+ }
-namespace google {
-namespace protobuf {
-namespace EnumValueDescriptorProto {
-inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_EnumValueDescriptorProto) }
-inline upb::reffed_ptr<const upb::FieldDef> name() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_EnumValueDescriptorProto_name) }
-inline upb::reffed_ptr<const upb::FieldDef> number() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_EnumValueDescriptorProto_number) }
-inline upb::reffed_ptr<const upb::FieldDef> options() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_EnumValueDescriptorProto_options) }
-} /* namespace EnumValueDescriptorProto */
-} /* namespace protobuf */
-} /* namespace google */
+ static ReservedRange get() {
+ const ::upb::MessageDef* m = upbdefs_google_protobuf_DescriptorProto_ReservedRange_get(&m);
+ return ReservedRange(m, &m);
+ }
+ };
+};
-namespace google {
-namespace protobuf {
-namespace EnumValueOptions {
-inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_EnumValueOptions) }
-inline upb::reffed_ptr<const upb::FieldDef> uninterpreted_option() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_EnumValueOptions_uninterpreted_option) }
-} /* namespace EnumValueOptions */
-} /* namespace protobuf */
-} /* namespace google */
+class EnumDescriptorProto : public ::upb::reffed_ptr<const ::upb::MessageDef> {
+ public:
+ EnumDescriptorProto(const ::upb::MessageDef* m, const void *ref_donor = NULL)
+ : reffed_ptr(m, ref_donor) {
+ assert(upbdefs_google_protobuf_EnumDescriptorProto_is(m));
+ }
-namespace google {
-namespace protobuf {
-namespace FieldDescriptorProto {
-inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_FieldDescriptorProto) }
-inline upb::reffed_ptr<const upb::FieldDef> default_value() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FieldDescriptorProto_default_value) }
-inline upb::reffed_ptr<const upb::FieldDef> extendee() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FieldDescriptorProto_extendee) }
-inline upb::reffed_ptr<const upb::FieldDef> label() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FieldDescriptorProto_label) }
-inline upb::reffed_ptr<const upb::FieldDef> name() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FieldDescriptorProto_name) }
-inline upb::reffed_ptr<const upb::FieldDef> number() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FieldDescriptorProto_number) }
-inline upb::reffed_ptr<const upb::FieldDef> options() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FieldDescriptorProto_options) }
-inline upb::reffed_ptr<const upb::FieldDef> type() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FieldDescriptorProto_type) }
-inline upb::reffed_ptr<const upb::FieldDef> type_name() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FieldDescriptorProto_type_name) }
-inline upb::reffed_ptr<const upb::EnumDef> Label() { RETURN_REFFED(upb::EnumDef, upbdefs_google_protobuf_FieldDescriptorProto_Label) }
-inline upb::reffed_ptr<const upb::EnumDef> Type() { RETURN_REFFED(upb::EnumDef, upbdefs_google_protobuf_FieldDescriptorProto_Type) }
-} /* namespace FieldDescriptorProto */
-} /* namespace protobuf */
-} /* namespace google */
+ static EnumDescriptorProto get() {
+ const ::upb::MessageDef* m = upbdefs_google_protobuf_EnumDescriptorProto_get(&m);
+ return EnumDescriptorProto(m, &m);
+ }
+};
-namespace google {
-namespace protobuf {
-namespace FieldOptions {
-inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_FieldOptions) }
-inline upb::reffed_ptr<const upb::FieldDef> ctype() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FieldOptions_ctype) }
-inline upb::reffed_ptr<const upb::FieldDef> deprecated() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FieldOptions_deprecated) }
-inline upb::reffed_ptr<const upb::FieldDef> experimental_map_key() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FieldOptions_experimental_map_key) }
-inline upb::reffed_ptr<const upb::FieldDef> lazy() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FieldOptions_lazy) }
-inline upb::reffed_ptr<const upb::FieldDef> packed() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FieldOptions_packed) }
-inline upb::reffed_ptr<const upb::FieldDef> uninterpreted_option() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FieldOptions_uninterpreted_option) }
-inline upb::reffed_ptr<const upb::FieldDef> weak() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FieldOptions_weak) }
-inline upb::reffed_ptr<const upb::EnumDef> CType() { RETURN_REFFED(upb::EnumDef, upbdefs_google_protobuf_FieldOptions_CType) }
-} /* namespace FieldOptions */
-} /* namespace protobuf */
-} /* namespace google */
+class EnumOptions : public ::upb::reffed_ptr<const ::upb::MessageDef> {
+ public:
+ EnumOptions(const ::upb::MessageDef* m, const void *ref_donor = NULL)
+ : reffed_ptr(m, ref_donor) {
+ assert(upbdefs_google_protobuf_EnumOptions_is(m));
+ }
-namespace google {
-namespace protobuf {
-namespace FileDescriptorProto {
-inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_FileDescriptorProto) }
-inline upb::reffed_ptr<const upb::FieldDef> dependency() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileDescriptorProto_dependency) }
-inline upb::reffed_ptr<const upb::FieldDef> enum_type() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileDescriptorProto_enum_type) }
-inline upb::reffed_ptr<const upb::FieldDef> extension() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileDescriptorProto_extension) }
-inline upb::reffed_ptr<const upb::FieldDef> message_type() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileDescriptorProto_message_type) }
-inline upb::reffed_ptr<const upb::FieldDef> name() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileDescriptorProto_name) }
-inline upb::reffed_ptr<const upb::FieldDef> options() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileDescriptorProto_options) }
-inline upb::reffed_ptr<const upb::FieldDef> package() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileDescriptorProto_package) }
-inline upb::reffed_ptr<const upb::FieldDef> public_dependency() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileDescriptorProto_public_dependency) }
-inline upb::reffed_ptr<const upb::FieldDef> service() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileDescriptorProto_service) }
-inline upb::reffed_ptr<const upb::FieldDef> source_code_info() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileDescriptorProto_source_code_info) }
-inline upb::reffed_ptr<const upb::FieldDef> weak_dependency() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileDescriptorProto_weak_dependency) }
-} /* namespace FileDescriptorProto */
-} /* namespace protobuf */
-} /* namespace google */
+ static EnumOptions get() {
+ const ::upb::MessageDef* m = upbdefs_google_protobuf_EnumOptions_get(&m);
+ return EnumOptions(m, &m);
+ }
+};
-namespace google {
-namespace protobuf {
-namespace FileDescriptorSet {
-inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_FileDescriptorSet) }
-inline upb::reffed_ptr<const upb::FieldDef> file() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileDescriptorSet_file) }
-} /* namespace FileDescriptorSet */
-} /* namespace protobuf */
-} /* namespace google */
+class EnumValueDescriptorProto : public ::upb::reffed_ptr<const ::upb::MessageDef> {
+ public:
+ EnumValueDescriptorProto(const ::upb::MessageDef* m, const void *ref_donor = NULL)
+ : reffed_ptr(m, ref_donor) {
+ assert(upbdefs_google_protobuf_EnumValueDescriptorProto_is(m));
+ }
-namespace google {
-namespace protobuf {
-namespace FileOptions {
-inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_FileOptions) }
-inline upb::reffed_ptr<const upb::FieldDef> cc_generic_services() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileOptions_cc_generic_services) }
-inline upb::reffed_ptr<const upb::FieldDef> go_package() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileOptions_go_package) }
-inline upb::reffed_ptr<const upb::FieldDef> java_generate_equals_and_hash() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileOptions_java_generate_equals_and_hash) }
-inline upb::reffed_ptr<const upb::FieldDef> java_generic_services() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileOptions_java_generic_services) }
-inline upb::reffed_ptr<const upb::FieldDef> java_multiple_files() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileOptions_java_multiple_files) }
-inline upb::reffed_ptr<const upb::FieldDef> java_outer_classname() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileOptions_java_outer_classname) }
-inline upb::reffed_ptr<const upb::FieldDef> java_package() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileOptions_java_package) }
-inline upb::reffed_ptr<const upb::FieldDef> optimize_for() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileOptions_optimize_for) }
-inline upb::reffed_ptr<const upb::FieldDef> py_generic_services() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileOptions_py_generic_services) }
-inline upb::reffed_ptr<const upb::FieldDef> uninterpreted_option() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_FileOptions_uninterpreted_option) }
-inline upb::reffed_ptr<const upb::EnumDef> OptimizeMode() { RETURN_REFFED(upb::EnumDef, upbdefs_google_protobuf_FileOptions_OptimizeMode) }
-} /* namespace FileOptions */
-} /* namespace protobuf */
-} /* namespace google */
+ static EnumValueDescriptorProto get() {
+ const ::upb::MessageDef* m = upbdefs_google_protobuf_EnumValueDescriptorProto_get(&m);
+ return EnumValueDescriptorProto(m, &m);
+ }
+};
-namespace google {
-namespace protobuf {
-namespace MessageOptions {
-inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_MessageOptions) }
-inline upb::reffed_ptr<const upb::FieldDef> message_set_wire_format() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_MessageOptions_message_set_wire_format) }
-inline upb::reffed_ptr<const upb::FieldDef> no_standard_descriptor_accessor() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_MessageOptions_no_standard_descriptor_accessor) }
-inline upb::reffed_ptr<const upb::FieldDef> uninterpreted_option() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_MessageOptions_uninterpreted_option) }
-} /* namespace MessageOptions */
-} /* namespace protobuf */
-} /* namespace google */
+class EnumValueOptions : public ::upb::reffed_ptr<const ::upb::MessageDef> {
+ public:
+ EnumValueOptions(const ::upb::MessageDef* m, const void *ref_donor = NULL)
+ : reffed_ptr(m, ref_donor) {
+ assert(upbdefs_google_protobuf_EnumValueOptions_is(m));
+ }
-namespace google {
-namespace protobuf {
-namespace MethodDescriptorProto {
-inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_MethodDescriptorProto) }
-inline upb::reffed_ptr<const upb::FieldDef> input_type() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_MethodDescriptorProto_input_type) }
-inline upb::reffed_ptr<const upb::FieldDef> name() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_MethodDescriptorProto_name) }
-inline upb::reffed_ptr<const upb::FieldDef> options() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_MethodDescriptorProto_options) }
-inline upb::reffed_ptr<const upb::FieldDef> output_type() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_MethodDescriptorProto_output_type) }
-} /* namespace MethodDescriptorProto */
-} /* namespace protobuf */
-} /* namespace google */
+ static EnumValueOptions get() {
+ const ::upb::MessageDef* m = upbdefs_google_protobuf_EnumValueOptions_get(&m);
+ return EnumValueOptions(m, &m);
+ }
+};
-namespace google {
-namespace protobuf {
-namespace MethodOptions {
-inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_MethodOptions) }
-inline upb::reffed_ptr<const upb::FieldDef> uninterpreted_option() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_MethodOptions_uninterpreted_option) }
-} /* namespace MethodOptions */
-} /* namespace protobuf */
-} /* namespace google */
+class FieldDescriptorProto : public ::upb::reffed_ptr<const ::upb::MessageDef> {
+ public:
+ FieldDescriptorProto(const ::upb::MessageDef* m, const void *ref_donor = NULL)
+ : reffed_ptr(m, ref_donor) {
+ assert(upbdefs_google_protobuf_FieldDescriptorProto_is(m));
+ }
-namespace google {
-namespace protobuf {
-namespace ServiceDescriptorProto {
-inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_ServiceDescriptorProto) }
-inline upb::reffed_ptr<const upb::FieldDef> method() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_ServiceDescriptorProto_method) }
-inline upb::reffed_ptr<const upb::FieldDef> name() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_ServiceDescriptorProto_name) }
-inline upb::reffed_ptr<const upb::FieldDef> options() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_ServiceDescriptorProto_options) }
-} /* namespace ServiceDescriptorProto */
-} /* namespace protobuf */
-} /* namespace google */
+ static FieldDescriptorProto get() {
+ const ::upb::MessageDef* m = upbdefs_google_protobuf_FieldDescriptorProto_get(&m);
+ return FieldDescriptorProto(m, &m);
+ }
-namespace google {
-namespace protobuf {
-namespace ServiceOptions {
-inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_ServiceOptions) }
-inline upb::reffed_ptr<const upb::FieldDef> uninterpreted_option() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_ServiceOptions_uninterpreted_option) }
-} /* namespace ServiceOptions */
-} /* namespace protobuf */
-} /* namespace google */
+ class Label : public ::upb::reffed_ptr<const ::upb::EnumDef> {
+ public:
+ Label(const ::upb::EnumDef* e, const void *ref_donor = NULL)
+ : reffed_ptr(e, ref_donor) {
+ assert(upbdefs_google_protobuf_FieldDescriptorProto_Label_is(e));
+ }
+ static Label get() {
+ const ::upb::EnumDef* e = upbdefs_google_protobuf_FieldDescriptorProto_Label_get(&e);
+ return Label(e, &e);
+ }
+ };
-namespace google {
-namespace protobuf {
-namespace SourceCodeInfo {
-inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_SourceCodeInfo) }
-inline upb::reffed_ptr<const upb::FieldDef> location() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_SourceCodeInfo_location) }
-} /* namespace SourceCodeInfo */
-} /* namespace protobuf */
-} /* namespace google */
+ class Type : public ::upb::reffed_ptr<const ::upb::EnumDef> {
+ public:
+ Type(const ::upb::EnumDef* e, const void *ref_donor = NULL)
+ : reffed_ptr(e, ref_donor) {
+ assert(upbdefs_google_protobuf_FieldDescriptorProto_Type_is(e));
+ }
+ static Type get() {
+ const ::upb::EnumDef* e = upbdefs_google_protobuf_FieldDescriptorProto_Type_get(&e);
+ return Type(e, &e);
+ }
+ };
+};
-namespace google {
-namespace protobuf {
-namespace SourceCodeInfo {
-namespace Location {
-inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_SourceCodeInfo_Location) }
-inline upb::reffed_ptr<const upb::FieldDef> leading_comments() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_SourceCodeInfo_Location_leading_comments) }
-inline upb::reffed_ptr<const upb::FieldDef> path() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_SourceCodeInfo_Location_path) }
-inline upb::reffed_ptr<const upb::FieldDef> span() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_SourceCodeInfo_Location_span) }
-inline upb::reffed_ptr<const upb::FieldDef> trailing_comments() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_SourceCodeInfo_Location_trailing_comments) }
-} /* namespace Location */
-} /* namespace SourceCodeInfo */
-} /* namespace protobuf */
-} /* namespace google */
+class FieldOptions : public ::upb::reffed_ptr<const ::upb::MessageDef> {
+ public:
+ FieldOptions(const ::upb::MessageDef* m, const void *ref_donor = NULL)
+ : reffed_ptr(m, ref_donor) {
+ assert(upbdefs_google_protobuf_FieldOptions_is(m));
+ }
-namespace google {
-namespace protobuf {
-namespace UninterpretedOption {
-inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_UninterpretedOption) }
-inline upb::reffed_ptr<const upb::FieldDef> aggregate_value() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_UninterpretedOption_aggregate_value) }
-inline upb::reffed_ptr<const upb::FieldDef> double_value() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_UninterpretedOption_double_value) }
-inline upb::reffed_ptr<const upb::FieldDef> identifier_value() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_UninterpretedOption_identifier_value) }
-inline upb::reffed_ptr<const upb::FieldDef> name() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_UninterpretedOption_name) }
-inline upb::reffed_ptr<const upb::FieldDef> negative_int_value() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_UninterpretedOption_negative_int_value) }
-inline upb::reffed_ptr<const upb::FieldDef> positive_int_value() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_UninterpretedOption_positive_int_value) }
-inline upb::reffed_ptr<const upb::FieldDef> string_value() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_UninterpretedOption_string_value) }
-} /* namespace UninterpretedOption */
-} /* namespace protobuf */
-} /* namespace google */
+ static FieldOptions get() {
+ const ::upb::MessageDef* m = upbdefs_google_protobuf_FieldOptions_get(&m);
+ return FieldOptions(m, &m);
+ }
+
+ class CType : public ::upb::reffed_ptr<const ::upb::EnumDef> {
+ public:
+ CType(const ::upb::EnumDef* e, const void *ref_donor = NULL)
+ : reffed_ptr(e, ref_donor) {
+ assert(upbdefs_google_protobuf_FieldOptions_CType_is(e));
+ }
+ static CType get() {
+ const ::upb::EnumDef* e = upbdefs_google_protobuf_FieldOptions_CType_get(&e);
+ return CType(e, &e);
+ }
+ };
+
+ class JSType : public ::upb::reffed_ptr<const ::upb::EnumDef> {
+ public:
+ JSType(const ::upb::EnumDef* e, const void *ref_donor = NULL)
+ : reffed_ptr(e, ref_donor) {
+ assert(upbdefs_google_protobuf_FieldOptions_JSType_is(e));
+ }
+ static JSType get() {
+ const ::upb::EnumDef* e = upbdefs_google_protobuf_FieldOptions_JSType_get(&e);
+ return JSType(e, &e);
+ }
+ };
+};
+
+class FileDescriptorProto : public ::upb::reffed_ptr<const ::upb::MessageDef> {
+ public:
+ FileDescriptorProto(const ::upb::MessageDef* m, const void *ref_donor = NULL)
+ : reffed_ptr(m, ref_donor) {
+ assert(upbdefs_google_protobuf_FileDescriptorProto_is(m));
+ }
+
+ static FileDescriptorProto get() {
+ const ::upb::MessageDef* m = upbdefs_google_protobuf_FileDescriptorProto_get(&m);
+ return FileDescriptorProto(m, &m);
+ }
+};
+
+class FileDescriptorSet : public ::upb::reffed_ptr<const ::upb::MessageDef> {
+ public:
+ FileDescriptorSet(const ::upb::MessageDef* m, const void *ref_donor = NULL)
+ : reffed_ptr(m, ref_donor) {
+ assert(upbdefs_google_protobuf_FileDescriptorSet_is(m));
+ }
+
+ static FileDescriptorSet get() {
+ const ::upb::MessageDef* m = upbdefs_google_protobuf_FileDescriptorSet_get(&m);
+ return FileDescriptorSet(m, &m);
+ }
+};
+
+class FileOptions : public ::upb::reffed_ptr<const ::upb::MessageDef> {
+ public:
+ FileOptions(const ::upb::MessageDef* m, const void *ref_donor = NULL)
+ : reffed_ptr(m, ref_donor) {
+ assert(upbdefs_google_protobuf_FileOptions_is(m));
+ }
+
+ static FileOptions get() {
+ const ::upb::MessageDef* m = upbdefs_google_protobuf_FileOptions_get(&m);
+ return FileOptions(m, &m);
+ }
+
+ class OptimizeMode : public ::upb::reffed_ptr<const ::upb::EnumDef> {
+ public:
+ OptimizeMode(const ::upb::EnumDef* e, const void *ref_donor = NULL)
+ : reffed_ptr(e, ref_donor) {
+ assert(upbdefs_google_protobuf_FileOptions_OptimizeMode_is(e));
+ }
+ static OptimizeMode get() {
+ const ::upb::EnumDef* e = upbdefs_google_protobuf_FileOptions_OptimizeMode_get(&e);
+ return OptimizeMode(e, &e);
+ }
+ };
+};
+
+class MessageOptions : public ::upb::reffed_ptr<const ::upb::MessageDef> {
+ public:
+ MessageOptions(const ::upb::MessageDef* m, const void *ref_donor = NULL)
+ : reffed_ptr(m, ref_donor) {
+ assert(upbdefs_google_protobuf_MessageOptions_is(m));
+ }
+
+ static MessageOptions get() {
+ const ::upb::MessageDef* m = upbdefs_google_protobuf_MessageOptions_get(&m);
+ return MessageOptions(m, &m);
+ }
+};
+
+class MethodDescriptorProto : public ::upb::reffed_ptr<const ::upb::MessageDef> {
+ public:
+ MethodDescriptorProto(const ::upb::MessageDef* m, const void *ref_donor = NULL)
+ : reffed_ptr(m, ref_donor) {
+ assert(upbdefs_google_protobuf_MethodDescriptorProto_is(m));
+ }
+
+ static MethodDescriptorProto get() {
+ const ::upb::MessageDef* m = upbdefs_google_protobuf_MethodDescriptorProto_get(&m);
+ return MethodDescriptorProto(m, &m);
+ }
+};
+
+class MethodOptions : public ::upb::reffed_ptr<const ::upb::MessageDef> {
+ public:
+ MethodOptions(const ::upb::MessageDef* m, const void *ref_donor = NULL)
+ : reffed_ptr(m, ref_donor) {
+ assert(upbdefs_google_protobuf_MethodOptions_is(m));
+ }
+
+ static MethodOptions get() {
+ const ::upb::MessageDef* m = upbdefs_google_protobuf_MethodOptions_get(&m);
+ return MethodOptions(m, &m);
+ }
+};
+
+class OneofDescriptorProto : public ::upb::reffed_ptr<const ::upb::MessageDef> {
+ public:
+ OneofDescriptorProto(const ::upb::MessageDef* m, const void *ref_donor = NULL)
+ : reffed_ptr(m, ref_donor) {
+ assert(upbdefs_google_protobuf_OneofDescriptorProto_is(m));
+ }
+
+ static OneofDescriptorProto get() {
+ const ::upb::MessageDef* m = upbdefs_google_protobuf_OneofDescriptorProto_get(&m);
+ return OneofDescriptorProto(m, &m);
+ }
+};
+
+class ServiceDescriptorProto : public ::upb::reffed_ptr<const ::upb::MessageDef> {
+ public:
+ ServiceDescriptorProto(const ::upb::MessageDef* m, const void *ref_donor = NULL)
+ : reffed_ptr(m, ref_donor) {
+ assert(upbdefs_google_protobuf_ServiceDescriptorProto_is(m));
+ }
+
+ static ServiceDescriptorProto get() {
+ const ::upb::MessageDef* m = upbdefs_google_protobuf_ServiceDescriptorProto_get(&m);
+ return ServiceDescriptorProto(m, &m);
+ }
+};
+
+class ServiceOptions : public ::upb::reffed_ptr<const ::upb::MessageDef> {
+ public:
+ ServiceOptions(const ::upb::MessageDef* m, const void *ref_donor = NULL)
+ : reffed_ptr(m, ref_donor) {
+ assert(upbdefs_google_protobuf_ServiceOptions_is(m));
+ }
+
+ static ServiceOptions get() {
+ const ::upb::MessageDef* m = upbdefs_google_protobuf_ServiceOptions_get(&m);
+ return ServiceOptions(m, &m);
+ }
+};
+
+class SourceCodeInfo : public ::upb::reffed_ptr<const ::upb::MessageDef> {
+ public:
+ SourceCodeInfo(const ::upb::MessageDef* m, const void *ref_donor = NULL)
+ : reffed_ptr(m, ref_donor) {
+ assert(upbdefs_google_protobuf_SourceCodeInfo_is(m));
+ }
+
+ static SourceCodeInfo get() {
+ const ::upb::MessageDef* m = upbdefs_google_protobuf_SourceCodeInfo_get(&m);
+ return SourceCodeInfo(m, &m);
+ }
+
+ class Location : public ::upb::reffed_ptr<const ::upb::MessageDef> {
+ public:
+ Location(const ::upb::MessageDef* m, const void *ref_donor = NULL)
+ : reffed_ptr(m, ref_donor) {
+ assert(upbdefs_google_protobuf_SourceCodeInfo_Location_is(m));
+ }
+
+ static Location get() {
+ const ::upb::MessageDef* m = upbdefs_google_protobuf_SourceCodeInfo_Location_get(&m);
+ return Location(m, &m);
+ }
+ };
+};
+
+class UninterpretedOption : public ::upb::reffed_ptr<const ::upb::MessageDef> {
+ public:
+ UninterpretedOption(const ::upb::MessageDef* m, const void *ref_donor = NULL)
+ : reffed_ptr(m, ref_donor) {
+ assert(upbdefs_google_protobuf_UninterpretedOption_is(m));
+ }
+
+ static UninterpretedOption get() {
+ const ::upb::MessageDef* m = upbdefs_google_protobuf_UninterpretedOption_get(&m);
+ return UninterpretedOption(m, &m);
+ }
+
+ class NamePart : public ::upb::reffed_ptr<const ::upb::MessageDef> {
+ public:
+ NamePart(const ::upb::MessageDef* m, const void *ref_donor = NULL)
+ : reffed_ptr(m, ref_donor) {
+ assert(upbdefs_google_protobuf_UninterpretedOption_NamePart_is(m));
+ }
+
+ static NamePart get() {
+ const ::upb::MessageDef* m = upbdefs_google_protobuf_UninterpretedOption_NamePart_get(&m);
+ return NamePart(m, &m);
+ }
+ };
+};
-namespace google {
-namespace protobuf {
-namespace UninterpretedOption {
-namespace NamePart {
-inline upb::reffed_ptr<const upb::MessageDef> MessageDef() { RETURN_REFFED(upb::MessageDef, upbdefs_google_protobuf_UninterpretedOption_NamePart) }
-inline upb::reffed_ptr<const upb::FieldDef> is_extension() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_UninterpretedOption_NamePart_is_extension) }
-inline upb::reffed_ptr<const upb::FieldDef> name_part() { RETURN_REFFED(upb::FieldDef, upbdefs_google_protobuf_UninterpretedOption_NamePart_name_part) }
-} /* namespace NamePart */
-} /* namespace UninterpretedOption */
} /* namespace protobuf */
} /* namespace google */
-
} /* namespace upbdefs */
+#endif /* __cplusplus */
-#undef RETURN_REFFED
-#endif /* __cplusplus */
-
-#endif /* GOOGLE_PROTOBUF_DESCRIPTOR_UPB_H_ */
+#endif /* UPB_DESCRIPTOR_DESCRIPTOR_PROTO_UPB_H_ */
/*
** Internal-only definitions for the decoder.
*/
@@ -7030,7 +7327,6 @@ inline upb::reffed_ptr<const upb::FieldDef> name_part() { RETURN_REFFED(upb::Fie
#ifndef UPB_DECODER_INT_H_
#define UPB_DECODER_INT_H_
-#include <stdlib.h>
/*
** upb::pb::Decoder
**
@@ -7067,6 +7363,13 @@ UPB_DECLARE_TYPE(upb::pb::DecoderMethodOptions, upb_pbdecodermethodopts)
UPB_DECLARE_DERIVED_TYPE(upb::pb::DecoderMethod, upb::RefCounted,
upb_pbdecodermethod, upb_refcounted)
+/* The maximum number of bytes we are required to buffer internally between
+ * calls to the decoder. The value is 14: a 5 byte unknown tag plus ten-byte
+ * varint, less one because we are buffering an incomplete value.
+ *
+ * Should only be used by unit tests. */
+#define UPB_DECODER_MAX_RESIDUAL_BYTES 14
+
#ifdef __cplusplus
/* The parameters one uses to construct a DecoderMethod.
@@ -7123,7 +7426,7 @@ class upb::pb::DecoderMethod {
* constructed. This hint may be an overestimate for some build configurations.
* But if the decoder library is upgraded without recompiling the application,
* it may be an underestimate. */
-#define UPB_PB_DECODER_SIZE 4408
+#define UPB_PB_DECODER_SIZE 4416
#ifdef __cplusplus
@@ -7541,11 +7844,8 @@ struct upb_pbdecoder {
/* Overall stream offset of "buf." */
uint64_t bufstart_ofs;
- /* Buffer for residual bytes not parsed from the previous buffer.
- * The maximum number of residual bytes we require is 12; a five-byte
- * unknown tag plus an eight-byte value, less one because the value
- * is only a partial value. */
- char residual[12];
+ /* Buffer for residual bytes not parsed from the previous buffer. */
+ char residual[UPB_DECODER_MAX_RESIDUAL_BYTES];
char *residual_end;
/* Bytes of data that should be discarded from the input beore we start
@@ -7939,49 +8239,44 @@ inline reffed_ptr<const Handlers> Encoder::NewHandlers(
#include <stdbool.h>
#ifdef __cplusplus
+#include <vector>
+
extern "C" {
#endif
-/* Loads all defs from the given protobuf binary descriptor, setting default
- * accessors and a default layout on all messages. The caller owns the
- * returned array of defs, which will be of length *n. On error NULL is
- * returned and status is set (if non-NULL). */
-upb_def **upb_load_defs_from_descriptor(const char *str, size_t len, int *n,
- void *owner, upb_status *status);
-
-/* Like the previous but also adds the loaded defs to the given symtab. */
-bool upb_load_descriptor_into_symtab(upb_symtab *symtab, const char *str,
- size_t len, upb_status *status);
-
-/* Like the previous but also reads the descriptor from the given filename. */
-bool upb_load_descriptor_file_into_symtab(upb_symtab *symtab, const char *fname,
- upb_status *status);
-
-/* Reads the given filename into a character string, returning NULL if there
- * was an error. */
-char *upb_readfile(const char *filename, size_t *len);
+/* Loads a binary descriptor and returns a NULL-terminated array of unfrozen
+ * filedefs. The caller owns the returned array, which must be freed with
+ * upb_gfree(). */
+upb_filedef **upb_loaddescriptor(const char *buf, size_t n, const void *owner,
+ upb_status *status);
#ifdef __cplusplus
} /* extern "C" */
namespace upb {
-/* All routines that load descriptors expect the descriptor to be a
- * FileDescriptorSet. */
-inline bool LoadDescriptorFileIntoSymtab(SymbolTable* s, const char *fname,
- Status* status) {
- return upb_load_descriptor_file_into_symtab(s, fname, status);
-}
+inline bool LoadDescriptor(const char* buf, size_t n, Status* status,
+ std::vector<reffed_ptr<FileDef> >* files) {
+ FileDef** parsed_files = upb_loaddescriptor(buf, n, &parsed_files, status);
-inline bool LoadDescriptorIntoSymtab(SymbolTable* s, const char* str,
- size_t len, Status* status) {
- return upb_load_descriptor_into_symtab(s, str, len, status);
+ if (parsed_files) {
+ FileDef** p = parsed_files;
+ while (*p) {
+ files->push_back(reffed_ptr<FileDef>(*p, &parsed_files));
+ ++p;
+ }
+ free(parsed_files);
+ return true;
+ } else {
+ return false;
+ }
}
/* Templated so it can accept both string and std::string. */
template <typename T>
-bool LoadDescriptorIntoSymtab(SymbolTable* s, const T& desc, Status* status) {
- return upb_load_descriptor_into_symtab(s, desc.c_str(), desc.size(), status);
+bool LoadDescriptor(const T& desc, Status* status,
+ std::vector<reffed_ptr<FileDef> >* files) {
+ return LoadDescriptor(desc.c_str(), desc.size(), status, files);
}
} /* namespace upb */
@@ -8083,11 +8378,14 @@ inline reffed_ptr<const Handlers> TextPrinter::NewHandlers(
namespace upb {
namespace json {
class Parser;
+class ParserMethod;
} /* namespace json */
} /* namespace upb */
#endif
UPB_DECLARE_TYPE(upb::json::Parser, upb_json_parser)
+UPB_DECLARE_DERIVED_TYPE(upb::json::ParserMethod, upb::RefCounted,
+ upb_json_parsermethod, upb_refcounted)
/* upb::json::Parser **********************************************************/
@@ -8095,7 +8393,7 @@ UPB_DECLARE_TYPE(upb::json::Parser, upb_json_parser)
* constructed. This hint may be an overestimate for some build configurations.
* But if the parser library is upgraded without recompiling the application,
* it may be an underestimate. */
-#define UPB_JSON_PARSER_SIZE 3704
+#define UPB_JSON_PARSER_SIZE 4112
#ifdef __cplusplus
@@ -8103,7 +8401,8 @@ UPB_DECLARE_TYPE(upb::json::Parser, upb_json_parser)
* sink. */
class upb::json::Parser {
public:
- static Parser* Create(Environment* env, Sink* output);
+ static Parser* Create(Environment* env, const ParserMethod* method,
+ Sink* output);
BytesSink* input();
@@ -8111,25 +8410,72 @@ class upb::json::Parser {
UPB_DISALLOW_POD_OPS(Parser, upb::json::Parser)
};
+class upb::json::ParserMethod {
+ public:
+ /* Include base methods from upb::ReferenceCounted. */
+ UPB_REFCOUNTED_CPPMETHODS
+
+ /* Returns handlers for parsing according to the specified schema. */
+ static reffed_ptr<const ParserMethod> New(const upb::MessageDef* md);
+
+ /* The destination handlers that are statically bound to this method.
+ * This method is only capable of outputting to a sink that uses these
+ * handlers. */
+ const Handlers* dest_handlers() const;
+
+ /* The input handlers for this decoder method. */
+ const BytesHandler* input_handler() const;
+
+ private:
+ UPB_DISALLOW_POD_OPS(ParserMethod, upb::json::ParserMethod)
+};
+
#endif
UPB_BEGIN_EXTERN_C
-upb_json_parser *upb_json_parser_create(upb_env *e, upb_sink *output);
+upb_json_parser* upb_json_parser_create(upb_env* e,
+ const upb_json_parsermethod* m,
+ upb_sink* output);
upb_bytessink *upb_json_parser_input(upb_json_parser *p);
+upb_json_parsermethod* upb_json_parsermethod_new(const upb_msgdef* md,
+ const void* owner);
+const upb_handlers *upb_json_parsermethod_desthandlers(
+ const upb_json_parsermethod *m);
+const upb_byteshandler *upb_json_parsermethod_inputhandler(
+ const upb_json_parsermethod *m);
+
+/* Include refcounted methods like upb_json_parsermethod_ref(). */
+UPB_REFCOUNTED_CMETHODS(upb_json_parsermethod, upb_json_parsermethod_upcast)
+
UPB_END_EXTERN_C
#ifdef __cplusplus
namespace upb {
namespace json {
-inline Parser* Parser::Create(Environment* env, Sink* output) {
- return upb_json_parser_create(env, output);
+inline Parser* Parser::Create(Environment* env, const ParserMethod* method,
+ Sink* output) {
+ return upb_json_parser_create(env, method, output);
}
inline BytesSink* Parser::input() {
return upb_json_parser_input(this);
}
+
+inline const Handlers* ParserMethod::dest_handlers() const {
+ return upb_json_parsermethod_desthandlers(this);
+}
+inline const BytesHandler* ParserMethod::input_handler() const {
+ return upb_json_parsermethod_inputhandler(this);
+}
+/* static */
+inline reffed_ptr<const ParserMethod> ParserMethod::New(
+ const MessageDef* md) {
+ const upb_json_parsermethod *m = upb_json_parsermethod_new(md, &m);
+ return reffed_ptr<const ParserMethod>(m, &m);
+}
+
} /* namespace json */
} /* namespace upb */
@@ -8160,7 +8506,7 @@ UPB_DECLARE_TYPE(upb::json::Printer, upb_json_printer)
/* upb::json::Printer *********************************************************/
-#define UPB_JSON_PRINTER_SIZE 168
+#define UPB_JSON_PRINTER_SIZE 176
#ifdef __cplusplus
@@ -8173,8 +8519,12 @@ class upb::json::Printer {
/* The input to the printer. */
Sink* input();
- /* Returns handlers for printing according to the specified schema. */
- static reffed_ptr<const Handlers> NewHandlers(const upb::MessageDef* md);
+ /* Returns handlers for printing according to the specified schema.
+ * If preserve_proto_fieldnames is true, the output JSON will use the
+ * original .proto field names (ie. {"my_field":3}) instead of using
+ * camelCased names, which is the default: (eg. {"myField":3}). */
+ static reffed_ptr<const Handlers> NewHandlers(const upb::MessageDef* md,
+ bool preserve_proto_fieldnames);
static const size_t kSize = UPB_JSON_PRINTER_SIZE;
@@ -8191,6 +8541,7 @@ upb_json_printer *upb_json_printer_create(upb_env *e, const upb_handlers *h,
upb_bytessink *output);
upb_sink *upb_json_printer_input(upb_json_printer *p);
const upb_handlers *upb_json_printer_newhandlers(const upb_msgdef *md,
+ bool preserve_fieldnames,
const void *owner);
UPB_END_EXTERN_C
@@ -8205,8 +8556,9 @@ inline Printer* Printer::Create(Environment* env, const upb::Handlers* handlers,
}
inline Sink* Printer::input() { return upb_json_printer_input(this); }
inline reffed_ptr<const Handlers> Printer::NewHandlers(
- const upb::MessageDef *md) {
- const Handlers* h = upb_json_printer_newhandlers(md, &h);
+ const upb::MessageDef *md, bool preserve_proto_fieldnames) {
+ const Handlers* h = upb_json_printer_newhandlers(
+ md, preserve_proto_fieldnames, &h);
return reffed_ptr<const Handlers>(h, &h);
}
} /* namespace json */
diff --git a/ruby/google-protobuf.gemspec b/ruby/google-protobuf.gemspec
index 3d53209d..286d8fe3 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.0.0.alpha.4.0"
+ s.version = "3.0.0"
s.licenses = ["BSD"]
s.summary = "Protocol Buffers"
s.description = "Protocol Buffers are Google's data interchange format."
@@ -8,12 +8,13 @@ Gem::Specification.new do |s|
s.authors = ["Protobuf Authors"]
s.email = "protobuf@googlegroups.com"
s.require_paths = ["lib"]
- s.files = `git ls-files -z`.split("\x0").find_all{|f| f =~ /lib\/.+\.rb/}
- unless RUBY_PLATFORM == "java"
- s.files += `git ls-files "*.c" "*.h" extconf.rb Makefile`.split
- s.extensions= ["ext/google/protobuf_c/extconf.rb"]
- else
+ s.files = Dir.glob('lib/**/*.rb')
+ if RUBY_PLATFORM == "java"
s.files += ["lib/google/protobuf_java.jar"]
+ else
+ s.files += Dir.glob('ext/**/*')
+ s.extensions= ["ext/google/protobuf_c/extconf.rb"]
+ s.add_development_dependency "rake-compiler-dock"
end
s.test_files = ["tests/basic.rb",
"tests/stress.rb",
diff --git a/ruby/lib/google/protobuf.rb b/ruby/lib/google/protobuf.rb
index f0eb6268..62bdd1bf 100644
--- a/ruby/lib/google/protobuf.rb
+++ b/ruby/lib/google/protobuf.rb
@@ -44,7 +44,11 @@ if RUBY_PLATFORM == "java"
require 'json'
require 'google/protobuf_java'
else
- require 'google/protobuf_c'
+ begin
+ require "google/#{RUBY_VERSION.sub(/\.\d$/, '')}/protobuf_c"
+ rescue LoadError
+ require 'google/protobuf_c'
+ end
end
require 'google/protobuf/repeated_field'
diff --git a/ruby/lib/google/protobuf/repeated_field.rb b/ruby/lib/google/protobuf/repeated_field.rb
index 16c843c0..831e0320 100644
--- a/ruby/lib/google/protobuf/repeated_field.rb
+++ b/ruby/lib/google/protobuf/repeated_field.rb
@@ -69,8 +69,8 @@ module Google
# relationship explicit instead of implicit
def_delegators :to_ary,
:&, :*, :-, :'<=>',
- :assoc, :bsearch, :combination, :compact, :count, :cycle,
- :drop, :drop_while, :eql?, :fetch, :find_index, :flatten,
+ :assoc, :bsearch, :bsearch_index, :combination, :compact, :count,
+ :cycle, :dig, :drop, :drop_while, :eql?, :fetch, :find_index, :flatten,
:include?, :index, :inspect, :join,
:pack, :permutation, :product, :pretty_print, :pretty_print_cycle,
:rassoc, :repeated_combination, :repeated_permutation, :reverse,
@@ -173,7 +173,7 @@ module Google
external_enumerator.each_with_index do |val, i|
result = yield(val)
results << result
- #nil means no change occured from yield; usually occurs when #to_a is called
+ #nil means no change occurred from yield; usually occurs when #to_a is called
if result
repeated_field[i] = result if result != val
end
diff --git a/ruby/lib/google/protobuf/well_known_types.rb b/ruby/lib/google/protobuf/well_known_types.rb
new file mode 100644
index 00000000..547de874
--- /dev/null
+++ b/ruby/lib/google/protobuf/well_known_types.rb
@@ -0,0 +1,212 @@
+#!/usr/bin/ruby
+# 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.
+
+require 'google/protobuf/any_pb'
+require 'google/protobuf/duration_pb'
+require 'google/protobuf/field_mask_pb'
+require 'google/protobuf/struct_pb'
+require 'google/protobuf/timestamp_pb'
+
+module Google
+ module Protobuf
+
+ Any.class_eval do
+ def pack(msg, type_url_prefix='type.googleapis.com/')
+ if type_url_prefix.empty? or type_url_prefix[-1] != '/' then
+ self.type_url = "#{type_url_prefix}/#{msg.class.descriptor.name}"
+ else
+ self.type_url = "#{type_url_prefix}#{msg.class.descriptor.name}"
+ end
+ self.value = msg.to_proto
+ end
+
+ def unpack(klass)
+ if self.is(klass) then
+ klass.decode(self.value)
+ else
+ nil
+ end
+ end
+
+ def type_name
+ return self.type_url.split("/")[-1]
+ end
+
+ def is(klass)
+ return self.type_name == klass.descriptor.name
+ end
+ end
+
+ Timestamp.class_eval do
+ def to_time
+ Time.at(self.to_f)
+ end
+
+ def from_time(time)
+ self.seconds = time.to_i
+ self.nanos = time.nsec
+ end
+
+ def to_i
+ self.seconds
+ end
+
+ def to_f
+ self.seconds + (self.nanos.to_f / 1_000_000_000)
+ end
+ end
+
+ Duration.class_eval do
+ def to_f
+ self.seconds + (self.nanos.to_f / 1_000_000_000)
+ end
+ end
+
+ class UnexpectedStructType < Google::Protobuf::Error; end
+
+ Value.class_eval do
+ def to_ruby(recursive = false)
+ case self.kind
+ when :struct_value
+ if recursive
+ self.struct_value.to_h
+ else
+ self.struct_value
+ end
+ when :list_value
+ if recursive
+ self.list_value.to_a
+ else
+ self.list_value
+ end
+ when :null_value
+ nil
+ when :number_value
+ self.number_value
+ when :string_value
+ self.string_value
+ when :bool_value
+ self.bool_value
+ else
+ raise UnexpectedStructType
+ end
+ end
+
+ def from_ruby(value)
+ case value
+ when NilClass
+ self.null_value = 0
+ when Numeric
+ self.number_value = value
+ when String
+ self.string_value = value
+ when TrueClass
+ self.bool_value = true
+ when FalseClass
+ self.bool_value = false
+ when Struct
+ self.struct_value = value
+ when Hash
+ self.struct_value = Struct.from_hash(value)
+ when ListValue
+ self.list_value = value
+ when Array
+ self.list_value = ListValue.from_a(value)
+ else
+ raise UnexpectedStructType
+ end
+ end
+ end
+
+ Struct.class_eval do
+ def [](key)
+ self.fields[key].to_ruby
+ end
+
+ def []=(key, value)
+ unless key.is_a?(String)
+ raise UnexpectedStructType, "Struct keys must be strings."
+ end
+ self.fields[key] ||= Google::Protobuf::Value.new
+ self.fields[key].from_ruby(value)
+ end
+
+ def to_h
+ ret = {}
+ self.fields.each { |key, val| ret[key] = val.to_ruby(true) }
+ ret
+ end
+
+ def self.from_hash(hash)
+ ret = Struct.new
+ hash.each { |key, val| ret[key] = val }
+ ret
+ end
+ end
+
+ ListValue.class_eval do
+ include Enumerable
+
+ def length
+ self.values.length
+ end
+
+ def [](index)
+ self.values[index].to_ruby
+ end
+
+ def []=(index, value)
+ self.values[index].from_ruby(value)
+ end
+
+ def <<(value)
+ wrapper = Google::Protobuf::Value.new
+ wrapper.from_ruby(value)
+ self.values << wrapper
+ end
+
+ def each
+ self.values.each { |x| yield(x.to_ruby) }
+ end
+
+ def to_a
+ self.values.map { |x| x.to_ruby(true) }
+ end
+
+ def self.from_a(arr)
+ ret = ListValue.new
+ arr.each { |val| ret << val }
+ ret
+ end
+ end
+
+ end
+end
diff --git a/ruby/pom.xml b/ruby/pom.xml
index 4cbd6d30..99e8449b 100644
--- a/ruby/pom.xml
+++ b/ruby/pom.xml
@@ -86,7 +86,7 @@
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
- <version>3.0.0-alpha-3</version>
+ <version>3.0.0-beta-4</version>
</dependency>
</dependencies>
</project>
diff --git a/ruby/src/main/java/com/google/protobuf/jruby/RubyMap.java b/ruby/src/main/java/com/google/protobuf/jruby/RubyMap.java
index 2d4c03b5..3adaa2a8 100644
--- a/ruby/src/main/java/com/google/protobuf/jruby/RubyMap.java
+++ b/ruby/src/main/java/com/google/protobuf/jruby/RubyMap.java
@@ -148,8 +148,8 @@ public class RubyMap extends RubyObject {
*/
@JRubyMethod(name = "[]=")
public IRubyObject indexSet(ThreadContext context, IRubyObject key, IRubyObject value) {
- Utils.checkType(context, keyType, key, (RubyModule) valueTypeClass);
- Utils.checkType(context, valueType, value, (RubyModule) valueTypeClass);
+ key = Utils.checkType(context, keyType, key, (RubyModule) valueTypeClass);
+ value = Utils.checkType(context, valueType, value, (RubyModule) valueTypeClass);
IRubyObject symbol;
if (valueType == Descriptors.FieldDescriptor.Type.ENUM &&
Utils.isRubyNum(value) &&
diff --git a/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java b/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java
index 547ab22c..462f8a69 100644
--- a/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java
+++ b/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java
@@ -86,14 +86,14 @@ public class RubyMessage extends RubyObject {
if (Utils.isMapEntry(fieldDescriptor)) {
if (!(value instanceof RubyHash))
- throw runtime.newArgumentError("Expected Hash object as initializer value for map field.");
+ throw runtime.newArgumentError("Expected Hash object as initializer value for map field '" + key.asJavaString() + "'.");
final RubyMap map = newMapForField(context, fieldDescriptor);
map.mergeIntoSelf(context, value);
maps.put(fieldDescriptor, map);
} else if (fieldDescriptor.isRepeated()) {
if (!(value instanceof RubyArray))
- throw runtime.newTypeError("Expected array as initializer var for repeated field.");
+ throw runtime.newArgumentError("Expected array as initializer value for repeated field '" + key.asJavaString() + "'.");
RubyRepeatedField repeatedField = rubyToRepeatedField(context, fieldDescriptor, value);
addRepeatedField(fieldDescriptor, repeatedField);
} else {
@@ -217,6 +217,9 @@ public class RubyMessage extends RubyObject {
RubyDescriptor rubyDescriptor = (RubyDescriptor) getDescriptor(context, metaClass);
IRubyObject oneofDescriptor = rubyDescriptor.lookupOneof(context, args[0]);
if (oneofDescriptor.isNil()) {
+ if (!hasField(args[0])) {
+ return Helpers.invokeSuper(context, this, metaClass, "method_missing", args, Block.NULL_BLOCK);
+ }
return index(context, args[0]);
}
RubyOneofDescriptor rubyOneofDescriptor = (RubyOneofDescriptor) oneofDescriptor;
@@ -233,6 +236,10 @@ public class RubyMessage extends RubyObject {
if (field.end_with_p(context, equalSign).isTrue()) {
field.chomp_bang(context, equalSign);
}
+
+ if (!hasField(field)) {
+ return Helpers.invokeSuper(context, this, metaClass, "method_missing", args, Block.NULL_BLOCK);
+ }
return indexSet(context, field, args[1]);
}
}
@@ -435,6 +442,11 @@ public class RubyMessage extends RubyObject {
return ret;
}
+ private boolean hasField(IRubyObject fieldName) {
+ String nameStr = fieldName.asJavaString();
+ return this.descriptor.findFieldByName(Utils.escapeIdentifier(nameStr)) != null;
+ }
+
private void checkRepeatedFieldType(ThreadContext context, IRubyObject value,
Descriptors.FieldDescriptor fieldDescriptor) {
Ruby runtime = context.runtime;
@@ -492,7 +504,7 @@ public class RubyMessage extends RubyObject {
break;
case BYTES:
case STRING:
- Utils.validateStringEncoding(context.runtime, fieldDescriptor.getType(), value);
+ Utils.validateStringEncoding(context, fieldDescriptor.getType(), value);
RubyString str = (RubyString) value;
switch (fieldDescriptor.getType()) {
case BYTES:
@@ -580,13 +592,17 @@ public class RubyMessage extends RubyObject {
protected IRubyObject getField(ThreadContext context, Descriptors.FieldDescriptor fieldDescriptor) {
Descriptors.OneofDescriptor oneofDescriptor = fieldDescriptor.getContainingOneof();
if (oneofDescriptor != null) {
- if (oneofCases.containsKey(oneofDescriptor)) {
- if (oneofCases.get(oneofDescriptor) != fieldDescriptor)
- return context.runtime.getNil();
+ if (oneofCases.get(oneofDescriptor) == fieldDescriptor) {
return fields.get(fieldDescriptor);
} else {
Descriptors.FieldDescriptor oneofCase = builder.getOneofFieldDescriptor(oneofDescriptor);
- if (oneofCase != fieldDescriptor) return context.runtime.getNil();
+ if (oneofCase != fieldDescriptor) {
+ if (fieldDescriptor.getType() == Descriptors.FieldDescriptor.Type.MESSAGE) {
+ return context.runtime.getNil();
+ } else {
+ return wrapField(context, fieldDescriptor, fieldDescriptor.getDefaultValue());
+ }
+ }
IRubyObject value = wrapField(context, oneofCase, builder.getField(oneofCase));
fields.put(fieldDescriptor, value);
return value;
@@ -679,7 +695,7 @@ public class RubyMessage extends RubyObject {
}
}
if (addValue) {
- Utils.checkType(context, fieldType, value, (RubyModule) typeClass);
+ value = Utils.checkType(context, fieldType, value, (RubyModule) typeClass);
this.fields.put(fieldDescriptor, value);
} else {
this.fields.remove(fieldDescriptor);
diff --git a/ruby/src/main/java/com/google/protobuf/jruby/RubyRepeatedField.java b/ruby/src/main/java/com/google/protobuf/jruby/RubyRepeatedField.java
index 946f9e74..ae2907a9 100644
--- a/ruby/src/main/java/com/google/protobuf/jruby/RubyRepeatedField.java
+++ b/ruby/src/main/java/com/google/protobuf/jruby/RubyRepeatedField.java
@@ -110,7 +110,7 @@ public class RubyRepeatedField extends RubyObject {
@JRubyMethod(name = "[]=")
public IRubyObject indexSet(ThreadContext context, IRubyObject index, IRubyObject value) {
int arrIndex = normalizeArrayIndex(index);
- Utils.checkType(context, fieldType, value, (RubyModule) typeClass);
+ value = Utils.checkType(context, fieldType, value, (RubyModule) typeClass);
IRubyObject defaultValue = defaultValue(context);
for (int i = this.storage.size(); i < arrIndex; i++) {
this.storage.set(i, defaultValue);
@@ -166,7 +166,7 @@ public class RubyRepeatedField extends RubyObject {
public IRubyObject push(ThreadContext context, IRubyObject value) {
if (!(fieldType == Descriptors.FieldDescriptor.Type.MESSAGE &&
value == context.runtime.getNil())) {
- Utils.checkType(context, fieldType, value, (RubyModule) typeClass);
+ value = Utils.checkType(context, fieldType, value, (RubyModule) typeClass);
}
this.storage.add(value);
return this.storage;
diff --git a/ruby/src/main/java/com/google/protobuf/jruby/Utils.java b/ruby/src/main/java/com/google/protobuf/jruby/Utils.java
index 596a0979..f199feb9 100644
--- a/ruby/src/main/java/com/google/protobuf/jruby/Utils.java
+++ b/ruby/src/main/java/com/google/protobuf/jruby/Utils.java
@@ -64,8 +64,8 @@ public class Utils {
return context.runtime.newSymbol(typeName.replace("TYPE_", "").toLowerCase());
}
- public static void checkType(ThreadContext context, Descriptors.FieldDescriptor.Type fieldType,
- IRubyObject value, RubyModule typeClass) {
+ public static IRubyObject checkType(ThreadContext context, Descriptors.FieldDescriptor.Type fieldType,
+ IRubyObject value, RubyModule typeClass) {
Ruby runtime = context.runtime;
Object val;
switch(fieldType) {
@@ -106,7 +106,7 @@ public class Utils {
break;
case BYTES:
case STRING:
- validateStringEncoding(context.runtime, fieldType, value);
+ value = validateStringEncoding(context, fieldType, value);
break;
case MESSAGE:
if (value.getMetaClass() != typeClass) {
@@ -127,6 +127,7 @@ public class Utils {
default:
break;
}
+ return value;
}
public static IRubyObject wrapPrimaryValue(ThreadContext context, Descriptors.FieldDescriptor.Type fieldType, Object value) {
@@ -148,10 +149,16 @@ public class Utils {
return runtime.newFloat((Double) value);
case BOOL:
return (Boolean) value ? runtime.getTrue() : runtime.getFalse();
- case BYTES:
- return runtime.newString(((ByteString) value).toStringUtf8());
- case STRING:
- return runtime.newString(value.toString());
+ case BYTES: {
+ IRubyObject wrapped = runtime.newString(((ByteString) value).toStringUtf8());
+ wrapped.setFrozen(true);
+ return wrapped;
+ }
+ case STRING: {
+ IRubyObject wrapped = runtime.newString(value.toString());
+ wrapped.setFrozen(true);
+ return wrapped;
+ }
default:
return runtime.getNil();
}
@@ -180,25 +187,21 @@ public class Utils {
}
}
- public static void validateStringEncoding(Ruby runtime, Descriptors.FieldDescriptor.Type type, IRubyObject value) {
+ public static IRubyObject validateStringEncoding(ThreadContext context, Descriptors.FieldDescriptor.Type type, IRubyObject value) {
if (!(value instanceof RubyString))
- throw runtime.newTypeError("Invalid argument for string field.");
- Encoding encoding = ((RubyString) value).getEncoding();
+ throw context.runtime.newTypeError("Invalid argument for string field.");
switch(type) {
case BYTES:
- if (encoding != ASCIIEncoding.INSTANCE)
- throw runtime.newTypeError("Encoding for bytes fields" +
- " must be \"ASCII-8BIT\", but was " + encoding);
+ value = ((RubyString)value).encode(context, context.runtime.evalScriptlet("Encoding::ASCII_8BIT"));
break;
case STRING:
- if (encoding != UTF8Encoding.INSTANCE
- && encoding != USASCIIEncoding.INSTANCE)
- throw runtime.newTypeError("Encoding for string fields" +
- " must be \"UTF-8\" or \"ASCII\", but was " + encoding);
+ value = ((RubyString)value).encode(context, context.runtime.evalScriptlet("Encoding::UTF_8"));
break;
default:
break;
}
+ value.setFrozen(true);
+ return value;
}
public static void checkNameAvailability(ThreadContext context, String name) {
diff --git a/ruby/src/main/sentinel.proto b/ruby/src/main/sentinel.proto
index 89a1ae19..722041ba 100644
--- a/ruby/src/main/sentinel.proto
+++ b/ruby/src/main/sentinel.proto
@@ -3,13 +3,13 @@ package com.google.protobuf.jruby;
option optimize_for = CODE_SIZE;
message Sentinel {
- optional int32 default_int32 = 1;
- optional int64 default_int64 = 2;
- optional uint32 default_unit32 = 3;
- optional uint64 default_uint64 = 4;
- optional string default_string = 5;
- optional bool default_bool = 6;
- optional float default_float = 7;
- optional double default_double = 8;
- optional bytes default_bytes = 9;
+ int32 default_int32 = 1;
+ int64 default_int64 = 2;
+ uint32 default_unit32 = 3;
+ uint64 default_uint64 = 4;
+ string default_string = 5;
+ bool default_bool = 6;
+ float default_float = 7;
+ double default_double = 8;
+ bytes default_bytes = 9;
}
diff --git a/ruby/tests/basic.rb b/ruby/tests/basic.rb
index 40c20078..8b6d329e 100644
--- a/ruby/tests/basic.rb
+++ b/ruby/tests/basic.rb
@@ -191,6 +191,35 @@ module BasicTest
assert m1.hash != m2.hash
end
+ def test_unknown_field_errors
+ e = assert_raise NoMethodError do
+ TestMessage.new.hello
+ end
+ assert_match(/hello/, e.message)
+
+ e = assert_raise NoMethodError do
+ TestMessage.new.hello = "world"
+ end
+ assert_match(/hello/, e.message)
+ end
+
+ def test_initialization_map_errors
+ e = assert_raise ArgumentError do
+ TestMessage.new(:hello => "world")
+ end
+ assert_match(/hello/, e.message)
+
+ e = assert_raise ArgumentError do
+ MapMessage.new(:map_string_int32 => "hello")
+ end
+ assert_equal e.message, "Expected Hash object as initializer value for map field 'map_string_int32'."
+
+ e = assert_raise ArgumentError do
+ TestMessage.new(:repeated_uint32 => "hello")
+ end
+ assert_equal e.message, "Expected array as initializer value for repeated field 'repeated_uint32'."
+ end
+
def test_type_errors
m = TestMessage.new
assert_raise TypeError do
@@ -226,14 +255,17 @@ module BasicTest
m = TestMessage.new
# Assigning a normal (ASCII or UTF8) string to a bytes field, or
- # ASCII-8BIT to a string field, raises an error.
- assert_raise TypeError do
- m.optional_bytes = "Test string ASCII".encode!('ASCII')
- end
- assert_raise TypeError do
+ # ASCII-8BIT to a string field will convert to the proper encoding.
+ m.optional_bytes = "Test string ASCII".encode!('ASCII')
+ assert m.optional_bytes.frozen?
+ assert_equal Encoding::ASCII_8BIT, m.optional_bytes.encoding
+ assert_equal "Test string ASCII", m.optional_bytes
+
+ assert_raise Encoding::UndefinedConversionError do
m.optional_bytes = "Test string UTF-8 \u0100".encode!('UTF-8')
end
- assert_raise TypeError do
+
+ assert_raise Encoding::UndefinedConversionError do
m.optional_string = ["FFFF"].pack('H*')
end
@@ -241,11 +273,10 @@ module BasicTest
m.optional_bytes = ["FFFF"].pack('H*')
m.optional_string = "\u0100"
- # strings are mutable so we can do this, but serialize should catch it.
+ # strings are immutable so we can't do this, but serialize should catch it.
m.optional_string = "asdf".encode!('UTF-8')
- m.optional_string.encode!('ASCII-8BIT')
- assert_raise TypeError do
- data = TestMessage.encode(m)
+ assert_raise RuntimeError do
+ m.optional_string.encode!('ASCII-8BIT')
end
end
@@ -437,9 +468,9 @@ module BasicTest
assert m.length == 2
m2 = m.dup
- assert m == m2
+ assert_equal m, m2
assert m.hash != 0
- assert m.hash == m2.hash
+ assert_equal m.hash, m2.hash
collected = {}
m.each { |k,v| collected[v] = k }
@@ -529,7 +560,7 @@ module BasicTest
assert_raise TypeError do
m[1] = 1
end
- assert_raise TypeError do
+ assert_raise Encoding::UndefinedConversionError do
bytestring = ["FFFF"].pack("H*")
m[bytestring] = 1
end
@@ -537,9 +568,8 @@ module BasicTest
m = Google::Protobuf::Map.new(:bytes, :int32)
bytestring = ["FFFF"].pack("H*")
m[bytestring] = 1
- assert_raise TypeError do
- m["asdf"] = 1
- end
+ # Allowed -- we will automatically convert to ASCII-8BIT.
+ m["asdf"] = 1
assert_raise TypeError do
m[1] = 1
end
@@ -674,36 +704,36 @@ module BasicTest
def test_oneof
d = OneofMessage.new
- assert d.a == nil
- assert d.b == nil
+ assert d.a == ""
+ assert d.b == 0
assert d.c == nil
- assert d.d == nil
+ assert d.d == :Default
assert d.my_oneof == nil
d.a = "hi"
assert d.a == "hi"
- assert d.b == nil
+ assert d.b == 0
assert d.c == nil
- assert d.d == nil
+ assert d.d == :Default
assert d.my_oneof == :a
d.b = 42
- assert d.a == nil
+ assert d.a == ""
assert d.b == 42
assert d.c == nil
- assert d.d == nil
+ assert d.d == :Default
assert d.my_oneof == :b
d.c = TestMessage2.new(:foo => 100)
- assert d.a == nil
- assert d.b == nil
+ assert d.a == ""
+ assert d.b == 0
assert d.c.foo == 100
- assert d.d == nil
+ assert d.d == :Default
assert d.my_oneof == :c
d.d = :C
- assert d.a == nil
- assert d.b == nil
+ assert d.a == ""
+ assert d.b == 0
assert d.c == nil
assert d.d == :C
assert d.my_oneof == :d
@@ -719,23 +749,23 @@ module BasicTest
d3 = OneofMessage.decode(
encoded_field_c + encoded_field_a + encoded_field_d)
- assert d3.a == nil
- assert d3.b == nil
+ assert d3.a == ""
+ assert d3.b == 0
assert d3.c == nil
assert d3.d == :B
d4 = OneofMessage.decode(
encoded_field_c + encoded_field_a + encoded_field_d +
encoded_field_c)
- assert d4.a == nil
- assert d4.b == nil
+ assert d4.a == ""
+ assert d4.b == 0
assert d4.c.foo == 1
- assert d4.d == nil
+ assert d4.d == :Default
d5 = OneofMessage.new(:a => "hello")
- assert d5.a != nil
+ assert d5.a == "hello"
d5.a = nil
- assert d5.a == nil
+ assert d5.a == ""
assert OneofMessage.encode(d5) == ''
assert d5.my_oneof == nil
end
@@ -824,15 +854,22 @@ module BasicTest
def test_encode_decode_helpers
m = TestMessage.new(:optional_string => 'foo', :repeated_string => ['bar1', 'bar2'])
+ assert_equal 'foo', m.optional_string
+ assert_equal ['bar1', 'bar2'], m.repeated_string
+
json = m.to_json
m2 = TestMessage.decode_json(json)
- assert m2.optional_string == 'foo'
- assert m2.repeated_string == ['bar1', 'bar2']
+ assert_equal 'foo', m2.optional_string
+ assert_equal ['bar1', 'bar2'], m2.repeated_string
+ if RUBY_PLATFORM != "java"
+ assert m2.optional_string.frozen?
+ assert m2.repeated_string[0].frozen?
+ end
proto = m.to_proto
m2 = TestMessage.decode(proto)
- assert m2.optional_string == 'foo'
- assert m2.repeated_string == ['bar1', 'bar2']
+ assert_equal 'foo', m2.optional_string
+ assert_equal ['bar1', 'bar2'], m2.repeated_string
end
def test_protobuf_encode_decode_helpers
@@ -1131,8 +1168,13 @@ module BasicTest
# TODO: Fix JSON in JRuby version.
return if RUBY_PLATFORM == "java"
m = MapMessage.new(:map_string_int32 => {"a" => 1})
- expected = '{"map_string_int32":{"a":1},"map_string_msg":{}}'
+ expected = '{"mapStringInt32":{"a":1},"mapStringMsg":{}}'
+ expected_preserve = '{"map_string_int32":{"a":1},"map_string_msg":{}}'
assert MapMessage.encode_json(m) == expected
+
+ json = MapMessage.encode_json(m, :preserve_proto_fieldnames => true)
+ assert json == expected_preserve
+
m2 = MapMessage.decode_json(MapMessage.encode_json(m))
assert m == m2
end
diff --git a/ruby/tests/generated_code.proto b/ruby/tests/generated_code.proto
index 42d82a6b..62fd83ed 100644
--- a/ruby/tests/generated_code.proto
+++ b/ruby/tests/generated_code.proto
@@ -1,6 +1,6 @@
syntax = "proto3";
-package A.B.C;
+package a.b.c;
message TestMessage {
int32 optional_int32 = 1;
diff --git a/ruby/tests/generated_code.rb b/ruby/tests/generated_code.rb
deleted file mode 100644
index 5a685433..00000000
--- a/ruby/tests/generated_code.rb
+++ /dev/null
@@ -1,74 +0,0 @@
-# Generated by the protocol buffer compiler. DO NOT EDIT!
-# source: generated_code.proto
-
-require 'google/protobuf'
-
-Google::Protobuf::DescriptorPool.generated_pool.build do
- add_message "A.B.C.TestMessage" do
- optional :optional_int32, :int32, 1
- optional :optional_int64, :int64, 2
- optional :optional_uint32, :uint32, 3
- optional :optional_uint64, :uint64, 4
- optional :optional_bool, :bool, 5
- optional :optional_double, :double, 6
- optional :optional_float, :float, 7
- optional :optional_string, :string, 8
- optional :optional_bytes, :string, 9
- optional :optional_enum, :enum, 10, "A.B.C.TestEnum"
- optional :optional_msg, :message, 11, "A.B.C.TestMessage"
- repeated :repeated_int32, :int32, 21
- repeated :repeated_int64, :int64, 22
- repeated :repeated_uint32, :uint32, 23
- repeated :repeated_uint64, :uint64, 24
- repeated :repeated_bool, :bool, 25
- repeated :repeated_double, :double, 26
- repeated :repeated_float, :float, 27
- repeated :repeated_string, :string, 28
- repeated :repeated_bytes, :string, 29
- repeated :repeated_enum, :enum, 30, "A.B.C.TestEnum"
- repeated :repeated_msg, :message, 31, "A.B.C.TestMessage"
- map :map_int32_string, :int32, :string, 61
- map :map_int64_string, :int64, :string, 62
- map :map_uint32_string, :uint32, :string, 63
- map :map_uint64_string, :uint64, :string, 64
- map :map_bool_string, :bool, :string, 65
- map :map_string_string, :string, :string, 66
- map :map_string_msg, :string, :message, 67, "A.B.C.TestMessage"
- map :map_string_enum, :string, :enum, 68, "A.B.C.TestEnum"
- map :map_string_int32, :string, :int32, 69
- map :map_string_bool, :string, :bool, 70
- optional :nested_message, :message, 80, "A.B.C.TestMessage.NestedMessage"
- oneof :my_oneof do
- optional :oneof_int32, :int32, 41
- optional :oneof_int64, :int64, 42
- optional :oneof_uint32, :uint32, 43
- optional :oneof_uint64, :uint64, 44
- optional :oneof_bool, :bool, 45
- optional :oneof_double, :double, 46
- optional :oneof_float, :float, 47
- optional :oneof_string, :string, 48
- optional :oneof_bytes, :string, 49
- optional :oneof_enum, :enum, 50, "A.B.C.TestEnum"
- optional :oneof_msg, :message, 51, "A.B.C.TestMessage"
- end
- end
- add_message "A.B.C.TestMessage.NestedMessage" do
- optional :foo, :int32, 1
- end
- add_enum "A.B.C.TestEnum" do
- value :Default, 0
- value :A, 1
- value :B, 2
- value :C, 3
- end
-end
-
-module A
- module B
- module C
- TestMessage = Google::Protobuf::DescriptorPool.generated_pool.lookup("A.B.C.TestMessage").msgclass
- TestMessage::NestedMessage = Google::Protobuf::DescriptorPool.generated_pool.lookup("A.B.C.TestMessage.NestedMessage").msgclass
- TestEnum = Google::Protobuf::DescriptorPool.generated_pool.lookup("A.B.C.TestEnum").enummodule
- end
- end
-end
diff --git a/ruby/tests/generated_code_test.rb b/ruby/tests/generated_code_test.rb
index daef357a..b92b0462 100644
--- a/ruby/tests/generated_code_test.rb
+++ b/ruby/tests/generated_code_test.rb
@@ -3,7 +3,8 @@
# generated_code.rb is in the same directory as this test.
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__)))
-require 'generated_code'
+require 'generated_code_pb'
+require 'test_import_pb'
require 'test/unit'
class GeneratedCodeTest < Test::Unit::TestCase
@@ -13,5 +14,6 @@ class GeneratedCodeTest < Test::Unit::TestCase
# successfully creates message definitions and classes, not to test every
# aspect of the extension (basic.rb is for that).
m = A::B::C::TestMessage.new()
+ m2 = FooBar::TestImportedMessage.new()
end
end
diff --git a/ruby/tests/test_import.proto b/ruby/tests/test_import.proto
new file mode 100644
index 00000000..230484ee
--- /dev/null
+++ b/ruby/tests/test_import.proto
@@ -0,0 +1,5 @@
+syntax = "proto3";
+
+package foo_bar;
+
+message TestImportedMessage {}
diff --git a/ruby/tests/well_known_types_test.rb b/ruby/tests/well_known_types_test.rb
new file mode 100644
index 00000000..9b46632b
--- /dev/null
+++ b/ruby/tests/well_known_types_test.rb
@@ -0,0 +1,122 @@
+#!/usr/bin/ruby
+
+require 'test/unit'
+require 'google/protobuf/well_known_types'
+
+class TestWellKnownTypes < Test::Unit::TestCase
+ def test_timestamp
+ ts = Google::Protobuf::Timestamp.new
+
+ assert_equal Time.at(0), ts.to_time
+
+ ts.seconds = 12345
+ assert_equal Time.at(12345), ts.to_time
+ assert_equal 12345, ts.to_i
+
+ ts.from_time(Time.at(123456, 654321))
+ assert_equal 123456, ts.seconds
+ assert_equal 654321000, ts.nanos
+ assert_equal Time.at(123456.654321), ts.to_time
+ end
+
+ def test_duration
+ duration = Google::Protobuf::Duration.new(seconds: 123, nanos: 456)
+ assert_equal 123.000000456, duration.to_f
+ end
+
+ def test_struct
+ struct = Google::Protobuf::Struct.new
+
+ substruct = {
+ "subkey" => 999,
+ "subkey2" => false
+ }
+
+ sublist = ["abc", 123, {"deepkey" => "deepval"}]
+
+ struct["number"] = 12345
+ struct["boolean-true"] = true
+ struct["boolean-false"] = false
+ struct["null"] = nil
+ struct["string"] = "abcdef"
+ struct["substruct"] = substruct
+ struct["sublist"] = sublist
+
+ assert_equal 12345, struct["number"]
+ assert_equal true, struct["boolean-true"]
+ assert_equal false, struct["boolean-false"]
+ assert_equal nil, struct["null"]
+ assert_equal "abcdef", struct["string"]
+ assert_equal(Google::Protobuf::Struct.from_hash(substruct),
+ struct["substruct"])
+ assert_equal(Google::Protobuf::ListValue.from_a(sublist),
+ struct["sublist"])
+
+ should_equal = {
+ "number" => 12345,
+ "boolean-true" => true,
+ "boolean-false" => false,
+ "null" => nil,
+ "string" => "abcdef",
+ "substruct" => {
+ "subkey" => 999,
+ "subkey2" => false
+ },
+ "sublist" => ["abc", 123, {"deepkey" => "deepval"}]
+ }
+
+ list = struct["sublist"]
+ list.is_a?(Google::Protobuf::ListValue)
+ assert_equal "abc", list[0]
+ assert_equal 123, list[1]
+ assert_equal({"deepkey" => "deepval"}, list[2].to_h)
+
+ # to_h returns a fully-flattened Ruby structure (Hash and Array).
+ assert_equal(should_equal, struct.to_h)
+
+ # Test that we can assign Struct and ListValue directly.
+ struct["substruct"] = Google::Protobuf::Struct.from_hash(substruct)
+ struct["sublist"] = Google::Protobuf::ListValue.from_a(sublist)
+
+ assert_equal(should_equal, struct.to_h)
+
+ struct["sublist"] << nil
+ should_equal["sublist"] << nil
+
+ assert_equal(should_equal, struct.to_h)
+ assert_equal(should_equal["sublist"].length, struct["sublist"].length)
+
+ assert_raise Google::Protobuf::UnexpectedStructType do
+ struct[123] = 5
+ end
+
+ assert_raise Google::Protobuf::UnexpectedStructType do
+ struct[5] = Time.new
+ end
+
+ assert_raise Google::Protobuf::UnexpectedStructType do
+ struct[5] = [Time.new]
+ end
+
+ assert_raise Google::Protobuf::UnexpectedStructType do
+ struct[5] = {123 => 456}
+ end
+
+ assert_raise Google::Protobuf::UnexpectedStructType do
+ struct = Google::Protobuf::Struct.new
+ struct.fields["foo"] = Google::Protobuf::Value.new
+ # Tries to return a Ruby value for a Value class whose type
+ # hasn't been filled in.
+ struct["foo"]
+ end
+ end
+
+ def test_any
+ any = Google::Protobuf::Any.new
+ ts = Google::Protobuf::Timestamp.new(seconds: 12345, nanos: 6789)
+ any.pack(ts)
+
+ assert any.is(Google::Protobuf::Timestamp)
+ assert_equal ts, any.unpack(Google::Protobuf::Timestamp)
+ end
+end
diff --git a/ruby/travis-test.sh b/ruby/travis-test.sh
index 9ec7eb22..59e970a6 100755
--- a/ruby/travis-test.sh
+++ b/ruby/travis-test.sh
@@ -5,7 +5,7 @@ set -e
test_version() {
version=$1
- if [ "$version" == "jruby" ] ; then
+ if [ "$version" == "jruby-1.7" ] ; then
# No conformance tests yet -- JRuby is too broken to run them.
bash --login -c \
"rvm install $version && rvm use $version && \
@@ -17,9 +17,8 @@ test_version() {
"rvm install $version && rvm use $version && \
which ruby && \
gem install bundler && bundle && \
- rake test && \
- cd ../conformance && \
- make test_ruby"
+ rake test &&
+ cd ../conformance && make test_ruby"
fi
}
diff --git a/src/Makefile.am b/src/Makefile.am
index b7d64093..f70e9550 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -19,8 +19,9 @@ PTHREAD_DEF =
endif
if GCC
-# These are good warnings to turn on by default
-NO_OPT_CXXFLAGS = $(PTHREAD_CFLAGS) $(PTHREAD_DEF) $(ZLIB_DEF) -Wall -Wwrite-strings -Woverloaded-virtual -Wno-sign-compare
+# Turn on all warnings except for sign comparison (we ignore sign comparison
+# in Google so our code base have tons of such warnings).
+NO_OPT_CXXFLAGS = $(PTHREAD_CFLAGS) $(PTHREAD_DEF) $(ZLIB_DEF) -Wall -Wno-sign-compare
else
NO_OPT_CXXFLAGS = $(PTHREAD_CFLAGS) $(PTHREAD_DEF) $(ZLIB_DEF)
endif
@@ -32,6 +33,10 @@ AM_LDFLAGS = $(PTHREAD_CFLAGS)
# If I say "dist_include_DATA", automake complains that $(includedir) is not
# a "legitimate" directory for DATA. Screw you, automake.
protodir = $(includedir)
+
+# If you are adding new files here, also remember to change the build files for
+# all other languages, //protoc-artifacts/build-zip.sh and run
+# //update_file_list.sh for bazel.
nobase_dist_proto_DATA = google/protobuf/descriptor.proto \
google/protobuf/any.proto \
google/protobuf/api.proto \
@@ -50,7 +55,8 @@ clean-local:
rm -f *.loT
CLEANFILES = $(protoc_outputs) unittest_proto_middleman \
- testzip.jar testzip.list testzip.proto testzip.zip
+ testzip.jar testzip.list testzip.proto testzip.zip \
+ no_warning_test.cc
MAINTAINERCLEANFILES = \
Makefile.in
@@ -59,6 +65,7 @@ nobase_include_HEADERS = \
google/protobuf/stubs/atomic_sequence_num.h \
google/protobuf/stubs/atomicops.h \
google/protobuf/stubs/atomicops_internals_power.h \
+ google/protobuf/stubs/atomicops_internals_ppc_gcc.h \
google/protobuf/stubs/atomicops_internals_arm64_gcc.h \
google/protobuf/stubs/atomicops_internals_arm_gcc.h \
google/protobuf/stubs/atomicops_internals_arm_qnx.h \
@@ -121,7 +128,6 @@ nobase_include_HEADERS = \
google/protobuf/reflection.h \
google/protobuf/reflection_ops.h \
google/protobuf/repeated_field.h \
- google/protobuf/repeated_field_reflection.h \
google/protobuf/service.h \
google/protobuf/source_context.pb.h \
google/protobuf/struct.pb.h \
@@ -148,15 +154,16 @@ nobase_include_HEADERS = \
google/protobuf/compiler/plugin.h \
google/protobuf/compiler/plugin.pb.h \
google/protobuf/compiler/cpp/cpp_generator.h \
+ google/protobuf/compiler/csharp/csharp_generator.h \
+ google/protobuf/compiler/csharp/csharp_names.h \
google/protobuf/compiler/java/java_generator.h \
google/protobuf/compiler/java/java_names.h \
google/protobuf/compiler/javanano/javanano_generator.h \
+ google/protobuf/compiler/js/js_generator.h \
google/protobuf/compiler/objectivec/objectivec_generator.h \
google/protobuf/compiler/objectivec/objectivec_helpers.h \
google/protobuf/compiler/python/python_generator.h \
google/protobuf/compiler/ruby/ruby_generator.h \
- google/protobuf/compiler/csharp/csharp_generator.h \
- google/protobuf/compiler/csharp/csharp_names.h \
google/protobuf/util/type_resolver.h \
google/protobuf/util/field_comparator.h \
google/protobuf/util/field_mask_util.h \
@@ -276,9 +283,9 @@ libprotobuf_la_SOURCES = \
google/protobuf/util/internal/protostream_objectsource.h \
google/protobuf/util/internal/protostream_objectwriter.cc \
google/protobuf/util/internal/protostream_objectwriter.h \
- google/protobuf/util/internal/snake2camel_objectwriter.h \
+ google/protobuf/util/internal/proto_writer.cc \
+ google/protobuf/util/internal/proto_writer.h \
google/protobuf/util/internal/structured_objectwriter.h \
- google/protobuf/util/internal/testdata \
google/protobuf/util/internal/type_info.cc \
google/protobuf/util/internal/type_info.h \
google/protobuf/util/internal/type_info_test_helper.cc \
@@ -341,6 +348,8 @@ libprotoc_la_SOURCES = \
google/protobuf/compiler/java/java_enum_lite.h \
google/protobuf/compiler/java/java_extension.cc \
google/protobuf/compiler/java/java_extension.h \
+ google/protobuf/compiler/java/java_extension_lite.cc \
+ google/protobuf/compiler/java/java_extension_lite.h \
google/protobuf/compiler/java/java_field.cc \
google/protobuf/compiler/java/java_field.h \
google/protobuf/compiler/java/java_file.cc \
@@ -372,6 +381,7 @@ libprotoc_la_SOURCES = \
google/protobuf/compiler/java/java_message_builder_lite.h \
google/protobuf/compiler/java/java_name_resolver.cc \
google/protobuf/compiler/java/java_name_resolver.h \
+ google/protobuf/compiler/java/java_options.h \
google/protobuf/compiler/java/java_primitive_field.cc \
google/protobuf/compiler/java/java_primitive_field.h \
google/protobuf/compiler/java/java_primitive_field_lite.cc \
@@ -386,6 +396,7 @@ libprotoc_la_SOURCES = \
google/protobuf/compiler/java/java_string_field_lite.h \
google/protobuf/compiler/java/java_doc_comment.cc \
google/protobuf/compiler/java/java_doc_comment.h \
+ google/protobuf/compiler/js/js_generator.cc \
google/protobuf/compiler/javanano/javanano_enum.cc \
google/protobuf/compiler/javanano/javanano_enum.h \
google/protobuf/compiler/javanano/javanano_enum_field.cc \
@@ -451,6 +462,7 @@ libprotoc_la_SOURCES = \
google/protobuf/compiler/csharp/csharp_message.h \
google/protobuf/compiler/csharp/csharp_message_field.cc \
google/protobuf/compiler/csharp/csharp_message_field.h \
+ google/protobuf/compiler/csharp/csharp_options.h \
google/protobuf/compiler/csharp/csharp_primitive_field.cc \
google/protobuf/compiler/csharp/csharp_primitive_field.h \
google/protobuf/compiler/csharp/csharp_reflection_class.cc \
@@ -502,6 +514,8 @@ protoc_inputs = \
google/protobuf/unittest_preserve_unknown_enum.proto \
google/protobuf/unittest.proto \
google/protobuf/unittest_proto3_arena.proto \
+ google/protobuf/unittest_proto3_arena_lite.proto \
+ google/protobuf/unittest_proto3_lite.proto \
google/protobuf/unittest_well_known_types.proto \
google/protobuf/util/internal/testdata/anys.proto \
google/protobuf/util/internal/testdata/books.proto \
@@ -513,6 +527,7 @@ protoc_inputs = \
google/protobuf/util/internal/testdata/struct.proto \
google/protobuf/util/internal/testdata/timestamp_duration.proto \
google/protobuf/util/json_format_proto3.proto \
+ google/protobuf/util/message_differencer_unittest.proto \
google/protobuf/compiler/cpp/cpp_test_large_enum_value.proto
EXTRA_DIST = \
@@ -521,6 +536,7 @@ EXTRA_DIST = \
google/protobuf/io/gzip_stream.h \
google/protobuf/io/gzip_stream_unittest.sh \
google/protobuf/testdata/golden_message \
+ google/protobuf/testdata/golden_message_maps \
google/protobuf/testdata/golden_message_oneof_implemented \
google/protobuf/testdata/golden_message_proto3 \
google/protobuf/testdata/golden_packed_fields_message \
@@ -535,9 +551,10 @@ EXTRA_DIST = \
google/protobuf/package_info.h \
google/protobuf/io/package_info.h \
google/protobuf/compiler/ruby/ruby_generated_code.proto \
- google/protobuf/compiler/ruby/ruby_generated_code.rb \
+ google/protobuf/compiler/ruby/ruby_generated_code_pb.rb \
google/protobuf/compiler/package_info.h \
- google/protobuf/compiler/zip_output_unittest.sh
+ google/protobuf/compiler/zip_output_unittest.sh \
+ README.md
protoc_lite_outputs = \
google/protobuf/map_lite_unittest.pb.cc \
@@ -603,6 +620,10 @@ protoc_outputs = \
google/protobuf/unittest_preserve_unknown_enum.pb.h \
google/protobuf/unittest_proto3_arena.pb.cc \
google/protobuf/unittest_proto3_arena.pb.h \
+ google/protobuf/unittest_proto3_arena_lite.pb.cc \
+ google/protobuf/unittest_proto3_arena_lite.pb.h \
+ google/protobuf/unittest_proto3_lite.pb.cc \
+ google/protobuf/unittest_proto3_lite.pb.h \
google/protobuf/unittest_well_known_types.pb.cc \
google/protobuf/unittest_well_known_types.pb.h \
google/protobuf/util/internal/testdata/anys.pb.cc \
@@ -624,7 +645,9 @@ protoc_outputs = \
google/protobuf/util/internal/testdata/timestamp_duration.pb.cc \
google/protobuf/util/internal/testdata/timestamp_duration.pb.h \
google/protobuf/util/json_format_proto3.pb.cc \
- google/protobuf/util/json_format_proto3.pb.h
+ google/protobuf/util/json_format_proto3.pb.h \
+ google/protobuf/util/message_differencer_unittest.pb.cc \
+ google/protobuf/util/message_differencer_unittest.pb.h
BUILT_SOURCES = $(protoc_outputs)
@@ -662,7 +685,7 @@ COMMON_TEST_SOURCES = \
check_PROGRAMS = protoc protobuf-test protobuf-lazy-descriptor-test \
protobuf-lite-test test_plugin protobuf-lite-arena-test \
- $(GZCHECKPROGRAMS)
+ no-warning-test $(GZCHECKPROGRAMS)
protobuf_test_LDADD = $(PTHREAD_LIBS) libprotobuf.la libprotoc.la \
../gmock/gtest/lib/libgtest.la \
../gmock/lib/libgmock.la \
@@ -702,6 +725,8 @@ protobuf_test_SOURCES = \
google/protobuf/no_field_presence_test.cc \
google/protobuf/preserve_unknown_enum_test.cc \
google/protobuf/proto3_arena_unittest.cc \
+ google/protobuf/proto3_arena_lite_unittest.cc \
+ google/protobuf/proto3_lite_unittest.cc \
google/protobuf/reflection_ops_unittest.cc \
google/protobuf/repeated_field_reflection_unittest.cc \
google/protobuf/repeated_field_unittest.cc \
@@ -722,6 +747,7 @@ protobuf_test_SOURCES = \
google/protobuf/compiler/cpp/cpp_unittest.h \
google/protobuf/compiler/cpp/cpp_unittest.cc \
google/protobuf/compiler/cpp/cpp_plugin_unittest.cc \
+ google/protobuf/compiler/cpp/metadata_test.cc \
google/protobuf/compiler/java/java_plugin_unittest.cc \
google/protobuf/compiler/java/java_doc_comment_unittest.cc \
google/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc \
@@ -737,6 +763,7 @@ protobuf_test_SOURCES = \
google/protobuf/util/internal/protostream_objectwriter_test.cc \
google/protobuf/util/internal/type_info_test_helper.cc \
google/protobuf/util/json_util_test.cc \
+ google/protobuf/util/message_differencer_unittest.cc \
google/protobuf/util/time_util_test.cc \
google/protobuf/util/type_resolver_util_test.cc \
$(COMMON_TEST_SOURCES)
@@ -811,6 +838,27 @@ zcgunzip_LDADD = $(PTHREAD_LIBS) libprotobuf.la
zcgunzip_SOURCES = google/protobuf/testing/zcgunzip.cc
endif
+# This test target is to ensure all our public header files and generated
+# code is free from warnings. We have to be more pedantic about these
+# files because they are compiled by users with different compiler flags.
+no_warning_test.cc:
+ echo "// Generated from Makefile.am" > no_warning_test.cc
+ for FILE in $(nobase_include_HEADERS); do \
+ if ! echo $${FILE} | grep "atomicops"; then \
+ echo "#include <$${FILE}>" >> no_warning_test.cc; \
+ fi \
+ done
+ echo "#include <gtest/gtest.h>" >> no_warning_test.cc
+ echo "TEST(NoWarningTest, Empty) {}" >> no_warning_test.cc
+
+no_warning_test_LDADD = $(PTHREAD_LIBS) libprotobuf.la \
+ ../gmock/gtest/lib/libgtest.la \
+ ../gmock/gtest/lib/libgtest_main.la
+no_warning_test_CPPFLAGS = -I$(srcdir)/../gmock/gtest/include
+no_warning_test_CXXFLAGS = $(PTHREAD_CFLAGS) $(PTHREAD_DEF) $(ZLIB_DEF) \
+ -Wall -Werror
+nodist_no_warning_test_SOURCES = no_warning_test.cc $(protoc_outputs)
+
TESTS = protobuf-test protobuf-lazy-descriptor-test protobuf-lite-test \
google/protobuf/compiler/zip_output_unittest.sh $(GZTESTS) \
- protobuf-lite-arena-test
+ protobuf-lite-arena-test no-warning-test
diff --git a/src/README.md b/src/README.md
new file mode 100644
index 00000000..c9362ee2
--- /dev/null
+++ b/src/README.md
@@ -0,0 +1,212 @@
+Protocol Buffers - Google's data interchange format
+===================================================
+
+[![Build Status](https://travis-ci.org/google/protobuf.svg?branch=master)](https://travis-ci.org/google/protobuf) [![Build status](https://ci.appveyor.com/api/projects/status/73ctee6ua4w2ruin?svg=true)](https://ci.appveyor.com/project/protobuf/protobuf)
+
+Copyright 2008 Google Inc.
+
+https://developers.google.com/protocol-buffers/
+
+C++ Installation - Unix
+-----------------------
+
+To build protobuf from source, the following tools are needed:
+
+ * autoconf
+ * automake
+ * libtool
+ * curl (used to download gmock)
+ * make
+ * g++
+ * unzip
+
+On Ubuntu, you can install them with:
+
+ $ sudo apt-get install autoconf automake libtool curl make g++ unzip
+
+On other platforms, please use the corresponding package managing tool to
+install them before proceeding.
+
+If you get the source from github, you need to generate the configure script
+first:
+
+ $ ./autogen.sh
+
+This will download gmock source (which is used for C++ Protocol Buffer
+unit-tests) to the current directory and run automake, autoconf, etc.
+to generate the configure script and various template makefiles.
+
+You can skip this step if you are using a release package (which already
+contains gmock and the configure script).
+
+To build and install the C++ Protocol Buffer runtime and the Protocol
+Buffer compiler (protoc) execute the following:
+
+ $ ./configure
+ $ make
+ $ make check
+ $ sudo make install
+ $ sudo ldconfig # refresh shared library cache.
+
+If "make check" fails, you can still install, but it is likely that
+some features of this library will not work correctly on your system.
+Proceed at your own risk.
+
+For advanced usage information on configure and make, please refer to the
+autoconf documentation:
+
+ http://www.gnu.org/software/autoconf/manual/autoconf.html#Running-configure-Scripts
+
+**Hint on install location**
+
+ By default, the package will be installed to /usr/local. However,
+ on many platforms, /usr/local/lib is not part of LD_LIBRARY_PATH.
+ You can add it, but it may be easier to just install to /usr
+ instead. To do this, invoke configure as follows:
+
+ ./configure --prefix=/usr
+
+ If you already built the package with a different prefix, make sure
+ to run "make clean" before building again.
+
+**Compiling dependent packages**
+
+ To compile a package that uses Protocol Buffers, you need to pass
+ various flags to your compiler and linker. As of version 2.2.0,
+ Protocol Buffers integrates with pkg-config to manage this. If you
+ have pkg-config installed, then you can invoke it to get a list of
+ flags like so:
+
+ pkg-config --cflags protobuf # print compiler flags
+ pkg-config --libs protobuf # print linker flags
+ pkg-config --cflags --libs protobuf # print both
+
+ For example:
+
+ c++ my_program.cc my_proto.pb.cc `pkg-config --cflags --libs protobuf`
+
+ Note that packages written prior to the 2.2.0 release of Protocol
+ Buffers may not yet integrate with pkg-config to get flags, and may
+ not pass the correct set of flags to correctly link against
+ libprotobuf. If the package in question uses autoconf, you can
+ often fix the problem by invoking its configure script like:
+
+ configure CXXFLAGS="$(pkg-config --cflags protobuf)" \
+ LIBS="$(pkg-config --libs protobuf)"
+
+ This will force it to use the correct flags.
+
+ If you are writing an autoconf-based package that uses Protocol
+ Buffers, you should probably use the PKG_CHECK_MODULES macro in your
+ configure script like:
+
+ PKG_CHECK_MODULES([protobuf], [protobuf])
+
+ See the pkg-config man page for more info.
+
+ If you only want protobuf-lite, substitute "protobuf-lite" in place
+ of "protobuf" in these examples.
+
+**Note for Mac users**
+
+ For a Mac system, Unix tools are not available by default. You will first need
+ to install Xcode from the Mac AppStore and then run the following command from
+ a terminal:
+
+ $ sudo xcode-select --install
+
+ To install Unix tools, you can install "port" following the instructions at
+ https://www.macports.org . This will reside in /opt/local/bin/port for most
+ Mac installations.
+
+ $ sudo /opt/local/bin/port install autoconf automake libtool
+
+ Then follow the Unix instructions above.
+
+**Note for cross-compiling**
+
+ The makefiles normally invoke the protoc executable that they just
+ built in order to build tests. When cross-compiling, the protoc
+ executable may not be executable on the host machine. In this case,
+ you must build a copy of protoc for the host machine first, then use
+ the --with-protoc option to tell configure to use it instead. For
+ example:
+
+ ./configure --with-protoc=protoc
+
+ This will use the installed protoc (found in your $PATH) instead of
+ trying to execute the one built during the build process. You can
+ also use an executable that hasn't been installed. For example, if
+ you built the protobuf package for your host machine in ../host,
+ you might do:
+
+ ./configure --with-protoc=../host/src/protoc
+
+ Either way, you must make sure that the protoc executable you use
+ has the same version as the protobuf source code you are trying to
+ use it with.
+
+**Note for Solaris users**
+
+ Solaris 10 x86 has a bug that will make linking fail, complaining
+ about libstdc++.la being invalid. We have included a work-around
+ in this package. To use the work-around, run configure as follows:
+
+ ./configure LDFLAGS=-L$PWD/src/solaris
+
+ See src/solaris/libstdc++.la for more info on this bug.
+
+**Note for HP C++ Tru64 users**
+
+ To compile invoke configure as follows:
+
+ ./configure CXXFLAGS="-O -std ansi -ieee -D__USE_STD_IOSTREAM"
+
+ Also, you will need to use gmake instead of make.
+
+**Note for AIX users**
+
+ Compile using the IBM xlC C++ compiler as follows:
+
+ ./configure CXX=xlC
+
+ Also, you will need to use GNU `make` (`gmake`) instead of AIX `make`.
+
+C++ Installation - Windows
+--------------------------
+
+If you only need the protoc binary, you can download it from the release
+page:
+
+ https://github.com/google/protobuf/releases
+
+In the downloads section, download the zip file protoc-$VERSION-win32.zip.
+It contains the protoc binary as well as public proto files of protobuf
+library.
+
+To build from source using Microsoft Visual C++, see [cmake/README.md](../cmake/README.md).
+
+To build from source using Cygwin or MinGW, follow the Unix installation
+instructions, above.
+
+Binary Compatibility Warning
+----------------------------
+
+Due to the nature of C++, it is unlikely that any two versions of the
+Protocol Buffers C++ runtime libraries will have compatible ABIs.
+That is, if you linked an executable against an older version of
+libprotobuf, it is unlikely to work with a newer version without
+re-compiling. This problem, when it occurs, will normally be detected
+immediately on startup of your app. Still, you may want to consider
+using static linkage. You can configure this package to install
+static libraries only using:
+
+ ./configure --disable-shared
+
+Usage
+-----
+
+The complete documentation for Protocol Buffers is available via the
+web at:
+
+ https://developers.google.com/protocol-buffers/
diff --git a/src/google/protobuf/any.cc b/src/google/protobuf/any.cc
index 7351d377..f7b1d310 100644
--- a/src/google/protobuf/any.cc
+++ b/src/google/protobuf/any.cc
@@ -35,10 +35,15 @@ namespace protobuf {
namespace internal {
namespace {
-string GetTypeUrl(const Descriptor* message) {
- return string(kTypeGoogleApisComPrefix) + message->full_name();
+string GetTypeUrl(const Descriptor* message,
+ const string& type_url_prefix) {
+ if (!type_url_prefix.empty() &&
+ type_url_prefix[type_url_prefix.size() - 1] == '/') {
+ return type_url_prefix + message->full_name();
+ } else {
+ return type_url_prefix + "/" + message->full_name();
+ }
}
-
} // namespace
const char kAnyFullTypeName[] = "google.protobuf.Any";
@@ -50,8 +55,13 @@ AnyMetadata::AnyMetadata(UrlType* type_url, ValueType* value)
}
void AnyMetadata::PackFrom(const Message& message) {
+ PackFrom(message, kTypeGoogleApisComPrefix);
+}
+
+void AnyMetadata::PackFrom(const Message& message,
+ const string& type_url_prefix) {
type_url_->SetNoArena(&::google::protobuf::internal::GetEmptyString(),
- GetTypeUrl(message.GetDescriptor()));
+ GetTypeUrl(message.GetDescriptor(), type_url_prefix));
message.SerializeToString(value_->MutableNoArena(
&::google::protobuf::internal::GetEmptyStringAlreadyInited()));
}
@@ -65,25 +75,22 @@ bool AnyMetadata::UnpackTo(Message* message) const {
}
bool AnyMetadata::InternalIs(const Descriptor* descriptor) const {
- return type_url_->GetNoArena(
- &::google::protobuf::internal::GetEmptyString()) ==
- GetTypeUrl(descriptor);
+ const string type_url = type_url_->GetNoArena(
+ &::google::protobuf::internal::GetEmptyString());
+ string full_name;
+ if (!ParseAnyTypeUrl(type_url, &full_name)) {
+ return false;
+ }
+ return full_name == descriptor->full_name();
}
bool ParseAnyTypeUrl(const string& type_url, string* full_type_name) {
- static const char* prefix[] = {
- kTypeGoogleApisComPrefix,
- kTypeGoogleProdComPrefix
- };
- for (int i = 0; i < 2; i++) {
- const int prefix_len = strlen(prefix[i]);
- if (strncmp(type_url.c_str(), prefix[i], prefix_len) == 0) {
- full_type_name->assign(type_url.data() + prefix_len,
- type_url.size() - prefix_len);
- return true;
- }
+ size_t pos = type_url.find_last_of("/");
+ if (pos == string::npos || pos + 1 == type_url.size()) {
+ return false;
}
- return false;
+ *full_type_name = type_url.substr(pos + 1);
+ return true;
}
diff --git a/src/google/protobuf/any.h b/src/google/protobuf/any.h
index f760ad5d..04e54166 100644
--- a/src/google/protobuf/any.h
+++ b/src/google/protobuf/any.h
@@ -50,10 +50,26 @@ class LIBPROTOBUF_EXPORT AnyMetadata {
// AnyMetadata does not take ownership of "type_url" and "value".
AnyMetadata(UrlType* type_url, ValueType* value);
+ // Packs a message using the default type URL prefix: "type.googleapis.com".
+ // The resulted type URL will be "type.googleapis.com/<message_full_name>".
void PackFrom(const Message& message);
-
+ // Packs a message using the given type URL prefix. The type URL will be
+ // constructed by concatenating the message type's full name to the prefix
+ // with an optional "/" separator if the prefix doesn't already end up "/".
+ // For example, both PackFrom(message, "type.googleapis.com") and
+ // PackFrom(message, "type.googleapis.com/") yield the same result type
+ // URL: "type.googleapis.com/<message_full_name>".
+ void PackFrom(const Message& message, const string& type_url_prefix);
+
+ // Unpacks the payload into the given message. Returns false if the message's
+ // type doesn't match the type specified in the type URL (i.e., the full
+ // name after the last "/" of the type URL doesn't match the message's actaul
+ // full name) or parsing the payload has failed.
bool UnpackTo(Message* message) const;
+ // Checks whether the type specified in the type URL matches the given type.
+ // A type is consdiered matching if its full name matches the full name after
+ // the last "/" in the type URL.
template<typename T>
bool Is() const {
return InternalIs(T::default_instance().GetDescriptor());
@@ -75,7 +91,7 @@ extern const char kTypeGoogleProdComPrefix[]; // "type.googleprod.com/".
// Get the proto type name from Any::type_url value. For example, passing
// "type.googleapis.com/rpc.QueryOrigin" will return "rpc.QueryOrigin" in
// *full_type_name. Returns false if type_url does not start with
-// "type.googleapis.com".
+// "type.googleapis.com" or "type.googleprod.com".
bool ParseAnyTypeUrl(const string& type_url, string* full_type_name);
// See if message is of type google.protobuf.Any, if so, return the descriptors
diff --git a/src/google/protobuf/any.pb.cc b/src/google/protobuf/any.pb.cc
index 321fd315..ccccc9c1 100644
--- a/src/google/protobuf/any.pb.cc
+++ b/src/google/protobuf/any.pb.cc
@@ -7,6 +7,7 @@
#include <algorithm>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/port.h>
#include <google/protobuf/stubs/once.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/wire_format_lite_inl.h>
@@ -28,6 +29,7 @@ const ::google::protobuf::internal::GeneratedMessageReflection*
} // namespace
+void protobuf_AssignDesc_google_2fprotobuf_2fany_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AssignDesc_google_2fprotobuf_2fany_2eproto() {
protobuf_AddDesc_google_2fprotobuf_2fany_2eproto();
const ::google::protobuf::FileDescriptor* file =
@@ -60,6 +62,7 @@ inline void protobuf_AssignDescriptorsOnce() {
&protobuf_AssignDesc_google_2fprotobuf_2fany_2eproto);
}
+void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
void protobuf_RegisterTypes(const ::std::string&) {
protobuf_AssignDescriptorsOnce();
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
@@ -73,6 +76,7 @@ void protobuf_ShutdownFile_google_2fprotobuf_2fany_2eproto() {
delete Any_reflection_;
}
+void protobuf_AddDesc_google_2fprotobuf_2fany_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AddDesc_google_2fprotobuf_2fany_2eproto() {
static bool already_here = false;
if (already_here) return;
@@ -82,9 +86,10 @@ void protobuf_AddDesc_google_2fprotobuf_2fany_2eproto() {
::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
"\n\031google/protobuf/any.proto\022\017google.prot"
"obuf\"&\n\003Any\022\020\n\010type_url\030\001 \001(\t\022\r\n\005value\030\002"
- " \001(\014BK\n\023com.google.protobufB\010AnyProtoP\001\240"
- "\001\001\242\002\003GPB\252\002\036Google.Protobuf.WellKnownType"
- "sb\006proto3", 169);
+ " \001(\014Br\n\023com.google.protobufB\010AnyProtoP\001Z"
+ "%github.com/golang/protobuf/ptypes/any\240\001"
+ "\001\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes"
+ "b\006proto3", 208);
::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
"google/protobuf/any.proto", &protobuf_RegisterTypes);
Any::default_instance_ = new Any();
@@ -99,22 +104,17 @@ struct StaticDescriptorInitializer_google_2fprotobuf_2fany_2eproto {
}
} static_descriptor_initializer_google_2fprotobuf_2fany_2eproto_;
-namespace {
-
-static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD;
-static void MergeFromFail(int line) {
- GOOGLE_CHECK(false) << __FILE__ << ":" << line;
-}
-
-} // namespace
-
-
// ===================================================================
void Any::PackFrom(const ::google::protobuf::Message& message) {
_any_metadata_.PackFrom(message);
}
+void Any::PackFrom(const ::google::protobuf::Message& message,
+ const ::std::string& type_url_prefix) {
+ _any_metadata_.PackFrom(message, type_url_prefix);
+}
+
bool Any::UnpackTo(::google::protobuf::Message* message) const {
return _any_metadata_.UnpackTo(message);
}
@@ -189,13 +189,14 @@ Any* Any::New(::google::protobuf::Arena* arena) const {
}
void Any::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.Any)
type_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
bool Any::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.Any)
for (;;) {
@@ -275,8 +276,8 @@ void Any::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.Any)
}
-::google::protobuf::uint8* Any::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* Any::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Any)
// optional string type_url = 1;
if (this->type_url().size() > 0) {
@@ -301,6 +302,7 @@ void Any::SerializeWithCachedSizes(
}
int Any::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Any)
int total_size = 0;
// optional string type_url = 1;
@@ -324,19 +326,27 @@ int Any::ByteSize() const {
}
void Any::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Any)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const Any* source =
::google::protobuf::internal::DynamicCastToGenerated<const Any>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.Any)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.Any)
MergeFrom(*source);
}
}
void Any::MergeFrom(const Any& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Any)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from.type_url().size() > 0) {
type_url_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.type_url_);
@@ -348,12 +358,14 @@ void Any::MergeFrom(const Any& from) {
}
void Any::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.Any)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void Any::CopyFrom(const Any& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Any)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -416,6 +428,7 @@ void Any::clear_type_url() {
return type_url_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* Any::release_type_url() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Any.type_url)
return type_url_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -459,6 +472,7 @@ void Any::clear_value() {
return value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* Any::release_value() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Any.value)
return value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
diff --git a/src/google/protobuf/any.pb.h b/src/google/protobuf/any.pb.h
index 97982ecf..d8cbee2d 100644
--- a/src/google/protobuf/any.pb.h
+++ b/src/google/protobuf/any.pb.h
@@ -42,7 +42,7 @@ class Any;
// ===================================================================
-class LIBPROTOBUF_EXPORT Any : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT Any : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Any) */ {
public:
Any();
virtual ~Any();
@@ -60,6 +60,8 @@ class LIBPROTOBUF_EXPORT Any : public ::google::protobuf::Message {
// implements Any -----------------------------------------------
void PackFrom(const ::google::protobuf::Message& message);
+ void PackFrom(const ::google::protobuf::Message& message,
+ const ::std::string& type_url_prefix);
bool UnpackTo(::google::protobuf::Message* message) const;
template<typename T> bool Is() const {
return _any_metadata_.Is<T>();
@@ -84,7 +86,11 @@ class LIBPROTOBUF_EXPORT Any : public ::google::protobuf::Message {
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
@@ -182,6 +188,7 @@ inline ::std::string* Any::mutable_type_url() {
return type_url_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* Any::release_type_url() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Any.type_url)
return type_url_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -225,6 +232,7 @@ inline ::std::string* Any::mutable_value() {
return value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* Any::release_value() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Any.value)
return value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
diff --git a/src/google/protobuf/any.proto b/src/google/protobuf/any.proto
index 423699be..81dcf46c 100644
--- a/src/google/protobuf/any.proto
+++ b/src/google/protobuf/any.proto
@@ -27,20 +27,60 @@
// 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.
+
syntax = "proto3";
package google.protobuf;
-option java_generate_equals_and_hash = true;
-option java_multiple_files = true;
-option java_outer_classname = "AnyProto";
-option java_package = "com.google.protobuf";
option csharp_namespace = "Google.Protobuf.WellKnownTypes";
+option go_package = "github.com/golang/protobuf/ptypes/any";
+option java_package = "com.google.protobuf";
+option java_outer_classname = "AnyProto";
+option java_multiple_files = true;
+option java_generate_equals_and_hash = true;
option objc_class_prefix = "GPB";
-
-// `Any` contains an arbitrary serialized message along with a URL
-// that describes the type of the serialized message.
+// `Any` contains an arbitrary serialized protocol buffer message along with a
+// URL that describes the type of the serialized message.
+//
+// Protobuf library provides support to pack/unpack Any values in the form
+// of utility functions or additional generated methods of the Any type.
+//
+// Example 1: Pack and unpack a message in C++.
+//
+// Foo foo = ...;
+// Any any;
+// any.PackFrom(foo);
+// ...
+// if (any.UnpackTo(&foo)) {
+// ...
+// }
+//
+// Example 2: Pack and unpack a message in Java.
+//
+// Foo foo = ...;
+// Any any = Any.pack(foo);
+// ...
+// if (any.is(Foo.class)) {
+// foo = any.unpack(Foo.class);
+// }
+//
+// Example 3: Pack and unpack a message in Python.
+//
+// foo = Foo(...)
+// any = Any()
+// any.Pack(foo)
+// ...
+// if any.Is(Foo.DESCRIPTOR):
+// any.Unpack(foo)
+// ...
+//
+// The pack methods provided by protobuf library will by default use
+// 'type.googleapis.com/full.type.name' as the type URL and the unpack
+// methods only use the fully qualified type name after the last '/'
+// in the type URL, for example "foo.bar.com/x/y.z" will yield type
+// name "y.z".
+//
//
// JSON
// ====
@@ -62,8 +102,8 @@ option objc_class_prefix = "GPB";
//
// If the embedded message type is well-known and has a custom JSON
// representation, that representation will be embedded adding a field
-// `value` which holds the custom JSON in addition to the the `@type`
-// field. Example (for message [google.protobuf.Duration][google.protobuf.Duration]):
+// `value` which holds the custom JSON in addition to the `@type`
+// field. Example (for message [google.protobuf.Duration][]):
//
// {
// "@type": "type.googleapis.com/google.protobuf.Duration",
@@ -72,15 +112,17 @@ option objc_class_prefix = "GPB";
//
message Any {
// A URL/resource name whose content describes the type of the
- // serialized message.
+ // serialized protocol buffer message.
//
- // For URLs which use the schema `http`, `https`, or no schema, the
+ // For URLs which use the scheme `http`, `https`, or no scheme, the
// following restrictions and interpretations apply:
//
- // * If no schema is provided, `https` is assumed.
+ // * If no scheme is provided, `https` is assumed.
// * The last segment of the URL's path must represent the fully
// qualified name of the type (as in `path/google.protobuf.Duration`).
- // * An HTTP GET on the URL must yield a [google.protobuf.Type][google.protobuf.Type]
+ // The name should be in a canonical form (e.g., leading "." is
+ // not accepted).
+ // * An HTTP GET on the URL must yield a [google.protobuf.Type][]
// value in binary format, or produce an error.
// * Applications are allowed to cache lookup results based on the
// URL, or have them precompiled into a binary to avoid any
@@ -88,11 +130,11 @@ message Any {
// on changes to types. (Use versioned type names to manage
// breaking changes.)
//
- // Schemas other than `http`, `https` (or the empty schema) might be
+ // Schemes other than `http`, `https` (or the empty scheme) might be
// used with implementation specific semantics.
//
string type_url = 1;
- // Must be valid serialized data of the above specified type.
+ // Must be a valid serialized protocol buffer of the above specified type.
bytes value = 2;
}
diff --git a/src/google/protobuf/api.pb.cc b/src/google/protobuf/api.pb.cc
index ed90702c..cfb30786 100644
--- a/src/google/protobuf/api.pb.cc
+++ b/src/google/protobuf/api.pb.cc
@@ -7,6 +7,7 @@
#include <algorithm>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/port.h>
#include <google/protobuf/stubs/once.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/wire_format_lite_inl.h>
@@ -34,6 +35,7 @@ const ::google::protobuf::internal::GeneratedMessageReflection*
} // namespace
+void protobuf_AssignDesc_google_2fprotobuf_2fapi_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AssignDesc_google_2fprotobuf_2fapi_2eproto() {
protobuf_AddDesc_google_2fprotobuf_2fapi_2eproto();
const ::google::protobuf::FileDescriptor* file =
@@ -108,6 +110,7 @@ inline void protobuf_AssignDescriptorsOnce() {
&protobuf_AssignDesc_google_2fprotobuf_2fapi_2eproto);
}
+void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
void protobuf_RegisterTypes(const ::std::string&) {
protobuf_AssignDescriptorsOnce();
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
@@ -129,6 +132,7 @@ void protobuf_ShutdownFile_google_2fprotobuf_2fapi_2eproto() {
delete Mixin_reflection_;
}
+void protobuf_AddDesc_google_2fprotobuf_2fapi_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AddDesc_google_2fprotobuf_2fapi_2eproto() {
static bool already_here = false;
if (already_here) return;
@@ -174,16 +178,6 @@ struct StaticDescriptorInitializer_google_2fprotobuf_2fapi_2eproto {
}
} static_descriptor_initializer_google_2fprotobuf_2fapi_2eproto_;
-namespace {
-
-static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD;
-static void MergeFromFail(int line) {
- GOOGLE_CHECK(false) << __FILE__ << ":" << line;
-}
-
-} // namespace
-
-
// ===================================================================
#if !defined(_MSC_VER) || _MSC_VER >= 1900
@@ -264,6 +258,7 @@ Api* Api::New(::google::protobuf::Arena* arena) const {
}
void Api::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.Api)
name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
version_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
if (GetArenaNoVirtual() == NULL && source_context_ != NULL) delete source_context_;
@@ -276,7 +271,7 @@ void Api::Clear() {
bool Api::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.Api)
for (;;) {
@@ -473,8 +468,8 @@ void Api::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.Api)
}
-::google::protobuf::uint8* Api::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* Api::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Api)
// optional string name = 1;
if (this->name().size() > 0) {
@@ -490,15 +485,15 @@ void Api::SerializeWithCachedSizes(
// repeated .google.protobuf.Method methods = 2;
for (unsigned int i = 0, n = this->methods_size(); i < n; i++) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 2, this->methods(i), target);
+ InternalWriteMessageNoVirtualToArray(
+ 2, this->methods(i), false, target);
}
// repeated .google.protobuf.Option options = 3;
for (unsigned int i = 0, n = this->options_size(); i < n; i++) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 3, this->options(i), target);
+ InternalWriteMessageNoVirtualToArray(
+ 3, this->options(i), false, target);
}
// optional string version = 4;
@@ -515,15 +510,15 @@ void Api::SerializeWithCachedSizes(
// optional .google.protobuf.SourceContext source_context = 5;
if (this->has_source_context()) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 5, *this->source_context_, target);
+ InternalWriteMessageNoVirtualToArray(
+ 5, *this->source_context_, false, target);
}
// repeated .google.protobuf.Mixin mixins = 6;
for (unsigned int i = 0, n = this->mixins_size(); i < n; i++) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 6, this->mixins(i), target);
+ InternalWriteMessageNoVirtualToArray(
+ 6, this->mixins(i), false, target);
}
// optional .google.protobuf.Syntax syntax = 7;
@@ -537,6 +532,7 @@ void Api::SerializeWithCachedSizes(
}
int Api::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Api)
int total_size = 0;
// optional string name = 1;
@@ -597,19 +593,27 @@ int Api::ByteSize() const {
}
void Api::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Api)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const Api* source =
::google::protobuf::internal::DynamicCastToGenerated<const Api>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.Api)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.Api)
MergeFrom(*source);
}
}
void Api::MergeFrom(const Api& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Api)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
methods_.MergeFrom(from.methods_);
options_.MergeFrom(from.options_);
mixins_.MergeFrom(from.mixins_);
@@ -630,12 +634,14 @@ void Api::MergeFrom(const Api& from) {
}
void Api::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.Api)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void Api::CopyFrom(const Api& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Api)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -703,6 +709,7 @@ void Api::clear_name() {
return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* Api::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Api.name)
return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -806,6 +813,7 @@ void Api::clear_version() {
return version_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* Api::release_version() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Api.version)
return version_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -840,6 +848,7 @@ const ::google::protobuf::SourceContext& Api::source_context() const {
return source_context_;
}
::google::protobuf::SourceContext* Api::release_source_context() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Api.source_context)
::google::protobuf::SourceContext* temp = source_context_;
source_context_ = NULL;
@@ -983,8 +992,17 @@ Method* Method::New(::google::protobuf::Arena* arena) const {
}
void Method::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.Method)
+#if defined(__clang__)
+#define ZR_HELPER_(f) \
+ _Pragma("clang diagnostic push") \
+ _Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"") \
+ __builtin_offsetof(Method, f) \
+ _Pragma("clang diagnostic pop")
+#else
#define ZR_HELPER_(f) reinterpret_cast<char*>(\
&reinterpret_cast<Method*>(16)->f)
+#endif
#define ZR_(first, last) do {\
::memset(&first, 0,\
@@ -1004,7 +1022,7 @@ void Method::Clear() {
bool Method::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.Method)
for (;;) {
@@ -1204,8 +1222,8 @@ void Method::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.Method)
}
-::google::protobuf::uint8* Method::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* Method::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Method)
// optional string name = 1;
if (this->name().size() > 0) {
@@ -1253,8 +1271,8 @@ void Method::SerializeWithCachedSizes(
// repeated .google.protobuf.Option options = 6;
for (unsigned int i = 0, n = this->options_size(); i < n; i++) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 6, this->options(i), target);
+ InternalWriteMessageNoVirtualToArray(
+ 6, this->options(i), false, target);
}
// optional .google.protobuf.Syntax syntax = 7;
@@ -1268,6 +1286,7 @@ void Method::SerializeWithCachedSizes(
}
int Method::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Method)
int total_size = 0;
// optional string name = 1;
@@ -1322,19 +1341,27 @@ int Method::ByteSize() const {
}
void Method::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Method)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const Method* source =
::google::protobuf::internal::DynamicCastToGenerated<const Method>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.Method)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.Method)
MergeFrom(*source);
}
}
void Method::MergeFrom(const Method& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Method)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
options_.MergeFrom(from.options_);
if (from.name().size() > 0) {
@@ -1360,12 +1387,14 @@ void Method::MergeFrom(const Method& from) {
}
void Method::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.Method)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void Method::CopyFrom(const Method& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Method)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -1433,6 +1462,7 @@ void Method::clear_name() {
return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* Method::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Method.name)
return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -1476,6 +1506,7 @@ void Method::clear_request_type_url() {
return request_type_url_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* Method::release_request_type_url() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Method.request_type_url)
return request_type_url_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -1533,6 +1564,7 @@ void Method::clear_response_type_url() {
return response_type_url_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* Method::release_response_type_url() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Method.response_type_url)
return response_type_url_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -1677,13 +1709,14 @@ Mixin* Mixin::New(::google::protobuf::Arena* arena) const {
}
void Mixin::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.Mixin)
name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
root_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
bool Mixin::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.Mixin)
for (;;) {
@@ -1771,8 +1804,8 @@ void Mixin::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.Mixin)
}
-::google::protobuf::uint8* Mixin::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* Mixin::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Mixin)
// optional string name = 1;
if (this->name().size() > 0) {
@@ -1801,6 +1834,7 @@ void Mixin::SerializeWithCachedSizes(
}
int Mixin::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Mixin)
int total_size = 0;
// optional string name = 1;
@@ -1824,19 +1858,27 @@ int Mixin::ByteSize() const {
}
void Mixin::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Mixin)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const Mixin* source =
::google::protobuf::internal::DynamicCastToGenerated<const Mixin>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.Mixin)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.Mixin)
MergeFrom(*source);
}
}
void Mixin::MergeFrom(const Mixin& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Mixin)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from.name().size() > 0) {
name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
@@ -1848,12 +1890,14 @@ void Mixin::MergeFrom(const Mixin& from) {
}
void Mixin::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.Mixin)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void Mixin::CopyFrom(const Mixin& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Mixin)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -1916,6 +1960,7 @@ void Mixin::clear_name() {
return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* Mixin::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Mixin.name)
return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -1959,6 +2004,7 @@ void Mixin::clear_root() {
return root_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* Mixin::release_root() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Mixin.root)
return root_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
diff --git a/src/google/protobuf/api.pb.h b/src/google/protobuf/api.pb.h
index e1dca4e4..c9ec923a 100644
--- a/src/google/protobuf/api.pb.h
+++ b/src/google/protobuf/api.pb.h
@@ -45,7 +45,7 @@ class Mixin;
// ===================================================================
-class LIBPROTOBUF_EXPORT Api : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT Api : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Api) */ {
public:
Api();
virtual ~Api();
@@ -79,7 +79,11 @@ class LIBPROTOBUF_EXPORT Api : public ::google::protobuf::Message {
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
@@ -196,7 +200,7 @@ class LIBPROTOBUF_EXPORT Api : public ::google::protobuf::Message {
};
// -------------------------------------------------------------------
-class LIBPROTOBUF_EXPORT Method : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT Method : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Method) */ {
public:
Method();
virtual ~Method();
@@ -230,7 +234,11 @@ class LIBPROTOBUF_EXPORT Method : public ::google::protobuf::Message {
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
@@ -337,7 +345,7 @@ class LIBPROTOBUF_EXPORT Method : public ::google::protobuf::Message {
};
// -------------------------------------------------------------------
-class LIBPROTOBUF_EXPORT Mixin : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT Mixin : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Mixin) */ {
public:
Mixin();
virtual ~Mixin();
@@ -371,7 +379,11 @@ class LIBPROTOBUF_EXPORT Mixin : public ::google::protobuf::Message {
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
@@ -468,6 +480,7 @@ inline ::std::string* Api::mutable_name() {
return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* Api::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Api.name)
return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -571,6 +584,7 @@ inline ::std::string* Api::mutable_version() {
return version_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* Api::release_version() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Api.version)
return version_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -605,6 +619,7 @@ inline ::google::protobuf::SourceContext* Api::mutable_source_context() {
return source_context_;
}
inline ::google::protobuf::SourceContext* Api::release_source_context() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Api.source_context)
::google::protobuf::SourceContext* temp = source_context_;
source_context_ = NULL;
@@ -699,6 +714,7 @@ inline ::std::string* Method::mutable_name() {
return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* Method::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Method.name)
return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -742,6 +758,7 @@ inline ::std::string* Method::mutable_request_type_url() {
return request_type_url_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* Method::release_request_type_url() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Method.request_type_url)
return request_type_url_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -799,6 +816,7 @@ inline ::std::string* Method::mutable_response_type_url() {
return response_type_url_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* Method::release_response_type_url() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Method.response_type_url)
return response_type_url_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -904,6 +922,7 @@ inline ::std::string* Mixin::mutable_name() {
return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* Mixin::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Mixin.name)
return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -947,6 +966,7 @@ inline ::std::string* Mixin::mutable_root() {
return root_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* Mixin::release_root() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Mixin.root)
return root_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
diff --git a/src/google/protobuf/api.proto b/src/google/protobuf/api.proto
index 597a6497..dbe87b8f 100644
--- a/src/google/protobuf/api.proto
+++ b/src/google/protobuf/api.proto
@@ -27,6 +27,7 @@
// 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.
+
syntax = "proto3";
package google.protobuf;
@@ -34,11 +35,11 @@ package google.protobuf;
import "google/protobuf/source_context.proto";
import "google/protobuf/type.proto";
+option csharp_namespace = "Google.Protobuf.WellKnownTypes";
option java_package = "com.google.protobuf";
option java_outer_classname = "ApiProto";
option java_multiple_files = true;
option java_generate_equals_and_hash = true;
-option csharp_namespace = "Google.Protobuf.WellKnownTypes";
option objc_class_prefix = "GPB";
// Api is a light-weight descriptor for a protocol buffer service.
@@ -75,6 +76,7 @@ message Api {
// be omitted. Zero major versions must only be used for
// experimental, none-GA apis.
//
+ //
string version = 4;
// Source context for the protocol buffer service represented by this
@@ -141,7 +143,6 @@ message Method {
//
// package google.storage.v2;
// service Storage {
-// // (-- see AccessControl.GetAcl --)
// rpc GetAcl(GetAclRequest) returns (Acl);
//
// // Get a data record.
diff --git a/src/google/protobuf/arena.cc b/src/google/protobuf/arena.cc
index cd0b21a7..78e20946 100755
--- a/src/google/protobuf/arena.cc
+++ b/src/google/protobuf/arena.cc
@@ -30,6 +30,7 @@
#include <google/protobuf/arena.h>
+
#ifdef ADDRESS_SANITIZER
#include <sanitizer/asan_interface.h>
#endif
@@ -37,6 +38,7 @@
namespace google {
namespace protobuf {
+
google::protobuf::internal::SequenceNumber Arena::lifecycle_id_generator_;
#if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL)
Arena::ThreadCache& Arena::thread_cache() {
@@ -131,12 +133,7 @@ Arena::Block* Arena::NewBlock(void* me, Block* my_last_block, size_t n,
Block* b = reinterpret_cast<Block*>(options_.block_alloc(size));
b->pos = kHeaderSize + n;
b->size = size;
- if (b->avail() == 0) {
- // Do not attempt to reuse this block.
- b->owner = NULL;
- } else {
- b->owner = me;
- }
+ b->owner = me;
#ifdef ADDRESS_SANITIZER
// Poison the rest of the block for ASAN. It was unpoisoned by the underlying
// malloc but it's not yet usable until we return it as part of an allocation.
@@ -221,9 +218,7 @@ void* Arena::SlowAlloc(size_t n) {
}
b = NewBlock(me, b, n, options_.start_block_size, options_.max_block_size);
AddBlock(b);
- if (b->owner == me) { // If this block can be reused (see NewBlock()).
- SetThreadCacheBlock(b);
- }
+ SetThreadCacheBlock(b);
return reinterpret_cast<char*>(b) + kHeaderSize;
}
@@ -247,6 +242,19 @@ uint64 Arena::SpaceUsed() const {
return space_used;
}
+pair<uint64, uint64> Arena::SpaceAllocatedAndUsed() const {
+ uint64 allocated = 0;
+ uint64 used = 0;
+
+ Block* b = reinterpret_cast<Block*>(google::protobuf::internal::NoBarrier_Load(&blocks_));
+ while (b != NULL) {
+ allocated += b->size;
+ used += (b->pos - kHeaderSize);
+ b = b->next;
+ }
+ return std::make_pair(allocated, used);
+}
+
uint64 Arena::FreeBlocks() {
uint64 space_allocated = 0;
Block* b = reinterpret_cast<Block*>(google::protobuf::internal::NoBarrier_Load(&blocks_));
diff --git a/src/google/protobuf/arena.h b/src/google/protobuf/arena.h
index 40c1e7c2..58b1e126 100644
--- a/src/google/protobuf/arena.h
+++ b/src/google/protobuf/arena.h
@@ -56,6 +56,7 @@ using type_info = ::type_info;
#include <google/protobuf/stubs/mutex.h>
#include <google/protobuf/stubs/type_traits.h>
+
namespace google {
namespace protobuf {
@@ -76,7 +77,7 @@ template<typename T> void arena_destruct_object(void* object) {
template<typename T> void arena_delete_object(void* object) {
delete reinterpret_cast<T*>(object);
}
-inline void arena_free(void* object, size_t size) {
+inline void arena_free(void* object, size_t /* size */) {
free(object);
}
@@ -210,7 +211,12 @@ struct ArenaOptions {
//
// This protocol is implemented by all arena-enabled proto2 message classes as
// well as RepeatedPtrField.
+
+#if __cplusplus >= 201103L
+class LIBPROTOBUF_EXPORT Arena final {
+#else
class LIBPROTOBUF_EXPORT Arena {
+#endif
public:
// Arena constructor taking custom options. See ArenaOptions below for
// descriptions of the options available.
@@ -446,6 +452,10 @@ class LIBPROTOBUF_EXPORT Arena {
// As above, but does not include any free space in underlying blocks.
GOOGLE_ATTRIBUTE_NOINLINE uint64 SpaceUsed() const;
+ // Combines SpaceAllocated and SpaceUsed. Returns a pair of
+ // <space_allocated, space_used>.
+ GOOGLE_ATTRIBUTE_NOINLINE pair<uint64, uint64> SpaceAllocatedAndUsed() const;
+
// Frees all storage allocated by this arena after calling destructors
// registered with OwnDestructor() and freeing objects registered with Own().
// Any objects allocated on this arena are unusable after this call. It also
@@ -507,11 +517,11 @@ class LIBPROTOBUF_EXPORT Arena {
//
// This is inside Arena because only Arena has the friend relationships
// necessary to see the underlying generated code traits.
- template<typename T>
- struct is_arena_constructable :
- public google::protobuf::internal::integral_constant<bool,
- sizeof(InternalIsArenaConstructableHelper::ArenaConstructable<
- const T>(static_cast<const T*>(0))) == sizeof(char)> {
+ template <typename T>
+ struct is_arena_constructable
+ : public google::protobuf::internal::integral_constant<
+ bool, sizeof(InternalIsArenaConstructableHelper::ArenaConstructable<
+ const T>(static_cast<const T*>(0))) == sizeof(char)> {
};
private:
@@ -591,14 +601,12 @@ class LIBPROTOBUF_EXPORT Arena {
// This is inside Arena because only Arena has the friend relationships
// necessary to see the underlying generated code traits.
template<typename T>
- struct is_destructor_skippable :
- public google::protobuf::internal::integral_constant<bool,
- sizeof(InternalIsDestructorSkippableHelper::DestructorSkippable<
- const T>(static_cast<const T*>(0))) ==
- sizeof(char) ||
- google::protobuf::internal::has_trivial_destructor<T>::value> {
- };
-
+ struct is_destructor_skippable
+ : public google::protobuf::internal::integral_constant<
+ bool,
+ sizeof(InternalIsDestructorSkippableHelper::DestructorSkippable<
+ const T>(static_cast<const T*>(0))) == sizeof(char) ||
+ google::protobuf::internal::has_trivial_destructor<T>::value> {};
// CreateMessage<T> requires that T supports arenas, but this private method
// works whether or not T supports arenas. These are not exposed to user code
@@ -793,7 +801,7 @@ class LIBPROTOBUF_EXPORT Arena {
template <typename T>
static void CreateInArenaStorageInternal(
T* ptr, Arena* arena, google::protobuf::internal::false_type) {
- new (ptr) T;
+ new (ptr) T();
}
template <typename T>
diff --git a/src/google/protobuf/arena_nc_test.py b/src/google/protobuf/arena_nc_test.py
index 87a69b2a..56a7dd05 100644
--- a/src/google/protobuf/arena_nc_test.py
+++ b/src/google/protobuf/arena_nc_test.py
@@ -35,7 +35,7 @@
import unittest
from google3.testing.pybase import fake_target_util
-import unittest
+from google3.testing.pybase import unittest
class ArenaNcTest(unittest.TestCase):
diff --git a/src/google/protobuf/arena_unittest.cc b/src/google/protobuf/arena_unittest.cc
index 6b67f446..5f33e939 100644
--- a/src/google/protobuf/arena_unittest.cc
+++ b/src/google/protobuf/arena_unittest.cc
@@ -42,7 +42,6 @@
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/scoped_ptr.h>
#include <google/protobuf/arena_test_util.h>
#include <google/protobuf/test_util.h>
#include <google/protobuf/unittest.pb.h>
@@ -342,6 +341,64 @@ TEST(ArenaTest, Swap) {
EXPECT_EQ(42, arena2_message->unknown_fields().field(0).varint());
}
+TEST(ArenaTest, ReflectionSwapFields) {
+ Arena arena1;
+ Arena arena2;
+ TestAllTypes* arena1_message;
+ TestAllTypes* arena2_message;
+
+ // Case 1: messages on different arenas, only one message is set.
+ arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
+ arena2_message = Arena::CreateMessage<TestAllTypes>(&arena2);
+ TestUtil::SetAllFields(arena1_message);
+ const Reflection* reflection = arena1_message->GetReflection();
+ std::vector<const FieldDescriptor*> fields;
+ reflection->ListFields(*arena1_message, &fields);
+ reflection->SwapFields(arena1_message, arena2_message, fields);
+ EXPECT_EQ(&arena1, arena1_message->GetArena());
+ EXPECT_EQ(&arena2, arena2_message->GetArena());
+ string output;
+ arena1_message->SerializeToString(&output);
+ EXPECT_EQ(0, output.size());
+ TestUtil::ExpectAllFieldsSet(*arena2_message);
+ reflection->SwapFields(arena1_message, arena2_message, fields);
+ arena2_message->SerializeToString(&output);
+ EXPECT_EQ(0, output.size());
+ TestUtil::ExpectAllFieldsSet(*arena1_message);
+
+ // Case 2: messages on different arenas, both messages are set.
+ arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
+ arena2_message = Arena::CreateMessage<TestAllTypes>(&arena2);
+ TestUtil::SetAllFields(arena1_message);
+ TestUtil::SetAllFields(arena2_message);
+ reflection->SwapFields(arena1_message, arena2_message, fields);
+ EXPECT_EQ(&arena1, arena1_message->GetArena());
+ EXPECT_EQ(&arena2, arena2_message->GetArena());
+ TestUtil::ExpectAllFieldsSet(*arena1_message);
+ TestUtil::ExpectAllFieldsSet(*arena2_message);
+
+ // Case 3: messages on different arenas with different lifetimes.
+ arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
+ {
+ Arena arena3;
+ TestAllTypes* arena3_message = Arena::CreateMessage<TestAllTypes>(&arena3);
+ TestUtil::SetAllFields(arena3_message);
+ reflection->SwapFields(arena1_message, arena3_message, fields);
+ }
+ TestUtil::ExpectAllFieldsSet(*arena1_message);
+
+ // Case 4: one message on arena, the other on heap.
+ arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
+ TestAllTypes message;
+ TestUtil::SetAllFields(arena1_message);
+ reflection->SwapFields(arena1_message, &message, fields);
+ EXPECT_EQ(&arena1, arena1_message->GetArena());
+ EXPECT_EQ(NULL, message.GetArena());
+ arena1_message->SerializeToString(&output);
+ EXPECT_EQ(0, output.size());
+ TestUtil::ExpectAllFieldsSet(message);
+}
+
TEST(ArenaTest, SetAllocatedMessage) {
Arena arena;
TestAllTypes *arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
diff --git a/src/google/protobuf/arenastring.h b/src/google/protobuf/arenastring.h
index 1dacdc68..590ffce9 100755
--- a/src/google/protobuf/arenastring.h
+++ b/src/google/protobuf/arenastring.h
@@ -36,7 +36,6 @@
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/fastmem.h>
-
#include <google/protobuf/arena.h>
#include <google/protobuf/generated_message_util.h>
@@ -65,7 +64,7 @@ struct LIBPROTOBUF_EXPORT ArenaStringPtr {
}
// Basic accessors.
- inline const ::std::string& Get(const ::std::string* default_value) const {
+ inline const ::std::string& Get(const ::std::string* /* default_value */) const {
return *ptr_;
}
@@ -103,7 +102,7 @@ struct LIBPROTOBUF_EXPORT ArenaStringPtr {
// state. Used to implement unsafe_arena_release_<field>() methods on
// generated classes.
inline ::std::string* UnsafeArenaRelease(const ::std::string* default_value,
- ::google::protobuf::Arena* arena) {
+ ::google::protobuf::Arena* /* arena */) {
if (ptr_ == default_value) {
return NULL;
}
@@ -135,7 +134,8 @@ struct LIBPROTOBUF_EXPORT ArenaStringPtr {
// UnsafeArenaRelease() on another field of a message in the same arena. Used
// to implement unsafe_arena_set_allocated_<field> in generated classes.
inline void UnsafeArenaSetAllocated(const ::std::string* default_value,
- ::std::string* value, ::google::protobuf::Arena* arena) {
+ ::std::string* value,
+ ::google::protobuf::Arena* /* arena */) {
if (value != NULL) {
ptr_ = value;
} else {
@@ -164,7 +164,7 @@ struct LIBPROTOBUF_EXPORT ArenaStringPtr {
// the user) will always be the empty string. Assumes that |default_value|
// is an empty string.
inline void ClearToEmpty(const ::std::string* default_value,
- ::google::protobuf::Arena* arena) {
+ ::google::protobuf::Arena* /* arena */) {
if (ptr_ == default_value) {
// Already set to default (which is empty) -- do nothing.
} else {
@@ -176,7 +176,7 @@ struct LIBPROTOBUF_EXPORT ArenaStringPtr {
// overhead of heap operations. After this returns, the content (as seen by
// the user) will always be equal to |default_value|.
inline void ClearToDefault(const ::std::string* default_value,
- ::google::protobuf::Arena* arena) {
+ ::google::protobuf::Arena* /* arena */) {
if (ptr_ == default_value) {
// Already set to default -- do nothing.
} else {
@@ -216,7 +216,7 @@ struct LIBPROTOBUF_EXPORT ArenaStringPtr {
void AssignWithDefault(const ::std::string* default_value, ArenaStringPtr value);
- inline const ::std::string& GetNoArena(const ::std::string* default_value) const {
+ inline const ::std::string& GetNoArena(const ::std::string* /* default_value */) const {
return *ptr_;
}
diff --git a/src/google/protobuf/arenastring_unittest.cc b/src/google/protobuf/arenastring_unittest.cc
index 3fb582be..ea405d7d 100644
--- a/src/google/protobuf/arenastring_unittest.cc
+++ b/src/google/protobuf/arenastring_unittest.cc
@@ -28,9 +28,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// arenastring_unittest.cc is not open-sourced. Do not include in open-source
-// distribution.
-
// Based on mvels@'s frankenstring.
#include <google/protobuf/arenastring.h>
diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc
index 26a4f0b0..bb781b0a 100644
--- a/src/google/protobuf/compiler/command_line_interface.cc
+++ b/src/google/protobuf/compiler/command_line_interface.cc
@@ -33,6 +33,7 @@
// Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/compiler/command_line_interface.h>
+#include <google/protobuf/stubs/platform_macros.h>
#include <stdio.h>
#include <sys/types.h>
@@ -45,9 +46,12 @@
#include <unistd.h>
#endif
#include <errno.h>
+#include <fstream>
#include <iostream>
#include <ctype.h>
+#include <limits.h> //For PATH_MAX
+
#include <memory>
#ifndef _SHARED_PTR_H
#include <google/protobuf/stubs/shared_ptr.h>
@@ -271,15 +275,35 @@ class CommandLineInterface::ErrorPrinter : public MultiFileErrorCollector,
// implements MultiFileErrorCollector ------------------------------
void AddError(const string& filename, int line, int column,
const string& message) {
+ AddErrorOrWarning(filename, line, column, message, "error", std::cerr);
+ }
+
+ void AddWarning(const string& filename, int line, int column,
+ const string& message) {
+ AddErrorOrWarning(filename, line, column, message, "warning", std::clog);
+ }
+
+ // implements io::ErrorCollector -----------------------------------
+ void AddError(int line, int column, const string& message) {
+ AddError("input", line, column, message);
+ }
+
+ void AddWarning(int line, int column, const string& message) {
+ AddErrorOrWarning("input", line, column, message, "warning", std::clog);
+ }
+ private:
+ void AddErrorOrWarning(
+ const string& filename, int line, int column,
+ const string& message, const string& type, ostream& out) {
// Print full path when running under MSVS
string dfile;
if (format_ == CommandLineInterface::ERROR_FORMAT_MSVS &&
tree_ != NULL &&
tree_->VirtualFileToDiskFile(filename, &dfile)) {
- std::cerr << dfile;
+ out << dfile;
} else {
- std::cerr << filename;
+ out << filename;
}
// Users typically expect 1-based line/column numbers, so we add 1
@@ -288,24 +312,22 @@ class CommandLineInterface::ErrorPrinter : public MultiFileErrorCollector,
// Allow for both GCC- and Visual-Studio-compatible output.
switch (format_) {
case CommandLineInterface::ERROR_FORMAT_GCC:
- std::cerr << ":" << (line + 1) << ":" << (column + 1);
+ out << ":" << (line + 1) << ":" << (column + 1);
break;
case CommandLineInterface::ERROR_FORMAT_MSVS:
- std::cerr << "(" << (line + 1)
- << ") : error in column=" << (column + 1);
+ out << "(" << (line + 1) << ") : "
+ << type << " in column=" << (column + 1);
break;
}
}
- std::cerr << ": " << message << std::endl;
- }
-
- // implements io::ErrorCollector -----------------------------------
- void AddError(int line, int column, const string& message) {
- AddError("input", line, column, message);
+ if (type == "warning") {
+ out << ": warning: " << message << std::endl;
+ } else {
+ out << ": " << message << std::endl;
+ }
}
- private:
const ErrorFormat format_;
DiskSourceTree *tree_;
};
@@ -590,7 +612,7 @@ CommandLineInterface::MemoryOutputStream::~MemoryOutputStream() {
} else {
// This was an OpenForInsert().
- // If the data doens't end with a clean line break, add one.
+ // If the data doesn't end with a clean line break, add one.
if (!data_.empty() && data_[data_.size() - 1] != '\n') {
data_.push_back('\n');
}
@@ -617,18 +639,23 @@ CommandLineInterface::MemoryOutputStream::~MemoryOutputStream() {
return;
}
- // Seek backwards to the beginning of the line, which is where we will
- // insert the data. Note that this has the effect of pushing the insertion
- // point down, so the data is inserted before it. This is intentional
- // because it means that multiple insertions at the same point will end
- // up in the expected order in the final output.
- pos = target->find_last_of('\n', pos);
- if (pos == string::npos) {
- // Insertion point is on the first line.
- pos = 0;
+ if ((pos > 3) && (target->substr(pos - 3, 2) == "/*")) {
+ // Support for inline "/* @@protoc_insertion_point() */"
+ pos = pos - 3;
} else {
- // Advance to character after '\n'.
- ++pos;
+ // Seek backwards to the beginning of the line, which is where we will
+ // insert the data. Note that this has the effect of pushing the
+ // insertion point down, so the data is inserted before it. This is
+ // intentional because it means that multiple insertions at the same point
+ // will end up in the expected order in the final output.
+ pos = target->find_last_of('\n', pos);
+ if (pos == string::npos) {
+ // Insertion point is on the first line.
+ pos = 0;
+ } else {
+ // Advance to character after '\n'.
+ ++pos;
+ }
}
// Extract indent.
@@ -925,17 +952,23 @@ bool CommandLineInterface::MakeInputsBeProtoPathRelative(
return true;
}
+
CommandLineInterface::ParseArgumentStatus
CommandLineInterface::ParseArguments(int argc, const char* const argv[]) {
executable_name_ = argv[0];
+ vector<string> arguments;
+ for (int i = 1; i < argc; ++i) {
+ arguments.push_back(argv[i]);
+ }
+
// Iterate through all arguments and parse them.
- for (int i = 1; i < argc; i++) {
+ for (int i = 0; i < arguments.size(); ++i) {
string name, value;
- if (ParseArgument(argv[i], &name, &value)) {
+ if (ParseArgument(arguments[i].c_str(), &name, &value)) {
// Returned true => Use the next argument as the flag value.
- if (i + 1 == argc || argv[i+1][0] == '-') {
+ if (i + 1 == arguments.size() || arguments[i + 1][0] == '-') {
std::cerr << "Missing value for flag: " << name << std::endl;
if (name == "--decode") {
std::cerr << "To decode an unknown message, use --decode_raw."
@@ -944,7 +977,7 @@ CommandLineInterface::ParseArguments(int argc, const char* const argv[]) {
return PARSE_ARGUMENT_FAIL;
} else {
++i;
- value = argv[i];
+ value = arguments[i];
}
}
@@ -1106,8 +1139,13 @@ CommandLineInterface::InterpretArgument(const string& name,
// Make sure disk path exists, warn otherwise.
if (access(disk_path.c_str(), F_OK) < 0) {
- std::cerr << disk_path << ": warning: directory does not exist."
- << std::endl;
+ // Try the original path; it may have just happed to have a '=' in it.
+ if (access(parts[i].c_str(), F_OK) < 0) {
+ cerr << disk_path << ": warning: directory does not exist." << endl;
+ } else {
+ virtual_path = "";
+ disk_path = parts[i];
+ }
}
// Don't use make_pair as the old/default standard library on Solaris
@@ -1353,7 +1391,7 @@ void CommandLineInterface::PrintHelpText() {
" defined in the given proto files. Groups share\n"
" the same field number space with the parent \n"
" message. Extension ranges are counted as \n"
-" occupied fields numbers."
+" occupied fields numbers.\n"
<< std::endl;
if (!plugin_prefix_.empty()) {
std::cerr <<
@@ -1443,6 +1481,7 @@ bool CommandLineInterface::GenerateDependencyManifestFile(
for (int i = 0; i < parsed_files.size(); i++) {
GetTransitiveDependencies(parsed_files[i],
false,
+ false,
&already_seen,
file_set.mutable_file());
}
@@ -1522,6 +1561,7 @@ bool CommandLineInterface::GeneratePluginOutput(
for (int i = 0; i < parsed_files.size(); i++) {
request.add_file_to_generate(parsed_files[i]->name());
GetTransitiveDependencies(parsed_files[i],
+ true, // Include json_name for plugins.
true, // Include source code info.
&already_seen, request.mutable_proto_file());
}
@@ -1654,6 +1694,7 @@ bool CommandLineInterface::WriteDescriptorSet(
set<const FileDescriptor*> already_seen;
for (int i = 0; i < parsed_files.size(); i++) {
GetTransitiveDependencies(parsed_files[i],
+ true, // Include json_name
source_info_in_descriptor_set_,
&already_seen, file_set.mutable_file());
}
@@ -1665,6 +1706,7 @@ bool CommandLineInterface::WriteDescriptorSet(
}
FileDescriptorProto* file_proto = file_set.add_file();
parsed_files[i]->CopyTo(file_proto);
+ parsed_files[i]->CopyJsonNameTo(file_proto);
if (source_info_in_descriptor_set_) {
parsed_files[i]->CopySourceCodeInfoTo(file_proto);
}
@@ -1699,7 +1741,9 @@ bool CommandLineInterface::WriteDescriptorSet(
}
void CommandLineInterface::GetTransitiveDependencies(
- const FileDescriptor* file, bool include_source_code_info,
+ const FileDescriptor* file,
+ bool include_json_name,
+ bool include_source_code_info,
set<const FileDescriptor*>* already_seen,
RepeatedPtrField<FileDescriptorProto>* output) {
if (!already_seen->insert(file).second) {
@@ -1709,13 +1753,18 @@ void CommandLineInterface::GetTransitiveDependencies(
// Add all dependencies.
for (int i = 0; i < file->dependency_count(); i++) {
- GetTransitiveDependencies(file->dependency(i), include_source_code_info,
+ GetTransitiveDependencies(file->dependency(i),
+ include_json_name,
+ include_source_code_info,
already_seen, output);
}
// Add this file.
FileDescriptorProto* new_descriptor = output->Add();
file->CopyTo(new_descriptor);
+ if (include_json_name) {
+ file->CopyJsonNameTo(new_descriptor);
+ }
if (include_source_code_info) {
file->CopySourceCodeInfoTo(new_descriptor);
}
diff --git a/src/google/protobuf/compiler/command_line_interface.h b/src/google/protobuf/compiler/command_line_interface.h
index 7e611c44..d1377666 100644
--- a/src/google/protobuf/compiler/command_line_interface.h
+++ b/src/google/protobuf/compiler/command_line_interface.h
@@ -212,6 +212,7 @@ class LIBPROTOC_EXPORT CommandLineInterface {
// Parse all command-line arguments.
ParseArgumentStatus ParseArguments(int argc, const char* const argv[]);
+
// Parses a command-line argument into a name/value pair. Returns
// true if the next argument in the argv should be used as the value,
// false otherwise.
@@ -262,8 +263,11 @@ class LIBPROTOC_EXPORT CommandLineInterface {
// in order. Any files in *already_seen will not be added, and each file
// added will be inserted into *already_seen. If include_source_code_info is
// true then include the source code information in the FileDescriptorProtos.
+ // If include_json_name is true, populate the json_name field of
+ // FieldDescriptorProto for all fields.
static void GetTransitiveDependencies(
const FileDescriptor* file,
+ bool include_json_name,
bool include_source_code_info,
set<const FileDescriptor*>* already_seen,
RepeatedPtrField<FileDescriptorProto>* output);
diff --git a/src/google/protobuf/compiler/command_line_interface_unittest.cc b/src/google/protobuf/compiler/command_line_interface_unittest.cc
index fa792dae..0ebf9b6a 100644
--- a/src/google/protobuf/compiler/command_line_interface_unittest.cc
+++ b/src/google/protobuf/compiler/command_line_interface_unittest.cc
@@ -60,17 +60,19 @@
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/substitute.h>
+#include <google/protobuf/testing/file.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
-// Disable the whole test when we use tcmalloc for "draconian" heap checks, in
-// which case tcmalloc will print warnings that fail the plugin tests.
-#if !GOOGLE_PROTOBUF_HEAP_CHECK_DRACONIAN
namespace google {
namespace protobuf {
namespace compiler {
+// Disable the whole test when we use tcmalloc for "draconian" heap checks, in
+// which case tcmalloc will print warnings that fail the plugin tests.
+#if !GOOGLE_PROTOBUF_HEAP_CHECK_DRACONIAN
+
#if defined(_WIN32)
#ifndef STDIN_FILENO
#define STDIN_FILENO 0
@@ -376,7 +378,9 @@ void CommandLineInterfaceTest::CreateTempFile(
// Write file.
string full_name = temp_directory_ + "/" + name;
- GOOGLE_CHECK_OK(File::SetContents(full_name, contents, true));
+ GOOGLE_CHECK_OK(File::SetContents(
+ full_name, StringReplace(contents, "$tmpdir", temp_directory_, true),
+ true));
}
void CommandLineInterfaceTest::CreateTempDir(const string& name) {
@@ -782,6 +786,21 @@ TEST_F(CommandLineInterfaceTest, NonRootMapping) {
ExpectGenerated("test_generator", "", "bar/foo.proto", "Foo");
}
+TEST_F(CommandLineInterfaceTest, PathWithEqualsSign) {
+ // Test setting up a search path which happens to have '=' in it.
+
+ CreateTempDir("with=sign");
+ CreateTempFile("with=sign/foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir/with=sign foo.proto");
+
+ ExpectNoErrors();
+ ExpectGenerated("test_generator", "", "foo.proto", "Foo");
+}
+
TEST_F(CommandLineInterfaceTest, MultipleGenerators) {
// Test that we can have multiple generators and use both in one invocation,
// each with a different output directory.
@@ -886,6 +905,10 @@ TEST_F(CommandLineInterfaceTest, WriteDescriptorSet) {
EXPECT_EQ("bar.proto", descriptor_set.file(0).name());
// Descriptor set should not have source code info.
EXPECT_FALSE(descriptor_set.file(0).has_source_code_info());
+ // Descriptor set should have json_name.
+ EXPECT_EQ("Bar", descriptor_set.file(0).message_type(0).name());
+ EXPECT_EQ("foo", descriptor_set.file(0).message_type(0).field(0).name());
+ EXPECT_TRUE(descriptor_set.file(0).message_type(0).field(0).has_json_name());
}
TEST_F(CommandLineInterfaceTest, WriteDescriptorSetWithDuplicates) {
@@ -919,6 +942,10 @@ TEST_F(CommandLineInterfaceTest, WriteDescriptorSetWithDuplicates) {
EXPECT_EQ("baz.proto", descriptor_set.file(2).name());
// Descriptor set should not have source code info.
EXPECT_FALSE(descriptor_set.file(0).has_source_code_info());
+ // Descriptor set should have json_name.
+ EXPECT_EQ("Bar", descriptor_set.file(0).message_type(0).name());
+ EXPECT_EQ("foo", descriptor_set.file(0).message_type(0).field(0).name());
+ EXPECT_TRUE(descriptor_set.file(0).message_type(0).field(0).has_json_name());
}
TEST_F(CommandLineInterfaceTest, WriteDescriptorSetWithSourceInfo) {
@@ -1082,6 +1109,7 @@ TEST_F(CommandLineInterfaceTest, WriteDependencyManifestFileForAbsolutePath) {
}
#endif // !_WIN32
+
// -------------------------------------------------------------------
TEST_F(CommandLineInterfaceTest, ParseErrors) {
@@ -1413,6 +1441,18 @@ TEST_F(CommandLineInterfaceTest, PluginReceivesSourceCodeInfo) {
"Saw message type MockCodeGenerator_HasSourceCodeInfo: 1.");
}
+TEST_F(CommandLineInterfaceTest, PluginReceivesJsonName) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message MockCodeGenerator_HasJsonName {\n"
+ " optional int32 value = 1;\n"
+ "}\n");
+
+ Run("protocol_compiler --plug_out=$tmpdir --proto_path=$tmpdir foo.proto");
+
+ ExpectErrorSubstring("Saw json_name: 1");
+}
+
TEST_F(CommandLineInterfaceTest, GeneratorPluginNotFound) {
// Test what happens if the plugin isn't found.
@@ -1802,8 +1842,8 @@ TEST_F(EncodeDecodeTest, ProtoParseError) {
} // anonymous namespace
+#endif // !GOOGLE_PROTOBUF_HEAP_CHECK_DRACONIAN
+
} // namespace compiler
} // namespace protobuf
-
-#endif // !GOOGLE_PROTOBUF_HEAP_CHECK_DRACONIAN
} // namespace google
diff --git a/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
index c3e9fe74..77451ab1 100644
--- a/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
@@ -54,6 +54,7 @@
#include <google/protobuf/stubs/substitute.h>
#include <google/protobuf/testing/file.h>
+#include <google/protobuf/testing/file.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
@@ -107,7 +108,7 @@ class MockGeneratorContext : public GeneratorContext {
virtual io::ZeroCopyOutputStream* Open(const string& filename) {
string** map_slot = &files_[filename];
- if (*map_slot != NULL) delete *map_slot;
+ delete *map_slot;
*map_slot = new string;
return new io::StringOutputStream(*map_slot);
diff --git a/src/google/protobuf/compiler/cpp/cpp_enum.cc b/src/google/protobuf/compiler/cpp/cpp_enum.cc
index 1a11bce8..62b7ed4e 100644
--- a/src/google/protobuf/compiler/cpp/cpp_enum.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_enum.cc
@@ -69,11 +69,12 @@ EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor,
EnumGenerator::~EnumGenerator() {}
-void EnumGenerator::FillForwardDeclaration(set<string>* enum_names) {
+void EnumGenerator::FillForwardDeclaration(
+ map<string, const EnumDescriptor*>* enum_names) {
if (!options_.proto_h) {
return;
}
- enum_names->insert(classname_);
+ (*enum_names)[classname_] = descriptor_;
}
void EnumGenerator::GenerateDefinition(io::Printer* printer) {
@@ -83,6 +84,7 @@ void EnumGenerator::GenerateDefinition(io::Printer* printer) {
vars["enumbase"] = classname_ + (options_.proto_h ? " : int" : "");
printer->Print(vars, "enum $enumbase$ {\n");
+ printer->Annotate("enumbase", descriptor_);
printer->Indent();
const EnumValueDescriptor* min_value = descriptor_->value(0);
@@ -96,9 +98,11 @@ void EnumGenerator::GenerateDefinition(io::Printer* printer) {
vars["number"] = Int32ToString(descriptor_->value(i)->number());
vars["prefix"] = (descriptor_->containing_type() == NULL) ?
"" : classname_ + "_";
+ vars["deprecation"] = descriptor_->value(i)->options().deprecated() ?
+ " PROTOBUF_DEPRECATED" : "";
if (i > 0) printer->Print(",\n");
- printer->Print(vars, "$prefix$$name$ = $number$");
+ printer->Print(vars, "$prefix$$name$$deprecation$ = $number$");
if (descriptor_->value(i)->number() < min_value->number()) {
min_value = descriptor_->value(i);
@@ -140,15 +144,16 @@ void EnumGenerator::GenerateDefinition(io::Printer* printer) {
"$prefix$$short_name$_MAX + 1;\n\n");
}
- if (HasDescriptorMethods(descriptor_->file())) {
+ if (HasDescriptorMethods(descriptor_->file(), options_)) {
printer->Print(vars,
"$dllexport$const ::google::protobuf::EnumDescriptor* $classname$_descriptor();\n");
// The _Name and _Parse methods
- printer->Print(vars,
- "inline const ::std::string& $classname$_Name($classname$ value) {\n"
- " return ::google::protobuf::internal::NameOfEnum(\n"
- " $classname$_descriptor(), value);\n"
- "}\n");
+ printer->Print(
+ vars,
+ "inline const ::std::string& $classname$_Name($classname$ value) {\n"
+ " return ::google::protobuf::internal::NameOfEnum(\n"
+ " $classname$_descriptor(), value);\n"
+ "}\n");
printer->Print(vars,
"inline bool $classname$_Parse(\n"
" const ::std::string& name, $classname$* value) {\n"
@@ -164,7 +169,7 @@ GenerateGetEnumDescriptorSpecializations(io::Printer* printer) {
"template <> struct is_proto_enum< $classname$> : ::google::protobuf::internal::true_type "
"{};\n",
"classname", ClassName(descriptor_, true));
- if (HasDescriptorMethods(descriptor_->file())) {
+ if (HasDescriptorMethods(descriptor_->file(), options_)) {
printer->Print(
"template <>\n"
"inline const EnumDescriptor* GetEnumDescriptor< $classname$>() {\n"
@@ -178,12 +183,16 @@ void EnumGenerator::GenerateSymbolImports(io::Printer* printer) {
map<string, string> vars;
vars["nested_name"] = descriptor_->name();
vars["classname"] = classname_;
+ vars["constexpr"] = options_.proto_h ? "constexpr " : "";
printer->Print(vars, "typedef $classname$ $nested_name$;\n");
for (int j = 0; j < descriptor_->value_count(); j++) {
vars["tag"] = EnumValueName(descriptor_->value(j));
+ vars["deprecated_attr"] = descriptor_->value(j)->options().deprecated() ?
+ "GOOGLE_PROTOBUF_DEPRECATED_ATTR " : "";
printer->Print(vars,
- "static const $nested_name$ $tag$ = $classname$_$tag$;\n");
+ "$deprecated_attr$static $constexpr$const $nested_name$ $tag$ =\n"
+ " $classname$_$tag$;\n");
}
printer->Print(vars,
@@ -200,16 +209,18 @@ void EnumGenerator::GenerateSymbolImports(io::Printer* printer) {
" $classname$_$nested_name$_ARRAYSIZE;\n");
}
- if (HasDescriptorMethods(descriptor_->file())) {
+ if (HasDescriptorMethods(descriptor_->file(), options_)) {
printer->Print(vars,
"static inline const ::google::protobuf::EnumDescriptor*\n"
"$nested_name$_descriptor() {\n"
" return $classname$_descriptor();\n"
"}\n");
printer->Print(vars,
- "static inline const ::std::string& $nested_name$_Name($nested_name$ value) {\n"
- " return $classname$_Name(value);\n"
- "}\n");
+ "static inline const ::std::string& "
+ "$nested_name$_Name($nested_name$ value) {"
+ "\n"
+ " return $classname$_Name(value);\n"
+ "}\n");
printer->Print(vars,
"static inline bool $nested_name$_Parse(const ::std::string& name,\n"
" $nested_name$* value) {\n"
@@ -237,8 +248,9 @@ void EnumGenerator::GenerateDescriptorInitializer(
void EnumGenerator::GenerateMethods(io::Printer* printer) {
map<string, string> vars;
vars["classname"] = classname_;
+ vars["constexpr"] = options_.proto_h ? "constexpr " : "";
- if (HasDescriptorMethods(descriptor_->file())) {
+ if (HasDescriptorMethods(descriptor_->file(), options_)) {
printer->Print(vars,
"const ::google::protobuf::EnumDescriptor* $classname$_descriptor() {\n"
" protobuf_AssignDescriptorsOnce();\n"
@@ -287,7 +299,7 @@ void EnumGenerator::GenerateMethods(io::Printer* printer) {
for (int i = 0; i < descriptor_->value_count(); i++) {
vars["value"] = EnumValueName(descriptor_->value(i));
printer->Print(vars,
- "const $classname$ $parent$::$value$;\n");
+ "$constexpr$const $classname$ $parent$::$value$;\n");
}
printer->Print(vars,
"const $classname$ $parent$::$nested_name$_MIN;\n"
diff --git a/src/google/protobuf/compiler/cpp/cpp_enum.h b/src/google/protobuf/compiler/cpp/cpp_enum.h
index f3aa72e4..90edf001 100644
--- a/src/google/protobuf/compiler/cpp/cpp_enum.h
+++ b/src/google/protobuf/compiler/cpp/cpp_enum.h
@@ -35,12 +35,12 @@
#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_H__
#define GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_H__
+#include <map>
#include <set>
#include <string>
#include <google/protobuf/compiler/cpp/cpp_options.h>
#include <google/protobuf/descriptor.h>
-
namespace google {
namespace protobuf {
namespace io {
@@ -55,8 +55,7 @@ namespace cpp {
class EnumGenerator {
public:
// See generator.cc for the meaning of dllexport_decl.
- explicit EnumGenerator(const EnumDescriptor* descriptor,
- const Options& options);
+ EnumGenerator(const EnumDescriptor* descriptor, const Options& options);
~EnumGenerator();
// Header stuff.
@@ -64,8 +63,10 @@ class EnumGenerator {
// Fills the name to use when declaring the enum. This is for use when
// generating other .proto.h files. This code should be placed within the
// enum's package namespace, but NOT within any class, even for nested
- // enums.
- void FillForwardDeclaration(set<string>* enum_names);
+ // enums. A given key in enum_names will map from an enum class name to the
+ // EnumDescriptor that was responsible for its inclusion in the map. This can
+ // be used to associate the descriptor with the code generated for it.
+ void FillForwardDeclaration(map<string, const EnumDescriptor*>* enum_names);
// Generate header code defining the enum. This code should be placed
// within the enum's package namespace, but NOT within any class, even for
@@ -94,10 +95,10 @@ class EnumGenerator {
private:
const EnumDescriptor* descriptor_;
- string classname_;
- Options options_;
+ const string classname_;
+ const Options& options_;
// whether to generate the *_ARRAYSIZE constant.
- bool generate_array_size_;
+ const bool generate_array_size_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumGenerator);
};
diff --git a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
index 824e2205..ffd81529 100644
--- a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
@@ -35,6 +35,7 @@
#include <google/protobuf/compiler/cpp/cpp_enum_field.h>
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
#include <google/protobuf/io/printer.h>
+#include <google/protobuf/wire_format.h>
#include <google/protobuf/stubs/strutil.h>
namespace google {
@@ -58,10 +59,9 @@ void SetEnumVariables(const FieldDescriptor* descriptor,
// ===================================================================
-EnumFieldGenerator::
-EnumFieldGenerator(const FieldDescriptor* descriptor,
- const Options& options)
- : descriptor_(descriptor) {
+EnumFieldGenerator::EnumFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
+ : FieldGenerator(options), descriptor_(descriptor) {
SetEnumVariables(descriptor, &variables_, options);
}
@@ -75,8 +75,8 @@ GeneratePrivateMembers(io::Printer* printer) const {
void EnumFieldGenerator::
GenerateAccessorDeclarations(io::Printer* printer) const {
printer->Print(variables_,
- "$type$ $name$() const$deprecation$;\n"
- "void set_$name$($type$ value)$deprecation$;\n");
+ "$deprecated_attr$$type$ $name$() const;\n"
+ "$deprecated_attr$void set_$name$($type$ value);\n");
}
void EnumFieldGenerator::
@@ -135,15 +135,16 @@ GenerateMergeFromCodedStream(io::Printer* printer) const {
printer->Print(variables_,
"if ($type$_IsValid(value)) {\n"
" set_$name$(static_cast< $type$ >(value));\n");
- if (UseUnknownFieldSet(descriptor_->file())) {
+ if (UseUnknownFieldSet(descriptor_->file(), options_)) {
printer->Print(variables_,
"} else {\n"
" mutable_unknown_fields()->AddVarint($number$, value);\n");
} else {
printer->Print(
"} else {\n"
- " unknown_fields_stream.WriteVarint32(tag);\n"
- " unknown_fields_stream.WriteVarint32(value);\n");
+ " unknown_fields_stream.WriteVarint32($tag$);\n"
+ " unknown_fields_stream.WriteVarint32(value);\n",
+ "tag", SimpleItoa(internal::WireFormat::MakeTag(descriptor_)));
}
printer->Print(variables_,
"}\n");
@@ -228,10 +229,9 @@ GenerateConstructorCode(io::Printer* printer) const {
// ===================================================================
-RepeatedEnumFieldGenerator::
-RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor,
- const Options& options)
- : descriptor_(descriptor) {
+RepeatedEnumFieldGenerator::RepeatedEnumFieldGenerator(
+ const FieldDescriptor* descriptor, const Options& options)
+ : FieldGenerator(options), descriptor_(descriptor) {
SetEnumVariables(descriptor, &variables_, options);
}
@@ -241,8 +241,8 @@ void RepeatedEnumFieldGenerator::
GeneratePrivateMembers(io::Printer* printer) const {
printer->Print(variables_,
"::google::protobuf::RepeatedField<int> $name$_;\n");
- if (descriptor_->is_packed()
- && HasGeneratedMethods(descriptor_->file())) {
+ if (descriptor_->is_packed() &&
+ HasGeneratedMethods(descriptor_->file(), options_)) {
printer->Print(variables_,
"mutable int _$name$_cached_byte_size_;\n");
}
@@ -251,12 +251,12 @@ GeneratePrivateMembers(io::Printer* printer) const {
void RepeatedEnumFieldGenerator::
GenerateAccessorDeclarations(io::Printer* printer) const {
printer->Print(variables_,
- "$type$ $name$(int index) const$deprecation$;\n"
- "void set_$name$(int index, $type$ value)$deprecation$;\n"
- "void add_$name$($type$ value)$deprecation$;\n");
+ "$deprecated_attr$$type$ $name$(int index) const;\n"
+ "$deprecated_attr$void set_$name$(int index, $type$ value);\n"
+ "$deprecated_attr$void add_$name$($type$ value);\n");
printer->Print(variables_,
- "const ::google::protobuf::RepeatedField<int>& $name$() const$deprecation$;\n"
- "::google::protobuf::RepeatedField<int>* mutable_$name$()$deprecation$;\n");
+ "$deprecated_attr$const ::google::protobuf::RepeatedField<int>& $name$() const;\n"
+ "$deprecated_attr$::google::protobuf::RepeatedField<int>* mutable_$name$();\n");
}
void RepeatedEnumFieldGenerator::
@@ -335,7 +335,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) const {
printer->Print(variables_,
"if ($type$_IsValid(value)) {\n"
" add_$name$(static_cast< $type$ >(value));\n");
- if (UseUnknownFieldSet(descriptor_->file())) {
+ if (UseUnknownFieldSet(descriptor_->file(), options_)) {
printer->Print(variables_,
"} else {\n"
" mutable_unknown_fields()->AddVarint($number$, value);\n");
@@ -362,7 +362,7 @@ GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const {
" NULL,\n"
" NULL,\n"
" this->mutable_$name$())));\n");
- } else if (UseUnknownFieldSet(descriptor_->file())) {
+ } else if (UseUnknownFieldSet(descriptor_->file(), options_)) {
printer->Print(variables_,
"DO_((::google::protobuf::internal::WireFormat::ReadPackedEnumPreserveUnknowns(\n"
" input,\n"
@@ -399,7 +399,7 @@ GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const {
" if ($type$_IsValid(value)) {\n"
" add_$name$(static_cast< $type$ >(value));\n"
" } else {\n");
- if (UseUnknownFieldSet(descriptor_->file())) {
+ if (UseUnknownFieldSet(descriptor_->file(), options_)) {
printer->Print(variables_,
" mutable_unknown_fields()->AddVarint($number$, value);\n");
} else {
diff --git a/src/google/protobuf/compiler/cpp/cpp_enum_field.h b/src/google/protobuf/compiler/cpp/cpp_enum_field.h
index 5b1d01ea..fe21c575 100644
--- a/src/google/protobuf/compiler/cpp/cpp_enum_field.h
+++ b/src/google/protobuf/compiler/cpp/cpp_enum_field.h
@@ -46,8 +46,7 @@ namespace cpp {
class EnumFieldGenerator : public FieldGenerator {
public:
- explicit EnumFieldGenerator(const FieldDescriptor* descriptor,
- const Options& options);
+ EnumFieldGenerator(const FieldDescriptor* descriptor, const Options& options);
~EnumFieldGenerator();
// implements FieldGenerator ---------------------------------------
@@ -74,8 +73,8 @@ class EnumFieldGenerator : public FieldGenerator {
class EnumOneofFieldGenerator : public EnumFieldGenerator {
public:
- explicit EnumOneofFieldGenerator(const FieldDescriptor* descriptor,
- const Options& options);
+ EnumOneofFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
~EnumOneofFieldGenerator();
// implements FieldGenerator ---------------------------------------
@@ -91,8 +90,8 @@ class EnumOneofFieldGenerator : public EnumFieldGenerator {
class RepeatedEnumFieldGenerator : public FieldGenerator {
public:
- explicit RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor,
- const Options& options);
+ RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
~RepeatedEnumFieldGenerator();
// implements FieldGenerator ---------------------------------------
diff --git a/src/google/protobuf/compiler/cpp/cpp_field.cc b/src/google/protobuf/compiler/cpp/cpp_field.cc
index 8d47d4e0..e2033c1a 100644
--- a/src/google/protobuf/compiler/cpp/cpp_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_field.cc
@@ -77,6 +77,8 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor,
WireFormat::TagSize(descriptor->number(), descriptor->type()));
(*variables)["deprecation"] = descriptor->options().deprecated()
? " PROTOBUF_DEPRECATED" : "";
+ (*variables)["deprecated_attr"] = descriptor->options().deprecated()
+ ? "GOOGLE_PROTOBUF_DEPRECATED_ATTR " : "";
(*variables)["cppget"] = "Get";
@@ -121,6 +123,7 @@ GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const {
FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor,
const Options& options)
: descriptor_(descriptor),
+ options_(options),
field_generators_(
new google::protobuf::scoped_ptr<FieldGenerator>[descriptor->field_count()]) {
// Construct all the FieldGenerators.
diff --git a/src/google/protobuf/compiler/cpp/cpp_field.h b/src/google/protobuf/compiler/cpp/cpp_field.h
index 1d7f8233..3b012527 100644
--- a/src/google/protobuf/compiler/cpp/cpp_field.h
+++ b/src/google/protobuf/compiler/cpp/cpp_field.h
@@ -69,7 +69,7 @@ void SetCommonOneofFieldVariables(const FieldDescriptor* descriptor,
class FieldGenerator {
public:
- FieldGenerator() {}
+ explicit FieldGenerator(const Options& options) : options_(options) {}
virtual ~FieldGenerator();
// Generate lines of code declaring members fields of the message class
@@ -194,6 +194,9 @@ class FieldGenerator {
// are placed in the message's ByteSize() method.
virtual void GenerateByteSize(io::Printer* printer) const = 0;
+ protected:
+ const Options& options_;
+
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGenerator);
};
@@ -201,13 +204,14 @@ class FieldGenerator {
// Convenience class which constructs FieldGenerators for a Descriptor.
class FieldGeneratorMap {
public:
- explicit FieldGeneratorMap(const Descriptor* descriptor, const Options& options);
+ FieldGeneratorMap(const Descriptor* descriptor, const Options& options);
~FieldGeneratorMap();
const FieldGenerator& get(const FieldDescriptor* field) const;
private:
const Descriptor* descriptor_;
+ const Options& options_;
google::protobuf::scoped_array<google::protobuf::scoped_ptr<FieldGenerator> > field_generators_;
static FieldGenerator* MakeGenerator(const FieldDescriptor* field,
diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc
index 9aa41534..b3eca660 100644
--- a/src/google/protobuf/compiler/cpp/cpp_file.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_file.cc
@@ -59,6 +59,7 @@ namespace cpp {
FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options)
: file_(file),
+ options_(options),
message_generators_(
new google::protobuf::scoped_ptr<MessageGenerator>[file->message_type_count()]),
enum_generators_(
@@ -66,8 +67,7 @@ FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options)
service_generators_(
new google::protobuf::scoped_ptr<ServiceGenerator>[file->service_count()]),
extension_generators_(
- new google::protobuf::scoped_ptr<ExtensionGenerator>[file->extension_count()]),
- options_(options) {
+ new google::protobuf::scoped_ptr<ExtensionGenerator>[file->extension_count()]) {
for (int i = 0; i < file->message_type_count(); i++) {
message_generators_[i].reset(
@@ -94,7 +94,8 @@ FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options)
FileGenerator::~FileGenerator() {}
-void FileGenerator::GenerateProtoHeader(io::Printer* printer) {
+void FileGenerator::GenerateProtoHeader(io::Printer* printer,
+ const string& info_path) {
if (!options_.proto_h) {
return;
}
@@ -114,6 +115,8 @@ void FileGenerator::GenerateProtoHeader(io::Printer* printer) {
"dependency", dependency);
}
+ GenerateMetadataPragma(printer, info_path);
+
printer->Print(
"// @@protoc_insertion_point(includes)\n");
@@ -167,7 +170,8 @@ void FileGenerator::GenerateProtoHeader(io::Printer* printer) {
GenerateBottomHeaderGuard(printer, filename_identifier);
}
-void FileGenerator::GeneratePBHeader(io::Printer* printer) {
+void FileGenerator::GeneratePBHeader(io::Printer* printer,
+ const string& info_path) {
string filename_identifier =
FilenameIdentifier(file_->name() + (options_.proto_h ? ".pb.h" : ""));
GenerateTopHeaderGuard(printer, filename_identifier);
@@ -179,6 +183,7 @@ void FileGenerator::GeneratePBHeader(io::Printer* printer) {
GenerateLibraryIncludes(printer);
}
GenerateDependencyIncludes(printer);
+ GenerateMetadataPragma(printer, info_path);
printer->Print(
"// @@protoc_insertion_point(includes)\n");
@@ -237,7 +242,7 @@ void FileGenerator::GeneratePBHeader(io::Printer* printer) {
}
void FileGenerator::GenerateSource(io::Printer* printer) {
- bool well_known = IsWellKnownMessage(file_);
+ const bool use_system_include = IsWellKnownMessage(file_);
string header =
StripProto(file_->name()) + (options_.proto_h ? ".proto.h" : ".pb.h");
printer->Print(
@@ -252,21 +257,22 @@ void FileGenerator::GenerateSource(io::Printer* printer) {
"#include <algorithm>\n" // for swap()
"\n"
"#include <google/protobuf/stubs/common.h>\n"
+ "#include <google/protobuf/stubs/port.h>\n"
"#include <google/protobuf/stubs/once.h>\n"
"#include <google/protobuf/io/coded_stream.h>\n"
"#include <google/protobuf/wire_format_lite_inl.h>\n",
"filename", file_->name(),
"header", header,
- "left", well_known ? "<" : "\"",
- "right", well_known ? ">" : "\"");
+ "left", use_system_include ? "<" : "\"",
+ "right", use_system_include ? ">" : "\"");
// Unknown fields implementation in lite mode uses StringOutputStream
- if (!UseUnknownFieldSet(file_) && file_->message_type_count() > 0) {
+ if (!UseUnknownFieldSet(file_, options_) && file_->message_type_count() > 0) {
printer->Print(
"#include <google/protobuf/io/zero_copy_stream_impl_lite.h>\n");
}
- if (HasDescriptorMethods(file_)) {
+ if (HasDescriptorMethods(file_, options_)) {
printer->Print(
"#include <google/protobuf/descriptor.h>\n"
"#include <google/protobuf/generated_message_reflection.h>\n"
@@ -291,7 +297,7 @@ void FileGenerator::GenerateSource(io::Printer* printer) {
GenerateNamespaceOpeners(printer);
- if (HasDescriptorMethods(file_)) {
+ if (HasDescriptorMethods(file_, options_)) {
printer->Print(
"\n"
"namespace {\n"
@@ -305,7 +311,7 @@ void FileGenerator::GenerateSource(io::Printer* printer) {
"name", ClassName(file_->enum_type(i), false));
}
- if (HasGenericServices(file_)) {
+ if (HasGenericServices(file_, options_)) {
for (int i = 0; i < file_->service_count(); i++) {
printer->Print(
"const ::google::protobuf::ServiceDescriptor* $name$_descriptor_ = NULL;\n",
@@ -330,19 +336,6 @@ void FileGenerator::GenerateSource(io::Printer* printer) {
// Generate classes.
for (int i = 0; i < file_->message_type_count(); i++) {
- if (i == 0 && HasGeneratedMethods(file_)) {
- printer->Print(
- "\n"
- "namespace {\n"
- "\n"
- "static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD;\n"
- "static void MergeFromFail(int line) {\n"
- " GOOGLE_CHECK(false) << __FILE__ << \":\" << line;\n"
- "}\n"
- "\n"
- "} // namespace\n"
- "\n");
- }
printer->Print("\n");
printer->Print(kThickSeparator);
printer->Print("\n");
@@ -355,7 +348,7 @@ void FileGenerator::GenerateSource(io::Printer* printer) {
printer->Print("#endif // PROTOBUF_INLINE_NOT_IN_HEADERS\n");
}
- if (HasGenericServices(file_)) {
+ if (HasGenericServices(file_, options_)) {
// Generate services.
for (int i = 0; i < file_->service_count(); i++) {
if (i == 0) printer->Print("\n");
@@ -400,20 +393,24 @@ class FileGenerator::ForwardDeclarations {
return ns;
}
- set<string>& classes() { return classes_; }
- set<string>& enums() { return enums_; }
+ map<string, const Descriptor*>& classes() { return classes_; }
+ map<string, const EnumDescriptor*>& enums() { return enums_; }
void Print(io::Printer* printer) const {
- for (set<string>::const_iterator it = enums_.begin(), end = enums_.end();
+ for (map<string, const EnumDescriptor *>::const_iterator
+ it = enums_.begin(),
+ end = enums_.end();
it != end; ++it) {
- printer->Print("enum $enumname$ : int;\n"
- "bool $enumname$_IsValid(int value);\n",
- "enumname", it->c_str());
+ printer->Print("enum $enumname$ : int;\n", "enumname", it->first);
+ printer->Annotate("enumname", it->second);
+ printer->Print("bool $enumname$_IsValid(int value);\n", "enumname",
+ it->first);
}
- for (set<string>::const_iterator it = classes_.begin(),
- end = classes_.end();
+ for (map<string, const Descriptor *>::const_iterator it = classes_.begin(),
+ end = classes_.end();
it != end; ++it) {
- printer->Print("class $classname$;\n", "classname", it->c_str());
+ printer->Print("class $classname$;\n", "classname", it->first);
+ printer->Annotate("classname", it->second);
}
for (map<string, ForwardDeclarations *>::const_iterator
it = namespaces_.begin(),
@@ -430,8 +427,8 @@ class FileGenerator::ForwardDeclarations {
private:
map<string, ForwardDeclarations*> namespaces_;
- set<string> classes_;
- set<string> enums_;
+ map<string, const Descriptor*> classes_;
+ map<string, const EnumDescriptor*> enums_;
};
void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
@@ -452,11 +449,12 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
// In optimize_for = LITE_RUNTIME mode, we don't generate AssignDescriptors()
// and we only use AddDescriptors() to allocate default instances.
- if (HasDescriptorMethods(file_)) {
+ if (HasDescriptorMethods(file_, options_)) {
printer->Print(
- "\n"
- "void $assigndescriptorsname$() {\n",
- "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name()));
+ "\n"
+ "void $assigndescriptorsname$() GOOGLE_ATTRIBUTE_COLD;\n"
+ "void $assigndescriptorsname$() {\n",
+ "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name()));
printer->Indent();
// Make sure the file has found its way into the pool. If a descriptor
@@ -485,7 +483,7 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
for (int i = 0; i < file_->enum_type_count(); i++) {
enum_generators_[i]->GenerateDescriptorInitializer(printer, i);
}
- if (HasGenericServices(file_)) {
+ if (HasGenericServices(file_, options_)) {
for (int i = 0; i < file_->service_count(); i++) {
service_generators_[i]->GenerateDescriptorInitializer(printer, i);
}
@@ -515,8 +513,9 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
// protobuf_RegisterTypes(): Calls
// MessageFactory::InternalRegisterGeneratedType() for each message type.
printer->Print(
- "void protobuf_RegisterTypes(const ::std::string&) {\n"
- " protobuf_AssignDescriptorsOnce();\n");
+ "void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;\n"
+ "void protobuf_RegisterTypes(const ::std::string&) {\n"
+ " protobuf_AssignDescriptorsOnce();\n");
printer->Indent();
for (int i = 0; i < file_->message_type_count(); i++) {
@@ -551,22 +550,24 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
// Now generate the AddDescriptors() function.
PrintHandlingOptionalStaticInitializers(
- file_, printer,
- // With static initializers.
- // Note that we don't need any special synchronization in the following code
- // because it is called at static init time before any threads exist.
- "void $adddescriptorsname$() {\n"
- " static bool already_here = false;\n"
- " if (already_here) return;\n"
- " already_here = true;\n"
- " GOOGLE_PROTOBUF_VERIFY_VERSION;\n"
- "\n",
- // Without.
- "void $adddescriptorsname$_impl() {\n"
- " GOOGLE_PROTOBUF_VERIFY_VERSION;\n"
- "\n",
- // Vars.
- "adddescriptorsname", GlobalAddDescriptorsName(file_->name()));
+ file_, options_, printer,
+ // With static initializers.
+ // Note that we don't need any special synchronization in the following
+ // code
+ // because it is called at static init time before any threads exist.
+ "void $adddescriptorsname$() GOOGLE_ATTRIBUTE_COLD;\n"
+ "void $adddescriptorsname$() {\n"
+ " static bool already_here = false;\n"
+ " if (already_here) return;\n"
+ " already_here = true;\n"
+ " GOOGLE_PROTOBUF_VERIFY_VERSION;\n"
+ "\n",
+ // Without.
+ "void $adddescriptorsname$_impl() {\n"
+ " GOOGLE_PROTOBUF_VERIFY_VERSION;\n"
+ "\n",
+ // Vars.
+ "adddescriptorsname", GlobalAddDescriptorsName(file_->name()));
printer->Indent();
@@ -583,7 +584,7 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
"name", add_desc_name);
}
- if (HasDescriptorMethods(file_)) {
+ if (HasDescriptorMethods(file_, options_)) {
// Embed the descriptor. We simply serialize the entire FileDescriptorProto
// and embed it as a string literal, which is parsed and built into real
// descriptors at initialization time.
@@ -677,23 +678,23 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
"\n");
PrintHandlingOptionalStaticInitializers(
- file_, printer,
- // With static initializers.
- "// Force AddDescriptors() to be called at static initialization time.\n"
- "struct StaticDescriptorInitializer_$filename$ {\n"
- " StaticDescriptorInitializer_$filename$() {\n"
- " $adddescriptorsname$();\n"
- " }\n"
- "} static_descriptor_initializer_$filename$_;\n",
- // Without.
- "GOOGLE_PROTOBUF_DECLARE_ONCE($adddescriptorsname$_once_);\n"
- "void $adddescriptorsname$() {\n"
- " ::google::protobuf::GoogleOnceInit(&$adddescriptorsname$_once_,\n"
- " &$adddescriptorsname$_impl);\n"
- "}\n",
- // Vars.
- "adddescriptorsname", GlobalAddDescriptorsName(file_->name()),
- "filename", FilenameIdentifier(file_->name()));
+ file_, options_, printer,
+ // With static initializers.
+ "// Force AddDescriptors() to be called at static initialization time.\n"
+ "struct StaticDescriptorInitializer_$filename$ {\n"
+ " StaticDescriptorInitializer_$filename$() {\n"
+ " $adddescriptorsname$();\n"
+ " }\n"
+ "} static_descriptor_initializer_$filename$_;\n",
+ // Without.
+ "GOOGLE_PROTOBUF_DECLARE_ONCE($adddescriptorsname$_once_);\n"
+ "void $adddescriptorsname$() {\n"
+ " ::google::protobuf::GoogleOnceInit(&$adddescriptorsname$_once_,\n"
+ " &$adddescriptorsname$_impl);\n"
+ "}\n",
+ // Vars.
+ "adddescriptorsname", GlobalAddDescriptorsName(file_->name()), "filename",
+ FilenameIdentifier(file_->name()));
}
void FileGenerator::GenerateNamespaceOpeners(io::Printer* printer) {
@@ -750,16 +751,15 @@ void FileGenerator::GenerateTopHeaderGuard(io::Printer* printer,
const string& filename_identifier) {
// Generate top of header.
printer->Print(
- "// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
- "// source: $filename$\n"
- "\n"
- "#ifndef PROTOBUF_$filename_identifier$__INCLUDED\n"
- "#define PROTOBUF_$filename_identifier$__INCLUDED\n"
- "\n"
- "#include <string>\n"
- "\n",
- "filename", file_->name(),
- "filename_identifier", filename_identifier);
+ "// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
+ "// source: $filename$\n"
+ "\n"
+ "#ifndef PROTOBUF_$filename_identifier$__INCLUDED\n"
+ "#define PROTOBUF_$filename_identifier$__INCLUDED\n"
+ "\n"
+ "#include <string>\n",
+ "filename", file_->name(), "filename_identifier", filename_identifier);
+ printer->Print("\n");
}
void FileGenerator::GenerateBottomHeaderGuard(
@@ -798,12 +798,12 @@ void FileGenerator::GenerateLibraryIncludes(io::Printer* printer) {
"#include <google/protobuf/arena.h>\n"
"#include <google/protobuf/arenastring.h>\n"
"#include <google/protobuf/generated_message_util.h>\n");
- if (UseUnknownFieldSet(file_)) {
+ if (UseUnknownFieldSet(file_, options_)) {
printer->Print(
"#include <google/protobuf/metadata.h>\n");
}
if (file_->message_type_count() > 0) {
- if (HasDescriptorMethods(file_)) {
+ if (HasDescriptorMethods(file_, options_)) {
printer->Print(
"#include <google/protobuf/message.h>\n");
} else {
@@ -817,7 +817,7 @@ void FileGenerator::GenerateLibraryIncludes(io::Printer* printer) {
if (HasMapFields(file_)) {
printer->Print(
"#include <google/protobuf/map.h>\n");
- if (HasDescriptorMethods(file_)) {
+ if (HasDescriptorMethods(file_, options_)) {
printer->Print(
"#include <google/protobuf/map_field_inl.h>\n");
} else {
@@ -827,7 +827,7 @@ void FileGenerator::GenerateLibraryIncludes(io::Printer* printer) {
}
if (HasEnumDefinitions(file_)) {
- if (HasDescriptorMethods(file_)) {
+ if (HasDescriptorMethods(file_, options_)) {
printer->Print(
"#include <google/protobuf/generated_enum_reflection.h>\n");
} else {
@@ -836,12 +836,12 @@ void FileGenerator::GenerateLibraryIncludes(io::Printer* printer) {
}
}
- if (HasGenericServices(file_)) {
+ if (HasGenericServices(file_, options_)) {
printer->Print(
"#include <google/protobuf/service.h>\n");
}
- if (UseUnknownFieldSet(file_) && file_->message_type_count() > 0) {
+ if (UseUnknownFieldSet(file_, options_) && file_->message_type_count() > 0) {
printer->Print(
"#include <google/protobuf/unknown_field_set.h>\n");
}
@@ -853,6 +853,19 @@ void FileGenerator::GenerateLibraryIncludes(io::Printer* printer) {
}
}
+void FileGenerator::GenerateMetadataPragma(io::Printer* printer,
+ const string& info_path) {
+ if (!info_path.empty() && !options_.annotation_pragma_name.empty() &&
+ !options_.annotation_guard_name.empty()) {
+ printer->Print(
+ "#ifdef $guard$\n"
+ "#pragma $pragma$ \"$info_path$\"\n"
+ "#endif // $guard$\n",
+ "guard", options_.annotation_guard_name, "pragma",
+ options_.annotation_pragma_name, "info_path", info_path);
+ }
+}
+
void FileGenerator::GenerateDependencyIncludes(io::Printer* printer) {
set<string> public_import_names;
for (int i = 0; i < file_->public_dependency_count(); i++) {
@@ -860,16 +873,17 @@ void FileGenerator::GenerateDependencyIncludes(io::Printer* printer) {
}
for (int i = 0; i < file_->dependency_count(); i++) {
- bool well_known = IsWellKnownMessage(file_->dependency(i));
+ const bool use_system_include = IsWellKnownMessage(file_->dependency(i));
const string& name = file_->dependency(i)->name();
bool public_import = (public_import_names.count(name) != 0);
+
printer->Print(
"#include $left$$dependency$.pb.h$right$$iwyu$\n",
"dependency", StripProto(name),
"iwyu", (public_import) ? " // IWYU pragma: export" : "",
- "left", well_known ? "<" : "\"",
- "right", well_known ? ">" : "\"");
+ "left", use_system_include ? "<" : "\"",
+ "right", use_system_include ? ">" : "\"");
}
}
@@ -896,13 +910,15 @@ void FileGenerator::GenerateGlobalStateFunctionDeclarations(
}
void FileGenerator::GenerateMessageForwardDeclarations(io::Printer* printer) {
- set<string> classes;
+ map<string, const Descriptor*> classes;
for (int i = 0; i < file_->message_type_count(); i++) {
message_generators_[i]->FillMessageForwardDeclarations(&classes);
}
- for (set<string>::const_iterator it = classes.begin(), end = classes.end();
+ for (map<string, const Descriptor *>::const_iterator it = classes.begin(),
+ end = classes.end();
it != end; ++it) {
- printer->Print("class $classname$;\n", "classname", it->c_str());
+ printer->Print("class $classname$;\n", "classname", it->first);
+ printer->Annotate("classname", it->second);
}
}
@@ -929,7 +945,7 @@ void FileGenerator::GenerateEnumDefinitions(io::Printer* printer) {
}
void FileGenerator::GenerateServiceDefinitions(io::Printer* printer) {
- if (HasGenericServices(file_)) {
+ if (HasGenericServices(file_, options_)) {
// Generate service definitions.
for (int i = 0; i < file_->service_count(); i++) {
if (i > 0) {
diff --git a/src/google/protobuf/compiler/cpp/cpp_file.h b/src/google/protobuf/compiler/cpp/cpp_file.h
index 29cdaea5..5dcf692b 100644
--- a/src/google/protobuf/compiler/cpp/cpp_file.h
+++ b/src/google/protobuf/compiler/cpp/cpp_file.h
@@ -65,12 +65,17 @@ class ExtensionGenerator; // extension.h
class FileGenerator {
public:
// See generator.cc for the meaning of dllexport_decl.
- explicit FileGenerator(const FileDescriptor* file,
- const Options& options);
+ FileGenerator(const FileDescriptor* file, const Options& options);
~FileGenerator();
- void GenerateProtoHeader(io::Printer* printer);
- void GeneratePBHeader(io::Printer* printer);
+ // info_path, if non-empty, should be the path (relative to printer's output)
+ // to the metadata file describing this proto header.
+ void GenerateProtoHeader(io::Printer* printer,
+ const string& info_path);
+ // info_path, if non-empty, should be the path (relative to printer's output)
+ // to the metadata file describing this PB header.
+ void GeneratePBHeader(io::Printer* printer,
+ const string& info_path);
void GenerateSource(io::Printer* printer);
private:
@@ -102,6 +107,10 @@ class FileGenerator {
void GenerateLibraryIncludes(io::Printer* printer);
void GenerateDependencyIncludes(io::Printer* printer);
+ // Generate a pragma to pull in metadata using the given info_path (if
+ // non-empty). info_path should be relative to printer's output.
+ void GenerateMetadataPragma(io::Printer* printer, const string& info_path);
+
// Generates a couple of different pieces before definitions:
void GenerateGlobalStateFunctionDeclarations(io::Printer* printer);
@@ -134,6 +143,7 @@ class FileGenerator {
void GenerateProto2NamespaceEnumSpecializations(io::Printer* printer);
const FileDescriptor* file_;
+ const Options options_;
google::protobuf::scoped_array<google::protobuf::scoped_ptr<MessageGenerator> > message_generators_;
google::protobuf::scoped_array<google::protobuf::scoped_ptr<EnumGenerator> > enum_generators_;
@@ -142,7 +152,6 @@ class FileGenerator {
// E.g. if the package is foo.bar, package_parts_ is {"foo", "bar"}.
vector<string> package_parts_;
- const Options options_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileGenerator);
};
diff --git a/src/google/protobuf/compiler/cpp/cpp_generator.cc b/src/google/protobuf/compiler/cpp/cpp_generator.cc
index 781526b5..31d189c2 100644
--- a/src/google/protobuf/compiler/cpp/cpp_generator.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_generator.cc
@@ -90,6 +90,14 @@ bool CppGenerator::Generate(const FileDescriptor* file,
file_options.dllexport_decl = options[i].second;
} else if (options[i].first == "safe_boundary_check") {
file_options.safe_boundary_check = true;
+ } else if (options[i].first == "annotate_headers") {
+ file_options.annotate_headers = true;
+ } else if (options[i].first == "annotation_pragma_name") {
+ file_options.annotation_pragma_name = options[i].second;
+ } else if (options[i].first == "annotation_guard_name") {
+ file_options.annotation_guard_name = options[i].second;
+ } else if (options[i].first == "lite") {
+ file_options.enforce_lite = true;
} else {
*error = "Unknown generator option: " + options[i].first;
return false;
@@ -107,16 +115,40 @@ bool CppGenerator::Generate(const FileDescriptor* file,
if (file_options.proto_h) {
google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(
generator_context->Open(basename + ".proto.h"));
- io::Printer printer(output.get(), '$');
- file_generator.GenerateProtoHeader(&printer);
+ GeneratedCodeInfo annotations;
+ io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector(
+ &annotations);
+ string info_path = basename + ".proto.h.meta";
+ io::Printer printer(output.get(), '$', file_options.annotate_headers
+ ? &annotation_collector
+ : NULL);
+ file_generator.GenerateProtoHeader(
+ &printer, file_options.annotate_headers ? info_path : "");
+ if (file_options.annotate_headers) {
+ google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> info_output(
+ generator_context->Open(info_path));
+ annotations.SerializeToZeroCopyStream(info_output.get());
+ }
}
basename.append(".pb");
{
google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(
generator_context->Open(basename + ".h"));
- io::Printer printer(output.get(), '$');
- file_generator.GeneratePBHeader(&printer);
+ GeneratedCodeInfo annotations;
+ io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector(
+ &annotations);
+ string info_path = basename + ".h.meta";
+ io::Printer printer(output.get(), '$', file_options.annotate_headers
+ ? &annotation_collector
+ : NULL);
+ file_generator.GeneratePBHeader(
+ &printer, file_options.annotate_headers ? info_path : "");
+ if (file_options.annotate_headers) {
+ google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> info_output(
+ generator_context->Open(info_path));
+ annotations.SerializeToZeroCopyStream(info_output.get());
+ }
}
// Generate cc file.
diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.cc b/src/google/protobuf/compiler/cpp/cpp_helpers.cc
index fb46e387..2ad4d36a 100644
--- a/src/google/protobuf/compiler/cpp/cpp_helpers.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_helpers.cc
@@ -68,14 +68,15 @@ const char* const kKeywordList[] = {
"alignas", "alignof", "and", "and_eq", "asm", "auto", "bitand", "bitor",
"bool", "break", "case", "catch", "char", "class", "compl", "const",
"constexpr", "const_cast", "continue", "decltype", "default", "delete", "do",
- "double", "dynamic_cast", "else", "enum", "explicit", "extern", "false",
- "float", "for", "friend", "goto", "if", "inline", "int", "long", "mutable",
- "namespace", "new", "noexcept", "not", "not_eq", "NULL", "operator", "or",
- "or_eq", "private", "protected", "public", "register", "reinterpret_cast",
- "return", "short", "signed", "sizeof", "static", "static_assert",
- "static_cast", "struct", "switch", "template", "this", "thread_local",
- "throw", "true", "try", "typedef", "typeid", "typename", "union", "unsigned",
- "using", "virtual", "void", "volatile", "wchar_t", "while", "xor", "xor_eq"
+ "double", "dynamic_cast", "else", "enum", "explicit", "export", "extern",
+ "false", "float", "for", "friend", "goto", "if", "inline", "int", "long",
+ "mutable", "namespace", "new", "noexcept", "not", "not_eq", "NULL",
+ "operator", "or", "or_eq", "private", "protected", "public", "register",
+ "reinterpret_cast", "return", "short", "signed", "sizeof", "static",
+ "static_assert", "static_cast", "struct", "switch", "template", "this",
+ "thread_local", "throw", "true", "try", "typedef", "typeid", "typename",
+ "union", "unsigned", "using", "virtual", "void", "volatile", "wchar_t",
+ "while", "xor", "xor_eq"
};
hash_set<string> MakeKeywordsMap() {
@@ -171,9 +172,10 @@ string DependentBaseClassTemplateName(const Descriptor* descriptor) {
return ClassName(descriptor, false) + "_InternalBase";
}
-string SuperClassName(const Descriptor* descriptor) {
- return HasDescriptorMethods(descriptor->file()) ?
- "::google::protobuf::Message" : "::google::protobuf::MessageLite";
+string SuperClassName(const Descriptor* descriptor, const Options& options) {
+ return HasDescriptorMethods(descriptor->file(), options)
+ ? "::google::protobuf::Message"
+ : "::google::protobuf::MessageLite";
}
string DependentBaseDownCast() {
@@ -485,8 +487,9 @@ string SafeFunctionName(const Descriptor* descriptor,
return function_name;
}
-bool StaticInitializersForced(const FileDescriptor* file) {
- if (HasDescriptorMethods(file) || file->extension_count() > 0) {
+bool StaticInitializersForced(const FileDescriptor* file,
+ const Options& options) {
+ if (HasDescriptorMethods(file, options) || file->extension_count() > 0) {
return true;
}
for (int i = 0; i < file->message_type_count(); ++i) {
@@ -498,10 +501,10 @@ bool StaticInitializersForced(const FileDescriptor* file) {
}
void PrintHandlingOptionalStaticInitializers(
- const FileDescriptor* file, io::Printer* printer,
+ const FileDescriptor* file, const Options& options, io::Printer* printer,
const char* with_static_init, const char* without_static_init,
- const char* var1, const string& val1,
- const char* var2, const string& val2) {
+ const char* var1, const string& val1, const char* var2,
+ const string& val2) {
map<string, string> vars;
if (var1) {
vars[var1] = val1;
@@ -510,14 +513,16 @@ void PrintHandlingOptionalStaticInitializers(
vars[var2] = val2;
}
PrintHandlingOptionalStaticInitializers(
- vars, file, printer, with_static_init, without_static_init);
+ vars, file, options, printer, with_static_init, without_static_init);
}
-void PrintHandlingOptionalStaticInitializers(
- const map<string, string>& vars, const FileDescriptor* file,
- io::Printer* printer, const char* with_static_init,
- const char* without_static_init) {
- if (StaticInitializersForced(file)) {
+void PrintHandlingOptionalStaticInitializers(const map<string, string>& vars,
+ const FileDescriptor* file,
+ const Options& options,
+ io::Printer* printer,
+ const char* with_static_init,
+ const char* without_static_init) {
+ if (StaticInitializersForced(file, options)) {
printer->Print(vars, with_static_init);
} else {
printer->Print(vars, (string(
@@ -612,10 +617,11 @@ enum Utf8CheckMode {
};
// Which level of UTF-8 enforcemant is placed on this file.
-static Utf8CheckMode GetUtf8CheckMode(const FieldDescriptor* field) {
+static Utf8CheckMode GetUtf8CheckMode(const FieldDescriptor* field,
+ const Options& options) {
if (field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3) {
return STRICT;
- } else if (field->file()->options().optimize_for() !=
+ } else if (GetOptimizeFor(field->file(), options) !=
FileOptions::LITE_RUNTIME) {
return VERIFY;
} else {
@@ -624,13 +630,13 @@ static Utf8CheckMode GetUtf8CheckMode(const FieldDescriptor* field) {
}
static void GenerateUtf8CheckCode(const FieldDescriptor* field,
- bool for_parse,
+ const Options& options, bool for_parse,
const map<string, string>& variables,
const char* parameters,
const char* strict_function,
const char* verify_function,
io::Printer* printer) {
- switch (GetUtf8CheckMode(field)) {
+ switch (GetUtf8CheckMode(field, options)) {
case STRICT: {
if (for_parse) {
printer->Print("DO_(");
@@ -674,23 +680,22 @@ static void GenerateUtf8CheckCode(const FieldDescriptor* field,
}
void GenerateUtf8CheckCodeForString(const FieldDescriptor* field,
- bool for_parse,
+ const Options& options, bool for_parse,
const map<string, string>& variables,
const char* parameters,
io::Printer* printer) {
- GenerateUtf8CheckCode(field, for_parse, variables, parameters,
+ GenerateUtf8CheckCode(field, options, for_parse, variables, parameters,
"VerifyUtf8String", "VerifyUTF8StringNamedField",
printer);
}
void GenerateUtf8CheckCodeForCord(const FieldDescriptor* field,
- bool for_parse,
+ const Options& options, bool for_parse,
const map<string, string>& variables,
const char* parameters,
io::Printer* printer) {
- GenerateUtf8CheckCode(field, for_parse, variables, parameters,
- "VerifyUtf8Cord", "VerifyUTF8CordNamedField",
- printer);
+ GenerateUtf8CheckCode(field, options, for_parse, variables, parameters,
+ "VerifyUtf8Cord", "VerifyUTF8CordNamedField", printer);
}
} // namespace cpp
diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.h b/src/google/protobuf/compiler/cpp/cpp_helpers.h
index a22d414d..018acfca 100644
--- a/src/google/protobuf/compiler/cpp/cpp_helpers.h
+++ b/src/google/protobuf/compiler/cpp/cpp_helpers.h
@@ -37,8 +37,9 @@
#include <map>
#include <string>
-#include <google/protobuf/descriptor.h>
+#include <google/protobuf/compiler/cpp/cpp_options.h>
#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/descriptor.h>
namespace google {
namespace protobuf {
@@ -72,7 +73,7 @@ string DependentBaseClassTemplateName(const Descriptor* descriptor);
// Name of the base class: either the dependent base class (for use with
// proto_h) or google::protobuf::Message.
-string SuperClassName(const Descriptor* descriptor);
+string SuperClassName(const Descriptor* descriptor, const Options& options);
// Returns a string that down-casts from the dependent base class to the
// derived class.
@@ -118,7 +119,7 @@ string DependentTypeName(const FieldDescriptor* field);
string FieldMessageTypeName(const FieldDescriptor* field);
// Strips ".proto" or ".protodevel" from the end of a filename.
-string StripProto(const string& filename);
+LIBPROTOC_EXPORT string StripProto(const string& filename);
// Get the C++ type name for a primitive type (e.g. "double", "::google::protobuf::int32", etc.).
// Note: non-built-in type names will be qualified, meaning they will start
@@ -168,12 +169,17 @@ inline bool PreserveUnknownFields(const Descriptor* message) {
return message->file()->syntax() != FileDescriptor::SYNTAX_PROTO3;
}
+// Returns the optimize mode for <file>, respecting <options.enforce_lite>.
+::google::protobuf::FileOptions_OptimizeMode GetOptimizeFor(
+ const FileDescriptor* file, const Options& options);
+
// If PreserveUnknownFields() is true, determines whether unknown
// fields will be stored in an UnknownFieldSet or a string.
// If PreserveUnknownFields() is false, this method will not be
// used.
-inline bool UseUnknownFieldSet(const FileDescriptor* file) {
- return file->options().optimize_for() != FileOptions::LITE_RUNTIME;
+inline bool UseUnknownFieldSet(const FileDescriptor* file,
+ const Options& options) {
+ return GetOptimizeFor(file, options) != FileOptions::LITE_RUNTIME;
}
@@ -186,45 +192,52 @@ bool HasEnumDefinitions(const FileDescriptor* file);
// Does this file have generated parsing, serialization, and other
// standard methods for which reflection-based fallback implementations exist?
-inline bool HasGeneratedMethods(const FileDescriptor* file) {
- return file->options().optimize_for() != FileOptions::CODE_SIZE;
+inline bool HasGeneratedMethods(const FileDescriptor* file,
+ const Options& options) {
+ return GetOptimizeFor(file, options) != FileOptions::CODE_SIZE;
}
// Do message classes in this file have descriptor and reflection methods?
-inline bool HasDescriptorMethods(const FileDescriptor* file) {
- return file->options().optimize_for() != FileOptions::LITE_RUNTIME;
+inline bool HasDescriptorMethods(const FileDescriptor* file,
+ const Options& options) {
+ return GetOptimizeFor(file, options) != FileOptions::LITE_RUNTIME;
}
// Should we generate generic services for this file?
-inline bool HasGenericServices(const FileDescriptor* file) {
+inline bool HasGenericServices(const FileDescriptor* file,
+ const Options& options) {
return file->service_count() > 0 &&
- file->options().optimize_for() != FileOptions::LITE_RUNTIME &&
+ GetOptimizeFor(file, options) != FileOptions::LITE_RUNTIME &&
file->options().cc_generic_services();
}
// Should we generate a separate, super-optimized code path for serializing to
// flat arrays? We don't do this in Lite mode because we'd rather reduce code
// size.
-inline bool HasFastArraySerialization(const FileDescriptor* file) {
- return file->options().optimize_for() == FileOptions::SPEED;
+inline bool HasFastArraySerialization(const FileDescriptor* file,
+ const Options& options) {
+ return GetOptimizeFor(file, options) == FileOptions::SPEED;
}
// Returns whether we have to generate code with static initializers.
-bool StaticInitializersForced(const FileDescriptor* file);
+bool StaticInitializersForced(const FileDescriptor* file,
+ const Options& options);
// Prints 'with_static_init' if static initializers have to be used for the
// provided file. Otherwise emits both 'with_static_init' and
// 'without_static_init' using #ifdef.
void PrintHandlingOptionalStaticInitializers(
- const FileDescriptor* file, io::Printer* printer,
+ const FileDescriptor* file, const Options& options, io::Printer* printer,
const char* with_static_init, const char* without_static_init,
- const char* var1 = NULL, const string& val1 = "",
- const char* var2 = NULL, const string& val2 = "");
+ const char* var1 = NULL, const string& val1 = "", const char* var2 = NULL,
+ const string& val2 = "");
-void PrintHandlingOptionalStaticInitializers(
- const map<string, string>& vars, const FileDescriptor* file,
- io::Printer* printer, const char* with_static_init,
- const char* without_static_init);
+void PrintHandlingOptionalStaticInitializers(const map<string, string>& vars,
+ const FileDescriptor* file,
+ const Options& options,
+ io::Printer* printer,
+ const char* with_static_init,
+ const char* without_static_init);
inline bool IsMapEntryMessage(const Descriptor* descriptor) {
@@ -267,19 +280,23 @@ bool IsAnyMessage(const Descriptor* descriptor);
bool IsWellKnownMessage(const FileDescriptor* descriptor);
-void GenerateUtf8CheckCodeForString(
- const FieldDescriptor* field,
- bool for_parse,
- const map<string, string>& variables,
- const char* parameters,
- io::Printer* printer);
-
-void GenerateUtf8CheckCodeForCord(
- const FieldDescriptor* field,
- bool for_parse,
- const map<string, string>& variables,
- const char* parameters,
- io::Printer* printer);
+void GenerateUtf8CheckCodeForString(const FieldDescriptor* field,
+ const Options& options, bool for_parse,
+ const map<string, string>& variables,
+ const char* parameters,
+ io::Printer* printer);
+
+void GenerateUtf8CheckCodeForCord(const FieldDescriptor* field,
+ const Options& options, bool for_parse,
+ const map<string, string>& variables,
+ const char* parameters, io::Printer* printer);
+
+inline ::google::protobuf::FileOptions_OptimizeMode GetOptimizeFor(
+ const FileDescriptor* file, const Options& options) {
+ return options.enforce_lite
+ ? FileOptions::LITE_RUNTIME
+ : file->options().optimize_for();
+}
} // namespace cpp
} // namespace compiler
diff --git a/src/google/protobuf/compiler/cpp/cpp_map_field.cc b/src/google/protobuf/compiler/cpp/cpp_map_field.cc
index e5e2f07d..0588e34e 100644
--- a/src/google/protobuf/compiler/cpp/cpp_map_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_map_field.cc
@@ -49,10 +49,11 @@ void SetMessageVariables(const FieldDescriptor* descriptor,
const Options& options) {
SetCommonFieldVariables(descriptor, variables, options);
(*variables)["type"] = FieldMessageTypeName(descriptor);
- (*variables)["stream_writer"] = (*variables)["declared_type"] +
- (HasFastArraySerialization(descriptor->message_type()->file()) ?
- "MaybeToArray" :
- "");
+ (*variables)["stream_writer"] =
+ (*variables)["declared_type"] +
+ (HasFastArraySerialization(descriptor->message_type()->file(), options)
+ ? "MaybeToArray"
+ : "");
(*variables)["full_name"] = descriptor->full_name();
const FieldDescriptor* key =
@@ -83,7 +84,7 @@ void SetMessageVariables(const FieldDescriptor* descriptor,
(*variables)["number"] = SimpleItoa(descriptor->number());
(*variables)["tag"] = SimpleItoa(internal::WireFormat::MakeTag(descriptor));
- if (HasDescriptorMethods(descriptor->file())) {
+ if (HasDescriptorMethods(descriptor->file(), options)) {
(*variables)["lite"] = "";
} else {
(*variables)["lite"] = "Lite";
@@ -98,10 +99,10 @@ void SetMessageVariables(const FieldDescriptor* descriptor,
}
}
-MapFieldGenerator::
-MapFieldGenerator(const FieldDescriptor* descriptor,
- const Options& options)
- : descriptor_(descriptor),
+MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
+ : FieldGenerator(options),
+ descriptor_(descriptor),
dependent_field_(options.proto_h && IsFieldDependent(descriptor)) {
SetMessageVariables(descriptor, &variables_, options);
}
@@ -127,10 +128,10 @@ GeneratePrivateMembers(io::Printer* printer) const {
void MapFieldGenerator::
GenerateAccessorDeclarations(io::Printer* printer) const {
printer->Print(variables_,
- "const ::google::protobuf::Map< $key_cpp$, $val_cpp$ >&\n"
- " $name$() const$deprecation$;\n"
- "::google::protobuf::Map< $key_cpp$, $val_cpp$ >*\n"
- " mutable_$name$()$deprecation$;\n");
+ "$deprecated_attr$const ::google::protobuf::Map< $key_cpp$, $val_cpp$ >&\n"
+ " $name$() const;\n"
+ "$deprecated_attr$::google::protobuf::Map< $key_cpp$, $val_cpp$ >*\n"
+ " mutable_$name$();\n");
}
void MapFieldGenerator::
@@ -170,7 +171,7 @@ GenerateSwappingCode(io::Printer* printer) const {
void MapFieldGenerator::
GenerateConstructorCode(io::Printer* printer) const {
- if (HasDescriptorMethods(descriptor_->file())) {
+ if (HasDescriptorMethods(descriptor_->file(), options_)) {
printer->Print(variables_,
"$name$_.SetAssignDescriptorCallback(\n"
" protobuf_AssignDescriptorsOnce);\n"
@@ -181,33 +182,33 @@ GenerateConstructorCode(io::Printer* printer) const {
void MapFieldGenerator::
GenerateMergeFromCodedStream(io::Printer* printer) const {
+ const FieldDescriptor* key_field =
+ descriptor_->message_type()->FindFieldByName("key");
const FieldDescriptor* value_field =
descriptor_->message_type()->FindFieldByName("value");
- printer->Print(variables_,
- "::google::protobuf::scoped_ptr<$map_classname$> entry($name$_.NewEntry());\n");
-
+ bool using_entry = false;
+ string key;
+ string value;
if (IsProto3Field(descriptor_) ||
value_field->type() != FieldDescriptor::TYPE_ENUM) {
printer->Print(variables_,
+ "$map_classname$::Parser< ::google::protobuf::internal::MapField$lite$<\n"
+ " $key_cpp$, $val_cpp$,\n"
+ " $key_wire_type$,\n"
+ " $val_wire_type$,\n"
+ " $default_enum_value$ >,\n"
+ " ::google::protobuf::Map< $key_cpp$, $val_cpp$ > >"
+ " parser(&$name$_);\n"
"DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n"
- " input, entry.get()));\n");
- switch (value_field->cpp_type()) {
- case FieldDescriptor::CPPTYPE_MESSAGE:
- printer->Print(variables_,
- "(*mutable_$name$())[entry->key()].Swap("
- "entry->mutable_value());\n");
- break;
- case FieldDescriptor::CPPTYPE_ENUM:
- printer->Print(variables_,
- "(*mutable_$name$())[entry->key()] =\n"
- " static_cast< $val_cpp$ >(*entry->mutable_value());\n");
- break;
- default:
- printer->Print(variables_,
- "(*mutable_$name$())[entry->key()] = *entry->mutable_value();\n");
- break;
- }
+ " input, &parser));\n");
+ key = "parser.key()";
+ value = "parser.value()";
} else {
+ using_entry = true;
+ key = "entry->key()";
+ value = "entry->value()";
+ printer->Print(variables_,
+ "::google::protobuf::scoped_ptr<$map_classname$> entry($name$_.NewEntry());\n");
printer->Print(variables_,
"{\n"
" ::std::string data;\n"
@@ -217,7 +218,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) const {
" (*mutable_$name$())[entry->key()] =\n"
" static_cast< $val_cpp$ >(*entry->mutable_value());\n"
" } else {\n");
- if (HasDescriptorMethods(descriptor_->file())) {
+ if (HasDescriptorMethods(descriptor_->file(), options_)) {
printer->Print(variables_,
" mutable_unknown_fields()"
"->AddLengthDelimited($number$, data);\n");
@@ -228,144 +229,170 @@ GenerateMergeFromCodedStream(io::Printer* printer) const {
" unknown_fields_stream.WriteString(data);\n");
}
-
printer->Print(variables_,
" }\n"
"}\n");
}
- const FieldDescriptor* key_field =
- descriptor_->message_type()->FindFieldByName("key");
if (key_field->type() == FieldDescriptor::TYPE_STRING) {
GenerateUtf8CheckCodeForString(
- key_field, true, variables_,
- "entry->key().data(), entry->key().length(),\n", printer);
+ key_field, options_, true, variables_,
+ StrCat(key, ".data(), ", key, ".length(),\n").data(), printer);
}
if (value_field->type() == FieldDescriptor::TYPE_STRING) {
- GenerateUtf8CheckCodeForString(
- value_field, true, variables_,
- "entry->mutable_value()->data(),\n"
- "entry->mutable_value()->length(),\n", printer);
+ GenerateUtf8CheckCodeForString(value_field, options_, true, variables_,
+ StrCat(value, ".data(), ", value, ".length(),\n").data(), printer);
}
// If entry is allocated by arena, its desctructor should be avoided.
- if (SupportsArenas(descriptor_)) {
+ if (using_entry && SupportsArenas(descriptor_)) {
printer->Print(variables_,
"if (entry->GetArena() != NULL) entry.release();\n");
}
}
-void MapFieldGenerator::
-GenerateSerializeWithCachedSizes(io::Printer* printer) const {
- printer->Print(variables_,
- "{\n"
- " ::google::protobuf::scoped_ptr<$map_classname$> entry;\n"
- " for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
- " it = this->$name$().begin();\n"
- " it != this->$name$().end(); ++it) {\n");
+static void GenerateSerializationLoop(io::Printer* printer,
+ const map<string, string>& variables,
+ bool supports_arenas,
+ const string& utf8_check,
+ const string& loop_header,
+ const string& ptr,
+ bool loop_via_iterators) {
+ printer->Print(variables,
+ StrCat("::google::protobuf::scoped_ptr<$map_classname$> entry;\n",
+ loop_header, " {\n").c_str());
+ printer->Indent();
+
+ printer->Print(variables, StrCat(
+ "entry.reset($name$_.New$wrapper$(\n"
+ " ", ptr, "->first, ", ptr, "->second));\n"
+ "$write_entry$;\n").c_str());
// If entry is allocated by arena, its desctructor should be avoided.
- if (SupportsArenas(descriptor_)) {
- printer->Print(variables_,
- " if (entry.get() != NULL && entry->GetArena() != NULL) {\n"
- " entry.release();\n"
- " }\n");
+ if (supports_arenas) {
+ printer->Print(
+ "if (entry->GetArena() != NULL) {\n"
+ " entry.release();\n"
+ "}\n");
}
- printer->Print(variables_,
- " entry.reset($name$_.New$wrapper$(it->first, it->second));\n"
- " ::google::protobuf::internal::WireFormatLite::Write$stream_writer$(\n"
- " $number$, *entry, output);\n");
-
- printer->Indent();
- printer->Indent();
-
- const FieldDescriptor* key_field =
- descriptor_->message_type()->FindFieldByName("key");
- const FieldDescriptor* value_field =
- descriptor_->message_type()->FindFieldByName("value");
- if (key_field->type() == FieldDescriptor::TYPE_STRING) {
- GenerateUtf8CheckCodeForString(
- key_field, false, variables_,
- "it->first.data(), it->first.length(),\n", printer);
- }
- if (value_field->type() == FieldDescriptor::TYPE_STRING) {
- GenerateUtf8CheckCodeForString(
- value_field, false, variables_,
- "it->second.data(), it->second.length(),\n", printer);
+ if (!utf8_check.empty()) {
+ // If loop_via_iterators is true then ptr is actually an iterator, and we
+ // create a pointer by prefixing it with "&*".
+ printer->Print(
+ StrCat(utf8_check, "(", (loop_via_iterators ? "&*" : ""), ptr, ");\n")
+ .c_str());
}
printer->Outdent();
- printer->Outdent();
-
printer->Print(
- " }\n");
-
- // If entry is allocated by arena, its desctructor should be avoided.
- if (SupportsArenas(descriptor_)) {
- printer->Print(variables_,
- " if (entry.get() != NULL && entry->GetArena() != NULL) {\n"
- " entry.release();\n"
- " }\n");
- }
+ "}\n");
+}
- printer->Print("}\n");
+void MapFieldGenerator::
+GenerateSerializeWithCachedSizes(io::Printer* printer) const {
+ map<string, string> variables(variables_);
+ variables["write_entry"] = "::google::protobuf::internal::WireFormatLite::Write" +
+ variables["stream_writer"] + "(\n " +
+ variables["number"] + ", *entry, output)";
+ variables["deterministic"] = "output->IsSerializationDeterminstic()";
+ GenerateSerializeWithCachedSizes(printer, variables);
}
void MapFieldGenerator::
GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
- printer->Print(variables_,
- "{\n"
- " ::google::protobuf::scoped_ptr<$map_classname$> entry;\n"
- " for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
- " it = this->$name$().begin();\n"
- " it != this->$name$().end(); ++it) {\n");
-
- // If entry is allocated by arena, its desctructor should be avoided.
- if (SupportsArenas(descriptor_)) {
- printer->Print(variables_,
- " if (entry.get() != NULL && entry->GetArena() != NULL) {\n"
- " entry.release();\n"
- " }\n");
- }
-
- printer->Print(variables_,
- " entry.reset($name$_.New$wrapper$(it->first, it->second));\n"
- " target = ::google::protobuf::internal::WireFormatLite::\n"
- " Write$declared_type$NoVirtualToArray(\n"
- " $number$, *entry, target);\n");
+ map<string, string> variables(variables_);
+ variables["write_entry"] =
+ "target = ::google::protobuf::internal::WireFormatLite::\n"
+ " InternalWrite" + variables["declared_type"] +
+ "NoVirtualToArray(\n " + variables["number"] +
+ ", *entry, deterministic, target);\n";
+ variables["deterministic"] = "deterministic";
+ GenerateSerializeWithCachedSizes(printer, variables);
+}
+void MapFieldGenerator::GenerateSerializeWithCachedSizes(
+ io::Printer* printer, const map<string, string>& variables) const {
+ printer->Print(variables,
+ "if (!this->$name$().empty()) {\n");
printer->Indent();
- printer->Indent();
-
const FieldDescriptor* key_field =
descriptor_->message_type()->FindFieldByName("key");
const FieldDescriptor* value_field =
descriptor_->message_type()->FindFieldByName("value");
- if (key_field->type() == FieldDescriptor::TYPE_STRING) {
- GenerateUtf8CheckCodeForString(
- key_field, false, variables_,
- "it->first.data(), it->first.length(),\n", printer);
+ const bool string_key = key_field->type() == FieldDescriptor::TYPE_STRING;
+ const bool string_value = value_field->type() == FieldDescriptor::TYPE_STRING;
+
+ printer->Print(variables,
+ "typedef ::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_pointer\n"
+ " ConstPtr;\n");
+ if (string_key) {
+ printer->Print(variables,
+ "typedef ConstPtr SortItem;\n"
+ "typedef ::google::protobuf::internal::"
+ "CompareByDerefFirst<SortItem> Less;\n");
+ } else {
+ printer->Print(variables,
+ "typedef ::google::protobuf::internal::SortItem< $key_cpp$, ConstPtr > "
+ "SortItem;\n"
+ "typedef ::google::protobuf::internal::CompareByFirstField<SortItem> Less;\n");
}
- if (value_field->type() == FieldDescriptor::TYPE_STRING) {
- GenerateUtf8CheckCodeForString(
- value_field, false, variables_,
- "it->second.data(), it->second.length(),\n", printer);
+ string utf8_check;
+ if (string_key || string_value) {
+ printer->Print(
+ "struct Utf8Check {\n"
+ " static void Check(ConstPtr p) {\n");
+ printer->Indent();
+ printer->Indent();
+ if (string_key) {
+ GenerateUtf8CheckCodeForString(key_field, options_, false, variables,
+ "p->first.data(), p->first.length(),\n",
+ printer);
+ }
+ if (string_value) {
+ GenerateUtf8CheckCodeForString(value_field, options_, false, variables,
+ "p->second.data(), p->second.length(),\n",
+ printer);
+ }
+ printer->Outdent();
+ printer->Outdent();
+ printer->Print(
+ " }\n"
+ "};\n");
+ utf8_check = "Utf8Check::Check";
}
- printer->Outdent();
+ printer->Print(variables,
+ "\n"
+ "if ($deterministic$ &&\n"
+ " this->$name$().size() > 1) {\n"
+ " ::google::protobuf::scoped_array<SortItem> items(\n"
+ " new SortItem[this->$name$().size()]);\n"
+ " typedef ::google::protobuf::Map< $key_cpp$, $val_cpp$ >::size_type size_type;\n"
+ " size_type n = 0;\n"
+ " for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
+ " it = this->$name$().begin();\n"
+ " it != this->$name$().end(); ++it, ++n) {\n"
+ " items[n] = SortItem(&*it);\n"
+ " }\n"
+ " ::std::sort(&items[0], &items[n], Less());\n");
+ printer->Indent();
+ GenerateSerializationLoop(printer, variables, SupportsArenas(descriptor_),
+ utf8_check, "for (size_type i = 0; i < n; i++)",
+ string_key ? "items[i]" : "items[i].second", false);
printer->Outdent();
printer->Print(
- " }\n");
-
- // If entry is allocated by arena, its desctructor should be avoided.
- if (SupportsArenas(descriptor_)) {
- printer->Print(variables_,
- " if (entry.get() != NULL && entry->GetArena() != NULL) {\n"
- " entry.release();\n"
- " }\n");
- }
-
+ "} else {\n");
+ printer->Indent();
+ GenerateSerializationLoop(
+ printer, variables, SupportsArenas(descriptor_), utf8_check,
+ "for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
+ " it = this->$name$().begin();\n"
+ " it != this->$name$().end(); ++it)",
+ "it", true);
+ printer->Outdent();
+ printer->Print("}\n");
+ printer->Outdent();
printer->Print("}\n");
}
diff --git a/src/google/protobuf/compiler/cpp/cpp_map_field.h b/src/google/protobuf/compiler/cpp/cpp_map_field.h
index 5e205623..2930fe59 100644
--- a/src/google/protobuf/compiler/cpp/cpp_map_field.h
+++ b/src/google/protobuf/compiler/cpp/cpp_map_field.h
@@ -43,8 +43,7 @@ namespace cpp {
class MapFieldGenerator : public FieldGenerator {
public:
- explicit MapFieldGenerator(const FieldDescriptor* descriptor,
- const Options& options);
+ MapFieldGenerator(const FieldDescriptor* descriptor, const Options& options);
~MapFieldGenerator();
// implements FieldGenerator ---------------------------------------
@@ -62,6 +61,10 @@ class MapFieldGenerator : public FieldGenerator {
void GenerateByteSize(io::Printer* printer) const;
private:
+ // A helper for GenerateSerializeWithCachedSizes{,ToArray}.
+ void GenerateSerializeWithCachedSizes(
+ io::Printer* printer, const map<string, string>& variables) const;
+
const FieldDescriptor* descriptor_;
const bool dependent_field_;
map<string, string> variables_;
diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc
index af409c29..405a5fed 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_message.cc
@@ -106,8 +106,8 @@ struct ExtensionRangeSorter {
// Returns true if the "required" restriction check should be ignored for the
// given field.
-inline static bool ShouldIgnoreRequiredFieldCheck(
- const FieldDescriptor* field) {
+inline static bool ShouldIgnoreRequiredFieldCheck(const FieldDescriptor* field,
+ const Options& options) {
return false;
}
@@ -116,9 +116,8 @@ inline static bool ShouldIgnoreRequiredFieldCheck(
//
// already_seen is used to avoid checking the same type multiple times
// (and also to protect against recursion).
-static bool HasRequiredFields(
- const Descriptor* type,
- hash_set<const Descriptor*>* already_seen) {
+static bool HasRequiredFields(const Descriptor* type, const Options& options,
+ hash_set<const Descriptor*>* already_seen) {
if (already_seen->count(type) > 0) {
// Since the first occurrence of a required field causes the whole
// function to return true, we can assume that if the type is already
@@ -138,8 +137,8 @@ static bool HasRequiredFields(
return true;
}
if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
- !ShouldIgnoreRequiredFieldCheck(field)) {
- if (HasRequiredFields(field->message_type(), already_seen)) {
+ !ShouldIgnoreRequiredFieldCheck(field, options)) {
+ if (HasRequiredFields(field->message_type(), options, already_seen)) {
return true;
}
}
@@ -148,9 +147,9 @@ static bool HasRequiredFields(
return false;
}
-static bool HasRequiredFields(const Descriptor* type) {
+static bool HasRequiredFields(const Descriptor* type, const Options& options) {
hash_set<const Descriptor*> already_seen;
- return HasRequiredFields(type, &already_seen);
+ return HasRequiredFields(type, options, &already_seen);
}
// This returns an estimate of the compiler's alignment for the field. This
@@ -423,8 +422,8 @@ MessageGenerator::MessageGenerator(const Descriptor* descriptor,
MessageGenerator::~MessageGenerator() {}
void MessageGenerator::
-FillMessageForwardDeclarations(set<string>* class_names) {
- class_names->insert(classname_);
+FillMessageForwardDeclarations(map<string, const Descriptor*>* class_names) {
+ (*class_names)[classname_] = descriptor_;
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
// map entry message doesn't need forward declaration. Since map entry
@@ -436,7 +435,7 @@ FillMessageForwardDeclarations(set<string>* class_names) {
}
void MessageGenerator::
-FillEnumForwardDeclarations(set<string>* enum_names) {
+FillEnumForwardDeclarations(map<string, const EnumDescriptor*>* enum_names) {
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
nested_generators_[i]->FillEnumForwardDeclarations(enum_names);
}
@@ -480,7 +479,7 @@ GenerateDependentFieldAccessorDeclarations(io::Printer* printer) {
// If the message is dependent, the inline clear_*() method will need
// to delete the message type, so it must be in the dependent base
// class. (See also GenerateFieldAccessorDeclarations.)
- printer->Print(vars, "void clear_$name$()$deprecation$;\n");
+ printer->Print(vars, "$deprecated_attr$void clear_$name$();\n");
}
// Generate type-specific accessor declarations.
field_generators_.get(field).GenerateDependentAccessorDeclarations(printer);
@@ -515,22 +514,24 @@ GenerateFieldAccessorDeclarations(io::Printer* printer) {
}
if (field->is_repeated()) {
- printer->Print(vars, "int $name$_size() const$deprecation$;\n");
+ printer->Print(vars, "$deprecated_attr$int $name$_size() const;\n");
} else if (HasHasMethod(field)) {
- printer->Print(vars, "bool has_$name$() const$deprecation$;\n");
+ printer->Print(vars, "$deprecated_attr$bool has_$name$() const;\n");
} else if (HasPrivateHasMethod(field)) {
printer->Print(vars,
"private:\n"
- "bool has_$name$() const$deprecation$;\n"
+ "bool has_$name$() const;\n"
"public:\n");
}
if (!dependent_field) {
// If this field is dependent, then its clear_() method is in the
// depenent base class. (See also GenerateDependentAccessorDeclarations.)
- printer->Print(vars, "void clear_$name$()$deprecation$;\n");
+ printer->Print(vars, "$deprecated_attr$void clear_$name$();\n");
}
- printer->Print(vars, "static const int $constant_name$ = $number$;\n");
+ printer->Print(vars,
+ "$deprecated_attr$static const int $constant_name$ = "
+ "$number$;\n");
// Generate type-specific accessor declarations.
field_generators_.get(field).GenerateAccessorDeclarations(printer);
@@ -837,11 +838,13 @@ GenerateDependentBaseClassDefinition(io::Printer* printer) {
map<string, string> vars;
vars["classname"] = DependentBaseClassTemplateName(descriptor_);
- vars["superclass"] = SuperClassName(descriptor_);
+ vars["full_name"] = descriptor_->full_name();
+ vars["superclass"] = SuperClassName(descriptor_, options_);
printer->Print(vars,
"template <class T>\n"
- "class $classname$ : public $superclass$ {\n"
+ "class $classname$ : public $superclass$ "
+ "/* @@protoc_insertion_point(dep_base_class_definition:$full_name$) */ {\n"
" public:\n");
printer->Indent();
@@ -877,6 +880,7 @@ GenerateClassDefinition(io::Printer* printer) {
map<string, string> vars;
vars["classname"] = classname_;
+ vars["full_name"] = descriptor_->full_name();
vars["field_count"] = SimpleItoa(descriptor_->field_count());
vars["oneof_decl_count"] = SimpleItoa(descriptor_->oneof_decl_count());
if (options_.dllexport_decl.empty()) {
@@ -888,10 +892,13 @@ GenerateClassDefinition(io::Printer* printer) {
vars["superclass"] =
DependentBaseClassTemplateName(descriptor_) + "<" + classname_ + ">";
} else {
- vars["superclass"] = SuperClassName(descriptor_);
+ vars["superclass"] = SuperClassName(descriptor_, options_);
}
printer->Print(vars,
- "class $dllexport$$classname$ : public $superclass$ {\n");
+ "class $dllexport$$classname$ : public $superclass$ "
+ "/* @@protoc_insertion_point(class_definition:$full_name$) */ "
+ "{\n");
+ printer->Annotate("classname", descriptor_);
if (use_dependent_base_) {
printer->Print(vars, " friend class $superclass$;\n");
}
@@ -911,7 +918,7 @@ GenerateClassDefinition(io::Printer* printer) {
"\n");
if (PreserveUnknownFields(descriptor_)) {
- if (UseUnknownFieldSet(descriptor_->file())) {
+ if (UseUnknownFieldSet(descriptor_->file(), options_)) {
printer->Print(
"inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {\n"
" return _internal_metadata_.unknown_fields();\n"
@@ -965,7 +972,7 @@ GenerateClassDefinition(io::Printer* printer) {
}
// Only generate this member if it's not disabled.
- if (HasDescriptorMethods(descriptor_->file()) &&
+ if (HasDescriptorMethods(descriptor_->file(), options_) &&
!descriptor_->options().no_standard_descriptor_accessor()) {
printer->Print(vars,
"static const ::google::protobuf::Descriptor* descriptor();\n");
@@ -1002,7 +1009,7 @@ GenerateClassDefinition(io::Printer* printer) {
"\n");
}
- if (!StaticInitializersForced(descriptor_->file())) {
+ if (!StaticInitializersForced(descriptor_->file(), options_)) {
printer->Print(vars,
"#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER\n"
"// Returns the internal default instance pointer. This function can\n"
@@ -1027,6 +1034,8 @@ GenerateClassDefinition(io::Printer* printer) {
"// implements Any -----------------------------------------------\n"
"\n"
"void PackFrom(const ::google::protobuf::Message& message);\n"
+ "void PackFrom(const ::google::protobuf::Message& message,\n"
+ " const ::std::string& type_url_prefix);\n"
"bool UnpackTo(::google::protobuf::Message* message) const;\n"
"template<typename T> bool Is() const {\n"
" return _any_metadata_.Is<T>();\n"
@@ -1043,8 +1052,8 @@ GenerateClassDefinition(io::Printer* printer) {
"\n"
"$classname$* New(::google::protobuf::Arena* arena) const;\n");
- if (HasGeneratedMethods(descriptor_->file())) {
- if (HasDescriptorMethods(descriptor_->file())) {
+ if (HasGeneratedMethods(descriptor_->file(), options_)) {
+ if (HasDescriptorMethods(descriptor_->file(), options_)) {
printer->Print(vars,
"void CopyFrom(const ::google::protobuf::Message& from);\n"
"void MergeFrom(const ::google::protobuf::Message& from);\n");
@@ -1066,13 +1075,17 @@ GenerateClassDefinition(io::Printer* printer) {
" ::google::protobuf::io::CodedOutputStream* output) const;\n");
// DiscardUnknownFields() is implemented in message.cc using reflections. We
// need to implement this function in generated code for messages.
- if (!UseUnknownFieldSet(descriptor_->file())) {
+ if (!UseUnknownFieldSet(descriptor_->file(), options_)) {
printer->Print(
"void DiscardUnknownFields();\n");
}
- if (HasFastArraySerialization(descriptor_->file())) {
+ if (HasFastArraySerialization(descriptor_->file(), options_)) {
printer->Print(
- "::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;\n");
+ "::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(\n"
+ " bool deterministic, ::google::protobuf::uint8* output) const;\n"
+ "::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {\n"
+ " return InternalSerializeWithCachedSizesToArray(false, output);\n"
+ "}\n");
}
}
@@ -1091,9 +1104,16 @@ GenerateClassDefinition(io::Printer* printer) {
descriptors.push_back(descriptor_->oneof_decl(i)->field(j));
}
}
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ const Descriptor* nested_type = descriptor_->nested_type(i);
+ if (IsMapEntryMessage(nested_type)) {
+ descriptors.push_back(nested_type->FindFieldByName("key"));
+ descriptors.push_back(nested_type->FindFieldByName("value"));
+ }
+ }
uses_string_ = false;
if (PreserveUnknownFields(descriptor_) &&
- !UseUnknownFieldSet(descriptor_->file())) {
+ !UseUnknownFieldSet(descriptor_->file(), options_)) {
uses_string_ = true;
}
for (int i = 0; i < descriptors.size(); i++) {
@@ -1123,7 +1143,7 @@ GenerateClassDefinition(io::Printer* printer) {
"classname", classname_);
}
- if (UseUnknownFieldSet(descriptor_->file())) {
+ if (UseUnknownFieldSet(descriptor_->file(), options_)) {
printer->Print(
"private:\n"
"inline ::google::protobuf::Arena* GetArenaNoVirtual() const {\n"
@@ -1147,7 +1167,7 @@ GenerateClassDefinition(io::Printer* printer) {
"\n");
}
- if (HasDescriptorMethods(descriptor_->file())) {
+ if (HasDescriptorMethods(descriptor_->file(), options_)) {
printer->Print(
"::google::protobuf::Metadata GetMetadata() const;\n"
"\n");
@@ -1236,7 +1256,7 @@ GenerateClassDefinition(io::Printer* printer) {
"oneof_name", descriptor_->oneof_decl(i)->name());
}
- if (HasGeneratedMethods(descriptor_->file()) &&
+ if (HasGeneratedMethods(descriptor_->file(), options_) &&
!descriptor_->options().message_set_wire_format() &&
num_required_fields_ > 1) {
printer->Print(
@@ -1278,7 +1298,7 @@ GenerateClassDefinition(io::Printer* printer) {
"\n");
}
- if (UseUnknownFieldSet(descriptor_->file())) {
+ if (UseUnknownFieldSet(descriptor_->file(), options_)) {
printer->Print(
"::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;\n");
} else {
@@ -1405,15 +1425,14 @@ GenerateClassDefinition(io::Printer* printer) {
// friends so that they can access private static variables like
// default_instance_ and reflection_.
PrintHandlingOptionalStaticInitializers(
- descriptor_->file(), printer,
- // With static initializers.
- "friend void $dllexport_decl$ $adddescriptorsname$();\n",
- // Without.
- "friend void $dllexport_decl$ $adddescriptorsname$_impl();\n",
- // Vars.
- "dllexport_decl", options_.dllexport_decl,
- "adddescriptorsname",
- GlobalAddDescriptorsName(descriptor_->file()->name()));
+ descriptor_->file(), options_, printer,
+ // With static initializers.
+ "friend void $dllexport_decl$ $adddescriptorsname$();\n",
+ // Without.
+ "friend void $dllexport_decl$ $adddescriptorsname$_impl();\n",
+ // Vars.
+ "dllexport_decl", options_.dllexport_decl, "adddescriptorsname",
+ GlobalAddDescriptorsName(descriptor_->file()->name()));
printer->Print(
"friend void $assigndescriptorsname$();\n"
@@ -1576,7 +1595,7 @@ GenerateDescriptorInitializer(io::Printer* printer, int index) {
// Unknown field offset: either points to the unknown field set if embedded
// directly, or indicates that the unknown field set is stored as part of the
// internal metadata if not.
- if (UseUnknownFieldSet(descriptor_->file())) {
+ if (UseUnknownFieldSet(descriptor_->file(), options_)) {
printer->Print(vars,
" -1,\n");
} else {
@@ -1616,7 +1635,7 @@ GenerateDescriptorInitializer(io::Printer* printer, int index) {
// arena pointer and unknown field set (in a space-efficient way) if we use
// that implementation strategy, or an offset directly to the arena pointer if
// not (because e.g. we don't have an unknown field set).
- if (UseUnknownFieldSet(descriptor_->file())) {
+ if (UseUnknownFieldSet(descriptor_->file(), options_)) {
printer->Print(vars,
" GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
"$classname$, _internal_metadata_),\n");
@@ -1706,7 +1725,7 @@ GenerateDefaultInstanceAllocator(io::Printer* printer) {
"classname", classname_);
if ((descriptor_->oneof_decl_count() > 0) &&
- HasDescriptorMethods(descriptor_->file())) {
+ HasDescriptorMethods(descriptor_->file(), options_)) {
printer->Print(
"$classname$_default_oneof_instance_ = new $classname$OneofInstance();\n",
"classname", classname_);
@@ -1746,7 +1765,7 @@ GenerateShutdownCode(io::Printer* printer) {
"delete $classname$::default_instance_;\n",
"classname", classname_);
- if (HasDescriptorMethods(descriptor_->file())) {
+ if (HasDescriptorMethods(descriptor_->file(), options_)) {
if (descriptor_->oneof_decl_count() > 0) {
printer->Print(
"delete $classname$_default_oneof_instance_;\n",
@@ -1772,12 +1791,29 @@ GenerateShutdownCode(io::Printer* printer) {
void MessageGenerator::
GenerateClassMethods(io::Printer* printer) {
+ // mutable_unknown_fields wrapper function for LazyStringOutputStream
+ // callback.
+ if (PreserveUnknownFields(descriptor_) &&
+ !UseUnknownFieldSet(descriptor_->file(), options_)) {
+ printer->Print(
+ "static ::std::string* MutableUnknownFieldsFor$classname$(\n"
+ " $classname$* ptr) {\n"
+ " return ptr->mutable_unknown_fields();\n"
+ "}\n"
+ "\n",
+ "classname", classname_);
+ }
if (IsAnyMessage(descriptor_)) {
printer->Print(
"void $classname$::PackFrom(const ::google::protobuf::Message& message) {\n"
" _any_metadata_.PackFrom(message);\n"
"}\n"
"\n"
+ "void $classname$::PackFrom(const ::google::protobuf::Message& message,\n"
+ " const ::std::string& type_url_prefix) {\n"
+ " _any_metadata_.PackFrom(message, type_url_prefix);\n"
+ "}\n"
+ "\n"
"bool $classname$::UnpackTo(::google::protobuf::Message* message) const {\n"
" return _any_metadata_.UnpackTo(message);\n"
"}\n"
@@ -1832,7 +1868,7 @@ GenerateClassMethods(io::Printer* printer) {
printer->Print("\n");
}
- if (HasGeneratedMethods(descriptor_->file())) {
+ if (HasGeneratedMethods(descriptor_->file(), options_)) {
GenerateClear(printer);
printer->Print("\n");
@@ -1842,7 +1878,7 @@ GenerateClassMethods(io::Printer* printer) {
GenerateSerializeWithCachedSizes(printer);
printer->Print("\n");
- if (HasFastArraySerialization(descriptor_->file())) {
+ if (HasFastArraySerialization(descriptor_->file(), options_)) {
GenerateSerializeWithCachedSizesToArray(printer);
printer->Print("\n");
}
@@ -1863,7 +1899,7 @@ GenerateClassMethods(io::Printer* printer) {
GenerateSwap(printer);
printer->Print("\n");
- if (HasDescriptorMethods(descriptor_->file())) {
+ if (HasDescriptorMethods(descriptor_->file(), options_)) {
printer->Print(
"::google::protobuf::Metadata $classname$::GetMetadata() const {\n"
" protobuf_AssignDescriptorsOnce();\n"
@@ -1888,11 +1924,10 @@ GenerateClassMethods(io::Printer* printer) {
void MessageGenerator::
GenerateOffsets(io::Printer* printer) {
- printer->Print(
- "static const int $classname$_offsets_[$field_count$] = {\n",
- "classname", classname_,
- "field_count", SimpleItoa(max(
- 1, descriptor_->field_count() + descriptor_->oneof_decl_count())));
+ printer->Print("static const int $classname$_offsets_[$field_count$] = {\n",
+ "classname", classname_, "field_count",
+ SimpleItoa(std::max(1, descriptor_->field_count() +
+ descriptor_->oneof_decl_count())));
printer->Indent();
for (int i = 0; i < descriptor_->field_count(); i++) {
@@ -1941,7 +1976,7 @@ GenerateSharedConstructorCode(io::Printer* printer) {
"_cached_size_ = 0;\n").c_str());
if (PreserveUnknownFields(descriptor_) &&
- !UseUnknownFieldSet(descriptor_->file())) {
+ !UseUnknownFieldSet(descriptor_->file(), options_)) {
printer->Print(
"_unknown_fields_.UnsafeSetDefault(\n"
" &::google::protobuf::internal::GetEmptyStringAlreadyInited());\n");
@@ -1986,7 +2021,7 @@ GenerateSharedDestructorCode(io::Printer* printer) {
// Write the desctructor for _unknown_fields_ in lite runtime.
if (PreserveUnknownFields(descriptor_) &&
- !UseUnknownFieldSet(descriptor_->file())) {
+ !UseUnknownFieldSet(descriptor_->file(), options_)) {
if (SupportsArenas(descriptor_)) {
printer->Print(
"_unknown_fields_.Destroy(\n"
@@ -2017,11 +2052,11 @@ GenerateSharedDestructorCode(io::Printer* printer) {
}
PrintHandlingOptionalStaticInitializers(
- descriptor_->file(), printer,
- // With static initializers.
- "if (this != default_instance_) {\n",
- // Without.
- "if (this != &default_instance()) {\n");
+ descriptor_->file(), options_, printer,
+ // With static initializers.
+ "if (this != default_instance_) {\n",
+ // Without.
+ "if (this != &default_instance()) {\n");
// We need to delete all embedded messages.
// TODO(kenton): If we make unset messages point at default instances
@@ -2101,7 +2136,7 @@ GenerateStructors(io::Printer* printer) {
superclass =
DependentBaseClassTemplateName(descriptor_) + "<" + classname_ + ">";
} else {
- superclass = SuperClassName(descriptor_);
+ superclass = SuperClassName(descriptor_, options_);
}
string initializer_with_arena = superclass + "()";
@@ -2109,7 +2144,7 @@ GenerateStructors(io::Printer* printer) {
initializer_with_arena += ",\n _extensions_(arena)";
}
- if (UseUnknownFieldSet(descriptor_->file())) {
+ if (UseUnknownFieldSet(descriptor_->file(), options_)) {
initializer_with_arena += ",\n _internal_metadata_(arena)";
} else {
initializer_with_arena += ",\n _arena_ptr_(arena)";
@@ -2129,7 +2164,7 @@ GenerateStructors(io::Printer* printer) {
}
string initializer_null;
- initializer_null = (UseUnknownFieldSet(descriptor_->file()) ?
+ initializer_null = (UseUnknownFieldSet(descriptor_->file(), options_) ?
", _internal_metadata_(NULL)" : ", _arena_ptr_(NULL)");
if (IsAnyMessage(descriptor_)) {
initializer_null += ", _any_metadata_(&type_url_, &value_)";
@@ -2183,24 +2218,23 @@ GenerateStructors(io::Printer* printer) {
if (!field->is_repeated() &&
field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
(field->containing_oneof() == NULL ||
- HasDescriptorMethods(descriptor_->file()))) {
+ HasDescriptorMethods(descriptor_->file(), options_))) {
string name;
if (field->containing_oneof()) {
name = classname_ + "_default_oneof_instance_->";
}
name += FieldName(field);
PrintHandlingOptionalStaticInitializers(
- descriptor_->file(), printer,
- // With static initializers.
- " $name$_ = const_cast< $type$*>(&$type$::default_instance());\n",
- // Without.
- " $name$_ = const_cast< $type$*>(\n"
- " $type$::internal_default_instance());\n",
- // Vars.
- "name", name,
- "type", FieldMessageTypeName(field));
+ descriptor_->file(), options_, printer,
+ // With static initializers.
+ " $name$_ = const_cast< $type$*>(&$type$::default_instance());\n",
+ // Without.
+ " $name$_ = const_cast< $type$*>(\n"
+ " $type$::internal_default_instance());\n",
+ // Vars.
+ "name", name, "type", FieldMessageTypeName(field));
} else if (field->containing_oneof() &&
- HasDescriptorMethods(descriptor_->file())) {
+ HasDescriptorMethods(descriptor_->file(), options_)) {
field_generators_.get(descriptor_->field(i))
.GenerateConstructorCode(printer);
}
@@ -2216,10 +2250,10 @@ GenerateStructors(io::Printer* printer) {
"classname", classname_,
"superclass", superclass,
"full_name", descriptor_->full_name());
- if (UseUnknownFieldSet(descriptor_->file())) {
+ if (UseUnknownFieldSet(descriptor_->file(), options_)) {
printer->Print(
",\n _internal_metadata_(NULL)");
- } else if (!UseUnknownFieldSet(descriptor_->file())) {
+ } else if (!UseUnknownFieldSet(descriptor_->file(), options_)) {
printer->Print(",\n _arena_ptr_(NULL)");
}
if (IsAnyMessage(descriptor_)) {
@@ -2267,7 +2301,7 @@ GenerateStructors(io::Printer* printer) {
"classname", classname_);
// Only generate this member if it's not disabled.
- if (HasDescriptorMethods(descriptor_->file()) &&
+ if (HasDescriptorMethods(descriptor_->file(), options_) &&
!descriptor_->options().no_standard_descriptor_accessor()) {
printer->Print(
"const ::google::protobuf::Descriptor* $classname$::descriptor() {\n"
@@ -2285,14 +2319,14 @@ GenerateStructors(io::Printer* printer) {
"classname", classname_);
PrintHandlingOptionalStaticInitializers(
- descriptor_->file(), printer,
- // With static initializers.
- " if (default_instance_ == NULL) $adddescriptorsname$();\n",
- // Without.
- " $adddescriptorsname$();\n",
- // Vars.
- "adddescriptorsname",
- GlobalAddDescriptorsName(descriptor_->file()->name()));
+ descriptor_->file(), options_, printer,
+ // With static initializers.
+ " if (default_instance_ == NULL) $adddescriptorsname$();\n",
+ // Without.
+ " $adddescriptorsname$();\n",
+ // Vars.
+ "adddescriptorsname",
+ GlobalAddDescriptorsName(descriptor_->file()->name()));
printer->Print(
" return *default_instance_;\n"
@@ -2334,8 +2368,10 @@ static int popcnt(uint32 n) {
void MessageGenerator::
GenerateClear(io::Printer* printer) {
- printer->Print("void $classname$::Clear() {\n",
- "classname", classname_);
+ printer->Print(
+ "void $classname$::Clear() {\n"
+ "// @@protoc_insertion_point(message_clear_start:$full_name$)\n",
+ "classname", classname_, "full_name", descriptor_->full_name());
printer->Indent();
// Step 1: Extensions
@@ -2372,8 +2408,16 @@ GenerateClear(io::Printer* printer) {
// positions of two fields in the Message.
// ZR_ zeroes a non-empty range of fields via memset.
const char* macros =
+ "#if defined(__clang__)\n"
+ "#define ZR_HELPER_(f) \\\n"
+ " _Pragma(\"clang diagnostic push\") \\\n"
+ " _Pragma(\"clang diagnostic ignored \\\"-Winvalid-offsetof\\\"\") \\\n"
+ " __builtin_offsetof($classname$, f) \\\n"
+ " _Pragma(\"clang diagnostic pop\")\n"
+ "#else\n"
"#define ZR_HELPER_(f) reinterpret_cast<char*>(\\\n"
- " &reinterpret_cast<$classname$*>(16)->f)\n\n"
+ " &reinterpret_cast<$classname$*>(16)->f)\n"
+ "#endif\n\n"
"#define ZR_(first, last) do {\\\n"
" ::memset(&first, 0,\\\n"
" ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\\\n"
@@ -2501,7 +2545,7 @@ GenerateClear(io::Printer* printer) {
}
if (PreserveUnknownFields(descriptor_)) {
- if (UseUnknownFieldSet(descriptor_->file())) {
+ if (UseUnknownFieldSet(descriptor_->file(), options_)) {
printer->Print(
"if (_internal_metadata_.have_unknown_fields()) {\n"
" mutable_unknown_fields()->Clear();\n"
@@ -2531,10 +2575,13 @@ GenerateOneofClear(io::Printer* printer) {
map<string, string> oneof_vars;
oneof_vars["classname"] = classname_;
oneof_vars["oneofname"] = descriptor_->oneof_decl(i)->name();
+ oneof_vars["full_name"] = descriptor_->full_name();
string message_class;
printer->Print(oneof_vars,
- "void $classname$::clear_$oneofname$() {\n");
+ "void $classname$::clear_$oneofname$() {\n"
+ "// @@protoc_insertion_point(one_of_clear_start:"
+ "$full_name$)\n");
printer->Indent();
printer->Print(oneof_vars,
"switch($oneofname$_case()) {\n");
@@ -2617,7 +2664,7 @@ GenerateSwap(io::Printer* printer) {
"classname", classname_);
printer->Indent();
- if (HasGeneratedMethods(descriptor_->file())) {
+ if (HasGeneratedMethods(descriptor_->file(), options_)) {
for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor* field = descriptor_->field(i);
field_generators_.get(field).GenerateSwappingCode(printer);
@@ -2638,19 +2685,15 @@ GenerateSwap(io::Printer* printer) {
}
}
- if (PreserveUnknownFields(descriptor_)) {
- if (UseUnknownFieldSet(descriptor_->file())) {
- printer->Print(
+ // Ignore PreserveUnknownFields here - always swap internal_metadata as it
+ // may contain more than just unknown fields.
+ if (UseUnknownFieldSet(descriptor_->file(), options_)) {
+ printer->Print(
"_internal_metadata_.Swap(&other->_internal_metadata_);\n");
- } else {
- printer->Print("_unknown_fields_.Swap(&other->_unknown_fields_);\n");
- }
} else {
- // Still swap internal_metadata as it may contain more than just
- // unknown fields.
- printer->Print(
- "_internal_metadata_.Swap(&other->_internal_metadata_);\n");
+ printer->Print("_unknown_fields_.Swap(&other->_unknown_fields_);\n");
}
+
printer->Print("std::swap(_cached_size_, other->_cached_size_);\n");
if (descriptor_->extension_range_count() > 0) {
printer->Print("_extensions_.Swap(&other->_extensions_);\n");
@@ -2665,13 +2708,17 @@ GenerateSwap(io::Printer* printer) {
void MessageGenerator::
GenerateMergeFrom(io::Printer* printer) {
- if (HasDescriptorMethods(descriptor_->file())) {
+ if (HasDescriptorMethods(descriptor_->file(), options_)) {
// Generate the generalized MergeFrom (aka that which takes in the Message
// base class as a parameter).
printer->Print(
- "void $classname$::MergeFrom(const ::google::protobuf::Message& from) {\n"
- " if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);\n",
- "classname", classname_);
+ "void $classname$::MergeFrom(const ::google::protobuf::Message& from) {\n"
+ "// @@protoc_insertion_point(generalized_merge_from_start:"
+ "$full_name$)\n"
+ " if (GOOGLE_PREDICT_FALSE(&from == this)) {\n"
+ " ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);\n"
+ " }\n",
+ "classname", classname_, "full_name", descriptor_->full_name());
printer->Indent();
// Cast the message to the proper type. If we find that the message is
@@ -2683,11 +2730,15 @@ GenerateMergeFrom(io::Printer* printer) {
" ::google::protobuf::internal::DynamicCastToGenerated<const $classname$>(\n"
" &from);\n"
"if (source == NULL) {\n"
+ "// @@protoc_insertion_point(generalized_merge_from_cast_fail:"
+ "$full_name$)\n"
" ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n"
"} else {\n"
+ "// @@protoc_insertion_point(generalized_merge_from_cast_success:"
+ "$full_name$)\n"
" MergeFrom(*source);\n"
"}\n",
- "classname", classname_);
+ "classname", classname_, "full_name", descriptor_->full_name());
printer->Outdent();
printer->Print("}\n\n");
@@ -2704,9 +2755,13 @@ GenerateMergeFrom(io::Printer* printer) {
// Generate the class-specific MergeFrom, which avoids the GOOGLE_CHECK and cast.
printer->Print(
- "void $classname$::MergeFrom(const $classname$& from) {\n"
- " if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);\n",
- "classname", classname_);
+ "void $classname$::MergeFrom(const $classname$& from) {\n"
+ "// @@protoc_insertion_point(class_specific_merge_from_start:"
+ "$full_name$)\n"
+ " if (GOOGLE_PREDICT_FALSE(&from == this)) {\n"
+ " ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);\n"
+ " }\n",
+ "classname", classname_, "full_name", descriptor_->full_name());
printer->Indent();
// Merge Repeated fields. These fields do not require a
@@ -2807,14 +2862,16 @@ GenerateMergeFrom(io::Printer* printer) {
}
if (PreserveUnknownFields(descriptor_)) {
- if (UseUnknownFieldSet(descriptor_->file())) {
+ if (UseUnknownFieldSet(descriptor_->file(), options_)) {
printer->Print(
"if (from._internal_metadata_.have_unknown_fields()) {\n"
" mutable_unknown_fields()->MergeFrom(from.unknown_fields());\n"
"}\n");
} else {
printer->Print(
- "mutable_unknown_fields()->append(from.unknown_fields());\n");
+ "if (!from.unknown_fields().empty()) {\n"
+ " mutable_unknown_fields()->append(from.unknown_fields());\n"
+ "}\n");
}
}
@@ -2824,12 +2881,14 @@ GenerateMergeFrom(io::Printer* printer) {
void MessageGenerator::
GenerateCopyFrom(io::Printer* printer) {
- if (HasDescriptorMethods(descriptor_->file())) {
+ if (HasDescriptorMethods(descriptor_->file(), options_)) {
// Generate the generalized CopyFrom (aka that which takes in the Message
// base class as a parameter).
printer->Print(
- "void $classname$::CopyFrom(const ::google::protobuf::Message& from) {\n",
- "classname", classname_);
+ "void $classname$::CopyFrom(const ::google::protobuf::Message& from) {\n"
+ "// @@protoc_insertion_point(generalized_copy_from_start:"
+ "$full_name$)\n",
+ "classname", classname_, "full_name", descriptor_->full_name());
printer->Indent();
printer->Print(
@@ -2843,8 +2902,10 @@ GenerateCopyFrom(io::Printer* printer) {
// Generate the class-specific CopyFrom.
printer->Print(
- "void $classname$::CopyFrom(const $classname$& from) {\n",
- "classname", classname_);
+ "void $classname$::CopyFrom(const $classname$& from) {\n"
+ "// @@protoc_insertion_point(class_specific_copy_from_start:"
+ "$full_name$)\n",
+ "classname", classname_, "full_name", descriptor_->full_name());
printer->Indent();
printer->Print(
@@ -2866,15 +2927,15 @@ GenerateMergeFromCodedStream(io::Printer* printer) {
"classname", classname_);
PrintHandlingOptionalStaticInitializers(
- descriptor_->file(), printer,
- // With static initializers.
- " return _extensions_.ParseMessageSet(input, default_instance_,\n"
- " mutable_unknown_fields());\n",
- // Without.
- " return _extensions_.ParseMessageSet(input, &default_instance(),\n"
- " mutable_unknown_fields());\n",
- // Vars.
- "classname", classname_);
+ descriptor_->file(), options_, printer,
+ // With static initializers.
+ " return _extensions_.ParseMessageSet(input, default_instance_,\n"
+ " mutable_unknown_fields());\n",
+ // Without.
+ " return _extensions_.ParseMessageSet(input, &default_instance(),\n"
+ " mutable_unknown_fields());\n",
+ // Vars.
+ "classname", classname_);
printer->Print(
"}\n");
@@ -2884,16 +2945,22 @@ GenerateMergeFromCodedStream(io::Printer* printer) {
printer->Print(
"bool $classname$::MergePartialFromCodedStream(\n"
" ::google::protobuf::io::CodedInputStream* input) {\n"
- "#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure\n"
+ "#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure\n"
" ::google::protobuf::uint32 tag;\n",
"classname", classname_);
- if (!UseUnknownFieldSet(descriptor_->file())) {
- printer->Print(
- " ::google::protobuf::io::StringOutputStream unknown_fields_string(\n"
- " mutable_unknown_fields());\n"
+ if (PreserveUnknownFields(descriptor_) &&
+ !UseUnknownFieldSet(descriptor_->file(), options_)) {
+ // Use LazyStringOutputString to avoid initializing unknown fields string
+ // unless it is actually needed. For the same reason, disable eager refresh
+ // on the CodedOutputStream.
+ printer->Print(
+ " ::google::protobuf::io::LazyStringOutputStream unknown_fields_string(\n"
+ " ::google::protobuf::internal::NewPermanentCallback(\n"
+ " &MutableUnknownFieldsFor$classname$, this));\n"
" ::google::protobuf::io::CodedOutputStream unknown_fields_stream(\n"
- " &unknown_fields_string);\n");
+ " &unknown_fields_string, false);\n",
+ "classname", classname_);
}
printer->Print(
@@ -3111,32 +3178,32 @@ GenerateMergeFromCodedStream(io::Printer* printer) {
}
printer->Print(") {\n");
if (PreserveUnknownFields(descriptor_)) {
- if (UseUnknownFieldSet(descriptor_->file())) {
+ if (UseUnknownFieldSet(descriptor_->file(), options_)) {
PrintHandlingOptionalStaticInitializers(
- descriptor_->file(), printer,
- // With static initializers.
- " DO_(_extensions_.ParseField(tag, input, default_instance_,\n"
- " mutable_unknown_fields()));\n",
- // Without.
- " DO_(_extensions_.ParseField(tag, input, &default_instance(),\n"
- " mutable_unknown_fields()));\n");
+ descriptor_->file(), options_, printer,
+ // With static initializers.
+ " DO_(_extensions_.ParseField(tag, input, default_instance_,\n"
+ " mutable_unknown_fields()));\n",
+ // Without.
+ " DO_(_extensions_.ParseField(tag, input, &default_instance(),\n"
+ " mutable_unknown_fields()));\n");
} else {
PrintHandlingOptionalStaticInitializers(
- descriptor_->file(), printer,
- // With static initializers.
- " DO_(_extensions_.ParseField(tag, input, default_instance_,\n"
- " &unknown_fields_stream));\n",
- // Without.
- " DO_(_extensions_.ParseField(tag, input, &default_instance(),\n"
- " &unknown_fields_stream));\n");
+ descriptor_->file(), options_, printer,
+ // With static initializers.
+ " DO_(_extensions_.ParseField(tag, input, default_instance_,\n"
+ " &unknown_fields_stream));\n",
+ // Without.
+ " DO_(_extensions_.ParseField(tag, input, &default_instance(),\n"
+ " &unknown_fields_stream));\n");
}
} else {
PrintHandlingOptionalStaticInitializers(
- descriptor_->file(), printer,
- // With static initializers.
- " DO_(_extensions_.ParseField(tag, input, default_instance_);\n",
- // Without.
- " DO_(_extensions_.ParseField(tag, input, &default_instance());\n");
+ descriptor_->file(), options_, printer,
+ // With static initializers.
+ " DO_(_extensions_.ParseField(tag, input, default_instance_);\n",
+ // Without.
+ " DO_(_extensions_.ParseField(tag, input, &default_instance());\n");
}
printer->Print(
" continue;\n"
@@ -3145,7 +3212,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) {
// We really don't recognize this tag. Skip it.
if (PreserveUnknownFields(descriptor_)) {
- if (UseUnknownFieldSet(descriptor_->file())) {
+ if (UseUnknownFieldSet(descriptor_->file(), options_)) {
printer->Print(
"DO_(::google::protobuf::internal::WireFormat::SkipField(\n"
" input, tag, mutable_unknown_fields()));\n");
@@ -3220,8 +3287,8 @@ void MessageGenerator::GenerateSerializeOneExtensionRange(
"// Extension range [$start$, $end$)\n");
if (to_array) {
printer->Print(vars,
- "target = _extensions_.SerializeWithCachedSizesToArray(\n"
- " $start$, $end$, target);\n\n");
+ "target = _extensions_.InternalSerializeWithCachedSizesToArray(\n"
+ " $start$, $end$, false, target);\n\n");
} else {
printer->Print(vars,
"_extensions_.SerializeWithCachedSizes(\n"
@@ -3238,7 +3305,7 @@ GenerateSerializeWithCachedSizes(io::Printer* printer) {
" ::google::protobuf::io::CodedOutputStream* output) const {\n"
" _extensions_.SerializeMessageSetWithCachedSizes(output);\n",
"classname", classname_);
- GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file()));
+ GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file(), options_));
printer->Print(
" ::google::protobuf::internal::WireFormat::SerializeUnknownMessageSetItems(\n"
" unknown_fields(), output);\n");
@@ -3273,12 +3340,13 @@ GenerateSerializeWithCachedSizesToArray(io::Printer* printer) {
if (descriptor_->options().message_set_wire_format()) {
// Special-case MessageSet.
printer->Print(
- "::google::protobuf::uint8* $classname$::SerializeWithCachedSizesToArray(\n"
- " ::google::protobuf::uint8* target) const {\n"
- " target =\n"
- " _extensions_.SerializeMessageSetWithCachedSizesToArray(target);\n",
+ "::google::protobuf::uint8* $classname$::InternalSerializeWithCachedSizesToArray(\n"
+ " bool deterministic, ::google::protobuf::uint8* target) const {\n"
+ " target = _extensions_."
+ "InternalSerializeMessageSetWithCachedSizesToArray(\n"
+ " deterministic, target);\n",
"classname", classname_);
- GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file()));
+ GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file(), options_));
printer->Print(
" target = ::google::protobuf::internal::WireFormat::\n"
" SerializeUnknownMessageSetItemsToArray(\n"
@@ -3290,8 +3358,8 @@ GenerateSerializeWithCachedSizesToArray(io::Printer* printer) {
}
printer->Print(
- "::google::protobuf::uint8* $classname$::SerializeWithCachedSizesToArray(\n"
- " ::google::protobuf::uint8* target) const {\n",
+ "::google::protobuf::uint8* $classname$::InternalSerializeWithCachedSizesToArray(\n"
+ " bool deterministic, ::google::protobuf::uint8* target) const {\n",
"classname", classname_);
printer->Indent();
@@ -3344,7 +3412,7 @@ GenerateSerializeWithCachedSizesBody(io::Printer* printer, bool to_array) {
}
if (PreserveUnknownFields(descriptor_)) {
- if (UseUnknownFieldSet(descriptor_->file())) {
+ if (UseUnknownFieldSet(descriptor_->file(), options_)) {
printer->Print("if (_internal_metadata_.have_unknown_fields()) {\n");
printer->Indent();
if (to_array) {
@@ -3411,10 +3479,11 @@ GenerateByteSize(io::Printer* printer) {
if (descriptor_->options().message_set_wire_format()) {
// Special-case MessageSet.
printer->Print(
- "int $classname$::ByteSize() const {\n"
- " int total_size = _extensions_.MessageSetByteSize();\n",
- "classname", classname_);
- GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file()));
+ "int $classname$::ByteSize() const {\n"
+ "// @@protoc_insertion_point(message_set_byte_size_start:$full_name$)\n"
+ " int total_size = _extensions_.MessageSetByteSize();\n",
+ "classname", classname_, "full_name", descriptor_->full_name());
+ GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file(), options_));
printer->Print(
"if (_internal_metadata_.have_unknown_fields()) {\n"
" total_size += ::google::protobuf::internal::WireFormat::\n"
@@ -3433,8 +3502,10 @@ GenerateByteSize(io::Printer* printer) {
// Emit a function (rarely used, we hope) that handles the required fields
// by checking for each one individually.
printer->Print(
- "int $classname$::RequiredFieldsByteSizeFallback() const {\n",
- "classname", classname_);
+ "int $classname$::RequiredFieldsByteSizeFallback() const {\n"
+ "// @@protoc_insertion_point(required_fields_byte_size_fallback_start:"
+ "$full_name$)\n",
+ "classname", classname_, "full_name", descriptor_->full_name());
printer->Indent();
printer->Print("int total_size = 0;\n");
for (int i = 0; i < descriptor_->field_count(); i++) {
@@ -3457,8 +3528,9 @@ GenerateByteSize(io::Printer* printer) {
}
printer->Print(
- "int $classname$::ByteSize() const {\n",
- "classname", classname_);
+ "int $classname$::ByteSize() const {\n"
+ "// @@protoc_insertion_point(message_byte_size_start:$full_name$)\n",
+ "classname", classname_, "full_name", descriptor_->full_name());
printer->Indent();
printer->Print(
"int total_size = 0;\n"
@@ -3634,7 +3706,7 @@ GenerateByteSize(io::Printer* printer) {
}
if (PreserveUnknownFields(descriptor_)) {
- if (UseUnknownFieldSet(descriptor_->file())) {
+ if (UseUnknownFieldSet(descriptor_->file(), options_)) {
printer->Print(
"if (_internal_metadata_.have_unknown_fields()) {\n"
" total_size +=\n"
@@ -3700,8 +3772,8 @@ GenerateIsInitialized(io::Printer* printer) {
for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor* field = descriptor_->field(i);
if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
- !ShouldIgnoreRequiredFieldCheck(field) &&
- HasRequiredFields(field->message_type())) {
+ !ShouldIgnoreRequiredFieldCheck(field, options_) &&
+ HasRequiredFields(field->message_type(), options_)) {
if (field->is_repeated()) {
printer->Print(
"if (!::google::protobuf::internal::AllAreInitialized(this->$name$()))"
diff --git a/src/google/protobuf/compiler/cpp/cpp_message.h b/src/google/protobuf/compiler/cpp/cpp_message.h
index 8e19a3f0..b1e3fe21 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message.h
+++ b/src/google/protobuf/compiler/cpp/cpp_message.h
@@ -66,10 +66,14 @@ class MessageGenerator {
// Header stuff.
- // Return names for foward declarations of this class and all its nested
- // types.
- void FillMessageForwardDeclarations(set<string>* class_names);
- void FillEnumForwardDeclarations(set<string>* enum_names);
+ // Return names for forward declarations of this class and all its nested
+ // types. A given key in {class,enum}_names will map from a class name to the
+ // descriptor that was responsible for its inclusion in the map. This can be
+ // used to associate the descriptor with the code generated for it.
+ void FillMessageForwardDeclarations(
+ map<string, const Descriptor*>* class_names);
+ void FillEnumForwardDeclarations(
+ map<string, const EnumDescriptor*>* enum_names);
// Generate definitions of all nested enums (must come before class
// definitions because those classes use the enums definitions).
diff --git a/src/google/protobuf/compiler/cpp/cpp_message_field.cc b/src/google/protobuf/compiler/cpp/cpp_message_field.cc
index b4545892..d021035d 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_message_field.cc
@@ -53,10 +53,11 @@ void SetMessageVariables(const FieldDescriptor* descriptor,
(*variables)["non_null_ptr_to_name"] =
StrCat("this->", (*variables)["name"], "_");
}
- (*variables)["stream_writer"] = (*variables)["declared_type"] +
- (HasFastArraySerialization(descriptor->message_type()->file()) ?
- "MaybeToArray" :
- "");
+ (*variables)["stream_writer"] =
+ (*variables)["declared_type"] +
+ (HasFastArraySerialization(descriptor->message_type()->file(), options)
+ ? "MaybeToArray"
+ : "");
// NOTE: Escaped here to unblock proto1->proto2 migration.
// TODO(liujisi): Extend this to apply for other conflicting methods.
(*variables)["release_name"] =
@@ -77,11 +78,11 @@ void SetMessageVariables(const FieldDescriptor* descriptor,
// ===================================================================
-MessageFieldGenerator::
-MessageFieldGenerator(const FieldDescriptor* descriptor,
- const Options& options)
- : descriptor_(descriptor),
- dependent_field_(options.proto_h && IsFieldDependent(descriptor)) {
+MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
+ : FieldGenerator(options),
+ descriptor_(descriptor),
+ dependent_field_(options.proto_h && IsFieldDependent(descriptor)) {
SetMessageVariables(descriptor, &variables_, options);
}
@@ -95,7 +96,7 @@ GeneratePrivateMembers(io::Printer* printer) const {
void MessageFieldGenerator::
GenerateGetterDeclaration(io::Printer* printer) const {
printer->Print(variables_,
- "const $type$& $name$() const$deprecation$;\n");
+ "$deprecated_attr$const $type$& $name$() const;\n");
}
void MessageFieldGenerator::
@@ -105,9 +106,9 @@ GenerateDependentAccessorDeclarations(io::Printer* printer) const {
}
// Arena manipulation code is out-of-line in the derived message class.
printer->Print(variables_,
- "$type$* mutable_$name$()$deprecation$;\n"
- "$type$* $release_name$()$deprecation$;\n"
- "void set_allocated_$name$($type$* $name$)$deprecation$;\n");
+ "$deprecated_attr$$type$* mutable_$name$();\n"
+ "$deprecated_attr$$type$* $release_name$();\n"
+ "$deprecated_attr$void set_allocated_$name$($type$* $name$);\n");
}
void MessageFieldGenerator::
@@ -115,28 +116,28 @@ GenerateAccessorDeclarations(io::Printer* printer) const {
if (SupportsArenas(descriptor_)) {
printer->Print(variables_,
"private:\n"
- "void _slow_mutable_$name$()$deprecation$;\n");
+ "void _slow_mutable_$name$();\n");
if (SupportsArenas(descriptor_->message_type())) {
printer->Print(variables_,
"void _slow_set_allocated_$name$(\n"
- " ::google::protobuf::Arena* message_arena, $type$** $name$)$deprecation$;\n");
+ " ::google::protobuf::Arena* message_arena, $type$** $name$);\n");
}
printer->Print(variables_,
- "$type$* _slow_$release_name$()$deprecation$;\n"
+ "$type$* _slow_$release_name$();\n"
"public:\n");
}
GenerateGetterDeclaration(printer);
if (!dependent_field_) {
printer->Print(variables_,
- "$type$* mutable_$name$()$deprecation$;\n"
- "$type$* $release_name$()$deprecation$;\n"
- "void set_allocated_$name$($type$* $name$)$deprecation$;\n");
+ "$deprecated_attr$$type$* mutable_$name$();\n"
+ "$deprecated_attr$$type$* $release_name$();\n"
+ "$deprecated_attr$void set_allocated_$name$($type$* $name$);\n");
}
if (SupportsArenas(descriptor_)) {
printer->Print(variables_,
- "$type$* unsafe_arena_release_$name$()$deprecation$;\n"
- "void unsafe_arena_set_allocated_$name$(\n"
- " $type$* $name$)$deprecation$;\n");
+ "$deprecated_attr$$type$* unsafe_arena_release_$name$();\n"
+ "$deprecated_attr$void unsafe_arena_set_allocated_$name$(\n"
+ " $type$* $name$);\n");
}
}
@@ -167,6 +168,7 @@ void MessageFieldGenerator::GenerateNonInlineAccessorDefinitions(
" }\n"
"}\n"
"$type$* $classname$::unsafe_arena_release_$name$() {\n"
+ " // @@protoc_insertion_point(field_unsafe_arena_release:$full_name$)\n"
" $clear_hasbit$\n"
" $type$* temp = $name$_;\n"
" $name$_ = NULL;\n"
@@ -246,6 +248,7 @@ GenerateDependentInlineAccessorDefinitions(io::Printer* printer) const {
"}\n"
"template <class T>\n"
"inline $type$* $dependent_classname$::$release_name$() {\n"
+ " // @@protoc_insertion_point(field_release:$full_name$)\n"
" $dependent_typename$*& $name$_ = $this_message$$name$_;\n"
" $clear_hasbit$\n"
" if ($this_message$GetArenaNoVirtual() != NULL) {\n"
@@ -305,6 +308,7 @@ GenerateDependentInlineAccessorDefinitions(io::Printer* printer) const {
"}\n"
"template <class T>\n"
"inline $type$* $dependent_classname$::$release_name$() {\n"
+ " // @@protoc_insertion_point(field_release:$full_name$)\n"
" $clear_hasbit$\n"
" $dependent_typename$*& $name$_ = $this_message$$name$_;\n"
" $dependent_typename$* temp = $name$_;\n"
@@ -349,11 +353,11 @@ GenerateInlineAccessorDefinitions(io::Printer* printer,
" // @@protoc_insertion_point(field_get:$full_name$)\n");
PrintHandlingOptionalStaticInitializers(
- variables, descriptor_->file(), printer,
- // With static initializers.
- " return $name$_ != NULL ? *$name$_ : *default_instance_->$name$_;\n",
- // Without.
- " return $name$_ != NULL ? *$name$_ : *default_instance().$name$_;\n");
+ variables, descriptor_->file(), options_, printer,
+ // With static initializers.
+ " return $name$_ != NULL ? *$name$_ : *default_instance_->$name$_;\n",
+ // Without.
+ " return $name$_ != NULL ? *$name$_ : *default_instance().$name$_;\n");
printer->Print(variables, "}\n");
if (dependent_field_) {
@@ -373,6 +377,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer,
"}\n"
"$inline$"
"$type$* $classname$::$release_name$() {\n"
+ " // @@protoc_insertion_point(field_release:$full_name$)\n"
" $clear_hasbit$\n"
" if (GetArenaNoVirtual() != NULL) {\n"
" return _slow_$release_name$();\n"
@@ -426,6 +431,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer,
"}\n"
"$inline$"
"$type$* $classname$::$release_name$() {\n"
+ " // @@protoc_insertion_point(field_release:$full_name$)\n"
" $clear_hasbit$\n"
" $type$* temp = $name$_;\n"
" $name$_ = NULL;\n"
@@ -514,8 +520,8 @@ void MessageFieldGenerator::
GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
printer->Print(variables_,
"target = ::google::protobuf::internal::WireFormatLite::\n"
- " Write$declared_type$NoVirtualToArray(\n"
- " $number$, *$non_null_ptr_to_name$, target);\n");
+ " InternalWrite$declared_type$NoVirtualToArray(\n"
+ " $number$, *$non_null_ptr_to_name$, false, target);\n");
}
void MessageFieldGenerator::
@@ -547,7 +553,7 @@ GenerateDependentAccessorDeclarations(io::Printer* printer) const {
return;
}
printer->Print(variables_,
- "const $type$& $name$() const$deprecation$;\n");
+ "$deprecated_attr$const $type$& $name$() const;\n");
MessageFieldGenerator::GenerateDependentAccessorDeclarations(printer);
}
@@ -560,7 +566,7 @@ GenerateGetterDeclaration(io::Printer* printer) const {
return;
}
printer->Print(variables_,
- "const $type$& $name$() const$deprecation$;\n");
+ "$deprecated_attr$const $type$& $name$() const;\n");
}
void MessageOneofFieldGenerator::
@@ -651,6 +657,7 @@ InternalGenerateInlineAccessorDefinitions(const map<string, string>& variables,
"$tmpl$"
"$inline$"
"$type$* $dependent_classname$::$release_name$() {\n"
+ " // @@protoc_insertion_point(field_release:$full_name$)\n"
" if ($this_message$has_$name$()) {\n"
" $this_message$clear_has_$oneof_name$();\n"
" if ($this_message$GetArenaNoVirtual() != NULL) {\n"
@@ -706,6 +713,8 @@ InternalGenerateInlineAccessorDefinitions(const map<string, string>& variables,
" // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
"}\n"
"$inline$ $type$* $classname$::unsafe_arena_release_$name$() {\n"
+ " // @@protoc_insertion_point(field_unsafe_arena_release"
+ ":$full_name$)\n"
" if (has_$name$()) {\n"
" clear_has_$oneof_name$();\n"
" $type$* temp = $oneof_prefix$$name$_;\n"
@@ -744,6 +753,7 @@ InternalGenerateInlineAccessorDefinitions(const map<string, string>& variables,
"$tmpl$"
"$inline$"
"$type$* $dependent_classname$::$release_name$() {\n"
+ " // @@protoc_insertion_point(field_release:$full_name$)\n"
" if ($this_message$has_$name$()) {\n"
" $this_message$clear_has_$oneof_name$();\n"
" $dependent_typename$* temp = $field_member$;\n"
@@ -805,12 +815,12 @@ GenerateConstructorCode(io::Printer* printer) const {
// ===================================================================
-RepeatedMessageFieldGenerator::
-RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor,
- const Options& options)
- : descriptor_(descriptor),
- dependent_field_(options.proto_h && IsFieldDependent(descriptor)),
- dependent_getter_(dependent_field_ && options.safe_boundary_check) {
+RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator(
+ const FieldDescriptor* descriptor, const Options& options)
+ : FieldGenerator(options),
+ descriptor_(descriptor),
+ dependent_field_(options.proto_h && IsFieldDependent(descriptor)),
+ dependent_getter_(dependent_field_ && options.safe_boundary_check) {
SetMessageVariables(descriptor, &variables_, options);
}
@@ -825,23 +835,23 @@ GeneratePrivateMembers(io::Printer* printer) const {
void RepeatedMessageFieldGenerator::
InternalGenerateTypeDependentAccessorDeclarations(io::Printer* printer) const {
printer->Print(variables_,
- "$type$* mutable_$name$(int index)$deprecation$;\n"
- "$type$* add_$name$()$deprecation$;\n");
+ "$deprecated_attr$$type$* mutable_$name$(int index);\n"
+ "$deprecated_attr$$type$* add_$name$();\n");
if (dependent_getter_) {
printer->Print(variables_,
- "const ::google::protobuf::RepeatedPtrField< $type$ >&\n"
- " $name$() const$deprecation$;\n");
+ "$deprecated_attr$const ::google::protobuf::RepeatedPtrField< $type$ >&\n"
+ " $name$() const;\n");
}
printer->Print(variables_,
- "::google::protobuf::RepeatedPtrField< $type$ >*\n"
- " mutable_$name$()$deprecation$;\n");
+ "$deprecated_attr$::google::protobuf::RepeatedPtrField< $type$ >*\n"
+ " mutable_$name$();\n");
}
void RepeatedMessageFieldGenerator::
GenerateDependentAccessorDeclarations(io::Printer* printer) const {
if (dependent_getter_) {
printer->Print(variables_,
- "const $type$& $name$(int index) const$deprecation$;\n");
+ "$deprecated_attr$const $type$& $name$(int index) const;\n");
}
if (dependent_field_) {
InternalGenerateTypeDependentAccessorDeclarations(printer);
@@ -852,15 +862,15 @@ void RepeatedMessageFieldGenerator::
GenerateAccessorDeclarations(io::Printer* printer) const {
if (!dependent_getter_) {
printer->Print(variables_,
- "const $type$& $name$(int index) const$deprecation$;\n");
+ "$deprecated_attr$const $type$& $name$(int index) const;\n");
}
if (!dependent_field_) {
InternalGenerateTypeDependentAccessorDeclarations(printer);
}
if (!dependent_getter_) {
printer->Print(variables_,
- "const ::google::protobuf::RepeatedPtrField< $type$ >&\n"
- " $name$() const$deprecation$;\n");
+ "$deprecated_attr$const ::google::protobuf::RepeatedPtrField< $type$ >&\n"
+ " $name$() const;\n");
}
}
@@ -1023,8 +1033,8 @@ GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
printer->Print(variables_,
"for (unsigned int i = 0, n = this->$name$_size(); i < n; i++) {\n"
" target = ::google::protobuf::internal::WireFormatLite::\n"
- " Write$declared_type$NoVirtualToArray(\n"
- " $number$, this->$name$(i), target);\n"
+ " InternalWrite$declared_type$NoVirtualToArray(\n"
+ " $number$, this->$name$(i), false, target);\n"
"}\n");
}
diff --git a/src/google/protobuf/compiler/cpp/cpp_message_field.h b/src/google/protobuf/compiler/cpp/cpp_message_field.h
index 35efd0fa..d8d9279c 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message_field.h
+++ b/src/google/protobuf/compiler/cpp/cpp_message_field.h
@@ -46,8 +46,8 @@ namespace cpp {
class MessageFieldGenerator : public FieldGenerator {
public:
- explicit MessageFieldGenerator(const FieldDescriptor* descriptor,
- const Options& options);
+ MessageFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
~MessageFieldGenerator();
// implements FieldGenerator ---------------------------------------
@@ -83,8 +83,8 @@ class MessageFieldGenerator : public FieldGenerator {
class MessageOneofFieldGenerator : public MessageFieldGenerator {
public:
- explicit MessageOneofFieldGenerator(const FieldDescriptor* descriptor,
- const Options& options);
+ MessageOneofFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
~MessageOneofFieldGenerator();
// implements FieldGenerator ---------------------------------------
@@ -110,8 +110,8 @@ class MessageOneofFieldGenerator : public MessageFieldGenerator {
class RepeatedMessageFieldGenerator : public FieldGenerator {
public:
- explicit RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor,
- const Options& options);
+ RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
~RepeatedMessageFieldGenerator();
// implements FieldGenerator ---------------------------------------
diff --git a/src/google/protobuf/compiler/cpp/cpp_options.h b/src/google/protobuf/compiler/cpp/cpp_options.h
index 4463f200..ee44fb0a 100644
--- a/src/google/protobuf/compiler/cpp/cpp_options.h
+++ b/src/google/protobuf/compiler/cpp/cpp_options.h
@@ -43,11 +43,21 @@ namespace cpp {
// Generator options (see generator.cc for a description of each):
struct Options {
- Options() : safe_boundary_check(false), proto_h(false) {
- }
+ Options()
+ : safe_boundary_check(false),
+ proto_h(false),
+ allow_import_public(true),
+ annotate_headers(false),
+ enforce_lite(false) {}
+
string dllexport_decl;
bool safe_boundary_check;
bool proto_h;
+ bool allow_import_public;
+ bool annotate_headers;
+ bool enforce_lite;
+ string annotation_pragma_name;
+ string annotation_guard_name;
};
} // namespace cpp
diff --git a/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc
index d1efbfe6..34a41d82 100644
--- a/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc
@@ -44,9 +44,10 @@
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/io/printer.h>
+#include <google/protobuf/testing/file.h>
+#include <google/protobuf/testing/file.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
-#include <google/protobuf/testing/file.h>
namespace google {
namespace protobuf {
diff --git a/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc b/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc
index 9f929d37..650f0381 100644
--- a/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc
@@ -100,10 +100,9 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
// ===================================================================
-PrimitiveFieldGenerator::
-PrimitiveFieldGenerator(const FieldDescriptor* descriptor,
- const Options& options)
- : descriptor_(descriptor) {
+PrimitiveFieldGenerator::PrimitiveFieldGenerator(
+ const FieldDescriptor* descriptor, const Options& options)
+ : FieldGenerator(options), descriptor_(descriptor) {
SetPrimitiveVariables(descriptor, &variables_, options);
}
@@ -117,8 +116,8 @@ GeneratePrivateMembers(io::Printer* printer) const {
void PrimitiveFieldGenerator::
GenerateAccessorDeclarations(io::Printer* printer) const {
printer->Print(variables_,
- "$type$ $name$() const$deprecation$;\n"
- "void set_$name$($type$ value)$deprecation$;\n");
+ "$deprecated_attr$$type$ $name$() const;\n"
+ "$deprecated_attr$void set_$name$($type$ value);\n");
}
void PrimitiveFieldGenerator::
@@ -256,10 +255,9 @@ GenerateMergeFromCodedStream(io::Printer* printer) const {
// ===================================================================
-RepeatedPrimitiveFieldGenerator::
-RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor,
- const Options& options)
- : descriptor_(descriptor) {
+RepeatedPrimitiveFieldGenerator::RepeatedPrimitiveFieldGenerator(
+ const FieldDescriptor* descriptor, const Options& options)
+ : FieldGenerator(options), descriptor_(descriptor) {
SetPrimitiveVariables(descriptor, &variables_, options);
if (descriptor->is_packed()) {
@@ -277,7 +275,8 @@ void RepeatedPrimitiveFieldGenerator::
GeneratePrivateMembers(io::Printer* printer) const {
printer->Print(variables_,
"::google::protobuf::RepeatedField< $type$ > $name$_;\n");
- if (descriptor_->is_packed() && HasGeneratedMethods(descriptor_->file())) {
+ if (descriptor_->is_packed() &&
+ HasGeneratedMethods(descriptor_->file(), options_)) {
printer->Print(variables_,
"mutable int _$name$_cached_byte_size_;\n");
}
@@ -286,14 +285,14 @@ GeneratePrivateMembers(io::Printer* printer) const {
void RepeatedPrimitiveFieldGenerator::
GenerateAccessorDeclarations(io::Printer* printer) const {
printer->Print(variables_,
- "$type$ $name$(int index) const$deprecation$;\n"
- "void set_$name$(int index, $type$ value)$deprecation$;\n"
- "void add_$name$($type$ value)$deprecation$;\n");
+ "$deprecated_attr$$type$ $name$(int index) const;\n"
+ "$deprecated_attr$void set_$name$(int index, $type$ value);\n"
+ "$deprecated_attr$void add_$name$($type$ value);\n");
printer->Print(variables_,
- "const ::google::protobuf::RepeatedField< $type$ >&\n"
- " $name$() const$deprecation$;\n"
- "::google::protobuf::RepeatedField< $type$ >*\n"
- " mutable_$name$()$deprecation$;\n");
+ "$deprecated_attr$const ::google::protobuf::RepeatedField< $type$ >&\n"
+ " $name$() const;\n"
+ "$deprecated_attr$::google::protobuf::RepeatedField< $type$ >*\n"
+ " mutable_$name$();\n");
}
void RepeatedPrimitiveFieldGenerator::
diff --git a/src/google/protobuf/compiler/cpp/cpp_primitive_field.h b/src/google/protobuf/compiler/cpp/cpp_primitive_field.h
index fcd7d684..655ebde4 100644
--- a/src/google/protobuf/compiler/cpp/cpp_primitive_field.h
+++ b/src/google/protobuf/compiler/cpp/cpp_primitive_field.h
@@ -46,8 +46,8 @@ namespace cpp {
class PrimitiveFieldGenerator : public FieldGenerator {
public:
- explicit PrimitiveFieldGenerator(const FieldDescriptor* descriptor,
- const Options& options);
+ PrimitiveFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
~PrimitiveFieldGenerator();
// implements FieldGenerator ---------------------------------------
@@ -74,8 +74,8 @@ class PrimitiveFieldGenerator : public FieldGenerator {
class PrimitiveOneofFieldGenerator : public PrimitiveFieldGenerator {
public:
- explicit PrimitiveOneofFieldGenerator(const FieldDescriptor* descriptor,
- const Options& options);
+ PrimitiveOneofFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
~PrimitiveOneofFieldGenerator();
// implements FieldGenerator ---------------------------------------
@@ -92,8 +92,8 @@ class PrimitiveOneofFieldGenerator : public PrimitiveFieldGenerator {
class RepeatedPrimitiveFieldGenerator : public FieldGenerator {
public:
- explicit RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor,
- const Options& options);
+ RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
~RepeatedPrimitiveFieldGenerator();
// implements FieldGenerator ---------------------------------------
diff --git a/src/google/protobuf/compiler/cpp/cpp_service.cc b/src/google/protobuf/compiler/cpp/cpp_service.cc
index 226c2aa0..6030f7ce 100644
--- a/src/google/protobuf/compiler/cpp/cpp_service.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_service.cc
@@ -298,13 +298,15 @@ void ServiceGenerator::GenerateGetPrototype(RequestOrResponse which,
" return $type$::default_instance();\n");
}
- printer->Print(vars_,
+ printer->Print(
" default:\n"
" GOOGLE_LOG(FATAL) << \"Bad method index; this should never happen.\";\n"
- " return *static_cast< ::google::protobuf::Message*>(NULL);\n"
+ " return *::google::protobuf::MessageFactory::generated_factory()\n"
+ " ->GetPrototype(method->$input_or_output$_type());\n"
" }\n"
"}\n"
- "\n");
+ "\n",
+ "input_or_output", which == REQUEST ? "input" : "output");
}
void ServiceGenerator::GenerateStubMethods(io::Printer* printer) {
diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.cc b/src/google/protobuf/compiler/cpp/cpp_string_field.cc
index 6b0821a6..1d743457 100644
--- a/src/google/protobuf/compiler/cpp/cpp_string_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_string_field.cc
@@ -76,10 +76,9 @@ void SetStringVariables(const FieldDescriptor* descriptor,
// ===================================================================
-StringFieldGenerator::
-StringFieldGenerator(const FieldDescriptor* descriptor,
- const Options& options)
- : descriptor_(descriptor) {
+StringFieldGenerator::StringFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
+ : FieldGenerator(options), descriptor_(descriptor) {
SetStringVariables(descriptor, &variables_, options);
}
@@ -140,19 +139,19 @@ GenerateAccessorDeclarations(io::Printer* printer) const {
}
printer->Print(variables_,
- "const ::std::string& $name$() const$deprecation$;\n"
- "void set_$name$(const ::std::string& value)$deprecation$;\n"
- "void set_$name$(const char* value)$deprecation$;\n"
- "void set_$name$(const $pointer_type$* value, size_t size)"
- "$deprecation$;\n"
- "::std::string* mutable_$name$()$deprecation$;\n"
- "::std::string* $release_name$()$deprecation$;\n"
- "void set_allocated_$name$(::std::string* $name$)$deprecation$;\n");
+ "$deprecated_attr$const ::std::string& $name$() const;\n"
+ "$deprecated_attr$void set_$name$(const ::std::string& value);\n"
+ "$deprecated_attr$void set_$name$(const char* value);\n"
+ "$deprecated_attr$void set_$name$(const $pointer_type$* value, size_t size)"
+ ";\n"
+ "$deprecated_attr$::std::string* mutable_$name$();\n"
+ "$deprecated_attr$::std::string* $release_name$();\n"
+ "$deprecated_attr$void set_allocated_$name$(::std::string* $name$);\n");
if (SupportsArenas(descriptor_)) {
printer->Print(variables_,
- "::std::string* unsafe_arena_release_$name$()$deprecation$;\n"
- "void unsafe_arena_set_allocated_$name$(\n"
- " ::std::string* $name$)$deprecation$;\n");
+ "$deprecated_attr$::std::string* unsafe_arena_release_$name$();\n"
+ "$deprecated_attr$void unsafe_arena_set_allocated_$name$(\n"
+ " ::std::string* $name$);\n");
}
@@ -199,10 +198,12 @@ GenerateInlineAccessorDefinitions(io::Printer* printer,
" return $name$_.Mutable($default_variable$, GetArenaNoVirtual());\n"
"}\n"
"$inline$ ::std::string* $classname$::$release_name$() {\n"
+ " // @@protoc_insertion_point(field_release:$full_name$)\n"
" $clear_hasbit$\n"
" return $name$_.Release($default_variable$, GetArenaNoVirtual());\n"
"}\n"
"$inline$ ::std::string* $classname$::unsafe_arena_release_$name$() {\n"
+ " // @@protoc_insertion_point(field_unsafe_arena_release:$full_name$)\n"
" GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);\n"
" $clear_hasbit$\n"
" return $name$_.UnsafeArenaRelease($default_variable$,\n"
@@ -228,7 +229,8 @@ GenerateInlineAccessorDefinitions(io::Printer* printer,
" }\n"
" $name$_.UnsafeArenaSetAllocated($default_variable$,\n"
" $name$, GetArenaNoVirtual());\n"
- " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
+ " // @@protoc_insertion_point(field_unsafe_arena_set_allocated:"
+ "$full_name$)\n"
"}\n");
} else {
// No-arena case.
@@ -261,6 +263,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer,
" return $name$_.MutableNoArena($default_variable$);\n"
"}\n"
"$inline$ ::std::string* $classname$::$release_name$() {\n"
+ " // @@protoc_insertion_point(field_release:$full_name$)\n"
" $clear_hasbit$\n"
" return $name$_.ReleaseNoArena($default_variable$);\n"
"}\n"
@@ -369,7 +372,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) const {
if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
GenerateUtf8CheckCodeForString(
- descriptor_, true, variables_,
+ descriptor_, options_, true, variables_,
"this->$name$().data(), this->$name$().length(),\n", printer);
}
}
@@ -378,7 +381,7 @@ void StringFieldGenerator::
GenerateSerializeWithCachedSizes(io::Printer* printer) const {
if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
GenerateUtf8CheckCodeForString(
- descriptor_, false, variables_,
+ descriptor_, options_, false, variables_,
"this->$name$().data(), this->$name$().length(),\n", printer);
}
printer->Print(variables_,
@@ -390,7 +393,7 @@ void StringFieldGenerator::
GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
GenerateUtf8CheckCodeForString(
- descriptor_, false, variables_,
+ descriptor_, options_, false, variables_,
"this->$name$().data(), this->$name$().length(),\n", printer);
}
printer->Print(variables_,
@@ -477,6 +480,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer,
" // @@protoc_insertion_point(field_mutable:$full_name$)\n"
"}\n"
"$inline$ ::std::string* $classname$::$release_name$() {\n"
+ " // @@protoc_insertion_point(field_release:$full_name$)\n"
" if (has_$name$()) {\n"
" clear_has_$oneof_name$();\n"
" return $oneof_prefix$$name$_.Release($default_variable$,\n"
@@ -486,6 +490,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer,
" }\n"
"}\n"
"$inline$ ::std::string* $classname$::unsafe_arena_release_$name$() {\n"
+ " // @@protoc_insertion_point(field_unsafe_arena_release:$full_name$)\n"
" GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);\n"
" if (has_$name$()) {\n"
" clear_has_$oneof_name$();\n"
@@ -519,7 +524,8 @@ GenerateInlineAccessorDefinitions(io::Printer* printer,
" $oneof_prefix$$name$_.UnsafeArenaSetAllocated($default_variable$, "
"$name$, GetArenaNoVirtual());\n"
" }\n"
- " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
+ " // @@protoc_insertion_point(field_unsafe_arena_set_allocated:"
+ "$full_name$)\n"
"}\n");
} else {
// No-arena case.
@@ -572,6 +578,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer,
" return $oneof_prefix$$name$_.MutableNoArena($default_variable$);\n"
"}\n"
"$inline$ ::std::string* $classname$::$release_name$() {\n"
+ " // @@protoc_insertion_point(field_release:$full_name$)\n"
" if (has_$name$()) {\n"
" clear_has_$oneof_name$();\n"
" return $oneof_prefix$$name$_.ReleaseNoArena($default_variable$);\n"
@@ -658,7 +665,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) const {
if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
GenerateUtf8CheckCodeForString(
- descriptor_, true, variables_,
+ descriptor_, options_, true, variables_,
"this->$name$().data(), this->$name$().length(),\n", printer);
}
}
@@ -666,10 +673,9 @@ GenerateMergeFromCodedStream(io::Printer* printer) const {
// ===================================================================
-RepeatedStringFieldGenerator::
-RepeatedStringFieldGenerator(const FieldDescriptor* descriptor,
- const Options& options)
- : descriptor_(descriptor) {
+RepeatedStringFieldGenerator::RepeatedStringFieldGenerator(
+ const FieldDescriptor* descriptor, const Options& options)
+ : FieldGenerator(options), descriptor_(descriptor) {
SetStringVariables(descriptor, &variables_, options);
}
@@ -696,24 +702,24 @@ GenerateAccessorDeclarations(io::Printer* printer) const {
}
printer->Print(variables_,
- "const ::std::string& $name$(int index) const$deprecation$;\n"
- "::std::string* mutable_$name$(int index)$deprecation$;\n"
- "void set_$name$(int index, const ::std::string& value)$deprecation$;\n"
- "void set_$name$(int index, const char* value)$deprecation$;\n"
+ "$deprecated_attr$const ::std::string& $name$(int index) const;\n"
+ "$deprecated_attr$::std::string* mutable_$name$(int index);\n"
+ "$deprecated_attr$void set_$name$(int index, const ::std::string& value);\n"
+ "$deprecated_attr$void set_$name$(int index, const char* value);\n"
""
- "void set_$name$(int index, const $pointer_type$* value, size_t size)"
- "$deprecation$;\n"
- "::std::string* add_$name$()$deprecation$;\n"
- "void add_$name$(const ::std::string& value)$deprecation$;\n"
- "void add_$name$(const char* value)$deprecation$;\n"
- "void add_$name$(const $pointer_type$* value, size_t size)"
- "$deprecation$;\n");
+ "$deprecated_attr$void set_$name$("
+ "int index, const $pointer_type$* value, size_t size);\n"
+ "$deprecated_attr$::std::string* add_$name$();\n"
+ "$deprecated_attr$void add_$name$(const ::std::string& value);\n"
+ "$deprecated_attr$void add_$name$(const char* value);\n"
+ "$deprecated_attr$void add_$name$(const $pointer_type$* value, size_t size)"
+ ";\n");
printer->Print(variables_,
- "const ::google::protobuf::RepeatedPtrField< ::std::string>& $name$() const"
- "$deprecation$;\n"
- "::google::protobuf::RepeatedPtrField< ::std::string>* mutable_$name$()"
- "$deprecation$;\n");
+ "$deprecated_attr$const ::google::protobuf::RepeatedPtrField< ::std::string>& $name$() "
+ "const;\n"
+ "$deprecated_attr$::google::protobuf::RepeatedPtrField< ::std::string>* mutable_$name$()"
+ ";\n");
if (unknown_ctype) {
printer->Outdent();
@@ -752,6 +758,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer,
" // @@protoc_insertion_point(field_set_pointer:$full_name$)\n"
"}\n"
"$inline$ ::std::string* $classname$::add_$name$() {\n"
+ " // @@protoc_insertion_point(field_add_mutable:$full_name$)\n"
" return $name$_.Add();\n"
"}\n"
"$inline$ void $classname$::add_$name$(const ::std::string& value) {\n"
@@ -807,7 +814,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) const {
" input, this->add_$name$()));\n");
if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
GenerateUtf8CheckCodeForString(
- descriptor_, true, variables_,
+ descriptor_, options_, true, variables_,
"this->$name$(this->$name$_size() - 1).data(),\n"
"this->$name$(this->$name$_size() - 1).length(),\n",
printer);
@@ -821,7 +828,7 @@ GenerateSerializeWithCachedSizes(io::Printer* printer) const {
printer->Indent();
if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
GenerateUtf8CheckCodeForString(
- descriptor_, false, variables_,
+ descriptor_, options_, false, variables_,
"this->$name$(i).data(), this->$name$(i).length(),\n", printer);
}
printer->Outdent();
@@ -838,7 +845,7 @@ GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
printer->Indent();
if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
GenerateUtf8CheckCodeForString(
- descriptor_, false, variables_,
+ descriptor_, options_, false, variables_,
"this->$name$(i).data(), this->$name$(i).length(),\n", printer);
}
printer->Outdent();
diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.h b/src/google/protobuf/compiler/cpp/cpp_string_field.h
index 616e2067..cb4e8772 100644
--- a/src/google/protobuf/compiler/cpp/cpp_string_field.h
+++ b/src/google/protobuf/compiler/cpp/cpp_string_field.h
@@ -46,8 +46,8 @@ namespace cpp {
class StringFieldGenerator : public FieldGenerator {
public:
- explicit StringFieldGenerator(const FieldDescriptor* descriptor,
- const Options& options);
+ StringFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
~StringFieldGenerator();
// implements FieldGenerator ---------------------------------------
@@ -79,8 +79,8 @@ class StringFieldGenerator : public FieldGenerator {
class StringOneofFieldGenerator : public StringFieldGenerator {
public:
- explicit StringOneofFieldGenerator(const FieldDescriptor* descriptor,
- const Options& options);
+ StringOneofFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
~StringOneofFieldGenerator();
// implements FieldGenerator ---------------------------------------
@@ -99,8 +99,8 @@ class StringOneofFieldGenerator : public StringFieldGenerator {
class RepeatedStringFieldGenerator : public FieldGenerator {
public:
- explicit RepeatedStringFieldGenerator(const FieldDescriptor* descriptor,
- const Options& options);
+ RepeatedStringFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
~RepeatedStringFieldGenerator();
// implements FieldGenerator ---------------------------------------
diff --git a/src/google/protobuf/compiler/cpp/cpp_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_unittest.cc
index 9942a343..5d82946d 100644
--- a/src/google/protobuf/compiler/cpp/cpp_unittest.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_unittest.cc
@@ -82,7 +82,6 @@
namespace google {
namespace protobuf {
-using internal::NewPermanentCallback;
namespace compiler {
namespace cpp {
@@ -1253,7 +1252,7 @@ class GeneratedServiceTest : public testing::Test {
foo_(descriptor_->FindMethodByName("Foo")),
bar_(descriptor_->FindMethodByName("Bar")),
stub_(&mock_channel_),
- done_(NewPermanentCallback(&DoNothing)) {}
+ done_(::google::protobuf::internal::NewPermanentCallback(&DoNothing)) {}
virtual void SetUp() {
ASSERT_TRUE(foo_ != NULL);
diff --git a/src/google/protobuf/compiler/cpp/metadata_test.cc b/src/google/protobuf/compiler/cpp/metadata_test.cc
new file mode 100644
index 00000000..edd30780
--- /dev/null
+++ b/src/google/protobuf/compiler/cpp/metadata_test.cc
@@ -0,0 +1,242 @@
+// 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 <memory>
+#ifndef _SHARED_PTR_H
+#include <google/protobuf/stubs/shared_ptr.h>
+#endif
+
+#include <google/protobuf/compiler/cpp/cpp_helpers.h>
+#include <google/protobuf/compiler/cpp/cpp_generator.h>
+#include <google/protobuf/compiler/command_line_interface.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/descriptor.pb.h>
+
+#include <google/protobuf/testing/file.h>
+#include <google/protobuf/testing/file.h>
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+namespace {
+
+// A CodeGenerator that captures the FileDescriptor it's passed as a
+// FileDescriptorProto.
+class DescriptorCapturingGenerator : public CodeGenerator {
+ public:
+ // Does not own file; file must outlive the Generator.
+ explicit DescriptorCapturingGenerator(FileDescriptorProto* file)
+ : file_(file) {}
+
+ virtual bool Generate(const FileDescriptor* file, const string& parameter,
+ GeneratorContext* context, string* error) const {
+ file->CopyTo(file_);
+ return true;
+ }
+
+ private:
+ FileDescriptorProto* file_;
+};
+
+class CppMetadataTest : public ::testing::Test {
+ public:
+ // Adds a file with name `filename` and content `data`.
+ void AddFile(const string& filename, const string& data) {
+ GOOGLE_CHECK_OK(File::SetContents(TestTempDir() + "/" + filename, data,
+ true));
+ }
+
+ // Tries to capture a FileDescriptorProto, GeneratedCodeInfo, and output
+ // code from the previously added file with name `filename`. Returns true on
+ // success. If pb_h is non-null, expects a .pb.h and a .pb.h.meta (copied to
+ // pb_h and pb_h_info respecfively); similarly for proto_h and proto_h_info.
+ bool CaptureMetadata(const string& filename, FileDescriptorProto* file,
+ string* pb_h, GeneratedCodeInfo* pb_h_info,
+ string* proto_h, GeneratedCodeInfo* proto_h_info,
+ string* pb_cc) {
+ google::protobuf::compiler::CommandLineInterface cli;
+ cli.SetInputsAreProtoPathRelative(true);
+
+ CppGenerator cpp_generator;
+ DescriptorCapturingGenerator capturing_generator(file);
+ cli.RegisterGenerator("--cpp_out", &cpp_generator, "");
+ cli.RegisterGenerator("--capture_out", &capturing_generator, "");
+
+ string proto_path = "-I" + TestTempDir();
+ string cpp_out =
+ "--cpp_out=annotate_headers=true,"
+ "annotation_pragma_name=pragma_name,"
+ "annotation_guard_name=guard_name:" +
+ TestTempDir();
+ string capture_out = "--capture_out=" + TestTempDir();
+
+ const char* argv[] = {"protoc", proto_path.c_str(), cpp_out.c_str(),
+ capture_out.c_str(), filename.c_str()};
+
+ if (cli.Run(5, argv) != 0) {
+ return false;
+ }
+
+ string output_base = TestTempDir() + "/" + StripProto(filename);
+
+ if (pb_cc != NULL) {
+ GOOGLE_CHECK_OK(
+ File::GetContents(output_base + ".pb.cc", pb_cc, true));
+ }
+
+ if (pb_h != NULL && pb_h_info != NULL) {
+ GOOGLE_CHECK_OK(
+ File::GetContents(output_base + ".pb.h", pb_h, true));
+ if (!DecodeMetadata(output_base + ".pb.h.meta", pb_h_info)) {
+ return false;
+ }
+ }
+
+ if (proto_h != NULL && proto_h_info != NULL) {
+ GOOGLE_CHECK_OK(File::GetContents(output_base + ".proto.h", proto_h,
+ true));
+ if (!DecodeMetadata(output_base + ".proto.h.meta", proto_h_info)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private:
+ // Decodes GeneratedCodeInfo stored in path and copies it to info.
+ // Returns true on success.
+ bool DecodeMetadata(const string& path, GeneratedCodeInfo* info) {
+ string data;
+ GOOGLE_CHECK_OK(File::GetContents(path, &data, true));
+ io::ArrayInputStream input(data.data(), data.size());
+ return info->ParseFromZeroCopyStream(&input);
+ }
+};
+
+const char kSmallTestFile[] =
+ "syntax = \"proto2\";\n"
+ "package foo;\n"
+ "enum Enum { VALUE = 0; }\n"
+ "message Message { }\n";
+
+// Finds the Annotation for a given source file and path (or returns null if it
+// couldn't).
+const GeneratedCodeInfo::Annotation* FindAnnotationOnPath(
+ const GeneratedCodeInfo& info, const string& source_file,
+ const vector<int>& path) {
+ for (int i = 0; i < info.annotation_size(); ++i) {
+ const GeneratedCodeInfo::Annotation* annotation = &info.annotation(i);
+ if (annotation->source_file() != source_file ||
+ annotation->path_size() != path.size()) {
+ continue;
+ }
+ int node = 0;
+ for (; node < path.size(); ++node) {
+ if (annotation->path(node) != path[node]) {
+ break;
+ }
+ }
+ if (node == path.size()) {
+ return annotation;
+ }
+ }
+ return NULL;
+}
+
+// Returns true if the provided annotation covers a given substring in
+// file_content.
+bool AnnotationMatchesSubstring(const string& file_content,
+ const GeneratedCodeInfo::Annotation* annotation,
+ const string& expected_text) {
+ uint32 begin = annotation->begin();
+ uint32 end = annotation->end();
+ if (end < begin || end > file_content.size()) {
+ return false;
+ }
+ return file_content.substr(begin, end - begin) == expected_text;
+}
+
+TEST_F(CppMetadataTest, CapturesEnumNames) {
+ FileDescriptorProto file;
+ GeneratedCodeInfo info;
+ string pb_h;
+ AddFile("test.proto", kSmallTestFile);
+ EXPECT_TRUE(
+ CaptureMetadata("test.proto", &file, &pb_h, &info, NULL, NULL, NULL));
+ EXPECT_EQ("Enum", file.enum_type(0).name());
+ vector<int> enum_path;
+ enum_path.push_back(FileDescriptorProto::kEnumTypeFieldNumber);
+ enum_path.push_back(0);
+ const GeneratedCodeInfo::Annotation* enum_annotation =
+ FindAnnotationOnPath(info, "test.proto", enum_path);
+ EXPECT_TRUE(NULL != enum_annotation);
+ EXPECT_TRUE(AnnotationMatchesSubstring(pb_h, enum_annotation, "Enum"));
+}
+
+TEST_F(CppMetadataTest, AddsPragma) {
+ FileDescriptorProto file;
+ GeneratedCodeInfo info;
+ string pb_h;
+ AddFile("test.proto", kSmallTestFile);
+ EXPECT_TRUE(
+ CaptureMetadata("test.proto", &file, &pb_h, &info, NULL, NULL, NULL));
+ EXPECT_TRUE(pb_h.find("#ifdef guard_name") != string::npos);
+ EXPECT_TRUE(pb_h.find("#pragma pragma_name \"test.pb.h.meta\"") !=
+ string::npos);
+}
+
+TEST_F(CppMetadataTest, CapturesMessageNames) {
+ FileDescriptorProto file;
+ GeneratedCodeInfo info;
+ string pb_h;
+ AddFile("test.proto", kSmallTestFile);
+ EXPECT_TRUE(
+ CaptureMetadata("test.proto", &file, &pb_h, &info, NULL, NULL, NULL));
+ EXPECT_EQ("Message", file.message_type(0).name());
+ vector<int> message_path;
+ message_path.push_back(FileDescriptorProto::kMessageTypeFieldNumber);
+ message_path.push_back(0);
+ const GeneratedCodeInfo::Annotation* message_annotation =
+ FindAnnotationOnPath(info, "test.proto", message_path);
+ EXPECT_TRUE(NULL != message_annotation);
+ EXPECT_TRUE(AnnotationMatchesSubstring(pb_h, message_annotation, "Message"));
+}
+
+} // namespace
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/google/protobuf/compiler/csharp/csharp_enum.cc b/src/google/protobuf/compiler/csharp/csharp_enum.cc
index 56681989..9e4da1ed 100644
--- a/src/google/protobuf/compiler/csharp/csharp_enum.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_enum.cc
@@ -41,6 +41,7 @@
#include <google/protobuf/compiler/csharp/csharp_doc_comment.h>
#include <google/protobuf/compiler/csharp/csharp_enum.h>
#include <google/protobuf/compiler/csharp/csharp_helpers.h>
+#include <google/protobuf/compiler/csharp/csharp_options.h>
using google::protobuf::internal::scoped_ptr;
@@ -49,8 +50,8 @@ namespace protobuf {
namespace compiler {
namespace csharp {
-EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor) :
- SourceGeneratorBase(descriptor->file()),
+EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor, const Options* options) :
+ SourceGeneratorBase(descriptor->file(), options),
descriptor_(descriptor) {
}
@@ -59,16 +60,26 @@ EnumGenerator::~EnumGenerator() {
void EnumGenerator::Generate(io::Printer* printer) {
WriteEnumDocComment(printer, descriptor_);
- WriteGeneratedCodeAttributes(printer);
printer->Print("$access_level$ enum $name$ {\n",
"access_level", class_access_level(),
"name", descriptor_->name());
printer->Indent();
+ std::set<string> used_names;
for (int i = 0; i < descriptor_->value_count(); i++) {
WriteEnumValueDocComment(printer, descriptor_->value(i));
- printer->Print("$name$ = $number$,\n",
- "name", descriptor_->value(i)->name(),
- "number", SimpleItoa(descriptor_->value(i)->number()));
+ string original_name = descriptor_->value(i)->name();
+ string name = GetEnumValueName(descriptor_->name(), descriptor_->value(i)->name());
+ // Make sure we don't get any duplicate names due to prefix removal.
+ while (!used_names.insert(name).second) {
+ // It's possible we'll end up giving this warning multiple times, but that's better than not at all.
+ GOOGLE_LOG(WARNING) << "Duplicate enum value " << name << " (originally " << original_name
+ << ") in " << descriptor_->name() << "; adding underscore to distinguish";
+ name += "_";
+ }
+ printer->Print("[pbr::OriginalName(\"$original_name$\")] $name$ = $number$,\n",
+ "original_name", original_name,
+ "name", name,
+ "number", SimpleItoa(descriptor_->value(i)->number()));
}
printer->Outdent();
printer->Print("}\n");
diff --git a/src/google/protobuf/compiler/csharp/csharp_enum.h b/src/google/protobuf/compiler/csharp/csharp_enum.h
index 2cf2fad4..8925cdf2 100644
--- a/src/google/protobuf/compiler/csharp/csharp_enum.h
+++ b/src/google/protobuf/compiler/csharp/csharp_enum.h
@@ -43,7 +43,7 @@ namespace csharp {
class EnumGenerator : public SourceGeneratorBase {
public:
- EnumGenerator(const EnumDescriptor* descriptor);
+ EnumGenerator(const EnumDescriptor* descriptor, const Options* options);
~EnumGenerator();
void Generate(io::Printer* printer);
diff --git a/src/google/protobuf/compiler/csharp/csharp_enum_field.cc b/src/google/protobuf/compiler/csharp/csharp_enum_field.cc
index d38fb1ed..67c0b596 100644
--- a/src/google/protobuf/compiler/csharp/csharp_enum_field.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_enum_field.cc
@@ -38,6 +38,7 @@
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/compiler/csharp/csharp_helpers.h>
+#include <google/protobuf/compiler/csharp/csharp_options.h>
#include <google/protobuf/compiler/csharp/csharp_enum_field.h>
namespace google {
@@ -46,8 +47,8 @@ namespace compiler {
namespace csharp {
EnumFieldGenerator::EnumFieldGenerator(const FieldDescriptor* descriptor,
- int fieldOrdinal)
- : PrimitiveFieldGenerator(descriptor, fieldOrdinal) {
+ int fieldOrdinal, const Options *options)
+ : PrimitiveFieldGenerator(descriptor, fieldOrdinal, options) {
}
EnumFieldGenerator::~EnumFieldGenerator() {
@@ -80,9 +81,9 @@ void EnumFieldGenerator::GenerateCodecCode(io::Printer* printer) {
"pb::FieldCodec.ForEnum($tag$, x => (int) x, x => ($type_name$) x)");
}
-EnumOneofFieldGenerator::EnumOneofFieldGenerator(const FieldDescriptor* descriptor,
- int fieldOrdinal)
- : PrimitiveOneofFieldGenerator(descriptor, fieldOrdinal) {
+EnumOneofFieldGenerator::EnumOneofFieldGenerator(
+ const FieldDescriptor* descriptor, int fieldOrdinal, const Options *options)
+ : PrimitiveOneofFieldGenerator(descriptor, fieldOrdinal, options) {
}
EnumOneofFieldGenerator::~EnumOneofFieldGenerator() {
diff --git a/src/google/protobuf/compiler/csharp/csharp_enum_field.h b/src/google/protobuf/compiler/csharp/csharp_enum_field.h
index 08364157..9b7669ba 100644
--- a/src/google/protobuf/compiler/csharp/csharp_enum_field.h
+++ b/src/google/protobuf/compiler/csharp/csharp_enum_field.h
@@ -43,7 +43,9 @@ namespace csharp {
class EnumFieldGenerator : public PrimitiveFieldGenerator {
public:
- EnumFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal);
+ EnumFieldGenerator(const FieldDescriptor* descriptor,
+ int fieldOrdinal,
+ const Options *options);
~EnumFieldGenerator();
virtual void GenerateCodecCode(io::Printer* printer);
@@ -57,7 +59,9 @@ class EnumFieldGenerator : public PrimitiveFieldGenerator {
class EnumOneofFieldGenerator : public PrimitiveOneofFieldGenerator {
public:
- EnumOneofFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal);
+ EnumOneofFieldGenerator(const FieldDescriptor* descriptor,
+ int fieldOrdinal,
+ const Options *options);
~EnumOneofFieldGenerator();
virtual void GenerateParsingCode(io::Printer* printer);
diff --git a/src/google/protobuf/compiler/csharp/csharp_field_base.cc b/src/google/protobuf/compiler/csharp/csharp_field_base.cc
index 5df43d3f..e2011b76 100644
--- a/src/google/protobuf/compiler/csharp/csharp_field_base.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_field_base.cc
@@ -94,14 +94,15 @@ void FieldGeneratorBase::SetCommonFieldVariables(
void FieldGeneratorBase::SetCommonOneofFieldVariables(
map<string, string>* variables) {
(*variables)["oneof_name"] = oneof_name();
- (*variables)["has_property_check"] = oneof_name() + "Case_ == " + oneof_property_name() +
+ (*variables)["has_property_check"] =
+ oneof_name() + "Case_ == " + oneof_property_name() +
"OneofCase." + property_name();
(*variables)["oneof_property_name"] = oneof_property_name();
}
FieldGeneratorBase::FieldGeneratorBase(const FieldDescriptor* descriptor,
- int fieldOrdinal)
- : SourceGeneratorBase(descriptor->file()),
+ int fieldOrdinal, const Options* options)
+ : SourceGeneratorBase(descriptor->file(), options),
descriptor_(descriptor),
fieldOrdinal_(fieldOrdinal) {
SetCommonFieldVariables(&variables_);
@@ -123,12 +124,13 @@ void FieldGeneratorBase::GenerateCodecCode(io::Printer* printer) {
void FieldGeneratorBase::AddDeprecatedFlag(io::Printer* printer) {
if (descriptor_->options().deprecated())
{
- printer->Print("[global::System.ObsoleteAttribute()]\n");
+ printer->Print("[global::System.ObsoleteAttribute]\n");
}
}
void FieldGeneratorBase::AddPublicMemberAttributes(io::Printer* printer) {
AddDeprecatedFlag(printer);
+ WriteGeneratedCodeAttributes(printer);
}
std::string FieldGeneratorBase::oneof_property_name() {
@@ -158,10 +160,11 @@ std::string FieldGeneratorBase::type_name(const FieldDescriptor* descriptor) {
case FieldDescriptor::TYPE_MESSAGE:
case FieldDescriptor::TYPE_GROUP:
if (IsWrapperType(descriptor)) {
- const FieldDescriptor* wrapped_field = descriptor->message_type()->field(0);
+ const FieldDescriptor* wrapped_field =
+ descriptor->message_type()->field(0);
string wrapped_field_type_name = type_name(wrapped_field);
- // String and ByteString go to the same type; other wrapped types go to the
- // nullable equivalent.
+ // String and ByteString go to the same type; other wrapped types
+ // go to the nullable equivalent.
if (wrapped_field->type() == FieldDescriptor::TYPE_STRING ||
wrapped_field->type() == FieldDescriptor::TYPE_BYTES) {
return wrapped_field_type_name;
@@ -304,7 +307,9 @@ std::string FieldGeneratorBase::default_value() {
std::string FieldGeneratorBase::default_value(const FieldDescriptor* descriptor) {
switch (descriptor->type()) {
case FieldDescriptor::TYPE_ENUM:
- return type_name() + "." + descriptor->default_value_enum()->name();
+ // All proto3 enums have a default value of 0, and there's an implicit conversion from the constant 0 to
+ // any C# enum. This means we don't need to work out what we actually mapped the enum value name to.
+ return "0";
case FieldDescriptor::TYPE_MESSAGE:
case FieldDescriptor::TYPE_GROUP:
if (IsWrapperType(descriptor)) {
diff --git a/src/google/protobuf/compiler/csharp/csharp_field_base.h b/src/google/protobuf/compiler/csharp/csharp_field_base.h
index d83543bd..4109f3ca 100644
--- a/src/google/protobuf/compiler/csharp/csharp_field_base.h
+++ b/src/google/protobuf/compiler/csharp/csharp_field_base.h
@@ -44,7 +44,9 @@ namespace csharp {
class FieldGeneratorBase : public SourceGeneratorBase {
public:
- FieldGeneratorBase(const FieldDescriptor* descriptor, int fieldOrdinal);
+ FieldGeneratorBase(const FieldDescriptor* descriptor,
+ int fieldOrdinal,
+ const Options* options);
~FieldGeneratorBase();
virtual void GenerateCloningCode(io::Printer* printer) = 0;
diff --git a/src/google/protobuf/compiler/csharp/csharp_generator.cc b/src/google/protobuf/compiler/csharp/csharp_generator.cc
index 825de542..c13ed65b 100644
--- a/src/google/protobuf/compiler/csharp/csharp_generator.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_generator.cc
@@ -41,6 +41,7 @@
#include <google/protobuf/compiler/csharp/csharp_generator.h>
#include <google/protobuf/compiler/csharp/csharp_helpers.h>
#include <google/protobuf/compiler/csharp/csharp_names.h>
+#include <google/protobuf/compiler/csharp/csharp_options.h>
#include <google/protobuf/compiler/csharp/csharp_reflection_class.h>
using google::protobuf::internal::scoped_ptr;
@@ -51,8 +52,9 @@ namespace compiler {
namespace csharp {
void GenerateFile(const google::protobuf::FileDescriptor* file,
- io::Printer* printer) {
- ReflectionClassGenerator reflectionClassGenerator(file);
+ io::Printer* printer,
+ const Options* options) {
+ ReflectionClassGenerator reflectionClassGenerator(file, options);
reflectionClassGenerator.Generate(printer);
}
@@ -71,15 +73,16 @@ bool Generator::Generate(
return false;
}
- std::string file_extension = ".cs";
- std::string base_namespace = "";
- bool generate_directories = false;
+ struct Options cli_options;
+
for (int i = 0; i < options.size(); i++) {
if (options[i].first == "file_extension") {
- file_extension = options[i].second;
+ cli_options.file_extension = options[i].second;
} else if (options[i].first == "base_namespace") {
- base_namespace = options[i].second;
- generate_directories = true;
+ cli_options.base_namespace = options[i].second;
+ cli_options.base_namespace_specified = true;
+ } else if (options[i].first == "internal_access") {
+ cli_options.internal_access = true;
} else {
*error = "Unknown generator option: " + options[i].first;
return false;
@@ -87,7 +90,12 @@ bool Generator::Generate(
}
string filename_error = "";
- std::string filename = GetOutputFile(file, file_extension, generate_directories, base_namespace, &filename_error);
+ std::string filename = GetOutputFile(file,
+ cli_options.file_extension,
+ cli_options.base_namespace_specified,
+ cli_options.base_namespace,
+ &filename_error);
+
if (filename.empty()) {
*error = filename_error;
return false;
@@ -96,7 +104,7 @@ bool Generator::Generate(
generator_context->Open(filename));
io::Printer printer(output.get(), '$');
- GenerateFile(file, &printer);
+ GenerateFile(file, &printer, &cli_options);
return true;
}
diff --git a/src/google/protobuf/compiler/csharp/csharp_generator_unittest.cc b/src/google/protobuf/compiler/csharp/csharp_generator_unittest.cc
index 7ef7df42..5755fee0 100644
--- a/src/google/protobuf/compiler/csharp/csharp_generator_unittest.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_generator_unittest.cc
@@ -30,8 +30,8 @@
#include <memory>
-#include <google/protobuf/compiler/ruby/ruby_generator.h>
#include <google/protobuf/compiler/command_line_interface.h>
+#include <google/protobuf/compiler/csharp/csharp_helpers.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/io/printer.h>
@@ -45,7 +45,23 @@ namespace compiler {
namespace csharp {
namespace {
-// TODO(jtattermusch): add some tests.
+TEST(CSharpEnumValue, PascalCasedPrefixStripping) {
+ EXPECT_EQ("Bar", GetEnumValueName("Foo", "BAR"));
+ EXPECT_EQ("BarBaz", GetEnumValueName("Foo", "BAR_BAZ"));
+ EXPECT_EQ("Bar", GetEnumValueName("Foo", "FOO_BAR"));
+ EXPECT_EQ("Bar", GetEnumValueName("Foo", "FOO__BAR"));
+ EXPECT_EQ("BarBaz", GetEnumValueName("Foo", "FOO_BAR_BAZ"));
+ EXPECT_EQ("BarBaz", GetEnumValueName("Foo", "Foo_BarBaz"));
+ EXPECT_EQ("Bar", GetEnumValueName("FO_O", "FOO_BAR"));
+ EXPECT_EQ("Bar", GetEnumValueName("FOO", "F_O_O_BAR"));
+ EXPECT_EQ("Bar", GetEnumValueName("Foo", "BAR"));
+ EXPECT_EQ("BarBaz", GetEnumValueName("Foo", "BAR_BAZ"));
+ EXPECT_EQ("Foo", GetEnumValueName("Foo", "FOO"));
+ EXPECT_EQ("Foo", GetEnumValueName("Foo", "FOO___"));
+ // Identifiers can't start with digits
+ EXPECT_EQ("_2Bar", GetEnumValueName("Foo", "FOO_2_BAR"));
+ EXPECT_EQ("_2", GetEnumValueName("Foo", "FOO___2"));
+}
} // namespace
} // namespace csharp
diff --git a/src/google/protobuf/compiler/csharp/csharp_helpers.cc b/src/google/protobuf/compiler/csharp/csharp_helpers.cc
index c51fe44b..6c154c5a 100644
--- a/src/google/protobuf/compiler/csharp/csharp_helpers.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_helpers.cc
@@ -48,6 +48,7 @@
#include <google/protobuf/compiler/csharp/csharp_enum_field.h>
#include <google/protobuf/compiler/csharp/csharp_map_field.h>
#include <google/protobuf/compiler/csharp/csharp_message_field.h>
+#include <google/protobuf/compiler/csharp/csharp_options.h>
#include <google/protobuf/compiler/csharp/csharp_primitive_field.h>
#include <google/protobuf/compiler/csharp/csharp_repeated_enum_field.h>
#include <google/protobuf/compiler/csharp/csharp_repeated_message_field.h>
@@ -127,7 +128,8 @@ std::string GetFileNameBase(const FileDescriptor* descriptor) {
}
std::string GetReflectionClassUnqualifiedName(const FileDescriptor* descriptor) {
- // TODO: Detect collisions with existing messages, and append an underscore if necessary.
+ // TODO: Detect collisions with existing messages,
+ // and append an underscore if necessary.
return GetFileNameBase(descriptor) + "Reflection";
}
@@ -176,6 +178,104 @@ std::string UnderscoresToPascalCase(const std::string& input) {
return UnderscoresToCamelCase(input, true);
}
+// Convert a string which is expected to be SHOUTY_CASE (but may not be *precisely* shouty)
+// into a PascalCase string. Precise rules implemented:
+
+// Previous input character Current character Case
+// Any Non-alphanumeric Skipped
+// None - first char of input Alphanumeric Upper
+// Non-letter (e.g. _ or 1) Alphanumeric Upper
+// Numeric Alphanumeric Upper
+// Lower letter Alphanumeric Same as current
+// Upper letter Alphanumeric Lower
+std::string ShoutyToPascalCase(const std::string& input) {
+ string result;
+ // Simple way of implementing "always start with upper"
+ char previous = '_';
+ for (int i = 0; i < input.size(); i++) {
+ char current = input[i];
+ if (!ascii_isalnum(current)) {
+ previous = current;
+ continue;
+ }
+ if (!ascii_isalnum(previous)) {
+ result += ascii_toupper(current);
+ } else if (ascii_isdigit(previous)) {
+ result += ascii_toupper(current);
+ } else if (ascii_islower(previous)) {
+ result += current;
+ } else {
+ result += ascii_tolower(current);
+ }
+ previous = current;
+ }
+ return result;
+}
+
+// Attempt to remove a prefix from a value, ignoring casing and skipping underscores.
+// (foo, foo_bar) => bar - underscore after prefix is skipped
+// (FOO, foo_bar) => bar - casing is ignored
+// (foo_bar, foobarbaz) => baz - underscore in prefix is ignored
+// (foobar, foo_barbaz) => baz - underscore in value is ignored
+// (foo, bar) => bar - prefix isn't matched; return original value
+std::string TryRemovePrefix(const std::string& prefix, const std::string& value) {
+ // First normalize to a lower-case no-underscores prefix to match against
+ std::string prefix_to_match = "";
+ for (size_t i = 0; i < prefix.size(); i++) {
+ if (prefix[i] != '_') {
+ prefix_to_match += ascii_tolower(prefix[i]);
+ }
+ }
+
+ // This keeps track of how much of value we've consumed
+ size_t prefix_index, value_index;
+ for (prefix_index = 0, value_index = 0;
+ prefix_index < prefix_to_match.size() && value_index < value.size();
+ value_index++) {
+ // Skip over underscores in the value
+ if (value[value_index] == '_') {
+ continue;
+ }
+ if (ascii_tolower(value[value_index]) != prefix_to_match[prefix_index++]) {
+ // Failed to match the prefix - bail out early.
+ return value;
+ }
+ }
+
+ // If we didn't finish looking through the prefix, we can't strip it.
+ if (prefix_index < prefix_to_match.size()) {
+ return value;
+ }
+
+ // Step over any underscores after the prefix
+ while (value_index < value.size() && value[value_index] == '_') {
+ value_index++;
+ }
+
+ // If there's nothing left (e.g. it was a prefix with only underscores afterwards), don't strip.
+ if (value_index == value.size()) {
+ return value;
+ }
+
+ return value.substr(value_index);
+}
+
+// Format the enum value name in a pleasant way for C#:
+// - Strip the enum name as a prefix if possible
+// - Convert to PascalCase.
+// For example, an enum called Color with a value of COLOR_BLUE should
+// result in an enum value in C# called just Blue
+std::string GetEnumValueName(const std::string& enum_name, const std::string& enum_value_name) {
+ std::string stripped = TryRemovePrefix(enum_name, enum_value_name);
+ std::string result = ShoutyToPascalCase(stripped);
+ // Just in case we have an enum name of FOO and a value of FOO_2... make sure the returned
+ // string is a valid identifier.
+ if (ascii_isdigit(result[0])) {
+ result = "_" + result;
+ }
+ return result;
+}
+
std::string ToCSharpName(const std::string& name, const FileDescriptor* file) {
std::string result = GetFileNamespace(file);
if (result != "") {
@@ -351,49 +451,50 @@ std::string FileDescriptorToBase64(const FileDescriptor* descriptor) {
}
FieldGeneratorBase* CreateFieldGenerator(const FieldDescriptor* descriptor,
- int fieldOrdinal) {
+ int fieldOrdinal,
+ const Options* options) {
switch (descriptor->type()) {
case FieldDescriptor::TYPE_GROUP:
case FieldDescriptor::TYPE_MESSAGE:
if (descriptor->is_repeated()) {
if (descriptor->is_map()) {
- return new MapFieldGenerator(descriptor, fieldOrdinal);
+ return new MapFieldGenerator(descriptor, fieldOrdinal, options);
} else {
- return new RepeatedMessageFieldGenerator(descriptor, fieldOrdinal);
+ return new RepeatedMessageFieldGenerator(descriptor, fieldOrdinal, options);
}
} else {
if (IsWrapperType(descriptor)) {
if (descriptor->containing_oneof()) {
- return new WrapperOneofFieldGenerator(descriptor, fieldOrdinal);
+ return new WrapperOneofFieldGenerator(descriptor, fieldOrdinal, options);
} else {
- return new WrapperFieldGenerator(descriptor, fieldOrdinal);
+ return new WrapperFieldGenerator(descriptor, fieldOrdinal, options);
}
} else {
if (descriptor->containing_oneof()) {
- return new MessageOneofFieldGenerator(descriptor, fieldOrdinal);
+ return new MessageOneofFieldGenerator(descriptor, fieldOrdinal, options);
} else {
- return new MessageFieldGenerator(descriptor, fieldOrdinal);
+ return new MessageFieldGenerator(descriptor, fieldOrdinal, options);
}
}
}
case FieldDescriptor::TYPE_ENUM:
if (descriptor->is_repeated()) {
- return new RepeatedEnumFieldGenerator(descriptor, fieldOrdinal);
+ return new RepeatedEnumFieldGenerator(descriptor, fieldOrdinal, options);
} else {
if (descriptor->containing_oneof()) {
- return new EnumOneofFieldGenerator(descriptor, fieldOrdinal);
+ return new EnumOneofFieldGenerator(descriptor, fieldOrdinal, options);
} else {
- return new EnumFieldGenerator(descriptor, fieldOrdinal);
+ return new EnumFieldGenerator(descriptor, fieldOrdinal, options);
}
}
default:
if (descriptor->is_repeated()) {
- return new RepeatedPrimitiveFieldGenerator(descriptor, fieldOrdinal);
+ return new RepeatedPrimitiveFieldGenerator(descriptor, fieldOrdinal, options);
} else {
if (descriptor->containing_oneof()) {
- return new PrimitiveOneofFieldGenerator(descriptor, fieldOrdinal);
+ return new PrimitiveOneofFieldGenerator(descriptor, fieldOrdinal, options);
} else {
- return new PrimitiveFieldGenerator(descriptor, fieldOrdinal);
+ return new PrimitiveFieldGenerator(descriptor, fieldOrdinal, options);
}
}
}
diff --git a/src/google/protobuf/compiler/csharp/csharp_helpers.h b/src/google/protobuf/compiler/csharp/csharp_helpers.h
index e96e7938..1563ca7e 100644
--- a/src/google/protobuf/compiler/csharp/csharp_helpers.h
+++ b/src/google/protobuf/compiler/csharp/csharp_helpers.h
@@ -36,6 +36,7 @@
#define GOOGLE_PROTOBUF_COMPILER_CSHARP_HELPERS_H__
#include <string>
+#include <google/protobuf/stubs/port.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/compiler/code_generator.h>
@@ -46,6 +47,7 @@ namespace protobuf {
namespace compiler {
namespace csharp {
+struct Options;
class FieldGeneratorBase;
// TODO: start using this enum.
@@ -82,7 +84,9 @@ std::string GetPropertyName(const FieldDescriptor* descriptor);
int GetFixedSize(FieldDescriptor::Type type);
-std::string UnderscoresToCamelCase(const std::string& input, bool cap_next_letter, bool preserve_period);
+std::string UnderscoresToCamelCase(const std::string& input,
+ bool cap_next_letter,
+ bool preserve_period);
inline std::string UnderscoresToCamelCase(const std::string& input, bool cap_next_letter) {
return UnderscoresToCamelCase(input, cap_next_letter, false);
@@ -90,22 +94,28 @@ inline std::string UnderscoresToCamelCase(const std::string& input, bool cap_nex
std::string UnderscoresToPascalCase(const std::string& input);
+// Note that we wouldn't normally want to export this (we're not expecting
+// it to be used outside libprotoc itself) but this exposes it for testing.
+std::string LIBPROTOBUF_EXPORT GetEnumValueName(const std::string& enum_name, const std::string& enum_value_name);
+
// TODO(jtattermusch): perhaps we could move this to strutil
std::string StringToBase64(const std::string& input);
std::string FileDescriptorToBase64(const FileDescriptor* descriptor);
-FieldGeneratorBase* CreateFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal);
+FieldGeneratorBase* CreateFieldGenerator(const FieldDescriptor* descriptor,
+ int fieldOrdinal,
+ const Options* options);
-// Determines whether the given message is a map entry message, i.e. one implicitly created
-// by protoc due to a map<key, value> field.
+// Determines whether the given message is a map entry message,
+// i.e. one implicitly created by protoc due to a map<key, value> field.
inline bool IsMapEntryMessage(const Descriptor* descriptor) {
return descriptor->options().map_entry();
}
-// Determines whether we're generating code for the proto representation of descriptors etc,
-// for use in the runtime. This is the only type which is allowed to use proto2 syntax,
-// and it generates internal classes.
+// Determines whether we're generating code for the proto representation of
+// descriptors etc, for use in the runtime. This is the only type which is
+// allowed to use proto2 syntax, and it generates internal classes.
inline bool IsDescriptorProto(const FileDescriptor* descriptor) {
return descriptor->name() == "google/protobuf/descriptor.proto";
}
diff --git a/src/google/protobuf/compiler/csharp/csharp_map_field.cc b/src/google/protobuf/compiler/csharp/csharp_map_field.cc
index b493495d..e6eac6ed 100644
--- a/src/google/protobuf/compiler/csharp/csharp_map_field.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_map_field.cc
@@ -48,8 +48,9 @@ namespace compiler {
namespace csharp {
MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor,
- int fieldOrdinal)
- : FieldGeneratorBase(descriptor, fieldOrdinal) {
+ int fieldOrdinal,
+ const Options* options)
+ : FieldGeneratorBase(descriptor, fieldOrdinal, options) {
}
MapFieldGenerator::~MapFieldGenerator() {
@@ -62,9 +63,10 @@ void MapFieldGenerator::GenerateMembers(io::Printer* printer) {
descriptor_->message_type()->FindFieldByName("value");
variables_["key_type_name"] = type_name(key_descriptor);
variables_["value_type_name"] = type_name(value_descriptor);
- variables_["true_for_wrappers"] = IsWrapperType(value_descriptor) ? "true" : "";
- scoped_ptr<FieldGeneratorBase> key_generator(CreateFieldGenerator(key_descriptor, 1));
- scoped_ptr<FieldGeneratorBase> value_generator(CreateFieldGenerator(value_descriptor, 2));
+ scoped_ptr<FieldGeneratorBase> key_generator(
+ CreateFieldGenerator(key_descriptor, 1, this->options()));
+ scoped_ptr<FieldGeneratorBase> value_generator(
+ CreateFieldGenerator(value_descriptor, 2, this->options()));
printer->Print(
variables_,
@@ -76,9 +78,9 @@ void MapFieldGenerator::GenerateMembers(io::Printer* printer) {
printer->Print(
variables_,
", $tag$);\n"
- "private readonly pbc::MapField<$key_type_name$, $value_type_name$> $name$_ = new pbc::MapField<$key_type_name$, $value_type_name$>($true_for_wrappers$);\n");
+ "private readonly pbc::MapField<$key_type_name$, $value_type_name$> $name$_ = new pbc::MapField<$key_type_name$, $value_type_name$>();\n");
WritePropertyDocComment(printer, descriptor_);
- AddDeprecatedFlag(printer);
+ AddPublicMemberAttributes(printer);
printer->Print(
variables_,
"$access_level$ pbc::MapField<$key_type_name$, $value_type_name$> $property_name$ {\n"
diff --git a/src/google/protobuf/compiler/csharp/csharp_map_field.h b/src/google/protobuf/compiler/csharp/csharp_map_field.h
index f33fe1c3..84a33a03 100644
--- a/src/google/protobuf/compiler/csharp/csharp_map_field.h
+++ b/src/google/protobuf/compiler/csharp/csharp_map_field.h
@@ -43,7 +43,9 @@ namespace csharp {
class MapFieldGenerator : public FieldGeneratorBase {
public:
- MapFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal);
+ MapFieldGenerator(const FieldDescriptor* descriptor,
+ int fieldOrdinal,
+ const Options* options);
~MapFieldGenerator();
virtual void GenerateCloningCode(io::Printer* printer);
diff --git a/src/google/protobuf/compiler/csharp/csharp_message.cc b/src/google/protobuf/compiler/csharp/csharp_message.cc
index 9c72043b..ed744854 100644
--- a/src/google/protobuf/compiler/csharp/csharp_message.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_message.cc
@@ -60,8 +60,9 @@ bool CompareFieldNumbers(const FieldDescriptor* d1, const FieldDescriptor* d2) {
return d1->number() < d2->number();
}
-MessageGenerator::MessageGenerator(const Descriptor* descriptor)
- : SourceGeneratorBase(descriptor->file()),
+MessageGenerator::MessageGenerator(const Descriptor* descriptor,
+ const Options* options)
+ : SourceGeneratorBase(descriptor->file(), options),
descriptor_(descriptor) {
// sorted field names
@@ -104,18 +105,19 @@ void MessageGenerator::Generate(io::Printer* printer) {
WriteMessageDocComment(printer, descriptor_);
printer->Print(
- "[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]\n");
- WriteGeneratedCodeAttributes(printer);
- printer->Print(
vars,
"$access_level$ sealed partial class $class_name$ : pb::IMessage<$class_name$> {\n");
printer->Indent();
// All static fields and properties
printer->Print(
- vars,
- "private static readonly pb::MessageParser<$class_name$> _parser = new pb::MessageParser<$class_name$>(() => new $class_name$());\n"
- "public static pb::MessageParser<$class_name$> Parser { get { return _parser; } }\n\n");
+ vars,
+ "private static readonly pb::MessageParser<$class_name$> _parser = new pb::MessageParser<$class_name$>(() => new $class_name$());\n");
+
+ WriteGeneratedCodeAttributes(printer);
+ printer->Print(
+ vars,
+ "public static pb::MessageParser<$class_name$> Parser { get { return _parser; } }\n\n");
// Access the message descriptor via the relevant file descriptor or containing message descriptor.
if (!descriptor_->containing_type()) {
@@ -126,18 +128,23 @@ void MessageGenerator::Generate(io::Printer* printer) {
+ ".Descriptor.NestedTypes[" + SimpleItoa(descriptor_->index()) + "]";
}
+ WriteGeneratedCodeAttributes(printer);
printer->Print(
- vars,
- "public static pbr::MessageDescriptor Descriptor {\n"
- " get { return $descriptor_accessor$; }\n"
- "}\n"
- "\n"
+ vars,
+ "public static pbr::MessageDescriptor Descriptor {\n"
+ " get { return $descriptor_accessor$; }\n"
+ "}\n"
+ "\n");
+ WriteGeneratedCodeAttributes(printer);
+ printer->Print(
+ vars,
"pbr::MessageDescriptor pb::IMessage.Descriptor {\n"
" get { return Descriptor; }\n"
"}\n"
"\n");
// Parameterless constructor and partial OnConstruction method.
+ WriteGeneratedCodeAttributes(printer);
printer->Print(
vars,
"public $class_name$() {\n"
@@ -185,13 +192,20 @@ void MessageGenerator::Generate(io::Printer* printer) {
}
printer->Outdent();
printer->Print("}\n");
- // TODO: Should we put the oneof .proto comments here? It's unclear exactly where they should go.
- printer->Print(
- vars,
- "private $property_name$OneofCase $name$Case_ = $property_name$OneofCase.None;\n"
- "public $property_name$OneofCase $property_name$Case {\n"
- " get { return $name$Case_; }\n"
- "}\n\n"
+ // TODO: Should we put the oneof .proto comments here?
+ // It's unclear exactly where they should go.
+ printer->Print(
+ vars,
+ "private $property_name$OneofCase $name$Case_ = $property_name$OneofCase.None;\n");
+ WriteGeneratedCodeAttributes(printer);
+ printer->Print(
+ vars,
+ "public $property_name$OneofCase $property_name$Case {\n"
+ " get { return $name$Case_; }\n"
+ "}\n\n");
+ WriteGeneratedCodeAttributes(printer);
+ printer->Print(
+ vars,
"public void Clear$property_name$() {\n"
" $name$Case_ = $property_name$OneofCase.None;\n"
" $name$_ = null;\n"
@@ -208,19 +222,19 @@ void MessageGenerator::Generate(io::Printer* printer) {
printer->Print(
vars,
"#region Nested types\n"
- "/// <summary>Container for nested types declared in the $class_name$ message type.</summary>\n"
- "[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]\n");
+ "/// <summary>Container for nested types declared in the $class_name$ message type.</summary>\n");
WriteGeneratedCodeAttributes(printer);
printer->Print("public static partial class Types {\n");
printer->Indent();
for (int i = 0; i < descriptor_->enum_type_count(); i++) {
- EnumGenerator enumGenerator(descriptor_->enum_type(i));
+ EnumGenerator enumGenerator(descriptor_->enum_type(i), this->options());
enumGenerator.Generate(printer);
}
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
// Don't generate nested types for maps...
if (!IsMapEntryMessage(descriptor_->nested_type(i))) {
- MessageGenerator messageGenerator(descriptor_->nested_type(i));
+ MessageGenerator messageGenerator(
+ descriptor_->nested_type(i), this->options());
messageGenerator.Generate(printer);
}
}
@@ -252,6 +266,7 @@ bool MessageGenerator::HasNestedGeneratedTypes()
void MessageGenerator::GenerateCloningCode(io::Printer* printer) {
map<string, string> vars;
+ WriteGeneratedCodeAttributes(printer);
vars["class_name"] = class_name();
printer->Print(
vars,
@@ -268,7 +283,8 @@ void MessageGenerator::GenerateCloningCode(io::Printer* printer) {
// Clone just the right field for each oneof
for (int i = 0; i < descriptor_->oneof_decl_count(); ++i) {
vars["name"] = UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), false);
- vars["property_name"] = UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true);
+ vars["property_name"] = UnderscoresToCamelCase(
+ descriptor_->oneof_decl(i)->name(), true);
printer->Print(vars, "switch (other.$property_name$Case) {\n");
printer->Indent();
for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
@@ -290,6 +306,7 @@ void MessageGenerator::GenerateCloningCode(io::Printer* printer) {
printer->Outdent();
printer->Print("}\n\n");
+ WriteGeneratedCodeAttributes(printer);
printer->Print(
vars,
"public $class_name$ Clone() {\n"
@@ -305,11 +322,15 @@ void MessageGenerator::GenerateFrameworkMethods(io::Printer* printer) {
vars["class_name"] = class_name();
// Equality
+ WriteGeneratedCodeAttributes(printer);
printer->Print(
vars,
"public override bool Equals(object other) {\n"
" return Equals(other as $class_name$);\n"
- "}\n\n"
+ "}\n\n");
+ WriteGeneratedCodeAttributes(printer);
+ printer->Print(
+ vars,
"public bool Equals($class_name$ other) {\n"
" if (ReferenceEquals(other, null)) {\n"
" return false;\n"
@@ -334,7 +355,8 @@ void MessageGenerator::GenerateFrameworkMethods(io::Printer* printer) {
// GetHashCode
// Start with a non-zero value to easily distinguish between null and "empty" messages.
- printer->Print(
+ WriteGeneratedCodeAttributes(printer);
+ printer->Print(
"public override int GetHashCode() {\n"
" int hash = 1;\n");
printer->Indent();
@@ -351,13 +373,15 @@ void MessageGenerator::GenerateFrameworkMethods(io::Printer* printer) {
printer->Outdent();
printer->Print("}\n\n");
- printer->Print(
+ WriteGeneratedCodeAttributes(printer);
+ printer->Print(
"public override string ToString() {\n"
- " return pb::JsonFormatter.Default.Format(this);\n"
+ " return pb::JsonFormatter.ToDiagnosticString(this);\n"
"}\n\n");
}
void MessageGenerator::GenerateMessageSerializationMethods(io::Printer* printer) {
+ WriteGeneratedCodeAttributes(printer);
printer->Print(
"public void WriteTo(pb::CodedOutputStream output) {\n");
printer->Indent();
@@ -372,8 +396,10 @@ void MessageGenerator::GenerateMessageSerializationMethods(io::Printer* printer)
// TODO(jonskeet): Memoize size of frozen messages?
printer->Outdent();
printer->Print(
- "}\n"
- "\n"
+ "}\n"
+ "\n");
+ WriteGeneratedCodeAttributes(printer);
+ printer->Print(
"public int CalculateSize() {\n");
printer->Indent();
printer->Print("int size = 0;\n");
@@ -394,6 +420,7 @@ void MessageGenerator::GenerateMergingMethods(io::Printer* printer) {
map<string, string> vars;
vars["class_name"] = class_name();
+ WriteGeneratedCodeAttributes(printer);
printer->Print(
vars,
"public void MergeFrom($class_name$ other) {\n");
@@ -430,6 +457,7 @@ void MessageGenerator::GenerateMergingMethods(io::Printer* printer) {
}
printer->Outdent();
printer->Print("}\n\n");
+ WriteGeneratedCodeAttributes(printer);
printer->Print("public void MergeFrom(pb::CodedInputStream input) {\n");
printer->Indent();
printer->Print(
@@ -449,7 +477,8 @@ void MessageGenerator::GenerateMergingMethods(io::Printer* printer) {
uint32 tag = internal::WireFormatLite::MakeTag(field->number(), wt);
// Handle both packed and unpacked repeated fields with the same Read*Array call;
// the two generated cases are the packed and unpacked tags.
- // TODO(jonskeet): Check that is_packable is equivalent to is_repeated && wt in { VARINT, FIXED32, FIXED64 }.
+ // TODO(jonskeet): Check that is_packable is equivalent to
+ // is_repeated && wt in { VARINT, FIXED32, FIXED64 }.
// It looks like it is...
if (field->is_packable()) {
printer->Print(
@@ -490,7 +519,7 @@ int MessageGenerator::GetFieldOrdinal(const FieldDescriptor* descriptor) {
FieldGeneratorBase* MessageGenerator::CreateFieldGeneratorInternal(
const FieldDescriptor* descriptor) {
- return CreateFieldGenerator(descriptor, GetFieldOrdinal(descriptor));
+ return CreateFieldGenerator(descriptor, GetFieldOrdinal(descriptor), this->options());
}
} // namespace csharp
diff --git a/src/google/protobuf/compiler/csharp/csharp_message.h b/src/google/protobuf/compiler/csharp/csharp_message.h
index f0c49ac9..f794d68d 100644
--- a/src/google/protobuf/compiler/csharp/csharp_message.h
+++ b/src/google/protobuf/compiler/csharp/csharp_message.h
@@ -47,7 +47,7 @@ class FieldGeneratorBase;
class MessageGenerator : public SourceGeneratorBase {
public:
- MessageGenerator(const Descriptor* descriptor);
+ MessageGenerator(const Descriptor* descriptor, const Options* options);
~MessageGenerator();
void GenerateCloningCode(io::Printer* printer);
diff --git a/src/google/protobuf/compiler/csharp/csharp_message_field.cc b/src/google/protobuf/compiler/csharp/csharp_message_field.cc
index f81f769b..438f3102 100644
--- a/src/google/protobuf/compiler/csharp/csharp_message_field.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_message_field.cc
@@ -41,6 +41,7 @@
#include <google/protobuf/compiler/csharp/csharp_doc_comment.h>
#include <google/protobuf/compiler/csharp/csharp_helpers.h>
#include <google/protobuf/compiler/csharp/csharp_message_field.h>
+#include <google/protobuf/compiler/csharp/csharp_options.h>
namespace google {
namespace protobuf {
@@ -48,8 +49,9 @@ namespace compiler {
namespace csharp {
MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor,
- int fieldOrdinal)
- : FieldGeneratorBase(descriptor, fieldOrdinal) {
+ int fieldOrdinal,
+ const Options *options)
+ : FieldGeneratorBase(descriptor, fieldOrdinal, options) {
variables_["has_property_check"] = name() + "_ != null";
variables_["has_not_property_check"] = name() + "_ == null";
}
@@ -63,7 +65,7 @@ void MessageFieldGenerator::GenerateMembers(io::Printer* printer) {
variables_,
"private $type_name$ $name$_;\n");
WritePropertyDocComment(printer, descriptor_);
- AddDeprecatedFlag(printer);
+ AddPublicMemberAttributes(printer);
printer->Print(
variables_,
"$access_level$ $type_name$ $property_name$ {\n"
@@ -143,9 +145,11 @@ void MessageFieldGenerator::GenerateCodecCode(io::Printer* printer) {
"pb::FieldCodec.ForMessage($tag$, $type_name$.Parser)");
}
-MessageOneofFieldGenerator::MessageOneofFieldGenerator(const FieldDescriptor* descriptor,
- int fieldOrdinal)
- : MessageFieldGenerator(descriptor, fieldOrdinal) {
+MessageOneofFieldGenerator::MessageOneofFieldGenerator(
+ const FieldDescriptor* descriptor,
+ int fieldOrdinal,
+ const Options *options)
+ : MessageFieldGenerator(descriptor, fieldOrdinal, options) {
SetCommonOneofFieldVariables(&variables_);
}
@@ -155,7 +159,7 @@ MessageOneofFieldGenerator::~MessageOneofFieldGenerator() {
void MessageOneofFieldGenerator::GenerateMembers(io::Printer* printer) {
WritePropertyDocComment(printer, descriptor_);
- AddDeprecatedFlag(printer);
+ AddPublicMemberAttributes(printer);
printer->Print(
variables_,
"$access_level$ $type_name$ $property_name$ {\n"
diff --git a/src/google/protobuf/compiler/csharp/csharp_message_field.h b/src/google/protobuf/compiler/csharp/csharp_message_field.h
index dc6e4dc5..7d614756 100644
--- a/src/google/protobuf/compiler/csharp/csharp_message_field.h
+++ b/src/google/protobuf/compiler/csharp/csharp_message_field.h
@@ -43,7 +43,9 @@ namespace csharp {
class MessageFieldGenerator : public FieldGeneratorBase {
public:
- MessageFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal);
+ MessageFieldGenerator(const FieldDescriptor* descriptor,
+ int fieldOrdinal,
+ const Options *options);
~MessageFieldGenerator();
virtual void GenerateCodecCode(io::Printer* printer);
@@ -65,7 +67,9 @@ class MessageFieldGenerator : public FieldGeneratorBase {
class MessageOneofFieldGenerator : public MessageFieldGenerator {
public:
- MessageOneofFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal);
+ MessageOneofFieldGenerator(const FieldDescriptor* descriptor,
+ int fieldOrdinal,
+ const Options *options);
~MessageOneofFieldGenerator();
virtual void GenerateCloningCode(io::Printer* printer);
diff --git a/src/google/protobuf/compiler/csharp/csharp_options.h b/src/google/protobuf/compiler/csharp/csharp_options.h
new file mode 100644
index 00000000..426fb3b5
--- /dev/null
+++ b/src/google/protobuf/compiler/csharp/csharp_options.h
@@ -0,0 +1,79 @@
+// 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.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_OPTIONS_H__
+#define GOOGLE_PROTOBUF_COMPILER_CSHARP_OPTIONS_H__
+
+#include <string>
+
+#include <google/protobuf/stubs/common.h>
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace csharp {
+
+// Generator options (used by csharp_generator.cc):
+struct Options {
+ Options() :
+ file_extension(".cs"),
+ base_namespace(""),
+ base_namespace_specified(false),
+ internal_access(false) {
+ }
+ // Extension of the generated file. Defaults to ".cs"
+ string file_extension;
+ // Base namespace to use to create directory hierarchy. Defaults to "".
+ // This option allows the simple creation of a conventional C# file layout,
+ // where directories are created relative to a project-specific base
+ // namespace. For example, in a project with a base namespace of PetShop, a
+ // proto of user.proto with a C# namespace of PetShop.Model.Shared would
+ // generate Model/Shared/User.cs underneath the specified --csharp_out
+ // directory.
+ //
+ // If no base namespace is specified, all files are generated in the
+ // --csharp_out directory, with no subdirectories created automatically.
+ string base_namespace;
+ // Whether the base namespace has been explicitly specified by the user.
+ // This is required as the base namespace can be explicitly set to the empty
+ // string, meaning "create a full directory hierarchy, starting from the first
+ // segment of the namespace."
+ bool base_namespace_specified;
+ // Whether the generated classes should have accessibility level of "internal".
+ // Defaults to false that generates "public" classes.
+ bool internal_access;
+};
+
+} // namespace csharp
+} // namespace compiler
+} // namespace protobuf
+
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_OPTIONS_H__
diff --git a/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc b/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc
index 76d5b247..169122e6 100644
--- a/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc
@@ -40,6 +40,7 @@
#include <google/protobuf/compiler/csharp/csharp_doc_comment.h>
#include <google/protobuf/compiler/csharp/csharp_helpers.h>
+#include <google/protobuf/compiler/csharp/csharp_options.h>
#include <google/protobuf/compiler/csharp/csharp_primitive_field.h>
namespace google {
@@ -48,8 +49,8 @@ namespace compiler {
namespace csharp {
PrimitiveFieldGenerator::PrimitiveFieldGenerator(
- const FieldDescriptor* descriptor, int fieldOrdinal)
- : FieldGeneratorBase(descriptor, fieldOrdinal) {
+ const FieldDescriptor* descriptor, int fieldOrdinal, const Options *options)
+ : FieldGeneratorBase(descriptor, fieldOrdinal, options) {
// TODO(jonskeet): Make this cleaner...
is_value_type = descriptor->type() != FieldDescriptor::TYPE_STRING
&& descriptor->type() != FieldDescriptor::TYPE_BYTES;
@@ -70,7 +71,7 @@ void PrimitiveFieldGenerator::GenerateMembers(io::Printer* printer) {
variables_,
"private $type_name$ $name_def_message$;\n");
WritePropertyDocComment(printer, descriptor_);
- AddDeprecatedFlag(printer);
+ AddPublicMemberAttributes(printer);
printer->Print(
variables_,
"$access_level$ $type_name$ $property_name$ {\n"
@@ -83,7 +84,7 @@ void PrimitiveFieldGenerator::GenerateMembers(io::Printer* printer) {
} else {
printer->Print(
variables_,
- " $name$_ = pb::Preconditions.CheckNotNull(value, \"value\");\n");
+ " $name$_ = pb::ProtoPreconditions.CheckNotNull(value, \"value\");\n");
}
printer->Print(
" }\n"
@@ -163,8 +164,8 @@ void PrimitiveFieldGenerator::GenerateCodecCode(io::Printer* printer) {
}
PrimitiveOneofFieldGenerator::PrimitiveOneofFieldGenerator(
- const FieldDescriptor* descriptor, int fieldOrdinal)
- : PrimitiveFieldGenerator(descriptor, fieldOrdinal) {
+ const FieldDescriptor* descriptor, int fieldOrdinal, const Options *options)
+ : PrimitiveFieldGenerator(descriptor, fieldOrdinal, options) {
SetCommonOneofFieldVariables(&variables_);
}
@@ -173,7 +174,7 @@ PrimitiveOneofFieldGenerator::~PrimitiveOneofFieldGenerator() {
void PrimitiveOneofFieldGenerator::GenerateMembers(io::Printer* printer) {
WritePropertyDocComment(printer, descriptor_);
- AddDeprecatedFlag(printer);
+ AddPublicMemberAttributes(printer);
printer->Print(
variables_,
"$access_level$ $type_name$ $property_name$ {\n"
@@ -186,7 +187,7 @@ void PrimitiveOneofFieldGenerator::GenerateMembers(io::Printer* printer) {
} else {
printer->Print(
variables_,
- " $oneof_name$_ = pb::Preconditions.CheckNotNull(value, \"value\");\n");
+ " $oneof_name$_ = pb::ProtoPreconditions.CheckNotNull(value, \"value\");\n");
}
printer->Print(
variables_,
diff --git a/src/google/protobuf/compiler/csharp/csharp_primitive_field.h b/src/google/protobuf/compiler/csharp/csharp_primitive_field.h
index 8b87ebc4..5f466fc4 100644
--- a/src/google/protobuf/compiler/csharp/csharp_primitive_field.h
+++ b/src/google/protobuf/compiler/csharp/csharp_primitive_field.h
@@ -41,9 +41,13 @@ namespace protobuf {
namespace compiler {
namespace csharp {
+struct Options;
+
class PrimitiveFieldGenerator : public FieldGeneratorBase {
public:
- PrimitiveFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal);
+ PrimitiveFieldGenerator(const FieldDescriptor* descriptor,
+ int fieldOrdinal,
+ const Options *options);
~PrimitiveFieldGenerator();
virtual void GenerateCodecCode(io::Printer* printer);
@@ -67,7 +71,9 @@ class PrimitiveFieldGenerator : public FieldGeneratorBase {
class PrimitiveOneofFieldGenerator : public PrimitiveFieldGenerator {
public:
- PrimitiveOneofFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal);
+ PrimitiveOneofFieldGenerator(const FieldDescriptor* descriptor,
+ int fieldOrdinal,
+ const Options *options);
~PrimitiveOneofFieldGenerator();
virtual void GenerateCloningCode(io::Printer* printer);
diff --git a/src/google/protobuf/compiler/csharp/csharp_reflection_class.cc b/src/google/protobuf/compiler/csharp/csharp_reflection_class.cc
index 3862f001..bac9aef7 100644
--- a/src/google/protobuf/compiler/csharp/csharp_reflection_class.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_reflection_class.cc
@@ -43,6 +43,7 @@
#include <google/protobuf/compiler/csharp/csharp_helpers.h>
#include <google/protobuf/compiler/csharp/csharp_message.h>
#include <google/protobuf/compiler/csharp/csharp_names.h>
+#include <google/protobuf/compiler/csharp/csharp_options.h>
#include <google/protobuf/compiler/csharp/csharp_reflection_class.h>
namespace google {
@@ -50,8 +51,9 @@ namespace protobuf {
namespace compiler {
namespace csharp {
-ReflectionClassGenerator::ReflectionClassGenerator(const FileDescriptor* file)
- : SourceGeneratorBase(file),
+ReflectionClassGenerator::ReflectionClassGenerator(const FileDescriptor* file,
+ const Options* options)
+ : SourceGeneratorBase(file, options),
file_(file) {
namespace_ = GetFileNamespace(file);
reflectionClassname_ = GetReflectionClassUnqualifiedName(file);
@@ -72,7 +74,7 @@ void ReflectionClassGenerator::Generate(io::Printer* printer) {
if (file_->enum_type_count() > 0) {
printer->Print("#region Enums\n");
for (int i = 0; i < file_->enum_type_count(); i++) {
- EnumGenerator enumGenerator(file_->enum_type(i));
+ EnumGenerator enumGenerator(file_->enum_type(i), this->options());
enumGenerator.Generate(printer);
}
printer->Print("#endregion\n");
@@ -83,7 +85,7 @@ void ReflectionClassGenerator::Generate(io::Printer* printer) {
if (file_->message_type_count() > 0) {
printer->Print("#region Messages\n");
for (int i = 0; i < file_->message_type_count(); i++) {
- MessageGenerator messageGenerator(file_->message_type(i));
+ MessageGenerator messageGenerator(file_->message_type(i), this->options());
messageGenerator.Generate(printer);
}
printer->Print("#endregion\n");
@@ -121,12 +123,9 @@ void ReflectionClassGenerator::WriteIntroduction(io::Printer* printer) {
printer->Print(
"/// <summary>Holder for reflection information generated from $file_name$</summary>\n"
- "[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]\n",
- "file_name", file_->name());
- WriteGeneratedCodeAttributes(printer);
- printer->Print(
"$access_level$ static partial class $reflection_class_name$ {\n"
"\n",
+ "file_name", file_->name(),
"access_level", class_access_level(),
"reflection_class_name", reflectionClassname_);
printer->Indent();
@@ -182,7 +181,7 @@ void ReflectionClassGenerator::WriteDescriptor(io::Printer* printer) {
}
}
printer->Print("},\n"
- " new pbr::GeneratedCodeInfo(");
+ " new pbr::GeneratedClrTypeInfo(");
// Specify all the generated code information, recursively.
if (file_->enum_type_count() > 0) {
printer->Print("new[] {");
@@ -195,7 +194,7 @@ void ReflectionClassGenerator::WriteDescriptor(io::Printer* printer) {
printer->Print("null, ");
}
if (file_->message_type_count() > 0) {
- printer->Print("new pbr::GeneratedCodeInfo[] {\n");
+ printer->Print("new pbr::GeneratedClrTypeInfo[] {\n");
printer->Indent();
printer->Indent();
printer->Indent();
@@ -232,7 +231,7 @@ void ReflectionClassGenerator::WriteGeneratedCodeInfo(const Descriptor* descript
return;
}
// Generated message type
- printer->Print("new pbr::GeneratedCodeInfo(typeof($type_name$), $type_name$.Parser, ", "type_name", GetClassName(descriptor));
+ printer->Print("new pbr::GeneratedClrTypeInfo(typeof($type_name$), $type_name$.Parser, ", "type_name", GetClassName(descriptor));
// Fields
if (descriptor->field_count() > 0) {
@@ -273,7 +272,7 @@ void ReflectionClassGenerator::WriteGeneratedCodeInfo(const Descriptor* descript
// Nested types
if (descriptor->nested_type_count() > 0) {
// Need to specify array type explicitly here, as all elements may be null.
- printer->Print("new pbr::GeneratedCodeInfo[] { ");
+ printer->Print("new pbr::GeneratedClrTypeInfo[] { ");
for (int i = 0; i < descriptor->nested_type_count(); i++) {
WriteGeneratedCodeInfo(descriptor->nested_type(i), printer, i == descriptor->nested_type_count() - 1);
}
diff --git a/src/google/protobuf/compiler/csharp/csharp_reflection_class.h b/src/google/protobuf/compiler/csharp/csharp_reflection_class.h
index 0a5b8ed5..e0c69f31 100644
--- a/src/google/protobuf/compiler/csharp/csharp_reflection_class.h
+++ b/src/google/protobuf/compiler/csharp/csharp_reflection_class.h
@@ -43,7 +43,7 @@ namespace csharp {
class ReflectionClassGenerator : public SourceGeneratorBase {
public:
- ReflectionClassGenerator(const FileDescriptor* file);
+ ReflectionClassGenerator(const FileDescriptor* file, const Options* options);
~ReflectionClassGenerator();
void Generate(io::Printer* printer);
@@ -56,7 +56,9 @@ class ReflectionClassGenerator : public SourceGeneratorBase {
void WriteIntroduction(io::Printer* printer);
void WriteDescriptor(io::Printer* printer);
- void WriteGeneratedCodeInfo(const Descriptor* descriptor, io::Printer* printer, bool last);
+ void WriteGeneratedCodeInfo(const Descriptor* descriptor,
+ io::Printer* printer,
+ bool last);
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ReflectionClassGenerator);
};
diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc b/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc
index 3a11b75d..683c4b0b 100644
--- a/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc
@@ -48,8 +48,8 @@ namespace compiler {
namespace csharp {
RepeatedEnumFieldGenerator::RepeatedEnumFieldGenerator(
- const FieldDescriptor* descriptor, int fieldOrdinal)
- : FieldGeneratorBase(descriptor, fieldOrdinal) {
+ const FieldDescriptor* descriptor, int fieldOrdinal, const Options *options)
+ : FieldGeneratorBase(descriptor, fieldOrdinal, options) {
}
RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() {
@@ -64,7 +64,7 @@ void RepeatedEnumFieldGenerator::GenerateMembers(io::Printer* printer) {
printer->Print(variables_,
"private readonly pbc::RepeatedField<$type_name$> $name$_ = new pbc::RepeatedField<$type_name$>();\n");
WritePropertyDocComment(printer, descriptor_);
- AddDeprecatedFlag(printer);
+ AddPublicMemberAttributes(printer);
printer->Print(
variables_,
"$access_level$ pbc::RepeatedField<$type_name$> $property_name$ {\n"
diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.h b/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.h
index ee50eef0..819b5832 100644
--- a/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.h
+++ b/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.h
@@ -45,7 +45,9 @@ namespace csharp {
// should probably have a RepeatedFieldGeneratorBase.
class RepeatedEnumFieldGenerator : public FieldGeneratorBase {
public:
- RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal);
+ RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor,
+ int fieldOrdinal,
+ const Options *options);
~RepeatedEnumFieldGenerator();
virtual void GenerateCloningCode(io::Printer* printer);
diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc b/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc
index fc12faed..8fa0b050 100644
--- a/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc
@@ -49,8 +49,8 @@ namespace compiler {
namespace csharp {
RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator(
- const FieldDescriptor* descriptor, int fieldOrdinal)
- : FieldGeneratorBase(descriptor, fieldOrdinal) {
+ const FieldDescriptor* descriptor, int fieldOrdinal, const Options *options)
+ : FieldGeneratorBase(descriptor, fieldOrdinal, options) {
}
RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {
@@ -66,10 +66,12 @@ void RepeatedMessageFieldGenerator::GenerateMembers(io::Printer* printer) {
// "create single field generator for this repeated field"
// function, but it doesn't seem worth it for just this.
if (IsWrapperType(descriptor_)) {
- scoped_ptr<FieldGeneratorBase> single_generator(new WrapperFieldGenerator(descriptor_, fieldOrdinal_));
+ scoped_ptr<FieldGeneratorBase> single_generator(
+ new WrapperFieldGenerator(descriptor_, fieldOrdinal_, this->options()));
single_generator->GenerateCodecCode(printer);
} else {
- scoped_ptr<FieldGeneratorBase> single_generator(new MessageFieldGenerator(descriptor_, fieldOrdinal_));
+ scoped_ptr<FieldGeneratorBase> single_generator(
+ new MessageFieldGenerator(descriptor_, fieldOrdinal_, this->options()));
single_generator->GenerateCodecCode(printer);
}
printer->Print(";\n");
@@ -77,7 +79,7 @@ void RepeatedMessageFieldGenerator::GenerateMembers(io::Printer* printer) {
variables_,
"private readonly pbc::RepeatedField<$type_name$> $name$_ = new pbc::RepeatedField<$type_name$>();\n");
WritePropertyDocComment(printer, descriptor_);
- AddDeprecatedFlag(printer);
+ AddPublicMemberAttributes(printer);
printer->Print(
variables_,
"$access_level$ pbc::RepeatedField<$type_name$> $property_name$ {\n"
diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.h b/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.h
index cf601c7e..6e33648b 100644
--- a/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.h
+++ b/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.h
@@ -41,9 +41,13 @@ namespace protobuf {
namespace compiler {
namespace csharp {
+struct Options;
+
class RepeatedMessageFieldGenerator : public FieldGeneratorBase {
public:
- RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal);
+ RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor,
+ int fieldOrdinal,
+ const Options *options);
~RepeatedMessageFieldGenerator();
virtual void GenerateCloningCode(io::Printer* printer);
diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc b/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc
index 5fe0b203..cd91506f 100644
--- a/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc
@@ -48,8 +48,8 @@ namespace compiler {
namespace csharp {
RepeatedPrimitiveFieldGenerator::RepeatedPrimitiveFieldGenerator(
- const FieldDescriptor* descriptor, int fieldOrdinal)
- : FieldGeneratorBase(descriptor, fieldOrdinal) {
+ const FieldDescriptor* descriptor, int fieldOrdinal, const Options *options)
+ : FieldGeneratorBase(descriptor, fieldOrdinal, options) {
}
RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {
@@ -64,7 +64,7 @@ void RepeatedPrimitiveFieldGenerator::GenerateMembers(io::Printer* printer) {
printer->Print(variables_,
"private readonly pbc::RepeatedField<$type_name$> $name$_ = new pbc::RepeatedField<$type_name$>();\n");
WritePropertyDocComment(printer, descriptor_);
- AddDeprecatedFlag(printer);
+ AddPublicMemberAttributes(printer);
printer->Print(
variables_,
"$access_level$ pbc::RepeatedField<$type_name$> $property_name$ {\n"
diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h b/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h
index f1ceeb50..a59348a9 100644
--- a/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h
+++ b/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h
@@ -43,7 +43,7 @@ namespace csharp {
class RepeatedPrimitiveFieldGenerator : public FieldGeneratorBase {
public:
- RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal);
+ RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal, const Options *options);
~RepeatedPrimitiveFieldGenerator();
virtual void GenerateCloningCode(io::Printer* printer);
diff --git a/src/google/protobuf/compiler/csharp/csharp_source_generator_base.cc b/src/google/protobuf/compiler/csharp/csharp_source_generator_base.cc
index 735d164a..1fda7ddf 100644
--- a/src/google/protobuf/compiler/csharp/csharp_source_generator_base.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_source_generator_base.cc
@@ -39,25 +39,32 @@
#include <google/protobuf/compiler/csharp/csharp_source_generator_base.h>
#include <google/protobuf/compiler/csharp/csharp_helpers.h>
+#include <google/protobuf/compiler/csharp/csharp_names.h>
+#include <google/protobuf/compiler/csharp/csharp_options.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace csharp {
-SourceGeneratorBase::SourceGeneratorBase(const FileDescriptor* descriptor)
- : descriptor_(descriptor) {
+SourceGeneratorBase::SourceGeneratorBase(const FileDescriptor* descriptor,
+ const Options *options)
+ : descriptor_(descriptor), options_(options) {
}
SourceGeneratorBase::~SourceGeneratorBase() {
}
void SourceGeneratorBase::WriteGeneratedCodeAttributes(io::Printer* printer) {
- // This hook can be used to reintroduce generated code attributes in the future.
+ printer->Print("[global::System.Diagnostics.DebuggerNonUserCodeAttribute]\n");
}
std::string SourceGeneratorBase::class_access_level() {
- return IsDescriptorProto(descriptor_) ? "internal" : "public"; // public_classes is always on.
+ return (IsDescriptorProto(descriptor_) || this->options()->internal_access) ? "internal" : "public";
+}
+
+const Options* SourceGeneratorBase::options() {
+ return this->options_;
}
} // namespace csharp
diff --git a/src/google/protobuf/compiler/csharp/csharp_source_generator_base.h b/src/google/protobuf/compiler/csharp/csharp_source_generator_base.h
index 6caef171..c741080e 100644
--- a/src/google/protobuf/compiler/csharp/csharp_source_generator_base.h
+++ b/src/google/protobuf/compiler/csharp/csharp_source_generator_base.h
@@ -40,17 +40,23 @@ namespace protobuf {
namespace compiler {
namespace csharp {
+struct Options;
+
class SourceGeneratorBase {
protected:
- SourceGeneratorBase(const FileDescriptor* descriptor);
+ SourceGeneratorBase(const FileDescriptor* descriptor, const Options* options);
virtual ~SourceGeneratorBase();
std::string class_access_level();
+ const Options* options();
+ // Write any attributes used to decorate generated function members (methods and properties).
+ // Should not be used to decorate types.
void WriteGeneratedCodeAttributes(io::Printer* printer);
private:
const FileDescriptor* descriptor_;
+ const Options *options_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SourceGeneratorBase);
};
diff --git a/src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc b/src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc
index 6a3750e0..797d498e 100644
--- a/src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc
@@ -39,6 +39,7 @@
#include <google/protobuf/compiler/csharp/csharp_doc_comment.h>
#include <google/protobuf/compiler/csharp/csharp_helpers.h>
+#include <google/protobuf/compiler/csharp/csharp_options.h>
#include <google/protobuf/compiler/csharp/csharp_wrapper_field.h>
namespace google {
@@ -47,8 +48,8 @@ namespace compiler {
namespace csharp {
WrapperFieldGenerator::WrapperFieldGenerator(const FieldDescriptor* descriptor,
- int fieldOrdinal)
- : FieldGeneratorBase(descriptor, fieldOrdinal) {
+ int fieldOrdinal, const Options *options)
+ : FieldGeneratorBase(descriptor, fieldOrdinal, options) {
variables_["has_property_check"] = name() + "_ != null";
variables_["has_not_property_check"] = name() + "_ == null";
const FieldDescriptor* wrapped_field = descriptor->message_type()->field(0);
@@ -72,7 +73,7 @@ void WrapperFieldGenerator::GenerateMembers(io::Printer* printer) {
";\n"
"private $type_name$ $name$_;\n");
WritePropertyDocComment(printer, descriptor_);
- AddDeprecatedFlag(printer);
+ AddPublicMemberAttributes(printer);
printer->Print(
variables_,
"$access_level$ $type_name$ $property_name$ {\n"
@@ -151,9 +152,9 @@ void WrapperFieldGenerator::GenerateCodecCode(io::Printer* printer) {
}
}
-WrapperOneofFieldGenerator::WrapperOneofFieldGenerator(const FieldDescriptor* descriptor,
- int fieldOrdinal)
- : WrapperFieldGenerator(descriptor, fieldOrdinal) {
+WrapperOneofFieldGenerator::WrapperOneofFieldGenerator(
+ const FieldDescriptor* descriptor, int fieldOrdinal, const Options *options)
+ : WrapperFieldGenerator(descriptor, fieldOrdinal, options) {
SetCommonOneofFieldVariables(&variables_);
}
@@ -168,7 +169,7 @@ void WrapperOneofFieldGenerator::GenerateMembers(io::Printer* printer) {
GenerateCodecCode(printer);
printer->Print(";\n");
WritePropertyDocComment(printer, descriptor_);
- AddDeprecatedFlag(printer);
+ AddPublicMemberAttributes(printer);
printer->Print(
variables_,
"$access_level$ $type_name$ $property_name$ {\n"
diff --git a/src/google/protobuf/compiler/csharp/csharp_wrapper_field.h b/src/google/protobuf/compiler/csharp/csharp_wrapper_field.h
index 6e2414af..250dfd25 100644
--- a/src/google/protobuf/compiler/csharp/csharp_wrapper_field.h
+++ b/src/google/protobuf/compiler/csharp/csharp_wrapper_field.h
@@ -41,9 +41,13 @@ namespace protobuf {
namespace compiler {
namespace csharp {
+struct Options;
+
class WrapperFieldGenerator : public FieldGeneratorBase {
public:
- WrapperFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal);
+ WrapperFieldGenerator(const FieldDescriptor* descriptor,
+ int fieldOrdinal,
+ const Options *options);
~WrapperFieldGenerator();
virtual void GenerateCodecCode(io::Printer* printer);
@@ -65,7 +69,9 @@ class WrapperFieldGenerator : public FieldGeneratorBase {
class WrapperOneofFieldGenerator : public WrapperFieldGenerator {
public:
- WrapperOneofFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal);
+ WrapperOneofFieldGenerator(const FieldDescriptor* descriptor,
+ int fieldOrdinal,
+ const Options *options);
~WrapperOneofFieldGenerator();
virtual void GenerateMembers(io::Printer* printer);
diff --git a/src/google/protobuf/compiler/importer.cc b/src/google/protobuf/compiler/importer.cc
index 8333684e..0d9093c0 100644
--- a/src/google/protobuf/compiler/importer.cc
+++ b/src/google/protobuf/compiler/importer.cc
@@ -185,6 +185,19 @@ void SourceTreeDescriptorDatabase::ValidationErrorCollector::AddError(
owner_->error_collector_->AddError(filename, line, column, message);
}
+void SourceTreeDescriptorDatabase::ValidationErrorCollector::AddWarning(
+ const string& filename,
+ const string& element_name,
+ const Message* descriptor,
+ ErrorLocation location,
+ const string& message) {
+ if (owner_->error_collector_ == NULL) return;
+
+ int line, column;
+ owner_->source_locations_.Find(descriptor, location, &line, &column);
+ owner_->error_collector_->AddWarning(filename, line, column, message);
+}
+
// ===================================================================
Importer::Importer(SourceTree* source_tree,
diff --git a/src/google/protobuf/compiler/importer.h b/src/google/protobuf/compiler/importer.h
index f010fd08..cc8fcc39 100644
--- a/src/google/protobuf/compiler/importer.h
+++ b/src/google/protobuf/compiler/importer.h
@@ -121,6 +121,12 @@ class LIBPROTOBUF_EXPORT SourceTreeDescriptorDatabase : public DescriptorDatabas
ErrorLocation location,
const string& message);
+ virtual void AddWarning(const string& filename,
+ const string& element_name,
+ const Message* descriptor,
+ ErrorLocation location,
+ const string& message);
+
private:
SourceTreeDescriptorDatabase* owner_;
};
@@ -188,6 +194,9 @@ class LIBPROTOBUF_EXPORT MultiFileErrorCollector {
virtual void AddError(const string& filename, int line, int column,
const string& message) = 0;
+ virtual void AddWarning(const string& filename, int line, int column,
+ const string& message) {}
+
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MultiFileErrorCollector);
};
diff --git a/src/google/protobuf/compiler/importer_unittest.cc b/src/google/protobuf/compiler/importer_unittest.cc
index 33c9328f..1b6e9700 100644
--- a/src/google/protobuf/compiler/importer_unittest.cc
+++ b/src/google/protobuf/compiler/importer_unittest.cc
@@ -32,25 +32,26 @@
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
+#include <google/protobuf/compiler/importer.h>
+
#include <google/protobuf/stubs/hash.h>
#include <memory>
#ifndef _SHARED_PTR_H
#include <google/protobuf/stubs/shared_ptr.h>
#endif
-#include <google/protobuf/compiler/importer.h>
-#include <google/protobuf/descriptor.h>
-#include <google/protobuf/testing/file.h>
-#include <google/protobuf/io/zero_copy_stream_impl.h>
-
-#include <google/protobuf/stubs/map_util.h>
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/testing/file.h>
+#include <google/protobuf/testing/file.h>
+#include <google/protobuf/testing/file.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/descriptor.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/substitute.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
+#include <google/protobuf/stubs/map_util.h>
namespace google {
namespace protobuf {
@@ -71,6 +72,7 @@ class MockErrorCollector : public MultiFileErrorCollector {
~MockErrorCollector() {}
string text_;
+ string warning_text_;
// implements ErrorCollector ---------------------------------------
void AddError(const string& filename, int line, int column,
@@ -78,6 +80,12 @@ class MockErrorCollector : public MultiFileErrorCollector {
strings::SubstituteAndAppend(&text_, "$0:$1:$2: $3\n",
filename, line, column, message);
}
+
+ void AddWarning(const string& filename, int line, int column,
+ const string& message) {
+ strings::SubstituteAndAppend(&warning_text_, "$0:$1:$2: $3\n",
+ filename, line, column, message);
+ }
};
// -------------------------------------------------------------------
@@ -123,6 +131,7 @@ class ImporterTest : public testing::Test {
// Return the collected error text
string error() const { return error_collector_.text_; }
+ string warning() const { return error_collector_.warning_text_; }
MockErrorCollector error_collector_;
MockSourceTree source_tree_;
diff --git a/src/google/protobuf/compiler/java/java_context.cc b/src/google/protobuf/compiler/java/java_context.cc
index 7d21fe61..6cfa14a0 100644
--- a/src/google/protobuf/compiler/java/java_context.cc
+++ b/src/google/protobuf/compiler/java/java_context.cc
@@ -42,8 +42,8 @@ namespace protobuf {
namespace compiler {
namespace java {
-Context::Context(const FileDescriptor* file)
- : name_resolver_(new ClassNameResolver) {
+Context::Context(const FileDescriptor* file, const Options& options)
+ : name_resolver_(new ClassNameResolver), options_(options) {
InitializeFieldGeneratorInfo(file);
}
@@ -189,6 +189,13 @@ const OneofGeneratorInfo* Context::GetOneofGeneratorInfo(
return result;
}
+// Does this message class have generated parsing, serialization, and other
+// standard methods for which reflection-based fallback implementations exist?
+bool Context::HasGeneratedMethods(const Descriptor* descriptor) const {
+ return options_.enforce_lite ||
+ descriptor->file()->options().optimize_for() != FileOptions::CODE_SIZE;
+}
+
} // namespace java
} // namespace compiler
} // namespace protobuf
diff --git a/src/google/protobuf/compiler/java/java_context.h b/src/google/protobuf/compiler/java/java_context.h
index 5b595d07..f92ae87e 100644
--- a/src/google/protobuf/compiler/java/java_context.h
+++ b/src/google/protobuf/compiler/java/java_context.h
@@ -39,6 +39,7 @@
#include <vector>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/compiler/java/java_options.h>
namespace google {
namespace protobuf {
@@ -46,6 +47,7 @@ namespace protobuf {
class FieldDescriptor;
class OneofDescriptor;
class Descriptor;
+ class EnumDescriptor;
namespace compiler {
namespace java {
class ClassNameResolver; // name_resolver.h
@@ -63,7 +65,7 @@ struct OneofGeneratorInfo;
// generators.
class Context {
public:
- explicit Context(const FileDescriptor* file);
+ Context(const FileDescriptor* file, const Options& options);
~Context();
// Get the name resolver associated with this context. The resolver
@@ -78,6 +80,17 @@ class Context {
const OneofGeneratorInfo* GetOneofGeneratorInfo(
const OneofDescriptor* oneof) const;
+ const Options& options() const { return options_; }
+
+ // Enforces all the files (including transitive dependencies) to use
+ // LiteRuntime.
+
+ bool EnforceLite() const { return options_.enforce_lite; }
+
+ // Does this message class have generated parsing, serialization, and other
+ // standard methods for which reflection-based fallback implementations exist?
+ bool HasGeneratedMethods(const Descriptor* descriptor) const;
+
private:
void InitializeFieldGeneratorInfo(const FileDescriptor* file);
void InitializeFieldGeneratorInfoForMessage(const Descriptor* message);
@@ -87,6 +100,7 @@ class Context {
google::protobuf::scoped_ptr<ClassNameResolver> name_resolver_;
map<const FieldDescriptor*, FieldGeneratorInfo> field_generator_info_map_;
map<const OneofDescriptor*, OneofGeneratorInfo> oneof_generator_info_map_;
+ Options options_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Context);
};
diff --git a/src/google/protobuf/compiler/java/java_doc_comment.cc b/src/google/protobuf/compiler/java/java_doc_comment.cc
index 663f0c97..0b5caba4 100644
--- a/src/google/protobuf/compiler/java/java_doc_comment.cc
+++ b/src/google/protobuf/compiler/java/java_doc_comment.cc
@@ -120,9 +120,7 @@ static void WriteDocCommentBodyForLocation(
lines.pop_back();
}
- printer->Print(
- " *\n"
- " * <pre>\n");
+ printer->Print(" * <pre>\n");
for (int i = 0; i < lines.size(); i++) {
// Most lines should start with a space. Watch out for lines that start
// with a /, since putting that right after the leading asterisk will
@@ -133,7 +131,9 @@ static void WriteDocCommentBodyForLocation(
printer->Print(" *$line$\n", "line", lines[i]);
}
}
- printer->Print(" * </pre>\n");
+ printer->Print(
+ " * </pre>\n"
+ " *\n");
}
}
@@ -163,12 +163,12 @@ static string FirstLineOf(const string& value) {
}
void WriteMessageDocComment(io::Printer* printer, const Descriptor* message) {
+ printer->Print("/**\n");
+ WriteDocCommentBody(printer, message);
printer->Print(
- "/**\n"
- " * Protobuf type {@code $fullname$}\n",
+ " * Protobuf type {@code $fullname$}\n"
+ " */\n",
"fullname", EscapeJavadoc(message->full_name()));
- WriteDocCommentBody(printer, message);
- printer->Print(" */\n");
}
void WriteFieldDocComment(io::Printer* printer, const FieldDescriptor* field) {
@@ -176,55 +176,55 @@ void WriteFieldDocComment(io::Printer* printer, const FieldDescriptor* field) {
// etc., but in practice everyone already knows the difference between these
// so it's redundant information.
- // We use the field declaration as the first line of the comment, e.g.:
+ // We start the comment with the main body based on the comments from the
+ // .proto file (if present). We then end with the field declaration, e.g.:
// optional string foo = 5;
- // This communicates a lot of information about the field in a small space.
// If the field is a group, the debug string might end with {.
+ printer->Print("/**\n");
+ WriteDocCommentBody(printer, field);
printer->Print(
- "/**\n"
" * <code>$def$</code>\n",
"def", EscapeJavadoc(FirstLineOf(field->DebugString())));
- WriteDocCommentBody(printer, field);
printer->Print(" */\n");
}
void WriteEnumDocComment(io::Printer* printer, const EnumDescriptor* enum_) {
+ printer->Print("/**\n");
+ WriteDocCommentBody(printer, enum_);
printer->Print(
- "/**\n"
- " * Protobuf enum {@code $fullname$}\n",
+ " * Protobuf enum {@code $fullname$}\n"
+ " */\n",
"fullname", EscapeJavadoc(enum_->full_name()));
- WriteDocCommentBody(printer, enum_);
- printer->Print(" */\n");
}
void WriteEnumValueDocComment(io::Printer* printer,
const EnumValueDescriptor* value) {
+ printer->Print("/**\n");
+ WriteDocCommentBody(printer, value);
printer->Print(
- "/**\n"
- " * <code>$def$</code>\n",
+ " * <code>$def$</code>\n"
+ " */\n",
"def", EscapeJavadoc(FirstLineOf(value->DebugString())));
- WriteDocCommentBody(printer, value);
- printer->Print(" */\n");
}
void WriteServiceDocComment(io::Printer* printer,
const ServiceDescriptor* service) {
+ printer->Print("/**\n");
+ WriteDocCommentBody(printer, service);
printer->Print(
- "/**\n"
- " * Protobuf service {@code $fullname$}\n",
+ " * Protobuf service {@code $fullname$}\n"
+ " */\n",
"fullname", EscapeJavadoc(service->full_name()));
- WriteDocCommentBody(printer, service);
- printer->Print(" */\n");
}
void WriteMethodDocComment(io::Printer* printer,
const MethodDescriptor* method) {
+ printer->Print("/**\n");
+ WriteDocCommentBody(printer, method);
printer->Print(
- "/**\n"
- " * <code>$def$</code>\n",
+ " * <code>$def$</code>\n"
+ " */\n",
"def", EscapeJavadoc(FirstLineOf(method->DebugString())));
- WriteDocCommentBody(printer, method);
- printer->Print(" */\n");
}
} // namespace java
diff --git a/src/google/protobuf/compiler/java/java_enum.cc b/src/google/protobuf/compiler/java/java_enum.cc
index 8a09f3a8..b46cfe9c 100644
--- a/src/google/protobuf/compiler/java/java_enum.cc
+++ b/src/google/protobuf/compiler/java/java_enum.cc
@@ -64,6 +64,7 @@ EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor,
bool immutable_api,
Context* context)
: descriptor_(descriptor), immutable_api_(immutable_api),
+ context_(context),
name_resolver_(context->GetNameResolver()) {
for (int i = 0; i < descriptor_->value_count(); i++) {
const EnumValueDescriptor* value = descriptor_->value(i);
@@ -85,19 +86,24 @@ EnumGenerator::~EnumGenerator() {}
void EnumGenerator::Generate(io::Printer* printer) {
WriteEnumDocComment(printer, descriptor_);
- if (HasDescriptorMethods(descriptor_)) {
- printer->Print(
+ MaybePrintGeneratedAnnotation(context_, printer, descriptor_, immutable_api_);
+ printer->Print(
"public enum $classname$\n"
" implements com.google.protobuf.ProtocolMessageEnum {\n",
"classname", descriptor_->name());
- } else {
- printer->Print(
- "public enum $classname$\n"
- " implements com.google.protobuf.Internal.EnumLite {\n",
- "classname", descriptor_->name());
- }
+ printer->Annotate("classname", descriptor_);
printer->Indent();
+ bool ordinal_is_index = true;
+ string index_text = "ordinal()";
+ for (int i = 0; i < canonical_values_.size(); i++) {
+ if (canonical_values_[i]->index() != i) {
+ ordinal_is_index = false;
+ index_text = "index";
+ break;
+ }
+ }
+
for (int i = 0; i < canonical_values_.size(); i++) {
map<string, string> vars;
vars["name"] = canonical_values_[i]->name();
@@ -107,12 +113,21 @@ void EnumGenerator::Generate(io::Printer* printer) {
if (canonical_values_[i]->options().deprecated()) {
printer->Print("@java.lang.Deprecated\n");
}
- printer->Print(vars,
- "$name$($index$, $number$),\n");
+ if (ordinal_is_index) {
+ printer->Print(vars,
+ "$name$($number$),\n");
+ } else {
+ printer->Print(vars,
+ "$name$($index$, $number$),\n");
+ }
}
if (SupportUnknownEnumValue(descriptor_->file())) {
- printer->Print("UNRECOGNIZED(-1, -1),\n");
+ if (ordinal_is_index) {
+ printer->Print("UNRECOGNIZED(-1),\n");
+ } else {
+ printer->Print("UNRECOGNIZED(-1, -1),\n");
+ }
}
printer->Print(
@@ -147,17 +162,33 @@ void EnumGenerator::Generate(io::Printer* printer) {
"\n"
"public final int getNumber() {\n");
if (SupportUnknownEnumValue(descriptor_->file())) {
- printer->Print(
- " if (index == -1) {\n"
- " throw new java.lang.IllegalArgumentException(\n"
- " \"Can't get the number of an unknown enum value.\");\n"
- " }\n");
+ if (ordinal_is_index) {
+ printer->Print(
+ " if (this == UNRECOGNIZED) {\n"
+ " throw new java.lang.IllegalArgumentException(\n"
+ " \"Can't get the number of an unknown enum value.\");\n"
+ " }\n");
+ } else {
+ printer->Print(
+ " if (index == -1) {\n"
+ " throw new java.lang.IllegalArgumentException(\n"
+ " \"Can't get the number of an unknown enum value.\");\n"
+ " }\n");
+ }
}
printer->Print(
" return value;\n"
"}\n"
"\n"
+ "/**\n"
+ " * @deprecated Use {@link #forNumber(int)} instead.\n"
+ " */\n"
+ "@java.lang.Deprecated\n"
"public static $classname$ valueOf(int value) {\n"
+ " return forNumber(value);\n"
+ "}\n"
+ "\n"
+ "public static $classname$ forNumber(int value) {\n"
" switch (value) {\n",
"classname", descriptor_->name());
printer->Indent();
@@ -185,7 +216,7 @@ void EnumGenerator::Generate(io::Printer* printer) {
" $classname$> internalValueMap =\n"
" new com.google.protobuf.Internal.EnumLiteMap<$classname$>() {\n"
" public $classname$ findValueByNumber(int number) {\n"
- " return $classname$.valueOf(number);\n"
+ " return $classname$.forNumber(number);\n"
" }\n"
" };\n"
"\n",
@@ -194,18 +225,19 @@ void EnumGenerator::Generate(io::Printer* printer) {
// -----------------------------------------------------------------
// Reflection
- if (HasDescriptorMethods(descriptor_)) {
+ if (HasDescriptorMethods(descriptor_, context_->EnforceLite())) {
printer->Print(
"public final com.google.protobuf.Descriptors.EnumValueDescriptor\n"
" getValueDescriptor() {\n"
- " return getDescriptor().getValues().get(index);\n"
+ " return getDescriptor().getValues().get($index_text$);\n"
"}\n"
"public final com.google.protobuf.Descriptors.EnumDescriptor\n"
" getDescriptorForType() {\n"
" return getDescriptor();\n"
"}\n"
"public static final com.google.protobuf.Descriptors.EnumDescriptor\n"
- " getDescriptor() {\n");
+ " getDescriptor() {\n",
+ "index_text", index_text);
// TODO(kenton): Cache statically? Note that we can't access descriptors
// at module init time because it wouldn't work with descriptor.proto, but
@@ -236,7 +268,7 @@ void EnumGenerator::Generate(io::Printer* printer) {
" (com.google.protobuf.Descriptors.FileDescriptor)\n"
" m.invoke(immutableFileClass);\n"
" return file.getEnumTypes().get($index$);\n"
- "} catch (Exception e) {\n"
+ "} catch (java.lang.Exception e) {\n"
// Immutable classes cannot be found. Proceed as if custom options
// don't exist.
"}\n",
@@ -311,17 +343,27 @@ void EnumGenerator::Generate(io::Printer* printer) {
"}\n"
"\n");
- // index is only used for reflection; lite implementation does not need it
- printer->Print("private final int index;\n");
+ if (!ordinal_is_index) {
+ printer->Print("private final int index;\n");
+ }
}
// -----------------------------------------------------------------
printer->Print(
- "private final int value;\n\n"
- "private $classname$(int index, int value) {\n",
- "classname", descriptor_->name());
- if (HasDescriptorMethods(descriptor_)) {
+ "private final int value;\n\n");
+
+ if (ordinal_is_index) {
+ printer->Print(
+ "private $classname$(int value) {\n",
+ "classname", descriptor_->name());
+ } else {
+ printer->Print(
+ "private $classname$(int index, int value) {\n",
+ "classname", descriptor_->name());
+ }
+ if (HasDescriptorMethods(descriptor_, context_->EnforceLite()) &&
+ !ordinal_is_index) {
printer->Print(" this.index = index;\n");
}
printer->Print(
diff --git a/src/google/protobuf/compiler/java/java_enum.h b/src/google/protobuf/compiler/java/java_enum.h
index a0d91f5a..c33e713d 100644
--- a/src/google/protobuf/compiler/java/java_enum.h
+++ b/src/google/protobuf/compiler/java/java_enum.h
@@ -58,9 +58,8 @@ namespace java {
class EnumGenerator {
public:
- explicit EnumGenerator(const EnumDescriptor* descriptor,
- bool immutable_api,
- Context* context);
+ EnumGenerator(const EnumDescriptor* descriptor, bool immutable_api,
+ Context* context);
~EnumGenerator();
void Generate(io::Printer* printer);
diff --git a/src/google/protobuf/compiler/java/java_enum_field.cc b/src/google/protobuf/compiler/java/java_enum_field.cc
index 558da968..2e916c56 100644
--- a/src/google/protobuf/compiler/java/java_enum_field.cc
+++ b/src/google/protobuf/compiler/java/java_enum_field.cc
@@ -68,21 +68,19 @@ void SetEnumVariables(const FieldDescriptor* descriptor,
(*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver);
(*variables)["default_number"] = SimpleItoa(
descriptor->default_value_enum()->number());
- if (descriptor->is_packed()) {
- (*variables)["tag"] = SimpleItoa(internal::WireFormatLite::MakeTag(
- descriptor->number(),
- internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED));
- } else {
- (*variables)["tag"] = SimpleItoa(internal::WireFormat::MakeTag(descriptor));
- }
+ (*variables)["tag"] = SimpleItoa(internal::WireFormat::MakeTag(descriptor));
(*variables)["tag_size"] = SimpleItoa(
internal::WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
// TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
// by the proto compiler
(*variables)["deprecation"] = descriptor->options().deprecated()
? "@java.lang.Deprecated " : "";
- (*variables)["on_changed"] =
- HasDescriptorMethods(descriptor->containing_type()) ? "onChanged();" : "";
+ (*variables)["on_changed"] = "onChanged();";
+ // Use deprecated valueOf() method to be compatible with old generated code
+ // for v2.5.0/v2.6.1.
+ // TODO(xiaofeng): Use "forNumber" when we no longer support compatibility
+ // with v2.5.0/v2.6.1.
+ (*variables)["for_number"] = "valueOf";
if (SupportFieldPresence(descriptor->file())) {
// For singular messages and builders, one bit is used for the hasField bit.
@@ -198,7 +196,7 @@ GenerateMembers(io::Printer* printer) const {
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public $type$ get$capitalized_name$() {\n"
- " $type$ result = $type$.valueOf($name$_);\n"
+ " $type$ result = $type$.$for_number$($name$_);\n"
" return result == null ? $unknown$ : result;\n"
"}\n");
}
@@ -231,7 +229,7 @@ GenerateBuilderMembers(io::Printer* printer) const {
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public $type$ get$capitalized_name$() {\n"
- " $type$ result = $type$.valueOf($name$_);\n"
+ " $type$ result = $type$.$for_number$($name$_);\n"
" return result == null ? $unknown$ : result;\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
@@ -311,7 +309,7 @@ GenerateParsingCode(io::Printer* printer) const {
} else {
printer->Print(variables_,
"int rawValue = input.readEnum();\n"
- "$type$ value = $type$.valueOf(rawValue);\n"
+ "$type$ value = $type$.$for_number$(rawValue);\n"
"if (value == null) {\n");
if (PreserveUnknownFields(descriptor_->containing_type())) {
printer->Print(variables_,
@@ -405,7 +403,8 @@ GenerateMembers(io::Printer* printer) const {
printer->Print(variables_,
"$deprecation$public $type$ get$capitalized_name$() {\n"
" if ($has_oneof_case_message$) {\n"
- " $type$ result = $type$.valueOf((java.lang.Integer) $oneof_name$_);\n"
+ " $type$ result = $type$.$for_number$(\n"
+ " (java.lang.Integer) $oneof_name$_);\n"
" return result == null ? $unknown$ : result;\n"
" }\n"
" return $default$;\n"
@@ -443,7 +442,8 @@ GenerateBuilderMembers(io::Printer* printer) const {
printer->Print(variables_,
"$deprecation$public $type$ get$capitalized_name$() {\n"
" if ($has_oneof_case_message$) {\n"
- " $type$ result = $type$.valueOf((java.lang.Integer) $oneof_name$_);\n"
+ " $type$ result = $type$.$for_number$(\n"
+ " (java.lang.Integer) $oneof_name$_);\n"
" return result == null ? $unknown$ : result;\n"
" }\n"
" return $default$;\n"
@@ -500,7 +500,7 @@ GenerateParsingCode(io::Printer* printer) const {
} else {
printer->Print(variables_,
"int rawValue = input.readEnum();\n"
- "$type$ value = $type$.valueOf(rawValue);\n"
+ "$type$ value = $type$.$for_number$(rawValue);\n"
"if (value == null) {\n");
if (PreserveUnknownFields(descriptor_->containing_type())) {
printer->Print(variables_,
@@ -613,7 +613,7 @@ GenerateMembers(io::Printer* printer) const {
" new com.google.protobuf.Internal.ListAdapter.Converter<\n"
" java.lang.Integer, $type$>() {\n"
" public $type$ convert(java.lang.Integer from) {\n"
- " $type$ result = $type$.valueOf(from);\n"
+ " $type$ result = $type$.$for_number$(from);\n"
" return result == null ? $unknown$ : result;\n"
" }\n"
" };\n");
@@ -649,7 +649,7 @@ GenerateMembers(io::Printer* printer) const {
}
if (descriptor_->is_packed() &&
- HasGeneratedMethods(descriptor_->containing_type())) {
+ context_->HasGeneratedMethods(descriptor_->containing_type())) {
printer->Print(variables_,
"private int $name$MemoizedSerializedSize;\n");
}
@@ -846,7 +846,7 @@ GenerateParsingCode(io::Printer* printer) const {
} else {
printer->Print(variables_,
"int rawValue = input.readEnum();\n"
- "$type$ value = $type$.valueOf(rawValue);\n"
+ "$type$ value = $type$.$for_number$(rawValue);\n"
"if (value == null) {\n");
if (PreserveUnknownFields(descriptor_->containing_type())) {
printer->Print(variables_,
@@ -894,8 +894,8 @@ GenerateSerializationCode(io::Printer* printer) const {
if (descriptor_->is_packed()) {
printer->Print(variables_,
"if (get$capitalized_name$List().size() > 0) {\n"
- " output.writeRawVarint32($tag$);\n"
- " output.writeRawVarint32($name$MemoizedSerializedSize);\n"
+ " output.writeUInt32NoTag($tag$);\n"
+ " output.writeUInt32NoTag($name$MemoizedSerializedSize);\n"
"}\n"
"for (int i = 0; i < $name$_.size(); i++) {\n"
" output.writeEnumNoTag($name$_.get(i));\n"
@@ -927,7 +927,7 @@ GenerateSerializedSizeCode(io::Printer* printer) const {
"if (!get$capitalized_name$List().isEmpty()) {"
" size += $tag_size$;\n"
" size += com.google.protobuf.CodedOutputStream\n"
- " .computeRawVarint32Size(dataSize);\n"
+ " .computeUInt32SizeNoTag(dataSize);\n"
"}");
} else {
printer->Print(variables_,
diff --git a/src/google/protobuf/compiler/java/java_enum_field_lite.cc b/src/google/protobuf/compiler/java/java_enum_field_lite.cc
index e8bf15d0..aa0eb5e8 100644
--- a/src/google/protobuf/compiler/java/java_enum_field_lite.cc
+++ b/src/google/protobuf/compiler/java/java_enum_field_lite.cc
@@ -75,8 +75,6 @@ void SetEnumVariables(const FieldDescriptor* descriptor,
// by the proto compiler
(*variables)["deprecation"] = descriptor->options().deprecated()
? "@java.lang.Deprecated " : "";
- (*variables)["on_changed"] =
- HasDescriptorMethods(descriptor->containing_type()) ? "onChanged();" : "";
if (SupportFieldPresence(descriptor->file())) {
// For singular messages and builders, one bit is used for the hasField bit.
@@ -179,7 +177,7 @@ GenerateMembers(io::Printer* printer) const {
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public $type$ get$capitalized_name$() {\n"
- " $type$ result = $type$.valueOf($name$_);\n"
+ " $type$ result = $type$.forNumber($name$_);\n"
" return result == null ? $unknown$ : result;\n"
"}\n");
@@ -228,7 +226,7 @@ GenerateBuilderMembers(io::Printer* printer) const {
printer->Print(variables_,
"$deprecation$public Builder set$capitalized_name$Value(int value) {\n"
" copyOnWrite();\n"
- " instance.set$capitalized_name$Value(int value);\n"
+ " instance.set$capitalized_name$Value(value);\n"
" return this;\n"
"}\n");
}
@@ -260,21 +258,21 @@ GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
void ImmutableEnumFieldLiteGenerator::
GenerateInitializationCode(io::Printer* printer) const {
- printer->Print(variables_, "$name$_ = $default_number$;\n");
+ if (!IsDefaultValueJavaDefault(descriptor_)) {
+ printer->Print(variables_, "$name$_ = $default_number$;\n");
+ }
}
void ImmutableEnumFieldLiteGenerator::
-GenerateMergingCode(io::Printer* printer) const {
+GenerateVisitCode(io::Printer* printer) const {
if (SupportFieldPresence(descriptor_->file())) {
printer->Print(variables_,
- "if (other.has$capitalized_name$()) {\n"
- " set$capitalized_name$(other.get$capitalized_name$());\n"
- "}\n");
+ "$name$_ = visitor.visitInt(has$capitalized_name$(), $name$_,\n"
+ " other.has$capitalized_name$(), other.$name$_);\n");
} else if (SupportUnknownEnumValue(descriptor_->file())) {
printer->Print(variables_,
- "if (other.$name$_ != $default_number$) {\n"
- " set$capitalized_name$Value(other.get$capitalized_name$Value());\n"
- "}\n");
+ "$name$_ = visitor.visitInt($name$_ != $default_number$, $name$_,"
+ " other.$name$_ != $default_number$, other.$name$_);\n");
} else {
GOOGLE_LOG(FATAL) << "Can't reach here.";
}
@@ -295,7 +293,7 @@ GenerateParsingCode(io::Printer* printer) const {
} else {
printer->Print(variables_,
"int rawValue = input.readEnum();\n"
- "$type$ value = $type$.valueOf(rawValue);\n"
+ "$type$ value = $type$.forNumber(rawValue);\n"
"if (value == null) {\n");
if (PreserveUnknownFields(descriptor_->containing_type())) {
printer->Print(variables_,
@@ -389,7 +387,7 @@ GenerateMembers(io::Printer* printer) const {
printer->Print(variables_,
"$deprecation$public $type$ get$capitalized_name$() {\n"
" if ($has_oneof_case_message$) {\n"
- " $type$ result = $type$.valueOf((java.lang.Integer) $oneof_name$_);\n"
+ " $type$ result = $type$.forNumber((java.lang.Integer) $oneof_name$_);\n"
" return result == null ? $unknown$ : result;\n"
" }\n"
" return $default$;\n"
@@ -468,14 +466,10 @@ GenerateBuilderMembers(io::Printer* printer) const {
}
void ImmutableEnumOneofFieldLiteGenerator::
-GenerateMergingCode(io::Printer* printer) const {
- if (SupportUnknownEnumValue(descriptor_->file())) {
- printer->Print(variables_,
- "set$capitalized_name$Value(other.get$capitalized_name$Value());\n");
- } else {
- printer->Print(variables_,
- "set$capitalized_name$(other.get$capitalized_name$());\n");
- }
+GenerateVisitCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "$oneof_name$_ = visitor.visitOneofInt(\n"
+ " $has_oneof_case_message$, $oneof_name$_, other.$oneof_name$_);\n");
}
void ImmutableEnumOneofFieldLiteGenerator::
@@ -488,7 +482,7 @@ GenerateParsingCode(io::Printer* printer) const {
} else {
printer->Print(variables_,
"int rawValue = input.readEnum();\n"
- "$type$ value = $type$.valueOf(rawValue);\n"
+ "$type$ value = $type$.forNumber(rawValue);\n"
"if (value == null) {\n");
if (PreserveUnknownFields(descriptor_->containing_type())) {
printer->Print(variables_,
@@ -596,15 +590,13 @@ GenerateInterfaceMembers(io::Printer* printer) const {
void RepeatedImmutableEnumFieldLiteGenerator::
GenerateMembers(io::Printer* printer) const {
printer->Print(variables_,
- // TODO(dweis): Switch to IntList?
- "private com.google.protobuf.Internal.ProtobufList<\n"
- " java.lang.Integer> $name$_;\n"
+ "private com.google.protobuf.Internal.IntList $name$_;\n"
"private static final com.google.protobuf.Internal.ListAdapter.Converter<\n"
" java.lang.Integer, $type$> $name$_converter_ =\n"
" new com.google.protobuf.Internal.ListAdapter.Converter<\n"
" java.lang.Integer, $type$>() {\n"
" public $type$ convert(java.lang.Integer from) {\n"
- " $type$ result = $type$.valueOf(from);\n"
+ " $type$ result = $type$.forNumber(from);\n"
" return result == null ? $unknown$ : result;\n"
" }\n"
" };\n");
@@ -623,7 +615,7 @@ GenerateMembers(io::Printer* printer) const {
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public $type$ get$capitalized_name$(int index) {\n"
- " return $name$_converter_.convert($name$_.get(index));\n"
+ " return $name$_converter_.convert($name$_.getInt(index));\n"
"}\n");
if (SupportUnknownEnumValue(descriptor_->file())) {
WriteFieldDocComment(printer, descriptor_);
@@ -635,12 +627,12 @@ GenerateMembers(io::Printer* printer) const {
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public int get$capitalized_name$Value(int index) {\n"
- " return $name$_.get(index);\n"
+ " return $name$_.getInt(index);\n"
"}\n");
}
if (descriptor_->options().packed() &&
- HasGeneratedMethods(descriptor_->containing_type())) {
+ context_->HasGeneratedMethods(descriptor_->containing_type())) {
printer->Print(variables_,
"private int $name$MemoizedSerializedSize;\n");
}
@@ -649,7 +641,8 @@ GenerateMembers(io::Printer* printer) const {
printer->Print(variables_,
"private void ensure$capitalized_name$IsMutable() {\n"
" if (!$is_mutable$) {\n"
- " $name$_ = newProtobufList($name$_);\n"
+ " $name$_ =\n"
+ " com.google.protobuf.GeneratedMessageLite.mutableCopy($name$_);\n"
" }\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
@@ -660,7 +653,7 @@ GenerateMembers(io::Printer* printer) const {
" throw new NullPointerException();\n"
" }\n"
" ensure$capitalized_name$IsMutable();\n"
- " $name$_.set(index, value.getNumber());\n"
+ " $name$_.setInt(index, value.getNumber());\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
@@ -669,7 +662,7 @@ GenerateMembers(io::Printer* printer) const {
" throw new NullPointerException();\n"
" }\n"
" ensure$capitalized_name$IsMutable();\n"
- " $name$_.add(value.getNumber());\n"
+ " $name$_.addInt(value.getNumber());\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
@@ -677,13 +670,13 @@ GenerateMembers(io::Printer* printer) const {
" java.lang.Iterable<? extends $type$> values) {\n"
" ensure$capitalized_name$IsMutable();\n"
" for ($type$ value : values) {\n"
- " $name$_.add(value.getNumber());\n"
+ " $name$_.addInt(value.getNumber());\n"
" }\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"private void clear$capitalized_name$() {\n"
- " $name$_ = emptyProtobufList();\n"
+ " $name$_ = emptyIntList();\n"
"}\n");
if (SupportUnknownEnumValue(descriptor_->file())) {
@@ -692,13 +685,13 @@ GenerateMembers(io::Printer* printer) const {
"private void set$capitalized_name$Value(\n"
" int index, int value) {\n"
" ensure$capitalized_name$IsMutable();\n"
- " $name$_.set(index, value);\n"
+ " $name$_.setInt(index, value);\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"private void add$capitalized_name$Value(int value) {\n"
" ensure$capitalized_name$IsMutable();\n"
- " $name$_.add(value);\n"
+ " $name$_.addInt(value);\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
@@ -706,7 +699,7 @@ GenerateMembers(io::Printer* printer) const {
" java.lang.Iterable<java.lang.Integer> values) {\n"
" ensure$capitalized_name$IsMutable();\n"
" for (int value : values) {\n"
- " $name$_.add(value);\n"
+ " $name$_.addInt(value);\n"
" }\n"
"}\n");
}
@@ -805,26 +798,13 @@ GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
void RepeatedImmutableEnumFieldLiteGenerator::
GenerateInitializationCode(io::Printer* printer) const {
- printer->Print(variables_, "$name$_ = emptyProtobufList();\n");
+ printer->Print(variables_, "$name$_ = emptyIntList();\n");
}
void RepeatedImmutableEnumFieldLiteGenerator::
-GenerateMergingCode(io::Printer* printer) const {
- // The code below does two optimizations:
- // 1. If the other list is empty, there's nothing to do. This ensures we
- // don't allocate a new array if we already have an immutable one.
- // 2. If the other list is non-empty and our current list is empty, we can
- // reuse the other list which is guaranteed to be immutable.
- printer->Print(variables_,
- "if (!other.$name$_.isEmpty()) {\n"
- " if ($name$_.isEmpty()) {\n"
- " $name$_ = other.$name$_;\n"
- " } else {\n"
- " ensure$capitalized_name$IsMutable();\n"
- " $name$_.addAll(other.$name$_);\n"
- " }\n"
- " $on_changed$\n"
- "}\n");
+GenerateVisitCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "$name$_= visitor.visitIntList($name$_, other.$name$_);\n");
}
void RepeatedImmutableEnumFieldLiteGenerator::
@@ -836,35 +816,35 @@ GenerateDynamicMethodMakeImmutableCode(io::Printer* printer) const {
void RepeatedImmutableEnumFieldLiteGenerator::
GenerateParsingCode(io::Printer* printer) const {
// Read and store the enum
+ printer->Print(variables_,
+ "if (!$is_mutable$) {\n"
+ " $name$_ =\n"
+ " com.google.protobuf.GeneratedMessageLite.mutableCopy($name$_);\n"
+ "}\n");
+
if (SupportUnknownEnumValue(descriptor_->file())) {
printer->Print(variables_,
- "int rawValue = input.readEnum();\n"
- "if (!$is_mutable$) {\n"
- " $name$_ = newProtobufList();\n"
- "}\n"
- "$name$_.add(rawValue);\n");
+ "$name$_.addInt(input.readEnum());\n");
} else {
printer->Print(variables_,
"int rawValue = input.readEnum();\n"
- "$type$ value = $type$.valueOf(rawValue);\n"
- "if (value == null) {\n");
- if (PreserveUnknownFields(descriptor_->containing_type())) {
- printer->Print(variables_,
- " super.mergeVarintField($number$, rawValue);\n");
- }
- printer->Print(variables_,
+ "$type$ value = $type$.forNumber(rawValue);\n"
+ "if (value == null) {\n"
+ // We store the unknown value in unknown fields.
+ " super.mergeVarintField($number$, rawValue);\n"
"} else {\n"
- " if (!$is_mutable$) {\n"
- " $name$_ = newProtobufList();\n"
- " }\n"
- " $name$_.add(rawValue);\n"
+ " $name$_.addInt(rawValue);\n"
"}\n");
}
}
void RepeatedImmutableEnumFieldLiteGenerator::
GenerateParsingCodeFromPacked(io::Printer* printer) const {
- // Wrap GenerateParsingCode's contents with a while loop.
+ printer->Print(variables_,
+ "if (!$is_mutable$) {\n"
+ " $name$_ =\n"
+ " com.google.protobuf.GeneratedMessageLite.mutableCopy($name$_);\n"
+ "}\n");
printer->Print(variables_,
"int length = input.readRawVarint32();\n"
@@ -872,7 +852,21 @@ GenerateParsingCodeFromPacked(io::Printer* printer) const {
"while(input.getBytesUntilLimit() > 0) {\n");
printer->Indent();
- GenerateParsingCode(printer);
+ // Read and store the enum
+ if (SupportUnknownEnumValue(descriptor_->file())) {
+ printer->Print(variables_,
+ "$name$_.addInt(input.readEnum());\n");
+ } else {
+ printer->Print(variables_,
+ "int rawValue = input.readEnum();\n"
+ "$type$ value = $type$.forNumber(rawValue);\n"
+ "if (value == null) {\n"
+ // We store the unknown value in unknown fields.
+ " super.mergeVarintField($number$, rawValue);\n"
+ "} else {\n"
+ " $name$_.addInt(rawValue);\n"
+ "}\n");
+ }
printer->Outdent();
printer->Print(variables_,
@@ -893,16 +887,16 @@ GenerateSerializationCode(io::Printer* printer) const {
if (descriptor_->options().packed()) {
printer->Print(variables_,
"if (get$capitalized_name$List().size() > 0) {\n"
- " output.writeRawVarint32($tag$);\n"
- " output.writeRawVarint32($name$MemoizedSerializedSize);\n"
+ " output.writeUInt32NoTag($tag$);\n"
+ " output.writeUInt32NoTag($name$MemoizedSerializedSize);\n"
"}\n"
"for (int i = 0; i < $name$_.size(); i++) {\n"
- " output.writeEnumNoTag($name$_.get(i));\n"
+ " output.writeEnumNoTag($name$_.getInt(i));\n"
"}\n");
} else {
printer->Print(variables_,
"for (int i = 0; i < $name$_.size(); i++) {\n"
- " output.writeEnum($number$, $name$_.get(i));\n"
+ " output.writeEnum($number$, $name$_.getInt(i));\n"
"}\n");
}
}
@@ -917,7 +911,7 @@ GenerateSerializedSizeCode(io::Printer* printer) const {
printer->Print(variables_,
"for (int i = 0; i < $name$_.size(); i++) {\n"
" dataSize += com.google.protobuf.CodedOutputStream\n"
- " .computeEnumSizeNoTag($name$_.get(i));\n"
+ " .computeEnumSizeNoTag($name$_.getInt(i));\n"
"}\n");
printer->Print(
"size += dataSize;\n");
@@ -926,7 +920,7 @@ GenerateSerializedSizeCode(io::Printer* printer) const {
"if (!get$capitalized_name$List().isEmpty()) {"
" size += $tag_size$;\n"
" size += com.google.protobuf.CodedOutputStream\n"
- " .computeRawVarint32Size(dataSize);\n"
+ " .computeUInt32SizeNoTag(dataSize);\n"
"}");
} else {
printer->Print(variables_,
diff --git a/src/google/protobuf/compiler/java/java_enum_field_lite.h b/src/google/protobuf/compiler/java/java_enum_field_lite.h
index 2c41c3e4..9201b8d6 100644
--- a/src/google/protobuf/compiler/java/java_enum_field_lite.h
+++ b/src/google/protobuf/compiler/java/java_enum_field_lite.h
@@ -67,7 +67,7 @@ class ImmutableEnumFieldLiteGenerator : public ImmutableFieldLiteGenerator {
void GenerateMembers(io::Printer* printer) const;
void GenerateBuilderMembers(io::Printer* printer) const;
void GenerateInitializationCode(io::Printer* printer) const;
- void GenerateMergingCode(io::Printer* printer) const;
+ void GenerateVisitCode(io::Printer* printer) const;
void GenerateDynamicMethodMakeImmutableCode(io::Printer* printer) const;
void GenerateParsingCode(io::Printer* printer) const;
void GenerateParsingDoneCode(io::Printer* printer) const;
@@ -101,7 +101,7 @@ class ImmutableEnumOneofFieldLiteGenerator
void GenerateMembers(io::Printer* printer) const;
void GenerateBuilderMembers(io::Printer* printer) const;
- void GenerateMergingCode(io::Printer* printer) const;
+ void GenerateVisitCode(io::Printer* printer) const;
void GenerateParsingCode(io::Printer* printer) const;
void GenerateSerializationCode(io::Printer* printer) const;
void GenerateSerializedSizeCode(io::Printer* printer) const;
@@ -127,7 +127,7 @@ class RepeatedImmutableEnumFieldLiteGenerator
void GenerateMembers(io::Printer* printer) const;
void GenerateBuilderMembers(io::Printer* printer) const;
void GenerateInitializationCode(io::Printer* printer) const;
- void GenerateMergingCode(io::Printer* printer) const;
+ void GenerateVisitCode(io::Printer* printer) const;
void GenerateDynamicMethodMakeImmutableCode(io::Printer* printer) const;
void GenerateParsingCode(io::Printer* printer) const;
void GenerateParsingCodeFromPacked(io::Printer* printer) const;
diff --git a/src/google/protobuf/compiler/java/java_enum_lite.cc b/src/google/protobuf/compiler/java/java_enum_lite.cc
index 62186386..99f52d40 100644
--- a/src/google/protobuf/compiler/java/java_enum_lite.cc
+++ b/src/google/protobuf/compiler/java/java_enum_lite.cc
@@ -61,10 +61,11 @@ bool EnumHasCustomOptions(const EnumDescriptor* descriptor) {
} // namespace
EnumLiteGenerator::EnumLiteGenerator(const EnumDescriptor* descriptor,
- bool immutable_api,
- Context* context)
- : descriptor_(descriptor), immutable_api_(immutable_api),
- name_resolver_(context->GetNameResolver()) {
+ bool immutable_api, Context* context)
+ : descriptor_(descriptor),
+ immutable_api_(immutable_api),
+ context_(context),
+ name_resolver_(context->GetNameResolver()) {
for (int i = 0; i < descriptor_->value_count(); i++) {
const EnumValueDescriptor* value = descriptor_->value(i);
const EnumValueDescriptor* canonical_value =
@@ -85,34 +86,28 @@ EnumLiteGenerator::~EnumLiteGenerator() {}
void EnumLiteGenerator::Generate(io::Printer* printer) {
WriteEnumDocComment(printer, descriptor_);
- if (HasDescriptorMethods(descriptor_)) {
- printer->Print(
- "public enum $classname$\n"
- " implements com.google.protobuf.ProtocolMessageEnum {\n",
- "classname", descriptor_->name());
- } else {
- printer->Print(
+ MaybePrintGeneratedAnnotation(context_, printer, descriptor_, immutable_api_);
+ printer->Print(
"public enum $classname$\n"
" implements com.google.protobuf.Internal.EnumLite {\n",
"classname", descriptor_->name());
- }
+ printer->Annotate("classname", descriptor_);
printer->Indent();
for (int i = 0; i < canonical_values_.size(); i++) {
map<string, string> vars;
vars["name"] = canonical_values_[i]->name();
- vars["index"] = SimpleItoa(canonical_values_[i]->index());
vars["number"] = SimpleItoa(canonical_values_[i]->number());
WriteEnumValueDocComment(printer, canonical_values_[i]);
if (canonical_values_[i]->options().deprecated()) {
printer->Print("@java.lang.Deprecated\n");
}
printer->Print(vars,
- "$name$($index$, $number$),\n");
+ "$name$($number$),\n");
}
if (SupportUnknownEnumValue(descriptor_->file())) {
- printer->Print("UNRECOGNIZED(-1, -1),\n");
+ printer->Print("UNRECOGNIZED(-1),\n");
}
printer->Print(
@@ -145,19 +140,19 @@ void EnumLiteGenerator::Generate(io::Printer* printer) {
printer->Print(
"\n"
- "public final int getNumber() {\n");
- if (SupportUnknownEnumValue(descriptor_->file())) {
- printer->Print(
- " if (index == -1) {\n"
- " throw new java.lang.IllegalArgumentException(\n"
- " \"Can't get the number of an unknown enum value.\");\n"
- " }\n");
- }
- printer->Print(
+ "public final int getNumber() {\n"
" return value;\n"
"}\n"
"\n"
+ "/**\n"
+ " * @deprecated Use {@link #forNumber(int)} instead.\n"
+ " */\n"
+ "@java.lang.Deprecated\n"
"public static $classname$ valueOf(int value) {\n"
+ " return forNumber(value);\n"
+ "}\n"
+ "\n"
+ "public static $classname$ forNumber(int value) {\n"
" switch (value) {\n",
"classname", descriptor_->name());
printer->Indent();
@@ -185,7 +180,7 @@ void EnumLiteGenerator::Generate(io::Printer* printer) {
" $classname$> internalValueMap =\n"
" new com.google.protobuf.Internal.EnumLiteMap<$classname$>() {\n"
" public $classname$ findValueByNumber(int number) {\n"
- " return $classname$.valueOf(number);\n"
+ " return $classname$.forNumber(number);\n"
" }\n"
" };\n"
"\n",
@@ -193,7 +188,7 @@ void EnumLiteGenerator::Generate(io::Printer* printer) {
printer->Print(
"private final int value;\n\n"
- "private $classname$(int index, int value) {\n",
+ "private $classname$(int value) {\n",
"classname", descriptor_->name());
printer->Print(
" this.value = value;\n"
diff --git a/src/google/protobuf/compiler/java/java_enum_lite.h b/src/google/protobuf/compiler/java/java_enum_lite.h
index ee2f5f7a..f27cb76f 100644
--- a/src/google/protobuf/compiler/java/java_enum_lite.h
+++ b/src/google/protobuf/compiler/java/java_enum_lite.h
@@ -58,9 +58,8 @@ namespace java {
class EnumLiteGenerator {
public:
- explicit EnumLiteGenerator(const EnumDescriptor* descriptor,
- bool immutable_api,
- Context* context);
+ EnumLiteGenerator(const EnumDescriptor* descriptor, bool immutable_api,
+ Context* context);
~EnumLiteGenerator();
void Generate(io::Printer* printer);
diff --git a/src/google/protobuf/compiler/java/java_extension.cc b/src/google/protobuf/compiler/java/java_extension.cc
index 4db7085e..46b5faaa 100644
--- a/src/google/protobuf/compiler/java/java_extension.cc
+++ b/src/google/protobuf/compiler/java/java_extension.cc
@@ -118,75 +118,38 @@ void ImmutableExtensionGenerator::Generate(io::Printer* printer) {
"public static final int $constant_name$ = $number$;\n");
WriteFieldDocComment(printer, descriptor_);
- if (HasDescriptorMethods(descriptor_->file())) {
- // Non-lite extensions
- if (descriptor_->extension_scope() == NULL) {
- // Non-nested
- printer->Print(
- vars,
- "public static final\n"
- " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
- " $containing_type$,\n"
- " $type$> $name$ = com.google.protobuf.GeneratedMessage\n"
- " .newFileScopedGeneratedExtension(\n"
- " $singular_type$.class,\n"
- " $prototype$);\n");
- } else {
- // Nested
- printer->Print(
- vars,
- "public static final\n"
- " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
- " $containing_type$,\n"
- " $type$> $name$ = com.google.protobuf.GeneratedMessage\n"
- " .newMessageScopedGeneratedExtension(\n"
- " $scope$.getDefaultInstance(),\n"
- " $index$,\n"
- " $singular_type$.class,\n"
- " $prototype$);\n");
- }
+ if (descriptor_->extension_scope() == NULL) {
+ // Non-nested
+ printer->Print(
+ vars,
+ "public static final\n"
+ " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
+ " $containing_type$,\n"
+ " $type$> $name$ = com.google.protobuf.GeneratedMessage\n"
+ " .newFileScopedGeneratedExtension(\n"
+ " $singular_type$.class,\n"
+ " $prototype$);\n");
} else {
- // Lite extensions
- if (descriptor_->is_repeated()) {
- printer->Print(
- vars,
- "public static final\n"
- " com.google.protobuf.GeneratedMessageLite.GeneratedExtension<\n"
- " $containing_type$,\n"
- " $type$> $name$ = com.google.protobuf.GeneratedMessageLite\n"
- " .newRepeatedGeneratedExtension(\n"
- " $containing_type$.getDefaultInstance(),\n"
- " $prototype$,\n"
- " $enum_map$,\n"
- " $number$,\n"
- " com.google.protobuf.WireFormat.FieldType.$type_constant$,\n"
- " $packed$,\n"
- " $singular_type$.class);\n");
- } else {
- printer->Print(
- vars,
- "public static final\n"
- " com.google.protobuf.GeneratedMessageLite.GeneratedExtension<\n"
- " $containing_type$,\n"
- " $type$> $name$ = com.google.protobuf.GeneratedMessageLite\n"
- " .newSingularGeneratedExtension(\n"
- " $containing_type$.getDefaultInstance(),\n"
- " $default$,\n"
- " $prototype$,\n"
- " $enum_map$,\n"
- " $number$,\n"
- " com.google.protobuf.WireFormat.FieldType.$type_constant$,\n"
- " $singular_type$.class);\n");
- }
+ // Nested
+ printer->Print(
+ vars,
+ "public static final\n"
+ " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
+ " $containing_type$,\n"
+ " $type$> $name$ = com.google.protobuf.GeneratedMessage\n"
+ " .newMessageScopedGeneratedExtension(\n"
+ " $scope$.getDefaultInstance(),\n"
+ " $index$,\n"
+ " $singular_type$.class,\n"
+ " $prototype$);\n");
}
}
int ImmutableExtensionGenerator::GenerateNonNestedInitializationCode(
io::Printer* printer) {
int bytecode_estimate = 0;
- if (descriptor_->extension_scope() == NULL &&
- HasDescriptorMethods(descriptor_->file())) {
- // Only applies to non-nested, non-lite extensions.
+ if (descriptor_->extension_scope() == NULL) {
+ // Only applies to non-nested extensions.
printer->Print(
"$name$.internalInit(descriptor.getExtensions().get($index$));\n",
"name", UnderscoresToCamelCase(descriptor_),
diff --git a/src/google/protobuf/compiler/java/java_extension_lite.cc b/src/google/protobuf/compiler/java/java_extension_lite.cc
new file mode 100644
index 00000000..23261bac
--- /dev/null
+++ b/src/google/protobuf/compiler/java/java_extension_lite.cc
@@ -0,0 +1,118 @@
+// 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 <google/protobuf/compiler/java/java_extension_lite.h>
+
+#include <google/protobuf/compiler/java/java_context.h>
+#include <google/protobuf/compiler/java/java_doc_comment.h>
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/compiler/java/java_name_resolver.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+ImmutableExtensionLiteGenerator::ImmutableExtensionLiteGenerator(
+ const FieldDescriptor* descriptor, Context* context)
+ : descriptor_(descriptor), context_(context),
+ name_resolver_(context->GetNameResolver()) {
+ if (descriptor_->extension_scope() != NULL) {
+ scope_ = name_resolver_->GetImmutableClassName(
+ descriptor_->extension_scope());
+ } else {
+ scope_ = name_resolver_->GetImmutableClassName(descriptor_->file());
+ }
+}
+
+ImmutableExtensionLiteGenerator::~ImmutableExtensionLiteGenerator() {}
+
+void ImmutableExtensionLiteGenerator::Generate(io::Printer* printer) {
+ map<string, string> vars;
+ const bool kUseImmutableNames = true;
+ InitTemplateVars(descriptor_, scope_, kUseImmutableNames, name_resolver_,
+ &vars);
+ printer->Print(vars,
+ "public static final int $constant_name$ = $number$;\n");
+
+ WriteFieldDocComment(printer, descriptor_);
+ if (descriptor_->is_repeated()) {
+ printer->Print(
+ vars,
+ "public static final\n"
+ " com.google.protobuf.GeneratedMessageLite.GeneratedExtension<\n"
+ " $containing_type$,\n"
+ " $type$> $name$ = com.google.protobuf.GeneratedMessageLite\n"
+ " .newRepeatedGeneratedExtension(\n"
+ " $containing_type$.getDefaultInstance(),\n"
+ " $prototype$,\n"
+ " $enum_map$,\n"
+ " $number$,\n"
+ " com.google.protobuf.WireFormat.FieldType.$type_constant$,\n"
+ " $packed$,\n"
+ " $singular_type$.class);\n");
+ } else {
+ printer->Print(
+ vars,
+ "public static final\n"
+ " com.google.protobuf.GeneratedMessageLite.GeneratedExtension<\n"
+ " $containing_type$,\n"
+ " $type$> $name$ = com.google.protobuf.GeneratedMessageLite\n"
+ " .newSingularGeneratedExtension(\n"
+ " $containing_type$.getDefaultInstance(),\n"
+ " $default$,\n"
+ " $prototype$,\n"
+ " $enum_map$,\n"
+ " $number$,\n"
+ " com.google.protobuf.WireFormat.FieldType.$type_constant$,\n"
+ " $singular_type$.class);\n");
+ }
+}
+
+int ImmutableExtensionLiteGenerator::GenerateNonNestedInitializationCode(
+ io::Printer* printer) {
+ return 0;
+}
+
+int ImmutableExtensionLiteGenerator::GenerateRegistrationCode(
+ io::Printer* printer) {
+ printer->Print(
+ "registry.add($scope$.$name$);\n",
+ "scope", scope_,
+ "name", UnderscoresToCamelCase(descriptor_));
+ return 7;
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/google/protobuf/compiler/java/java_extension_lite.h b/src/google/protobuf/compiler/java/java_extension_lite.h
new file mode 100644
index 00000000..4cd49bda
--- /dev/null
+++ b/src/google/protobuf/compiler/java/java_extension_lite.h
@@ -0,0 +1,76 @@
+// 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.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_EXTENSION_LITE_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_EXTENSION_LITE_H__
+
+#include <map>
+#include <string>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/compiler/java/java_extension.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+// Generates code for a lite extension, which may be within the scope of some
+// message or may be at file scope. This is much simpler than FieldGenerator
+// since extensions are just simple identifiers with interesting types.
+class ImmutableExtensionLiteGenerator : public ExtensionGenerator {
+ public:
+ explicit ImmutableExtensionLiteGenerator(const FieldDescriptor* descriptor,
+ Context* context);
+ virtual ~ImmutableExtensionLiteGenerator();
+
+ virtual void Generate(io::Printer* printer);
+
+ // Returns an estimate of the number of bytes the printed code will compile to
+ virtual int GenerateNonNestedInitializationCode(io::Printer* printer);
+
+ // Returns an estimate of the number of bytes the printed code will compile to
+ virtual int GenerateRegistrationCode(io::Printer* printer);
+
+ private:
+ const FieldDescriptor* descriptor_;
+ Context* context_;
+ ClassNameResolver* name_resolver_;
+ string scope_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableExtensionLiteGenerator);
+};
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_EXTENSION_LITE_H__
diff --git a/src/google/protobuf/compiler/java/java_field.cc b/src/google/protobuf/compiler/java/java_field.cc
index c5434767..3c7bc5c4 100644
--- a/src/google/protobuf/compiler/java/java_field.cc
+++ b/src/google/protobuf/compiler/java/java_field.cc
@@ -77,7 +77,7 @@ ImmutableFieldGenerator* MakeImmutableGenerator(
return new ImmutableMapFieldGenerator(
field, messageBitIndex, builderBitIndex, context);
} else {
- if (IsLazy(field)) {
+ if (IsLazy(field, context->EnforceLite())) {
return new RepeatedImmutableLazyMessageFieldGenerator(
field, messageBitIndex, builderBitIndex, context);
} else {
@@ -99,7 +99,7 @@ ImmutableFieldGenerator* MakeImmutableGenerator(
if (field->containing_oneof()) {
switch (GetJavaType(field)) {
case JAVATYPE_MESSAGE:
- if (IsLazy(field)) {
+ if (IsLazy(field, context->EnforceLite())) {
return new ImmutableLazyMessageOneofFieldGenerator(
field, messageBitIndex, builderBitIndex, context);
} else {
@@ -119,7 +119,7 @@ ImmutableFieldGenerator* MakeImmutableGenerator(
} else {
switch (GetJavaType(field)) {
case JAVATYPE_MESSAGE:
- if (IsLazy(field)) {
+ if (IsLazy(field, context->EnforceLite())) {
return new ImmutableLazyMessageFieldGenerator(
field, messageBitIndex, builderBitIndex, context);
} else {
@@ -150,7 +150,7 @@ ImmutableFieldLiteGenerator* MakeImmutableLiteGenerator(
return new ImmutableMapFieldLiteGenerator(
field, messageBitIndex, builderBitIndex, context);
} else {
- if (IsLazy(field)) {
+ if (IsLazy(field, context->EnforceLite())) {
return new RepeatedImmutableLazyMessageFieldLiteGenerator(
field, messageBitIndex, builderBitIndex, context);
} else {
@@ -172,7 +172,7 @@ ImmutableFieldLiteGenerator* MakeImmutableLiteGenerator(
if (field->containing_oneof()) {
switch (GetJavaType(field)) {
case JAVATYPE_MESSAGE:
- if (IsLazy(field)) {
+ if (IsLazy(field, context->EnforceLite())) {
return new ImmutableLazyMessageOneofFieldLiteGenerator(
field, messageBitIndex, builderBitIndex, context);
} else {
@@ -192,7 +192,7 @@ ImmutableFieldLiteGenerator* MakeImmutableLiteGenerator(
} else {
switch (GetJavaType(field)) {
case JAVATYPE_MESSAGE:
- if (IsLazy(field)) {
+ if (IsLazy(field, context->EnforceLite())) {
return new ImmutableLazyMessageFieldLiteGenerator(
field, messageBitIndex, builderBitIndex, context);
} else {
diff --git a/src/google/protobuf/compiler/java/java_field.h b/src/google/protobuf/compiler/java/java_field.h
index 0e24da24..4dd4f57f 100644
--- a/src/google/protobuf/compiler/java/java_field.h
+++ b/src/google/protobuf/compiler/java/java_field.h
@@ -105,7 +105,7 @@ class ImmutableFieldLiteGenerator {
virtual void GenerateMembers(io::Printer* printer) const = 0;
virtual void GenerateBuilderMembers(io::Printer* printer) const = 0;
virtual void GenerateInitializationCode(io::Printer* printer) const = 0;
- virtual void GenerateMergingCode(io::Printer* printer) const = 0;
+ virtual void GenerateVisitCode(io::Printer* printer) const = 0;
virtual void GenerateDynamicMethodMakeImmutableCode(io::Printer* printer)
const = 0;
virtual void GenerateParsingCode(io::Printer* printer) const = 0;
diff --git a/src/google/protobuf/compiler/java/java_file.cc b/src/google/protobuf/compiler/java/java_file.cc
index 68b47ee1..5e387285 100644
--- a/src/google/protobuf/compiler/java/java_file.cc
+++ b/src/google/protobuf/compiler/java/java_file.cc
@@ -42,6 +42,7 @@
#include <google/protobuf/compiler/java/java_context.h>
#include <google/protobuf/compiler/java/java_enum.h>
+#include <google/protobuf/compiler/java/java_enum_lite.h>
#include <google/protobuf/compiler/java/java_extension.h>
#include <google/protobuf/compiler/java/java_generator_factory.h>
#include <google/protobuf/compiler/java/java_helpers.h>
@@ -176,7 +177,7 @@ void MaybeRestartJavaMethod(io::Printer* printer,
// since otherwise we hit a hardcoded limit in the jvm and javac will
// then fail with the error "code too large". This limit lets our
// estimates be off by a factor of two and still we're okay.
- static const int bytesPerMethod = 1<<15; // aka 32K
+ static const int bytesPerMethod = kMaxStaticSize;
if ((*bytecode_estimate) > bytesPerMethod) {
++(*method_num);
@@ -192,15 +193,17 @@ void MaybeRestartJavaMethod(io::Printer* printer,
} // namespace
-FileGenerator::FileGenerator(const FileDescriptor* file, bool immutable_api)
+FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options,
+ bool immutable_api)
: file_(file),
java_package_(FileJavaPackage(file, immutable_api)),
message_generators_(
new google::protobuf::scoped_ptr<MessageGenerator>[file->message_type_count()]),
extension_generators_(
new google::protobuf::scoped_ptr<ExtensionGenerator>[file->extension_count()]),
- context_(new Context(file)),
+ context_(new Context(file, options)),
name_resolver_(context_->GetNameResolver()),
+ options_(options),
immutable_api_(immutable_api) {
classname_ = name_resolver_->GetFileClassName(file, immutable_api);
generator_factory_.reset(
@@ -250,18 +253,20 @@ void FileGenerator::Generate(io::Printer* printer) {
"\n",
"package", java_package_);
}
+ PrintGeneratedAnnotation(
+ printer, '$', options_.annotate_code ? classname_ + ".java.pb.meta" : "");
printer->Print(
- "public final class $classname$ {\n"
- " private $classname$() {}\n",
- "classname", classname_);
+ "public final class $classname$ {\n"
+ " private $ctor$() {}\n",
+ "classname", classname_, "ctor", classname_);
+ printer->Annotate("classname", file_->name());
printer->Indent();
// -----------------------------------------------------------------
printer->Print(
"public static void registerAllExtensions(\n"
- " com.google.protobuf.ExtensionRegistry$lite$ registry) {\n",
- "lite", HasDescriptorMethods(file_) ? "" : "Lite");
+ " com.google.protobuf.ExtensionRegistryLite registry) {\n");
printer->Indent();
@@ -276,19 +281,38 @@ void FileGenerator::Generate(io::Printer* printer) {
printer->Outdent();
printer->Print(
"}\n");
+ if (HasDescriptorMethods(file_, context_->EnforceLite())) {
+ // Overload registerAllExtensions for the non-lite usage to
+ // redundantly maintain the original signature (this is
+ // redundant because ExtensionRegistryLite now invokes
+ // ExtensionRegistry in the non-lite usage). Intent is
+ // to remove this in the future.
+ printer->Print(
+ "\n"
+ "public static void registerAllExtensions(\n"
+ " com.google.protobuf.ExtensionRegistry registry) {\n"
+ " registerAllExtensions(\n"
+ " (com.google.protobuf.ExtensionRegistryLite) registry);\n"
+ "}\n");
+ }
// -----------------------------------------------------------------
if (!MultipleJavaFiles(file_, immutable_api_)) {
for (int i = 0; i < file_->enum_type_count(); i++) {
- EnumGenerator(file_->enum_type(i), immutable_api_, context_.get())
- .Generate(printer);
+ if (HasDescriptorMethods(file_, context_->EnforceLite())) {
+ EnumGenerator(file_->enum_type(i), immutable_api_, context_.get())
+ .Generate(printer);
+ } else {
+ EnumLiteGenerator(file_->enum_type(i), immutable_api_, context_.get())
+ .Generate(printer);
+ }
}
for (int i = 0; i < file_->message_type_count(); i++) {
message_generators_[i]->GenerateInterface(printer);
message_generators_[i]->Generate(printer);
}
- if (HasGenericServices(file_)) {
+ if (HasGenericServices(file_, context_->EnforceLite())) {
for (int i = 0; i < file_->service_count(); i++) {
google::protobuf::scoped_ptr<ServiceGenerator> generator(
generator_factory_->NewServiceGenerator(file_->service(i)));
@@ -303,14 +327,18 @@ void FileGenerator::Generate(io::Printer* printer) {
extension_generators_[i]->Generate(printer);
}
- // Static variables.
+ // Static variables. We'd like them to be final if possible, but due to
+ // the JVM's 64k size limit on static blocks, we have to initialize some
+ // of them in methods; thus they cannot be final.
+ int static_block_bytecode_estimate = 0;
for (int i = 0; i < file_->message_type_count(); i++) {
- message_generators_[i]->GenerateStaticVariables(printer);
+ message_generators_[i]->GenerateStaticVariables(
+ printer, &static_block_bytecode_estimate);
}
printer->Print("\n");
- if (HasDescriptorMethods(file_)) {
+ if (HasDescriptorMethods(file_, context_->EnforceLite())) {
if (immutable_api_) {
GenerateDescriptorInitializationCodeForImmutable(printer);
} else {
@@ -352,12 +380,14 @@ void FileGenerator::GenerateDescriptorInitializationCodeForImmutable(
" getDescriptor() {\n"
" return descriptor;\n"
"}\n"
- "private static com.google.protobuf.Descriptors.FileDescriptor\n"
+ "private static $final$ com.google.protobuf.Descriptors.FileDescriptor\n"
" descriptor;\n"
- "static {\n");
+ "static {\n",
+ // TODO(dweis): Mark this as final.
+ "final", "");
printer->Indent();
- SharedCodeGenerator shared_code_generator(file_);
+ SharedCodeGenerator shared_code_generator(file_, options_);
shared_code_generator.GenerateDescriptors(printer);
int bytecode_estimate = 0;
@@ -447,7 +477,7 @@ void FileGenerator::GenerateDescriptorInitializationCodeForMutable(io::Printer*
" getDescriptor() {\n"
" return descriptor;\n"
"}\n"
- "private static com.google.protobuf.Descriptors.FileDescriptor\n"
+ "private static final com.google.protobuf.Descriptors.FileDescriptor\n"
" descriptor;\n"
"static {\n");
printer->Indent();
@@ -508,20 +538,26 @@ void FileGenerator::GenerateDescriptorInitializationCodeForMutable(io::Printer*
"}\n");
}
-template<typename GeneratorClass, typename DescriptorClass>
+template <typename GeneratorClass, typename DescriptorClass>
static void GenerateSibling(const string& package_dir,
const string& java_package,
const DescriptorClass* descriptor,
GeneratorContext* context,
- vector<string>* file_list,
+ vector<string>* file_list, bool annotate_code,
+ vector<string>* annotation_list,
const string& name_suffix,
GeneratorClass* generator,
void (GeneratorClass::*pfn)(io::Printer* printer)) {
string filename = package_dir + descriptor->name() + name_suffix + ".java";
file_list->push_back(filename);
+ string info_full_path = filename + ".pb.meta";
+ GeneratedCodeInfo annotations;
+ io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector(
+ &annotations);
google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(context->Open(filename));
- io::Printer printer(output.get(), '$');
+ io::Printer printer(output.get(), '$',
+ annotate_code ? &annotation_collector : NULL);
printer.Print(
"// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
@@ -536,45 +572,57 @@ static void GenerateSibling(const string& package_dir,
}
(generator->*pfn)(&printer);
+
+ if (annotate_code) {
+ google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> info_output(
+ context->Open(info_full_path));
+ annotations.SerializeToZeroCopyStream(info_output.get());
+ annotation_list->push_back(info_full_path);
+ }
}
void FileGenerator::GenerateSiblings(const string& package_dir,
GeneratorContext* context,
- vector<string>* file_list) {
+ vector<string>* file_list,
+ vector<string>* annotation_list) {
if (MultipleJavaFiles(file_, immutable_api_)) {
for (int i = 0; i < file_->enum_type_count(); i++) {
- EnumGenerator generator(file_->enum_type(i), immutable_api_,
- context_.get());
- GenerateSibling<EnumGenerator>(package_dir, java_package_,
- file_->enum_type(i),
- context, file_list, "",
- &generator,
- &EnumGenerator::Generate);
+ if (HasDescriptorMethods(file_, context_->EnforceLite())) {
+ EnumGenerator generator(file_->enum_type(i), immutable_api_,
+ context_.get());
+ GenerateSibling<EnumGenerator>(
+ package_dir, java_package_, file_->enum_type(i), context, file_list,
+ options_.annotate_code, annotation_list, "", &generator,
+ &EnumGenerator::Generate);
+ } else {
+ EnumLiteGenerator generator(file_->enum_type(i), immutable_api_,
+ context_.get());
+ GenerateSibling<EnumLiteGenerator>(
+ package_dir, java_package_, file_->enum_type(i), context, file_list,
+ options_.annotate_code, annotation_list, "", &generator,
+ &EnumLiteGenerator::Generate);
+ }
}
for (int i = 0; i < file_->message_type_count(); i++) {
if (immutable_api_) {
- GenerateSibling<MessageGenerator>(package_dir, java_package_,
- file_->message_type(i),
- context, file_list,
- "OrBuilder",
- message_generators_[i].get(),
- &MessageGenerator::GenerateInterface);
+ GenerateSibling<MessageGenerator>(
+ package_dir, java_package_, file_->message_type(i), context,
+ file_list, options_.annotate_code, annotation_list, "OrBuilder",
+ message_generators_[i].get(), &MessageGenerator::GenerateInterface);
}
- GenerateSibling<MessageGenerator>(package_dir, java_package_,
- file_->message_type(i),
- context, file_list, "",
- message_generators_[i].get(),
- &MessageGenerator::Generate);
+ GenerateSibling<MessageGenerator>(
+ package_dir, java_package_, file_->message_type(i), context,
+ file_list, options_.annotate_code, annotation_list, "",
+ message_generators_[i].get(), &MessageGenerator::Generate);
}
- if (HasGenericServices(file_)) {
+ if (HasGenericServices(file_, context_->EnforceLite())) {
for (int i = 0; i < file_->service_count(); i++) {
google::protobuf::scoped_ptr<ServiceGenerator> generator(
generator_factory_->NewServiceGenerator(file_->service(i)));
- GenerateSibling<ServiceGenerator>(package_dir, java_package_,
- file_->service(i),
- context, file_list, "",
- generator.get(),
- &ServiceGenerator::Generate);
+ GenerateSibling<ServiceGenerator>(
+ package_dir, java_package_, file_->service(i), context, file_list,
+ options_.annotate_code, annotation_list, "", generator.get(),
+ &ServiceGenerator::Generate);
}
}
}
diff --git a/src/google/protobuf/compiler/java/java_file.h b/src/google/protobuf/compiler/java/java_file.h
index 080b3424..1e643f79 100644
--- a/src/google/protobuf/compiler/java/java_file.h
+++ b/src/google/protobuf/compiler/java/java_file.h
@@ -42,6 +42,7 @@
#include <string>
#include <vector>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/compiler/java/java_options.h>
namespace google {
namespace protobuf {
@@ -67,7 +68,8 @@ namespace java {
class FileGenerator {
public:
- FileGenerator(const FileDescriptor* file, bool immutable_api = true);
+ FileGenerator(const FileDescriptor* file, const Options& options,
+ bool immutable_api = true);
~FileGenerator();
// Checks for problems that would otherwise lead to cryptic compile errors.
@@ -82,12 +84,12 @@ class FileGenerator {
// service type).
void GenerateSiblings(const string& package_dir,
GeneratorContext* generator_context,
- vector<string>* file_list);
+ vector<string>* file_list,
+ vector<string>* annotation_list);
const string& java_package() { return java_package_; }
const string& classname() { return classname_; }
-
private:
void GenerateDescriptorInitializationCodeForImmutable(io::Printer* printer);
void GenerateDescriptorInitializationCodeForMutable(io::Printer* printer);
@@ -104,9 +106,9 @@ class FileGenerator {
google::protobuf::scoped_ptr<GeneratorFactory> generator_factory_;
google::protobuf::scoped_ptr<Context> context_;
ClassNameResolver* name_resolver_;
+ const Options options_;
bool immutable_api_;
-
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileGenerator);
};
diff --git a/src/google/protobuf/compiler/java/java_generator.cc b/src/google/protobuf/compiler/java/java_generator.cc
index 6c6f7286..b1ab4043 100644
--- a/src/google/protobuf/compiler/java/java_generator.cc
+++ b/src/google/protobuf/compiler/java/java_generator.cc
@@ -42,6 +42,7 @@
#include <google/protobuf/compiler/java/java_file.h>
#include <google/protobuf/compiler/java/java_generator_factory.h>
#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/compiler/java/java_options.h>
#include <google/protobuf/compiler/java/java_shared_code_generator.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream.h>
@@ -64,51 +65,58 @@ bool JavaGenerator::Generate(const FileDescriptor* file,
// -----------------------------------------------------------------
// parse generator options
- // Name a file where we will write a list of generated file names, one
- // per line.
- string output_list_file;
-
vector<pair<string, string> > options;
ParseGeneratorParameter(parameter, &options);
+ Options file_options;
- bool generate_immutable_code = false;
- bool generate_mutable_code = false;
- bool generate_shared_code = false;
for (int i = 0; i < options.size(); i++) {
if (options[i].first == "output_list_file") {
- output_list_file = options[i].second;
+ file_options.output_list_file = options[i].second;
} else if (options[i].first == "immutable") {
- generate_immutable_code = true;
+ file_options.generate_immutable_code = true;
} else if (options[i].first == "mutable") {
- generate_mutable_code = true;
+ file_options.generate_mutable_code = true;
} else if (options[i].first == "shared") {
- generate_shared_code = true;
+ file_options.generate_shared_code = true;
+ } else if (options[i].first == "annotate_code") {
+ file_options.annotate_code = true;
+ } else if (options[i].first == "annotation_list_file") {
+ file_options.annotation_list_file = options[i].second;
} else {
*error = "Unknown generator option: " + options[i].first;
return false;
}
}
+ if (file_options.enforce_lite && file_options.generate_mutable_code) {
+ *error = "lite runtime generator option cannot be used with mutable API.";
+ return false;
+ }
+
// By default we generate immutable code and shared code for immutable API.
- if (!generate_immutable_code && !generate_mutable_code &&
- !generate_shared_code) {
- generate_immutable_code = true;
- generate_shared_code = true;
+ if (!file_options.generate_immutable_code &&
+ !file_options.generate_mutable_code &&
+ !file_options.generate_shared_code) {
+ file_options.generate_immutable_code = true;
+ file_options.generate_shared_code = true;
}
// -----------------------------------------------------------------
vector<string> all_files;
+ vector<string> all_annotations;
vector<FileGenerator*> file_generators;
- if (generate_immutable_code) {
- file_generators.push_back(new FileGenerator(file, /* immutable = */ true));
+ if (file_options.generate_immutable_code) {
+ file_generators.push_back(new FileGenerator(file, file_options,
+ /* immutable = */ true));
}
- if (generate_mutable_code) {
- file_generators.push_back(new FileGenerator(file, /* mutable = */ false));
+ if (file_options.generate_mutable_code) {
+ file_generators.push_back(new FileGenerator(file, file_options,
+ /* mutable = */ false));
}
for (int i = 0; i < file_generators.size(); ++i) {
if (!file_generators[i]->Validate(error)) {
@@ -128,15 +136,32 @@ bool JavaGenerator::Generate(const FileDescriptor* file,
java_filename += file_generator->classname();
java_filename += ".java";
all_files.push_back(java_filename);
+ string info_full_path = java_filename + ".pb.meta";
+ if (file_options.annotate_code) {
+ all_annotations.push_back(info_full_path);
+ }
// Generate main java file.
google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(
context->Open(java_filename));
- io::Printer printer(output.get(), '$');
+ GeneratedCodeInfo annotations;
+ io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector(
+ &annotations);
+ io::Printer printer(output.get(), '$', file_options.annotate_code
+ ? &annotation_collector
+ : NULL);
+
file_generator->Generate(&printer);
// Generate sibling files.
- file_generator->GenerateSiblings(package_dir, context, &all_files);
+ file_generator->GenerateSiblings(package_dir, context, &all_files,
+ &all_annotations);
+
+ if (file_options.annotate_code) {
+ google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> info_output(
+ context->Open(info_full_path));
+ annotations.SerializeToZeroCopyStream(info_output.get());
+ }
}
for (int i = 0; i < file_generators.size(); ++i) {
@@ -145,17 +170,29 @@ bool JavaGenerator::Generate(const FileDescriptor* file,
file_generators.clear();
// Generate output list if requested.
- if (!output_list_file.empty()) {
+ if (!file_options.output_list_file.empty()) {
// Generate output list. This is just a simple text file placed in a
// deterministic location which lists the .java files being generated.
google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> srclist_raw_output(
- context->Open(output_list_file));
+ context->Open(file_options.output_list_file));
io::Printer srclist_printer(srclist_raw_output.get(), '$');
for (int i = 0; i < all_files.size(); i++) {
srclist_printer.Print("$filename$\n", "filename", all_files[i]);
}
}
+ if (!file_options.annotation_list_file.empty()) {
+ // Generate output list. This is just a simple text file placed in a
+ // deterministic location which lists the .java files being generated.
+ google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> annotation_list_raw_output(
+ context->Open(file_options.annotation_list_file));
+ io::Printer annotation_list_printer(annotation_list_raw_output.get(), '$');
+ for (int i = 0; i < all_annotations.size(); i++) {
+ annotation_list_printer.Print("$filename$\n", "filename",
+ all_annotations[i]);
+ }
+ }
+
return true;
}
diff --git a/src/google/protobuf/compiler/java/java_generator_factory.cc b/src/google/protobuf/compiler/java/java_generator_factory.cc
index 92ef851b..3218b410 100644
--- a/src/google/protobuf/compiler/java/java_generator_factory.cc
+++ b/src/google/protobuf/compiler/java/java_generator_factory.cc
@@ -35,6 +35,7 @@
#include <google/protobuf/compiler/java/java_context.h>
#include <google/protobuf/compiler/java/java_enum_field.h>
#include <google/protobuf/compiler/java/java_extension.h>
+#include <google/protobuf/compiler/java/java_extension_lite.h>
#include <google/protobuf/compiler/java/java_field.h>
#include <google/protobuf/compiler/java/java_helpers.h>
#include <google/protobuf/compiler/java/java_message.h>
@@ -58,17 +59,20 @@ ImmutableGeneratorFactory::~ImmutableGeneratorFactory() {}
MessageGenerator* ImmutableGeneratorFactory::NewMessageGenerator(
const Descriptor* descriptor) const {
- if (descriptor->file()->options().optimize_for() ==
- FileOptions::LITE_RUNTIME) {
- return new ImmutableMessageLiteGenerator(descriptor, context_);
- } else {
+ if (HasDescriptorMethods(descriptor, context_->EnforceLite())) {
return new ImmutableMessageGenerator(descriptor, context_);
+ } else {
+ return new ImmutableMessageLiteGenerator(descriptor, context_);
}
}
ExtensionGenerator* ImmutableGeneratorFactory::NewExtensionGenerator(
const FieldDescriptor* descriptor) const {
- return new ImmutableExtensionGenerator(descriptor, context_);
+ if (HasDescriptorMethods(descriptor->file(), context_->EnforceLite())) {
+ return new ImmutableExtensionGenerator(descriptor, context_);
+ } else {
+ return new ImmutableExtensionLiteGenerator(descriptor, context_);
+ }
}
ServiceGenerator* ImmutableGeneratorFactory::NewServiceGenerator(
diff --git a/src/google/protobuf/compiler/java/java_helpers.cc b/src/google/protobuf/compiler/java/java_helpers.cc
index e24894b1..c31df265 100644
--- a/src/google/protobuf/compiler/java/java_helpers.cc
+++ b/src/google/protobuf/compiler/java/java_helpers.cc
@@ -101,6 +101,20 @@ string FieldName(const FieldDescriptor* field) {
} // namespace
+void PrintGeneratedAnnotation(io::Printer* printer, char delimiter,
+ const string& annotation_file) {
+ if (annotation_file.empty()) {
+ return;
+ }
+ string ptemplate =
+ "@javax.annotation.Generated(value=\"protoc\", comments=\"annotations:";
+ ptemplate.push_back(delimiter);
+ ptemplate.append("annotation_file");
+ ptemplate.push_back(delimiter);
+ ptemplate.append("\")\n");
+ printer->Print(ptemplate.c_str(), "annotation_file", annotation_file);
+}
+
string UnderscoresToCamelCase(const string& input, bool cap_next_letter) {
string result;
// Note: I distrust ctype.h due to locales.
@@ -481,9 +495,9 @@ bool IsDefaultValueJavaDefault(const FieldDescriptor* field) {
return field->default_value_float() == 0.0;
case FieldDescriptor::CPPTYPE_BOOL:
return field->default_value_bool() == false;
-
- case FieldDescriptor::CPPTYPE_STRING:
case FieldDescriptor::CPPTYPE_ENUM:
+ return field->default_value_enum()->number() == 0;
+ case FieldDescriptor::CPPTYPE_STRING:
case FieldDescriptor::CPPTYPE_MESSAGE:
return false;
@@ -495,6 +509,11 @@ bool IsDefaultValueJavaDefault(const FieldDescriptor* field) {
return false;
}
+bool IsByteStringWithCustomDefaultValue(const FieldDescriptor* field) {
+ return GetJavaType(field) == JAVATYPE_BYTES &&
+ field->default_value_string() != "";
+}
+
const char* bit_masks[] = {
"0x00000001",
"0x00000002",
diff --git a/src/google/protobuf/compiler/java/java_helpers.h b/src/google/protobuf/compiler/java/java_helpers.h
index 5392d6d7..829ec3d7 100644
--- a/src/google/protobuf/compiler/java/java_helpers.h
+++ b/src/google/protobuf/compiler/java/java_helpers.h
@@ -36,6 +36,8 @@
#define GOOGLE_PROTOBUF_COMPILER_JAVA_HELPERS_H__
#include <string>
+#include <google/protobuf/compiler/java/java_context.h>
+#include <google/protobuf/io/printer.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/descriptor.h>
@@ -49,6 +51,17 @@ namespace java {
extern const char kThickSeparator[];
extern const char kThinSeparator[];
+// If annotation_file is non-empty, prints a javax.annotation.Generated
+// annotation to the given Printer. annotation_file will be referenced in the
+// annotation's comments field. delimiter should be the Printer's delimiter
+// character. annotation_file will be included verbatim into a Java literal
+// string, so it should not contain quotes or invalid Java escape sequences;
+// however, these are unlikely to appear in practice, as the value of
+// annotation_file should be generated from the filename of the source file
+// being annotated (which in turn must be a Java identifier plus ".java").
+void PrintGeneratedAnnotation(io::Printer* printer, char delimiter = '$',
+ const string& annotation_file = "");
+
// Converts a name to camel-case. If cap_first_letter is true, capitalize the
// first letter.
string UnderscoresToCamelCase(const string& name, bool cap_first_letter);
@@ -126,6 +139,38 @@ inline bool MultipleJavaFiles(
return descriptor->options().java_multiple_files();
}
+// Returns true if `descriptor` will be written to its own .java file.
+// `immutable` should be set to true if we're generating for the immutable API.
+template <typename Descriptor>
+bool IsOwnFile(const Descriptor* descriptor, bool immutable) {
+ return descriptor->containing_type() == NULL &&
+ MultipleJavaFiles(descriptor->file(), immutable);
+}
+
+template <>
+inline bool IsOwnFile(const ServiceDescriptor* descriptor, bool immutable) {
+ return MultipleJavaFiles(descriptor->file(), immutable);
+}
+
+// If `descriptor` describes an object with its own .java file,
+// returns the name (relative to that .java file) of the file that stores
+// annotation data for that descriptor. `suffix` is usually empty, but may
+// (e.g.) be "OrBuilder" for some generated interfaces.
+template <typename Descriptor>
+string AnnotationFileName(const Descriptor* descriptor, const string& suffix) {
+ return descriptor->name() + suffix + ".java.pb.meta";
+}
+
+template <typename Descriptor>
+void MaybePrintGeneratedAnnotation(Context* context, io::Printer* printer,
+ Descriptor* descriptor, bool immutable,
+ const string& suffix = "") {
+ if (context->options().annotate_code && IsOwnFile(descriptor, immutable)) {
+ PrintGeneratedAnnotation(printer, '$',
+ AnnotationFileName(descriptor, suffix));
+ }
+}
+
// Get the unqualified name that should be used for a field's field
// number constant.
string FieldConstantName(const FieldDescriptor *field);
@@ -169,45 +214,38 @@ inline string ImmutableDefaultValue(const FieldDescriptor* field,
return DefaultValue(field, true, name_resolver);
}
bool IsDefaultValueJavaDefault(const FieldDescriptor* field);
-
-// Does this message class have generated parsing, serialization, and other
-// standard methods for which reflection-based fallback implementations exist?
-inline bool HasGeneratedMethods(const Descriptor* descriptor) {
- return descriptor->file()->options().optimize_for() !=
- FileOptions::CODE_SIZE;
-}
-
-// Does this message have specialized equals() and hashCode() methods?
-inline bool HasEqualsAndHashCode(const Descriptor* descriptor) {
- return descriptor->file()->options().java_generate_equals_and_hash();
-}
+bool IsByteStringWithCustomDefaultValue(const FieldDescriptor* field);
// Does this message class have descriptor and reflection methods?
-inline bool HasDescriptorMethods(const Descriptor* descriptor) {
- return descriptor->file()->options().optimize_for() !=
- FileOptions::LITE_RUNTIME;
+inline bool HasDescriptorMethods(const Descriptor* descriptor,
+ bool enforce_lite) {
+ return !enforce_lite &&
+ descriptor->file()->options().optimize_for() !=
+ FileOptions::LITE_RUNTIME;
}
-inline bool HasDescriptorMethods(const EnumDescriptor* descriptor) {
- return descriptor->file()->options().optimize_for() !=
- FileOptions::LITE_RUNTIME;
+inline bool HasDescriptorMethods(const EnumDescriptor* descriptor,
+ bool enforce_lite) {
+ return !enforce_lite &&
+ descriptor->file()->options().optimize_for() !=
+ FileOptions::LITE_RUNTIME;
}
-inline bool HasDescriptorMethods(const FileDescriptor* descriptor) {
- return descriptor->options().optimize_for() !=
- FileOptions::LITE_RUNTIME;
+inline bool HasDescriptorMethods(const FileDescriptor* descriptor,
+ bool enforce_lite) {
+ return !enforce_lite &&
+ descriptor->options().optimize_for() != FileOptions::LITE_RUNTIME;
}
// Should we generate generic services for this file?
-inline bool HasGenericServices(const FileDescriptor *file) {
+inline bool HasGenericServices(const FileDescriptor *file, bool enforce_lite) {
return file->service_count() > 0 &&
- file->options().optimize_for() != FileOptions::LITE_RUNTIME &&
+ HasDescriptorMethods(file, enforce_lite) &&
file->options().java_generic_services();
}
-inline bool IsLazy(const FieldDescriptor* descriptor) {
- // Currently, the proto-lite version suports lazy field.
+inline bool IsLazy(const FieldDescriptor* descriptor, bool enforce_lite) {
+ // Currently, the proto-lite version supports lazy field.
// TODO(niwasaki): Support lazy fields also for other proto runtimes.
- if (descriptor->file()->options().optimize_for() !=
- FileOptions::LITE_RUNTIME) {
+ if (HasDescriptorMethods(descriptor->file(), enforce_lite)) {
return false;
}
return descriptor->options().lazy();
@@ -347,6 +385,9 @@ inline bool CheckUtf8(const FieldDescriptor* descriptor) {
descriptor->file()->options().java_string_check_utf8();
}
+inline string GeneratedCodeVersionSuffix() {
+ return "V3";
+}
} // namespace java
} // namespace compiler
} // namespace protobuf
diff --git a/src/google/protobuf/compiler/java/java_lazy_message_field.cc b/src/google/protobuf/compiler/java/java_lazy_message_field.cc
index 0de8cbe5..abf8e55c 100644
--- a/src/google/protobuf/compiler/java/java_lazy_message_field.cc
+++ b/src/google/protobuf/compiler/java/java_lazy_message_field.cc
@@ -93,7 +93,7 @@ GenerateBuilderMembers(io::Printer* printer) const {
printer->Print(variables_,
// If this builder is non-null, it is used and the other fields are
// ignored.
- "private com.google.protobuf.SingleFieldBuilder<\n"
+ "private com.google.protobuf.SingleFieldBuilder$ver$<\n"
" $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;"
"\n");
@@ -193,11 +193,11 @@ GenerateBuilderMembers(io::Printer* printer) const {
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
- "private com.google.protobuf.SingleFieldBuilder<\n"
+ "private com.google.protobuf.SingleFieldBuilder$ver$<\n"
" $type$, $type$.Builder, $type$OrBuilder> \n"
" get$capitalized_name$FieldBuilder() {\n"
" if ($name$Builder_ == null) {\n"
- " $name$Builder_ = new com.google.protobuf.SingleFieldBuilder<\n"
+ " $name$Builder_ = new com.google.protobuf.SingleFieldBuilder$ver$<\n"
" $type$, $type$.Builder, $type$OrBuilder>(\n"
" $name$_,\n"
" getParentForChildren(),\n"
@@ -535,7 +535,7 @@ GenerateBuilderMembers(io::Printer* printer) const {
printer->Print(variables_,
// If this builder is non-null, it is used and the other fields are
// ignored.
- "private com.google.protobuf.RepeatedFieldBuilder<\n"
+ "private com.google.protobuf.RepeatedFieldBuilder$ver$<\n"
" $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;\n"
"\n");
@@ -763,11 +763,11 @@ GenerateBuilderMembers(io::Printer* printer) const {
" get$capitalized_name$BuilderList() {\n"
" return get$capitalized_name$FieldBuilder().getBuilderList();\n"
"}\n"
- "private com.google.protobuf.RepeatedFieldBuilder<\n"
+ "private com.google.protobuf.RepeatedFieldBuilder$ver$<\n"
" $type$, $type$.Builder, $type$OrBuilder> \n"
" get$capitalized_name$FieldBuilder() {\n"
" if ($name$Builder_ == null) {\n"
- " $name$Builder_ = new com.google.protobuf.RepeatedFieldBuilder<\n"
+ " $name$Builder_ = new com.google.protobuf.RepeatedFieldBuilder$ver$<\n"
" $type$, $type$.Builder, $type$OrBuilder>(\n"
" $name$_,\n"
" $get_mutable_bit_builder$,\n"
diff --git a/src/google/protobuf/compiler/java/java_lazy_message_field_lite.cc b/src/google/protobuf/compiler/java/java_lazy_message_field_lite.cc
index 283ba1d3..dac1b51f 100644
--- a/src/google/protobuf/compiler/java/java_lazy_message_field_lite.cc
+++ b/src/google/protobuf/compiler/java/java_lazy_message_field_lite.cc
@@ -59,19 +59,28 @@ ImmutableLazyMessageFieldLiteGenerator::
void ImmutableLazyMessageFieldLiteGenerator::
GenerateMembers(io::Printer* printer) const {
printer->Print(variables_,
- "private com.google.protobuf.LazyFieldLite $name$_ =\n"
- " new com.google.protobuf.LazyFieldLite();\n");
+ "private com.google.protobuf.LazyFieldLite $name$_;");
PrintExtraFieldInfo(variables_, printer);
WriteFieldDocComment(printer, descriptor_);
- printer->Print(variables_,
- "$deprecation$public boolean has$capitalized_name$() {\n"
- " return $get_has_field_bit_message$;\n"
- "}\n");
+ if (SupportFieldPresence(descriptor_->file())) {
+ printer->Print(variables_,
+ "$deprecation$public boolean has$capitalized_name$() {\n"
+ " return $get_has_field_bit_message$;\n"
+ "}\n");
+ } else {
+ printer->Print(variables_,
+ "$deprecation$public boolean has$capitalized_name$() {\n"
+ " return $name$_ != null;\n"
+ "}\n");
+ }
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public $type$ get$capitalized_name$() {\n"
+ " if ($name$_ == null) {\n"
+ " return $type$.getDefaultInstance();\n"
+ " }\n"
" return ($type$) $name$_.getValue($type$.getDefaultInstance());\n"
"}\n");
@@ -82,8 +91,11 @@ GenerateMembers(io::Printer* printer) const {
" if (value == null) {\n"
" throw new NullPointerException();\n"
" }\n"
+ " if ($name$_ == null) {\n"
+ " $name$_ = new com.google.protobuf.LazyFieldLite();\n"
+ " }\n"
" $name$_.setValue(value);\n"
- " $set_has_field_bit_message$;\n"
+ " $set_has_field_bit_message$\n"
"}\n");
// Field.Builder setField(Field.Builder builderForValue)
@@ -91,30 +103,36 @@ GenerateMembers(io::Printer* printer) const {
printer->Print(variables_,
"private void set$capitalized_name$(\n"
" $type$.Builder builderForValue) {\n"
+ " if ($name$_ == null) {\n"
+ " $name$_ = new com.google.protobuf.LazyFieldLite();\n"
+ " }\n"
" $name$_.setValue(builderForValue.build());\n"
- " $set_has_field_bit_message$;\n"
+ " $set_has_field_bit_message$\n"
"}\n");
// Field.Builder mergeField(Field value)
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"private void merge$capitalized_name$($type$ value) {\n"
- " if ($get_has_field_bit_message$ &&\n"
+ " if (has$capitalized_name$() &&\n"
" !$name$_.containsDefaultInstance()) {\n"
" $name$_.setValue(\n"
" $type$.newBuilder(\n"
" get$capitalized_name$()).mergeFrom(value).buildPartial());\n"
" } else {\n"
+ " if ($name$_ == null) {\n"
+ " $name$_ = new com.google.protobuf.LazyFieldLite();\n"
+ " }\n"
" $name$_.setValue(value);\n"
+ " $set_has_field_bit_message$\n"
" }\n"
- " $set_has_field_bit_message$;\n"
"}\n");
// Field.Builder clearField()
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"private void clear$capitalized_name$() {\n"
- " $name$_.clear();\n"
+ " $name$_ = null;\n"
" $clear_has_field_bit_message$;\n"
"}\n");
}
@@ -177,32 +195,30 @@ GenerateBuilderMembers(io::Printer* printer) const {
void ImmutableLazyMessageFieldLiteGenerator::
-GenerateInitializationCode(io::Printer* printer) const {
- printer->Print(variables_, "$name$_.clear();\n");
-}
+GenerateInitializationCode(io::Printer* printer) const {}
void ImmutableLazyMessageFieldLiteGenerator::
-GenerateMergingCode(io::Printer* printer) const {
+GenerateVisitCode(io::Printer* printer) const {
printer->Print(variables_,
- "if (other.has$capitalized_name$()) {\n"
- " $name$_.merge(other.$name$_);\n"
- " $set_has_field_bit_message$;\n"
- "}\n");
+ "$name$_ = visitor.visitLazyMessage($name$_, other.$name$_);\n");
}
void ImmutableLazyMessageFieldLiteGenerator::
GenerateParsingCode(io::Printer* printer) const {
printer->Print(variables_,
- "$name$_.setByteString(input.readBytes(), extensionRegistry);\n");
+ "if ($name$_ == null) {\n"
+ " $name$_ = new com.google.protobuf.LazyFieldLite();\n"
+ "}\n"
+ "$name$_.mergeFrom(input, extensionRegistry);\n");
printer->Print(variables_,
- "$set_has_field_bit_message$;\n");
+ "$set_has_field_bit_message$\n");
}
void ImmutableLazyMessageFieldLiteGenerator::
GenerateSerializationCode(io::Printer* printer) const {
// Do not de-serialize lazy fields.
printer->Print(variables_,
- "if ($get_has_field_bit_message$) {\n"
+ "if (has$capitalized_name$()) {\n"
" output.writeBytes($number$, $name$_.toByteString());\n"
"}\n");
}
@@ -210,7 +226,7 @@ GenerateSerializationCode(io::Printer* printer) const {
void ImmutableLazyMessageFieldLiteGenerator::
GenerateSerializedSizeCode(io::Printer* printer) const {
printer->Print(variables_,
- "if ($get_has_field_bit_message$) {\n"
+ "if (has$capitalized_name$()) {\n"
" size += com.google.protobuf.CodedOutputStream\n"
" .computeLazyFieldSize($number$, $name$_);\n"
"}\n");
@@ -362,14 +378,12 @@ GenerateBuilderMembers(io::Printer* printer) const {
}
void ImmutableLazyMessageOneofFieldLiteGenerator::
-GenerateMergingCode(io::Printer* printer) const {
+GenerateVisitCode(io::Printer* printer) const {
printer->Print(variables_,
- "if (!($has_oneof_case_message$)) {\n"
- " $oneof_name$_ = new $lazy_type$();\n"
- "}\n"
- "(($lazy_type$) $oneof_name$_).merge(\n"
- " ($lazy_type$) other.$oneof_name$_);\n"
- "$set_oneof_case_message$;\n");
+ "$oneof_name$_ = visitor.visitOneofLazyMessage(\n"
+ " $has_oneof_case_message$,\n"
+ " ($lazy_type$) $oneof_name$_,\n"
+ " ($lazy_type$) other.$oneof_name$_);\n");
}
void ImmutableLazyMessageOneofFieldLiteGenerator::
@@ -378,8 +392,7 @@ GenerateParsingCode(io::Printer* printer) const {
"if (!($has_oneof_case_message$)) {\n"
" $oneof_name$_ = new $lazy_type$();\n"
"}\n"
- "(($lazy_type$) $oneof_name$_).setByteString(\n"
- " input.readBytes(), extensionRegistry);\n"
+ "(($lazy_type$) $oneof_name$_).mergeFrom(input, extensionRegistry);\n"
"$set_oneof_case_message$;\n");
}
@@ -464,7 +477,8 @@ GenerateMembers(io::Printer* printer) const {
printer->Print(variables_,
"private void ensure$capitalized_name$IsMutable() {\n"
" if (!$is_mutable$) {\n"
- " $name$_ = newProtobufList($name$_);\n"
+ " $name$_ =\n"
+ " com.google.protobuf.GeneratedMessageLite.mutableCopy($name$_);\n"
" }\n"
"}\n"
"\n");
@@ -679,7 +693,8 @@ void RepeatedImmutableLazyMessageFieldLiteGenerator::
GenerateParsingCode(io::Printer* printer) const {
printer->Print(variables_,
"if (!$is_mutable$) {\n"
- " $name$_ = newProtobufList();\n"
+ " $name$_ =\n"
+ " com.google.protobuf.GeneratedMessageLite.mutableCopy($name$_);\n"
"}\n"
"$name$_.add(new com.google.protobuf.LazyFieldLite(\n"
" extensionRegistry, input.readBytes()));\n");
diff --git a/src/google/protobuf/compiler/java/java_lazy_message_field_lite.h b/src/google/protobuf/compiler/java/java_lazy_message_field_lite.h
index e85ec0f3..47ebeb49 100644
--- a/src/google/protobuf/compiler/java/java_lazy_message_field_lite.h
+++ b/src/google/protobuf/compiler/java/java_lazy_message_field_lite.h
@@ -63,7 +63,7 @@ class ImmutableLazyMessageFieldLiteGenerator
void GenerateMembers(io::Printer* printer) const;
void GenerateBuilderMembers(io::Printer* printer) const;
void GenerateInitializationCode(io::Printer* printer) const;
- void GenerateMergingCode(io::Printer* printer) const;
+ void GenerateVisitCode(io::Printer* printer) const;
void GenerateParsingCode(io::Printer* printer) const;
void GenerateSerializationCode(io::Printer* printer) const;
void GenerateSerializedSizeCode(io::Printer* printer) const;
@@ -82,7 +82,7 @@ class ImmutableLazyMessageOneofFieldLiteGenerator
void GenerateMembers(io::Printer* printer) const;
void GenerateBuilderMembers(io::Printer* printer) const;
- void GenerateMergingCode(io::Printer* printer) const;
+ void GenerateVisitCode(io::Printer* printer) const;
void GenerateParsingCode(io::Printer* printer) const;
void GenerateSerializationCode(io::Printer* printer) const;
void GenerateSerializedSizeCode(io::Printer* printer) const;
diff --git a/src/google/protobuf/compiler/java/java_map_field.cc b/src/google/protobuf/compiler/java/java_map_field.cc
index 3e035c89..16c5bec5 100644
--- a/src/google/protobuf/compiler/java/java_map_field.cc
+++ b/src/google/protobuf/compiler/java/java_map_field.cc
@@ -79,19 +79,27 @@ void SetMessageVariables(const FieldDescriptor* descriptor,
int messageBitIndex,
int builderBitIndex,
const FieldGeneratorInfo* info,
- ClassNameResolver* name_resolver,
+ Context* context,
map<string, string>* variables) {
SetCommonFieldVariables(descriptor, info, variables);
+ ClassNameResolver* name_resolver = context->GetNameResolver();
(*variables)["type"] =
name_resolver->GetImmutableClassName(descriptor->message_type());
const FieldDescriptor* key = KeyField(descriptor);
const FieldDescriptor* value = ValueField(descriptor);
+ const JavaType keyJavaType = GetJavaType(key);
+ const JavaType valueJavaType = GetJavaType(value);
+
(*variables)["key_type"] = TypeName(key, name_resolver, false);
(*variables)["boxed_key_type"] = TypeName(key, name_resolver, true);
(*variables)["key_wire_type"] = WireType(key);
(*variables)["key_default_value"] = DefaultValue(key, true, name_resolver);
- if (GetJavaType(value) == JAVATYPE_ENUM) {
+ (*variables)["key_null_check"] = IsReferenceType(keyJavaType) ?
+ "if (key == null) { throw new java.lang.NullPointerException(); }" : "";
+ (*variables)["value_null_check"] = IsReferenceType(valueJavaType) ?
+ "if (value == null) { throw new java.lang.NullPointerException(); }" : "";
+ if (valueJavaType == JAVATYPE_ENUM) {
// We store enums as Integers internally.
(*variables)["value_type"] = "int";
(*variables)["boxed_value_type"] = "java.lang.Integer";
@@ -123,8 +131,7 @@ void SetMessageVariables(const FieldDescriptor* descriptor,
// by the proto compiler
(*variables)["deprecation"] = descriptor->options().deprecated()
? "@java.lang.Deprecated " : "";
- (*variables)["on_changed"] =
- HasDescriptorMethods(descriptor->containing_type()) ? "onChanged();" : "";
+ (*variables)["on_changed"] = "onChanged();";
// For repeated fields, one bit is used for whether the array is immutable
// in the parsing constructor.
@@ -135,18 +142,11 @@ void SetMessageVariables(const FieldDescriptor* descriptor,
(*variables)["default_entry"] = (*variables)["capitalized_name"] +
"DefaultEntryHolder.defaultEntry";
- if (HasDescriptorMethods(descriptor->file())) {
- (*variables)["lite"] = "";
- (*variables)["map_field_parameter"] = (*variables)["default_entry"];
- (*variables)["descriptor"] =
- name_resolver->GetImmutableClassName(descriptor->file()) +
- ".internal_" + UniqueFileScopeIdentifier(descriptor->message_type()) +
- "_descriptor, ";
- } else {
- (*variables)["lite"] = "Lite";
- (*variables)["map_field_parameter"] = "";
- (*variables)["descriptor"] = "";
- }
+ (*variables)["map_field_parameter"] = (*variables)["default_entry"];
+ (*variables)["descriptor"] =
+ name_resolver->GetImmutableClassName(descriptor->file()) +
+ ".internal_" + UniqueFileScopeIdentifier(descriptor->message_type()) +
+ "_descriptor, ";
}
} // namespace
@@ -159,7 +159,7 @@ ImmutableMapFieldGenerator(const FieldDescriptor* descriptor,
: descriptor_(descriptor), name_resolver_(context->GetNameResolver()) {
SetMessageVariables(descriptor, messageBitIndex, builderBitIndex,
context->GetFieldGeneratorInfo(descriptor),
- name_resolver_, &variables_);
+ context, &variables_);
}
ImmutableMapFieldGenerator::
@@ -175,25 +175,95 @@ int ImmutableMapFieldGenerator::GetNumBitsForBuilder() const {
void ImmutableMapFieldGenerator::
GenerateInterfaceMembers(io::Printer* printer) const {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$int get$capitalized_name$Count();\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$boolean contains$capitalized_name$(\n"
+ " $key_type$ key);\n");
if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
+ printer->Print(
+ variables_,
+ "/**\n"
+ " * Use {@link #get$capitalized_name$Map()} instead.\n"
+ " */\n"
+ "@java.lang.Deprecated\n"
+ "java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
+ "get$capitalized_name$();\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(
variables_,
"$deprecation$java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
- "get$capitalized_name$();\n");
+ "get$capitalized_name$Map();\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$$value_enum_type$ get$capitalized_name$OrDefault(\n"
+ " $key_type$ key,\n"
+ " $value_enum_type$ defaultValue);\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$$value_enum_type$ get$capitalized_name$OrThrow(\n"
+ " $key_type$ key);\n");
if (SupportUnknownEnumValue(descriptor_->file())) {
+ printer->Print(
+ variables_,
+ "/**\n"
+ " * Use {@link #get$capitalized_name$ValueMap()} instead.\n"
+ " */\n"
+ "@java.lang.Deprecated\n"
+ "java.util.Map<$type_parameters$>\n"
+ "get$capitalized_name$Value();\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(
variables_,
"$deprecation$java.util.Map<$type_parameters$>\n"
- "get$capitalized_name$Value();\n");
+ "get$capitalized_name$ValueMap();\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$\n"
+ "$value_type$ get$capitalized_name$ValueOrDefault(\n"
+ " $key_type$ key,\n"
+ " $value_type$ defaultValue);\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$\n"
+ "$value_type$ get$capitalized_name$ValueOrThrow(\n"
+ " $key_type$ key);\n");
}
} else {
+ printer->Print(
+ variables_,
+ "/**\n"
+ " * Use {@link #get$capitalized_name$Map()} instead.\n"
+ " */\n"
+ "@java.lang.Deprecated\n"
+ "java.util.Map<$type_parameters$>\n"
+ "get$capitalized_name$();\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(
variables_,
"$deprecation$java.util.Map<$type_parameters$>\n"
- "get$capitalized_name$();\n");
+ "get$capitalized_name$Map();\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$\n"
+ "$value_type$ get$capitalized_name$OrDefault(\n"
+ " $key_type$ key,\n"
+ " $value_type$ defaultValue);\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$\n"
+ "$value_type$ get$capitalized_name$OrThrow(\n"
+ " $key_type$ key);\n");
}
}
@@ -202,9 +272,9 @@ GenerateMembers(io::Printer* printer) const {
printer->Print(
variables_,
"private static final class $capitalized_name$DefaultEntryHolder {\n"
- " static final com.google.protobuf.MapEntry$lite$<\n"
+ " static final com.google.protobuf.MapEntry<\n"
" $type_parameters$> defaultEntry =\n"
- " com.google.protobuf.MapEntry$lite$\n"
+ " com.google.protobuf.MapEntry\n"
" .<$type_parameters$>newDefaultInstance(\n"
" $descriptor$\n"
" $key_wire_type$,\n"
@@ -214,14 +284,14 @@ GenerateMembers(io::Printer* printer) const {
"}\n");
printer->Print(
variables_,
- "private com.google.protobuf.MapField$lite$<\n"
+ "private com.google.protobuf.MapField<\n"
" $type_parameters$> $name$_;\n"
- "private com.google.protobuf.MapField$lite$<$type_parameters$>\n"
+ "private com.google.protobuf.MapField<$type_parameters$>\n"
"internalGet$capitalized_name$() {\n"
" if ($name$_ == null) {\n"
- " return com.google.protobuf.MapField$lite$.emptyMapField(\n"
+ " return com.google.protobuf.MapField.emptyMapField(\n"
" $map_field_parameter$);\n"
- " }\n"
+ " }\n"
" return $name$_;\n"
"}\n");
if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
@@ -233,57 +303,29 @@ GenerateMembers(io::Printer* printer) const {
" com.google.protobuf.Internal.MapAdapter.newEnumConverter(\n"
" $value_enum_type$.internalGetValueMap(),\n"
" $unrecognized_value$);\n");
- if (SupportUnknownEnumValue(descriptor_->file())) {
- WriteFieldDocComment(printer, descriptor_);
- printer->Print(
- variables_,
- "$deprecation$\n"
- "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
- "get$capitalized_name$Value() {\n"
- " return internalGet$capitalized_name$().getMap();\n"
- "}\n");
- }
- WriteFieldDocComment(printer, descriptor_);
- printer->Print(
- variables_,
- "$deprecation$\n"
- "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
- "get$capitalized_name$() {\n"
- " return new com.google.protobuf.Internal.MapAdapter<\n"
- " $boxed_key_type$, $value_enum_type$, java.lang.Integer>(\n"
- " internalGet$capitalized_name$().getMap(),\n"
- " $name$ValueConverter);\n"
- "}\n");
- } else {
- WriteFieldDocComment(printer, descriptor_);
- printer->Print(
- variables_,
- "$deprecation$\n"
- "public java.util.Map<$type_parameters$> get$capitalized_name$() {\n"
- " return internalGet$capitalized_name$().getMap();\n"
- "}\n");
}
+ GenerateMapGetters(printer);
}
void ImmutableMapFieldGenerator::
GenerateBuilderMembers(io::Printer* printer) const {
printer->Print(
variables_,
- "private com.google.protobuf.MapField$lite$<\n"
+ "private com.google.protobuf.MapField<\n"
" $type_parameters$> $name$_;\n"
- "private com.google.protobuf.MapField$lite$<$type_parameters$>\n"
+ "private com.google.protobuf.MapField<$type_parameters$>\n"
"internalGet$capitalized_name$() {\n"
" if ($name$_ == null) {\n"
- " return com.google.protobuf.MapField$lite$.emptyMapField(\n"
+ " return com.google.protobuf.MapField.emptyMapField(\n"
" $map_field_parameter$);\n"
- " }\n"
+ " }\n"
" return $name$_;\n"
"}\n"
- "private com.google.protobuf.MapField$lite$<$type_parameters$>\n"
+ "private com.google.protobuf.MapField<$type_parameters$>\n"
"internalGetMutable$capitalized_name$() {\n"
" $on_changed$;\n"
" if ($name$_ == null) {\n"
- " $name$_ = com.google.protobuf.MapField$lite$.newMapField(\n"
+ " $name$_ = com.google.protobuf.MapField.newMapField(\n"
" $map_field_parameter$);\n"
" }\n"
" if (!$name$_.isMutable()) {\n"
@@ -291,53 +333,82 @@ GenerateBuilderMembers(io::Printer* printer) const {
" }\n"
" return $name$_;\n"
"}\n");
+ GenerateMapGetters(printer);
+ printer->Print(
+ variables_,
+ "$deprecation$\n"
+ "public Builder clear$capitalized_name$() {\n"
+ " getMutable$capitalized_name$().clear();\n"
+ " return this;\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$\n"
+ "public Builder remove$capitalized_name$(\n"
+ " $key_type$ key) {\n"
+ " $key_null_check$\n"
+ " getMutable$capitalized_name$().remove(key);\n"
+ " return this;\n"
+ "}\n");
if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
- WriteFieldDocComment(printer, descriptor_);
printer->Print(
variables_,
- "$deprecation$\n"
+ "/**\n"
+ " * Use alternate mutation accessors instead.\n"
+ " */\n"
+ "@java.lang.Deprecated\n"
"public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
- "get$capitalized_name$() {\n"
+ "getMutable$capitalized_name$() {\n"
" return new com.google.protobuf.Internal.MapAdapter<\n"
" $boxed_key_type$, $value_enum_type$, java.lang.Integer>(\n"
- " internalGet$capitalized_name$().getMap(),\n"
+ " internalGetMutable$capitalized_name$().getMutableMap(),\n"
" $name$ValueConverter);\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(
variables_,
- "$deprecation$\n"
- "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
- "getMutable$capitalized_name$() {\n"
- " return new com.google.protobuf.Internal.MapAdapter<\n"
- " $boxed_key_type$, $value_enum_type$, java.lang.Integer>(\n"
- " internalGetMutable$capitalized_name$().getMutableMap(),\n"
- " $name$ValueConverter);\n"
+ "$deprecation$public Builder put$capitalized_name$(\n"
+ " $key_type$ key,\n"
+ " $value_enum_type$ value) {\n"
+ " $key_null_check$\n"
+ " $value_null_check$\n"
+ " getMutable$capitalized_name$().put(key, value);\n"
+ " return this;\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(
variables_,
+ // TODO(arielb): null check map keys/values here and everywhere else
+ // related to putAll
"$deprecation$public Builder putAll$capitalized_name$(\n"
" java.util.Map<$boxed_key_type$, $value_enum_type$> values) {\n"
" getMutable$capitalized_name$().putAll(values);\n"
" return this;\n"
"}\n");
if (SupportUnknownEnumValue(descriptor_->file())) {
- WriteFieldDocComment(printer, descriptor_);
printer->Print(
variables_,
- "$deprecation$\n"
+ "/**\n"
+ " * Use alternate mutation accessors instead.\n"
+ " */\n"
+ "@java.lang.Deprecated\n"
"public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
- "get$capitalized_name$Value() {\n"
- " return internalGet$capitalized_name$().getMap();\n"
+ "getMutable$capitalized_name$Value() {\n"
+ " return internalGetMutable$capitalized_name$().getMutableMap();\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(
variables_,
- "$deprecation$\n"
- "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
- "getMutable$capitalized_name$Value() {\n"
- " return internalGetMutable$capitalized_name$().getMutableMap();\n"
+ "$deprecation$public Builder put$capitalized_name$Value(\n"
+ " $key_type$ key,\n"
+ " $value_type$ value) {\n"
+ " $key_null_check$\n"
+ " if ($value_enum_type$.forNumber(value) == null) {\n"
+ " throw new java.lang.IllegalArgumentException();\n"
+ " }\n"
+ " getMutable$capitalized_name$Value().put(key, value);\n"
+ " return this;\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(
@@ -349,23 +420,33 @@ GenerateBuilderMembers(io::Printer* printer) const {
"}\n");
}
} else {
- WriteFieldDocComment(printer, descriptor_);
printer->Print(
variables_,
- "public java.util.Map<$type_parameters$> get$capitalized_name$() {\n"
- " return internalGet$capitalized_name$().getMap();\n"
+ "/**\n"
+ " * Use alternate mutation accessors instead.\n"
+ " */\n"
+ "@java.lang.Deprecated\n"
+ "public java.util.Map<$type_parameters$>\n"
+ "getMutable$capitalized_name$() {\n"
+ " return internalGetMutable$capitalized_name$().getMutableMap();\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(
variables_,
- "public java.util.Map<$type_parameters$>\n"
- "getMutable$capitalized_name$() {\n"
- " return internalGetMutable$capitalized_name$().getMutableMap();\n"
+ "$deprecation$"
+ "public Builder put$capitalized_name$(\n"
+ " $key_type$ key,\n"
+ " $value_type$ value) {\n"
+ " $key_null_check$\n"
+ " $value_null_check$\n"
+ " getMutable$capitalized_name$().put(key, value);\n"
+ " return this;\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(
variables_,
- "$deprecation$public Builder putAll$capitalized_name$(\n"
+ "$deprecation$\n"
+ "public Builder putAll$capitalized_name$(\n"
" java.util.Map<$type_parameters$> values) {\n"
" getMutable$capitalized_name$().putAll(values);\n"
" return this;\n"
@@ -374,6 +455,165 @@ GenerateBuilderMembers(io::Printer* printer) const {
}
void ImmutableMapFieldGenerator::
+GenerateMapGetters(io::Printer* printer) const {
+ printer->Print(
+ variables_,
+ "$deprecation$\n"
+ "public int get$capitalized_name$Count() {\n"
+ " return internalGet$capitalized_name$().getMap().size();\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$\n"
+ "public boolean contains$capitalized_name$(\n"
+ " $key_type$ key) {\n"
+ " $key_null_check$\n"
+ " return internalGet$capitalized_name$().getMap().containsKey(key);\n"
+ "}\n");
+ if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
+ printer->Print(
+ variables_,
+ "/**\n"
+ " * Use {@link #get$capitalized_name$Map()} instead.\n"
+ " */\n"
+ "@java.lang.Deprecated\n"
+ "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
+ "get$capitalized_name$() {\n"
+ " return get$capitalized_name$Map();\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$\n"
+ "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
+ "get$capitalized_name$Map() {\n"
+ " return new com.google.protobuf.Internal.MapAdapter<\n"
+ " $boxed_key_type$, $value_enum_type$, java.lang.Integer>(\n"
+ " internalGet$capitalized_name$().getMap(),\n"
+ " $name$ValueConverter);\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$\n"
+ "public $value_enum_type$ get$capitalized_name$OrDefault(\n"
+ " $key_type$ key,\n"
+ " $value_enum_type$ defaultValue) {\n"
+ " $key_null_check$\n"
+ " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
+ " internalGet$capitalized_name$().getMap();\n"
+ " return map.containsKey(key)\n"
+ " ? $name$ValueConverter.doForward(map.get(key))\n"
+ " : defaultValue;\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$\n"
+ "public $value_enum_type$ get$capitalized_name$OrThrow(\n"
+ " $key_type$ key) {\n"
+ " $key_null_check$\n"
+ " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
+ " internalGet$capitalized_name$().getMap();\n"
+ " if (!map.containsKey(key)) {\n"
+ " throw new java.lang.IllegalArgumentException();\n"
+ " }\n"
+ " return $name$ValueConverter.doForward(map.get(key));\n"
+ "}\n");
+ if (SupportUnknownEnumValue(descriptor_->file())) {
+ printer->Print(
+ variables_,
+ "/**\n"
+ " * Use {@link #get$capitalized_name$ValueMap()} instead.\n"
+ " */\n"
+ "@java.lang.Deprecated\n"
+ "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
+ "get$capitalized_name$Value() {\n"
+ " return get$capitalized_name$ValueMap();\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$\n"
+ "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
+ "get$capitalized_name$ValueMap() {\n"
+ " return internalGet$capitalized_name$().getMap();\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$\n"
+ "public $value_type$ get$capitalized_name$ValueOrDefault(\n"
+ " $key_type$ key,\n"
+ " $value_type$ defaultValue) {\n"
+ " $key_null_check$\n"
+ " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
+ " internalGet$capitalized_name$().getMap();\n"
+ " return map.containsKey(key) ? map.get(key) : defaultValue;\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$\n"
+ "public $value_type$ get$capitalized_name$ValueOrThrow(\n"
+ " $key_type$ key) {\n"
+ " $key_null_check$\n"
+ " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
+ " internalGet$capitalized_name$().getMap();\n"
+ " if (!map.containsKey(key)) {\n"
+ " throw new java.lang.IllegalArgumentException();\n"
+ " }\n"
+ " return map.get(key);\n"
+ "}\n");
+ }
+ } else {
+ printer->Print(
+ variables_,
+ "/**\n"
+ " * Use {@link #get$capitalized_name$Map()} instead.\n"
+ " */\n"
+ "@java.lang.Deprecated\n"
+ "public java.util.Map<$type_parameters$> get$capitalized_name$() {\n"
+ " return get$capitalized_name$Map();\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$\n"
+ "public java.util.Map<$type_parameters$> get$capitalized_name$Map() {\n"
+ " return internalGet$capitalized_name$().getMap();\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$\n"
+ "public $value_type$ get$capitalized_name$OrDefault(\n"
+ " $key_type$ key,\n"
+ " $value_type$ defaultValue) {\n"
+ " $key_null_check$\n"
+ " java.util.Map<$type_parameters$> map =\n"
+ " internalGet$capitalized_name$().getMap();\n"
+ " return map.containsKey(key) ? map.get(key) : defaultValue;\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$\n"
+ "public $value_type$ get$capitalized_name$OrThrow(\n"
+ " $key_type$ key) {\n"
+ " $key_null_check$\n"
+ " java.util.Map<$type_parameters$> map =\n"
+ " internalGet$capitalized_name$().getMap();\n"
+ " if (!map.containsKey(key)) {\n"
+ " throw new java.lang.IllegalArgumentException();\n"
+ " }\n"
+ " return map.get(key);\n"
+ "}\n");
+ }
+}
+
+void ImmutableMapFieldGenerator::
GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
// Nothing to initialize.
}
@@ -411,7 +651,7 @@ GenerateParsingCode(io::Printer* printer) const {
printer->Print(
variables_,
"if (!$get_mutable_bit_parser$) {\n"
- " $name$_ = com.google.protobuf.MapField$lite$.newMapField(\n"
+ " $name$_ = com.google.protobuf.MapField.newMapField(\n"
" $map_field_parameter$);\n"
" $set_mutable_bit_parser$;\n"
"}\n");
@@ -420,11 +660,11 @@ GenerateParsingCode(io::Printer* printer) const {
printer->Print(
variables_,
"com.google.protobuf.ByteString bytes = input.readBytes();\n"
- "com.google.protobuf.MapEntry$lite$<$type_parameters$>\n"
+ "com.google.protobuf.MapEntry<$type_parameters$>\n"
"$name$ = $default_entry$.getParserForType().parseFrom(bytes);\n");
printer->Print(
variables_,
- "if ($value_enum_type$.valueOf($name$.getValue()) == null) {\n"
+ "if ($value_enum_type$.forNumber($name$.getValue()) == null) {\n"
" unknownFields.mergeLengthDelimitedField($number$, bytes);\n"
"} else {\n"
" $name$_.getMutableMap().put($name$.getKey(), $name$.getValue());\n"
@@ -432,7 +672,7 @@ GenerateParsingCode(io::Printer* printer) const {
} else {
printer->Print(
variables_,
- "com.google.protobuf.MapEntry$lite$<$type_parameters$>\n"
+ "com.google.protobuf.MapEntry<$type_parameters$>\n"
"$name$ = input.readMessage(\n"
" $default_entry$.getParserForType(), extensionRegistry);\n"
"$name$_.getMutableMap().put($name$.getKey(), $name$.getValue());\n");
@@ -450,7 +690,7 @@ GenerateSerializationCode(io::Printer* printer) const {
variables_,
"for (java.util.Map.Entry<$type_parameters$> entry\n"
" : internalGet$capitalized_name$().getMap().entrySet()) {\n"
- " com.google.protobuf.MapEntry$lite$<$type_parameters$>\n"
+ " com.google.protobuf.MapEntry<$type_parameters$>\n"
" $name$ = $default_entry$.newBuilderForType()\n"
" .setKey(entry.getKey())\n"
" .setValue(entry.getValue())\n"
@@ -465,7 +705,7 @@ GenerateSerializedSizeCode(io::Printer* printer) const {
variables_,
"for (java.util.Map.Entry<$type_parameters$> entry\n"
" : internalGet$capitalized_name$().getMap().entrySet()) {\n"
- " com.google.protobuf.MapEntry$lite$<$type_parameters$>\n"
+ " com.google.protobuf.MapEntry<$type_parameters$>\n"
" $name$ = $default_entry$.newBuilderForType()\n"
" .setKey(entry.getKey())\n"
" .setValue(entry.getValue())\n"
diff --git a/src/google/protobuf/compiler/java/java_map_field.h b/src/google/protobuf/compiler/java/java_map_field.h
index f2768f3a..ae7ce7c5 100644
--- a/src/google/protobuf/compiler/java/java_map_field.h
+++ b/src/google/protobuf/compiler/java/java_map_field.h
@@ -69,6 +69,7 @@ class ImmutableMapFieldGenerator : public ImmutableFieldGenerator {
const FieldDescriptor* descriptor_;
map<string, string> variables_;
ClassNameResolver* name_resolver_;
+ void GenerateMapGetters(io::Printer* printer) const;
};
} // namespace java
diff --git a/src/google/protobuf/compiler/java/java_map_field_lite.cc b/src/google/protobuf/compiler/java/java_map_field_lite.cc
index d2039403..0d3bea17 100644
--- a/src/google/protobuf/compiler/java/java_map_field_lite.cc
+++ b/src/google/protobuf/compiler/java/java_map_field_lite.cc
@@ -79,18 +79,27 @@ void SetMessageVariables(const FieldDescriptor* descriptor,
int messageBitIndex,
int builderBitIndex,
const FieldGeneratorInfo* info,
- ClassNameResolver* name_resolver,
+ Context* context,
map<string, string>* variables) {
SetCommonFieldVariables(descriptor, info, variables);
+ ClassNameResolver* name_resolver = context->GetNameResolver();
(*variables)["type"] =
name_resolver->GetImmutableClassName(descriptor->message_type());
const FieldDescriptor* key = KeyField(descriptor);
const FieldDescriptor* value = ValueField(descriptor);
+ const JavaType keyJavaType = GetJavaType(key);
+ const JavaType valueJavaType = GetJavaType(value);
+
(*variables)["key_type"] = TypeName(key, name_resolver, false);
(*variables)["boxed_key_type"] = TypeName(key, name_resolver, true);
(*variables)["key_wire_type"] = WireType(key);
(*variables)["key_default_value"] = DefaultValue(key, true, name_resolver);
+ (*variables)["key_null_check"] = IsReferenceType(keyJavaType) ?
+ "if (key == null) { throw new java.lang.NullPointerException(); }" : "";
+ (*variables)["value_null_check"] = IsReferenceType(valueJavaType) ?
+ "if (value == null) { throw new java.lang.NullPointerException(); }" : "";
+
if (GetJavaType(value) == JAVATYPE_ENUM) {
// We store enums as Integers internally.
(*variables)["value_type"] = "int";
@@ -123,13 +132,9 @@ void SetMessageVariables(const FieldDescriptor* descriptor,
// by the proto compiler
(*variables)["deprecation"] = descriptor->options().deprecated()
? "@java.lang.Deprecated " : "";
- (*variables)["on_changed"] =
- HasDescriptorMethods(descriptor->containing_type()) ? "onChanged();" : "";
(*variables)["default_entry"] = (*variables)["capitalized_name"] +
"DefaultEntryHolder.defaultEntry";
- (*variables)["lite"] = "Lite";
- (*variables)["descriptor"] = "";
}
} // namespace
@@ -142,7 +147,7 @@ ImmutableMapFieldLiteGenerator(const FieldDescriptor* descriptor,
: descriptor_(descriptor), name_resolver_(context->GetNameResolver()) {
SetMessageVariables(descriptor, messageBitIndex, builderBitIndex,
context->GetFieldGeneratorInfo(descriptor),
- name_resolver_, &variables_);
+ context, &variables_);
}
ImmutableMapFieldLiteGenerator::
@@ -158,25 +163,95 @@ int ImmutableMapFieldLiteGenerator::GetNumBitsForBuilder() const {
void ImmutableMapFieldLiteGenerator::
GenerateInterfaceMembers(io::Printer* printer) const {
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$int get$capitalized_name$Count();\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$boolean contains$capitalized_name$(\n"
+ " $key_type$ key);\n");
if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
+ printer->Print(
+ variables_,
+ "/**\n"
+ " * Use {@link #get$capitalized_name$Map()} instead.\n"
+ " */\n"
+ "@java.lang.Deprecated\n"
+ "java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
+ "get$capitalized_name$();\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(
variables_,
"$deprecation$java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
- "get$capitalized_name$();\n");
+ "get$capitalized_name$Map();\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$$value_enum_type$ get$capitalized_name$OrDefault(\n"
+ " $key_type$ key,\n"
+ " $value_enum_type$ defaultValue);\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$$value_enum_type$ get$capitalized_name$OrThrow(\n"
+ " $key_type$ key);\n");
if (SupportUnknownEnumValue(descriptor_->file())) {
+ printer->Print(
+ variables_,
+ "/**\n"
+ " * Use {@link #get$capitalized_name$ValueMap()} instead.\n"
+ " */\n"
+ "@java.lang.Deprecated\n"
+ "java.util.Map<$type_parameters$>\n"
+ "get$capitalized_name$Value();\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(
variables_,
"$deprecation$java.util.Map<$type_parameters$>\n"
- "get$capitalized_name$Value();\n");
+ "get$capitalized_name$ValueMap();\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$\n"
+ "$value_type$ get$capitalized_name$ValueOrDefault(\n"
+ " $key_type$ key,\n"
+ " $value_type$ defaultValue);\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$\n"
+ "$value_type$ get$capitalized_name$ValueOrThrow(\n"
+ " $key_type$ key);\n");
}
} else {
+ printer->Print(
+ variables_,
+ "/**\n"
+ " * Use {@link #get$capitalized_name$Map()} instead.\n"
+ " */\n"
+ "@java.lang.Deprecated\n"
+ "java.util.Map<$type_parameters$>\n"
+ "get$capitalized_name$();\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(
variables_,
"$deprecation$java.util.Map<$type_parameters$>\n"
- "get$capitalized_name$();\n");
+ "get$capitalized_name$Map();\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$\n"
+ "$value_type$ get$capitalized_name$OrDefault(\n"
+ " $key_type$ key,\n"
+ " $value_type$ defaultValue);\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$\n"
+ "$value_type$ get$capitalized_name$OrThrow(\n"
+ " $key_type$ key);\n");
}
}
@@ -185,11 +260,10 @@ GenerateMembers(io::Printer* printer) const {
printer->Print(
variables_,
"private static final class $capitalized_name$DefaultEntryHolder {\n"
- " static final com.google.protobuf.MapEntry$lite$<\n"
+ " static final com.google.protobuf.MapEntryLite<\n"
" $type_parameters$> defaultEntry =\n"
- " com.google.protobuf.MapEntry$lite$\n"
+ " com.google.protobuf.MapEntryLite\n"
" .<$type_parameters$>newDefaultInstance(\n"
- " $descriptor$\n"
" $key_wire_type$,\n"
" $key_default_value$,\n"
" $value_wire_type$,\n"
@@ -197,20 +271,35 @@ GenerateMembers(io::Printer* printer) const {
"}\n");
printer->Print(
variables_,
- "private com.google.protobuf.MapField$lite$<\n"
+ "private com.google.protobuf.MapFieldLite<\n"
" $type_parameters$> $name$_ =\n"
- " com.google.protobuf.MapField$lite$.emptyMapField();\n"
- "private com.google.protobuf.MapField$lite$<$type_parameters$>\n"
+ " com.google.protobuf.MapFieldLite.emptyMapField();\n"
+ "private com.google.protobuf.MapFieldLite<$type_parameters$>\n"
"internalGet$capitalized_name$() {\n"
" return $name$_;\n"
"}\n"
- "private com.google.protobuf.MapField$lite$<$type_parameters$>\n"
+ "private com.google.protobuf.MapFieldLite<$type_parameters$>\n"
"internalGetMutable$capitalized_name$() {\n"
" if (!$name$_.isMutable()) {\n"
- " $name$_ = $name$_.copy();\n"
+ " $name$_ = $name$_.mutableCopy();\n"
" }\n"
" return $name$_;\n"
"}\n");
+ printer->Print(
+ variables_,
+ "$deprecation$\n"
+ "public int get$capitalized_name$Count() {\n"
+ " return internalGet$capitalized_name$().size();\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$\n"
+ "public boolean contains$capitalized_name$(\n"
+ " $key_type$ key) {\n"
+ " $key_null_check$\n"
+ " return internalGet$capitalized_name$().containsKey(key);\n"
+ "}\n");
if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
printer->Print(
variables_,
@@ -220,34 +309,146 @@ GenerateMembers(io::Printer* printer) const {
" com.google.protobuf.Internal.MapAdapter.newEnumConverter(\n"
" $value_enum_type$.internalGetValueMap(),\n"
" $unrecognized_value$);\n");
+ printer->Print(
+ variables_,
+ "/**\n"
+ " * Use {@link #get$capitalized_name$Map()} instead.\n"
+ " */\n"
+ "@java.lang.Deprecated\n"
+ "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
+ "get$capitalized_name$() {\n"
+ " return get$capitalized_name$Map();\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$\n"
+ "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
+ "get$capitalized_name$Map() {\n"
+ " return java.util.Collections.unmodifiableMap(\n"
+ " new com.google.protobuf.Internal.MapAdapter<\n"
+ " $boxed_key_type$, $value_enum_type$, java.lang.Integer>(\n"
+ " internalGet$capitalized_name$(),\n"
+ " $name$ValueConverter));\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$\n"
+ "public $value_enum_type$ get$capitalized_name$OrDefault(\n"
+ " $key_type$ key,\n"
+ " $value_enum_type$ defaultValue) {\n"
+ " $key_null_check$\n"
+ " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
+ " internalGet$capitalized_name$();\n"
+ " return map.containsKey(key)\n"
+ " ? $name$ValueConverter.doForward(map.get(key))\n"
+ " : defaultValue;\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$\n"
+ "public $value_enum_type$ get$capitalized_name$OrThrow(\n"
+ " $key_type$ key) {\n"
+ " $key_null_check$\n"
+ " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
+ " internalGet$capitalized_name$();\n"
+ " if (!map.containsKey(key)) {\n"
+ " throw new java.lang.IllegalArgumentException();\n"
+ " }\n"
+ " return $name$ValueConverter.doForward(map.get(key));\n"
+ "}\n");
if (SupportUnknownEnumValue(descriptor_->file())) {
+ printer->Print(
+ variables_,
+ "/**\n"
+ " * Use {@link #get$capitalized_name$ValueMap()} instead.\n"
+ " */\n"
+ "@java.lang.Deprecated\n"
+ "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
+ "get$capitalized_name$Value() {\n"
+ " return get$capitalized_name$ValueMap();\n"
+ "}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(
variables_,
"$deprecation$\n"
"public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
- "get$capitalized_name$Value() {\n"
- " return internalGet$capitalized_name$().getMap();\n"
+ "get$capitalized_name$ValueMap() {\n"
+ " return java.util.Collections.unmodifiableMap(\n"
+ " internalGet$capitalized_name$());\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$\n"
+ "public $value_type$ get$capitalized_name$ValueOrDefault(\n"
+ " $key_type$ key,\n"
+ " $value_type$ defaultValue) {\n"
+ " $key_null_check$\n"
+ " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
+ " internalGet$capitalized_name$();\n"
+ " return map.containsKey(key) ? map.get(key) : defaultValue;\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$\n"
+ "public $value_type$ get$capitalized_name$ValueOrThrow(\n"
+ " $key_type$ key) {\n"
+ " $key_null_check$\n"
+ " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
+ " internalGet$capitalized_name$();\n"
+ " if (!map.containsKey(key)) {\n"
+ " throw new java.lang.IllegalArgumentException();\n"
+ " }\n"
+ " return map.get(key);\n"
"}\n");
}
+ } else {
+ printer->Print(
+ variables_,
+ "/**\n"
+ " * Use {@link #get$capitalized_name$Map()} instead.\n"
+ " */\n"
+ "@java.lang.Deprecated\n"
+ "public java.util.Map<$type_parameters$> get$capitalized_name$() {\n"
+ " return get$capitalized_name$Map();\n"
+ "}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(
variables_,
"$deprecation$\n"
- "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
- "get$capitalized_name$() {\n"
- " return new com.google.protobuf.Internal.MapAdapter<\n"
- " $boxed_key_type$, $value_enum_type$, java.lang.Integer>(\n"
- " internalGet$capitalized_name$().getMap(),\n"
- " $name$ValueConverter);\n"
+ "public java.util.Map<$type_parameters$> get$capitalized_name$Map() {\n"
+ " return java.util.Collections.unmodifiableMap(\n"
+ " internalGet$capitalized_name$());\n"
"}\n");
- } else {
WriteFieldDocComment(printer, descriptor_);
printer->Print(
variables_,
"$deprecation$\n"
- "public java.util.Map<$type_parameters$> get$capitalized_name$() {\n"
- " return internalGet$capitalized_name$().getMap();\n"
+ "public $value_type$ get$capitalized_name$OrDefault(\n"
+ " $key_type$ key,\n"
+ " $value_type$ defaultValue) {\n"
+ " $key_null_check$\n"
+ " java.util.Map<$type_parameters$> map =\n"
+ " internalGet$capitalized_name$();\n"
+ " return map.containsKey(key) ? map.get(key) : defaultValue;\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$\n"
+ "public $value_type$ get$capitalized_name$OrThrow(\n"
+ " $key_type$ key) {\n"
+ " $key_null_check$\n"
+ " java.util.Map<$type_parameters$> map =\n"
+ " internalGet$capitalized_name$();\n"
+ " if (!map.containsKey(key)) {\n"
+ " throw new java.lang.IllegalArgumentException();\n"
+ " }\n"
+ " return map.get(key);\n"
"}\n");
}
@@ -257,10 +458,10 @@ GenerateMembers(io::Printer* printer) const {
printer->Print(
variables_,
"private java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
- "getMutable$capitalized_name$() {\n"
+ "getMutable$capitalized_name$Map() {\n"
" return new com.google.protobuf.Internal.MapAdapter<\n"
" $boxed_key_type$, $value_enum_type$, java.lang.Integer>(\n"
- " internalGetMutable$capitalized_name$().getMutableMap(),\n"
+ " internalGetMutable$capitalized_name$(),\n"
" $name$ValueConverter);\n"
"}\n");
if (SupportUnknownEnumValue(descriptor_->file())) {
@@ -268,8 +469,8 @@ GenerateMembers(io::Printer* printer) const {
printer->Print(
variables_,
"private java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
- "getMutable$capitalized_name$Value() {\n"
- " return internalGetMutable$capitalized_name$().getMutableMap();\n"
+ "getMutable$capitalized_name$ValueMap() {\n"
+ " return internalGetMutable$capitalized_name$();\n"
"}\n");
}
} else {
@@ -277,88 +478,252 @@ GenerateMembers(io::Printer* printer) const {
printer->Print(
variables_,
"private java.util.Map<$type_parameters$>\n"
- "getMutable$capitalized_name$() {\n"
- " return internalGetMutable$capitalized_name$().getMutableMap();\n"
+ "getMutable$capitalized_name$Map() {\n"
+ " return internalGetMutable$capitalized_name$();\n"
"}\n");
}
}
void ImmutableMapFieldLiteGenerator::
GenerateBuilderMembers(io::Printer* printer) const {
+ printer->Print(
+ variables_,
+ "$deprecation$\n"
+ "public int get$capitalized_name$Count() {\n"
+ " return instance.get$capitalized_name$Map().size();\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$\n"
+ "public boolean contains$capitalized_name$(\n"
+ " $key_type$ key) {\n"
+ " $key_null_check$\n"
+ " return instance.get$capitalized_name$Map().containsKey(key);\n"
+ "}\n");
+ printer->Print(
+ variables_,
+ "$deprecation$\n"
+ "public Builder clear$capitalized_name$() {\n"
+ " copyOnWrite();\n"
+ " instance.getMutable$capitalized_name$Map().clear();\n"
+ " return this;\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$\n"
+ "public Builder remove$capitalized_name$(\n"
+ " $key_type$ key) {\n"
+ " $key_null_check$\n"
+ " copyOnWrite();\n"
+ " instance.getMutable$capitalized_name$Map().remove(key);\n"
+ " return this;\n"
+ "}\n");
if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
- WriteFieldDocComment(printer, descriptor_);
printer->Print(
variables_,
- "$deprecation$\n"
+ "/**\n"
+ " * Use {@link #get$capitalized_name$Map()} instead.\n"
+ " */\n"
+ "@java.lang.Deprecated\n"
"public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
"get$capitalized_name$() {\n"
- " return instance.get$capitalized_name$();\n"
+ " return get$capitalized_name$Map();\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(
variables_,
"$deprecation$\n"
"public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
- "getMutable$capitalized_name$() {\n"
+ "get$capitalized_name$Map() {\n"
+ " return java.util.Collections.unmodifiableMap(\n"
+ " instance.get$capitalized_name$Map());\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$\n"
+ "public $value_enum_type$ get$capitalized_name$OrDefault(\n"
+ " $key_type$ key,\n"
+ " $value_enum_type$ defaultValue) {\n"
+ " $key_null_check$\n"
+ " java.util.Map<$boxed_key_type$, $value_enum_type$> map =\n"
+ " instance.get$capitalized_name$Map();\n"
+ " return map.containsKey(key)\n"
+ " ? map.get(key)\n"
+ " : defaultValue;\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$\n"
+ "public $value_enum_type$ get$capitalized_name$OrThrow(\n"
+ " $key_type$ key) {\n"
+ " $key_null_check$\n"
+ " java.util.Map<$boxed_key_type$, $value_enum_type$> map =\n"
+ " instance.get$capitalized_name$Map();\n"
+ " if (!map.containsKey(key)) {\n"
+ " throw new java.lang.IllegalArgumentException();\n"
+ " }\n"
+ " return map.get(key);\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder put$capitalized_name$(\n"
+ " $key_type$ key,\n"
+ " $value_enum_type$ value) {\n"
+ " $key_null_check$\n"
+ " $value_null_check$\n"
" copyOnWrite();\n"
- " return instance.getMutable$capitalized_name$();\n"
+ " instance.getMutable$capitalized_name$Map().put(key, value);\n"
+ " return this;\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(
variables_,
"$deprecation$public Builder putAll$capitalized_name$(\n"
" java.util.Map<$boxed_key_type$, $value_enum_type$> values) {\n"
- " getMutable$capitalized_name$().putAll(values);\n"
+ " copyOnWrite();\n"
+ " instance.getMutable$capitalized_name$Map().putAll(values);\n"
" return this;\n"
"}\n");
if (SupportUnknownEnumValue(descriptor_->file())) {
- WriteFieldDocComment(printer, descriptor_);
printer->Print(
variables_,
- "$deprecation$\n"
+ "/**\n"
+ " * Use {@link #get$capitalized_name$ValueMap()} instead.\n"
+ " */\n"
+ "@java.lang.Deprecated\n"
"public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
"get$capitalized_name$Value() {\n"
- " return instance.get$capitalized_name$Value();\n"
+ " return get$capitalized_name$ValueMap();\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(
variables_,
"$deprecation$\n"
"public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
- "getMutable$capitalized_name$Value() {\n"
+ "get$capitalized_name$ValueMap() {\n"
+ " return java.util.Collections.unmodifiableMap(\n"
+ " instance.get$capitalized_name$ValueMap());\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$\n"
+ "public $value_type$ get$capitalized_name$ValueOrDefault(\n"
+ " $key_type$ key,\n"
+ " $value_type$ defaultValue) {\n"
+ " $key_null_check$\n"
+ " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
+ " instance.get$capitalized_name$ValueMap();\n"
+ " return map.containsKey(key) ? map.get(key) : defaultValue;\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$\n"
+ "public $value_type$ get$capitalized_name$ValueOrThrow(\n"
+ " $key_type$ key) {\n"
+ " $key_null_check$\n"
+ " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
+ " instance.get$capitalized_name$ValueMap();\n"
+ " if (!map.containsKey(key)) {\n"
+ " throw new java.lang.IllegalArgumentException();\n"
+ " }\n"
+ " return map.get(key);\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder put$capitalized_name$Value(\n"
+ " $key_type$ key,\n"
+ " $value_type$ value) {\n"
+ " $key_null_check$\n"
+ " if ($value_enum_type$.forNumber(value) == null) {\n"
+ " throw new java.lang.IllegalArgumentException();\n"
+ " }\n"
" copyOnWrite();\n"
- " return instance.getMutable$capitalized_name$Value();\n"
+ " instance.getMutable$capitalized_name$ValueMap().put(key, value);\n"
+ " return this;\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(
variables_,
"$deprecation$public Builder putAll$capitalized_name$Value(\n"
" java.util.Map<$boxed_key_type$, $boxed_value_type$> values) {\n"
- " getMutable$capitalized_name$Value().putAll(values);\n"
+ " copyOnWrite();\n"
+ " instance.getMutable$capitalized_name$ValueMap().putAll(values);\n"
" return this;\n"
"}\n");
}
} else {
- WriteFieldDocComment(printer, descriptor_);
printer->Print(
variables_,
+ "/**\n"
+ " * Use {@link #get$capitalized_name$Map()} instead.\n"
+ " */\n"
+ "@java.lang.Deprecated\n"
"public java.util.Map<$type_parameters$> get$capitalized_name$() {\n"
- " return instance.get$capitalized_name$();\n"
+ " return get$capitalized_name$Map();\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$"
+ "public java.util.Map<$type_parameters$> get$capitalized_name$Map() {\n"
+ " return java.util.Collections.unmodifiableMap(\n"
+ " instance.get$capitalized_name$Map());\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$\n"
+ "public $value_type$ get$capitalized_name$OrDefault(\n"
+ " $key_type$ key,\n"
+ " $value_type$ defaultValue) {\n"
+ " $key_null_check$\n"
+ " java.util.Map<$type_parameters$> map =\n"
+ " instance.get$capitalized_name$Map();\n"
+ " return map.containsKey(key) ? map.get(key) : defaultValue;\n"
+ "}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$\n"
+ "public $value_type$ get$capitalized_name$OrThrow(\n"
+ " $key_type$ key) {\n"
+ " $key_null_check$\n"
+ " java.util.Map<$type_parameters$> map =\n"
+ " instance.get$capitalized_name$Map();\n"
+ " if (!map.containsKey(key)) {\n"
+ " throw new java.lang.IllegalArgumentException();\n"
+ " }\n"
+ " return map.get(key);\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(
variables_,
- "public java.util.Map<$type_parameters$>\n"
- "getMutable$capitalized_name$() {\n"
+ "$deprecation$"
+ "public Builder put$capitalized_name$(\n"
+ " $key_type$ key,\n"
+ " $value_type$ value) {\n"
+ " $key_null_check$\n"
+ " $value_null_check$\n"
" copyOnWrite();\n"
- " return instance.getMutable$capitalized_name$();\n"
+ " instance.getMutable$capitalized_name$Map().put(key, value);\n"
+ " return this;\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(
variables_,
+ "$deprecation$"
"public Builder putAll$capitalized_name$(\n"
" java.util.Map<$type_parameters$> values) {\n"
- " getMutable$capitalized_name$().putAll(values);\n"
+ " copyOnWrite();\n"
+ " instance.getMutable$capitalized_name$Map().putAll(values);\n"
" return this;\n"
"}\n");
}
@@ -375,11 +740,11 @@ GenerateInitializationCode(io::Printer* printer) const {
}
void ImmutableMapFieldLiteGenerator::
-GenerateMergingCode(io::Printer* printer) const {
+GenerateVisitCode(io::Printer* printer) const {
printer->Print(
variables_,
- "internalGetMutable$capitalized_name$().mergeFrom(\n"
- " other.internalGet$capitalized_name$());\n");
+ "$name$_ = visitor.visitMap(\n"
+ " $name$_, other.internalGet$capitalized_name$());\n");
}
void ImmutableMapFieldLiteGenerator::
@@ -393,29 +758,26 @@ GenerateParsingCode(io::Printer* printer) const {
printer->Print(
variables_,
"if (!$name$_.isMutable()) {\n"
- " $name$_ = $name$_.copy();\n"
+ " $name$_ = $name$_.mutableCopy();\n"
"}\n");
if (!SupportUnknownEnumValue(descriptor_->file()) &&
GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
printer->Print(
variables_,
"com.google.protobuf.ByteString bytes = input.readBytes();\n"
- "com.google.protobuf.MapEntry$lite$<$type_parameters$>\n"
- "$name$ = $default_entry$.getParserForType().parseFrom(bytes);\n");
+ "java.util.Map.Entry<$type_parameters$> $name$ =\n"
+ " $default_entry$.parseEntry(bytes, extensionRegistry);\n");
printer->Print(
variables_,
- "if ($value_enum_type$.valueOf($name$.getValue()) == null) {\n"
+ "if ($value_enum_type$.forNumber($name$.getValue()) == null) {\n"
" super.mergeLengthDelimitedField($number$, bytes);\n"
"} else {\n"
- " $name$_.getMutableMap().put($name$.getKey(), $name$.getValue());\n"
+ " $name$_.put($name$);\n"
"}\n");
} else {
printer->Print(
variables_,
- "com.google.protobuf.MapEntry$lite$<$type_parameters$>\n"
- "$name$ = input.readMessage(\n"
- " $default_entry$.getParserForType(), extensionRegistry);\n"
- "$name$_.getMutableMap().put($name$.getKey(), $name$.getValue());\n");
+ "$default_entry$.parseInto($name$_, input, extensionRegistry);");
}
}
@@ -429,13 +791,9 @@ GenerateSerializationCode(io::Printer* printer) const {
printer->Print(
variables_,
"for (java.util.Map.Entry<$type_parameters$> entry\n"
- " : internalGet$capitalized_name$().getMap().entrySet()) {\n"
- " com.google.protobuf.MapEntry$lite$<$type_parameters$>\n"
- " $name$ = $default_entry$.newBuilderForType()\n"
- " .setKey(entry.getKey())\n"
- " .setValue(entry.getValue())\n"
- " .build();\n"
- " output.writeMessage($number$, $name$);\n"
+ " : internalGet$capitalized_name$().entrySet()) {\n"
+ " $default_entry$.serializeTo(\n"
+ " output, $number$, entry.getKey(), entry.getValue());\n"
"}\n");
}
@@ -444,14 +802,9 @@ GenerateSerializedSizeCode(io::Printer* printer) const {
printer->Print(
variables_,
"for (java.util.Map.Entry<$type_parameters$> entry\n"
- " : internalGet$capitalized_name$().getMap().entrySet()) {\n"
- " com.google.protobuf.MapEntry$lite$<$type_parameters$>\n"
- " $name$ = $default_entry$.newBuilderForType()\n"
- " .setKey(entry.getKey())\n"
- " .setValue(entry.getValue())\n"
- " .build();\n"
- " size += com.google.protobuf.CodedOutputStream\n"
- " .computeMessageSize($number$, $name$);\n"
+ " : internalGet$capitalized_name$().entrySet()) {\n"
+ " size += $default_entry$.computeMessageSize(\n"
+ " $number$, entry.getKey(), entry.getValue());\n"
"}\n");
}
@@ -467,7 +820,7 @@ void ImmutableMapFieldLiteGenerator::
GenerateHashCode(io::Printer* printer) const {
printer->Print(
variables_,
- "if (!internalGet$capitalized_name$().getMap().isEmpty()) {\n"
+ "if (!internalGet$capitalized_name$().isEmpty()) {\n"
" hash = (37 * hash) + $constant_name$;\n"
" hash = (53 * hash) + internalGet$capitalized_name$().hashCode();\n"
"}\n");
diff --git a/src/google/protobuf/compiler/java/java_map_field_lite.h b/src/google/protobuf/compiler/java/java_map_field_lite.h
index a09cd536..555b5c5b 100644
--- a/src/google/protobuf/compiler/java/java_map_field_lite.h
+++ b/src/google/protobuf/compiler/java/java_map_field_lite.h
@@ -52,7 +52,7 @@ class ImmutableMapFieldLiteGenerator : public ImmutableFieldLiteGenerator {
void GenerateMembers(io::Printer* printer) const;
void GenerateBuilderMembers(io::Printer* printer) const;
void GenerateInitializationCode(io::Printer* printer) const;
- void GenerateMergingCode(io::Printer* printer) const;
+ void GenerateVisitCode(io::Printer* printer) const;
void GenerateDynamicMethodMakeImmutableCode(io::Printer* printer) const;
void GenerateParsingCode(io::Printer* printer) const;
void GenerateParsingDoneCode(io::Printer* printer) const;
diff --git a/src/google/protobuf/compiler/java/java_message.cc b/src/google/protobuf/compiler/java/java_message.cc
index 5715a432..6c80d070 100644
--- a/src/google/protobuf/compiler/java/java_message.cc
+++ b/src/google/protobuf/compiler/java/java_message.cc
@@ -89,19 +89,20 @@ MessageGenerator::MessageGenerator(const Descriptor* descriptor)
MessageGenerator::~MessageGenerator() {}
// ===================================================================
-// TODO(api): Move this class to a separate immutable_message.cc file.
ImmutableMessageGenerator::ImmutableMessageGenerator(
const Descriptor* descriptor, Context* context)
: MessageGenerator(descriptor), context_(context),
name_resolver_(context->GetNameResolver()),
field_generators_(descriptor, context_) {
- GOOGLE_CHECK_NE(
- FileOptions::LITE_RUNTIME, descriptor->file()->options().optimize_for());
+ GOOGLE_CHECK(HasDescriptorMethods(descriptor->file(), context->EnforceLite()))
+ << "Generator factory error: A non-lite message generator is used to "
+ "generate lite messages.";
}
ImmutableMessageGenerator::~ImmutableMessageGenerator() {}
-void ImmutableMessageGenerator::GenerateStaticVariables(io::Printer* printer) {
+void ImmutableMessageGenerator::GenerateStaticVariables(
+ io::Printer* printer, int* bytecode_estimate) {
// Because descriptor.proto (com.google.protobuf.DescriptorProtos) is
// used in the construction of descriptors, we have a tricky bootstrapping
// problem. To help control static initialization order, we make sure all
@@ -124,23 +125,29 @@ void ImmutableMessageGenerator::GenerateStaticVariables(io::Printer* printer) {
} else {
vars["private"] = "private ";
}
+ if (*bytecode_estimate <= kMaxStaticSize) {
+ vars["final"] = "final ";
+ } else {
+ vars["final"] = "";
+ }
// The descriptor for this type.
printer->Print(vars,
// TODO(teboring): final needs to be added back. The way to fix it is to
// generate methods that can construct the types, and then still declare the
// types, and then init them in clinit with the new method calls.
- "$private$static com.google.protobuf.Descriptors.Descriptor\n"
+ "$private$static $final$com.google.protobuf.Descriptors.Descriptor\n"
" internal_$identifier$_descriptor;\n");
+ *bytecode_estimate += 30;
// And the FieldAccessorTable.
- GenerateFieldAccessorTable(printer);
+ GenerateFieldAccessorTable(printer, bytecode_estimate);
// Generate static members for all nested types.
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
// TODO(kenton): Reuse MessageGenerator objects?
ImmutableMessageGenerator(descriptor_->nested_type(i), context_)
- .GenerateStaticVariables(printer);
+ .GenerateStaticVariables(printer, bytecode_estimate);
}
}
@@ -183,7 +190,7 @@ int ImmutableMessageGenerator::GenerateStaticVariableInitializers(
}
void ImmutableMessageGenerator::
-GenerateFieldAccessorTable(io::Printer* printer) {
+GenerateFieldAccessorTable(io::Printer* printer, int* bytecode_estimate) {
map<string, string> vars;
vars["identifier"] = UniqueFileScopeIdentifier(descriptor_);
if (MultipleJavaFiles(descriptor_->file(), /* immutable = */ true)) {
@@ -193,10 +200,20 @@ GenerateFieldAccessorTable(io::Printer* printer) {
} else {
vars["private"] = "private ";
}
+ if (*bytecode_estimate <= kMaxStaticSize) {
+ vars["final"] = "final ";
+ } else {
+ vars["final"] = "";
+ }
+ vars["ver"] = GeneratedCodeVersionSuffix();
printer->Print(vars,
- "$private$static\n"
- " com.google.protobuf.GeneratedMessage.FieldAccessorTable\n"
+ "$private$static $final$\n"
+ " com.google.protobuf.GeneratedMessage$ver$.FieldAccessorTable\n"
" internal_$identifier$_fieldAccessorTable;\n");
+
+ // 6 bytes per field and oneof
+ *bytecode_estimate += 10 + 6 * descriptor_->field_count()
+ + 6 * descriptor_->oneof_decl_count();
}
int ImmutableMessageGenerator::
@@ -204,11 +221,11 @@ GenerateFieldAccessorTableInitializer(io::Printer* printer) {
int bytecode_estimate = 10;
printer->Print(
"internal_$identifier$_fieldAccessorTable = new\n"
- " com.google.protobuf.GeneratedMessage.FieldAccessorTable(\n"
+ " com.google.protobuf.GeneratedMessage$ver$.FieldAccessorTable(\n"
" internal_$identifier$_descriptor,\n"
" new java.lang.String[] { ",
- "identifier",
- UniqueFileScopeIdentifier(descriptor_));
+ "identifier", UniqueFileScopeIdentifier(descriptor_),
+ "ver", GeneratedCodeVersionSuffix());
for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor* field = descriptor_->field(i);
const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
@@ -232,22 +249,27 @@ GenerateFieldAccessorTableInitializer(io::Printer* printer) {
// ===================================================================
void ImmutableMessageGenerator::GenerateInterface(io::Printer* printer) {
+ MaybePrintGeneratedAnnotation(context_, printer, descriptor_,
+ /* immutable = */ true, "OrBuilder");
if (descriptor_->extension_range_count() > 0) {
printer->Print(
- "public interface $classname$OrBuilder extends\n"
- " $extra_interfaces$\n"
- " com.google.protobuf.GeneratedMessage.\n"
- " ExtendableMessageOrBuilder<$classname$> {\n",
- "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_),
- "classname", descriptor_->name());
+ "public interface $classname$OrBuilder$idend$ extends\n"
+ " $extra_interfaces$\n"
+ " com.google.protobuf.GeneratedMessage$ver$.\n"
+ " ExtendableMessageOrBuilder<$classname$> {\n",
+ "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_),
+ "classname", descriptor_->name(),
+ "idend", "", "ver", GeneratedCodeVersionSuffix());
} else {
printer->Print(
- "public interface $classname$OrBuilder extends\n"
- " $extra_interfaces$\n"
- " com.google.protobuf.MessageOrBuilder {\n",
- "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_),
- "classname", descriptor_->name());
+ "public interface $classname$OrBuilder$idend$ extends\n"
+ " $extra_interfaces$\n"
+ " com.google.protobuf.MessageOrBuilder {\n",
+ "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_),
+ "classname", descriptor_->name(),
+ "idend", "");
}
+ printer->Annotate("classname", "idend", descriptor_);
printer->Indent();
for (int i = 0; i < descriptor_->field_count(); i++) {
@@ -275,36 +297,45 @@ void ImmutableMessageGenerator::GenerateInterface(io::Printer* printer) {
// ===================================================================
void ImmutableMessageGenerator::Generate(io::Printer* printer) {
- bool is_own_file =
- descriptor_->containing_type() == NULL &&
- MultipleJavaFiles(descriptor_->file(), /* immutable = */ true);
+ bool is_own_file = IsOwnFile(descriptor_, /* immutable = */ true);
map<string, string> variables;
variables["static"] = is_own_file ? " " : " static ";
variables["classname"] = descriptor_->name();
variables["extra_interfaces"] = ExtraMessageInterfaces(descriptor_);
+ variables["ver"] = GeneratedCodeVersionSuffix();
WriteMessageDocComment(printer, descriptor_);
+ MaybePrintGeneratedAnnotation(context_, printer, descriptor_,
+ /* immutable = */ true);
// The builder_type stores the super type name of the nested Builder class.
string builder_type;
if (descriptor_->extension_range_count() > 0) {
printer->Print(variables,
- "public $static$final class $classname$ extends\n"
- " com.google.protobuf.GeneratedMessage.ExtendableMessage<\n"
- " $classname$> implements\n"
- " $extra_interfaces$\n"
- " $classname$OrBuilder {\n");
+ "public $static$final class $classname$ extends\n");
+ printer->Annotate("classname", descriptor_);
+ printer->Print(
+ variables,
+ " com.google.protobuf.GeneratedMessage$ver$.ExtendableMessage<\n"
+ " $classname$> implements\n"
+ " $extra_interfaces$\n"
+ " $classname$OrBuilder {\n");
builder_type = strings::Substitute(
- "com.google.protobuf.GeneratedMessage.ExtendableBuilder<$0, ?>",
- name_resolver_->GetImmutableClassName(descriptor_));
+ "com.google.protobuf.GeneratedMessage$1.ExtendableBuilder<$0, ?>",
+ name_resolver_->GetImmutableClassName(descriptor_),
+ GeneratedCodeVersionSuffix());
} else {
printer->Print(variables,
- "public $static$final class $classname$ extends\n"
- " com.google.protobuf.GeneratedMessage implements\n"
+ "public $static$final class $classname$ extends\n");
+ printer->Annotate("classname", descriptor_);
+ printer->Print(variables,
+ " com.google.protobuf.GeneratedMessage$ver$ implements\n"
" $extra_interfaces$\n"
" $classname$OrBuilder {\n");
- builder_type = "com.google.protobuf.GeneratedMessage.Builder<?>";
+ builder_type = strings::Substitute(
+ "com.google.protobuf.GeneratedMessage$0.Builder<?>",
+ GeneratedCodeVersionSuffix());
}
printer->Indent();
// Using builder_type, instead of Builder, prevents the Builder class from
@@ -342,7 +373,7 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) {
printer->Print(
"}\n");
- if (HasGeneratedMethods(descriptor_)) {
+ if (context_->HasGeneratedMethods(descriptor_)) {
GenerateParsingConstructor(printer);
}
@@ -408,12 +439,20 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) {
"cap_oneof_name",
ToUpper(vars["oneof_name"]));
printer->Print(vars,
- "private int value = 0;\n"
+ "private final int value;\n"
"private $oneof_capitalized_name$Case(int value) {\n"
" this.value = value;\n"
"}\n");
printer->Print(vars,
+ "/**\n"
+ " * @deprecated Use {@link #forNumber(int)} instead.\n"
+ " */\n"
+ "@java.lang.Deprecated\n"
"public static $oneof_capitalized_name$Case valueOf(int value) {\n"
+ " return forNumber(value);\n"
+ "}\n"
+ "\n"
+ "public static $oneof_capitalized_name$Case forNumber(int value) {\n"
" switch (value) {\n");
for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
@@ -426,8 +465,7 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) {
}
printer->Print(
" case 0: return $cap_oneof_name$_NOT_SET;\n"
- " default: throw new java.lang.IllegalArgumentException(\n"
- " \"Value is undefined for this oneof enum.\");\n"
+ " default: return null;\n"
" }\n"
"}\n"
"public int getNumber() {\n"
@@ -440,7 +478,7 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) {
printer->Print(vars,
"public $oneof_capitalized_name$Case\n"
"get$oneof_capitalized_name$Case() {\n"
- " return $oneof_capitalized_name$Case.valueOf(\n"
+ " return $oneof_capitalized_name$Case.forNumber(\n"
" $oneof_name$Case_);\n"
"}\n"
"\n");
@@ -459,12 +497,9 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) {
printer->Print("\n");
}
- if (HasGeneratedMethods(descriptor_)) {
+ if (context_->HasGeneratedMethods(descriptor_)) {
GenerateIsInitialized(printer);
GenerateMessageSerializationMethods(printer);
- }
-
- if (HasEqualsAndHashCode(descriptor_)) {
GenerateEqualsAndHashCode(printer);
}
@@ -551,16 +586,18 @@ GenerateMessageSerializationMethods(io::Printer* printer) {
if (descriptor_->extension_range_count() > 0) {
if (descriptor_->options().message_set_wire_format()) {
printer->Print(
- "com.google.protobuf.GeneratedMessage\n"
+ "com.google.protobuf.GeneratedMessage$ver$\n"
" .ExtendableMessage<$classname$>.ExtensionWriter\n"
" extensionWriter = newMessageSetExtensionWriter();\n",
- "classname", name_resolver_->GetImmutableClassName(descriptor_));
+ "classname", name_resolver_->GetImmutableClassName(descriptor_),
+ "ver", GeneratedCodeVersionSuffix());
} else {
printer->Print(
- "com.google.protobuf.GeneratedMessage\n"
+ "com.google.protobuf.GeneratedMessage$ver$\n"
" .ExtendableMessage<$classname$>.ExtensionWriter\n"
" extensionWriter = newExtensionWriter();\n",
- "classname", name_resolver_->GetImmutableClassName(descriptor_));
+ "classname", name_resolver_->GetImmutableClassName(descriptor_),
+ "ver", GeneratedCodeVersionSuffix());
}
}
@@ -664,37 +701,44 @@ GenerateParseFromMethods(io::Printer* printer) {
"}\n"
"public static $classname$ parseFrom(java.io.InputStream input)\n"
" throws java.io.IOException {\n"
- " return PARSER.parseFrom(input);\n"
+ " return com.google.protobuf.GeneratedMessage$ver$\n"
+ " .parseWithIOException(PARSER, input);\n"
"}\n"
"public static $classname$ parseFrom(\n"
" java.io.InputStream input,\n"
" com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
" throws java.io.IOException {\n"
- " return PARSER.parseFrom(input, extensionRegistry);\n"
+ " return com.google.protobuf.GeneratedMessage$ver$\n"
+ " .parseWithIOException(PARSER, input, extensionRegistry);\n"
"}\n"
"public static $classname$ parseDelimitedFrom(java.io.InputStream input)\n"
" throws java.io.IOException {\n"
- " return PARSER.parseDelimitedFrom(input);\n"
+ " return com.google.protobuf.GeneratedMessage$ver$\n"
+ " .parseDelimitedWithIOException(PARSER, input);\n"
"}\n"
"public static $classname$ parseDelimitedFrom(\n"
" java.io.InputStream input,\n"
" com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
" throws java.io.IOException {\n"
- " return PARSER.parseDelimitedFrom(input, extensionRegistry);\n"
+ " return com.google.protobuf.GeneratedMessage$ver$\n"
+ " .parseDelimitedWithIOException(PARSER, input, extensionRegistry);\n"
"}\n"
"public static $classname$ parseFrom(\n"
" com.google.protobuf.CodedInputStream input)\n"
" throws java.io.IOException {\n"
- " return PARSER.parseFrom(input);\n"
+ " return com.google.protobuf.GeneratedMessage$ver$\n"
+ " .parseWithIOException(PARSER, input);\n"
"}\n"
"public static $classname$ parseFrom(\n"
" com.google.protobuf.CodedInputStream input,\n"
" com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
" throws java.io.IOException {\n"
- " return PARSER.parseFrom(input, extensionRegistry);\n"
+ " return com.google.protobuf.GeneratedMessage$ver$\n"
+ " .parseWithIOException(PARSER, input, extensionRegistry);\n"
"}\n"
"\n",
- "classname", name_resolver_->GetImmutableClassName(descriptor_));
+ "classname", name_resolver_->GetImmutableClassName(descriptor_),
+ "ver", GeneratedCodeVersionSuffix());
}
void ImmutableMessageGenerator::GenerateSerializeOneField(
@@ -733,10 +777,11 @@ void ImmutableMessageGenerator::GenerateBuilder(io::Printer* printer) {
printer->Print(
"@java.lang.Override\n"
"protected Builder newBuilderForType(\n"
- " com.google.protobuf.GeneratedMessage.BuilderParent parent) {\n"
+ " com.google.protobuf.GeneratedMessage$ver$.BuilderParent parent) {\n"
" Builder builder = new Builder(parent);\n"
" return builder;\n"
- "}\n");
+ "}\n",
+ "ver", GeneratedCodeVersionSuffix());
MessageBuilderGenerator builderGenerator(descriptor_, context_);
builderGenerator.Generate(printer);
@@ -790,7 +835,7 @@ GenerateDescriptorMethods(io::Printer* printer) {
"}\n");
}
printer->Print(
- "protected com.google.protobuf.GeneratedMessage.FieldAccessorTable\n"
+ "protected com.google.protobuf.GeneratedMessage$ver$.FieldAccessorTable\n"
" internalGetFieldAccessorTable() {\n"
" return $fileclass$.internal_$identifier$_fieldAccessorTable\n"
" .ensureFieldAccessorsInitialized(\n"
@@ -799,7 +844,8 @@ GenerateDescriptorMethods(io::Printer* printer) {
"\n",
"classname", name_resolver_->GetImmutableClassName(descriptor_),
"fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()),
- "identifier", UniqueFileScopeIdentifier(descriptor_));
+ "identifier", UniqueFileScopeIdentifier(descriptor_),
+ "ver", GeneratedCodeVersionSuffix());
}
// ===================================================================
@@ -1049,22 +1095,52 @@ GenerateEqualsAndHashCode(io::Printer* printer) {
printer->Print("hash = (19 * hash) + getDescriptorForType().hashCode();\n");
+ // hashCode non-oneofs.
for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor* field = descriptor_->field(i);
- const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
- bool check_has_bits = CheckHasBitsForEqualsAndHashCode(field);
- if (check_has_bits) {
+ if (field->containing_oneof() == NULL) {
+ const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
+ bool check_has_bits = CheckHasBitsForEqualsAndHashCode(field);
+ if (check_has_bits) {
+ printer->Print(
+ "if (has$name$()) {\n",
+ "name", info->capitalized_name);
+ printer->Indent();
+ }
+ field_generators_.get(field).GenerateHashCode(printer);
+ if (check_has_bits) {
+ printer->Outdent();
+ printer->Print("}\n");
+ }
+ }
+ }
+
+ // hashCode oneofs.
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ printer->Print(
+ "switch ($oneof_name$Case_) {\n",
+ "oneof_name",
+ context_->GetOneofGeneratorInfo(
+ descriptor_->oneof_decl(i))->name);
+ printer->Indent();
+ for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
+ const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
printer->Print(
- "if (has$name$()) {\n",
- "name", info->capitalized_name);
+ "case $field_number$:\n",
+ "field_number",
+ SimpleItoa(field->number()));
printer->Indent();
- }
- field_generators_.get(field).GenerateHashCode(printer);
- if (check_has_bits) {
+ field_generators_.get(field).GenerateHashCode(printer);
+ printer->Print("break;\n");
printer->Outdent();
- printer->Print("}\n");
}
+ printer->Print(
+ "case 0:\n"
+ "default:\n");
+ printer->Outdent();
+ printer->Print("}\n");
}
+
if (descriptor_->extension_range_count() > 0) {
printer->Print(
"hash = hashFields(hash, getExtensionFields());\n");
@@ -1105,7 +1181,8 @@ GenerateParsingConstructor(io::Printer* printer) {
printer->Print(
"private $classname$(\n"
" com.google.protobuf.CodedInputStream input,\n"
- " com.google.protobuf.ExtensionRegistryLite extensionRegistry) {\n",
+ " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
+ " throws com.google.protobuf.InvalidProtocolBufferException {\n",
"classname", descriptor_->name());
printer->Indent();
@@ -1215,11 +1292,10 @@ GenerateParsingConstructor(io::Printer* printer) {
printer->Outdent();
printer->Print(
"} catch (com.google.protobuf.InvalidProtocolBufferException e) {\n"
- " throw new RuntimeException(e.setUnfinishedMessage(this));\n"
+ " throw e.setUnfinishedMessage(this);\n"
"} catch (java.io.IOException e) {\n"
- " throw new RuntimeException(\n"
- " new com.google.protobuf.InvalidProtocolBufferException(\n"
- " e.getMessage()).setUnfinishedMessage(this));\n"
+ " throw new com.google.protobuf.InvalidProtocolBufferException(\n"
+ " e).setUnfinishedMessage(this);\n"
"} finally {\n");
printer->Indent();
@@ -1261,20 +1337,9 @@ void ImmutableMessageGenerator::GenerateParser(io::Printer* printer) {
" com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
" throws com.google.protobuf.InvalidProtocolBufferException {\n",
"classname", descriptor_->name());
- if (HasGeneratedMethods(descriptor_)) {
- // The parsing constructor throws an InvalidProtocolBufferException via a
- // RuntimeException to aid in method pruning. We unwrap it here.
+ if (context_->HasGeneratedMethods(descriptor_)) {
printer->Print(
- " try {\n"
- " return new $classname$(input, extensionRegistry);\n"
- " } catch (RuntimeException e) {\n"
- " if (e.getCause() instanceof\n"
- " com.google.protobuf.InvalidProtocolBufferException) {\n"
- " throw (com.google.protobuf.InvalidProtocolBufferException)\n"
- " e.getCause();\n"
- " }\n"
- " throw e;\n"
- " }\n",
+ " return new $classname$(input, extensionRegistry);\n",
"classname", descriptor_->name());
} else {
// When parsing constructor isn't generated, use builder to parse
@@ -1329,14 +1394,39 @@ void ImmutableMessageGenerator::GenerateInitializers(io::Printer* printer) {
void ImmutableMessageGenerator::GenerateAnyMethods(io::Printer* printer) {
printer->Print(
"private static String getTypeUrl(\n"
+ " java.lang.String typeUrlPrefix,\n"
" com.google.protobuf.Descriptors.Descriptor descriptor) {\n"
- " return \"type.googleapis.com/\" + descriptor.getFullName();\n"
+ " return typeUrlPrefix.endsWith(\"/\")\n"
+ " ? typeUrlPrefix + descriptor.getFullName()\n"
+ " : typeUrlPrefix + \"/\" + descriptor.getFullName();\n"
+ "}\n"
+ "\n"
+ "private static String getTypeNameFromTypeUrl(\n"
+ " java.lang.String typeUrl) {\n"
+ " int pos = typeUrl.lastIndexOf('/');\n"
+ " return pos == -1 ? \"\" : typeUrl.substring(pos + 1);\n"
"}\n"
"\n"
"public static <T extends com.google.protobuf.Message> Any pack(\n"
" T message) {\n"
" return Any.newBuilder()\n"
- " .setTypeUrl(getTypeUrl(message.getDescriptorForType()))\n"
+ " .setTypeUrl(getTypeUrl(\"type.googleapis.com\",\n"
+ " message.getDescriptorForType()))\n"
+ " .setValue(message.toByteString())\n"
+ " .build();\n"
+ "}\n"
+ "\n"
+ "/**\n"
+ " * Packs a message uisng the given type URL prefix. The type URL will\n"
+ " * be constructed by concatenating the message type's full name to the\n"
+ " * prefix with an optional \"/\" separator if the prefix doesn't end\n"
+ " * with \"/\" already.\n"
+ " */\n"
+ "public static <T extends com.google.protobuf.Message> Any pack(\n"
+ " T message, java.lang.String typeUrlPrefix) {\n"
+ " return Any.newBuilder()\n"
+ " .setTypeUrl(getTypeUrl(typeUrlPrefix,\n"
+ " message.getDescriptorForType()))\n"
" .setValue(message.toByteString())\n"
" .build();\n"
"}\n"
@@ -1345,8 +1435,8 @@ void ImmutableMessageGenerator::GenerateAnyMethods(io::Printer* printer) {
" java.lang.Class<T> clazz) {\n"
" T defaultInstance =\n"
" com.google.protobuf.Internal.getDefaultInstance(clazz);\n"
- " return getTypeUrl().equals(\n"
- " getTypeUrl(defaultInstance.getDescriptorForType()));\n"
+ " return getTypeNameFromTypeUrl(getTypeUrl()).equals(\n"
+ " defaultInstance.getDescriptorForType().getFullName());\n"
"}\n"
"\n"
"private volatile com.google.protobuf.Message cachedUnpackValue;\n"
diff --git a/src/google/protobuf/compiler/java/java_message.h b/src/google/protobuf/compiler/java/java_message.h
index be5bfb07..da1447c1 100644
--- a/src/google/protobuf/compiler/java/java_message.h
+++ b/src/google/protobuf/compiler/java/java_message.h
@@ -56,6 +56,8 @@ namespace protobuf {
namespace compiler {
namespace java {
+static const int kMaxStaticSize = 1 << 15; // aka 32k
+
class MessageGenerator {
public:
explicit MessageGenerator(const Descriptor* descriptor);
@@ -64,7 +66,8 @@ class MessageGenerator {
// All static variables have to be declared at the top-level of the file
// so that we can control initialization order, which is important for
// DescriptorProto bootstrapping to work.
- virtual void GenerateStaticVariables(io::Printer* printer) = 0;
+ virtual void GenerateStaticVariables(
+ io::Printer* printer, int* bytecode_estimate) = 0;
// Output code which initializes the static variables generated by
// GenerateStaticVariables(). Returns an estimate of bytecode size.
@@ -89,21 +92,21 @@ class MessageGenerator {
class ImmutableMessageGenerator : public MessageGenerator {
public:
- explicit ImmutableMessageGenerator(const Descriptor* descriptor,
- Context* context);
+ ImmutableMessageGenerator(const Descriptor* descriptor, Context* context);
virtual ~ImmutableMessageGenerator();
virtual void Generate(io::Printer* printer);
virtual void GenerateInterface(io::Printer* printer);
virtual void GenerateExtensionRegistrationCode(io::Printer* printer);
- virtual void GenerateStaticVariables(io::Printer* printer);
+ virtual void GenerateStaticVariables(
+ io::Printer* printer, int* bytecode_estimate);
// Returns an estimate of the number of bytes the printed code will compile to
virtual int GenerateStaticVariableInitializers(io::Printer* printer);
private:
- void GenerateFieldAccessorTable(io::Printer* printer);
+ void GenerateFieldAccessorTable(io::Printer* printer, int* bytecode_estimate);
// Returns an estimate of the number of bytes the printed code will compile to
int GenerateFieldAccessorTableInitializer(io::Printer* printer);
diff --git a/src/google/protobuf/compiler/java/java_message_builder.cc b/src/google/protobuf/compiler/java/java_message_builder.cc
index 72694119..42154694 100644
--- a/src/google/protobuf/compiler/java/java_message_builder.cc
+++ b/src/google/protobuf/compiler/java/java_message_builder.cc
@@ -81,8 +81,9 @@ MessageBuilderGenerator::MessageBuilderGenerator(
: descriptor_(descriptor), context_(context),
name_resolver_(context->GetNameResolver()),
field_generators_(descriptor, context_) {
- GOOGLE_CHECK_NE(
- FileOptions::LITE_RUNTIME, descriptor->file()->options().optimize_for());
+ GOOGLE_CHECK(HasDescriptorMethods(descriptor->file(), context->EnforceLite()))
+ << "Generator factory error: A non-lite message generator is used to "
+ "generate lite messages.";
}
MessageBuilderGenerator::~MessageBuilderGenerator() {}
@@ -93,27 +94,29 @@ Generate(io::Printer* printer) {
if (descriptor_->extension_range_count() > 0) {
printer->Print(
"public static final class Builder extends\n"
- " com.google.protobuf.GeneratedMessage.ExtendableBuilder<\n"
+ " com.google.protobuf.GeneratedMessage$ver$.ExtendableBuilder<\n"
" $classname$, Builder> implements\n"
" $extra_interfaces$\n"
" $classname$OrBuilder {\n",
"classname", name_resolver_->GetImmutableClassName(descriptor_),
- "extra_interfaces", ExtraBuilderInterfaces(descriptor_));
+ "extra_interfaces", ExtraBuilderInterfaces(descriptor_),
+ "ver", GeneratedCodeVersionSuffix());
} else {
printer->Print(
"public static final class Builder extends\n"
- " com.google.protobuf.GeneratedMessage.Builder<Builder> implements\n"
+ " com.google.protobuf.GeneratedMessage$ver$.Builder<Builder> implements\n"
" $extra_interfaces$\n"
" $classname$OrBuilder {\n",
"classname", name_resolver_->GetImmutableClassName(descriptor_),
- "extra_interfaces", ExtraBuilderInterfaces(descriptor_));
+ "extra_interfaces", ExtraBuilderInterfaces(descriptor_),
+ "ver", GeneratedCodeVersionSuffix());
}
printer->Indent();
GenerateDescriptorMethods(printer);
GenerateCommonBuilderMethods(printer);
- if (HasGeneratedMethods(descriptor_)) {
+ if (context_->HasGeneratedMethods(descriptor_)) {
GenerateIsInitialized(printer);
GenerateBuilderParsingMethods(printer);
}
@@ -134,7 +137,7 @@ Generate(io::Printer* printer) {
printer->Print(vars,
"public $oneof_capitalized_name$Case\n"
" get$oneof_capitalized_name$Case() {\n"
- " return $oneof_capitalized_name$Case.valueOf(\n"
+ " return $oneof_capitalized_name$Case.forNumber(\n"
" $oneof_name$Case_);\n"
"}\n"
"\n"
@@ -180,6 +183,18 @@ Generate(io::Printer* printer) {
" return this;\n"
"}\n"
"\n");
+ } else {
+ printer->Print(
+ "public final Builder setUnknownFields(\n"
+ " final com.google.protobuf.UnknownFieldSet unknownFields) {\n"
+ " return super.setUnknownFields(unknownFields);\n"
+ "}\n"
+ "\n"
+ "public final Builder mergeUnknownFields(\n"
+ " final com.google.protobuf.UnknownFieldSet unknownFields) {\n"
+ " return super.mergeUnknownFields(unknownFields);\n"
+ "}\n"
+ "\n");
}
printer->Print(
@@ -267,7 +282,7 @@ GenerateDescriptorMethods(io::Printer* printer) {
"}\n");
}
printer->Print(
- "protected com.google.protobuf.GeneratedMessage.FieldAccessorTable\n"
+ "protected com.google.protobuf.GeneratedMessage$ver$.FieldAccessorTable\n"
" internalGetFieldAccessorTable() {\n"
" return $fileclass$.internal_$identifier$_fieldAccessorTable\n"
" .ensureFieldAccessorsInitialized(\n"
@@ -276,7 +291,8 @@ GenerateDescriptorMethods(io::Printer* printer) {
"\n",
"classname", name_resolver_->GetImmutableClassName(descriptor_),
"fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()),
- "identifier", UniqueFileScopeIdentifier(descriptor_));
+ "identifier", UniqueFileScopeIdentifier(descriptor_),
+ "ver", GeneratedCodeVersionSuffix());
}
// ===================================================================
@@ -293,15 +309,18 @@ GenerateCommonBuilderMethods(io::Printer* printer) {
printer->Print(
"private Builder(\n"
- " com.google.protobuf.GeneratedMessage.BuilderParent parent) {\n"
+ " com.google.protobuf.GeneratedMessage$ver$.BuilderParent parent) {\n"
" super(parent);\n"
" maybeForceBuilderInitialization();\n"
"}\n",
- "classname", name_resolver_->GetImmutableClassName(descriptor_));
+ "classname", name_resolver_->GetImmutableClassName(descriptor_),
+ "ver", GeneratedCodeVersionSuffix());
printer->Print(
"private void maybeForceBuilderInitialization() {\n"
- " if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {\n");
+ " if (com.google.protobuf.GeneratedMessage$ver$\n"
+ " .alwaysUseFieldBuilders) {\n",
+ "ver", GeneratedCodeVersionSuffix());
printer->Indent();
printer->Indent();
@@ -437,9 +456,65 @@ GenerateCommonBuilderMethods(io::Printer* printer) {
"\n",
"classname", name_resolver_->GetImmutableClassName(descriptor_));
+ printer->Print(
+ "public Builder clone() {\n"
+ " return (Builder) super.clone();\n"
+ "}\n"
+ "public Builder setField(\n"
+ " com.google.protobuf.Descriptors.FieldDescriptor field,\n"
+ " Object value) {\n"
+ " return (Builder) super.setField(field, value);\n"
+ "}\n"
+ "public Builder clearField(\n"
+ " com.google.protobuf.Descriptors.FieldDescriptor field) {\n"
+ " return (Builder) super.clearField(field);\n"
+ "}\n"
+ "public Builder clearOneof(\n"
+ " com.google.protobuf.Descriptors.OneofDescriptor oneof) {\n"
+ " return (Builder) super.clearOneof(oneof);\n"
+ "}\n"
+ "public Builder setRepeatedField(\n"
+ " com.google.protobuf.Descriptors.FieldDescriptor field,\n"
+ " int index, Object value) {\n"
+ " return (Builder) super.setRepeatedField(field, index, value);\n"
+ "}\n"
+ "public Builder addRepeatedField(\n"
+ " com.google.protobuf.Descriptors.FieldDescriptor field,\n"
+ " Object value) {\n"
+ " return (Builder) super.addRepeatedField(field, value);\n"
+ "}\n");
+
+ if (descriptor_->extension_range_count() > 0) {
+ printer->Print(
+ "public <Type> Builder setExtension(\n"
+ " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
+ " $classname$, Type> extension,\n"
+ " Type value) {\n"
+ " return (Builder) super.setExtension(extension, value);\n"
+ "}\n"
+ "public <Type> Builder setExtension(\n"
+ " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
+ " $classname$, java.util.List<Type>> extension,\n"
+ " int index, Type value) {\n"
+ " return (Builder) super.setExtension(extension, index, value);\n"
+ "}\n"
+ "public <Type> Builder addExtension(\n"
+ " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
+ " $classname$, java.util.List<Type>> extension,\n"
+ " Type value) {\n"
+ " return (Builder) super.addExtension(extension, value);\n"
+ "}\n"
+ "public <Type> Builder clearExtension(\n"
+ " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
+ " $classname$, ?> extension) {\n"
+ " return (Builder) super.clearExtension(extension);\n"
+ "}\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
+ }
+
// -----------------------------------------------------------------
- if (HasGeneratedMethods(descriptor_)) {
+ if (context_->HasGeneratedMethods(descriptor_)) {
printer->Print(
"public Builder mergeFrom(com.google.protobuf.Message other) {\n"
" if (other instanceof $classname$) {\n"
@@ -521,6 +596,7 @@ GenerateCommonBuilderMethods(io::Printer* printer) {
" return this;\n"
"}\n"
"\n");
+
}
}
@@ -538,7 +614,7 @@ GenerateBuilderParsingMethods(io::Printer* printer) {
" parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);\n"
" } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n"
" parsedMessage = ($classname$) e.getUnfinishedMessage();\n"
- " throw e;\n"
+ " throw e.unwrapIOException();\n"
" } finally {\n"
" if (parsedMessage != null) {\n"
" mergeFrom(parsedMessage);\n"
diff --git a/src/google/protobuf/compiler/java/java_message_builder_lite.cc b/src/google/protobuf/compiler/java/java_message_builder_lite.cc
index 8719d00d..dd429dc9 100644
--- a/src/google/protobuf/compiler/java/java_message_builder_lite.cc
+++ b/src/google/protobuf/compiler/java/java_message_builder_lite.cc
@@ -81,8 +81,9 @@ MessageBuilderLiteGenerator::MessageBuilderLiteGenerator(
: descriptor_(descriptor), context_(context),
name_resolver_(context->GetNameResolver()),
field_generators_(descriptor, context_) {
- GOOGLE_CHECK_EQ(
- FileOptions::LITE_RUNTIME, descriptor->file()->options().optimize_for());
+ GOOGLE_CHECK(!HasDescriptorMethods(descriptor->file(), context->EnforceLite()))
+ << "Generator factory error: A lite message generator is used to "
+ "generate non-lite messages.";
}
MessageBuilderLiteGenerator::~MessageBuilderLiteGenerator() {}
@@ -148,20 +149,6 @@ Generate(io::Printer* printer) {
.GenerateBuilderMembers(printer);
}
- if (!PreserveUnknownFields(descriptor_)) {
- printer->Print(
- "public final Builder setUnknownFields(\n"
- " final com.google.protobuf.UnknownFieldSet unknownFields) {\n"
- " return this;\n"
- "}\n"
- "\n"
- "public final Builder mergeUnknownFields(\n"
- " final com.google.protobuf.UnknownFieldSet unknownFields) {\n"
- " return this;\n"
- "}\n"
- "\n");
- }
-
printer->Print(
"\n"
"// @@protoc_insertion_point(builder_scope:$full_name$)\n",
diff --git a/src/google/protobuf/compiler/java/java_message_field.cc b/src/google/protobuf/compiler/java/java_message_field.cc
index b5f8e626..c9865dda 100644
--- a/src/google/protobuf/compiler/java/java_message_field.cc
+++ b/src/google/protobuf/compiler/java/java_message_field.cc
@@ -70,8 +70,11 @@ void SetMessageVariables(const FieldDescriptor* descriptor,
// by the proto compiler
(*variables)["deprecation"] = descriptor->options().deprecated()
? "@java.lang.Deprecated " : "";
- (*variables)["on_changed"] =
- HasDescriptorMethods(descriptor->containing_type()) ? "onChanged();" : "";
+ (*variables)["on_changed"] = "onChanged();";
+ (*variables)["ver"] = GeneratedCodeVersionSuffix();
+ (*variables)["get_parser"] =
+ ExposePublicParser(descriptor->message_type()->file())
+ ? "PARSER" : "parser()";
if (SupportFieldPresence(descriptor->file())) {
// For singular messages and builders, one bit is used for the hasField bit.
@@ -253,7 +256,7 @@ GenerateBuilderMembers(io::Printer* printer) const {
printer->Print(variables_,
// If this builder is non-null, it is used and the other fields are
// ignored.
- "private com.google.protobuf.SingleFieldBuilder<\n"
+ "private com.google.protobuf.SingleFieldBuilder$ver$<\n"
" $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;"
"\n");
@@ -375,11 +378,11 @@ GenerateBuilderMembers(io::Printer* printer) const {
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
- "private com.google.protobuf.SingleFieldBuilder<\n"
+ "private com.google.protobuf.SingleFieldBuilder$ver$<\n"
" $type$, $type$.Builder, $type$OrBuilder> \n"
" get$capitalized_name$FieldBuilder() {\n"
" if ($name$Builder_ == null) {\n"
- " $name$Builder_ = new com.google.protobuf.SingleFieldBuilder<\n"
+ " $name$Builder_ = new com.google.protobuf.SingleFieldBuilder$ver$<\n"
" $type$, $type$.Builder, $type$OrBuilder>(\n"
" get$capitalized_name$(),\n"
" getParentForChildren(),\n"
@@ -452,11 +455,11 @@ GenerateParsingCode(io::Printer* printer) const {
if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
printer->Print(variables_,
- "$name$_ = input.readGroup($number$, $type$.parser(),\n"
+ "$name$_ = input.readGroup($number$, $type$.$get_parser$,\n"
" extensionRegistry);\n");
} else {
printer->Print(variables_,
- "$name$_ = input.readMessage($type$.parser(), extensionRegistry);\n");
+ "$name$_ = input.readMessage($type$.$get_parser$, extensionRegistry);\n");
}
printer->Print(variables_,
@@ -561,7 +564,7 @@ GenerateBuilderMembers(io::Printer* printer) const {
printer->Print(variables_,
// If this builder is non-null, it is used and the other fields are
// ignored.
- "private com.google.protobuf.SingleFieldBuilder<\n"
+ "private com.google.protobuf.SingleFieldBuilder$ver$<\n"
" $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;"
"\n");
@@ -684,14 +687,14 @@ GenerateBuilderMembers(io::Printer* printer) const {
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
- "private com.google.protobuf.SingleFieldBuilder<\n"
+ "private com.google.protobuf.SingleFieldBuilder$ver$<\n"
" $type$, $type$.Builder, $type$OrBuilder> \n"
" get$capitalized_name$FieldBuilder() {\n"
" if ($name$Builder_ == null) {\n"
" if (!($has_oneof_case_message$)) {\n"
" $oneof_name$_ = $type$.getDefaultInstance();\n"
" }\n"
- " $name$Builder_ = new com.google.protobuf.SingleFieldBuilder<\n"
+ " $name$Builder_ = new com.google.protobuf.SingleFieldBuilder$ver$<\n"
" $type$, $type$.Builder, $type$OrBuilder>(\n"
" ($type$) $oneof_name$_,\n"
" getParentForChildren(),\n"
@@ -736,12 +739,12 @@ GenerateParsingCode(io::Printer* printer) const {
if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
printer->Print(variables_,
- "$oneof_name$_ = input.readGroup($number$, $type$.parser(),\n"
+ "$oneof_name$_ = input.readGroup($number$, $type$.$get_parser$,\n"
" extensionRegistry);\n");
} else {
printer->Print(variables_,
"$oneof_name$_ =\n"
- " input.readMessage($type$.parser(), extensionRegistry);\n");
+ " input.readMessage($type$.$get_parser$, extensionRegistry);\n");
}
printer->Print(variables_,
@@ -921,7 +924,7 @@ GenerateBuilderMembers(io::Printer* printer) const {
printer->Print(variables_,
// If this builder is non-null, it is used and the other fields are
// ignored.
- "private com.google.protobuf.RepeatedFieldBuilder<\n"
+ "private com.google.protobuf.RepeatedFieldBuilder$ver$<\n"
" $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;\n"
"\n");
@@ -1138,11 +1141,11 @@ GenerateBuilderMembers(io::Printer* printer) const {
" get$capitalized_name$BuilderList() {\n"
" return get$capitalized_name$FieldBuilder().getBuilderList();\n"
"}\n"
- "private com.google.protobuf.RepeatedFieldBuilder<\n"
+ "private com.google.protobuf.RepeatedFieldBuilder$ver$<\n"
" $type$, $type$.Builder, $type$OrBuilder> \n"
" get$capitalized_name$FieldBuilder() {\n"
" if ($name$Builder_ == null) {\n"
- " $name$Builder_ = new com.google.protobuf.RepeatedFieldBuilder<\n"
+ " $name$Builder_ = new com.google.protobuf.RepeatedFieldBuilder$ver$<\n"
" $type$, $type$.Builder, $type$OrBuilder>(\n"
" $name$_,\n"
" $get_mutable_bit_builder$,\n"
@@ -1200,7 +1203,7 @@ GenerateMergingCode(io::Printer* printer) const {
" $name$_ = other.$name$_;\n"
" $clear_mutable_bit_builder$;\n"
" $name$Builder_ = \n"
- " com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?\n"
+ " com.google.protobuf.GeneratedMessage$ver$.alwaysUseFieldBuilders ?\n"
" get$capitalized_name$FieldBuilder() : null;\n"
" } else {\n"
" $name$Builder_.addAllMessages(other.$name$_);\n"
@@ -1233,11 +1236,12 @@ GenerateParsingCode(io::Printer* printer) const {
if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
printer->Print(variables_,
- "$name$_.add(input.readGroup($number$, $type$.parser(),\n"
+ "$name$_.add(input.readGroup($number$, $type$.$get_parser$,\n"
" extensionRegistry));\n");
} else {
printer->Print(variables_,
- "$name$_.add(input.readMessage($type$.parser(), extensionRegistry));\n");
+ "$name$_.add(\n"
+ " input.readMessage($type$.$get_parser$, extensionRegistry));\n");
}
}
diff --git a/src/google/protobuf/compiler/java/java_message_field_lite.cc b/src/google/protobuf/compiler/java/java_message_field_lite.cc
index 356520ec..14281816 100644
--- a/src/google/protobuf/compiler/java/java_message_field_lite.cc
+++ b/src/google/protobuf/compiler/java/java_message_field_lite.cc
@@ -70,8 +70,6 @@ void SetMessageVariables(const FieldDescriptor* descriptor,
// by the proto compiler
(*variables)["deprecation"] = descriptor->options().deprecated()
? "@java.lang.Deprecated " : "";
- (*variables)["on_changed"] =
- HasDescriptorMethods(descriptor->containing_type()) ? "onChanged();" : "";
if (SupportFieldPresence(descriptor->file())) {
// For singular messages and builders, one bit is used for the hasField bit.
@@ -288,11 +286,9 @@ void ImmutableMessageFieldLiteGenerator::
GenerateInitializationCode(io::Printer* printer) const {}
void ImmutableMessageFieldLiteGenerator::
-GenerateMergingCode(io::Printer* printer) const {
+GenerateVisitCode(io::Printer* printer) const {
printer->Print(variables_,
- "if (other.has$capitalized_name$()) {\n"
- " merge$capitalized_name$(other.get$capitalized_name$());\n"
- "}\n");
+ "$name$_ = visitor.visitMessage($name$_, other.$name$_);\n");
}
void ImmutableMessageFieldLiteGenerator::
@@ -302,11 +298,18 @@ GenerateDynamicMethodMakeImmutableCode(io::Printer* printer) const {
void ImmutableMessageFieldLiteGenerator::
GenerateParsingCode(io::Printer* printer) const {
- printer->Print(variables_,
- "$type$.Builder subBuilder = null;\n"
- "if ($is_field_present_message$) {\n"
- " subBuilder = $name$_.toBuilder();\n"
- "}\n");
+ // TODO(dweis): Update this code to avoid the builder allocation and instead
+ // only allocate a submessage that isn't made immutable. Rely on the top
+ // message calling makeImmutable once done to actually traverse the tree and
+ // finalize state. This will avoid:
+ // - transitive builder allocations
+ // - the extra transitive iteration for streamed fields
+ // - reallocations for copying repeated fields
+ printer->Print(variables_,
+ "$type$.Builder subBuilder = null;\n"
+ "if ($is_field_present_message$) {\n"
+ " subBuilder = $name$_.toBuilder();\n"
+ "}\n");
if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
printer->Print(variables_,
@@ -506,9 +509,12 @@ GenerateBuilderMembers(io::Printer* printer) const {
}
void ImmutableMessageOneofFieldLiteGenerator::
-GenerateMergingCode(io::Printer* printer) const {
+GenerateVisitCode(io::Printer* printer) const {
printer->Print(variables_,
- "merge$capitalized_name$(other.get$capitalized_name$());\n");
+ "$oneof_name$_ = visitor.visitOneofMessage(\n"
+ " $has_oneof_case_message$,\n"
+ " $oneof_name$_,\n"
+ " other.$oneof_name$_);\n");
}
void ImmutableMessageOneofFieldLiteGenerator::
@@ -635,7 +641,8 @@ GenerateMembers(io::Printer* printer) const {
printer->Print(variables_,
"private void ensure$capitalized_name$IsMutable() {\n"
" if (!$is_mutable$) {\n"
- " $name$_ = newProtobufList($name$_);\n"
+ " $name$_ =\n"
+ " com.google.protobuf.GeneratedMessageLite.mutableCopy($name$_);\n"
" }\n"
"}\n"
"\n");
@@ -853,22 +860,9 @@ GenerateInitializationCode(io::Printer* printer) const {
}
void RepeatedImmutableMessageFieldLiteGenerator::
-GenerateMergingCode(io::Printer* printer) const {
- // The code below does two optimizations (non-nested builder case):
- // 1. If the other list is empty, there's nothing to do. This ensures we
- // don't allocate a new array if we already have an immutable one.
- // 2. If the other list is non-empty and our current list is empty, we can
- // reuse the other list which is guaranteed to be immutable.
- printer->Print(variables_,
- "if (!other.$name$_.isEmpty()) {\n"
- " if ($name$_.isEmpty()) {\n"
- " $name$_ = other.$name$_;\n"
- " } else {\n"
- " ensure$capitalized_name$IsMutable();\n"
- " $name$_.addAll(other.$name$_);\n"
- " }\n"
- " $on_changed$\n"
- "}\n");
+GenerateVisitCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "$name$_= visitor.visitList($name$_, other.$name$_);\n");
}
void RepeatedImmutableMessageFieldLiteGenerator::
@@ -881,7 +875,8 @@ void RepeatedImmutableMessageFieldLiteGenerator::
GenerateParsingCode(io::Printer* printer) const {
printer->Print(variables_,
"if (!$is_mutable$) {\n"
- " $name$_ = newProtobufList();\n"
+ " $name$_ =\n"
+ " com.google.protobuf.GeneratedMessageLite.mutableCopy($name$_);\n"
"}\n");
if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
diff --git a/src/google/protobuf/compiler/java/java_message_field_lite.h b/src/google/protobuf/compiler/java/java_message_field_lite.h
index ae26c06a..61321547 100644
--- a/src/google/protobuf/compiler/java/java_message_field_lite.h
+++ b/src/google/protobuf/compiler/java/java_message_field_lite.h
@@ -67,7 +67,7 @@ class ImmutableMessageFieldLiteGenerator : public ImmutableFieldLiteGenerator {
void GenerateMembers(io::Printer* printer) const;
void GenerateBuilderMembers(io::Printer* printer) const;
void GenerateInitializationCode(io::Printer* printer) const;
- void GenerateMergingCode(io::Printer* printer) const;
+ void GenerateVisitCode(io::Printer* printer) const;
void GenerateDynamicMethodMakeImmutableCode(io::Printer* printer) const;
void GenerateParsingCode(io::Printer* printer) const;
void GenerateParsingDoneCode(io::Printer* printer) const;
@@ -101,7 +101,7 @@ class ImmutableMessageOneofFieldLiteGenerator
void GenerateMembers(io::Printer* printer) const;
void GenerateBuilderMembers(io::Printer* printer) const;
- void GenerateMergingCode(io::Printer* printer) const;
+ void GenerateVisitCode(io::Printer* printer) const;
void GenerateParsingCode(io::Printer* printer) const;
void GenerateSerializationCode(io::Printer* printer) const;
void GenerateSerializedSizeCode(io::Printer* printer) const;
@@ -125,7 +125,7 @@ class RepeatedImmutableMessageFieldLiteGenerator
void GenerateMembers(io::Printer* printer) const;
void GenerateBuilderMembers(io::Printer* printer) const;
void GenerateInitializationCode(io::Printer* printer) const;
- void GenerateMergingCode(io::Printer* printer) const;
+ void GenerateVisitCode(io::Printer* printer) const;
void GenerateDynamicMethodMakeImmutableCode(io::Printer* printer) const;
void GenerateParsingCode(io::Printer* printer) const;
void GenerateParsingDoneCode(io::Printer* printer) const;
diff --git a/src/google/protobuf/compiler/java/java_message_lite.cc b/src/google/protobuf/compiler/java/java_message_lite.cc
index 94ed2c39..7c8c4a03 100644
--- a/src/google/protobuf/compiler/java/java_message_lite.cc
+++ b/src/google/protobuf/compiler/java/java_message_lite.cc
@@ -46,7 +46,7 @@
#include <google/protobuf/compiler/java/java_context.h>
#include <google/protobuf/compiler/java/java_doc_comment.h>
#include <google/protobuf/compiler/java/java_enum_lite.h>
-#include <google/protobuf/compiler/java/java_extension.h>
+#include <google/protobuf/compiler/java/java_extension_lite.h>
#include <google/protobuf/compiler/java/java_generator_factory.h>
#include <google/protobuf/compiler/java/java_helpers.h>
#include <google/protobuf/compiler/java/java_message_builder.h>
@@ -87,19 +87,20 @@ ImmutableMessageLiteGenerator::ImmutableMessageLiteGenerator(
: MessageGenerator(descriptor), context_(context),
name_resolver_(context->GetNameResolver()),
field_generators_(descriptor, context_) {
- GOOGLE_CHECK_EQ(
- FileOptions::LITE_RUNTIME, descriptor->file()->options().optimize_for());
+ GOOGLE_CHECK(!HasDescriptorMethods(descriptor->file(), context->EnforceLite()))
+ << "Generator factory error: A lite message generator is used to "
+ "generate non-lite messages.";
}
ImmutableMessageLiteGenerator::~ImmutableMessageLiteGenerator() {}
void ImmutableMessageLiteGenerator::GenerateStaticVariables(
- io::Printer* printer) {
+ io::Printer* printer, int* bytecode_estimate) {
// Generate static members for all nested types.
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
// TODO(kenton): Reuse MessageGenerator objects?
ImmutableMessageLiteGenerator(descriptor_->nested_type(i), context_)
- .GenerateStaticVariables(printer);
+ .GenerateStaticVariables(printer, bytecode_estimate);
}
}
@@ -119,23 +120,28 @@ int ImmutableMessageLiteGenerator::GenerateStaticVariableInitializers(
// ===================================================================
void ImmutableMessageLiteGenerator::GenerateInterface(io::Printer* printer) {
+ MaybePrintGeneratedAnnotation(context_, printer, descriptor_,
+ /* immutable = */ true, "OrBuilder");
if (descriptor_->extension_range_count() > 0) {
printer->Print(
- "public interface $classname$OrBuilder extends \n"
- " $extra_interfaces$\n"
- " com.google.protobuf.GeneratedMessageLite.\n"
- " ExtendableMessageOrBuilder<\n"
- " $classname$, $classname$.Builder> {\n",
- "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_),
- "classname", descriptor_->name());
+ "public interface $classname$OrBuilder$idend$ extends \n"
+ " $extra_interfaces$\n"
+ " com.google.protobuf.GeneratedMessageLite.\n"
+ " ExtendableMessageOrBuilder<\n"
+ " $classname$, $classname$.Builder> {\n",
+ "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_),
+ "classname", descriptor_->name(),
+ "idend", "");
} else {
printer->Print(
- "public interface $classname$OrBuilder extends\n"
- " $extra_interfaces$\n"
- " com.google.protobuf.MessageLiteOrBuilder {\n",
- "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_),
- "classname", descriptor_->name());
+ "public interface $classname$OrBuilder$idend$ extends\n"
+ " $extra_interfaces$\n"
+ " com.google.protobuf.MessageLiteOrBuilder {\n",
+ "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_),
+ "classname", descriptor_->name(),
+ "idend", "");
}
+ printer->Annotate("classname", "idend", descriptor_);
printer->Indent();
for (int i = 0; i < descriptor_->field_count(); i++) {
@@ -162,9 +168,7 @@ void ImmutableMessageLiteGenerator::GenerateInterface(io::Printer* printer) {
// ===================================================================
void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) {
- bool is_own_file =
- descriptor_->containing_type() == NULL &&
- MultipleJavaFiles(descriptor_->file(), /* immutable = */ true);
+ bool is_own_file = IsOwnFile(descriptor_, /* immutable = */ true);
map<string, string> variables;
variables["static"] = is_own_file ? " " : " static ";
@@ -172,6 +176,8 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) {
variables["extra_interfaces"] = ExtraMessageInterfaces(descriptor_);
WriteMessageDocComment(printer, descriptor_);
+ MaybePrintGeneratedAnnotation(context_, printer, descriptor_,
+ /* immutable = */ true);
// The builder_type stores the super type name of the nested Builder class.
string builder_type;
@@ -197,7 +203,8 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) {
}
printer->Indent();
- GenerateParsingConstructor(printer);
+
+ GenerateConstructor(printer);
// Nested types
for (int i = 0; i < descriptor_->enum_type_count(); i++) {
@@ -259,12 +266,20 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) {
"cap_oneof_name",
ToUpper(vars["oneof_name"]));
printer->Print(vars,
- "private int value = 0;\n"
+ "private final int value;\n"
"private $oneof_capitalized_name$Case(int value) {\n"
" this.value = value;\n"
"}\n");
printer->Print(vars,
+ "/**\n"
+ " * @deprecated Use {@link #forNumber(int)} instead.\n"
+ " */\n"
+ "@java.lang.Deprecated\n"
"public static $oneof_capitalized_name$Case valueOf(int value) {\n"
+ " return forNumber(value);\n"
+ "}\n"
+ "\n"
+ "public static $oneof_capitalized_name$Case forNumber(int value) {\n"
" switch (value) {\n");
for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
@@ -277,8 +292,7 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) {
}
printer->Print(
" case 0: return $cap_oneof_name$_NOT_SET;\n"
- " default: throw new java.lang.IllegalArgumentException(\n"
- " \"Value is undefined for this oneof enum.\");\n"
+ " default: return null;\n"
" }\n"
"}\n"
"public int getNumber() {\n"
@@ -291,7 +305,7 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) {
printer->Print(vars,
"public $oneof_capitalized_name$Case\n"
"get$oneof_capitalized_name$Case() {\n"
- " return $oneof_capitalized_name$Case.valueOf(\n"
+ " return $oneof_capitalized_name$Case.forNumber(\n"
" $oneof_name$Case_);\n"
"}\n"
"\n"
@@ -313,11 +327,6 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) {
GenerateMessageSerializationMethods(printer);
- if (HasEqualsAndHashCode(descriptor_)) {
- GenerateEqualsAndHashCode(printer);
- }
-
-
GenerateParseFromMethods(printer);
GenerateBuilder(printer);
@@ -334,16 +343,8 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) {
" com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n"
" Object arg0, Object arg1) {\n"
" switch (method) {\n"
- " case PARSE_PARTIAL_FROM: {\n"
- " return new $classname$("
- " (com.google.protobuf.CodedInputStream) arg0,\n"
- " (com.google.protobuf.ExtensionRegistryLite) arg1);\n"
- " }\n"
- " case NEW_INSTANCE: {\n"
- " return new $classname$(\n"
- " com.google.protobuf.Internal.EMPTY_CODED_INPUT_STREAM,\n"
- " com.google.protobuf.ExtensionRegistryLite\n"
- " .getEmptyRegistry());\n"
+ " case NEW_MUTABLE_INSTANCE: {\n"
+ " return new $classname$();\n"
" }\n",
"classname", name_resolver_->GetImmutableClassName(descriptor_));
@@ -374,10 +375,18 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) {
printer->Print(
"}\n"
- "case MERGE_FROM: {\n");
+ "case VISIT: {\n");
printer->Indent();
- GenerateDynamicMethodMergeFrom(printer);
+ GenerateDynamicMethodVisit(printer);
+ printer->Outdent();
+
+ printer->Print(
+ "}\n"
+ "case MERGE_FROM_STREAM: {\n");
+
+ printer->Indent();
+ GenerateDynamicMethodMergeFromStream(printer);
printer->Outdent();
printer->Print(
@@ -425,11 +434,8 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) {
printer->Print(
"static {\n"
- " DEFAULT_INSTANCE = new $classname$(\n"
- " com.google.protobuf.Internal\n"
- " .EMPTY_CODED_INPUT_STREAM,\n"
- " com.google.protobuf.ExtensionRegistryLite\n"
- " .getEmptyRegistry());\n"
+ " DEFAULT_INSTANCE = new $classname$();\n"
+ " DEFAULT_INSTANCE.makeImmutable();\n"
"}\n"
"\n",
"classname", descriptor_->name());
@@ -446,7 +452,7 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) {
// because the DEFAULT_INSTANCE is used by the extension to lazily retrieve
// the outer class's FileDescriptor.
for (int i = 0; i < descriptor_->extension_count(); i++) {
- ImmutableExtensionGenerator(descriptor_->extension(i), context_)
+ ImmutableExtensionLiteGenerator(descriptor_->extension(i), context_)
.Generate(printer);
}
@@ -557,9 +563,6 @@ GenerateMessageSerializationMethods(io::Printer* printer) {
" return size;\n"
"}\n"
"\n");
-
- printer->Print(
- "private static final long serialVersionUID = 0L;\n");
}
void ImmutableMessageLiteGenerator::
@@ -571,54 +574,62 @@ GenerateParseFromMethods(io::Printer* printer) {
"public static $classname$ parseFrom(\n"
" com.google.protobuf.ByteString data)\n"
" throws com.google.protobuf.InvalidProtocolBufferException {\n"
- " return parser().parseFrom(data);\n"
+ " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
+ " DEFAULT_INSTANCE, data);\n"
"}\n"
"public static $classname$ parseFrom(\n"
" com.google.protobuf.ByteString data,\n"
" com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
" throws com.google.protobuf.InvalidProtocolBufferException {\n"
- " return parser().parseFrom(data, extensionRegistry);\n"
+ " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
+ " DEFAULT_INSTANCE, data, extensionRegistry);\n"
"}\n"
"public static $classname$ parseFrom(byte[] data)\n"
" throws com.google.protobuf.InvalidProtocolBufferException {\n"
- " return parser().parseFrom(data);\n"
+ " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
+ " DEFAULT_INSTANCE, data);\n"
"}\n"
"public static $classname$ parseFrom(\n"
" byte[] data,\n"
" com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
" throws com.google.protobuf.InvalidProtocolBufferException {\n"
- " return parser().parseFrom(data, extensionRegistry);\n"
+ " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
+ " DEFAULT_INSTANCE, data, extensionRegistry);\n"
"}\n"
"public static $classname$ parseFrom(java.io.InputStream input)\n"
" throws java.io.IOException {\n"
- " return parser().parseFrom(input);\n"
+ " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
+ " DEFAULT_INSTANCE, input);\n"
"}\n"
"public static $classname$ parseFrom(\n"
" java.io.InputStream input,\n"
" com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
" throws java.io.IOException {\n"
- " return parser().parseFrom(input, extensionRegistry);\n"
+ " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
+ " DEFAULT_INSTANCE, input, extensionRegistry);\n"
"}\n"
"public static $classname$ parseDelimitedFrom(java.io.InputStream input)\n"
" throws java.io.IOException {\n"
- " return parser().parseDelimitedFrom(input);\n"
+ " return parseDelimitedFrom(DEFAULT_INSTANCE, input);\n"
"}\n"
"public static $classname$ parseDelimitedFrom(\n"
" java.io.InputStream input,\n"
" com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
" throws java.io.IOException {\n"
- " return parser().parseDelimitedFrom(input, extensionRegistry);\n"
+ " return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);\n"
"}\n"
"public static $classname$ parseFrom(\n"
" com.google.protobuf.CodedInputStream input)\n"
" throws java.io.IOException {\n"
- " return parser().parseFrom(input);\n"
+ " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
+ " DEFAULT_INSTANCE, input);\n"
"}\n"
"public static $classname$ parseFrom(\n"
" com.google.protobuf.CodedInputStream input,\n"
" com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
" throws java.io.IOException {\n"
- " return parser().parseFrom(input, extensionRegistry);\n"
+ " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
+ " DEFAULT_INSTANCE, input, extensionRegistry);\n"
"}\n"
"\n",
"classname", name_resolver_->GetImmutableClassName(descriptor_));
@@ -789,11 +800,13 @@ void ImmutableMessageLiteGenerator::GenerateDynamicMethodIsInitialized(
void ImmutableMessageLiteGenerator::GenerateDynamicMethodMakeImmutable(
io::Printer* printer) {
+
// Output generation code for each field.
for (int i = 0; i < descriptor_->field_count(); i++) {
field_generators_.get(descriptor_->field(i))
.GenerateDynamicMethodMakeImmutableCode(printer);
}
+
printer->Print(
"return null;\n");
}
@@ -808,19 +821,17 @@ void ImmutableMessageLiteGenerator::GenerateDynamicMethodNewBuilder(
// ===================================================================
-void ImmutableMessageLiteGenerator::GenerateDynamicMethodMergeFrom(
+void ImmutableMessageLiteGenerator::GenerateDynamicMethodVisit(
io::Printer* printer) {
printer->Print(
- // Optimization: If other is the default instance, we know none of its
- // fields are set so we can skip the merge.
- "if (arg0 == $classname$.getDefaultInstance()) return this;\n"
- "$classname$ other = ($classname$) arg0;\n",
+ "Visitor visitor = (Visitor) arg0;\n"
+ "$classname$ other = ($classname$) arg1;\n",
"classname", name_resolver_->GetImmutableClassName(descriptor_));
for (int i = 0; i < descriptor_->field_count(); i++) {
if (!descriptor_->field(i)->containing_oneof()) {
field_generators_.get(
- descriptor_->field(i)).GenerateMergingCode(printer);
+ descriptor_->field(i)).GenerateVisitCode(printer);
}
}
@@ -839,7 +850,7 @@ void ImmutableMessageLiteGenerator::GenerateDynamicMethodMergeFrom(
"field_name",
ToUpper(field->name()));
printer->Indent();
- field_generators_.get(field).GenerateMergingCode(printer);
+ field_generators_.get(field).GenerateVisitCode(printer);
printer->Print(
"break;\n");
printer->Outdent();
@@ -848,188 +859,66 @@ void ImmutableMessageLiteGenerator::GenerateDynamicMethodMergeFrom(
}
printer->Print(
"case $cap_oneof_name$_NOT_SET: {\n"
+ " visitor.visitOneofNotSet($oneof_name$Case_ != 0);\n"
" break;\n"
"}\n",
"cap_oneof_name",
ToUpper(context_->GetOneofGeneratorInfo(
- descriptor_->oneof_decl(i))->name));
+ descriptor_->oneof_decl(i))->name),
+ "oneof_name",
+ context_->GetOneofGeneratorInfo(
+ descriptor_->oneof_decl(i))->name);
printer->Outdent();
printer->Print(
"}\n");
}
- // if message type has extensions
- if (descriptor_->extension_range_count() > 0) {
- printer->Print(
- "this.mergeExtensionFields(other);\n");
- }
-
- if (PreserveUnknownFields(descriptor_)) {
- printer->Print(
- "this.mergeUnknownFields(other.unknownFields);\n");
- }
-
- printer->Print(
- "return this;\n");
-}
-
-// ===================================================================
-
-namespace {
-bool CheckHasBitsForEqualsAndHashCode(const FieldDescriptor* field) {
- if (field->is_repeated()) {
- return false;
- }
- if (SupportFieldPresence(field->file())) {
- return true;
- }
- return GetJavaType(field) == JAVATYPE_MESSAGE &&
- field->containing_oneof() == NULL;
-}
-} // namespace
-
-void ImmutableMessageLiteGenerator::
-GenerateEqualsAndHashCode(io::Printer* printer) {
printer->Print(
- "@java.lang.Override\n"
- "public boolean equals(final java.lang.Object obj) {\n");
+ "if (visitor == com.google.protobuf.GeneratedMessageLite.MergeFromVisitor\n"
+ " .INSTANCE) {\n");
printer->Indent();
- printer->Print(
- "if (obj == this) {\n"
- " return true;\n"
- "}\n"
- "if (!(obj instanceof $classname$)) {\n"
- " return super.equals(obj);\n"
- "}\n"
- "$classname$ other = ($classname$) obj;\n"
- "\n",
- "classname", name_resolver_->GetImmutableClassName(descriptor_));
-
- printer->Print("boolean result = true;\n");
- for (int i = 0; i < descriptor_->field_count(); i++) {
- const FieldDescriptor* field = descriptor_->field(i);
- const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
- bool check_has_bits = CheckHasBitsForEqualsAndHashCode(field);
- if (check_has_bits) {
- printer->Print(
- "result = result && (has$name$() == other.has$name$());\n"
- "if (has$name$()) {\n",
- "name", info->capitalized_name);
- printer->Indent();
- }
- field_generators_.get(field).GenerateEqualsCode(printer);
- if (check_has_bits) {
- printer->Outdent();
- printer->Print(
- "}\n");
- }
- }
- if (PreserveUnknownFields(descriptor_)) {
- // Always consider unknown fields for equality. This will sometimes return
- // false for non-canonical ordering when running in LITE_RUNTIME but it's
- // the best we can do.
+ for (int i = 0; i < descriptor_->oneof_decl_count(); ++i) {
+ const OneofDescriptor* field = descriptor_->oneof_decl(i);
printer->Print(
- "result = result && unknownFields.equals(other.unknownFields);\n");
+ "if (other.$oneof_name$Case_ != 0) {\n"
+ " $oneof_name$Case_ = other.$oneof_name$Case_;\n"
+ "}\n",
+ "oneof_name", context_->GetOneofGeneratorInfo(field)->name);
}
- printer->Print(
- "return result;\n");
- printer->Outdent();
- printer->Print(
- "}\n"
- "\n");
- printer->Print(
- "@java.lang.Override\n"
- "public int hashCode() {\n");
- printer->Indent();
- printer->Print(
- "if (memoizedHashCode != 0) {\n");
- printer->Indent();
- printer->Print(
- "return memoizedHashCode;\n");
- printer->Outdent();
- printer->Print(
- "}\n"
- "int hash = 41;\n");
-
- // Include the hash of the class so that two objects with different types
- // but the same field values will probably have different hashes.
- printer->Print("hash = (19 * hash) + $classname$.class.hashCode();\n",
- "classname", name_resolver_->GetImmutableClassName(descriptor_));
+ if (GenerateHasBits(descriptor_)) {
+ // Integers for bit fields.
+ int totalBits = 0;
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ totalBits += field_generators_.get(descriptor_->field(i))
+ .GetNumBitsForMessage();
+ }
+ int totalInts = (totalBits + 31) / 32;
- for (int i = 0; i < descriptor_->field_count(); i++) {
- const FieldDescriptor* field = descriptor_->field(i);
- const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
- bool check_has_bits = CheckHasBitsForEqualsAndHashCode(field);
- if (check_has_bits) {
+ for (int i = 0; i < totalInts; i++) {
printer->Print(
- "if (has$name$()) {\n",
- "name", info->capitalized_name);
- printer->Indent();
- }
- field_generators_.get(field).GenerateHashCode(printer);
- if (check_has_bits) {
- printer->Outdent();
- printer->Print("}\n");
+ "$bit_field_name$ |= other.$bit_field_name$;\n",
+ "bit_field_name", GetBitFieldName(i));
}
}
-
- printer->Print(
- "hash = (29 * hash) + unknownFields.hashCode();\n");
- printer->Print(
- "memoizedHashCode = hash;\n"
- "return hash;\n");
printer->Outdent();
printer->Print(
- "}\n"
- "\n");
-}
+ "}\n");
-// ===================================================================
-
-void ImmutableMessageLiteGenerator::
-GenerateExtensionRegistrationCode(io::Printer* printer) {
- for (int i = 0; i < descriptor_->extension_count(); i++) {
- ImmutableExtensionGenerator(descriptor_->extension(i), context_)
- .GenerateRegistrationCode(printer);
- }
- for (int i = 0; i < descriptor_->nested_type_count(); i++) {
- ImmutableMessageLiteGenerator(descriptor_->nested_type(i), context_)
- .GenerateExtensionRegistrationCode(printer);
- }
+ printer->Print(
+ "return this;\n");
}
// ===================================================================
-void ImmutableMessageLiteGenerator::
-GenerateParsingConstructor(io::Printer* printer) {
- google::protobuf::scoped_array<const FieldDescriptor * > sorted_fields(
- SortFieldsByNumber(descriptor_));
-
- printer->Print(
- "private $classname$(\n"
- " com.google.protobuf.CodedInputStream input,\n"
- " com.google.protobuf.ExtensionRegistryLite extensionRegistry) {\n",
- "classname", descriptor_->name());
- printer->Indent();
-
- // Initialize all fields to default.
- GenerateInitializers(printer);
-
- // Use builder bits to track mutable repeated fields.
- int totalBuilderBits = 0;
- for (int i = 0; i < descriptor_->field_count(); i++) {
- const ImmutableFieldLiteGenerator& field =
- field_generators_.get(descriptor_->field(i));
- totalBuilderBits += field.GetNumBitsForBuilder();
- }
- int totalBuilderInts = (totalBuilderBits + 31) / 32;
- for (int i = 0; i < totalBuilderInts; i++) {
- printer->Print("int mutable_$bit_field_name$ = 0;\n",
- "bit_field_name", GetBitFieldName(i));
- }
+void ImmutableMessageLiteGenerator::GenerateDynamicMethodMergeFromStream(
+ io::Printer* printer) {
printer->Print(
+ "com.google.protobuf.CodedInputStream input =\n"
+ " (com.google.protobuf.CodedInputStream) arg0;\n"
+ "com.google.protobuf.ExtensionRegistryLite extensionRegistry =\n"
+ " (com.google.protobuf.ExtensionRegistryLite) arg1;\n"
"try {\n");
printer->Indent();
@@ -1077,6 +966,8 @@ GenerateParsingConstructor(io::Printer* printer) {
"}\n");
}
+ google::protobuf::scoped_array<const FieldDescriptor * > sorted_fields(
+ SortFieldsByNumber(descriptor_));
for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor* field = sorted_fields[i];
uint32 tag = WireFormatLite::MakeTag(field->number(),
@@ -1130,19 +1021,54 @@ GenerateParsingConstructor(io::Printer* printer) {
"} finally {\n");
printer->Indent();
- // Make repeated field list immutable.
- for (int i = 0; i < descriptor_->field_count(); i++) {
- const FieldDescriptor* field = sorted_fields[i];
- field_generators_.get(field).GenerateParsingDoneCode(printer);
+ printer->Outdent();
+ printer->Print(
+ "}\n"); // finally
+}
+
+// ===================================================================
+
+namespace {
+bool CheckHasBitsForEqualsAndHashCode(const FieldDescriptor* field) {
+ if (field->is_repeated()) {
+ return false;
+ }
+ if (SupportFieldPresence(field->file())) {
+ return true;
+ }
+ return GetJavaType(field) == JAVATYPE_MESSAGE &&
+ field->containing_oneof() == NULL;
+}
+} // namespace
+
+// ===================================================================
+
+void ImmutableMessageLiteGenerator::
+GenerateExtensionRegistrationCode(io::Printer* printer) {
+ for (int i = 0; i < descriptor_->extension_count(); i++) {
+ ImmutableExtensionLiteGenerator(descriptor_->extension(i), context_)
+ .GenerateRegistrationCode(printer);
}
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ ImmutableMessageLiteGenerator(descriptor_->nested_type(i), context_)
+ .GenerateExtensionRegistrationCode(printer);
+ }
+}
+
+// ===================================================================
+void ImmutableMessageLiteGenerator::
+GenerateConstructor(io::Printer* printer) {
printer->Print(
- "doneParsing();\n");
+ "private $classname$() {\n",
+ "classname", descriptor_->name());
+ printer->Indent();
+
+ // Initialize all fields to default.
+ GenerateInitializers(printer);
- printer->Outdent();
printer->Outdent();
printer->Print(
- " }\n" // finally
"}\n");
}
@@ -1167,7 +1093,6 @@ void ImmutableMessageLiteGenerator::GenerateInitializers(io::Printer* printer) {
}
}
-
} // namespace java
} // namespace compiler
} // namespace protobuf
diff --git a/src/google/protobuf/compiler/java/java_message_lite.h b/src/google/protobuf/compiler/java/java_message_lite.h
index 2bd3cdd4..1e319c6d 100644
--- a/src/google/protobuf/compiler/java/java_message_lite.h
+++ b/src/google/protobuf/compiler/java/java_message_lite.h
@@ -47,14 +47,14 @@ namespace java {
class ImmutableMessageLiteGenerator : public MessageGenerator {
public:
- explicit ImmutableMessageLiteGenerator(const Descriptor* descriptor,
- Context* context);
+ ImmutableMessageLiteGenerator(const Descriptor* descriptor, Context* context);
virtual ~ImmutableMessageLiteGenerator();
virtual void Generate(io::Printer* printer);
virtual void GenerateInterface(io::Printer* printer);
virtual void GenerateExtensionRegistrationCode(io::Printer* printer);
- virtual void GenerateStaticVariables(io::Printer* printer);
+ virtual void GenerateStaticVariables(
+ io::Printer* printer, int* bytecode_estimate);
virtual int GenerateStaticVariableInitializers(io::Printer* printer);
private:
@@ -69,12 +69,13 @@ class ImmutableMessageLiteGenerator : public MessageGenerator {
void GenerateBuilder(io::Printer* printer);
void GenerateDynamicMethodIsInitialized(io::Printer* printer);
void GenerateDynamicMethodMakeImmutable(io::Printer* printer);
- void GenerateDynamicMethodMergeFrom(io::Printer* printer);
+ void GenerateDynamicMethodVisit(io::Printer* printer);
+ void GenerateDynamicMethodMergeFromStream(io::Printer* printer);
void GenerateDynamicMethodNewBuilder(io::Printer* printer);
void GenerateInitializers(io::Printer* printer);
void GenerateEqualsAndHashCode(io::Printer* printer);
void GenerateParser(io::Printer* printer);
- void GenerateParsingConstructor(io::Printer* printer);
+ void GenerateConstructor(io::Printer* printer);
Context* context_;
ClassNameResolver* name_resolver_;
diff --git a/src/google/protobuf/compiler/java/java_name_resolver.cc b/src/google/protobuf/compiler/java/java_name_resolver.cc
index 0c363f9f..bffe4f16 100644
--- a/src/google/protobuf/compiler/java/java_name_resolver.cc
+++ b/src/google/protobuf/compiler/java/java_name_resolver.cc
@@ -259,6 +259,13 @@ string ClassNameResolver::GetJavaImmutableClassName(
descriptor->file(), true);
}
+string ClassNameResolver::GetJavaImmutableClassName(
+ const EnumDescriptor* descriptor) {
+ return GetJavaClassFullName(
+ ClassNameWithoutPackage(descriptor, true),
+ descriptor->file(), true);
+}
+
} // namespace java
} // namespace compiler
diff --git a/src/google/protobuf/compiler/java/java_name_resolver.h b/src/google/protobuf/compiler/java/java_name_resolver.h
index ab60b0a0..570d8d8f 100644
--- a/src/google/protobuf/compiler/java/java_name_resolver.h
+++ b/src/google/protobuf/compiler/java/java_name_resolver.h
@@ -98,6 +98,7 @@ class ClassNameResolver {
// For example:
// com.package.OuterClass$OuterMessage$InnerMessage
string GetJavaImmutableClassName(const Descriptor* descriptor);
+ string GetJavaImmutableClassName(const EnumDescriptor* descriptor);
private:
// Get the full name of a Java class by prepending the Java package name
// or outer class name.
diff --git a/src/google/protobuf/compiler/java/java_options.h b/src/google/protobuf/compiler/java/java_options.h
new file mode 100644
index 00000000..7bce1447
--- /dev/null
+++ b/src/google/protobuf/compiler/java/java_options.h
@@ -0,0 +1,73 @@
+// 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.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_OPTIONS_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_OPTIONS_H__
+
+#include <string>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+// Generator options
+struct Options {
+ Options()
+ : generate_immutable_code(false),
+ generate_mutable_code(false),
+ generate_shared_code(false),
+ enforce_lite(false),
+ annotate_code(false) {
+ }
+
+ bool generate_immutable_code;
+ bool generate_mutable_code;
+ bool generate_shared_code;
+ // When set, the protoc will generate the current files and all the transitive
+ // dependencies as lite runtime.
+ bool enforce_lite;
+ // If true, we should build .meta files and emit @Generated annotations into
+ // generated code.
+ bool annotate_code;
+ // Name of a file where we will write a list of generated .meta file names,
+ // one per line.
+ string annotation_list_file;
+ // Name of a file where we will write a list of generated file names, one
+ // per line.
+ string output_list_file;
+};
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_OPTIONS_H__
diff --git a/src/google/protobuf/compiler/java/java_plugin_unittest.cc b/src/google/protobuf/compiler/java/java_plugin_unittest.cc
index fe527623..3e4910c8 100644
--- a/src/google/protobuf/compiler/java/java_plugin_unittest.cc
+++ b/src/google/protobuf/compiler/java/java_plugin_unittest.cc
@@ -44,9 +44,10 @@
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/io/printer.h>
+#include <google/protobuf/testing/file.h>
+#include <google/protobuf/testing/file.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
-#include <google/protobuf/testing/file.h>
namespace google {
namespace protobuf {
diff --git a/src/google/protobuf/compiler/java/java_primitive_field.cc b/src/google/protobuf/compiler/java/java_primitive_field.cc
index 178bbe19..877baf0a 100644
--- a/src/google/protobuf/compiler/java/java_primitive_field.cc
+++ b/src/google/protobuf/compiler/java/java_primitive_field.cc
@@ -75,12 +75,7 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
"" : ("= " + ImmutableDefaultValue(descriptor, name_resolver));
(*variables)["capitalized_type"] =
GetCapitalizedType(descriptor, /* immutable = */ true);
- if (descriptor->is_packed()) {
- (*variables)["tag"] = SimpleItoa(WireFormatLite::MakeTag(
- descriptor->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED));
- } else {
- (*variables)["tag"] = SimpleItoa(WireFormat::MakeTag(descriptor));
- }
+ (*variables)["tag"] = SimpleItoa(WireFormat::MakeTag(descriptor));
(*variables)["tag_size"] = SimpleItoa(
WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
if (IsReferenceType(GetJavaType(descriptor))) {
@@ -99,8 +94,7 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
if (fixed_size != -1) {
(*variables)["fixed_size"] = SimpleItoa(fixed_size);
}
- (*variables)["on_changed"] =
- HasDescriptorMethods(descriptor->containing_type()) ? "onChanged();" : "";
+ (*variables)["on_changed"] = "onChanged();";
if (SupportFieldPresence(descriptor->file())) {
// For singular messages and builders, one bit is used for the hasField bit.
@@ -606,7 +600,7 @@ GenerateMembers(io::Printer* printer) const {
"}\n");
if (descriptor_->is_packed() &&
- HasGeneratedMethods(descriptor_->containing_type())) {
+ context_->HasGeneratedMethods(descriptor_->containing_type())) {
printer->Print(variables_,
"private int $name$MemoizedSerializedSize = -1;\n");
}
@@ -783,8 +777,8 @@ GenerateSerializationCode(io::Printer* printer) const {
// That makes it safe to rely on the memoized size here.
printer->Print(variables_,
"if (get$capitalized_name$List().size() > 0) {\n"
- " output.writeRawVarint32($tag$);\n"
- " output.writeRawVarint32($name$MemoizedSerializedSize);\n"
+ " output.writeUInt32NoTag($tag$);\n"
+ " output.writeUInt32NoTag($name$MemoizedSerializedSize);\n"
"}\n"
"for (int i = 0; i < $name$_.size(); i++) {\n"
" output.write$capitalized_type$NoTag($name$_.get(i));\n"
diff --git a/src/google/protobuf/compiler/java/java_primitive_field_lite.cc b/src/google/protobuf/compiler/java/java_primitive_field_lite.cc
index 392333b8..ad2db30c 100644
--- a/src/google/protobuf/compiler/java/java_primitive_field_lite.cc
+++ b/src/google/protobuf/compiler/java/java_primitive_field_lite.cc
@@ -63,22 +63,20 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
ClassNameResolver* name_resolver,
map<string, string>* variables) {
SetCommonFieldVariables(descriptor, info, variables);
-
- (*variables)["type"] = PrimitiveTypeName(GetJavaType(descriptor));
- (*variables)["boxed_type"] = BoxedPrimitiveTypeName(GetJavaType(descriptor));
+ JavaType javaType = GetJavaType(descriptor);
+ (*variables)["type"] = PrimitiveTypeName(javaType);
+ (*variables)["boxed_type"] = BoxedPrimitiveTypeName(javaType);
(*variables)["field_type"] = (*variables)["type"];
(*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver);
- (*variables)["default_init"] = IsDefaultValueJavaDefault(descriptor) ?
- "" : ("= " + ImmutableDefaultValue(descriptor, name_resolver));
(*variables)["capitalized_type"] =
GetCapitalizedType(descriptor, /* immutable = */ true);
(*variables)["tag"] = SimpleItoa(WireFormat::MakeTag(descriptor));
(*variables)["tag_size"] = SimpleItoa(
WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
- string capitalized_type = UnderscoresToCamelCase(PrimitiveTypeName(
- GetJavaType(descriptor)), true /* cap_next_letter */);
- switch (GetJavaType(descriptor)) {
+ string capitalized_type = UnderscoresToCamelCase(PrimitiveTypeName(javaType),
+ true /* cap_next_letter */);
+ switch (javaType) {
case JAVATYPE_INT:
case JAVATYPE_LONG:
case JAVATYPE_FLOAT:
@@ -86,32 +84,38 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
case JAVATYPE_BOOLEAN:
(*variables)["field_list_type"] =
"com.google.protobuf.Internal." + capitalized_type + "List";
- (*variables)["new_list"] = "new" + capitalized_type + "List";
(*variables)["empty_list"] = "empty" + capitalized_type + "List()";
(*variables)["make_name_unmodifiable"] =
(*variables)["name"] + "_.makeImmutable()";
- (*variables)["repeated_index_get"] =
- (*variables)["name"] + "_.get" + capitalized_type + "(index)";
+ (*variables)["repeated_get"] =
+ (*variables)["name"] + "_.get" + capitalized_type;
(*variables)["repeated_add"] =
(*variables)["name"] + "_.add" + capitalized_type;
(*variables)["repeated_set"] =
(*variables)["name"] + "_.set" + capitalized_type;
+ (*variables)["visit_type"] = capitalized_type;
+ (*variables)["visit_type_list"] = "visit" + capitalized_type + "List";
break;
default:
(*variables)["field_list_type"] =
"com.google.protobuf.Internal.ProtobufList<" +
(*variables)["boxed_type"] + ">";
- (*variables)["new_list"] = "newProtobufList";
(*variables)["empty_list"] = "emptyProtobufList()";
(*variables)["make_name_unmodifiable"] =
(*variables)["name"] + "_.makeImmutable()";
- (*variables)["repeated_index_get"] =
- (*variables)["name"] + "_.get(index)";
+ (*variables)["repeated_get"] = (*variables)["name"] + "_.get";
(*variables)["repeated_add"] = (*variables)["name"] + "_.add";
(*variables)["repeated_set"] = (*variables)["name"] + "_.set";
+ (*variables)["visit_type"] = "ByteString";
+ (*variables)["visit_type_list"] = "visitList";
+ }
+
+ if (javaType == JAVATYPE_BYTES) {
+ (*variables)["bytes_default"] =
+ ToUpper((*variables)["name"]) + "_DEFAULT_VALUE";
}
- if (IsReferenceType(GetJavaType(descriptor))) {
+ if (IsReferenceType(javaType)) {
(*variables)["null_check"] =
" if (value == null) {\n"
" throw new NullPointerException();\n"
@@ -127,8 +131,6 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
if (fixed_size != -1) {
(*variables)["fixed_size"] = SimpleItoa(fixed_size);
}
- (*variables)["on_changed"] =
- HasDescriptorMethods(descriptor->containing_type()) ? "onChanged();" : "";
if (SupportFieldPresence(descriptor->file())) {
// For singular messages and builders, one bit is used for the hasField bit.
@@ -205,6 +207,13 @@ GenerateInterfaceMembers(io::Printer* printer) const {
void ImmutablePrimitiveFieldLiteGenerator::
GenerateMembers(io::Printer* printer) const {
+ if (IsByteStringWithCustomDefaultValue(descriptor_)) {
+ // allocate this once statically since we know ByteStrings are immutable
+ // values that can be reused.
+ printer->Print(
+ variables_,
+ "private static final $field_type$ $bytes_default$ = $default$;\n");
+ }
printer->Print(variables_,
"private $field_type$ $name$_;\n");
PrintExtraFieldInfo(variables_, printer);
@@ -288,7 +297,11 @@ GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
void ImmutablePrimitiveFieldLiteGenerator::
GenerateInitializationCode(io::Printer* printer) const {
- printer->Print(variables_, "$name$_ = $default$;\n");
+ if (IsByteStringWithCustomDefaultValue(descriptor_)) {
+ printer->Print(variables_, "$name$_ = $bytes_default$;\n");
+ } else if (!IsDefaultValueJavaDefault(descriptor_)) {
+ printer->Print(variables_, "$name$_ = $default$;\n");
+ }
}
void ImmutablePrimitiveFieldLiteGenerator::
@@ -297,17 +310,16 @@ GenerateBuilderClearCode(io::Printer* printer) const {
}
void ImmutablePrimitiveFieldLiteGenerator::
-GenerateMergingCode(io::Printer* printer) const {
+GenerateVisitCode(io::Printer* printer) const {
if (SupportFieldPresence(descriptor_->file())) {
printer->Print(variables_,
- "if (other.has$capitalized_name$()) {\n"
- " set$capitalized_name$(other.get$capitalized_name$());\n"
- "}\n");
+ "$name$_ = visitor.visit$visit_type$(\n"
+ " has$capitalized_name$(), $name$_,\n"
+ " other.has$capitalized_name$(), other.$name$_);\n");
} else {
printer->Print(variables_,
- "if (other.get$capitalized_name$() != $default$) {\n"
- " set$capitalized_name$(other.get$capitalized_name$());\n"
- "}\n");
+ "$name$_ = visitor.visit$visit_type$($name$_ != $default$, $name$_,\n"
+ " other.$name$_ != $default$, other.$name$_);\n");
}
}
@@ -539,9 +551,10 @@ GenerateBuildingCode(io::Printer* printer) const {
}
void ImmutablePrimitiveOneofFieldLiteGenerator::
-GenerateMergingCode(io::Printer* printer) const {
+GenerateVisitCode(io::Printer* printer) const {
printer->Print(variables_,
- "set$capitalized_name$(other.get$capitalized_name$());\n");
+ "$oneof_name$_ = visitor.visitOneof$visit_type$(\n"
+ " $has_oneof_case_message$, $oneof_name$_, other.$oneof_name$_);\n");
}
void ImmutablePrimitiveOneofFieldLiteGenerator::
@@ -629,11 +642,11 @@ GenerateMembers(io::Printer* printer) const {
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public $type$ get$capitalized_name$(int index) {\n"
- " return $repeated_index_get$;\n"
+ " return $repeated_get$(index);\n"
"}\n");
if (descriptor_->options().packed() &&
- HasGeneratedMethods(descriptor_->containing_type())) {
+ context_->HasGeneratedMethods(descriptor_->containing_type())) {
printer->Print(variables_,
"private int $name$MemoizedSerializedSize = -1;\n");
}
@@ -641,7 +654,8 @@ GenerateMembers(io::Printer* printer) const {
printer->Print(variables_,
"private void ensure$capitalized_name$IsMutable() {\n"
" if (!$is_mutable$) {\n"
- " $name$_ = $new_list$($name$_);\n"
+ " $name$_ =\n"
+ " com.google.protobuf.GeneratedMessageLite.mutableCopy($name$_);\n"
" }\n"
"}\n");
@@ -742,22 +756,9 @@ GenerateBuilderClearCode(io::Printer* printer) const {
}
void RepeatedImmutablePrimitiveFieldLiteGenerator::
-GenerateMergingCode(io::Printer* printer) const {
- // The code below does two optimizations:
- // 1. If the other list is empty, there's nothing to do. This ensures we
- // don't allocate a new array if we already have an immutable one.
- // 2. If the other list is non-empty and our current list is empty, we can
- // reuse the other list which is guaranteed to be immutable.
- printer->Print(variables_,
- "if (!other.$name$_.isEmpty()) {\n"
- " if ($name$_.isEmpty()) {\n"
- " $name$_ = other.$name$_;\n"
- " } else {\n"
- " ensure$capitalized_name$IsMutable();\n"
- " $name$_.addAll(other.$name$_);\n"
- " }\n"
- " $on_changed$\n"
- "}\n");
+GenerateVisitCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "$name$_= visitor.$visit_type_list$($name$_, other.$name$_);\n");
}
void RepeatedImmutablePrimitiveFieldLiteGenerator::
@@ -773,9 +774,13 @@ GenerateDynamicMethodMakeImmutableCode(io::Printer* printer) const {
void RepeatedImmutablePrimitiveFieldLiteGenerator::
GenerateParsingCode(io::Printer* printer) const {
+ // TODO(dweis): Scan the input buffer to count, then initialize
+ // appropriately.
+ // TODO(dweis): Scan the input buffer to count and ensure capacity.
printer->Print(variables_,
"if (!$is_mutable$) {\n"
- " $name$_ = $new_list$();\n"
+ " $name$_ =\n"
+ " com.google.protobuf.GeneratedMessageLite.mutableCopy($name$_);\n"
"}\n"
"$repeated_add$(input.read$capitalized_type$());\n");
}
@@ -785,8 +790,24 @@ GenerateParsingCodeFromPacked(io::Printer* printer) const {
printer->Print(variables_,
"int length = input.readRawVarint32();\n"
"int limit = input.pushLimit(length);\n"
- "if (!$is_mutable$ && input.getBytesUntilLimit() > 0) {\n"
- " $name$_ = $new_list$();\n"
+ "if (!$is_mutable$ && input.getBytesUntilLimit() > 0) {\n");
+
+ int fixed_size = FixedSize(GetType(descriptor_));
+ if (fixed_size == -1) {
+ // TODO(dweis): Scan the input buffer to count, then initialize
+ // appropriately.
+ printer->Print(variables_,
+ " $name$_ =\n"
+ " com.google.protobuf.GeneratedMessageLite.mutableCopy($name$_);\n");
+ } else {
+ printer->Print(variables_,
+ " final int currentSize = $name$_.size();\n"
+ " $name$_ = $name$_.mutableCopyWithCapacity(\n"
+ " currentSize + (length/$fixed_size$));\n");
+ }
+
+ // TODO(dweis): Scan the input buffer to count and ensure capacity.
+ printer->Print(variables_,
"}\n"
"while (input.getBytesUntilLimit() > 0) {\n"
" $repeated_add$(input.read$capitalized_type$());\n"
@@ -810,16 +831,16 @@ GenerateSerializationCode(io::Printer* printer) const {
// That makes it safe to rely on the memoized size here.
printer->Print(variables_,
"if (get$capitalized_name$List().size() > 0) {\n"
- " output.writeRawVarint32($tag$);\n"
- " output.writeRawVarint32($name$MemoizedSerializedSize);\n"
+ " output.writeUInt32NoTag($tag$);\n"
+ " output.writeUInt32NoTag($name$MemoizedSerializedSize);\n"
"}\n"
"for (int i = 0; i < $name$_.size(); i++) {\n"
- " output.write$capitalized_type$NoTag($name$_.get(i));\n"
+ " output.write$capitalized_type$NoTag($repeated_get$(i));\n"
"}\n");
} else {
printer->Print(variables_,
"for (int i = 0; i < $name$_.size(); i++) {\n"
- " output.write$capitalized_type$($number$, $name$_.get(i));\n"
+ " output.write$capitalized_type$($number$, $repeated_get$(i));\n"
"}\n");
}
}
@@ -835,7 +856,7 @@ GenerateSerializedSizeCode(io::Printer* printer) const {
printer->Print(variables_,
"for (int i = 0; i < $name$_.size(); i++) {\n"
" dataSize += com.google.protobuf.CodedOutputStream\n"
- " .compute$capitalized_type$SizeNoTag($name$_.get(i));\n"
+ " .compute$capitalized_type$SizeNoTag($repeated_get$(i));\n"
"}\n");
} else {
printer->Print(variables_,
diff --git a/src/google/protobuf/compiler/java/java_primitive_field_lite.h b/src/google/protobuf/compiler/java/java_primitive_field_lite.h
index ad603c2a..6cfbbb98 100644
--- a/src/google/protobuf/compiler/java/java_primitive_field_lite.h
+++ b/src/google/protobuf/compiler/java/java_primitive_field_lite.h
@@ -69,7 +69,7 @@ class ImmutablePrimitiveFieldLiteGenerator
void GenerateBuilderMembers(io::Printer* printer) const;
void GenerateInitializationCode(io::Printer* printer) const;
void GenerateBuilderClearCode(io::Printer* printer) const;
- void GenerateMergingCode(io::Printer* printer) const;
+ void GenerateVisitCode(io::Printer* printer) const;
void GenerateBuildingCode(io::Printer* printer) const;
void GenerateDynamicMethodMakeImmutableCode(io::Printer* printer) const;
void GenerateParsingCode(io::Printer* printer) const;
@@ -105,7 +105,7 @@ class ImmutablePrimitiveOneofFieldLiteGenerator
void GenerateMembers(io::Printer* printer) const;
void GenerateBuilderMembers(io::Printer* printer) const;
void GenerateBuildingCode(io::Printer* printer) const;
- void GenerateMergingCode(io::Printer* printer) const;
+ void GenerateVisitCode(io::Printer* printer) const;
void GenerateParsingCode(io::Printer* printer) const;
void GenerateSerializationCode(io::Printer* printer) const;
void GenerateSerializedSizeCode(io::Printer* printer) const;
@@ -130,7 +130,7 @@ class RepeatedImmutablePrimitiveFieldLiteGenerator
void GenerateBuilderMembers(io::Printer* printer) const;
void GenerateInitializationCode(io::Printer* printer) const;
void GenerateBuilderClearCode(io::Printer* printer) const;
- void GenerateMergingCode(io::Printer* printer) const;
+ void GenerateVisitCode(io::Printer* printer) const;
void GenerateBuildingCode(io::Printer* printer) const;
void GenerateDynamicMethodMakeImmutableCode(io::Printer* printer) const;
void GenerateParsingCode(io::Printer* printer) const;
diff --git a/src/google/protobuf/compiler/java/java_service.cc b/src/google/protobuf/compiler/java/java_service.cc
index 11bfc12d..9f34f010 100644
--- a/src/google/protobuf/compiler/java/java_service.cc
+++ b/src/google/protobuf/compiler/java/java_service.cc
@@ -60,9 +60,10 @@ ImmutableServiceGenerator::ImmutableServiceGenerator(
ImmutableServiceGenerator::~ImmutableServiceGenerator() {}
void ImmutableServiceGenerator::Generate(io::Printer* printer) {
- bool is_own_file =
- MultipleJavaFiles(descriptor_->file(), /* immutable = */ true);
+ bool is_own_file = IsOwnFile(descriptor_, /* immutable = */ true);
WriteServiceDocComment(printer, descriptor_);
+ MaybePrintGeneratedAnnotation(context_, printer, descriptor_,
+ /* immutable = */ true);
printer->Print(
"public $static$ abstract class $classname$\n"
" implements com.google.protobuf.Service {\n",
diff --git a/src/google/protobuf/compiler/java/java_service.h b/src/google/protobuf/compiler/java/java_service.h
index 6707e821..5fc9e2f6 100644
--- a/src/google/protobuf/compiler/java/java_service.h
+++ b/src/google/protobuf/compiler/java/java_service.h
@@ -74,8 +74,8 @@ class ServiceGenerator {
class ImmutableServiceGenerator : public ServiceGenerator {
public:
- explicit ImmutableServiceGenerator(const ServiceDescriptor* descriptor,
- Context* context);
+ ImmutableServiceGenerator(const ServiceDescriptor* descriptor,
+ Context* context);
virtual ~ImmutableServiceGenerator();
virtual void Generate(io::Printer* printer);
diff --git a/src/google/protobuf/compiler/java/java_shared_code_generator.cc b/src/google/protobuf/compiler/java/java_shared_code_generator.cc
index 70177367..52893721 100644
--- a/src/google/protobuf/compiler/java/java_shared_code_generator.cc
+++ b/src/google/protobuf/compiler/java/java_shared_code_generator.cc
@@ -51,43 +51,53 @@ namespace protobuf {
namespace compiler {
namespace java {
-SharedCodeGenerator::SharedCodeGenerator(const FileDescriptor* file)
- : name_resolver_(new ClassNameResolver), file_(file) {
-}
+SharedCodeGenerator::SharedCodeGenerator(const FileDescriptor* file,
+ const Options& options)
+ : name_resolver_(new ClassNameResolver), file_(file), options_(options) {}
SharedCodeGenerator::~SharedCodeGenerator() {
}
void SharedCodeGenerator::Generate(GeneratorContext* context,
- vector<string>* file_list) {
+ vector<string>* file_list,
+ vector<string>* annotation_file_list) {
string java_package = FileJavaPackage(file_);
string package_dir = JavaPackageToDir(java_package);
- if (HasDescriptorMethods(file_)) {
+ if (HasDescriptorMethods(file_, options_.enforce_lite)) {
// Generate descriptors.
string classname = name_resolver_->GetDescriptorClassName(file_);
string filename = package_dir + classname + ".java";
file_list->push_back(filename);
google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(context->Open(filename));
- google::protobuf::scoped_ptr<io::Printer> printer(new io::Printer(output.get(), '$'));
-
+ GeneratedCodeInfo annotations;
+ io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector(
+ &annotations);
+ google::protobuf::scoped_ptr<io::Printer> printer(
+ new io::Printer(output.get(), '$',
+ options_.annotate_code ? &annotation_collector : NULL));
+ string info_relative_path = classname + ".java.pb.meta";
+ string info_full_path = filename + ".pb.meta";
printer->Print(
- "// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
- "// source: $filename$\n"
- "\n",
- "filename", file_->name());
+ "// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
+ "// source: $filename$\n"
+ "\n",
+ "filename", file_->name());
if (!java_package.empty()) {
printer->Print(
"package $package$;\n"
"\n",
"package", java_package);
}
+ PrintGeneratedAnnotation(printer.get(), '$',
+ options_.annotate_code ? info_relative_path : "");
printer->Print(
- "public final class $classname$ {\n"
- " public static com.google.protobuf.Descriptors.FileDescriptor\n"
- " descriptor;\n"
- " static {\n",
- "classname", classname);
+ "public final class $classname$ {\n"
+ " public static com.google.protobuf.Descriptors.FileDescriptor\n"
+ " descriptor;\n"
+ " static {\n",
+ "classname", classname);
+ printer->Annotate("classname", file_->name());
printer->Indent();
printer->Indent();
GenerateDescriptors(printer.get());
@@ -97,6 +107,13 @@ void SharedCodeGenerator::Generate(GeneratorContext* context,
" }\n"
"}\n");
+ if (options_.annotate_code) {
+ google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> info_output(
+ context->Open(info_full_path));
+ annotations.SerializeToZeroCopyStream(info_output.get());
+ annotation_file_list->push_back(info_full_path);
+ }
+
printer.reset();
output.reset();
}
diff --git a/src/google/protobuf/compiler/java/java_shared_code_generator.h b/src/google/protobuf/compiler/java/java_shared_code_generator.h
index 38a32fc2..7e1e1f17 100644
--- a/src/google/protobuf/compiler/java/java_shared_code_generator.h
+++ b/src/google/protobuf/compiler/java/java_shared_code_generator.h
@@ -43,6 +43,7 @@
#include <vector>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/compiler/java/java_options.h>
namespace google {
namespace protobuf {
@@ -66,11 +67,11 @@ namespace java {
// and mutable API. Currently only descriptors are shared.
class SharedCodeGenerator {
public:
- explicit SharedCodeGenerator(const FileDescriptor* file);
+ SharedCodeGenerator(const FileDescriptor* file, const Options& options);
~SharedCodeGenerator();
- void Generate(GeneratorContext* generator_context,
- vector<string>* file_list);
+ void Generate(GeneratorContext* generator_context, vector<string>* file_list,
+ vector<string>* annotation_file_list);
void GenerateDescriptors(io::Printer* printer);
@@ -82,6 +83,7 @@ class SharedCodeGenerator {
google::protobuf::scoped_ptr<ClassNameResolver> name_resolver_;
const FileDescriptor* file_;
+ const Options options_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SharedCodeGenerator);
};
diff --git a/src/google/protobuf/compiler/java/java_string_field.cc b/src/google/protobuf/compiler/java/java_string_field.cc
index 72ebaeca..ff1865b1 100644
--- a/src/google/protobuf/compiler/java/java_string_field.cc
+++ b/src/google/protobuf/compiler/java/java_string_field.cc
@@ -79,16 +79,17 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
" throw new NullPointerException();\n"
" }\n";
(*variables)["writeString"] =
- "com.google.protobuf.GeneratedMessage.writeString";
+ "com.google.protobuf.GeneratedMessage" + GeneratedCodeVersionSuffix() +
+ ".writeString";
(*variables)["computeStringSize"] =
- "com.google.protobuf.GeneratedMessage.computeStringSize";
+ "com.google.protobuf.GeneratedMessage" + GeneratedCodeVersionSuffix() +
+ ".computeStringSize";
// TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
// by the proto compiler
(*variables)["deprecation"] = descriptor->options().deprecated()
? "@java.lang.Deprecated " : "";
- (*variables)["on_changed"] =
- HasDescriptorMethods(descriptor->containing_type()) ? "onChanged();" : "";
+ (*variables)["on_changed"] = "onChanged();";
if (SupportFieldPresence(descriptor->file())) {
// For singular messages and builders, one bit is used for the hasField bit.
@@ -405,16 +406,7 @@ void ImmutableStringFieldGenerator::
GenerateParsingCode(io::Printer* printer) const {
if (CheckUtf8(descriptor_)) {
printer->Print(variables_,
- "String s = input.readStringRequireUtf8();\n"
- "$set_has_field_bit_message$\n"
- "$name$_ = s;\n");
- } else if (!HasDescriptorMethods(descriptor_->file())) {
- // Lite runtime should attempt to reduce allocations by attempting to
- // construct the string directly from the input stream buffer. This avoids
- // spurious intermediary ByteString allocations, cutting overall allocations
- // in half.
- printer->Print(variables_,
- "String s = input.readString();\n"
+ "java.lang.String s = input.readStringRequireUtf8();\n"
"$set_has_field_bit_message$\n"
"$name$_ = s;\n");
} else {
@@ -665,16 +657,7 @@ void ImmutableStringOneofFieldGenerator::
GenerateParsingCode(io::Printer* printer) const {
if (CheckUtf8(descriptor_)) {
printer->Print(variables_,
- "String s = input.readStringRequireUtf8();\n"
- "$set_oneof_case_message$;\n"
- "$oneof_name$_ = s;\n");
- } else if (!HasDescriptorMethods(descriptor_->file())) {
- // Lite runtime should attempt to reduce allocations by attempting to
- // construct the string directly from the input stream buffer. This avoids
- // spurious intermediary ByteString allocations, cutting overall allocations
- // in half.
- printer->Print(variables_,
- "String s = input.readString();\n"
+ "java.lang.String s = input.readStringRequireUtf8();\n"
"$set_oneof_case_message$;\n"
"$oneof_name$_ = s;\n");
} else {
@@ -731,7 +714,13 @@ void RepeatedImmutableStringFieldGenerator::
GenerateInterfaceMembers(io::Printer* printer) const {
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
- "$deprecation$com.google.protobuf.ProtocolStringList\n"
+ // NOTE: the same method in the implementation class actually returns
+ // com.google.protobuf.ProtocolStringList (a subclass of List). It's
+ // changed between protobuf 2.5.0 release and protobuf 2.6.1 release.
+ // To retain binary compatibility with both 2.5.0 and 2.6.1 generated
+ // code, we make this interface method return List so both methods
+ // with different return types exist in the compiled byte code.
+ "$deprecation$java.util.List<java.lang.String>\n"
" get$capitalized_name$List();\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
@@ -773,12 +762,6 @@ GenerateMembers(io::Printer* printer) const {
" get$capitalized_name$Bytes(int index) {\n"
" return $name$_.getByteString(index);\n"
"}\n");
-
- if (descriptor_->options().packed() &&
- HasGeneratedMethods(descriptor_->containing_type())) {
- printer->Print(variables_,
- "private int $name$MemoizedSerializedSize = -1;\n");
- }
}
void RepeatedImmutableStringFieldGenerator::
@@ -939,14 +922,7 @@ void RepeatedImmutableStringFieldGenerator::
GenerateParsingCode(io::Printer* printer) const {
if (CheckUtf8(descriptor_)) {
printer->Print(variables_,
- "String s = input.readStringRequireUtf8();\n");
- } else if (!HasDescriptorMethods(descriptor_->file())) {
- // Lite runtime should attempt to reduce allocations by attempting to
- // construct the string directly from the input stream buffer. This avoids
- // spurious intermediary ByteString allocations, cutting overall allocations
- // in half.
- printer->Print(variables_,
- "String s = input.readString();\n");
+ "java.lang.String s = input.readStringRequireUtf8();\n");
} else {
printer->Print(variables_,
"com.google.protobuf.ByteString bs = input.readBytes();\n");
@@ -956,7 +932,7 @@ GenerateParsingCode(io::Printer* printer) const {
" $name$_ = new com.google.protobuf.LazyStringArrayList();\n"
" $set_mutable_bit_parser$;\n"
"}\n");
- if (CheckUtf8(descriptor_) || !HasDescriptorMethods(descriptor_->file())) {
+ if (CheckUtf8(descriptor_)) {
printer->Print(variables_,
"$name$_.add(s);\n");
} else {
@@ -966,30 +942,6 @@ GenerateParsingCode(io::Printer* printer) const {
}
void RepeatedImmutableStringFieldGenerator::
-GenerateParsingCodeFromPacked(io::Printer* printer) const {
- printer->Print(variables_,
- "int length = input.readRawVarint32();\n"
- "int limit = input.pushLimit(length);\n"
- "if (!$get_mutable_bit_parser$ && input.getBytesUntilLimit() > 0) {\n"
- " $name$_ = new com.google.protobuf.LazyStringArrayList();\n"
- " $set_mutable_bit_parser$;\n"
- "}\n"
- "while (input.getBytesUntilLimit() > 0) {\n");
- if (CheckUtf8(descriptor_)) {
- printer->Print(variables_,
- " String s = input.readStringRequireUtf8();\n");
- } else {
- printer->Print(variables_,
- " String s = input.readString();\n");
- }
- printer->Print(variables_,
- " $name$.add(s);\n");
- printer->Print(variables_,
- "}\n"
- "input.popLimit(limit);\n");
-}
-
-void RepeatedImmutableStringFieldGenerator::
GenerateParsingDoneCode(io::Printer* printer) const {
printer->Print(variables_,
"if ($get_mutable_bit_parser$) {\n"
@@ -999,21 +951,10 @@ GenerateParsingDoneCode(io::Printer* printer) const {
void RepeatedImmutableStringFieldGenerator::
GenerateSerializationCode(io::Printer* printer) const {
- if (descriptor_->options().packed()) {
- printer->Print(variables_,
- "if (get$capitalized_name$List().size() > 0) {\n"
- " output.writeRawVarint32($tag$);\n"
- " output.writeRawVarint32($name$MemoizedSerializedSize);\n"
- "}\n"
- "for (int i = 0; i < $name$_.size(); i++) {\n"
- " writeStringNoTag(output, $name$_.getRaw(i));\n"
- "}\n");
- } else {
- printer->Print(variables_,
- "for (int i = 0; i < $name$_.size(); i++) {\n"
- " $writeString$(output, $number$, $name$_.getRaw(i));\n"
- "}\n");
- }
+ printer->Print(variables_,
+ "for (int i = 0; i < $name$_.size(); i++) {\n"
+ " $writeString$(output, $number$, $name$_.getRaw(i));\n"
+ "}\n");
}
void RepeatedImmutableStringFieldGenerator::
@@ -1031,23 +972,8 @@ GenerateSerializedSizeCode(io::Printer* printer) const {
printer->Print(
"size += dataSize;\n");
- if (descriptor_->options().packed()) {
- printer->Print(variables_,
- "if (!get$capitalized_name$List().isEmpty()) {\n"
- " size += $tag_size$;\n"
- " size += com.google.protobuf.CodedOutputStream\n"
- " .computeInt32SizeNoTag(dataSize);\n"
- "}\n");
- } else {
- printer->Print(variables_,
- "size += $tag_size$ * get$capitalized_name$List().size();\n");
- }
-
- // cache the data size for packed fields.
- if (descriptor_->options().packed()) {
- printer->Print(variables_,
- "$name$MemoizedSerializedSize = dataSize;\n");
- }
+ printer->Print(variables_,
+ "size += $tag_size$ * get$capitalized_name$List().size();\n");
printer->Outdent();
printer->Print("}\n");
diff --git a/src/google/protobuf/compiler/java/java_string_field.h b/src/google/protobuf/compiler/java/java_string_field.h
index 1ea44dec..a3b57351 100644
--- a/src/google/protobuf/compiler/java/java_string_field.h
+++ b/src/google/protobuf/compiler/java/java_string_field.h
@@ -131,7 +131,6 @@ class RepeatedImmutableStringFieldGenerator : public ImmutableFieldGenerator {
void GenerateMergingCode(io::Printer* printer) const;
void GenerateBuildingCode(io::Printer* printer) const;
void GenerateParsingCode(io::Printer* printer) const;
- void GenerateParsingCodeFromPacked(io::Printer* printer) const;
void GenerateParsingDoneCode(io::Printer* printer) const;
void GenerateSerializationCode(io::Printer* printer) const;
void GenerateSerializedSizeCode(io::Printer* printer) const;
diff --git a/src/google/protobuf/compiler/java/java_string_field_lite.cc b/src/google/protobuf/compiler/java/java_string_field_lite.cc
index 092e3c29..0b92c021 100644
--- a/src/google/protobuf/compiler/java/java_string_field_lite.cc
+++ b/src/google/protobuf/compiler/java/java_string_field_lite.cc
@@ -84,8 +84,6 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
// by the proto compiler
(*variables)["deprecation"] = descriptor->options().deprecated()
? "@java.lang.Deprecated " : "";
- (*variables)["on_changed"] =
- HasDescriptorMethods(descriptor->containing_type()) ? "onChanged();" : "";
if (SupportFieldPresence(descriptor->file())) {
// For singular messages and builders, one bit is used for the hasField bit.
@@ -103,7 +101,7 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
(*variables)["clear_has_field_bit_message"] = "";
(*variables)["is_field_present_message"] =
- "!get" + (*variables)["capitalized_name"] + ".isEmpty()";
+ "!" + (*variables)["name"] + "_.isEmpty()";
}
// For repeated builders, the underlying list tracks mutability state.
@@ -301,22 +299,16 @@ GenerateInitializationCode(io::Printer* printer) const {
}
void ImmutableStringFieldLiteGenerator::
-GenerateMergingCode(io::Printer* printer) const {
+GenerateVisitCode(io::Printer* printer) const {
if (SupportFieldPresence(descriptor_->file())) {
- // Allow a slight breach of abstraction here in order to avoid forcing
- // all string fields to Strings when copying fields from a Message.
printer->Print(variables_,
- "if (other.has$capitalized_name$()) {\n"
- " $set_has_field_bit_message$\n"
- " $name$_ = other.$name$_;\n"
- " $on_changed$\n"
- "}\n");
+ "$name$_ = visitor.visitString(\n"
+ " has$capitalized_name$(), $name$_,\n"
+ " other.has$capitalized_name$(), other.$name$_);\n");
} else {
printer->Print(variables_,
- "if (!other.get$capitalized_name$().isEmpty()) {\n"
- " $name$_ = other.$name$_;\n"
- " $on_changed$\n"
- "}\n");
+ "$name$_ = visitor.visitString(!$name$_.isEmpty(), $name$_,\n"
+ " !other.$name$_.isEmpty(), other.$name$_);\n");
}
}
@@ -523,13 +515,10 @@ GenerateBuilderMembers(io::Printer* printer) const {
}
void ImmutableStringOneofFieldLiteGenerator::
-GenerateMergingCode(io::Printer* printer) const {
- // Allow a slight breach of abstraction here in order to avoid forcing
- // all string fields to Strings when copying fields from a Message.
+GenerateVisitCode(io::Printer* printer) const {
printer->Print(variables_,
- "$set_oneof_case_message$;\n"
- "$oneof_name$_ = other.$oneof_name$_;\n"
- "$on_changed$\n");
+ "$oneof_name$_ = visitor.visitOneofString(\n"
+ " $has_oneof_case_message$, $oneof_name$_, other.$oneof_name$_);\n");
}
void ImmutableStringOneofFieldLiteGenerator::
@@ -647,17 +636,11 @@ GenerateMembers(io::Printer* printer) const {
" $name$_.get(index));\n"
"}\n");
- if (descriptor_->options().packed() &&
- HasGeneratedMethods(descriptor_->containing_type())) {
- printer->Print(variables_,
- "private int $name$MemoizedSerializedSize = -1;\n");
- }
-
printer->Print(variables_,
"private void ensure$capitalized_name$IsMutable() {\n"
" if (!$is_mutable$) {\n"
- " $name$_ = com.google.protobuf.GeneratedMessageLite.newProtobufList(\n"
- " $name$_);\n"
+ " $name$_ =\n"
+ " com.google.protobuf.GeneratedMessageLite.mutableCopy($name$_);\n"
" }\n"
"}\n");
@@ -784,22 +767,9 @@ GenerateInitializationCode(io::Printer* printer) const {
}
void RepeatedImmutableStringFieldLiteGenerator::
-GenerateMergingCode(io::Printer* printer) const {
- // The code below does two optimizations:
- // 1. If the other list is empty, there's nothing to do. This ensures we
- // don't allocate a new array if we already have an immutable one.
- // 2. If the other list is non-empty and our current list is empty, we can
- // reuse the other list which is guaranteed to be immutable.
- printer->Print(variables_,
- "if (!other.$name$_.isEmpty()) {\n"
- " if ($name$_.isEmpty()) {\n"
- " $name$_ = other.$name$_;\n"
- " } else {\n"
- " ensure$capitalized_name$IsMutable();\n"
- " $name$_.addAll(other.$name$_);\n"
- " }\n"
- " $on_changed$\n"
- "}\n");
+GenerateVisitCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "$name$_= visitor.visitList($name$_, other.$name$_);\n");
}
void RepeatedImmutableStringFieldLiteGenerator::
@@ -823,38 +793,11 @@ GenerateParsingCode(io::Printer* printer) const {
}
printer->Print(variables_,
"if (!$is_mutable$) {\n"
- " $name$_ = com.google.protobuf.GeneratedMessageLite.newProtobufList();\n"
+ " $name$_ =\n"
+ " com.google.protobuf.GeneratedMessageLite.mutableCopy($name$_);\n"
"}\n");
- if (CheckUtf8(descriptor_) || !HasDescriptorMethods(descriptor_->file())) {
- printer->Print(variables_,
- "$name$_.add(s);\n");
- } else {
- printer->Print(variables_,
- "$name$_.add(bs);\n");
- }
-}
-
-void RepeatedImmutableStringFieldLiteGenerator::
-GenerateParsingCodeFromPacked(io::Printer* printer) const {
- printer->Print(variables_,
- "int length = input.readRawVarint32();\n"
- "int limit = input.pushLimit(length);\n"
- "if (!$is_mutable$ && input.getBytesUntilLimit() > 0) {\n"
- " $name$_ = com.google.protobuf.GeneratedMessageLite.newProtobufList();\n"
- "}\n"
- "while (input.getBytesUntilLimit() > 0) {\n");
- if (CheckUtf8(descriptor_)) {
- printer->Print(variables_,
- " String s = input.readStringRequireUtf8();\n");
- } else {
- printer->Print(variables_,
- " String s = input.readString();\n");
- }
- printer->Print(variables_,
- " $name$.add(s);\n");
printer->Print(variables_,
- "}\n"
- "input.popLimit(limit);\n");
+ "$name$_.add(s);\n");
}
void RepeatedImmutableStringFieldLiteGenerator::
@@ -870,21 +813,10 @@ GenerateSerializationCode(io::Printer* printer) const {
// Lite runtime should reduce allocations by serializing the string directly.
// This avoids spurious intermediary ByteString allocations, cutting overall
// allocations in half.
- if (descriptor_->options().packed()) {
- printer->Print(variables_,
- "if (get$capitalized_name$List().size() > 0) {\n"
- " output.writeRawVarint32($tag$);\n"
- " output.writeRawVarint32($name$MemoizedSerializedSize);\n"
- "}\n"
- "for (int i = 0; i < $name$_.size(); i++) {\n"
- " output.writeStringNoTag($name$_.get(i));\n"
- "}\n");
- } else {
- printer->Print(variables_,
- "for (int i = 0; i < $name$_.size(); i++) {\n"
- " output.writeString($number$, $name$_.get(i));\n"
- "}\n");
- }
+ printer->Print(variables_,
+ "for (int i = 0; i < $name$_.size(); i++) {\n"
+ " output.writeString($number$, $name$_.get(i));\n"
+ "}\n");
}
void RepeatedImmutableStringFieldLiteGenerator::
@@ -906,23 +838,9 @@ GenerateSerializedSizeCode(io::Printer* printer) const {
printer->Print(
"size += dataSize;\n");
- if (descriptor_->options().packed()) {
- printer->Print(variables_,
- "if (!get$capitalized_name$List().isEmpty()) {\n"
- " size += $tag_size$;\n"
- " size += com.google.protobuf.CodedOutputStream\n"
- " .computeInt32SizeNoTag(dataSize);\n"
- "}\n");
- } else {
- printer->Print(variables_,
- "size += $tag_size$ * get$capitalized_name$List().size();\n");
- }
- // cache the data size for packed fields.
- if (descriptor_->options().packed()) {
- printer->Print(variables_,
- "$name$MemoizedSerializedSize = dataSize;\n");
- }
+ printer->Print(variables_,
+ "size += $tag_size$ * get$capitalized_name$List().size();\n");
printer->Outdent();
printer->Print("}\n");
diff --git a/src/google/protobuf/compiler/java/java_string_field_lite.h b/src/google/protobuf/compiler/java/java_string_field_lite.h
index 9d93b307..4148aa4d 100644
--- a/src/google/protobuf/compiler/java/java_string_field_lite.h
+++ b/src/google/protobuf/compiler/java/java_string_field_lite.h
@@ -68,7 +68,7 @@ class ImmutableStringFieldLiteGenerator : public ImmutableFieldLiteGenerator {
void GenerateMembers(io::Printer* printer) const;
void GenerateBuilderMembers(io::Printer* printer) const;
void GenerateInitializationCode(io::Printer* printer) const;
- void GenerateMergingCode(io::Printer* printer) const;
+ void GenerateVisitCode(io::Printer* printer) const;
void GenerateDynamicMethodMakeImmutableCode(io::Printer* printer) const;
void GenerateParsingCode(io::Printer* printer) const;
void GenerateParsingDoneCode(io::Printer* printer) const;
@@ -103,7 +103,7 @@ class ImmutableStringOneofFieldLiteGenerator
private:
void GenerateMembers(io::Printer* printer) const;
void GenerateBuilderMembers(io::Printer* printer) const;
- void GenerateMergingCode(io::Printer* printer) const;
+ void GenerateVisitCode(io::Printer* printer) const;
void GenerateParsingCode(io::Printer* printer) const;
void GenerateSerializationCode(io::Printer* printer) const;
void GenerateSerializedSizeCode(io::Printer* printer) const;
@@ -126,10 +126,9 @@ class RepeatedImmutableStringFieldLiteGenerator
void GenerateMembers(io::Printer* printer) const;
void GenerateBuilderMembers(io::Printer* printer) const;
void GenerateInitializationCode(io::Printer* printer) const;
- void GenerateMergingCode(io::Printer* printer) const;
+ void GenerateVisitCode(io::Printer* printer) const;
void GenerateDynamicMethodMakeImmutableCode(io::Printer* printer) const;
void GenerateParsingCode(io::Printer* printer) const;
- void GenerateParsingCodeFromPacked(io::Printer* printer) const;
void GenerateParsingDoneCode(io::Printer* printer) const;
void GenerateSerializationCode(io::Printer* printer) const;
void GenerateSerializedSizeCode(io::Printer* printer) const;
diff --git a/src/google/protobuf/compiler/javanano/javanano_generator.cc b/src/google/protobuf/compiler/javanano/javanano_generator.cc
index a33eba1b..7c3a0421 100644
--- a/src/google/protobuf/compiler/javanano/javanano_generator.cc
+++ b/src/google/protobuf/compiler/javanano/javanano_generator.cc
@@ -68,12 +68,10 @@ void UpdateParamsRecursively(Params& params,
}
if (file->options().has_java_package()) {
string result = file->options().java_package();
- if (!file->options().javanano_use_deprecated_package()) {
- if (!result.empty()) {
- result += ".";
- }
- result += "nano";
+ if (!result.empty()) {
+ result += ".";
}
+ result += "nano";
params.set_java_package(
file->name(), result);
}
diff --git a/src/google/protobuf/compiler/javanano/javanano_helpers.cc b/src/google/protobuf/compiler/javanano/javanano_helpers.cc
index 5465655f..02811a24 100644
--- a/src/google/protobuf/compiler/javanano/javanano_helpers.cc
+++ b/src/google/protobuf/compiler/javanano/javanano_helpers.cc
@@ -201,12 +201,10 @@ string FileJavaPackage(const Params& params, const FileDescriptor* file) {
result += file->package();
}
- if (!file->options().javanano_use_deprecated_package()) {
- if (!result.empty()) {
- result += ".";
- }
- result += "nano";
+ if (!result.empty()) {
+ result += ".";
}
+ result += "nano";
return result;
}
diff --git a/src/google/protobuf/compiler/js/js_generator.cc b/src/google/protobuf/compiler/js/js_generator.cc
new file mode 100755
index 00000000..58c77d00
--- /dev/null
+++ b/src/google/protobuf/compiler/js/js_generator.cc
@@ -0,0 +1,3307 @@
+// 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 "google/protobuf/compiler/js/js_generator.h"
+
+#include <assert.h>
+#include <algorithm>
+#include <limits>
+#include <map>
+#include <memory>
+#ifndef _SHARED_PTR_H
+#include <google/protobuf/stubs/shared_ptr.h>
+#endif
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <google/protobuf/stubs/logging.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/stringprintf.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace js {
+
+// Sorted list of JavaScript keywords. These cannot be used as names. If they
+// appear, we prefix them with "pb_".
+const char* kKeyword[] = {
+ "abstract",
+ "boolean",
+ "break",
+ "byte",
+ "case",
+ "catch",
+ "char",
+ "class",
+ "const",
+ "continue",
+ "debugger",
+ "default",
+ "delete",
+ "do",
+ "double",
+ "else",
+ "enum",
+ "export",
+ "extends",
+ "false",
+ "final",
+ "finally",
+ "float",
+ "for",
+ "function",
+ "goto",
+ "if",
+ "implements",
+ "import",
+ "in",
+ "instanceof",
+ "int",
+ "interface",
+ "long",
+ "native",
+ "new",
+ "null",
+ "package",
+ "private",
+ "protected",
+ "public",
+ "return",
+ "short",
+ "static",
+ "super",
+ "switch",
+ "synchronized",
+ "this",
+ "throw",
+ "throws",
+ "transient",
+ "try",
+ "typeof",
+ "var",
+ "void",
+ "volatile",
+ "while",
+ "with",
+};
+
+static const int kNumKeyword = sizeof(kKeyword) / sizeof(char*);
+
+namespace {
+
+// The mode of operation for bytes fields. Historically JSPB always carried
+// bytes as JS {string}, containing base64 content by convention. With binary
+// and proto3 serialization the new convention is to represent it as binary
+// data in Uint8Array. See b/26173701 for background on the migration.
+enum BytesMode {
+ BYTES_DEFAULT, // Default type for getBytesField to return.
+ BYTES_B64, // Explicitly coerce to base64 string where needed.
+ BYTES_U8, // Explicitly coerce to Uint8Array where needed.
+};
+
+bool IsReserved(const string& ident) {
+ for (int i = 0; i < kNumKeyword; i++) {
+ if (ident == kKeyword[i]) {
+ return true;
+ }
+ }
+ return false;
+}
+
+// Returns a copy of |filename| with any trailing ".protodevel" or ".proto
+// suffix stripped.
+// TODO(haberman): Unify with copy in compiler/cpp/internal/helpers.cc.
+string StripProto(const string& filename) {
+ const char* suffix = HasSuffixString(filename, ".protodevel")
+ ? ".protodevel" : ".proto";
+ return StripSuffixString(filename, suffix);
+}
+
+// Given a filename like foo/bar/baz.proto, returns the corresponding JavaScript
+// file foo/bar/baz.js.
+string GetJSFilename(const string& filename) {
+ return StripProto(filename) + "_pb.js";
+}
+
+// Given a filename like foo/bar/baz.proto, returns the root directory
+// path ../../
+string GetRootPath(const string& from_filename, const string& to_filename) {
+ if (to_filename.find("google/protobuf") == 0) {
+ // Well-known types (.proto files in the google/protobuf directory) are
+ // assumed to come from the 'google-protobuf' npm package. We may want to
+ // generalize this exception later by letting others put generated code in
+ // their own npm packages.
+ return "google-protobuf/";
+ }
+
+ size_t slashes = std::count(from_filename.begin(), from_filename.end(), '/');
+ if (slashes == 0) {
+ return "./";
+ }
+ string result = "";
+ for (size_t i = 0; i < slashes; i++) {
+ result += "../";
+ }
+ return result;
+}
+
+// Returns the alias we assign to the module of the given .proto filename
+// when importing.
+string ModuleAlias(const string& filename) {
+ // This scheme could technically cause problems if a file includes any 2 of:
+ // foo/bar_baz.proto
+ // foo_bar_baz.proto
+ // foo_bar/baz.proto
+ //
+ // We'll worry about this problem if/when we actually see it. This name isn't
+ // exposed to users so we can change it later if we need to.
+ string basename = StripProto(filename);
+ StripString(&basename, "-", '$');
+ StripString(&basename, "/", '_');
+ return basename + "_pb";
+}
+
+// Returns the fully normalized JavaScript path for the given
+// file descriptor's package.
+string GetPath(const GeneratorOptions& options,
+ const FileDescriptor* file) {
+ if (!options.namespace_prefix.empty()) {
+ return options.namespace_prefix;
+ } else if (!file->package().empty()) {
+ return "proto." + file->package();
+ } else {
+ return "proto";
+ }
+}
+
+// Forward declare, so that GetPrefix can call this method,
+// which in turn, calls GetPrefix.
+string GetPath(const GeneratorOptions& options,
+ const Descriptor* descriptor);
+
+// Returns the path prefix for a message or enumeration that
+// lives under the given file and containing type.
+string GetPrefix(const GeneratorOptions& options,
+ const FileDescriptor* file_descriptor,
+ const Descriptor* containing_type) {
+ string prefix = "";
+
+ if (containing_type == NULL) {
+ prefix = GetPath(options, file_descriptor);
+ } else {
+ prefix = GetPath(options, containing_type);
+ }
+
+ if (!prefix.empty()) {
+ prefix += ".";
+ }
+
+ return prefix;
+}
+
+
+// Returns the fully normalized JavaScript path for the given
+// message descriptor.
+string GetPath(const GeneratorOptions& options,
+ const Descriptor* descriptor) {
+ return GetPrefix(
+ options, descriptor->file(),
+ descriptor->containing_type()) + descriptor->name();
+}
+
+
+// Returns the fully normalized JavaScript path for the given
+// field's containing message descriptor.
+string GetPath(const GeneratorOptions& options,
+ const FieldDescriptor* descriptor) {
+ return GetPath(options, descriptor->containing_type());
+}
+
+// Returns the fully normalized JavaScript path for the given
+// enumeration descriptor.
+string GetPath(const GeneratorOptions& options,
+ const EnumDescriptor* enum_descriptor) {
+ return GetPrefix(
+ options, enum_descriptor->file(),
+ enum_descriptor->containing_type()) + enum_descriptor->name();
+}
+
+
+// Returns the fully normalized JavaScript path for the given
+// enumeration value descriptor.
+string GetPath(const GeneratorOptions& options,
+ const EnumValueDescriptor* value_descriptor) {
+ return GetPath(
+ options,
+ value_descriptor->type()) + "." + value_descriptor->name();
+}
+
+string MaybeCrossFileRef(const GeneratorOptions& options,
+ const FileDescriptor* from_file,
+ const Descriptor* to_message) {
+ if (options.import_style == GeneratorOptions::IMPORT_COMMONJS &&
+ from_file != to_message->file()) {
+ // Cross-file ref in CommonJS needs to use the module alias instead of
+ // the global name.
+ return ModuleAlias(to_message->file()->name()) + "." + to_message->name();
+ } else {
+ // Within a single file we use a full name.
+ return GetPath(options, to_message);
+ }
+}
+
+string SubmessageTypeRef(const GeneratorOptions& options,
+ const FieldDescriptor* field) {
+ GOOGLE_CHECK(field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE);
+ return MaybeCrossFileRef(options, field->file(), field->message_type());
+}
+
+// - Object field name: LOWER_UNDERSCORE -> LOWER_CAMEL, except for group fields
+// (UPPER_CAMEL -> LOWER_CAMEL), with "List" (or "Map") appended if appropriate,
+// and with reserved words triggering a "pb_" prefix.
+// - Getters/setters: LOWER_UNDERSCORE -> UPPER_CAMEL, except for group fields
+// (use the name directly), then append "List" if appropriate, then append "$"
+// if resulting name is equal to a reserved word.
+// - Enums: just uppercase.
+
+// Locale-independent version of ToLower that deals only with ASCII A-Z.
+char ToLowerASCII(char c) {
+ if (c >= 'A' && c <= 'Z') {
+ return (c - 'A') + 'a';
+ } else {
+ return c;
+ }
+}
+
+vector<string> ParseLowerUnderscore(const string& input) {
+ vector<string> words;
+ string running = "";
+ for (int i = 0; i < input.size(); i++) {
+ if (input[i] == '_') {
+ if (!running.empty()) {
+ words.push_back(running);
+ running.clear();
+ }
+ } else {
+ running += ToLowerASCII(input[i]);
+ }
+ }
+ if (!running.empty()) {
+ words.push_back(running);
+ }
+ return words;
+}
+
+vector<string> ParseUpperCamel(const string& input) {
+ vector<string> words;
+ string running = "";
+ for (int i = 0; i < input.size(); i++) {
+ if (input[i] >= 'A' && input[i] <= 'Z' && !running.empty()) {
+ words.push_back(running);
+ running.clear();
+ }
+ running += ToLowerASCII(input[i]);
+ }
+ if (!running.empty()) {
+ words.push_back(running);
+ }
+ return words;
+}
+
+string ToLowerCamel(const vector<string>& words) {
+ string result;
+ for (int i = 0; i < words.size(); i++) {
+ string word = words[i];
+ if (i == 0 && (word[0] >= 'A' && word[0] <= 'Z')) {
+ word[0] = (word[0] - 'A') + 'a';
+ } else if (i != 0 && (word[0] >= 'a' && word[0] <= 'z')) {
+ word[0] = (word[0] - 'a') + 'A';
+ }
+ result += word;
+ }
+ return result;
+}
+
+string ToUpperCamel(const vector<string>& words) {
+ string result;
+ for (int i = 0; i < words.size(); i++) {
+ string word = words[i];
+ if (word[0] >= 'a' && word[0] <= 'z') {
+ word[0] = (word[0] - 'a') + 'A';
+ }
+ result += word;
+ }
+ return result;
+}
+
+// Based on code from descriptor.cc (Thanks Kenton!)
+// Uppercases the entire string, turning ValueName into
+// VALUENAME.
+string ToEnumCase(const string& input) {
+ string result;
+ result.reserve(input.size());
+
+ for (int i = 0; i < input.size(); i++) {
+ if ('a' <= input[i] && input[i] <= 'z') {
+ result.push_back(input[i] - 'a' + 'A');
+ } else {
+ result.push_back(input[i]);
+ }
+ }
+
+ return result;
+}
+
+string ToFileName(const string& input) {
+ string result;
+ result.reserve(input.size());
+
+ for (int i = 0; i < input.size(); i++) {
+ if ('A' <= input[i] && input[i] <= 'Z') {
+ result.push_back(input[i] - 'A' + 'a');
+ } else {
+ result.push_back(input[i]);
+ }
+ }
+
+ return result;
+}
+
+// When we're generating one output file per type name, this is the filename
+// that top-level extensions should go in.
+string GetExtensionFileName(const GeneratorOptions& options,
+ const FileDescriptor* file) {
+ return options.output_dir + "/" + ToFileName(GetPath(options, file)) + ".js";
+}
+
+// When we're generating one output file per type name, this is the filename
+// that a top-level message should go in.
+string GetMessageFileName(const GeneratorOptions& options,
+ const Descriptor* desc) {
+ return options.output_dir + "/" + ToFileName(desc->name()) + ".js";
+}
+
+// When we're generating one output file per type name, this is the filename
+// that a top-level message should go in.
+string GetEnumFileName(const GeneratorOptions& options,
+ const EnumDescriptor* desc) {
+ return options.output_dir + "/" + ToFileName(desc->name()) + ".js";
+}
+
+// Returns the message/response ID, if set.
+string GetMessageId(const Descriptor* desc) {
+ return string();
+}
+
+bool IgnoreExtensionField(const FieldDescriptor* field) {
+ // Exclude descriptor extensions from output "to avoid clutter" (from original
+ // codegen).
+ return field->is_extension() &&
+ field->containing_type()->file()->name() ==
+ "google/protobuf/descriptor.proto";
+}
+
+
+// Used inside Google only -- do not remove.
+bool IsResponse(const Descriptor* desc) { return false; }
+
+bool IgnoreField(const FieldDescriptor* field) {
+ return IgnoreExtensionField(field);
+}
+
+
+// Do we ignore this message type?
+bool IgnoreMessage(const GeneratorOptions& options, const Descriptor* d) {
+ return d->options().map_entry();
+}
+
+// Does JSPB ignore this entire oneof? True only if all fields are ignored.
+bool IgnoreOneof(const OneofDescriptor* oneof) {
+ for (int i = 0; i < oneof->field_count(); i++) {
+ if (!IgnoreField(oneof->field(i))) {
+ return false;
+ }
+ }
+ return true;
+}
+
+string JSIdent(const GeneratorOptions& options,
+ const FieldDescriptor* field,
+ bool is_upper_camel,
+ bool is_map) {
+ string result;
+ if (field->type() == FieldDescriptor::TYPE_GROUP) {
+ result = is_upper_camel ?
+ ToUpperCamel(ParseUpperCamel(field->message_type()->name())) :
+ ToLowerCamel(ParseUpperCamel(field->message_type()->name()));
+ } else {
+ result = is_upper_camel ?
+ ToUpperCamel(ParseLowerUnderscore(field->name())) :
+ ToLowerCamel(ParseLowerUnderscore(field->name()));
+ }
+ if (is_map || (field->is_map())) {
+ // JSPB-style or proto3-style map.
+ result += "Map";
+ } else if (field->is_repeated()) {
+ // Repeated field.
+ result += "List";
+ }
+ return result;
+}
+
+string JSObjectFieldName(const GeneratorOptions& options,
+ const FieldDescriptor* field) {
+ string name = JSIdent(
+ options,
+ field,
+ /* is_upper_camel = */ false,
+ /* is_map = */ false);
+ if (IsReserved(name)) {
+ name = "pb_" + name;
+ }
+ return name;
+}
+
+string JSByteGetterSuffix(BytesMode bytes_mode) {
+ switch (bytes_mode) {
+ case BYTES_DEFAULT:
+ return "";
+ case BYTES_B64:
+ return "B64";
+ case BYTES_U8:
+ return "U8";
+ default:
+ assert(false);
+ }
+ return "";
+}
+
+// Returns the field name as a capitalized portion of a getter/setter method
+// name, e.g. MyField for .getMyField().
+string JSGetterName(const GeneratorOptions& options,
+ const FieldDescriptor* field,
+ BytesMode bytes_mode = BYTES_DEFAULT) {
+ string name = JSIdent(options, field,
+ /* is_upper_camel = */ true,
+ /* is_map = */ false);
+ if (field->type() == FieldDescriptor::TYPE_BYTES) {
+ string suffix = JSByteGetterSuffix(bytes_mode);
+ if (!suffix.empty()) {
+ name += "_as" + suffix;
+ }
+ }
+ if (name == "Extension" || name == "JsPbMessageId") {
+ // Avoid conflicts with base-class names.
+ name += "$";
+ }
+ return name;
+}
+
+string JSMapGetterName(const GeneratorOptions& options,
+ const FieldDescriptor* field) {
+ return JSIdent(options, field,
+ /* is_upper_camel = */ true,
+ /* is_map = */ true);
+}
+
+
+
+string JSOneofName(const OneofDescriptor* oneof) {
+ return ToUpperCamel(ParseLowerUnderscore(oneof->name()));
+}
+
+// Returns the index corresponding to this field in the JSPB array (underlying
+// data storage array).
+string JSFieldIndex(const FieldDescriptor* field) {
+ // Determine whether this field is a member of a group. Group fields are a bit
+ // wonky: their "containing type" is a message type created just for the
+ // group, and that type's parent type has a field with the group-message type
+ // as its message type and TYPE_GROUP as its field type. For such fields, the
+ // index we use is relative to the field number of the group submessage field.
+ // For all other fields, we just use the field number.
+ const Descriptor* containing_type = field->containing_type();
+ const Descriptor* parent_type = containing_type->containing_type();
+ if (parent_type != NULL) {
+ for (int i = 0; i < parent_type->field_count(); i++) {
+ if (parent_type->field(i)->type() == FieldDescriptor::TYPE_GROUP &&
+ parent_type->field(i)->message_type() == containing_type) {
+ return SimpleItoa(field->number() - parent_type->field(i)->number());
+ }
+ }
+ }
+ return SimpleItoa(field->number());
+}
+
+string JSOneofIndex(const OneofDescriptor* oneof) {
+ int index = -1;
+ for (int i = 0; i < oneof->containing_type()->oneof_decl_count(); i++) {
+ const OneofDescriptor* o = oneof->containing_type()->oneof_decl(i);
+ // If at least one field in this oneof is not JSPB-ignored, count the oneof.
+ for (int j = 0; j < o->field_count(); j++) {
+ const FieldDescriptor* f = o->field(j);
+ if (!IgnoreField(f)) {
+ index++;
+ break; // inner loop
+ }
+ }
+ if (o == oneof) {
+ break;
+ }
+ }
+ return SimpleItoa(index);
+}
+
+// Decodes a codepoint in \x0000 -- \xFFFF.
+uint16 DecodeUTF8Codepoint(uint8* bytes, size_t* length) {
+ if (*length == 0) {
+ return 0;
+ }
+ size_t expected = 0;
+ if ((*bytes & 0x80) == 0) {
+ expected = 1;
+ } else if ((*bytes & 0xe0) == 0xc0) {
+ expected = 2;
+ } else if ((*bytes & 0xf0) == 0xe0) {
+ expected = 3;
+ } else {
+ // Too long -- don't accept.
+ *length = 0;
+ return 0;
+ }
+
+ if (*length < expected) {
+ // Not enough bytes -- don't accept.
+ *length = 0;
+ return 0;
+ }
+
+ *length = expected;
+ switch (expected) {
+ case 1: return bytes[0];
+ case 2: return ((bytes[0] & 0x1F) << 6) |
+ ((bytes[1] & 0x3F) << 0);
+ case 3: return ((bytes[0] & 0x0F) << 12) |
+ ((bytes[1] & 0x3F) << 6) |
+ ((bytes[2] & 0x3F) << 0);
+ default: return 0;
+ }
+}
+
+// Escapes the contents of a string to be included within double-quotes ("") in
+// JavaScript. The input data should be a UTF-8 encoded C++ string of chars.
+// Returns false if |out| was truncated because |in| contained invalid UTF-8 or
+// codepoints outside the BMP.
+// TODO(lukestebbing): Support codepoints outside the BMP.
+bool EscapeJSString(const string& in, string* out) {
+ size_t decoded = 0;
+ for (size_t i = 0; i < in.size(); i += decoded) {
+ uint16 codepoint = 0;
+ // Decode the next UTF-8 codepoint.
+ size_t have_bytes = in.size() - i;
+ uint8 bytes[3] = {
+ static_cast<uint8>(in[i]),
+ static_cast<uint8>(((i + 1) < in.size()) ? in[i + 1] : 0),
+ static_cast<uint8>(((i + 2) < in.size()) ? in[i + 2] : 0),
+ };
+ codepoint = DecodeUTF8Codepoint(bytes, &have_bytes);
+ if (have_bytes == 0) {
+ return false;
+ }
+ decoded = have_bytes;
+
+ switch (codepoint) {
+ case '\'': *out += "\\x27"; break;
+ case '"': *out += "\\x22"; break;
+ case '<': *out += "\\x3c"; break;
+ case '=': *out += "\\x3d"; break;
+ case '>': *out += "\\x3e"; break;
+ case '&': *out += "\\x26"; break;
+ case '\b': *out += "\\b"; break;
+ case '\t': *out += "\\t"; break;
+ case '\n': *out += "\\n"; break;
+ case '\f': *out += "\\f"; break;
+ case '\r': *out += "\\r"; break;
+ case '\\': *out += "\\\\"; break;
+ default:
+ // TODO(lukestebbing): Once we're supporting codepoints outside the BMP,
+ // use a single Unicode codepoint escape if the output language is
+ // ECMAScript 2015 or above. Otherwise, use a surrogate pair.
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#String_literals
+ if (codepoint >= 0x20 && codepoint <= 0x7e) {
+ *out += static_cast<char>(codepoint);
+ } else if (codepoint >= 0x100) {
+ *out += StringPrintf("\\u%04x", codepoint);
+ } else {
+ *out += StringPrintf("\\x%02x", codepoint);
+ }
+ break;
+ }
+ }
+ return true;
+}
+
+string EscapeBase64(const string& in) {
+ static const char* kAlphabet =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ string result;
+
+ for (size_t i = 0; i < in.size(); i += 3) {
+ int value = (in[i] << 16) |
+ (((i + 1) < in.size()) ? (in[i + 1] << 8) : 0) |
+ (((i + 2) < in.size()) ? (in[i + 2] << 0) : 0);
+ result += kAlphabet[(value >> 18) & 0x3f];
+ result += kAlphabet[(value >> 12) & 0x3f];
+ if ((i + 1) < in.size()) {
+ result += kAlphabet[(value >> 6) & 0x3f];
+ } else {
+ result += '=';
+ }
+ if ((i + 2) < in.size()) {
+ result += kAlphabet[(value >> 0) & 0x3f];
+ } else {
+ result += '=';
+ }
+ }
+
+ return result;
+}
+
+// Post-process the result of SimpleFtoa/SimpleDtoa to *exactly* match the
+// original codegen's formatting (which is just .toString() on java.lang.Double
+// or java.lang.Float).
+string PostProcessFloat(string result) {
+ // If inf, -inf or nan, replace with +Infinity, -Infinity or NaN.
+ if (result == "inf") {
+ return "Infinity";
+ } else if (result == "-inf") {
+ return "-Infinity";
+ } else if (result == "nan") {
+ return "NaN";
+ }
+
+ // If scientific notation (e.g., "1e10"), (i) capitalize the "e", (ii)
+ // ensure that the mantissa (portion prior to the "e") has at least one
+ // fractional digit (after the decimal point), and (iii) strip any unnecessary
+ // leading zeroes and/or '+' signs from the exponent.
+ string::size_type exp_pos = result.find('e');
+ if (exp_pos != string::npos) {
+ string mantissa = result.substr(0, exp_pos);
+ string exponent = result.substr(exp_pos + 1);
+
+ // Add ".0" to mantissa if no fractional part exists.
+ if (mantissa.find('.') == string::npos) {
+ mantissa += ".0";
+ }
+
+ // Strip the sign off the exponent and store as |exp_neg|.
+ bool exp_neg = false;
+ if (!exponent.empty() && exponent[0] == '+') {
+ exponent = exponent.substr(1);
+ } else if (!exponent.empty() && exponent[0] == '-') {
+ exp_neg = true;
+ exponent = exponent.substr(1);
+ }
+
+ // Strip any leading zeroes off the exponent.
+ while (exponent.size() > 1 && exponent[0] == '0') {
+ exponent = exponent.substr(1);
+ }
+
+ return mantissa + "E" + string(exp_neg ? "-" : "") + exponent;
+ }
+
+ // Otherwise, this is an ordinary decimal number. Append ".0" if result has no
+ // decimal/fractional part in order to match output of original codegen.
+ if (result.find('.') == string::npos) {
+ result += ".0";
+ }
+
+ return result;
+}
+
+string FloatToString(float value) {
+ string result = SimpleFtoa(value);
+ return PostProcessFloat(result);
+}
+
+string DoubleToString(double value) {
+ string result = SimpleDtoa(value);
+ return PostProcessFloat(result);
+}
+
+string MaybeNumberString(const FieldDescriptor* field, const string& orig) {
+ return orig;
+}
+
+string JSFieldDefault(const FieldDescriptor* field) {
+ switch (field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ return MaybeNumberString(
+ field, SimpleItoa(field->default_value_int32()));
+ case FieldDescriptor::CPPTYPE_UINT32:
+ // The original codegen is in Java, and Java protobufs store unsigned
+ // integer values as signed integer values. In order to exactly match the
+ // output, we need to reinterpret as base-2 signed. Ugh.
+ return MaybeNumberString(
+ field, SimpleItoa(static_cast<int32>(field->default_value_uint32())));
+ case FieldDescriptor::CPPTYPE_INT64:
+ return MaybeNumberString(
+ field, SimpleItoa(field->default_value_int64()));
+ case FieldDescriptor::CPPTYPE_UINT64:
+ // See above note for uint32 -- reinterpreting as signed.
+ return MaybeNumberString(
+ field, SimpleItoa(static_cast<int64>(field->default_value_uint64())));
+ case FieldDescriptor::CPPTYPE_ENUM:
+ return SimpleItoa(field->default_value_enum()->number());
+ case FieldDescriptor::CPPTYPE_BOOL:
+ return field->default_value_bool() ? "true" : "false";
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ return FloatToString(field->default_value_float());
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ return DoubleToString(field->default_value_double());
+ case FieldDescriptor::CPPTYPE_STRING:
+ if (field->type() == FieldDescriptor::TYPE_STRING) {
+ string out;
+ bool is_valid = EscapeJSString(field->default_value_string(), &out);
+ if (!is_valid) {
+ // TODO(lukestebbing): Decide whether this should be a hard error.
+ GOOGLE_LOG(WARNING) << "The default value for field " << field->full_name()
+ << " was truncated since it contained invalid UTF-8 or"
+ " codepoints outside the basic multilingual plane.";
+ }
+ return "\"" + out + "\"";
+ } else { // Bytes
+ return "\"" + EscapeBase64(field->default_value_string()) + "\"";
+ }
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ return "null";
+ }
+ GOOGLE_LOG(FATAL) << "Shouldn't reach here.";
+ return "";
+}
+
+string ProtoTypeName(const GeneratorOptions& options,
+ const FieldDescriptor* field) {
+ switch (field->type()) {
+ case FieldDescriptor::TYPE_BOOL:
+ return "bool";
+ case FieldDescriptor::TYPE_INT32:
+ return "int32";
+ case FieldDescriptor::TYPE_UINT32:
+ return "uint32";
+ case FieldDescriptor::TYPE_SINT32:
+ return "sint32";
+ case FieldDescriptor::TYPE_FIXED32:
+ return "fixed32";
+ case FieldDescriptor::TYPE_SFIXED32:
+ return "sfixed32";
+ case FieldDescriptor::TYPE_INT64:
+ return "int64";
+ case FieldDescriptor::TYPE_UINT64:
+ return "uint64";
+ case FieldDescriptor::TYPE_SINT64:
+ return "sint64";
+ case FieldDescriptor::TYPE_FIXED64:
+ return "fixed64";
+ case FieldDescriptor::TYPE_SFIXED64:
+ return "sfixed64";
+ case FieldDescriptor::TYPE_FLOAT:
+ return "float";
+ case FieldDescriptor::TYPE_DOUBLE:
+ return "double";
+ case FieldDescriptor::TYPE_STRING:
+ return "string";
+ case FieldDescriptor::TYPE_BYTES:
+ return "bytes";
+ case FieldDescriptor::TYPE_GROUP:
+ return GetPath(options, field->message_type());
+ case FieldDescriptor::TYPE_ENUM:
+ return GetPath(options, field->enum_type());
+ case FieldDescriptor::TYPE_MESSAGE:
+ return GetPath(options, field->message_type());
+ default:
+ return "";
+ }
+}
+
+string JSIntegerTypeName(const FieldDescriptor* field) {
+ return "number";
+}
+
+string JSStringTypeName(const GeneratorOptions& options,
+ const FieldDescriptor* field,
+ BytesMode bytes_mode) {
+ if (field->type() == FieldDescriptor::TYPE_BYTES) {
+ switch (bytes_mode) {
+ case BYTES_DEFAULT:
+ return "(string|Uint8Array)";
+ case BYTES_B64:
+ return "string";
+ case BYTES_U8:
+ return "Uint8Array";
+ default:
+ assert(false);
+ }
+ }
+ return "string";
+}
+
+string JSTypeName(const GeneratorOptions& options,
+ const FieldDescriptor* field,
+ BytesMode bytes_mode) {
+ switch (field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_BOOL:
+ return "boolean";
+ case FieldDescriptor::CPPTYPE_INT32:
+ return JSIntegerTypeName(field);
+ case FieldDescriptor::CPPTYPE_INT64:
+ return JSIntegerTypeName(field);
+ case FieldDescriptor::CPPTYPE_UINT32:
+ return JSIntegerTypeName(field);
+ case FieldDescriptor::CPPTYPE_UINT64:
+ return JSIntegerTypeName(field);
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ return "number";
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ return "number";
+ case FieldDescriptor::CPPTYPE_STRING:
+ return JSStringTypeName(options, field, bytes_mode);
+ case FieldDescriptor::CPPTYPE_ENUM:
+ return GetPath(options, field->enum_type());
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ return GetPath(options, field->message_type());
+ default:
+ return "";
+ }
+}
+
+bool HasFieldPresence(const FieldDescriptor* field);
+
+string JSFieldTypeAnnotation(const GeneratorOptions& options,
+ const FieldDescriptor* field,
+ bool force_optional,
+ bool force_present,
+ bool singular_if_not_packed,
+ BytesMode bytes_mode = BYTES_DEFAULT) {
+ bool is_primitive =
+ (field->cpp_type() != FieldDescriptor::CPPTYPE_ENUM &&
+ field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE &&
+ (field->type() != FieldDescriptor::TYPE_BYTES ||
+ bytes_mode == BYTES_B64));
+
+ string jstype = JSTypeName(options, field, bytes_mode);
+
+ if (field->is_repeated() &&
+ (field->is_packed() || !singular_if_not_packed)) {
+ if (field->type() == FieldDescriptor::TYPE_BYTES &&
+ bytes_mode == BYTES_DEFAULT) {
+ jstype = "(Array<!Uint8Array>|Array<string>)";
+ } else {
+ if (!is_primitive) {
+ jstype = "!" + jstype;
+ }
+ jstype = "Array.<" + jstype + ">";
+ }
+ if (!force_optional) {
+ jstype = "!" + jstype;
+ }
+ }
+
+ if (field->is_optional() && is_primitive &&
+ force_optional && !force_present) {
+ jstype += "?";
+ } else if (field->is_required() && !is_primitive && !force_optional) {
+ jstype = "!" + jstype;
+ }
+
+ if (force_optional && HasFieldPresence(field)) {
+ jstype += "|undefined";
+ }
+ if (force_present && jstype[0] != '!' && !is_primitive) {
+ jstype = "!" + jstype;
+ }
+
+ return jstype;
+}
+
+string JSBinaryReaderMethodType(const FieldDescriptor* field) {
+ string name = field->type_name();
+ if (name[0] >= 'a' && name[0] <= 'z') {
+ name[0] = (name[0] - 'a') + 'A';
+ }
+
+ return name;
+}
+
+string JSBinaryReadWriteMethodName(const FieldDescriptor* field,
+ bool is_writer) {
+ string name = JSBinaryReaderMethodType(field);
+ if (field->is_packed()) {
+ name = "Packed" + name;
+ } else if (is_writer && field->is_repeated()) {
+ name = "Repeated" + name;
+ }
+ return name;
+}
+
+string JSBinaryReaderMethodName(const GeneratorOptions& options,
+ const FieldDescriptor* field) {
+ if (options.binary) {
+ return "jspb.BinaryReader.prototype.read" +
+ JSBinaryReadWriteMethodName(field, /* is_writer = */ false);
+ } else {
+ return "null";
+ }
+}
+
+string JSBinaryWriterMethodName(const GeneratorOptions& options,
+ const FieldDescriptor* field) {
+ if (options.binary) {
+ return "jspb.BinaryWriter.prototype.write" +
+ JSBinaryReadWriteMethodName(field, /* is_writer = */ true);
+ } else {
+ return "null";
+ }
+}
+
+string JSReturnClause(const FieldDescriptor* desc) {
+ return "";
+}
+
+string JSReturnDoc(const GeneratorOptions& options,
+ const FieldDescriptor* desc) {
+ return "";
+}
+
+bool HasRepeatedFields(const Descriptor* desc) {
+ for (int i = 0; i < desc->field_count(); i++) {
+ if (desc->field(i)->is_repeated() && !desc->field(i)->is_map()) {
+ return true;
+ }
+ }
+ return false;
+}
+
+static const char* kRepeatedFieldArrayName = ".repeatedFields_";
+
+string RepeatedFieldsArrayName(const GeneratorOptions& options,
+ const Descriptor* desc) {
+ return HasRepeatedFields(desc) ?
+ (GetPath(options, desc) + kRepeatedFieldArrayName) : "null";
+}
+
+bool HasOneofFields(const Descriptor* desc) {
+ for (int i = 0; i < desc->field_count(); i++) {
+ if (desc->field(i)->containing_oneof()) {
+ return true;
+ }
+ }
+ return false;
+}
+
+static const char* kOneofGroupArrayName = ".oneofGroups_";
+
+string OneofFieldsArrayName(const GeneratorOptions& options,
+ const Descriptor* desc) {
+ return HasOneofFields(desc) ?
+ (GetPath(options, desc) + kOneofGroupArrayName) : "null";
+}
+
+string RepeatedFieldNumberList(const Descriptor* desc) {
+ std::vector<string> numbers;
+ for (int i = 0; i < desc->field_count(); i++) {
+ if (desc->field(i)->is_repeated() && !desc->field(i)->is_map()) {
+ numbers.push_back(JSFieldIndex(desc->field(i)));
+ }
+ }
+ return "[" + Join(numbers, ",") + "]";
+}
+
+string OneofGroupList(const Descriptor* desc) {
+ // List of arrays (one per oneof), each of which is a list of field indices
+ std::vector<string> oneof_entries;
+ for (int i = 0; i < desc->oneof_decl_count(); i++) {
+ const OneofDescriptor* oneof = desc->oneof_decl(i);
+ if (IgnoreOneof(oneof)) {
+ continue;
+ }
+
+ std::vector<string> oneof_fields;
+ for (int j = 0; j < oneof->field_count(); j++) {
+ if (IgnoreField(oneof->field(j))) {
+ continue;
+ }
+ oneof_fields.push_back(JSFieldIndex(oneof->field(j)));
+ }
+ oneof_entries.push_back("[" + Join(oneof_fields, ",") + "]");
+ }
+ return "[" + Join(oneof_entries, ",") + "]";
+}
+
+string JSOneofArray(const GeneratorOptions& options,
+ const FieldDescriptor* field) {
+ return OneofFieldsArrayName(options, field->containing_type()) + "[" +
+ JSOneofIndex(field->containing_oneof()) + "]";
+}
+
+string RelativeTypeName(const FieldDescriptor* field) {
+ assert(field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM ||
+ field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE);
+ // For a field with an enum or message type, compute a name relative to the
+ // path name of the message type containing this field.
+ string package = field->file()->package();
+ string containing_type = field->containing_type()->full_name() + ".";
+ string type = (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) ?
+ field->enum_type()->full_name() : field->message_type()->full_name();
+
+ // |prefix| is advanced as we find separators '.' past the common package
+ // prefix that yield common prefixes in the containing type's name and this
+ // type's name.
+ int prefix = 0;
+ for (int i = 0; i < type.size() && i < containing_type.size(); i++) {
+ if (type[i] != containing_type[i]) {
+ break;
+ }
+ if (type[i] == '.' && i >= package.size()) {
+ prefix = i + 1;
+ }
+ }
+
+ return type.substr(prefix);
+}
+
+string JSExtensionsObjectName(const GeneratorOptions& options,
+ const FileDescriptor* from_file,
+ const Descriptor* desc) {
+ if (desc->full_name() == "google.protobuf.bridge.MessageSet") {
+ // TODO(haberman): fix this for the IMPORT_COMMONJS case.
+ return "jspb.Message.messageSetExtensions";
+ } else {
+ return MaybeCrossFileRef(options, from_file, desc) + ".extensions";
+ }
+}
+
+static const int kMapKeyField = 1;
+static const int kMapValueField = 2;
+
+const FieldDescriptor* MapFieldKey(const FieldDescriptor* field) {
+ assert(field->is_map());
+ return field->message_type()->FindFieldByNumber(kMapKeyField);
+}
+
+const FieldDescriptor* MapFieldValue(const FieldDescriptor* field) {
+ assert(field->is_map());
+ return field->message_type()->FindFieldByNumber(kMapValueField);
+}
+
+string FieldDefinition(const GeneratorOptions& options,
+ const FieldDescriptor* field) {
+ if (field->is_map()) {
+ const FieldDescriptor* key_field = MapFieldKey(field);
+ const FieldDescriptor* value_field = MapFieldValue(field);
+ string key_type = ProtoTypeName(options, key_field);
+ string value_type;
+ if (value_field->type() == FieldDescriptor::TYPE_ENUM ||
+ value_field->type() == FieldDescriptor::TYPE_MESSAGE) {
+ value_type = RelativeTypeName(value_field);
+ } else {
+ value_type = ProtoTypeName(options, value_field);
+ }
+ return StringPrintf("map<%s, %s> %s = %d;",
+ key_type.c_str(),
+ value_type.c_str(),
+ field->name().c_str(),
+ field->number());
+ } else {
+ string qualifier = field->is_repeated() ? "repeated" :
+ (field->is_optional() ? "optional" : "required");
+ string type, name;
+ if (field->type() == FieldDescriptor::TYPE_ENUM ||
+ field->type() == FieldDescriptor::TYPE_MESSAGE) {
+ type = RelativeTypeName(field);
+ name = field->name();
+ } else if (field->type() == FieldDescriptor::TYPE_GROUP) {
+ type = "group";
+ name = field->message_type()->name();
+ } else {
+ type = ProtoTypeName(options, field);
+ name = field->name();
+ }
+ return StringPrintf("%s %s %s = %d;",
+ qualifier.c_str(),
+ type.c_str(),
+ name.c_str(),
+ field->number());
+ }
+}
+
+string FieldComments(const FieldDescriptor* field, BytesMode bytes_mode) {
+ string comments;
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_BOOL) {
+ comments +=
+ " * Note that Boolean fields may be set to 0/1 when serialized from "
+ "a Java server.\n"
+ " * You should avoid comparisons like {@code val === true/false} in "
+ "those cases.\n";
+ }
+ if (field->is_repeated()) {
+ comments +=
+ " * If you change this array by adding, removing or replacing "
+ "elements, or if you\n"
+ " * replace the array itself, then you must call the setter to "
+ "update it.\n";
+ }
+ if (field->type() == FieldDescriptor::TYPE_BYTES && bytes_mode == BYTES_U8) {
+ comments +=
+ " * Note that Uint8Array is not supported on all browsers.\n"
+ " * @see http://caniuse.com/Uint8Array\n";
+ }
+ return comments;
+}
+
+bool ShouldGenerateExtension(const FieldDescriptor* field) {
+ return
+ field->is_extension() &&
+ !IgnoreField(field);
+}
+
+bool HasExtensions(const Descriptor* desc) {
+ for (int i = 0; i < desc->extension_count(); i++) {
+ if (ShouldGenerateExtension(desc->extension(i))) {
+ return true;
+ }
+ }
+ for (int i = 0; i < desc->nested_type_count(); i++) {
+ if (HasExtensions(desc->nested_type(i))) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool HasExtensions(const FileDescriptor* file) {
+ for (int i = 0; i < file->extension_count(); i++) {
+ if (ShouldGenerateExtension(file->extension(i))) {
+ return true;
+ }
+ }
+ for (int i = 0; i < file->message_type_count(); i++) {
+ if (HasExtensions(file->message_type(i))) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool IsExtendable(const Descriptor* desc) {
+ return desc->extension_range_count() > 0;
+}
+
+// Returns the max index in the underlying data storage array beyond which the
+// extension object is used.
+string GetPivot(const Descriptor* desc) {
+ static const int kDefaultPivot = (1 << 29); // max field number (29 bits)
+
+ // Find the max field number
+ int max_field_number = 0;
+ for (int i = 0; i < desc->field_count(); i++) {
+ if (!IgnoreField(desc->field(i)) &&
+ desc->field(i)->number() > max_field_number) {
+ max_field_number = desc->field(i)->number();
+ }
+ }
+
+ int pivot = -1;
+ if (IsExtendable(desc)) {
+ pivot = ((max_field_number + 1) < kDefaultPivot) ?
+ (max_field_number + 1) : kDefaultPivot;
+ }
+
+ return SimpleItoa(pivot);
+}
+
+// Returns true for fields that represent "null" as distinct from the default
+// value. See http://go/proto3#heading=h.kozewqqcqhuz for more information.
+bool HasFieldPresence(const FieldDescriptor* field) {
+ if (field->is_repeated()) {
+ return false;
+ }
+
+ return
+ (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) ||
+ (field->containing_oneof() != NULL) ||
+ (field->file()->syntax() != FileDescriptor::SYNTAX_PROTO3);
+}
+
+// For proto3 fields without presence, returns a string representing the default
+// value in JavaScript. See http://go/proto3#heading=h.kozewqqcqhuz for more
+// information.
+string Proto3PrimitiveFieldDefault(const FieldDescriptor* field) {
+ switch (field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ case FieldDescriptor::CPPTYPE_INT64:
+ case FieldDescriptor::CPPTYPE_UINT32:
+ case FieldDescriptor::CPPTYPE_UINT64: {
+ return "0";
+ }
+
+ case FieldDescriptor::CPPTYPE_ENUM:
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ return "0";
+
+ case FieldDescriptor::CPPTYPE_BOOL:
+ return "false";
+
+ case FieldDescriptor::CPPTYPE_STRING: // includes BYTES
+ return "\"\"";
+
+ default:
+ // MESSAGE is handled separately.
+ assert(false);
+ return "";
+ }
+}
+
+// We use this to implement the semantics that same file can be generated
+// multiple times, but the last one wins. We never actually write the files,
+// but we keep a set of which descriptors were the final one for a given
+// filename.
+class FileDeduplicator {
+ public:
+ explicit FileDeduplicator(const GeneratorOptions& options)
+ : error_on_conflict_(options.error_on_name_conflict) {}
+
+ bool AddFile(const string& filename, const void* desc, string* error) {
+ if (descs_by_filename_.find(filename) != descs_by_filename_.end()) {
+ if (error_on_conflict_) {
+ *error = "Name conflict: file name " + filename +
+ " would be generated by two descriptors";
+ return false;
+ }
+ allowed_descs_.erase(descs_by_filename_[filename]);
+ }
+
+ descs_by_filename_[filename] = desc;
+ allowed_descs_.insert(desc);
+ return true;
+ }
+
+ void GetAllowedSet(set<const void*>* allowed_set) {
+ *allowed_set = allowed_descs_;
+ }
+
+ private:
+ bool error_on_conflict_;
+ map<string, const void*> descs_by_filename_;
+ set<const void*> allowed_descs_;
+};
+
+void DepthFirstSearch(const FileDescriptor* file,
+ vector<const FileDescriptor*>* list,
+ set<const FileDescriptor*>* seen) {
+ if (!seen->insert(file).second) {
+ return;
+ }
+
+ // Add all dependencies.
+ for (int i = 0; i < file->dependency_count(); i++) {
+ DepthFirstSearch(file->dependency(i), list, seen);
+ }
+
+ // Add this file.
+ list->push_back(file);
+}
+
+// A functor for the predicate to remove_if() below. Returns true if a given
+// FileDescriptor is not in the given set.
+class NotInSet {
+ public:
+ explicit NotInSet(const set<const FileDescriptor*>& file_set)
+ : file_set_(file_set) {}
+
+ bool operator()(const FileDescriptor* file) {
+ return file_set_.count(file) == 0;
+ }
+
+ private:
+ const set<const FileDescriptor*>& file_set_;
+};
+
+// This function generates an ordering of the input FileDescriptors that matches
+// the logic of the old code generator. The order is significant because two
+// different input files can generate the same output file, and the last one
+// needs to win.
+void GenerateJspbFileOrder(const vector<const FileDescriptor*>& input,
+ vector<const FileDescriptor*>* ordered) {
+ // First generate an ordering of all reachable files (including dependencies)
+ // with depth-first search. This mimics the behavior of --include_imports,
+ // which is what the old codegen used.
+ ordered->clear();
+ set<const FileDescriptor*> seen;
+ set<const FileDescriptor*> input_set;
+ for (int i = 0; i < input.size(); i++) {
+ DepthFirstSearch(input[i], ordered, &seen);
+ input_set.insert(input[i]);
+ }
+
+ // Now remove the entries that are not actually in our input list.
+ ordered->erase(
+ std::remove_if(ordered->begin(), ordered->end(), NotInSet(input_set)),
+ ordered->end());
+}
+
+// If we're generating code in file-per-type mode, avoid overwriting files
+// by choosing the last descriptor that writes each filename and permitting
+// only those to generate code.
+
+bool GenerateJspbAllowedSet(const GeneratorOptions& options,
+ const vector<const FileDescriptor*>& files,
+ set<const void*>* allowed_set,
+ string* error) {
+ vector<const FileDescriptor*> files_ordered;
+ GenerateJspbFileOrder(files, &files_ordered);
+
+ // Choose the last descriptor for each filename.
+ FileDeduplicator dedup(options);
+ for (int i = 0; i < files_ordered.size(); i++) {
+ for (int j = 0; j < files_ordered[i]->message_type_count(); j++) {
+ const Descriptor* desc = files_ordered[i]->message_type(j);
+ if (!dedup.AddFile(GetMessageFileName(options, desc), desc, error)) {
+ return false;
+ }
+ }
+ for (int j = 0; j < files_ordered[i]->enum_type_count(); j++) {
+ const EnumDescriptor* desc = files_ordered[i]->enum_type(j);
+ if (!dedup.AddFile(GetEnumFileName(options, desc), desc, error)) {
+ return false;
+ }
+ }
+
+ // Pull out all free-floating extensions and generate files for those too.
+ bool has_extension = false;
+
+ for (int j = 0; j < files_ordered[i]->extension_count(); j++) {
+ if (ShouldGenerateExtension(files_ordered[i]->extension(j))) {
+ has_extension = true;
+ }
+ }
+
+ if (has_extension) {
+ if (!dedup.AddFile(GetExtensionFileName(options, files_ordered[i]),
+ files_ordered[i], error)) {
+ return false;
+ }
+ }
+ }
+
+ dedup.GetAllowedSet(allowed_set);
+
+ return true;
+}
+
+} // anonymous namespace
+
+void Generator::GenerateHeader(const GeneratorOptions& options,
+ io::Printer* printer) const {
+ printer->Print("/**\n"
+ " * @fileoverview\n"
+ " * @enhanceable\n"
+ " * @public\n"
+ " */\n"
+ "// GENERATED CODE -- DO NOT EDIT!\n"
+ "\n");
+}
+
+void Generator::FindProvidesForFile(const GeneratorOptions& options,
+ io::Printer* printer,
+ const FileDescriptor* file,
+ std::set<string>* provided) const {
+ for (int i = 0; i < file->message_type_count(); i++) {
+ FindProvidesForMessage(options, printer, file->message_type(i), provided);
+ }
+ for (int i = 0; i < file->enum_type_count(); i++) {
+ FindProvidesForEnum(options, printer, file->enum_type(i), provided);
+ }
+}
+
+void Generator::FindProvides(const GeneratorOptions& options,
+ io::Printer* printer,
+ const vector<const FileDescriptor*>& files,
+ std::set<string>* provided) const {
+ for (int i = 0; i < files.size(); i++) {
+ FindProvidesForFile(options, printer, files[i], provided);
+ }
+
+ printer->Print("\n");
+}
+
+void Generator::FindProvidesForMessage(
+ const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc,
+ std::set<string>* provided) const {
+ if (IgnoreMessage(options, desc)) {
+ return;
+ }
+
+ string name = GetPath(options, desc);
+ provided->insert(name);
+
+ for (int i = 0; i < desc->enum_type_count(); i++) {
+ FindProvidesForEnum(options, printer, desc->enum_type(i),
+ provided);
+ }
+ for (int i = 0; i < desc->nested_type_count(); i++) {
+ FindProvidesForMessage(options, printer, desc->nested_type(i),
+ provided);
+ }
+}
+
+void Generator::FindProvidesForEnum(const GeneratorOptions& options,
+ io::Printer* printer,
+ const EnumDescriptor* enumdesc,
+ std::set<string>* provided) const {
+ string name = GetPath(options, enumdesc);
+ provided->insert(name);
+}
+
+void Generator::FindProvidesForFields(
+ const GeneratorOptions& options,
+ io::Printer* printer,
+ const vector<const FieldDescriptor*>& fields,
+ std::set<string>* provided) const {
+ for (int i = 0; i < fields.size(); i++) {
+ const FieldDescriptor* field = fields[i];
+
+ if (IgnoreField(field)) {
+ continue;
+ }
+
+ string name =
+ GetPath(options, field->file()) + "." +
+ JSObjectFieldName(options, field);
+ provided->insert(name);
+ }
+}
+
+void Generator::GenerateProvides(const GeneratorOptions& options,
+ io::Printer* printer,
+ std::set<string>* provided) const {
+ for (std::set<string>::iterator it = provided->begin();
+ it != provided->end(); ++it) {
+ printer->Print("goog.provide('$name$');\n",
+ "name", *it);
+ }
+}
+
+void Generator::GenerateRequiresForMessage(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc,
+ std::set<string>* provided) const {
+ std::set<string> required;
+ std::set<string> forwards;
+ bool have_message = false;
+ FindRequiresForMessage(options, desc,
+ &required, &forwards, &have_message);
+
+ GenerateRequiresImpl(options, printer, &required, &forwards, provided,
+ /* require_jspb = */ have_message,
+ /* require_extension = */ HasExtensions(desc));
+}
+
+void Generator::GenerateRequiresForLibrary(
+ const GeneratorOptions& options, io::Printer* printer,
+ const vector<const FileDescriptor*>& files,
+ std::set<string>* provided) const {
+ GOOGLE_CHECK_EQ(options.import_style, GeneratorOptions::IMPORT_CLOSURE);
+ // For Closure imports we need to import every message type individually.
+ std::set<string> required;
+ std::set<string> forwards;
+ bool have_extensions = false;
+ bool have_message = false;
+
+ for (int i = 0; i < files.size(); i++) {
+ for (int j = 0; j < files[i]->message_type_count(); j++) {
+ const Descriptor* desc = files[i]->message_type(j);
+ if (!IgnoreMessage(options, desc)) {
+ FindRequiresForMessage(options, desc, &required, &forwards,
+ &have_message);
+ }
+ }
+
+ if (!have_extensions && HasExtensions(files[i])) {
+ have_extensions = true;
+ }
+
+ for (int j = 0; j < files[i]->extension_count(); j++) {
+ const FieldDescriptor* extension = files[i]->extension(j);
+ if (IgnoreField(extension)) {
+ continue;
+ }
+ if (extension->containing_type()->full_name() !=
+ "google.protobuf.bridge.MessageSet") {
+ required.insert(GetPath(options, extension->containing_type()));
+ }
+ FindRequiresForField(options, extension, &required, &forwards);
+ have_extensions = true;
+ }
+ }
+
+ GenerateRequiresImpl(options, printer, &required, &forwards, provided,
+ /* require_jspb = */ have_message,
+ /* require_extension = */ have_extensions);
+}
+
+void Generator::GenerateRequiresForExtensions(
+ const GeneratorOptions& options, io::Printer* printer,
+ const vector<const FieldDescriptor*>& fields,
+ std::set<string>* provided) const {
+ std::set<string> required;
+ std::set<string> forwards;
+ for (int i = 0; i < fields.size(); i++) {
+ const FieldDescriptor* field = fields[i];
+ if (IgnoreField(field)) {
+ continue;
+ }
+ FindRequiresForExtension(options, field, &required, &forwards);
+ }
+
+ GenerateRequiresImpl(options, printer, &required, &forwards, provided,
+ /* require_jspb = */ false,
+ /* require_extension = */ fields.size() > 0);
+}
+
+void Generator::GenerateRequiresImpl(const GeneratorOptions& options,
+ io::Printer* printer,
+ std::set<string>* required,
+ std::set<string>* forwards,
+ std::set<string>* provided,
+ bool require_jspb,
+ bool require_extension) const {
+ if (require_jspb) {
+ printer->Print(
+ "goog.require('jspb.Message');\n");
+ if (options.binary) {
+ printer->Print(
+ "goog.require('jspb.BinaryReader');\n"
+ "goog.require('jspb.BinaryWriter');\n");
+ }
+ }
+ if (require_extension) {
+ printer->Print(
+ "goog.require('jspb.ExtensionFieldInfo');\n");
+ }
+
+ std::set<string>::iterator it;
+ for (it = required->begin(); it != required->end(); ++it) {
+ if (provided->find(*it) != provided->end()) {
+ continue;
+ }
+ printer->Print("goog.require('$name$');\n",
+ "name", *it);
+ }
+
+ printer->Print("\n");
+
+ for (it = forwards->begin(); it != forwards->end(); ++it) {
+ if (provided->find(*it) != provided->end()) {
+ continue;
+ }
+ printer->Print("goog.forwardDeclare('$name$');\n",
+ "name", *it);
+ }
+}
+
+bool NamespaceOnly(const Descriptor* desc) {
+ return false;
+}
+
+void Generator::FindRequiresForMessage(
+ const GeneratorOptions& options,
+ const Descriptor* desc,
+ std::set<string>* required,
+ std::set<string>* forwards,
+ bool* have_message) const {
+
+
+ if (!NamespaceOnly(desc)) {
+ *have_message = true;
+ for (int i = 0; i < desc->field_count(); i++) {
+ const FieldDescriptor* field = desc->field(i);
+ if (IgnoreField(field)) {
+ continue;
+ }
+ FindRequiresForField(options, field, required, forwards);
+ }
+ }
+
+ for (int i = 0; i < desc->extension_count(); i++) {
+ const FieldDescriptor* field = desc->extension(i);
+ if (IgnoreField(field)) {
+ continue;
+ }
+ FindRequiresForExtension(options, field, required, forwards);
+ }
+
+ for (int i = 0; i < desc->nested_type_count(); i++) {
+ FindRequiresForMessage(options, desc->nested_type(i), required, forwards,
+ have_message);
+ }
+}
+
+void Generator::FindRequiresForField(const GeneratorOptions& options,
+ const FieldDescriptor* field,
+ std::set<string>* required,
+ std::set<string>* forwards) const {
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM &&
+ // N.B.: file-level extensions with enum type do *not* create
+ // dependencies, as per original codegen.
+ !(field->is_extension() && field->extension_scope() == NULL)) {
+ if (options.add_require_for_enums) {
+ required->insert(GetPath(options, field->enum_type()));
+ } else {
+ forwards->insert(GetPath(options, field->enum_type()));
+ }
+ } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ if (!IgnoreMessage(options, field->message_type())) {
+ required->insert(GetPath(options, field->message_type()));
+ }
+ }
+}
+
+void Generator::FindRequiresForExtension(const GeneratorOptions& options,
+ const FieldDescriptor* field,
+ std::set<string>* required,
+ std::set<string>* forwards) const {
+ if (field->containing_type()->full_name() != "google.protobuf.bridge.MessageSet") {
+ required->insert(GetPath(options, field->containing_type()));
+ }
+ FindRequiresForField(options, field, required, forwards);
+}
+
+void Generator::GenerateTestOnly(const GeneratorOptions& options,
+ io::Printer* printer) const {
+ if (options.testonly) {
+ printer->Print("goog.setTestOnly();\n\n");
+ }
+ printer->Print("\n");
+}
+
+void Generator::GenerateClassesAndEnums(const GeneratorOptions& options,
+ io::Printer* printer,
+ const FileDescriptor* file) const {
+ for (int i = 0; i < file->message_type_count(); i++) {
+ GenerateClass(options, printer, file->message_type(i));
+ }
+ for (int i = 0; i < file->enum_type_count(); i++) {
+ GenerateEnum(options, printer, file->enum_type(i));
+ }
+}
+
+void Generator::GenerateClass(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const {
+ if (IgnoreMessage(options, desc)) {
+ return;
+ }
+
+ if (!NamespaceOnly(desc)) {
+ printer->Print("\n");
+ GenerateClassConstructor(options, printer, desc);
+ GenerateClassFieldInfo(options, printer, desc);
+
+
+ GenerateClassToObject(options, printer, desc);
+ if (options.binary) {
+ // These must come *before* the extension-field info generation in
+ // GenerateClassRegistration so that references to the binary
+ // serialization/deserialization functions may be placed in the extension
+ // objects.
+ GenerateClassDeserializeBinary(options, printer, desc);
+ GenerateClassSerializeBinary(options, printer, desc);
+ }
+ GenerateClassClone(options, printer, desc);
+ GenerateClassRegistration(options, printer, desc);
+ GenerateClassFields(options, printer, desc);
+ if (IsExtendable(desc) && desc->full_name() != "google.protobuf.bridge.MessageSet") {
+ GenerateClassExtensionFieldInfo(options, printer, desc);
+ }
+
+ if (options.import_style != GeneratorOptions:: IMPORT_CLOSURE) {
+ for (int i = 0; i < desc->extension_count(); i++) {
+ GenerateExtension(options, printer, desc->extension(i));
+ }
+ }
+ }
+
+ // Recurse on nested types.
+ for (int i = 0; i < desc->enum_type_count(); i++) {
+ GenerateEnum(options, printer, desc->enum_type(i));
+ }
+ for (int i = 0; i < desc->nested_type_count(); i++) {
+ GenerateClass(options, printer, desc->nested_type(i));
+ }
+}
+
+void Generator::GenerateClassConstructor(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const {
+ printer->Print(
+ "/**\n"
+ " * Generated by JsPbCodeGenerator.\n"
+ " * @param {Array=} opt_data Optional initial data array, typically "
+ "from a\n"
+ " * server response, or constructed directly in Javascript. The array "
+ "is used\n"
+ " * in place and becomes part of the constructed object. It is not "
+ "cloned.\n"
+ " * If no data is provided, the constructed object will be empty, but "
+ "still\n"
+ " * valid.\n"
+ " * @extends {jspb.Message}\n"
+ " * @constructor\n"
+ " */\n"
+ "$classname$ = function(opt_data) {\n",
+ "classname", GetPath(options, desc));
+ string message_id = GetMessageId(desc);
+ printer->Print(
+ " jspb.Message.initialize(this, opt_data, $messageId$, $pivot$, "
+ "$rptfields$, $oneoffields$);\n",
+ "messageId", !message_id.empty() ?
+ ("'" + message_id + "'") :
+ (IsResponse(desc) ? "''" : "0"),
+ "pivot", GetPivot(desc),
+ "rptfields", RepeatedFieldsArrayName(options, desc),
+ "oneoffields", OneofFieldsArrayName(options, desc));
+ printer->Print(
+ "};\n"
+ "goog.inherits($classname$, jspb.Message);\n"
+ "if (goog.DEBUG && !COMPILED) {\n"
+ " $classname$.displayName = '$classname$';\n"
+ "}\n",
+ "classname", GetPath(options, desc));
+}
+
+void Generator::GenerateClassFieldInfo(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const {
+ if (HasRepeatedFields(desc)) {
+ printer->Print(
+ "/**\n"
+ " * List of repeated fields within this message type.\n"
+ " * @private {!Array<number>}\n"
+ " * @const\n"
+ " */\n"
+ "$classname$$rptfieldarray$ = $rptfields$;\n"
+ "\n",
+ "classname", GetPath(options, desc),
+ "rptfieldarray", kRepeatedFieldArrayName,
+ "rptfields", RepeatedFieldNumberList(desc));
+ }
+
+ if (HasOneofFields(desc)) {
+ printer->Print(
+ "/**\n"
+ " * Oneof group definitions for this message. Each group defines the "
+ "field\n"
+ " * numbers belonging to that group. When of these fields' value is "
+ "set, all\n"
+ " * other fields in the group are cleared. During deserialization, if "
+ "multiple\n"
+ " * fields are encountered for a group, only the last value seen will "
+ "be kept.\n"
+ " * @private {!Array<!Array<number>>}\n"
+ " * @const\n"
+ " */\n"
+ "$classname$$oneofgrouparray$ = $oneofgroups$;\n"
+ "\n",
+ "classname", GetPath(options, desc),
+ "oneofgrouparray", kOneofGroupArrayName,
+ "oneofgroups", OneofGroupList(desc));
+
+ for (int i = 0; i < desc->oneof_decl_count(); i++) {
+ if (IgnoreOneof(desc->oneof_decl(i))) {
+ continue;
+ }
+ GenerateOneofCaseDefinition(options, printer, desc->oneof_decl(i));
+ }
+ }
+}
+
+void Generator::GenerateClassXid(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const {
+ printer->Print(
+ "\n"
+ "\n"
+ "$class$.prototype.messageXid = xid('$class$');\n",
+ "class", GetPath(options, desc));
+}
+
+void Generator::GenerateOneofCaseDefinition(
+ const GeneratorOptions& options,
+ io::Printer* printer,
+ const OneofDescriptor* oneof) const {
+ printer->Print(
+ "/**\n"
+ " * @enum {number}\n"
+ " */\n"
+ "$classname$.$oneof$Case = {\n"
+ " $upcase$_NOT_SET: 0",
+ "classname", GetPath(options, oneof->containing_type()),
+ "oneof", JSOneofName(oneof),
+ "upcase", ToEnumCase(oneof->name()));
+
+ for (int i = 0; i < oneof->field_count(); i++) {
+ if (IgnoreField(oneof->field(i))) {
+ continue;
+ }
+
+ printer->Print(
+ ",\n"
+ " $upcase$: $number$",
+ "upcase", ToEnumCase(oneof->field(i)->name()),
+ "number", JSFieldIndex(oneof->field(i)));
+ }
+
+ printer->Print(
+ "\n"
+ "};\n"
+ "\n"
+ "/**\n"
+ " * @return {$class$.$oneof$Case}\n"
+ " */\n"
+ "$class$.prototype.get$oneof$Case = function() {\n"
+ " return /** @type {$class$.$oneof$Case} */(jspb.Message."
+ "computeOneofCase(this, $class$.oneofGroups_[$oneofindex$]));\n"
+ "};\n"
+ "\n",
+ "class", GetPath(options, oneof->containing_type()),
+ "oneof", JSOneofName(oneof),
+ "oneofindex", JSOneofIndex(oneof));
+}
+
+void Generator::GenerateClassToObject(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const {
+ printer->Print(
+ "\n"
+ "\n"
+ "if (jspb.Message.GENERATE_TO_OBJECT) {\n"
+ "/**\n"
+ " * Creates an object representation of this proto suitable for use in "
+ "Soy templates.\n"
+ " * Field names that are reserved in JavaScript and will be renamed to "
+ "pb_name.\n"
+ " * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.\n"
+ " * For the list of reserved names please see:\n"
+ " * com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS.\n"
+ " * @param {boolean=} opt_includeInstance Whether to include the JSPB "
+ "instance\n"
+ " * for transitional soy proto support: http://goto/soy-param-"
+ "migration\n"
+ " * @return {!Object}\n"
+ " */\n"
+ "$classname$.prototype.toObject = function(opt_includeInstance) {\n"
+ " return $classname$.toObject(opt_includeInstance, this);\n"
+ "};\n"
+ "\n"
+ "\n"
+ "/**\n"
+ " * Static version of the {@see toObject} method.\n"
+ " * @param {boolean|undefined} includeInstance Whether to include the "
+ "JSPB\n"
+ " * instance for transitional soy proto support:\n"
+ " * http://goto/soy-param-migration\n"
+ " * @param {!$classname$} msg The msg instance to transform.\n"
+ " * @return {!Object}\n"
+ " */\n"
+ "$classname$.toObject = function(includeInstance, msg) {\n"
+ " var f, obj = {",
+ "classname", GetPath(options, desc));
+
+ bool first = true;
+ for (int i = 0; i < desc->field_count(); i++) {
+ const FieldDescriptor* field = desc->field(i);
+ if (IgnoreField(field)) {
+ continue;
+ }
+
+ if (!first) {
+ printer->Print(",\n ");
+ } else {
+ printer->Print("\n ");
+ first = false;
+ }
+
+ GenerateClassFieldToObject(options, printer, field);
+ }
+
+ if (!first) {
+ printer->Print("\n };\n\n");
+ } else {
+ printer->Print("\n\n };\n\n");
+ }
+
+ if (IsExtendable(desc)) {
+ printer->Print(
+ " jspb.Message.toObjectExtension(/** @type {!jspb.Message} */ (msg), "
+ "obj,\n"
+ " $extObject$, $class$.prototype.getExtension,\n"
+ " includeInstance);\n",
+ "extObject", JSExtensionsObjectName(options, desc->file(), desc),
+ "class", GetPath(options, desc));
+ }
+
+ printer->Print(
+ " if (includeInstance) {\n"
+ " obj.$$jspbMessageInstance = msg;\n"
+ " }\n"
+ " return obj;\n"
+ "};\n"
+ "}\n"
+ "\n"
+ "\n",
+ "classname", GetPath(options, desc));
+}
+
+void Generator::GenerateClassFieldToObject(const GeneratorOptions& options,
+ io::Printer* printer,
+ const FieldDescriptor* field) const {
+ printer->Print("$fieldname$: ",
+ "fieldname", JSObjectFieldName(options, field));
+
+ if (field->is_map()) {
+ printer->Print("(f = msg.get$name$(true)) ? f.toArray() : []",
+ "name", JSGetterName(options, field));
+ } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ // Message field.
+ if (field->is_repeated()) {
+ {
+ printer->Print("jspb.Message.toObjectList(msg.get$getter$(),\n"
+ " $type$.toObject, includeInstance)",
+ "getter", JSGetterName(options, field),
+ "type", SubmessageTypeRef(options, field));
+ }
+ } else {
+ printer->Print("(f = msg.get$getter$()) && "
+ "$type$.toObject(includeInstance, f)",
+ "getter", JSGetterName(options, field),
+ "type", SubmessageTypeRef(options, field));
+ }
+ } else {
+ // Simple field (singular or repeated).
+ if ((!HasFieldPresence(field) && !field->is_repeated()) ||
+ field->type() == FieldDescriptor::TYPE_BYTES) {
+ // Delegate to the generated get<field>() method in order not to duplicate
+ // the proto3-field-default-value or byte-coercion logic here.
+ printer->Print("msg.get$getter$()",
+ "getter", JSGetterName(options, field, BYTES_B64));
+ } else {
+ if (field->has_default_value()) {
+ printer->Print("!msg.has$name$() ? $defaultValue$ : ",
+ "name", JSGetterName(options, field),
+ "defaultValue", JSFieldDefault(field));
+ }
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_FLOAT ||
+ field->cpp_type() == FieldDescriptor::CPPTYPE_DOUBLE) {
+ if (field->is_repeated()) {
+ printer->Print("jspb.Message.getRepeatedFloatingPointField("
+ "msg, $index$)",
+ "index", JSFieldIndex(field));
+ } else if (field->is_optional() && !field->has_default_value()) {
+ printer->Print("jspb.Message.getOptionalFloatingPointField("
+ "msg, $index$)",
+ "index", JSFieldIndex(field));
+ } else {
+ // Convert "NaN" to NaN.
+ printer->Print("+jspb.Message.getField(msg, $index$)",
+ "index", JSFieldIndex(field));
+ }
+ } else {
+ printer->Print("jspb.Message.getField(msg, $index$)",
+ "index", JSFieldIndex(field));
+ }
+ }
+ }
+}
+
+void Generator::GenerateClassFromObject(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const {
+ printer->Print(
+ "if (jspb.Message.GENERATE_FROM_OBJECT) {\n"
+ "/**\n"
+ " * Loads data from an object into a new instance of this proto.\n"
+ " * @param {!Object} obj The object representation of this proto to\n"
+ " * load the data from.\n"
+ " * @return {!$classname$}\n"
+ " */\n"
+ "$classname$.fromObject = function(obj) {\n"
+ " var f, msg = new $classname$();\n",
+ "classname", GetPath(options, desc));
+
+ for (int i = 0; i < desc->field_count(); i++) {
+ const FieldDescriptor* field = desc->field(i);
+ GenerateClassFieldFromObject(options, printer, field);
+ }
+
+ printer->Print(
+ " return msg;\n"
+ "};\n"
+ "}\n");
+}
+
+void Generator::GenerateClassFieldFromObject(
+ const GeneratorOptions& options,
+ io::Printer* printer,
+ const FieldDescriptor* field) const {
+
+ if (field->is_map()) {
+ // `msg` is a newly-constructed message object that has not yet built any
+ // map containers wrapping underlying arrays, so we can simply directly set
+ // the array here without fear of a stale wrapper.
+ printer->Print(
+ " goog.isDef(obj.$name$) && "
+ "jspb.Message.setField(msg, $index$, obj.$name$);\n",
+ "name", JSObjectFieldName(options, field),
+ "index", JSFieldIndex(field));
+ } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ // Message field (singular or repeated)
+ if (field->is_repeated()) {
+ {
+ printer->Print(
+ " goog.isDef(obj.$name$) && "
+ "jspb.Message.setRepeatedWrapperField(\n"
+ " msg, $index$, goog.array.map(obj.$name$, function(i) {\n"
+ " return $fieldclass$.fromObject(i);\n"
+ " }));\n",
+ "name", JSObjectFieldName(options, field),
+ "index", JSFieldIndex(field),
+ "fieldclass", SubmessageTypeRef(options, field));
+ }
+ } else {
+ printer->Print(
+ " goog.isDef(obj.$name$) && jspb.Message.setWrapperField(\n"
+ " msg, $index$, $fieldclass$.fromObject(obj.$name$));\n",
+ "name", JSObjectFieldName(options, field),
+ "index", JSFieldIndex(field),
+ "fieldclass", SubmessageTypeRef(options, field));
+ }
+ } else {
+ // Simple (primitive) field.
+ printer->Print(
+ " goog.isDef(obj.$name$) && jspb.Message.setField(msg, $index$, "
+ "obj.$name$);\n",
+ "name", JSObjectFieldName(options, field),
+ "index", JSFieldIndex(field));
+ }
+}
+
+void Generator::GenerateClassClone(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const {
+ printer->Print(
+ "/**\n"
+ " * Creates a deep clone of this proto. No data is shared with the "
+ "original.\n"
+ " * @return {!$name$} The clone.\n"
+ " */\n"
+ "$name$.prototype.cloneMessage = function() {\n"
+ " return /** @type {!$name$} */ (jspb.Message.cloneMessage(this));\n"
+ "};\n\n\n",
+ "name", GetPath(options, desc));
+}
+
+void Generator::GenerateClassRegistration(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const {
+ // Register any extensions defined inside this message type.
+ for (int i = 0; i < desc->extension_count(); i++) {
+ const FieldDescriptor* extension = desc->extension(i);
+ if (ShouldGenerateExtension(extension)) {
+ GenerateExtension(options, printer, extension);
+ }
+ }
+
+}
+
+void Generator::GenerateClassFields(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const {
+ for (int i = 0; i < desc->field_count(); i++) {
+ if (!IgnoreField(desc->field(i))) {
+ GenerateClassField(options, printer, desc->field(i));
+ }
+ }
+}
+
+void GenerateBytesWrapper(const GeneratorOptions& options,
+ io::Printer* printer,
+ const FieldDescriptor* field,
+ BytesMode bytes_mode) {
+ string type =
+ JSFieldTypeAnnotation(options, field,
+ /* force_optional = */ false,
+ /* force_present = */ !HasFieldPresence(field),
+ /* singular_if_not_packed = */ false,
+ bytes_mode);
+ printer->Print(
+ "/**\n"
+ " * $fielddef$\n"
+ "$comment$"
+ " * This is a type-conversion wrapper around `get$defname$()`\n"
+ " * @return {$type$}\n"
+ " */\n"
+ "$class$.prototype.get$name$ = function() {\n"
+ " return /** @type {$type$} */ (jspb.Message.bytes$list$As$suffix$(\n"
+ " this.get$defname$()));\n"
+ "};\n"
+ "\n"
+ "\n",
+ "fielddef", FieldDefinition(options, field),
+ "comment", FieldComments(field, bytes_mode),
+ "type", type,
+ "class", GetPath(options, field->containing_type()),
+ "name", JSGetterName(options, field, bytes_mode),
+ "list", field->is_repeated() ? "List" : "",
+ "suffix", JSByteGetterSuffix(bytes_mode),
+ "defname", JSGetterName(options, field, BYTES_DEFAULT));
+}
+
+
+void Generator::GenerateClassField(const GeneratorOptions& options,
+ io::Printer* printer,
+ const FieldDescriptor* field) const {
+ if (field->is_map()) {
+ const FieldDescriptor* key_field = MapFieldKey(field);
+ const FieldDescriptor* value_field = MapFieldValue(field);
+ // Map field: special handling to instantiate the map object on demand.
+ string key_type =
+ JSFieldTypeAnnotation(
+ options, key_field,
+ /* force_optional = */ false,
+ /* force_present = */ true,
+ /* singular_if_not_packed = */ false);
+ string value_type =
+ JSFieldTypeAnnotation(
+ options, value_field,
+ /* force_optional = */ false,
+ /* force_present = */ true,
+ /* singular_if_not_packed = */ false);
+
+ printer->Print(
+ "/**\n"
+ " * $fielddef$\n"
+ " * @param {boolean=} opt_noLazyCreate Do not create the map if\n"
+ " * empty, instead returning `undefined`\n"
+ " * @return {!jspb.Map<$keytype$,$valuetype$>}\n"
+ " */\n",
+ "fielddef", FieldDefinition(options, field),
+ "keytype", key_type,
+ "valuetype", value_type);
+ printer->Print(
+ "$class$.prototype.get$name$ = function(opt_noLazyCreate) {\n"
+ " return /** @type {!jspb.Map<$keytype$,$valuetype$>} */ (\n",
+ "class", GetPath(options, field->containing_type()),
+ "name", JSGetterName(options, field),
+ "keytype", key_type,
+ "valuetype", value_type);
+ printer->Print(
+ " jspb.Message.getMapField(this, $index$, opt_noLazyCreate",
+ "index", JSFieldIndex(field));
+
+ if (value_field->type() == FieldDescriptor::TYPE_MESSAGE) {
+ printer->Print(",\n"
+ " $messageType$",
+ "messageType", GetPath(options, value_field->message_type()));
+ } else if (options.binary) {
+ printer->Print(",\n"
+ " null");
+ }
+
+ printer->Print(
+ "));\n");
+
+ printer->Print(
+ "};\n"
+ "\n"
+ "\n");
+ } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ // Message field: special handling in order to wrap the underlying data
+ // array with a message object.
+
+ printer->Print(
+ "/**\n"
+ " * $fielddef$\n"
+ "$comment$"
+ " * @return {$type$}\n"
+ " */\n",
+ "fielddef", FieldDefinition(options, field),
+ "comment", FieldComments(field, BYTES_DEFAULT),
+ "type", JSFieldTypeAnnotation(options, field,
+ /* force_optional = */ false,
+ /* force_present = */ false,
+ /* singular_if_not_packed = */ false));
+ printer->Print(
+ "$class$.prototype.get$name$ = function() {\n"
+ " return /** @type{$type$} */ (\n"
+ " jspb.Message.get$rpt$WrapperField(this, $wrapperclass$, "
+ "$index$$required$));\n"
+ "};\n"
+ "\n"
+ "\n",
+ "class", GetPath(options, field->containing_type()),
+ "name", JSGetterName(options, field),
+ "type", JSFieldTypeAnnotation(options, field,
+ /* force_optional = */ false,
+ /* force_present = */ false,
+ /* singular_if_not_packed = */ false),
+ "rpt", (field->is_repeated() ? "Repeated" : ""),
+ "index", JSFieldIndex(field),
+ "wrapperclass", SubmessageTypeRef(options, field),
+ "required", (field->label() == FieldDescriptor::LABEL_REQUIRED ?
+ ", 1" : ""));
+ printer->Print(
+ "/** @param {$optionaltype$} value $returndoc$ */\n"
+ "$class$.prototype.set$name$ = function(value) {\n"
+ " jspb.Message.set$oneoftag$$repeatedtag$WrapperField(",
+ "optionaltype",
+ JSFieldTypeAnnotation(options, field,
+ /* force_optional = */ true,
+ /* force_present = */ false,
+ /* singular_if_not_packed = */ false),
+ "returndoc", JSReturnDoc(options, field),
+ "class", GetPath(options, field->containing_type()),
+ "name", JSGetterName(options, field),
+ "oneoftag", (field->containing_oneof() ? "Oneof" : ""),
+ "repeatedtag", (field->is_repeated() ? "Repeated" : ""));
+
+ printer->Print(
+ "this, $index$$oneofgroup$, value);$returnvalue$\n"
+ "};\n"
+ "\n"
+ "\n",
+ "index", JSFieldIndex(field),
+ "oneofgroup", (field->containing_oneof() ?
+ (", " + JSOneofArray(options, field)) : ""),
+ "returnvalue", JSReturnClause(field));
+
+ printer->Print(
+ "$class$.prototype.clear$name$ = function() {\n"
+ " this.set$name$($clearedvalue$);$returnvalue$\n"
+ "};\n"
+ "\n"
+ "\n",
+ "class", GetPath(options, field->containing_type()),
+ "name", JSGetterName(options, field),
+ "clearedvalue", (field->is_repeated() ? "[]" : "undefined"),
+ "returnvalue", JSReturnClause(field));
+
+ } else {
+ bool untyped =
+ false;
+
+ // Simple (primitive) field, either singular or repeated.
+
+ // TODO(b/26173701): Always use BYTES_DEFAULT for the getter return type;
+ // at this point we "lie" to non-binary users and tell the the return
+ // type is always base64 string, pending a LSC to migrate to typed getters.
+ BytesMode bytes_mode =
+ field->type() == FieldDescriptor::TYPE_BYTES && !options.binary ?
+ BYTES_B64 : BYTES_DEFAULT;
+ string typed_annotation =
+ JSFieldTypeAnnotation(options, field,
+ /* force_optional = */ false,
+ /* force_present = */ !HasFieldPresence(field),
+ /* singular_if_not_packed = */ false,
+ /* bytes_mode = */ bytes_mode);
+ if (untyped) {
+ printer->Print(
+ "/**\n"
+ " * @return {?} Raw field, untyped.\n"
+ " */\n");
+ } else {
+ printer->Print(
+ "/**\n"
+ " * $fielddef$\n"
+ "$comment$"
+ " * @return {$type$}\n"
+ " */\n",
+ "fielddef", FieldDefinition(options, field),
+ "comment", FieldComments(field, bytes_mode),
+ "type", typed_annotation);
+ }
+
+ printer->Print(
+ "$class$.prototype.get$name$ = function() {\n",
+ "class", GetPath(options, field->containing_type()),
+ "name", JSGetterName(options, field));
+
+ if (untyped) {
+ printer->Print(
+ " return ");
+ } else {
+ printer->Print(
+ " return /** @type {$type$} */ (",
+ "type", typed_annotation);
+ }
+
+ // For proto3 fields without presence, use special getters that will return
+ // defaults when the field is unset, possibly constructing a value if
+ // required.
+ if (!HasFieldPresence(field) && !field->is_repeated()) {
+ printer->Print("jspb.Message.getFieldProto3(this, $index$, $default$)",
+ "index", JSFieldIndex(field),
+ "default", Proto3PrimitiveFieldDefault(field));
+ } else {
+ if (!field->is_repeated()) {
+ printer->Print("!this.has$name$() ? $defaultValue$ : ",
+ "name", JSGetterName(options, field),
+ "defaultValue", JSFieldDefault(field));
+ }
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_FLOAT ||
+ field->cpp_type() == FieldDescriptor::CPPTYPE_DOUBLE) {
+ if (field->is_repeated()) {
+ printer->Print("jspb.Message.getRepeatedFloatingPointField("
+ "this, $index$)",
+ "index", JSFieldIndex(field));
+ } else {
+ // Convert "NaN" to NaN.
+ printer->Print("+jspb.Message.getField(this, $index$)",
+ "index", JSFieldIndex(field));
+ }
+ } else {
+ printer->Print("jspb.Message.getField(this, $index$)",
+ "index", JSFieldIndex(field));
+ }
+ }
+
+ if (untyped) {
+ printer->Print(
+ ";\n"
+ "};\n"
+ "\n"
+ "\n");
+ } else {
+ printer->Print(
+ ");\n"
+ "};\n"
+ "\n"
+ "\n");
+ }
+
+ if (field->type() == FieldDescriptor::TYPE_BYTES && !untyped) {
+ GenerateBytesWrapper(options, printer, field, BYTES_B64);
+ GenerateBytesWrapper(options, printer, field, BYTES_U8);
+ }
+
+ if (untyped) {
+ printer->Print(
+ "/**\n"
+ " * @param {*} value $returndoc$\n"
+ " */\n",
+ "returndoc", JSReturnDoc(options, field));
+ } else {
+ printer->Print(
+ "/** @param {$optionaltype$} value $returndoc$ */\n",
+ "optionaltype",
+ JSFieldTypeAnnotation(options, field,
+ /* force_optional = */ true,
+ /* force_present = */ !HasFieldPresence(field),
+ /* singular_if_not_packed = */ false),
+ "returndoc", JSReturnDoc(options, field));
+ }
+ printer->Print(
+ "$class$.prototype.set$name$ = function(value) {\n"
+ " jspb.Message.set$oneoftag$Field(this, $index$",
+ "class", GetPath(options, field->containing_type()),
+ "name", JSGetterName(options, field),
+ "oneoftag", (field->containing_oneof() ? "Oneof" : ""),
+ "index", JSFieldIndex(field));
+ printer->Print(
+ "$oneofgroup$, $type$value$rptvalueinit$$typeclose$);$returnvalue$\n"
+ "};\n"
+ "\n"
+ "\n",
+ "type",
+ untyped ? "/** @type{string|number|boolean|Array|undefined} */(" : "",
+ "typeclose", untyped ? ")" : "",
+ "oneofgroup",
+ (field->containing_oneof() ? (", " + JSOneofArray(options, field))
+ : ""),
+ "returnvalue", JSReturnClause(field), "rptvalueinit",
+ (field->is_repeated() ? " || []" : ""));
+
+ if (untyped) {
+ printer->Print(
+ "/**\n"
+ " * Clears the value. $returndoc$\n"
+ " */\n",
+ "returndoc", JSReturnDoc(options, field));
+ }
+
+ if (HasFieldPresence(field) || field->is_repeated()) {
+ printer->Print(
+ "$class$.prototype.clear$name$ = function() {\n"
+ " jspb.Message.set$oneoftag$Field(this, $index$$oneofgroup$, ",
+ "class", GetPath(options, field->containing_type()),
+ "name", JSGetterName(options, field),
+ "oneoftag", (field->containing_oneof() ? "Oneof" : ""),
+ "oneofgroup", (field->containing_oneof() ?
+ (", " + JSOneofArray(options, field)) : ""),
+ "index", JSFieldIndex(field));
+ printer->Print(
+ "$clearedvalue$);$returnvalue$\n"
+ "};\n"
+ "\n"
+ "\n",
+ "clearedvalue", (field->is_repeated() ? "[]" : "undefined"),
+ "returnvalue", JSReturnClause(field));
+ }
+ }
+
+ if (HasFieldPresence(field)) {
+ printer->Print(
+ "/**\n"
+ " * Returns whether this field is set.\n"
+ " * @return{!boolean}\n"
+ " */\n"
+ "$class$.prototype.has$name$ = function() {\n"
+ " return jspb.Message.getField(this, $index$) != null;\n"
+ "};\n"
+ "\n"
+ "\n",
+ "class", GetPath(options, field->containing_type()),
+ "name", JSGetterName(options, field),
+ "index", JSFieldIndex(field));
+ }
+}
+
+void Generator::GenerateClassExtensionFieldInfo(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const {
+ if (IsExtendable(desc)) {
+ printer->Print(
+ "\n"
+ "/**\n"
+ " * The extensions registered with this message class. This is a "
+ "map of\n"
+ " * extension field number to fieldInfo object.\n"
+ " *\n"
+ " * For example:\n"
+ " * { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, "
+ "ctor: proto.example.MyMessage} }\n"
+ " *\n"
+ " * fieldName contains the JsCompiler renamed field name property "
+ "so that it\n"
+ " * works in OPTIMIZED mode.\n"
+ " *\n"
+ " * @type {!Object.<number, jspb.ExtensionFieldInfo>}\n"
+ " */\n"
+ "$class$.extensions = {};\n"
+ "\n",
+ "class", GetPath(options, desc));
+
+ if (options.binary) {
+ printer->Print(
+ "\n"
+ "/**\n"
+ " * The extensions registered with this message class. This is a "
+ "map of\n"
+ " * extension field number to fieldInfo object.\n"
+ " *\n"
+ " * For example:\n"
+ " * { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, "
+ "ctor: proto.example.MyMessage} }\n"
+ " *\n"
+ " * fieldName contains the JsCompiler renamed field name property "
+ "so that it\n"
+ " * works in OPTIMIZED mode.\n"
+ " *\n"
+ " * @type {!Object.<number, jspb.ExtensionFieldInfo>}\n"
+ " */\n"
+ "$class$.extensionsBinary = {};\n"
+ "\n",
+ "class", GetPath(options, desc));
+ }
+ }
+}
+
+
+void Generator::GenerateClassDeserializeBinary(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const {
+ // TODO(cfallin): Handle lazy decoding when requested by field option and/or
+ // by default for 'bytes' fields and packed repeated fields.
+
+ printer->Print(
+ "/**\n"
+ " * Deserializes binary data (in protobuf wire format).\n"
+ " * @param {jspb.ByteSource} bytes The bytes to deserialize.\n"
+ " * @return {!$class$}\n"
+ " */\n"
+ "$class$.deserializeBinary = function(bytes) {\n"
+ " var reader = new jspb.BinaryReader(bytes);\n"
+ " var msg = new $class$;\n"
+ " return $class$.deserializeBinaryFromReader(msg, reader);\n"
+ "};\n"
+ "\n"
+ "\n"
+ "/**\n"
+ " * Deserializes binary data (in protobuf wire format) from the\n"
+ " * given reader into the given message object.\n"
+ " * @param {!$class$} msg The message object to deserialize into.\n"
+ " * @param {!jspb.BinaryReader} reader The BinaryReader to use.\n"
+ " * @return {!$class$}\n"
+ " */\n"
+ "$class$.deserializeBinaryFromReader = function(msg, reader) {\n"
+ " while (reader.nextField()) {\n"
+ " if (reader.isEndGroup()) {\n"
+ " break;\n"
+ " }\n"
+ " var field = reader.getFieldNumber();\n"
+ " switch (field) {\n",
+ "class", GetPath(options, desc));
+
+ for (int i = 0; i < desc->field_count(); i++) {
+ GenerateClassDeserializeBinaryField(options, printer, desc->field(i));
+ }
+
+ printer->Print(
+ " default:\n");
+ if (IsExtendable(desc)) {
+ printer->Print(
+ " jspb.Message.readBinaryExtension(msg, reader, $extobj$Binary,\n"
+ " $class$.prototype.getExtension,\n"
+ " $class$.prototype.setExtension);\n"
+ " break;\n",
+ "extobj", JSExtensionsObjectName(options, desc->file(), desc),
+ "class", GetPath(options, desc));
+ } else {
+ printer->Print(
+ " reader.skipField();\n"
+ " break;\n");
+ }
+
+ printer->Print(
+ " }\n"
+ " }\n"
+ " return msg;\n"
+ "};\n"
+ "\n"
+ "\n");
+}
+
+void Generator::GenerateClassDeserializeBinaryField(
+ const GeneratorOptions& options,
+ io::Printer* printer,
+ const FieldDescriptor* field) const {
+
+ printer->Print(" case $num$:\n",
+ "num", SimpleItoa(field->number()));
+
+ if (field->is_map()) {
+ const FieldDescriptor* key_field = MapFieldKey(field);
+ const FieldDescriptor* value_field = MapFieldValue(field);
+ printer->Print(
+ " var value = msg.get$name$();\n"
+ " reader.readMessage(value, function(message, reader) {\n",
+ "name", JSGetterName(options, field));
+
+ printer->Print(" jspb.Map.deserializeBinary(message, reader, "
+ "$keyReaderFn$, $valueReaderFn$",
+ "keyReaderFn", JSBinaryReaderMethodName(options, key_field),
+ "valueReaderFn", JSBinaryReaderMethodName(options, value_field));
+
+ if (value_field->type() == FieldDescriptor::TYPE_MESSAGE) {
+ printer->Print(", $messageType$.deserializeBinaryFromReader",
+ "messageType", GetPath(options, value_field->message_type()));
+ }
+
+ printer->Print(");\n");
+ printer->Print(" });\n");
+ } else {
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ printer->Print(
+ " var value = new $fieldclass$;\n"
+ " reader.read$msgOrGroup$($grpfield$value,"
+ "$fieldclass$.deserializeBinaryFromReader);\n",
+ "fieldclass", SubmessageTypeRef(options, field),
+ "msgOrGroup", (field->type() == FieldDescriptor::TYPE_GROUP) ?
+ "Group" : "Message",
+ "grpfield", (field->type() == FieldDescriptor::TYPE_GROUP) ?
+ (SimpleItoa(field->number()) + ", ") : "");
+ } else {
+ printer->Print(
+ " var value = /** @type {$fieldtype$} */ "
+ "(reader.read$reader$());\n",
+ "fieldtype", JSFieldTypeAnnotation(options, field, false, true,
+ /* singular_if_not_packed */ true,
+ BYTES_U8),
+ "reader",
+ JSBinaryReadWriteMethodName(field, /* is_writer = */ false));
+ }
+
+ if (field->is_repeated() && !field->is_packed()) {
+ // Repeated fields receive a |value| one at at a time; append to array
+ // returned by get$name$(). Annoyingly, we have to call 'set' after
+ // changing the array.
+ printer->Print(" msg.get$name$().push(value);\n", "name",
+ JSGetterName(options, field));
+ printer->Print(" msg.set$name$(msg.get$name$());\n", "name",
+ JSGetterName(options, field));
+ } else {
+ // Singular fields, and packed repeated fields, receive a |value| either
+ // as the field's value or as the array of all the field's values; set
+ // this as the field's value directly.
+ printer->Print(
+ " msg.set$name$(value);\n",
+ "name", JSGetterName(options, field));
+ }
+ }
+
+ printer->Print(" break;\n");
+}
+
+void Generator::GenerateClassSerializeBinary(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const {
+ printer->Print(
+ "/**\n"
+ " * Class method variant: serializes the given message to binary data\n"
+ " * (in protobuf wire format), writing to the given BinaryWriter.\n"
+ " * @param {!$class$} message\n"
+ " * @param {!jspb.BinaryWriter} writer\n"
+ " */\n"
+ "$class$.serializeBinaryToWriter = function(message, "
+ "writer) {\n"
+ " message.serializeBinaryToWriter(writer);\n"
+ "};\n"
+ "\n"
+ "\n"
+ "/**\n"
+ " * Serializes the message to binary data (in protobuf wire format).\n"
+ " * @return {!Uint8Array}\n"
+ " */\n"
+ "$class$.prototype.serializeBinary = function() {\n"
+ " var writer = new jspb.BinaryWriter();\n"
+ " this.serializeBinaryToWriter(writer);\n"
+ " return writer.getResultBuffer();\n"
+ "};\n"
+ "\n"
+ "\n"
+ "/**\n"
+ " * Serializes the message to binary data (in protobuf wire format),\n"
+ " * writing to the given BinaryWriter.\n"
+ " * @param {!jspb.BinaryWriter} writer\n"
+ " */\n"
+ "$class$.prototype.serializeBinaryToWriter = function (writer) {\n"
+ " var f = undefined;\n",
+ "class", GetPath(options, desc));
+
+ for (int i = 0; i < desc->field_count(); i++) {
+ GenerateClassSerializeBinaryField(options, printer, desc->field(i));
+ }
+
+ if (IsExtendable(desc)) {
+ printer->Print(
+ " jspb.Message.serializeBinaryExtensions(this, writer,\n"
+ " $extobj$Binary, $class$.prototype.getExtension);\n",
+ "extobj", JSExtensionsObjectName(options, desc->file(), desc),
+ "class", GetPath(options, desc));
+ }
+
+ printer->Print(
+ "};\n"
+ "\n"
+ "\n");
+}
+
+void Generator::GenerateClassSerializeBinaryField(
+ const GeneratorOptions& options,
+ io::Printer* printer,
+ const FieldDescriptor* field) const {
+ if (HasFieldPresence(field) &&
+ field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
+ printer->Print(
+ " f = jspb.Message.getField(this, $index$);\n",
+ "index", JSFieldIndex(field));
+ } else {
+ printer->Print(
+ " f = this.get$name$($nolazy$);\n",
+ "name", JSGetterName(options, field, BYTES_U8),
+ // No lazy creation for maps containers -- fastpath the empty case.
+ "nolazy", (field->is_map()) ? "true" : "");
+ }
+
+
+ // Print an `if (condition)` statement that evaluates to true if the field
+ // goes on the wire.
+ if (field->is_map()) {
+ printer->Print(
+ " if (f && f.getLength() > 0) {\n");
+ } else if (field->is_repeated()) {
+ printer->Print(
+ " if (f.length > 0) {\n");
+ } else {
+ if (HasFieldPresence(field)) {
+ printer->Print(
+ " if (f != null) {\n");
+ } else {
+ // No field presence: serialize onto the wire only if value is
+ // non-default. Defaults are documented here:
+ // https://goto.google.com/lhdfm
+ switch (field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ case FieldDescriptor::CPPTYPE_INT64:
+ case FieldDescriptor::CPPTYPE_UINT32:
+ case FieldDescriptor::CPPTYPE_UINT64: {
+ {
+ printer->Print(" if (f !== 0) {\n");
+ }
+ break;
+ }
+
+ case FieldDescriptor::CPPTYPE_ENUM:
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ printer->Print(
+ " if (f !== 0.0) {\n");
+ break;
+ case FieldDescriptor::CPPTYPE_BOOL:
+ printer->Print(
+ " if (f) {\n");
+ break;
+ case FieldDescriptor::CPPTYPE_STRING:
+ printer->Print(
+ " if (f.length > 0) {\n");
+ break;
+ default:
+ assert(false);
+ break;
+ }
+ }
+ }
+
+ // Write the field on the wire.
+ if (field->is_map()) {
+ const FieldDescriptor* key_field = MapFieldKey(field);
+ const FieldDescriptor* value_field = MapFieldValue(field);
+ printer->Print(
+ " f.serializeBinary($index$, writer, "
+ "$keyWriterFn$, $valueWriterFn$",
+ "index", SimpleItoa(field->number()),
+ "keyWriterFn", JSBinaryWriterMethodName(options, key_field),
+ "valueWriterFn", JSBinaryWriterMethodName(options, value_field));
+
+ if (value_field->type() == FieldDescriptor::TYPE_MESSAGE) {
+ printer->Print(", $messageType$.serializeBinaryToWriter",
+ "messageType", GetPath(options, value_field->message_type()));
+ }
+
+ printer->Print(");\n");
+ } else {
+ printer->Print(
+ " writer.write$method$(\n"
+ " $index$,\n"
+ " f",
+ "method", JSBinaryReadWriteMethodName(field, /* is_writer = */ true),
+ "index", SimpleItoa(field->number()));
+
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
+ !(field->is_map())) {
+ printer->Print(
+ ",\n"
+ " $submsg$.serializeBinaryToWriter\n",
+ "submsg", SubmessageTypeRef(options, field));
+ } else {
+ printer->Print("\n");
+ }
+
+ printer->Print(
+ " );\n");
+ }
+
+ // Close the `if`.
+ printer->Print(
+ " }\n");
+}
+
+void Generator::GenerateEnum(const GeneratorOptions& options,
+ io::Printer* printer,
+ const EnumDescriptor* enumdesc) const {
+ printer->Print(
+ "/**\n"
+ " * @enum {number}\n"
+ " */\n"
+ "$name$ = {\n",
+ "name", GetPath(options, enumdesc));
+
+ for (int i = 0; i < enumdesc->value_count(); i++) {
+ const EnumValueDescriptor* value = enumdesc->value(i);
+ printer->Print(
+ " $name$: $value$$comma$\n",
+ "name", ToEnumCase(value->name()),
+ "value", SimpleItoa(value->number()),
+ "comma", (i == enumdesc->value_count() - 1) ? "" : ",");
+ }
+
+ printer->Print(
+ "};\n"
+ "\n");
+}
+
+void Generator::GenerateExtension(const GeneratorOptions& options,
+ io::Printer* printer,
+ const FieldDescriptor* field) const {
+ string extension_scope =
+ (field->extension_scope() ?
+ GetPath(options, field->extension_scope()) :
+ GetPath(options, field->file()));
+
+ printer->Print(
+ "\n"
+ "/**\n"
+ " * A tuple of {field number, class constructor} for the extension\n"
+ " * field named `$name$`.\n"
+ " * @type {!jspb.ExtensionFieldInfo.<$extensionType$>}\n"
+ " */\n"
+ "$class$.$name$ = new jspb.ExtensionFieldInfo(\n",
+ "name", JSObjectFieldName(options, field),
+ "class", extension_scope,
+ "extensionType", JSFieldTypeAnnotation(
+ options, field,
+ /* force_optional = */ false,
+ /* force_present = */ true,
+ /* singular_if_not_packed = */ false));
+ printer->Print(
+ " $index$,\n"
+ " {$name$: 0},\n"
+ " $ctor$,\n"
+ " /** @type {?function((boolean|undefined),!jspb.Message=): "
+ "!Object} */ (\n"
+ " $toObject$),\n"
+ " $repeated$);\n",
+ "index", SimpleItoa(field->number()),
+ "name", JSObjectFieldName(options, field),
+ "ctor", (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ?
+ SubmessageTypeRef(options, field) : string("null")),
+ "toObject", (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ?
+ (SubmessageTypeRef(options, field) + ".toObject") :
+ string("null")),
+ "repeated", (field->is_repeated() ? "1" : "0"));
+
+ if (options.binary) {
+ printer->Print(
+ "\n"
+ "$extendName$Binary[$index$] = new jspb.ExtensionFieldBinaryInfo(\n"
+ " $class$.$name$,\n"
+ " $binaryReaderFn$,\n"
+ " $binaryWriterFn$,\n"
+ " $binaryMessageSerializeFn$,\n"
+ " $binaryMessageDeserializeFn$,\n",
+ "extendName", JSExtensionsObjectName(options, field->file(),
+ field->containing_type()),
+ "index", SimpleItoa(field->number()),
+ "class", extension_scope,
+ "name", JSObjectFieldName(options, field),
+ "binaryReaderFn", JSBinaryReaderMethodName(options, field),
+ "binaryWriterFn", JSBinaryWriterMethodName(options, field),
+ "binaryMessageSerializeFn",
+ (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) ?
+ (SubmessageTypeRef(options, field) +
+ ".serializeBinaryToWriter") : "null",
+ "binaryMessageDeserializeFn",
+ (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) ?
+ (SubmessageTypeRef(options, field) +
+ ".deserializeBinaryFromReader") : "null");
+
+ printer->Print(
+ " $isPacked$);\n",
+ "isPacked", (field->is_packed() ? "true" : "false"));
+ }
+
+ printer->Print(
+ "// This registers the extension field with the extended class, so that\n"
+ "// toObject() will function correctly.\n"
+ "$extendName$[$index$] = $class$.$name$;\n"
+ "\n",
+ "extendName", JSExtensionsObjectName(options, field->file(),
+ field->containing_type()),
+ "index", SimpleItoa(field->number()),
+ "class", extension_scope,
+ "name", JSObjectFieldName(options, field));
+}
+
+bool GeneratorOptions::ParseFromOptions(
+ const vector< pair< string, string > >& options,
+ string* error) {
+ for (int i = 0; i < options.size(); i++) {
+ if (options[i].first == "add_require_for_enums") {
+ if (options[i].second != "") {
+ *error = "Unexpected option value for add_require_for_enums";
+ return false;
+ }
+ add_require_for_enums = true;
+ } else if (options[i].first == "binary") {
+ if (options[i].second != "") {
+ *error = "Unexpected option value for binary";
+ return false;
+ }
+ binary = true;
+ } else if (options[i].first == "testonly") {
+ if (options[i].second != "") {
+ *error = "Unexpected option value for testonly";
+ return false;
+ }
+ testonly = true;
+ } else if (options[i].first == "error_on_name_conflict") {
+ if (options[i].second != "") {
+ *error = "Unexpected option value for error_on_name_conflict";
+ return false;
+ }
+ error_on_name_conflict = true;
+ } else if (options[i].first == "output_dir") {
+ output_dir = options[i].second;
+ } else if (options[i].first == "namespace_prefix") {
+ namespace_prefix = options[i].second;
+ } else if (options[i].first == "library") {
+ library = options[i].second;
+ } else if (options[i].first == "import_style") {
+ if (options[i].second == "closure") {
+ import_style = IMPORT_CLOSURE;
+ } else if (options[i].second == "commonjs") {
+ import_style = IMPORT_COMMONJS;
+ } else if (options[i].second == "browser") {
+ import_style = IMPORT_BROWSER;
+ } else if (options[i].second == "es6") {
+ import_style = IMPORT_ES6;
+ } else {
+ *error = "Unknown import style " + options[i].second + ", expected " +
+ "one of: closure, commonjs, browser, es6.";
+ }
+ } else {
+ // Assume any other option is an output directory, as long as it is a bare
+ // `key` rather than a `key=value` option.
+ if (options[i].second != "") {
+ *error = "Unknown option: " + options[i].first;
+ return false;
+ }
+ output_dir = options[i].first;
+ }
+ }
+
+ if (!library.empty() && import_style != IMPORT_CLOSURE) {
+ *error = "The library option should only be used for "
+ "import_style=closure";
+ }
+
+ return true;
+}
+
+void Generator::GenerateFilesInDepOrder(
+ const GeneratorOptions& options,
+ io::Printer* printer,
+ const vector<const FileDescriptor*>& files) const {
+ // Build a std::set over all files so that the DFS can detect when it recurses
+ // into a dep not specified in the user's command line.
+ std::set<const FileDescriptor*> all_files(files.begin(), files.end());
+ // Track the in-progress set of files that have been generated already.
+ std::set<const FileDescriptor*> generated;
+ for (int i = 0; i < files.size(); i++) {
+ GenerateFileAndDeps(options, printer, files[i], &all_files, &generated);
+ }
+}
+
+void Generator::GenerateFileAndDeps(
+ const GeneratorOptions& options,
+ io::Printer* printer,
+ const FileDescriptor* root,
+ std::set<const FileDescriptor*>* all_files,
+ std::set<const FileDescriptor*>* generated) const {
+ // Skip if already generated.
+ if (generated->find(root) != generated->end()) {
+ return;
+ }
+ generated->insert(root);
+
+ // Generate all dependencies before this file's content.
+ for (int i = 0; i < root->dependency_count(); i++) {
+ const FileDescriptor* dep = root->dependency(i);
+ GenerateFileAndDeps(options, printer, dep, all_files, generated);
+ }
+
+ // Generate this file's content. Only generate if the file is part of the
+ // original set requested to be generated; i.e., don't take all transitive
+ // deps down to the roots.
+ if (all_files->find(root) != all_files->end()) {
+ GenerateClassesAndEnums(options, printer, root);
+ }
+}
+
+void Generator::GenerateFile(const GeneratorOptions& options,
+ io::Printer* printer,
+ const FileDescriptor* file) const {
+ GenerateHeader(options, printer);
+
+ // Generate "require" statements.
+ if (options.import_style == GeneratorOptions::IMPORT_COMMONJS) {
+ printer->Print("var jspb = require('google-protobuf');\n");
+ printer->Print("var goog = jspb;\n");
+ printer->Print("var global = Function('return this')();\n\n");
+
+ for (int i = 0; i < file->dependency_count(); i++) {
+ const string& name = file->dependency(i)->name();
+ printer->Print(
+ "var $alias$ = require('$file$');\n",
+ "alias", ModuleAlias(name),
+ "file", GetRootPath(file->name(), name) + GetJSFilename(name));
+ }
+ }
+
+ // We aren't using Closure's import system, but we use goog.exportSymbol()
+ // to construct the expected tree of objects, eg.
+ //
+ // goog.exportSymbol('foo.bar.Baz', null, this);
+ //
+ // // Later generated code expects foo.bar = {} to exist:
+ // foo.bar.Baz = function() { /* ... */ }
+ set<string> provided;
+
+ // Cover the case where this file declares extensions but no messages.
+ // This will ensure that the file-level object will be declared to hold
+ // the extensions.
+ for (int i = 0; i < file->extension_count(); i++) {
+ provided.insert(file->extension(i)->full_name());
+ }
+
+ FindProvidesForFile(options, printer, file, &provided);
+ for (std::set<string>::iterator it = provided.begin();
+ it != provided.end(); ++it) {
+ printer->Print("goog.exportSymbol('$name$', null, global);\n",
+ "name", *it);
+ }
+
+ GenerateClassesAndEnums(options, printer, file);
+
+ // Extensions nested inside messages are emitted inside
+ // GenerateClassesAndEnums().
+ for (int i = 0; i < file->extension_count(); i++) {
+ GenerateExtension(options, printer, file->extension(i));
+ }
+
+ if (options.import_style == GeneratorOptions::IMPORT_COMMONJS) {
+ printer->Print("goog.object.extend(exports, $package$);\n",
+ "package", GetPath(options, file));
+ }
+}
+
+bool Generator::GenerateAll(const vector<const FileDescriptor*>& files,
+ const string& parameter,
+ GeneratorContext* context,
+ string* error) const {
+ vector< pair< string, string > > option_pairs;
+ ParseGeneratorParameter(parameter, &option_pairs);
+ GeneratorOptions options;
+ if (!options.ParseFromOptions(option_pairs, error)) {
+ return false;
+ }
+
+
+ // There are three schemes for where output files go:
+ //
+ // - import_style = IMPORT_CLOSURE, library non-empty: all output in one file
+ // - import_style = IMPORT_CLOSURE, library empty: one output file per type
+ // - import_style != IMPORT_CLOSURE: one output file per .proto file
+ if (options.import_style == GeneratorOptions::IMPORT_CLOSURE &&
+ options.library != "") {
+ // All output should go in a single file.
+ string filename = options.output_dir + "/" + options.library + ".js";
+ google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(context->Open(filename));
+ GOOGLE_CHECK(output.get());
+ io::Printer printer(output.get(), '$');
+
+ // Pull out all extensions -- we need these to generate all
+ // provides/requires.
+ vector<const FieldDescriptor*> extensions;
+ for (int i = 0; i < files.size(); i++) {
+ for (int j = 0; j < files[i]->extension_count(); j++) {
+ const FieldDescriptor* extension = files[i]->extension(j);
+ extensions.push_back(extension);
+ }
+ }
+
+ GenerateHeader(options, &printer);
+
+ std::set<string> provided;
+ FindProvides(options, &printer, files, &provided);
+ FindProvidesForFields(options, &printer, extensions, &provided);
+ GenerateProvides(options, &printer, &provided);
+ GenerateTestOnly(options, &printer);
+ GenerateRequiresForLibrary(options, &printer, files, &provided);
+
+ GenerateFilesInDepOrder(options, &printer, files);
+
+ for (int i = 0; i < extensions.size(); i++) {
+ if (ShouldGenerateExtension(extensions[i])) {
+ GenerateExtension(options, &printer, extensions[i]);
+ }
+ }
+
+ if (printer.failed()) {
+ return false;
+ }
+ } else if (options.import_style == GeneratorOptions::IMPORT_CLOSURE) {
+ set<const void*> allowed_set;
+ if (!GenerateJspbAllowedSet(options, files, &allowed_set, error)) {
+ return false;
+ }
+
+ for (int i = 0; i < files.size(); i++) {
+ const FileDescriptor* file = files[i];
+ for (int j = 0; j < file->message_type_count(); j++) {
+ const Descriptor* desc = file->message_type(j);
+ if (allowed_set.count(desc) == 0) {
+ continue;
+ }
+
+ string filename = GetMessageFileName(options, desc);
+ google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(
+ context->Open(filename));
+ GOOGLE_CHECK(output.get());
+ io::Printer printer(output.get(), '$');
+
+ GenerateHeader(options, &printer);
+
+ std::set<string> provided;
+ FindProvidesForMessage(options, &printer, desc, &provided);
+ GenerateProvides(options, &printer, &provided);
+ GenerateTestOnly(options, &printer);
+ GenerateRequiresForMessage(options, &printer, desc, &provided);
+
+ GenerateClass(options, &printer, desc);
+
+ if (printer.failed()) {
+ return false;
+ }
+ }
+ for (int j = 0; j < file->enum_type_count(); j++) {
+ const EnumDescriptor* enumdesc = file->enum_type(j);
+ if (allowed_set.count(enumdesc) == 0) {
+ continue;
+ }
+
+ string filename = GetEnumFileName(options, enumdesc);
+ google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(
+ context->Open(filename));
+ GOOGLE_CHECK(output.get());
+ io::Printer printer(output.get(), '$');
+
+ GenerateHeader(options, &printer);
+
+ std::set<string> provided;
+ FindProvidesForEnum(options, &printer, enumdesc, &provided);
+ GenerateProvides(options, &printer, &provided);
+ GenerateTestOnly(options, &printer);
+
+ GenerateEnum(options, &printer, enumdesc);
+
+ if (printer.failed()) {
+ return false;
+ }
+ }
+ // File-level extensions (message-level extensions are generated under
+ // the enclosing message).
+ if (allowed_set.count(file) == 1) {
+ string filename = GetExtensionFileName(options, file);
+
+ google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(
+ context->Open(filename));
+ GOOGLE_CHECK(output.get());
+ io::Printer printer(output.get(), '$');
+
+ GenerateHeader(options, &printer);
+
+ std::set<string> provided;
+ vector<const FieldDescriptor*> fields;
+
+ for (int j = 0; j < files[i]->extension_count(); j++) {
+ if (ShouldGenerateExtension(files[i]->extension(j))) {
+ fields.push_back(files[i]->extension(j));
+ }
+ }
+
+ FindProvidesForFields(options, &printer, fields, &provided);
+ GenerateProvides(options, &printer, &provided);
+ GenerateTestOnly(options, &printer);
+ GenerateRequiresForExtensions(options, &printer, fields, &provided);
+
+ for (int j = 0; j < files[i]->extension_count(); j++) {
+ if (ShouldGenerateExtension(files[i]->extension(j))) {
+ GenerateExtension(options, &printer, files[i]->extension(j));
+ }
+ }
+ }
+ }
+ } else {
+ // Generate one output file per input (.proto) file.
+
+ for (int i = 0; i < files.size(); i++) {
+ const google::protobuf::FileDescriptor* file = files[i];
+
+ string filename = options.output_dir + "/" + GetJSFilename(file->name());
+ google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(context->Open(filename));
+ GOOGLE_CHECK(output.get());
+ io::Printer printer(output.get(), '$');
+
+ GenerateFile(options, &printer, file);
+
+ if (printer.failed()) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+} // namespace js
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/google/protobuf/compiler/js/js_generator.h b/src/google/protobuf/compiler/js/js_generator.h
new file mode 100755
index 00000000..6fd7ca50
--- /dev/null
+++ b/src/google/protobuf/compiler/js/js_generator.h
@@ -0,0 +1,281 @@
+// 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.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JS_GENERATOR_H__
+#define GOOGLE_PROTOBUF_COMPILER_JS_GENERATOR_H__
+
+#include <string>
+#include <set>
+
+#include <google/protobuf/compiler/code_generator.h>
+
+namespace google {
+namespace protobuf {
+
+class Descriptor;
+class EnumDescriptor;
+class FieldDescriptor;
+class OneofDescriptor;
+class FileDescriptor;
+
+namespace io { class Printer; }
+
+namespace compiler {
+namespace js {
+
+struct GeneratorOptions {
+ // Add a `goog.requires()` call for each enum type used. If not set, a forward
+ // declaration with `goog.forwardDeclare` is produced instead.
+ bool add_require_for_enums;
+ // Set this as a test-only module via `goog.setTestOnly();`.
+ bool testonly;
+ // Output path.
+ string output_dir;
+ // Namespace prefix.
+ string namespace_prefix;
+ // Create a library with name <name>_lib.js rather than a separate .js file
+ // per type?
+ string library;
+ // Error if there are two types that would generate the same output file?
+ bool error_on_name_conflict;
+ // Enable binary-format support?
+ bool binary;
+ // What style of imports should be used.
+ enum ImportStyle {
+ IMPORT_CLOSURE, // goog.require()
+ IMPORT_COMMONJS, // require()
+ IMPORT_BROWSER, // no import statements
+ IMPORT_ES6, // import { member } from ''
+ } import_style;
+
+ GeneratorOptions()
+ : add_require_for_enums(false),
+ testonly(false),
+ output_dir("."),
+ namespace_prefix(""),
+ library(""),
+ error_on_name_conflict(false),
+ binary(false),
+ import_style(IMPORT_CLOSURE) {}
+
+ bool ParseFromOptions(
+ const vector< pair< string, string > >& options,
+ string* error);
+};
+
+class LIBPROTOC_EXPORT Generator : public CodeGenerator {
+ public:
+ Generator() {}
+ virtual ~Generator() {}
+
+ virtual bool Generate(const FileDescriptor* file,
+ const string& parameter,
+ GeneratorContext* context,
+ string* error) const {
+ *error = "Unimplemented Generate() method. Call GenerateAll() instead.";
+ return false;
+ }
+
+ virtual bool HasGenerateAll() const { return true; }
+
+ virtual bool GenerateAll(const vector<const FileDescriptor*>& files,
+ const string& parameter,
+ GeneratorContext* context,
+ string* error) const;
+
+ private:
+ void GenerateHeader(const GeneratorOptions& options,
+ io::Printer* printer) const;
+
+ // Generate goog.provides() calls.
+ void FindProvides(const GeneratorOptions& options,
+ io::Printer* printer,
+ const vector<const FileDescriptor*>& file,
+ std::set<string>* provided) const;
+ void FindProvidesForFile(const GeneratorOptions& options,
+ io::Printer* printer,
+ const FileDescriptor* file,
+ std::set<string>* provided) const;
+ void FindProvidesForMessage(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc,
+ std::set<string>* provided) const;
+ void FindProvidesForEnum(const GeneratorOptions& options,
+ io::Printer* printer,
+ const EnumDescriptor* enumdesc,
+ std::set<string>* provided) const;
+ // For extension fields at file scope.
+ void FindProvidesForFields(const GeneratorOptions& options,
+ io::Printer* printer,
+ const vector<const FieldDescriptor*>& fields,
+ std::set<string>* provided) const;
+ // Print the goog.provides() found by the methods above.
+ void GenerateProvides(const GeneratorOptions& options,
+ io::Printer* printer,
+ std::set<string>* provided) const;
+
+ // Generate goog.setTestOnly() if indicated.
+ void GenerateTestOnly(const GeneratorOptions& options,
+ io::Printer* printer) const;
+
+ // Generate goog.requires() calls.
+ void GenerateRequiresForLibrary(const GeneratorOptions& options,
+ io::Printer* printer,
+ const vector<const FileDescriptor*>& files,
+ std::set<string>* provided) const;
+ void GenerateRequiresForMessage(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc,
+ std::set<string>* provided) const;
+ // For extension fields at file scope.
+ void GenerateRequiresForExtensions(
+ const GeneratorOptions& options, io::Printer* printer,
+ const vector<const FieldDescriptor*>& fields,
+ std::set<string>* provided) const;
+ void GenerateRequiresImpl(const GeneratorOptions& options,
+ io::Printer* printer,
+ std::set<string>* required,
+ std::set<string>* forwards,
+ std::set<string>* provided,
+ bool require_jspb,
+ bool require_extension) const;
+ void FindRequiresForMessage(const GeneratorOptions& options,
+ const Descriptor* desc,
+ std::set<string>* required,
+ std::set<string>* forwards,
+ bool* have_message) const;
+ void FindRequiresForField(const GeneratorOptions& options,
+ const FieldDescriptor* field,
+ std::set<string>* required,
+ std::set<string>* forwards) const;
+ void FindRequiresForExtension(const GeneratorOptions& options,
+ const FieldDescriptor* field,
+ std::set<string>* required,
+ std::set<string>* forwards) const;
+
+ void GenerateFile(const GeneratorOptions& options,
+ io::Printer* printer,
+ const FileDescriptor* file) const;
+
+ // Generate definitions for all message classes and enums in all files,
+ // processing the files in dependence order.
+ void GenerateFilesInDepOrder(const GeneratorOptions& options,
+ io::Printer* printer,
+ const vector<const FileDescriptor*>& file) const;
+ // Helper for above.
+ void GenerateFileAndDeps(const GeneratorOptions& options,
+ io::Printer* printer,
+ const FileDescriptor* root,
+ std::set<const FileDescriptor*>* all_files,
+ std::set<const FileDescriptor*>* generated) const;
+
+ // Generate definitions for all message classes and enums.
+ void GenerateClassesAndEnums(const GeneratorOptions& options,
+ io::Printer* printer,
+ const FileDescriptor* file) const;
+
+ // Generate definition for one class.
+ void GenerateClass(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const;
+ void GenerateClassConstructor(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const;
+ void GenerateClassFieldInfo(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const;
+ void GenerateClassXid(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const;
+ void GenerateOneofCaseDefinition(const GeneratorOptions& options,
+ io::Printer* printer,
+ const OneofDescriptor* oneof) const;
+ void GenerateClassToObject(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const;
+ void GenerateClassFieldToObject(const GeneratorOptions& options,
+ io::Printer* printer,
+ const FieldDescriptor* field) const;
+ void GenerateClassFromObject(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const;
+ void GenerateClassFieldFromObject(const GeneratorOptions& options,
+ io::Printer* printer,
+ const FieldDescriptor* field) const;
+ void GenerateClassClone(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const;
+ void GenerateClassRegistration(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const;
+ void GenerateClassFields(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const;
+ void GenerateClassField(const GeneratorOptions& options,
+ io::Printer* printer,
+ const FieldDescriptor* desc) const;
+ void GenerateClassExtensionFieldInfo(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const;
+ void GenerateClassDeserialize(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const;
+ void GenerateClassDeserializeBinary(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const;
+ void GenerateClassDeserializeBinaryField(const GeneratorOptions& options,
+ io::Printer* printer,
+ const FieldDescriptor* field) const;
+ void GenerateClassSerializeBinary(const GeneratorOptions& options,
+ io::Printer* printer,
+ const Descriptor* desc) const;
+ void GenerateClassSerializeBinaryField(const GeneratorOptions& options,
+ io::Printer* printer,
+ const FieldDescriptor* field) const;
+
+ // Generate definition for one enum.
+ void GenerateEnum(const GeneratorOptions& options,
+ io::Printer* printer,
+ const EnumDescriptor* enumdesc) const;
+
+ // Generate an extension definition.
+ void GenerateExtension(const GeneratorOptions& options,
+ io::Printer* printer,
+ const FieldDescriptor* field) const;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Generator);
+};
+
+} // namespace js
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_JS_GENERATOR_H__
diff --git a/src/google/protobuf/compiler/main.cc b/src/google/protobuf/compiler/main.cc
index 584e5a40..2f3c5b8f 100644
--- a/src/google/protobuf/compiler/main.cc
+++ b/src/google/protobuf/compiler/main.cc
@@ -35,9 +35,12 @@
#include <google/protobuf/compiler/python/python_generator.h>
#include <google/protobuf/compiler/java/java_generator.h>
#include <google/protobuf/compiler/javanano/javanano_generator.h>
+// TODO(teboring): Add it back when php implementation is ready
+// #include <google/protobuf/compiler/php/php_generator.h>
#include <google/protobuf/compiler/ruby/ruby_generator.h>
#include <google/protobuf/compiler/csharp/csharp_generator.h>
#include <google/protobuf/compiler/objectivec/objectivec_generator.h>
+#include <google/protobuf/compiler/js/js_generator.h>
int main(int argc, char* argv[]) {
@@ -65,6 +68,12 @@ int main(int argc, char* argv[]) {
cli.RegisterGenerator("--javanano_out", &javanano_generator,
"Generate Java Nano source file.");
+ // TODO(teboring): Add it back when php implementation is ready
+ // PHP
+ // google::protobuf::compiler::php::Generator php_generator;
+ // cli.RegisterGenerator("--php_out", &php_generator,
+ // "Generate PHP source file.");
+
// Ruby
google::protobuf::compiler::ruby::Generator rb_generator;
cli.RegisterGenerator("--ruby_out", &rb_generator,
@@ -77,8 +86,13 @@ int main(int argc, char* argv[]) {
// Objective C
google::protobuf::compiler::objectivec::ObjectiveCGenerator objc_generator;
- cli.RegisterGenerator("--objc_out", &objc_generator,
+ cli.RegisterGenerator("--objc_out", "--objc_opt", &objc_generator,
"Generate Objective C header and source.");
+ // JavaScript
+ google::protobuf::compiler::js::Generator js_generator;
+ cli.RegisterGenerator("--js_out", &js_generator,
+ "Generate JavaScript source.");
+
return cli.Run(argc, argv);
}
diff --git a/src/google/protobuf/compiler/mock_code_generator.cc b/src/google/protobuf/compiler/mock_code_generator.cc
index 98261431..82bb3427 100644
--- a/src/google/protobuf/compiler/mock_code_generator.cc
+++ b/src/google/protobuf/compiler/mock_code_generator.cc
@@ -32,20 +32,26 @@
#include <google/protobuf/compiler/mock_code_generator.h>
+#include <stdlib.h>
+#include <iostream>
#include <memory>
#ifndef _SHARED_PTR_H
#include <google/protobuf/stubs/shared_ptr.h>
#endif
+#include <vector>
+#include <google/protobuf/stubs/logging.h>
+#include <google/protobuf/stubs/common.h>
#include <google/protobuf/testing/file.h>
+#include <google/protobuf/testing/file.h>
+#include <google/protobuf/testing/file.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/descriptor.h>
-#include <google/protobuf/io/zero_copy_stream.h>
-#include <google/protobuf/io/printer.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/substitute.h>
#include <gtest/gtest.h>
-#include <google/protobuf/stubs/stl_util.h>
namespace google {
namespace protobuf {
@@ -147,6 +153,12 @@ bool MockCodeGenerator::Generate(
std::cerr << "Saw message type MockCodeGenerator_HasSourceCodeInfo: "
<< has_source_code_info << "." << std::endl;
abort();
+ } else if (command == "HasJsonName") {
+ FieldDescriptorProto field_descriptor_proto;
+ file->message_type(i)->field(0)->CopyTo(&field_descriptor_proto);
+ std::cerr << "Saw json_name: "
+ << field_descriptor_proto.has_json_name() << std::endl;
+ abort();
} else {
GOOGLE_LOG(FATAL) << "Unknown MockCodeGenerator command: " << command;
}
diff --git a/src/google/protobuf/compiler/mock_code_generator.h b/src/google/protobuf/compiler/mock_code_generator.h
index 8c8348d8..e1665f88 100644
--- a/src/google/protobuf/compiler/mock_code_generator.h
+++ b/src/google/protobuf/compiler/mock_code_generator.h
@@ -34,10 +34,15 @@
#define GOOGLE_PROTOBUF_COMPILER_MOCK_CODE_GENERATOR_H__
#include <string>
+
#include <google/protobuf/compiler/code_generator.h>
namespace google {
namespace protobuf {
+class FileDescriptor;
+} // namespace protobuf
+
+namespace protobuf {
namespace compiler {
// A mock CodeGenerator, used by command_line_interface_unittest. This is in
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_enum.cc b/src/google/protobuf/compiler/objectivec/objectivec_enum.cc
index d6f01c60..e76f8e99 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_enum.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_enum.cc
@@ -72,18 +72,21 @@ void EnumGenerator::GenerateHeader(io::Printer* printer) {
"\n",
"name", name_);
- printer->Print("$comments$typedef GPB_ENUM($name$) {\n",
+ printer->Print("$comments$typedef$deprecated_attribute$ GPB_ENUM($name$) {\n",
"comments", enum_comments,
+ "deprecated_attribute", GetOptionalDeprecatedAttribute(descriptor_),
"name", name_);
printer->Indent();
if (HasPreservingUnknownEnumSemantics(descriptor_->file())) {
// Include the unknown value.
printer->Print(
+ "/// Value used if any message's field encounters a value that is not defined\n"
+ "/// by this enum. The message will also have C functions to get/set the rawValue\n"
+ "/// of the field.\n"
"$name$_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue,\n",
"name", name_);
}
-
for (int i = 0; i < all_values_.size(); i++) {
SourceLocation location;
if (all_values_[i]->GetSourceLocation(&location)) {
@@ -97,8 +100,9 @@ void EnumGenerator::GenerateHeader(io::Printer* printer) {
}
printer->Print(
- "$name$ = $value$,\n",
+ "$name$$deprecated_attribute$ = $value$,\n",
"name", EnumValueName(all_values_[i]),
+ "deprecated_attribute", GetOptionalDeprecatedAttribute(all_values_[i]),
"value", SimpleItoa(all_values_[i]->number()));
}
printer->Outdent();
@@ -107,6 +111,8 @@ void EnumGenerator::GenerateHeader(io::Printer* printer) {
"\n"
"GPBEnumDescriptor *$name$_EnumDescriptor(void);\n"
"\n"
+ "/// Checks to see if the given value is defined by the enum or was not known at\n"
+ "/// the time this source was generated.\n"
"BOOL $name$_IsValidValue(int32_t value);\n"
"\n",
"name", name_);
@@ -118,16 +124,6 @@ void EnumGenerator::GenerateSource(io::Printer* printer) {
"\n",
"name", name_);
- printer->Print(
- "GPBEnumDescriptor *$name$_EnumDescriptor(void) {\n"
- " static GPBEnumDescriptor *descriptor = NULL;\n"
- " if (!descriptor) {\n"
- " static GPBMessageEnumValueDescription values[] = {\n",
- "name", name_);
- printer->Indent();
- printer->Indent();
- printer->Indent();
-
// Note: For the TextFormat decode info, we can't use the enum value as
// the key because protocol buffer enums have 'allow_alias', which lets
// a value be used more than once. Instead, the index into the list of
@@ -135,41 +131,66 @@ void EnumGenerator::GenerateSource(io::Printer* printer) {
// will be zero.
TextFormatDecodeData text_format_decode_data;
int enum_value_description_key = -1;
+ string text_blob;
for (int i = 0; i < all_values_.size(); i++) {
++enum_value_description_key;
string short_name(EnumValueShortName(all_values_[i]));
- printer->Print("{ .name = \"$short_name$\", .number = $name$ },\n",
- "short_name", short_name,
- "name", EnumValueName(all_values_[i]));
+ text_blob += short_name + '\0';
if (UnCamelCaseEnumShortName(short_name) != all_values_[i]->name()) {
text_format_decode_data.AddString(enum_value_description_key, short_name,
all_values_[i]->name());
}
}
- printer->Outdent();
- printer->Outdent();
- printer->Outdent();
+
+ printer->Print(
+ "GPBEnumDescriptor *$name$_EnumDescriptor(void) {\n"
+ " static GPBEnumDescriptor *descriptor = NULL;\n"
+ " if (!descriptor) {\n",
+ "name", name_);
+
+ static const int kBytesPerLine = 40; // allow for escaping
+ printer->Print(
+ " static const char *valueNames =");
+ for (int i = 0; i < text_blob.size(); i += kBytesPerLine) {
+ printer->Print(
+ "\n \"$data$\"",
+ "data", EscapeTrigraphs(CEscape(text_blob.substr(i, kBytesPerLine))));
+ }
+ printer->Print(
+ ";\n"
+ " static const int32_t values[] = {\n");
+ for (int i = 0; i < all_values_.size(); i++) {
+ printer->Print(" $name$,\n", "name", EnumValueName(all_values_[i]));
+ }
printer->Print(" };\n");
+
if (text_format_decode_data.num_entries() == 0) {
printer->Print(
- " descriptor = [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol($name$)\n"
- " values:values\n"
- " valueCount:sizeof(values) / sizeof(GPBMessageEnumValueDescription)\n"
- " enumVerifier:$name$_IsValidValue];\n",
+ " GPBEnumDescriptor *worker =\n"
+ " [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol($name$)\n"
+ " valueNames:valueNames\n"
+ " values:values\n"
+ " count:(uint32_t)(sizeof(values) / sizeof(int32_t))\n"
+ " enumVerifier:$name$_IsValidValue];\n",
"name", name_);
} else {
printer->Print(
" static const char *extraTextFormatInfo = \"$extraTextFormatInfo$\";\n"
- " descriptor = [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol($name$)\n"
- " values:values\n"
- " valueCount:sizeof(values) / sizeof(GPBMessageEnumValueDescription)\n"
- " enumVerifier:$name$_IsValidValue\n"
- " extraTextFormatInfo:extraTextFormatInfo];\n",
+ " GPBEnumDescriptor *worker =\n"
+ " [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol($name$)\n"
+ " valueNames:valueNames\n"
+ " values:values\n"
+ " count:(uint32_t)(sizeof(values) / sizeof(int32_t))\n"
+ " enumVerifier:$name$_IsValidValue\n"
+ " extraTextFormatInfo:extraTextFormatInfo];\n",
"name", name_,
"extraTextFormatInfo", CEscape(text_format_decode_data.Data()));
}
printer->Print(
+ " if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) {\n"
+ " [worker release];\n"
+ " }\n"
" }\n"
" return descriptor;\n"
"}\n\n");
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc
index 30a13ddb..b63bc0de 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc
@@ -44,6 +44,7 @@ namespace compiler {
namespace objectivec {
namespace {
+
void SetEnumVariables(const FieldDescriptor* descriptor,
map<string, string>* variables) {
string type = EnumName(descriptor->enum_type());
@@ -58,25 +59,22 @@ void SetEnumVariables(const FieldDescriptor* descriptor,
(*variables)["enum_verifier"] = type + "_IsValidValue";
(*variables)["enum_desc_func"] = type + "_EnumDescriptor";
+ (*variables)["dataTypeSpecific_name"] = "enumDescFunc";
+ (*variables)["dataTypeSpecific_value"] = (*variables)["enum_desc_func"];
+
const Descriptor* msg_descriptor = descriptor->containing_type();
(*variables)["owning_message_class"] = ClassName(msg_descriptor);
}
} // namespace
-EnumFieldGenerator::EnumFieldGenerator(const FieldDescriptor* descriptor)
- : SingleFieldGenerator(descriptor) {
+EnumFieldGenerator::EnumFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
+ : SingleFieldGenerator(descriptor, options) {
SetEnumVariables(descriptor, &variables_);
}
EnumFieldGenerator::~EnumFieldGenerator() {}
-void EnumFieldGenerator::GenerateFieldDescriptionTypeSpecific(
- io::Printer* printer) const {
- printer->Print(
- variables_,
- " .dataTypeSpecific.enumDescFunc = $enum_desc_func$,\n");
-}
-
void EnumFieldGenerator::GenerateCFunctionDeclarations(
io::Printer* printer) const {
if (!HasPreservingUnknownEnumSemantics(descriptor_->file())) {
@@ -85,7 +83,12 @@ void EnumFieldGenerator::GenerateCFunctionDeclarations(
printer->Print(
variables_,
+ "/// Fetches the raw value of a @c $owning_message_class$'s @c $name$ property, even\n"
+ "/// if the value was not defined by the enum at the time the code was generated.\n"
"int32_t $owning_message_class$_$capitalized_name$_RawValue($owning_message_class$ *message);\n"
+ "/// Sets the raw value of an @c $owning_message_class$'s @c $name$ property, allowing\n"
+ "/// it to be set to a value that was not defined by the enum at the time the code\n"
+ "/// was generated.\n"
"void Set$owning_message_class$_$capitalized_name$_RawValue($owning_message_class$ *message, int32_t value);\n"
"\n");
}
@@ -112,6 +115,7 @@ void EnumFieldGenerator::GenerateCFunctionImplementations(
void EnumFieldGenerator::DetermineForwardDeclarations(
set<string>* fwd_decls) const {
+ SingleFieldGenerator::DetermineForwardDeclarations(fwd_decls);
// If it is an enum defined in a different file, then we'll need a forward
// declaration for it. When it is in our file, all the enums are output
// before the message, so it will be declared before it is needed.
@@ -123,19 +127,18 @@ void EnumFieldGenerator::DetermineForwardDeclarations(
}
RepeatedEnumFieldGenerator::RepeatedEnumFieldGenerator(
- const FieldDescriptor* descriptor)
- : RepeatedFieldGenerator(descriptor) {
+ const FieldDescriptor* descriptor, const Options& options)
+ : RepeatedFieldGenerator(descriptor, options) {
SetEnumVariables(descriptor, &variables_);
variables_["array_storage_type"] = "GPBEnumArray";
}
RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() {}
-void RepeatedEnumFieldGenerator::GenerateFieldDescriptionTypeSpecific(
- io::Printer* printer) const {
- printer->Print(
- variables_,
- " .dataTypeSpecific.enumDescFunc = $enum_desc_func$,\n");
+void RepeatedEnumFieldGenerator::FinishInitialization(void) {
+ RepeatedFieldGenerator::FinishInitialization();
+ variables_["array_comment"] =
+ "// |" + variables_["name"] + "| contains |" + variables_["storage_type"] + "|\n";
}
} // namespace objectivec
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h b/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h
index b629eae8..946faa81 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h
+++ b/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h
@@ -41,16 +41,16 @@ namespace compiler {
namespace objectivec {
class EnumFieldGenerator : public SingleFieldGenerator {
- friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field);
+ friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field,
+ const Options& options);
public:
- virtual void GenerateFieldDescriptionTypeSpecific(io::Printer* printer) const;
virtual void GenerateCFunctionDeclarations(io::Printer* printer) const;
virtual void GenerateCFunctionImplementations(io::Printer* printer) const;
virtual void DetermineForwardDeclarations(set<string>* fwd_decls) const;
protected:
- explicit EnumFieldGenerator(const FieldDescriptor* descriptor);
+ EnumFieldGenerator(const FieldDescriptor* descriptor, const Options& options);
virtual ~EnumFieldGenerator();
private:
@@ -58,13 +58,15 @@ class EnumFieldGenerator : public SingleFieldGenerator {
};
class RepeatedEnumFieldGenerator : public RepeatedFieldGenerator {
- friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field);
+ friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field,
+ const Options& options);
public:
- virtual void GenerateFieldDescriptionTypeSpecific(io::Printer* printer) const;
+ virtual void FinishInitialization();
protected:
- RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor);
+ RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
virtual ~RepeatedEnumFieldGenerator();
private:
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_extension.cc b/src/google/protobuf/compiler/objectivec/objectivec_extension.cc
index 4e348393..3f7ab9d3 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_extension.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_extension.cc
@@ -114,14 +114,14 @@ void ExtensionGenerator::GenerateStaticVariablesInitialization(
printer->Print(vars,
"{\n"
+ " .defaultValue.$default_name$ = $default$,\n"
" .singletonName = GPBStringifySymbol($root_class_and_method_name$),\n"
- " .dataType = $extension_type$,\n"
" .extendedClass = GPBStringifySymbol($extended_type$),\n"
- " .fieldNumber = $number$,\n"
- " .defaultValue.$default_name$ = $default$,\n"
" .messageOrGroupClassName = $type$,\n"
- " .options = $options$,\n"
" .enumDescriptorFunc = $enum_desc_func_name$,\n"
+ " .fieldNumber = $number$,\n"
+ " .dataType = $extension_type$,\n"
+ " .options = $options$,\n"
"},\n");
}
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_field.cc
index cf5d8cfb..812b4a1c 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_field.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_field.cc
@@ -28,6 +28,8 @@
// (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 <iostream>
+
#include <google/protobuf/compiler/objectivec/objectivec_field.h>
#include <google/protobuf/compiler/objectivec/objectivec_helpers.h>
#include <google/protobuf/compiler/objectivec/objectivec_enum_field.h>
@@ -45,6 +47,7 @@ namespace compiler {
namespace objectivec {
namespace {
+
void SetCommonFieldVariables(const FieldDescriptor* descriptor,
map<string, string>* variables) {
string camel_case_name = FieldName(descriptor);
@@ -74,8 +77,8 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor,
(*variables)["field_number_name"] =
classname + "_FieldNumber_" + capitalized_name;
(*variables)["field_number"] = SimpleItoa(descriptor->number());
- (*variables)["has_index"] = SimpleItoa(descriptor->index());
(*variables)["field_type"] = GetCapitalizedType(descriptor);
+ (*variables)["deprecated_attribute"] = GetOptionalDeprecatedAttribute(descriptor);
std::vector<string> field_flags;
if (descriptor->is_repeated()) field_flags.push_back("GPBFieldRepeated");
if (descriptor->is_required()) field_flags.push_back("GPBFieldRequired");
@@ -98,18 +101,9 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor,
(*variables)["dataTypeSpecific_name"] = "className";
(*variables)["dataTypeSpecific_value"] = "NULL";
- string field_options = descriptor->options().SerializeAsString();
- // Must convert to a standard byte order for packing length into
- // a cstring.
- uint32 length = ghtonl(field_options.length());
- if (length > 0) {
- string bytes((const char*)&length, sizeof(length));
- bytes.append(field_options);
- string options_str = "\"" + CEscape(bytes) + "\"";
- (*variables)["fieldoptions"] = "\"" + CEscape(bytes) + "\"";
- } else {
- (*variables)["fieldoptions"] = "";
- }
+ (*variables)["storage_offset_value"] =
+ "(uint32_t)offsetof(" + classname + "__storage_, " + camel_case_name + ")";
+ (*variables)["storage_offset_comment"] = "";
// Clear some common things so they can be set just when needed.
(*variables)["storage_attribute"] = "";
@@ -117,39 +111,40 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor,
} // namespace
-FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field) {
+FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field,
+ const Options& options) {
FieldGenerator* result = NULL;
if (field->is_repeated()) {
switch (GetObjectiveCType(field)) {
case OBJECTIVECTYPE_MESSAGE: {
if (field->is_map()) {
- result = new MapFieldGenerator(field);
+ result = new MapFieldGenerator(field, options);
} else {
- result = new RepeatedMessageFieldGenerator(field);
+ result = new RepeatedMessageFieldGenerator(field, options);
}
break;
}
case OBJECTIVECTYPE_ENUM:
- result = new RepeatedEnumFieldGenerator(field);
+ result = new RepeatedEnumFieldGenerator(field, options);
break;
default:
- result = new RepeatedPrimitiveFieldGenerator(field);
+ result = new RepeatedPrimitiveFieldGenerator(field, options);
break;
}
} else {
switch (GetObjectiveCType(field)) {
case OBJECTIVECTYPE_MESSAGE: {
- result = new MessageFieldGenerator(field);
+ result = new MessageFieldGenerator(field, options);
break;
}
case OBJECTIVECTYPE_ENUM:
- result = new EnumFieldGenerator(field);
+ result = new EnumFieldGenerator(field, options);
break;
default:
if (IsReferenceType(field)) {
- result = new PrimitiveObjFieldGenerator(field);
+ result = new PrimitiveObjFieldGenerator(field, options);
} else {
- result = new PrimitiveFieldGenerator(field);
+ result = new PrimitiveFieldGenerator(field, options);
}
break;
}
@@ -158,8 +153,8 @@ FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field) {
return result;
}
-
-FieldGenerator::FieldGenerator(const FieldDescriptor* descriptor)
+FieldGenerator::FieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
: descriptor_(descriptor) {
SetCommonFieldVariables(descriptor, &variables_);
}
@@ -188,52 +183,54 @@ void FieldGenerator::DetermineForwardDeclarations(
}
void FieldGenerator::GenerateFieldDescription(
- io::Printer* printer) const {
- printer->Print(
- variables_,
- "{\n"
- " .name = \"$name$\",\n"
- " .number = $field_number_name$,\n"
- " .hasIndex = $has_index$,\n"
- " .flags = $fieldflags$,\n"
- " .dataType = GPBDataType$field_type$,\n"
- " .offset = offsetof($classname$__storage_, $name$),\n"
- " .defaultValue.$default_name$ = $default$,\n");
-
- // TODO(thomasvl): It might be useful to add a CPP wrapper to support
- // compiling away the EnumDescriptors. To do that, we'd need a #if here
- // to control setting the descriptor vs. the validator, and above in
- // SetCommonFieldVariables() we'd want to wrap how we add
- // GPBFieldHasDefaultValue to the flags.
-
- // " .dataTypeSpecific.value* = [something],"
- GenerateFieldDescriptionTypeSpecific(printer);
-
- const string& field_options(variables_.find("fieldoptions")->second);
- if (field_options.empty()) {
- printer->Print(" .fieldOptions = NULL,\n");
+ io::Printer* printer, bool include_default) const {
+ // Printed in the same order as the structure decl.
+ if (include_default) {
+ printer->Print(
+ variables_,
+ "{\n"
+ " .defaultValue.$default_name$ = $default$,\n"
+ " .core.name = \"$name$\",\n"
+ " .core.dataTypeSpecific.$dataTypeSpecific_name$ = $dataTypeSpecific_value$,\n"
+ " .core.number = $field_number_name$,\n"
+ " .core.hasIndex = $has_index$,\n"
+ " .core.offset = $storage_offset_value$,$storage_offset_comment$\n"
+ " .core.flags = $fieldflags$,\n"
+ " .core.dataType = GPBDataType$field_type$,\n"
+ "},\n");
} else {
- // Can't use PrintRaw() here to get the #if/#else/#endif lines completely
- // outdented because the need for indent captured on the previous
- // printing of a \n and there is no way to get the current indent level
- // to call the right number of Outdent()/Indents() to maintain state.
printer->Print(
variables_,
- "#if GPBOBJC_INCLUDE_FIELD_OPTIONS\n"
- " .fieldOptions = $fieldoptions$,\n"
- "#else\n"
- " .fieldOptions = NULL,\n"
- "#endif // GPBOBJC_INCLUDE_FIELD_OPTIONS\n");
+ "{\n"
+ " .name = \"$name$\",\n"
+ " .dataTypeSpecific.$dataTypeSpecific_name$ = $dataTypeSpecific_value$,\n"
+ " .number = $field_number_name$,\n"
+ " .hasIndex = $has_index$,\n"
+ " .offset = $storage_offset_value$,$storage_offset_comment$\n"
+ " .flags = $fieldflags$,\n"
+ " .dataType = GPBDataType$field_type$,\n"
+ "},\n");
}
+}
- printer->Print("},\n");
+void FieldGenerator::SetRuntimeHasBit(int has_index) {
+ variables_["has_index"] = SimpleItoa(has_index);
}
-void FieldGenerator::GenerateFieldDescriptionTypeSpecific(
- io::Printer* printer) const {
- printer->Print(
- variables_,
- " .dataTypeSpecific.$dataTypeSpecific_name$ = $dataTypeSpecific_value$,\n");
+void FieldGenerator::SetNoHasBit(void) {
+ variables_["has_index"] = "GPBNoHasBit";
+}
+
+int FieldGenerator::ExtraRuntimeHasBitsNeeded(void) const {
+ return 0;
+}
+
+void FieldGenerator::SetExtraRuntimeHasBitsBase(int index_base) {
+ // NOTE: src/google/protobuf/compiler/plugin.cc makes use of cerr for some
+ // error cases, so it seems to be ok to use as a back door for errors.
+ cerr << "Error: should have overridden SetExtraRuntimeHasBitsBase()." << endl;
+ cerr.flush();
+ abort();
}
void FieldGenerator::SetOneofIndexBase(int index_base) {
@@ -252,9 +249,9 @@ void FieldGenerator::FinishInitialization(void) {
}
}
-SingleFieldGenerator::SingleFieldGenerator(
- const FieldDescriptor* descriptor)
- : FieldGenerator(descriptor) {
+SingleFieldGenerator::SingleFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
+ : FieldGenerator(descriptor, options) {
// Nothing
}
@@ -268,15 +265,15 @@ void SingleFieldGenerator::GenerateFieldStorageDeclaration(
void SingleFieldGenerator::GeneratePropertyDeclaration(
io::Printer* printer) const {
printer->Print(variables_, "$comments$");
+ printer->Print(
+ variables_,
+ "@property(nonatomic, readwrite) $property_type$ $name$$deprecated_attribute$;\n"
+ "\n");
if (WantsHasProperty()) {
printer->Print(
variables_,
- "@property(nonatomic, readwrite) BOOL has$capitalized_name$;\n");
+ "@property(nonatomic, readwrite) BOOL has$capitalized_name$$deprecated_attribute$;\n");
}
- printer->Print(
- variables_,
- "@property(nonatomic, readwrite) $property_type$ $name$;\n"
- "\n");
}
void SingleFieldGenerator::GeneratePropertyImplementation(
@@ -300,9 +297,17 @@ bool SingleFieldGenerator::WantsHasProperty(void) const {
return false;
}
-ObjCObjFieldGenerator::ObjCObjFieldGenerator(
- const FieldDescriptor* descriptor)
- : SingleFieldGenerator(descriptor) {
+bool SingleFieldGenerator::RuntimeUsesHasBit(void) const {
+ if (descriptor_->containing_oneof() != NULL) {
+ // The oneof tracks what is set instead.
+ return false;
+ }
+ return true;
+}
+
+ObjCObjFieldGenerator::ObjCObjFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
+ : SingleFieldGenerator(descriptor, options) {
variables_["property_storage_attribute"] = "strong";
if (IsRetainedName(variables_["name"])) {
variables_["storage_attribute"] = " NS_RETURNS_NOT_RETAINED";
@@ -324,36 +329,38 @@ void ObjCObjFieldGenerator::GeneratePropertyDeclaration(
// conventions (init*, new*, etc.)
printer->Print(variables_, "$comments$");
+ printer->Print(
+ variables_,
+ "@property(nonatomic, readwrite, $property_storage_attribute$, null_resettable) $property_type$ *$name$$storage_attribute$$deprecated_attribute$;\n");
if (WantsHasProperty()) {
printer->Print(
variables_,
- "@property(nonatomic, readwrite) BOOL has$capitalized_name$;\n");
+ "/// Test to see if @c $name$ has been set.\n"
+ "@property(nonatomic, readwrite) BOOL has$capitalized_name$$deprecated_attribute$;\n");
}
- printer->Print(
- variables_,
- "@property(nonatomic, readwrite, $property_storage_attribute$, null_resettable) $property_type$ *$name$$storage_attribute$;\n");
if (IsInitName(variables_.find("name")->second)) {
// If property name starts with init we need to annotate it to get past ARC.
// http://stackoverflow.com/questions/18723226/how-do-i-annotate-an-objective-c-property-with-an-objc-method-family/18723227#18723227
printer->Print(variables_,
- "- ($property_type$ *)$name$ GPB_METHOD_FAMILY_NONE;\n");
+ "- ($property_type$ *)$name$ GPB_METHOD_FAMILY_NONE$deprecated_attribute$;\n");
}
printer->Print("\n");
}
RepeatedFieldGenerator::RepeatedFieldGenerator(
- const FieldDescriptor* descriptor)
- : ObjCObjFieldGenerator(descriptor) {
- // Repeated fields don't use the has index.
- variables_["has_index"] = "GPBNoHasBit";
+ const FieldDescriptor* descriptor, const Options& options)
+ : ObjCObjFieldGenerator(descriptor, options) {
+ // Default to no comment and let the cases needing it fill it in.
+ variables_["array_comment"] = "";
}
RepeatedFieldGenerator::~RepeatedFieldGenerator() {}
void RepeatedFieldGenerator::FinishInitialization(void) {
FieldGenerator::FinishInitialization();
- variables_["array_comment"] =
- "// |" + variables_["name"] + "| contains |" + variables_["storage_type"] + "|\n";
+ if (variables_.find("array_property_type") == variables_.end()) {
+ variables_["array_property_type"] = variable("array_storage_type");
+ }
}
void RepeatedFieldGenerator::GenerateFieldStorageDeclaration(
@@ -379,13 +386,14 @@ void RepeatedFieldGenerator::GeneratePropertyDeclaration(
variables_,
"$comments$"
"$array_comment$"
- "@property(nonatomic, readwrite, strong, null_resettable) $array_storage_type$ *$name$$storage_attribute$;\n"
- "@property(nonatomic, readonly) NSUInteger $name$_Count;\n");
+ "@property(nonatomic, readwrite, strong, null_resettable) $array_property_type$ *$name$$storage_attribute$$deprecated_attribute$;\n"
+ "/// The number of items in @c $name$ without causing the array to be created.\n"
+ "@property(nonatomic, readonly) NSUInteger $name$_Count$deprecated_attribute$;\n");
if (IsInitName(variables_.find("name")->second)) {
// If property name starts with init we need to annotate it to get past ARC.
// http://stackoverflow.com/questions/18723226/how-do-i-annotate-an-objective-c-property-with-an-objc-method-family/18723227#18723227
printer->Print(variables_,
- "- ($array_storage_type$ *)$name$ GPB_METHOD_FAMILY_NONE;\n");
+ "- ($array_property_type$ *)$name$ GPB_METHOD_FAMILY_NONE$deprecated_attribute$;\n");
}
printer->Print("\n");
}
@@ -395,7 +403,12 @@ bool RepeatedFieldGenerator::WantsHasProperty(void) const {
return false;
}
-FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor)
+bool RepeatedFieldGenerator::RuntimeUsesHasBit(void) const {
+ return false; // The array having anything is what is used.
+}
+
+FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor,
+ const Options& options)
: descriptor_(descriptor),
field_generators_(
new scoped_ptr<FieldGenerator>[descriptor->field_count()]),
@@ -403,10 +416,12 @@ FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor)
new scoped_ptr<FieldGenerator>[descriptor->extension_count()]) {
// Construct all the FieldGenerators.
for (int i = 0; i < descriptor->field_count(); i++) {
- field_generators_[i].reset(FieldGenerator::Make(descriptor->field(i)));
+ field_generators_[i].reset(
+ FieldGenerator::Make(descriptor->field(i), options));
}
for (int i = 0; i < descriptor->extension_count(); i++) {
- extension_generators_[i].reset(FieldGenerator::Make(descriptor->extension(i)));
+ extension_generators_[i].reset(
+ FieldGenerator::Make(descriptor->extension(i), options));
}
}
@@ -422,12 +437,40 @@ const FieldGenerator& FieldGeneratorMap::get_extension(int index) const {
return *extension_generators_[index];
}
+int FieldGeneratorMap::CalculateHasBits(void) {
+ int total_bits = 0;
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ if (field_generators_[i]->RuntimeUsesHasBit()) {
+ field_generators_[i]->SetRuntimeHasBit(total_bits);
+ ++total_bits;
+ } else {
+ field_generators_[i]->SetNoHasBit();
+ }
+ int extra_bits = field_generators_[i]->ExtraRuntimeHasBitsNeeded();
+ if (extra_bits) {
+ field_generators_[i]->SetExtraRuntimeHasBitsBase(total_bits);
+ total_bits += extra_bits;
+ }
+ }
+ return total_bits;
+}
+
void FieldGeneratorMap::SetOneofIndexBase(int index_base) {
for (int i = 0; i < descriptor_->field_count(); i++) {
field_generators_[i]->SetOneofIndexBase(index_base);
}
}
+bool FieldGeneratorMap::DoesAnyFieldHaveNonZeroDefault(void) const {
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ if (HasNonZeroDefaultValue(descriptor_->field(i))) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
} // namespace objectivec
} // namespace compiler
} // namespace protobuf
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_field.h b/src/google/protobuf/compiler/objectivec/objectivec_field.h
index 130a52dd..a3a4b1b6 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_field.h
+++ b/src/google/protobuf/compiler/objectivec/objectivec_field.h
@@ -49,24 +49,37 @@ namespace objectivec {
class FieldGenerator {
public:
- static FieldGenerator* Make(const FieldDescriptor* field);
+ static FieldGenerator* Make(const FieldDescriptor* field,
+ const Options& options);
virtual ~FieldGenerator();
+ // Exposed for subclasses to fill in.
virtual void GenerateFieldStorageDeclaration(io::Printer* printer) const = 0;
virtual void GeneratePropertyDeclaration(io::Printer* printer) const = 0;
-
virtual void GeneratePropertyImplementation(io::Printer* printer) const = 0;
- virtual void GenerateFieldDescription(io::Printer* printer) const;
- virtual void GenerateFieldDescriptionTypeSpecific(io::Printer* printer) const;
- virtual void GenerateFieldNumberConstant(io::Printer* printer) const;
+ // Called by GenerateFieldDescription, exposed for classes that need custom
+ // generation.
+ // Exposed for subclasses to extend, base does nothing.
virtual void GenerateCFunctionDeclarations(io::Printer* printer) const;
virtual void GenerateCFunctionImplementations(io::Printer* printer) const;
+ // Exposed for subclasses, should always call it on the parent class also.
virtual void DetermineForwardDeclarations(set<string>* fwd_decls) const;
+ // Used during generation, not intended to be extended by subclasses.
+ void GenerateFieldDescription(
+ io::Printer* printer, bool include_default) const;
+ void GenerateFieldNumberConstant(io::Printer* printer) const;
+
+ // Exposed to get and set the has bits information.
+ virtual bool RuntimeUsesHasBit(void) const = 0;
+ void SetRuntimeHasBit(int has_index);
+ void SetNoHasBit(void);
+ virtual int ExtraRuntimeHasBitsNeeded(void) const;
+ virtual void SetExtraRuntimeHasBitsBase(int index_base);
void SetOneofIndexBase(int index_base);
string variable(const char* key) const {
@@ -81,7 +94,7 @@ class FieldGenerator {
string raw_field_name() const { return variable("raw_field_name"); }
protected:
- explicit FieldGenerator(const FieldDescriptor* descriptor);
+ FieldGenerator(const FieldDescriptor* descriptor, const Options& options);
virtual void FinishInitialization(void);
virtual bool WantsHasProperty(void) const = 0;
@@ -102,8 +115,11 @@ class SingleFieldGenerator : public FieldGenerator {
virtual void GeneratePropertyImplementation(io::Printer* printer) const;
+ virtual bool RuntimeUsesHasBit(void) const;
+
protected:
- explicit SingleFieldGenerator(const FieldDescriptor* descriptor);
+ SingleFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
virtual bool WantsHasProperty(void) const;
private:
@@ -119,7 +135,8 @@ class ObjCObjFieldGenerator : public SingleFieldGenerator {
virtual void GeneratePropertyDeclaration(io::Printer* printer) const;
protected:
- explicit ObjCObjFieldGenerator(const FieldDescriptor* descriptor);
+ ObjCObjFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ObjCObjFieldGenerator);
@@ -134,8 +151,11 @@ class RepeatedFieldGenerator : public ObjCObjFieldGenerator {
virtual void GeneratePropertyImplementation(io::Printer* printer) const;
+ virtual bool RuntimeUsesHasBit(void) const;
+
protected:
- explicit RepeatedFieldGenerator(const FieldDescriptor* descriptor);
+ RepeatedFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
virtual void FinishInitialization(void);
virtual bool WantsHasProperty(void) const;
@@ -146,14 +166,20 @@ class RepeatedFieldGenerator : public ObjCObjFieldGenerator {
// Convenience class which constructs FieldGenerators for a Descriptor.
class FieldGeneratorMap {
public:
- explicit FieldGeneratorMap(const Descriptor* descriptor);
+ FieldGeneratorMap(const Descriptor* descriptor, const Options& options);
~FieldGeneratorMap();
const FieldGenerator& get(const FieldDescriptor* field) const;
const FieldGenerator& get_extension(int index) const;
+ // Assigns the has bits and returns the number of bits needed.
+ int CalculateHasBits(void);
+
void SetOneofIndexBase(int index_base);
+ // Check if any field of this message has a non zero default.
+ bool DoesAnyFieldHaveNonZeroDefault(void) const;
+
private:
const Descriptor* descriptor_;
scoped_array<scoped_ptr<FieldGenerator> > field_generators_;
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_file.cc b/src/google/protobuf/compiler/objectivec/objectivec_file.cc
index 228c66f0..b864ef12 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_file.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_file.cc
@@ -37,30 +37,234 @@
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/stubs/stl_util.h>
#include <google/protobuf/stubs/strutil.h>
+#include <iostream>
#include <sstream>
+// NOTE: src/google/protobuf/compiler/plugin.cc makes use of cerr for some
+// error cases, so it seems to be ok to use as a back door for errors.
+
namespace google {
namespace protobuf {
// This is also found in GPBBootstrap.h, and needs to be kept in sync. It
// is the version check done to ensure generated code works with the current
// runtime being used.
-const int32 GOOGLE_PROTOBUF_OBJC_GEN_VERSION = 30000;
+const int32 GOOGLE_PROTOBUF_OBJC_GEN_VERSION = 30001;
namespace compiler {
namespace objectivec {
-FileGenerator::FileGenerator(const FileDescriptor *file)
+namespace {
+
+class ImportWriter {
+ public:
+ ImportWriter(const Options& options)
+ : options_(options),
+ need_to_parse_mapping_file_(true) {}
+
+ void AddFile(const FileGenerator* file);
+ void Print(io::Printer *printer) const;
+
+ private:
+ class ProtoFrameworkCollector : public LineConsumer {
+ public:
+ ProtoFrameworkCollector(map<string, string>* inout_proto_file_to_framework_name)
+ : map_(inout_proto_file_to_framework_name) {}
+
+ virtual bool ConsumeLine(const StringPiece& line, string* out_error);
+
+ private:
+ map<string, string>* map_;
+ };
+
+ void ParseFrameworkMappings();
+
+ const Options options_;
+ map<string, string> proto_file_to_framework_name_;
+ bool need_to_parse_mapping_file_;
+
+ vector<string> protobuf_framework_imports_;
+ vector<string> protobuf_non_framework_imports_;
+ vector<string> other_framework_imports_;
+ vector<string> other_imports_;
+};
+
+void ImportWriter::AddFile(const FileGenerator* file) {
+ const FileDescriptor* file_descriptor = file->Descriptor();
+ const string extension(".pbobjc.h");
+
+ if (IsProtobufLibraryBundledProtoFile(file_descriptor)) {
+ protobuf_framework_imports_.push_back(
+ FilePathBasename(file_descriptor) + extension);
+ protobuf_non_framework_imports_.push_back(file->Path() + extension);
+ return;
+ }
+
+ // Lazy parse any mappings.
+ if (need_to_parse_mapping_file_) {
+ ParseFrameworkMappings();
+ }
+
+ map<string, string>::iterator proto_lookup =
+ proto_file_to_framework_name_.find(file_descriptor->name());
+ if (proto_lookup != proto_file_to_framework_name_.end()) {
+ other_framework_imports_.push_back(
+ proto_lookup->second + "/" +
+ FilePathBasename(file_descriptor) + extension);
+ return;
+ }
+
+ if (!options_.generate_for_named_framework.empty()) {
+ other_framework_imports_.push_back(
+ options_.generate_for_named_framework + "/" +
+ FilePathBasename(file_descriptor) + extension);
+ return;
+ }
+
+ other_imports_.push_back(file->Path() + extension);
+}
+
+void ImportWriter::Print(io::Printer* printer) const {
+ assert(protobuf_non_framework_imports_.size() ==
+ protobuf_framework_imports_.size());
+
+ bool add_blank_line = false;
+
+ if (protobuf_framework_imports_.size() > 0) {
+ const string framework_name(ProtobufLibraryFrameworkName);
+ const string cpp_symbol(ProtobufFrameworkImportSymbol(framework_name));
+
+ printer->Print(
+ "#if $cpp_symbol$\n",
+ "cpp_symbol", cpp_symbol);
+ for (vector<string>::const_iterator iter = protobuf_framework_imports_.begin();
+ iter != protobuf_framework_imports_.end(); ++iter) {
+ printer->Print(
+ " #import <$framework_name$/$header$>\n",
+ "framework_name", framework_name,
+ "header", *iter);
+ }
+ printer->Print(
+ "#else\n");
+ for (vector<string>::const_iterator iter = protobuf_non_framework_imports_.begin();
+ iter != protobuf_non_framework_imports_.end(); ++iter) {
+ printer->Print(
+ " #import \"$header$\"\n",
+ "header", *iter);
+ }
+ printer->Print(
+ "#endif\n");
+
+ add_blank_line = true;
+ }
+
+ if (other_framework_imports_.size() > 0) {
+ if (add_blank_line) {
+ printer->Print("\n");
+ }
+
+ for (vector<string>::const_iterator iter = other_framework_imports_.begin();
+ iter != other_framework_imports_.end(); ++iter) {
+ printer->Print(
+ " #import <$header$>\n",
+ "header", *iter);
+ }
+
+ add_blank_line = true;
+ }
+
+ if (other_imports_.size() > 0) {
+ if (add_blank_line) {
+ printer->Print("\n");
+ }
+
+ for (vector<string>::const_iterator iter = other_imports_.begin();
+ iter != other_imports_.end(); ++iter) {
+ printer->Print(
+ " #import \"$header$\"\n",
+ "header", *iter);
+ }
+ }
+}
+
+void ImportWriter::ParseFrameworkMappings() {
+ need_to_parse_mapping_file_ = false;
+ if (options_.named_framework_to_proto_path_mappings_path.empty()) {
+ return; // Nothing to do.
+ }
+
+ ProtoFrameworkCollector collector(&proto_file_to_framework_name_);
+ string parse_error;
+ if (!ParseSimpleFile(options_.named_framework_to_proto_path_mappings_path,
+ &collector, &parse_error)) {
+ cerr << "error parsing " << options_.named_framework_to_proto_path_mappings_path
+ << " : " << parse_error << endl;
+ cerr.flush();
+ }
+}
+
+bool ImportWriter::ProtoFrameworkCollector::ConsumeLine(
+ const StringPiece& line, string* out_error) {
+ int offset = line.find(':');
+ if (offset == StringPiece::npos) {
+ *out_error =
+ string("Framework/proto file mapping line without colon sign: '") +
+ line.ToString() + "'.";
+ return false;
+ }
+ StringPiece framework_name(line, 0, offset);
+ StringPiece proto_file_list(line, offset + 1, line.length() - offset - 1);
+ StringPieceTrimWhitespace(&framework_name);
+
+ int start = 0;
+ while (start < proto_file_list.length()) {
+ offset = proto_file_list.find(',', start);
+ if (offset == StringPiece::npos) {
+ offset = proto_file_list.length();
+ }
+
+ StringPiece proto_file(proto_file_list, start, offset - start);
+ StringPieceTrimWhitespace(&proto_file);
+ if (proto_file.size() != 0) {
+ map<string, string>::iterator existing_entry =
+ map_->find(proto_file.ToString());
+ if (existing_entry != map_->end()) {
+ cerr << "warning: duplicate proto file reference, replacing framework entry for '"
+ << proto_file.ToString() << "' with '" << framework_name.ToString()
+ << "' (was '" << existing_entry->second << "')." << endl;
+ cerr.flush();
+ }
+
+ if (proto_file.find(' ') != StringPiece::npos) {
+ cerr << "note: framework mapping file had a proto file with a space in, hopefully that isn't a missing comma: '"
+ << proto_file.ToString() << "'" << endl;
+ cerr.flush();
+ }
+
+ (*map_)[proto_file.ToString()] = framework_name.ToString();
+ }
+
+ start = offset + 1;
+ }
+
+ return true;
+}
+
+} // namespace
+
+
+FileGenerator::FileGenerator(const FileDescriptor *file, const Options& options)
: file_(file),
root_class_name_(FileClassName(file)),
- is_public_dep_(false) {
+ is_public_dep_(false),
+ options_(options) {
for (int i = 0; i < file_->enum_type_count(); i++) {
EnumGenerator *generator = new EnumGenerator(file_->enum_type(i));
enum_generators_.push_back(generator);
}
for (int i = 0; i < file_->message_type_count(); i++) {
MessageGenerator *generator =
- new MessageGenerator(root_class_name_, file_->message_type(i));
+ new MessageGenerator(root_class_name_, file_->message_type(i), options_);
message_generators_.push_back(generator);
}
for (int i = 0; i < file_->extension_count(); i++) {
@@ -81,15 +285,7 @@ FileGenerator::~FileGenerator() {
}
void FileGenerator::GenerateHeader(io::Printer *printer) {
- printer->Print(
- "// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
- "// source: $filename$\n"
- "\n",
- "filename", file_->name());
-
- printer->Print(
- "#import \"GPBProtocolBuffers.h\"\n"
- "\n");
+ PrintFileRuntimePreamble(printer, "GPBProtocolBuffers.h");
// Add some verification that the generated code matches the source the
// code is being compiled with.
@@ -101,19 +297,30 @@ void FileGenerator::GenerateHeader(io::Printer *printer) {
"protoc_gen_objc_version",
SimpleItoa(GOOGLE_PROTOBUF_OBJC_GEN_VERSION));
- const vector<FileGenerator *> &dependency_generators = DependencyGenerators();
- for (vector<FileGenerator *>::const_iterator iter =
- dependency_generators.begin();
- iter != dependency_generators.end(); ++iter) {
- if ((*iter)->IsPublicDependency()) {
- printer->Print("#import \"$header$.pbobjc.h\"\n",
- "header", (*iter)->Path());
+ // #import any headers for "public imports" in the proto file.
+ {
+ ImportWriter import_writer(options_);
+ const vector<FileGenerator *> &dependency_generators = DependencyGenerators();
+ for (vector<FileGenerator *>::const_iterator iter =
+ dependency_generators.begin();
+ iter != dependency_generators.end(); ++iter) {
+ if ((*iter)->IsPublicDependency()) {
+ import_writer.AddFile(*iter);
+ }
}
+ import_writer.Print(printer);
}
+ // Note:
+ // deprecated-declarations suppression is only needed if some place in this
+ // proto file is something deprecated or if it references something from
+ // another file that is deprecated.
printer->Print(
"// @@protoc_insertion_point(imports)\n"
"\n"
+ "#pragma clang diagnostic push\n"
+ "#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n"
+ "\n"
"CF_EXTERN_C_BEGIN\n"
"\n");
@@ -150,13 +357,15 @@ void FileGenerator::GenerateHeader(io::Printer *printer) {
printer->Print(
"#pragma mark - $root_class_name$\n"
"\n"
+ "/// Exposes the extension registry for this file.\n"
+ "///\n"
+ "/// The base class provides:\n"
+ "/// @code\n"
+ "/// + (GPBExtensionRegistry *)extensionRegistry;\n"
+ "/// @endcode\n"
+ "/// which is a @c GPBExtensionRegistry that includes all the extensions defined by\n"
+ "/// this file and all files that it depends on.\n"
"@interface $root_class_name$ : GPBRootObject\n"
- "\n"
- "// The base class provides:\n"
- "// + (GPBExtensionRegistry *)extensionRegistry;\n"
- "// which is an GPBExtensionRegistry that includes all the extensions defined by\n"
- "// this file and all files that it depends on.\n"
- "\n"
"@end\n"
"\n",
"root_class_name", root_class_name_);
@@ -186,36 +395,64 @@ void FileGenerator::GenerateHeader(io::Printer *printer) {
"\n"
"CF_EXTERN_C_END\n"
"\n"
+ "#pragma clang diagnostic pop\n"
+ "\n"
"// @@protoc_insertion_point(global_scope)\n");
}
void FileGenerator::GenerateSource(io::Printer *printer) {
- printer->Print(
- "// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
- "// source: $filename$\n"
- "\n",
- "filename", file_->name());
+ // #import the runtime support.
+ PrintFileRuntimePreamble(printer, "GPBProtocolBuffers_RuntimeSupport.h");
- string header_file = Path() + ".pbobjc.h";
- printer->Print(
- "#import \"GPBProtocolBuffers_RuntimeSupport.h\"\n"
- "#import \"$header_file$\"\n",
- "header_file", header_file);
- const vector<FileGenerator *> &dependency_generators =
- DependencyGenerators();
- for (vector<FileGenerator *>::const_iterator iter =
- dependency_generators.begin();
- iter != dependency_generators.end(); ++iter) {
- if (!(*iter)->IsPublicDependency()) {
- printer->Print("#import \"$header$.pbobjc.h\"\n",
- "header", (*iter)->Path());
+ {
+ ImportWriter import_writer(options_);
+
+ // #import the header for this proto file.
+ import_writer.AddFile(this);
+
+ // #import the headers for anything that a plain dependency of this proto
+ // file (that means they were just an include, not a "public" include).
+ const vector<FileGenerator *> &dependency_generators =
+ DependencyGenerators();
+ for (vector<FileGenerator *>::const_iterator iter =
+ dependency_generators.begin();
+ iter != dependency_generators.end(); ++iter) {
+ if (!(*iter)->IsPublicDependency()) {
+ import_writer.AddFile(*iter);
+ }
+ }
+
+ import_writer.Print(printer);
+ }
+
+ bool includes_oneof = false;
+ for (vector<MessageGenerator *>::iterator iter = message_generators_.begin();
+ iter != message_generators_.end(); ++iter) {
+ if ((*iter)->IncludesOneOfDefinition()) {
+ includes_oneof = true;
+ break;
}
}
+
+ // Note:
+ // deprecated-declarations suppression is only needed if some place in this
+ // proto file is something deprecated or if it references something from
+ // another file that is deprecated.
printer->Print(
"// @@protoc_insertion_point(imports)\n"
- "\n");
+ "\n"
+ "#pragma clang diagnostic push\n"
+ "#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
+ // generated code.
+ printer->Print(
+ "#pragma clang diagnostic ignored \"-Wdirect-ivar-access\"\n");
+ }
printer->Print(
+ "\n"
"#pragma mark - $root_class_name$\n"
"\n"
"@implementation $root_class_name$\n\n",
@@ -340,11 +577,11 @@ void FileGenerator::GenerateSource(io::Printer *printer) {
printer->Print(
"\n"
+ "#pragma clang diagnostic pop\n"
+ "\n"
"// @@protoc_insertion_point(global_scope)\n");
}
-const string FileGenerator::Path() const { return FilePath(file_); }
-
const vector<FileGenerator *> &FileGenerator::DependencyGenerators() {
if (file_->dependency_count() != dependency_generators_.size()) {
set<string> public_import_names;
@@ -352,7 +589,8 @@ const vector<FileGenerator *> &FileGenerator::DependencyGenerators() {
public_import_names.insert(file_->public_dependency(i)->name());
}
for (int i = 0; i < file_->dependency_count(); i++) {
- FileGenerator *generator = new FileGenerator(file_->dependency(i));
+ FileGenerator *generator =
+ new FileGenerator(file_->dependency(i), options_);
const string& name = file_->dependency(i)->name();
bool public_import = (public_import_names.count(name) != 0);
generator->SetIsPublicDependency(public_import);
@@ -362,6 +600,37 @@ const vector<FileGenerator *> &FileGenerator::DependencyGenerators() {
return dependency_generators_;
}
+// Helper to print the import of the runtime support at the top of generated
+// files. This currently only supports the runtime coming from a framework
+// as defined by the official CocoaPod.
+void FileGenerator::PrintFileRuntimePreamble(
+ io::Printer* printer, const string& header_to_import) const {
+ printer->Print(
+ "// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
+ "// source: $filename$\n"
+ "\n",
+ "filename", file_->name());
+
+ const string framework_name(ProtobufLibraryFrameworkName);
+ const string cpp_symbol(ProtobufFrameworkImportSymbol(framework_name));
+ printer->Print(
+ "// This CPP symbol can be defined to use imports that match up to the framework\n"
+ "// imports needed when using CocoaPods.\n"
+ "#if !defined($cpp_symbol$)\n"
+ " #define $cpp_symbol$ 0\n"
+ "#endif\n"
+ "\n"
+ "#if $cpp_symbol$\n"
+ " #import <$framework_name$/$header$>\n"
+ "#else\n"
+ " #import \"$header$\"\n"
+ "#endif\n"
+ "\n",
+ "cpp_symbol", cpp_symbol,
+ "header", header_to_import,
+ "framework_name", framework_name);
+}
+
} // namespace objectivec
} // namespace compiler
} // namespace protobuf
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_file.h b/src/google/protobuf/compiler/objectivec/objectivec_file.h
index 1bb4f0ea..8e4388d8 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_file.h
+++ b/src/google/protobuf/compiler/objectivec/objectivec_file.h
@@ -55,14 +55,15 @@ class MessageGenerator;
class FileGenerator {
public:
- explicit FileGenerator(const FileDescriptor* file);
+ FileGenerator(const FileDescriptor* file, const Options& options);
~FileGenerator();
void GenerateSource(io::Printer* printer);
void GenerateHeader(io::Printer* printer);
const string& RootClassName() const { return root_class_name_; }
- const string Path() const;
+ const string Path() const { return FilePath(file_); }
+ const FileDescriptor* Descriptor() const { return file_; }
bool IsPublicDependency() const { return is_public_dep_; }
@@ -84,7 +85,11 @@ class FileGenerator {
vector<ExtensionGenerator*> extension_generators_;
bool is_public_dep_;
+ const Options options_;
+
const vector<FileGenerator*>& DependencyGenerators();
+ void PrintFileRuntimePreamble(
+ io::Printer* printer, const string& header_to_import) const;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileGenerator);
};
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_generator.cc b/src/google/protobuf/compiler/objectivec/objectivec_generator.cc
index 375b4e0f..a0b6d6cb 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_generator.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_generator.cc
@@ -49,21 +49,81 @@ bool ObjectiveCGenerator::Generate(const FileDescriptor* file,
const string& parameter,
OutputDirectory* output_directory,
string* error) const {
- // ObjC doesn't have any options at the moment, error if passed one.
+ // -----------------------------------------------------------------
+ // Parse generator options. These options are passed to the compiler using the
+ // --objc_opt flag. The options are passed as a comma separated list of
+ // options along with their values. If the option appears multiple times, only
+ // the last value will be considered.
+ //
+ // e.g. protoc ... --objc_opt=expected_prefixes=file.txt,generate_for_named_framework=MyFramework
+
+ Options generation_options;
+
vector<pair<string, string> > options;
ParseGeneratorParameter(parameter, &options);
for (int i = 0; i < options.size(); i++) {
- *error = "error:: Unknown generator option: " + options[i].first;
- return false;
+ if (options[i].first == "expected_prefixes_path") {
+ // Path to find a file containing the expected prefixes
+ // (objc_class_prefix "PREFIX") for proto packages (package NAME). The
+ // generator will then issue warnings/errors if in the proto files being
+ // generated the option is not listed/wrong/etc in the file.
+ //
+ // The format of the file is:
+ // - An entry is a line of "package=prefix".
+ // - Comments start with "#".
+ // - A comment can go on a line after a expected package/prefix pair.
+ // (i.e. - "package=prefix # comment")
+ //
+ // There is no validation that the prefixes are good prefixes, it is
+ // assumed that they are when you create the file.
+ generation_options.expected_prefixes_path = options[i].second;
+ } 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
+ // name (i.e. - "#import <NAME/proto.pbobjc.h>).
+ //
+ // NOTE: If this option is used with
+ // named_framework_to_proto_path_mappings_path, then this is effectively
+ // the "default" framework name used for everything that wasn't mapped by
+ // the mapping file.
+ generation_options.generate_for_named_framework = options[i].second;
+ } else if (options[i].first == "named_framework_to_proto_path_mappings_path") {
+ // Path to find a file containing the list of framework names and proto
+ // files. The generator uses this to decide if a proto file
+ // referenced should use a framework style import vs. a user level import
+ // (#import <FRAMEWORK/file.pbobjc.h> vs #import "dir/file.pbobjc.h").
+ //
+ // The format of the file is:
+ // - An entry is a line of "frameworkName: file.proto, dir/file2.proto".
+ // - Comments start with "#".
+ // - A comment can go on a line after a expected package/prefix pair.
+ // (i.e. - "frameworkName: file.proto # comment")
+ //
+ // 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 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
+ // with generate_for_named_framework, or the relative path to it's include
+ // path otherwise.
+ generation_options.named_framework_to_proto_path_mappings_path = options[i].second;
+ } else {
+ *error = "error: Unknown generator option: " + options[i].first;
+ return false;
+ }
}
+ // -----------------------------------------------------------------
+
// Validate the objc prefix/package pairing.
- if (!ValidateObjCClassPrefix(file, error)) {
+ if (!ValidateObjCClassPrefix(file, generation_options, error)) {
// *error will have been filled in.
return false;
}
- FileGenerator file_generator(file);
+ FileGenerator file_generator(file, generation_options);
string filepath = FilePath(file);
// Generate header.
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc
index 990aca24..22c7a883 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc
@@ -58,6 +58,14 @@ namespace protobuf {
namespace compiler {
namespace objectivec {
+Options::Options() {
+ // Default is the value of the env for the package prefixes.
+ const char* file_path = getenv("GPB_OBJC_EXPECTED_PACKAGE_PREFIXES");
+ if (file_path) {
+ expected_prefixes_path = file_path;
+ }
+}
+
namespace {
hash_set<string> MakeWordsMap(const char* const words[], size_t num_words) {
@@ -73,6 +81,10 @@ const char* const kUpperSegmentsList[] = {"url", "http", "https"};
hash_set<string> kUpperSegments =
MakeWordsMap(kUpperSegmentsList, GOOGLE_ARRAYSIZE(kUpperSegmentsList));
+bool ascii_isnewline(char c) {
+ return c == '\n' || c == '\r';
+}
+
// Internal helper for name handing.
// Do not expose this outside of helpers, stick to having functions for specific
// cases (ClassName(), FieldName()), so there is always consistent suffix rules.
@@ -116,9 +128,14 @@ string UnderscoresToCamelCase(const string& input, bool first_capitalized) {
}
values.push_back(current);
+ string result;
+ bool first_segment_forces_upper = false;
for (vector<string>::iterator i = values.begin(); i != values.end(); ++i) {
string value = *i;
bool all_upper = (kUpperSegments.count(value) > 0);
+ if (all_upper && (result.length() == 0)) {
+ first_segment_forces_upper = true;
+ }
for (int j = 0; j < value.length(); j++) {
if (j == 0 || all_upper) {
value[j] = ascii_toupper(value[j]);
@@ -126,13 +143,11 @@ string UnderscoresToCamelCase(const string& input, bool first_capitalized) {
// Nothing, already in lower.
}
}
- *i = value;
+ result += value;
}
- string result;
- for (vector<string>::iterator i = values.begin(); i != values.end(); ++i) {
- result += *i;
- }
- if ((result.length() != 0) && !first_capitalized) {
+ if ((result.length() != 0) &&
+ !first_capitalized &&
+ !first_segment_forces_upper) {
result[0] = ascii_tolower(result[0]);
}
return result;
@@ -209,11 +224,6 @@ string NameFromFieldDescriptor(const FieldDescriptor* field) {
}
}
-// Escape C++ trigraphs by escaping question marks to \?
-string EscapeTrigraphs(const string& to_escape) {
- return StringReplace(to_escape, "?", "\\?", true);
-}
-
void PathSplit(const string& path, string* directory, string* basename) {
string::size_type last_slash = path.rfind('/');
if (last_slash == string::npos) {
@@ -253,6 +263,11 @@ bool IsSpecialName(const string& name, const string* special_names,
} // namespace
+// Escape C++ trigraphs by escaping question marks to \?
+string EscapeTrigraphs(const string& to_escape) {
+ return StringReplace(to_escape, "?", "\\?", true);
+}
+
string StripProto(const string& filename) {
if (HasSuffixString(filename, ".protodevel")) {
return StripSuffixString(filename, ".protodevel");
@@ -261,6 +276,16 @@ string StripProto(const string& filename) {
}
}
+void StringPieceTrimWhitespace(StringPiece* input) {
+ while (!input->empty() && ascii_isspace(*input->data())) {
+ input->remove_prefix(1);
+ }
+ while (!input->empty() && ascii_isspace((*input)[input->length() - 1])) {
+ input->remove_suffix(1);
+ }
+}
+
+
bool IsRetainedName(const string& name) {
// List of prefixes from
// http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html
@@ -282,13 +307,6 @@ string BaseFileName(const FileDescriptor* file) {
return basename;
}
-string FileName(const FileDescriptor* file) {
- string path = FilePath(file);
- string basename;
- PathSplit(path, NULL, &basename);
- return basename;
-}
-
string FilePath(const FileDescriptor* file) {
string output;
string basename;
@@ -306,6 +324,19 @@ string FilePath(const FileDescriptor* file) {
return output;
}
+string FilePathBasename(const FileDescriptor* file) {
+ string output;
+ string basename;
+ string directory;
+ PathSplit(file->name(), &directory, &basename);
+ basename = StripProto(basename);
+
+ // CamelCase to be more ObjC friendly.
+ output = UnderscoresToCamelCase(basename, true);
+
+ return output;
+}
+
string FileClassPrefix(const FileDescriptor* file) {
// Default is empty string, no need to check has_objc_class_prefix.
string result = file->options().objc_class_prefix();
@@ -723,7 +754,7 @@ string DefaultValue(const FieldDescriptor* field) {
uint32 length = ghtonl(default_string.length());
string bytes((const char*)&length, sizeof(length));
bytes.append(default_string);
- return "(NSData*)\"" + CEscape(bytes) + "\"";
+ return "(NSData*)\"" + EscapeTrigraphs(CEscape(bytes)) + "\"";
} else {
return "@\"" + EscapeTrigraphs(CEscape(default_string)) + "\"";
}
@@ -740,6 +771,51 @@ string DefaultValue(const FieldDescriptor* field) {
return NULL;
}
+bool HasNonZeroDefaultValue(const FieldDescriptor* field) {
+ // Repeated fields don't have defaults.
+ if (field->is_repeated()) {
+ return false;
+ }
+
+ // As much as checking field->has_default_value() seems useful, it isn't
+ // because of enums. proto2 syntax allows the first item in an enum (the
+ // default) to be non zero. So checking field->has_default_value() would
+ // result in missing this non zero default. See MessageWithOneBasedEnum in
+ // objectivec/Tests/unittest_objc.proto for a test Message to confirm this.
+
+ // Some proto file set the default to the zero value, so make sure the value
+ // isn't the zero case.
+ switch (field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ return field->default_value_int32() != 0;
+ case FieldDescriptor::CPPTYPE_UINT32:
+ return field->default_value_uint32() != 0U;
+ case FieldDescriptor::CPPTYPE_INT64:
+ return field->default_value_int64() != 0LL;
+ case FieldDescriptor::CPPTYPE_UINT64:
+ return field->default_value_uint64() != 0ULL;
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ return field->default_value_double() != 0.0;
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ return field->default_value_float() != 0.0f;
+ case FieldDescriptor::CPPTYPE_BOOL:
+ return field->default_value_bool();
+ case FieldDescriptor::CPPTYPE_STRING: {
+ const string& default_string = field->default_value_string();
+ return default_string.length() != 0;
+ }
+ case FieldDescriptor::CPPTYPE_ENUM:
+ return field->default_value_enum()->number() != 0;
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ return false;
+ }
+
+ // Some compilers report reaching end of function even though all cases of
+ // the enum are handed in the switch.
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return false;
+}
+
string BuildFlagsString(const vector<string>& strings) {
if (strings.size() == 0) {
return "0";
@@ -763,79 +839,52 @@ string BuildCommentsString(const SourceLocation& location) {
while (!lines.empty() && lines.back().empty()) {
lines.pop_back();
}
- string prefix("//");
+ string prefix("///");
string suffix("\n");
string final_comments;
for (int i = 0; i < lines.size(); i++) {
- // We use $ for delimiters, so replace comments with dollars with
- // html escaped version.
- // None of the other compilers handle this (as of this writing) but we
- // ran into it once, so just to be safe.
+ // HeaderDoc uses '\' and '@' for markers; escape them.
+ const string line = StringReplace(lines[i], "\\", "\\\\", true);
final_comments +=
- prefix + StringReplace(lines[i], "$", "&#36;", true) + suffix;
+ prefix + StringReplace(line, "@", "\\@", true) + suffix;
}
return final_comments;
}
-namespace {
-
-// Internal helper class that parses the expected package to prefix mappings
-// file.
-class Parser {
- public:
- Parser(map<string, string>* inout_package_to_prefix_map)
- : prefix_map_(inout_package_to_prefix_map), line_(0) {}
-
- // Parses a check of input, returning success/failure.
- bool ParseChunk(StringPiece chunk);
-
- // Should be called to finish parsing (after all input has been provided via
- // ParseChunk()). Returns success/failure.
- bool Finish();
-
- int last_line() const { return line_; }
- string error_str() const { return error_str_; }
-
- private:
- bool ParseLoop();
-
- map<string, string>* prefix_map_;
- int line_;
- string error_str_;
- StringPiece p_;
- string leftover_;
-};
-
-bool Parser::ParseChunk(StringPiece chunk) {
- if (!leftover_.empty()) {
- chunk.AppendToString(&leftover_);
- p_ = StringPiece(leftover_);
- } else {
- p_ = chunk;
- }
- bool result = ParseLoop();
- if (p_.empty()) {
- leftover_.clear();
- } else {
- leftover_ = p_.ToString();
- }
+// Making these a generator option for folks that don't use CocoaPods, but do
+// want to put the library in a framework is an interesting question. The
+// problem is it means changing sources shipped with the library to actually
+// use a different value; so it isn't as simple as a option.
+const char* const ProtobufLibraryFrameworkName = "Protobuf";
+
+string ProtobufFrameworkImportSymbol(const string& framework_name) {
+ // GPB_USE_[framework_name]_FRAMEWORK_IMPORTS
+ string result = string("GPB_USE_");
+ result += ToUpper(framework_name);
+ result += "_FRAMEWORK_IMPORTS";
return result;
}
-bool Parser::Finish() {
- if (leftover_.empty()) {
+bool IsProtobufLibraryBundledProtoFile(const FileDescriptor* file) {
+ // We don't check the name prefix or proto package because some files
+ // (descriptor.proto), aren't shipped generated by the library, so this
+ // seems to be the safest way to only catch the ones shipped.
+ const string name = file->name();
+ if (name == "google/protobuf/any.proto" ||
+ name == "google/protobuf/api.proto" ||
+ name == "google/protobuf/duration.proto" ||
+ name == "google/protobuf/empty.proto" ||
+ name == "google/protobuf/field_mask.proto" ||
+ name == "google/protobuf/source_context.proto" ||
+ name == "google/protobuf/struct.proto" ||
+ name == "google/protobuf/timestamp.proto" ||
+ name == "google/protobuf/type.proto" ||
+ name == "google/protobuf/wrappers.proto") {
return true;
}
- // Force a newline onto the end to finish parsing.
- p_ = StringPiece(leftover_ + "\n");
- if (!ParseLoop()) {
- return false;
- }
- return p_.empty(); // Everything used?
+ return false;
}
-static bool ascii_isnewline(char c) { return c == '\n' || c == '\r'; }
-
bool ReadLine(StringPiece* input, StringPiece* line) {
for (int len = 0; len < input->size(); ++len) {
if (ascii_isnewline((*input)[len])) {
@@ -848,15 +897,6 @@ bool ReadLine(StringPiece* input, StringPiece* line) {
return false; // Ran out of input with no newline.
}
-void TrimWhitespace(StringPiece* input) {
- while (!input->empty() && ascii_isspace(*input->data())) {
- input->remove_prefix(1);
- }
- while (!input->empty() && ascii_isspace((*input)[input->length() - 1])) {
- input->remove_suffix(1);
- }
-}
-
void RemoveComment(StringPiece* input) {
int offset = input->find('#');
if (offset != StringPiece::npos) {
@@ -864,73 +904,55 @@ void RemoveComment(StringPiece* input) {
}
}
-bool Parser::ParseLoop() {
- StringPiece line;
- while (ReadLine(&p_, &line)) {
- ++line_;
- RemoveComment(&line);
- TrimWhitespace(&line);
- if (line.size() == 0) {
- continue; // Blank line.
- }
- int offset = line.find('=');
- if (offset == StringPiece::npos) {
- error_str_ =
- string("Line without equal sign: '") + line.ToString() + "'.";
- return false;
- }
- StringPiece package(line, 0, offset);
- StringPiece prefix(line, offset + 1, line.length() - offset - 1);
- TrimWhitespace(&package);
- TrimWhitespace(&prefix);
- // Don't really worry about error checking the the package/prefix for
- // being valid. Assume the file is validated when it is created/edited.
- (*prefix_map_)[package.ToString()] = prefix.ToString();
+namespace {
+
+class ExpectedPrefixesCollector : public LineConsumer {
+ public:
+ ExpectedPrefixesCollector(map<string, string>* inout_package_to_prefix_map)
+ : prefix_map_(inout_package_to_prefix_map) {}
+
+ virtual bool ConsumeLine(const StringPiece& line, string* out_error);
+
+ private:
+ map<string, string>* prefix_map_;
+};
+
+bool ExpectedPrefixesCollector::ConsumeLine(
+ const StringPiece& line, string* out_error) {
+ int offset = line.find('=');
+ if (offset == StringPiece::npos) {
+ *out_error =
+ string("Expected prefixes file line without equal sign: '") +
+ line.ToString() + "'.";
+ return false;
}
+ StringPiece package(line, 0, offset);
+ StringPiece prefix(line, offset + 1, line.length() - offset - 1);
+ StringPieceTrimWhitespace(&package);
+ StringPieceTrimWhitespace(&prefix);
+ // Don't really worry about error checking the package/prefix for
+ // being valid. Assume the file is validated when it is created/edited.
+ (*prefix_map_)[package.ToString()] = prefix.ToString();
return true;
}
-bool LoadExpectedPackagePrefixes(map<string, string>* prefix_map,
- string* out_expect_file_path,
+bool LoadExpectedPackagePrefixes(const Options &generation_options,
+ map<string, string>* prefix_map,
string* out_error) {
- const char* file_path = getenv("GPB_OBJC_EXPECTED_PACKAGE_PREFIXES");
- if (file_path == NULL) {
+ if (generation_options.expected_prefixes_path.empty()) {
return true;
}
- int fd;
- do {
- fd = open(file_path, O_RDONLY);
- } while (fd < 0 && errno == EINTR);
- if (fd < 0) {
- *out_error =
- string(file_path) + ":0:0: error: Unable to open." + strerror(errno);
- return false;
- }
- io::FileInputStream file_stream(fd);
- file_stream.SetCloseOnDelete(true);
- *out_expect_file_path = file_path;
-
- Parser parser(prefix_map);
- const void* buf;
- int buf_len;
- while (file_stream.Next(&buf, &buf_len)) {
- if (buf_len == 0) {
- continue;
- }
-
- if (!parser.ParseChunk(StringPiece(static_cast<const char*>(buf), buf_len))) {
- *out_error = string(file_path) + ":" + SimpleItoa(parser.last_line()) +
- ":0: error: " + parser.error_str();
- return false;
- }
- }
- return parser.Finish();
+ ExpectedPrefixesCollector collector(prefix_map);
+ return ParseSimpleFile(
+ generation_options.expected_prefixes_path, &collector, out_error);
}
} // namespace
-bool ValidateObjCClassPrefix(const FileDescriptor* file, string* out_error) {
+bool ValidateObjCClassPrefix(const FileDescriptor* file,
+ const Options& generation_options,
+ string* out_error) {
const string prefix = file->options().objc_class_prefix();
const string package = file->package();
@@ -939,11 +961,10 @@ bool ValidateObjCClassPrefix(const FileDescriptor* file, string* out_error) {
// Load any expected package prefixes to validate against those.
map<string, string> expected_package_prefixes;
- string expect_file_path;
- if (!LoadExpectedPackagePrefixes(&expected_package_prefixes,
- &expect_file_path, out_error)) {
- // Any error, clear the entries that were read.
- expected_package_prefixes.clear();
+ if (!LoadExpectedPackagePrefixes(generation_options,
+ &expected_package_prefixes,
+ out_error)) {
+ return false;
}
// Check: Error - See if there was an expected prefix for the package and
@@ -957,8 +978,9 @@ bool ValidateObjCClassPrefix(const FileDescriptor* file, string* out_error) {
return true;
} else {
// ...it didn't match!
- *out_error = "protoc:0: error: Expected 'option objc_class_prefix = \"" +
- package_match->second + "\";' in '" + file->name() + "'";
+ *out_error = "error: Expected 'option objc_class_prefix = \"" +
+ package_match->second + "\";' for package '" + package +
+ "' in '" + file->name() + "'";
if (prefix.length()) {
*out_error += "; but found '" + prefix + "' instead";
}
@@ -980,11 +1002,11 @@ bool ValidateObjCClassPrefix(const FileDescriptor* file, string* out_error) {
i != expected_package_prefixes.end(); ++i) {
if (i->second == prefix) {
*out_error =
- "protoc:0: error: Found 'option objc_class_prefix = \"" + prefix +
+ "error: Found 'option objc_class_prefix = \"" + prefix +
"\";' in '" + file->name() +
"'; that prefix is already used for 'package " + i->first +
";'. It can only be reused by listing it in the expected file (" +
- expect_file_path + ").";
+ generation_options.expected_prefixes_path + ").";
return false; // Only report first usage of the prefix.
}
}
@@ -1017,13 +1039,17 @@ bool ValidateObjCClassPrefix(const FileDescriptor* file, string* out_error) {
<< "protoc:0: warning: Found unexpected 'option objc_class_prefix = \""
<< prefix << "\";' in '" << file->name() << "';"
<< " consider adding it to the expected prefixes file ("
- << expect_file_path << ")." << endl;
+ << generation_options.expected_prefixes_path << ")." << endl;
cerr.flush();
}
return true;
}
+TextFormatDecodeData::TextFormatDecodeData() { }
+
+TextFormatDecodeData::~TextFormatDecodeData() { }
+
void TextFormatDecodeData::AddString(int32 key,
const string& input_for_decode,
const string& desired_output) {
@@ -1232,6 +1258,117 @@ string TextFormatDecodeData::DecodeDataForString(const string& input_for_decode,
return builder.Finish() + (char)'\0';
}
+namespace {
+
+class Parser {
+ public:
+ Parser(LineConsumer* line_consumer)
+ : line_consumer_(line_consumer), line_(0) {}
+
+ // Parses a check of input, returning success/failure.
+ bool ParseChunk(StringPiece chunk);
+
+ // Should be called to finish parsing (after all input has been provided via
+ // ParseChunk()). Returns success/failure.
+ bool Finish();
+
+ int last_line() const { return line_; }
+ string error_str() const { return error_str_; }
+
+ private:
+ bool ParseLoop();
+
+ LineConsumer* line_consumer_;
+ int line_;
+ string error_str_;
+ StringPiece p_;
+ string leftover_;
+};
+
+bool Parser::ParseChunk(StringPiece chunk) {
+ if (!leftover_.empty()) {
+ chunk.AppendToString(&leftover_);
+ p_ = StringPiece(leftover_);
+ } else {
+ p_ = chunk;
+ }
+ bool result = ParseLoop();
+ if (p_.empty()) {
+ leftover_.clear();
+ } else {
+ leftover_ = p_.ToString();
+ }
+ return result;
+}
+
+bool Parser::Finish() {
+ if (leftover_.empty()) {
+ return true;
+ }
+ // Force a newline onto the end to finish parsing.
+ leftover_ += "\n";
+ p_ = StringPiece(leftover_);
+ if (!ParseLoop()) {
+ return false;
+ }
+ return p_.empty(); // Everything used?
+}
+
+bool Parser::ParseLoop() {
+ StringPiece line;
+ while (ReadLine(&p_, &line)) {
+ ++line_;
+ RemoveComment(&line);
+ StringPieceTrimWhitespace(&line);
+ if (line.size() == 0) {
+ continue; // Blank line.
+ }
+ if (!line_consumer_->ConsumeLine(line, &error_str_)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+} // namespace
+
+LineConsumer::LineConsumer() {}
+
+LineConsumer::~LineConsumer() {}
+
+bool ParseSimpleFile(
+ const string& path, LineConsumer* line_consumer, string* out_error) {
+ int fd;
+ do {
+ fd = open(path.c_str(), O_RDONLY);
+ } while (fd < 0 && errno == EINTR);
+ if (fd < 0) {
+ *out_error =
+ string("error: Unable to open \"") + path + "\", " + strerror(errno);
+ return false;
+ }
+ io::FileInputStream file_stream(fd);
+ file_stream.SetCloseOnDelete(true);
+
+ Parser parser(line_consumer);
+ const void* buf;
+ int buf_len;
+ while (file_stream.Next(&buf, &buf_len)) {
+ if (buf_len == 0) {
+ continue;
+ }
+
+ if (!parser.ParseChunk(StringPiece(static_cast<const char*>(buf), buf_len))) {
+ *out_error =
+ string("error: ") + path +
+ " Line " + SimpleItoa(parser.last_line()) + ", " + parser.error_str();
+ return false;
+ }
+ }
+ return parser.Finish();
+}
+
+
} // namespace objectivec
} // namespace compiler
} // namespace protobuf
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers.h b/src/google/protobuf/compiler/objectivec/objectivec_helpers.h
index 072a2e57..be20beee 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_helpers.h
+++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers.h
@@ -42,9 +42,23 @@ namespace protobuf {
namespace compiler {
namespace objectivec {
+// Generator options (see objectivec_generator.cc for a description of each):
+struct Options {
+ Options();
+ string expected_prefixes_path;
+ string generate_for_named_framework;
+ string named_framework_to_proto_path_mappings_path;
+};
+
+// Escape C++ trigraphs by escaping question marks to "\?".
+string EscapeTrigraphs(const string& to_escape);
+
// Strips ".proto" or ".protodevel" from the end of a filename.
string StripProto(const string& filename);
+// Remove white space from either end of a StringPiece.
+void StringPieceTrimWhitespace(StringPiece* input);
+
// Returns true if the name requires a ns_returns_not_retained attribute applied
// to it.
bool IsRetainedName(const string& name);
@@ -53,18 +67,17 @@ bool IsRetainedName(const string& name);
// handling under ARC.
bool IsInitName(const string& name);
-// Gets the name of the file we're going to generate (sans the .pb.h
-// extension). This does not include the path to that file.
-string FileName(const FileDescriptor* file);
-
// Gets the path of the file we're going to generate (sans the .pb.h
// extension). The path will be dependent on the objectivec package
// declared in the proto package.
string FilePath(const FileDescriptor* file);
+// Just like FilePath(), but without the directory part.
+string FilePathBasename(const FileDescriptor* file);
+
// Gets the name of the root class we'll generate in the file. This class
// is not meant for external consumption, but instead contains helpers that
-// the rest of the the classes need
+// the rest of the classes need
string FileClassName(const FileDescriptor* file);
// These return the fully-qualified class name corresponding to the given
@@ -124,6 +137,22 @@ enum ObjectiveCType {
OBJECTIVECTYPE_MESSAGE
};
+template<class TDescriptor>
+string GetOptionalDeprecatedAttribute(const TDescriptor* descriptor, bool preSpace = true, bool postNewline = false) {
+ if (descriptor->options().deprecated()) {
+ string result = "DEPRECATED_ATTRIBUTE";
+ if (preSpace) {
+ result.insert(0, " ");
+ }
+ if (postNewline) {
+ result.append("\n");
+ }
+ return result;
+ } else {
+ return "";
+ }
+}
+
string GetCapitalizedType(const FieldDescriptor* field);
ObjectiveCType GetObjectiveCType(FieldDescriptor::Type field_type);
@@ -137,21 +166,36 @@ bool IsReferenceType(const FieldDescriptor* field);
string GPBGenericValueFieldName(const FieldDescriptor* field);
string DefaultValue(const FieldDescriptor* field);
+bool HasNonZeroDefaultValue(const FieldDescriptor* field);
string BuildFlagsString(const vector<string>& strings);
+// Builds a HeaderDoc style comment out of the comments in the .proto file.
string BuildCommentsString(const SourceLocation& location);
+// The name the commonly used by the library when built as a framework.
+// This lines up to the name used in the CocoaPod.
+extern const char* const ProtobufLibraryFrameworkName;
+// Returns the CPP symbol name to use as the gate for framework style imports
+// for the given framework name to use.
+string ProtobufFrameworkImportSymbol(const string& framework_name);
+
+// Checks if the file is one of the proto's bundled with the library.
+bool IsProtobufLibraryBundledProtoFile(const FileDescriptor* file);
+
// Checks the prefix for a given file and outputs any warnings needed, if
// there are flat out errors, then out_error is filled in and the result is
// false.
-bool ValidateObjCClassPrefix(const FileDescriptor* file, string *out_error);
+bool ValidateObjCClassPrefix(const FileDescriptor* file,
+ const Options& generation_options,
+ string* out_error);
// Generate decode data needed for ObjC's GPBDecodeTextFormatName() to transform
-// the input into the the expected output.
+// the input into the expected output.
class LIBPROTOC_EXPORT TextFormatDecodeData {
public:
- TextFormatDecodeData() {}
+ TextFormatDecodeData();
+ ~TextFormatDecodeData();
void AddString(int32 key, const string& input_for_decode,
const string& desired_output);
@@ -168,6 +212,17 @@ class LIBPROTOC_EXPORT TextFormatDecodeData {
vector<DataEntry> entries_;
};
+// Helper for parsing simple files.
+class LIBPROTOC_EXPORT LineConsumer {
+ public:
+ LineConsumer();
+ virtual ~LineConsumer();
+ virtual bool ConsumeLine(const StringPiece& line, string* out_error) = 0;
+};
+
+bool ParseSimpleFile(
+ const string& path, LineConsumer* line_consumer, string* out_error);
+
} // namespace objectivec
} // namespace compiler
} // namespace protobuf
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc
index 2987f3db..ac5d8aea 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc
@@ -84,13 +84,14 @@ const char* MapEntryTypeName(const FieldDescriptor* descriptor, bool isKey) {
} // namespace
-MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor)
- : RepeatedFieldGenerator(descriptor) {
+MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
+ : RepeatedFieldGenerator(descriptor, options) {
const FieldDescriptor* key_descriptor =
descriptor->message_type()->FindFieldByName("key");
const FieldDescriptor* value_descriptor =
descriptor->message_type()->FindFieldByName("value");
- value_field_generator_.reset(FieldGenerator::Make(value_descriptor));
+ value_field_generator_.reset(FieldGenerator::Make(value_descriptor, options));
// Pull over some variables_ from the value.
variables_["field_type"] = value_field_generator_->variable("field_type");
@@ -117,46 +118,62 @@ MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor)
variables_["fieldflags"] = BuildFlagsString(field_flags);
ObjectiveCType value_objc_type = GetObjectiveCType(value_descriptor);
- if ((GetObjectiveCType(key_descriptor) == OBJECTIVECTYPE_STRING) &&
+ const bool value_is_object_type =
((value_objc_type == OBJECTIVECTYPE_STRING) ||
(value_objc_type == OBJECTIVECTYPE_DATA) ||
- (value_objc_type == OBJECTIVECTYPE_MESSAGE))) {
+ (value_objc_type == OBJECTIVECTYPE_MESSAGE));
+ if ((GetObjectiveCType(key_descriptor) == OBJECTIVECTYPE_STRING) &&
+ value_is_object_type) {
variables_["array_storage_type"] = "NSMutableDictionary";
+ variables_["array_property_type"] =
+ "NSMutableDictionary<NSString*, " +
+ value_field_generator_->variable("storage_type") + "*>";
} else {
- string base_name = MapEntryTypeName(key_descriptor, true);
- base_name += MapEntryTypeName(value_descriptor, false);
- base_name += "Dictionary";
- variables_["array_storage_type"] = "GPB" + base_name;
+ string class_name("GPB");
+ class_name += MapEntryTypeName(key_descriptor, true);
+ class_name += MapEntryTypeName(value_descriptor, false);
+ class_name += "Dictionary";
+ variables_["array_storage_type"] = class_name;
+ if (value_is_object_type) {
+ variables_["array_property_type"] =
+ class_name + "<" +
+ value_field_generator_->variable("storage_type") + "*>";
+ }
}
+
+ variables_["dataTypeSpecific_name"] =
+ value_field_generator_->variable("dataTypeSpecific_name");
+ variables_["dataTypeSpecific_value"] =
+ value_field_generator_->variable("dataTypeSpecific_value");
}
MapFieldGenerator::~MapFieldGenerator() {}
void MapFieldGenerator::FinishInitialization(void) {
RepeatedFieldGenerator::FinishInitialization();
- // Use the array_comment suport in RepeatedFieldGenerator to output what the
+ // Use the array_comment support in RepeatedFieldGenerator to output what the
// values in the map are.
const FieldDescriptor* value_descriptor =
descriptor_->message_type()->FindFieldByName("value");
- ObjectiveCType value_objc_type = GetObjectiveCType(value_descriptor);
- if ((value_objc_type == OBJECTIVECTYPE_MESSAGE) ||
- (value_objc_type == OBJECTIVECTYPE_DATA) ||
- (value_objc_type == OBJECTIVECTYPE_STRING) ||
- (value_objc_type == OBJECTIVECTYPE_ENUM)) {
+ if (GetObjectiveCType(value_descriptor) == OBJECTIVECTYPE_ENUM) {
variables_["array_comment"] =
"// |" + variables_["name"] + "| values are |" + value_field_generator_->variable("storage_type") + "|\n";
- } else {
- variables_["array_comment"] = "";
}
}
-void MapFieldGenerator::GenerateFieldDescriptionTypeSpecific(
- io::Printer* printer) const {
- // Relay it to the value generator to provide enum validator, message
- // class, etc.
- value_field_generator_->GenerateFieldDescriptionTypeSpecific(printer);
+void MapFieldGenerator::DetermineForwardDeclarations(
+ set<string>* fwd_decls) const {
+ RepeatedFieldGenerator::DetermineForwardDeclarations(fwd_decls);
+ const FieldDescriptor* value_descriptor =
+ descriptor_->message_type()->FindFieldByName("value");
+ if (GetObjectiveCType(value_descriptor) == OBJECTIVECTYPE_MESSAGE) {
+ const string& value_storage_type =
+ value_field_generator_->variable("storage_type");
+ fwd_decls->insert("@class " + value_storage_type);
+ }
}
+
} // namespace objectivec
} // namespace compiler
} // namespace protobuf
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_map_field.h b/src/google/protobuf/compiler/objectivec/objectivec_map_field.h
index 173541f2..bc68a682 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_map_field.h
+++ b/src/google/protobuf/compiler/objectivec/objectivec_map_field.h
@@ -41,18 +41,21 @@ namespace compiler {
namespace objectivec {
class MapFieldGenerator : public RepeatedFieldGenerator {
- friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field);
+ friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field,
+ const Options& options);
public:
virtual void FinishInitialization(void);
- virtual void GenerateFieldDescriptionTypeSpecific(io::Printer* printer) const;
protected:
- explicit MapFieldGenerator(const FieldDescriptor* descriptor);
+ MapFieldGenerator(const FieldDescriptor* descriptor, const Options& options);
virtual ~MapFieldGenerator();
+ virtual void DetermineForwardDeclarations(set<string>* fwd_decls) const;
+
private:
scoped_ptr<FieldGenerator> value_field_generator_;
+
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapFieldGenerator);
};
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_message.cc b/src/google/protobuf/compiler/objectivec/objectivec_message.cc
index 32671d42..e1a78619 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_message.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_message.cc
@@ -66,11 +66,12 @@ int OrderGroupForFieldDescriptor(const FieldDescriptor* descriptor) {
// The first item in the object structure is our uint32[] for has bits.
// We then want to order things to make the instances as small as
// possible. So we follow the has bits with:
- // 1. Bools (1 byte)
- // 2. Anything always 4 bytes - float, *32, enums
- // 3. Anything that is always a pointer (they will be 8 bytes on 64 bit
+ // 1. Anything always 4 bytes - float, *32, enums
+ // 2. Anything that is always a pointer (they will be 8 bytes on 64 bit
// builds and 4 bytes on 32bit builds.
- // 4. Anything always 8 bytes - double, *64
+ // 3. Anything always 8 bytes - double, *64
+ //
+ // NOTE: Bools aren't listed, they were stored in the has bits.
//
// Why? Using 64bit builds as an example, this means worse case, we have
// enough bools that we overflow 1 byte from 4 byte alignment, so 3 bytes
@@ -115,9 +116,9 @@ int OrderGroupForFieldDescriptor(const FieldDescriptor* descriptor) {
case FieldDescriptor::TYPE_ENUM:
return 2;
- // 1 byte.
+ // 0 bytes. Stored in the has bits.
case FieldDescriptor::TYPE_BOOL:
- return 1;
+ return 99; // End of the list (doesn't really matter).
}
// Some compilers report reaching end of function even though all cases of
@@ -174,10 +175,11 @@ const FieldDescriptor** SortFieldsByStorageSize(const Descriptor* descriptor) {
} // namespace
MessageGenerator::MessageGenerator(const string& root_classname,
- const Descriptor* descriptor)
+ const Descriptor* descriptor,
+ const Options& options)
: root_classname_(root_classname),
descriptor_(descriptor),
- field_generators_(descriptor),
+ field_generators_(descriptor, options),
class_name_(ClassName(descriptor_)) {
for (int i = 0; i < descriptor_->extension_count(); i++) {
extension_generators_.push_back(
@@ -196,7 +198,9 @@ MessageGenerator::MessageGenerator(const string& root_classname,
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
MessageGenerator* generator =
- new MessageGenerator(root_classname_, descriptor_->nested_type(i));
+ new MessageGenerator(root_classname_,
+ descriptor_->nested_type(i),
+ options);
nested_message_generators_.push_back(generator);
}
}
@@ -230,11 +234,6 @@ void MessageGenerator::DetermineForwardDeclarations(set<string>* fwd_decls) {
if (!IsMapEntryMessage(descriptor_)) {
for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor* fieldDescriptor = descriptor_->field(i);
- // If it is a the field is repeated, the type will be and *Array, and we
- // don't need any forward decl.
- if (fieldDescriptor->is_repeated()) {
- continue;
- }
field_generators_.get(fieldDescriptor)
.DetermineForwardDeclarations(fwd_decls);
}
@@ -247,6 +246,22 @@ void MessageGenerator::DetermineForwardDeclarations(set<string>* fwd_decls) {
}
}
+bool MessageGenerator::IncludesOneOfDefinition() const {
+ if (!oneof_generators_.empty()) {
+ return true;
+ }
+
+ for (vector<MessageGenerator*>::const_iterator iter =
+ nested_message_generators_.begin();
+ iter != nested_message_generators_.end(); ++iter) {
+ if ((*iter)->IncludesOneOfDefinition()) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
void MessageGenerator::GenerateEnumHeader(io::Printer* printer) {
for (vector<EnumGenerator*>::iterator iter = enum_generators_.begin();
iter != enum_generators_.end(); ++iter) {
@@ -322,8 +337,9 @@ void MessageGenerator::GenerateMessageHeader(io::Printer* printer) {
}
printer->Print(
- "$comments$@interface $classname$ : GPBMessage\n\n",
+ "$comments$$deprecated_attribute$@interface $classname$ : GPBMessage\n\n",
"classname", class_name_,
+ "deprecated_attribute", GetOptionalDeprecatedAttribute(descriptor_, false, true),
"comments", message_comments);
vector<char> seen_oneofs(descriptor_->oneof_decl_count(), 0);
@@ -406,32 +422,28 @@ void MessageGenerator::GenerateSource(io::Printer* printer) {
sort(sorted_extensions.begin(), sorted_extensions.end(),
ExtensionRangeOrdering());
- // TODO(thomasvl): Finish optimizing has bit. The current behavior is as
- // follows:
- // 1. objectivec_field.cc's SetCommonFieldVariables() defaults the has_index
- // to the field's index in the list of fields.
- // 2. RepeatedFieldGenerator::RepeatedFieldGenerator() sets has_index to
- // GPBNoHasBit because repeated fields & map<> fields don't use the has
- // bit.
- // 3. FieldGenerator::SetOneofIndexBase() overrides has_bit with a negative
- // index that groups all the elements on of the oneof.
- // So in has_storage, we need enough bits for the single fields that aren't
- // in any oneof, and then one int32 for each oneof (to store the field
- // number). So we could save a little space by not using the field's index
- // and instead make a second pass only assigning indexes for the fields
- // that would need it. The only savings would come when messages have over
- // a multiple of 32 fields with some number being repeated or in oneofs to
- // drop the count below that 32 multiple; so it hasn't seemed worth doing
- // at the moment.
- size_t num_has_bits = descriptor_->field_count();
+ // Assign has bits:
+ // 1. FieldGeneratorMap::CalculateHasBits() loops through the fields seeing
+ // who needs has bits and assigning them.
+ // 2. FieldGenerator::SetOneofIndexBase() overrides has_bit with a negative
+ // index that groups all the elements in the oneof.
+ size_t num_has_bits = field_generators_.CalculateHasBits();
size_t sizeof_has_storage = (num_has_bits + 31) / 32;
+ if (sizeof_has_storage == 0) {
+ // In the case where no field needs has bits, don't let the _has_storage_
+ // end up as zero length (zero length arrays are sort of a grey area
+ // since it has to be at the start of the struct). This also ensures a
+ // field with only oneofs keeps the required negative indices they need.
+ sizeof_has_storage = 1;
+ }
// Tell all the fields the oneof base.
for (vector<OneofGenerator*>::iterator iter = oneof_generators_.begin();
iter != oneof_generators_.end(); ++iter) {
(*iter)->SetOneofIndexBase(sizeof_has_storage);
}
field_generators_.SetOneofIndexBase(sizeof_has_storage);
- // Add an int32 for each oneof to store which is set.
+ // sizeof_has_storage needs enough bits for the single fields that aren't in
+ // any oneof, and then one int32 for each oneof (to store the field number).
sizeof_has_storage += descriptor_->oneof_decl_count();
printer->Print(
@@ -458,47 +470,26 @@ void MessageGenerator::GenerateSource(io::Printer* printer) {
" static GPBDescriptor *descriptor = nil;\n"
" if (!descriptor) {\n");
- bool has_oneofs = oneof_generators_.size();
- if (has_oneofs) {
- printer->Print(
- " static GPBMessageOneofDescription oneofs[] = {\n");
- printer->Indent();
- printer->Indent();
- printer->Indent();
- for (vector<OneofGenerator*>::iterator iter = oneof_generators_.begin();
- iter != oneof_generators_.end(); ++iter) {
- (*iter)->GenerateDescription(printer);
- }
- printer->Outdent();
- printer->Outdent();
- printer->Outdent();
- printer->Print(
- " };\n");
- }
-
TextFormatDecodeData text_format_decode_data;
bool has_fields = descriptor_->field_count() > 0;
+ bool need_defaults = field_generators_.DoesAnyFieldHaveNonZeroDefault();
+ string field_description_type;
+ if (need_defaults) {
+ field_description_type = "GPBMessageFieldDescriptionWithDefault";
+ } else {
+ field_description_type = "GPBMessageFieldDescription";
+ }
if (has_fields) {
- // TODO(thomasvl): The plugin's FieldGenerator::GenerateFieldDescription()
- // wraps the fieldOptions's value of this structure in an CPP gate so
- // they can be compiled away; but that still results in a const char* in
- // the structure for a NULL pointer for every message field. If the
- // fieldOptions are moved to a separate payload like the TextFormat extra
- // data is, then it would shrink that static data shrinking the binaries
- // a little more.
- // TODO(thomasvl): proto3 syntax doens't need a defaultValue in the
- // structure because primitive types are always zero. If we add a second
- // structure and a different initializer, we can avoid the wasted static
- // storage for every field in a proto3 message.
printer->Print(
- " static GPBMessageFieldDescription fields[] = {\n");
+ " static $field_description_type$ fields[] = {\n",
+ "field_description_type", field_description_type);
printer->Indent();
printer->Indent();
printer->Indent();
for (int i = 0; i < descriptor_->field_count(); ++i) {
const FieldGenerator& field_generator =
field_generators_.get(sorted_fields[i]);
- field_generator.GenerateFieldDescription(printer);
+ field_generator.GenerateFieldDescription(printer, need_defaults);
if (field_generator.needs_textformat_name_support()) {
text_format_decode_data.AddString(sorted_fields[i]->number(),
field_generator.generated_objc_name(),
@@ -512,111 +503,89 @@ void MessageGenerator::GenerateSource(io::Printer* printer) {
" };\n");
}
- bool has_enums = enum_generators_.size();
- if (has_enums) {
+ map<string, string> vars;
+ vars["classname"] = class_name_;
+ vars["rootclassname"] = root_classname_;
+ vars["fields"] = has_fields ? "fields" : "NULL";
+ if (has_fields) {
+ vars["fields_count"] =
+ "(uint32_t)(sizeof(fields) / sizeof(" + field_description_type + "))";
+ } else {
+ vars["fields_count"] = "0";
+ }
+
+ std::vector<string> init_flags;
+ if (need_defaults) {
+ init_flags.push_back("GPBDescriptorInitializationFlag_FieldsWithDefault");
+ }
+ if (descriptor_->options().message_set_wire_format()) {
+ init_flags.push_back("GPBDescriptorInitializationFlag_WireFormat");
+ }
+ vars["init_flags"] = BuildFlagsString(init_flags);
+
+ printer->Print(
+ vars,
+ " GPBDescriptor *localDescriptor =\n"
+ " [GPBDescriptor allocDescriptorForClass:[$classname$ class]\n"
+ " rootClass:[$rootclassname$ class]\n"
+ " file:$rootclassname$_FileDescriptor()\n"
+ " fields:$fields$\n"
+ " fieldCount:$fields_count$\n"
+ " storageSize:sizeof($classname$__storage_)\n"
+ " flags:$init_flags$];\n");
+ if (oneof_generators_.size() != 0) {
printer->Print(
- " static GPBMessageEnumDescription enums[] = {\n");
- printer->Indent();
- printer->Indent();
- printer->Indent();
- for (vector<EnumGenerator*>::iterator iter = enum_generators_.begin();
- iter != enum_generators_.end(); ++iter) {
- printer->Print("{ .enumDescriptorFunc = $name$_EnumDescriptor },\n",
- "name", (*iter)->name());
+ " static const char *oneofs[] = {\n");
+ for (vector<OneofGenerator*>::iterator iter = oneof_generators_.begin();
+ iter != oneof_generators_.end(); ++iter) {
+ printer->Print(
+ " \"$name$\",\n",
+ "name", (*iter)->DescriptorName());
}
- printer->Outdent();
- printer->Outdent();
- printer->Outdent();
printer->Print(
- " };\n");
+ " };\n"
+ " [localDescriptor setupOneofs:oneofs\n"
+ " count:(uint32_t)(sizeof(oneofs) / sizeof(char*))\n"
+ " firstHasIndex:$first_has_index$];\n",
+ "first_has_index", oneof_generators_[0]->HasIndexAsString());
}
-
- bool has_extensions = sorted_extensions.size();
- if (has_extensions) {
+ if (text_format_decode_data.num_entries() != 0) {
+ const string text_format_data_str(text_format_decode_data.Data());
printer->Print(
- " static GPBExtensionRange ranges[] = {\n");
- printer->Indent();
- printer->Indent();
- printer->Indent();
- for (int i = 0; i < sorted_extensions.size(); i++) {
- printer->Print("{ .start = $start$, .end = $end$ },\n",
- "start", SimpleItoa(sorted_extensions[i]->start),
- "end", SimpleItoa(sorted_extensions[i]->end));
+ "#if !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS\n"
+ " static const char *extraTextFormatInfo =");
+ static const int kBytesPerLine = 40; // allow for escaping
+ for (int i = 0; i < text_format_data_str.size(); i += kBytesPerLine) {
+ printer->Print(
+ "\n \"$data$\"",
+ "data", EscapeTrigraphs(
+ CEscape(text_format_data_str.substr(i, kBytesPerLine))));
}
- printer->Outdent();
- printer->Outdent();
- printer->Outdent();
printer->Print(
- " };\n");
+ ";\n"
+ " [localDescriptor setupExtraTextInfo:extraTextFormatInfo];\n"
+ "#endif // !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS\n");
}
-
- map<string, string> vars;
- vars["classname"] = class_name_;
- vars["rootclassname"] = root_classname_;
- vars["fields"] = has_fields ? "fields" : "NULL";
- vars["fields_count"] =
- has_fields ? "sizeof(fields) / sizeof(GPBMessageFieldDescription)" : "0";
- vars["oneofs"] = has_oneofs ? "oneofs" : "NULL";
- vars["oneof_count"] =
- has_oneofs ? "sizeof(oneofs) / sizeof(GPBMessageOneofDescription)" : "0";
- vars["enums"] = has_enums ? "enums" : "NULL";
- vars["enum_count"] =
- has_enums ? "sizeof(enums) / sizeof(GPBMessageEnumDescription)" : "0";
- vars["ranges"] = has_extensions ? "ranges" : "NULL";
- vars["range_count"] =
- has_extensions ? "sizeof(ranges) / sizeof(GPBExtensionRange)" : "0";
- vars["wireformat"] =
- descriptor_->options().message_set_wire_format() ? "YES" : "NO";
-
- if (text_format_decode_data.num_entries() == 0) {
+ if (sorted_extensions.size() != 0) {
printer->Print(
- vars,
- " GPBDescriptor *localDescriptor =\n"
- " [GPBDescriptor allocDescriptorForClass:[$classname$ class]\n"
- " rootClass:[$rootclassname$ class]\n"
- " file:$rootclassname$_FileDescriptor()\n"
- " fields:$fields$\n"
- " fieldCount:$fields_count$\n"
- " oneofs:$oneofs$\n"
- " oneofCount:$oneof_count$\n"
- " enums:$enums$\n"
- " enumCount:$enum_count$\n"
- " ranges:$ranges$\n"
- " rangeCount:$range_count$\n"
- " storageSize:sizeof($classname$__storage_)\n"
- " wireFormat:$wireformat$];\n");
- } else {
- vars["extraTextFormatInfo"] = CEscape(text_format_decode_data.Data());
- printer->Print(
- vars,
- "#if GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS\n"
- " const char *extraTextFormatInfo = NULL;\n"
- "#else\n"
- " static const char *extraTextFormatInfo = \"$extraTextFormatInfo$\";\n"
- "#endif // GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS\n"
- " GPBDescriptor *localDescriptor =\n"
- " [GPBDescriptor allocDescriptorForClass:[$classname$ class]\n"
- " rootClass:[$rootclassname$ class]\n"
- " file:$rootclassname$_FileDescriptor()\n"
- " fields:$fields$\n"
- " fieldCount:$fields_count$\n"
- " oneofs:$oneofs$\n"
- " oneofCount:$oneof_count$\n"
- " enums:$enums$\n"
- " enumCount:$enum_count$\n"
- " ranges:$ranges$\n"
- " rangeCount:$range_count$\n"
- " storageSize:sizeof($classname$__storage_)\n"
- " wireFormat:$wireformat$\n"
- " extraTextFormatInfo:extraTextFormatInfo];\n");
+ " static const GPBExtensionRange ranges[] = {\n");
+ for (int i = 0; i < sorted_extensions.size(); i++) {
+ printer->Print(" { .start = $start$, .end = $end$ },\n",
+ "start", SimpleItoa(sorted_extensions[i]->start),
+ "end", SimpleItoa(sorted_extensions[i]->end));
}
printer->Print(
- " NSAssert(descriptor == nil, @\"Startup recursed!\");\n"
- " descriptor = localDescriptor;\n"
- " }\n"
- " return descriptor;\n"
- "}\n\n"
- "@end\n\n");
+ " };\n"
+ " [localDescriptor setupExtensionRanges:ranges\n"
+ " count:(uint32_t)(sizeof(ranges) / sizeof(GPBExtensionRange))];\n");
+ }
+ printer->Print(
+ " NSAssert(descriptor == nil, @\"Startup recursed!\");\n"
+ " descriptor = localDescriptor;\n"
+ " }\n"
+ " return descriptor;\n"
+ "}\n\n"
+ "@end\n\n");
for (int i = 0; i < descriptor_->field_count(); i++) {
field_generators_.get(descriptor_->field(i))
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_message.h b/src/google/protobuf/compiler/objectivec/objectivec_message.h
index 06b536ff..910535ac 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_message.h
+++ b/src/google/protobuf/compiler/objectivec/objectivec_message.h
@@ -54,7 +54,9 @@ class EnumGenerator;
class MessageGenerator {
public:
- MessageGenerator(const string& root_classname, const Descriptor* descriptor);
+ MessageGenerator(const string& root_classname,
+ const Descriptor* descriptor,
+ const Options& options);
~MessageGenerator();
void GenerateStaticVariablesInitialization(io::Printer* printer);
@@ -64,6 +66,9 @@ class MessageGenerator {
void GenerateExtensionRegistrationSource(io::Printer* printer);
void DetermineForwardDeclarations(set<string>* fwd_decls);
+ // Checks if the message or a nested message includes a oneof definition.
+ bool IncludesOneOfDefinition() const;
+
private:
void GenerateParseFromMethodsHeader(io::Printer* printer);
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc
index f2ce4e5b..d6ccd6d1 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc
@@ -58,8 +58,9 @@ void SetMessageVariables(const FieldDescriptor* descriptor,
} // namespace
-MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor)
- : ObjCObjFieldGenerator(descriptor) {
+MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
+ : ObjCObjFieldGenerator(descriptor, options) {
SetMessageVariables(descriptor, &variables_);
}
@@ -67,6 +68,7 @@ MessageFieldGenerator::~MessageFieldGenerator() {}
void MessageFieldGenerator::DetermineForwardDeclarations(
set<string>* fwd_decls) const {
+ ObjCObjFieldGenerator::DetermineForwardDeclarations(fwd_decls);
// Class name is already in "storage_type".
fwd_decls->insert("@class " + variable("storage_type"));
}
@@ -82,14 +84,24 @@ bool MessageFieldGenerator::WantsHasProperty(void) const {
}
RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator(
- const FieldDescriptor* descriptor)
- : RepeatedFieldGenerator(descriptor) {
+ const FieldDescriptor* descriptor, const Options& options)
+ : RepeatedFieldGenerator(descriptor, options) {
SetMessageVariables(descriptor, &variables_);
variables_["array_storage_type"] = "NSMutableArray";
+ variables_["array_property_type"] =
+ "NSMutableArray<" + variables_["storage_type"] + "*>";
}
RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {}
+void RepeatedMessageFieldGenerator::DetermineForwardDeclarations(
+ set<string>* fwd_decls) const {
+ RepeatedFieldGenerator::DetermineForwardDeclarations(fwd_decls);
+ // Class name is already in "storage_type".
+ fwd_decls->insert("@class " + variable("storage_type"));
+}
+
+
} // namespace objectivec
} // namespace compiler
} // namespace protobuf
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_message_field.h b/src/google/protobuf/compiler/objectivec/objectivec_message_field.h
index 708ea566..d2dba153 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_message_field.h
+++ b/src/google/protobuf/compiler/objectivec/objectivec_message_field.h
@@ -41,10 +41,12 @@ namespace compiler {
namespace objectivec {
class MessageFieldGenerator : public ObjCObjFieldGenerator {
- friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field);
+ friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field,
+ const Options& options);
protected:
- explicit MessageFieldGenerator(const FieldDescriptor* descriptor);
+ MessageFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
virtual ~MessageFieldGenerator();
virtual bool WantsHasProperty(void) const;
@@ -56,12 +58,17 @@ class MessageFieldGenerator : public ObjCObjFieldGenerator {
};
class RepeatedMessageFieldGenerator : public RepeatedFieldGenerator {
- friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field);
+ friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field,
+ const Options& options);
protected:
- explicit RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor);
+ RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
virtual ~RepeatedMessageFieldGenerator();
+ public:
+ virtual void DetermineForwardDeclarations(set<string>* fwd_decls) const;
+
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedMessageFieldGenerator);
};
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_oneof.cc b/src/google/protobuf/compiler/objectivec/objectivec_oneof.cc
index 3cb87482..3dda903b 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_oneof.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_oneof.cc
@@ -104,6 +104,7 @@ void OneofGenerator::GeneratePublicCasePropertyDeclaration(
void OneofGenerator::GenerateClearFunctionDeclaration(io::Printer* printer) {
printer->Print(
variables_,
+ "/// Clears whatever value was set for the oneof '$name$'.\n"
"void $owning_message_class$_Clear$capitalized_name$OneOfCase($owning_message_class$ *message);\n");
}
@@ -118,18 +119,17 @@ void OneofGenerator::GenerateClearFunctionImplementation(io::Printer* printer) {
variables_,
"void $owning_message_class$_Clear$capitalized_name$OneOfCase($owning_message_class$ *message) {\n"
" GPBDescriptor *descriptor = [message descriptor];\n"
- " GPBOneofDescriptor *oneof = descriptor->oneofs_[$raw_index$];\n"
- " GPBMaybeClearOneof(message, oneof, 0);\n"
+ " GPBOneofDescriptor *oneof = [descriptor.oneofs objectAtIndex:$raw_index$];\n"
+ " GPBMaybeClearOneof(message, oneof, $index$, 0);\n"
"}\n");
}
-void OneofGenerator::GenerateDescription(io::Printer* printer) {
- printer->Print(
- variables_,
- "{\n"
- " .name = \"$name$\",\n"
- " .index = $index$,\n"
- "},\n");
+string OneofGenerator::DescriptorName(void) const {
+ return variables_.find("name")->second;
+}
+
+string OneofGenerator::HasIndexAsString(void) const {
+ return variables_.find("index")->second;
}
} // namespace objectivec
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_oneof.h b/src/google/protobuf/compiler/objectivec/objectivec_oneof.h
index bcba82da..3d9df4db 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_oneof.h
+++ b/src/google/protobuf/compiler/objectivec/objectivec_oneof.h
@@ -61,7 +61,9 @@ class OneofGenerator {
void GeneratePropertyImplementation(io::Printer* printer);
void GenerateClearFunctionImplementation(io::Printer* printer);
- void GenerateDescription(io::Printer* printer);
+
+ string DescriptorName(void) const;
+ string HasIndexAsString(void) const;
private:
const OneofDescriptor* descriptor_;
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc
index c185b66d..d49350f4 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc
@@ -74,7 +74,7 @@ const char* PrimitiveTypeName(const FieldDescriptor* descriptor) {
case OBJECTIVECTYPE_ENUM:
return "int32_t";
case OBJECTIVECTYPE_MESSAGE:
- return NULL;
+ return NULL; // Messages go through objectivec_message_field.cc|h.
}
// Some compilers report reaching end of function even though all cases of
@@ -107,7 +107,8 @@ const char* PrimitiveArrayTypeName(const FieldDescriptor* descriptor) {
case OBJECTIVECTYPE_ENUM:
return "Enum";
case OBJECTIVECTYPE_MESSAGE:
- return ""; // Want NSArray
+ // Want NSArray (but goes through objectivec_message_field.cc|h).
+ return "";
}
// Some compilers report reaching end of function even though all cases of
@@ -126,16 +127,42 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
} // namespace
PrimitiveFieldGenerator::PrimitiveFieldGenerator(
- const FieldDescriptor* descriptor)
- : SingleFieldGenerator(descriptor) {
+ const FieldDescriptor* descriptor, const Options& options)
+ : SingleFieldGenerator(descriptor, options) {
SetPrimitiveVariables(descriptor, &variables_);
}
PrimitiveFieldGenerator::~PrimitiveFieldGenerator() {}
+void PrimitiveFieldGenerator::GenerateFieldStorageDeclaration(
+ io::Printer* printer) const {
+ if (GetObjectiveCType(descriptor_) == OBJECTIVECTYPE_BOOLEAN) {
+ // Nothing, BOOLs are stored in the has bits.
+ } else {
+ SingleFieldGenerator::GenerateFieldStorageDeclaration(printer);
+ }
+}
+
+int PrimitiveFieldGenerator::ExtraRuntimeHasBitsNeeded(void) const {
+ if (GetObjectiveCType(descriptor_) == OBJECTIVECTYPE_BOOLEAN) {
+ // Reserve a bit for the storage of the boolean.
+ return 1;
+ }
+ return 0;
+}
+
+void PrimitiveFieldGenerator::SetExtraRuntimeHasBitsBase(int has_base) {
+ if (GetObjectiveCType(descriptor_) == OBJECTIVECTYPE_BOOLEAN) {
+ // Set into the offset the has bit to use for the actual value.
+ variables_["storage_offset_value"] = SimpleItoa(has_base);
+ variables_["storage_offset_comment"] =
+ " // Stored in _has_storage_ to save space.";
+ }
+}
+
PrimitiveObjFieldGenerator::PrimitiveObjFieldGenerator(
- const FieldDescriptor* descriptor)
- : ObjCObjFieldGenerator(descriptor) {
+ const FieldDescriptor* descriptor, const Options& options)
+ : ObjCObjFieldGenerator(descriptor, options) {
SetPrimitiveVariables(descriptor, &variables_);
variables_["property_storage_attribute"] = "copy";
}
@@ -143,8 +170,8 @@ PrimitiveObjFieldGenerator::PrimitiveObjFieldGenerator(
PrimitiveObjFieldGenerator::~PrimitiveObjFieldGenerator() {}
RepeatedPrimitiveFieldGenerator::RepeatedPrimitiveFieldGenerator(
- const FieldDescriptor* descriptor)
- : RepeatedFieldGenerator(descriptor) {
+ const FieldDescriptor* descriptor, const Options& options)
+ : RepeatedFieldGenerator(descriptor, options) {
SetPrimitiveVariables(descriptor, &variables_);
string base_name = PrimitiveArrayTypeName(descriptor);
@@ -152,19 +179,13 @@ RepeatedPrimitiveFieldGenerator::RepeatedPrimitiveFieldGenerator(
variables_["array_storage_type"] = "GPB" + base_name + "Array";
} else {
variables_["array_storage_type"] = "NSMutableArray";
+ variables_["array_property_type"] =
+ "NSMutableArray<" + variables_["storage_type"] + "*>";
}
}
RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {}
-void RepeatedPrimitiveFieldGenerator::FinishInitialization(void) {
- RepeatedFieldGenerator::FinishInitialization();
- if (IsPrimitiveType(descriptor_)) {
- // No comment needed for primitive types.
- variables_["array_comment"] = "";
- }
-}
-
} // namespace objectivec
} // namespace compiler
} // namespace protobuf
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.h b/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.h
index 9bb79343..69bb1fdd 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.h
+++ b/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.h
@@ -41,21 +41,30 @@ namespace compiler {
namespace objectivec {
class PrimitiveFieldGenerator : public SingleFieldGenerator {
- friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field);
+ friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field,
+ const Options& options);
protected:
- explicit PrimitiveFieldGenerator(const FieldDescriptor* descriptor);
+ PrimitiveFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
virtual ~PrimitiveFieldGenerator();
+ virtual void GenerateFieldStorageDeclaration(io::Printer* printer) const;
+
+ virtual int ExtraRuntimeHasBitsNeeded(void) const;
+ virtual void SetExtraRuntimeHasBitsBase(int index_base);
+
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveFieldGenerator);
};
class PrimitiveObjFieldGenerator : public ObjCObjFieldGenerator {
- friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field);
+ friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field,
+ const Options& options);
protected:
- explicit PrimitiveObjFieldGenerator(const FieldDescriptor* descriptor);
+ PrimitiveObjFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
virtual ~PrimitiveObjFieldGenerator();
private:
@@ -63,12 +72,13 @@ class PrimitiveObjFieldGenerator : public ObjCObjFieldGenerator {
};
class RepeatedPrimitiveFieldGenerator : public RepeatedFieldGenerator {
- friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field);
+ friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field,
+ const Options& options);
protected:
- explicit RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor);
+ RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
virtual ~RepeatedPrimitiveFieldGenerator();
- virtual void FinishInitialization(void);
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPrimitiveFieldGenerator);
diff --git a/src/google/protobuf/compiler/parser.cc b/src/google/protobuf/compiler/parser.cc
index a389a4fc..214d7c9c 100644
--- a/src/google/protobuf/compiler/parser.cc
+++ b/src/google/protobuf/compiler/parser.cc
@@ -458,6 +458,61 @@ void Parser::SkipRestOfBlock() {
// ===================================================================
+bool Parser::ValidateEnum(const EnumDescriptorProto* proto) {
+ bool has_allow_alias = false;
+ bool allow_alias = false;
+
+ for (int i = 0; i < proto->options().uninterpreted_option_size(); i++) {
+ const UninterpretedOption option = proto->options().uninterpreted_option(i);
+ if (option.name_size() > 1) {
+ continue;
+ }
+ if (!option.name(0).is_extension() &&
+ option.name(0).name_part() == "allow_alias") {
+ has_allow_alias = true;
+ if (option.identifier_value() == "true") {
+ allow_alias = true;
+ }
+ break;
+ }
+ }
+
+ if (has_allow_alias && !allow_alias) {
+ string error =
+ "\"" + proto->name() +
+ "\" declares 'option allow_alias = false;' which has no effect. "
+ "Please remove the declaration.";
+ // This needlessly clutters declarations with nops.
+ AddError(error);
+ return false;
+ }
+
+ set<int> used_values;
+ bool has_duplicates = false;
+ for (int i = 0; i < proto->value_size(); ++i) {
+ const EnumValueDescriptorProto enum_value = proto->value(i);
+ if (used_values.find(enum_value.number()) != used_values.end()) {
+ has_duplicates = true;
+ break;
+ } else {
+ used_values.insert(enum_value.number());
+ }
+ }
+ if (allow_alias && !has_duplicates) {
+ string error =
+ "\"" + proto->name() +
+ "\" declares support for enum aliases but no enum values share field "
+ "numbers. Please remove the unnecessary 'option allow_alias = true;' "
+ "declaration.";
+ // Generate an error if an enum declares support for duplicate enum values
+ // and does not use it protect future authors.
+ AddError(error);
+ return false;
+ }
+
+ return true;
+}
+
bool Parser::Parse(io::Tokenizer* input, FileDescriptorProto* file) {
input_ = input;
had_errors_ = false;
@@ -489,9 +544,9 @@ bool Parser::Parse(io::Tokenizer* input, FileDescriptorProto* file) {
// Store the syntax into the file.
if (file != NULL) file->set_syntax(syntax_identifier_);
} else if (!stop_after_syntax_identifier_) {
- GOOGLE_LOG(WARNING) << "No syntax specified for the proto file. "
- << "Please use 'syntax = \"proto2\";' or "
- << "'syntax = \"proto3\";' to specify a syntax "
+ GOOGLE_LOG(WARNING) << "No syntax specified for the proto file: "
+ << file->name() << ". Please use 'syntax = \"proto2\";' "
+ << "or 'syntax = \"proto3\";' to specify a syntax "
<< "version. (Defaulted to proto2 syntax.)";
syntax_identifier_ = "proto2";
}
@@ -1575,6 +1630,16 @@ bool Parser::ParseOneof(OneofDescriptorProto* oneof_decl,
return false;
}
+ if (LookingAt("option")) {
+ LocationRecorder option_location(
+ oneof_location, OneofDescriptorProto::kOptionsFieldNumber);
+ if (!ParseOption(oneof_decl->mutable_options(), option_location,
+ containing_file, OPTION_STATEMENT)) {
+ return false;
+ }
+ continue;
+ }
+
// Print a nice error if the user accidentally tries to place a label
// on an individual member of a oneof.
if (LookingAt("required") ||
@@ -1627,6 +1692,9 @@ bool Parser::ParseEnumDefinition(EnumDescriptorProto* enum_type,
}
DO(ParseEnumBlock(enum_type, enum_location, containing_file));
+
+ DO(ValidateEnum(enum_type));
+
return true;
}
diff --git a/src/google/protobuf/compiler/parser.h b/src/google/protobuf/compiler/parser.h
index 3ba1e170..0f80e78b 100644
--- a/src/google/protobuf/compiler/parser.h
+++ b/src/google/protobuf/compiler/parser.h
@@ -71,7 +71,7 @@ class LIBPROTOBUF_EXPORT Parser {
// it. Returns true if no errors occurred, false otherwise.
bool Parse(io::Tokenizer* input, FileDescriptorProto* file);
- // Optional fetaures:
+ // Optional features:
// DEPRECATED: New code should use the SourceCodeInfo embedded in the
// FileDescriptorProto.
@@ -498,6 +498,8 @@ class LIBPROTOBUF_EXPORT Parser {
}
+ bool ValidateEnum(const EnumDescriptorProto* proto);
+
// =================================================================
io::Tokenizer* input_;
diff --git a/src/google/protobuf/compiler/parser_unittest.cc b/src/google/protobuf/compiler/parser_unittest.cc
index 0d729e0b..1d623dd9 100644
--- a/src/google/protobuf/compiler/parser_unittest.cc
+++ b/src/google/protobuf/compiler/parser_unittest.cc
@@ -1170,6 +1170,29 @@ TEST_F(ParseErrorTest, EnumValueOutOfRange) {
"4:19: Integer out of range.\n");
}
+TEST_F(ParseErrorTest, EnumAllowAliasFalse) {
+ ExpectHasErrors(
+ "enum Foo {\n"
+ " option allow_alias = false;\n"
+ " BAR = 1;\n"
+ " BAZ = 2;\n"
+ "}\n",
+ "5:0: \"Foo\" declares 'option allow_alias = false;' which has no effect. "
+ "Please remove the declaration.\n");
+}
+
+TEST_F(ParseErrorTest, UnnecessaryEnumAllowAlias) {
+ ExpectHasErrors(
+ "enum Foo {\n"
+ " option allow_alias = true;\n"
+ " BAR = 1;\n"
+ " BAZ = 2;\n"
+ "}\n",
+ "5:0: \"Foo\" declares support for enum aliases but no enum values share "
+ "field numbers. Please remove the unnecessary 'option allow_alias = true;' "
+ "declaration.\n");
+}
+
TEST_F(ParseErrorTest, DefaultValueMissing) {
ExpectHasErrors(
"message TestMessage {\n"
@@ -1839,6 +1862,8 @@ TEST_F(ParseDescriptorDebugTest, TestCommentsInDebugString) {
"// Detached comment before TestMessage1.\n"
"\n"
"// Message comment.\n"
+ "//\n"
+ "// More detail in message comment.\n"
"message TestMessage1 {\n"
"\n"
" // Detached comment before foo.\n"
@@ -1890,11 +1915,6 @@ TEST_F(ParseDescriptorDebugTest, TestCommentsInDebugString) {
pool_.BuildFileCollectingErrors(parsed_desc, &collector);
ASSERT_TRUE(descriptor != NULL);
- DebugStringOptions debug_string_options;
- debug_string_options.include_comments = true;
- const string debug_string =
- descriptor->DebugStringWithOptions(debug_string_options);
-
// Ensure that each of the comments appears somewhere in the DebugString().
// We don't test the exact comment placement or formatting, because we do not
// want to be too fragile here.
@@ -1905,6 +1925,7 @@ TEST_F(ParseDescriptorDebugTest, TestCommentsInDebugString) {
"Package comment.",
"Detached comment before TestMessage1.",
"Message comment.",
+ "More detail in message comment.",
"Detached comment before foo.",
"Field comment",
"Detached comment before NestedMessage.",
@@ -1919,11 +1940,28 @@ TEST_F(ParseDescriptorDebugTest, TestCommentsInDebugString) {
"RPC comment",
};
- for (int i = 0; i < GOOGLE_ARRAYSIZE(expected_comments); ++i) {
- string::size_type found_pos = debug_string.find(expected_comments[i]);
- EXPECT_TRUE(found_pos != string::npos)
- << "\"" << expected_comments[i] << "\" not found.";
+ DebugStringOptions debug_string_options;
+ debug_string_options.include_comments = true;
+
+ {
+ const string debug_string =
+ descriptor->DebugStringWithOptions(debug_string_options);
+
+ for (int i = 0; i < GOOGLE_ARRAYSIZE(expected_comments); ++i) {
+ string::size_type found_pos = debug_string.find(expected_comments[i]);
+ EXPECT_TRUE(found_pos != string::npos)
+ << "\"" << expected_comments[i] << "\" not found.";
+ }
+
+ // Result of DebugStringWithOptions should be parseable.
+ SetupParser(debug_string.c_str());
+ FileDescriptorProto parsed;
+ parser_->Parse(input_.get(), &parsed);
+ EXPECT_EQ(io::Tokenizer::TYPE_END, input_->current().type);
+ ASSERT_EQ("", error_collector_.text_)
+ << "Failed to parse:\n" << debug_string;
}
+
}
TEST_F(ParseDescriptorDebugTest, TestMaps) {
diff --git a/src/google/protobuf/compiler/plugin.cc b/src/google/protobuf/compiler/plugin.cc
index 2bebf1f3..2ff50f61 100644
--- a/src/google/protobuf/compiler/plugin.cc
+++ b/src/google/protobuf/compiler/plugin.cc
@@ -93,31 +93,15 @@ class GeneratorResponseContext : public GeneratorContext {
const vector<const FileDescriptor*>& parsed_files_;
};
-int PluginMain(int argc, char* argv[], const CodeGenerator* generator) {
-
- if (argc > 1) {
- std::cerr << argv[0] << ": Unknown option: " << argv[1] << std::endl;
- return 1;
- }
-
-#ifdef _WIN32
- _setmode(STDIN_FILENO, _O_BINARY);
- _setmode(STDOUT_FILENO, _O_BINARY);
-#endif
-
- CodeGeneratorRequest request;
- if (!request.ParseFromFileDescriptor(STDIN_FILENO)) {
- std::cerr << argv[0] << ": protoc sent unparseable request to plugin."
- << std::endl;
- return 1;
- }
-
+bool GenerateCode(const CodeGeneratorRequest& request,
+ const CodeGenerator& generator, CodeGeneratorResponse* response,
+ string* error_msg) {
DescriptorPool pool;
for (int i = 0; i < request.proto_file_size(); i++) {
const FileDescriptor* file = pool.BuildFile(request.proto_file(i));
if (file == NULL) {
// BuildFile() already wrote an error message.
- return 1;
+ return false;
}
}
@@ -125,19 +109,18 @@ int PluginMain(int argc, char* argv[], const CodeGenerator* generator) {
for (int i = 0; i < request.file_to_generate_size(); i++) {
parsed_files.push_back(pool.FindFileByName(request.file_to_generate(i)));
if (parsed_files.back() == NULL) {
- std::cerr << argv[0] << ": protoc asked plugin to generate a file but "
- "did not provide a descriptor for the file: "
- << request.file_to_generate(i) << std::endl;
- return 1;
+ *error_msg = "protoc asked plugin to generate a file but "
+ "did not provide a descriptor for the file: " +
+ request.file_to_generate(i);
+ return false;
}
}
- CodeGeneratorResponse response;
- GeneratorResponseContext context(&response, parsed_files);
+ GeneratorResponseContext context(response, parsed_files);
- if (generator->HasGenerateAll()) {
+ if (generator.HasGenerateAll()) {
string error;
- bool succeeded = generator->GenerateAll(
+ bool succeeded = generator.GenerateAll(
parsed_files, request.parameter(), &context, &error);
if (!succeeded && error.empty()) {
@@ -145,14 +128,14 @@ int PluginMain(int argc, char* argv[], const CodeGenerator* generator) {
"description.";
}
if (!error.empty()) {
- response.set_error(error);
+ response->set_error(error);
}
} else {
for (int i = 0; i < parsed_files.size(); i++) {
const FileDescriptor* file = parsed_files[i];
string error;
- bool succeeded = generator->Generate(
+ bool succeeded = generator.Generate(
file, request.parameter(), &context, &error);
if (!succeeded && error.empty()) {
@@ -160,14 +143,46 @@ int PluginMain(int argc, char* argv[], const CodeGenerator* generator) {
"description.";
}
if (!error.empty()) {
- response.set_error(file->name() + ": " + error);
+ response->set_error(file->name() + ": " + error);
break;
}
}
}
- if (!response.SerializeToFileDescriptor(STDOUT_FILENO)) {
- std::cerr << argv[0] << ": Error writing to stdout." << std::endl;
+ return true;
+}
+
+int PluginMain(int argc, char* argv[], const CodeGenerator* generator) {
+
+ if (argc > 1) {
+ std::cerr << argv[0] << ": Unknown option: " << argv[1] << std::endl;
+ return 1;
+ }
+
+#ifdef _WIN32
+ _setmode(STDIN_FILENO, _O_BINARY);
+ _setmode(STDOUT_FILENO, _O_BINARY);
+#endif
+
+ CodeGeneratorRequest request;
+ if (!request.ParseFromFileDescriptor(STDIN_FILENO)) {
+ std::cerr << argv[0] << ": protoc sent unparseable request to plugin."
+ << std::endl;
+ return 1;
+ }
+
+ string error_msg;
+ CodeGeneratorResponse response;
+
+ if (GenerateCode(request, *generator, &response, &error_msg)) {
+ if (!response.SerializeToFileDescriptor(STDOUT_FILENO)) {
+ std::cerr << argv[0] << ": Error writing to stdout." << std::endl;
+ return 1;
+ }
+ } else {
+ if (!error_msg.empty()) {
+ std::cerr << argv[0] << ": " << error_msg << std::endl;
+ }
return 1;
}
diff --git a/src/google/protobuf/compiler/plugin.h b/src/google/protobuf/compiler/plugin.h
index 679f9bdb..d2793a9f 100644
--- a/src/google/protobuf/compiler/plugin.h
+++ b/src/google/protobuf/compiler/plugin.h
@@ -40,6 +40,13 @@
// }
// You must link your plugin against libprotobuf and libprotoc.
//
+// The core part of PluginMain is to invoke the given CodeGenerator on a
+// CodeGeneratorRequest to generate a CodeGeneratorResponse. This part is
+// abstracted out and made into function GenerateCode so that it can be reused,
+// for example, to implement a variant of PluginMain that does some
+// preprocessing on the input CodeGeneratorRequest before feeding the request
+// to the given code generator.
+//
// To get protoc to use the plugin, do one of the following:
// * Place the plugin binary somewhere in the PATH and give it the name
// "protoc-gen-NAME" (replacing "NAME" with the name of your plugin). If you
@@ -55,16 +62,27 @@
#ifndef GOOGLE_PROTOBUF_COMPILER_PLUGIN_H__
#define GOOGLE_PROTOBUF_COMPILER_PLUGIN_H__
+#include <string>
+
#include <google/protobuf/stubs/common.h>
namespace google {
namespace protobuf {
namespace compiler {
class CodeGenerator; // code_generator.h
+class CodeGeneratorRequest;
+class CodeGeneratorResponse;
// Implements main() for a protoc plugin exposing the given code generator.
LIBPROTOC_EXPORT int PluginMain(int argc, char* argv[], const CodeGenerator* generator);
+// Generates code using the given code generator. Returns true if the code
+// generation is successful. If the code geneartion fails, error_msg may be
+// populated to describe the failure cause.
+bool GenerateCode(const CodeGeneratorRequest& request,
+ const CodeGenerator& generator, CodeGeneratorResponse* response,
+ string* error_msg);
+
} // namespace compiler
} // namespace protobuf
diff --git a/src/google/protobuf/compiler/plugin.pb.cc b/src/google/protobuf/compiler/plugin.pb.cc
index 636673ae..9064c382 100644
--- a/src/google/protobuf/compiler/plugin.pb.cc
+++ b/src/google/protobuf/compiler/plugin.pb.cc
@@ -7,6 +7,7 @@
#include <algorithm>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/port.h>
#include <google/protobuf/stubs/once.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/wire_format_lite_inl.h>
@@ -35,6 +36,7 @@ const ::google::protobuf::internal::GeneratedMessageReflection*
} // namespace
+void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto() {
protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
const ::google::protobuf::FileDescriptor* file =
@@ -101,6 +103,7 @@ inline void protobuf_AssignDescriptorsOnce() {
&protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto);
}
+void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
void protobuf_RegisterTypes(const ::std::string&) {
protobuf_AssignDescriptorsOnce();
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
@@ -122,6 +125,7 @@ void protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto() {
delete CodeGeneratorResponse_File_reflection_;
}
+void protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto() {
static bool already_here = false;
if (already_here) return;
@@ -160,16 +164,6 @@ struct StaticDescriptorInitializer_google_2fprotobuf_2fcompiler_2fplugin_2eproto
}
} static_descriptor_initializer_google_2fprotobuf_2fcompiler_2fplugin_2eproto_;
-namespace {
-
-static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD;
-static void MergeFromFail(int line) {
- GOOGLE_CHECK(false) << __FILE__ << ":" << line;
-}
-
-} // namespace
-
-
// ===================================================================
#if !defined(_MSC_VER) || _MSC_VER >= 1900
@@ -239,6 +233,7 @@ CodeGeneratorRequest* CodeGeneratorRequest::New(::google::protobuf::Arena* arena
}
void CodeGeneratorRequest::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.compiler.CodeGeneratorRequest)
if (has_parameter()) {
parameter_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -252,7 +247,7 @@ void CodeGeneratorRequest::Clear() {
bool CodeGeneratorRequest::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.compiler.CodeGeneratorRequest)
for (;;) {
@@ -371,8 +366,8 @@ void CodeGeneratorRequest::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.compiler.CodeGeneratorRequest)
}
-::google::protobuf::uint8* CodeGeneratorRequest::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* CodeGeneratorRequest::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.compiler.CodeGeneratorRequest)
// repeated string file_to_generate = 1;
for (int i = 0; i < this->file_to_generate_size(); i++) {
@@ -398,8 +393,8 @@ void CodeGeneratorRequest::SerializeWithCachedSizes(
// repeated .google.protobuf.FileDescriptorProto proto_file = 15;
for (unsigned int i = 0, n = this->proto_file_size(); i < n; i++) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 15, this->proto_file(i), target);
+ InternalWriteMessageNoVirtualToArray(
+ 15, this->proto_file(i), false, target);
}
if (_internal_metadata_.have_unknown_fields()) {
@@ -411,6 +406,7 @@ void CodeGeneratorRequest::SerializeWithCachedSizes(
}
int CodeGeneratorRequest::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.compiler.CodeGeneratorRequest)
int total_size = 0;
// optional string parameter = 2;
@@ -447,19 +443,27 @@ int CodeGeneratorRequest::ByteSize() const {
}
void CodeGeneratorRequest::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.compiler.CodeGeneratorRequest)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const CodeGeneratorRequest* source =
::google::protobuf::internal::DynamicCastToGenerated<const CodeGeneratorRequest>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.compiler.CodeGeneratorRequest)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.compiler.CodeGeneratorRequest)
MergeFrom(*source);
}
}
void CodeGeneratorRequest::MergeFrom(const CodeGeneratorRequest& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.CodeGeneratorRequest)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
file_to_generate_.MergeFrom(from.file_to_generate_);
proto_file_.MergeFrom(from.proto_file_);
if (from._has_bits_[1 / 32] & (0xffu << (1 % 32))) {
@@ -474,12 +478,14 @@ void CodeGeneratorRequest::MergeFrom(const CodeGeneratorRequest& from) {
}
void CodeGeneratorRequest::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.compiler.CodeGeneratorRequest)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void CodeGeneratorRequest::CopyFrom(const CodeGeneratorRequest& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.compiler.CodeGeneratorRequest)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -544,6 +550,7 @@ void CodeGeneratorRequest::clear_file_to_generate() {
// @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
}
::std::string* CodeGeneratorRequest::add_file_to_generate() {
+ // @@protoc_insertion_point(field_add_mutable:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
return file_to_generate_.Add();
}
void CodeGeneratorRequest::add_file_to_generate(const ::std::string& value) {
@@ -609,6 +616,7 @@ void CodeGeneratorRequest::clear_parameter() {
return parameter_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* CodeGeneratorRequest::release_parameter() {
+ // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorRequest.parameter)
clear_has_parameter();
return parameter_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -727,6 +735,7 @@ CodeGeneratorResponse_File* CodeGeneratorResponse_File::New(::google::protobuf::
}
void CodeGeneratorResponse_File::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.compiler.CodeGeneratorResponse.File)
if (_has_bits_[0 / 32] & 7u) {
if (has_name()) {
name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
@@ -746,7 +755,7 @@ void CodeGeneratorResponse_File::Clear() {
bool CodeGeneratorResponse_File::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.compiler.CodeGeneratorResponse.File)
for (;;) {
@@ -866,8 +875,8 @@ void CodeGeneratorResponse_File::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.compiler.CodeGeneratorResponse.File)
}
-::google::protobuf::uint8* CodeGeneratorResponse_File::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* CodeGeneratorResponse_File::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.compiler.CodeGeneratorResponse.File)
// optional string name = 1;
if (has_name()) {
@@ -911,6 +920,7 @@ void CodeGeneratorResponse_File::SerializeWithCachedSizes(
}
int CodeGeneratorResponse_File::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.compiler.CodeGeneratorResponse.File)
int total_size = 0;
if (_has_bits_[0 / 32] & 7u) {
@@ -948,19 +958,27 @@ int CodeGeneratorResponse_File::ByteSize() const {
}
void CodeGeneratorResponse_File::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.compiler.CodeGeneratorResponse.File)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const CodeGeneratorResponse_File* source =
::google::protobuf::internal::DynamicCastToGenerated<const CodeGeneratorResponse_File>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.compiler.CodeGeneratorResponse.File)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.compiler.CodeGeneratorResponse.File)
MergeFrom(*source);
}
}
void CodeGeneratorResponse_File::MergeFrom(const CodeGeneratorResponse_File& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.CodeGeneratorResponse.File)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_name()) {
set_has_name();
@@ -981,12 +999,14 @@ void CodeGeneratorResponse_File::MergeFrom(const CodeGeneratorResponse_File& fro
}
void CodeGeneratorResponse_File::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.compiler.CodeGeneratorResponse.File)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void CodeGeneratorResponse_File::CopyFrom(const CodeGeneratorResponse_File& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.compiler.CodeGeneratorResponse.File)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -1087,6 +1107,7 @@ CodeGeneratorResponse* CodeGeneratorResponse::New(::google::protobuf::Arena* are
}
void CodeGeneratorResponse::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.compiler.CodeGeneratorResponse)
if (has_error()) {
error_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -1099,7 +1120,7 @@ void CodeGeneratorResponse::Clear() {
bool CodeGeneratorResponse::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.compiler.CodeGeneratorResponse)
for (;;) {
@@ -1188,8 +1209,8 @@ void CodeGeneratorResponse::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.compiler.CodeGeneratorResponse)
}
-::google::protobuf::uint8* CodeGeneratorResponse::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* CodeGeneratorResponse::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.compiler.CodeGeneratorResponse)
// optional string error = 1;
if (has_error()) {
@@ -1205,8 +1226,8 @@ void CodeGeneratorResponse::SerializeWithCachedSizes(
// repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
for (unsigned int i = 0, n = this->file_size(); i < n; i++) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 15, this->file(i), target);
+ InternalWriteMessageNoVirtualToArray(
+ 15, this->file(i), false, target);
}
if (_internal_metadata_.have_unknown_fields()) {
@@ -1218,6 +1239,7 @@ void CodeGeneratorResponse::SerializeWithCachedSizes(
}
int CodeGeneratorResponse::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.compiler.CodeGeneratorResponse)
int total_size = 0;
// optional string error = 1;
@@ -1247,19 +1269,27 @@ int CodeGeneratorResponse::ByteSize() const {
}
void CodeGeneratorResponse::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.compiler.CodeGeneratorResponse)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const CodeGeneratorResponse* source =
::google::protobuf::internal::DynamicCastToGenerated<const CodeGeneratorResponse>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.compiler.CodeGeneratorResponse)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.compiler.CodeGeneratorResponse)
MergeFrom(*source);
}
}
void CodeGeneratorResponse::MergeFrom(const CodeGeneratorResponse& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.CodeGeneratorResponse)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
file_.MergeFrom(from.file_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_error()) {
@@ -1273,12 +1303,14 @@ void CodeGeneratorResponse::MergeFrom(const CodeGeneratorResponse& from) {
}
void CodeGeneratorResponse::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.compiler.CodeGeneratorResponse)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void CodeGeneratorResponse::CopyFrom(const CodeGeneratorResponse& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.compiler.CodeGeneratorResponse)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -1352,6 +1384,7 @@ void CodeGeneratorResponse_File::clear_name() {
return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* CodeGeneratorResponse_File::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.File.name)
clear_has_name();
return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -1405,6 +1438,7 @@ void CodeGeneratorResponse_File::clear_insertion_point() {
return insertion_point_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* CodeGeneratorResponse_File::release_insertion_point() {
+ // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
clear_has_insertion_point();
return insertion_point_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -1458,6 +1492,7 @@ void CodeGeneratorResponse_File::clear_content() {
return content_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* CodeGeneratorResponse_File::release_content() {
+ // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.File.content)
clear_has_content();
return content_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -1515,6 +1550,7 @@ void CodeGeneratorResponse::clear_error() {
return error_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* CodeGeneratorResponse::release_error() {
+ // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.error)
clear_has_error();
return error_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
diff --git a/src/google/protobuf/compiler/plugin.pb.h b/src/google/protobuf/compiler/plugin.pb.h
index 0a03e979..13eeb69f 100644
--- a/src/google/protobuf/compiler/plugin.pb.h
+++ b/src/google/protobuf/compiler/plugin.pb.h
@@ -45,7 +45,7 @@ class CodeGeneratorResponse_File;
// ===================================================================
-class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message {
+class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.compiler.CodeGeneratorRequest) */ {
public:
CodeGeneratorRequest();
virtual ~CodeGeneratorRequest();
@@ -87,7 +87,11 @@ class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
@@ -169,7 +173,7 @@ class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message
};
// -------------------------------------------------------------------
-class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::Message {
+class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.compiler.CodeGeneratorResponse.File) */ {
public:
CodeGeneratorResponse_File();
virtual ~CodeGeneratorResponse_File();
@@ -211,7 +215,11 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::M
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
@@ -293,7 +301,7 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::M
};
// -------------------------------------------------------------------
-class LIBPROTOC_EXPORT CodeGeneratorResponse : public ::google::protobuf::Message {
+class LIBPROTOC_EXPORT CodeGeneratorResponse : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.compiler.CodeGeneratorResponse) */ {
public:
CodeGeneratorResponse();
virtual ~CodeGeneratorResponse();
@@ -335,7 +343,11 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse : public ::google::protobuf::Messag
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
@@ -437,6 +449,7 @@ inline void CodeGeneratorRequest::set_file_to_generate(int index, const char* va
// @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
}
inline ::std::string* CodeGeneratorRequest::add_file_to_generate() {
+ // @@protoc_insertion_point(field_add_mutable:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
return file_to_generate_.Add();
}
inline void CodeGeneratorRequest::add_file_to_generate(const ::std::string& value) {
@@ -502,6 +515,7 @@ inline ::std::string* CodeGeneratorRequest::mutable_parameter() {
return parameter_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* CodeGeneratorRequest::release_parameter() {
+ // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorRequest.parameter)
clear_has_parameter();
return parameter_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -589,6 +603,7 @@ inline ::std::string* CodeGeneratorResponse_File::mutable_name() {
return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* CodeGeneratorResponse_File::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.File.name)
clear_has_name();
return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -642,6 +657,7 @@ inline ::std::string* CodeGeneratorResponse_File::mutable_insertion_point() {
return insertion_point_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* CodeGeneratorResponse_File::release_insertion_point() {
+ // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
clear_has_insertion_point();
return insertion_point_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -695,6 +711,7 @@ inline ::std::string* CodeGeneratorResponse_File::mutable_content() {
return content_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* CodeGeneratorResponse_File::release_content() {
+ // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.File.content)
clear_has_content();
return content_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -752,6 +769,7 @@ inline ::std::string* CodeGeneratorResponse::mutable_error() {
return error_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* CodeGeneratorResponse::release_error() {
+ // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.error)
clear_has_error();
return error_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
diff --git a/src/google/protobuf/compiler/python/python_generator.cc b/src/google/protobuf/compiler/python/python_generator.cc
index 4d500f90..d5468a0c 100644
--- a/src/google/protobuf/compiler/python/python_generator.cc
+++ b/src/google/protobuf/compiler/python/python_generator.cc
@@ -44,6 +44,7 @@
// performance-minded Python code leverage the fast C++ implementation
// directly.
+#include <algorithm>
#include <google/protobuf/stubs/hash.h>
#include <limits>
#include <map>
@@ -107,20 +108,25 @@ string ModuleAlias(const string& filename) {
return module_name;
}
-
-// Returns an import statement of form "from X.Y.Z import T" for the given
-// .proto filename.
-string ModuleImportStatement(const string& filename) {
- string module_name = ModuleName(filename);
- int last_dot_pos = module_name.rfind('.');
- if (last_dot_pos == string::npos) {
- // NOTE(petya): this is not tested as it would require a protocol buffer
- // outside of any package, and I don't think that is easily achievable.
- return "import " + module_name;
- } else {
- return "from " + module_name.substr(0, last_dot_pos) + " import " +
- module_name.substr(last_dot_pos + 1);
+// Keywords reserved by the Python language.
+const char* const kKeywords[] = {
+ "False", "None", "True", "and", "as", "assert", "break",
+ "class", "continue", "def", "del", "elif", "else", "except",
+ "finally", "for", "from", "global", "if", "import", "in",
+ "is", "lambda", "nonlocal", "not", "or", "pass", "raise",
+ "return", "try", "while", "with", "yield",
+};
+const char* const* kKeywordsEnd =
+ kKeywords + (sizeof(kKeywords) / sizeof(kKeywords[0]));
+
+bool ContainsPythonKeyword(const string& module_name) {
+ vector<string> tokens = Split(module_name, ".");
+ for (int i = 0; i < tokens.size(); ++i) {
+ if (std::find(kKeywords, kKeywordsEnd, tokens[i]) != kKeywordsEnd) {
+ return true;
+ }
}
+ return false;
}
@@ -235,7 +241,7 @@ string StringifyDefaultValue(const FieldDescriptor& field) {
// infinity * 0 = nan
return "(1e10000 * 0)";
} else {
- return SimpleDtoa(value);
+ return "float(" + SimpleDtoa(value) + ")";
}
}
case FieldDescriptor::CPPTYPE_FLOAT: {
@@ -251,7 +257,7 @@ string StringifyDefaultValue(const FieldDescriptor& field) {
// infinity - infinity = nan
return "(1e10000 * 0)";
} else {
- return SimpleFtoa(value);
+ return "float(" + SimpleFtoa(value) + ")";
}
}
case FieldDescriptor::CPPTYPE_BOOL:
@@ -359,10 +365,32 @@ bool Generator::Generate(const FileDescriptor* file,
void Generator::PrintImports() const {
for (int i = 0; i < file_->dependency_count(); ++i) {
const string& filename = file_->dependency(i)->name();
- string import_statement = ModuleImportStatement(filename);
+
+ string module_name = ModuleName(filename);
string module_alias = ModuleAlias(filename);
- printer_->Print("$statement$ as $alias$\n", "statement",
- import_statement, "alias", module_alias);
+ if (ContainsPythonKeyword(module_name)) {
+ // If the module path contains a Python keyword, we have to quote the
+ // module name and import it using importlib. Otherwise the usual kind of
+ // import statement would result in a syntax error from the presence of
+ // the keyword.
+ printer_->Print("import importlib\n");
+ printer_->Print("$alias$ = importlib.import_module('$name$')\n", "alias",
+ module_alias, "name", module_name);
+ } else {
+ int last_dot_pos = module_name.rfind('.');
+ string import_statement;
+ if (last_dot_pos == string::npos) {
+ // NOTE(petya): this is not tested as it would require a protocol buffer
+ // outside of any package, and I don't think that is easily achievable.
+ import_statement = "import " + module_name;
+ } else {
+ import_statement = "from " + module_name.substr(0, last_dot_pos) +
+ " import " + module_name.substr(last_dot_pos + 1);
+ }
+ printer_->Print("$statement$ as $alias$\n", "statement", import_statement,
+ "alias", module_alias);
+ }
+
CopyPublicDependenciesAliases(module_alias, file_->dependency(i));
}
printer_->Print("\n");
@@ -707,11 +735,18 @@ void Generator::PrintDescriptor(const Descriptor& message_descriptor) const {
m["name"] = desc->name();
m["full_name"] = desc->full_name();
m["index"] = SimpleItoa(desc->index());
+ string options_string =
+ OptionsValue("OneofOptions", desc->options().SerializeAsString());
+ if (options_string == "None") {
+ m["options"] = "";
+ } else {
+ m["options"] = ", options=" + options_string;
+ }
printer_->Print(
m,
"_descriptor.OneofDescriptor(\n"
" name='$name$', full_name='$full_name$',\n"
- " index=$index$, containing_type=None, fields=[]),\n");
+ " index=$index$, containing_type=None, fields=[]$options$),\n");
}
printer_->Outdent();
printer_->Print("],\n");
@@ -1235,6 +1270,18 @@ void Generator::FixAllDescriptorOptions() const {
}
}
+void Generator::FixOptionsForOneof(const OneofDescriptor& oneof) const {
+ string oneof_options = OptionsValue(
+ "OneofOptions", oneof.options().SerializeAsString());
+ if (oneof_options != "None") {
+ string oneof_name = strings::Substitute(
+ "$0.$1['$2']",
+ ModuleLevelDescriptorName(*oneof.containing_type()),
+ "oneofs_by_name", oneof.name());
+ PrintDescriptorOptionsFixingCode(oneof_name, oneof_options, printer_);
+ }
+}
+
// Prints expressions that set the options for an enum descriptor and its
// value descriptors.
void Generator::FixOptionsForEnum(const EnumDescriptor& enum_descriptor) const {
@@ -1288,6 +1335,10 @@ void Generator::FixOptionsForMessage(const Descriptor& descriptor) const {
for (int i = 0; i < descriptor.nested_type_count(); ++i) {
FixOptionsForMessage(*descriptor.nested_type(i));
}
+ // Oneofs.
+ for (int i = 0; i < descriptor.oneof_decl_count(); ++i) {
+ FixOptionsForOneof(*descriptor.oneof_decl(i));
+ }
// Enums.
for (int i = 0; i < descriptor.enum_type_count(); ++i) {
FixOptionsForEnum(*descriptor.enum_type(i));
diff --git a/src/google/protobuf/compiler/python/python_generator.h b/src/google/protobuf/compiler/python/python_generator.h
index aa0f5fce..7583aa65 100644
--- a/src/google/protobuf/compiler/python/python_generator.h
+++ b/src/google/protobuf/compiler/python/python_generator.h
@@ -48,6 +48,7 @@ class Descriptor;
class EnumDescriptor;
class EnumValueDescriptor;
class FieldDescriptor;
+class OneofDescriptor;
class ServiceDescriptor;
namespace io { class Printer; }
@@ -148,6 +149,7 @@ class LIBPROTOC_EXPORT Generator : public CodeGenerator {
void FixAllDescriptorOptions() const;
void FixOptionsForField(const FieldDescriptor& field) const;
+ void FixOptionsForOneof(const OneofDescriptor& oneof) const;
void FixOptionsForEnum(const EnumDescriptor& descriptor) const;
void FixOptionsForMessage(const Descriptor& descriptor) const;
diff --git a/src/google/protobuf/compiler/python/python_plugin_unittest.cc b/src/google/protobuf/compiler/python/python_plugin_unittest.cc
index e82bbae7..34f857fd 100644
--- a/src/google/protobuf/compiler/python/python_plugin_unittest.cc
+++ b/src/google/protobuf/compiler/python/python_plugin_unittest.cc
@@ -44,9 +44,11 @@
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/io/printer.h>
+#include <google/protobuf/testing/file.h>
+#include <google/protobuf/testing/file.h>
+#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
-#include <google/protobuf/testing/file.h>
namespace google {
namespace protobuf {
@@ -114,6 +116,53 @@ TEST(PythonPluginTest, PluginTest) {
EXPECT_EQ(0, cli.Run(5, argv));
}
+// This test verifies that the generated Python output uses regular imports (as
+// opposed to importlib) in the usual case where the .proto file paths do not
+// not contain any Python keywords.
+TEST(PythonPluginTest, ImportTest) {
+ // Create files test1.proto and test2.proto with the former importing the
+ // latter.
+ GOOGLE_CHECK_OK(File::SetContents(TestTempDir() + "/test1.proto",
+ "syntax = \"proto3\";\n"
+ "package foo;\n"
+ "import \"test2.proto\";"
+ "message Message1 {\n"
+ " Message2 message_2 = 1;\n"
+ "}\n",
+ true));
+ GOOGLE_CHECK_OK(File::SetContents(TestTempDir() + "/test2.proto",
+ "syntax = \"proto3\";\n"
+ "package foo;\n"
+ "message Message2 {}\n",
+ true));
+
+ google::protobuf::compiler::CommandLineInterface cli;
+ cli.SetInputsAreProtoPathRelative(true);
+ python::Generator python_generator;
+ cli.RegisterGenerator("--python_out", &python_generator, "");
+ string proto_path = "-I" + TestTempDir();
+ string python_out = "--python_out=" + TestTempDir();
+ const char* argv[] = {"protoc", proto_path.c_str(), "-I.", python_out.c_str(),
+ "test1.proto"};
+ ASSERT_EQ(0, cli.Run(5, argv));
+
+ // Loop over the lines of the generated code and verify that we find an
+ // ordinary Python import but do not find the string "importlib".
+ string output;
+ GOOGLE_CHECK_OK(File::GetContents(TestTempDir() + "/test1_pb2.py", &output,
+ true));
+ std::vector<string> lines = Split(output, "\n");
+ string expected_import = "import test2_pb2";
+ bool found_expected_import = false;
+ for (int i = 0; i < lines.size(); ++i) {
+ if (lines[i].find(expected_import) != string::npos) {
+ found_expected_import = true;
+ }
+ EXPECT_EQ(string::npos, lines[i].find("importlib"));
+ }
+ EXPECT_TRUE(found_expected_import);
+}
+
} // namespace
} // namespace python
} // namespace compiler
diff --git a/src/google/protobuf/compiler/ruby/ruby_generated_code.rb b/src/google/protobuf/compiler/ruby/ruby_generated_code_pb.rb
index 49b23fbe..49b23fbe 100644
--- a/src/google/protobuf/compiler/ruby/ruby_generated_code.rb
+++ b/src/google/protobuf/compiler/ruby/ruby_generated_code_pb.rb
diff --git a/src/google/protobuf/compiler/ruby/ruby_generator.cc b/src/google/protobuf/compiler/ruby/ruby_generator.cc
index 9692f1bf..fbe3b4cb 100644
--- a/src/google/protobuf/compiler/ruby/ruby_generator.cc
+++ b/src/google/protobuf/compiler/ruby/ruby_generator.cc
@@ -48,7 +48,7 @@ namespace ruby {
// Forward decls.
std::string IntToString(int32 value);
-std::string StripDotProto(const std::string& proto_file);
+std::string GetRequireName(const std::string& proto_file);
std::string LabelForField(google::protobuf::FieldDescriptor* field);
std::string TypeName(google::protobuf::FieldDescriptor* field);
void GenerateMessage(const google::protobuf::Descriptor* message,
@@ -70,9 +70,13 @@ std::string IntToString(int32 value) {
return os.str();
}
-std::string StripDotProto(const std::string& proto_file) {
+std::string GetRequireName(const std::string& proto_file) {
int lastindex = proto_file.find_last_of(".");
- return proto_file.substr(0, lastindex);
+ return proto_file.substr(0, lastindex) + "_pb";
+}
+
+std::string GetOutputFilename(const std::string& proto_file) {
+ return GetRequireName(proto_file) + ".rb";
}
std::string LabelForField(const google::protobuf::FieldDescriptor* field) {
@@ -233,15 +237,52 @@ void GenerateEnum(const google::protobuf::EnumDescriptor* en,
"end\n");
}
-// Module names, class names, and enum value names need to be Ruby constants,
-// which must start with a capital letter.
+// Locale-agnostic utility functions.
+bool IsLower(char ch) { return ch >= 'a' && ch <= 'z'; }
+
+bool IsUpper(char ch) { return ch >= 'A' && ch <= 'Z'; }
+
+bool IsAlpha(char ch) { return IsLower(ch) || IsUpper(ch); }
+
+char ToUpper(char ch) { return IsLower(ch) ? (ch - 'a' + 'A') : ch; }
+
+
+// Package names in protobuf are snake_case by convention, but Ruby module
+// names must be PascalCased.
+//
+// foo_bar_baz -> FooBarBaz
+std::string PackageToModule(const std::string& name) {
+ bool next_upper = true;
+ std::string result;
+ result.reserve(name.size());
+
+ for (int i = 0; i < name.size(); i++) {
+ if (name[i] == '_') {
+ next_upper = true;
+ } else {
+ if (next_upper) {
+ result.push_back(ToUpper(name[i]));
+ } else {
+ result.push_back(name[i]);
+ }
+ next_upper = false;
+ }
+ }
+
+ return result;
+}
+
+// Class and enum names in protobuf should be PascalCased by convention, but
+// since there is nothing enforcing this we need to ensure that they are valid
+// Ruby constants. That mainly means making sure that the first character is
+// an upper-case letter.
std::string RubifyConstant(const std::string& name) {
std::string ret = name;
if (!ret.empty()) {
- if (ret[0] >= 'a' && ret[0] <= 'z') {
+ if (IsLower(ret[0])) {
// If it starts with a lowercase letter, capitalize it.
- ret[0] = ret[0] - 'a' + 'A';
- } else if (ret[0] < 'A' || ret[0] > 'Z') {
+ ret[0] = ToUpper(ret[0]);
+ } else if (!IsAlpha(ret[0])) {
// Otherwise (e.g. if it begins with an underscore), we need to come up
// with some prefix that starts with a capital letter. We could be smarter
// here, e.g. try to strip leading underscores, but this may cause other
@@ -250,6 +291,7 @@ std::string RubifyConstant(const std::string& name) {
ret = "PB_" + ret;
}
}
+
return ret;
}
@@ -310,7 +352,7 @@ int GeneratePackageModules(
component = package_name.substr(0, dot_index);
package_name = package_name.substr(dot_index + 1);
}
- component = RubifyConstant(component);
+ component = PackageToModule(component);
printer->Print(
"module $name$\n",
"name", component);
@@ -331,8 +373,69 @@ void EndPackageModules(
}
}
-void GenerateFile(const google::protobuf::FileDescriptor* file,
- google::protobuf::io::Printer* printer) {
+bool UsesTypeFromFile(const Descriptor* message, const FileDescriptor* file,
+ string* error) {
+ for (int i = 0; i < message->field_count(); i++) {
+ const FieldDescriptor* field = message->field(i);
+ if ((field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
+ field->message_type()->file() == file) ||
+ (field->type() == FieldDescriptor::TYPE_ENUM &&
+ field->enum_type()->file() == file)) {
+ *error = "proto3 message field " + field->full_name() + " in file " +
+ file->name() + " has a dependency on a type from proto2 file " +
+ file->name() +
+ ". Ruby doesn't support proto2 yet, so we must fail.";
+ return true;
+ }
+ }
+
+ for (int i = 0; i < message->nested_type_count(); i++) {
+ if (UsesTypeFromFile(message->nested_type(i), file, error)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+// Ruby doesn't currently support proto2. This causes a failure even for proto3
+// files that import proto2. But in some cases, the proto2 file is only being
+// imported to extend another proto2 message. The prime example is declaring
+// custom options by extending FileOptions/FieldOptions/etc.
+//
+// If the proto3 messages don't have any proto2 submessages, it is safe to omit
+// the dependency completely. Users won't be able to use any proto2 extensions,
+// but they already couldn't because proto2 messages aren't supported.
+//
+// If/when we add proto2 support, we should remove this.
+bool MaybeEmitDependency(const FileDescriptor* import,
+ const FileDescriptor* from,
+ io::Printer* printer,
+ string* error) {
+ if (import->syntax() == FileDescriptor::SYNTAX_PROTO2) {
+ for (int i = 0; i < from->message_type_count(); i++) {
+ if (UsesTypeFromFile(from->message_type(i), import, error)) {
+ // Error text was already set by UsesTypeFromFile().
+ return false;
+ }
+ }
+
+ // Ok to omit this proto2 dependency -- so we won't print anything.
+ GOOGLE_LOG(WARNING) << "Omitting proto2 dependency '" << import->name()
+ << "' from proto3 output file '"
+ << GetOutputFilename(from->name())
+ << "' because we don't support proto2 and no proto2 "
+ "types from that file are being used.";
+ return true;
+ } else {
+ printer->Print(
+ "require '$name$'\n", "name", GetRequireName(import->name()));
+ return true;
+ }
+}
+
+bool GenerateFile(const FileDescriptor* file, io::Printer* printer,
+ string* error) {
printer->Print(
"# Generated by the protocol buffer compiler. DO NOT EDIT!\n"
"# source: $filename$\n"
@@ -343,9 +446,9 @@ void GenerateFile(const google::protobuf::FileDescriptor* file,
"require 'google/protobuf'\n\n");
for (int i = 0; i < file->dependency_count(); i++) {
- const std::string& name = file->dependency(i)->name();
- printer->Print(
- "require '$name$'\n", "name", StripDotProto(name));
+ if (!MaybeEmitDependency(file->dependency(i), file, printer, error)) {
+ return false;
+ }
}
printer->Print(
@@ -369,6 +472,7 @@ void GenerateFile(const google::protobuf::FileDescriptor* file,
GenerateEnumAssignment("", file->enum_type(i), printer);
}
EndPackageModules(levels, printer);
+ return true;
}
bool Generator::Generate(
@@ -384,15 +488,11 @@ bool Generator::Generate(
return false;
}
- std::string filename =
- StripDotProto(file->name()) + ".rb";
scoped_ptr<io::ZeroCopyOutputStream> output(
- generator_context->Open(filename));
+ generator_context->Open(GetOutputFilename(file->name())));
io::Printer printer(output.get(), '$');
- GenerateFile(file, &printer);
-
- return true;
+ return GenerateFile(file, &printer, error);
}
} // namespace ruby
diff --git a/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc b/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc
index 1b04cb32..1aabe8aa 100644
--- a/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc
+++ b/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc
@@ -45,22 +45,8 @@ namespace compiler {
namespace ruby {
namespace {
-string FindRubyTestDir(const string& file) {
- // Inspired by TestSourceDir() in src/google/protobuf/testing/googletest.cc.
-#ifndef GOOGLE_THIRD_PARTY_PROTOBUF
- string prefix = ".";
- while (!File::Exists(prefix + "/src/google/protobuf/compiler/ruby" + file)) {
- if (!File::Exists(prefix)) {
- GOOGLE_LOG(FATAL)
- << "Could not find Ruby test directory. Please run tests from "
- "somewhere within the protobuf source package.";
- }
- prefix += "/..";
- }
- return prefix + "/src/google/protobuf/compiler/ruby";
-#else
- return "third_party/protobuf/src/google/protobuf/compiler/ruby";
-#endif // GOOGLE_THIRD_PARTY_PROTOBUF
+string FindRubyTestDir() {
+ return TestSourceDir() + "/google/protobuf/compiler/ruby";
}
// This test is a simple golden-file test over the output of the Ruby code
@@ -71,7 +57,7 @@ string FindRubyTestDir(const string& file) {
// extensions to the point where we can do this test in a more automated way.
TEST(RubyGeneratorTest, GeneratorTest) {
- string ruby_tests = FindRubyTestDir("/ruby_generated_code.proto");
+ string ruby_tests = FindRubyTestDir();
google::protobuf::compiler::CommandLineInterface cli;
cli.SetInputsAreProtoPathRelative(true);
@@ -105,12 +91,12 @@ TEST(RubyGeneratorTest, GeneratorTest) {
// Load the generated output and compare to the expected result.
string output;
GOOGLE_CHECK_OK(File::GetContents(
- TestTempDir() + "/ruby_generated_code.rb",
+ TestTempDir() + "/ruby_generated_code_pb.rb",
&output,
true));
string expected_output;
GOOGLE_CHECK_OK(File::GetContents(
- ruby_tests + "/ruby_generated_code.rb",
+ ruby_tests + "/ruby_generated_code_pb.rb",
&expected_output,
true));
EXPECT_EQ(expected_output, output);
diff --git a/src/google/protobuf/compiler/subprocess.cc b/src/google/protobuf/compiler/subprocess.cc
index 85429924..6e258664 100644
--- a/src/google/protobuf/compiler/subprocess.cc
+++ b/src/google/protobuf/compiler/subprocess.cc
@@ -47,6 +47,7 @@
#include <google/protobuf/message.h>
#include <google/protobuf/stubs/substitute.h>
+
namespace google {
namespace protobuf {
namespace compiler {
@@ -360,7 +361,7 @@ bool Subprocess::Communicate(const Message& input, Message* output,
string output_data;
int input_pos = 0;
- int max_fd = max(child_stdin_, child_stdout_);
+ int max_fd = std::max(child_stdin_, child_stdout_);
while (child_stdout_ != -1) {
fd_set read_fds;
diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc
index 9a1c6fe8..9b20946c 100644
--- a/src/google/protobuf/descriptor.cc
+++ b/src/google/protobuf/descriptor.cc
@@ -357,13 +357,20 @@ void DeleteAllowedProto3Extendee() {
void InitAllowedProto3Extendee() {
allowed_proto3_extendees_ = new set<string>;
- allowed_proto3_extendees_->insert("google.protobuf.FileOptions");
- allowed_proto3_extendees_->insert("google.protobuf.MessageOptions");
- allowed_proto3_extendees_->insert("google.protobuf.FieldOptions");
- allowed_proto3_extendees_->insert("google.protobuf.EnumOptions");
- allowed_proto3_extendees_->insert("google.protobuf.EnumValueOptions");
- allowed_proto3_extendees_->insert("google.protobuf.ServiceOptions");
- allowed_proto3_extendees_->insert("google.protobuf.MethodOptions");
+ const char* kOptionNames[] = {
+ "FileOptions", "MessageOptions", "FieldOptions", "EnumOptions",
+ "EnumValueOptions", "ServiceOptions", "MethodOptions"};
+ for (int i = 0; i < GOOGLE_ARRAYSIZE(kOptionNames); ++i) {
+ // descriptor.proto has a different package name in opensource. We allow
+ // both so the opensource protocol compiler can also compile internal
+ // proto3 files with custom options. See: b/27567912
+ allowed_proto3_extendees_->insert(string("google.protobuf.") +
+ kOptionNames[i]);
+ // Split the word to trick the opensource processing scripts so they
+ // will keep the origial package name.
+ allowed_proto3_extendees_->insert(string("proto") + "2." + kOptionNames[i]);
+ }
+
google::protobuf::internal::OnShutdown(&DeleteAllowedProto3Extendee);
}
@@ -560,7 +567,7 @@ class FileDescriptorTables {
~FileDescriptorTables();
// Empty table, used with placeholder files.
- static const FileDescriptorTables kEmpty;
+ inline static const FileDescriptorTables& GetEmptyInstance();
// -----------------------------------------------------------------
// Finding items.
@@ -665,7 +672,32 @@ FileDescriptorTables::FileDescriptorTables()
FileDescriptorTables::~FileDescriptorTables() {}
-const FileDescriptorTables FileDescriptorTables::kEmpty;
+namespace {
+
+FileDescriptorTables* file_descriptor_tables_ = NULL;
+GOOGLE_PROTOBUF_DECLARE_ONCE(file_descriptor_tables_once_init_);
+
+void DeleteFileDescriptorTables() {
+ delete file_descriptor_tables_;
+ file_descriptor_tables_ = NULL;
+}
+
+void InitFileDescriptorTables() {
+ file_descriptor_tables_ = new FileDescriptorTables();
+ internal::OnShutdown(&DeleteFileDescriptorTables);
+}
+
+inline void InitFileDescriptorTablesOnce() {
+ ::google::protobuf::GoogleOnceInit(
+ &file_descriptor_tables_once_init_, &InitFileDescriptorTables);
+}
+
+} // anonymous namespace
+
+inline const FileDescriptorTables& FileDescriptorTables::GetEmptyInstance() {
+ InitFileDescriptorTablesOnce();
+ return *file_descriptor_tables_;
+}
void DescriptorPool::Tables::AddCheckpoint() {
checkpoints_.push_back(CheckPoint(this));
@@ -1864,6 +1896,9 @@ void FieldDescriptor::CopyJsonNameTo(FieldDescriptorProto* proto) const {
void OneofDescriptor::CopyTo(OneofDescriptorProto* proto) const {
proto->set_name(name());
+ if (&options() != &OneofOptions::default_instance()) {
+ proto->mutable_options()->CopyFrom(options());
+ }
}
void EnumDescriptor::CopyTo(EnumDescriptorProto* proto) const {
@@ -2050,6 +2085,7 @@ class SourceLocationCommentPrinter {
}
private:
+
bool have_source_loc_;
SourceLocation source_loc_;
DebugStringOptions options_;
@@ -2402,6 +2438,9 @@ void OneofDescriptor::DebugString(int depth, string* contents,
comment_printer.AddPreComment(contents);
strings::SubstituteAndAppend(
contents, "$0 oneof $1 {", prefix, name());
+
+ FormatLineOptions(depth, options(), contents);
+
if (debug_string_options.elide_oneof_body) {
contents->append(" ... }\n");
} else {
@@ -2740,6 +2779,9 @@ class DescriptorBuilder {
private:
friend class OptionInterpreter;
+ // Non-recursive part of BuildFile functionality.
+ const FileDescriptor* BuildFileImpl(const FileDescriptorProto& proto);
+
const DescriptorPool* pool_;
DescriptorPool::Tables* tables_; // for convenience
DescriptorPool::ErrorCollector* error_collector_;
@@ -2951,7 +2993,8 @@ class DescriptorBuilder {
const ServiceDescriptor* parent,
MethodDescriptor* result);
- void LogUnusedDependency(const FileDescriptor* result);
+ void LogUnusedDependency(const FileDescriptorProto& proto,
+ const FileDescriptor* result);
// Must be run only after building.
//
@@ -3535,7 +3578,7 @@ FileDescriptor* DescriptorBuilder::NewPlaceholderFile(
placeholder->package_ = &internal::GetEmptyString();
placeholder->pool_ = pool_;
placeholder->options_ = &FileOptions::default_instance();
- placeholder->tables_ = &FileDescriptorTables::kEmpty;
+ placeholder->tables_ = &FileDescriptorTables::GetEmptyInstance();
placeholder->source_code_info_ = &SourceCodeInfo::default_instance();
placeholder->is_placeholder_ = true;
placeholder->syntax_ = FileDescriptor::SYNTAX_PROTO2;
@@ -3807,7 +3850,11 @@ const FileDescriptor* DescriptorBuilder::BuildFile(
}
tables_->pending_files_.pop_back();
}
+ return BuildFileImpl(proto);
+}
+const FileDescriptor* DescriptorBuilder::BuildFileImpl(
+ const FileDescriptorProto& proto) {
// Checkpoint the tables so that we can roll back if something goes wrong.
tables_->AddCheckpoint();
@@ -3996,7 +4043,7 @@ const FileDescriptor* DescriptorBuilder::BuildFile(
if (!unused_dependency_.empty()) {
- LogUnusedDependency(result);
+ LogUnusedDependency(proto, result);
}
if (had_errors_) {
@@ -4143,6 +4190,7 @@ void DescriptorBuilder::BuildMessage(const DescriptorProto& proto,
}
}
+
void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto,
const Descriptor* parent,
FieldDescriptor* result,
@@ -4248,8 +4296,8 @@ void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto,
} else if (proto.default_value() == "nan") {
result->default_value_float_ = numeric_limits<float>::quiet_NaN();
} else {
- result->default_value_float_ =
- io::NoLocaleStrtod(proto.default_value().c_str(), &end_pos);
+ result->default_value_float_ = io::SafeDoubleToFloat(
+ io::NoLocaleStrtod(proto.default_value().c_str(), &end_pos));
}
break;
case FieldDescriptor::CPPTYPE_DOUBLE:
@@ -4421,6 +4469,7 @@ void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto,
AllocateOptions(proto.options(), result);
}
+
AddSymbol(result->full_name(), parent, result->name(),
proto, Symbol(result));
}
@@ -4480,6 +4529,13 @@ void DescriptorBuilder::BuildOneof(const OneofDescriptorProto& proto,
result->field_count_ = 0;
result->fields_ = NULL;
+ // Copy options.
+ if (!proto.has_options()) {
+ result->options_ = NULL; // Will set to default_instance later.
+ } else {
+ AllocateOptions(proto.options(), result);
+ }
+
AddSymbol(result->full_name(), parent, result->name(),
proto, Symbol(result));
}
@@ -4740,6 +4796,10 @@ void DescriptorBuilder::CrossLinkMessage(
oneof_decl->fields_ =
tables_->AllocateArray<const FieldDescriptor*>(oneof_decl->field_count_);
oneof_decl->field_count_ = 0;
+
+ if (oneof_decl->options_ == NULL) {
+ oneof_decl->options_ = &OneofOptions::default_instance();
+ }
}
// Then fill them in.
@@ -5084,11 +5144,6 @@ void DescriptorBuilder::ValidateProto3(
for (int i = 0; i < file->enum_type_count(); ++i) {
ValidateProto3Enum(file->enum_types_ + i, proto.enum_type(i));
}
- if (IsLite(file)) {
- AddError(file->name(), proto,
- DescriptorPool::ErrorCollector::OTHER,
- "Lite runtime is not supported in proto3.");
- }
}
static string ToLowercaseWithoutUnderscores(const string& name) {
@@ -5143,7 +5198,7 @@ void DescriptorBuilder::ValidateProto3Message(
if (name_to_field.find(lowercase_name) != name_to_field.end()) {
AddError(message->full_name(), proto,
DescriptorPool::ErrorCollector::OTHER,
- "The JSON camcel-case name of field \"" +
+ "The JSON camel-case name of field \"" +
message->field(i)->name() + "\" conflicts with field \"" +
name_to_field[lowercase_name]->name() + "\". This is not " +
"allowed in proto3.");
@@ -5199,6 +5254,7 @@ void DescriptorBuilder::ValidateProto3Enum(
}
}
+
void DescriptorBuilder::ValidateMessageOptions(Descriptor* message,
const DescriptorProto& proto) {
VALIDATE_OPTIONS_FROM_ARRAY(message, field, Field);
@@ -5219,6 +5275,7 @@ void DescriptorBuilder::ValidateMessageOptions(Descriptor* message,
max_extension_range));
}
}
+
}
void DescriptorBuilder::ValidateFieldOptions(FieldDescriptor* field,
@@ -5533,11 +5590,19 @@ bool DescriptorBuilder::OptionInterpreter::InterpretOptions(
// UnknownFieldSet and wait there until the message is parsed by something
// that does know about the options.
string buf;
- options->AppendToString(&buf);
- GOOGLE_CHECK(options->ParseFromString(buf))
+ GOOGLE_CHECK(options->AppendPartialToString(&buf))
+ << "Protocol message could not be serialized.";
+ GOOGLE_CHECK(options->ParsePartialFromString(buf))
<< "Protocol message serialized itself in invalid fashion.";
+ if (!options->IsInitialized()) {
+ builder_->AddWarning(
+ options_to_interpret->element_name, *original_options,
+ DescriptorPool::ErrorCollector::OTHER,
+ "Options could not be fully parsed using the proto descriptors "
+ "compiled into this binary. Missing required fields: " +
+ options->InitializationErrorString());
+ }
}
-
return !failed;
}
@@ -6191,7 +6256,8 @@ void DescriptorBuilder::OptionInterpreter::SetUInt64(int number, uint64 value,
}
}
-void DescriptorBuilder::LogUnusedDependency(const FileDescriptor* result) {
+void DescriptorBuilder::LogUnusedDependency(const FileDescriptorProto& proto,
+ const FileDescriptor* result) {
if (!unused_dependency_.empty()) {
std::set<string> annotation_extensions;
@@ -6217,9 +6283,9 @@ void DescriptorBuilder::LogUnusedDependency(const FileDescriptor* result) {
}
// Log warnings for unused imported files.
if (i == (*it)->extension_count()) {
- GOOGLE_LOG(WARNING) << "Warning: Unused import: \"" << result->name()
- << "\" imports \"" << (*it)->name()
- << "\" which is not used.";
+ string error_message = "Import " + (*it)->name() + " but not used.";
+ AddWarning((*it)->name(), proto, DescriptorPool::ErrorCollector::OTHER,
+ error_message);
}
}
}
diff --git a/src/google/protobuf/descriptor.h b/src/google/protobuf/descriptor.h
index e7e8c6af..b040b62c 100644
--- a/src/google/protobuf/descriptor.h
+++ b/src/google/protobuf/descriptor.h
@@ -62,7 +62,6 @@
#include <string>
#include <vector>
#include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/scoped_ptr.h>
// TYPE_BOOL is defined in the MacOS's ConditionalMacros.h.
#ifdef TYPE_BOOL
@@ -95,6 +94,7 @@ class MethodDescriptorProto;
class FileDescriptorProto;
class MessageOptions;
class FieldOptions;
+class OneofOptions;
class EnumOptions;
class EnumValueOptions;
class ServiceOptions;
@@ -127,6 +127,11 @@ namespace descriptor_unittest {
class DescriptorTest;
} // namespace descriptor_unittest
+// Defined in printer.h
+namespace io {
+class Printer;
+} // namespace io
+
// NB, all indices are zero-based.
struct SourceLocation {
int start_line;
@@ -359,6 +364,9 @@ class LIBPROTOBUF_EXPORT Descriptor {
// Allows tests to test CopyTo(proto, true).
friend class ::google::protobuf::descriptor_unittest::DescriptorTest;
+ // Allows access to GetLocationPath for annotations.
+ friend class ::google::protobuf::io::Printer;
+
// Fill the json_name field of FieldDescriptorProto.
void CopyJsonNameTo(DescriptorProto* proto) const;
@@ -644,6 +652,9 @@ class LIBPROTOBUF_EXPORT FieldDescriptor {
private:
typedef FieldOptions OptionsType;
+ // Allows access to GetLocationPath for annotations.
+ friend class ::google::protobuf::io::Printer;
+
// Fill the json_name field of FieldDescriptorProto.
void CopyJsonNameTo(FieldDescriptorProto* proto) const;
@@ -739,6 +750,8 @@ class LIBPROTOBUF_EXPORT OneofDescriptor {
// .proto file. Does not include extensions.
const FieldDescriptor* field(int index) const;
+ const OneofOptions& options() const;
+
// See Descriptor::CopyTo().
void CopyTo(OneofDescriptorProto* proto) const;
@@ -756,6 +769,11 @@ class LIBPROTOBUF_EXPORT OneofDescriptor {
bool GetSourceLocation(SourceLocation* out_location) const;
private:
+ typedef OneofOptions OptionsType;
+
+ // Allows access to GetLocationPath for annotations.
+ friend class ::google::protobuf::io::Printer;
+
// See Descriptor::DebugString().
void DebugString(int depth, string* contents,
const DebugStringOptions& options) const;
@@ -770,6 +788,8 @@ class LIBPROTOBUF_EXPORT OneofDescriptor {
bool is_extendable_;
int field_count_;
const FieldDescriptor** fields_;
+ const OneofOptions* options_;
+
// IMPORTANT: If you add a new field, make sure to search for all instances
// of Allocate<OneofDescriptor>() and AllocateArray<OneofDescriptor>()
// in descriptor.cc and update them to initialize the field.
@@ -846,6 +866,9 @@ class LIBPROTOBUF_EXPORT EnumDescriptor {
private:
typedef EnumOptions OptionsType;
+ // Allows access to GetLocationPath for annotations.
+ friend class ::google::protobuf::io::Printer;
+
// Looks up a value by number. If the value does not exist, dynamically
// creates a new EnumValueDescriptor for that value, assuming that it was
// unknown. If a new descriptor is created, this is done in a thread-safe way,
@@ -942,6 +965,9 @@ class LIBPROTOBUF_EXPORT EnumValueDescriptor {
private:
typedef EnumValueOptions OptionsType;
+ // Allows access to GetLocationPath for annotations.
+ friend class ::google::protobuf::io::Printer;
+
// See Descriptor::DebugString().
void DebugString(int depth, string *contents,
const DebugStringOptions& options) const;
@@ -1018,6 +1044,9 @@ class LIBPROTOBUF_EXPORT ServiceDescriptor {
private:
typedef ServiceOptions OptionsType;
+ // Allows access to GetLocationPath for annotations.
+ friend class ::google::protobuf::io::Printer;
+
// See Descriptor::DebugString().
void DebugString(string *contents, const DebugStringOptions& options) const;
@@ -1096,6 +1125,9 @@ class LIBPROTOBUF_EXPORT MethodDescriptor {
private:
typedef MethodOptions OptionsType;
+ // Allows access to GetLocationPath for annotations.
+ friend class ::google::protobuf::io::Printer;
+
// See Descriptor::DebugString().
void DebugString(int depth, string *contents,
const DebugStringOptions& options) const;
@@ -1645,7 +1677,7 @@ PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, reserved_range,
const Descriptor::ReservedRange*)
PROTOBUF_DEFINE_ACCESSOR(Descriptor, reserved_name_count, int)
-PROTOBUF_DEFINE_OPTIONS_ACCESSOR(Descriptor, MessageOptions);
+PROTOBUF_DEFINE_OPTIONS_ACCESSOR(Descriptor, MessageOptions)
PROTOBUF_DEFINE_ACCESSOR(Descriptor, is_placeholder, bool)
PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, name)
@@ -1682,6 +1714,7 @@ PROTOBUF_DEFINE_STRING_ACCESSOR(OneofDescriptor, name)
PROTOBUF_DEFINE_STRING_ACCESSOR(OneofDescriptor, full_name)
PROTOBUF_DEFINE_ACCESSOR(OneofDescriptor, containing_type, const Descriptor*)
PROTOBUF_DEFINE_ACCESSOR(OneofDescriptor, field_count, int)
+PROTOBUF_DEFINE_OPTIONS_ACCESSOR(OneofDescriptor, OneofOptions)
PROTOBUF_DEFINE_STRING_ACCESSOR(EnumDescriptor, name)
PROTOBUF_DEFINE_STRING_ACCESSOR(EnumDescriptor, full_name)
@@ -1690,7 +1723,7 @@ PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, containing_type, const Descriptor*)
PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, value_count, int)
PROTOBUF_DEFINE_ARRAY_ACCESSOR(EnumDescriptor, value,
const EnumValueDescriptor*)
-PROTOBUF_DEFINE_OPTIONS_ACCESSOR(EnumDescriptor, EnumOptions);
+PROTOBUF_DEFINE_OPTIONS_ACCESSOR(EnumDescriptor, EnumOptions)
PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, is_placeholder, bool)
PROTOBUF_DEFINE_STRING_ACCESSOR(EnumValueDescriptor, name)
@@ -1705,14 +1738,14 @@ PROTOBUF_DEFINE_ACCESSOR(ServiceDescriptor, file, const FileDescriptor*)
PROTOBUF_DEFINE_ACCESSOR(ServiceDescriptor, method_count, int)
PROTOBUF_DEFINE_ARRAY_ACCESSOR(ServiceDescriptor, method,
const MethodDescriptor*)
-PROTOBUF_DEFINE_OPTIONS_ACCESSOR(ServiceDescriptor, ServiceOptions);
+PROTOBUF_DEFINE_OPTIONS_ACCESSOR(ServiceDescriptor, ServiceOptions)
PROTOBUF_DEFINE_STRING_ACCESSOR(MethodDescriptor, name)
PROTOBUF_DEFINE_STRING_ACCESSOR(MethodDescriptor, full_name)
PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, service, const ServiceDescriptor*)
PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, input_type, const Descriptor*)
PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, output_type, const Descriptor*)
-PROTOBUF_DEFINE_OPTIONS_ACCESSOR(MethodDescriptor, MethodOptions);
+PROTOBUF_DEFINE_OPTIONS_ACCESSOR(MethodDescriptor, MethodOptions)
PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, client_streaming, bool)
PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, server_streaming, bool)
@@ -1726,7 +1759,7 @@ PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, message_type_count, int)
PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, enum_type_count, int)
PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, service_count, int)
PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, extension_count, int)
-PROTOBUF_DEFINE_OPTIONS_ACCESSOR(FileDescriptor, FileOptions);
+PROTOBUF_DEFINE_OPTIONS_ACCESSOR(FileDescriptor, FileOptions)
PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, is_placeholder, bool)
PROTOBUF_DEFINE_ARRAY_ACCESSOR(FileDescriptor, message_type, const Descriptor*)
diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc
index bc846609..0028c708 100644
--- a/src/google/protobuf/descriptor.pb.cc
+++ b/src/google/protobuf/descriptor.pb.cc
@@ -7,6 +7,7 @@
#include <algorithm>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/port.h>
#include <google/protobuf/stubs/once.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/wire_format_lite_inl.h>
@@ -68,6 +69,9 @@ const ::google::protobuf::internal::GeneratedMessageReflection*
FieldOptions_reflection_ = NULL;
const ::google::protobuf::EnumDescriptor* FieldOptions_CType_descriptor_ = NULL;
const ::google::protobuf::EnumDescriptor* FieldOptions_JSType_descriptor_ = NULL;
+const ::google::protobuf::Descriptor* OneofOptions_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+ OneofOptions_reflection_ = NULL;
const ::google::protobuf::Descriptor* EnumOptions_descriptor_ = NULL;
const ::google::protobuf::internal::GeneratedMessageReflection*
EnumOptions_reflection_ = NULL;
@@ -92,10 +96,17 @@ const ::google::protobuf::internal::GeneratedMessageReflection*
const ::google::protobuf::Descriptor* SourceCodeInfo_Location_descriptor_ = NULL;
const ::google::protobuf::internal::GeneratedMessageReflection*
SourceCodeInfo_Location_reflection_ = NULL;
+const ::google::protobuf::Descriptor* GeneratedCodeInfo_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+ GeneratedCodeInfo_reflection_ = NULL;
+const ::google::protobuf::Descriptor* GeneratedCodeInfo_Annotation_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+ GeneratedCodeInfo_Annotation_reflection_ = NULL;
} // namespace
+void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
const ::google::protobuf::FileDescriptor* file =
@@ -226,8 +237,9 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
FieldDescriptorProto_Type_descriptor_ = FieldDescriptorProto_descriptor_->enum_type(0);
FieldDescriptorProto_Label_descriptor_ = FieldDescriptorProto_descriptor_->enum_type(1);
OneofDescriptorProto_descriptor_ = file->message_type(4);
- static const int OneofDescriptorProto_offsets_[1] = {
+ static const int OneofDescriptorProto_offsets_[2] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(OneofDescriptorProto, name_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(OneofDescriptorProto, options_),
};
OneofDescriptorProto_reflection_ =
::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
@@ -312,7 +324,7 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, _internal_metadata_),
-1);
FileOptions_descriptor_ = file->message_type(9);
- static const int FileOptions_offsets_[16] = {
+ static const int FileOptions_offsets_[15] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_package_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_outer_classname_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_multiple_files_),
@@ -327,7 +339,6 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, cc_enable_arenas_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, objc_class_prefix_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, csharp_namespace_),
- GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, javanano_use_deprecated_package_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, uninterpreted_option_),
};
FileOptions_reflection_ =
@@ -384,7 +395,22 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
-1);
FieldOptions_CType_descriptor_ = FieldOptions_descriptor_->enum_type(0);
FieldOptions_JSType_descriptor_ = FieldOptions_descriptor_->enum_type(1);
- EnumOptions_descriptor_ = file->message_type(12);
+ OneofOptions_descriptor_ = file->message_type(12);
+ static const int OneofOptions_offsets_[1] = {
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(OneofOptions, uninterpreted_option_),
+ };
+ OneofOptions_reflection_ =
+ ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
+ OneofOptions_descriptor_,
+ OneofOptions::default_instance_,
+ OneofOptions_offsets_,
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(OneofOptions, _has_bits_[0]),
+ -1,
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(OneofOptions, _extensions_),
+ sizeof(OneofOptions),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(OneofOptions, _internal_metadata_),
+ -1);
+ EnumOptions_descriptor_ = file->message_type(13);
static const int EnumOptions_offsets_[3] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, allow_alias_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, deprecated_),
@@ -401,7 +427,7 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
sizeof(EnumOptions),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, _internal_metadata_),
-1);
- EnumValueOptions_descriptor_ = file->message_type(13);
+ EnumValueOptions_descriptor_ = file->message_type(14);
static const int EnumValueOptions_offsets_[2] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, deprecated_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, uninterpreted_option_),
@@ -417,7 +443,7 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
sizeof(EnumValueOptions),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, _internal_metadata_),
-1);
- ServiceOptions_descriptor_ = file->message_type(14);
+ ServiceOptions_descriptor_ = file->message_type(15);
static const int ServiceOptions_offsets_[2] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, deprecated_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, uninterpreted_option_),
@@ -433,7 +459,7 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
sizeof(ServiceOptions),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, _internal_metadata_),
-1);
- MethodOptions_descriptor_ = file->message_type(15);
+ MethodOptions_descriptor_ = file->message_type(16);
static const int MethodOptions_offsets_[2] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, deprecated_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, uninterpreted_option_),
@@ -449,7 +475,7 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
sizeof(MethodOptions),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, _internal_metadata_),
-1);
- UninterpretedOption_descriptor_ = file->message_type(16);
+ UninterpretedOption_descriptor_ = file->message_type(17);
static const int UninterpretedOption_offsets_[7] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, name_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, identifier_value_),
@@ -486,7 +512,7 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
sizeof(UninterpretedOption_NamePart),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption_NamePart, _internal_metadata_),
-1);
- SourceCodeInfo_descriptor_ = file->message_type(17);
+ SourceCodeInfo_descriptor_ = file->message_type(18);
static const int SourceCodeInfo_offsets_[1] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo, location_),
};
@@ -520,6 +546,39 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
sizeof(SourceCodeInfo_Location),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, _internal_metadata_),
-1);
+ GeneratedCodeInfo_descriptor_ = file->message_type(19);
+ static const int GeneratedCodeInfo_offsets_[1] = {
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(GeneratedCodeInfo, annotation_),
+ };
+ GeneratedCodeInfo_reflection_ =
+ ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
+ GeneratedCodeInfo_descriptor_,
+ GeneratedCodeInfo::default_instance_,
+ GeneratedCodeInfo_offsets_,
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(GeneratedCodeInfo, _has_bits_[0]),
+ -1,
+ -1,
+ sizeof(GeneratedCodeInfo),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(GeneratedCodeInfo, _internal_metadata_),
+ -1);
+ GeneratedCodeInfo_Annotation_descriptor_ = GeneratedCodeInfo_descriptor_->nested_type(0);
+ static const int GeneratedCodeInfo_Annotation_offsets_[4] = {
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(GeneratedCodeInfo_Annotation, path_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(GeneratedCodeInfo_Annotation, source_file_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(GeneratedCodeInfo_Annotation, begin_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(GeneratedCodeInfo_Annotation, end_),
+ };
+ GeneratedCodeInfo_Annotation_reflection_ =
+ ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
+ GeneratedCodeInfo_Annotation_descriptor_,
+ GeneratedCodeInfo_Annotation::default_instance_,
+ GeneratedCodeInfo_Annotation_offsets_,
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(GeneratedCodeInfo_Annotation, _has_bits_[0]),
+ -1,
+ -1,
+ sizeof(GeneratedCodeInfo_Annotation),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(GeneratedCodeInfo_Annotation, _internal_metadata_),
+ -1);
}
namespace {
@@ -530,6 +589,7 @@ inline void protobuf_AssignDescriptorsOnce() {
&protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto);
}
+void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
void protobuf_RegisterTypes(const ::std::string&) {
protobuf_AssignDescriptorsOnce();
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
@@ -561,6 +621,8 @@ void protobuf_RegisterTypes(const ::std::string&) {
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
FieldOptions_descriptor_, &FieldOptions::default_instance());
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+ OneofOptions_descriptor_, &OneofOptions::default_instance());
+ ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
EnumOptions_descriptor_, &EnumOptions::default_instance());
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
EnumValueOptions_descriptor_, &EnumValueOptions::default_instance());
@@ -576,6 +638,10 @@ void protobuf_RegisterTypes(const ::std::string&) {
SourceCodeInfo_descriptor_, &SourceCodeInfo::default_instance());
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
SourceCodeInfo_Location_descriptor_, &SourceCodeInfo_Location::default_instance());
+ ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+ GeneratedCodeInfo_descriptor_, &GeneratedCodeInfo::default_instance());
+ ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+ GeneratedCodeInfo_Annotation_descriptor_, &GeneratedCodeInfo_Annotation::default_instance());
}
} // namespace
@@ -609,6 +675,8 @@ void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto() {
delete MessageOptions_reflection_;
delete FieldOptions::default_instance_;
delete FieldOptions_reflection_;
+ delete OneofOptions::default_instance_;
+ delete OneofOptions_reflection_;
delete EnumOptions::default_instance_;
delete EnumOptions_reflection_;
delete EnumValueOptions::default_instance_;
@@ -625,8 +693,13 @@ void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto() {
delete SourceCodeInfo_reflection_;
delete SourceCodeInfo_Location::default_instance_;
delete SourceCodeInfo_Location_reflection_;
+ delete GeneratedCodeInfo::default_instance_;
+ delete GeneratedCodeInfo_reflection_;
+ delete GeneratedCodeInfo_Annotation::default_instance_;
+ delete GeneratedCodeInfo_Annotation_reflection_;
}
+void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() {
static bool already_here = false;
if (already_here) return;
@@ -682,84 +755,91 @@ void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() {
"SFIXED32\020\017\022\021\n\rTYPE_SFIXED64\020\020\022\017\n\013TYPE_SI"
"NT32\020\021\022\017\n\013TYPE_SINT64\020\022\"C\n\005Label\022\022\n\016LABE"
"L_OPTIONAL\020\001\022\022\n\016LABEL_REQUIRED\020\002\022\022\n\016LABE"
- "L_REPEATED\020\003\"$\n\024OneofDescriptorProto\022\014\n\004"
- "name\030\001 \001(\t\"\214\001\n\023EnumDescriptorProto\022\014\n\004na"
- "me\030\001 \001(\t\0228\n\005value\030\002 \003(\0132).google.protobu"
- "f.EnumValueDescriptorProto\022-\n\007options\030\003 "
- "\001(\0132\034.google.protobuf.EnumOptions\"l\n\030Enu"
- "mValueDescriptorProto\022\014\n\004name\030\001 \001(\t\022\016\n\006n"
- "umber\030\002 \001(\005\0222\n\007options\030\003 \001(\0132!.google.pr"
- "otobuf.EnumValueOptions\"\220\001\n\026ServiceDescr"
- "iptorProto\022\014\n\004name\030\001 \001(\t\0226\n\006method\030\002 \003(\013"
- "2&.google.protobuf.MethodDescriptorProto"
- "\0220\n\007options\030\003 \001(\0132\037.google.protobuf.Serv"
- "iceOptions\"\301\001\n\025MethodDescriptorProto\022\014\n\004"
- "name\030\001 \001(\t\022\022\n\ninput_type\030\002 \001(\t\022\023\n\013output"
- "_type\030\003 \001(\t\022/\n\007options\030\004 \001(\0132\036.google.pr"
- "otobuf.MethodOptions\022\037\n\020client_streaming"
- "\030\005 \001(\010:\005false\022\037\n\020server_streaming\030\006 \001(\010:"
- "\005false\"\252\005\n\013FileOptions\022\024\n\014java_package\030\001"
- " \001(\t\022\034\n\024java_outer_classname\030\010 \001(\t\022\"\n\023ja"
- "va_multiple_files\030\n \001(\010:\005false\022,\n\035java_g"
- "enerate_equals_and_hash\030\024 \001(\010:\005false\022%\n\026"
- "java_string_check_utf8\030\033 \001(\010:\005false\022F\n\014o"
- "ptimize_for\030\t \001(\0162).google.protobuf.File"
- "Options.OptimizeMode:\005SPEED\022\022\n\ngo_packag"
- "e\030\013 \001(\t\022\"\n\023cc_generic_services\030\020 \001(\010:\005fa"
- "lse\022$\n\025java_generic_services\030\021 \001(\010:\005fals"
- "e\022\"\n\023py_generic_services\030\022 \001(\010:\005false\022\031\n"
- "\ndeprecated\030\027 \001(\010:\005false\022\037\n\020cc_enable_ar"
- "enas\030\037 \001(\010:\005false\022\031\n\021objc_class_prefix\030$"
- " \001(\t\022\030\n\020csharp_namespace\030% \001(\t\022\'\n\037javana"
- "no_use_deprecated_package\030& \001(\010\022C\n\024unint"
- "erpreted_option\030\347\007 \003(\0132$.google.protobuf"
- ".UninterpretedOption\":\n\014OptimizeMode\022\t\n\005"
- "SPEED\020\001\022\r\n\tCODE_SIZE\020\002\022\020\n\014LITE_RUNTIME\020\003"
- "*\t\010\350\007\020\200\200\200\200\002\"\346\001\n\016MessageOptions\022&\n\027messag"
- "e_set_wire_format\030\001 \001(\010:\005false\022.\n\037no_sta"
- "ndard_descriptor_accessor\030\002 \001(\010:\005false\022\031"
- "\n\ndeprecated\030\003 \001(\010:\005false\022\021\n\tmap_entry\030\007"
- " \001(\010\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.go"
+ "L_REPEATED\020\003\"T\n\024OneofDescriptorProto\022\014\n\004"
+ "name\030\001 \001(\t\022.\n\007options\030\002 \001(\0132\035.google.pro"
+ "tobuf.OneofOptions\"\214\001\n\023EnumDescriptorPro"
+ "to\022\014\n\004name\030\001 \001(\t\0228\n\005value\030\002 \003(\0132).google"
+ ".protobuf.EnumValueDescriptorProto\022-\n\007op"
+ "tions\030\003 \001(\0132\034.google.protobuf.EnumOption"
+ "s\"l\n\030EnumValueDescriptorProto\022\014\n\004name\030\001 "
+ "\001(\t\022\016\n\006number\030\002 \001(\005\0222\n\007options\030\003 \001(\0132!.g"
+ "oogle.protobuf.EnumValueOptions\"\220\001\n\026Serv"
+ "iceDescriptorProto\022\014\n\004name\030\001 \001(\t\0226\n\006meth"
+ "od\030\002 \003(\0132&.google.protobuf.MethodDescrip"
+ "torProto\0220\n\007options\030\003 \001(\0132\037.google.proto"
+ "buf.ServiceOptions\"\301\001\n\025MethodDescriptorP"
+ "roto\022\014\n\004name\030\001 \001(\t\022\022\n\ninput_type\030\002 \001(\t\022\023"
+ "\n\013output_type\030\003 \001(\t\022/\n\007options\030\004 \001(\0132\036.g"
+ "oogle.protobuf.MethodOptions\022\037\n\020client_s"
+ "treaming\030\005 \001(\010:\005false\022\037\n\020server_streamin"
+ "g\030\006 \001(\010:\005false\"\207\005\n\013FileOptions\022\024\n\014java_p"
+ "ackage\030\001 \001(\t\022\034\n\024java_outer_classname\030\010 \001"
+ "(\t\022\"\n\023java_multiple_files\030\n \001(\010:\005false\022,"
+ "\n\035java_generate_equals_and_hash\030\024 \001(\010:\005f"
+ "alse\022%\n\026java_string_check_utf8\030\033 \001(\010:\005fa"
+ "lse\022F\n\014optimize_for\030\t \001(\0162).google.proto"
+ "buf.FileOptions.OptimizeMode:\005SPEED\022\022\n\ng"
+ "o_package\030\013 \001(\t\022\"\n\023cc_generic_services\030\020"
+ " \001(\010:\005false\022$\n\025java_generic_services\030\021 \001"
+ "(\010:\005false\022\"\n\023py_generic_services\030\022 \001(\010:\005"
+ "false\022\031\n\ndeprecated\030\027 \001(\010:\005false\022\037\n\020cc_e"
+ "nable_arenas\030\037 \001(\010:\005false\022\031\n\021objc_class_"
+ "prefix\030$ \001(\t\022\030\n\020csharp_namespace\030% \001(\t\022C"
+ "\n\024uninterpreted_option\030\347\007 \003(\0132$.google.p"
+ "rotobuf.UninterpretedOption\":\n\014OptimizeM"
+ "ode\022\t\n\005SPEED\020\001\022\r\n\tCODE_SIZE\020\002\022\020\n\014LITE_RU"
+ "NTIME\020\003*\t\010\350\007\020\200\200\200\200\002J\004\010&\020\'\"\346\001\n\016MessageOpti"
+ "ons\022&\n\027message_set_wire_format\030\001 \001(\010:\005fa"
+ "lse\022.\n\037no_standard_descriptor_accessor\030\002"
+ " \001(\010:\005false\022\031\n\ndeprecated\030\003 \001(\010:\005false\022\021"
+ "\n\tmap_entry\030\007 \001(\010\022C\n\024uninterpreted_optio"
+ "n\030\347\007 \003(\0132$.google.protobuf.Uninterpreted"
+ "Option*\t\010\350\007\020\200\200\200\200\002\"\230\003\n\014FieldOptions\022:\n\005ct"
+ "ype\030\001 \001(\0162#.google.protobuf.FieldOptions"
+ ".CType:\006STRING\022\016\n\006packed\030\002 \001(\010\022\?\n\006jstype"
+ "\030\006 \001(\0162$.google.protobuf.FieldOptions.JS"
+ "Type:\tJS_NORMAL\022\023\n\004lazy\030\005 \001(\010:\005false\022\031\n\n"
+ "deprecated\030\003 \001(\010:\005false\022\023\n\004weak\030\n \001(\010:\005f"
+ "alse\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.go"
+ "ogle.protobuf.UninterpretedOption\"/\n\005CTy"
+ "pe\022\n\n\006STRING\020\000\022\010\n\004CORD\020\001\022\020\n\014STRING_PIECE"
+ "\020\002\"5\n\006JSType\022\r\n\tJS_NORMAL\020\000\022\r\n\tJS_STRING"
+ "\020\001\022\r\n\tJS_NUMBER\020\002*\t\010\350\007\020\200\200\200\200\002\"^\n\014OneofOpt"
+ "ions\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.go"
+ "ogle.protobuf.UninterpretedOption*\t\010\350\007\020\200"
+ "\200\200\200\002\"\215\001\n\013EnumOptions\022\023\n\013allow_alias\030\002 \001("
+ "\010\022\031\n\ndeprecated\030\003 \001(\010:\005false\022C\n\024uninterp"
+ "reted_option\030\347\007 \003(\0132$.google.protobuf.Un"
+ "interpretedOption*\t\010\350\007\020\200\200\200\200\002\"}\n\020EnumValu"
+ "eOptions\022\031\n\ndeprecated\030\001 \001(\010:\005false\022C\n\024u"
+ "ninterpreted_option\030\347\007 \003(\0132$.google.prot"
+ "obuf.UninterpretedOption*\t\010\350\007\020\200\200\200\200\002\"{\n\016S"
+ "erviceOptions\022\031\n\ndeprecated\030! \001(\010:\005false"
+ "\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.google"
+ ".protobuf.UninterpretedOption*\t\010\350\007\020\200\200\200\200\002"
+ "\"z\n\rMethodOptions\022\031\n\ndeprecated\030! \001(\010:\005f"
+ "alse\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.go"
"ogle.protobuf.UninterpretedOption*\t\010\350\007\020\200"
- "\200\200\200\002\"\230\003\n\014FieldOptions\022:\n\005ctype\030\001 \001(\0162#.g"
- "oogle.protobuf.FieldOptions.CType:\006STRIN"
- "G\022\016\n\006packed\030\002 \001(\010\022\?\n\006jstype\030\006 \001(\0162$.goog"
- "le.protobuf.FieldOptions.JSType:\tJS_NORM"
- "AL\022\023\n\004lazy\030\005 \001(\010:\005false\022\031\n\ndeprecated\030\003 "
- "\001(\010:\005false\022\023\n\004weak\030\n \001(\010:\005false\022C\n\024unint"
- "erpreted_option\030\347\007 \003(\0132$.google.protobuf"
- ".UninterpretedOption\"/\n\005CType\022\n\n\006STRING\020"
- "\000\022\010\n\004CORD\020\001\022\020\n\014STRING_PIECE\020\002\"5\n\006JSType\022"
- "\r\n\tJS_NORMAL\020\000\022\r\n\tJS_STRING\020\001\022\r\n\tJS_NUMB"
- "ER\020\002*\t\010\350\007\020\200\200\200\200\002\"\215\001\n\013EnumOptions\022\023\n\013allow"
- "_alias\030\002 \001(\010\022\031\n\ndeprecated\030\003 \001(\010:\005false\022"
- "C\n\024uninterpreted_option\030\347\007 \003(\0132$.google."
- "protobuf.UninterpretedOption*\t\010\350\007\020\200\200\200\200\002\""
- "}\n\020EnumValueOptions\022\031\n\ndeprecated\030\001 \001(\010:"
- "\005false\022C\n\024uninterpreted_option\030\347\007 \003(\0132$."
- "google.protobuf.UninterpretedOption*\t\010\350\007"
- "\020\200\200\200\200\002\"{\n\016ServiceOptions\022\031\n\ndeprecated\030!"
- " \001(\010:\005false\022C\n\024uninterpreted_option\030\347\007 \003"
- "(\0132$.google.protobuf.UninterpretedOption"
- "*\t\010\350\007\020\200\200\200\200\002\"z\n\rMethodOptions\022\031\n\ndeprecat"
- "ed\030! \001(\010:\005false\022C\n\024uninterpreted_option\030"
- "\347\007 \003(\0132$.google.protobuf.UninterpretedOp"
- "tion*\t\010\350\007\020\200\200\200\200\002\"\236\002\n\023UninterpretedOption\022"
- ";\n\004name\030\002 \003(\0132-.google.protobuf.Uninterp"
- "retedOption.NamePart\022\030\n\020identifier_value"
- "\030\003 \001(\t\022\032\n\022positive_int_value\030\004 \001(\004\022\032\n\022ne"
- "gative_int_value\030\005 \001(\003\022\024\n\014double_value\030\006"
- " \001(\001\022\024\n\014string_value\030\007 \001(\014\022\027\n\017aggregate_"
- "value\030\010 \001(\t\0323\n\010NamePart\022\021\n\tname_part\030\001 \002"
- "(\t\022\024\n\014is_extension\030\002 \002(\010\"\325\001\n\016SourceCodeI"
- "nfo\022:\n\010location\030\001 \003(\0132(.google.protobuf."
- "SourceCodeInfo.Location\032\206\001\n\010Location\022\020\n\004"
- "path\030\001 \003(\005B\002\020\001\022\020\n\004span\030\002 \003(\005B\002\020\001\022\030\n\020lead"
- "ing_comments\030\003 \001(\t\022\031\n\021trailing_comments\030"
- "\004 \001(\t\022!\n\031leading_detached_comments\030\006 \003(\t"
- "BX\n\023com.google.protobufB\020DescriptorProto"
- "sH\001Z\ndescriptor\242\002\003GPB\252\002\032Google.Protobuf."
- "Reflection", 5010);
+ "\200\200\200\002\"\236\002\n\023UninterpretedOption\022;\n\004name\030\002 \003"
+ "(\0132-.google.protobuf.UninterpretedOption"
+ ".NamePart\022\030\n\020identifier_value\030\003 \001(\t\022\032\n\022p"
+ "ositive_int_value\030\004 \001(\004\022\032\n\022negative_int_"
+ "value\030\005 \001(\003\022\024\n\014double_value\030\006 \001(\001\022\024\n\014str"
+ "ing_value\030\007 \001(\014\022\027\n\017aggregate_value\030\010 \001(\t"
+ "\0323\n\010NamePart\022\021\n\tname_part\030\001 \002(\t\022\024\n\014is_ex"
+ "tension\030\002 \002(\010\"\325\001\n\016SourceCodeInfo\022:\n\010loca"
+ "tion\030\001 \003(\0132(.google.protobuf.SourceCodeI"
+ "nfo.Location\032\206\001\n\010Location\022\020\n\004path\030\001 \003(\005B"
+ "\002\020\001\022\020\n\004span\030\002 \003(\005B\002\020\001\022\030\n\020leading_comment"
+ "s\030\003 \001(\t\022\031\n\021trailing_comments\030\004 \001(\t\022!\n\031le"
+ "ading_detached_comments\030\006 \003(\t\"\247\001\n\021Genera"
+ "tedCodeInfo\022A\n\nannotation\030\001 \003(\0132-.google"
+ ".protobuf.GeneratedCodeInfo.Annotation\032O"
+ "\n\nAnnotation\022\020\n\004path\030\001 \003(\005B\002\020\001\022\023\n\013source"
+ "_file\030\002 \001(\t\022\r\n\005begin\030\003 \001(\005\022\013\n\003end\030\004 \001(\005B"
+ "[\n\023com.google.protobufB\020DescriptorProtos"
+ "H\001Z\ndescriptor\240\001\001\242\002\003GPB\252\002\032Google.Protobu"
+ "f.Reflection", 5292);
::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
"google/protobuf/descriptor.proto", &protobuf_RegisterTypes);
FileDescriptorSet::default_instance_ = new FileDescriptorSet();
@@ -776,6 +856,7 @@ void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() {
FileOptions::default_instance_ = new FileOptions();
MessageOptions::default_instance_ = new MessageOptions();
FieldOptions::default_instance_ = new FieldOptions();
+ OneofOptions::default_instance_ = new OneofOptions();
EnumOptions::default_instance_ = new EnumOptions();
EnumValueOptions::default_instance_ = new EnumValueOptions();
ServiceOptions::default_instance_ = new ServiceOptions();
@@ -784,6 +865,8 @@ void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() {
UninterpretedOption_NamePart::default_instance_ = new UninterpretedOption_NamePart();
SourceCodeInfo::default_instance_ = new SourceCodeInfo();
SourceCodeInfo_Location::default_instance_ = new SourceCodeInfo_Location();
+ GeneratedCodeInfo::default_instance_ = new GeneratedCodeInfo();
+ GeneratedCodeInfo_Annotation::default_instance_ = new GeneratedCodeInfo_Annotation();
FileDescriptorSet::default_instance_->InitAsDefaultInstance();
FileDescriptorProto::default_instance_->InitAsDefaultInstance();
DescriptorProto::default_instance_->InitAsDefaultInstance();
@@ -798,6 +881,7 @@ void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() {
FileOptions::default_instance_->InitAsDefaultInstance();
MessageOptions::default_instance_->InitAsDefaultInstance();
FieldOptions::default_instance_->InitAsDefaultInstance();
+ OneofOptions::default_instance_->InitAsDefaultInstance();
EnumOptions::default_instance_->InitAsDefaultInstance();
EnumValueOptions::default_instance_->InitAsDefaultInstance();
ServiceOptions::default_instance_->InitAsDefaultInstance();
@@ -806,6 +890,8 @@ void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() {
UninterpretedOption_NamePart::default_instance_->InitAsDefaultInstance();
SourceCodeInfo::default_instance_->InitAsDefaultInstance();
SourceCodeInfo_Location::default_instance_->InitAsDefaultInstance();
+ GeneratedCodeInfo::default_instance_->InitAsDefaultInstance();
+ GeneratedCodeInfo_Annotation::default_instance_->InitAsDefaultInstance();
::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto);
}
@@ -816,16 +902,6 @@ struct StaticDescriptorInitializer_google_2fprotobuf_2fdescriptor_2eproto {
}
} static_descriptor_initializer_google_2fprotobuf_2fdescriptor_2eproto_;
-namespace {
-
-static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD;
-static void MergeFromFail(int line) {
- GOOGLE_CHECK(false) << __FILE__ << ":" << line;
-}
-
-} // namespace
-
-
// ===================================================================
#if !defined(_MSC_VER) || _MSC_VER >= 1900
@@ -890,6 +966,7 @@ FileDescriptorSet* FileDescriptorSet::New(::google::protobuf::Arena* arena) cons
}
void FileDescriptorSet::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.FileDescriptorSet)
file_.Clear();
::memset(_has_bits_, 0, sizeof(_has_bits_));
if (_internal_metadata_.have_unknown_fields()) {
@@ -899,7 +976,7 @@ void FileDescriptorSet::Clear() {
bool FileDescriptorSet::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.FileDescriptorSet)
for (;;) {
@@ -961,14 +1038,14 @@ void FileDescriptorSet::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.FileDescriptorSet)
}
-::google::protobuf::uint8* FileDescriptorSet::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* FileDescriptorSet::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FileDescriptorSet)
// repeated .google.protobuf.FileDescriptorProto file = 1;
for (unsigned int i = 0, n = this->file_size(); i < n; i++) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 1, this->file(i), target);
+ InternalWriteMessageNoVirtualToArray(
+ 1, this->file(i), false, target);
}
if (_internal_metadata_.have_unknown_fields()) {
@@ -980,6 +1057,7 @@ void FileDescriptorSet::SerializeWithCachedSizes(
}
int FileDescriptorSet::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.FileDescriptorSet)
int total_size = 0;
// repeated .google.protobuf.FileDescriptorProto file = 1;
@@ -1002,19 +1080,27 @@ int FileDescriptorSet::ByteSize() const {
}
void FileDescriptorSet::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.FileDescriptorSet)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const FileDescriptorSet* source =
::google::protobuf::internal::DynamicCastToGenerated<const FileDescriptorSet>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.FileDescriptorSet)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.FileDescriptorSet)
MergeFrom(*source);
}
}
void FileDescriptorSet::MergeFrom(const FileDescriptorSet& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FileDescriptorSet)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
file_.MergeFrom(from.file_);
if (from._internal_metadata_.have_unknown_fields()) {
mutable_unknown_fields()->MergeFrom(from.unknown_fields());
@@ -1022,12 +1108,14 @@ void FileDescriptorSet::MergeFrom(const FileDescriptorSet& from) {
}
void FileDescriptorSet::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.FileDescriptorSet)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void FileDescriptorSet::CopyFrom(const FileDescriptorSet& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.FileDescriptorSet)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -1181,6 +1269,7 @@ FileDescriptorProto* FileDescriptorProto::New(::google::protobuf::Arena* arena)
}
void FileDescriptorProto::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.FileDescriptorProto)
if (_has_bits_[0 / 32] & 3u) {
if (has_name()) {
name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
@@ -1215,7 +1304,7 @@ void FileDescriptorProto::Clear() {
bool FileDescriptorProto::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.FileDescriptorProto)
for (;;) {
@@ -1541,8 +1630,8 @@ void FileDescriptorProto::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.FileDescriptorProto)
}
-::google::protobuf::uint8* FileDescriptorProto::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* FileDescriptorProto::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FileDescriptorProto)
// optional string name = 1;
if (has_name()) {
@@ -1579,43 +1668,43 @@ void FileDescriptorProto::SerializeWithCachedSizes(
// repeated .google.protobuf.DescriptorProto message_type = 4;
for (unsigned int i = 0, n = this->message_type_size(); i < n; i++) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 4, this->message_type(i), target);
+ InternalWriteMessageNoVirtualToArray(
+ 4, this->message_type(i), false, target);
}
// repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
for (unsigned int i = 0, n = this->enum_type_size(); i < n; i++) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 5, this->enum_type(i), target);
+ InternalWriteMessageNoVirtualToArray(
+ 5, this->enum_type(i), false, target);
}
// repeated .google.protobuf.ServiceDescriptorProto service = 6;
for (unsigned int i = 0, n = this->service_size(); i < n; i++) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 6, this->service(i), target);
+ InternalWriteMessageNoVirtualToArray(
+ 6, this->service(i), false, target);
}
// repeated .google.protobuf.FieldDescriptorProto extension = 7;
for (unsigned int i = 0, n = this->extension_size(); i < n; i++) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 7, this->extension(i), target);
+ InternalWriteMessageNoVirtualToArray(
+ 7, this->extension(i), false, target);
}
// optional .google.protobuf.FileOptions options = 8;
if (has_options()) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 8, *this->options_, target);
+ InternalWriteMessageNoVirtualToArray(
+ 8, *this->options_, false, target);
}
// optional .google.protobuf.SourceCodeInfo source_code_info = 9;
if (has_source_code_info()) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 9, *this->source_code_info_, target);
+ InternalWriteMessageNoVirtualToArray(
+ 9, *this->source_code_info_, false, target);
}
// repeated int32 public_dependency = 10;
@@ -1650,6 +1739,7 @@ void FileDescriptorProto::SerializeWithCachedSizes(
}
int FileDescriptorProto::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.FileDescriptorProto)
int total_size = 0;
if (_has_bits_[0 / 32] & 3u) {
@@ -1762,19 +1852,27 @@ int FileDescriptorProto::ByteSize() const {
}
void FileDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.FileDescriptorProto)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const FileDescriptorProto* source =
::google::protobuf::internal::DynamicCastToGenerated<const FileDescriptorProto>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.FileDescriptorProto)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.FileDescriptorProto)
MergeFrom(*source);
}
}
void FileDescriptorProto::MergeFrom(const FileDescriptorProto& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FileDescriptorProto)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
dependency_.MergeFrom(from.dependency_);
public_dependency_.MergeFrom(from.public_dependency_);
weak_dependency_.MergeFrom(from.weak_dependency_);
@@ -1810,12 +1908,14 @@ void FileDescriptorProto::MergeFrom(const FileDescriptorProto& from) {
}
void FileDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.FileDescriptorProto)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void FileDescriptorProto::CopyFrom(const FileDescriptorProto& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.FileDescriptorProto)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -1906,6 +2006,7 @@ void FileDescriptorProto::clear_name() {
return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* FileDescriptorProto::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.name)
clear_has_name();
return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -1959,6 +2060,7 @@ void FileDescriptorProto::clear_package() {
return package_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* FileDescriptorProto::release_package() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.package)
clear_has_package();
return package_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -2001,6 +2103,7 @@ void FileDescriptorProto::clear_dependency() {
// @@protoc_insertion_point(field_set_pointer:google.protobuf.FileDescriptorProto.dependency)
}
::std::string* FileDescriptorProto::add_dependency() {
+ // @@protoc_insertion_point(field_add_mutable:google.protobuf.FileDescriptorProto.dependency)
return dependency_.Add();
}
void FileDescriptorProto::add_dependency(const ::std::string& value) {
@@ -2233,6 +2336,7 @@ const ::google::protobuf::FileOptions& FileDescriptorProto::options() const {
return options_;
}
::google::protobuf::FileOptions* FileDescriptorProto::release_options() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.options)
clear_has_options();
::google::protobuf::FileOptions* temp = options_;
options_ = NULL;
@@ -2276,6 +2380,7 @@ const ::google::protobuf::SourceCodeInfo& FileDescriptorProto::source_code_info(
return source_code_info_;
}
::google::protobuf::SourceCodeInfo* FileDescriptorProto::release_source_code_info() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.source_code_info)
clear_has_source_code_info();
::google::protobuf::SourceCodeInfo* temp = source_code_info_;
source_code_info_ = NULL;
@@ -2332,6 +2437,7 @@ void FileDescriptorProto::clear_syntax() {
return syntax_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* FileDescriptorProto::release_syntax() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.syntax)
clear_has_syntax();
return syntax_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -2414,8 +2520,17 @@ DescriptorProto_ExtensionRange* DescriptorProto_ExtensionRange::New(::google::pr
}
void DescriptorProto_ExtensionRange::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.DescriptorProto.ExtensionRange)
+#if defined(__clang__)
+#define ZR_HELPER_(f) \
+ _Pragma("clang diagnostic push") \
+ _Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"") \
+ __builtin_offsetof(DescriptorProto_ExtensionRange, f) \
+ _Pragma("clang diagnostic pop")
+#else
#define ZR_HELPER_(f) reinterpret_cast<char*>(\
&reinterpret_cast<DescriptorProto_ExtensionRange*>(16)->f)
+#endif
#define ZR_(first, last) do {\
::memset(&first, 0,\
@@ -2435,7 +2550,7 @@ void DescriptorProto_ExtensionRange::Clear() {
bool DescriptorProto_ExtensionRange::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.DescriptorProto.ExtensionRange)
for (;;) {
@@ -2514,8 +2629,8 @@ void DescriptorProto_ExtensionRange::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.DescriptorProto.ExtensionRange)
}
-::google::protobuf::uint8* DescriptorProto_ExtensionRange::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* DescriptorProto_ExtensionRange::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.DescriptorProto.ExtensionRange)
// optional int32 start = 1;
if (has_start()) {
@@ -2536,6 +2651,7 @@ void DescriptorProto_ExtensionRange::SerializeWithCachedSizes(
}
int DescriptorProto_ExtensionRange::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.DescriptorProto.ExtensionRange)
int total_size = 0;
if (_has_bits_[0 / 32] & 3u) {
@@ -2566,19 +2682,27 @@ int DescriptorProto_ExtensionRange::ByteSize() const {
}
void DescriptorProto_ExtensionRange::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.DescriptorProto.ExtensionRange)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const DescriptorProto_ExtensionRange* source =
::google::protobuf::internal::DynamicCastToGenerated<const DescriptorProto_ExtensionRange>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.DescriptorProto.ExtensionRange)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.DescriptorProto.ExtensionRange)
MergeFrom(*source);
}
}
void DescriptorProto_ExtensionRange::MergeFrom(const DescriptorProto_ExtensionRange& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.DescriptorProto.ExtensionRange)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_start()) {
set_start(from.start());
@@ -2593,12 +2717,14 @@ void DescriptorProto_ExtensionRange::MergeFrom(const DescriptorProto_ExtensionRa
}
void DescriptorProto_ExtensionRange::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.DescriptorProto.ExtensionRange)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void DescriptorProto_ExtensionRange::CopyFrom(const DescriptorProto_ExtensionRange& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.DescriptorProto.ExtensionRange)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -2697,8 +2823,17 @@ DescriptorProto_ReservedRange* DescriptorProto_ReservedRange::New(::google::prot
}
void DescriptorProto_ReservedRange::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.DescriptorProto.ReservedRange)
+#if defined(__clang__)
+#define ZR_HELPER_(f) \
+ _Pragma("clang diagnostic push") \
+ _Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"") \
+ __builtin_offsetof(DescriptorProto_ReservedRange, f) \
+ _Pragma("clang diagnostic pop")
+#else
#define ZR_HELPER_(f) reinterpret_cast<char*>(\
&reinterpret_cast<DescriptorProto_ReservedRange*>(16)->f)
+#endif
#define ZR_(first, last) do {\
::memset(&first, 0,\
@@ -2718,7 +2853,7 @@ void DescriptorProto_ReservedRange::Clear() {
bool DescriptorProto_ReservedRange::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.DescriptorProto.ReservedRange)
for (;;) {
@@ -2797,8 +2932,8 @@ void DescriptorProto_ReservedRange::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.DescriptorProto.ReservedRange)
}
-::google::protobuf::uint8* DescriptorProto_ReservedRange::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* DescriptorProto_ReservedRange::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.DescriptorProto.ReservedRange)
// optional int32 start = 1;
if (has_start()) {
@@ -2819,6 +2954,7 @@ void DescriptorProto_ReservedRange::SerializeWithCachedSizes(
}
int DescriptorProto_ReservedRange::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.DescriptorProto.ReservedRange)
int total_size = 0;
if (_has_bits_[0 / 32] & 3u) {
@@ -2849,19 +2985,27 @@ int DescriptorProto_ReservedRange::ByteSize() const {
}
void DescriptorProto_ReservedRange::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.DescriptorProto.ReservedRange)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const DescriptorProto_ReservedRange* source =
::google::protobuf::internal::DynamicCastToGenerated<const DescriptorProto_ReservedRange>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.DescriptorProto.ReservedRange)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.DescriptorProto.ReservedRange)
MergeFrom(*source);
}
}
void DescriptorProto_ReservedRange::MergeFrom(const DescriptorProto_ReservedRange& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.DescriptorProto.ReservedRange)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_start()) {
set_start(from.start());
@@ -2876,12 +3020,14 @@ void DescriptorProto_ReservedRange::MergeFrom(const DescriptorProto_ReservedRang
}
void DescriptorProto_ReservedRange::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.DescriptorProto.ReservedRange)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void DescriptorProto_ReservedRange::CopyFrom(const DescriptorProto_ReservedRange& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.DescriptorProto.ReservedRange)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -2992,6 +3138,7 @@ DescriptorProto* DescriptorProto::New(::google::protobuf::Arena* arena) const {
}
void DescriptorProto::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.DescriptorProto)
if (_has_bits_[0 / 32] & 129u) {
if (has_name()) {
name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
@@ -3016,7 +3163,7 @@ void DescriptorProto::Clear() {
bool DescriptorProto::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.DescriptorProto)
for (;;) {
@@ -3286,8 +3433,8 @@ void DescriptorProto::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.DescriptorProto)
}
-::google::protobuf::uint8* DescriptorProto::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* DescriptorProto::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.DescriptorProto)
// optional string name = 1;
if (has_name()) {
@@ -3303,57 +3450,57 @@ void DescriptorProto::SerializeWithCachedSizes(
// repeated .google.protobuf.FieldDescriptorProto field = 2;
for (unsigned int i = 0, n = this->field_size(); i < n; i++) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 2, this->field(i), target);
+ InternalWriteMessageNoVirtualToArray(
+ 2, this->field(i), false, target);
}
// repeated .google.protobuf.DescriptorProto nested_type = 3;
for (unsigned int i = 0, n = this->nested_type_size(); i < n; i++) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 3, this->nested_type(i), target);
+ InternalWriteMessageNoVirtualToArray(
+ 3, this->nested_type(i), false, target);
}
// repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
for (unsigned int i = 0, n = this->enum_type_size(); i < n; i++) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 4, this->enum_type(i), target);
+ InternalWriteMessageNoVirtualToArray(
+ 4, this->enum_type(i), false, target);
}
// repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
for (unsigned int i = 0, n = this->extension_range_size(); i < n; i++) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 5, this->extension_range(i), target);
+ InternalWriteMessageNoVirtualToArray(
+ 5, this->extension_range(i), false, target);
}
// repeated .google.protobuf.FieldDescriptorProto extension = 6;
for (unsigned int i = 0, n = this->extension_size(); i < n; i++) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 6, this->extension(i), target);
+ InternalWriteMessageNoVirtualToArray(
+ 6, this->extension(i), false, target);
}
// optional .google.protobuf.MessageOptions options = 7;
if (has_options()) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 7, *this->options_, target);
+ InternalWriteMessageNoVirtualToArray(
+ 7, *this->options_, false, target);
}
// repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
for (unsigned int i = 0, n = this->oneof_decl_size(); i < n; i++) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 8, this->oneof_decl(i), target);
+ InternalWriteMessageNoVirtualToArray(
+ 8, this->oneof_decl(i), false, target);
}
// repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9;
for (unsigned int i = 0, n = this->reserved_range_size(); i < n; i++) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 9, this->reserved_range(i), target);
+ InternalWriteMessageNoVirtualToArray(
+ 9, this->reserved_range(i), false, target);
}
// repeated string reserved_name = 10;
@@ -3375,6 +3522,7 @@ void DescriptorProto::SerializeWithCachedSizes(
}
int DescriptorProto::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.DescriptorProto)
int total_size = 0;
if (_has_bits_[0 / 32] & 129u) {
@@ -3468,19 +3616,27 @@ int DescriptorProto::ByteSize() const {
}
void DescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.DescriptorProto)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const DescriptorProto* source =
::google::protobuf::internal::DynamicCastToGenerated<const DescriptorProto>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.DescriptorProto)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.DescriptorProto)
MergeFrom(*source);
}
}
void DescriptorProto::MergeFrom(const DescriptorProto& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.DescriptorProto)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
field_.MergeFrom(from.field_);
extension_.MergeFrom(from.extension_);
nested_type_.MergeFrom(from.nested_type_);
@@ -3504,12 +3660,14 @@ void DescriptorProto::MergeFrom(const DescriptorProto& from) {
}
void DescriptorProto::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.DescriptorProto)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void DescriptorProto::CopyFrom(const DescriptorProto& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.DescriptorProto)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -3521,6 +3679,7 @@ bool DescriptorProto::IsInitialized() const {
if (!::google::protobuf::internal::AllAreInitialized(this->extension())) return false;
if (!::google::protobuf::internal::AllAreInitialized(this->nested_type())) return false;
if (!::google::protobuf::internal::AllAreInitialized(this->enum_type())) return false;
+ if (!::google::protobuf::internal::AllAreInitialized(this->oneof_decl())) return false;
if (has_options()) {
if (!this->options_->IsInitialized()) return false;
}
@@ -3702,6 +3861,7 @@ void DescriptorProto::clear_name() {
return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* DescriptorProto::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.DescriptorProto.name)
clear_has_name();
return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -3922,6 +4082,7 @@ const ::google::protobuf::MessageOptions& DescriptorProto::options() const {
return options_;
}
::google::protobuf::MessageOptions* DescriptorProto::release_options() {
+ // @@protoc_insertion_point(field_release:google.protobuf.DescriptorProto.options)
clear_has_options();
::google::protobuf::MessageOptions* temp = options_;
options_ = NULL;
@@ -3997,6 +4158,7 @@ void DescriptorProto::clear_reserved_name() {
// @@protoc_insertion_point(field_set_pointer:google.protobuf.DescriptorProto.reserved_name)
}
::std::string* DescriptorProto::add_reserved_name() {
+ // @@protoc_insertion_point(field_add_mutable:google.protobuf.DescriptorProto.reserved_name)
return reserved_name_.Add();
}
void DescriptorProto::add_reserved_name(const ::std::string& value) {
@@ -4191,6 +4353,7 @@ FieldDescriptorProto* FieldDescriptorProto::New(::google::protobuf::Arena* arena
}
void FieldDescriptorProto::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.FieldDescriptorProto)
if (_has_bits_[0 / 32] & 255u) {
if (has_name()) {
name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
@@ -4225,7 +4388,7 @@ void FieldDescriptorProto::Clear() {
bool FieldDescriptorProto::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.FieldDescriptorProto)
for (;;) {
@@ -4510,8 +4673,8 @@ void FieldDescriptorProto::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.FieldDescriptorProto)
}
-::google::protobuf::uint8* FieldDescriptorProto::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* FieldDescriptorProto::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FieldDescriptorProto)
// optional string name = 1;
if (has_name()) {
@@ -4577,8 +4740,8 @@ void FieldDescriptorProto::SerializeWithCachedSizes(
// optional .google.protobuf.FieldOptions options = 8;
if (has_options()) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 8, *this->options_, target);
+ InternalWriteMessageNoVirtualToArray(
+ 8, *this->options_, false, target);
}
// optional int32 oneof_index = 9;
@@ -4606,6 +4769,7 @@ void FieldDescriptorProto::SerializeWithCachedSizes(
}
int FieldDescriptorProto::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.FieldDescriptorProto)
int total_size = 0;
if (_has_bits_[0 / 32] & 255u) {
@@ -4692,19 +4856,27 @@ int FieldDescriptorProto::ByteSize() const {
}
void FieldDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.FieldDescriptorProto)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const FieldDescriptorProto* source =
::google::protobuf::internal::DynamicCastToGenerated<const FieldDescriptorProto>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.FieldDescriptorProto)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.FieldDescriptorProto)
MergeFrom(*source);
}
}
void FieldDescriptorProto::MergeFrom(const FieldDescriptorProto& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FieldDescriptorProto)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_name()) {
set_has_name();
@@ -4750,12 +4922,14 @@ void FieldDescriptorProto::MergeFrom(const FieldDescriptorProto& from) {
}
void FieldDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.FieldDescriptorProto)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void FieldDescriptorProto::CopyFrom(const FieldDescriptorProto& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.FieldDescriptorProto)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -4840,6 +5014,7 @@ void FieldDescriptorProto::clear_name() {
return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* FieldDescriptorProto::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.name)
clear_has_name();
return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -4967,6 +5142,7 @@ void FieldDescriptorProto::clear_type_name() {
return type_name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* FieldDescriptorProto::release_type_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.type_name)
clear_has_type_name();
return type_name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -5020,6 +5196,7 @@ void FieldDescriptorProto::clear_extendee() {
return extendee_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* FieldDescriptorProto::release_extendee() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.extendee)
clear_has_extendee();
return extendee_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -5073,6 +5250,7 @@ void FieldDescriptorProto::clear_default_value() {
return default_value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* FieldDescriptorProto::release_default_value() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.default_value)
clear_has_default_value();
return default_value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -5150,6 +5328,7 @@ void FieldDescriptorProto::clear_json_name() {
return json_name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* FieldDescriptorProto::release_json_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.json_name)
clear_has_json_name();
return json_name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -5190,6 +5369,7 @@ const ::google::protobuf::FieldOptions& FieldDescriptorProto::options() const {
return options_;
}
::google::protobuf::FieldOptions* FieldDescriptorProto::release_options() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.options)
clear_has_options();
::google::protobuf::FieldOptions* temp = options_;
options_ = NULL;
@@ -5212,6 +5392,7 @@ void FieldDescriptorProto::set_allocated_options(::google::protobuf::FieldOption
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int OneofDescriptorProto::kNameFieldNumber;
+const int OneofDescriptorProto::kOptionsFieldNumber;
#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
OneofDescriptorProto::OneofDescriptorProto()
@@ -5221,6 +5402,7 @@ OneofDescriptorProto::OneofDescriptorProto()
}
void OneofDescriptorProto::InitAsDefaultInstance() {
+ options_ = const_cast< ::google::protobuf::OneofOptions*>(&::google::protobuf::OneofOptions::default_instance());
}
OneofDescriptorProto::OneofDescriptorProto(const OneofDescriptorProto& from)
@@ -5235,6 +5417,7 @@ void OneofDescriptorProto::SharedCtor() {
::google::protobuf::internal::GetEmptyString();
_cached_size_ = 0;
name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ options_ = NULL;
::memset(_has_bits_, 0, sizeof(_has_bits_));
}
@@ -5246,6 +5429,7 @@ OneofDescriptorProto::~OneofDescriptorProto() {
void OneofDescriptorProto::SharedDtor() {
name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
if (this != default_instance_) {
+ delete options_;
}
}
@@ -5275,8 +5459,14 @@ OneofDescriptorProto* OneofDescriptorProto::New(::google::protobuf::Arena* arena
}
void OneofDescriptorProto::Clear() {
- if (has_name()) {
- name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+// @@protoc_insertion_point(message_clear_start:google.protobuf.OneofDescriptorProto)
+ if (_has_bits_[0 / 32] & 3u) {
+ if (has_name()) {
+ name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ }
+ if (has_options()) {
+ if (options_ != NULL) options_->::google::protobuf::OneofOptions::Clear();
+ }
}
::memset(_has_bits_, 0, sizeof(_has_bits_));
if (_internal_metadata_.have_unknown_fields()) {
@@ -5286,7 +5476,7 @@ void OneofDescriptorProto::Clear() {
bool OneofDescriptorProto::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.OneofDescriptorProto)
for (;;) {
@@ -5306,6 +5496,19 @@ bool OneofDescriptorProto::MergePartialFromCodedStream(
} else {
goto handle_unusual;
}
+ if (input->ExpectTag(18)) goto parse_options;
+ break;
+ }
+
+ // optional .google.protobuf.OneofOptions options = 2;
+ case 2: {
+ if (tag == 18) {
+ parse_options:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+ input, mutable_options()));
+ } else {
+ goto handle_unusual;
+ }
if (input->ExpectAtEnd()) goto success;
break;
}
@@ -5345,6 +5548,12 @@ void OneofDescriptorProto::SerializeWithCachedSizes(
1, this->name(), output);
}
+ // optional .google.protobuf.OneofOptions options = 2;
+ if (has_options()) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+ 2, *this->options_, output);
+ }
+
if (_internal_metadata_.have_unknown_fields()) {
::google::protobuf::internal::WireFormat::SerializeUnknownFields(
unknown_fields(), output);
@@ -5352,8 +5561,8 @@ void OneofDescriptorProto::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.OneofDescriptorProto)
}
-::google::protobuf::uint8* OneofDescriptorProto::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* OneofDescriptorProto::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.OneofDescriptorProto)
// optional string name = 1;
if (has_name()) {
@@ -5366,6 +5575,13 @@ void OneofDescriptorProto::SerializeWithCachedSizes(
1, this->name(), target);
}
+ // optional .google.protobuf.OneofOptions options = 2;
+ if (has_options()) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ InternalWriteMessageNoVirtualToArray(
+ 2, *this->options_, false, target);
+ }
+
if (_internal_metadata_.have_unknown_fields()) {
target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
unknown_fields(), target);
@@ -5375,15 +5591,25 @@ void OneofDescriptorProto::SerializeWithCachedSizes(
}
int OneofDescriptorProto::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.OneofDescriptorProto)
int total_size = 0;
- // optional string name = 1;
- if (has_name()) {
- total_size += 1 +
- ::google::protobuf::internal::WireFormatLite::StringSize(
- this->name());
- }
+ if (_has_bits_[0 / 32] & 3u) {
+ // optional string name = 1;
+ if (has_name()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::StringSize(
+ this->name());
+ }
+ // optional .google.protobuf.OneofOptions options = 2;
+ if (has_options()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ *this->options_);
+ }
+
+ }
if (_internal_metadata_.have_unknown_fields()) {
total_size +=
::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
@@ -5396,24 +5622,35 @@ int OneofDescriptorProto::ByteSize() const {
}
void OneofDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.OneofDescriptorProto)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const OneofDescriptorProto* source =
::google::protobuf::internal::DynamicCastToGenerated<const OneofDescriptorProto>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.OneofDescriptorProto)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.OneofDescriptorProto)
MergeFrom(*source);
}
}
void OneofDescriptorProto::MergeFrom(const OneofDescriptorProto& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.OneofDescriptorProto)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_name()) {
set_has_name();
name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
}
+ if (from.has_options()) {
+ mutable_options()->::google::protobuf::OneofOptions::MergeFrom(from.options());
+ }
}
if (from._internal_metadata_.have_unknown_fields()) {
mutable_unknown_fields()->MergeFrom(from.unknown_fields());
@@ -5421,12 +5658,14 @@ void OneofDescriptorProto::MergeFrom(const OneofDescriptorProto& from) {
}
void OneofDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.OneofDescriptorProto)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void OneofDescriptorProto::CopyFrom(const OneofDescriptorProto& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.OneofDescriptorProto)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -5434,6 +5673,9 @@ void OneofDescriptorProto::CopyFrom(const OneofDescriptorProto& from) {
bool OneofDescriptorProto::IsInitialized() const {
+ if (has_options()) {
+ if (!this->options_->IsInitialized()) return false;
+ }
return true;
}
@@ -5443,6 +5685,7 @@ void OneofDescriptorProto::Swap(OneofDescriptorProto* other) {
}
void OneofDescriptorProto::InternalSwap(OneofDescriptorProto* other) {
name_.Swap(&other->name_);
+ std::swap(options_, other->options_);
std::swap(_has_bits_[0], other->_has_bits_[0]);
_internal_metadata_.Swap(&other->_internal_metadata_);
std::swap(_cached_size_, other->_cached_size_);
@@ -5499,6 +5742,7 @@ void OneofDescriptorProto::clear_name() {
return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* OneofDescriptorProto::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.OneofDescriptorProto.name)
clear_has_name();
return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -5512,6 +5756,50 @@ void OneofDescriptorProto::clear_name() {
// @@protoc_insertion_point(field_set_allocated:google.protobuf.OneofDescriptorProto.name)
}
+// optional .google.protobuf.OneofOptions options = 2;
+bool OneofDescriptorProto::has_options() const {
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+void OneofDescriptorProto::set_has_options() {
+ _has_bits_[0] |= 0x00000002u;
+}
+void OneofDescriptorProto::clear_has_options() {
+ _has_bits_[0] &= ~0x00000002u;
+}
+void OneofDescriptorProto::clear_options() {
+ if (options_ != NULL) options_->::google::protobuf::OneofOptions::Clear();
+ clear_has_options();
+}
+const ::google::protobuf::OneofOptions& OneofDescriptorProto::options() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.OneofDescriptorProto.options)
+ return options_ != NULL ? *options_ : *default_instance_->options_;
+}
+::google::protobuf::OneofOptions* OneofDescriptorProto::mutable_options() {
+ set_has_options();
+ if (options_ == NULL) {
+ options_ = new ::google::protobuf::OneofOptions;
+ }
+ // @@protoc_insertion_point(field_mutable:google.protobuf.OneofDescriptorProto.options)
+ return options_;
+}
+::google::protobuf::OneofOptions* OneofDescriptorProto::release_options() {
+ // @@protoc_insertion_point(field_release:google.protobuf.OneofDescriptorProto.options)
+ clear_has_options();
+ ::google::protobuf::OneofOptions* temp = options_;
+ options_ = NULL;
+ return temp;
+}
+void OneofDescriptorProto::set_allocated_options(::google::protobuf::OneofOptions* options) {
+ delete options_;
+ options_ = options;
+ if (options) {
+ set_has_options();
+ } else {
+ clear_has_options();
+ }
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.OneofDescriptorProto.options)
+}
+
#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
// ===================================================================
@@ -5586,6 +5874,7 @@ EnumDescriptorProto* EnumDescriptorProto::New(::google::protobuf::Arena* arena)
}
void EnumDescriptorProto::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.EnumDescriptorProto)
if (_has_bits_[0 / 32] & 5u) {
if (has_name()) {
name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
@@ -5603,7 +5892,7 @@ void EnumDescriptorProto::Clear() {
bool EnumDescriptorProto::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.EnumDescriptorProto)
for (;;) {
@@ -5711,8 +6000,8 @@ void EnumDescriptorProto::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.EnumDescriptorProto)
}
-::google::protobuf::uint8* EnumDescriptorProto::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* EnumDescriptorProto::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumDescriptorProto)
// optional string name = 1;
if (has_name()) {
@@ -5728,15 +6017,15 @@ void EnumDescriptorProto::SerializeWithCachedSizes(
// repeated .google.protobuf.EnumValueDescriptorProto value = 2;
for (unsigned int i = 0, n = this->value_size(); i < n; i++) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 2, this->value(i), target);
+ InternalWriteMessageNoVirtualToArray(
+ 2, this->value(i), false, target);
}
// optional .google.protobuf.EnumOptions options = 3;
if (has_options()) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 3, *this->options_, target);
+ InternalWriteMessageNoVirtualToArray(
+ 3, *this->options_, false, target);
}
if (_internal_metadata_.have_unknown_fields()) {
@@ -5748,6 +6037,7 @@ void EnumDescriptorProto::SerializeWithCachedSizes(
}
int EnumDescriptorProto::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.EnumDescriptorProto)
int total_size = 0;
if (_has_bits_[0 / 32] & 5u) {
@@ -5786,19 +6076,27 @@ int EnumDescriptorProto::ByteSize() const {
}
void EnumDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.EnumDescriptorProto)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const EnumDescriptorProto* source =
::google::protobuf::internal::DynamicCastToGenerated<const EnumDescriptorProto>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.EnumDescriptorProto)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.EnumDescriptorProto)
MergeFrom(*source);
}
}
void EnumDescriptorProto::MergeFrom(const EnumDescriptorProto& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumDescriptorProto)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
value_.MergeFrom(from.value_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_name()) {
@@ -5815,12 +6113,14 @@ void EnumDescriptorProto::MergeFrom(const EnumDescriptorProto& from) {
}
void EnumDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.EnumDescriptorProto)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void EnumDescriptorProto::CopyFrom(const EnumDescriptorProto& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.EnumDescriptorProto)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -5899,6 +6199,7 @@ void EnumDescriptorProto::clear_name() {
return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* EnumDescriptorProto::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.EnumDescriptorProto.name)
clear_has_name();
return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -5969,6 +6270,7 @@ const ::google::protobuf::EnumOptions& EnumDescriptorProto::options() const {
return options_;
}
::google::protobuf::EnumOptions* EnumDescriptorProto::release_options() {
+ // @@protoc_insertion_point(field_release:google.protobuf.EnumDescriptorProto.options)
clear_has_options();
::google::protobuf::EnumOptions* temp = options_;
options_ = NULL;
@@ -6060,6 +6362,7 @@ EnumValueDescriptorProto* EnumValueDescriptorProto::New(::google::protobuf::Aren
}
void EnumValueDescriptorProto::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.EnumValueDescriptorProto)
if (_has_bits_[0 / 32] & 7u) {
if (has_name()) {
name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
@@ -6077,7 +6380,7 @@ void EnumValueDescriptorProto::Clear() {
bool EnumValueDescriptorProto::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.EnumValueDescriptorProto)
for (;;) {
@@ -6182,8 +6485,8 @@ void EnumValueDescriptorProto::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.EnumValueDescriptorProto)
}
-::google::protobuf::uint8* EnumValueDescriptorProto::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* EnumValueDescriptorProto::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumValueDescriptorProto)
// optional string name = 1;
if (has_name()) {
@@ -6204,8 +6507,8 @@ void EnumValueDescriptorProto::SerializeWithCachedSizes(
// optional .google.protobuf.EnumValueOptions options = 3;
if (has_options()) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 3, *this->options_, target);
+ InternalWriteMessageNoVirtualToArray(
+ 3, *this->options_, false, target);
}
if (_internal_metadata_.have_unknown_fields()) {
@@ -6217,6 +6520,7 @@ void EnumValueDescriptorProto::SerializeWithCachedSizes(
}
int EnumValueDescriptorProto::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.EnumValueDescriptorProto)
int total_size = 0;
if (_has_bits_[0 / 32] & 7u) {
@@ -6254,19 +6558,27 @@ int EnumValueDescriptorProto::ByteSize() const {
}
void EnumValueDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.EnumValueDescriptorProto)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const EnumValueDescriptorProto* source =
::google::protobuf::internal::DynamicCastToGenerated<const EnumValueDescriptorProto>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.EnumValueDescriptorProto)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.EnumValueDescriptorProto)
MergeFrom(*source);
}
}
void EnumValueDescriptorProto::MergeFrom(const EnumValueDescriptorProto& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumValueDescriptorProto)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_name()) {
set_has_name();
@@ -6285,12 +6597,14 @@ void EnumValueDescriptorProto::MergeFrom(const EnumValueDescriptorProto& from) {
}
void EnumValueDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.EnumValueDescriptorProto)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void EnumValueDescriptorProto::CopyFrom(const EnumValueDescriptorProto& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.EnumValueDescriptorProto)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -6368,6 +6682,7 @@ void EnumValueDescriptorProto::clear_name() {
return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* EnumValueDescriptorProto::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.EnumValueDescriptorProto.name)
clear_has_name();
return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -6432,6 +6747,7 @@ const ::google::protobuf::EnumValueOptions& EnumValueDescriptorProto::options()
return options_;
}
::google::protobuf::EnumValueOptions* EnumValueDescriptorProto::release_options() {
+ // @@protoc_insertion_point(field_release:google.protobuf.EnumValueDescriptorProto.options)
clear_has_options();
::google::protobuf::EnumValueOptions* temp = options_;
options_ = NULL;
@@ -6522,6 +6838,7 @@ ServiceDescriptorProto* ServiceDescriptorProto::New(::google::protobuf::Arena* a
}
void ServiceDescriptorProto::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.ServiceDescriptorProto)
if (_has_bits_[0 / 32] & 5u) {
if (has_name()) {
name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
@@ -6539,7 +6856,7 @@ void ServiceDescriptorProto::Clear() {
bool ServiceDescriptorProto::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.ServiceDescriptorProto)
for (;;) {
@@ -6647,8 +6964,8 @@ void ServiceDescriptorProto::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.ServiceDescriptorProto)
}
-::google::protobuf::uint8* ServiceDescriptorProto::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* ServiceDescriptorProto::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.ServiceDescriptorProto)
// optional string name = 1;
if (has_name()) {
@@ -6664,15 +6981,15 @@ void ServiceDescriptorProto::SerializeWithCachedSizes(
// repeated .google.protobuf.MethodDescriptorProto method = 2;
for (unsigned int i = 0, n = this->method_size(); i < n; i++) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 2, this->method(i), target);
+ InternalWriteMessageNoVirtualToArray(
+ 2, this->method(i), false, target);
}
// optional .google.protobuf.ServiceOptions options = 3;
if (has_options()) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 3, *this->options_, target);
+ InternalWriteMessageNoVirtualToArray(
+ 3, *this->options_, false, target);
}
if (_internal_metadata_.have_unknown_fields()) {
@@ -6684,6 +7001,7 @@ void ServiceDescriptorProto::SerializeWithCachedSizes(
}
int ServiceDescriptorProto::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.ServiceDescriptorProto)
int total_size = 0;
if (_has_bits_[0 / 32] & 5u) {
@@ -6722,19 +7040,27 @@ int ServiceDescriptorProto::ByteSize() const {
}
void ServiceDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.ServiceDescriptorProto)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const ServiceDescriptorProto* source =
::google::protobuf::internal::DynamicCastToGenerated<const ServiceDescriptorProto>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.ServiceDescriptorProto)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.ServiceDescriptorProto)
MergeFrom(*source);
}
}
void ServiceDescriptorProto::MergeFrom(const ServiceDescriptorProto& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.ServiceDescriptorProto)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
method_.MergeFrom(from.method_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_name()) {
@@ -6751,12 +7077,14 @@ void ServiceDescriptorProto::MergeFrom(const ServiceDescriptorProto& from) {
}
void ServiceDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.ServiceDescriptorProto)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void ServiceDescriptorProto::CopyFrom(const ServiceDescriptorProto& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.ServiceDescriptorProto)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -6835,6 +7163,7 @@ void ServiceDescriptorProto::clear_name() {
return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* ServiceDescriptorProto::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.ServiceDescriptorProto.name)
clear_has_name();
return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -6905,6 +7234,7 @@ const ::google::protobuf::ServiceOptions& ServiceDescriptorProto::options() cons
return options_;
}
::google::protobuf::ServiceOptions* ServiceDescriptorProto::release_options() {
+ // @@protoc_insertion_point(field_release:google.protobuf.ServiceDescriptorProto.options)
clear_has_options();
::google::protobuf::ServiceOptions* temp = options_;
options_ = NULL;
@@ -7004,8 +7334,17 @@ MethodDescriptorProto* MethodDescriptorProto::New(::google::protobuf::Arena* are
}
void MethodDescriptorProto::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.MethodDescriptorProto)
+#if defined(__clang__)
+#define ZR_HELPER_(f) \
+ _Pragma("clang diagnostic push") \
+ _Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"") \
+ __builtin_offsetof(MethodDescriptorProto, f) \
+ _Pragma("clang diagnostic pop")
+#else
#define ZR_HELPER_(f) reinterpret_cast<char*>(\
&reinterpret_cast<MethodDescriptorProto*>(16)->f)
+#endif
#define ZR_(first, last) do {\
::memset(&first, 0,\
@@ -7039,7 +7378,7 @@ void MethodDescriptorProto::Clear() {
bool MethodDescriptorProto::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.MethodDescriptorProto)
for (;;) {
@@ -7218,8 +7557,8 @@ void MethodDescriptorProto::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.MethodDescriptorProto)
}
-::google::protobuf::uint8* MethodDescriptorProto::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* MethodDescriptorProto::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.MethodDescriptorProto)
// optional string name = 1;
if (has_name()) {
@@ -7257,8 +7596,8 @@ void MethodDescriptorProto::SerializeWithCachedSizes(
// optional .google.protobuf.MethodOptions options = 4;
if (has_options()) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 4, *this->options_, target);
+ InternalWriteMessageNoVirtualToArray(
+ 4, *this->options_, false, target);
}
// optional bool client_streaming = 5 [default = false];
@@ -7280,6 +7619,7 @@ void MethodDescriptorProto::SerializeWithCachedSizes(
}
int MethodDescriptorProto::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.MethodDescriptorProto)
int total_size = 0;
if (_has_bits_[0 / 32] & 63u) {
@@ -7334,19 +7674,27 @@ int MethodDescriptorProto::ByteSize() const {
}
void MethodDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.MethodDescriptorProto)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const MethodDescriptorProto* source =
::google::protobuf::internal::DynamicCastToGenerated<const MethodDescriptorProto>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.MethodDescriptorProto)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.MethodDescriptorProto)
MergeFrom(*source);
}
}
void MethodDescriptorProto::MergeFrom(const MethodDescriptorProto& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.MethodDescriptorProto)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_name()) {
set_has_name();
@@ -7376,12 +7724,14 @@ void MethodDescriptorProto::MergeFrom(const MethodDescriptorProto& from) {
}
void MethodDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.MethodDescriptorProto)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void MethodDescriptorProto::CopyFrom(const MethodDescriptorProto& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.MethodDescriptorProto)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -7462,6 +7812,7 @@ void MethodDescriptorProto::clear_name() {
return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* MethodDescriptorProto::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.MethodDescriptorProto.name)
clear_has_name();
return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -7515,6 +7866,7 @@ void MethodDescriptorProto::clear_input_type() {
return input_type_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* MethodDescriptorProto::release_input_type() {
+ // @@protoc_insertion_point(field_release:google.protobuf.MethodDescriptorProto.input_type)
clear_has_input_type();
return input_type_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -7568,6 +7920,7 @@ void MethodDescriptorProto::clear_output_type() {
return output_type_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* MethodDescriptorProto::release_output_type() {
+ // @@protoc_insertion_point(field_release:google.protobuf.MethodDescriptorProto.output_type)
clear_has_output_type();
return output_type_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -7608,6 +7961,7 @@ const ::google::protobuf::MethodOptions& MethodDescriptorProto::options() const
return options_;
}
::google::protobuf::MethodOptions* MethodDescriptorProto::release_options() {
+ // @@protoc_insertion_point(field_release:google.protobuf.MethodDescriptorProto.options)
clear_has_options();
::google::protobuf::MethodOptions* temp = options_;
options_ = NULL;
@@ -7714,7 +8068,6 @@ const int FileOptions::kDeprecatedFieldNumber;
const int FileOptions::kCcEnableArenasFieldNumber;
const int FileOptions::kObjcClassPrefixFieldNumber;
const int FileOptions::kCsharpNamespaceFieldNumber;
-const int FileOptions::kJavananoUseDeprecatedPackageFieldNumber;
const int FileOptions::kUninterpretedOptionFieldNumber;
#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
@@ -7752,7 +8105,6 @@ void FileOptions::SharedCtor() {
cc_enable_arenas_ = false;
objc_class_prefix_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
csharp_namespace_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
- javanano_use_deprecated_package_ = false;
::memset(_has_bits_, 0, sizeof(_has_bits_));
}
@@ -7797,9 +8149,18 @@ FileOptions* FileOptions::New(::google::protobuf::Arena* arena) const {
}
void FileOptions::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.FileOptions)
_extensions_.Clear();
+#if defined(__clang__)
+#define ZR_HELPER_(f) \
+ _Pragma("clang diagnostic push") \
+ _Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"") \
+ __builtin_offsetof(FileOptions, f) \
+ _Pragma("clang diagnostic pop")
+#else
#define ZR_HELPER_(f) reinterpret_cast<char*>(\
&reinterpret_cast<FileOptions*>(16)->f)
+#endif
#define ZR_(first, last) do {\
::memset(&first, 0,\
@@ -7819,8 +8180,8 @@ void FileOptions::Clear() {
go_package_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
}
- if (_has_bits_[8 / 32] & 32512u) {
- ZR_(java_generic_services_, javanano_use_deprecated_package_);
+ if (_has_bits_[8 / 32] & 16128u) {
+ ZR_(java_generic_services_, cc_enable_arenas_);
if (has_objc_class_prefix()) {
objc_class_prefix_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -7841,7 +8202,7 @@ void FileOptions::Clear() {
bool FileOptions::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.FileOptions)
for (;;) {
@@ -8069,21 +8430,6 @@ bool FileOptions::MergePartialFromCodedStream(
} else {
goto handle_unusual;
}
- if (input->ExpectTag(304)) goto parse_javanano_use_deprecated_package;
- break;
- }
-
- // optional bool javanano_use_deprecated_package = 38;
- case 38: {
- if (tag == 304) {
- parse_javanano_use_deprecated_package:
- DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
- bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
- input, &javanano_use_deprecated_package_)));
- set_has_javanano_use_deprecated_package();
- } else {
- goto handle_unusual;
- }
if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
break;
}
@@ -8231,11 +8577,6 @@ void FileOptions::SerializeWithCachedSizes(
37, this->csharp_namespace(), output);
}
- // optional bool javanano_use_deprecated_package = 38;
- if (has_javanano_use_deprecated_package()) {
- ::google::protobuf::internal::WireFormatLite::WriteBool(38, this->javanano_use_deprecated_package(), output);
- }
-
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) {
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
@@ -8253,8 +8594,8 @@ void FileOptions::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.FileOptions)
}
-::google::protobuf::uint8* FileOptions::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* FileOptions::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FileOptions)
// optional string java_package = 1;
if (has_java_package()) {
@@ -8357,21 +8698,16 @@ void FileOptions::SerializeWithCachedSizes(
37, this->csharp_namespace(), target);
}
- // optional bool javanano_use_deprecated_package = 38;
- if (has_javanano_use_deprecated_package()) {
- target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(38, this->javanano_use_deprecated_package(), target);
- }
-
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 999, this->uninterpreted_option(i), target);
+ InternalWriteMessageNoVirtualToArray(
+ 999, this->uninterpreted_option(i), false, target);
}
// Extension range [1000, 536870912)
- target = _extensions_.SerializeWithCachedSizesToArray(
- 1000, 536870912, target);
+ target = _extensions_.InternalSerializeWithCachedSizesToArray(
+ 1000, 536870912, false, target);
if (_internal_metadata_.have_unknown_fields()) {
target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
@@ -8382,6 +8718,7 @@ void FileOptions::SerializeWithCachedSizes(
}
int FileOptions::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.FileOptions)
int total_size = 0;
if (_has_bits_[0 / 32] & 255u) {
@@ -8433,7 +8770,7 @@ int FileOptions::ByteSize() const {
}
}
- if (_has_bits_[8 / 32] & 32512u) {
+ if (_has_bits_[8 / 32] & 16128u) {
// optional bool java_generic_services = 17 [default = false];
if (has_java_generic_services()) {
total_size += 2 + 1;
@@ -8468,11 +8805,6 @@ int FileOptions::ByteSize() const {
this->csharp_namespace());
}
- // optional bool javanano_use_deprecated_package = 38;
- if (has_javanano_use_deprecated_package()) {
- total_size += 2 + 1;
- }
-
}
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
total_size += 2 * this->uninterpreted_option_size();
@@ -8496,19 +8828,27 @@ int FileOptions::ByteSize() const {
}
void FileOptions::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.FileOptions)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const FileOptions* source =
::google::protobuf::internal::DynamicCastToGenerated<const FileOptions>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.FileOptions)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.FileOptions)
MergeFrom(*source);
}
}
void FileOptions::MergeFrom(const FileOptions& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FileOptions)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_java_package()) {
@@ -8560,9 +8900,6 @@ void FileOptions::MergeFrom(const FileOptions& from) {
set_has_csharp_namespace();
csharp_namespace_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.csharp_namespace_);
}
- if (from.has_javanano_use_deprecated_package()) {
- set_javanano_use_deprecated_package(from.javanano_use_deprecated_package());
- }
}
_extensions_.MergeFrom(from._extensions_);
if (from._internal_metadata_.have_unknown_fields()) {
@@ -8571,12 +8908,14 @@ void FileOptions::MergeFrom(const FileOptions& from) {
}
void FileOptions::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.FileOptions)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void FileOptions::CopyFrom(const FileOptions& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.FileOptions)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -8608,7 +8947,6 @@ void FileOptions::InternalSwap(FileOptions* other) {
std::swap(cc_enable_arenas_, other->cc_enable_arenas_);
objc_class_prefix_.Swap(&other->objc_class_prefix_);
csharp_namespace_.Swap(&other->csharp_namespace_);
- std::swap(javanano_use_deprecated_package_, other->javanano_use_deprecated_package_);
uninterpreted_option_.UnsafeArenaSwap(&other->uninterpreted_option_);
std::swap(_has_bits_[0], other->_has_bits_[0]);
_internal_metadata_.Swap(&other->_internal_metadata_);
@@ -8667,6 +9005,7 @@ void FileOptions::clear_java_package() {
return java_package_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* FileOptions::release_java_package() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.java_package)
clear_has_java_package();
return java_package_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -8720,6 +9059,7 @@ void FileOptions::clear_java_outer_classname() {
return java_outer_classname_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* FileOptions::release_java_outer_classname() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.java_outer_classname)
clear_has_java_outer_classname();
return java_outer_classname_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -8870,6 +9210,7 @@ void FileOptions::clear_go_package() {
return go_package_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* FileOptions::release_go_package() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.go_package)
clear_has_go_package();
return go_package_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -9043,6 +9384,7 @@ void FileOptions::clear_objc_class_prefix() {
return objc_class_prefix_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* FileOptions::release_objc_class_prefix() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.objc_class_prefix)
clear_has_objc_class_prefix();
return objc_class_prefix_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -9096,6 +9438,7 @@ void FileOptions::clear_csharp_namespace() {
return csharp_namespace_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* FileOptions::release_csharp_namespace() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.csharp_namespace)
clear_has_csharp_namespace();
return csharp_namespace_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -9109,30 +9452,6 @@ void FileOptions::clear_csharp_namespace() {
// @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.csharp_namespace)
}
-// optional bool javanano_use_deprecated_package = 38;
-bool FileOptions::has_javanano_use_deprecated_package() const {
- return (_has_bits_[0] & 0x00004000u) != 0;
-}
-void FileOptions::set_has_javanano_use_deprecated_package() {
- _has_bits_[0] |= 0x00004000u;
-}
-void FileOptions::clear_has_javanano_use_deprecated_package() {
- _has_bits_[0] &= ~0x00004000u;
-}
-void FileOptions::clear_javanano_use_deprecated_package() {
- javanano_use_deprecated_package_ = false;
- clear_has_javanano_use_deprecated_package();
-}
- bool FileOptions::javanano_use_deprecated_package() const {
- // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.javanano_use_deprecated_package)
- return javanano_use_deprecated_package_;
-}
- void FileOptions::set_javanano_use_deprecated_package(bool value) {
- set_has_javanano_use_deprecated_package();
- javanano_use_deprecated_package_ = value;
- // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.javanano_use_deprecated_package)
-}
-
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
int FileOptions::uninterpreted_option_size() const {
return uninterpreted_option_.size();
@@ -9237,9 +9556,18 @@ MessageOptions* MessageOptions::New(::google::protobuf::Arena* arena) const {
}
void MessageOptions::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.MessageOptions)
_extensions_.Clear();
+#if defined(__clang__)
+#define ZR_HELPER_(f) \
+ _Pragma("clang diagnostic push") \
+ _Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"") \
+ __builtin_offsetof(MessageOptions, f) \
+ _Pragma("clang diagnostic pop")
+#else
#define ZR_HELPER_(f) reinterpret_cast<char*>(\
&reinterpret_cast<MessageOptions*>(16)->f)
+#endif
#define ZR_(first, last) do {\
::memset(&first, 0,\
@@ -9260,7 +9588,7 @@ void MessageOptions::Clear() {
bool MessageOptions::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.MessageOptions)
for (;;) {
@@ -9411,8 +9739,8 @@ void MessageOptions::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.MessageOptions)
}
-::google::protobuf::uint8* MessageOptions::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* MessageOptions::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.MessageOptions)
// optional bool message_set_wire_format = 1 [default = false];
if (has_message_set_wire_format()) {
@@ -9437,13 +9765,13 @@ void MessageOptions::SerializeWithCachedSizes(
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 999, this->uninterpreted_option(i), target);
+ InternalWriteMessageNoVirtualToArray(
+ 999, this->uninterpreted_option(i), false, target);
}
// Extension range [1000, 536870912)
- target = _extensions_.SerializeWithCachedSizesToArray(
- 1000, 536870912, target);
+ target = _extensions_.InternalSerializeWithCachedSizesToArray(
+ 1000, 536870912, false, target);
if (_internal_metadata_.have_unknown_fields()) {
target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
@@ -9454,6 +9782,7 @@ void MessageOptions::SerializeWithCachedSizes(
}
int MessageOptions::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.MessageOptions)
int total_size = 0;
if (_has_bits_[0 / 32] & 15u) {
@@ -9500,19 +9829,27 @@ int MessageOptions::ByteSize() const {
}
void MessageOptions::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.MessageOptions)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const MessageOptions* source =
::google::protobuf::internal::DynamicCastToGenerated<const MessageOptions>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.MessageOptions)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.MessageOptions)
MergeFrom(*source);
}
}
void MessageOptions::MergeFrom(const MessageOptions& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.MessageOptions)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_message_set_wire_format()) {
@@ -9535,12 +9872,14 @@ void MessageOptions::MergeFrom(const MessageOptions& from) {
}
void MessageOptions::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.MessageOptions)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void MessageOptions::CopyFrom(const MessageOptions& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.MessageOptions)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -9830,9 +10169,18 @@ FieldOptions* FieldOptions::New(::google::protobuf::Arena* arena) const {
}
void FieldOptions::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.FieldOptions)
_extensions_.Clear();
+#if defined(__clang__)
+#define ZR_HELPER_(f) \
+ _Pragma("clang diagnostic push") \
+ _Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"") \
+ __builtin_offsetof(FieldOptions, f) \
+ _Pragma("clang diagnostic pop")
+#else
#define ZR_HELPER_(f) reinterpret_cast<char*>(\
&reinterpret_cast<FieldOptions*>(16)->f)
+#endif
#define ZR_(first, last) do {\
::memset(&first, 0,\
@@ -9856,7 +10204,7 @@ void FieldOptions::Clear() {
bool FieldOptions::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.FieldOptions)
for (;;) {
@@ -10059,8 +10407,8 @@ void FieldOptions::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.FieldOptions)
}
-::google::protobuf::uint8* FieldOptions::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* FieldOptions::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FieldOptions)
// optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
if (has_ctype()) {
@@ -10097,13 +10445,13 @@ void FieldOptions::SerializeWithCachedSizes(
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 999, this->uninterpreted_option(i), target);
+ InternalWriteMessageNoVirtualToArray(
+ 999, this->uninterpreted_option(i), false, target);
}
// Extension range [1000, 536870912)
- target = _extensions_.SerializeWithCachedSizesToArray(
- 1000, 536870912, target);
+ target = _extensions_.InternalSerializeWithCachedSizesToArray(
+ 1000, 536870912, false, target);
if (_internal_metadata_.have_unknown_fields()) {
target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
@@ -10114,6 +10462,7 @@ void FieldOptions::SerializeWithCachedSizes(
}
int FieldOptions::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.FieldOptions)
int total_size = 0;
if (_has_bits_[0 / 32] & 63u) {
@@ -10172,19 +10521,27 @@ int FieldOptions::ByteSize() const {
}
void FieldOptions::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.FieldOptions)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const FieldOptions* source =
::google::protobuf::internal::DynamicCastToGenerated<const FieldOptions>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.FieldOptions)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.FieldOptions)
MergeFrom(*source);
}
}
void FieldOptions::MergeFrom(const FieldOptions& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FieldOptions)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_ctype()) {
@@ -10213,12 +10570,14 @@ void FieldOptions::MergeFrom(const FieldOptions& from) {
}
void FieldOptions::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.FieldOptions)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void FieldOptions::CopyFrom(const FieldOptions& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.FieldOptions)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -10441,6 +10800,304 @@ FieldOptions::uninterpreted_option() const {
// ===================================================================
#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int OneofOptions::kUninterpretedOptionFieldNumber;
+#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+OneofOptions::OneofOptions()
+ : ::google::protobuf::Message(), _internal_metadata_(NULL) {
+ SharedCtor();
+ // @@protoc_insertion_point(constructor:google.protobuf.OneofOptions)
+}
+
+void OneofOptions::InitAsDefaultInstance() {
+}
+
+OneofOptions::OneofOptions(const OneofOptions& from)
+ : ::google::protobuf::Message(),
+ _internal_metadata_(NULL) {
+ SharedCtor();
+ MergeFrom(from);
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.OneofOptions)
+}
+
+void OneofOptions::SharedCtor() {
+ _cached_size_ = 0;
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+OneofOptions::~OneofOptions() {
+ // @@protoc_insertion_point(destructor:google.protobuf.OneofOptions)
+ SharedDtor();
+}
+
+void OneofOptions::SharedDtor() {
+ if (this != default_instance_) {
+ }
+}
+
+void OneofOptions::SetCachedSize(int size) const {
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* OneofOptions::descriptor() {
+ protobuf_AssignDescriptorsOnce();
+ return OneofOptions_descriptor_;
+}
+
+const OneofOptions& OneofOptions::default_instance() {
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ return *default_instance_;
+}
+
+OneofOptions* OneofOptions::default_instance_ = NULL;
+
+OneofOptions* OneofOptions::New(::google::protobuf::Arena* arena) const {
+ OneofOptions* n = new OneofOptions;
+ if (arena != NULL) {
+ arena->Own(n);
+ }
+ return n;
+}
+
+void OneofOptions::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.OneofOptions)
+ _extensions_.Clear();
+ uninterpreted_option_.Clear();
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+ if (_internal_metadata_.have_unknown_fields()) {
+ mutable_unknown_fields()->Clear();
+ }
+}
+
+bool OneofOptions::MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+ ::google::protobuf::uint32 tag;
+ // @@protoc_insertion_point(parse_start:google.protobuf.OneofOptions)
+ for (;;) {
+ ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(16383);
+ tag = p.first;
+ if (!p.second) goto handle_unusual;
+ switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ case 999: {
+ if (tag == 7994) {
+ DO_(input->IncrementRecursionDepth());
+ parse_loop_uninterpreted_option:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+ input, add_uninterpreted_option()));
+ } else {
+ goto handle_unusual;
+ }
+ if (input->ExpectTag(7994)) goto parse_loop_uninterpreted_option;
+ input->UnsafeDecrementRecursionDepth();
+ if (input->ExpectAtEnd()) goto success;
+ break;
+ }
+
+ default: {
+ handle_unusual:
+ if (tag == 0 ||
+ ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+ goto success;
+ }
+ if ((8000u <= tag)) {
+ DO_(_extensions_.ParseField(tag, input, default_instance_,
+ mutable_unknown_fields()));
+ continue;
+ }
+ DO_(::google::protobuf::internal::WireFormat::SkipField(
+ input, tag, mutable_unknown_fields()));
+ break;
+ }
+ }
+ }
+success:
+ // @@protoc_insertion_point(parse_success:google.protobuf.OneofOptions)
+ return true;
+failure:
+ // @@protoc_insertion_point(parse_failure:google.protobuf.OneofOptions)
+ return false;
+#undef DO_
+}
+
+void OneofOptions::SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const {
+ // @@protoc_insertion_point(serialize_start:google.protobuf.OneofOptions)
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+ 999, this->uninterpreted_option(i), output);
+ }
+
+ // Extension range [1000, 536870912)
+ _extensions_.SerializeWithCachedSizes(
+ 1000, 536870912, output);
+
+ if (_internal_metadata_.have_unknown_fields()) {
+ ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+ unknown_fields(), output);
+ }
+ // @@protoc_insertion_point(serialize_end:google.protobuf.OneofOptions)
+}
+
+::google::protobuf::uint8* OneofOptions::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.OneofOptions)
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ InternalWriteMessageNoVirtualToArray(
+ 999, this->uninterpreted_option(i), false, target);
+ }
+
+ // Extension range [1000, 536870912)
+ target = _extensions_.InternalSerializeWithCachedSizesToArray(
+ 1000, 536870912, false, target);
+
+ if (_internal_metadata_.have_unknown_fields()) {
+ target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+ unknown_fields(), target);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.OneofOptions)
+ return target;
+}
+
+int OneofOptions::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.OneofOptions)
+ int total_size = 0;
+
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ total_size += 2 * this->uninterpreted_option_size();
+ for (int i = 0; i < this->uninterpreted_option_size(); i++) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->uninterpreted_option(i));
+ }
+
+ total_size += _extensions_.ByteSize();
+
+ if (_internal_metadata_.have_unknown_fields()) {
+ total_size +=
+ ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+ unknown_fields());
+ }
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = total_size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+ return total_size;
+}
+
+void OneofOptions::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.OneofOptions)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
+ const OneofOptions* source =
+ ::google::protobuf::internal::DynamicCastToGenerated<const OneofOptions>(
+ &from);
+ if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.OneofOptions)
+ ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+ } else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.OneofOptions)
+ MergeFrom(*source);
+ }
+}
+
+void OneofOptions::MergeFrom(const OneofOptions& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.OneofOptions)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
+ uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
+ _extensions_.MergeFrom(from._extensions_);
+ if (from._internal_metadata_.have_unknown_fields()) {
+ mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+ }
+}
+
+void OneofOptions::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.OneofOptions)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+void OneofOptions::CopyFrom(const OneofOptions& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.OneofOptions)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool OneofOptions::IsInitialized() const {
+
+ if (!::google::protobuf::internal::AllAreInitialized(this->uninterpreted_option())) return false;
+
+ if (!_extensions_.IsInitialized()) return false; return true;
+}
+
+void OneofOptions::Swap(OneofOptions* other) {
+ if (other == this) return;
+ InternalSwap(other);
+}
+void OneofOptions::InternalSwap(OneofOptions* other) {
+ uninterpreted_option_.UnsafeArenaSwap(&other->uninterpreted_option_);
+ std::swap(_has_bits_[0], other->_has_bits_[0]);
+ _internal_metadata_.Swap(&other->_internal_metadata_);
+ std::swap(_cached_size_, other->_cached_size_);
+ _extensions_.Swap(&other->_extensions_);
+}
+
+::google::protobuf::Metadata OneofOptions::GetMetadata() const {
+ protobuf_AssignDescriptorsOnce();
+ ::google::protobuf::Metadata metadata;
+ metadata.descriptor = OneofOptions_descriptor_;
+ metadata.reflection = OneofOptions_reflection_;
+ return metadata;
+}
+
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// OneofOptions
+
+// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+int OneofOptions::uninterpreted_option_size() const {
+ return uninterpreted_option_.size();
+}
+void OneofOptions::clear_uninterpreted_option() {
+ uninterpreted_option_.Clear();
+}
+const ::google::protobuf::UninterpretedOption& OneofOptions::uninterpreted_option(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.OneofOptions.uninterpreted_option)
+ return uninterpreted_option_.Get(index);
+}
+::google::protobuf::UninterpretedOption* OneofOptions::mutable_uninterpreted_option(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.OneofOptions.uninterpreted_option)
+ return uninterpreted_option_.Mutable(index);
+}
+::google::protobuf::UninterpretedOption* OneofOptions::add_uninterpreted_option() {
+ // @@protoc_insertion_point(field_add:google.protobuf.OneofOptions.uninterpreted_option)
+ return uninterpreted_option_.Add();
+}
+::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+OneofOptions::mutable_uninterpreted_option() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.OneofOptions.uninterpreted_option)
+ return &uninterpreted_option_;
+}
+const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+OneofOptions::uninterpreted_option() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.OneofOptions.uninterpreted_option)
+ return uninterpreted_option_;
+}
+
+#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
+
+// ===================================================================
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int EnumOptions::kAllowAliasFieldNumber;
const int EnumOptions::kDeprecatedFieldNumber;
const int EnumOptions::kUninterpretedOptionFieldNumber;
@@ -10506,9 +11163,18 @@ EnumOptions* EnumOptions::New(::google::protobuf::Arena* arena) const {
}
void EnumOptions::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.EnumOptions)
_extensions_.Clear();
+#if defined(__clang__)
+#define ZR_HELPER_(f) \
+ _Pragma("clang diagnostic push") \
+ _Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"") \
+ __builtin_offsetof(EnumOptions, f) \
+ _Pragma("clang diagnostic pop")
+#else
#define ZR_HELPER_(f) reinterpret_cast<char*>(\
&reinterpret_cast<EnumOptions*>(16)->f)
+#endif
#define ZR_(first, last) do {\
::memset(&first, 0,\
@@ -10529,7 +11195,7 @@ void EnumOptions::Clear() {
bool EnumOptions::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.EnumOptions)
for (;;) {
@@ -10640,8 +11306,8 @@ void EnumOptions::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.EnumOptions)
}
-::google::protobuf::uint8* EnumOptions::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* EnumOptions::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumOptions)
// optional bool allow_alias = 2;
if (has_allow_alias()) {
@@ -10656,13 +11322,13 @@ void EnumOptions::SerializeWithCachedSizes(
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 999, this->uninterpreted_option(i), target);
+ InternalWriteMessageNoVirtualToArray(
+ 999, this->uninterpreted_option(i), false, target);
}
// Extension range [1000, 536870912)
- target = _extensions_.SerializeWithCachedSizesToArray(
- 1000, 536870912, target);
+ target = _extensions_.InternalSerializeWithCachedSizesToArray(
+ 1000, 536870912, false, target);
if (_internal_metadata_.have_unknown_fields()) {
target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
@@ -10673,6 +11339,7 @@ void EnumOptions::SerializeWithCachedSizes(
}
int EnumOptions::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.EnumOptions)
int total_size = 0;
if (_has_bits_[0 / 32] & 3u) {
@@ -10709,19 +11376,27 @@ int EnumOptions::ByteSize() const {
}
void EnumOptions::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.EnumOptions)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const EnumOptions* source =
::google::protobuf::internal::DynamicCastToGenerated<const EnumOptions>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.EnumOptions)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.EnumOptions)
MergeFrom(*source);
}
}
void EnumOptions::MergeFrom(const EnumOptions& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumOptions)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_allow_alias()) {
@@ -10738,12 +11413,14 @@ void EnumOptions::MergeFrom(const EnumOptions& from) {
}
void EnumOptions::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.EnumOptions)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void EnumOptions::CopyFrom(const EnumOptions& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.EnumOptions)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -10927,6 +11604,7 @@ EnumValueOptions* EnumValueOptions::New(::google::protobuf::Arena* arena) const
}
void EnumValueOptions::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.EnumValueOptions)
_extensions_.Clear();
deprecated_ = false;
uninterpreted_option_.Clear();
@@ -10938,7 +11616,7 @@ void EnumValueOptions::Clear() {
bool EnumValueOptions::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.EnumValueOptions)
for (;;) {
@@ -11029,8 +11707,8 @@ void EnumValueOptions::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.EnumValueOptions)
}
-::google::protobuf::uint8* EnumValueOptions::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* EnumValueOptions::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumValueOptions)
// optional bool deprecated = 1 [default = false];
if (has_deprecated()) {
@@ -11040,13 +11718,13 @@ void EnumValueOptions::SerializeWithCachedSizes(
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 999, this->uninterpreted_option(i), target);
+ InternalWriteMessageNoVirtualToArray(
+ 999, this->uninterpreted_option(i), false, target);
}
// Extension range [1000, 536870912)
- target = _extensions_.SerializeWithCachedSizesToArray(
- 1000, 536870912, target);
+ target = _extensions_.InternalSerializeWithCachedSizesToArray(
+ 1000, 536870912, false, target);
if (_internal_metadata_.have_unknown_fields()) {
target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
@@ -11057,6 +11735,7 @@ void EnumValueOptions::SerializeWithCachedSizes(
}
int EnumValueOptions::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.EnumValueOptions)
int total_size = 0;
// optional bool deprecated = 1 [default = false];
@@ -11086,19 +11765,27 @@ int EnumValueOptions::ByteSize() const {
}
void EnumValueOptions::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.EnumValueOptions)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const EnumValueOptions* source =
::google::protobuf::internal::DynamicCastToGenerated<const EnumValueOptions>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.EnumValueOptions)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.EnumValueOptions)
MergeFrom(*source);
}
}
void EnumValueOptions::MergeFrom(const EnumValueOptions& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumValueOptions)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_deprecated()) {
@@ -11112,12 +11799,14 @@ void EnumValueOptions::MergeFrom(const EnumValueOptions& from) {
}
void EnumValueOptions::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.EnumValueOptions)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void EnumValueOptions::CopyFrom(const EnumValueOptions& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.EnumValueOptions)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -11276,6 +11965,7 @@ ServiceOptions* ServiceOptions::New(::google::protobuf::Arena* arena) const {
}
void ServiceOptions::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.ServiceOptions)
_extensions_.Clear();
deprecated_ = false;
uninterpreted_option_.Clear();
@@ -11287,7 +11977,7 @@ void ServiceOptions::Clear() {
bool ServiceOptions::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.ServiceOptions)
for (;;) {
@@ -11378,8 +12068,8 @@ void ServiceOptions::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.ServiceOptions)
}
-::google::protobuf::uint8* ServiceOptions::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* ServiceOptions::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.ServiceOptions)
// optional bool deprecated = 33 [default = false];
if (has_deprecated()) {
@@ -11389,13 +12079,13 @@ void ServiceOptions::SerializeWithCachedSizes(
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 999, this->uninterpreted_option(i), target);
+ InternalWriteMessageNoVirtualToArray(
+ 999, this->uninterpreted_option(i), false, target);
}
// Extension range [1000, 536870912)
- target = _extensions_.SerializeWithCachedSizesToArray(
- 1000, 536870912, target);
+ target = _extensions_.InternalSerializeWithCachedSizesToArray(
+ 1000, 536870912, false, target);
if (_internal_metadata_.have_unknown_fields()) {
target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
@@ -11406,6 +12096,7 @@ void ServiceOptions::SerializeWithCachedSizes(
}
int ServiceOptions::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.ServiceOptions)
int total_size = 0;
// optional bool deprecated = 33 [default = false];
@@ -11435,19 +12126,27 @@ int ServiceOptions::ByteSize() const {
}
void ServiceOptions::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.ServiceOptions)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const ServiceOptions* source =
::google::protobuf::internal::DynamicCastToGenerated<const ServiceOptions>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.ServiceOptions)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.ServiceOptions)
MergeFrom(*source);
}
}
void ServiceOptions::MergeFrom(const ServiceOptions& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.ServiceOptions)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_deprecated()) {
@@ -11461,12 +12160,14 @@ void ServiceOptions::MergeFrom(const ServiceOptions& from) {
}
void ServiceOptions::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.ServiceOptions)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void ServiceOptions::CopyFrom(const ServiceOptions& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.ServiceOptions)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -11625,6 +12326,7 @@ MethodOptions* MethodOptions::New(::google::protobuf::Arena* arena) const {
}
void MethodOptions::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.MethodOptions)
_extensions_.Clear();
deprecated_ = false;
uninterpreted_option_.Clear();
@@ -11636,7 +12338,7 @@ void MethodOptions::Clear() {
bool MethodOptions::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.MethodOptions)
for (;;) {
@@ -11727,8 +12429,8 @@ void MethodOptions::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.MethodOptions)
}
-::google::protobuf::uint8* MethodOptions::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* MethodOptions::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.MethodOptions)
// optional bool deprecated = 33 [default = false];
if (has_deprecated()) {
@@ -11738,13 +12440,13 @@ void MethodOptions::SerializeWithCachedSizes(
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 999, this->uninterpreted_option(i), target);
+ InternalWriteMessageNoVirtualToArray(
+ 999, this->uninterpreted_option(i), false, target);
}
// Extension range [1000, 536870912)
- target = _extensions_.SerializeWithCachedSizesToArray(
- 1000, 536870912, target);
+ target = _extensions_.InternalSerializeWithCachedSizesToArray(
+ 1000, 536870912, false, target);
if (_internal_metadata_.have_unknown_fields()) {
target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
@@ -11755,6 +12457,7 @@ void MethodOptions::SerializeWithCachedSizes(
}
int MethodOptions::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.MethodOptions)
int total_size = 0;
// optional bool deprecated = 33 [default = false];
@@ -11784,19 +12487,27 @@ int MethodOptions::ByteSize() const {
}
void MethodOptions::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.MethodOptions)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const MethodOptions* source =
::google::protobuf::internal::DynamicCastToGenerated<const MethodOptions>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.MethodOptions)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.MethodOptions)
MergeFrom(*source);
}
}
void MethodOptions::MergeFrom(const MethodOptions& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.MethodOptions)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_deprecated()) {
@@ -11810,12 +12521,14 @@ void MethodOptions::MergeFrom(const MethodOptions& from) {
}
void MethodOptions::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.MethodOptions)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void MethodOptions::CopyFrom(const MethodOptions& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.MethodOptions)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -11977,6 +12690,7 @@ UninterpretedOption_NamePart* UninterpretedOption_NamePart::New(::google::protob
}
void UninterpretedOption_NamePart::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.UninterpretedOption.NamePart)
if (_has_bits_[0 / 32] & 3u) {
if (has_name_part()) {
name_part_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
@@ -11991,7 +12705,7 @@ void UninterpretedOption_NamePart::Clear() {
bool UninterpretedOption_NamePart::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.UninterpretedOption.NamePart)
for (;;) {
@@ -12077,8 +12791,8 @@ void UninterpretedOption_NamePart::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.UninterpretedOption.NamePart)
}
-::google::protobuf::uint8* UninterpretedOption_NamePart::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* UninterpretedOption_NamePart::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.UninterpretedOption.NamePart)
// required string name_part = 1;
if (has_name_part()) {
@@ -12105,6 +12819,7 @@ void UninterpretedOption_NamePart::SerializeWithCachedSizes(
}
int UninterpretedOption_NamePart::RequiredFieldsByteSizeFallback() const {
+// @@protoc_insertion_point(required_fields_byte_size_fallback_start:google.protobuf.UninterpretedOption.NamePart)
int total_size = 0;
if (has_name_part()) {
@@ -12122,6 +12837,7 @@ int UninterpretedOption_NamePart::RequiredFieldsByteSizeFallback() const {
return total_size;
}
int UninterpretedOption_NamePart::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.UninterpretedOption.NamePart)
int total_size = 0;
if (((_has_bits_[0] & 0x00000003) ^ 0x00000003) == 0) { // All required fields are present.
@@ -12148,19 +12864,27 @@ int UninterpretedOption_NamePart::ByteSize() const {
}
void UninterpretedOption_NamePart::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.UninterpretedOption.NamePart)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const UninterpretedOption_NamePart* source =
::google::protobuf::internal::DynamicCastToGenerated<const UninterpretedOption_NamePart>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.UninterpretedOption.NamePart)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.UninterpretedOption.NamePart)
MergeFrom(*source);
}
}
void UninterpretedOption_NamePart::MergeFrom(const UninterpretedOption_NamePart& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.UninterpretedOption.NamePart)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_name_part()) {
set_has_name_part();
@@ -12176,12 +12900,14 @@ void UninterpretedOption_NamePart::MergeFrom(const UninterpretedOption_NamePart&
}
void UninterpretedOption_NamePart::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.UninterpretedOption.NamePart)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void UninterpretedOption_NamePart::CopyFrom(const UninterpretedOption_NamePart& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.UninterpretedOption.NamePart)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -12294,8 +13020,17 @@ UninterpretedOption* UninterpretedOption::New(::google::protobuf::Arena* arena)
}
void UninterpretedOption::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.UninterpretedOption)
+#if defined(__clang__)
+#define ZR_HELPER_(f) \
+ _Pragma("clang diagnostic push") \
+ _Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"") \
+ __builtin_offsetof(UninterpretedOption, f) \
+ _Pragma("clang diagnostic pop")
+#else
#define ZR_HELPER_(f) reinterpret_cast<char*>(\
&reinterpret_cast<UninterpretedOption*>(16)->f)
+#endif
#define ZR_(first, last) do {\
::memset(&first, 0,\
@@ -12327,7 +13062,7 @@ void UninterpretedOption::Clear() {
bool UninterpretedOption::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.UninterpretedOption)
for (;;) {
@@ -12522,14 +13257,14 @@ void UninterpretedOption::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.UninterpretedOption)
}
-::google::protobuf::uint8* UninterpretedOption::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* UninterpretedOption::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.UninterpretedOption)
// repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
for (unsigned int i = 0, n = this->name_size(); i < n; i++) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 2, this->name(i), target);
+ InternalWriteMessageNoVirtualToArray(
+ 2, this->name(i), false, target);
}
// optional string identifier_value = 3;
@@ -12585,6 +13320,7 @@ void UninterpretedOption::SerializeWithCachedSizes(
}
int UninterpretedOption::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.UninterpretedOption)
int total_size = 0;
if (_has_bits_[1 / 32] & 126u) {
@@ -12649,19 +13385,27 @@ int UninterpretedOption::ByteSize() const {
}
void UninterpretedOption::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.UninterpretedOption)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const UninterpretedOption* source =
::google::protobuf::internal::DynamicCastToGenerated<const UninterpretedOption>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.UninterpretedOption)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.UninterpretedOption)
MergeFrom(*source);
}
}
void UninterpretedOption::MergeFrom(const UninterpretedOption& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.UninterpretedOption)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
name_.MergeFrom(from.name_);
if (from._has_bits_[1 / 32] & (0xffu << (1 % 32))) {
if (from.has_identifier_value()) {
@@ -12692,12 +13436,14 @@ void UninterpretedOption::MergeFrom(const UninterpretedOption& from) {
}
void UninterpretedOption::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.UninterpretedOption)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void UninterpretedOption::CopyFrom(const UninterpretedOption& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.UninterpretedOption)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -12777,6 +13523,7 @@ void UninterpretedOption_NamePart::clear_name_part() {
return name_part_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* UninterpretedOption_NamePart::release_name_part() {
+ // @@protoc_insertion_point(field_release:google.protobuf.UninterpretedOption.NamePart.name_part)
clear_has_name_part();
return name_part_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -12888,6 +13635,7 @@ void UninterpretedOption::clear_identifier_value() {
return identifier_value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* UninterpretedOption::release_identifier_value() {
+ // @@protoc_insertion_point(field_release:google.protobuf.UninterpretedOption.identifier_value)
clear_has_identifier_value();
return identifier_value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -13013,6 +13761,7 @@ void UninterpretedOption::clear_string_value() {
return string_value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* UninterpretedOption::release_string_value() {
+ // @@protoc_insertion_point(field_release:google.protobuf.UninterpretedOption.string_value)
clear_has_string_value();
return string_value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -13066,6 +13815,7 @@ void UninterpretedOption::clear_aggregate_value() {
return aggregate_value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* UninterpretedOption::release_aggregate_value() {
+ // @@protoc_insertion_point(field_release:google.protobuf.UninterpretedOption.aggregate_value)
clear_has_aggregate_value();
return aggregate_value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -13154,6 +13904,7 @@ SourceCodeInfo_Location* SourceCodeInfo_Location::New(::google::protobuf::Arena*
}
void SourceCodeInfo_Location::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.SourceCodeInfo.Location)
if (_has_bits_[0 / 32] & 12u) {
if (has_leading_comments()) {
leading_comments_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
@@ -13173,7 +13924,7 @@ void SourceCodeInfo_Location::Clear() {
bool SourceCodeInfo_Location::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.SourceCodeInfo.Location)
for (;;) {
@@ -13351,8 +14102,8 @@ void SourceCodeInfo_Location::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.SourceCodeInfo.Location)
}
-::google::protobuf::uint8* SourceCodeInfo_Location::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* SourceCodeInfo_Location::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.SourceCodeInfo.Location)
// repeated int32 path = 1 [packed = true];
if (this->path_size() > 0) {
@@ -13423,6 +14174,7 @@ void SourceCodeInfo_Location::SerializeWithCachedSizes(
}
int SourceCodeInfo_Location::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.SourceCodeInfo.Location)
int total_size = 0;
if (_has_bits_[2 / 32] & 12u) {
@@ -13494,19 +14246,27 @@ int SourceCodeInfo_Location::ByteSize() const {
}
void SourceCodeInfo_Location::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.SourceCodeInfo.Location)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const SourceCodeInfo_Location* source =
::google::protobuf::internal::DynamicCastToGenerated<const SourceCodeInfo_Location>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.SourceCodeInfo.Location)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.SourceCodeInfo.Location)
MergeFrom(*source);
}
}
void SourceCodeInfo_Location::MergeFrom(const SourceCodeInfo_Location& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.SourceCodeInfo.Location)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
path_.MergeFrom(from.path_);
span_.MergeFrom(from.span_);
leading_detached_comments_.MergeFrom(from.leading_detached_comments_);
@@ -13526,12 +14286,14 @@ void SourceCodeInfo_Location::MergeFrom(const SourceCodeInfo_Location& from) {
}
void SourceCodeInfo_Location::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.SourceCodeInfo.Location)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void SourceCodeInfo_Location::CopyFrom(const SourceCodeInfo_Location& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.SourceCodeInfo.Location)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -13630,6 +14392,7 @@ SourceCodeInfo* SourceCodeInfo::New(::google::protobuf::Arena* arena) const {
}
void SourceCodeInfo::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.SourceCodeInfo)
location_.Clear();
::memset(_has_bits_, 0, sizeof(_has_bits_));
if (_internal_metadata_.have_unknown_fields()) {
@@ -13639,7 +14402,7 @@ void SourceCodeInfo::Clear() {
bool SourceCodeInfo::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.SourceCodeInfo)
for (;;) {
@@ -13701,14 +14464,14 @@ void SourceCodeInfo::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.SourceCodeInfo)
}
-::google::protobuf::uint8* SourceCodeInfo::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* SourceCodeInfo::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.SourceCodeInfo)
// repeated .google.protobuf.SourceCodeInfo.Location location = 1;
for (unsigned int i = 0, n = this->location_size(); i < n; i++) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 1, this->location(i), target);
+ InternalWriteMessageNoVirtualToArray(
+ 1, this->location(i), false, target);
}
if (_internal_metadata_.have_unknown_fields()) {
@@ -13720,6 +14483,7 @@ void SourceCodeInfo::SerializeWithCachedSizes(
}
int SourceCodeInfo::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.SourceCodeInfo)
int total_size = 0;
// repeated .google.protobuf.SourceCodeInfo.Location location = 1;
@@ -13742,19 +14506,27 @@ int SourceCodeInfo::ByteSize() const {
}
void SourceCodeInfo::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.SourceCodeInfo)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const SourceCodeInfo* source =
::google::protobuf::internal::DynamicCastToGenerated<const SourceCodeInfo>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.SourceCodeInfo)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.SourceCodeInfo)
MergeFrom(*source);
}
}
void SourceCodeInfo::MergeFrom(const SourceCodeInfo& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.SourceCodeInfo)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
location_.MergeFrom(from.location_);
if (from._internal_metadata_.have_unknown_fields()) {
mutable_unknown_fields()->MergeFrom(from.unknown_fields());
@@ -13762,12 +14534,14 @@ void SourceCodeInfo::MergeFrom(const SourceCodeInfo& from) {
}
void SourceCodeInfo::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.SourceCodeInfo)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void SourceCodeInfo::CopyFrom(const SourceCodeInfo& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.SourceCodeInfo)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -13900,6 +14674,7 @@ void SourceCodeInfo_Location::clear_leading_comments() {
return leading_comments_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* SourceCodeInfo_Location::release_leading_comments() {
+ // @@protoc_insertion_point(field_release:google.protobuf.SourceCodeInfo.Location.leading_comments)
clear_has_leading_comments();
return leading_comments_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -13953,6 +14728,7 @@ void SourceCodeInfo_Location::clear_trailing_comments() {
return trailing_comments_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* SourceCodeInfo_Location::release_trailing_comments() {
+ // @@protoc_insertion_point(field_release:google.protobuf.SourceCodeInfo.Location.trailing_comments)
clear_has_trailing_comments();
return trailing_comments_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -13995,6 +14771,7 @@ void SourceCodeInfo_Location::clear_leading_detached_comments() {
// @@protoc_insertion_point(field_set_pointer:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
}
::std::string* SourceCodeInfo_Location::add_leading_detached_comments() {
+ // @@protoc_insertion_point(field_add_mutable:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
return leading_detached_comments_.Add();
}
void SourceCodeInfo_Location::add_leading_detached_comments(const ::std::string& value) {
@@ -14056,6 +14833,845 @@ SourceCodeInfo::location() const {
#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
+// ===================================================================
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int GeneratedCodeInfo_Annotation::kPathFieldNumber;
+const int GeneratedCodeInfo_Annotation::kSourceFileFieldNumber;
+const int GeneratedCodeInfo_Annotation::kBeginFieldNumber;
+const int GeneratedCodeInfo_Annotation::kEndFieldNumber;
+#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+GeneratedCodeInfo_Annotation::GeneratedCodeInfo_Annotation()
+ : ::google::protobuf::Message(), _internal_metadata_(NULL) {
+ SharedCtor();
+ // @@protoc_insertion_point(constructor:google.protobuf.GeneratedCodeInfo.Annotation)
+}
+
+void GeneratedCodeInfo_Annotation::InitAsDefaultInstance() {
+}
+
+GeneratedCodeInfo_Annotation::GeneratedCodeInfo_Annotation(const GeneratedCodeInfo_Annotation& from)
+ : ::google::protobuf::Message(),
+ _internal_metadata_(NULL) {
+ SharedCtor();
+ MergeFrom(from);
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.GeneratedCodeInfo.Annotation)
+}
+
+void GeneratedCodeInfo_Annotation::SharedCtor() {
+ ::google::protobuf::internal::GetEmptyString();
+ _cached_size_ = 0;
+ source_file_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ begin_ = 0;
+ end_ = 0;
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+GeneratedCodeInfo_Annotation::~GeneratedCodeInfo_Annotation() {
+ // @@protoc_insertion_point(destructor:google.protobuf.GeneratedCodeInfo.Annotation)
+ SharedDtor();
+}
+
+void GeneratedCodeInfo_Annotation::SharedDtor() {
+ source_file_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ if (this != default_instance_) {
+ }
+}
+
+void GeneratedCodeInfo_Annotation::SetCachedSize(int size) const {
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* GeneratedCodeInfo_Annotation::descriptor() {
+ protobuf_AssignDescriptorsOnce();
+ return GeneratedCodeInfo_Annotation_descriptor_;
+}
+
+const GeneratedCodeInfo_Annotation& GeneratedCodeInfo_Annotation::default_instance() {
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ return *default_instance_;
+}
+
+GeneratedCodeInfo_Annotation* GeneratedCodeInfo_Annotation::default_instance_ = NULL;
+
+GeneratedCodeInfo_Annotation* GeneratedCodeInfo_Annotation::New(::google::protobuf::Arena* arena) const {
+ GeneratedCodeInfo_Annotation* n = new GeneratedCodeInfo_Annotation;
+ if (arena != NULL) {
+ arena->Own(n);
+ }
+ return n;
+}
+
+void GeneratedCodeInfo_Annotation::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.GeneratedCodeInfo.Annotation)
+#if defined(__clang__)
+#define ZR_HELPER_(f) \
+ _Pragma("clang diagnostic push") \
+ _Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"") \
+ __builtin_offsetof(GeneratedCodeInfo_Annotation, f) \
+ _Pragma("clang diagnostic pop")
+#else
+#define ZR_HELPER_(f) reinterpret_cast<char*>(\
+ &reinterpret_cast<GeneratedCodeInfo_Annotation*>(16)->f)
+#endif
+
+#define ZR_(first, last) do {\
+ ::memset(&first, 0,\
+ ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\
+} while (0)
+
+ if (_has_bits_[0 / 32] & 14u) {
+ ZR_(begin_, end_);
+ if (has_source_file()) {
+ source_file_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ }
+ }
+
+#undef ZR_HELPER_
+#undef ZR_
+
+ path_.Clear();
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+ if (_internal_metadata_.have_unknown_fields()) {
+ mutable_unknown_fields()->Clear();
+ }
+}
+
+bool GeneratedCodeInfo_Annotation::MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+ ::google::protobuf::uint32 tag;
+ // @@protoc_insertion_point(parse_start:google.protobuf.GeneratedCodeInfo.Annotation)
+ for (;;) {
+ ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
+ tag = p.first;
+ if (!p.second) goto handle_unusual;
+ switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+ // repeated int32 path = 1 [packed = true];
+ case 1: {
+ if (tag == 10) {
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
+ ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+ input, this->mutable_path())));
+ } else if (tag == 8) {
+ DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
+ ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+ 1, 10, input, this->mutable_path())));
+ } else {
+ goto handle_unusual;
+ }
+ if (input->ExpectTag(18)) goto parse_source_file;
+ break;
+ }
+
+ // optional string source_file = 2;
+ case 2: {
+ if (tag == 18) {
+ parse_source_file:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+ input, this->mutable_source_file()));
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->source_file().data(), this->source_file().length(),
+ ::google::protobuf::internal::WireFormat::PARSE,
+ "google.protobuf.GeneratedCodeInfo.Annotation.source_file");
+ } else {
+ goto handle_unusual;
+ }
+ if (input->ExpectTag(24)) goto parse_begin;
+ break;
+ }
+
+ // optional int32 begin = 3;
+ case 3: {
+ if (tag == 24) {
+ parse_begin:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+ input, &begin_)));
+ set_has_begin();
+ } else {
+ goto handle_unusual;
+ }
+ if (input->ExpectTag(32)) goto parse_end;
+ break;
+ }
+
+ // optional int32 end = 4;
+ case 4: {
+ if (tag == 32) {
+ parse_end:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+ input, &end_)));
+ set_has_end();
+ } else {
+ goto handle_unusual;
+ }
+ if (input->ExpectAtEnd()) goto success;
+ break;
+ }
+
+ default: {
+ handle_unusual:
+ if (tag == 0 ||
+ ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+ goto success;
+ }
+ DO_(::google::protobuf::internal::WireFormat::SkipField(
+ input, tag, mutable_unknown_fields()));
+ break;
+ }
+ }
+ }
+success:
+ // @@protoc_insertion_point(parse_success:google.protobuf.GeneratedCodeInfo.Annotation)
+ return true;
+failure:
+ // @@protoc_insertion_point(parse_failure:google.protobuf.GeneratedCodeInfo.Annotation)
+ return false;
+#undef DO_
+}
+
+void GeneratedCodeInfo_Annotation::SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const {
+ // @@protoc_insertion_point(serialize_start:google.protobuf.GeneratedCodeInfo.Annotation)
+ // repeated int32 path = 1 [packed = true];
+ if (this->path_size() > 0) {
+ ::google::protobuf::internal::WireFormatLite::WriteTag(1, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
+ output->WriteVarint32(_path_cached_byte_size_);
+ }
+ for (int i = 0; i < this->path_size(); i++) {
+ ::google::protobuf::internal::WireFormatLite::WriteInt32NoTag(
+ this->path(i), output);
+ }
+
+ // optional string source_file = 2;
+ if (has_source_file()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->source_file().data(), this->source_file().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "google.protobuf.GeneratedCodeInfo.Annotation.source_file");
+ ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+ 2, this->source_file(), output);
+ }
+
+ // optional int32 begin = 3;
+ if (has_begin()) {
+ ::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->begin(), output);
+ }
+
+ // optional int32 end = 4;
+ if (has_end()) {
+ ::google::protobuf::internal::WireFormatLite::WriteInt32(4, this->end(), output);
+ }
+
+ if (_internal_metadata_.have_unknown_fields()) {
+ ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+ unknown_fields(), output);
+ }
+ // @@protoc_insertion_point(serialize_end:google.protobuf.GeneratedCodeInfo.Annotation)
+}
+
+::google::protobuf::uint8* GeneratedCodeInfo_Annotation::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.GeneratedCodeInfo.Annotation)
+ // repeated int32 path = 1 [packed = true];
+ if (this->path_size() > 0) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
+ 1,
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
+ target);
+ target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
+ _path_cached_byte_size_, target);
+ }
+ for (int i = 0; i < this->path_size(); i++) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ WriteInt32NoTagToArray(this->path(i), target);
+ }
+
+ // optional string source_file = 2;
+ if (has_source_file()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->source_file().data(), this->source_file().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "google.protobuf.GeneratedCodeInfo.Annotation.source_file");
+ target =
+ ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+ 2, this->source_file(), target);
+ }
+
+ // optional int32 begin = 3;
+ if (has_begin()) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(3, this->begin(), target);
+ }
+
+ // optional int32 end = 4;
+ if (has_end()) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(4, this->end(), target);
+ }
+
+ if (_internal_metadata_.have_unknown_fields()) {
+ target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+ unknown_fields(), target);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.GeneratedCodeInfo.Annotation)
+ return target;
+}
+
+int GeneratedCodeInfo_Annotation::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.GeneratedCodeInfo.Annotation)
+ int total_size = 0;
+
+ if (_has_bits_[1 / 32] & 14u) {
+ // optional string source_file = 2;
+ if (has_source_file()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::StringSize(
+ this->source_file());
+ }
+
+ // optional int32 begin = 3;
+ if (has_begin()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::Int32Size(
+ this->begin());
+ }
+
+ // optional int32 end = 4;
+ if (has_end()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::Int32Size(
+ this->end());
+ }
+
+ }
+ // repeated int32 path = 1 [packed = true];
+ {
+ int data_size = 0;
+ for (int i = 0; i < this->path_size(); i++) {
+ data_size += ::google::protobuf::internal::WireFormatLite::
+ Int32Size(this->path(i));
+ }
+ if (data_size > 0) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
+ }
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _path_cached_byte_size_ = data_size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+ total_size += data_size;
+ }
+
+ if (_internal_metadata_.have_unknown_fields()) {
+ total_size +=
+ ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+ unknown_fields());
+ }
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = total_size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+ return total_size;
+}
+
+void GeneratedCodeInfo_Annotation::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.GeneratedCodeInfo.Annotation)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
+ const GeneratedCodeInfo_Annotation* source =
+ ::google::protobuf::internal::DynamicCastToGenerated<const GeneratedCodeInfo_Annotation>(
+ &from);
+ if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.GeneratedCodeInfo.Annotation)
+ ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+ } else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.GeneratedCodeInfo.Annotation)
+ MergeFrom(*source);
+ }
+}
+
+void GeneratedCodeInfo_Annotation::MergeFrom(const GeneratedCodeInfo_Annotation& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.GeneratedCodeInfo.Annotation)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
+ path_.MergeFrom(from.path_);
+ if (from._has_bits_[1 / 32] & (0xffu << (1 % 32))) {
+ if (from.has_source_file()) {
+ set_has_source_file();
+ source_file_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.source_file_);
+ }
+ if (from.has_begin()) {
+ set_begin(from.begin());
+ }
+ if (from.has_end()) {
+ set_end(from.end());
+ }
+ }
+ if (from._internal_metadata_.have_unknown_fields()) {
+ mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+ }
+}
+
+void GeneratedCodeInfo_Annotation::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.GeneratedCodeInfo.Annotation)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+void GeneratedCodeInfo_Annotation::CopyFrom(const GeneratedCodeInfo_Annotation& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.GeneratedCodeInfo.Annotation)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool GeneratedCodeInfo_Annotation::IsInitialized() const {
+
+ return true;
+}
+
+void GeneratedCodeInfo_Annotation::Swap(GeneratedCodeInfo_Annotation* other) {
+ if (other == this) return;
+ InternalSwap(other);
+}
+void GeneratedCodeInfo_Annotation::InternalSwap(GeneratedCodeInfo_Annotation* other) {
+ path_.UnsafeArenaSwap(&other->path_);
+ source_file_.Swap(&other->source_file_);
+ std::swap(begin_, other->begin_);
+ std::swap(end_, other->end_);
+ std::swap(_has_bits_[0], other->_has_bits_[0]);
+ _internal_metadata_.Swap(&other->_internal_metadata_);
+ std::swap(_cached_size_, other->_cached_size_);
+}
+
+::google::protobuf::Metadata GeneratedCodeInfo_Annotation::GetMetadata() const {
+ protobuf_AssignDescriptorsOnce();
+ ::google::protobuf::Metadata metadata;
+ metadata.descriptor = GeneratedCodeInfo_Annotation_descriptor_;
+ metadata.reflection = GeneratedCodeInfo_Annotation_reflection_;
+ return metadata;
+}
+
+
+// -------------------------------------------------------------------
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int GeneratedCodeInfo::kAnnotationFieldNumber;
+#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+GeneratedCodeInfo::GeneratedCodeInfo()
+ : ::google::protobuf::Message(), _internal_metadata_(NULL) {
+ SharedCtor();
+ // @@protoc_insertion_point(constructor:google.protobuf.GeneratedCodeInfo)
+}
+
+void GeneratedCodeInfo::InitAsDefaultInstance() {
+}
+
+GeneratedCodeInfo::GeneratedCodeInfo(const GeneratedCodeInfo& from)
+ : ::google::protobuf::Message(),
+ _internal_metadata_(NULL) {
+ SharedCtor();
+ MergeFrom(from);
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.GeneratedCodeInfo)
+}
+
+void GeneratedCodeInfo::SharedCtor() {
+ _cached_size_ = 0;
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+GeneratedCodeInfo::~GeneratedCodeInfo() {
+ // @@protoc_insertion_point(destructor:google.protobuf.GeneratedCodeInfo)
+ SharedDtor();
+}
+
+void GeneratedCodeInfo::SharedDtor() {
+ if (this != default_instance_) {
+ }
+}
+
+void GeneratedCodeInfo::SetCachedSize(int size) const {
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* GeneratedCodeInfo::descriptor() {
+ protobuf_AssignDescriptorsOnce();
+ return GeneratedCodeInfo_descriptor_;
+}
+
+const GeneratedCodeInfo& GeneratedCodeInfo::default_instance() {
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ return *default_instance_;
+}
+
+GeneratedCodeInfo* GeneratedCodeInfo::default_instance_ = NULL;
+
+GeneratedCodeInfo* GeneratedCodeInfo::New(::google::protobuf::Arena* arena) const {
+ GeneratedCodeInfo* n = new GeneratedCodeInfo;
+ if (arena != NULL) {
+ arena->Own(n);
+ }
+ return n;
+}
+
+void GeneratedCodeInfo::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.GeneratedCodeInfo)
+ annotation_.Clear();
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+ if (_internal_metadata_.have_unknown_fields()) {
+ mutable_unknown_fields()->Clear();
+ }
+}
+
+bool GeneratedCodeInfo::MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+ ::google::protobuf::uint32 tag;
+ // @@protoc_insertion_point(parse_start:google.protobuf.GeneratedCodeInfo)
+ for (;;) {
+ ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
+ tag = p.first;
+ if (!p.second) goto handle_unusual;
+ switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+ // repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1;
+ case 1: {
+ if (tag == 10) {
+ DO_(input->IncrementRecursionDepth());
+ parse_loop_annotation:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+ input, add_annotation()));
+ } else {
+ goto handle_unusual;
+ }
+ if (input->ExpectTag(10)) goto parse_loop_annotation;
+ input->UnsafeDecrementRecursionDepth();
+ if (input->ExpectAtEnd()) goto success;
+ break;
+ }
+
+ default: {
+ handle_unusual:
+ if (tag == 0 ||
+ ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+ goto success;
+ }
+ DO_(::google::protobuf::internal::WireFormat::SkipField(
+ input, tag, mutable_unknown_fields()));
+ break;
+ }
+ }
+ }
+success:
+ // @@protoc_insertion_point(parse_success:google.protobuf.GeneratedCodeInfo)
+ return true;
+failure:
+ // @@protoc_insertion_point(parse_failure:google.protobuf.GeneratedCodeInfo)
+ return false;
+#undef DO_
+}
+
+void GeneratedCodeInfo::SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const {
+ // @@protoc_insertion_point(serialize_start:google.protobuf.GeneratedCodeInfo)
+ // repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1;
+ for (unsigned int i = 0, n = this->annotation_size(); i < n; i++) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+ 1, this->annotation(i), output);
+ }
+
+ if (_internal_metadata_.have_unknown_fields()) {
+ ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+ unknown_fields(), output);
+ }
+ // @@protoc_insertion_point(serialize_end:google.protobuf.GeneratedCodeInfo)
+}
+
+::google::protobuf::uint8* GeneratedCodeInfo::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.GeneratedCodeInfo)
+ // repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1;
+ for (unsigned int i = 0, n = this->annotation_size(); i < n; i++) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ InternalWriteMessageNoVirtualToArray(
+ 1, this->annotation(i), false, target);
+ }
+
+ if (_internal_metadata_.have_unknown_fields()) {
+ target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+ unknown_fields(), target);
+ }
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.GeneratedCodeInfo)
+ return target;
+}
+
+int GeneratedCodeInfo::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.GeneratedCodeInfo)
+ int total_size = 0;
+
+ // repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1;
+ total_size += 1 * this->annotation_size();
+ for (int i = 0; i < this->annotation_size(); i++) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->annotation(i));
+ }
+
+ if (_internal_metadata_.have_unknown_fields()) {
+ total_size +=
+ ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+ unknown_fields());
+ }
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = total_size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+ return total_size;
+}
+
+void GeneratedCodeInfo::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.GeneratedCodeInfo)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
+ const GeneratedCodeInfo* source =
+ ::google::protobuf::internal::DynamicCastToGenerated<const GeneratedCodeInfo>(
+ &from);
+ if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.GeneratedCodeInfo)
+ ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+ } else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.GeneratedCodeInfo)
+ MergeFrom(*source);
+ }
+}
+
+void GeneratedCodeInfo::MergeFrom(const GeneratedCodeInfo& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.GeneratedCodeInfo)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
+ annotation_.MergeFrom(from.annotation_);
+ if (from._internal_metadata_.have_unknown_fields()) {
+ mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+ }
+}
+
+void GeneratedCodeInfo::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.GeneratedCodeInfo)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+void GeneratedCodeInfo::CopyFrom(const GeneratedCodeInfo& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.GeneratedCodeInfo)
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool GeneratedCodeInfo::IsInitialized() const {
+
+ return true;
+}
+
+void GeneratedCodeInfo::Swap(GeneratedCodeInfo* other) {
+ if (other == this) return;
+ InternalSwap(other);
+}
+void GeneratedCodeInfo::InternalSwap(GeneratedCodeInfo* other) {
+ annotation_.UnsafeArenaSwap(&other->annotation_);
+ std::swap(_has_bits_[0], other->_has_bits_[0]);
+ _internal_metadata_.Swap(&other->_internal_metadata_);
+ std::swap(_cached_size_, other->_cached_size_);
+}
+
+::google::protobuf::Metadata GeneratedCodeInfo::GetMetadata() const {
+ protobuf_AssignDescriptorsOnce();
+ ::google::protobuf::Metadata metadata;
+ metadata.descriptor = GeneratedCodeInfo_descriptor_;
+ metadata.reflection = GeneratedCodeInfo_reflection_;
+ return metadata;
+}
+
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// GeneratedCodeInfo_Annotation
+
+// repeated int32 path = 1 [packed = true];
+int GeneratedCodeInfo_Annotation::path_size() const {
+ return path_.size();
+}
+void GeneratedCodeInfo_Annotation::clear_path() {
+ path_.Clear();
+}
+ ::google::protobuf::int32 GeneratedCodeInfo_Annotation::path(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.GeneratedCodeInfo.Annotation.path)
+ return path_.Get(index);
+}
+ void GeneratedCodeInfo_Annotation::set_path(int index, ::google::protobuf::int32 value) {
+ path_.Set(index, value);
+ // @@protoc_insertion_point(field_set:google.protobuf.GeneratedCodeInfo.Annotation.path)
+}
+ void GeneratedCodeInfo_Annotation::add_path(::google::protobuf::int32 value) {
+ path_.Add(value);
+ // @@protoc_insertion_point(field_add:google.protobuf.GeneratedCodeInfo.Annotation.path)
+}
+ const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
+GeneratedCodeInfo_Annotation::path() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.GeneratedCodeInfo.Annotation.path)
+ return path_;
+}
+ ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
+GeneratedCodeInfo_Annotation::mutable_path() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.GeneratedCodeInfo.Annotation.path)
+ return &path_;
+}
+
+// optional string source_file = 2;
+bool GeneratedCodeInfo_Annotation::has_source_file() const {
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+void GeneratedCodeInfo_Annotation::set_has_source_file() {
+ _has_bits_[0] |= 0x00000002u;
+}
+void GeneratedCodeInfo_Annotation::clear_has_source_file() {
+ _has_bits_[0] &= ~0x00000002u;
+}
+void GeneratedCodeInfo_Annotation::clear_source_file() {
+ source_file_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ clear_has_source_file();
+}
+ const ::std::string& GeneratedCodeInfo_Annotation::source_file() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.GeneratedCodeInfo.Annotation.source_file)
+ return source_file_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void GeneratedCodeInfo_Annotation::set_source_file(const ::std::string& value) {
+ set_has_source_file();
+ source_file_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+ // @@protoc_insertion_point(field_set:google.protobuf.GeneratedCodeInfo.Annotation.source_file)
+}
+ void GeneratedCodeInfo_Annotation::set_source_file(const char* value) {
+ set_has_source_file();
+ source_file_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+ // @@protoc_insertion_point(field_set_char:google.protobuf.GeneratedCodeInfo.Annotation.source_file)
+}
+ void GeneratedCodeInfo_Annotation::set_source_file(const char* value, size_t size) {
+ set_has_source_file();
+ source_file_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+ ::std::string(reinterpret_cast<const char*>(value), size));
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.GeneratedCodeInfo.Annotation.source_file)
+}
+ ::std::string* GeneratedCodeInfo_Annotation::mutable_source_file() {
+ set_has_source_file();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.GeneratedCodeInfo.Annotation.source_file)
+ return source_file_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* GeneratedCodeInfo_Annotation::release_source_file() {
+ // @@protoc_insertion_point(field_release:google.protobuf.GeneratedCodeInfo.Annotation.source_file)
+ clear_has_source_file();
+ return source_file_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void GeneratedCodeInfo_Annotation::set_allocated_source_file(::std::string* source_file) {
+ if (source_file != NULL) {
+ set_has_source_file();
+ } else {
+ clear_has_source_file();
+ }
+ source_file_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), source_file);
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.GeneratedCodeInfo.Annotation.source_file)
+}
+
+// optional int32 begin = 3;
+bool GeneratedCodeInfo_Annotation::has_begin() const {
+ return (_has_bits_[0] & 0x00000004u) != 0;
+}
+void GeneratedCodeInfo_Annotation::set_has_begin() {
+ _has_bits_[0] |= 0x00000004u;
+}
+void GeneratedCodeInfo_Annotation::clear_has_begin() {
+ _has_bits_[0] &= ~0x00000004u;
+}
+void GeneratedCodeInfo_Annotation::clear_begin() {
+ begin_ = 0;
+ clear_has_begin();
+}
+ ::google::protobuf::int32 GeneratedCodeInfo_Annotation::begin() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.GeneratedCodeInfo.Annotation.begin)
+ return begin_;
+}
+ void GeneratedCodeInfo_Annotation::set_begin(::google::protobuf::int32 value) {
+ set_has_begin();
+ begin_ = value;
+ // @@protoc_insertion_point(field_set:google.protobuf.GeneratedCodeInfo.Annotation.begin)
+}
+
+// optional int32 end = 4;
+bool GeneratedCodeInfo_Annotation::has_end() const {
+ return (_has_bits_[0] & 0x00000008u) != 0;
+}
+void GeneratedCodeInfo_Annotation::set_has_end() {
+ _has_bits_[0] |= 0x00000008u;
+}
+void GeneratedCodeInfo_Annotation::clear_has_end() {
+ _has_bits_[0] &= ~0x00000008u;
+}
+void GeneratedCodeInfo_Annotation::clear_end() {
+ end_ = 0;
+ clear_has_end();
+}
+ ::google::protobuf::int32 GeneratedCodeInfo_Annotation::end() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.GeneratedCodeInfo.Annotation.end)
+ return end_;
+}
+ void GeneratedCodeInfo_Annotation::set_end(::google::protobuf::int32 value) {
+ set_has_end();
+ end_ = value;
+ // @@protoc_insertion_point(field_set:google.protobuf.GeneratedCodeInfo.Annotation.end)
+}
+
+// -------------------------------------------------------------------
+
+// GeneratedCodeInfo
+
+// repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1;
+int GeneratedCodeInfo::annotation_size() const {
+ return annotation_.size();
+}
+void GeneratedCodeInfo::clear_annotation() {
+ annotation_.Clear();
+}
+const ::google::protobuf::GeneratedCodeInfo_Annotation& GeneratedCodeInfo::annotation(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.GeneratedCodeInfo.annotation)
+ return annotation_.Get(index);
+}
+::google::protobuf::GeneratedCodeInfo_Annotation* GeneratedCodeInfo::mutable_annotation(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.GeneratedCodeInfo.annotation)
+ return annotation_.Mutable(index);
+}
+::google::protobuf::GeneratedCodeInfo_Annotation* GeneratedCodeInfo::add_annotation() {
+ // @@protoc_insertion_point(field_add:google.protobuf.GeneratedCodeInfo.annotation)
+ return annotation_.Add();
+}
+::google::protobuf::RepeatedPtrField< ::google::protobuf::GeneratedCodeInfo_Annotation >*
+GeneratedCodeInfo::mutable_annotation() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.GeneratedCodeInfo.annotation)
+ return &annotation_;
+}
+const ::google::protobuf::RepeatedPtrField< ::google::protobuf::GeneratedCodeInfo_Annotation >&
+GeneratedCodeInfo::annotation() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.GeneratedCodeInfo.annotation)
+ return annotation_;
+}
+
+#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
+
// @@protoc_insertion_point(namespace_scope)
} // namespace protobuf
diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h
index 60255162..5a9e12bc 100644
--- a/src/google/protobuf/descriptor.pb.h
+++ b/src/google/protobuf/descriptor.pb.h
@@ -50,10 +50,13 @@ class FieldOptions;
class FileDescriptorProto;
class FileDescriptorSet;
class FileOptions;
+class GeneratedCodeInfo;
+class GeneratedCodeInfo_Annotation;
class MessageOptions;
class MethodDescriptorProto;
class MethodOptions;
class OneofDescriptorProto;
+class OneofOptions;
class ServiceDescriptorProto;
class ServiceOptions;
class SourceCodeInfo;
@@ -178,7 +181,7 @@ inline bool FieldOptions_JSType_Parse(
}
// ===================================================================
-class LIBPROTOBUF_EXPORT FileDescriptorSet : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT FileDescriptorSet : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FileDescriptorSet) */ {
public:
FileDescriptorSet();
virtual ~FileDescriptorSet();
@@ -220,7 +223,11 @@ class LIBPROTOBUF_EXPORT FileDescriptorSet : public ::google::protobuf::Message
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
@@ -270,7 +277,7 @@ class LIBPROTOBUF_EXPORT FileDescriptorSet : public ::google::protobuf::Message
};
// -------------------------------------------------------------------
-class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FileDescriptorProto) */ {
public:
FileDescriptorProto();
virtual ~FileDescriptorProto();
@@ -312,7 +319,11 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
@@ -513,7 +524,7 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag
};
// -------------------------------------------------------------------
-class LIBPROTOBUF_EXPORT DescriptorProto_ExtensionRange : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT DescriptorProto_ExtensionRange : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.DescriptorProto.ExtensionRange) */ {
public:
DescriptorProto_ExtensionRange();
virtual ~DescriptorProto_ExtensionRange();
@@ -555,7 +566,11 @@ class LIBPROTOBUF_EXPORT DescriptorProto_ExtensionRange : public ::google::proto
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
@@ -612,7 +627,7 @@ class LIBPROTOBUF_EXPORT DescriptorProto_ExtensionRange : public ::google::proto
};
// -------------------------------------------------------------------
-class LIBPROTOBUF_EXPORT DescriptorProto_ReservedRange : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT DescriptorProto_ReservedRange : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.DescriptorProto.ReservedRange) */ {
public:
DescriptorProto_ReservedRange();
virtual ~DescriptorProto_ReservedRange();
@@ -654,7 +669,11 @@ class LIBPROTOBUF_EXPORT DescriptorProto_ReservedRange : public ::google::protob
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
@@ -711,7 +730,7 @@ class LIBPROTOBUF_EXPORT DescriptorProto_ReservedRange : public ::google::protob
};
// -------------------------------------------------------------------
-class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.DescriptorProto) */ {
public:
DescriptorProto();
virtual ~DescriptorProto();
@@ -753,7 +772,11 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message {
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
@@ -928,7 +951,7 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message {
};
// -------------------------------------------------------------------
-class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FieldDescriptorProto) */ {
public:
FieldDescriptorProto();
virtual ~FieldDescriptorProto();
@@ -970,7 +993,11 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
@@ -991,24 +1018,42 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa
// nested types ----------------------------------------------------
typedef FieldDescriptorProto_Type Type;
- static const Type TYPE_DOUBLE = FieldDescriptorProto_Type_TYPE_DOUBLE;
- static const Type TYPE_FLOAT = FieldDescriptorProto_Type_TYPE_FLOAT;
- static const Type TYPE_INT64 = FieldDescriptorProto_Type_TYPE_INT64;
- static const Type TYPE_UINT64 = FieldDescriptorProto_Type_TYPE_UINT64;
- static const Type TYPE_INT32 = FieldDescriptorProto_Type_TYPE_INT32;
- static const Type TYPE_FIXED64 = FieldDescriptorProto_Type_TYPE_FIXED64;
- static const Type TYPE_FIXED32 = FieldDescriptorProto_Type_TYPE_FIXED32;
- static const Type TYPE_BOOL = FieldDescriptorProto_Type_TYPE_BOOL;
- static const Type TYPE_STRING = FieldDescriptorProto_Type_TYPE_STRING;
- static const Type TYPE_GROUP = FieldDescriptorProto_Type_TYPE_GROUP;
- static const Type TYPE_MESSAGE = FieldDescriptorProto_Type_TYPE_MESSAGE;
- static const Type TYPE_BYTES = FieldDescriptorProto_Type_TYPE_BYTES;
- static const Type TYPE_UINT32 = FieldDescriptorProto_Type_TYPE_UINT32;
- static const Type TYPE_ENUM = FieldDescriptorProto_Type_TYPE_ENUM;
- static const Type TYPE_SFIXED32 = FieldDescriptorProto_Type_TYPE_SFIXED32;
- static const Type TYPE_SFIXED64 = FieldDescriptorProto_Type_TYPE_SFIXED64;
- static const Type TYPE_SINT32 = FieldDescriptorProto_Type_TYPE_SINT32;
- static const Type TYPE_SINT64 = FieldDescriptorProto_Type_TYPE_SINT64;
+ static const Type TYPE_DOUBLE =
+ FieldDescriptorProto_Type_TYPE_DOUBLE;
+ static const Type TYPE_FLOAT =
+ FieldDescriptorProto_Type_TYPE_FLOAT;
+ static const Type TYPE_INT64 =
+ FieldDescriptorProto_Type_TYPE_INT64;
+ static const Type TYPE_UINT64 =
+ FieldDescriptorProto_Type_TYPE_UINT64;
+ static const Type TYPE_INT32 =
+ FieldDescriptorProto_Type_TYPE_INT32;
+ static const Type TYPE_FIXED64 =
+ FieldDescriptorProto_Type_TYPE_FIXED64;
+ static const Type TYPE_FIXED32 =
+ FieldDescriptorProto_Type_TYPE_FIXED32;
+ static const Type TYPE_BOOL =
+ FieldDescriptorProto_Type_TYPE_BOOL;
+ static const Type TYPE_STRING =
+ FieldDescriptorProto_Type_TYPE_STRING;
+ static const Type TYPE_GROUP =
+ FieldDescriptorProto_Type_TYPE_GROUP;
+ static const Type TYPE_MESSAGE =
+ FieldDescriptorProto_Type_TYPE_MESSAGE;
+ static const Type TYPE_BYTES =
+ FieldDescriptorProto_Type_TYPE_BYTES;
+ static const Type TYPE_UINT32 =
+ FieldDescriptorProto_Type_TYPE_UINT32;
+ static const Type TYPE_ENUM =
+ FieldDescriptorProto_Type_TYPE_ENUM;
+ static const Type TYPE_SFIXED32 =
+ FieldDescriptorProto_Type_TYPE_SFIXED32;
+ static const Type TYPE_SFIXED64 =
+ FieldDescriptorProto_Type_TYPE_SFIXED64;
+ static const Type TYPE_SINT32 =
+ FieldDescriptorProto_Type_TYPE_SINT32;
+ static const Type TYPE_SINT64 =
+ FieldDescriptorProto_Type_TYPE_SINT64;
static inline bool Type_IsValid(int value) {
return FieldDescriptorProto_Type_IsValid(value);
}
@@ -1031,9 +1076,12 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa
}
typedef FieldDescriptorProto_Label Label;
- static const Label LABEL_OPTIONAL = FieldDescriptorProto_Label_LABEL_OPTIONAL;
- static const Label LABEL_REQUIRED = FieldDescriptorProto_Label_LABEL_REQUIRED;
- static const Label LABEL_REPEATED = FieldDescriptorProto_Label_LABEL_REPEATED;
+ static const Label LABEL_OPTIONAL =
+ FieldDescriptorProto_Label_LABEL_OPTIONAL;
+ static const Label LABEL_REQUIRED =
+ FieldDescriptorProto_Label_LABEL_REQUIRED;
+ static const Label LABEL_REPEATED =
+ FieldDescriptorProto_Label_LABEL_REPEATED;
static inline bool Label_IsValid(int value) {
return FieldDescriptorProto_Label_IsValid(value);
}
@@ -1199,7 +1247,7 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa
};
// -------------------------------------------------------------------
-class LIBPROTOBUF_EXPORT OneofDescriptorProto : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT OneofDescriptorProto : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.OneofDescriptorProto) */ {
public:
OneofDescriptorProto();
virtual ~OneofDescriptorProto();
@@ -1241,7 +1289,11 @@ class LIBPROTOBUF_EXPORT OneofDescriptorProto : public ::google::protobuf::Messa
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
@@ -1275,15 +1327,27 @@ class LIBPROTOBUF_EXPORT OneofDescriptorProto : public ::google::protobuf::Messa
::std::string* release_name();
void set_allocated_name(::std::string* name);
+ // optional .google.protobuf.OneofOptions options = 2;
+ bool has_options() const;
+ void clear_options();
+ static const int kOptionsFieldNumber = 2;
+ const ::google::protobuf::OneofOptions& options() const;
+ ::google::protobuf::OneofOptions* mutable_options();
+ ::google::protobuf::OneofOptions* release_options();
+ void set_allocated_options(::google::protobuf::OneofOptions* options);
+
// @@protoc_insertion_point(class_scope:google.protobuf.OneofDescriptorProto)
private:
inline void set_has_name();
inline void clear_has_name();
+ inline void set_has_options();
+ inline void clear_has_options();
::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
::google::protobuf::uint32 _has_bits_[1];
mutable int _cached_size_;
::google::protobuf::internal::ArenaStringPtr name_;
+ ::google::protobuf::OneofOptions* options_;
friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
@@ -1293,7 +1357,7 @@ class LIBPROTOBUF_EXPORT OneofDescriptorProto : public ::google::protobuf::Messa
};
// -------------------------------------------------------------------
-class LIBPROTOBUF_EXPORT EnumDescriptorProto : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT EnumDescriptorProto : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumDescriptorProto) */ {
public:
EnumDescriptorProto();
virtual ~EnumDescriptorProto();
@@ -1335,7 +1399,11 @@ class LIBPROTOBUF_EXPORT EnumDescriptorProto : public ::google::protobuf::Messag
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
@@ -1412,7 +1480,7 @@ class LIBPROTOBUF_EXPORT EnumDescriptorProto : public ::google::protobuf::Messag
};
// -------------------------------------------------------------------
-class LIBPROTOBUF_EXPORT EnumValueDescriptorProto : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT EnumValueDescriptorProto : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumValueDescriptorProto) */ {
public:
EnumValueDescriptorProto();
virtual ~EnumValueDescriptorProto();
@@ -1454,7 +1522,11 @@ class LIBPROTOBUF_EXPORT EnumValueDescriptorProto : public ::google::protobuf::M
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
@@ -1528,7 +1600,7 @@ class LIBPROTOBUF_EXPORT EnumValueDescriptorProto : public ::google::protobuf::M
};
// -------------------------------------------------------------------
-class LIBPROTOBUF_EXPORT ServiceDescriptorProto : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT ServiceDescriptorProto : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.ServiceDescriptorProto) */ {
public:
ServiceDescriptorProto();
virtual ~ServiceDescriptorProto();
@@ -1570,7 +1642,11 @@ class LIBPROTOBUF_EXPORT ServiceDescriptorProto : public ::google::protobuf::Mes
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
@@ -1647,7 +1723,7 @@ class LIBPROTOBUF_EXPORT ServiceDescriptorProto : public ::google::protobuf::Mes
};
// -------------------------------------------------------------------
-class LIBPROTOBUF_EXPORT MethodDescriptorProto : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT MethodDescriptorProto : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.MethodDescriptorProto) */ {
public:
MethodDescriptorProto();
virtual ~MethodDescriptorProto();
@@ -1689,7 +1765,11 @@ class LIBPROTOBUF_EXPORT MethodDescriptorProto : public ::google::protobuf::Mess
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
@@ -1803,7 +1883,7 @@ class LIBPROTOBUF_EXPORT MethodDescriptorProto : public ::google::protobuf::Mess
};
// -------------------------------------------------------------------
-class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FileOptions) */ {
public:
FileOptions();
virtual ~FileOptions();
@@ -1845,7 +1925,11 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message {
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
@@ -1866,9 +1950,12 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message {
// nested types ----------------------------------------------------
typedef FileOptions_OptimizeMode OptimizeMode;
- static const OptimizeMode SPEED = FileOptions_OptimizeMode_SPEED;
- static const OptimizeMode CODE_SIZE = FileOptions_OptimizeMode_CODE_SIZE;
- static const OptimizeMode LITE_RUNTIME = FileOptions_OptimizeMode_LITE_RUNTIME;
+ static const OptimizeMode SPEED =
+ FileOptions_OptimizeMode_SPEED;
+ static const OptimizeMode CODE_SIZE =
+ FileOptions_OptimizeMode_CODE_SIZE;
+ static const OptimizeMode LITE_RUNTIME =
+ FileOptions_OptimizeMode_LITE_RUNTIME;
static inline bool OptimizeMode_IsValid(int value) {
return FileOptions_OptimizeMode_IsValid(value);
}
@@ -2015,13 +2102,6 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message {
::std::string* release_csharp_namespace();
void set_allocated_csharp_namespace(::std::string* csharp_namespace);
- // optional bool javanano_use_deprecated_package = 38;
- bool has_javanano_use_deprecated_package() const;
- void clear_javanano_use_deprecated_package();
- static const int kJavananoUseDeprecatedPackageFieldNumber = 38;
- bool javanano_use_deprecated_package() const;
- void set_javanano_use_deprecated_package(bool value);
-
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
int uninterpreted_option_size() const;
void clear_uninterpreted_option();
@@ -2065,8 +2145,6 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message {
inline void clear_has_objc_class_prefix();
inline void set_has_csharp_namespace();
inline void clear_has_csharp_namespace();
- inline void set_has_javanano_use_deprecated_package();
- inline void clear_has_javanano_use_deprecated_package();
::google::protobuf::internal::ExtensionSet _extensions_;
@@ -2081,14 +2159,13 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message {
bool cc_generic_services_;
int optimize_for_;
::google::protobuf::internal::ArenaStringPtr go_package_;
+ ::google::protobuf::internal::ArenaStringPtr objc_class_prefix_;
+ ::google::protobuf::internal::ArenaStringPtr csharp_namespace_;
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
bool java_generic_services_;
bool py_generic_services_;
bool deprecated_;
bool cc_enable_arenas_;
- bool javanano_use_deprecated_package_;
- ::google::protobuf::internal::ArenaStringPtr objc_class_prefix_;
- ::google::protobuf::internal::ArenaStringPtr csharp_namespace_;
- ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
@@ -2098,7 +2175,7 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message {
};
// -------------------------------------------------------------------
-class LIBPROTOBUF_EXPORT MessageOptions : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT MessageOptions : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.MessageOptions) */ {
public:
MessageOptions();
virtual ~MessageOptions();
@@ -2140,7 +2217,11 @@ class LIBPROTOBUF_EXPORT MessageOptions : public ::google::protobuf::Message {
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
@@ -2233,7 +2314,7 @@ class LIBPROTOBUF_EXPORT MessageOptions : public ::google::protobuf::Message {
};
// -------------------------------------------------------------------
-class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FieldOptions) */ {
public:
FieldOptions();
virtual ~FieldOptions();
@@ -2275,7 +2356,11 @@ class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message {
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
@@ -2296,9 +2381,12 @@ class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message {
// nested types ----------------------------------------------------
typedef FieldOptions_CType CType;
- static const CType STRING = FieldOptions_CType_STRING;
- static const CType CORD = FieldOptions_CType_CORD;
- static const CType STRING_PIECE = FieldOptions_CType_STRING_PIECE;
+ static const CType STRING =
+ FieldOptions_CType_STRING;
+ static const CType CORD =
+ FieldOptions_CType_CORD;
+ static const CType STRING_PIECE =
+ FieldOptions_CType_STRING_PIECE;
static inline bool CType_IsValid(int value) {
return FieldOptions_CType_IsValid(value);
}
@@ -2321,9 +2409,12 @@ class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message {
}
typedef FieldOptions_JSType JSType;
- static const JSType JS_NORMAL = FieldOptions_JSType_JS_NORMAL;
- static const JSType JS_STRING = FieldOptions_JSType_JS_STRING;
- static const JSType JS_NUMBER = FieldOptions_JSType_JS_NUMBER;
+ static const JSType JS_NORMAL =
+ FieldOptions_JSType_JS_NORMAL;
+ static const JSType JS_STRING =
+ FieldOptions_JSType_JS_STRING;
+ static const JSType JS_NUMBER =
+ FieldOptions_JSType_JS_NUMBER;
static inline bool JSType_IsValid(int value) {
return FieldOptions_JSType_IsValid(value);
}
@@ -2438,7 +2529,106 @@ class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message {
};
// -------------------------------------------------------------------
-class LIBPROTOBUF_EXPORT EnumOptions : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT OneofOptions : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.OneofOptions) */ {
+ public:
+ OneofOptions();
+ virtual ~OneofOptions();
+
+ OneofOptions(const OneofOptions& from);
+
+ inline OneofOptions& operator=(const OneofOptions& from) {
+ CopyFrom(from);
+ return *this;
+ }
+
+ inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+ return _internal_metadata_.unknown_fields();
+ }
+
+ inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+ return _internal_metadata_.mutable_unknown_fields();
+ }
+
+ static const ::google::protobuf::Descriptor* descriptor();
+ static const OneofOptions& default_instance();
+
+ void Swap(OneofOptions* other);
+
+ // implements Message ----------------------------------------------
+
+ inline OneofOptions* New() const { return New(NULL); }
+
+ OneofOptions* New(::google::protobuf::Arena* arena) const;
+ void CopyFrom(const ::google::protobuf::Message& from);
+ void MergeFrom(const ::google::protobuf::Message& from);
+ void CopyFrom(const OneofOptions& from);
+ void MergeFrom(const OneofOptions& from);
+ void Clear();
+ bool IsInitialized() const;
+
+ int ByteSize() const;
+ bool MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input);
+ void SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
+ int GetCachedSize() const { return _cached_size_; }
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const;
+ void InternalSwap(OneofOptions* other);
+ private:
+ inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+ return _internal_metadata_.arena();
+ }
+ inline void* MaybeArenaPtr() const {
+ return _internal_metadata_.raw_arena_ptr();
+ }
+ public:
+
+ ::google::protobuf::Metadata GetMetadata() const;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ int uninterpreted_option_size() const;
+ void clear_uninterpreted_option();
+ static const int kUninterpretedOptionFieldNumber = 999;
+ const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
+ ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
+ ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+ mutable_uninterpreted_option();
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+ uninterpreted_option() const;
+
+ GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(OneofOptions)
+ // @@protoc_insertion_point(class_scope:google.protobuf.OneofOptions)
+ private:
+
+ ::google::protobuf::internal::ExtensionSet _extensions_;
+
+ ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+ ::google::protobuf::uint32 _has_bits_[1];
+ mutable int _cached_size_;
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
+ friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+ void InitAsDefaultInstance();
+ static OneofOptions* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class LIBPROTOBUF_EXPORT EnumOptions : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumOptions) */ {
public:
EnumOptions();
virtual ~EnumOptions();
@@ -2480,7 +2670,11 @@ class LIBPROTOBUF_EXPORT EnumOptions : public ::google::protobuf::Message {
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
@@ -2553,7 +2747,7 @@ class LIBPROTOBUF_EXPORT EnumOptions : public ::google::protobuf::Message {
};
// -------------------------------------------------------------------
-class LIBPROTOBUF_EXPORT EnumValueOptions : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT EnumValueOptions : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumValueOptions) */ {
public:
EnumValueOptions();
virtual ~EnumValueOptions();
@@ -2595,7 +2789,11 @@ class LIBPROTOBUF_EXPORT EnumValueOptions : public ::google::protobuf::Message {
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
@@ -2658,7 +2856,7 @@ class LIBPROTOBUF_EXPORT EnumValueOptions : public ::google::protobuf::Message {
};
// -------------------------------------------------------------------
-class LIBPROTOBUF_EXPORT ServiceOptions : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT ServiceOptions : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.ServiceOptions) */ {
public:
ServiceOptions();
virtual ~ServiceOptions();
@@ -2700,7 +2898,11 @@ class LIBPROTOBUF_EXPORT ServiceOptions : public ::google::protobuf::Message {
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
@@ -2763,7 +2965,7 @@ class LIBPROTOBUF_EXPORT ServiceOptions : public ::google::protobuf::Message {
};
// -------------------------------------------------------------------
-class LIBPROTOBUF_EXPORT MethodOptions : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT MethodOptions : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.MethodOptions) */ {
public:
MethodOptions();
virtual ~MethodOptions();
@@ -2805,7 +3007,11 @@ class LIBPROTOBUF_EXPORT MethodOptions : public ::google::protobuf::Message {
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
@@ -2868,7 +3074,7 @@ class LIBPROTOBUF_EXPORT MethodOptions : public ::google::protobuf::Message {
};
// -------------------------------------------------------------------
-class LIBPROTOBUF_EXPORT UninterpretedOption_NamePart : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT UninterpretedOption_NamePart : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.UninterpretedOption.NamePart) */ {
public:
UninterpretedOption_NamePart();
virtual ~UninterpretedOption_NamePart();
@@ -2910,7 +3116,11 @@ class LIBPROTOBUF_EXPORT UninterpretedOption_NamePart : public ::google::protobu
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
@@ -2975,7 +3185,7 @@ class LIBPROTOBUF_EXPORT UninterpretedOption_NamePart : public ::google::protobu
};
// -------------------------------------------------------------------
-class LIBPROTOBUF_EXPORT UninterpretedOption : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT UninterpretedOption : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.UninterpretedOption) */ {
public:
UninterpretedOption();
virtual ~UninterpretedOption();
@@ -3017,7 +3227,11 @@ class LIBPROTOBUF_EXPORT UninterpretedOption : public ::google::protobuf::Messag
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
@@ -3144,7 +3358,7 @@ class LIBPROTOBUF_EXPORT UninterpretedOption : public ::google::protobuf::Messag
};
// -------------------------------------------------------------------
-class LIBPROTOBUF_EXPORT SourceCodeInfo_Location : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT SourceCodeInfo_Location : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.SourceCodeInfo.Location) */ {
public:
SourceCodeInfo_Location();
virtual ~SourceCodeInfo_Location();
@@ -3186,7 +3400,11 @@ class LIBPROTOBUF_EXPORT SourceCodeInfo_Location : public ::google::protobuf::Me
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
@@ -3298,7 +3516,7 @@ class LIBPROTOBUF_EXPORT SourceCodeInfo_Location : public ::google::protobuf::Me
};
// -------------------------------------------------------------------
-class LIBPROTOBUF_EXPORT SourceCodeInfo : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT SourceCodeInfo : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.SourceCodeInfo) */ {
public:
SourceCodeInfo();
virtual ~SourceCodeInfo();
@@ -3340,7 +3558,11 @@ class LIBPROTOBUF_EXPORT SourceCodeInfo : public ::google::protobuf::Message {
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
@@ -3390,6 +3612,236 @@ class LIBPROTOBUF_EXPORT SourceCodeInfo : public ::google::protobuf::Message {
void InitAsDefaultInstance();
static SourceCodeInfo* default_instance_;
};
+// -------------------------------------------------------------------
+
+class LIBPROTOBUF_EXPORT GeneratedCodeInfo_Annotation : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.GeneratedCodeInfo.Annotation) */ {
+ public:
+ GeneratedCodeInfo_Annotation();
+ virtual ~GeneratedCodeInfo_Annotation();
+
+ GeneratedCodeInfo_Annotation(const GeneratedCodeInfo_Annotation& from);
+
+ inline GeneratedCodeInfo_Annotation& operator=(const GeneratedCodeInfo_Annotation& from) {
+ CopyFrom(from);
+ return *this;
+ }
+
+ inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+ return _internal_metadata_.unknown_fields();
+ }
+
+ inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+ return _internal_metadata_.mutable_unknown_fields();
+ }
+
+ static const ::google::protobuf::Descriptor* descriptor();
+ static const GeneratedCodeInfo_Annotation& default_instance();
+
+ void Swap(GeneratedCodeInfo_Annotation* other);
+
+ // implements Message ----------------------------------------------
+
+ inline GeneratedCodeInfo_Annotation* New() const { return New(NULL); }
+
+ GeneratedCodeInfo_Annotation* New(::google::protobuf::Arena* arena) const;
+ void CopyFrom(const ::google::protobuf::Message& from);
+ void MergeFrom(const ::google::protobuf::Message& from);
+ void CopyFrom(const GeneratedCodeInfo_Annotation& from);
+ void MergeFrom(const GeneratedCodeInfo_Annotation& from);
+ void Clear();
+ bool IsInitialized() const;
+
+ int ByteSize() const;
+ bool MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input);
+ void SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
+ int GetCachedSize() const { return _cached_size_; }
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const;
+ void InternalSwap(GeneratedCodeInfo_Annotation* other);
+ private:
+ inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+ return _internal_metadata_.arena();
+ }
+ inline void* MaybeArenaPtr() const {
+ return _internal_metadata_.raw_arena_ptr();
+ }
+ public:
+
+ ::google::protobuf::Metadata GetMetadata() const;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ // repeated int32 path = 1 [packed = true];
+ int path_size() const;
+ void clear_path();
+ static const int kPathFieldNumber = 1;
+ ::google::protobuf::int32 path(int index) const;
+ void set_path(int index, ::google::protobuf::int32 value);
+ void add_path(::google::protobuf::int32 value);
+ const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
+ path() const;
+ ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
+ mutable_path();
+
+ // optional string source_file = 2;
+ bool has_source_file() const;
+ void clear_source_file();
+ static const int kSourceFileFieldNumber = 2;
+ const ::std::string& source_file() const;
+ void set_source_file(const ::std::string& value);
+ void set_source_file(const char* value);
+ void set_source_file(const char* value, size_t size);
+ ::std::string* mutable_source_file();
+ ::std::string* release_source_file();
+ void set_allocated_source_file(::std::string* source_file);
+
+ // optional int32 begin = 3;
+ bool has_begin() const;
+ void clear_begin();
+ static const int kBeginFieldNumber = 3;
+ ::google::protobuf::int32 begin() const;
+ void set_begin(::google::protobuf::int32 value);
+
+ // optional int32 end = 4;
+ bool has_end() const;
+ void clear_end();
+ static const int kEndFieldNumber = 4;
+ ::google::protobuf::int32 end() const;
+ void set_end(::google::protobuf::int32 value);
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.GeneratedCodeInfo.Annotation)
+ private:
+ inline void set_has_source_file();
+ inline void clear_has_source_file();
+ inline void set_has_begin();
+ inline void clear_has_begin();
+ inline void set_has_end();
+ inline void clear_has_end();
+
+ ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+ ::google::protobuf::uint32 _has_bits_[1];
+ mutable int _cached_size_;
+ ::google::protobuf::RepeatedField< ::google::protobuf::int32 > path_;
+ mutable int _path_cached_byte_size_;
+ ::google::protobuf::internal::ArenaStringPtr source_file_;
+ ::google::protobuf::int32 begin_;
+ ::google::protobuf::int32 end_;
+ friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+ void InitAsDefaultInstance();
+ static GeneratedCodeInfo_Annotation* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class LIBPROTOBUF_EXPORT GeneratedCodeInfo : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.GeneratedCodeInfo) */ {
+ public:
+ GeneratedCodeInfo();
+ virtual ~GeneratedCodeInfo();
+
+ GeneratedCodeInfo(const GeneratedCodeInfo& from);
+
+ inline GeneratedCodeInfo& operator=(const GeneratedCodeInfo& from) {
+ CopyFrom(from);
+ return *this;
+ }
+
+ inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+ return _internal_metadata_.unknown_fields();
+ }
+
+ inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+ return _internal_metadata_.mutable_unknown_fields();
+ }
+
+ static const ::google::protobuf::Descriptor* descriptor();
+ static const GeneratedCodeInfo& default_instance();
+
+ void Swap(GeneratedCodeInfo* other);
+
+ // implements Message ----------------------------------------------
+
+ inline GeneratedCodeInfo* New() const { return New(NULL); }
+
+ GeneratedCodeInfo* New(::google::protobuf::Arena* arena) const;
+ void CopyFrom(const ::google::protobuf::Message& from);
+ void MergeFrom(const ::google::protobuf::Message& from);
+ void CopyFrom(const GeneratedCodeInfo& from);
+ void MergeFrom(const GeneratedCodeInfo& from);
+ void Clear();
+ bool IsInitialized() const;
+
+ int ByteSize() const;
+ bool MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input);
+ void SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
+ int GetCachedSize() const { return _cached_size_; }
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const;
+ void InternalSwap(GeneratedCodeInfo* other);
+ private:
+ inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+ return _internal_metadata_.arena();
+ }
+ inline void* MaybeArenaPtr() const {
+ return _internal_metadata_.raw_arena_ptr();
+ }
+ public:
+
+ ::google::protobuf::Metadata GetMetadata() const;
+
+ // nested types ----------------------------------------------------
+
+ typedef GeneratedCodeInfo_Annotation Annotation;
+
+ // accessors -------------------------------------------------------
+
+ // repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1;
+ int annotation_size() const;
+ void clear_annotation();
+ static const int kAnnotationFieldNumber = 1;
+ const ::google::protobuf::GeneratedCodeInfo_Annotation& annotation(int index) const;
+ ::google::protobuf::GeneratedCodeInfo_Annotation* mutable_annotation(int index);
+ ::google::protobuf::GeneratedCodeInfo_Annotation* add_annotation();
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::GeneratedCodeInfo_Annotation >*
+ mutable_annotation();
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::GeneratedCodeInfo_Annotation >&
+ annotation() const;
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.GeneratedCodeInfo)
+ private:
+
+ ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+ ::google::protobuf::uint32 _has_bits_[1];
+ mutable int _cached_size_;
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::GeneratedCodeInfo_Annotation > annotation_;
+ friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+ void InitAsDefaultInstance();
+ static GeneratedCodeInfo* default_instance_;
+};
// ===================================================================
@@ -3472,6 +3924,7 @@ inline ::std::string* FileDescriptorProto::mutable_name() {
return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* FileDescriptorProto::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.name)
clear_has_name();
return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -3525,6 +3978,7 @@ inline ::std::string* FileDescriptorProto::mutable_package() {
return package_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* FileDescriptorProto::release_package() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.package)
clear_has_package();
return package_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -3567,6 +4021,7 @@ inline void FileDescriptorProto::set_dependency(int index, const char* value, si
// @@protoc_insertion_point(field_set_pointer:google.protobuf.FileDescriptorProto.dependency)
}
inline ::std::string* FileDescriptorProto::add_dependency() {
+ // @@protoc_insertion_point(field_add_mutable:google.protobuf.FileDescriptorProto.dependency)
return dependency_.Add();
}
inline void FileDescriptorProto::add_dependency(const ::std::string& value) {
@@ -3799,6 +4254,7 @@ inline ::google::protobuf::FileOptions* FileDescriptorProto::mutable_options() {
return options_;
}
inline ::google::protobuf::FileOptions* FileDescriptorProto::release_options() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.options)
clear_has_options();
::google::protobuf::FileOptions* temp = options_;
options_ = NULL;
@@ -3842,6 +4298,7 @@ inline ::google::protobuf::SourceCodeInfo* FileDescriptorProto::mutable_source_c
return source_code_info_;
}
inline ::google::protobuf::SourceCodeInfo* FileDescriptorProto::release_source_code_info() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.source_code_info)
clear_has_source_code_info();
::google::protobuf::SourceCodeInfo* temp = source_code_info_;
source_code_info_ = NULL;
@@ -3898,6 +4355,7 @@ inline ::std::string* FileDescriptorProto::mutable_syntax() {
return syntax_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* FileDescriptorProto::release_syntax() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.syntax)
clear_has_syntax();
return syntax_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -4059,6 +4517,7 @@ inline ::std::string* DescriptorProto::mutable_name() {
return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* DescriptorProto::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.DescriptorProto.name)
clear_has_name();
return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -4279,6 +4738,7 @@ inline ::google::protobuf::MessageOptions* DescriptorProto::mutable_options() {
return options_;
}
inline ::google::protobuf::MessageOptions* DescriptorProto::release_options() {
+ // @@protoc_insertion_point(field_release:google.protobuf.DescriptorProto.options)
clear_has_options();
::google::protobuf::MessageOptions* temp = options_;
options_ = NULL;
@@ -4354,6 +4814,7 @@ inline void DescriptorProto::set_reserved_name(int index, const char* value, siz
// @@protoc_insertion_point(field_set_pointer:google.protobuf.DescriptorProto.reserved_name)
}
inline ::std::string* DescriptorProto::add_reserved_name() {
+ // @@protoc_insertion_point(field_add_mutable:google.protobuf.DescriptorProto.reserved_name)
return reserved_name_.Add();
}
inline void DescriptorProto::add_reserved_name(const ::std::string& value) {
@@ -4423,6 +4884,7 @@ inline ::std::string* FieldDescriptorProto::mutable_name() {
return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* FieldDescriptorProto::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.name)
clear_has_name();
return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -4550,6 +5012,7 @@ inline ::std::string* FieldDescriptorProto::mutable_type_name() {
return type_name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* FieldDescriptorProto::release_type_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.type_name)
clear_has_type_name();
return type_name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -4603,6 +5066,7 @@ inline ::std::string* FieldDescriptorProto::mutable_extendee() {
return extendee_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* FieldDescriptorProto::release_extendee() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.extendee)
clear_has_extendee();
return extendee_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -4656,6 +5120,7 @@ inline ::std::string* FieldDescriptorProto::mutable_default_value() {
return default_value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* FieldDescriptorProto::release_default_value() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.default_value)
clear_has_default_value();
return default_value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -4733,6 +5198,7 @@ inline ::std::string* FieldDescriptorProto::mutable_json_name() {
return json_name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* FieldDescriptorProto::release_json_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.json_name)
clear_has_json_name();
return json_name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -4773,6 +5239,7 @@ inline ::google::protobuf::FieldOptions* FieldDescriptorProto::mutable_options()
return options_;
}
inline ::google::protobuf::FieldOptions* FieldDescriptorProto::release_options() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.options)
clear_has_options();
::google::protobuf::FieldOptions* temp = options_;
options_ = NULL;
@@ -4833,6 +5300,7 @@ inline ::std::string* OneofDescriptorProto::mutable_name() {
return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* OneofDescriptorProto::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.OneofDescriptorProto.name)
clear_has_name();
return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -4846,6 +5314,50 @@ inline void OneofDescriptorProto::set_allocated_name(::std::string* name) {
// @@protoc_insertion_point(field_set_allocated:google.protobuf.OneofDescriptorProto.name)
}
+// optional .google.protobuf.OneofOptions options = 2;
+inline bool OneofDescriptorProto::has_options() const {
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void OneofDescriptorProto::set_has_options() {
+ _has_bits_[0] |= 0x00000002u;
+}
+inline void OneofDescriptorProto::clear_has_options() {
+ _has_bits_[0] &= ~0x00000002u;
+}
+inline void OneofDescriptorProto::clear_options() {
+ if (options_ != NULL) options_->::google::protobuf::OneofOptions::Clear();
+ clear_has_options();
+}
+inline const ::google::protobuf::OneofOptions& OneofDescriptorProto::options() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.OneofDescriptorProto.options)
+ return options_ != NULL ? *options_ : *default_instance_->options_;
+}
+inline ::google::protobuf::OneofOptions* OneofDescriptorProto::mutable_options() {
+ set_has_options();
+ if (options_ == NULL) {
+ options_ = new ::google::protobuf::OneofOptions;
+ }
+ // @@protoc_insertion_point(field_mutable:google.protobuf.OneofDescriptorProto.options)
+ return options_;
+}
+inline ::google::protobuf::OneofOptions* OneofDescriptorProto::release_options() {
+ // @@protoc_insertion_point(field_release:google.protobuf.OneofDescriptorProto.options)
+ clear_has_options();
+ ::google::protobuf::OneofOptions* temp = options_;
+ options_ = NULL;
+ return temp;
+}
+inline void OneofDescriptorProto::set_allocated_options(::google::protobuf::OneofOptions* options) {
+ delete options_;
+ options_ = options;
+ if (options) {
+ set_has_options();
+ } else {
+ clear_has_options();
+ }
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.OneofDescriptorProto.options)
+}
+
// -------------------------------------------------------------------
// EnumDescriptorProto
@@ -4890,6 +5402,7 @@ inline ::std::string* EnumDescriptorProto::mutable_name() {
return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* EnumDescriptorProto::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.EnumDescriptorProto.name)
clear_has_name();
return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -4960,6 +5473,7 @@ inline ::google::protobuf::EnumOptions* EnumDescriptorProto::mutable_options() {
return options_;
}
inline ::google::protobuf::EnumOptions* EnumDescriptorProto::release_options() {
+ // @@protoc_insertion_point(field_release:google.protobuf.EnumDescriptorProto.options)
clear_has_options();
::google::protobuf::EnumOptions* temp = options_;
options_ = NULL;
@@ -5020,6 +5534,7 @@ inline ::std::string* EnumValueDescriptorProto::mutable_name() {
return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* EnumValueDescriptorProto::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.EnumValueDescriptorProto.name)
clear_has_name();
return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -5084,6 +5599,7 @@ inline ::google::protobuf::EnumValueOptions* EnumValueDescriptorProto::mutable_o
return options_;
}
inline ::google::protobuf::EnumValueOptions* EnumValueDescriptorProto::release_options() {
+ // @@protoc_insertion_point(field_release:google.protobuf.EnumValueDescriptorProto.options)
clear_has_options();
::google::protobuf::EnumValueOptions* temp = options_;
options_ = NULL;
@@ -5144,6 +5660,7 @@ inline ::std::string* ServiceDescriptorProto::mutable_name() {
return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* ServiceDescriptorProto::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.ServiceDescriptorProto.name)
clear_has_name();
return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -5214,6 +5731,7 @@ inline ::google::protobuf::ServiceOptions* ServiceDescriptorProto::mutable_optio
return options_;
}
inline ::google::protobuf::ServiceOptions* ServiceDescriptorProto::release_options() {
+ // @@protoc_insertion_point(field_release:google.protobuf.ServiceDescriptorProto.options)
clear_has_options();
::google::protobuf::ServiceOptions* temp = options_;
options_ = NULL;
@@ -5274,6 +5792,7 @@ inline ::std::string* MethodDescriptorProto::mutable_name() {
return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* MethodDescriptorProto::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.MethodDescriptorProto.name)
clear_has_name();
return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -5327,6 +5846,7 @@ inline ::std::string* MethodDescriptorProto::mutable_input_type() {
return input_type_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* MethodDescriptorProto::release_input_type() {
+ // @@protoc_insertion_point(field_release:google.protobuf.MethodDescriptorProto.input_type)
clear_has_input_type();
return input_type_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -5380,6 +5900,7 @@ inline ::std::string* MethodDescriptorProto::mutable_output_type() {
return output_type_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* MethodDescriptorProto::release_output_type() {
+ // @@protoc_insertion_point(field_release:google.protobuf.MethodDescriptorProto.output_type)
clear_has_output_type();
return output_type_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -5420,6 +5941,7 @@ inline ::google::protobuf::MethodOptions* MethodDescriptorProto::mutable_options
return options_;
}
inline ::google::protobuf::MethodOptions* MethodDescriptorProto::release_options() {
+ // @@protoc_insertion_point(field_release:google.protobuf.MethodDescriptorProto.options)
clear_has_options();
::google::protobuf::MethodOptions* temp = options_;
options_ = NULL;
@@ -5528,6 +6050,7 @@ inline ::std::string* FileOptions::mutable_java_package() {
return java_package_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* FileOptions::release_java_package() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.java_package)
clear_has_java_package();
return java_package_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -5581,6 +6104,7 @@ inline ::std::string* FileOptions::mutable_java_outer_classname() {
return java_outer_classname_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* FileOptions::release_java_outer_classname() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.java_outer_classname)
clear_has_java_outer_classname();
return java_outer_classname_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -5731,6 +6255,7 @@ inline ::std::string* FileOptions::mutable_go_package() {
return go_package_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* FileOptions::release_go_package() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.go_package)
clear_has_go_package();
return go_package_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -5904,6 +6429,7 @@ inline ::std::string* FileOptions::mutable_objc_class_prefix() {
return objc_class_prefix_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* FileOptions::release_objc_class_prefix() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.objc_class_prefix)
clear_has_objc_class_prefix();
return objc_class_prefix_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -5957,6 +6483,7 @@ inline ::std::string* FileOptions::mutable_csharp_namespace() {
return csharp_namespace_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* FileOptions::release_csharp_namespace() {
+ // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.csharp_namespace)
clear_has_csharp_namespace();
return csharp_namespace_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -5970,30 +6497,6 @@ inline void FileOptions::set_allocated_csharp_namespace(::std::string* csharp_na
// @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.csharp_namespace)
}
-// optional bool javanano_use_deprecated_package = 38;
-inline bool FileOptions::has_javanano_use_deprecated_package() const {
- return (_has_bits_[0] & 0x00004000u) != 0;
-}
-inline void FileOptions::set_has_javanano_use_deprecated_package() {
- _has_bits_[0] |= 0x00004000u;
-}
-inline void FileOptions::clear_has_javanano_use_deprecated_package() {
- _has_bits_[0] &= ~0x00004000u;
-}
-inline void FileOptions::clear_javanano_use_deprecated_package() {
- javanano_use_deprecated_package_ = false;
- clear_has_javanano_use_deprecated_package();
-}
-inline bool FileOptions::javanano_use_deprecated_package() const {
- // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.javanano_use_deprecated_package)
- return javanano_use_deprecated_package_;
-}
-inline void FileOptions::set_javanano_use_deprecated_package(bool value) {
- set_has_javanano_use_deprecated_package();
- javanano_use_deprecated_package_ = value;
- // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.javanano_use_deprecated_package)
-}
-
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
inline int FileOptions::uninterpreted_option_size() const {
return uninterpreted_option_.size();
@@ -6336,6 +6839,40 @@ FieldOptions::uninterpreted_option() const {
// -------------------------------------------------------------------
+// OneofOptions
+
+// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+inline int OneofOptions::uninterpreted_option_size() const {
+ return uninterpreted_option_.size();
+}
+inline void OneofOptions::clear_uninterpreted_option() {
+ uninterpreted_option_.Clear();
+}
+inline const ::google::protobuf::UninterpretedOption& OneofOptions::uninterpreted_option(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.OneofOptions.uninterpreted_option)
+ return uninterpreted_option_.Get(index);
+}
+inline ::google::protobuf::UninterpretedOption* OneofOptions::mutable_uninterpreted_option(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.OneofOptions.uninterpreted_option)
+ return uninterpreted_option_.Mutable(index);
+}
+inline ::google::protobuf::UninterpretedOption* OneofOptions::add_uninterpreted_option() {
+ // @@protoc_insertion_point(field_add:google.protobuf.OneofOptions.uninterpreted_option)
+ return uninterpreted_option_.Add();
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+OneofOptions::mutable_uninterpreted_option() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.OneofOptions.uninterpreted_option)
+ return &uninterpreted_option_;
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+OneofOptions::uninterpreted_option() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.OneofOptions.uninterpreted_option)
+ return uninterpreted_option_;
+}
+
+// -------------------------------------------------------------------
+
// EnumOptions
// optional bool allow_alias = 2;
@@ -6634,6 +7171,7 @@ inline ::std::string* UninterpretedOption_NamePart::mutable_name_part() {
return name_part_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* UninterpretedOption_NamePart::release_name_part() {
+ // @@protoc_insertion_point(field_release:google.protobuf.UninterpretedOption.NamePart.name_part)
clear_has_name_part();
return name_part_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -6745,6 +7283,7 @@ inline ::std::string* UninterpretedOption::mutable_identifier_value() {
return identifier_value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* UninterpretedOption::release_identifier_value() {
+ // @@protoc_insertion_point(field_release:google.protobuf.UninterpretedOption.identifier_value)
clear_has_identifier_value();
return identifier_value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -6870,6 +7409,7 @@ inline ::std::string* UninterpretedOption::mutable_string_value() {
return string_value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* UninterpretedOption::release_string_value() {
+ // @@protoc_insertion_point(field_release:google.protobuf.UninterpretedOption.string_value)
clear_has_string_value();
return string_value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -6923,6 +7463,7 @@ inline ::std::string* UninterpretedOption::mutable_aggregate_value() {
return aggregate_value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* UninterpretedOption::release_aggregate_value() {
+ // @@protoc_insertion_point(field_release:google.protobuf.UninterpretedOption.aggregate_value)
clear_has_aggregate_value();
return aggregate_value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -7040,6 +7581,7 @@ inline ::std::string* SourceCodeInfo_Location::mutable_leading_comments() {
return leading_comments_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* SourceCodeInfo_Location::release_leading_comments() {
+ // @@protoc_insertion_point(field_release:google.protobuf.SourceCodeInfo.Location.leading_comments)
clear_has_leading_comments();
return leading_comments_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -7093,6 +7635,7 @@ inline ::std::string* SourceCodeInfo_Location::mutable_trailing_comments() {
return trailing_comments_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* SourceCodeInfo_Location::release_trailing_comments() {
+ // @@protoc_insertion_point(field_release:google.protobuf.SourceCodeInfo.Location.trailing_comments)
clear_has_trailing_comments();
return trailing_comments_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -7135,6 +7678,7 @@ inline void SourceCodeInfo_Location::set_leading_detached_comments(int index, co
// @@protoc_insertion_point(field_set_pointer:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
}
inline ::std::string* SourceCodeInfo_Location::add_leading_detached_comments() {
+ // @@protoc_insertion_point(field_add_mutable:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
return leading_detached_comments_.Add();
}
inline void SourceCodeInfo_Location::add_leading_detached_comments(const ::std::string& value) {
@@ -7194,6 +7738,176 @@ SourceCodeInfo::location() const {
return location_;
}
+// -------------------------------------------------------------------
+
+// GeneratedCodeInfo_Annotation
+
+// repeated int32 path = 1 [packed = true];
+inline int GeneratedCodeInfo_Annotation::path_size() const {
+ return path_.size();
+}
+inline void GeneratedCodeInfo_Annotation::clear_path() {
+ path_.Clear();
+}
+inline ::google::protobuf::int32 GeneratedCodeInfo_Annotation::path(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.GeneratedCodeInfo.Annotation.path)
+ return path_.Get(index);
+}
+inline void GeneratedCodeInfo_Annotation::set_path(int index, ::google::protobuf::int32 value) {
+ path_.Set(index, value);
+ // @@protoc_insertion_point(field_set:google.protobuf.GeneratedCodeInfo.Annotation.path)
+}
+inline void GeneratedCodeInfo_Annotation::add_path(::google::protobuf::int32 value) {
+ path_.Add(value);
+ // @@protoc_insertion_point(field_add:google.protobuf.GeneratedCodeInfo.Annotation.path)
+}
+inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
+GeneratedCodeInfo_Annotation::path() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.GeneratedCodeInfo.Annotation.path)
+ return path_;
+}
+inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
+GeneratedCodeInfo_Annotation::mutable_path() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.GeneratedCodeInfo.Annotation.path)
+ return &path_;
+}
+
+// optional string source_file = 2;
+inline bool GeneratedCodeInfo_Annotation::has_source_file() const {
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void GeneratedCodeInfo_Annotation::set_has_source_file() {
+ _has_bits_[0] |= 0x00000002u;
+}
+inline void GeneratedCodeInfo_Annotation::clear_has_source_file() {
+ _has_bits_[0] &= ~0x00000002u;
+}
+inline void GeneratedCodeInfo_Annotation::clear_source_file() {
+ source_file_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ clear_has_source_file();
+}
+inline const ::std::string& GeneratedCodeInfo_Annotation::source_file() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.GeneratedCodeInfo.Annotation.source_file)
+ return source_file_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void GeneratedCodeInfo_Annotation::set_source_file(const ::std::string& value) {
+ set_has_source_file();
+ source_file_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+ // @@protoc_insertion_point(field_set:google.protobuf.GeneratedCodeInfo.Annotation.source_file)
+}
+inline void GeneratedCodeInfo_Annotation::set_source_file(const char* value) {
+ set_has_source_file();
+ source_file_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+ // @@protoc_insertion_point(field_set_char:google.protobuf.GeneratedCodeInfo.Annotation.source_file)
+}
+inline void GeneratedCodeInfo_Annotation::set_source_file(const char* value, size_t size) {
+ set_has_source_file();
+ source_file_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+ ::std::string(reinterpret_cast<const char*>(value), size));
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.GeneratedCodeInfo.Annotation.source_file)
+}
+inline ::std::string* GeneratedCodeInfo_Annotation::mutable_source_file() {
+ set_has_source_file();
+ // @@protoc_insertion_point(field_mutable:google.protobuf.GeneratedCodeInfo.Annotation.source_file)
+ return source_file_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* GeneratedCodeInfo_Annotation::release_source_file() {
+ // @@protoc_insertion_point(field_release:google.protobuf.GeneratedCodeInfo.Annotation.source_file)
+ clear_has_source_file();
+ return source_file_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void GeneratedCodeInfo_Annotation::set_allocated_source_file(::std::string* source_file) {
+ if (source_file != NULL) {
+ set_has_source_file();
+ } else {
+ clear_has_source_file();
+ }
+ source_file_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), source_file);
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.GeneratedCodeInfo.Annotation.source_file)
+}
+
+// optional int32 begin = 3;
+inline bool GeneratedCodeInfo_Annotation::has_begin() const {
+ return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void GeneratedCodeInfo_Annotation::set_has_begin() {
+ _has_bits_[0] |= 0x00000004u;
+}
+inline void GeneratedCodeInfo_Annotation::clear_has_begin() {
+ _has_bits_[0] &= ~0x00000004u;
+}
+inline void GeneratedCodeInfo_Annotation::clear_begin() {
+ begin_ = 0;
+ clear_has_begin();
+}
+inline ::google::protobuf::int32 GeneratedCodeInfo_Annotation::begin() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.GeneratedCodeInfo.Annotation.begin)
+ return begin_;
+}
+inline void GeneratedCodeInfo_Annotation::set_begin(::google::protobuf::int32 value) {
+ set_has_begin();
+ begin_ = value;
+ // @@protoc_insertion_point(field_set:google.protobuf.GeneratedCodeInfo.Annotation.begin)
+}
+
+// optional int32 end = 4;
+inline bool GeneratedCodeInfo_Annotation::has_end() const {
+ return (_has_bits_[0] & 0x00000008u) != 0;
+}
+inline void GeneratedCodeInfo_Annotation::set_has_end() {
+ _has_bits_[0] |= 0x00000008u;
+}
+inline void GeneratedCodeInfo_Annotation::clear_has_end() {
+ _has_bits_[0] &= ~0x00000008u;
+}
+inline void GeneratedCodeInfo_Annotation::clear_end() {
+ end_ = 0;
+ clear_has_end();
+}
+inline ::google::protobuf::int32 GeneratedCodeInfo_Annotation::end() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.GeneratedCodeInfo.Annotation.end)
+ return end_;
+}
+inline void GeneratedCodeInfo_Annotation::set_end(::google::protobuf::int32 value) {
+ set_has_end();
+ end_ = value;
+ // @@protoc_insertion_point(field_set:google.protobuf.GeneratedCodeInfo.Annotation.end)
+}
+
+// -------------------------------------------------------------------
+
+// GeneratedCodeInfo
+
+// repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1;
+inline int GeneratedCodeInfo::annotation_size() const {
+ return annotation_.size();
+}
+inline void GeneratedCodeInfo::clear_annotation() {
+ annotation_.Clear();
+}
+inline const ::google::protobuf::GeneratedCodeInfo_Annotation& GeneratedCodeInfo::annotation(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.GeneratedCodeInfo.annotation)
+ return annotation_.Get(index);
+}
+inline ::google::protobuf::GeneratedCodeInfo_Annotation* GeneratedCodeInfo::mutable_annotation(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.GeneratedCodeInfo.annotation)
+ return annotation_.Mutable(index);
+}
+inline ::google::protobuf::GeneratedCodeInfo_Annotation* GeneratedCodeInfo::add_annotation() {
+ // @@protoc_insertion_point(field_add:google.protobuf.GeneratedCodeInfo.annotation)
+ return annotation_.Add();
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::GeneratedCodeInfo_Annotation >*
+GeneratedCodeInfo::mutable_annotation() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.GeneratedCodeInfo.annotation)
+ return &annotation_;
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::GeneratedCodeInfo_Annotation >&
+GeneratedCodeInfo::annotation() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.GeneratedCodeInfo.annotation)
+ return annotation_;
+}
+
#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS
// -------------------------------------------------------------------
@@ -7237,6 +7951,12 @@ SourceCodeInfo::location() const {
// -------------------------------------------------------------------
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
// @@protoc_insertion_point(namespace_scope)
diff --git a/src/google/protobuf/descriptor.proto b/src/google/protobuf/descriptor.proto
index c59a6022..28410d4a 100644
--- a/src/google/protobuf/descriptor.proto
+++ b/src/google/protobuf/descriptor.proto
@@ -45,6 +45,7 @@ option java_package = "com.google.protobuf";
option java_outer_classname = "DescriptorProtos";
option csharp_namespace = "Google.Protobuf.Reflection";
option objc_class_prefix = "GPB";
+option java_generate_equals_and_hash = true;
// descriptor.proto must be optimized for speed because reflection-based
// algorithms don't work during bootstrapping.
@@ -202,6 +203,7 @@ message FieldDescriptorProto {
// Describes a oneof.
message OneofDescriptorProto {
optional string name = 1;
+ optional OneofOptions options = 2;
}
// Describes an enum type.
@@ -377,15 +379,13 @@ message FileOptions {
// Namespace for generated classes; defaults to the package.
optional string csharp_namespace = 37;
- // Whether the nano proto compiler should generate in the deprecated non-nano
- // suffixed package.
- optional bool javanano_use_deprecated_package = 38;
-
// The parser stores options it doesn't recognize here. See above.
repeated UninterpretedOption uninterpreted_option = 999;
// Clients can define custom options in extensions of this message. See above.
extensions 1000 to max;
+
+ reserved 38;
}
message MessageOptions {
@@ -540,6 +540,14 @@ message FieldOptions {
extensions 1000 to max;
}
+message OneofOptions {
+ // The parser stores options it doesn't recognize here. See above.
+ repeated UninterpretedOption uninterpreted_option = 999;
+
+ // Clients can define custom options in extensions of this message. See above.
+ extensions 1000 to max;
+}
+
message EnumOptions {
// Set this option to true to allow mapping different tag names to the same
@@ -777,3 +785,29 @@ message SourceCodeInfo {
repeated string leading_detached_comments = 6;
}
}
+
+// Describes the relationship between generated code and its original source
+// file. A GeneratedCodeInfo message is associated with only one generated
+// source file, but may contain references to different source .proto files.
+message GeneratedCodeInfo {
+ // An Annotation connects some span of text in generated code to an element
+ // of its generating .proto file.
+ repeated Annotation annotation = 1;
+ message Annotation {
+ // Identifies the element in the original source .proto file. This field
+ // is formatted the same as SourceCodeInfo.Location.path.
+ repeated int32 path = 1 [packed=true];
+
+ // Identifies the filesystem path to the original source .proto.
+ optional string source_file = 2;
+
+ // Identifies the starting offset in bytes in the generated code
+ // that relates to the identified object.
+ optional int32 begin = 3;
+
+ // Identifies the ending offset in bytes in the generated code that
+ // relates to the identified offset. The end offset should be one past
+ // the last relevant byte (so the length of the text = end - begin).
+ optional int32 end = 4;
+ }
+}
diff --git a/src/google/protobuf/descriptor_database_unittest.cc b/src/google/protobuf/descriptor_database_unittest.cc
index 1fc3816e..4f568f7d 100644
--- a/src/google/protobuf/descriptor_database_unittest.cc
+++ b/src/google/protobuf/descriptor_database_unittest.cc
@@ -48,7 +48,6 @@
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/scoped_ptr.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
diff --git a/src/google/protobuf/descriptor_unittest.cc b/src/google/protobuf/descriptor_unittest.cc
index ccd0650d..4183138f 100644
--- a/src/google/protobuf/descriptor_unittest.cc
+++ b/src/google/protobuf/descriptor_unittest.cc
@@ -54,7 +54,7 @@
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/logging.h>
-#include <google/protobuf/stubs/scoped_ptr.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
@@ -178,6 +178,61 @@ void AddEmptyEnum(FileDescriptorProto* file, const string& name) {
AddEnumValue(AddEnum(file, name), name + "_DUMMY", 1);
}
+class MockErrorCollector : public DescriptorPool::ErrorCollector {
+ public:
+ MockErrorCollector() {}
+ ~MockErrorCollector() {}
+
+ string text_;
+ string warning_text_;
+
+ // implements ErrorCollector ---------------------------------------
+ void AddError(const string& filename,
+ const string& element_name, const Message* descriptor,
+ ErrorLocation location, const string& message) {
+ const char* location_name = NULL;
+ switch (location) {
+ case NAME : location_name = "NAME" ; break;
+ case NUMBER : location_name = "NUMBER" ; break;
+ case TYPE : location_name = "TYPE" ; break;
+ case EXTENDEE : location_name = "EXTENDEE" ; break;
+ case DEFAULT_VALUE: location_name = "DEFAULT_VALUE"; break;
+ case OPTION_NAME : location_name = "OPTION_NAME" ; break;
+ case OPTION_VALUE : location_name = "OPTION_VALUE" ; break;
+ case INPUT_TYPE : location_name = "INPUT_TYPE" ; break;
+ case OUTPUT_TYPE : location_name = "OUTPUT_TYPE" ; break;
+ case OTHER : location_name = "OTHER" ; break;
+ }
+
+ strings::SubstituteAndAppend(
+ &text_, "$0: $1: $2: $3\n",
+ filename, element_name, location_name, message);
+ }
+
+ // implements ErrorCollector ---------------------------------------
+ void AddWarning(const string& filename, const string& element_name,
+ const Message* descriptor, ErrorLocation location,
+ const string& message) {
+ const char* location_name = NULL;
+ switch (location) {
+ case NAME : location_name = "NAME" ; break;
+ case NUMBER : location_name = "NUMBER" ; break;
+ case TYPE : location_name = "TYPE" ; break;
+ case EXTENDEE : location_name = "EXTENDEE" ; break;
+ case DEFAULT_VALUE: location_name = "DEFAULT_VALUE"; break;
+ case OPTION_NAME : location_name = "OPTION_NAME" ; break;
+ case OPTION_VALUE : location_name = "OPTION_VALUE" ; break;
+ case INPUT_TYPE : location_name = "INPUT_TYPE" ; break;
+ case OUTPUT_TYPE : location_name = "OUTPUT_TYPE" ; break;
+ case OTHER : location_name = "OTHER" ; break;
+ }
+
+ strings::SubstituteAndAppend(
+ &warning_text_, "$0: $1: $2: $3\n",
+ filename, element_name, location_name, message);
+ }
+};
+
// ===================================================================
// Test simple files.
@@ -2649,6 +2704,7 @@ TEST(CustomOptions, OptionLocations) {
protobuf_unittest::TestMessageWithCustomOptions::descriptor();
const FileDescriptor* file = message->file();
const FieldDescriptor* field = message->FindFieldByName("field1");
+ const OneofDescriptor* oneof = message->FindOneofByName("AnOneof");
const EnumDescriptor* enm = message->FindEnumTypeByName("AnEnum");
// TODO(benjy): Support EnumValue options, once the compiler does.
const ServiceDescriptor* service =
@@ -2663,6 +2719,8 @@ TEST(CustomOptions, OptionLocations) {
field->options().GetExtension(protobuf_unittest::field_opt1));
EXPECT_EQ(42, // Check that we get the default for an option we don't set.
field->options().GetExtension(protobuf_unittest::field_opt2));
+ EXPECT_EQ(-99,
+ oneof->options().GetExtension(protobuf_unittest::oneof_opt1));
EXPECT_EQ(-789,
enm->options().GetExtension(protobuf_unittest::enum_opt1));
EXPECT_EQ(123,
@@ -3120,77 +3178,95 @@ TEST(CustomOptions, UnusedImportWarning) {
->file()->CopyTo(&file_proto);
ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
-
pool.AddUnusedImportTrackFile("custom_options_import.proto");
ASSERT_TRUE(TextFormat::ParseFromString(
"name: \"custom_options_import.proto\" "
"package: \"protobuf_unittest\" "
"dependency: \"google/protobuf/unittest_custom_options.proto\" ",
&file_proto));
- pool.BuildFile(file_proto);
-}
-// ===================================================================
+ MockErrorCollector error_collector;
+ EXPECT_TRUE(pool.BuildFileCollectingErrors(file_proto, &error_collector));
+ EXPECT_EQ("", error_collector.warning_text_);
+}
-// The tests below trigger every unique call to AddError() in descriptor.cc,
-// in the order in which they appear in that file. I'm using TextFormat here
-// to specify the input descriptors because building them using code would
-// be too bulky.
+// Verifies that proto files can correctly be parsed, even if the
+// custom options defined in the file are incompatible with those
+// compiled in the binary. See http://b/19276250.
+TEST(CustomOptions, OptionsWithRequiredEnums) {
+ DescriptorPool pool;
-class MockErrorCollector : public DescriptorPool::ErrorCollector {
- public:
- MockErrorCollector() {}
- ~MockErrorCollector() {}
+ FileDescriptorProto file_proto;
+ MessageOptions::descriptor()->file()->CopyTo(&file_proto);
+ ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
- string text_;
- string warning_text_;
+ // Create a new file descriptor proto containing a subset of the
+ // messages defined in google/protobuf/unittest_custom_options.proto.
+ file_proto.Clear();
+ file_proto.set_name("unittest_custom_options.proto");
+ file_proto.set_package("protobuf_unittest");
+ file_proto.add_dependency("google/protobuf/descriptor.proto");
- // implements ErrorCollector ---------------------------------------
- void AddError(const string& filename,
- const string& element_name, const Message* descriptor,
- ErrorLocation location, const string& message) {
- const char* location_name = NULL;
- switch (location) {
- case NAME : location_name = "NAME" ; break;
- case NUMBER : location_name = "NUMBER" ; break;
- case TYPE : location_name = "TYPE" ; break;
- case EXTENDEE : location_name = "EXTENDEE" ; break;
- case DEFAULT_VALUE: location_name = "DEFAULT_VALUE"; break;
- case OPTION_NAME : location_name = "OPTION_NAME" ; break;
- case OPTION_VALUE : location_name = "OPTION_VALUE" ; break;
- case INPUT_TYPE : location_name = "INPUT_TYPE" ; break;
- case OUTPUT_TYPE : location_name = "OUTPUT_TYPE" ; break;
- case OTHER : location_name = "OTHER" ; break;
- }
+ // Add the "required_enum_opt" extension.
+ FieldDescriptorProto* extension = file_proto.add_extension();
+ protobuf_unittest::OldOptionType::descriptor()->file()
+ ->FindExtensionByName("required_enum_opt")->CopyTo(extension);
+
+ // Add a test message that uses the "required_enum_opt" option.
+ DescriptorProto* test_message_type = file_proto.add_message_type();
+ protobuf_unittest::TestMessageWithRequiredEnumOption::descriptor()
+ ->CopyTo(test_message_type);
+
+ // Instruct the extension to use NewOptionType instead of
+ // OldOptionType, and add the descriptor of NewOptionType.
+ extension->set_type_name(".protobuf_unittest.NewOptionType");
+ DescriptorProto* new_option_type = file_proto.add_message_type();
+ protobuf_unittest::NewOptionType::descriptor()
+ ->CopyTo(new_option_type);
+
+ // Replace the value of the "required_enum_opt" option used in the
+ // test message with an enum value that only exists in NewOptionType.
+ ASSERT_TRUE(TextFormat::ParseFromString(
+ "uninterpreted_option { "
+ " name { "
+ " name_part: 'required_enum_opt' "
+ " is_extension: true "
+ " } "
+ " aggregate_value: 'value: NEW_VALUE' "
+ "}",
+ test_message_type->mutable_options()));
- strings::SubstituteAndAppend(
- &text_, "$0: $1: $2: $3\n",
- filename, element_name, location_name, message);
- }
+ // Add the file descriptor to the pool.
+ ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
- // implements ErrorCollector ---------------------------------------
- void AddWarning(const string& filename, const string& element_name,
- const Message* descriptor, ErrorLocation location,
- const string& message) {
- const char* location_name = NULL;
- switch (location) {
- case NAME : location_name = "NAME" ; break;
- case NUMBER : location_name = "NUMBER" ; break;
- case TYPE : location_name = "TYPE" ; break;
- case EXTENDEE : location_name = "EXTENDEE" ; break;
- case DEFAULT_VALUE: location_name = "DEFAULT_VALUE"; break;
- case OPTION_NAME : location_name = "OPTION_NAME" ; break;
- case OPTION_VALUE : location_name = "OPTION_VALUE" ; break;
- case INPUT_TYPE : location_name = "INPUT_TYPE" ; break;
- case OUTPUT_TYPE : location_name = "OUTPUT_TYPE" ; break;
- case OTHER : location_name = "OTHER" ; break;
- }
+ // Find the test message.
+ const Descriptor* test_message = pool.FindMessageTypeByName(
+ "protobuf_unittest.TestMessageWithRequiredEnumOption");
+ ASSERT_TRUE(test_message != NULL);
+
+ const MessageOptions& options = test_message->options();
+ // Extract the "required_enum_opt" option. Since the binary does not
+ // know that the extension was updated, this will still return an
+ // OldOptionType message.
+ ASSERT_TRUE(
+ options.HasExtension(protobuf_unittest::required_enum_opt));
+ const protobuf_unittest::OldOptionType& old_enum_opt =
+ options.GetExtension(protobuf_unittest::required_enum_opt);
+
+ // Confirm that the required enum field is missing.
+ EXPECT_FALSE(old_enum_opt.IsInitialized());
+ EXPECT_FALSE(old_enum_opt.has_value());
+
+ string buf;
+ // Verify that the required enum field does show up when the option
+ // is re-parsed as a NewOptionType message;
+ protobuf_unittest::NewOptionType new_enum_opt;
+ EXPECT_TRUE(old_enum_opt.AppendPartialToString(&buf));
+ EXPECT_TRUE(new_enum_opt.ParseFromString(buf));
+ EXPECT_EQ(protobuf_unittest::NewOptionType::NEW_VALUE, new_enum_opt.value());
+}
- strings::SubstituteAndAppend(
- &warning_text_, "$0: $1: $2: $3\n",
- filename, element_name, location_name, message);
- }
-};
+// ===================================================================
class ValidationErrorTest : public testing::Test {
protected:
@@ -4953,7 +5029,7 @@ TEST_F(ValidationErrorTest, AggregateValueParseError) {
BuildFileWithErrors(
EmbedAggregateValue("aggregate_value: \"1+2\""),
"foo.proto: foo.proto: OPTION_VALUE: Error while parsing option "
- "value for \"foo\": Expected identifier.\n");
+ "value for \"foo\": Expected identifier, got: 1\n");
}
TEST_F(ValidationErrorTest, AggregateValueUnknownFields) {
@@ -5123,7 +5199,6 @@ TEST_F(ValidationErrorTest, AllowEnumAlias) {
}
TEST_F(ValidationErrorTest, UnusedImportWarning) {
-
pool_.AddUnusedImportTrackFile("bar.proto");
BuildFile(
"name: \"bar.proto\" "
@@ -5155,7 +5230,7 @@ TEST_F(ValidationErrorTest, UnusedImportWarning) {
// }
//
pool_.AddUnusedImportTrackFile("forward.proto");
- BuildFile(
+ BuildFileWithWarnings(
"name: \"forward.proto\""
"dependency: \"base.proto\""
"dependency: \"bar.proto\""
@@ -5165,7 +5240,8 @@ TEST_F(ValidationErrorTest, UnusedImportWarning) {
"message_type {"
" name: \"Forward\""
" field { name:\"base\" number:1 label:LABEL_OPTIONAL type_name:\"Base\" }"
- "}");
+ "}",
+ "forward.proto: bar.proto: OTHER: Import bar.proto but not used.\n");
}
namespace {
@@ -5666,18 +5742,6 @@ TEST_F(ValidationErrorTest, ValidateProto3Enum) {
"}");
}
-TEST_F(ValidationErrorTest, ValidateProto3LiteRuntime) {
- // Lite runtime is not supported in proto3.
- BuildFileWithErrors(
- "name: 'foo.proto' "
- "syntax: 'proto3' "
- "options { "
- " optimize_for: LITE_RUNTIME "
- "} ",
- "foo.proto: foo.proto: OTHER: Lite runtime is not supported "
- "in proto3.\n");
-}
-
TEST_F(ValidationErrorTest, ValidateProto3Group) {
BuildFileWithErrors(
"name: 'foo.proto' "
@@ -5772,7 +5836,7 @@ TEST_F(ValidationErrorTest, ValidateProto3JsonName) {
" field { name:'name' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
" field { name:'Name' number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }"
"}",
- "foo.proto: Foo: OTHER: The JSON camcel-case name of field \"Name\" "
+ "foo.proto: Foo: OTHER: The JSON camel-case name of field \"Name\" "
"conflicts with field \"name\". This is not allowed in proto3.\n");
// Underscores are ignored.
BuildFileWithErrors(
@@ -5783,7 +5847,7 @@ TEST_F(ValidationErrorTest, ValidateProto3JsonName) {
" field { name:'ab' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
" field { name:'_a__b_' number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }"
"}",
- "foo.proto: Foo: OTHER: The JSON camcel-case name of field \"_a__b_\" "
+ "foo.proto: Foo: OTHER: The JSON camel-case name of field \"_a__b_\" "
"conflicts with field \"ab\". This is not allowed in proto3.\n");
}
diff --git a/src/google/protobuf/duration.pb.cc b/src/google/protobuf/duration.pb.cc
index c7eed0d5..94ece18e 100644
--- a/src/google/protobuf/duration.pb.cc
+++ b/src/google/protobuf/duration.pb.cc
@@ -7,6 +7,7 @@
#include <algorithm>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/port.h>
#include <google/protobuf/stubs/once.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/wire_format_lite_inl.h>
@@ -28,6 +29,7 @@ const ::google::protobuf::internal::GeneratedMessageReflection*
} // namespace
+void protobuf_AssignDesc_google_2fprotobuf_2fduration_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AssignDesc_google_2fprotobuf_2fduration_2eproto() {
protobuf_AddDesc_google_2fprotobuf_2fduration_2eproto();
const ::google::protobuf::FileDescriptor* file =
@@ -60,6 +62,7 @@ inline void protobuf_AssignDescriptorsOnce() {
&protobuf_AssignDesc_google_2fprotobuf_2fduration_2eproto);
}
+void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
void protobuf_RegisterTypes(const ::std::string&) {
protobuf_AssignDescriptorsOnce();
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
@@ -73,6 +76,7 @@ void protobuf_ShutdownFile_google_2fprotobuf_2fduration_2eproto() {
delete Duration_reflection_;
}
+void protobuf_AddDesc_google_2fprotobuf_2fduration_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AddDesc_google_2fprotobuf_2fduration_2eproto() {
static bool already_here = false;
if (already_here) return;
@@ -82,9 +86,10 @@ void protobuf_AddDesc_google_2fprotobuf_2fduration_2eproto() {
::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
"\n\036google/protobuf/duration.proto\022\017google"
".protobuf\"*\n\010Duration\022\017\n\007seconds\030\001 \001(\003\022\r"
- "\n\005nanos\030\002 \001(\005BP\n\023com.google.protobufB\rDu"
- "rationProtoP\001\240\001\001\242\002\003GPB\252\002\036Google.Protobuf"
- ".WellKnownTypesb\006proto3", 183);
+ "\n\005nanos\030\002 \001(\005B|\n\023com.google.protobufB\rDu"
+ "rationProtoP\001Z*github.com/golang/protobu"
+ "f/ptypes/duration\240\001\001\242\002\003GPB\252\002\036Google.Prot"
+ "obuf.WellKnownTypesb\006proto3", 227);
::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
"google/protobuf/duration.proto", &protobuf_RegisterTypes);
Duration::default_instance_ = new Duration();
@@ -99,16 +104,6 @@ struct StaticDescriptorInitializer_google_2fprotobuf_2fduration_2eproto {
}
} static_descriptor_initializer_google_2fprotobuf_2fduration_2eproto_;
-namespace {
-
-static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD;
-static void MergeFromFail(int line) {
- GOOGLE_CHECK(false) << __FILE__ << ":" << line;
-}
-
-} // namespace
-
-
// ===================================================================
#if !defined(_MSC_VER) || _MSC_VER >= 1900
@@ -177,8 +172,17 @@ Duration* Duration::New(::google::protobuf::Arena* arena) const {
}
void Duration::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.Duration)
+#if defined(__clang__)
+#define ZR_HELPER_(f) \
+ _Pragma("clang diagnostic push") \
+ _Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"") \
+ __builtin_offsetof(Duration, f) \
+ _Pragma("clang diagnostic pop")
+#else
#define ZR_HELPER_(f) reinterpret_cast<char*>(\
&reinterpret_cast<Duration*>(16)->f)
+#endif
#define ZR_(first, last) do {\
::memset(&first, 0,\
@@ -194,7 +198,7 @@ void Duration::Clear() {
bool Duration::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.Duration)
for (;;) {
@@ -268,8 +272,8 @@ void Duration::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.Duration)
}
-::google::protobuf::uint8* Duration::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* Duration::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Duration)
// optional int64 seconds = 1;
if (this->seconds() != 0) {
@@ -286,6 +290,7 @@ void Duration::SerializeWithCachedSizes(
}
int Duration::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Duration)
int total_size = 0;
// optional int64 seconds = 1;
@@ -309,19 +314,27 @@ int Duration::ByteSize() const {
}
void Duration::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Duration)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const Duration* source =
::google::protobuf::internal::DynamicCastToGenerated<const Duration>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.Duration)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.Duration)
MergeFrom(*source);
}
}
void Duration::MergeFrom(const Duration& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Duration)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from.seconds() != 0) {
set_seconds(from.seconds());
}
@@ -331,12 +344,14 @@ void Duration::MergeFrom(const Duration& from) {
}
void Duration::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.Duration)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void Duration::CopyFrom(const Duration& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Duration)
if (&from == this) return;
Clear();
MergeFrom(from);
diff --git a/src/google/protobuf/duration.pb.h b/src/google/protobuf/duration.pb.h
index 215a52c4..ad479639 100644
--- a/src/google/protobuf/duration.pb.h
+++ b/src/google/protobuf/duration.pb.h
@@ -41,7 +41,7 @@ class Duration;
// ===================================================================
-class LIBPROTOBUF_EXPORT Duration : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT Duration : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Duration) */ {
public:
Duration();
virtual ~Duration();
@@ -75,7 +75,11 @@ class LIBPROTOBUF_EXPORT Duration : public ::google::protobuf::Message {
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
diff --git a/src/google/protobuf/duration.proto b/src/google/protobuf/duration.proto
index 7f172aa6..96c1796d 100644
--- a/src/google/protobuf/duration.proto
+++ b/src/google/protobuf/duration.proto
@@ -27,15 +27,17 @@
// 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.
+
syntax = "proto3";
package google.protobuf;
-option java_generate_equals_and_hash = true;
-option java_multiple_files = true;
-option java_outer_classname = "DurationProto";
-option java_package = "com.google.protobuf";
option csharp_namespace = "Google.Protobuf.WellKnownTypes";
+option go_package = "github.com/golang/protobuf/ptypes/duration";
+option java_package = "com.google.protobuf";
+option java_outer_classname = "DurationProto";
+option java_multiple_files = true;
+option java_generate_equals_and_hash = true;
option objc_class_prefix = "GPB";
// A Duration represents a signed, fixed-length span of time represented
@@ -79,6 +81,7 @@ option objc_class_prefix = "GPB";
// end.nanos -= 1000000000;
// }
//
+//
message Duration {
// Signed seconds of the span of time. Must be from -315,576,000,000
diff --git a/src/google/protobuf/dynamic_message.cc b/src/google/protobuf/dynamic_message.cc
index 091fc975..5d914bf6 100644
--- a/src/google/protobuf/dynamic_message.cc
+++ b/src/google/protobuf/dynamic_message.cc
@@ -69,7 +69,6 @@
#include <google/protobuf/stubs/shared_ptr.h>
#endif
-#include <google/protobuf/stubs/scoped_ptr.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/dynamic_message.h>
@@ -267,6 +266,16 @@ class DynamicMessage : public Message {
Metadata GetMetadata() const;
+ // We actually allocate more memory than sizeof(*this) when this
+ // class's memory is allocated via the global operator new. Thus, we need to
+ // manually call the global operator delete. Calling the destructor is taken
+ // care of for us. This makes DynamicMessage compatible with -fsized-delete.
+ // It doesn't work for MSVC though.
+#ifndef _MSC_VER
+ static void operator delete(void* ptr) {
+ ::operator delete(ptr);
+ }
+#endif // !_MSC_VER
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMessage);
@@ -419,7 +428,7 @@ DynamicMessage::~DynamicMessage() {
}
// We need to manually run the destructors for repeated fields and strings,
- // just as we ran their constructors in the the DynamicMessage constructor.
+ // just as we ran their constructors in the DynamicMessage constructor.
// We also need to manually delete oneof fields if it is set and is string
// or message.
// Additionally, if any singular embedded messages have been allocated, we
@@ -442,8 +451,10 @@ DynamicMessage::~DynamicMessage() {
case FieldOptions::STRING: {
const ::std::string* default_value =
&(reinterpret_cast<const ArenaStringPtr*>(
- type_info_->prototype->OffsetToPointer(
- type_info_->offsets[i]))->Get(NULL));
+ reinterpret_cast<uint8*>(
+ type_info_->default_oneof_instance)
+ + type_info_->offsets[i])
+ ->Get(NULL));
reinterpret_cast<ArenaStringPtr*>(field_ptr)->Destroy(
default_value, NULL);
break;
@@ -704,7 +715,7 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock(
// Oneof fields do not use any space.
if (!type->field(i)->containing_oneof()) {
int field_size = FieldSpaceUsed(type->field(i));
- size = AlignTo(size, min(kSafeAlignment, field_size));
+ size = AlignTo(size, std::min(kSafeAlignment, field_size));
offsets[i] = size;
size += field_size;
}
@@ -748,7 +759,7 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock(
for (int j = 0; j < type->oneof_decl(i)->field_count(); j++) {
const FieldDescriptor* field = type->oneof_decl(i)->field(j);
int field_size = OneofFieldSpaceUsed(field);
- oneof_size = AlignTo(oneof_size, min(kSafeAlignment, field_size));
+ oneof_size = AlignTo(oneof_size, std::min(kSafeAlignment, field_size));
offsets[field->index()] = oneof_size;
oneof_size += field_size;
}
diff --git a/src/google/protobuf/dynamic_message_unittest.cc b/src/google/protobuf/dynamic_message_unittest.cc
index 70e437d7..fe51d8cf 100644
--- a/src/google/protobuf/dynamic_message_unittest.cc
+++ b/src/google/protobuf/dynamic_message_unittest.cc
@@ -45,8 +45,6 @@
#include <google/protobuf/stubs/shared_ptr.h>
#endif
-#include <google/protobuf/stubs/scoped_ptr.h>
-#include <google/protobuf/stubs/common.h>
#include <google/protobuf/dynamic_message.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/descriptor.pb.h>
@@ -55,6 +53,7 @@
#include <google/protobuf/unittest_no_field_presence.pb.h>
#include <google/protobuf/stubs/logging.h>
+#include <google/protobuf/stubs/common.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
diff --git a/src/google/protobuf/empty.pb.cc b/src/google/protobuf/empty.pb.cc
index 4a4f6eae..83775753 100644
--- a/src/google/protobuf/empty.pb.cc
+++ b/src/google/protobuf/empty.pb.cc
@@ -7,6 +7,7 @@
#include <algorithm>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/port.h>
#include <google/protobuf/stubs/once.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/wire_format_lite_inl.h>
@@ -28,6 +29,7 @@ const ::google::protobuf::internal::GeneratedMessageReflection*
} // namespace
+void protobuf_AssignDesc_google_2fprotobuf_2fempty_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AssignDesc_google_2fprotobuf_2fempty_2eproto() {
protobuf_AddDesc_google_2fprotobuf_2fempty_2eproto();
const ::google::protobuf::FileDescriptor* file =
@@ -58,6 +60,7 @@ inline void protobuf_AssignDescriptorsOnce() {
&protobuf_AssignDesc_google_2fprotobuf_2fempty_2eproto);
}
+void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
void protobuf_RegisterTypes(const ::std::string&) {
protobuf_AssignDescriptorsOnce();
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
@@ -71,6 +74,7 @@ void protobuf_ShutdownFile_google_2fprotobuf_2fempty_2eproto() {
delete Empty_reflection_;
}
+void protobuf_AddDesc_google_2fprotobuf_2fempty_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AddDesc_google_2fprotobuf_2fempty_2eproto() {
static bool already_here = false;
if (already_here) return;
@@ -79,9 +83,10 @@ void protobuf_AddDesc_google_2fprotobuf_2fempty_2eproto() {
::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
"\n\033google/protobuf/empty.proto\022\017google.pr"
- "otobuf\"\007\n\005EmptyBM\n\023com.google.protobufB\n"
- "EmptyProtoP\001\240\001\001\242\002\003GPB\252\002\036Google.Protobuf."
- "WellKnownTypesb\006proto3", 142);
+ "otobuf\"\007\n\005EmptyBy\n\023com.google.protobufB\n"
+ "EmptyProtoP\001Z\'github.com/golang/protobuf"
+ "/ptypes/empty\240\001\001\370\001\001\242\002\003GPB\252\002\036Google.Proto"
+ "buf.WellKnownTypesb\006proto3", 186);
::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
"google/protobuf/empty.proto", &protobuf_RegisterTypes);
Empty::default_instance_ = new Empty();
@@ -96,16 +101,6 @@ struct StaticDescriptorInitializer_google_2fprotobuf_2fempty_2eproto {
}
} static_descriptor_initializer_google_2fprotobuf_2fempty_2eproto_;
-namespace {
-
-static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD;
-static void MergeFromFail(int line) {
- GOOGLE_CHECK(false) << __FILE__ << ":" << line;
-}
-
-} // namespace
-
-
// ===================================================================
#if !defined(_MSC_VER) || _MSC_VER >= 1900
@@ -117,6 +112,14 @@ Empty::Empty()
// @@protoc_insertion_point(constructor:google.protobuf.Empty)
}
+Empty::Empty(::google::protobuf::Arena* arena)
+ : ::google::protobuf::Message(),
+ _internal_metadata_(arena) {
+ SharedCtor();
+ RegisterArenaDtor(arena);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.Empty)
+}
+
void Empty::InitAsDefaultInstance() {
_is_default_instance_ = true;
}
@@ -140,10 +143,20 @@ Empty::~Empty() {
}
void Empty::SharedDtor() {
+ if (GetArenaNoVirtual() != NULL) {
+ return;
+ }
+
if (this != default_instance_) {
}
}
+void Empty::ArenaDtor(void* object) {
+ Empty* _this = reinterpret_cast< Empty* >(object);
+ (void)_this;
+}
+void Empty::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+}
void Empty::SetCachedSize(int size) const {
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
_cached_size_ = size;
@@ -162,19 +175,16 @@ const Empty& Empty::default_instance() {
Empty* Empty::default_instance_ = NULL;
Empty* Empty::New(::google::protobuf::Arena* arena) const {
- Empty* n = new Empty;
- if (arena != NULL) {
- arena->Own(n);
- }
- return n;
+ return ::google::protobuf::Arena::CreateMessage<Empty>(arena);
}
void Empty::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.Empty)
}
bool Empty::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.Empty)
for (;;) {
@@ -204,14 +214,15 @@ void Empty::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.Empty)
}
-::google::protobuf::uint8* Empty::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* Empty::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Empty)
// @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Empty)
return target;
}
int Empty::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Empty)
int total_size = 0;
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
@@ -221,28 +232,38 @@ int Empty::ByteSize() const {
}
void Empty::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Empty)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const Empty* source =
::google::protobuf::internal::DynamicCastToGenerated<const Empty>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.Empty)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.Empty)
MergeFrom(*source);
}
}
void Empty::MergeFrom(const Empty& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Empty)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
}
void Empty::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.Empty)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void Empty::CopyFrom(const Empty& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Empty)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -255,6 +276,18 @@ bool Empty::IsInitialized() const {
void Empty::Swap(Empty* other) {
if (other == this) return;
+ if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
+ InternalSwap(other);
+ } else {
+ Empty temp;
+ temp.MergeFrom(*this);
+ CopyFrom(*other);
+ other->CopyFrom(temp);
+ }
+}
+void Empty::UnsafeArenaSwap(Empty* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
void Empty::InternalSwap(Empty* other) {
diff --git a/src/google/protobuf/empty.pb.h b/src/google/protobuf/empty.pb.h
index 20876bea..8e78733b 100644
--- a/src/google/protobuf/empty.pb.h
+++ b/src/google/protobuf/empty.pb.h
@@ -41,7 +41,7 @@ class Empty;
// ===================================================================
-class LIBPROTOBUF_EXPORT Empty : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT Empty : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Empty) */ {
public:
Empty();
virtual ~Empty();
@@ -53,9 +53,14 @@ class LIBPROTOBUF_EXPORT Empty : public ::google::protobuf::Message {
return *this;
}
+ inline ::google::protobuf::Arena* GetArena() const { return GetArenaNoVirtual(); }
+ inline void* GetMaybeArenaPointer() const {
+ return MaybeArenaPtr();
+ }
static const ::google::protobuf::Descriptor* descriptor();
static const Empty& default_instance();
+ void UnsafeArenaSwap(Empty* other);
void Swap(Empty* other);
// implements Message ----------------------------------------------
@@ -75,13 +80,22 @@ class LIBPROTOBUF_EXPORT Empty : public ::google::protobuf::Message {
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
void SharedDtor();
void SetCachedSize(int size) const;
void InternalSwap(Empty* other);
+ protected:
+ explicit Empty(::google::protobuf::Arena* arena);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::google::protobuf::Arena* arena);
private:
inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
return _internal_metadata_.arena();
@@ -101,6 +115,9 @@ class LIBPROTOBUF_EXPORT Empty : public ::google::protobuf::Message {
private:
::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+ friend class ::google::protobuf::Arena;
+ typedef void InternalArenaConstructable_;
+ typedef void DestructorSkippable_;
bool _is_default_instance_;
mutable int _cached_size_;
friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fempty_2eproto();
diff --git a/src/google/protobuf/empty.proto b/src/google/protobuf/empty.proto
index 9dddc6c5..37f4cd10 100644
--- a/src/google/protobuf/empty.proto
+++ b/src/google/protobuf/empty.proto
@@ -27,16 +27,19 @@
// 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.
+
syntax = "proto3";
package google.protobuf;
-option java_multiple_files = true;
-option java_outer_classname = "EmptyProto";
+option csharp_namespace = "Google.Protobuf.WellKnownTypes";
+option go_package = "github.com/golang/protobuf/ptypes/empty";
option java_package = "com.google.protobuf";
+option java_outer_classname = "EmptyProto";
+option java_multiple_files = true;
option java_generate_equals_and_hash = true;
-option csharp_namespace = "Google.Protobuf.WellKnownTypes";
option objc_class_prefix = "GPB";
+option cc_enable_arenas = true;
// A generic empty message that you can re-use to avoid defining duplicated
// empty messages in your APIs. A typical example is to use it as the request
diff --git a/src/google/protobuf/extension_set.cc b/src/google/protobuf/extension_set.cc
index 9afb2361..7d20a0f8 100644
--- a/src/google/protobuf/extension_set.cc
+++ b/src/google/protobuf/extension_set.cc
@@ -177,7 +177,8 @@ void ExtensionSet::RegisterMessageExtension(const MessageLite* containing_type,
// ===================================================================
// Constructors and basic methods.
-ExtensionSet::ExtensionSet(::google::protobuf::Arena* arena) : arena_(arena) {
+ExtensionSet::ExtensionSet(::google::protobuf::Arena* arena)
+ : arena_(arena) {
if (arena_ != NULL) {
arena_->OwnDestructor(&extensions_);
}
@@ -188,7 +189,7 @@ ExtensionSet::ExtensionSet() : arena_(NULL) {}
ExtensionSet::~ExtensionSet() {
// Deletes all allocated extensions.
if (arena_ == NULL) {
- for (map<int, Extension>::iterator iter = extensions_.begin();
+ for (ExtensionMap::iterator iter = extensions_.begin();
iter != extensions_.end(); ++iter) {
iter->second.Free();
}
@@ -201,7 +202,7 @@ ExtensionSet::~ExtensionSet() {
// vector<const FieldDescriptor*>* output) const
bool ExtensionSet::Has(int number) const {
- map<int, Extension>::const_iterator iter = extensions_.find(number);
+ ExtensionMap::const_iterator iter = extensions_.find(number);
if (iter == extensions_.end()) return false;
GOOGLE_DCHECK(!iter->second.is_repeated);
return !iter->second.is_cleared;
@@ -209,7 +210,7 @@ bool ExtensionSet::Has(int number) const {
int ExtensionSet::NumExtensions() const {
int result = 0;
- for (map<int, Extension>::const_iterator iter = extensions_.begin();
+ for (ExtensionMap::const_iterator iter = extensions_.begin();
iter != extensions_.end(); ++iter) {
if (!iter->second.is_cleared) {
++result;
@@ -219,13 +220,13 @@ int ExtensionSet::NumExtensions() const {
}
int ExtensionSet::ExtensionSize(int number) const {
- map<int, Extension>::const_iterator iter = extensions_.find(number);
+ ExtensionMap::const_iterator iter = extensions_.find(number);
if (iter == extensions_.end()) return false;
return iter->second.GetSize();
}
FieldType ExtensionSet::ExtensionType(int number) const {
- map<int, Extension>::const_iterator iter = extensions_.find(number);
+ ExtensionMap::const_iterator iter = extensions_.find(number);
if (iter == extensions_.end()) {
GOOGLE_LOG(DFATAL) << "Don't lookup extension types if they aren't present (1). ";
return 0;
@@ -237,7 +238,7 @@ FieldType ExtensionSet::ExtensionType(int number) const {
}
void ExtensionSet::ClearExtension(int number) {
- map<int, Extension>::iterator iter = extensions_.find(number);
+ ExtensionMap::iterator iter = extensions_.find(number);
if (iter == extensions_.end()) return;
iter->second.Clear();
}
@@ -265,7 +266,7 @@ enum Cardinality {
\
LOWERCASE ExtensionSet::Get##CAMELCASE(int number, \
LOWERCASE default_value) const { \
- map<int, Extension>::const_iterator iter = extensions_.find(number); \
+ ExtensionMap::const_iterator iter = extensions_.find(number); \
if (iter == extensions_.end() || iter->second.is_cleared) { \
return default_value; \
} else { \
@@ -290,7 +291,7 @@ void ExtensionSet::Set##CAMELCASE(int number, FieldType type, \
} \
\
LOWERCASE ExtensionSet::GetRepeated##CAMELCASE(int number, int index) const { \
- map<int, Extension>::const_iterator iter = extensions_.find(number); \
+ ExtensionMap::const_iterator iter = extensions_.find(number); \
GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; \
GOOGLE_DCHECK_TYPE(iter->second, REPEATED, UPPERCASE); \
return iter->second.repeated_##LOWERCASE##_value->Get(index); \
@@ -298,7 +299,7 @@ LOWERCASE ExtensionSet::GetRepeated##CAMELCASE(int number, int index) const { \
\
void ExtensionSet::SetRepeated##CAMELCASE( \
int number, int index, LOWERCASE value) { \
- map<int, Extension>::iterator iter = extensions_.find(number); \
+ ExtensionMap::iterator iter = extensions_.find(number); \
GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; \
GOOGLE_DCHECK_TYPE(iter->second, REPEATED, UPPERCASE); \
iter->second.repeated_##LOWERCASE##_value->Set(index, value); \
@@ -334,7 +335,7 @@ PRIMITIVE_ACCESSORS( BOOL, bool, Bool)
const void* ExtensionSet::GetRawRepeatedField(int number,
const void* default_value) const {
- map<int, Extension>::const_iterator iter = extensions_.find(number);
+ ExtensionMap::const_iterator iter = extensions_.find(number);
if (iter == extensions_.end()) {
return default_value;
}
@@ -408,7 +409,7 @@ void* ExtensionSet::MutableRawRepeatedField(int number, FieldType field_type,
// Compatible version using old call signature. Does not create extensions when
// the don't already exist; instead, just GOOGLE_CHECK-fails.
void* ExtensionSet::MutableRawRepeatedField(int number) {
- map<int, Extension>::iterator iter = extensions_.find(number);
+ ExtensionMap::iterator iter = extensions_.find(number);
GOOGLE_CHECK(iter == extensions_.end()) << "Extension not found.";
// We assume that all the RepeatedField<>* pointers have the same
// size and alignment within the anonymous union in Extension.
@@ -420,7 +421,7 @@ void* ExtensionSet::MutableRawRepeatedField(int number) {
// Enums
int ExtensionSet::GetEnum(int number, int default_value) const {
- map<int, Extension>::const_iterator iter = extensions_.find(number);
+ ExtensionMap::const_iterator iter = extensions_.find(number);
if (iter == extensions_.end() || iter->second.is_cleared) {
// Not present. Return the default value.
return default_value;
@@ -445,14 +446,14 @@ void ExtensionSet::SetEnum(int number, FieldType type, int value,
}
int ExtensionSet::GetRepeatedEnum(int number, int index) const {
- map<int, Extension>::const_iterator iter = extensions_.find(number);
+ ExtensionMap::const_iterator iter = extensions_.find(number);
GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
GOOGLE_DCHECK_TYPE(iter->second, REPEATED, ENUM);
return iter->second.repeated_enum_value->Get(index);
}
void ExtensionSet::SetRepeatedEnum(int number, int index, int value) {
- map<int, Extension>::iterator iter = extensions_.find(number);
+ ExtensionMap::iterator iter = extensions_.find(number);
GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
GOOGLE_DCHECK_TYPE(iter->second, REPEATED, ENUM);
iter->second.repeated_enum_value->Set(index, value);
@@ -481,7 +482,7 @@ void ExtensionSet::AddEnum(int number, FieldType type,
const string& ExtensionSet::GetString(int number,
const string& default_value) const {
- map<int, Extension>::const_iterator iter = extensions_.find(number);
+ ExtensionMap::const_iterator iter = extensions_.find(number);
if (iter == extensions_.end() || iter->second.is_cleared) {
// Not present. Return the default value.
return default_value;
@@ -507,14 +508,14 @@ string* ExtensionSet::MutableString(int number, FieldType type,
}
const string& ExtensionSet::GetRepeatedString(int number, int index) const {
- map<int, Extension>::const_iterator iter = extensions_.find(number);
+ ExtensionMap::const_iterator iter = extensions_.find(number);
GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
GOOGLE_DCHECK_TYPE(iter->second, REPEATED, STRING);
return iter->second.repeated_string_value->Get(index);
}
string* ExtensionSet::MutableRepeatedString(int number, int index) {
- map<int, Extension>::iterator iter = extensions_.find(number);
+ ExtensionMap::iterator iter = extensions_.find(number);
GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
GOOGLE_DCHECK_TYPE(iter->second, REPEATED, STRING);
return iter->second.repeated_string_value->Mutable(index);
@@ -541,7 +542,7 @@ string* ExtensionSet::AddString(int number, FieldType type,
const MessageLite& ExtensionSet::GetMessage(
int number, const MessageLite& default_value) const {
- map<int, Extension>::const_iterator iter = extensions_.find(number);
+ ExtensionMap::const_iterator iter = extensions_.find(number);
if (iter == extensions_.end()) {
// Not present. Return the default value.
return default_value;
@@ -664,7 +665,7 @@ void ExtensionSet::UnsafeArenaSetAllocatedMessage(
MessageLite* ExtensionSet::ReleaseMessage(int number,
const MessageLite& prototype) {
- map<int, Extension>::iterator iter = extensions_.find(number);
+ ExtensionMap::iterator iter = extensions_.find(number);
if (iter == extensions_.end()) {
// Not present. Return NULL.
return NULL;
@@ -693,7 +694,7 @@ MessageLite* ExtensionSet::ReleaseMessage(int number,
MessageLite* ExtensionSet::UnsafeArenaReleaseMessage(
int number, const MessageLite& prototype) {
- map<int, Extension>::iterator iter = extensions_.find(number);
+ ExtensionMap::iterator iter = extensions_.find(number);
if (iter == extensions_.end()) {
// Not present. Return NULL.
return NULL;
@@ -720,14 +721,14 @@ MessageLite* ExtensionSet::UnsafeArenaReleaseMessage(
const MessageLite& ExtensionSet::GetRepeatedMessage(
int number, int index) const {
- map<int, Extension>::const_iterator iter = extensions_.find(number);
+ ExtensionMap::const_iterator iter = extensions_.find(number);
GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
GOOGLE_DCHECK_TYPE(iter->second, REPEATED, MESSAGE);
return iter->second.repeated_message_value->Get(index);
}
MessageLite* ExtensionSet::MutableRepeatedMessage(int number, int index) {
- map<int, Extension>::iterator iter = extensions_.find(number);
+ ExtensionMap::iterator iter = extensions_.find(number);
GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
GOOGLE_DCHECK_TYPE(iter->second, REPEATED, MESSAGE);
return iter->second.repeated_message_value->Mutable(index);
@@ -766,7 +767,7 @@ MessageLite* ExtensionSet::AddMessage(int number, FieldType type,
#undef GOOGLE_DCHECK_TYPE
void ExtensionSet::RemoveLast(int number) {
- map<int, Extension>::iterator iter = extensions_.find(number);
+ ExtensionMap::iterator iter = extensions_.find(number);
GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
Extension* extension = &iter->second;
@@ -807,7 +808,7 @@ void ExtensionSet::RemoveLast(int number) {
}
MessageLite* ExtensionSet::ReleaseLast(int number) {
- map<int, Extension>::iterator iter = extensions_.find(number);
+ ExtensionMap::iterator iter = extensions_.find(number);
GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
Extension* extension = &iter->second;
@@ -817,7 +818,7 @@ MessageLite* ExtensionSet::ReleaseLast(int number) {
}
void ExtensionSet::SwapElements(int number, int index1, int index2) {
- map<int, Extension>::iterator iter = extensions_.find(number);
+ ExtensionMap::iterator iter = extensions_.find(number);
GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
Extension* extension = &iter->second;
@@ -860,14 +861,14 @@ void ExtensionSet::SwapElements(int number, int index1, int index2) {
// ===================================================================
void ExtensionSet::Clear() {
- for (map<int, Extension>::iterator iter = extensions_.begin();
+ for (ExtensionMap::iterator iter = extensions_.begin();
iter != extensions_.end(); ++iter) {
iter->second.Clear();
}
}
void ExtensionSet::MergeFrom(const ExtensionSet& other) {
- for (map<int, Extension>::const_iterator iter = other.extensions_.begin();
+ for (ExtensionMap::const_iterator iter = other.extensions_.begin();
iter != other.extensions_.end(); ++iter) {
const Extension& other_extension = iter->second;
InternalExtensionMergeFrom(iter->first, other_extension);
@@ -1031,8 +1032,8 @@ void ExtensionSet::Swap(ExtensionSet* x) {
void ExtensionSet::SwapExtension(ExtensionSet* other,
int number) {
if (this == other) return;
- map<int, Extension>::iterator this_iter = extensions_.find(number);
- map<int, Extension>::iterator other_iter = other->extensions_.find(number);
+ ExtensionMap::iterator this_iter = extensions_.find(number);
+ ExtensionMap::iterator other_iter = other->extensions_.find(number);
if (this_iter == extensions_.end() &&
other_iter == other->extensions_.end()) {
@@ -1052,7 +1053,7 @@ void ExtensionSet::SwapExtension(ExtensionSet* other,
// implemented in ExtensionSet's MergeFrom.
ExtensionSet temp;
temp.InternalExtensionMergeFrom(number, other_iter->second);
- map<int, Extension>::iterator temp_iter = temp.extensions_.find(number);
+ ExtensionMap::iterator temp_iter = temp.extensions_.find(number);
other_iter->second.Clear();
other->InternalExtensionMergeFrom(number, this_iter->second);
this_iter->second.Clear();
@@ -1085,7 +1086,7 @@ void ExtensionSet::SwapExtension(ExtensionSet* other,
bool ExtensionSet::IsInitialized() const {
// Extensions are never required. However, we need to check that all
// embedded messages are initialized.
- for (map<int, Extension>::const_iterator iter = extensions_.begin();
+ for (ExtensionMap::const_iterator iter = extensions_.begin();
iter != extensions_.end(); ++iter) {
const Extension& extension = iter->second;
if (cpp_type(extension.type) == WireFormatLite::CPPTYPE_MESSAGE) {
@@ -1345,7 +1346,7 @@ bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
void ExtensionSet::SerializeWithCachedSizes(
int start_field_number, int end_field_number,
io::CodedOutputStream* output) const {
- map<int, Extension>::const_iterator iter;
+ ExtensionMap::const_iterator iter;
for (iter = extensions_.lower_bound(start_field_number);
iter != extensions_.end() && iter->first < end_field_number;
++iter) {
@@ -1356,7 +1357,7 @@ void ExtensionSet::SerializeWithCachedSizes(
int ExtensionSet::ByteSize() const {
int total_size = 0;
- for (map<int, Extension>::const_iterator iter = extensions_.begin();
+ for (ExtensionMap::const_iterator iter = extensions_.begin();
iter != extensions_.end(); ++iter) {
total_size += iter->second.ByteSize(iter->first);
}
@@ -1370,7 +1371,7 @@ int ExtensionSet::ByteSize() const {
bool ExtensionSet::MaybeNewExtension(int number,
const FieldDescriptor* descriptor,
Extension** result) {
- pair<map<int, Extension>::iterator, bool> insert_result =
+ pair<ExtensionMap::iterator, bool> insert_result =
extensions_.insert(std::make_pair(number, Extension()));
*result = &insert_result.first->second;
(*result)->descriptor = descriptor;
diff --git a/src/google/protobuf/extension_set.h b/src/google/protobuf/extension_set.h
index bca179be..3e1d1ef5 100644
--- a/src/google/protobuf/extension_set.h
+++ b/src/google/protobuf/extension_set.h
@@ -273,6 +273,8 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
MessageLite* ReleaseMessage(const FieldDescriptor* descriptor,
MessageFactory* factory);
+ MessageLite* UnsafeArenaReleaseMessage(const FieldDescriptor* descriptor,
+ MessageFactory* factory);
#undef desc
::google::protobuf::Arena* GetArenaNoVirtual() const { return arena_; }
@@ -403,12 +405,21 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
// serialized extensions.
//
// Returns a pointer past the last written byte.
- uint8* SerializeWithCachedSizesToArray(int start_field_number,
- int end_field_number,
- uint8* target) const;
+ uint8* InternalSerializeWithCachedSizesToArray(int start_field_number,
+ int end_field_number,
+ bool deterministic,
+ uint8* target) const;
// Like above but serializes in MessageSet format.
void SerializeMessageSetWithCachedSizes(io::CodedOutputStream* output) const;
+ uint8* InternalSerializeMessageSetWithCachedSizesToArray(bool deterministic,
+ uint8* target) const;
+
+ // For backward-compatibility, versions of two of the above methods that
+ // are never forced to serialize deterministically.
+ uint8* SerializeWithCachedSizesToArray(int start_field_number,
+ int end_field_number,
+ uint8* target) const;
uint8* SerializeMessageSetWithCachedSizesToArray(uint8* target) const;
// Returns the total serialized size of all the extensions.
@@ -456,6 +467,13 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
virtual void WriteMessage(int number,
io::CodedOutputStream* output) const = 0;
virtual uint8* WriteMessageToArray(int number, uint8* target) const = 0;
+ virtual uint8* InternalWriteMessageToArray(int number, bool,
+ uint8* target) const {
+ // TODO(gpike): make this pure virtual. This is a placeholder because we
+ // need to update third_party/upb, for example.
+ return WriteMessageToArray(number, target);
+ }
+
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(LazyMessageExtension);
};
@@ -522,14 +540,16 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
void SerializeFieldWithCachedSizes(
int number,
io::CodedOutputStream* output) const;
- uint8* SerializeFieldWithCachedSizesToArray(
+ uint8* InternalSerializeFieldWithCachedSizesToArray(
int number,
+ bool deterministic,
uint8* target) const;
void SerializeMessageSetItemWithCachedSizes(
int number,
io::CodedOutputStream* output) const;
- uint8* SerializeMessageSetItemWithCachedSizesToArray(
+ uint8* InternalSerializeMessageSetItemWithCachedSizesToArray(
int number,
+ bool deterministic,
uint8* target) const;
int ByteSize(int number) const;
int MessageSetItemByteSize(int number) const;
@@ -538,6 +558,7 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
void Free();
int SpaceUsedExcludingSelf() const;
};
+ typedef std::map<int, Extension> ExtensionMap;
// Merges existing Extension from other_extension
@@ -608,7 +629,7 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
// only contain a small number of extensions whereas hash_map is optimized
// for 100 elements or more. Also, we want AppendToList() to order fields
// by field number.
- std::map<int, Extension> extensions_;
+ ExtensionMap extensions_;
::google::protobuf::Arena* arena_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionSet);
};
@@ -980,11 +1001,22 @@ class MessageTypeTraits {
MutableType message, ExtensionSet* set) {
set->SetAllocatedMessage(number, field_type, NULL, message);
}
+ static inline void UnsafeArenaSetAllocated(int number, FieldType field_type,
+ MutableType message,
+ ExtensionSet* set) {
+ set->UnsafeArenaSetAllocatedMessage(number, field_type, NULL, message);
+ }
static inline MutableType Release(int number, FieldType /* field_type */,
ExtensionSet* set) {
return static_cast<Type*>(set->ReleaseMessage(
number, Type::default_instance()));
}
+ static inline MutableType UnsafeArenaRelease(int number,
+ FieldType /* field_type */,
+ ExtensionSet* set) {
+ return static_cast<Type*>(set->UnsafeArenaReleaseMessage(
+ number, Type::default_instance()));
+ }
};
// forward declaration
@@ -1178,12 +1210,32 @@ class ExtensionIdentifier {
template <typename _proto_TypeTraits, \
::google::protobuf::internal::FieldType _field_type, \
bool _is_packed> \
+ inline void UnsafeArenaSetAllocatedExtension( \
+ const ::google::protobuf::internal::ExtensionIdentifier< \
+ CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id, \
+ typename _proto_TypeTraits::Singular::MutableType value) { \
+ _proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type, \
+ value, &_extensions_); \
+ } \
+ template <typename _proto_TypeTraits, \
+ ::google::protobuf::internal::FieldType _field_type, \
+ bool _is_packed> \
inline typename _proto_TypeTraits::Singular::MutableType ReleaseExtension( \
const ::google::protobuf::internal::ExtensionIdentifier< \
CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) { \
return _proto_TypeTraits::Release(id.number(), _field_type, \
&_extensions_); \
} \
+ template <typename _proto_TypeTraits, \
+ ::google::protobuf::internal::FieldType _field_type, \
+ bool _is_packed> \
+ inline typename _proto_TypeTraits::Singular::MutableType \
+ UnsafeArenaReleaseExtension( \
+ const ::google::protobuf::internal::ExtensionIdentifier< \
+ CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) { \
+ return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type, \
+ &_extensions_); \
+ } \
\
/* Repeated accessors */ \
template <typename _proto_TypeTraits, \
diff --git a/src/google/protobuf/extension_set_heavy.cc b/src/google/protobuf/extension_set_heavy.cc
index 82e3e099..b26a246c 100644
--- a/src/google/protobuf/extension_set_heavy.cc
+++ b/src/google/protobuf/extension_set_heavy.cc
@@ -95,7 +95,7 @@ void ExtensionSet::AppendToList(
const Descriptor* containing_type,
const DescriptorPool* pool,
std::vector<const FieldDescriptor*>* output) const {
- for (map<int, Extension>::const_iterator iter = extensions_.begin();
+ for (ExtensionMap::const_iterator iter = extensions_.begin();
iter != extensions_.end(); ++iter) {
bool has = false;
if (iter->second.is_repeated) {
@@ -144,7 +144,7 @@ inline WireFormatLite::FieldType field_type(FieldType type) {
const MessageLite& ExtensionSet::GetMessage(int number,
const Descriptor* message_type,
MessageFactory* factory) const {
- map<int, Extension>::const_iterator iter = extensions_.find(number);
+ ExtensionMap::const_iterator iter = extensions_.find(number);
if (iter == extensions_.end() || iter->second.is_cleared) {
// Not present. Return the default value.
return *factory->GetPrototype(message_type);
@@ -187,7 +187,7 @@ MessageLite* ExtensionSet::MutableMessage(const FieldDescriptor* descriptor,
MessageLite* ExtensionSet::ReleaseMessage(const FieldDescriptor* descriptor,
MessageFactory* factory) {
- map<int, Extension>::iterator iter = extensions_.find(descriptor->number());
+ ExtensionMap::iterator iter = extensions_.find(descriptor->number());
if (iter == extensions_.end()) {
// Not present. Return NULL.
return NULL;
@@ -213,6 +213,29 @@ MessageLite* ExtensionSet::ReleaseMessage(const FieldDescriptor* descriptor,
}
}
+MessageLite* ExtensionSet::UnsafeArenaReleaseMessage(
+ const FieldDescriptor* descriptor, MessageFactory* factory) {
+ ExtensionMap::iterator iter = extensions_.find(descriptor->number());
+ if (iter == extensions_.end()) {
+ // Not present. Return NULL.
+ return NULL;
+ } else {
+ GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
+ MessageLite* ret = NULL;
+ if (iter->second.is_lazy) {
+ ret = iter->second.lazymessage_value->UnsafeArenaReleaseMessage(
+ *factory->GetPrototype(descriptor->message_type()));
+ if (arena_ == NULL) {
+ delete iter->second.lazymessage_value;
+ }
+ } else {
+ ret = iter->second.message_value;
+ }
+ extensions_.erase(descriptor->number());
+ return ret;
+ }
+}
+
ExtensionSet::Extension* ExtensionSet::MaybeNewRepeatedExtension(const FieldDescriptor* descriptor) {
Extension* extension;
if (MaybeNewExtension(descriptor->number(), descriptor, &extension)) {
@@ -318,8 +341,8 @@ bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
int ExtensionSet::SpaceUsedExcludingSelf() const {
int total_size =
- extensions_.size() * sizeof(map<int, Extension>::value_type);
- for (map<int, Extension>::const_iterator iter = extensions_.begin(),
+ extensions_.size() * sizeof(ExtensionMap::value_type);
+ for (ExtensionMap::const_iterator iter = extensions_.begin(),
end = extensions_.end();
iter != end;
++iter) {
@@ -386,31 +409,43 @@ int ExtensionSet::Extension::SpaceUsedExcludingSelf() const {
// The Serialize*ToArray methods are only needed in the heavy library, as
// the lite library only generates SerializeWithCachedSizes.
-uint8* ExtensionSet::SerializeWithCachedSizesToArray(
- int start_field_number, int end_field_number,
+uint8* ExtensionSet::SerializeWithCachedSizesToArray(int start_field_number,
+ int end_field_number,
+ uint8* target) const {
+ return InternalSerializeWithCachedSizesToArray(
+ start_field_number, end_field_number, false, target);
+}
+
+uint8* ExtensionSet::SerializeMessageSetWithCachedSizesToArray(
uint8* target) const {
- map<int, Extension>::const_iterator iter;
+ return InternalSerializeMessageSetWithCachedSizesToArray(false, target);
+}
+
+uint8* ExtensionSet::InternalSerializeWithCachedSizesToArray(
+ int start_field_number, int end_field_number,
+ bool deterministic, uint8* target) const {
+ ExtensionMap::const_iterator iter;
for (iter = extensions_.lower_bound(start_field_number);
iter != extensions_.end() && iter->first < end_field_number;
++iter) {
- target = iter->second.SerializeFieldWithCachedSizesToArray(iter->first,
- target);
+ target = iter->second.InternalSerializeFieldWithCachedSizesToArray(
+ iter->first, deterministic, target);
}
return target;
}
-uint8* ExtensionSet::SerializeMessageSetWithCachedSizesToArray(
- uint8* target) const {
- map<int, Extension>::const_iterator iter;
+uint8* ExtensionSet::InternalSerializeMessageSetWithCachedSizesToArray(
+ bool deterministic, uint8* target) const {
+ ExtensionMap::const_iterator iter;
for (iter = extensions_.begin(); iter != extensions_.end(); ++iter) {
- target = iter->second.SerializeMessageSetItemWithCachedSizesToArray(
- iter->first, target);
+ target = iter->second.InternalSerializeMessageSetItemWithCachedSizesToArray(
+ iter->first, deterministic, target);
}
return target;
}
-uint8* ExtensionSet::Extension::SerializeFieldWithCachedSizesToArray(
- int number, uint8* target) const {
+uint8* ExtensionSet::Extension::InternalSerializeFieldWithCachedSizesToArray(
+ int number, bool deterministic, uint8* target) const {
if (is_repeated) {
if (is_packed) {
if (cached_size == 0) return target;
@@ -477,6 +512,16 @@ uint8* ExtensionSet::Extension::SerializeFieldWithCachedSizesToArray(
HANDLE_TYPE( STRING, String, string);
HANDLE_TYPE( BYTES, Bytes, string);
HANDLE_TYPE( ENUM, Enum, enum);
+#undef HANDLE_TYPE
+#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
+ case FieldDescriptor::TYPE_##UPPERCASE: \
+ for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
+ target = WireFormatLite::InternalWrite##CAMELCASE##ToArray( \
+ number, repeated_##LOWERCASE##_value->Get(i), \
+ deterministic, target); \
+ } \
+ break
+
HANDLE_TYPE( GROUP, Group, message);
HANDLE_TYPE( MESSAGE, Message, message);
#undef HANDLE_TYPE
@@ -510,10 +555,11 @@ uint8* ExtensionSet::Extension::SerializeFieldWithCachedSizesToArray(
#undef HANDLE_TYPE
case FieldDescriptor::TYPE_MESSAGE:
if (is_lazy) {
- target = lazymessage_value->WriteMessageToArray(number, target);
+ target = lazymessage_value->InternalWriteMessageToArray(
+ number, deterministic, target);
} else {
- target = WireFormatLite::WriteMessageToArray(
- number, *message_value, target);
+ target = WireFormatLite::InternalWriteMessageToArray(
+ number, *message_value, deterministic, target);
}
break;
}
@@ -521,13 +567,14 @@ uint8* ExtensionSet::Extension::SerializeFieldWithCachedSizesToArray(
return target;
}
-uint8* ExtensionSet::Extension::SerializeMessageSetItemWithCachedSizesToArray(
- int number,
- uint8* target) const {
+uint8*
+ExtensionSet::Extension::InternalSerializeMessageSetItemWithCachedSizesToArray(
+ int number, bool deterministic, uint8* target) const {
if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
// Not a valid MessageSet extension, but serialize it the normal way.
GOOGLE_LOG(WARNING) << "Invalid message set extension.";
- return SerializeFieldWithCachedSizesToArray(number, target);
+ return InternalSerializeFieldWithCachedSizesToArray(number, deterministic,
+ target);
}
if (is_cleared) return target;
@@ -732,7 +779,7 @@ int ExtensionSet::Extension::MessageSetItemByteSize(int number) const {
void ExtensionSet::SerializeMessageSetWithCachedSizes(
io::CodedOutputStream* output) const {
- for (map<int, Extension>::const_iterator iter = extensions_.begin();
+ for (ExtensionMap::const_iterator iter = extensions_.begin();
iter != extensions_.end(); ++iter) {
iter->second.SerializeMessageSetItemWithCachedSizes(iter->first, output);
}
@@ -741,7 +788,7 @@ void ExtensionSet::SerializeMessageSetWithCachedSizes(
int ExtensionSet::MessageSetByteSize() const {
int total_size = 0;
- for (map<int, Extension>::const_iterator iter = extensions_.begin();
+ for (ExtensionMap::const_iterator iter = extensions_.begin();
iter != extensions_.end(); ++iter) {
total_size += iter->second.MessageSetItemByteSize(iter->first);
}
diff --git a/src/google/protobuf/extension_set_unittest.cc b/src/google/protobuf/extension_set_unittest.cc
index f40fcbc2..688afedb 100644
--- a/src/google/protobuf/extension_set_unittest.cc
+++ b/src/google/protobuf/extension_set_unittest.cc
@@ -205,6 +205,74 @@ TEST(ExtensionSetTest, ReleaseExtension) {
delete released_extension;
}
+TEST(ExtensionSetTest, ArenaUnsafeArenaSetAllocatedAndRelease) {
+ ::google::protobuf::Arena arena;
+ unittest::TestAllExtensions* message =
+ ::google::protobuf::Arena::CreateMessage<unittest::TestAllExtensions>(&arena);
+ unittest::ForeignMessage extension;
+ message->UnsafeArenaSetAllocatedExtension(
+ unittest::optional_foreign_message_extension,
+ &extension);
+ // No copy when set.
+ unittest::ForeignMessage* mutable_extension =
+ message->MutableExtension(unittest::optional_foreign_message_extension);
+ EXPECT_EQ(&extension, mutable_extension);
+ // No copy when unsafe released.
+ unittest::ForeignMessage* released_extension =
+ message->UnsafeArenaReleaseExtension(
+ unittest::optional_foreign_message_extension);
+ EXPECT_EQ(&extension, released_extension);
+ EXPECT_FALSE(message->HasExtension(
+ unittest::optional_foreign_message_extension));
+ // Set the ownership back and let the destructors run. It should not take
+ // ownership, so this should not crash.
+ message->UnsafeArenaSetAllocatedExtension(
+ unittest::optional_foreign_message_extension,
+ &extension);
+}
+
+TEST(ExtensionSetTest, UnsafeArenaSetAllocatedAndRelease) {
+ unittest::TestAllExtensions message;
+ unittest::ForeignMessage* extension = new unittest::ForeignMessage();
+ message.UnsafeArenaSetAllocatedExtension(
+ unittest::optional_foreign_message_extension,
+ extension);
+ // No copy when set.
+ unittest::ForeignMessage* mutable_extension =
+ message.MutableExtension(unittest::optional_foreign_message_extension);
+ EXPECT_EQ(extension, mutable_extension);
+ // No copy when unsafe released.
+ unittest::ForeignMessage* released_extension =
+ message.UnsafeArenaReleaseExtension(
+ unittest::optional_foreign_message_extension);
+ EXPECT_EQ(extension, released_extension);
+ EXPECT_FALSE(message.HasExtension(
+ unittest::optional_foreign_message_extension));
+ // Set the ownership back and let the destructors run. It should take
+ // ownership, so this should not leak.
+ message.UnsafeArenaSetAllocatedExtension(
+ unittest::optional_foreign_message_extension,
+ extension);
+}
+
+TEST(ExtensionSetTest, ArenaUnsafeArenaReleaseOfHeapAlloc) {
+ ::google::protobuf::Arena arena;
+ unittest::TestAllExtensions* message =
+ ::google::protobuf::Arena::CreateMessage<unittest::TestAllExtensions>(&arena);
+ unittest::ForeignMessage* extension = new unittest::ForeignMessage;
+ message->SetAllocatedExtension(
+ unittest::optional_foreign_message_extension,
+ extension);
+ // The arena should maintain ownership of the heap allocated proto because we
+ // used UnsafeArenaReleaseExtension. The leak checker will ensure this.
+ unittest::ForeignMessage* released_extension =
+ message->UnsafeArenaReleaseExtension(
+ unittest::optional_foreign_message_extension);
+ EXPECT_EQ(extension, released_extension);
+ EXPECT_FALSE(message->HasExtension(
+ unittest::optional_foreign_message_extension));
+}
+
TEST(ExtensionSetTest, CopyFrom) {
unittest::TestAllExtensions message1, message2;
diff --git a/src/google/protobuf/field_mask.pb.cc b/src/google/protobuf/field_mask.pb.cc
index f834363b..ed05fe57 100644
--- a/src/google/protobuf/field_mask.pb.cc
+++ b/src/google/protobuf/field_mask.pb.cc
@@ -7,6 +7,7 @@
#include <algorithm>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/port.h>
#include <google/protobuf/stubs/once.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/wire_format_lite_inl.h>
@@ -28,6 +29,7 @@ const ::google::protobuf::internal::GeneratedMessageReflection*
} // namespace
+void protobuf_AssignDesc_google_2fprotobuf_2ffield_5fmask_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AssignDesc_google_2fprotobuf_2ffield_5fmask_2eproto() {
protobuf_AddDesc_google_2fprotobuf_2ffield_5fmask_2eproto();
const ::google::protobuf::FileDescriptor* file =
@@ -59,6 +61,7 @@ inline void protobuf_AssignDescriptorsOnce() {
&protobuf_AssignDesc_google_2fprotobuf_2ffield_5fmask_2eproto);
}
+void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
void protobuf_RegisterTypes(const ::std::string&) {
protobuf_AssignDescriptorsOnce();
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
@@ -72,6 +75,7 @@ void protobuf_ShutdownFile_google_2fprotobuf_2ffield_5fmask_2eproto() {
delete FieldMask_reflection_;
}
+void protobuf_AddDesc_google_2fprotobuf_2ffield_5fmask_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AddDesc_google_2fprotobuf_2ffield_5fmask_2eproto() {
static bool already_here = false;
if (already_here) return;
@@ -98,16 +102,6 @@ struct StaticDescriptorInitializer_google_2fprotobuf_2ffield_5fmask_2eproto {
}
} static_descriptor_initializer_google_2fprotobuf_2ffield_5fmask_2eproto_;
-namespace {
-
-static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD;
-static void MergeFromFail(int line) {
- GOOGLE_CHECK(false) << __FILE__ << ":" << line;
-}
-
-} // namespace
-
-
// ===================================================================
#if !defined(_MSC_VER) || _MSC_VER >= 1900
@@ -174,12 +168,13 @@ FieldMask* FieldMask::New(::google::protobuf::Arena* arena) const {
}
void FieldMask::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.FieldMask)
paths_.Clear();
}
bool FieldMask::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.FieldMask)
for (;;) {
@@ -243,8 +238,8 @@ void FieldMask::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.FieldMask)
}
-::google::protobuf::uint8* FieldMask::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* FieldMask::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FieldMask)
// repeated string paths = 1;
for (int i = 0; i < this->paths_size(); i++) {
@@ -261,6 +256,7 @@ void FieldMask::SerializeWithCachedSizes(
}
int FieldMask::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.FieldMask)
int total_size = 0;
// repeated string paths = 1;
@@ -277,29 +273,39 @@ int FieldMask::ByteSize() const {
}
void FieldMask::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.FieldMask)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const FieldMask* source =
::google::protobuf::internal::DynamicCastToGenerated<const FieldMask>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.FieldMask)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.FieldMask)
MergeFrom(*source);
}
}
void FieldMask::MergeFrom(const FieldMask& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FieldMask)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
paths_.MergeFrom(from.paths_);
}
void FieldMask::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.FieldMask)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void FieldMask::CopyFrom(const FieldMask& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.FieldMask)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -360,6 +366,7 @@ void FieldMask::clear_paths() {
// @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldMask.paths)
}
::std::string* FieldMask::add_paths() {
+ // @@protoc_insertion_point(field_add_mutable:google.protobuf.FieldMask.paths)
return paths_.Add();
}
void FieldMask::add_paths(const ::std::string& value) {
diff --git a/src/google/protobuf/field_mask.pb.h b/src/google/protobuf/field_mask.pb.h
index 7189fd79..7a19c4aa 100644
--- a/src/google/protobuf/field_mask.pb.h
+++ b/src/google/protobuf/field_mask.pb.h
@@ -41,7 +41,7 @@ class FieldMask;
// ===================================================================
-class LIBPROTOBUF_EXPORT FieldMask : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT FieldMask : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FieldMask) */ {
public:
FieldMask();
virtual ~FieldMask();
@@ -75,7 +75,11 @@ class LIBPROTOBUF_EXPORT FieldMask : public ::google::protobuf::Message {
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
@@ -164,6 +168,7 @@ inline void FieldMask::set_paths(int index, const char* value, size_t size) {
// @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldMask.paths)
}
inline ::std::string* FieldMask::add_paths() {
+ // @@protoc_insertion_point(field_add_mutable:google.protobuf.FieldMask.paths)
return paths_.Add();
}
inline void FieldMask::add_paths(const ::std::string& value) {
diff --git a/src/google/protobuf/field_mask.proto b/src/google/protobuf/field_mask.proto
index 8b21c692..c51de09a 100644
--- a/src/google/protobuf/field_mask.proto
+++ b/src/google/protobuf/field_mask.proto
@@ -27,16 +27,17 @@
// 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.
+
syntax = "proto3";
package google.protobuf;
-option java_generate_equals_and_hash = true;
-option java_multiple_files = true;
-option java_outer_classname = "FieldMaskProto";
-option java_package = "com.google.protobuf";
option csharp_namespace = "Google.Protobuf.WellKnownTypes";
+option java_package = "com.google.protobuf";
+option java_outer_classname = "FieldMaskProto";
+option java_multiple_files = true;
option objc_class_prefix = "GPB";
+option java_generate_equals_and_hash = true;
// `FieldMask` represents a set of symbolic field paths, for example:
//
@@ -69,7 +70,7 @@ option objc_class_prefix = "GPB";
// z: 8
//
// The result will not contain specific values for fields x,y and z
-// (there value will be set to the default, and omitted in proto text
+// (their value will be set to the default, and omitted in proto text
// output):
//
//
@@ -87,7 +88,7 @@ option objc_class_prefix = "GPB";
// operation applies to all fields (as if a FieldMask of all fields
// had been specified).
//
-// Note that a field mask does not necessarily applies to the
+// Note that a field mask does not necessarily apply to the
// top-level response message. In case of a REST get operation, the
// field mask applies directly to the response, but in case of a REST
// list operation, the mask instead applies to each individual message
@@ -106,6 +107,58 @@ option objc_class_prefix = "GPB";
// describe the updated values, the API ignores the values of all
// fields not covered by the mask.
//
+// If a repeated field is specified for an update operation, the existing
+// repeated values in the target resource will be overwritten by the new values.
+// Note that a repeated field is only allowed in the last position of a field
+// mask.
+//
+// If a sub-message is specified in the last position of the field mask for an
+// update operation, then the existing sub-message in the target resource is
+// overwritten. Given the target message:
+//
+// f {
+// b {
+// d : 1
+// x : 2
+// }
+// c : 1
+// }
+//
+// And an update message:
+//
+// f {
+// b {
+// d : 10
+// }
+// }
+//
+// then if the field mask is:
+//
+// paths: "f.b"
+//
+// then the result will be:
+//
+// f {
+// b {
+// d : 10
+// }
+// c : 1
+// }
+//
+// However, if the update mask was:
+//
+// paths: "f.b.d"
+//
+// then the result would be:
+//
+// f {
+// b {
+// d : 10
+// x : 2
+// }
+// c : 1
+// }
+//
// In order to reset a field's value to the default, the field must
// be in the mask and set to the default value in the provided resource.
// Hence, in order to reset all fields of a resource, provide a default
@@ -161,6 +214,32 @@ option objc_class_prefix = "GPB";
// mask: "user.displayName,photo"
// }
//
+// # Field Masks and Oneof Fields
+//
+// Field masks treat fields in oneofs just as regular fields. Consider the
+// following message:
+//
+// message SampleMessage {
+// oneof test_oneof {
+// string name = 4;
+// SubMessage sub_message = 9;
+// }
+// }
+//
+// The field mask can be:
+//
+// mask {
+// paths: "name"
+// }
+//
+// Or:
+//
+// mask {
+// paths: "sub_message"
+// }
+//
+// Note that oneof type names ("test_oneof" in this case) cannot be used in
+// paths.
message FieldMask {
// The set of field mask paths.
repeated string paths = 1;
diff --git a/src/google/protobuf/generated_message_reflection.cc b/src/google/protobuf/generated_message_reflection.cc
index eee024ee..d1f7b5ca 100644
--- a/src/google/protobuf/generated_message_reflection.cc
+++ b/src/google/protobuf/generated_message_reflection.cc
@@ -412,6 +412,15 @@ void GeneratedMessageReflection::SwapField(
#undef SWAP_ARRAYS
case FieldDescriptor::CPPTYPE_STRING:
+ switch (field->options().ctype()) {
+ default: // TODO(kenton): Support other string reps.
+ case FieldOptions::STRING:
+ MutableRaw<RepeatedPtrFieldBase>(message1, field)->
+ Swap<GenericTypeHandler<string> >(
+ MutableRaw<RepeatedPtrFieldBase>(message2, field));
+ break;
+ }
+ break;
case FieldDescriptor::CPPTYPE_MESSAGE:
if (IsMapFieldInApi(field)) {
MutableRaw<MapFieldBase>(message1, field)->
@@ -447,16 +456,50 @@ void GeneratedMessageReflection::SwapField(
SWAP_VALUES(ENUM , int );
#undef SWAP_VALUES
case FieldDescriptor::CPPTYPE_MESSAGE:
- std::swap(*MutableRaw<Message*>(message1, field),
- *MutableRaw<Message*>(message2, field));
+ if (GetArena(message1) == GetArena(message2)) {
+ std::swap(*MutableRaw<Message*>(message1, field),
+ *MutableRaw<Message*>(message2, field));
+ } else {
+ Message** sub_msg1 = MutableRaw<Message*>(message1, field);
+ Message** sub_msg2 = MutableRaw<Message*>(message2, field);
+ if (*sub_msg1 == NULL && *sub_msg2 == NULL) break;
+ if (*sub_msg1 && *sub_msg2) {
+ (*sub_msg1)->GetReflection()->Swap(*sub_msg1, *sub_msg2);
+ break;
+ }
+ if (*sub_msg1 == NULL) {
+ *sub_msg1 = (*sub_msg2)->New(message1->GetArena());
+ (*sub_msg1)->CopyFrom(**sub_msg2);
+ ClearField(message2, field);
+ } else {
+ *sub_msg2 = (*sub_msg1)->New(message2->GetArena());
+ (*sub_msg2)->CopyFrom(**sub_msg1);
+ ClearField(message1, field);
+ }
+ }
break;
case FieldDescriptor::CPPTYPE_STRING:
switch (field->options().ctype()) {
default: // TODO(kenton): Support other string reps.
case FieldOptions::STRING:
- MutableRaw<ArenaStringPtr>(message1, field)->Swap(
- MutableRaw<ArenaStringPtr>(message2, field));
+ {
+ Arena* arena1 = GetArena(message1);
+ Arena* arena2 = GetArena(message2);
+ ArenaStringPtr* string1 =
+ MutableRaw<ArenaStringPtr>(message1, field);
+ ArenaStringPtr* string2 =
+ MutableRaw<ArenaStringPtr>(message2, field);
+ if (arena1 == arena2) {
+ string1->Swap(string2);
+ } else {
+ const string* default_ptr =
+ &DefaultRaw<ArenaStringPtr>(field).Get(NULL);
+ const string temp = string1->Get(default_ptr);
+ string1->Set(default_ptr, string2->Get(default_ptr), arena1);
+ string2->Set(default_ptr, temp, arena2);
+ }
+ }
break;
}
break;
@@ -1536,7 +1579,8 @@ Message* GeneratedMessageReflection::UnsafeArenaReleaseMessage(
if (field->is_extension()) {
return static_cast<Message*>(
- MutableExtensionSet(message)->ReleaseMessage(field, factory));
+ MutableExtensionSet(message)->UnsafeArenaReleaseMessage(field,
+ factory));
} else {
ClearBit(message, field);
if (field->containing_oneof()) {
@@ -1752,7 +1796,8 @@ bool GeneratedMessageReflection::InsertOrLookupMapValue(
"InsertOrLookupMapValue",
"Field is not a map field.");
val->SetType(field->message_type()->FindFieldByName("value")->cpp_type());
- return MutableRaw<MapFieldBase>(message, field)->InsertMapValue(key, val);
+ return MutableRaw<MapFieldBase>(message, field)->InsertOrLookupMapValue(
+ key, val);
}
bool GeneratedMessageReflection::DeleteMapValue(
@@ -2081,7 +2126,7 @@ inline void GeneratedMessageReflection::ClearOneofField(
inline void GeneratedMessageReflection::ClearOneof(
Message* message, const OneofDescriptor* oneof_descriptor) const {
// TODO(jieluo): Consider to cache the unused object instead of deleting
- // it. It will be much faster if an aplication switches a lot from
+ // it. It will be much faster if an application switches a lot from
// a few oneof fields. Time/space tradeoff
uint32 oneof_case = GetOneofCase(*message, oneof_descriptor);
if (oneof_case > 0) {
diff --git a/src/google/protobuf/generated_message_reflection.h b/src/google/protobuf/generated_message_reflection.h
index 9ef78710..15fc802c 100644
--- a/src/google/protobuf/generated_message_reflection.h
+++ b/src/google/protobuf/generated_message_reflection.h
@@ -582,7 +582,16 @@ class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Reflection {
// which the offsets of the direct fields of a class are non-constant.
// Fields inherited from superclasses *can* have non-constant offsets,
// but that's not what this macro will be used for.
-//
+#if defined(__clang__)
+// For Clang we use __builtin_offsetof() and suppress the warning,
+// to avoid Control Flow Integrity and UBSan vptr sanitizers from
+// crashing while trying to validate the invalid reinterpet_casts.
+#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TYPE, FIELD) \
+ _Pragma("clang diagnostic push") \
+ _Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"") \
+ __builtin_offsetof(TYPE, FIELD) \
+ _Pragma("clang diagnostic pop")
+#else
// Note that we calculate relative to the pointer value 16 here since if we
// just use zero, GCC complains about dereferencing a NULL pointer. We
// choose 16 rather than some other number just in case the compiler would
@@ -592,6 +601,7 @@ class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Reflection {
reinterpret_cast<const char*>( \
&reinterpret_cast<const TYPE*>(16)->FIELD) - \
reinterpret_cast<const char*>(16))
+#endif
#define PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(ONEOF, FIELD) \
static_cast<int>( \
diff --git a/src/google/protobuf/generated_message_reflection_unittest.cc b/src/google/protobuf/generated_message_reflection_unittest.cc
index 85ebdef1..6276b667 100644
--- a/src/google/protobuf/generated_message_reflection_unittest.cc
+++ b/src/google/protobuf/generated_message_reflection_unittest.cc
@@ -795,6 +795,73 @@ TEST(GeneratedMessageReflectionTest, ReleaseOneofMessageTest) {
EXPECT_TRUE(released == NULL);
}
+TEST(GeneratedMessageReflectionTest, ArenaReleaseMessageTest) {
+ ::google::protobuf::Arena arena;
+ unittest::TestAllTypes* message =
+ ::google::protobuf::Arena::CreateMessage<unittest::TestAllTypes>(&arena);
+ TestUtil::ReflectionTester reflection_tester(
+ unittest::TestAllTypes::descriptor());
+
+ // When nothing is set, we expect all released messages to be NULL.
+ reflection_tester.ExpectMessagesReleasedViaReflection(
+ message, TestUtil::ReflectionTester::IS_NULL);
+
+ // After fields are set we should get non-NULL releases.
+ reflection_tester.SetAllFieldsViaReflection(message);
+ reflection_tester.ExpectMessagesReleasedViaReflection(
+ message, TestUtil::ReflectionTester::NOT_NULL);
+
+ // After Clear() we may or may not get a message from ReleaseMessage().
+ // This is implementation specific.
+ reflection_tester.SetAllFieldsViaReflection(message);
+ message->Clear();
+ reflection_tester.ExpectMessagesReleasedViaReflection(
+ message, TestUtil::ReflectionTester::CAN_BE_NULL);
+}
+
+TEST(GeneratedMessageReflectionTest, ArenaReleaseExtensionMessageTest) {
+ ::google::protobuf::Arena arena;
+ unittest::TestAllExtensions* message =
+ ::google::protobuf::Arena::CreateMessage<unittest::TestAllExtensions>(&arena);
+ TestUtil::ReflectionTester reflection_tester(
+ unittest::TestAllExtensions::descriptor());
+
+ // When nothing is set, we expect all released messages to be NULL.
+ reflection_tester.ExpectMessagesReleasedViaReflection(
+ message, TestUtil::ReflectionTester::IS_NULL);
+
+ // After fields are set we should get non-NULL releases.
+ reflection_tester.SetAllFieldsViaReflection(message);
+ reflection_tester.ExpectMessagesReleasedViaReflection(
+ message, TestUtil::ReflectionTester::NOT_NULL);
+
+ // After Clear() we may or may not get a message from ReleaseMessage().
+ // This is implementation specific.
+ reflection_tester.SetAllFieldsViaReflection(message);
+ message->Clear();
+ reflection_tester.ExpectMessagesReleasedViaReflection(
+ message, TestUtil::ReflectionTester::CAN_BE_NULL);
+}
+
+TEST(GeneratedMessageReflectionTest, ArenaReleaseOneofMessageTest) {
+ ::google::protobuf::Arena arena;
+ unittest::TestOneof2* message =
+ ::google::protobuf::Arena::CreateMessage<unittest::TestOneof2>(&arena);
+ TestUtil::ReflectionTester::SetOneofViaReflection(message);
+
+ const Descriptor* descriptor = unittest::TestOneof2::descriptor();
+ const Reflection* reflection = message->GetReflection();
+ Message* released = reflection->ReleaseMessage(
+ message, descriptor->FindFieldByName("foo_lazy_message"));
+
+ EXPECT_TRUE(released != NULL);
+ delete released;
+
+ released = reflection->ReleaseMessage(
+ message, descriptor->FindFieldByName("foo_lazy_message"));
+ EXPECT_TRUE(released == NULL);
+}
+
#ifdef PROTOBUF_HAS_DEATH_TEST
TEST(GeneratedMessageReflectionTest, UsageErrors) {
diff --git a/src/google/protobuf/generated_message_util.cc b/src/google/protobuf/generated_message_util.cc
index 7b813f8a..7ad6d61c 100644
--- a/src/google/protobuf/generated_message_util.cc
+++ b/src/google/protobuf/generated_message_util.cc
@@ -73,6 +73,12 @@ int StringSpaceUsedExcludingSelf(const string& str) {
+void MergeFromFail(const char* file, int line) {
+ GOOGLE_CHECK(false) << file << ":" << line;
+ // Open-source GOOGLE_CHECK(false) is not NORETURN.
+ exit(1);
+}
+
} // namespace internal
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/generated_message_util.h b/src/google/protobuf/generated_message_util.h
index 78c8d7ff..8967726e 100644
--- a/src/google/protobuf/generated_message_util.h
+++ b/src/google/protobuf/generated_message_util.h
@@ -41,9 +41,9 @@
#include <assert.h>
#include <string>
+#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/once.h>
-#include <google/protobuf/stubs/common.h>
namespace google {
namespace protobuf {
@@ -63,6 +63,8 @@ namespace internal {
#undef DEPRECATED_PROTOBUF_FIELD
#define PROTOBUF_DEPRECATED
+#define GOOGLE_PROTOBUF_DEPRECATED_ATTR
+
// Constants for special floating point values.
LIBPROTOBUF_EXPORT double Infinity();
@@ -110,8 +112,13 @@ class ArenaString;
// pointer to a copy of the string that resides in *arena. Requires both
// args to be non-NULL. If something goes wrong while reading the data
// then NULL is returned (e.g., input does not start with a valid varint).
-ArenaString* ReadArenaString(::google::protobuf::io::CodedInputStream* input,
- ::google::protobuf::Arena* arena);
+LIBPROTOBUF_EXPORT ArenaString* ReadArenaString(
+ ::google::protobuf::io::CodedInputStream* input,
+ ::google::protobuf::Arena* arena);
+
+// Helper function to crash on merge failure.
+// Moved out of generated code to reduce binary size.
+LIBPROTOBUF_EXPORT void MergeFromFail(const char* file, int line) GOOGLE_ATTRIBUTE_NORETURN;
} // namespace internal
} // namespace protobuf
diff --git a/src/google/protobuf/io/coded_stream.cc b/src/google/protobuf/io/coded_stream.cc
index 4bcd354f..a5675e79 100644
--- a/src/google/protobuf/io/coded_stream.cc
+++ b/src/google/protobuf/io/coded_stream.cc
@@ -105,7 +105,7 @@ void CodedInputStream::BackUpInputToCurrentPosition() {
inline void CodedInputStream::RecomputeBufferLimits() {
buffer_end_ += buffer_size_after_limit_;
- int closest_limit = min(current_limit_, total_bytes_limit_);
+ int closest_limit = std::min(current_limit_, total_bytes_limit_);
if (closest_limit < total_bytes_read_) {
// The limit position is in the current buffer. We must adjust
// the buffer size accordingly.
@@ -135,7 +135,7 @@ CodedInputStream::Limit CodedInputStream::PushLimit(int byte_limit) {
// We need to enforce all limits, not just the new one, so if the previous
// limit was before the new requested limit, we continue to enforce the
// previous limit.
- current_limit_ = min(current_limit_, old_limit);
+ current_limit_ = std::min(current_limit_, old_limit);
RecomputeBufferLimits();
return old_limit;
@@ -188,7 +188,7 @@ void CodedInputStream::SetTotalBytesLimit(
// Make sure the limit isn't already past, since this could confuse other
// code.
int current_position = CurrentPosition();
- total_bytes_limit_ = max(current_position, total_bytes_limit);
+ total_bytes_limit_ = std::max(current_position, total_bytes_limit);
if (warning_threshold >= 0) {
total_bytes_warning_threshold_ = warning_threshold;
} else {
@@ -233,7 +233,7 @@ bool CodedInputStream::Skip(int count) {
buffer_end_ = buffer_;
// Make sure this skip doesn't try to skip past the current limit.
- int closest_limit = min(current_limit_, total_bytes_limit_);
+ int closest_limit = std::min(current_limit_, total_bytes_limit_);
int bytes_until_limit = closest_limit - total_bytes_read_;
if (bytes_until_limit < count) {
// We hit the limit. Skip up to it then fail.
@@ -270,7 +270,7 @@ bool CodedInputStream::ReadStringFallback(string* buffer, int size) {
buffer->clear();
}
- int closest_limit = min(current_limit_, total_bytes_limit_);
+ int closest_limit = std::min(current_limit_, total_bytes_limit_);
if (closest_limit != INT_MAX) {
int bytes_to_limit = closest_limit - CurrentPosition();
if (bytes_to_limit > 0 && size > 0 && size <= bytes_to_limit) {
@@ -376,6 +376,49 @@ inline ::std::pair<bool, const uint8*> ReadVarint32FromArray(
return std::make_pair(true, ptr);
}
+GOOGLE_ATTRIBUTE_ALWAYS_INLINE::std::pair<bool, const uint8*> ReadVarint64FromArray(
+ const uint8* buffer, uint64* value);
+inline ::std::pair<bool, const uint8*> ReadVarint64FromArray(
+ const uint8* buffer, uint64* value) {
+ const uint8* ptr = buffer;
+ uint32 b;
+
+ // Splitting into 32-bit pieces gives better performance on 32-bit
+ // processors.
+ uint32 part0 = 0, part1 = 0, part2 = 0;
+
+ b = *(ptr++); part0 = b ; if (!(b & 0x80)) goto done;
+ part0 -= 0x80;
+ b = *(ptr++); part0 += b << 7; if (!(b & 0x80)) goto done;
+ part0 -= 0x80 << 7;
+ b = *(ptr++); part0 += b << 14; if (!(b & 0x80)) goto done;
+ part0 -= 0x80 << 14;
+ b = *(ptr++); part0 += b << 21; if (!(b & 0x80)) goto done;
+ part0 -= 0x80 << 21;
+ b = *(ptr++); part1 = b ; if (!(b & 0x80)) goto done;
+ part1 -= 0x80;
+ b = *(ptr++); part1 += b << 7; if (!(b & 0x80)) goto done;
+ part1 -= 0x80 << 7;
+ b = *(ptr++); part1 += b << 14; if (!(b & 0x80)) goto done;
+ part1 -= 0x80 << 14;
+ b = *(ptr++); part1 += b << 21; if (!(b & 0x80)) goto done;
+ part1 -= 0x80 << 21;
+ b = *(ptr++); part2 = b ; if (!(b & 0x80)) goto done;
+ part2 -= 0x80;
+ b = *(ptr++); part2 += b << 7; if (!(b & 0x80)) goto done;
+ // "part2 -= 0x80 << 7" is irrelevant because (0x80 << 7) << 56 is 0.
+
+ // We have overrun the maximum size of a varint (10 bytes). Assume
+ // the data is corrupt.
+ return std::make_pair(false, ptr);
+
+ done:
+ *value = (static_cast<uint64>(part0)) |
+ (static_cast<uint64>(part1) << 28) |
+ (static_cast<uint64>(part2) << 56);
+ return std::make_pair(true, ptr);
+}
+
} // namespace
bool CodedInputStream::ReadVarint32Slow(uint32* value) {
@@ -408,6 +451,32 @@ int64 CodedInputStream::ReadVarint32Fallback(uint32 first_byte_or_zero) {
}
}
+int CodedInputStream::ReadVarintSizeAsIntSlow() {
+ // Directly invoke ReadVarint64Fallback, since we already tried to optimize
+ // for one-byte varints.
+ std::pair<uint64, bool> p = ReadVarint64Fallback();
+ if (!p.second || p.first > static_cast<uint64>(INT_MAX)) return -1;
+ return p.first;
+}
+
+int CodedInputStream::ReadVarintSizeAsIntFallback() {
+ if (BufferSize() >= kMaxVarintBytes ||
+ // Optimization: We're also safe if the buffer is non-empty and it ends
+ // with a byte that would terminate a varint.
+ (buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) {
+ uint64 temp;
+ ::std::pair<bool, const uint8*> p = ReadVarint64FromArray(buffer_, &temp);
+ if (!p.first || temp > static_cast<uint64>(INT_MAX)) return -1;
+ buffer_ = p.second;
+ return temp;
+ } else {
+ // Really slow case: we will incur the cost of an extra function call here,
+ // but moving this out of line reduces the size of this function, which
+ // improves the common case. In micro benchmarks, this is worth about 10-15%
+ return ReadVarintSizeAsIntSlow();
+ }
+}
+
uint32 CodedInputStream::ReadTagSlow() {
if (buffer_ == buffer_end_) {
// Call refresh.
@@ -499,47 +568,13 @@ std::pair<uint64, bool> CodedInputStream::ReadVarint64Fallback() {
// Optimization: We're also safe if the buffer is non-empty and it ends
// with a byte that would terminate a varint.
(buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) {
- // Fast path: We have enough bytes left in the buffer to guarantee that
- // this read won't cross the end, so we can skip the checks.
-
- const uint8* ptr = buffer_;
- uint32 b;
-
- // Splitting into 32-bit pieces gives better performance on 32-bit
- // processors.
- uint32 part0 = 0, part1 = 0, part2 = 0;
-
- b = *(ptr++); part0 = b ; if (!(b & 0x80)) goto done;
- part0 -= 0x80;
- b = *(ptr++); part0 += b << 7; if (!(b & 0x80)) goto done;
- part0 -= 0x80 << 7;
- b = *(ptr++); part0 += b << 14; if (!(b & 0x80)) goto done;
- part0 -= 0x80 << 14;
- b = *(ptr++); part0 += b << 21; if (!(b & 0x80)) goto done;
- part0 -= 0x80 << 21;
- b = *(ptr++); part1 = b ; if (!(b & 0x80)) goto done;
- part1 -= 0x80;
- b = *(ptr++); part1 += b << 7; if (!(b & 0x80)) goto done;
- part1 -= 0x80 << 7;
- b = *(ptr++); part1 += b << 14; if (!(b & 0x80)) goto done;
- part1 -= 0x80 << 14;
- b = *(ptr++); part1 += b << 21; if (!(b & 0x80)) goto done;
- part1 -= 0x80 << 21;
- b = *(ptr++); part2 = b ; if (!(b & 0x80)) goto done;
- part2 -= 0x80;
- b = *(ptr++); part2 += b << 7; if (!(b & 0x80)) goto done;
- // "part2 -= 0x80 << 7" is irrelevant because (0x80 << 7) << 56 is 0.
-
- // We have overrun the maximum size of a varint (10 bytes). The data
- // must be corrupt.
- return std::make_pair(0, false);
-
- done:
- Advance(ptr - buffer_);
- return std::make_pair((static_cast<uint64>(part0)) |
- (static_cast<uint64>(part1) << 28) |
- (static_cast<uint64>(part2) << 56),
- true);
+ uint64 temp;
+ ::std::pair<bool, const uint8*> p = ReadVarint64FromArray(buffer_, &temp);
+ if (!p.first) {
+ return std::make_pair(0, false);
+ }
+ buffer_ = p.second;
+ return std::make_pair(temp, true);
} else {
uint64 temp;
bool success = ReadVarint64Slow(&temp);
@@ -614,13 +649,16 @@ bool CodedInputStream::Refresh() {
// CodedOutputStream =================================================
+bool CodedOutputStream::default_serialization_deterministic_ = false;
+
CodedOutputStream::CodedOutputStream(ZeroCopyOutputStream* output)
: output_(output),
buffer_(NULL),
buffer_size_(0),
total_bytes_(0),
had_error_(false),
- aliasing_enabled_(false) {
+ aliasing_enabled_(false),
+ serialization_deterministic_is_overridden_(false) {
// Eagerly Refresh() so buffer space is immediately available.
Refresh();
// The Refresh() may have failed. If the client doesn't write any data,
@@ -629,6 +667,25 @@ CodedOutputStream::CodedOutputStream(ZeroCopyOutputStream* output)
had_error_ = false;
}
+CodedOutputStream::CodedOutputStream(ZeroCopyOutputStream* output,
+ bool do_eager_refresh)
+ : output_(output),
+ buffer_(NULL),
+ buffer_size_(0),
+ total_bytes_(0),
+ had_error_(false),
+ aliasing_enabled_(false),
+ serialization_deterministic_is_overridden_(false) {
+ if (do_eager_refresh) {
+ // Eagerly Refresh() so buffer space is immediately available.
+ Refresh();
+ // The Refresh() may have failed. If the client doesn't write any data,
+ // though, don't consider this an error. If the client does write data, then
+ // another Refresh() will be attempted and it will set the error once again.
+ had_error_ = false;
+ }
+}
+
CodedOutputStream::~CodedOutputStream() {
Trim();
}
diff --git a/src/google/protobuf/io/coded_stream.h b/src/google/protobuf/io/coded_stream.h
index cb1869a7..316da765 100644
--- a/src/google/protobuf/io/coded_stream.h
+++ b/src/google/protobuf/io/coded_stream.h
@@ -109,6 +109,7 @@
#ifndef GOOGLE_PROTOBUF_IO_CODED_STREAM_H__
#define GOOGLE_PROTOBUF_IO_CODED_STREAM_H__
+#include <assert.h>
#include <string>
#include <utility>
#ifdef _MSC_VER
@@ -116,7 +117,7 @@
#if !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST)
#define PROTOBUF_LITTLE_ENDIAN 1
#endif
- #if _MSC_VER >= 1300
+ #if _MSC_VER >= 1300 && !defined(__INTEL_COMPILER)
// If MSVC has "/RTCc" set, it will complain about truncating casts at
// runtime. This file contains some intentional truncating casts.
#pragma runtime_checks("c", off)
@@ -236,6 +237,17 @@ class LIBPROTOBUF_EXPORT CodedInputStream {
// Read an unsigned integer with Varint encoding.
bool ReadVarint64(uint64* value);
+ // Reads a varint off the wire into an "int". This should be used for reading
+ // sizes off the wire (sizes of strings, submessages, bytes fields, etc).
+ //
+ // The value from the wire is interpreted as unsigned. If its value exceeds
+ // the representable value of an integer on this platform, instead of
+ // truncating we return false. Truncating (as performed by ReadVarint32()
+ // above) is an acceptable approach for fields representing an integer, but
+ // when we are parsing a size from the wire, truncating the value would result
+ // in us misparsing the payload.
+ bool ReadVarintSizeAsInt(int* value);
+
// Read a tag. This calls ReadVarint32() and returns the result, or returns
// zero (which is not a valid tag) if ReadVarint32() fails. Also, it updates
// the last tag value, which can be checked with LastTagWas().
@@ -593,9 +605,11 @@ class LIBPROTOBUF_EXPORT CodedInputStream {
// if it fails and the uint32 it read otherwise. The latter has a bool
// indicating success or failure as part of its return type.
int64 ReadVarint32Fallback(uint32 first_byte_or_zero);
+ int ReadVarintSizeAsIntFallback();
std::pair<uint64, bool> ReadVarint64Fallback();
bool ReadVarint32Slow(uint32* value);
bool ReadVarint64Slow(uint64* value);
+ int ReadVarintSizeAsIntSlow();
bool ReadLittleEndian32Fallback(uint32* value);
bool ReadLittleEndian64Fallback(uint64* value);
// Fallback/slow methods for reading tags. These do not update last_tag_,
@@ -665,6 +679,7 @@ class LIBPROTOBUF_EXPORT CodedOutputStream {
public:
// Create an CodedOutputStream that writes to the given ZeroCopyOutputStream.
explicit CodedOutputStream(ZeroCopyOutputStream* output);
+ CodedOutputStream(ZeroCopyOutputStream* output, bool do_eager_refresh);
// Destroy the CodedOutputStream and position the underlying
// ZeroCopyOutputStream immediately after the last byte written.
@@ -798,6 +813,44 @@ class LIBPROTOBUF_EXPORT CodedOutputStream {
// created.
bool HadError() const { return had_error_; }
+ // Deterministic serialization, if requested, guarantees that for a given
+ // binary, equal messages will always be serialized to the same bytes. This
+ // implies:
+ // . repeated serialization of a message will return the same bytes
+ // . different processes of the same binary (which may be executing on
+ // different machines) will serialize equal messages to the same bytes.
+ //
+ // Note the deterministic serialization is NOT canonical across languages; it
+ // is also unstable across different builds with schema changes due to unknown
+ // fields. Users who need canonical serialization, e.g., persistent storage in
+ // a canonical form, fingerprinting, etc., should define their own
+ // canonicalization specification and implement the serializer using
+ // reflection APIs rather than relying on this API.
+ //
+ // If determinisitc serialization is requested, the serializer will
+ // sort map entries by keys in lexicographical order or numerical order.
+ // (This is an implementation detail and may subject to change.)
+ //
+ // There are two ways to determine whether serialization should be
+ // deterministic for this CodedOutputStream. If SetSerializationDeterministic
+ // has not yet been called, then the default comes from the global default,
+ // which is false, until SetDefaultSerializationDeterministic has been called.
+ // Otherwise, SetSerializationDeterministic has been called, and the last
+ // value passed to it is all that matters.
+ void SetSerializationDeterministic(bool value) {
+ serialization_deterministic_is_overridden_ = true;
+ serialization_deterministic_override_ = value;
+ }
+ // See above. Also, note that users of this CodedOutputStream may need to
+ // call IsSerializationDeterminstic() to serialize in the intended way. This
+ // CodedOutputStream cannot enforce a desire for deterministic serialization
+ // by itself.
+ bool IsSerializationDeterminstic() const {
+ return serialization_deterministic_is_overridden_ ?
+ serialization_deterministic_override_ :
+ default_serialization_deterministic_;
+ }
+
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CodedOutputStream);
@@ -807,6 +860,10 @@ class LIBPROTOBUF_EXPORT CodedOutputStream {
int total_bytes_; // Sum of sizes of all buffers seen so far.
bool had_error_; // Whether an error occurred during output.
bool aliasing_enabled_; // See EnableAliasing().
+ // See SetSerializationDeterministic() regarding these three fields.
+ bool serialization_deterministic_is_overridden_;
+ bool serialization_deterministic_override_;
+ static bool default_serialization_deterministic_;
// Advance the buffer by a given number of bytes.
void Advance(int amount);
@@ -834,6 +891,11 @@ class LIBPROTOBUF_EXPORT CodedOutputStream {
uint64 value, uint8* target);
static int VarintSize32Fallback(uint32 value);
+
+ // See above. Other projects may use "friend" to allow them to call this.
+ static void SetDefaultSerializationDeterministic() {
+ default_serialization_deterministic_ = true;
+ }
};
// inline methods ====================================================
@@ -866,6 +928,19 @@ inline bool CodedInputStream::ReadVarint64(uint64* value) {
return p.second;
}
+inline bool CodedInputStream::ReadVarintSizeAsInt(int* value) {
+ if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_)) {
+ int v = *buffer_;
+ if (v < 0x80) {
+ *value = v;
+ Advance(1);
+ return true;
+ }
+ }
+ *value = ReadVarintSizeAsIntFallback();
+ return *value >= 0;
+}
+
// static
inline const uint8* CodedInputStream::ReadLittleEndian32FromArray(
const uint8* buffer,
@@ -1134,7 +1209,7 @@ inline void CodedOutputStream::WriteVarint32(uint32 value) {
// this write won't cross the end, so we can skip the checks.
uint8* target = buffer_;
uint8* end = WriteVarint32ToArray(value, target);
- int size = end - target;
+ int size = static_cast<int>(end - target);
Advance(size);
} else {
WriteVarint32SlowPath(value);
@@ -1284,9 +1359,9 @@ inline bool CodedInputStream::IsFlat() const {
} // namespace protobuf
-#if defined(_MSC_VER) && _MSC_VER >= 1300
+#if _MSC_VER >= 1300 && !defined(__INTEL_COMPILER)
#pragma runtime_checks("c", restore)
-#endif // _MSC_VER
+#endif // _MSC_VER && !defined(__INTEL_COMPILER)
} // namespace google
#endif // GOOGLE_PROTOBUF_IO_CODED_STREAM_H__
diff --git a/src/google/protobuf/io/coded_stream_unittest.cc b/src/google/protobuf/io/coded_stream_unittest.cc
index d1782e39..a8108e45 100644
--- a/src/google/protobuf/io/coded_stream_unittest.cc
+++ b/src/google/protobuf/io/coded_stream_unittest.cc
@@ -46,7 +46,7 @@
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/logging.h>
-#include <google/protobuf/stubs/scoped_ptr.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
diff --git a/src/google/protobuf/io/gzip_stream.cc b/src/google/protobuf/io/gzip_stream.cc
index 1be6c863..9c621b6a 100644
--- a/src/google/protobuf/io/gzip_stream.cc
+++ b/src/google/protobuf/io/gzip_stream.cc
@@ -241,9 +241,7 @@ void GzipOutputStream::Init(ZeroCopyOutputStream* sub_stream,
GzipOutputStream::~GzipOutputStream() {
Close();
- if (input_buffer_ != NULL) {
- operator delete(input_buffer_);
- }
+ operator delete(input_buffer_);
}
// private
diff --git a/src/google/protobuf/io/gzip_stream.h b/src/google/protobuf/io/gzip_stream.h
index 82445000..15b02fe3 100644
--- a/src/google/protobuf/io/gzip_stream.h
+++ b/src/google/protobuf/io/gzip_stream.h
@@ -43,10 +43,9 @@
#ifndef GOOGLE_PROTOBUF_IO_GZIP_STREAM_H__
#define GOOGLE_PROTOBUF_IO_GZIP_STREAM_H__
-#include <zlib.h>
-
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/io/zero_copy_stream.h>
+#include <zlib.h>
namespace google {
namespace protobuf {
diff --git a/src/google/protobuf/io/printer.cc b/src/google/protobuf/io/printer.cc
index 7d886506..7532b098 100644
--- a/src/google/protobuf/io/printer.cc
+++ b/src/google/protobuf/io/printer.cc
@@ -42,13 +42,25 @@ namespace protobuf {
namespace io {
Printer::Printer(ZeroCopyOutputStream* output, char variable_delimiter)
- : variable_delimiter_(variable_delimiter),
- output_(output),
- buffer_(NULL),
- buffer_size_(0),
- at_start_of_line_(true),
- failed_(false) {
-}
+ : variable_delimiter_(variable_delimiter),
+ output_(output),
+ buffer_(NULL),
+ buffer_size_(0),
+ offset_(0),
+ at_start_of_line_(true),
+ failed_(false),
+ annotation_collector_(NULL) {}
+
+Printer::Printer(ZeroCopyOutputStream* output, char variable_delimiter,
+ AnnotationCollector* annotation_collector)
+ : variable_delimiter_(variable_delimiter),
+ output_(output),
+ buffer_(NULL),
+ buffer_size_(0),
+ offset_(0),
+ at_start_of_line_(true),
+ failed_(false),
+ annotation_collector_(annotation_collector) {}
Printer::~Printer() {
// Only BackUp() if we have called Next() at least once and never failed.
@@ -57,9 +69,47 @@ Printer::~Printer() {
}
}
+bool Printer::GetSubstitutionRange(const char* varname,
+ pair<size_t, size_t>* range) {
+ map<string, pair<size_t, size_t> >::const_iterator iter =
+ substitutions_.find(varname);
+ if (iter == substitutions_.end()) {
+ GOOGLE_LOG(DFATAL) << " Undefined variable in annotation: " << varname;
+ return false;
+ }
+ if (iter->second.first > iter->second.second) {
+ GOOGLE_LOG(DFATAL) << " Variable used for annotation used multiple times: "
+ << varname;
+ return false;
+ }
+ *range = iter->second;
+ return true;
+}
+
+void Printer::Annotate(const char* begin_varname, const char* end_varname,
+ const string& file_path, const vector<int>& path) {
+ if (annotation_collector_ == NULL) {
+ // Can't generate signatures with this Printer.
+ return;
+ }
+ pair<size_t, size_t> begin, end;
+ if (!GetSubstitutionRange(begin_varname, &begin) ||
+ !GetSubstitutionRange(end_varname, &end)) {
+ return;
+ }
+ if (begin.first > end.second) {
+ GOOGLE_LOG(DFATAL) << " Annotation has negative length from " << begin_varname
+ << " to " << end_varname;
+ } else {
+ annotation_collector_->AddAnnotation(begin.first, end.second, file_path,
+ path);
+ }
+}
+
void Printer::Print(const map<string, string>& variables, const char* text) {
int size = strlen(text);
int pos = 0; // The number of bytes we've written so far.
+ substitutions_.clear();
for (int i = 0; i < size; i++) {
if (text[i] == '\n') {
@@ -97,7 +147,17 @@ void Printer::Print(const map<string, string>& variables, const char* text) {
if (iter == variables.end()) {
GOOGLE_LOG(DFATAL) << " Undefined variable: " << varname;
} else {
+ size_t begin = offset_;
WriteRaw(iter->second.data(), iter->second.size());
+ pair<map<string, pair<size_t, size_t> >::iterator, bool> inserted =
+ substitutions_.insert(
+ std::make_pair(varname, std::make_pair(begin, offset_)));
+ if (!inserted.second) {
+ // This variable was used multiple times. Make its span have
+ // negative length so we can detect it if it gets used in an
+ // annotation.
+ inserted.first->second = std::make_pair(1, 0);
+ }
}
}
@@ -265,6 +325,7 @@ void Printer::WriteRaw(const char* data, int size) {
// Data exceeds space in the buffer. Copy what we can and request a
// new buffer.
memcpy(buffer_, data, buffer_size_);
+ offset_ += buffer_size_;
data += buffer_size_;
size -= buffer_size_;
void* void_buffer;
@@ -277,6 +338,7 @@ void Printer::WriteRaw(const char* data, int size) {
memcpy(buffer_, data, size);
buffer_ += size;
buffer_size_ -= size;
+ offset_ += size;
}
} // namespace io
diff --git a/src/google/protobuf/io/printer.h b/src/google/protobuf/io/printer.h
index f1490bbe..e78e2efd 100644
--- a/src/google/protobuf/io/printer.h
+++ b/src/google/protobuf/io/printer.h
@@ -39,6 +39,7 @@
#include <string>
#include <map>
+#include <vector>
#include <google/protobuf/stubs/common.h>
namespace google {
@@ -47,6 +48,47 @@ namespace io {
class ZeroCopyOutputStream; // zero_copy_stream.h
+// Records annotations about a Printer's output.
+class LIBPROTOBUF_EXPORT AnnotationCollector {
+ public:
+ // Records that the bytes in file_path beginning with begin_offset and ending
+ // before end_offset are associated with the SourceCodeInfo-style path.
+ virtual void AddAnnotation(size_t begin_offset, size_t end_offset,
+ const string& file_path,
+ const vector<int>& path) = 0;
+
+ virtual ~AnnotationCollector() {}
+};
+
+// Records annotations about a Printer's output to the given protocol buffer,
+// assuming that the buffer has an ::Annotation message exposing path,
+// source_file, begin and end fields.
+template <typename AnnotationProto>
+class AnnotationProtoCollector : public AnnotationCollector {
+ public:
+ // annotation_proto is the protocol buffer to which new Annotations should be
+ // added. It is not owned by the AnnotationProtoCollector.
+ explicit AnnotationProtoCollector(AnnotationProto* annotation_proto)
+ : annotation_proto_(annotation_proto) {}
+
+ // Override for AnnotationCollector::AddAnnotation.
+ virtual void AddAnnotation(size_t begin_offset, size_t end_offset,
+ const string& file_path, const vector<int>& path) {
+ typename AnnotationProto::Annotation* annotation =
+ annotation_proto_->add_annotation();
+ for (int i = 0; i < path.size(); ++i) {
+ annotation->add_path(path[i]);
+ }
+ annotation->set_source_file(file_path);
+ annotation->set_begin(begin_offset);
+ annotation->set_end(end_offset);
+ }
+
+ private:
+ // The protocol buffer to which new annotations should be added.
+ AnnotationProto* const annotation_proto_;
+};
+
// This simple utility class assists in code generation. It basically
// allows the caller to define a set of variables and then output some
// text with variable substitutions. Example usage:
@@ -61,13 +103,123 @@ class ZeroCopyOutputStream; // zero_copy_stream.h
// Printer aggressively enforces correct usage, crashing (with assert failures)
// in the case of undefined variables in debug builds. This helps greatly in
// debugging code which uses it.
+//
+// If a Printer is constructed with an AnnotationCollector, it will provide it
+// with annotations that connect the Printer's output to paths that can identify
+// various descriptors. In the above example, if person_ is a descriptor that
+// identifies Bob, we can associate the output string "My name is Bob." with
+// a source path pointing to that descriptor with:
+//
+// printer.Annotate("name", person_);
+//
+// The AnnotationCollector will be sent an annotation linking the output range
+// covering "Bob" to the logical path provided by person_. Tools may use
+// this association to (for example) link "Bob" in the output back to the
+// source file that defined the person_ descriptor identifying Bob.
+//
+// Annotate can only examine variables substituted during the last call to
+// Print. It is invalid to refer to a variable that was used multiple times
+// in a single Print call.
+//
+// In full generality, one may specify a range of output text using a beginning
+// substitution variable and an ending variable. The resulting annotation will
+// span from the first character of the substituted value for the beginning
+// variable to the last character of the substituted value for the ending
+// variable. For example, the Annotate call above is equivalent to this one:
+//
+// printer.Annotate("name", "name", person_);
+//
+// This is useful if multiple variables combine to form a single span of output
+// that should be annotated with the same source path. For example:
+//
+// Printer printer(output, '$');
+// map<string, string> vars;
+// vars["first"] = "Alice";
+// vars["last"] = "Smith";
+// printer.Print(vars, "My name is $first$ $last$.");
+// printer.Annotate("first", "last", person_);
+//
+// This code would associate the span covering "Alice Smith" in the output with
+// the person_ descriptor.
+//
+// Note that the beginning variable must come before (or overlap with, in the
+// case of zero-sized substitution values) the ending variable.
+//
+// It is also sometimes useful to use variables with zero-sized values as
+// markers. This avoids issues with multiple references to the same variable
+// and also allows annotation ranges to span literal text from the Print
+// templates:
+//
+// Printer printer(output, '$');
+// map<string, string> vars;
+// vars["foo"] = "bar";
+// vars["function"] = "call";
+// vars["mark"] = "";
+// printer.Print(vars, "$function$($foo$,$foo$)$mark$");
+// printer.Annotate("function", "rmark", call_);
+//
+// This code associates the span covering "call(bar,bar)" in the output with the
+// call_ descriptor.
+
class LIBPROTOBUF_EXPORT Printer {
public:
// Create a printer that writes text to the given output stream. Use the
// given character as the delimiter for variables.
Printer(ZeroCopyOutputStream* output, char variable_delimiter);
+
+ // Create a printer that writes text to the given output stream. Use the
+ // given character as the delimiter for variables. If annotation_collector
+ // is not null, Printer will provide it with annotations about code written
+ // to the stream. annotation_collector is not owned by Printer.
+ Printer(ZeroCopyOutputStream* output, char variable_delimiter,
+ AnnotationCollector* annotation_collector);
+
~Printer();
+ // Link a subsitution variable emitted by the last call to Print to the object
+ // described by descriptor.
+ template <typename SomeDescriptor>
+ void Annotate(const char* varname, const SomeDescriptor* descriptor) {
+ Annotate(varname, varname, descriptor);
+ }
+
+ // Link the output range defined by the substitution variables as emitted by
+ // the last call to Print to the object described by descriptor. The range
+ // begins at begin_varname's value and ends after the last character of the
+ // value substituted for end_varname.
+ template <typename SomeDescriptor>
+ void Annotate(const char* begin_varname, const char* end_varname,
+ const SomeDescriptor* descriptor) {
+ if (annotation_collector_ == NULL) {
+ // Annotations aren't turned on for this Printer, so don't pay the cost
+ // of building the location path.
+ return;
+ }
+ vector<int> path;
+ descriptor->GetLocationPath(&path);
+ Annotate(begin_varname, end_varname, descriptor->file()->name(), path);
+ }
+
+ // Link a subsitution variable emitted by the last call to Print to the file
+ // with path file_name.
+ void Annotate(const char* varname, const string& file_name) {
+ Annotate(varname, varname, file_name);
+ }
+
+ // Link the output range defined by the substitution variables as emitted by
+ // the last call to Print to the file with path file_name. The range begins
+ // at begin_varname's value and ends after the last character of the value
+ // substituted for end_varname.
+ void Annotate(const char* begin_varname, const char* end_varname,
+ const string& file_name) {
+ if (annotation_collector_ == NULL) {
+ // Annotations aren't turned on for this Printer.
+ return;
+ }
+ vector<int> empty_path;
+ Annotate(begin_varname, end_varname, file_name, empty_path);
+ }
+
// Print some text after applying variable substitutions. If a particular
// variable in the text is not defined, this will crash. Variables to be
// substituted are identified by their names surrounded by delimiter
@@ -149,16 +301,48 @@ class LIBPROTOBUF_EXPORT Printer {
bool failed() const { return failed_; }
private:
+ // Link the output range defined by the substitution variables as emitted by
+ // the last call to Print to the object found at the SourceCodeInfo-style path
+ // in a file with path file_path. The range begins at the start of
+ // begin_varname's value and ends after the last character of the value
+ // substituted for end_varname. Note that begin_varname and end_varname
+ // may refer to the same variable.
+ void Annotate(const char* begin_varname, const char* end_varname,
+ const string& file_path, const vector<int>& path);
+
const char variable_delimiter_;
ZeroCopyOutputStream* const output_;
char* buffer_;
int buffer_size_;
+ // The current position, in bytes, in the output stream. This is equivalent
+ // to the total number of bytes that have been written so far. This value is
+ // used to calculate annotation ranges in the substitutions_ map below.
+ size_t offset_;
string indent_;
bool at_start_of_line_;
bool failed_;
+ // A map from variable name to [start, end) offsets in the output buffer.
+ // These refer to the offsets used for a variable after the last call to
+ // Print. If a variable was used more than once, the entry used in
+ // this map is set to a negative-length span. For singly-used variables, the
+ // start offset is the beginning of the substitution; the end offset is the
+ // last byte of the substitution plus one (such that (end - start) is the
+ // length of the substituted string).
+ map<string, pair<size_t, size_t> > substitutions_;
+
+ // Returns true and sets range to the substitution range in the output for
+ // varname if varname was used once in the last call to Print. If varname
+ // was not used, or if it was used multiple times, returns false (and
+ // fails a debug assertion).
+ bool GetSubstitutionRange(const char* varname, pair<size_t, size_t>* range);
+
+ // If non-null, annotation_collector_ is used to store annotations about
+ // generated code.
+ AnnotationCollector* const annotation_collector_;
+
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Printer);
};
diff --git a/src/google/protobuf/io/printer_unittest.cc b/src/google/protobuf/io/printer_unittest.cc
index 258dd986..95f3afa2 100644
--- a/src/google/protobuf/io/printer_unittest.cc
+++ b/src/google/protobuf/io/printer_unittest.cc
@@ -36,6 +36,7 @@
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
@@ -169,6 +170,196 @@ TEST(Printer, InlineVariableSubstitution) {
buffer);
}
+// MockDescriptorFile defines only those members that Printer uses to write out
+// annotations.
+class MockDescriptorFile {
+ public:
+ explicit MockDescriptorFile(const string& file) : file_(file) {}
+
+ // The mock filename for this file.
+ const string& name() const { return file_; }
+
+ private:
+ string file_;
+};
+
+// MockDescriptor defines only those members that Printer uses to write out
+// annotations.
+class MockDescriptor {
+ public:
+ MockDescriptor(const string& file, const vector<int>& path)
+ : file_(file), path_(path) {}
+
+ // The mock file in which this descriptor was defined.
+ const MockDescriptorFile* file() const { return &file_; }
+
+ private:
+ // Allows access to GetLocationPath.
+ friend class ::google::protobuf::io::Printer;
+
+ // Copies the pre-stored path to output.
+ void GetLocationPath(std::vector<int>* output) const { *output = path_; }
+
+ MockDescriptorFile file_;
+ vector<int> path_;
+};
+
+TEST(Printer, AnnotateMap) {
+ char buffer[8192];
+ ArrayOutputStream output(buffer, sizeof(buffer));
+ GeneratedCodeInfo info;
+ AnnotationProtoCollector<GeneratedCodeInfo> info_collector(&info);
+ {
+ Printer printer(&output, '$', &info_collector);
+ map<string, string> vars;
+ vars["foo"] = "3";
+ vars["bar"] = "5";
+ printer.Print(vars, "012$foo$4$bar$\n");
+ vector<int> path_1;
+ path_1.push_back(33);
+ vector<int> path_2;
+ path_2.push_back(11);
+ path_2.push_back(22);
+ MockDescriptor descriptor_1("path_1", path_1);
+ MockDescriptor descriptor_2("path_2", path_2);
+ printer.Annotate("foo", "foo", &descriptor_1);
+ printer.Annotate("bar", "bar", &descriptor_2);
+ }
+ buffer[output.ByteCount()] = '\0';
+ EXPECT_STREQ("012345\n", buffer);
+ ASSERT_EQ(2, info.annotation_size());
+ const GeneratedCodeInfo::Annotation* foo = info.annotation(0).path_size() == 1
+ ? &info.annotation(0)
+ : &info.annotation(1);
+ const GeneratedCodeInfo::Annotation* bar = info.annotation(0).path_size() == 1
+ ? &info.annotation(1)
+ : &info.annotation(0);
+ ASSERT_EQ(1, foo->path_size());
+ ASSERT_EQ(2, bar->path_size());
+ EXPECT_EQ(33, foo->path(0));
+ EXPECT_EQ(11, bar->path(0));
+ EXPECT_EQ(22, bar->path(1));
+ EXPECT_EQ("path_1", foo->source_file());
+ EXPECT_EQ("path_2", bar->source_file());
+ EXPECT_EQ(3, foo->begin());
+ EXPECT_EQ(4, foo->end());
+ EXPECT_EQ(5, bar->begin());
+ EXPECT_EQ(6, bar->end());
+}
+
+TEST(Printer, AnnotateInline) {
+ char buffer[8192];
+ ArrayOutputStream output(buffer, sizeof(buffer));
+ GeneratedCodeInfo info;
+ AnnotationProtoCollector<GeneratedCodeInfo> info_collector(&info);
+ {
+ Printer printer(&output, '$', &info_collector);
+ printer.Print("012$foo$4$bar$\n", "foo", "3", "bar", "5");
+ vector<int> path_1;
+ path_1.push_back(33);
+ vector<int> path_2;
+ path_2.push_back(11);
+ path_2.push_back(22);
+ MockDescriptor descriptor_1("path_1", path_1);
+ MockDescriptor descriptor_2("path_2", path_2);
+ printer.Annotate("foo", "foo", &descriptor_1);
+ printer.Annotate("bar", "bar", &descriptor_2);
+ }
+ buffer[output.ByteCount()] = '\0';
+ EXPECT_STREQ("012345\n", buffer);
+ ASSERT_EQ(2, info.annotation_size());
+ const GeneratedCodeInfo::Annotation* foo = info.annotation(0).path_size() == 1
+ ? &info.annotation(0)
+ : &info.annotation(1);
+ const GeneratedCodeInfo::Annotation* bar = info.annotation(0).path_size() == 1
+ ? &info.annotation(1)
+ : &info.annotation(0);
+ ASSERT_EQ(1, foo->path_size());
+ ASSERT_EQ(2, bar->path_size());
+ EXPECT_EQ(33, foo->path(0));
+ EXPECT_EQ(11, bar->path(0));
+ EXPECT_EQ(22, bar->path(1));
+ EXPECT_EQ("path_1", foo->source_file());
+ EXPECT_EQ("path_2", bar->source_file());
+ EXPECT_EQ(3, foo->begin());
+ EXPECT_EQ(4, foo->end());
+ EXPECT_EQ(5, bar->begin());
+ EXPECT_EQ(6, bar->end());
+}
+
+TEST(Printer, AnnotateRange) {
+ char buffer[8192];
+ ArrayOutputStream output(buffer, sizeof(buffer));
+ GeneratedCodeInfo info;
+ AnnotationProtoCollector<GeneratedCodeInfo> info_collector(&info);
+ {
+ Printer printer(&output, '$', &info_collector);
+ printer.Print("012$foo$4$bar$\n", "foo", "3", "bar", "5");
+ vector<int> path;
+ path.push_back(33);
+ MockDescriptor descriptor("path", path);
+ printer.Annotate("foo", "bar", &descriptor);
+ }
+ buffer[output.ByteCount()] = '\0';
+ EXPECT_STREQ("012345\n", buffer);
+ ASSERT_EQ(1, info.annotation_size());
+ const GeneratedCodeInfo::Annotation* foobar = &info.annotation(0);
+ ASSERT_EQ(1, foobar->path_size());
+ EXPECT_EQ(33, foobar->path(0));
+ EXPECT_EQ("path", foobar->source_file());
+ EXPECT_EQ(3, foobar->begin());
+ EXPECT_EQ(6, foobar->end());
+}
+
+TEST(Printer, AnnotateEmptyRange) {
+ char buffer[8192];
+ ArrayOutputStream output(buffer, sizeof(buffer));
+ GeneratedCodeInfo info;
+ AnnotationProtoCollector<GeneratedCodeInfo> info_collector(&info);
+ {
+ Printer printer(&output, '$', &info_collector);
+ printer.Print("012$foo$4$baz$$bam$$bar$\n", "foo", "3", "bar", "5", "baz",
+ "", "bam", "");
+ vector<int> path;
+ path.push_back(33);
+ MockDescriptor descriptor("path", path);
+ printer.Annotate("baz", "bam", &descriptor);
+ }
+ buffer[output.ByteCount()] = '\0';
+ EXPECT_STREQ("012345\n", buffer);
+ ASSERT_EQ(1, info.annotation_size());
+ const GeneratedCodeInfo::Annotation* bazbam = &info.annotation(0);
+ ASSERT_EQ(1, bazbam->path_size());
+ EXPECT_EQ(33, bazbam->path(0));
+ EXPECT_EQ("path", bazbam->source_file());
+ EXPECT_EQ(5, bazbam->begin());
+ EXPECT_EQ(5, bazbam->end());
+}
+
+TEST(Printer, AnnotateDespiteUnrelatedMultipleUses) {
+ char buffer[8192];
+ ArrayOutputStream output(buffer, sizeof(buffer));
+ GeneratedCodeInfo info;
+ AnnotationProtoCollector<GeneratedCodeInfo> info_collector(&info);
+ {
+ Printer printer(&output, '$', &info_collector);
+ printer.Print("012$foo$4$foo$$bar$\n", "foo", "3", "bar", "5");
+ vector<int> path;
+ path.push_back(33);
+ MockDescriptor descriptor("path", path);
+ printer.Annotate("bar", "bar", &descriptor);
+ }
+ buffer[output.ByteCount()] = '\0';
+ EXPECT_STREQ("0123435\n", buffer);
+ ASSERT_EQ(1, info.annotation_size());
+ const GeneratedCodeInfo::Annotation* bar = &info.annotation(0);
+ ASSERT_EQ(1, bar->path_size());
+ EXPECT_EQ(33, bar->path(0));
+ EXPECT_EQ("path", bar->source_file());
+ EXPECT_EQ(6, bar->begin());
+ EXPECT_EQ(7, bar->end());
+}
+
TEST(Printer, Indenting) {
char buffer[8192];
@@ -232,6 +423,52 @@ TEST(Printer, Death) {
EXPECT_DEBUG_DEATH(printer.Print("$unclosed"), "Unclosed variable name");
EXPECT_DEBUG_DEATH(printer.Outdent(), "without matching Indent");
}
+
+TEST(Printer, AnnotateMultipleUsesDeath) {
+ char buffer[8192];
+ ArrayOutputStream output(buffer, sizeof(buffer));
+ GeneratedCodeInfo info;
+ AnnotationProtoCollector<GeneratedCodeInfo> info_collector(&info);
+ {
+ Printer printer(&output, '$', &info_collector);
+ printer.Print("012$foo$4$foo$\n", "foo", "3");
+ vector<int> path;
+ path.push_back(33);
+ MockDescriptor descriptor("path", path);
+ EXPECT_DEBUG_DEATH(printer.Annotate("foo", "foo", &descriptor), "multiple");
+ }
+}
+
+TEST(Printer, AnnotateNegativeLengthDeath) {
+ char buffer[8192];
+ ArrayOutputStream output(buffer, sizeof(buffer));
+ GeneratedCodeInfo info;
+ AnnotationProtoCollector<GeneratedCodeInfo> info_collector(&info);
+ {
+ Printer printer(&output, '$', &info_collector);
+ printer.Print("012$foo$4$bar$\n", "foo", "3", "bar", "5");
+ vector<int> path;
+ path.push_back(33);
+ MockDescriptor descriptor("path", path);
+ EXPECT_DEBUG_DEATH(printer.Annotate("bar", "foo", &descriptor), "negative");
+ }
+}
+
+TEST(Printer, AnnotateUndefinedDeath) {
+ char buffer[8192];
+ ArrayOutputStream output(buffer, sizeof(buffer));
+ GeneratedCodeInfo info;
+ AnnotationProtoCollector<GeneratedCodeInfo> info_collector(&info);
+ {
+ Printer printer(&output, '$', &info_collector);
+ printer.Print("012$foo$4$foo$\n", "foo", "3");
+ vector<int> path;
+ path.push_back(33);
+ MockDescriptor descriptor("path", path);
+ EXPECT_DEBUG_DEATH(printer.Annotate("bar", "bar", &descriptor),
+ "Undefined");
+ }
+}
#endif // PROTOBUF_HAS_DEATH_TEST
TEST(Printer, WriteFailurePartial) {
diff --git a/src/google/protobuf/io/strtod.cc b/src/google/protobuf/io/strtod.cc
index 579de9aa..a90bb9a3 100644
--- a/src/google/protobuf/io/strtod.cc
+++ b/src/google/protobuf/io/strtod.cc
@@ -32,6 +32,7 @@
#include <cstdio>
#include <cstring>
+#include <limits>
#include <string>
#include <google/protobuf/stubs/logging.h>
@@ -109,6 +110,16 @@ double NoLocaleStrtod(const char* text, char** original_endptr) {
return result;
}
+float SafeDoubleToFloat(double value) {
+ if (value > std::numeric_limits<float>::max()) {
+ return std::numeric_limits<float>::infinity();
+ } else if (value < -std::numeric_limits<float>::max()) {
+ return -std::numeric_limits<float>::infinity();
+ } else {
+ return static_cast<float>(value);
+ }
+}
+
} // namespace io
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/io/strtod.h b/src/google/protobuf/io/strtod.h
index c2efc8d3..f56e41c8 100644
--- a/src/google/protobuf/io/strtod.h
+++ b/src/google/protobuf/io/strtod.h
@@ -43,6 +43,11 @@ namespace io {
// uses a dot as the decimal separator.
double NoLocaleStrtod(const char* str, char** endptr);
+// Casts a double value to a float value. If the value is outside of the
+// representable range of float, it will be converted to positive or negative
+// infinity.
+float SafeDoubleToFloat(double value);
+
} // namespace io
} // namespace protobuf
diff --git a/src/google/protobuf/io/tokenizer.cc b/src/google/protobuf/io/tokenizer.cc
index 7ccd633d..b3550dfb 100644
--- a/src/google/protobuf/io/tokenizer.cc
+++ b/src/google/protobuf/io/tokenizer.cc
@@ -375,7 +375,7 @@ void Tokenizer::ConsumeString(char delimiter) {
// Possibly followed by two more octal digits, but these will
// just be consumed by the main loop anyway so we don't need
// to do so explicitly here.
- } else if (TryConsume('x') || TryConsume('X')) {
+ } else if (TryConsume('x')) {
if (!TryConsumeOne<HexDigit>()) {
AddError("Expected hex digits for escape sequence.");
}
@@ -881,9 +881,11 @@ bool Tokenizer::ParseInteger(const string& text, uint64 max_value,
uint64 result = 0;
for (; *ptr != '\0'; ptr++) {
int digit = DigitValue(*ptr);
- GOOGLE_LOG_IF(DFATAL, digit < 0 || digit >= base)
- << " Tokenizer::ParseInteger() passed text that could not have been"
- " tokenized as an integer: " << CEscape(text);
+ if (digit < 0 || digit >= base) {
+ // The token provided by Tokenizer is invalid. i.e., 099 is an invalid
+ // token, but Tokenizer still think it's integer.
+ return false;
+ }
if (digit > max_value || result > (max_value - digit) / base) {
// Overflow.
return false;
diff --git a/src/google/protobuf/io/tokenizer.h b/src/google/protobuf/io/tokenizer.h
index 49885eda..77a873bc 100644
--- a/src/google/protobuf/io/tokenizer.h
+++ b/src/google/protobuf/io/tokenizer.h
@@ -52,6 +52,12 @@ class ZeroCopyInputStream; // zero_copy_stream.h
class ErrorCollector;
class Tokenizer;
+// By "column number", the proto compiler refers to a count of the number
+// of bytes before a given byte, except that a tab character advances to
+// the next multiple of 8 bytes. Note in particular that column numbers
+// are zero-based, while many user interfaces use one-based column numbers.
+typedef int ColumnNumber;
+
// Abstract interface for an object which collects the errors that occur
// during parsing. A typical implementation might simply print the errors
// to stdout.
@@ -63,13 +69,14 @@ class LIBPROTOBUF_EXPORT ErrorCollector {
// Indicates that there was an error in the input at the given line and
// column numbers. The numbers are zero-based, so you may want to add
// 1 to each before printing them.
- virtual void AddError(int line, int column, const string& message) = 0;
+ virtual void AddError(int line, ColumnNumber column,
+ const string& message) = 0;
// Indicates that there was a warning in the input at the given line and
// column numbers. The numbers are zero-based, so you may want to add
// 1 to each before printing them.
- virtual void AddWarning(int /* line */, int /* column */,
- const string& /* message */) { }
+ virtual void AddWarning(int line, ColumnNumber column,
+ const string& message) { }
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ErrorCollector);
@@ -124,8 +131,8 @@ class LIBPROTOBUF_EXPORT Tokenizer {
// "line" and "column" specify the position of the first character of
// the token within the input stream. They are zero-based.
int line;
- int column;
- int end_column;
+ ColumnNumber column;
+ ColumnNumber end_column;
};
// Get the current token. This is updated when Next() is called. Before
@@ -263,7 +270,7 @@ class LIBPROTOBUF_EXPORT Tokenizer {
// Line and column number of current_char_ within the whole input stream.
int line_;
- int column_;
+ ColumnNumber column_;
// String to which text should be appended as we advance through it.
// Call RecordTo(&str) to start recording and StopRecording() to stop.
@@ -280,6 +287,7 @@ class LIBPROTOBUF_EXPORT Tokenizer {
// Since we count columns we need to interpret tabs somehow. We'll take
// the standard 8-character definition for lack of any way to do better.
+ // This must match the documentation of ColumnNumber.
static const int kTabWidth = 8;
// -----------------------------------------------------------------
@@ -321,7 +329,7 @@ class LIBPROTOBUF_EXPORT Tokenizer {
// depending on what was read. This needs to know if the first
// character was a zero in order to correctly recognize hex and octal
// numbers.
- // It also needs to know if the first characted was a . to parse floating
+ // It also needs to know if the first character was a . to parse floating
// point correctly.
TokenType ConsumeNumber(bool started_with_zero, bool started_with_dot);
diff --git a/src/google/protobuf/io/tokenizer_unittest.cc b/src/google/protobuf/io/tokenizer_unittest.cc
index 6526056a..ae0811f8 100644
--- a/src/google/protobuf/io/tokenizer_unittest.cc
+++ b/src/google/protobuf/io/tokenizer_unittest.cc
@@ -736,19 +736,13 @@ TEST_F(TokenizerTest, ParseInteger) {
EXPECT_EQ(0, ParseInteger("0x"));
uint64 i;
-#ifdef PROTOBUF_HAS_DEATH_TEST // death tests do not work on Windows yet
+
// Test invalid integers that will never be tokenized as integers.
- EXPECT_DEBUG_DEATH(Tokenizer::ParseInteger("zxy", kuint64max, &i),
- "passed text that could not have been tokenized as an integer");
- EXPECT_DEBUG_DEATH(Tokenizer::ParseInteger("1.2", kuint64max, &i),
- "passed text that could not have been tokenized as an integer");
- EXPECT_DEBUG_DEATH(Tokenizer::ParseInteger("08", kuint64max, &i),
- "passed text that could not have been tokenized as an integer");
- EXPECT_DEBUG_DEATH(Tokenizer::ParseInteger("0xg", kuint64max, &i),
- "passed text that could not have been tokenized as an integer");
- EXPECT_DEBUG_DEATH(Tokenizer::ParseInteger("-1", kuint64max, &i),
- "passed text that could not have been tokenized as an integer");
-#endif // PROTOBUF_HAS_DEATH_TEST
+ EXPECT_FALSE(Tokenizer::ParseInteger("zxy", kuint64max, &i));
+ EXPECT_FALSE(Tokenizer::ParseInteger("1.2", kuint64max, &i));
+ EXPECT_FALSE(Tokenizer::ParseInteger("08", kuint64max, &i));
+ EXPECT_FALSE(Tokenizer::ParseInteger("0xg", kuint64max, &i));
+ EXPECT_FALSE(Tokenizer::ParseInteger("-1", kuint64max, &i));
// Test overflows.
EXPECT_TRUE (Tokenizer::ParseInteger("0", 0, &i));
@@ -875,6 +869,8 @@ ErrorCase kErrorCases[] = {
// String errors.
{ "'\\l' foo", true,
"0:2: Invalid escape sequence in string literal.\n" },
+ { "'\\X' foo", true,
+ "0:2: Invalid escape sequence in string literal.\n" },
{ "'\\x' foo", true,
"0:3: Expected hex digits for escape sequence.\n" },
{ "'foo", false,
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 686e63f2..e6ca88c2 100644
--- a/src/google/protobuf/io/zero_copy_stream_impl_lite.cc
+++ b/src/google/protobuf/io/zero_copy_stream_impl_lite.cc
@@ -69,7 +69,7 @@ ArrayInputStream::~ArrayInputStream() {
bool ArrayInputStream::Next(const void** data, int* size) {
if (position_ < size_) {
- last_returned_size_ = min(block_size_, size_ - position_);
+ last_returned_size_ = std::min(block_size_, size_ - position_);
*data = data_ + position_;
*size = last_returned_size_;
position_ += last_returned_size_;
@@ -122,7 +122,7 @@ ArrayOutputStream::~ArrayOutputStream() {
bool ArrayOutputStream::Next(void** data, int* size) {
if (position_ < size_) {
- last_returned_size_ = min(block_size_, size_ - position_);
+ last_returned_size_ = std::min(block_size_, size_ - position_);
*data = data_ + position_;
*size = last_returned_size_;
position_ += last_returned_size_;
@@ -157,6 +157,7 @@ StringOutputStream::~StringOutputStream() {
}
bool StringOutputStream::Next(void** data, int* size) {
+ GOOGLE_CHECK(target_ != NULL);
int old_size = target_->size();
// Grow the string.
@@ -176,9 +177,9 @@ bool StringOutputStream::Next(void** data, int* size) {
// Double the size, also make sure that the new size is at least
// kMinimumSize.
STLStringResizeUninitialized(
- target_,
- max(old_size * 2,
- kMinimumSize + 0)); // "+ 0" works around GCC4 weirdness.
+ target_,
+ std::max(old_size * 2,
+ kMinimumSize + 0)); // "+ 0" works around GCC4 weirdness.
}
*data = mutable_string_data(target_) + old_size;
@@ -188,14 +189,44 @@ bool StringOutputStream::Next(void** data, int* size) {
void StringOutputStream::BackUp(int count) {
GOOGLE_CHECK_GE(count, 0);
+ GOOGLE_CHECK(target_ != NULL);
GOOGLE_CHECK_LE(count, target_->size());
target_->resize(target_->size() - count);
}
int64 StringOutputStream::ByteCount() const {
+ GOOGLE_CHECK(target_ != NULL);
return target_->size();
}
+void StringOutputStream::SetString(string* target) {
+ target_ = target;
+}
+
+// ===================================================================
+
+LazyStringOutputStream::LazyStringOutputStream(
+ ResultCallback<string*>* callback)
+ : StringOutputStream(NULL),
+ callback_(GOOGLE_CHECK_NOTNULL(callback)),
+ string_is_set_(false) {
+}
+
+LazyStringOutputStream::~LazyStringOutputStream() {
+}
+
+bool LazyStringOutputStream::Next(void** data, int* size) {
+ if (!string_is_set_) {
+ SetString(callback_->Run());
+ string_is_set_ = true;
+ }
+ return StringOutputStream::Next(data, size);
+}
+
+int64 LazyStringOutputStream::ByteCount() const {
+ return string_is_set_ ? StringOutputStream::ByteCount() : 0;
+}
+
// ===================================================================
CopyingInputStream::~CopyingInputStream() {}
@@ -204,8 +235,8 @@ int CopyingInputStream::Skip(int count) {
char junk[4096];
int skipped = 0;
while (skipped < count) {
- int bytes = Read(junk, min(count - skipped,
- implicit_cast<int>(sizeof(junk))));
+ int bytes =
+ Read(junk, std::min(count - skipped, implicit_cast<int>(sizeof(junk))));
if (bytes <= 0) {
// EOF or read error.
return skipped;
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 a598ef2e..e4d6a024 100644
--- a/src/google/protobuf/io/zero_copy_stream_impl_lite.h
+++ b/src/google/protobuf/io/zero_copy_stream_impl_lite.h
@@ -51,8 +51,8 @@
#include <string>
#include <iosfwd>
#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/stubs/callback.h>
#include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/scoped_ptr.h>
#include <google/protobuf/stubs/stl_util.h>
@@ -148,6 +148,9 @@ class LIBPROTOBUF_EXPORT StringOutputStream : public ZeroCopyOutputStream {
void BackUp(int count);
int64 ByteCount() const;
+ protected:
+ void SetString(string* target);
+
private:
static const int kMinimumSize = 16;
@@ -156,6 +159,27 @@ class LIBPROTOBUF_EXPORT StringOutputStream : public ZeroCopyOutputStream {
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringOutputStream);
};
+// LazyStringOutputStream is a StringOutputStream with lazy acquisition of
+// the output string from a callback. The string is owned externally, and not
+// deleted in the stream destructor.
+class LIBPROTOBUF_EXPORT LazyStringOutputStream : public StringOutputStream {
+ public:
+ // Callback should be permanent (non-self-deleting). Ownership is transferred
+ // to the LazyStringOutputStream.
+ explicit LazyStringOutputStream(ResultCallback<string*>* callback);
+ ~LazyStringOutputStream();
+
+ // implements ZeroCopyOutputStream, overriding StringOutputStream -----------
+ bool Next(void** data, int* size);
+ int64 ByteCount() const;
+
+ private:
+ const google::protobuf::scoped_ptr<ResultCallback<string*> > callback_;
+ bool string_is_set_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(LazyStringOutputStream);
+};
+
// Note: There is no StringInputStream. Instead, just create an
// ArrayInputStream as follows:
// ArrayInputStream input(str.data(), str.size());
diff --git a/src/google/protobuf/io/zero_copy_stream_unittest.cc b/src/google/protobuf/io/zero_copy_stream_unittest.cc
index 8c7358c1..a9db8872 100644
--- a/src/google/protobuf/io/zero_copy_stream_unittest.cc
+++ b/src/google/protobuf/io/zero_copy_stream_unittest.cc
@@ -63,8 +63,9 @@
#endif
#include <sstream>
-#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/testing/file.h>
#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
#if HAVE_ZLIB
#include <google/protobuf/io/gzip_stream.h>
@@ -72,7 +73,6 @@
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/logging.h>
-#include <google/protobuf/stubs/scoped_ptr.h>
#include <google/protobuf/testing/googletest.h>
#include <google/protobuf/testing/file.h>
#include <gtest/gtest.h>
diff --git a/src/google/protobuf/lite_unittest.cc b/src/google/protobuf/lite_unittest.cc
index d1948ab5..3ca3fbaf 100644
--- a/src/google/protobuf/lite_unittest.cc
+++ b/src/google/protobuf/lite_unittest.cc
@@ -686,6 +686,33 @@ int main(int argc, char* argv[]) {
EXPECT_TRUE(map_message.IsInitialized());
}
+ {
+ // Check that adding more values to enum does not corrupt message
+ // when passed through an old client.
+ protobuf_unittest::V2MessageLite v2_message;
+ v2_message.set_int_field(800);
+ // Set enum field to the value not understood by the old client.
+ v2_message.set_enum_field(protobuf_unittest::V2_SECOND);
+ string v2_bytes = v2_message.SerializeAsString();
+
+ protobuf_unittest::V1MessageLite v1_message;
+ v1_message.ParseFromString(v2_bytes);
+ EXPECT_TRUE(v1_message.IsInitialized());
+ EXPECT_EQ(v1_message.int_field(), v2_message.int_field());
+ // V1 client does not understand V2_SECOND value, so it discards it and
+ // uses default value instead.
+ EXPECT_EQ(v1_message.enum_field(), protobuf_unittest::V1_FIRST);
+
+ // However, when re-serialized, it should preserve enum value.
+ string v1_bytes = v1_message.SerializeAsString();
+
+ protobuf_unittest::V2MessageLite same_v2_message;
+ same_v2_message.ParseFromString(v1_bytes);
+
+ EXPECT_EQ(v2_message.int_field(), same_v2_message.int_field());
+ EXPECT_EQ(v2_message.enum_field(), same_v2_message.enum_field());
+ }
+
std::cout << "PASS" << std::endl;
return 0;
}
diff --git a/src/google/protobuf/map.h b/src/google/protobuf/map.h
index 4bd76f25..1b9aa703 100644
--- a/src/google/protobuf/map.h
+++ b/src/google/protobuf/map.h
@@ -31,9 +31,11 @@
#ifndef GOOGLE_PROTOBUF_MAP_H__
#define GOOGLE_PROTOBUF_MAP_H__
-#include <iterator>
#include <google/protobuf/stubs/hash.h>
+#include <iterator>
#include <limits> // To support Visual Studio 2008
+#include <set>
+#include <utility>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/arena.h>
@@ -41,17 +43,23 @@
#include <google/protobuf/map_type_handler.h>
#include <google/protobuf/message.h>
#include <google/protobuf/descriptor.h>
+#if __cpp_exceptions && LANG_CXX11
+#include <random>
+#endif
namespace google {
namespace protobuf {
+// The Map and MapIterator types are provided by this header file.
+// Please avoid using other types defined here, unless they are public
+// types within Map or MapIterator, such as Map::value_type.
template <typename Key, typename T>
class Map;
-template <typename Enum> struct is_proto_enum;
-
class MapIterator;
+template <typename Enum> struct is_proto_enum;
+
namespace internal {
template <typename Key, typename T,
WireFormatLite::FieldType key_wire_type,
@@ -73,15 +81,15 @@ class DynamicMapField;
class GeneratedMessageReflection;
} // namespace internal
-#define TYPE_CHECK(EXPECTEDTYPE, METHOD) \
- if (type() != EXPECTEDTYPE) { \
- GOOGLE_LOG(FATAL) \
- << "Protocol Buffer map usage error:\n" \
- << METHOD << " type does not match\n" \
- << " Expected : " \
- << FieldDescriptor::CppTypeName(EXPECTEDTYPE) << "\n" \
- << " Actual : " \
- << FieldDescriptor::CppTypeName(type()); \
+#define TYPE_CHECK(EXPECTEDTYPE, METHOD) \
+ if (type() != EXPECTEDTYPE) { \
+ GOOGLE_LOG(FATAL) \
+ << "Protocol Buffer map usage error:\n" \
+ << METHOD << " type does not match\n" \
+ << " Expected : " \
+ << FieldDescriptor::CppTypeName(EXPECTEDTYPE) << "\n" \
+ << " Actual : " \
+ << FieldDescriptor::CppTypeName(type()); \
}
// MapKey is an union type for representing any possible
@@ -166,11 +174,47 @@ class LIBPROTOBUF_EXPORT MapKey {
return *val_.string_value_;
}
+ bool operator<(const MapKey& other) const {
+ if (type_ != other.type_) {
+ // We could define a total order that handles this case, but
+ // there currently no need. So, for now, fail.
+ GOOGLE_LOG(FATAL) << "Unsupported: type mismatch";
+ }
+ switch (type()) {
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ case FieldDescriptor::CPPTYPE_ENUM:
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ GOOGLE_LOG(FATAL) << "Unsupported";
+ return false;
+ case FieldDescriptor::CPPTYPE_STRING:
+ return *val_.string_value_ < *other.val_.string_value_;
+ case FieldDescriptor::CPPTYPE_INT64:
+ return val_.int64_value_ < other.val_.int64_value_;
+ case FieldDescriptor::CPPTYPE_INT32:
+ return val_.int32_value_ < other.val_.int32_value_;
+ case FieldDescriptor::CPPTYPE_UINT64:
+ return val_.uint64_value_ < other.val_.uint64_value_;
+ case FieldDescriptor::CPPTYPE_UINT32:
+ return val_.uint32_value_ < other.val_.uint32_value_;
+ case FieldDescriptor::CPPTYPE_BOOL:
+ return val_.bool_value_ < other.val_.bool_value_;
+ }
+ return false;
+ }
+
bool operator==(const MapKey& other) const {
if (type_ != other.type_) {
- return false;
+ // To be consistent with operator<, we don't allow this either.
+ GOOGLE_LOG(FATAL) << "Unsupported: type mismatch";
}
switch (type()) {
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ case FieldDescriptor::CPPTYPE_ENUM:
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ GOOGLE_LOG(FATAL) << "Unsupported";
+ break;
case FieldDescriptor::CPPTYPE_STRING:
return *val_.string_value_ == *other.val_.string_value_;
case FieldDescriptor::CPPTYPE_INT64:
@@ -183,12 +227,6 @@ class LIBPROTOBUF_EXPORT MapKey {
return val_.uint32_value_ == other.val_.uint32_value_;
case FieldDescriptor::CPPTYPE_BOOL:
return val_.bool_value_ == other.val_.bool_value_;
- case FieldDescriptor::CPPTYPE_DOUBLE:
- case FieldDescriptor::CPPTYPE_FLOAT:
- case FieldDescriptor::CPPTYPE_ENUM:
- case FieldDescriptor::CPPTYPE_MESSAGE:
- GOOGLE_LOG(FATAL) << "Can't get here.";
- return false;
}
GOOGLE_LOG(FATAL) << "Can't get here.";
return false;
@@ -197,6 +235,12 @@ class LIBPROTOBUF_EXPORT MapKey {
void CopyFrom(const MapKey& other) {
SetType(other.type());
switch (type_) {
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ case FieldDescriptor::CPPTYPE_ENUM:
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ GOOGLE_LOG(FATAL) << "Unsupported";
+ break;
case FieldDescriptor::CPPTYPE_STRING:
*val_.string_value_ = *other.val_.string_value_;
break;
@@ -215,12 +259,6 @@ class LIBPROTOBUF_EXPORT MapKey {
case FieldDescriptor::CPPTYPE_BOOL:
val_.bool_value_ = other.val_.bool_value_;
break;
- case FieldDescriptor::CPPTYPE_DOUBLE:
- case FieldDescriptor::CPPTYPE_FLOAT:
- case FieldDescriptor::CPPTYPE_ENUM:
- case FieldDescriptor::CPPTYPE_MESSAGE:
- GOOGLE_LOG(FATAL) << "Can't get here.";
- break;
}
}
@@ -458,8 +496,15 @@ class MapPair {
};
// google::protobuf::Map is an associative container type used to store protobuf map
-// fields. Its interface is similar to std::unordered_map. Users should use this
-// interface directly to visit or change map fields.
+// fields. Each Map instance may or may not use a different hash function, a
+// different iteration order, and so on. E.g., please don't examine
+// implementation details to decide if the following would work:
+// Map<int, int> m0, m1;
+// m0[0] = m1[0] = m0[1] = m1[1] = 0;
+// assert(m0.begin()->first == m1.begin()->first); // Bug!
+//
+// Map's interface is similar to std::unordered_map, except that Map is not
+// designed to play well with exceptions.
template <typename Key, typename T>
class Map {
public:
@@ -474,40 +519,56 @@ class Map {
typedef size_t size_type;
typedef hash<Key> hasher;
- typedef equal_to<Key> key_equal;
- Map()
+ explicit Map(bool old_style = true)
: arena_(NULL),
- allocator_(arena_),
- elements_(0, hasher(), key_equal(), allocator_),
- default_enum_value_(0) {}
- explicit Map(Arena* arena)
+ default_enum_value_(0),
+ old_style_(old_style) {
+ Init();
+ }
+ explicit Map(Arena* arena, bool old_style = true)
: arena_(arena),
- allocator_(arena_),
- elements_(0, hasher(), key_equal(), allocator_),
- default_enum_value_(0) {
- arena_->OwnDestructor(&elements_);
+ default_enum_value_(0),
+ old_style_(old_style) {
+ Init();
}
-
Map(const Map& other)
: arena_(NULL),
- allocator_(arena_),
- elements_(0, hasher(), key_equal(), allocator_),
- default_enum_value_(other.default_enum_value_) {
+ default_enum_value_(other.default_enum_value_),
+ old_style_(other.old_style_) {
+ Init();
insert(other.begin(), other.end());
}
template <class InputIt>
- explicit Map(const InputIt& first, const InputIt& last)
+ Map(const InputIt& first, const InputIt& last, bool old_style = true)
: arena_(NULL),
- allocator_(arena_),
- elements_(0, hasher(), key_equal(), allocator_),
- default_enum_value_(0) {
+ default_enum_value_(0),
+ old_style_(old_style) {
+ Init();
insert(first, last);
}
- ~Map() { clear(); }
+ ~Map() {
+ clear();
+ if (arena_ == NULL) {
+ if (old_style_)
+ delete deprecated_elements_;
+ else
+ delete elements_;
+ }
+ }
private:
+ void Init() {
+ if (old_style_)
+ deprecated_elements_ = Arena::Create<DeprecatedInnerMap>(
+ arena_, 0, hasher(), equal_to<Key>(),
+ MapAllocator<std::pair<const Key, MapPair<Key, T>*> >(arena_));
+ else
+ elements_ =
+ Arena::Create<InnerMap>(arena_, 0, hasher(), Allocator(arena_));
+ }
+
// re-implement std::allocator to use arena allocator for memory allocation.
// Used for google::protobuf::Map implementation. Users should not use this class
// directly.
@@ -526,7 +587,7 @@ class Map {
explicit MapAllocator(Arena* arena) : arena_(arena) {}
template <typename X>
MapAllocator(const MapAllocator<X>& allocator)
- : arena_(allocator.arena_) {}
+ : arena_(allocator.arena()) {}
pointer allocate(size_type n, const_pointer hint = 0) {
// If arena is not given, malloc needs to be called which doesn't
@@ -551,7 +612,12 @@ class Map {
!defined(GOOGLE_PROTOBUF_OS_EMSCRIPTEN)
template<class NodeType, class... Args>
void construct(NodeType* p, Args&&... args) {
- new (static_cast<void*>(p)) NodeType(std::forward<Args>(args)...);
+ // Clang 3.6 doesn't compile static casting to void* directly. (Issue
+ // #1266) According C++ standard 5.2.9/1: "The static_cast operator shall
+ // not cast away constness". So first the maybe const pointer is casted to
+ // const void* and after the const void* is const casted.
+ new (const_cast<void*>(static_cast<const void*>(p)))
+ NodeType(std::forward<Args>(args)...);
}
template<class NodeType>
@@ -584,94 +650,860 @@ class Map {
return std::numeric_limits<size_type>::max();
}
+ // To support gcc-4.4, which does not properly
+ // support templated friend classes
+ Arena* arena() const {
+ return arena_;
+ }
+
private:
typedef void DestructorSkippable_;
- Arena* arena_;
+ Arena* const arena_;
+ };
- template <typename X>
- friend class MapAllocator;
+ // InnerMap's key type is Key and its value type is value_type*. We use a
+ // custom class here and for Node, below, to ensure that k_ is at offset 0,
+ // allowing safe conversion from pointer to Node to pointer to Key, and vice
+ // versa when appropriate.
+ class KeyValuePair {
+ public:
+ KeyValuePair(const Key& k, value_type* v) : k_(k), v_(v) {}
+
+ const Key& key() const { return k_; }
+ Key& key() { return k_; }
+ value_type* const value() const { return v_; }
+ value_type*& value() { return v_; }
+
+ private:
+ Key k_;
+ value_type* v_;
};
- public:
- typedef MapAllocator<std::pair<const Key, MapPair<Key, T>*> > Allocator;
+ typedef MapAllocator<KeyValuePair> Allocator;
+
+ // InnerMap is a generic hash-based map. It doesn't contain any
+ // protocol-buffer-specific logic. It is a chaining hash map with the
+ // additional feature that some buckets can be converted to use an ordered
+ // container. This ensures O(lg n) bounds on find, insert, and erase, while
+ // avoiding the overheads of ordered containers most of the time.
+ //
+ // The implementation doesn't need the full generality of unordered_map,
+ // and it doesn't have it. More bells and whistles can be added as needed.
+ // Some implementation details:
+ // 1. The hash function has type hasher and the equality function
+ // equal_to<Key>. We inherit from hasher to save space
+ // (empty-base-class optimization).
+ // 2. The number of buckets is a power of two.
+ // 3. Buckets are converted to trees in pairs: if we convert bucket b then
+ // buckets b and b^1 will share a tree. Invariant: buckets b and b^1 have
+ // the same non-NULL value iff they are sharing a tree. (An alternative
+ // implementation strategy would be to have a tag bit per bucket.)
+ // 4. As is typical for hash_map and such, the Keys and Values are always
+ // stored in linked list nodes. Pointers to elements are never invalidated
+ // until the element is deleted.
+ // 5. The trees' payload type is pointer to linked-list node. Tree-converting
+ // a bucket doesn't copy Key-Value pairs.
+ // 6. Once we've tree-converted a bucket, it is never converted back. However,
+ // the items a tree contains may wind up assigned to trees or lists upon a
+ // rehash.
+ // 7. The code requires no C++ features from C++11 or later.
+ // 8. Mutations to a map do not invalidate the map's iterators, pointers to
+ // elements, or references to elements.
+ // 9. Except for erase(iterator), any non-const method can reorder iterators.
+ class InnerMap : private hasher {
+ public:
+ typedef value_type* Value;
+
+ InnerMap(size_type n, hasher h, Allocator alloc)
+ : hasher(h),
+ num_elements_(0),
+ seed_(Seed()),
+ table_(NULL),
+ alloc_(alloc) {
+ n = TableSize(n);
+ table_ = CreateEmptyTable(n);
+ num_buckets_ = index_of_first_non_null_ = n;
+ }
+
+ ~InnerMap() {
+ if (table_ != NULL) {
+ clear();
+ Dealloc<void*>(table_, num_buckets_);
+ }
+ }
+
+ private:
+ enum { kMinTableSize = 8 };
+
+ // Linked-list nodes, as one would expect for a chaining hash table.
+ struct Node {
+ KeyValuePair kv;
+ Node* next;
+ };
+
+ // This is safe only if the given pointer is known to point to a Key that is
+ // part of a Node.
+ static Node* NodePtrFromKeyPtr(Key* k) {
+ return reinterpret_cast<Node*>(k);
+ }
+
+ static Key* KeyPtrFromNodePtr(Node* node) { return &node->kv.key(); }
+
+ // Trees. The payload type is pointer to Key, so that we can query the tree
+ // with Keys that are not in any particular data structure. When we insert,
+ // though, the pointer is always pointing to a Key that is inside a Node.
+ struct KeyCompare {
+ bool operator()(const Key* n0, const Key* n1) const { return *n0 < *n1; }
+ };
+ typedef typename Allocator::template rebind<Key*>::other KeyPtrAllocator;
+ typedef std::set<Key*, KeyCompare, KeyPtrAllocator> Tree;
+
+ // iterator and const_iterator are instantiations of iterator_base.
+ template <typename KeyValueType>
+ class iterator_base {
+ public:
+ typedef KeyValueType& reference;
+ typedef KeyValueType* pointer;
+ typedef typename Tree::iterator TreeIterator;
+
+ // Invariants:
+ // node_ is always correct. This is handy because the most common
+ // operations are operator* and operator-> and they only use node_.
+ // When node_ is set to a non-NULL value, all the other non-const fields
+ // are updated to be correct also, but those fields can become stale
+ // if the underlying map is modified. When those fields are needed they
+ // are rechecked, and updated if necessary.
+ iterator_base() : node_(NULL) {}
+
+ explicit iterator_base(const InnerMap* m) : m_(m) {
+ SearchFrom(m->index_of_first_non_null_);
+ }
+
+ // Any iterator_base can convert to any other. This is overkill, and we
+ // rely on the enclosing class to use it wisely. The standard "iterator
+ // can convert to const_iterator" is OK but the reverse direction is not.
+ template <typename U>
+ explicit iterator_base(const iterator_base<U>& it)
+ : node_(it.node_),
+ m_(it.m_),
+ bucket_index_(it.bucket_index_),
+ tree_it_(it.tree_it_) {}
+
+ iterator_base(Node* n, const InnerMap* m, size_type index)
+ : node_(n),
+ m_(m),
+ bucket_index_(index) {}
+
+ iterator_base(TreeIterator tree_it, const InnerMap* m, size_type index)
+ : node_(NodePtrFromKeyPtr(*tree_it)),
+ m_(m),
+ bucket_index_(index),
+ tree_it_(tree_it) {
+ // Invariant: iterators that use tree_it_ have an even bucket_index_.
+ GOOGLE_DCHECK_EQ(bucket_index_ % 2, 0);
+ }
+
+ // Advance through buckets, looking for the first that isn't empty.
+ // If nothing non-empty is found then leave node_ == NULL.
+ void SearchFrom(size_type start_bucket) {
+ GOOGLE_DCHECK(m_->index_of_first_non_null_ == m_->num_buckets_ ||
+ m_->table_[m_->index_of_first_non_null_] != NULL);
+ node_ = NULL;
+ for (bucket_index_ = start_bucket; bucket_index_ < m_->num_buckets_;
+ bucket_index_++) {
+ if (m_->TableEntryIsNonEmptyList(bucket_index_)) {
+ node_ = static_cast<Node*>(m_->table_[bucket_index_]);
+ break;
+ } else if (m_->TableEntryIsTree(bucket_index_)) {
+ Tree* tree = static_cast<Tree*>(m_->table_[bucket_index_]);
+ GOOGLE_DCHECK(!tree->empty());
+ tree_it_ = tree->begin();
+ node_ = NodePtrFromKeyPtr(*tree_it_);
+ break;
+ }
+ }
+ }
+
+ reference operator*() const { return node_->kv; }
+ pointer operator->() const { return &(operator*()); }
+
+ friend bool operator==(const iterator_base& a, const iterator_base& b) {
+ return a.node_ == b.node_;
+ }
+ friend bool operator!=(const iterator_base& a, const iterator_base& b) {
+ return a.node_ != b.node_;
+ }
+
+ iterator_base& operator++() {
+ if (node_->next == NULL) {
+ const bool is_list = revalidate_if_necessary();
+ if (is_list) {
+ SearchFrom(bucket_index_ + 1);
+ } else {
+ GOOGLE_DCHECK_EQ(bucket_index_ & 1, 0);
+ Tree* tree = static_cast<Tree*>(m_->table_[bucket_index_]);
+ if (++tree_it_ == tree->end()) {
+ SearchFrom(bucket_index_ + 2);
+ } else {
+ node_ = NodePtrFromKeyPtr(*tree_it_);
+ }
+ }
+ } else {
+ node_ = node_->next;
+ }
+ return *this;
+ }
+
+ iterator_base operator++(int /* unused */) {
+ iterator_base tmp = *this;
+ ++*this;
+ return tmp;
+ }
+
+ // Assumes node_ and m_ are correct and non-NULL, but other fields may be
+ // stale. Fix them as needed. Then return true iff node_ points to a
+ // Node in a list.
+ bool revalidate_if_necessary() {
+ GOOGLE_DCHECK(node_ != NULL && m_ != NULL);
+ // Force bucket_index_ to be in range.
+ bucket_index_ &= (m_->num_buckets_ - 1);
+ // Common case: the bucket we think is relevant points to node_.
+ if (m_->table_[bucket_index_] == static_cast<void*>(node_))
+ return true;
+ // Less common: the bucket is a linked list with node_ somewhere in it,
+ // but not at the head.
+ if (m_->TableEntryIsNonEmptyList(bucket_index_)) {
+ Node* l = static_cast<Node*>(m_->table_[bucket_index_]);
+ while ((l = l->next) != NULL) {
+ if (l == node_) {
+ return true;
+ }
+ }
+ }
+ // Well, bucket_index_ still might be correct, but probably
+ // not. Revalidate just to be sure. This case is rare enough that we
+ // don't worry about potential optimizations, such as having a custom
+ // find-like method that compares Node* instead of const Key&.
+ iterator_base i(m_->find(*KeyPtrFromNodePtr(node_)));
+ bucket_index_ = i.bucket_index_;
+ tree_it_ = i.tree_it_;
+ return m_->TableEntryIsList(bucket_index_);
+ }
+
+ Node* node_;
+ const InnerMap* m_;
+ size_type bucket_index_;
+ TreeIterator tree_it_;
+ };
+
+ public:
+ typedef iterator_base<KeyValuePair> iterator;
+ typedef iterator_base<const KeyValuePair> const_iterator;
+
+ iterator begin() { return iterator(this); }
+ iterator end() { return iterator(); }
+ const_iterator begin() const { return const_iterator(this); }
+ const_iterator end() const { return const_iterator(); }
+
+ void clear() {
+ for (size_type b = 0; b < num_buckets_; b++) {
+ if (TableEntryIsNonEmptyList(b)) {
+ Node* node = static_cast<Node*>(table_[b]);
+ table_[b] = NULL;
+ do {
+ Node* next = node->next;
+ DestroyNode(node);
+ node = next;
+ } while (node != NULL);
+ } else if (TableEntryIsTree(b)) {
+ Tree* tree = static_cast<Tree*>(table_[b]);
+ GOOGLE_DCHECK(table_[b] == table_[b + 1] && (b & 1) == 0);
+ table_[b] = table_[b + 1] = NULL;
+ typename Tree::iterator tree_it = tree->begin();
+ do {
+ Node* node = NodePtrFromKeyPtr(*tree_it);
+ typename Tree::iterator next = tree_it;
+ ++next;
+ tree->erase(tree_it);
+ DestroyNode(node);
+ tree_it = next;
+ } while (tree_it != tree->end());
+ DestroyTree(tree);
+ b++;
+ }
+ }
+ num_elements_ = 0;
+ index_of_first_non_null_ = num_buckets_;
+ }
+
+ const hasher& hash_function() const { return *this; }
+
+ static size_type max_size() {
+ return static_cast<size_type>(1) << (sizeof(void**) >= 8 ? 60 : 28);
+ }
+ size_type size() const { return num_elements_; }
+ bool empty() const { return size() == 0; }
+
+ iterator find(const Key& k) { return iterator(FindHelper(k).first); }
+ const_iterator find(const Key& k) const { return FindHelper(k).first; }
+
+ // In traditional C++ style, this performs "insert if not present."
+ std::pair<iterator, bool> insert(const KeyValuePair& kv) {
+ std::pair<const_iterator, size_type> p = FindHelper(kv.key());
+ // Case 1: key was already present.
+ if (p.first.node_ != NULL)
+ return std::make_pair(iterator(p.first), false);
+ // Case 2: insert.
+ if (ResizeIfLoadIsOutOfRange(num_elements_ + 1)) {
+ p = FindHelper(kv.key());
+ }
+ const size_type b = p.second; // bucket number
+ Node* node = Alloc<Node>(1);
+ alloc_.construct(&node->kv, kv);
+ iterator result = InsertUnique(b, node);
+ ++num_elements_;
+ return std::make_pair(result, true);
+ }
+
+ // The same, but if an insertion is necessary then the value portion of the
+ // inserted key-value pair is left uninitialized.
+ std::pair<iterator, bool> insert(const Key& k) {
+ std::pair<const_iterator, size_type> p = FindHelper(k);
+ // Case 1: key was already present.
+ if (p.first.node_ != NULL)
+ return std::make_pair(iterator(p.first), false);
+ // Case 2: insert.
+ if (ResizeIfLoadIsOutOfRange(num_elements_ + 1)) {
+ p = FindHelper(k);
+ }
+ const size_type b = p.second; // bucket number
+ Node* node = Alloc<Node>(1);
+ typedef typename Allocator::template rebind<Key>::other KeyAllocator;
+ KeyAllocator(alloc_).construct(&node->kv.key(), k);
+ iterator result = InsertUnique(b, node);
+ ++num_elements_;
+ return std::make_pair(result, true);
+ }
+
+ Value& operator[](const Key& k) {
+ KeyValuePair kv(k, Value());
+ return insert(kv).first->value();
+ }
+
+ void erase(iterator it) {
+ GOOGLE_DCHECK_EQ(it.m_, this);
+ const bool is_list = it.revalidate_if_necessary();
+ size_type b = it.bucket_index_;
+ Node* const item = it.node_;
+ if (is_list) {
+ GOOGLE_DCHECK(TableEntryIsNonEmptyList(b));
+ Node* head = static_cast<Node*>(table_[b]);
+ head = EraseFromLinkedList(item, head);
+ table_[b] = static_cast<void*>(head);
+ } else {
+ GOOGLE_DCHECK(TableEntryIsTree(b));
+ Tree* tree = static_cast<Tree*>(table_[b]);
+ tree->erase(it.tree_it_);
+ if (tree->empty()) {
+ // Force b to be the minimum of b and b ^ 1. This is important
+ // only because we want index_of_first_non_null_ to be correct.
+ b &= ~static_cast<size_type>(1);
+ DestroyTree(tree);
+ table_[b] = table_[b + 1] = NULL;
+ }
+ }
+ DestroyNode(item);
+ --num_elements_;
+ if (GOOGLE_PREDICT_FALSE(b == index_of_first_non_null_)) {
+ while (index_of_first_non_null_ < num_buckets_ &&
+ table_[index_of_first_non_null_] == NULL) {
+ ++index_of_first_non_null_;
+ }
+ }
+ }
+
+ private:
+ std::pair<const_iterator, size_type> FindHelper(const Key& k) const {
+ size_type b = BucketNumber(k);
+ if (TableEntryIsNonEmptyList(b)) {
+ Node* node = static_cast<Node*>(table_[b]);
+ do {
+ if (IsMatch(*KeyPtrFromNodePtr(node), k)) {
+ return std::make_pair(const_iterator(node, this, b), b);
+ } else {
+ node = node->next;
+ }
+ } while (node != NULL);
+ } else if (TableEntryIsTree(b)) {
+ GOOGLE_DCHECK_EQ(table_[b], table_[b ^ 1]);
+ b &= ~static_cast<size_t>(1);
+ Tree* tree = static_cast<Tree*>(table_[b]);
+ Key* key = const_cast<Key*>(&k);
+ typename Tree::iterator tree_it = tree->find(key);
+ if (tree_it != tree->end()) {
+ return std::make_pair(const_iterator(tree_it, this, b), b);
+ }
+ }
+ return std::make_pair(end(), b);
+ }
+ // Insert the given Node in bucket b. If that would make bucket b too big,
+ // and bucket b is not a tree, create a tree for buckets b and b^1 to share.
+ // Requires count(*KeyPtrFromNodePtr(node)) == 0 and that b is the correct
+ // bucket. num_elements_ is not modified.
+ iterator InsertUnique(size_type b, Node* node) {
+ GOOGLE_DCHECK(index_of_first_non_null_ == num_buckets_ ||
+ table_[index_of_first_non_null_] != NULL);
+ // In practice, the code that led to this point may have already
+ // determined whether we are inserting into an empty list, a short list,
+ // or whatever. But it's probably cheap enough to recompute that here;
+ // it's likely that we're inserting into an empty or short list.
+ iterator result;
+ GOOGLE_DCHECK(find(*KeyPtrFromNodePtr(node)) == end());
+ if (TableEntryIsEmpty(b)) {
+ result = InsertUniqueInList(b, node);
+ } else if (TableEntryIsNonEmptyList(b)) {
+ if (GOOGLE_PREDICT_FALSE(TableEntryIsTooLong(b))) {
+ TreeConvert(b);
+ result = InsertUniqueInTree(b, node);
+ GOOGLE_DCHECK_EQ(result.bucket_index_, b & ~static_cast<size_type>(1));
+ } else {
+ // Insert into a pre-existing list. This case cannot modify
+ // index_of_first_non_null_, so we skip the code to update it.
+ return InsertUniqueInList(b, node);
+ }
+ } else {
+ // Insert into a pre-existing tree. This case cannot modify
+ // index_of_first_non_null_, so we skip the code to update it.
+ return InsertUniqueInTree(b, node);
+ }
+ index_of_first_non_null_ =
+ std::min(index_of_first_non_null_, result.bucket_index_);
+ return result;
+ }
+
+ // Helper for InsertUnique. Handles the case where bucket b is a
+ // not-too-long linked list.
+ iterator InsertUniqueInList(size_type b, Node* node) {
+ node->next = static_cast<Node*>(table_[b]);
+ table_[b] = static_cast<void*>(node);
+ return iterator(node, this, b);
+ }
+
+ // Helper for InsertUnique. Handles the case where bucket b points to a
+ // Tree.
+ iterator InsertUniqueInTree(size_type b, Node* node) {
+ GOOGLE_DCHECK_EQ(table_[b], table_[b ^ 1]);
+ // Maintain the invariant that node->next is NULL for all Nodes in Trees.
+ node->next = NULL;
+ return iterator(static_cast<Tree*>(table_[b])
+ ->insert(KeyPtrFromNodePtr(node))
+ .first,
+ this, b & ~static_cast<size_t>(1));
+ }
+
+ // Returns whether it did resize. Currently this is only used when
+ // num_elements_ increases, though it could be used in other situations.
+ // It checks for load too low as well as load too high: because any number
+ // of erases can occur between inserts, the load could be as low as 0 here.
+ // Resizing to a lower size is not always helpful, but failing to do so can
+ // destroy the expected big-O bounds for some operations. By having the
+ // policy that sometimes we resize down as well as up, clients can easily
+ // keep O(size()) = O(number of buckets) if they want that.
+ bool ResizeIfLoadIsOutOfRange(size_type new_size) {
+ const size_type kMaxMapLoadTimes16 = 12; // controls RAM vs CPU tradeoff
+ const size_type hi_cutoff = num_buckets_ * kMaxMapLoadTimes16 / 16;
+ const size_type lo_cutoff = hi_cutoff / 4;
+ // We don't care how many elements are in trees. If a lot are,
+ // we may resize even though there are many empty buckets. In
+ // practice, this seems fine.
+ if (GOOGLE_PREDICT_FALSE(new_size >= hi_cutoff)) {
+ if (num_buckets_ <= max_size() / 2) {
+ Resize(num_buckets_ * 2);
+ return true;
+ }
+ } else if (GOOGLE_PREDICT_FALSE(new_size <= lo_cutoff &&
+ num_buckets_ > kMinTableSize)) {
+ size_type lg2_of_size_reduction_factor = 1;
+ // It's possible we want to shrink a lot here... size() could even be 0.
+ // So, estimate how much to shrink by making sure we don't shrink so
+ // much that we would need to grow the table after a few inserts.
+ const size_type hypothetical_size = new_size * 5 / 4 + 1;
+ while ((hypothetical_size << lg2_of_size_reduction_factor) <
+ hi_cutoff) {
+ ++lg2_of_size_reduction_factor;
+ }
+ size_type new_num_buckets = std::max<size_type>(
+ kMinTableSize, num_buckets_ >> lg2_of_size_reduction_factor);
+ if (new_num_buckets != num_buckets_) {
+ Resize(new_num_buckets);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // Resize to the given number of buckets.
+ void Resize(size_t new_num_buckets) {
+ GOOGLE_DCHECK_GE(new_num_buckets, kMinTableSize);
+ void** const old_table = table_;
+ const size_type old_table_size = num_buckets_;
+ num_buckets_ = new_num_buckets;
+ table_ = CreateEmptyTable(num_buckets_);
+ const size_type start = index_of_first_non_null_;
+ index_of_first_non_null_ = num_buckets_;
+ for (size_type i = start; i < old_table_size; i++) {
+ if (TableEntryIsNonEmptyList(old_table, i)) {
+ TransferList(old_table, i);
+ } else if (TableEntryIsTree(old_table, i)) {
+ TransferTree(old_table, i++);
+ }
+ }
+ Dealloc<void*>(old_table, old_table_size);
+ }
+
+ void TransferList(void* const* table, size_type index) {
+ Node* node = static_cast<Node*>(table[index]);
+ do {
+ Node* next = node->next;
+ InsertUnique(BucketNumber(*KeyPtrFromNodePtr(node)), node);
+ node = next;
+ } while (node != NULL);
+ }
+
+ void TransferTree(void* const* table, size_type index) {
+ Tree* tree = static_cast<Tree*>(table[index]);
+ typename Tree::iterator tree_it = tree->begin();
+ do {
+ Node* node = NodePtrFromKeyPtr(*tree_it);
+ InsertUnique(BucketNumber(**tree_it), node);
+ } while (++tree_it != tree->end());
+ DestroyTree(tree);
+ }
+
+ Node* EraseFromLinkedList(Node* item, Node* head) {
+ if (head == item) {
+ return head->next;
+ } else {
+ head->next = EraseFromLinkedList(item, head->next);
+ return head;
+ }
+ }
+
+ bool TableEntryIsEmpty(size_type b) const {
+ return TableEntryIsEmpty(table_, b);
+ }
+ bool TableEntryIsNonEmptyList(size_type b) const {
+ return TableEntryIsNonEmptyList(table_, b);
+ }
+ bool TableEntryIsTree(size_type b) const {
+ return TableEntryIsTree(table_, b);
+ }
+ bool TableEntryIsList(size_type b) const {
+ return TableEntryIsList(table_, b);
+ }
+ static bool TableEntryIsEmpty(void* const* table, size_type b) {
+ return table[b] == NULL;
+ }
+ static bool TableEntryIsNonEmptyList(void* const* table, size_type b) {
+ return table[b] != NULL && table[b] != table[b ^ 1];
+ }
+ static bool TableEntryIsTree(void* const* table, size_type b) {
+ return !TableEntryIsEmpty(table, b) &&
+ !TableEntryIsNonEmptyList(table, b);
+ }
+ static bool TableEntryIsList(void* const* table, size_type b) {
+ return !TableEntryIsTree(table, b);
+ }
+
+ void TreeConvert(size_type b) {
+ GOOGLE_DCHECK(!TableEntryIsTree(b) && !TableEntryIsTree(b ^ 1));
+ typename Allocator::template rebind<Tree>::other tree_allocator(alloc_);
+ Tree* tree = tree_allocator.allocate(1);
+ // We want to use the three-arg form of construct, if it exists, but we
+ // create a temporary and use the two-arg construct that's known to exist.
+ // It's clunky, but the compiler should be able to generate more-or-less
+ // the same code.
+ tree_allocator.construct(tree,
+ Tree(KeyCompare(), KeyPtrAllocator(alloc_)));
+ // Now the tree is ready to use.
+ size_type count = CopyListToTree(b, tree) + CopyListToTree(b ^ 1, tree);
+ GOOGLE_DCHECK_EQ(count, tree->size());
+ table_[b] = table_[b ^ 1] = static_cast<void*>(tree);
+ }
+
+ // Copy a linked list in the given bucket to a tree.
+ // Returns the number of things it copied.
+ size_type CopyListToTree(size_type b, Tree* tree) {
+ size_type count = 0;
+ Node* node = static_cast<Node*>(table_[b]);
+ while (node != NULL) {
+ tree->insert(KeyPtrFromNodePtr(node));
+ ++count;
+ Node* next = node->next;
+ node->next = NULL;
+ node = next;
+ }
+ return count;
+ }
+
+ // Return whether table_[b] is a linked list that seems awfully long.
+ // Requires table_[b] to point to a non-empty linked list.
+ bool TableEntryIsTooLong(size_type b) {
+ const size_type kMaxLength = 8;
+ size_type count = 0;
+ Node* node = static_cast<Node*>(table_[b]);
+ do {
+ ++count;
+ node = node->next;
+ } while (node != NULL);
+ // Invariant: no linked list ever is more than kMaxLength in length.
+ GOOGLE_DCHECK_LE(count, kMaxLength);
+ return count >= kMaxLength;
+ }
+
+ size_type BucketNumber(const Key& k) const {
+ // We inherit from hasher, so one-arg operator() provides a hash function.
+ size_type h = (*const_cast<InnerMap*>(this))(k);
+ // To help prevent people from making assumptions about the hash function,
+ // we use the seed differently depending on NDEBUG. The default hash
+ // function, the seeding, etc., are all likely to change in the future.
+#ifndef NDEBUG
+ return (h * (seed_ | 1)) & (num_buckets_ - 1);
+#else
+ return (h + seed_) & (num_buckets_ - 1);
+#endif
+ }
+
+ bool IsMatch(const Key& k0, const Key& k1) const {
+ return std::equal_to<Key>()(k0, k1);
+ }
+
+ // Return a power of two no less than max(kMinTableSize, n).
+ // Assumes either n < kMinTableSize or n is a power of two.
+ size_type TableSize(size_type n) {
+ return n < kMinTableSize ? kMinTableSize : n;
+ }
+
+ // Use alloc_ to allocate an array of n objects of type U.
+ template <typename U>
+ U* Alloc(size_type n) {
+ typedef typename Allocator::template rebind<U>::other alloc_type;
+ return alloc_type(alloc_).allocate(n);
+ }
+
+ // Use alloc_ to deallocate an array of n objects of type U.
+ template <typename U>
+ void Dealloc(U* t, size_type n) {
+ typedef typename Allocator::template rebind<U>::other alloc_type;
+ alloc_type(alloc_).deallocate(t, n);
+ }
+
+ void DestroyNode(Node* node) {
+ alloc_.destroy(&node->kv);
+ Dealloc<Node>(node, 1);
+ }
+
+ void DestroyTree(Tree* tree) {
+ typename Allocator::template rebind<Tree>::other tree_allocator(alloc_);
+ tree_allocator.destroy(tree);
+ tree_allocator.deallocate(tree, 1);
+ }
+
+ void** CreateEmptyTable(size_type n) {
+ GOOGLE_DCHECK(n >= kMinTableSize);
+ GOOGLE_DCHECK_EQ(n & (n - 1), 0);
+ void** result = Alloc<void*>(n);
+ memset(result, 0, n * sizeof(result[0]));
+ return result;
+ }
+
+ // Return a randomish value.
+ size_type Seed() const {
+ // random_device can throw, so avoid it unless we are compiling with
+ // exceptions enabled.
+#if __cpp_exceptions && LANG_CXX11
+ try {
+ std::random_device rd;
+ std::knuth_b knuth(rd());
+ std::uniform_int_distribution<size_type> u;
+ return u(knuth);
+ } catch (...) { }
+#endif
+ size_type s = static_cast<size_type>(reinterpret_cast<uintptr_t>(this));
+#if defined(__x86_64__) && defined(__GNUC__)
+ uint32 hi, lo;
+ asm("rdtsc" : "=a" (lo), "=d" (hi));
+ s += ((static_cast<uint64>(hi) << 32) | lo);
+#endif
+ return s;
+ }
+
+ size_type num_elements_;
+ size_type num_buckets_;
+ size_type seed_;
+ size_type index_of_first_non_null_;
+ void** table_; // an array with num_buckets_ entries
+ Allocator alloc_;
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(InnerMap);
+ }; // end of class InnerMap
+
+ typedef hash_map<Key, value_type*, hash<Key>, equal_to<Key>,
+ MapAllocator<std::pair<const Key, MapPair<Key, T>*> > >
+ DeprecatedInnerMap;
+
+ public:
// Iterators
+ class iterator_base {
+ public:
+ // We support "old style" and "new style" iterators for now. This is
+ // temporary. Also, for "iterator()" we have an unknown category.
+ // TODO(gpike): get rid of this.
+ enum IteratorStyle { kUnknown, kOld, kNew };
+ explicit iterator_base(IteratorStyle style) : iterator_style_(style) {}
+
+ bool OldStyle() const {
+ GOOGLE_DCHECK_NE(iterator_style_, kUnknown);
+ return iterator_style_ == kOld;
+ }
+ bool UnknownStyle() const {
+ return iterator_style_ == kUnknown;
+ }
+ bool SameStyle(const iterator_base& other) const {
+ return iterator_style_ == other.iterator_style_;
+ }
+
+ private:
+ IteratorStyle iterator_style_;
+ };
+
class const_iterator
- : public std::iterator<std::forward_iterator_tag, value_type, ptrdiff_t,
+ : private iterator_base,
+ public std::iterator<std::forward_iterator_tag, value_type, ptrdiff_t,
const value_type*, const value_type&> {
- typedef typename hash_map<Key, value_type*, hash<Key>, equal_to<Key>,
- Allocator>::const_iterator InnerIt;
+ typedef typename InnerMap::const_iterator InnerIt;
+ typedef typename DeprecatedInnerMap::const_iterator DeprecatedInnerIt;
public:
- const_iterator() {}
- explicit const_iterator(const InnerIt& it) : it_(it) {}
+ const_iterator() : iterator_base(iterator_base::kUnknown) {}
+ explicit const_iterator(const DeprecatedInnerIt& dit)
+ : iterator_base(iterator_base::kOld), dit_(dit) {}
+ explicit const_iterator(const InnerIt& it)
+ : iterator_base(iterator_base::kNew), it_(it) {}
- const_reference operator*() const { return *it_->second; }
- const_pointer operator->() const { return it_->second; }
+ const_iterator(const const_iterator& other)
+ : iterator_base(other), it_(other.it_), dit_(other.dit_) {}
+
+ const_reference operator*() const {
+ return this->OldStyle() ? *dit_->second : *it_->value();
+ }
+ const_pointer operator->() const { return &(operator*()); }
const_iterator& operator++() {
- ++it_;
+ if (this->OldStyle())
+ ++dit_;
+ else
+ ++it_;
return *this;
}
- const_iterator operator++(int) { return const_iterator(it_++); }
+ const_iterator operator++(int) {
+ return this->OldStyle() ? const_iterator(dit_++) : const_iterator(it_++);
+ }
friend bool operator==(const const_iterator& a, const const_iterator& b) {
- return a.it_ == b.it_;
+ if (!a.SameStyle(b)) return false;
+ if (a.UnknownStyle()) return true;
+ return a.OldStyle() ? (a.dit_ == b.dit_) : (a.it_ == b.it_);
}
friend bool operator!=(const const_iterator& a, const const_iterator& b) {
- return a.it_ != b.it_;
+ return !(a == b);
}
private:
InnerIt it_;
+ DeprecatedInnerIt dit_;
};
- class iterator : public std::iterator<std::forward_iterator_tag, value_type> {
- typedef typename hash_map<Key, value_type*, hasher, equal_to<Key>,
- Allocator>::iterator InnerIt;
+ class iterator : private iterator_base,
+ public std::iterator<std::forward_iterator_tag, value_type> {
+ typedef typename InnerMap::iterator InnerIt;
+ typedef typename DeprecatedInnerMap::iterator DeprecatedInnerIt;
public:
- iterator() {}
- explicit iterator(const InnerIt& it) : it_(it) {}
-
- reference operator*() const { return *it_->second; }
- pointer operator->() const { return it_->second; }
+ iterator() : iterator_base(iterator_base::kUnknown) {}
+ explicit iterator(const DeprecatedInnerIt& dit)
+ : iterator_base(iterator_base::kOld), dit_(dit) {}
+ explicit iterator(const InnerIt& it)
+ : iterator_base(iterator_base::kNew), it_(it) {}
+
+ reference operator*() const {
+ return this->OldStyle() ? *dit_->second : *it_->value();
+ }
+ pointer operator->() const { return &(operator*()); }
iterator& operator++() {
- ++it_;
+ if (this->OldStyle())
+ ++dit_;
+ else
+ ++it_;
return *this;
}
- iterator operator++(int) { return iterator(it_++); }
+ iterator operator++(int) {
+ return this->OldStyle() ? iterator(dit_++) : iterator(it_++);
+ }
- // Implicitly convertible to const_iterator.
- operator const_iterator() const { return const_iterator(it_); }
+ // Allow implicit conversion to const_iterator.
+ operator const_iterator() const {
+ return this->OldStyle() ?
+ const_iterator(typename DeprecatedInnerMap::const_iterator(dit_)) :
+ const_iterator(typename InnerMap::const_iterator(it_));
+ }
friend bool operator==(const iterator& a, const iterator& b) {
- return a.it_ == b.it_;
+ if (!a.SameStyle(b)) return false;
+ if (a.UnknownStyle()) return true;
+ return a.OldStyle() ? a.dit_ == b.dit_ : a.it_ == b.it_;
}
friend bool operator!=(const iterator& a, const iterator& b) {
- return a.it_ != b.it_;
+ return !(a == b);
}
private:
friend class Map;
+
InnerIt it_;
+ DeprecatedInnerIt dit_;
};
- 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()); }
+ iterator begin() {
+ return old_style_ ? iterator(deprecated_elements_->begin())
+ : iterator(elements_->begin());
+ }
+ iterator end() {
+ return old_style_ ? iterator(deprecated_elements_->end())
+ : iterator(elements_->end());
+ }
+ const_iterator begin() const {
+ return old_style_ ? const_iterator(deprecated_elements_->begin())
+ : const_iterator(iterator(elements_->begin()));
+ }
+ const_iterator end() const {
+ return old_style_ ? const_iterator(deprecated_elements_->end())
+ : const_iterator(iterator(elements_->end()));
+ }
const_iterator cbegin() const { return begin(); }
const_iterator cend() const { return end(); }
// Capacity
- size_type size() const { return elements_.size(); }
- bool empty() const { return elements_.empty(); }
+ size_type size() const {
+ return old_style_ ? deprecated_elements_->size() : elements_->size();
+ }
+ bool empty() const { return size() == 0; }
// Element access
T& operator[](const key_type& key) {
- value_type** value = &elements_[key];
+ value_type** value =
+ old_style_ ? &(*deprecated_elements_)[key] : &(*elements_)[key];
if (*value == NULL) {
*value = CreateValueTypeInternal(key);
internal::MapValueInitializer<google::protobuf::is_proto_enum<T>::value,
@@ -693,13 +1525,16 @@ class Map {
// Lookup
size_type count(const key_type& key) const {
- return elements_.count(key);
+ if (find(key) != end()) assert(key == find(key)->first);
+ return find(key) == end() ? 0 : 1;
}
const_iterator find(const key_type& key) const {
- return const_iterator(elements_.find(key));
+ return old_style_ ? const_iterator(deprecated_elements_->find(key))
+ : const_iterator(iterator(elements_->find(key)));
}
iterator find(const key_type& key) {
- return iterator(elements_.find(key));
+ return old_style_ ? iterator(deprecated_elements_->find(key))
+ : iterator(elements_->find(key));
}
std::pair<const_iterator, const_iterator> equal_range(
const key_type& key) const {
@@ -723,13 +1558,22 @@ class Map {
// insert
std::pair<iterator, bool> insert(const value_type& value) {
- iterator it = find(value.first);
- if (it != end()) {
- return std::pair<iterator, bool>(it, false);
+ if (old_style_) {
+ iterator it = find(value.first);
+ if (it != end()) {
+ return std::pair<iterator, bool>(it, false);
+ } else {
+ return std::pair<iterator, bool>(
+ iterator(deprecated_elements_->insert(std::pair<Key, value_type*>(
+ value.first, CreateValueTypeInternal(value))).first), true);
+ }
} else {
- return std::pair<iterator, bool>(
- iterator(elements_.insert(std::pair<Key, value_type*>(
- value.first, CreateValueTypeInternal(value))).first), true);
+ std::pair<typename InnerMap::iterator, bool> p =
+ elements_->insert(value.first);
+ if (p.second) {
+ p.first->value() = CreateValueTypeInternal(value);
+ }
+ return std::pair<iterator, bool>(iterator(p.first), p.second);
}
}
template <class InputIt>
@@ -742,34 +1586,31 @@ class Map {
}
}
- // Erase
+ // Erase and clear
size_type erase(const key_type& key) {
- typename hash_map<Key, value_type*, hash<Key>, equal_to<Key>,
- Allocator>::iterator it = elements_.find(key);
- if (it == elements_.end()) {
+ iterator it = find(key);
+ if (it == end()) {
return 0;
} else {
- if (arena_ == NULL) delete it->second;
- elements_.erase(it);
+ erase(it);
return 1;
}
}
- void erase(iterator pos) {
- if (arena_ == NULL) delete pos.it_->second;
- elements_.erase(pos.it_);
+ iterator erase(iterator pos) {
+ if (arena_ == NULL) delete pos.operator->();
+ iterator i = pos++;
+ if (old_style_)
+ deprecated_elements_->erase(i.dit_);
+ else
+ elements_->erase(i.it_);
+ return pos;
}
void erase(iterator first, iterator last) {
- for (iterator it = first; it != last;) {
- if (arena_ == NULL) delete it.it_->second;
- elements_.erase((it++).it_);
- }
- }
- void clear() {
- for (iterator it = begin(); it != end(); ++it) {
- if (arena_ == NULL) delete it.it_->second;
+ while (first != last) {
+ first = erase(first);
}
- elements_.clear();
}
+ void clear() { erase(begin(), end()); }
// Assign
Map& operator=(const Map& other) {
@@ -780,6 +1621,31 @@ class Map {
return *this;
}
+ void swap(Map& other) {
+ if (arena_ == other.arena_ && old_style_ == other.old_style_) {
+ std::swap(default_enum_value_, other.default_enum_value_);
+ if (old_style_) {
+ std::swap(deprecated_elements_, other.deprecated_elements_);
+ } else {
+ std::swap(elements_, 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
+ // be replaced with the fast-path swap above.
+ Map copy = *this;
+ *this = other;
+ other = copy;
+ }
+ }
+
+ // 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 old_style_ ? deprecated_elements_->hash_function()
+ : elements_->hash_function();
+ }
+
private:
// Set default enum value only for proto2 map field whose value is enum type.
void SetDefaultEnumValue(int default_enum_value) {
@@ -814,9 +1680,15 @@ class Map {
}
Arena* arena_;
- Allocator allocator_;
- hash_map<Key, value_type*, hash<Key>, equal_to<Key>, Allocator> elements_;
int default_enum_value_;
+ // The following is a tagged union because we support two map styles
+ // for now.
+ // TODO(gpike): get rid of the old style.
+ const bool old_style_;
+ union {
+ InnerMap* elements_;
+ DeprecatedInnerMap* deprecated_elements_;
+ };
friend class ::google::protobuf::Arena;
typedef void InternalArenaConstructable_;
@@ -837,6 +1709,12 @@ struct hash<google::protobuf::MapKey> {
size_t
operator()(const google::protobuf::MapKey& map_key) const {
switch (map_key.type()) {
+ case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
+ case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT:
+ case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
+ case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
+ GOOGLE_LOG(FATAL) << "Unsupported";
+ break;
case google::protobuf::FieldDescriptor::CPPTYPE_STRING:
return hash<string>()(map_key.GetStringValue());
case google::protobuf::FieldDescriptor::CPPTYPE_INT64:
@@ -849,12 +1727,6 @@ struct hash<google::protobuf::MapKey> {
return hash< ::google::protobuf::uint32>()(map_key.GetUInt32Value());
case google::protobuf::FieldDescriptor::CPPTYPE_BOOL:
return hash<bool>()(map_key.GetBoolValue());
- case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
- case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT:
- case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
- case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
- GOOGLE_LOG(FATAL) << "Can't get here.";
- return 0;
}
GOOGLE_LOG(FATAL) << "Can't get here.";
return 0;
@@ -862,27 +1734,7 @@ struct hash<google::protobuf::MapKey> {
bool
operator()(const google::protobuf::MapKey& map_key1,
const google::protobuf::MapKey& map_key2) const {
- switch (map_key1.type()) {
-#define COMPARE_CPPTYPE(CPPTYPE, CPPTYPE_METHOD) \
- case google::protobuf::FieldDescriptor::CPPTYPE_##CPPTYPE: \
- return map_key1.Get##CPPTYPE_METHOD##Value() < \
- map_key2.Get##CPPTYPE_METHOD##Value();
- COMPARE_CPPTYPE(STRING, String)
- COMPARE_CPPTYPE(INT64, Int64)
- COMPARE_CPPTYPE(INT32, Int32)
- COMPARE_CPPTYPE(UINT64, UInt64)
- COMPARE_CPPTYPE(UINT32, UInt32)
- COMPARE_CPPTYPE(BOOL, Bool)
-#undef COMPARE_CPPTYPE
- case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
- case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT:
- case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
- case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
- GOOGLE_LOG(FATAL) << "Can't get here.";
- return true;
- }
- GOOGLE_LOG(FATAL) << "Can't get here.";
- return true;
+ return map_key1 < map_key2;
}
};
GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_END
diff --git a/src/google/protobuf/map_entry.h b/src/google/protobuf/map_entry.h
index 987c4e29..e87eda64 100644
--- a/src/google/protobuf/map_entry.h
+++ b/src/google/protobuf/map_entry.h
@@ -83,7 +83,7 @@ class LIBPROTOBUF_EXPORT MapEntryBase : public Message {
// reflection, its in-memory type is the same as generated message with the same
// fields. However, in order to decide the in-memory type of key/value, we need
// to know both their cpp type in generated api and proto type. In
-// implmentation, all in-memory types have related wire format functions to
+// implementation, all in-memory types have related wire format functions to
// support except ArenaStringPtr. Therefore, we need to define another type with
// supporting wire format functions. Since this type is only used as return type
// of MapEntry accessors, it's named MapEntry accessor type.
@@ -166,8 +166,10 @@ class MapEntry : public MapEntryBase {
entry_lite_.SerializeWithCachedSizes(output);
}
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
- return entry_lite_.SerializeWithCachedSizesToArray(output);
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(bool deterministic,
+ ::google::protobuf::uint8* output) const {
+ return entry_lite_.InternalSerializeWithCachedSizesToArray(deterministic,
+ output);
}
int GetCachedSize() const {
diff --git a/src/google/protobuf/map_entry_lite.h b/src/google/protobuf/map_entry_lite.h
index 7cdf1b93..4dedfd57 100644
--- a/src/google/protobuf/map_entry_lite.h
+++ b/src/google/protobuf/map_entry_lite.h
@@ -31,6 +31,7 @@
#ifndef GOOGLE_PROTOBUF_MAP_ENTRY_LITE_H__
#define GOOGLE_PROTOBUF_MAP_ENTRY_LITE_H__
+#include <assert.h>
#include <google/protobuf/map_type_handler.h>
#include <google/protobuf/wire_format_lite_inl.h>
@@ -54,6 +55,38 @@ class MapFieldLite;
namespace protobuf {
namespace internal {
+// MoveHelper::Move is used to set *dest. It copies *src, or moves it (in
+// the C++11 sense), or swaps it. *src is left in a sane state for
+// subsequent destruction, but shouldn't be used for anything.
+template <bool is_enum, bool is_message, bool is_stringlike, typename T>
+struct MoveHelper { // primitives
+ static void Move(T* src, T* dest) { *dest = *src; }
+};
+
+template <bool is_message, bool is_stringlike, typename T>
+struct MoveHelper<true, is_message, is_stringlike, T> { // enums
+ static void Move(T* src, T* dest) { *dest = *src; }
+ // T is an enum here, so allow conversions to and from int.
+ static void Move(T* src, int* dest) { *dest = static_cast<int>(*src); }
+ static void Move(int* src, T* dest) { *dest = static_cast<T>(*src); }
+};
+
+template <bool is_stringlike, typename T>
+struct MoveHelper<false, true, is_stringlike, T> { // messages
+ static void Move(T* src, T* dest) { dest->Swap(src); }
+};
+
+template <typename T>
+struct MoveHelper<false, false, true, T> { // strings and similar
+ static void Move(T* src, T* dest) {
+#if __cplusplus >= 201103L
+ *dest = std::move(*src);
+#else
+ dest->swap(*src);
+#endif
+ }
+};
+
// MapEntryLite is used to implement parsing and serialization of map for lite
// runtime.
template <typename Key, typename Value,
@@ -180,11 +213,17 @@ class MapEntryLite : public MessageLite {
ValueTypeHandler::Write(kValueFieldNumber, value(), output);
}
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
- output = KeyTypeHandler::WriteToArray(kKeyFieldNumber, key(), output);
- output = ValueTypeHandler::WriteToArray(kValueFieldNumber, value(), output);
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(bool deterministic,
+ ::google::protobuf::uint8* output) const {
+ output = KeyTypeHandler::InternalWriteToArray(kKeyFieldNumber, key(),
+ deterministic, output);
+ output = ValueTypeHandler::InternalWriteToArray(kValueFieldNumber, value(),
+ deterministic, output);
return output;
}
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const {
int size = 0;
@@ -271,6 +310,108 @@ class MapEntryLite : public MessageLite {
arena, key, value);
}
+ // Parsing using MergePartialFromCodedStream, above, is not as
+ // efficient as it could be. This helper class provides a speedier way.
+ template <typename MapField, typename Map>
+ class Parser {
+ public:
+ explicit Parser(MapField* mf) : mf_(mf), map_(mf->MutableMap()) {}
+
+ // This does what the typical MergePartialFromCodedStream() is expected to
+ // do, with the additional side-effect that if successful (i.e., if true is
+ // going to be its return value) it inserts the key-value pair into map_.
+ bool MergePartialFromCodedStream(::google::protobuf::io::CodedInputStream* input) {
+ // Look for the expected thing: a key and then a value. If it fails,
+ // invoke the enclosing class's MergePartialFromCodedStream, or return
+ // false if that would be pointless.
+ if (input->ExpectTag(kKeyTag)) {
+ if (!KeyTypeHandler::Read(input, &key_)) {
+ return false;
+ }
+ // Peek at the next byte to see if it is kValueTag. If not, bail out.
+ const void* data;
+ int size;
+ input->GetDirectBufferPointerInline(&data, &size);
+ // We could use memcmp here, but we don't bother. The tag is one byte.
+ assert(kTagSize == 1);
+ if (size > 0 && *reinterpret_cast<const char*>(data) == kValueTag) {
+ typename Map::size_type size = map_->size();
+ value_ptr_ = &(*map_)[key_];
+ if (GOOGLE_PREDICT_TRUE(size != map_->size())) {
+ // We created a new key-value pair. Fill in the value.
+ typedef
+ typename MapIf<ValueTypeHandler::kIsEnum, int*, Value*>::type T;
+ input->Skip(kTagSize); // Skip kValueTag.
+ if (!ValueTypeHandler::Read(input,
+ reinterpret_cast<T>(value_ptr_))) {
+ map_->erase(key_); // Failure! Undo insertion.
+ return false;
+ }
+ if (input->ExpectAtEnd()) return true;
+ return ReadBeyondKeyValuePair(input);
+ }
+ }
+ } else {
+ key_ = Key();
+ }
+
+ entry_.reset(mf_->NewEntry());
+ *entry_->mutable_key() = key_;
+ if (!entry_->MergePartialFromCodedStream(input)) return false;
+ return UseKeyAndValueFromEntry();
+ }
+
+ const Key& key() const { return key_; }
+ const Value& value() const { return *value_ptr_; }
+
+ private:
+ bool UseKeyAndValueFromEntry() GOOGLE_ATTRIBUTE_COLD {
+ // Update key_ in case we need it later (because key() is called).
+ // This is potentially inefficient, especially if the key is
+ // expensive to copy (e.g., a long string), but this is a cold
+ // path, so it's not a big deal.
+ key_ = entry_->key();
+ value_ptr_ = &(*map_)[key_];
+ MoveHelper<ValueTypeHandler::kIsEnum,
+ ValueTypeHandler::kIsMessage,
+ ValueTypeHandler::kWireType ==
+ WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
+ Value>::Move(entry_->mutable_value(), value_ptr_);
+ if (entry_->GetArena() != NULL) entry_.release();
+ return true;
+ }
+
+ // After reading a key and value successfully, and inserting that data
+ // into map_, we are not at the end of the input. This is unusual, but
+ // allowed by the spec.
+ bool ReadBeyondKeyValuePair(::google::protobuf::io::CodedInputStream* input)
+ GOOGLE_ATTRIBUTE_COLD {
+ typedef MoveHelper<KeyTypeHandler::kIsEnum,
+ KeyTypeHandler::kIsMessage,
+ KeyTypeHandler::kWireType ==
+ WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
+ Key> KeyMover;
+ typedef MoveHelper<ValueTypeHandler::kIsEnum,
+ ValueTypeHandler::kIsMessage,
+ ValueTypeHandler::kWireType ==
+ WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
+ Value> ValueMover;
+ entry_.reset(mf_->NewEntry());
+ ValueMover::Move(value_ptr_, entry_->mutable_value());
+ map_->erase(key_);
+ KeyMover::Move(&key_, entry_->mutable_key());
+ if (!entry_->MergePartialFromCodedStream(input)) return false;
+ return UseKeyAndValueFromEntry();
+ }
+
+ MapField* const mf_;
+ Map* const map_;
+ Key key_;
+ Value* value_ptr_;
+ // On the fast path entry_ is not used.
+ google::protobuf::scoped_ptr<MapEntryLite> entry_;
+ };
+
protected:
void set_has_key() { _has_bits_[0] |= 0x00000001u; }
bool has_key() const { return (_has_bits_[0] & 0x00000001u) != 0; }
@@ -394,6 +535,32 @@ class MapEntryLite : public MessageLite {
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapEntryLite);
};
+// Helpers for deterministic serialization =============================
+
+// This struct can be used with any generic sorting algorithm. If the Key
+// type is relatively small and easy to copy then copying Keys into an
+// array of SortItems can be beneficial. Then all the data the sorting
+// algorithm needs to touch is in that one array.
+template <typename Key, typename PtrToKeyValuePair> struct SortItem {
+ SortItem() {}
+ explicit SortItem(PtrToKeyValuePair p) : first(p->first), second(p) {}
+
+ Key first;
+ PtrToKeyValuePair second;
+};
+
+template <typename T> struct CompareByFirstField {
+ bool operator()(const T& a, const T& b) const {
+ return a.first < b.first;
+ }
+};
+
+template <typename T> struct CompareByDerefFirst {
+ bool operator()(const T& a, const T& b) const {
+ return a->first < b->first;
+ }
+};
+
} // namespace internal
} // namespace protobuf
diff --git a/src/google/protobuf/map_field.cc b/src/google/protobuf/map_field.cc
index eddc95c4..49f91818 100644
--- a/src/google/protobuf/map_field.cc
+++ b/src/google/protobuf/map_field.cc
@@ -178,18 +178,19 @@ bool DynamicMapField::ContainsMapKey(
return iter != map.end();
}
-bool DynamicMapField::InsertMapValue(
+bool DynamicMapField::InsertOrLookupMapValue(
const MapKey& map_key, MapValueRef* val) {
- bool result = false;
-
- MapValueRef& map_val = (*MutableMap())[map_key];
- // If map_val.data_ is not set, it is newly inserted by map_[map_key].
- if (map_val.data_ == NULL) {
- result = true;
+ // Always use mutable map because users may change the map value by
+ // MapValueRef.
+ Map<MapKey, MapValueRef>* map = MutableMap();
+ Map<MapKey, MapValueRef>::iterator iter = map->find(map_key);
+ if (iter == map->end()) {
+ // Insert
+ MapValueRef& map_val = (*map)[map_key];
const FieldDescriptor* val_des =
default_entry_->GetDescriptor()->FindFieldByName("value");
map_val.SetType(val_des->cpp_type());
- // Allocate momery for the inserted MapValueRef, and initialize to
+ // Allocate memory for the inserted MapValueRef, and initialize to
// default value.
switch (val_des->cpp_type()) {
#define HANDLE_TYPE(CPPTYPE, TYPE) \
@@ -216,9 +217,13 @@ bool DynamicMapField::InsertMapValue(
break;
}
}
+ val->CopyFrom(map_val);
+ return true;
}
- val->CopyFrom(map_val);
- return result;
+ // map_key is already in the map. Make sure (*map)[map_key] is not called.
+ // [] may reorder the map and iterators.
+ val->CopyFrom(iter->second);
+ return false;
}
bool DynamicMapField::DeleteMapValue(const MapKey& map_key) {
diff --git a/src/google/protobuf/map_field.h b/src/google/protobuf/map_field.h
index 9130166b..d6af8532 100644
--- a/src/google/protobuf/map_field.h
+++ b/src/google/protobuf/map_field.h
@@ -54,7 +54,7 @@ class ContendedMapCleanTest;
class GeneratedMessageReflection;
class MapFieldAccessor;
-// This class provides accesss to map field using reflection, which is the same
+// This class provides access to map field using reflection, which is the same
// as those provided for RepeatedPtrField<Message>. It is used for internal
// reflection implentation only. Users should never use this directly.
class LIBPROTOBUF_EXPORT MapFieldBase {
@@ -87,7 +87,8 @@ class LIBPROTOBUF_EXPORT MapFieldBase {
// Pure virtual map APIs for Map Reflection.
virtual bool ContainsMapKey(const MapKey& map_key) const = 0;
- virtual bool InsertMapValue(const MapKey& map_key, MapValueRef* val) = 0;
+ virtual bool InsertOrLookupMapValue(
+ const MapKey& map_key, MapValueRef* val) = 0;
virtual bool DeleteMapValue(const MapKey& map_key) = 0;
virtual bool EqualIterator(const MapIterator& a,
const MapIterator& b) const = 0;
@@ -207,7 +208,7 @@ class TypeDefinedMapFieldBase : public MapFieldBase {
virtual void SetMapIteratorValue(MapIterator* map_iter) const = 0;
};
-// This class provides accesss to map field using generated api. It is used for
+// This class provides access to map field using generated api. It is used for
// internal generated message implentation only. Users should never use this
// directly.
template <typename Key, typename T,
@@ -251,7 +252,7 @@ class MapField : public TypeDefinedMapFieldBase<Key, T>,
// Implement MapFieldBase
bool ContainsMapKey(const MapKey& map_key) const;
- bool InsertMapValue(const MapKey& map_key, MapValueRef* val);
+ bool InsertOrLookupMapValue(const MapKey& map_key, MapValueRef* val);
bool DeleteMapValue(const MapKey& map_key);
// Accessors
@@ -302,7 +303,7 @@ class LIBPROTOBUF_EXPORT DynamicMapField: public TypeDefinedMapFieldBase<MapKey,
// Implement MapFieldBase
bool ContainsMapKey(const MapKey& map_key) const;
- bool InsertMapValue(const MapKey& map_key, MapValueRef* val);
+ bool InsertOrLookupMapValue(const MapKey& map_key, MapValueRef* val);
bool DeleteMapValue(const MapKey& map_key);
const Map<MapKey, MapValueRef>& GetMap() const;
diff --git a/src/google/protobuf/map_field_inl.h b/src/google/protobuf/map_field_inl.h
index f116697c..01c9b89a 100644
--- a/src/google/protobuf/map_field_inl.h
+++ b/src/google/protobuf/map_field_inl.h
@@ -262,16 +262,22 @@ template <typename Key, typename T,
WireFormatLite::FieldType kValueFieldType,
int default_enum_value>
bool MapField<Key, T, kKeyFieldType, kValueFieldType,
- default_enum_value>::InsertMapValue(const MapKey& map_key,
- MapValueRef* val) {
+ default_enum_value>::InsertOrLookupMapValue(
+ const MapKey& map_key,
+ MapValueRef* val) {
+ // Always use mutable map because users may change the map value by
+ // MapValueRef.
Map<Key, T>* map = MutableMap();
- bool result = false;
const Key& key = UnwrapMapKey<Key>(map_key);
- if (map->end() == map->find(key)) {
- result = true;
+ typename Map<Key, T>::iterator iter = map->find(key);
+ if (map->end() == iter) {
+ val->SetValue(&((*map)[key]));
+ return true;
}
- val->SetValue(&((*map)[key]));
- return result;
+ // Key is already in the map. Make sure (*map)[key] is not called.
+ // [] may reorder the map and iterators.
+ val->SetValue(&(iter->second));
+ return false;
}
template <typename Key, typename T,
diff --git a/src/google/protobuf/map_field_lite.h b/src/google/protobuf/map_field_lite.h
index 860dae55..a9f30f59 100644
--- a/src/google/protobuf/map_field_lite.h
+++ b/src/google/protobuf/map_field_lite.h
@@ -38,7 +38,7 @@ namespace google {
namespace protobuf {
namespace internal {
-// This class provides accesss to map field using generated api. It is used for
+// This class provides access to map field using generated api. It is used for
// internal generated message implentation only. Users should never use this
// directly.
template <typename Key, typename T,
diff --git a/src/google/protobuf/map_field_test.cc b/src/google/protobuf/map_field_test.cc
index 2ff1d6bb..dd5061c4 100644
--- a/src/google/protobuf/map_field_test.cc
+++ b/src/google/protobuf/map_field_test.cc
@@ -47,8 +47,8 @@
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/wire_format_lite_inl.h>
#include <gtest/gtest.h>
-
namespace google {
+
namespace protobuf {
namespace internal {
@@ -78,7 +78,7 @@ class MapFieldBaseStub : public MapFieldBase {
bool ContainsMapKey(const MapKey& map_key) const {
return false;
}
- bool InsertMapValue(const MapKey& map_key, MapValueRef* val) {
+ bool InsertOrLookupMapValue(const MapKey& map_key, MapValueRef* val) {
return false;
}
bool DeleteMapValue(const MapKey& map_key) {
diff --git a/src/google/protobuf/map_lite_unittest.proto b/src/google/protobuf/map_lite_unittest.proto
index 0592dd7a..0135fff3 100644
--- a/src/google/protobuf/map_lite_unittest.proto
+++ b/src/google/protobuf/map_lite_unittest.proto
@@ -81,7 +81,7 @@ message TestArenaMapLite {
map_int32_foreign_message_no_arena = 18;
}
-// Test embeded message with required fields
+// Test embedded message with required fields
message TestRequiredMessageMapLite {
map<int32, TestRequiredLite> map_field = 1;
}
diff --git a/src/google/protobuf/map_proto2_unittest.proto b/src/google/protobuf/map_proto2_unittest.proto
index 916cc546..ddc2a582 100644
--- a/src/google/protobuf/map_proto2_unittest.proto
+++ b/src/google/protobuf/map_proto2_unittest.proto
@@ -64,3 +64,23 @@ message TestEnumMapPlusExtra {
message TestImportEnumMap {
map<int32, protobuf_unittest_import.ImportEnumForMap> import_enum_amp = 1;
}
+
+message TestIntIntMap {
+ map<int32, int32> m = 1;
+}
+
+// Test all key types: string, plus the non-floating-point scalars.
+message TestMaps {
+ map<int32, TestIntIntMap> m_int32 = 1;
+ map<int64, TestIntIntMap> m_int64 = 2;
+ map<uint32, TestIntIntMap> m_uint32 = 3;
+ map<uint64, TestIntIntMap> m_uint64 = 4;
+ map<sint32, TestIntIntMap> m_sint32 = 5;
+ map<sint64, TestIntIntMap> m_sint64 = 6;
+ map<fixed32, TestIntIntMap> m_fixed32 = 7;
+ map<fixed64, TestIntIntMap> m_fixed64 = 8;
+ map<sfixed32, TestIntIntMap> m_sfixed32 = 9;
+ map<sfixed64, TestIntIntMap> m_sfixed64 = 10;
+ map<bool, TestIntIntMap> m_bool = 11;
+ map<string, TestIntIntMap> m_string = 12;
+}
diff --git a/src/google/protobuf/map_test.cc b/src/google/protobuf/map_test.cc
index 451b02e8..03954e75 100644
--- a/src/google/protobuf/map_test.cc
+++ b/src/google/protobuf/map_test.cc
@@ -28,17 +28,28 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// A hack to include windows.h first, which ensures the GetMessage macro can
+// be undefined when we include <google/protobuf/stubs/common.h>
+#if defined(_WIN32)
+#define _WINSOCKAPI_ // to avoid re-definition in WinSock2.h
+#define NOMINMAX // to avoid defining min/max macros
+#include <windows.h>
+#endif // _WIN32
+
+#include <algorithm>
+#include <google/protobuf/stubs/hash.h>
#include <map>
#include <memory>
#ifndef _SHARED_PTR_H
#include <google/protobuf/stubs/shared_ptr.h>
#endif
+#include <set>
#include <sstream>
+#include <vector>
#include <google/protobuf/stubs/casts.h>
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/scoped_ptr.h>
#include <google/protobuf/stubs/stringprintf.h>
#include <google/protobuf/testing/file.h>
#include <google/protobuf/arena_test_util.h>
@@ -62,8 +73,11 @@
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/tokenizer.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/util/time_util.h>
+#include <google/protobuf/util/message_differencer.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/substitute.h>
+#include <gmock/gmock.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
@@ -79,10 +93,11 @@ namespace internal {
// Map API Test =====================================================
-class MapImplTest : public ::testing::Test {
+// Parameterized tests on whether to use old style maps.
+class MapImplTest : public testing::TestWithParam<bool> {
protected:
MapImplTest()
- : map_ptr_(new Map<int32, int32>),
+ : map_ptr_(new Map<int32, int32>(GetParam())),
map_(*map_ptr_),
const_map_(*map_ptr_) {
EXPECT_TRUE(map_.empty());
@@ -159,7 +174,7 @@ class MapImplTest : public ::testing::Test {
const Map<int32, int32>& const_map_;
};
-TEST_F(MapImplTest, OperatorBracket) {
+TEST_P(MapImplTest, OperatorBracket) {
int32 key = 0;
int32 value1 = 100;
int32 value2 = 101;
@@ -173,7 +188,7 @@ TEST_F(MapImplTest, OperatorBracket) {
ExpectSingleElement(key, value2);
}
-TEST_F(MapImplTest, OperatorBracketNonExist) {
+TEST_P(MapImplTest, OperatorBracketNonExist) {
int32 key = 0;
int32 default_value = 0;
@@ -181,7 +196,7 @@ TEST_F(MapImplTest, OperatorBracketNonExist) {
ExpectSingleElement(key, default_value);
}
-TEST_F(MapImplTest, MutableAt) {
+TEST_P(MapImplTest, MutableAt) {
int32 key = 0;
int32 value1 = 100;
int32 value2 = 101;
@@ -195,15 +210,15 @@ TEST_F(MapImplTest, MutableAt) {
#ifdef PROTOBUF_HAS_DEATH_TEST
-TEST_F(MapImplTest, MutableAtNonExistDeathTest) {
+TEST_P(MapImplTest, MutableAtNonExistDeathTest) {
EXPECT_DEATH(map_.at(0), "");
}
-TEST_F(MapImplTest, ImmutableAtNonExistDeathTest) {
+TEST_P(MapImplTest, ImmutableAtNonExistDeathTest) {
EXPECT_DEATH(const_map_.at(0), "");
}
-TEST_F(MapImplTest, UsageErrors) {
+TEST_P(MapImplTest, UsageErrors) {
MapKey key;
key.SetInt64Value(1);
EXPECT_DEATH(key.GetUInt64Value(),
@@ -220,23 +235,23 @@ TEST_F(MapImplTest, UsageErrors) {
#endif // PROTOBUF_HAS_DEATH_TEST
-TEST_F(MapImplTest, CountNonExist) {
+TEST_P(MapImplTest, CountNonExist) {
EXPECT_EQ(0, map_.count(0));
}
-TEST_F(MapImplTest, MutableFindNonExist) {
+TEST_P(MapImplTest, MutableFindNonExist) {
EXPECT_TRUE(map_.end() == map_.find(0));
}
-TEST_F(MapImplTest, ImmutableFindNonExist) {
+TEST_P(MapImplTest, ImmutableFindNonExist) {
EXPECT_TRUE(const_map_.end() == const_map_.find(0));
}
-TEST_F(MapImplTest, ConstEnd) {
+TEST_P(MapImplTest, ConstEnd) {
EXPECT_TRUE(const_map_.end() == const_map_.cend());
}
-TEST_F(MapImplTest, GetReferenceFromIterator) {
+TEST_P(MapImplTest, GetReferenceFromIterator) {
for (int i = 0; i < 10; i++) {
map_[i] = i;
}
@@ -259,7 +274,7 @@ TEST_F(MapImplTest, GetReferenceFromIterator) {
}
}
-TEST_F(MapImplTest, IteratorBasic) {
+TEST_P(MapImplTest, IteratorBasic) {
map_[0] = 0;
// Default constructible (per forward iterator requirements).
@@ -281,6 +296,292 @@ TEST_F(MapImplTest, IteratorBasic) {
EXPECT_TRUE(it == cit);
}
+template <typename Iterator>
+static int64 median(Iterator i0, Iterator i1) {
+ vector<int64> v(i0, i1);
+ std::nth_element(v.begin(), v.begin() + v.size() / 2, v.end());
+ return v[v.size() / 2];
+}
+
+static int64 Now() {
+ return google::protobuf::util::TimeUtil::TimestampToNanoseconds(
+ google::protobuf::util::TimeUtil::GetCurrentTime());
+}
+
+// Arbitrary odd integers for creating test data.
+static int k0 = 812398771;
+static int k1 = 1312938717;
+static int k2 = 1321555333;
+
+// A naive begin() implementation will cause begin() to get slower and slower
+// if one erases elements at the "front" of the hash map, and we'd like to
+// avoid that, as std::unordered_map does.
+TEST_P(MapImplTest, BeginIsFast) {
+ // Disable this test for both new and old implementations.
+ if (/*GetParam()*/true) return;
+ Map<int32, int32> map(false); // This test uses new-style maps only.
+ const int kTestSize = 250000;
+ // Create a random-looking map of size n. Use non-negative integer keys.
+ uint32 frog = 123983;
+ int last_key = 0;
+ int counter = 0;
+ while (map.size() < kTestSize) {
+ frog *= static_cast<uint32>(k0);
+ frog ^= frog >> 17;
+ frog += counter++;
+ last_key =
+ static_cast<int>(frog) >= 0 ? static_cast<int>(frog) : last_key ^ 1;
+ GOOGLE_DCHECK_GE(last_key, 0);
+ map[last_key] = last_key ^ 1;
+ }
+ vector<int64> times;
+ // We're going to do map.erase(map.begin()) over and over again. But,
+ // just in case one iteration is fast compared to the granularity of
+ // our time keeping, we measure kChunkSize iterations per outer-loop iter.
+ const int kChunkSize = 1000;
+ GOOGLE_CHECK_EQ(kTestSize % kChunkSize, 0);
+ do {
+ const int64 start = Now();
+ for (int i = 0; i < kChunkSize; i++) {
+ map.erase(map.begin());
+ }
+ const int64 end = Now();
+ if (end > start) {
+ times.push_back(end - start);
+ }
+ } while (!map.empty());
+ if (times.size() < .99 * kTestSize / kChunkSize) {
+ GOOGLE_LOG(WARNING) << "Now() isn't helping us measure time";
+ return;
+ }
+ int64 x0 = median(times.begin(), times.begin() + 9);
+ int64 x1 = median(times.begin() + times.size() - 9, times.end());
+ GOOGLE_LOG(INFO) << "x0=" << x0 << ", x1=" << x1;
+ // x1 will greatly exceed x0 if the code we just executed took O(n^2) time.
+ // And we'll probably time out and never get here. So, this test is
+ // intentionally loose: we check that x0 and x1 are within a factor of 8.
+ EXPECT_GE(x1, x0 / 8);
+ EXPECT_GE(x0, x1 / 8);
+}
+
+// Try to create kTestSize keys that will land in just a few buckets, and
+// time the insertions, to get a rough estimate of whether an O(n^2) worst case
+// was triggered. This test is a hacky, but probably better than nothing.
+TEST_P(MapImplTest, HashFlood) {
+ const int kTestSize = 1024; // must be a power of 2
+ std::set<int> s;
+ for (int i = 0; s.size() < kTestSize; i++) {
+ if ((map_.hash_function()(i) & (kTestSize - 1)) < 3) {
+ s.insert(i);
+ }
+ }
+ // Create hash table with kTestSize entries that hash flood a table with
+ // 1024 (or 512 or 2048 or ...) entries. This assumes that map_ uses powers
+ // of 2 for table sizes, and that it's sufficient to "flood" with respect to
+ // the low bits of the output of map_.hash_function().
+ vector<int64> times;
+ std::set<int>::iterator it = s.begin();
+ int count = 0;
+ do {
+ const int64 start = Now();
+ map_[*it] = 0;
+ const int64 end = Now();
+ if (end > start) {
+ times.push_back(end - start);
+ }
+ ++count;
+ ++it;
+ } while (it != s.end());
+ if (times.size() < .99 * count) return;
+ int64 x0 = median(times.begin(), times.begin() + 9);
+ int64 x1 = median(times.begin() + times.size() - 9, times.end());
+ // x1 will greatly exceed x0 if the code we just executed took O(n^2) time.
+ // But we want to allow O(n log n). A factor of 20 should be generous enough.
+ EXPECT_LE(x1, x0 * 20);
+}
+
+template <typename T, typename U>
+static void TestValidityForAllKeysExcept(int key_to_avoid,
+ const T& check_map,
+ const U& map) {
+ typedef typename U::value_type value_type; // a key-value pair
+ for (typename U::const_iterator it = map.begin(); it != map.end(); ++it) {
+ const int key = it->first;
+ if (key == key_to_avoid) continue;
+ // All iterators relevant to this key, whether old (from check_map) or new,
+ // must point to the same memory. So, test pointer equality here.
+ const value_type* check_val = &*check_map.find(key)->second;
+ EXPECT_EQ(check_val, &*it);
+ EXPECT_EQ(check_val, &*map.find(key));
+ }
+}
+
+// EXPECT i0 and i1 to be the same. Advancing them should have the same effect,
+// too.
+template <typename Iter>
+static void TestEqualIterators(Iter i0, Iter i1, Iter end) {
+ const int kMaxAdvance = 10;
+ for (int i = 0; i < kMaxAdvance; i++) {
+ EXPECT_EQ(i0 == end, i1 == end);
+ if (i0 == end) return;
+ EXPECT_EQ(&*i0, &*i1) << "iter " << i;
+ ++i0;
+ ++i1;
+ }
+}
+
+template <typename IteratorType>
+static void TestOldVersusNewIterator(int skip, Map<int, int>* m) {
+ const int initial_size = m->size();
+ IteratorType it = m->begin();
+ for (int i = 0; i < skip && it != m->end(); it++, i++) {}
+ if (it == m->end()) return;
+ const IteratorType old = it;
+ GOOGLE_LOG(INFO) << "skip=" << skip << ", old->first=" << old->first;
+ const int target_size =
+ initial_size < 100 ? initial_size * 5 : initial_size * 5 / 4;
+ for (int i = 0; m->size() <= target_size; i++) {
+ (*m)[i] = 0;
+ }
+ // Iterator 'old' should still work just fine despite the growth of *m.
+ const IteratorType after_growth = m->find(old->first);
+ TestEqualIterators<IteratorType>(old, after_growth, m->end());
+
+ // Now shrink the number of elements. Do this with a mix of erases and
+ // inserts to increase the chance that the hashtable will resize to a lower
+ // number of buckets. (But, in any case, the test is still useful.)
+ for (int i = 0; i < 2 * (target_size - initial_size); i++) {
+ if (i != old->first) {
+ m->erase(i);
+ }
+ if (((i ^ m->begin()->first) & 15) == 0) {
+ (*m)[i * 342] = i;
+ }
+ }
+ // Now, the table has grown and shrunk; test again.
+ TestEqualIterators<IteratorType>(old, m->find(old->first), m->end());
+ TestEqualIterators<IteratorType>(old, after_growth, m->end());
+}
+
+// Create and test an n-element Map, with emphasis on iterator correctness.
+static void StressTestIterators(int n, bool test_old_style_proto2_maps) {
+ GOOGLE_LOG(INFO) << "StressTestIterators " << n;
+ GOOGLE_CHECK_GT(n, 0);
+ // Create a random-looking map of size n. Use non-negative integer keys.
+ Map<int, int> m(test_old_style_proto2_maps);
+ uint32 frog = 123987 + n;
+ int last_key = 0;
+ int counter = 0;
+ while (m.size() < n) {
+ frog *= static_cast<uint32>(k0);
+ frog ^= frog >> 17;
+ frog += counter++;
+ last_key =
+ static_cast<int>(frog) >= 0 ? static_cast<int>(frog) : last_key ^ 1;
+ GOOGLE_DCHECK_GE(last_key, 0);
+ m[last_key] = last_key ^ 1;
+ }
+ // Test it.
+ ASSERT_EQ(n, m.size());
+ // Create maps of pointers and iterators.
+ // These should remain valid even if we modify m.
+ hash_map<int, Map<int, int>::value_type*> mp(n);
+ hash_map<int, Map<int, int>::iterator> mi(n);
+ for (Map<int, int>::iterator it = m.begin(); it != m.end(); ++it) {
+ mp[it->first] = &*it;
+ mi[it->first] = it;
+ }
+ ASSERT_EQ(m.size(), mi.size());
+ ASSERT_EQ(m.size(), mp.size());
+ m.erase(last_key);
+ ASSERT_EQ(n - 1, m.size());
+ TestValidityForAllKeysExcept(last_key, mp, m);
+ TestValidityForAllKeysExcept(last_key, mi, m);
+
+ m[last_key] = 0;
+ ASSERT_EQ(n, m.size());
+ // Test old iterator vs new iterator, with table modification in between.
+ TestOldVersusNewIterator<Map<int, int>::const_iterator>(n % 3, &m);
+ TestOldVersusNewIterator<Map<int, int>::iterator>(n % (1 + (n / 40)), &m);
+ // Finally, ensure erase(iterator) doesn't reorder anything, because that is
+ // what its documentation says.
+ m[last_key] = m[last_key ^ 999] = 0;
+ vector<Map<int, int>::iterator> v;
+ v.reserve(m.size());
+ int position_of_last_key = 0;
+ for (Map<int, int>::iterator it = m.begin(); it != m.end(); ++it) {
+ if (it->first == last_key) {
+ position_of_last_key = v.size();
+ }
+ v.push_back(it);
+ }
+ ASSERT_EQ(m.size(), v.size());
+ const Map<int, int>::iterator erase_result = m.erase(m.find(last_key));
+ int index = 0;
+ for (Map<int, int>::iterator it = m.begin(); it != m.end(); ++it, ++index) {
+ if (index == position_of_last_key) {
+ EXPECT_EQ(&*erase_result, &*v[++index]);
+ }
+ ASSERT_EQ(&*it, &*v[index]);
+ }
+}
+
+TEST_P(MapImplTest, IteratorInvalidation) {
+ // As multiple underlying hash_map implementations do not follow the
+ // validation requirement, the test is disabled for old-style maps.
+ if (GetParam()) return;
+ // Create a set of pseudo-random sizes to test.
+#ifndef NDEBUG
+ const int kMaxSizeToTest = 100 * 1000;
+#else
+ const int kMaxSizeToTest = 1000 * 1000;
+#endif
+ std::set<int> s;
+ int n = kMaxSizeToTest;
+ int frog = k1 + n;
+ while (n > 1 && s.size() < 25) {
+ s.insert(n);
+ n = static_cast<int>(n * 100 / (101.0 + (frog & 63)));
+ frog *= k2;
+ frog ^= frog >> 17;
+ }
+ // Ensure we test a few small sizes.
+ s.insert(1);
+ s.insert(2);
+ s.insert(3);
+ // Now, the real work.
+ for (std::set<int>::iterator i = s.begin(); i != s.end(); ++i) {
+ StressTestIterators(*i, GetParam());
+ }
+}
+
+// Test that erase() revalidates iterators.
+TEST_P(MapImplTest, EraseRevalidates) {
+ // As multiple underlying hash_map implementations do not follow the
+ // validation requirement, the test is disabled for old-style maps.
+ if (GetParam()) return;
+ map_[3] = map_[13] = map_[20] = 0;
+ const int initial_size = map_.size();
+ EXPECT_EQ(3, initial_size);
+ vector<Map<int, int>::iterator> v;
+ for (Map<int, int>::iterator it = map_.begin(); it != map_.end(); ++it) {
+ v.push_back(it);
+ }
+ EXPECT_EQ(initial_size, v.size());
+ for (int i = 0; map_.size() <= initial_size * 20; i++) {
+ map_[i] = 0;
+ }
+ const int larger_size = map_.size();
+ // We've greatly increased the size of the map, so it is highly likely that
+ // the following will corrupt m if erase() doesn't properly revalidate
+ // iterators passed to it. Finishing this routine without crashing indicates
+ // success.
+ for (int i = 0; i < v.size(); i++) {
+ map_.erase(v[i]);
+ }
+ EXPECT_EQ(larger_size - v.size(), map_.size());
+}
+
template <typename T>
bool IsConstHelper(T& /*t*/) { // NOLINT. We want to catch non-const refs here.
return false;
@@ -290,7 +591,7 @@ bool IsConstHelper(const T& /*t*/) {
return true;
}
-TEST_F(MapImplTest, IteratorConstness) {
+TEST_P(MapImplTest, IteratorConstness) {
map_[0] = 0;
EXPECT_TRUE(IsConstHelper(*map_.cbegin()));
EXPECT_TRUE(IsConstHelper(*const_map_.begin()));
@@ -303,14 +604,14 @@ bool IsForwardIteratorHelper(T /*t*/) {
return false;
}
-TEST_F(MapImplTest, IteratorCategory) {
+TEST_P(MapImplTest, IteratorCategory) {
EXPECT_TRUE(IsForwardIteratorHelper(
std::iterator_traits<Map<int, int>::iterator>::iterator_category()));
EXPECT_TRUE(IsForwardIteratorHelper(std::iterator_traits<
Map<int, int>::const_iterator>::iterator_category()));
}
-TEST_F(MapImplTest, InsertSingle) {
+TEST_P(MapImplTest, InsertSingle) {
int32 key = 0;
int32 value1 = 100;
int32 value2 = 101;
@@ -335,7 +636,7 @@ TEST_F(MapImplTest, InsertSingle) {
EXPECT_FALSE(result2.second);
}
-TEST_F(MapImplTest, InsertByIterator) {
+TEST_P(MapImplTest, InsertByIterator) {
int32 key1 = 0;
int32 key2 = 1;
int32 value1a = 100;
@@ -358,7 +659,7 @@ TEST_F(MapImplTest, InsertByIterator) {
ExpectElements(map1);
}
-TEST_F(MapImplTest, EraseSingleByKey) {
+TEST_P(MapImplTest, EraseSingleByKey) {
int32 key = 0;
int32 value = 100;
@@ -376,7 +677,7 @@ TEST_F(MapImplTest, EraseSingleByKey) {
EXPECT_EQ(0, map_.erase(key));
}
-TEST_F(MapImplTest, EraseMutipleByKey) {
+TEST_P(MapImplTest, EraseMutipleByKey) {
// erase in one specific order to trigger corner cases
for (int i = 0; i < 5; i++) {
map_[i] = i;
@@ -403,7 +704,7 @@ TEST_F(MapImplTest, EraseMutipleByKey) {
EXPECT_TRUE(map_.end() == map_.find(2));
}
-TEST_F(MapImplTest, EraseSingleByIterator) {
+TEST_P(MapImplTest, EraseSingleByIterator) {
int32 key = 0;
int32 value = 100;
@@ -418,7 +719,7 @@ TEST_F(MapImplTest, EraseSingleByIterator) {
EXPECT_TRUE(map_.begin() == map_.end());
}
-TEST_F(MapImplTest, ValidIteratorAfterErase) {
+TEST_P(MapImplTest, ValidIteratorAfterErase) {
for (int i = 0; i < 10; i++) {
map_[i] = i;
}
@@ -438,7 +739,7 @@ TEST_F(MapImplTest, ValidIteratorAfterErase) {
EXPECT_EQ(5, map_.size());
}
-TEST_F(MapImplTest, EraseByIterator) {
+TEST_P(MapImplTest, EraseByIterator) {
int32 key1 = 0;
int32 key2 = 1;
int32 value1 = 100;
@@ -459,7 +760,7 @@ TEST_F(MapImplTest, EraseByIterator) {
EXPECT_TRUE(map_.begin() == map_.end());
}
-TEST_F(MapImplTest, Clear) {
+TEST_P(MapImplTest, Clear) {
int32 key = 0;
int32 value = 100;
@@ -474,7 +775,7 @@ TEST_F(MapImplTest, Clear) {
EXPECT_TRUE(map_.begin() == map_.end());
}
-TEST_F(MapImplTest, CopyConstructor) {
+static void CopyConstructorHelper(Arena* arena, Map<int32, int32>* m) {
int32 key1 = 0;
int32 key2 = 1;
int32 value1 = 100;
@@ -484,16 +785,25 @@ TEST_F(MapImplTest, CopyConstructor) {
map[key1] = value1;
map[key2] = value2;
- map_.insert(map.begin(), map.end());
+ m->insert(map.begin(), map.end());
- Map<int32, int32> other(map_);
+ Map<int32, int32> other(*m);
EXPECT_EQ(2, other.size());
EXPECT_EQ(value1, other.at(key1));
EXPECT_EQ(value2, other.at(key2));
}
-TEST_F(MapImplTest, IterConstructor) {
+TEST_P(MapImplTest, CopyConstructorWithArena) {
+ Arena a;
+ CopyConstructorHelper(&a, &map_);
+}
+
+TEST_P(MapImplTest, CopyConstructorWithoutArena) {
+ CopyConstructorHelper(NULL, &map_);
+}
+
+TEST_P(MapImplTest, IterConstructor) {
int32 key1 = 0;
int32 key2 = 1;
int32 value1 = 100;
@@ -503,14 +813,15 @@ TEST_F(MapImplTest, IterConstructor) {
map[key1] = value1;
map[key2] = value2;
- Map<int32, int32> new_map(map.begin(), map.end());
+ Map<int32, int32> new_map(map.begin(), map.end(),
+ GetParam());
EXPECT_EQ(2, new_map.size());
EXPECT_EQ(value1, new_map.at(key1));
EXPECT_EQ(value2, new_map.at(key2));
}
-TEST_F(MapImplTest, Assigner) {
+TEST_P(MapImplTest, Assigner) {
int32 key1 = 0;
int32 key2 = 1;
int32 value1 = 100;
@@ -522,7 +833,7 @@ TEST_F(MapImplTest, Assigner) {
map_.insert(map.begin(), map.end());
- Map<int32, int32> other;
+ Map<int32, int32> other(GetParam());
int32 key_other = 123;
int32 value_other = 321;
other[key_other] = value_other;
@@ -540,9 +851,16 @@ TEST_F(MapImplTest, Assigner) {
EXPECT_EQ(2, other.size());
EXPECT_EQ(value1, other.at(key1));
EXPECT_EQ(value2, other.at(key2));
+
+ // Try assignment to a map with a different choice of "style."
+ Map<int32, int32> m(!GetParam());
+ m = other;
+ EXPECT_EQ(2, m.size());
+ EXPECT_EQ(value1, m.at(key1));
+ EXPECT_EQ(value2, m.at(key2));
}
-TEST_F(MapImplTest, Rehash) {
+TEST_P(MapImplTest, Rehash) {
const int test_size = 50;
std::map<int32, int32> reference_map;
for (int i = 0; i < test_size; i++) {
@@ -559,7 +877,7 @@ TEST_F(MapImplTest, Rehash) {
EXPECT_TRUE(map_.empty());
}
-TEST_F(MapImplTest, EqualRange) {
+TEST_P(MapImplTest, EqualRange) {
int key = 100, key_missing = 101;
map_[key] = 100;
@@ -583,14 +901,14 @@ TEST_F(MapImplTest, EqualRange) {
EXPECT_TRUE(const_map_.end() == const_range.second);
}
-TEST_F(MapImplTest, ConvertToStdMap) {
+TEST_P(MapImplTest, ConvertToStdMap) {
map_[100] = 101;
std::map<int32, int32> std_map(map_.begin(), map_.end());
EXPECT_EQ(1, std_map.size());
EXPECT_EQ(101, std_map[100]);
}
-TEST_F(MapImplTest, ConvertToStdVectorOfPairs) {
+TEST_P(MapImplTest, ConvertToStdVectorOfPairs) {
map_[100] = 101;
std::vector<std::pair<int32, int32> > std_vec(map_.begin(), map_.end());
EXPECT_EQ(1, std_vec.size());
@@ -598,6 +916,57 @@ TEST_F(MapImplTest, ConvertToStdVectorOfPairs) {
EXPECT_EQ(101, std_vec[0].second);
}
+TEST_P(MapImplTest, SwapSameStyle) {
+ Map<int32, int32> another(GetParam()); // same old_style_ value
+ map_[9398] = 41999;
+ another[9398] = 41999;
+ another[8070] = 42056;
+ another.swap(map_);
+ EXPECT_THAT(another, testing::UnorderedElementsAre(
+ testing::Pair(9398, 41999)));
+ EXPECT_THAT(map_, testing::UnorderedElementsAre(
+ testing::Pair(8070, 42056),
+ testing::Pair(9398, 41999)));
+}
+
+TEST_P(MapImplTest, SwapDifferentStyle) {
+ Map<int32, int32> another(!GetParam()); // different old_style_ value
+ map_[9398] = 41999;
+ another[9398] = 41999;
+ another[8070] = 42056;
+ another.swap(map_);
+ EXPECT_THAT(another, testing::UnorderedElementsAre(
+ testing::Pair(9398, 41999)));
+ EXPECT_THAT(map_, testing::UnorderedElementsAre(
+ testing::Pair(8070, 42056),
+ testing::Pair(9398, 41999)));
+}
+
+TEST_P(MapImplTest, SwapArena) {
+ Arena arena1, arena2;
+ Map<int32, int32> m1(&arena1, false);
+ Map<int32, int32> m2(&arena2, false);
+ map_[9398] = 41999;
+ m1[9398] = 41999;
+ m1[8070] = 42056;
+ m2[10244] = 10247;
+ m2[8070] = 42056;
+ m1.swap(map_);
+ EXPECT_THAT(m1, testing::UnorderedElementsAre(
+ testing::Pair(9398, 41999)));
+ EXPECT_THAT(map_, testing::UnorderedElementsAre(
+ testing::Pair(8070, 42056),
+ testing::Pair(9398, 41999)));
+ m2.swap(m1);
+ EXPECT_THAT(m1, testing::UnorderedElementsAre(
+ testing::Pair(8070, 42056),
+ testing::Pair(10244, 10247)));
+ EXPECT_THAT(m2, testing::UnorderedElementsAre(
+ testing::Pair(9398, 41999)));
+}
+
+INSTANTIATE_TEST_CASE_P(BoolSequence, MapImplTest, testing::Bool());
+
// Map Field Reflection Test ========================================
static int Func(int i, int j) {
@@ -1787,6 +2156,76 @@ TEST(GeneratedMapFieldTest, DuplicatedKeyWireFormat) {
EXPECT_TRUE(message.ParseFromString(data));
EXPECT_EQ(1, message.map_int32_int32().size());
EXPECT_EQ(1, message.map_int32_int32().at(2));
+
+ // A similar test, but with a map from int to a message type.
+ // Again, we want to be sure that the "second one wins" when
+ // there are two separate entries with the same key.
+ const int key = 99;
+ unittest::TestRequiredMessageMap map_message;
+ unittest::TestRequired with_dummy4;
+ with_dummy4.set_a(0);
+ with_dummy4.set_b(0);
+ with_dummy4.set_c(0);
+ with_dummy4.set_dummy4(11);
+ (*map_message.mutable_map_field())[key] = with_dummy4;
+ string s = map_message.SerializeAsString();
+ unittest::TestRequired with_dummy5;
+ with_dummy5.set_a(0);
+ with_dummy5.set_b(0);
+ with_dummy5.set_c(0);
+ with_dummy5.set_dummy5(12);
+ (*map_message.mutable_map_field())[key] = with_dummy5;
+ string both = s + map_message.SerializeAsString();
+ // We don't expect a merge now. The "second one wins."
+ ASSERT_TRUE(map_message.ParseFromString(both));
+ ASSERT_EQ(1, map_message.map_field().size());
+ ASSERT_EQ(1, map_message.map_field().count(key));
+ EXPECT_EQ(0, map_message.map_field().find(key)->second.a());
+ EXPECT_EQ(0, map_message.map_field().find(key)->second.b());
+ EXPECT_EQ(0, map_message.map_field().find(key)->second.c());
+ EXPECT_FALSE(map_message.map_field().find(key)->second.has_dummy4());
+ ASSERT_TRUE(map_message.map_field().find(key)->second.has_dummy5());
+ EXPECT_EQ(12, map_message.map_field().find(key)->second.dummy5());
+}
+
+// Exhaustive combinations of keys, values, and junk in any order.
+// This re-tests some of the things tested above, but if it fails
+// it's more work to determine what went wrong, so it isn't necessarily
+// bad that we have the simpler tests too.
+TEST(GeneratedMapFieldTest, KeysValuesUnknownsWireFormat) {
+ unittest::TestMap message;
+ const int kMaxNumKeysAndValuesAndJunk = 4;
+ const char kKeyTag = 0x08;
+ const char kValueTag = 0x10;
+ const char kJunkTag = 0x20;
+ for (int items = 0; items <= kMaxNumKeysAndValuesAndJunk; items++) {
+ string data = "\x0A";
+ // Encode length of what will follow.
+ data.push_back(items * 2);
+ static const int kBitsOfIPerItem = 4;
+ static const int mask = (1 << kBitsOfIPerItem) - 1;
+ // Each iteration of the following is a test. It uses i as bit vector
+ // encoding the keys and values to put in the wire format.
+ for (int i = 0; i < (1 << (items * kBitsOfIPerItem)); i++) {
+ string wire_format = data;
+ int expected_key = 0;
+ int expected_value = 0;
+ for (int k = i, j = 0; j < items; j++, k >>= kBitsOfIPerItem) {
+ bool is_key = k & 0x1;
+ bool is_value = !is_key && (k & 0x2);
+ wire_format.push_back(is_key ? kKeyTag :
+ is_value ? kValueTag : kJunkTag);
+ char c = static_cast<char>(k & mask) >> 2; // One char after the tag.
+ wire_format.push_back(c);
+ if (is_key) expected_key = static_cast<int>(c);
+ if (is_value) expected_value = static_cast<int>(c);
+ ASSERT_TRUE(message.ParseFromString(wire_format));
+ ASSERT_EQ(1, message.map_int32_int32().size());
+ ASSERT_EQ(expected_key, message.map_int32_int32().begin()->first);
+ ASSERT_EQ(expected_value, message.map_int32_int32().begin()->second);
+ }
+ }
+ }
}
TEST(GeneratedMapFieldTest, DuplicatedValueWireFormat) {
@@ -1870,6 +2309,74 @@ TEST(GeneratedMapFieldTest, IsInitialized) {
EXPECT_TRUE(map_message.IsInitialized());
}
+TEST(GeneratedMapFieldTest, MessagesMustMerge) {
+ unittest::TestRequiredMessageMap map_message;
+ unittest::TestRequired with_dummy4;
+ with_dummy4.set_a(97);
+ with_dummy4.set_b(0);
+ with_dummy4.set_c(0);
+ with_dummy4.set_dummy4(98);
+
+ EXPECT_TRUE(with_dummy4.IsInitialized());
+ (*map_message.mutable_map_field())[0] = with_dummy4;
+ EXPECT_TRUE(map_message.IsInitialized());
+ string s = map_message.SerializeAsString();
+
+ // Modify s so that there are two values in the entry for key 0.
+ // The first will have no value for c. The second will have no value for a.
+ // Those are required fields. Also, make some other little changes, to
+ // ensure we are merging the two values (because they're messages).
+ ASSERT_EQ(s.size() - 2, s[1]); // encoding of the length of what follows
+ string encoded_val(s.data() + 4, s.data() + s.size());
+ // In s, change the encoding of c to an encoding of dummy32.
+ s[s.size() - 3] -= 8;
+ // Make encoded_val slightly different from what's in s.
+ encoded_val[encoded_val.size() - 1] += 33; // Encode c = 33.
+ for (int i = 0; i < encoded_val.size(); i++) {
+ if (encoded_val[i] == 97) {
+ // Encode b = 91 instead of a = 97. But this won't matter, because
+ // we also encode b = 0 right after this. The point is to leave out
+ // a required field, and make sure the parser doesn't complain, because
+ // every required field is set after the merge of the two values.
+ encoded_val[i - 1] += 16;
+ encoded_val[i] = 91;
+ } else if (encoded_val[i] == 98) {
+ // Encode dummy5 = 99 instead of dummy4 = 98.
+ encoded_val[i - 1] += 8; // The tag for dummy5 is 8 more.
+ encoded_val[i]++;
+ break;
+ }
+ }
+
+ s += encoded_val; // Add the second message.
+ s[1] += encoded_val.size(); // Adjust encoded size.
+
+ // Test key then value then value.
+ int key = 0;
+ ASSERT_TRUE(map_message.ParseFromString(s));
+ ASSERT_EQ(1, map_message.map_field().size());
+ ASSERT_EQ(1, map_message.map_field().count(key));
+ EXPECT_EQ(97, map_message.map_field().find(key)->second.a());
+ EXPECT_EQ(0, map_message.map_field().find(key)->second.b());
+ EXPECT_EQ(33, map_message.map_field().find(key)->second.c());
+ EXPECT_EQ(98, map_message.map_field().find(key)->second.dummy4());
+ EXPECT_EQ(99, map_message.map_field().find(key)->second.dummy5());
+
+ // Test key then value then value then key.
+ s.push_back(s[2]); // Copy the key's tag.
+ key = 19;
+ s.push_back(key); // Second key is 19 instead of 0.
+ s[1] += 2; // Adjust encoded size.
+ ASSERT_TRUE(map_message.ParseFromString(s));
+ ASSERT_EQ(1, map_message.map_field().size());
+ ASSERT_EQ(1, map_message.map_field().count(key));
+ EXPECT_EQ(97, map_message.map_field().find(key)->second.a());
+ EXPECT_EQ(0, map_message.map_field().find(key)->second.b());
+ EXPECT_EQ(33, map_message.map_field().find(key)->second.c());
+ EXPECT_EQ(98, map_message.map_field().find(key)->second.dummy4());
+ EXPECT_EQ(99, map_message.map_field().find(key)->second.dummy5());
+}
+
// Generated Message Reflection Test ================================
TEST(GeneratedMapFieldReflectionTest, SpaceUsed) {
@@ -2363,6 +2870,82 @@ TEST(WireFormatForMapFieldTest, MapParseHelpers) {
}
}
+// Deterministic Serialization Test ==========================================
+
+template <typename T>
+static string DeterministicSerialization(const T& t) {
+ const int size = t.ByteSize();
+ string result(size, '\0');
+ io::ArrayOutputStream array_stream(string_as_array(&result), size);
+ io::CodedOutputStream output_stream(&array_stream);
+ output_stream.SetSerializationDeterministic(true);
+ t.SerializeWithCachedSizes(&output_stream);
+ EXPECT_FALSE(output_stream.HadError());
+ EXPECT_EQ(size, output_stream.ByteCount());
+ return result;
+}
+
+// Helper to test the serialization of the first arg against a golden file.
+static void TestDeterministicSerialization(const protobuf_unittest::TestMaps& t,
+ const string& filename) {
+ string expected;
+ GOOGLE_CHECK_OK(File::GetContents(
+ TestSourceDir() + "/google/protobuf/testdata/" + filename,
+ &expected, true));
+ const string actual = DeterministicSerialization(t);
+ EXPECT_EQ(expected, actual);
+ protobuf_unittest::TestMaps u;
+ EXPECT_TRUE(u.ParseFromString(actual));
+ EXPECT_TRUE(google::protobuf::util::MessageDifferencer::Equals(u, t));
+}
+
+// Helper for MapSerializationTest. Return a 7-bit ASCII string.
+static string ConstructKey(uint64 n) {
+ string s(n % static_cast<uint64>(9), '\0');
+ if (s.empty()) {
+ return StrCat(n);
+ } else {
+ while (n != 0) {
+ s[n % s.size()] = (n >> 10) & 0x7f;
+ n /= 888;
+ }
+ return s;
+ }
+}
+
+TEST(MapSerializationTest, Deterministic) {
+ const int kIters = 25;
+ protobuf_unittest::TestMaps t;
+ protobuf_unittest::TestIntIntMap inner;
+ (*inner.mutable_m())[0] = (*inner.mutable_m())[10] =
+ (*inner.mutable_m())[-200] = 0;
+ uint64 frog = 9;
+ const uint64 multiplier = 0xa29cd16f;
+ for (int i = 0; i < kIters; i++) {
+ const int32 i32 = static_cast<int32>(frog & 0xffffffff);
+ const uint32 u32 = static_cast<uint32>(i32) * 91919;
+ const int64 i64 = static_cast<int64>(frog);
+ const uint64 u64 = frog * static_cast<uint64>(187321);
+ const bool b = i32 > 0;
+ const string s = ConstructKey(frog);
+ (*inner.mutable_m())[i] = i32;
+ (*t.mutable_m_int32())[i32] = (*t.mutable_m_sint32())[i32] =
+ (*t.mutable_m_sfixed32())[i32] = inner;
+ (*t.mutable_m_uint32())[u32] = (*t.mutable_m_fixed32())[u32] = inner;
+ (*t.mutable_m_int64())[i64] = (*t.mutable_m_sint64())[i64] =
+ (*t.mutable_m_sfixed64())[i64] = inner;
+ (*t.mutable_m_uint64())[u64] = (*t.mutable_m_fixed64())[u64] = inner;
+ (*t.mutable_m_bool())[b] = inner;
+ (*t.mutable_m_string())[s] = inner;
+ (*t.mutable_m_string())[s + string(1 << (u32 % static_cast<uint32>(9)),
+ b)] = inner;
+ inner.mutable_m()->erase(i);
+ frog = frog * multiplier + i;
+ frog ^= (frog >> 41);
+ }
+ TestDeterministicSerialization(t, "golden_message_maps");
+}
+
// Text Format Test =================================================
TEST(TextFormatMapTest, SerializeAndParse) {
@@ -2464,6 +3047,21 @@ TEST(ArenaTest, StringMapNoLeak) {
ASSERT_FALSE(message == NULL);
}
+TEST(ArenaTest, IsInitialized) {
+ // Allocate a large initial polluted block.
+ std::vector<char> arena_block(128 * 1024);
+ std::fill(arena_block.begin(), arena_block.end(), '\xff');
+
+ ArenaOptions options;
+ options.initial_block = &arena_block[0];
+ options.initial_block_size = arena_block.size();
+ Arena arena(options);
+
+ unittest::TestArenaMap* message =
+ Arena::CreateMessage<unittest::TestArenaMap>(&arena);
+ EXPECT_EQ(0, (*message->mutable_map_int32_int32())[0]);
+}
+
} // namespace internal
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/map_type_handler.h b/src/google/protobuf/map_type_handler.h
index f8ad7584..685a770f 100644
--- a/src/google/protobuf/map_type_handler.h
+++ b/src/google/protobuf/map_type_handler.h
@@ -164,9 +164,12 @@ class MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type> {
MapEntryAccessorType* value);
static inline void Write(int field, const MapEntryAccessorType& value,
io::CodedOutputStream* output);
+ static inline uint8* InternalWriteToArray(int field,
+ const MapEntryAccessorType& value,
+ bool deterministic, uint8* target);
static inline uint8* WriteToArray(int field,
const MapEntryAccessorType& value,
- uint8* output);
+ uint8* target);
// Functions to manipulate data on memory. ========================
static inline const Type& GetExternalReference(const Type* value);
@@ -220,9 +223,16 @@ class MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type> {
MapEntryAccessorType* value); \
static inline void Write(int field, const MapEntryAccessorType& value, \
io::CodedOutputStream* output); \
+ static inline uint8* InternalWriteToArray( \
+ int field, \
+ const MapEntryAccessorType& value, \
+ bool deterministic, \
+ uint8* target); \
static inline uint8* WriteToArray(int field, \
const MapEntryAccessorType& value, \
- uint8* output); \
+ uint8* target) { \
+ return InternalWriteToArray(field, value, false, target); \
+ } \
static inline const MapEntryAccessorType& GetExternalReference( \
const TypeOnMemory& value); \
static inline void DeleteNoArena(const TypeOnMemory& x); \
@@ -362,9 +372,11 @@ inline void MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::Write(
template <typename Type>
inline uint8*
-MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::WriteToArray(
- int field, const MapEntryAccessorType& value, uint8* output) {
- return WireFormatLite::WriteMessageToArray(field, value, output);
+MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::InternalWriteToArray(
+ int field, const MapEntryAccessorType& value, bool deterministic,
+ uint8* target) {
+ return WireFormatLite::InternalWriteMessageToArray(field, value,
+ deterministic, target);
}
#define WRITE_METHOD(FieldType, DeclaredType) \
@@ -376,9 +388,10 @@ MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::WriteToArray(
} \
template <typename Type> \
inline uint8* \
- MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::WriteToArray( \
- int field, const MapEntryAccessorType& value, uint8* output) { \
- return WireFormatLite::Write##DeclaredType##ToArray(field, value, output); \
+ MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
+ Type>::InternalWriteToArray( \
+ int field, const MapEntryAccessorType& value, bool, uint8* target) { \
+ return WireFormatLite::Write##DeclaredType##ToArray(field, value, target); \
}
WRITE_METHOD(STRING , String)
@@ -543,7 +556,7 @@ inline bool MapTypeHandler<WireFormatLite::TYPE_MESSAGE,
Type>::MapEntryAccessorType& \
MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
Type>::GetExternalReference(const TypeOnMemory& value) { \
- return value.Get(&::google::protobuf::internal::GetEmptyString()); \
+ return value.Get(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); \
} \
template <typename Type> \
inline int \
@@ -564,7 +577,8 @@ inline bool MapTypeHandler<WireFormatLite::TYPE_MESSAGE,
template <typename Type> \
inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Clear( \
TypeOnMemory* value, Arena* arena) { \
- value->ClearToEmpty(&::google::protobuf::internal::GetEmptyString(), arena); \
+ value->ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), \
+ arena); \
} \
template <typename Type> \
inline void \
@@ -577,12 +591,12 @@ inline bool MapTypeHandler<WireFormatLite::TYPE_MESSAGE,
template <typename Type> \
inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Merge( \
const MapEntryAccessorType& from, TypeOnMemory* to, Arena* arena) { \
- to->Set(&::google::protobuf::internal::GetEmptyString(), from, arena); \
+ to->Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from, arena); \
} \
template <typename Type> \
void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::DeleteNoArena( \
TypeOnMemory& value) { \
- value.DestroyNoArena(&::google::protobuf::internal::GetEmptyString()); \
+ value.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); \
} \
template <typename Type> \
inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
@@ -591,7 +605,8 @@ inline bool MapTypeHandler<WireFormatLite::TYPE_MESSAGE,
inline void \
MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Initialize( \
TypeOnMemory* value, Arena* arena) { \
- value->UnsafeSetDefault(&::google::protobuf::internal::GetEmptyString()); \
+ value->UnsafeSetDefault( \
+ &::google::protobuf::internal::GetEmptyStringAlreadyInited()); \
} \
template <typename Type> \
inline void \
@@ -606,7 +621,8 @@ inline bool MapTypeHandler<WireFormatLite::TYPE_MESSAGE,
Type>::MapEntryAccessorType* \
MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::EnsureMutable( \
TypeOnMemory* value, Arena* arena) { \
- return value->Mutable(&::google::protobuf::internal::GetEmptyString(), arena); \
+ return value->Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), \
+ arena); \
} \
template <typename Type> \
inline const typename MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
@@ -615,7 +631,7 @@ inline bool MapTypeHandler<WireFormatLite::TYPE_MESSAGE,
Type>::DefaultIfNotInitialized(const TypeOnMemory& value, \
const TypeOnMemory& \
default_value) { \
- return value.Get(&::google::protobuf::internal::GetEmptyString()); \
+ return value.Get(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); \
} \
template <typename Type> \
inline bool MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
diff --git a/src/google/protobuf/map_unittest.proto b/src/google/protobuf/map_unittest.proto
index aea1e8ce..c6154f04 100644
--- a/src/google/protobuf/map_unittest.proto
+++ b/src/google/protobuf/map_unittest.proto
@@ -83,7 +83,7 @@ enum MapEnum {
MAP_ENUM_BAZ = 2;
}
-// Test embeded message with required fields
+// Test embedded message with required fields
message TestRequiredMessageMap {
map<int32, TestRequired> map_field = 1;
}
diff --git a/src/google/protobuf/message.cc b/src/google/protobuf/message.cc
index 032748bd..f18077dd 100644
--- a/src/google/protobuf/message.cc
+++ b/src/google/protobuf/message.cc
@@ -62,14 +62,12 @@ namespace protobuf {
using internal::WireFormat;
using internal::ReflectionOps;
-Message::~Message() {}
-
void Message::MergeFrom(const Message& from) {
const Descriptor* descriptor = GetDescriptor();
GOOGLE_CHECK_EQ(from.GetDescriptor(), descriptor)
<< ": Tried to merge from a message with a different type. "
"to: " << descriptor->full_name() << ", "
- "from:" << from.GetDescriptor()->full_name();
+ "from: " << from.GetDescriptor()->full_name();
ReflectionOps::Merge(from, this);
}
@@ -82,7 +80,7 @@ void Message::CopyFrom(const Message& from) {
GOOGLE_CHECK_EQ(from.GetDescriptor(), descriptor)
<< ": Tried to copy from a message with a different type. "
"to: " << descriptor->full_name() << ", "
- "from:" << from.GetDescriptor()->full_name();
+ "from: " << from.GetDescriptor()->full_name();
ReflectionOps::Copy(from, this);
}
diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h
index 7c27afd9..9705e97e 100644
--- a/src/google/protobuf/message.h
+++ b/src/google/protobuf/message.h
@@ -179,7 +179,7 @@ struct Metadata {
class LIBPROTOBUF_EXPORT Message : public MessageLite {
public:
inline Message() {}
- virtual ~Message();
+ virtual ~Message() {}
// Basic Operations ------------------------------------------------
@@ -585,8 +585,8 @@ class LIBPROTOBUF_EXPORT Reflection {
// If you have no idea what that meant, then you probably don't need to worry
// about it (don't provide a MessageFactory). WARNING: If the
// FieldDescriptor is for a compiled-in extension, then
- // factory->GetPrototype(field->message_type() MUST return an instance of the
- // compiled-in class for this type, NOT DynamicMessage.
+ // factory->GetPrototype(field->message_type()) MUST return an instance of
+ // the compiled-in class for this type, NOT DynamicMessage.
virtual Message* MutableMessage(Message* message,
const FieldDescriptor* field,
MessageFactory* factory = NULL) const = 0;
@@ -739,9 +739,9 @@ class LIBPROTOBUF_EXPORT Reflection {
// specifyed by 'field' passing ownership to the message.
// TODO(tmarek): Make virtual after all subclasses have been
// updated.
- virtual void AddAllocatedMessage(Message* message,
- const FieldDescriptor* field,
- Message* new_entry) const {}
+ virtual void AddAllocatedMessage(Message* /* message */,
+ const FieldDescriptor* /*field */,
+ Message* /* new_entry */) const {}
// Get a RepeatedFieldRef object that can be used to read the underlying
@@ -947,27 +947,27 @@ class LIBPROTOBUF_EXPORT Reflection {
// TODO(jieluo) - make the map APIs pure virtual after updating
// all the subclasses.
// Returns true if key is in map. Returns false if key is not in map field.
- virtual bool ContainsMapKey(const Message& message,
- const FieldDescriptor* field,
- const MapKey& key) const {
+ virtual bool ContainsMapKey(const Message& /* message*/,
+ const FieldDescriptor* /* field */,
+ const MapKey& /* key */) const {
return false;
}
// If key is in map field: Saves the value pointer to val and returns
// false. If key in not in map field: Insert the key into map, saves
// value pointer to val and retuns true.
- virtual bool InsertOrLookupMapValue(Message* message,
- const FieldDescriptor* field,
- const MapKey& key,
- MapValueRef* val) const {
+ virtual bool InsertOrLookupMapValue(Message* /* message */,
+ const FieldDescriptor* /* field */,
+ const MapKey& /* key */,
+ MapValueRef* /* val */) const {
return false;
}
// Delete and returns true if key is in the map field. Returns false
// otherwise.
- virtual bool DeleteMapValue(Message* message,
- const FieldDescriptor* field,
- const MapKey& key) const {
+ virtual bool DeleteMapValue(Message* /* mesage */,
+ const FieldDescriptor* /* field */,
+ const MapKey& /* key */) const {
return false;
}
@@ -987,15 +987,15 @@ class LIBPROTOBUF_EXPORT Reflection {
// Get the number of <key, value> pair of a map field. The result may be
// different from FieldSize which can have duplicate keys.
- virtual int MapSize(const Message& message,
- const FieldDescriptor* field) const {
+ virtual int MapSize(const Message& /* message */,
+ const FieldDescriptor* /* field */) const {
return 0;
}
// Help method for MapIterator.
friend class MapIterator;
virtual internal::MapFieldBase* MapData(
- Message* message, const FieldDescriptor* field) const {
+ Message* /* message */, const FieldDescriptor* /* field */) const {
return NULL;
}
diff --git a/src/google/protobuf/message_lite.cc b/src/google/protobuf/message_lite.cc
index 5bd8bcfb..ba56db95 100644
--- a/src/google/protobuf/message_lite.cc
+++ b/src/google/protobuf/message_lite.cc
@@ -46,8 +46,6 @@
namespace google {
namespace protobuf {
-MessageLite::~MessageLite() {}
-
string MessageLite::InitializationErrorString() const {
return "(cannot determine missing fields for lite message)";
}
@@ -62,13 +60,15 @@ namespace {
// provide a useful error message.
void ByteSizeConsistencyError(int byte_size_before_serialization,
int byte_size_after_serialization,
- int bytes_produced_by_serialization) {
+ int bytes_produced_by_serialization,
+ const MessageLite& message) {
GOOGLE_CHECK_EQ(byte_size_before_serialization, byte_size_after_serialization)
- << "Protocol message was modified concurrently during serialization.";
+ << message.GetTypeName()
+ << " was modified concurrently during serialization.";
GOOGLE_CHECK_EQ(bytes_produced_by_serialization, byte_size_before_serialization)
<< "Byte size calculation and serialization were inconsistent. This "
"may indicate a bug in protocol buffers or it may be caused by "
- "concurrent modification of the message.";
+ "concurrent modification of " << message.GetTypeName() << ".";
GOOGLE_LOG(FATAL) << "This shouldn't be called if all the sizes are equal.";
}
@@ -219,7 +219,8 @@ bool MessageLite::ParsePartialFromArray(const void* data, int size) {
// ===================================================================
-uint8* MessageLite::SerializeWithCachedSizesToArray(uint8* target) const {
+uint8* MessageLite::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, uint8* target) const {
// We only optimize this when using optimize_for = SPEED. In other cases
// we just use the CodedOutputStream path.
int size = GetCachedSize();
@@ -248,7 +249,7 @@ bool MessageLite::SerializePartialToCodedStream(
if (buffer != NULL) {
uint8* end = SerializeWithCachedSizesToArray(buffer);
if (end - buffer != size) {
- ByteSizeConsistencyError(size, ByteSize(), end - buffer);
+ ByteSizeConsistencyError(size, ByteSize(), end - buffer, *this);
}
return true;
} else {
@@ -261,7 +262,7 @@ bool MessageLite::SerializePartialToCodedStream(
if (final_byte_count - original_byte_count != size) {
ByteSizeConsistencyError(size, ByteSize(),
- final_byte_count - original_byte_count);
+ final_byte_count - original_byte_count, *this);
}
return true;
@@ -299,7 +300,7 @@ bool MessageLite::AppendPartialToString(string* output) const {
reinterpret_cast<uint8*>(io::mutable_string_data(output) + old_size);
uint8* end = SerializeWithCachedSizesToArray(start);
if (end - start != byte_size) {
- ByteSizeConsistencyError(byte_size, ByteSize(), end - start);
+ ByteSizeConsistencyError(byte_size, ByteSize(), end - start, *this);
}
return true;
}
@@ -325,7 +326,7 @@ bool MessageLite::SerializePartialToArray(void* data, int size) const {
uint8* start = reinterpret_cast<uint8*>(data);
uint8* end = SerializeWithCachedSizesToArray(start);
if (end - start != byte_size) {
- ByteSizeConsistencyError(byte_size, ByteSize(), end - start);
+ ByteSizeConsistencyError(byte_size, ByteSize(), end - start, *this);
}
return true;
}
@@ -359,6 +360,11 @@ void GenericTypeHandler<MessageLite>::Merge(const MessageLite& from,
MessageLite* to) {
to->CheckTypeAndMergeFrom(from);
}
+template<>
+void GenericTypeHandler<string>::Merge(const string& from,
+ string* to) {
+ *to = from;
+}
} // namespace internal
} // namespace protobuf
diff --git a/src/google/protobuf/message_lite.h b/src/google/protobuf/message_lite.h
index 4c16f4c0..2bdfe496 100644
--- a/src/google/protobuf/message_lite.h
+++ b/src/google/protobuf/message_lite.h
@@ -51,6 +51,9 @@ namespace io {
class ZeroCopyInputStream;
class ZeroCopyOutputStream;
}
+namespace internal {
+ class WireFormatLite;
+}
// Interface to light weight protocol messages.
//
@@ -78,7 +81,7 @@ namespace io {
class LIBPROTOBUF_EXPORT MessageLite {
public:
inline MessageLite() {}
- virtual ~MessageLite();
+ virtual ~MessageLite() {}
// Basic Operations ------------------------------------------------
@@ -249,10 +252,11 @@ class LIBPROTOBUF_EXPORT MessageLite {
virtual void SerializeWithCachedSizes(
io::CodedOutputStream* output) const = 0;
- // Like SerializeWithCachedSizes, but writes directly to *target, returning
- // a pointer to the byte immediately after the last byte written. "target"
- // must point at a byte array of at least ByteSize() bytes.
- virtual uint8* SerializeWithCachedSizesToArray(uint8* target) const;
+ // A version of SerializeWithCachedSizesToArray, below, that does
+ // not guarantee deterministic serialization.
+ virtual uint8* SerializeWithCachedSizesToArray(uint8* target) const {
+ return InternalSerializeWithCachedSizesToArray(false, target);
+ }
// Returns the result of the last call to ByteSize(). An embedded message's
// size is needed both to serialize it (because embedded messages are
@@ -267,7 +271,22 @@ class LIBPROTOBUF_EXPORT MessageLite {
// method.)
virtual int GetCachedSize() const = 0;
+ // Functions below here are not part of the public interface. It isn't
+ // enforced, but they should be treated as private, and will be private
+ // at some future time. Unfortunately the implementation of the "friend"
+ // keyword in GCC is broken at the moment, but we expect it will be fixed.
+
+ // Like SerializeWithCachedSizes, but writes directly to *target, returning
+ // a pointer to the byte immediately after the last byte written. "target"
+ // must point at a byte array of at least ByteSize() bytes. If deterministic
+ // is true then we use deterministic serialization, e.g., map keys are sorted.
+ // FOR INTERNAL USE ONLY!
+ virtual uint8* InternalSerializeWithCachedSizesToArray(bool deterministic,
+ uint8* target) const;
+
private:
+ friend class internal::WireFormatLite;
+
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageLite);
};
diff --git a/src/google/protobuf/message_unittest.cc b/src/google/protobuf/message_unittest.cc
index 2d4780fe..d668a1a6 100644
--- a/src/google/protobuf/message_unittest.cc
+++ b/src/google/protobuf/message_unittest.cc
@@ -55,6 +55,7 @@
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
diff --git a/src/google/protobuf/metadata.h b/src/google/protobuf/metadata.h
index 219645d3..fdee150b 100644
--- a/src/google/protobuf/metadata.h
+++ b/src/google/protobuf/metadata.h
@@ -56,7 +56,7 @@ namespace internal {
// The tagged pointer uses the LSB to disambiguate cases, and uses bit 0 == 0 to
// indicate an arena pointer and bit 0 == 1 to indicate a UFS+Arena-container
// pointer.
-class InternalMetadataWithArena {
+class LIBPROTOBUF_EXPORT InternalMetadataWithArena {
public:
InternalMetadataWithArena() : ptr_(NULL) {}
explicit InternalMetadataWithArena(Arena* arena)
diff --git a/src/google/protobuf/proto3_arena_lite_unittest.cc b/src/google/protobuf/proto3_arena_lite_unittest.cc
new file mode 100644
index 00000000..0f18c027
--- /dev/null
+++ b/src/google/protobuf/proto3_arena_lite_unittest.cc
@@ -0,0 +1,164 @@
+// 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 <string>
+#include <memory>
+#ifndef _SHARED_PTR_H
+#include <google/protobuf/stubs/shared_ptr.h>
+#endif
+#include <vector>
+
+#include <google/protobuf/test_util.h>
+#include <google/protobuf/unittest.pb.h>
+#include <google/protobuf/unittest_proto3_arena_lite.pb.h>
+#include <google/protobuf/arena.h>
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+using proto3_arena_lite_unittest::TestAllTypes;
+
+namespace protobuf {
+namespace {
+// We selectively set/check a few representative fields rather than all fields
+// as this test is only expected to cover the basics of arena support.
+void SetAllFields(TestAllTypes* m) {
+ m->set_optional_int32(100);
+ m->set_optional_string("asdf");
+ m->set_optional_bytes("jkl;");
+ m->mutable_optional_nested_message()->set_bb(42);
+ m->mutable_optional_foreign_message()->set_c(43);
+ m->set_optional_nested_enum(
+ proto3_arena_lite_unittest::TestAllTypes_NestedEnum_BAZ);
+ m->set_optional_foreign_enum(
+ proto3_arena_lite_unittest::FOREIGN_BAZ);
+ m->mutable_optional_lazy_message()->set_bb(45);
+ m->add_repeated_int32(100);
+ m->add_repeated_string("asdf");
+ m->add_repeated_bytes("jkl;");
+ m->add_repeated_nested_message()->set_bb(46);
+ m->add_repeated_foreign_message()->set_c(47);
+ m->add_repeated_nested_enum(
+ proto3_arena_lite_unittest::TestAllTypes_NestedEnum_BAZ);
+ m->add_repeated_foreign_enum(
+ proto3_arena_lite_unittest::FOREIGN_BAZ);
+ m->add_repeated_lazy_message()->set_bb(49);
+
+ m->set_oneof_uint32(1);
+ m->mutable_oneof_nested_message()->set_bb(50);
+ m->set_oneof_string("test"); // only this one remains set
+}
+
+void ExpectAllFieldsSet(const TestAllTypes& m) {
+ EXPECT_EQ(100, m.optional_int32());
+ EXPECT_EQ("asdf", m.optional_string());
+ EXPECT_EQ("jkl;", m.optional_bytes());
+ EXPECT_EQ(true, m.has_optional_nested_message());
+ EXPECT_EQ(42, m.optional_nested_message().bb());
+ EXPECT_EQ(true, m.has_optional_foreign_message());
+ EXPECT_EQ(43, m.optional_foreign_message().c());
+ EXPECT_EQ(proto3_arena_lite_unittest::TestAllTypes_NestedEnum_BAZ,
+ m.optional_nested_enum());
+ EXPECT_EQ(proto3_arena_lite_unittest::FOREIGN_BAZ,
+ m.optional_foreign_enum());
+ EXPECT_EQ(true, m.has_optional_lazy_message());
+ EXPECT_EQ(45, m.optional_lazy_message().bb());
+
+ EXPECT_EQ(1, m.repeated_int32_size());
+ EXPECT_EQ(100, m.repeated_int32(0));
+ EXPECT_EQ(1, m.repeated_string_size());
+ EXPECT_EQ("asdf", m.repeated_string(0));
+ EXPECT_EQ(1, m.repeated_bytes_size());
+ EXPECT_EQ("jkl;", m.repeated_bytes(0));
+ EXPECT_EQ(1, m.repeated_nested_message_size());
+ EXPECT_EQ(46, m.repeated_nested_message(0).bb());
+ EXPECT_EQ(1, m.repeated_foreign_message_size());
+ EXPECT_EQ(47, m.repeated_foreign_message(0).c());
+ EXPECT_EQ(1, m.repeated_nested_enum_size());
+ EXPECT_EQ(proto3_arena_lite_unittest::TestAllTypes_NestedEnum_BAZ,
+ m.repeated_nested_enum(0));
+ EXPECT_EQ(1, m.repeated_foreign_enum_size());
+ EXPECT_EQ(proto3_arena_lite_unittest::FOREIGN_BAZ,
+ m.repeated_foreign_enum(0));
+ EXPECT_EQ(1, m.repeated_lazy_message_size());
+ EXPECT_EQ(49, m.repeated_lazy_message(0).bb());
+
+ EXPECT_EQ(proto3_arena_lite_unittest::TestAllTypes::kOneofString,
+ m.oneof_field_case());
+ EXPECT_EQ("test", m.oneof_string());
+}
+
+// In this file we only test some basic functionalities of arena support in
+// proto3 and expect the arena support to be fully tested in proto2 unittests
+// because proto3 shares most code with proto2.
+
+TEST(Proto3ArenaLiteTest, Parsing) {
+ TestAllTypes original;
+ SetAllFields(&original);
+
+ Arena arena;
+ TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
+ arena_message->ParseFromString(original.SerializeAsString());
+ ExpectAllFieldsSet(*arena_message);
+}
+
+TEST(Proto3ArenaLiteTest, Swap) {
+ Arena arena1;
+ Arena arena2;
+
+ // Test Swap().
+ TestAllTypes* arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
+ TestAllTypes* arena2_message = Arena::CreateMessage<TestAllTypes>(&arena2);
+ arena1_message->Swap(arena2_message);
+ EXPECT_EQ(&arena1, arena1_message->GetArena());
+ EXPECT_EQ(&arena2, arena2_message->GetArena());
+}
+
+TEST(Proto3ArenaLiteTest, SetAllocatedMessage) {
+ Arena arena;
+ TestAllTypes *arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
+ TestAllTypes::NestedMessage* nested = new TestAllTypes::NestedMessage;
+ nested->set_bb(118);
+ arena_message->set_allocated_optional_nested_message(nested);
+ EXPECT_EQ(118, arena_message->optional_nested_message().bb());
+}
+
+TEST(Proto3ArenaLiteTest, ReleaseMessage) {
+ Arena arena;
+ TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
+ arena_message->mutable_optional_nested_message()->set_bb(118);
+ google::protobuf::scoped_ptr<TestAllTypes::NestedMessage> nested(
+ arena_message->release_optional_nested_message());
+ EXPECT_EQ(118, nested->bb());
+}
+
+} // namespace
+} // namespace protobuf
+} // namespace google
diff --git a/src/google/protobuf/proto3_lite_unittest.cc b/src/google/protobuf/proto3_lite_unittest.cc
new file mode 100644
index 00000000..2e2beea9
--- /dev/null
+++ b/src/google/protobuf/proto3_lite_unittest.cc
@@ -0,0 +1,145 @@
+// 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 <string>
+#include <memory>
+#ifndef _SHARED_PTR_H
+#include <google/protobuf/stubs/shared_ptr.h>
+#endif
+#include <vector>
+
+#include <google/protobuf/test_util.h>
+#include <google/protobuf/unittest.pb.h>
+#include <google/protobuf/unittest_proto3_lite.pb.h>
+#include <google/protobuf/arena.h>
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+using proto3_lite_unittest::TestAllTypes;
+
+namespace protobuf {
+namespace {
+// We selectively set/check a few representative fields rather than all fields
+// as this test is only expected to cover the basics of lite support.
+void SetAllFields(TestAllTypes* m) {
+ m->set_optional_int32(100);
+ m->set_optional_string("asdf");
+ m->set_optional_bytes("jkl;");
+ m->mutable_optional_nested_message()->set_bb(42);
+ m->mutable_optional_foreign_message()->set_c(43);
+ m->set_optional_nested_enum(
+ proto3_lite_unittest::TestAllTypes_NestedEnum_BAZ);
+ m->set_optional_foreign_enum(
+ proto3_lite_unittest::FOREIGN_BAZ);
+ m->mutable_optional_lazy_message()->set_bb(45);
+ m->add_repeated_int32(100);
+ m->add_repeated_string("asdf");
+ m->add_repeated_bytes("jkl;");
+ m->add_repeated_nested_message()->set_bb(46);
+ m->add_repeated_foreign_message()->set_c(47);
+ m->add_repeated_nested_enum(
+ proto3_lite_unittest::TestAllTypes_NestedEnum_BAZ);
+ m->add_repeated_foreign_enum(
+ proto3_lite_unittest::FOREIGN_BAZ);
+ m->add_repeated_lazy_message()->set_bb(49);
+
+ m->set_oneof_uint32(1);
+ m->mutable_oneof_nested_message()->set_bb(50);
+ m->set_oneof_string("test"); // only this one remains set
+}
+
+void ExpectAllFieldsSet(const TestAllTypes& m) {
+ EXPECT_EQ(100, m.optional_int32());
+ EXPECT_EQ("asdf", m.optional_string());
+ EXPECT_EQ("jkl;", m.optional_bytes());
+ EXPECT_EQ(true, m.has_optional_nested_message());
+ EXPECT_EQ(42, m.optional_nested_message().bb());
+ EXPECT_EQ(true, m.has_optional_foreign_message());
+ EXPECT_EQ(43, m.optional_foreign_message().c());
+ EXPECT_EQ(proto3_lite_unittest::TestAllTypes_NestedEnum_BAZ,
+ m.optional_nested_enum());
+ EXPECT_EQ(proto3_lite_unittest::FOREIGN_BAZ,
+ m.optional_foreign_enum());
+ EXPECT_EQ(true, m.has_optional_lazy_message());
+ EXPECT_EQ(45, m.optional_lazy_message().bb());
+
+ EXPECT_EQ(1, m.repeated_int32_size());
+ EXPECT_EQ(100, m.repeated_int32(0));
+ EXPECT_EQ(1, m.repeated_string_size());
+ EXPECT_EQ("asdf", m.repeated_string(0));
+ EXPECT_EQ(1, m.repeated_bytes_size());
+ EXPECT_EQ("jkl;", m.repeated_bytes(0));
+ EXPECT_EQ(1, m.repeated_nested_message_size());
+ EXPECT_EQ(46, m.repeated_nested_message(0).bb());
+ EXPECT_EQ(1, m.repeated_foreign_message_size());
+ EXPECT_EQ(47, m.repeated_foreign_message(0).c());
+ EXPECT_EQ(1, m.repeated_nested_enum_size());
+ EXPECT_EQ(proto3_lite_unittest::TestAllTypes_NestedEnum_BAZ,
+ m.repeated_nested_enum(0));
+ EXPECT_EQ(1, m.repeated_foreign_enum_size());
+ EXPECT_EQ(proto3_lite_unittest::FOREIGN_BAZ,
+ m.repeated_foreign_enum(0));
+ EXPECT_EQ(1, m.repeated_lazy_message_size());
+ EXPECT_EQ(49, m.repeated_lazy_message(0).bb());
+
+ EXPECT_EQ(proto3_lite_unittest::TestAllTypes::kOneofString,
+ m.oneof_field_case());
+ EXPECT_EQ("test", m.oneof_string());
+}
+
+// In this file we only test some basic functionalities of in proto3 and expect
+// the rest is fully tested in proto2 unittests because proto3 shares most code
+// with proto2.
+
+TEST(Proto3LiteTest, Parsing) {
+ TestAllTypes original;
+ SetAllFields(&original);
+
+ TestAllTypes msg;
+ msg.ParseFromString(original.SerializeAsString());
+ ExpectAllFieldsSet(msg);
+}
+
+TEST(Proto3LiteTest, Swap) {
+ // Test Swap().
+ TestAllTypes msg1;
+ TestAllTypes msg2;
+ msg1.set_optional_string("123");
+ msg2.set_optional_string("3456");
+ msg1.Swap(&msg2);
+ EXPECT_EQ("3456", msg1.optional_string());
+ EXPECT_EQ("123", msg2.optional_string());
+ EXPECT_EQ(msg1.ByteSize(), msg2.ByteSize() + 1);
+}
+
+} // namespace
+} // namespace protobuf
+} // namespace google
diff --git a/src/google/protobuf/reflection.h b/src/google/protobuf/reflection.h
index 671aafdc..2391f453 100755
--- a/src/google/protobuf/reflection.h
+++ b/src/google/protobuf/reflection.h
@@ -356,7 +356,7 @@ class LIBPROTOBUF_EXPORT RepeatedFieldAccessor {
virtual void Swap(Field* data, const RepeatedFieldAccessor* other_mutator,
Field* other_data) const = 0;
- // Create an iterator that points at the begining of the repeated field.
+ // Create an iterator that points at the beginning of the repeated field.
virtual Iterator* BeginIterator(const Field* data) const = 0;
// Create an iterator that points at the end of the repeated field.
virtual Iterator* EndIterator(const Field* data) const = 0;
diff --git a/src/google/protobuf/repeated_field.cc b/src/google/protobuf/repeated_field.cc
index 949e0a23..77004f59 100644
--- a/src/google/protobuf/repeated_field.cc
+++ b/src/google/protobuf/repeated_field.cc
@@ -52,8 +52,8 @@ void** RepeatedPtrFieldBase::InternalExtend(int extend_amount) {
}
Rep* old_rep = rep_;
Arena* arena = GetArenaNoVirtual();
- new_size = max(kMinRepeatedFieldAllocationSize,
- max(total_size_ * 2, new_size));
+ new_size = std::max(kMinRepeatedFieldAllocationSize,
+ std::max(total_size_ * 2, new_size));
GOOGLE_CHECK_LE(new_size,
(std::numeric_limits<size_t>::max() - kRepHeaderSize) /
sizeof(old_rep->elements[0]))
diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h
index 5530fefe..bc567555 100644
--- a/src/google/protobuf/repeated_field.h
+++ b/src/google/protobuf/repeated_field.h
@@ -208,10 +208,19 @@ class RepeatedField {
// sizeof(*this)
int SpaceUsedExcludingSelf() const;
- // Remove the element referenced by position.
+ // Removes the element referenced by position.
+ //
+ // Returns an iterator to the element immediately following the removed
+ // element.
+ //
+ // Invalidates all iterators at or after the removed element, including end().
iterator erase(const_iterator position);
- // Remove the elements in the range [first, last).
+ // Removes the elements in the range [first, last).
+ //
+ // Returns an iterator to the element immediately following the removed range.
+ //
+ // Invalidates all iterators at or after the removed range, including end().
iterator erase(const_iterator first, const_iterator last);
// Get the Arena on which this RepeatedField stores its elements.
@@ -235,7 +244,7 @@ class RepeatedField {
int total_size_;
struct Rep {
Arena* arena;
- Element elements[1];
+ Element elements[1];
};
// 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
@@ -263,6 +272,22 @@ class RepeatedField {
inline Arena* GetArenaNoVirtual() const {
return (rep_ == NULL) ? NULL : rep_->arena;
}
+
+ // 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::~Element();
+ }
+ if (rep->arena == NULL) {
+ delete[] reinterpret_cast<char*>(rep);
+ }
+ }
+ }
};
template<typename Element>
@@ -539,12 +564,16 @@ class GenericTypeHandler {
return ::google::protobuf::Arena::CreateMaybeMessage<Type>(
arena, static_cast<GenericType*>(0));
}
- // We force NewFromPrototype() and Delete() to be non-inline to reduce code
- // size: else, several other methods get inlined copies of message types'
- // constructors and destructors.
+ // We force NewFromPrototype() to be non-inline to reduce code size:
+ // else, several other methods get inlined copies of message types'
+ // constructors.
GOOGLE_ATTRIBUTE_NOINLINE static GenericType* NewFromPrototype(
const GenericType* prototype, ::google::protobuf::Arena* arena = NULL);
- GOOGLE_ATTRIBUTE_NOINLINE static void Delete(GenericType* value, Arena* arena);
+ static inline void Delete(GenericType* value, Arena* arena) {
+ if (arena == NULL) {
+ delete value;
+ }
+ }
static inline ::google::protobuf::Arena* GetArena(GenericType* value) {
return ::google::protobuf::Arena::GetArena<Type>(value);
}
@@ -565,16 +594,10 @@ class GenericTypeHandler {
template <typename GenericType>
GenericType* GenericTypeHandler<GenericType>::NewFromPrototype(
- const GenericType* prototype, ::google::protobuf::Arena* arena) {
+ const GenericType* /* prototype */, ::google::protobuf::Arena* arena) {
return New(arena);
}
template <typename GenericType>
-void GenericTypeHandler<GenericType>::Delete(GenericType* value, Arena* arena) {
- if (arena == NULL) {
- delete value;
- }
-}
-template <typename GenericType>
void GenericTypeHandler<GenericType>::Merge(const GenericType& from,
GenericType* to) {
to->MergeFrom(from);
@@ -601,6 +624,13 @@ inline void* GenericTypeHandler<MessageLite>::GetMaybeArenaPointer(
template <>
void GenericTypeHandler<MessageLite>::Merge(const MessageLite& from,
MessageLite* to);
+template<>
+inline void GenericTypeHandler<string>::Clear(string* value) {
+ value->clear();
+}
+template<>
+void GenericTypeHandler<string>::Merge(const string& from,
+ string* to);
// Declarations of the specialization as we cannot define them here, as the
// header that defines ProtocolMessage depends on types defined in this header.
@@ -618,7 +648,7 @@ void GenericTypeHandler<MessageLite>::Merge(const MessageLite& from,
// Message specialization bodies defined in message.cc. This split is necessary
// to allow proto2-lite (which includes this header) to be independent of
// Message.
-DECLARE_SPECIALIZATIONS_FOR_BASE_PROTO_TYPES(Message);
+DECLARE_SPECIALIZATIONS_FOR_BASE_PROTO_TYPES(Message)
#undef DECLARE_SPECIALIZATIONS_FOR_BASE_PROTO_TYPES
@@ -665,7 +695,7 @@ class LIBPROTOBUF_EXPORT StringTypeHandlerBase {
static inline ::google::protobuf::Arena* GetArena(string*) {
return NULL;
}
- static inline void* GetMaybeArenaPointer(string* value) {
+ static inline void* GetMaybeArenaPointer(string* /* value */) {
return NULL;
}
static inline void Delete(string* value, Arena* arena) {
@@ -683,7 +713,7 @@ class LIBPROTOBUF_EXPORT StringTypeHandlerBase {
class StringTypeHandler : public StringTypeHandlerBase {
public:
static int SpaceUsed(const string& value) {
- return sizeof(value) + StringSpaceUsedExcludingSelf(value);
+ return static_cast<int>(sizeof(value)) + StringSpaceUsedExcludingSelf(value);
}
};
@@ -827,6 +857,15 @@ class RepeatedPtrField : public internal::RepeatedPtrFieldBase {
// Add an already-allocated object, skipping arena-ownership checks. The user
// must guarantee that the given object is in the same arena as this
// RepeatedPtrField.
+ // It is also useful in legacy code that uses temporary ownership to avoid
+ // copies. Example:
+ // RepeatedPtrField<T> temp_field;
+ // temp_field.AddAllocated(new T);
+ // ... // Do something with temp_field
+ // temp_field.ExtractSubrange(0, temp_field.size(), NULL);
+ // If you put temp_field on the arena this fails, because the ownership
+ // transfers to the arena at the "AddAllocated" call and is not released
+ // anymore causing a double delete. UnsafeArenaAddAllocated prevents this.
void UnsafeArenaAddAllocated(Element* value);
// Remove the last element and return it. Works only when operating on an
@@ -885,10 +924,19 @@ class RepeatedPtrField : public internal::RepeatedPtrFieldBase {
// so will trigger a GOOGLE_DCHECK-failure.
Element* ReleaseCleared();
- // Remove the element referenced by position.
+ // Removes the element referenced by position.
+ //
+ // Returns an iterator to the element immediately following the removed
+ // element.
+ //
+ // Invalidates all iterators at or after the removed element, including end().
iterator erase(const_iterator position);
// Removes the elements in the range [first, last).
+ //
+ // Returns an iterator to the element immediately following the removed range.
+ //
+ // Invalidates all iterators at or after the removed range, including end().
iterator erase(const_iterator first, const_iterator last);
// Gets the arena on which this RepeatedPtrField stores its elements.
@@ -974,19 +1022,8 @@ RepeatedField<Element>::RepeatedField(Iter begin, const Iter& end)
template <typename Element>
RepeatedField<Element>::~RepeatedField() {
// See explanation in Reserve(): we need to invoke destructors here for the
- // case that Element has a non-trivial destructor. If Element has a trivial
- // destructor (for example, if it's a primitive type, like int32), this entire
- // loop will be removed by the optimizer.
- if (rep_ != NULL) {
- Element* e = &rep_->elements[0];
- Element* limit = &rep_->elements[total_size_];
- for (; e < limit; e++) {
- e->Element::~Element();
- }
- if (rep_->arena == NULL) {
- delete[] reinterpret_cast<char*>(rep_);
- }
- }
+ // case that Element has a non-trivial destructor.
+ InternalDeallocate(rep_, total_size_);
}
template <typename Element>
@@ -1222,8 +1259,8 @@ void RepeatedField<Element>::Reserve(int new_size) {
if (total_size_ >= new_size) return;
Rep* old_rep = rep_;
Arena* arena = GetArenaNoVirtual();
- new_size = max(google::protobuf::internal::kMinRepeatedFieldAllocationSize,
- max(total_size_ * 2, new_size));
+ new_size = std::max(google::protobuf::internal::kMinRepeatedFieldAllocationSize,
+ std::max(total_size_ * 2, new_size));
GOOGLE_CHECK_LE(static_cast<size_t>(new_size),
(std::numeric_limits<size_t>::max() - kRepHeaderSize) /
sizeof(Element))
@@ -1256,18 +1293,10 @@ void RepeatedField<Element>::Reserve(int new_size) {
if (current_size_ > 0) {
MoveArray(rep_->elements, old_rep->elements, current_size_);
}
- if (old_rep) {
- // Likewise, we need to invoke destructors on the old array. If Element has
- // no destructor, this loop will disappear.
- e = &old_rep->elements[0];
- limit = &old_rep->elements[old_total_size];
- for (; e < limit; e++) {
- e->Element::~Element();
- }
- if (arena == NULL) {
- delete[] reinterpret_cast<char*>(old_rep);
- }
- }
+
+ // Likewise, we need to invoke destructors on the old array.
+ InternalDeallocate(old_rep, old_total_size);
+
}
template <typename Element>
@@ -1328,13 +1357,13 @@ inline RepeatedPtrFieldBase::RepeatedPtrFieldBase(::google::protobuf::Arena* are
template <typename TypeHandler>
void RepeatedPtrFieldBase::Destroy() {
- if (rep_ != NULL) {
- for (int i = 0; i < rep_->allocated_size; i++) {
- TypeHandler::Delete(cast<TypeHandler>(rep_->elements[i]), arena_);
- }
- if (arena_ == NULL) {
- delete [] reinterpret_cast<char*>(rep_);
+ if (rep_ != NULL && arena_ == NULL) {
+ int n = rep_->allocated_size;
+ void* const* elements = rep_->elements;
+ for (int i = 0; i < n; i++) {
+ TypeHandler::Delete(cast<TypeHandler>(elements[i]), NULL);
}
+ delete[] reinterpret_cast<char*>(rep_);
}
rep_ = NULL;
}
@@ -2334,7 +2363,7 @@ template<typename T> class RepeatedPtrFieldBackInsertIterator
RepeatedPtrField<T>* field_;
};
-// A back inserter for RepeatedPtrFields that inserts by transfering ownership
+// A back inserter for RepeatedPtrFields that inserts by transferring ownership
// of a pointer.
template<typename T> class AllocatedRepeatedPtrFieldBackInsertIterator
: public std::iterator<std::output_iterator_tag, T> {
@@ -2362,6 +2391,37 @@ template<typename T> class AllocatedRepeatedPtrFieldBackInsertIterator
private:
RepeatedPtrField<T>* field_;
};
+
+// Almost identical to AllocatedRepeatedPtrFieldBackInsertIterator. This one
+// uses the UnsafeArenaAddAllocated instead.
+template<typename T>
+class UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator
+ : public std::iterator<std::output_iterator_tag, T> {
+ public:
+ explicit UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator(
+ ::google::protobuf::RepeatedPtrField<T>* const mutable_field)
+ : field_(mutable_field) {
+ }
+ UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator<T>& operator=(
+ T const* const ptr_to_value) {
+ field_->UnsafeArenaAddAllocated(const_cast<T*>(ptr_to_value));
+ return *this;
+ }
+ UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator<T>& operator*() {
+ return *this;
+ }
+ UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator<T>& operator++() {
+ return *this;
+ }
+ UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator<T>& operator++(
+ int /* unused */) {
+ return *this;
+ }
+
+ private:
+ ::google::protobuf::RepeatedPtrField<T>* field_;
+};
+
} // namespace internal
// Provides a back insert iterator for RepeatedField instances,
@@ -2396,6 +2456,25 @@ AllocatedRepeatedPtrFieldBackInserter(
mutable_field);
}
+// Similar to AllocatedRepeatedPtrFieldBackInserter, using
+// UnsafeArenaAddAllocated instead of AddAllocated.
+// This is slightly faster if that matters. It is also useful in legacy code
+// that uses temporary ownership to avoid copies. Example:
+// RepeatedPtrField<T> temp_field;
+// temp_field.AddAllocated(new T);
+// ... // Do something with temp_field
+// temp_field.ExtractSubrange(0, temp_field.size(), NULL);
+// If you put temp_field on the arena this fails, because the ownership
+// transfers to the arena at the "AddAllocated" call and is not released anymore
+// causing a double delete. Using UnsafeArenaAddAllocated prevents this.
+template<typename T>
+internal::UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator<T>
+UnsafeArenaAllocatedRepeatedPtrFieldBackInserter(
+ ::google::protobuf::RepeatedPtrField<T>* const mutable_field) {
+ return internal::UnsafeArenaAllocatedRepeatedPtrFieldBackInsertIterator<T>(
+ mutable_field);
+}
+
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/repeated_field_reflection.h b/src/google/protobuf/repeated_field_reflection.h
deleted file mode 100644
index 44d14d5b..00000000
--- a/src/google/protobuf/repeated_field_reflection.h
+++ /dev/null
@@ -1,337 +0,0 @@
-// 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.
-
-// This header file is protobuf internal. Users should not include this
-// file directly.
-#ifndef GOOGLE_PROTOBUF_REPEATED_FIELD_REFLECTION_H__
-#define GOOGLE_PROTOBUF_REPEATED_FIELD_REFLECTION_H__
-
-#include <memory>
-#ifndef _SHARED_PTR_H
-#include <google/protobuf/stubs/shared_ptr.h>
-#endif
-
-#include <google/protobuf/generated_enum_reflection.h>
-
-namespace google {
-namespace protobuf {
-namespace internal {
-// Interfaces used to implement reflection RepeatedFieldRef API.
-// Reflection::GetRepeatedAccessor() should return a pointer to an singleton
-// object that implements the below interface.
-//
-// This interface passes/returns values using void pointers. The actual type
-// of the value depends on the field's cpp_type. Following is a mapping from
-// cpp_type to the type that should be used in this interface:
-//
-// field->cpp_type() T Actual type of void*
-// CPPTYPE_INT32 int32 int32
-// CPPTYPE_UINT32 uint32 uint32
-// CPPTYPE_INT64 int64 int64
-// CPPTYPE_UINT64 uint64 uint64
-// CPPTYPE_DOUBLE double double
-// CPPTYPE_FLOAT float float
-// CPPTYPE_BOOL bool bool
-// CPPTYPE_ENUM generated enum type int32
-// CPPTYPE_STRING string string
-// CPPTYPE_MESSAGE generated message type google::protobuf::Message
-// or google::protobuf::Message
-//
-// Note that for enums we use int32 in the interface.
-//
-// You can map from T to the actual type using RefTypeTraits:
-// typedef RefTypeTraits<T>::AccessorValueType ActualType;
-class LIBPROTOBUF_EXPORT RepeatedFieldAccessor {
- public:
- // Typedefs for clarity.
- typedef void Field;
- typedef void Value;
- typedef void Iterator;
-
- virtual ~RepeatedFieldAccessor();
- virtual bool IsEmpty(const Field* data) const = 0;
- virtual int Size(const Field* data) const = 0;
- // Depends on the underlying representation of the repeated field, this
- // method can return a pointer to the underlying object if such an object
- // exists, or fill the data into scratch_space and return scratch_space.
- // Callers of this method must ensure scratch_space is a valid pointer
- // to a mutable object of the correct type.
- virtual const Value* Get(
- const Field* data, int index, Value* scratch_space) const = 0;
-
- virtual void Clear(Field* data) const = 0;
- virtual void Set(Field* data, int index, const Value* value) const = 0;
- virtual void Add(Field* data, const Value* value) const = 0;
- virtual void RemoveLast(Field* data) const = 0;
- virtual void SwapElements(Field* data, int index1, int index2) const = 0;
- virtual void Swap(Field* data, const RepeatedFieldAccessor* other_mutator,
- Field* other_data) const = 0;
-
- // Create an iterator that points at the begining of the repeated field.
- virtual Iterator* BeginIterator(const Field* data) const = 0;
- // Create an iterator that points at the end of the repeated field.
- virtual Iterator* EndIterator(const Field* data) const = 0;
- // Make a copy of an iterator and return the new copy.
- virtual Iterator* CopyIterator(const Field* data,
- const Iterator* iterator) const = 0;
- // Move an iterator to point to the next element.
- virtual Iterator* AdvanceIterator(const Field* data,
- Iterator* iterator) const = 0;
- // Compare whether two iterators point to the same element.
- virtual bool EqualsIterator(const Field* data, const Iterator* a,
- const Iterator* b) const = 0;
- // Delete an iterator created by BeginIterator(), EndIterator() and
- // CopyIterator().
- virtual void DeleteIterator(const Field* data, Iterator* iterator) const = 0;
- // Like Get() but for iterators.
- virtual const Value* GetIteratorValue(const Field* data,
- const Iterator* iterator,
- Value* scratch_space) const = 0;
-
- // Templated methods that make using this interface easier for non-message
- // types.
- template<typename T>
- T Get(const Field* data, int index) const {
- typedef typename RefTypeTraits<T>::AccessorValueType ActualType;
- ActualType scratch_space;
- return static_cast<T>(
- *reinterpret_cast<const ActualType*>(
- Get(data, index, static_cast<Value*>(&scratch_space))));
- }
-
- template<typename T, typename ValueType>
- void Set(Field* data, int index, const ValueType& value) const {
- typedef typename RefTypeTraits<T>::AccessorValueType ActualType;
- // In this RepeatedFieldAccessor interface we pass/return data using
- // raw pointers. Type of the data these raw pointers point to should
- // be ActualType. Here we have a ValueType object and want a ActualType
- // pointer. We can't cast a ValueType pointer to an ActualType pointer
- // directly because their type might be different (for enums ValueType
- // may be a generated enum type while ActualType is int32). To be safe
- // we make a copy to get a temporary ActualType object and use it.
- ActualType tmp = static_cast<ActualType>(value);
- Set(data, index, static_cast<const Value*>(&tmp));
- }
-
- template<typename T, typename ValueType>
- void Add(Field* data, const ValueType& value) const {
- typedef typename RefTypeTraits<T>::AccessorValueType ActualType;
- // In this RepeatedFieldAccessor interface we pass/return data using
- // raw pointers. Type of the data these raw pointers point to should
- // be ActualType. Here we have a ValueType object and want a ActualType
- // pointer. We can't cast a ValueType pointer to an ActualType pointer
- // directly because their type might be different (for enums ValueType
- // may be a generated enum type while ActualType is int32). To be safe
- // we make a copy to get a temporary ActualType object and use it.
- ActualType tmp = static_cast<ActualType>(value);
- Add(data, static_cast<const Value*>(&tmp));
- }
-};
-
-// Implement (Mutable)RepeatedFieldRef::iterator
-template<typename T>
-class RepeatedFieldRefIterator
- : public std::iterator<std::forward_iterator_tag, T> {
- typedef typename RefTypeTraits<T>::AccessorValueType AccessorValueType;
- typedef typename RefTypeTraits<T>::IteratorValueType IteratorValueType;
- typedef typename RefTypeTraits<T>::IteratorPointerType IteratorPointerType;
-
- public:
- // Constructor for non-message fields.
- RepeatedFieldRefIterator(const void* data,
- const RepeatedFieldAccessor* accessor,
- bool begin)
- : data_(data), accessor_(accessor),
- iterator_(begin ? accessor->BeginIterator(data) :
- accessor->EndIterator(data)),
- scratch_space_(new AccessorValueType) {
- }
- // Constructor for message fields.
- RepeatedFieldRefIterator(const void* data,
- const RepeatedFieldAccessor* accessor,
- bool begin,
- AccessorValueType* scratch_space)
- : data_(data), accessor_(accessor),
- iterator_(begin ? accessor->BeginIterator(data) :
- accessor->EndIterator(data)),
- scratch_space_(scratch_space) {
- }
- ~RepeatedFieldRefIterator() {
- accessor_->DeleteIterator(data_, iterator_);
- }
- RepeatedFieldRefIterator operator++(int) {
- RepeatedFieldRefIterator tmp(*this);
- iterator_ = accessor_->AdvanceIterator(data_, iterator_);
- return tmp;
- }
- RepeatedFieldRefIterator& operator++() {
- iterator_ = accessor_->AdvanceIterator(data_, iterator_);
- return *this;
- }
- IteratorValueType operator*() const {
- return static_cast<IteratorValueType>(
- *static_cast<const AccessorValueType*>(
- accessor_->GetIteratorValue(
- data_, iterator_, scratch_space_.get())));
- }
- IteratorPointerType operator->() const {
- return static_cast<IteratorPointerType>(
- accessor_->GetIteratorValue(
- data_, iterator_, scratch_space_.get()));
- }
- bool operator!=(const RepeatedFieldRefIterator& other) const {
- assert(data_ == other.data_);
- assert(accessor_ == other.accessor_);
- return !accessor_->EqualsIterator(data_, iterator_, other.iterator_);
- }
- bool operator==(const RepeatedFieldRefIterator& other) const {
- return !this->operator!=(other);
- }
-
- RepeatedFieldRefIterator(const RepeatedFieldRefIterator& other)
- : data_(other.data_), accessor_(other.accessor_),
- iterator_(accessor_->CopyIterator(data_, other.iterator_)) {
- }
- RepeatedFieldRefIterator& operator=(const RepeatedFieldRefIterator& other) {
- if (this != &other) {
- accessor_->DeleteIterator(data_, iterator_);
- data_ = other.data_;
- accessor_ = other.accessor_;
- iterator_ = accessor_->CopyIterator(data_, other.iterator_);
- }
- return *this;
- }
-
- protected:
- const void* data_;
- const RepeatedFieldAccessor* accessor_;
- void* iterator_;
- google::protobuf::scoped_ptr<AccessorValueType> scratch_space_;
-};
-
-// TypeTraits that maps the type parameter T of RepeatedFieldRef or
-// MutableRepeatedFieldRef to corresponding iterator type,
-// RepeatedFieldAccessor type, etc.
-template<typename T>
-struct PrimitiveTraits {
- static const bool is_primitive = false;
-};
-#define DEFINE_PRIMITIVE(TYPE, type) \
- template<> struct PrimitiveTraits<type> { \
- static const bool is_primitive = true; \
- static const FieldDescriptor::CppType cpp_type = \
- FieldDescriptor::CPPTYPE_ ## TYPE; \
- };
-DEFINE_PRIMITIVE(INT32, int32)
-DEFINE_PRIMITIVE(UINT32, uint32)
-DEFINE_PRIMITIVE(INT64, int64)
-DEFINE_PRIMITIVE(UINT64, uint64)
-DEFINE_PRIMITIVE(FLOAT, float)
-DEFINE_PRIMITIVE(DOUBLE, double)
-DEFINE_PRIMITIVE(BOOL, bool)
-#undef DEFINE_PRIMITIVE
-
-template<typename T>
-struct RefTypeTraits<
- T, typename internal::enable_if<PrimitiveTraits<T>::is_primitive>::type> {
- typedef RepeatedFieldRefIterator<T> iterator;
- typedef RepeatedFieldAccessor AccessorType;
- typedef T AccessorValueType;
- typedef T IteratorValueType;
- typedef T* IteratorPointerType;
- static const FieldDescriptor::CppType cpp_type =
- PrimitiveTraits<T>::cpp_type;
- static const Descriptor* GetMessageFieldDescriptor() {
- return NULL;
- }
-};
-
-template<typename T>
-struct RefTypeTraits<
- T, typename internal::enable_if<is_proto_enum<T>::value>::type> {
- typedef RepeatedFieldRefIterator<T> iterator;
- typedef RepeatedFieldAccessor AccessorType;
- // We use int32 for repeated enums in RepeatedFieldAccessor.
- typedef int32 AccessorValueType;
- typedef T IteratorValueType;
- typedef int32* IteratorPointerType;
- static const FieldDescriptor::CppType cpp_type =
- FieldDescriptor::CPPTYPE_ENUM;
- static const Descriptor* GetMessageFieldDescriptor() {
- return NULL;
- }
-};
-
-template<typename T>
-struct RefTypeTraits<
- T, typename internal::enable_if<internal::is_same<string, T>::value>::type> {
- typedef RepeatedFieldRefIterator<T> iterator;
- typedef RepeatedFieldAccessor AccessorType;
- typedef string AccessorValueType;
- typedef string IteratorValueType;
- typedef string* IteratorPointerType;
- static const FieldDescriptor::CppType cpp_type =
- FieldDescriptor::CPPTYPE_STRING;
- static const Descriptor* GetMessageFieldDescriptor() {
- return NULL;
- }
-};
-
-template<typename T>
-struct MessageDescriptorGetter {
- static const Descriptor* get() {
- return T::default_instance().GetDescriptor();
- }
-};
-template<>
-struct MessageDescriptorGetter<Message> {
- static const Descriptor* get() {
- return NULL;
- }
-};
-
-template<typename T>
-struct RefTypeTraits<
- T, typename internal::enable_if<internal::is_base_of<Message, T>::value>::type> {
- typedef RepeatedFieldRefIterator<T> iterator;
- typedef RepeatedFieldAccessor AccessorType;
- typedef Message AccessorValueType;
- typedef const T& IteratorValueType;
- typedef const T* IteratorPointerType;
- static const FieldDescriptor::CppType cpp_type =
- FieldDescriptor::CPPTYPE_MESSAGE;
- static const Descriptor* GetMessageFieldDescriptor() {
- return MessageDescriptorGetter<T>::get();
- }
-};
-} // namespace internal
-} // namespace protobuf
-} // namespace google
-#endif // GOOGLE_PROTOBUF_REPEATED_FIELD_REFLECTION_H__
diff --git a/src/google/protobuf/repeated_field_unittest.cc b/src/google/protobuf/repeated_field_unittest.cc
index b45664b0..39b24b33 100644
--- a/src/google/protobuf/repeated_field_unittest.cc
+++ b/src/google/protobuf/repeated_field_unittest.cc
@@ -1522,6 +1522,44 @@ TEST_F(RepeatedFieldInsertionIteratorsTest,
EXPECT_EQ(testproto.DebugString(), goldenproto.DebugString());
}
+TEST_F(RepeatedFieldInsertionIteratorsTest,
+ UnsafeArenaAllocatedRepeatedPtrFieldWithStringIntData) {
+ vector<Nested*> data;
+ TestAllTypes goldenproto;
+ for (int i = 0; i < 10; ++i) {
+ Nested* new_data = new Nested;
+ new_data->set_bb(i);
+ data.push_back(new_data);
+
+ new_data = goldenproto.add_repeated_nested_message();
+ new_data->set_bb(i);
+ }
+ TestAllTypes testproto;
+ std::copy(data.begin(), data.end(),
+ UnsafeArenaAllocatedRepeatedPtrFieldBackInserter(
+ testproto.mutable_repeated_nested_message()));
+ EXPECT_EQ(testproto.DebugString(), goldenproto.DebugString());
+}
+
+TEST_F(RepeatedFieldInsertionIteratorsTest,
+ UnsafeArenaAllocatedRepeatedPtrFieldWithString) {
+ vector<string*> data;
+ TestAllTypes goldenproto;
+ for (int i = 0; i < 10; ++i) {
+ string* new_data = new string;
+ *new_data = "name-" + SimpleItoa(i);
+ data.push_back(new_data);
+
+ new_data = goldenproto.add_repeated_string();
+ *new_data = "name-" + SimpleItoa(i);
+ }
+ TestAllTypes testproto;
+ std::copy(data.begin(), data.end(),
+ UnsafeArenaAllocatedRepeatedPtrFieldBackInserter(
+ testproto.mutable_repeated_string()));
+ EXPECT_EQ(testproto.DebugString(), goldenproto.DebugString());
+}
+
} // namespace
} // namespace protobuf
diff --git a/src/google/protobuf/source_context.pb.cc b/src/google/protobuf/source_context.pb.cc
index 1be3297e..5cc77bf3 100644
--- a/src/google/protobuf/source_context.pb.cc
+++ b/src/google/protobuf/source_context.pb.cc
@@ -7,6 +7,7 @@
#include <algorithm>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/port.h>
#include <google/protobuf/stubs/once.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/wire_format_lite_inl.h>
@@ -28,6 +29,7 @@ const ::google::protobuf::internal::GeneratedMessageReflection*
} // namespace
+void protobuf_AssignDesc_google_2fprotobuf_2fsource_5fcontext_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AssignDesc_google_2fprotobuf_2fsource_5fcontext_2eproto() {
protobuf_AddDesc_google_2fprotobuf_2fsource_5fcontext_2eproto();
const ::google::protobuf::FileDescriptor* file =
@@ -59,6 +61,7 @@ inline void protobuf_AssignDescriptorsOnce() {
&protobuf_AssignDesc_google_2fprotobuf_2fsource_5fcontext_2eproto);
}
+void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
void protobuf_RegisterTypes(const ::std::string&) {
protobuf_AssignDescriptorsOnce();
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
@@ -72,6 +75,7 @@ void protobuf_ShutdownFile_google_2fprotobuf_2fsource_5fcontext_2eproto() {
delete SourceContext_reflection_;
}
+void protobuf_AddDesc_google_2fprotobuf_2fsource_5fcontext_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AddDesc_google_2fprotobuf_2fsource_5fcontext_2eproto() {
static bool already_here = false;
if (already_here) return;
@@ -98,16 +102,6 @@ struct StaticDescriptorInitializer_google_2fprotobuf_2fsource_5fcontext_2eproto
}
} static_descriptor_initializer_google_2fprotobuf_2fsource_5fcontext_2eproto_;
-namespace {
-
-static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD;
-static void MergeFromFail(int line) {
- GOOGLE_CHECK(false) << __FILE__ << ":" << line;
-}
-
-} // namespace
-
-
// ===================================================================
#if !defined(_MSC_VER) || _MSC_VER >= 1900
@@ -176,12 +170,13 @@ SourceContext* SourceContext::New(::google::protobuf::Arena* arena) const {
}
void SourceContext::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.SourceContext)
file_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
bool SourceContext::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.SourceContext)
for (;;) {
@@ -242,8 +237,8 @@ void SourceContext::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.SourceContext)
}
-::google::protobuf::uint8* SourceContext::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* SourceContext::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.SourceContext)
// optional string file_name = 1;
if (this->file_name().size() > 0) {
@@ -261,6 +256,7 @@ void SourceContext::SerializeWithCachedSizes(
}
int SourceContext::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.SourceContext)
int total_size = 0;
// optional string file_name = 1;
@@ -277,19 +273,27 @@ int SourceContext::ByteSize() const {
}
void SourceContext::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.SourceContext)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const SourceContext* source =
::google::protobuf::internal::DynamicCastToGenerated<const SourceContext>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.SourceContext)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.SourceContext)
MergeFrom(*source);
}
}
void SourceContext::MergeFrom(const SourceContext& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.SourceContext)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from.file_name().size() > 0) {
file_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.file_name_);
@@ -297,12 +301,14 @@ void SourceContext::MergeFrom(const SourceContext& from) {
}
void SourceContext::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.SourceContext)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void SourceContext::CopyFrom(const SourceContext& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.SourceContext)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -364,6 +370,7 @@ void SourceContext::clear_file_name() {
return file_name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* SourceContext::release_file_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.SourceContext.file_name)
return file_name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
diff --git a/src/google/protobuf/source_context.pb.h b/src/google/protobuf/source_context.pb.h
index 02e11460..341a4534 100644
--- a/src/google/protobuf/source_context.pb.h
+++ b/src/google/protobuf/source_context.pb.h
@@ -41,7 +41,7 @@ class SourceContext;
// ===================================================================
-class LIBPROTOBUF_EXPORT SourceContext : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT SourceContext : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.SourceContext) */ {
public:
SourceContext();
virtual ~SourceContext();
@@ -75,7 +75,11 @@ class LIBPROTOBUF_EXPORT SourceContext : public ::google::protobuf::Message {
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
@@ -160,6 +164,7 @@ inline ::std::string* SourceContext::mutable_file_name() {
return file_name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* SourceContext::release_file_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.SourceContext.file_name)
return file_name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
diff --git a/src/google/protobuf/source_context.proto b/src/google/protobuf/source_context.proto
index e9a27d65..a2c08e2b 100644
--- a/src/google/protobuf/source_context.proto
+++ b/src/google/protobuf/source_context.proto
@@ -27,21 +27,22 @@
// 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.
+
syntax = "proto3";
package google.protobuf;
-option java_multiple_files = true;
-option java_outer_classname = "SourceContextProto";
+option csharp_namespace = "Google.Protobuf.WellKnownTypes";
option java_package = "com.google.protobuf";
+option java_outer_classname = "SourceContextProto";
+option java_multiple_files = true;
option java_generate_equals_and_hash = true;
-option csharp_namespace = "Google.Protobuf.WellKnownTypes";
option objc_class_prefix = "GPB";
// `SourceContext` represents information about the source of a
// protobuf element, like the file in which it is defined.
message SourceContext {
// The path-qualified name of the .proto file that contained the associated
- // protobuf element. For example: `"google/protobuf/source.proto"`.
+ // protobuf element. For example: `"google/protobuf/source_context.proto"`.
string file_name = 1;
}
diff --git a/src/google/protobuf/struct.pb.cc b/src/google/protobuf/struct.pb.cc
index 273645d9..a551384c 100644
--- a/src/google/protobuf/struct.pb.cc
+++ b/src/google/protobuf/struct.pb.cc
@@ -7,6 +7,7 @@
#include <algorithm>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/port.h>
#include <google/protobuf/stubs/once.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/wire_format_lite_inl.h>
@@ -44,6 +45,7 @@ const ::google::protobuf::EnumDescriptor* NullValue_descriptor_ = NULL;
} // namespace
+void protobuf_AssignDesc_google_2fprotobuf_2fstruct_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AssignDesc_google_2fprotobuf_2fstruct_2eproto() {
protobuf_AddDesc_google_2fprotobuf_2fstruct_2eproto();
const ::google::protobuf::FileDescriptor* file =
@@ -115,6 +117,7 @@ inline void protobuf_AssignDescriptorsOnce() {
&protobuf_AssignDesc_google_2fprotobuf_2fstruct_2eproto);
}
+void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
void protobuf_RegisterTypes(const ::std::string&) {
protobuf_AssignDescriptorsOnce();
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
@@ -146,6 +149,7 @@ void protobuf_ShutdownFile_google_2fprotobuf_2fstruct_2eproto() {
delete ListValue_reflection_;
}
+void protobuf_AddDesc_google_2fprotobuf_2fstruct_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AddDesc_google_2fprotobuf_2fstruct_2eproto() {
static bool already_here = false;
if (already_here) return;
@@ -165,9 +169,11 @@ void protobuf_AddDesc_google_2fprotobuf_2fstruct_2eproto() {
"\000\0220\n\nlist_value\030\006 \001(\0132\032.google.protobuf."
"ListValueH\000B\006\n\004kind\"3\n\tListValue\022&\n\006valu"
"es\030\001 \003(\0132\026.google.protobuf.Value*\033\n\tNull"
- "Value\022\016\n\nNULL_VALUE\020\000BN\n\023com.google.prot"
- "obufB\013StructProtoP\001\240\001\001\242\002\003GPB\252\002\036Google.Pr"
- "otobuf.WellKnownTypesb\006proto3", 589);
+ "Value\022\016\n\nNULL_VALUE\020\000B\201\001\n\023com.google.pro"
+ "tobufB\013StructProtoP\001Z1github.com/golang/"
+ "protobuf/ptypes/struct;structpb\240\001\001\242\002\003GPB"
+ "\252\002\036Google.Protobuf.WellKnownTypesb\006proto"
+ "3", 641);
::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
"google/protobuf/struct.proto", &protobuf_RegisterTypes);
Struct::default_instance_ = new Struct();
@@ -200,16 +206,6 @@ bool NullValue_IsValid(int value) {
}
-namespace {
-
-static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD;
-static void MergeFromFail(int line) {
- GOOGLE_CHECK(false) << __FILE__ << ":" << line;
-}
-
-} // namespace
-
-
// ===================================================================
#if !defined(_MSC_VER) || _MSC_VER >= 1900
@@ -236,6 +232,7 @@ Struct::Struct(const Struct& from)
void Struct::SharedCtor() {
_is_default_instance_ = false;
+ ::google::protobuf::internal::GetEmptyString();
_cached_size_ = 0;
fields_.SetAssignDescriptorCallback(
protobuf_AssignDescriptorsOnce);
@@ -279,12 +276,13 @@ Struct* Struct::New(::google::protobuf::Arena* arena) const {
}
void Struct::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.Struct)
fields_.Clear();
}
bool Struct::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.Struct)
for (;;) {
@@ -297,12 +295,16 @@ bool Struct::MergePartialFromCodedStream(
if (tag == 10) {
DO_(input->IncrementRecursionDepth());
parse_loop_fields:
- ::google::protobuf::scoped_ptr<Struct_FieldsEntry> entry(fields_.NewEntry());
+ Struct_FieldsEntry::Parser< ::google::protobuf::internal::MapField<
+ ::std::string, ::google::protobuf::Value,
+ ::google::protobuf::internal::WireFormatLite::TYPE_STRING,
+ ::google::protobuf::internal::WireFormatLite::TYPE_MESSAGE,
+ 0 >,
+ ::google::protobuf::Map< ::std::string, ::google::protobuf::Value > > parser(&fields_);
DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
- input, entry.get()));
- (*mutable_fields())[entry->key()].Swap(entry->mutable_value());
+ input, &parser));
DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
- entry->key().data(), entry->key().length(),
+ parser.key().data(), parser.key().length(),
::google::protobuf::internal::WireFormatLite::PARSE,
"google.protobuf.Struct.FieldsEntry.key"));
} else {
@@ -339,41 +341,110 @@ void Struct::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
// @@protoc_insertion_point(serialize_start:google.protobuf.Struct)
// map<string, .google.protobuf.Value> fields = 1;
- {
- ::google::protobuf::scoped_ptr<Struct_FieldsEntry> entry;
- for (::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::const_iterator
- it = this->fields().begin();
- it != this->fields().end(); ++it) {
- entry.reset(fields_.NewEntryWrapper(it->first, it->second));
- ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
- 1, *entry, output);
- ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
- it->first.data(), it->first.length(),
- ::google::protobuf::internal::WireFormatLite::SERIALIZE,
- "google.protobuf.Struct.FieldsEntry.key");
+ if (!this->fields().empty()) {
+ typedef ::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::const_pointer
+ ConstPtr;
+ typedef ConstPtr SortItem;
+ typedef ::google::protobuf::internal::CompareByDerefFirst<SortItem> Less;
+ struct Utf8Check {
+ static void Check(ConstPtr p) {
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+ p->first.data(), p->first.length(),
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+ "google.protobuf.Struct.FieldsEntry.key");
+ }
+ };
+
+ if (output->IsSerializationDeterminstic() &&
+ this->fields().size() > 1) {
+ ::google::protobuf::scoped_array<SortItem> items(
+ new SortItem[this->fields().size()]);
+ typedef ::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::size_type size_type;
+ size_type n = 0;
+ for (::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::const_iterator
+ it = this->fields().begin();
+ it != this->fields().end(); ++it, ++n) {
+ items[n] = SortItem(&*it);
+ }
+ ::std::sort(&items[0], &items[n], Less());
+ ::google::protobuf::scoped_ptr<Struct_FieldsEntry> entry;
+ for (size_type i = 0; i < n; i++) {
+ entry.reset(fields_.NewEntryWrapper(
+ items[i]->first, items[i]->second));
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+ 1, *entry, output);
+ Utf8Check::Check(items[i]);
+ }
+ } else {
+ ::google::protobuf::scoped_ptr<Struct_FieldsEntry> entry;
+ for (::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::const_iterator
+ it = this->fields().begin();
+ it != this->fields().end(); ++it) {
+ entry.reset(fields_.NewEntryWrapper(
+ it->first, it->second));
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+ 1, *entry, output);
+ Utf8Check::Check(&*it);
+ }
}
}
// @@protoc_insertion_point(serialize_end:google.protobuf.Struct)
}
-::google::protobuf::uint8* Struct::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* Struct::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Struct)
// map<string, .google.protobuf.Value> fields = 1;
- {
- ::google::protobuf::scoped_ptr<Struct_FieldsEntry> entry;
- for (::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::const_iterator
- it = this->fields().begin();
- it != this->fields().end(); ++it) {
- entry.reset(fields_.NewEntryWrapper(it->first, it->second));
- target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 1, *entry, target);
- ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
- it->first.data(), it->first.length(),
- ::google::protobuf::internal::WireFormatLite::SERIALIZE,
- "google.protobuf.Struct.FieldsEntry.key");
+ if (!this->fields().empty()) {
+ typedef ::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::const_pointer
+ ConstPtr;
+ typedef ConstPtr SortItem;
+ typedef ::google::protobuf::internal::CompareByDerefFirst<SortItem> Less;
+ struct Utf8Check {
+ static void Check(ConstPtr p) {
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+ p->first.data(), p->first.length(),
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+ "google.protobuf.Struct.FieldsEntry.key");
+ }
+ };
+
+ if (deterministic &&
+ this->fields().size() > 1) {
+ ::google::protobuf::scoped_array<SortItem> items(
+ new SortItem[this->fields().size()]);
+ typedef ::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::size_type size_type;
+ size_type n = 0;
+ for (::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::const_iterator
+ it = this->fields().begin();
+ it != this->fields().end(); ++it, ++n) {
+ items[n] = SortItem(&*it);
+ }
+ ::std::sort(&items[0], &items[n], Less());
+ ::google::protobuf::scoped_ptr<Struct_FieldsEntry> entry;
+ for (size_type i = 0; i < n; i++) {
+ entry.reset(fields_.NewEntryWrapper(
+ items[i]->first, items[i]->second));
+ target = ::google::protobuf::internal::WireFormatLite::
+ InternalWriteMessageNoVirtualToArray(
+ 1, *entry, deterministic, target);
+;
+ Utf8Check::Check(items[i]);
+ }
+ } else {
+ ::google::protobuf::scoped_ptr<Struct_FieldsEntry> entry;
+ for (::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::const_iterator
+ it = this->fields().begin();
+ it != this->fields().end(); ++it) {
+ entry.reset(fields_.NewEntryWrapper(
+ it->first, it->second));
+ target = ::google::protobuf::internal::WireFormatLite::
+ InternalWriteMessageNoVirtualToArray(
+ 1, *entry, deterministic, target);
+;
+ Utf8Check::Check(&*it);
+ }
}
}
@@ -382,6 +453,7 @@ void Struct::SerializeWithCachedSizes(
}
int Struct::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Struct)
int total_size = 0;
// map<string, .google.protobuf.Value> fields = 1;
@@ -404,29 +476,39 @@ int Struct::ByteSize() const {
}
void Struct::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Struct)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const Struct* source =
::google::protobuf::internal::DynamicCastToGenerated<const Struct>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.Struct)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.Struct)
MergeFrom(*source);
}
}
void Struct::MergeFrom(const Struct& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Struct)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
fields_.MergeFrom(from.fields_);
}
void Struct::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.Struct)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void Struct::CopyFrom(const Struct& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Struct)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -559,6 +641,7 @@ Value* Value::New(::google::protobuf::Arena* arena) const {
}
void Value::clear_kind() {
+// @@protoc_insertion_point(one_of_clear_start:google.protobuf.Value)
switch(kind_case()) {
case kNullValue: {
// No need to clear
@@ -593,12 +676,13 @@ void Value::clear_kind() {
void Value::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.Value)
clear_kind();
}
bool Value::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.Value)
for (;;) {
@@ -761,8 +845,8 @@ void Value::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.Value)
}
-::google::protobuf::uint8* Value::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* Value::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Value)
// optional .google.protobuf.NullValue null_value = 1;
if (has_null_value()) {
@@ -794,15 +878,15 @@ void Value::SerializeWithCachedSizes(
// optional .google.protobuf.Struct struct_value = 5;
if (has_struct_value()) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 5, *kind_.struct_value_, target);
+ InternalWriteMessageNoVirtualToArray(
+ 5, *kind_.struct_value_, false, target);
}
// optional .google.protobuf.ListValue list_value = 6;
if (has_list_value()) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 6, *kind_.list_value_, target);
+ InternalWriteMessageNoVirtualToArray(
+ 6, *kind_.list_value_, false, target);
}
// @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Value)
@@ -810,6 +894,7 @@ void Value::SerializeWithCachedSizes(
}
int Value::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Value)
int total_size = 0;
switch (kind_case()) {
@@ -861,19 +946,27 @@ int Value::ByteSize() const {
}
void Value::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Value)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const Value* source =
::google::protobuf::internal::DynamicCastToGenerated<const Value>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.Value)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.Value)
MergeFrom(*source);
}
}
void Value::MergeFrom(const Value& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Value)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
switch (from.kind_case()) {
case kNullValue: {
set_null_value(from.null_value());
@@ -906,12 +999,14 @@ void Value::MergeFrom(const Value& from) {
}
void Value::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.Value)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void Value::CopyFrom(const Value& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Value)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -1062,6 +1157,7 @@ void Value::clear_string_value() {
return kind_.string_value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* Value::release_string_value() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Value.string_value)
if (has_string_value()) {
clear_has_kind();
return kind_.string_value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
@@ -1140,6 +1236,7 @@ void Value::clear_struct_value() {
return kind_.struct_value_;
}
::google::protobuf::Struct* Value::release_struct_value() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Value.struct_value)
if (has_struct_value()) {
clear_has_kind();
::google::protobuf::Struct* temp = kind_.struct_value_;
@@ -1187,6 +1284,7 @@ void Value::clear_list_value() {
return kind_.list_value_;
}
::google::protobuf::ListValue* Value::release_list_value() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Value.list_value)
if (has_list_value()) {
clear_has_kind();
::google::protobuf::ListValue* temp = kind_.list_value_;
@@ -1281,12 +1379,13 @@ ListValue* ListValue::New(::google::protobuf::Arena* arena) const {
}
void ListValue::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.ListValue)
values_.Clear();
}
bool ListValue::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.ListValue)
for (;;) {
@@ -1343,14 +1442,14 @@ void ListValue::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.ListValue)
}
-::google::protobuf::uint8* ListValue::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* ListValue::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.ListValue)
// repeated .google.protobuf.Value values = 1;
for (unsigned int i = 0, n = this->values_size(); i < n; i++) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 1, this->values(i), target);
+ InternalWriteMessageNoVirtualToArray(
+ 1, this->values(i), false, target);
}
// @@protoc_insertion_point(serialize_to_array_end:google.protobuf.ListValue)
@@ -1358,6 +1457,7 @@ void ListValue::SerializeWithCachedSizes(
}
int ListValue::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.ListValue)
int total_size = 0;
// repeated .google.protobuf.Value values = 1;
@@ -1375,29 +1475,39 @@ int ListValue::ByteSize() const {
}
void ListValue::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.ListValue)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const ListValue* source =
::google::protobuf::internal::DynamicCastToGenerated<const ListValue>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.ListValue)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.ListValue)
MergeFrom(*source);
}
}
void ListValue::MergeFrom(const ListValue& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.ListValue)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
values_.MergeFrom(from.values_);
}
void ListValue::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.ListValue)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void ListValue::CopyFrom(const ListValue& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.ListValue)
if (&from == this) return;
Clear();
MergeFrom(from);
diff --git a/src/google/protobuf/struct.pb.h b/src/google/protobuf/struct.pb.h
index 0527c812..b085b849 100644
--- a/src/google/protobuf/struct.pb.h
+++ b/src/google/protobuf/struct.pb.h
@@ -66,7 +66,7 @@ inline bool NullValue_Parse(
}
// ===================================================================
-class LIBPROTOBUF_EXPORT Struct : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT Struct : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Struct) */ {
public:
Struct();
virtual ~Struct();
@@ -100,7 +100,11 @@ class LIBPROTOBUF_EXPORT Struct : public ::google::protobuf::Message {
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
@@ -158,7 +162,7 @@ class LIBPROTOBUF_EXPORT Struct : public ::google::protobuf::Message {
};
// -------------------------------------------------------------------
-class LIBPROTOBUF_EXPORT Value : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT Value : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Value) */ {
public:
Value();
virtual ~Value();
@@ -202,7 +206,11 @@ class LIBPROTOBUF_EXPORT Value : public ::google::protobuf::Message {
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
@@ -320,7 +328,7 @@ class LIBPROTOBUF_EXPORT Value : public ::google::protobuf::Message {
};
// -------------------------------------------------------------------
-class LIBPROTOBUF_EXPORT ListValue : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT ListValue : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.ListValue) */ {
public:
ListValue();
virtual ~ListValue();
@@ -354,7 +362,11 @@ class LIBPROTOBUF_EXPORT ListValue : public ::google::protobuf::Message {
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
@@ -550,6 +562,7 @@ inline ::std::string* Value::mutable_string_value() {
return kind_.string_value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* Value::release_string_value() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Value.string_value)
if (has_string_value()) {
clear_has_kind();
return kind_.string_value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
@@ -628,6 +641,7 @@ inline ::google::protobuf::Struct* Value::mutable_struct_value() {
return kind_.struct_value_;
}
inline ::google::protobuf::Struct* Value::release_struct_value() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Value.struct_value)
if (has_struct_value()) {
clear_has_kind();
::google::protobuf::Struct* temp = kind_.struct_value_;
@@ -675,6 +689,7 @@ inline ::google::protobuf::ListValue* Value::mutable_list_value() {
return kind_.list_value_;
}
inline ::google::protobuf::ListValue* Value::release_list_value() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Value.list_value)
if (has_list_value()) {
clear_has_kind();
::google::protobuf::ListValue* temp = kind_.list_value_;
diff --git a/src/google/protobuf/struct.proto b/src/google/protobuf/struct.proto
index b3e9e699..beeba811 100644
--- a/src/google/protobuf/struct.proto
+++ b/src/google/protobuf/struct.proto
@@ -27,15 +27,17 @@
// 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.
+
syntax = "proto3";
package google.protobuf;
-option java_generate_equals_and_hash = true;
-option java_multiple_files = true;
-option java_outer_classname = "StructProto";
-option java_package = "com.google.protobuf";
option csharp_namespace = "Google.Protobuf.WellKnownTypes";
+option go_package = "github.com/golang/protobuf/ptypes/struct;structpb";
+option java_package = "com.google.protobuf";
+option java_outer_classname = "StructProto";
+option java_multiple_files = true;
+option java_generate_equals_and_hash = true;
option objc_class_prefix = "GPB";
@@ -48,7 +50,7 @@ option objc_class_prefix = "GPB";
//
// The JSON representation for `Struct` is JSON object.
message Struct {
- // Map of dynamically typed values.
+ // Unordered map of dynamically typed values.
map<string, Value> fields = 1;
}
diff --git a/src/google/protobuf/stubs/atomicops.h b/src/google/protobuf/stubs/atomicops.h
index 31e2b782..9b3d1e6b 100644
--- a/src/google/protobuf/stubs/atomicops.h
+++ b/src/google/protobuf/stubs/atomicops.h
@@ -76,7 +76,7 @@ typedef int32 Atomic32;
#ifdef GOOGLE_PROTOBUF_ARCH_64_BIT
// We need to be able to go between Atomic64 and AtomicWord implicitly. This
// means Atomic64 and AtomicWord should be the same type on 64-bit.
-#if defined(__ILP32__) || defined(GOOGLE_PROTOBUF_OS_NACL) || defined(GOOGLE_PROTOBUF_ARCH_SPARC)
+#if defined(__ILP32__) || defined(GOOGLE_PROTOBUF_OS_NACL)
// NaCl's intptr_t is not actually 64-bits on 64-bit!
// http://code.google.com/p/nativeclient/issues/detail?id=1162
// sparcv9's pointer type is 32bits
@@ -214,6 +214,8 @@ Atomic64 Release_Load(volatile const Atomic64* ptr);
#include <google/protobuf/stubs/atomicops_internals_power.h>
#elif defined(__native_client__)
#include <google/protobuf/stubs/atomicops_internals_pnacl.h>
+#elif defined(GOOGLE_PROTOBUF_ARCH_PPC)
+#include <google/protobuf/stubs/atomicops_internals_ppc_gcc.h>
#elif (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4))
#include <google/protobuf/stubs/atomicops_internals_generic_gcc.h>
#elif defined(__clang__)
diff --git a/src/google/protobuf/stubs/atomicops_internals_ppc_gcc.h b/src/google/protobuf/stubs/atomicops_internals_ppc_gcc.h
new file mode 100644
index 00000000..8231a578
--- /dev/null
+++ b/src/google/protobuf/stubs/atomicops_internals_ppc_gcc.h
@@ -0,0 +1,155 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2015 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.
+
+// Author: ogabbay@advaoptical.com (Oded Gabbay)
+// Cleaned up by: bsilver16384@gmail.com (Brian Silverman)
+//
+// This file is an internal atomic implementation, use atomicops.h instead.
+
+#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_PPC_GCC_H_
+#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_PPC_GCC_H_
+
+#define ATOMICOPS_COMPILER_BARRIER() __asm__ __volatile__("" : : : "memory")
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32 *ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ Atomic32 prev;
+
+ __asm__ __volatile__(
+ "0: \n\t"
+ "lwarx %[prev],0,%[ptr] \n\t"
+ "cmpw 0,%[prev],%[old_value] \n\t"
+ "bne- 1f \n\t"
+ "stwcx. %[new_value],0,%[ptr] \n\t"
+ "bne- 0b \n\t"
+ "1: \n\t"
+ : [prev] "=&r"(prev), "+m"(*ptr)
+ : [ptr] "r"(ptr), [old_value] "r"(old_value), [new_value] "r"(new_value)
+ : "cc", "memory");
+
+ return prev;
+}
+
+inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32 *ptr,
+ Atomic32 new_value) {
+ Atomic32 old;
+
+ __asm__ __volatile__(
+ "0: \n\t"
+ "lwarx %[old],0,%[ptr] \n\t"
+ "stwcx. %[new_value],0,%[ptr] \n\t"
+ "bne- 0b \n\t"
+ : [old] "=&r"(old), "+m"(*ptr)
+ : [ptr] "r"(ptr), [new_value] "r"(new_value)
+ : "cc", "memory");
+
+ return old;
+}
+
+inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32 *ptr,
+ Atomic32 increment) {
+ Atomic32 temp;
+
+ __asm__ __volatile__(
+ "0: \n\t"
+ "lwarx %[temp],0,%[ptr] \n\t"
+ "add %[temp],%[increment],%[temp] \n\t"
+ "stwcx. %[temp],0,%[ptr] \n\t"
+ "bne- 0b \n\t"
+ : [temp] "=&r"(temp)
+ : [increment] "r"(increment), [ptr] "r"(ptr)
+ : "cc", "memory");
+
+ return temp;
+}
+
+inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32 *ptr,
+ Atomic32 increment) {
+ MemoryBarrier();
+ Atomic32 res = NoBarrier_AtomicIncrement(ptr, increment);
+ MemoryBarrier();
+ return res;
+}
+
+inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32 *ptr,
+ Atomic32 old_value, Atomic32 new_value) {
+ Atomic32 res = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+ MemoryBarrier();
+ return res;
+}
+
+inline Atomic32 Release_CompareAndSwap(volatile Atomic32 *ptr,
+ Atomic32 old_value, Atomic32 new_value) {
+ MemoryBarrier();
+ Atomic32 res = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+ return res;
+}
+
+inline void NoBarrier_Store(volatile Atomic32 *ptr, Atomic32 value) {
+ *ptr = value;
+}
+
+inline void MemoryBarrier() { __asm__ __volatile__("sync" : : : "memory"); }
+
+inline void Acquire_Store(volatile Atomic32 *ptr, Atomic32 value) {
+ *ptr = value;
+ MemoryBarrier();
+}
+
+inline void Release_Store(volatile Atomic32 *ptr, Atomic32 value) {
+ MemoryBarrier();
+ *ptr = value;
+}
+
+inline Atomic32 NoBarrier_Load(volatile const Atomic32 *ptr) { return *ptr; }
+
+inline Atomic32 Acquire_Load(volatile const Atomic32 *ptr) {
+ Atomic32 value = *ptr;
+ MemoryBarrier();
+ return value;
+}
+
+inline Atomic32 Release_Load(volatile const Atomic32 *ptr) {
+ MemoryBarrier();
+ return *ptr;
+}
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#undef ATOMICOPS_COMPILER_BARRIER
+
+#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_PPC_GCC_H_
diff --git a/src/google/protobuf/stubs/bytestream.h b/src/google/protobuf/stubs/bytestream.h
index de8e0204..07604e17 100644
--- a/src/google/protobuf/stubs/bytestream.h
+++ b/src/google/protobuf/stubs/bytestream.h
@@ -208,7 +208,7 @@ class LIBPROTOBUF_EXPORT CheckedArrayByteSink : public ByteSink {
};
// Implementation of ByteSink that allocates an internal buffer (a char array)
-// and expands it as needed to accomodate appended data (similar to a string),
+// and expands it as needed to accommodate appended data (similar to a string),
// and allows the caller to take ownership of the internal buffer via the
// GetBuffer() method. The buffer returned from GetBuffer() must be deleted by
// the caller with delete[]. GetBuffer() also sets the internal buffer to be
diff --git a/src/google/protobuf/stubs/callback.h b/src/google/protobuf/stubs/callback.h
index 6da530d3..87271c5e 100644
--- a/src/google/protobuf/stubs/callback.h
+++ b/src/google/protobuf/stubs/callback.h
@@ -78,6 +78,18 @@ class LIBPROTOBUF_EXPORT Closure {
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Closure);
};
+template<typename R>
+class ResultCallback {
+ public:
+ ResultCallback() {}
+ virtual ~ResultCallback() {}
+
+ virtual R Run() = 0;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ResultCallback);
+};
+
template<typename R, typename A1>
class LIBPROTOBUF_EXPORT ResultCallback1 {
public:
@@ -240,6 +252,50 @@ class MethodClosure2 : public Closure {
Arg2 arg2_;
};
+template<typename R>
+class FunctionResultCallback_0_0 : public ResultCallback<R> {
+ public:
+ typedef R (*FunctionType)();
+
+ FunctionResultCallback_0_0(FunctionType function, bool self_deleting)
+ : function_(function), self_deleting_(self_deleting) {}
+ ~FunctionResultCallback_0_0() {}
+
+ R Run() {
+ bool needs_delete = self_deleting_; // read in case callback deletes
+ R result = function_();
+ if (needs_delete) delete this;
+ return result;
+ }
+
+ private:
+ FunctionType function_;
+ bool self_deleting_;
+};
+
+template<typename R, typename P1>
+class FunctionResultCallback_1_0 : public ResultCallback<R> {
+ public:
+ typedef R (*FunctionType)(P1);
+
+ FunctionResultCallback_1_0(FunctionType function, bool self_deleting,
+ P1 p1)
+ : function_(function), self_deleting_(self_deleting), p1_(p1) {}
+ ~FunctionResultCallback_1_0() {}
+
+ R Run() {
+ bool needs_delete = self_deleting_; // read in case callback deletes
+ R result = function_(p1_);
+ if (needs_delete) delete this;
+ return result;
+ }
+
+ private:
+ FunctionType function_;
+ bool self_deleting_;
+ P1 p1_;
+};
+
template<typename R, typename Arg1>
class FunctionResultCallback_0_1 : public ResultCallback1<R, Arg1> {
public:
@@ -408,6 +464,33 @@ inline Closure* NewPermanentCallback(
object, method, false, arg1, arg2);
}
+// See ResultCallback
+template<typename R>
+inline ResultCallback<R>* NewCallback(R (*function)()) {
+ return new internal::FunctionResultCallback_0_0<R>(function, true);
+}
+
+// See ResultCallback
+template<typename R>
+inline ResultCallback<R>* NewPermanentCallback(R (*function)()) {
+ return new internal::FunctionResultCallback_0_0<R>(function, false);
+}
+
+// See ResultCallback
+template<typename R, typename P1>
+inline ResultCallback<R>* NewCallback(R (*function)(P1), P1 p1) {
+ return new internal::FunctionResultCallback_1_0<R, P1>(
+ function, true, p1);
+}
+
+// See ResultCallback
+template<typename R, typename P1>
+inline ResultCallback<R>* NewPermanentCallback(
+ R (*function)(P1), P1 p1) {
+ return new internal::FunctionResultCallback_1_0<R, P1>(
+ function, false, p1);
+}
+
// See ResultCallback1
template<typename R, typename A1>
inline ResultCallback1<R, A1>* NewCallback(R (*function)(A1)) {
diff --git a/src/google/protobuf/stubs/hash.h b/src/google/protobuf/stubs/hash.h
index 58334322..4eac7d5d 100755..100644
--- a/src/google/protobuf/stubs/hash.h
+++ b/src/google/protobuf/stubs/hash.h
@@ -108,8 +108,13 @@
# define GOOGLE_PROTOBUF_HAS_CXX11_HASH
# define GOOGLE_PROTOBUF_HASH_COMPARE std::hash_compare
# elif _MSC_VER >= 1500 // Since Visual Studio 2008
-# undef GOOGLE_PROTOBUF_HAVE_HASH_MAP
-# undef GOOGLE_PROTOBUF_HAVE_HASH_SET
+# define GOOGLE_PROTOBUF_HASH_NAMESPACE stdext
+# include <hash_map>
+# define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map
+# include <hash_set>
+# define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set
+# define GOOGLE_PROTOBUF_HASH_COMPARE stdext::hash_compare
+# define GOOGLE_PROTOBUF_CONTAINERS_NEED_HASH_COMPARE
# elif _MSC_VER >= 1310
# define GOOGLE_PROTOBUF_HASH_NAMESPACE stdext
# include <hash_map>
@@ -214,6 +219,8 @@ class hash_map : public std::map<Key, Data, HashFcn, Alloc> {
hash_map(int a = 0, const HashFcn& b = HashFcn(),
const EqualKey& c = EqualKey(),
const Alloc& d = Alloc()) : BaseClass(b, d) {}
+
+ HashFcn hash_function() const { return HashFcn(); }
};
template <typename Key,
@@ -222,6 +229,8 @@ template <typename Key,
class hash_set : public std::set<Key, HashFcn> {
public:
hash_set(int = 0) {}
+
+ HashFcn hash_function() const { return HashFcn(); }
};
#elif defined(_MSC_VER) && !defined(_STLPORT_VERSION)
@@ -243,6 +252,52 @@ template <>
struct hash<const char*>
: public GOOGLE_PROTOBUF_HASH_COMPARE<const char*, CstringLess> {};
+#ifdef GOOGLE_PROTOBUF_CONTAINERS_NEED_HASH_COMPARE
+
+template <typename Key, typename HashFcn, typename EqualKey>
+struct InternalHashCompare : public GOOGLE_PROTOBUF_HASH_COMPARE<Key> {
+ InternalHashCompare() {}
+ InternalHashCompare(HashFcn hashfcn, EqualKey equalkey)
+ : hashfcn_(hashfcn), equalkey_(equalkey) {}
+ size_t operator()(const Key& key) const { return hashfcn_(key); }
+ bool operator()(const Key& key1, const Key& key2) const {
+ return !equalkey_(key1, key2);
+ }
+ HashFcn hashfcn_;
+ EqualKey equalkey_;
+};
+
+template <typename Key, typename Data,
+ typename HashFcn = hash<Key>,
+ typename EqualKey = std::equal_to<Key>,
+ typename Alloc = std::allocator< std::pair<const Key, Data> > >
+class hash_map
+ : public GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_MAP_CLASS<
+ Key, Data, InternalHashCompare<Key, HashFcn, EqualKey>, Alloc> {
+ typedef GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_MAP_CLASS<
+ Key, Data, InternalHashCompare<Key, HashFcn, EqualKey>, Alloc> BaseClass;
+
+ public:
+ hash_map(int a = 0, const HashFcn& b = HashFcn(),
+ const EqualKey& c = EqualKey(), const Alloc& d = Alloc())
+ : BaseClass(InternalHashCompare<Key, HashFcn, EqualKey>(b, c), d) {}
+
+ HashFcn hash_function() const { return HashFcn(); }
+};
+
+template <typename Key, typename HashFcn = hash<Key>,
+ typename EqualKey = std::equal_to<Key> >
+class hash_set
+ : public GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_SET_CLASS<
+ Key, InternalHashCompare<Key, HashFcn, EqualKey> > {
+ public:
+ hash_set(int = 0) {}
+
+ HashFcn hash_function() const { return HashFcn(); }
+};
+
+#else // GOOGLE_PROTOBUF_CONTAINERS_NEED_HASH_COMPARE
+
template <typename Key, typename Data,
typename HashFcn = hash<Key>,
typename EqualKey = std::equal_to<Key>,
@@ -257,6 +312,8 @@ class hash_map
hash_map(int a = 0, const HashFcn& b = HashFcn(),
const EqualKey& c = EqualKey(),
const Alloc& d = Alloc()) : BaseClass(a, b, c, d) {}
+
+ HashFcn hash_function() const { return HashFcn(); }
};
template <typename Key, typename HashFcn = hash<Key>,
@@ -266,9 +323,12 @@ class hash_set
Key, HashFcn, EqualKey> {
public:
hash_set(int = 0) {}
+
+ HashFcn hash_function() const { return HashFcn(); }
};
+#endif // GOOGLE_PROTOBUF_CONTAINERS_NEED_HASH_COMPARE
-#else
+#else // defined(_MSC_VER) && !defined(_STLPORT_VERSION)
template <typename Key>
struct hash : public GOOGLE_PROTOBUF_HASH_NAMESPACE::hash<Key> {
@@ -315,6 +375,8 @@ class hash_map
hash_map(int a = 0, const HashFcn& b = HashFcn(),
const EqualKey& c = EqualKey(),
const Alloc& d = Alloc()) : BaseClass(a, b, c, d) {}
+
+ HashFcn hash_function() const { return HashFcn(); }
};
template <typename Key, typename HashFcn = hash<Key>,
@@ -324,6 +386,8 @@ class hash_set
Key, HashFcn, EqualKey> {
public:
hash_set(int = 0) {}
+
+ HashFcn hash_function() const { return HashFcn(); }
};
#endif // !GOOGLE_PROTOBUF_MISSING_HASH
diff --git a/src/google/protobuf/stubs/int128.cc b/src/google/protobuf/stubs/int128.cc
index d80c64f2..a5090801 100644
--- a/src/google/protobuf/stubs/int128.cc
+++ b/src/google/protobuf/stubs/int128.cc
@@ -31,7 +31,7 @@
#include <google/protobuf/stubs/int128.h>
#include <iomanip>
-#include <iostream> // NOLINT(readability/streams)
+#include <ostream> // NOLINT(readability/streams)
#include <sstream>
namespace google {
@@ -145,15 +145,15 @@ std::ostream& operator<<(std::ostream& o, const uint128& b) {
std::streamsize div_base_log;
switch (flags & std::ios::basefield) {
case std::ios::hex:
- div = GOOGLE_ULONGLONG(0x1000000000000000); // 16^15
+ div = static_cast<uint64>(GOOGLE_ULONGLONG(0x1000000000000000)); // 16^15
div_base_log = 15;
break;
case std::ios::oct:
- div = GOOGLE_ULONGLONG(01000000000000000000000); // 8^21
+ div = static_cast<uint64>(GOOGLE_ULONGLONG(01000000000000000000000)); // 8^21
div_base_log = 21;
break;
default: // std::ios::dec
- div = GOOGLE_ULONGLONG(10000000000000000000); // 10^19
+ div = static_cast<uint64>(GOOGLE_ULONGLONG(10000000000000000000)); // 10^19
div_base_log = 19;
break;
}
diff --git a/src/google/protobuf/stubs/logging.h b/src/google/protobuf/stubs/logging.h
index 3108db8c..f69605d9 100644
--- a/src/google/protobuf/stubs/logging.h
+++ b/src/google/protobuf/stubs/logging.h
@@ -174,7 +174,7 @@ T* CheckNotNull(const char* /* file */, int /* line */,
#ifdef NDEBUG
-#define GOOGLE_DLOG GOOGLE_LOG_IF(INFO, false)
+#define GOOGLE_DLOG(LEVEL) GOOGLE_LOG_IF(LEVEL, false)
#define GOOGLE_DCHECK(EXPRESSION) while(false) GOOGLE_CHECK(EXPRESSION)
#define GOOGLE_DCHECK_OK(E) GOOGLE_DCHECK(::google::protobuf::internal::IsOk(E))
diff --git a/src/google/protobuf/stubs/map_util.h b/src/google/protobuf/stubs/map_util.h
index 4cccbbed..887f12a6 100644
--- a/src/google/protobuf/stubs/map_util.h
+++ b/src/google/protobuf/stubs/map_util.h
@@ -208,7 +208,7 @@ typename Collection::value_type::second_type::element_type&
FindLinkedPtrOrDie(const Collection& collection,
const typename Collection::value_type::first_type& key) {
typename Collection::const_iterator it = collection.find(key);
- CHECK(it != collection.end()) << "key not found: " << key;
+ GOOGLE_CHECK(it != collection.end()) << "key not found: " << key;
// Since linked_ptr::operator*() is a const member returning a non const,
// we do not need a version of this function taking a non const collection.
return *it->second;
@@ -337,14 +337,15 @@ bool InsertIfNotPresent(
template <class Collection>
void InsertOrDie(Collection* const collection,
const typename Collection::value_type& value) {
- CHECK(InsertIfNotPresent(collection, value)) << "duplicate value: " << value;
+ GOOGLE_CHECK(InsertIfNotPresent(collection, value))
+ << "duplicate value: " << value;
}
// Same as above except doesn't log the value on error.
template <class Collection>
void InsertOrDieNoPrint(Collection* const collection,
const typename Collection::value_type& value) {
- CHECK(InsertIfNotPresent(collection, value)) << "duplicate value.";
+ GOOGLE_CHECK(InsertIfNotPresent(collection, value)) << "duplicate value.";
}
// Inserts the key-value pair into the collection. Dies if key was already
diff --git a/src/google/protobuf/stubs/mathlimits.h b/src/google/protobuf/stubs/mathlimits.h
index d9846940..70e47bff 100644
--- a/src/google/protobuf/stubs/mathlimits.h
+++ b/src/google/protobuf/stubs/mathlimits.h
@@ -230,11 +230,11 @@ DECL_UNSIGNED_INT_LIMITS(unsigned long long int)
static bool IsNegInf(const Type x) { return _fpclass(x) == _FPCLASS_NINF; }
#else
#define DECL_FP_LIMIT_FUNCS \
- static bool IsFinite(const Type x) { return !isinf(x) && !isnan(x); } \
+ static bool IsFinite(const Type x) { return !isinf(x) && !isnan(x); } \
static bool IsNaN(const Type x) { return isnan(x); } \
static bool IsInf(const Type x) { return isinf(x); } \
- static bool IsPosInf(const Type x) { return isinf(x) && x > 0; } \
- static bool IsNegInf(const Type x) { return isinf(x) && x < 0; }
+ static bool IsPosInf(const Type x) { return isinf(x) && x > 0; } \
+ static bool IsNegInf(const Type x) { return isinf(x) && x < 0; }
#endif
// We can't put floating-point constant values in the header here because
diff --git a/src/google/protobuf/stubs/mathutil.h b/src/google/protobuf/stubs/mathutil.h
index 3a1ef8a8..27956a8e 100644
--- a/src/google/protobuf/stubs/mathutil.h
+++ b/src/google/protobuf/stubs/mathutil.h
@@ -83,7 +83,7 @@ class MathUtil {
if (value == T(0) || ::google::protobuf::internal::IsNan<T>(value)) {
return value;
}
- return value > T(0) ? value : -value;
+ return value > T(0) ? 1 : -1;
}
template<typename T>
diff --git a/src/google/protobuf/stubs/platform_macros.h b/src/google/protobuf/stubs/platform_macros.h
index 5cde8f4e..4ba4b348 100644
--- a/src/google/protobuf/stubs/platform_macros.h
+++ b/src/google/protobuf/stubs/platform_macros.h
@@ -65,7 +65,7 @@
#define GOOGLE_PROTOBUF_ARCH_32_BIT 1
#elif defined(sparc)
#define GOOGLE_PROTOBUF_ARCH_SPARC 1
-#ifdef SOLARIS_64BIT_ENABLED
+#if defined(__sparc_v9__) || defined(__sparcv9) || defined(__arch64__)
#define GOOGLE_PROTOBUF_ARCH_64_BIT 1
#else
#define GOOGLE_PROTOBUF_ARCH_32_BIT 1
@@ -73,6 +73,9 @@
#elif defined(_POWER) || defined(__powerpc64__) || defined(__PPC64__)
#define GOOGLE_PROTOBUF_ARCH_POWER 1
#define GOOGLE_PROTOBUF_ARCH_64_BIT 1
+#elif defined(__PPC__)
+#define GOOGLE_PROTOBUF_ARCH_PPC 1
+#define GOOGLE_PROTOBUF_ARCH_32_BIT 1
#elif defined(__GNUC__)
# if (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4))
// We fallback to the generic Clang/GCC >= 4.7 implementation in atomicops.h
diff --git a/src/google/protobuf/stubs/port.h b/src/google/protobuf/stubs/port.h
index b35a3afe..d7f93b4c 100644
--- a/src/google/protobuf/stubs/port.h
+++ b/src/google/protobuf/stubs/port.h
@@ -53,7 +53,7 @@
#if !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST)
#define PROTOBUF_LITTLE_ENDIAN 1
#endif
- #if defined(_MSC_VER) && _MSC_VER >= 1300
+ #if _MSC_VER >= 1300 && !defined(__INTEL_COMPILER)
// If MSVC has "/RTCc" set, it will complain about truncating casts at
// runtime. This file contains some intentional truncating casts.
#pragma runtime_checks("c", off)
@@ -109,15 +109,15 @@ typedef unsigned __int16 uint16;
typedef unsigned __int32 uint32;
typedef unsigned __int64 uint64;
#else
-typedef signed char int8;
-typedef short int16;
-typedef int int32;
-typedef long long int64;
-
-typedef unsigned char uint8;
-typedef unsigned short uint16;
-typedef unsigned int uint32;
-typedef unsigned long long uint64;
+typedef int8_t int8;
+typedef int16_t int16;
+typedef int32_t int32;
+typedef int64_t int64;
+
+typedef uint8_t uint8;
+typedef uint16_t uint16;
+typedef uint32_t uint32;
+typedef uint64_t uint64;
#endif
// long long macros to be used because gcc and vc++ use different suffixes,
@@ -131,8 +131,10 @@ typedef unsigned long long uint64;
#define GOOGLE_ULONGLONG(x) x##UI64
#define GOOGLE_LL_FORMAT "I64" // As in printf("%I64d", ...)
#else
+// By long long, we actually mean int64.
#define GOOGLE_LONGLONG(x) x##LL
#define GOOGLE_ULONGLONG(x) x##ULL
+// Used to format real long long integers.
#define GOOGLE_LL_FORMAT "ll" // As in "%lld". Note that "q" is poor form also.
#endif
@@ -174,6 +176,15 @@ static const uint64 kuint64max = GOOGLE_ULONGLONG(0xFFFFFFFFFFFFFFFF);
#endif
#endif
+#ifndef GOOGLE_ATTRIBUTE_NORETURN
+#ifdef __GNUC__
+// Tell the compiler that a given function never returns.
+#define GOOGLE_ATTRIBUTE_NORETURN __attribute__((noreturn))
+#else
+#define GOOGLE_ATTRIBUTE_NORETURN
+#endif
+#endif
+
#ifndef GOOGLE_ATTRIBUTE_DEPRECATED
#ifdef __GNUC__
// If the method/variable/type is used anywhere, produce a warning.
@@ -276,10 +287,8 @@ inline void GOOGLE_UNALIGNED_STORE64(void *p, uint64 v) {
#define GOOGLE_THREAD_LOCAL __thread
#endif
-// The following guarantees declaration of the byte swap functions, and
-// defines __BYTE_ORDER for MSVC
+// The following guarantees declaration of the byte swap functions.
#ifdef _MSC_VER
-#define __BYTE_ORDER __LITTLE_ENDIAN
#define bswap_16(x) _byteswap_ushort(x)
#define bswap_32(x) _byteswap_ulong(x)
#define bswap_64(x) _byteswap_uint64(x)
diff --git a/src/google/protobuf/stubs/statusor.h b/src/google/protobuf/stubs/statusor.h
index a9d2b374..29f869ad 100644
--- a/src/google/protobuf/stubs/statusor.h
+++ b/src/google/protobuf/stubs/statusor.h
@@ -224,14 +224,14 @@ inline StatusOr<T>& StatusOr<T>::operator=(const StatusOr<T>& other) {
template<typename T>
template<typename U>
inline StatusOr<T>::StatusOr(const StatusOr<U>& other)
- : status_(other.status_), value_(other.value_) {
+ : status_(other.status_), value_(other.status_.ok() ? other.value_ : T()) {
}
template<typename T>
template<typename U>
inline StatusOr<T>& StatusOr<T>::operator=(const StatusOr<U>& other) {
status_ = other.status_;
- value_ = other.value_;
+ if (status_.ok()) value_ = other.value_;
return *this;
}
diff --git a/src/google/protobuf/stubs/stringpiece.h b/src/google/protobuf/stubs/stringpiece.h
index ec3ffd5b..8910688b 100644
--- a/src/google/protobuf/stubs/stringpiece.h
+++ b/src/google/protobuf/stubs/stringpiece.h
@@ -222,14 +222,6 @@ class LIBPROTOBUF_EXPORT StringPiece {
: ptr_(str.data()), length_(0) {
length_ = CheckedSsizeTFromSizeT(str.size());
}
-#if defined(HAS_GLOBAL_STRING)
- template <class Allocator>
- StringPiece( // NOLINT(runtime/explicit)
- const basic_string<char, std::char_traits<char>, Allocator>& str)
- : ptr_(str.data()), length_(0) {
- length_ = CheckedSsizeTFromSizeT(str.size());
- }
-#endif
StringPiece(const char* offset, stringpiece_ssize_type len)
: ptr_(offset), length_(len) {
@@ -435,6 +427,44 @@ inline bool operator>=(StringPiece x, StringPiece y) {
// allow StringPiece to be logged
extern std::ostream& operator<<(std::ostream& o, StringPiece piece);
+namespace internal {
+// StringPiece is not a POD and can not be used in an union (pre C++11). We
+// need a POD version of it.
+struct StringPiecePod {
+ // Create from a StringPiece.
+ static StringPiecePod CreateFromStringPiece(StringPiece str) {
+ StringPiecePod pod;
+ pod.data_ = str.data();
+ pod.size_ = str.size();
+ return pod;
+ }
+
+ // Cast to StringPiece.
+ operator StringPiece() const { return StringPiece(data_, size_); }
+
+ bool operator==(const char* value) const {
+ return StringPiece(data_, size_) == StringPiece(value);
+ }
+
+ char operator[](stringpiece_ssize_type i) const {
+ assert(0 <= i);
+ assert(i < size_);
+ return data_[i];
+ }
+
+ const char* data() const { return data_; }
+
+ stringpiece_ssize_type size() const {
+ return size_;
+ }
+
+ std::string ToString() const { return std::string(data_, size_); }
+ private:
+ const char* data_;
+ stringpiece_ssize_type size_;
+};
+
+} // namespace internal
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/stubs/stringpiece_unittest.cc b/src/google/protobuf/stubs/stringpiece_unittest.cc
index 43737a57..a52d81f8 100644
--- a/src/google/protobuf/stubs/stringpiece_unittest.cc
+++ b/src/google/protobuf/stubs/stringpiece_unittest.cc
@@ -746,23 +746,6 @@ TEST(StringPiece, Comparisons2) {
EXPECT_TRUE(abc.ends_with("nopqrstuvwxyz"));
}
-TEST(StringPiece, HashFunction) {
- hash_set<StringPiece> set;
-
- set.insert(StringPiece("hello"));
- EXPECT_EQ(1, set.size());
-
- // Insert a StringPiece of the same value again and should NOT increment
- // size of the set.
- set.insert(StringPiece("hello"));
- EXPECT_EQ(1, set.size());
-
- // Insert a StringPiece with different value and check that size of the set
- // has been increment by one.
- set.insert(StringPiece("world"));
- EXPECT_EQ(2, set.size());
-}
-
TEST(ComparisonOpsTest, StringCompareNotAmbiguous) {
EXPECT_EQ("hello", string("hello"));
EXPECT_LT("hello", string("world"));
diff --git a/src/google/protobuf/stubs/stringprintf.cc b/src/google/protobuf/stubs/stringprintf.cc
index 3272d8e3..83fdfe45 100644
--- a/src/google/protobuf/stubs/stringprintf.cc
+++ b/src/google/protobuf/stubs/stringprintf.cc
@@ -37,7 +37,6 @@
#include <stdio.h> // MSVC requires this for _vsnprintf
#include <vector>
#include <google/protobuf/stubs/common.h>
-#include <google/protobuf/testing/googletest.h>
namespace google {
namespace protobuf {
diff --git a/src/google/protobuf/stubs/strutil.cc b/src/google/protobuf/stubs/strutil.cc
index 8442f2ce..7ba92e8f 100644
--- a/src/google/protobuf/stubs/strutil.cc
+++ b/src/google/protobuf/stubs/strutil.cc
@@ -524,27 +524,81 @@ int CEscapeInternal(const char* src, int src_len, char* dest,
return used;
}
-int CEscapeString(const char* src, int src_len, char* dest, int dest_len) {
- return CEscapeInternal(src, src_len, dest, dest_len, false, false);
+// Calculates the length of the C-style escaped version of 'src'.
+// Assumes that non-printable characters are escaped using octal sequences, and
+// that UTF-8 bytes are not handled specially.
+static inline size_t CEscapedLength(StringPiece src) {
+ static char c_escaped_len[256] = {
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 4, 4, 2, 4, 4, // \t, \n, \r
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 1, 1, 2, 1, 1, 1, 1, 2, 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'..'9'
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 'A'..'O'
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, // 'P'..'Z', '\'
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 'a'..'o'
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, // 'p'..'z', DEL
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ };
+
+ size_t escaped_len = 0;
+ for (int i = 0; i < src.size(); ++i) {
+ unsigned char c = static_cast<unsigned char>(src[i]);
+ escaped_len += c_escaped_len[c];
+ }
+ return escaped_len;
}
// ----------------------------------------------------------------------
-// CEscape()
-// CHexEscape()
-// Copies 'src' to result, escaping dangerous characters using
-// C-style escape sequences. This is very useful for preparing query
-// flags. 'src' and 'dest' should not overlap. The 'Hex' version
-// hexadecimal rather than octal sequences.
-//
-// Currently only \n, \r, \t, ", ', \ and !isprint() chars are escaped.
+// Escapes 'src' using C-style escape sequences, and appends the escaped string
+// to 'dest'. This version is faster than calling CEscapeInternal as it computes
+// the required space using a lookup table, and also does not do any special
+// handling for Hex or UTF-8 characters.
// ----------------------------------------------------------------------
+void CEscapeAndAppend(StringPiece src, string* dest) {
+ size_t escaped_len = CEscapedLength(src);
+ if (escaped_len == src.size()) {
+ dest->append(src.data(), src.size());
+ return;
+ }
+
+ size_t cur_dest_len = dest->size();
+ dest->resize(cur_dest_len + escaped_len);
+ char* append_ptr = &(*dest)[cur_dest_len];
+
+ for (int i = 0; i < src.size(); ++i) {
+ unsigned char c = static_cast<unsigned char>(src[i]);
+ switch (c) {
+ case '\n': *append_ptr++ = '\\'; *append_ptr++ = 'n'; break;
+ case '\r': *append_ptr++ = '\\'; *append_ptr++ = 'r'; break;
+ case '\t': *append_ptr++ = '\\'; *append_ptr++ = 't'; break;
+ case '\"': *append_ptr++ = '\\'; *append_ptr++ = '\"'; break;
+ case '\'': *append_ptr++ = '\\'; *append_ptr++ = '\''; break;
+ case '\\': *append_ptr++ = '\\'; *append_ptr++ = '\\'; break;
+ default:
+ if (!isprint(c)) {
+ *append_ptr++ = '\\';
+ *append_ptr++ = '0' + c / 64;
+ *append_ptr++ = '0' + (c % 64) / 8;
+ *append_ptr++ = '0' + c % 8;
+ } else {
+ *append_ptr++ = c;
+ }
+ break;
+ }
+ }
+}
+
string CEscape(const string& src) {
- const int dest_length = src.size() * 4 + 1; // Maximum possible expansion
- scoped_array<char> dest(new char[dest_length]);
- const int len = CEscapeInternal(src.data(), src.size(),
- dest.get(), dest_length, false, false);
- GOOGLE_DCHECK_GE(len, 0);
- return string(dest.get(), len);
+ string dest;
+ CEscapeAndAppend(src, &dest);
+ return dest;
}
namespace strings {
diff --git a/src/google/protobuf/stubs/strutil.h b/src/google/protobuf/stubs/strutil.h
index b22066b6..8bdd6110 100644
--- a/src/google/protobuf/stubs/strutil.h
+++ b/src/google/protobuf/stubs/strutil.h
@@ -314,26 +314,20 @@ LIBPROTOBUF_EXPORT int UnescapeCEscapeString(const string& src, string* dest,
LIBPROTOBUF_EXPORT string UnescapeCEscapeString(const string& src);
// ----------------------------------------------------------------------
-// CEscapeString()
-// Copies 'src' to 'dest', escaping dangerous characters using
-// C-style escape sequences. This is very useful for preparing query
-// flags. 'src' and 'dest' should not overlap.
-// Returns the number of bytes written to 'dest' (not including the \0)
-// or -1 if there was insufficient space.
+// CEscape()
+// Escapes 'src' using C-style escape sequences and returns the resulting
+// string.
//
-// Currently only \n, \r, \t, ", ', \ and !isprint() chars are escaped.
+// Escaped chars: \n, \r, \t, ", ', \, and !isprint().
// ----------------------------------------------------------------------
-LIBPROTOBUF_EXPORT int CEscapeString(const char* src, int src_len,
- char* dest, int dest_len);
+LIBPROTOBUF_EXPORT string CEscape(const string& src);
// ----------------------------------------------------------------------
-// CEscape()
-// More convenient form of CEscapeString: returns result as a "string".
-// This version is slower than CEscapeString() because it does more
-// allocation. However, it is much more convenient to use in
-// non-speed-critical code like logging messages etc.
+// CEscapeAndAppend()
+// Escapes 'src' using C-style escape sequences, and appends the escaped
+// string to 'dest'.
// ----------------------------------------------------------------------
-LIBPROTOBUF_EXPORT string CEscape(const string& src);
+LIBPROTOBUF_EXPORT void CEscapeAndAppend(StringPiece src, string* dest);
namespace strings {
// Like CEscape() but does not escape bytes with the upper bit set.
@@ -654,6 +648,9 @@ struct LIBPROTOBUF_EXPORT AlphaNum {
AlphaNum(StringPiece str)
: piece_data_(str.data()), piece_size_(str.size()) {}
+ AlphaNum(internal::StringPiecePod str)
+ : piece_data_(str.data()), piece_size_(str.size()) {}
+
size_t size() const { return piece_size_; }
const char *data() const { return piece_data_; }
@@ -853,6 +850,11 @@ LIBPROTOBUF_EXPORT void Base64Escape(const unsigned char* src, int szsrc,
LIBPROTOBUF_EXPORT void WebSafeBase64Escape(const unsigned char* src, int szsrc,
string* dest, bool do_padding);
+inline bool IsValidCodePoint(uint32 code_point) {
+ return code_point < 0xD800 ||
+ (code_point >= 0xE000 && code_point <= 0x10FFFF);
+}
+
static const int UTFmax = 4;
// ----------------------------------------------------------------------
// EncodeAsUTF8Char()
diff --git a/src/google/protobuf/stubs/time.h b/src/google/protobuf/stubs/time.h
index 20a6b56d..45607ca9 100644
--- a/src/google/protobuf/stubs/time.h
+++ b/src/google/protobuf/stubs/time.h
@@ -66,7 +66,7 @@ void LIBPROTOBUF_EXPORT GetCurrentTime(int64* seconds, int32* nanos);
string LIBPROTOBUF_EXPORT FormatTime(int64 seconds, int32 nanos);
// Parses a time string. This method accepts RFC3339 date/time string with UTC
// offset. For example, "2015-05-20T13:29:35.120-08:00".
-bool LIBPROTOBUF_EXPORT ParseTime(const string& vaule, int64* seconds, int32* nanos);
+bool LIBPROTOBUF_EXPORT ParseTime(const string& value, int64* seconds, int32* nanos);
} // namespace internal
} // namespace protobuf
diff --git a/src/google/protobuf/test_util.cc b/src/google/protobuf/test_util.cc
index 07aa1d77..658c8ee2 100644
--- a/src/google/protobuf/test_util.cc
+++ b/src/google/protobuf/test_util.cc
@@ -3332,7 +3332,11 @@ void TestUtil::ReflectionTester::ExpectMessagesReleasedViaReflection(
break;
case NOT_NULL:
EXPECT_TRUE(released != NULL);
- EXPECT_EQ(&sub_message, released);
+ if (message->GetArena() == NULL) {
+ // released message must be same as sub_message if source message is
+ // not on arena.
+ EXPECT_EQ(&sub_message, released);
+ }
break;
case CAN_BE_NULL:
break;
diff --git a/src/google/protobuf/testdata/golden_message_maps b/src/google/protobuf/testdata/golden_message_maps
new file mode 100644
index 00000000..c70a4d7c
--- /dev/null
+++ b/src/google/protobuf/testdata/golden_message_maps
Binary files differ
diff --git a/src/google/protobuf/testing/googletest.cc b/src/google/protobuf/testing/googletest.cc
index 2b9cddef..d45706b6 100644
--- a/src/google/protobuf/testing/googletest.cc
+++ b/src/google/protobuf/testing/googletest.cc
@@ -66,6 +66,9 @@ namespace protobuf {
string TestSourceDir() {
#ifndef GOOGLE_THIRD_PARTY_PROTOBUF
+#ifdef GOOGLE_PROTOBUF_TEST_SOURCE_PATH
+ return GOOGLE_PROTOBUF_TEST_SOURCE_PATH;
+#else
#ifndef _MSC_VER
// automake sets the "srcdir" environment variable.
char* result = getenv("srcdir");
@@ -86,6 +89,7 @@ string TestSourceDir() {
prefix += "/..";
}
return prefix + "/src";
+#endif // GOOGLE_PROTOBUF_TEST_SOURCE_PATH
#else
return "third_party/protobuf/src";
#endif // GOOGLE_THIRD_PARTY_PROTOBUF
diff --git a/src/google/protobuf/text_format.cc b/src/google/protobuf/text_format.cc
index 38b9069b..66b2648b 100644
--- a/src/google/protobuf/text_format.cc
+++ b/src/google/protobuf/text_format.cc
@@ -46,6 +46,7 @@
#include <google/protobuf/dynamic_message.h>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/wire_format_lite.h>
+#include <google/protobuf/io/strtod.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
@@ -90,7 +91,10 @@ inline bool GetAnyFieldDescriptors(const Message& message,
string Message::DebugString() const {
string debug_string;
- TextFormat::PrintToString(*this, &debug_string);
+ TextFormat::Printer printer;
+ printer.SetExpandAny(true);
+
+ printer.PrintToString(*this, &debug_string);
return debug_string;
}
@@ -100,6 +104,7 @@ string Message::ShortDebugString() const {
TextFormat::Printer printer;
printer.SetSingleLineMode(true);
+ printer.SetExpandAny(true);
printer.PrintToString(*this, &debug_string);
// Single line mode currently might have an extra space at the end.
@@ -116,6 +121,7 @@ string Message::Utf8DebugString() const {
TextFormat::Printer printer;
printer.SetUseUtf8StringEscaping(true);
+ printer.SetExpandAny(true);
printer.PrintToString(*this, &debug_string);
@@ -228,7 +234,8 @@ class TextFormat::Parser::ParserImpl {
bool allow_unknown_field,
bool allow_unknown_enum,
bool allow_field_number,
- bool allow_relaxed_whitespace)
+ bool allow_relaxed_whitespace,
+ bool allow_partial)
: error_collector_(error_collector),
finder_(finder),
parse_info_tree_(parse_info_tree),
@@ -240,6 +247,7 @@ class TextFormat::Parser::ParserImpl {
allow_unknown_field_(allow_unknown_field),
allow_unknown_enum_(allow_unknown_enum),
allow_field_number_(allow_field_number),
+ allow_partial_(allow_partial),
had_errors_(false) {
// For backwards-compatibility with proto1, we need to allow the 'f' suffix
// for floats.
@@ -380,6 +388,7 @@ class TextFormat::Parser::ParserImpl {
string full_type_name, prefix;
DO(ConsumeAnyTypeUrl(&full_type_name, &prefix));
DO(Consume("]"));
+ TryConsume(":"); // ':' is optional between message labels and values.
string serialized_value;
DO(ConsumeAnyValue(full_type_name,
message->GetDescriptor()->file()->pool(),
@@ -389,7 +398,6 @@ class TextFormat::Parser::ParserImpl {
string(prefix + full_type_name));
reflection->SetString(message, any_value_field, serialized_value);
return true;
- // Fall through.
}
if (TryConsume("[")) {
// Extension.
@@ -656,7 +664,7 @@ class TextFormat::Parser::ParserImpl {
case FieldDescriptor::CPPTYPE_FLOAT: {
double value;
DO(ConsumeDouble(&value));
- SET_FIELD(Float, static_cast<float>(value));
+ SET_FIELD(Float, io::SafeDoubleToFloat(value));
break;
}
@@ -712,7 +720,8 @@ class TextFormat::Parser::ParserImpl {
value = SimpleItoa(int_value); // for error reporting
enum_value = enum_type->FindValueByNumber(int_value);
} else {
- ReportError("Expected integer or identifier.");
+ ReportError("Expected integer or identifier, got: " +
+ tokenizer_.current().text);
return false;
}
@@ -750,6 +759,20 @@ class TextFormat::Parser::ParserImpl {
}
return true;
}
+ if (TryConsume("[")) {
+ while (true) {
+ if (!LookingAt("{") && !LookingAt("<")) {
+ DO(SkipFieldValue());
+ } else {
+ DO(SkipFieldMessage());
+ }
+ if (TryConsume("]")) {
+ break;
+ }
+ DO(Consume(","));
+ }
+ return true;
+ }
// Possible field values other than string:
// 12345 => TYPE_INTEGER
// -12345 => TYPE_SYMBOL + TYPE_INTEGER
@@ -825,7 +848,7 @@ class TextFormat::Parser::ParserImpl {
return true;
}
- ReportError("Expected identifier.");
+ ReportError("Expected identifier, got: " + tokenizer_.current().text);
return false;
}
@@ -845,7 +868,7 @@ class TextFormat::Parser::ParserImpl {
// Returns false if the token is not of type STRING.
bool ConsumeString(string* text) {
if (!LookingAtType(io::Tokenizer::TYPE_STRING)) {
- ReportError("Expected string.");
+ ReportError("Expected string, got: " + tokenizer_.current().text);
return false;
}
@@ -863,13 +886,13 @@ class TextFormat::Parser::ParserImpl {
// Returns false if the token is not of type INTEGER.
bool ConsumeUnsignedInteger(uint64* value, uint64 max_value) {
if (!LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
- ReportError("Expected integer.");
+ ReportError("Expected integer, got: " + tokenizer_.current().text);
return false;
}
if (!io::Tokenizer::ParseInteger(tokenizer_.current().text,
max_value, value)) {
- ReportError("Integer out of range.");
+ ReportError("Integer out of range (" + tokenizer_.current().text + ")");
return false;
}
@@ -896,10 +919,14 @@ class TextFormat::Parser::ParserImpl {
DO(ConsumeUnsignedInteger(&unsigned_value, max_value));
- *value = static_cast<int64>(unsigned_value);
-
if (negative) {
- *value = -*value;
+ if ((static_cast<uint64>(kint64max) + 1) == unsigned_value) {
+ *value = kint64min;
+ } else {
+ *value = -static_cast<int64>(unsigned_value);
+ }
+ } else {
+ *value = static_cast<int64>(unsigned_value);
}
return true;
@@ -909,18 +936,18 @@ class TextFormat::Parser::ParserImpl {
// Accepts decimal numbers only, rejects hex or oct numbers.
bool ConsumeUnsignedDecimalInteger(uint64* value, uint64 max_value) {
if (!LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
- ReportError("Expected integer.");
+ ReportError("Expected integer, got: " + tokenizer_.current().text);
return false;
}
const string& text = tokenizer_.current().text;
if (IsHexNumber(text) || IsOctNumber(text)) {
- ReportError("Expect a decimal number.");
+ ReportError("Expect a decimal number, got: " + text);
return false;
}
if (!io::Tokenizer::ParseInteger(text, max_value, value)) {
- ReportError("Integer out of range.");
+ ReportError("Integer out of range (" + text + ")");
return false;
}
@@ -965,11 +992,11 @@ class TextFormat::Parser::ParserImpl {
*value = std::numeric_limits<double>::quiet_NaN();
tokenizer_.Next();
} else {
- ReportError("Expected double.");
+ ReportError("Expected double, got: " + text);
return false;
}
} else {
- ReportError("Expected double.");
+ ReportError("Expected double, got: " + tokenizer_.current().text);
return false;
}
@@ -1027,7 +1054,17 @@ class TextFormat::Parser::ParserImpl {
DO(ConsumeMessageDelimiter(&sub_delimiter));
DO(ConsumeMessage(value.get(), sub_delimiter));
- value->AppendToString(serialized_value);
+ if (allow_partial_) {
+ value->AppendPartialToString(serialized_value);
+ } else {
+ if (!value->IsInitialized()) {
+ ReportError(
+ "Value of type \"" + full_type_name +
+ "\" stored in google.protobuf.Any has missing required fields");
+ return false;
+ }
+ value->AppendToString(serialized_value);
+ }
return true;
}
@@ -1092,6 +1129,7 @@ class TextFormat::Parser::ParserImpl {
const bool allow_unknown_field_;
const bool allow_unknown_enum_;
const bool allow_field_number_;
+ const bool allow_partial_;
bool had_errors_;
};
@@ -1152,10 +1190,10 @@ class TextFormat::Printer::TextGenerator {
}
// Print text to the output stream.
- void Print(const char* text, int size) {
- int pos = 0; // The number of bytes we've written so far.
+ void Print(const char* text, size_t size) {
+ size_t pos = 0; // The number of bytes we've written so far.
- for (int i = 0; i < size; i++) {
+ for (size_t i = 0; i < size; i++) {
if (text[i] == '\n') {
// Saw newline. If there is more text, we may need to insert an indent
// here. So, write what we have so far, including the '\n'.
@@ -1180,7 +1218,7 @@ class TextFormat::Printer::TextGenerator {
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TextGenerator);
- void Write(const char* data, int size) {
+ void Write(const char* data, size_t size) {
if (failed_) return;
if (size == 0) return;
@@ -1253,7 +1291,7 @@ bool TextFormat::Parser::Parse(io::ZeroCopyInputStream* input,
overwrites_policy,
allow_case_insensitive_field_, allow_unknown_field_,
allow_unknown_enum_, allow_field_number_,
- allow_relaxed_whitespace_);
+ allow_relaxed_whitespace_, allow_partial_);
return MergeUsingImpl(input, output, &parser);
}
@@ -1270,7 +1308,7 @@ bool TextFormat::Parser::Merge(io::ZeroCopyInputStream* input,
ParserImpl::ALLOW_SINGULAR_OVERWRITES,
allow_case_insensitive_field_, allow_unknown_field_,
allow_unknown_enum_, allow_field_number_,
- allow_relaxed_whitespace_);
+ allow_relaxed_whitespace_, allow_partial_);
return MergeUsingImpl(input, output, &parser);
}
@@ -1304,7 +1342,7 @@ bool TextFormat::Parser::ParseFieldValueFromString(
ParserImpl::ALLOW_SINGULAR_OVERWRITES,
allow_case_insensitive_field_, allow_unknown_field_,
allow_unknown_enum_, allow_field_number_,
- allow_relaxed_whitespace_);
+ allow_relaxed_whitespace_, allow_partial_);
return parser.ParseField(field, output);
}
@@ -1357,7 +1395,10 @@ string TextFormat::FieldValuePrinter::PrintDouble(double val) const {
return SimpleDtoa(val);
}
string TextFormat::FieldValuePrinter::PrintString(const string& val) const {
- return StrCat("\"", CEscape(val), "\"");
+ string printed("\"");
+ CEscapeAndAppend(val, &printed);
+ printed.push_back('\"');
+ return printed;
}
string TextFormat::FieldValuePrinter::PrintBytes(const string& val) const {
return PrintString(val);
@@ -1423,7 +1464,8 @@ TextFormat::Printer::Printer()
use_short_repeated_primitives_(false),
hide_unknown_fields_(false),
print_message_fields_in_index_order_(false),
- expand_any_(false) {
+ expand_any_(false),
+ truncate_string_field_longer_than_(0LL) {
SetUseUtf8StringEscaping(false);
}
@@ -1775,11 +1817,19 @@ void TextFormat::Printer::PrintFieldValue(
? reflection->GetRepeatedStringReference(
message, field, index, &scratch)
: reflection->GetStringReference(message, field, &scratch);
+ const string* value_to_print = &value;
+ string truncated_value;
+ if (truncate_string_field_longer_than_ > 0 &&
+ truncate_string_field_longer_than_ < value.size()) {
+ truncated_value = value.substr(0, truncate_string_field_longer_than_) +
+ "...<truncated>...";
+ value_to_print = &truncated_value;
+ }
if (field->type() == FieldDescriptor::TYPE_STRING) {
- generator.Print(printer->PrintString(value));
+ generator.Print(printer->PrintString(*value_to_print));
} else {
GOOGLE_DCHECK_EQ(field->type(), FieldDescriptor::TYPE_BYTES);
- generator.Print(printer->PrintBytes(value));
+ generator.Print(printer->PrintBytes(*value_to_print));
}
break;
}
@@ -1926,14 +1976,10 @@ void TextFormat::Printer::PrintUnknownFields(
} else {
// This field is not parseable as a Message.
// So it is probably just a plain string.
- generator.Print(": \"");
- generator.Print(CEscape(value));
- generator.Print("\"");
- if (single_line_mode_) {
- generator.Print(" ");
- } else {
- generator.Print("\n");
- }
+ string printed(": \"");
+ CEscapeAndAppend(value, &printed);
+ printed.append(single_line_mode_ ? "\" " : "\"\n");
+ generator.Print(printed);
}
break;
}
diff --git a/src/google/protobuf/text_format.h b/src/google/protobuf/text_format.h
index 6717aecd..ef3d4a8f 100644
--- a/src/google/protobuf/text_format.h
+++ b/src/google/protobuf/text_format.h
@@ -219,6 +219,18 @@ class LIBPROTOBUF_EXPORT TextFormat {
expand_any_ = expand;
}
+ // If non-zero, we truncate all string fields that are longer than this
+ // threshold. This is useful when the proto message has very long strings,
+ // e.g., dump of encoded image file.
+ //
+ // NOTE(hfgong): Setting a non-zero value breaks round-trip safe
+ // property of TextFormat::Printer. That is, from the printed message, we
+ // cannot fully recover the original string field any more.
+ void SetTruncateStringFieldLongerThan(
+ const int64 truncate_string_field_longer_than) {
+ truncate_string_field_longer_than_ = truncate_string_field_longer_than;
+ }
+
// Register a custom field-specific FieldValuePrinter for fields
// with a particular FieldDescriptor.
// Returns "true" if the registration succeeded, or "false", if there is
@@ -286,6 +298,8 @@ class LIBPROTOBUF_EXPORT TextFormat {
bool expand_any_;
+ int64 truncate_string_field_longer_than_;
+
google::protobuf::scoped_ptr<const FieldValuePrinter> default_field_value_printer_;
typedef map<const FieldDescriptor*,
const FieldValuePrinter*> CustomPrinterMap;
diff --git a/src/google/protobuf/text_format_unittest.cc b/src/google/protobuf/text_format_unittest.cc
index 8d61be19..c9521cc3 100644
--- a/src/google/protobuf/text_format_unittest.cc
+++ b/src/google/protobuf/text_format_unittest.cc
@@ -44,6 +44,8 @@
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/logging.h>
+#include <google/protobuf/testing/file.h>
#include <google/protobuf/testing/file.h>
#include <google/protobuf/test_util.h>
#include <google/protobuf/unittest.pb.h>
@@ -51,8 +53,8 @@
#include <google/protobuf/unittest_mset_wire_format.pb.h>
#include <google/protobuf/io/tokenizer.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
-#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/mathlimits.h>
+#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/substitute.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
@@ -1194,11 +1196,13 @@ TEST_F(TextFormatParserTest, ParseFieldValueFromString) {
TEST_F(TextFormatParserTest, InvalidToken) {
- ExpectFailure("optional_bool: true\n-5\n", "Expected identifier.",
+ ExpectFailure("optional_bool: true\n-5\n", "Expected identifier, got: -",
2, 1);
- ExpectFailure("optional_bool: true!\n", "Expected identifier.", 1, 20);
- ExpectFailure("\"some string\"", "Expected identifier.", 1, 1);
+ ExpectFailure("optional_bool: true!\n", "Expected identifier, got: !", 1,
+ 20);
+ ExpectFailure("\"some string\"",
+ "Expected identifier, got: \"some string\"", 1, 1);
}
TEST_F(TextFormatParserTest, InvalidFieldName) {
@@ -1246,46 +1250,52 @@ TEST_F(TextFormatParserTest, AllowIgnoreCapitalizationError) {
TEST_F(TextFormatParserTest, InvalidFieldValues) {
// Invalid values for a double/float field.
- ExpectFailure("optional_double: \"hello\"\n", "Expected double.", 1, 18);
- ExpectFailure("optional_double: true\n", "Expected double.", 1, 18);
- ExpectFailure("optional_double: !\n", "Expected double.", 1, 18);
+ ExpectFailure("optional_double: \"hello\"\n",
+ "Expected double, got: \"hello\"", 1, 18);
+ ExpectFailure("optional_double: true\n", "Expected double, got: true", 1,
+ 18);
+ ExpectFailure("optional_double: !\n", "Expected double, got: !", 1, 18);
ExpectFailure("optional_double {\n \n}\n", "Expected \":\", found \"{\".",
1, 17);
// Invalid values for a signed integer field.
- ExpectFailure("optional_int32: \"hello\"\n", "Expected integer.", 1, 17);
- ExpectFailure("optional_int32: true\n", "Expected integer.", 1, 17);
- ExpectFailure("optional_int32: 4.5\n", "Expected integer.", 1, 17);
- ExpectFailure("optional_int32: !\n", "Expected integer.", 1, 17);
+ ExpectFailure("optional_int32: \"hello\"\n",
+ "Expected integer, got: \"hello\"", 1, 17);
+ ExpectFailure("optional_int32: true\n", "Expected integer, got: true", 1, 17);
+ ExpectFailure("optional_int32: 4.5\n", "Expected integer, got: 4.5", 1, 17);
+ ExpectFailure("optional_int32: !\n", "Expected integer, got: !", 1, 17);
ExpectFailure("optional_int32 {\n \n}\n", "Expected \":\", found \"{\".",
1, 16);
ExpectFailure("optional_int32: 0x80000000\n",
- "Integer out of range.", 1, 17);
+ "Integer out of range (0x80000000)", 1, 17);
ExpectFailure("optional_int64: 0x8000000000000000\n",
- "Integer out of range.", 1, 17);
+ "Integer out of range (0x8000000000000000)", 1, 17);
ExpectFailure("optional_int32: -0x80000001\n",
- "Integer out of range.", 1, 18);
+ "Integer out of range (0x80000001)", 1, 18);
ExpectFailure("optional_int64: -0x8000000000000001\n",
- "Integer out of range.", 1, 18);
+ "Integer out of range (0x8000000000000001)", 1, 18);
// Invalid values for an unsigned integer field.
- ExpectFailure("optional_uint64: \"hello\"\n", "Expected integer.", 1, 18);
- ExpectFailure("optional_uint64: true\n", "Expected integer.", 1, 18);
- ExpectFailure("optional_uint64: 4.5\n", "Expected integer.", 1, 18);
- ExpectFailure("optional_uint64: -5\n", "Expected integer.", 1, 18);
- ExpectFailure("optional_uint64: !\n", "Expected integer.", 1, 18);
+ ExpectFailure("optional_uint64: \"hello\"\n",
+ "Expected integer, got: \"hello\"", 1, 18);
+ ExpectFailure("optional_uint64: true\n",
+ "Expected integer, got: true", 1, 18);
+ ExpectFailure("optional_uint64: 4.5\n", "Expected integer, got: 4.5", 1, 18);
+ ExpectFailure("optional_uint64: -5\n", "Expected integer, got: -", 1, 18);
+ ExpectFailure("optional_uint64: !\n", "Expected integer, got: !", 1, 18);
ExpectFailure("optional_uint64 {\n \n}\n", "Expected \":\", found \"{\".",
1, 17);
ExpectFailure("optional_uint32: 0x100000000\n",
- "Integer out of range.", 1, 18);
+ "Integer out of range (0x100000000)", 1, 18);
ExpectFailure("optional_uint64: 0x10000000000000000\n",
- "Integer out of range.", 1, 18);
+ "Integer out of range (0x10000000000000000)", 1, 18);
// Invalid values for a boolean field.
- ExpectFailure("optional_bool: \"hello\"\n", "Expected identifier.", 1, 16);
- ExpectFailure("optional_bool: 5\n", "Integer out of range.", 1, 16);
- ExpectFailure("optional_bool: -7.5\n", "Expected identifier.", 1, 16);
- ExpectFailure("optional_bool: !\n", "Expected identifier.", 1, 16);
+ ExpectFailure("optional_bool: \"hello\"\n",
+ "Expected identifier, got: \"hello\"", 1, 16);
+ ExpectFailure("optional_bool: 5\n", "Integer out of range (5)", 1, 16);
+ ExpectFailure("optional_bool: -7.5\n", "Expected identifier, got: -", 1, 16);
+ ExpectFailure("optional_bool: !\n", "Expected identifier, got: !", 1, 16);
ExpectFailure(
"optional_bool: meh\n",
@@ -1296,16 +1306,16 @@ TEST_F(TextFormatParserTest, InvalidFieldValues) {
1, 15);
// Invalid values for a string field.
- ExpectFailure("optional_string: true\n", "Expected string.", 1, 18);
- ExpectFailure("optional_string: 5\n", "Expected string.", 1, 18);
- ExpectFailure("optional_string: -7.5\n", "Expected string.", 1, 18);
- ExpectFailure("optional_string: !\n", "Expected string.", 1, 18);
+ ExpectFailure("optional_string: true\n", "Expected string, got: true", 1, 18);
+ ExpectFailure("optional_string: 5\n", "Expected string, got: 5", 1, 18);
+ ExpectFailure("optional_string: -7.5\n", "Expected string, got: -", 1, 18);
+ ExpectFailure("optional_string: !\n", "Expected string, got: !", 1, 18);
ExpectFailure("optional_string {\n \n}\n", "Expected \":\", found \"{\".",
1, 17);
// Invalid values for an enumeration field.
ExpectFailure("optional_nested_enum: \"hello\"\n",
- "Expected integer or identifier.", 1, 23);
+ "Expected integer or identifier, got: \"hello\"", 1, 23);
// Valid token, but enum value is not defined.
ExpectFailure("optional_nested_enum: 5\n",
@@ -1313,9 +1323,10 @@ TEST_F(TextFormatParserTest, InvalidFieldValues) {
"\"optional_nested_enum\".", 2, 1);
// We consume the negative sign, so the error position starts one character
// later.
- ExpectFailure("optional_nested_enum: -7.5\n", "Expected integer.", 1, 24);
+ ExpectFailure("optional_nested_enum: -7.5\n", "Expected integer, got: 7.5", 1,
+ 24);
ExpectFailure("optional_nested_enum: !\n",
- "Expected integer or identifier.", 1, 23);
+ "Expected integer or identifier, got: !", 1, 23);
ExpectFailure(
"optional_nested_enum: grah\n",
@@ -1338,7 +1349,7 @@ TEST_F(TextFormatParserTest, MessageDelimiters) {
// Unending message.
ExpectFailure("optional_nested_message {\n \nbb: 118\n",
- "Expected identifier.",
+ "Expected identifier, got: ",
4, 1);
}
diff --git a/src/google/protobuf/timestamp.pb.cc b/src/google/protobuf/timestamp.pb.cc
index f0b09195..542e5ed7 100644
--- a/src/google/protobuf/timestamp.pb.cc
+++ b/src/google/protobuf/timestamp.pb.cc
@@ -7,6 +7,7 @@
#include <algorithm>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/port.h>
#include <google/protobuf/stubs/once.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/wire_format_lite_inl.h>
@@ -28,6 +29,7 @@ const ::google::protobuf::internal::GeneratedMessageReflection*
} // namespace
+void protobuf_AssignDesc_google_2fprotobuf_2ftimestamp_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AssignDesc_google_2fprotobuf_2ftimestamp_2eproto() {
protobuf_AddDesc_google_2fprotobuf_2ftimestamp_2eproto();
const ::google::protobuf::FileDescriptor* file =
@@ -60,6 +62,7 @@ inline void protobuf_AssignDescriptorsOnce() {
&protobuf_AssignDesc_google_2fprotobuf_2ftimestamp_2eproto);
}
+void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
void protobuf_RegisterTypes(const ::std::string&) {
protobuf_AssignDescriptorsOnce();
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
@@ -73,6 +76,7 @@ void protobuf_ShutdownFile_google_2fprotobuf_2ftimestamp_2eproto() {
delete Timestamp_reflection_;
}
+void protobuf_AddDesc_google_2fprotobuf_2ftimestamp_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AddDesc_google_2fprotobuf_2ftimestamp_2eproto() {
static bool already_here = false;
if (already_here) return;
@@ -82,9 +86,10 @@ void protobuf_AddDesc_google_2fprotobuf_2ftimestamp_2eproto() {
::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
"\n\037google/protobuf/timestamp.proto\022\017googl"
"e.protobuf\"+\n\tTimestamp\022\017\n\007seconds\030\001 \001(\003"
- "\022\r\n\005nanos\030\002 \001(\005BQ\n\023com.google.protobufB\016"
- "TimestampProtoP\001\240\001\001\242\002\003GPB\252\002\036Google.Proto"
- "buf.WellKnownTypesb\006proto3", 186);
+ "\022\r\n\005nanos\030\002 \001(\005B\201\001\n\023com.google.protobufB"
+ "\016TimestampProtoP\001Z+github.com/golang/pro"
+ "tobuf/ptypes/timestamp\240\001\001\370\001\001\242\002\003GPB\252\002\036Goo"
+ "gle.Protobuf.WellKnownTypesb\006proto3", 235);
::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
"google/protobuf/timestamp.proto", &protobuf_RegisterTypes);
Timestamp::default_instance_ = new Timestamp();
@@ -99,16 +104,6 @@ struct StaticDescriptorInitializer_google_2fprotobuf_2ftimestamp_2eproto {
}
} static_descriptor_initializer_google_2fprotobuf_2ftimestamp_2eproto_;
-namespace {
-
-static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD;
-static void MergeFromFail(int line) {
- GOOGLE_CHECK(false) << __FILE__ << ":" << line;
-}
-
-} // namespace
-
-
// ===================================================================
#if !defined(_MSC_VER) || _MSC_VER >= 1900
@@ -122,6 +117,14 @@ Timestamp::Timestamp()
// @@protoc_insertion_point(constructor:google.protobuf.Timestamp)
}
+Timestamp::Timestamp(::google::protobuf::Arena* arena)
+ : ::google::protobuf::Message(),
+ _internal_metadata_(arena) {
+ SharedCtor();
+ RegisterArenaDtor(arena);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.Timestamp)
+}
+
void Timestamp::InitAsDefaultInstance() {
_is_default_instance_ = true;
}
@@ -147,10 +150,20 @@ Timestamp::~Timestamp() {
}
void Timestamp::SharedDtor() {
+ if (GetArenaNoVirtual() != NULL) {
+ return;
+ }
+
if (this != default_instance_) {
}
}
+void Timestamp::ArenaDtor(void* object) {
+ Timestamp* _this = reinterpret_cast< Timestamp* >(object);
+ (void)_this;
+}
+void Timestamp::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+}
void Timestamp::SetCachedSize(int size) const {
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
_cached_size_ = size;
@@ -169,16 +182,21 @@ const Timestamp& Timestamp::default_instance() {
Timestamp* Timestamp::default_instance_ = NULL;
Timestamp* Timestamp::New(::google::protobuf::Arena* arena) const {
- Timestamp* n = new Timestamp;
- if (arena != NULL) {
- arena->Own(n);
- }
- return n;
+ return ::google::protobuf::Arena::CreateMessage<Timestamp>(arena);
}
void Timestamp::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.Timestamp)
+#if defined(__clang__)
+#define ZR_HELPER_(f) \
+ _Pragma("clang diagnostic push") \
+ _Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"") \
+ __builtin_offsetof(Timestamp, f) \
+ _Pragma("clang diagnostic pop")
+#else
#define ZR_HELPER_(f) reinterpret_cast<char*>(\
&reinterpret_cast<Timestamp*>(16)->f)
+#endif
#define ZR_(first, last) do {\
::memset(&first, 0,\
@@ -194,7 +212,7 @@ void Timestamp::Clear() {
bool Timestamp::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.Timestamp)
for (;;) {
@@ -268,8 +286,8 @@ void Timestamp::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.Timestamp)
}
-::google::protobuf::uint8* Timestamp::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* Timestamp::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Timestamp)
// optional int64 seconds = 1;
if (this->seconds() != 0) {
@@ -286,6 +304,7 @@ void Timestamp::SerializeWithCachedSizes(
}
int Timestamp::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Timestamp)
int total_size = 0;
// optional int64 seconds = 1;
@@ -309,19 +328,27 @@ int Timestamp::ByteSize() const {
}
void Timestamp::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Timestamp)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const Timestamp* source =
::google::protobuf::internal::DynamicCastToGenerated<const Timestamp>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.Timestamp)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.Timestamp)
MergeFrom(*source);
}
}
void Timestamp::MergeFrom(const Timestamp& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Timestamp)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from.seconds() != 0) {
set_seconds(from.seconds());
}
@@ -331,12 +358,14 @@ void Timestamp::MergeFrom(const Timestamp& from) {
}
void Timestamp::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.Timestamp)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void Timestamp::CopyFrom(const Timestamp& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Timestamp)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -349,6 +378,18 @@ bool Timestamp::IsInitialized() const {
void Timestamp::Swap(Timestamp* other) {
if (other == this) return;
+ if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
+ InternalSwap(other);
+ } else {
+ Timestamp temp;
+ temp.MergeFrom(*this);
+ CopyFrom(*other);
+ other->CopyFrom(temp);
+ }
+}
+void Timestamp::UnsafeArenaSwap(Timestamp* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
void Timestamp::InternalSwap(Timestamp* other) {
diff --git a/src/google/protobuf/timestamp.pb.h b/src/google/protobuf/timestamp.pb.h
index 85fc1242..19f4f86f 100644
--- a/src/google/protobuf/timestamp.pb.h
+++ b/src/google/protobuf/timestamp.pb.h
@@ -41,7 +41,7 @@ class Timestamp;
// ===================================================================
-class LIBPROTOBUF_EXPORT Timestamp : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT Timestamp : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Timestamp) */ {
public:
Timestamp();
virtual ~Timestamp();
@@ -53,9 +53,14 @@ class LIBPROTOBUF_EXPORT Timestamp : public ::google::protobuf::Message {
return *this;
}
+ inline ::google::protobuf::Arena* GetArena() const { return GetArenaNoVirtual(); }
+ inline void* GetMaybeArenaPointer() const {
+ return MaybeArenaPtr();
+ }
static const ::google::protobuf::Descriptor* descriptor();
static const Timestamp& default_instance();
+ void UnsafeArenaSwap(Timestamp* other);
void Swap(Timestamp* other);
// implements Message ----------------------------------------------
@@ -75,13 +80,22 @@ class LIBPROTOBUF_EXPORT Timestamp : public ::google::protobuf::Message {
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
void SharedDtor();
void SetCachedSize(int size) const;
void InternalSwap(Timestamp* other);
+ protected:
+ explicit Timestamp(::google::protobuf::Arena* arena);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::google::protobuf::Arena* arena);
private:
inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
return _internal_metadata_.arena();
@@ -113,6 +127,9 @@ class LIBPROTOBUF_EXPORT Timestamp : public ::google::protobuf::Message {
private:
::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+ friend class ::google::protobuf::Arena;
+ typedef void InternalArenaConstructable_;
+ typedef void DestructorSkippable_;
bool _is_default_instance_;
::google::protobuf::int64 seconds_;
::google::protobuf::int32 nanos_;
diff --git a/src/google/protobuf/timestamp.proto b/src/google/protobuf/timestamp.proto
index 06b60e6f..7992a858 100644
--- a/src/google/protobuf/timestamp.proto
+++ b/src/google/protobuf/timestamp.proto
@@ -27,15 +27,18 @@
// 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.
+
syntax = "proto3";
package google.protobuf;
-option java_generate_equals_and_hash = true;
-option java_multiple_files = true;
-option java_outer_classname = "TimestampProto";
-option java_package = "com.google.protobuf";
option csharp_namespace = "Google.Protobuf.WellKnownTypes";
+option cc_enable_arenas = true;
+option go_package = "github.com/golang/protobuf/ptypes/timestamp";
+option java_package = "com.google.protobuf";
+option java_outer_classname = "TimestampProto";
+option java_multiple_files = true;
+option java_generate_equals_and_hash = true;
option objc_class_prefix = "GPB";
// A Timestamp represents a point in time independent of any time zone
@@ -92,6 +95,7 @@ option objc_class_prefix = "GPB";
// nanos = int((now - seconds) * 10**9)
// timestamp = Timestamp(seconds=seconds, nanos=nanos)
//
+//
message Timestamp {
// Represents seconds of UTC time since Unix epoch
diff --git a/src/google/protobuf/type.pb.cc b/src/google/protobuf/type.pb.cc
index 5792dff2..7ba909ef 100644
--- a/src/google/protobuf/type.pb.cc
+++ b/src/google/protobuf/type.pb.cc
@@ -7,6 +7,7 @@
#include <algorithm>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/port.h>
#include <google/protobuf/stubs/once.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/wire_format_lite_inl.h>
@@ -43,6 +44,7 @@ const ::google::protobuf::EnumDescriptor* Syntax_descriptor_ = NULL;
} // namespace
+void protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto() {
protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto();
const ::google::protobuf::FileDescriptor* file =
@@ -70,7 +72,7 @@ void protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto() {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, _internal_metadata_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, _is_default_instance_));
Field_descriptor_ = file->message_type(1);
- static const int Field_offsets_[9] = {
+ static const int Field_offsets_[10] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, kind_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, cardinality_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, number_),
@@ -80,6 +82,7 @@ void protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto() {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, packed_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, options_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, json_name_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, default_value_),
};
Field_reflection_ =
::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
@@ -157,6 +160,7 @@ inline void protobuf_AssignDescriptorsOnce() {
&protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto);
}
+void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
void protobuf_RegisterTypes(const ::std::string&) {
protobuf_AssignDescriptorsOnce();
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
@@ -186,6 +190,7 @@ void protobuf_ShutdownFile_google_2fprotobuf_2ftype_2eproto() {
delete Option_reflection_;
}
+void protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto() {
static bool already_here = false;
if (already_here) return;
@@ -203,37 +208,37 @@ void protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto() {
"\030\004 \003(\0132\027.google.protobuf.Option\0226\n\016sourc"
"e_context\030\005 \001(\0132\036.google.protobuf.Source"
"Context\022\'\n\006syntax\030\006 \001(\0162\027.google.protobu"
- "f.Syntax\"\276\005\n\005Field\022)\n\004kind\030\001 \001(\0162\033.googl"
+ "f.Syntax\"\325\005\n\005Field\022)\n\004kind\030\001 \001(\0162\033.googl"
"e.protobuf.Field.Kind\0227\n\013cardinality\030\002 \001"
"(\0162\".google.protobuf.Field.Cardinality\022\016"
"\n\006number\030\003 \001(\005\022\014\n\004name\030\004 \001(\t\022\020\n\010type_url"
"\030\006 \001(\t\022\023\n\013oneof_index\030\007 \001(\005\022\016\n\006packed\030\010 "
"\001(\010\022(\n\007options\030\t \003(\0132\027.google.protobuf.O"
- "ption\022\021\n\tjson_name\030\n \001(\t\"\310\002\n\004Kind\022\020\n\014TYP"
- "E_UNKNOWN\020\000\022\017\n\013TYPE_DOUBLE\020\001\022\016\n\nTYPE_FLO"
- "AT\020\002\022\016\n\nTYPE_INT64\020\003\022\017\n\013TYPE_UINT64\020\004\022\016\n"
- "\nTYPE_INT32\020\005\022\020\n\014TYPE_FIXED64\020\006\022\020\n\014TYPE_"
- "FIXED32\020\007\022\r\n\tTYPE_BOOL\020\010\022\017\n\013TYPE_STRING\020"
- "\t\022\016\n\nTYPE_GROUP\020\n\022\020\n\014TYPE_MESSAGE\020\013\022\016\n\nT"
- "YPE_BYTES\020\014\022\017\n\013TYPE_UINT32\020\r\022\r\n\tTYPE_ENU"
- "M\020\016\022\021\n\rTYPE_SFIXED32\020\017\022\021\n\rTYPE_SFIXED64\020"
- "\020\022\017\n\013TYPE_SINT32\020\021\022\017\n\013TYPE_SINT64\020\022\"t\n\013C"
- "ardinality\022\027\n\023CARDINALITY_UNKNOWN\020\000\022\030\n\024C"
- "ARDINALITY_OPTIONAL\020\001\022\030\n\024CARDINALITY_REQ"
- "UIRED\020\002\022\030\n\024CARDINALITY_REPEATED\020\003\"\316\001\n\004En"
- "um\022\014\n\004name\030\001 \001(\t\022-\n\tenumvalue\030\002 \003(\0132\032.go"
- "ogle.protobuf.EnumValue\022(\n\007options\030\003 \003(\013"
- "2\027.google.protobuf.Option\0226\n\016source_cont"
- "ext\030\004 \001(\0132\036.google.protobuf.SourceContex"
- "t\022\'\n\006syntax\030\005 \001(\0162\027.google.protobuf.Synt"
- "ax\"S\n\tEnumValue\022\014\n\004name\030\001 \001(\t\022\016\n\006number\030"
- "\002 \001(\005\022(\n\007options\030\003 \003(\0132\027.google.protobuf"
- ".Option\";\n\006Option\022\014\n\004name\030\001 \001(\t\022#\n\005value"
- "\030\002 \001(\0132\024.google.protobuf.Any*.\n\006Syntax\022\021"
- "\n\rSYNTAX_PROTO2\020\000\022\021\n\rSYNTAX_PROTO3\020\001BL\n\023"
- "com.google.protobufB\tTypeProtoP\001\240\001\001\242\002\003GP"
- "B\252\002\036Google.Protobuf.WellKnownTypesb\006prot"
- "o3", 1522);
+ "ption\022\021\n\tjson_name\030\n \001(\t\022\025\n\rdefault_valu"
+ "e\030\013 \001(\t\"\310\002\n\004Kind\022\020\n\014TYPE_UNKNOWN\020\000\022\017\n\013TY"
+ "PE_DOUBLE\020\001\022\016\n\nTYPE_FLOAT\020\002\022\016\n\nTYPE_INT6"
+ "4\020\003\022\017\n\013TYPE_UINT64\020\004\022\016\n\nTYPE_INT32\020\005\022\020\n\014"
+ "TYPE_FIXED64\020\006\022\020\n\014TYPE_FIXED32\020\007\022\r\n\tTYPE"
+ "_BOOL\020\010\022\017\n\013TYPE_STRING\020\t\022\016\n\nTYPE_GROUP\020\n"
+ "\022\020\n\014TYPE_MESSAGE\020\013\022\016\n\nTYPE_BYTES\020\014\022\017\n\013TY"
+ "PE_UINT32\020\r\022\r\n\tTYPE_ENUM\020\016\022\021\n\rTYPE_SFIXE"
+ "D32\020\017\022\021\n\rTYPE_SFIXED64\020\020\022\017\n\013TYPE_SINT32\020"
+ "\021\022\017\n\013TYPE_SINT64\020\022\"t\n\013Cardinality\022\027\n\023CAR"
+ "DINALITY_UNKNOWN\020\000\022\030\n\024CARDINALITY_OPTION"
+ "AL\020\001\022\030\n\024CARDINALITY_REQUIRED\020\002\022\030\n\024CARDIN"
+ "ALITY_REPEATED\020\003\"\316\001\n\004Enum\022\014\n\004name\030\001 \001(\t\022"
+ "-\n\tenumvalue\030\002 \003(\0132\032.google.protobuf.Enu"
+ "mValue\022(\n\007options\030\003 \003(\0132\027.google.protobu"
+ "f.Option\0226\n\016source_context\030\004 \001(\0132\036.googl"
+ "e.protobuf.SourceContext\022\'\n\006syntax\030\005 \001(\016"
+ "2\027.google.protobuf.Syntax\"S\n\tEnumValue\022\014"
+ "\n\004name\030\001 \001(\t\022\016\n\006number\030\002 \001(\005\022(\n\007options\030"
+ "\003 \003(\0132\027.google.protobuf.Option\";\n\006Option"
+ "\022\014\n\004name\030\001 \001(\t\022#\n\005value\030\002 \001(\0132\024.google.p"
+ "rotobuf.Any*.\n\006Syntax\022\021\n\rSYNTAX_PROTO2\020\000"
+ "\022\021\n\rSYNTAX_PROTO3\020\001BL\n\023com.google.protob"
+ "ufB\tTypeProtoP\001\240\001\001\242\002\003GPB\252\002\036Google.Protob"
+ "uf.WellKnownTypesb\006proto3", 1545);
::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
"google/protobuf/type.proto", &protobuf_RegisterTypes);
Type::default_instance_ = new Type();
@@ -270,16 +275,6 @@ bool Syntax_IsValid(int value) {
}
-namespace {
-
-static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD;
-static void MergeFromFail(int line) {
- GOOGLE_CHECK(false) << __FILE__ << ":" << line;
-}
-
-} // namespace
-
-
// ===================================================================
#if !defined(_MSC_VER) || _MSC_VER >= 1900
@@ -357,6 +352,7 @@ Type* Type::New(::google::protobuf::Arena* arena) const {
}
void Type::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.Type)
name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
if (GetArenaNoVirtual() == NULL && source_context_ != NULL) delete source_context_;
source_context_ = NULL;
@@ -368,7 +364,7 @@ void Type::Clear() {
bool Type::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.Type)
for (;;) {
@@ -545,8 +541,8 @@ void Type::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.Type)
}
-::google::protobuf::uint8* Type::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* Type::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Type)
// optional string name = 1;
if (this->name().size() > 0) {
@@ -562,8 +558,8 @@ void Type::SerializeWithCachedSizes(
// repeated .google.protobuf.Field fields = 2;
for (unsigned int i = 0, n = this->fields_size(); i < n; i++) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 2, this->fields(i), target);
+ InternalWriteMessageNoVirtualToArray(
+ 2, this->fields(i), false, target);
}
// repeated string oneofs = 3;
@@ -579,15 +575,15 @@ void Type::SerializeWithCachedSizes(
// repeated .google.protobuf.Option options = 4;
for (unsigned int i = 0, n = this->options_size(); i < n; i++) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 4, this->options(i), target);
+ InternalWriteMessageNoVirtualToArray(
+ 4, this->options(i), false, target);
}
// optional .google.protobuf.SourceContext source_context = 5;
if (this->has_source_context()) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 5, *this->source_context_, target);
+ InternalWriteMessageNoVirtualToArray(
+ 5, *this->source_context_, false, target);
}
// optional .google.protobuf.Syntax syntax = 6;
@@ -601,6 +597,7 @@ void Type::SerializeWithCachedSizes(
}
int Type::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Type)
int total_size = 0;
// optional string name = 1;
@@ -653,19 +650,27 @@ int Type::ByteSize() const {
}
void Type::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Type)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const Type* source =
::google::protobuf::internal::DynamicCastToGenerated<const Type>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.Type)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.Type)
MergeFrom(*source);
}
}
void Type::MergeFrom(const Type& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Type)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
fields_.MergeFrom(from.fields_);
oneofs_.MergeFrom(from.oneofs_);
options_.MergeFrom(from.options_);
@@ -682,12 +687,14 @@ void Type::MergeFrom(const Type& from) {
}
void Type::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.Type)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void Type::CopyFrom(const Type& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Type)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -754,6 +761,7 @@ void Type::clear_name() {
return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* Type::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Type.name)
return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -826,6 +834,7 @@ void Type::clear_oneofs() {
// @@protoc_insertion_point(field_set_pointer:google.protobuf.Type.oneofs)
}
::std::string* Type::add_oneofs() {
+ // @@protoc_insertion_point(field_add_mutable:google.protobuf.Type.oneofs)
return oneofs_.Add();
}
void Type::add_oneofs(const ::std::string& value) {
@@ -902,6 +911,7 @@ const ::google::protobuf::SourceContext& Type::source_context() const {
return source_context_;
}
::google::protobuf::SourceContext* Type::release_source_context() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Type.source_context)
::google::protobuf::SourceContext* temp = source_context_;
source_context_ = NULL;
@@ -1026,6 +1036,7 @@ const int Field::kOneofIndexFieldNumber;
const int Field::kPackedFieldNumber;
const int Field::kOptionsFieldNumber;
const int Field::kJsonNameFieldNumber;
+const int Field::kDefaultValueFieldNumber;
#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
Field::Field()
@@ -1058,6 +1069,7 @@ void Field::SharedCtor() {
oneof_index_ = 0;
packed_ = false;
json_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ default_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
Field::~Field() {
@@ -1069,6 +1081,7 @@ void Field::SharedDtor() {
name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
type_url_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
json_name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ default_value_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
if (this != default_instance_) {
}
}
@@ -1099,8 +1112,17 @@ Field* Field::New(::google::protobuf::Arena* arena) const {
}
void Field::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.Field)
+#if defined(__clang__)
+#define ZR_HELPER_(f) \
+ _Pragma("clang diagnostic push") \
+ _Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"") \
+ __builtin_offsetof(Field, f) \
+ _Pragma("clang diagnostic pop")
+#else
#define ZR_HELPER_(f) reinterpret_cast<char*>(\
&reinterpret_cast<Field*>(16)->f)
+#endif
#define ZR_(first, last) do {\
::memset(&first, 0,\
@@ -1113,6 +1135,7 @@ void Field::Clear() {
type_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
packed_ = false;
json_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ default_value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
#undef ZR_HELPER_
#undef ZR_
@@ -1122,7 +1145,7 @@ void Field::Clear() {
bool Field::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.Field)
for (;;) {
@@ -1270,6 +1293,23 @@ bool Field::MergePartialFromCodedStream(
} else {
goto handle_unusual;
}
+ if (input->ExpectTag(90)) goto parse_default_value;
+ break;
+ }
+
+ // optional string default_value = 11;
+ case 11: {
+ if (tag == 90) {
+ parse_default_value:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+ input, this->mutable_default_value()));
+ DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+ this->default_value().data(), this->default_value().length(),
+ ::google::protobuf::internal::WireFormatLite::PARSE,
+ "google.protobuf.Field.default_value"));
+ } else {
+ goto handle_unusual;
+ }
if (input->ExpectAtEnd()) goto success;
break;
}
@@ -1361,11 +1401,21 @@ void Field::SerializeWithCachedSizes(
10, this->json_name(), output);
}
+ // optional string default_value = 11;
+ if (this->default_value().size() > 0) {
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+ this->default_value().data(), this->default_value().length(),
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+ "google.protobuf.Field.default_value");
+ ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+ 11, this->default_value(), output);
+ }
+
// @@protoc_insertion_point(serialize_end:google.protobuf.Field)
}
-::google::protobuf::uint8* Field::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* Field::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Field)
// optional .google.protobuf.Field.Kind kind = 1;
if (this->kind() != 0) {
@@ -1419,8 +1469,8 @@ void Field::SerializeWithCachedSizes(
// repeated .google.protobuf.Option options = 9;
for (unsigned int i = 0, n = this->options_size(); i < n; i++) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 9, this->options(i), target);
+ InternalWriteMessageNoVirtualToArray(
+ 9, this->options(i), false, target);
}
// optional string json_name = 10;
@@ -1434,11 +1484,23 @@ void Field::SerializeWithCachedSizes(
10, this->json_name(), target);
}
+ // optional string default_value = 11;
+ if (this->default_value().size() > 0) {
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+ this->default_value().data(), this->default_value().length(),
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+ "google.protobuf.Field.default_value");
+ target =
+ ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+ 11, this->default_value(), target);
+ }
+
// @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Field)
return target;
}
int Field::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Field)
int total_size = 0;
// optional .google.protobuf.Field.Kind kind = 1;
@@ -1493,6 +1555,13 @@ int Field::ByteSize() const {
this->json_name());
}
+ // optional string default_value = 11;
+ if (this->default_value().size() > 0) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::StringSize(
+ this->default_value());
+ }
+
// repeated .google.protobuf.Option options = 9;
total_size += 1 * this->options_size();
for (int i = 0; i < this->options_size(); i++) {
@@ -1508,19 +1577,27 @@ int Field::ByteSize() const {
}
void Field::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Field)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const Field* source =
::google::protobuf::internal::DynamicCastToGenerated<const Field>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.Field)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.Field)
MergeFrom(*source);
}
}
void Field::MergeFrom(const Field& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Field)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
options_.MergeFrom(from.options_);
if (from.kind() != 0) {
set_kind(from.kind());
@@ -1549,15 +1626,21 @@ void Field::MergeFrom(const Field& from) {
json_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.json_name_);
}
+ if (from.default_value().size() > 0) {
+
+ default_value_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.default_value_);
+ }
}
void Field::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.Field)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void Field::CopyFrom(const Field& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Field)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -1582,6 +1665,7 @@ void Field::InternalSwap(Field* other) {
std::swap(packed_, other->packed_);
options_.UnsafeArenaSwap(&other->options_);
json_name_.Swap(&other->json_name_);
+ default_value_.Swap(&other->default_value_);
_internal_metadata_.Swap(&other->_internal_metadata_);
std::swap(_cached_size_, other->_cached_size_);
}
@@ -1669,6 +1753,7 @@ void Field::clear_name() {
return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* Field::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Field.name)
return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -1712,6 +1797,7 @@ void Field::clear_type_url() {
return type_url_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* Field::release_type_url() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Field.type_url)
return type_url_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -1813,6 +1899,7 @@ void Field::clear_json_name() {
return json_name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* Field::release_json_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Field.json_name)
return json_name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -1826,6 +1913,50 @@ void Field::clear_json_name() {
// @@protoc_insertion_point(field_set_allocated:google.protobuf.Field.json_name)
}
+// optional string default_value = 11;
+void Field::clear_default_value() {
+ default_value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ const ::std::string& Field::default_value() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Field.default_value)
+ return default_value_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void Field::set_default_value(const ::std::string& value) {
+
+ default_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+ // @@protoc_insertion_point(field_set:google.protobuf.Field.default_value)
+}
+ void Field::set_default_value(const char* value) {
+
+ default_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+ // @@protoc_insertion_point(field_set_char:google.protobuf.Field.default_value)
+}
+ void Field::set_default_value(const char* value, size_t size) {
+
+ default_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+ ::std::string(reinterpret_cast<const char*>(value), size));
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.Field.default_value)
+}
+ ::std::string* Field::mutable_default_value() {
+
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Field.default_value)
+ return default_value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* Field::release_default_value() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Field.default_value)
+
+ return default_value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void Field::set_allocated_default_value(::std::string* default_value) {
+ if (default_value != NULL) {
+
+ } else {
+
+ }
+ default_value_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), default_value);
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.Field.default_value)
+}
+
#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
// ===================================================================
@@ -1904,6 +2035,7 @@ Enum* Enum::New(::google::protobuf::Arena* arena) const {
}
void Enum::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.Enum)
name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
if (GetArenaNoVirtual() == NULL && source_context_ != NULL) delete source_context_;
source_context_ = NULL;
@@ -1914,7 +2046,7 @@ void Enum::Clear() {
bool Enum::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.Enum)
for (;;) {
@@ -2061,8 +2193,8 @@ void Enum::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.Enum)
}
-::google::protobuf::uint8* Enum::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* Enum::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Enum)
// optional string name = 1;
if (this->name().size() > 0) {
@@ -2078,22 +2210,22 @@ void Enum::SerializeWithCachedSizes(
// repeated .google.protobuf.EnumValue enumvalue = 2;
for (unsigned int i = 0, n = this->enumvalue_size(); i < n; i++) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 2, this->enumvalue(i), target);
+ InternalWriteMessageNoVirtualToArray(
+ 2, this->enumvalue(i), false, target);
}
// repeated .google.protobuf.Option options = 3;
for (unsigned int i = 0, n = this->options_size(); i < n; i++) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 3, this->options(i), target);
+ InternalWriteMessageNoVirtualToArray(
+ 3, this->options(i), false, target);
}
// optional .google.protobuf.SourceContext source_context = 4;
if (this->has_source_context()) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 4, *this->source_context_, target);
+ InternalWriteMessageNoVirtualToArray(
+ 4, *this->source_context_, false, target);
}
// optional .google.protobuf.Syntax syntax = 5;
@@ -2107,6 +2239,7 @@ void Enum::SerializeWithCachedSizes(
}
int Enum::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Enum)
int total_size = 0;
// optional string name = 1;
@@ -2152,19 +2285,27 @@ int Enum::ByteSize() const {
}
void Enum::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Enum)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const Enum* source =
::google::protobuf::internal::DynamicCastToGenerated<const Enum>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.Enum)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.Enum)
MergeFrom(*source);
}
}
void Enum::MergeFrom(const Enum& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Enum)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
enumvalue_.MergeFrom(from.enumvalue_);
options_.MergeFrom(from.options_);
if (from.name().size() > 0) {
@@ -2180,12 +2321,14 @@ void Enum::MergeFrom(const Enum& from) {
}
void Enum::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.Enum)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void Enum::CopyFrom(const Enum& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Enum)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -2251,6 +2394,7 @@ void Enum::clear_name() {
return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* Enum::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Enum.name)
return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -2345,6 +2489,7 @@ const ::google::protobuf::SourceContext& Enum::source_context() const {
return source_context_;
}
::google::protobuf::SourceContext* Enum::release_source_context() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Enum.source_context)
::google::protobuf::SourceContext* temp = source_context_;
source_context_ = NULL;
@@ -2448,6 +2593,7 @@ EnumValue* EnumValue::New(::google::protobuf::Arena* arena) const {
}
void EnumValue::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.EnumValue)
name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
number_ = 0;
options_.Clear();
@@ -2455,7 +2601,7 @@ void EnumValue::Clear() {
bool EnumValue::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.EnumValue)
for (;;) {
@@ -2559,8 +2705,8 @@ void EnumValue::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.EnumValue)
}
-::google::protobuf::uint8* EnumValue::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* EnumValue::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumValue)
// optional string name = 1;
if (this->name().size() > 0) {
@@ -2581,8 +2727,8 @@ void EnumValue::SerializeWithCachedSizes(
// repeated .google.protobuf.Option options = 3;
for (unsigned int i = 0, n = this->options_size(); i < n; i++) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 3, this->options(i), target);
+ InternalWriteMessageNoVirtualToArray(
+ 3, this->options(i), false, target);
}
// @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumValue)
@@ -2590,6 +2736,7 @@ void EnumValue::SerializeWithCachedSizes(
}
int EnumValue::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.EnumValue)
int total_size = 0;
// optional string name = 1;
@@ -2621,19 +2768,27 @@ int EnumValue::ByteSize() const {
}
void EnumValue::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.EnumValue)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const EnumValue* source =
::google::protobuf::internal::DynamicCastToGenerated<const EnumValue>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.EnumValue)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.EnumValue)
MergeFrom(*source);
}
}
void EnumValue::MergeFrom(const EnumValue& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumValue)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
options_.MergeFrom(from.options_);
if (from.name().size() > 0) {
@@ -2645,12 +2800,14 @@ void EnumValue::MergeFrom(const EnumValue& from) {
}
void EnumValue::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.EnumValue)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void EnumValue::CopyFrom(const EnumValue& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.EnumValue)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -2714,6 +2871,7 @@ void EnumValue::clear_name() {
return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* EnumValue::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.EnumValue.name)
return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -2845,6 +3003,7 @@ Option* Option::New(::google::protobuf::Arena* arena) const {
}
void Option::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.Option)
name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
if (GetArenaNoVirtual() == NULL && value_ != NULL) delete value_;
value_ = NULL;
@@ -2852,7 +3011,7 @@ void Option::Clear() {
bool Option::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.Option)
for (;;) {
@@ -2932,8 +3091,8 @@ void Option::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.Option)
}
-::google::protobuf::uint8* Option::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* Option::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Option)
// optional string name = 1;
if (this->name().size() > 0) {
@@ -2949,8 +3108,8 @@ void Option::SerializeWithCachedSizes(
// optional .google.protobuf.Any value = 2;
if (this->has_value()) {
target = ::google::protobuf::internal::WireFormatLite::
- WriteMessageNoVirtualToArray(
- 2, *this->value_, target);
+ InternalWriteMessageNoVirtualToArray(
+ 2, *this->value_, false, target);
}
// @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Option)
@@ -2958,6 +3117,7 @@ void Option::SerializeWithCachedSizes(
}
int Option::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Option)
int total_size = 0;
// optional string name = 1;
@@ -2981,19 +3141,27 @@ int Option::ByteSize() const {
}
void Option::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Option)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const Option* source =
::google::protobuf::internal::DynamicCastToGenerated<const Option>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.Option)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.Option)
MergeFrom(*source);
}
}
void Option::MergeFrom(const Option& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Option)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from.name().size() > 0) {
name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
@@ -3004,12 +3172,14 @@ void Option::MergeFrom(const Option& from) {
}
void Option::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.Option)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void Option::CopyFrom(const Option& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Option)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -3072,6 +3242,7 @@ void Option::clear_name() {
return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
::std::string* Option::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Option.name)
return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -3106,6 +3277,7 @@ const ::google::protobuf::Any& Option::value() const {
return value_;
}
::google::protobuf::Any* Option::release_value() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Option.value)
::google::protobuf::Any* temp = value_;
value_ = NULL;
diff --git a/src/google/protobuf/type.pb.h b/src/google/protobuf/type.pb.h
index 2533eb4e..ce29c281 100644
--- a/src/google/protobuf/type.pb.h
+++ b/src/google/protobuf/type.pb.h
@@ -130,7 +130,7 @@ inline bool Syntax_Parse(
}
// ===================================================================
-class LIBPROTOBUF_EXPORT Type : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT Type : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Type) */ {
public:
Type();
virtual ~Type();
@@ -164,7 +164,11 @@ class LIBPROTOBUF_EXPORT Type : public ::google::protobuf::Message {
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
@@ -273,7 +277,7 @@ class LIBPROTOBUF_EXPORT Type : public ::google::protobuf::Message {
};
// -------------------------------------------------------------------
-class LIBPROTOBUF_EXPORT Field : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT Field : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Field) */ {
public:
Field();
virtual ~Field();
@@ -307,7 +311,11 @@ class LIBPROTOBUF_EXPORT Field : public ::google::protobuf::Message {
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
@@ -328,25 +336,44 @@ class LIBPROTOBUF_EXPORT Field : public ::google::protobuf::Message {
// nested types ----------------------------------------------------
typedef Field_Kind Kind;
- static const Kind TYPE_UNKNOWN = Field_Kind_TYPE_UNKNOWN;
- static const Kind TYPE_DOUBLE = Field_Kind_TYPE_DOUBLE;
- static const Kind TYPE_FLOAT = Field_Kind_TYPE_FLOAT;
- static const Kind TYPE_INT64 = Field_Kind_TYPE_INT64;
- static const Kind TYPE_UINT64 = Field_Kind_TYPE_UINT64;
- static const Kind TYPE_INT32 = Field_Kind_TYPE_INT32;
- static const Kind TYPE_FIXED64 = Field_Kind_TYPE_FIXED64;
- static const Kind TYPE_FIXED32 = Field_Kind_TYPE_FIXED32;
- static const Kind TYPE_BOOL = Field_Kind_TYPE_BOOL;
- static const Kind TYPE_STRING = Field_Kind_TYPE_STRING;
- static const Kind TYPE_GROUP = Field_Kind_TYPE_GROUP;
- static const Kind TYPE_MESSAGE = Field_Kind_TYPE_MESSAGE;
- static const Kind TYPE_BYTES = Field_Kind_TYPE_BYTES;
- static const Kind TYPE_UINT32 = Field_Kind_TYPE_UINT32;
- static const Kind TYPE_ENUM = Field_Kind_TYPE_ENUM;
- static const Kind TYPE_SFIXED32 = Field_Kind_TYPE_SFIXED32;
- static const Kind TYPE_SFIXED64 = Field_Kind_TYPE_SFIXED64;
- static const Kind TYPE_SINT32 = Field_Kind_TYPE_SINT32;
- static const Kind TYPE_SINT64 = Field_Kind_TYPE_SINT64;
+ static const Kind TYPE_UNKNOWN =
+ Field_Kind_TYPE_UNKNOWN;
+ static const Kind TYPE_DOUBLE =
+ Field_Kind_TYPE_DOUBLE;
+ static const Kind TYPE_FLOAT =
+ Field_Kind_TYPE_FLOAT;
+ static const Kind TYPE_INT64 =
+ Field_Kind_TYPE_INT64;
+ static const Kind TYPE_UINT64 =
+ Field_Kind_TYPE_UINT64;
+ static const Kind TYPE_INT32 =
+ Field_Kind_TYPE_INT32;
+ static const Kind TYPE_FIXED64 =
+ Field_Kind_TYPE_FIXED64;
+ static const Kind TYPE_FIXED32 =
+ Field_Kind_TYPE_FIXED32;
+ static const Kind TYPE_BOOL =
+ Field_Kind_TYPE_BOOL;
+ static const Kind TYPE_STRING =
+ Field_Kind_TYPE_STRING;
+ static const Kind TYPE_GROUP =
+ Field_Kind_TYPE_GROUP;
+ static const Kind TYPE_MESSAGE =
+ Field_Kind_TYPE_MESSAGE;
+ static const Kind TYPE_BYTES =
+ Field_Kind_TYPE_BYTES;
+ static const Kind TYPE_UINT32 =
+ Field_Kind_TYPE_UINT32;
+ static const Kind TYPE_ENUM =
+ Field_Kind_TYPE_ENUM;
+ static const Kind TYPE_SFIXED32 =
+ Field_Kind_TYPE_SFIXED32;
+ static const Kind TYPE_SFIXED64 =
+ Field_Kind_TYPE_SFIXED64;
+ static const Kind TYPE_SINT32 =
+ Field_Kind_TYPE_SINT32;
+ static const Kind TYPE_SINT64 =
+ Field_Kind_TYPE_SINT64;
static inline bool Kind_IsValid(int value) {
return Field_Kind_IsValid(value);
}
@@ -369,10 +396,14 @@ class LIBPROTOBUF_EXPORT Field : public ::google::protobuf::Message {
}
typedef Field_Cardinality Cardinality;
- static const Cardinality CARDINALITY_UNKNOWN = Field_Cardinality_CARDINALITY_UNKNOWN;
- static const Cardinality CARDINALITY_OPTIONAL = Field_Cardinality_CARDINALITY_OPTIONAL;
- static const Cardinality CARDINALITY_REQUIRED = Field_Cardinality_CARDINALITY_REQUIRED;
- static const Cardinality CARDINALITY_REPEATED = Field_Cardinality_CARDINALITY_REPEATED;
+ static const Cardinality CARDINALITY_UNKNOWN =
+ Field_Cardinality_CARDINALITY_UNKNOWN;
+ static const Cardinality CARDINALITY_OPTIONAL =
+ Field_Cardinality_CARDINALITY_OPTIONAL;
+ static const Cardinality CARDINALITY_REQUIRED =
+ Field_Cardinality_CARDINALITY_REQUIRED;
+ static const Cardinality CARDINALITY_REPEATED =
+ Field_Cardinality_CARDINALITY_REPEATED;
static inline bool Cardinality_IsValid(int value) {
return Field_Cardinality_IsValid(value);
}
@@ -471,6 +502,17 @@ class LIBPROTOBUF_EXPORT Field : public ::google::protobuf::Message {
::std::string* release_json_name();
void set_allocated_json_name(::std::string* json_name);
+ // optional string default_value = 11;
+ void clear_default_value();
+ static const int kDefaultValueFieldNumber = 11;
+ const ::std::string& default_value() const;
+ void set_default_value(const ::std::string& value);
+ void set_default_value(const char* value);
+ void set_default_value(const char* value, size_t size);
+ ::std::string* mutable_default_value();
+ ::std::string* release_default_value();
+ void set_allocated_default_value(::std::string* default_value);
+
// @@protoc_insertion_point(class_scope:google.protobuf.Field)
private:
@@ -484,6 +526,7 @@ class LIBPROTOBUF_EXPORT Field : public ::google::protobuf::Message {
::google::protobuf::internal::ArenaStringPtr type_url_;
::google::protobuf::RepeatedPtrField< ::google::protobuf::Option > options_;
::google::protobuf::internal::ArenaStringPtr json_name_;
+ ::google::protobuf::internal::ArenaStringPtr default_value_;
bool packed_;
mutable int _cached_size_;
friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto();
@@ -495,7 +538,7 @@ class LIBPROTOBUF_EXPORT Field : public ::google::protobuf::Message {
};
// -------------------------------------------------------------------
-class LIBPROTOBUF_EXPORT Enum : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT Enum : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Enum) */ {
public:
Enum();
virtual ~Enum();
@@ -529,7 +572,11 @@ class LIBPROTOBUF_EXPORT Enum : public ::google::protobuf::Message {
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
@@ -621,7 +668,7 @@ class LIBPROTOBUF_EXPORT Enum : public ::google::protobuf::Message {
};
// -------------------------------------------------------------------
-class LIBPROTOBUF_EXPORT EnumValue : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT EnumValue : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumValue) */ {
public:
EnumValue();
virtual ~EnumValue();
@@ -655,7 +702,11 @@ class LIBPROTOBUF_EXPORT EnumValue : public ::google::protobuf::Message {
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
@@ -724,7 +775,7 @@ class LIBPROTOBUF_EXPORT EnumValue : public ::google::protobuf::Message {
};
// -------------------------------------------------------------------
-class LIBPROTOBUF_EXPORT Option : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT Option : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Option) */ {
public:
Option();
virtual ~Option();
@@ -758,7 +809,11 @@ class LIBPROTOBUF_EXPORT Option : public ::google::protobuf::Message {
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
@@ -853,6 +908,7 @@ inline ::std::string* Type::mutable_name() {
return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* Type::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Type.name)
return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -925,6 +981,7 @@ inline void Type::set_oneofs(int index, const char* value, size_t size) {
// @@protoc_insertion_point(field_set_pointer:google.protobuf.Type.oneofs)
}
inline ::std::string* Type::add_oneofs() {
+ // @@protoc_insertion_point(field_add_mutable:google.protobuf.Type.oneofs)
return oneofs_.Add();
}
inline void Type::add_oneofs(const ::std::string& value) {
@@ -1001,6 +1058,7 @@ inline ::google::protobuf::SourceContext* Type::mutable_source_context() {
return source_context_;
}
inline ::google::protobuf::SourceContext* Type::release_source_context() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Type.source_context)
::google::protobuf::SourceContext* temp = source_context_;
source_context_ = NULL;
@@ -1107,6 +1165,7 @@ inline ::std::string* Field::mutable_name() {
return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* Field::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Field.name)
return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -1150,6 +1209,7 @@ inline ::std::string* Field::mutable_type_url() {
return type_url_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* Field::release_type_url() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Field.type_url)
return type_url_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -1251,6 +1311,7 @@ inline ::std::string* Field::mutable_json_name() {
return json_name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* Field::release_json_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Field.json_name)
return json_name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -1264,6 +1325,50 @@ inline void Field::set_allocated_json_name(::std::string* json_name) {
// @@protoc_insertion_point(field_set_allocated:google.protobuf.Field.json_name)
}
+// optional string default_value = 11;
+inline void Field::clear_default_value() {
+ default_value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& Field::default_value() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Field.default_value)
+ return default_value_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void Field::set_default_value(const ::std::string& value) {
+
+ default_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+ // @@protoc_insertion_point(field_set:google.protobuf.Field.default_value)
+}
+inline void Field::set_default_value(const char* value) {
+
+ default_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+ // @@protoc_insertion_point(field_set_char:google.protobuf.Field.default_value)
+}
+inline void Field::set_default_value(const char* value, size_t size) {
+
+ default_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+ ::std::string(reinterpret_cast<const char*>(value), size));
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.Field.default_value)
+}
+inline ::std::string* Field::mutable_default_value() {
+
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Field.default_value)
+ return default_value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* Field::release_default_value() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Field.default_value)
+
+ return default_value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void Field::set_allocated_default_value(::std::string* default_value) {
+ if (default_value != NULL) {
+
+ } else {
+
+ }
+ default_value_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), default_value);
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.Field.default_value)
+}
+
// -------------------------------------------------------------------
// Enum
@@ -1298,6 +1403,7 @@ inline ::std::string* Enum::mutable_name() {
return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* Enum::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Enum.name)
return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -1392,6 +1498,7 @@ inline ::google::protobuf::SourceContext* Enum::mutable_source_context() {
return source_context_;
}
inline ::google::protobuf::SourceContext* Enum::release_source_context() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Enum.source_context)
::google::protobuf::SourceContext* temp = source_context_;
source_context_ = NULL;
@@ -1456,6 +1563,7 @@ inline ::std::string* EnumValue::mutable_name() {
return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* EnumValue::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.EnumValue.name)
return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -1547,6 +1655,7 @@ inline ::std::string* Option::mutable_name() {
return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* Option::release_name() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Option.name)
return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
@@ -1581,6 +1690,7 @@ inline ::google::protobuf::Any* Option::mutable_value() {
return value_;
}
inline ::google::protobuf::Any* Option::release_value() {
+ // @@protoc_insertion_point(field_release:google.protobuf.Option.value)
::google::protobuf::Any* temp = value_;
value_ = NULL;
diff --git a/src/google/protobuf/type.proto b/src/google/protobuf/type.proto
index 4df95762..1c9cf53d 100644
--- a/src/google/protobuf/type.proto
+++ b/src/google/protobuf/type.proto
@@ -27,6 +27,7 @@
// 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.
+
syntax = "proto3";
package google.protobuf;
@@ -34,22 +35,22 @@ package google.protobuf;
import "google/protobuf/any.proto";
import "google/protobuf/source_context.proto";
+option csharp_namespace = "Google.Protobuf.WellKnownTypes";
option java_package = "com.google.protobuf";
option java_outer_classname = "TypeProto";
option java_multiple_files = true;
option java_generate_equals_and_hash = true;
-option csharp_namespace = "Google.Protobuf.WellKnownTypes";
option objc_class_prefix = "GPB";
-// A light-weight descriptor for a proto message type.
+// A protocol buffer message type.
message Type {
// The fully qualified message name.
string name = 1;
// The list of fields.
repeated Field fields = 2;
- // The list of oneof definitions.
- repeated string oneofs = 3; // The list of oneofs declared in this Type
- // The proto options.
+ // The list of types appearing in `oneof` definitions in this type.
+ repeated string oneofs = 3;
+ // The protocol buffer options.
repeated Option options = 4;
// The source context.
SourceContext source_context = 5;
@@ -57,9 +58,9 @@ message Type {
Syntax syntax = 6;
}
-// Field represents a single field of a message type.
+// A single field of a message type.
message Field {
- // Kind represents a basic field type.
+ // Basic field types.
enum Kind {
// Field type unknown.
TYPE_UNKNOWN = 0;
@@ -81,7 +82,7 @@ message Field {
TYPE_BOOL = 8;
// Field type string.
TYPE_STRING = 9;
- // Field type group (deprecated proto2 type)
+ // Field type group. Proto2 syntax only, and deprecated.
TYPE_GROUP = 10;
// Field type message.
TYPE_MESSAGE = 11;
@@ -101,38 +102,40 @@ message Field {
TYPE_SINT64 = 18;
};
- // Cardinality represents whether a field is optional, required, or
- // repeated.
+ // Whether a field is optional, required, or repeated.
enum Cardinality {
- // The field cardinality is unknown. Typically an error condition.
+ // For fields with unknown cardinality.
CARDINALITY_UNKNOWN = 0;
// For optional fields.
CARDINALITY_OPTIONAL = 1;
- // For required fields. Not used for proto3.
+ // For required fields. Proto2 syntax only.
CARDINALITY_REQUIRED = 2;
// For repeated fields.
CARDINALITY_REPEATED = 3;
};
- // The field kind.
+ // The field type.
Kind kind = 1;
- // The field cardinality, i.e. optional/required/repeated.
+ // The field cardinality.
Cardinality cardinality = 2;
- // The proto field number.
+ // The field number.
int32 number = 3;
// The field name.
string name = 4;
- // The type URL (without the scheme) when the type is MESSAGE or ENUM,
- // such as `type.googleapis.com/google.protobuf.Empty`.
+ // The field type URL, without the scheme, for message or enumeration
+ // types. Example: `"type.googleapis.com/google.protobuf.Timestamp"`.
string type_url = 6;
- // Index in Type.oneofs. Starts at 1. Zero means no oneof mapping.
+ // The index of the field type in `Type.oneofs`, for message or enumeration
+ // types. The first type has index 1; zero means the type is not in the list.
int32 oneof_index = 7;
// Whether to use alternative packed wire representation.
bool packed = 8;
- // The proto options.
+ // The protocol buffer options.
repeated Option options = 9;
- // The JSON name for this field.
+ // The field JSON name.
string json_name = 10;
+ // The string value of the default value of this field. Proto2 syntax only.
+ string default_value = 11;
}
// Enum type definition.
@@ -141,7 +144,7 @@ message Enum {
string name = 1;
// Enum value definitions.
repeated EnumValue enumvalue = 2;
- // Proto options for the enum type.
+ // Protocol buffer options.
repeated Option options = 3;
// The source context.
SourceContext source_context = 4;
@@ -155,22 +158,23 @@ message EnumValue {
string name = 1;
// Enum value number.
int32 number = 2;
- // Proto options for the enum value.
+ // Protocol buffer options.
repeated Option options = 3;
}
-// Proto option attached to messages/fields/enums etc.
+// A protocol buffer option, which can be attached to a message, field,
+// enumeration, etc.
message Option {
- // Proto option name.
+ // The option's name. For example, `"java_package"`.
string name = 1;
- // Proto option value.
+ // The option's value. For example, `"com.google.protobuf"`.
Any value = 2;
}
-// Syntax specifies the syntax in which a service element was defined.
+// The syntax in which a protocol buffer element is defined.
enum Syntax {
- // Syntax "proto2"
+ // Syntax `proto2`.
SYNTAX_PROTO2 = 0;
- // Syntax "proto3"
+ // Syntax `proto3`.
SYNTAX_PROTO3 = 1;
}
diff --git a/src/google/protobuf/unittest.proto b/src/google/protobuf/unittest.proto
index 85fe6153..d5206d24 100644
--- a/src/google/protobuf/unittest.proto
+++ b/src/google/protobuf/unittest.proto
@@ -195,6 +195,7 @@ message TestDeprecatedFields {
// that.
message ForeignMessage {
optional int32 c = 1;
+ optional int32 d = 2;
}
enum ForeignEnum {
@@ -696,6 +697,7 @@ message TestRequiredOneof {
}
}
+
// Test messages for packed fields
message TestPackedTypes {
diff --git a/src/google/protobuf/unittest_custom_options.proto b/src/google/protobuf/unittest_custom_options.proto
index d4d6e869..218447e9 100644
--- a/src/google/protobuf/unittest_custom_options.proto
+++ b/src/google/protobuf/unittest_custom_options.proto
@@ -69,6 +69,10 @@ extend google.protobuf.FieldOptions {
optional int32 field_opt2 = 7753913 [default=42];
}
+extend google.protobuf.OneofOptions {
+ optional int32 oneof_opt1 = 7740111;
+}
+
extend google.protobuf.EnumOptions {
optional sfixed32 enum_opt1 = 7753576;
}
@@ -100,6 +104,11 @@ message TestMessageWithCustomOptions {
optional string field1 = 1 [ctype=CORD,
(field_opt1)=8765432109];
+ oneof AnOneof {
+ option (oneof_opt1) = -99;
+ int32 oneof_field = 2;
+ }
+
enum AnEnum {
option (enum_opt1) = -789;
@@ -392,3 +401,30 @@ message NestedOptionType {
optional int32 nested_extension = 7912573 [(field_opt2) = 1005];
}
}
+
+// Custom message option that has a required enum field.
+// WARNING: this is strongly discouraged!
+message OldOptionType {
+ enum TestEnum {
+ OLD_VALUE = 0;
+ }
+ required TestEnum value = 1;
+}
+
+// Updated version of the custom option above.
+message NewOptionType {
+ enum TestEnum {
+ OLD_VALUE = 0;
+ NEW_VALUE = 1;
+ }
+ required TestEnum value = 1;
+}
+
+extend google.protobuf.MessageOptions {
+ optional OldOptionType required_enum_opt = 106161807;
+}
+
+// Test message using the "required_enum_opt" option defined above.
+message TestMessageWithRequiredEnumOption {
+ option (required_enum_opt) = { value: OLD_VALUE };
+}
diff --git a/src/google/protobuf/unittest_lite.proto b/src/google/protobuf/unittest_lite.proto
index 662c0e46..878ec7c1 100644
--- a/src/google/protobuf/unittest_lite.proto
+++ b/src/google/protobuf/unittest_lite.proto
@@ -43,8 +43,10 @@ option java_package = "com.google.protobuf";
// Same as TestAllTypes but with the lite runtime.
message TestAllTypesLite {
+
message NestedMessage {
optional int32 bb = 1;
+ optional int64 cc = 2;
}
enum NestedEnum {
@@ -159,6 +161,7 @@ message TestAllTypesLite {
NestedMessage oneof_nested_message = 112;
string oneof_string = 113;
bytes oneof_bytes = 114;
+ NestedMessage oneof_lazy_nested_message = 115 [lazy = true];
}
}
@@ -383,3 +386,22 @@ message TestEmptyMessageLite{
message TestEmptyMessageWithExtensionsLite {
extensions 1 to max;
}
+
+enum V1EnumLite {
+ V1_FIRST = 1;
+}
+
+enum V2EnumLite {
+ V2_FIRST = 1;
+ V2_SECOND = 2;
+}
+
+message V1MessageLite {
+ required int32 int_field = 1;
+ optional V1EnumLite enum_field = 2 [ default = V1_FIRST ];
+}
+
+message V2MessageLite {
+ required int32 int_field = 1;
+ optional V2EnumLite enum_field = 2 [ default = V2_FIRST ];
+}
diff --git a/src/google/protobuf/unittest_proto3_arena_lite.proto b/src/google/protobuf/unittest_proto3_arena_lite.proto
new file mode 100644
index 00000000..5a60b90f
--- /dev/null
+++ b/src/google/protobuf/unittest_proto3_arena_lite.proto
@@ -0,0 +1,207 @@
+// 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.
+
+syntax = "proto3";
+
+option cc_enable_arenas = true;
+option optimize_for = LITE_RUNTIME;
+
+import "google/protobuf/unittest_import.proto";
+
+package proto3_arena_lite_unittest;
+
+// This proto includes every type of field in both singular and repeated
+// forms.
+message TestAllTypes {
+ message NestedMessage {
+ // The field name "b" fails to compile in proto1 because it conflicts with
+ // a local variable named "b" in one of the generated methods. Doh.
+ // This file needs to compile in proto1 to test backwards-compatibility.
+ int32 bb = 1;
+ }
+
+ enum NestedEnum {
+ ZERO = 0;
+ FOO = 1;
+ BAR = 2;
+ BAZ = 3;
+ NEG = -1; // Intentionally negative.
+ }
+
+ // Singular
+ int32 optional_int32 = 1;
+ int64 optional_int64 = 2;
+ uint32 optional_uint32 = 3;
+ uint64 optional_uint64 = 4;
+ sint32 optional_sint32 = 5;
+ sint64 optional_sint64 = 6;
+ fixed32 optional_fixed32 = 7;
+ fixed64 optional_fixed64 = 8;
+ sfixed32 optional_sfixed32 = 9;
+ sfixed64 optional_sfixed64 = 10;
+ float optional_float = 11;
+ double optional_double = 12;
+ bool optional_bool = 13;
+ string optional_string = 14;
+ bytes optional_bytes = 15;
+
+ // Groups are not allowed in proto3.
+ // optional group OptionalGroup = 16 {
+ // optional int32 a = 17;
+ // }
+
+ NestedMessage optional_nested_message = 18;
+ ForeignMessage optional_foreign_message = 19;
+ protobuf_unittest_import.ImportMessage optional_import_message = 20;
+
+ NestedEnum optional_nested_enum = 21;
+ ForeignEnum optional_foreign_enum = 22;
+
+ // Omitted (compared to unittest.proto) because proto2 enums are not allowed
+ // inside proto2 messages.
+ //
+ // optional protobuf_unittest_import.ImportEnum optional_import_enum = 23;
+
+ string optional_string_piece = 24 [ctype=STRING_PIECE];
+ string optional_cord = 25 [ctype=CORD];
+
+ // Defined in unittest_import_public.proto
+ protobuf_unittest_import.PublicImportMessage
+ optional_public_import_message = 26;
+
+ NestedMessage optional_lazy_message = 27 [lazy=true];
+
+ // Repeated
+ repeated int32 repeated_int32 = 31;
+ repeated int64 repeated_int64 = 32;
+ repeated uint32 repeated_uint32 = 33;
+ repeated uint64 repeated_uint64 = 34;
+ repeated sint32 repeated_sint32 = 35;
+ repeated sint64 repeated_sint64 = 36;
+ repeated fixed32 repeated_fixed32 = 37;
+ repeated fixed64 repeated_fixed64 = 38;
+ repeated sfixed32 repeated_sfixed32 = 39;
+ repeated sfixed64 repeated_sfixed64 = 40;
+ repeated float repeated_float = 41;
+ repeated double repeated_double = 42;
+ repeated bool repeated_bool = 43;
+ repeated string repeated_string = 44;
+ repeated bytes repeated_bytes = 45;
+
+ // Groups are not allowed in proto3.
+ // repeated group RepeatedGroup = 46 {
+ // optional int32 a = 47;
+ // }
+
+ repeated NestedMessage repeated_nested_message = 48;
+ repeated ForeignMessage repeated_foreign_message = 49;
+ repeated protobuf_unittest_import.ImportMessage repeated_import_message = 50;
+
+ repeated NestedEnum repeated_nested_enum = 51;
+ repeated ForeignEnum repeated_foreign_enum = 52;
+
+ // Omitted (compared to unittest.proto) because proto2 enums are not allowed
+ // inside proto2 messages.
+ //
+ // repeated protobuf_unittest_import.ImportEnum repeated_import_enum = 53;
+
+ repeated string repeated_string_piece = 54 [ctype=STRING_PIECE];
+ repeated string repeated_cord = 55 [ctype=CORD];
+
+ repeated NestedMessage repeated_lazy_message = 57 [lazy=true];
+
+ oneof oneof_field {
+ uint32 oneof_uint32 = 111;
+ NestedMessage oneof_nested_message = 112;
+ string oneof_string = 113;
+ bytes oneof_bytes = 114;
+ }
+}
+
+// Test messages for packed fields
+
+message TestPackedTypes {
+ repeated int32 packed_int32 = 90 [packed = true];
+ repeated int64 packed_int64 = 91 [packed = true];
+ repeated uint32 packed_uint32 = 92 [packed = true];
+ repeated uint64 packed_uint64 = 93 [packed = true];
+ repeated sint32 packed_sint32 = 94 [packed = true];
+ repeated sint64 packed_sint64 = 95 [packed = true];
+ repeated fixed32 packed_fixed32 = 96 [packed = true];
+ repeated fixed64 packed_fixed64 = 97 [packed = true];
+ repeated sfixed32 packed_sfixed32 = 98 [packed = true];
+ repeated sfixed64 packed_sfixed64 = 99 [packed = true];
+ repeated float packed_float = 100 [packed = true];
+ repeated double packed_double = 101 [packed = true];
+ repeated bool packed_bool = 102 [packed = true];
+ repeated ForeignEnum packed_enum = 103 [packed = true];
+}
+
+// Explicitly set packed to false
+message TestUnpackedTypes {
+ repeated int32 repeated_int32 = 1 [packed = false];
+ repeated int64 repeated_int64 = 2 [packed = false];
+ repeated uint32 repeated_uint32 = 3 [packed = false];
+ repeated uint64 repeated_uint64 = 4 [packed = false];
+ repeated sint32 repeated_sint32 = 5 [packed = false];
+ repeated sint64 repeated_sint64 = 6 [packed = false];
+ repeated fixed32 repeated_fixed32 = 7 [packed = false];
+ repeated fixed64 repeated_fixed64 = 8 [packed = false];
+ repeated sfixed32 repeated_sfixed32 = 9 [packed = false];
+ repeated sfixed64 repeated_sfixed64 = 10 [packed = false];
+ repeated float repeated_float = 11 [packed = false];
+ repeated double repeated_double = 12 [packed = false];
+ repeated bool repeated_bool = 13 [packed = false];
+ repeated TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false];
+}
+
+// This proto includes a recusively nested message.
+message NestedTestAllTypes {
+ NestedTestAllTypes child = 1;
+ TestAllTypes payload = 2;
+}
+
+// Define these after TestAllTypes to make sure the compiler can handle
+// that.
+message ForeignMessage {
+ int32 c = 1;
+}
+
+enum ForeignEnum {
+ FOREIGN_ZERO = 0;
+ FOREIGN_FOO = 4;
+ FOREIGN_BAR = 5;
+ FOREIGN_BAZ = 6;
+}
+
+// TestEmptyMessage is used to test behavior of unknown fields.
+message TestEmptyMessage {
+}
+
diff --git a/src/google/protobuf/unittest_proto3_lite.proto b/src/google/protobuf/unittest_proto3_lite.proto
new file mode 100644
index 00000000..874ade6c
--- /dev/null
+++ b/src/google/protobuf/unittest_proto3_lite.proto
@@ -0,0 +1,206 @@
+// 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.
+
+syntax = "proto3";
+
+option optimize_for = LITE_RUNTIME;
+
+import "google/protobuf/unittest_import.proto";
+
+package proto3_lite_unittest;
+
+// This proto includes every type of field in both singular and repeated
+// forms.
+message TestAllTypes {
+ message NestedMessage {
+ // The field name "b" fails to compile in proto1 because it conflicts with
+ // a local variable named "b" in one of the generated methods. Doh.
+ // This file needs to compile in proto1 to test backwards-compatibility.
+ int32 bb = 1;
+ }
+
+ enum NestedEnum {
+ ZERO = 0;
+ FOO = 1;
+ BAR = 2;
+ BAZ = 3;
+ NEG = -1; // Intentionally negative.
+ }
+
+ // Singular
+ int32 optional_int32 = 1;
+ int64 optional_int64 = 2;
+ uint32 optional_uint32 = 3;
+ uint64 optional_uint64 = 4;
+ sint32 optional_sint32 = 5;
+ sint64 optional_sint64 = 6;
+ fixed32 optional_fixed32 = 7;
+ fixed64 optional_fixed64 = 8;
+ sfixed32 optional_sfixed32 = 9;
+ sfixed64 optional_sfixed64 = 10;
+ float optional_float = 11;
+ double optional_double = 12;
+ bool optional_bool = 13;
+ string optional_string = 14;
+ bytes optional_bytes = 15;
+
+ // Groups are not allowed in proto3.
+ // optional group OptionalGroup = 16 {
+ // optional int32 a = 17;
+ // }
+
+ NestedMessage optional_nested_message = 18;
+ ForeignMessage optional_foreign_message = 19;
+ protobuf_unittest_import.ImportMessage optional_import_message = 20;
+
+ NestedEnum optional_nested_enum = 21;
+ ForeignEnum optional_foreign_enum = 22;
+
+ // Omitted (compared to unittest.proto) because proto2 enums are not allowed
+ // inside proto2 messages.
+ //
+ // optional protobuf_unittest_import.ImportEnum optional_import_enum = 23;
+
+ string optional_string_piece = 24 [ctype=STRING_PIECE];
+ string optional_cord = 25 [ctype=CORD];
+
+ // Defined in unittest_import_public.proto
+ protobuf_unittest_import.PublicImportMessage
+ optional_public_import_message = 26;
+
+ NestedMessage optional_lazy_message = 27 [lazy=true];
+
+ // Repeated
+ repeated int32 repeated_int32 = 31;
+ repeated int64 repeated_int64 = 32;
+ repeated uint32 repeated_uint32 = 33;
+ repeated uint64 repeated_uint64 = 34;
+ repeated sint32 repeated_sint32 = 35;
+ repeated sint64 repeated_sint64 = 36;
+ repeated fixed32 repeated_fixed32 = 37;
+ repeated fixed64 repeated_fixed64 = 38;
+ repeated sfixed32 repeated_sfixed32 = 39;
+ repeated sfixed64 repeated_sfixed64 = 40;
+ repeated float repeated_float = 41;
+ repeated double repeated_double = 42;
+ repeated bool repeated_bool = 43;
+ repeated string repeated_string = 44;
+ repeated bytes repeated_bytes = 45;
+
+ // Groups are not allowed in proto3.
+ // repeated group RepeatedGroup = 46 {
+ // optional int32 a = 47;
+ // }
+
+ repeated NestedMessage repeated_nested_message = 48;
+ repeated ForeignMessage repeated_foreign_message = 49;
+ repeated protobuf_unittest_import.ImportMessage repeated_import_message = 50;
+
+ repeated NestedEnum repeated_nested_enum = 51;
+ repeated ForeignEnum repeated_foreign_enum = 52;
+
+ // Omitted (compared to unittest.proto) because proto2 enums are not allowed
+ // inside proto2 messages.
+ //
+ // repeated protobuf_unittest_import.ImportEnum repeated_import_enum = 53;
+
+ repeated string repeated_string_piece = 54 [ctype=STRING_PIECE];
+ repeated string repeated_cord = 55 [ctype=CORD];
+
+ repeated NestedMessage repeated_lazy_message = 57 [lazy=true];
+
+ oneof oneof_field {
+ uint32 oneof_uint32 = 111;
+ NestedMessage oneof_nested_message = 112;
+ string oneof_string = 113;
+ bytes oneof_bytes = 114;
+ }
+}
+
+// Test messages for packed fields
+
+message TestPackedTypes {
+ repeated int32 packed_int32 = 90 [packed = true];
+ repeated int64 packed_int64 = 91 [packed = true];
+ repeated uint32 packed_uint32 = 92 [packed = true];
+ repeated uint64 packed_uint64 = 93 [packed = true];
+ repeated sint32 packed_sint32 = 94 [packed = true];
+ repeated sint64 packed_sint64 = 95 [packed = true];
+ repeated fixed32 packed_fixed32 = 96 [packed = true];
+ repeated fixed64 packed_fixed64 = 97 [packed = true];
+ repeated sfixed32 packed_sfixed32 = 98 [packed = true];
+ repeated sfixed64 packed_sfixed64 = 99 [packed = true];
+ repeated float packed_float = 100 [packed = true];
+ repeated double packed_double = 101 [packed = true];
+ repeated bool packed_bool = 102 [packed = true];
+ repeated ForeignEnum packed_enum = 103 [packed = true];
+}
+
+// Explicitly set packed to false
+message TestUnpackedTypes {
+ repeated int32 repeated_int32 = 1 [packed = false];
+ repeated int64 repeated_int64 = 2 [packed = false];
+ repeated uint32 repeated_uint32 = 3 [packed = false];
+ repeated uint64 repeated_uint64 = 4 [packed = false];
+ repeated sint32 repeated_sint32 = 5 [packed = false];
+ repeated sint64 repeated_sint64 = 6 [packed = false];
+ repeated fixed32 repeated_fixed32 = 7 [packed = false];
+ repeated fixed64 repeated_fixed64 = 8 [packed = false];
+ repeated sfixed32 repeated_sfixed32 = 9 [packed = false];
+ repeated sfixed64 repeated_sfixed64 = 10 [packed = false];
+ repeated float repeated_float = 11 [packed = false];
+ repeated double repeated_double = 12 [packed = false];
+ repeated bool repeated_bool = 13 [packed = false];
+ repeated TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false];
+}
+
+// This proto includes a recusively nested message.
+message NestedTestAllTypes {
+ NestedTestAllTypes child = 1;
+ TestAllTypes payload = 2;
+}
+
+// Define these after TestAllTypes to make sure the compiler can handle
+// that.
+message ForeignMessage {
+ int32 c = 1;
+}
+
+enum ForeignEnum {
+ FOREIGN_ZERO = 0;
+ FOREIGN_FOO = 4;
+ FOREIGN_BAR = 5;
+ FOREIGN_BAZ = 6;
+}
+
+// TestEmptyMessage is used to test behavior of unknown fields.
+message TestEmptyMessage {
+}
+
diff --git a/src/google/protobuf/unittest_well_known_types.proto b/src/google/protobuf/unittest_well_known_types.proto
index 2cb7775c..c9075244 100644
--- a/src/google/protobuf/unittest_well_known_types.proto
+++ b/src/google/protobuf/unittest_well_known_types.proto
@@ -39,6 +39,8 @@ message TestWellKnownTypes {
google.protobuf.BoolValue bool_field = 16;
google.protobuf.StringValue string_field = 17;
google.protobuf.BytesValue bytes_field = 18;
+ // Part of struct, but useful to be able to test separately
+ google.protobuf.Value value_field = 19;
}
// A repeated field for each well-known type.
diff --git a/src/google/protobuf/unknown_field_set.cc b/src/google/protobuf/unknown_field_set.cc
index d4e383da..8ee99d48 100644
--- a/src/google/protobuf/unknown_field_set.cc
+++ b/src/google/protobuf/unknown_field_set.cc
@@ -69,28 +69,14 @@ const UnknownFieldSet* UnknownFieldSet::default_instance() {
return default_unknown_field_set_instance_;
}
-UnknownFieldSet::UnknownFieldSet()
- : fields_(NULL) {}
-
-UnknownFieldSet::~UnknownFieldSet() {
- Clear();
- delete fields_;
-}
-
void UnknownFieldSet::ClearFallback() {
- if (fields_ != NULL) {
- for (int i = 0; i < fields_->size(); i++) {
- (*fields_)[i].Delete();
- }
- delete fields_;
- fields_ = NULL;
- }
-}
-
-void UnknownFieldSet::ClearAndFreeMemory() {
- if (fields_ != NULL) {
- Clear();
- }
+ GOOGLE_DCHECK(fields_ != NULL && fields_->size() > 0);
+ int n = fields_->size();
+ do {
+ (*fields_)[--n].Delete();
+ } while (n > 0);
+ delete fields_;
+ fields_ = NULL;
}
void UnknownFieldSet::InternalMergeFrom(const UnknownFieldSet& other) {
diff --git a/src/google/protobuf/unknown_field_set.h b/src/google/protobuf/unknown_field_set.h
index 612a942a..aa752916 100644
--- a/src/google/protobuf/unknown_field_set.h
+++ b/src/google/protobuf/unknown_field_set.h
@@ -241,8 +241,14 @@ class LIBPROTOBUF_EXPORT UnknownField {
// ===================================================================
// inline implementations
+inline UnknownFieldSet::UnknownFieldSet() : fields_(NULL) {}
+
+inline UnknownFieldSet::~UnknownFieldSet() { Clear(); }
+
+inline void UnknownFieldSet::ClearAndFreeMemory() { Clear(); }
+
inline void UnknownFieldSet::Clear() {
- if (fields_) {
+ if (fields_ != NULL) {
ClearFallback();
}
}
diff --git a/src/google/protobuf/util/field_comparator.cc b/src/google/protobuf/util/field_comparator.cc
index 9f613265..a1a56ee6 100644
--- a/src/google/protobuf/util/field_comparator.cc
+++ b/src/google/protobuf/util/field_comparator.cc
@@ -92,7 +92,27 @@ FieldComparator::ComparisonResult DefaultFieldComparator::Compare(
case FieldDescriptor::CPPTYPE_INT64:
COMPARE_FIELD(Int64);
case FieldDescriptor::CPPTYPE_STRING:
- COMPARE_FIELD(String);
+ if (field->is_repeated()) {
+ // Allocate scratch strings to store the result if a conversion is
+ // needed.
+ string scratch1;
+ string scratch2;
+ return ResultFromBoolean(
+ CompareString(*field, reflection_1->GetRepeatedStringReference(
+ message_1, field, index_1, &scratch1),
+ reflection_2->GetRepeatedStringReference(
+ message_2, field, index_2, &scratch2)));
+ } else {
+ // Allocate scratch strings to store the result if a conversion is
+ // needed.
+ string scratch1;
+ string scratch2;
+ return ResultFromBoolean(CompareString(
+ *field,
+ reflection_1->GetStringReference(message_1, field, &scratch1),
+ reflection_2->GetStringReference(message_2, field, &scratch2)));
+ }
+ break;
case FieldDescriptor::CPPTYPE_UINT32:
COMPARE_FIELD(UInt32);
case FieldDescriptor::CPPTYPE_UINT64:
@@ -169,7 +189,7 @@ bool DefaultFieldComparator::CompareDoubleOrFloat(const FieldDescriptor& field,
return MathUtil::AlmostEquals(value_1, value_2);
} else {
// Use user-provided fraction and margin. Since they are stored as
- // doubles, we explicitely cast them to types of values provided. This
+ // doubles, we explicitly cast them to types of values provided. This
// is very likely to fail if provided values are not numeric.
return MathUtil::WithinFractionOrMargin(
value_1, value_2, static_cast<T>(tolerance->fraction),
diff --git a/src/google/protobuf/util/field_comparator.h b/src/google/protobuf/util/field_comparator.h
index ee676265..1b4d65b0 100644
--- a/src/google/protobuf/util/field_comparator.h
+++ b/src/google/protobuf/util/field_comparator.h
@@ -91,9 +91,9 @@ class LIBPROTOBUF_EXPORT FieldComparator {
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldComparator);
};
-// Basic implementation of FieldComparator. Supports four modes of floating
+// Basic implementation of FieldComparator. Supports three modes of floating
// point value comparison: exact, approximate using MathUtil::AlmostEqual
-// method, and arbitrarilly precise using MathUtil::WithinFracionOrMargin.
+// method, and arbitrarily precise using MathUtil::WithinFractionOrMargin.
class LIBPROTOBUF_EXPORT DefaultFieldComparator : public FieldComparator {
public:
enum FloatComparison {
diff --git a/src/google/protobuf/util/field_comparator_test.cc b/src/google/protobuf/util/field_comparator_test.cc
index d3d34602..6fd631d8 100644
--- a/src/google/protobuf/util/field_comparator_test.cc
+++ b/src/google/protobuf/util/field_comparator_test.cc
@@ -35,9 +35,13 @@
#include <google/protobuf/unittest.pb.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/stubs/mathutil.h>
-
+// This gtest header is put after mathutil.h intentionally. We have to do
+// this because mathutil.h includes mathlimits.h which requires cmath not
+// being included to compile on some versions of gcc:
+// https://github.com/google/protobuf/blob/818c5eee08840355d70d2f3bdf1a2f17986a5e70/src/google/protobuf/stubs/mathlimits.h#L48
+// and the opensource version gtest.h header includes cmath transitively
+// somehow.
#include <gtest/gtest.h>
-
namespace google {
namespace protobuf {
namespace util {
diff --git a/src/google/protobuf/util/field_mask_util.cc b/src/google/protobuf/util/field_mask_util.cc
index 29ca9c1e..409010a0 100644
--- a/src/google/protobuf/util/field_mask_util.cc
+++ b/src/google/protobuf/util/field_mask_util.cc
@@ -52,6 +52,82 @@ void FieldMaskUtil::FromString(StringPiece str, FieldMask* out) {
}
}
+bool FieldMaskUtil::SnakeCaseToCamelCase(StringPiece input, string* output) {
+ output->clear();
+ bool after_underscore = false;
+ for (int i = 0; i < input.size(); ++i) {
+ if (input[i] >= 'A' && input[i] <= 'Z') {
+ // The field name must not contain uppercase letters.
+ return false;
+ }
+ if (after_underscore) {
+ if (input[i] >= 'a' && input[i] <= 'z') {
+ output->push_back(input[i] + 'A' - 'a');
+ after_underscore = false;
+ } else {
+ // The character after a "_" must be a lowercase letter.
+ return false;
+ }
+ } else if (input[i] == '_') {
+ after_underscore = true;
+ } else {
+ output->push_back(input[i]);
+ }
+ }
+ if (after_underscore) {
+ // Trailing "_".
+ return false;
+ }
+ return true;
+}
+
+bool FieldMaskUtil::CamelCaseToSnakeCase(StringPiece input, string* output) {
+ output->clear();
+ for (int i = 0; i < input.size(); ++i) {
+ if (input[i] == '_') {
+ // The field name must not contain "_"s.
+ return false;
+ }
+ if (input[i] >= 'A' && input[i] <= 'Z') {
+ output->push_back('_');
+ output->push_back(input[i] + 'a' - 'A');
+ } else {
+ output->push_back(input[i]);
+ }
+ }
+ return true;
+}
+
+bool FieldMaskUtil::ToJsonString(const FieldMask& mask, string* out) {
+ out->clear();
+ for (int i = 0; i < mask.paths_size(); ++i) {
+ const string& path = mask.paths(i);
+ string camelcase_path;
+ if (!SnakeCaseToCamelCase(path, &camelcase_path)) {
+ return false;
+ }
+ if (i > 0) {
+ out->push_back(',');
+ }
+ out->append(camelcase_path);
+ }
+ return true;
+}
+
+bool FieldMaskUtil::FromJsonString(StringPiece str, FieldMask* out) {
+ out->Clear();
+ vector<string> paths = Split(str, ",");
+ for (int i = 0; i < paths.size(); ++i) {
+ if (paths[i].empty()) continue;
+ string snakecase_path;
+ if (!CamelCaseToSnakeCase(paths[i], &snakecase_path)) {
+ return false;
+ }
+ out->add_paths(snakecase_path);
+ }
+ return true;
+}
+
bool FieldMaskUtil::InternalIsValidPath(const Descriptor* descriptor,
StringPiece path) {
vector<string> parts = Split(path, ".");
@@ -103,7 +179,7 @@ class FieldMaskTree {
// Add a field path into the tree. In a FieldMask, each field path matches
// the specified field and also all its sub-fields. If the field path to
// add is a sub-path of an existing field path in the tree (i.e., a leaf
- // node), it means the tree already matchesthe the given path so nothing will
+ // node), it means the tree already matches the given path so nothing will
// be added to the tree. If the path matches an existing non-leaf node in the
// tree, that non-leaf node will be turned into a leaf node with all its
// children removed because the path matches all the node's children.
@@ -124,6 +200,15 @@ class FieldMaskTree {
MergeMessage(&root_, source, options, destination);
}
+ // Trims all fields not specified by this tree from the given message.
+ void TrimMessage(Message* message) {
+ // Do nothing if the tree is empty.
+ if (root_.children.empty()) {
+ return;
+ }
+ TrimMessage(&root_, message);
+ }
+
private:
struct Node {
Node() {}
@@ -157,6 +242,9 @@ class FieldMaskTree {
const FieldMaskUtil::MergeOptions& options,
Message* destination);
+ // Trims all fields not specified by this sub-tree from the given message.
+ void TrimMessage(const Node* node, Message* message);
+
Node root_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldMaskTree);
@@ -291,11 +379,15 @@ void FieldMaskTree::MergeMessage(const Node* node, const Message& source,
}
if (!field->is_repeated()) {
switch (field->cpp_type()) {
-#define COPY_VALUE(TYPE, Name) \
- case FieldDescriptor::CPPTYPE_##TYPE: { \
- destination_reflection->Set##Name( \
- destination, field, source_reflection->Get##Name(source, field)); \
- break; \
+#define COPY_VALUE(TYPE, Name) \
+ case FieldDescriptor::CPPTYPE_##TYPE: { \
+ if (source_reflection->HasField(source, field)) { \
+ destination_reflection->Set##Name( \
+ destination, field, source_reflection->Get##Name(source, field)); \
+ } else { \
+ destination_reflection->ClearField(destination, field); \
+ } \
+ break; \
}
COPY_VALUE(BOOL, Bool)
COPY_VALUE(INT32, Int32)
@@ -357,6 +449,26 @@ void FieldMaskTree::MergeMessage(const Node* node, const Message& source,
}
}
+void FieldMaskTree::TrimMessage(const Node* node, Message* message) {
+ GOOGLE_DCHECK(!node->children.empty());
+ const Reflection* reflection = message->GetReflection();
+ const Descriptor* descriptor = message->GetDescriptor();
+ const int32 field_count = descriptor->field_count();
+ for (int index = 0; index < field_count; ++index) {
+ const FieldDescriptor* field = descriptor->field(index);
+ if (!ContainsKey(node->children, field->name())) {
+ reflection->ClearField(message, field);
+ } else {
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ Node* child = node->children.at(field->name());
+ if (!child->children.empty()) {
+ TrimMessage(child, reflection->MutableMessage(message, field));
+ }
+ }
+ }
+ }
+}
+
} // namespace
void FieldMaskUtil::ToCanonicalForm(const FieldMask& mask, FieldMask* out) {
@@ -413,6 +525,14 @@ void FieldMaskUtil::MergeMessageTo(const Message& source, const FieldMask& mask,
tree.MergeMessage(source, options, destination);
}
+void FieldMaskUtil::TrimMessage(const FieldMask& mask, Message* destination) {
+ // Build a FieldMaskTree and walk through the tree to merge all specified
+ // fields.
+ FieldMaskTree tree;
+ tree.MergeFromFieldMask(mask);
+ tree.TrimMessage(GOOGLE_CHECK_NOTNULL(destination));
+}
+
} // namespace util
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/util/field_mask_util.h b/src/google/protobuf/util/field_mask_util.h
index 92f69893..e79b65e9 100644
--- a/src/google/protobuf/util/field_mask_util.h
+++ b/src/google/protobuf/util/field_mask_util.h
@@ -45,11 +45,18 @@ class LIBPROTOBUF_EXPORT FieldMaskUtil {
typedef google::protobuf::FieldMask FieldMask;
public:
- // Converts FieldMask to/from string, formatted according to proto3 JSON
- // spec for FieldMask (e.g., "foo,bar,baz.quz").
+ // Converts FieldMask to/from string, formatted by separating each path
+ // with a comma (e.g., "foo_bar,baz.quz").
static string ToString(const FieldMask& mask);
static void FromString(StringPiece str, FieldMask* out);
+ // Converts FieldMask to/from string, formatted according to proto3 JSON
+ // spec for FieldMask (e.g., "fooBar,baz.quz"). If the field name is not
+ // style conforming (i.e., not snake_case when converted to string, or not
+ // camelCase when converted from string), the conversion will fail.
+ static bool ToJsonString(const FieldMask& mask, string* out);
+ static bool FromJsonString(StringPiece str, FieldMask* out);
+
// Checks whether the given path is valid for type T.
template <typename T>
static bool IsValidPath(StringPiece path) {
@@ -100,11 +107,46 @@ class LIBPROTOBUF_EXPORT FieldMaskUtil {
static bool IsPathInFieldMask(StringPiece path, const FieldMask& mask);
class MergeOptions;
- // Merges fields specified in a FieldMask into another message.
+ // Merges fields specified in a FieldMask into another message. See the
+ // comments in MergeOptions regarding compatibility with
+ // google/protobuf/field_mask.proto
static void MergeMessageTo(const Message& source, const FieldMask& mask,
const MergeOptions& options, Message* destination);
+ // Removes from 'message' any field that is not represented in the given
+ // FieldMask. If the FieldMask is empty, does nothing.
+ static void TrimMessage(const FieldMask& mask, Message* message);
+
private:
+ friend class SnakeCaseCamelCaseTest;
+ // Converts a field name from snake_case to camelCase:
+ // 1. Every character after "_" will be converted to uppercase.
+ // 2. All "_"s are removed.
+ // The conversion will fail if:
+ // 1. The field name contains uppercase letters.
+ // 2. Any character after a "_" is not a lowercase letter.
+ // If the conversion succeeds, it's guaranteed that the resulted
+ // camelCase name will yield the original snake_case name when
+ // converted using CamelCaseToSnakeCase().
+ //
+ // Note that the input can contain characters not allowed in C identifiers.
+ // For example, "foo_bar,baz_quz" will be converted to "fooBar,bazQuz"
+ // successfully.
+ static bool SnakeCaseToCamelCase(StringPiece input, string* output);
+ // Converts a field name from camelCase to snake_case:
+ // 1. Every uppercase letter is converted to lowercase with a additional
+ // preceding "-".
+ // The conversion will fail if:
+ // 1. The field name contains "_"s.
+ // If the conversion succeeds, it's guaranteed that the resulted
+ // snake_case name will yield the original camelCase name when
+ // converted using SnakeCaseToCamelCase().
+ //
+ // Note that the input can contain characters not allowed in C identifiers.
+ // For example, "fooBar,bazQuz" will be converted to "foo_bar,baz_quz"
+ // successfully.
+ static bool CamelCaseToSnakeCase(StringPiece input, string* output);
+
static bool InternalIsValidPath(const Descriptor* descriptor,
StringPiece path);
@@ -112,6 +154,10 @@ class LIBPROTOBUF_EXPORT FieldMaskUtil {
FieldMask* out);
};
+// Note that for compatibility with the defined behaviour for FieldMask in
+// google/protobuf/field_mask.proto, set replace_message_fields and
+// replace_repeated_fields to 'true'. The default options are not compatible
+// with google/protobuf/field_mask.proto.
class LIBPROTOBUF_EXPORT FieldMaskUtil::MergeOptions {
public:
MergeOptions()
diff --git a/src/google/protobuf/util/field_mask_util_test.cc b/src/google/protobuf/util/field_mask_util_test.cc
index a9523250..43fb7905 100644
--- a/src/google/protobuf/util/field_mask_util_test.cc
+++ b/src/google/protobuf/util/field_mask_util_test.cc
@@ -30,6 +30,10 @@
#include <google/protobuf/util/field_mask_util.h>
+#include <algorithm>
+
+#include <google/protobuf/stubs/logging.h>
+#include <google/protobuf/stubs/common.h>
#include <google/protobuf/field_mask.pb.h>
#include <google/protobuf/unittest.pb.h>
#include <google/protobuf/test_util.h>
@@ -38,8 +42,77 @@
namespace google {
namespace protobuf {
namespace util {
+
+class SnakeCaseCamelCaseTest : public ::testing::Test {
+ protected:
+ string SnakeCaseToCamelCase(const string& input) {
+ string output;
+ if (FieldMaskUtil::SnakeCaseToCamelCase(input, &output)) {
+ return output;
+ } else {
+ return "#FAIL#";
+ }
+ }
+
+ string CamelCaseToSnakeCase(const string& input) {
+ string output;
+ if (FieldMaskUtil::CamelCaseToSnakeCase(input, &output)) {
+ return output;
+ } else {
+ return "#FAIL#";
+ }
+ }
+};
+
namespace {
+TEST_F(SnakeCaseCamelCaseTest, SnakeToCamel) {
+ EXPECT_EQ("fooBar", SnakeCaseToCamelCase("foo_bar"));
+ EXPECT_EQ("FooBar", SnakeCaseToCamelCase("_foo_bar"));
+ EXPECT_EQ("foo3Bar", SnakeCaseToCamelCase("foo3_bar"));
+ // No uppercase letter is allowed.
+ EXPECT_EQ("#FAIL#", SnakeCaseToCamelCase("Foo"));
+ // Any character after a "_" must be a lowercase letter.
+ // 1. "_" cannot be followed by another "_".
+ // 2. "_" cannot be followed by a digit.
+ // 3. "_" cannot appear as the last character.
+ EXPECT_EQ("#FAIL#", SnakeCaseToCamelCase("foo__bar"));
+ EXPECT_EQ("#FAIL#", SnakeCaseToCamelCase("foo_3bar"));
+ EXPECT_EQ("#FAIL#", SnakeCaseToCamelCase("foo_bar_"));
+}
+
+TEST_F(SnakeCaseCamelCaseTest, CamelToSnake) {
+ EXPECT_EQ("foo_bar", CamelCaseToSnakeCase("fooBar"));
+ EXPECT_EQ("_foo_bar", CamelCaseToSnakeCase("FooBar"));
+ EXPECT_EQ("foo3_bar", CamelCaseToSnakeCase("foo3Bar"));
+ // "_"s are not allowed.
+ EXPECT_EQ("#FAIL#", CamelCaseToSnakeCase("foo_bar"));
+}
+
+TEST_F(SnakeCaseCamelCaseTest, RoundTripTest) {
+ // Enumerates all possible snake_case names and test that converting it to
+ // camelCase and then to snake_case again will yield the original name.
+ string name = "___abc123";
+ std::sort(name.begin(), name.end());
+ do {
+ string camelName = SnakeCaseToCamelCase(name);
+ if (camelName != "#FAIL#") {
+ EXPECT_EQ(name, CamelCaseToSnakeCase(camelName));
+ }
+ } while (std::next_permutation(name.begin(), name.end()));
+
+ // Enumerates all possible camelCase names and test that converting it to
+ // snake_case and then to camelCase again will yield the original name.
+ name = "abcABC123";
+ std::sort(name.begin(), name.end());
+ do {
+ string camelName = CamelCaseToSnakeCase(name);
+ if (camelName != "#FAIL#") {
+ EXPECT_EQ(name, SnakeCaseToCamelCase(camelName));
+ }
+ } while (std::next_permutation(name.begin(), name.end()));
+}
+
using protobuf_unittest::TestAllTypes;
using protobuf_unittest::NestedTestAllTypes;
using google::protobuf::FieldMask;
@@ -47,20 +120,43 @@ using google::protobuf::FieldMask;
TEST(FieldMaskUtilTest, StringFormat) {
FieldMask mask;
EXPECT_EQ("", FieldMaskUtil::ToString(mask));
- mask.add_paths("foo");
- EXPECT_EQ("foo", FieldMaskUtil::ToString(mask));
- mask.add_paths("bar");
- EXPECT_EQ("foo,bar", FieldMaskUtil::ToString(mask));
+ mask.add_paths("foo_bar");
+ EXPECT_EQ("foo_bar", FieldMaskUtil::ToString(mask));
+ mask.add_paths("baz_quz");
+ EXPECT_EQ("foo_bar,baz_quz", FieldMaskUtil::ToString(mask));
FieldMaskUtil::FromString("", &mask);
EXPECT_EQ(0, mask.paths_size());
- FieldMaskUtil::FromString("foo", &mask);
+ FieldMaskUtil::FromString("fooBar", &mask);
+ EXPECT_EQ(1, mask.paths_size());
+ EXPECT_EQ("fooBar", mask.paths(0));
+ FieldMaskUtil::FromString("fooBar,bazQuz", &mask);
+ EXPECT_EQ(2, mask.paths_size());
+ EXPECT_EQ("fooBar", mask.paths(0));
+ EXPECT_EQ("bazQuz", mask.paths(1));
+}
+
+TEST(FieldMaskUtilTest, JsonStringFormat) {
+ FieldMask mask;
+ string value;
+ EXPECT_TRUE(FieldMaskUtil::ToJsonString(mask, &value));
+ EXPECT_EQ("", value);
+ mask.add_paths("foo_bar");
+ EXPECT_TRUE(FieldMaskUtil::ToJsonString(mask, &value));
+ EXPECT_EQ("fooBar", value);
+ mask.add_paths("bar_quz");
+ EXPECT_TRUE(FieldMaskUtil::ToJsonString(mask, &value));
+ EXPECT_EQ("fooBar,barQuz", value);
+
+ FieldMaskUtil::FromJsonString("", &mask);
+ EXPECT_EQ(0, mask.paths_size());
+ FieldMaskUtil::FromJsonString("fooBar", &mask);
EXPECT_EQ(1, mask.paths_size());
- EXPECT_EQ("foo", mask.paths(0));
- FieldMaskUtil::FromString("foo,bar", &mask);
+ EXPECT_EQ("foo_bar", mask.paths(0));
+ FieldMaskUtil::FromJsonString("fooBar,bazQuz", &mask);
EXPECT_EQ(2, mask.paths_size());
- EXPECT_EQ("foo", mask.paths(0));
- EXPECT_EQ("bar", mask.paths(1));
+ EXPECT_EQ("foo_bar", mask.paths(0));
+ EXPECT_EQ("baz_quz", mask.paths(1));
}
TEST(FieldMaskUtilTest, TestIsVaildPath) {
@@ -253,6 +349,10 @@ TEST(FieldMaskUtilTest, MergeMessage) {
dst.Clear(); \
FieldMaskUtil::MergeMessageTo(src, mask, options, &dst); \
EXPECT_EQ(tmp.DebugString(), dst.DebugString()); \
+ src.clear_##field_name(); \
+ tmp.clear_##field_name(); \
+ FieldMaskUtil::MergeMessageTo(src, mask, options, &dst); \
+ EXPECT_EQ(tmp.DebugString(), dst.DebugString()); \
}
TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_int32)
TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_int64)
@@ -388,6 +488,117 @@ TEST(FieldMaskUtilTest, MergeMessage) {
EXPECT_EQ(1234, nested_dst.payload().repeated_int32(0));
}
+TEST(FieldMaskUtilTest, TrimMessage) {
+#define TEST_TRIM_ONE_PRIMITIVE_FIELD(field_name) \
+ { \
+ TestAllTypes msg; \
+ TestUtil::SetAllFields(&msg); \
+ TestAllTypes tmp; \
+ tmp.set_##field_name(msg.field_name()); \
+ FieldMask mask; \
+ mask.add_paths(#field_name); \
+ FieldMaskUtil::TrimMessage(mask, &msg); \
+ EXPECT_EQ(tmp.DebugString(), msg.DebugString()); \
+ }
+ TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_int32)
+ TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_int64)
+ TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_uint32)
+ TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_uint64)
+ TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_sint32)
+ TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_sint64)
+ TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_fixed32)
+ TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_fixed64)
+ TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_sfixed32)
+ TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_sfixed64)
+ TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_float)
+ TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_double)
+ TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_bool)
+ TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_string)
+ TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_bytes)
+ TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_nested_enum)
+ TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_foreign_enum)
+ TEST_TRIM_ONE_PRIMITIVE_FIELD(optional_import_enum)
+#undef TEST_TRIM_ONE_PRIMITIVE_FIELD
+
+#define TEST_TRIM_ONE_FIELD(field_name) \
+ { \
+ TestAllTypes msg; \
+ TestUtil::SetAllFields(&msg); \
+ TestAllTypes tmp; \
+ *tmp.mutable_##field_name() = msg.field_name(); \
+ FieldMask mask; \
+ mask.add_paths(#field_name); \
+ FieldMaskUtil::TrimMessage(mask, &msg); \
+ EXPECT_EQ(tmp.DebugString(), msg.DebugString()); \
+ }
+ TEST_TRIM_ONE_FIELD(optional_nested_message)
+ TEST_TRIM_ONE_FIELD(optional_foreign_message)
+ TEST_TRIM_ONE_FIELD(optional_import_message)
+
+ TEST_TRIM_ONE_FIELD(repeated_int32)
+ TEST_TRIM_ONE_FIELD(repeated_int64)
+ TEST_TRIM_ONE_FIELD(repeated_uint32)
+ TEST_TRIM_ONE_FIELD(repeated_uint64)
+ TEST_TRIM_ONE_FIELD(repeated_sint32)
+ TEST_TRIM_ONE_FIELD(repeated_sint64)
+ TEST_TRIM_ONE_FIELD(repeated_fixed32)
+ TEST_TRIM_ONE_FIELD(repeated_fixed64)
+ TEST_TRIM_ONE_FIELD(repeated_sfixed32)
+ TEST_TRIM_ONE_FIELD(repeated_sfixed64)
+ TEST_TRIM_ONE_FIELD(repeated_float)
+ TEST_TRIM_ONE_FIELD(repeated_double)
+ TEST_TRIM_ONE_FIELD(repeated_bool)
+ TEST_TRIM_ONE_FIELD(repeated_string)
+ TEST_TRIM_ONE_FIELD(repeated_bytes)
+ TEST_TRIM_ONE_FIELD(repeated_nested_message)
+ TEST_TRIM_ONE_FIELD(repeated_foreign_message)
+ TEST_TRIM_ONE_FIELD(repeated_import_message)
+ TEST_TRIM_ONE_FIELD(repeated_nested_enum)
+ TEST_TRIM_ONE_FIELD(repeated_foreign_enum)
+ TEST_TRIM_ONE_FIELD(repeated_import_enum)
+#undef TEST_TRIM_ONE_FIELD
+
+ // Test trim nested fields.
+ NestedTestAllTypes nested_msg;
+ nested_msg.mutable_child()->mutable_payload()->set_optional_int32(1234);
+ nested_msg.mutable_child()
+ ->mutable_child()
+ ->mutable_payload()
+ ->set_optional_int32(5678);
+ NestedTestAllTypes trimmed_msg(nested_msg);
+ FieldMask mask;
+ FieldMaskUtil::FromString("child.payload", &mask);
+ FieldMaskUtil::TrimMessage(mask, &trimmed_msg);
+ EXPECT_EQ(1234, trimmed_msg.child().payload().optional_int32());
+ EXPECT_EQ(0, trimmed_msg.child().child().payload().optional_int32());
+
+ trimmed_msg = nested_msg;
+ FieldMaskUtil::FromString("child.child.payload", &mask);
+ FieldMaskUtil::TrimMessage(mask, &trimmed_msg);
+ EXPECT_EQ(0, trimmed_msg.child().payload().optional_int32());
+ EXPECT_EQ(5678, trimmed_msg.child().child().payload().optional_int32());
+
+ trimmed_msg = nested_msg;
+ FieldMaskUtil::FromString("child", &mask);
+ FieldMaskUtil::TrimMessage(mask, &trimmed_msg);
+ EXPECT_EQ(1234, trimmed_msg.child().payload().optional_int32());
+ EXPECT_EQ(5678, trimmed_msg.child().child().payload().optional_int32());
+
+ trimmed_msg = nested_msg;
+ FieldMaskUtil::FromString("child.child", &mask);
+ FieldMaskUtil::TrimMessage(mask, &trimmed_msg);
+ EXPECT_EQ(0, trimmed_msg.child().payload().optional_int32());
+ EXPECT_EQ(5678, trimmed_msg.child().child().payload().optional_int32());
+
+ // Verify than an empty FieldMask trims nothing
+ TestAllTypes all_types_msg;
+ TestUtil::SetAllFields(&all_types_msg);
+ TestAllTypes trimmed_all_types(all_types_msg);
+ FieldMask empty_mask;
+ FieldMaskUtil::TrimMessage(empty_mask, &trimmed_all_types);
+ EXPECT_EQ(trimmed_all_types.DebugString(), all_types_msg.DebugString());
+}
+
} // namespace
} // namespace util
diff --git a/src/google/protobuf/util/internal/constants.h b/src/google/protobuf/util/internal/constants.h
index 0cb8f6e1..e556888c 100644
--- a/src/google/protobuf/util/internal/constants.h
+++ b/src/google/protobuf/util/internal/constants.h
@@ -43,13 +43,23 @@ namespace converter {
const char kTypeServiceBaseUrl[] = "type.googleapis.com";
// Format string for RFC3339 timestamp formatting.
-const char kRfc3339TimeFormat[] = "%Y-%m-%dT%H:%M:%S";
+const char kRfc3339TimeFormat[] = "%E4Y-%m-%dT%H:%M:%S";
-// Minimum seconds allowed in a google.protobuf.TimeStamp or Duration value.
-const int64 kMinSeconds = -315576000000;
+// Same as above, but the year value is not zero-padded i.e. this accepts
+// timestamps like "1-01-0001T23:59:59Z" instead of "0001-01-0001T23:59:59Z".
+const char kRfc3339TimeFormatNoPadding[] = "%Y-%m-%dT%H:%M:%S";
-// Maximum seconds allowed in a google.protobuf.TimeStamp or Duration value.
-const int64 kMaxSeconds = 315576000000;
+// Minimun seconds allowed in a google.protobuf.Timestamp value.
+const int64 kTimestampMinSeconds = -62135596800;
+
+// Maximum seconds allowed in a google.protobuf.Timestamp value.
+const int64 kTimestampMaxSeconds = 253402300799;
+
+// Minimum seconds allowed in a google.protobuf.Duration value.
+const int64 kDurationMinSeconds = -315576000000;
+
+// Maximum seconds allowed in a google.protobuf.Duration value.
+const int64 kDurationMaxSeconds = 315576000000;
// Nano seconds in a second.
const int32 kNanosPerSecond = 1000000000;
diff --git a/src/google/protobuf/util/internal/datapiece.cc b/src/google/protobuf/util/internal/datapiece.cc
index ea360798..ef8da427 100644
--- a/src/google/protobuf/util/internal/datapiece.cc
+++ b/src/google/protobuf/util/internal/datapiece.cc
@@ -35,8 +35,8 @@
#include <google/protobuf/descriptor.h>
#include <google/protobuf/util/internal/utility.h>
#include <google/protobuf/stubs/strutil.h>
-#include <google/protobuf/stubs/mathutil.h>
#include <google/protobuf/stubs/mathlimits.h>
+#include <google/protobuf/stubs/mathutil.h>
namespace google {
namespace protobuf {
@@ -47,6 +47,7 @@ using google::protobuf::EnumDescriptor;
using google::protobuf::EnumValueDescriptor;
;
;
+;
using util::error::Code;
using util::Status;
using util::StatusOr;
@@ -57,13 +58,8 @@ inline Status InvalidArgument(StringPiece value_str) {
return Status(util::error::INVALID_ARGUMENT, value_str);
}
-// For general conversion between
-// int32, int64, uint32, uint64, double and float
-// except conversion between double and float.
template <typename To, typename From>
-StatusOr<To> NumberConvertAndCheck(From before) {
- if (::google::protobuf::internal::is_same<From, To>::value) return before;
- To after = static_cast<To>(before);
+StatusOr<To> ValidateNumberConversion(To after, From before) {
if (after == before &&
MathUtil::Sign<From>(before) == MathUtil::Sign<To>(after)) {
return after;
@@ -76,6 +72,27 @@ StatusOr<To> NumberConvertAndCheck(From before) {
}
}
+// For general conversion between
+// int32, int64, uint32, uint64, double and float
+// except conversion between double and float.
+template <typename To, typename From>
+StatusOr<To> NumberConvertAndCheck(From before) {
+ if (::google::protobuf::internal::is_same<From, To>::value) return before;
+
+ To after = static_cast<To>(before);
+ return ValidateNumberConversion(after, before);
+}
+
+// For conversion to integer types (int32, int64, uint32, uint64) from floating
+// point types (double, float) only.
+template <typename To, typename From>
+StatusOr<To> FloatingPointToIntConvertAndCheck(From before) {
+ if (::google::protobuf::internal::is_same<From, To>::value) return before;
+
+ To after = static_cast<To>(before);
+ return ValidateNumberConversion(after, before);
+}
+
// For conversion between double and float only.
template <typename To, typename From>
StatusOr<To> FloatingPointConvertAndCheck(From before) {
@@ -96,30 +113,50 @@ StatusOr<To> FloatingPointConvertAndCheck(From before) {
} // namespace
StatusOr<int32> DataPiece::ToInt32() const {
- if (type_ == TYPE_STRING) {
- return StringToNumber<int32>(safe_strto32);
- }
+ if (type_ == TYPE_STRING) return StringToNumber<int32>(safe_strto32);
+
+ if (type_ == TYPE_DOUBLE)
+ return FloatingPointToIntConvertAndCheck<int32, double>(double_);
+
+ if (type_ == TYPE_FLOAT)
+ return FloatingPointToIntConvertAndCheck<int32, float>(float_);
+
return GenericConvert<int32>();
}
StatusOr<uint32> DataPiece::ToUint32() const {
- if (type_ == TYPE_STRING) {
- return StringToNumber<uint32>(safe_strtou32);
- }
+ if (type_ == TYPE_STRING) return StringToNumber<uint32>(safe_strtou32);
+
+ if (type_ == TYPE_DOUBLE)
+ return FloatingPointToIntConvertAndCheck<uint32, double>(double_);
+
+ if (type_ == TYPE_FLOAT)
+ return FloatingPointToIntConvertAndCheck<uint32, float>(float_);
+
return GenericConvert<uint32>();
}
StatusOr<int64> DataPiece::ToInt64() const {
- if (type_ == TYPE_STRING) {
- return StringToNumber<int64>(safe_strto64);
- }
+ if (type_ == TYPE_STRING) return StringToNumber<int64>(safe_strto64);
+
+ if (type_ == TYPE_DOUBLE)
+ return FloatingPointToIntConvertAndCheck<int64, double>(double_);
+
+ if (type_ == TYPE_FLOAT)
+ return FloatingPointToIntConvertAndCheck<int64, float>(float_);
+
return GenericConvert<int64>();
}
StatusOr<uint64> DataPiece::ToUint64() const {
- if (type_ == TYPE_STRING) {
- return StringToNumber<uint64>(safe_strtou64);
- }
+ if (type_ == TYPE_STRING) return StringToNumber<uint64>(safe_strtou64);
+
+ if (type_ == TYPE_DOUBLE)
+ return FloatingPointToIntConvertAndCheck<uint64, double>(double_);
+
+ if (type_ == TYPE_FLOAT)
+ return FloatingPointToIntConvertAndCheck<uint64, float>(float_);
+
return GenericConvert<uint64>();
}
@@ -212,11 +249,8 @@ StatusOr<string> DataPiece::ToBytes() const {
if (type_ == TYPE_BYTES) return str_.ToString();
if (type_ == TYPE_STRING) {
string decoded;
- if (!WebSafeBase64Unescape(str_, &decoded)) {
- if (!Base64Unescape(str_, &decoded)) {
- return InvalidArgument(
- ValueAsStringOrDefault("Invalid data in input."));
- }
+ if (!DecodeBase64(str_, &decoded)) {
+ return InvalidArgument(ValueAsStringOrDefault("Invalid data in input."));
}
return decoded;
} else {
@@ -277,11 +311,67 @@ StatusOr<To> DataPiece::GenericConvert() const {
template <typename To>
StatusOr<To> DataPiece::StringToNumber(bool (*func)(StringPiece, To*)) const {
+ if (str_.size() > 0 && (str_[0] == ' ' || str_[str_.size() - 1] == ' ')) {
+ return InvalidArgument(StrCat("\"", str_, "\""));
+ }
To result;
if (func(str_, &result)) return result;
return InvalidArgument(StrCat("\"", str_.ToString(), "\""));
}
+bool DataPiece::DecodeBase64(StringPiece src, string* dest) const {
+ // Try web-safe decode first, if it fails, try the non-web-safe decode.
+ if (WebSafeBase64Unescape(src, dest)) {
+ if (use_strict_base64_decoding_) {
+ // In strict mode, check if the escaped version gives us the same value as
+ // unescaped.
+ string encoded;
+ // WebSafeBase64Escape does no padding by default.
+ WebSafeBase64Escape(*dest, &encoded);
+ // Remove trailing padding '=' characters before comparison.
+ StringPiece src_no_padding = StringPiece(src).substr(
+ 0, src.ends_with("=") ? src.find_last_not_of('=') + 1 : src.length());
+ return encoded == src_no_padding;
+ }
+ return true;
+ }
+
+ if (Base64Unescape(src, dest)) {
+ if (use_strict_base64_decoding_) {
+ string encoded;
+ Base64Escape(
+ reinterpret_cast<const unsigned char*>(dest->data()), dest->length(),
+ &encoded, false);
+ StringPiece src_no_padding = StringPiece(src).substr(
+ 0, src.ends_with("=") ? src.find_last_not_of('=') + 1 : src.length());
+ return encoded == src_no_padding;
+ }
+ return true;
+ }
+
+ return false;
+}
+
+void DataPiece::InternalCopy(const DataPiece& other) {
+ type_ = other.type_;
+ switch (type_) {
+ case TYPE_INT32:
+ case TYPE_INT64:
+ case TYPE_UINT32:
+ case TYPE_UINT64:
+ case TYPE_DOUBLE:
+ case TYPE_FLOAT:
+ case TYPE_BOOL:
+ case TYPE_ENUM:
+ case TYPE_NULL:
+ case TYPE_BYTES:
+ case TYPE_STRING: {
+ str_ = other.str_;
+ break;
+ }
+ }
+}
+
} // namespace converter
} // namespace util
} // namespace protobuf
diff --git a/src/google/protobuf/util/internal/datapiece.h b/src/google/protobuf/util/internal/datapiece.h
index 2ab3fa88..e82cdbac 100644
--- a/src/google/protobuf/util/internal/datapiece.h
+++ b/src/google/protobuf/util/internal/datapiece.h
@@ -83,22 +83,27 @@ class LIBPROTOBUF_EXPORT DataPiece {
explicit DataPiece(const double value) : type_(TYPE_DOUBLE), double_(value) {}
explicit DataPiece(const float value) : type_(TYPE_FLOAT), float_(value) {}
explicit DataPiece(const bool value) : type_(TYPE_BOOL), bool_(value) {}
- explicit DataPiece(StringPiece value)
+ DataPiece(StringPiece value, bool use_strict_base64_decoding)
: type_(TYPE_STRING),
- str_(StringPiecePod::CreateFromStringPiece(value)) {}
+ str_(StringPiecePod::CreateFromStringPiece(value)),
+ use_strict_base64_decoding_(use_strict_base64_decoding) {}
// Constructor for bytes. The second parameter is not used.
- explicit DataPiece(StringPiece value, bool dummy)
- : type_(TYPE_BYTES), str_(StringPiecePod::CreateFromStringPiece(value)) {}
- DataPiece(const DataPiece& r) : type_(r.type_), str_(r.str_) {}
+ DataPiece(StringPiece value, bool dummy, bool use_strict_base64_decoding)
+ : type_(TYPE_BYTES),
+ str_(StringPiecePod::CreateFromStringPiece(value)),
+ use_strict_base64_decoding_(use_strict_base64_decoding) {}
+
+ DataPiece(const DataPiece& r) : type_(r.type_) { InternalCopy(r); }
+
DataPiece& operator=(const DataPiece& x) {
- type_ = x.type_;
- str_ = x.str_;
+ InternalCopy(x);
return *this;
}
static DataPiece NullData() { return DataPiece(TYPE_NULL, 0); }
- virtual ~DataPiece() {}
+ virtual ~DataPiece() {
+ }
// Accessors
Type type() const { return type_; }
@@ -164,32 +169,16 @@ class LIBPROTOBUF_EXPORT DataPiece {
template <typename To>
util::StatusOr<To> StringToNumber(bool (*func)(StringPiece, To*)) const;
- // Data type for this piece of data.
- Type type_;
-
- // StringPiece is not a POD and can not be used in an union (pre C++11). We
- // need a POD version of it.
- struct StringPiecePod {
- const char* data;
- int size;
+ // Decodes a base64 string. Returns true on success.
+ bool DecodeBase64(StringPiece src, string* dest) const;
- // Create from a StringPiece.
- static StringPiecePod CreateFromStringPiece(StringPiece str) {
- StringPiecePod pod;
- pod.data = str.data();
- pod.size = str.size();
- return pod;
- }
+ // Helper function to initialize this DataPiece with 'other'.
+ void InternalCopy(const DataPiece& other);
- // Cast to StringPiece.
- operator StringPiece() const { return StringPiece(data, size); }
+ // Data type for this piece of data.
+ Type type_;
- bool operator==(const char* value) const {
- return StringPiece(data, size) == StringPiece(value);
- }
-
- string ToString() const { return string(data, size); }
- };
+ typedef ::google::protobuf::internal::StringPiecePod StringPiecePod;
// Stored piece of data.
union {
@@ -202,6 +191,9 @@ class LIBPROTOBUF_EXPORT DataPiece {
bool bool_;
StringPiecePod str_;
};
+
+ // Uses a stricter version of base64 decoding for byte fields.
+ bool use_strict_base64_decoding_;
};
} // namespace converter
diff --git a/src/google/protobuf/util/internal/default_value_objectwriter.cc b/src/google/protobuf/util/internal/default_value_objectwriter.cc
index 97b248ff..1e8dab70 100644
--- a/src/google/protobuf/util/internal/default_value_objectwriter.cc
+++ b/src/google/protobuf/util/internal/default_value_objectwriter.cc
@@ -33,6 +33,7 @@
#include <google/protobuf/stubs/hash.h>
#include <google/protobuf/util/internal/constants.h>
+#include <google/protobuf/util/internal/utility.h>
#include <google/protobuf/stubs/map_util.h>
namespace google {
@@ -42,15 +43,29 @@ using util::Status;
using util::StatusOr;
namespace converter {
+namespace {
+// Helper function to convert string value to given data type by calling the
+// passed converter function on the DataPiece created from "value" argument.
+// If value is empty or if conversion fails, the default_value is returned.
+template <typename T>
+T ConvertTo(StringPiece value, StatusOr<T> (DataPiece::*converter_fn)() const,
+ T default_value) {
+ if (value.empty()) return default_value;
+ StatusOr<T> result = (DataPiece(value, true).*converter_fn)();
+ return result.ok() ? result.ValueOrDie() : default_value;
+}
+} // namespace
+
DefaultValueObjectWriter::DefaultValueObjectWriter(
TypeResolver* type_resolver, const google::protobuf::Type& type,
ObjectWriter* ow)
: typeinfo_(TypeInfo::NewTypeInfo(type_resolver)),
own_typeinfo_(true),
type_(type),
- disable_normalize_(false),
current_(NULL),
root_(NULL),
+ suppress_empty_list_(false),
+ field_scrub_callback_(NULL),
ow_(ow) {}
DefaultValueObjectWriter::~DefaultValueObjectWriter() {
@@ -140,7 +155,7 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::RenderString(
// Since StringPiece is essentially a pointer, takes a copy of "value" to
// avoid ownership issues.
string_values_.push_back(new string(value.ToString()));
- RenderDataPiece(name, DataPiece(*string_values_.back()));
+ RenderDataPiece(name, DataPiece(*string_values_.back(), true));
}
return this;
}
@@ -150,7 +165,7 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::RenderBytes(
if (current_ == NULL) {
ow_->RenderBytes(name, value);
} else {
- RenderDataPiece(name, DataPiece(value));
+ RenderDataPiece(name, DataPiece(value, false, true));
}
return this;
}
@@ -165,23 +180,24 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::RenderNull(
return this;
}
-DefaultValueObjectWriter*
-DefaultValueObjectWriter::DisableCaseNormalizationForNextKey() {
- disable_normalize_ = true;
- return this;
+void DefaultValueObjectWriter::RegisterFieldScrubCallBack(
+ FieldScrubCallBackPtr field_scrub_callback) {
+ field_scrub_callback_.reset(field_scrub_callback.release());
}
-DefaultValueObjectWriter::Node::Node(const string& name,
- const google::protobuf::Type* type,
- NodeKind kind, const DataPiece& data,
- bool is_placeholder)
+DefaultValueObjectWriter::Node::Node(
+ const string& name, const google::protobuf::Type* type, NodeKind kind,
+ const DataPiece& data, bool is_placeholder, const vector<string>& path,
+ bool suppress_empty_list, FieldScrubCallBack* field_scrub_callback)
: name_(name),
type_(type),
kind_(kind),
- disable_normalize_(false),
is_any_(false),
data_(data),
- is_placeholder_(is_placeholder) {}
+ is_placeholder_(is_placeholder),
+ path_(path),
+ suppress_empty_list_(suppress_empty_list),
+ field_scrub_callback_(field_scrub_callback) {}
DefaultValueObjectWriter::Node* DefaultValueObjectWriter::Node::FindChild(
StringPiece name) {
@@ -198,10 +214,6 @@ DefaultValueObjectWriter::Node* DefaultValueObjectWriter::Node::FindChild(
}
void DefaultValueObjectWriter::Node::WriteTo(ObjectWriter* ow) {
- if (disable_normalize_) {
- ow->DisableCaseNormalizationForNextKey();
- }
-
if (kind_ == PRIMITIVE) {
ObjectWriter::RenderDataPieceTo(data_, name_, ow);
return;
@@ -218,6 +230,9 @@ void DefaultValueObjectWriter::Node::WriteTo(ObjectWriter* ow) {
// Write out lists. If we didn't have any list in response, write out empty
// list.
if (kind_ == LIST) {
+ // Suppress empty lists if requested.
+ if (suppress_empty_list_ && is_placeholder_) return;
+
ow->StartList(name_);
WriteChildren(ow);
ow->EndList();
@@ -289,6 +304,19 @@ void DefaultValueObjectWriter::Node::PopulateChildren(
for (int i = 0; i < type_->fields_size(); ++i) {
const google::protobuf::Field& field = type_->fields(i);
+
+ // This code is checking if the field to be added to the tree should be
+ // scrubbed or not by calling the field_scrub_callback_ callback function.
+ vector<string> path;
+ if (!path_.empty()) {
+ path.insert(path.begin(), path_.begin(), path_.end());
+ }
+ path.push_back(field.name());
+ if (field_scrub_callback_ != NULL &&
+ field_scrub_callback_->Run(path, &field)) {
+ continue;
+ }
+
hash_map<string, int>::iterator found =
orig_children_map.find(field.name());
// If the child field has already been set, we just add it to the new list
@@ -324,6 +352,7 @@ void DefaultValueObjectWriter::Node::PopulateChildren(
}
}
}
+
if (!is_map &&
field.cardinality() ==
google::protobuf::Field_Cardinality_CARDINALITY_REPEATED) {
@@ -336,11 +365,11 @@ void DefaultValueObjectWriter::Node::PopulateChildren(
// If the child field is of primitive type, sets its data to the default
// value of its type.
- google::protobuf::scoped_ptr<Node> child(
- new Node(field.json_name(), field_type, kind,
- kind == PRIMITIVE ? CreateDefaultDataPieceForField(field)
- : DataPiece::NullData(),
- true));
+ google::protobuf::scoped_ptr<Node> child(new Node(
+ field.json_name(), field_type, kind,
+ kind == PRIMITIVE ? CreateDefaultDataPieceForField(field, typeinfo)
+ : DataPiece::NullData(),
+ true, path, suppress_empty_list_, field_scrub_callback_));
new_children.push_back(child.release());
}
// Adds all leftover nodes in children_ to the beginning of new_child.
@@ -363,41 +392,69 @@ void DefaultValueObjectWriter::MaybePopulateChildrenOfAny(Node* node) {
}
}
+DataPiece DefaultValueObjectWriter::FindEnumDefault(
+ const google::protobuf::Field& field, const TypeInfo* typeinfo) {
+ if (!field.default_value().empty())
+ return DataPiece(field.default_value(), true);
+
+ const google::protobuf::Enum* enum_type =
+ typeinfo->GetEnumByTypeUrl(field.type_url());
+ if (!enum_type) {
+ GOOGLE_LOG(WARNING) << "Could not find enum with type '" << field.type_url()
+ << "'";
+ return DataPiece::NullData();
+ }
+ // We treat the first value as the default if none is specified.
+ return enum_type->enumvalue_size() > 0
+ ? DataPiece(enum_type->enumvalue(0).name(), true)
+ : DataPiece::NullData();
+}
+
DataPiece DefaultValueObjectWriter::CreateDefaultDataPieceForField(
- const google::protobuf::Field& field) {
+ const google::protobuf::Field& field, const TypeInfo* typeinfo) {
switch (field.kind()) {
case google::protobuf::Field_Kind_TYPE_DOUBLE: {
- return DataPiece(static_cast<double>(0));
+ return DataPiece(ConvertTo<double>(
+ field.default_value(), &DataPiece::ToDouble, static_cast<double>(0)));
}
case google::protobuf::Field_Kind_TYPE_FLOAT: {
- return DataPiece(static_cast<float>(0));
+ return DataPiece(ConvertTo<float>(
+ field.default_value(), &DataPiece::ToFloat, static_cast<float>(0)));
}
case google::protobuf::Field_Kind_TYPE_INT64:
case google::protobuf::Field_Kind_TYPE_SINT64:
case google::protobuf::Field_Kind_TYPE_SFIXED64: {
- return DataPiece(static_cast<int64>(0));
+ return DataPiece(ConvertTo<int64>(
+ field.default_value(), &DataPiece::ToInt64, static_cast<int64>(0)));
}
case google::protobuf::Field_Kind_TYPE_UINT64:
case google::protobuf::Field_Kind_TYPE_FIXED64: {
- return DataPiece(static_cast<uint64>(0));
+ return DataPiece(ConvertTo<uint64>(
+ field.default_value(), &DataPiece::ToUint64, static_cast<uint64>(0)));
}
case google::protobuf::Field_Kind_TYPE_INT32:
case google::protobuf::Field_Kind_TYPE_SINT32:
case google::protobuf::Field_Kind_TYPE_SFIXED32: {
- return DataPiece(static_cast<int32>(0));
+ return DataPiece(ConvertTo<int32>(
+ field.default_value(), &DataPiece::ToInt32, static_cast<int32>(0)));
}
case google::protobuf::Field_Kind_TYPE_BOOL: {
- return DataPiece(false);
+ return DataPiece(
+ ConvertTo<bool>(field.default_value(), &DataPiece::ToBool, false));
}
case google::protobuf::Field_Kind_TYPE_STRING: {
- return DataPiece(string());
+ return DataPiece(field.default_value(), true);
}
case google::protobuf::Field_Kind_TYPE_BYTES: {
- return DataPiece("", false);
+ return DataPiece(field.default_value(), false, true);
}
case google::protobuf::Field_Kind_TYPE_UINT32:
case google::protobuf::Field_Kind_TYPE_FIXED32: {
- return DataPiece(static_cast<uint32>(0));
+ return DataPiece(ConvertTo<uint32>(
+ field.default_value(), &DataPiece::ToUint32, static_cast<uint32>(0)));
+ }
+ case google::protobuf::Field_Kind_TYPE_ENUM: {
+ return FindEnumDefault(field, typeinfo);
}
default: { return DataPiece::NullData(); }
}
@@ -406,9 +463,10 @@ DataPiece DefaultValueObjectWriter::CreateDefaultDataPieceForField(
DefaultValueObjectWriter* DefaultValueObjectWriter::StartObject(
StringPiece name) {
if (current_ == NULL) {
+ vector<string> path;
root_.reset(new Node(name.ToString(), &type_, OBJECT, DataPiece::NullData(),
- false));
- root_->set_disable_normalize(GetAndResetDisableNormalize());
+ false, path, suppress_empty_list_,
+ field_scrub_callback_.get()));
root_->PopulateChildren(typeinfo_);
current_ = root_.get();
return this;
@@ -422,13 +480,14 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::StartObject(
name.ToString(), ((current_->kind() == LIST || current_->kind() == MAP)
? current_->type()
: NULL),
- OBJECT, DataPiece::NullData(), false));
+ OBJECT, DataPiece::NullData(), false,
+ child == NULL ? current_->path() : child->path(),
+ suppress_empty_list_, field_scrub_callback_.get()));
child = node.get();
current_->AddChild(node.release());
}
child->set_is_placeholder(false);
- child->set_disable_normalize(GetAndResetDisableNormalize());
if (child->kind() == OBJECT && child->number_of_children() == 0) {
child->PopulateChildren(typeinfo_);
}
@@ -452,23 +511,24 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::EndObject() {
DefaultValueObjectWriter* DefaultValueObjectWriter::StartList(
StringPiece name) {
if (current_ == NULL) {
- root_.reset(
- new Node(name.ToString(), &type_, LIST, DataPiece::NullData(), false));
- root_->set_disable_normalize(GetAndResetDisableNormalize());
+ vector<string> path;
+ root_.reset(new Node(name.ToString(), &type_, LIST, DataPiece::NullData(),
+ false, path, suppress_empty_list_,
+ field_scrub_callback_.get()));
current_ = root_.get();
return this;
}
MaybePopulateChildrenOfAny(current_);
Node* child = current_->FindChild(name);
if (child == NULL || child->kind() != LIST) {
- GOOGLE_LOG(WARNING) << "Cannot find field '" << name << "'.";
google::protobuf::scoped_ptr<Node> node(
- new Node(name.ToString(), NULL, LIST, DataPiece::NullData(), false));
+ new Node(name.ToString(), NULL, LIST, DataPiece::NullData(), false,
+ child == NULL ? current_->path() : child->path(),
+ suppress_empty_list_, field_scrub_callback_.get()));
child = node.get();
current_->AddChild(node.release());
}
child->set_is_placeholder(false);
- child->set_disable_normalize(GetAndResetDisableNormalize());
stack_.push(current_);
current_ = child;
@@ -520,13 +580,14 @@ void DefaultValueObjectWriter::RenderDataPiece(StringPiece name,
if (child == NULL || child->kind() != PRIMITIVE) {
// No children are found, creates a new child.
google::protobuf::scoped_ptr<Node> node(
- new Node(name.ToString(), NULL, PRIMITIVE, data, false));
+ new Node(name.ToString(), NULL, PRIMITIVE, data, false,
+ child == NULL ? current_->path() : child->path(),
+ suppress_empty_list_, field_scrub_callback_.get()));
child = node.get();
current_->AddChild(node.release());
} else {
child->set_data(data);
}
- child->set_disable_normalize(GetAndResetDisableNormalize());
}
} // namespace converter
diff --git a/src/google/protobuf/util/internal/default_value_objectwriter.h b/src/google/protobuf/util/internal/default_value_objectwriter.h
index bcb526e8..5f3b25f3 100644
--- a/src/google/protobuf/util/internal/default_value_objectwriter.h
+++ b/src/google/protobuf/util/internal/default_value_objectwriter.h
@@ -38,6 +38,7 @@
#include <stack>
#include <vector>
+#include <google/protobuf/stubs/callback.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/util/internal/type_info.h>
#include <google/protobuf/util/internal/datapiece.h>
@@ -59,6 +60,25 @@ namespace converter {
// with their default values (0 for numbers, "" for strings, etc).
class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter {
public:
+ // A Callback function to check whether a field needs to be scrubbed.
+ //
+ // Returns true if the field should not be present in the output. Returns
+ // false otherwise.
+ //
+ // The 'path' parameter is a vector of path to the field from root. For
+ // example: if a nested field "a.b.c" (b is the parent message field of c and
+ // a is the parent message field of b), then the vector should contain { "a",
+ // "b", "c" }.
+ //
+ // The Field* should point to the google::protobuf::Field of "c".
+ typedef ResultCallback2<bool /*return*/,
+ const std::vector<string>& /*path of the field*/,
+ const google::protobuf::Field* /*field*/>
+ FieldScrubCallBack;
+
+ // A unique pointer to a DefaultValueObjectWriter::FieldScrubCallBack.
+ typedef google::protobuf::scoped_ptr<FieldScrubCallBack> FieldScrubCallBackPtr;
+
DefaultValueObjectWriter(TypeResolver* type_resolver,
const google::protobuf::Type& type,
ObjectWriter* ow);
@@ -98,7 +118,13 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter {
virtual DefaultValueObjectWriter* RenderNull(StringPiece name);
- virtual DefaultValueObjectWriter* DisableCaseNormalizationForNextKey();
+ // Register the callback for scrubbing of fields. Owership of
+ // field_scrub_callback pointer is also transferred to this class
+ void RegisterFieldScrubCallBack(FieldScrubCallBackPtr field_scrub_callback);
+
+ // If set to true, empty lists are suppressed from output when default values
+ // are written.
+ void set_suppress_empty_list(bool value) { suppress_empty_list_ = value; }
private:
enum NodeKind {
@@ -113,7 +139,8 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter {
class LIBPROTOBUF_EXPORT Node {
public:
Node(const string& name, const google::protobuf::Type* type, NodeKind kind,
- const DataPiece& data, bool is_placeholder);
+ const DataPiece& data, bool is_placeholder, const vector<string>& path,
+ bool suppress_empty_list, FieldScrubCallBack* field_scrub_callback);
virtual ~Node() {
for (int i = 0; i < children_.size(); ++i) {
delete children_[i];
@@ -139,21 +166,19 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter {
// Accessors
const string& name() const { return name_; }
- const google::protobuf::Type* type() { return type_; }
+ const vector<string>& path() const { return path_; }
+
+ const google::protobuf::Type* type() const { return type_; }
void set_type(const google::protobuf::Type* type) { type_ = type; }
- NodeKind kind() { return kind_; }
+ NodeKind kind() const { return kind_; }
- int number_of_children() { return children_.size(); }
+ int number_of_children() const { return children_.size(); }
void set_data(const DataPiece& data) { data_ = data; }
- void set_disable_normalize(bool disable_normalize) {
- disable_normalize_ = disable_normalize;
- }
-
- bool is_any() { return is_any_; }
+ bool is_any() const { return is_any_; }
void set_is_any(bool is_any) { is_any_ = is_any; }
@@ -176,8 +201,6 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter {
const google::protobuf::Type* type_;
// The kind of this node.
NodeKind kind_;
- // Whether to disable case normalization of the name.
- bool disable_normalize_;
// Whether this is a node for "Any".
bool is_any_;
// The data of this node when it is a leaf node.
@@ -189,6 +212,18 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter {
// the parent node's StartObject()/StartList() method is called with this
// node's name.
bool is_placeholder_;
+
+ // Path of the field of this node
+ std::vector<string> path_;
+
+ // Whether to suppress empty list output.
+ bool suppress_empty_list_;
+
+ // Pointer to function for determining whether a field needs to be scrubbed
+ // or not. This callback is owned by the creator of this node.
+ FieldScrubCallBack* field_scrub_callback_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Node);
};
// Populates children of "node" if it is an "any" Node and its real type has
@@ -201,16 +236,17 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter {
// Creates a DataPiece containing the default value of the type of the field.
static DataPiece CreateDefaultDataPieceForField(
- const google::protobuf::Field& field);
-
- // Returns disable_normalize_ and reset it to false.
- bool GetAndResetDisableNormalize() {
- return disable_normalize_ ? (disable_normalize_ = false, true) : false;
- }
+ const google::protobuf::Field& field, const TypeInfo* typeinfo);
// Adds or replaces the data_ of a primitive child node.
void RenderDataPiece(StringPiece name, const DataPiece& data);
+ // Returns the default enum value as a DataPiece, or the first enum value if
+ // there is no default. For proto3, where we cannot specify an explicit
+ // default, a zero value will always be returned.
+ static DataPiece FindEnumDefault(const google::protobuf::Field& field,
+ const TypeInfo* typeinfo);
+
// Type information for all the types used in the descriptor. Used to find
// google::protobuf::Type of nested messages/enums.
const TypeInfo* typeinfo_;
@@ -221,8 +257,6 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter {
// Holds copies of strings passed to RenderString.
vector<string*> string_values_;
- // Whether to disable case normalization of the next node.
- bool disable_normalize_;
// The current Node. Owned by its parents.
Node* current_;
// The root Node.
@@ -230,6 +264,13 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter {
// The stack to hold the path of Nodes from current_ to root_;
std::stack<Node*> stack_;
+ // Whether to suppress output of empty lists.
+ bool suppress_empty_list_;
+
+ // Unique Pointer to function for determining whether a field needs to be
+ // scrubbed or not.
+ FieldScrubCallBackPtr field_scrub_callback_;
+
ObjectWriter* ow_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DefaultValueObjectWriter);
diff --git a/src/google/protobuf/util/internal/default_value_objectwriter_test.cc b/src/google/protobuf/util/internal/default_value_objectwriter_test.cc
index 237d0722..e1dd697a 100644
--- a/src/google/protobuf/util/internal/default_value_objectwriter_test.cc
+++ b/src/google/protobuf/util/internal/default_value_objectwriter_test.cc
@@ -43,21 +43,19 @@ namespace testing {
using google::protobuf::testing::DefaultValueTest;
-// Tests to cover some basic DefaultValueObjectWriter use cases. More tests are
-// in the marshalling_test.cc and translator_integration_test.cc.
-class DefaultValueObjectWriterTest
+// Base class for setting up required state for running default values tests on
+// different descriptors.
+class BaseDefaultValueObjectWriterTest
: public ::testing::TestWithParam<testing::TypeInfoSource> {
protected:
- DefaultValueObjectWriterTest()
+ explicit BaseDefaultValueObjectWriterTest(const Descriptor* descriptor)
: helper_(GetParam()), mock_(), expects_(&mock_) {
- helper_.ResetTypeInfo(DefaultValueTest::descriptor());
+ helper_.ResetTypeInfo(descriptor);
testing_.reset(helper_.NewDefaultValueWriter(
- string(kTypeServiceBaseUrl) + "/" +
- DefaultValueTest::descriptor()->full_name(),
- &mock_));
+ string(kTypeServiceBaseUrl) + "/" + descriptor->full_name(), &mock_));
}
- virtual ~DefaultValueObjectWriterTest() {}
+ virtual ~BaseDefaultValueObjectWriterTest() {}
TypeInfoTestHelper helper_;
MockObjectWriter mock_;
@@ -65,6 +63,15 @@ class DefaultValueObjectWriterTest
google::protobuf::scoped_ptr<DefaultValueObjectWriter> testing_;
};
+// Tests to cover some basic DefaultValueObjectWriter use cases. More tests are
+// in the marshalling_test.cc and translator_integration_test.cc.
+class DefaultValueObjectWriterTest : public BaseDefaultValueObjectWriterTest {
+ protected:
+ DefaultValueObjectWriterTest()
+ : BaseDefaultValueObjectWriterTest(DefaultValueTest::descriptor()) {}
+ virtual ~DefaultValueObjectWriterTest() {}
+};
+
INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
DefaultValueObjectWriterTest,
::testing::Values(
@@ -74,6 +81,8 @@ TEST_P(DefaultValueObjectWriterTest, Empty) {
// Set expectation
expects_.StartObject("")
->RenderDouble("doubleValue", 0.0)
+ ->StartList("repeatedDouble")
+ ->EndList()
->RenderFloat("floatValue", 0.0)
->RenderInt64("int64Value", 0)
->RenderUint64("uint64Value", 0)
@@ -82,6 +91,7 @@ TEST_P(DefaultValueObjectWriterTest, Empty) {
->RenderBool("boolValue", false)
->RenderString("stringValue", "")
->RenderBytes("bytesValue", "")
+ ->RenderString("enumValue", "ENUM_FIRST")
->EndObject();
// Actual testing
@@ -92,6 +102,8 @@ TEST_P(DefaultValueObjectWriterTest, NonDefaultDouble) {
// Set expectation
expects_.StartObject("")
->RenderDouble("doubleValue", 1.0)
+ ->StartList("repeatedDouble")
+ ->EndList()
->RenderFloat("floatValue", 0.0)
->RenderInt64("int64Value", 0)
->RenderUint64("uint64Value", 0)
@@ -99,6 +111,7 @@ TEST_P(DefaultValueObjectWriterTest, NonDefaultDouble) {
->RenderUint32("uint32Value", 0)
->RenderBool("boolValue", false)
->RenderString("stringValue", "")
+ ->RenderString("enumValue", "ENUM_FIRST")
->EndObject();
// Actual testing
@@ -109,6 +122,8 @@ TEST_P(DefaultValueObjectWriterTest, ShouldRetainUnknownField) {
// Set expectation
expects_.StartObject("")
->RenderDouble("doubleValue", 1.0)
+ ->StartList("repeatedDouble")
+ ->EndList()
->RenderFloat("floatValue", 0.0)
->RenderInt64("int64Value", 0)
->RenderUint64("uint64Value", 0)
@@ -120,6 +135,7 @@ TEST_P(DefaultValueObjectWriterTest, ShouldRetainUnknownField) {
->StartObject("unknownObject")
->RenderString("unknown", "def")
->EndObject()
+ ->RenderString("enumValue", "ENUM_FIRST")
->EndObject();
// Actual testing
@@ -132,6 +148,40 @@ TEST_P(DefaultValueObjectWriterTest, ShouldRetainUnknownField) {
->EndObject();
}
+
+class DefaultValueObjectWriterSuppressListTest
+ : public BaseDefaultValueObjectWriterTest {
+ protected:
+ DefaultValueObjectWriterSuppressListTest()
+ : BaseDefaultValueObjectWriterTest(DefaultValueTest::descriptor()) {
+ testing_->set_suppress_empty_list(true);
+ }
+ ~DefaultValueObjectWriterSuppressListTest() {}
+};
+
+INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
+ DefaultValueObjectWriterSuppressListTest,
+ ::testing::Values(
+ testing::USE_TYPE_RESOLVER));
+
+TEST_P(DefaultValueObjectWriterSuppressListTest, Empty) {
+ // Set expectation. Emtpy lists should be suppressed.
+ expects_.StartObject("")
+ ->RenderDouble("doubleValue", 0.0)
+ ->RenderFloat("floatValue", 0.0)
+ ->RenderInt64("int64Value", 0)
+ ->RenderUint64("uint64Value", 0)
+ ->RenderInt32("int32Value", 0)
+ ->RenderUint32("uint32Value", 0)
+ ->RenderBool("boolValue", false)
+ ->RenderString("stringValue", "")
+ ->RenderBytes("bytesValue", "")
+ ->RenderString("enumValue", "ENUM_FIRST")
+ ->EndObject();
+
+ // Actual testing
+ testing_->StartObject("")->EndObject();
+}
} // namespace testing
} // namespace converter
} // namespace util
diff --git a/src/google/protobuf/util/internal/error_listener.h b/src/google/protobuf/util/internal/error_listener.h
index 2699684d..3f063936 100644
--- a/src/google/protobuf/util/internal/error_listener.h
+++ b/src/google/protobuf/util/internal/error_listener.h
@@ -31,11 +31,13 @@
#ifndef GOOGLE_PROTOBUF_UTIL_CONVERTER_ERROR_LISTENER_H__
#define GOOGLE_PROTOBUF_UTIL_CONVERTER_ERROR_LISTENER_H__
+#include <algorithm>
#include <memory>
#ifndef _SHARED_PTR_H
#include <google/protobuf/stubs/shared_ptr.h>
#endif
#include <string>
+#include <vector>
#include <google/protobuf/stubs/callback.h>
#include <google/protobuf/stubs/common.h>
diff --git a/src/google/protobuf/util/internal/json_escaping.cc b/src/google/protobuf/util/internal/json_escaping.cc
index 36dc8ef9..06d2791b 100644
--- a/src/google/protobuf/util/internal/json_escaping.cc
+++ b/src/google/protobuf/util/internal/json_escaping.cc
@@ -186,7 +186,7 @@ bool ReadCodePoint(StringPiece str, int index,
uint32 *cp, int* num_left, int *num_read) {
if (*num_left == 0) {
// Last read was complete. Start reading a new unicode code point.
- *cp = str[index++];
+ *cp = static_cast<uint8>(str[index++]);
*num_read = 1;
// The length of the code point is determined from reading the first byte.
//
@@ -235,7 +235,7 @@ bool ReadCodePoint(StringPiece str, int index,
*num_read = 0;
}
while (*num_left > 0 && index < str.size()) {
- uint32 ch = str[index++];
+ uint32 ch = static_cast<uint8>(str[index++]);
--(*num_left);
++(*num_read);
*cp = (*cp << 6) | (ch & 0x3f);
@@ -255,7 +255,7 @@ StringPiece ToHex(uint16 cp, char* buffer) {
buffer[3] = kHex[cp & 0x0f];
cp >>= 4;
buffer[2] = kHex[cp & 0x0f];
- return StringPiece(buffer, 0, 6);
+ return StringPiece(buffer).substr(0, 6);
}
// Stores the 32-bit unicode code point as its hexadecimal digits in buffer
diff --git a/src/google/protobuf/util/internal/json_objectwriter.cc b/src/google/protobuf/util/internal/json_objectwriter.cc
index 94d2ab7a..b84210c1 100644
--- a/src/google/protobuf/util/internal/json_objectwriter.cc
+++ b/src/google/protobuf/util/internal/json_objectwriter.cc
@@ -46,6 +46,7 @@ namespace util {
namespace converter {
using strings::ArrayByteSource;
+;
JsonObjectWriter::~JsonObjectWriter() {
if (!element_->is_root()) {
@@ -81,13 +82,11 @@ JsonObjectWriter* JsonObjectWriter::EndList() {
return this;
}
-JsonObjectWriter* JsonObjectWriter::RenderBool(StringPiece name,
- bool value) {
+JsonObjectWriter* JsonObjectWriter::RenderBool(StringPiece name, bool value) {
return RenderSimple(name, value ? "true" : "false");
}
-JsonObjectWriter* JsonObjectWriter::RenderInt32(StringPiece name,
- int32 value) {
+JsonObjectWriter* JsonObjectWriter::RenderInt32(StringPiece name, int32 value) {
return RenderSimple(name, SimpleItoa(value));
}
@@ -96,8 +95,7 @@ JsonObjectWriter* JsonObjectWriter::RenderUint32(StringPiece name,
return RenderSimple(name, SimpleItoa(value));
}
-JsonObjectWriter* JsonObjectWriter::RenderInt64(StringPiece name,
- int64 value) {
+JsonObjectWriter* JsonObjectWriter::RenderInt64(StringPiece name, int64 value) {
WritePrefix(name);
WriteChar('"');
stream_->WriteString(SimpleItoa(value));
@@ -124,8 +122,7 @@ JsonObjectWriter* JsonObjectWriter::RenderDouble(StringPiece name,
return RenderString(name, DoubleAsString(value));
}
-JsonObjectWriter* JsonObjectWriter::RenderFloat(StringPiece name,
- float value) {
+JsonObjectWriter* JsonObjectWriter::RenderFloat(StringPiece name, float value) {
if (MathLimits<float>::IsFinite(value)) {
return RenderSimple(name, SimpleFtoa(value));
}
@@ -148,7 +145,12 @@ JsonObjectWriter* JsonObjectWriter::RenderBytes(StringPiece name,
StringPiece value) {
WritePrefix(name);
string base64;
- Base64Escape(value, &base64);
+
+ if (use_websafe_base64_for_bytes_)
+ WebSafeBase64Escape(value.ToString(), &base64);
+ else
+ Base64Escape(value, &base64);
+
WriteChar('"');
// TODO(wpoon): Consider a ByteSink solution that writes the base64 bytes
// directly to the stream, rather than first putting them
diff --git a/src/google/protobuf/util/internal/json_objectwriter.h b/src/google/protobuf/util/internal/json_objectwriter.h
index 761a0a10..cb7e2fb3 100644
--- a/src/google/protobuf/util/internal/json_objectwriter.h
+++ b/src/google/protobuf/util/internal/json_objectwriter.h
@@ -90,9 +90,10 @@ class LIBPROTOBUF_EXPORT JsonObjectWriter : public StructuredObjectWriter {
JsonObjectWriter(StringPiece indent_string,
google::protobuf::io::CodedOutputStream* out)
: element_(new Element(NULL)),
- stream_(out), sink_(out),
- indent_string_(indent_string.ToString()) {
- }
+ stream_(out),
+ sink_(out),
+ indent_string_(indent_string.ToString()),
+ use_websafe_base64_for_bytes_(false) {}
virtual ~JsonObjectWriter();
// ObjectWriter methods.
@@ -111,6 +112,10 @@ class LIBPROTOBUF_EXPORT JsonObjectWriter : public StructuredObjectWriter {
virtual JsonObjectWriter* RenderBytes(StringPiece name, StringPiece value);
virtual JsonObjectWriter* RenderNull(StringPiece name);
+ void set_use_websafe_base64_for_bytes(bool value) {
+ use_websafe_base64_for_bytes_ = value;
+ }
+
protected:
class LIBPROTOBUF_EXPORT Element : public BaseElement {
public:
@@ -195,6 +200,10 @@ class LIBPROTOBUF_EXPORT JsonObjectWriter : public StructuredObjectWriter {
ByteSinkWrapper sink_;
const string indent_string_;
+ // Whether to use regular or websafe base64 encoding for byte fields. Defaults
+ // to regular base64 encoding.
+ bool use_websafe_base64_for_bytes_;
+
GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(JsonObjectWriter);
};
diff --git a/src/google/protobuf/util/internal/json_objectwriter_test.cc b/src/google/protobuf/util/internal/json_objectwriter_test.cc
index dcd60601..b87b06ac 100644
--- a/src/google/protobuf/util/internal/json_objectwriter_test.cc
+++ b/src/google/protobuf/util/internal/json_objectwriter_test.cc
@@ -47,8 +47,7 @@ class JsonObjectWriterTest : public ::testing::Test {
JsonObjectWriterTest()
: str_stream_(new StringOutputStream(&output_)),
out_stream_(new CodedOutputStream(str_stream_)),
- ow_(NULL) {
- }
+ ow_(NULL) {}
virtual ~JsonObjectWriterTest() {
delete ow_;
@@ -59,41 +58,39 @@ class JsonObjectWriterTest : public ::testing::Test {
string output_;
StringOutputStream* const str_stream_;
CodedOutputStream* const out_stream_;
- ObjectWriter* ow_;
+ JsonObjectWriter* ow_;
};
TEST_F(JsonObjectWriterTest, EmptyRootObject) {
ow_ = new JsonObjectWriter("", out_stream_);
- ow_->StartObject("")
- ->EndObject();
+ ow_->StartObject("")->EndObject();
EXPECT_EQ("{}", output_.substr(0, out_stream_->ByteCount()));
}
TEST_F(JsonObjectWriterTest, EmptyObject) {
ow_ = new JsonObjectWriter("", out_stream_);
ow_->StartObject("")
- ->RenderString("test", "value")
- ->StartObject("empty")
- ->EndObject()
- ->EndObject();
+ ->RenderString("test", "value")
+ ->StartObject("empty")
+ ->EndObject()
+ ->EndObject();
EXPECT_EQ("{\"test\":\"value\",\"empty\":{}}",
output_.substr(0, out_stream_->ByteCount()));
}
TEST_F(JsonObjectWriterTest, EmptyRootList) {
ow_ = new JsonObjectWriter("", out_stream_);
- ow_->StartList("")
- ->EndList();
+ ow_->StartList("")->EndList();
EXPECT_EQ("[]", output_.substr(0, out_stream_->ByteCount()));
}
TEST_F(JsonObjectWriterTest, EmptyList) {
ow_ = new JsonObjectWriter("", out_stream_);
ow_->StartObject("")
- ->RenderString("test", "value")
- ->StartList("empty")
- ->EndList()
- ->EndObject();
+ ->RenderString("test", "value")
+ ->StartList("empty")
+ ->EndList()
+ ->EndObject();
EXPECT_EQ("{\"test\":\"value\",\"empty\":[]}",
output_.substr(0, out_stream_->ByteCount()));
}
@@ -101,10 +98,10 @@ TEST_F(JsonObjectWriterTest, EmptyList) {
TEST_F(JsonObjectWriterTest, ObjectInObject) {
ow_ = new JsonObjectWriter("", out_stream_);
ow_->StartObject("")
- ->StartObject("nested")
- ->RenderString("field", "value")
- ->EndObject()
- ->EndObject();
+ ->StartObject("nested")
+ ->RenderString("field", "value")
+ ->EndObject()
+ ->EndObject();
EXPECT_EQ("{\"nested\":{\"field\":\"value\"}}",
output_.substr(0, out_stream_->ByteCount()));
}
@@ -112,10 +109,10 @@ TEST_F(JsonObjectWriterTest, ObjectInObject) {
TEST_F(JsonObjectWriterTest, ListInObject) {
ow_ = new JsonObjectWriter("", out_stream_);
ow_->StartObject("")
- ->StartList("nested")
- ->RenderString("", "value")
- ->EndList()
- ->EndObject();
+ ->StartList("nested")
+ ->RenderString("", "value")
+ ->EndList()
+ ->EndObject();
EXPECT_EQ("{\"nested\":[\"value\"]}",
output_.substr(0, out_stream_->ByteCount()));
}
@@ -123,10 +120,10 @@ TEST_F(JsonObjectWriterTest, ListInObject) {
TEST_F(JsonObjectWriterTest, ObjectInList) {
ow_ = new JsonObjectWriter("", out_stream_);
ow_->StartList("")
- ->StartObject("")
- ->RenderString("field", "value")
- ->EndObject()
- ->EndList();
+ ->StartObject("")
+ ->RenderString("field", "value")
+ ->EndObject()
+ ->EndList();
EXPECT_EQ("[{\"field\":\"value\"}]",
output_.substr(0, out_stream_->ByteCount()));
}
@@ -134,10 +131,10 @@ TEST_F(JsonObjectWriterTest, ObjectInList) {
TEST_F(JsonObjectWriterTest, ListInList) {
ow_ = new JsonObjectWriter("", out_stream_);
ow_->StartList("")
- ->StartList("")
- ->RenderString("", "value")
- ->EndList()
- ->EndList();
+ ->StartList("")
+ ->RenderString("", "value")
+ ->EndList()
+ ->EndList();
EXPECT_EQ("[[\"value\"]]", output_.substr(0, out_stream_->ByteCount()));
}
@@ -156,14 +153,18 @@ TEST_F(JsonObjectWriterTest, RenderPrimitives) {
->EndObject();
EXPECT_EQ(
"{\"bool\":true,"
- "\"double\":" + ValueAsString<double>(1.7976931348623157e+308) + ","
- "\"float\":" + ValueAsString<float>(3.4028235e+38) + ","
- "\"int\":-2147483648,"
- "\"long\":\"-9223372036854775808\","
- "\"bytes\":\"YWJyYWNhZGFicmE=\","
- "\"string\":\"string\","
- "\"emptybytes\":\"\","
- "\"emptystring\":\"\"}",
+ "\"double\":" +
+ ValueAsString<double>(std::numeric_limits<double>::max()) +
+ ","
+ "\"float\":" +
+ ValueAsString<float>(std::numeric_limits<float>::max()) +
+ ","
+ "\"int\":-2147483648,"
+ "\"long\":\"-9223372036854775808\","
+ "\"bytes\":\"YWJyYWNhZGFicmE=\","
+ "\"string\":\"string\","
+ "\"emptybytes\":\"\","
+ "\"emptystring\":\"\"}",
output_.substr(0, out_stream_->ByteCount()));
}
@@ -181,81 +182,83 @@ TEST_F(JsonObjectWriterTest, BytesEncodesAsNonWebSafeBase64) {
TEST_F(JsonObjectWriterTest, PrettyPrintList) {
ow_ = new JsonObjectWriter(" ", out_stream_);
ow_->StartObject("")
- ->StartList("items")
- ->RenderString("", "item1")
- ->RenderString("", "item2")
- ->RenderString("", "item3")
- ->EndList()
- ->StartList("empty")
- ->EndList()
- ->EndObject();
- EXPECT_EQ("{\n"
- " \"items\": [\n"
- " \"item1\",\n"
- " \"item2\",\n"
- " \"item3\"\n"
- " ],\n"
- " \"empty\": []\n"
- "}\n",
- output_.substr(0, out_stream_->ByteCount()));
+ ->StartList("items")
+ ->RenderString("", "item1")
+ ->RenderString("", "item2")
+ ->RenderString("", "item3")
+ ->EndList()
+ ->StartList("empty")
+ ->EndList()
+ ->EndObject();
+ EXPECT_EQ(
+ "{\n"
+ " \"items\": [\n"
+ " \"item1\",\n"
+ " \"item2\",\n"
+ " \"item3\"\n"
+ " ],\n"
+ " \"empty\": []\n"
+ "}\n",
+ output_.substr(0, out_stream_->ByteCount()));
}
TEST_F(JsonObjectWriterTest, PrettyPrintObject) {
ow_ = new JsonObjectWriter(" ", out_stream_);
ow_->StartObject("")
- ->StartObject("items")
- ->RenderString("key1", "item1")
- ->RenderString("key2", "item2")
- ->RenderString("key3", "item3")
- ->EndObject()
- ->StartObject("empty")
- ->EndObject()
- ->EndObject();
- EXPECT_EQ("{\n"
- " \"items\": {\n"
- " \"key1\": \"item1\",\n"
- " \"key2\": \"item2\",\n"
- " \"key3\": \"item3\"\n"
- " },\n"
- " \"empty\": {}\n"
- "}\n",
- output_.substr(0, out_stream_->ByteCount()));
+ ->StartObject("items")
+ ->RenderString("key1", "item1")
+ ->RenderString("key2", "item2")
+ ->RenderString("key3", "item3")
+ ->EndObject()
+ ->StartObject("empty")
+ ->EndObject()
+ ->EndObject();
+ EXPECT_EQ(
+ "{\n"
+ " \"items\": {\n"
+ " \"key1\": \"item1\",\n"
+ " \"key2\": \"item2\",\n"
+ " \"key3\": \"item3\"\n"
+ " },\n"
+ " \"empty\": {}\n"
+ "}\n",
+ output_.substr(0, out_stream_->ByteCount()));
}
TEST_F(JsonObjectWriterTest, PrettyPrintEmptyObjectInEmptyList) {
ow_ = new JsonObjectWriter(" ", out_stream_);
ow_->StartObject("")
- ->StartList("list")
- ->StartObject("")
- ->EndObject()
- ->EndList()
- ->EndObject();
- EXPECT_EQ("{\n"
- " \"list\": [\n"
- " {}\n"
- " ]\n"
- "}\n",
- output_.substr(0, out_stream_->ByteCount()));
+ ->StartList("list")
+ ->StartObject("")
+ ->EndObject()
+ ->EndList()
+ ->EndObject();
+ EXPECT_EQ(
+ "{\n"
+ " \"list\": [\n"
+ " {}\n"
+ " ]\n"
+ "}\n",
+ output_.substr(0, out_stream_->ByteCount()));
}
TEST_F(JsonObjectWriterTest, PrettyPrintDoubleIndent) {
ow_ = new JsonObjectWriter(" ", out_stream_);
ow_->StartObject("")
- ->RenderBool("bool", true)
- ->RenderInt32("int", 42)
- ->EndObject();
- EXPECT_EQ("{\n"
- " \"bool\": true,\n"
- " \"int\": 42\n"
- "}\n",
- output_.substr(0, out_stream_->ByteCount()));
+ ->RenderBool("bool", true)
+ ->RenderInt32("int", 42)
+ ->EndObject();
+ EXPECT_EQ(
+ "{\n"
+ " \"bool\": true,\n"
+ " \"int\": 42\n"
+ "}\n",
+ output_.substr(0, out_stream_->ByteCount()));
}
TEST_F(JsonObjectWriterTest, StringsEscapedAndEnclosedInDoubleQuotes) {
ow_ = new JsonObjectWriter("", out_stream_);
- ow_->StartObject("")
- ->RenderString("string", "'<>&amp;\\\"\r\n")
- ->EndObject();
+ ow_->StartObject("")->RenderString("string", "'<>&amp;\\\"\r\n")->EndObject();
EXPECT_EQ("{\"string\":\"'\\u003c\\u003e&amp;\\\\\\\"\\r\\n\"}",
output_.substr(0, out_stream_->ByteCount()));
}
@@ -263,13 +266,13 @@ TEST_F(JsonObjectWriterTest, StringsEscapedAndEnclosedInDoubleQuotes) {
TEST_F(JsonObjectWriterTest, Stringification) {
ow_ = new JsonObjectWriter("", out_stream_);
ow_->StartObject("")
- ->RenderDouble("double_nan", std::numeric_limits<double>::quiet_NaN())
- ->RenderFloat("float_nan", std::numeric_limits<float>::quiet_NaN())
- ->RenderDouble("double_pos", std::numeric_limits<double>::infinity())
- ->RenderFloat("float_pos", std::numeric_limits<float>::infinity())
- ->RenderDouble("double_neg", -std::numeric_limits<double>::infinity())
- ->RenderFloat("float_neg", -std::numeric_limits<float>::infinity())
- ->EndObject();
+ ->RenderDouble("double_nan", std::numeric_limits<double>::quiet_NaN())
+ ->RenderFloat("float_nan", std::numeric_limits<float>::quiet_NaN())
+ ->RenderDouble("double_pos", std::numeric_limits<double>::infinity())
+ ->RenderFloat("float_pos", std::numeric_limits<float>::infinity())
+ ->RenderDouble("double_neg", -std::numeric_limits<double>::infinity())
+ ->RenderFloat("float_neg", -std::numeric_limits<float>::infinity())
+ ->EndObject();
EXPECT_EQ(
"{\"double_nan\":\"NaN\","
"\"float_nan\":\"NaN\","
@@ -280,6 +283,30 @@ TEST_F(JsonObjectWriterTest, Stringification) {
output_.substr(0, out_stream_->ByteCount()));
}
+TEST_F(JsonObjectWriterTest, TestRegularByteEncoding) {
+ ow_ = new JsonObjectWriter("", out_stream_);
+ ow_->StartObject("")
+ ->RenderBytes("bytes", "\x03\xef\xc0")
+ ->EndObject();
+
+ // Test that we get regular (non websafe) base64 encoding on byte fields by
+ // default.
+ EXPECT_EQ("{\"bytes\":\"A+/A\"}",
+ output_.substr(0, out_stream_->ByteCount()));
+}
+
+TEST_F(JsonObjectWriterTest, TestWebsafeByteEncoding) {
+ ow_ = new JsonObjectWriter("", out_stream_);
+ ow_->set_use_websafe_base64_for_bytes(true);
+ ow_->StartObject("")
+ ->RenderBytes("bytes", "\x03\xef\xc0")
+ ->EndObject();
+
+ // Test that we get websafe base64 encoding when explicitly asked.
+ EXPECT_EQ("{\"bytes\":\"A-_A\"}",
+ output_.substr(0, out_stream_->ByteCount()));
+}
+
} // namespace converter
} // namespace util
} // namespace protobuf
diff --git a/src/google/protobuf/util/internal/json_stream_parser.cc b/src/google/protobuf/util/internal/json_stream_parser.cc
index a7ef7fe2..39be7b03 100644
--- a/src/google/protobuf/util/internal/json_stream_parser.cc
+++ b/src/google/protobuf/util/internal/json_stream_parser.cc
@@ -42,8 +42,9 @@
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/util/internal/object_writer.h>
+#include <google/protobuf/util/internal/json_escaping.h>
+#include <google/protobuf/stubs/strutil.h>
namespace google {
namespace protobuf {
@@ -59,7 +60,7 @@ using util::error::INVALID_ARGUMENT;
namespace converter {
-// Number of digits in a unicode escape sequence (/uXXXX)
+// Number of digits in an escaped UTF-16 code unit ('\\' 'u' X X X X)
static const int kUnicodeEscapedLength = 6;
// Length of the true, false, and null literals.
@@ -157,10 +158,10 @@ util::Status JsonStreamParser::FinishParse() {
char* coerced = internal::UTF8CoerceToStructurallyValid(leftover_, utf8.get(), ' ');
p_ = json_ = StringPiece(coerced, leftover_.size());
} else {
+ p_ = json_ = leftover_;
if (!internal::IsStructurallyValidUTF8(leftover_)) {
return ReportFailure("Encountered non UTF-8 code points.");
}
- p_ = json_ = leftover_;
}
// Parse the remainder in finishing mode, which reports errors for things like
@@ -419,9 +420,45 @@ util::Status JsonStreamParser::ParseUnicodeEscape() {
}
code = (code << 4) + hex_digit_to_int(p_.data()[i]);
}
+ if (code >= JsonEscaping::kMinHighSurrogate &&
+ code <= JsonEscaping::kMaxHighSurrogate) {
+ if (p_.length() < 2 * kUnicodeEscapedLength) {
+ if (!finishing_) {
+ return util::Status::CANCELLED;
+ }
+ if (!coerce_to_utf8_) {
+ return ReportFailure("Missing low surrogate.");
+ }
+ } else if (p_.data()[kUnicodeEscapedLength] == '\\' &&
+ p_.data()[kUnicodeEscapedLength + 1] == 'u') {
+ uint32 low_code = 0;
+ for (int i = kUnicodeEscapedLength + 2; i < 2 * kUnicodeEscapedLength;
+ ++i) {
+ if (!isxdigit(p_.data()[i])) {
+ return ReportFailure("Invalid escape sequence.");
+ }
+ low_code = (low_code << 4) + hex_digit_to_int(p_.data()[i]);
+ }
+ if (low_code >= JsonEscaping::kMinLowSurrogate &&
+ low_code <= JsonEscaping::kMaxLowSurrogate) {
+ // Convert UTF-16 surrogate pair to 21-bit Unicode codepoint.
+ code = (((code & 0x3FF) << 10) | (low_code & 0x3FF)) +
+ JsonEscaping::kMinSupplementaryCodePoint;
+ // Advance past the first code unit escape.
+ p_.remove_prefix(kUnicodeEscapedLength);
+ } else if (!coerce_to_utf8_) {
+ return ReportFailure("Invalid low surrogate.");
+ }
+ } else if (!coerce_to_utf8_) {
+ return ReportFailure("Missing low surrogate.");
+ }
+ }
+ if (!coerce_to_utf8_ && !IsValidCodePoint(code)) {
+ return ReportFailure("Invalid unicode code point.");
+ }
char buf[UTFmax];
int len = EncodeAsUTF8Char(code, buf);
- // Advance past the unicode escape.
+ // Advance past the [final] code unit escape.
p_.remove_prefix(kUnicodeEscapedLength);
parsed_storage_.append(buf, len);
return util::Status::OK;
@@ -473,7 +510,7 @@ util::Status JsonStreamParser::ParseNumberHelper(NumberResult* result) {
floating = true;
continue;
}
- if (c == '+' || c == '-') continue;
+ if (c == '+' || c == '-' || c == 'x') continue;
// Not a valid number character, break out.
break;
}
@@ -499,6 +536,10 @@ util::Status JsonStreamParser::ParseNumberHelper(NumberResult* result) {
// Positive non-floating point number, parse as a uint64.
if (!negative) {
+ // Octal/Hex numbers are not valid JSON values.
+ if (number.length() >= 2 && number[0] == '0') {
+ return ReportFailure("Octal/hex numbers are not valid JSON values.");
+ }
if (!safe_strtou64(number, &result->uint_val)) {
return ReportFailure("Unable to parse number.");
}
@@ -507,6 +548,10 @@ util::Status JsonStreamParser::ParseNumberHelper(NumberResult* result) {
return util::Status::OK;
}
+ // Octal/Hex numbers are not valid JSON values.
+ if (number.length() >= 3 && number[1] == '0') {
+ return ReportFailure("Octal/hex numbers are not valid JSON values.");
+ }
// Negative non-floating point number, parse as an int64.
if (!safe_strto64(number, &result->int_val)) {
return ReportFailure("Unable to parse number.");
@@ -677,8 +722,9 @@ util::Status JsonStreamParser::ReportFailure(StringPiece message) {
static const int kContextLength = 20;
const char* p_start = p_.data();
const char* json_start = json_.data();
- const char* begin = max(p_start - kContextLength, json_start);
- const char* end = min(p_start + kContextLength, json_start + json_.size());
+ const char* begin = std::max(p_start - kContextLength, json_start);
+ const char* end =
+ std::min(p_start + kContextLength, json_start + json_.size());
StringPiece segment(begin, end - begin);
string location(p_start - begin, ' ');
location.push_back('^');
@@ -706,8 +752,8 @@ void JsonStreamParser::SkipWhitespace() {
void JsonStreamParser::Advance() {
// Advance by moving one UTF8 character while making sure we don't go beyond
// the length of StringPiece.
- p_.remove_prefix(
- min<int>(p_.length(), UTF8FirstLetterNumBytes(p_.data(), p_.length())));
+ p_.remove_prefix(std::min<int>(
+ p_.length(), UTF8FirstLetterNumBytes(p_.data(), p_.length())));
}
util::Status JsonStreamParser::ParseKey() {
diff --git a/src/google/protobuf/util/internal/json_stream_parser_test.cc b/src/google/protobuf/util/internal/json_stream_parser_test.cc
index c833ed1f..059ea6d8 100644
--- a/src/google/protobuf/util/internal/json_stream_parser_test.cc
+++ b/src/google/protobuf/util/internal/json_stream_parser_test.cc
@@ -124,8 +124,9 @@ class JsonStreamParserTest : public ::testing::Test {
EXPECT_OK(result);
}
- void DoErrorTest(StringPiece json, int split, StringPiece error_prefix) {
- util::Status result = RunTest(json, split);
+ void DoErrorTest(StringPiece json, int split, StringPiece error_prefix,
+ bool coerce_utf8 = false) {
+ util::Status result = RunTest(json, split, coerce_utf8);
EXPECT_EQ(util::error::INVALID_ARGUMENT, result.error_code());
StringPiece error_message(result.error_message());
EXPECT_EQ(error_prefix, error_message.substr(0, error_prefix.size()));
@@ -230,6 +231,32 @@ TEST_F(JsonStreamParserTest, SimpleUnsignedInt) {
}
}
+TEST_F(JsonStreamParserTest, OctalNumberIsInvalid) {
+ StringPiece str = "01234";
+ for (int i = 0; i <= str.length(); ++i) {
+ DoErrorTest(str, i, "Octal/hex numbers are not valid JSON values.");
+ }
+ str = "-01234";
+ for (int i = 0; i <= str.length(); ++i) {
+ DoErrorTest(str, i, "Octal/hex numbers are not valid JSON values.");
+ }
+}
+
+TEST_F(JsonStreamParserTest, HexNumberIsInvalid) {
+ StringPiece str = "0x1234";
+ for (int i = 0; i <= str.length(); ++i) {
+ DoErrorTest(str, i, "Octal/hex numbers are not valid JSON values.");
+ }
+ str = "-0x1234";
+ for (int i = 0; i <= str.length(); ++i) {
+ DoErrorTest(str, i, "Octal/hex numbers are not valid JSON values.");
+ }
+ str = "12x34";
+ for (int i = 0; i <= str.length(); ++i) {
+ DoErrorTest(str, i, "Unable to parse number.");
+ }
+}
+
// - single and double quoted strings
TEST_F(JsonStreamParserTest, EmptyDoubleQuotedString) {
StringPiece str = "\"\"";
@@ -348,21 +375,65 @@ TEST_F(JsonStreamParserTest, RejectNonUtf8WhenNotCoerced) {
for (int i = 0; i <= json.length(); ++i) {
DoErrorTest(json, i, "Encountered non UTF-8 code points.");
}
+ DoErrorTest("\xFF{}", 0, "Encountered non UTF-8 code points.");
}
-#ifndef _MSC_VER
// - unicode handling in strings
TEST_F(JsonStreamParserTest, UnicodeEscaping) {
StringPiece str = "[\"\\u0639\\u0631\\u0628\\u0649\"]";
for (int i = 0; i <= str.length(); ++i) {
- // TODO(xiaofeng): Figure out what default encoding to use for JSON strings.
- // In protobuf we use UTF-8 for strings, but for JSON we probably should
- // allow different encodings?
- ow_.StartList("")->RenderString("", "\u0639\u0631\u0628\u0649")->EndList();
+ ow_.StartList("")
+ ->RenderString("", "\xD8\xB9\xD8\xB1\xD8\xA8\xD9\x89")
+ ->EndList();
+ DoTest(str, i);
+ }
+}
+
+// - unicode UTF-16 surrogate pair handling in strings
+TEST_F(JsonStreamParserTest, UnicodeSurrogatePairEscaping) {
+ StringPiece str =
+ "[\"\\u0bee\\ud800\\uddf1\\uD80C\\uDDA4\\uD83d\\udC1D\\uD83C\\uDF6F\"]";
+ for (int i = 0; i <= str.length(); ++i) {
+ ow_.StartList("")
+ ->RenderString("",
+ "\xE0\xAF\xAE\xF0\x90\x87\xB1\xF0\x93\x86\xA4\xF0"
+ "\x9F\x90\x9D\xF0\x9F\x8D\xAF")
+ ->EndList();
DoTest(str, i);
}
}
-#endif
+
+
+TEST_F(JsonStreamParserTest, UnicodeEscapingInvalidCodePointWhenNotCoerced) {
+ // A low surrogate alone.
+ StringPiece str = "[\"\\ude36\"]";
+ for (int i = 0; i <= str.length(); ++i) {
+ DoErrorTest(str, i, "Invalid unicode code point.");
+ }
+}
+
+TEST_F(JsonStreamParserTest, UnicodeEscapingMissingLowSurrogateWhenNotCoerced) {
+ // A high surrogate alone.
+ StringPiece str = "[\"\\ud83d\"]";
+ for (int i = 0; i <= str.length(); ++i) {
+ DoErrorTest(str, i, "Missing low surrogate.");
+ }
+ // A high surrogate with some trailing characters.
+ str = "[\"\\ud83d|ude36\"]";
+ for (int i = 0; i <= str.length(); ++i) {
+ DoErrorTest(str, i, "Missing low surrogate.");
+ }
+ // A high surrogate with half a low surrogate.
+ str = "[\"\\ud83d\\ude--\"]";
+ for (int i = 0; i <= str.length(); ++i) {
+ DoErrorTest(str, i, "Invalid escape sequence.");
+ }
+ // Two high surrogates.
+ str = "[\"\\ud83d\\ud83d\"]";
+ for (int i = 0; i <= str.length(); ++i) {
+ DoErrorTest(str, i, "Invalid low surrogate.");
+ }
+}
// - ascii escaping (\b, \f, \n, \r, \t, \v)
TEST_F(JsonStreamParserTest, AsciiEscaping) {
@@ -628,6 +699,22 @@ TEST_F(JsonStreamParserTest, DoubleTooBig) {
}
*/
+// invalid bare backslash.
+TEST_F(JsonStreamParserTest, UnfinishedEscape) {
+ StringPiece str = "\"\\";
+ for (int i = 0; i <= str.length(); ++i) {
+ DoErrorTest(str, i, "Closing quote expected in string.");
+ }
+}
+
+// invalid bare backslash u.
+TEST_F(JsonStreamParserTest, UnfinishedUnicodeEscape) {
+ StringPiece str = "\"\\u";
+ for (int i = 0; i <= str.length(); ++i) {
+ DoErrorTest(str, i, "Illegal hex string.");
+ }
+}
+
// invalid unicode sequence.
TEST_F(JsonStreamParserTest, UnicodeEscapeCutOff) {
StringPiece str = "\"\\u12";
@@ -636,6 +723,15 @@ TEST_F(JsonStreamParserTest, UnicodeEscapeCutOff) {
}
}
+// invalid unicode sequence (valid in modern EcmaScript but not in JSON).
+TEST_F(JsonStreamParserTest, BracketedUnicodeEscape) {
+ StringPiece str = "\"\\u{1f36f}\"";
+ for (int i = 0; i <= str.length(); ++i) {
+ DoErrorTest(str, i, "Invalid escape sequence.");
+ }
+}
+
+
TEST_F(JsonStreamParserTest, UnicodeEscapeInvalidCharacters) {
StringPiece str = "\"\\u12$4hello";
for (int i = 0; i <= str.length(); ++i) {
@@ -643,6 +739,14 @@ TEST_F(JsonStreamParserTest, UnicodeEscapeInvalidCharacters) {
}
}
+// invalid unicode sequence in low half surrogate: g is not a hex digit.
+TEST_F(JsonStreamParserTest, UnicodeEscapeLowHalfSurrogateInvalidCharacters) {
+ StringPiece str = "\"\\ud800\\udcfg\"";
+ for (int i = 0; i <= str.length(); ++i) {
+ DoErrorTest(str, i, "Invalid escape sequence.");
+ }
+}
+
// Extra commas with an object or array.
TEST_F(JsonStreamParserTest, ExtraCommaInObject) {
StringPiece str = "{'k1': true,,'k2': false}";
diff --git a/src/google/protobuf/util/internal/object_writer.h b/src/google/protobuf/util/internal/object_writer.h
index 20bd3627..5781aa1e 100644
--- a/src/google/protobuf/util/internal/object_writer.h
+++ b/src/google/protobuf/util/internal/object_writer.h
@@ -101,19 +101,32 @@ class LIBPROTOBUF_EXPORT ObjectWriter {
// Renders a Null value.
virtual ObjectWriter* RenderNull(StringPiece name) = 0;
- // Disables case normalization. Any RenderTYPE call after calling this
- // function will output the name field as-is. No normalization is attempted on
- // it. This setting is reset immediately after the next RenderTYPE is called.
- virtual ObjectWriter* DisableCaseNormalizationForNextKey() { return this; }
// Renders a DataPiece object to a ObjectWriter.
static void RenderDataPieceTo(const DataPiece& data, StringPiece name,
ObjectWriter* ow);
+ // Indicates whether this ObjectWriter has completed writing the root message,
+ // usually this means writing of one complete object. Subclasses must override
+ // this behavior appropriately.
+ virtual bool done() { return false; }
+
+ void set_use_strict_base64_decoding(bool value) {
+ use_strict_base64_decoding_ = value;
+ }
+
+ bool use_strict_base64_decoding() const {
+ return use_strict_base64_decoding_;
+ }
+
protected:
- ObjectWriter() {}
+ ObjectWriter() : use_strict_base64_decoding_(true) {}
private:
+ // If set to true, we use the stricter version of base64 decoding for byte
+ // fields by making sure decoded version encodes back to the original string.
+ bool use_strict_base64_decoding_;
+
// Do not add any data members to this class.
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ObjectWriter);
};
diff --git a/src/google/protobuf/util/internal/proto_writer.cc b/src/google/protobuf/util/internal/proto_writer.cc
new file mode 100644
index 00000000..0c38aeb9
--- /dev/null
+++ b/src/google/protobuf/util/internal/proto_writer.cc
@@ -0,0 +1,796 @@
+// 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 <google/protobuf/util/internal/proto_writer.h>
+
+#include <functional>
+#include <stack>
+
+#include <google/protobuf/stubs/once.h>
+#include <google/protobuf/stubs/time.h>
+#include <google/protobuf/wire_format_lite.h>
+#include <google/protobuf/util/internal/field_mask_utility.h>
+#include <google/protobuf/util/internal/object_location_tracker.h>
+#include <google/protobuf/util/internal/constants.h>
+#include <google/protobuf/util/internal/utility.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/map_util.h>
+#include <google/protobuf/stubs/statusor.h>
+
+
+namespace google {
+namespace protobuf {
+namespace util {
+namespace converter {
+
+using google::protobuf::internal::WireFormatLite;
+using google::protobuf::io::CodedOutputStream;
+using util::error::INVALID_ARGUMENT;
+using util::Status;
+using util::StatusOr;
+
+
+ProtoWriter::ProtoWriter(TypeResolver* type_resolver,
+ const google::protobuf::Type& type,
+ strings::ByteSink* output, ErrorListener* listener)
+ : master_type_(type),
+ typeinfo_(TypeInfo::NewTypeInfo(type_resolver)),
+ own_typeinfo_(true),
+ done_(false),
+ ignore_unknown_fields_(false),
+ element_(NULL),
+ size_insert_(),
+ output_(output),
+ buffer_(),
+ adapter_(&buffer_),
+ stream_(new CodedOutputStream(&adapter_)),
+ listener_(listener),
+ invalid_depth_(0),
+ tracker_(new ObjectLocationTracker()) {}
+
+ProtoWriter::ProtoWriter(const TypeInfo* typeinfo,
+ const google::protobuf::Type& type,
+ strings::ByteSink* output, ErrorListener* listener)
+ : master_type_(type),
+ typeinfo_(typeinfo),
+ own_typeinfo_(false),
+ done_(false),
+ ignore_unknown_fields_(false),
+ element_(NULL),
+ size_insert_(),
+ output_(output),
+ buffer_(),
+ adapter_(&buffer_),
+ stream_(new CodedOutputStream(&adapter_)),
+ listener_(listener),
+ invalid_depth_(0),
+ tracker_(new ObjectLocationTracker()) {}
+
+ProtoWriter::~ProtoWriter() {
+ if (own_typeinfo_) {
+ delete typeinfo_;
+ }
+ if (element_ == NULL) return;
+ // Cleanup explicitly in order to avoid destructor stack overflow when input
+ // is deeply nested.
+ // Cast to BaseElement to avoid doing additional checks (like missing fields)
+ // during pop().
+ google::protobuf::scoped_ptr<BaseElement> element(
+ static_cast<BaseElement*>(element_.get())->pop<BaseElement>());
+ while (element != NULL) {
+ element.reset(element->pop<BaseElement>());
+ }
+}
+
+namespace {
+
+// Writes an INT32 field, including tag to the stream.
+inline Status WriteInt32(int field_number, const DataPiece& data,
+ CodedOutputStream* stream) {
+ StatusOr<int32> i32 = data.ToInt32();
+ if (i32.ok()) {
+ WireFormatLite::WriteInt32(field_number, i32.ValueOrDie(), stream);
+ }
+ return i32.status();
+}
+
+// writes an SFIXED32 field, including tag, to the stream.
+inline Status WriteSFixed32(int field_number, const DataPiece& data,
+ CodedOutputStream* stream) {
+ StatusOr<int32> i32 = data.ToInt32();
+ if (i32.ok()) {
+ WireFormatLite::WriteSFixed32(field_number, i32.ValueOrDie(), stream);
+ }
+ return i32.status();
+}
+
+// Writes an SINT32 field, including tag, to the stream.
+inline Status WriteSInt32(int field_number, const DataPiece& data,
+ CodedOutputStream* stream) {
+ StatusOr<int32> i32 = data.ToInt32();
+ if (i32.ok()) {
+ WireFormatLite::WriteSInt32(field_number, i32.ValueOrDie(), stream);
+ }
+ return i32.status();
+}
+
+// Writes a FIXED32 field, including tag, to the stream.
+inline Status WriteFixed32(int field_number, const DataPiece& data,
+ CodedOutputStream* stream) {
+ StatusOr<uint32> u32 = data.ToUint32();
+ if (u32.ok()) {
+ WireFormatLite::WriteFixed32(field_number, u32.ValueOrDie(), stream);
+ }
+ return u32.status();
+}
+
+// Writes a UINT32 field, including tag, to the stream.
+inline Status WriteUInt32(int field_number, const DataPiece& data,
+ CodedOutputStream* stream) {
+ StatusOr<uint32> u32 = data.ToUint32();
+ if (u32.ok()) {
+ WireFormatLite::WriteUInt32(field_number, u32.ValueOrDie(), stream);
+ }
+ return u32.status();
+}
+
+// Writes an INT64 field, including tag, to the stream.
+inline Status WriteInt64(int field_number, const DataPiece& data,
+ CodedOutputStream* stream) {
+ StatusOr<int64> i64 = data.ToInt64();
+ if (i64.ok()) {
+ WireFormatLite::WriteInt64(field_number, i64.ValueOrDie(), stream);
+ }
+ return i64.status();
+}
+
+// Writes an SFIXED64 field, including tag, to the stream.
+inline Status WriteSFixed64(int field_number, const DataPiece& data,
+ CodedOutputStream* stream) {
+ StatusOr<int64> i64 = data.ToInt64();
+ if (i64.ok()) {
+ WireFormatLite::WriteSFixed64(field_number, i64.ValueOrDie(), stream);
+ }
+ return i64.status();
+}
+
+// Writes an SINT64 field, including tag, to the stream.
+inline Status WriteSInt64(int field_number, const DataPiece& data,
+ CodedOutputStream* stream) {
+ StatusOr<int64> i64 = data.ToInt64();
+ if (i64.ok()) {
+ WireFormatLite::WriteSInt64(field_number, i64.ValueOrDie(), stream);
+ }
+ return i64.status();
+}
+
+// Writes a FIXED64 field, including tag, to the stream.
+inline Status WriteFixed64(int field_number, const DataPiece& data,
+ CodedOutputStream* stream) {
+ StatusOr<uint64> u64 = data.ToUint64();
+ if (u64.ok()) {
+ WireFormatLite::WriteFixed64(field_number, u64.ValueOrDie(), stream);
+ }
+ return u64.status();
+}
+
+// Writes a UINT64 field, including tag, to the stream.
+inline Status WriteUInt64(int field_number, const DataPiece& data,
+ CodedOutputStream* stream) {
+ StatusOr<uint64> u64 = data.ToUint64();
+ if (u64.ok()) {
+ WireFormatLite::WriteUInt64(field_number, u64.ValueOrDie(), stream);
+ }
+ return u64.status();
+}
+
+// Writes a DOUBLE field, including tag, to the stream.
+inline Status WriteDouble(int field_number, const DataPiece& data,
+ CodedOutputStream* stream) {
+ StatusOr<double> d = data.ToDouble();
+ if (d.ok()) {
+ WireFormatLite::WriteDouble(field_number, d.ValueOrDie(), stream);
+ }
+ return d.status();
+}
+
+// Writes a FLOAT field, including tag, to the stream.
+inline Status WriteFloat(int field_number, const DataPiece& data,
+ CodedOutputStream* stream) {
+ StatusOr<float> f = data.ToFloat();
+ if (f.ok()) {
+ WireFormatLite::WriteFloat(field_number, f.ValueOrDie(), stream);
+ }
+ return f.status();
+}
+
+// Writes a BOOL field, including tag, to the stream.
+inline Status WriteBool(int field_number, const DataPiece& data,
+ CodedOutputStream* stream) {
+ StatusOr<bool> b = data.ToBool();
+ if (b.ok()) {
+ WireFormatLite::WriteBool(field_number, b.ValueOrDie(), stream);
+ }
+ return b.status();
+}
+
+// Writes a BYTES field, including tag, to the stream.
+inline Status WriteBytes(int field_number, const DataPiece& data,
+ CodedOutputStream* stream) {
+ StatusOr<string> c = data.ToBytes();
+ if (c.ok()) {
+ WireFormatLite::WriteBytes(field_number, c.ValueOrDie(), stream);
+ }
+ return c.status();
+}
+
+// Writes a STRING field, including tag, to the stream.
+inline Status WriteString(int field_number, const DataPiece& data,
+ CodedOutputStream* stream) {
+ StatusOr<string> s = data.ToString();
+ if (s.ok()) {
+ WireFormatLite::WriteString(field_number, s.ValueOrDie(), stream);
+ }
+ return s.status();
+}
+
+// Writes an ENUM field, including tag, to the stream.
+inline Status WriteEnum(int field_number, const DataPiece& data,
+ const google::protobuf::Enum* enum_type,
+ CodedOutputStream* stream) {
+ StatusOr<int> e = data.ToEnum(enum_type);
+ if (e.ok()) {
+ WireFormatLite::WriteEnum(field_number, e.ValueOrDie(), stream);
+ }
+ return e.status();
+}
+
+// Given a google::protobuf::Type, returns the set of all required fields.
+std::set<const google::protobuf::Field*> GetRequiredFields(
+ const google::protobuf::Type& type) {
+ std::set<const google::protobuf::Field*> required;
+ for (int i = 0; i < type.fields_size(); i++) {
+ const google::protobuf::Field& field = type.fields(i);
+ if (field.cardinality() ==
+ google::protobuf::Field_Cardinality_CARDINALITY_REQUIRED) {
+ required.insert(&field);
+ }
+ }
+ return required;
+}
+
+} // namespace
+
+ProtoWriter::ProtoElement::ProtoElement(const TypeInfo* typeinfo,
+ const google::protobuf::Type& type,
+ ProtoWriter* enclosing)
+ : BaseElement(NULL),
+ ow_(enclosing),
+ parent_field_(NULL),
+ typeinfo_(typeinfo),
+ proto3_(type.syntax() == google::protobuf::SYNTAX_PROTO3),
+ type_(type),
+ size_index_(-1),
+ array_index_(-1),
+ // oneof_indices_ values are 1-indexed (0 means not present).
+ oneof_indices_(type.oneofs_size() + 1) {
+ if (!proto3_) {
+ required_fields_ = GetRequiredFields(type_);
+ }
+}
+
+ProtoWriter::ProtoElement::ProtoElement(ProtoWriter::ProtoElement* parent,
+ const google::protobuf::Field* field,
+ const google::protobuf::Type& type,
+ bool is_list)
+ : BaseElement(parent),
+ ow_(this->parent()->ow_),
+ parent_field_(field),
+ typeinfo_(this->parent()->typeinfo_),
+ proto3_(type.syntax() == google::protobuf::SYNTAX_PROTO3),
+ type_(type),
+ size_index_(
+ !is_list && field->kind() == google::protobuf::Field_Kind_TYPE_MESSAGE
+ ? ow_->size_insert_.size()
+ : -1),
+ array_index_(is_list ? 0 : -1),
+ // oneof_indices_ values are 1-indexed (0 means not present).
+ oneof_indices_(type_.oneofs_size() + 1) {
+ if (!is_list) {
+ if (ow_->IsRepeated(*field)) {
+ // Update array_index_ if it is an explicit list.
+ if (this->parent()->array_index_ >= 0) this->parent()->array_index_++;
+ } else if (!proto3_) {
+ // For required fields tracking.
+ this->parent()->RegisterField(field);
+ }
+
+ if (field->kind() == google::protobuf::Field_Kind_TYPE_MESSAGE) {
+ if (!proto3_) {
+ required_fields_ = GetRequiredFields(type_);
+ }
+ int start_pos = ow_->stream_->ByteCount();
+ // length of serialized message is the final buffer position minus
+ // starting buffer position, plus length adjustments for size fields
+ // of any nested messages. We start with -start_pos here, so we only
+ // need to add the final buffer position to it at the end.
+ SizeInfo info = {start_pos, -start_pos};
+ ow_->size_insert_.push_back(info);
+ }
+ }
+}
+
+ProtoWriter::ProtoElement* ProtoWriter::ProtoElement::pop() {
+ if (!proto3_) {
+ // Calls the registered error listener for any required field(s) not yet
+ // seen.
+ for (set<const google::protobuf::Field*>::iterator it =
+ required_fields_.begin();
+ it != required_fields_.end(); ++it) {
+ ow_->MissingField((*it)->name());
+ }
+ }
+ // Computes the total number of proto bytes used by a message, also adjusts
+ // the size of all parent messages by the length of this size field.
+ // If size_index_ < 0, this is not a message, so no size field is added.
+ if (size_index_ >= 0) {
+ // Add the final buffer position to compute the total length of this
+ // serialized message. The stored value (before this addition) already
+ // contains the total length of the size fields of all nested messages
+ // minus the initial buffer position.
+ ow_->size_insert_[size_index_].size += ow_->stream_->ByteCount();
+ // Calculate the length required to serialize the size field of the
+ // message, and propagate this additional size information upward to
+ // all enclosing messages.
+ int size = ow_->size_insert_[size_index_].size;
+ int length = CodedOutputStream::VarintSize32(size);
+ for (ProtoElement* e = parent(); e != NULL; e = e->parent()) {
+ // Only nested messages have size field, lists do not have size field.
+ if (e->size_index_ >= 0) {
+ ow_->size_insert_[e->size_index_].size += length;
+ }
+ }
+ }
+ return BaseElement::pop<ProtoElement>();
+}
+
+void ProtoWriter::ProtoElement::RegisterField(
+ const google::protobuf::Field* field) {
+ if (!required_fields_.empty() &&
+ field->cardinality() ==
+ google::protobuf::Field_Cardinality_CARDINALITY_REQUIRED) {
+ required_fields_.erase(field);
+ }
+}
+
+string ProtoWriter::ProtoElement::ToString() const {
+ if (parent() == NULL) return "";
+ string loc = parent()->ToString();
+ if (!ow_->IsRepeated(*parent_field_) ||
+ parent()->parent_field_ != parent_field_) {
+ string name = parent_field_->name();
+ int i = 0;
+ while (i < name.size() && (ascii_isalnum(name[i]) || name[i] == '_')) ++i;
+ if (i > 0 && i == name.size()) { // safe field name
+ if (loc.empty()) {
+ loc = name;
+ } else {
+ StrAppend(&loc, ".", name);
+ }
+ } else {
+ StrAppend(&loc, "[\"", CEscape(name), "\"]");
+ }
+ }
+ if (ow_->IsRepeated(*parent_field_) && array_index_ > 0) {
+ StrAppend(&loc, "[", array_index_ - 1, "]");
+ }
+ return loc.empty() ? "." : loc;
+}
+
+bool ProtoWriter::ProtoElement::IsOneofIndexTaken(int32 index) {
+ return oneof_indices_[index];
+}
+
+void ProtoWriter::ProtoElement::TakeOneofIndex(int32 index) {
+ oneof_indices_[index] = true;
+}
+
+void ProtoWriter::InvalidName(StringPiece unknown_name, StringPiece message) {
+ listener_->InvalidName(location(), ToSnakeCase(unknown_name), message);
+}
+
+void ProtoWriter::InvalidValue(StringPiece type_name, StringPiece value) {
+ listener_->InvalidValue(location(), type_name, value);
+}
+
+void ProtoWriter::MissingField(StringPiece missing_name) {
+ listener_->MissingField(location(), missing_name);
+}
+
+ProtoWriter* ProtoWriter::StartObject(StringPiece name) {
+ // Starting the root message. Create the root ProtoElement and return.
+ if (element_ == NULL) {
+ if (!name.empty()) {
+ InvalidName(name, "Root element should not be named.");
+ }
+ element_.reset(new ProtoElement(typeinfo_, master_type_, this));
+ return this;
+ }
+
+ const google::protobuf::Field* field = NULL;
+ field = BeginNamed(name, false);
+ if (field == NULL) return this;
+
+ // Check to see if this field is a oneof and that no oneof in that group has
+ // already been set.
+ if (!ValidOneof(*field, name)) {
+ ++invalid_depth_;
+ return this;
+ }
+
+ const google::protobuf::Type* type = LookupType(field);
+ if (type == NULL) {
+ ++invalid_depth_;
+ InvalidName(name,
+ StrCat("Missing descriptor for field: ", field->type_url()));
+ return this;
+ }
+
+ return StartObjectField(*field, *type);
+}
+
+ProtoWriter* ProtoWriter::EndObject() {
+ if (invalid_depth_ > 0) {
+ --invalid_depth_;
+ return this;
+ }
+
+ if (element_ != NULL) {
+ element_.reset(element_->pop());
+ }
+
+
+ // If ending the root element,
+ // then serialize the full message with calculated sizes.
+ if (element_ == NULL) {
+ WriteRootMessage();
+ }
+ return this;
+}
+
+ProtoWriter* ProtoWriter::StartList(StringPiece name) {
+ const google::protobuf::Field* field = BeginNamed(name, true);
+ if (field == NULL) return this;
+
+ if (!ValidOneof(*field, name)) {
+ ++invalid_depth_;
+ return this;
+ }
+
+ const google::protobuf::Type* type = LookupType(field);
+ if (type == NULL) {
+ ++invalid_depth_;
+ InvalidName(name,
+ StrCat("Missing descriptor for field: ", field->type_url()));
+ return this;
+ }
+
+ return StartListField(*field, *type);
+}
+
+ProtoWriter* ProtoWriter::EndList() {
+ if (invalid_depth_ > 0) {
+ --invalid_depth_;
+ } else if (element_ != NULL) {
+ element_.reset(element_->pop());
+ }
+ return this;
+}
+
+ProtoWriter* ProtoWriter::RenderDataPiece(StringPiece name,
+ const DataPiece& data) {
+ Status status;
+ if (invalid_depth_ > 0) return this;
+
+ const google::protobuf::Field* field = Lookup(name);
+ if (field == NULL) return this;
+
+ if (!ValidOneof(*field, name)) return this;
+
+ const google::protobuf::Type* type = LookupType(field);
+ if (type == NULL) {
+ InvalidName(name,
+ StrCat("Missing descriptor for field: ", field->type_url()));
+ return this;
+ }
+
+ return RenderPrimitiveField(*field, *type, data);
+}
+
+bool ProtoWriter::ValidOneof(const google::protobuf::Field& field,
+ StringPiece unnormalized_name) {
+ if (element_ == NULL) return true;
+
+ if (field.oneof_index() > 0) {
+ if (element_->IsOneofIndexTaken(field.oneof_index())) {
+ InvalidValue(
+ "oneof",
+ StrCat("oneof field '",
+ element_->type().oneofs(field.oneof_index() - 1),
+ "' is already set. Cannot set '", unnormalized_name, "'"));
+ return false;
+ }
+ element_->TakeOneofIndex(field.oneof_index());
+ }
+ return true;
+}
+
+bool ProtoWriter::IsRepeated(const google::protobuf::Field& field) {
+ return field.cardinality() ==
+ google::protobuf::Field_Cardinality_CARDINALITY_REPEATED;
+}
+
+ProtoWriter* ProtoWriter::StartObjectField(const google::protobuf::Field& field,
+ const google::protobuf::Type& type) {
+ WriteTag(field);
+ element_.reset(new ProtoElement(element_.release(), &field, type, false));
+ return this;
+}
+
+ProtoWriter* ProtoWriter::StartListField(const google::protobuf::Field& field,
+ const google::protobuf::Type& type) {
+ element_.reset(new ProtoElement(element_.release(), &field, type, true));
+ return this;
+}
+
+ProtoWriter* ProtoWriter::RenderPrimitiveField(
+ const google::protobuf::Field& field, const google::protobuf::Type& type,
+ const DataPiece& data) {
+ Status status;
+
+ // Pushing a ProtoElement and then pop it off at the end for 2 purposes:
+ // error location reporting and required field accounting.
+ //
+ // For proto3, since there is no required field tracking, we only need to push
+ // ProtoElement for error cases.
+ if (!element_->proto3()) {
+ element_.reset(new ProtoElement(element_.release(), &field, type, false));
+ }
+
+ if (field.kind() == google::protobuf::Field_Kind_TYPE_UNKNOWN ||
+ field.kind() == google::protobuf::Field_Kind_TYPE_MESSAGE) {
+ // Push a ProtoElement for location reporting purposes.
+ if (element_->proto3()) {
+ element_.reset(new ProtoElement(element_.release(), &field, type, false));
+ }
+ InvalidValue(field.type_url().empty()
+ ? google::protobuf::Field_Kind_Name(field.kind())
+ : field.type_url(),
+ data.ValueAsStringOrDefault(""));
+ element_.reset(element()->pop());
+ return this;
+ }
+
+ switch (field.kind()) {
+ case google::protobuf::Field_Kind_TYPE_INT32: {
+ status = WriteInt32(field.number(), data, stream_.get());
+ break;
+ }
+ case google::protobuf::Field_Kind_TYPE_SFIXED32: {
+ status = WriteSFixed32(field.number(), data, stream_.get());
+ break;
+ }
+ case google::protobuf::Field_Kind_TYPE_SINT32: {
+ status = WriteSInt32(field.number(), data, stream_.get());
+ break;
+ }
+ case google::protobuf::Field_Kind_TYPE_FIXED32: {
+ status = WriteFixed32(field.number(), data, stream_.get());
+ break;
+ }
+ case google::protobuf::Field_Kind_TYPE_UINT32: {
+ status = WriteUInt32(field.number(), data, stream_.get());
+ break;
+ }
+ case google::protobuf::Field_Kind_TYPE_INT64: {
+ status = WriteInt64(field.number(), data, stream_.get());
+ break;
+ }
+ case google::protobuf::Field_Kind_TYPE_SFIXED64: {
+ status = WriteSFixed64(field.number(), data, stream_.get());
+ break;
+ }
+ case google::protobuf::Field_Kind_TYPE_SINT64: {
+ status = WriteSInt64(field.number(), data, stream_.get());
+ break;
+ }
+ case google::protobuf::Field_Kind_TYPE_FIXED64: {
+ status = WriteFixed64(field.number(), data, stream_.get());
+ break;
+ }
+ case google::protobuf::Field_Kind_TYPE_UINT64: {
+ status = WriteUInt64(field.number(), data, stream_.get());
+ break;
+ }
+ case google::protobuf::Field_Kind_TYPE_DOUBLE: {
+ status = WriteDouble(field.number(), data, stream_.get());
+ break;
+ }
+ case google::protobuf::Field_Kind_TYPE_FLOAT: {
+ status = WriteFloat(field.number(), data, stream_.get());
+ break;
+ }
+ case google::protobuf::Field_Kind_TYPE_BOOL: {
+ status = WriteBool(field.number(), data, stream_.get());
+ break;
+ }
+ case google::protobuf::Field_Kind_TYPE_BYTES: {
+ status = WriteBytes(field.number(), data, stream_.get());
+ break;
+ }
+ case google::protobuf::Field_Kind_TYPE_STRING: {
+ status = WriteString(field.number(), data, stream_.get());
+ break;
+ }
+ case google::protobuf::Field_Kind_TYPE_ENUM: {
+ status = WriteEnum(field.number(), data,
+ typeinfo_->GetEnumByTypeUrl(field.type_url()),
+ stream_.get());
+ break;
+ }
+ default: // TYPE_GROUP or TYPE_MESSAGE
+ status = Status(INVALID_ARGUMENT, data.ToString().ValueOrDie());
+ }
+
+ if (!status.ok()) {
+ // Push a ProtoElement for location reporting purposes.
+ if (element_->proto3()) {
+ element_.reset(new ProtoElement(element_.release(), &field, type, false));
+ }
+ InvalidValue(google::protobuf::Field_Kind_Name(field.kind()),
+ status.error_message());
+ element_.reset(element()->pop());
+ return this;
+ }
+
+ if (!element_->proto3()) element_.reset(element()->pop());
+
+ return this;
+}
+
+const google::protobuf::Field* ProtoWriter::BeginNamed(StringPiece name,
+ bool is_list) {
+ if (invalid_depth_ > 0) {
+ ++invalid_depth_;
+ return NULL;
+ }
+ const google::protobuf::Field* field = Lookup(name);
+ if (field == NULL) {
+ ++invalid_depth_;
+ // InvalidName() already called in Lookup().
+ return NULL;
+ }
+ if (is_list && !IsRepeated(*field)) {
+ ++invalid_depth_;
+ InvalidName(name, "Proto field is not repeating, cannot start list.");
+ return NULL;
+ }
+ return field;
+}
+
+const google::protobuf::Field* ProtoWriter::Lookup(
+ StringPiece unnormalized_name) {
+ ProtoElement* e = element();
+ if (e == NULL) {
+ InvalidName(unnormalized_name, "Root element must be a message.");
+ return NULL;
+ }
+ if (unnormalized_name.empty()) {
+ // Objects in repeated field inherit the same field descriptor.
+ if (e->parent_field() == NULL) {
+ InvalidName(unnormalized_name, "Proto fields must have a name.");
+ } else if (!IsRepeated(*e->parent_field())) {
+ InvalidName(unnormalized_name, "Proto fields must have a name.");
+ return NULL;
+ }
+ return e->parent_field();
+ }
+ const google::protobuf::Field* field =
+ typeinfo_->FindField(&e->type(), unnormalized_name);
+ if (field == NULL && !ignore_unknown_fields_) {
+ InvalidName(unnormalized_name, "Cannot find field.");
+ }
+ return field;
+}
+
+const google::protobuf::Type* ProtoWriter::LookupType(
+ const google::protobuf::Field* field) {
+ return ((field->kind() == google::protobuf::Field_Kind_TYPE_MESSAGE ||
+ field->kind() == google::protobuf::Field_Kind_TYPE_GROUP)
+ ? typeinfo_->GetTypeByTypeUrl(field->type_url())
+ : &element_->type());
+}
+
+void ProtoWriter::WriteRootMessage() {
+ GOOGLE_DCHECK(!done_);
+ int curr_pos = 0;
+ // Calls the destructor of CodedOutputStream to remove any uninitialized
+ // memory from the Cord before we read it.
+ stream_.reset(NULL);
+ const void* data;
+ int length;
+ google::protobuf::io::ArrayInputStream input_stream(buffer_.data(), buffer_.size());
+ while (input_stream.Next(&data, &length)) {
+ if (length == 0) continue;
+ int num_bytes = length;
+ // Write up to where we need to insert the size field.
+ // The number of bytes we may write is the smaller of:
+ // - the current fragment size
+ // - the distance to the next position where a size field needs to be
+ // inserted.
+ if (!size_insert_.empty() &&
+ size_insert_.front().pos - curr_pos < num_bytes) {
+ num_bytes = size_insert_.front().pos - curr_pos;
+ }
+ output_->Append(static_cast<const char*>(data), num_bytes);
+ if (num_bytes < length) {
+ input_stream.BackUp(length - num_bytes);
+ }
+ curr_pos += num_bytes;
+ // Insert the size field.
+ // size_insert_.front(): the next <index, size> pair to be written.
+ // size_insert_.front().pos: position of the size field.
+ // size_insert_.front().size: the size (integer) to be inserted.
+ if (!size_insert_.empty() && curr_pos == size_insert_.front().pos) {
+ // Varint32 occupies at most 10 bytes.
+ uint8 insert_buffer[10];
+ uint8* insert_buffer_pos = CodedOutputStream::WriteVarint32ToArray(
+ size_insert_.front().size, insert_buffer);
+ output_->Append(reinterpret_cast<const char*>(insert_buffer),
+ insert_buffer_pos - insert_buffer);
+ size_insert_.pop_front();
+ }
+ }
+ output_->Flush();
+ stream_.reset(new CodedOutputStream(&adapter_));
+ done_ = true;
+}
+
+void ProtoWriter::WriteTag(const google::protobuf::Field& field) {
+ WireFormatLite::WireType wire_type = WireFormatLite::WireTypeForFieldType(
+ static_cast<WireFormatLite::FieldType>(field.kind()));
+ stream_->WriteTag(WireFormatLite::MakeTag(field.number(), wire_type));
+}
+
+
+} // namespace converter
+} // namespace util
+} // namespace protobuf
+} // namespace google
diff --git a/src/google/protobuf/util/internal/proto_writer.h b/src/google/protobuf/util/internal/proto_writer.h
new file mode 100644
index 00000000..7f1108ab
--- /dev/null
+++ b/src/google/protobuf/util/internal/proto_writer.h
@@ -0,0 +1,345 @@
+// 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.
+
+#ifndef GOOGLE_PROTOBUF_UTIL_CONVERTER_PROTO_WRITER_H__
+#define GOOGLE_PROTOBUF_UTIL_CONVERTER_PROTO_WRITER_H__
+
+#include <deque>
+#include <string>
+#include <vector>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/util/internal/type_info.h>
+#include <google/protobuf/util/internal/datapiece.h>
+#include <google/protobuf/util/internal/error_listener.h>
+#include <google/protobuf/util/internal/structured_objectwriter.h>
+#include <google/protobuf/util/type_resolver.h>
+#include <google/protobuf/stubs/bytestream.h>
+#include <google/protobuf/stubs/hash.h>
+
+namespace google {
+namespace protobuf {
+namespace io {
+class CodedOutputStream;
+} // namespace io
+} // namespace protobuf
+
+
+namespace protobuf {
+class Type;
+class Field;
+} // namespace protobuf
+
+
+namespace protobuf {
+namespace util {
+namespace converter {
+
+class ObjectLocationTracker;
+
+// An ObjectWriter that can write protobuf bytes directly from writer events.
+// This class does not support special types like Struct or Map. However, since
+// this class supports raw protobuf, it can be used to provide support for
+// special types by inheriting from it or by wrapping it.
+//
+// It also supports streaming.
+class LIBPROTOBUF_EXPORT ProtoWriter : public StructuredObjectWriter {
+ public:
+// Constructor. Does not take ownership of any parameter passed in.
+ ProtoWriter(TypeResolver* type_resolver, const google::protobuf::Type& type,
+ strings::ByteSink* output, ErrorListener* listener);
+ virtual ~ProtoWriter();
+
+ // ObjectWriter methods.
+ virtual ProtoWriter* StartObject(StringPiece name);
+ virtual ProtoWriter* EndObject();
+ virtual ProtoWriter* StartList(StringPiece name);
+ virtual ProtoWriter* EndList();
+ virtual ProtoWriter* RenderBool(StringPiece name, bool value) {
+ return RenderDataPiece(name, DataPiece(value));
+ }
+ virtual ProtoWriter* RenderInt32(StringPiece name, int32 value) {
+ return RenderDataPiece(name, DataPiece(value));
+ }
+ virtual ProtoWriter* RenderUint32(StringPiece name, uint32 value) {
+ return RenderDataPiece(name, DataPiece(value));
+ }
+ virtual ProtoWriter* RenderInt64(StringPiece name, int64 value) {
+ return RenderDataPiece(name, DataPiece(value));
+ }
+ virtual ProtoWriter* RenderUint64(StringPiece name, uint64 value) {
+ return RenderDataPiece(name, DataPiece(value));
+ }
+ virtual ProtoWriter* RenderDouble(StringPiece name, double value) {
+ return RenderDataPiece(name, DataPiece(value));
+ }
+ virtual ProtoWriter* RenderFloat(StringPiece name, float value) {
+ return RenderDataPiece(name, DataPiece(value));
+ }
+ virtual ProtoWriter* RenderString(StringPiece name, StringPiece value) {
+ return RenderDataPiece(name,
+ DataPiece(value, use_strict_base64_decoding()));
+ }
+ virtual ProtoWriter* RenderBytes(StringPiece name, StringPiece value) {
+ return RenderDataPiece(
+ name, DataPiece(value, false, use_strict_base64_decoding()));
+ }
+ virtual ProtoWriter* RenderNull(StringPiece name) {
+ return RenderDataPiece(name, DataPiece::NullData());
+ }
+
+
+ // Renders a DataPiece 'value' into a field whose wire type is determined
+ // from the given field 'name'.
+ virtual ProtoWriter* RenderDataPiece(StringPiece name,
+ const DataPiece& value);
+
+ // Returns the location tracker to use for tracking locations for errors.
+ const LocationTrackerInterface& location() {
+ return element_ != NULL ? *element_ : *tracker_;
+ }
+
+ // When true, we finished writing to output a complete message.
+ bool done() { return done_; }
+
+ // Returns the proto stream object.
+ google::protobuf::io::CodedOutputStream* stream() { return stream_.get(); }
+
+ // Getters and mutators of invalid_depth_.
+ void IncrementInvalidDepth() { ++invalid_depth_; }
+ void DecrementInvalidDepth() { --invalid_depth_; }
+ int invalid_depth() { return invalid_depth_; }
+
+ ErrorListener* listener() { return listener_; }
+
+ const TypeInfo* typeinfo() { return typeinfo_; }
+
+ void set_ignore_unknown_fields(bool ignore_unknown_fields) {
+ ignore_unknown_fields_ = ignore_unknown_fields;
+ }
+
+ protected:
+ class LIBPROTOBUF_EXPORT ProtoElement : public BaseElement, public LocationTrackerInterface {
+ public:
+ // Constructor for the root element. No parent nor field.
+ ProtoElement(const TypeInfo* typeinfo, const google::protobuf::Type& type,
+ ProtoWriter* enclosing);
+
+ // Constructor for a field of an element.
+ ProtoElement(ProtoElement* parent, const google::protobuf::Field* field,
+ const google::protobuf::Type& type, bool is_list);
+
+ virtual ~ProtoElement() {}
+
+ // Called just before the destructor for clean up:
+ // - reports any missing required fields
+ // - computes the space needed by the size field, and augment the
+ // length of all parent messages by this additional space.
+ // - releases and returns the parent pointer.
+ ProtoElement* pop();
+
+ // Accessors
+ // parent_field() may be NULL if we are at root.
+ const google::protobuf::Field* parent_field() const {
+ return parent_field_;
+ }
+ const google::protobuf::Type& type() const { return type_; }
+
+ // Registers field for accounting required fields.
+ void RegisterField(const google::protobuf::Field* field);
+
+ // To report location on error messages.
+ virtual string ToString() const;
+
+ virtual ProtoElement* parent() const {
+ return static_cast<ProtoElement*>(BaseElement::parent());
+ }
+
+ // Returns true if the index is already taken by a preceding oneof input.
+ bool IsOneofIndexTaken(int32 index);
+
+ // Marks the oneof 'index' as taken. Future inputs to this oneof will
+ // generate an error.
+ void TakeOneofIndex(int32 index);
+
+ bool proto3() { return proto3_; }
+
+ private:
+ // Used for access to variables of the enclosing instance of
+ // ProtoWriter.
+ ProtoWriter* ow_;
+
+ // Describes the element as a field in the parent message.
+ // parent_field_ is NULL if and only if this element is the root element.
+ const google::protobuf::Field* parent_field_;
+
+ // TypeInfo to lookup types.
+ const TypeInfo* typeinfo_;
+
+ // Whether the type_ is proto3 or not.
+ bool proto3_;
+
+ // Additional variables if this element is a message:
+ // (Root element is always a message).
+ // type_ : the type of this element.
+ // required_fields_ : set of required fields.
+ // size_index_ : index into ProtoWriter::size_insert_
+ // for later insertion of serialized message length.
+ const google::protobuf::Type& type_;
+ std::set<const google::protobuf::Field*> required_fields_;
+ const int size_index_;
+
+ // Tracks position in repeated fields, needed for LocationTrackerInterface.
+ int array_index_;
+
+ // Set of oneof indices already seen for the type_. Used to validate
+ // incoming messages so no more than one oneof is set.
+ std::vector<bool> oneof_indices_;
+
+ GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(ProtoElement);
+ };
+
+ // Container for inserting 'size' information at the 'pos' position.
+ struct SizeInfo {
+ const int pos;
+ int size;
+ };
+
+ ProtoWriter(const TypeInfo* typeinfo, const google::protobuf::Type& type,
+ strings::ByteSink* output, ErrorListener* listener);
+
+ virtual ProtoElement* element() { return element_.get(); }
+
+ // Helper methods for calling ErrorListener. See error_listener.h.
+ void InvalidName(StringPiece unknown_name, StringPiece message);
+ void InvalidValue(StringPiece type_name, StringPiece value);
+ void MissingField(StringPiece missing_name);
+
+ // Common code for BeginObject() and BeginList() that does invalid_depth_
+ // bookkeeping associated with name lookup.
+ const google::protobuf::Field* BeginNamed(StringPiece name, bool is_list);
+
+ // Lookup the field in the current element. Looks in the base descriptor
+ // and in any extension. This will report an error if the field cannot be
+ // found when ignore_unknown_names_ is false or if multiple matching
+ // extensions are found.
+ const google::protobuf::Field* Lookup(StringPiece name);
+
+ // Lookup the field type in the type descriptor. Returns NULL if the type
+ // is not known.
+ const google::protobuf::Type* LookupType(
+ const google::protobuf::Field* field);
+
+ // Write serialized output to the final output ByteSink, inserting all
+ // the size information for nested messages that are missing from the
+ // intermediate Cord buffer.
+ void WriteRootMessage();
+
+ // Helper method to write proto tags based on the given field.
+ void WriteTag(const google::protobuf::Field& field);
+
+
+ // Returns true if the field for type_ can be set as a oneof. If field is not
+ // a oneof type, this function does nothing and returns true.
+ // If another field for this oneof is already set, this function returns
+ // false. It also calls the appropriate error callback.
+ // unnormalized_name is used for error string.
+ bool ValidOneof(const google::protobuf::Field& field,
+ StringPiece unnormalized_name);
+
+ // Returns true if the field is repeated.
+ bool IsRepeated(const google::protobuf::Field& field);
+
+ // Starts an object given the field and the enclosing type.
+ ProtoWriter* StartObjectField(const google::protobuf::Field& field,
+ const google::protobuf::Type& type);
+
+ // Starts a list given the field and the enclosing type.
+ ProtoWriter* StartListField(const google::protobuf::Field& field,
+ const google::protobuf::Type& type);
+
+ // Renders a primitve field given the field and the enclosing type.
+ ProtoWriter* RenderPrimitiveField(const google::protobuf::Field& field,
+ const google::protobuf::Type& type,
+ const DataPiece& value);
+
+ private:
+ // Variables for describing the structure of the input tree:
+ // master_type_: descriptor for the whole protobuf message.
+ // typeinfo_ : the TypeInfo object to lookup types.
+ const google::protobuf::Type& master_type_;
+ const TypeInfo* typeinfo_;
+ // Whether we own the typeinfo_ object.
+ bool own_typeinfo_;
+
+ // Indicates whether we finished writing root message completely.
+ bool done_;
+
+ // If true, don't report unknown field names to the listener.
+ bool ignore_unknown_fields_;
+
+ // Variable for internal state processing:
+ // element_ : the current element.
+ // size_insert_: sizes of nested messages.
+ // pos - position to insert the size field.
+ // size - size value to be inserted.
+ google::protobuf::scoped_ptr<ProtoElement> element_;
+ std::deque<SizeInfo> size_insert_;
+
+ // Variables for output generation:
+ // output_ : pointer to an external ByteSink for final user-visible output.
+ // buffer_ : buffer holding partial message before being ready for output_.
+ // adapter_ : internal adapter between CodedOutputStream and buffer_.
+ // stream_ : wrapper for writing tags and other encodings in wire format.
+ strings::ByteSink* output_;
+ string buffer_;
+ google::protobuf::io::StringOutputStream adapter_;
+ google::protobuf::scoped_ptr<google::protobuf::io::CodedOutputStream> stream_;
+
+ // Variables for error tracking and reporting:
+ // listener_ : a place to report any errors found.
+ // invalid_depth_: number of enclosing invalid nested messages.
+ // tracker_ : the root location tracker interface.
+ ErrorListener* listener_;
+ int invalid_depth_;
+ google::protobuf::scoped_ptr<LocationTrackerInterface> tracker_;
+
+ GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(ProtoWriter);
+};
+
+} // namespace converter
+} // namespace util
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_UTIL_CONVERTER_PROTO_WRITER_H__
diff --git a/src/google/protobuf/util/internal/protostream_objectsource.cc b/src/google/protobuf/util/internal/protostream_objectsource.cc
index 2bbb1597..0048d75b 100644
--- a/src/google/protobuf/util/internal/protostream_objectsource.cc
+++ b/src/google/protobuf/util/internal/protostream_objectsource.cc
@@ -70,6 +70,9 @@ using util::Status;
using util::StatusOr;
namespace {
+
+static int kDefaultMaxRecursionDepth = 64;
+
// Finds a field with the given number. NULL if none found.
const google::protobuf::Field* FindFieldByNumber(
const google::protobuf::Type& type, int number);
@@ -83,6 +86,29 @@ const google::protobuf::EnumValue* FindEnumValueByNumber(
// Utility function to format nanos.
const string FormatNanos(uint32 nanos);
+
+StatusOr<string> MapKeyDefaultValueAsString(
+ const google::protobuf::Field& field) {
+ switch (field.kind()) {
+ case google::protobuf::Field_Kind_TYPE_BOOL:
+ return string("false");
+ case google::protobuf::Field_Kind_TYPE_INT32:
+ case google::protobuf::Field_Kind_TYPE_INT64:
+ case google::protobuf::Field_Kind_TYPE_UINT32:
+ case google::protobuf::Field_Kind_TYPE_UINT64:
+ case google::protobuf::Field_Kind_TYPE_SINT32:
+ case google::protobuf::Field_Kind_TYPE_SINT64:
+ case google::protobuf::Field_Kind_TYPE_SFIXED32:
+ case google::protobuf::Field_Kind_TYPE_SFIXED64:
+ case google::protobuf::Field_Kind_TYPE_FIXED32:
+ case google::protobuf::Field_Kind_TYPE_FIXED64:
+ return string("0");
+ case google::protobuf::Field_Kind_TYPE_STRING:
+ return string();
+ default:
+ return Status(util::error::INTERNAL, "Invalid map key type.");
+ }
+}
} // namespace
@@ -92,14 +118,25 @@ ProtoStreamObjectSource::ProtoStreamObjectSource(
: stream_(stream),
typeinfo_(TypeInfo::NewTypeInfo(type_resolver)),
own_typeinfo_(true),
- type_(type) {
+ type_(type),
+ use_lower_camel_for_enums_(false),
+ recursion_depth_(0),
+ max_recursion_depth_(kDefaultMaxRecursionDepth),
+ render_unknown_fields_(false) {
GOOGLE_LOG_IF(DFATAL, stream == NULL) << "Input stream is NULL.";
}
ProtoStreamObjectSource::ProtoStreamObjectSource(
google::protobuf::io::CodedInputStream* stream, const TypeInfo* typeinfo,
const google::protobuf::Type& type)
- : stream_(stream), typeinfo_(typeinfo), own_typeinfo_(false), type_(type) {
+ : stream_(stream),
+ typeinfo_(typeinfo),
+ own_typeinfo_(false),
+ type_(type),
+ use_lower_camel_for_enums_(false),
+ recursion_depth_(0),
+ max_recursion_depth_(kDefaultMaxRecursionDepth),
+ render_unknown_fields_(false) {
GOOGLE_LOG_IF(DFATAL, stream == NULL) << "Input stream is NULL.";
}
@@ -140,15 +177,16 @@ Status ProtoStreamObjectSource::WriteMessage(const google::protobuf::Type& type,
bool include_start_and_end,
ObjectWriter* ow) const {
- const TypeRenderer* type_renderer = FindTypeRenderer(type.name());
- if (type_renderer != NULL) {
- return (*type_renderer)(this, type, name, ow);
- }
+ const TypeRenderer* type_renderer = FindTypeRenderer(type.name());
+ if (type_renderer != NULL) {
+ return (*type_renderer)(this, type, name, ow);
+ }
const google::protobuf::Field* field = NULL;
string field_name;
// last_tag set to dummy value that is different from tag.
uint32 tag = stream_->ReadTag(), last_tag = tag + 1;
+ google::protobuf::UnknownFieldSet unknown_fields;
if (include_start_and_end) {
ow->StartObject(name);
@@ -164,14 +202,17 @@ Status ProtoStreamObjectSource::WriteMessage(const google::protobuf::Type& type,
if (field == NULL) {
// If we didn't find a field, skip this unknown tag.
// TODO(wpoon): Check return boolean value.
- WireFormat::SkipField(stream_, tag, NULL);
+ WireFormat::SkipField(stream_, tag,
+ render_unknown_fields_ ? &unknown_fields : NULL);
tag = stream_->ReadTag();
continue;
}
if (field->cardinality() ==
google::protobuf::Field_Cardinality_CARDINALITY_REPEATED) {
- if (IsMap(*field)) {
+ bool check_maps = true;
+
+ if (check_maps && IsMap(*field)) {
ow->StartObject(field_name);
ASSIGN_OR_RETURN(tag, RenderMap(field, field_name, tag, ow));
ow->EndObject();
@@ -184,6 +225,8 @@ Status ProtoStreamObjectSource::WriteMessage(const google::protobuf::Type& type,
tag = stream_->ReadTag();
}
}
+
+
if (include_start_and_end) {
ow->EndObject();
}
@@ -218,48 +261,44 @@ StatusOr<uint32> ProtoStreamObjectSource::RenderMap(
const google::protobuf::Type* field_type =
typeinfo_->GetTypeByTypeUrl(field->type_url());
uint32 tag_to_return = 0;
- if (IsPackable(*field) &&
- list_tag ==
- WireFormatLite::MakeTag(field->number(),
- WireFormatLite::WIRETYPE_LENGTH_DELIMITED)) {
- RETURN_IF_ERROR(RenderPackedMapEntry(field_type, ow));
- tag_to_return = stream_->ReadTag();
- } else {
- do {
- RETURN_IF_ERROR(RenderMapEntry(field_type, ow));
- } while ((tag_to_return = stream_->ReadTag()) == list_tag);
- }
- return tag_to_return;
-}
-
-Status ProtoStreamObjectSource::RenderMapEntry(
- const google::protobuf::Type* type, ObjectWriter* ow) const {
- uint32 buffer32;
- stream_->ReadVarint32(&buffer32); // message length
- int old_limit = stream_->PushLimit(buffer32);
- string map_key;
- for (uint32 tag = stream_->ReadTag(); tag != 0; tag = stream_->ReadTag()) {
- const google::protobuf::Field* field = FindAndVerifyField(*type, tag);
- if (field == NULL) {
- WireFormat::SkipField(stream_, tag, NULL);
- continue;
- }
- // Map field numbers are key = 1 and value = 2
- if (field->number() == 1) {
- map_key = ReadFieldValueAsString(*field);
- } else if (field->number() == 2) {
- if (map_key.empty()) {
- return Status(util::error::INTERNAL, "Map key must be non-empty");
+ do {
+ // Render map entry message type.
+ uint32 buffer32;
+ stream_->ReadVarint32(&buffer32); // message length
+ int old_limit = stream_->PushLimit(buffer32);
+ string map_key;
+ for (uint32 tag = stream_->ReadTag(); tag != 0; tag = stream_->ReadTag()) {
+ const google::protobuf::Field* field =
+ FindAndVerifyField(*field_type, tag);
+ if (field == NULL) {
+ WireFormat::SkipField(stream_, tag, NULL);
+ continue;
+ }
+ // Map field numbers are key = 1 and value = 2
+ if (field->number() == 1) {
+ map_key = ReadFieldValueAsString(*field);
+ } else if (field->number() == 2) {
+ if (map_key.empty()) {
+ // An absent map key is treated as the default.
+ const google::protobuf::Field* key_field =
+ FindFieldByNumber(*field_type, 1);
+ if (key_field == NULL) {
+ // The Type info for this map entry is incorrect. It should always
+ // have a field named "key" and with field number 1.
+ return Status(util::error::INTERNAL, "Invalid map entry.");
+ }
+ ASSIGN_OR_RETURN(map_key, MapKeyDefaultValueAsString(*key_field));
+ }
+ RETURN_IF_ERROR(RenderField(field, map_key, ow));
+ } else {
+ // The Type info for this map entry is incorrect. It should contain
+ // exactly two fields with field number 1 and 2.
+ return Status(util::error::INTERNAL, "Invalid map entry.");
}
- // Disable case normalization for map keys as they are just data. We
- // retain them intact.
- ow->DisableCaseNormalizationForNextKey();
- RETURN_IF_ERROR(RenderField(field, map_key, ow));
}
- }
- stream_->PopLimit(old_limit);
-
- return Status::OK;
+ stream_->PopLimit(old_limit);
+ } while ((tag_to_return = stream_->ReadTag()) == list_tag);
+ return tag_to_return;
}
Status ProtoStreamObjectSource::RenderPacked(
@@ -274,25 +313,13 @@ Status ProtoStreamObjectSource::RenderPacked(
return Status::OK;
}
-Status ProtoStreamObjectSource::RenderPackedMapEntry(
- const google::protobuf::Type* type, ObjectWriter* ow) const {
- uint32 length;
- stream_->ReadVarint32(&length);
- int old_limit = stream_->PushLimit(length);
- while (stream_->BytesUntilLimit() > 0) {
- RETURN_IF_ERROR(RenderMapEntry(type, ow));
- }
- stream_->PopLimit(old_limit);
- return Status::OK;
-}
-
Status ProtoStreamObjectSource::RenderTimestamp(
const ProtoStreamObjectSource* os, const google::protobuf::Type& type,
StringPiece field_name, ObjectWriter* ow) {
pair<int64, int32> p = os->ReadSecondsAndNanos(type);
int64 seconds = p.first;
int32 nanos = p.second;
- if (seconds > kMaxSeconds || seconds < kMinSeconds) {
+ if (seconds > kTimestampMaxSeconds || seconds < kTimestampMinSeconds) {
return Status(
util::error::INTERNAL,
StrCat("Timestamp seconds exceeds limit for field: ", field_name));
@@ -316,7 +343,7 @@ Status ProtoStreamObjectSource::RenderDuration(
pair<int64, int32> p = os->ReadSecondsAndNanos(type);
int64 seconds = p.first;
int32 nanos = p.second;
- if (seconds > kMaxSeconds || seconds < kMinSeconds) {
+ if (seconds > kDurationMaxSeconds || seconds < kDurationMinSeconds) {
return Status(
util::error::INTERNAL,
StrCat("Duration seconds exceeds limit for field: ", field_name));
@@ -601,10 +628,10 @@ Status ProtoStreamObjectSource::RenderAny(const ProtoStreamObjectSource* os,
// nested_type cannot be null at this time.
const google::protobuf::Type* nested_type = resolved_type.ValueOrDie();
- // We know the type so we can render it. Recursively parse the nested stream
- // using a nested ProtoStreamObjectSource using our nested type information.
google::protobuf::io::ArrayInputStream zero_copy_stream(value.data(), value.size());
google::protobuf::io::CodedInputStream in_stream(&zero_copy_stream);
+ // We know the type so we can render it. Recursively parse the nested stream
+ // using a nested ProtoStreamObjectSource using our nested type information.
ProtoStreamObjectSource nested_os(&in_stream, os->typeinfo_, *nested_type);
// We manually call start and end object here so we can inject the @type.
@@ -676,8 +703,7 @@ void ProtoStreamObjectSource::InitRendererMap() {
&ProtoStreamObjectSource::RenderString;
(*renderers_)["google.protobuf.BytesValue"] =
&ProtoStreamObjectSource::RenderBytes;
- (*renderers_)["google.protobuf.Any"] =
- &ProtoStreamObjectSource::RenderAny;
+ (*renderers_)["google.protobuf.Any"] = &ProtoStreamObjectSource::RenderAny;
(*renderers_)["google.protobuf.Struct"] =
&ProtoStreamObjectSource::RenderStruct;
(*renderers_)["google.protobuf.Value"] =
@@ -704,87 +730,120 @@ ProtoStreamObjectSource::FindTypeRenderer(const string& type_url) {
Status ProtoStreamObjectSource::RenderField(
const google::protobuf::Field* field, StringPiece field_name,
ObjectWriter* ow) const {
+ // Short-circuit message types as it tends to call WriteMessage recursively
+ // and ends up using a lot of stack space. Keep the stack usage of this
+ // message small in order to preserve stack space and not crash.
+ if (field->kind() == google::protobuf::Field_Kind_TYPE_MESSAGE) {
+ uint32 buffer32;
+ stream_->ReadVarint32(&buffer32); // message length
+ int old_limit = stream_->PushLimit(buffer32);
+ // Get the nested message type for this field.
+ const google::protobuf::Type* type =
+ typeinfo_->GetTypeByTypeUrl(field->type_url());
+ if (type == NULL) {
+ return Status(util::error::INTERNAL,
+ StrCat("Invalid configuration. Could not find the type: ",
+ field->type_url()));
+ }
+
+ // Short-circuit any special type rendering to save call-stack space.
+ const TypeRenderer* type_renderer = FindTypeRenderer(type->name());
+
+ bool use_type_renderer = type_renderer != NULL;
+
+ if (use_type_renderer) {
+ RETURN_IF_ERROR((*type_renderer)(this, *type, field_name, ow));
+ } else {
+ RETURN_IF_ERROR(IncrementRecursionDepth(type->name(), field_name));
+ RETURN_IF_ERROR(WriteMessage(*type, field_name, 0, true, ow));
+ --recursion_depth_;
+ }
+ if (!stream_->ConsumedEntireMessage()) {
+ return Status(util::error::INVALID_ARGUMENT,
+ "Nested protocol message not parsed in its entirety.");
+ }
+ stream_->PopLimit(old_limit);
+ } else {
+ // Render all other non-message types.
+ return RenderNonMessageField(field, field_name, ow);
+ }
+ return Status::OK;
+}
+
+Status ProtoStreamObjectSource::RenderNonMessageField(
+ const google::protobuf::Field* field, StringPiece field_name,
+ ObjectWriter* ow) const {
+ // Temporary buffers of different types.
+ uint32 buffer32;
+ uint64 buffer64;
+ string strbuffer;
switch (field->kind()) {
case google::protobuf::Field_Kind_TYPE_BOOL: {
- uint64 buffer64;
stream_->ReadVarint64(&buffer64);
ow->RenderBool(field_name, buffer64 != 0);
break;
}
case google::protobuf::Field_Kind_TYPE_INT32: {
- uint32 buffer32;
stream_->ReadVarint32(&buffer32);
ow->RenderInt32(field_name, bit_cast<int32>(buffer32));
break;
}
case google::protobuf::Field_Kind_TYPE_INT64: {
- uint64 buffer64;
stream_->ReadVarint64(&buffer64);
ow->RenderInt64(field_name, bit_cast<int64>(buffer64));
break;
}
case google::protobuf::Field_Kind_TYPE_UINT32: {
- uint32 buffer32;
stream_->ReadVarint32(&buffer32);
ow->RenderUint32(field_name, bit_cast<uint32>(buffer32));
break;
}
case google::protobuf::Field_Kind_TYPE_UINT64: {
- uint64 buffer64;
stream_->ReadVarint64(&buffer64);
ow->RenderUint64(field_name, bit_cast<uint64>(buffer64));
break;
}
case google::protobuf::Field_Kind_TYPE_SINT32: {
- uint32 buffer32;
stream_->ReadVarint32(&buffer32);
ow->RenderInt32(field_name, WireFormatLite::ZigZagDecode32(buffer32));
break;
}
case google::protobuf::Field_Kind_TYPE_SINT64: {
- uint64 buffer64;
stream_->ReadVarint64(&buffer64);
ow->RenderInt64(field_name, WireFormatLite::ZigZagDecode64(buffer64));
break;
}
case google::protobuf::Field_Kind_TYPE_SFIXED32: {
- uint32 buffer32;
stream_->ReadLittleEndian32(&buffer32);
ow->RenderInt32(field_name, bit_cast<int32>(buffer32));
break;
}
case google::protobuf::Field_Kind_TYPE_SFIXED64: {
- uint64 buffer64;
stream_->ReadLittleEndian64(&buffer64);
ow->RenderInt64(field_name, bit_cast<int64>(buffer64));
break;
}
case google::protobuf::Field_Kind_TYPE_FIXED32: {
- uint32 buffer32;
stream_->ReadLittleEndian32(&buffer32);
ow->RenderUint32(field_name, bit_cast<uint32>(buffer32));
break;
}
case google::protobuf::Field_Kind_TYPE_FIXED64: {
- uint64 buffer64;
stream_->ReadLittleEndian64(&buffer64);
ow->RenderUint64(field_name, bit_cast<uint64>(buffer64));
break;
}
case google::protobuf::Field_Kind_TYPE_FLOAT: {
- uint32 buffer32;
stream_->ReadLittleEndian32(&buffer32);
ow->RenderFloat(field_name, bit_cast<float>(buffer32));
break;
}
case google::protobuf::Field_Kind_TYPE_DOUBLE: {
- uint64 buffer64;
stream_->ReadLittleEndian64(&buffer64);
ow->RenderDouble(field_name, bit_cast<double>(buffer64));
break;
}
case google::protobuf::Field_Kind_TYPE_ENUM: {
- uint32 buffer32;
stream_->ReadVarint32(&buffer32);
// If the field represents an explicit NULL value, render null.
@@ -803,7 +862,10 @@ Status ProtoStreamObjectSource::RenderField(
const google::protobuf::EnumValue* enum_value =
FindEnumValueByNumber(*en, buffer32);
if (enum_value != NULL) {
- ow->RenderString(field_name, enum_value->name());
+ if (use_lower_camel_for_enums_)
+ ow->RenderString(field_name, ToCamelCase(enum_value->name()));
+ else
+ ow->RenderString(field_name, enum_value->name());
}
} else {
GOOGLE_LOG(INFO) << "Unknown enum skipped: " << field->type_url();
@@ -811,40 +873,15 @@ Status ProtoStreamObjectSource::RenderField(
break;
}
case google::protobuf::Field_Kind_TYPE_STRING: {
- uint32 buffer32;
- string str;
stream_->ReadVarint32(&buffer32); // string size.
- stream_->ReadString(&str, buffer32);
- ow->RenderString(field_name, str);
+ stream_->ReadString(&strbuffer, buffer32);
+ ow->RenderString(field_name, strbuffer);
break;
}
case google::protobuf::Field_Kind_TYPE_BYTES: {
- uint32 buffer32;
stream_->ReadVarint32(&buffer32); // bytes size.
- string value;
- stream_->ReadString(&value, buffer32);
- ow->RenderBytes(field_name, value);
- break;
- }
- case google::protobuf::Field_Kind_TYPE_MESSAGE: {
- uint32 buffer32;
- stream_->ReadVarint32(&buffer32); // message length
- int old_limit = stream_->PushLimit(buffer32);
- // Get the nested message type for this field.
- const google::protobuf::Type* type =
- typeinfo_->GetTypeByTypeUrl(field->type_url());
- if (type == NULL) {
- return Status(util::error::INTERNAL,
- StrCat("Invalid configuration. Could not find the type: ",
- field->type_url()));
- }
-
- RETURN_IF_ERROR(WriteMessage(*type, field_name, 0, true, ow));
- if (!stream_->ConsumedEntireMessage()) {
- return Status(util::error::INVALID_ARGUMENT,
- "Nested protocol message not parsed in its entirety.");
- }
- stream_->PopLimit(old_limit);
+ stream_->ReadString(&strbuffer, buffer32);
+ ow->RenderBytes(field_name, strbuffer);
break;
}
default:
@@ -1015,6 +1052,17 @@ std::pair<int64, int32> ProtoStreamObjectSource::ReadSecondsAndNanos(
return std::pair<int64, int32>(signed_seconds, signed_nanos);
}
+Status ProtoStreamObjectSource::IncrementRecursionDepth(
+ StringPiece type_name, StringPiece field_name) const {
+ if (++recursion_depth_ > max_recursion_depth_) {
+ return Status(
+ util::error::INVALID_ARGUMENT,
+ StrCat("Message too deep. Max recursion depth reached for type '",
+ type_name, "', field '", field_name, "'"));
+ }
+ return Status::OK;
+}
+
namespace {
// TODO(skarvaje): Speed this up by not doing a linear scan.
const google::protobuf::Field* FindFieldByNumber(
diff --git a/src/google/protobuf/util/internal/protostream_objectsource.h b/src/google/protobuf/util/internal/protostream_objectsource.h
index 3cd37aa1..243f85b2 100644
--- a/src/google/protobuf/util/internal/protostream_objectsource.h
+++ b/src/google/protobuf/util/internal/protostream_objectsource.h
@@ -82,6 +82,42 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectSource : public ObjectSource {
virtual util::Status NamedWriteTo(StringPiece name, ObjectWriter* ow) const;
+ // Sets whether or not to use lowerCamelCase casing for enum values. If set to
+ // false, enum values are output without any case conversions.
+ //
+ // For example, if we have an enum:
+ // enum Type {
+ // ACTION_AND_ADVENTURE = 1;
+ // }
+ // Type type = 20;
+ //
+ // And this option is set to true. Then the rendered "type" field will have
+ // the string "actionAndAdventure".
+ // {
+ // ...
+ // "type": "actionAndAdventure",
+ // ...
+ // }
+ //
+ // If set to false, the rendered "type" field will have the string
+ // "ACTION_AND_ADVENTURE".
+ // {
+ // ...
+ // "type": "ACTION_AND_ADVENTURE",
+ // ...
+ // }
+ void set_use_lower_camel_for_enums(bool value) {
+ use_lower_camel_for_enums_ = value;
+ }
+
+ // Sets the max recursion depth of proto message to be deserialized. Proto
+ // messages over this depth will fail to be deserialized.
+ // Default value is 64.
+ void set_max_recursion_depth(int max_depth) {
+ max_recursion_depth_ = max_depth;
+ }
+
+
protected:
// Writes a proto2 Message to the ObjectWriter. When the given end_tag is
// found this method will complete, allowing it to be used for parsing both
@@ -122,20 +158,12 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectSource : public ObjectSource {
StringPiece name, uint32 list_tag,
ObjectWriter* ow) const;
- // Renders an entry in a map, advancing stream pointers appropriately.
- util::Status RenderMapEntry(const google::protobuf::Type* type,
- ObjectWriter* ow) const;
-
// Renders a packed repeating field. A packed field is stored as:
// {tag length item1 item2 item3} instead of the less efficient
// {tag item1 tag item2 tag item3}.
util::Status RenderPacked(const google::protobuf::Field* field,
ObjectWriter* ow) const;
- // Equivalent of RenderPacked, but for map entries.
- util::Status RenderPackedMapEntry(const google::protobuf::Type* type,
- ObjectWriter* ow) const;
-
// Renders a google.protobuf.Timestamp value to ObjectWriter
static util::Status RenderTimestamp(const ProtoStreamObjectSource* os,
const google::protobuf::Type& type,
@@ -210,6 +238,12 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectSource : public ObjectSource {
util::Status RenderField(const google::protobuf::Field* field,
StringPiece field_name, ObjectWriter* ow) const;
+ // Same as above but renders all non-message field types. Callers don't call
+ // this function directly. They just use RenderField.
+ util::Status RenderNonMessageField(const google::protobuf::Field* field,
+ StringPiece field_name,
+ ObjectWriter* ow) const;
+
// Reads field value according to Field spec in 'field' and returns the read
// value as string. This only works for primitive datatypes (no message
@@ -225,6 +259,12 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectSource : public ObjectSource {
std::pair<int64, int32> ReadSecondsAndNanos(
const google::protobuf::Type& type) const;
+ // Helper function to check recursion depth and increment it. It will return
+ // Status::OK if the current depth is allowed. Otherwise an error is returned.
+ // type_name and field_name are used for error reporting.
+ util::Status IncrementRecursionDepth(StringPiece type_name,
+ StringPiece field_name) const;
+
// Input stream to read from. Ownership rests with the caller.
google::protobuf::io::CodedInputStream* stream_;
@@ -238,6 +278,19 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectSource : public ObjectSource {
// google::protobuf::Type of the message source.
const google::protobuf::Type& type_;
+
+ // Whether to render enums using lowerCamelCase. Defaults to false.
+ bool use_lower_camel_for_enums_;
+
+ // Tracks current recursion depth.
+ mutable int recursion_depth_;
+
+ // Maximum allowed recursion depth.
+ int max_recursion_depth_;
+
+ // Whether to render unknown fields.
+ bool render_unknown_fields_;
+
GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(ProtoStreamObjectSource);
};
diff --git a/src/google/protobuf/util/internal/protostream_objectsource_test.cc b/src/google/protobuf/util/internal/protostream_objectsource_test.cc
index f6e5ee7a..3f6fdf97 100644
--- a/src/google/protobuf/util/internal/protostream_objectsource_test.cc
+++ b/src/google/protobuf/util/internal/protostream_objectsource_test.cc
@@ -50,6 +50,7 @@
#include <google/protobuf/util/internal/testdata/anys.pb.h>
#include <google/protobuf/util/internal/testdata/maps.pb.h>
#include <google/protobuf/util/internal/testdata/struct.pb.h>
+#include <google/protobuf/util/internal/testdata/timestamp_duration.pb.h>
#include <gtest/gtest.h>
@@ -69,12 +70,15 @@ using google::protobuf::testing::Author;
using google::protobuf::testing::BadAuthor;
using google::protobuf::testing::BadNestedBook;
using google::protobuf::testing::Book;
+using google::protobuf::testing::Cyclic;
using google::protobuf::testing::Book_Label;
using google::protobuf::testing::NestedBook;
using google::protobuf::testing::PackedPrimitive;
using google::protobuf::testing::Primitive;
using google::protobuf::testing::more_author;
using google::protobuf::testing::maps::MapOut;
+using google::protobuf::testing::maps::MapOutWireFormat;
+using google::protobuf::testing::timestampduration::TimestampDuration;
using google::protobuf::testing::anys::AnyOut;
using google::protobuf::testing::anys::AnyM;
using google::protobuf::testing::FieldMaskTest;
@@ -92,7 +96,11 @@ string GetTypeUrl(const Descriptor* descriptor) {
class ProtostreamObjectSourceTest
: public ::testing::TestWithParam<testing::TypeInfoSource> {
protected:
- ProtostreamObjectSourceTest() : helper_(GetParam()), mock_(), ow_(&mock_) {
+ ProtostreamObjectSourceTest()
+ : helper_(GetParam()),
+ mock_(),
+ ow_(&mock_),
+ use_lower_camel_for_enums_(false) {
helper_.ResetTypeInfo(Book::descriptor());
}
@@ -112,6 +120,8 @@ class ProtostreamObjectSourceTest
google::protobuf::scoped_ptr<ProtoStreamObjectSource> os(
helper_.NewProtoSource(&in_stream, GetTypeUrl(descriptor)));
+ if (use_lower_camel_for_enums_) os->set_use_lower_camel_for_enums(true);
+ os->set_max_recursion_depth(64);
return os->WriteTo(&mock_);
}
@@ -256,10 +266,13 @@ class ProtostreamObjectSourceTest
return primitive;
}
+ void UseLowerCamelForEnums() { use_lower_camel_for_enums_ = true; }
+
testing::TypeInfoTestHelper helper_;
::testing::NiceMock<MockObjectWriter> mock_;
ExpectingObjectWriter ow_;
+ bool use_lower_camel_for_enums_;
};
INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
@@ -327,9 +340,16 @@ TEST_P(ProtostreamObjectSourceTest, RepeatingPrimitives) {
DoTest(primitive, Primitive::descriptor());
}
+TEST_P(ProtostreamObjectSourceTest, CustomJsonName) {
+ Author author;
+ author.set_id(12345);
+
+ ow_.StartObject("")->RenderUint64("@id", 12345)->EndObject();
+ DoTest(author, Author::descriptor());
+}
+
TEST_P(ProtostreamObjectSourceTest, NestedMessage) {
Author* author = new Author();
- author->set_id(101L);
author->set_name("Tolstoy");
Book book;
book.set_title("My Book");
@@ -338,7 +358,6 @@ TEST_P(ProtostreamObjectSourceTest, NestedMessage) {
ow_.StartObject("")
->RenderString("title", "My Book")
->StartObject("author")
- ->RenderUint64("id", bit_cast<uint64>(101LL))
->RenderString("name", "Tolstoy")
->EndObject()
->EndObject();
@@ -455,6 +474,52 @@ TEST_P(ProtostreamObjectSourceTest,
DoTest(book, Book::descriptor());
}
+TEST_P(ProtostreamObjectSourceTest, LowerCamelEnumOutputTest) {
+ Book book;
+ book.set_type(Book::ACTION_AND_ADVENTURE);
+
+ UseLowerCamelForEnums();
+
+ ow_.StartObject("")->RenderString("type", "actionAndAdventure")->EndObject();
+ DoTest(book, Book::descriptor());
+}
+
+TEST_P(ProtostreamObjectSourceTest, EnumCaseIsUnchangedByDefault) {
+ Book book;
+ book.set_type(Book::ACTION_AND_ADVENTURE);
+ ow_.StartObject("")
+ ->RenderString("type", "ACTION_AND_ADVENTURE")
+ ->EndObject();
+ DoTest(book, Book::descriptor());
+}
+
+TEST_P(ProtostreamObjectSourceTest, CyclicMessageDepthTest) {
+ Cyclic cyclic;
+ cyclic.set_m_int(123);
+
+ Book* book = cyclic.mutable_m_book();
+ book->set_title("book title");
+ Cyclic* current = cyclic.mutable_m_cyclic();
+ Author* current_author = cyclic.add_m_author();
+ for (int i = 0; i < 63; ++i) {
+ Author* next = current_author->add_friend_();
+ next->set_id(i);
+ next->set_name(StrCat("author_name_", i));
+ next->set_alive(true);
+ current_author = next;
+ }
+
+ // Recursive message with depth (65) > max (max is 64).
+ for (int i = 0; i < 64; ++i) {
+ Cyclic* next = current->mutable_m_cyclic();
+ next->set_m_str(StrCat("count_", i));
+ current = next;
+ }
+
+ Status status = ExecuteTest(cyclic, Cyclic::descriptor());
+ EXPECT_EQ(util::error::INVALID_ARGUMENT, status.error_code());
+}
+
class ProtostreamObjectSourceMapsTest : public ProtostreamObjectSourceTest {
protected:
ProtostreamObjectSourceMapsTest() {
@@ -535,6 +600,67 @@ TEST_P(ProtostreamObjectSourceMapsTest, MapsTest) {
DoTest(out, MapOut::descriptor());
}
+TEST_P(ProtostreamObjectSourceMapsTest, MissingKeysTest) {
+ // MapOutWireFormat has the same wire representation with MapOut but uses
+ // repeated message fields to represent map fields so we can intentionally
+ // leave out the key field or the value field of a map entry.
+ MapOutWireFormat out;
+ // Create some map entries without keys. They will be rendered with the
+ // default values ("" for strings, "0" for integers, etc.).
+ // {
+ // "map1": {
+ // "": {
+ // "foo": "foovalue"
+ // }
+ // },
+ // "map2": {
+ // "": {
+ // "map1": {
+ // "nested_key1": {
+ // "foo": "nested_foo"
+ // }
+ // }
+ // }
+ // },
+ // "map3": {
+ // "0": "one one one"
+ // },
+ // "map4": {
+ // "false": "bool"
+ // }
+ // }
+ out.add_map1()->mutable_value()->set_foo("foovalue");
+ MapOut* nested = out.add_map2()->mutable_value();
+ (*nested->mutable_map1())["nested_key1"].set_foo("nested_foo");
+ out.add_map3()->set_value("one one one");
+ out.add_map4()->set_value("bool");
+
+ ow_.StartObject("")
+ ->StartObject("map1")
+ ->StartObject("")
+ ->RenderString("foo", "foovalue")
+ ->EndObject()
+ ->EndObject()
+ ->StartObject("map2")
+ ->StartObject("")
+ ->StartObject("map1")
+ ->StartObject("nested_key1")
+ ->RenderString("foo", "nested_foo")
+ ->EndObject()
+ ->EndObject()
+ ->EndObject()
+ ->EndObject()
+ ->StartObject("map3")
+ ->RenderString("0", "one one one")
+ ->EndObject()
+ ->StartObject("map4")
+ ->RenderString("false", "bool")
+ ->EndObject()
+ ->EndObject();
+
+ DoTest(out, MapOut::descriptor());
+}
+
class ProtostreamObjectSourceAnysTest : public ProtostreamObjectSourceTest {
protected:
ProtostreamObjectSourceAnysTest() {
@@ -818,6 +944,63 @@ TEST_P(ProtostreamObjectSourceFieldMaskTest, FieldMaskRenderSuccess) {
DoTest(out, FieldMaskTest::descriptor());
}
+class ProtostreamObjectSourceTimestampTest
+ : public ProtostreamObjectSourceTest {
+ protected:
+ ProtostreamObjectSourceTimestampTest() {
+ helper_.ResetTypeInfo(TimestampDuration::descriptor());
+ }
+};
+
+INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
+ ProtostreamObjectSourceTimestampTest,
+ ::testing::Values(
+ testing::USE_TYPE_RESOLVER));
+
+TEST_P(ProtostreamObjectSourceTimestampTest, InvalidTimestampBelowMinTest) {
+ TimestampDuration out;
+ google::protobuf::Timestamp* ts = out.mutable_ts();
+ // Min allowed seconds - 1
+ ts->set_seconds(kTimestampMinSeconds - 1);
+ ow_.StartObject("");
+
+ Status status = ExecuteTest(out, TimestampDuration::descriptor());
+ EXPECT_EQ(util::error::INTERNAL, status.error_code());
+}
+
+TEST_P(ProtostreamObjectSourceTimestampTest, InvalidTimestampAboveMaxTest) {
+ TimestampDuration out;
+ google::protobuf::Timestamp* ts = out.mutable_ts();
+ // Max allowed seconds + 1
+ ts->set_seconds(kTimestampMaxSeconds + 1);
+ ow_.StartObject("");
+
+ Status status = ExecuteTest(out, TimestampDuration::descriptor());
+ EXPECT_EQ(util::error::INTERNAL, status.error_code());
+}
+
+TEST_P(ProtostreamObjectSourceTimestampTest, InvalidDurationBelowMinTest) {
+ TimestampDuration out;
+ google::protobuf::Duration* dur = out.mutable_dur();
+ // Min allowed seconds - 1
+ dur->set_seconds(kDurationMinSeconds - 1);
+ ow_.StartObject("");
+
+ Status status = ExecuteTest(out, TimestampDuration::descriptor());
+ EXPECT_EQ(util::error::INTERNAL, status.error_code());
+}
+
+TEST_P(ProtostreamObjectSourceTimestampTest, InvalidDurationAboveMaxTest) {
+ TimestampDuration out;
+ google::protobuf::Duration* dur = out.mutable_dur();
+ // Min allowed seconds + 1
+ dur->set_seconds(kDurationMaxSeconds + 1);
+ ow_.StartObject("");
+
+ Status status = ExecuteTest(out, TimestampDuration::descriptor());
+ EXPECT_EQ(util::error::INTERNAL, status.error_code());
+}
+
} // namespace converter
} // namespace util
} // namespace protobuf
diff --git a/src/google/protobuf/util/internal/protostream_objectwriter.cc b/src/google/protobuf/util/internal/protostream_objectwriter.cc
index 0958997c..1825f556 100644
--- a/src/google/protobuf/util/internal/protostream_objectwriter.cc
+++ b/src/google/protobuf/util/internal/protostream_objectwriter.cc
@@ -51,7 +51,6 @@ namespace util {
namespace converter {
using google::protobuf::internal::WireFormatLite;
-using google::protobuf::io::CodedOutputStream;
using util::error::INVALID_ARGUMENT;
using util::Status;
using util::StatusOr;
@@ -59,231 +58,37 @@ using util::StatusOr;
ProtoStreamObjectWriter::ProtoStreamObjectWriter(
TypeResolver* type_resolver, const google::protobuf::Type& type,
- strings::ByteSink* output, ErrorListener* listener)
- : master_type_(type),
- typeinfo_(TypeInfo::NewTypeInfo(type_resolver)),
- own_typeinfo_(true),
- done_(false),
- element_(NULL),
- size_insert_(),
- output_(output),
- buffer_(),
- adapter_(&buffer_),
- stream_(new CodedOutputStream(&adapter_)),
- listener_(listener),
- invalid_depth_(0),
- tracker_(new ObjectLocationTracker()) {}
+ strings::ByteSink* output, ErrorListener* listener,
+ const ProtoStreamObjectWriter::Options& options)
+ : ProtoWriter(type_resolver, type, output, listener),
+ master_type_(type),
+ current_(NULL),
+ options_(options) {
+ set_ignore_unknown_fields(options_.ignore_unknown_fields);
+}
ProtoStreamObjectWriter::ProtoStreamObjectWriter(
const TypeInfo* typeinfo, const google::protobuf::Type& type,
strings::ByteSink* output, ErrorListener* listener)
- : master_type_(type),
- typeinfo_(typeinfo),
- own_typeinfo_(false),
- done_(false),
- element_(NULL),
- size_insert_(),
- output_(output),
- buffer_(),
- adapter_(&buffer_),
- stream_(new CodedOutputStream(&adapter_)),
- listener_(listener),
- invalid_depth_(0),
- tracker_(new ObjectLocationTracker()) {}
+ : ProtoWriter(typeinfo, type, output, listener),
+ master_type_(type),
+ current_(NULL),
+ options_(ProtoStreamObjectWriter::Options::Defaults()) {}
ProtoStreamObjectWriter::~ProtoStreamObjectWriter() {
- if (own_typeinfo_) {
- delete typeinfo_;
- }
- if (element_ == NULL) return;
+ if (current_ == NULL) return;
// Cleanup explicitly in order to avoid destructor stack overflow when input
// is deeply nested.
// Cast to BaseElement to avoid doing additional checks (like missing fields)
// during pop().
google::protobuf::scoped_ptr<BaseElement> element(
- static_cast<BaseElement*>(element_.get())->pop<BaseElement>());
+ static_cast<BaseElement*>(current_.get())->pop<BaseElement>());
while (element != NULL) {
element.reset(element->pop<BaseElement>());
}
}
namespace {
-
-// Writes an INT32 field, including tag to the stream.
-inline Status WriteInt32(int field_number, const DataPiece& data,
- CodedOutputStream* stream) {
- StatusOr<int32> i32 = data.ToInt32();
- if (i32.ok()) {
- WireFormatLite::WriteInt32(field_number, i32.ValueOrDie(), stream);
- }
- return i32.status();
-}
-
-// writes an SFIXED32 field, including tag, to the stream.
-inline Status WriteSFixed32(int field_number, const DataPiece& data,
- CodedOutputStream* stream) {
- StatusOr<int32> i32 = data.ToInt32();
- if (i32.ok()) {
- WireFormatLite::WriteSFixed32(field_number, i32.ValueOrDie(), stream);
- }
- return i32.status();
-}
-
-// Writes an SINT32 field, including tag, to the stream.
-inline Status WriteSInt32(int field_number, const DataPiece& data,
- CodedOutputStream* stream) {
- StatusOr<int32> i32 = data.ToInt32();
- if (i32.ok()) {
- WireFormatLite::WriteSInt32(field_number, i32.ValueOrDie(), stream);
- }
- return i32.status();
-}
-
-// Writes a FIXED32 field, including tag, to the stream.
-inline Status WriteFixed32(int field_number, const DataPiece& data,
- CodedOutputStream* stream) {
- StatusOr<uint32> u32 = data.ToUint32();
- if (u32.ok()) {
- WireFormatLite::WriteFixed32(field_number, u32.ValueOrDie(), stream);
- }
- return u32.status();
-}
-
-// Writes a UINT32 field, including tag, to the stream.
-inline Status WriteUInt32(int field_number, const DataPiece& data,
- CodedOutputStream* stream) {
- StatusOr<uint32> u32 = data.ToUint32();
- if (u32.ok()) {
- WireFormatLite::WriteUInt32(field_number, u32.ValueOrDie(), stream);
- }
- return u32.status();
-}
-
-// Writes an INT64 field, including tag, to the stream.
-inline Status WriteInt64(int field_number, const DataPiece& data,
- CodedOutputStream* stream) {
- StatusOr<int64> i64 = data.ToInt64();
- if (i64.ok()) {
- WireFormatLite::WriteInt64(field_number, i64.ValueOrDie(), stream);
- }
- return i64.status();
-}
-
-// Writes an SFIXED64 field, including tag, to the stream.
-inline Status WriteSFixed64(int field_number, const DataPiece& data,
- CodedOutputStream* stream) {
- StatusOr<int64> i64 = data.ToInt64();
- if (i64.ok()) {
- WireFormatLite::WriteSFixed64(field_number, i64.ValueOrDie(), stream);
- }
- return i64.status();
-}
-
-// Writes an SINT64 field, including tag, to the stream.
-inline Status WriteSInt64(int field_number, const DataPiece& data,
- CodedOutputStream* stream) {
- StatusOr<int64> i64 = data.ToInt64();
- if (i64.ok()) {
- WireFormatLite::WriteSInt64(field_number, i64.ValueOrDie(), stream);
- }
- return i64.status();
-}
-
-// Writes a FIXED64 field, including tag, to the stream.
-inline Status WriteFixed64(int field_number, const DataPiece& data,
- CodedOutputStream* stream) {
- StatusOr<uint64> u64 = data.ToUint64();
- if (u64.ok()) {
- WireFormatLite::WriteFixed64(field_number, u64.ValueOrDie(), stream);
- }
- return u64.status();
-}
-
-// Writes a UINT64 field, including tag, to the stream.
-inline Status WriteUInt64(int field_number, const DataPiece& data,
- CodedOutputStream* stream) {
- StatusOr<uint64> u64 = data.ToUint64();
- if (u64.ok()) {
- WireFormatLite::WriteUInt64(field_number, u64.ValueOrDie(), stream);
- }
- return u64.status();
-}
-
-// Writes a DOUBLE field, including tag, to the stream.
-inline Status WriteDouble(int field_number, const DataPiece& data,
- CodedOutputStream* stream) {
- StatusOr<double> d = data.ToDouble();
- if (d.ok()) {
- WireFormatLite::WriteDouble(field_number, d.ValueOrDie(), stream);
- }
- return d.status();
-}
-
-// Writes a FLOAT field, including tag, to the stream.
-inline Status WriteFloat(int field_number, const DataPiece& data,
- CodedOutputStream* stream) {
- StatusOr<float> f = data.ToFloat();
- if (f.ok()) {
- WireFormatLite::WriteFloat(field_number, f.ValueOrDie(), stream);
- }
- return f.status();
-}
-
-// Writes a BOOL field, including tag, to the stream.
-inline Status WriteBool(int field_number, const DataPiece& data,
- CodedOutputStream* stream) {
- StatusOr<bool> b = data.ToBool();
- if (b.ok()) {
- WireFormatLite::WriteBool(field_number, b.ValueOrDie(), stream);
- }
- return b.status();
-}
-
-// Writes a BYTES field, including tag, to the stream.
-inline Status WriteBytes(int field_number, const DataPiece& data,
- CodedOutputStream* stream) {
- StatusOr<string> c = data.ToBytes();
- if (c.ok()) {
- WireFormatLite::WriteBytes(field_number, c.ValueOrDie(), stream);
- }
- return c.status();
-}
-
-// Writes a STRING field, including tag, to the stream.
-inline Status WriteString(int field_number, const DataPiece& data,
- CodedOutputStream* stream) {
- StatusOr<string> s = data.ToString();
- if (s.ok()) {
- WireFormatLite::WriteString(field_number, s.ValueOrDie(), stream);
- }
- return s.status();
-}
-
-// Writes an ENUM field, including tag, to the stream.
-inline Status WriteEnum(int field_number, const DataPiece& data,
- const google::protobuf::Enum* enum_type,
- CodedOutputStream* stream) {
- StatusOr<int> e = data.ToEnum(enum_type);
- if (e.ok()) {
- WireFormatLite::WriteEnum(field_number, e.ValueOrDie(), stream);
- }
- return e.status();
-}
-
-// Given a google::protobuf::Type, returns the set of all required fields.
-std::set<const google::protobuf::Field*> GetRequiredFields(
- const google::protobuf::Type& type) {
- std::set<const google::protobuf::Field*> required;
- for (int i = 0; i < type.fields_size(); i++) {
- const google::protobuf::Field& field = type.fields(i);
- if (field.cardinality() ==
- google::protobuf::Field_Cardinality_CARDINALITY_REQUIRED) {
- required.insert(&field);
- }
- }
- return required;
-}
-
// Utility method to split a string representation of Timestamp or Duration and
// return the parts.
void SplitSecondsAndNanos(StringPiece input, StringPiece* seconds,
@@ -298,6 +103,78 @@ void SplitSecondsAndNanos(StringPiece input, StringPiece* seconds,
}
}
+Status GetNanosFromStringPiece(StringPiece s_nanos,
+ const char* parse_failure_message,
+ const char* exceeded_limit_message,
+ int32* nanos) {
+ *nanos = 0;
+
+ // Count the number of leading 0s and consume them.
+ int num_leading_zeros = 0;
+ while (s_nanos.Consume("0")) {
+ num_leading_zeros++;
+ }
+ int32 i_nanos = 0;
+ // 's_nanos' contains fractional seconds -- i.e. 'nanos' is equal to
+ // "0." + s_nanos.ToString() seconds. An int32 is used for the
+ // conversion to 'nanos', rather than a double, so that there is no
+ // loss of precision.
+ if (!s_nanos.empty() && !safe_strto32(s_nanos.ToString(), &i_nanos)) {
+ return Status(INVALID_ARGUMENT, parse_failure_message);
+ }
+ if (i_nanos > kNanosPerSecond || i_nanos < 0) {
+ return Status(INVALID_ARGUMENT, exceeded_limit_message);
+ }
+ // s_nanos should only have digits. No whitespace.
+ if (s_nanos.find_first_not_of("0123456789") != StringPiece::npos) {
+ return Status(INVALID_ARGUMENT, parse_failure_message);
+ }
+
+ if (i_nanos > 0) {
+ // 'scale' is the number of digits to the right of the decimal
+ // point in "0." + s_nanos.ToString()
+ int32 scale = num_leading_zeros + s_nanos.size();
+ // 'conversion' converts i_nanos into nanoseconds.
+ // conversion = kNanosPerSecond / static_cast<int32>(std::pow(10, scale))
+ // For efficiency, we precompute the conversion factor.
+ int32 conversion = 0;
+ switch (scale) {
+ case 1:
+ conversion = 100000000;
+ break;
+ case 2:
+ conversion = 10000000;
+ break;
+ case 3:
+ conversion = 1000000;
+ break;
+ case 4:
+ conversion = 100000;
+ break;
+ case 5:
+ conversion = 10000;
+ break;
+ case 6:
+ conversion = 1000;
+ break;
+ case 7:
+ conversion = 100;
+ break;
+ case 8:
+ conversion = 10;
+ break;
+ case 9:
+ conversion = 1;
+ break;
+ default:
+ return Status(INVALID_ARGUMENT, exceeded_limit_message);
+ }
+ *nanos = i_nanos * conversion;
+ }
+
+ return Status::OK;
+}
+
} // namespace
ProtoStreamObjectWriter::AnyWriter::AnyWriter(ProtoStreamObjectWriter* parent)
@@ -307,7 +184,8 @@ ProtoStreamObjectWriter::AnyWriter::AnyWriter(ProtoStreamObjectWriter* parent)
data_(),
output_(&data_),
depth_(0),
- has_injected_value_message_(false) {}
+ is_well_known_type_(false),
+ well_known_type_render_(NULL) {}
ProtoStreamObjectWriter::AnyWriter::~AnyWriter() {}
@@ -325,10 +203,19 @@ void ProtoStreamObjectWriter::AnyWriter::StartObject(StringPiece name) {
parent_->master_type_.name()));
invalid_ = true;
}
- } else if (!has_injected_value_message_ || depth_ != 1 || name != "value") {
- // We don't propagate to ow_ StartObject("value") calls for nested Anys or
- // Struct at depth 1 as they are nested one level deep with an injected
+ } else if (is_well_known_type_ && depth_ == 1) {
+ // For well-known types, the only other field besides "@type" should be a
// "value" field.
+ if (name != "value" && !invalid_) {
+ parent_->InvalidValue("Any",
+ "Expect a \"value\" field for well-known types.");
+ invalid_ = true;
+ }
+ ow_->StartObject("");
+ } else {
+ // Forward the call to the child writer if:
+ // 1. the type is not a well-known type.
+ // 2. or, we are in a nested Any, Struct, or Value object.
ow_->StartObject(name);
}
}
@@ -336,10 +223,9 @@ void ProtoStreamObjectWriter::AnyWriter::StartObject(StringPiece name) {
bool ProtoStreamObjectWriter::AnyWriter::EndObject() {
--depth_;
// As long as depth_ >= 0, we know we haven't reached the end of Any.
- // Propagate these EndObject() calls to the contained ow_. If we are in a
- // nested Any or Struct type, ignore the second to last EndObject call (depth_
- // == -1)
- if (ow_ != NULL && (!has_injected_value_message_ || depth_ >= 0)) {
+ // Propagate these EndObject() calls to the contained ow_. For regular
+ // message types, we propagate the end of Any as well.
+ if (ow_ != NULL && (depth_ >= 0 || !is_well_known_type_)) {
ow_->EndObject();
}
// A negative depth_ implies that we have reached the end of Any
@@ -361,6 +247,13 @@ void ProtoStreamObjectWriter::AnyWriter::StartList(StringPiece name) {
parent_->master_type_.name()));
invalid_ = true;
}
+ } else if (is_well_known_type_ && depth_ == 1) {
+ if (name != "value" && !invalid_) {
+ parent_->InvalidValue("Any",
+ "Expect a \"value\" field for well-known types.");
+ invalid_ = true;
+ }
+ ow_->StartList("");
} else {
ow_->StartList(name);
}
@@ -391,17 +284,27 @@ void ProtoStreamObjectWriter::AnyWriter::RenderDataPiece(
parent_->master_type_.name()));
invalid_ = true;
}
- } else {
- // Check to see if the data needs to be rendered with well-known-type
- // renderer.
- const TypeRenderer* type_renderer =
- FindTypeRenderer(GetFullTypeWithUrl(ow_->master_type_.name()));
- if (type_renderer) {
- Status status = (*type_renderer)(ow_.get(), value);
- if (!status.ok()) ow_->InvalidValue("Any", status.error_message());
+ } else if (depth_ == 0 && is_well_known_type_) {
+ if (name != "value" && !invalid_) {
+ parent_->InvalidValue("Any",
+ "Expect a \"value\" field for well-known types.");
+ invalid_ = true;
+ }
+ if (well_known_type_render_ == NULL) {
+ // Only Any and Struct don't have a special type render but both of
+ // them expect a JSON object (i.e., a StartObject() call).
+ if (!invalid_) {
+ parent_->InvalidValue("Any", "Expect a JSON object.");
+ invalid_ = true;
+ }
} else {
- ow_->RenderDataPiece(name, value);
+ ow_->ProtoWriter::StartObject("");
+ Status status = (*well_known_type_render_)(ow_.get(), value);
+ if (!status.ok()) ow_->InvalidValue("Any", status.error_message());
+ ow_->ProtoWriter::EndObject();
}
+ } else {
+ ow_->RenderDataPiece(name, value);
}
}
@@ -421,7 +324,7 @@ void ProtoStreamObjectWriter::AnyWriter::StartAny(const DataPiece& value) {
}
// Resolve the type url, and report an error if we failed to resolve it.
StatusOr<const google::protobuf::Type*> resolved_type =
- parent_->typeinfo_->ResolveTypeUrl(type_url_);
+ parent_->typeinfo()->ResolveTypeUrl(type_url_);
if (!resolved_type.ok()) {
parent_->InvalidValue("Any", resolved_type.status().error_message());
invalid_ = true;
@@ -430,19 +333,31 @@ void ProtoStreamObjectWriter::AnyWriter::StartAny(const DataPiece& value) {
// At this point, type is never null.
const google::protobuf::Type* type = resolved_type.ValueOrDie();
- // If this is the case of an Any in an Any or Struct in an Any, we need to
- // expect a StartObject call with "value" while we're at depth_ 0, which we
- // should ignore (not propagate to our nested object writer). We also need to
- // ignore the second-to-last EndObject call, and not propagate that either.
- if (type->name() == kAnyType || type->name() == kStructType) {
- has_injected_value_message_ = true;
+ well_known_type_render_ = FindTypeRenderer(type_url_);
+ if (well_known_type_render_ != NULL ||
+ // Explicitly list Any and Struct here because they don't have a
+ // custom renderer.
+ type->name() == kAnyType || type->name() == kStructType) {
+ is_well_known_type_ = true;
}
// Create our object writer and initialize it with the first StartObject
// call.
- ow_.reset(new ProtoStreamObjectWriter(parent_->typeinfo_, *type, &output_,
- parent_->listener_));
- ow_->StartObject("");
+ ow_.reset(new ProtoStreamObjectWriter(parent_->typeinfo(), *type, &output_,
+ parent_->listener()));
+
+ // Don't call StartObject() for well-known types yet. Depending on the
+ // type of actual data, we may not need to call StartObject(). For
+ // example:
+ // {
+ // "@type": "type.googleapis.com/google.protobuf.Value",
+ // "value": [1, 2, 3],
+ // }
+ // With the above JSON representation, we will only call StartList() on the
+ // contained ow_.
+ if (!is_well_known_type_) {
+ ow_->StartObject("");
+ }
}
void ProtoStreamObjectWriter::AnyWriter::WriteAny() {
@@ -453,604 +368,439 @@ void ProtoStreamObjectWriter::AnyWriter::WriteAny() {
}
// Render the type_url and value fields directly to the stream.
// type_url has tag 1 and value has tag 2.
- WireFormatLite::WriteString(1, type_url_, parent_->stream_.get());
+ WireFormatLite::WriteString(1, type_url_, parent_->stream());
if (!data_.empty()) {
- WireFormatLite::WriteBytes(2, data_, parent_->stream_.get());
+ WireFormatLite::WriteBytes(2, data_, parent_->stream());
}
}
-ProtoStreamObjectWriter::ProtoElement::ProtoElement(
- const TypeInfo* typeinfo, const google::protobuf::Type& type,
- ProtoStreamObjectWriter* enclosing)
+ProtoStreamObjectWriter::Item::Item(ProtoStreamObjectWriter* enclosing,
+ ItemType item_type, bool is_placeholder,
+ bool is_list)
: BaseElement(NULL),
ow_(enclosing),
any_(),
- field_(NULL),
- typeinfo_(typeinfo),
- type_(type),
- required_fields_(GetRequiredFields(type)),
- is_repeated_type_(false),
- size_index_(-1),
- array_index_(-1),
- element_type_(GetElementType(type_)) {
- if (element_type_ == ANY) {
+ item_type_(item_type),
+ is_placeholder_(is_placeholder),
+ is_list_(is_list) {
+ if (item_type_ == ANY) {
any_.reset(new AnyWriter(ow_));
}
+ if (item_type == MAP) {
+ map_keys_.reset(new hash_set<string>);
+ }
}
-ProtoStreamObjectWriter::ProtoElement::ProtoElement(
- ProtoStreamObjectWriter::ProtoElement* parent,
- const google::protobuf::Field* field, const google::protobuf::Type& type,
- ElementType element_type)
+ProtoStreamObjectWriter::Item::Item(ProtoStreamObjectWriter::Item* parent,
+ ItemType item_type, bool is_placeholder,
+ bool is_list)
: BaseElement(parent),
ow_(this->parent()->ow_),
any_(),
- field_(field),
- typeinfo_(this->parent()->typeinfo_),
- type_(type),
- is_repeated_type_(element_type == ProtoElement::LIST ||
- element_type == ProtoElement::STRUCT_LIST ||
- element_type == ProtoElement::MAP ||
- element_type == ProtoElement::STRUCT_MAP),
- size_index_(!is_repeated_type_ &&
- field->kind() ==
- google::protobuf::Field_Kind_TYPE_MESSAGE
- ? ow_->size_insert_.size()
- : -1),
- array_index_(is_repeated_type_ ? 0 : -1),
- element_type_(element_type) {
- if (!is_repeated_type_) {
- if (field->cardinality() ==
- google::protobuf::Field_Cardinality_CARDINALITY_REPEATED) {
- // Update array_index_ if it is an explicit list.
- if (this->parent()->array_index_ >= 0) this->parent()->array_index_++;
- } else {
- this->parent()->RegisterField(field);
- }
- if (field->kind() == google::protobuf::Field_Kind_TYPE_MESSAGE) {
- required_fields_ = GetRequiredFields(type_);
- int start_pos = ow_->stream_->ByteCount();
- // length of serialized message is the final buffer position minus
- // starting buffer position, plus length adjustments for size fields
- // of any nested messages. We start with -start_pos here, so we only
- // need to add the final buffer position to it at the end.
- SizeInfo info = {start_pos, -start_pos};
- ow_->size_insert_.push_back(info);
- }
- }
- if (element_type == ANY) {
+ item_type_(item_type),
+ is_placeholder_(is_placeholder),
+ is_list_(is_list) {
+ if (item_type == ANY) {
any_.reset(new AnyWriter(ow_));
}
-}
-
-ProtoStreamObjectWriter::ProtoElement*
-ProtoStreamObjectWriter::ProtoElement::pop() {
- // Calls the registered error listener for any required field(s) not yet
- // seen.
- for (set<const google::protobuf::Field*>::iterator it =
- required_fields_.begin();
- it != required_fields_.end(); ++it) {
- ow_->MissingField((*it)->name());
- }
- // Computes the total number of proto bytes used by a message, also adjusts
- // the size of all parent messages by the length of this size field.
- // If size_index_ < 0, this is not a message, so no size field is added.
- if (size_index_ >= 0) {
- // Add the final buffer position to compute the total length of this
- // serialized message. The stored value (before this addition) already
- // contains the total length of the size fields of all nested messages
- // minus the initial buffer position.
- ow_->size_insert_[size_index_].size += ow_->stream_->ByteCount();
- // Calculate the length required to serialize the size field of the
- // message, and propagate this additional size information upward to
- // all enclosing messages.
- int size = ow_->size_insert_[size_index_].size;
- int length = CodedOutputStream::VarintSize32(size);
- for (ProtoElement* e = parent(); e != NULL; e = e->parent()) {
- // Only nested messages have size field, lists do not have size field.
- if (e->size_index_ >= 0) {
- ow_->size_insert_[e->size_index_].size += length;
- }
- }
+ if (item_type == MAP) {
+ map_keys_.reset(new hash_set<string>);
}
- return BaseElement::pop<ProtoElement>();
}
-void ProtoStreamObjectWriter::ProtoElement::RegisterField(
- const google::protobuf::Field* field) {
- if (!required_fields_.empty() &&
- field->cardinality() ==
- google::protobuf::Field_Cardinality_CARDINALITY_REQUIRED) {
- required_fields_.erase(field);
- }
-}
-
-string ProtoStreamObjectWriter::ProtoElement::ToString() const {
- if (parent() == NULL) return "";
- string loc = parent()->ToString();
- if (field_->cardinality() !=
- google::protobuf::Field_Cardinality_CARDINALITY_REPEATED ||
- parent()->field_ != field_) {
- string name = field_->name();
- int i = 0;
- while (i < name.size() && (ascii_isalnum(name[i]) || name[i] == '_')) ++i;
- if (i > 0 && i == name.size()) { // safe field name
- if (loc.empty()) {
- loc = name;
- } else {
- StrAppend(&loc, ".", name);
- }
- } else {
- StrAppend(&loc, "[\"", CEscape(name), "\"]");
- }
- }
- if (field_->cardinality() ==
- google::protobuf::Field_Cardinality_CARDINALITY_REPEATED &&
- array_index_ > 0) {
- StrAppend(&loc, "[", array_index_ - 1, "]");
- }
- return loc.empty() ? "." : loc;
-}
-
-bool ProtoStreamObjectWriter::ProtoElement::OneofIndexTaken(int32 index) {
- return ContainsKey(oneof_indices_, index);
-}
-
-void ProtoStreamObjectWriter::ProtoElement::TakeOneofIndex(int32 index) {
- InsertIfNotPresent(&oneof_indices_, index);
-}
-
-bool ProtoStreamObjectWriter::ProtoElement::InsertMapKeyIfNotPresent(
+bool ProtoStreamObjectWriter::Item::InsertMapKeyIfNotPresent(
StringPiece map_key) {
- return InsertIfNotPresent(&map_keys_, map_key.ToString());
-}
-
-inline void ProtoStreamObjectWriter::InvalidName(StringPiece unknown_name,
- StringPiece message) {
- listener_->InvalidName(location(), ToSnakeCase(unknown_name), message);
-}
-
-inline void ProtoStreamObjectWriter::InvalidValue(StringPiece type_name,
- StringPiece value) {
- listener_->InvalidValue(location(), type_name, value);
-}
-
-inline void ProtoStreamObjectWriter::MissingField(StringPiece missing_name) {
- listener_->MissingField(location(), missing_name);
+ return InsertIfNotPresent(map_keys_.get(), map_key.ToString());
}
ProtoStreamObjectWriter* ProtoStreamObjectWriter::StartObject(
StringPiece name) {
- // Starting the root message. Create the root ProtoElement and return.
- if (element_ == NULL) {
- if (!name.empty()) {
- InvalidName(name, "Root element should not be named.");
- }
- element_.reset(new ProtoElement(typeinfo_, master_type_, this));
+ if (invalid_depth() > 0) {
+ IncrementInvalidDepth();
+ return this;
+ }
+
+ // Starting the root message. Create the root Item and return.
+ // ANY message type does not need special handling, just set the ItemType
+ // to ANY.
+ if (current_ == NULL) {
+ ProtoWriter::StartObject(name);
+ current_.reset(new Item(
+ this, master_type_.name() == kAnyType ? Item::ANY : Item::MESSAGE,
+ false, false));
// If master type is a special type that needs extra values to be written to
// stream, we write those values.
if (master_type_.name() == kStructType) {
- StartStruct(NULL);
- } else if (master_type_.name() == kStructValueType) {
- // We got a StartObject call with google.protobuf.Value field. This means
- // we are starting an object within google.protobuf.Value type. The only
+ // Struct has a map<string, Value> field called "fields".
+ // https://github.com/google/protobuf/blob/master/src/google/protobuf/struct.proto
+ // "fields": [
+ Push("fields", Item::MAP, true, true);
+ return this;
+ }
+
+ if (master_type_.name() == kStructValueType) {
+ // We got a StartObject call with google.protobuf.Value field. The only
// object within that type is a struct type. So start a struct.
- const google::protobuf::Field* field = StartStructValueInStruct(NULL);
- StartStruct(field);
+ //
+ // The struct field in Value type is named "struct_value"
+ // https://github.com/google/protobuf/blob/master/src/google/protobuf/struct.proto
+ // Also start the map field "fields" within the struct.
+ // "struct_value": {
+ // "fields": [
+ Push("struct_value", Item::MESSAGE, true, false);
+ Push("fields", Item::MAP, true, true);
+ return this;
+ }
+
+ if (master_type_.name() == kStructListValueType) {
+ InvalidValue(kStructListValueType,
+ "Cannot start root message with ListValue.");
}
+
return this;
}
- const google::protobuf::Field* field = NULL;
- if (element_ != NULL && element_->IsAny()) {
- element_->any()->StartObject(name);
+ // Send all ANY events to AnyWriter.
+ if (current_->IsAny()) {
+ current_->any()->StartObject(name);
return this;
- } else if (element_ != NULL &&
- (element_->IsMap() || element_->IsStructMap())) {
+ }
+
+ // If we are within a map, we render name as keys and send StartObject to the
+ // value field.
+ if (current_->IsMap()) {
if (!ValidMapKey(name)) {
- ++invalid_depth_;
+ IncrementInvalidDepth();
return this;
}
- field = StartMapEntry(name);
- if (element_->IsStructMapEntry()) {
- // If the top element is a map entry, this means we are starting another
- // struct within a struct.
- field = StartStructValueInStruct(field);
+ // Map is a repeated field of message type with a "key" and a "value" field.
+ // https://developers.google.com/protocol-buffers/docs/proto3?hl=en#maps
+ // message MapFieldEntry {
+ // key_type key = 1;
+ // value_type value = 2;
+ // }
+ //
+ // repeated MapFieldEntry map_field = N;
+ //
+ // That means, we render the following element within a list (hence no
+ // name):
+ // { "key": "<name>", "value": {
+ Push("", Item::MESSAGE, false, false);
+ ProtoWriter::RenderDataPiece("key",
+ DataPiece(name, use_strict_base64_decoding()));
+ Push("value", Item::MESSAGE, true, false);
+
+ // Make sure we are valid so far after starting map fields.
+ if (invalid_depth() > 0) return this;
+
+ // If top of stack is g.p.Struct type, start the struct the map field within
+ // it.
+ if (element() != NULL && IsStruct(*element()->parent_field())) {
+ // Render "fields": [
+ Push("fields", Item::MAP, true, true);
+ return this;
}
- } else if (element_ != NULL && element_->IsStructList()) {
- // If the top element is a list, then we are starting a list field within a
- // struct.
- field = Lookup(name);
- field = StartStructValueInStruct(field);
- } else {
- field = BeginNamed(name, false);
- }
- if (field == NULL) {
- return this;
- }
- const google::protobuf::Type* type = LookupType(field);
- if (type == NULL) {
- ++invalid_depth_;
- InvalidName(name,
- StrCat("Missing descriptor for field: ", field->type_url()));
+ // If top of stack is g.p.Value type, start the Struct within it.
+ if (element() != NULL && IsStructValue(*element()->parent_field())) {
+ // Render
+ // "struct_value": {
+ // "fields": [
+ Push("struct_value", Item::MESSAGE, true, false);
+ Push("fields", Item::MAP, true, true);
+ }
return this;
}
- // Check to see if this field is a oneof and that no oneof in that group has
- // already been set.
- if (!ValidOneof(*field, name)) {
- ++invalid_depth_;
- return this;
- }
+ const google::protobuf::Field* field = BeginNamed(name, false);
+ if (field == NULL) return this;
- if (field->type_url() == GetFullTypeWithUrl(kStructType)) {
+ if (IsStruct(*field)) {
// Start a struct object.
- StartStruct(field);
- } else if (field->type_url() == GetFullTypeWithUrl(kStructValueType)) {
- // We got a StartObject call with google.protobuf.Value field. This means we
- // are starting an object within google.protobuf.Value type. The only object
- // within that type is a struct type. So start a struct.
- field = StartStructValueInStruct(field);
- StartStruct(field);
- } else if (field->type_url() == GetFullTypeWithUrl(kAnyType)) {
- // Begin an Any. We can't do the real work till we get the @type field.
- WriteTag(*field);
- element_.reset(
- new ProtoElement(element_.release(), field, *type, ProtoElement::ANY));
- } else if (IsMap(*field)) {
- // Begin a map.
- // A map is triggered by a StartObject() call if the current field has a map
- // type. Map values are written to proto in a manner detailed in comments
- // above StartMapEntry() function.
- element_.reset(
- new ProtoElement(element_.release(), field, *type, ProtoElement::MAP));
- } else {
- WriteTag(*field);
- element_.reset(new ProtoElement(element_.release(), field, *type,
- ProtoElement::MESSAGE));
+ // Render
+ // "<name>": {
+ // "fields": {
+ Push(name, Item::MESSAGE, false, false);
+ Push("fields", Item::MAP, true, true);
+ return this;
}
- return this;
-}
-
-// Proto3 maps are represented on the wire as a message with
-// "key" and a "value".
-//
-// For example, the syntax:
-// map<key_type, value_type> map_field = N;
-//
-// is represented as:
-// message MapFieldEntry {
-// option map_entry = true; // marks the map construct in the descriptor
-//
-// key_type key = 1;
-// value_type value = 2;
-// }
-// repeated MapFieldEntry map_field = N;
-//
-// See go/proto3-maps for more information.
-const google::protobuf::Field* ProtoStreamObjectWriter::StartMapEntry(
- StringPiece name) {
- // top of stack is already a map field
- const google::protobuf::Field* field = element_->field();
- const google::protobuf::Type& type = element_->type();
- // If we come from a regular map, use MAP_ENTRY or if we come from a struct,
- // use STRUCT_MAP_ENTRY. These values are used later in StartObject/StartList
- // or RenderDataPiece for making appropriate decisions.
- ProtoElement::ElementType element_type = element_->IsStructMap()
- ? ProtoElement::STRUCT_MAP_ENTRY
- : ProtoElement::MAP_ENTRY;
- WriteTag(*field);
- element_.reset(
- new ProtoElement(element_.release(), field, type, element_type));
- RenderDataPiece("key", DataPiece(name));
- return BeginNamed("value", false);
-}
-// Starts a google.protobuf.Struct.
-// 'field' represents a field in a message of type google.protobuf.Struct. A
-// struct contains a map with name 'fields'. This function starts this map as
-// well.
-// When 'field' is NULL, it means that the top level message is of struct
-// type.
-void ProtoStreamObjectWriter::StartStruct(
- const google::protobuf::Field* field) {
- const google::protobuf::Type* type = NULL;
- if (field) {
- type = LookupType(field);
- WriteTag(*field);
- element_.reset(new ProtoElement(element_.release(), field, *type,
- ProtoElement::STRUCT));
- }
- const google::protobuf::Field* struct_field = BeginNamed("fields", false);
-
- if (!struct_field) {
- // It is a programmatic error if this happens. Log an error.
- GOOGLE_LOG(ERROR) << "Invalid internal state. Cannot find 'fields' within "
- << (field ? field->type_url() : "google.protobuf.Struct");
- return;
+ if (IsStructValue(*field)) {
+ // We got a StartObject call with google.protobuf.Value field. The only
+ // object within that type is a struct type. So start a struct.
+ // Render
+ // "<name>": {
+ // "struct_value": {
+ // "fields": {
+ Push(name, Item::MESSAGE, false, false);
+ Push("struct_value", Item::MESSAGE, true, false);
+ Push("fields", Item::MAP, true, true);
+ return this;
}
- type = LookupType(struct_field);
- element_.reset(new ProtoElement(element_.release(), struct_field, *type,
- ProtoElement::STRUCT_MAP));
-}
-
-// Starts a "struct_value" within struct.proto's google.protobuf.Value type.
-// 'field' should be of the type google.protobuf.Value.
-// Returns the field identifying "struct_value" within the given field.
-//
-// If field is NULL, then we are starting struct_value at the top-level, in
-// this case skip writing any tag information for the passed field.
-const google::protobuf::Field*
-ProtoStreamObjectWriter::StartStructValueInStruct(
- const google::protobuf::Field* field) {
- if (field) {
- const google::protobuf::Type* type = LookupType(field);
- WriteTag(*field);
- element_.reset(new ProtoElement(element_.release(), field, *type,
- ProtoElement::STRUCT_VALUE));
- }
- return BeginNamed("struct_value", false);
-}
-
-// Starts a "list_value" within struct.proto's google.protobuf.Value type.
-// 'field' should be of the type google.protobuf.Value.
-// Returns the field identifying "list_value" within the given field.
-//
-// If field is NULL, then we are starting list_value at the top-level, in
-// this case skip writing any tag information for the passed field.
-const google::protobuf::Field* ProtoStreamObjectWriter::StartListValueInStruct(
- const google::protobuf::Field* field) {
- if (field) {
- const google::protobuf::Type* type = LookupType(field);
- WriteTag(*field);
- element_.reset(new ProtoElement(element_.release(), field, *type,
- ProtoElement::STRUCT_VALUE));
- }
- const google::protobuf::Field* list_value = BeginNamed("list_value", false);
-
- if (!list_value) {
- // It is a programmatic error if this happens. Log an error.
- GOOGLE_LOG(ERROR) << "Invalid internal state. Cannot find 'list_value' within "
- << (field ? field->type_url() : "google.protobuf.Value");
- return field;
- }
-
- return StartRepeatedValuesInListValue(list_value);
-}
-
-// Starts the repeated "values" field in struct.proto's
-// google.protobuf.ListValue type. 'field' should be of type
-// google.protobuf.ListValue.
-//
-// If field is NULL, then we are starting ListValue at the top-level, in
-// this case skip writing any tag information for the passed field.
-const google::protobuf::Field*
-ProtoStreamObjectWriter::StartRepeatedValuesInListValue(
- const google::protobuf::Field* field) {
- if (field) {
- const google::protobuf::Type* type = LookupType(field);
- WriteTag(*field);
- element_.reset(new ProtoElement(element_.release(), field, *type,
- ProtoElement::STRUCT_LIST_VALUE));
- }
- return BeginNamed("values", true);
-}
-
-void ProtoStreamObjectWriter::SkipElements() {
- if (element_ == NULL) return;
-
- ProtoElement::ElementType element_type = element_->element_type();
- while (element_type == ProtoElement::STRUCT ||
- element_type == ProtoElement::STRUCT_LIST_VALUE ||
- element_type == ProtoElement::STRUCT_VALUE ||
- element_type == ProtoElement::STRUCT_MAP_ENTRY ||
- element_type == ProtoElement::MAP_ENTRY) {
- element_.reset(element_->pop());
- element_type =
- element_ != NULL ? element_->element_type() : ProtoElement::MESSAGE;
+ 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
+ // "<name>": [
+ Push(name, Item::MAP, false, true);
+ return this;
}
+
+ // A regular message type. Pass it directly to ProtoWriter.
+ // Render
+ // "<name>": {
+ Push(name, IsAny(*field) ? Item::ANY : Item::MESSAGE, false, false);
+ return this;
}
ProtoStreamObjectWriter* ProtoStreamObjectWriter::EndObject() {
- if (invalid_depth_ > 0) {
- --invalid_depth_;
+ if (invalid_depth() > 0) {
+ DecrementInvalidDepth();
return this;
}
- if (element_ != NULL && element_->IsAny()) {
- if (element_->any()->EndObject()) {
- return this;
- }
- }
- if (element_ != NULL) {
- element_.reset(element_->pop());
- }
-
- // Skip sentinel elements added to keep track of new proto3 types - map,
- // struct.
- SkipElements();
+ if (current_ == NULL) return this;
- // If ending the root element,
- // then serialize the full message with calculated sizes.
- if (element_ == NULL) {
- WriteRootMessage();
+ if (current_->IsAny()) {
+ if (current_->any()->EndObject()) return this;
}
+
+ Pop();
+
return this;
}
ProtoStreamObjectWriter* ProtoStreamObjectWriter::StartList(StringPiece name) {
- const google::protobuf::Field* field = NULL;
+ if (invalid_depth() > 0) {
+ IncrementInvalidDepth();
+ return this;
+ }
+
// Since we cannot have a top-level repeated item in protobuf, the only way
- // element_ can be null when here is when we start a top-level list
- // google.protobuf.ListValue.
- if (element_ == NULL) {
+ // this is valid is if we start a special type google.protobuf.ListValue or
+ // google.protobuf.Value.
+ if (current_ == NULL) {
if (!name.empty()) {
InvalidName(name, "Root element should not be named.");
+ IncrementInvalidDepth();
+ return this;
}
- element_.reset(new ProtoElement(typeinfo_, master_type_, this));
// If master type is a special type that needs extra values to be written to
// stream, we write those values.
if (master_type_.name() == kStructValueType) {
// We got a StartList with google.protobuf.Value master type. This means
// we have to start the "list_value" within google.protobuf.Value.
- field = StartListValueInStruct(NULL);
- } else if (master_type_.name() == kStructListValueType) {
+ //
+ // See
+ // https://github.com/google/protobuf/blob/master/src/google/protobuf/struct.proto
+ //
+ // Render
+ // "<name>": {
+ // "list_value": {
+ // "values": [ // Start this list.
+ ProtoWriter::StartObject(name);
+ current_.reset(new Item(this, Item::MESSAGE, false, false));
+ Push("list_value", Item::MESSAGE, true, false);
+ Push("values", Item::MESSAGE, true, true);
+ return this;
+ }
+
+ if (master_type_.name() == kStructListValueType) {
// We got a StartList with google.protobuf.ListValue master type. This
// means we have to start the "values" within google.protobuf.ListValue.
- field = StartRepeatedValuesInListValue(NULL);
+ //
+ // Render
+ // "<name>": {
+ // "values": [ // Start this list.
+ ProtoWriter::StartObject(name);
+ current_.reset(new Item(this, Item::MESSAGE, false, false));
+ Push("values", Item::MESSAGE, true, true);
+ return this;
}
- // field is NULL when master_type_ is anything other than
- // google.protobuf.Value or google.protobuf.ListValue.
- if (field) {
- const google::protobuf::Type* type = LookupType(field);
- element_.reset(new ProtoElement(element_.release(), field, *type,
- ProtoElement::STRUCT_LIST));
- }
+ // Send the event to ProtoWriter so proper errors can be reported.
+ //
+ // Render a regular list:
+ // "<name>": [
+ ProtoWriter::StartList(name);
+ current_.reset(new Item(this, Item::MESSAGE, false, true));
return this;
}
- if (element_->IsAny()) {
- element_->any()->StartList(name);
+ if (current_->IsAny()) {
+ current_->any()->StartList(name);
return this;
}
- // The type of element we push to stack.
- ProtoElement::ElementType element_type = ProtoElement::LIST;
- // Check if we need to start a map. This can heppen when there is either a map
- // or a struct type within a list.
- if (element_->IsMap() || element_->IsStructMap()) {
+ // If the top of stack is a map, we are starting a list value within a map.
+ // Since map does not allow repeated values, this can only happen when the map
+ // value is of a special type that renders a list in JSON. These can be one
+ // of 3 cases:
+ // i. We are rendering a list value within google.protobuf.Struct
+ // ii. We are rendering a list value within google.protobuf.Value
+ // iii. We are rendering a list value with type google.protobuf.ListValue.
+ if (current_->IsMap()) {
if (!ValidMapKey(name)) {
- ++invalid_depth_;
+ IncrementInvalidDepth();
return this;
}
- field = StartMapEntry(name);
- if (field == NULL) return this;
+ // Start the repeated map entry object.
+ // Render
+ // { "key": "<name>", "value": {
+ Push("", Item::MESSAGE, false, false);
+ ProtoWriter::RenderDataPiece("key",
+ DataPiece(name, use_strict_base64_decoding()));
+ Push("value", Item::MESSAGE, true, false);
+
+ // Make sure we are valid after pushing all above items.
+ if (invalid_depth() > 0) return this;
+
+ // case i and ii above. Start "list_value" field within g.p.Value
+ if (element() != NULL && element()->parent_field() != NULL) {
+ // Render
+ // "list_value": {
+ // "values": [ // Start this list
+ if (IsStructValue(*element()->parent_field())) {
+ Push("list_value", Item::MESSAGE, true, false);
+ Push("values", Item::MESSAGE, true, true);
+ return this;
+ }
- if (element_->IsStructMapEntry()) {
- // If the top element is a map entry, this means we are starting a list
- // within a struct or a map.
- // An example sequence of calls would be
- // StartObject -> StartList
- field = StartListValueInStruct(field);
- if (field == NULL) return this;
+ // Render
+ // "values": [
+ if (IsStructListValue(*element()->parent_field())) {
+ // case iii above. Bind directly to g.p.ListValue
+ Push("values", Item::MESSAGE, true, true);
+ return this;
+ }
}
- element_type = ProtoElement::STRUCT_LIST;
- } else if (element_->IsStructList()) {
- // If the top element is a STRUCT_LIST, this means we are starting a list
- // within the current list (inside a struct).
- // An example call sequence would be
- // StartObject -> StartList -> StartList
- // with StartObject starting a struct.
+ // Report an error.
+ InvalidValue("Map", StrCat("Cannot have repeated items ('", name,
+ "') within a map."));
+ return this;
+ }
- // Lookup the last list type in element stack as we are adding an element of
- // the same type.
- field = Lookup(name);
- if (field == NULL) return this;
+ // When name is empty and stack is not empty, we are rendering an item within
+ // a list.
+ if (name.empty()) {
+ if (element() != NULL && element()->parent_field() != NULL) {
+ if (IsStructValue(*element()->parent_field())) {
+ // Since it is g.p.Value, we bind directly to the list_value.
+ // Render
+ // { // g.p.Value item within the list
+ // "list_value": {
+ // "values": [
+ Push("", Item::MESSAGE, false, false);
+ Push("list_value", Item::MESSAGE, true, false);
+ Push("values", Item::MESSAGE, true, true);
+ return this;
+ }
- field = StartListValueInStruct(field);
- if (field == NULL) return this;
+ if (IsStructListValue(*element()->parent_field())) {
+ // Since it is g.p.ListValue, we bind to it directly.
+ // Render
+ // { // g.p.ListValue item within the list
+ // "values": [
+ Push("", Item::MESSAGE, false, false);
+ Push("values", Item::MESSAGE, true, true);
+ return this;
+ }
+ }
- element_type = ProtoElement::STRUCT_LIST;
- } else {
- // Lookup field corresponding to 'name'. If it is a google.protobuf.Value
- // or google.protobuf.ListValue type, then StartList is a valid call, start
- // this list.
- // We cannot use Lookup() here as it will produce InvalidName() error if the
- // field is not found. We do not want to error here as it would cause us to
- // report errors twice, once here and again later in BeginNamed() call.
- // Also we ignore if the field is not found here as it is caught later.
- field = typeinfo_->FindField(&element_->type(), name);
-
- // Only check for oneof collisions on the first StartList call. We identify
- // the first call with !name.empty() check. Subsequent list element calls
- // will not have the name filled.
- if (!name.empty() && field && !ValidOneof(*field, name)) {
- ++invalid_depth_;
+ // Pass the event to underlying ProtoWriter.
+ Push(name, Item::MESSAGE, false, true);
+ return this;
+ }
+
+ // name is not empty
+ const google::protobuf::Field* field = Lookup(name);
+ if (field == NULL) {
+ IncrementInvalidDepth();
+ return this;
+ }
+
+ if (IsStructValue(*field)) {
+ // If g.p.Value is repeated, start that list. Otherwise, start the
+ // "list_value" within it.
+ if (IsRepeated(*field)) {
+ // Render it just like a regular repeated field.
+ // "<name>": [
+ Push(name, Item::MESSAGE, false, true);
return this;
}
- // It is an error to try to bind to map, which behind the scenes is a list.
- if (field && IsMap(*field)) {
- // Push field to stack for error location tracking & reporting.
- element_.reset(new ProtoElement(element_.release(), field,
- *LookupType(field),
- ProtoElement::MESSAGE));
- InvalidValue("Map", "Cannot bind a list to map.");
- ++invalid_depth_;
- element_.reset(element_->pop());
+ // Start the "list_value" field.
+ // Render
+ // "<name>": {
+ // "list_value": {
+ // "values": [
+ Push(name, Item::MESSAGE, false, false);
+ Push("list_value", Item::MESSAGE, true, false);
+ Push("values", Item::MESSAGE, true, true);
+ return this;
+ }
+
+ if (IsStructListValue(*field)) {
+ // If g.p.ListValue is repeated, start that list. Otherwise, start the
+ // "values" within it.
+ if (IsRepeated(*field)) {
+ // Render it just like a regular repeated field.
+ // "<name>": [
+ Push(name, Item::MESSAGE, false, true);
return this;
}
- if (field && field->type_url() == GetFullTypeWithUrl(kStructValueType)) {
- // There are 2 cases possible:
- // a. g.p.Value is repeated
- // b. g.p.Value is not repeated
- //
- // For case (a), the StartList should bind to the repeated g.p.Value.
- // For case (b), the StartList should bind to g.p.ListValue within the
- // g.p.Value.
- //
- // This means, for case (a), we treat it just like any other repeated
- // message, except we would apply an appropriate element_type so future
- // Start or Render calls are routed appropriately.
- if (field->cardinality() !=
- google::protobuf::Field_Cardinality_CARDINALITY_REPEATED) {
- field = StartListValueInStruct(field);
- }
- element_type = ProtoElement::STRUCT_LIST;
- } else if (field &&
- field->type_url() == GetFullTypeWithUrl(kStructListValueType)) {
- // We got a StartList with google.protobuf.ListValue master type. This
- // means we have to start the "values" within google.protobuf.ListValue.
- field = StartRepeatedValuesInListValue(field);
- } else {
- // If no special types are to be bound, fall back to normal processing of
- // StartList.
- field = BeginNamed(name, true);
- }
- if (field == NULL) return this;
+ // Start the "values" field within g.p.ListValue.
+ // Render
+ // "<name>": {
+ // "values": [
+ Push(name, Item::MESSAGE, false, false);
+ Push("values", Item::MESSAGE, true, true);
+ return this;
}
- const google::protobuf::Type* type = LookupType(field);
- if (type == NULL) {
- ++invalid_depth_;
- InvalidName(name,
- StrCat("Missing descriptor for field: ", field->type_url()));
+ // If we are here, the field should be repeated. Report an error otherwise.
+ if (!IsRepeated(*field)) {
+ IncrementInvalidDepth();
+ InvalidName(name, "Proto field is not repeating, cannot start list.");
+ return this;
+ }
+
+ if (IsMap(*field)) {
+ InvalidValue("Map",
+ StrCat("Cannot bind a list to map for field '", name, "'."));
+ IncrementInvalidDepth();
return this;
}
- element_.reset(
- new ProtoElement(element_.release(), field, *type, element_type));
+ // Pass the event to ProtoWriter.
+ // Render
+ // "<name>": [
+ Push(name, Item::MESSAGE, false, true);
return this;
}
ProtoStreamObjectWriter* ProtoStreamObjectWriter::EndList() {
- if (invalid_depth_ > 0) {
- --invalid_depth_;
- } else if (element_ != NULL) {
- if (element_->IsAny()) {
- element_->any()->EndList();
- } else {
- element_.reset(element_->pop());
- // Skip sentinel elements added to keep track of new proto3 types - map,
- // struct.
- SkipElements();
- }
+ if (invalid_depth() > 0) {
+ DecrementInvalidDepth();
+ return this;
}
- // When element_ is NULL, we have reached the root message type. Write out
- // the bytes.
- if (element_ == NULL) {
- WriteRootMessage();
+ if (current_ == NULL) return this;
+
+ if (current_->IsAny()) {
+ current_->any()->EndList();
+ return this;
}
+
+ Pop();
return this;
}
@@ -1059,8 +809,36 @@ Status ProtoStreamObjectWriter::RenderStructValue(ProtoStreamObjectWriter* ow,
string struct_field_name;
switch (data.type()) {
// Our JSON parser parses numbers as either int64, uint64, or double.
- case DataPiece::TYPE_INT64:
- case DataPiece::TYPE_UINT64:
+ case DataPiece::TYPE_INT64: {
+ // If the option to treat integers as strings is set, then render them as
+ // strings. Otherwise, fallback to rendering them as double.
+ if (ow->options_.struct_integers_as_strings) {
+ StatusOr<int64> int_value = data.ToInt64();
+ if (int_value.ok()) {
+ ow->ProtoWriter::RenderDataPiece(
+ "string_value",
+ DataPiece(SimpleItoa(int_value.ValueOrDie()), true));
+ return Status::OK;
+ }
+ }
+ struct_field_name = "number_value";
+ break;
+ }
+ case DataPiece::TYPE_UINT64: {
+ // If the option to treat integers as strings is set, then render them as
+ // strings. Otherwise, fallback to rendering them as double.
+ if (ow->options_.struct_integers_as_strings) {
+ StatusOr<uint64> int_value = data.ToUint64();
+ if (int_value.ok()) {
+ ow->ProtoWriter::RenderDataPiece(
+ "string_value",
+ DataPiece(SimpleItoa(int_value.ValueOrDie()), true));
+ return Status::OK;
+ }
+ }
+ struct_field_name = "number_value";
+ break;
+ }
case DataPiece::TYPE_DOUBLE: {
struct_field_name = "number_value";
break;
@@ -1083,7 +861,7 @@ Status ProtoStreamObjectWriter::RenderStructValue(ProtoStreamObjectWriter* ow,
"null values are supported.");
}
}
- ow->RenderDataPiece(struct_field_name, data);
+ ow->ProtoWriter::RenderDataPiece(struct_field_name, data);
return Status::OK;
}
@@ -1105,15 +883,15 @@ Status ProtoStreamObjectWriter::RenderTimestamp(ProtoStreamObjectWriter* ow,
}
- ow->RenderDataPiece("seconds", DataPiece(seconds));
- ow->RenderDataPiece("nanos", DataPiece(nanos));
+ ow->ProtoWriter::RenderDataPiece("seconds", DataPiece(seconds));
+ ow->ProtoWriter::RenderDataPiece("nanos", DataPiece(nanos));
return Status::OK;
}
static inline util::Status RenderOneFieldPath(ProtoStreamObjectWriter* ow,
StringPiece path) {
- ow->RenderDataPiece("paths",
- DataPiece(ConvertFieldMaskPath(path, &ToSnakeCase)));
+ ow->ProtoWriter::RenderDataPiece(
+ "paths", DataPiece(ConvertFieldMaskPath(path, &ToSnakeCase), true));
return Status::OK;
}
@@ -1129,7 +907,7 @@ Status ProtoStreamObjectWriter::RenderFieldMask(ProtoStreamObjectWriter* ow,
// conversions as much as possible. Because ToSnakeCase sometimes returns the
// wrong value.
google::protobuf::scoped_ptr<ResultCallback1<util::Status, StringPiece> > callback(
- google::protobuf::internal::NewPermanentCallback(&RenderOneFieldPath, ow));
+ ::google::protobuf::internal::NewPermanentCallback(&RenderOneFieldPath, ow));
return DecodeCompactFieldMaskPaths(data.str(), callback.get());
}
@@ -1162,224 +940,136 @@ Status ProtoStreamObjectWriter::RenderDuration(ProtoStreamObjectWriter* ow,
"Invalid duration format, failed to parse seconds");
}
- double d_nanos = 0;
- if (!safe_strtod("0." + s_nanos.ToString(), &d_nanos)) {
- return Status(INVALID_ARGUMENT,
- "Invalid duration format, failed to parse nanos seconds");
+ int32 nanos = 0;
+ Status nanos_status = GetNanosFromStringPiece(
+ s_nanos, "Invalid duration format, failed to parse nano seconds",
+ "Duration value exceeds limits", &nanos);
+ if (!nanos_status.ok()) {
+ return nanos_status;
}
+ nanos = sign * nanos;
- int32 nanos = sign * static_cast<int32>(d_nanos * kNanosPerSecond);
int64 seconds = sign * unsigned_seconds;
-
- if (seconds > kMaxSeconds || seconds < kMinSeconds ||
+ if (seconds > kDurationMaxSeconds || seconds < kDurationMinSeconds ||
nanos <= -kNanosPerSecond || nanos >= kNanosPerSecond) {
return Status(INVALID_ARGUMENT, "Duration value exceeds limits");
}
- ow->RenderDataPiece("seconds", DataPiece(seconds));
- ow->RenderDataPiece("nanos", DataPiece(nanos));
+ ow->ProtoWriter::RenderDataPiece("seconds", DataPiece(seconds));
+ ow->ProtoWriter::RenderDataPiece("nanos", DataPiece(nanos));
return Status::OK;
}
Status ProtoStreamObjectWriter::RenderWrapperType(ProtoStreamObjectWriter* ow,
const DataPiece& data) {
- ow->RenderDataPiece("value", data);
+ ow->ProtoWriter::RenderDataPiece("value", data);
return Status::OK;
}
ProtoStreamObjectWriter* ProtoStreamObjectWriter::RenderDataPiece(
StringPiece name, const DataPiece& data) {
Status status;
- if (invalid_depth_ > 0) return this;
- if (element_ != NULL && element_->IsAny()) {
- element_->any()->RenderDataPiece(name, data);
+ if (invalid_depth() > 0) return this;
+
+ if (current_ == NULL) {
+ const TypeRenderer* type_renderer =
+ FindTypeRenderer(GetFullTypeWithUrl(master_type_.name()));
+ if (type_renderer == NULL) {
+ InvalidName(name, "Root element must be a message.");
+ return this;
+ }
+ // Render the special type.
+ // "<name>": {
+ // ... Render special type ...
+ // }
+ ProtoWriter::StartObject(name);
+ status = (*type_renderer)(this, data);
+ if (!status.ok()) {
+ InvalidValue(master_type_.name(),
+ StrCat("Field '", name, "', ", status.error_message()));
+ }
+ ProtoWriter::EndObject();
+ return this;
+ }
+
+ if (current_->IsAny()) {
+ current_->any()->RenderDataPiece(name, data);
return this;
}
const google::protobuf::Field* field = NULL;
- string type_url;
- bool is_map_entry = false;
- // We are at the root when element_ == NULL.
- if (element_ == NULL) {
- type_url = GetFullTypeWithUrl(master_type_.name());
- } else {
- if (element_->IsMap() || element_->IsStructMap()) {
- if (!ValidMapKey(name)) return this;
- is_map_entry = true;
- field = StartMapEntry(name);
- } else {
- field = Lookup(name);
- }
+ if (current_->IsMap()) {
+ if (!ValidMapKey(name)) return this;
+
+ // Render an item in repeated map list.
+ // { "key": "<name>", "value":
+ Push("", Item::MESSAGE, false, false);
+ ProtoWriter::RenderDataPiece("key",
+ DataPiece(name, use_strict_base64_decoding()));
+ field = Lookup("value");
if (field == NULL) {
+ Pop();
+ GOOGLE_LOG(DFATAL) << "Map does not have a value field.";
return this;
}
- // Check to see if this field is a oneof and that no oneof in that group has
- // already been set.
- if (!ValidOneof(*field, name)) return this;
+ const TypeRenderer* type_renderer = FindTypeRenderer(field->type_url());
+ if (type_renderer != NULL) {
+ // Map's value type is a special type. Render it like a message:
+ // "value": {
+ // ... Render special type ...
+ // }
+ Push("value", Item::MESSAGE, true, false);
+ status = (*type_renderer)(this, data);
+ if (!status.ok()) {
+ InvalidValue(field->type_url(),
+ StrCat("Field '", name, "', ", status.error_message()));
+ }
+ Pop();
+ return this;
+ }
+
+ // If we are rendering explicit null values and the backend proto field is
+ // not of the google.protobuf.NullType type, we do nothing.
+ if (data.type() == DataPiece::TYPE_NULL &&
+ field->type_url() != kStructNullValueTypeUrl) {
+ Pop();
+ return this;
+ }
- type_url = field->type_url();
+ // Render the map value as a primitive type.
+ ProtoWriter::RenderDataPiece("value", data);
+ Pop();
+ return this;
}
- // Check if there are any well known type renderers available for type_url.
- const TypeRenderer* type_renderer = FindTypeRenderer(type_url);
+ field = Lookup(name);
+ if (field == NULL) return this;
+
+ // Check if the field is of special type. Render it accordingly if so.
+ const TypeRenderer* type_renderer = FindTypeRenderer(field->type_url());
if (type_renderer != NULL) {
- // Push the current element to stack so lookups in type_renderer will
- // find the fields. We do an EndObject soon after, which pops this. This is
- // safe because all well-known types are messages.
- if (element_ == NULL) {
- element_.reset(new ProtoElement(typeinfo_, master_type_, this));
- } else {
- if (field) {
- WriteTag(*field);
- const google::protobuf::Type* type = LookupType(field);
- element_.reset(new ProtoElement(element_.release(), field, *type,
- ProtoElement::MESSAGE));
- }
- }
+ Push(name, Item::MESSAGE, false, false);
status = (*type_renderer)(this, data);
if (!status.ok()) {
- InvalidValue(type_url,
+ InvalidValue(field->type_url(),
StrCat("Field '", name, "', ", status.error_message()));
}
- EndObject();
- return this;
- } else if (element_ == NULL) { // no message type found at root
- element_.reset(new ProtoElement(typeinfo_, master_type_, this));
- InvalidName(name, "Root element must be a message.");
+ Pop();
return this;
}
- if (field == NULL) {
- return this;
- }
- const google::protobuf::Type* type = LookupType(field);
- if (type == NULL) {
- InvalidName(name,
- StrCat("Missing descriptor for field: ", field->type_url()));
+ // If we are rendering explicit null values and the backend proto field is
+ // not of the google.protobuf.NullType type, we do nothing.
+ if (data.type() == DataPiece::TYPE_NULL &&
+ field->type_url() != kStructNullValueTypeUrl) {
return this;
}
- // Whether we should pop at the end. Set to true if the data field is a
- // message type, which can happen in case of struct values.
- bool should_pop = false;
-
- RenderSimpleDataPiece(*field, *type, data);
-
- if (should_pop && element_ != NULL) {
- element_.reset(element_->pop());
- }
-
- if (is_map_entry) {
- // Ending map is the same as ending an object.
- EndObject();
- }
+ ProtoWriter::RenderDataPiece(name, data);
return this;
}
-void ProtoStreamObjectWriter::RenderSimpleDataPiece(
- const google::protobuf::Field& field, const google::protobuf::Type& type,
- const DataPiece& data) {
- // If we are rendering explicit null values and the backend proto field is not
- // of the google.protobuf.NullType type, we do nothing.
- if (data.type() == DataPiece::TYPE_NULL &&
- field.type_url() != kStructNullValueTypeUrl) {
- return;
- }
-
- // Pushing a ProtoElement and then pop it off at the end for 2 purposes:
- // error location reporting and required field accounting.
- element_.reset(new ProtoElement(element_.release(), &field, type,
- ProtoElement::MESSAGE));
-
- // Make sure that field represents a simple data type.
- if (field.kind() == google::protobuf::Field_Kind_TYPE_UNKNOWN ||
- field.kind() == google::protobuf::Field_Kind_TYPE_MESSAGE) {
- InvalidValue(field.type_url().empty()
- ? google::protobuf::Field_Kind_Name(field.kind())
- : field.type_url(),
- data.ValueAsStringOrDefault(""));
- return;
- }
-
- Status status;
- switch (field.kind()) {
- case google::protobuf::Field_Kind_TYPE_INT32: {
- status = WriteInt32(field.number(), data, stream_.get());
- break;
- }
- case google::protobuf::Field_Kind_TYPE_SFIXED32: {
- status = WriteSFixed32(field.number(), data, stream_.get());
- break;
- }
- case google::protobuf::Field_Kind_TYPE_SINT32: {
- status = WriteSInt32(field.number(), data, stream_.get());
- break;
- }
- case google::protobuf::Field_Kind_TYPE_FIXED32: {
- status = WriteFixed32(field.number(), data, stream_.get());
- break;
- }
- case google::protobuf::Field_Kind_TYPE_UINT32: {
- status = WriteUInt32(field.number(), data, stream_.get());
- break;
- }
- case google::protobuf::Field_Kind_TYPE_INT64: {
- status = WriteInt64(field.number(), data, stream_.get());
- break;
- }
- case google::protobuf::Field_Kind_TYPE_SFIXED64: {
- status = WriteSFixed64(field.number(), data, stream_.get());
- break;
- }
- case google::protobuf::Field_Kind_TYPE_SINT64: {
- status = WriteSInt64(field.number(), data, stream_.get());
- break;
- }
- case google::protobuf::Field_Kind_TYPE_FIXED64: {
- status = WriteFixed64(field.number(), data, stream_.get());
- break;
- }
- case google::protobuf::Field_Kind_TYPE_UINT64: {
- status = WriteUInt64(field.number(), data, stream_.get());
- break;
- }
- case google::protobuf::Field_Kind_TYPE_DOUBLE: {
- status = WriteDouble(field.number(), data, stream_.get());
- break;
- }
- case google::protobuf::Field_Kind_TYPE_FLOAT: {
- status = WriteFloat(field.number(), data, stream_.get());
- break;
- }
- case google::protobuf::Field_Kind_TYPE_BOOL: {
- status = WriteBool(field.number(), data, stream_.get());
- break;
- }
- case google::protobuf::Field_Kind_TYPE_BYTES: {
- status = WriteBytes(field.number(), data, stream_.get());
- break;
- }
- case google::protobuf::Field_Kind_TYPE_STRING: {
- status = WriteString(field.number(), data, stream_.get());
- break;
- }
- case google::protobuf::Field_Kind_TYPE_ENUM: {
- status = WriteEnum(field.number(), data,
- typeinfo_->GetEnumByTypeUrl(field.type_url()),
- stream_.get());
- break;
- }
- default: // TYPE_GROUP or TYPE_MESSAGE
- status = Status(INVALID_ARGUMENT, data.ToString().ValueOrDie());
- }
- if (!status.ok()) {
- InvalidValue(google::protobuf::Field_Kind_Name(field.kind()),
- status.error_message());
- }
- element_.reset(element_->pop());
-}
-
// Map of functions that are responsible for rendering well known type
// represented by the key.
hash_map<string, ProtoStreamObjectWriter::TypeRenderer>*
@@ -1446,45 +1136,12 @@ ProtoStreamObjectWriter::FindTypeRenderer(const string& type_url) {
return FindOrNull(*renderers_, type_url);
}
-ProtoStreamObjectWriter::ProtoElement::ElementType
-ProtoStreamObjectWriter::GetElementType(const google::protobuf::Type& type) {
- if (type.name() == kAnyType) {
- return ProtoElement::ANY;
- } else if (type.name() == kStructType) {
- return ProtoElement::STRUCT;
- } else if (type.name() == kStructValueType) {
- return ProtoElement::STRUCT_VALUE;
- } else if (type.name() == kStructListValueType) {
- return ProtoElement::STRUCT_LIST_VALUE;
- } else {
- return ProtoElement::MESSAGE;
- }
-}
-
-bool ProtoStreamObjectWriter::ValidOneof(const google::protobuf::Field& field,
- StringPiece unnormalized_name) {
- if (element_ == NULL) return true;
-
- if (field.oneof_index() > 0) {
- if (element_->OneofIndexTaken(field.oneof_index())) {
- InvalidValue(
- "oneof",
- StrCat("oneof field '",
- element_->type().oneofs(field.oneof_index() - 1),
- "' is already set. Cannot set '", unnormalized_name, "'"));
- return false;
- }
- element_->TakeOneofIndex(field.oneof_index());
- }
- return true;
-}
-
bool ProtoStreamObjectWriter::ValidMapKey(StringPiece unnormalized_name) {
- if (element_ == NULL) return true;
+ if (current_ == NULL) return true;
- if (!element_->InsertMapKeyIfNotPresent(unnormalized_name)) {
- InvalidName(
- unnormalized_name,
+ if (!current_->InsertMapKeyIfNotPresent(unnormalized_name)) {
+ listener()->InvalidName(
+ location(), unnormalized_name,
StrCat("Repeated map key: '", unnormalized_name, "' is already set."));
return false;
}
@@ -1492,134 +1149,30 @@ bool ProtoStreamObjectWriter::ValidMapKey(StringPiece unnormalized_name) {
return true;
}
-const google::protobuf::Field* ProtoStreamObjectWriter::BeginNamed(
- StringPiece name, bool is_list) {
- if (invalid_depth_ > 0) {
- ++invalid_depth_;
- return NULL;
- }
- const google::protobuf::Field* field = Lookup(name);
- if (field == NULL) {
- ++invalid_depth_;
- // InvalidName() already called in Lookup().
- return NULL;
- }
- if (is_list &&
- field->cardinality() !=
- google::protobuf::Field_Cardinality_CARDINALITY_REPEATED) {
- ++invalid_depth_;
- InvalidName(name, "Proto field is not repeating, cannot start list.");
- return NULL;
- }
- return field;
-}
-
-const google::protobuf::Field* ProtoStreamObjectWriter::Lookup(
- StringPiece unnormalized_name) {
- ProtoElement* e = element();
- if (e == NULL) {
- InvalidName(unnormalized_name, "Root element must be a message.");
- return NULL;
- }
- if (unnormalized_name.empty()) {
- // Objects in repeated field inherit the same field descriptor.
- if (e->field() == NULL) {
- InvalidName(unnormalized_name, "Proto fields must have a name.");
- } else if (e->field()->cardinality() !=
- google::protobuf::Field_Cardinality_CARDINALITY_REPEATED) {
- InvalidName(unnormalized_name, "Proto fields must have a name.");
- return NULL;
- }
- return e->field();
- }
- const google::protobuf::Field* field =
- typeinfo_->FindField(&e->type(), unnormalized_name);
- if (field == NULL) InvalidName(unnormalized_name, "Cannot find field.");
- return field;
-}
+void ProtoStreamObjectWriter::Push(StringPiece name, Item::ItemType item_type,
+ bool is_placeholder, bool is_list) {
+ is_list ? ProtoWriter::StartList(name) : ProtoWriter::StartObject(name);
-const google::protobuf::Type* ProtoStreamObjectWriter::LookupType(
- const google::protobuf::Field* field) {
- return (field->kind() == google::protobuf::Field_Kind_TYPE_MESSAGE
- ? typeinfo_->GetTypeByTypeUrl(field->type_url())
- : &element_->type());
+ // invalid_depth == 0 means it is a successful StartObject or StartList.
+ if (invalid_depth() == 0)
+ current_.reset(
+ new Item(current_.release(), item_type, is_placeholder, is_list));
}
-// Looks up the oneof struct field based on the data type.
-StatusOr<const google::protobuf::Field*>
-ProtoStreamObjectWriter::LookupStructField(DataPiece::Type type) {
- const google::protobuf::Field* field = NULL;
- switch (type) {
- // Our JSON parser parses numbers as either int64, uint64, or double.
- case DataPiece::TYPE_INT64:
- case DataPiece::TYPE_UINT64:
- case DataPiece::TYPE_DOUBLE: {
- field = Lookup("number_value");
- break;
- }
- case DataPiece::TYPE_STRING: {
- field = Lookup("string_value");
- break;
- }
- case DataPiece::TYPE_BOOL: {
- field = Lookup("bool_value");
- break;
- }
- case DataPiece::TYPE_NULL: {
- field = Lookup("null_value");
- break;
- }
- default: { return Status(INVALID_ARGUMENT, "Invalid struct data type"); }
+void ProtoStreamObjectWriter::Pop() {
+ // Pop all placeholder items sending StartObject or StartList events to
+ // ProtoWriter according to is_list value.
+ while (current_ != NULL && current_->is_placeholder()) {
+ PopOneElement();
}
- if (field == NULL) {
- return Status(INVALID_ARGUMENT, "Could not lookup struct field");
+ if (current_ != NULL) {
+ PopOneElement();
}
- return field;
}
-void ProtoStreamObjectWriter::WriteRootMessage() {
- GOOGLE_DCHECK(!done_);
- int curr_pos = 0;
- // Calls the destructor of CodedOutputStream to remove any uninitialized
- // memory from the Cord before we read it.
- stream_.reset(NULL);
- const void* data;
- int length;
- google::protobuf::io::ArrayInputStream input_stream(buffer_.data(), buffer_.size());
- while (input_stream.Next(&data, &length)) {
- if (length == 0) continue;
- int num_bytes = length;
- // Write up to where we need to insert the size field.
- // The number of bytes we may write is the smaller of:
- // - the current fragment size
- // - the distance to the next position where a size field needs to be
- // inserted.
- if (!size_insert_.empty() &&
- size_insert_.front().pos - curr_pos < num_bytes) {
- num_bytes = size_insert_.front().pos - curr_pos;
- }
- output_->Append(static_cast<const char*>(data), num_bytes);
- if (num_bytes < length) {
- input_stream.BackUp(length - num_bytes);
- }
- curr_pos += num_bytes;
- // Insert the size field.
- // size_insert_.front(): the next <index, size> pair to be written.
- // size_insert_.front().pos: position of the size field.
- // size_insert_.front().size: the size (integer) to be inserted.
- if (!size_insert_.empty() && curr_pos == size_insert_.front().pos) {
- // Varint32 occupies at most 10 bytes.
- uint8 insert_buffer[10];
- uint8* insert_buffer_pos = CodedOutputStream::WriteVarint32ToArray(
- size_insert_.front().size, insert_buffer);
- output_->Append(reinterpret_cast<const char*>(insert_buffer),
- insert_buffer_pos - insert_buffer);
- size_insert_.pop_front();
- }
- }
- output_->Flush();
- stream_.reset(new CodedOutputStream(&adapter_));
- done_ = true;
+void ProtoStreamObjectWriter::PopOneElement() {
+ current_->is_list() ? ProtoWriter::EndList() : ProtoWriter::EndObject();
+ current_.reset(current_->pop<Item>());
}
bool ProtoStreamObjectWriter::IsMap(const google::protobuf::Field& field) {
@@ -1630,7 +1183,7 @@ bool ProtoStreamObjectWriter::IsMap(const google::protobuf::Field& field) {
return false;
}
const google::protobuf::Type* field_type =
- typeinfo_->GetTypeByTypeUrl(field.type_url());
+ typeinfo()->GetTypeByTypeUrl(field.type_url());
// TODO(xiaofeng): Unify option names.
return GetBoolOptionOrDefault(field_type->options(),
@@ -1638,12 +1191,23 @@ bool ProtoStreamObjectWriter::IsMap(const google::protobuf::Field& field) {
GetBoolOptionOrDefault(field_type->options(), "map_entry", false);
}
-void ProtoStreamObjectWriter::WriteTag(const google::protobuf::Field& field) {
- WireFormatLite::WireType wire_type = WireFormatLite::WireTypeForFieldType(
- static_cast<WireFormatLite::FieldType>(field.kind()));
- stream_->WriteTag(WireFormatLite::MakeTag(field.number(), wire_type));
+bool ProtoStreamObjectWriter::IsAny(const google::protobuf::Field& field) {
+ return GetTypeWithoutUrl(field.type_url()) == kAnyType;
}
+bool ProtoStreamObjectWriter::IsStruct(const google::protobuf::Field& field) {
+ return GetTypeWithoutUrl(field.type_url()) == kStructType;
+}
+
+bool ProtoStreamObjectWriter::IsStructValue(
+ const google::protobuf::Field& field) {
+ return GetTypeWithoutUrl(field.type_url()) == kStructValueType;
+}
+
+bool ProtoStreamObjectWriter::IsStructListValue(
+ const google::protobuf::Field& field) {
+ return GetTypeWithoutUrl(field.type_url()) == kStructListValueType;
+}
} // namespace converter
} // namespace util
diff --git a/src/google/protobuf/util/internal/protostream_objectwriter.h b/src/google/protobuf/util/internal/protostream_objectwriter.h
index 6e133679..2e4d14d1 100644
--- a/src/google/protobuf/util/internal/protostream_objectwriter.h
+++ b/src/google/protobuf/util/internal/protostream_objectwriter.h
@@ -42,6 +42,7 @@
#include <google/protobuf/util/internal/type_info.h>
#include <google/protobuf/util/internal/datapiece.h>
#include <google/protobuf/util/internal/error_listener.h>
+#include <google/protobuf/util/internal/proto_writer.h>
#include <google/protobuf/util/internal/structured_objectwriter.h>
#include <google/protobuf/util/type_resolver.h>
#include <google/protobuf/stubs/bytestream.h>
@@ -67,14 +68,41 @@ namespace converter {
class ObjectLocationTracker;
// An ObjectWriter that can write protobuf bytes directly from writer events.
+// This class supports all special types like Struct and Map. It uses
+// the ProtoWriter class to write raw proto bytes.
//
// It also supports streaming.
-class LIBPROTOBUF_EXPORT ProtoStreamObjectWriter : public StructuredObjectWriter {
+class LIBPROTOBUF_EXPORT ProtoStreamObjectWriter : public ProtoWriter {
public:
+ // Options that control ProtoStreamObjectWriter class's behavior.
+ struct Options {
+ // Treats integer inputs in google.protobuf.Struct as strings. Normally,
+ // integer values are returned in double field "number_value" of
+ // google.protobuf.Struct. However, this can cause precision loss for
+ // int64/uint64 inputs. This option is provided for cases that want to
+ // preserve integer precision.
+ bool struct_integers_as_strings;
+
+ // Not treat unknown fields as an error. If there is an unknown fields,
+ // just ignore it and continue to process the rest.
+ bool ignore_unknown_fields;
+
+ Options()
+ : struct_integers_as_strings(false), ignore_unknown_fields(false) {}
+
+ // Default instance of Options with all options set to defaults.
+ static const Options& Defaults() {
+ static Options defaults;
+ return defaults;
+ }
+ };
+
// Constructor. Does not take ownership of any parameter passed in.
ProtoStreamObjectWriter(TypeResolver* type_resolver,
const google::protobuf::Type& type,
- strings::ByteSink* output, ErrorListener* listener);
+ strings::ByteSink* output, ErrorListener* listener,
+ const ProtoStreamObjectWriter::Options& options =
+ ProtoStreamObjectWriter::Options::Defaults());
virtual ~ProtoStreamObjectWriter();
// ObjectWriter methods.
@@ -82,56 +110,13 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectWriter : public StructuredObjectWriter
virtual ProtoStreamObjectWriter* EndObject();
virtual ProtoStreamObjectWriter* StartList(StringPiece name);
virtual ProtoStreamObjectWriter* EndList();
- virtual ProtoStreamObjectWriter* RenderBool(StringPiece name, bool value) {
- return RenderDataPiece(name, DataPiece(value));
- }
- virtual ProtoStreamObjectWriter* RenderInt32(StringPiece name, int32 value) {
- return RenderDataPiece(name, DataPiece(value));
- }
- virtual ProtoStreamObjectWriter* RenderUint32(StringPiece name,
- uint32 value) {
- return RenderDataPiece(name, DataPiece(value));
- }
- virtual ProtoStreamObjectWriter* RenderInt64(StringPiece name, int64 value) {
- return RenderDataPiece(name, DataPiece(value));
- }
- virtual ProtoStreamObjectWriter* RenderUint64(StringPiece name,
- uint64 value) {
- return RenderDataPiece(name, DataPiece(value));
- }
- virtual ProtoStreamObjectWriter* RenderDouble(StringPiece name,
- double value) {
- return RenderDataPiece(name, DataPiece(value));
- }
- virtual ProtoStreamObjectWriter* RenderFloat(StringPiece name, float value) {
- return RenderDataPiece(name, DataPiece(value));
- }
- virtual ProtoStreamObjectWriter* RenderString(StringPiece name,
- StringPiece value) {
- return RenderDataPiece(name, DataPiece(value));
- }
- virtual ProtoStreamObjectWriter* RenderBytes(StringPiece name,
- StringPiece value) {
- return RenderDataPiece(name, DataPiece(value, false));
- }
- virtual ProtoStreamObjectWriter* RenderNull(StringPiece name) {
- return RenderDataPiece(name, DataPiece::NullData());
- }
// Renders a DataPiece 'value' into a field whose wire type is determined
// from the given field 'name'.
- ProtoStreamObjectWriter* RenderDataPiece(StringPiece name,
- const DataPiece& value);
-
- // Returns the location tracker to use for tracking locations for errors.
- const LocationTrackerInterface& location() {
- return element_ != NULL ? *element_ : *tracker_;
- }
+ virtual ProtoStreamObjectWriter* RenderDataPiece(StringPiece name,
+ const DataPiece& value);
- // When true, we finished writing to output a complete message.
- bool done() const { return done_; }
-
- private:
+ protected:
// Function that renders a well known type with modified behavior.
typedef util::Status (*TypeRenderer)(ProtoStreamObjectWriter*,
const DataPiece&);
@@ -187,78 +172,47 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectWriter : public StructuredObjectWriter
// The depth within the Any, so we can track when we're done.
int depth_;
- // True if the message type contained in Any has a special "value" message
- // injected. This is true for well-known message types like Any or Struct.
- bool has_injected_value_message_;
+ // True if the type is a well-known type. Well-known types in Any
+ // has a special formating:
+ // {
+ // "@type": "type.googleapis.com/google.protobuf.XXX",
+ // "value": <JSON representation of the type>,
+ // }
+ bool is_well_known_type_;
+ TypeRenderer* well_known_type_render_;
};
- class LIBPROTOBUF_EXPORT ProtoElement : public BaseElement, public LocationTrackerInterface {
+ // Represents an item in a stack of items used to keep state between
+ // ObjectWrier events.
+ class LIBPROTOBUF_EXPORT Item : public BaseElement {
public:
- // Indicates the type of element. Special types like LIST, MAP, MAP_ENTRY,
- // STRUCT etc. are used to deduce other information based on their position
- // on the stack of elements.
- enum ElementType {
- MESSAGE, // Simple message
- LIST, // List/repeated element
- MAP, // Proto3 map type
- MAP_ENTRY, // Proto3 map message type, with 'key' and 'value' fields
- ANY, // Proto3 Any type
- STRUCT, // Proto3 struct type
- STRUCT_VALUE, // Struct's Value message type
- STRUCT_LIST, // List type indicator within a struct
- STRUCT_LIST_VALUE, // Struct Value's ListValue message type
- STRUCT_MAP, // Struct within a struct type
- STRUCT_MAP_ENTRY // Struct map's entry type with 'key' and 'value'
- // fields
+ // Indicates the type of item.
+ enum ItemType {
+ MESSAGE, // Simple message
+ MAP, // Proto3 map type
+ ANY, // Proto3 Any type
};
- // Constructor for the root element. No parent nor field.
- ProtoElement(const TypeInfo* typeinfo, const google::protobuf::Type& type,
- ProtoStreamObjectWriter* enclosing);
-
- // Constructor for a field of an element.
- ProtoElement(ProtoElement* parent, const google::protobuf::Field* field,
- const google::protobuf::Type& type, ElementType element_type);
+ // Constructor for the root item.
+ Item(ProtoStreamObjectWriter* enclosing, ItemType item_type,
+ bool is_placeholder, bool is_list);
- virtual ~ProtoElement() {}
+ // Constructor for a field of a message.
+ Item(Item* parent, ItemType item_type, bool is_placeholder, bool is_list);
- // Called just before the destructor for clean up:
- // - reports any missing required fields
- // - computes the space needed by the size field, and augment the
- // length of all parent messages by this additional space.
- // - releases and returns the parent pointer.
- ProtoElement* pop();
-
- // Accessors
- const google::protobuf::Field* field() const { return field_; }
- const google::protobuf::Type& type() const { return type_; }
+ virtual ~Item() {}
// These functions return true if the element type is corresponding to the
// type in function name.
- bool IsMap() { return element_type_ == MAP; }
- bool IsStructMap() { return element_type_ == STRUCT_MAP; }
- bool IsStructMapEntry() { return element_type_ == STRUCT_MAP_ENTRY; }
- bool IsStructList() { return element_type_ == STRUCT_LIST; }
- bool IsAny() { return element_type_ == ANY; }
-
- ElementType element_type() { return element_type_; }
-
- void RegisterField(const google::protobuf::Field* field);
- virtual string ToString() const;
+ bool IsMap() { return item_type_ == MAP; }
+ bool IsAny() { return item_type_ == ANY; }
AnyWriter* any() const { return any_.get(); }
- virtual ProtoElement* parent() const {
- return static_cast<ProtoElement*>(BaseElement::parent());
+ virtual Item* parent() const {
+ return static_cast<Item*>(BaseElement::parent());
}
- // Returns true if the index is already taken by a preceeding oneof input.
- bool OneofIndexTaken(int32 index);
-
- // Marks the oneof 'index' as taken. Future inputs to this oneof will
- // generate an error.
- void TakeOneofIndex(int32 index);
-
// Inserts map key into hash set if and only if the key did NOT already
// exist in hash set.
// The hash set (map_keys_) is ONLY used to keep track of map keys.
@@ -266,6 +220,9 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectWriter : public StructuredObjectWriter
// already present.
bool InsertMapKeyIfNotPresent(StringPiece map_key);
+ bool is_placeholder() const { return is_placeholder_; }
+ bool is_list() const { return is_list_; }
+
private:
// Used for access to variables of the enclosing instance of
// ProtoStreamObjectWriter.
@@ -274,126 +231,42 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectWriter : public StructuredObjectWriter
// A writer for Any objects, handles all Any-related nonsense.
google::protobuf::scoped_ptr<AnyWriter> any_;
- // Describes the element as a field in the parent message.
- // field_ is NULL if and only if this element is the root element.
- const google::protobuf::Field* field_;
-
- // TypeInfo to lookup types.
- const TypeInfo* typeinfo_;
-
- // Additional variables if this element is a message:
- // (Root element is always a message).
- // descriptor_ : describes allowed fields in the message.
- // required_fields_: set of required fields.
- // is_repeated_type_ : true if the element is of type list or map.
- // size_index_ : index into ProtoStreamObjectWriter::size_insert_
- // for later insertion of serialized message length.
- const google::protobuf::Type& type_;
- std::set<const google::protobuf::Field*> required_fields_;
- const bool is_repeated_type_;
- const int size_index_;
-
- // Tracks position in repeated fields, needed for LocationTrackerInterface.
- int array_index_;
-
// The type of this element, see enum for permissible types.
- ElementType element_type_;
-
- // Set of oneof indices already seen for the type_. Used to validate
- // incoming messages so no more than one oneof is set.
- hash_set<int32> oneof_indices_;
+ ItemType item_type_;
// Set of map keys already seen for the type_. Used to validate incoming
// messages so no map key appears more than once.
- hash_set<string> map_keys_;
+ google::protobuf::scoped_ptr<hash_set<string> > map_keys_;
- GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(ProtoElement);
- };
+ // Conveys whether this Item is a placeholder or not. Placeholder items are
+ // pushed to stack to account for special types.
+ bool is_placeholder_;
+
+ // Conveys whether this Item is a list or not. This is used to send
+ // StartList or EndList calls to underlying ObjectWriter.
+ bool is_list_;
- // Container for inserting 'size' information at the 'pos' position.
- struct SizeInfo {
- const int pos;
- int size;
+ GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(Item);
};
ProtoStreamObjectWriter(const TypeInfo* typeinfo,
const google::protobuf::Type& type,
strings::ByteSink* output, ErrorListener* listener);
- ProtoElement* element() { return element_.get(); }
-
- // Helper methods for calling ErrorListener. See error_listener.h.
- void InvalidName(StringPiece unknown_name, StringPiece message);
- void InvalidValue(StringPiece type_name, StringPiece value);
- void MissingField(StringPiece missing_name);
-
- // Common code for BeginObject() and BeginList() that does invalid_depth_
- // bookkeeping associated with name lookup.
- const google::protobuf::Field* BeginNamed(StringPiece name, bool is_list);
-
- // Lookup the field in the current element. Looks in the base descriptor
- // and in any extension. This will report an error if the field cannot be
- // found or if multiple matching extensions are found.
- const google::protobuf::Field* Lookup(StringPiece name);
-
- // Lookup the field type in the type descriptor. Returns NULL if the type
- // is not known.
- const google::protobuf::Type* LookupType(
- const google::protobuf::Field* field);
-
- // Looks up the oneof struct Value field depending on the type.
- // On failure to find, it returns an appropriate error.
- util::StatusOr<const google::protobuf::Field*> LookupStructField(
- DataPiece::Type type);
-
- // Starts an entry in map. This will be called after placing map element at
- // the top of the stack. Uses this information to write map entries.
- const google::protobuf::Field* StartMapEntry(StringPiece name);
-
- // Starts a google.protobuf.Struct.
- // 'field' is of type google.protobuf.Struct.
- // If field is NULL, it indicates that the top-level message is a struct
- // type.
- void StartStruct(const google::protobuf::Field* field);
-
- // Starts another struct within a struct.
- // 'field' is of type google.protobuf.Value (see struct.proto).
- const google::protobuf::Field* StartStructValueInStruct(
- const google::protobuf::Field* field);
-
- // Starts a list within a struct.
- // 'field' is of type google.protobuf.ListValue (see struct.proto).
- const google::protobuf::Field* StartListValueInStruct(
- const google::protobuf::Field* field);
-
- // Starts the repeated "values" field in struct.proto's
- // google.protobuf.ListValue type. 'field' should be of type
- // google.protobuf.ListValue.
- const google::protobuf::Field* StartRepeatedValuesInListValue(
- const google::protobuf::Field* field);
-
- // Pops sentinel elements off the stack.
- void SkipElements();
-
- // Write serialized output to the final output ByteSink, inserting all
- // the size information for nested messages that are missing from the
- // intermediate Cord buffer.
- void WriteRootMessage();
-
// Returns true if the field is a map.
- bool IsMap(const google::protobuf::Field& field);
+ inline bool IsMap(const google::protobuf::Field& field);
// Returns true if the field is an any.
- bool IsAny(const google::protobuf::Field& field);
+ inline bool IsAny(const google::protobuf::Field& field);
- // Helper method to write proto tags based on the given field.
- void WriteTag(const google::protobuf::Field& field);
+ // Returns true if the field is google.protobuf.Struct.
+ inline bool IsStruct(const google::protobuf::Field& field);
+ // Returns true if the field is google.protobuf.Value.
+ inline bool IsStructValue(const google::protobuf::Field& field);
- // Helper function to render primitive data types in DataPiece.
- void RenderSimpleDataPiece(const google::protobuf::Field& field,
- const google::protobuf::Type& type,
- const DataPiece& data);
+ // Returns true if the field is google.protobuf.ListValue.
+ inline bool IsStructListValue(const google::protobuf::Field& field);
// Renders google.protobuf.Value in struct.proto. It picks the right oneof
// type based on value's type.
@@ -417,69 +290,49 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectWriter : public StructuredObjectWriter
static util::Status RenderWrapperType(ProtoStreamObjectWriter* ow,
const DataPiece& value);
- // Helper functions to create the map and find functions responsible for
- // rendering well known types, keyed by type URL.
- static hash_map<string, TypeRenderer>* renderers_;
static void InitRendererMap();
static void DeleteRendererMap();
static TypeRenderer* FindTypeRenderer(const string& type_url);
- // Returns the ProtoElement::ElementType for the given Type.
- static ProtoElement::ElementType GetElementType(
- const google::protobuf::Type& type);
-
- // Returns true if the field for type_ can be set as a oneof. If field is not
- // a oneof type, this function does nothing and returns true.
- // If another field for this oneof is already set, this function returns
- // false. It also calls the appropriate error callback.
- // unnormalized_name is used for error string.
- bool ValidOneof(const google::protobuf::Field& field,
- StringPiece unnormalized_name);
-
// Returns true if the map key for type_ is not duplicated key.
// If map key is duplicated key, this function returns false.
- // Note that caller should make sure that the current proto element (element_)
+ // Note that caller should make sure that the current proto element (current_)
// is of element type MAP or STRUCT_MAP.
// It also calls the appropriate error callback and unnormalzied_name is used
// for error string.
bool ValidMapKey(StringPiece unnormalized_name);
+ // Pushes an item on to the stack. Also calls either StartObject or StartList
+ // on the underlying ObjectWriter depending on whether is_list is false or
+ // not.
+ // is_placeholder conveys whether the item is a placeholder item or not.
+ // Placeholder items are pushed when adding auxillary types' StartObject or
+ // StartList calls.
+ void Push(StringPiece name, Item::ItemType item_type, bool is_placeholder,
+ bool is_list);
+
+ // Pops items from the stack. All placeholder items are popped until a
+ // non-placeholder item is found.
+ void Pop();
+
+ // Pops one element from the stack. Calls EndObject() or EndList() on the
+ // underlying ObjectWriter depending on the value of is_list_.
+ void PopOneElement();
+
+ private:
+ // Helper functions to create the map and find functions responsible for
+ // rendering well known types, keyed by type URL.
+ static hash_map<string, TypeRenderer>* renderers_;
+
// Variables for describing the structure of the input tree:
// master_type_: descriptor for the whole protobuf message.
- // typeinfo_ : the TypeInfo object to lookup types.
const google::protobuf::Type& master_type_;
- const TypeInfo* typeinfo_;
- // Whether we own the typeinfo_ object.
- bool own_typeinfo_;
-
- // Indicates whether we finished writing root message completely.
- bool done_;
-
- // Variable for internal state processing:
- // element_ : the current element.
- // size_insert_: sizes of nested messages.
- // pos - position to insert the size field.
- // size - size value to be inserted.
- google::protobuf::scoped_ptr<ProtoElement> element_;
- std::deque<SizeInfo> size_insert_;
-
- // Variables for output generation:
- // output_ : pointer to an external ByteSink for final user-visible output.
- // buffer_ : buffer holding partial message before being ready for output_.
- // adapter_ : internal adapter between CodedOutputStream and Cord buffer_.
- // stream_ : wrapper for writing tags and other encodings in wire format.
- strings::ByteSink* output_;
- string buffer_;
- google::protobuf::io::StringOutputStream adapter_;
- google::protobuf::scoped_ptr<google::protobuf::io::CodedOutputStream> stream_;
-
- // Variables for error tracking and reporting:
- // listener_ : a place to report any errors found.
- // invalid_depth_: number of enclosing invalid nested messages.
- // tracker_ : the root location tracker interface.
- ErrorListener* listener_;
- int invalid_depth_;
- google::protobuf::scoped_ptr<LocationTrackerInterface> tracker_;
+
+ // The current element, variable for internal state processing.
+ google::protobuf::scoped_ptr<Item> current_;
+
+ // Reference to the options that control this class's behavior.
+ const ProtoStreamObjectWriter::Options options_;
GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(ProtoStreamObjectWriter);
};
diff --git a/src/google/protobuf/util/internal/protostream_objectwriter_test.cc b/src/google/protobuf/util/internal/protostream_objectwriter_test.cc
index cb9f97f7..30e58e62 100644
--- a/src/google/protobuf/util/internal/protostream_objectwriter_test.cc
+++ b/src/google/protobuf/util/internal/protostream_objectwriter_test.cc
@@ -90,6 +90,12 @@ string GetTypeUrl(const Descriptor* descriptor) {
}
} // namespace
+#if __cplusplus >= 201103L
+ using std::get;
+#else
+ using std::tr1::get;
+#endif
+
class BaseProtoStreamObjectWriterTest
: public ::testing::TestWithParam<testing::TypeInfoSource> {
protected:
@@ -122,7 +128,13 @@ class BaseProtoStreamObjectWriterTest
GOOGLE_CHECK(!descriptors.empty()) << "Must have at least one descriptor!";
helper_.ResetTypeInfo(descriptors);
ow_.reset(helper_.NewProtoWriter(GetTypeUrl(descriptors[0]), output_.get(),
- &listener_));
+ &listener_, options_));
+ }
+
+ void ResetTypeInfo(const Descriptor* descriptor) {
+ vector<const Descriptor*> descriptors;
+ descriptors.push_back(descriptor);
+ ResetTypeInfo(descriptors);
}
virtual ~BaseProtoStreamObjectWriterTest() {}
@@ -155,16 +167,12 @@ class BaseProtoStreamObjectWriterTest
MockErrorListener listener_;
google::protobuf::scoped_ptr<GrowingArrayByteSink> output_;
google::protobuf::scoped_ptr<ProtoStreamObjectWriter> ow_;
+ ProtoStreamObjectWriter::Options options_;
};
MATCHER_P(HasObjectLocation, expected,
"Verifies the expected object location") {
- string actual;
-#if __cplusplus >= 201103L
- actual = std::get<0>(arg).ToString();
-#else
- actual = std::tr1::get<0>(arg).ToString();
-#endif
+ string actual = get<0>(arg).ToString();
if (actual.compare(expected) == 0) return true;
*result_listener << "actual location is: " << actual;
return false;
@@ -175,6 +183,10 @@ class ProtoStreamObjectWriterTest : public BaseProtoStreamObjectWriterTest {
ProtoStreamObjectWriterTest()
: BaseProtoStreamObjectWriterTest(Book::descriptor()) {}
+ void ResetProtoWriter() {
+ ResetTypeInfo(Book::descriptor());
+ }
+
virtual ~ProtoStreamObjectWriterTest() {}
};
@@ -241,6 +253,21 @@ TEST_P(ProtoStreamObjectWriterTest, SimpleMessage) {
CheckOutput(book);
}
+TEST_P(ProtoStreamObjectWriterTest, CustomJsonName) {
+ Book book;
+ Author* robert = book.mutable_author();
+ robert->set_id(12345);
+ robert->set_name("robert");
+
+ ow_->StartObject("")
+ ->StartObject("author")
+ ->RenderUint64("@id", 12345)
+ ->RenderString("name", "robert")
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(book);
+}
+
TEST_P(ProtoStreamObjectWriterTest, PrimitiveFromStringConversion) {
Primitive full;
full.set_fix32(101);
@@ -274,8 +301,7 @@ TEST_P(ProtoStreamObjectWriterTest, PrimitiveFromStringConversion) {
full.add_rep_double(-8.05L);
full.add_rep_bool(false);
- ow_.reset(helper_.NewProtoWriter(GetTypeUrl(Primitive::descriptor()),
- output_.get(), &listener_));
+ ResetTypeInfo(Primitive::descriptor());
ow_->StartObject("")
->RenderString("fix32", "101")
@@ -348,8 +374,7 @@ TEST_P(ProtoStreamObjectWriterTest, InfinityInputTest) {
full.set_float_(std::numeric_limits<float>::infinity());
full.set_str("-Infinity");
- ow_.reset(helper_.NewProtoWriter(GetTypeUrl(Primitive::descriptor()),
- output_.get(), &listener_));
+ ResetTypeInfo(Primitive::descriptor());
EXPECT_CALL(listener_, InvalidValue(_, StringPiece("TYPE_INT32"),
StringPiece("\"Infinity\"")))
@@ -382,8 +407,7 @@ TEST_P(ProtoStreamObjectWriterTest, NaNInputTest) {
full.set_float_(std::numeric_limits<float>::quiet_NaN());
full.set_str("NaN");
- ow_.reset(helper_.NewProtoWriter(GetTypeUrl(Primitive::descriptor()),
- output_.get(), &listener_));
+ ResetTypeInfo(Primitive::descriptor());
EXPECT_CALL(listener_, InvalidValue(_, StringPiece("TYPE_INT32"),
StringPiece("\"NaN\"")))
@@ -689,6 +713,119 @@ TEST_P(ProtoStreamObjectWriterTest, UnknownListAtPublisher) {
CheckOutput(expected);
}
+TEST_P(ProtoStreamObjectWriterTest, IgnoreUnknownFieldAtRoot) {
+ Book empty;
+
+ options_.ignore_unknown_fields = true;
+ ResetProtoWriter();
+
+ EXPECT_CALL(listener_, InvalidName(_, _, _)).Times(0);
+ ow_->StartObject("")->RenderString("unknown", "Nope!")->EndObject();
+ CheckOutput(empty, 0);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, IgnoreUnknownFieldAtAuthorFriend) {
+ Book expected;
+ Author* paul = expected.mutable_author();
+ paul->set_name("Paul");
+ Author* mark = paul->add_friend_();
+ mark->set_name("Mark");
+ Author* john = paul->add_friend_();
+ john->set_name("John");
+ Author* luke = paul->add_friend_();
+ luke->set_name("Luke");
+
+ options_.ignore_unknown_fields = true;
+ ResetProtoWriter();
+
+ EXPECT_CALL(listener_, InvalidName(_, _, _)).Times(0);
+ ow_->StartObject("")
+ ->StartObject("author")
+ ->RenderString("name", "Paul")
+ ->StartList("friend")
+ ->StartObject("")
+ ->RenderString("name", "Mark")
+ ->EndObject()
+ ->StartObject("")
+ ->RenderString("name", "John")
+ ->RenderString("address", "Patmos")
+ ->EndObject()
+ ->StartObject("")
+ ->RenderString("name", "Luke")
+ ->EndObject()
+ ->EndList()
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(expected);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, IgnoreUnknownObjectAtRoot) {
+ Book empty;
+
+ options_.ignore_unknown_fields = true;
+ ResetProtoWriter();
+
+ EXPECT_CALL(listener_, InvalidName(_, StringPiece("unknown"),
+ StringPiece("Cannot find field.")))
+ .Times(0);
+ ow_->StartObject("")->StartObject("unknown")->EndObject()->EndObject();
+ CheckOutput(empty, 0);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, IgnoreUnknownObjectAtAuthor) {
+ Book expected;
+ Author* author = expected.mutable_author();
+ author->set_name("William");
+ author->add_pseudonym("Bill");
+
+ options_.ignore_unknown_fields = true;
+ ResetProtoWriter();
+
+ EXPECT_CALL(listener_, InvalidName(_, _, _)).Times(0);
+ ow_->StartObject("")
+ ->StartObject("author")
+ ->RenderString("name", "William")
+ ->StartObject("wife")
+ ->RenderString("name", "Hilary")
+ ->EndObject()
+ ->RenderString("pseudonym", "Bill")
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(expected);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, IgnoreUnknownListAtRoot) {
+ Book empty;
+
+ options_.ignore_unknown_fields = true;
+ ResetProtoWriter();
+
+ EXPECT_CALL(listener_, InvalidName(_, _, _)).Times(0);
+ ow_->StartObject("")->StartList("unknown")->EndList()->EndObject();
+ CheckOutput(empty, 0);
+}
+
+TEST_P(ProtoStreamObjectWriterTest, IgnoreUnknownListAtPublisher) {
+ Book expected;
+ expected.set_title("Brainwashing");
+ Publisher* publisher = expected.mutable_publisher();
+ publisher->set_name("propaganda");
+
+ options_.ignore_unknown_fields = true;
+ ResetProtoWriter();
+
+ EXPECT_CALL(listener_, InvalidName(_, _, _)).Times(0);
+ ow_->StartObject("")
+ ->StartObject("publisher")
+ ->RenderString("name", "propaganda")
+ ->StartList("alliance")
+ ->EndList()
+ ->EndObject()
+ ->RenderString("title", "Brainwashing")
+ ->EndObject();
+ CheckOutput(expected);
+}
+
TEST_P(ProtoStreamObjectWriterTest, MissingRequiredField) {
Book expected;
expected.set_title("My Title");
@@ -796,10 +933,6 @@ TEST_P(ProtoStreamObjectWriterTest, RootNamedList) {
InvalidName(_, StringPiece("oops"),
StringPiece("Root element should not be named.")))
.With(Args<0>(HasObjectLocation("")));
- EXPECT_CALL(listener_,
- InvalidName(_, StringPiece(""),
- StringPiece("Proto fields must have a name.")))
- .With(Args<0>(HasObjectLocation("")));
ow_->StartList("oops")->RenderString("", "item")->EndList();
CheckOutput(empty, 0);
}
@@ -864,6 +997,136 @@ INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
::testing::Values(
testing::USE_TYPE_RESOLVER));
+TEST_P(ProtoStreamObjectWriterTimestampDurationTest, ParseTimestamp) {
+ TimestampDuration timestamp;
+ google::protobuf::Timestamp* ts = timestamp.mutable_ts();
+ ts->set_seconds(1448249855);
+ ts->set_nanos(33155000);
+
+ ow_->StartObject("")
+ ->RenderString("ts", "2015-11-23T03:37:35.033155Z")
+ ->EndObject();
+ CheckOutput(timestamp);
+}
+
+TEST_P(ProtoStreamObjectWriterTimestampDurationTest,
+ ParseTimestampYearNotZeroPadded) {
+ TimestampDuration timestamp;
+ google::protobuf::Timestamp* ts = timestamp.mutable_ts();
+ ts->set_seconds(-61665654145);
+ ts->set_nanos(33155000);
+
+ ow_->StartObject("")
+ ->RenderString("ts", "15-11-23T03:37:35.033155Z")
+ ->EndObject();
+ CheckOutput(timestamp);
+}
+
+TEST_P(ProtoStreamObjectWriterTimestampDurationTest,
+ ParseTimestampYearZeroPadded) {
+ TimestampDuration timestamp;
+ google::protobuf::Timestamp* ts = timestamp.mutable_ts();
+ ts->set_seconds(-61665654145);
+ ts->set_nanos(33155000);
+
+ ow_->StartObject("")
+ ->RenderString("ts", "0015-11-23T03:37:35.033155Z")
+ ->EndObject();
+ CheckOutput(timestamp);
+}
+
+TEST_P(ProtoStreamObjectWriterTimestampDurationTest,
+ ParseTimestampWithPositiveOffset) {
+ TimestampDuration timestamp;
+ google::protobuf::Timestamp* ts = timestamp.mutable_ts();
+ ts->set_seconds(1448249855);
+ ts->set_nanos(33155000);
+
+ ow_->StartObject("")
+ ->RenderString("ts", "2015-11-23T11:47:35.033155+08:10")
+ ->EndObject();
+ CheckOutput(timestamp);
+}
+
+TEST_P(ProtoStreamObjectWriterTimestampDurationTest,
+ ParseTimestampWithNegativeOffset) {
+ TimestampDuration timestamp;
+ google::protobuf::Timestamp* ts = timestamp.mutable_ts();
+ ts->set_seconds(1448249855);
+ ts->set_nanos(33155000);
+
+ ow_->StartObject("")
+ ->RenderString("ts", "2015-11-22T19:47:35.033155-07:50")
+ ->EndObject();
+ CheckOutput(timestamp);
+}
+
+TEST_P(ProtoStreamObjectWriterTimestampDurationTest,
+ TimestampWithInvalidOffset1) {
+ TimestampDuration timestamp;
+
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(_,
+ StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
+ StringPiece("Field 'ts', Invalid time format: "
+ "2016-03-07T15:14:23+")));
+
+ ow_->StartObject("")->RenderString("ts", "2016-03-07T15:14:23+")->EndObject();
+ CheckOutput(timestamp);
+}
+
+TEST_P(ProtoStreamObjectWriterTimestampDurationTest,
+ TimestampWithInvalidOffset2) {
+ TimestampDuration timestamp;
+
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(_,
+ StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
+ StringPiece("Field 'ts', Invalid time format: "
+ "2016-03-07T15:14:23+08-10")));
+
+ ow_->StartObject("")
+ ->RenderString("ts", "2016-03-07T15:14:23+08-10")
+ ->EndObject();
+ CheckOutput(timestamp);
+}
+
+TEST_P(ProtoStreamObjectWriterTimestampDurationTest,
+ TimestampWithInvalidOffset3) {
+ TimestampDuration timestamp;
+
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(_,
+ StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
+ StringPiece("Field 'ts', Invalid time format: "
+ "2016-03-07T15:14:23+24:10")));
+
+ ow_->StartObject("")
+ ->RenderString("ts", "2016-03-07T15:14:23+24:10")
+ ->EndObject();
+ CheckOutput(timestamp);
+}
+
+TEST_P(ProtoStreamObjectWriterTimestampDurationTest,
+ TimestampWithInvalidOffset4) {
+ TimestampDuration timestamp;
+
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(_,
+ StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
+ StringPiece("Field 'ts', Invalid time format: "
+ "2016-03-07T15:14:23+04:60")));
+
+ ow_->StartObject("")
+ ->RenderString("ts", "2016-03-07T15:14:23+04:60")
+ ->EndObject();
+ CheckOutput(timestamp);
+}
+
TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidTimestampError1) {
TimestampDuration timestamp;
@@ -914,17 +1177,90 @@ TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidTimestampError4) {
InvalidValue(_,
StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
StringPiece("Field 'ts', Invalid time format: "
- "-8032-10-18T00:00:00.000Z")));
+ "-8031-10-18T00:00:00.000Z")));
+
+ ow_->StartObject("")
+ ->RenderString("ts", "-8031-10-18T00:00:00.000Z")
+ ->EndObject();
+ CheckOutput(timestamp);
+}
+
+TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidTimestampError5) {
+ TimestampDuration timestamp;
+
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(_,
+ StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
+ StringPiece("Field 'ts', Invalid time format: "
+ "2015-11-23T03:37:35.033155 Z")));
+
+ ow_->StartObject("")
+ // Whitespace in the Timestamp nanos is not allowed.
+ ->RenderString("ts", "2015-11-23T03:37:35.033155 Z")
+ ->EndObject();
+ CheckOutput(timestamp);
+}
+
+TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidTimestampError6) {
+ TimestampDuration timestamp;
+
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(_,
+ StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
+ StringPiece("Field 'ts', Invalid time format: "
+ "2015-11-23T03:37:35.033155 1234Z")));
+
+ ow_->StartObject("")
+ // Whitespace in the Timestamp nanos is not allowed.
+ ->RenderString("ts", "2015-11-23T03:37:35.033155 1234Z")
+ ->EndObject();
+ CheckOutput(timestamp);
+}
+
+TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidTimestampError7) {
+ TimestampDuration timestamp;
+
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(_,
+ StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
+ StringPiece("Field 'ts', Invalid time format: "
+ "2015-11-23T03:37:35.033abc155Z")));
ow_->StartObject("")
- ->RenderString("ts", "-8032-10-18T00:00:00.000Z")
+ // Non-numeric characters in the Timestamp nanos is not allowed.
+ ->RenderString("ts", "2015-11-23T03:37:35.033abc155Z")
->EndObject();
CheckOutput(timestamp);
}
-// TODO(skarvaje): Write a test for nanos that exceed limit. Currently, it is
-// not possible to construct a test case where nanos exceed limit because of
-// floating point arithmetic.
+TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidTimestampError8) {
+ TimestampDuration timestamp;
+
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(_,
+ StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
+ StringPiece("Field 'ts', Invalid time format: "
+ "0-12-31T23:59:59.000Z")));
+
+ ow_->StartObject("")
+ ->RenderString("ts", "0-12-31T23:59:59.000Z")
+ ->EndObject();
+ CheckOutput(timestamp);
+}
+
+TEST_P(ProtoStreamObjectWriterTimestampDurationTest, ParseDuration) {
+ TimestampDuration duration;
+ google::protobuf::Duration* dur = duration.mutable_dur();
+ dur->set_seconds(1448216930);
+ dur->set_nanos(132262000);
+
+ ow_->StartObject("")->RenderString("dur", "1448216930.132262s")->EndObject();
+ CheckOutput(duration);
+}
TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidDurationError1) {
TimestampDuration duration;
@@ -962,7 +1298,7 @@ TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidDurationError3) {
InvalidValue(
_, StringPiece("type.googleapis.com/google.protobuf.Duration"),
StringPiece("Field 'dur', Invalid duration format, failed to "
- "parse nanos seconds")));
+ "parse nano seconds")));
ow_->StartObject("")->RenderString("dur", "123.DEFs")->EndObject();
CheckOutput(duration);
@@ -981,6 +1317,19 @@ TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidDurationError4) {
CheckOutput(duration);
}
+TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidDurationError5) {
+ TimestampDuration duration;
+
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(_,
+ StringPiece("type.googleapis.com/google.protobuf.Duration"),
+ StringPiece("Field 'dur', Duration value exceeds limits")));
+
+ ow_->StartObject("")->RenderString("dur", "0.1000000001s")->EndObject();
+ CheckOutput(duration);
+}
+
TEST_P(ProtoStreamObjectWriterTimestampDurationTest,
MismatchedTimestampTypeInput) {
TimestampDuration timestamp;
@@ -1012,7 +1361,10 @@ TEST_P(ProtoStreamObjectWriterTimestampDurationTest,
class ProtoStreamObjectWriterStructTest
: public BaseProtoStreamObjectWriterTest {
protected:
- ProtoStreamObjectWriterStructTest() {
+ ProtoStreamObjectWriterStructTest() { ResetProtoWriter(); }
+
+ // Resets ProtoWriter with current set of options and other state.
+ void ResetProtoWriter() {
vector<const Descriptor*> descriptors;
descriptors.push_back(StructType::descriptor());
descriptors.push_back(google::protobuf::Struct::descriptor());
@@ -1066,12 +1418,12 @@ TEST_P(ProtoStreamObjectWriterStructTest, StructInvalidInputFailure) {
TEST_P(ProtoStreamObjectWriterStructTest, SimpleRepeatedStructMapKeyTest) {
EXPECT_CALL(
listener_,
- InvalidName(_, StringPiece("k1"),
- StringPiece("Repeated map key: 'k1' is already set.")));
+ InvalidName(_, StringPiece("gBike"),
+ StringPiece("Repeated map key: 'gBike' is already set.")));
ow_->StartObject("")
->StartObject("object")
- ->RenderString("k1", "v1")
- ->RenderString("k1", "v2")
+ ->RenderString("gBike", "v1")
+ ->RenderString("gBike", "v2")
->EndObject()
->EndObject();
}
@@ -1108,6 +1460,28 @@ TEST_P(ProtoStreamObjectWriterStructTest, RepeatedStructMapObjectKeyTest) {
->EndObject();
}
+TEST_P(ProtoStreamObjectWriterStructTest, OptionStructIntAsStringsTest) {
+ StructType struct_type;
+ google::protobuf::Struct* s = struct_type.mutable_object();
+ s->mutable_fields()->operator[]("k1").set_number_value(123);
+ s->mutable_fields()->operator[]("k2").set_bool_value(true);
+ s->mutable_fields()->operator[]("k3").set_string_value("-222222222");
+ s->mutable_fields()->operator[]("k4").set_string_value("33333333");
+
+ options_.struct_integers_as_strings = true;
+ ResetProtoWriter();
+
+ ow_->StartObject("")
+ ->StartObject("object")
+ ->RenderDouble("k1", 123)
+ ->RenderBool("k2", true)
+ ->RenderInt64("k3", -222222222)
+ ->RenderUint64("k4", 33333333)
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(struct_type);
+}
+
class ProtoStreamObjectWriterMapTest : public BaseProtoStreamObjectWriterTest {
protected:
ProtoStreamObjectWriterMapTest()
@@ -1121,10 +1495,11 @@ INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
TEST_P(ProtoStreamObjectWriterMapTest, MapShouldNotAcceptList) {
MapIn mm;
- EXPECT_CALL(listener_,
- InvalidValue(_, StringPiece("Map"),
- StringPiece("Cannot bind a list to map.")))
- .With(Args<0>(HasObjectLocation("map_input")));
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(
+ _, StringPiece("Map"),
+ StringPiece("Cannot bind a list to map for field 'map_input'.")));
ow_->StartObject("")
->StartList("map_input")
->RenderString("a", "b")
@@ -1155,6 +1530,8 @@ class ProtoStreamObjectWriterAnyTest : public BaseProtoStreamObjectWriterTest {
descriptors.push_back(google::protobuf::DoubleValue::descriptor());
descriptors.push_back(google::protobuf::Timestamp::descriptor());
descriptors.push_back(google::protobuf::Any::descriptor());
+ descriptors.push_back(google::protobuf::Value::descriptor());
+ descriptors.push_back(google::protobuf::Struct::descriptor());
ResetTypeInfo(descriptors);
}
};
@@ -1363,6 +1740,222 @@ TEST_P(ProtoStreamObjectWriterAnyTest, AnyWellKnownTypeErrorTest) {
CheckOutput(any);
}
+// Test the following case:
+//
+// {
+// "any": {
+// "@type": "type.googleapis.com/google.protobuf.Value",
+// "value": "abc"
+// }
+// }
+TEST_P(ProtoStreamObjectWriterAnyTest, AnyWithNestedPrimitiveValue) {
+ AnyOut out;
+ ::google::protobuf::Any* any = out.mutable_any();
+
+ ::google::protobuf::Value value;
+ value.set_string_value("abc");
+ any->PackFrom(value);
+
+ ow_->StartObject("")
+ ->StartObject("any")
+ ->RenderString("@type", "type.googleapis.com/google.protobuf.Value")
+ ->RenderString("value", "abc")
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(out);
+}
+
+// Test the following case:
+//
+// {
+// "any": {
+// "@type": "type.googleapis.com/google.protobuf.Value",
+// "value": {
+// "foo": "abc"
+// }
+// }
+// }
+TEST_P(ProtoStreamObjectWriterAnyTest, AnyWithNestedObjectValue) {
+ AnyOut out;
+ ::google::protobuf::Any* any = out.mutable_any();
+
+ ::google::protobuf::Value value;
+ (*value.mutable_struct_value()->mutable_fields())["foo"].set_string_value(
+ "abc");
+ any->PackFrom(value);
+
+ ow_->StartObject("")
+ ->StartObject("any")
+ ->RenderString("@type", "type.googleapis.com/google.protobuf.Value")
+ ->StartObject("value")
+ ->RenderString("foo", "abc")
+ ->EndObject()
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(out);
+}
+
+// Test the following case:
+//
+// {
+// "any": {
+// "@type": "type.googleapis.com/google.protobuf.Value",
+// "value": ["hello"],
+// }
+// }
+TEST_P(ProtoStreamObjectWriterAnyTest, AnyWithNestedArrayValue) {
+ AnyOut out;
+ ::google::protobuf::Any* any = out.mutable_any();
+
+ ::google::protobuf::Value value;
+ value.mutable_list_value()->add_values()->set_string_value("hello");
+ any->PackFrom(value);
+
+ ow_->StartObject("")
+ ->StartObject("any")
+ ->RenderString("@type", "type.googleapis.com/google.protobuf.Value")
+ ->StartList("value")
+ ->RenderString("", "hello")
+ ->EndList()
+ ->EndObject()
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(out);
+}
+
+// Test the following case:
+//
+// {
+// "any": {
+// "@type": "type.googleapis.com/google.protobuf.Value",
+// "not_value": ""
+// }
+// }
+TEST_P(ProtoStreamObjectWriterAnyTest,
+ AnyWellKnownTypesNoValueFieldForPrimitive) {
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(
+ _, StringPiece("Any"),
+ StringPiece("Expect a \"value\" field for well-known types.")));
+ AnyOut any;
+ google::protobuf::Any* any_type = any.mutable_any();
+ any_type->set_type_url("type.googleapis.com/google.protobuf.Value");
+
+ ow_->StartObject("")
+ ->StartObject("any")
+ ->RenderString("@type", "type.googleapis.com/google.protobuf.Value")
+ ->RenderString("not_value", "")
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(any);
+}
+
+// Test the following case:
+//
+// {
+// "any": {
+// "@type": "type.googleapis.com/google.protobuf.Value",
+// "not_value": {}
+// }
+// }
+TEST_P(ProtoStreamObjectWriterAnyTest, AnyWellKnownTypesNoValueFieldForObject) {
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(
+ _, StringPiece("Any"),
+ StringPiece("Expect a \"value\" field for well-known types.")));
+ AnyOut any;
+ google::protobuf::Any* any_type = any.mutable_any();
+ any_type->set_type_url("type.googleapis.com/google.protobuf.Value");
+
+ ow_->StartObject("")
+ ->StartObject("any")
+ ->RenderString("@type", "type.googleapis.com/google.protobuf.Value")
+ ->StartObject("not_value")
+ ->EndObject()
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(any);
+}
+
+// Test the following case:
+//
+// {
+// "any": {
+// "@type": "type.googleapis.com/google.protobuf.Value",
+// "not_value": [],
+// }
+// }
+TEST_P(ProtoStreamObjectWriterAnyTest, AnyWellKnownTypesNoValueFieldForArray) {
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(
+ _, StringPiece("Any"),
+ StringPiece("Expect a \"value\" field for well-known types.")));
+ AnyOut any;
+ google::protobuf::Any* any_type = any.mutable_any();
+ any_type->set_type_url("type.googleapis.com/google.protobuf.Value");
+
+ ow_->StartObject("")
+ ->StartObject("any")
+ ->RenderString("@type", "type.googleapis.com/google.protobuf.Value")
+ ->StartList("not_value")
+ ->EndList()
+ ->EndObject()
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(any);
+}
+
+// Test the following case:
+//
+// {
+// "any": {
+// "@type": "type.googleapis.com/google.protobuf.Struct",
+// "value": "",
+// }
+// }
+TEST_P(ProtoStreamObjectWriterAnyTest, AnyWellKnownTypesExpectObjectForStruct) {
+ EXPECT_CALL(listener_, InvalidValue(_, StringPiece("Any"),
+ StringPiece("Expect a JSON object.")));
+ AnyOut any;
+ google::protobuf::Any* any_type = any.mutable_any();
+ any_type->set_type_url("type.googleapis.com/google.protobuf.Struct");
+
+ ow_->StartObject("")
+ ->StartObject("any")
+ ->RenderString("@type", "type.googleapis.com/google.protobuf.Struct")
+ ->RenderString("value", "")
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(any);
+}
+
+// Test the following case:
+//
+// {
+// "any": {
+// "@type": "type.googleapis.com/google.protobuf.Any",
+// "value": "",
+// }
+// }
+TEST_P(ProtoStreamObjectWriterAnyTest, AnyWellKnownTypesExpectObjectForAny) {
+ EXPECT_CALL(listener_, InvalidValue(_, StringPiece("Any"),
+ StringPiece("Expect a JSON object.")));
+ AnyOut any;
+ google::protobuf::Any* any_type = any.mutable_any();
+ any_type->set_type_url("type.googleapis.com/google.protobuf.Any");
+
+ ow_->StartObject("")
+ ->StartObject("any")
+ ->RenderString("@type", "type.googleapis.com/google.protobuf.Any")
+ ->RenderString("value", "")
+ ->EndObject()
+ ->EndObject();
+ CheckOutput(any);
+}
+
class ProtoStreamObjectWriterFieldMaskTest
: public BaseProtoStreamObjectWriterTest {
protected:
@@ -1591,13 +2184,17 @@ TEST_P(ProtoStreamObjectWriterFieldMaskTest, MapKeyMustBeEscapedCorrectly) {
TEST_P(ProtoStreamObjectWriterFieldMaskTest, MapKeyCanContainAnyChars) {
FieldMaskTest expected;
expected.mutable_single_mask()->add_paths(
- "path.to.map[\"(),[],\\\"'!@#$%^&*123_|War孙天涌,./?><\\\\\"]");
+ // \xE5\xAD\x99 is the UTF-8 byte sequence for chinese character 孙.
+ // We cannot embed non-ASCII characters in the code directly because
+ // some windows compilers will try to interpret them using the system's
+ // current encoding and end up with invalid UTF-8 byte sequence.
+ "path.to.map[\"(),[],\\\"'!@#$%^&*123_|War\xE5\xAD\x99,./?><\\\\\"]");
expected.mutable_single_mask()->add_paths("path.to.map[\"key2\"]");
ow_->StartObject("");
ow_->RenderString(
"single_mask",
- "path.to.map[\"(),[],\\\"'!@#$%^&*123_|War孙天涌,./?><\\\\\"],"
+ "path.to.map[\"(),[],\\\"'!@#$%^&*123_|War\xE5\xAD\x99,./?><\\\\\"],"
"path.to.map[\"key2\"]");
ow_->EndObject();
diff --git a/src/google/protobuf/util/internal/snake2camel_objectwriter.h b/src/google/protobuf/util/internal/snake2camel_objectwriter.h
deleted file mode 100644
index 9b4ab8a3..00000000
--- a/src/google/protobuf/util/internal/snake2camel_objectwriter.h
+++ /dev/null
@@ -1,165 +0,0 @@
-// 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.
-
-#ifndef GOOGLE_PROTOBUF_UTIL_CONVERTER_SNAKE2CAMEL_OBJECTWRITER_H__
-#define GOOGLE_PROTOBUF_UTIL_CONVERTER_SNAKE2CAMEL_OBJECTWRITER_H__
-
-#include <string>
-
-#include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/strutil.h>
-#include <google/protobuf/stubs/stringpiece.h>
-#include <google/protobuf/util/internal/object_writer.h>
-#include <google/protobuf/util/internal/utility.h>
-
-namespace google {
-namespace protobuf {
-namespace util {
-namespace converter {
-
-// Snake2CamelObjectWriter is an ObjectWriter than translates each field name
-// from snake_case to camelCase. Typical usage is:
-// ProtoStreamObjectSource psos(...);
-// JsonObjectWriter jow(...);
-// Snake2CamelObjectWriter snake_to_camel(&jow);
-// psos.writeTo(&snake_to_camel);
-class Snake2CamelObjectWriter : public ObjectWriter {
- public:
- explicit Snake2CamelObjectWriter(ObjectWriter* ow)
- : ow_(ow), normalize_case_(true) {}
- virtual ~Snake2CamelObjectWriter() {}
-
- // ObjectWriter methods.
- virtual Snake2CamelObjectWriter* StartObject(StringPiece name) {
- ow_->StartObject(name);
- return this;
- }
-
- virtual Snake2CamelObjectWriter* EndObject() {
- ow_->EndObject();
- return this;
- }
-
- virtual Snake2CamelObjectWriter* StartList(StringPiece name) {
- ow_->StartList(name);
- return this;
- }
-
- virtual Snake2CamelObjectWriter* EndList() {
- ow_->EndList();
- return this;
- }
-
- virtual Snake2CamelObjectWriter* RenderBool(StringPiece name, bool value) {
- ow_->RenderBool(name, value);
- return this;
- }
-
- virtual Snake2CamelObjectWriter* RenderInt32(StringPiece name, int32 value) {
- ow_->RenderInt32(name, value);
- return this;
- }
-
- virtual Snake2CamelObjectWriter* RenderUint32(StringPiece name,
- uint32 value) {
- ow_->RenderUint32(name, value);
- return this;
- }
-
- virtual Snake2CamelObjectWriter* RenderInt64(StringPiece name, int64 value) {
- ow_->RenderInt64(name, value);
- return this;
- }
-
- virtual Snake2CamelObjectWriter* RenderUint64(StringPiece name,
- uint64 value) {
- ow_->RenderUint64(name, value);
- return this;
- }
-
- virtual Snake2CamelObjectWriter* RenderDouble(StringPiece name,
- double value) {
- ow_->RenderDouble(name, value);
- return this;
- }
-
- virtual Snake2CamelObjectWriter* RenderFloat(StringPiece name, float value) {
- ow_->RenderFloat(name, value);
- return this;
- }
-
- virtual Snake2CamelObjectWriter* RenderString(StringPiece name,
- StringPiece value) {
- ow_->RenderString(name, value);
- return this;
- }
-
- virtual Snake2CamelObjectWriter* RenderBytes(StringPiece name,
- StringPiece value) {
- ow_->RenderBytes(name, value);
- return this;
- }
-
- virtual Snake2CamelObjectWriter* RenderNull(StringPiece name) {
- ow_->RenderNull(name);
- return this;
- }
-
- virtual Snake2CamelObjectWriter* DisableCaseNormalizationForNextKey() {
- normalize_case_ = false;
- return this;
- }
-
- private:
- ObjectWriter* ow_;
- bool normalize_case_;
-
- bool ShouldNormalizeCase(StringPiece name) {
- if (normalize_case_) {
- return !IsCamel(name);
- } else {
- normalize_case_ = true;
- return false;
- }
- }
-
- bool IsCamel(StringPiece name) {
- return name.empty() || (ascii_islower(name[0]) && !name.contains("_"));
- }
-
- GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Snake2CamelObjectWriter);
-};
-
-} // namespace converter
-} // namespace util
-} // namespace protobuf
-
-} // namespace google
-#endif // GOOGLE_PROTOBUF_UTIL_CONVERTER_SNAKE2CAMEL_OBJECTWRITER_H__
diff --git a/src/google/protobuf/util/internal/testdata/books.proto b/src/google/protobuf/util/internal/testdata/books.proto
index 6e2f109b..1cbbba47 100644
--- a/src/google/protobuf/util/internal/testdata/books.proto
+++ b/src/google/protobuf/util/internal/testdata/books.proto
@@ -56,6 +56,13 @@ message Book {
optional Publisher publisher = 9;
repeated Label labels = 10;
+ enum Type {
+ FICTION = 1;
+ KIDS = 2;
+ ACTION_AND_ADVENTURE = 3;
+ }
+ optional Type type = 11;
+
extensions 200 to 499;
}
@@ -66,7 +73,7 @@ message Publisher {
// An author of a book
message Author {
- optional uint64 id = 1;
+ optional uint64 id = 1 [json_name = "@id"];
optional string name = 2;
repeated string pseudonym = 3;
optional bool alive = 4;
@@ -169,3 +176,12 @@ message NestedBook {
message BadNestedBook {
repeated uint32 book = 1 [packed=true]; // Packed to optional message.
}
+
+// A recursively defined message.
+message Cyclic {
+ optional int32 m_int = 1;
+ optional string m_str = 2;
+ optional Book m_book = 3;
+ repeated Author m_author = 5;
+ optional Cyclic m_cyclic = 4;
+}
diff --git a/src/google/protobuf/util/internal/testdata/default_value.proto b/src/google/protobuf/util/internal/testdata/default_value.proto
index ebbdf6ab..cccc741c 100644
--- a/src/google/protobuf/util/internal/testdata/default_value.proto
+++ b/src/google/protobuf/util/internal/testdata/default_value.proto
@@ -75,9 +75,10 @@ message DefaultValueTestCases {
IntToStringMap int_to_string = 403;
MixedMap mixed1 = 404;
MixedMap2 mixed2 = 405;
- MessageMap map_of_objects = 406;
- MixedMap mixed_empty = 407;
- MessageMap message_map_empty = 408;
+ MixedMap2 empty_mixed2 = 406;
+ MessageMap map_of_objects = 407;
+ MixedMap mixed_empty = 408;
+ MessageMap message_map_empty = 409;
DoubleValueMessage double_value = 501;
DoubleValueMessage double_value_default = 502;
}
diff --git a/src/google/protobuf/util/internal/testdata/default_value_test.proto b/src/google/protobuf/util/internal/testdata/default_value_test.proto
index 21b85e6d..93288341 100644
--- a/src/google/protobuf/util/internal/testdata/default_value_test.proto
+++ b/src/google/protobuf/util/internal/testdata/default_value_test.proto
@@ -43,4 +43,11 @@ message DefaultValueTest {
bool bool_value = 13;
string string_value = 15;
bytes bytes_value = 17 [ctype = CORD];
+
+ enum EnumDefault {
+ ENUM_FIRST = 0;
+ ENUM_SECOND = 1;
+ ENUM_THIRD = 2;
+ }
+ EnumDefault enum_value = 18;
}
diff --git a/src/google/protobuf/util/internal/testdata/maps.proto b/src/google/protobuf/util/internal/testdata/maps.proto
index 7fb42a26..6475ecdd 100644
--- a/src/google/protobuf/util/internal/testdata/maps.proto
+++ b/src/google/protobuf/util/internal/testdata/maps.proto
@@ -44,6 +44,35 @@ message MapOut {
map<string, MapM> map1 = 1;
map<string, MapOut> map2 = 2;
map<int32, string> map3 = 3;
+ map<bool, string> map4 = 5;
+ string bar = 4;
+}
+
+// A message with exactly the same wire representation as MapOut, but using
+// repeated message fields instead of map fields. We use this message to test
+// the wire-format compatibility of the JSON transcoder (e.g., whether it
+// handles missing keys correctly).
+message MapOutWireFormat {
+ message Map1Entry {
+ string key = 1;
+ MapM value = 2;
+ }
+ repeated Map1Entry map1 = 1;
+ message Map2Entry {
+ string key = 1;
+ MapOut value = 2;
+ }
+ repeated Map2Entry map2 = 2;
+ message Map3Entry {
+ int32 key = 1;
+ string value = 2;
+ }
+ repeated Map3Entry map3 = 3;
+ message Map4Entry {
+ bool key = 1;
+ string value = 2;
+ }
+ repeated Map4Entry map4 = 5;
string bar = 4;
}
diff --git a/src/google/protobuf/util/internal/type_info.cc b/src/google/protobuf/util/internal/type_info.cc
index a45a76e3..00a8ee7a 100644
--- a/src/google/protobuf/util/internal/type_info.cc
+++ b/src/google/protobuf/util/internal/type_info.cc
@@ -136,8 +136,7 @@ class TypeInfoForTypeResolver : public TypeInfo {
for (int i = 0; i < type->fields_size(); ++i) {
const google::protobuf::Field& field = type->fields(i);
StringPiece name = field.name();
- StringPiece camel_case_name =
- *string_storage_.insert(ToCamelCase(name)).first;
+ StringPiece camel_case_name = field.json_name();
const StringPiece* existing = InsertOrReturnExisting(
&camel_case_name_table_, camel_case_name, name);
if (existing && *existing != name) {
diff --git a/src/google/protobuf/util/internal/type_info_test_helper.cc b/src/google/protobuf/util/internal/type_info_test_helper.cc
index 1b9c5154..49e18ed0 100644
--- a/src/google/protobuf/util/internal/type_info_test_helper.cc
+++ b/src/google/protobuf/util/internal/type_info_test_helper.cc
@@ -102,13 +102,13 @@ ProtoStreamObjectSource* TypeInfoTestHelper::NewProtoSource(
}
ProtoStreamObjectWriter* TypeInfoTestHelper::NewProtoWriter(
- const string& type_url, strings::ByteSink* output,
- ErrorListener* listener) {
+ const string& type_url, strings::ByteSink* output, ErrorListener* listener,
+ const ProtoStreamObjectWriter::Options& options) {
const google::protobuf::Type* type = typeinfo_->GetTypeByTypeUrl(type_url);
switch (type_) {
case USE_TYPE_RESOLVER: {
return new ProtoStreamObjectWriter(type_resolver_.get(), *type, output,
- listener);
+ listener, options);
}
}
GOOGLE_LOG(FATAL) << "Can not reach here.";
diff --git a/src/google/protobuf/util/internal/type_info_test_helper.h b/src/google/protobuf/util/internal/type_info_test_helper.h
index 6916a73b..1a279849 100644
--- a/src/google/protobuf/util/internal/type_info_test_helper.h
+++ b/src/google/protobuf/util/internal/type_info_test_helper.h
@@ -39,8 +39,8 @@
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/descriptor.h>
-#include <google/protobuf/util/internal/type_info.h>
#include <google/protobuf/util/internal/default_value_objectwriter.h>
+#include <google/protobuf/util/internal/type_info.h>
#include <google/protobuf/util/internal/protostream_objectsource.h>
#include <google/protobuf/util/internal/protostream_objectwriter.h>
#include <google/protobuf/util/type_resolver.h>
@@ -77,9 +77,9 @@ class TypeInfoTestHelper {
ProtoStreamObjectSource* NewProtoSource(io::CodedInputStream* coded_input,
const string& type_url);
- ProtoStreamObjectWriter* NewProtoWriter(const string& type_url,
- strings::ByteSink* output,
- ErrorListener* listener);
+ ProtoStreamObjectWriter* NewProtoWriter(
+ const string& type_url, strings::ByteSink* output,
+ ErrorListener* listener, const ProtoStreamObjectWriter::Options& options);
DefaultValueObjectWriter* NewDefaultValueWriter(const string& type_url,
ObjectWriter* writer);
diff --git a/src/google/protobuf/util/internal/utility.cc b/src/google/protobuf/util/internal/utility.cc
index 61899c24..5f613e77 100644
--- a/src/google/protobuf/util/internal/utility.cc
+++ b/src/google/protobuf/util/internal/utility.cc
@@ -49,9 +49,10 @@ namespace converter {
namespace {
const StringPiece SkipWhiteSpace(StringPiece str) {
StringPiece::size_type i;
- for (i = 0; i < str.size() && isspace(str[i]); ++i) {}
+ for (i = 0; i < str.size() && isspace(str[i]); ++i) {
+ }
GOOGLE_DCHECK(i == str.size() || !isspace(str[i]));
- return StringPiece(str, i);
+ return str.substr(i);
}
} // namespace
@@ -127,8 +128,12 @@ string GetStringFromAny(const google::protobuf::Any& any) {
}
const StringPiece GetTypeWithoutUrl(StringPiece type_url) {
- size_t idx = type_url.rfind('/');
- return type_url.substr(idx + 1);
+ if (type_url.size() > kTypeUrlSize && type_url[kTypeUrlSize] == '/') {
+ return type_url.substr(kTypeUrlSize + 1);
+ } else {
+ size_t idx = type_url.rfind('/');
+ return type_url.substr(idx + 1);
+ }
}
const string GetFullTypeWithUrl(StringPiece simple_type) {
@@ -160,6 +165,19 @@ const google::protobuf::Field* FindFieldInTypeOrNull(
return NULL;
}
+const google::protobuf::Field* FindJsonFieldInTypeOrNull(
+ const google::protobuf::Type* type, StringPiece json_name) {
+ if (type != NULL) {
+ for (int i = 0; i < type->fields_size(); ++i) {
+ const google::protobuf::Field& field = type->fields(i);
+ if (field.json_name() == json_name) {
+ return &field;
+ }
+ }
+ }
+ return NULL;
+}
+
const google::protobuf::EnumValue* FindEnumValueByNameOrNull(
const google::protobuf::Enum* enum_type, StringPiece enum_name) {
if (enum_type != NULL) {
@@ -208,6 +226,7 @@ string ToCamelCase(const StringPiece input) {
if (!result.empty() && is_cap &&
(!was_cap || (i + 1 < input.size() && ascii_islower(input[i + 1])))) {
first_word = false;
+ result.push_back(input[i]);
} else {
result.push_back(ascii_tolower(input[i]));
continue;
@@ -217,9 +236,13 @@ string ToCamelCase(const StringPiece input) {
if (ascii_islower(input[i])) {
result.push_back(ascii_toupper(input[i]));
continue;
+ } else {
+ result.push_back(input[i]);
+ continue;
}
+ } else {
+ result.push_back(ascii_tolower(input[i]));
}
- result.push_back(input[i]);
}
return result;
}
@@ -316,16 +339,23 @@ string FloatAsString(float value) {
return DoubleAsString(value);
}
-bool SafeStrToFloat(StringPiece str, float *value) {
+bool SafeStrToFloat(StringPiece str, float* value) {
double double_value;
if (!safe_strtod(str, &double_value)) {
return false;
}
- *value = static_cast<float>(double_value);
- if (MathLimits<float>::IsInf(*value)) {
+ if (MathLimits<double>::IsInf(double_value) ||
+ MathLimits<double>::IsNaN(double_value))
+ return false;
+
+ // Fail if the value is not representable in float.
+ if (double_value > std::numeric_limits<float>::max() ||
+ double_value < -std::numeric_limits<float>::max()) {
return false;
}
+
+ *value = static_cast<float>(double_value);
return true;
}
diff --git a/src/google/protobuf/util/internal/utility.h b/src/google/protobuf/util/internal/utility.h
index 5ba97bd2..26fed444 100644
--- a/src/google/protobuf/util/internal/utility.h
+++ b/src/google/protobuf/util/internal/utility.h
@@ -64,6 +64,10 @@ class EnumValue;
namespace protobuf {
namespace util {
namespace converter {
+
+// Size of "type.googleapis.com"
+static const int64 kTypeUrlSize = 19;
+
// Finds the tech option identified by option_name. Parses the boolean value and
// returns it.
// When the option with the given name is not found, default_value is returned.
@@ -127,6 +131,11 @@ const google::protobuf::Option* FindOptionOrNull(
const google::protobuf::Field* FindFieldInTypeOrNull(
const google::protobuf::Type* type, StringPiece field_name);
+// Similar to FindFieldInTypeOrNull, but this looks up fields with given
+// json_name.
+const google::protobuf::Field* FindJsonFieldInTypeOrNull(
+ const google::protobuf::Type* type, StringPiece json_name);
+
// Finds and returns the EnumValue identified by enum_name in the passed tech
// Enum object. Returns NULL if none found.
const google::protobuf::EnumValue* FindEnumValueByNameOrNull(
diff --git a/src/google/protobuf/util/json_format_proto3.proto b/src/google/protobuf/util/json_format_proto3.proto
index e8137677..3835b30e 100644
--- a/src/google/protobuf/util/json_format_proto3.proto
+++ b/src/google/protobuf/util/json_format_proto3.proto
@@ -39,6 +39,7 @@ import "google/protobuf/wrappers.proto";
import "google/protobuf/struct.proto";
import "google/protobuf/any.proto";
import "google/protobuf/field_mask.proto";
+import "google/protobuf/unittest.proto";
enum EnumType {
FOO = 0;
@@ -165,3 +166,16 @@ message TestListValue {
google.protobuf.ListValue value = 1;
repeated google.protobuf.ListValue repeated_value = 2;
}
+
+message TestBoolValue {
+ bool bool_value = 1;
+ map<bool, int32> bool_map = 2;
+}
+
+message TestCustomJsonName {
+ int32 value = 1 [json_name = "@value"];
+}
+
+message TestExtensions {
+ .protobuf_unittest.TestAllExtensions extensions = 1;
+}
diff --git a/src/google/protobuf/util/json_util.cc b/src/google/protobuf/util/json_util.cc
index c3b8d502..d7ac2dba 100644
--- a/src/google/protobuf/util/json_util.cc
+++ b/src/google/protobuf/util/json_util.cc
@@ -74,7 +74,7 @@ util::Status BinaryToJsonStream(TypeResolver* resolver,
const string& type_url,
io::ZeroCopyInputStream* binary_input,
io::ZeroCopyOutputStream* json_output,
- const JsonOptions& options) {
+ const JsonPrintOptions& options) {
io::CodedInputStream in_stream(binary_input);
google::protobuf::Type type;
RETURN_IF_ERROR(resolver->ResolveMessageType(type_url, &type));
@@ -95,23 +95,63 @@ util::Status BinaryToJsonString(TypeResolver* resolver,
const string& type_url,
const string& binary_input,
string* json_output,
- const JsonOptions& options) {
+ const JsonPrintOptions& options) {
io::ArrayInputStream input_stream(binary_input.data(), binary_input.size());
io::StringOutputStream output_stream(json_output);
return BinaryToJsonStream(resolver, type_url, &input_stream, &output_stream,
options);
}
+namespace {
+class StatusErrorListener : public converter::ErrorListener {
+ public:
+ StatusErrorListener() : status_(util::Status::OK) {}
+ virtual ~StatusErrorListener() {}
+
+ util::Status GetStatus() { return status_; }
+
+ virtual void InvalidName(const converter::LocationTrackerInterface& loc,
+ StringPiece unknown_name, StringPiece message) {
+ status_ = util::Status(util::error::INVALID_ARGUMENT,
+ loc.ToString() + ": " + message.ToString());
+ }
+
+ virtual void InvalidValue(const converter::LocationTrackerInterface& loc,
+ StringPiece type_name, StringPiece value) {
+ status_ =
+ util::Status(util::error::INVALID_ARGUMENT,
+ loc.ToString() + ": invalid value " + value.ToString() +
+ " for type " + type_name.ToString());
+ }
+
+ virtual void MissingField(const converter::LocationTrackerInterface& loc,
+ StringPiece missing_name) {
+ status_ = util::Status(
+ util::error::INVALID_ARGUMENT,
+ loc.ToString() + ": missing field " + missing_name.ToString());
+ }
+
+ private:
+ util::Status status_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StatusErrorListener);
+};
+} // namespace
+
util::Status JsonToBinaryStream(TypeResolver* resolver,
const string& type_url,
io::ZeroCopyInputStream* json_input,
- io::ZeroCopyOutputStream* binary_output) {
+ io::ZeroCopyOutputStream* binary_output,
+ const JsonParseOptions& options) {
google::protobuf::Type type;
RETURN_IF_ERROR(resolver->ResolveMessageType(type_url, &type));
internal::ZeroCopyStreamByteSink sink(binary_output);
- converter::NoopErrorListener listener;
+ StatusErrorListener listener;
+ converter::ProtoStreamObjectWriter::Options proto_writer_options;
+ proto_writer_options.ignore_unknown_fields = options.ignore_unknown_fields;
converter::ProtoStreamObjectWriter proto_writer(resolver, type, &sink,
- &listener);
+ &listener,
+ proto_writer_options);
converter::JsonStreamParser parser(&proto_writer);
const void* buffer;
@@ -123,16 +163,78 @@ util::Status JsonToBinaryStream(TypeResolver* resolver,
}
RETURN_IF_ERROR(parser.FinishParse());
- return util::Status::OK;
+ return listener.GetStatus();
}
util::Status JsonToBinaryString(TypeResolver* resolver,
const string& type_url,
const string& json_input,
- string* binary_output) {
+ string* binary_output,
+ const JsonParseOptions& options) {
io::ArrayInputStream input_stream(json_input.data(), json_input.size());
io::StringOutputStream output_stream(binary_output);
- return JsonToBinaryStream(resolver, type_url, &input_stream, &output_stream);
+ return JsonToBinaryStream(
+ resolver, type_url, &input_stream, &output_stream, options);
+}
+
+namespace {
+const char* kTypeUrlPrefix = "type.googleapis.com";
+TypeResolver* generated_type_resolver_ = NULL;
+GOOGLE_PROTOBUF_DECLARE_ONCE(generated_type_resolver_init_);
+
+string GetTypeUrl(const Message& message) {
+ return string(kTypeUrlPrefix) + "/" + message.GetDescriptor()->full_name();
+}
+
+void DeleteGeneratedTypeResolver() { delete generated_type_resolver_; }
+
+void InitGeneratedTypeResolver() {
+ generated_type_resolver_ = NewTypeResolverForDescriptorPool(
+ kTypeUrlPrefix, DescriptorPool::generated_pool());
+ ::google::protobuf::internal::OnShutdown(&DeleteGeneratedTypeResolver);
+}
+
+TypeResolver* GetGeneratedTypeResolver() {
+ ::google::protobuf::GoogleOnceInit(&generated_type_resolver_init_, &InitGeneratedTypeResolver);
+ return generated_type_resolver_;
+}
+} // namespace
+
+util::Status MessageToJsonString(const Message& message, string* output,
+ const JsonOptions& options) {
+ const DescriptorPool* pool = message.GetDescriptor()->file()->pool();
+ TypeResolver* resolver =
+ pool == DescriptorPool::generated_pool()
+ ? GetGeneratedTypeResolver()
+ : NewTypeResolverForDescriptorPool(kTypeUrlPrefix, pool);
+ util::Status result =
+ BinaryToJsonString(resolver, GetTypeUrl(message),
+ message.SerializeAsString(), output, options);
+ if (pool != DescriptorPool::generated_pool()) {
+ delete resolver;
+ }
+ return result;
+}
+
+util::Status JsonStringToMessage(const string& input, Message* message,
+ const JsonParseOptions& options) {
+ const DescriptorPool* pool = message->GetDescriptor()->file()->pool();
+ TypeResolver* resolver =
+ pool == DescriptorPool::generated_pool()
+ ? GetGeneratedTypeResolver()
+ : NewTypeResolverForDescriptorPool(kTypeUrlPrefix, pool);
+ string binary;
+ util::Status result = JsonToBinaryString(
+ resolver, GetTypeUrl(*message), input, &binary, options);
+ if (result.ok() && !message->ParseFromString(binary)) {
+ result =
+ util::Status(util::error::INVALID_ARGUMENT,
+ "JSON transcoder produced invalid protobuf output.");
+ }
+ if (pool != DescriptorPool::generated_pool()) {
+ delete resolver;
+ }
+ return result;
}
} // namespace util
diff --git a/src/google/protobuf/util/json_util.h b/src/google/protobuf/util/json_util.h
index 1718bfb5..6d3cee52 100644
--- a/src/google/protobuf/util/json_util.h
+++ b/src/google/protobuf/util/json_util.h
@@ -33,6 +33,7 @@
#ifndef GOOGLE_PROTOBUF_UTIL_JSON_UTIL_H__
#define GOOGLE_PROTOBUF_UTIL_JSON_UTIL_H__
+#include <google/protobuf/message.h>
#include <google/protobuf/util/type_resolver.h>
#include <google/protobuf/stubs/bytestream.h>
@@ -44,7 +45,14 @@ class ZeroCopyOutputStream;
} // namespace io
namespace util {
-struct JsonOptions {
+struct JsonParseOptions {
+ // Whether to ignore unknown JSON fields during parsing
+ bool ignore_unknown_fields;
+
+ JsonParseOptions() : ignore_unknown_fields(false) {}
+};
+
+struct JsonPrintOptions {
// Whether to add spaces, line breaks and indentation to make the JSON output
// easy to read.
bool add_whitespace;
@@ -54,30 +62,57 @@ struct JsonOptions {
// behavior and print primitive fields regardless of their values.
bool always_print_primitive_fields;
- JsonOptions() : add_whitespace(false),
- always_print_primitive_fields(false) {
+ JsonPrintOptions() : add_whitespace(false),
+ always_print_primitive_fields(false) {
}
};
+// DEPRECATED. Use JsonPrintOptions instead.
+typedef JsonPrintOptions JsonOptions;
+
+// Converts from protobuf message to JSON. This is a simple wrapper of
+// BinaryToJsonString(). It will use the DescriptorPool of the passed-in
+// message to resolve Any types.
+LIBPROTOBUF_EXPORT util::Status MessageToJsonString(const Message& message,
+ string* output,
+ const JsonOptions& options);
+
+inline util::Status MessageToJsonString(const Message& message,
+ string* output) {
+ return MessageToJsonString(message, output, JsonOptions());
+}
+
+// Converts from JSON to protobuf message. This is a simple wrapper of
+// JsonStringToBinary(). It will use the DescriptorPool of the passed-in
+// message to resolve Any types.
+LIBPROTOBUF_EXPORT util::Status JsonStringToMessage(const string& input,
+ Message* message,
+ const JsonParseOptions& options);
+
+inline util::Status JsonStringToMessage(const string& input,
+ Message* message) {
+ return JsonStringToMessage(input, message, JsonParseOptions());
+}
+
// Converts protobuf binary data to JSON.
// The conversion will fail if:
// 1. TypeResolver fails to resolve a type.
// 2. input is not valid protobuf wire format, or conflicts with the type
// information returned by TypeResolver.
// Note that unknown fields will be discarded silently.
-util::Status BinaryToJsonStream(
+LIBPROTOBUF_EXPORT util::Status BinaryToJsonStream(
TypeResolver* resolver,
const string& type_url,
io::ZeroCopyInputStream* binary_input,
io::ZeroCopyOutputStream* json_output,
- const JsonOptions& options);
+ const JsonPrintOptions& options);
inline util::Status BinaryToJsonStream(
TypeResolver* resolver, const string& type_url,
io::ZeroCopyInputStream* binary_input,
io::ZeroCopyOutputStream* json_output) {
return BinaryToJsonStream(resolver, type_url, binary_input, json_output,
- JsonOptions());
+ JsonPrintOptions());
}
LIBPROTOBUF_EXPORT util::Status BinaryToJsonString(
@@ -85,14 +120,14 @@ LIBPROTOBUF_EXPORT util::Status BinaryToJsonString(
const string& type_url,
const string& binary_input,
string* json_output,
- const JsonOptions& options);
+ const JsonPrintOptions& options);
inline util::Status BinaryToJsonString(TypeResolver* resolver,
const string& type_url,
const string& binary_input,
string* json_output) {
return BinaryToJsonString(resolver, type_url, binary_input, json_output,
- JsonOptions());
+ JsonPrintOptions());
}
// Converts JSON data to protobuf binary format.
@@ -100,18 +135,37 @@ inline util::Status BinaryToJsonString(TypeResolver* resolver,
// 1. TypeResolver fails to resolve a type.
// 2. input is not valid JSON format, or conflicts with the type
// information returned by TypeResolver.
-// 3. input has unknown fields.
-util::Status JsonToBinaryStream(
+LIBPROTOBUF_EXPORT util::Status JsonToBinaryStream(
TypeResolver* resolver,
const string& type_url,
io::ZeroCopyInputStream* json_input,
- io::ZeroCopyOutputStream* binary_output);
+ io::ZeroCopyOutputStream* binary_output,
+ const JsonParseOptions& options);
+
+inline util::Status JsonToBinaryStream(
+ TypeResolver* resolver,
+ const string& type_url,
+ io::ZeroCopyInputStream* json_input,
+ io::ZeroCopyOutputStream* binary_output) {
+ return JsonToBinaryStream(resolver, type_url, json_input, binary_output,
+ JsonParseOptions());
+}
LIBPROTOBUF_EXPORT util::Status JsonToBinaryString(
TypeResolver* resolver,
const string& type_url,
const string& json_input,
- string* binary_output);
+ string* binary_output,
+ const JsonParseOptions& options);
+
+inline util::Status JsonToBinaryString(
+ TypeResolver* resolver,
+ const string& type_url,
+ const string& json_input,
+ string* binary_output) {
+ return JsonToBinaryString(resolver, type_url, json_input, binary_output,
+ JsonParseOptions());
+}
namespace internal {
// Internal helper class. Put in the header so we can write unit-tests for it.
diff --git a/src/google/protobuf/util/json_util_test.cc b/src/google/protobuf/util/json_util_test.cc
index da68495f..dacac5e0 100644
--- a/src/google/protobuf/util/json_util_test.cc
+++ b/src/google/protobuf/util/json_util_test.cc
@@ -34,6 +34,8 @@
#include <string>
#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/descriptor_database.h>
+#include <google/protobuf/dynamic_message.h>
#include <google/protobuf/util/json_format_proto3.pb.h>
#include <google/protobuf/util/type_resolver.h>
#include <google/protobuf/util/type_resolver_util.h>
@@ -63,23 +65,21 @@ static string GetTypeUrl(const Descriptor* message) {
class JsonUtilTest : public testing::Test {
protected:
JsonUtilTest() {
- resolver_.reset(NewTypeResolverForDescriptorPool(
- kTypeUrlPrefix, DescriptorPool::generated_pool()));
}
- string ToJson(const Message& message, const JsonOptions& options) {
+ string ToJson(const Message& message, const JsonPrintOptions& options) {
string result;
- GOOGLE_CHECK_OK(BinaryToJsonString(resolver_.get(),
- GetTypeUrl(message.GetDescriptor()),
- message.SerializeAsString(), &result, options));
+ GOOGLE_CHECK_OK(MessageToJsonString(message, &result, options));
return result;
}
+ bool FromJson(const string& json, Message* message,
+ const JsonParseOptions& options) {
+ return JsonStringToMessage(json, message, options).ok();
+ }
+
bool FromJson(const string& json, Message* message) {
- string binary;
- GOOGLE_CHECK_OK(JsonToBinaryString(
- resolver_.get(), GetTypeUrl(message->GetDescriptor()), json, &binary));
- return message->ParseFromString(binary);
+ return FromJson(json, message, JsonParseOptions());
}
google::protobuf::scoped_ptr<TypeResolver> resolver_;
@@ -89,7 +89,7 @@ TEST_F(JsonUtilTest, TestWhitespaces) {
TestMessage m;
m.mutable_message_value();
- JsonOptions options;
+ JsonPrintOptions options;
EXPECT_EQ("{\"messageValue\":{}}", ToJson(m, options));
options.add_whitespace = true;
EXPECT_EQ(
@@ -99,28 +99,36 @@ TEST_F(JsonUtilTest, TestWhitespaces) {
ToJson(m, options));
}
-// TODO(skarvaje): Uncomment after cl/96232915 is submitted.
-// TEST_F(JsonUtilTest, TestDefaultValues) {
- // TestMessage m;
- // JsonOptions options;
- // EXPECT_EQ("{}", ToJson(m, options));
- // options.always_print_primitive_fields = true;
- // EXPECT_EQ(
- // "{\"boolValue\":false,"
- // "\"int32Value\":0,"
- // "\"int64Value\":\"0\","
- // "\"uint32Value\":0,"
- // "\"uint64Value\":\"0\","
- // "\"floatValue\":0,"
- // "\"doubleValue\":0,"
- // "\"stringValue\":\"\","
- // "\"bytesValue\":\"\","
- // // TODO(xiaofeng): The default enum value should be FOO. I believe
- // // this is a bug in DefaultValueObjectWriter.
- // "\"enumValue\":null"
- // "}",
- // ToJson(m, options));
-// }
+TEST_F(JsonUtilTest, TestDefaultValues) {
+ TestMessage m;
+ JsonPrintOptions options;
+ EXPECT_EQ("{}", ToJson(m, options));
+ options.always_print_primitive_fields = true;
+ EXPECT_EQ(
+ "{\"boolValue\":false,"
+ "\"int32Value\":0,"
+ "\"int64Value\":\"0\","
+ "\"uint32Value\":0,"
+ "\"uint64Value\":\"0\","
+ "\"floatValue\":0,"
+ "\"doubleValue\":0,"
+ "\"stringValue\":\"\","
+ "\"bytesValue\":\"\","
+ "\"enumValue\":\"FOO\","
+ "\"repeatedBoolValue\":[],"
+ "\"repeatedInt32Value\":[],"
+ "\"repeatedInt64Value\":[],"
+ "\"repeatedUint32Value\":[],"
+ "\"repeatedUint64Value\":[],"
+ "\"repeatedFloatValue\":[],"
+ "\"repeatedDoubleValue\":[],"
+ "\"repeatedStringValue\":[],"
+ "\"repeatedBytesValue\":[],"
+ "\"repeatedEnumValue\":[],"
+ "\"repeatedMessageValue\":[]"
+ "}",
+ ToJson(m, options));
+}
TEST_F(JsonUtilTest, ParseMessage) {
// Some random message but good enough to verify that the parsing warpper
@@ -136,8 +144,9 @@ TEST_F(JsonUtilTest, ParseMessage) {
" {\"value\": 40}, {\"value\": 96}\n"
" ]\n"
"}\n";
+ JsonParseOptions options;
TestMessage m;
- ASSERT_TRUE(FromJson(input, &m));
+ ASSERT_TRUE(FromJson(input, &m, options));
EXPECT_EQ(1024, m.int32_value());
ASSERT_EQ(2, m.repeated_int32_value_size());
EXPECT_EQ(1, m.repeated_int32_value(0));
@@ -151,13 +160,69 @@ TEST_F(JsonUtilTest, ParseMessage) {
TEST_F(JsonUtilTest, ParseMap) {
TestMap message;
(*message.mutable_string_map())["hello"] = 1234;
- JsonOptions options;
- EXPECT_EQ("{\"stringMap\":{\"hello\":1234}}", ToJson(message, options));
+ JsonPrintOptions print_options;
+ JsonParseOptions parse_options;
+ EXPECT_EQ("{\"stringMap\":{\"hello\":1234}}", ToJson(message, print_options));
TestMap other;
- ASSERT_TRUE(FromJson(ToJson(message, options), &other));
+ ASSERT_TRUE(FromJson(ToJson(message, print_options), &other, parse_options));
EXPECT_EQ(message.DebugString(), other.DebugString());
}
+TEST_F(JsonUtilTest, TestParseIgnoreUnknownFields) {
+ TestMessage m;
+ JsonParseOptions options;
+ options.ignore_unknown_fields = true;
+ EXPECT_TRUE(FromJson("{\"unknownName\":0}", &m, options));
+}
+
+TEST_F(JsonUtilTest, TestParseErrors) {
+ TestMessage m;
+ JsonParseOptions options;
+ // Parsing should fail if the field name can not be recognized.
+ EXPECT_FALSE(FromJson("{\"unknownName\":0}", &m, options));
+ // Parsing should fail if the value is invalid.
+ EXPECT_FALSE(FromJson("{\"int32Value\":2147483648}", &m, options));
+}
+
+TEST_F(JsonUtilTest, TestDynamicMessage) {
+ // Some random message but good enough to test the wrapper functions.
+ string input =
+ "{\n"
+ " \"int32Value\": 1024,\n"
+ " \"repeatedInt32Value\": [1, 2],\n"
+ " \"messageValue\": {\n"
+ " \"value\": 2048\n"
+ " },\n"
+ " \"repeatedMessageValue\": [\n"
+ " {\"value\": 40}, {\"value\": 96}\n"
+ " ]\n"
+ "}\n";
+
+ // Create a new DescriptorPool with the same protos as the generated one.
+ DescriptorPoolDatabase database(*DescriptorPool::generated_pool());
+ DescriptorPool pool(&database);
+ // A dynamic version of the test proto.
+ DynamicMessageFactory factory;
+ google::protobuf::scoped_ptr<Message> message(factory.GetPrototype(
+ pool.FindMessageTypeByName("proto3.TestMessage"))->New());
+ EXPECT_TRUE(FromJson(input, message.get()));
+
+ // Convert to generated message for easy inspection.
+ TestMessage generated;
+ EXPECT_TRUE(generated.ParseFromString(message->SerializeAsString()));
+ EXPECT_EQ(1024, generated.int32_value());
+ ASSERT_EQ(2, generated.repeated_int32_value_size());
+ EXPECT_EQ(1, generated.repeated_int32_value(0));
+ EXPECT_EQ(2, generated.repeated_int32_value(1));
+ EXPECT_EQ(2048, generated.message_value().value());
+ ASSERT_EQ(2, generated.repeated_message_value_size());
+ EXPECT_EQ(40, generated.repeated_message_value(0).value());
+ EXPECT_EQ(96, generated.repeated_message_value(1).value());
+
+ JsonOptions options;
+ EXPECT_EQ(ToJson(generated, options), ToJson(*message, options));
+}
+
typedef pair<char*, int> Segment;
// A ZeroCopyOutputStream that writes to multiple buffers.
class SegmentedZeroCopyOutputStream : public io::ZeroCopyOutputStream {
diff --git a/src/google/protobuf/util/message_differencer.cc b/src/google/protobuf/util/message_differencer.cc
index 47237e5a..a6d0cb07 100644
--- a/src/google/protobuf/util/message_differencer.cc
+++ b/src/google/protobuf/util/message_differencer.cc
@@ -47,6 +47,7 @@
#include <google/protobuf/stubs/callback.h>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/stringprintf.h>
#include <google/protobuf/any.h>
#include <google/protobuf/io/printer.h>
@@ -238,9 +239,25 @@ void MessageDifferencer::TreatAsSet(const FieldDescriptor* field) {
GOOGLE_CHECK(key_comparator == NULL)
<< "Cannot treat this repeated field as both Map and Set for"
<< " comparison. Field name is: " << field->full_name();
+ GOOGLE_CHECK(list_fields_.find(field) == list_fields_.end())
+ << "Cannot treat the same field as both SET and LIST. Field name is: "
+ << field->full_name();
set_fields_.insert(field);
}
+void MessageDifferencer::TreatAsList(const FieldDescriptor* field) {
+ GOOGLE_CHECK(field->is_repeated()) << "Field must be repeated: "
+ << field->full_name();
+ const MapKeyComparator* key_comparator = GetMapKeyComparator(field);
+ GOOGLE_CHECK(key_comparator == NULL)
+ << "Cannot treat this repeated field as both Map and Set for"
+ << " comparison. Field name is: " << field->full_name();
+ GOOGLE_CHECK(set_fields_.find(field) == set_fields_.end())
+ << "Cannot treat the same field as both SET and LIST. Field name is: "
+ << field->full_name();
+ list_fields_.insert(field);
+}
+
void MessageDifferencer::TreatAsMap(const FieldDescriptor* field,
const FieldDescriptor* key) {
GOOGLE_CHECK(field->is_repeated()) << "Field must be repeated: "
@@ -255,6 +272,9 @@ void MessageDifferencer::TreatAsMap(const FieldDescriptor* field,
GOOGLE_CHECK(set_fields_.find(field) == set_fields_.end())
<< "Cannot treat this repeated field as both Map and Set for "
<< "comparison.";
+ GOOGLE_CHECK(list_fields_.find(field) == list_fields_.end())
+ << "Cannot treat this repeated field as both Map and List for "
+ << "comparison.";
MapKeyComparator* key_comparator =
new MultipleFieldsMapKeyComparator(this, key);
owned_key_comparators_.push_back(key_comparator);
@@ -436,7 +456,9 @@ bool MessageDifferencer::Compare(
const Descriptor* descriptor2 = message2.GetDescriptor();
if (descriptor1 != descriptor2) {
GOOGLE_LOG(DFATAL) << "Comparison between two messages with different "
- << "descriptors.";
+ << "descriptors. "
+ << descriptor1->full_name() << " vs "
+ << descriptor2->full_name();
return false;
}
// Expand google.protobuf.Any payload if possible.
@@ -452,7 +474,10 @@ bool MessageDifferencer::Compare(
// Retrieve all the set fields, including extensions.
vector<const FieldDescriptor*> message1_fields;
+ message1_fields.reserve(1 + message1.GetDescriptor()->field_count());
+
vector<const FieldDescriptor*> message2_fields;
+ message2_fields.reserve(1 + message2.GetDescriptor()->field_count());
reflection1->ListFields(message1, &message1_fields);
reflection2->ListFields(message2, &message2_fields);
@@ -920,7 +945,8 @@ bool MessageDifferencer::CheckPathChanged(
bool MessageDifferencer::IsTreatedAsSet(const FieldDescriptor* field) {
if (!field->is_repeated()) return false;
if (field->is_map()) return true;
- if (repeated_field_comparison_ == AS_SET) return true;
+ if (repeated_field_comparison_ == AS_SET)
+ return list_fields_.find(field) == list_fields_.end();
return (set_fields_.find(field) != set_fields_.end());
}
@@ -1001,7 +1027,7 @@ bool MessageDifferencer::UnpackAny(const Message& any,
any.GetDescriptor()->file()->pool()->FindMessageTypeByName(
full_type_name);
if (desc == NULL) {
- GOOGLE_LOG(ERROR) << "Proto type '" << full_type_name << "' not found";
+ GOOGLE_DLOG(ERROR) << "Proto type '" << full_type_name << "' not found";
return false;
}
@@ -1011,7 +1037,7 @@ bool MessageDifferencer::UnpackAny(const Message& any,
data->reset(dynamic_message_factory_->GetPrototype(desc)->New());
string serialized_value = reflection->GetString(any, value_field);
if (!(*data)->ParseFromString(serialized_value)) {
- GOOGLE_LOG(ERROR) << "Failed to parse value for " << full_type_name;
+ GOOGLE_DLOG(ERROR) << "Failed to parse value for " << full_type_name;
return false;
}
return true;
@@ -1360,11 +1386,11 @@ bool MessageDifferencer::MatchRepeatedFieldIndices(
if (key_comparator != NULL || IsTreatedAsSet(repeated_field)) {
if (scope_ == PARTIAL) {
// When partial matching is enabled, Compare(a, b) && Compare(a, c)
- // doesn't neccessarily imply Compare(b, c). Therefore a naive greedy
+ // doesn't necessarily imply Compare(b, c). Therefore a naive greedy
// algorithm will fail to find a maximum matching.
// Here we use the argumenting path algorithm.
MaximumMatcher::NodeMatchCallback* callback =
- google::protobuf::internal::NewPermanentCallback(
+ ::google::protobuf::internal::NewPermanentCallback(
this, &MessageDifferencer::IsMatch,
repeated_field, key_comparator,
&message1, &message2, parent_fields);
diff --git a/src/google/protobuf/util/message_differencer.h b/src/google/protobuf/util/message_differencer.h
index 34c173db..654d1a67 100644
--- a/src/google/protobuf/util/message_differencer.h
+++ b/src/google/protobuf/util/message_differencer.h
@@ -278,7 +278,7 @@ class LIBPROTOBUF_EXPORT MessageDifferencer {
const Message& message2,
const vector<SpecificField>& field_path) { }
- // Report that an unkown field is ignored. (see comment above).
+ // Report that an unknown field is ignored. (see comment above).
// Note this is a different function since the last SpecificField in field
// path has a null field. This could break existing Reporter.
virtual void ReportUnknownFieldIgnored(
@@ -397,9 +397,16 @@ class LIBPROTOBUF_EXPORT MessageDifferencer {
// + n^3) in which n^3 is the time complexity of the maximum matching
// algorithm.
//
- // REQUIRES: field->is_repeated()
+ // REQUIRES: field->is_repeated() and field not registered with TreatAsList
void TreatAsSet(const FieldDescriptor* field);
+ // The elements of the given repeated field will be treated as a list for
+ // diffing purposes, so different orderings of the same elements will NOT be
+ // considered equal.
+ //
+ // REQUIRED: field->is_repeated() and field not registered with TreatAsSet
+ void TreatAsList(const FieldDescriptor* field);
+
// The elements of the given repeated field will be treated as a map for
// diffing purposes, with |key| being the map key. Thus, elements with the
// same key will be compared even if they do not appear at the same index.
@@ -563,6 +570,12 @@ class LIBPROTOBUF_EXPORT MessageDifferencer {
// any differences found in human-readable form to the supplied
// ZeroCopyOutputStream or Printer. If a printer is used, the delimiter
// *must* be '$'.
+ //
+ // WARNING: this reporter does not necessarily flush its output until it is
+ // destroyed. As a result, it is not safe to assume the output is valid or
+ // complete until after you destroy the reporter. For example, if you use a
+ // StreamReporter to write to a StringOutputStream, the target string may
+ // contain uninitialized data until the reporter is destroyed.
class LIBPROTOBUF_EXPORT StreamReporter : public Reporter {
public:
explicit StreamReporter(io::ZeroCopyOutputStream* output);
@@ -791,6 +804,7 @@ class LIBPROTOBUF_EXPORT MessageDifferencer {
RepeatedFieldComparison repeated_field_comparison_;
FieldSet set_fields_;
+ FieldSet list_fields_;
// Keeps track of MapKeyComparators that are created within
// MessageDifferencer. These MapKeyComparators should be deleted
// before MessageDifferencer is destroyed.
diff --git a/src/google/protobuf/util/message_differencer_unittest.cc b/src/google/protobuf/util/message_differencer_unittest.cc
index 701b94ae..ed43c512 100755
--- a/src/google/protobuf/util/message_differencer_unittest.cc
+++ b/src/google/protobuf/util/message_differencer_unittest.cc
@@ -1103,12 +1103,19 @@ TEST(MessageDifferencerTest, RepeatedFieldSetTest_Combination) {
msg1.add_rw("change"); msg2.add_rw("change");
// Compare
- util::MessageDifferencer differencer;
- differencer.TreatAsMap(msg1.GetDescriptor()->FindFieldByName("item"),
- item->GetDescriptor()->FindFieldByName("a"));
- differencer.TreatAsSet(msg1.GetDescriptor()->FindFieldByName("rv"));
- differencer.TreatAsSet(item->GetDescriptor()->FindFieldByName("ra"));
- EXPECT_TRUE(differencer.Compare(msg1, msg2));
+ util::MessageDifferencer differencer1;
+ differencer1.TreatAsMap(msg1.GetDescriptor()->FindFieldByName("item"),
+ item->GetDescriptor()->FindFieldByName("a"));
+ differencer1.TreatAsSet(msg1.GetDescriptor()->FindFieldByName("rv"));
+ differencer1.TreatAsSet(item->GetDescriptor()->FindFieldByName("ra"));
+ EXPECT_TRUE(differencer1.Compare(msg1, msg2));
+
+ util::MessageDifferencer differencer2;
+ differencer2.TreatAsMap(msg1.GetDescriptor()->FindFieldByName("item"),
+ item->GetDescriptor()->FindFieldByName("a"));
+ differencer2.set_repeated_field_comparison(util::MessageDifferencer::AS_SET);
+ differencer2.TreatAsList(msg1.GetDescriptor()->FindFieldByName("rw"));
+ EXPECT_TRUE(differencer2.Compare(msg1, msg2));
}
TEST(MessageDifferencerTest, RepeatedFieldMapTest_Partial) {
@@ -1168,6 +1175,11 @@ TEST(MessageDifferencerTest, RepeatedFieldSetTest_Duplicates) {
differencer.TreatAsSet(GetFieldDescriptor(a, "rv"));
EXPECT_TRUE(differencer.Compare(b, a));
EXPECT_FALSE(differencer.Compare(c, a));
+
+ util::MessageDifferencer differencer1;
+ differencer1.set_repeated_field_comparison(util::MessageDifferencer::AS_SET);
+ EXPECT_TRUE(differencer1.Compare(b, a));
+ EXPECT_FALSE(differencer1.Compare(c, a));
}
TEST(MessageDifferencerTest, RepeatedFieldSetTest_PartialSimple) {
@@ -1442,11 +1454,10 @@ static const char* const kIgnoredFields[] = {"rm.b", "rm.m.b"};
class TestIgnorer : public util::MessageDifferencer::IgnoreCriteria {
public:
- bool IsIgnored(
+ virtual bool IsIgnored(
const Message& message1, const Message& message2,
const FieldDescriptor* field,
- const vector<util::MessageDifferencer::SpecificField>& parent_fields)
- override {
+ const vector<util::MessageDifferencer::SpecificField>& parent_fields) {
string name = "";
for (int i = 0; i < parent_fields.size(); ++i) {
name += parent_fields[i].field->name() + ".";
@@ -1488,8 +1499,10 @@ TEST(MessageDifferencerTest, TreatRepeatedFieldAsMapWithIgnoredKeyFields) {
class ValueProductMapKeyComparator
: public util::MessageDifferencer::MapKeyComparator {
public:
- virtual bool IsMatch(const Message &message1,
- const Message &message2) const {
+ typedef util::MessageDifferencer::SpecificField SpecificField;
+ virtual bool IsMatch(
+ const Message &message1, const Message &message2,
+ const vector<SpecificField>& parent_fields) const {
const Reflection* reflection1 = message1.GetReflection();
const Reflection* reflection2 = message2.GetReflection();
// FieldDescriptor for item.ra
@@ -2336,7 +2349,7 @@ TEST_F(ComparisonTest, RepeatedMapFieldTest_RepeatedMessageKey) {
}
TEST_F(ComparisonTest, RepeatedSetOptionTest_Unknown) {
- // Currently, as_set option doens't have affects on unknown field.
+ // Currently, as_set option doesn't have affects on unknown field.
// If needed, this feature will be added by request.
repeated_field_as_set();
unknown1_->AddGroup(245)->AddFixed32(248, 1);
@@ -2803,15 +2816,20 @@ class MatchingTest : public testing::Test {
const Message& msg1, const Message& msg2,
bool result) {
string output;
- io::StringOutputStream output_stream(&output);
- MessageDifferencer::StreamReporter reporter(&output_stream);
- reporter.set_report_modified_aggregates(true);
- differencer->set_report_matches(true);
- differencer->ReportDifferencesTo(&reporter);
- if (result) {
- EXPECT_TRUE(differencer->Compare(msg1, msg2));
- } else {
- EXPECT_FALSE(differencer->Compare(msg1, msg2));
+ {
+ // Before we return the "output" string, we must make sure the
+ // StreamReporter is destructored because its destructor will
+ // flush the stream.
+ io::StringOutputStream output_stream(&output);
+ MessageDifferencer::StreamReporter reporter(&output_stream);
+ reporter.set_report_modified_aggregates(true);
+ differencer->set_report_matches(true);
+ differencer->ReportDifferencesTo(&reporter);
+ if (result) {
+ EXPECT_TRUE(differencer->Compare(msg1, msg2));
+ } else {
+ EXPECT_FALSE(differencer->Compare(msg1, msg2));
+ }
}
return output;
}
diff --git a/src/google/protobuf/util/time_util.cc b/src/google/protobuf/util/time_util.cc
index c782d691..031d019a 100644
--- a/src/google/protobuf/util/time_util.cc
+++ b/src/google/protobuf/util/time_util.cc
@@ -142,6 +142,13 @@ int64 RoundTowardZero(int64 value, int64 divider) {
}
} // namespace
+// Actually define these static const integers. Required by C++ standard (but
+// omitting them may still work with some compilers).
+const int64 TimeUtil::kTimestampMinSeconds;
+const int64 TimeUtil::kTimestampMaxSeconds;
+const int64 TimeUtil::kDurationMaxSeconds;
+const int64 TimeUtil::kDurationMinSeconds;
+
string TimeUtil::ToString(const Timestamp& timestamp) {
return FormatTime(timestamp.seconds(), timestamp.nanos());
}
@@ -174,7 +181,7 @@ string TimeUtil::ToString(const Duration& duration) {
seconds = -seconds;
nanos = -nanos;
}
- result += StringPrintf("%" GOOGLE_LL_FORMAT "d", seconds);
+ result += SimpleItoa(seconds);
if (nanos != 0) {
result += "." + FormatNanos(nanos);
}
diff --git a/src/google/protobuf/util/type_resolver_util.cc b/src/google/protobuf/util/type_resolver_util.cc
index a0996954..96393903 100644
--- a/src/google/protobuf/util/type_resolver_util.cc
+++ b/src/google/protobuf/util/type_resolver_util.cc
@@ -159,7 +159,10 @@ class DescriptorPoolTypeResolver : public TypeResolver {
}
field->set_number(descriptor->number());
field->set_name(descriptor->name());
- field->set_json_name(converter::ToCamelCase(descriptor->name()));
+ field->set_json_name(descriptor->json_name());
+ if (descriptor->has_default_value()) {
+ field->set_default_value(DefaultValueAsString(descriptor));
+ }
if (descriptor->type() == FieldDescriptor::TYPE_MESSAGE) {
field->set_type_url(GetTypeUrl(descriptor->message_type()));
} else if (descriptor->type() == FieldDescriptor::TYPE_ENUM) {
@@ -200,6 +203,46 @@ class DescriptorPoolTypeResolver : public TypeResolver {
return url_prefix_ + "/" + descriptor->full_name();
}
+ string DefaultValueAsString(const FieldDescriptor* descriptor) {
+ switch (descriptor->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ return SimpleItoa(descriptor->default_value_int32());
+ break;
+ case FieldDescriptor::CPPTYPE_INT64:
+ return SimpleItoa(descriptor->default_value_int64());
+ break;
+ case FieldDescriptor::CPPTYPE_UINT32:
+ return SimpleItoa(descriptor->default_value_uint32());
+ break;
+ case FieldDescriptor::CPPTYPE_UINT64:
+ return SimpleItoa(descriptor->default_value_uint64());
+ break;
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ return SimpleFtoa(descriptor->default_value_float());
+ break;
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ return SimpleDtoa(descriptor->default_value_double());
+ break;
+ case FieldDescriptor::CPPTYPE_BOOL:
+ return descriptor->default_value_bool() ? "true" : "false";
+ break;
+ case FieldDescriptor::CPPTYPE_STRING:
+ if (descriptor->type() == FieldDescriptor::TYPE_BYTES) {
+ return CEscape(descriptor->default_value_string());
+ } else {
+ return descriptor->default_value_string();
+ }
+ break;
+ case FieldDescriptor::CPPTYPE_ENUM:
+ return descriptor->default_value_enum()->name();
+ break;
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ GOOGLE_LOG(DFATAL) << "Messages can't have default values!";
+ break;
+ }
+ return "";
+ }
+
string url_prefix_;
const DescriptorPool* pool_;
};
diff --git a/src/google/protobuf/util/type_resolver_util_test.cc b/src/google/protobuf/util/type_resolver_util_test.cc
index 74b2d0da..8a0bf652 100644
--- a/src/google/protobuf/util/type_resolver_util_test.cc
+++ b/src/google/protobuf/util/type_resolver_util_test.cc
@@ -43,6 +43,7 @@
#include <google/protobuf/map_unittest.pb.h>
#include <google/protobuf/test_util.h>
#include <google/protobuf/unittest.pb.h>
+#include <google/protobuf/util/json_format_proto3.pb.h>
#include <google/protobuf/util/type_resolver.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
@@ -332,6 +333,19 @@ TEST_F(DescriptorPoolTypeResolverTest, TestEnum) {
EnumHasValue(type, "NEG", -1);
}
+TEST_F(DescriptorPoolTypeResolverTest, TestJsonName) {
+ Type type;
+ ASSERT_TRUE(resolver_->ResolveMessageType(
+ GetTypeUrl<protobuf_unittest::TestAllTypes>(), &type)
+ .ok());
+ EXPECT_EQ("optionalInt32", FindField(type, "optional_int32")->json_name());
+
+ ASSERT_TRUE(resolver_->ResolveMessageType(
+ GetTypeUrl<proto3::TestCustomJsonName>(), &type)
+ .ok());
+ EXPECT_EQ("@value", FindField(type, "value")->json_name());
+}
+
} // namespace
} // namespace util
} // namespace protobuf
diff --git a/src/google/protobuf/wire_format.h b/src/google/protobuf/wire_format.h
index 941be75b..aaee21f0 100644
--- a/src/google/protobuf/wire_format.h
+++ b/src/google/protobuf/wire_format.h
@@ -315,7 +315,7 @@ inline void WireFormat::VerifyUTF8String(const char* data, int size,
WireFormatLite::VerifyUtf8String(
data, size, static_cast<WireFormatLite::Operation>(op), NULL);
#else
- // Avoid the compiler warning about unsued variables.
+ // Avoid the compiler warning about unused variables.
(void)data; (void)size; (void)op;
#endif
}
diff --git a/src/google/protobuf/wire_format_lite.cc b/src/google/protobuf/wire_format_lite.cc
index 7f1093c8..05cc0854 100644
--- a/src/google/protobuf/wire_format_lite.cc
+++ b/src/google/protobuf/wire_format_lite.cc
@@ -412,7 +412,7 @@ void WireFormatLite::WriteString(int field_number, const string& value,
io::CodedOutputStream* output) {
// String is for UTF-8 text only
WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
- GOOGLE_CHECK(value.size() <= kint32max);
+ GOOGLE_CHECK_LE(value.size(), kint32max);
output->WriteVarint32(value.size());
output->WriteString(value);
}
@@ -421,14 +421,14 @@ void WireFormatLite::WriteStringMaybeAliased(
io::CodedOutputStream* output) {
// String is for UTF-8 text only
WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
- GOOGLE_CHECK(value.size() <= kint32max);
+ GOOGLE_CHECK_LE(value.size(), kint32max);
output->WriteVarint32(value.size());
output->WriteRawMaybeAliased(value.data(), value.size());
}
void WireFormatLite::WriteBytes(int field_number, const string& value,
io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
- GOOGLE_CHECK(value.size() <= kint32max);
+ GOOGLE_CHECK_LE(value.size(), kint32max);
output->WriteVarint32(value.size());
output->WriteString(value);
}
@@ -436,7 +436,7 @@ void WireFormatLite::WriteBytesMaybeAliased(
int field_number, const string& value,
io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
- GOOGLE_CHECK(value.size() <= kint32max);
+ GOOGLE_CHECK_LE(value.size(), kint32max);
output->WriteVarint32(value.size());
output->WriteRawMaybeAliased(value.data(), value.size());
}
@@ -466,7 +466,8 @@ void WireFormatLite::WriteGroupMaybeToArray(int field_number,
const int size = value.GetCachedSize();
uint8* target = output->GetDirectBufferForNBytesAndAdvance(size);
if (target != NULL) {
- uint8* end = value.SerializeWithCachedSizesToArray(target);
+ uint8* end = value.InternalSerializeWithCachedSizesToArray(
+ output->IsSerializationDeterminstic(), target);
GOOGLE_DCHECK_EQ(end - target, size);
} else {
value.SerializeWithCachedSizes(output);
@@ -482,7 +483,8 @@ void WireFormatLite::WriteMessageMaybeToArray(int field_number,
output->WriteVarint32(size);
uint8* target = output->GetDirectBufferForNBytesAndAdvance(size);
if (target != NULL) {
- uint8* end = value.SerializeWithCachedSizesToArray(target);
+ uint8* end = value.InternalSerializeWithCachedSizesToArray(
+ output->IsSerializationDeterminstic(), target);
GOOGLE_DCHECK_EQ(end - target, size);
} else {
value.SerializeWithCachedSizes(output);
diff --git a/src/google/protobuf/wire_format_lite.h b/src/google/protobuf/wire_format_lite.h
index 55fc7ecd..580d4db0 100644
--- a/src/google/protobuf/wire_format_lite.h
+++ b/src/google/protobuf/wire_format_lite.h
@@ -457,20 +457,48 @@ class LIBPROTOBUF_EXPORT WireFormatLite {
INL static uint8* WriteBytesToArray(
field_number, const string& value, output);
- INL static uint8* WriteGroupToArray(
- field_number, const MessageLite& value, output);
- INL static uint8* WriteMessageToArray(
- field_number, const MessageLite& value, output);
+ // Whether to serialize deterministically (e.g., map keys are
+ // sorted) is a property of a CodedOutputStream, and in the process
+ // of serialization, the "ToArray" variants may be invoked. But they don't
+ // have a CodedOutputStream available, so they get an additional parameter
+ // telling them whether to serialize deterministically.
+ INL static uint8* InternalWriteGroupToArray(
+ field_number, const MessageLite& value, bool deterministic, output);
+ INL static uint8* InternalWriteMessageToArray(
+ field_number, const MessageLite& value, bool deterministic, output);
// Like above, but de-virtualize the call to SerializeWithCachedSizes(). The
// pointer must point at an instance of MessageType, *not* a subclass (or
// the subclass must not override SerializeWithCachedSizes()).
template<typename MessageType>
+ INL static uint8* InternalWriteGroupNoVirtualToArray(
+ field_number, const MessageType& value, bool deterministic, output);
+ template<typename MessageType>
+ INL static uint8* InternalWriteMessageNoVirtualToArray(
+ field_number, const MessageType& value, bool deterministic, output);
+
+ // For backward-compatibility, the last four methods also have versions
+ // that are non-deterministic always.
+ INL static uint8* WriteGroupToArray(
+ field_number, const MessageLite& value, output) {
+ return InternalWriteGroupToArray(field_number_arg, value, false, target);
+ }
+ INL static uint8* WriteMessageToArray(
+ field_number, const MessageLite& value, output) {
+ return InternalWriteMessageToArray(field_number_arg, value, false, target);
+ }
+ template<typename MessageType>
INL static uint8* WriteGroupNoVirtualToArray(
- field_number, const MessageType& value, output);
+ field_number, const MessageType& value, output) {
+ return InternalWriteGroupNoVirtualToArray(field_number_arg, value, false,
+ target);
+ }
template<typename MessageType>
INL static uint8* WriteMessageNoVirtualToArray(
- field_number, const MessageType& value, output);
+ field_number, const MessageType& value, output) {
+ return InternalWriteMessageNoVirtualToArray(field_number_arg, value, false,
+ target);
+ }
#undef output
#undef input
diff --git a/src/google/protobuf/wire_format_lite_inl.h b/src/google/protobuf/wire_format_lite_inl.h
index b1c477d1..93d7c824 100644
--- a/src/google/protobuf/wire_format_lite_inl.h
+++ b/src/google/protobuf/wire_format_lite_inl.h
@@ -274,8 +274,8 @@ inline bool WireFormatLite::ReadRepeatedFixedSizePrimitive(
// The number of bytes each type occupies on the wire.
const int per_value_size = tag_size + sizeof(value);
- int elements_available = min(values->Capacity() - values->size(),
- size / per_value_size);
+ int elements_available =
+ std::min(values->Capacity() - values->size(), size / per_value_size);
int num_read = 0;
while (num_read < elements_available &&
(buffer = io::CodedInputStream::ExpectTagFromArray(
@@ -329,8 +329,8 @@ bool WireFormatLite::ReadRepeatedPrimitiveNoInline(
template <typename CType, enum WireFormatLite::FieldType DeclaredType>
inline bool WireFormatLite::ReadPackedPrimitive(io::CodedInputStream* input,
RepeatedField<CType>* values) {
- uint32 length;
- if (!input->ReadVarint32(&length)) return false;
+ int length;
+ if (!input->ReadVarintSizeAsInt(&length)) return false;
io::CodedInputStream::Limit limit = input->PushLimit(length);
while (input->BytesUntilLimit() > 0) {
CType value;
@@ -344,11 +344,11 @@ inline bool WireFormatLite::ReadPackedPrimitive(io::CodedInputStream* input,
template <typename CType, enum WireFormatLite::FieldType DeclaredType>
inline bool WireFormatLite::ReadPackedFixedSizePrimitive(
io::CodedInputStream* input, RepeatedField<CType>* values) {
- uint32 length;
- if (!input->ReadVarint32(&length)) return false;
- const uint32 old_entries = values->size();
- const uint32 new_entries = length / sizeof(CType);
- const uint32 new_bytes = new_entries * sizeof(CType);
+ int length;
+ if (!input->ReadVarintSizeAsInt(&length)) return false;
+ const int old_entries = values->size();
+ const int new_entries = length / sizeof(CType);
+ const int new_bytes = new_entries * sizeof(CType);
if (new_bytes != length) return false;
// We would *like* to pre-allocate the buffer to write into (for
// speed), but *must* avoid performing a very large allocation due
@@ -367,7 +367,7 @@ inline bool WireFormatLite::ReadPackedFixedSizePrimitive(
bytes_limit = input->BytesUntilLimit();
} else {
bytes_limit =
- min(bytes_limit, static_cast<int64>(input->BytesUntilLimit()));
+ std::min(bytes_limit, static_cast<int64>(input->BytesUntilLimit()));
}
if (bytes_limit >= new_bytes) {
// Fast-path that pre-allocates *values to the final size.
@@ -382,7 +382,7 @@ inline bool WireFormatLite::ReadPackedFixedSizePrimitive(
#else
values->Reserve(old_entries + new_entries);
CType value;
- for (uint32 i = 0; i < new_entries; ++i) {
+ for (int i = 0; i < new_entries; ++i) {
if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
values->AddAlreadyReserved(value);
}
@@ -392,7 +392,7 @@ inline bool WireFormatLite::ReadPackedFixedSizePrimitive(
// safely allocate. We read as much as we can into *values
// without pre-allocating "length" bytes.
CType value;
- for (uint32 i = 0; i < new_entries; ++i) {
+ for (int i = 0; i < new_entries; ++i) {
if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
values->Add(value);
}
@@ -412,12 +412,12 @@ inline bool WireFormatLite::ReadPackedPrimitive< \
CPPTYPE, WireFormatLite::DECLARED_TYPE>(input, values); \
}
-READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(uint32, TYPE_FIXED32);
-READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(uint64, TYPE_FIXED64);
-READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(int32, TYPE_SFIXED32);
-READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(int64, TYPE_SFIXED64);
-READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(float, TYPE_FLOAT);
-READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(double, TYPE_DOUBLE);
+READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(uint32, TYPE_FIXED32)
+READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(uint64, TYPE_FIXED64)
+READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(int32, TYPE_SFIXED32)
+READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(int64, TYPE_SFIXED64)
+READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(float, TYPE_FLOAT)
+READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(double, TYPE_DOUBLE)
#undef READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE
@@ -443,8 +443,8 @@ inline bool WireFormatLite::ReadGroup(int field_number,
}
inline bool WireFormatLite::ReadMessage(io::CodedInputStream* input,
MessageLite* value) {
- uint32 length;
- if (!input->ReadVarint32(&length)) return false;
+ int length;
+ if (!input->ReadVarintSizeAsInt(&length)) return false;
std::pair<io::CodedInputStream::Limit, int> p =
input->IncrementRecursionDepthAndPushLimit(length);
if (p.second < 0 || !value->MergePartialFromCodedStream(input)) return false;
@@ -489,8 +489,8 @@ inline bool WireFormatLite::ReadGroupNoVirtualNoRecursionDepth(
template<typename MessageType_WorkAroundCppLookupDefect>
inline bool WireFormatLite::ReadMessageNoVirtual(
io::CodedInputStream* input, MessageType_WorkAroundCppLookupDefect* value) {
- uint32 length;
- if (!input->ReadVarint32(&length)) return false;
+ int length;
+ if (!input->ReadVarintSizeAsInt(&length)) return false;
std::pair<io::CodedInputStream::Limit, int> p =
input->IncrementRecursionDepthAndPushLimit(length);
if (p.second < 0 || !value->
@@ -772,42 +772,40 @@ inline uint8* WireFormatLite::WriteBytesToArray(int field_number,
}
-inline uint8* WireFormatLite::WriteGroupToArray(int field_number,
- const MessageLite& value,
- uint8* target) {
+inline uint8* WireFormatLite::InternalWriteGroupToArray(
+ int field_number, const MessageLite& value, bool deterministic,
+ uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target);
- target = value.SerializeWithCachedSizesToArray(target);
+ target = value.InternalSerializeWithCachedSizesToArray(deterministic, target);
return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target);
}
-inline uint8* WireFormatLite::WriteMessageToArray(int field_number,
- const MessageLite& value,
- uint8* target) {
+inline uint8* WireFormatLite::InternalWriteMessageToArray(
+ int field_number, const MessageLite& value, bool deterministic,
+ uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
target = io::CodedOutputStream::WriteVarint32ToArray(
value.GetCachedSize(), target);
- return value.SerializeWithCachedSizesToArray(target);
+ return value.InternalSerializeWithCachedSizesToArray(deterministic, target);
}
// See comment on ReadGroupNoVirtual to understand the need for this template
// parameter name.
template<typename MessageType_WorkAroundCppLookupDefect>
-inline uint8* WireFormatLite::WriteGroupNoVirtualToArray(
+inline uint8* WireFormatLite::InternalWriteGroupNoVirtualToArray(
int field_number, const MessageType_WorkAroundCppLookupDefect& value,
- uint8* target) {
+ bool deterministic, uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target);
- target = value.MessageType_WorkAroundCppLookupDefect
- ::SerializeWithCachedSizesToArray(target);
+ target = value.InternalSerializeWithCachedSizesToArray(deterministic, target);
return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target);
}
template<typename MessageType_WorkAroundCppLookupDefect>
-inline uint8* WireFormatLite::WriteMessageNoVirtualToArray(
+inline uint8* WireFormatLite::InternalWriteMessageNoVirtualToArray(
int field_number, const MessageType_WorkAroundCppLookupDefect& value,
- uint8* target) {
+ bool deterministic, uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
target = io::CodedOutputStream::WriteVarint32ToArray(
value.MessageType_WorkAroundCppLookupDefect::GetCachedSize(), target);
- return value.MessageType_WorkAroundCppLookupDefect
- ::SerializeWithCachedSizesToArray(target);
+ return value.InternalSerializeWithCachedSizesToArray(deterministic, target);
}
// ===================================================================
diff --git a/src/google/protobuf/wire_format_unittest.cc b/src/google/protobuf/wire_format_unittest.cc
index 15c37556..4e4add66 100644
--- a/src/google/protobuf/wire_format_unittest.cc
+++ b/src/google/protobuf/wire_format_unittest.cc
@@ -45,6 +45,7 @@
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
#include <google/protobuf/stubs/stl_util.h>
diff --git a/src/google/protobuf/wrappers.pb.cc b/src/google/protobuf/wrappers.pb.cc
index e153687b..33a69d3b 100644
--- a/src/google/protobuf/wrappers.pb.cc
+++ b/src/google/protobuf/wrappers.pb.cc
@@ -7,6 +7,7 @@
#include <algorithm>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/port.h>
#include <google/protobuf/stubs/once.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/wire_format_lite_inl.h>
@@ -52,6 +53,7 @@ const ::google::protobuf::internal::GeneratedMessageReflection*
} // namespace
+void protobuf_AssignDesc_google_2fprotobuf_2fwrappers_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AssignDesc_google_2fprotobuf_2fwrappers_2eproto() {
protobuf_AddDesc_google_2fprotobuf_2fwrappers_2eproto();
const ::google::protobuf::FileDescriptor* file =
@@ -203,6 +205,7 @@ inline void protobuf_AssignDescriptorsOnce() {
&protobuf_AssignDesc_google_2fprotobuf_2fwrappers_2eproto);
}
+void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
void protobuf_RegisterTypes(const ::std::string&) {
protobuf_AssignDescriptorsOnce();
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
@@ -248,6 +251,7 @@ void protobuf_ShutdownFile_google_2fprotobuf_2fwrappers_2eproto() {
delete BytesValue_reflection_;
}
+void protobuf_AddDesc_google_2fprotobuf_2fwrappers_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AddDesc_google_2fprotobuf_2fwrappers_2eproto() {
static bool already_here = false;
if (already_here) return;
@@ -262,10 +266,11 @@ void protobuf_AddDesc_google_2fprotobuf_2fwrappers_2eproto() {
"e\030\001 \001(\004\"\033\n\nInt32Value\022\r\n\005value\030\001 \001(\005\"\034\n\013"
"UInt32Value\022\r\n\005value\030\001 \001(\r\"\032\n\tBoolValue\022"
"\r\n\005value\030\001 \001(\010\"\034\n\013StringValue\022\r\n\005value\030\001"
- " \001(\t\"\033\n\nBytesValue\022\r\n\005value\030\001 \001(\014BP\n\023com"
- ".google.protobufB\rWrappersProtoP\001\240\001\001\242\002\003G"
- "PB\252\002\036Google.Protobuf.WellKnownTypesb\006pro"
- "to3", 403);
+ " \001(\t\"\033\n\nBytesValue\022\r\n\005value\030\001 \001(\014B\177\n\023com"
+ ".google.protobufB\rWrappersProtoP\001Z*githu"
+ "b.com/golang/protobuf/ptypes/wrappers\240\001\001"
+ "\370\001\001\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTyp"
+ "esb\006proto3", 450);
::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
"google/protobuf/wrappers.proto", &protobuf_RegisterTypes);
DoubleValue::default_instance_ = new DoubleValue();
@@ -296,16 +301,6 @@ struct StaticDescriptorInitializer_google_2fprotobuf_2fwrappers_2eproto {
}
} static_descriptor_initializer_google_2fprotobuf_2fwrappers_2eproto_;
-namespace {
-
-static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD;
-static void MergeFromFail(int line) {
- GOOGLE_CHECK(false) << __FILE__ << ":" << line;
-}
-
-} // namespace
-
-
// ===================================================================
#if !defined(_MSC_VER) || _MSC_VER >= 1900
@@ -318,6 +313,14 @@ DoubleValue::DoubleValue()
// @@protoc_insertion_point(constructor:google.protobuf.DoubleValue)
}
+DoubleValue::DoubleValue(::google::protobuf::Arena* arena)
+ : ::google::protobuf::Message(),
+ _internal_metadata_(arena) {
+ SharedCtor();
+ RegisterArenaDtor(arena);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.DoubleValue)
+}
+
void DoubleValue::InitAsDefaultInstance() {
_is_default_instance_ = true;
}
@@ -342,10 +345,20 @@ DoubleValue::~DoubleValue() {
}
void DoubleValue::SharedDtor() {
+ if (GetArenaNoVirtual() != NULL) {
+ return;
+ }
+
if (this != default_instance_) {
}
}
+void DoubleValue::ArenaDtor(void* object) {
+ DoubleValue* _this = reinterpret_cast< DoubleValue* >(object);
+ (void)_this;
+}
+void DoubleValue::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+}
void DoubleValue::SetCachedSize(int size) const {
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
_cached_size_ = size;
@@ -364,20 +377,17 @@ const DoubleValue& DoubleValue::default_instance() {
DoubleValue* DoubleValue::default_instance_ = NULL;
DoubleValue* DoubleValue::New(::google::protobuf::Arena* arena) const {
- DoubleValue* n = new DoubleValue;
- if (arena != NULL) {
- arena->Own(n);
- }
- return n;
+ return ::google::protobuf::Arena::CreateMessage<DoubleValue>(arena);
}
void DoubleValue::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.DoubleValue)
value_ = 0;
}
bool DoubleValue::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.DoubleValue)
for (;;) {
@@ -431,8 +441,8 @@ void DoubleValue::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.DoubleValue)
}
-::google::protobuf::uint8* DoubleValue::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* DoubleValue::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.DoubleValue)
// optional double value = 1;
if (this->value() != 0) {
@@ -444,6 +454,7 @@ void DoubleValue::SerializeWithCachedSizes(
}
int DoubleValue::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.DoubleValue)
int total_size = 0;
// optional double value = 1;
@@ -458,31 +469,41 @@ int DoubleValue::ByteSize() const {
}
void DoubleValue::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.DoubleValue)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const DoubleValue* source =
::google::protobuf::internal::DynamicCastToGenerated<const DoubleValue>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.DoubleValue)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.DoubleValue)
MergeFrom(*source);
}
}
void DoubleValue::MergeFrom(const DoubleValue& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.DoubleValue)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from.value() != 0) {
set_value(from.value());
}
}
void DoubleValue::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.DoubleValue)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void DoubleValue::CopyFrom(const DoubleValue& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.DoubleValue)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -495,6 +516,18 @@ bool DoubleValue::IsInitialized() const {
void DoubleValue::Swap(DoubleValue* other) {
if (other == this) return;
+ if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
+ InternalSwap(other);
+ } else {
+ DoubleValue temp;
+ temp.MergeFrom(*this);
+ CopyFrom(*other);
+ other->CopyFrom(temp);
+ }
+}
+void DoubleValue::UnsafeArenaSwap(DoubleValue* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
void DoubleValue::InternalSwap(DoubleValue* other) {
@@ -542,6 +575,14 @@ FloatValue::FloatValue()
// @@protoc_insertion_point(constructor:google.protobuf.FloatValue)
}
+FloatValue::FloatValue(::google::protobuf::Arena* arena)
+ : ::google::protobuf::Message(),
+ _internal_metadata_(arena) {
+ SharedCtor();
+ RegisterArenaDtor(arena);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.FloatValue)
+}
+
void FloatValue::InitAsDefaultInstance() {
_is_default_instance_ = true;
}
@@ -566,10 +607,20 @@ FloatValue::~FloatValue() {
}
void FloatValue::SharedDtor() {
+ if (GetArenaNoVirtual() != NULL) {
+ return;
+ }
+
if (this != default_instance_) {
}
}
+void FloatValue::ArenaDtor(void* object) {
+ FloatValue* _this = reinterpret_cast< FloatValue* >(object);
+ (void)_this;
+}
+void FloatValue::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+}
void FloatValue::SetCachedSize(int size) const {
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
_cached_size_ = size;
@@ -588,20 +639,17 @@ const FloatValue& FloatValue::default_instance() {
FloatValue* FloatValue::default_instance_ = NULL;
FloatValue* FloatValue::New(::google::protobuf::Arena* arena) const {
- FloatValue* n = new FloatValue;
- if (arena != NULL) {
- arena->Own(n);
- }
- return n;
+ return ::google::protobuf::Arena::CreateMessage<FloatValue>(arena);
}
void FloatValue::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.FloatValue)
value_ = 0;
}
bool FloatValue::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.FloatValue)
for (;;) {
@@ -655,8 +703,8 @@ void FloatValue::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.FloatValue)
}
-::google::protobuf::uint8* FloatValue::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* FloatValue::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FloatValue)
// optional float value = 1;
if (this->value() != 0) {
@@ -668,6 +716,7 @@ void FloatValue::SerializeWithCachedSizes(
}
int FloatValue::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.FloatValue)
int total_size = 0;
// optional float value = 1;
@@ -682,31 +731,41 @@ int FloatValue::ByteSize() const {
}
void FloatValue::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.FloatValue)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const FloatValue* source =
::google::protobuf::internal::DynamicCastToGenerated<const FloatValue>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.FloatValue)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.FloatValue)
MergeFrom(*source);
}
}
void FloatValue::MergeFrom(const FloatValue& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FloatValue)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from.value() != 0) {
set_value(from.value());
}
}
void FloatValue::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.FloatValue)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void FloatValue::CopyFrom(const FloatValue& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.FloatValue)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -719,6 +778,18 @@ bool FloatValue::IsInitialized() const {
void FloatValue::Swap(FloatValue* other) {
if (other == this) return;
+ if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
+ InternalSwap(other);
+ } else {
+ FloatValue temp;
+ temp.MergeFrom(*this);
+ CopyFrom(*other);
+ other->CopyFrom(temp);
+ }
+}
+void FloatValue::UnsafeArenaSwap(FloatValue* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
void FloatValue::InternalSwap(FloatValue* other) {
@@ -766,6 +837,14 @@ Int64Value::Int64Value()
// @@protoc_insertion_point(constructor:google.protobuf.Int64Value)
}
+Int64Value::Int64Value(::google::protobuf::Arena* arena)
+ : ::google::protobuf::Message(),
+ _internal_metadata_(arena) {
+ SharedCtor();
+ RegisterArenaDtor(arena);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.Int64Value)
+}
+
void Int64Value::InitAsDefaultInstance() {
_is_default_instance_ = true;
}
@@ -790,10 +869,20 @@ Int64Value::~Int64Value() {
}
void Int64Value::SharedDtor() {
+ if (GetArenaNoVirtual() != NULL) {
+ return;
+ }
+
if (this != default_instance_) {
}
}
+void Int64Value::ArenaDtor(void* object) {
+ Int64Value* _this = reinterpret_cast< Int64Value* >(object);
+ (void)_this;
+}
+void Int64Value::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+}
void Int64Value::SetCachedSize(int size) const {
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
_cached_size_ = size;
@@ -812,20 +901,17 @@ const Int64Value& Int64Value::default_instance() {
Int64Value* Int64Value::default_instance_ = NULL;
Int64Value* Int64Value::New(::google::protobuf::Arena* arena) const {
- Int64Value* n = new Int64Value;
- if (arena != NULL) {
- arena->Own(n);
- }
- return n;
+ return ::google::protobuf::Arena::CreateMessage<Int64Value>(arena);
}
void Int64Value::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.Int64Value)
value_ = GOOGLE_LONGLONG(0);
}
bool Int64Value::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.Int64Value)
for (;;) {
@@ -879,8 +965,8 @@ void Int64Value::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.Int64Value)
}
-::google::protobuf::uint8* Int64Value::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* Int64Value::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Int64Value)
// optional int64 value = 1;
if (this->value() != 0) {
@@ -892,6 +978,7 @@ void Int64Value::SerializeWithCachedSizes(
}
int Int64Value::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Int64Value)
int total_size = 0;
// optional int64 value = 1;
@@ -908,31 +995,41 @@ int Int64Value::ByteSize() const {
}
void Int64Value::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Int64Value)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const Int64Value* source =
::google::protobuf::internal::DynamicCastToGenerated<const Int64Value>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.Int64Value)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.Int64Value)
MergeFrom(*source);
}
}
void Int64Value::MergeFrom(const Int64Value& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Int64Value)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from.value() != 0) {
set_value(from.value());
}
}
void Int64Value::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.Int64Value)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void Int64Value::CopyFrom(const Int64Value& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Int64Value)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -945,6 +1042,18 @@ bool Int64Value::IsInitialized() const {
void Int64Value::Swap(Int64Value* other) {
if (other == this) return;
+ if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
+ InternalSwap(other);
+ } else {
+ Int64Value temp;
+ temp.MergeFrom(*this);
+ CopyFrom(*other);
+ other->CopyFrom(temp);
+ }
+}
+void Int64Value::UnsafeArenaSwap(Int64Value* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
void Int64Value::InternalSwap(Int64Value* other) {
@@ -992,6 +1101,14 @@ UInt64Value::UInt64Value()
// @@protoc_insertion_point(constructor:google.protobuf.UInt64Value)
}
+UInt64Value::UInt64Value(::google::protobuf::Arena* arena)
+ : ::google::protobuf::Message(),
+ _internal_metadata_(arena) {
+ SharedCtor();
+ RegisterArenaDtor(arena);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.UInt64Value)
+}
+
void UInt64Value::InitAsDefaultInstance() {
_is_default_instance_ = true;
}
@@ -1016,10 +1133,20 @@ UInt64Value::~UInt64Value() {
}
void UInt64Value::SharedDtor() {
+ if (GetArenaNoVirtual() != NULL) {
+ return;
+ }
+
if (this != default_instance_) {
}
}
+void UInt64Value::ArenaDtor(void* object) {
+ UInt64Value* _this = reinterpret_cast< UInt64Value* >(object);
+ (void)_this;
+}
+void UInt64Value::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+}
void UInt64Value::SetCachedSize(int size) const {
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
_cached_size_ = size;
@@ -1038,20 +1165,17 @@ const UInt64Value& UInt64Value::default_instance() {
UInt64Value* UInt64Value::default_instance_ = NULL;
UInt64Value* UInt64Value::New(::google::protobuf::Arena* arena) const {
- UInt64Value* n = new UInt64Value;
- if (arena != NULL) {
- arena->Own(n);
- }
- return n;
+ return ::google::protobuf::Arena::CreateMessage<UInt64Value>(arena);
}
void UInt64Value::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.UInt64Value)
value_ = GOOGLE_ULONGLONG(0);
}
bool UInt64Value::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.UInt64Value)
for (;;) {
@@ -1105,8 +1229,8 @@ void UInt64Value::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.UInt64Value)
}
-::google::protobuf::uint8* UInt64Value::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* UInt64Value::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.UInt64Value)
// optional uint64 value = 1;
if (this->value() != 0) {
@@ -1118,6 +1242,7 @@ void UInt64Value::SerializeWithCachedSizes(
}
int UInt64Value::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.UInt64Value)
int total_size = 0;
// optional uint64 value = 1;
@@ -1134,31 +1259,41 @@ int UInt64Value::ByteSize() const {
}
void UInt64Value::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.UInt64Value)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const UInt64Value* source =
::google::protobuf::internal::DynamicCastToGenerated<const UInt64Value>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.UInt64Value)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.UInt64Value)
MergeFrom(*source);
}
}
void UInt64Value::MergeFrom(const UInt64Value& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.UInt64Value)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from.value() != 0) {
set_value(from.value());
}
}
void UInt64Value::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.UInt64Value)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void UInt64Value::CopyFrom(const UInt64Value& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.UInt64Value)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -1171,6 +1306,18 @@ bool UInt64Value::IsInitialized() const {
void UInt64Value::Swap(UInt64Value* other) {
if (other == this) return;
+ if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
+ InternalSwap(other);
+ } else {
+ UInt64Value temp;
+ temp.MergeFrom(*this);
+ CopyFrom(*other);
+ other->CopyFrom(temp);
+ }
+}
+void UInt64Value::UnsafeArenaSwap(UInt64Value* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
void UInt64Value::InternalSwap(UInt64Value* other) {
@@ -1218,6 +1365,14 @@ Int32Value::Int32Value()
// @@protoc_insertion_point(constructor:google.protobuf.Int32Value)
}
+Int32Value::Int32Value(::google::protobuf::Arena* arena)
+ : ::google::protobuf::Message(),
+ _internal_metadata_(arena) {
+ SharedCtor();
+ RegisterArenaDtor(arena);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.Int32Value)
+}
+
void Int32Value::InitAsDefaultInstance() {
_is_default_instance_ = true;
}
@@ -1242,10 +1397,20 @@ Int32Value::~Int32Value() {
}
void Int32Value::SharedDtor() {
+ if (GetArenaNoVirtual() != NULL) {
+ return;
+ }
+
if (this != default_instance_) {
}
}
+void Int32Value::ArenaDtor(void* object) {
+ Int32Value* _this = reinterpret_cast< Int32Value* >(object);
+ (void)_this;
+}
+void Int32Value::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+}
void Int32Value::SetCachedSize(int size) const {
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
_cached_size_ = size;
@@ -1264,20 +1429,17 @@ const Int32Value& Int32Value::default_instance() {
Int32Value* Int32Value::default_instance_ = NULL;
Int32Value* Int32Value::New(::google::protobuf::Arena* arena) const {
- Int32Value* n = new Int32Value;
- if (arena != NULL) {
- arena->Own(n);
- }
- return n;
+ return ::google::protobuf::Arena::CreateMessage<Int32Value>(arena);
}
void Int32Value::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.Int32Value)
value_ = 0;
}
bool Int32Value::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.Int32Value)
for (;;) {
@@ -1331,8 +1493,8 @@ void Int32Value::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.Int32Value)
}
-::google::protobuf::uint8* Int32Value::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* Int32Value::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Int32Value)
// optional int32 value = 1;
if (this->value() != 0) {
@@ -1344,6 +1506,7 @@ void Int32Value::SerializeWithCachedSizes(
}
int Int32Value::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.Int32Value)
int total_size = 0;
// optional int32 value = 1;
@@ -1360,31 +1523,41 @@ int Int32Value::ByteSize() const {
}
void Int32Value::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Int32Value)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const Int32Value* source =
::google::protobuf::internal::DynamicCastToGenerated<const Int32Value>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.Int32Value)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.Int32Value)
MergeFrom(*source);
}
}
void Int32Value::MergeFrom(const Int32Value& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Int32Value)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from.value() != 0) {
set_value(from.value());
}
}
void Int32Value::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.Int32Value)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void Int32Value::CopyFrom(const Int32Value& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.Int32Value)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -1397,6 +1570,18 @@ bool Int32Value::IsInitialized() const {
void Int32Value::Swap(Int32Value* other) {
if (other == this) return;
+ if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
+ InternalSwap(other);
+ } else {
+ Int32Value temp;
+ temp.MergeFrom(*this);
+ CopyFrom(*other);
+ other->CopyFrom(temp);
+ }
+}
+void Int32Value::UnsafeArenaSwap(Int32Value* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
void Int32Value::InternalSwap(Int32Value* other) {
@@ -1444,6 +1629,14 @@ UInt32Value::UInt32Value()
// @@protoc_insertion_point(constructor:google.protobuf.UInt32Value)
}
+UInt32Value::UInt32Value(::google::protobuf::Arena* arena)
+ : ::google::protobuf::Message(),
+ _internal_metadata_(arena) {
+ SharedCtor();
+ RegisterArenaDtor(arena);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.UInt32Value)
+}
+
void UInt32Value::InitAsDefaultInstance() {
_is_default_instance_ = true;
}
@@ -1468,10 +1661,20 @@ UInt32Value::~UInt32Value() {
}
void UInt32Value::SharedDtor() {
+ if (GetArenaNoVirtual() != NULL) {
+ return;
+ }
+
if (this != default_instance_) {
}
}
+void UInt32Value::ArenaDtor(void* object) {
+ UInt32Value* _this = reinterpret_cast< UInt32Value* >(object);
+ (void)_this;
+}
+void UInt32Value::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+}
void UInt32Value::SetCachedSize(int size) const {
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
_cached_size_ = size;
@@ -1490,20 +1693,17 @@ const UInt32Value& UInt32Value::default_instance() {
UInt32Value* UInt32Value::default_instance_ = NULL;
UInt32Value* UInt32Value::New(::google::protobuf::Arena* arena) const {
- UInt32Value* n = new UInt32Value;
- if (arena != NULL) {
- arena->Own(n);
- }
- return n;
+ return ::google::protobuf::Arena::CreateMessage<UInt32Value>(arena);
}
void UInt32Value::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.UInt32Value)
value_ = 0u;
}
bool UInt32Value::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.UInt32Value)
for (;;) {
@@ -1557,8 +1757,8 @@ void UInt32Value::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.UInt32Value)
}
-::google::protobuf::uint8* UInt32Value::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* UInt32Value::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.UInt32Value)
// optional uint32 value = 1;
if (this->value() != 0) {
@@ -1570,6 +1770,7 @@ void UInt32Value::SerializeWithCachedSizes(
}
int UInt32Value::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.UInt32Value)
int total_size = 0;
// optional uint32 value = 1;
@@ -1586,31 +1787,41 @@ int UInt32Value::ByteSize() const {
}
void UInt32Value::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.UInt32Value)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const UInt32Value* source =
::google::protobuf::internal::DynamicCastToGenerated<const UInt32Value>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.UInt32Value)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.UInt32Value)
MergeFrom(*source);
}
}
void UInt32Value::MergeFrom(const UInt32Value& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.UInt32Value)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from.value() != 0) {
set_value(from.value());
}
}
void UInt32Value::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.UInt32Value)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void UInt32Value::CopyFrom(const UInt32Value& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.UInt32Value)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -1623,6 +1834,18 @@ bool UInt32Value::IsInitialized() const {
void UInt32Value::Swap(UInt32Value* other) {
if (other == this) return;
+ if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
+ InternalSwap(other);
+ } else {
+ UInt32Value temp;
+ temp.MergeFrom(*this);
+ CopyFrom(*other);
+ other->CopyFrom(temp);
+ }
+}
+void UInt32Value::UnsafeArenaSwap(UInt32Value* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
void UInt32Value::InternalSwap(UInt32Value* other) {
@@ -1670,6 +1893,14 @@ BoolValue::BoolValue()
// @@protoc_insertion_point(constructor:google.protobuf.BoolValue)
}
+BoolValue::BoolValue(::google::protobuf::Arena* arena)
+ : ::google::protobuf::Message(),
+ _internal_metadata_(arena) {
+ SharedCtor();
+ RegisterArenaDtor(arena);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.BoolValue)
+}
+
void BoolValue::InitAsDefaultInstance() {
_is_default_instance_ = true;
}
@@ -1694,10 +1925,20 @@ BoolValue::~BoolValue() {
}
void BoolValue::SharedDtor() {
+ if (GetArenaNoVirtual() != NULL) {
+ return;
+ }
+
if (this != default_instance_) {
}
}
+void BoolValue::ArenaDtor(void* object) {
+ BoolValue* _this = reinterpret_cast< BoolValue* >(object);
+ (void)_this;
+}
+void BoolValue::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+}
void BoolValue::SetCachedSize(int size) const {
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
_cached_size_ = size;
@@ -1716,20 +1957,17 @@ const BoolValue& BoolValue::default_instance() {
BoolValue* BoolValue::default_instance_ = NULL;
BoolValue* BoolValue::New(::google::protobuf::Arena* arena) const {
- BoolValue* n = new BoolValue;
- if (arena != NULL) {
- arena->Own(n);
- }
- return n;
+ return ::google::protobuf::Arena::CreateMessage<BoolValue>(arena);
}
void BoolValue::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.BoolValue)
value_ = false;
}
bool BoolValue::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.BoolValue)
for (;;) {
@@ -1783,8 +2021,8 @@ void BoolValue::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.BoolValue)
}
-::google::protobuf::uint8* BoolValue::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* BoolValue::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.BoolValue)
// optional bool value = 1;
if (this->value() != 0) {
@@ -1796,6 +2034,7 @@ void BoolValue::SerializeWithCachedSizes(
}
int BoolValue::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.BoolValue)
int total_size = 0;
// optional bool value = 1;
@@ -1810,31 +2049,41 @@ int BoolValue::ByteSize() const {
}
void BoolValue::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.BoolValue)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const BoolValue* source =
::google::protobuf::internal::DynamicCastToGenerated<const BoolValue>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.BoolValue)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.BoolValue)
MergeFrom(*source);
}
}
void BoolValue::MergeFrom(const BoolValue& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.BoolValue)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from.value() != 0) {
set_value(from.value());
}
}
void BoolValue::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.BoolValue)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void BoolValue::CopyFrom(const BoolValue& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.BoolValue)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -1847,6 +2096,18 @@ bool BoolValue::IsInitialized() const {
void BoolValue::Swap(BoolValue* other) {
if (other == this) return;
+ if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
+ InternalSwap(other);
+ } else {
+ BoolValue temp;
+ temp.MergeFrom(*this);
+ CopyFrom(*other);
+ other->CopyFrom(temp);
+ }
+}
+void BoolValue::UnsafeArenaSwap(BoolValue* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
void BoolValue::InternalSwap(BoolValue* other) {
@@ -1894,6 +2155,14 @@ StringValue::StringValue()
// @@protoc_insertion_point(constructor:google.protobuf.StringValue)
}
+StringValue::StringValue(::google::protobuf::Arena* arena)
+ : ::google::protobuf::Message(),
+ _internal_metadata_(arena) {
+ SharedCtor();
+ RegisterArenaDtor(arena);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.StringValue)
+}
+
void StringValue::InitAsDefaultInstance() {
_is_default_instance_ = true;
}
@@ -1919,11 +2188,21 @@ StringValue::~StringValue() {
}
void StringValue::SharedDtor() {
- value_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ if (GetArenaNoVirtual() != NULL) {
+ return;
+ }
+
+ value_.Destroy(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
if (this != default_instance_) {
}
}
+void StringValue::ArenaDtor(void* object) {
+ StringValue* _this = reinterpret_cast< StringValue* >(object);
+ (void)_this;
+}
+void StringValue::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+}
void StringValue::SetCachedSize(int size) const {
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
_cached_size_ = size;
@@ -1942,20 +2221,17 @@ const StringValue& StringValue::default_instance() {
StringValue* StringValue::default_instance_ = NULL;
StringValue* StringValue::New(::google::protobuf::Arena* arena) const {
- StringValue* n = new StringValue;
- if (arena != NULL) {
- arena->Own(n);
- }
- return n;
+ return ::google::protobuf::Arena::CreateMessage<StringValue>(arena);
}
void StringValue::Clear() {
- value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+// @@protoc_insertion_point(message_clear_start:google.protobuf.StringValue)
+ value_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
}
bool StringValue::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.StringValue)
for (;;) {
@@ -2016,8 +2292,8 @@ void StringValue::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.StringValue)
}
-::google::protobuf::uint8* StringValue::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* StringValue::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.StringValue)
// optional string value = 1;
if (this->value().size() > 0) {
@@ -2035,6 +2311,7 @@ void StringValue::SerializeWithCachedSizes(
}
int StringValue::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.StringValue)
int total_size = 0;
// optional string value = 1;
@@ -2051,32 +2328,41 @@ int StringValue::ByteSize() const {
}
void StringValue::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.StringValue)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const StringValue* source =
::google::protobuf::internal::DynamicCastToGenerated<const StringValue>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.StringValue)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.StringValue)
MergeFrom(*source);
}
}
void StringValue::MergeFrom(const StringValue& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.StringValue)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from.value().size() > 0) {
-
- value_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.value_);
+ set_value(from.value());
}
}
void StringValue::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.StringValue)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void StringValue::CopyFrom(const StringValue& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.StringValue)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -2089,6 +2375,18 @@ bool StringValue::IsInitialized() const {
void StringValue::Swap(StringValue* other) {
if (other == this) return;
+ if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
+ InternalSwap(other);
+ } else {
+ StringValue temp;
+ temp.MergeFrom(*this);
+ CopyFrom(*other);
+ other->CopyFrom(temp);
+ }
+}
+void StringValue::UnsafeArenaSwap(StringValue* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
void StringValue::InternalSwap(StringValue* other) {
@@ -2110,36 +2408,46 @@ void StringValue::InternalSwap(StringValue* other) {
// optional string value = 1;
void StringValue::clear_value() {
- value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ value_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
}
const ::std::string& StringValue::value() const {
// @@protoc_insertion_point(field_get:google.protobuf.StringValue.value)
- return value_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ return value_.Get(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
void StringValue::set_value(const ::std::string& value) {
- value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+ value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
// @@protoc_insertion_point(field_set:google.protobuf.StringValue.value)
}
void StringValue::set_value(const char* value) {
- value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+ value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
+ GetArenaNoVirtual());
// @@protoc_insertion_point(field_set_char:google.protobuf.StringValue.value)
}
- void StringValue::set_value(const char* value, size_t size) {
+ void StringValue::set_value(const char* value,
+ size_t size) {
- value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
- ::std::string(reinterpret_cast<const char*>(value), size));
+ value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
+ reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
// @@protoc_insertion_point(field_set_pointer:google.protobuf.StringValue.value)
}
::std::string* StringValue::mutable_value() {
// @@protoc_insertion_point(field_mutable:google.protobuf.StringValue.value)
- return value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ return value_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
}
::std::string* StringValue::release_value() {
+ // @@protoc_insertion_point(field_release:google.protobuf.StringValue.value)
- return value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ return value_.Release(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
+}
+ ::std::string* StringValue::unsafe_arena_release_value() {
+ // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.StringValue.value)
+ GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
+
+ return value_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+ GetArenaNoVirtual());
}
void StringValue::set_allocated_value(::std::string* value) {
if (value != NULL) {
@@ -2147,9 +2455,22 @@ void StringValue::clear_value() {
} else {
}
- value_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+ value_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value,
+ GetArenaNoVirtual());
// @@protoc_insertion_point(field_set_allocated:google.protobuf.StringValue.value)
}
+ void StringValue::unsafe_arena_set_allocated_value(
+ ::std::string* value) {
+ GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
+ if (value != NULL) {
+
+ } else {
+
+ }
+ value_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+ value, GetArenaNoVirtual());
+ // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.StringValue.value)
+}
#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -2165,6 +2486,14 @@ BytesValue::BytesValue()
// @@protoc_insertion_point(constructor:google.protobuf.BytesValue)
}
+BytesValue::BytesValue(::google::protobuf::Arena* arena)
+ : ::google::protobuf::Message(),
+ _internal_metadata_(arena) {
+ SharedCtor();
+ RegisterArenaDtor(arena);
+ // @@protoc_insertion_point(arena_constructor:google.protobuf.BytesValue)
+}
+
void BytesValue::InitAsDefaultInstance() {
_is_default_instance_ = true;
}
@@ -2190,11 +2519,21 @@ BytesValue::~BytesValue() {
}
void BytesValue::SharedDtor() {
- value_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ if (GetArenaNoVirtual() != NULL) {
+ return;
+ }
+
+ value_.Destroy(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
if (this != default_instance_) {
}
}
+void BytesValue::ArenaDtor(void* object) {
+ BytesValue* _this = reinterpret_cast< BytesValue* >(object);
+ (void)_this;
+}
+void BytesValue::RegisterArenaDtor(::google::protobuf::Arena* arena) {
+}
void BytesValue::SetCachedSize(int size) const {
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
_cached_size_ = size;
@@ -2213,20 +2552,17 @@ const BytesValue& BytesValue::default_instance() {
BytesValue* BytesValue::default_instance_ = NULL;
BytesValue* BytesValue::New(::google::protobuf::Arena* arena) const {
- BytesValue* n = new BytesValue;
- if (arena != NULL) {
- arena->Own(n);
- }
- return n;
+ return ::google::protobuf::Arena::CreateMessage<BytesValue>(arena);
}
void BytesValue::Clear() {
- value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+// @@protoc_insertion_point(message_clear_start:google.protobuf.BytesValue)
+ value_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
}
bool BytesValue::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
-#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
::google::protobuf::uint32 tag;
// @@protoc_insertion_point(parse_start:google.protobuf.BytesValue)
for (;;) {
@@ -2279,8 +2615,8 @@ void BytesValue::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_end:google.protobuf.BytesValue)
}
-::google::protobuf::uint8* BytesValue::SerializeWithCachedSizesToArray(
- ::google::protobuf::uint8* target) const {
+::google::protobuf::uint8* BytesValue::InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.BytesValue)
// optional bytes value = 1;
if (this->value().size() > 0) {
@@ -2294,6 +2630,7 @@ void BytesValue::SerializeWithCachedSizes(
}
int BytesValue::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.BytesValue)
int total_size = 0;
// optional bytes value = 1;
@@ -2310,32 +2647,41 @@ int BytesValue::ByteSize() const {
}
void BytesValue::MergeFrom(const ::google::protobuf::Message& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.BytesValue)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const BytesValue* source =
::google::protobuf::internal::DynamicCastToGenerated<const BytesValue>(
&from);
if (source == NULL) {
+ // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.BytesValue)
::google::protobuf::internal::ReflectionOps::Merge(from, this);
} else {
+ // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.BytesValue)
MergeFrom(*source);
}
}
void BytesValue::MergeFrom(const BytesValue& from) {
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.BytesValue)
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from.value().size() > 0) {
-
- value_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.value_);
+ set_value(from.value());
}
}
void BytesValue::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.BytesValue)
if (&from == this) return;
Clear();
MergeFrom(from);
}
void BytesValue::CopyFrom(const BytesValue& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.BytesValue)
if (&from == this) return;
Clear();
MergeFrom(from);
@@ -2348,6 +2694,18 @@ bool BytesValue::IsInitialized() const {
void BytesValue::Swap(BytesValue* other) {
if (other == this) return;
+ if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
+ InternalSwap(other);
+ } else {
+ BytesValue temp;
+ temp.MergeFrom(*this);
+ CopyFrom(*other);
+ other->CopyFrom(temp);
+ }
+}
+void BytesValue::UnsafeArenaSwap(BytesValue* other) {
+ if (other == this) return;
+ GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual());
InternalSwap(other);
}
void BytesValue::InternalSwap(BytesValue* other) {
@@ -2369,36 +2727,46 @@ void BytesValue::InternalSwap(BytesValue* other) {
// optional bytes value = 1;
void BytesValue::clear_value() {
- value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ value_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
}
const ::std::string& BytesValue::value() const {
// @@protoc_insertion_point(field_get:google.protobuf.BytesValue.value)
- return value_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ return value_.Get(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
void BytesValue::set_value(const ::std::string& value) {
- value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+ value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
// @@protoc_insertion_point(field_set:google.protobuf.BytesValue.value)
}
void BytesValue::set_value(const char* value) {
- value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+ value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
+ GetArenaNoVirtual());
// @@protoc_insertion_point(field_set_char:google.protobuf.BytesValue.value)
}
- void BytesValue::set_value(const void* value, size_t size) {
+ void BytesValue::set_value(const void* value,
+ size_t size) {
- value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
- ::std::string(reinterpret_cast<const char*>(value), size));
+ value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
+ reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
// @@protoc_insertion_point(field_set_pointer:google.protobuf.BytesValue.value)
}
::std::string* BytesValue::mutable_value() {
// @@protoc_insertion_point(field_mutable:google.protobuf.BytesValue.value)
- return value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ return value_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
}
::std::string* BytesValue::release_value() {
+ // @@protoc_insertion_point(field_release:google.protobuf.BytesValue.value)
- return value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ return value_.Release(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
+}
+ ::std::string* BytesValue::unsafe_arena_release_value() {
+ // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.BytesValue.value)
+ GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
+
+ return value_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+ GetArenaNoVirtual());
}
void BytesValue::set_allocated_value(::std::string* value) {
if (value != NULL) {
@@ -2406,9 +2774,22 @@ void BytesValue::clear_value() {
} else {
}
- value_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+ value_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value,
+ GetArenaNoVirtual());
// @@protoc_insertion_point(field_set_allocated:google.protobuf.BytesValue.value)
}
+ void BytesValue::unsafe_arena_set_allocated_value(
+ ::std::string* value) {
+ GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
+ if (value != NULL) {
+
+ } else {
+
+ }
+ value_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+ value, GetArenaNoVirtual());
+ // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.BytesValue.value)
+}
#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
diff --git a/src/google/protobuf/wrappers.pb.h b/src/google/protobuf/wrappers.pb.h
index 15bcc7a2..73f8ff62 100644
--- a/src/google/protobuf/wrappers.pb.h
+++ b/src/google/protobuf/wrappers.pb.h
@@ -49,7 +49,7 @@ class UInt64Value;
// ===================================================================
-class LIBPROTOBUF_EXPORT DoubleValue : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT DoubleValue : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.DoubleValue) */ {
public:
DoubleValue();
virtual ~DoubleValue();
@@ -61,9 +61,14 @@ class LIBPROTOBUF_EXPORT DoubleValue : public ::google::protobuf::Message {
return *this;
}
+ inline ::google::protobuf::Arena* GetArena() const { return GetArenaNoVirtual(); }
+ inline void* GetMaybeArenaPointer() const {
+ return MaybeArenaPtr();
+ }
static const ::google::protobuf::Descriptor* descriptor();
static const DoubleValue& default_instance();
+ void UnsafeArenaSwap(DoubleValue* other);
void Swap(DoubleValue* other);
// implements Message ----------------------------------------------
@@ -83,13 +88,22 @@ class LIBPROTOBUF_EXPORT DoubleValue : public ::google::protobuf::Message {
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
void SharedDtor();
void SetCachedSize(int size) const;
void InternalSwap(DoubleValue* other);
+ protected:
+ explicit DoubleValue(::google::protobuf::Arena* arena);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::google::protobuf::Arena* arena);
private:
inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
return _internal_metadata_.arena();
@@ -115,6 +129,9 @@ class LIBPROTOBUF_EXPORT DoubleValue : public ::google::protobuf::Message {
private:
::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+ friend class ::google::protobuf::Arena;
+ typedef void InternalArenaConstructable_;
+ typedef void DestructorSkippable_;
bool _is_default_instance_;
double value_;
mutable int _cached_size_;
@@ -127,7 +144,7 @@ class LIBPROTOBUF_EXPORT DoubleValue : public ::google::protobuf::Message {
};
// -------------------------------------------------------------------
-class LIBPROTOBUF_EXPORT FloatValue : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT FloatValue : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FloatValue) */ {
public:
FloatValue();
virtual ~FloatValue();
@@ -139,9 +156,14 @@ class LIBPROTOBUF_EXPORT FloatValue : public ::google::protobuf::Message {
return *this;
}
+ inline ::google::protobuf::Arena* GetArena() const { return GetArenaNoVirtual(); }
+ inline void* GetMaybeArenaPointer() const {
+ return MaybeArenaPtr();
+ }
static const ::google::protobuf::Descriptor* descriptor();
static const FloatValue& default_instance();
+ void UnsafeArenaSwap(FloatValue* other);
void Swap(FloatValue* other);
// implements Message ----------------------------------------------
@@ -161,13 +183,22 @@ class LIBPROTOBUF_EXPORT FloatValue : public ::google::protobuf::Message {
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
void SharedDtor();
void SetCachedSize(int size) const;
void InternalSwap(FloatValue* other);
+ protected:
+ explicit FloatValue(::google::protobuf::Arena* arena);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::google::protobuf::Arena* arena);
private:
inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
return _internal_metadata_.arena();
@@ -193,6 +224,9 @@ class LIBPROTOBUF_EXPORT FloatValue : public ::google::protobuf::Message {
private:
::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+ friend class ::google::protobuf::Arena;
+ typedef void InternalArenaConstructable_;
+ typedef void DestructorSkippable_;
bool _is_default_instance_;
float value_;
mutable int _cached_size_;
@@ -205,7 +239,7 @@ class LIBPROTOBUF_EXPORT FloatValue : public ::google::protobuf::Message {
};
// -------------------------------------------------------------------
-class LIBPROTOBUF_EXPORT Int64Value : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT Int64Value : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Int64Value) */ {
public:
Int64Value();
virtual ~Int64Value();
@@ -217,9 +251,14 @@ class LIBPROTOBUF_EXPORT Int64Value : public ::google::protobuf::Message {
return *this;
}
+ inline ::google::protobuf::Arena* GetArena() const { return GetArenaNoVirtual(); }
+ inline void* GetMaybeArenaPointer() const {
+ return MaybeArenaPtr();
+ }
static const ::google::protobuf::Descriptor* descriptor();
static const Int64Value& default_instance();
+ void UnsafeArenaSwap(Int64Value* other);
void Swap(Int64Value* other);
// implements Message ----------------------------------------------
@@ -239,13 +278,22 @@ class LIBPROTOBUF_EXPORT Int64Value : public ::google::protobuf::Message {
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
void SharedDtor();
void SetCachedSize(int size) const;
void InternalSwap(Int64Value* other);
+ protected:
+ explicit Int64Value(::google::protobuf::Arena* arena);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::google::protobuf::Arena* arena);
private:
inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
return _internal_metadata_.arena();
@@ -271,6 +319,9 @@ class LIBPROTOBUF_EXPORT Int64Value : public ::google::protobuf::Message {
private:
::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+ friend class ::google::protobuf::Arena;
+ typedef void InternalArenaConstructable_;
+ typedef void DestructorSkippable_;
bool _is_default_instance_;
::google::protobuf::int64 value_;
mutable int _cached_size_;
@@ -283,7 +334,7 @@ class LIBPROTOBUF_EXPORT Int64Value : public ::google::protobuf::Message {
};
// -------------------------------------------------------------------
-class LIBPROTOBUF_EXPORT UInt64Value : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT UInt64Value : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.UInt64Value) */ {
public:
UInt64Value();
virtual ~UInt64Value();
@@ -295,9 +346,14 @@ class LIBPROTOBUF_EXPORT UInt64Value : public ::google::protobuf::Message {
return *this;
}
+ inline ::google::protobuf::Arena* GetArena() const { return GetArenaNoVirtual(); }
+ inline void* GetMaybeArenaPointer() const {
+ return MaybeArenaPtr();
+ }
static const ::google::protobuf::Descriptor* descriptor();
static const UInt64Value& default_instance();
+ void UnsafeArenaSwap(UInt64Value* other);
void Swap(UInt64Value* other);
// implements Message ----------------------------------------------
@@ -317,13 +373,22 @@ class LIBPROTOBUF_EXPORT UInt64Value : public ::google::protobuf::Message {
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
void SharedDtor();
void SetCachedSize(int size) const;
void InternalSwap(UInt64Value* other);
+ protected:
+ explicit UInt64Value(::google::protobuf::Arena* arena);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::google::protobuf::Arena* arena);
private:
inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
return _internal_metadata_.arena();
@@ -349,6 +414,9 @@ class LIBPROTOBUF_EXPORT UInt64Value : public ::google::protobuf::Message {
private:
::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+ friend class ::google::protobuf::Arena;
+ typedef void InternalArenaConstructable_;
+ typedef void DestructorSkippable_;
bool _is_default_instance_;
::google::protobuf::uint64 value_;
mutable int _cached_size_;
@@ -361,7 +429,7 @@ class LIBPROTOBUF_EXPORT UInt64Value : public ::google::protobuf::Message {
};
// -------------------------------------------------------------------
-class LIBPROTOBUF_EXPORT Int32Value : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT Int32Value : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Int32Value) */ {
public:
Int32Value();
virtual ~Int32Value();
@@ -373,9 +441,14 @@ class LIBPROTOBUF_EXPORT Int32Value : public ::google::protobuf::Message {
return *this;
}
+ inline ::google::protobuf::Arena* GetArena() const { return GetArenaNoVirtual(); }
+ inline void* GetMaybeArenaPointer() const {
+ return MaybeArenaPtr();
+ }
static const ::google::protobuf::Descriptor* descriptor();
static const Int32Value& default_instance();
+ void UnsafeArenaSwap(Int32Value* other);
void Swap(Int32Value* other);
// implements Message ----------------------------------------------
@@ -395,13 +468,22 @@ class LIBPROTOBUF_EXPORT Int32Value : public ::google::protobuf::Message {
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
void SharedDtor();
void SetCachedSize(int size) const;
void InternalSwap(Int32Value* other);
+ protected:
+ explicit Int32Value(::google::protobuf::Arena* arena);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::google::protobuf::Arena* arena);
private:
inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
return _internal_metadata_.arena();
@@ -427,6 +509,9 @@ class LIBPROTOBUF_EXPORT Int32Value : public ::google::protobuf::Message {
private:
::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+ friend class ::google::protobuf::Arena;
+ typedef void InternalArenaConstructable_;
+ typedef void DestructorSkippable_;
bool _is_default_instance_;
::google::protobuf::int32 value_;
mutable int _cached_size_;
@@ -439,7 +524,7 @@ class LIBPROTOBUF_EXPORT Int32Value : public ::google::protobuf::Message {
};
// -------------------------------------------------------------------
-class LIBPROTOBUF_EXPORT UInt32Value : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT UInt32Value : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.UInt32Value) */ {
public:
UInt32Value();
virtual ~UInt32Value();
@@ -451,9 +536,14 @@ class LIBPROTOBUF_EXPORT UInt32Value : public ::google::protobuf::Message {
return *this;
}
+ inline ::google::protobuf::Arena* GetArena() const { return GetArenaNoVirtual(); }
+ inline void* GetMaybeArenaPointer() const {
+ return MaybeArenaPtr();
+ }
static const ::google::protobuf::Descriptor* descriptor();
static const UInt32Value& default_instance();
+ void UnsafeArenaSwap(UInt32Value* other);
void Swap(UInt32Value* other);
// implements Message ----------------------------------------------
@@ -473,13 +563,22 @@ class LIBPROTOBUF_EXPORT UInt32Value : public ::google::protobuf::Message {
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
void SharedDtor();
void SetCachedSize(int size) const;
void InternalSwap(UInt32Value* other);
+ protected:
+ explicit UInt32Value(::google::protobuf::Arena* arena);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::google::protobuf::Arena* arena);
private:
inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
return _internal_metadata_.arena();
@@ -505,6 +604,9 @@ class LIBPROTOBUF_EXPORT UInt32Value : public ::google::protobuf::Message {
private:
::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+ friend class ::google::protobuf::Arena;
+ typedef void InternalArenaConstructable_;
+ typedef void DestructorSkippable_;
bool _is_default_instance_;
::google::protobuf::uint32 value_;
mutable int _cached_size_;
@@ -517,7 +619,7 @@ class LIBPROTOBUF_EXPORT UInt32Value : public ::google::protobuf::Message {
};
// -------------------------------------------------------------------
-class LIBPROTOBUF_EXPORT BoolValue : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT BoolValue : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.BoolValue) */ {
public:
BoolValue();
virtual ~BoolValue();
@@ -529,9 +631,14 @@ class LIBPROTOBUF_EXPORT BoolValue : public ::google::protobuf::Message {
return *this;
}
+ inline ::google::protobuf::Arena* GetArena() const { return GetArenaNoVirtual(); }
+ inline void* GetMaybeArenaPointer() const {
+ return MaybeArenaPtr();
+ }
static const ::google::protobuf::Descriptor* descriptor();
static const BoolValue& default_instance();
+ void UnsafeArenaSwap(BoolValue* other);
void Swap(BoolValue* other);
// implements Message ----------------------------------------------
@@ -551,13 +658,22 @@ class LIBPROTOBUF_EXPORT BoolValue : public ::google::protobuf::Message {
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
void SharedDtor();
void SetCachedSize(int size) const;
void InternalSwap(BoolValue* other);
+ protected:
+ explicit BoolValue(::google::protobuf::Arena* arena);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::google::protobuf::Arena* arena);
private:
inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
return _internal_metadata_.arena();
@@ -583,6 +699,9 @@ class LIBPROTOBUF_EXPORT BoolValue : public ::google::protobuf::Message {
private:
::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+ friend class ::google::protobuf::Arena;
+ typedef void InternalArenaConstructable_;
+ typedef void DestructorSkippable_;
bool _is_default_instance_;
bool value_;
mutable int _cached_size_;
@@ -595,7 +714,7 @@ class LIBPROTOBUF_EXPORT BoolValue : public ::google::protobuf::Message {
};
// -------------------------------------------------------------------
-class LIBPROTOBUF_EXPORT StringValue : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT StringValue : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.StringValue) */ {
public:
StringValue();
virtual ~StringValue();
@@ -607,9 +726,14 @@ class LIBPROTOBUF_EXPORT StringValue : public ::google::protobuf::Message {
return *this;
}
+ inline ::google::protobuf::Arena* GetArena() const { return GetArenaNoVirtual(); }
+ inline void* GetMaybeArenaPointer() const {
+ return MaybeArenaPtr();
+ }
static const ::google::protobuf::Descriptor* descriptor();
static const StringValue& default_instance();
+ void UnsafeArenaSwap(StringValue* other);
void Swap(StringValue* other);
// implements Message ----------------------------------------------
@@ -629,13 +753,22 @@ class LIBPROTOBUF_EXPORT StringValue : public ::google::protobuf::Message {
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
void SharedDtor();
void SetCachedSize(int size) const;
void InternalSwap(StringValue* other);
+ protected:
+ explicit StringValue(::google::protobuf::Arena* arena);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::google::protobuf::Arena* arena);
private:
inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
return _internal_metadata_.arena();
@@ -661,11 +794,17 @@ class LIBPROTOBUF_EXPORT StringValue : public ::google::protobuf::Message {
::std::string* mutable_value();
::std::string* release_value();
void set_allocated_value(::std::string* value);
+ ::std::string* unsafe_arena_release_value();
+ void unsafe_arena_set_allocated_value(
+ ::std::string* value);
// @@protoc_insertion_point(class_scope:google.protobuf.StringValue)
private:
::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+ friend class ::google::protobuf::Arena;
+ typedef void InternalArenaConstructable_;
+ typedef void DestructorSkippable_;
bool _is_default_instance_;
::google::protobuf::internal::ArenaStringPtr value_;
mutable int _cached_size_;
@@ -678,7 +817,7 @@ class LIBPROTOBUF_EXPORT StringValue : public ::google::protobuf::Message {
};
// -------------------------------------------------------------------
-class LIBPROTOBUF_EXPORT BytesValue : public ::google::protobuf::Message {
+class LIBPROTOBUF_EXPORT BytesValue : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.BytesValue) */ {
public:
BytesValue();
virtual ~BytesValue();
@@ -690,9 +829,14 @@ class LIBPROTOBUF_EXPORT BytesValue : public ::google::protobuf::Message {
return *this;
}
+ inline ::google::protobuf::Arena* GetArena() const { return GetArenaNoVirtual(); }
+ inline void* GetMaybeArenaPointer() const {
+ return MaybeArenaPtr();
+ }
static const ::google::protobuf::Descriptor* descriptor();
static const BytesValue& default_instance();
+ void UnsafeArenaSwap(BytesValue* other);
void Swap(BytesValue* other);
// implements Message ----------------------------------------------
@@ -712,13 +856,22 @@ class LIBPROTOBUF_EXPORT BytesValue : public ::google::protobuf::Message {
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
- ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+ bool deterministic, ::google::protobuf::uint8* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
+ return InternalSerializeWithCachedSizesToArray(false, output);
+ }
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
void SharedDtor();
void SetCachedSize(int size) const;
void InternalSwap(BytesValue* other);
+ protected:
+ explicit BytesValue(::google::protobuf::Arena* arena);
+ private:
+ static void ArenaDtor(void* object);
+ inline void RegisterArenaDtor(::google::protobuf::Arena* arena);
private:
inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
return _internal_metadata_.arena();
@@ -744,11 +897,17 @@ class LIBPROTOBUF_EXPORT BytesValue : public ::google::protobuf::Message {
::std::string* mutable_value();
::std::string* release_value();
void set_allocated_value(::std::string* value);
+ ::std::string* unsafe_arena_release_value();
+ void unsafe_arena_set_allocated_value(
+ ::std::string* value);
// @@protoc_insertion_point(class_scope:google.protobuf.BytesValue)
private:
::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+ friend class ::google::protobuf::Arena;
+ typedef void InternalArenaConstructable_;
+ typedef void DestructorSkippable_;
bool _is_default_instance_;
::google::protobuf::internal::ArenaStringPtr value_;
mutable int _cached_size_;
@@ -895,36 +1054,46 @@ inline void BoolValue::set_value(bool value) {
// optional string value = 1;
inline void StringValue::clear_value() {
- value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ value_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
}
inline const ::std::string& StringValue::value() const {
// @@protoc_insertion_point(field_get:google.protobuf.StringValue.value)
- return value_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ return value_.Get(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void StringValue::set_value(const ::std::string& value) {
- value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+ value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
// @@protoc_insertion_point(field_set:google.protobuf.StringValue.value)
}
inline void StringValue::set_value(const char* value) {
- value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+ value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
+ GetArenaNoVirtual());
// @@protoc_insertion_point(field_set_char:google.protobuf.StringValue.value)
}
-inline void StringValue::set_value(const char* value, size_t size) {
+inline void StringValue::set_value(const char* value,
+ size_t size) {
- value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
- ::std::string(reinterpret_cast<const char*>(value), size));
+ value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
+ reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
// @@protoc_insertion_point(field_set_pointer:google.protobuf.StringValue.value)
}
inline ::std::string* StringValue::mutable_value() {
// @@protoc_insertion_point(field_mutable:google.protobuf.StringValue.value)
- return value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ return value_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
}
inline ::std::string* StringValue::release_value() {
+ // @@protoc_insertion_point(field_release:google.protobuf.StringValue.value)
- return value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ return value_.Release(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
+}
+inline ::std::string* StringValue::unsafe_arena_release_value() {
+ // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.StringValue.value)
+ GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
+
+ return value_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+ GetArenaNoVirtual());
}
inline void StringValue::set_allocated_value(::std::string* value) {
if (value != NULL) {
@@ -932,9 +1101,22 @@ inline void StringValue::set_allocated_value(::std::string* value) {
} else {
}
- value_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+ value_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value,
+ GetArenaNoVirtual());
// @@protoc_insertion_point(field_set_allocated:google.protobuf.StringValue.value)
}
+inline void StringValue::unsafe_arena_set_allocated_value(
+ ::std::string* value) {
+ GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
+ if (value != NULL) {
+
+ } else {
+
+ }
+ value_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+ value, GetArenaNoVirtual());
+ // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.StringValue.value)
+}
// -------------------------------------------------------------------
@@ -942,36 +1124,46 @@ inline void StringValue::set_allocated_value(::std::string* value) {
// optional bytes value = 1;
inline void BytesValue::clear_value() {
- value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ value_.ClearToEmpty(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
}
inline const ::std::string& BytesValue::value() const {
// @@protoc_insertion_point(field_get:google.protobuf.BytesValue.value)
- return value_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ return value_.Get(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void BytesValue::set_value(const ::std::string& value) {
- value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+ value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual());
// @@protoc_insertion_point(field_set:google.protobuf.BytesValue.value)
}
inline void BytesValue::set_value(const char* value) {
- value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+ value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value),
+ GetArenaNoVirtual());
// @@protoc_insertion_point(field_set_char:google.protobuf.BytesValue.value)
}
-inline void BytesValue::set_value(const void* value, size_t size) {
+inline void BytesValue::set_value(const void* value,
+ size_t size) {
- value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
- ::std::string(reinterpret_cast<const char*>(value), size));
+ value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
+ reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());
// @@protoc_insertion_point(field_set_pointer:google.protobuf.BytesValue.value)
}
inline ::std::string* BytesValue::mutable_value() {
// @@protoc_insertion_point(field_mutable:google.protobuf.BytesValue.value)
- return value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ return value_.Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
}
inline ::std::string* BytesValue::release_value() {
+ // @@protoc_insertion_point(field_release:google.protobuf.BytesValue.value)
- return value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ return value_.Release(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual());
+}
+inline ::std::string* BytesValue::unsafe_arena_release_value() {
+ // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.BytesValue.value)
+ GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
+
+ return value_.UnsafeArenaRelease(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+ GetArenaNoVirtual());
}
inline void BytesValue::set_allocated_value(::std::string* value) {
if (value != NULL) {
@@ -979,9 +1171,22 @@ inline void BytesValue::set_allocated_value(::std::string* value) {
} else {
}
- value_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+ value_.SetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value,
+ GetArenaNoVirtual());
// @@protoc_insertion_point(field_set_allocated:google.protobuf.BytesValue.value)
}
+inline void BytesValue::unsafe_arena_set_allocated_value(
+ ::std::string* value) {
+ GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);
+ if (value != NULL) {
+
+ } else {
+
+ }
+ value_.UnsafeArenaSetAllocated(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+ value, GetArenaNoVirtual());
+ // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.BytesValue.value)
+}
#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS
// -------------------------------------------------------------------
diff --git a/src/google/protobuf/wrappers.proto b/src/google/protobuf/wrappers.proto
index a1d6e446..4828ad9a 100644
--- a/src/google/protobuf/wrappers.proto
+++ b/src/google/protobuf/wrappers.proto
@@ -37,11 +37,13 @@ syntax = "proto3";
package google.protobuf;
-option java_generate_equals_and_hash = true;
-option java_multiple_files = true;
-option java_outer_classname = "WrappersProto";
-option java_package = "com.google.protobuf";
option csharp_namespace = "Google.Protobuf.WellKnownTypes";
+option cc_enable_arenas = true;
+option go_package = "github.com/golang/protobuf/ptypes/wrappers";
+option java_package = "com.google.protobuf";
+option java_outer_classname = "WrappersProto";
+option java_multiple_files = true;
+option java_generate_equals_and_hash = true;
option objc_class_prefix = "GPB";
// Wrapper message for `double`.
diff --git a/tests.sh b/tests.sh
new file mode 100755
index 00000000..9e95f2b7
--- /dev/null
+++ b/tests.sh
@@ -0,0 +1,371 @@
+#!/bin/bash
+#
+# Build and runs tests for the protobuf project. The tests as written here are
+# used by both Jenkins and Travis, though some specialized logic is required to
+# handle the differences between them.
+
+on_travis() {
+ if [ "$TRAVIS" == "true" ]; then
+ "$@"
+ fi
+}
+
+# For when some other test needs the C++ main build, including protoc and
+# libprotobuf.
+internal_build_cpp() {
+ if [ -f src/protoc ]; then
+ # Already built.
+ return
+ fi
+
+ if [[ $(uname -s) == "Linux" && "$TRAVIS" == "true" ]]; then
+ # Install GCC 4.8 to replace the default GCC 4.6. We need 4.8 for more
+ # decent C++ 11 support in order to compile conformance tests.
+ sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y
+ sudo apt-get update -qq
+ sudo apt-get install -qq g++-4.8
+ export CXX="g++-4.8" CC="gcc-4.8"
+ fi
+
+ ./autogen.sh
+ ./configure
+ make -j2
+}
+
+build_cpp() {
+ internal_build_cpp
+ make check -j2
+ cd conformance && make test_cpp && cd ..
+
+ # Verify benchmarking code can build successfully.
+ cd benchmarks && make && ./generate-datasets && cd ..
+}
+
+build_cpp_distcheck() {
+ ./autogen.sh
+ ./configure
+ make dist
+
+ # List all files that should be included in the distribution package.
+ git ls-files | grep "^\(java\|python\|objectivec\|csharp\|js\|ruby\|cmake\|examples\)" |\
+ grep -v ".gitignore" | grep -v "java/compatibility_tests" > dist.lst
+ # Unzip the dist tar file.
+ DIST=`ls *.tar.gz`
+ tar -xf $DIST
+ cd ${DIST//.tar.gz}
+ # Check if every file exists in the dist tar file.
+ FILES_MISSING=""
+ for FILE in $(<../dist.lst); do
+ if ! file $FILE &>/dev/null; then
+ echo "$FILE is not found!"
+ FILES_MISSING="$FILE $FILES_MISSING"
+ fi
+ done
+ cd ..
+ if [ ! -z "$FILES_MISSING" ]; then
+ echo "Missing files in EXTRA_DIST: $FILES_MISSING"
+ exit 1
+ fi
+
+ # Do the regular dist-check for C++.
+ make distcheck -j2
+}
+
+build_csharp() {
+ # Just for the conformance tests. We don't currently
+ # need to really build protoc, but it's simplest to keep with the
+ # conventions of the other builds.
+ internal_build_cpp
+ NUGET=/usr/local/bin/nuget.exe
+
+ if [ "$TRAVIS" == "true" ]; then
+ # Install latest version of Mono
+ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
+ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 1397BC53640DB551
+ echo "deb http://download.mono-project.com/repo/debian wheezy main" | sudo tee /etc/apt/sources.list.d/mono-xamarin.list
+ sudo apt-get update -qq
+ sudo apt-get install -qq mono-devel referenceassemblies-pcl nunit
+
+ # Then install the dotnet SDK as per Ubuntu 14.04 instructions on dot.net.
+ sudo sh -c 'echo "deb [arch=amd64] https://apt-mo.trafficmanager.net/repos/dotnet-release/ trusty main" > /etc/apt/sources.list.d/dotnetdev.list'
+ sudo apt-key adv --keyserver apt-mo.trafficmanager.net --recv-keys 417A0893
+ sudo apt-get update -qq
+ sudo apt-get install -qq dotnet-dev-1.0.0-preview2-003121
+ fi
+
+ # Perform "dotnet new" once to get the setup preprocessing out of the
+ # way. That spews a lot of output (including backspaces) into logs
+ # otherwise, and can cause problems. It doesn't matter if this step
+ # is performed multiple times; it's cheap after the first time anyway.
+ mkdir dotnettmp
+ (cd dotnettmp; dotnet new > /dev/null)
+ rm -rf dotnettmp
+
+ (cd csharp/src; dotnet restore)
+ csharp/buildall.sh
+ cd conformance && make test_csharp && cd ..
+}
+
+build_golang() {
+ # Go build needs `protoc`.
+ internal_build_cpp
+ # Add protoc to the path so that the examples build finds it.
+ export PATH="`pwd`/src:$PATH"
+
+ # Install Go and the Go protobuf compiler plugin.
+ on_travis sudo apt-get update -qq
+ on_travis sudo apt-get install -qq golang
+
+ export GOPATH="$HOME/gocode"
+ mkdir -p "$GOPATH/src/github.com/google"
+ rm -f "$GOPATH/src/github.com/google/protobuf"
+ ln -s "`pwd`" "$GOPATH/src/github.com/google/protobuf"
+ export PATH="$GOPATH/bin:$PATH"
+ go get github.com/golang/protobuf/protoc-gen-go
+
+ cd examples && make gotest && cd ..
+}
+
+use_java() {
+ version=$1
+ case "$version" in
+ jdk7)
+ on_travis sudo apt-get install openjdk-7-jdk
+ export PATH=/usr/lib/jvm/java-7-openjdk-amd64/bin:$PATH
+ export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64
+ ;;
+ oracle7)
+ if [ "$TRAVIS" == "true" ]; then
+ sudo apt-get install python-software-properties # for apt-add-repository
+ echo "oracle-java7-installer shared/accepted-oracle-license-v1-1 select true" | \
+ sudo debconf-set-selections
+ yes | sudo apt-add-repository ppa:webupd8team/java
+ yes | sudo apt-get install oracle-java7-installer
+ fi;
+ export PATH=/usr/lib/jvm/java-7-oracle/bin:$PATH
+ export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64
+ ;;
+ esac
+
+ if [ "$TRAVIS" != "true" ]; then
+ MAVEN_LOCAL_REPOSITORY=/var/maven_local_repository
+ MVN="$MVN -e -X --offline -Dmaven.repo.local=$MAVEN_LOCAL_REPOSITORY"
+ fi;
+
+ which java
+ java -version
+ $MVN -version
+}
+
+# --batch-mode supresses download progress output that spams the logs.
+MVN="mvn --batch-mode"
+
+build_java() {
+ version=$1
+ dir=java_$version
+ # Java build needs `protoc`.
+ internal_build_cpp
+ cp -r java $dir
+ cd $dir && $MVN clean && $MVN test
+ cd ../..
+}
+
+# The conformance tests are hard-coded to work with the $ROOT/java directory.
+# So this can't run in parallel with two different sets of tests.
+build_java_with_conformance_tests() {
+ # Java build needs `protoc`.
+ internal_build_cpp
+ cd java && $MVN test && $MVN install
+ cd util && $MVN package assembly:single
+ cd ../..
+ cd conformance && make test_java && cd ..
+}
+
+build_javanano() {
+ # Java build needs `protoc`.
+ internal_build_cpp
+ cd javanano && $MVN test && cd ..
+}
+
+build_java_jdk7() {
+ use_java jdk7
+ build_java_with_conformance_tests
+}
+build_java_oracle7() {
+ use_java oracle7
+ build_java oracle7
+}
+build_java_compatibility() {
+ use_java jdk7
+ internal_build_cpp
+ # Use the unit-tests extraced from 2.5.0 to test the compatibilty between
+ # 3.0.0-beta-4 and the current version.
+ cd java/compatibility_tests/v2.5.0
+ ./test.sh 3.0.0-beta-4
+}
+
+build_javanano_jdk7() {
+ use_java jdk7
+ build_javanano
+}
+build_javanano_oracle7() {
+ use_java oracle7
+ build_javanano
+}
+
+internal_install_python_deps() {
+ if [ "$TRAVIS" != "true" ]; then
+ return;
+ fi
+ # Install tox (OS X doesn't have pip).
+ if [ $(uname -s) == "Darwin" ]; then
+ sudo easy_install tox
+ else
+ sudo pip install tox
+ fi
+ # Only install Python2.6/3.x on Linux.
+ if [ $(uname -s) == "Linux" ]; then
+ sudo apt-get install -y python-software-properties # for apt-add-repository
+ sudo apt-add-repository -y ppa:fkrull/deadsnakes
+ sudo apt-get update -qq
+ sudo apt-get install -y python2.6 python2.6-dev
+ sudo apt-get install -y python3.3 python3.3-dev
+ sudo apt-get install -y python3.4 python3.4-dev
+ fi
+}
+
+build_objectivec_ios() {
+ # Reused the build script that takes care of configuring and ensuring things
+ # are up to date. The OS X test runs the objc conformance test, so skip it
+ # here.
+ # Note: travis has xctool installed, and we've looked at using it in the past
+ # but it has ended up proving unreliable (bugs), an they are removing build
+ # support in favor of xcbuild (or just xcodebuild).
+ objectivec/DevTools/full_mac_build.sh \
+ --core-only --skip-xcode-osx --skip-objc-conformance "$@"
+}
+
+build_objectivec_ios_debug() {
+ build_objectivec_ios --skip-xcode-release
+}
+
+build_objectivec_ios_release() {
+ build_objectivec_ios --skip-xcode-debug
+}
+
+build_objectivec_osx() {
+ # Reused the build script that takes care of configuring and ensuring things
+ # are up to date.
+ objectivec/DevTools/full_mac_build.sh \
+ --core-only --skip-xcode-ios
+}
+
+build_objectivec_cocoapods_integration() {
+ # First, load the RVM environment in bash, needed to update ruby.
+ source ~/.rvm/scripts/rvm
+ # Update rvm to the latest version. This is needed to solve
+ # https://github.com/google/protobuf/issues/1786 and may not be needed in the
+ # future when Travis updates the default version of rvm.
+ rvm get head
+ # Update ruby to 2.2.3 as the default one crashes with segmentation faults
+ # when using pod.
+ rvm use 2.2.3 --install --binary --fuzzy
+ # Update pod to the latest version.
+ gem install cocoapods --no-ri --no-rdoc
+ objectivec/Tests/CocoaPods/run_tests.sh
+}
+
+build_python() {
+ internal_build_cpp
+ internal_install_python_deps
+ cd python
+ # Only test Python 2.6/3.x on Linux
+ if [ $(uname -s) == "Linux" ]; then
+ envlist=py\{26,27,33,34\}-python
+ else
+ envlist=py27-python
+ fi
+ tox -e $envlist
+ cd ..
+}
+
+build_python_cpp() {
+ internal_build_cpp
+ internal_install_python_deps
+ export LD_LIBRARY_PATH=../src/.libs # for Linux
+ export DYLD_LIBRARY_PATH=../src/.libs # for OS X
+ cd python
+ # Only test Python 2.6/3.x on Linux
+ if [ $(uname -s) == "Linux" ]; then
+ # py26 is currently disabled due to json_format
+ envlist=py\{27,33,34\}-cpp
+ else
+ envlist=py27-cpp
+ fi
+ tox -e $envlist
+ cd ..
+}
+
+build_ruby21() {
+ internal_build_cpp # For conformance tests.
+ cd ruby && bash travis-test.sh ruby-2.1 && cd ..
+}
+build_ruby22() {
+ internal_build_cpp # For conformance tests.
+ cd ruby && bash travis-test.sh ruby-2.2 && cd ..
+}
+build_jruby() {
+ internal_build_cpp # For conformance tests.
+ # TODO(xiaofeng): Upgrade to jruby-9.x. There are some broken jests to be
+ # fixed.
+ cd ruby && bash travis-test.sh jruby-1.7 && cd ..
+}
+build_ruby_all() {
+ build_ruby21
+ build_ruby22
+ build_jruby
+}
+
+build_javascript() {
+ internal_build_cpp
+ cd js && npm install && npm test && cd ..
+}
+
+# Note: travis currently does not support testing more than one language so the
+# .travis.yml cheats and claims to only be cpp. If they add multiple language
+# support, this should probably get updated to install steps and/or
+# rvm/gemfile/jdk/etc. entries rather than manually doing the work.
+
+# .travis.yml uses matrix.exclude to block the cases where app-get can't be
+# use to install things.
+
+# -------- main --------
+
+if [ "$#" -ne 1 ]; then
+ echo "
+Usage: $0 { cpp |
+ cpp_distcheck |
+ csharp |
+ java_jdk7 |
+ java_oracle7 |
+ java_compatibility |
+ javanano_jdk7 |
+ javanano_oracle7 |
+ objectivec_ios |
+ objectivec_ios_debug |
+ objectivec_ios_release |
+ objectivec_osx |
+ objectivec_cocoapods_integration |
+ python |
+ python_cpp |
+ ruby21 |
+ ruby22 |
+ jruby |
+ ruby_all)
+"
+ exit 1
+fi
+
+set -e # exit immediately on error
+set -x # display all commands
+eval "build_$1"
diff --git a/travis.sh b/travis.sh
deleted file mode 100755
index 6295336b..00000000
--- a/travis.sh
+++ /dev/null
@@ -1,282 +0,0 @@
-#!/usr/bin/env bash
-
-# Note: travis currently does not support testing more than one language so the
-# .travis.yml cheats and claims to only be cpp. If they add multiple language
-# support, this should probably get updated to install steps and/or
-# rvm/gemfile/jdk/etc. entries rather than manually doing the work.
-
-# .travis.yml uses matrix.exclude to block the cases where app-get can't be
-# use to install things.
-
-# For when some other test needs the C++ main build, including protoc and
-# libprotobuf.
-internal_build_cpp() {
- ./autogen.sh
- ./configure
- make -j2
-}
-
-build_cpp() {
- internal_build_cpp
- make check -j2
- cd conformance && make test_cpp && cd ..
-}
-
-build_cpp_distcheck() {
- ./autogen.sh
- ./configure
- make distcheck -j2
-}
-
-build_csharp() {
- # Just for the conformance tests. We don't currently
- # need to really build protoc, but it's simplest to keep with the
- # conventions of the other builds.
- internal_build_cpp
-
- # Install latest version of Mono
- sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
- echo "deb http://download.mono-project.com/repo/debian wheezy main" | sudo tee /etc/apt/sources.list.d/mono-xamarin.list
- echo "deb http://download.mono-project.com/repo/debian wheezy-libtiff-compat main" | sudo tee -a /etc/apt/sources.list.d/mono-xamarin.list
- sudo apt-get update -qq
- sudo apt-get install -qq mono-devel referenceassemblies-pcl nunit
- wget www.nuget.org/NuGet.exe -O nuget.exe
-
- (cd csharp/src; mono ../../nuget.exe restore)
- csharp/buildall.sh
- cd conformance && make test_csharp && cd ..
-}
-
-build_golang() {
- # Go build needs `protoc`.
- internal_build_cpp
- # Add protoc to the path so that the examples build finds it.
- export PATH="`pwd`/src:$PATH"
-
- # Install Go and the Go protobuf compiler plugin.
- sudo apt-get update -qq
- sudo apt-get install -qq golang
- export GOPATH="$HOME/gocode"
- mkdir -p "$GOPATH/src/github.com/google"
- ln -s "`pwd`" "$GOPATH/src/github.com/google/protobuf"
- export PATH="$GOPATH/bin:$PATH"
- go get github.com/golang/protobuf/protoc-gen-go
-
- cd examples && make gotest && cd ..
-}
-
-use_java() {
- version=$1
- case "$version" in
- jdk6)
- sudo apt-get install openjdk-6-jdk
- export PATH=/usr/lib/jvm/java-6-openjdk-amd64/bin:$PATH
- ;;
- jdk7)
- sudo apt-get install openjdk-7-jdk
- export PATH=/usr/lib/jvm/java-7-openjdk-amd64/bin:$PATH
- ;;
- oracle7)
- sudo apt-get install python-software-properties # for apt-add-repository
- echo "oracle-java7-installer shared/accepted-oracle-license-v1-1 select true" | \
- sudo debconf-set-selections
- yes | sudo apt-add-repository ppa:webupd8team/java
- yes | sudo apt-get install oracle-java7-installer
- export PATH=/usr/lib/jvm/java-7-oracle/bin:$PATH
- ;;
- esac
-
- which java
- java -version
-}
-
-build_java() {
- # Java build needs `protoc`.
- internal_build_cpp
- cd java && mvn test && cd ..
- cd conformance && make test_java && cd ..
-}
-
-build_javanano() {
- # Java build needs `protoc`.
- internal_build_cpp
- cd javanano && mvn test && cd ..
-}
-
-build_java_jdk6() {
- use_java jdk6
- build_java
-}
-build_java_jdk7() {
- use_java jdk7
- build_java
-}
-build_java_oracle7() {
- use_java oracle7
- build_java
-}
-
-build_javanano_jdk6() {
- use_java jdk6
- build_javanano
-}
-build_javanano_jdk7() {
- use_java jdk7
- build_javanano
-}
-build_javanano_oracle7() {
- use_java oracle7
- build_javanano
-}
-
-internal_install_python_deps() {
- # Install tox (OS X doesn't have pip).
- if [ $(uname -s) == "Darwin" ]; then
- sudo easy_install tox
- else
- sudo pip install tox
- fi
- # Only install Python2.6/3.x on Linux.
- if [ $(uname -s) == "Linux" ]; then
- sudo apt-get install -y python-software-properties # for apt-add-repository
- sudo apt-add-repository -y ppa:fkrull/deadsnakes
- sudo apt-get update -qq
- sudo apt-get install -y python2.6 python2.6-dev
- sudo apt-get install -y python3.3 python3.3-dev
- sudo apt-get install -y python3.4 python3.4-dev
- fi
-}
-
-internal_objectivec_common () {
- # Make sure xctool is up to date. Adapted from
- # http://docs.travis-ci.com/user/osx-ci-environment/
- # We don't use a before_install because we test multiple OSes.
- brew update
- brew outdated xctool || brew upgrade xctool
- # Reused the build script that takes care of configuring and ensuring things
- # are up to date. Xcode and conformance tests will be directly invoked.
- objectivec/DevTools/full_mac_build.sh \
- --core-only --skip-xcode --skip-objc-conformance
-}
-
-internal_xctool_debug_and_release() {
- xctool -configuration Debug "$@"
- xctool -configuration Release "$@"
-}
-
-build_objectivec_ios() {
- internal_objectivec_common
- # https://github.com/facebook/xctool/issues/509 - unlike xcodebuild, xctool
- # doesn't support >1 destination, so we have to build first and then run the
- # tests one destination at a time.
- internal_xctool_debug_and_release \
- -project objectivec/ProtocolBuffers_iOS.xcodeproj \
- -scheme ProtocolBuffers \
- -sdk iphonesimulator \
- build-tests
- IOS_DESTINATIONS=(
- "platform=iOS Simulator,name=iPhone 4s,OS=8.1" # 32bit
- "platform=iOS Simulator,name=iPhone 6,OS=9.1" # 64bit
- "platform=iOS Simulator,name=iPad 2,OS=8.1" # 32bit
- "platform=iOS Simulator,name=iPad Air,OS=9.1" # 64bit
- )
- for i in "${IOS_DESTINATIONS[@]}" ; do
- internal_xctool_debug_and_release \
- -project objectivec/ProtocolBuffers_iOS.xcodeproj \
- -scheme ProtocolBuffers \
- -sdk iphonesimulator \
- -destination "${i}" \
- run-tests
- done
-}
-
-build_objectivec_osx() {
- internal_objectivec_common
- internal_xctool_debug_and_release \
- -project objectivec/ProtocolBuffers_OSX.xcodeproj \
- -scheme ProtocolBuffers \
- -destination "platform=OS X,arch=x86_64" \
- test
- cd conformance && make test_objc && cd ..
-}
-
-build_python() {
- internal_build_cpp
- internal_install_python_deps
- cd python
- # Only test Python 2.6/3.x on Linux
- if [ $(uname -s) == "Linux" ]; then
- envlist=py\{26,27,33,34\}-python
- else
- envlist=py27-python
- fi
- tox -e $envlist
- cd ..
-}
-
-build_python_cpp() {
- internal_build_cpp
- internal_install_python_deps
- export LD_LIBRARY_PATH=../src/.libs # for Linux
- export DYLD_LIBRARY_PATH=../src/.libs # for OS X
- cd python
- # Only test Python 2.6/3.x on Linux
- if [ $(uname -s) == "Linux" ]; then
- # py26 is currently disabled due to json_format
- envlist=py\{27,33,34\}-cpp
- else
- envlist=py27-cpp
- fi
- tox -e $envlist
- cd ..
-}
-
-build_ruby19() {
- internal_build_cpp # For conformance tests.
- cd ruby && bash travis-test.sh ruby-1.9 && cd ..
-}
-build_ruby20() {
- internal_build_cpp # For conformance tests.
- cd ruby && bash travis-test.sh ruby-2.0 && cd ..
-}
-build_ruby21() {
- internal_build_cpp # For conformance tests.
- cd ruby && bash travis-test.sh ruby-2.1 && cd ..
-}
-build_ruby22() {
- internal_build_cpp # For conformance tests.
- cd ruby && bash travis-test.sh ruby-2.2 && cd ..
-}
-build_jruby() {
- internal_build_cpp # For conformance tests.
- cd ruby && bash travis-test.sh jruby && cd ..
-}
-
-# -------- main --------
-
-if [ "$#" -ne 1 ]; then
- echo "
-Usage: $0 { cpp |
- csharp |
- java_jdk6 |
- java_jdk7 |
- java_oracle7 |
- javanano_jdk6 |
- javanano_jdk7 |
- javanano_oracle7 |
- objectivec_ios |
- objectivec_osx |
- python |
- python_cpp |
- ruby_19 |
- ruby_20 |
- ruby_21 |
- ruby_22 |
- jruby }
-"
- exit 1
-fi
-
-set -e # exit immediately on error
-set -x # display all commands
-eval "build_$1"
diff --git a/util/python/BUILD b/util/python/BUILD
index 358c381c..3ac03856 100644
--- a/util/python/BUILD
+++ b/util/python/BUILD
@@ -1,7 +1,17 @@
# This is a placeholder for python headers. Projects needing to use
# fast cpp protos in protobuf's python interface should build with
# --define=use_fast_cpp_protos=true, and in addition, provide
-# //util/python:python_headers dependency that in turn provides Python.h.
+# //external:python_headers dependency that in turn provides Python.h.
+#
+# Projects that include protobuf using a Bazel external repository will need to
+# add a workspace rule to their WORKSPACE files to add an external workspace
+# that includes the Python headers. For example, the protobuf WORKSPACE file
+# includes the following local_repository rule that points to this directory:
+#
+# new_local_repository(
+# name = "python",
+# path = __workspace_dir__ + "/util/python",
+# )
cc_library(
name = "python_headers",
visibility = ["//visibility:public"],